jscript: Always use jsval-based to_primitive.

This commit is contained in:
Jacek Caban 2012-09-17 15:17:50 +02:00 committed by Alexandre Julliard
parent daf0b8dad2
commit c1eb4326a0
5 changed files with 45 additions and 120 deletions

View File

@ -2505,23 +2505,19 @@ static HRESULT DateConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
/* ECMA-262 3rd Edition 15.9.3.2 */
case 1: {
VARIANT prim,var;
jsval_t prim;
double n;
hres = jsval_to_variant(argv[0], &var);
if(SUCCEEDED(hres)) {
hres = to_primitive(ctx, &var, ei, &prim, NO_HINT);
VariantClear(&var);
}
hres = to_primitive(ctx, argv[0], ei, &prim, NO_HINT);
if(FAILED(hres))
return hres;
if(V_VT(&prim) == VT_BSTR)
hres = date_parse(V_BSTR(&prim), &n);
if(is_string(prim))
hres = date_parse(get_string(prim), &n);
else
hres = to_number(ctx, &prim, ei, &n);
hres = to_number_jsval(ctx, prim, ei, &n);
VariantClear(&prim);
jsval_release(prim);
if(FAILED(hres))
return hres;

View File

@ -1013,29 +1013,16 @@ HRESULT jsdisp_call_value(jsdisp_t *jsfunc, IDispatch *jsthis, WORD flags, unsig
return hres;
}
HRESULT jsdisp_call(jsdisp_t *disp, DISPID id, WORD flags, unsigned argc, jsval_t *argv, VARIANT *retv, jsexcept_t *ei)
HRESULT jsdisp_call(jsdisp_t *disp, DISPID id, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r, jsexcept_t *ei)
{
dispex_prop_t *prop;
jsval_t r;
HRESULT hres;
memset(ei, 0, sizeof(*ei));
if(retv)
V_VT(retv) = VT_EMPTY;
prop = get_prop(disp, id);
if(!prop)
return DISP_E_MEMBERNOTFOUND;
hres = invoke_prop_func(disp, to_disp(disp), prop, flags, argc, argv, retv ? &r : NULL, ei, NULL);
if(FAILED(hres))
return hres;
if(retv) {
hres = jsval_to_variant(r, retv);
jsval_release(r);
}
return hres;
memset(ei, 0, sizeof(*ei));
return invoke_prop_func(disp, to_disp(disp), prop, flags, argc, argv, r, ei, NULL);
}
HRESULT jsdisp_call_name(jsdisp_t *disp, const WCHAR *name, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r,
@ -1069,16 +1056,8 @@ HRESULT disp_call(script_ctx_t *ctx, IDispatch *disp, DISPID id, WORD flags, uns
return E_FAIL;
}
V_VT(&retv) = VT_EMPTY;
hres = jsdisp_call(jsdisp, id, flags, argc, argv, ret ? &retv : NULL, ei);
hres = jsdisp_call(jsdisp, id, flags, argc, argv, ret, ei);
jsdisp_release(jsdisp);
if(FAILED(hres))
return hres;
if(ret) {
hres = variant_to_jsval(&retv, ret);
VariantClear(&retv);
}
return hres;
}

View File

@ -1406,11 +1406,11 @@ static HRESULT add_eval(script_ctx_t *ctx, jsval_t lval, jsval_t rval, jsexcept_
jsval_t r, l;
HRESULT hres;
hres = to_primitive_jsval(ctx, lval, ei, &l, NO_HINT);
hres = to_primitive(ctx, lval, ei, &l, NO_HINT);
if(FAILED(hres))
return hres;
hres = to_primitive_jsval(ctx, rval, ei, &r, NO_HINT);
hres = to_primitive(ctx, rval, ei, &r, NO_HINT);
if(FAILED(hres)) {
jsval_release(l);
return hres;
@ -1925,7 +1925,7 @@ static HRESULT equal_values(script_ctx_t *ctx, jsval_t lval, jsval_t rval, jsexc
jsval_t prim;
HRESULT hres;
hres = to_primitive_jsval(ctx, rval, ei, &prim, NO_HINT);
hres = to_primitive(ctx, rval, ei, &prim, NO_HINT);
if(FAILED(hres))
return hres;
@ -1939,7 +1939,7 @@ static HRESULT equal_values(script_ctx_t *ctx, jsval_t lval, jsval_t rval, jsexc
jsval_t prim;
HRESULT hres;
hres = to_primitive_jsval(ctx, lval, ei, &prim, NO_HINT);
hres = to_primitive(ctx, lval, ei, &prim, NO_HINT);
if(FAILED(hres))
return hres;
@ -2044,11 +2044,11 @@ static HRESULT less_eval(script_ctx_t *ctx, jsval_t lval, jsval_t rval, BOOL gre
jsval_t l, r;
HRESULT hres;
hres = to_primitive_jsval(ctx, lval, ei, &l, NO_HINT);
hres = to_primitive(ctx, lval, ei, &l, NO_HINT);
if(FAILED(hres))
return hres;
hres = to_primitive_jsval(ctx, rval, ei, &r, NO_HINT);
hres = to_primitive(ctx, rval, ei, &r, NO_HINT);
if(FAILED(hres)) {
jsval_release(l);
return hres;

View File

@ -207,7 +207,7 @@ HRESULT init_dispex_from_constr(jsdisp_t*,script_ctx_t*,const builtin_info_t*,js
HRESULT disp_call(script_ctx_t*,IDispatch*,DISPID,WORD,unsigned,jsval_t*,jsval_t*,jsexcept_t*) DECLSPEC_HIDDEN;
HRESULT disp_call_value(script_ctx_t*,IDispatch*,IDispatch*,WORD,unsigned,jsval_t*,jsval_t*,jsexcept_t*) DECLSPEC_HIDDEN;
HRESULT jsdisp_call_value(jsdisp_t*,IDispatch*,WORD,unsigned,jsval_t*,jsval_t*,jsexcept_t*) DECLSPEC_HIDDEN;
HRESULT jsdisp_call(jsdisp_t*,DISPID,WORD,unsigned,jsval_t*,VARIANT*,jsexcept_t*) DECLSPEC_HIDDEN;
HRESULT jsdisp_call(jsdisp_t*,DISPID,WORD,unsigned,jsval_t*,jsval_t*,jsexcept_t*) DECLSPEC_HIDDEN;
HRESULT jsdisp_call_name(jsdisp_t*,const WCHAR*,WORD,unsigned,jsval_t*,jsval_t*,jsexcept_t*) DECLSPEC_HIDDEN;
HRESULT disp_propget(script_ctx_t*,IDispatch*,DISPID,jsval_t*,jsexcept_t*) DECLSPEC_HIDDEN;
HRESULT disp_propput(script_ctx_t*,IDispatch*,DISPID,jsval_t,jsexcept_t*) DECLSPEC_HIDDEN;
@ -254,8 +254,7 @@ typedef enum {
HINT_NUMBER
} hint_t;
HRESULT to_primitive(script_ctx_t*,VARIANT*,jsexcept_t*,VARIANT*, hint_t) DECLSPEC_HIDDEN;
HRESULT to_primitive_jsval(script_ctx_t*,jsval_t,jsexcept_t*,jsval_t*, hint_t) DECLSPEC_HIDDEN;
HRESULT to_primitive(script_ctx_t*,jsval_t,jsexcept_t*,jsval_t*, hint_t) DECLSPEC_HIDDEN;
HRESULT to_boolean(VARIANT*,VARIANT_BOOL*) DECLSPEC_HIDDEN;
HRESULT to_boolean_jsval(jsval_t,BOOL*) DECLSPEC_HIDDEN;
HRESULT to_number(script_ctx_t*,VARIANT*,jsexcept_t*,double*) DECLSPEC_HIDDEN;

View File

@ -369,46 +369,25 @@ HRESULT jsval_to_variant(jsval_t val, VARIANT *retv)
}
/* ECMA-262 3rd Edition 9.1 */
HRESULT to_primitive(script_ctx_t *ctx, VARIANT *v, jsexcept_t *ei, VARIANT *ret, hint_t hint)
HRESULT to_primitive(script_ctx_t *ctx, jsval_t val, jsexcept_t *ei, jsval_t *ret, hint_t hint)
{
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: {
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(!V_DISPATCH(v)) {
V_VT(ret) = VT_NULL;
break;
if(!get_object(val)) {
*ret = jsval_null();
return S_OK;
}
jsdisp = iface_to_jsdisp((IUnknown*)V_DISPATCH(v));
if(!jsdisp) {
jsval_t val;
HRESULT hres;
hres = disp_propget(ctx, V_DISPATCH(v), DISPID_VALUE, &val, ei);
if(FAILED(hres))
return hres;
hres = jsval_to_variant(val, ret);
jsval_release(val);
return hres;
}
jsdisp = iface_to_jsdisp((IUnknown*)get_object(val));
if(!jsdisp)
return disp_propget(ctx, get_object(val), DISPID_VALUE, ret, ei);
if(hint == NO_HINT)
hint = is_class(jsdisp, JSCLASS_DATE) ? HINT_STRING : HINT_NUMBER;
@ -417,34 +396,34 @@ HRESULT to_primitive(script_ctx_t *ctx, VARIANT *v, jsexcept_t *ei, VARIANT *ret
hres = jsdisp_get_id(jsdisp, hint == HINT_STRING ? toStringW : valueOfW, 0, &id);
if(SUCCEEDED(hres)) {
hres = jsdisp_call(jsdisp, id, DISPATCH_METHOD, 0, NULL, ret, ei);
hres = jsdisp_call(jsdisp, id, DISPATCH_METHOD, 0, NULL, &prim, ei);
if(FAILED(hres)) {
WARN("call error - forwarding exception\n");
jsdisp_release(jsdisp);
return hres;
}
else if(V_VT(ret) != VT_DISPATCH) {
}else if(!is_object_instance(prim)) {
jsdisp_release(jsdisp);
*ret = prim;
return S_OK;
}else {
IDispatch_Release(get_object(prim));
}
else
IDispatch_Release(V_DISPATCH(ret));
}
hres = jsdisp_get_id(jsdisp, hint == HINT_STRING ? valueOfW : toStringW, 0, &id);
if(SUCCEEDED(hres)) {
hres = jsdisp_call(jsdisp, id, DISPATCH_METHOD, 0, NULL, ret, ei);
hres = jsdisp_call(jsdisp, id, DISPATCH_METHOD, 0, NULL, &prim, ei);
if(FAILED(hres)) {
WARN("call error - forwarding exception\n");
jsdisp_release(jsdisp);
return hres;
}
else if(V_VT(ret) != VT_DISPATCH) {
}else if(!is_object_instance(prim)) {
jsdisp_release(jsdisp);
*ret = prim;
return S_OK;
}else {
IDispatch_Release(get_object(prim));
}
else
IDispatch_Release(V_DISPATCH(ret));
}
jsdisp_release(jsdisp);
@ -452,34 +431,6 @@ HRESULT to_primitive(script_ctx_t *ctx, VARIANT *v, jsexcept_t *ei, VARIANT *ret
WARN("failed\n");
return throw_type_error(ctx, ei, JS_E_TO_PRIMITIVE, NULL);
}
case VT_I2:
case VT_INT:
assert(0);
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_jsval(script_ctx_t *ctx, jsval_t val, jsexcept_t *ei, jsval_t *ret, hint_t hint)
{
if(is_object_instance(val)) {
VARIANT var, retv;
HRESULT hres;
V_VT(&var) = VT_DISPATCH;
V_DISPATCH(&var) = get_object(val);
hres = to_primitive(ctx, &var, ei, &retv, hint);
if(FAILED(hres))
return hres;
hres = variant_to_jsval(&retv, ret);
VariantClear(&retv);
return hres;
}
return jsval_copy(val, ret);
@ -670,15 +621,15 @@ HRESULT to_number(script_ctx_t *ctx, VARIANT *v, jsexcept_t *ei, double *ret)
case VT_BSTR:
return str_to_number(V_BSTR(v), ret);
case VT_DISPATCH: {
VARIANT prim;
jsval_t prim;
HRESULT hres;
hres = to_primitive(ctx, v, ei, &prim, HINT_NUMBER);
hres = to_primitive(ctx, jsval_disp(V_DISPATCH(v)), ei, &prim, HINT_NUMBER);
if(FAILED(hres))
return hres;
hres = to_number(ctx, &prim, ei, ret);
VariantClear(&prim);
hres = to_number_jsval(ctx, prim, ei, ret);
jsval_release(prim);
return hres;
}
case VT_BOOL:
@ -879,15 +830,15 @@ HRESULT to_string(script_ctx_t *ctx, VARIANT *v, jsexcept_t *ei, BSTR *str)
*str = SysAllocString(V_BSTR(v));
break;
case VT_DISPATCH: {
VARIANT prim;
jsval_t prim;
HRESULT hres;
hres = to_primitive(ctx, v, ei, &prim, HINT_STRING);
hres = to_primitive(ctx, jsval_disp(V_DISPATCH(v)), ei, &prim, HINT_STRING);
if(FAILED(hres))
return hres;
hres = to_string(ctx, &prim, ei, str);
VariantClear(&prim);
hres = to_string_jsval(ctx, prim, ei, str);
jsval_release(prim);
return hres;
}
case VT_BOOL: