jscript: Use bytecode for new expression implementation.
This commit is contained in:
parent
25e58de596
commit
518f4c4983
|
@ -227,6 +227,26 @@ static HRESULT compile_conditional_expression(compiler_ctx_t *ctx, conditional_e
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT compile_new_expression(compiler_ctx_t *ctx, call_expression_t *expr)
|
||||
{
|
||||
unsigned arg_cnt = 0;
|
||||
argument_t *arg;
|
||||
HRESULT hres;
|
||||
|
||||
hres = compile_expression(ctx, expr->expression);
|
||||
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++;
|
||||
}
|
||||
|
||||
return push_instr_int(ctx, OP_new, arg_cnt);
|
||||
}
|
||||
|
||||
static HRESULT compile_interp_fallback(compiler_ctx_t *ctx, expression_t *expr)
|
||||
{
|
||||
unsigned instr;
|
||||
|
@ -300,6 +320,8 @@ static HRESULT compile_expression(compiler_ctx_t *ctx, expression_t *expr)
|
|||
return compile_unary_expression(ctx, (unary_expression_t*)expr, OP_neg);
|
||||
case EXPR_MINUS:
|
||||
return compile_unary_expression(ctx, (unary_expression_t*)expr, OP_minus);
|
||||
case EXPR_NEW:
|
||||
return compile_new_expression(ctx, (call_expression_t*)expr);
|
||||
case EXPR_NOTEQ:
|
||||
return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_neq);
|
||||
case EXPR_NOTEQEQ:
|
||||
|
|
|
@ -96,9 +96,16 @@ static inline HRESULT stack_push_number(exec_ctx_t *ctx, double number)
|
|||
|
||||
static inline VARIANT *stack_top(exec_ctx_t *ctx)
|
||||
{
|
||||
assert(ctx->top);
|
||||
return ctx->stack + ctx->top-1;
|
||||
}
|
||||
|
||||
static inline VARIANT *stack_topn(exec_ctx_t *ctx, unsigned n)
|
||||
{
|
||||
assert(ctx->top > n);
|
||||
return ctx->stack + ctx->top-1-n;
|
||||
}
|
||||
|
||||
static inline VARIANT *stack_pop(exec_ctx_t *ctx)
|
||||
{
|
||||
assert(ctx->top);
|
||||
|
@ -1594,51 +1601,55 @@ static HRESULT args_to_param(script_ctx_t *ctx, argument_t *args, jsexcept_t *ei
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
/* ECMA-262 3rd Edition 11.2.2 */
|
||||
HRESULT new_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
|
||||
static void jsstack_to_dp(exec_ctx_t *ctx, unsigned arg_cnt, DISPPARAMS *dp)
|
||||
{
|
||||
call_expression_t *expr = (call_expression_t*)_expr;
|
||||
exprval_t exprval;
|
||||
VARIANT constr, var;
|
||||
VARIANT tmp;
|
||||
unsigned i;
|
||||
|
||||
dp->cArgs = arg_cnt;
|
||||
dp->rgdispidNamedArgs = NULL;
|
||||
dp->cNamedArgs = 0;
|
||||
|
||||
assert(ctx->top >= arg_cnt);
|
||||
|
||||
for(i=1; i*2 <= arg_cnt; i++) {
|
||||
tmp = ctx->stack[ctx->top-i];
|
||||
ctx->stack[ctx->top-i] = ctx->stack[ctx->top-arg_cnt+i-1];
|
||||
ctx->stack[ctx->top-arg_cnt+i-1] = tmp;
|
||||
}
|
||||
|
||||
dp->rgvarg = ctx->stack + ctx->top-arg_cnt;
|
||||
}
|
||||
|
||||
/* ECMA-262 3rd Edition 11.2.2 */
|
||||
HRESULT interp_new(exec_ctx_t *ctx)
|
||||
{
|
||||
const LONG arg = ctx->parser->code->instrs[ctx->ip].arg1.lng;
|
||||
VARIANT *constr, v;
|
||||
DISPPARAMS dp;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("\n");
|
||||
TRACE("%d\n", arg);
|
||||
|
||||
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))
|
||||
hres = exprval_to_value(ctx, &exprval, ei, &constr);
|
||||
exprval_release(&exprval);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
constr = stack_topn(ctx, arg);
|
||||
|
||||
/* NOTE: Should use to_object here */
|
||||
|
||||
if(V_VT(&constr) == VT_NULL) {
|
||||
VariantClear(&constr);
|
||||
return throw_type_error(ctx, ei, JS_E_OBJECT_EXPECTED, NULL);
|
||||
} else if(V_VT(&constr) != VT_DISPATCH) {
|
||||
VariantClear(&constr);
|
||||
return throw_type_error(ctx, ei, JS_E_INVALID_ACTION, NULL);
|
||||
} else if(!V_DISPATCH(&constr)) {
|
||||
VariantClear(&constr);
|
||||
return throw_type_error(ctx, ei, JS_E_INVALID_PROPERTY, NULL);
|
||||
}
|
||||
if(V_VT(constr) == VT_NULL)
|
||||
return throw_type_error(ctx->parser->script, &ctx->ei, JS_E_OBJECT_EXPECTED, NULL);
|
||||
else if(V_VT(constr) != VT_DISPATCH)
|
||||
return throw_type_error(ctx->parser->script, &ctx->ei, JS_E_INVALID_ACTION, NULL);
|
||||
else if(!V_DISPATCH(constr))
|
||||
return throw_type_error(ctx->parser->script, &ctx->ei, JS_E_INVALID_PROPERTY, NULL);
|
||||
|
||||
hres = disp_call(ctx, V_DISPATCH(&constr), DISPID_VALUE,
|
||||
DISPATCH_CONSTRUCT, &dp, &var, ei, NULL/*FIXME*/);
|
||||
IDispatch_Release(V_DISPATCH(&constr));
|
||||
free_dp(&dp);
|
||||
jsstack_to_dp(ctx, arg, &dp);
|
||||
hres = disp_call(ctx->parser->script, V_DISPATCH(constr), DISPID_VALUE,
|
||||
DISPATCH_CONSTRUCT, &dp, &v, &ctx->ei, NULL/*FIXME*/);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
ret->type = EXPRVAL_VARIANT;
|
||||
ret->u.var = var;
|
||||
return S_OK;
|
||||
stack_popn(ctx, arg+1);
|
||||
return stack_push(ctx, &v);
|
||||
}
|
||||
|
||||
/* ECMA-262 3rd Edition 11.2.3 */
|
||||
|
|
|
@ -57,6 +57,7 @@ typedef struct _func_stack {
|
|||
X(neg, 1, 0,0) \
|
||||
X(neq, 1, 0,0) \
|
||||
X(neq2, 1, 0,0) \
|
||||
X(new, 1, ARG_INT, 0) \
|
||||
X(null, 1, 0,0) \
|
||||
X(pop, 1, 0,0) \
|
||||
X(regexp, 1, ARG_STR, ARG_INT) \
|
||||
|
@ -538,7 +539,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 new_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;
|
||||
|
|
|
@ -1355,7 +1355,7 @@ static const expression_eval_t expression_eval_table[] = {
|
|||
compiled_expression_eval,
|
||||
array_expression_eval,
|
||||
member_expression_eval,
|
||||
new_expression_eval,
|
||||
compiled_expression_eval,
|
||||
call_expression_eval,
|
||||
compiled_expression_eval,
|
||||
function_expression_eval,
|
||||
|
|
Loading…
Reference in New Issue