mirror of
https://github.com/reactos/wine.git
synced 2024-11-29 06:30:37 +00:00
jscript: Changed to_primitive implementation.
This commit is contained in:
parent
3f18e98413
commit
b9be3bd766
@ -2634,7 +2634,7 @@ static HRESULT DateConstr_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPP
|
|||||||
case 1: {
|
case 1: {
|
||||||
VARIANT prim, num;
|
VARIANT prim, num;
|
||||||
|
|
||||||
hres = to_primitive(dispex->ctx, get_arg(dp,0), ei, &prim);
|
hres = to_primitive(dispex->ctx, get_arg(dp,0), ei, &prim, NO_HINT);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
|
@ -828,7 +828,7 @@ HRESULT jsdisp_call_value(DispatchEx *disp, LCID lcid, WORD flags, DISPPARAMS *d
|
|||||||
return disp->builtin_info->value_prop.invoke(disp, lcid, flags, dp, retv, ei, caller);
|
return disp->builtin_info->value_prop.invoke(disp, lcid, flags, dp, retv, ei, caller);
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT jsdisp_call(DispatchEx *disp, DISPID id, LCID lcid, WORD flags, DISPPARAMS *dp, VARIANT *retv,
|
HRESULT jsdisp_call(DispatchEx *disp, DISPID id, LCID lcid, WORD flags, DISPPARAMS *dp, VARIANT *retv,
|
||||||
jsexcept_t *ei, IServiceProvider *caller)
|
jsexcept_t *ei, IServiceProvider *caller)
|
||||||
{
|
{
|
||||||
dispex_prop_t *prop;
|
dispex_prop_t *prop;
|
||||||
|
@ -1931,11 +1931,11 @@ static HRESULT add_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexcept_
|
|||||||
VARIANT r, l;
|
VARIANT r, l;
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
|
||||||
hres = to_primitive(ctx->parser->script, lval, ei, &l);
|
hres = to_primitive(ctx->parser->script, lval, ei, &l, NO_HINT);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
hres = to_primitive(ctx->parser->script, rval, ei, &r);
|
hres = to_primitive(ctx->parser->script, rval, ei, &r, NO_HINT);
|
||||||
if(FAILED(hres)) {
|
if(FAILED(hres)) {
|
||||||
VariantClear(&l);
|
VariantClear(&l);
|
||||||
return hres;
|
return hres;
|
||||||
@ -2518,7 +2518,7 @@ static HRESULT equal_values(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexc
|
|||||||
VARIANT v;
|
VARIANT v;
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
|
||||||
hres = to_primitive(ctx->parser->script, rval, ei, &v);
|
hres = to_primitive(ctx->parser->script, rval, ei, &v, NO_HINT);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
@ -2533,7 +2533,7 @@ static HRESULT equal_values(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, jsexc
|
|||||||
VARIANT v;
|
VARIANT v;
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
|
||||||
hres = to_primitive(ctx->parser->script, lval, ei, &v);
|
hres = to_primitive(ctx->parser->script, lval, ei, &v, NO_HINT);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
@ -2638,11 +2638,11 @@ static HRESULT less_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *rval, BOOL gre
|
|||||||
VARIANT l, r, ln, rn;
|
VARIANT l, r, ln, rn;
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
|
||||||
hres = to_primitive(ctx->parser->script, lval, ei, &l);
|
hres = to_primitive(ctx->parser->script, lval, ei, &l, NO_HINT);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
hres = to_primitive(ctx->parser->script, rval, ei, &r);
|
hres = to_primitive(ctx->parser->script, rval, ei, &r, NO_HINT);
|
||||||
if(FAILED(hres)) {
|
if(FAILED(hres)) {
|
||||||
VariantClear(&l);
|
VariantClear(&l);
|
||||||
return hres;
|
return hres;
|
||||||
|
@ -123,6 +123,7 @@ DispatchEx *iface_to_jsdisp(IUnknown*);
|
|||||||
|
|
||||||
HRESULT disp_call(IDispatch*,DISPID,LCID,WORD,DISPPARAMS*,VARIANT*,jsexcept_t*,IServiceProvider*);
|
HRESULT disp_call(IDispatch*,DISPID,LCID,WORD,DISPPARAMS*,VARIANT*,jsexcept_t*,IServiceProvider*);
|
||||||
HRESULT jsdisp_call_value(DispatchEx*,LCID,WORD,DISPPARAMS*,VARIANT*,jsexcept_t*,IServiceProvider*);
|
HRESULT jsdisp_call_value(DispatchEx*,LCID,WORD,DISPPARAMS*,VARIANT*,jsexcept_t*,IServiceProvider*);
|
||||||
|
HRESULT jsdisp_call(DispatchEx*,DISPID,LCID,WORD,DISPPARAMS*,VARIANT*,jsexcept_t*,IServiceProvider*);
|
||||||
HRESULT disp_propget(IDispatch*,DISPID,LCID,VARIANT*,jsexcept_t*,IServiceProvider*);
|
HRESULT disp_propget(IDispatch*,DISPID,LCID,VARIANT*,jsexcept_t*,IServiceProvider*);
|
||||||
HRESULT disp_propput(IDispatch*,DISPID,LCID,VARIANT*,jsexcept_t*,IServiceProvider*);
|
HRESULT disp_propput(IDispatch*,DISPID,LCID,VARIANT*,jsexcept_t*,IServiceProvider*);
|
||||||
HRESULT jsdisp_propget(DispatchEx*,DISPID,LCID,VARIANT*,jsexcept_t*,IServiceProvider*);
|
HRESULT jsdisp_propget(DispatchEx*,DISPID,LCID,VARIANT*,jsexcept_t*,IServiceProvider*);
|
||||||
@ -145,7 +146,13 @@ HRESULT create_string(script_ctx_t*,const WCHAR*,DWORD,DispatchEx**);
|
|||||||
HRESULT create_bool(script_ctx_t*,VARIANT_BOOL,DispatchEx**);
|
HRESULT create_bool(script_ctx_t*,VARIANT_BOOL,DispatchEx**);
|
||||||
HRESULT create_number(script_ctx_t*,VARIANT*,DispatchEx**);
|
HRESULT create_number(script_ctx_t*,VARIANT*,DispatchEx**);
|
||||||
|
|
||||||
HRESULT to_primitive(script_ctx_t*,VARIANT*,jsexcept_t*,VARIANT*);
|
typedef enum {
|
||||||
|
NO_HINT,
|
||||||
|
HINT_STRING,
|
||||||
|
HINT_NUMBER
|
||||||
|
} hint_t;
|
||||||
|
|
||||||
|
HRESULT to_primitive(script_ctx_t*,VARIANT*,jsexcept_t*,VARIANT*, hint_t);
|
||||||
HRESULT to_boolean(VARIANT*,VARIANT_BOOL*);
|
HRESULT to_boolean(VARIANT*,VARIANT_BOOL*);
|
||||||
HRESULT to_number(script_ctx_t*,VARIANT*,jsexcept_t*,VARIANT*);
|
HRESULT to_number(script_ctx_t*,VARIANT*,jsexcept_t*,VARIANT*);
|
||||||
HRESULT to_integer(script_ctx_t*,VARIANT*,jsexcept_t*,VARIANT*);
|
HRESULT to_integer(script_ctx_t*,VARIANT*,jsexcept_t*,VARIANT*);
|
||||||
|
@ -175,7 +175,7 @@ jsheap_t *jsheap_mark(jsheap_t *heap)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ECMA-262 3rd Edition 9.1 */
|
/* ECMA-262 3rd Edition 9.1 */
|
||||||
HRESULT to_primitive(script_ctx_t *ctx, VARIANT *v, jsexcept_t *ei, VARIANT *ret)
|
HRESULT to_primitive(script_ctx_t *ctx, VARIANT *v, jsexcept_t *ei, VARIANT *ret, hint_t hint)
|
||||||
{
|
{
|
||||||
switch(V_VT(v)) {
|
switch(V_VT(v)) {
|
||||||
case VT_EMPTY:
|
case VT_EMPTY:
|
||||||
@ -189,8 +189,61 @@ HRESULT to_primitive(script_ctx_t *ctx, VARIANT *v, jsexcept_t *ei, VARIANT *ret
|
|||||||
V_VT(ret) = VT_BSTR;
|
V_VT(ret) = VT_BSTR;
|
||||||
V_BSTR(ret) = SysAllocString(V_BSTR(v));
|
V_BSTR(ret) = SysAllocString(V_BSTR(v));
|
||||||
break;
|
break;
|
||||||
case VT_DISPATCH:
|
case VT_DISPATCH: {
|
||||||
return disp_propget(V_DISPATCH(v), DISPID_VALUE, ctx->lcid, ret, ei, NULL /*FIXME*/);
|
DispatchEx *jsdisp;
|
||||||
|
DISPID id;
|
||||||
|
DISPPARAMS dp = {NULL, NULL, 0, 0};
|
||||||
|
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};
|
||||||
|
|
||||||
|
jsdisp = iface_to_jsdisp((IUnknown*)V_DISPATCH(v));
|
||||||
|
if(!jsdisp)
|
||||||
|
return disp_propget(V_DISPATCH(v), DISPID_VALUE, ctx->lcid, ret, ei, NULL /*FIXME*/);
|
||||||
|
|
||||||
|
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, ctx->lcid, DISPATCH_METHOD, &dp, ret, ei, NULL /*FIXME*/);
|
||||||
|
if(FAILED(hres)) {
|
||||||
|
FIXME("throw TypeError\n");
|
||||||
|
jsdisp_release(jsdisp);
|
||||||
|
return hres;
|
||||||
|
}
|
||||||
|
else if(V_VT(ret) != VT_DISPATCH) {
|
||||||
|
jsdisp_release(jsdisp);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
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, ctx->lcid, DISPATCH_METHOD, &dp, ret, ei, NULL /*FIXME*/);
|
||||||
|
if(FAILED(hres)) {
|
||||||
|
FIXME("throw TypeError\n");
|
||||||
|
jsdisp_release(jsdisp);
|
||||||
|
return hres;
|
||||||
|
}
|
||||||
|
else if(V_VT(ret) != VT_DISPATCH) {
|
||||||
|
jsdisp_release(jsdisp);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
IDispatch_Release(V_DISPATCH(ret));
|
||||||
|
}
|
||||||
|
|
||||||
|
jsdisp_release(jsdisp);
|
||||||
|
|
||||||
|
FIXME("throw TypeError\n");
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
FIXME("Unimplemented for vt %d\n", V_VT(v));
|
FIXME("Unimplemented for vt %d\n", V_VT(v));
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
@ -356,7 +409,7 @@ HRESULT to_number(script_ctx_t *ctx, VARIANT *v, jsexcept_t *ei, VARIANT *ret)
|
|||||||
VARIANT prim;
|
VARIANT prim;
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
|
||||||
hres = to_primitive(ctx, v, ei, &prim);
|
hres = to_primitive(ctx, v, ei, &prim, HINT_NUMBER);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
@ -489,7 +542,7 @@ HRESULT to_string(script_ctx_t *ctx, VARIANT *v, jsexcept_t *ei, BSTR *str)
|
|||||||
VARIANT prim;
|
VARIANT prim;
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
|
||||||
hres = to_primitive(ctx, v, ei, &prim);
|
hres = to_primitive(ctx, v, ei, &prim, HINT_STRING);
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
|
@ -1026,6 +1026,8 @@ date.setUTCMonth(22, 37);
|
|||||||
ok(date.getTime() === 60987050010, "date.getTime() = " + date.getTime());
|
ok(date.getTime() === 60987050010, "date.getTime() = " + date.getTime());
|
||||||
date.setUTCFullYear(83, 21, 321);
|
date.setUTCFullYear(83, 21, 321);
|
||||||
ok(date.getTime() === -59464984149990, "date.getTime() = " + date.getTime());
|
ok(date.getTime() === -59464984149990, "date.getTime() = " + date.getTime());
|
||||||
|
ok(Math.abs(date) === 59464984149990, "Math.abs(date) = " + Math.abs(date));
|
||||||
|
ok(getVT(date+1) === "VT_BSTR", "getVT(date+1) = " + getVT(date+1));
|
||||||
|
|
||||||
ok(isNaN(Date.parse()), "Date.parse() is not NaN");
|
ok(isNaN(Date.parse()), "Date.parse() is not NaN");
|
||||||
ok(isNaN(Date.parse("")), "Date.parse(\"\") is not NaN");
|
ok(isNaN(Date.parse("")), "Date.parse(\"\") is not NaN");
|
||||||
|
@ -882,4 +882,16 @@ function testEmbededFunctions() {
|
|||||||
|
|
||||||
testEmbededFunctions();
|
testEmbededFunctions();
|
||||||
|
|
||||||
|
date = new Date();
|
||||||
|
date.toString = function() { return "toString"; }
|
||||||
|
ok(""+date === "toString", "''+date = " + date);
|
||||||
|
date.toString = function() { return this; }
|
||||||
|
ok(""+date === ""+date.valueOf(), "''+date = " + date);
|
||||||
|
|
||||||
|
str = new String("test");
|
||||||
|
str.valueOf = function() { return "valueOf"; }
|
||||||
|
ok(""+str === "valueOf", "''+str = " + str);
|
||||||
|
str.valueOf = function() { return new Date(); }
|
||||||
|
ok(""+str === "test", "''+str = " + str);
|
||||||
|
|
||||||
reportSuccess();
|
reportSuccess();
|
||||||
|
Loading…
Reference in New Issue
Block a user