ReactOS  0.4.14-dev-98-gb0d4763
compile.c
Go to the documentation of this file.
1 /*
2  * Copyright 2011 Jacek Caban for CodeWeavers
3  *
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.
8  *
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.
13  *
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
17  */
18 
19 #include <math.h>
20 #include <assert.h>
21 
22 #include "jscript.h"
23 #include "engine.h"
24 #include "parser.h"
25 
26 #include "wine/rbtree.h"
27 #include "wine/debug.h"
28 
30 WINE_DECLARE_DEBUG_CHANNEL(jscript_disas);
31 
32 typedef struct _statement_ctx_t {
33  unsigned stack_use;
36 
37  unsigned break_label;
38  unsigned continue_label;
39 
41 
44 
45 typedef struct {
48  int ref;
50 
51 typedef struct {
54 
56 
57  unsigned code_off;
58  unsigned code_size;
59 
60  unsigned *labels;
61  unsigned labels_size;
62  unsigned labels_cnt;
63 
64  struct wine_rb_tree locals;
65  unsigned locals_cnt;
66 
69 
72 
75 
76 static const struct {
77  const char *op_str;
80 } instr_info[] = {
81 #define X(n,a,b,c) {#n,b,c},
82 OP_LIST
83 #undef X
84 };
85 
87 {
88  switch(type) {
89  case ARG_STR:
90  TRACE_(jscript_disas)("\t%s", debugstr_jsstr(arg->str));
91  break;
92  case ARG_BSTR:
93  TRACE_(jscript_disas)("\t%s", debugstr_wn(arg->bstr, SysStringLen(arg->bstr)));
94  break;
95  case ARG_INT:
96  TRACE_(jscript_disas)("\t%d", arg->uint);
97  break;
98  case ARG_UINT:
99  case ARG_ADDR:
100  TRACE_(jscript_disas)("\t%u", arg->uint);
101  break;
102  case ARG_FUNC:
103  case ARG_NONE:
104  break;
106  }
107 }
108 
109 static void dump_code(compiler_ctx_t *ctx, unsigned off)
110 {
111  instr_t *instr;
112 
113  for(instr = ctx->code->instrs+off; instr < ctx->code->instrs+ctx->code_off; instr++) {
114  TRACE_(jscript_disas)("%d:\t%s", (int)(instr-ctx->code->instrs), instr_info[instr->op].op_str);
115  if(instr_info[instr->op].arg1_type == ARG_DBL) {
116  TRACE_(jscript_disas)("\t%lf", instr->u.dbl);
117  }else {
118  dump_instr_arg(instr_info[instr->op].arg1_type, instr->u.arg);
119  dump_instr_arg(instr_info[instr->op].arg2_type, instr->u.arg+1);
120  }
121  TRACE_(jscript_disas)("\n");
122  }
123 }
124 
127 
128 static inline void *compiler_alloc(bytecode_t *code, size_t size)
129 {
130  return heap_pool_alloc(&code->heap, size);
131 }
132 
134 {
135  jsstr_t *new_str;
136 
137  if(!ctx->code->str_pool_size) {
138  ctx->code->str_pool = heap_alloc(8 * sizeof(jsstr_t*));
139  if(!ctx->code->str_pool)
140  return NULL;
141  ctx->code->str_pool_size = 8;
142  }else if(ctx->code->str_pool_size == ctx->code->str_cnt) {
143  jsstr_t **new_pool;
144 
145  new_pool = heap_realloc(ctx->code->str_pool, ctx->code->str_pool_size*2*sizeof(jsstr_t*));
146  if(!new_pool)
147  return NULL;
148 
149  ctx->code->str_pool = new_pool;
150  ctx->code->str_pool_size *= 2;
151  }
152 
153  new_str = jsstr_alloc_len(str, len);
154  if(!new_str)
155  return NULL;
156 
157  ctx->code->str_pool[ctx->code->str_cnt++] = new_str;
158  return new_str;
159 }
160 
162 {
163  return compiler_alloc_string_len(ctx, str, strlenW(str));
164 }
165 
167 {
168  if(!ctx->code->bstr_pool_size) {
169  ctx->code->bstr_pool = heap_alloc(8 * sizeof(BSTR));
170  if(!ctx->code->bstr_pool)
171  return FALSE;
172  ctx->code->bstr_pool_size = 8;
173  }else if(ctx->code->bstr_pool_size == ctx->code->bstr_cnt) {
174  BSTR *new_pool;
175 
176  new_pool = heap_realloc(ctx->code->bstr_pool, ctx->code->bstr_pool_size*2*sizeof(BSTR));
177  if(!new_pool)
178  return FALSE;
179 
180  ctx->code->bstr_pool = new_pool;
181  ctx->code->bstr_pool_size *= 2;
182  }
183 
184  return TRUE;
185 }
186 
188 {
189  if(!ensure_bstr_slot(ctx))
190  return NULL;
191 
192  ctx->code->bstr_pool[ctx->code->bstr_cnt] = SysAllocString(str);
193  if(!ctx->code->bstr_pool[ctx->code->bstr_cnt])
194  return NULL;
195 
196  return ctx->code->bstr_pool[ctx->code->bstr_cnt++];
197 }
198 
200 {
201  if(!ensure_bstr_slot(ctx))
202  return NULL;
203 
205  if(!ctx->code->bstr_pool[ctx->code->bstr_cnt])
206  return NULL;
207 
208  return ctx->code->bstr_pool[ctx->code->bstr_cnt++];
209 }
210 
211 static unsigned push_instr(compiler_ctx_t *ctx, jsop_t op)
212 {
213  assert(ctx->code_size >= ctx->code_off);
214 
215  if(ctx->code_size == ctx->code_off) {
216  instr_t *new_instrs;
217 
218  new_instrs = heap_realloc(ctx->code->instrs, ctx->code_size*2*sizeof(instr_t));
219  if(!new_instrs)
220  return 0;
221 
222  ctx->code->instrs = new_instrs;
223  ctx->code_size *= 2;
224  }
225 
226  ctx->code->instrs[ctx->code_off].op = op;
227  return ctx->code_off++;
228 }
229 
230 static inline instr_t *instr_ptr(compiler_ctx_t *ctx, unsigned off)
231 {
232  assert(off < ctx->code_off);
233  return ctx->code->instrs + off;
234 }
235 
237 {
238  unsigned instr;
239 
240  instr = push_instr(ctx, op);
241  if(!instr)
242  return E_OUTOFMEMORY;
243 
244  instr_ptr(ctx, instr)->u.arg->lng = arg;
245  return S_OK;
246 }
247 
249 {
250  unsigned instr;
251  jsstr_t *str;
252 
253  str = compiler_alloc_string(ctx, arg);
254  if(!str)
255  return E_OUTOFMEMORY;
256 
257  instr = push_instr(ctx, op);
258  if(!instr)
259  return E_OUTOFMEMORY;
260 
261  instr_ptr(ctx, instr)->u.arg->str = str;
262  return S_OK;
263 }
264 
266 {
267  unsigned instr;
268  WCHAR *str;
269 
270  str = compiler_alloc_bstr(ctx, arg);
271  if(!str)
272  return E_OUTOFMEMORY;
273 
274  instr = push_instr(ctx, op);
275  if(!instr)
276  return E_OUTOFMEMORY;
277 
278  instr_ptr(ctx, instr)->u.arg->bstr = str;
279  return S_OK;
280 }
281 
283 {
284  unsigned instr;
285  WCHAR *str;
286 
287  str = compiler_alloc_bstr(ctx, arg1);
288  if(!str)
289  return E_OUTOFMEMORY;
290 
291  instr = push_instr(ctx, op);
292  if(!instr)
293  return E_OUTOFMEMORY;
294 
295  instr_ptr(ctx, instr)->u.arg[0].bstr = str;
296  instr_ptr(ctx, instr)->u.arg[1].uint = arg2;
297  return S_OK;
298 }
299 
301 {
302  unsigned instr;
303  jsstr_t *str;
304 
306  if(!str)
307  return E_OUTOFMEMORY;
308 
309  instr = push_instr(ctx, op);
310  if(!instr)
311  return E_OUTOFMEMORY;
312 
313  instr_ptr(ctx, instr)->u.arg[0].uint = arg1;
314  instr_ptr(ctx, instr)->u.arg[1].str = str;
315  return S_OK;
316 }
317 
319 {
320  unsigned instr;
321 
322  instr = push_instr(ctx, op);
323  if(!instr)
324  return E_OUTOFMEMORY;
325 
326  instr_ptr(ctx, instr)->u.dbl = arg;
327  return S_OK;
328 }
329 
330 static inline void set_arg_uint(compiler_ctx_t *ctx, unsigned instr, unsigned arg)
331 {
332  instr_ptr(ctx, instr)->u.arg->uint = arg;
333 }
334 
336 {
337  unsigned instr;
338 
339  instr = push_instr(ctx, op);
340  if(!instr)
341  return E_OUTOFMEMORY;
342 
343  set_arg_uint(ctx, instr, arg);
344  return S_OK;
345 }
346 
348 {
349  HRESULT hres;
350 
351  hres = compile_expression(ctx, expr->expression1, TRUE);
352  if(FAILED(hres))
353  return hres;
354 
355  hres = compile_expression(ctx, expr->expression2, TRUE);
356  if(FAILED(hres))
357  return hres;
358 
359  return push_instr(ctx, op) ? S_OK : E_OUTOFMEMORY;
360 }
361 
363 {
364  HRESULT hres;
365 
366  hres = compile_expression(ctx, expr->expression, TRUE);
367  if(FAILED(hres))
368  return hres;
369 
370  return push_instr(ctx, op) ? S_OK : E_OUTOFMEMORY;
371 }
372 
373 /* ECMA-262 3rd Edition 11.2.1 */
375 {
376  HRESULT hres;
377 
378  hres = compile_expression(ctx, expr->expression, TRUE);
379  if(FAILED(hres))
380  return hres;
381 
382  return push_instr_bstr(ctx, OP_member, expr->identifier);
383 }
384 
385 #define LABEL_FLAG 0x80000000
386 
387 static unsigned alloc_label(compiler_ctx_t *ctx)
388 {
389  if(!ctx->labels_size) {
390  ctx->labels = heap_alloc(8 * sizeof(*ctx->labels));
391  if(!ctx->labels)
392  return 0;
393  ctx->labels_size = 8;
394  }else if(ctx->labels_size == ctx->labels_cnt) {
395  unsigned *new_labels;
396 
397  new_labels = heap_realloc(ctx->labels, 2*ctx->labels_size*sizeof(*ctx->labels));
398  if(!new_labels)
399  return 0;
400 
401  ctx->labels = new_labels;
402  ctx->labels_size *= 2;
403  }
404 
405  return ctx->labels_cnt++ | LABEL_FLAG;
406 }
407 
408 static void label_set_addr(compiler_ctx_t *ctx, unsigned label)
409 {
411  ctx->labels[label & ~LABEL_FLAG] = ctx->code_off;
412 }
413 
415 {
416  return type == EXPR_IDENT || type == EXPR_MEMBER || type == EXPR_ARRAY;
417 }
418 
419 static BOOL bind_local(compiler_ctx_t *ctx, const WCHAR *identifier, int *ret_ref)
420 {
421  statement_ctx_t *iter;
422  local_ref_t *ref;
423 
424  for(iter = ctx->stat_ctx; iter; iter = iter->next) {
425  if(iter->using_scope)
426  return FALSE;
427  }
428 
429  ref = lookup_local(ctx->func, identifier);
430  if(!ref)
431  return FALSE;
432 
433  *ret_ref = ref->ref;
434  return TRUE;
435 }
436 
437 static HRESULT emit_identifier_ref(compiler_ctx_t *ctx, const WCHAR *identifier, unsigned flags)
438 {
439  int local_ref;
440  if(bind_local(ctx, identifier, &local_ref))
441  return push_instr_int(ctx, OP_local_ref, local_ref);
442  return push_instr_bstr_uint(ctx, OP_identid, identifier, flags);
443 }
444 
445 static HRESULT emit_identifier(compiler_ctx_t *ctx, const WCHAR *identifier)
446 {
447  int local_ref;
448  if(bind_local(ctx, identifier, &local_ref))
449  return push_instr_int(ctx, OP_local, local_ref);
450  return push_instr_bstr(ctx, OP_ident, identifier);
451 }
452 
454 {
455  HRESULT hres = S_OK;
456 
457  switch(expr->type) {
458  case EXPR_IDENT: {
460 
461  hres = emit_identifier_ref(ctx, ident_expr->identifier, flags);
462  break;
463  }
464  case EXPR_ARRAY: {
466 
467  hres = compile_expression(ctx, array_expr->expression1, TRUE);
468  if(FAILED(hres))
469  return hres;
470 
471  hres = compile_expression(ctx, array_expr->expression2, TRUE);
472  if(FAILED(hres))
473  return hres;
474 
475  hres = push_instr_uint(ctx, OP_memberid, flags);
476  break;
477  }
478  case EXPR_MEMBER: {
480 
481  hres = compile_expression(ctx, member_expr->expression, TRUE);
482  if(FAILED(hres))
483  return hres;
484 
485  /* FIXME: Potential optimization */
486  hres = push_instr_str(ctx, OP_str, member_expr->identifier);
487  if(FAILED(hres))
488  return hres;
489 
490  hres = push_instr_uint(ctx, OP_memberid, flags);
491  break;
492  }
494  }
495 
496  return hres;
497 }
498 
500 {
501  HRESULT hres;
502 
503  if(!is_memberid_expr(expr->expression->type)) {
504  hres = compile_expression(ctx, expr->expression, TRUE);
505  if(FAILED(hres))
506  return hres;
507 
508  return push_instr_uint(ctx, OP_throw_ref, JS_E_ILLEGAL_ASSIGN);
509  }
510 
511  hres = compile_memberid_expression(ctx, expr->expression, fdexNameEnsure);
512  if(FAILED(hres))
513  return hres;
514 
515  return push_instr_int(ctx, op, n);
516 }
517 
518 /* ECMA-262 3rd Edition 11.14 */
520 {
521  HRESULT hres;
522 
523  hres = compile_expression(ctx, expr->expression1, FALSE);
524  if(FAILED(hres))
525  return hres;
526 
527  return compile_expression(ctx, expr->expression2, emit_ret);
528 }
529 
530 /* ECMA-262 3rd Edition 11.11 */
532 {
533  unsigned instr;
534  HRESULT hres;
535 
536  hres = compile_expression(ctx, expr->expression1, TRUE);
537  if(FAILED(hres))
538  return hres;
539 
540  instr = push_instr(ctx, op);
541  if(!instr)
542  return E_OUTOFMEMORY;
543 
544  hres = compile_expression(ctx, expr->expression2, TRUE);
545  if(FAILED(hres))
546  return hres;
547 
548  set_arg_uint(ctx, instr, ctx->code_off);
549  return S_OK;
550 }
551 
552 /* ECMA-262 3rd Edition 11.12 */
554 {
555  unsigned jmp_false, jmp_end;
556  HRESULT hres;
557 
558  hres = compile_expression(ctx, expr->expression, TRUE);
559  if(FAILED(hres))
560  return hres;
561 
562  jmp_false = push_instr(ctx, OP_cnd_z);
563  if(!jmp_false)
564  return E_OUTOFMEMORY;
565 
566  hres = compile_expression(ctx, expr->true_expression, TRUE);
567  if(FAILED(hres))
568  return hres;
569 
570  jmp_end = push_instr(ctx, OP_jmp);
571  if(!jmp_end)
572  return E_OUTOFMEMORY;
573 
574  set_arg_uint(ctx, jmp_false, ctx->code_off);
575  hres = push_instr_uint(ctx, OP_pop, 1);
576  if(FAILED(hres))
577  return hres;
578 
579  hres = compile_expression(ctx, expr->false_expression, TRUE);
580  if(FAILED(hres))
581  return hres;
582 
583  set_arg_uint(ctx, jmp_end, ctx->code_off);
584  return S_OK;
585 }
586 
588 {
589  unsigned arg_cnt = 0;
590  argument_t *arg;
591  HRESULT hres;
592 
593  hres = compile_expression(ctx, expr->expression, TRUE);
594  if(FAILED(hres))
595  return hres;
596 
597  for(arg = expr->argument_list; arg; arg = arg->next) {
598  hres = compile_expression(ctx, arg->expr, TRUE);
599  if(FAILED(hres))
600  return hres;
601  arg_cnt++;
602  }
603 
604  hres = push_instr_uint(ctx, OP_new, arg_cnt);
605  if(FAILED(hres))
606  return hres;
607 
608  hres = push_instr_uint(ctx, OP_pop, arg_cnt+1);
609  if(FAILED(hres))
610  return hres;
611 
612  return push_instr(ctx, OP_push_acc) ? S_OK : E_OUTOFMEMORY;
613 }
614 
616 {
617  unsigned arg_cnt = 0, extra_args;
618  argument_t *arg;
619  unsigned instr;
620  jsop_t op;
621  HRESULT hres;
622 
623  if(is_memberid_expr(expr->expression->type)) {
624  op = OP_call_member;
625  extra_args = 2;
626  hres = compile_memberid_expression(ctx, expr->expression, 0);
627  }else {
628  op = OP_call;
629  extra_args = 1;
630  hres = compile_expression(ctx, expr->expression, TRUE);
631  }
632 
633  if(FAILED(hres))
634  return hres;
635 
636  for(arg = expr->argument_list; arg; arg = arg->next) {
637  hres = compile_expression(ctx, arg->expr, TRUE);
638  if(FAILED(hres))
639  return hres;
640  arg_cnt++;
641  }
642 
643  instr = push_instr(ctx, op);
644  if(!instr)
645  return E_OUTOFMEMORY;
646 
647  instr_ptr(ctx, instr)->u.arg[0].uint = arg_cnt;
648  instr_ptr(ctx, instr)->u.arg[1].lng = emit_ret;
649 
650  hres = push_instr_uint(ctx, OP_pop, arg_cnt + extra_args);
651  if(FAILED(hres))
652  return hres;
653 
654  return !emit_ret || push_instr(ctx, OP_push_acc) ? S_OK : E_OUTOFMEMORY;
655 }
656 
658 {
659  HRESULT hres;
660 
661  switch(expr->expression->type) {
662  case EXPR_ARRAY: {
663  binary_expression_t *array_expr = (binary_expression_t*)expr->expression;
664 
665  hres = compile_expression(ctx, array_expr->expression1, TRUE);
666  if(FAILED(hres))
667  return hres;
668 
669  hres = compile_expression(ctx, array_expr->expression2, TRUE);
670  if(FAILED(hres))
671  return hres;
672 
673  if(!push_instr(ctx, OP_delete))
674  return E_OUTOFMEMORY;
675  break;
676  }
677  case EXPR_MEMBER: {
678  member_expression_t *member_expr = (member_expression_t*)expr->expression;
679 
680  hres = compile_expression(ctx, member_expr->expression, TRUE);
681  if(FAILED(hres))
682  return hres;
683 
684  /* FIXME: Potential optimization */
685  hres = push_instr_str(ctx, OP_str, member_expr->identifier);
686  if(FAILED(hres))
687  return hres;
688 
689  if(!push_instr(ctx, OP_delete))
690  return E_OUTOFMEMORY;
691  break;
692  }
693  case EXPR_IDENT:
694  return push_instr_bstr(ctx, OP_delete_ident, ((identifier_expression_t*)expr->expression)->identifier);
695  default: {
696  static const WCHAR fixmeW[] = {'F','I','X','M','E',0};
697 
698  WARN("invalid delete, unimplemented exception message\n");
699 
700  hres = compile_expression(ctx, expr->expression, TRUE);
701  if(FAILED(hres))
702  return hres;
703 
704  return push_instr_uint_str(ctx, OP_throw_type, JS_E_INVALID_DELETE, fixmeW);
705  }
706  }
707 
708  return S_OK;
709 }
710 
712 {
713  BOOL use_throw_path = FALSE;
714  unsigned arg_cnt = 0;
715  HRESULT hres;
716 
717  if(expr->expression1->type == EXPR_CALL) {
718  call_expression_t *call_expr = (call_expression_t*)expr->expression1;
719  argument_t *arg;
720 
721  if(op != OP_LAST) {
722  FIXME("op %d not supported on parametrized assign expressions\n", op);
723  return E_NOTIMPL;
724  }
725 
726  if(is_memberid_expr(call_expr->expression->type) && call_expr->argument_list) {
727  hres = compile_memberid_expression(ctx, call_expr->expression, fdexNameEnsure);
728  if(FAILED(hres))
729  return hres;
730 
731  for(arg = call_expr->argument_list; arg; arg = arg->next) {
732  hres = compile_expression(ctx, arg->expr, TRUE);
733  if(FAILED(hres))
734  return hres;
735  arg_cnt++;
736  }
737  }else {
738  use_throw_path = TRUE;
739  }
740  }else if(is_memberid_expr(expr->expression1->type)) {
741  hres = compile_memberid_expression(ctx, expr->expression1, fdexNameEnsure);
742  if(FAILED(hres))
743  return hres;
744  }else {
745  use_throw_path = TRUE;
746  }
747 
748  if(use_throw_path) {
749  /* Illegal assignment: evaluate and throw */
750  hres = compile_expression(ctx, expr->expression1, TRUE);
751  if(FAILED(hres))
752  return hres;
753 
754  hres = compile_expression(ctx, expr->expression2, TRUE);
755  if(FAILED(hres))
756  return hres;
757 
758  if(op != OP_LAST && !push_instr(ctx, op))
759  return E_OUTOFMEMORY;
760 
761  return push_instr_uint(ctx, OP_throw_ref, JS_E_ILLEGAL_ASSIGN);
762  }
763 
764  if(op != OP_LAST && !push_instr(ctx, OP_refval))
765  return E_OUTOFMEMORY;
766 
767  hres = compile_expression(ctx, expr->expression2, TRUE);
768  if(FAILED(hres))
769  return hres;
770 
771  if(op != OP_LAST && !push_instr(ctx, op))
772  return E_OUTOFMEMORY;
773 
774  if(arg_cnt)
775  return push_instr_uint(ctx, OP_assign_call, arg_cnt);
776 
777  if(!push_instr(ctx, OP_assign))
778  return E_OUTOFMEMORY;
779 
780  return S_OK;
781 }
782 
784 {
785  jsop_t op;
786  HRESULT hres;
787 
788  if(is_memberid_expr(expr->expression->type)) {
789  if(expr->expression->type == EXPR_IDENT)
790  return push_instr_bstr(ctx, OP_typeofident, ((identifier_expression_t*)expr->expression)->identifier);
791 
792  op = OP_typeofid;
793  hres = compile_memberid_expression(ctx, expr->expression, 0);
794  }else {
795  op = OP_typeof;
796  hres = compile_expression(ctx, expr->expression, TRUE);
797  }
798  if(FAILED(hres))
799  return hres;
800 
801  return push_instr(ctx, op) ? S_OK : E_OUTOFMEMORY;
802 }
803 
805 {
806  switch(literal->type) {
807  case LT_BOOL:
808  return push_instr_int(ctx, OP_bool, literal->u.bval);
809  case LT_DOUBLE:
810  return push_instr_double(ctx, OP_double, literal->u.dval);
811  case LT_NULL:
812  return push_instr(ctx, OP_null) ? S_OK : E_OUTOFMEMORY;
813  case LT_STRING:
814  return push_instr_str(ctx, OP_str, literal->u.wstr);
815  case LT_REGEXP: {
816  unsigned instr;
817  jsstr_t *str;
818 
819  str = compiler_alloc_string_len(ctx, literal->u.regexp.str, literal->u.regexp.str_len);
820  if(!str)
821  return E_OUTOFMEMORY;
822 
823  instr = push_instr(ctx, OP_regexp);
824  if(!instr)
825  return E_OUTOFMEMORY;
826 
827  instr_ptr(ctx, instr)->u.arg[0].str = str;
828  instr_ptr(ctx, instr)->u.arg[1].uint = literal->u.regexp.flags;
829  return S_OK;
830  }
832  }
833  return E_FAIL;
834 }
835 
837 {
838  switch(literal->type) {
839  case LT_STRING:
840  *str = compiler_alloc_bstr(ctx, literal->u.wstr);
841  break;
842  case LT_DOUBLE: {
843  jsstr_t *jsstr;
844  HRESULT hres;
845 
846  hres = double_to_string(literal->u.dval, &jsstr);
847  if(FAILED(hres))
848  return hres;
849 
850  *str = compiler_alloc_bstr_len(ctx, NULL, jsstr_length(jsstr));
851  if(*str)
852  jsstr_flush(jsstr, *str);
853  jsstr_release(jsstr);
854  break;
855  }
857  }
858 
859  return *str ? S_OK : E_OUTOFMEMORY;
860 }
861 
863 {
864  unsigned length = 0;
865  array_element_t *iter;
866  unsigned array_instr;
867  HRESULT hres;
868 
869  array_instr = push_instr(ctx, OP_carray);
870 
871  for(iter = expr->element_list; iter; iter = iter->next) {
872  length += iter->elision;
873 
874  hres = compile_expression(ctx, iter->expr, TRUE);
875  if(FAILED(hres))
876  return hres;
877 
878  hres = push_instr_uint(ctx, OP_carray_set, length);
879  if(FAILED(hres))
880  return hres;
881 
882  length++;
883  }
884 
885  instr_ptr(ctx, array_instr)->u.arg[0].uint = length + expr->length;
886  return S_OK;
887 }
888 
890 {
891  property_definition_t *iter;
892  BSTR name;
893  HRESULT hres;
894 
895  if(!push_instr(ctx, OP_new_obj))
896  return E_OUTOFMEMORY;
897 
898  for(iter = expr->property_list; iter; iter = iter->next) {
899  hres = literal_as_bstr(ctx, iter->name, &name);
900  if(FAILED(hres))
901  return hres;
902 
903  hres = compile_expression(ctx, iter->value, TRUE);
904  if(FAILED(hres))
905  return hres;
906 
907  hres = push_instr_bstr_uint(ctx, OP_obj_prop, name, iter->type);
908  if(FAILED(hres))
909  return hres;
910  }
911 
912  return S_OK;
913 }
914 
916 {
917  return emit_ret ? push_instr_uint(ctx, OP_func, expr->func_id) : S_OK;
918 }
919 
921 {
922  HRESULT hres;
923 
924  switch(expr->type) {
925  case EXPR_ADD:
927  break;
928  case EXPR_AND:
930  break;
931  case EXPR_ARRAY:
933  break;
934  case EXPR_ARRAYLIT:
936  break;
937  case EXPR_ASSIGN:
939  break;
940  case EXPR_ASSIGNADD:
942  break;
943  case EXPR_ASSIGNAND:
945  break;
946  case EXPR_ASSIGNSUB:
948  break;
949  case EXPR_ASSIGNMUL:
951  break;
952  case EXPR_ASSIGNDIV:
954  break;
955  case EXPR_ASSIGNMOD:
957  break;
958  case EXPR_ASSIGNOR:
960  break;
961  case EXPR_ASSIGNLSHIFT:
963  break;
964  case EXPR_ASSIGNRSHIFT:
966  break;
967  case EXPR_ASSIGNRRSHIFT:
969  break;
970  case EXPR_ASSIGNXOR:
972  break;
973  case EXPR_BAND:
975  break;
976  case EXPR_BITNEG:
978  break;
979  case EXPR_BOR:
981  break;
982  case EXPR_CALL:
983  return compile_call_expression(ctx, (call_expression_t*)expr, emit_ret);
984  case EXPR_COMMA:
985  return compile_comma_expression(ctx, (binary_expression_t*)expr, emit_ret);
986  case EXPR_COND:
988  break;
989  case EXPR_DELETE:
991  break;
992  case EXPR_DIV:
994  break;
995  case EXPR_EQ:
997  break;
998  case EXPR_EQEQ:
1000  break;
1001  case EXPR_FUNC:
1002  return compile_function_expression(ctx, (function_expression_t*)expr, emit_ret);
1003  case EXPR_GREATER:
1005  break;
1006  case EXPR_GREATEREQ:
1008  break;
1009  case EXPR_IDENT:
1010  hres = emit_identifier(ctx, ((identifier_expression_t*)expr)->identifier);
1011  break;
1012  case EXPR_IN:
1014  break;
1015  case EXPR_INSTANCEOF:
1016  hres = compile_binary_expression(ctx, (binary_expression_t*)expr, OP_instanceof);
1017  break;
1018  case EXPR_LESS:
1020  break;
1021  case EXPR_LESSEQ:
1023  break;
1024  case EXPR_LITERAL:
1025  hres = compile_literal(ctx, ((literal_expression_t*)expr)->literal);
1026  break;
1027  case EXPR_LOGNEG:
1029  break;
1030  case EXPR_LSHIFT:
1032  break;
1033  case EXPR_MEMBER:
1035  break;
1036  case EXPR_MINUS:
1038  break;
1039  case EXPR_MOD:
1041  break;
1042  case EXPR_MUL:
1044  break;
1045  case EXPR_NEW:
1047  break;
1048  case EXPR_NOTEQ:
1050  break;
1051  case EXPR_NOTEQEQ:
1053  break;
1054  case EXPR_OR:
1056  break;
1057  case EXPR_PLUS:
1059  break;
1060  case EXPR_POSTDEC:
1061  hres = compile_increment_expression(ctx, (unary_expression_t*)expr, OP_postinc, -1);
1062  break;
1063  case EXPR_POSTINC:
1064  hres = compile_increment_expression(ctx, (unary_expression_t*)expr, OP_postinc, 1);
1065  break;
1066  case EXPR_PREDEC:
1067  hres = compile_increment_expression(ctx, (unary_expression_t*)expr, OP_preinc, -1);
1068  break;
1069  case EXPR_PREINC:
1070  hres = compile_increment_expression(ctx, (unary_expression_t*)expr, OP_preinc, 1);
1071  break;
1072  case EXPR_PROPVAL:
1074  break;
1075  case EXPR_RSHIFT:
1077  break;
1078  case EXPR_RRSHIFT:
1080  break;
1081  case EXPR_SUB:
1083  break;
1084  case EXPR_THIS:
1085  return !emit_ret || push_instr(ctx, OP_this) ? S_OK : E_OUTOFMEMORY;
1086  case EXPR_TYPEOF:
1088  break;
1089  case EXPR_VOID:
1091  break;
1092  case EXPR_BXOR:
1094  break;
1096  }
1097 
1098  if(FAILED(hres))
1099  return hres;
1100 
1101  return emit_ret ? S_OK : push_instr_uint(ctx, OP_pop, 1);
1102 }
1103 
1105 {
1106  return type == STAT_FOR || type == STAT_FORIN || type == STAT_WHILE;
1107 }
1108 
1109 /* ECMA-262 3rd Edition 12.1 */
1111 {
1112  HRESULT hres;
1113 
1114  while(iter) {
1115  hres = compile_statement(ctx, NULL, iter);
1116  if(FAILED(hres))
1117  return hres;
1118 
1119  iter = iter->next;
1120  }
1121 
1122  return S_OK;
1123 }
1124 
1125 /* ECMA-262 3rd Edition 12.2 */
1127 {
1128  variable_declaration_t *iter;
1129  HRESULT hres;
1130 
1131  assert(list != NULL);
1132 
1133  for(iter = list; iter; iter = iter->next) {
1134  if(!iter->expr)
1135  continue;
1136 
1137  hres = emit_identifier_ref(ctx, iter->identifier, 0);
1138  if(FAILED(hres))
1139  return hres;
1140 
1141  hres = compile_expression(ctx, iter->expr, TRUE);
1142  if(FAILED(hres))
1143  return hres;
1144 
1145  if(!push_instr(ctx, OP_assign))
1146  return E_OUTOFMEMORY;
1147 
1148  hres = push_instr_uint(ctx, OP_pop, 1);
1149  if(FAILED(hres))
1150  return hres;
1151  }
1152 
1153  return S_OK;
1154 }
1155 
1156 /* ECMA-262 3rd Edition 12.2 */
1158 {
1159  return compile_variable_list(ctx, stat->variable_list);
1160 }
1161 
1162 /* ECMA-262 3rd Edition 12.4 */
1164 {
1165  HRESULT hres;
1166 
1167  hres = compile_expression(ctx, stat->expr, ctx->from_eval);
1168  if(FAILED(hres))
1169  return hres;
1170 
1171  return !ctx->from_eval || push_instr(ctx, OP_setret) ? S_OK : E_OUTOFMEMORY;
1172 }
1173 
1174 /* ECMA-262 3rd Edition 12.5 */
1176 {
1177  unsigned jmp_else;
1178  HRESULT hres;
1179 
1180  hres = compile_expression(ctx, stat->expr, TRUE);
1181  if(FAILED(hres))
1182  return hres;
1183 
1184  jmp_else = push_instr(ctx, OP_jmp_z);
1185  if(!jmp_else)
1186  return E_OUTOFMEMORY;
1187 
1188  hres = compile_statement(ctx, NULL, stat->if_stat);
1189  if(FAILED(hres))
1190  return hres;
1191 
1192  if(stat->else_stat) {
1193  unsigned jmp_end;
1194 
1195  jmp_end = push_instr(ctx, OP_jmp);
1196  if(!jmp_end)
1197  return E_OUTOFMEMORY;
1198 
1199  set_arg_uint(ctx, jmp_else, ctx->code_off);
1200 
1201  hres = compile_statement(ctx, NULL, stat->else_stat);
1202  if(FAILED(hres))
1203  return hres;
1204 
1205  set_arg_uint(ctx, jmp_end, ctx->code_off);
1206  }else {
1207  set_arg_uint(ctx, jmp_else, ctx->code_off);
1208  }
1209 
1210  return S_OK;
1211 }
1212 
1213 /* ECMA-262 3rd Edition 12.6.2 */
1215 {
1216  statement_ctx_t stat_ctx = {0, FALSE, FALSE};
1217  unsigned jmp_off;
1218  HRESULT hres;
1219 
1220  stat_ctx.break_label = alloc_label(ctx);
1221  if(!stat_ctx.break_label)
1222  return E_OUTOFMEMORY;
1223 
1224  stat_ctx.continue_label = alloc_label(ctx);
1225  if(!stat_ctx.continue_label)
1226  return E_OUTOFMEMORY;
1227 
1228  jmp_off = ctx->code_off;
1229 
1230  if(!stat->do_while) {
1231  label_set_addr(ctx, stat_ctx.continue_label);
1232  hres = compile_expression(ctx, stat->expr, TRUE);
1233  if(FAILED(hres))
1234  return hres;
1235 
1236  hres = push_instr_uint(ctx, OP_jmp_z, stat_ctx.break_label);
1237  if(FAILED(hres))
1238  return hres;
1239  }
1240 
1241  hres = compile_statement(ctx, &stat_ctx, stat->statement);
1242  if(FAILED(hres))
1243  return hres;
1244 
1245  if(stat->do_while) {
1246  label_set_addr(ctx, stat_ctx.continue_label);
1247  hres = compile_expression(ctx, stat->expr, TRUE);
1248  if(FAILED(hres))
1249  return hres;
1250 
1251  hres = push_instr_uint(ctx, OP_jmp_z, stat_ctx.break_label);
1252  if(FAILED(hres))
1253  return hres;
1254  }
1255 
1256  hres = push_instr_uint(ctx, OP_jmp, jmp_off);
1257  if(FAILED(hres))
1258  return hres;
1259 
1260  label_set_addr(ctx, stat_ctx.break_label);
1261  return S_OK;
1262 }
1263 
1264 /* ECMA-262 3rd Edition 12.6.3 */
1266 {
1267  statement_ctx_t stat_ctx = {0, FALSE, FALSE};
1268  unsigned expr_off;
1269  HRESULT hres;
1270 
1271  if(stat->variable_list) {
1272  hres = compile_variable_list(ctx, stat->variable_list);
1273  if(FAILED(hres))
1274  return hres;
1275  }else if(stat->begin_expr) {
1276  hres = compile_expression(ctx, stat->begin_expr, FALSE);
1277  if(FAILED(hres))
1278  return hres;
1279  }
1280 
1281  stat_ctx.break_label = alloc_label(ctx);
1282  if(!stat_ctx.break_label)
1283  return E_OUTOFMEMORY;
1284 
1285  stat_ctx.continue_label = alloc_label(ctx);
1286  if(!stat_ctx.continue_label)
1287  return E_OUTOFMEMORY;
1288 
1289  expr_off = ctx->code_off;
1290 
1291  if(stat->expr) {
1292  hres = compile_expression(ctx, stat->expr, TRUE);
1293  if(FAILED(hres))
1294  return hres;
1295 
1296  hres = push_instr_uint(ctx, OP_jmp_z, stat_ctx.break_label);
1297  if(FAILED(hres))
1298  return hres;
1299  }
1300 
1301  hres = compile_statement(ctx, &stat_ctx, stat->statement);
1302  if(FAILED(hres))
1303  return hres;
1304 
1305  label_set_addr(ctx, stat_ctx.continue_label);
1306 
1307  if(stat->end_expr) {
1308  hres = compile_expression(ctx, stat->end_expr, FALSE);
1309  if(FAILED(hres))
1310  return hres;
1311  }
1312 
1313  hres = push_instr_uint(ctx, OP_jmp, expr_off);
1314  if(FAILED(hres))
1315  return hres;
1316 
1317  label_set_addr(ctx, stat_ctx.break_label);
1318  return S_OK;
1319 }
1320 
1321 /* ECMA-262 3rd Edition 12.6.4 */
1323 {
1324  statement_ctx_t stat_ctx = {4, FALSE, FALSE};
1325  HRESULT hres;
1326 
1327  if(stat->variable) {
1328  hres = compile_variable_list(ctx, stat->variable);
1329  if(FAILED(hres))
1330  return hres;
1331  }
1332 
1333  stat_ctx.break_label = alloc_label(ctx);
1334  if(!stat_ctx.break_label)
1335  return E_OUTOFMEMORY;
1336 
1337  stat_ctx.continue_label = alloc_label(ctx);
1338  if(!stat_ctx.continue_label)
1339  return E_OUTOFMEMORY;
1340 
1341  hres = compile_expression(ctx, stat->in_expr, TRUE);
1342  if(FAILED(hres))
1343  return hres;
1344 
1345  if(stat->variable) {
1346  hres = emit_identifier_ref(ctx, stat->variable->identifier, fdexNameEnsure);
1347  if(FAILED(hres))
1348  return hres;
1349  }else if(is_memberid_expr(stat->expr->type)) {
1350  hres = compile_memberid_expression(ctx, stat->expr, fdexNameEnsure);
1351  if(FAILED(hres))
1352  return hres;
1353  }else {
1354  hres = push_instr_uint(ctx, OP_throw_ref, JS_E_ILLEGAL_ASSIGN);
1355  if(FAILED(hres))
1356  return hres;
1357 
1358  /* FIXME: compile statement anyways when we depend on compiler to check errors */
1359  return S_OK;
1360  }
1361 
1362  hres = push_instr_int(ctx, OP_int, DISPID_STARTENUM);
1363  if(FAILED(hres))
1364  return hres;
1365 
1366  label_set_addr(ctx, stat_ctx.continue_label);
1367  hres = push_instr_uint(ctx, OP_forin, stat_ctx.break_label);
1368  if(FAILED(hres))
1369  return E_OUTOFMEMORY;
1370 
1371  hres = compile_statement(ctx, &stat_ctx, stat->statement);
1372  if(FAILED(hres))
1373  return hres;
1374 
1375  hres = push_instr_uint(ctx, OP_jmp, stat_ctx.continue_label);
1376  if(FAILED(hres))
1377  return hres;
1378 
1379  label_set_addr(ctx, stat_ctx.break_label);
1380  return S_OK;
1381 }
1382 
1384 {
1385  unsigned stack_pop = 0;
1386  statement_ctx_t *iter;
1387  HRESULT hres;
1388 
1389  for(iter = ctx->stat_ctx; iter != stat_ctx; iter = iter->next) {
1390  if(iter->using_scope && !push_instr(ctx, OP_pop_scope))
1391  return E_OUTOFMEMORY;
1392  if(iter->using_except) {
1393  if(stack_pop) {
1394  hres = push_instr_uint(ctx, OP_pop, stack_pop);
1395  if(FAILED(hres))
1396  return hres;
1397  stack_pop = 0;
1398  }
1399  hres = push_instr_uint(ctx, OP_pop_except, ctx->code_off+1);
1400  if(FAILED(hres))
1401  return hres;
1402  }
1403  stack_pop += iter->stack_use;
1404  }
1405 
1406  if(stack_pop) {
1407  hres = push_instr_uint(ctx, OP_pop, stack_pop);
1408  if(FAILED(hres))
1409  return hres;
1410  }
1411 
1412  return S_OK;
1413 }
1414 
1415 /* ECMA-262 3rd Edition 12.7 */
1417 {
1418  statement_ctx_t *pop_ctx;
1419  HRESULT hres;
1420 
1421  if(stat->identifier) {
1422  statement_t *label_stat;
1423  statement_ctx_t *iter;
1424 
1425  pop_ctx = NULL;
1426 
1427  for(iter = ctx->stat_ctx; iter; iter = iter->next) {
1428  if(iter->continue_label)
1429  pop_ctx = iter;
1430  if(iter->labelled_stat && !strcmpW(iter->labelled_stat->identifier, stat->identifier))
1431  break;
1432  }
1433 
1434  if(!iter) {
1435  WARN("Label not found\n");
1436  return JS_E_LABEL_NOT_FOUND;
1437  }
1438 
1439  /* Labelled continue are allowed only on loops */
1440  for(label_stat = iter->labelled_stat->statement;
1441  label_stat->type == STAT_LABEL;
1442  label_stat = ((labelled_statement_t*)label_stat)->statement);
1443  if(!is_loop_statement(label_stat->type)) {
1444  WARN("Label is not a loop\n");
1445  return JS_E_INVALID_CONTINUE;
1446  }
1447 
1448  assert(pop_ctx != NULL);
1449  }else {
1450  for(pop_ctx = ctx->stat_ctx; pop_ctx; pop_ctx = pop_ctx->next) {
1451  if(pop_ctx->continue_label)
1452  break;
1453  }
1454 
1455  if(!pop_ctx) {
1456  WARN("continue outside loop\n");
1457  return JS_E_INVALID_CONTINUE;
1458  }
1459  }
1460 
1461  hres = pop_to_stat(ctx, pop_ctx);
1462  if(FAILED(hres))
1463  return hres;
1464 
1465  return push_instr_uint(ctx, OP_jmp, pop_ctx->continue_label);
1466 }
1467 
1468 /* ECMA-262 3rd Edition 12.8 */
1470 {
1471  statement_ctx_t *pop_ctx;
1472  HRESULT hres;
1473 
1474  if(stat->identifier) {
1475  for(pop_ctx = ctx->stat_ctx; pop_ctx; pop_ctx = pop_ctx->next) {
1476  if(pop_ctx->labelled_stat && !strcmpW(pop_ctx->labelled_stat->identifier, stat->identifier)) {
1477  assert(pop_ctx->break_label);
1478  break;
1479  }
1480  }
1481 
1482  if(!pop_ctx) {
1483  WARN("Label not found\n");
1484  return JS_E_LABEL_NOT_FOUND;
1485  }
1486  }else {
1487  for(pop_ctx = ctx->stat_ctx; pop_ctx; pop_ctx = pop_ctx->next) {
1488  if(pop_ctx->break_label && !pop_ctx->labelled_stat)
1489  break;
1490  }
1491 
1492  if(!pop_ctx) {
1493  WARN("Break outside loop\n");
1494  return JS_E_INVALID_BREAK;
1495  }
1496  }
1497 
1498  hres = pop_to_stat(ctx, pop_ctx->next);
1499  if(FAILED(hres))
1500  return hres;
1501 
1502  return push_instr_uint(ctx, OP_jmp, pop_ctx->break_label);
1503 }
1504 
1505 /* ECMA-262 3rd Edition 12.9 */
1507 {
1508  HRESULT hres;
1509 
1510  if(ctx->from_eval) {
1511  WARN("misplaced return statement\n");
1512  return JS_E_MISPLACED_RETURN;
1513  }
1514 
1515  if(stat->expr) {
1516  hres = compile_expression(ctx, stat->expr, TRUE);
1517  if(FAILED(hres))
1518  return hres;
1519  if(!push_instr(ctx, OP_setret))
1520  return E_OUTOFMEMORY;
1521  }
1522 
1523  hres = pop_to_stat(ctx, NULL);
1524  if(FAILED(hres))
1525  return hres;
1526 
1527  return push_instr_uint(ctx, OP_ret, !stat->expr);
1528 }
1529 
1530 /* ECMA-262 3rd Edition 12.10 */
1532 {
1533  statement_ctx_t stat_ctx = {0, TRUE, FALSE};
1534  HRESULT hres;
1535 
1536  hres = compile_expression(ctx, stat->expr, TRUE);
1537  if(FAILED(hres))
1538  return hres;
1539 
1540  if(!push_instr(ctx, OP_push_scope))
1541  return E_OUTOFMEMORY;
1542 
1543  hres = compile_statement(ctx, &stat_ctx, stat->statement);
1544  if(FAILED(hres))
1545  return hres;
1546 
1547  if(!push_instr(ctx, OP_pop_scope))
1548  return E_OUTOFMEMORY;
1549 
1550  return S_OK;
1551 }
1552 
1553 /* ECMA-262 3rd Edition 12.10 */
1555 {
1556  statement_ctx_t stat_ctx = {0, FALSE, FALSE, 0, 0, stat}, *iter;
1557  HRESULT hres;
1558 
1559  for(iter = ctx->stat_ctx; iter; iter = iter->next) {
1560  if(iter->labelled_stat && !strcmpW(iter->labelled_stat->identifier, stat->identifier)) {
1561  WARN("Label %s redefined\n", debugstr_w(stat->identifier));
1562  return JS_E_LABEL_REDEFINED;
1563  }
1564  }
1565 
1566  /* Labelled breaks are allowed for any labelled statements, not only loops (violating spec) */
1567  stat_ctx.break_label = alloc_label(ctx);
1568  if(!stat_ctx.break_label)
1569  return E_OUTOFMEMORY;
1570 
1571  hres = compile_statement(ctx, &stat_ctx, stat->statement);
1572  if(FAILED(hres))
1573  return hres;
1574 
1575  label_set_addr(ctx, stat_ctx.break_label);
1576  return S_OK;
1577 }
1578 
1579 /* ECMA-262 3rd Edition 12.13 */
1581 {
1582  statement_ctx_t stat_ctx = {0, FALSE, FALSE};
1583  unsigned case_cnt = 0, *case_jmps, i, default_jmp;
1584  BOOL have_default = FALSE;
1585  statement_t *stat_iter;
1586  case_clausule_t *iter;
1587  HRESULT hres;
1588 
1589  hres = compile_expression(ctx, stat->expr, TRUE);
1590  if(FAILED(hres))
1591  return hres;
1592 
1593  stat_ctx.break_label = alloc_label(ctx);
1594  if(!stat_ctx.break_label)
1595  return E_OUTOFMEMORY;
1596 
1597  for(iter = stat->case_list; iter; iter = iter->next) {
1598  if(iter->expr)
1599  case_cnt++;
1600  }
1601 
1602  case_jmps = heap_alloc(case_cnt * sizeof(*case_jmps));
1603  if(!case_jmps)
1604  return E_OUTOFMEMORY;
1605 
1606  i = 0;
1607  for(iter = stat->case_list; iter; iter = iter->next) {
1608  if(!iter->expr) {
1609  have_default = TRUE;
1610  continue;
1611  }
1612 
1613  hres = compile_expression(ctx, iter->expr, TRUE);
1614  if(FAILED(hres))
1615  break;
1616 
1617  case_jmps[i] = push_instr(ctx, OP_case);
1618  if(!case_jmps[i]) {
1619  hres = E_OUTOFMEMORY;
1620  break;
1621  }
1622  i++;
1623  }
1624 
1625  if(SUCCEEDED(hres)) {
1626  hres = push_instr_uint(ctx, OP_pop, 1);
1627  if(SUCCEEDED(hres)) {
1628  default_jmp = push_instr(ctx, OP_jmp);
1629  if(!default_jmp)
1630  hres = E_OUTOFMEMORY;
1631  }
1632  }
1633 
1634  if(FAILED(hres)) {
1635  heap_free(case_jmps);
1636  return hres;
1637  }
1638 
1639  i = 0;
1640  for(iter = stat->case_list; iter; iter = iter->next) {
1641  while(iter->next && iter->next->stat == iter->stat) {
1642  set_arg_uint(ctx, iter->expr ? case_jmps[i++] : default_jmp, ctx->code_off);
1643  iter = iter->next;
1644  }
1645 
1646  set_arg_uint(ctx, iter->expr ? case_jmps[i++] : default_jmp, ctx->code_off);
1647 
1648  for(stat_iter = iter->stat; stat_iter && (!iter->next || iter->next->stat != stat_iter);
1649  stat_iter = stat_iter->next) {
1650  hres = compile_statement(ctx, &stat_ctx, stat_iter);
1651  if(FAILED(hres))
1652  break;
1653  }
1654  if(FAILED(hres))
1655  break;
1656  }
1657 
1658  heap_free(case_jmps);
1659  if(FAILED(hres))
1660  return hres;
1661  assert(i == case_cnt);
1662 
1663  if(!have_default) {
1664  hres = push_instr_uint(ctx, OP_jmp, stat_ctx.break_label);
1665  if(FAILED(hres))
1666  return hres;
1667  set_arg_uint(ctx, default_jmp, ctx->code_off);
1668  }
1669 
1670  label_set_addr(ctx, stat_ctx.break_label);
1671  return S_OK;
1672 }
1673 
1674 /* ECMA-262 3rd Edition 12.13 */
1676 {
1677  HRESULT hres;
1678 
1679  hres = compile_expression(ctx, stat->expr, TRUE);
1680  if(FAILED(hres))
1681  return hres;
1682 
1683  return push_instr(ctx, OP_throw) ? S_OK : E_OUTOFMEMORY;
1684 }
1685 
1686 /* ECMA-262 3rd Edition 12.14 */
1688 {
1689  statement_ctx_t try_ctx = {0, FALSE, TRUE}, finally_ctx = {2, FALSE, FALSE};
1690  unsigned push_except, finally_off = 0, catch_off = 0, pop_except, catch_pop_except = 0;
1691  BSTR ident;
1692  HRESULT hres;
1693 
1694  push_except = push_instr(ctx, OP_push_except);
1695  if(!push_except)
1696  return E_OUTOFMEMORY;
1697 
1698  if(stat->catch_block) {
1699  ident = compiler_alloc_bstr(ctx, stat->catch_block->identifier);
1700  if(!ident)
1701  return E_OUTOFMEMORY;
1702  }else {
1703  ident = NULL;
1704  }
1705 
1706  hres = compile_statement(ctx, &try_ctx, stat->try_statement);
1707  if(FAILED(hres))
1708  return hres;
1709 
1710  pop_except = push_instr(ctx, OP_pop_except);
1711  if(!pop_except)
1712  return E_OUTOFMEMORY;
1713 
1714  if(stat->catch_block) {
1715  statement_ctx_t catch_ctx = {0, TRUE, stat->finally_statement != NULL};
1716 
1717  if(stat->finally_statement)
1718  catch_ctx.using_except = TRUE;
1719 
1720  catch_off = ctx->code_off;
1721 
1722  hres = push_instr_bstr(ctx, OP_enter_catch, ident);
1723  if(FAILED(hres))
1724  return hres;
1725 
1726  hres = compile_statement(ctx, &catch_ctx, stat->catch_block->statement);
1727  if(FAILED(hres))
1728  return hres;
1729 
1730  if(!push_instr(ctx, OP_pop_scope))
1731  return E_OUTOFMEMORY;
1732 
1733  if(stat->finally_statement) {
1734  catch_pop_except = push_instr(ctx, OP_pop_except);
1735  if(!catch_pop_except)
1736  return E_OUTOFMEMORY;
1737  }
1738  }
1739 
1740  if(stat->finally_statement) {
1741  /*
1742  * finally block expects two elements on the stack, which may be:
1743  * - (true, return_addr) set by OP_pop_except, OP_end_finally jumps back to passed address
1744  * - (false, exception_value) set when unwinding an exception, which OP_end_finally rethrows
1745  */
1746  finally_off = ctx->code_off;
1747  hres = compile_statement(ctx, &finally_ctx, stat->finally_statement);
1748  if(FAILED(hres))
1749  return hres;
1750 
1751  if(!push_instr(ctx, OP_end_finally))
1752  return E_OUTOFMEMORY;
1753  }
1754 
1755  instr_ptr(ctx, pop_except)->u.arg[0].uint = ctx->code_off;
1756  if(catch_pop_except)
1757  instr_ptr(ctx, catch_pop_except)->u.arg[0].uint = ctx->code_off;
1758  instr_ptr(ctx, push_except)->u.arg[0].uint = catch_off;
1759  instr_ptr(ctx, push_except)->u.arg[1].uint = finally_off;
1760  return S_OK;
1761 }
1762 
1764 {
1765  HRESULT hres;
1766 
1767  if(stat_ctx) {
1768  stat_ctx->next = ctx->stat_ctx;
1769  ctx->stat_ctx = stat_ctx;
1770  }
1771 
1772  switch(stat->type) {
1773  case STAT_BLOCK:
1774  hres = compile_block_statement(ctx, ((block_statement_t*)stat)->stat_list);
1775  break;
1776  case STAT_BREAK:
1778  break;
1779  case STAT_CONTINUE:
1781  break;
1782  case STAT_EMPTY:
1783  /* nothing to do */
1784  hres = S_OK;
1785  break;
1786  case STAT_EXPR:
1788  break;
1789  case STAT_FOR:
1791  break;
1792  case STAT_FORIN:
1794  break;
1795  case STAT_IF:
1797  break;
1798  case STAT_LABEL:
1800  break;
1801  case STAT_RETURN:
1803  break;
1804  case STAT_SWITCH:
1806  break;
1807  case STAT_THROW:
1809  break;
1810  case STAT_TRY:
1812  break;
1813  case STAT_VAR:
1815  break;
1816  case STAT_WHILE:
1818  break;
1819  case STAT_WITH:
1821  break;
1823  }
1824 
1825  if(stat_ctx) {
1826  assert(ctx->stat_ctx == stat_ctx);
1827  ctx->stat_ctx = stat_ctx->next;
1828  }
1829 
1830  return hres;
1831 }
1832 
1833 static int function_local_cmp(const void *key, const struct wine_rb_entry *entry)
1834 {
1836  return strcmpW(key, local->name);
1837 }
1838 
1840 {
1841  struct wine_rb_entry *entry = wine_rb_get(&ctx->locals, name);
1843 }
1844 
1846 {
1848 
1849  local = heap_pool_alloc(&ctx->heap, sizeof(*local));
1850  if(!local)
1851  return FALSE;
1852 
1853  local->name = name;
1854  local->ref = ref;
1855  wine_rb_put(&ctx->locals, name, &local->entry);
1856  ctx->locals_cnt++;
1857  return TRUE;
1858 }
1859 
1861 {
1862  BSTR ident;
1863 
1864  if(find_local(ctx, name))
1865  return TRUE;
1866 
1867  ident = compiler_alloc_bstr(ctx, name);
1868  if(!ident)
1869  return FALSE;
1870 
1871  return alloc_local(ctx, ident, ctx->func->var_cnt++);
1872 }
1873 
1875 {
1876  expr->func_id = ctx->func->func_cnt++;
1877  ctx->func_tail = ctx->func_tail ? (ctx->func_tail->next = expr) : (ctx->func_head = expr);
1878 
1879  return !expr->identifier || expr->event_target || alloc_variable(ctx, expr->identifier)
1880  ? S_OK : E_OUTOFMEMORY;
1881 }
1882 
1884 {
1885  HRESULT hres = S_OK;
1886 
1887  switch(expr->type) {
1888  case EXPR_ADD:
1889  case EXPR_AND:
1890  case EXPR_ARRAY:
1891  case EXPR_ASSIGN:
1892  case EXPR_ASSIGNADD:
1893  case EXPR_ASSIGNAND:
1894  case EXPR_ASSIGNSUB:
1895  case EXPR_ASSIGNMUL:
1896  case EXPR_ASSIGNDIV:
1897  case EXPR_ASSIGNMOD:
1898  case EXPR_ASSIGNOR:
1899  case EXPR_ASSIGNLSHIFT:
1900  case EXPR_ASSIGNRSHIFT:
1901  case EXPR_ASSIGNRRSHIFT:
1902  case EXPR_ASSIGNXOR:
1903  case EXPR_BAND:
1904  case EXPR_BOR:
1905  case EXPR_COMMA:
1906  case EXPR_DIV:
1907  case EXPR_EQ:
1908  case EXPR_EQEQ:
1909  case EXPR_GREATER:
1910  case EXPR_GREATEREQ:
1911  case EXPR_IN:
1912  case EXPR_INSTANCEOF:
1913  case EXPR_LESS:
1914  case EXPR_LESSEQ:
1915  case EXPR_LSHIFT:
1916  case EXPR_MOD:
1917  case EXPR_MUL:
1918  case EXPR_NOTEQ:
1919  case EXPR_NOTEQEQ:
1920  case EXPR_OR:
1921  case EXPR_RSHIFT:
1922  case EXPR_RRSHIFT:
1923  case EXPR_SUB:
1924  case EXPR_BXOR: {
1925  binary_expression_t *binary_expr = (binary_expression_t*)expr;
1926 
1927  hres = visit_expression(ctx, binary_expr->expression1);
1928  if(FAILED(hres))
1929  return hres;
1930 
1931  hres = visit_expression(ctx, binary_expr->expression2);
1932  break;
1933  }
1934  case EXPR_BITNEG:
1935  case EXPR_DELETE:
1936  case EXPR_LOGNEG:
1937  case EXPR_MINUS:
1938  case EXPR_PLUS:
1939  case EXPR_POSTDEC:
1940  case EXPR_POSTINC:
1941  case EXPR_PREDEC:
1942  case EXPR_PREINC:
1943  case EXPR_TYPEOF:
1944  case EXPR_VOID:
1945  hres = visit_expression(ctx, ((unary_expression_t*)expr)->expression);
1946  break;
1947  case EXPR_IDENT:
1948  case EXPR_LITERAL:
1949  case EXPR_THIS:
1950  break;
1951  case EXPR_ARRAYLIT: {
1953  array_element_t *iter;
1954 
1955  for(iter = array_expr->element_list; iter; iter = iter->next) {
1956  hres = visit_expression(ctx, iter->expr);
1957  if(FAILED(hres))
1958  return hres;
1959  }
1960  break;
1961  }
1962  case EXPR_CALL:
1963  case EXPR_NEW: {
1964  call_expression_t *call_expr = (call_expression_t*)expr;
1965  argument_t *arg;
1966 
1967  hres = visit_expression(ctx, call_expr->expression);
1968  if(FAILED(hres))
1969  return hres;
1970 
1971  for(arg = call_expr->argument_list; arg; arg = arg->next) {
1972  hres = visit_expression(ctx, arg->expr);
1973  if(FAILED(hres))
1974  return hres;
1975  }
1976  break;
1977  }
1978  case EXPR_COND: {
1980 
1981  hres = visit_expression(ctx, cond_expr->expression);
1982  if(FAILED(hres))
1983  return hres;
1984 
1985  hres = visit_expression(ctx, cond_expr->true_expression);
1986  if(FAILED(hres))
1987  return hres;
1988 
1989  hres = visit_expression(ctx, cond_expr->false_expression);
1990  break;
1991  }
1992  case EXPR_FUNC:
1994  break;
1995  case EXPR_MEMBER:
1996  hres = visit_expression(ctx, ((member_expression_t*)expr)->expression);
1997  break;
1998  case EXPR_PROPVAL: {
1999  property_definition_t *iter;
2000  for(iter = ((property_value_expression_t*)expr)->property_list; iter; iter = iter->next) {
2001  hres = visit_expression(ctx, iter->value);
2002  if(FAILED(hres))
2003  return hres;
2004  }
2005  break;
2006  }
2008  }
2009 
2010  return hres;
2011 }
2012 
2014 {
2015  variable_declaration_t *iter;
2016  HRESULT hres;
2017 
2018  for(iter = list; iter; iter = iter->next) {
2019  if(!alloc_variable(ctx, iter->identifier))
2020  return E_OUTOFMEMORY;
2021 
2022  if(iter->expr) {
2023  hres = visit_expression(ctx, iter->expr);
2024  if(FAILED(hres))
2025  return hres;
2026  }
2027  }
2028 
2029  return S_OK;
2030 }
2031 
2033 
2035 {
2036  HRESULT hres;
2037 
2038  while(iter) {
2039  hres = visit_statement(ctx, iter);
2040  if(FAILED(hres))
2041  return hres;
2042 
2043  iter = iter->next;
2044  }
2045 
2046  return S_OK;
2047 }
2048 
2050 {
2051  HRESULT hres = S_OK;
2052 
2053  switch(stat->type) {
2054  case STAT_BLOCK:
2055  hres = visit_block_statement(ctx, ((block_statement_t*)stat)->stat_list);
2056  break;
2057  case STAT_BREAK:
2058  case STAT_CONTINUE:
2059  case STAT_EMPTY:
2060  break;
2061  case STAT_EXPR:
2062  case STAT_RETURN:
2063  case STAT_THROW: {
2065  if(expr_stat->expr)
2066  hres = visit_expression(ctx, expr_stat->expr);
2067  break;
2068  }
2069  case STAT_FOR: {
2070  for_statement_t *for_stat = (for_statement_t*)stat;
2071 
2072  if(for_stat->variable_list)
2073  hres = visit_variable_list(ctx, for_stat->variable_list);
2074  else if(for_stat->begin_expr)
2075  hres = visit_expression(ctx, for_stat->begin_expr);
2076  if(FAILED(hres))
2077  break;
2078 
2079  if(for_stat->expr) {
2080  hres = visit_expression(ctx, for_stat->expr);
2081  if(FAILED(hres))
2082  break;
2083  }
2084 
2085  hres = visit_statement(ctx, for_stat->statement);
2086  if(FAILED(hres))
2087  break;
2088 
2089  if(for_stat->end_expr)
2090  hres = visit_expression(ctx, for_stat->end_expr);
2091  break;
2092  }
2093  case STAT_FORIN: {
2094  forin_statement_t *forin_stat = (forin_statement_t*)stat;
2095 
2096  if(forin_stat->variable) {
2097  hres = visit_variable_list(ctx, forin_stat->variable);
2098  if(FAILED(hres))
2099  break;
2100  }
2101 
2102  hres = visit_expression(ctx, forin_stat->in_expr);
2103  if(FAILED(hres))
2104  return hres;
2105 
2106  if(forin_stat->expr) {
2107  hres = visit_expression(ctx, forin_stat->expr);
2108  if(FAILED(hres))
2109  return hres;
2110  }
2111 
2112  hres = visit_statement(ctx, forin_stat->statement);
2113  break;
2114  }
2115  case STAT_IF: {
2116  if_statement_t *if_stat = (if_statement_t*)stat;
2117 
2118  hres = visit_expression(ctx, if_stat->expr);
2119  if(FAILED(hres))
2120  return hres;
2121 
2122  hres = visit_statement(ctx, if_stat->if_stat);
2123  if(FAILED(hres))
2124  return hres;
2125 
2126  if(if_stat->else_stat)
2127  hres = visit_statement(ctx, if_stat->else_stat);
2128  break;
2129  }
2130  case STAT_LABEL:
2131  hres = visit_statement(ctx, ((labelled_statement_t*)stat)->statement);
2132  break;
2133  case STAT_SWITCH: {
2134  switch_statement_t *switch_stat = (switch_statement_t*)stat;
2135  statement_t *stat_iter;
2136  case_clausule_t *iter;
2137 
2138  hres = visit_expression(ctx, switch_stat->expr);
2139  if(FAILED(hres))
2140  return hres;
2141 
2142  for(iter = switch_stat->case_list; iter; iter = iter->next) {
2143  if(!iter->expr)
2144  continue;
2145  hres = visit_expression(ctx, iter->expr);
2146  if(FAILED(hres))
2147  return hres;
2148  }
2149 
2150  for(iter = switch_stat->case_list; iter; iter = iter->next) {
2151  while(iter->next && iter->next->stat == iter->stat)
2152  iter = iter->next;
2153  for(stat_iter = iter->stat; stat_iter && (!iter->next || iter->next->stat != stat_iter);
2154  stat_iter = stat_iter->next) {
2155  hres = visit_statement(ctx, stat_iter);
2156  if(FAILED(hres))
2157  return hres;
2158  }
2159  }
2160  break;
2161  }
2162  case STAT_TRY: {
2163  try_statement_t *try_stat = (try_statement_t*)stat;
2164 
2165  hres = visit_statement(ctx, try_stat->try_statement);
2166  if(FAILED(hres))
2167  return hres;
2168 
2169  if(try_stat->catch_block) {
2170  hres = visit_statement(ctx, try_stat->catch_block->statement);
2171  if(FAILED(hres))
2172  return hres;
2173  }
2174 
2175  if(try_stat->finally_statement)
2176  hres = visit_statement(ctx, try_stat->finally_statement);
2177  break;
2178  }
2179  case STAT_VAR:
2180  hres = visit_variable_list(ctx, ((var_statement_t*)stat)->variable_list);
2181  break;
2182  case STAT_WHILE: {
2183  while_statement_t *while_stat = (while_statement_t*)stat;
2184 
2185  hres = visit_expression(ctx, while_stat->expr);
2186  if(FAILED(hres))
2187  return hres;
2188 
2189  hres = visit_statement(ctx, while_stat->statement);
2190  break;
2191  }
2192  case STAT_WITH: {
2193  with_statement_t *with_stat = (with_statement_t*)stat;
2194 
2195  hres = visit_expression(ctx, with_stat->expr);
2196  if(FAILED(hres))
2197  return hres;
2198 
2199  hres = visit_statement(ctx, with_stat->statement);
2200  break;
2201  }
2203  }
2204 
2205  return hres;
2206 }
2207 
2208 static void resolve_labels(compiler_ctx_t *ctx, unsigned off)
2209 {
2210  instr_t *instr;
2211 
2212  for(instr = ctx->code->instrs+off; instr < ctx->code->instrs+ctx->code_off; instr++) {
2213  if(instr_info[instr->op].arg1_type == ARG_ADDR && (instr->u.arg->uint & LABEL_FLAG)) {
2214  assert((instr->u.arg->uint & ~LABEL_FLAG) < ctx->labels_cnt);
2215  instr->u.arg->uint = ctx->labels[instr->u.arg->uint & ~LABEL_FLAG];
2216  }
2217  assert(instr_info[instr->op].arg2_type != ARG_ADDR);
2218  }
2219 
2220  ctx->labels_cnt = 0;
2221 }
2222 
2224 {
2225  unsigned i;
2226 
2227  if(--code->ref)
2228  return;
2229 
2230  for(i=0; i < code->bstr_cnt; i++)
2231  SysFreeString(code->bstr_pool[i]);
2232  for(i=0; i < code->str_cnt; i++)
2233  jsstr_release(code->str_pool[i]);
2234 
2235  heap_free(code->source);
2236  heap_pool_free(&code->heap);
2237  heap_free(code->bstr_pool);
2238  heap_free(code->str_pool);
2239  heap_free(code->instrs);
2240  heap_free(code);
2241 }
2242 
2243 static HRESULT init_code(compiler_ctx_t *compiler, const WCHAR *source)
2244 {
2245  compiler->code = heap_alloc_zero(sizeof(bytecode_t));
2246  if(!compiler->code)
2247  return E_OUTOFMEMORY;
2248 
2249  compiler->code->ref = 1;
2250  heap_pool_init(&compiler->code->heap);
2251 
2252  compiler->code->source = heap_strdupW(source);
2253  if(!compiler->code->source) {
2254  release_bytecode(compiler->code);
2255  return E_OUTOFMEMORY;
2256  }
2257 
2258  compiler->code->instrs = heap_alloc(64 * sizeof(instr_t));
2259  if(!compiler->code->instrs) {
2260  release_bytecode(compiler->code);
2261  return E_OUTOFMEMORY;
2262  }
2263 
2264  compiler->code_size = 64;
2265  compiler->code_off = 1;
2266  return S_OK;
2267 }
2268 
2270  BOOL from_eval, function_code_t *func)
2271 {
2272  function_expression_t *iter;
2274  unsigned off, i;
2275  HRESULT hres;
2276 
2277  TRACE("\n");
2278 
2279  ctx->func_head = ctx->func_tail = NULL;
2280  ctx->from_eval = from_eval;
2281  ctx->func = func;
2282  ctx->locals_cnt = 0;
2284 
2285  if(func_expr) {
2286  parameter_t *param_iter;
2287 
2288  if(func_expr->identifier) {
2289  func->name = compiler_alloc_bstr(ctx, func_expr->identifier);
2290  if(!func->name)
2291  return E_OUTOFMEMORY;
2292  }
2293 
2294  if(func_expr->event_target) {
2295  func->event_target = compiler_alloc_bstr(ctx, func_expr->event_target);
2296  if(!func->event_target)
2297  return E_OUTOFMEMORY;
2298  }
2299 
2300  func->source = func_expr->src_str;
2301  func->source_len = func_expr->src_len;
2302 
2303  for(param_iter = func_expr->parameter_list; param_iter; param_iter = param_iter->next)
2304  func->param_cnt++;
2305 
2306  func->params = compiler_alloc(ctx->code, func->param_cnt * sizeof(*func->params));
2307  if(!func->params)
2308  return E_OUTOFMEMORY;
2309 
2310  for(param_iter = func_expr->parameter_list, i=0; param_iter; param_iter = param_iter->next, i++) {
2311  func->params[i] = compiler_alloc_bstr(ctx, param_iter->identifier);
2312  if(!func->params[i])
2313  return E_OUTOFMEMORY;
2314  }
2315  }
2316 
2317  for(i = 0; i < func->param_cnt; i++) {
2318  if(!find_local(ctx, func->params[i]) && !alloc_local(ctx, func->params[i], -i-1))
2319  return E_OUTOFMEMORY;
2320  }
2321 
2322  hres = visit_block_statement(ctx, source->statement);
2323  if(FAILED(hres))
2324  return hres;
2325 
2326  func->locals = compiler_alloc(ctx->code, ctx->locals_cnt * sizeof(*func->locals));
2327  if(!func->locals)
2328  return E_OUTOFMEMORY;
2329  func->locals_cnt = ctx->locals_cnt;
2330 
2331  func->variables = compiler_alloc(ctx->code, func->var_cnt * sizeof(*func->variables));
2332  if(!func->variables)
2333  return E_OUTOFMEMORY;
2334 
2335  i = 0;
2337  func->locals[i].name = local->name;
2338  func->locals[i].ref = local->ref;
2339  if(local->ref >= 0) {
2340  func->variables[local->ref].name = local->name;
2341  func->variables[local->ref].func_id = -1;
2342  }
2343  i++;
2344  }
2345  assert(i == ctx->locals_cnt);
2346 
2347  func->funcs = compiler_alloc(ctx->code, func->func_cnt * sizeof(*func->funcs));
2348  if(!func->funcs)
2349  return E_OUTOFMEMORY;
2350  memset(func->funcs, 0, func->func_cnt * sizeof(*func->funcs));
2351 
2352  off = ctx->code_off;
2353  hres = compile_block_statement(ctx, source->statement);
2354  if(FAILED(hres))
2355  return hres;
2356 
2357  resolve_labels(ctx, off);
2358 
2359  hres = push_instr_uint(ctx, OP_ret, !from_eval);
2360  if(FAILED(hres))
2361  return hres;
2362 
2363  if(TRACE_ON(jscript_disas))
2364  dump_code(ctx, off);
2365 
2366  func->instr_off = off;
2367 
2368  for(iter = ctx->func_head, i=0; iter; iter = iter->next, i++) {
2369  hres = compile_function(ctx, iter->source_elements, iter, FALSE, func->funcs+i);
2370  if(FAILED(hres))
2371  return hres;
2372 
2373  TRACE("[%d] func %s\n", i, debugstr_w(func->funcs[i].name));
2374  if(func->funcs[i].name && !func->funcs[i].event_target) {
2375  local_ref_t *local_ref = lookup_local(func, func->funcs[i].name);
2376  func->funcs[i].local_ref = local_ref->ref;
2377  TRACE("found ref %s %d for %s\n", debugstr_w(local_ref->name), local_ref->ref, debugstr_w(func->funcs[i].name));
2378  if(local_ref->ref >= 0)
2379  func->variables[local_ref->ref].func_id = i;
2380  }
2381  }
2382 
2383  assert(i == func->func_cnt);
2384 
2385  return S_OK;
2386 }
2387 
2388 static HRESULT parse_arguments(compiler_ctx_t *ctx, const WCHAR *args, BSTR *arg_array, unsigned *args_size)
2389 {
2390  const WCHAR *ptr = args, *ptr2;
2391  unsigned arg_cnt = 0;
2392 
2393  while(isspaceW(*ptr))
2394  ptr++;
2395  if(!*ptr) {
2396  if(args_size)
2397  *args_size = 0;
2398  return S_OK;
2399  }
2400 
2401  while(1) {
2402  if(!isalphaW(*ptr) && *ptr != '_') {
2403  FIXME("expected alpha or '_': %s\n", debugstr_w(ptr));
2404  return E_FAIL;
2405  }
2406 
2407  ptr2 = ptr;
2408  while(isalnumW(*ptr) || *ptr == '_')
2409  ptr++;
2410 
2411  if(*ptr && *ptr != ',' && !isspaceW(*ptr)) {
2412  FIXME("unexpected har %s\n", debugstr_w(ptr));
2413  return E_FAIL;
2414  }
2415 
2416  if(arg_array) {
2417  arg_array[arg_cnt] = compiler_alloc_bstr_len(ctx, ptr2, ptr-ptr2);
2418  if(!arg_array[arg_cnt])
2419  return E_OUTOFMEMORY;
2420  }
2421  arg_cnt++;
2422 
2423  while(isspaceW(*ptr))
2424  ptr++;
2425  if(!*ptr)
2426  break;
2427  if(*ptr != ',') {
2428  FIXME("expected ',': %s\n", debugstr_w(ptr));
2429  return E_FAIL;
2430  }
2431 
2432  ptr++;
2433  while(isspaceW(*ptr))
2434  ptr++;
2435  }
2436 
2437  if(args_size)
2438  *args_size = arg_cnt;
2439  return S_OK;
2440 }
2441 
2443 {
2444  HRESULT hres;
2445 
2447  if(FAILED(hres))
2448  return hres;
2449 
2450  ctx->code->global_code.params = compiler_alloc(ctx->code,
2451  ctx->code->global_code.param_cnt * sizeof(*ctx->code->global_code.params));
2452  if(!ctx->code->global_code.params)
2453  return E_OUTOFMEMORY;
2454 
2455  return parse_arguments(ctx, args, ctx->code->global_code.params, NULL);
2456 }
2457 
2459  BOOL from_eval, BOOL use_decode, bytecode_t **ret)
2460 {
2461  compiler_ctx_t compiler = {0};
2462  HRESULT hres;
2463 
2464  hres = init_code(&compiler, code);
2465  if(FAILED(hres))
2466  return hres;
2467 
2468  if(args) {
2469  hres = compile_arguments(&compiler, args);
2470  if(FAILED(hres))
2471  return hres;
2472  }
2473 
2474  if(use_decode) {
2475  hres = decode_source(compiler.code->source);
2476  if(FAILED(hres)) {
2477  WARN("Decoding failed\n");
2478  return hres;
2479  }
2480  }
2481 
2482  hres = script_parse(ctx, compiler.code->source, delimiter, from_eval, &compiler.parser);
2483  if(FAILED(hres)) {
2484  release_bytecode(compiler.code);
2485  return hres;
2486  }
2487 
2488  heap_pool_init(&compiler.heap);
2489  hres = compile_function(&compiler, compiler.parser->source, NULL, from_eval, &compiler.code->global_code);
2490  heap_pool_free(&compiler.heap);
2491  parser_release(compiler.parser);
2492  if(FAILED(hres)) {
2493  release_bytecode(compiler.code);
2494  return hres;
2495  }
2496 
2497  *ret = compiler.code;
2498  return S_OK;
2499 }
jsstr_t * jsstr_alloc_len(const WCHAR *buf, unsigned len)
Definition: jsstr.c:86
unsigned break_label
Definition: compile.c:37
static unsigned push_instr(compiler_ctx_t *ctx, jsop_t op)
Definition: compile.c:211
GLenum func
Definition: glext.h:6028
#define DEFAULT_UNREACHABLE
char * name
Definition: wpp.c:36
unsigned bstr_cnt
Definition: engine.h:184
BOOL using_scope
Definition: compile.c:34
#define WINE_RB_FOR_EACH_ENTRY(elem, tree, type, field)
Definition: rbtree.h:154
expression_type_t
Definition: parser.h:216
const WCHAR * identifier
Definition: parser.h:97
struct _function_expression_t * next
Definition: parser.h:301
#define TRUE
Definition: types.h:120
function_code_t global_code
Definition: engine.h:178
static HRESULT push_instr_double(compiler_ctx_t *ctx, jsop_t op, double arg)
Definition: compile.c:318
expression_t * expression
Definition: parser.h:324
static HRESULT compile_throw_statement(compiler_ctx_t *ctx, expression_statement_t *stat)
Definition: compile.c:1675
instr_arg_type_t arg1_type
Definition: compile.c:78
BOOL using_except
Definition: compile.c:35
LOCAL int expr(arg_t *ap, int *altp)
Definition: match.c:512
WINE_UNICODE_INLINE unsigned int strlenW(const WCHAR *str)
Definition: unicode.h:212
expression_t * expression2
Definition: parser.h:307
BSTR WINAPI SysAllocStringLen(const OLECHAR *str, unsigned int len)
Definition: oleaut.c:342
unsigned labels_cnt
Definition: compile.c:62
variable_declaration_t * variable
Definition: parser.h:168
static HRESULT pop_to_stat(compiler_ctx_t *ctx, statement_ctx_t *stat_ctx)
Definition: compile.c:1383
Definition: jsstr.h:39
heap_pool_t heap
Definition: compile.c:73
struct x86_inst instr
expression_t * expr
Definition: parser.h:200
case_clausule_t * case_list
Definition: parser.h:201
static HRESULT compile_statement(compiler_ctx_t *, statement_ctx_t *, statement_t *)
Definition: compile.c:1763
#define JS_E_MISPLACED_RETURN
Definition: jscript.h:548
instr_arg_t arg[2]
Definition: engine.h:129
static HRESULT compile_labelled_statement(compiler_ctx_t *ctx, labelled_statement_t *stat)
Definition: compile.c:1554
void * heap_pool_alloc(heap_pool_t *, DWORD) __WINE_ALLOC_SIZE(2) DECLSPEC_HIDDEN
Definition: jsutils.c:75
struct literal_t::@428::@429 regexp
WINE_UNICODE_INLINE int isspaceW(WCHAR wc)
Definition: unicode.h:165
struct _variable_declaration_t * next
Definition: parser.h:100
static BSTR compiler_alloc_bstr_len(compiler_ctx_t *ctx, const WCHAR *str, size_t len)
Definition: compile.c:199
expression_t * expr
Definition: parser.h:153
static BSTR compiler_alloc_bstr(compiler_ctx_t *ctx, const WCHAR *str)
Definition: compile.c:187
unsigned bstr_pool_size
Definition: engine.h:183
#define WARN(fmt,...)
Definition: debug.h:111
struct _property_definition_t * next
Definition: parser.h:368
static HRESULT compile_unary_expression(compiler_ctx_t *ctx, unary_expression_t *expr, jsop_t op)
Definition: compile.c:362
static void resolve_labels(compiler_ctx_t *ctx, unsigned off)
Definition: compile.c:2208
function_expression_t * func_tail
Definition: compile.c:71
statement_t * if_stat
Definition: parser.h:146
GLdouble n
Definition: glext.h:7729
unsigned * labels
Definition: compile.c:60
static HRESULT compile_new_expression(compiler_ctx_t *ctx, call_expression_t *expr)
Definition: compile.c:587
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
static unsigned jsstr_flush(jsstr_t *str, WCHAR *buf)
Definition: jsstr.h:148
#define assert(x)
Definition: debug.h:53
double dval
Definition: parser.h:82
BSTR * bstr_pool
Definition: engine.h:182
static HRESULT init_code(compiler_ctx_t *compiler, const WCHAR *source)
Definition: compile.c:2243
bytecode_t * code
Definition: compile.c:53
unsigned func_cnt
Definition: engine.h:154
unsigned locals_cnt
Definition: compile.c:65
void * arg
Definition: msvc.h:12
Definition: parser.h:74
static unsigned jsstr_length(jsstr_t *str)
Definition: jsstr.h:58
static void dump_instr_arg(instr_arg_type_t type, instr_arg_t *arg)
Definition: compile.c:86
OLECHAR * BSTR
Definition: compat.h:1934
WINE_DEFAULT_DEBUG_CHANNEL(jscript)
static HRESULT compile_delete_expression(compiler_ctx_t *ctx, unary_expression_t *expr)
Definition: compile.c:657
static void jsstr_release(jsstr_t *str)
Definition: jsstr.h:110
const WCHAR * identifier
Definition: parser.h:293
HRESULT double_to_string(double, jsstr_t **) DECLSPEC_HIDDEN
Definition: jsutils.c:719
static BOOL is_memberid_expr(expression_type_t type)
Definition: compile.c:414
static HRESULT compile_block_statement(compiler_ctx_t *ctx, statement_t *iter)
Definition: compile.c:1110
array_element_t * element_list
Definition: parser.h:359
#define JS_E_LABEL_NOT_FOUND
Definition: jscript.h:552
static HRESULT compile_break_statement(compiler_ctx_t *ctx, branch_statement_t *stat)
Definition: compile.c:1469
#define E_FAIL
Definition: ddrawi.h:102
expression_type_t type
Definition: parser.h:278
Definition: match.c:390
struct _statement_ctx_t statement_ctx_t
Definition: query.h:86
Definition: send.c:47
static void * heap_realloc(void *mem, size_t len)
Definition: appwiz.h:70
static void * heap_alloc(size_t len)
Definition: appwiz.h:65
expression_t * true_expression
Definition: parser.h:318
#define JS_E_INVALID_DELETE
Definition: jscript.h:564
static HRESULT compile_try_statement(compiler_ctx_t *ctx, try_statement_t *stat)
Definition: compile.c:1687
BSTR name
Definition: engine.h:141
static HRESULT compile_member_expression(compiler_ctx_t *ctx, member_expression_t *expr)
Definition: compile.c:374
GLuint GLuint GLuint GLuint GLuint GLuint GLuint arg2
Definition: glext.h:9514
WCHAR * source
Definition: engine.h:180
double dbl
Definition: engine.h:130
const WCHAR * identifier
Definition: parser.h:282
unsigned var_cnt
Definition: engine.h:157
statement_t * next
Definition: parser.h:125
static HRESULT compile_conditional_expression(compiler_ctx_t *ctx, conditional_expression_t *expr)
Definition: compile.c:553
jsstr_t ** str_pool
Definition: engine.h:186
Definition: parser.h:75
const WCHAR * event_target
Definition: parser.h:294
static void dump_code(compiler_ctx_t *ctx, unsigned off)
Definition: compile.c:109
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
struct _statement_ctx_t * next
Definition: compile.c:42
static instr_t * instr_ptr(compiler_ctx_t *ctx, unsigned off)
Definition: compile.c:230
#define JS_E_ILLEGAL_ASSIGN
Definition: jscript.h:560
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
expression_t * expression1
Definition: parser.h:306
unsigned int BOOL
Definition: ntddk_ex.h:94
int type
Definition: query.h:88
static unsigned alloc_label(compiler_ctx_t *ctx)
Definition: compile.c:387
long LONG
Definition: pedump.c:60
expression_t * expr
Definition: parser.h:140
unsigned code_off
Definition: compile.c:57
GLuint GLuint GLuint GLuint arg1
Definition: glext.h:9513
BOOL from_eval
Definition: compile.c:55
static WCHAR * heap_strdupW(const WCHAR *str)
Definition: propsheet.c:178
#define debugstr_w
Definition: kernel32.h:32
static HRESULT compile_binary_expression(compiler_ctx_t *ctx, binary_expression_t *expr, jsop_t op)
Definition: compile.c:347
statement_t * stat
Definition: parser.h:193
unsigned str_cnt
Definition: engine.h:188
statement_t * statement
Definition: parser.h:163
GLenum GLint ref
Definition: glext.h:6028
#define FIXME(fmt,...)
Definition: debug.h:110
source_elements_t * source_elements
Definition: parser.h:296
static PVOID ptr
Definition: dispmode.c:27
expression_t * expr
Definition: parser.h:192
const WCHAR * identifier
Definition: parser.h:325
static BOOL is_loop_statement(statement_type_t type)
Definition: compile.c:1104
LONG lng
Definition: engine.h:110
const WCHAR * str
const WCHAR * wstr
Definition: parser.h:83
static HRESULT compile_variable_list(compiler_ctx_t *ctx, variable_declaration_t *list)
Definition: compile.c:1126
smooth NULL
Definition: ftsmooth.c:416
static HRESULT visit_variable_list(compiler_ctx_t *ctx, variable_declaration_t *list)
Definition: compile.c:2013
static HRESULT compile_object_literal(compiler_ctx_t *ctx, property_value_expression_t *expr)
Definition: compile.c:889
const char * delimiter
Definition: string.c:1523
struct _case_clausule_t * next
Definition: parser.h:195
BSTR WINAPI SysAllocString(LPCOLESTR str)
Definition: oleaut.c:241
jsstr_t * str
Definition: engine.h:111
static HRESULT visit_function_expression(compiler_ctx_t *ctx, function_expression_t *expr)
Definition: compile.c:1874
expression_t * expr
Definition: parser.h:352
statement_type_t type
Definition: parser.h:124
static HRESULT visit_expression(compiler_ctx_t *ctx, expression_t *expr)
Definition: compile.c:1883
#define LABEL_FLAG
Definition: compile.c:385
HRESULT compile_script(script_ctx_t *ctx, const WCHAR *code, const WCHAR *args, const WCHAR *delimiter, BOOL from_eval, BOOL use_decode, bytecode_t **ret)
Definition: compile.c:2458
static HRESULT compile_memberid_expression(compiler_ctx_t *ctx, expression_t *expr, unsigned flags)
Definition: compile.c:453
literal_t * name
Definition: parser.h:365
statement_ctx_t * stat_ctx
Definition: compile.c:67
static BOOL bind_local(compiler_ctx_t *ctx, const WCHAR *identifier, int *ret_ref)
Definition: compile.c:419
#define JS_E_INVALID_BREAK
Definition: jscript.h:549
expression_t * expr
Definition: parser.h:98
static void label_set_addr(compiler_ctx_t *ctx, unsigned label)
Definition: compile.c:408
static HRESULT visit_statement(compiler_ctx_t *, statement_t *)
Definition: compile.c:2049
statement_t * statement
Definition: parser.h:171
static HRESULT emit_identifier_ref(compiler_ctx_t *ctx, const WCHAR *identifier, unsigned flags)
Definition: compile.c:437
_In_ ULONG _In_ ULONG_PTR ident
Definition: winddi.h:3993
static BOOL alloc_local(compiler_ctx_t *ctx, BSTR name, int ref)
Definition: compile.c:1845
static void wine_rb_init(struct wine_rb_tree *tree, wine_rb_compare_func_t compare)
Definition: rbtree.h:179
statement_t * statement
Definition: parser.h:188
unsigned continue_label
Definition: compile.c:38
#define TRACE_(x)
Definition: compat.h:66
void parser_release(parser_ctx_t *) DECLSPEC_HIDDEN
Definition: parser.tab.c:4330
#define ARG_NONE
Definition: amlcode.h:216
#define TRACE(s)
Definition: solgame.cpp:4
const char * debugstr_jsstr(jsstr_t *str)
Definition: jsstr.c:37
GLsizeiptr size
Definition: glext.h:5919
HRESULT hres
Definition: protocol.c:465
function_expression_t * func_head
Definition: compile.c:70
__wchar_t WCHAR
Definition: xmlstorage.h:180
LONG HRESULT
Definition: typedefs.h:77
#define WINE_RB_ENTRY_VALUE(element, type, field)
Definition: rbtree.h:31
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
BOOL bval
Definition: parser.h:84
static HRESULT compile_if_statement(compiler_ctx_t *ctx, if_statement_t *stat)
Definition: compile.c:1175
static HRESULT visit_block_statement(compiler_ctx_t *ctx, statement_t *iter)
Definition: compile.c:2034
static HRESULT compile_while_statement(compiler_ctx_t *ctx, while_statement_t *stat)
Definition: compile.c:1214
const labelled_statement_t * labelled_stat
Definition: compile.c:40
unsigned code_size
Definition: compile.c:58
argument_t * argument_list
Definition: parser.h:337
static HRESULT compile_for_statement(compiler_ctx_t *ctx, for_statement_t *stat)
Definition: compile.c:1265
static HRESULT parse_arguments(compiler_ctx_t *ctx, const WCHAR *args, BSTR *arg_array, unsigned *args_size)
Definition: compile.c:2388
static BOOL alloc_variable(compiler_ctx_t *ctx, const WCHAR *name)
Definition: compile.c:1860
parser_ctx_t * parser
Definition: compile.c:52
static HRESULT push_instr_str(compiler_ctx_t *ctx, jsop_t op, const WCHAR *arg)
Definition: compile.c:248
expression_t * in_expr
Definition: parser.h:170
static HRESULT emit_identifier(compiler_ctx_t *ctx, const WCHAR *identifier)
Definition: compile.c:445
static HRESULT compile_literal(compiler_ctx_t *ctx, literal_t *literal)
Definition: compile.c:804
instr_t * instrs
Definition: engine.h:175
statement_type_t
Definition: parser.h:104
static HRESULT compile_function_expression(compiler_ctx_t *ctx, function_expression_t *expr, BOOL emit_ret)
Definition: compile.c:915
GLbitfield flags
Definition: glext.h:7161
jsop_t op
Definition: engine.h:127
static jsstr_t * compiler_alloc_string_len(compiler_ctx_t *ctx, const WCHAR *str, unsigned len)
Definition: compile.c:133
static HRESULT compile_return_statement(compiler_ctx_t *ctx, expression_statement_t *stat)
Definition: compile.c:1506
unsigned param_cnt
Definition: engine.h:163
static void * compiler_alloc(bytecode_t *code, size_t size)
Definition: compile.c:128
int ret
expression_t * expr
Definition: parser.h:161
struct _array_element_t * next
Definition: parser.h:354
static jsstr_t * compiler_alloc_string(compiler_ctx_t *ctx, const WCHAR *str)
Definition: compile.c:161
jsop_t
Definition: engine.h:101
union literal_t::@428 u
Definition: stat.h:55
uint32_t entry
Definition: isohybrid.c:63
static HRESULT push_instr_bstr_uint(compiler_ctx_t *ctx, jsop_t op, const WCHAR *arg1, unsigned arg2)
Definition: compile.c:282
GLenum GLsizei len
Definition: glext.h:6722
statement_t * try_statement
Definition: parser.h:211
unsigned labels_size
Definition: compile.c:61
Definition: _list.h:228
UINT WINAPI SysStringLen(BSTR str)
Definition: oleaut.c:199
const WCHAR * identifier
Definition: parser.h:187
local_ref_t * lookup_local(const function_code_t *function, const WCHAR *identifier)
Definition: engine.c:627
static function_local_t * find_local(compiler_ctx_t *ctx, const WCHAR *name)
Definition: compile.c:1839
const WCHAR * identifier
Definition: parser.h:342
static HRESULT compile_arguments(compiler_ctx_t *ctx, const WCHAR *args)
Definition: compile.c:2442
struct _parameter_t * next
Definition: parser.h:283
uint8_t label[11]
Definition: fsck.fat.h:65
void heap_pool_init(heap_pool_t *) DECLSPEC_HIDDEN
Definition: jsutils.c:69
#define debugstr_wn
Definition: kernel32.h:33
WINE_UNICODE_INLINE int isalnumW(WCHAR wc)
Definition: unicode.h:190
statement_t * else_stat
Definition: parser.h:147
literal_type_t type
Definition: parser.h:80
#define local
Definition: zutil.h:30
static void set_arg_uint(compiler_ctx_t *ctx, unsigned instr, unsigned arg)
Definition: compile.c:330
static HRESULT compile_increment_expression(compiler_ctx_t *ctx, unary_expression_t *expr, jsop_t op, int n)
Definition: compile.c:499
static HRESULT push_instr_uint(compiler_ctx_t *ctx, jsop_t op, unsigned arg)
Definition: compile.c:335
static HRESULT push_instr_uint_str(compiler_ctx_t *ctx, jsop_t op, unsigned arg1, const WCHAR *arg2)
Definition: compile.c:300
parameter_t * parameter_list
Definition: parser.h:295
static HRESULT compile_with_statement(compiler_ctx_t *ctx, with_statement_t *stat)
Definition: compile.c:1531
#define S_OK
Definition: intsafe.h:59
static unsigned arg_cnt(const DISPPARAMS *dp)
Definition: vbscript.h:166
static HRESULT literal_as_bstr(compiler_ctx_t *ctx, literal_t *literal, BSTR *str)
Definition: compile.c:836
expression_t * expression
Definition: parser.h:336
statement_t * statement
Definition: parser.h:182
static HRESULT compile_call_expression(compiler_ctx_t *ctx, call_expression_t *expr, BOOL emit_ret)
Definition: compile.c:615
HRESULT decode_source(WCHAR *code)
Definition: decode.c:111
struct wine_rb_tree locals
Definition: compile.c:64
LONG ref
Definition: engine.h:173
#define JS_E_LABEL_REDEFINED
Definition: jscript.h:551
#define JS_E_INVALID_CONTINUE
Definition: jscript.h:550
Definition: rbtree.h:35
expression_t * expr
Definition: parser.h:169
#define E_NOTIMPL
Definition: ddrawi.h:99
union instr_t::@422 u
static int wine_rb_put(struct wine_rb_tree *tree, const void *key, struct wine_rb_entry *entry)
Definition: rbtree.h:215
BSTR bstr
Definition: engine.h:109
instr_arg_type_t
Definition: engine.h:115
static HRESULT compile_continue_statement(compiler_ctx_t *ctx, branch_statement_t *stat)
Definition: compile.c:1416
void WINAPI DECLSPEC_HOTPATCH SysFreeString(BSTR str)
Definition: oleaut.c:274
variable_declaration_t * variable_list
Definition: parser.h:159
expression_t * end_expr
Definition: parser.h:162
#define OP_LIST
Definition: engine.h:21
static HRESULT compile_typeof_expression(compiler_ctx_t *ctx, unary_expression_t *expr)
Definition: compile.c:783
static int function_local_cmp(const void *key, const struct wine_rb_entry *entry)
Definition: compile.c:1833
catch_block_t * catch_block
Definition: parser.h:212
static HRESULT compile_switch_statement(compiler_ctx_t *ctx, switch_statement_t *stat)
Definition: compile.c:1580
static HRESULT push_instr_int(compiler_ctx_t *ctx, jsop_t op, LONG arg)
Definition: compile.c:236
const WCHAR * src_str
Definition: parser.h:297
static HRESULT compile_var_statement(compiler_ctx_t *ctx, var_statement_t *stat)
Definition: compile.c:1157
static HRESULT push_instr_bstr(compiler_ctx_t *ctx, jsop_t op, const WCHAR *arg)
Definition: compile.c:265
static HRESULT compile_assign_expression(compiler_ctx_t *ctx, binary_expression_t *expr, jsop_t op)
Definition: compile.c:711
static HRESULT compile_expression_statement(compiler_ctx_t *ctx, expression_statement_t *stat)
Definition: compile.c:1163
heap_pool_t heap
Definition: engine.h:176
void heap_pool_free(heap_pool_t *) DECLSPEC_HIDDEN
Definition: jsutils.c:167
void release_bytecode(bytecode_t *code)
Definition: compile.c:2223
static HRESULT compile_logical_expression(compiler_ctx_t *ctx, binary_expression_t *expr, jsop_t op)
Definition: compile.c:531
static HRESULT compile_array_literal(compiler_ctx_t *ctx, array_literal_expression_t *expr)
Definition: compile.c:862
instr_arg_type_t arg2_type
Definition: compile.c:79
Definition: name.c:36
WINE_UNICODE_INLINE int strcmpW(const WCHAR *str1, const WCHAR *str2)
Definition: unicode.h:229
static struct wine_rb_entry * wine_rb_get(const struct wine_rb_tree *tree, const void *key)
Definition: rbtree.h:203
static HRESULT compile_expression(compiler_ctx_t *, expression_t *, BOOL)
Definition: compile.c:920
expression_t * expr
Definition: parser.h:181
static HRESULT compile_function(compiler_ctx_t *ctx, source_elements_t *source, function_expression_t *func_expr, BOOL from_eval, function_code_t *func)
Definition: compile.c:2269
const char * op_str
Definition: compile.c:77
unsigned uint
Definition: engine.h:112
static HRESULT compile_forin_statement(compiler_ctx_t *ctx, forin_statement_t *stat)
Definition: compile.c:1322
UINT op
Definition: effect.c:223
expression_t * begin_expr
Definition: parser.h:160
WINE_UNICODE_INLINE int isalphaW(WCHAR wc)
Definition: unicode.h:195
statement_t * finally_statement
Definition: parser.h:213
BSTR * params
Definition: engine.h:164
statement_t * statement
Definition: parser.h:206
unsigned stack_use
Definition: compile.c:33
#define memset(x, y, z)
Definition: compat.h:39
static jsval_t stack_pop(script_ctx_t *ctx)
Definition: engine.c:127
HRESULT script_parse(script_ctx_t *, const WCHAR *, const WCHAR *, BOOL, parser_ctx_t **) DECLSPEC_HIDDEN
Definition: parser.tab.c:4337
#define TRACE_ON(x)
Definition: compat.h:65
#define args
Definition: format.c:66
expression_t * false_expression
Definition: parser.h:319
unsigned str_pool_size
Definition: engine.h:187
int ref
Definition: engine.h:142
expression_t * expression
Definition: parser.h:317
#define SUCCEEDED(hr)
Definition: intsafe.h:57
expression_t * value
Definition: parser.h:366
Definition: path.c:42
static BOOL heap_free(void *mem)
Definition: appwiz.h:75
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
expression_t * expr
Definition: parser.h:145
WINE_DECLARE_DEBUG_CHANNEL(jscript_disas)
off
Definition: i386-dis.c:3909
function_code_t * func
Definition: compile.c:68
statement_t * statement
Definition: parser.h:154
static BOOL ensure_bstr_slot(compiler_ctx_t *ctx)
Definition: compile.c:166
static HRESULT compile_comma_expression(compiler_ctx_t *ctx, binary_expression_t *expr, BOOL emit_ret)
Definition: compile.c:519
GLuint const GLchar * name
Definition: glext.h:6031