jscript: Use jsval_t instead of VARIANT for stack values.
This commit is contained in:
parent
847aebdc87
commit
16b2b019b8
|
@ -971,19 +971,6 @@ jsdisp_t *iface_to_jsdisp(IUnknown *iface)
|
|||
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)
|
||||
{
|
||||
dispex_prop_t *prop;
|
||||
|
@ -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,
|
||||
VARIANT *retv, jsexcept_t *ei)
|
||||
jsval_t *ret, jsexcept_t *ei)
|
||||
{
|
||||
IDispatchEx *dispex;
|
||||
jsdisp_t *jsdisp;
|
||||
VARIANT buf[6];
|
||||
VARIANT buf[6], retv;
|
||||
DISPPARAMS dp;
|
||||
unsigned i;
|
||||
HRESULT hres;
|
||||
|
@ -1078,13 +1065,21 @@ HRESULT disp_call(script_ctx_t *ctx, IDispatch *disp, DISPID id, WORD flags, uns
|
|||
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);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
if(ret) {
|
||||
hres = variant_to_jsval(&retv, ret);
|
||||
VariantClear(&retv);
|
||||
}
|
||||
return hres;
|
||||
}
|
||||
|
||||
memset(ei, 0, sizeof(*ei));
|
||||
if(retv && argc)
|
||||
if(ret && argc)
|
||||
flags |= DISPATCH_PROPERTYGET;
|
||||
|
||||
dp.cArgs = argc;
|
||||
|
@ -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);
|
||||
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);
|
||||
}else {
|
||||
UINT err = 0;
|
||||
|
@ -1134,7 +1128,7 @@ HRESULT disp_call(script_ctx_t *ctx, IDispatch *disp, DISPID id, WORD flags, uns
|
|||
}
|
||||
|
||||
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++)
|
||||
|
@ -1144,9 +1138,11 @@ HRESULT disp_call(script_ctx_t *ctx, IDispatch *disp, DISPID id, WORD flags, uns
|
|||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
if(retv)
|
||||
ensure_retval_type(retv);
|
||||
return S_OK;
|
||||
if(ret) {
|
||||
hres = variant_to_jsval(&retv, ret);
|
||||
VariantClear(&retv);
|
||||
}
|
||||
return hres;
|
||||
}
|
||||
|
||||
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
|
|||
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;
|
||||
HRESULT hres;
|
||||
|
@ -1298,11 +1294,6 @@ HRESULT disp_propput(script_ctx_t *ctx, IDispatch *disp, DISPID id, VARIANT *var
|
|||
jsdisp = iface_to_jsdisp((IUnknown*)disp);
|
||||
if(jsdisp) {
|
||||
dispex_prop_t *prop;
|
||||
jsval_t val;
|
||||
|
||||
hres = variant_to_jsval(var, &val);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
prop = get_prop(jsdisp, id);
|
||||
if(prop)
|
||||
|
@ -1310,13 +1301,17 @@ HRESULT disp_propput(script_ctx_t *ctx, IDispatch *disp, DISPID id, VARIANT *var
|
|||
else
|
||||
hres = DISP_E_MEMBERNOTFOUND;
|
||||
|
||||
jsval_release(val);
|
||||
jsdisp_release(jsdisp);
|
||||
}else {
|
||||
DISPID dispid = DISPID_PROPERTYPUT;
|
||||
DISPPARAMS dp = {var, &dispid, 1, 1};
|
||||
VARIANT var;
|
||||
DISPPARAMS dp = {&var, &dispid, 1, 1};
|
||||
IDispatchEx *dispex;
|
||||
|
||||
hres = jsval_to_variant(val, &var);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
|
||||
if(SUCCEEDED(hres)) {
|
||||
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
|
|||
TRACE("using IDispatch\n");
|
||||
hres = IDispatch_Invoke(disp, id, &IID_NULL, ctx->lcid, DISPATCH_PROPERTYPUT, &dp, NULL, &ei->ei, &err);
|
||||
}
|
||||
|
||||
VariantClear(&var);
|
||||
}
|
||||
|
||||
return hres;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
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};
|
||||
IDispatchEx *dispex;
|
||||
jsdisp_t *jsdisp;
|
||||
VARIANT var;
|
||||
HRESULT hres;
|
||||
|
||||
jsdisp = iface_to_jsdisp((IUnknown*)disp);
|
||||
if(jsdisp) {
|
||||
jsval_t v;
|
||||
hres = jsdisp_propget(jsdisp, id, &v, ei);
|
||||
hres = jsdisp_propget(jsdisp, id, val, ei);
|
||||
jsdisp_release(jsdisp);
|
||||
if(SUCCEEDED(hres)) {
|
||||
hres = jsval_to_variant(v, val);
|
||||
jsval_release(v);
|
||||
}
|
||||
return hres;
|
||||
}
|
||||
|
||||
V_VT(&var) = VT_EMPTY;
|
||||
hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
|
||||
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);
|
||||
IDispatchEx_Release(dispex);
|
||||
}else {
|
||||
ULONG err = 0;
|
||||
|
||||
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))
|
||||
return hres;
|
||||
|
||||
ensure_retval_type(val);
|
||||
return S_OK;
|
||||
return variant_to_jsval(&var, val);
|
||||
}
|
||||
|
||||
HRESULT jsdisp_delete_idx(jsdisp_t *obj, DWORD idx)
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -230,7 +230,7 @@ struct _exec_ctx_t {
|
|||
function_code_t *func_code;
|
||||
BOOL is_global;
|
||||
|
||||
VARIANT *stack;
|
||||
jsval_t *stack;
|
||||
unsigned stack_size;
|
||||
unsigned top;
|
||||
except_frame_t *except_frame;
|
||||
|
@ -246,7 +246,7 @@ static inline void exec_addref(exec_ctx_t *ctx)
|
|||
|
||||
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 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;
|
||||
|
||||
typedef enum {
|
||||
|
@ -396,12 +396,12 @@ typedef struct {
|
|||
|
||||
typedef struct {
|
||||
enum {
|
||||
EXPRVAL_VARIANT,
|
||||
EXPRVAL_JSVAL,
|
||||
EXPRVAL_IDREF,
|
||||
EXPRVAL_INVALID
|
||||
} type;
|
||||
union {
|
||||
VARIANT var;
|
||||
jsval_t val;
|
||||
struct {
|
||||
IDispatch *disp;
|
||||
DISPID id;
|
||||
|
|
|
@ -180,16 +180,11 @@ static HRESULT invoke_source(script_ctx_t *ctx, FunctionInstance *function, IDis
|
|||
jsdisp_release(var_disp);
|
||||
if(SUCCEEDED(hres)) {
|
||||
jsdisp_t *prev_args;
|
||||
VARIANT retv;
|
||||
|
||||
prev_args = function->arguments;
|
||||
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;
|
||||
if(SUCCEEDED(hres) && r) {
|
||||
hres = variant_to_jsval(&retv, r);
|
||||
VariantClear(&retv);
|
||||
}
|
||||
}
|
||||
|
||||
jsdisp_release(arg_disp);
|
||||
|
|
|
@ -349,7 +349,6 @@ static HRESULT JSGlobal_eval(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, uns
|
|||
jsval_t *r, jsexcept_t *ei)
|
||||
{
|
||||
bytecode_t *code;
|
||||
VARIANT retv;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("\n");
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
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);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
if(r) {
|
||||
hres = variant_to_jsval(&retv, r);
|
||||
VariantClear(&retv);
|
||||
}
|
||||
return hres;
|
||||
}
|
||||
|
||||
|
|
|
@ -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_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 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_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_propput(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,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_const(jsdisp_t*,const WCHAR*,VARIANT*) DECLSPEC_HIDDEN;
|
||||
|
@ -259,6 +259,7 @@ typedef enum {
|
|||
} 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_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;
|
||||
|
|
|
@ -52,6 +52,8 @@ const char *debugstr_variant(const VARIANT *v)
|
|||
return wine_dbg_sprintf("{VT_DISPATCH: %p}", V_DISPATCH(v));
|
||||
case VT_BOOL:
|
||||
return wine_dbg_sprintf("{VT_BOOL: %x}", V_BOOL(v));
|
||||
case VT_ARRAY|VT_VARIANT:
|
||||
return "{VT_ARRAY|VT_VARIANT: ...}";
|
||||
default:
|
||||
return wine_dbg_sprintf("{vt %d}", V_VT(v));
|
||||
}
|
||||
|
@ -241,7 +243,7 @@ HRESULT jsval_variant(jsval_t *val, VARIANT *var)
|
|||
if(!val->u.v)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
V_VT(val->u.v) = VT_EMPTY;
|
||||
V_VT(val->u.v) = VT_EMPTY;
|
||||
hres = VariantCopy(val->u.v, var);
|
||||
if(FAILED(hres))
|
||||
heap_free(val->u.v);
|
||||
|
@ -357,6 +359,7 @@ HRESULT jsval_to_variant(jsval_t val, VARIANT *retv)
|
|||
V_BOOL(retv) = val.u.b ? VARIANT_TRUE : VARIANT_FALSE;
|
||||
return S_OK;
|
||||
case JSV_VARIANT:
|
||||
V_VT(retv) = VT_EMPTY;
|
||||
return VariantCopy(retv, val.u.v);
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
if(!jsdisp) {
|
||||
V_VT(ret) = VT_EMPTY;
|
||||
return disp_propget(ctx, V_DISPATCH(v), DISPID_VALUE, ret, ei);
|
||||
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;
|
||||
}
|
||||
|
||||
if(hint == NO_HINT)
|
||||
|
@ -451,6 +462,28 @@ HRESULT to_primitive(script_ctx_t *ctx, VARIANT *v, jsexcept_t *ei, VARIANT *ret
|
|||
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 */
|
||||
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)
|
|||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
hres = to_object(ctx, &var, disp);
|
||||
VariantClear(&var);
|
||||
return hres;
|
||||
return to_object(ctx, &var, disp);
|
||||
}
|
||||
|
||||
HRESULT variant_change_type(script_ctx_t *ctx, VARIANT *dst, VARIANT *src, VARTYPE vt)
|
||||
|
|
Loading…
Reference in New Issue