Jacek Caban : jscript: Use bytecode for instanceof implementation.

Alexandre Julliard julliard at winehq.org
Mon Dec 12 12:25:55 CST 2011


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Mon Dec 12 14:43:54 2011 +0100

jscript: Use bytecode for instanceof implementation.

---

 dlls/jscript/compile.c |    2 +
 dlls/jscript/engine.c  |  105 ++++++++++--------------------------------------
 dlls/jscript/engine.h  |    2 +-
 dlls/jscript/parser.y  |    2 +-
 4 files changed, 26 insertions(+), 85 deletions(-)

diff --git a/dlls/jscript/compile.c b/dlls/jscript/compile.c
index 1121838..0d4ce79 100644
--- a/dlls/jscript/compile.c
+++ b/dlls/jscript/compile.c
@@ -661,6 +661,8 @@ static HRESULT compile_expression_noret(compiler_ctx_t *ctx, expression_t *expr,
         return push_instr_bstr(ctx, OP_ident, ((identifier_expression_t*)expr)->identifier);
     case EXPR_IN:
         return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_in);
+    case EXPR_INSTANCEOF:
+        return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_instanceof);
     case EXPR_LESS:
         return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_lt);
     case EXPR_LESSEQ:
diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c
index 7b85040..288c5d2 100644
--- a/dlls/jscript/engine.c
+++ b/dlls/jscript/engine.c
@@ -1389,57 +1389,6 @@ static HRESULT return_bool(exprval_t *ret, DWORD b)
     return S_OK;
 }
 
-static HRESULT get_binary_expr_values(script_ctx_t *ctx, binary_expression_t *expr, jsexcept_t *ei, VARIANT *lval, VARIANT *rval)
-{
-    exprval_t exprval;
-    HRESULT hres;
-
-    hres = expr_eval(ctx, expr->expression1, 0, ei, &exprval);
-    if(FAILED(hres))
-        return hres;
-
-    hres = exprval_to_value(ctx, &exprval, ei, lval);
-    exprval_release(&exprval);
-    if(FAILED(hres))
-        return hres;
-
-    hres = expr_eval(ctx, expr->expression2, 0, ei, &exprval);
-    if(SUCCEEDED(hres)) {
-        hres = exprval_to_value(ctx, &exprval, ei, rval);
-        exprval_release(&exprval);
-    }
-
-    if(FAILED(hres)) {
-        VariantClear(lval);
-        return hres;
-    }
-
-    return S_OK;
-}
-
-typedef HRESULT (*oper_t)(script_ctx_t*,VARIANT*,VARIANT*,jsexcept_t*,VARIANT*);
-
-static HRESULT binary_expr_eval(script_ctx_t *ctx, binary_expression_t *expr, oper_t oper, jsexcept_t *ei,
-        exprval_t *ret)
-{
-    VARIANT lval, rval, retv;
-    HRESULT hres;
-
-    hres = get_binary_expr_values(ctx, expr, ei, &lval, &rval);
-    if(FAILED(hres))
-        return hres;
-
-    hres = oper(ctx, &lval, &rval, ei, &retv);
-    VariantClear(&lval);
-    VariantClear(&rval);
-    if(FAILED(hres))
-        return hres;
-
-    ret->type = EXPRVAL_VARIANT;
-    ret->u.var = retv;
-    return S_OK;
-}
-
 /* ECMA-262 3rd Edition    13 */
 HRESULT function_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
 {
@@ -2149,45 +2098,46 @@ static HRESULT interp_and(exec_ctx_t *ctx)
 }
 
 /* ECMA-262 3rd Edition    11.8.6 */
-static HRESULT instanceof_eval(script_ctx_t *ctx, VARIANT *inst, VARIANT *objv, jsexcept_t *ei, VARIANT *retv)
+static HRESULT interp_instanceof(exec_ctx_t *ctx)
 {
     jsdisp_t *obj, *iter, *tmp = NULL;
-    VARIANT_BOOL ret = VARIANT_FALSE;
-    BOOL b;
-    VARIANT var;
+    VARIANT prot, *v;
+    BOOL ret = FALSE;
     HRESULT hres;
 
     static const WCHAR prototypeW[] = {'p','r','o','t','o','t', 'y', 'p','e',0};
 
-    if(V_VT(objv) != VT_DISPATCH || !V_DISPATCH(objv))
-        return throw_type_error(ctx, ei, JS_E_FUNCTION_EXPECTED, NULL);
+    v = stack_pop(ctx);
+    if(V_VT(v) != VT_DISPATCH || !V_DISPATCH(v)) {
+        VariantClear(v);
+        return throw_type_error(ctx->parser->script, &ctx->ei, JS_E_FUNCTION_EXPECTED, NULL);
+    }
 
-    obj = iface_to_jsdisp((IUnknown*)V_DISPATCH(objv));
+    obj = iface_to_jsdisp((IUnknown*)V_DISPATCH(v));
+    IDispatch_Release(V_DISPATCH(v));
     if(!obj) {
         FIXME("non-jsdisp objects not supported\n");
         return E_FAIL;
     }
 
     if(is_class(obj, JSCLASS_FUNCTION)) {
-        hres = jsdisp_propget_name(obj, prototypeW, &var, ei, NULL/*FIXME*/);
+        hres = jsdisp_propget_name(obj, prototypeW, &prot, &ctx->ei, NULL/*FIXME*/);
     }else {
-        hres = throw_type_error(ctx, ei, JS_E_FUNCTION_EXPECTED, NULL);
+        hres = throw_type_error(ctx->parser->script, &ctx->ei, JS_E_FUNCTION_EXPECTED, NULL);
     }
     jsdisp_release(obj);
     if(FAILED(hres))
         return hres;
 
-    if(V_VT(&var) == VT_DISPATCH) {
-        if(V_VT(inst) == VT_DISPATCH)
-            tmp = iface_to_jsdisp((IUnknown*)V_DISPATCH(inst));
-        for(iter = tmp; iter; iter = iter->prototype) {
-            hres = disp_cmp(V_DISPATCH(&var), to_disp(iter), &b);
+    v = stack_pop(ctx);
+
+    if(V_VT(&prot) == VT_DISPATCH) {
+        if(V_VT(v) == VT_DISPATCH)
+            tmp = iface_to_jsdisp((IUnknown*)V_DISPATCH(v));
+        for(iter = tmp; !ret && iter; iter = iter->prototype) {
+            hres = disp_cmp(V_DISPATCH(&prot), to_disp(iter), &ret);
             if(FAILED(hres))
                 break;
-            if(b) {
-                ret = VARIANT_TRUE;
-                break;
-            }
         }
 
         if(tmp)
@@ -2197,23 +2147,12 @@ static HRESULT instanceof_eval(script_ctx_t *ctx, VARIANT *inst, VARIANT *objv,
         hres = E_FAIL;
     }
 
-    VariantClear(&var);
+    VariantClear(&prot);
+    VariantClear(v);
     if(FAILED(hres))
         return hres;
 
-    V_VT(retv) = VT_BOOL;
-    V_BOOL(retv) = ret;
-    return S_OK;
-}
-
-/* ECMA-262 3rd Edition    11.8.6 */
-HRESULT instanceof_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;
-
-    TRACE("\n");
-
-    return binary_expr_eval(ctx, expr, instanceof_eval, ei, ret);
+    return stack_push_bool(ctx, ret);
 }
 
 /* ECMA-262 3rd Edition    11.8.7 */
diff --git a/dlls/jscript/engine.h b/dlls/jscript/engine.h
index e6ad0c9..b9e6441 100644
--- a/dlls/jscript/engine.h
+++ b/dlls/jscript/engine.h
@@ -61,6 +61,7 @@ typedef struct _func_stack {
     X(ident,      1, ARG_BSTR,   0)        \
     X(identid,    1, ARG_BSTR,   ARG_INT)  \
     X(in,         1, 0,0)                  \
+    X(instanceof, 1, 0,0)                  \
     X(int,        1, ARG_INT,    0)        \
     X(jmp,        0, ARG_ADDR,   0)        \
     X(jmp_nz,     0, ARG_ADDR,   0)        \
@@ -565,7 +566,6 @@ HRESULT member_expression_eval(script_ctx_t*,expression_t*,DWORD,jsexcept_t*,exp
 HRESULT identifier_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 instanceof_expression_eval(script_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*) DECLSPEC_HIDDEN;
 HRESULT delete_expression_eval(script_ctx_t*,expression_t*,DWORD,jsexcept_t*,exprval_t*) DECLSPEC_HIDDEN;
 HRESULT typeof_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 76d1c1d..88676dd 100644
--- a/dlls/jscript/parser.y
+++ b/dlls/jscript/parser.y
@@ -1310,7 +1310,7 @@ static const expression_eval_t expression_eval_table[] = {
    compiled_expression_eval,
    compiled_expression_eval,
    compiled_expression_eval,
-   instanceof_expression_eval,
+   compiled_expression_eval,
    compiled_expression_eval,
    compiled_expression_eval,
    compiled_expression_eval,




More information about the wine-cvs mailing list