From a289b8e0a40a29a0e2aa0fdc959766a189b0135d Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Tue, 6 Dec 2011 10:42:09 +0100 Subject: [PATCH] jscript: Added bytecode version of member expression. --- dlls/jscript/compile.c | 14 +++++++++++++ dlls/jscript/engine.c | 45 ++++++++++++++++++++++++++++++++++++++++++ dlls/jscript/engine.h | 1 + 3 files changed, 60 insertions(+) diff --git a/dlls/jscript/compile.c b/dlls/jscript/compile.c index af227c0f835..9a0a47191c0 100644 --- a/dlls/jscript/compile.c +++ b/dlls/jscript/compile.c @@ -210,6 +210,18 @@ static HRESULT compile_unary_expression(compiler_ctx_t *ctx, unary_expression_t return push_instr(ctx, op) == -1 ? E_OUTOFMEMORY : S_OK; } +/* ECMA-262 3rd Edition 11.2.1 */ +static HRESULT compile_member_expression(compiler_ctx_t *ctx, member_expression_t *expr) +{ + HRESULT hres; + + hres = compile_expression(ctx, expr->expression); + if(FAILED(hres)) + return hres; + + return push_instr_bstr(ctx, OP_member, expr->identifier); +} + /* ECMA-262 3rd Edition 11.14 */ static HRESULT compile_comma_expression(compiler_ctx_t *ctx, binary_expression_t *expr) { @@ -519,6 +531,8 @@ static HRESULT compile_expression(compiler_ctx_t *ctx, expression_t *expr) return compile_literal(ctx, ((literal_expression_t*)expr)->literal); case EXPR_LOGNEG: return compile_unary_expression(ctx, (unary_expression_t*)expr, OP_neg); + case EXPR_MEMBER: + return compile_member_expression(ctx, (member_expression_t*)expr); case EXPR_MINUS: return compile_unary_expression(ctx, (unary_expression_t*)expr, OP_minus); case EXPR_MOD: diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c index 0696e778c10..9e9c04d2377 100644 --- a/dlls/jscript/engine.c +++ b/dlls/jscript/engine.c @@ -153,6 +153,22 @@ static HRESULT stack_pop_number(exec_ctx_t *ctx, VARIANT *r) return hres; } +static HRESULT stack_pop_object(exec_ctx_t *ctx, IDispatch **r) +{ + VARIANT *v; + HRESULT hres; + + v = stack_pop(ctx); + if(V_VT(v) == VT_DISPATCH) { + *r = V_DISPATCH(v); + return S_OK; + } + + hres = to_object(ctx->parser->script, v, r); + VariantClear(v); + return hres; +} + static inline HRESULT stack_pop_int(exec_ctx_t *ctx, INT *r) { return to_int32(ctx->parser->script, stack_pop(ctx), &ctx->ei, r); @@ -1590,6 +1606,35 @@ HRESULT member_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD fla return hres; } +/* ECMA-262 3rd Edition 11.2.1 */ +static HRESULT interp_member(exec_ctx_t *ctx) +{ + const BSTR arg = ctx->parser->code->instrs[ctx->ip].arg1.bstr; + IDispatch *obj; + VARIANT v; + DISPID id; + HRESULT hres; + + TRACE("\n"); + + hres = stack_pop_object(ctx, &obj); + if(FAILED(hres)) + return hres; + + hres = disp_get_id(ctx->parser->script, obj, arg, 0, &id); + if(SUCCEEDED(hres)) { + hres = disp_propget(ctx->parser->script, obj, id, &v, &ctx->ei, NULL/*FIXME*/); + }else if(hres == DISP_E_UNKNOWNNAME) { + V_VT(&v) = VT_EMPTY; + hres = S_OK; + } + IDispatch_Release(obj); + if(FAILED(hres)) + return hres; + + return stack_push(ctx, &v); +} + /* ECMA-262 3rd Edition 11.2.1 */ static HRESULT interp_memberid(exec_ctx_t *ctx) { diff --git a/dlls/jscript/engine.h b/dlls/jscript/engine.h index 54e28a9f093..330dc34936f 100644 --- a/dlls/jscript/engine.h +++ b/dlls/jscript/engine.h @@ -62,6 +62,7 @@ typedef struct _func_stack { X(jmp_z, 0, ARG_ADDR, 0) \ X(lt, 1, 0,0) \ X(lteq, 1, 0,0) \ + X(member, 1, ARG_BSTR, 0) \ X(memberid, 1, 0,0) \ X(minus, 1, 0,0) \ X(mod, 1, 0,0) \