ReactOS  0.4.14-dev-337-gf981a68
compile.c File Reference
#include <math.h>
#include <assert.h>
#include "jscript.h"
#include "engine.h"
#include "parser.h"
#include "wine/rbtree.h"
#include "wine/debug.h"
Include dependency graph for compile.c:

Go to the source code of this file.

Classes

struct  _statement_ctx_t
 
struct  function_local_t
 
struct  _compiler_ctx_t
 

Macros

#define X(n, a, b, c)   {#n,b,c},
 
#define LABEL_FLAG   0x80000000
 

Typedefs

typedef struct _statement_ctx_t statement_ctx_t
 
typedef struct _compiler_ctx_t compiler_ctx_t
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (jscript)
 
 WINE_DECLARE_DEBUG_CHANNEL (jscript_disas)
 
static void dump_instr_arg (instr_arg_type_t type, instr_arg_t *arg)
 
static void dump_code (compiler_ctx_t *ctx, unsigned off)
 
static HRESULT compile_expression (compiler_ctx_t *, expression_t *, BOOL)
 
static HRESULT compile_statement (compiler_ctx_t *, statement_ctx_t *, statement_t *)
 
static voidcompiler_alloc (bytecode_t *code, size_t size)
 
jsstr_tcompiler_alloc_string_len (compiler_ctx_t *ctx, const WCHAR *str, unsigned len)
 
static jsstr_tcompiler_alloc_string (compiler_ctx_t *ctx, const WCHAR *str)
 
static BOOL ensure_bstr_slot (compiler_ctx_t *ctx)
 
static BSTR compiler_alloc_bstr (compiler_ctx_t *ctx, const WCHAR *str)
 
static BSTR compiler_alloc_bstr_len (compiler_ctx_t *ctx, const WCHAR *str, size_t len)
 
static unsigned push_instr (compiler_ctx_t *ctx, jsop_t op)
 
static instr_tinstr_ptr (compiler_ctx_t *ctx, unsigned off)
 
static HRESULT push_instr_int (compiler_ctx_t *ctx, jsop_t op, LONG arg)
 
static HRESULT push_instr_str (compiler_ctx_t *ctx, jsop_t op, jsstr_t *str)
 
static HRESULT push_instr_str_uint (compiler_ctx_t *ctx, jsop_t op, jsstr_t *str, unsigned arg2)
 
static HRESULT push_instr_bstr (compiler_ctx_t *ctx, jsop_t op, const WCHAR *arg)
 
static HRESULT push_instr_bstr_uint (compiler_ctx_t *ctx, jsop_t op, const WCHAR *arg1, unsigned arg2)
 
static HRESULT push_instr_uint_str (compiler_ctx_t *ctx, jsop_t op, unsigned arg1, const WCHAR *arg2)
 
static HRESULT push_instr_double (compiler_ctx_t *ctx, jsop_t op, double arg)
 
static void set_arg_uint (compiler_ctx_t *ctx, unsigned instr, unsigned arg)
 
static HRESULT push_instr_uint (compiler_ctx_t *ctx, jsop_t op, unsigned arg)
 
static HRESULT compile_binary_expression (compiler_ctx_t *ctx, binary_expression_t *expr, jsop_t op)
 
static HRESULT compile_unary_expression (compiler_ctx_t *ctx, unary_expression_t *expr, jsop_t op)
 
static HRESULT compile_member_expression (compiler_ctx_t *ctx, member_expression_t *expr)
 
static unsigned alloc_label (compiler_ctx_t *ctx)
 
static void label_set_addr (compiler_ctx_t *ctx, unsigned label)
 
static BOOL is_memberid_expr (expression_type_t type)
 
static BOOL bind_local (compiler_ctx_t *ctx, const WCHAR *identifier, int *ret_ref)
 
static HRESULT emit_identifier_ref (compiler_ctx_t *ctx, const WCHAR *identifier, unsigned flags)
 
static HRESULT emit_identifier (compiler_ctx_t *ctx, const WCHAR *identifier)
 
static HRESULT compile_memberid_expression (compiler_ctx_t *ctx, expression_t *expr, unsigned flags)
 
static HRESULT compile_increment_expression (compiler_ctx_t *ctx, unary_expression_t *expr, jsop_t op, int n)
 
static HRESULT compile_comma_expression (compiler_ctx_t *ctx, binary_expression_t *expr, BOOL emit_ret)
 
static HRESULT compile_logical_expression (compiler_ctx_t *ctx, binary_expression_t *expr, jsop_t op)
 
static HRESULT compile_conditional_expression (compiler_ctx_t *ctx, conditional_expression_t *expr)
 
static HRESULT compile_new_expression (compiler_ctx_t *ctx, call_expression_t *expr)
 
static HRESULT compile_call_expression (compiler_ctx_t *ctx, call_expression_t *expr, BOOL emit_ret)
 
static HRESULT compile_delete_expression (compiler_ctx_t *ctx, unary_expression_t *expr)
 
static HRESULT compile_assign_expression (compiler_ctx_t *ctx, binary_expression_t *expr, jsop_t op)
 
static HRESULT compile_typeof_expression (compiler_ctx_t *ctx, unary_expression_t *expr)
 
static HRESULT compile_literal (compiler_ctx_t *ctx, literal_t *literal)
 
static HRESULT literal_as_string (compiler_ctx_t *ctx, literal_t *literal, jsstr_t **str)
 
static HRESULT compile_array_literal (compiler_ctx_t *ctx, array_literal_expression_t *expr)
 
static HRESULT compile_object_literal (compiler_ctx_t *ctx, property_value_expression_t *expr)
 
static HRESULT compile_function_expression (compiler_ctx_t *ctx, function_expression_t *expr, BOOL emit_ret)
 
static BOOL is_loop_statement (statement_type_t type)
 
static HRESULT compile_block_statement (compiler_ctx_t *ctx, statement_t *iter)
 
static HRESULT compile_variable_list (compiler_ctx_t *ctx, variable_declaration_t *list)
 
static HRESULT compile_var_statement (compiler_ctx_t *ctx, var_statement_t *stat)
 
static HRESULT compile_expression_statement (compiler_ctx_t *ctx, expression_statement_t *stat)
 
static HRESULT compile_if_statement (compiler_ctx_t *ctx, if_statement_t *stat)
 
static HRESULT compile_while_statement (compiler_ctx_t *ctx, while_statement_t *stat)
 
static HRESULT compile_for_statement (compiler_ctx_t *ctx, for_statement_t *stat)
 
static HRESULT compile_forin_statement (compiler_ctx_t *ctx, forin_statement_t *stat)
 
static HRESULT pop_to_stat (compiler_ctx_t *ctx, statement_ctx_t *stat_ctx)
 
static HRESULT compile_continue_statement (compiler_ctx_t *ctx, branch_statement_t *stat)
 
static HRESULT compile_break_statement (compiler_ctx_t *ctx, branch_statement_t *stat)
 
static HRESULT compile_return_statement (compiler_ctx_t *ctx, expression_statement_t *stat)
 
static HRESULT compile_with_statement (compiler_ctx_t *ctx, with_statement_t *stat)
 
static HRESULT compile_labelled_statement (compiler_ctx_t *ctx, labelled_statement_t *stat)
 
static HRESULT compile_switch_statement (compiler_ctx_t *ctx, switch_statement_t *stat)
 
static HRESULT compile_throw_statement (compiler_ctx_t *ctx, expression_statement_t *stat)
 
static HRESULT compile_try_statement (compiler_ctx_t *ctx, try_statement_t *stat)
 
static int function_local_cmp (const void *key, const struct wine_rb_entry *entry)
 
static function_local_tfind_local (compiler_ctx_t *ctx, const WCHAR *name)
 
static BOOL alloc_local (compiler_ctx_t *ctx, BSTR name, int ref)
 
static BOOL alloc_variable (compiler_ctx_t *ctx, const WCHAR *name)
 
static HRESULT visit_function_expression (compiler_ctx_t *ctx, function_expression_t *expr)
 
static HRESULT visit_expression (compiler_ctx_t *ctx, expression_t *expr)
 
static HRESULT visit_variable_list (compiler_ctx_t *ctx, variable_declaration_t *list)
 
static HRESULT visit_statement (compiler_ctx_t *, statement_t *)
 
static HRESULT visit_block_statement (compiler_ctx_t *ctx, statement_t *iter)
 
static void resolve_labels (compiler_ctx_t *ctx, unsigned off)
 
void release_bytecode (bytecode_t *code)
 
static HRESULT init_code (compiler_ctx_t *compiler, const WCHAR *source)
 
static HRESULT compile_function (compiler_ctx_t *ctx, source_elements_t *source, function_expression_t *func_expr, BOOL from_eval, function_code_t *func)
 
static HRESULT parse_arguments (compiler_ctx_t *ctx, const WCHAR *args, BSTR *arg_array, unsigned *args_size)
 
static HRESULT compile_arguments (compiler_ctx_t *ctx, const WCHAR *args)
 
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)
 

Variables

struct {
   const char *   op_str
 
   instr_arg_type_t   arg1_type
 
   instr_arg_type_t   arg2_type
 
instr_info []
 

Macro Definition Documentation

◆ LABEL_FLAG

#define LABEL_FLAG   0x80000000

Definition at line 393 of file compile.c.

◆ X

#define X (   n,
  a,
  b,
  c 
)    {#n,b,c},

Typedef Documentation

◆ compiler_ctx_t

◆ statement_ctx_t

Function Documentation

◆ alloc_label()

static unsigned alloc_label ( compiler_ctx_t ctx)
static

Definition at line 395 of file compile.c.

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 }
unsigned labels_size
Definition: compile.c:61
static void * heap_realloc(void *mem, size_t len)
Definition: appwiz.h:70
static void * heap_alloc(size_t len)
Definition: appwiz.h:65
#define LABEL_FLAG
Definition: compile.c:393
unsigned labels_cnt
Definition: compile.c:62
unsigned * labels
Definition: compile.c:60

Referenced by compile_for_statement(), compile_forin_statement(), compile_labelled_statement(), compile_switch_statement(), and compile_while_statement().

◆ alloc_local()

static BOOL alloc_local ( compiler_ctx_t ctx,
BSTR  name,
int  ref 
)
static

Definition at line 1848 of file compile.c.

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 }
unsigned locals_cnt
Definition: compile.c:65
#define TRUE
Definition: types.h:120
void * heap_pool_alloc(heap_pool_t *, DWORD) __WINE_ALLOC_SIZE(2) DECLSPEC_HIDDEN
Definition: jsutils.c:77
GLenum GLint ref
Definition: glext.h:6028
char * name
Definition: compiler.c:66
#define local
Definition: zutil.h:30
static int wine_rb_put(struct wine_rb_tree *tree, const void *key, struct wine_rb_entry *entry)
Definition: rbtree.h:215
struct wine_rb_tree locals
Definition: compile.c:64
Definition: name.c:36
heap_pool_t heap
Definition: compile.c:73
GLuint const GLchar * name
Definition: glext.h:6031

Referenced by alloc_variable(), and compile_function().

◆ alloc_variable()

static BOOL alloc_variable ( compiler_ctx_t ctx,
const WCHAR name 
)
static

Definition at line 1863 of file compile.c.

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 }
#define TRUE
Definition: types.h:120
static BSTR compiler_alloc_bstr(compiler_ctx_t *ctx, const WCHAR *str)
Definition: compile.c:187
OLECHAR * BSTR
Definition: compat.h:1942
unsigned var_cnt
Definition: engine.h:157
function_code_t * func
Definition: compile.c:68
_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 function_local_t * find_local(compiler_ctx_t *ctx, const WCHAR *name)
Definition: compile.c:1842
Definition: name.c:36

Referenced by visit_function_expression(), and visit_variable_list().

◆ bind_local()

static BOOL bind_local ( compiler_ctx_t ctx,
const WCHAR identifier,
int ret_ref 
)
static

Definition at line 427 of file compile.c.

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 }
BOOL using_scope
Definition: compile.c:34
#define TRUE
Definition: types.h:120
statement_ctx_t * stat_ctx
Definition: compile.c:67
Definition: send.c:47
function_code_t * func
Definition: compile.c:68
struct _statement_ctx_t * next
Definition: compile.c:42
GLenum GLint ref
Definition: glext.h:6028
local_ref_t * lookup_local(const function_code_t *function, const WCHAR *identifier)
Definition: engine.c:629

Referenced by emit_identifier(), and emit_identifier_ref().

◆ compile_arguments()

static HRESULT compile_arguments ( compiler_ctx_t ctx,
const WCHAR args 
)
static

Definition at line 2445 of file compile.c.

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 }
function_code_t global_code
Definition: engine.h:178
Definition: match.c:390
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
smooth NULL
Definition: ftsmooth.c:416
HRESULT hres
Definition: protocol.c:465
LONG HRESULT
Definition: typedefs.h:77
static HRESULT parse_arguments(compiler_ctx_t *ctx, const WCHAR *args, BSTR *arg_array, unsigned *args_size)
Definition: compile.c:2391
static void * compiler_alloc(bytecode_t *code, size_t size)
Definition: compile.c:128
unsigned param_cnt
Definition: engine.h:163
BSTR * params
Definition: engine.h:164
bytecode_t * code
Definition: compile.c:53

Referenced by compile_script().

◆ compile_array_literal()

static HRESULT compile_array_literal ( compiler_ctx_t ctx,
array_literal_expression_t expr 
)
static

Definition at line 865 of file compile.c.

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 }
static unsigned push_instr(compiler_ctx_t *ctx, jsop_t op)
Definition: compile.c:211
#define TRUE
Definition: types.h:120
instr_arg_t arg[2]
Definition: engine.h:129
Definition: query.h:86
static instr_t * instr_ptr(compiler_ctx_t *ctx, unsigned off)
Definition: compile.c:230
expression_t * expr
Definition: parser.h:352
HRESULT hres
Definition: protocol.c:465
LONG HRESULT
Definition: typedefs.h:77
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
struct _array_element_t * next
Definition: parser.h:354
static HRESULT push_instr_uint(compiler_ctx_t *ctx, jsop_t op, unsigned arg)
Definition: compile.c:343
#define S_OK
Definition: intsafe.h:59
static HRESULT compile_expression(compiler_ctx_t *, expression_t *, BOOL)
Definition: compile.c:923
unsigned uint
Definition: engine.h:112
union instr_t::@423 u

Referenced by compile_expression().

◆ compile_assign_expression()

static HRESULT compile_assign_expression ( compiler_ctx_t ctx,
binary_expression_t expr,
jsop_t  op 
)
static

Definition at line 729 of file compile.c.

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 }
static unsigned push_instr(compiler_ctx_t *ctx, jsop_t op)
Definition: compile.c:211
#define TRUE
Definition: types.h:120
struct x86_inst instr
instr_arg_t arg[2]
Definition: engine.h:129
static BOOL is_memberid_expr(expression_type_t type)
Definition: compile.c:422
expression_type_t type
Definition: parser.h:278
Definition: query.h:86
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
unsigned int BOOL
Definition: ntddk_ex.h:94
int type
Definition: query.h:88
LONG lng
Definition: engine.h:110
static HRESULT compile_memberid_expression(compiler_ctx_t *ctx, expression_t *expr, unsigned flags)
Definition: compile.c:461
HRESULT hres
Definition: protocol.c:465
LONG HRESULT
Definition: typedefs.h:77
argument_t * argument_list
Definition: parser.h:337
static HRESULT push_instr_uint(compiler_ctx_t *ctx, jsop_t op, unsigned arg)
Definition: compile.c:343
#define S_OK
Definition: intsafe.h:59
static unsigned arg_cnt(const DISPPARAMS *dp)
Definition: vbscript.h:166
expression_t * expression
Definition: parser.h:336
static HRESULT compile_expression(compiler_ctx_t *, expression_t *, BOOL)
Definition: compile.c:923
unsigned uint
Definition: engine.h:112
UINT op
Definition: effect.c:223
union instr_t::@423 u

Referenced by compile_expression().

◆ compile_binary_expression()

static HRESULT compile_binary_expression ( compiler_ctx_t ctx,
binary_expression_t expr,
jsop_t  op 
)
static

Definition at line 355 of file compile.c.

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 }
static unsigned push_instr(compiler_ctx_t *ctx, jsop_t op)
Definition: compile.c:211
#define TRUE
Definition: types.h:120
Definition: query.h:86
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
HRESULT hres
Definition: protocol.c:465
LONG HRESULT
Definition: typedefs.h:77
#define S_OK
Definition: intsafe.h:59
static HRESULT compile_expression(compiler_ctx_t *, expression_t *, BOOL)
Definition: compile.c:923
UINT op
Definition: effect.c:223

Referenced by compile_expression().

◆ compile_block_statement()

static HRESULT compile_block_statement ( compiler_ctx_t ctx,
statement_t iter 
)
static

Definition at line 1113 of file compile.c.

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 }
static HRESULT compile_statement(compiler_ctx_t *, statement_ctx_t *, statement_t *)
Definition: compile.c:1766
statement_t * next
Definition: parser.h:125
smooth NULL
Definition: ftsmooth.c:416
HRESULT hres
Definition: protocol.c:465
LONG HRESULT
Definition: typedefs.h:77
#define S_OK
Definition: intsafe.h:59

Referenced by compile_function(), and compile_statement().

◆ compile_break_statement()

static HRESULT compile_break_statement ( compiler_ctx_t ctx,
branch_statement_t stat 
)
static

Definition at line 1472 of file compile.c.

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 }
unsigned break_label
Definition: compile.c:37
static HRESULT pop_to_stat(compiler_ctx_t *ctx, statement_ctx_t *stat_ctx)
Definition: compile.c:1386
#define WARN(fmt,...)
Definition: debug.h:111
#define assert(x)
Definition: debug.h:53
statement_ctx_t * stat_ctx
Definition: compile.c:67
#define JS_E_LABEL_NOT_FOUND
Definition: jscript.h:548
struct _statement_ctx_t * next
Definition: compile.c:42
#define JS_E_INVALID_BREAK
Definition: jscript.h:545
HRESULT hres
Definition: protocol.c:465
LONG HRESULT
Definition: typedefs.h:77
const labelled_statement_t * labelled_stat
Definition: compile.c:40
Definition: stat.h:55
const WCHAR * identifier
Definition: parser.h:187
static HRESULT push_instr_uint(compiler_ctx_t *ctx, jsop_t op, unsigned arg)
Definition: compile.c:343
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)

Referenced by compile_statement().

◆ compile_call_expression()

static HRESULT compile_call_expression ( compiler_ctx_t ctx,
call_expression_t expr,
BOOL  emit_ret 
)
static

Definition at line 628 of file compile.c.

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 }
static unsigned push_instr(compiler_ctx_t *ctx, jsop_t op)
Definition: compile.c:211
#define TRUE
Definition: types.h:120
struct x86_inst instr
instr_arg_t arg[2]
Definition: engine.h:129
void * arg
Definition: msvc.h:12
static BOOL is_memberid_expr(expression_type_t type)
Definition: compile.c:422
Definition: query.h:86
static instr_t * instr_ptr(compiler_ctx_t *ctx, unsigned off)
Definition: compile.c:230
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
int type
Definition: query.h:88
LONG lng
Definition: engine.h:110
static HRESULT compile_memberid_expression(compiler_ctx_t *ctx, expression_t *expr, unsigned flags)
Definition: compile.c:461
HRESULT hres
Definition: protocol.c:465
LONG HRESULT
Definition: typedefs.h:77
jsop_t
Definition: engine.h:101
static HRESULT push_instr_uint(compiler_ctx_t *ctx, jsop_t op, unsigned arg)
Definition: compile.c:343
#define S_OK
Definition: intsafe.h:59
static unsigned arg_cnt(const DISPPARAMS *dp)
Definition: vbscript.h:166
static HRESULT compile_expression(compiler_ctx_t *, expression_t *, BOOL)
Definition: compile.c:923
unsigned uint
Definition: engine.h:112
UINT op
Definition: effect.c:223
union instr_t::@423 u

Referenced by compile_expression().

◆ compile_comma_expression()

static HRESULT compile_comma_expression ( compiler_ctx_t ctx,
binary_expression_t expr,
BOOL  emit_ret 
)
static

Definition at line 532 of file compile.c.

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 }
Definition: query.h:86
HRESULT hres
Definition: protocol.c:465
LONG HRESULT
Definition: typedefs.h:77
static HRESULT compile_expression(compiler_ctx_t *, expression_t *, BOOL)
Definition: compile.c:923

Referenced by compile_expression().

◆ compile_conditional_expression()

static HRESULT compile_conditional_expression ( compiler_ctx_t ctx,
conditional_expression_t expr 
)
static

Definition at line 566 of file compile.c.

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 }
static unsigned push_instr(compiler_ctx_t *ctx, jsop_t op)
Definition: compile.c:211
#define TRUE
Definition: types.h:120
Definition: query.h:86
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
unsigned code_off
Definition: compile.c:57
HRESULT hres
Definition: protocol.c:465
LONG HRESULT
Definition: typedefs.h:77
static void set_arg_uint(compiler_ctx_t *ctx, unsigned instr, unsigned arg)
Definition: compile.c:338
static HRESULT push_instr_uint(compiler_ctx_t *ctx, jsop_t op, unsigned arg)
Definition: compile.c:343
#define S_OK
Definition: intsafe.h:59
static HRESULT compile_expression(compiler_ctx_t *, expression_t *, BOOL)
Definition: compile.c:923

Referenced by compile_expression().

◆ compile_continue_statement()

static HRESULT compile_continue_statement ( compiler_ctx_t ctx,
branch_statement_t stat 
)
static

Definition at line 1419 of file compile.c.

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 }
static HRESULT pop_to_stat(compiler_ctx_t *ctx, statement_ctx_t *stat_ctx)
Definition: compile.c:1386
#define WARN(fmt,...)
Definition: debug.h:111
#define assert(x)
Definition: debug.h:53
statement_ctx_t * stat_ctx
Definition: compile.c:67
#define JS_E_LABEL_NOT_FOUND
Definition: jscript.h:548
struct _statement_ctx_t * next
Definition: compile.c:42
static BOOL is_loop_statement(statement_type_t type)
Definition: compile.c:1107
smooth NULL
Definition: ftsmooth.c:416
statement_type_t type
Definition: parser.h:124
statement_t * statement
Definition: parser.h:188
unsigned continue_label
Definition: compile.c:38
HRESULT hres
Definition: protocol.c:465
LONG HRESULT
Definition: typedefs.h:77
const labelled_statement_t * labelled_stat
Definition: compile.c:40
Definition: stat.h:55
const WCHAR * identifier
Definition: parser.h:187
static HRESULT push_instr_uint(compiler_ctx_t *ctx, jsop_t op, unsigned arg)
Definition: compile.c:343
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
#define JS_E_INVALID_CONTINUE
Definition: jscript.h:546

Referenced by compile_statement().

◆ compile_delete_expression()

static HRESULT compile_delete_expression ( compiler_ctx_t ctx,
unary_expression_t expr 
)
static

Definition at line 670 of file compile.c.

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 }
static unsigned push_instr(compiler_ctx_t *ctx, jsop_t op)
Definition: compile.c:211
#define TRUE
Definition: types.h:120
expression_t * expression
Definition: parser.h:324
expression_t * expression2
Definition: parser.h:307
Definition: jsstr.h:39
#define WARN(fmt,...)
Definition: debug.h:111
Definition: query.h:86
#define JS_E_INVALID_DELETE
Definition: jscript.h:560
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
expression_t * expression1
Definition: parser.h:306
int type
Definition: query.h:88
const WCHAR * identifier
Definition: parser.h:325
static HRESULT push_instr_str(compiler_ctx_t *ctx, jsop_t op, jsstr_t *str)
Definition: compile.c:248
HRESULT hres
Definition: protocol.c:465
__wchar_t WCHAR
Definition: xmlstorage.h:180
LONG HRESULT
Definition: typedefs.h:77
static jsstr_t * compiler_alloc_string(compiler_ctx_t *ctx, const WCHAR *str)
Definition: compile.c:161
static HRESULT push_instr_uint_str(compiler_ctx_t *ctx, jsop_t op, unsigned arg1, const WCHAR *arg2)
Definition: compile.c:308
#define S_OK
Definition: intsafe.h:59
static HRESULT push_instr_bstr(compiler_ctx_t *ctx, jsop_t op, const WCHAR *arg)
Definition: compile.c:273
static HRESULT compile_expression(compiler_ctx_t *, expression_t *, BOOL)
Definition: compile.c:923

Referenced by compile_expression().

◆ compile_expression()

static HRESULT compile_expression ( compiler_ctx_t ctx,
expression_t expr,
BOOL  emit_ret 
)
static

Definition at line 923 of file compile.c.

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 }
static unsigned push_instr(compiler_ctx_t *ctx, jsop_t op)
Definition: compile.c:211
#define DEFAULT_UNREACHABLE
static HRESULT compile_unary_expression(compiler_ctx_t *ctx, unary_expression_t *expr, jsop_t op)
Definition: compile.c:370
static HRESULT compile_new_expression(compiler_ctx_t *ctx, call_expression_t *expr)
Definition: compile.c:600
static HRESULT compile_delete_expression(compiler_ctx_t *ctx, unary_expression_t *expr)
Definition: compile.c:670
Definition: query.h:86
static HRESULT compile_member_expression(compiler_ctx_t *ctx, member_expression_t *expr)
Definition: compile.c:382
static HRESULT compile_conditional_expression(compiler_ctx_t *ctx, conditional_expression_t *expr)
Definition: compile.c:566
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
int type
Definition: query.h:88
static HRESULT compile_binary_expression(compiler_ctx_t *ctx, binary_expression_t *expr, jsop_t op)
Definition: compile.c:355
static HRESULT compile_object_literal(compiler_ctx_t *ctx, property_value_expression_t *expr)
Definition: compile.c:892
HRESULT hres
Definition: protocol.c:465
LONG HRESULT
Definition: typedefs.h:77
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
static HRESULT compile_function_expression(compiler_ctx_t *ctx, function_expression_t *expr, BOOL emit_ret)
Definition: compile.c:918
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
#define S_OK
Definition: intsafe.h:59
static HRESULT compile_call_expression(compiler_ctx_t *ctx, call_expression_t *expr, BOOL emit_ret)
Definition: compile.c:628
static HRESULT compile_typeof_expression(compiler_ctx_t *ctx, unary_expression_t *expr)
Definition: compile.c:812
static HRESULT compile_assign_expression(compiler_ctx_t *ctx, binary_expression_t *expr, jsop_t op)
Definition: compile.c:729
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
static HRESULT compile_comma_expression(compiler_ctx_t *ctx, binary_expression_t *expr, BOOL emit_ret)
Definition: compile.c:532

Referenced by compile_array_literal(), compile_assign_expression(), compile_binary_expression(), compile_call_expression(), compile_comma_expression(), compile_conditional_expression(), compile_delete_expression(), compile_expression_statement(), compile_for_statement(), compile_forin_statement(), compile_if_statement(), compile_increment_expression(), compile_logical_expression(), compile_member_expression(), compile_memberid_expression(), compile_new_expression(), compile_object_literal(), compile_return_statement(), compile_switch_statement(), compile_throw_statement(), compile_typeof_expression(), compile_unary_expression(), compile_variable_list(), compile_while_statement(), and compile_with_statement().

◆ compile_expression_statement()

static HRESULT compile_expression_statement ( compiler_ctx_t ctx,
expression_statement_t stat 
)
static

Definition at line 1166 of file compile.c.

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 }
static unsigned push_instr(compiler_ctx_t *ctx, jsop_t op)
Definition: compile.c:211
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
HRESULT hres
Definition: protocol.c:465
LONG HRESULT
Definition: typedefs.h:77
Definition: stat.h:55
#define S_OK
Definition: intsafe.h:59
BOOL from_eval
Definition: compile.c:55
static HRESULT compile_expression(compiler_ctx_t *, expression_t *, BOOL)
Definition: compile.c:923

Referenced by compile_statement().

◆ compile_for_statement()

static HRESULT compile_for_statement ( compiler_ctx_t ctx,
for_statement_t stat 
)
static

Definition at line 1268 of file compile.c.

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 }
unsigned break_label
Definition: compile.c:37
#define TRUE
Definition: types.h:120
static HRESULT compile_statement(compiler_ctx_t *, statement_ctx_t *, statement_t *)
Definition: compile.c:1766
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
static unsigned alloc_label(compiler_ctx_t *ctx)
Definition: compile.c:395
unsigned code_off
Definition: compile.c:57
static HRESULT compile_variable_list(compiler_ctx_t *ctx, variable_declaration_t *list)
Definition: compile.c:1129
static void label_set_addr(compiler_ctx_t *ctx, unsigned label)
Definition: compile.c:416
unsigned continue_label
Definition: compile.c:38
HRESULT hres
Definition: protocol.c:465
LONG HRESULT
Definition: typedefs.h:77
Definition: stat.h:55
static HRESULT push_instr_uint(compiler_ctx_t *ctx, jsop_t op, unsigned arg)
Definition: compile.c:343
#define S_OK
Definition: intsafe.h:59
static HRESULT compile_expression(compiler_ctx_t *, expression_t *, BOOL)
Definition: compile.c:923

Referenced by compile_statement().

◆ compile_forin_statement()

static HRESULT compile_forin_statement ( compiler_ctx_t ctx,
forin_statement_t stat 
)
static

Definition at line 1325 of file compile.c.

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 }
unsigned break_label
Definition: compile.c:37
#define TRUE
Definition: types.h:120
static HRESULT compile_statement(compiler_ctx_t *, statement_ctx_t *, statement_t *)
Definition: compile.c:1766
static BOOL is_memberid_expr(expression_type_t type)
Definition: compile.c:422
#define JS_E_ILLEGAL_ASSIGN
Definition: jscript.h:556
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
static unsigned alloc_label(compiler_ctx_t *ctx)
Definition: compile.c:395
static HRESULT compile_variable_list(compiler_ctx_t *ctx, variable_declaration_t *list)
Definition: compile.c:1129
static HRESULT compile_memberid_expression(compiler_ctx_t *ctx, expression_t *expr, unsigned flags)
Definition: compile.c:461
static void label_set_addr(compiler_ctx_t *ctx, unsigned label)
Definition: compile.c:416
static HRESULT emit_identifier_ref(compiler_ctx_t *ctx, const WCHAR *identifier, unsigned flags)
Definition: compile.c:445
unsigned continue_label
Definition: compile.c:38
HRESULT hres
Definition: protocol.c:465
LONG HRESULT
Definition: typedefs.h:77
Definition: stat.h:55
static HRESULT push_instr_uint(compiler_ctx_t *ctx, jsop_t op, unsigned arg)
Definition: compile.c:343
#define S_OK
Definition: intsafe.h:59
static HRESULT push_instr_int(compiler_ctx_t *ctx, jsop_t op, LONG arg)
Definition: compile.c:236
static HRESULT compile_expression(compiler_ctx_t *, expression_t *, BOOL)
Definition: compile.c:923

Referenced by compile_statement().

◆ compile_function()

static HRESULT compile_function ( compiler_ctx_t ctx,
source_elements_t source,
function_expression_t func_expr,
BOOL  from_eval,
function_code_t func 
)
static

Definition at line 2272 of file compile.c.

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 }
unsigned locals_cnt
Definition: compile.c:65
GLenum func
Definition: glext.h:6028
#define WINE_RB_FOR_EACH_ENTRY(elem, tree, type, field)
Definition: rbtree.h:154
struct _function_expression_t * next
Definition: parser.h:301
static BSTR compiler_alloc_bstr(compiler_ctx_t *ctx, const WCHAR *str)
Definition: compile.c:187
static void resolve_labels(compiler_ctx_t *ctx, unsigned off)
Definition: compile.c:2211
#define assert(x)
Definition: debug.h:53
function_expression_t * func_head
Definition: compile.c:70
const WCHAR * identifier
Definition: parser.h:293
static HRESULT compile_block_statement(compiler_ctx_t *ctx, statement_t *iter)
Definition: compile.c:1113
BSTR name
Definition: engine.h:141
const WCHAR * identifier
Definition: parser.h:282
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
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define debugstr_w
Definition: kernel32.h:32
source_elements_t * source_elements
Definition: parser.h:296
unsigned code_off
Definition: compile.c:57
smooth NULL
Definition: ftsmooth.c:416
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
#define TRACE(s)
Definition: solgame.cpp:4
HRESULT hres
Definition: protocol.c:465
LONG HRESULT
Definition: typedefs.h:77
static HRESULT visit_block_statement(compiler_ctx_t *ctx, statement_t *iter)
Definition: compile.c:2037
char * name
Definition: compiler.c:66
static void * compiler_alloc(bytecode_t *code, size_t size)
Definition: compile.c:128
uint32_t entry
Definition: isohybrid.c:63
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
struct _parameter_t * next
Definition: parser.h:283
#define local
Definition: zutil.h:30
static HRESULT push_instr_uint(compiler_ctx_t *ctx, jsop_t op, unsigned arg)
Definition: compile.c:343
parameter_t * parameter_list
Definition: parser.h:295
#define S_OK
Definition: intsafe.h:59
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
struct wine_rb_tree locals
Definition: compile.c:64
const WCHAR * src_str
Definition: parser.h:297
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
#define memset(x, y, z)
Definition: compat.h:39
#define TRACE_ON(x)
Definition: compat.h:65
int ref
Definition: engine.h:142
bytecode_t * code
Definition: compile.c:53
off
Definition: i386-dis.c:3909
function_expression_t * func_tail
Definition: compile.c:71

Referenced by compile_script().

◆ compile_function_expression()

static HRESULT compile_function_expression ( compiler_ctx_t ctx,
function_expression_t expr,
BOOL  emit_ret 
)
static

Definition at line 918 of file compile.c.

919 {
920  return emit_ret ? push_instr_uint(ctx, OP_func, expr->func_id) : S_OK;
921 }
Definition: query.h:86
static HRESULT push_instr_uint(compiler_ctx_t *ctx, jsop_t op, unsigned arg)
Definition: compile.c:343
#define S_OK
Definition: intsafe.h:59

Referenced by compile_expression().

◆ compile_if_statement()

static HRESULT compile_if_statement ( compiler_ctx_t ctx,
if_statement_t stat 
)
static

Definition at line 1178 of file compile.c.

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 }
static unsigned push_instr(compiler_ctx_t *ctx, jsop_t op)
Definition: compile.c:211
#define TRUE
Definition: types.h:120
static HRESULT compile_statement(compiler_ctx_t *, statement_ctx_t *, statement_t *)
Definition: compile.c:1766
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
unsigned code_off
Definition: compile.c:57
smooth NULL
Definition: ftsmooth.c:416
HRESULT hres
Definition: protocol.c:465
LONG HRESULT
Definition: typedefs.h:77
Definition: stat.h:55
static void set_arg_uint(compiler_ctx_t *ctx, unsigned instr, unsigned arg)
Definition: compile.c:338
#define S_OK
Definition: intsafe.h:59
static HRESULT compile_expression(compiler_ctx_t *, expression_t *, BOOL)
Definition: compile.c:923

Referenced by compile_statement().

◆ compile_increment_expression()

static HRESULT compile_increment_expression ( compiler_ctx_t ctx,
unary_expression_t expr,
jsop_t  op,
int  n 
)
static

Definition at line 512 of file compile.c.

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 }
#define TRUE
Definition: types.h:120
GLdouble n
Definition: glext.h:7729
static BOOL is_memberid_expr(expression_type_t type)
Definition: compile.c:422
Definition: query.h:86
#define JS_E_ILLEGAL_ASSIGN
Definition: jscript.h:556
int type
Definition: query.h:88
static HRESULT compile_memberid_expression(compiler_ctx_t *ctx, expression_t *expr, unsigned flags)
Definition: compile.c:461
HRESULT hres
Definition: protocol.c:465
LONG HRESULT
Definition: typedefs.h:77
static HRESULT push_instr_uint(compiler_ctx_t *ctx, jsop_t op, unsigned arg)
Definition: compile.c:343
static HRESULT push_instr_int(compiler_ctx_t *ctx, jsop_t op, LONG arg)
Definition: compile.c:236
static HRESULT compile_expression(compiler_ctx_t *, expression_t *, BOOL)
Definition: compile.c:923
UINT op
Definition: effect.c:223

Referenced by compile_expression().

◆ compile_labelled_statement()

static HRESULT compile_labelled_statement ( compiler_ctx_t ctx,
labelled_statement_t stat 
)
static

Definition at line 1557 of file compile.c.

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 }
unsigned break_label
Definition: compile.c:37
static HRESULT compile_statement(compiler_ctx_t *, statement_ctx_t *, statement_t *)
Definition: compile.c:1766
#define WARN(fmt,...)
Definition: debug.h:111
statement_ctx_t * stat_ctx
Definition: compile.c:67
struct _statement_ctx_t * next
Definition: compile.c:42
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
static unsigned alloc_label(compiler_ctx_t *ctx)
Definition: compile.c:395
#define debugstr_w
Definition: kernel32.h:32
static void label_set_addr(compiler_ctx_t *ctx, unsigned label)
Definition: compile.c:416
HRESULT hres
Definition: protocol.c:465
LONG HRESULT
Definition: typedefs.h:77
Definition: stat.h:55
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
#define S_OK
Definition: intsafe.h:59
#define JS_E_LABEL_REDEFINED
Definition: jscript.h:547

Referenced by compile_statement().

◆ compile_literal()

static HRESULT compile_literal ( compiler_ctx_t ctx,
literal_t literal 
)
static

Definition at line 833 of file compile.c.

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 }
static unsigned push_instr(compiler_ctx_t *ctx, jsop_t op)
Definition: compile.c:211
#define DEFAULT_UNREACHABLE
static HRESULT push_instr_double(compiler_ctx_t *ctx, jsop_t op, double arg)
Definition: compile.c:326
static HRESULT push_instr_str_uint(compiler_ctx_t *ctx, jsop_t op, jsstr_t *str, unsigned arg2)
Definition: compile.c:260
double dval
Definition: parser.h:83
Definition: parser.h:75
#define E_FAIL
Definition: ddrawi.h:102
jsstr_t * str
Definition: parser.h:84
Definition: parser.h:76
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
struct literal_t::@429::@430 regexp
static HRESULT push_instr_str(compiler_ctx_t *ctx, jsop_t op, jsstr_t *str)
Definition: compile.c:248
BOOL bval
Definition: parser.h:85
union literal_t::@429 u
literal_type_t type
Definition: parser.h:81
#define S_OK
Definition: intsafe.h:59
static HRESULT push_instr_int(compiler_ctx_t *ctx, jsop_t op, LONG arg)
Definition: compile.c:236

Referenced by compile_expression().

◆ compile_logical_expression()

static HRESULT compile_logical_expression ( compiler_ctx_t ctx,
binary_expression_t expr,
jsop_t  op 
)
static

Definition at line 544 of file compile.c.

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 }
static unsigned push_instr(compiler_ctx_t *ctx, jsop_t op)
Definition: compile.c:211
#define TRUE
Definition: types.h:120
struct x86_inst instr
Definition: query.h:86
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
unsigned code_off
Definition: compile.c:57
HRESULT hres
Definition: protocol.c:465
LONG HRESULT
Definition: typedefs.h:77
static void set_arg_uint(compiler_ctx_t *ctx, unsigned instr, unsigned arg)
Definition: compile.c:338
#define S_OK
Definition: intsafe.h:59
static HRESULT compile_expression(compiler_ctx_t *, expression_t *, BOOL)
Definition: compile.c:923
UINT op
Definition: effect.c:223

Referenced by compile_expression().

◆ compile_member_expression()

static HRESULT compile_member_expression ( compiler_ctx_t ctx,
member_expression_t expr 
)
static

Definition at line 382 of file compile.c.

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 }
#define TRUE
Definition: types.h:120
Definition: query.h:86
HRESULT hres
Definition: protocol.c:465
LONG HRESULT
Definition: typedefs.h:77
static HRESULT push_instr_bstr(compiler_ctx_t *ctx, jsop_t op, const WCHAR *arg)
Definition: compile.c:273
static HRESULT compile_expression(compiler_ctx_t *, expression_t *, BOOL)
Definition: compile.c:923

Referenced by compile_expression().

◆ compile_memberid_expression()

static HRESULT compile_memberid_expression ( compiler_ctx_t ctx,
expression_t expr,
unsigned  flags 
)
static

Definition at line 461 of file compile.c.

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 }
#define DEFAULT_UNREACHABLE
#define TRUE
Definition: types.h:120
expression_t * expression
Definition: parser.h:324
expression_t * expression2
Definition: parser.h:307
Definition: jsstr.h:39
Definition: query.h:86
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
expression_t * expression1
Definition: parser.h:306
int type
Definition: query.h:88
const WCHAR * identifier
Definition: parser.h:325
static HRESULT emit_identifier_ref(compiler_ctx_t *ctx, const WCHAR *identifier, unsigned flags)
Definition: compile.c:445
static HRESULT push_instr_str(compiler_ctx_t *ctx, jsop_t op, jsstr_t *str)
Definition: compile.c:248
HRESULT hres
Definition: protocol.c:465
LONG HRESULT
Definition: typedefs.h:77
GLbitfield flags
Definition: glext.h:7161
static jsstr_t * compiler_alloc_string(compiler_ctx_t *ctx, const WCHAR *str)
Definition: compile.c:161
const WCHAR * identifier
Definition: parser.h:342
static HRESULT push_instr_uint(compiler_ctx_t *ctx, jsop_t op, unsigned arg)
Definition: compile.c:343
#define S_OK
Definition: intsafe.h:59
static HRESULT compile_expression(compiler_ctx_t *, expression_t *, BOOL)
Definition: compile.c:923

Referenced by compile_assign_expression(), compile_call_expression(), compile_forin_statement(), compile_increment_expression(), and compile_typeof_expression().

◆ compile_new_expression()

static HRESULT compile_new_expression ( compiler_ctx_t ctx,
call_expression_t expr 
)
static

Definition at line 600 of file compile.c.

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 }
static unsigned push_instr(compiler_ctx_t *ctx, jsop_t op)
Definition: compile.c:211
#define TRUE
Definition: types.h:120
void * arg
Definition: msvc.h:12
Definition: query.h:86
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
HRESULT hres
Definition: protocol.c:465
LONG HRESULT
Definition: typedefs.h:77
static HRESULT push_instr_uint(compiler_ctx_t *ctx, jsop_t op, unsigned arg)
Definition: compile.c:343
#define S_OK
Definition: intsafe.h:59
static unsigned arg_cnt(const DISPPARAMS *dp)
Definition: vbscript.h:166
static HRESULT compile_expression(compiler_ctx_t *, expression_t *, BOOL)
Definition: compile.c:923

Referenced by compile_expression().

◆ compile_object_literal()

static HRESULT compile_object_literal ( compiler_ctx_t ctx,
property_value_expression_t expr 
)
static

Definition at line 892 of file compile.c.

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 }
static unsigned push_instr(compiler_ctx_t *ctx, jsop_t op)
Definition: compile.c:211
#define TRUE
Definition: types.h:120
Definition: jsstr.h:39
static HRESULT push_instr_str_uint(compiler_ctx_t *ctx, jsop_t op, jsstr_t *str, unsigned arg2)
Definition: compile.c:260
struct _property_definition_t * next
Definition: parser.h:368
Definition: query.h:86
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
literal_t * name
Definition: parser.h:365
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
LONG HRESULT
Definition: typedefs.h:77
#define S_OK
Definition: intsafe.h:59
Definition: name.c:36
static HRESULT compile_expression(compiler_ctx_t *, expression_t *, BOOL)
Definition: compile.c:923
expression_t * value
Definition: parser.h:366
GLuint const GLchar * name
Definition: glext.h:6031

Referenced by compile_expression().

◆ compile_return_statement()

static HRESULT compile_return_statement ( compiler_ctx_t ctx,
expression_statement_t stat 
)
static

Definition at line 1509 of file compile.c.

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 }
static unsigned push_instr(compiler_ctx_t *ctx, jsop_t op)
Definition: compile.c:211
#define TRUE
Definition: types.h:120
static HRESULT pop_to_stat(compiler_ctx_t *ctx, statement_ctx_t *stat_ctx)
Definition: compile.c:1386
#define JS_E_MISPLACED_RETURN
Definition: jscript.h:544
#define WARN(fmt,...)
Definition: debug.h:111
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
smooth NULL
Definition: ftsmooth.c:416
HRESULT hres
Definition: protocol.c:465
LONG HRESULT
Definition: typedefs.h:77
Definition: stat.h:55
static HRESULT push_instr_uint(compiler_ctx_t *ctx, jsop_t op, unsigned arg)
Definition: compile.c:343
BOOL from_eval
Definition: compile.c:55
static HRESULT compile_expression(compiler_ctx_t *, expression_t *, BOOL)
Definition: compile.c:923

Referenced by compile_statement().

◆ compile_script()

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 at line 2461 of file compile.c.

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 }
function_code_t global_code
Definition: engine.h:178
#define WARN(fmt,...)
Definition: debug.h:111
static HRESULT init_code(compiler_ctx_t *compiler, const WCHAR *source)
Definition: compile.c:2246
Definition: match.c:390
WCHAR * source
Definition: engine.h:180
smooth NULL
Definition: ftsmooth.c:416
const char * delimiter
Definition: string.c:1566
void parser_release(parser_ctx_t *) DECLSPEC_HIDDEN
Definition: parser.tab.c:4361
HRESULT hres
Definition: protocol.c:465
LONG HRESULT
Definition: typedefs.h:77
int ret
static HRESULT compile_arguments(compiler_ctx_t *ctx, const WCHAR *args)
Definition: compile.c:2445
void heap_pool_init(heap_pool_t *) DECLSPEC_HIDDEN
Definition: jsutils.c:71
parser_ctx_t * parser
Definition: compile.c:52
#define S_OK
Definition: intsafe.h:59
HRESULT decode_source(WCHAR *code)
Definition: decode.c:111
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_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
heap_pool_t heap
Definition: compile.c:73
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
bytecode_t * code
Definition: compile.c:53

Referenced by construct_function(), JScriptParse_ParseScriptText(), JScriptParseProcedure_ParseProcedureText(), JSGlobal_eval(), VBScriptParse_ParseScriptText(), and VBScriptParseProcedure_ParseProcedureText().

◆ compile_statement()

static HRESULT compile_statement ( compiler_ctx_t ctx,
statement_ctx_t stat_ctx,
statement_t stat 
)
static

Definition at line 1766 of file compile.c.

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 }
#define DEFAULT_UNREACHABLE
static HRESULT compile_throw_statement(compiler_ctx_t *ctx, expression_statement_t *stat)
Definition: compile.c:1678
static HRESULT compile_labelled_statement(compiler_ctx_t *ctx, labelled_statement_t *stat)
Definition: compile.c:1557
#define assert(x)
Definition: debug.h:53
statement_ctx_t * stat_ctx
Definition: compile.c:67
static HRESULT compile_block_statement(compiler_ctx_t *ctx, statement_t *iter)
Definition: compile.c:1113
static HRESULT compile_break_statement(compiler_ctx_t *ctx, branch_statement_t *stat)
Definition: compile.c:1472
static HRESULT compile_try_statement(compiler_ctx_t *ctx, try_statement_t *stat)
Definition: compile.c:1690
struct _statement_ctx_t * next
Definition: compile.c:42
HRESULT hres
Definition: protocol.c:465
LONG HRESULT
Definition: typedefs.h:77
static HRESULT compile_if_statement(compiler_ctx_t *ctx, if_statement_t *stat)
Definition: compile.c:1178
static HRESULT compile_while_statement(compiler_ctx_t *ctx, while_statement_t *stat)
Definition: compile.c:1217
static HRESULT compile_for_statement(compiler_ctx_t *ctx, for_statement_t *stat)
Definition: compile.c:1268
static HRESULT compile_return_statement(compiler_ctx_t *ctx, expression_statement_t *stat)
Definition: compile.c:1509
Definition: stat.h:55
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 HRESULT compile_continue_statement(compiler_ctx_t *ctx, branch_statement_t *stat)
Definition: compile.c:1419
static HRESULT compile_switch_statement(compiler_ctx_t *ctx, switch_statement_t *stat)
Definition: compile.c:1583
static HRESULT compile_var_statement(compiler_ctx_t *ctx, var_statement_t *stat)
Definition: compile.c:1160
static HRESULT compile_expression_statement(compiler_ctx_t *ctx, expression_statement_t *stat)
Definition: compile.c:1166
static HRESULT compile_forin_statement(compiler_ctx_t *ctx, forin_statement_t *stat)
Definition: compile.c:1325

Referenced by compile_block_statement(), compile_for_statement(), compile_forin_statement(), compile_if_statement(), compile_labelled_statement(), compile_switch_statement(), compile_try_statement(), compile_while_statement(), and compile_with_statement().

◆ compile_switch_statement()

static HRESULT compile_switch_statement ( compiler_ctx_t ctx,
switch_statement_t stat 
)
static

Definition at line 1583 of file compile.c.

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 }
unsigned break_label
Definition: compile.c:37
static unsigned push_instr(compiler_ctx_t *ctx, jsop_t op)
Definition: compile.c:211
#define TRUE
Definition: types.h:120
static HRESULT compile_statement(compiler_ctx_t *, statement_ctx_t *, statement_t *)
Definition: compile.c:1766
#define assert(x)
Definition: debug.h:53
static void * heap_alloc(size_t len)
Definition: appwiz.h:65
statement_t * next
Definition: parser.h:125
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
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
unsigned int BOOL
Definition: ntddk_ex.h:94
static unsigned alloc_label(compiler_ctx_t *ctx)
Definition: compile.c:395
statement_t * stat
Definition: parser.h:193
expression_t * expr
Definition: parser.h:192
unsigned code_off
Definition: compile.c:57
struct _case_clausule_t * next
Definition: parser.h:195
static void label_set_addr(compiler_ctx_t *ctx, unsigned label)
Definition: compile.c:416
HRESULT hres
Definition: protocol.c:465
LONG HRESULT
Definition: typedefs.h:77
Definition: stat.h:55
static void set_arg_uint(compiler_ctx_t *ctx, unsigned instr, unsigned arg)
Definition: compile.c:338
static HRESULT push_instr_uint(compiler_ctx_t *ctx, jsop_t op, unsigned arg)
Definition: compile.c:343
#define S_OK
Definition: intsafe.h:59
static HRESULT compile_expression(compiler_ctx_t *, expression_t *, BOOL)
Definition: compile.c:923
#define SUCCEEDED(hr)
Definition: intsafe.h:57
static BOOL heap_free(void *mem)
Definition: appwiz.h:75

Referenced by compile_statement().

◆ compile_throw_statement()

static HRESULT compile_throw_statement ( compiler_ctx_t ctx,
expression_statement_t stat 
)
static

Definition at line 1678 of file compile.c.

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 }
static unsigned push_instr(compiler_ctx_t *ctx, jsop_t op)
Definition: compile.c:211
#define TRUE
Definition: types.h:120
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
HRESULT hres
Definition: protocol.c:465
LONG HRESULT
Definition: typedefs.h:77
Definition: stat.h:55
#define S_OK
Definition: intsafe.h:59
static HRESULT compile_expression(compiler_ctx_t *, expression_t *, BOOL)
Definition: compile.c:923

Referenced by compile_statement().

◆ compile_try_statement()

static HRESULT compile_try_statement ( compiler_ctx_t ctx,
try_statement_t stat 
)
static

Definition at line 1690 of file compile.c.

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 }
static unsigned push_instr(compiler_ctx_t *ctx, jsop_t op)
Definition: compile.c:211
#define TRUE
Definition: types.h:120
BOOL using_except
Definition: compile.c:35
static HRESULT compile_statement(compiler_ctx_t *, statement_ctx_t *, statement_t *)
Definition: compile.c:1766
instr_arg_t arg[2]
Definition: engine.h:129
static BSTR compiler_alloc_bstr(compiler_ctx_t *ctx, const WCHAR *str)
Definition: compile.c:187
OLECHAR * BSTR
Definition: compat.h:1942
static instr_t * instr_ptr(compiler_ctx_t *ctx, unsigned off)
Definition: compile.c:230
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
unsigned code_off
Definition: compile.c:57
smooth NULL
Definition: ftsmooth.c:416
_In_ ULONG _In_ ULONG_PTR ident
Definition: winddi.h:3993
HRESULT hres
Definition: protocol.c:465
LONG HRESULT
Definition: typedefs.h:77
Definition: stat.h:55
#define S_OK
Definition: intsafe.h:59
static HRESULT push_instr_bstr(compiler_ctx_t *ctx, jsop_t op, const WCHAR *arg)
Definition: compile.c:273
unsigned uint
Definition: engine.h:112
union instr_t::@423 u

Referenced by compile_statement().

◆ compile_typeof_expression()

static HRESULT compile_typeof_expression ( compiler_ctx_t ctx,
unary_expression_t expr 
)
static

Definition at line 812 of file compile.c.

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 }
static unsigned push_instr(compiler_ctx_t *ctx, jsop_t op)
Definition: compile.c:211
#define TRUE
Definition: types.h:120
static BOOL is_memberid_expr(expression_type_t type)
Definition: compile.c:422
Definition: query.h:86
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
int type
Definition: query.h:88
static HRESULT compile_memberid_expression(compiler_ctx_t *ctx, expression_t *expr, unsigned flags)
Definition: compile.c:461
HRESULT hres
Definition: protocol.c:465
LONG HRESULT
Definition: typedefs.h:77
jsop_t
Definition: engine.h:101
#define S_OK
Definition: intsafe.h:59
static HRESULT push_instr_bstr(compiler_ctx_t *ctx, jsop_t op, const WCHAR *arg)
Definition: compile.c:273
static HRESULT compile_expression(compiler_ctx_t *, expression_t *, BOOL)
Definition: compile.c:923
UINT op
Definition: effect.c:223

Referenced by compile_expression().

◆ compile_unary_expression()

static HRESULT compile_unary_expression ( compiler_ctx_t ctx,
unary_expression_t expr,
jsop_t  op 
)
static

Definition at line 370 of file compile.c.

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 }
static unsigned push_instr(compiler_ctx_t *ctx, jsop_t op)
Definition: compile.c:211
#define TRUE
Definition: types.h:120
Definition: query.h:86
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
HRESULT hres
Definition: protocol.c:465
LONG HRESULT
Definition: typedefs.h:77
#define S_OK
Definition: intsafe.h:59
static HRESULT compile_expression(compiler_ctx_t *, expression_t *, BOOL)
Definition: compile.c:923
UINT op
Definition: effect.c:223

Referenced by compile_expression().

◆ compile_var_statement()

static HRESULT compile_var_statement ( compiler_ctx_t ctx,
var_statement_t stat 
)
static

Definition at line 1160 of file compile.c.

1161 {
1162  return compile_variable_list(ctx, stat->variable_list);
1163 }
static HRESULT compile_variable_list(compiler_ctx_t *ctx, variable_declaration_t *list)
Definition: compile.c:1129
Definition: stat.h:55

Referenced by compile_statement().

◆ compile_variable_list()

static HRESULT compile_variable_list ( compiler_ctx_t ctx,
variable_declaration_t list 
)
static

Definition at line 1129 of file compile.c.

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 }
static unsigned push_instr(compiler_ctx_t *ctx, jsop_t op)
Definition: compile.c:211
const WCHAR * identifier
Definition: parser.h:97
#define TRUE
Definition: types.h:120
struct _variable_declaration_t * next
Definition: parser.h:100
#define assert(x)
Definition: debug.h:53
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
smooth NULL
Definition: ftsmooth.c:416
expression_t * expr
Definition: parser.h:98
static HRESULT emit_identifier_ref(compiler_ctx_t *ctx, const WCHAR *identifier, unsigned flags)
Definition: compile.c:445
HRESULT hres
Definition: protocol.c:465
LONG HRESULT
Definition: typedefs.h:77
Definition: _list.h:228
static HRESULT push_instr_uint(compiler_ctx_t *ctx, jsop_t op, unsigned arg)
Definition: compile.c:343
#define S_OK
Definition: intsafe.h:59
static HRESULT compile_expression(compiler_ctx_t *, expression_t *, BOOL)
Definition: compile.c:923

Referenced by compile_for_statement(), compile_forin_statement(), and compile_var_statement().

◆ compile_while_statement()

static HRESULT compile_while_statement ( compiler_ctx_t ctx,
while_statement_t stat 
)
static

Definition at line 1217 of file compile.c.

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 }
unsigned break_label
Definition: compile.c:37
#define TRUE
Definition: types.h:120
static HRESULT compile_statement(compiler_ctx_t *, statement_ctx_t *, statement_t *)
Definition: compile.c:1766
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
static unsigned alloc_label(compiler_ctx_t *ctx)
Definition: compile.c:395
unsigned code_off
Definition: compile.c:57
static void label_set_addr(compiler_ctx_t *ctx, unsigned label)
Definition: compile.c:416
unsigned continue_label
Definition: compile.c:38
HRESULT hres
Definition: protocol.c:465
LONG HRESULT
Definition: typedefs.h:77
Definition: stat.h:55
static HRESULT push_instr_uint(compiler_ctx_t *ctx, jsop_t op, unsigned arg)
Definition: compile.c:343
#define S_OK
Definition: intsafe.h:59
static HRESULT compile_expression(compiler_ctx_t *, expression_t *, BOOL)
Definition: compile.c:923

Referenced by compile_statement().

◆ compile_with_statement()

static HRESULT compile_with_statement ( compiler_ctx_t ctx,
with_statement_t stat 
)
static

Definition at line 1534 of file compile.c.

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 }
static unsigned push_instr(compiler_ctx_t *ctx, jsop_t op)
Definition: compile.c:211
#define TRUE
Definition: types.h:120
static HRESULT compile_statement(compiler_ctx_t *, statement_ctx_t *, statement_t *)
Definition: compile.c:1766
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
HRESULT hres
Definition: protocol.c:465
LONG HRESULT
Definition: typedefs.h:77
Definition: stat.h:55
#define S_OK
Definition: intsafe.h:59
static HRESULT compile_expression(compiler_ctx_t *, expression_t *, BOOL)
Definition: compile.c:923

Referenced by compile_statement().

◆ compiler_alloc()

static void* compiler_alloc ( bytecode_t code,
size_t  size 
)
inlinestatic

Definition at line 128 of file compile.c.

129 {
130  return heap_pool_alloc(&code->heap, size);
131 }
void * heap_pool_alloc(heap_pool_t *, DWORD) __WINE_ALLOC_SIZE(2) DECLSPEC_HIDDEN
Definition: jsutils.c:77
GLsizeiptr size
Definition: glext.h:5919

Referenced by compile_arguments(), and compile_function().

◆ compiler_alloc_bstr()

static BSTR compiler_alloc_bstr ( compiler_ctx_t ctx,
const WCHAR str 
)
static

Definition at line 187 of file compile.c.

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 }
unsigned bstr_cnt
Definition: engine.h:184
BSTR * bstr_pool
Definition: engine.h:182
const WCHAR * str
smooth NULL
Definition: ftsmooth.c:416
BSTR WINAPI SysAllocString(LPCOLESTR str)
Definition: oleaut.c:241
bytecode_t * code
Definition: compile.c:53
static BOOL ensure_bstr_slot(compiler_ctx_t *ctx)
Definition: compile.c:166

Referenced by alloc_variable(), compile_function(), compile_try_statement(), push_instr_bstr(), and push_instr_bstr_uint().

◆ compiler_alloc_bstr_len()

static BSTR compiler_alloc_bstr_len ( compiler_ctx_t ctx,
const WCHAR str,
size_t  len 
)
static

Definition at line 199 of file compile.c.

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 }
unsigned bstr_cnt
Definition: engine.h:184
BSTR WINAPI SysAllocStringLen(const OLECHAR *str, unsigned int len)
Definition: oleaut.c:342
BSTR * bstr_pool
Definition: engine.h:182
const WCHAR * str
smooth NULL
Definition: ftsmooth.c:416
GLenum GLsizei len
Definition: glext.h:6722
bytecode_t * code
Definition: compile.c:53
static BOOL ensure_bstr_slot(compiler_ctx_t *ctx)
Definition: compile.c:166

Referenced by parse_arguments().

◆ compiler_alloc_string()

static jsstr_t* compiler_alloc_string ( compiler_ctx_t ctx,
const WCHAR str 
)
static

Definition at line 161 of file compile.c.

162 {
163  return compiler_alloc_string_len(ctx, str, lstrlenW(str));
164 }
#define lstrlenW
Definition: compat.h:415
const WCHAR * str
jsstr_t * compiler_alloc_string_len(compiler_ctx_t *ctx, const WCHAR *str, unsigned len)
Definition: compile.c:133

Referenced by compile_delete_expression(), compile_memberid_expression(), and push_instr_uint_str().

◆ compiler_alloc_string_len()

jsstr_t* compiler_alloc_string_len ( compiler_ctx_t ctx,
const WCHAR str,
unsigned  len 
)

Definition at line 133 of file compile.c.

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 }
jsstr_t * jsstr_alloc_len(const WCHAR *buf, unsigned len)
Definition: jsstr.c:86
Definition: jsstr.h:39
static void * heap_realloc(void *mem, size_t len)
Definition: appwiz.h:70
static void * heap_alloc(size_t len)
Definition: appwiz.h:65
jsstr_t ** str_pool
Definition: engine.h:186
unsigned str_cnt
Definition: engine.h:188
const WCHAR * str
smooth NULL
Definition: ftsmooth.c:416
GLenum GLsizei len
Definition: glext.h:6722
unsigned str_pool_size
Definition: engine.h:187
bytecode_t * code
Definition: compile.c:53

Referenced by compiler_alloc_string(), parse_regexp(), parse_string_literal(), and yyparse().

◆ dump_code()

static void dump_code ( compiler_ctx_t ctx,
unsigned  off 
)
static

Definition at line 109 of file compile.c.

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 }
struct x86_inst instr
static void dump_instr_arg(instr_arg_type_t type, instr_arg_t *arg)
Definition: compile.c:86
unsigned code_off
Definition: compile.c:57
#define TRACE_(x)
Definition: compat.h:66
instr_t * instrs
Definition: engine.h:175
bytecode_t * code
Definition: compile.c:53
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
off
Definition: i386-dis.c:3909

Referenced by compile_function().

◆ dump_instr_arg()

static void dump_instr_arg ( instr_arg_type_t  type,
instr_arg_t arg 
)
static

Definition at line 86 of file compile.c.

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 }
#define DEFAULT_UNREACHABLE
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
#define TRACE_(x)
Definition: compat.h:66
#define ARG_NONE
Definition: amlcode.h:216
const char * debugstr_jsstr(jsstr_t *str)
Definition: jsstr.c:37
UINT WINAPI SysStringLen(BSTR str)
Definition: oleaut.c:199
#define debugstr_wn
Definition: kernel32.h:33

Referenced by dump_code().

◆ emit_identifier()

static HRESULT emit_identifier ( compiler_ctx_t ctx,
const WCHAR identifier 
)
static

Definition at line 453 of file compile.c.

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 }
static BOOL bind_local(compiler_ctx_t *ctx, const WCHAR *identifier, int *ret_ref)
Definition: compile.c:427
static HRESULT push_instr_int(compiler_ctx_t *ctx, jsop_t op, LONG arg)
Definition: compile.c:236
static HRESULT push_instr_bstr(compiler_ctx_t *ctx, jsop_t op, const WCHAR *arg)
Definition: compile.c:273

Referenced by compile_expression().

◆ emit_identifier_ref()

static HRESULT emit_identifier_ref ( compiler_ctx_t ctx,
const WCHAR identifier,
unsigned  flags 
)
static

Definition at line 445 of file compile.c.

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 }
static BOOL bind_local(compiler_ctx_t *ctx, const WCHAR *identifier, int *ret_ref)
Definition: compile.c:427
GLbitfield flags
Definition: glext.h:7161
static HRESULT push_instr_bstr_uint(compiler_ctx_t *ctx, jsop_t op, const WCHAR *arg1, unsigned arg2)
Definition: compile.c:290
static HRESULT push_instr_int(compiler_ctx_t *ctx, jsop_t op, LONG arg)
Definition: compile.c:236

Referenced by compile_forin_statement(), compile_memberid_expression(), and compile_variable_list().

◆ ensure_bstr_slot()

static BOOL ensure_bstr_slot ( compiler_ctx_t ctx)
static

Definition at line 166 of file compile.c.

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 }
unsigned bstr_cnt
Definition: engine.h:184
#define TRUE
Definition: types.h:120
unsigned bstr_pool_size
Definition: engine.h:183
BSTR * bstr_pool
Definition: engine.h:182
OLECHAR * BSTR
Definition: compat.h:1942
static void * heap_realloc(void *mem, size_t len)
Definition: appwiz.h:70
static void * heap_alloc(size_t len)
Definition: appwiz.h:65
bytecode_t * code
Definition: compile.c:53

Referenced by compiler_alloc_bstr(), and compiler_alloc_bstr_len().

◆ find_local()

static function_local_t* find_local ( compiler_ctx_t ctx,
const WCHAR name 
)
inlinestatic

Definition at line 1842 of file compile.c.

1843 {
1844  struct wine_rb_entry *entry = wine_rb_get(&ctx->locals, name);
1846 }
smooth NULL
Definition: ftsmooth.c:416
#define WINE_RB_ENTRY_VALUE(element, type, field)
Definition: rbtree.h:31
uint32_t entry
Definition: isohybrid.c:63
Definition: rbtree.h:35
struct wine_rb_tree locals
Definition: compile.c:64
Definition: name.c:36
static struct wine_rb_entry * wine_rb_get(const struct wine_rb_tree *tree, const void *key)
Definition: rbtree.h:203

Referenced by alloc_variable(), and compile_function().

◆ function_local_cmp()

static int function_local_cmp ( const void key,
const struct wine_rb_entry entry 
)
static

Definition at line 1836 of file compile.c.

1837 {
1839  return wcscmp(key, local->name);
1840 }
#define WINE_RB_ENTRY_VALUE(element, type, field)
Definition: rbtree.h:31
char * name
Definition: compiler.c:66
uint32_t entry
Definition: isohybrid.c:63
#define local
Definition: zutil.h:30
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
Definition: path.c:42

Referenced by compile_function().

◆ init_code()

static HRESULT init_code ( compiler_ctx_t compiler,
const WCHAR source 
)
static

Definition at line 2246 of file compile.c.

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 }
unsigned code_size
Definition: compile.c:58
static void * heap_alloc(size_t len)
Definition: appwiz.h:65
WCHAR * source
Definition: engine.h:180
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
static WCHAR * heap_strdupW(const WCHAR *str)
Definition: propsheet.c:178
unsigned code_off
Definition: compile.c:57
instr_t * instrs
Definition: engine.h:175
void heap_pool_init(heap_pool_t *) DECLSPEC_HIDDEN
Definition: jsutils.c:71
#define S_OK
Definition: intsafe.h:59
LONG ref
Definition: engine.h:173
heap_pool_t heap
Definition: engine.h:176
void release_bytecode(bytecode_t *code)
Definition: compile.c:2226
bytecode_t * code
Definition: compile.c:53

Referenced by compile_script().

◆ instr_ptr()

static instr_t* instr_ptr ( compiler_ctx_t ctx,
unsigned  off 
)
inlinestatic

◆ is_loop_statement()

static BOOL is_loop_statement ( statement_type_t  type)
inlinestatic

Definition at line 1107 of file compile.c.

1108 {
1109  return type == STAT_FOR || type == STAT_FORIN || type == STAT_WHILE;
1110 }
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545

Referenced by compile_continue_statement().

◆ is_memberid_expr()

static BOOL is_memberid_expr ( expression_type_t  type)
inlinestatic

Definition at line 422 of file compile.c.

423 {
424  return type == EXPR_IDENT || type == EXPR_MEMBER || type == EXPR_ARRAY;
425 }
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545

Referenced by compile_assign_expression(), compile_call_expression(), compile_forin_statement(), compile_increment_expression(), and compile_typeof_expression().

◆ label_set_addr()

static void label_set_addr ( compiler_ctx_t ctx,
unsigned  label 
)
static

Definition at line 416 of file compile.c.

417 {
419  ctx->labels[label & ~LABEL_FLAG] = ctx->code_off;
420 }
#define assert(x)
Definition: debug.h:53
unsigned code_off
Definition: compile.c:57
#define LABEL_FLAG
Definition: compile.c:393
uint8_t label[11]
Definition: fsck.fat.h:65
unsigned * labels
Definition: compile.c:60

Referenced by compile_for_statement(), compile_forin_statement(), compile_labelled_statement(), compile_switch_statement(), and compile_while_statement().

◆ literal_as_string()

static HRESULT literal_as_string ( compiler_ctx_t ctx,
literal_t literal,
jsstr_t **  str 
)
static

Definition at line 851 of file compile.c.

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 }
#define DEFAULT_UNREACHABLE
double dval
Definition: parser.h:83
HRESULT double_to_string(double, jsstr_t **) DECLSPEC_HIDDEN
Definition: jsutils.c:727
jsstr_t * str
Definition: parser.h:84
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
const WCHAR * str
union literal_t::@429 u
literal_type_t type
Definition: parser.h:81
#define S_OK
Definition: intsafe.h:59

Referenced by compile_object_literal().

◆ parse_arguments()

static HRESULT parse_arguments ( compiler_ctx_t ctx,
const WCHAR args,
BSTR arg_array,
unsigned *  args_size 
)
static

Definition at line 2391 of file compile.c.

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 }
static BSTR compiler_alloc_bstr_len(compiler_ctx_t *ctx, const WCHAR *str, size_t len)
Definition: compile.c:199
#define iswalpha(_c)
Definition: ctype.h:664
#define E_FAIL
Definition: ddrawi.h:102
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define iswalnum(_c)
Definition: ctype.h:671
#define debugstr_w
Definition: kernel32.h:32
#define FIXME(fmt,...)
Definition: debug.h:110
static PVOID ptr
Definition: dispmode.c:27
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define iswspace(_c)
Definition: ctype.h:669
#define S_OK
Definition: intsafe.h:59
static unsigned arg_cnt(const DISPPARAMS *dp)
Definition: vbscript.h:166
#define args
Definition: format.c:66

Referenced by compile_arguments().

◆ pop_to_stat()

static HRESULT pop_to_stat ( compiler_ctx_t ctx,
statement_ctx_t stat_ctx 
)
static

Definition at line 1386 of file compile.c.

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 }
static unsigned push_instr(compiler_ctx_t *ctx, jsop_t op)
Definition: compile.c:211
BOOL using_scope
Definition: compile.c:34
BOOL using_except
Definition: compile.c:35
statement_ctx_t * stat_ctx
Definition: compile.c:67
struct _statement_ctx_t * next
Definition: compile.c:42
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
unsigned code_off
Definition: compile.c:57
HRESULT hres
Definition: protocol.c:465
LONG HRESULT
Definition: typedefs.h:77
static HRESULT push_instr_uint(compiler_ctx_t *ctx, jsop_t op, unsigned arg)
Definition: compile.c:343
#define S_OK
Definition: intsafe.h:59
unsigned stack_use
Definition: compile.c:33
static jsval_t stack_pop(script_ctx_t *ctx)
Definition: engine.c:129

Referenced by compile_break_statement(), compile_continue_statement(), and compile_return_statement().

◆ push_instr()

static unsigned push_instr ( compiler_ctx_t ctx,
jsop_t  op 
)
static

Definition at line 211 of file compile.c.

212 {
213  assert(ctx->code_size >= ctx->code_off);
214 
215  if(ctx->code_size == ctx->code_off) {
216  instr_t *new_instrs;
217