Jacek Caban : jscript: Use bytecode for all call expressions.
Alexandre Julliard
julliard at winehq.org
Wed Dec 7 13:57:13 CST 2011
Module: wine
Branch: master
Commit: 4da0cf39f4399f22f34c4c1ef0d5f14e971f3dc1
URL: http://source.winehq.org/git/wine.git/?a=commit;h=4da0cf39f4399f22f34c4c1ef0d5f14e971f3dc1
Author: Jacek Caban <jacek at codeweavers.com>
Date: Wed Dec 7 11:00:44 2011 +0100
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 34ac0a4..a476155 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 0170303..d3b1334 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 88c61fc..ffa0fcd 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;
More information about the wine-cvs
mailing list