HRESULT disp_propget(IDispatch *disp, DISPID id, LCID lcid, VARIANT *val, jsexcept_t *ei, IServiceProvider *caller) { DISPPARAMS dp = {NULL,NULL,0,0}; IDispatchEx *dispex; DispatchEx *jsdisp; HRESULT hres; jsdisp = iface_to_jsdisp((IUnknown*)disp); if(jsdisp) { hres = jsdisp_propget(jsdisp, id, lcid, val, ei, caller); IDispatchEx_Release(_IDispatchEx_(jsdisp)); return hres; } hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex); if(FAILED(hres)) { ULONG err = 0; TRACE("using IDispatch\n"); return IDispatch_Invoke(disp, id, &IID_NULL, lcid, INVOKE_PROPERTYGET, &dp, val, &ei->ei, &err); } hres = IDispatchEx_InvokeEx(dispex, id, lcid, INVOKE_PROPERTYGET, &dp, val, &ei->ei, caller); IDispatchEx_Release(dispex); return hres; }
/* ECMA-262 3rd Edition 15.4.4.13 */ static HRESULT Array_unshift(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) { jsdisp_t *jsthis; WCHAR buf[14], *buf_end, *str; DWORD i, length; jsval_t val; DISPID id; HRESULT hres; TRACE("\n"); hres = get_length(ctx, vthis, &jsthis, &length); if(FAILED(hres)) return hres; if(argc) { buf_end = buf + sizeof(buf)/sizeof(WCHAR)-1; *buf_end-- = 0; i = length; while(i--) { str = idx_to_str(i, buf_end); hres = jsdisp_get_id(jsthis, str, 0, &id); if(SUCCEEDED(hres)) { hres = jsdisp_propget(jsthis, id, &val); if(FAILED(hres)) return hres; hres = jsdisp_propput_idx(jsthis, i+argc, val); jsval_release(val); }else if(hres == DISP_E_UNKNOWNNAME) { hres = IDispatchEx_DeleteMemberByDispID(vthis->u.dispex, id); } } if(FAILED(hres)) return hres; } for(i=0; i<argc; i++) { hres = jsdisp_propput_idx(jsthis, i, argv[i]); if(FAILED(hres)) return hres; } if(argc) { length += argc; hres = set_length(jsthis, length); if(FAILED(hres)) return hres; } if(r) *r = ctx->version < 2 ? jsval_undefined() : jsval_number(length); return S_OK; }
/* ECMA-262 5.1 Edition 15.12.3 (abstract operation JO) */ static HRESULT stringify_object(stringify_ctx_t *ctx, jsdisp_t *obj) { DISPID dispid = DISPID_STARTENUM; jsval_t val = jsval_undefined(); unsigned prop_cnt = 0, i; size_t stepback; BSTR prop_name; HRESULT hres; if(is_on_stack(ctx, obj)) { FIXME("Found a cycle\n"); return E_FAIL; } if(!stringify_push_obj(ctx, obj)) return E_OUTOFMEMORY; if(!append_char(ctx, '{')) return E_OUTOFMEMORY; while((hres = IDispatchEx_GetNextDispID(&obj->IDispatchEx_iface, fdexEnumDefault, dispid, &dispid)) == S_OK) { jsval_release(val); hres = jsdisp_propget(obj, dispid, &val); if(FAILED(hres)) return hres; if(is_undefined(val)) continue; stepback = ctx->buf_len; if(prop_cnt && !append_char(ctx, ',')) { hres = E_OUTOFMEMORY; break; } if(*ctx->gap) { if(!append_char(ctx, '\n')) { hres = E_OUTOFMEMORY; break; } for(i=0; i < ctx->stack_top; i++) { if(!append_string(ctx, ctx->gap)) { hres = E_OUTOFMEMORY; break; } } } hres = IDispatchEx_GetMemberName(&obj->IDispatchEx_iface, dispid, &prop_name); if(FAILED(hres)) break; hres = json_quote(ctx, prop_name, SysStringLen(prop_name)); SysFreeString(prop_name); if(FAILED(hres)) break; if(!append_char(ctx, ':') || (*ctx->gap && !append_char(ctx, ' '))) { hres = E_OUTOFMEMORY; break; } hres = stringify(ctx, val); if(FAILED(hres)) break; if(hres == S_FALSE) { ctx->buf_len = stepback; continue; } prop_cnt++; } jsval_release(val); if(FAILED(hres)) return hres; if(prop_cnt && *ctx->gap) { if(!append_char(ctx, '\n')) return E_OUTOFMEMORY; for(i=1; i < ctx->stack_top; i++) { if(!append_string(ctx, ctx->gap)) { hres = E_OUTOFMEMORY; break; } } } if(!append_char(ctx, '}')) return E_OUTOFMEMORY; stringify_pop_obj(ctx); return S_OK; }
/* ECMA-262 3rd Edition 15.4.4.13 */ static HRESULT Array_unshift(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei) { jsdisp_t *jsthis; WCHAR buf[14], *buf_end, *str; DWORD argc, i, length; VARIANT var; DISPID id; HRESULT hres; TRACE("\n"); hres = get_length(ctx, vthis, ei, &jsthis, &length); if(FAILED(hres)) return hres; argc = arg_cnt(dp); if(argc) { buf_end = buf + sizeof(buf)/sizeof(WCHAR)-1; *buf_end-- = 0; i = length; while(i--) { str = idx_to_str(i, buf_end); hres = jsdisp_get_id(jsthis, str, 0, &id); if(SUCCEEDED(hres)) { hres = jsdisp_propget(jsthis, id, &var, ei); if(FAILED(hres)) return hres; hres = jsdisp_propput_idx(jsthis, i+argc, &var, ei); VariantClear(&var); }else if(hres == DISP_E_UNKNOWNNAME) { hres = IDispatchEx_DeleteMemberByDispID(vthis->u.dispex, id); } } if(FAILED(hres)) return hres; } for(i=0; i<argc; i++) { hres = jsdisp_propput_idx(jsthis, i, get_arg(dp,i), ei); if(FAILED(hres)) return hres; } if(argc) { length += argc; hres = set_length(jsthis, ei, length); if(FAILED(hres)) return hres; } if(retv) { if(ctx->version < 2) { V_VT(retv) = VT_EMPTY; }else { V_VT(retv) = VT_I4; V_I4(retv) = length; } } return S_OK; }