Jacek Caban : jscript: Use bytecode for invalid assignments.

Alexandre Julliard julliard at winehq.org
Mon Dec 5 14:55:01 CST 2011


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Mon Dec  5 11:12:32 2011 +0100

jscript: Use bytecode for invalid assignments.

---

 dlls/jscript/compile.c    |   23 +++++++++++++++++++++--
 dlls/jscript/engine.c     |   43 +++++++++----------------------------------
 dlls/jscript/engine.h     |    2 +-
 dlls/jscript/tests/api.js |   12 ++++++++++++
 4 files changed, 43 insertions(+), 37 deletions(-)

diff --git a/dlls/jscript/compile.c b/dlls/jscript/compile.c
index 93d780f..73f57ee 100644
--- a/dlls/jscript/compile.c
+++ b/dlls/jscript/compile.c
@@ -172,6 +172,18 @@ static HRESULT push_instr_double(compiler_ctx_t *ctx, jsop_t op, double arg)
     return S_OK;
 }
 
+static HRESULT push_instr_uint(compiler_ctx_t *ctx, jsop_t op, unsigned arg)
+{
+    unsigned instr;
+
+    instr = push_instr(ctx, op);
+    if(instr == -1)
+        return E_OUTOFMEMORY;
+
+    instr_ptr(ctx, instr)->arg1.uint = arg;
+    return S_OK;
+}
+
 static HRESULT compile_binary_expression(compiler_ctx_t *ctx, binary_expression_t *expr, jsop_t op)
 {
     HRESULT hres;
@@ -390,8 +402,15 @@ static HRESULT compile_assign_expression(compiler_ctx_t *ctx, binary_expression_
         break;
     }
     default:
-        expr->expr.eval = assign_expression_eval;
-        return compile_interp_fallback(ctx, &expr->expr);
+        hres = compile_expression(ctx, expr->expression1);
+        if(FAILED(hres))
+            return hres;
+
+        hres = compile_expression(ctx, expr->expression2);
+        if(FAILED(hres))
+            return hres;
+
+        return push_instr_uint(ctx, OP_throw, JS_E_ILLEGAL_ASSIGN);
     }
 
 
diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c
index 2af2d75..124b7b0 100644
--- a/dlls/jscript/engine.c
+++ b/dlls/jscript/engine.c
@@ -1279,6 +1279,15 @@ HRESULT throw_statement_eval(script_ctx_t *ctx, statement_t *_stat, return_type_
     return DISP_E_EXCEPTION;
 }
 
+static HRESULT interp_throw(exec_ctx_t *ctx)
+{
+    const HRESULT arg = ctx->parser->code->instrs[ctx->ip].arg1.uint;
+
+    TRACE("%08x\n", arg);
+
+    return throw_reference_error(ctx->parser->script, &ctx->ei, arg, NULL);
+}
+
 /* ECMA-262 3rd Edition    12.14 */
 static HRESULT catch_eval(script_ctx_t *ctx, catch_block_t *block, return_type_t *rt, VARIANT *ret)
 {
@@ -3308,40 +3317,6 @@ HRESULT right2_shift_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWO
 }
 
 /* ECMA-262 3rd Edition    11.13.1 */
-HRESULT assign_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
-{
-    binary_expression_t *expr = (binary_expression_t*)_expr;
-    exprval_t exprval, exprvalr;
-    VARIANT rval;
-    HRESULT hres;
-
-    TRACE("\n");
-
-    hres = expr_eval(ctx, expr->expression1, EXPR_NEWREF, ei, &exprval);
-    if(FAILED(hres))
-        return hres;
-
-    hres = expr_eval(ctx, expr->expression2, 0, ei, &exprvalr);
-    if(SUCCEEDED(hres)) {
-        hres = exprval_to_value(ctx, &exprvalr, ei, &rval);
-        exprval_release(&exprvalr);
-    }
-
-    if(SUCCEEDED(hres)) {
-        assert(exprval.type != EXPRVAL_IDREF);
-        return throw_reference_error(ctx, ei, JS_E_ILLEGAL_ASSIGN, NULL);
-    }
-
-    exprval_release(&exprval);
-    if(FAILED(hres))
-        return hres;
-
-    ret->type = EXPRVAL_VARIANT;
-    ret->u.var = rval;
-    return S_OK;
-}
-
-/* ECMA-262 3rd Edition    11.13.1 */
 static HRESULT interp_assign(exec_ctx_t *ctx)
 {
     IDispatch *disp;
diff --git a/dlls/jscript/engine.h b/dlls/jscript/engine.h
index a032f7b..0825649 100644
--- a/dlls/jscript/engine.h
+++ b/dlls/jscript/engine.h
@@ -76,6 +76,7 @@ typedef struct _func_stack {
     X(regexp,     1, ARG_STR,    ARG_INT)  \
     X(str,        1, ARG_STR,    0)        \
     X(this,       1, 0,0)                  \
+    X(throw,      0, ARG_UINT,   0)        \
     X(tonum,      1, 0,0)                  \
     X(tree,       1, ARG_EXPR,   0)        \
     X(ret,        0, 0,0)                  \
@@ -570,7 +571,6 @@ HRESULT pre_decrement_expression_eval(script_ctx_t*,expression_t*,DWORD,jsexcept
 HRESULT left_shift_expression_eval(script_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*) DECLSPEC_HIDDEN;
 HRESULT right_shift_expression_eval(script_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*) DECLSPEC_HIDDEN;
 HRESULT right2_shift_expression_eval(script_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*) DECLSPEC_HIDDEN;
-HRESULT assign_expression_eval(script_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*) DECLSPEC_HIDDEN;
 HRESULT assign_lshift_expression_eval(script_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*) DECLSPEC_HIDDEN;
 HRESULT assign_rshift_expression_eval(script_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*) DECLSPEC_HIDDEN;
 HRESULT assign_rrshift_expression_eval(script_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*) DECLSPEC_HIDDEN;
diff --git a/dlls/jscript/tests/api.js b/dlls/jscript/tests/api.js
index b5ac66a..0118743 100644
--- a/dlls/jscript/tests/api.js
+++ b/dlls/jscript/tests/api.js
@@ -2076,6 +2076,18 @@ tmp = false;
 testException(function() {test = (tmp = true);}, "E_ILLEGAL_ASSIGN");
 ok(tmp, "expr value on invalid assign not evaluated");
 
+tmp = false;
+testException(function() {(tmp = true) = false;}, "E_ILLEGAL_ASSIGN");
+ok(tmp, "expr assign not evaluated");
+
+tmp = false;
+testException(function() {true = (tmp = true);}, "E_ILLEGAL_ASSIGN");
+ok(tmp, "expr value assign not evaluated");
+
+tmp = "";
+testException(function() {(tmp = tmp+"1") = (tmp = tmp+"2");}, "E_ILLEGAL_ASSIGN");
+ok(tmp === "12", "assign evaluated in unexpected order");
+
 // RegExpError tests
 testException(function() {RegExp(/a/, "g");}, "E_REGEXP_SYNTAX_ERROR");
 




More information about the wine-cvs mailing list