Jacek Caban : jscript: Addded parameterized property assignment support.

Alexandre Julliard julliard at winehq.org
Tue Apr 17 13:31:49 CDT 2012


Module: wine
Branch: master
Commit: 0b0e34ab390af7cec0123cbc452425e83a419d57
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=0b0e34ab390af7cec0123cbc452425e83a419d57

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Tue Apr 17 16:25:58 2012 +0200

jscript: Addded parameterized property assignment support.

---

 dlls/jscript/compile.c |   43 ++++++++++++++++++++++++++++++++++++++-----
 dlls/jscript/dispex.c  |    5 +++++
 dlls/jscript/engine.c  |   29 +++++++++++++++++++++++++++++
 dlls/jscript/engine.h  |    1 +
 4 files changed, 73 insertions(+), 5 deletions(-)

diff --git a/dlls/jscript/compile.c b/dlls/jscript/compile.c
index b14c50b..16eed9e 100644
--- a/dlls/jscript/compile.c
+++ b/dlls/jscript/compile.c
@@ -607,9 +607,43 @@ static HRESULT compile_delete_expression(compiler_ctx_t *ctx, unary_expression_t
 
 static HRESULT compile_assign_expression(compiler_ctx_t *ctx, binary_expression_t *expr, jsop_t op)
 {
+    BOOL use_throw_path = FALSE;
+    unsigned arg_cnt = 0;
     HRESULT hres;
 
-    if(!is_memberid_expr(expr->expression1->type)) {
+    if(expr->expression1->type == EXPR_CALL) {
+        call_expression_t *call_expr = (call_expression_t*)expr->expression1;
+        argument_t *arg;
+
+        if(op != OP_LAST) {
+            FIXME("op %d not supported on parametrized assign expressions\n", op);
+            return E_NOTIMPL;
+        }
+
+        if(is_memberid_expr(call_expr->expression->type) && call_expr->argument_list) {
+            hres = compile_memberid_expression(ctx, call_expr->expression, fdexNameEnsure);
+            if(FAILED(hres))
+                return hres;
+
+            for(arg = call_expr->argument_list; arg; arg = arg->next) {
+                hres = compile_expression(ctx, arg->expr);
+                if(FAILED(hres))
+                    return hres;
+                arg_cnt++;
+            }
+        }else {
+            use_throw_path = TRUE;
+        }
+    }else if(is_memberid_expr(expr->expression1->type)) {
+        hres = compile_memberid_expression(ctx, expr->expression1, fdexNameEnsure);
+        if(FAILED(hres))
+            return hres;
+    }else {
+        use_throw_path = TRUE;
+    }
+
+    if(use_throw_path) {
+        /* Illegal assignment: evaluate and throw */
         hres = compile_expression(ctx, expr->expression1);
         if(FAILED(hres))
             return hres;
@@ -624,10 +658,6 @@ static HRESULT compile_assign_expression(compiler_ctx_t *ctx, binary_expression_
         return push_instr_uint(ctx, OP_throw_ref, JS_E_ILLEGAL_ASSIGN);
     }
 
-    hres = compile_memberid_expression(ctx, expr->expression1, fdexNameEnsure);
-    if(FAILED(hres))
-        return hres;
-
     if(op != OP_LAST && !push_instr(ctx, OP_refval))
         return E_OUTOFMEMORY;
 
@@ -638,6 +668,9 @@ static HRESULT compile_assign_expression(compiler_ctx_t *ctx, binary_expression_
     if(op != OP_LAST && !push_instr(ctx, op))
         return E_OUTOFMEMORY;
 
+    if(arg_cnt)
+        return push_instr_uint(ctx, OP_assign_call, arg_cnt);
+
     if(!push_instr(ctx, OP_assign))
         return E_OUTOFMEMORY;
 
diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c
index 0e209db..8518768 100644
--- a/dlls/jscript/dispex.c
+++ b/dlls/jscript/dispex.c
@@ -1030,6 +1030,11 @@ HRESULT disp_call(script_ctx_t *ctx, IDispatch *disp, DISPID id, WORD flags, DIS
 
     jsdisp = iface_to_jsdisp((IUnknown*)disp);
     if(jsdisp) {
+        if(flags & DISPATCH_PROPERTYPUT) {
+            FIXME("disp_call(propput) on builtin object\n");
+            return E_FAIL;
+        }
+
         hres = jsdisp_call(jsdisp, id, flags, dp, retv, ei);
         jsdisp_release(jsdisp);
         return hres;
diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c
index 19fddd4..d1854f8 100644
--- a/dlls/jscript/engine.c
+++ b/dlls/jscript/engine.c
@@ -2382,6 +2382,35 @@ static HRESULT interp_assign(exec_ctx_t *ctx)
     return stack_push(ctx, v);
 }
 
+/* JScript extension */
+static HRESULT interp_assign_call(exec_ctx_t *ctx)
+{
+    const unsigned arg = ctx->code->instrs[ctx->ip].arg1.uint;
+    DISPID propput_dispid = DISPID_PROPERTYPUT;
+    IDispatch *disp;
+    DISPPARAMS dp;
+    VARIANT *v;
+    DISPID id;
+    HRESULT hres;
+
+    TRACE("%u\n", arg);
+
+    disp = stack_topn_objid(ctx, arg+1, &id);
+    if(!disp)
+        return throw_reference_error(ctx->script, ctx->ei, JS_E_ILLEGAL_ASSIGN, NULL);
+
+    jsstack_to_dp(ctx, arg+1, &dp);
+    dp.cNamedArgs = 1;
+    dp.rgdispidNamedArgs = &propput_dispid;
+    hres = disp_call(ctx->script, disp, id, DISPATCH_PROPERTYPUT, &dp, NULL, ctx->ei);
+    if(FAILED(hres))
+        return hres;
+
+    v = stack_pop(ctx);
+    stack_popn(ctx, arg+2);
+    return stack_push(ctx, v);
+}
+
 static HRESULT interp_undefined(exec_ctx_t *ctx)
 {
     VARIANT v;
diff --git a/dlls/jscript/engine.h b/dlls/jscript/engine.h
index bb6552e..f214501 100644
--- a/dlls/jscript/engine.h
+++ b/dlls/jscript/engine.h
@@ -64,6 +64,7 @@ typedef struct {
     X(and,        1, 0,0)                  \
     X(array,      1, 0,0)                  \
     X(assign,     1, 0,0)                  \
+    X(assign_call,1, ARG_UINT,   0)       \
     X(bool,       1, ARG_INT,    0)        \
     X(bneg,       1, 0,0)                  \
     X(call,       1, ARG_UINT,   ARG_UINT) \




More information about the wine-cvs mailing list