Commit 932b3dd0 authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

jscript: Added new variable representation and use it for internal function return values.

parent b57323a6
......@@ -139,7 +139,7 @@ static IUnknown *create_activex_object(script_ctx_t *ctx, const WCHAR *progid)
}
static HRESULT ActiveXObject_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, VARIANT *argv,
VARIANT *retv, jsexcept_t *ei)
jsval_t *r, jsexcept_t *ei)
{
IDispatch *disp;
IUnknown *obj;
......@@ -180,8 +180,7 @@ static HRESULT ActiveXObject_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flag
return E_NOTIMPL;
}
V_VT(retv) = VT_DISPATCH;
V_DISPATCH(retv) = disp;
*r = jsval_disp(disp);
return S_OK;
}
......
......@@ -39,7 +39,7 @@ static inline BoolInstance *bool_this(vdisp_t *jsthis)
/* ECMA-262 3rd Edition 15.6.4.2 */
static HRESULT Bool_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, VARIANT *argv,
VARIANT *retv, jsexcept_t *ei)
jsval_t *r, jsexcept_t *ei)
{
BoolInstance *bool;
......@@ -51,7 +51,7 @@ static HRESULT Bool_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, uns
if(!(bool = bool_this(jsthis)))
return throw_type_error(ctx, ei, JS_E_BOOLEAN_EXPECTED, NULL);
if(retv) {
if(r) {
BSTR val;
if(bool->val) val = SysAllocString(trueW);
......@@ -60,8 +60,7 @@ static HRESULT Bool_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, uns
if(!val)
return E_OUTOFMEMORY;
V_VT(retv) = VT_BSTR;
V_BSTR(retv) = val;
*r = jsval_string(val);
}
return S_OK;
......@@ -69,7 +68,7 @@ static HRESULT Bool_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, uns
/* ECMA-262 3rd Edition 15.6.4.3 */
static HRESULT Bool_valueOf(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, VARIANT *argv,
VARIANT *retv, jsexcept_t *ei)
jsval_t *r, jsexcept_t *ei)
{
BoolInstance *bool;
......@@ -78,16 +77,13 @@ static HRESULT Bool_valueOf(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsi
if(!(bool = bool_this(jsthis)))
return throw_type_error(ctx, ei, JS_E_BOOLEAN_EXPECTED, NULL);
if(retv) {
V_VT(retv) = VT_BOOL;
V_BOOL(retv) = bool->val;
}
if(r)
*r = jsval_bool(bool->val);
return S_OK;
}
static HRESULT Bool_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, VARIANT *argv,
VARIANT *retv, jsexcept_t *ei)
jsval_t *r, jsexcept_t *ei)
{
TRACE("\n");
......@@ -126,7 +122,7 @@ static const builtin_info_t BoolInst_info = {
};
static HRESULT BoolConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, VARIANT *argv,
VARIANT *retv, jsexcept_t *ei)
jsval_t *r, jsexcept_t *ei)
{
HRESULT hres;
VARIANT_BOOL value = VARIANT_FALSE;
......@@ -145,15 +141,13 @@ static HRESULT BoolConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
if(FAILED(hres))
return hres;
var_set_jsdisp(retv, bool);
*r = jsval_obj(bool);
return S_OK;
}
case INVOKE_FUNC:
if(retv) {
V_VT(retv) = VT_BOOL;
V_BOOL(retv) = value;
}
if(r)
*r = jsval_bool(value);
return S_OK;
default:
......
......@@ -348,7 +348,7 @@ static HRESULT convert_params(const DISPPARAMS *dp, VARIANT *buf, unsigned *argc
}
static HRESULT invoke_prop_func(jsdisp_t *This, IDispatch *jsthis, dispex_prop_t *prop, WORD flags,
unsigned argc, VARIANT *argv, VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
unsigned argc, VARIANT *argv, jsval_t *r, jsexcept_t *ei, IServiceProvider *caller)
{
HRESULT hres;
......@@ -366,17 +366,17 @@ static HRESULT invoke_prop_func(jsdisp_t *This, IDispatch *jsthis, dispex_prop_t
set_disp(&vthis, jsthis);
else
set_jsdisp(&vthis, This);
hres = prop->u.p->invoke(This->ctx, &vthis, flags, argc, argv, retv, ei);
hres = prop->u.p->invoke(This->ctx, &vthis, flags, argc, argv, r, ei);
vdisp_release(&vthis);
}else {
/* Function object calls are special case */
hres = Function_invoke(This, jsthis, flags, argc, argv, retv, ei);
hres = Function_invoke(This, jsthis, flags, argc, argv, r, ei);
}
return hres;
}
case PROP_PROTREF:
return invoke_prop_func(This->prototype, jsthis, This->prototype->props+prop->u.ref,
flags, argc, argv, retv, ei, caller);
flags, argc, argv, r, ei, caller);
case PROP_VARIANT: {
if(V_VT(&prop->u.var) != VT_DISPATCH) {
FIXME("invoke vt %d\n", V_VT(&prop->u.var));
......@@ -385,7 +385,7 @@ static HRESULT invoke_prop_func(jsdisp_t *This, IDispatch *jsthis, dispex_prop_t
TRACE("call %s %p\n", debugstr_w(prop->name), V_DISPATCH(&prop->u.var));
return disp_call_value(This->ctx, V_DISPATCH(&prop->u.var), jsthis, flags, argc, argv, retv, ei);
return disp_call_value(This->ctx, V_DISPATCH(&prop->u.var), jsthis, flags, argc, argv, r, ei);
}
default:
ERR("type %d\n", prop->type);
......@@ -413,10 +413,15 @@ static HRESULT prop_get(jsdisp_t *This, dispex_prop_t *prop, DISPPARAMS *dp,
hres = VariantCopy(retv, &prop->u.var);
}else {
vdisp_t vthis;
jsval_t r;
set_jsdisp(&vthis, This);
hres = prop->u.p->invoke(This->ctx, &vthis, DISPATCH_PROPERTYGET, 0, NULL, retv, ei);
hres = prop->u.p->invoke(This->ctx, &vthis, DISPATCH_PROPERTYGET, 0, NULL, &r, ei);
vdisp_release(&vthis);
if(SUCCEEDED(hres)) {
hres = jsval_to_variant(r, retv);
jsval_release(r);
}
}
break;
case PROP_PROTREF:
......@@ -679,15 +684,20 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
case DISPATCH_CONSTRUCT: {
VARIANT *argv;
unsigned argc;
jsval_t r;
VARIANT buf[6];
hres = convert_params(pdp, buf, &argc, &argv);
if(FAILED(hres))
return hres;
hres = invoke_prop_func(This, get_this(pdp), prop, wFlags, argc, argv, pvarRes, &jsexcept, pspCaller);
hres = invoke_prop_func(This, get_this(pdp), prop, wFlags, argc, argv, pvarRes ? &r : NULL, &jsexcept, pspCaller);
if(argv != buf)
heap_free(argv);
if(SUCCEEDED(hres) && pvarRes) {
hres = jsval_to_variant(r, pvarRes);
jsval_release(r);
}
break;
}
case DISPATCH_PROPERTYGET:
......@@ -995,18 +1005,18 @@ HRESULT jsdisp_get_id(jsdisp_t *jsdisp, const WCHAR *name, DWORD flags, DISPID *
return DISP_E_UNKNOWNNAME;
}
HRESULT jsdisp_call_value(jsdisp_t *jsfunc, IDispatch *jsthis, WORD flags, unsigned argc, VARIANT *argv, VARIANT *retv,
HRESULT jsdisp_call_value(jsdisp_t *jsfunc, IDispatch *jsthis, WORD flags, unsigned argc, VARIANT *argv, jsval_t *r,
jsexcept_t *ei)
{
HRESULT hres;
if(is_class(jsfunc, JSCLASS_FUNCTION)) {
hres = Function_invoke(jsfunc, jsthis, flags, argc, argv, retv, ei);
hres = Function_invoke(jsfunc, jsthis, flags, argc, argv, r, ei);
}else {
vdisp_t vdisp;
set_disp(&vdisp, jsthis);
hres = jsfunc->builtin_info->value_prop.invoke(jsfunc->ctx, &vdisp, flags, argc, argv, retv, ei);
hres = jsfunc->builtin_info->value_prop.invoke(jsfunc->ctx, &vdisp, flags, argc, argv, r, ei);
vdisp_release(&vdisp);
}
return hres;
......@@ -1015,6 +1025,8 @@ HRESULT jsdisp_call_value(jsdisp_t *jsfunc, IDispatch *jsthis, WORD flags, unsig
HRESULT jsdisp_call(jsdisp_t *disp, DISPID id, WORD flags, unsigned argc, VARIANT *argv, VARIANT *retv, jsexcept_t *ei)
{
dispex_prop_t *prop;
jsval_t r;
HRESULT hres;
memset(ei, 0, sizeof(*ei));
if(retv)
......@@ -1024,10 +1036,18 @@ HRESULT jsdisp_call(jsdisp_t *disp, DISPID id, WORD flags, unsigned argc, VARIAN
if(!prop)
return DISP_E_MEMBERNOTFOUND;
return invoke_prop_func(disp, to_disp(disp), prop, flags, argc, argv, retv, ei, NULL);
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;
}
HRESULT jsdisp_call_name(jsdisp_t *disp, const WCHAR *name, WORD flags, unsigned argc, VARIANT *argv, VARIANT *retv,
HRESULT jsdisp_call_name(jsdisp_t *disp, const WCHAR *name, WORD flags, unsigned argc, VARIANT *argv, jsval_t *r,
jsexcept_t *ei)
{
dispex_prop_t *prop;
......@@ -1038,10 +1058,7 @@ HRESULT jsdisp_call_name(jsdisp_t *disp, const WCHAR *name, WORD flags, unsigned
return hres;
memset(ei, 0, sizeof(*ei));
if(retv)
V_VT(retv) = VT_EMPTY;
return invoke_prop_func(disp, to_disp(disp), prop, flags, argc, argv, retv, ei, NULL);
return invoke_prop_func(disp, to_disp(disp), prop, flags, argc, argv, r, ei, NULL);
}
HRESULT disp_call(script_ctx_t *ctx, IDispatch *disp, DISPID id, WORD flags, unsigned argc, VARIANT *argv,
......@@ -1123,11 +1140,11 @@ HRESULT disp_call(script_ctx_t *ctx, IDispatch *disp, DISPID id, WORD flags, uns
}
HRESULT disp_call_value(script_ctx_t *ctx, IDispatch *disp, IDispatch *jsthis, WORD flags, unsigned argc, VARIANT *argv,
VARIANT *retv, jsexcept_t *ei)
jsval_t *r, jsexcept_t *ei)
{
jsdisp_t *jsdisp;
IDispatchEx *dispex;
VARIANT buf[6];
VARIANT buf[6], retv;
DISPPARAMS dp;
unsigned i;
HRESULT hres;
......@@ -1139,13 +1156,13 @@ HRESULT disp_call_value(script_ctx_t *ctx, IDispatch *disp, IDispatch *jsthis, W
return E_FAIL;
}
hres = jsdisp_call_value(jsdisp, jsthis, flags, argc, argv, retv, ei);
hres = jsdisp_call_value(jsdisp, jsthis, flags, argc, argv, r, ei);
jsdisp_release(jsdisp);
return hres;
}
memset(ei, 0, sizeof(*ei));
if(retv && argc)
if(r && argc)
flags |= DISPATCH_PROPERTYGET;
......@@ -1176,11 +1193,10 @@ HRESULT disp_call_value(script_ctx_t *ctx, IDispatch *disp, IDispatch *jsthis, W
V_DISPATCH(dp.rgvarg) = jsthis;
}
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, DISPID_VALUE, ctx->lcid, flags, &dp, retv, &ei->ei,
hres = IDispatchEx_InvokeEx(dispex, DISPID_VALUE, ctx->lcid, flags, &dp, r ? &retv : NULL, &ei->ei,
&ctx->jscaller->IServiceProvider_iface);
IDispatchEx_Release(dispex);
}else {
......@@ -1192,7 +1208,7 @@ HRESULT disp_call_value(script_ctx_t *ctx, IDispatch *disp, IDispatch *jsthis, W
}
TRACE("using IDispatch\n");
hres = IDispatch_Invoke(disp, DISPID_VALUE, &IID_NULL, ctx->lcid, flags, &dp, retv, &ei->ei, &err);
hres = IDispatch_Invoke(disp, DISPID_VALUE, &IID_NULL, ctx->lcid, flags, &dp, r ? &retv : NULL, &ei->ei, &err);
}
if(dp.rgvarg != buf)
......@@ -1200,9 +1216,12 @@ HRESULT disp_call_value(script_ctx_t *ctx, IDispatch *disp, IDispatch *jsthis, W
if(FAILED(hres))
return hres;
if(retv)
ensure_retval_type(retv);
if(!r)
return S_OK;
hres = variant_to_jsval(&retv, r);
VariantClear(&retv);
return hres;
}
HRESULT jsdisp_propput_name(jsdisp_t *obj, const WCHAR *name, VARIANT *val, jsexcept_t *ei)
......
......@@ -385,7 +385,7 @@ static HRESULT disp_get_id(script_ctx_t *ctx, IDispatch *disp, BSTR name, DWORD
return hres;
}
static inline BOOL is_null(const VARIANT *v)
static inline BOOL is_null_var(const VARIANT *v)
{
return V_VT(v) == VT_NULL || (V_VT(v) == VT_DISPATCH && !V_DISPATCH(v));
}
......@@ -442,8 +442,8 @@ static HRESULT equal2_values(VARIANT *lval, VARIANT *rval, BOOL *ret)
if(V_VT(lval) != V_VT(rval)) {
if(is_num_vt(V_VT(lval)) && is_num_vt(V_VT(rval)))
*ret = num_val(lval) == num_val(rval);
else if(is_null(lval))
*ret = is_null(rval);
else if(is_null_var(lval))
*ret = is_null_var(rval);
else
*ret = FALSE;
return S_OK;
......@@ -981,6 +981,7 @@ static HRESULT interp_new(exec_ctx_t *ctx)
{
const unsigned arg = get_op_uint(ctx, 0);
VARIANT *constr, v;
jsval_t r;
HRESULT hres;
TRACE("%d\n", arg);
......@@ -996,7 +997,12 @@ static HRESULT interp_new(exec_ctx_t *ctx)
else if(!V_DISPATCH(constr))
return throw_type_error(ctx->script, ctx->ei, JS_E_INVALID_PROPERTY, NULL);
hres = disp_call_value(ctx->script, V_DISPATCH(constr), NULL, DISPATCH_CONSTRUCT, arg, stack_args(ctx, arg), &v, ctx->ei);
hres = disp_call_value(ctx->script, V_DISPATCH(constr), NULL, DISPATCH_CONSTRUCT, arg, stack_args(ctx, arg), &r, ctx->ei);
if(FAILED(hres))
return hres;
hres = jsval_to_variant(r, &v);
jsval_release(r);
if(FAILED(hres))
return hres;
......@@ -1010,6 +1016,7 @@ static HRESULT interp_call(exec_ctx_t *ctx)
const unsigned argn = get_op_uint(ctx, 0);
const int do_ret = get_op_int(ctx, 1);
VARIANT v, *objv;
jsval_t r;
HRESULT hres;
TRACE("%d %d\n", argn, do_ret);
......@@ -1019,12 +1026,21 @@ static HRESULT interp_call(exec_ctx_t *ctx)
return throw_type_error(ctx->script, ctx->ei, JS_E_INVALID_PROPERTY, NULL);
hres = disp_call_value(ctx->script, V_DISPATCH(objv), NULL, DISPATCH_METHOD, argn, stack_args(ctx, argn),
do_ret ? &v : NULL, ctx->ei);
do_ret ? &r : NULL, ctx->ei);
if(FAILED(hres))
return hres;
stack_popn(ctx, argn+1);
return do_ret ? stack_push(ctx, &v) : S_OK;
if(!do_ret)
return S_OK;
hres = jsval_to_variant(r, &v);
jsval_release(r);
if(FAILED(hres))
return hres;
return stack_push(ctx, &v);
}
......
......@@ -35,7 +35,7 @@ static const WCHAR toStringW[] = {'t','o','S','t','r','i','n','g',0};
/* ECMA-262 3rd Edition 15.11.4.4 */
static HRESULT Error_toString(script_ctx_t *ctx, vdisp_t *vthis, WORD flags,
unsigned argc, VARIANT *argv, VARIANT *retv, jsexcept_t *ei)
unsigned argc, VARIANT *argv, jsval_t *r, jsexcept_t *ei)
{
jsdisp_t *jsthis;
BSTR name = NULL, msg = NULL, ret = NULL;
......@@ -48,11 +48,11 @@ static HRESULT Error_toString(script_ctx_t *ctx, vdisp_t *vthis, WORD flags,
jsthis = get_jsdisp(vthis);
if(!jsthis || ctx->version < 2) {
if(retv) {
V_VT(retv) = VT_BSTR;
V_BSTR(retv) = SysAllocString(object_errorW);
if(!V_BSTR(retv))
if(r) {
BSTR ret = SysAllocString(object_errorW);
if(!ret)
return E_OUTOFMEMORY;
*r = jsval_string(ret);
}
return S_OK;
}
......@@ -116,18 +116,15 @@ static HRESULT Error_toString(script_ctx_t *ctx, vdisp_t *vthis, WORD flags,
if(!ret)
return E_OUTOFMEMORY;
if(retv) {
V_VT(retv) = VT_BSTR;
V_BSTR(retv) = ret;
}else {
if(r)
*r = jsval_string(ret);
else
SysFreeString(ret);
}
return S_OK;
}
static HRESULT Error_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
unsigned argc, VARIANT *argv, VARIANT *retv, jsexcept_t *ei)
unsigned argc, VARIANT *argv, jsval_t *r, jsexcept_t *ei)
{
TRACE("\n");
......@@ -227,7 +224,7 @@ static HRESULT create_error(script_ctx_t *ctx, jsdisp_t *constr,
}
static HRESULT error_constr(script_ctx_t *ctx, WORD flags, unsigned argc, VARIANT *argv,
VARIANT *retv, jsexcept_t *ei, jsdisp_t *constr) {
jsval_t *r, jsexcept_t *ei, jsdisp_t *constr) {
jsdisp_t *err;
UINT num = 0;
BSTR msg = NULL;
......@@ -261,11 +258,10 @@ static HRESULT error_constr(script_ctx_t *ctx, WORD flags, unsigned argc, VARIAN
if(FAILED(hres))
return hres;
if(retv)
var_set_jsdisp(retv, err);
if(r)
*r = jsval_obj(err);
else
jsdisp_release(err);
return S_OK;
default:
......@@ -275,59 +271,59 @@ static HRESULT error_constr(script_ctx_t *ctx, WORD flags, unsigned argc, VARIAN
}
static HRESULT ErrorConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
unsigned argc, VARIANT *argv, VARIANT *retv, jsexcept_t *ei)
unsigned argc, VARIANT *argv, jsval_t *r, jsexcept_t *ei)
{
TRACE("\n");
return error_constr(ctx, flags, argc, argv, retv, ei, ctx->error_constr);
return error_constr(ctx, flags, argc, argv, r, ei, ctx->error_constr);
}
static HRESULT EvalErrorConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
unsigned argc, VARIANT *argv, VARIANT *retv, jsexcept_t *ei)
unsigned argc, VARIANT *argv, jsval_t *r, jsexcept_t *ei)
{
TRACE("\n");
return error_constr(ctx, flags, argc, argv, retv, ei, ctx->eval_error_constr);
return error_constr(ctx, flags, argc, argv, r, ei, ctx->eval_error_constr);
}
static HRESULT RangeErrorConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
unsigned argc, VARIANT *argv, VARIANT *retv, jsexcept_t *ei)
unsigned argc, VARIANT *argv, jsval_t *r, jsexcept_t *ei)
{
TRACE("\n");
return error_constr(ctx, flags, argc, argv, retv, ei, ctx->range_error_constr);
return error_constr(ctx, flags, argc, argv, r, ei, ctx->range_error_constr);
}
static HRESULT ReferenceErrorConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
unsigned argc, VARIANT *argv, VARIANT *retv, jsexcept_t *ei)
unsigned argc, VARIANT *argv, jsval_t *r, jsexcept_t *ei)
{
TRACE("\n");
return error_constr(ctx, flags, argc, argv, retv, ei, ctx->reference_error_constr);
return error_constr(ctx, flags, argc, argv, r, ei, ctx->reference_error_constr);
}
static HRESULT RegExpErrorConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
unsigned argc, VARIANT *argv, VARIANT *retv, jsexcept_t *ei)
unsigned argc, VARIANT *argv, jsval_t *r, jsexcept_t *ei)
{
TRACE("\n");
return error_constr(ctx, flags, argc, argv, retv, ei, ctx->regexp_error_constr);
return error_constr(ctx, flags, argc, argv, r, ei, ctx->regexp_error_constr);
}
static HRESULT SyntaxErrorConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
unsigned argc, VARIANT *argv, VARIANT *retv, jsexcept_t *ei)
unsigned argc, VARIANT *argv, jsval_t *r, jsexcept_t *ei)
{
TRACE("\n");
return error_constr(ctx, flags, argc, argv, retv, ei, ctx->syntax_error_constr);
return error_constr(ctx, flags, argc, argv, r, ei, ctx->syntax_error_constr);
}
static HRESULT TypeErrorConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
unsigned argc, VARIANT *argv, VARIANT *retv, jsexcept_t *ei)
unsigned argc, VARIANT *argv, jsval_t *r, jsexcept_t *ei)
{
TRACE("\n");
return error_constr(ctx, flags, argc, argv, retv, ei, ctx->type_error_constr);
return error_constr(ctx, flags, argc, argv, r, ei, ctx->type_error_constr);
}
static HRESULT URIErrorConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
unsigned argc, VARIANT *argv, VARIANT *retv, jsexcept_t *ei)
unsigned argc, VARIANT *argv, jsval_t *r, jsexcept_t *ei)
{
TRACE("\n");
return error_constr(ctx, flags, argc, argv, retv, ei, ctx->uri_error_constr);
return error_constr(ctx, flags, argc, argv, r, ei, ctx->uri_error_constr);
}
HRESULT init_error_constr(script_ctx_t *ctx, jsdisp_t *object_prototype)
......
......@@ -33,6 +33,7 @@
#include "wine/unicode.h"
#include "wine/list.h"
typedef struct _jsval_t jsval_t;
typedef struct _script_ctx_t script_ctx_t;
typedef struct _exec_ctx_t exec_ctx_t;
typedef struct _dispex_prop_t dispex_prop_t;
......@@ -152,7 +153,7 @@ static inline jsdisp_t *get_jsdisp(vdisp_t *vdisp)
return is_jsdisp(vdisp) ? vdisp->u.jsdisp : NULL;
}
typedef HRESULT (*builtin_invoke_t)(script_ctx_t*,vdisp_t*,WORD,unsigned,VARIANT*,VARIANT*,jsexcept_t*);
typedef HRESULT (*builtin_invoke_t)(script_ctx_t*,vdisp_t*,WORD,unsigned,VARIANT*,jsval_t*,jsexcept_t*);
typedef struct {
const WCHAR *name;
......@@ -192,9 +193,10 @@ static inline IDispatch *to_disp(jsdisp_t *jsdisp)
jsdisp_t *as_jsdisp(IDispatch*) DECLSPEC_HIDDEN;
jsdisp_t *to_jsdisp(IDispatch*) DECLSPEC_HIDDEN;
static inline void jsdisp_addref(jsdisp_t *jsdisp)
static inline jsdisp_t *jsdisp_addref(jsdisp_t *jsdisp)
{
IDispatchEx_AddRef(&jsdisp->IDispatchEx_iface);
return jsdisp;
}
static inline void jsdisp_release(jsdisp_t *jsdisp)
......@@ -207,10 +209,10 @@ HRESULT init_dispex(jsdisp_t*,script_ctx_t*,const builtin_info_t*,jsdisp_t*) DEC
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,VARIANT*,VARIANT*,jsexcept_t*) DECLSPEC_HIDDEN;
HRESULT disp_call_value(script_ctx_t*,IDispatch*,IDispatch*,WORD,unsigned,VARIANT*,VARIANT*,jsexcept_t*) DECLSPEC_HIDDEN;
HRESULT jsdisp_call_value(jsdisp_t*,IDispatch*,WORD,unsigned,VARIANT*,VARIANT*,jsexcept_t*) DECLSPEC_HIDDEN;
HRESULT disp_call_value(script_ctx_t*,IDispatch*,IDispatch*,WORD,unsigned,VARIANT*,jsval_t*,jsexcept_t*) DECLSPEC_HIDDEN;
HRESULT jsdisp_call_value(jsdisp_t*,IDispatch*,WORD,unsigned,VARIANT*,jsval_t*,jsexcept_t*) DECLSPEC_HIDDEN;
HRESULT jsdisp_call(jsdisp_t*,DISPID,WORD,unsigned,VARIANT*,VARIANT*,jsexcept_t*) DECLSPEC_HIDDEN;
HRESULT jsdisp_call_name(jsdisp_t*,const WCHAR*,WORD,unsigned,VARIANT*,VARIANT*,jsexcept_t*) DECLSPEC_HIDDEN;
HRESULT jsdisp_call_name(jsdisp_t*,const WCHAR*,WORD,unsigned,VARIANT*,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 jsdisp_propget(jsdisp_t*,DISPID,VARIANT*,jsexcept_t*) DECLSPEC_HIDDEN;
......@@ -228,8 +230,8 @@ HRESULT create_builtin_function(script_ctx_t*,builtin_invoke_t,const WCHAR*,cons
jsdisp_t*,jsdisp_t**) DECLSPEC_HIDDEN;
HRESULT create_builtin_constructor(script_ctx_t*,builtin_invoke_t,const WCHAR*,const builtin_info_t*,DWORD,
jsdisp_t*,jsdisp_t**) DECLSPEC_HIDDEN;
HRESULT Function_value(script_ctx_t*,vdisp_t*,WORD,unsigned,VARIANT*,VARIANT*,jsexcept_t*) DECLSPEC_HIDDEN;
HRESULT Function_invoke(jsdisp_t*,IDispatch*,WORD,unsigned,VARIANT*,VARIANT*,jsexcept_t*);
HRESULT Function_value(script_ctx_t*,vdisp_t*,WORD,unsigned,VARIANT*,jsval_t*,jsexcept_t*) DECLSPEC_HIDDEN;
HRESULT Function_invoke(jsdisp_t*,IDispatch*,WORD,unsigned,VARIANT*,jsval_t*,jsexcept_t*) DECLSPEC_HIDDEN;
HRESULT throw_eval_error(script_ctx_t*,jsexcept_t*,HRESULT,const WCHAR*) DECLSPEC_HIDDEN;
HRESULT throw_generic_error(script_ctx_t*,jsexcept_t*,HRESULT,const WCHAR*) DECLSPEC_HIDDEN;
......@@ -259,10 +261,12 @@ typedef enum {
HRESULT to_primitive(script_ctx_t*,VARIANT*,jsexcept_t*,VARIANT*, hint_t) DECLSPEC_HIDDEN;
HRESULT to_boolean(VARIANT*,VARIANT_BOOL*) DECLSPEC_HIDDEN;
HRESULT to_number(script_ctx_t*,VARIANT*,jsexcept_t*,double*) DECLSPEC_HIDDEN;
HRESULT to_number_jsval(script_ctx_t*,jsval_t,jsexcept_t*,double*) DECLSPEC_HIDDEN;
HRESULT to_integer(script_ctx_t*,VARIANT*,jsexcept_t*,double*) DECLSPEC_HIDDEN;
HRESULT to_int32(script_ctx_t*,VARIANT*,jsexcept_t*,INT*) DECLSPEC_HIDDEN;
HRESULT to_uint32(script_ctx_t*,VARIANT*,jsexcept_t*,DWORD*) DECLSPEC_HIDDEN;
HRESULT to_string(script_ctx_t*,VARIANT*,jsexcept_t*,BSTR*) DECLSPEC_HIDDEN;
HRESULT to_string_jsval(script_ctx_t*,jsval_t,jsexcept_t*,BSTR*) DECLSPEC_HIDDEN;
HRESULT to_object(script_ctx_t*,VARIANT*,IDispatch**) DECLSPEC_HIDDEN;
HRESULT variant_change_type(script_ctx_t*,VARIANT*,VARIANT*,VARTYPE) DECLSPEC_HIDDEN;
......@@ -377,7 +381,7 @@ HRESULT regexp_match_next(script_ctx_t*,jsdisp_t*,DWORD,const WCHAR*,DWORD,const
DWORD*,DWORD*,match_result_t*) DECLSPEC_HIDDEN;
HRESULT regexp_match(script_ctx_t*,jsdisp_t*,const WCHAR*,DWORD,BOOL,match_result_t**,DWORD*) DECLSPEC_HIDDEN;
HRESULT parse_regexp_flags(const WCHAR*,DWORD,DWORD*) DECLSPEC_HIDDEN;
HRESULT regexp_string_match(script_ctx_t*,jsdisp_t*,BSTR,VARIANT*,jsexcept_t*) DECLSPEC_HIDDEN;
HRESULT regexp_string_match(script_ctx_t*,jsdisp_t*,BSTR,jsval_t*,jsexcept_t*) DECLSPEC_HIDDEN;
static inline BOOL is_class(jsdisp_t *jsdisp, jsclass_t class)
{
......@@ -536,3 +540,5 @@ static inline LPWSTR heap_strdupW(LPCWSTR str)
return ret;
}
#include "jsval.h"
......@@ -185,6 +185,118 @@ jsheap_t *jsheap_mark(jsheap_t *heap)
return heap;
}
static BSTR clone_bstr(BSTR str)
{
return SysAllocStringLen(str, str ? SysStringLen(str) : 0);
}
void jsval_release(jsval_t val)
{
switch(val.type) {
case JSV_OBJECT:
IDispatch_Release(val.u.obj);
break;
case JSV_STRING:
SysFreeString(val.u.str);
break;
case JSV_VARIANT:
VariantClear(val.u.v);
heap_free(val.u.v);
break;
default:
break;
}
}
HRESULT jsval_variant(jsval_t *val, VARIANT *var)
{
HRESULT hres;
val->type = JSV_VARIANT;
val->u.v = heap_alloc(sizeof(VARIANT));
if(!val->u.v)
return E_OUTOFMEMORY;
V_VT(val->u.v) = VT_EMPTY;
hres = VariantCopy(val->u.v, var);
if(FAILED(hres))
heap_free(val->u.v);
return hres;
}
HRESULT variant_to_jsval(VARIANT *var, jsval_t *r)
{
switch(V_VT(var)) {
case VT_EMPTY:
*r = jsval_undefined();
return S_OK;
case VT_NULL:
*r = jsval_null();
return S_OK;
case VT_BOOL:
*r = jsval_bool(V_BOOL(var));
return S_OK;
case VT_I4:
*r = jsval_number(V_I4(var));
return S_OK;
case VT_R8:
*r = jsval_number(V_R8(var));
return S_OK;
case VT_BSTR: {
BSTR str = clone_bstr(V_BSTR(var));
if(!str)
return E_OUTOFMEMORY;
*r = jsval_string(str);
return S_OK;
}
case VT_DISPATCH: {
IDispatch_AddRef(V_DISPATCH(var));
*r = jsval_disp(V_DISPATCH(var));
return S_OK;
}
case VT_I2:
case VT_INT:
assert(0);
default:
return jsval_variant(r, var);
}
}
HRESULT jsval_to_variant(jsval_t val, VARIANT *retv)
{
switch(val.type) {
case JSV_UNDEFINED:
V_VT(retv) = VT_EMPTY;
return S_OK;
case JSV_NULL:
V_VT(retv) = VT_NULL;
return S_OK;
case JSV_OBJECT:
V_VT(retv) = VT_DISPATCH;
IDispatch_AddRef(val.u.obj);
V_DISPATCH(retv) = val.u.obj;
return S_OK;
case JSV_STRING:
V_VT(retv) = VT_BSTR;
V_BSTR(retv) = clone_bstr(val.u.str);
if(!V_BSTR(retv))
return E_OUTOFMEMORY;
return S_OK;
case JSV_NUMBER:
num_set_val(retv, val.u.n);
return S_OK;
case JSV_BOOL:
V_VT(retv) = VT_BOOL;
V_BOOL(retv) = val.u.b ? VARIANT_TRUE : VARIANT_FALSE;
return S_OK;
case JSV_VARIANT:
return VariantCopy(retv, val.u.v);
}
assert(0);
return E_FAIL;
}
/* ECMA-262 3rd Edition 9.1 */
HRESULT to_primitive(script_ctx_t *ctx, VARIANT *v, jsexcept_t *ei, VARIANT *ret, hint_t hint)
{
......@@ -457,6 +569,26 @@ HRESULT to_number(script_ctx_t *ctx, VARIANT *v, jsexcept_t *ei, double *ret)
return S_OK;
}
/* ECMA-262 3rd Edition 9.3 */
HRESULT to_number_jsval(script_ctx_t *ctx, jsval_t v, jsexcept_t *ei, double *ret)
{
VARIANT var;
HRESULT hres;
if(v.type == JSV_NUMBER) {
*ret = v.u.n;
return S_OK;
}
hres = jsval_to_variant(v, &var);
if(FAILED(hres))
return hres;
hres = to_number(ctx, &var, ei, ret);
VariantClear(&var);
return hres;
}
/* ECMA-262 3rd Edition 9.4 */
HRESULT to_integer(script_ctx_t *ctx, VARIANT *v, jsexcept_t *ei, double *ret)
{
......@@ -619,6 +751,26 @@ HRESULT to_string(script_ctx_t *ctx, VARIANT *v, jsexcept_t *ei, BSTR *str)
return *str ? S_OK : E_OUTOFMEMORY;
}
/* ECMA-262 3rd Edition 9.8 */
HRESULT to_string_jsval(script_ctx_t *ctx, jsval_t v, jsexcept_t *ei, BSTR *str)
{
VARIANT var;
HRESULT hres;
if(v.type == JSV_STRING) {
*str = clone_bstr(v.u.str);
return *str ? S_OK : E_OUTOFMEMORY;
}
hres = jsval_to_variant(v, &var);
if(FAILED(hres))
return hres;
hres = to_string(ctx, &var, ei, str);
VariantClear(&var);
return hres;
}
/* ECMA-262 3rd Edition 9.9 */
HRESULT to_object(script_ctx_t *ctx, VARIANT *v, IDispatch **disp)
{
......
/*
* Copyright 2012 Jacek Caban for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef JSVAL_H
#define JSVAL_H
typedef enum {
JSV_UNDEFINED,
JSV_NULL,
JSV_OBJECT,
JSV_STRING,
JSV_NUMBER,
JSV_BOOL,
JSV_VARIANT
} jsval_type_t;
struct _jsval_t {
jsval_type_t type;
union {
IDispatch *obj;
BSTR str;
double n;
BOOL b;
VARIANT *v;
} u;
};
static inline jsval_t jsval_bool(BOOL b)
{
jsval_t ret;
ret.type = JSV_BOOL;
ret.u.b = b;
return ret;
}
static inline jsval_t jsval_string(BSTR str)
{
jsval_t ret;
ret.type = JSV_STRING;
ret.u.str = str;
return ret;
}
static inline jsval_t jsval_disp(IDispatch *obj)
{
jsval_t ret;
ret.type = JSV_OBJECT;
ret.u.obj = obj;
return ret;
}
static inline jsval_t jsval_obj(jsdisp_t *obj)
{
return jsval_disp(to_disp(obj));
}
static inline jsval_t jsval_null(void)
{
jsval_t ret = { JSV_NULL };
return ret;
}
static inline jsval_t jsval_undefined(void)
{
jsval_t ret = { JSV_UNDEFINED };
return ret;
}
static inline jsval_t jsval_number(double n)
{
jsval_t ret;
ret.type = JSV_NUMBER;
ret.u.n = n;
return ret;
}
static inline BOOL is_object_instance(jsval_t v)
{
return v.type == JSV_OBJECT;
}
static inline BOOL is_undefined(jsval_t v)
{
return v.type == JSV_UNDEFINED;
}
static inline BOOL is_null(jsval_t v)
{
return v.type == JSV_NULL;
}
static inline BOOL is_null_instance(jsval_t v)
{
return v.type == JSV_NULL || (v.type == JSV_OBJECT && !v.u.obj);
}
static inline BOOL is_string(jsval_t v)
{
return v.type == JSV_STRING;
}
static inline BOOL is_number(jsval_t v)
{
return v.type == JSV_NUMBER;
}
static inline BOOL is_variant(jsval_t v)
{
return v.type == JSV_VARIANT;
}
static inline BOOL is_bool(jsval_t v)
{
return v.type == JSV_BOOL;
}
static inline IDispatch *get_object(jsval_t v)
{
return v.u.obj;
}
static inline double get_number(jsval_t v)
{
return v.u.n;
}
static inline BSTR get_string(jsval_t v)
{
return v.u.str;
}
static inline VARIANT *get_variant(jsval_t v)
{
return v.u.v;
}
static inline BOOL get_bool(jsval_t v)
{
return v.u.b;
}
HRESULT variant_to_jsval(VARIANT*,jsval_t*) DECLSPEC_HIDDEN;
HRESULT jsval_to_variant(jsval_t,VARIANT*) DECLSPEC_HIDDEN;
void jsval_release(jsval_t) DECLSPEC_HIDDEN;
HRESULT jsval_variant(jsval_t*,VARIANT*) DECLSPEC_HIDDEN;
HRESULT jsval_copy(jsval_t,jsval_t*) DECLSPEC_HIDDEN;
#endif
......@@ -219,7 +219,7 @@ static inline void number_to_exponential(double val, int prec, BSTR *out)
/* ECMA-262 3rd Edition 15.7.4.2 */
static HRESULT Number_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, VARIANT *argv,
VARIANT *retv, jsexcept_t *ei)
jsval_t *r, jsexcept_t *ei)
{
NumberInstance *number;
INT radix = 10;
......@@ -334,24 +334,22 @@ static HRESULT Number_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, u
return E_OUTOFMEMORY;
}
if(retv) {
V_VT(retv) = VT_BSTR;
V_BSTR(retv) = str;
}else {
if(r)
*r = jsval_string(str);
else
SysFreeString(str);
}
return S_OK;
}
static HRESULT Number_toLocaleString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, VARIANT *argv,
VARIANT *retv, jsexcept_t *ei)
jsval_t *r, jsexcept_t *ei)
{
FIXME("\n");
return E_NOTIMPL;
}
static HRESULT Number_toFixed(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, VARIANT *argv,
VARIANT *retv, jsexcept_t *ei)
jsval_t *r, jsexcept_t *ei)
{
NumberInstance *number;
DOUBLE val;
......@@ -385,17 +383,15 @@ static HRESULT Number_toFixed(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
number_to_fixed(val, prec, &str);
}
if(retv) {
V_VT(retv) = VT_BSTR;
V_BSTR(retv) = str;
}else {
if(r)
*r = jsval_string(str);
else
SysFreeString(str);
}
return S_OK;
}
static HRESULT Number_toExponential(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, VARIANT *argv,
VARIANT *retv, jsexcept_t *ei)
jsval_t *r, jsexcept_t *ei)
{
NumberInstance *number;
DOUBLE val;
......@@ -431,17 +427,15 @@ static HRESULT Number_toExponential(script_ctx_t *ctx, vdisp_t *jsthis, WORD fla
number_to_exponential(val, prec, &str);
}
if(retv) {
V_VT(retv) = VT_BSTR;
V_BSTR(retv) = str;
}else {
if(r)
*r = jsval_string(str);
else
SysFreeString(str);
}
return S_OK;
}
static HRESULT Number_toPrecision(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, VARIANT *argv,
VARIANT *retv, jsexcept_t *ei)
jsval_t *r, jsexcept_t *ei)
{
NumberInstance *number;
INT prec = 0, size;
......@@ -481,17 +475,15 @@ static HRESULT Number_toPrecision(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags
number_to_fixed(val, prec-size, &str);
}
if(retv) {
V_VT(retv) = VT_BSTR;
V_BSTR(retv) = str;
}else {
if(r)
*r = jsval_string(str);
else
SysFreeString(str);
}
return S_OK;
}
static HRESULT Number_valueOf(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, VARIANT *argv,
VARIANT *retv, jsexcept_t *ei)
jsval_t *r, jsexcept_t *ei)
{
NumberInstance *number;
......@@ -500,13 +492,13 @@ static HRESULT Number_valueOf(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
if(!(number = number_this(jsthis)))
return throw_type_error(ctx, ei, JS_E_NUMBER_EXPECTED, NULL);
if(retv)
num_set_val(retv, number->value);
if(r)
*r = jsval_number(number->value);
return S_OK;
}
static HRESULT Number_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, VARIANT *argv,
VARIANT *retv, jsexcept_t *ei)
jsval_t *r, jsexcept_t *ei)
{
NumberInstance *number = number_from_vdisp(jsthis);
......@@ -514,7 +506,7 @@ static HRESULT Number_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsi
case INVOKE_FUNC:
return throw_type_error(ctx, ei, JS_E_FUNCTION_EXPECTED, NULL);
case DISPATCH_PROPERTYGET:
num_set_val(retv, number->value);
*r = jsval_number(number->value);
break;
default:
......@@ -552,7 +544,7 @@ static const builtin_info_t NumberInst_info = {
};
static HRESULT NumberConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, VARIANT *argv,
VARIANT *retv, jsexcept_t *ei)
jsval_t *r, jsexcept_t *ei)
{
double n;
HRESULT hres;
......@@ -562,8 +554,8 @@ static HRESULT NumberConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags
switch(flags) {
case INVOKE_FUNC:
if(!argc) {
if(retv)
num_set_int(retv, 0);
if(r)
*r = jsval_number(0);
return S_OK;
}
......@@ -571,8 +563,8 @@ static HRESULT NumberConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags
if(FAILED(hres))
return hres;
if(retv)
num_set_val(retv, n);
if(r)
*r = jsval_number(n);
break;
case DISPATCH_CONSTRUCT: {
......@@ -590,7 +582,7 @@ static HRESULT NumberConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags
if(FAILED(hres))
return hres;
var_set_jsdisp(retv, obj);
*r = jsval_obj(obj);
break;
}
default:
......
......@@ -33,7 +33,7 @@ static const WCHAR isPrototypeOfW[] = {'i','s','P','r','o','t','o','t','y','p','
static const WCHAR default_valueW[] = {'[','o','b','j','e','c','t',' ','O','b','j','e','c','t',']',0};
static HRESULT Object_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, VARIANT *argv,
VARIANT *retv, jsexcept_t *ei)
jsval_t *r, jsexcept_t *ei)
{
jsdisp_t *jsdisp;
const WCHAR *str;
......@@ -66,20 +66,20 @@ static HRESULT Object_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, u
return E_FAIL;
}
if(retv) {
V_VT(retv) = VT_BSTR;
V_BSTR(retv) = SysAllocStringLen(NULL, 9+strlenW(str));
if(!V_BSTR(retv))
if(r) {
BSTR ret = SysAllocStringLen(NULL, 9+strlenW(str));
if(!ret)
return E_OUTOFMEMORY;
sprintfW(V_BSTR(retv), formatW, str);
sprintfW(ret, formatW, str);
*r = jsval_string(ret);
}
return S_OK;
}
static HRESULT Object_toLocaleString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, VARIANT *argv,
VARIANT *retv, jsexcept_t *ei)
jsval_t *r, jsexcept_t *ei)
{
TRACE("\n");
......@@ -88,26 +88,23 @@ static HRESULT Object_toLocaleString(script_ctx_t *ctx, vdisp_t *jsthis, WORD fl
return E_FAIL;
}
return jsdisp_call_name(jsthis->u.jsdisp, toStringW, DISPATCH_METHOD, 0, NULL, retv, ei);
return jsdisp_call_name(jsthis->u.jsdisp, toStringW, DISPATCH_METHOD, 0, NULL, r, ei);
}
static HRESULT Object_valueOf(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, VARIANT *argv,
VARIANT *retv, jsexcept_t *ei)
jsval_t *r, jsexcept_t *ei)
{
TRACE("\n");
if(retv) {
if(r) {
IDispatch_AddRef(jsthis->u.disp);
V_VT(retv) = VT_DISPATCH;
V_DISPATCH(retv) = jsthis->u.disp;
*r = jsval_disp(jsthis->u.disp);
}
return S_OK;
}
static HRESULT Object_hasOwnProperty(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, VARIANT *argv,
VARIANT *retv, jsexcept_t *ei)
jsval_t *r, jsexcept_t *ei)
{
BSTR name;
DISPID id;
......@@ -116,11 +113,8 @@ static HRESULT Object_hasOwnProperty(script_ctx_t *ctx, vdisp_t *jsthis, WORD fl
TRACE("\n");
if(!argc) {
if(retv) {
V_VT(retv) = VT_BOOL;
V_BOOL(retv) = VARIANT_FALSE;
}
if(r)
*r = jsval_bool(FALSE);
return S_OK;
}
......@@ -135,11 +129,8 @@ static HRESULT Object_hasOwnProperty(script_ctx_t *ctx, vdisp_t *jsthis, WORD fl
if(FAILED(hres))
return hres;
if(retv) {
V_VT(retv) = VT_BOOL;
V_BOOL(retv) = result;
}
if(r)
*r = jsval_bool(result);
return S_OK;
}
......@@ -151,41 +142,40 @@ static HRESULT Object_hasOwnProperty(script_ctx_t *ctx, vdisp_t *jsthis, WORD fl
&name, 1, ctx->lcid, &id);
}
if(retv) {
V_VT(retv) = VT_BOOL;
V_BOOL(retv) = SUCCEEDED(hres) ? VARIANT_TRUE : VARIANT_FALSE;
}
if(r)
*r = jsval_bool(SUCCEEDED(hres));
return S_OK;
}
static HRESULT Object_propertyIsEnumerable(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, VARIANT *argv,
VARIANT *retv, jsexcept_t *ei)
jsval_t *r, jsexcept_t *ei)
{
FIXME("\n");
return E_NOTIMPL;
}
static HRESULT Object_isPrototypeOf(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, VARIANT *argv,
VARIANT *retv, jsexcept_t *ei)
jsval_t *r, jsexcept_t *ei)
{
FIXME("\n");
return E_NOTIMPL;
}
static HRESULT Object_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, VARIANT *argv,
VARIANT *retv, jsexcept_t *ei)
jsval_t *r, jsexcept_t *ei)
{
TRACE("\n");
switch(flags) {
case INVOKE_FUNC:
return throw_type_error(ctx, ei, JS_E_FUNCTION_EXPECTED, NULL);
case DISPATCH_PROPERTYGET:
V_VT(retv) = VT_BSTR;
V_BSTR(retv) = SysAllocString(default_valueW);
if(!V_BSTR(retv))
case DISPATCH_PROPERTYGET: {
BSTR ret = SysAllocString(default_valueW);
if(!ret)
return E_OUTOFMEMORY;
*r = jsval_string(ret);
break;
}
default:
FIXME("unimplemented flags %x\n", flags);
return E_NOTIMPL;
......@@ -226,7 +216,7 @@ static const builtin_info_t ObjectInst_info = {
};
static HRESULT ObjectConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, VARIANT *argv,
VARIANT *retv, jsexcept_t *ei)
jsval_t *r, jsexcept_t *ei)
{
HRESULT hres;
......@@ -242,12 +232,10 @@ static HRESULT ObjectConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags
if(FAILED(hres))
return hres;
if(retv) {
V_VT(retv) = VT_DISPATCH;
V_DISPATCH(retv) = disp;
}else {
if(r)
*r = jsval_disp(disp);
else
IDispatch_Release(disp);
}
return S_OK;
}
}
......@@ -259,8 +247,8 @@ static HRESULT ObjectConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags
if(FAILED(hres))
return hres;
if(retv)
var_set_jsdisp(retv, obj);
if(r)
*r = jsval_obj(obj);
else
jsdisp_release(obj);
break;
......
......@@ -3474,18 +3474,17 @@ HRESULT regexp_match(script_ctx_t *ctx, jsdisp_t *dispex, const WCHAR *str, DWOR
}
static HRESULT RegExp_source(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, VARIANT *argv,
VARIANT *retv, jsexcept_t *ei)
jsval_t *r, jsexcept_t *ei)
{
TRACE("\n");
switch(flags) {
case DISPATCH_PROPERTYGET: {
RegExpInstance *This = regexp_from_vdisp(jsthis);
V_VT(retv) = VT_BSTR;
V_BSTR(retv) = SysAllocString(This->str);
if(!V_BSTR(retv))
BSTR ret = SysAllocString(This->str);
if(!ret)
return E_OUTOFMEMORY;
*r = jsval_string(ret);
break;
}
default:
......@@ -3497,21 +3496,21 @@ static HRESULT RegExp_source(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, uns
}
static HRESULT RegExp_global(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, VARIANT *argv,
VARIANT *retv, jsexcept_t *ei)
jsval_t *r, jsexcept_t *ei)
{
FIXME("\n");
return E_NOTIMPL;
}
static HRESULT RegExp_ignoreCase(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, VARIANT *argv,
VARIANT *retv, jsexcept_t *ei)
jsval_t *r, jsexcept_t *ei)
{
FIXME("\n");
return E_NOTIMPL;
}
static HRESULT RegExp_multiline(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, VARIANT *argv,
VARIANT *retv, jsexcept_t *ei)
jsval_t *r, jsexcept_t *ei)
{
FIXME("\n");
return E_NOTIMPL;
......@@ -3535,7 +3534,7 @@ static INT index_from_var(script_ctx_t *ctx, VARIANT *v)
}
static HRESULT RegExp_lastIndex(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, VARIANT *argv,
VARIANT *retv, jsexcept_t *ei)
jsval_t *r, jsexcept_t *ei)
{
TRACE("\n");
......@@ -3543,8 +3542,7 @@ static HRESULT RegExp_lastIndex(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
case DISPATCH_PROPERTYGET: {
RegExpInstance *regexp = regexp_from_vdisp(jsthis);
V_VT(retv) = VT_EMPTY;
return VariantCopy(retv, &regexp->last_index_var);
return variant_to_jsval(&regexp->last_index_var, r);
}
case DISPATCH_PROPERTYPUT: {
RegExpInstance *regexp = regexp_from_vdisp(jsthis);
......@@ -3566,7 +3564,7 @@ static HRESULT RegExp_lastIndex(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
}
static HRESULT RegExp_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, VARIANT *argv,
VARIANT *retv, jsexcept_t *ei)
jsval_t *r, jsexcept_t *ei)
{
FIXME("\n");
return E_NOTIMPL;
......@@ -3697,7 +3695,7 @@ static HRESULT run_exec(script_ctx_t *ctx, vdisp_t *jsthis, VARIANT *arg, jsexce
}
static HRESULT RegExp_exec(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, VARIANT *argv,
VARIANT *retv, jsexcept_t *ei)
jsval_t *r, jsexcept_t *ei)
{
match_result_t *parens = NULL, match;
DWORD parens_cnt = 0;
......@@ -3711,17 +3709,15 @@ static HRESULT RegExp_exec(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsig
if(FAILED(hres))
return hres;
if(retv) {
if(r) {
if(b) {
IDispatch *ret;
hres = create_match_array(ctx, string, &match, parens, parens_cnt, ei, &ret);
if(SUCCEEDED(hres)) {
V_VT(retv) = VT_DISPATCH;
V_DISPATCH(retv) = ret;
}
if(SUCCEEDED(hres))
*r = jsval_disp(ret);
}else {
V_VT(retv) = VT_NULL;
*r = jsval_null();
}
}
......@@ -3731,7 +3727,7 @@ static HRESULT RegExp_exec(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsig
}
static HRESULT RegExp_test(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, VARIANT *argv,
VARIANT *retv, jsexcept_t *ei)
jsval_t *r, jsexcept_t *ei)
{
match_result_t match;
VARIANT undef_var;
......@@ -3753,15 +3749,13 @@ static HRESULT RegExp_test(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsig
if(FAILED(hres))
return hres;
if(retv) {
V_VT(retv) = VT_BOOL;
V_BOOL(retv) = b;
}
if(r)
*r = jsval_bool(b);
return S_OK;
}
static HRESULT RegExp_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, VARIANT *argv,
VARIANT *retv, jsexcept_t *ei)
jsval_t *r, jsexcept_t *ei)
{
TRACE("\n");
......@@ -3927,7 +3921,7 @@ HRESULT create_regexp_var(script_ctx_t *ctx, VARIANT *src_arg, VARIANT *flags_ar
}
HRESULT regexp_string_match(script_ctx_t *ctx, jsdisp_t *re, BSTR str,
VARIANT *retv, jsexcept_t *ei)
jsval_t *r, jsexcept_t *ei)
{
static const WCHAR indexW[] = {'i','n','d','e','x',0};
static const WCHAR inputW[] = {'i','n','p','u','t',0};
......@@ -3951,17 +3945,15 @@ HRESULT regexp_string_match(script_ctx_t *ctx, jsdisp_t *re, BSTR str,
if(FAILED(hres))
return hres;
if(retv) {
if(r) {
if(hres == S_OK) {
IDispatch *ret;
hres = create_match_array(ctx, str, &match, parens, parens_cnt, ei, &ret);
if(SUCCEEDED(hres)) {
V_VT(retv) = VT_DISPATCH;
V_DISPATCH(retv) = ret;
}
if(SUCCEEDED(hres))
*r = jsval_disp(ret);
}else {
V_VT(retv) = VT_NULL;
*r = jsval_null();
}
}
......@@ -3976,8 +3968,8 @@ HRESULT regexp_string_match(script_ctx_t *ctx, jsdisp_t *re, BSTR str,
if(!match_cnt) {
TRACE("no match\n");
if(retv)
V_VT(retv) = VT_NULL;
if(r)
*r = jsval_null();
return S_OK;
}
......@@ -4019,15 +4011,15 @@ HRESULT regexp_string_match(script_ctx_t *ctx, jsdisp_t *re, BSTR str,
heap_free(match_result);
if(SUCCEEDED(hres) && retv)
var_set_jsdisp(retv, array);
if(SUCCEEDED(hres) && r)
*r = jsval_obj(array);
else
jsdisp_release(array);
return hres;
}
static HRESULT RegExpConstr_leftContext(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
unsigned argc, VARIANT *argv, VARIANT *retv, jsexcept_t *ei)
unsigned argc, VARIANT *argv, jsval_t *r, jsexcept_t *ei)
{
TRACE("\n");
......@@ -4039,8 +4031,7 @@ static HRESULT RegExpConstr_leftContext(script_ctx_t *ctx, vdisp_t *jsthis, WORD
if(!ret)
return E_OUTOFMEMORY;
V_VT(retv) = VT_BSTR;
V_BSTR(retv) = ret;
*r = jsval_string(ret);
break;
}
case DISPATCH_PROPERTYPUT:
......@@ -4054,7 +4045,7 @@ static HRESULT RegExpConstr_leftContext(script_ctx_t *ctx, vdisp_t *jsthis, WORD
}
static HRESULT RegExpConstr_rightContext(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
unsigned argc, VARIANT *argv, VARIANT *retv, jsexcept_t *ei)
unsigned argc, VARIANT *argv, jsval_t *r, jsexcept_t *ei)
{
TRACE("\n");
......@@ -4066,8 +4057,7 @@ static HRESULT RegExpConstr_rightContext(script_ctx_t *ctx, vdisp_t *jsthis, WOR
if(!ret)
return E_OUTOFMEMORY;
V_VT(retv) = VT_BSTR;
V_BSTR(retv) = ret;
*r = jsval_string(ret);
break;
}
case DISPATCH_PROPERTYPUT:
......@@ -4081,7 +4071,7 @@ static HRESULT RegExpConstr_rightContext(script_ctx_t *ctx, vdisp_t *jsthis, WOR
}
static HRESULT RegExpConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, VARIANT *argv,
VARIANT *retv, jsexcept_t *ei)
jsval_t *r, jsexcept_t *ei)
{
TRACE("\n");
......@@ -4097,8 +4087,8 @@ static HRESULT RegExpConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags
return throw_regexp_error(ctx, ei, JS_E_REGEXP_SYNTAX, NULL);
}
if(retv)
var_set_jsdisp(retv, jsdisp);
if(r)
*r = jsval_obj(jsdisp);
else
jsdisp_release(jsdisp);
return S_OK;
......@@ -4121,8 +4111,8 @@ static HRESULT RegExpConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags
if(FAILED(hres))
return hres;
if(retv)
var_set_jsdisp(retv, ret);
if(r)
*r = jsval_obj(ret);
else
jsdisp_release(ret);
return S_OK;
......
......@@ -45,7 +45,7 @@ static inline VBArrayInstance *vbarray_this(vdisp_t *jsthis)
}
static HRESULT VBArray_dimensions(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned argc, VARIANT *argv,
VARIANT *retv, jsexcept_t *ei)
jsval_t *r, jsexcept_t *ei)
{
VBArrayInstance *vbarray;
......@@ -55,13 +55,13 @@ static HRESULT VBArray_dimensions(script_ctx_t *ctx, vdisp_t *vthis, WORD flags,
if(!vbarray)
return throw_type_error(ctx, ei, JS_E_VBARRAY_EXPECTED, NULL);
if(retv)
num_set_int(retv, SafeArrayGetDim(vbarray->safearray));
if(r)
*r = jsval_number(SafeArrayGetDim(vbarray->safearray));
return S_OK;
}
static HRESULT VBArray_getItem(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned argc, VARIANT *argv,
VARIANT *retv, jsexcept_t *ei)
jsval_t *r, jsexcept_t *ei)
{
VBArrayInstance *vbarray;
int i, *indexes;
......@@ -96,14 +96,13 @@ static HRESULT VBArray_getItem(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, un
else if(FAILED(hres))
return hres;
if(retv)
hres = VariantCopy(retv, &out);
if(r)
hres = jsval_variant(r, &out);
return hres;
}
static HRESULT VBArray_lbound(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned argc, VARIANT *argv,
VARIANT *retv, jsexcept_t *ei)
jsval_t *r, jsexcept_t *ei)
{
VBArrayInstance *vbarray;
int dim;
......@@ -128,13 +127,13 @@ static HRESULT VBArray_lbound(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, uns
else if(FAILED(hres))
return hres;
if(retv)
num_set_int(retv, dim);
if(r)
*r = jsval_number(dim);
return S_OK;
}
static HRESULT VBArray_toArray(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned argc, VARIANT *argv,
VARIANT *retv, jsexcept_t *ei)
jsval_t *r, jsexcept_t *ei)
{
VBArrayInstance *vbarray;
jsdisp_t *array;
......@@ -176,13 +175,13 @@ static HRESULT VBArray_toArray(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, un
SafeArrayUnaccessData(vbarray->safearray);
if(retv)
var_set_jsdisp(retv, array);
if(r)
*r = jsval_obj(array);
return S_OK;
}
static HRESULT VBArray_ubound(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned argc, VARIANT *argv,
VARIANT *retv, jsexcept_t *ei)
jsval_t *r, jsexcept_t *ei)
{
VBArrayInstance *vbarray;
int dim;
......@@ -207,13 +206,13 @@ static HRESULT VBArray_ubound(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, uns
else if(FAILED(hres))
return hres;
if(retv)
num_set_int(retv, dim);
if(r)
*r = jsval_number(dim);
return S_OK;
}
static HRESULT VBArray_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, VARIANT *argv,
VARIANT *retv, jsexcept_t *ei)
jsval_t *r, jsexcept_t *ei)
{
FIXME("\n");
......@@ -275,7 +274,7 @@ static HRESULT alloc_vbarray(script_ctx_t *ctx, jsdisp_t *object_prototype, VBAr
}
static HRESULT VBArrayConstr_value(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned argc, VARIANT *argv,
VARIANT *retv, jsexcept_t *ei)
jsval_t *r, jsexcept_t *ei)
{
VBArrayInstance *vbarray;
HRESULT hres;
......@@ -287,8 +286,7 @@ static HRESULT VBArrayConstr_value(script_ctx_t *ctx, vdisp_t *vthis, WORD flags
if(argc<1 || V_VT(argv) != (VT_ARRAY|VT_VARIANT))
return throw_type_error(ctx, ei, JS_E_VBARRAY_EXPECTED, NULL);
hres = VariantCopy(retv, argv);
return hres;
return variant_to_jsval(argv, r);
case DISPATCH_CONSTRUCT:
if(argc<1 || V_VT(argv) != (VT_ARRAY|VT_VARIANT))
......@@ -304,7 +302,7 @@ static HRESULT VBArrayConstr_value(script_ctx_t *ctx, vdisp_t *vthis, WORD flags
return hres;
}
var_set_jsdisp(retv, &vbarray->dispex);
*r = jsval_obj(&vbarray->dispex);
break;
default:
......
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