jscript: Use bytecode for calls on identifier and member expressions.
This commit is contained in:
parent
18576b36e4
commit
3aa7cee00e
|
@ -154,6 +154,24 @@ static HRESULT push_instr_bstr(compiler_ctx_t *ctx, jsop_t op, const WCHAR *arg)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HRESULT push_instr_bstr_uint(compiler_ctx_t *ctx, jsop_t op, const WCHAR *arg1, unsigned arg2)
|
||||||
|
{
|
||||||
|
unsigned instr;
|
||||||
|
WCHAR *str;
|
||||||
|
|
||||||
|
str = compiler_alloc_bstr(ctx, arg1);
|
||||||
|
if(!str)
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
instr = push_instr(ctx, op);
|
||||||
|
if(instr == -1)
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
instr_ptr(ctx, instr)->arg1.bstr = str;
|
||||||
|
instr_ptr(ctx, instr)->arg2.uint = arg2;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
static HRESULT push_instr_double(compiler_ctx_t *ctx, jsop_t op, double arg)
|
static HRESULT push_instr_double(compiler_ctx_t *ctx, jsop_t op, double arg)
|
||||||
{
|
{
|
||||||
unsigned instr;
|
unsigned instr;
|
||||||
|
@ -222,6 +240,58 @@ static HRESULT compile_member_expression(compiler_ctx_t *ctx, member_expression_
|
||||||
return push_instr_bstr(ctx, OP_member, expr->identifier);
|
return push_instr_bstr(ctx, OP_member, expr->identifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline BOOL is_memberid_expr(expression_type_t type)
|
||||||
|
{
|
||||||
|
return type == EXPR_IDENT || type == EXPR_MEMBER || type == EXPR_ARRAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT compile_memberid_expression(compiler_ctx_t *ctx, expression_t *expr, unsigned flags)
|
||||||
|
{
|
||||||
|
HRESULT hres = S_OK;
|
||||||
|
|
||||||
|
switch(expr->type) {
|
||||||
|
case EXPR_IDENT: {
|
||||||
|
identifier_expression_t *ident_expr = (identifier_expression_t*)expr;
|
||||||
|
|
||||||
|
hres = push_instr_bstr_uint(ctx, OP_identid, ident_expr->identifier, flags);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case EXPR_ARRAY: {
|
||||||
|
array_expression_t *array_expr = (array_expression_t*)expr;
|
||||||
|
|
||||||
|
hres = compile_expression(ctx, array_expr->member_expr);
|
||||||
|
if(FAILED(hres))
|
||||||
|
return hres;
|
||||||
|
|
||||||
|
hres = compile_expression(ctx, array_expr->expression);
|
||||||
|
if(FAILED(hres))
|
||||||
|
return hres;
|
||||||
|
|
||||||
|
hres = push_instr_uint(ctx, OP_memberid, flags);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case EXPR_MEMBER: {
|
||||||
|
member_expression_t *member_expr = (member_expression_t*)expr;
|
||||||
|
|
||||||
|
hres = compile_expression(ctx, member_expr->expression);
|
||||||
|
if(FAILED(hres))
|
||||||
|
return hres;
|
||||||
|
|
||||||
|
/* FIXME: Potential optimization */
|
||||||
|
hres = push_instr_str(ctx, OP_str, member_expr->identifier);
|
||||||
|
if(FAILED(hres))
|
||||||
|
return hres;
|
||||||
|
|
||||||
|
hres = push_instr_uint(ctx, OP_memberid, flags);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return hres;
|
||||||
|
}
|
||||||
|
|
||||||
/* ECMA-262 3rd Edition 11.14 */
|
/* ECMA-262 3rd Edition 11.14 */
|
||||||
static HRESULT compile_comma_expression(compiler_ctx_t *ctx, binary_expression_t *expr)
|
static HRESULT compile_comma_expression(compiler_ctx_t *ctx, binary_expression_t *expr)
|
||||||
{
|
{
|
||||||
|
@ -325,6 +395,40 @@ static HRESULT compile_interp_fallback(compiler_ctx_t *ctx, expression_t *expr)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HRESULT compile_call_expression(compiler_ctx_t *ctx, call_expression_t *expr, BOOL *no_ret)
|
||||||
|
{
|
||||||
|
unsigned arg_cnt = 0;
|
||||||
|
argument_t *arg;
|
||||||
|
unsigned instr;
|
||||||
|
HRESULT hres;
|
||||||
|
|
||||||
|
if(!is_memberid_expr(expr->expression->type)) {
|
||||||
|
expr->expr.eval = call_expression_eval;
|
||||||
|
return compile_interp_fallback(ctx, &expr->expr);
|
||||||
|
}
|
||||||
|
|
||||||
|
hres = compile_memberid_expression(ctx, expr->expression, 0);
|
||||||
|
if(FAILED(hres))
|
||||||
|
return hres;
|
||||||
|
|
||||||
|
for(arg = expr->argument_list; arg; arg = arg->next) {
|
||||||
|
hres = compile_expression(ctx, arg->expr);
|
||||||
|
if(FAILED(hres))
|
||||||
|
return hres;
|
||||||
|
arg_cnt++;
|
||||||
|
}
|
||||||
|
|
||||||
|
instr = push_instr(ctx, OP_call_member);
|
||||||
|
if(instr == -1)
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
instr_ptr(ctx, instr)->arg1.uint = arg_cnt;
|
||||||
|
instr_ptr(ctx, instr)->arg2.lng = no_ret == NULL;
|
||||||
|
if(no_ret)
|
||||||
|
*no_ret = TRUE;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
static HRESULT compile_delete_expression(compiler_ctx_t *ctx, unary_expression_t *expr)
|
static HRESULT compile_delete_expression(compiler_ctx_t *ctx, unary_expression_t *expr)
|
||||||
{
|
{
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
@ -373,47 +477,7 @@ static HRESULT compile_assign_expression(compiler_ctx_t *ctx, binary_expression_
|
||||||
{
|
{
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
|
||||||
switch(expr->expression1->type) {
|
if(!is_memberid_expr(expr->expression1->type)) {
|
||||||
case EXPR_IDENT: {
|
|
||||||
identifier_expression_t *ident_expr = (identifier_expression_t*)expr->expression1;
|
|
||||||
|
|
||||||
hres = push_instr_bstr(ctx, OP_identid, ident_expr->identifier);
|
|
||||||
if(FAILED(hres))
|
|
||||||
return hres;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case EXPR_ARRAY: {
|
|
||||||
array_expression_t *array_expr = (array_expression_t*)expr->expression1;
|
|
||||||
|
|
||||||
hres = compile_expression(ctx, array_expr->member_expr);
|
|
||||||
if(FAILED(hres))
|
|
||||||
return hres;
|
|
||||||
|
|
||||||
hres = compile_expression(ctx, array_expr->expression);
|
|
||||||
if(FAILED(hres))
|
|
||||||
return hres;
|
|
||||||
|
|
||||||
if(push_instr(ctx, OP_memberid) == -1)
|
|
||||||
return E_OUTOFMEMORY;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case EXPR_MEMBER: {
|
|
||||||
member_expression_t *member_expr = (member_expression_t*)expr->expression1;
|
|
||||||
|
|
||||||
hres = compile_expression(ctx, member_expr->expression);
|
|
||||||
if(FAILED(hres))
|
|
||||||
return hres;
|
|
||||||
|
|
||||||
/* FIXME: Potential optimization */
|
|
||||||
hres = push_instr_str(ctx, OP_str, member_expr->identifier);
|
|
||||||
if(FAILED(hres))
|
|
||||||
return hres;
|
|
||||||
|
|
||||||
if(push_instr(ctx, OP_memberid) == -1)
|
|
||||||
return E_OUTOFMEMORY;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
hres = compile_expression(ctx, expr->expression1);
|
hres = compile_expression(ctx, expr->expression1);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
@ -428,6 +492,10 @@ static HRESULT compile_assign_expression(compiler_ctx_t *ctx, binary_expression_
|
||||||
return push_instr_uint(ctx, OP_throw, JS_E_ILLEGAL_ASSIGN);
|
return push_instr_uint(ctx, OP_throw, JS_E_ILLEGAL_ASSIGN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hres = compile_memberid_expression(ctx, expr->expression1, fdexNameEnsure);
|
||||||
|
if(FAILED(hres))
|
||||||
|
return hres;
|
||||||
|
|
||||||
if(op != OP_LAST && push_instr(ctx, OP_refval) == -1)
|
if(op != OP_LAST && push_instr(ctx, OP_refval) == -1)
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
@ -480,7 +548,7 @@ static HRESULT compile_literal(compiler_ctx_t *ctx, literal_t *literal)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT compile_expression(compiler_ctx_t *ctx, expression_t *expr)
|
static HRESULT compile_expression_noret(compiler_ctx_t *ctx, expression_t *expr, BOOL *no_ret)
|
||||||
{
|
{
|
||||||
switch(expr->type) {
|
switch(expr->type) {
|
||||||
case EXPR_ADD:
|
case EXPR_ADD:
|
||||||
|
@ -507,6 +575,8 @@ static HRESULT compile_expression(compiler_ctx_t *ctx, expression_t *expr)
|
||||||
return compile_unary_expression(ctx, (unary_expression_t*)expr, OP_bneg);
|
return compile_unary_expression(ctx, (unary_expression_t*)expr, OP_bneg);
|
||||||
case EXPR_BOR:
|
case EXPR_BOR:
|
||||||
return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_or);
|
return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_or);
|
||||||
|
case EXPR_CALL:
|
||||||
|
return compile_call_expression(ctx, (call_expression_t*)expr, no_ret);
|
||||||
case EXPR_COMMA:
|
case EXPR_COMMA:
|
||||||
return compile_comma_expression(ctx, (binary_expression_t*)expr);
|
return compile_comma_expression(ctx, (binary_expression_t*)expr);
|
||||||
case EXPR_COND:
|
case EXPR_COND:
|
||||||
|
@ -569,6 +639,11 @@ static HRESULT compile_expression(compiler_ctx_t *ctx, expression_t *expr)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HRESULT compile_expression(compiler_ctx_t *ctx, expression_t *expr)
|
||||||
|
{
|
||||||
|
return compile_expression_noret(ctx, expr, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
void release_bytecode(bytecode_t *code)
|
void release_bytecode(bytecode_t *code)
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
@ -587,8 +662,9 @@ void release_compiler(compiler_ctx_t *ctx)
|
||||||
heap_free(ctx);
|
heap_free(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT compile_subscript(parser_ctx_t *parser, expression_t *expr, unsigned *ret_off)
|
HRESULT compile_subscript(parser_ctx_t *parser, expression_t *expr, BOOL do_ret, unsigned *ret_off)
|
||||||
{
|
{
|
||||||
|
BOOL no_ret = FALSE;
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
|
||||||
if(!parser->code) {
|
if(!parser->code) {
|
||||||
|
@ -608,7 +684,7 @@ HRESULT compile_subscript(parser_ctx_t *parser, expression_t *expr, unsigned *re
|
||||||
}
|
}
|
||||||
|
|
||||||
*ret_off = parser->compiler->code_off;
|
*ret_off = parser->compiler->code_off;
|
||||||
hres = compile_expression(parser->compiler, expr);
|
hres = compile_expression_noret(parser->compiler, expr, do_ret ? NULL : &no_ret);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
|
|
|
@ -182,12 +182,12 @@ static inline IDispatch *stack_pop_objid(exec_ctx_t *ctx, DISPID *id)
|
||||||
return V_DISPATCH(stack_pop(ctx));
|
return V_DISPATCH(stack_pop(ctx));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline IDispatch *stack_top_objid(exec_ctx_t *ctx, DISPID *id)
|
static inline IDispatch *stack_topn_objid(exec_ctx_t *ctx, unsigned n, DISPID *id)
|
||||||
{
|
{
|
||||||
assert(V_VT(stack_top(ctx)) == VT_INT && V_VT(stack_topn(ctx, 1)) == VT_DISPATCH);
|
assert(V_VT(stack_topn(ctx, n)) == VT_INT && V_VT(stack_topn(ctx, n+1)) == VT_DISPATCH);
|
||||||
|
|
||||||
*id = V_INT(stack_top(ctx));
|
*id = V_INT(stack_topn(ctx, n));
|
||||||
return V_DISPATCH(stack_topn(ctx, 1));
|
return V_DISPATCH(stack_topn(ctx, n+1));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void exprval_release(exprval_t *val)
|
static void exprval_release(exprval_t *val)
|
||||||
|
@ -1638,13 +1638,14 @@ static HRESULT interp_member(exec_ctx_t *ctx)
|
||||||
/* ECMA-262 3rd Edition 11.2.1 */
|
/* ECMA-262 3rd Edition 11.2.1 */
|
||||||
static HRESULT interp_memberid(exec_ctx_t *ctx)
|
static HRESULT interp_memberid(exec_ctx_t *ctx)
|
||||||
{
|
{
|
||||||
|
const unsigned arg = ctx->parser->code->instrs[ctx->ip].arg1.lng;
|
||||||
VARIANT *objv, *namev;
|
VARIANT *objv, *namev;
|
||||||
IDispatch *obj;
|
IDispatch *obj;
|
||||||
BSTR name;
|
BSTR name;
|
||||||
DISPID id;
|
DISPID id;
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
|
||||||
TRACE("\n");
|
TRACE("%x\n", arg);
|
||||||
|
|
||||||
namev = stack_pop(ctx);
|
namev = stack_pop(ctx);
|
||||||
objv = stack_pop(ctx);
|
objv = stack_pop(ctx);
|
||||||
|
@ -1660,11 +1661,16 @@ static HRESULT interp_memberid(exec_ctx_t *ctx)
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
hres = disp_get_id(ctx->parser->script, obj, name, fdexNameEnsure, &id);
|
hres = disp_get_id(ctx->parser->script, obj, name, arg, &id);
|
||||||
SysFreeString(name);
|
SysFreeString(name);
|
||||||
if(FAILED(hres)) {
|
if(FAILED(hres)) {
|
||||||
IDispatch_Release(obj);
|
IDispatch_Release(obj);
|
||||||
return hres;
|
if(hres == DISP_E_UNKNOWNNAME && !(arg & fdexNameEnsure)) {
|
||||||
|
obj = NULL;
|
||||||
|
id = JS_E_INVALID_PROPERTY;
|
||||||
|
}else {
|
||||||
|
return hres;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return stack_push_objid(ctx, obj, id);
|
return stack_push_objid(ctx, obj, id);
|
||||||
|
@ -1680,7 +1686,7 @@ static HRESULT interp_refval(exec_ctx_t *ctx)
|
||||||
|
|
||||||
TRACE("\n");
|
TRACE("\n");
|
||||||
|
|
||||||
disp = stack_top_objid(ctx, &id);
|
disp = stack_topn_objid(ctx, 0, &id);
|
||||||
if(!disp)
|
if(!disp)
|
||||||
return throw_reference_error(ctx->parser->script, &ctx->ei, JS_E_ILLEGAL_ASSIGN, NULL);
|
return throw_reference_error(ctx->parser->script, &ctx->ei, JS_E_ILLEGAL_ASSIGN, NULL);
|
||||||
|
|
||||||
|
@ -1817,9 +1823,7 @@ HRESULT call_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags
|
||||||
hres = throw_type_error(ctx, ei, JS_E_INVALID_PROPERTY, NULL);
|
hres = throw_type_error(ctx, ei, JS_E_INVALID_PROPERTY, NULL);
|
||||||
break;
|
break;
|
||||||
case EXPRVAL_IDREF:
|
case EXPRVAL_IDREF:
|
||||||
hres = disp_call(ctx, exprval.u.idref.disp, exprval.u.idref.id,
|
assert(0);
|
||||||
DISPATCH_METHOD, &dp, flags & EXPR_NOVAL ? NULL : &var, ei, NULL/*FIXME*/);
|
|
||||||
break;
|
|
||||||
case EXPRVAL_INVALID:
|
case EXPRVAL_INVALID:
|
||||||
hres = throw_type_error(ctx, ei, JS_E_OBJECT_EXPECTED, NULL);
|
hres = throw_type_error(ctx, ei, JS_E_OBJECT_EXPECTED, NULL);
|
||||||
break;
|
break;
|
||||||
|
@ -1845,6 +1849,33 @@ HRESULT call_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ECMA-262 3rd Edition 11.2.3 */
|
||||||
|
static HRESULT interp_call_member(exec_ctx_t *ctx)
|
||||||
|
{
|
||||||
|
const unsigned argn = ctx->parser->code->instrs[ctx->ip].arg1.uint;
|
||||||
|
const int do_ret = ctx->parser->code->instrs[ctx->ip].arg2.lng;
|
||||||
|
IDispatch *obj;
|
||||||
|
DISPPARAMS dp;
|
||||||
|
VARIANT v;
|
||||||
|
DISPID id;
|
||||||
|
HRESULT hres;
|
||||||
|
|
||||||
|
TRACE("%d %d\n", argn, do_ret);
|
||||||
|
|
||||||
|
obj = stack_topn_objid(ctx, argn, &id);
|
||||||
|
if(!obj)
|
||||||
|
return throw_type_error(ctx->parser->script, &ctx->ei, id, NULL);
|
||||||
|
|
||||||
|
jsstack_to_dp(ctx, argn, &dp);
|
||||||
|
hres = disp_call(ctx->parser->script, obj, id, DISPATCH_METHOD, &dp, do_ret ? &v : NULL, &ctx->ei, NULL/*FIXME*/);
|
||||||
|
if(FAILED(hres))
|
||||||
|
return hres;
|
||||||
|
|
||||||
|
stack_popn(ctx, argn+2);
|
||||||
|
return do_ret ? stack_push(ctx, &v) : S_OK;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* ECMA-262 3rd Edition 11.1.1 */
|
/* ECMA-262 3rd Edition 11.1.1 */
|
||||||
static HRESULT interp_this(exec_ctx_t *ctx)
|
static HRESULT interp_this(exec_ctx_t *ctx)
|
||||||
{
|
{
|
||||||
|
@ -1903,19 +1934,20 @@ static HRESULT interp_ident(exec_ctx_t *ctx)
|
||||||
static HRESULT interp_identid(exec_ctx_t *ctx)
|
static HRESULT interp_identid(exec_ctx_t *ctx)
|
||||||
{
|
{
|
||||||
const BSTR arg = ctx->parser->code->instrs[ctx->ip].arg1.bstr;
|
const BSTR arg = ctx->parser->code->instrs[ctx->ip].arg1.bstr;
|
||||||
|
const unsigned flags = ctx->parser->code->instrs[ctx->ip].arg2.uint;
|
||||||
exprval_t exprval;
|
exprval_t exprval;
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
|
||||||
TRACE("%s\n", debugstr_w(arg));
|
TRACE("%s %x\n", debugstr_w(arg), flags);
|
||||||
|
|
||||||
hres = identifier_eval(ctx->parser->script, arg, EXPR_NEWREF, &ctx->ei, &exprval);
|
hres = identifier_eval(ctx->parser->script, arg, (flags&fdexNameEnsure) ? EXPR_NEWREF : 0, &ctx->ei, &exprval);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
if(exprval.type != EXPRVAL_IDREF) {
|
if(exprval.type != EXPRVAL_IDREF) {
|
||||||
WARN("invalid ref\n");
|
WARN("invalid ref\n");
|
||||||
exprval_release(&exprval);
|
exprval_release(&exprval);
|
||||||
return stack_push_objid(ctx, NULL, -1);
|
return stack_push_objid(ctx, NULL, JS_E_OBJECT_EXPECTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
return stack_push_objid(ctx, exprval.u.idref.disp, exprval.u.idref.id);
|
return stack_push_objid(ctx, exprval.u.idref.disp, exprval.u.idref.id);
|
||||||
|
@ -3437,10 +3469,13 @@ static HRESULT interp_expression_eval(script_ctx_t *ctx, expression_t *expr, DWO
|
||||||
return hres;
|
return hres;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(exec_ctx->top == prev_top+1);
|
assert(exec_ctx->top == prev_top+1 || ((flags&EXPR_NOVAL) && exec_ctx->top == prev_top));
|
||||||
|
|
||||||
ret->type = EXPRVAL_VARIANT;
|
ret->type = EXPRVAL_VARIANT;
|
||||||
ret->u.var = *stack_pop(exec_ctx);
|
if(exec_ctx->top == prev_top)
|
||||||
|
V_VT(&ret->u.var) = VT_EMPTY;
|
||||||
|
else
|
||||||
|
ret->u.var = *stack_pop(exec_ctx);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3450,7 +3485,7 @@ HRESULT compiled_expression_eval(script_ctx_t *ctx, expression_t *expr, DWORD fl
|
||||||
|
|
||||||
TRACE("\n");
|
TRACE("\n");
|
||||||
|
|
||||||
hres = compile_subscript(ctx->exec_ctx->parser, expr, &expr->instr_off);
|
hres = compile_subscript(ctx->exec_ctx->parser, expr, !(flags & EXPR_NOVAL), &expr->instr_off);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,7 @@ typedef struct _func_stack {
|
||||||
X(assign, 1, 0,0) \
|
X(assign, 1, 0,0) \
|
||||||
X(bool, 1, ARG_INT, 0) \
|
X(bool, 1, ARG_INT, 0) \
|
||||||
X(bneg, 1, 0,0) \
|
X(bneg, 1, 0,0) \
|
||||||
|
X(call_member,1, ARG_UINT, ARG_UINT) \
|
||||||
X(delete, 1, 0,0) \
|
X(delete, 1, 0,0) \
|
||||||
X(div, 1, 0,0) \
|
X(div, 1, 0,0) \
|
||||||
X(double, 1, ARG_SBL, 0) \
|
X(double, 1, ARG_SBL, 0) \
|
||||||
|
@ -54,7 +55,7 @@ typedef struct _func_stack {
|
||||||
X(gt, 1, 0,0) \
|
X(gt, 1, 0,0) \
|
||||||
X(gteq, 1, 0,0) \
|
X(gteq, 1, 0,0) \
|
||||||
X(ident, 1, ARG_BSTR, 0) \
|
X(ident, 1, ARG_BSTR, 0) \
|
||||||
X(identid, 1, ARG_BSTR, 0) \
|
X(identid, 1, ARG_BSTR, ARG_INT) \
|
||||||
X(in, 1, 0,0) \
|
X(in, 1, 0,0) \
|
||||||
X(int, 1, ARG_INT, 0) \
|
X(int, 1, ARG_INT, 0) \
|
||||||
X(jmp, 0, ARG_ADDR, 0) \
|
X(jmp, 0, ARG_ADDR, 0) \
|
||||||
|
@ -63,7 +64,7 @@ typedef struct _func_stack {
|
||||||
X(lt, 1, 0,0) \
|
X(lt, 1, 0,0) \
|
||||||
X(lteq, 1, 0,0) \
|
X(lteq, 1, 0,0) \
|
||||||
X(member, 1, ARG_BSTR, 0) \
|
X(member, 1, ARG_BSTR, 0) \
|
||||||
X(memberid, 1, 0,0) \
|
X(memberid, 1, ARG_UINT, 0) \
|
||||||
X(minus, 1, 0,0) \
|
X(minus, 1, 0,0) \
|
||||||
X(mod, 1, 0,0) \
|
X(mod, 1, 0,0) \
|
||||||
X(mul, 1, 0,0) \
|
X(mul, 1, 0,0) \
|
||||||
|
@ -580,4 +581,4 @@ HRESULT assign_and_expression_eval(script_ctx_t*,expression_t*,DWORD,jsexcept_t*
|
||||||
|
|
||||||
HRESULT compiled_expression_eval(script_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*) DECLSPEC_HIDDEN;
|
HRESULT compiled_expression_eval(script_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
HRESULT compile_subscript(parser_ctx_t*,expression_t*,unsigned*) DECLSPEC_HIDDEN;
|
HRESULT compile_subscript(parser_ctx_t*,expression_t*,BOOL,unsigned*) DECLSPEC_HIDDEN;
|
||||||
|
|
|
@ -1356,7 +1356,7 @@ static const expression_eval_t expression_eval_table[] = {
|
||||||
array_expression_eval,
|
array_expression_eval,
|
||||||
member_expression_eval,
|
member_expression_eval,
|
||||||
compiled_expression_eval,
|
compiled_expression_eval,
|
||||||
call_expression_eval,
|
compiled_expression_eval,
|
||||||
compiled_expression_eval,
|
compiled_expression_eval,
|
||||||
function_expression_eval,
|
function_expression_eval,
|
||||||
identifier_expression_eval,
|
identifier_expression_eval,
|
||||||
|
|
|
@ -729,7 +729,7 @@ static HRESULT WINAPI Global_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid,
|
||||||
|
|
||||||
ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
|
ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
|
||||||
ok(pdp != NULL, "pdp == NULL\n");
|
ok(pdp != NULL, "pdp == NULL\n");
|
||||||
todo_wine ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
|
ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
|
||||||
ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
|
ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
|
||||||
ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
|
ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs);
|
||||||
ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
|
ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
|
||||||
|
|
Loading…
Reference in New Issue