Jacek Caban : jscript: Use bytecode for delete on array expression implementation.
Alexandre Julliard
julliard at winehq.org
Wed Nov 30 14:19:20 CST 2011
Module: wine
Branch: master
Commit: facc2189d298ad0a76844c178fd2609e2fc7406c
URL: http://source.winehq.org/git/wine.git/?a=commit;h=facc2189d298ad0a76844c178fd2609e2fc7406c
Author: Jacek Caban <jacek at codeweavers.com>
Date: Wed Nov 30 10:14:22 2011 +0100
jscript: Use bytecode for delete on array expression implementation.
---
dlls/jscript/compile.c | 30 +++++++++++++++++++++++++
dlls/jscript/engine.c | 52 +++++++++++++++++++++++++++++++++++++++++++-
dlls/jscript/engine.h | 1 +
dlls/jscript/parser.y | 2 +-
dlls/jscript/tests/lang.js | 7 ++++++
5 files changed, 90 insertions(+), 2 deletions(-)
diff --git a/dlls/jscript/compile.c b/dlls/jscript/compile.c
index b7abdda..adcd749 100644
--- a/dlls/jscript/compile.c
+++ b/dlls/jscript/compile.c
@@ -301,6 +301,34 @@ static HRESULT compile_interp_fallback(compiler_ctx_t *ctx, expression_t *expr)
return S_OK;
}
+static HRESULT compile_delete_expression(compiler_ctx_t *ctx, unary_expression_t *expr)
+{
+ HRESULT hres;
+
+ switch(expr->expression->type) {
+ case EXPR_ARRAY: {
+ array_expression_t *array_expr = (array_expression_t*)expr->expression;
+
+ hres = compile_expression(ctx, array_expr->member_expr);
+ if(FAILED(hres))
+ return hres;
+
+ hres = compile_expression(ctx, array_expr->expression);
+ if(FAILED(hres))
+ return hres;
+
+ if(push_instr(ctx, OP_delete) == -1)
+ return E_OUTOFMEMORY;
+ break;
+ }
+ default:
+ expr->expr.eval = delete_expression_eval;
+ return compile_interp_fallback(ctx, &expr->expr);
+ }
+
+ return S_OK;
+}
+
static HRESULT compile_literal(compiler_ctx_t *ctx, literal_t *literal)
{
switch(literal->type) {
@@ -352,6 +380,8 @@ static HRESULT compile_expression(compiler_ctx_t *ctx, expression_t *expr)
return compile_comma_expression(ctx, (binary_expression_t*)expr);
case EXPR_COND:
return compile_conditional_expression(ctx, (conditional_expression_t*)expr);
+ case EXPR_DELETE:
+ return compile_delete_expression(ctx, (unary_expression_t*)expr);
case EXPR_DIV:
return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_div);
case EXPR_EQ:
diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c
index 48633cf..6567d68 100644
--- a/dlls/jscript/engine.c
+++ b/dlls/jscript/engine.c
@@ -2498,6 +2498,53 @@ HRESULT delete_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD fla
}
/* ECMA-262 3rd Edition 11.4.2 */
+static HRESULT interp_delete(exec_ctx_t *ctx)
+{
+ VARIANT *obj_var, *name_var;
+ IDispatchEx *dispex;
+ IDispatch *obj;
+ BSTR name;
+ BOOL ret;
+ HRESULT hres;
+
+ TRACE("\n");
+
+ name_var = stack_pop(ctx);
+ obj_var = stack_pop(ctx);
+
+ hres = to_object(ctx->parser->script, obj_var, &obj);
+ VariantClear(obj_var);
+ if(FAILED(hres)) {
+ VariantClear(name_var);
+ return hres;
+ }
+
+ hres = to_string(ctx->parser->script, name_var, &ctx->ei, &name);
+ VariantClear(name_var);
+ if(FAILED(hres)) {
+ IDispatch_Release(obj);
+ return hres;
+ }
+
+ hres = IDispatch_QueryInterface(obj, &IID_IDispatchEx, (void**)&dispex);
+ if(SUCCEEDED(hres)) {
+ hres = IDispatchEx_DeleteMemberByName(dispex, name, make_grfdex(ctx->parser->script, fdexNameCaseSensitive));
+ ret = TRUE;
+ IDispatchEx_Release(dispex);
+ }else {
+ hres = S_OK;
+ ret = FALSE;
+ }
+
+ IDispatch_Release(obj);
+ SysFreeString(name);
+ if(FAILED(hres))
+ return hres;
+
+ return stack_push_bool(ctx, ret);
+}
+
+/* ECMA-262 3rd Edition 11.4.2 */
static HRESULT interp_void(exec_ctx_t *ctx)
{
VARIANT v;
@@ -3469,5 +3516,8 @@ HRESULT compiled_expression_eval(script_ctx_t *ctx, expression_t *expr, DWORD fl
if(FAILED(hres))
return hres;
- return (expr->eval = interp_expression_eval)(ctx, expr, flags, ei, ret);
+ if(expr->eval == compiled_expression_eval)
+ expr->eval = interp_expression_eval;
+
+ return expr->eval(ctx, expr, flags, ei, ret);
}
diff --git a/dlls/jscript/engine.h b/dlls/jscript/engine.h
index 58f12c7..f2af36f 100644
--- a/dlls/jscript/engine.h
+++ b/dlls/jscript/engine.h
@@ -45,6 +45,7 @@ typedef struct _func_stack {
X(add, 1, 0,0) \
X(bool, 1, ARG_INT, 0) \
X(bneg, 1, 0,0) \
+ X(delete, 1, 0,0) \
X(div, 1, 0,0) \
X(double, 1, ARG_SBL, 0) \
X(eq, 1, 0,0) \
diff --git a/dlls/jscript/parser.y b/dlls/jscript/parser.y
index 0912107..3fffbe9 100644
--- a/dlls/jscript/parser.y
+++ b/dlls/jscript/parser.y
@@ -1318,7 +1318,7 @@ static const expression_eval_t expression_eval_table[] = {
compiled_expression_eval,
compiled_expression_eval,
compiled_expression_eval,
- delete_expression_eval,
+ compiled_expression_eval,
compiled_expression_eval,
typeof_expression_eval,
compiled_expression_eval,
diff --git a/dlls/jscript/tests/lang.js b/dlls/jscript/tests/lang.js
index c85907c..4f3d509 100644
--- a/dlls/jscript/tests/lang.js
+++ b/dlls/jscript/tests/lang.js
@@ -830,9 +830,16 @@ tmp = new Object();
tmp.test = false;
ok((delete tmp.test) === true, "delete returned false");
ok(typeof(tmp.test) === "undefined", "tmp.test type = " + typeof(tmp.test));
+ok(!("test" in tmp), "test is still in tmp after delete?");
for(iter in tmp)
ok(false, "tmp has prop " + iter);
+tmp = new Object();
+tmp.test = false;
+ok((delete tmp["test"]) === true, "delete returned false");
+ok(typeof(tmp.test) === "undefined", "tmp.test type = " + typeof(tmp.test));
+ok(!("test" in tmp), "test is still in tmp after delete?");
+
tmp.testWith = true;
with(tmp)
ok(testWith === true, "testWith !== true");
More information about the wine-cvs
mailing list