jscript: Use bytecode for delete on array expression implementation.
This commit is contained in:
parent
6c47177cb1
commit
facc2189d2
|
@ -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:
|
||||
|
|
|
@ -2497,6 +2497,53 @@ HRESULT delete_expression_eval(script_ctx_t *ctx, expression_t *_expr, DWORD fla
|
|||
return return_bool(ret, b);
|
||||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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) \
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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");
|
||||
|
|
Loading…
Reference in New Issue