jscript: Use bytecode for all call expressions.
This commit is contained in:
parent
3aa7cee00e
commit
4da0cf39f4
|
@ -400,14 +400,17 @@ static HRESULT compile_call_expression(compiler_ctx_t *ctx, call_expression_t *e
|
||||||
unsigned arg_cnt = 0;
|
unsigned arg_cnt = 0;
|
||||||
argument_t *arg;
|
argument_t *arg;
|
||||||
unsigned instr;
|
unsigned instr;
|
||||||
|
jsop_t op;
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
|
||||||
if(!is_memberid_expr(expr->expression->type)) {
|
if(is_memberid_expr(expr->expression->type)) {
|
||||||
expr->expr.eval = call_expression_eval;
|
op = OP_call_member;
|
||||||
return compile_interp_fallback(ctx, &expr->expr);
|
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))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
|
@ -418,7 +421,7 @@ static HRESULT compile_call_expression(compiler_ctx_t *ctx, call_expression_t *e
|
||||||
arg_cnt++;
|
arg_cnt++;
|
||||||
}
|
}
|
||||||
|
|
||||||
instr = push_instr(ctx, OP_call_member);
|
instr = push_instr(ctx, op);
|
||||||
if(instr == -1)
|
if(instr == -1)
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
|
|
@ -1697,55 +1697,6 @@ static HRESULT interp_refval(exec_ctx_t *ctx)
|
||||||
return stack_push(ctx, &v);
|
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)
|
static void jsstack_to_dp(exec_ctx_t *ctx, unsigned arg_cnt, DISPPARAMS *dp)
|
||||||
{
|
{
|
||||||
VARIANT tmp;
|
VARIANT tmp;
|
||||||
|
@ -1798,55 +1749,29 @@ static HRESULT interp_new(exec_ctx_t *ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ECMA-262 3rd Edition 11.2.3 */
|
/* 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;
|
const unsigned argn = ctx->parser->code->instrs[ctx->ip].arg1.uint;
|
||||||
VARIANT var;
|
const int do_ret = ctx->parser->code->instrs[ctx->ip].arg2.lng;
|
||||||
exprval_t exprval;
|
VARIANT v, *objv;
|
||||||
DISPPARAMS dp;
|
DISPPARAMS dp;
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
|
||||||
TRACE("\n");
|
TRACE("%d %d\n", argn, do_ret);
|
||||||
|
|
||||||
hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
|
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);
|
||||||
|
|
||||||
|
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))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
hres = args_to_param(ctx, expr->argument_list, ei, &dp);
|
stack_popn(ctx, argn+1);
|
||||||
if(SUCCEEDED(hres)) {
|
return do_ret ? stack_push(ctx, &v) : S_OK;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
free_dp(&dp);
|
|
||||||
}
|
|
||||||
|
|
||||||
exprval_release(&exprval);
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ECMA-262 3rd Edition 11.2.3 */
|
/* ECMA-262 3rd Edition 11.2.3 */
|
||||||
|
|
|
@ -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, 1, ARG_UINT, ARG_UINT) \
|
||||||
X(call_member,1, ARG_UINT, ARG_UINT) \
|
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) \
|
||||||
|
@ -558,7 +559,6 @@ typedef struct {
|
||||||
HRESULT function_expression_eval(script_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*) DECLSPEC_HIDDEN;
|
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 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 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 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 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;
|
HRESULT property_value_expression_eval(script_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*) DECLSPEC_HIDDEN;
|
||||||
|
|
Loading…
Reference in New Issue