Commit 16b2b019 authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

jscript: Use jsval_t instead of VARIANT for stack values.

parent 847aebdc
...@@ -971,19 +971,6 @@ jsdisp_t *iface_to_jsdisp(IUnknown *iface) ...@@ -971,19 +971,6 @@ jsdisp_t *iface_to_jsdisp(IUnknown *iface)
return ret; return ret;
} }
static void ensure_retval_type(VARIANT *v)
{
switch(V_VT(v)) {
case VT_I2:
V_VT(v) = VT_I4;
V_I4(v) = V_I2(v);
break;
case VT_INT:
V_VT(v) = VT_I4;
V_I4(v) = V_INT(v);
}
}
HRESULT jsdisp_get_id(jsdisp_t *jsdisp, const WCHAR *name, DWORD flags, DISPID *id) HRESULT jsdisp_get_id(jsdisp_t *jsdisp, const WCHAR *name, DWORD flags, DISPID *id)
{ {
dispex_prop_t *prop; dispex_prop_t *prop;
...@@ -1062,11 +1049,11 @@ HRESULT jsdisp_call_name(jsdisp_t *disp, const WCHAR *name, WORD flags, unsigned ...@@ -1062,11 +1049,11 @@ HRESULT jsdisp_call_name(jsdisp_t *disp, const WCHAR *name, WORD flags, unsigned
} }
HRESULT disp_call(script_ctx_t *ctx, IDispatch *disp, DISPID id, WORD flags, unsigned argc, jsval_t *argv, HRESULT disp_call(script_ctx_t *ctx, IDispatch *disp, DISPID id, WORD flags, unsigned argc, jsval_t *argv,
VARIANT *retv, jsexcept_t *ei) jsval_t *ret, jsexcept_t *ei)
{ {
IDispatchEx *dispex; IDispatchEx *dispex;
jsdisp_t *jsdisp; jsdisp_t *jsdisp;
VARIANT buf[6]; VARIANT buf[6], retv;
DISPPARAMS dp; DISPPARAMS dp;
unsigned i; unsigned i;
HRESULT hres; HRESULT hres;
...@@ -1078,13 +1065,21 @@ HRESULT disp_call(script_ctx_t *ctx, IDispatch *disp, DISPID id, WORD flags, uns ...@@ -1078,13 +1065,21 @@ HRESULT disp_call(script_ctx_t *ctx, IDispatch *disp, DISPID id, WORD flags, uns
return E_FAIL; return E_FAIL;
} }
hres = jsdisp_call(jsdisp, id, flags, argc, argv, retv, ei); V_VT(&retv) = VT_EMPTY;
hres = jsdisp_call(jsdisp, id, flags, argc, argv, ret ? &retv : NULL, ei);
jsdisp_release(jsdisp); jsdisp_release(jsdisp);
if(FAILED(hres))
return hres;
if(ret) {
hres = variant_to_jsval(&retv, ret);
VariantClear(&retv);
}
return hres; return hres;
} }
memset(ei, 0, sizeof(*ei)); memset(ei, 0, sizeof(*ei));
if(retv && argc) if(ret && argc)
flags |= DISPATCH_PROPERTYGET; flags |= DISPATCH_PROPERTYGET;
dp.cArgs = argc; dp.cArgs = argc;
...@@ -1118,12 +1113,11 @@ HRESULT disp_call(script_ctx_t *ctx, IDispatch *disp, DISPID id, WORD flags, uns ...@@ -1118,12 +1113,11 @@ HRESULT disp_call(script_ctx_t *ctx, IDispatch *disp, DISPID id, WORD flags, uns
} }
} }
if(retv) V_VT(&retv) = VT_EMPTY;
V_VT(retv) = VT_EMPTY;
hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex); hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
if(SUCCEEDED(hres)) { if(SUCCEEDED(hres)) {
hres = IDispatchEx_InvokeEx(dispex, id, ctx->lcid, flags, &dp, retv, &ei->ei, &ctx->jscaller->IServiceProvider_iface); hres = IDispatchEx_InvokeEx(dispex, id, ctx->lcid, flags, &dp, ret ? &retv : NULL, &ei->ei,
&ctx->jscaller->IServiceProvider_iface);
IDispatchEx_Release(dispex); IDispatchEx_Release(dispex);
}else { }else {
UINT err = 0; UINT err = 0;
...@@ -1134,7 +1128,7 @@ HRESULT disp_call(script_ctx_t *ctx, IDispatch *disp, DISPID id, WORD flags, uns ...@@ -1134,7 +1128,7 @@ HRESULT disp_call(script_ctx_t *ctx, IDispatch *disp, DISPID id, WORD flags, uns
} }
TRACE("using IDispatch\n"); TRACE("using IDispatch\n");
hres = IDispatch_Invoke(disp, id, &IID_NULL, ctx->lcid, flags, &dp, retv, &ei->ei, &err); hres = IDispatch_Invoke(disp, id, &IID_NULL, ctx->lcid, flags, &dp, ret ? &retv : NULL, &ei->ei, &err);
} }
for(i=0; i<argc; i++) for(i=0; i<argc; i++)
...@@ -1144,9 +1138,11 @@ HRESULT disp_call(script_ctx_t *ctx, IDispatch *disp, DISPID id, WORD flags, uns ...@@ -1144,9 +1138,11 @@ HRESULT disp_call(script_ctx_t *ctx, IDispatch *disp, DISPID id, WORD flags, uns
if(FAILED(hres)) if(FAILED(hres))
return hres; return hres;
if(retv) if(ret) {
ensure_retval_type(retv); hres = variant_to_jsval(&retv, ret);
return S_OK; VariantClear(&retv);
}
return hres;
} }
HRESULT disp_call_value(script_ctx_t *ctx, IDispatch *disp, IDispatch *jsthis, WORD flags, unsigned argc, jsval_t *argv, HRESULT disp_call_value(script_ctx_t *ctx, IDispatch *disp, IDispatch *jsthis, WORD flags, unsigned argc, jsval_t *argv,
...@@ -1290,7 +1286,7 @@ HRESULT jsdisp_propput_idx(jsdisp_t *obj, DWORD idx, jsval_t val, jsexcept_t *ei ...@@ -1290,7 +1286,7 @@ HRESULT jsdisp_propput_idx(jsdisp_t *obj, DWORD idx, jsval_t val, jsexcept_t *ei
return jsdisp_propput_name(obj, buf, val, ei); return jsdisp_propput_name(obj, buf, val, ei);
} }
HRESULT disp_propput(script_ctx_t *ctx, IDispatch *disp, DISPID id, VARIANT *var, jsexcept_t *ei) HRESULT disp_propput(script_ctx_t *ctx, IDispatch *disp, DISPID id, jsval_t val, jsexcept_t *ei)
{ {
jsdisp_t *jsdisp; jsdisp_t *jsdisp;
HRESULT hres; HRESULT hres;
...@@ -1298,11 +1294,6 @@ HRESULT disp_propput(script_ctx_t *ctx, IDispatch *disp, DISPID id, VARIANT *var ...@@ -1298,11 +1294,6 @@ HRESULT disp_propput(script_ctx_t *ctx, IDispatch *disp, DISPID id, VARIANT *var
jsdisp = iface_to_jsdisp((IUnknown*)disp); jsdisp = iface_to_jsdisp((IUnknown*)disp);
if(jsdisp) { if(jsdisp) {
dispex_prop_t *prop; dispex_prop_t *prop;
jsval_t val;
hres = variant_to_jsval(var, &val);
if(FAILED(hres))
return hres;
prop = get_prop(jsdisp, id); prop = get_prop(jsdisp, id);
if(prop) if(prop)
...@@ -1310,13 +1301,17 @@ HRESULT disp_propput(script_ctx_t *ctx, IDispatch *disp, DISPID id, VARIANT *var ...@@ -1310,13 +1301,17 @@ HRESULT disp_propput(script_ctx_t *ctx, IDispatch *disp, DISPID id, VARIANT *var
else else
hres = DISP_E_MEMBERNOTFOUND; hres = DISP_E_MEMBERNOTFOUND;
jsval_release(val);
jsdisp_release(jsdisp); jsdisp_release(jsdisp);
}else { }else {
DISPID dispid = DISPID_PROPERTYPUT; DISPID dispid = DISPID_PROPERTYPUT;
DISPPARAMS dp = {var, &dispid, 1, 1}; VARIANT var;
DISPPARAMS dp = {&var, &dispid, 1, 1};
IDispatchEx *dispex; IDispatchEx *dispex;
hres = jsval_to_variant(val, &var);
if(FAILED(hres))
return hres;
hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex); hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
if(SUCCEEDED(hres)) { if(SUCCEEDED(hres)) {
hres = IDispatchEx_InvokeEx(dispex, id, ctx->lcid, DISPATCH_PROPERTYPUT, &dp, NULL, &ei->ei, hres = IDispatchEx_InvokeEx(dispex, id, ctx->lcid, DISPATCH_PROPERTYPUT, &dp, NULL, &ei->ei,
...@@ -1328,6 +1323,8 @@ HRESULT disp_propput(script_ctx_t *ctx, IDispatch *disp, DISPID id, VARIANT *var ...@@ -1328,6 +1323,8 @@ HRESULT disp_propput(script_ctx_t *ctx, IDispatch *disp, DISPID id, VARIANT *var
TRACE("using IDispatch\n"); TRACE("using IDispatch\n");
hres = IDispatch_Invoke(disp, id, &IID_NULL, ctx->lcid, DISPATCH_PROPERTYPUT, &dp, NULL, &ei->ei, &err); hres = IDispatch_Invoke(disp, id, &IID_NULL, ctx->lcid, DISPATCH_PROPERTYPUT, &dp, NULL, &ei->ei, &err);
} }
VariantClear(&var);
} }
return hres; return hres;
...@@ -1386,41 +1383,37 @@ HRESULT jsdisp_propget(jsdisp_t *jsdisp, DISPID id, jsval_t *val, jsexcept_t *ei ...@@ -1386,41 +1383,37 @@ HRESULT jsdisp_propget(jsdisp_t *jsdisp, DISPID id, jsval_t *val, jsexcept_t *ei
return prop_get(jsdisp, prop, &dp, val, ei, NULL); return prop_get(jsdisp, prop, &dp, val, ei, NULL);
} }
HRESULT disp_propget(script_ctx_t *ctx, IDispatch *disp, DISPID id, VARIANT *val, jsexcept_t *ei) HRESULT disp_propget(script_ctx_t *ctx, IDispatch *disp, DISPID id, jsval_t *val, jsexcept_t *ei)
{ {
DISPPARAMS dp = {NULL,NULL,0,0}; DISPPARAMS dp = {NULL,NULL,0,0};
IDispatchEx *dispex; IDispatchEx *dispex;
jsdisp_t *jsdisp; jsdisp_t *jsdisp;
VARIANT var;
HRESULT hres; HRESULT hres;
jsdisp = iface_to_jsdisp((IUnknown*)disp); jsdisp = iface_to_jsdisp((IUnknown*)disp);
if(jsdisp) { if(jsdisp) {
jsval_t v; hres = jsdisp_propget(jsdisp, id, val, ei);
hres = jsdisp_propget(jsdisp, id, &v, ei);
jsdisp_release(jsdisp); jsdisp_release(jsdisp);
if(SUCCEEDED(hres)) {
hres = jsval_to_variant(v, val);
jsval_release(v);
}
return hres; return hres;
} }
V_VT(&var) = VT_EMPTY;
hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex); hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
if(SUCCEEDED(hres)) { if(SUCCEEDED(hres)) {
hres = IDispatchEx_InvokeEx(dispex, id, ctx->lcid, INVOKE_PROPERTYGET, &dp, val, &ei->ei, hres = IDispatchEx_InvokeEx(dispex, id, ctx->lcid, INVOKE_PROPERTYGET, &dp, &var, &ei->ei,
&ctx->jscaller->IServiceProvider_iface); &ctx->jscaller->IServiceProvider_iface);
IDispatchEx_Release(dispex); IDispatchEx_Release(dispex);
}else { }else {
ULONG err = 0; ULONG err = 0;
TRACE("using IDispatch\n"); TRACE("using IDispatch\n");
hres = IDispatch_Invoke(disp, id, &IID_NULL, ctx->lcid, INVOKE_PROPERTYGET, &dp, val, &ei->ei, &err); hres = IDispatch_Invoke(disp, id, &IID_NULL, ctx->lcid, INVOKE_PROPERTYGET, &dp, &var, &ei->ei, &err);
} }
if(FAILED(hres)) if(FAILED(hres))
return hres; return hres;
ensure_retval_type(val); return variant_to_jsval(&var, val);
return S_OK;
} }
HRESULT jsdisp_delete_idx(jsdisp_t *obj, DWORD idx) HRESULT jsdisp_delete_idx(jsdisp_t *obj, DWORD idx)
......
...@@ -230,7 +230,7 @@ struct _exec_ctx_t { ...@@ -230,7 +230,7 @@ struct _exec_ctx_t {
function_code_t *func_code; function_code_t *func_code;
BOOL is_global; BOOL is_global;
VARIANT *stack; jsval_t *stack;
unsigned stack_size; unsigned stack_size;
unsigned top; unsigned top;
except_frame_t *except_frame; except_frame_t *except_frame;
...@@ -246,7 +246,7 @@ static inline void exec_addref(exec_ctx_t *ctx) ...@@ -246,7 +246,7 @@ static inline void exec_addref(exec_ctx_t *ctx)
void exec_release(exec_ctx_t*) DECLSPEC_HIDDEN; void exec_release(exec_ctx_t*) DECLSPEC_HIDDEN;
HRESULT create_exec_ctx(script_ctx_t*,IDispatch*,jsdisp_t*,scope_chain_t*,BOOL,exec_ctx_t**) DECLSPEC_HIDDEN; HRESULT create_exec_ctx(script_ctx_t*,IDispatch*,jsdisp_t*,scope_chain_t*,BOOL,exec_ctx_t**) DECLSPEC_HIDDEN;
HRESULT exec_source(exec_ctx_t*,bytecode_t*,function_code_t*,BOOL,jsexcept_t*,VARIANT*) DECLSPEC_HIDDEN; HRESULT exec_source(exec_ctx_t*,bytecode_t*,function_code_t*,BOOL,jsexcept_t*,jsval_t*) DECLSPEC_HIDDEN;
HRESULT create_source_function(script_ctx_t*,bytecode_t*,function_code_t*,scope_chain_t*,jsdisp_t**) DECLSPEC_HIDDEN; HRESULT create_source_function(script_ctx_t*,bytecode_t*,function_code_t*,scope_chain_t*,jsdisp_t**) DECLSPEC_HIDDEN;
typedef enum { typedef enum {
...@@ -396,12 +396,12 @@ typedef struct { ...@@ -396,12 +396,12 @@ typedef struct {
typedef struct { typedef struct {
enum { enum {
EXPRVAL_VARIANT, EXPRVAL_JSVAL,
EXPRVAL_IDREF, EXPRVAL_IDREF,
EXPRVAL_INVALID EXPRVAL_INVALID
} type; } type;
union { union {
VARIANT var; jsval_t val;
struct { struct {
IDispatch *disp; IDispatch *disp;
DISPID id; DISPID id;
......
...@@ -180,16 +180,11 @@ static HRESULT invoke_source(script_ctx_t *ctx, FunctionInstance *function, IDis ...@@ -180,16 +180,11 @@ static HRESULT invoke_source(script_ctx_t *ctx, FunctionInstance *function, IDis
jsdisp_release(var_disp); jsdisp_release(var_disp);
if(SUCCEEDED(hres)) { if(SUCCEEDED(hres)) {
jsdisp_t *prev_args; jsdisp_t *prev_args;
VARIANT retv;
prev_args = function->arguments; prev_args = function->arguments;
function->arguments = arg_disp; function->arguments = arg_disp;
hres = exec_source(exec_ctx, function->code, function->func_code, FALSE, ei, r ? &retv : NULL); hres = exec_source(exec_ctx, function->code, function->func_code, FALSE, ei, r);
function->arguments = prev_args; function->arguments = prev_args;
if(SUCCEEDED(hres) && r) {
hres = variant_to_jsval(&retv, r);
VariantClear(&retv);
}
} }
jsdisp_release(arg_disp); jsdisp_release(arg_disp);
......
...@@ -349,7 +349,6 @@ static HRESULT JSGlobal_eval(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, uns ...@@ -349,7 +349,6 @@ static HRESULT JSGlobal_eval(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, uns
jsval_t *r, jsexcept_t *ei) jsval_t *r, jsexcept_t *ei)
{ {
bytecode_t *code; bytecode_t *code;
VARIANT retv;
HRESULT hres; HRESULT hres;
TRACE("\n"); TRACE("\n");
...@@ -378,15 +377,8 @@ static HRESULT JSGlobal_eval(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, uns ...@@ -378,15 +377,8 @@ static HRESULT JSGlobal_eval(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, uns
return throw_syntax_error(ctx, ei, hres, NULL); return throw_syntax_error(ctx, ei, hres, NULL);
} }
hres = exec_source(ctx->exec_ctx, code, &code->global_code, TRUE, ei, r ? &retv : NULL); hres = exec_source(ctx->exec_ctx, code, &code->global_code, TRUE, ei, r);
release_bytecode(code); release_bytecode(code);
if(FAILED(hres))
return hres;
if(r) {
hres = variant_to_jsval(&retv, r);
VariantClear(&retv);
}
return hres; return hres;
} }
......
...@@ -208,13 +208,13 @@ HRESULT create_dispex(script_ctx_t*,const builtin_info_t*,jsdisp_t*,jsdisp_t**) ...@@ -208,13 +208,13 @@ HRESULT create_dispex(script_ctx_t*,const builtin_info_t*,jsdisp_t*,jsdisp_t**)
HRESULT init_dispex(jsdisp_t*,script_ctx_t*,const builtin_info_t*,jsdisp_t*) DECLSPEC_HIDDEN; HRESULT init_dispex(jsdisp_t*,script_ctx_t*,const builtin_info_t*,jsdisp_t*) DECLSPEC_HIDDEN;
HRESULT init_dispex_from_constr(jsdisp_t*,script_ctx_t*,const builtin_info_t*,jsdisp_t*) DECLSPEC_HIDDEN; HRESULT init_dispex_from_constr(jsdisp_t*,script_ctx_t*,const builtin_info_t*,jsdisp_t*) DECLSPEC_HIDDEN;
HRESULT disp_call(script_ctx_t*,IDispatch*,DISPID,WORD,unsigned,jsval_t*,VARIANT*,jsexcept_t*) DECLSPEC_HIDDEN; 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 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_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*,VARIANT*,jsexcept_t*) DECLSPEC_HIDDEN;
HRESULT jsdisp_call_name(jsdisp_t*,const WCHAR*,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,VARIANT*,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,VARIANT*,jsexcept_t*) DECLSPEC_HIDDEN; HRESULT disp_propput(script_ctx_t*,IDispatch*,DISPID,jsval_t,jsexcept_t*) DECLSPEC_HIDDEN;
HRESULT jsdisp_propget(jsdisp_t*,DISPID,jsval_t*,jsexcept_t*) DECLSPEC_HIDDEN; HRESULT jsdisp_propget(jsdisp_t*,DISPID,jsval_t*,jsexcept_t*) DECLSPEC_HIDDEN;
HRESULT jsdisp_propput_name(jsdisp_t*,const WCHAR*,jsval_t,jsexcept_t*) DECLSPEC_HIDDEN; HRESULT jsdisp_propput_name(jsdisp_t*,const WCHAR*,jsval_t,jsexcept_t*) DECLSPEC_HIDDEN;
HRESULT jsdisp_propput_const(jsdisp_t*,const WCHAR*,VARIANT*) DECLSPEC_HIDDEN; HRESULT jsdisp_propput_const(jsdisp_t*,const WCHAR*,VARIANT*) DECLSPEC_HIDDEN;
...@@ -259,6 +259,7 @@ typedef enum { ...@@ -259,6 +259,7 @@ typedef enum {
} hint_t; } hint_t;
HRESULT to_primitive(script_ctx_t*,VARIANT*,jsexcept_t*,VARIANT*, hint_t) DECLSPEC_HIDDEN; 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_boolean(VARIANT*,VARIANT_BOOL*) DECLSPEC_HIDDEN; HRESULT to_boolean(VARIANT*,VARIANT_BOOL*) DECLSPEC_HIDDEN;
HRESULT to_boolean_jsval(jsval_t,BOOL*) DECLSPEC_HIDDEN; HRESULT to_boolean_jsval(jsval_t,BOOL*) DECLSPEC_HIDDEN;
HRESULT to_number(script_ctx_t*,VARIANT*,jsexcept_t*,double*) DECLSPEC_HIDDEN; HRESULT to_number(script_ctx_t*,VARIANT*,jsexcept_t*,double*) DECLSPEC_HIDDEN;
......
...@@ -52,6 +52,8 @@ const char *debugstr_variant(const VARIANT *v) ...@@ -52,6 +52,8 @@ const char *debugstr_variant(const VARIANT *v)
return wine_dbg_sprintf("{VT_DISPATCH: %p}", V_DISPATCH(v)); return wine_dbg_sprintf("{VT_DISPATCH: %p}", V_DISPATCH(v));
case VT_BOOL: case VT_BOOL:
return wine_dbg_sprintf("{VT_BOOL: %x}", V_BOOL(v)); return wine_dbg_sprintf("{VT_BOOL: %x}", V_BOOL(v));
case VT_ARRAY|VT_VARIANT:
return "{VT_ARRAY|VT_VARIANT: ...}";
default: default:
return wine_dbg_sprintf("{vt %d}", V_VT(v)); return wine_dbg_sprintf("{vt %d}", V_VT(v));
} }
...@@ -241,7 +243,7 @@ HRESULT jsval_variant(jsval_t *val, VARIANT *var) ...@@ -241,7 +243,7 @@ HRESULT jsval_variant(jsval_t *val, VARIANT *var)
if(!val->u.v) if(!val->u.v)
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
V_VT(val->u.v) = VT_EMPTY; V_VT(val->u.v) = VT_EMPTY;
hres = VariantCopy(val->u.v, var); hres = VariantCopy(val->u.v, var);
if(FAILED(hres)) if(FAILED(hres))
heap_free(val->u.v); heap_free(val->u.v);
...@@ -357,6 +359,7 @@ HRESULT jsval_to_variant(jsval_t val, VARIANT *retv) ...@@ -357,6 +359,7 @@ HRESULT jsval_to_variant(jsval_t val, VARIANT *retv)
V_BOOL(retv) = val.u.b ? VARIANT_TRUE : VARIANT_FALSE; V_BOOL(retv) = val.u.b ? VARIANT_TRUE : VARIANT_FALSE;
return S_OK; return S_OK;
case JSV_VARIANT: case JSV_VARIANT:
V_VT(retv) = VT_EMPTY;
return VariantCopy(retv, val.u.v); return VariantCopy(retv, val.u.v);
} }
...@@ -394,8 +397,16 @@ HRESULT to_primitive(script_ctx_t *ctx, VARIANT *v, jsexcept_t *ei, VARIANT *ret ...@@ -394,8 +397,16 @@ HRESULT to_primitive(script_ctx_t *ctx, VARIANT *v, jsexcept_t *ei, VARIANT *ret
jsdisp = iface_to_jsdisp((IUnknown*)V_DISPATCH(v)); jsdisp = iface_to_jsdisp((IUnknown*)V_DISPATCH(v));
if(!jsdisp) { if(!jsdisp) {
V_VT(ret) = VT_EMPTY; jsval_t val;
return disp_propget(ctx, V_DISPATCH(v), DISPID_VALUE, ret, ei); 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;
} }
if(hint == NO_HINT) if(hint == NO_HINT)
...@@ -451,6 +462,28 @@ HRESULT to_primitive(script_ctx_t *ctx, VARIANT *v, jsexcept_t *ei, VARIANT *ret ...@@ -451,6 +462,28 @@ HRESULT to_primitive(script_ctx_t *ctx, VARIANT *v, jsexcept_t *ei, VARIANT *ret
return S_OK; 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);
}
/* ECMA-262 3rd Edition 9.2 */ /* ECMA-262 3rd Edition 9.2 */
HRESULT to_boolean(VARIANT *v, VARIANT_BOOL *b) HRESULT to_boolean(VARIANT *v, VARIANT_BOOL *b)
{ {
...@@ -961,9 +994,7 @@ HRESULT to_object_jsval(script_ctx_t *ctx, jsval_t v, IDispatch **disp) ...@@ -961,9 +994,7 @@ HRESULT to_object_jsval(script_ctx_t *ctx, jsval_t v, IDispatch **disp)
if(FAILED(hres)) if(FAILED(hres))
return hres; return hres;
hres = to_object(ctx, &var, disp); return to_object(ctx, &var, disp);
VariantClear(&var);
return hres;
} }
HRESULT variant_change_type(script_ctx_t *ctx, VARIANT *dst, VARIANT *src, VARTYPE vt) HRESULT variant_change_type(script_ctx_t *ctx, VARIANT *dst, VARIANT *src, VARTYPE vt)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment