From 518f4c498383cc0fe065edcccdc812e2581c0c45 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Mon, 28 Nov 2011 12:05:07 +0100 Subject: [PATCH] jscript: Use bytecode for new expression implementation. --- dlls/jscript/compile.c | 22 ++++++++++++ dlls/jscript/engine.c | 77 ++++++++++++++++++++++++------------------ dlls/jscript/engine.h | 2 +- dlls/jscript/parser.y | 2 +- 4 files changed, 68 insertions(+), 35 deletions(-) diff --git a/dlls/jscript/compile.c b/dlls/jscript/compile.c index 5c830d2ec5e..492ca3c928b 100644 --- a/dlls/jscript/compile.c +++ b/dlls/jscript/compile.c @@ -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: diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c index 9244effb0a1..7e78c83118b 100644 --- a/dlls/jscript/engine.c +++ b/dlls/jscript/engine.c @@ -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 */ diff --git a/dlls/jscript/engine.h b/dlls/jscript/engine.h index a92b9423005..c5681f74542 100644 --- a/dlls/jscript/engine.h +++ b/dlls/jscript/engine.h @@ -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; diff --git a/dlls/jscript/parser.y b/dlls/jscript/parser.y index a3c54ad6b27..617c8488bf8 100644 --- a/dlls/jscript/parser.y +++ b/dlls/jscript/parser.y @@ -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,