jscript: Added for..in statement implementation.
This commit is contained in:
parent
4731f17435
commit
8e16240467
|
@ -381,6 +381,8 @@ static HRESULT fill_protrefs(DispatchEx *This)
|
||||||
fill_protrefs(This->prototype);
|
fill_protrefs(This->prototype);
|
||||||
|
|
||||||
for(iter = This->prototype->props; iter < This->prototype->props+This->prototype->prop_cnt; iter++) {
|
for(iter = This->prototype->props; iter < This->prototype->props+This->prototype->prop_cnt; iter++) {
|
||||||
|
if(!iter->name)
|
||||||
|
continue;
|
||||||
hres = find_prop_name(This, iter->name, &prop);
|
hres = find_prop_name(This, iter->name, &prop);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
|
@ -764,10 +764,102 @@ HRESULT for_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *r
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT forin_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
|
/* ECMA-262 3rd Edition 12.6.4 */
|
||||||
|
HRESULT forin_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
|
||||||
{
|
{
|
||||||
FIXME("\n");
|
forin_statement_t *stat = (forin_statement_t*)_stat;
|
||||||
return E_NOTIMPL;
|
VARIANT val, name, retv, tmp;
|
||||||
|
DISPID id = DISPID_STARTENUM;
|
||||||
|
BSTR str, identifier = NULL;
|
||||||
|
IDispatchEx *in_obj;
|
||||||
|
exprval_t exprval;
|
||||||
|
HRESULT hres;
|
||||||
|
|
||||||
|
TRACE("\n");
|
||||||
|
|
||||||
|
if(stat->variable) {
|
||||||
|
hres = variable_list_eval(ctx, stat->variable, &rt->ei);
|
||||||
|
if(FAILED(hres))
|
||||||
|
return hres;
|
||||||
|
}
|
||||||
|
|
||||||
|
hres = expr_eval(ctx, stat->in_expr, EXPR_NEWREF, &rt->ei, &exprval);
|
||||||
|
if(FAILED(hres))
|
||||||
|
return hres;
|
||||||
|
|
||||||
|
hres = exprval_to_value(ctx->parser->script, &exprval, &rt->ei, &val);
|
||||||
|
exprval_release(&exprval);
|
||||||
|
if(FAILED(hres))
|
||||||
|
return hres;
|
||||||
|
|
||||||
|
if(V_VT(&val) != VT_DISPATCH) {
|
||||||
|
FIXME("in vt %d\n", V_VT(&val));
|
||||||
|
VariantClear(&val);
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
hres = IDispatch_QueryInterface(V_DISPATCH(&val), &IID_IDispatchEx, (void**)&in_obj);
|
||||||
|
IDispatch_Release(V_DISPATCH(&val));
|
||||||
|
if(FAILED(hres)) {
|
||||||
|
FIXME("Object doesn't support IDispatchEx\n");
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
V_VT(&retv) = VT_EMPTY;
|
||||||
|
|
||||||
|
if(stat->variable)
|
||||||
|
identifier = SysAllocString(stat->variable->identifier);
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
hres = IDispatchEx_GetNextDispID(in_obj, fdexEnumDefault, id, &id);
|
||||||
|
if(FAILED(hres) || hres == S_FALSE)
|
||||||
|
break;
|
||||||
|
|
||||||
|
hres = IDispatchEx_GetMemberName(in_obj, id, &str);
|
||||||
|
if(FAILED(hres))
|
||||||
|
break;
|
||||||
|
|
||||||
|
TRACE("iter %s\n", debugstr_w(str));
|
||||||
|
|
||||||
|
if(stat->variable)
|
||||||
|
hres = identifier_eval(ctx, identifier, 0, &exprval);
|
||||||
|
else
|
||||||
|
hres = expr_eval(ctx, stat->expr, EXPR_NEWREF, &rt->ei, &exprval);
|
||||||
|
if(SUCCEEDED(hres)) {
|
||||||
|
V_VT(&name) = VT_BSTR;
|
||||||
|
V_BSTR(&name) = str;
|
||||||
|
hres = put_value(ctx->parser->script, &exprval, &name, &rt->ei);
|
||||||
|
exprval_release(&exprval);
|
||||||
|
}
|
||||||
|
SysFreeString(str);
|
||||||
|
if(FAILED(hres))
|
||||||
|
break;
|
||||||
|
|
||||||
|
hres = stat_eval(ctx, stat->statement, rt, &tmp);
|
||||||
|
if(FAILED(hres))
|
||||||
|
break;
|
||||||
|
|
||||||
|
VariantClear(&retv);
|
||||||
|
retv = tmp;
|
||||||
|
|
||||||
|
if(rt->type == RT_CONTINUE)
|
||||||
|
rt->type = RT_NORMAL;
|
||||||
|
else if(rt->type != RT_NORMAL)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
SysFreeString(identifier);
|
||||||
|
IDispatchEx_Release(in_obj);
|
||||||
|
if(FAILED(hres)) {
|
||||||
|
VariantClear(&retv);
|
||||||
|
return hres;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(rt->type == RT_BREAK)
|
||||||
|
rt->type = RT_NORMAL;
|
||||||
|
|
||||||
|
*ret = retv;
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ECMA-262 3rd Edition 12.7 */
|
/* ECMA-262 3rd Edition 12.7 */
|
||||||
|
|
|
@ -617,4 +617,37 @@ ok(fi === 4, "fi !== 4");
|
||||||
|
|
||||||
ok((void 1) === undefined, "(void 1) !== undefined");
|
ok((void 1) === undefined, "(void 1) !== undefined");
|
||||||
|
|
||||||
|
var inobj = new Object();
|
||||||
|
|
||||||
|
for(var iter in inobj)
|
||||||
|
ok(false, "unexpected iter = " + iter);
|
||||||
|
|
||||||
|
inobj.test = true;
|
||||||
|
tmp = 0;
|
||||||
|
for(iter in inobj) {
|
||||||
|
ok(iter == "test", "unexpected iter = " + iter);
|
||||||
|
tmp++;
|
||||||
|
}
|
||||||
|
ok(tmp === 1, "for..in tmp = " + tmp);
|
||||||
|
|
||||||
|
function forinTestObj() {}
|
||||||
|
|
||||||
|
forinTestObj.prototype.test3 = true;
|
||||||
|
|
||||||
|
var arr = new Array();
|
||||||
|
inobj = new forinTestObj();
|
||||||
|
inobj.test1 = true;
|
||||||
|
inobj.test2 = true;
|
||||||
|
|
||||||
|
tmp = 0;
|
||||||
|
for(iter in inobj) {
|
||||||
|
arr[iter] = true;
|
||||||
|
tmp++;
|
||||||
|
}
|
||||||
|
|
||||||
|
ok(tmp === 3, "for..in tmp = " + tmp);
|
||||||
|
ok(arr["test1"] === true, "arr[test1] !== true");
|
||||||
|
ok(arr["test2"] === true, "arr[test2] !== true");
|
||||||
|
ok(arr["test3"] === true, "arr[test3] !== true");
|
||||||
|
|
||||||
reportSuccess();
|
reportSuccess();
|
||||||
|
|
Loading…
Reference in New Issue