ReactOS 0.4.17-dev-357-ga8f14ff
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 int function_local_cmp (const void *key, const struct wine_rb_entry *entry)
 
static BOOL alloc_local_scope (compiler_ctx_t *ctx, unsigned int *scope_index)
 
static void remove_local_scope (compiler_ctx_t *ctx, unsigned int scope_index)
 
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)
 
void set_compiler_loc (compiler_ctx_t *ctx, unsigned loc)
 
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 emit_member_expression (compiler_ctx_t *ctx, expression_t *expr)
 
static void push_compiler_statement_ctx (compiler_ctx_t *ctx, statement_ctx_t *stat_ctx)
 
static void pop_compiler_statement_ctx (compiler_ctx_t *ctx, statement_ctx_t *stat_ctx)
 
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, block_statement_t *block, 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 function_local_tfind_local (compiler_ctx_t *ctx, const WCHAR *name, unsigned int scope)
 
static BOOL alloc_local (compiler_ctx_t *ctx, BSTR name, int ref, unsigned int scope)
 
static BOOL alloc_variable (compiler_ctx_t *ctx, const WCHAR *name, unsigned int scope)
 
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_ctx_t *, statement_t *)
 
static HRESULT visit_block_statement (compiler_ctx_t *ctx, block_statement_t *block, statement_t *iter)
 
static void resolve_labels (compiler_ctx_t *ctx, unsigned off)
 
unsigned get_location_line (bytecode_t *code, unsigned loc, unsigned *char_pos)
 
void release_bytecode (bytecode_t *code)
 
static HRESULT init_code (compiler_ctx_t *compiler, const WCHAR *source, UINT64 source_context, unsigned start_line)
 
static HRESULT compile_function (compiler_ctx_t *ctx, statement_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, UINT64 source_context, unsigned start_line, const WCHAR *args, const WCHAR *delimiter, BOOL from_eval, BOOL use_decode, named_item_t *named_item, 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 455 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 457 of file compile.c.

458{
459 if(!ctx->labels_size) {
460 ctx->labels = malloc(8 * sizeof(*ctx->labels));
461 if(!ctx->labels)
462 return 0;
463 ctx->labels_size = 8;
464 }else if(ctx->labels_size == ctx->labels_cnt) {
465 unsigned *new_labels;
466
467 new_labels = realloc(ctx->labels, 2*ctx->labels_size*sizeof(*ctx->labels));
468 if(!new_labels)
469 return 0;
470
471 ctx->labels = new_labels;
472 ctx->labels_size *= 2;
473 }
474
475 return ctx->labels_cnt++ | LABEL_FLAG;
476}
#define realloc
Definition: debug_ros.c:6
#define malloc
Definition: debug_ros.c:4
#define LABEL_FLAG
Definition: compile.c:455

Referenced by compile_dowhile_statement(), compile_for_statement(), compile_foreach_statement(), compile_forin_statement(), compile_forto_statement(), compile_func(), compile_if_statement(), compile_labelled_statement(), compile_select_statement(), compile_switch_statement(), and compile_while_statement().

◆ alloc_local()

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

Definition at line 1983 of file compile.c.

1984{
1986
1987 local = heap_pool_alloc(&ctx->heap, sizeof(*local));
1988 if(!local)
1989 return FALSE;
1990
1991 local->name = name;
1992 local->ref = ref;
1993 wine_rb_put(&ctx->local_scopes[scope].locals, name, &local->entry);
1994 ctx->local_scopes[scope].locals_cnt++;
1995 return TRUE;
1996}
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define local
Definition: zutil.h:30
void * heap_pool_alloc(heap_pool_t *, DWORD) __WINE_ALLOC_SIZE(2)
Definition: jsutils.c:72
#define wine_rb_put
Definition: rbtree.h:410
char * name
Definition: compiler.c:66
struct list entry
Definition: wpp.c:51
Definition: name.c:39
Definition: send.c:48

Referenced by alloc_variable(), and compile_function().

◆ alloc_local_scope()

static BOOL alloc_local_scope ( compiler_ctx_t ctx,
unsigned int scope_index 
)
static

Definition at line 147 of file compile.c.

148{
149 unsigned int scope, new_size;
150 void *new_alloc;
151
152 scope = ctx->local_scope_count++;
153 if (scope == ctx->local_scope_size)
154 {
155 new_size = max(1, ctx->local_scope_size * 2);
156 if (!(new_alloc = realloc(ctx->local_scopes, new_size * sizeof(*ctx->local_scopes))))
157 return FALSE;
158 ctx->local_scopes = new_alloc;
159 ctx->local_scope_size = new_size;
160 }
161
162 ctx->local_scopes[scope].locals_cnt = 0;
163 ctx->local_scopes[scope].ref_index = scope_index;
164 wine_rb_init(&ctx->local_scopes[scope].locals, function_local_cmp);
165 *scope_index = scope;
166
167 return TRUE;
168}
size_t const new_size
Definition: expand.cpp:66
static int function_local_cmp(const void *key, const struct wine_rb_entry *entry)
Definition: compile.c:141
#define wine_rb_init
Definition: rbtree.h:406
#define max(a, b)
Definition: svc.c:63

Referenced by compile_function(), visit_block_statement(), and visit_statement().

◆ alloc_variable()

static BOOL alloc_variable ( compiler_ctx_t ctx,
const WCHAR name,
unsigned int  scope 
)
static

Definition at line 1998 of file compile.c.

1999{
2000 BSTR ident;
2001
2002 if(find_local(ctx, name, scope))
2003 return TRUE;
2004
2006 if(!ident)
2007 return FALSE;
2008
2009 return alloc_local(ctx, ident, ctx->func->var_cnt++, scope);
2010}
OLECHAR * BSTR
Definition: compat.h:2293
static BSTR compiler_alloc_bstr(compiler_ctx_t *ctx, const WCHAR *str)
Definition: compile.c:243
static function_local_t * find_local(compiler_ctx_t *ctx, const WCHAR *name, unsigned int scope)
Definition: compile.c:1977
static BOOL alloc_local(compiler_ctx_t *ctx, BSTR name, int ref, unsigned int scope)
Definition: compile.c:1983
_In_ ULONG _In_ ULONG_PTR ident
Definition: winddi.h:3994

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 489 of file compile.c.

490{
491 statement_ctx_t *iter;
493
494 for(iter = ctx->stat_ctx; iter; iter = iter->next) {
495 if(iter->using_scope)
496 {
497 if (!iter->block_scope)
498 return FALSE;
499
500 if ((ref = lookup_local(ctx->func, identifier, iter->scope_index)))
501 {
502 *ret_ref = ref->ref;
503 return TRUE;
504 }
505 }
506 }
507
508 ref = lookup_local(ctx->func, identifier, 0);
509 if(!ref)
510 return FALSE;
511
512 *ret_ref = ref->ref;
513 return TRUE;
514}
local_ref_t * lookup_local(const function_code_t *function, const WCHAR *identifier, unsigned int scope)
Definition: engine.c:865
BOOL using_scope
Definition: compile.c:34
BOOL block_scope
Definition: compile.c:43
unsigned int scope_index
Definition: compile.c:42
struct _statement_ctx_t * next
Definition: compile.c:45

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 2709 of file compile.c.

2710{
2711 HRESULT hres;
2712
2713 hres = parse_arguments(ctx, args, NULL, &ctx->code->global_code.param_cnt);
2714 if(FAILED(hres))
2715 return hres;
2716
2717 ctx->code->global_code.params = compiler_alloc(ctx->code,
2718 ctx->code->global_code.param_cnt * sizeof(*ctx->code->global_code.params));
2719 if(!ctx->code->global_code.params)
2720 return E_OUTOFMEMORY;
2721
2722 return parse_arguments(ctx, args, ctx->code->global_code.params, NULL);
2723}
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define NULL
Definition: types.h:112
#define FAILED(hr)
Definition: intsafe.h:51
static HRESULT parse_arguments(compiler_ctx_t *ctx, const WCHAR *args, BSTR *arg_array, unsigned *args_size)
Definition: compile.c:2655
static void * compiler_alloc(bytecode_t *code, size_t size)
Definition: compile.c:184
HRESULT hres
Definition: protocol.c:465
Definition: match.c:390

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 951 of file compile.c.

952{
953 unsigned length = 0;
954 array_element_t *iter;
955 unsigned array_instr;
957
958 array_instr = push_instr(ctx, OP_carray);
959
960 for(iter = expr->element_list; iter; iter = iter->next) {
961 length += iter->elision;
962
964 if(FAILED(hres))
965 return hres;
966
967 hres = push_instr_uint(ctx, OP_carray_set, length);
968 if(FAILED(hres))
969 return hres;
970
971 length++;
972 }
973
974 instr_ptr(ctx, array_instr)->u.arg[0].uint = length + expr->length;
975 return S_OK;
976}
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
#define S_OK
Definition: intsafe.h:52
static HRESULT compile_expression(compiler_ctx_t *, expression_t *, BOOL)
Definition: compile.c:1021
static unsigned push_instr(compiler_ctx_t *ctx, jsop_t op)
Definition: compile.c:272
static HRESULT push_instr_uint(compiler_ctx_t *ctx, jsop_t op, unsigned arg)
Definition: compile.c:405
static instr_t * instr_ptr(compiler_ctx_t *ctx, unsigned off)
Definition: compile.c:292
expression_t * expr
Definition: parser.h:360
struct _array_element_t * next
Definition: parser.h:362
Definition: query.h:86
instr_arg_t arg[2]
Definition: engine.h:136
union instr_t::@435 u
unsigned uint
Definition: engine.h:118

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 824 of file compile.c.

825{
826 jsop_t assign_op = OP_throw_ref;
827 unsigned arg_cnt = 0;
829
830 if(expr->expression1->type == EXPR_CALL) {
831 call_expression_t *call_expr = (call_expression_t*)expr->expression1;
833
834 if(is_memberid_expr(call_expr->expression->type) && call_expr->argument_list) {
835 hres = compile_memberid_expression(ctx, call_expr->expression, fdexNameEnsure);
836 if(FAILED(hres))
837 return hres;
838
839 for(arg = call_expr->argument_list; arg; arg = arg->next) {
841 if(FAILED(hres))
842 return hres;
843 arg_cnt++;
844 }
845
846 if(op != OP_LAST) {
847 unsigned instr;
848
849 /* We need to call the functions twice: to get the value and to set it.
850 * JavaScript interpreted functions may to modify value on the stack,
851 * but assignment calls are allowed only on external functions, so we
852 * may reuse the stack here. */
853 instr = push_instr(ctx, OP_call_member);
854 if(!instr)
855 return E_OUTOFMEMORY;
856 instr_ptr(ctx, instr)->u.arg[0].uint = arg_cnt;
857 instr_ptr(ctx, instr)->u.arg[1].lng = 1;
858
859 if(!push_instr(ctx, OP_push_acc))
860 return E_OUTOFMEMORY;
861 }
862 assign_op = OP_assign_call;
863 }
864 }else if(is_memberid_expr(expr->expression1->type)) {
865 if(op != OP_LAST || expr->expression1->type == EXPR_IDENT) {
866 hres = compile_memberid_expression(ctx, expr->expression1, fdexNameEnsure);
867 if(FAILED(hres))
868 return hres;
869 if(op != OP_LAST && !push_instr(ctx, OP_refval))
870 return E_OUTOFMEMORY;
871 assign_op = OP_assign;
872 }else {
873 hres = emit_member_expression(ctx, expr->expression1);
874 if(FAILED(hres))
875 return hres;
876 assign_op = OP_set_member;
877 }
878 }
879
880 if(assign_op == OP_throw_ref) {
881 /* Illegal assignment: evaluate and throw */
882 hres = compile_expression(ctx, expr->expression1, TRUE);
883 if(FAILED(hres))
884 return hres;
886 }
887
888 hres = compile_expression(ctx, expr->expression2, TRUE);
889 if(FAILED(hres))
890 return hres;
891
892 if(op != OP_LAST && !push_instr(ctx, op))
893 return E_OUTOFMEMORY;
894
895 return push_instr_uint(ctx, assign_op, arg_cnt);
896}
UINT op
Definition: effect.c:236
@ EXPR_CALL
Definition: parser.h:279
@ EXPR_IDENT
Definition: parser.h:282
jsop_t
Definition: engine.h:105
@ OP_LAST
Definition: engine.h:109
static HRESULT emit_member_expression(compiler_ctx_t *ctx, expression_t *expr)
Definition: compile.c:532
static BOOL is_memberid_expr(expression_type_t type)
Definition: compile.c:484
static HRESULT compile_memberid_expression(compiler_ctx_t *ctx, expression_t *expr, unsigned flags)
Definition: compile.c:589
#define JS_E_ILLEGAL_ASSIGN
Definition: jscript.h:556
expression_type_t type
Definition: parser.h:289
expression_t * expression
Definition: parser.h:344
argument_t * argument_list
Definition: parser.h:345
int type
Definition: query.h:87
LONG lng
Definition: engine.h:116
static unsigned arg_cnt(const DISPPARAMS *dp)
Definition: vbscript.h:175

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 417 of file compile.c.

418{
420
421 hres = compile_expression(ctx, expr->expression1, TRUE);
422 if(FAILED(hres))
423 return hres;
424
425 hres = compile_expression(ctx, expr->expression2, TRUE);
426 if(FAILED(hres))
427 return hres;
428
429 return push_instr(ctx, op) ? S_OK : E_OUTOFMEMORY;
430}

Referenced by compile_expression().

◆ compile_block_statement()

static HRESULT compile_block_statement ( compiler_ctx_t ctx,
block_statement_t block,
statement_t iter 
)
static

Definition at line 1211 of file compile.c.

1212{
1213 statement_ctx_t stat_ctx = {0, TRUE};
1214 BOOL needs_scope;
1215 HRESULT hres;
1216
1217 needs_scope = block && block->scope_index;
1218 if (needs_scope)
1219 {
1220 if(FAILED(hres = push_instr_uint(ctx, OP_push_block_scope, block->scope_index)))
1221 return hres;
1222
1223 stat_ctx.scope_index = block->scope_index;
1224 stat_ctx.block_scope = TRUE;
1225 }
1226
1227 while(iter) {
1228 hres = compile_statement(ctx, needs_scope ? &stat_ctx : NULL, iter);
1229 if(FAILED(hres))
1230 return hres;
1231
1232 iter = iter->next;
1233 }
1234
1235 if(needs_scope && !push_instr(ctx, OP_pop_scope))
1236 return E_OUTOFMEMORY;
1237
1238 return S_OK;
1239}
unsigned int BOOL
Definition: ntddk_ex.h:94
static HRESULT compile_statement(compiler_ctx_t *, statement_ctx_t *, statement_t *)
Definition: compile.c:1911
statement_t * next
Definition: parser.h:129
static unsigned int block
Definition: xmlmemory.c:101

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 1615 of file compile.c.

1616{
1617 statement_ctx_t *pop_ctx;
1618 HRESULT hres;
1619
1620 if(stat->identifier) {
1621 for(pop_ctx = ctx->stat_ctx; pop_ctx; pop_ctx = pop_ctx->next) {
1622 if(pop_ctx->labelled_stat && !wcscmp(pop_ctx->labelled_stat->identifier, stat->identifier)) {
1623 assert(pop_ctx->break_label);
1624 break;
1625 }
1626 }
1627
1628 if(!pop_ctx) {
1629 WARN("Label not found\n");
1630 return JS_E_LABEL_NOT_FOUND;
1631 }
1632 }else {
1633 for(pop_ctx = ctx->stat_ctx; pop_ctx; pop_ctx = pop_ctx->next) {
1634 if(pop_ctx->break_label && !pop_ctx->labelled_stat)
1635 break;
1636 }
1637
1638 if(!pop_ctx) {
1639 WARN("Break outside loop\n");
1640 return JS_E_INVALID_BREAK;
1641 }
1642 }
1643
1644 hres = pop_to_stat(ctx, pop_ctx->next);
1645 if(FAILED(hres))
1646 return hres;
1647
1648 return push_instr_uint(ctx, OP_jmp, pop_ctx->break_label);
1649}
#define WARN(fmt,...)
Definition: precomp.h:61
#define assert(_expr)
Definition: assert.h:32
_ACRTIMP int __cdecl wcscmp(const wchar_t *, const wchar_t *)
Definition: wcs.c:1977
static HRESULT pop_to_stat(compiler_ctx_t *ctx, statement_ctx_t *stat_ctx)
Definition: compile.c:1529
#define JS_E_INVALID_BREAK
Definition: jscript.h:545
#define JS_E_LABEL_NOT_FOUND
Definition: jscript.h:548
const labelled_statement_t * labelled_stat
Definition: compile.c:40
unsigned break_label
Definition: compile.c:37
const WCHAR * identifier
Definition: parser.h:196
Definition: stat.h:66

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 721 of file compile.c.

722{
723 unsigned arg_cnt = 0, extra_args = 0;
724 HRESULT hres = S_OK;
726 unsigned instr;
727 jsop_t op;
728
729 if(is_memberid_expr(expr->expression->type)) {
730 if(expr->expression->type == EXPR_IDENT && !wcscmp(((identifier_expression_t*)expr->expression)->identifier, L"eval"))
731 op = OP_call_eval;
732 else {
733 op = OP_call_member;
734 extra_args = 2;
735 hres = compile_memberid_expression(ctx, expr->expression, 0);
736 }
737 }else {
738 op = OP_call;
739 extra_args = 1;
740 hres = compile_expression(ctx, expr->expression, TRUE);
741 }
742
743 if(FAILED(hres))
744 return hres;
745
746 for(arg = expr->argument_list; arg; arg = arg->next) {
748 if(FAILED(hres))
749 return hres;
750 arg_cnt++;
751 }
752
753 instr = push_instr(ctx, op);
754 if(!instr)
755 return E_OUTOFMEMORY;
756
757 instr_ptr(ctx, instr)->u.arg[0].uint = arg_cnt;
758 instr_ptr(ctx, instr)->u.arg[1].lng = emit_ret;
759
760 hres = push_instr_uint(ctx, OP_pop, arg_cnt + extra_args);
761 if(FAILED(hres))
762 return hres;
763
764 return !emit_ret || push_instr(ctx, OP_push_acc) ? S_OK : E_OUTOFMEMORY;
765}
#define L(x)
Definition: resources.c:13
void * arg
Definition: msvc.h:10

Referenced by compile_call_statement(), and 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 625 of file compile.c.

626{
628
629 hres = compile_expression(ctx, expr->expression1, FALSE);
630 if(FAILED(hres))
631 return hres;
632
633 return compile_expression(ctx, expr->expression2, emit_ret);
634}

Referenced by compile_expression().

◆ compile_conditional_expression()

static HRESULT compile_conditional_expression ( compiler_ctx_t ctx,
conditional_expression_t expr 
)
static

Definition at line 659 of file compile.c.

660{
661 unsigned jmp_false, jmp_end;
663
664 hres = compile_expression(ctx, expr->expression, TRUE);
665 if(FAILED(hres))
666 return hres;
667
668 jmp_false = push_instr(ctx, OP_cnd_z);
669 if(!jmp_false)
670 return E_OUTOFMEMORY;
671
672 hres = compile_expression(ctx, expr->true_expression, TRUE);
673 if(FAILED(hres))
674 return hres;
675
676 jmp_end = push_instr(ctx, OP_jmp);
677 if(!jmp_end)
678 return E_OUTOFMEMORY;
679
680 set_arg_uint(ctx, jmp_false, ctx->code_off);
681 hres = push_instr_uint(ctx, OP_pop, 1);
682 if(FAILED(hres))
683 return hres;
684
685 hres = compile_expression(ctx, expr->false_expression, TRUE);
686 if(FAILED(hres))
687 return hres;
688
689 set_arg_uint(ctx, jmp_end, ctx->code_off);
690 return S_OK;
691}
static void set_arg_uint(compiler_ctx_t *ctx, unsigned instr, unsigned arg)
Definition: compile.c:400

Referenced by compile_expression().

◆ compile_continue_statement()

static HRESULT compile_continue_statement ( compiler_ctx_t ctx,
branch_statement_t stat 
)
static

Definition at line 1562 of file compile.c.

1563{
1564 statement_ctx_t *pop_ctx;
1565 HRESULT hres;
1566
1567 if(stat->identifier) {
1568 statement_t *label_stat;
1569 statement_ctx_t *iter;
1570
1571 pop_ctx = NULL;
1572
1573 for(iter = ctx->stat_ctx; iter; iter = iter->next) {
1574 if(iter->continue_label)
1575 pop_ctx = iter;
1576 if(iter->labelled_stat && !wcscmp(iter->labelled_stat->identifier, stat->identifier))
1577 break;
1578 }
1579
1580 if(!iter) {
1581 WARN("Label not found\n");
1582 return JS_E_LABEL_NOT_FOUND;
1583 }
1584
1585 /* Labelled continue are allowed only on loops */
1586 for(label_stat = iter->labelled_stat->statement;
1587 label_stat->type == STAT_LABEL;
1588 label_stat = ((labelled_statement_t*)label_stat)->statement);
1589 if(!is_loop_statement(label_stat->type)) {
1590 WARN("Label is not a loop\n");
1591 return JS_E_INVALID_CONTINUE;
1592 }
1593
1594 assert(pop_ctx != NULL);
1595 }else {
1596 for(pop_ctx = ctx->stat_ctx; pop_ctx; pop_ctx = pop_ctx->next) {
1597 if(pop_ctx->continue_label)
1598 break;
1599 }
1600
1601 if(!pop_ctx) {
1602 WARN("continue outside loop\n");
1603 return JS_E_INVALID_CONTINUE;
1604 }
1605 }
1606
1607 hres = pop_to_stat(ctx, pop_ctx);
1608 if(FAILED(hres))
1609 return hres;
1610
1611 return push_instr_uint(ctx, OP_jmp, pop_ctx->continue_label);
1612}
@ STAT_LABEL
Definition: parser.h:117
static BOOL is_loop_statement(statement_type_t type)
Definition: compile.c:1205
#define JS_E_INVALID_CONTINUE
Definition: jscript.h:546
unsigned continue_label
Definition: compile.c:38
statement_type_t type
Definition: parser.h:128
statement_t * statement
Definition: parser.h:197

Referenced by compile_statement().

◆ compile_delete_expression()

static HRESULT compile_delete_expression ( compiler_ctx_t ctx,
unary_expression_t expr 
)
static

Definition at line 767 of file compile.c.

768{
770
771 switch(expr->expression->type) {
772 case EXPR_ARRAY: {
773 binary_expression_t *array_expr = (binary_expression_t*)expr->expression;
774
775 hres = compile_expression(ctx, array_expr->expression1, TRUE);
776 if(FAILED(hres))
777 return hres;
778
779 hres = compile_expression(ctx, array_expr->expression2, TRUE);
780 if(FAILED(hres))
781 return hres;
782
783 if(!push_instr(ctx, OP_delete))
784 return E_OUTOFMEMORY;
785 break;
786 }
787 case EXPR_MEMBER: {
788 member_expression_t *member_expr = (member_expression_t*)expr->expression;
789 jsstr_t *jsstr;
790
791 hres = compile_expression(ctx, member_expr->expression, TRUE);
792 if(FAILED(hres))
793 return hres;
794
795 /* FIXME: Potential optimization */
796 jsstr = compiler_alloc_string(ctx, member_expr->identifier);
797 if(!jsstr)
798 return E_OUTOFMEMORY;
799
800 hres = push_instr_str(ctx, OP_str, jsstr);
801 if(FAILED(hres))
802 return hres;
803
804 if(!push_instr(ctx, OP_delete))
805 return E_OUTOFMEMORY;
806 break;
807 }
808 case EXPR_IDENT:
809 return push_instr_bstr(ctx, OP_delete_ident, ((identifier_expression_t*)expr->expression)->identifier);
810 default: {
811 WARN("invalid delete, unimplemented exception message\n");
812
813 hres = compile_expression(ctx, expr->expression, TRUE);
814 if(FAILED(hres))
815 return hres;
816
817 return push_instr_uint_str(ctx, OP_throw_type, JS_E_INVALID_DELETE, L"FIXME");
818 }
819 }
820
821 return S_OK;
822}
@ EXPR_MEMBER
Definition: parser.h:277
@ EXPR_ARRAY
Definition: parser.h:276
static HRESULT push_instr_bstr(compiler_ctx_t *ctx, jsop_t op, const WCHAR *arg)
Definition: compile.c:335
static HRESULT push_instr_uint_str(compiler_ctx_t *ctx, jsop_t op, unsigned arg1, const WCHAR *arg2)
Definition: compile.c:370
static jsstr_t * compiler_alloc_string(compiler_ctx_t *ctx, const WCHAR *str)
Definition: compile.c:217
static HRESULT push_instr_str(compiler_ctx_t *ctx, jsop_t op, jsstr_t *str)
Definition: compile.c:310
#define JS_E_INVALID_DELETE
Definition: jscript.h:560
Definition: jsstr.h:36
expression_t * expression1
Definition: parser.h:314
expression_t * expression2
Definition: parser.h:315
const WCHAR * identifier
Definition: parser.h:333
expression_t * expression
Definition: parser.h:332

Referenced by compile_expression().

◆ compile_expression()

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

Definition at line 1021 of file compile.c.

1022{
1023 HRESULT hres;
1024
1025 switch(expr->type) {
1026 case EXPR_ADD:
1028 break;
1029 case EXPR_AND:
1031 break;
1032 case EXPR_ARRAY:
1034 break;
1035 case EXPR_ARRAYLIT:
1037 break;
1038 case EXPR_ASSIGN:
1040 break;
1041 case EXPR_ASSIGNADD:
1043 break;
1044 case EXPR_ASSIGNAND:
1046 break;
1047 case EXPR_ASSIGNSUB:
1049 break;
1050 case EXPR_ASSIGNMUL:
1052 break;
1053 case EXPR_ASSIGNDIV:
1055 break;
1056 case EXPR_ASSIGNMOD:
1058 break;
1059 case EXPR_ASSIGNOR:
1061 break;
1062 case EXPR_ASSIGNLSHIFT:
1064 break;
1065 case EXPR_ASSIGNRSHIFT:
1067 break;
1068 case EXPR_ASSIGNRRSHIFT:
1070 break;
1071 case EXPR_ASSIGNXOR:
1073 break;
1074 case EXPR_BAND:
1076 break;
1077 case EXPR_BITNEG:
1079 break;
1080 case EXPR_BOR:
1082 break;
1083 case EXPR_CALL:
1085 case EXPR_COMMA:
1087 case EXPR_COND:
1089 break;
1090 case EXPR_DELETE:
1092 break;
1093 case EXPR_DIV:
1095 break;
1096 case EXPR_EQ:
1098 break;
1099 case EXPR_EQEQ:
1101 break;
1102 case EXPR_FUNC:
1104 case EXPR_GREATER:
1106 break;
1107 case EXPR_GREATEREQ:
1109 break;
1110 case EXPR_IDENT:
1112 break;
1113 case EXPR_IN:
1115 break;
1116 case EXPR_INSTANCEOF:
1118 break;
1119 case EXPR_LESS:
1121 break;
1122 case EXPR_LESSEQ:
1124 break;
1125 case EXPR_LITERAL:
1127 break;
1128 case EXPR_LOGNEG:
1130 break;
1131 case EXPR_LSHIFT:
1133 break;
1134 case EXPR_MEMBER:
1136 break;
1137 case EXPR_MINUS:
1139 break;
1140 case EXPR_MOD:
1142 break;
1143 case EXPR_MUL:
1145 break;
1146 case EXPR_NEW:
1148 break;
1149 case EXPR_NOTEQ:
1151 break;
1152 case EXPR_NOTEQEQ:
1154 break;
1155 case EXPR_OR:
1157 break;
1158 case EXPR_PLUS:
1160 break;
1161 case EXPR_POSTDEC:
1163 break;
1164 case EXPR_POSTINC:
1166 break;
1167 case EXPR_PREDEC:
1169 break;
1170 case EXPR_PREINC:
1172 break;
1173 case EXPR_PROPVAL:
1175 break;
1176 case EXPR_RSHIFT:
1178 break;
1179 case EXPR_RRSHIFT:
1181 break;
1182 case EXPR_SUB:
1184 break;
1185 case EXPR_THIS:
1186 return !emit_ret || push_instr(ctx, OP_this) ? S_OK : E_OUTOFMEMORY;
1187 case EXPR_TYPEOF:
1189 break;
1190 case EXPR_VOID:
1192 break;
1193 case EXPR_BXOR:
1195 break;
1197 }
1198
1199 if(FAILED(hres))
1200 return hres;
1201
1202 return emit_ret ? S_OK : push_instr_uint(ctx, OP_pop, 1);
1203}
@ EXPR_PREDEC
Definition: parser.h:249
@ EXPR_RSHIFT
Definition: parser.h:261
@ EXPR_LESS
Definition: parser.h:254
@ EXPR_ASSIGNADD
Definition: parser.h:267
@ EXPR_GREATER
Definition: parser.h:256
@ EXPR_THIS
Definition: parser.h:280
@ EXPR_BOR
Definition: parser.h:231
@ EXPR_LITERAL
Definition: parser.h:285
@ EXPR_EQEQ
Definition: parser.h:251
@ EXPR_ASSIGNRRSHIFT
Definition: parser.h:266
@ EXPR_ASSIGNDIV
Definition: parser.h:270
@ EXPR_ASSIGNMUL
Definition: parser.h:269
@ EXPR_BXOR
Definition: parser.h:232
@ EXPR_ASSIGNMOD
Definition: parser.h:271
@ EXPR_MOD
Definition: parser.h:240
@ EXPR_FUNC
Definition: parser.h:281
@ EXPR_BAND
Definition: parser.h:233
@ EXPR_VOID
Definition: parser.h:242
@ EXPR_NEW
Definition: parser.h:278
@ EXPR_POSTDEC
Definition: parser.h:247
@ EXPR_ASSIGNOR
Definition: parser.h:273
@ EXPR_GREATEREQ
Definition: parser.h:257
@ EXPR_ASSIGNLSHIFT
Definition: parser.h:264
@ EXPR_LSHIFT
Definition: parser.h:260
@ EXPR_LOGNEG
Definition: parser.h:259
@ EXPR_PROPVAL
Definition: parser.h:284
@ EXPR_DELETE
Definition: parser.h:241
@ EXPR_ARRAYLIT
Definition: parser.h:283
@ EXPR_DIV
Definition: parser.h:239
@ EXPR_ADD
Definition: parser.h:236
@ EXPR_ASSIGN
Definition: parser.h:263
@ EXPR_TYPEOF
Definition: parser.h:243
@ EXPR_IN
Definition: parser.h:235
@ EXPR_INSTANCEOF
Definition: parser.h:234
@ EXPR_PLUS
Definition: parser.h:245
@ EXPR_MUL
Definition: parser.h:238
@ EXPR_BITNEG
Definition: parser.h:258
@ EXPR_COND
Definition: parser.h:275
@ EXPR_PREINC
Definition: parser.h:248
@ EXPR_OR
Definition: parser.h:229
@ EXPR_NOTEQ
Definition: parser.h:252
@ EXPR_NOTEQEQ
Definition: parser.h:253
@ EXPR_POSTINC
Definition: parser.h:246
@ EXPR_ASSIGNAND
Definition: parser.h:272
@ EXPR_RRSHIFT
Definition: parser.h:262
@ EXPR_ASSIGNSUB
Definition: parser.h:268
@ EXPR_SUB
Definition: parser.h:237
@ EXPR_EQ
Definition: parser.h:250
@ EXPR_ASSIGNRSHIFT
Definition: parser.h:265
@ EXPR_LESSEQ
Definition: parser.h:255
@ EXPR_MINUS
Definition: parser.h:244
@ EXPR_COMMA
Definition: parser.h:228
@ EXPR_ASSIGNXOR
Definition: parser.h:274
@ EXPR_AND
Definition: parser.h:230
static HRESULT compile_comma_expression(compiler_ctx_t *ctx, binary_expression_t *expr, BOOL emit_ret)
Definition: compile.c:625
static HRESULT compile_new_expression(compiler_ctx_t *ctx, call_expression_t *expr)
Definition: compile.c:693
static HRESULT compile_conditional_expression(compiler_ctx_t *ctx, conditional_expression_t *expr)
Definition: compile.c:659
static HRESULT compile_member_expression(compiler_ctx_t *ctx, member_expression_t *expr)
Definition: compile.c:444
static HRESULT compile_logical_expression(compiler_ctx_t *ctx, binary_expression_t *expr, jsop_t op)
Definition: compile.c:637
static HRESULT compile_binary_expression(compiler_ctx_t *ctx, binary_expression_t *expr, jsop_t op)
Definition: compile.c:417
static HRESULT compile_typeof_expression(compiler_ctx_t *ctx, unary_expression_t *expr)
Definition: compile.c:898
static HRESULT compile_literal(compiler_ctx_t *ctx, literal_t *literal)
Definition: compile.c:919
static HRESULT compile_array_literal(compiler_ctx_t *ctx, array_literal_expression_t *expr)
Definition: compile.c:951
static HRESULT compile_unary_expression(compiler_ctx_t *ctx, unary_expression_t *expr, jsop_t op)
Definition: compile.c:432
static HRESULT compile_function_expression(compiler_ctx_t *ctx, function_expression_t *expr, BOOL emit_ret)
Definition: compile.c:1004
static HRESULT compile_assign_expression(compiler_ctx_t *ctx, binary_expression_t *expr, jsop_t op)
Definition: compile.c:824
static HRESULT emit_identifier(compiler_ctx_t *ctx, const WCHAR *identifier)
Definition: compile.c:524
static HRESULT compile_increment_expression(compiler_ctx_t *ctx, unary_expression_t *expr, jsop_t op, int n)
Definition: compile.c:605
static HRESULT compile_object_literal(compiler_ctx_t *ctx, property_value_expression_t *expr)
Definition: compile.c:978
static HRESULT compile_call_expression(compiler_ctx_t *ctx, call_expression_t *expr, BOOL emit_ret)
Definition: compile.c:721
static HRESULT compile_delete_expression(compiler_ctx_t *ctx, unary_expression_t *expr)
Definition: compile.c:767
#define DEFAULT_UNREACHABLE

Referenced by compile_args(), compile_array_literal(), compile_assign_expression(), compile_assignment(), compile_binary_expression(), compile_call_expression(), compile_comma_expression(), compile_conditional_expression(), compile_const_statement(), compile_delete_expression(), compile_dowhile_statement(), compile_expression(), compile_expression_statement(), compile_for_statement(), compile_foreach_statement(), compile_forin_statement(), compile_forto_statement(), compile_if_statement(), compile_increment_expression(), compile_logical_expression(), compile_member_call_expression(), compile_member_expression(), compile_new_expression(), compile_object_literal(), compile_return_statement(), compile_retval_statement(), compile_select_statement(), compile_switch_statement(), compile_throw_statement(), compile_typeof_expression(), compile_unary_expression(), compile_variable_list(), compile_while_statement(), compile_with_statement(), and emit_member_expression().

◆ compile_expression_statement()

static HRESULT compile_expression_statement ( compiler_ctx_t ctx,
expression_statement_t stat 
)
static

Definition at line 1282 of file compile.c.

1283{
1284 HRESULT hres;
1285
1286 hres = compile_expression(ctx, stat->expr, ctx->from_eval);
1287 if(FAILED(hres))
1288 return hres;
1289
1290 return !ctx->from_eval || push_instr(ctx, OP_setret) ? S_OK : E_OUTOFMEMORY;
1291}

Referenced by compile_statement().

◆ compile_for_statement()

static HRESULT compile_for_statement ( compiler_ctx_t ctx,
for_statement_t stat 
)
static

Definition at line 1385 of file compile.c.

1386{
1387 statement_ctx_t stat_ctx = {0, FALSE, FALSE};
1388 statement_ctx_t scope_stat_ctx = {0, TRUE};
1389 unsigned expr_off;
1390 HRESULT hres;
1391
1392 if (stat->scope_index)
1393 {
1394 if(FAILED(hres = push_instr_uint(ctx, OP_push_block_scope, stat->scope_index)))
1395 return hres;
1396
1397 scope_stat_ctx.scope_index = stat->scope_index;
1398 scope_stat_ctx.block_scope = TRUE;
1399 push_compiler_statement_ctx(ctx, &scope_stat_ctx);
1400 }
1401
1402 if(stat->variable_list) {
1403 hres = compile_variable_list(ctx, stat->variable_list);
1404 if(FAILED(hres))
1405 goto done;
1406 }else if(stat->begin_expr) {
1407 hres = compile_expression(ctx, stat->begin_expr, FALSE);
1408 if(FAILED(hres))
1409 goto done;
1410 }
1411
1412 stat_ctx.break_label = alloc_label(ctx);
1413 if(!stat_ctx.break_label)
1414 {
1416 goto done;
1417 }
1418
1419 stat_ctx.continue_label = alloc_label(ctx);
1420 if(!stat_ctx.continue_label)
1421 {
1423 goto done;
1424 }
1425 expr_off = ctx->code_off;
1426
1427 if(stat->expr) {
1428 set_compiler_loc(ctx, stat->expr_loc);
1429 hres = compile_expression(ctx, stat->expr, TRUE);
1430 if(FAILED(hres))
1431 goto done;
1432
1433 hres = push_instr_uint(ctx, OP_jmp_z, stat_ctx.break_label);
1434 if(FAILED(hres))
1435 goto done;
1436 }
1437
1438 hres = compile_statement(ctx, &stat_ctx, stat->statement);
1439 if(FAILED(hres))
1440 goto done;
1441
1443
1444 if(stat->end_expr) {
1445 set_compiler_loc(ctx, stat->end_loc);
1446 hres = compile_expression(ctx, stat->end_expr, FALSE);
1447 if(FAILED(hres))
1448 goto done;
1449 }
1450
1451 hres = push_instr_uint(ctx, OP_jmp, expr_off);
1452 if(FAILED(hres))
1453 goto done;
1454
1455 label_set_addr(ctx, stat_ctx.break_label);
1456 hres = S_OK;
1457done:
1458 if (stat->scope_index)
1459 {
1460 pop_compiler_statement_ctx(ctx, &scope_stat_ctx);
1461 if(SUCCEEDED(hres) && !push_instr(ctx, OP_pop_scope))
1462 return E_OUTOFMEMORY;
1463 }
1464 return hres;
1465}
#define SUCCEEDED(hr)
Definition: intsafe.h:50
static unsigned alloc_label(compiler_ctx_t *ctx)
Definition: compile.c:457
static void pop_compiler_statement_ctx(compiler_ctx_t *ctx, statement_ctx_t *stat_ctx)
Definition: compile.c:580
static HRESULT compile_variable_list(compiler_ctx_t *ctx, variable_declaration_t *list)
Definition: compile.c:1242
static void label_set_addr(compiler_ctx_t *ctx, unsigned label)
Definition: compile.c:478
static void push_compiler_statement_ctx(compiler_ctx_t *ctx, statement_ctx_t *stat_ctx)
Definition: compile.c:571
void set_compiler_loc(compiler_ctx_t *ctx, unsigned loc)
Definition: compile.c:267

Referenced by compile_statement().

◆ compile_forin_statement()

static HRESULT compile_forin_statement ( compiler_ctx_t ctx,
forin_statement_t stat 
)
static

Definition at line 1468 of file compile.c.

1469{
1470 statement_ctx_t stat_ctx = {4, FALSE, FALSE};
1471 HRESULT hres;
1472
1473 if(stat->variable) {
1474 hres = compile_variable_list(ctx, stat->variable);
1475 if(FAILED(hres))
1476 return hres;
1477 }
1478
1479 stat_ctx.break_label = alloc_label(ctx);
1480 if(!stat_ctx.break_label)
1481 return E_OUTOFMEMORY;
1482
1483 stat_ctx.continue_label = alloc_label(ctx);
1484 if(!stat_ctx.continue_label)
1485 return E_OUTOFMEMORY;
1486
1487 hres = compile_expression(ctx, stat->in_expr, TRUE);
1488 if(FAILED(hres))
1489 return hres;
1490
1491 if(stat->variable) {
1492 hres = emit_identifier_ref(ctx, stat->variable->identifier, fdexNameEnsure);
1493 if(FAILED(hres))
1494 return hres;
1495 }else if(is_memberid_expr(stat->expr->type)) {
1496 hres = compile_memberid_expression(ctx, stat->expr, fdexNameEnsure);
1497 if(FAILED(hres))
1498 return hres;
1499 }else {
1500 hres = push_instr_uint(ctx, OP_throw_ref, JS_E_ILLEGAL_ASSIGN);
1501 if(FAILED(hres))
1502 return hres;
1503
1504 /* FIXME: compile statement anyways when we depend on compiler to check errors */
1505 return S_OK;
1506 }
1507
1508 hres = push_instr_int(ctx, OP_int, DISPID_STARTENUM);
1509 if(FAILED(hres))
1510 return hres;
1511
1513 hres = push_instr_uint(ctx, OP_forin, stat_ctx.break_label);
1514 if(FAILED(hres))
1515 return E_OUTOFMEMORY;
1516
1517 hres = compile_statement(ctx, &stat_ctx, stat->statement);
1518 if(FAILED(hres))
1519 return hres;
1520
1521 hres = push_instr_uint(ctx, OP_jmp, stat_ctx.continue_label);
1522 if(FAILED(hres))
1523 return hres;
1524
1525 label_set_addr(ctx, stat_ctx.break_label);
1526 return S_OK;
1527}
static HRESULT emit_identifier_ref(compiler_ctx_t *ctx, const WCHAR *identifier, unsigned flags)
Definition: compile.c:516
static HRESULT push_instr_int(compiler_ctx_t *ctx, jsop_t op, LONG arg)
Definition: compile.c:298

Referenced by compile_statement().

◆ compile_function()

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

Definition at line 2517 of file compile.c.

2519{
2522 unsigned off, i, scope;
2523 HRESULT hres;
2524
2525 TRACE("\n");
2526
2527 func->bytecode = ctx->code;
2528 func->local_ref = INVALID_LOCAL_REF;
2529 func->scope_index = 0;
2530 ctx->func_head = ctx->func_tail = NULL;
2531 ctx->from_eval = from_eval;
2532 ctx->func = func;
2533 ctx->local_scope_count = 0;
2534 if (!alloc_local_scope(ctx, &scope))
2535 return E_OUTOFMEMORY;
2536 assert(!scope);
2537
2538 if(func_expr) {
2539 parameter_t *param_iter;
2540
2541 if(func_expr->identifier) {
2542 func->name = compiler_alloc_bstr(ctx, func_expr->identifier);
2543 if(!func->name)
2544 return E_OUTOFMEMORY;
2545 }
2546
2547 if(func_expr->event_target) {
2548 func->event_target = compiler_alloc_bstr(ctx, func_expr->event_target);
2549 if(!func->event_target)
2550 return E_OUTOFMEMORY;
2551 }
2552
2553 func->source = func_expr->src_str;
2554 func->source_len = func_expr->src_len;
2555
2556 for(param_iter = func_expr->parameter_list; param_iter; param_iter = param_iter->next)
2557 func->param_cnt++;
2558
2559 func->params = compiler_alloc(ctx->code, func->param_cnt * sizeof(*func->params));
2560 if(!func->params)
2561 return E_OUTOFMEMORY;
2562
2563 for(param_iter = func_expr->parameter_list, i=0; param_iter; param_iter = param_iter->next, i++) {
2564 func->params[i] = compiler_alloc_bstr(ctx, param_iter->identifier);
2565 if(!func->params[i])
2566 return E_OUTOFMEMORY;
2567 }
2568 }
2569
2570 for(i = func->param_cnt; i--;) {
2571 if(!find_local(ctx, func->params[i], 0) && !alloc_local(ctx, func->params[i], -i-1, 0))
2572 return E_OUTOFMEMORY;
2573 }
2574
2576 if(FAILED(hres))
2577 return hres;
2578
2579 func->local_scope_count = ctx->local_scope_count;
2580 func->local_scopes = compiler_alloc(ctx->code, func->local_scope_count * sizeof(*func->local_scopes));
2581 if(!func->local_scopes)
2582 return E_OUTOFMEMORY;
2583
2584 func->variables = compiler_alloc(ctx->code, func->var_cnt * sizeof(*func->variables));
2585 if(!func->variables)
2586 return E_OUTOFMEMORY;
2587
2588 for (scope = 0; scope < func->local_scope_count; ++scope)
2589 {
2590 func->local_scopes[scope].locals = compiler_alloc(ctx->code,
2591 ctx->local_scopes[scope].locals_cnt * sizeof(*func->local_scopes[scope].locals));
2592 if(!func->local_scopes[scope].locals)
2593 return E_OUTOFMEMORY;
2594 func->local_scopes[scope].locals_cnt = ctx->local_scopes[scope].locals_cnt;
2595
2596 i = 0;
2597 WINE_RB_FOR_EACH_ENTRY(local, &ctx->local_scopes[scope].locals, function_local_t, entry) {
2598 func->local_scopes[scope].locals[i].name = local->name;
2599 func->local_scopes[scope].locals[i].ref = local->ref;
2600 if(local->ref >= 0) {
2601 func->variables[local->ref].name = local->name;
2602 func->variables[local->ref].func_id = -1;
2603 }
2604 i++;
2605 }
2606 assert(i == ctx->local_scopes[scope].locals_cnt);
2607 }
2608
2609 func->funcs = compiler_alloc(ctx->code, func->func_cnt * sizeof(*func->funcs));
2610 if(!func->funcs)
2611 return E_OUTOFMEMORY;
2612 memset(func->funcs, 0, func->func_cnt * sizeof(*func->funcs));
2613
2614 ctx->current_function_expr = ctx->func_head;
2615 off = ctx->code_off;
2617 if(FAILED(hres))
2618 return hres;
2619
2620 resolve_labels(ctx, off);
2621
2622 hres = push_instr_uint(ctx, OP_ret, !from_eval);
2623 if(FAILED(hres))
2624 return hres;
2625
2626 if(TRACE_ON(jscript_disas))
2627 dump_code(ctx, off);
2628
2629 func->instr_off = off;
2630
2631 for(iter = ctx->func_head, i=0; iter; iter = iter->next, i++) {
2632 hres = compile_function(ctx, iter->statement_list, iter, FALSE, func->funcs+i);
2633 if(FAILED(hres))
2634 return hres;
2635
2636 func->funcs[i].scope_index = iter->scope_index;
2637
2638 TRACE("[%d] func %s, scope_index %u\n", i, debugstr_w(func->funcs[i].name), iter->scope_index);
2639 if((ctx->parser->script->version < SCRIPTLANGUAGEVERSION_ES5 || iter->is_statement) &&
2640 func->funcs[i].name && !func->funcs[i].event_target) {
2641 local_ref_t *local_ref = lookup_local(func, func->funcs[i].name, func->funcs[i].scope_index);
2642
2643 func->funcs[i].local_ref = local_ref->ref;
2644 TRACE("found ref %s %d for %s\n", debugstr_w(local_ref->name), local_ref->ref, debugstr_w(func->funcs[i].name));
2645 if(local_ref->ref >= 0)
2646 func->variables[local_ref->ref].func_id = i;
2647 }
2648 }
2649
2650 assert(i == func->func_cnt);
2651
2652 return S_OK;
2653}
#define TRACE_ON(x)
Definition: compat.h:75
#define INVALID_LOCAL_REF
Definition: engine.h:152
GLenum func
Definition: glext.h:6028
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
uint32_t entry
Definition: isohybrid.c:63
static void dump_code(compiler_ctx_t *ctx, unsigned off)
Definition: compile.c:122
static void resolve_labels(compiler_ctx_t *ctx, unsigned off)
Definition: compile.c:2430
static HRESULT compile_function(compiler_ctx_t *ctx, statement_t *source, function_expression_t *func_expr, BOOL from_eval, function_code_t *func)
Definition: compile.c:2517
static BOOL alloc_local_scope(compiler_ctx_t *ctx, unsigned int *scope_index)
Definition: compile.c:147
static HRESULT visit_block_statement(compiler_ctx_t *ctx, block_statement_t *block, statement_t *iter)
Definition: compile.c:2195
static HRESULT compile_block_statement(compiler_ctx_t *ctx, block_statement_t *block, statement_t *iter)
Definition: compile.c:1211
#define SCRIPTLANGUAGEVERSION_ES5
Definition: jscript.h:53
#define debugstr_w
Definition: kernel32.h:32
#define WINE_RB_FOR_EACH_ENTRY
Definition: rbtree.h:415
#define memset(x, y, z)
Definition: compat.h:39
#define TRACE(s)
Definition: solgame.cpp:4
const WCHAR * event_target
Definition: parser.h:300
unsigned int scope_index
Definition: parser.h:307
parameter_t * parameter_list
Definition: parser.h:301
const WCHAR * src_str
Definition: parser.h:303
struct _function_expression_t * next
Definition: parser.h:309
statement_t * statement_list
Definition: parser.h:302
const WCHAR * identifier
Definition: parser.h:299
struct _parameter_t * next
Definition: parser.h:294
const WCHAR * identifier
Definition: parser.h:293
int ref
Definition: engine.h:149
BSTR name
Definition: engine.h:148

Referenced by compile_function(), and 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 1004 of file compile.c.

1005{
1006 statement_ctx_t *stat_ctx;
1007
1008 assert(ctx->current_function_expr);
1009
1010 for(stat_ctx = ctx->stat_ctx; stat_ctx; stat_ctx = stat_ctx->next)
1011 {
1012 if(stat_ctx->block_scope)
1013 break;
1014 }
1015 ctx->current_function_expr->scope_index = stat_ctx ? stat_ctx->scope_index : 0;
1016 ctx->current_function_expr = ctx->current_function_expr->next;
1017
1018 return emit_ret ? push_instr_uint(ctx, OP_func, expr->func_id) : S_OK;
1019}

Referenced by compile_expression().

◆ compile_if_statement()

static HRESULT compile_if_statement ( compiler_ctx_t ctx,
if_statement_t stat 
)
static

Definition at line 1294 of file compile.c.

1295{
1296 unsigned jmp_else;
1297 HRESULT hres;
1298
1299 hres = compile_expression(ctx, stat->expr, TRUE);
1300 if(FAILED(hres))
1301 return hres;
1302
1303 jmp_else = push_instr(ctx, OP_jmp_z);
1304 if(!jmp_else)
1305 return E_OUTOFMEMORY;
1306
1307 hres = compile_statement(ctx, NULL, stat->if_stat);
1308 if(FAILED(hres))
1309 return hres;
1310
1311 if(stat->else_stat) {
1312 unsigned jmp_end;
1313
1314 jmp_end = push_instr(ctx, OP_jmp);
1315 if(!jmp_end)
1316 return E_OUTOFMEMORY;
1317
1318 set_arg_uint(ctx, jmp_else, ctx->code_off);
1319
1320 hres = compile_statement(ctx, NULL, stat->else_stat);
1321 if(FAILED(hres))
1322 return hres;
1323
1324 set_arg_uint(ctx, jmp_end, ctx->code_off);
1325 }else {
1326 set_arg_uint(ctx, jmp_else, ctx->code_off);
1327 }
1328
1329 return S_OK;
1330}

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 605 of file compile.c.

606{
608
609 if(!is_memberid_expr(expr->expression->type)) {
610 hres = compile_expression(ctx, expr->expression, TRUE);
611 if(FAILED(hres))
612 return hres;
613
614 return push_instr_uint(ctx, OP_throw_ref, JS_E_ILLEGAL_ASSIGN);
615 }
616
617 hres = compile_memberid_expression(ctx, expr->expression, fdexNameEnsure);
618 if(FAILED(hres))
619 return hres;
620
621 return push_instr_int(ctx, op, n);
622}
GLdouble n
Definition: glext.h:7729

Referenced by compile_expression().

◆ compile_labelled_statement()

static HRESULT compile_labelled_statement ( compiler_ctx_t ctx,
labelled_statement_t stat 
)
static

Definition at line 1700 of file compile.c.

1701{
1702 statement_ctx_t stat_ctx = {0, FALSE, FALSE, 0, 0, stat}, *iter;
1703 HRESULT hres;
1704
1705 for(iter = ctx->stat_ctx; iter; iter = iter->next) {
1706 if(iter->labelled_stat && !wcscmp(iter->labelled_stat->identifier, stat->identifier)) {
1707 WARN("Label %s redefined\n", debugstr_w(stat->identifier));
1708 return JS_E_LABEL_REDEFINED;
1709 }
1710 }
1711
1712 /* Labelled breaks are allowed for any labelled statements, not only loops (violating spec) */
1713 stat_ctx.break_label = alloc_label(ctx);
1714 if(!stat_ctx.break_label)
1715 return E_OUTOFMEMORY;
1716
1717 hres = compile_statement(ctx, &stat_ctx, stat->statement);
1718 if(FAILED(hres))
1719 return hres;
1720
1721 label_set_addr(ctx, stat_ctx.break_label);
1722 return S_OK;
1723}
#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 919 of file compile.c.

920{
921 switch(literal->type) {
922 case LT_BOOL:
923 return push_instr_int(ctx, OP_bool, literal->u.bval);
924 case LT_DOUBLE:
925 return push_instr_double(ctx, OP_double, literal->u.dval);
926 case LT_NULL:
927 return push_instr(ctx, OP_null) ? S_OK : E_OUTOFMEMORY;
928 case LT_STRING:
929 return push_instr_str(ctx, OP_str, literal->u.str);
930 case LT_REGEXP:
931 return push_instr_str_uint(ctx, OP_regexp, literal->u.regexp.str, literal->u.regexp.flags);
933 }
934 return E_FAIL;
935}
#define E_FAIL
Definition: ddrawi.h:102
@ LT_BOOL
Definition: parser.h:78
@ LT_STRING
Definition: parser.h:77
@ LT_NULL
Definition: parser.h:79
@ LT_REGEXP
Definition: parser.h:80
@ LT_DOUBLE
Definition: parser.h:76
static HRESULT push_instr_str_uint(compiler_ctx_t *ctx, jsop_t op, jsstr_t *str, unsigned arg2)
Definition: compile.c:322
static HRESULT push_instr_double(compiler_ctx_t *ctx, jsop_t op, double arg)
Definition: compile.c:388
struct literal_t::@444::@445 regexp
BOOL bval
Definition: parser.h:88
double dval
Definition: parser.h:86
union literal_t::@444 u
literal_type_t type
Definition: parser.h:84
jsstr_t * str
Definition: parser.h:87

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 637 of file compile.c.

638{
639 unsigned instr;
641
642 hres = compile_expression(ctx, expr->expression1, TRUE);
643 if(FAILED(hres))
644 return hres;
645
646 instr = push_instr(ctx, op);
647 if(!instr)
648 return E_OUTOFMEMORY;
649
650 hres = compile_expression(ctx, expr->expression2, TRUE);
651 if(FAILED(hres))
652 return hres;
653
654 set_arg_uint(ctx, instr, ctx->code_off);
655 return S_OK;
656}

Referenced by compile_expression().

◆ compile_member_expression()

static HRESULT compile_member_expression ( compiler_ctx_t ctx,
member_expression_t expr 
)
static

Definition at line 444 of file compile.c.

445{
447
448 hres = compile_expression(ctx, expr->expression, TRUE);
449 if(FAILED(hres))
450 return hres;
451
452 return push_instr_bstr(ctx, OP_member, expr->identifier);
453}

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 589 of file compile.c.

590{
592
593 if(expr->type == EXPR_IDENT) {
595 return emit_identifier_ref(ctx, ident_expr->identifier, flags);
596 }
597
599 if(FAILED(hres))
600 return hres;
601
602 return push_instr_uint(ctx, OP_memberid, flags);
603}
GLbitfield flags
Definition: glext.h:7161
const WCHAR * identifier
Definition: parser.h:350

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 693 of file compile.c.

694{
695 unsigned arg_cnt = 0;
698
699 hres = compile_expression(ctx, expr->expression, TRUE);
700 if(FAILED(hres))
701 return hres;
702
703 for(arg = expr->argument_list; arg; arg = arg->next) {
705 if(FAILED(hres))
706 return hres;
707 arg_cnt++;
708 }
709
710 hres = push_instr_uint(ctx, OP_new, arg_cnt);
711 if(FAILED(hres))
712 return hres;
713
714 hres = push_instr_uint(ctx, OP_pop, arg_cnt+1);
715 if(FAILED(hres))
716 return hres;
717
718 return push_instr(ctx, OP_push_acc) ? S_OK : E_OUTOFMEMORY;
719}

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 978 of file compile.c.

979{
981 jsstr_t *name;
983
984 if(!push_instr(ctx, OP_new_obj))
985 return E_OUTOFMEMORY;
986
987 for(iter = expr->property_list; iter; iter = iter->next) {
988 hres = literal_as_string(ctx, iter->name, &name);
989 if(FAILED(hres))
990 return hres;
991
993 if(FAILED(hres))
994 return hres;
995
996 hres = push_instr_str_uint(ctx, OP_obj_prop, name, iter->type);
997 if(FAILED(hres))
998 return hres;
999 }
1000
1001 return S_OK;
1002}
static HRESULT literal_as_string(compiler_ctx_t *ctx, literal_t *literal, jsstr_t **str)
Definition: compile.c:937
struct _property_definition_t * next
Definition: parser.h:376
literal_t * name
Definition: parser.h:373
expression_t * value
Definition: parser.h:374

Referenced by compile_expression().

◆ compile_return_statement()

static HRESULT compile_return_statement ( compiler_ctx_t ctx,
expression_statement_t stat 
)
static

Definition at line 1652 of file compile.c.

1653{
1654 HRESULT hres;
1655
1656 if(ctx->from_eval) {
1657 WARN("misplaced return statement\n");
1658 return JS_E_MISPLACED_RETURN;
1659 }
1660
1661 if(stat->expr) {
1662 hres = compile_expression(ctx, stat->expr, TRUE);
1663 if(FAILED(hres))
1664 return hres;
1665 if(!push_instr(ctx, OP_setret))
1666 return E_OUTOFMEMORY;
1667 }
1668
1670 if(FAILED(hres))
1671 return hres;
1672
1673 return push_instr_uint(ctx, OP_ret, !stat->expr);
1674}
#define JS_E_MISPLACED_RETURN
Definition: jscript.h:544

Referenced by compile_statement().

◆ compile_script()

HRESULT compile_script ( script_ctx_t ctx,
const WCHAR code,
UINT64  source_context,
unsigned  start_line,
const WCHAR args,
const WCHAR delimiter,
BOOL  from_eval,
BOOL  use_decode,
named_item_t named_item,
bytecode_t **  ret 
)

Definition at line 2725 of file compile.c.

2728{
2729 compiler_ctx_t compiler = {0};
2730 HRESULT hres;
2731
2732 hres = init_code(&compiler, code, source_context, start_line);
2733 if(FAILED(hres))
2734 return hres;
2735
2736 if(args) {
2737 hres = compile_arguments(&compiler, args);
2738 if(FAILED(hres))
2739 return hres;
2740 }
2741
2742 if(use_decode) {
2743 hres = decode_source(compiler.code->source);
2744 if(FAILED(hres)) {
2745 WARN("Decoding failed\n");
2746 return hres;
2747 }
2748 }
2749
2750 hres = script_parse(ctx, &compiler, compiler.code, delimiter, from_eval, &compiler.parser);
2751 if(FAILED(hres)) {
2752 release_bytecode(compiler.code);
2753 return hres;
2754 }
2755
2756 heap_pool_init(&compiler.heap);
2757 hres = compile_function(&compiler, compiler.parser->source, NULL, from_eval, &compiler.code->global_code);
2758 free(compiler.local_scopes);
2759 heap_pool_free(&compiler.heap);
2760 parser_release(compiler.parser);
2761 if(FAILED(hres)) {
2762 if(hres != DISP_E_EXCEPTION)
2764 set_error_location(ctx->ei, compiler.code, compiler.loc, IDS_COMPILATION_ERROR, NULL);
2765 release_bytecode(compiler.code);
2766 return DISP_E_EXCEPTION;
2767 }
2768
2769 if(named_item) {
2770 compiler.code->named_item = named_item;
2771 named_item->ref++;
2772 }
2773
2774 *ret = compiler.code;
2775 return S_OK;
2776}
#define free
Definition: debug_ros.c:5
HRESULT throw_error(script_ctx_t *ctx, HRESULT error, const WCHAR *str)
Definition: error.c:398
HRESULT script_parse(script_ctx_t *, struct _compiler_ctx_t *, struct _bytecode_t *, const WCHAR *, BOOL, parser_ctx_t **)
void parser_release(parser_ctx_t *)
#define IDS_COMPILATION_ERROR
Definition: resource.h:89
return ret
Definition: mutex.c:146
void set_error_location(jsexcept_t *, bytecode_t *, unsigned, unsigned, jsstr_t *)
Definition: error.c:426
void release_bytecode(bytecode_t *code)
Definition: compile.c:2459
static HRESULT compile_arguments(compiler_ctx_t *ctx, const WCHAR *args)
Definition: compile.c:2709
static HRESULT init_code(compiler_ctx_t *compiler, const WCHAR *source, UINT64 source_context, unsigned start_line)
Definition: compile.c:2481
HRESULT decode_source(WCHAR *code)
Definition: decode.c:111
void heap_pool_init(heap_pool_t *)
Definition: jsutils.c:66
void heap_pool_free(heap_pool_t *)
Definition: jsutils.c:164
const char * delimiter
Definition: string.c:1779
WCHAR * source
Definition: engine.h:201
named_item_t * named_item
Definition: engine.h:199
function_code_t global_code
Definition: engine.h:198
bytecode_t * code
Definition: compile.c:56
heap_pool_t heap
Definition: compile.c:86
struct _compiler_ctx_t::@429 * local_scopes
unsigned loc
Definition: compile.c:80
parser_ctx_t * parser
Definition: compile.c:55
Definition: inflate.c:139
unsigned ref
Definition: jscript.h:152
#define DISP_E_EXCEPTION
Definition: winerror.h:3621

Referenced by builtin_eval(), compile_procedure(), construct_function(), JScriptParse_ParseScriptText(), JScriptParseProcedure_ParseProcedureText(), and VBScriptParse_ParseScriptText().

◆ compile_statement()

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

Definition at line 1911 of file compile.c.

1912{
1913 HRESULT hres;
1914
1916
1917 set_compiler_loc(ctx, stat->loc);
1918
1919 switch(stat->type) {
1920 case STAT_BLOCK:
1922 break;
1923 case STAT_BREAK:
1925 break;
1926 case STAT_CONTINUE:
1928 break;
1929 case STAT_EMPTY:
1930 /* nothing to do */
1931 hres = S_OK;
1932 break;
1933 case STAT_EXPR:
1935 break;
1936 case STAT_FOR:
1938 break;
1939 case STAT_FORIN:
1941 break;
1942 case STAT_IF:
1944 break;
1945 case STAT_LABEL:
1947 break;
1948 case STAT_RETURN:
1950 break;
1951 case STAT_SWITCH:
1953 break;
1954 case STAT_THROW:
1956 break;
1957 case STAT_TRY:
1959 break;
1960 case STAT_VAR:
1962 break;
1963 case STAT_WHILE:
1965 break;
1966 case STAT_WITH:
1968 break;
1970 }
1971
1973
1974 return hres;
1975}
@ STAT_CONTINUE
Definition: parser.h:111
@ STAT_FOR
Definition: parser.h:114
@ STAT_EMPTY
Definition: parser.h:112
@ STAT_THROW
Definition: parser.h:120
@ STAT_SWITCH
Definition: parser.h:119
@ STAT_VAR
Definition: parser.h:122
@ STAT_EXPR
Definition: parser.h:113
@ STAT_TRY
Definition: parser.h:121
@ STAT_RETURN
Definition: parser.h:118
@ STAT_BLOCK
Definition: parser.h:109
@ STAT_WITH
Definition: parser.h:124
@ STAT_IF
Definition: parser.h:116
@ STAT_FORIN
Definition: parser.h:115
@ STAT_BREAK
Definition: parser.h:110
@ STAT_WHILE
Definition: parser.h:123
static HRESULT compile_for_statement(compiler_ctx_t *ctx, for_statement_t *stat)
Definition: compile.c:1385
static HRESULT compile_forin_statement(compiler_ctx_t *ctx, forin_statement_t *stat)
Definition: compile.c:1468
static HRESULT compile_continue_statement(compiler_ctx_t *ctx, branch_statement_t *stat)
Definition: compile.c:1562
static HRESULT compile_return_statement(compiler_ctx_t *ctx, expression_statement_t *stat)
Definition: compile.c:1652
static HRESULT compile_while_statement(compiler_ctx_t *ctx, while_statement_t *stat)
Definition: compile.c:1333
static HRESULT compile_labelled_statement(compiler_ctx_t *ctx, labelled_statement_t *stat)
Definition: compile.c:1700
static HRESULT compile_throw_statement(compiler_ctx_t *ctx, expression_statement_t *stat)
Definition: compile.c:1822
static HRESULT compile_if_statement(compiler_ctx_t *ctx, if_statement_t *stat)
Definition: compile.c:1294
static HRESULT compile_var_statement(compiler_ctx_t *ctx, var_statement_t *stat)
Definition: compile.c:1276
static HRESULT compile_expression_statement(compiler_ctx_t *ctx, expression_statement_t *stat)
Definition: compile.c:1282
static HRESULT compile_break_statement(compiler_ctx_t *ctx, branch_statement_t *stat)
Definition: compile.c:1615
static HRESULT compile_switch_statement(compiler_ctx_t *ctx, switch_statement_t *stat)
Definition: compile.c:1726
static HRESULT compile_try_statement(compiler_ctx_t *ctx, try_statement_t *stat)
Definition: compile.c:1834
static HRESULT compile_with_statement(compiler_ctx_t *ctx, with_statement_t *stat)
Definition: compile.c:1677

Referenced by compile_block_statement(), compile_dowhile_statement(), compile_for_statement(), compile_foreach_statement(), compile_forin_statement(), compile_forto_statement(), compile_func(), compile_if_statement(), compile_labelled_statement(), compile_select_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 1726 of file compile.c.

1727{
1728 statement_ctx_t stat_ctx = {0, FALSE, FALSE};
1729 unsigned case_cnt = 0, *case_jmps, i, default_jmp;
1730 BOOL have_default = FALSE;
1731 statement_t *stat_iter;
1732 case_clausule_t *iter;
1733 HRESULT hres;
1734
1735 hres = compile_expression(ctx, stat->expr, TRUE);
1736 if(FAILED(hres))
1737 return hres;
1738
1739 stat_ctx.break_label = alloc_label(ctx);
1740 if(!stat_ctx.break_label)
1741 return E_OUTOFMEMORY;
1742
1743 for(iter = stat->case_list; iter; iter = iter->next) {
1744 if(iter->expr)
1745 case_cnt++;
1746 }
1747
1748 case_jmps = malloc(case_cnt * sizeof(*case_jmps));
1749 if(!case_jmps)
1750 return E_OUTOFMEMORY;
1751
1752 i = 0;
1753 for(iter = stat->case_list; iter; iter = iter->next) {
1754 if(!iter->expr) {
1755 have_default = TRUE;
1756 continue;
1757 }
1758
1759 set_compiler_loc(ctx, iter->loc);
1760 hres = compile_expression(ctx, iter->expr, TRUE);
1761 if(FAILED(hres))
1762 break;
1763
1764 case_jmps[i] = push_instr(ctx, OP_case);
1765 if(!case_jmps[i]) {
1767 break;
1768 }
1769 i++;
1770 }
1771
1772 if(SUCCEEDED(hres)) {
1773 hres = push_instr_uint(ctx, OP_pop, 1);
1774 if(SUCCEEDED(hres)) {
1775 default_jmp = push_instr(ctx, OP_jmp);
1776 if(!default_jmp)
1778 }
1779 }
1780
1781 if(FAILED(hres)) {
1782 free(case_jmps);
1783 return hres;
1784 }
1785
1786 i = 0;
1787 for(iter = stat->case_list; iter; iter = iter->next) {
1788 while(iter->next && iter->next->stat == iter->stat) {
1789 set_arg_uint(ctx, iter->expr ? case_jmps[i++] : default_jmp, ctx->code_off);
1790 iter = iter->next;
1791 }
1792
1793 set_arg_uint(ctx, iter->expr ? case_jmps[i++] : default_jmp, ctx->code_off);
1794
1795 for(stat_iter = iter->stat; stat_iter && (!iter->next || iter->next->stat != stat_iter);
1796 stat_iter = stat_iter->next) {
1797 hres = compile_statement(ctx, &stat_ctx, stat_iter);
1798 if(FAILED(hres))
1799 break;
1800 }
1801 if(FAILED(hres))
1802 break;
1803 }
1804
1805 free(case_jmps);
1806 if(FAILED(hres))
1807 return hres;
1808 assert(i == case_cnt);
1809
1810 if(!have_default) {
1811 hres = push_instr_uint(ctx, OP_jmp, stat_ctx.break_label);
1812 if(FAILED(hres))
1813 return hres;
1814 set_arg_uint(ctx, default_jmp, ctx->code_off);
1815 }
1816
1817 label_set_addr(ctx, stat_ctx.break_label);
1818 return S_OK;
1819}
struct _case_clausule_t * next
Definition: parser.h:205
statement_t * stat
Definition: parser.h:203
expression_t * expr
Definition: parser.h:201
unsigned loc
Definition: parser.h:202

Referenced by compile_statement().

◆ compile_throw_statement()

static HRESULT compile_throw_statement ( compiler_ctx_t ctx,
expression_statement_t stat 
)
static

Definition at line 1822 of file compile.c.

1823{
1824 HRESULT hres;
1825
1826 hres = compile_expression(ctx, stat->expr, TRUE);
1827 if(FAILED(hres))
1828 return hres;
1829
1830 return push_instr(ctx, OP_throw) ? S_OK : E_OUTOFMEMORY;
1831}

Referenced by compile_statement().

◆ compile_try_statement()

static HRESULT compile_try_statement ( compiler_ctx_t ctx,
try_statement_t stat 
)
static

Definition at line 1834 of file compile.c.

1835{
1836 statement_ctx_t try_ctx = {0, FALSE, TRUE}, finally_ctx = {2, FALSE, FALSE};
1837 unsigned push_except, finally_off = 0, catch_off = 0, pop_except, catch_pop_except = 0;
1838 BSTR ident;
1839 HRESULT hres;
1840
1841 push_except = push_instr(ctx, OP_push_except);
1842 if(!push_except)
1843 return E_OUTOFMEMORY;
1844
1845 if(stat->catch_block) {
1846 ident = compiler_alloc_bstr(ctx, stat->catch_block->identifier);
1847 if(!ident)
1848 return E_OUTOFMEMORY;
1849 }else {
1850 ident = NULL;
1851 }
1852
1853 hres = compile_statement(ctx, &try_ctx, stat->try_statement);
1854 if(FAILED(hres))
1855 return hres;
1856
1857 pop_except = push_instr(ctx, OP_pop_except);
1858 if(!pop_except)
1859 return E_OUTOFMEMORY;
1860
1861 if(stat->catch_block) {
1862 statement_ctx_t catch_ctx = {0, TRUE, stat->finally_statement != NULL};
1863
1864 if(stat->finally_statement)
1865 catch_ctx.using_except = TRUE;
1866
1867 catch_off = ctx->code_off;
1868
1869 hres = push_instr_bstr(ctx, OP_enter_catch, ident);
1870 if(FAILED(hres))
1871 return hres;
1872
1873 hres = compile_statement(ctx, &catch_ctx, stat->catch_block->statement);
1874 if(FAILED(hres))
1875 return hres;
1876
1877 if(!push_instr(ctx, OP_pop_scope))
1878 return E_OUTOFMEMORY;
1879
1880 if(stat->finally_statement) {
1881 catch_pop_except = push_instr(ctx, OP_pop_except);
1882 if(!catch_pop_except)
1883 return E_OUTOFMEMORY;
1884 }
1885 }
1886
1887 if(stat->finally_statement) {
1888 /*
1889 * finally block expects two elements on the stack, which may be:
1890 * - (true, return_addr) set by OP_pop_except, OP_end_finally jumps back to passed address
1891 * - (false, exception_value) set when unwinding an exception, which OP_end_finally rethrows
1892 */
1893 finally_off = ctx->code_off;
1894 hres = compile_statement(ctx, &finally_ctx, stat->finally_statement);
1895 if(FAILED(hres))
1896 return hres;
1897
1898 set_compiler_loc(ctx, stat->finally_loc);
1899 if(!push_instr(ctx, OP_end_finally))
1900 return E_OUTOFMEMORY;
1901 }
1902
1903 instr_ptr(ctx, pop_except)->u.arg[0].uint = ctx->code_off;
1904 if(catch_pop_except)
1905 instr_ptr(ctx, catch_pop_except)->u.arg[0].uint = ctx->code_off;
1906 instr_ptr(ctx, push_except)->u.arg[0].uint = catch_off;
1907 instr_ptr(ctx, push_except)->u.arg[1].uint = finally_off;
1908 return S_OK;
1909}
BOOL using_except
Definition: compile.c:35

Referenced by compile_statement().

◆ compile_typeof_expression()

static HRESULT compile_typeof_expression ( compiler_ctx_t ctx,
unary_expression_t expr 
)
static

Definition at line 898 of file compile.c.

899{
900 jsop_t op;
902
903 if(is_memberid_expr(expr->expression->type)) {
904 if(expr->expression->type == EXPR_IDENT)
905 return push_instr_bstr(ctx, OP_typeofident, ((identifier_expression_t*)expr->expression)->identifier);
906
907 op = OP_typeofid;
908 hres = compile_memberid_expression(ctx, expr->expression, 0);
909 }else {
910 op = OP_typeof;
911 hres = compile_expression(ctx, expr->expression, TRUE);
912 }
913 if(FAILED(hres))
914 return hres;
915
916 return push_instr(ctx, op) ? S_OK : E_OUTOFMEMORY;
917}

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 432 of file compile.c.

433{
435
436 hres = compile_expression(ctx, expr->expression, TRUE);
437 if(FAILED(hres))
438 return hres;
439
440 return push_instr(ctx, op) ? S_OK : E_OUTOFMEMORY;
441}

Referenced by compile_expression().

◆ compile_var_statement()

static HRESULT compile_var_statement ( compiler_ctx_t ctx,
var_statement_t stat 
)
static

Definition at line 1276 of file compile.c.

1277{
1278 return compile_variable_list(ctx, stat->variable_list);
1279}

Referenced by compile_statement().

◆ compile_variable_list()

static HRESULT compile_variable_list ( compiler_ctx_t ctx,
variable_declaration_t list 
)
static

Definition at line 1242 of file compile.c.

1243{
1245 HRESULT hres;
1246
1247 assert(list != NULL);
1248
1249 for(iter = list; iter; iter = iter->next) {
1250 if(!iter->expr)
1251 continue;
1252
1253 if (iter->constant)
1254 FIXME("Constant variables are not supported.\n");
1255
1257 if(FAILED(hres))
1258 return hres;
1259
1260 hres = compile_expression(ctx, iter->expr, TRUE);
1261 if(FAILED(hres))
1262 return hres;
1263
1264 if(!push_instr(ctx, OP_assign))
1265 return E_OUTOFMEMORY;
1266
1267 hres = push_instr_uint(ctx, OP_pop, 1);
1268 if(FAILED(hres))
1269 return hres;
1270 }
1271
1272 return S_OK;
1273}
#define FIXME(fmt,...)
Definition: precomp.h:53
Definition: list.h:37
const WCHAR * identifier
Definition: parser.h:100
expression_t * expr
Definition: parser.h:102
struct _variable_declaration_t * next
Definition: parser.h:104

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 1333 of file compile.c.

1334{
1335 statement_ctx_t stat_ctx = {0, FALSE, FALSE};
1336 unsigned jmp_off;
1337 HRESULT hres;
1338
1339 stat_ctx.break_label = alloc_label(ctx);
1340 if(!stat_ctx.break_label)
1341 return E_OUTOFMEMORY;
1342
1343 stat_ctx.continue_label = alloc_label(ctx);
1344 if(!stat_ctx.continue_label)
1345 return E_OUTOFMEMORY;
1346
1347 jmp_off = ctx->code_off;
1348
1349 if(!stat->do_while) {
1351 hres = compile_expression(ctx, stat->expr, TRUE);
1352 if(FAILED(hres))
1353 return hres;
1354
1355 hres = push_instr_uint(ctx, OP_jmp_z, stat_ctx.break_label);
1356 if(FAILED(hres))
1357 return hres;
1358 }
1359
1360 hres = compile_statement(ctx, &stat_ctx, stat->statement);
1361 if(FAILED(hres))
1362 return hres;
1363
1364 set_compiler_loc(ctx, stat->stat.loc);
1365 if(stat->do_while) {
1367 hres = compile_expression(ctx, stat->expr, TRUE);
1368 if(FAILED(hres))
1369 return hres;
1370
1371 hres = push_instr_uint(ctx, OP_jmp_z, stat_ctx.break_label);
1372 if(FAILED(hres))
1373 return hres;
1374 }
1375
1376 hres = push_instr_uint(ctx, OP_jmp, jmp_off);
1377 if(FAILED(hres))
1378 return hres;
1379
1380 label_set_addr(ctx, stat_ctx.break_label);
1381 return S_OK;
1382}

Referenced by compile_statement().

◆ compile_with_statement()

static HRESULT compile_with_statement ( compiler_ctx_t ctx,
with_statement_t stat 
)
static

Definition at line 1677 of file compile.c.

1678{
1679 statement_ctx_t stat_ctx = {0, TRUE, FALSE};
1680 HRESULT hres;
1681
1682 hres = compile_expression(ctx, stat->expr, TRUE);
1683 if(FAILED(hres))
1684 return hres;
1685
1686 if(!push_instr(ctx, OP_push_with_scope))
1687 return E_OUTOFMEMORY;
1688
1689 hres = compile_statement(ctx, &stat_ctx, stat->statement);
1690 if(FAILED(hres))
1691 return hres;
1692
1693 if(!push_instr(ctx, OP_pop_scope))
1694 return E_OUTOFMEMORY;
1695
1696 return S_OK;
1697}

Referenced by compile_statement().

◆ compiler_alloc()

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

◆ compiler_alloc_bstr()

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

Definition at line 243 of file compile.c.

244{
246 return NULL;
247
248 ctx->code->bstr_pool[ctx->code->bstr_cnt] = SysAllocString(str);
249 if(!ctx->code->bstr_pool[ctx->code->bstr_cnt])
250 return NULL;
251
252 return ctx->code->bstr_pool[ctx->code->bstr_cnt++];
253}
static BOOL ensure_bstr_slot(compiler_ctx_t *ctx)
Definition: compile.c:222
BSTR WINAPI SysAllocString(LPCOLESTR str)
Definition: oleaut.c:238
const WCHAR * str

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 255 of file compile.c.

256{
258 return NULL;
259
260 ctx->code->bstr_pool[ctx->code->bstr_cnt] = SysAllocStringLen(str, len);
261 if(!ctx->code->bstr_pool[ctx->code->bstr_cnt])
262 return NULL;
263
264 return ctx->code->bstr_pool[ctx->code->bstr_cnt++];
265}
GLenum GLsizei len
Definition: glext.h:6722
BSTR WINAPI SysAllocStringLen(const OLECHAR *str, unsigned int len)
Definition: oleaut.c:339

Referenced by parse_arguments().

◆ compiler_alloc_string()

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

Definition at line 217 of file compile.c.

218{
220}
#define lstrlenW
Definition: compat.h:750
jsstr_t * compiler_alloc_string_len(compiler_ctx_t *ctx, const WCHAR *str, unsigned len)
Definition: compile.c:189

Referenced by compile_class(), compile_delete_expression(), compile_func(), create_class_funcprop(), create_function(), emit_member_expression(), push_instr_str(), 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 189 of file compile.c.

190{
191 jsstr_t *new_str;
192
193 if(!ctx->code->str_pool_size) {
194 ctx->code->str_pool = malloc(8 * sizeof(jsstr_t*));
195 if(!ctx->code->str_pool)
196 return NULL;
197 ctx->code->str_pool_size = 8;
198 }else if(ctx->code->str_pool_size == ctx->code->str_cnt) {
199 jsstr_t **new_pool;
200
201 new_pool = realloc(ctx->code->str_pool, ctx->code->str_pool_size*2*sizeof(jsstr_t*));
202 if(!new_pool)
203 return NULL;
204
205 ctx->code->str_pool = new_pool;
206 ctx->code->str_pool_size *= 2;
207 }
208
209 new_str = jsstr_alloc_len(str, len);
210 if(!new_str)
211 return NULL;
212
213 ctx->code->str_pool[ctx->code->str_cnt++] = new_str;
214 return new_str;
215}
jsstr_t * jsstr_alloc_len(const WCHAR *buf, unsigned len)
Definition: jsstr.c:86

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

◆ dump_code()

static void dump_code ( compiler_ctx_t ctx,
unsigned  off 
)
static

Definition at line 122 of file compile.c.

123{
124 instr_t *instr;
125
126 for(instr = ctx->code->instrs+off; instr < ctx->code->instrs+ctx->code_off; instr++) {
127 TRACE_(jscript_disas)("%d:\t%s", (int)(instr-ctx->code->instrs), instr_info[instr->op].op_str);
128 if(instr_info[instr->op].arg1_type == ARG_DBL) {
129 TRACE_(jscript_disas)("\t%lf", instr->u.dbl);
130 }else {
131 dump_instr_arg(instr_info[instr->op].arg1_type, instr->u.arg);
132 dump_instr_arg(instr_info[instr->op].arg2_type, instr->u.arg+1);
133 }
134 TRACE_(jscript_disas)("\n");
135 }
136}
#define TRACE_(x)
Definition: compat.h:76
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
@ ARG_DBL
Definition: engine.h:125
static void dump_instr_arg(instr_arg_type_t type, instr_arg_t *arg)
Definition: compile.c:99
jsop_t op
Definition: engine.h:133
double dbl
Definition: engine.h:137

Referenced by compile_function(), and compile_script().

◆ dump_instr_arg()

static void dump_instr_arg ( instr_arg_type_t  type,
instr_arg_t arg 
)
static

Definition at line 99 of file compile.c.

100{
101 switch(type) {
102 case ARG_STR:
103 TRACE_(jscript_disas)("\t%s", debugstr_jsstr(arg->str));
104 break;
105 case ARG_BSTR:
106 TRACE_(jscript_disas)("\t%s", debugstr_wn(arg->bstr, SysStringLen(arg->bstr)));
107 break;
108 case ARG_INT:
109 TRACE_(jscript_disas)("\t%d", arg->uint);
110 break;
111 case ARG_UINT:
112 case ARG_ADDR:
113 TRACE_(jscript_disas)("\t%u", arg->uint);
114 break;
115 case ARG_FUNC:
116 case ARG_NONE:
117 break;
119 }
120}
#define ARG_NONE
Definition: amlcode.h:216
@ ARG_INT
Definition: engine.h:127
@ ARG_ADDR
Definition: engine.h:123
@ ARG_BSTR
Definition: engine.h:124
@ ARG_FUNC
Definition: engine.h:126
@ ARG_STR
Definition: engine.h:128
@ ARG_UINT
Definition: engine.h:129
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
const char * debugstr_jsstr(jsstr_t *str)
Definition: jsstr.c:37
#define debugstr_wn
Definition: kernel32.h:33
UINT WINAPI SysStringLen(BSTR str)
Definition: oleaut.c:196

Referenced by dump_code().

◆ emit_identifier()

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

Definition at line 524 of file compile.c.

525{
526 int local_ref;
527 if(bind_local(ctx, identifier, &local_ref))
528 return push_instr_int(ctx, OP_local, local_ref);
529 return push_instr_bstr(ctx, OP_ident, identifier);
530}
static BOOL bind_local(compiler_ctx_t *ctx, const WCHAR *identifier, int *ret_ref)
Definition: compile.c:489

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 516 of file compile.c.

517{
518 int local_ref;
519 if(bind_local(ctx, identifier, &local_ref))
520 return push_instr_int(ctx, OP_local_ref, local_ref);
521 return push_instr_bstr_uint(ctx, OP_identid, identifier, flags);
522}
static HRESULT push_instr_bstr_uint(compiler_ctx_t *ctx, jsop_t op, const WCHAR *arg1, unsigned arg2)
Definition: compile.c:352

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

◆ emit_member_expression()

static HRESULT emit_member_expression ( compiler_ctx_t ctx,
expression_t expr 
)
static

Definition at line 532 of file compile.c.

533{
535
536 if(expr->type == EXPR_ARRAY) {
538
539 hres = compile_expression(ctx, array_expr->expression1, TRUE);
540 if(FAILED(hres))
541 return hres;
542
543 hres = compile_expression(ctx, array_expr->expression2, TRUE);
544 if(FAILED(hres))
545 return hres;
546
547 if(!push_instr(ctx, OP_to_string))
548 return E_OUTOFMEMORY;
549 }else {
551 jsstr_t *jsstr;
552
554
555 hres = compile_expression(ctx, member_expr->expression, TRUE);
556 if(FAILED(hres))
557 return hres;
558
559 jsstr = compiler_alloc_string(ctx, member_expr->identifier);
560 if(!jsstr)
561 return E_OUTOFMEMORY;
562
563 hres = push_instr_str(ctx, OP_str, jsstr);
564 if(FAILED(hres))
565 return hres;
566 }
567
568 return S_OK;
569}

Referenced by compile_assign_expression(), and compile_memberid_expression().

◆ ensure_bstr_slot()

static BOOL ensure_bstr_slot ( compiler_ctx_t ctx)
static

Definition at line 222 of file compile.c.

223{
224 if(!ctx->code->bstr_pool_size) {
225 ctx->code->bstr_pool = malloc(8 * sizeof(BSTR));
226 if(!ctx->code->bstr_pool)
227 return FALSE;
228 ctx->code->bstr_pool_size = 8;
229 }else if(ctx->code->bstr_pool_size == ctx->code->bstr_cnt) {
230 BSTR *new_pool;
231
232 new_pool = realloc(ctx->code->bstr_pool, ctx->code->bstr_pool_size*2*sizeof(BSTR));
233 if(!new_pool)
234 return FALSE;
235
236 ctx->code->bstr_pool = new_pool;
237 ctx->code->bstr_pool_size *= 2;
238 }
239
240 return TRUE;
241}

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,
unsigned int  scope 
)
inlinestatic

Definition at line 1977 of file compile.c.

1978{
1979 struct wine_rb_entry *entry = wine_rb_get(&ctx->local_scopes[scope].locals, name);
1981}
#define wine_rb_entry
Definition: rbtree.h:404
#define WINE_RB_ENTRY_VALUE
Definition: rbtree.h:414
#define wine_rb_get
Definition: rbtree.h:409

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 141 of file compile.c.

Referenced by alloc_local_scope().

◆ get_location_line()

unsigned get_location_line ( bytecode_t code,
unsigned  loc,
unsigned char_pos 
)

Definition at line 2445 of file compile.c.

2446{
2447 unsigned line = code->start_line;
2448 const WCHAR *nl, *p;
2449
2450 for(nl = p = code->source; p < code->source + loc; p++) {
2451 if(*p != '\n') continue;
2452 line++;
2453 nl = p + 1;
2454 }
2455 *char_pos = loc - (nl - code->source);
2456 return line;
2457}
GLfloat GLfloat p
Definition: glext.h:8902
short WCHAR
Definition: pedump.c:58
Definition: parser.c:49

Referenced by JScriptError_GetSourcePosition(), and print_backtrace().

◆ init_code()

static HRESULT init_code ( compiler_ctx_t compiler,
const WCHAR source,
UINT64  source_context,
unsigned  start_line 
)
static

Definition at line 2481 of file compile.c.

2482{
2483 size_t len = source ? lstrlenW(source) : 0;
2484
2485 if(len > INT32_MAX)
2486 return E_OUTOFMEMORY;
2487
2488 compiler->code = calloc(1, sizeof(bytecode_t));
2489 if(!compiler->code)
2490 return E_OUTOFMEMORY;
2491
2492 compiler->code->ref = 1;
2493 compiler->code->source_context = source_context;
2494 compiler->code->start_line = start_line;
2495 heap_pool_init(&compiler->code->heap);
2496
2497 compiler->code->source = malloc((len + 1) * sizeof(WCHAR));
2498 if(!compiler->code->source) {
2499 release_bytecode(compiler->code);
2500 return E_OUTOFMEMORY;
2501 }
2502 if(len)
2503 memcpy(compiler->code->source, source, len * sizeof(WCHAR));
2504 compiler->code->source[len] = 0;
2505
2506 compiler->code->instrs = malloc(64 * sizeof(instr_t));
2507 if(!compiler->code->instrs) {
2508 release_bytecode(compiler->code);
2509 return E_OUTOFMEMORY;
2510 }
2511
2512 compiler->code_size = 64;
2513 compiler->code_off = 1;
2514 return S_OK;
2515}
#define INT32_MAX
Definition: stdint.h:80
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define calloc
Definition: rosglue.h:14
instr_t * instrs
Definition: engine.h:195
LONG ref
Definition: engine.h:192
heap_pool_t heap
Definition: engine.h:196
UINT64 source_context
Definition: engine.h:202
unsigned start_line
Definition: engine.h:203
unsigned code_size
Definition: compile.c:61
unsigned code_off
Definition: compile.c:60

Referenced by compile_script().

◆ instr_ptr()

◆ is_loop_statement()

static BOOL is_loop_statement ( statement_type_t  type)
inlinestatic

Definition at line 1205 of file compile.c.

1206{
1207 return type == STAT_FOR || type == STAT_FORIN || type == STAT_WHILE;
1208}

Referenced by compile_continue_statement().

◆ is_memberid_expr()

static BOOL is_memberid_expr ( expression_type_t  type)
inlinestatic

◆ label_set_addr()

◆ literal_as_string()

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

Definition at line 937 of file compile.c.

938{
939 switch(literal->type) {
940 case LT_STRING:
941 *str = literal->u.str;
942 break;
943 case LT_DOUBLE:
944 return double_to_string(literal->u.dval, str);
946 }
947
948 return *str ? S_OK : E_OUTOFMEMORY;
949}
HRESULT double_to_string(double, jsstr_t **)
Definition: jsutils.c:767

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 2655 of file compile.c.

2656{
2657 const WCHAR *ptr = args, *ptr2;
2658 unsigned arg_cnt = 0;
2659
2660 while(iswspace(*ptr))
2661 ptr++;
2662 if(!*ptr) {
2663 if(args_size)
2664 *args_size = 0;
2665 return S_OK;
2666 }
2667
2668 while(1) {
2669 if(!iswalpha(*ptr) && *ptr != '_') {
2670 FIXME("expected alpha or '_': %s\n", debugstr_w(ptr));
2671 return E_FAIL;
2672 }
2673
2674 ptr2 = ptr;
2675 while(iswalnum(*ptr) || *ptr == '_')
2676 ptr++;
2677
2678 if(*ptr && *ptr != ',' && !iswspace(*ptr)) {
2679 FIXME("unexpected har %s\n", debugstr_w(ptr));
2680 return E_FAIL;
2681 }
2682
2683 if(arg_array) {
2684 arg_array[arg_cnt] = compiler_alloc_bstr_len(ctx, ptr2, ptr-ptr2);
2685 if(!arg_array[arg_cnt])
2686 return E_OUTOFMEMORY;
2687 }
2688 arg_cnt++;
2689
2690 while(iswspace(*ptr))
2691 ptr++;
2692 if(!*ptr)
2693 break;
2694 if(*ptr != ',') {
2695 FIXME("expected ',': %s\n", debugstr_w(ptr));
2696 return E_FAIL;
2697 }
2698
2699 ptr++;
2700 while(iswspace(*ptr))
2701 ptr++;
2702 }
2703
2704 if(args_size)
2705 *args_size = arg_cnt;
2706 return S_OK;
2707}
static BSTR compiler_alloc_bstr_len(compiler_ctx_t *ctx, const WCHAR *str, size_t len)
Definition: compile.c:255
static PVOID ptr
Definition: dispmode.c:27
#define iswspace(_c)
Definition: ctype.h:669
#define iswalnum(_c)
Definition: ctype.h:671
#define iswalpha(_c)
Definition: ctype.h:664
#define args
Definition: format.c:66

Referenced by compile_arguments().

◆ pop_compiler_statement_ctx()

static void pop_compiler_statement_ctx ( compiler_ctx_t ctx,
statement_ctx_t stat_ctx 
)
static

Definition at line 580 of file compile.c.

581{
582 if (stat_ctx)
583 {
584 assert(ctx->stat_ctx == stat_ctx);
585 ctx->stat_ctx = stat_ctx->next;
586 }
587}

Referenced by compile_for_statement(), compile_statement(), and visit_statement().

◆ pop_to_stat()

static HRESULT pop_to_stat ( compiler_ctx_t ctx,
statement_ctx_t stat_ctx 
)
static

Definition at line 1529 of file compile.c.

1530{
1531 unsigned stack_pop = 0;
1532 statement_ctx_t *iter;
1533 HRESULT hres;
1534
1535 for(iter = ctx->stat_ctx; iter != stat_ctx; iter = iter->next) {
1536 if(iter->using_scope && !push_instr(ctx, OP_pop_scope))
1537 return E_OUTOFMEMORY;
1538 if(iter->using_except) {
1539 if(stack_pop) {
1540 hres = push_instr_uint(ctx, OP_pop, stack_pop);
1541 if(FAILED(hres))
1542 return hres;
1543 stack_pop = 0;
1544 }
1545 hres = push_instr_uint(ctx, OP_pop_except, ctx->code_off+1);
1546 if(FAILED(hres))
1547 return hres;
1548 }
1549 stack_pop += iter->stack_use;
1550 }
1551
1552 if(stack_pop) {
1553 hres = push_instr_uint(ctx, OP_pop, stack_pop);
1554 if(FAILED(hres))
1555 return hres;
1556 }
1557
1558 return S_OK;
1559}
static jsval_t stack_pop(script_ctx_t *ctx)
Definition: engine.c:108
unsigned stack_use
Definition: compile.c:33

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

◆ push_compiler_statement_ctx()

static void push_compiler_statement_ctx ( compiler_ctx_t ctx,
statement_ctx_t stat_ctx 
)
static

Definition at line 571 of file compile.c.

572{
573 if (stat_ctx)
574 {
575 stat_ctx->next = ctx->stat_ctx;
576 ctx->stat_ctx = stat_ctx;
577 }
578}

Referenced by compile_for_statement(), compile_statement(), and visit_statement().

◆ push_instr()

static unsigned push_instr ( compiler_ctx_t ctx,
jsop_t  op 
)
static

Definition at line 272 of file compile.c.

273{
274 assert(ctx->code_size >= ctx->code_off);
275
276 if(ctx->code_size == ctx->code_off) {
277 instr_t *new_instrs;
278
279 new_instrs = realloc(ctx->code->instrs, ctx->code_size*2*sizeof(instr_t));
280 if(!new_instrs)
281 return 0;
282
283 ctx->code->instrs = new_instrs;
284 ctx->code_size *= 2;
285 }
286
287 ctx->code->instrs[ctx->code_off].op = op;
288 ctx->code->instrs[ctx->code_off].loc = ctx->loc;
289 return ctx->code_off++;
290}

Referenced by compile_args(), compile_array_literal(), compile_assign_expression(), compile_binary_expression(), compile_block_statement(), compile_call_expression(), compile_conditional_expression(), compile_delete_expression(), compile_expression(), compile_expression_statement(), compile_for_statement(), compile_foreach_statement(), compile_forto_statement(), compile_func(), compile_if_statement(), compile_literal(), compile_logical_expression(), compile_new_expression(), compile_object_literal(), compile_return_statement(), compile_retval_statement(), compile_select_statement(), compile_statement(), compile_switch_statement(), compile_throw_statement(), compile_try_statement(), compile_typeof_expression(), compile_unary_expression(), compile_variable_list(), compile_while_statement(), compile_with_statement(), emit_catch_jmp(), emit_member_expression(), pop_to_stat(), push_instr_addr(), push_instr_bstr(), push_instr_bstr_uint(), push_instr_date(), push_instr_double(), push_instr_int(), push_instr_str(), push_instr_str_uint(), push_instr_uint(), push_instr_uint_bstr(), and push_instr_uint_str().

◆ push_instr_bstr()

static HRESULT push_instr_bstr ( compiler_ctx_t ctx,
jsop_t  op,
const WCHAR arg 
)
static

Definition at line 335 of file compile.c.

336{
337 unsigned instr;
338 WCHAR *str;
339
341 if(!str)
342 return E_OUTOFMEMORY;
343
344 instr = push_instr(ctx, op);
345 if(!instr)
346 return E_OUTOFMEMORY;
347
348 instr_ptr(ctx, instr)->u.arg->bstr = str;
349 return S_OK;
350}
BSTR bstr
Definition: engine.h:115

Referenced by compile_const_statement(), compile_delete_expression(), compile_member_expression(), compile_try_statement(), compile_typeof_expression(), and emit_identifier().

◆ push_instr_bstr_uint()

static HRESULT push_instr_bstr_uint ( compiler_ctx_t ctx,
jsop_t  op,
const WCHAR arg1,
unsigned  arg2 
)
static

Definition at line 352 of file compile.c.

353{
354 unsigned instr;
355 WCHAR *str;
356
358 if(!str)
359 return E_OUTOFMEMORY;
360
361 instr = push_instr(ctx, op);
362 if(!instr)
363 return E_OUTOFMEMORY;
364
365 instr_ptr(ctx, instr)->u.arg[0].bstr = str;
366 instr_ptr(ctx, instr)->u.arg[1].uint = arg2;
367 return S_OK;
368}
GLuint GLuint GLuint GLuint arg1
Definition: glext.h:9513
GLuint GLuint GLuint GLuint GLuint GLuint GLuint arg2
Definition: glext.h:9514

Referenced by compile_assignment(), compile_dim_statement(), compile_member_call_expression(), compile_redim_statement(), and emit_identifier_ref().

◆ push_instr_double()

static HRESULT push_instr_double ( compiler_ctx_t ctx,
jsop_t  op,
double  arg 
)
static

Definition at line 388 of file compile.c.

389{
390 unsigned instr;
391
392 instr = push_instr(ctx, op);
393 if(!instr)
394 return E_OUTOFMEMORY;
395
396 instr_ptr(ctx, instr)->u.dbl = arg;
397 return S_OK;
398}

Referenced by compile_expression(), and compile_literal().

◆ push_instr_int()

static HRESULT push_instr_int ( compiler_ctx_t ctx,
jsop_t  op,
LONG  arg 
)
static

Definition at line 298 of file compile.c.

299{
300 unsigned instr;
301
302 instr = push_instr(ctx, op);
303 if(!instr)
304 return E_OUTOFMEMORY;
305
306 instr_ptr(ctx, instr)->u.arg->lng = arg;
307 return S_OK;
308}

Referenced by compile_expression(), compile_forin_statement(), compile_forto_statement(), compile_increment_expression(), compile_literal(), compile_onerror_statement(), emit_identifier(), and emit_identifier_ref().

◆ push_instr_str()

static HRESULT push_instr_str ( compiler_ctx_t ctx,
jsop_t  op,
jsstr_t str 
)
static

Definition at line 310 of file compile.c.

311{
312 unsigned instr;
313
314 instr = push_instr(ctx, op);
315 if(!instr)
316 return E_OUTOFMEMORY;
317
318 instr_ptr(ctx, instr)->u.arg->str = str;
319 return S_OK;
320}
jsstr_t * str
Definition: engine.h:117

Referenced by compile_delete_expression(), compile_expression(), compile_literal(), and emit_member_expression().

◆ push_instr_str_uint()

static HRESULT push_instr_str_uint ( compiler_ctx_t ctx,
jsop_t  op,
jsstr_t str,
unsigned  arg2 
)
static

Definition at line 322 of file compile.c.

323{
324 unsigned instr;
325
326 instr = push_instr(ctx, op);
327 if(!instr)
328 return E_OUTOFMEMORY;
329
330 instr_ptr(ctx, instr)->u.arg[0].str = str;
331 instr_ptr(ctx, instr)->u.arg[1].uint = arg2;
332 return S_OK;
333}

Referenced by compile_literal(), and compile_object_literal().

◆ push_instr_uint()

◆ push_instr_uint_str()

static HRESULT push_instr_uint_str ( compiler_ctx_t ctx,
jsop_t  op,
unsigned  arg1,
const WCHAR arg2 
)
static

Definition at line 370 of file compile.c.

371{
372 unsigned instr;
373 jsstr_t *str;
374
376 if(!str)
377 return E_OUTOFMEMORY;
378
379 instr = push_instr(ctx, op);
380 if(!instr)
381 return E_OUTOFMEMORY;
382
383 instr_ptr(ctx, instr)->u.arg[0].uint = arg1;
384 instr_ptr(ctx, instr)->u.arg[1].str = str;
385 return S_OK;
386}

Referenced by compile_delete_expression().

◆ release_bytecode()

void release_bytecode ( bytecode_t code)

Definition at line 2459 of file compile.c.

2460{
2461 unsigned i;
2462
2463 if(--code->ref)
2464 return;
2465
2466 for(i=0; i < code->bstr_cnt; i++)
2467 SysFreeString(code->bstr_pool[i]);
2468 for(i=0; i < code->str_cnt; i++)
2469 jsstr_release(code->str_pool[i]);
2470
2471 if(code->named_item)
2472 release_named_item(code->named_item);
2473 free(code->source);
2474 heap_pool_free(&code->heap);
2475 free(code->bstr_pool);
2476 free(code->str_pool);
2477 free(code->instrs);
2478 free(code);
2479}
void release_named_item(named_item_t *item)
Definition: jscript.c:186
static void jsstr_release(jsstr_t *str)
Definition: jsstr.h:107
void WINAPI DECLSPEC_HOTPATCH SysFreeString(BSTR str)
Definition: oleaut.c:271

Referenced by builtin_eval(), clear_persistent_code_list(), clear_script_queue(), compile_script(), construct_function(), exec_source(), init_code(), InterpretedFunction_destructor(), JScriptParse_ParseScriptText(), JScriptParseProcedure_ParseProcedureText(), pop_call_frame(), reset_ei(), scope_destructor(), and ScriptTypeInfo_Release().

◆ remove_local_scope()

static void remove_local_scope ( compiler_ctx_t ctx,
unsigned int  scope_index 
)
static

Definition at line 170 of file compile.c.

171{
172 unsigned int i;
173
174 assert(scope_index < ctx->local_scope_count);
175 --ctx->local_scope_count;
176 assert(scope_index == *ctx->local_scopes[scope_index].ref_index);
177 *ctx->local_scopes[scope_index].ref_index = 0;
178 memmove(&ctx->local_scopes[scope_index], &ctx->local_scopes[scope_index + 1],
179 sizeof(*ctx->local_scopes) * (ctx->local_scope_count - scope_index));
180 for (i = scope_index; i < ctx->local_scope_count; ++i)
181 --*ctx->local_scopes[i].ref_index;
182}
#define memmove(s1, s2, n)
Definition: mkisofs.h:881

Referenced by visit_block_statement().

◆ resolve_labels()

static void resolve_labels ( compiler_ctx_t ctx,
unsigned  off 
)
static

Definition at line 2430 of file compile.c.

2431{
2432 instr_t *instr;
2433
2434 for(instr = ctx->code->instrs+off; instr < ctx->code->instrs+ctx->code_off; instr++) {
2435 if(instr_info[instr->op].arg1_type == ARG_ADDR && (instr->u.arg->uint & LABEL_FLAG)) {
2436 assert((instr->u.arg->uint & ~LABEL_FLAG) < ctx->labels_cnt);
2437 instr->u.arg->uint = ctx->labels[instr->u.arg->uint & ~LABEL_FLAG];
2438 }
2439 assert(instr_info[instr->op].arg2_type != ARG_ADDR);
2440 }
2441
2442 ctx->labels_cnt = 0;
2443}

Referenced by compile_func(), and compile_function().

◆ set_arg_uint()

static void set_arg_uint ( compiler_ctx_t ctx,
unsigned  instr,
unsigned  arg 
)
inlinestatic

◆ set_compiler_loc()

void set_compiler_loc ( compiler_ctx_t ctx,
unsigned  loc 
)

◆ visit_block_statement()

static HRESULT visit_block_statement ( compiler_ctx_t ctx,
block_statement_t block,
statement_t iter 
)
static

Definition at line 2195 of file compile.c.

2196{
2197 statement_ctx_t stat_ctx = {0, TRUE};
2198 BOOL needs_scope;
2199 HRESULT hres;
2200
2201 needs_scope = block && ctx->parser->script->version >= SCRIPTLANGUAGEVERSION_ES5;
2202 if (needs_scope)
2203 {
2204 if (!alloc_local_scope(ctx, &block->scope_index))
2205 return E_OUTOFMEMORY;
2206
2207 stat_ctx.scope_index = block->scope_index;
2208 stat_ctx.block_scope = TRUE;
2209 }
2210
2211 while(iter) {
2212 hres = visit_statement(ctx, needs_scope ? &stat_ctx : NULL, iter);
2213 if(FAILED(hres))
2214 return hres;
2215
2216 iter = iter->next;
2217 }
2218
2219 if (needs_scope && !(ctx->local_scopes[stat_ctx.scope_index].locals_cnt || stat_ctx.scope_has_functions))
2220 remove_local_scope(ctx, block->scope_index);
2221
2222 return S_OK;
2223}
static HRESULT visit_statement(compiler_ctx_t *, statement_ctx_t *, statement_t *)
Definition: compile.c:2225
static void remove_local_scope(compiler_ctx_t *ctx, unsigned int scope_index)
Definition: compile.c:170
BOOL scope_has_functions
Definition: compile.c:44

Referenced by compile_function(), and visit_statement().

◆ visit_expression()

static HRESULT visit_expression ( compiler_ctx_t ctx,
expression_t expr 
)
static

Definition at line 2037 of file compile.c.

2038{
2039 HRESULT hres = S_OK;
2040
2041 switch(expr->type) {
2042 case EXPR_ADD:
2043 case EXPR_AND:
2044 case EXPR_ARRAY:
2045 case EXPR_ASSIGN:
2046 case EXPR_ASSIGNADD:
2047 case EXPR_ASSIGNAND:
2048 case EXPR_ASSIGNSUB:
2049 case EXPR_ASSIGNMUL:
2050 case EXPR_ASSIGNDIV:
2051 case EXPR_ASSIGNMOD:
2052 case EXPR_ASSIGNOR:
2053 case EXPR_ASSIGNLSHIFT:
2054 case EXPR_ASSIGNRSHIFT:
2055 case EXPR_ASSIGNRRSHIFT:
2056 case EXPR_ASSIGNXOR:
2057 case EXPR_BAND:
2058 case EXPR_BOR:
2059 case EXPR_COMMA:
2060 case EXPR_DIV:
2061 case EXPR_EQ:
2062 case EXPR_EQEQ:
2063 case EXPR_GREATER:
2064 case EXPR_GREATEREQ:
2065 case EXPR_IN:
2066 case EXPR_INSTANCEOF:
2067 case EXPR_LESS:
2068 case EXPR_LESSEQ:
2069 case EXPR_LSHIFT:
2070 case EXPR_MOD:
2071 case EXPR_MUL:
2072 case EXPR_NOTEQ:
2073 case EXPR_NOTEQEQ:
2074 case EXPR_OR:
2075 case EXPR_RSHIFT:
2076 case EXPR_RRSHIFT:
2077 case EXPR_SUB:
2078 case EXPR_BXOR: {
2080
2081 hres = visit_expression(ctx, binary_expr->expression1);
2082 if(FAILED(hres))
2083 return hres;
2084
2085 hres = visit_expression(ctx, binary_expr->expression2);
2086 break;
2087 }
2088 case EXPR_BITNEG:
2089 case EXPR_DELETE:
2090 case EXPR_LOGNEG:
2091 case EXPR_MINUS:
2092 case EXPR_PLUS:
2093 case EXPR_POSTDEC:
2094 case EXPR_POSTINC:
2095 case EXPR_PREDEC:
2096 case EXPR_PREINC:
2097 case EXPR_TYPEOF:
2098 case EXPR_VOID:
2099 hres = visit_expression(ctx, ((unary_expression_t*)expr)->expression);
2100 break;
2101 case EXPR_IDENT:
2102 case EXPR_LITERAL:
2103 case EXPR_THIS:
2104 break;
2105 case EXPR_ARRAYLIT: {
2107 array_element_t *iter;
2108
2109 for(iter = array_expr->element_list; iter; iter = iter->next) {
2110 hres = visit_expression(ctx, iter->expr);
2111 if(FAILED(hres))
2112 return hres;
2113 }
2114 break;
2115 }
2116 case EXPR_CALL:
2117 case EXPR_NEW: {
2119 argument_t *arg;
2120
2121 hres = visit_expression(ctx, call_expr->expression);
2122 if(FAILED(hres))
2123 return hres;
2124
2125 for(arg = call_expr->argument_list; arg; arg = arg->next) {
2126 hres = visit_expression(ctx, arg->expr);
2127 if(FAILED(hres))
2128 return hres;
2129 }
2130 break;
2131 }
2132 case EXPR_COND: {
2134
2135 hres = visit_expression(ctx, cond_expr->expression);
2136 if(FAILED(hres))
2137 return hres;
2138
2140 if(FAILED(hres))
2141 return hres;
2142
2144 break;
2145 }
2146 case EXPR_FUNC:
2148 break;
2149 case EXPR_MEMBER:
2150 hres = visit_expression(ctx, ((member_expression_t*)expr)->expression);
2151 break;
2152 case EXPR_PROPVAL: {
2154 for(iter = ((property_value_expression_t*)expr)->property_list; iter; iter = iter->next) {
2155 hres = visit_expression(ctx, iter->value);
2156 if(FAILED(hres))
2157 return hres;
2158 }
2159 break;
2160 }
2162 }
2163
2164 return hres;
2165}
static HRESULT visit_function_expression(compiler_ctx_t *ctx, function_expression_t *expr)
Definition: compile.c:2012
static HRESULT visit_expression(compiler_ctx_t *ctx, expression_t *expr)
Definition: compile.c:2037
array_element_t * element_list
Definition: parser.h:367
expression_t * true_expression
Definition: parser.h:326
expression_t * expression
Definition: parser.h:325
expression_t * false_expression
Definition: parser.h:327

Referenced by visit_expression(), visit_statement(), and visit_variable_list().

◆ visit_function_expression()

static HRESULT visit_function_expression ( compiler_ctx_t ctx,
function_expression_t expr 
)
static

Definition at line 2012 of file compile.c.

2013{
2014 statement_ctx_t *stat_ctx;
2015
2016 expr->func_id = ctx->func->func_cnt++;
2017 ctx->func_tail = ctx->func_tail ? (ctx->func_tail->next = expr) : (ctx->func_head = expr);
2018
2019 if(!expr->identifier || expr->event_target)
2020 return S_OK;
2021
2022 for (stat_ctx = ctx->stat_ctx; stat_ctx; stat_ctx = stat_ctx->next)
2023 {
2024 if (stat_ctx->block_scope)
2025 {
2026 stat_ctx->scope_has_functions = TRUE;
2027 break;
2028 }
2029 }
2030
2031 if(!expr->is_statement && ctx->parser->script->version >= SCRIPTLANGUAGEVERSION_ES5)
2032 return S_OK;
2033
2034 return alloc_variable(ctx, expr->identifier, stat_ctx ? stat_ctx->scope_index : 0) ? S_OK : E_OUTOFMEMORY;
2035}
static BOOL alloc_variable(compiler_ctx_t *ctx, const WCHAR *name, unsigned int scope)
Definition: compile.c:1998

Referenced by visit_expression().

◆ visit_statement()

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

Definition at line 2225 of file compile.c.

2226{
2227 HRESULT hres = S_OK;
2228
2230
2231 switch(stat->type) {
2232 case STAT_BLOCK:
2234 break;
2235 case STAT_BREAK:
2236 case STAT_CONTINUE:
2237 case STAT_EMPTY:
2238 break;
2239 case STAT_EXPR: {
2241 if(expr_stat->expr) {
2242 if(expr_stat->expr->type == EXPR_FUNC)
2243 ((function_expression_t*)expr_stat->expr)->is_statement = TRUE;
2244 hres = visit_expression(ctx, expr_stat->expr);
2245 }
2246 break;
2247 }
2248 case STAT_RETURN:
2249 case STAT_THROW: {
2251 if(expr_stat->expr)
2252 hres = visit_expression(ctx, expr_stat->expr);
2253 break;
2254 }
2255 case STAT_FOR: {
2256 statement_ctx_t stat_ctx_data = {0, TRUE}, *stat_ctx = NULL;
2257 for_statement_t *for_stat = (for_statement_t*)stat;
2258
2259 if(for_stat->variable_list)
2260 {
2262
2263 for(var = for_stat->variable_list; var; var = var->next)
2264 {
2265 if (var->block_scope)
2266 {
2267 stat_ctx = &stat_ctx_data;
2268 break;
2269 }
2270 }
2271
2272 if (stat_ctx)
2273 {
2274 if (!alloc_local_scope(ctx, &for_stat->scope_index))
2275 {
2277 break;
2278 }
2279 stat_ctx->scope_index = for_stat->scope_index;
2280 stat_ctx->block_scope = TRUE;
2282 }
2284 }
2285 else if(for_stat->begin_expr)
2286 hres = visit_expression(ctx, for_stat->begin_expr);
2287 if(FAILED(hres))
2288 {
2290 break;
2291 }
2292
2293 if(for_stat->expr) {
2294 hres = visit_expression(ctx, for_stat->expr);
2295 if(FAILED(hres))
2296 {
2298 break;
2299 }
2300 }
2301
2302 hres = visit_statement(ctx, NULL, for_stat->statement);
2303 if(FAILED(hres))
2304 {
2306 break;
2307 }
2308 if(for_stat->end_expr)
2309 hres = visit_expression(ctx, for_stat->end_expr);
2311 break;
2312 }
2313 case STAT_FORIN: {
2315
2316 if(forin_stat->variable) {
2317 hres = visit_variable_list(ctx, forin_stat->variable);
2318 if(FAILED(hres))
2319 break;
2320 }
2321
2322 hres = visit_expression(ctx, forin_stat->in_expr);
2323 if(FAILED(hres))
2324 return hres;
2325
2326 if(forin_stat->expr) {
2327 hres = visit_expression(ctx, forin_stat->expr);
2328 if(FAILED(hres))
2329 return hres;
2330 }
2331
2332 hres = visit_statement(ctx, NULL, forin_stat->statement);
2333 break;
2334 }
2335 case STAT_IF: {
2336 if_statement_t *if_stat = (if_statement_t*)stat;
2337
2338 hres = visit_expression(ctx, if_stat->expr);
2339 if(FAILED(hres))
2340 return hres;
2341
2342 hres = visit_statement(ctx, NULL, if_stat->if_stat);
2343 if(FAILED(hres))
2344 return hres;
2345
2346 if(if_stat->else_stat)
2347 hres = visit_statement(ctx, NULL, if_stat->else_stat);
2348 break;
2349 }
2350 case STAT_LABEL:
2352 break;
2353 case STAT_SWITCH: {
2355 statement_t *stat_iter;
2356 case_clausule_t *iter;
2357
2358 hres = visit_expression(ctx, switch_stat->expr);
2359 if(FAILED(hres))
2360 return hres;
2361
2362 for(iter = switch_stat->case_list; iter; iter = iter->next) {
2363 if(!iter->expr)
2364 continue;
2365 hres = visit_expression(ctx, iter->expr);
2366 if(FAILED(hres))
2367 return hres;
2368 }
2369
2370 for(iter = switch_stat->case_list; iter; iter = iter->next) {
2371 while(iter->next && iter->next->stat == iter->stat)
2372 iter = iter->next;
2373 for(stat_iter = iter->stat; stat_iter && (!iter->next || iter->next->stat != stat_iter);
2374 stat_iter = stat_iter->next) {
2375 hres = visit_statement(ctx, NULL, stat_iter);
2376 if(FAILED(hres))
2377 return hres;
2378 }
2379 }
2380 break;
2381 }
2382 case STAT_TRY: {
2383 try_statement_t *try_stat = (try_statement_t*)stat;
2384
2385 hres = visit_statement(ctx, NULL, try_stat->try_statement);
2386 if(FAILED(hres))
2387 return hres;
2388
2389 if(try_stat->catch_block) {
2391 if(FAILED(hres))
2392 return hres;
2393 }
2394
2395 if(try_stat->finally_statement)
2397 break;
2398 }
2399 case STAT_VAR:
2400 hres = visit_variable_list(ctx, ((var_statement_t*)stat)->variable_list);
2401 break;
2402 case STAT_WHILE: {
2404
2405 hres = visit_expression(ctx, while_stat->expr);
2406 if(FAILED(hres))
2407 return hres;
2408
2409 hres = visit_statement(ctx, NULL, while_stat->statement);
2410 break;
2411 }
2412 case STAT_WITH: {
2413 with_statement_t *with_stat = (with_statement_t*)stat;
2414
2415 hres = visit_expression(ctx, with_stat->expr);
2416 if(FAILED(hres))
2417 return hres;
2418
2419 hres = visit_statement(ctx, NULL, with_stat->statement);
2420 break;
2421 }
2423 }
2424
2426
2427 return hres;
2428}
static HRESULT visit_variable_list(compiler_ctx_t *ctx, variable_declaration_t *list)
Definition: compile.c:2167
const char * var
Definition: shader.c:5666
statement_t * statement
Definition: parser.h:216
expression_t * expr
Definition: parser.h:146
expression_t * expr
Definition: parser.h:167
statement_t * statement
Definition: parser.h:171
expression_t * end_expr
Definition: parser.h:169
unsigned int scope_index
Definition: parser.h:172
expression_t * begin_expr
Definition: parser.h:166
variable_declaration_t * variable_list
Definition: parser.h:165
variable_declaration_t * variable
Definition: parser.h:177
statement_t * statement
Definition: parser.h:180
expression_t * in_expr
Definition: parser.h:179
expression_t * expr
Definition: parser.h:178
statement_t * if_stat
Definition: parser.h:152
expression_t * expr
Definition: parser.h:151
statement_t * else_stat
Definition: parser.h:153
expression_t * expr
Definition: parser.h:210
case_clausule_t * case_list
Definition: parser.h:211
catch_block_t * catch_block
Definition: parser.h:222
statement_t * try_statement
Definition: parser.h:221
statement_t * finally_statement
Definition: parser.h:223
expression_t * expr
Definition: parser.h:159
statement_t * statement
Definition: parser.h:160
statement_t * statement
Definition: parser.h:191
expression_t * expr
Definition: parser.h:190

Referenced by visit_block_statement(), and visit_statement().

◆ visit_variable_list()

static HRESULT visit_variable_list ( compiler_ctx_t ctx,
variable_declaration_t list 
)
static

Definition at line 2167 of file compile.c.

2168{
2170 statement_ctx_t *stat_ctx;
2171 HRESULT hres;
2172
2173 for(iter = list; iter; iter = iter->next) {
2174 for (stat_ctx = ctx->stat_ctx; stat_ctx; stat_ctx = stat_ctx->next)
2175 {
2176 if (stat_ctx->block_scope)
2177 break;
2178 }
2179
2180 if(!alloc_variable(ctx, iter->identifier, iter->block_scope && stat_ctx ? stat_ctx->scope_index : 0))
2181 return E_OUTOFMEMORY;
2182
2183 if(iter->expr) {
2184 hres = visit_expression(ctx, iter->expr);
2185 if(FAILED(hres))
2186 return hres;
2187 }
2188 }
2189
2190 return S_OK;
2191}

Referenced by visit_statement().

◆ WINE_DECLARE_DEBUG_CHANNEL()

WINE_DECLARE_DEBUG_CHANNEL ( jscript_disas  )

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( jscript  )

Variable Documentation

◆ arg1_type

instr_arg_type_t arg1_type

Definition at line 91 of file compile.c.

◆ arg2_type

instr_arg_type_t arg2_type

Definition at line 92 of file compile.c.

◆ 

const struct { ... } instr_info[]
Initial value:
= {
#define X(n,a,b,c)
}
#define OP_LIST
Definition: engine.h:21

◆ op_str

const char* op_str

Definition at line 90 of file compile.c.

Referenced by CShellDispatch::ShellExecute().