From 4da0cf39f4399f22f34c4c1ef0d5f14e971f3dc1 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Wed, 7 Dec 2011 11:00:44 +0100 Subject: [PATCH] jscript: Use bytecode for all call expressions. --- dlls/jscript/compile.c | 13 ++++--- dlls/jscript/engine.c | 103 +++++++------------------------------------------ dlls/jscript/engine.h | 2 +- 3 files changed, 23 insertions(+), 95 deletions(-) diff --git a/dlls/jscript/compile.c b/dlls/jscript/compile.c index 34ac0a4d60c..a476155276e 100644 --- a/dlls/jscript/compile.c +++ b/dlls/jscript/compile.c @@ -400,14 +400,17 @@ static HRESULT compile_call_expression(compiler_ctx_t *ctx, call_expression_t *e unsigned arg_cnt = 0; argument_t *arg; unsigned instr; + jsop_t op; HRESULT hres; - if(!is_memberid_expr(expr->expression->type)) { - expr->expr.eval = call_expression_eval; - return compile_interp_fallback(ctx, &expr->expr); + if(is_memberid_expr(expr->expression->type)) { + op = OP_call_member; + hres = compile_memberid_expression(ctx, expr->expression, 0); + }else { + op = OP_call; + hres = compile_expression(ctx, expr->expression); } - hres = compile_memberid_expression(ctx, expr->expression, 0); if(FAILED(hres)) return hres; @@ -418,7 +421,7 @@ static HRESULT compile_call_expression(compiler_ctx_t *ctx, call_expression_t *e arg_cnt++; } - instr = push_instr(ctx, OP_call_member); + instr = push_instr(ctx, op); if(instr == -1) return E_OUTOFMEMORY; diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c index 017030387ca..d3b1334391e 100644 --- a/dlls/jscript/engine.c +++ b/dlls/jscript/engine.c @@ -1697,55 +1697,6 @@ static HRESULT interp_refval(exec_ctx_t *ctx) return stack_push(ctx, &v); } -static void free_dp(DISPPARAMS *dp) -{ - DWORD i; - - for(i=0; i < dp->cArgs; i++) - VariantClear(dp->rgvarg+i); - heap_free(dp->rgvarg); -} - -static HRESULT args_to_param(script_ctx_t *ctx, argument_t *args, jsexcept_t *ei, DISPPARAMS *dp) -{ - VARIANTARG *vargs; - exprval_t exprval; - argument_t *iter; - DWORD cnt = 0, i; - HRESULT hres = S_OK; - - memset(dp, 0, sizeof(*dp)); - if(!args) - return S_OK; - - for(iter = args; iter; iter = iter->next) - cnt++; - - vargs = heap_alloc_zero(cnt * sizeof(*vargs)); - if(!vargs) - return E_OUTOFMEMORY; - - for(i = cnt, iter = args; iter; iter = iter->next) { - hres = expr_eval(ctx, iter->expr, 0, ei, &exprval); - if(FAILED(hres)) - break; - - hres = exprval_to_value(ctx, &exprval, ei, vargs + (--i)); - exprval_release(&exprval); - if(FAILED(hres)) - break; - } - - if(FAILED(hres)) { - free_dp(dp); - return hres; - } - - dp->rgvarg = vargs; - dp->cArgs = cnt; - return S_OK; -} - static void jsstack_to_dp(exec_ctx_t *ctx, unsigned arg_cnt, DISPPARAMS *dp) { VARIANT tmp; @@ -1798,55 +1749,29 @@ static HRESULT interp_new(exec_ctx_t *ctx) } /* ECMA-262 3rd Edition 11.2.3 */ -HRESULT call_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) +static HRESULT interp_call(exec_ctx_t *ctx) { - call_expression_t *expr = (call_expression_t*)_expr; - VARIANT var; - exprval_t exprval; + const unsigned argn = ctx->parser->code->instrs[ctx->ip].arg1.uint; + const int do_ret = ctx->parser->code->instrs[ctx->ip].arg2.lng; + VARIANT v, *objv; DISPPARAMS dp; HRESULT hres; - TRACE("\n"); - - hres = expr_eval(ctx, expr->expression, 0, ei, &exprval); - if(FAILED(hres)) - return hres; - - hres = args_to_param(ctx, expr->argument_list, ei, &dp); - if(SUCCEEDED(hres)) { - switch(exprval.type) { - case EXPRVAL_VARIANT: - if(V_VT(&exprval.u.var) == VT_DISPATCH) - hres = disp_call(ctx, V_DISPATCH(&exprval.u.var), DISPID_VALUE, - DISPATCH_METHOD, &dp, flags & EXPR_NOVAL ? NULL : &var, ei, NULL/*FIXME*/); - else - hres = throw_type_error(ctx, ei, JS_E_INVALID_PROPERTY, NULL); - break; - case EXPRVAL_IDREF: - assert(0); - case EXPRVAL_INVALID: - hres = throw_type_error(ctx, ei, JS_E_OBJECT_EXPECTED, NULL); - break; - default: - FIXME("unimplemented type %d\n", exprval.type); - hres = E_NOTIMPL; - } + TRACE("%d %d\n", argn, do_ret); - free_dp(&dp); - } + objv = stack_topn(ctx, argn); + if(V_VT(objv) != VT_DISPATCH) + return throw_type_error(ctx->parser->script, &ctx->ei, JS_E_INVALID_PROPERTY, NULL); - exprval_release(&exprval); + jsstack_to_dp(ctx, argn, &dp); + hres = disp_call(ctx->parser->script, V_DISPATCH(objv), DISPID_VALUE, DISPATCH_METHOD, &dp, + do_ret ? &v : NULL, &ctx->ei, NULL/*FIXME*/); if(FAILED(hres)) return hres; - ret->type = EXPRVAL_VARIANT; - if(flags & EXPR_NOVAL) { - V_VT(&ret->u.var) = VT_EMPTY; - }else { - TRACE("= %s\n", debugstr_variant(&var)); - ret->u.var = var; - } - return S_OK; + stack_popn(ctx, argn+1); + return do_ret ? stack_push(ctx, &v) : S_OK; + } /* ECMA-262 3rd Edition 11.2.3 */ diff --git a/dlls/jscript/engine.h b/dlls/jscript/engine.h index 88c61fc0277..ffa0fcde6c0 100644 --- a/dlls/jscript/engine.h +++ b/dlls/jscript/engine.h @@ -46,6 +46,7 @@ typedef struct _func_stack { X(assign, 1, 0,0) \ X(bool, 1, ARG_INT, 0) \ X(bneg, 1, 0,0) \ + X(call, 1, ARG_UINT, ARG_UINT) \ X(call_member,1, ARG_UINT, ARG_UINT) \ X(delete, 1, 0,0) \ X(div, 1, 0,0) \ @@ -558,7 +559,6 @@ typedef struct { HRESULT function_expression_eval(script_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*) DECLSPEC_HIDDEN; HRESULT array_expression_eval(script_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*) DECLSPEC_HIDDEN; HRESULT member_expression_eval(script_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*) DECLSPEC_HIDDEN; -HRESULT call_expression_eval(script_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*) DECLSPEC_HIDDEN; HRESULT identifier_expression_eval(script_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*) DECLSPEC_HIDDEN; HRESULT array_literal_expression_eval(script_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*) DECLSPEC_HIDDEN; HRESULT property_value_expression_eval(script_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*) DECLSPEC_HIDDEN; -- 2.11.4.GIT