HRESULT disp_call(IDispatch *disp, DISPID id, LCID lcid, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller) { DispatchEx *jsdisp; IDispatchEx *dispex; HRESULT hres; jsdisp = iface_to_jsdisp((IUnknown*)disp); if(jsdisp) { hres = jsdisp_call(jsdisp, id, lcid, flags, dp, retv, ei, caller); IDispatchEx_Release(_IDispatchEx_(jsdisp)); return hres; } memset(ei, 0, sizeof(*ei)); if(retv) V_VT(retv) = VT_EMPTY; hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex); if(FAILED(hres)) { UINT err = 0; if(flags == DISPATCH_CONSTRUCT) { WARN("IDispatch cannot be constructor\n"); return DISP_E_MEMBERNOTFOUND; } TRACE("using IDispatch\n"); return IDispatch_Invoke(disp, id, &IID_NULL, lcid, flags, dp, retv, &ei->ei, &err); } hres = IDispatchEx_InvokeEx(dispex, id, lcid, flags, dp, retv, &ei->ei, caller); IDispatchEx_Release(dispex); return hres; }
/* ECMA-262 3rd Edition 9.1 */ HRESULT to_primitive(script_ctx_t *ctx, jsval_t val, jsval_t *ret, hint_t hint) { if(is_object_instance(val)) { jsdisp_t *jsdisp; jsval_t prim; DISPID id; HRESULT hres; static const WCHAR toStringW[] = {'t','o','S','t','r','i','n','g',0}; static const WCHAR valueOfW[] = {'v','a','l','u','e','O','f',0}; if(!get_object(val)) { *ret = jsval_null(); return S_OK; } jsdisp = iface_to_jsdisp((IUnknown*)get_object(val)); if(!jsdisp) return disp_propget(ctx, get_object(val), DISPID_VALUE, ret); if(hint == NO_HINT) hint = is_class(jsdisp, JSCLASS_DATE) ? HINT_STRING : HINT_NUMBER; /* Native implementation doesn't throw TypeErrors, returns strange values */ hres = jsdisp_get_id(jsdisp, hint == HINT_STRING ? toStringW : valueOfW, 0, &id); if(SUCCEEDED(hres)) { hres = jsdisp_call(jsdisp, id, DISPATCH_METHOD, 0, NULL, &prim); if(FAILED(hres)) { WARN("call error - forwarding exception\n"); jsdisp_release(jsdisp); return hres; }else if(!is_object_instance(prim)) { jsdisp_release(jsdisp); *ret = prim; return S_OK; }else { IDispatch_Release(get_object(prim)); } } hres = jsdisp_get_id(jsdisp, hint == HINT_STRING ? valueOfW : toStringW, 0, &id); if(SUCCEEDED(hres)) { hres = jsdisp_call(jsdisp, id, DISPATCH_METHOD, 0, NULL, &prim); if(FAILED(hres)) { WARN("call error - forwarding exception\n"); jsdisp_release(jsdisp); return hres; }else if(!is_object_instance(prim)) { jsdisp_release(jsdisp); *ret = prim; return S_OK; }else { IDispatch_Release(get_object(prim)); } } jsdisp_release(jsdisp); WARN("failed\n"); return throw_type_error(ctx, JS_E_TO_PRIMITIVE, NULL); } return jsval_copy(val, ret); }