Commit b7fae529 authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

jscript: Use separated functions for implementing builtin call, get and set operation.

parent 90d3569c
......@@ -113,23 +113,26 @@ static WCHAR *idx_to_str(DWORD idx, WCHAR *ptr)
return ptr+1;
}
static HRESULT Array_length(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
jsval_t *r)
static HRESULT Array_get_length(script_ctx_t *ctx, vdisp_t *jsthis, jsval_t *r)
{
ArrayInstance *This = array_from_vdisp(jsthis);
TRACE("%p %d\n", This, This->length);
switch(flags) {
case DISPATCH_PROPERTYGET:
*r = jsval_number(This->length);
break;
case DISPATCH_PROPERTYPUT: {
return S_OK;
}
static HRESULT Array_set_length(script_ctx_t *ctx, vdisp_t *jsthis, jsval_t value)
{
ArrayInstance *This = array_from_vdisp(jsthis);
DOUBLE len = -1;
DWORD i;
HRESULT hres;
hres = to_number(ctx, argv[0], &len);
TRACE("%p %d\n", This, This->length);
hres = to_number(ctx, value, &len);
if(FAILED(hres))
return hres;
......@@ -137,20 +140,13 @@ static HRESULT Array_length(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsi
if(len!=(DWORD)len)
return throw_range_error(ctx, JS_E_INVALID_LENGTH, NULL);
for(i=len; i<This->length; i++) {
for(i=len; i < This->length; i++) {
hres = jsdisp_delete_idx(&This->dispex, i);
if(FAILED(hres))
return hres;
}
This->length = len;
break;
}
default:
FIXME("unimplemented flags %x\n", flags);
return E_NOTIMPL;
}
return S_OK;
}
......@@ -999,22 +995,11 @@ static HRESULT Array_unshift(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsi
return S_OK;
}
static HRESULT Array_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
jsval_t *r)
static HRESULT Array_get_value(script_ctx_t *ctx, vdisp_t *jsthis, jsval_t *r)
{
TRACE("\n");
switch(flags) {
case INVOKE_FUNC:
return throw_type_error(ctx, JS_E_FUNCTION_EXPECTED, NULL);
case INVOKE_PROPERTYGET:
return array_join(ctx, jsthis->u.jsdisp, array_from_vdisp(jsthis)->length, default_separatorW, r);
default:
FIXME("unimplemented flags %x\n", flags);
return E_NOTIMPL;
}
return S_OK;
}
static void Array_destructor(jsdisp_t *dispex)
......@@ -1046,7 +1031,7 @@ static void Array_on_put(jsdisp_t *dispex, const WCHAR *name)
static const builtin_prop_t Array_props[] = {
{concatW, Array_concat, PROPF_METHOD|1},
{joinW, Array_join, PROPF_METHOD|1},
{lengthW, Array_length, 0},
{lengthW, NULL,0, Array_get_length, Array_set_length},
{popW, Array_pop, PROPF_METHOD},
{pushW, Array_push, PROPF_METHOD|1},
{reverseW, Array_reverse, PROPF_METHOD},
......@@ -1061,7 +1046,7 @@ static const builtin_prop_t Array_props[] = {
static const builtin_info_t Array_info = {
JSCLASS_ARRAY,
{NULL, Array_value, 0},
{NULL, NULL,0, Array_get_value},
sizeof(Array_props)/sizeof(*Array_props),
Array_props,
Array_destructor,
......@@ -1069,12 +1054,12 @@ static const builtin_info_t Array_info = {
};
static const builtin_prop_t ArrayInst_props[] = {
{lengthW, Array_length, 0}
{lengthW, NULL,0, Array_get_length, Array_set_length}
};
static const builtin_info_t ArrayInst_info = {
JSCLASS_ARRAY,
{NULL, Array_value, 0},
{NULL, NULL,0, Array_get_value},
sizeof(ArrayInst_props)/sizeof(*ArrayInst_props),
ArrayInst_props,
Array_destructor,
......
......@@ -1917,22 +1917,11 @@ static HRESULT Date_setYear(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsi
return S_OK;
}
static HRESULT Date_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
jsval_t *r)
static HRESULT Date_get_value(script_ctx_t *ctx, vdisp_t *jsthis, jsval_t *r)
{
TRACE("\n");
switch(flags) {
case INVOKE_FUNC:
return throw_type_error(ctx, JS_E_FUNCTION_EXPECTED, NULL);
case INVOKE_PROPERTYGET:
return dateobj_to_string( (DateInstance*)jsthis->u.jsdisp, r);
default:
FIXME("unimplemented flags %x\n", flags);
return E_NOTIMPL;
}
return S_OK;
return dateobj_to_string((DateInstance*)jsthis->u.jsdisp, r);
}
static const builtin_prop_t Date_props[] = {
......@@ -1984,7 +1973,7 @@ static const builtin_prop_t Date_props[] = {
static const builtin_info_t Date_info = {
JSCLASS_DATE,
{NULL, Date_value, 0},
{NULL, NULL,0, Date_get_value},
sizeof(Date_props)/sizeof(*Date_props),
Date_props,
NULL,
......@@ -1993,7 +1982,7 @@ static const builtin_info_t Date_info = {
static const builtin_info_t DateInst_info = {
JSCLASS_DATE,
{NULL, Date_value, 0},
{NULL, NULL,0, Date_get_value},
0, NULL,
NULL,
NULL
......@@ -2508,7 +2497,7 @@ static const builtin_prop_t DateConstr_props[] = {
static const builtin_info_t DateConstr_info = {
JSCLASS_FUNCTION,
{NULL, Function_value, 0},
DEFAULT_FUNCTION_VALUE,
sizeof(DateConstr_props)/sizeof(*DateConstr_props),
DateConstr_props,
NULL,
......
......@@ -420,8 +420,16 @@ static HRESULT prop_get(jsdisp_t *This, dispex_prop_t *prop, DISPPARAMS *dp,
switch(prop->type) {
case PROP_BUILTIN:
if(prop->u.p->flags & PROPF_METHOD) {
if(prop->u.p->getter) {
vdisp_t vthis;
set_jsdisp(&vthis, This);
hres = prop->u.p->getter(This->ctx, &vthis, r);
vdisp_release(&vthis);
}else {
jsdisp_t *obj;
assert(prop->u.p->invoke != NULL);
hres = create_builtin_function(This->ctx, prop->u.p->invoke, prop->u.p->name, NULL,
prop->u.p->flags, NULL, &obj);
if(FAILED(hres))
......@@ -432,12 +440,6 @@ static HRESULT prop_get(jsdisp_t *This, dispex_prop_t *prop, DISPPARAMS *dp,
jsdisp_addref(obj);
*r = jsval_obj(obj);
}else {
vdisp_t vthis;
set_jsdisp(&vthis, This);
hres = prop->u.p->invoke(This->ctx, &vthis, DISPATCH_PROPERTYGET, 0, NULL, r);
vdisp_release(&vthis);
}
break;
case PROP_PROTREF:
......@@ -472,14 +474,18 @@ static HRESULT prop_put(jsdisp_t *This, dispex_prop_t *prop, jsval_t val, IServi
switch(prop->type) {
case PROP_BUILTIN:
if(!(prop->flags & PROPF_METHOD)) {
if(prop->u.p->setter) {
vdisp_t vthis;
set_jsdisp(&vthis, This);
hres = prop->u.p->invoke(This->ctx, &vthis, DISPATCH_PROPERTYPUT, 1, &val, NULL);
hres = prop->u.p->setter(This->ctx, &vthis, val);
vdisp_release(&vthis);
return hres;
}
if(prop->u.p->setter) {
FIXME("getter with no setter\n");
return E_FAIL;
}
/* fall through */
case PROP_PROTREF:
prop->type = PROP_JSVAL;
......@@ -510,6 +516,12 @@ static HRESULT prop_put(jsdisp_t *This, dispex_prop_t *prop, jsval_t val, IServi
return S_OK;
}
HRESULT builtin_set_const(script_ctx_t *ctx, vdisp_t *jsthis, jsval_t value)
{
TRACE("%p %s\n", jsthis, debugstr_jsval(value));
return S_OK;
}
static HRESULT fill_protrefs(jsdisp_t *This)
{
dispex_prop_t *iter, *prop;
......@@ -907,7 +919,7 @@ HRESULT init_dispex(jsdisp_t *dispex, script_ctx_t *ctx, const builtin_info_t *b
jsdisp_addref(prototype);
dispex->prop_cnt = 1;
if(builtin_info->value_prop.invoke) {
if(builtin_info->value_prop.invoke || builtin_info->value_prop.getter) {
dispex->props[0].type = PROP_BUILTIN;
dispex->props[0].u.p = &builtin_info->value_prop;
}else {
......@@ -1057,11 +1069,18 @@ HRESULT jsdisp_call_value(jsdisp_t *jsfunc, IDispatch *jsthis, WORD flags, unsig
{
HRESULT hres;
assert(!(flags & ~(DISPATCH_METHOD|DISPATCH_CONSTRUCT)));
if(is_class(jsfunc, JSCLASS_FUNCTION)) {
hres = Function_invoke(jsfunc, jsthis, flags, argc, argv, r);
}else {
vdisp_t vdisp;
if(!jsfunc->builtin_info->value_prop.invoke) {
WARN("Not a function\n");
return throw_type_error(jsfunc->ctx, JS_E_FUNCTION_EXPECTED, NULL);
}
set_disp(&vdisp, jsthis);
hres = jsfunc->builtin_info->value_prop.invoke(jsfunc->ctx, &vdisp, flags, argc, argv, r);
vdisp_release(&vdisp);
......@@ -1190,13 +1209,10 @@ HRESULT disp_call_value(script_ctx_t *ctx, IDispatch *disp, IDispatch *jsthis, W
unsigned i;
HRESULT hres;
assert(!(flags & ~(DISPATCH_METHOD|DISPATCH_CONSTRUCT)));
jsdisp = iface_to_jsdisp((IUnknown*)disp);
if(jsdisp) {
if(flags & DISPATCH_PROPERTYPUT) {
FIXME("disp_call(propput) on builtin object\n");
return E_FAIL;
}
hres = jsdisp_call_value(jsdisp, jsthis, flags, argc, argv, r);
jsdisp_release(jsdisp);
return hres;
......
......@@ -362,25 +362,22 @@ HRESULT Function_invoke(jsdisp_t *func_this, IDispatch *jsthis, WORD flags, unsi
return invoke_source(function->dispex.ctx, function, jsthis, argc, argv, r);
}
static HRESULT Function_length(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
jsval_t *r)
static HRESULT Function_get_length(script_ctx_t *ctx, vdisp_t *jsthis, jsval_t *r)
{
FunctionInstance *This = function_from_vdisp(jsthis);
TRACE("%p %d\n", This, This->length);
switch(flags) {
case DISPATCH_PROPERTYGET:
*r = jsval_number(This->length);
break;
default:
FIXME("unimplemented flags %x\n", flags);
return E_NOTIMPL;
}
return S_OK;
}
static HRESULT Function_set_length(script_ctx_t *ctx, vdisp_t *jsthis, jsval_t value)
{
FIXME("\n");
return E_NOTIMPL;
}
static HRESULT Function_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
jsval_t *r)
{
......@@ -537,56 +534,34 @@ HRESULT Function_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned
function = (FunctionInstance*)jsthis->u.jsdisp;
switch(flags) {
case DISPATCH_METHOD:
assert(function->value_proc != NULL);
return invoke_value_proc(ctx, function, NULL, flags, argc, argv, r);
}
case DISPATCH_PROPERTYGET: {
HRESULT hres;
HRESULT Function_get_value(script_ctx_t *ctx, vdisp_t *jsthis, jsval_t *r)
{
FunctionInstance *function = (FunctionInstance*)jsthis->u.jsdisp;
jsstr_t *str;
HRESULT hres;
TRACE("\n");
hres = function_to_string(function, &str);
if(FAILED(hres))
return hres;
*r = jsval_string(str);
break;
}
case DISPATCH_CONSTRUCT:
assert(function->value_proc != NULL);
return invoke_value_proc(ctx, function, NULL, flags, argc, argv, r);
default:
FIXME("not implemented flags %x\n", flags);
return E_NOTIMPL;
}
return S_OK;
}
static HRESULT Function_arguments(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
unsigned argc, jsval_t *argv, jsval_t *r)
static HRESULT Function_get_arguments(script_ctx_t *ctx, vdisp_t *jsthis, jsval_t *r)
{
FunctionInstance *function = (FunctionInstance*)jsthis->u.jsdisp;
HRESULT hres = S_OK;
TRACE("\n");
switch(flags) {
case DISPATCH_PROPERTYGET: {
*r = function->arguments ? jsval_obj(jsdisp_addref(function->arguments)) : jsval_null();
break;
}
case DISPATCH_PROPERTYPUT:
break;
default:
FIXME("unimplemented flags %x\n", flags);
hres = E_NOTIMPL;
}
return hres;
return S_OK;
}
static void Function_destructor(jsdisp_t *dispex)
......@@ -602,15 +577,15 @@ static void Function_destructor(jsdisp_t *dispex)
static const builtin_prop_t Function_props[] = {
{applyW, Function_apply, PROPF_METHOD|2},
{argumentsW, Function_arguments, 0},
{argumentsW, NULL, 0, Function_get_arguments, builtin_set_const},
{callW, Function_call, PROPF_METHOD|1},
{lengthW, Function_length, 0},
{lengthW, NULL, 0, Function_get_length, Function_set_length},
{toStringW, Function_toString, PROPF_METHOD}
};
static const builtin_info_t Function_info = {
JSCLASS_FUNCTION,
{NULL, Function_value, 0},
DEFAULT_FUNCTION_VALUE,
sizeof(Function_props)/sizeof(*Function_props),
Function_props,
Function_destructor,
......@@ -618,13 +593,13 @@ static const builtin_info_t Function_info = {
};
static const builtin_prop_t FunctionInst_props[] = {
{argumentsW, Function_arguments, 0},
{lengthW, Function_length, 0}
{argumentsW, NULL, 0, Function_get_arguments, builtin_set_const},
{lengthW, NULL, 0, Function_get_length, Function_set_length}
};
static const builtin_info_t FunctionInst_info = {
JSCLASS_FUNCTION,
{NULL, Function_value, 0},
DEFAULT_FUNCTION_VALUE,
sizeof(FunctionInst_props)/sizeof(*FunctionInst_props),
FunctionInst_props,
Function_destructor,
......
......@@ -187,11 +187,17 @@ static inline jsdisp_t *get_jsdisp(vdisp_t *vdisp)
}
typedef HRESULT (*builtin_invoke_t)(script_ctx_t*,vdisp_t*,WORD,unsigned,jsval_t*,jsval_t*);
typedef HRESULT (*builtin_getter_t)(script_ctx_t*,vdisp_t*,jsval_t*);
typedef HRESULT (*builtin_setter_t)(script_ctx_t*,vdisp_t*,jsval_t);
HRESULT builtin_set_const(script_ctx_t*,vdisp_t*,jsval_t) DECLSPEC_HIDDEN;
typedef struct {
const WCHAR *name;
builtin_invoke_t invoke;
DWORD flags;
builtin_getter_t getter;
builtin_setter_t setter;
} builtin_prop_t;
typedef struct {
......@@ -287,9 +293,12 @@ 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,jsval_t*,jsval_t*) DECLSPEC_HIDDEN;
HRESULT Function_invoke(jsdisp_t*,IDispatch*,WORD,unsigned,jsval_t*,jsval_t*) DECLSPEC_HIDDEN;
HRESULT Function_value(script_ctx_t*,vdisp_t*,WORD,unsigned,jsval_t*,jsval_t*) DECLSPEC_HIDDEN;
HRESULT Function_get_value(script_ctx_t*,vdisp_t*,jsval_t*) DECLSPEC_HIDDEN;
#define DEFAULT_FUNCTION_VALUE {NULL, Function_value,0, Function_get_value}
HRESULT throw_eval_error(script_ctx_t*,HRESULT,const WCHAR*) DECLSPEC_HIDDEN;
HRESULT throw_generic_error(script_ctx_t*,HRESULT,const WCHAR*) DECLSPEC_HIDDEN;
HRESULT throw_range_error(script_ctx_t*,HRESULT,const WCHAR*) DECLSPEC_HIDDEN;
......
......@@ -500,23 +500,13 @@ static HRESULT Number_valueOf(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
return S_OK;
}
static HRESULT Number_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
jsval_t *r)
static HRESULT Number_get_value(script_ctx_t *ctx, vdisp_t *jsthis, jsval_t *r)
{
NumberInstance *number = number_from_vdisp(jsthis);
switch(flags) {
case INVOKE_FUNC:
return throw_type_error(ctx, JS_E_FUNCTION_EXPECTED, NULL);
case DISPATCH_PROPERTYGET:
*r = jsval_number(number->value);
break;
default:
FIXME("flags %x\n", flags);
return E_NOTIMPL;
}
TRACE("(%p)\n", number);
*r = jsval_number(number->value);
return S_OK;
}
......@@ -531,7 +521,7 @@ static const builtin_prop_t Number_props[] = {
static const builtin_info_t Number_info = {
JSCLASS_NUMBER,
{NULL, Number_value, 0},
{NULL, NULL,0, Number_get_value},
sizeof(Number_props)/sizeof(*Number_props),
Number_props,
NULL,
......@@ -540,7 +530,7 @@ static const builtin_info_t Number_info = {
static const builtin_info_t NumberInst_info = {
JSCLASS_NUMBER,
{NULL, Number_value, 0},
{NULL, NULL,0, Number_get_value},
0, NULL,
NULL,
NULL
......
......@@ -207,26 +207,17 @@ static HRESULT Object_isPrototypeOf(script_ctx_t *ctx, vdisp_t *jsthis, WORD fla
return E_NOTIMPL;
}
static HRESULT Object_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
jsval_t *r)
static HRESULT Object_get_value(script_ctx_t *ctx, vdisp_t *jsthis, jsval_t *r)
{
jsstr_t *ret;
TRACE("\n");
switch(flags) {
case INVOKE_FUNC:
return throw_type_error(ctx, JS_E_FUNCTION_EXPECTED, NULL);
case DISPATCH_PROPERTYGET: {
jsstr_t *ret = jsstr_alloc(default_valueW);
ret = jsstr_alloc(default_valueW);
if(!ret)
return E_OUTOFMEMORY;
*r = jsval_string(ret);
break;
}
default:
FIXME("unimplemented flags %x\n", flags);
return E_NOTIMPL;
}
*r = jsval_string(ret);
return S_OK;
}
......@@ -246,7 +237,7 @@ static const builtin_prop_t Object_props[] = {
static const builtin_info_t Object_info = {
JSCLASS_OBJECT,
{NULL, Object_value, 0},
{NULL, NULL,0, Object_get_value},
sizeof(Object_props)/sizeof(*Object_props),
Object_props,
Object_destructor,
......@@ -255,7 +246,7 @@ static const builtin_info_t Object_info = {
static const builtin_info_t ObjectInst_info = {
JSCLASS_OBJECT,
{NULL, Object_value, 0},
{NULL, NULL,0, Object_get_value},
0, NULL,
Object_destructor,
NULL
......
......@@ -106,26 +106,22 @@ static HRESULT get_string_flat_val(script_ctx_t *ctx, vdisp_t *jsthis, jsstr_t *
return E_OUTOFMEMORY;
}
static HRESULT String_length(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
jsval_t *r)
static HRESULT String_get_length(script_ctx_t *ctx, vdisp_t *jsthis, jsval_t *r)
{
TRACE("%p\n", jsthis);
switch(flags) {
case DISPATCH_PROPERTYGET: {
StringInstance *string = string_from_vdisp(jsthis);
*r = jsval_number(jsstr_length(string->str));
break;
}
default:
FIXME("unimplemented flags %x\n", flags);
return E_NOTIMPL;
}
TRACE("%p\n", jsthis);
*r = jsval_number(jsstr_length(string->str));
return S_OK;
}
static HRESULT String_set_length(script_ctx_t *ctx, vdisp_t *jsthis, jsval_t value)
{
FIXME("%p\n", jsthis);
return E_NOTIMPL;
}
static HRESULT stringobj_to_string(vdisp_t *jsthis, jsval_t *r)
{
StringInstance *string;
......@@ -1471,25 +1467,13 @@ static HRESULT String_localeCompare(script_ctx_t *ctx, vdisp_t *jsthis, WORD fla
return E_NOTIMPL;
}
static HRESULT String_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv,
jsval_t *r)
static HRESULT String_get_value(script_ctx_t *ctx, vdisp_t *jsthis, jsval_t *r)
{
StringInstance *This = string_from_vdisp(jsthis);
TRACE("\n");
switch(flags) {
case INVOKE_FUNC:
return throw_type_error(ctx, JS_E_FUNCTION_EXPECTED, NULL);
case DISPATCH_PROPERTYGET: {
*r = jsval_string(jsstr_addref(This->str));
break;
}
default:
FIXME("flags %x\n", flags);
return E_NOTIMPL;
}
return S_OK;
}
......@@ -1544,7 +1528,7 @@ static const builtin_prop_t String_props[] = {
{indexOfW, String_indexOf, PROPF_METHOD|2},
{italicsW, String_italics, PROPF_METHOD},
{lastIndexOfW, String_lastIndexOf, PROPF_METHOD|2},
{lengthW, String_length, 0},
{lengthW, NULL,0, String_get_length, String_set_length},
{linkW, String_link, PROPF_METHOD|1},
{localeCompareW, String_localeCompare, PROPF_METHOD|1},
{matchW, String_match, PROPF_METHOD|1},
......@@ -1568,7 +1552,7 @@ static const builtin_prop_t String_props[] = {
static const builtin_info_t String_info = {
JSCLASS_STRING,
{NULL, String_value, 0},
{NULL, NULL,0, String_get_value},
sizeof(String_props)/sizeof(*String_props),
String_props,
String_destructor,
......@@ -1576,12 +1560,12 @@ static const builtin_info_t String_info = {
};
static const builtin_prop_t StringInst_props[] = {
{lengthW, String_length, 0}
{lengthW, NULL,0, String_get_length, String_set_length}
};
static const builtin_info_t StringInst_info = {
JSCLASS_STRING,
{NULL, String_value, 0},
{NULL, NULL,0, String_get_value},
sizeof(StringInst_props)/sizeof(*StringInst_props),
StringInst_props,
String_destructor,
......@@ -1699,7 +1683,7 @@ static const builtin_prop_t StringConstr_props[] = {
static const builtin_info_t StringConstr_info = {
JSCLASS_FUNCTION,
{NULL, Function_value, 0},
DEFAULT_FUNCTION_VALUE,
sizeof(StringConstr_props)/sizeof(*StringConstr_props),
StringConstr_props,
NULL,
......
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