/* ECMA-262 3rd Edition 9.1 */ HRESULT to_primitive(script_ctx_t *ctx, VARIANT *v, jsexcept_t *ei, VARIANT *ret) { switch(V_VT(v)) { case VT_EMPTY: case VT_NULL: case VT_BOOL: case VT_I4: case VT_R8: *ret = *v; break; case VT_BSTR: V_VT(ret) = VT_BSTR; V_BSTR(ret) = SysAllocString(V_BSTR(v)); break; case VT_DISPATCH: return disp_propget(V_DISPATCH(v), DISPID_VALUE, ctx->lcid, ret, ei, NULL /*FIXME*/); default: FIXME("Unimplemented for vt %d\n", V_VT(v)); return E_NOTIMPL; } return S_OK; }
/* 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); }