blob: 0bcabf614d2ba070ab71e2dc59c8ffc9d07bb0d0 [file] [log] [blame]
/*
* Copyright 2008 Jacek Caban for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
typedef struct _source_elements_t source_elements_t;
typedef struct _function_expression_t function_expression_t;
typedef struct _function_declaration_t {
function_expression_t *expr;
struct _function_declaration_t *next;
} function_declaration_t;
typedef struct _var_list_t {
const WCHAR *identifier;
struct _var_list_t *next;
} var_list_t;
typedef struct _func_stack {
function_declaration_t *func_head;
function_declaration_t *func_tail;
var_list_t *var_head;
var_list_t *var_tail;
struct _func_stack *next;
} func_stack_t;
typedef struct _parser_ctx_t {
LONG ref;
WCHAR *begin;
const WCHAR *end;
const WCHAR *ptr;
script_ctx_t *script;
source_elements_t *source;
BOOL nl;
BOOL is_html;
BOOL lexer_error;
HRESULT hres;
jsheap_t heap;
func_stack_t *func_stack;
struct _parser_ctx_t *next;
} parser_ctx_t;
HRESULT script_parse(script_ctx_t*,const WCHAR*,const WCHAR*,parser_ctx_t**);
void parser_release(parser_ctx_t*);
int parser_lex(void*,parser_ctx_t*);
static inline void parser_addref(parser_ctx_t *ctx)
{
ctx->ref++;
}
static inline void *parser_alloc(parser_ctx_t *ctx, DWORD size)
{
return jsheap_alloc(&ctx->heap, size);
}
static inline void *parser_alloc_tmp(parser_ctx_t *ctx, DWORD size)
{
return jsheap_alloc(&ctx->script->tmp_heap, size);
}
typedef struct _scope_chain_t {
LONG ref;
DispatchEx *obj;
struct _scope_chain_t *next;
} scope_chain_t;
HRESULT scope_push(scope_chain_t*,DispatchEx*,scope_chain_t**);
void scope_release(scope_chain_t*);
static inline void scope_addref(scope_chain_t *scope)
{
scope->ref++;
}
struct _exec_ctx_t {
LONG ref;
parser_ctx_t *parser;
scope_chain_t *scope_chain;
DispatchEx *var_disp;
IDispatch *this_obj;
};
static inline void exec_addref(exec_ctx_t *ctx)
{
ctx->ref++;
}
typedef enum {
EXECT_PROGRAM,
EXECT_FUNCTION,
EXECT_EVAL
} exec_type_t;
void exec_release(exec_ctx_t*);
HRESULT create_exec_ctx(script_ctx_t*,IDispatch*,DispatchEx*,scope_chain_t*,exec_ctx_t**);
HRESULT exec_source(exec_ctx_t*,parser_ctx_t*,source_elements_t*,exec_type_t,jsexcept_t*,VARIANT*);
typedef struct _statement_t statement_t;
typedef struct _expression_t expression_t;
typedef struct _parameter_t parameter_t;
HRESULT create_source_function(parser_ctx_t*,parameter_t*,source_elements_t*,scope_chain_t*,
const WCHAR*,DWORD,DispatchEx**);
typedef enum {
LT_INT,
LT_DOUBLE,
LT_STRING,
LT_BOOL,
LT_NULL,
LT_REGEXP
}literal_type_t;
typedef struct {
literal_type_t type;
union {
LONG lval;
double dval;
const WCHAR *wstr;
VARIANT_BOOL bval;
IDispatch *disp;
struct {
const WCHAR *str;
DWORD str_len;
DWORD flags;
} regexp;
} u;
} literal_t;
literal_t *parse_regexp(parser_ctx_t*);
typedef struct _variable_declaration_t {
const WCHAR *identifier;
expression_t *expr;
struct _variable_declaration_t *next;
} variable_declaration_t;
typedef struct {
enum{
RT_NORMAL,
RT_RETURN,
RT_BREAK,
RT_CONTINUE
} type;
jsexcept_t ei;
} return_type_t;
typedef HRESULT (*statement_eval_t)(exec_ctx_t*,statement_t*,return_type_t*,VARIANT*);
struct _statement_t {
statement_eval_t eval;
statement_t *next;
};
typedef struct {
statement_t stat;
statement_t *stat_list;
} block_statement_t;
typedef struct {
statement_t stat;
variable_declaration_t *variable_list;
} var_statement_t;
typedef struct {
statement_t stat;
expression_t *expr;
} expression_statement_t;
typedef struct {
statement_t stat;
expression_t *expr;
statement_t *if_stat;
statement_t *else_stat;
} if_statement_t;
typedef struct {
statement_t stat;
BOOL do_while;
expression_t *expr;
statement_t *statement;
} while_statement_t;
typedef struct {
statement_t stat;
variable_declaration_t *variable_list;
expression_t *begin_expr;
expression_t *expr;
expression_t *end_expr;
statement_t *statement;
} for_statement_t;
typedef struct {
statement_t stat;
variable_declaration_t *variable;
expression_t *expr;
expression_t *in_expr;
statement_t *statement;
} forin_statement_t;
typedef struct {
statement_t stat;
const WCHAR *identifier;
} branch_statement_t;
typedef struct {
statement_t stat;
expression_t *expr;
statement_t *statement;
} with_statement_t;
typedef struct {
statement_t stat;
const WCHAR *identifier;
statement_t *statement;
} labelled_statement_t;
typedef struct _case_clausule_t {
expression_t *expr;
statement_t *stat;
struct _case_clausule_t *next;
} case_clausule_t;
typedef struct {
statement_t stat;
expression_t *expr;
case_clausule_t *case_list;
} switch_statement_t;
typedef struct {
const WCHAR *identifier;
statement_t *statement;
} catch_block_t;
typedef struct {
statement_t stat;
statement_t *try_statement;
catch_block_t *catch_block;
statement_t *finally_statement;
} try_statement_t;
HRESULT block_statement_eval(exec_ctx_t*,statement_t*,return_type_t*,VARIANT*);
HRESULT var_statement_eval(exec_ctx_t*,statement_t*,return_type_t*,VARIANT*);
HRESULT empty_statement_eval(exec_ctx_t*,statement_t*,return_type_t*,VARIANT*);
HRESULT expression_statement_eval(exec_ctx_t*,statement_t*,return_type_t*,VARIANT*);
HRESULT if_statement_eval(exec_ctx_t*,statement_t*,return_type_t*,VARIANT*);
HRESULT while_statement_eval(exec_ctx_t*,statement_t*,return_type_t*,VARIANT*);
HRESULT for_statement_eval(exec_ctx_t*,statement_t*,return_type_t*,VARIANT*);
HRESULT forin_statement_eval(exec_ctx_t*,statement_t*,return_type_t*,VARIANT*);
HRESULT continue_statement_eval(exec_ctx_t*,statement_t*,return_type_t*,VARIANT*);
HRESULT break_statement_eval(exec_ctx_t*,statement_t*,return_type_t*,VARIANT*);
HRESULT return_statement_eval(exec_ctx_t*,statement_t*,return_type_t*,VARIANT*);
HRESULT with_statement_eval(exec_ctx_t*,statement_t*,return_type_t*,VARIANT*);
HRESULT labelled_statement_eval(exec_ctx_t*,statement_t*,return_type_t*,VARIANT*);
HRESULT switch_statement_eval(exec_ctx_t*,statement_t*,return_type_t*,VARIANT*);
HRESULT throw_statement_eval(exec_ctx_t*,statement_t*,return_type_t*,VARIANT*);
HRESULT try_statement_eval(exec_ctx_t*,statement_t*,return_type_t*,VARIANT*);
typedef struct {
enum {
EXPRVAL_VARIANT,
EXPRVAL_IDREF,
EXPRVAL_NAMEREF,
EXPRVAL_INVALID
} type;
union {
VARIANT var;
struct {
IDispatch *disp;
DISPID id;
} idref;
struct {
IDispatch *disp;
BSTR name;
} nameref;
BSTR identifier;
} u;
} exprval_t;
typedef HRESULT (*expression_eval_t)(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);
struct _expression_t {
expression_eval_t eval;
};
struct _parameter_t {
const WCHAR *identifier;
struct _parameter_t *next;
};
struct _source_elements_t {
statement_t *statement;
statement_t *statement_tail;
function_declaration_t *functions;
var_list_t *variables;
};
struct _function_expression_t {
expression_t expr;
const WCHAR *identifier;
parameter_t *parameter_list;
source_elements_t *source_elements;
const WCHAR *src_str;
DWORD src_len;
};
typedef struct {
expression_t expr;
expression_t *expression1;
expression_t *expression2;
} binary_expression_t;
typedef struct {
expression_t expr;
expression_t *expression;
} unary_expression_t;
typedef struct {
expression_t expr;
expression_t *expression;
expression_t *true_expression;
expression_t *false_expression;
} conditional_expression_t;
typedef struct {
expression_t expr;
expression_t *member_expr;
expression_t *expression;
} array_expression_t;
typedef struct {
expression_t expr;
expression_t *expression;
const WCHAR *identifier;
} member_expression_t;
typedef struct _argument_t {
expression_t *expr;
struct _argument_t *next;
} argument_t;
typedef struct {
expression_t expr;
expression_t *expression;
argument_t *argument_list;
} call_expression_t;
typedef struct {
expression_t expr;
const WCHAR *identifier;
} identifier_expression_t;
typedef struct {
expression_t expr;
literal_t *literal;
} literal_expression_t;
typedef struct _array_element_t {
int elision;
expression_t *expr;
struct _array_element_t *next;
} array_element_t;
typedef struct {
expression_t expr;
array_element_t *element_list;
int length;
} array_literal_expression_t;
typedef struct _prop_val_t {
literal_t *name;
expression_t *value;
struct _prop_val_t *next;
} prop_val_t;
typedef struct {
expression_t expr;
prop_val_t *property_list;
} property_value_expression_t;
typedef enum {
EXPR_COMMA,
EXPR_OR,
EXPR_AND,
EXPR_BOR,
EXPR_BXOR,
EXPR_BAND,
EXPR_INSTANCEOF,
EXPR_IN,
EXPR_ADD,
EXPR_SUB,
EXPR_MUL,
EXPR_DIV,
EXPR_MOD,
EXPR_DELETE,
EXPR_VOID,
EXPR_TYPEOF,
EXPR_MINUS,
EXPR_PLUS,
EXPR_POSTINC,
EXPR_POSTDEC,
EXPR_PREINC,
EXPR_PREDEC,
EXPR_EQ,
EXPR_EQEQ,
EXPR_NOTEQ,
EXPR_NOTEQEQ,
EXPR_LESS,
EXPR_LESSEQ,
EXPR_GREATER,
EXPR_GREATEREQ,
EXPR_BITNEG,
EXPR_LOGNEG,
EXPR_LSHIFT,
EXPR_RSHIFT,
EXPR_RRSHIFT,
EXPR_ASSIGN,
EXPR_ASSIGNLSHIFT,
EXPR_ASSIGNRSHIFT,
EXPR_ASSIGNRRSHIFT,
EXPR_ASSIGNADD,
EXPR_ASSIGNSUB,
EXPR_ASSIGNMUL,
EXPR_ASSIGNDIV,
EXPR_ASSIGNMOD,
EXPR_ASSIGNAND,
EXPR_ASSIGNOR,
EXPR_ASSIGNXOR
} expression_type_t;
HRESULT function_expression_eval(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);
HRESULT conditional_expression_eval(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);
HRESULT array_expression_eval(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);
HRESULT member_expression_eval(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);
HRESULT new_expression_eval(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);
HRESULT call_expression_eval(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);
HRESULT this_expression_eval(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);
HRESULT identifier_expression_eval(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);
HRESULT literal_expression_eval(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);
HRESULT array_literal_expression_eval(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);
HRESULT property_value_expression_eval(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);
HRESULT comma_expression_eval(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);
HRESULT logical_or_expression_eval(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);
HRESULT logical_and_expression_eval(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);
HRESULT binary_or_expression_eval(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);
HRESULT binary_xor_expression_eval(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);
HRESULT binary_and_expression_eval(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);
HRESULT instanceof_expression_eval(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);
HRESULT in_expression_eval(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);
HRESULT add_expression_eval(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);
HRESULT sub_expression_eval(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);
HRESULT mul_expression_eval(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);
HRESULT div_expression_eval(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);
HRESULT mod_expression_eval(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);
HRESULT delete_expression_eval(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);
HRESULT void_expression_eval(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);
HRESULT typeof_expression_eval(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);
HRESULT minus_expression_eval(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);
HRESULT plus_expression_eval(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);
HRESULT post_increment_expression_eval(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);
HRESULT post_decrement_expression_eval(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);
HRESULT pre_increment_expression_eval(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);
HRESULT pre_decrement_expression_eval(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);
HRESULT equal_expression_eval(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);
HRESULT equal2_expression_eval(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);
HRESULT not_equal_expression_eval(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);
HRESULT not_equal2_expression_eval(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);
HRESULT less_expression_eval(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);
HRESULT lesseq_expression_eval(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);
HRESULT greater_expression_eval(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);
HRESULT greatereq_expression_eval(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);
HRESULT binary_negation_expression_eval(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);
HRESULT logical_negation_expression_eval(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);
HRESULT left_shift_expression_eval(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);
HRESULT right_shift_expression_eval(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);
HRESULT right2_shift_expression_eval(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);
HRESULT assign_expression_eval(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);
HRESULT assign_lshift_expression_eval(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);
HRESULT assign_rshift_expression_eval(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);
HRESULT assign_rrshift_expression_eval(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);
HRESULT assign_add_expression_eval(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);
HRESULT assign_sub_expression_eval(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);
HRESULT assign_mul_expression_eval(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);
HRESULT assign_div_expression_eval(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);
HRESULT assign_mod_expression_eval(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);
HRESULT assign_and_expression_eval(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);
HRESULT assign_or_expression_eval(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);
HRESULT assign_xor_expression_eval(exec_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*);