From 558d759465898c20135da6ed03106d454ccdf18a Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Thu, 8 Dec 2011 12:02:40 +0100 Subject: [PATCH] jscript: Use bytecode for array literal expressions. --- dlls/jscript/compile.c | 30 +++++++++++++++++++ dlls/jscript/engine.c | 65 ++++++++++++++++++------------------------ dlls/jscript/engine.h | 3 +- dlls/jscript/parser.y | 2 +- 4 files changed, 60 insertions(+), 40 deletions(-) diff --git a/dlls/jscript/compile.c b/dlls/jscript/compile.c index 483c9de5d9a..f0f9cc029a8 100644 --- a/dlls/jscript/compile.c +++ b/dlls/jscript/compile.c @@ -570,6 +570,34 @@ static HRESULT compile_literal(compiler_ctx_t *ctx, literal_t *literal) } } +static HRESULT compile_array_literal(compiler_ctx_t *ctx, array_literal_expression_t *expr) +{ + unsigned i, elem_cnt = expr->length; + array_element_t *iter; + HRESULT hres; + + for(iter = expr->element_list; iter; iter = iter->next) { + elem_cnt += iter->elision+1; + + for(i=0; i < iter->elision; i++) { + if(push_instr(ctx, OP_undefined) == -1) + return E_OUTOFMEMORY; + } + + hres = compile_expression(ctx, iter->expr); + if(FAILED(hres)) + return hres; + } + + for(i=0; i < expr->length; i++) { + if(push_instr(ctx, OP_undefined) == -1) + return E_OUTOFMEMORY; + } + + return push_instr_uint(ctx, OP_carray, elem_cnt); +} + + static HRESULT compile_expression_noret(compiler_ctx_t *ctx, expression_t *expr, BOOL *no_ret) { switch(expr->type) { @@ -579,6 +607,8 @@ static HRESULT compile_expression_noret(compiler_ctx_t *ctx, expression_t *expr, return compile_logical_expression(ctx, (binary_expression_t*)expr, OP_jmp_z); case EXPR_ARRAY: return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_array); + case EXPR_ARRAYLIT: + return compile_array_literal(ctx, (array_literal_expression_t*)expr); case EXPR_ASSIGN: return compile_assign_expression(ctx, (binary_expression_t*)expr, OP_LAST); case EXPR_ASSIGNADD: diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c index 467d6865853..f72ee42234d 100644 --- a/dlls/jscript/engine.c +++ b/dlls/jscript/engine.c @@ -2001,54 +2001,33 @@ static HRESULT interp_regexp(exec_ctx_t *ctx) } /* ECMA-262 3rd Edition 11.1.4 */ -HRESULT array_literal_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret) +static HRESULT interp_carray(exec_ctx_t *ctx) { - array_literal_expression_t *expr = (array_literal_expression_t*)_expr; - DWORD length = 0, i = 0; - array_element_t *elem; + const unsigned arg = ctx->parser->code->instrs[ctx->ip].arg1.uint; jsdisp_t *array; - exprval_t exprval; - VARIANT val; + VARIANT *v, r; + unsigned i; HRESULT hres; - TRACE("\n"); + TRACE("%u\n", arg); - for(elem = expr->element_list; elem; elem = elem->next) - length += elem->elision+1; - length += expr->length; - - hres = create_array(ctx, length, &array); + hres = create_array(ctx->parser->script, arg, &array); if(FAILED(hres)) return hres; - for(elem = expr->element_list; elem; elem = elem->next) { - i += elem->elision; - - hres = expr_eval(ctx, elem->expr, 0, ei, &exprval); - if(FAILED(hres)) - break; - - hres = exprval_to_value(ctx, &exprval, ei, &val); - exprval_release(&exprval); - if(FAILED(hres)) - break; - - hres = jsdisp_propput_idx(array, i, &val, ei, NULL/*FIXME*/); - VariantClear(&val); - if(FAILED(hres)) - break; - - i++; + i = arg; + while(i--) { + v = stack_pop(ctx); + hres = jsdisp_propput_idx(array, i, v, &ctx->ei, NULL/*FIXME*/); + VariantClear(v); + if(FAILED(hres)) { + jsdisp_release(array); + return hres; + } } - if(FAILED(hres)) { - jsdisp_release(array); - return hres; - } - - ret->type = EXPRVAL_VARIANT; - var_set_jsdisp(&ret->u.var, array); - return S_OK; + var_set_jsdisp(&r, array); + return stack_push(ctx, &r); } /* ECMA-262 3rd Edition 11.1.5 */ @@ -3270,6 +3249,16 @@ HRESULT assign_and_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD return assign_oper_eval(ctx, expr->expression1, expr->expression2, bitand_eval, ei, ret); } +static HRESULT interp_undefined(exec_ctx_t *ctx) +{ + VARIANT v; + + TRACE("\n"); + + V_VT(&v) = VT_EMPTY; + return stack_push(ctx, &v); +} + static HRESULT interp_jmp(exec_ctx_t *ctx) { const unsigned arg = ctx->parser->code->instrs[ctx->ip].arg1.uint; diff --git a/dlls/jscript/engine.h b/dlls/jscript/engine.h index dab692f98a9..4bee8248d13 100644 --- a/dlls/jscript/engine.h +++ b/dlls/jscript/engine.h @@ -49,6 +49,7 @@ typedef struct _func_stack { X(bneg, 1, 0,0) \ X(call, 1, ARG_UINT, ARG_UINT) \ X(call_member,1, ARG_UINT, ARG_UINT) \ + X(carray, 1, ARG_UINT, 0) \ X(delete, 1, 0,0) \ X(div, 1, 0,0) \ X(double, 1, ARG_SBL, 0) \ @@ -88,6 +89,7 @@ typedef struct _func_stack { X(refval, 1, 0,0) \ X(ret, 0, 0,0) \ X(sub, 1, 0,0) \ + X(undefined, 1, 0,0) \ X(void, 1, 0,0) \ X(xor, 1, 0,0) @@ -557,7 +559,6 @@ HRESULT function_expression_eval(script_ctx_t*,expression_t*,DWORD,jsexcept_t*,e 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 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; HRESULT binary_and_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 4fbd678fe84..e7eadfa5faf 100644 --- a/dlls/jscript/parser.y +++ b/dlls/jscript/parser.y @@ -1359,7 +1359,7 @@ static const expression_eval_t expression_eval_table[] = { compiled_expression_eval, function_expression_eval, identifier_expression_eval, - array_literal_expression_eval, + compiled_expression_eval, property_value_expression_eval, compiled_expression_eval };