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