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