mirror of
https://github.com/reactos/reactos.git
synced 2024-07-02 10:45:24 +00:00
[JSCRIPT]
sync jscript to wine 1.1.39 svn path=/trunk/; revision=45765
This commit is contained in:
parent
72a689d62e
commit
8c353150ee
|
@ -86,7 +86,7 @@ static IUnknown *create_activex_object(script_ctx_t *ctx, const WCHAR *progid)
|
|||
if(FAILED(hres) || policy != URLPOLICY_ALLOW)
|
||||
return NULL;
|
||||
|
||||
hres = CoGetClassObject(&guid, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER, NULL, &IID_IClassFactory, (void**)&cf);
|
||||
hres = CoGetClassObject(&guid, CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER, NULL, &IID_IClassFactory, (void**)&cf);
|
||||
if(FAILED(hres))
|
||||
return NULL;
|
||||
|
||||
|
@ -192,7 +192,8 @@ HRESULT create_activex_constr(script_ctx_t *ctx, DispatchEx **ret)
|
|||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
hres = create_builtin_function(ctx, ActiveXObject_value, ActiveXObjectW, NULL, PROPF_CONSTR, prototype, ret);
|
||||
hres = create_builtin_function(ctx, ActiveXObject_value, ActiveXObjectW, NULL,
|
||||
PROPF_CONSTR|1, prototype, ret);
|
||||
|
||||
jsdisp_release(prototype);
|
||||
return hres;
|
||||
|
|
|
@ -166,7 +166,7 @@ static HRESULT concat_array(DispatchEx *array, ArrayInstance *obj, DWORD *len,
|
|||
HRESULT hres;
|
||||
|
||||
for(i=0; i < obj->length; i++) {
|
||||
hres = jsdisp_propget_idx(&obj->dispex, i, &var, ei, caller);
|
||||
hres = jsdisp_get_idx(&obj->dispex, i, &var, ei, caller);
|
||||
if(hres == DISP_E_UNKNOWNNAME)
|
||||
continue;
|
||||
if(FAILED(hres))
|
||||
|
@ -267,8 +267,11 @@ static HRESULT array_join(script_ctx_t *ctx, DispatchEx *array, DWORD length, co
|
|||
return E_OUTOFMEMORY;
|
||||
|
||||
for(i=0; i < length; i++) {
|
||||
hres = jsdisp_propget_idx(array, i, &var, ei, caller);
|
||||
if(FAILED(hres))
|
||||
hres = jsdisp_get_idx(array, i, &var, ei, caller);
|
||||
if(hres == DISP_E_UNKNOWNNAME) {
|
||||
hres = S_OK;
|
||||
continue;
|
||||
} else if(FAILED(hres))
|
||||
break;
|
||||
|
||||
if(V_VT(&var) != VT_EMPTY && V_VT(&var) != VT_NULL)
|
||||
|
@ -342,20 +345,18 @@ static HRESULT array_join(script_ctx_t *ctx, DispatchEx *array, DWORD length, co
|
|||
}
|
||||
|
||||
/* ECMA-262 3rd Edition 15.4.4.5 */
|
||||
static HRESULT Array_join(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
|
||||
static HRESULT Array_join(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, DISPPARAMS *dp,
|
||||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
|
||||
{
|
||||
DispatchEx *jsthis;
|
||||
DWORD length;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("\n");
|
||||
|
||||
if(is_vclass(jsthis, JSCLASS_ARRAY)) {
|
||||
length = array_from_vdisp(jsthis)->length;
|
||||
}else {
|
||||
FIXME("dispid is not Array\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
hres = get_length(ctx, vthis, ei, &jsthis, &length);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
if(arg_cnt(dp)) {
|
||||
BSTR sep;
|
||||
|
@ -364,62 +365,52 @@ static HRESULT Array_join(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPA
|
|||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
hres = array_join(ctx, jsthis->u.jsdisp, length, sep, retv, ei, caller);
|
||||
hres = array_join(ctx, jsthis, length, sep, retv, ei, caller);
|
||||
|
||||
SysFreeString(sep);
|
||||
}else {
|
||||
hres = array_join(ctx, jsthis->u.jsdisp, length, default_separatorW, retv, ei, caller);
|
||||
hres = array_join(ctx, jsthis, length, default_separatorW, retv, ei, caller);
|
||||
}
|
||||
|
||||
return hres;
|
||||
}
|
||||
|
||||
static HRESULT Array_pop(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
|
||||
static HRESULT Array_pop(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, DISPPARAMS *dp,
|
||||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
|
||||
{
|
||||
DispatchEx *jsthis;
|
||||
VARIANT val;
|
||||
DWORD length;
|
||||
WCHAR buf[14];
|
||||
DISPID id;
|
||||
HRESULT hres;
|
||||
|
||||
static const WCHAR formatW[] = {'%','d',0};
|
||||
|
||||
TRACE("\n");
|
||||
|
||||
if(is_vclass(jsthis, JSCLASS_ARRAY)) {
|
||||
ArrayInstance *array = array_from_vdisp(jsthis);
|
||||
length = array->length;
|
||||
}else {
|
||||
FIXME("not Array this\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
hres = get_length(ctx, vthis, ei, &jsthis, &length);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
if(!length) {
|
||||
hres = set_length(jsthis, ei, 0);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
if(retv)
|
||||
V_VT(retv) = VT_EMPTY;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
sprintfW(buf, formatW, --length);
|
||||
hres = jsdisp_get_id(jsthis->u.jsdisp, buf, 0, &id);
|
||||
length--;
|
||||
hres = jsdisp_get_idx(jsthis, length, &val, ei, caller);
|
||||
if(SUCCEEDED(hres)) {
|
||||
hres = jsdisp_propget(jsthis->u.jsdisp, id, &val, ei, caller);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
hres = IDispatchEx_DeleteMemberByDispID(jsthis->u.dispex, id);
|
||||
}else if(hres == DISP_E_UNKNOWNNAME) {
|
||||
hres = jsdisp_delete_idx(jsthis, length);
|
||||
} else if(hres == DISP_E_UNKNOWNNAME) {
|
||||
V_VT(&val) = VT_EMPTY;
|
||||
hres = S_OK;
|
||||
}else {
|
||||
} else
|
||||
return hres;
|
||||
}
|
||||
|
||||
if(SUCCEEDED(hres)) {
|
||||
ArrayInstance *array = array_from_vdisp(jsthis);
|
||||
array->length = length;
|
||||
}
|
||||
if(SUCCEEDED(hres))
|
||||
hres = set_length(jsthis, ei, length);
|
||||
|
||||
if(FAILED(hres)) {
|
||||
VariantClear(&val);
|
||||
|
@ -430,6 +421,7 @@ static HRESULT Array_pop(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPAR
|
|||
*retv = val;
|
||||
else
|
||||
VariantClear(&val);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -469,8 +461,59 @@ static HRESULT Array_push(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, DISPPAR
|
|||
static HRESULT Array_reverse(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, DISPPARAMS *dp,
|
||||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
DispatchEx *jsthis;
|
||||
DWORD length, k, l;
|
||||
VARIANT v1, v2;
|
||||
HRESULT hres1, hres2;
|
||||
|
||||
TRACE("\n");
|
||||
|
||||
hres1 = get_length(ctx, vthis, ei, &jsthis, &length);
|
||||
if(FAILED(hres1))
|
||||
return hres1;
|
||||
|
||||
for(k=0; k<length/2; k++) {
|
||||
l = length-k-1;
|
||||
|
||||
hres1 = jsdisp_get_idx(jsthis, k, &v1, ei, sp);
|
||||
if(FAILED(hres1) && hres1!=DISP_E_UNKNOWNNAME)
|
||||
return hres1;
|
||||
|
||||
hres2 = jsdisp_get_idx(jsthis, l, &v2, ei, sp);
|
||||
if(FAILED(hres2) && hres2!=DISP_E_UNKNOWNNAME) {
|
||||
VariantClear(&v1);
|
||||
return hres2;
|
||||
}
|
||||
|
||||
if(hres1 == DISP_E_UNKNOWNNAME)
|
||||
hres1 = jsdisp_delete_idx(jsthis, l);
|
||||
else
|
||||
hres1 = jsdisp_propput_idx(jsthis, l, &v1, ei, sp);
|
||||
|
||||
if(FAILED(hres1)) {
|
||||
VariantClear(&v1);
|
||||
VariantClear(&v2);
|
||||
return hres1;
|
||||
}
|
||||
|
||||
if(hres2 == DISP_E_UNKNOWNNAME)
|
||||
hres2 = jsdisp_delete_idx(jsthis, k);
|
||||
else
|
||||
hres2 = jsdisp_propput_idx(jsthis, k, &v2, ei, sp);
|
||||
|
||||
if(FAILED(hres2)) {
|
||||
VariantClear(&v2);
|
||||
return hres2;
|
||||
}
|
||||
}
|
||||
|
||||
if(retv) {
|
||||
V_VT(retv) = VT_DISPATCH;
|
||||
V_DISPATCH(retv) = (IDispatch*)_IDispatchEx_(jsthis);
|
||||
IDispatch_AddRef(V_DISPATCH(retv));
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/* ECMA-262 3rd Edition 15.4.4.9 */
|
||||
|
@ -500,14 +543,14 @@ static HRESULT Array_shift(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, DISPPA
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
hres = jsdisp_propget_idx(jsthis, 0, &ret, ei, caller);
|
||||
hres = jsdisp_get_idx(jsthis, 0, &ret, ei, caller);
|
||||
if(hres == DISP_E_UNKNOWNNAME) {
|
||||
V_VT(&ret) = VT_EMPTY;
|
||||
hres = S_OK;
|
||||
}
|
||||
|
||||
for(i=1; SUCCEEDED(hres) && i<length; i++) {
|
||||
hres = jsdisp_propget_idx(jsthis, i, &v, ei, caller);
|
||||
hres = jsdisp_get_idx(jsthis, i, &v, ei, caller);
|
||||
if(hres == DISP_E_UNKNOWNNAME)
|
||||
hres = jsdisp_delete_idx(jsthis, i-1);
|
||||
else if(SUCCEEDED(hres))
|
||||
|
@ -582,12 +625,14 @@ static HRESULT Array_slice(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, DISPPA
|
|||
return hres;
|
||||
|
||||
for(idx=start; idx<end; idx++) {
|
||||
hres = jsdisp_propget_idx(jsthis, idx, &v, ei, sp);
|
||||
hres = jsdisp_get_idx(jsthis, idx, &v, ei, sp);
|
||||
if(hres == DISP_E_UNKNOWNNAME)
|
||||
continue;
|
||||
|
||||
if(SUCCEEDED(hres))
|
||||
if(SUCCEEDED(hres)) {
|
||||
hres = jsdisp_propput_idx(arr, idx-start, &v, ei, sp);
|
||||
VariantClear(&v);
|
||||
}
|
||||
|
||||
if(FAILED(hres)) {
|
||||
jsdisp_release(arr);
|
||||
|
@ -661,10 +706,10 @@ static HRESULT sort_cmp(script_ctx_t *ctx, DispatchEx *cmp_func, VARIANT *v1, VA
|
|||
}
|
||||
|
||||
/* ECMA-262 3rd Edition 15.4.4.11 */
|
||||
static HRESULT Array_sort(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
|
||||
static HRESULT Array_sort(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, DISPPARAMS *dp,
|
||||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
|
||||
{
|
||||
DispatchEx *cmp_func = NULL;
|
||||
DispatchEx *jsthis, *cmp_func = NULL;
|
||||
VARIANT *vtab, **sorttab = NULL;
|
||||
DWORD length;
|
||||
DWORD i;
|
||||
|
@ -672,12 +717,9 @@ static HRESULT Array_sort(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPA
|
|||
|
||||
TRACE("\n");
|
||||
|
||||
if(is_vclass(jsthis, JSCLASS_ARRAY)) {
|
||||
length = array_from_vdisp(jsthis)->length;
|
||||
}else {
|
||||
FIXME("unsupported this not array\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
hres = get_length(ctx, vthis, ei, &jsthis, &length);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
if(arg_cnt(dp) > 1) {
|
||||
WARN("invalid arg_cnt %d\n", arg_cnt(dp));
|
||||
|
@ -707,8 +749,8 @@ static HRESULT Array_sort(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPA
|
|||
jsdisp_release(cmp_func);
|
||||
if(retv) {
|
||||
V_VT(retv) = VT_DISPATCH;
|
||||
V_DISPATCH(retv) = jsthis->u.disp;
|
||||
IDispatch_AddRef(jsthis->u.disp);
|
||||
V_DISPATCH(retv) = (IDispatch*)_IDispatchEx_(jsthis);
|
||||
IDispatch_AddRef(V_DISPATCH(retv));
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
@ -716,8 +758,11 @@ static HRESULT Array_sort(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPA
|
|||
vtab = heap_alloc_zero(length * sizeof(VARIANT));
|
||||
if(vtab) {
|
||||
for(i=0; i<length; i++) {
|
||||
hres = jsdisp_propget_idx(jsthis->u.jsdisp, i, vtab+i, ei, caller);
|
||||
if(FAILED(hres) && hres != DISP_E_UNKNOWNNAME) {
|
||||
hres = jsdisp_get_idx(jsthis, i, vtab+i, ei, caller);
|
||||
if(hres == DISP_E_UNKNOWNNAME) {
|
||||
V_VT(vtab+i) = VT_EMPTY;
|
||||
hres = S_OK;
|
||||
} else if(FAILED(hres)) {
|
||||
WARN("Could not get elem %d: %08x\n", i, hres);
|
||||
break;
|
||||
}
|
||||
|
@ -793,7 +838,7 @@ static HRESULT Array_sort(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPA
|
|||
}
|
||||
|
||||
for(i=0; SUCCEEDED(hres) && i < length; i++)
|
||||
hres = jsdisp_propput_idx(jsthis->u.jsdisp, i, sorttab[i], ei, caller);
|
||||
hres = jsdisp_propput_idx(jsthis, i, sorttab[i], ei, caller);
|
||||
}
|
||||
|
||||
if(vtab) {
|
||||
|
@ -810,8 +855,8 @@ static HRESULT Array_sort(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPA
|
|||
|
||||
if(retv) {
|
||||
V_VT(retv) = VT_DISPATCH;
|
||||
V_DISPATCH(retv) = jsthis->u.disp;
|
||||
IDispatch_AddRef(jsthis->u.disp);
|
||||
V_DISPATCH(retv) = (IDispatch*)_IDispatchEx_(jsthis);
|
||||
IDispatch_AddRef(V_DISPATCH(retv));
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
|
@ -869,7 +914,7 @@ static HRESULT Array_splice(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, DISPP
|
|||
return hres;
|
||||
|
||||
for(i=0; SUCCEEDED(hres) && i < delete_cnt; i++) {
|
||||
hres = jsdisp_propget_idx(jsthis, start+i, &v, ei, caller);
|
||||
hres = jsdisp_get_idx(jsthis, start+i, &v, ei, caller);
|
||||
if(hres == DISP_E_UNKNOWNNAME)
|
||||
hres = S_OK;
|
||||
else if(SUCCEEDED(hres))
|
||||
|
@ -886,7 +931,7 @@ static HRESULT Array_splice(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, DISPP
|
|||
|
||||
if(add_args < delete_cnt) {
|
||||
for(i = start; SUCCEEDED(hres) && i < length-delete_cnt; i++) {
|
||||
hres = jsdisp_propget_idx(jsthis, i+delete_cnt, &v, ei, caller);
|
||||
hres = jsdisp_get_idx(jsthis, i+delete_cnt, &v, ei, caller);
|
||||
if(hres == DISP_E_UNKNOWNNAME)
|
||||
hres = jsdisp_delete_idx(jsthis, i+add_args);
|
||||
else if(SUCCEEDED(hres))
|
||||
|
@ -897,7 +942,7 @@ static HRESULT Array_splice(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, DISPP
|
|||
hres = jsdisp_delete_idx(jsthis, i-1);
|
||||
}else if(add_args > delete_cnt) {
|
||||
for(i=length-delete_cnt; SUCCEEDED(hres) && i != start; i--) {
|
||||
hres = jsdisp_propget_idx(jsthis, i+delete_cnt-1, &v, ei, caller);
|
||||
hres = jsdisp_get_idx(jsthis, i+delete_cnt-1, &v, ei, caller);
|
||||
if(hres == DISP_E_UNKNOWNNAME)
|
||||
hres = jsdisp_delete_idx(jsthis, i+add_args-1);
|
||||
else if(SUCCEEDED(hres))
|
||||
|
@ -967,29 +1012,25 @@ static HRESULT Array_unshift(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, DISP
|
|||
return hres;
|
||||
|
||||
argc = arg_cnt(dp);
|
||||
if(!argc) {
|
||||
if(retv)
|
||||
V_VT(retv) = VT_EMPTY;
|
||||
return S_OK;
|
||||
}
|
||||
if(argc) {
|
||||
buf_end = buf + sizeof(buf)/sizeof(WCHAR)-1;
|
||||
*buf_end-- = 0;
|
||||
i = length;
|
||||
|
||||
buf_end = buf + sizeof(buf)/sizeof(WCHAR)-1;
|
||||
*buf_end-- = 0;
|
||||
i = length;
|
||||
while(i--) {
|
||||
str = idx_to_str(i, buf_end);
|
||||
|
||||
while(i--) {
|
||||
str = idx_to_str(i, buf_end);
|
||||
hres = jsdisp_get_id(jsthis, str, 0, &id);
|
||||
if(SUCCEEDED(hres)) {
|
||||
hres = jsdisp_propget(jsthis, id, &var, ei, caller);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
hres = jsdisp_get_id(jsthis, str, 0, &id);
|
||||
if(SUCCEEDED(hres)) {
|
||||
hres = jsdisp_propget(jsthis, id, &var, ei, caller);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
hres = jsdisp_propput_idx(jsthis, i+argc, &var, ei, caller);
|
||||
VariantClear(&var);
|
||||
}else if(hres == DISP_E_UNKNOWNNAME) {
|
||||
hres = IDispatchEx_DeleteMemberByDispID(vthis->u.dispex, id);
|
||||
hres = jsdisp_propput_idx(jsthis, i+argc, &var, ei, caller);
|
||||
VariantClear(&var);
|
||||
}else if(hres == DISP_E_UNKNOWNNAME) {
|
||||
hres = IDispatchEx_DeleteMemberByDispID(vthis->u.dispex, id);
|
||||
}
|
||||
}
|
||||
|
||||
if(FAILED(hres))
|
||||
|
@ -1002,12 +1043,21 @@ static HRESULT Array_unshift(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, DISP
|
|||
return hres;
|
||||
}
|
||||
|
||||
hres = set_length(jsthis, ei, length+argc);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
if(argc) {
|
||||
length += argc;
|
||||
hres = set_length(jsthis, ei, length);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
}
|
||||
|
||||
if(retv)
|
||||
V_VT(retv) = VT_EMPTY;
|
||||
if(retv) {
|
||||
if(ctx->version < 2) {
|
||||
V_VT(retv) = VT_EMPTY;
|
||||
}else {
|
||||
V_VT(retv) = VT_I4;
|
||||
V_I4(retv) = length;
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -1166,7 +1216,7 @@ HRESULT create_array_constr(script_ctx_t *ctx, DispatchEx *object_prototype, Dis
|
|||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
hres = create_builtin_function(ctx, ArrayConstr_value, ArrayW, NULL, PROPF_CONSTR, &array->dispex, ret);
|
||||
hres = create_builtin_function(ctx, ArrayConstr_value, ArrayW, NULL, PROPF_CONSTR|1, &array->dispex, ret);
|
||||
|
||||
jsdisp_release(&array->dispex);
|
||||
return hres;
|
||||
|
|
|
@ -191,7 +191,8 @@ HRESULT create_bool_constr(script_ctx_t *ctx, DispatchEx *object_prototype, Disp
|
|||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
hres = create_builtin_function(ctx, BoolConstr_value, BooleanW, NULL, PROPF_CONSTR, &bool->dispex, ret);
|
||||
hres = create_builtin_function(ctx, BoolConstr_value, BooleanW, NULL,
|
||||
PROPF_CONSTR|1, &bool->dispex, ret);
|
||||
|
||||
jsdisp_release(&bool->dispex);
|
||||
return hres;
|
||||
|
|
|
@ -2624,7 +2624,8 @@ HRESULT create_date_constr(script_ctx_t *ctx, DispatchEx *object_prototype, Disp
|
|||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
hres = create_builtin_function(ctx, DateConstr_value, DateW, &DateConstr_info, PROPF_CONSTR, date, ret);
|
||||
hres = create_builtin_function(ctx, DateConstr_value, DateW, &DateConstr_info,
|
||||
PROPF_CONSTR|7, date, ret);
|
||||
|
||||
jsdisp_release(date);
|
||||
return hres;
|
||||
|
|
|
@ -30,6 +30,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(jscript);
|
|||
static const IID IID_IDispatchJS =
|
||||
{0x719c3050,0xf9d3,0x11cf,{0xa4,0x93,0x00,0x40,0x05,0x23,0xa8,0xa6}};
|
||||
|
||||
#define FDEX_VERSION_MASK 0xf0000000
|
||||
|
||||
typedef enum {
|
||||
PROP_VARIANT,
|
||||
PROP_BUILTIN,
|
||||
|
@ -158,7 +160,7 @@ static HRESULT find_prop_name(DispatchEx *This, const WCHAR *name, dispex_prop_t
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT find_prop_name_prot(DispatchEx *This, const WCHAR *name, BOOL alloc, dispex_prop_t **ret)
|
||||
static HRESULT find_prop_name_prot(DispatchEx *This, const WCHAR *name, dispex_prop_t **ret)
|
||||
{
|
||||
dispex_prop_t *prop;
|
||||
HRESULT hres;
|
||||
|
@ -172,7 +174,7 @@ static HRESULT find_prop_name_prot(DispatchEx *This, const WCHAR *name, BOOL all
|
|||
}
|
||||
|
||||
if(This->prototype) {
|
||||
hres = find_prop_name_prot(This->prototype, name, FALSE, &prop);
|
||||
hres = find_prop_name_prot(This->prototype, name, &prop);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
if(prop) {
|
||||
|
@ -184,17 +186,30 @@ static HRESULT find_prop_name_prot(DispatchEx *This, const WCHAR *name, BOOL all
|
|||
}
|
||||
}
|
||||
|
||||
if(alloc) {
|
||||
*ret = prop;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT ensure_prop_name(DispatchEx *This, const WCHAR *name, BOOL search_prot, DWORD create_flags, dispex_prop_t **ret)
|
||||
{
|
||||
dispex_prop_t *prop;
|
||||
HRESULT hres;
|
||||
|
||||
if(search_prot)
|
||||
hres = find_prop_name_prot(This, name, &prop);
|
||||
else
|
||||
hres = find_prop_name(This, name, &prop);
|
||||
if(SUCCEEDED(hres) && !prop) {
|
||||
TRACE("creating prop %s\n", debugstr_w(name));
|
||||
|
||||
prop = alloc_prop(This, name, PROP_VARIANT, PROPF_ENUM);
|
||||
prop = alloc_prop(This, name, PROP_VARIANT, create_flags);
|
||||
if(!prop)
|
||||
return E_OUTOFMEMORY;
|
||||
VariantInit(&prop->u.var);
|
||||
}
|
||||
|
||||
*ret = prop;
|
||||
return S_OK;
|
||||
return hres;
|
||||
}
|
||||
|
||||
static HRESULT set_this(DISPPARAMS *dp, DISPPARAMS *olddp, IDispatch *jsthis)
|
||||
|
@ -338,19 +353,19 @@ static HRESULT prop_get(DispatchEx *This, dispex_prop_t *prop, DISPPARAMS *dp,
|
|||
return hres;
|
||||
}
|
||||
|
||||
static HRESULT prop_put(DispatchEx *This, dispex_prop_t *prop, DISPPARAMS *dp,
|
||||
static HRESULT prop_put(DispatchEx *This, dispex_prop_t *prop, VARIANT *val,
|
||||
jsexcept_t *ei, IServiceProvider *caller)
|
||||
{
|
||||
DWORD i;
|
||||
HRESULT hres;
|
||||
|
||||
switch(prop->type) {
|
||||
case PROP_BUILTIN:
|
||||
if(!(prop->flags & PROPF_METHOD)) {
|
||||
DISPPARAMS dp = {val, NULL, 1, 0};
|
||||
vdisp_t vthis;
|
||||
|
||||
set_jsdisp(&vthis, This);
|
||||
hres = prop->u.p->invoke(This->ctx, &vthis, DISPATCH_PROPERTYPUT, dp, NULL, ei, caller);
|
||||
hres = prop->u.p->invoke(This->ctx, &vthis, DISPATCH_PROPERTYPUT, &dp, NULL, ei, caller);
|
||||
vdisp_release(&vthis);
|
||||
return hres;
|
||||
}
|
||||
|
@ -367,24 +382,14 @@ static HRESULT prop_put(DispatchEx *This, dispex_prop_t *prop, DISPPARAMS *dp,
|
|||
return E_FAIL;
|
||||
}
|
||||
|
||||
for(i=0; i < dp->cNamedArgs; i++) {
|
||||
if(dp->rgdispidNamedArgs[i] == DISPID_PROPERTYPUT)
|
||||
break;
|
||||
}
|
||||
|
||||
if(i == dp->cNamedArgs) {
|
||||
TRACE("no value to set\n");
|
||||
return DISP_E_PARAMNOTOPTIONAL;
|
||||
}
|
||||
|
||||
hres = VariantCopy(&prop->u.var, dp->rgvarg+i);
|
||||
hres = VariantCopy(&prop->u.var, val);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
if(This->builtin_info->on_put)
|
||||
This->builtin_info->on_put(This, prop->name);
|
||||
|
||||
TRACE("%s = %s\n", debugstr_w(prop->name), debugstr_variant(dp->rgvarg+i));
|
||||
TRACE("%s = %s\n", debugstr_w(prop->name), debugstr_variant(val));
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -471,6 +476,8 @@ static ULONG WINAPI DispatchEx_Release(IDispatchEx *iface)
|
|||
}
|
||||
heap_free(This->props);
|
||||
script_release(This->ctx);
|
||||
if(This->prototype)
|
||||
jsdisp_release(This->prototype);
|
||||
|
||||
if(This->builtin_info->destructor)
|
||||
This->builtin_info->destructor(This);
|
||||
|
@ -538,7 +545,7 @@ static HRESULT WINAPI DispatchEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DW
|
|||
|
||||
TRACE("(%p)->(%s %x %p)\n", This, debugstr_w(bstrName), grfdex, pid);
|
||||
|
||||
if(grfdex & ~(fdexNameCaseSensitive|fdexNameEnsure|fdexNameImplicit)) {
|
||||
if(grfdex & ~(fdexNameCaseSensitive|fdexNameEnsure|fdexNameImplicit|FDEX_VERSION_MASK)) {
|
||||
FIXME("Unsupported grfdex %x\n", grfdex);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
@ -575,9 +582,22 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
|
|||
case DISPATCH_PROPERTYGET:
|
||||
hres = prop_get(This, prop, pdp, pvarRes, &jsexcept, pspCaller);
|
||||
break;
|
||||
case DISPATCH_PROPERTYPUT:
|
||||
hres = prop_put(This, prop, pdp, &jsexcept, pspCaller);
|
||||
case DISPATCH_PROPERTYPUT: {
|
||||
DWORD i;
|
||||
|
||||
for(i=0; i < pdp->cNamedArgs; i++) {
|
||||
if(pdp->rgdispidNamedArgs[i] == DISPID_PROPERTYPUT)
|
||||
break;
|
||||
}
|
||||
|
||||
if(i == pdp->cNamedArgs) {
|
||||
TRACE("no value to set\n");
|
||||
return DISP_E_PARAMNOTOPTIONAL;
|
||||
}
|
||||
|
||||
hres = prop_put(This, prop, pdp->rgvarg+i, &jsexcept, pspCaller);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
FIXME("Unimplemented flags %x\n", wFlags);
|
||||
return E_INVALIDARG;
|
||||
|
@ -606,7 +626,7 @@ static HRESULT WINAPI DispatchEx_DeleteMemberByName(IDispatchEx *iface, BSTR bst
|
|||
|
||||
TRACE("(%p)->(%s %x)\n", This, debugstr_w(bstrName), grfdex);
|
||||
|
||||
if(grfdex & ~(fdexNameCaseSensitive|fdexNameEnsure|fdexNameImplicit))
|
||||
if(grfdex & ~(fdexNameCaseSensitive|fdexNameEnsure|fdexNameImplicit|FDEX_VERSION_MASK))
|
||||
FIXME("Unsupported grfdex %x\n", grfdex);
|
||||
|
||||
hres = find_prop_name(This, bstrName, &prop);
|
||||
|
@ -783,9 +803,10 @@ HRESULT init_dispex_from_constr(DispatchEx *dispex, script_ctx_t *ctx, const bui
|
|||
dispex_prop_t *prop;
|
||||
HRESULT hres;
|
||||
|
||||
static const WCHAR constructorW[] = {'c','o','n','s','t','r','u','c','t','o','r'};
|
||||
static const WCHAR prototypeW[] = {'p','r','o','t','o','t','y','p','e',0};
|
||||
|
||||
hres = find_prop_name_prot(constr, prototypeW, FALSE, &prop);
|
||||
hres = find_prop_name_prot(constr, prototypeW, &prop);
|
||||
if(SUCCEEDED(hres) && prop) {
|
||||
jsexcept_t jsexcept;
|
||||
VARIANT var;
|
||||
|
@ -807,6 +828,22 @@ HRESULT init_dispex_from_constr(DispatchEx *dispex, script_ctx_t *ctx, const bui
|
|||
|
||||
if(prot)
|
||||
jsdisp_release(prot);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
hres = ensure_prop_name(dispex, constructorW, FALSE, 0, &prop);
|
||||
if(SUCCEEDED(hres)) {
|
||||
jsexcept_t jsexcept;
|
||||
VARIANT var;
|
||||
|
||||
V_VT(&var) = VT_DISPATCH;
|
||||
V_DISPATCH(&var) = (IDispatch*)_IDispatchEx_(constr);
|
||||
memset(&jsexcept, 0, sizeof(jsexcept));
|
||||
hres = prop_put(dispex, prop, &var, &jsexcept, NULL/*FIXME*/);
|
||||
}
|
||||
if(FAILED(hres))
|
||||
jsdisp_release(dispex);
|
||||
|
||||
return hres;
|
||||
}
|
||||
|
||||
|
@ -827,7 +864,10 @@ HRESULT jsdisp_get_id(DispatchEx *jsdisp, const WCHAR *name, DWORD flags, DISPID
|
|||
dispex_prop_t *prop;
|
||||
HRESULT hres;
|
||||
|
||||
hres = find_prop_name_prot(jsdisp, name, (flags&fdexNameEnsure) != 0, &prop);
|
||||
if(flags & fdexNameEnsure)
|
||||
hres = ensure_prop_name(jsdisp, name, TRUE, PROPF_ENUM, &prop);
|
||||
else
|
||||
hres = find_prop_name_prot(jsdisp, name, &prop);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
|
@ -874,7 +914,7 @@ HRESULT jsdisp_call_name(DispatchEx *disp, const WCHAR *name, WORD flags, DISPPA
|
|||
dispex_prop_t *prop;
|
||||
HRESULT hres;
|
||||
|
||||
hres = find_prop_name_prot(disp, name, TRUE, &prop);
|
||||
hres = find_prop_name_prot(disp, name, &prop);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
|
@ -924,16 +964,14 @@ HRESULT disp_call(script_ctx_t *ctx, IDispatch *disp, DISPID id, WORD flags, DIS
|
|||
|
||||
HRESULT jsdisp_propput_name(DispatchEx *obj, const WCHAR *name, VARIANT *val, jsexcept_t *ei, IServiceProvider *caller)
|
||||
{
|
||||
DISPID named_arg = DISPID_PROPERTYPUT;
|
||||
DISPPARAMS dp = {val, &named_arg, 1, 1};
|
||||
dispex_prop_t *prop;
|
||||
HRESULT hres;
|
||||
|
||||
hres = find_prop_name_prot(obj, name, TRUE, &prop);
|
||||
hres = ensure_prop_name(obj, name, FALSE, PROPF_ENUM, &prop);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
return prop_put(obj, prop, &dp, ei, caller);
|
||||
return prop_put(obj, prop, val, ei, caller);
|
||||
}
|
||||
|
||||
HRESULT jsdisp_propput_idx(DispatchEx *obj, DWORD idx, VARIANT *val, jsexcept_t *ei, IServiceProvider *caller)
|
||||
|
@ -948,9 +986,6 @@ HRESULT jsdisp_propput_idx(DispatchEx *obj, DWORD idx, VARIANT *val, jsexcept_t
|
|||
|
||||
HRESULT disp_propput(script_ctx_t *ctx, IDispatch *disp, DISPID id, VARIANT *val, jsexcept_t *ei, IServiceProvider *caller)
|
||||
{
|
||||
DISPID dispid = DISPID_PROPERTYPUT;
|
||||
DISPPARAMS dp = {val, &dispid, 1, 1};
|
||||
IDispatchEx *dispex;
|
||||
DispatchEx *jsdisp;
|
||||
HRESULT hres;
|
||||
|
||||
|
@ -960,25 +995,28 @@ HRESULT disp_propput(script_ctx_t *ctx, IDispatch *disp, DISPID id, VARIANT *val
|
|||
|
||||
prop = get_prop(jsdisp, id);
|
||||
if(prop)
|
||||
hres = prop_put(jsdisp, prop, &dp, ei, caller);
|
||||
hres = prop_put(jsdisp, prop, val, ei, caller);
|
||||
else
|
||||
hres = DISP_E_MEMBERNOTFOUND;
|
||||
|
||||
jsdisp_release(jsdisp);
|
||||
return hres;
|
||||
}else {
|
||||
DISPID dispid = DISPID_PROPERTYPUT;
|
||||
DISPPARAMS dp = {val, &dispid, 1, 1};
|
||||
IDispatchEx *dispex;
|
||||
|
||||
hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
|
||||
if(SUCCEEDED(hres)) {
|
||||
hres = IDispatchEx_InvokeEx(dispex, id, ctx->lcid, DISPATCH_PROPERTYPUT, &dp, NULL, &ei->ei, caller);
|
||||
IDispatchEx_Release(dispex);
|
||||
}else {
|
||||
ULONG err = 0;
|
||||
|
||||
TRACE("using IDispatch\n");
|
||||
hres = IDispatch_Invoke(disp, id, &IID_NULL, ctx->lcid, DISPATCH_PROPERTYPUT, &dp, NULL, &ei->ei, &err);
|
||||
}
|
||||
}
|
||||
|
||||
hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
|
||||
if(FAILED(hres)) {
|
||||
ULONG err = 0;
|
||||
|
||||
TRACE("using IDispatch\n");
|
||||
return IDispatch_Invoke(disp, id, &IID_NULL, ctx->lcid, DISPATCH_PROPERTYPUT, &dp, NULL, &ei->ei, &err);
|
||||
}
|
||||
|
||||
hres = IDispatchEx_InvokeEx(dispex, id, ctx->lcid, DISPATCH_PROPERTYPUT, &dp, NULL, &ei->ei, caller);
|
||||
|
||||
IDispatchEx_Release(dispex);
|
||||
return hres;
|
||||
}
|
||||
|
||||
|
@ -988,7 +1026,7 @@ HRESULT jsdisp_propget_name(DispatchEx *obj, const WCHAR *name, VARIANT *var, js
|
|||
dispex_prop_t *prop;
|
||||
HRESULT hres;
|
||||
|
||||
hres = find_prop_name_prot(obj, name, FALSE, &prop);
|
||||
hres = find_prop_name_prot(obj, name, &prop);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
|
@ -999,14 +1037,26 @@ HRESULT jsdisp_propget_name(DispatchEx *obj, const WCHAR *name, VARIANT *var, js
|
|||
return prop_get(obj, prop, &dp, var, ei, caller);
|
||||
}
|
||||
|
||||
HRESULT jsdisp_propget_idx(DispatchEx *obj, DWORD idx, VARIANT *var, jsexcept_t *ei, IServiceProvider *caller)
|
||||
HRESULT jsdisp_get_idx(DispatchEx *obj, DWORD idx, VARIANT *var, jsexcept_t *ei, IServiceProvider *caller)
|
||||
{
|
||||
WCHAR buf[12];
|
||||
WCHAR name[12];
|
||||
DISPPARAMS dp = {NULL, NULL, 0, 0};
|
||||
dispex_prop_t *prop;
|
||||
HRESULT hres;
|
||||
|
||||
static const WCHAR formatW[] = {'%','d',0};
|
||||
|
||||
sprintfW(buf, formatW, idx);
|
||||
return jsdisp_propget_name(obj, buf, var, ei, caller);
|
||||
sprintfW(name, formatW, idx);
|
||||
|
||||
hres = find_prop_name_prot(obj, name, &prop);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
V_VT(var) = VT_EMPTY;
|
||||
if(!prop)
|
||||
return DISP_E_UNKNOWNNAME;
|
||||
|
||||
return prop_get(obj, prop, &dp, var, ei, caller);
|
||||
}
|
||||
|
||||
HRESULT jsdisp_propget(DispatchEx *jsdisp, DISPID id, VARIANT *val, jsexcept_t *ei, IServiceProvider *caller)
|
||||
|
|
|
@ -223,7 +223,7 @@ void exec_release(exec_ctx_t *ctx)
|
|||
heap_free(ctx);
|
||||
}
|
||||
|
||||
static HRESULT disp_get_id(IDispatch *disp, BSTR name, DWORD flags, DISPID *id)
|
||||
static HRESULT disp_get_id(script_ctx_t *ctx, IDispatch *disp, BSTR name, DWORD flags, DISPID *id)
|
||||
{
|
||||
IDispatchEx *dispex;
|
||||
HRESULT hres;
|
||||
|
@ -237,7 +237,7 @@ static HRESULT disp_get_id(IDispatch *disp, BSTR name, DWORD flags, DISPID *id)
|
|||
}
|
||||
|
||||
*id = 0;
|
||||
hres = IDispatchEx_GetDispID(dispex, name, flags|fdexNameCaseSensitive, id);
|
||||
hres = IDispatchEx_GetDispID(dispex, name, make_grfdex(ctx, flags|fdexNameCaseSensitive), id);
|
||||
IDispatchEx_Release(dispex);
|
||||
return hres;
|
||||
}
|
||||
|
@ -347,33 +347,45 @@ static HRESULT equal2_values(VARIANT *lval, VARIANT *rval, BOOL *ret)
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT literal_to_var(literal_t *literal, VARIANT *v)
|
||||
static HRESULT literal_to_var(script_ctx_t *ctx, literal_t *literal, VARIANT *v)
|
||||
{
|
||||
V_VT(v) = literal->vt;
|
||||
|
||||
switch(V_VT(v)) {
|
||||
case VT_EMPTY:
|
||||
case VT_NULL:
|
||||
switch(literal->type) {
|
||||
case LT_NULL:
|
||||
V_VT(v) = VT_NULL;
|
||||
break;
|
||||
case VT_I4:
|
||||
case LT_INT:
|
||||
V_VT(v) = VT_I4;
|
||||
V_I4(v) = literal->u.lval;
|
||||
break;
|
||||
case VT_R8:
|
||||
case LT_DOUBLE:
|
||||
V_VT(v) = VT_R8;
|
||||
V_R8(v) = literal->u.dval;
|
||||
break;
|
||||
case VT_BSTR:
|
||||
V_BSTR(v) = SysAllocString(literal->u.wstr);
|
||||
case LT_STRING: {
|
||||
BSTR str = SysAllocString(literal->u.wstr);
|
||||
if(!str)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
V_VT(v) = VT_BSTR;
|
||||
V_BSTR(v) = str;
|
||||
break;
|
||||
case VT_BOOL:
|
||||
}
|
||||
case LT_BOOL:
|
||||
V_VT(v) = VT_BOOL;
|
||||
V_BOOL(v) = literal->u.bval;
|
||||
break;
|
||||
case VT_DISPATCH:
|
||||
IDispatch_AddRef(literal->u.disp);
|
||||
V_DISPATCH(v) = literal->u.disp;
|
||||
break;
|
||||
default:
|
||||
ERR("wrong type %d\n", V_VT(v));
|
||||
return E_NOTIMPL;
|
||||
case LT_REGEXP: {
|
||||
DispatchEx *regexp;
|
||||
HRESULT hres;
|
||||
|
||||
hres = create_regexp(ctx, literal->u.regexp.str, literal->u.regexp.str_len,
|
||||
literal->u.regexp.flags, ®exp);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
V_VT(v) = VT_DISPATCH;
|
||||
V_DISPATCH(v) = (IDispatch*)_IDispatchEx_(regexp);
|
||||
}
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
|
@ -387,7 +399,7 @@ static BOOL lookup_global_members(script_ctx_t *ctx, BSTR identifier, exprval_t
|
|||
|
||||
for(item = ctx->named_items; item; item = item->next) {
|
||||
if(item->flags & SCRIPTITEM_GLOBALMEMBERS) {
|
||||
hres = disp_get_id(item->disp, identifier, 0, &id);
|
||||
hres = disp_get_id(ctx, item->disp, identifier, 0, &id);
|
||||
if(SUCCEEDED(hres)) {
|
||||
if(ret)
|
||||
exprval_set_idref(ret, item->disp, id);
|
||||
|
@ -399,7 +411,8 @@ static BOOL lookup_global_members(script_ctx_t *ctx, BSTR identifier, exprval_t
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
HRESULT exec_source(exec_ctx_t *ctx, parser_ctx_t *parser, source_elements_t *source, jsexcept_t *ei, VARIANT *retv)
|
||||
HRESULT exec_source(exec_ctx_t *ctx, parser_ctx_t *parser, source_elements_t *source, exec_type_t exec_type,
|
||||
jsexcept_t *ei, VARIANT *retv)
|
||||
{
|
||||
script_ctx_t *script = parser->script;
|
||||
function_declaration_t *func;
|
||||
|
@ -478,10 +491,14 @@ HRESULT exec_source(exec_ctx_t *ctx, parser_ctx_t *parser, source_elements_t *so
|
|||
return hres;
|
||||
}
|
||||
|
||||
if(retv)
|
||||
if(retv && (exec_type == EXECT_EVAL || rt.type == RT_RETURN))
|
||||
*retv = val;
|
||||
else
|
||||
else {
|
||||
if (retv) {
|
||||
VariantInit(retv);
|
||||
}
|
||||
VariantClear(&val);
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -1380,7 +1397,7 @@ HRESULT array_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags,
|
|||
|
||||
TRACE("\n");
|
||||
|
||||
hres = expr_eval(ctx, expr->member_expr, EXPR_NEWREF, ei, &exprval);
|
||||
hres = expr_eval(ctx, expr->member_expr, 0, ei, &exprval);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
|
@ -1395,11 +1412,15 @@ HRESULT array_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags,
|
|||
exprval_release(&exprval);
|
||||
}
|
||||
|
||||
if(SUCCEEDED(hres))
|
||||
if(SUCCEEDED(hres)) {
|
||||
hres = to_object(ctx->parser->script, &member, &obj);
|
||||
if(FAILED(hres))
|
||||
VariantClear(&val);
|
||||
}
|
||||
VariantClear(&member);
|
||||
if(SUCCEEDED(hres)) {
|
||||
hres = to_string(ctx->parser->script, &val, ei, &str);
|
||||
VariantClear(&val);
|
||||
if(SUCCEEDED(hres)) {
|
||||
if(flags & EXPR_STRREF) {
|
||||
ret->type = EXPRVAL_NAMEREF;
|
||||
|
@ -1408,7 +1429,8 @@ HRESULT array_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags,
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
hres = disp_get_id(obj, str, flags & EXPR_NEWREF ? fdexNameEnsure : 0, &id);
|
||||
hres = disp_get_id(ctx->parser->script, obj, str, flags & EXPR_NEWREF ? fdexNameEnsure : 0, &id);
|
||||
SysFreeString(str);
|
||||
}
|
||||
|
||||
if(SUCCEEDED(hres)) {
|
||||
|
@ -1459,7 +1481,7 @@ HRESULT member_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
hres = disp_get_id(obj, str, flags & EXPR_NEWREF ? fdexNameEnsure : 0, &id);
|
||||
hres = disp_get_id(ctx->parser->script, obj, str, flags & EXPR_NEWREF ? fdexNameEnsure : 0, &id);
|
||||
SysFreeString(str);
|
||||
if(SUCCEEDED(hres)) {
|
||||
exprval_set_idref(ret, obj, id);
|
||||
|
@ -1552,6 +1574,7 @@ HRESULT new_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, j
|
|||
hres = disp_call(ctx->parser->script, V_DISPATCH(&constr), DISPID_VALUE,
|
||||
DISPATCH_CONSTRUCT, &dp, &var, ei, NULL/*FIXME*/);
|
||||
IDispatch_Release(V_DISPATCH(&constr));
|
||||
free_dp(&dp);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
|
@ -1654,7 +1677,7 @@ HRESULT literal_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flag
|
|||
|
||||
TRACE("\n");
|
||||
|
||||
hres = literal_to_var(expr->literal, &var);
|
||||
hres = literal_to_var(ctx->parser->script, expr->literal, &var);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
|
@ -1733,7 +1756,7 @@ HRESULT property_value_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWO
|
|||
return hres;
|
||||
|
||||
for(iter = expr->property_list; iter; iter = iter->next) {
|
||||
hres = literal_to_var(iter->name, &tmp);
|
||||
hres = literal_to_var(ctx->parser->script, iter->name, &tmp);
|
||||
if(FAILED(hres))
|
||||
break;
|
||||
|
||||
|
@ -2053,7 +2076,7 @@ static HRESULT in_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *obj, jsexcept_t
|
|||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
hres = disp_get_id(V_DISPATCH(obj), str, 0, &id);
|
||||
hres = disp_get_id(ctx->parser->script, V_DISPATCH(obj), str, 0, &id);
|
||||
SysFreeString(str);
|
||||
if(SUCCEEDED(hres))
|
||||
ret = VARIANT_TRUE;
|
||||
|
@ -2293,7 +2316,8 @@ HRESULT delete_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags
|
|||
|
||||
hres = IDispatch_QueryInterface(exprval.u.nameref.disp, &IID_IDispatchEx, (void**)&dispex);
|
||||
if(SUCCEEDED(hres)) {
|
||||
hres = IDispatchEx_DeleteMemberByName(dispex, exprval.u.nameref.name, fdexNameCaseSensitive);
|
||||
hres = IDispatchEx_DeleteMemberByName(dispex, exprval.u.nameref.name,
|
||||
make_grfdex(ctx->parser->script, fdexNameCaseSensitive));
|
||||
b = VARIANT_TRUE;
|
||||
IDispatchEx_Release(dispex);
|
||||
}
|
||||
|
@ -2472,6 +2496,7 @@ HRESULT plus_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags,
|
|||
return hres;
|
||||
|
||||
hres = to_number(ctx->parser->script, &val, ei, &num);
|
||||
VariantClear(&val);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
|
@ -2731,6 +2756,8 @@ HRESULT equal_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags,
|
|||
return hres;
|
||||
|
||||
hres = equal_values(ctx, &rval, &lval, ei, &b);
|
||||
VariantClear(&lval);
|
||||
VariantClear(&rval);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
|
@ -2752,6 +2779,8 @@ HRESULT equal2_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags
|
|||
return hres;
|
||||
|
||||
hres = equal2_values(&rval, &lval, &b);
|
||||
VariantClear(&lval);
|
||||
VariantClear(&rval);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
|
@ -2773,6 +2802,8 @@ HRESULT not_equal_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD fl
|
|||
return hres;
|
||||
|
||||
hres = equal_values(ctx, &lval, &rval, ei, &b);
|
||||
VariantClear(&lval);
|
||||
VariantClear(&rval);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
|
@ -2794,6 +2825,8 @@ HRESULT not_equal2_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD f
|
|||
return hres;
|
||||
|
||||
hres = equal2_values(&lval, &rval, &b);
|
||||
VariantClear(&lval);
|
||||
VariantClear(&rval);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
|
@ -3096,8 +3129,11 @@ HRESULT assign_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags
|
|||
exprval_release(&exprvalr);
|
||||
}
|
||||
|
||||
if(SUCCEEDED(hres))
|
||||
if(SUCCEEDED(hres)) {
|
||||
hres = put_value(ctx->parser->script, &exprval, &rval, ei);
|
||||
if(FAILED(hres))
|
||||
VariantClear(&rval);
|
||||
}
|
||||
|
||||
exprval_release(&exprval);
|
||||
if(FAILED(hres))
|
||||
|
|
|
@ -19,11 +19,6 @@
|
|||
typedef struct _source_elements_t source_elements_t;
|
||||
typedef struct _function_expression_t function_expression_t;
|
||||
|
||||
typedef struct _obj_literal_t {
|
||||
DispatchEx *obj;
|
||||
struct _obj_literal_t *next;
|
||||
} obj_literal_t;
|
||||
|
||||
typedef struct _function_declaration_t {
|
||||
function_expression_t *expr;
|
||||
|
||||
|
@ -48,9 +43,9 @@ typedef struct _func_stack {
|
|||
typedef struct _parser_ctx_t {
|
||||
LONG ref;
|
||||
|
||||
const WCHAR *ptr;
|
||||
const WCHAR *begin;
|
||||
WCHAR *begin;
|
||||
const WCHAR *end;
|
||||
const WCHAR *ptr;
|
||||
|
||||
script_ctx_t *script;
|
||||
source_elements_t *source;
|
||||
|
@ -61,7 +56,6 @@ typedef struct _parser_ctx_t {
|
|||
|
||||
jsheap_t heap;
|
||||
|
||||
obj_literal_t *obj_literals;
|
||||
func_stack_t *func_stack;
|
||||
|
||||
struct _parser_ctx_t *next;
|
||||
|
@ -115,9 +109,15 @@ static inline void exec_addref(exec_ctx_t *ctx)
|
|||
ctx->ref++;
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
EXECT_PROGRAM,
|
||||
EXECT_FUNCTION,
|
||||
EXECT_EVAL
|
||||
} exec_type_t;
|
||||
|
||||
void exec_release(exec_ctx_t*);
|
||||
HRESULT create_exec_ctx(script_ctx_t*,IDispatch*,DispatchEx*,scope_chain_t*,exec_ctx_t**);
|
||||
HRESULT exec_source(exec_ctx_t*,parser_ctx_t*,source_elements_t*,jsexcept_t*,VARIANT*);
|
||||
HRESULT exec_source(exec_ctx_t*,parser_ctx_t*,source_elements_t*,exec_type_t,jsexcept_t*,VARIANT*);
|
||||
|
||||
typedef struct _statement_t statement_t;
|
||||
typedef struct _expression_t expression_t;
|
||||
|
@ -126,14 +126,28 @@ typedef struct _parameter_t parameter_t;
|
|||
HRESULT create_source_function(parser_ctx_t*,parameter_t*,source_elements_t*,scope_chain_t*,
|
||||
const WCHAR*,DWORD,DispatchEx**);
|
||||
|
||||
typedef enum {
|
||||
LT_INT,
|
||||
LT_DOUBLE,
|
||||
LT_STRING,
|
||||
LT_BOOL,
|
||||
LT_NULL,
|
||||
LT_REGEXP
|
||||
}literal_type_t;
|
||||
|
||||
typedef struct {
|
||||
VARTYPE vt;
|
||||
literal_type_t type;
|
||||
union {
|
||||
LONG lval;
|
||||
double dval;
|
||||
const WCHAR *wstr;
|
||||
VARIANT_BOOL bval;
|
||||
IDispatch *disp;
|
||||
struct {
|
||||
const WCHAR *str;
|
||||
DWORD str_len;
|
||||
DWORD flags;
|
||||
} regexp;
|
||||
} u;
|
||||
} literal_t;
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@ typedef struct {
|
|||
|
||||
static const WCHAR descriptionW[] = {'d','e','s','c','r','i','p','t','i','o','n',0};
|
||||
static const WCHAR messageW[] = {'m','e','s','s','a','g','e',0};
|
||||
static const WCHAR nameW[] = {'n','a','m','e',0};
|
||||
static const WCHAR numberW[] = {'n','u','m','b','e','r',0};
|
||||
static const WCHAR toStringW[] = {'t','o','S','t','r','i','n','g',0};
|
||||
|
||||
|
@ -44,6 +45,11 @@ static inline ErrorInstance *error_from_vdisp(vdisp_t *vdisp)
|
|||
return (ErrorInstance*)vdisp->u.jsdisp;
|
||||
}
|
||||
|
||||
static inline ErrorInstance *error_this(vdisp_t *jsthis)
|
||||
{
|
||||
return is_vclass(jsthis, JSCLASS_ERROR) ? error_from_vdisp(jsthis) : NULL;
|
||||
}
|
||||
|
||||
static HRESULT Error_number(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
|
||||
DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
|
@ -101,17 +107,77 @@ static HRESULT Error_message(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
|
|||
|
||||
/* ECMA-262 3rd Edition 15.11.4.4 */
|
||||
static HRESULT Error_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
|
||||
DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
|
||||
{
|
||||
ErrorInstance *error;
|
||||
BSTR name, msg = NULL, ret = NULL;
|
||||
VARIANT v;
|
||||
HRESULT hres;
|
||||
|
||||
static const WCHAR str[] = {'[','o','b','j','e','c','t',' ','E','r','r','o','r',']',0};
|
||||
|
||||
TRACE("\n");
|
||||
|
||||
error = error_this(jsthis);
|
||||
if(ctx->version < 2 || !error) {
|
||||
if(retv) {
|
||||
V_VT(retv) = VT_BSTR;
|
||||
V_BSTR(retv) = SysAllocString(str);
|
||||
if(!V_BSTR(retv))
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
hres = jsdisp_propget_name(&error->dispex, nameW, &v, ei, caller);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
hres = to_string(ctx, &v, ei, &name);
|
||||
VariantClear(&v);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
if(V_VT(&error->message) != VT_EMPTY) {
|
||||
hres = to_string(ctx, &error->message, ei, &msg);
|
||||
if(SUCCEEDED(hres) && !*msg) {
|
||||
SysFreeString(msg);
|
||||
msg = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if(SUCCEEDED(hres)) {
|
||||
if(msg) {
|
||||
DWORD name_len, msg_len;
|
||||
|
||||
name_len = SysStringLen(name);
|
||||
msg_len = SysStringLen(msg);
|
||||
|
||||
ret = SysAllocStringLen(NULL, name_len + msg_len + 2);
|
||||
if(ret) {
|
||||
memcpy(ret, name, name_len*sizeof(WCHAR));
|
||||
ret[name_len] = ':';
|
||||
ret[name_len+1] = ' ';
|
||||
memcpy(ret+name_len+2, msg, msg_len*sizeof(WCHAR));
|
||||
}
|
||||
}else {
|
||||
ret = name;
|
||||
name = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
SysFreeString(msg);
|
||||
SysFreeString(name);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
if(!ret)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
if(retv) {
|
||||
V_VT(retv) = VT_BSTR;
|
||||
V_BSTR(retv) = SysAllocString(str);
|
||||
if(!V_BSTR(retv))
|
||||
return E_OUTOFMEMORY;
|
||||
V_BSTR(retv) = ret;
|
||||
}else {
|
||||
SysFreeString(ret);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
|
@ -264,6 +330,7 @@ static HRESULT error_constr(script_ctx_t *ctx, WORD flags, DISPPARAMS *dp,
|
|||
hres = create_error(ctx, constr, NULL, msg, &err);
|
||||
else
|
||||
hres = create_error(ctx, constr, &num, msg, &err);
|
||||
SysFreeString(msg);
|
||||
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
@ -341,7 +408,6 @@ static HRESULT URIErrorConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD fla
|
|||
|
||||
HRESULT init_error_constr(script_ctx_t *ctx, DispatchEx *object_prototype)
|
||||
{
|
||||
static const WCHAR nameW[] = {'n','a','m','e',0};
|
||||
static const WCHAR ErrorW[] = {'E','r','r','o','r',0};
|
||||
static const WCHAR EvalErrorW[] = {'E','v','a','l','E','r','r','o','r',0};
|
||||
static const WCHAR RangeErrorW[] = {'R','a','n','g','e','E','r','r','o','r',0};
|
||||
|
@ -381,7 +447,7 @@ HRESULT init_error_constr(script_ctx_t *ctx, DispatchEx *object_prototype)
|
|||
|
||||
if(SUCCEEDED(hres))
|
||||
hres = create_builtin_function(ctx, constr_val[i], names[i], NULL,
|
||||
PROPF_CONSTR, &err->dispex, constr_addr[i]);
|
||||
PROPF_CONSTR|1, &err->dispex, constr_addr[i]);
|
||||
|
||||
jsdisp_release(&err->dispex);
|
||||
VariantClear(&v);
|
||||
|
@ -424,11 +490,6 @@ static HRESULT throw_error(script_ctx_t *ctx, jsexcept_t *ei, UINT id, const WCH
|
|||
return id;
|
||||
}
|
||||
|
||||
HRESULT throw_eval_error(script_ctx_t *ctx, jsexcept_t *ei, UINT id, const WCHAR *str)
|
||||
{
|
||||
return throw_error(ctx, ei, id, str, ctx->eval_error_constr);
|
||||
}
|
||||
|
||||
HRESULT throw_generic_error(script_ctx_t *ctx, jsexcept_t *ei, UINT id, const WCHAR *str)
|
||||
{
|
||||
return throw_error(ctx, ei, id, str, ctx->error_constr);
|
||||
|
|
|
@ -213,10 +213,11 @@ static HRESULT invoke_source(script_ctx_t *ctx, FunctionInstance *function, IDis
|
|||
hres = create_exec_ctx(ctx, this_obj, var_disp, scope, &exec_ctx);
|
||||
scope_release(scope);
|
||||
}
|
||||
jsdisp_release(var_disp);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
hres = exec_source(exec_ctx, function->parser, function->source, ei, retv);
|
||||
hres = exec_source(exec_ctx, function->parser, function->source, EXECT_FUNCTION, ei, retv);
|
||||
exec_release(exec_ctx);
|
||||
|
||||
return hres;
|
||||
|
@ -226,20 +227,27 @@ static HRESULT invoke_constructor(script_ctx_t *ctx, FunctionInstance *function,
|
|||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
|
||||
{
|
||||
DispatchEx *this_obj;
|
||||
VARIANT var;
|
||||
HRESULT hres;
|
||||
|
||||
hres = create_object(ctx, &function->dispex, &this_obj);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
hres = invoke_source(ctx, function, (IDispatch*)_IDispatchEx_(this_obj), dp, retv, ei, caller);
|
||||
hres = invoke_source(ctx, function, (IDispatch*)_IDispatchEx_(this_obj), dp, &var, ei, caller);
|
||||
if(FAILED(hres)) {
|
||||
jsdisp_release(this_obj);
|
||||
return hres;
|
||||
}
|
||||
|
||||
V_VT(retv) = VT_DISPATCH;
|
||||
V_DISPATCH(retv) = (IDispatch*)_IDispatchEx_(this_obj);
|
||||
if(V_VT(&var) == VT_DISPATCH) {
|
||||
jsdisp_release(this_obj);
|
||||
V_DISPATCH(retv) = V_DISPATCH(&var);
|
||||
}else {
|
||||
VariantClear(&var);
|
||||
V_DISPATCH(retv) = (IDispatch*)_IDispatchEx_(this_obj);
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -366,8 +374,10 @@ static HRESULT array_to_args(script_ctx_t *ctx, DispatchEx *arg_array, jsexcept_
|
|||
return E_OUTOFMEMORY;
|
||||
|
||||
for(i=0; i<length; i++) {
|
||||
hres = jsdisp_propget_idx(arg_array, i, argv+i, ei, caller);
|
||||
if(FAILED(hres)) {
|
||||
hres = jsdisp_get_idx(arg_array, i, argv+i, ei, caller);
|
||||
if(hres == DISP_E_UNKNOWNNAME)
|
||||
V_VT(argv+i) = VT_EMPTY;
|
||||
else if(FAILED(hres)) {
|
||||
while(i--)
|
||||
VariantClear(argv+i);
|
||||
heap_free(argv);
|
||||
|
@ -396,9 +406,13 @@ static HRESULT Function_apply(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DI
|
|||
|
||||
argc = arg_cnt(dp);
|
||||
if(argc) {
|
||||
hres = to_object(ctx, get_arg(dp,0), &this_obj);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
VARIANT *v = get_arg(dp,0);
|
||||
|
||||
if(V_VT(v) != VT_EMPTY && V_VT(v) != VT_NULL) {
|
||||
hres = to_object(ctx, v, &this_obj);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
}
|
||||
}
|
||||
|
||||
if(argc >= 2) {
|
||||
|
@ -406,8 +420,8 @@ static HRESULT Function_apply(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DI
|
|||
|
||||
if(V_VT(get_arg(dp,1)) == VT_DISPATCH) {
|
||||
arg_array = iface_to_jsdisp((IUnknown*)V_DISPATCH(get_arg(dp,1)));
|
||||
if(arg_array && (
|
||||
!is_class(arg_array, JSCLASS_ARRAY) && !is_class(arg_array, JSCLASS_ARGUMENTS) )) {
|
||||
if(arg_array &&
|
||||
(!is_class(arg_array, JSCLASS_ARRAY) && !is_class(arg_array, JSCLASS_ARGUMENTS) )) {
|
||||
jsdisp_release(arg_array);
|
||||
arg_array = NULL;
|
||||
}
|
||||
|
@ -448,9 +462,14 @@ static HRESULT Function_call(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DIS
|
|||
|
||||
argc = arg_cnt(dp);
|
||||
if(argc) {
|
||||
hres = to_object(ctx, get_arg(dp,0), &this_obj);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
VARIANT *v = get_arg(dp,0);
|
||||
|
||||
if(V_VT(v) != VT_EMPTY && V_VT(v) != VT_NULL) {
|
||||
hres = to_object(ctx, v, &this_obj);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
}
|
||||
|
||||
args.cArgs = argc-1;
|
||||
}
|
||||
|
||||
|
@ -539,20 +558,6 @@ static const builtin_info_t Function_info = {
|
|||
NULL
|
||||
};
|
||||
|
||||
static HRESULT FunctionConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
|
||||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT FunctionProt_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
|
||||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT create_function(script_ctx_t *ctx, const builtin_info_t *builtin_info, DWORD flags,
|
||||
BOOL funcprot, DispatchEx *prototype, FunctionInstance **ret)
|
||||
{
|
||||
|
@ -659,6 +664,131 @@ HRESULT create_source_function(parser_ctx_t *ctx, parameter_t *parameters, sourc
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT construct_function(script_ctx_t *ctx, DISPPARAMS *dp, jsexcept_t *ei, IDispatch **ret)
|
||||
{
|
||||
function_expression_t *expr;
|
||||
WCHAR *str = NULL, *ptr;
|
||||
DWORD argc, len = 0, l;
|
||||
parser_ctx_t *parser;
|
||||
DispatchEx *function;
|
||||
BSTR *params = NULL;
|
||||
int i=0, j=0;
|
||||
HRESULT hres = S_OK;
|
||||
|
||||
static const WCHAR function_anonymousW[] = {'f','u','n','c','t','i','o','n',' ','a','n','o','n','y','m','o','u','s','('};
|
||||
static const WCHAR function_beginW[] = {')',' ','{','\n'};
|
||||
static const WCHAR function_endW[] = {'\n','}',0};
|
||||
|
||||
argc = arg_cnt(dp);
|
||||
if(argc) {
|
||||
params = heap_alloc(argc*sizeof(BSTR));
|
||||
if(!params)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
if(argc > 2)
|
||||
len = (argc-2)*2; /* separating commas */
|
||||
for(i=0; i < argc; i++) {
|
||||
hres = to_string(ctx, get_arg(dp,i), ei, params+i);
|
||||
if(FAILED(hres))
|
||||
break;
|
||||
len += SysStringLen(params[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if(SUCCEEDED(hres)) {
|
||||
len += (sizeof(function_anonymousW) + sizeof(function_beginW) + sizeof(function_endW)) / sizeof(WCHAR);
|
||||
str = heap_alloc(len*sizeof(WCHAR));
|
||||
if(str) {
|
||||
memcpy(str, function_anonymousW, sizeof(function_anonymousW));
|
||||
ptr = str + sizeof(function_anonymousW)/sizeof(WCHAR);
|
||||
if(argc > 1) {
|
||||
while(1) {
|
||||
l = SysStringLen(params[j]);
|
||||
memcpy(ptr, params[j], l*sizeof(WCHAR));
|
||||
ptr += l;
|
||||
if(++j == argc-1)
|
||||
break;
|
||||
*ptr++ = ',';
|
||||
*ptr++ = ' ';
|
||||
}
|
||||
}
|
||||
memcpy(ptr, function_beginW, sizeof(function_beginW));
|
||||
ptr += sizeof(function_beginW)/sizeof(WCHAR);
|
||||
if(argc) {
|
||||
l = SysStringLen(params[argc-1]);
|
||||
memcpy(ptr, params[argc-1], l*sizeof(WCHAR));
|
||||
ptr += l;
|
||||
}
|
||||
memcpy(ptr, function_endW, sizeof(function_endW));
|
||||
|
||||
TRACE("%s\n", debugstr_w(str));
|
||||
}else {
|
||||
hres = E_OUTOFMEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
while(--i >= 0)
|
||||
SysFreeString(params[i]);
|
||||
heap_free(params);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
hres = script_parse(ctx, str, NULL, &parser);
|
||||
heap_free(str);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
if(!parser->source || !parser->source->functions || parser->source->functions->next || parser->source->variables) {
|
||||
ERR("Invalid parser result!\n");
|
||||
parser_release(parser);
|
||||
return E_UNEXPECTED;
|
||||
}
|
||||
expr = parser->source->functions->expr;
|
||||
|
||||
hres = create_source_function(parser, expr->parameter_list, expr->source_elements, NULL, expr->src_str,
|
||||
expr->src_len, &function);
|
||||
parser_release(parser);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
*ret = (IDispatch*)_IDispatchEx_(function);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT FunctionConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
|
||||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("\n");
|
||||
|
||||
switch(flags) {
|
||||
case DISPATCH_CONSTRUCT: {
|
||||
IDispatch *ret;
|
||||
|
||||
hres = construct_function(ctx, dp, ei, &ret);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
V_VT(retv) = VT_DISPATCH;
|
||||
V_DISPATCH(retv) = ret;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
FIXME("unimplemented flags %x\n", flags);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT FunctionProt_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
|
||||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT init_function_constr(script_ctx_t *ctx, DispatchEx *object_prototype)
|
||||
{
|
||||
FunctionInstance *prot, *constr;
|
||||
|
@ -673,7 +803,7 @@ HRESULT init_function_constr(script_ctx_t *ctx, DispatchEx *object_prototype)
|
|||
prot->value_proc = FunctionProt_value;
|
||||
prot->name = prototypeW;
|
||||
|
||||
hres = create_function(ctx, NULL, PROPF_CONSTR, TRUE, &prot->dispex, &constr);
|
||||
hres = create_function(ctx, NULL, PROPF_CONSTR|1, TRUE, &prot->dispex, &constr);
|
||||
if(SUCCEEDED(hres)) {
|
||||
constr->value_proc = FunctionConstr_value;
|
||||
constr->name = FunctionW;
|
||||
|
|
|
@ -334,8 +334,10 @@ static HRESULT JSGlobal_escape(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, D
|
|||
}
|
||||
|
||||
ret = SysAllocStringLen(NULL, len);
|
||||
if(!ret)
|
||||
if(!ret) {
|
||||
SysFreeString(str);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
len = 0;
|
||||
for(ptr=str; *ptr; ptr++) {
|
||||
|
@ -357,6 +359,8 @@ static HRESULT JSGlobal_escape(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, D
|
|||
}
|
||||
}
|
||||
|
||||
SysFreeString(str);
|
||||
|
||||
if(retv) {
|
||||
V_VT(retv) = VT_BSTR;
|
||||
V_BSTR(retv) = ret;
|
||||
|
@ -404,7 +408,7 @@ static HRESULT JSGlobal_eval(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DIS
|
|||
return throw_syntax_error(ctx, ei, hres, NULL);
|
||||
}
|
||||
|
||||
hres = exec_source(ctx->exec_ctx, parser_ctx, parser_ctx->source, ei, retv);
|
||||
hres = exec_source(ctx->exec_ctx, parser_ctx, parser_ctx->source, EXECT_EVAL, ei, retv);
|
||||
parser_release(parser_ctx);
|
||||
|
||||
return hres;
|
||||
|
@ -690,8 +694,10 @@ static HRESULT JSGlobal_unescape(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
|
|||
}
|
||||
|
||||
ret = SysAllocStringLen(NULL, len);
|
||||
if(!ret)
|
||||
if(!ret) {
|
||||
SysFreeString(str);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
len = 0;
|
||||
for(ptr=str; *ptr; ptr++) {
|
||||
|
@ -715,6 +721,8 @@ static HRESULT JSGlobal_unescape(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
|
|||
len++;
|
||||
}
|
||||
|
||||
SysFreeString(str);
|
||||
|
||||
if(retv) {
|
||||
V_VT(retv) = VT_BSTR;
|
||||
V_BSTR(retv) = ret;
|
||||
|
@ -802,8 +810,8 @@ static HRESULT JSGlobal_encodeURI(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags
|
|||
}else {
|
||||
i = WideCharToMultiByte(CP_UTF8, 0, ptr, 1, NULL, 0, NULL, NULL)*3;
|
||||
if(!i) {
|
||||
FIXME("throw URIError\n");
|
||||
return E_FAIL;
|
||||
SysFreeString(str);
|
||||
return throw_uri_error(ctx, ei, IDS_URI_INVALID_CHAR, NULL);
|
||||
}
|
||||
|
||||
len += i;
|
||||
|
@ -811,8 +819,10 @@ static HRESULT JSGlobal_encodeURI(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags
|
|||
}
|
||||
|
||||
rptr = ret = SysAllocStringLen(NULL, len);
|
||||
if(!ret)
|
||||
if(!ret) {
|
||||
SysFreeString(str);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
for(ptr = str; *ptr; ptr++) {
|
||||
if(is_uri_unescaped(*ptr) || is_uri_reserved(*ptr) || *ptr == '#') {
|
||||
|
@ -827,6 +837,8 @@ static HRESULT JSGlobal_encodeURI(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags
|
|||
}
|
||||
}
|
||||
|
||||
SysFreeString(str);
|
||||
|
||||
TRACE("%s -> %s\n", debugstr_w(str), debugstr_w(ret));
|
||||
if(retv) {
|
||||
V_VT(retv) = VT_BSTR;
|
||||
|
@ -847,56 +859,239 @@ static HRESULT JSGlobal_decodeURI(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags
|
|||
static HRESULT JSGlobal_encodeURIComponent(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
|
||||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
BSTR str, ret;
|
||||
char buf[4];
|
||||
const WCHAR *ptr;
|
||||
DWORD len = 0, size, i;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("\n");
|
||||
|
||||
if(!arg_cnt(dp)) {
|
||||
if(retv) {
|
||||
ret = SysAllocString(undefinedW);
|
||||
if(!ret)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
V_VT(retv) = VT_BSTR;
|
||||
V_BSTR(retv) = ret;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
hres = to_string(ctx, get_arg(dp, 0), ei, &str);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
for(ptr=str; *ptr; ptr++) {
|
||||
if(is_uri_unescaped(*ptr))
|
||||
len++;
|
||||
else {
|
||||
size = WideCharToMultiByte(CP_UTF8, 0, ptr, 1, NULL, 0, NULL, NULL);
|
||||
if(!size) {
|
||||
SysFreeString(str);
|
||||
FIXME("throw Error\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
len += size*3;
|
||||
}
|
||||
}
|
||||
|
||||
ret = SysAllocStringLen(NULL, len);
|
||||
if(!ret) {
|
||||
SysFreeString(str);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
len = 0;
|
||||
for(ptr=str; *ptr; ptr++) {
|
||||
if(is_uri_unescaped(*ptr))
|
||||
ret[len++] = *ptr;
|
||||
else {
|
||||
size = WideCharToMultiByte(CP_UTF8, 0, ptr, 1, buf, sizeof(buf), NULL, NULL);
|
||||
for(i=0; i<size; i++) {
|
||||
ret[len++] = '%';
|
||||
ret[len++] = int_to_char((BYTE)buf[i] >> 4);
|
||||
ret[len++] = int_to_char(buf[i] & 0x0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SysFreeString(str);
|
||||
|
||||
if(retv) {
|
||||
V_VT(retv) = VT_BSTR;
|
||||
V_BSTR(retv) = ret;
|
||||
} else {
|
||||
SysFreeString(ret);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/* ECMA-262 3rd Edition 15.1.3.2 */
|
||||
static HRESULT JSGlobal_decodeURIComponent(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
|
||||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
BSTR str, ret;
|
||||
const WCHAR *ptr;
|
||||
WCHAR *out_ptr;
|
||||
DWORD len = 0;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("\n");
|
||||
|
||||
if(!arg_cnt(dp)) {
|
||||
if(retv) {
|
||||
ret = SysAllocString(undefinedW);
|
||||
if(!ret)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
V_VT(retv) = VT_BSTR;
|
||||
V_BSTR(retv) = ret;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
hres = to_string(ctx, get_arg(dp, 0), ei, &str);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
ptr = str;
|
||||
while(*ptr) {
|
||||
if(*ptr == '%') {
|
||||
char octets[4];
|
||||
unsigned char mask = 0x80;
|
||||
int i, size, num_bytes = 0;
|
||||
if(hex_to_int(*(ptr+1)) < 0 || hex_to_int(*(ptr+2)) < 0) {
|
||||
FIXME("Throw URIError: Invalid hex sequence\n");
|
||||
SysFreeString(str);
|
||||
return E_FAIL;
|
||||
}
|
||||
octets[0] = (hex_to_int(*(ptr+1)) << 4) + hex_to_int(*(ptr+2));
|
||||
ptr += 3;
|
||||
while(octets[0] & mask) {
|
||||
mask = mask >> 1;
|
||||
++num_bytes;
|
||||
}
|
||||
if(num_bytes == 1 || num_bytes > 4) {
|
||||
FIXME("Throw URIError: Invalid initial UTF character\n");
|
||||
SysFreeString(str);
|
||||
return E_FAIL;
|
||||
}
|
||||
for(i = 1; i < num_bytes; ++i) {
|
||||
if(*ptr != '%'){
|
||||
FIXME("Throw URIError: Incomplete UTF sequence\n");
|
||||
SysFreeString(str);
|
||||
return E_FAIL;
|
||||
}
|
||||
if(hex_to_int(*(ptr+1)) < 0 || hex_to_int(*(ptr+2)) < 0) {
|
||||
FIXME("Throw URIError: Invalid hex sequence\n");
|
||||
SysFreeString(str);
|
||||
return E_FAIL;
|
||||
}
|
||||
octets[i] = (hex_to_int(*(ptr+1)) << 4) + hex_to_int(*(ptr+2));
|
||||
ptr += 3;
|
||||
}
|
||||
size = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, octets,
|
||||
num_bytes ? num_bytes : 1, NULL, 0);
|
||||
if(size == 0) {
|
||||
FIXME("Throw URIError: Invalid UTF sequence\n");
|
||||
SysFreeString(str);
|
||||
return E_FAIL;
|
||||
}
|
||||
len += size;
|
||||
}else {
|
||||
++ptr;
|
||||
++len;
|
||||
}
|
||||
}
|
||||
|
||||
out_ptr = ret = SysAllocStringLen(NULL, len);
|
||||
if(!ret) {
|
||||
SysFreeString(str);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
ptr = str;
|
||||
while(*ptr) {
|
||||
if(*ptr == '%') {
|
||||
char octets[4];
|
||||
unsigned char mask = 0x80;
|
||||
int i, size, num_bytes = 0;
|
||||
octets[0] = (hex_to_int(*(ptr+1)) << 4) + hex_to_int(*(ptr+2));
|
||||
ptr += 3;
|
||||
while(octets[0] & mask) {
|
||||
mask = mask >> 1;
|
||||
++num_bytes;
|
||||
}
|
||||
for(i = 1; i < num_bytes; ++i) {
|
||||
octets[i] = (hex_to_int(*(ptr+1)) << 4) + hex_to_int(*(ptr+2));
|
||||
ptr += 3;
|
||||
}
|
||||
size = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, octets,
|
||||
num_bytes ? num_bytes : 1, out_ptr, len);
|
||||
len -= size;
|
||||
out_ptr += size;
|
||||
}else {
|
||||
*out_ptr++ = *ptr++;
|
||||
--len;
|
||||
}
|
||||
}
|
||||
|
||||
SysFreeString(str);
|
||||
|
||||
if(retv) {
|
||||
V_VT(retv) = VT_BSTR;
|
||||
V_BSTR(retv) = ret;
|
||||
}else {
|
||||
SysFreeString(ret);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static const builtin_prop_t JSGlobal_props[] = {
|
||||
{ActiveXObjectW, JSGlobal_ActiveXObject, PROPF_CONSTR},
|
||||
{ArrayW, JSGlobal_Array, PROPF_CONSTR},
|
||||
{BooleanW, JSGlobal_Boolean, PROPF_CONSTR},
|
||||
{ActiveXObjectW, JSGlobal_ActiveXObject, PROPF_CONSTR|1},
|
||||
{ArrayW, JSGlobal_Array, PROPF_CONSTR|1},
|
||||
{BooleanW, JSGlobal_Boolean, PROPF_CONSTR|1},
|
||||
{CollectGarbageW, JSGlobal_CollectGarbage, PROPF_METHOD},
|
||||
{DateW, JSGlobal_Date, PROPF_CONSTR},
|
||||
{EnumeratorW, JSGlobal_Enumerator, PROPF_METHOD},
|
||||
{ErrorW, JSGlobal_Error, PROPF_CONSTR},
|
||||
{EvalErrorW, JSGlobal_EvalError, PROPF_CONSTR},
|
||||
{FunctionW, JSGlobal_Function, PROPF_CONSTR},
|
||||
{_GetObjectW, JSGlobal_GetObject, PROPF_METHOD},
|
||||
{DateW, JSGlobal_Date, PROPF_CONSTR|7},
|
||||
{EnumeratorW, JSGlobal_Enumerator, PROPF_METHOD|7},
|
||||
{ErrorW, JSGlobal_Error, PROPF_CONSTR|1},
|
||||
{EvalErrorW, JSGlobal_EvalError, PROPF_CONSTR|1},
|
||||
{FunctionW, JSGlobal_Function, PROPF_CONSTR|1},
|
||||
{_GetObjectW, JSGlobal_GetObject, PROPF_METHOD|2},
|
||||
{InfinityW, JSGlobal_Infinity, 0},
|
||||
/* {MathW, JSGlobal_Math, 0}, */
|
||||
{NaNW, JSGlobal_NaN, 0},
|
||||
{NumberW, JSGlobal_Number, PROPF_CONSTR},
|
||||
{ObjectW, JSGlobal_Object, PROPF_CONSTR},
|
||||
{RangeErrorW, JSGlobal_RangeError, PROPF_CONSTR},
|
||||
{ReferenceErrorW, JSGlobal_ReferenceError, PROPF_CONSTR},
|
||||
{RegExpW, JSGlobal_RegExp, PROPF_CONSTR},
|
||||
{NumberW, JSGlobal_Number, PROPF_CONSTR|1},
|
||||
{ObjectW, JSGlobal_Object, PROPF_CONSTR|1},
|
||||
{RangeErrorW, JSGlobal_RangeError, PROPF_CONSTR|1},
|
||||
{ReferenceErrorW, JSGlobal_ReferenceError, PROPF_CONSTR|1},
|
||||
{RegExpW, JSGlobal_RegExp, PROPF_CONSTR|2},
|
||||
{ScriptEngineW, JSGlobal_ScriptEngine, PROPF_METHOD},
|
||||
{ScriptEngineBuildVersionW, JSGlobal_ScriptEngineBuildVersion, PROPF_METHOD},
|
||||
{ScriptEngineMajorVersionW, JSGlobal_ScriptEngineMajorVersion, PROPF_METHOD},
|
||||
{ScriptEngineMinorVersionW, JSGlobal_ScriptEngineMinorVersion, PROPF_METHOD},
|
||||
{StringW, JSGlobal_String, PROPF_CONSTR},
|
||||
{SyntaxErrorW, JSGlobal_SyntaxError, PROPF_CONSTR},
|
||||
{TypeErrorW, JSGlobal_TypeError, PROPF_CONSTR},
|
||||
{URIErrorW, JSGlobal_URIError, PROPF_CONSTR},
|
||||
{VBArrayW, JSGlobal_VBArray, PROPF_METHOD},
|
||||
{decodeURIW, JSGlobal_decodeURI, PROPF_METHOD},
|
||||
{decodeURIComponentW, JSGlobal_decodeURIComponent, PROPF_METHOD},
|
||||
{encodeURIW, JSGlobal_encodeURI, PROPF_METHOD},
|
||||
{encodeURIComponentW, JSGlobal_encodeURIComponent, PROPF_METHOD},
|
||||
{escapeW, JSGlobal_escape, PROPF_METHOD},
|
||||
{StringW, JSGlobal_String, PROPF_CONSTR|1},
|
||||
{SyntaxErrorW, JSGlobal_SyntaxError, PROPF_CONSTR|1},
|
||||
{TypeErrorW, JSGlobal_TypeError, PROPF_CONSTR|1},
|
||||
{URIErrorW, JSGlobal_URIError, PROPF_CONSTR|1},
|
||||
{VBArrayW, JSGlobal_VBArray, PROPF_METHOD|1},
|
||||
{decodeURIW, JSGlobal_decodeURI, PROPF_METHOD|1},
|
||||
{decodeURIComponentW, JSGlobal_decodeURIComponent, PROPF_METHOD|1},
|
||||
{encodeURIW, JSGlobal_encodeURI, PROPF_METHOD|1},
|
||||
{encodeURIComponentW, JSGlobal_encodeURIComponent, PROPF_METHOD|1},
|
||||
{escapeW, JSGlobal_escape, PROPF_METHOD|1},
|
||||
{evalW, JSGlobal_eval, PROPF_METHOD|1},
|
||||
{isFiniteW, JSGlobal_isFinite, PROPF_METHOD},
|
||||
{isNaNW, JSGlobal_isNaN, PROPF_METHOD},
|
||||
{parseFloatW, JSGlobal_parseFloat, PROPF_METHOD},
|
||||
{isFiniteW, JSGlobal_isFinite, PROPF_METHOD|1},
|
||||
{isNaNW, JSGlobal_isNaN, PROPF_METHOD|1},
|
||||
{parseFloatW, JSGlobal_parseFloat, PROPF_METHOD|1},
|
||||
{parseIntW, JSGlobal_parseInt, PROPF_METHOD|2},
|
||||
{unescapeW, JSGlobal_unescape, PROPF_METHOD}
|
||||
{unescapeW, JSGlobal_unescape, PROPF_METHOD|1}
|
||||
};
|
||||
|
||||
static const builtin_info_t JSGlobal_info = {
|
||||
|
@ -981,6 +1176,11 @@ HRESULT init_global(script_ctx_t *ctx)
|
|||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
V_VT(&var) = VT_EMPTY;
|
||||
hres = jsdisp_propput_name(ctx->global, undefinedW, &var, NULL/*FIXME*/, NULL/*FIXME*/);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
V_VT(&var) = VT_DISPATCH;
|
||||
V_DISPATCH(&var) = (IDispatch*)_IDispatchEx_(math);
|
||||
hres = jsdisp_propput_name(ctx->global, MathW, &var, NULL/*FIXME*/, NULL/*FIXME*/);
|
||||
|
|
|
@ -51,6 +51,7 @@ typedef struct {
|
|||
script_ctx_t *ctx;
|
||||
LONG thread_id;
|
||||
LCID lcid;
|
||||
DWORD version;
|
||||
|
||||
IActiveScriptSite *site;
|
||||
|
||||
|
@ -93,7 +94,6 @@ static HRESULT exec_global_code(JScript *This, parser_ctx_t *parser_ctx)
|
|||
{
|
||||
exec_ctx_t *exec_ctx;
|
||||
jsexcept_t jsexcept;
|
||||
VARIANT var;
|
||||
HRESULT hres;
|
||||
|
||||
hres = create_exec_ctx(This->ctx, NULL, This->ctx->global, NULL, &exec_ctx);
|
||||
|
@ -103,14 +103,11 @@ static HRESULT exec_global_code(JScript *This, parser_ctx_t *parser_ctx)
|
|||
IActiveScriptSite_OnEnterScript(This->site);
|
||||
|
||||
memset(&jsexcept, 0, sizeof(jsexcept));
|
||||
hres = exec_source(exec_ctx, parser_ctx, parser_ctx->source, &jsexcept, &var);
|
||||
hres = exec_source(exec_ctx, parser_ctx, parser_ctx->source, EXECT_PROGRAM, &jsexcept, NULL);
|
||||
VariantClear(&jsexcept.var);
|
||||
exec_release(exec_ctx);
|
||||
if(SUCCEEDED(hres))
|
||||
VariantClear(&var);
|
||||
|
||||
IActiveScriptSite_OnLeaveScript(This->site);
|
||||
|
||||
return hres;
|
||||
}
|
||||
|
||||
|
@ -659,6 +656,7 @@ static HRESULT WINAPI JScriptParse_InitNew(IActiveScriptParse *iface)
|
|||
ctx->ref = 1;
|
||||
ctx->state = SCRIPTSTATE_UNINITIALIZED;
|
||||
ctx->safeopt = This->safeopt;
|
||||
ctx->version = This->version;
|
||||
jsheap_init(&ctx->tmp_heap);
|
||||
|
||||
ctx = InterlockedCompareExchangePointer((void**)&This->ctx, ctx, NULL);
|
||||
|
@ -822,8 +820,27 @@ static HRESULT WINAPI JScriptProperty_SetProperty(IActiveScriptProperty *iface,
|
|||
VARIANT *pvarIndex, VARIANT *pvarValue)
|
||||
{
|
||||
JScript *This = ACTSCPPROP_THIS(iface);
|
||||
FIXME("(%p)->(%x %p %p)\n", This, dwProperty, pvarIndex, pvarValue);
|
||||
return E_NOTIMPL;
|
||||
|
||||
TRACE("(%p)->(%x %s %s)\n", This, dwProperty, debugstr_variant(pvarIndex), debugstr_variant(pvarValue));
|
||||
|
||||
if(pvarIndex)
|
||||
FIXME("unsupported pvarIndex\n");
|
||||
|
||||
switch(dwProperty) {
|
||||
case SCRIPTPROP_INVOKEVERSIONING:
|
||||
if(V_VT(pvarValue) != VT_I4 || V_I4(pvarValue) < 0 || V_I4(pvarValue) > 15) {
|
||||
WARN("invalid value %s\n", debugstr_variant(pvarValue));
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
This->version = V_I4(pvarValue);
|
||||
break;
|
||||
default:
|
||||
FIXME("Unimplemented property %x\n", dwProperty);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
#undef ACTSCPPROP_THIS
|
||||
|
|
|
@ -205,7 +205,7 @@ HRESULT jsdisp_propget(DispatchEx*,DISPID,VARIANT*,jsexcept_t*,IServiceProvider*
|
|||
HRESULT jsdisp_propput_name(DispatchEx*,const WCHAR*,VARIANT*,jsexcept_t*,IServiceProvider*);
|
||||
HRESULT jsdisp_propput_idx(DispatchEx*,DWORD,VARIANT*,jsexcept_t*,IServiceProvider*);
|
||||
HRESULT jsdisp_propget_name(DispatchEx*,LPCWSTR,VARIANT*,jsexcept_t*,IServiceProvider*);
|
||||
HRESULT jsdisp_propget_idx(DispatchEx*,DWORD,VARIANT*,jsexcept_t*,IServiceProvider*);
|
||||
HRESULT jsdisp_get_idx(DispatchEx*,DWORD,VARIANT*,jsexcept_t*,IServiceProvider*);
|
||||
HRESULT jsdisp_get_id(DispatchEx*,const WCHAR*,DWORD,DISPID*);
|
||||
HRESULT jsdisp_delete_idx(DispatchEx*,DWORD);
|
||||
|
||||
|
@ -225,7 +225,8 @@ HRESULT throw_uri_error(script_ctx_t*,jsexcept_t*,UINT,const WCHAR*);
|
|||
HRESULT create_object(script_ctx_t*,DispatchEx*,DispatchEx**);
|
||||
HRESULT create_math(script_ctx_t*,DispatchEx**);
|
||||
HRESULT create_array(script_ctx_t*,DWORD,DispatchEx**);
|
||||
HRESULT create_regexp_str(script_ctx_t*,const WCHAR*,DWORD,const WCHAR*,DWORD,DispatchEx**);
|
||||
HRESULT create_regexp(script_ctx_t*,const WCHAR *,int,DWORD,DispatchEx**);
|
||||
HRESULT create_regexp_var(script_ctx_t*,VARIANT*,VARIANT*,DispatchEx**);
|
||||
HRESULT create_string(script_ctx_t*,const WCHAR*,DWORD,DispatchEx**);
|
||||
HRESULT create_bool(script_ctx_t*,VARIANT_BOOL,DispatchEx**);
|
||||
HRESULT create_number(script_ctx_t*,VARIANT*,DispatchEx**);
|
||||
|
@ -262,6 +263,7 @@ struct _script_ctx_t {
|
|||
IActiveScriptSite *site;
|
||||
IInternetHostSecurityManager *secmgr;
|
||||
DWORD safeopt;
|
||||
DWORD version;
|
||||
LCID lcid;
|
||||
|
||||
jsheap_t tmp_heap;
|
||||
|
@ -316,9 +318,12 @@ typedef struct {
|
|||
DWORD len;
|
||||
} match_result_t;
|
||||
|
||||
HRESULT regexp_match_next(script_ctx_t*,DispatchEx*,BOOL,const WCHAR*,DWORD,const WCHAR**,match_result_t**,
|
||||
#define REM_CHECK_GLOBAL 0x0001
|
||||
#define REM_RESET_INDEX 0x0002
|
||||
HRESULT regexp_match_next(script_ctx_t*,DispatchEx*,DWORD,const WCHAR*,DWORD,const WCHAR**,match_result_t**,
|
||||
DWORD*,DWORD*,match_result_t*);
|
||||
HRESULT regexp_match(script_ctx_t*,DispatchEx*,const WCHAR*,DWORD,BOOL,match_result_t**,DWORD*);
|
||||
HRESULT parse_regexp_flags(const WCHAR*,DWORD,DWORD*);
|
||||
|
||||
static inline VARIANT *get_arg(DISPPARAMS *dp, DWORD i)
|
||||
{
|
||||
|
@ -390,6 +395,11 @@ static inline void num_set_inf(VARIANT *v, BOOL positive)
|
|||
#endif
|
||||
}
|
||||
|
||||
static inline DWORD make_grfdex(script_ctx_t *ctx, DWORD flags)
|
||||
{
|
||||
return (ctx->version << 28) | flags;
|
||||
}
|
||||
|
||||
const char *debugstr_variant(const VARIANT*);
|
||||
|
||||
HRESULT WINAPI JScriptFactory_CreateInstance(IClassFactory*,IUnknown*,REFIID,void**);
|
||||
|
|
|
@ -12,27 +12,27 @@ DelReg=Classes.Reg
|
|||
|
||||
[Classes.Reg]
|
||||
HKCR,"CLSID\%CLSID_JScript%",,,"JScript Language"
|
||||
HKCR,"CLSID\%CLSID_JScript%\Implemented Categories\%CATID_ActiveScript%",,,
|
||||
HKCR,"CLSID\%CLSID_JScript%\Implemented Categories\%CATID_ActiveScriptParse%",,,
|
||||
HKCR,"CLSID\%CLSID_JScript%\Implemented Categories\%CATID_ActiveScript%",,16
|
||||
HKCR,"CLSID\%CLSID_JScript%\Implemented Categories\%CATID_ActiveScriptParse%",,16
|
||||
HKCR,"CLSID\%CLSID_JScript%\InprocServer32",,,"%MODULE%"
|
||||
HKCR,"CLSID\%CLSID_JScript%\InprocServer32","ThreadingModel",,"Both"
|
||||
HKCR,"CLSID\%CLSID_JScript%\OLEScript",,,
|
||||
HKCR,"CLSID\%CLSID_JScript%\OLEScript",,16
|
||||
HKCR,"CLSID\%CLSID_JScript%\ProgID",,,"JScript"
|
||||
|
||||
HKCR,"CLSID\%CLSID_JScriptAuthor%",,,"JScript Language Authoring"
|
||||
HKCR,"CLSID\%CLSID_JScriptAuthor%\Implemented Categories\%CATID_ActiveScriptAuthor%",,,
|
||||
HKCR,"CLSID\%CLSID_JScriptAuthor%\Implemented Categories\%CATID_ActiveScriptAuthor%",,16
|
||||
HKCR,"CLSID\%CLSID_JScriptAuthor%\InprocServer32",,,"%MODULE%"
|
||||
HKCR,"CLSID\%CLSID_JScriptAuthor%\InprocServer32","ThreadingModel",,"Both"
|
||||
HKCR,"CLSID\%CLSID_JScriptAuthor%\OLEScript",,,
|
||||
HKCR,"CLSID\%CLSID_JScriptAuthor%\OLEScript",,16
|
||||
HKCR,"CLSID\%CLSID_JScriptAuthor%\ProgID",,,"JScript Author"
|
||||
|
||||
HKCR,"CLSID\%CLSID_JScriptEncode%",,,"JScript Language Encoding"
|
||||
HKCR,"CLSID\%CLSID_JScriptEncode%\Implemented Categories\%CATID_ActiveScript%",,,
|
||||
HKCR,"CLSID\%CLSID_JScriptEncode%\Implemented Categories\%CATID_ActiveScriptParse%",,,
|
||||
HKCR,"CLSID\%CLSID_JScriptEncode%\Implemented Categories\%CATID_ActiveScriptEncode%",,,
|
||||
HKCR,"CLSID\%CLSID_JScriptEncode%\Implemented Categories\%CATID_ActiveScript%",,16
|
||||
HKCR,"CLSID\%CLSID_JScriptEncode%\Implemented Categories\%CATID_ActiveScriptParse%",,16
|
||||
HKCR,"CLSID\%CLSID_JScriptEncode%\Implemented Categories\%CATID_ActiveScriptEncode%",,16
|
||||
HKCR,"CLSID\%CLSID_JScriptEncode%\InprocServer32",,,"%MODULE%"
|
||||
HKCR,"CLSID\%CLSID_JScriptEncode%\InprocServer32","ThreadingModel",,"Both"
|
||||
HKCR,"CLSID\%CLSID_JScriptEncode%\OLEScript",,,
|
||||
HKCR,"CLSID\%CLSID_JScriptEncode%\OLEScript",,16
|
||||
HKCR,"CLSID\%CLSID_JScriptEncode%\ProgID",,,"JScript.Encode"
|
||||
|
||||
HKCR,"Component Categories\%CATID_ActiveScriptAuthor%","409",,"Active Scripting Engine with Authoring"
|
||||
|
@ -42,55 +42,55 @@ HKCR,"Component Categories\%CATID_ActiveScriptEncode%","409",,"Active Scripting
|
|||
|
||||
HKCR,"ECMAScript",,,"JScript Language"
|
||||
HKCR,"ECMAScript\CLSID",,,"%CLSID_JScript%"
|
||||
HKCR,"ECMAScript\OLEScript",,,
|
||||
HKCR,"ECMAScript\OLEScript",,16
|
||||
|
||||
HKCR,"JavaScript",,,"JScript Language"
|
||||
HKCR,"JavaScript\CLSID",,,"%CLSID_JScript%"
|
||||
HKCR,"JavaScript\OLEScript",,,
|
||||
HKCR,"JavaScript\OLEScript",,16
|
||||
|
||||
HKCR,"JavaScript Author",,,"JScript Language Authoring"
|
||||
HKCR,"JavaScript Author\CLSID",,,"%CLSID_JScriptAuthor%"
|
||||
HKCR,"JavaScript Author\OLEScript",,,
|
||||
HKCR,"JavaScript Author\OLEScript",,16
|
||||
|
||||
HKCR,"JavaScript1.1",,,"JScript Language"
|
||||
HKCR,"JavaScript1.1\CLSID",,,"%CLSID_JScript%"
|
||||
HKCR,"JavaScript1.1\OLEScript",,,
|
||||
HKCR,"JavaScript1.1\OLEScript",,16
|
||||
|
||||
HKCR,"JavaScript1.1 Author",,,"JScript Language Authoring"
|
||||
HKCR,"JavaScript1.1 Author\CLSID",,,"%CLSID_JScriptAuthor%"
|
||||
HKCR,"JavaScript1.1 Author\OLEScript",,,
|
||||
HKCR,"JavaScript1.1 Author\OLEScript",,16
|
||||
|
||||
HKCR,"JavaScript1.2",,,"JScript Language"
|
||||
HKCR,"JavaScript1.2\CLSID",,,"%CLSID_JScript%"
|
||||
HKCR,"JavaScript1.2\OLEScript",,,
|
||||
HKCR,"JavaScript1.2\OLEScript",,16
|
||||
|
||||
HKCR,"JavaScript1.2 Author",,,"JScript Language Authoring"
|
||||
HKCR,"JavaScript1.2 Author\CLSID",,,"%CLSID_JScriptAuthor%"
|
||||
HKCR,"JavaScript1.2 Author\OLEScript",,,
|
||||
HKCR,"JavaScript1.2 Author\OLEScript",,16
|
||||
|
||||
HKCR,"JavaScript1.3",,,"JScript Language"
|
||||
HKCR,"JavaScript1.3\CLSID",,,"%CLSID_JScript%"
|
||||
HKCR,"JavaScript1.3\OLEScript",,,
|
||||
HKCR,"JavaScript1.3\OLEScript",,16
|
||||
|
||||
HKCR,"JScript",,,"JScript Language"
|
||||
HKCR,"JScript\CLSID",,,"%CLSID_JScript%"
|
||||
HKCR,"JScript\OLEScript",,,
|
||||
HKCR,"JScript\OLEScript",,16
|
||||
|
||||
HKCR,"JScript Author",,,"JScript Language Authoring"
|
||||
HKCR,"JScript Author\CLSID",,,"%CLSID_JScriptAuthor%"
|
||||
HKCR,"JScript Author\OLEScript",,,
|
||||
HKCR,"JScript Author\OLEScript",,16
|
||||
|
||||
HKCR,"JScript.Encode",,,"JScript Language Encoding"
|
||||
HKCR,"JScript.Encode\CLSID",,,"%CLSID_JScriptEncode%"
|
||||
HKCR,"JScript.Encode\OLEScript",,,
|
||||
HKCR,"JScript.Encode\OLEScript",,16
|
||||
|
||||
HKCR,"LiveScript",,,"JScript Language"
|
||||
HKCR,"LiveScript\CLSID",,,"%CLSID_JScript%"
|
||||
HKCR,"LiveScript\OLEScript",,,
|
||||
HKCR,"LiveScript\OLEScript",,16
|
||||
|
||||
HKCR,"LiveScript Author",,,"JScript Language Authoring"
|
||||
HKCR,"LiveScript Author\CLSID",,,"%CLSID_JScriptAuthor%"
|
||||
HKCR,"LiveScript Author\OLEScript",,,
|
||||
HKCR,"LiveScript Author\OLEScript",,16
|
||||
|
||||
|
||||
[Strings]
|
||||
|
|
|
@ -43,6 +43,7 @@ STRINGTABLE DISCARDABLE
|
|||
IDS_NOT_BOOL "Boolisches Objekt erwartet"
|
||||
IDS_JSCRIPT_EXPECTED "JScript Objekt erwartet"
|
||||
IDS_REGEXP_SYNTAX_ERROR "Syntax Fehler in regulärem Ausdruck"
|
||||
IDS_URI_INVALID_CHAR "Zu verschlüsselnde URI enthält ungültige Zeichen"
|
||||
IDS_INVALID_LENGTH "Array-Größe muss eine endliche, positive Ganzzahl sein"
|
||||
IDS_ARRAY_EXPECTED "Array Objekt erwartet"
|
||||
}
|
||||
|
|
|
@ -41,6 +41,7 @@ STRINGTABLE DISCARDABLE
|
|||
IDS_NOT_BOOL "Boolean object expected"
|
||||
IDS_JSCRIPT_EXPECTED "JScript object expected"
|
||||
IDS_REGEXP_SYNTAX_ERROR "Syntax error in regular expression"
|
||||
IDS_URI_INVALID_CHAR "URI to be encoded contains invalid characters"
|
||||
IDS_INVALID_LENGTH "Array length must be a finite positive integer"
|
||||
IDS_ARRAY_EXPECTED "Array object expected"
|
||||
}
|
||||
|
|
|
@ -46,6 +46,7 @@ STRINGTABLE DISCARDABLE
|
|||
IDS_NOT_BOOL "Objet booléen attendu"
|
||||
IDS_JSCRIPT_EXPECTED "Objet JScript attendu"
|
||||
IDS_REGEXP_SYNTAX_ERROR "Erreur de syntaxe dans l'expression rationnelle"
|
||||
IDS_URI_INVALID_CHAR "L'URI à coder contient des caractères invalides"
|
||||
IDS_INVALID_LENGTH "La longueur d'un tableau doit être un entier positif"
|
||||
IDS_ARRAY_EXPECTED "Objet tableau attendu"
|
||||
}
|
||||
|
|
51
reactos/dll/win32/jscript/jscript_Ko.rc
Normal file
51
reactos/dll/win32/jscript/jscript_Ko.rc
Normal file
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright 2009 Piotr Caban
|
||||
* Copyright 2010 YunSong Hwang
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include "resource.h"
|
||||
|
||||
/* UTF-8 */
|
||||
#pragma code_page(65001)
|
||||
|
||||
LANGUAGE LANG_KOREAN, SUBLANG_DEFAULT
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
{
|
||||
IDS_TO_PRIMITIVE "객페를 기본 형식으로 변환하는 중에 에러 발생"
|
||||
IDS_INVALID_CALL_ARG "올바르지 않은 프로시져 호출이나 인수"
|
||||
IDS_CREATE_OBJ_ERROR "자동화 서버가 객체를 만들 수 없습니다"
|
||||
IDS_NO_PROPERTY "객체는 이 속성이나 메소드를 지원하지 않습니다"
|
||||
IDS_ARG_NOT_OPT "인수는 옵션이 아닙니다"
|
||||
IDS_SYNTAX_ERROR "문법 에러"
|
||||
IDS_SEMICOLON "';' 가 필요합니다"
|
||||
IDS_LBRACKET "'(' 가 필요합니다"
|
||||
IDS_RBRACKET "')' 가 필요합니다"
|
||||
IDS_UNTERMINATED_STR "띁나지 않은 문자열 상수"
|
||||
IDS_NOT_FUNC "함수가 필요합니다"
|
||||
IDS_NOT_DATE "'[객체]' 는 날짜 객체가 아닙니다"
|
||||
IDS_NOT_NUM "숫자가 필요합니다"
|
||||
IDS_OBJECT_EXPECTED "객체가 필요합니다"
|
||||
IDS_ILLEGAL_ASSIGN "잘못된 할당"
|
||||
IDS_UNDEFINED "'|' 는 정의되지 않았습니다"
|
||||
IDS_NOT_BOOL "볼린 객제가 필요합니다"
|
||||
IDS_JSCRIPT_EXPECTED "JScript 객체가 필요합니다"
|
||||
IDS_REGEXP_SYNTAX_ERROR "정규 표현식에 문법에러가 있습니다"
|
||||
IDS_URI_INVALID_CHAR "URI 는 올바르지 않은 문자를 포함해서 인코딩되었습니다"
|
||||
IDS_INVALID_LENGTH "배열 길이는 반드시 한정된 양의 정수이어야 합니다"
|
||||
IDS_ARRAY_EXPECTED "배열 객체가 필요합니다"
|
||||
}
|
|
@ -44,6 +44,7 @@ STRINGTABLE DISCARDABLE
|
|||
IDS_NOT_BOOL "Tikėtasi loginio objekto"
|
||||
IDS_JSCRIPT_EXPECTED "Tikėtasi JScript objekto"
|
||||
IDS_REGEXP_SYNTAX_ERROR "Sintaksės klaida reguliariajame reiškinyje"
|
||||
IDS_URI_INVALID_CHAR "Koduotiname URI yra netinkamų simbolių"
|
||||
IDS_INVALID_LENGTH "Masyvo dydis turi būti teigiamas sveikasis skaičius"
|
||||
IDS_ARRAY_EXPECTED "Tikėtasi masyvo objekto"
|
||||
}
|
||||
|
|
50
reactos/dll/win32/jscript/jscript_Ru.rc
Normal file
50
reactos/dll/win32/jscript/jscript_Ru.rc
Normal file
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright 2009 Vladimir Pankratov
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include "resource.h"
|
||||
|
||||
/* UTF-8 */
|
||||
#pragma code_page(65001)
|
||||
|
||||
LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
{
|
||||
IDS_TO_PRIMITIVE "Ошибка конвертирования объекта в примитивный тип"
|
||||
IDS_INVALID_CALL_ARG "Неверный вызов процедуры или аргумент"
|
||||
IDS_CREATE_OBJ_ERROR "Сервер автоматизации не может создать объект"
|
||||
IDS_NO_PROPERTY "Объект не поддерживает это свойство или метод"
|
||||
IDS_ARG_NOT_OPT "Отсутствует обязательный аргумент"
|
||||
IDS_SYNTAX_ERROR "Синтаксическая ошибка"
|
||||
IDS_SEMICOLON "Ожидается ';'"
|
||||
IDS_LBRACKET "Ожидается '('"
|
||||
IDS_RBRACKET "Ожидается ')'"
|
||||
IDS_UNTERMINATED_STR "Незавершённая строковая константа"
|
||||
IDS_NOT_FUNC "Ожидается функция"
|
||||
IDS_NOT_DATE "'[object]' не объект типа 'date'"
|
||||
IDS_NOT_NUM "Ожидается число"
|
||||
IDS_OBJECT_EXPECTED "Ожидается объект"
|
||||
IDS_ILLEGAL_ASSIGN "Неверное присваивание"
|
||||
IDS_UNDEFINED "'|' не определён"
|
||||
IDS_NOT_BOOL "Ожидается объект типа 'bool'"
|
||||
IDS_JSCRIPT_EXPECTED "Ожидается объект типа 'JScript'"
|
||||
IDS_REGEXP_SYNTAX_ERROR "Синтаксическая ошибка в регулярном выражении"
|
||||
IDS_URI_INVALID_CHAR "URI содержит неверные символы"
|
||||
IDS_INVALID_LENGTH "Длиной массива должно быть конечное положительное число"
|
||||
IDS_ARRAY_EXPECTED "Ожидается объект типа 'Array'"
|
||||
}
|
|
@ -449,10 +449,14 @@ HRESULT to_integer(script_ctx_t *ctx, VARIANT *v, jsexcept_t *ei, VARIANT *ret)
|
|||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
if(V_VT(&num) == VT_I4)
|
||||
if(V_VT(&num) == VT_I4) {
|
||||
*ret = num;
|
||||
else
|
||||
}else if(isnan(V_R8(&num))) {
|
||||
V_VT(ret) = VT_I4;
|
||||
V_I4(ret) = 0;
|
||||
}else {
|
||||
num_set_val(ret, V_R8(&num) >= 0.0 ? floor(V_R8(&num)) : -floor(-V_R8(&num)));
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
@ -467,7 +471,10 @@ HRESULT to_int32(script_ctx_t *ctx, VARIANT *v, jsexcept_t *ei, INT *ret)
|
|||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
*ret = V_VT(&num) == VT_I4 ? V_I4(&num) : (INT)V_R8(&num);
|
||||
if(V_VT(&num) == VT_I4)
|
||||
*ret = V_I4(&num);
|
||||
else
|
||||
*ret = isnan(V_R8(&num)) || isinf(V_R8(&num)) ? 0 : (INT)V_R8(&num);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -481,7 +488,10 @@ HRESULT to_uint32(script_ctx_t *ctx, VARIANT *v, jsexcept_t *ei, DWORD *ret)
|
|||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
*ret = V_VT(&num) == VT_I4 ? V_I4(&num) : (DWORD)V_R8(&num);
|
||||
if(V_VT(&num) == VT_I4)
|
||||
*ret = V_I4(&num);
|
||||
else
|
||||
*ret = isnan(V_R8(&num)) || isinf(V_R8(&num)) ? 0 : (DWORD)V_R8(&num);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -91,7 +91,6 @@ static const struct {
|
|||
{trueW, kTRUE},
|
||||
{tryW, kTRY},
|
||||
{typeofW, kTYPEOF},
|
||||
{undefinedW, kUNDEFINED},
|
||||
{varW, kVAR},
|
||||
{voidW, kVOID},
|
||||
{whileW, kWHILE},
|
||||
|
@ -369,7 +368,7 @@ static literal_t *alloc_int_literal(parser_ctx_t *ctx, LONG l)
|
|||
{
|
||||
literal_t *ret = parser_alloc(ctx, sizeof(literal_t));
|
||||
|
||||
ret->vt = VT_I4;
|
||||
ret->type = LT_INT;
|
||||
ret->u.lval = l;
|
||||
|
||||
return ret;
|
||||
|
@ -447,7 +446,7 @@ static int parse_double_literal(parser_ctx_t *ctx, LONG int_part, literal_t **li
|
|||
}
|
||||
|
||||
*literal = parser_alloc(ctx, sizeof(literal_t));
|
||||
(*literal)->vt = VT_R8;
|
||||
(*literal)->type = LT_DOUBLE;
|
||||
(*literal)->u.dval = (double)d*pow(10, exp);
|
||||
|
||||
return tNumericLiteral;
|
||||
|
@ -755,21 +754,11 @@ int parser_lex(void *lval, parser_ctx_t *ctx)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void add_object_literal(parser_ctx_t *ctx, DispatchEx *obj)
|
||||
{
|
||||
obj_literal_t *literal = parser_alloc(ctx, sizeof(obj_literal_t));
|
||||
|
||||
literal->obj = obj;
|
||||
literal->next = ctx->obj_literals;
|
||||
ctx->obj_literals = literal;
|
||||
}
|
||||
|
||||
literal_t *parse_regexp(parser_ctx_t *ctx)
|
||||
{
|
||||
const WCHAR *re, *flags;
|
||||
DispatchEx *regexp;
|
||||
const WCHAR *re, *flags_ptr;
|
||||
DWORD re_len, flags;
|
||||
literal_t *ret;
|
||||
DWORD re_len;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("\n");
|
||||
|
@ -790,18 +779,18 @@ literal_t *parse_regexp(parser_ctx_t *ctx)
|
|||
|
||||
re_len = ctx->ptr-re;
|
||||
|
||||
flags = ++ctx->ptr;
|
||||
flags_ptr = ++ctx->ptr;
|
||||
while(ctx->ptr < ctx->end && isalnumW(*ctx->ptr))
|
||||
ctx->ptr++;
|
||||
|
||||
hres = create_regexp_str(ctx->script, re, re_len, flags, ctx->ptr-flags, ®exp);
|
||||
hres = parse_regexp_flags(flags_ptr, ctx->ptr-flags_ptr, &flags);
|
||||
if(FAILED(hres))
|
||||
return NULL;
|
||||
|
||||
add_object_literal(ctx, regexp);
|
||||
|
||||
ret = parser_alloc(ctx, sizeof(literal_t));
|
||||
ret->vt = VT_DISPATCH;
|
||||
ret->u.disp = (IDispatch*)_IDispatchEx_(regexp);
|
||||
ret->type = LT_REGEXP;
|
||||
ret->u.regexp.str = re;
|
||||
ret->u.regexp.str_len = re_len;
|
||||
ret->u.regexp.flags = flags;
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -346,7 +346,8 @@ HRESULT create_number_constr(script_ctx_t *ctx, DispatchEx *object_prototype, Di
|
|||
return hres;
|
||||
|
||||
V_VT(&number->num) = VT_I4;
|
||||
hres = create_builtin_function(ctx, NumberConstr_value, NumberW, NULL, PROPF_CONSTR, &number->dispex, ret);
|
||||
hres = create_builtin_function(ctx, NumberConstr_value, NumberW, NULL,
|
||||
PROPF_CONSTR|1, &number->dispex, ret);
|
||||
|
||||
jsdisp_release(&number->dispex);
|
||||
return hres;
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -54,34 +54,33 @@
|
|||
kINSTANCEOF = 270,
|
||||
kNEW = 271,
|
||||
kNULL = 272,
|
||||
kUNDEFINED = 273,
|
||||
kRETURN = 274,
|
||||
kSWITCH = 275,
|
||||
kTHIS = 276,
|
||||
kTHROW = 277,
|
||||
kTRUE = 278,
|
||||
kFALSE = 279,
|
||||
kTRY = 280,
|
||||
kTYPEOF = 281,
|
||||
kVAR = 282,
|
||||
kVOID = 283,
|
||||
kWHILE = 284,
|
||||
kWITH = 285,
|
||||
tANDAND = 286,
|
||||
tOROR = 287,
|
||||
tINC = 288,
|
||||
tDEC = 289,
|
||||
tHTMLCOMMENT = 290,
|
||||
kDIVEQ = 291,
|
||||
kFUNCTION = 292,
|
||||
tIdentifier = 293,
|
||||
tAssignOper = 294,
|
||||
tEqOper = 295,
|
||||
tShiftOper = 296,
|
||||
tRelOper = 297,
|
||||
tNumericLiteral = 298,
|
||||
tStringLiteral = 299,
|
||||
LOWER_THAN_ELSE = 300
|
||||
kRETURN = 273,
|
||||
kSWITCH = 274,
|
||||
kTHIS = 275,
|
||||
kTHROW = 276,
|
||||
kTRUE = 277,
|
||||
kFALSE = 278,
|
||||
kTRY = 279,
|
||||
kTYPEOF = 280,
|
||||
kVAR = 281,
|
||||
kVOID = 282,
|
||||
kWHILE = 283,
|
||||
kWITH = 284,
|
||||
tANDAND = 285,
|
||||
tOROR = 286,
|
||||
tINC = 287,
|
||||
tDEC = 288,
|
||||
tHTMLCOMMENT = 289,
|
||||
kDIVEQ = 290,
|
||||
kFUNCTION = 291,
|
||||
tIdentifier = 292,
|
||||
tAssignOper = 293,
|
||||
tEqOper = 294,
|
||||
tShiftOper = 295,
|
||||
tRelOper = 296,
|
||||
tNumericLiteral = 297,
|
||||
tStringLiteral = 298,
|
||||
LOWER_THAN_ELSE = 299
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -92,7 +91,7 @@ typedef union YYSTYPE
|
|||
{
|
||||
|
||||
/* Line 1676 of yacc.c */
|
||||
#line 151 "parser.y"
|
||||
#line 150 "parser.y"
|
||||
|
||||
int ival;
|
||||
const WCHAR *srcptr;
|
||||
|
@ -116,7 +115,7 @@ typedef union YYSTYPE
|
|||
|
||||
|
||||
/* Line 1676 of yacc.c */
|
||||
#line 120 "parser.tab.h"
|
||||
#line 119 "parser.tab.h"
|
||||
} YYSTYPE;
|
||||
# define YYSTYPE_IS_TRIVIAL 1
|
||||
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
|
||||
|
|
|
@ -38,7 +38,6 @@ typedef struct _statement_list_t {
|
|||
|
||||
static literal_t *new_string_literal(parser_ctx_t*,const WCHAR*);
|
||||
static literal_t *new_null_literal(parser_ctx_t*);
|
||||
static literal_t *new_undefined_literal(parser_ctx_t*);
|
||||
static literal_t *new_boolean_literal(parser_ctx_t*,VARIANT_BOOL);
|
||||
|
||||
typedef struct _property_list_t {
|
||||
|
@ -171,7 +170,7 @@ static source_elements_t *source_elements_add_statement(source_elements_t*,state
|
|||
|
||||
/* keywords */
|
||||
%token kBREAK kCASE kCATCH kCONTINUE kDEFAULT kDELETE kDO kELSE kIF kFINALLY kFOR kIN
|
||||
%token kINSTANCEOF kNEW kNULL kUNDEFINED kRETURN kSWITCH kTHIS kTHROW kTRUE kFALSE kTRY kTYPEOF kVAR kVOID kWHILE kWITH
|
||||
%token kINSTANCEOF kNEW kNULL kRETURN kSWITCH kTHIS kTHROW kTRUE kFALSE kTRY kTYPEOF kVAR kVOID kWHILE kWITH
|
||||
%token tANDAND tOROR tINC tDEC tHTMLCOMMENT kDIVEQ
|
||||
|
||||
%token <srcptr> kFUNCTION '}'
|
||||
|
@ -800,7 +799,6 @@ Identifier_opt
|
|||
/* ECMA-262 3rd Edition 7.8 */
|
||||
Literal
|
||||
: kNULL { $$ = new_null_literal(ctx); }
|
||||
| kUNDEFINED { $$ = new_undefined_literal(ctx); }
|
||||
| BooleanLiteral { $$ = $1; }
|
||||
| tNumericLiteral { $$ = $1; }
|
||||
| tStringLiteral { $$ = new_string_literal(ctx, $1); }
|
||||
|
@ -841,7 +839,7 @@ static literal_t *new_string_literal(parser_ctx_t *ctx, const WCHAR *str)
|
|||
{
|
||||
literal_t *ret = parser_alloc(ctx, sizeof(literal_t));
|
||||
|
||||
ret->vt = VT_BSTR;
|
||||
ret->type = LT_STRING;
|
||||
ret->u.wstr = str;
|
||||
|
||||
return ret;
|
||||
|
@ -851,16 +849,7 @@ static literal_t *new_null_literal(parser_ctx_t *ctx)
|
|||
{
|
||||
literal_t *ret = parser_alloc(ctx, sizeof(literal_t));
|
||||
|
||||
ret->vt = VT_NULL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static literal_t *new_undefined_literal(parser_ctx_t *ctx)
|
||||
{
|
||||
literal_t *ret = parser_alloc(ctx, sizeof(literal_t));
|
||||
|
||||
ret->vt = VT_EMPTY;
|
||||
ret->type = LT_NULL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -869,7 +858,7 @@ static literal_t *new_boolean_literal(parser_ctx_t *ctx, VARIANT_BOOL bval)
|
|||
{
|
||||
literal_t *ret = parser_alloc(ctx, sizeof(literal_t));
|
||||
|
||||
ret->vt = VT_BOOL;
|
||||
ret->type = LT_BOOL;
|
||||
ret->u.bval = bval;
|
||||
|
||||
return ret;
|
||||
|
@ -1591,14 +1580,11 @@ static void program_parsed(parser_ctx_t *ctx, source_elements_t *source)
|
|||
|
||||
void parser_release(parser_ctx_t *ctx)
|
||||
{
|
||||
obj_literal_t *iter;
|
||||
|
||||
if(--ctx->ref)
|
||||
return;
|
||||
|
||||
for(iter = ctx->obj_literals; iter; iter = iter->next)
|
||||
jsdisp_release(iter->obj);
|
||||
|
||||
script_release(ctx->script);
|
||||
heap_free(ctx->begin);
|
||||
jsheap_free(&ctx->heap);
|
||||
heap_free(ctx);
|
||||
}
|
||||
|
@ -1620,8 +1606,14 @@ HRESULT script_parse(script_ctx_t *ctx, const WCHAR *code, const WCHAR *delimite
|
|||
parser_ctx->hres = JSCRIPT_ERROR|IDS_SYNTAX_ERROR;
|
||||
parser_ctx->is_html = delimiter && !strcmpiW(delimiter, html_tagW);
|
||||
|
||||
parser_ctx->begin = parser_ctx->ptr = code;
|
||||
parser_ctx->end = code + strlenW(code);
|
||||
parser_ctx->begin = heap_strdupW(code);
|
||||
if(!parser_ctx->begin) {
|
||||
heap_free(parser_ctx);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
parser_ctx->ptr = parser_ctx->begin;
|
||||
parser_ctx->end = parser_ctx->begin + strlenW(parser_ctx->begin);
|
||||
|
||||
script_addref(ctx);
|
||||
parser_ctx->script = ctx;
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "jscript.h"
|
||||
|
||||
|
@ -82,7 +83,8 @@ typedef struct {
|
|||
|
||||
JSRegExp *jsregexp;
|
||||
BSTR str;
|
||||
DWORD last_index;
|
||||
INT last_index;
|
||||
VARIANT last_index_var;
|
||||
} RegExpInstance;
|
||||
|
||||
static const WCHAR sourceW[] = {'s','o','u','r','c','e',0};
|
||||
|
@ -3299,8 +3301,16 @@ static inline RegExpInstance *regexp_from_vdisp(vdisp_t *vdisp)
|
|||
return (RegExpInstance*)vdisp->u.jsdisp;
|
||||
}
|
||||
|
||||
static HRESULT do_regexp_match_next(script_ctx_t *ctx, RegExpInstance *regexp, const WCHAR *str, DWORD len,
|
||||
const WCHAR **cp, match_result_t **parens, DWORD *parens_size, DWORD *parens_cnt, match_result_t *ret)
|
||||
static void set_last_index(RegExpInstance *This, DWORD last_index)
|
||||
{
|
||||
This->last_index = last_index;
|
||||
VariantClear(&This->last_index_var);
|
||||
num_set_val(&This->last_index_var, last_index);
|
||||
}
|
||||
|
||||
static HRESULT do_regexp_match_next(script_ctx_t *ctx, RegExpInstance *regexp, DWORD rem_flags,
|
||||
const WCHAR *str, DWORD len, const WCHAR **cp, match_result_t **parens, DWORD *parens_size,
|
||||
DWORD *parens_cnt, match_result_t *ret)
|
||||
{
|
||||
REMatchState *x, *result;
|
||||
REGlobalData gData;
|
||||
|
@ -3325,8 +3335,11 @@ static HRESULT do_regexp_match_next(script_ctx_t *ctx, RegExpInstance *regexp, c
|
|||
return E_FAIL;
|
||||
}
|
||||
|
||||
if(!result)
|
||||
if(!result) {
|
||||
if(rem_flags & REM_RESET_INDEX)
|
||||
set_last_index(regexp, 0);
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
if(parens) {
|
||||
DWORD i;
|
||||
|
@ -3347,8 +3360,13 @@ static HRESULT do_regexp_match_next(script_ctx_t *ctx, RegExpInstance *regexp, c
|
|||
*parens_cnt = regexp->jsregexp->parenCount;
|
||||
|
||||
for(i=0; i < regexp->jsregexp->parenCount; i++) {
|
||||
(*parens)[i].str = *cp + result->parens[i].index;
|
||||
(*parens)[i].len = result->parens[i].length;
|
||||
if(result->parens[i].index == -1) {
|
||||
(*parens)[i].str = NULL;
|
||||
(*parens)[i].len = 0;
|
||||
}else {
|
||||
(*parens)[i].str = *cp + result->parens[i].index;
|
||||
(*parens)[i].len = result->parens[i].length;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3356,23 +3374,25 @@ static HRESULT do_regexp_match_next(script_ctx_t *ctx, RegExpInstance *regexp, c
|
|||
*cp = result->cp;
|
||||
ret->str = result->cp-matchlen;
|
||||
ret->len = matchlen;
|
||||
set_last_index(regexp, result->cp-str);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT regexp_match_next(script_ctx_t *ctx, DispatchEx *dispex, BOOL gcheck, const WCHAR *str, DWORD len,
|
||||
const WCHAR **cp, match_result_t **parens, DWORD *parens_size, DWORD *parens_cnt, match_result_t *ret)
|
||||
HRESULT regexp_match_next(script_ctx_t *ctx, DispatchEx *dispex, DWORD rem_flags, const WCHAR *str,
|
||||
DWORD len, const WCHAR **cp, match_result_t **parens, DWORD *parens_size, DWORD *parens_cnt,
|
||||
match_result_t *ret)
|
||||
{
|
||||
RegExpInstance *regexp = (RegExpInstance*)dispex;
|
||||
jsheap_t *mark;
|
||||
HRESULT hres;
|
||||
|
||||
if(gcheck && !(regexp->jsregexp->flags & JSREG_GLOB))
|
||||
if((rem_flags & REM_CHECK_GLOBAL) && !(regexp->jsregexp->flags & JSREG_GLOB))
|
||||
return S_FALSE;
|
||||
|
||||
mark = jsheap_mark(&ctx->tmp_heap);
|
||||
|
||||
hres = do_regexp_match_next(ctx, regexp, str, len, cp, parens, parens_size, parens_cnt, ret);
|
||||
hres = do_regexp_match_next(ctx, regexp, rem_flags, str, len, cp, parens, parens_size, parens_cnt, ret);
|
||||
|
||||
jsheap_clear(mark);
|
||||
return hres;
|
||||
|
@ -3391,7 +3411,7 @@ HRESULT regexp_match(script_ctx_t *ctx, DispatchEx *dispex, const WCHAR *str, DW
|
|||
mark = jsheap_mark(&ctx->tmp_heap);
|
||||
|
||||
while(1) {
|
||||
hres = do_regexp_match_next(ctx, This, str, len, &cp, NULL, NULL, NULL, &cres);
|
||||
hres = do_regexp_match_next(ctx, This, 0, str, len, &cp, NULL, NULL, NULL, &cres);
|
||||
if(hres == S_FALSE) {
|
||||
hres = S_OK;
|
||||
break;
|
||||
|
@ -3474,6 +3494,27 @@ static HRESULT RegExp_multiline(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
|
|||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static INT index_from_var(script_ctx_t *ctx, VARIANT *v)
|
||||
{
|
||||
jsexcept_t ei;
|
||||
VARIANT num;
|
||||
HRESULT hres;
|
||||
|
||||
memset(&ei, 0, sizeof(ei));
|
||||
hres = to_number(ctx, v, &ei, &num);
|
||||
if(FAILED(hres)) { /* FIXME: Move ignoring exceptions to to_promitive */
|
||||
VariantClear(&ei.var);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(V_VT(&num) == VT_R8) {
|
||||
DOUBLE d = floor(V_R8(&num));
|
||||
return (DOUBLE)(INT)d == d ? d : 0;
|
||||
}
|
||||
|
||||
return V_I4(&num);
|
||||
}
|
||||
|
||||
static HRESULT RegExp_lastIndex(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
|
||||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
|
@ -3482,8 +3523,21 @@ static HRESULT RegExp_lastIndex(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
|
|||
switch(flags) {
|
||||
case DISPATCH_PROPERTYGET: {
|
||||
RegExpInstance *regexp = regexp_from_vdisp(jsthis);
|
||||
V_VT(retv) = VT_I4;
|
||||
V_I4(retv) = regexp->last_index;
|
||||
|
||||
V_VT(retv) = VT_EMPTY;
|
||||
return VariantCopy(retv, ®exp->last_index_var);
|
||||
}
|
||||
case DISPATCH_PROPERTYPUT: {
|
||||
RegExpInstance *regexp = regexp_from_vdisp(jsthis);
|
||||
VARIANT *arg;
|
||||
HRESULT hres;
|
||||
|
||||
arg = get_arg(dp,0);
|
||||
hres = VariantCopy(®exp->last_index_var, arg);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
regexp->last_index = index_from_var(ctx, arg);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -3589,28 +3643,34 @@ static HRESULT run_exec(script_ctx_t *ctx, vdisp_t *jsthis, VARIANT *arg, jsexce
|
|||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
if(regexp->last_index < 0) {
|
||||
SysFreeString(string);
|
||||
set_last_index(regexp, 0);
|
||||
*ret = VARIANT_FALSE;
|
||||
if(input) {
|
||||
*input = NULL;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
length = SysStringLen(string);
|
||||
if(regexp->jsregexp->flags & JSREG_GLOB)
|
||||
last_index = regexp->last_index;
|
||||
|
||||
cp = string + last_index;
|
||||
hres = regexp_match_next(ctx, ®exp->dispex, FALSE, string, length, &cp, parens, parens ? &parens_size : NULL,
|
||||
parens_cnt, match);
|
||||
hres = regexp_match_next(ctx, ®exp->dispex, REM_RESET_INDEX, string, length, &cp, parens,
|
||||
parens ? &parens_size : NULL, parens_cnt, match);
|
||||
if(FAILED(hres)) {
|
||||
SysFreeString(string);
|
||||
return hres;
|
||||
}
|
||||
|
||||
if(hres == S_OK) {
|
||||
regexp->last_index = cp-string;
|
||||
*ret = VARIANT_TRUE;
|
||||
}else {
|
||||
regexp->last_index = 0;
|
||||
*ret = VARIANT_FALSE;
|
||||
}
|
||||
|
||||
if(input)
|
||||
*ret = hres == S_OK ? VARIANT_TRUE : VARIANT_FALSE;
|
||||
if(input) {
|
||||
*input = string;
|
||||
}else {
|
||||
SysFreeString(string);
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -3690,6 +3750,7 @@ static void RegExp_destructor(DispatchEx *dispex)
|
|||
|
||||
if(This->jsregexp)
|
||||
js_DestroyRegExp(This->jsregexp);
|
||||
VariantClear(&This->last_index_var);
|
||||
SysFreeString(This->str);
|
||||
heap_free(This);
|
||||
}
|
||||
|
@ -3737,7 +3798,7 @@ static HRESULT alloc_regexp(script_ctx_t *ctx, DispatchEx *object_prototype, Reg
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT create_regexp(script_ctx_t *ctx, const WCHAR *exp, int len, DWORD flags, DispatchEx **ret)
|
||||
HRESULT create_regexp(script_ctx_t *ctx, const WCHAR *exp, int len, DWORD flags, DispatchEx **ret)
|
||||
{
|
||||
RegExpInstance *regexp;
|
||||
HRESULT hres;
|
||||
|
@ -3764,73 +3825,57 @@ static HRESULT create_regexp(script_ctx_t *ctx, const WCHAR *exp, int len, DWORD
|
|||
return E_FAIL;
|
||||
}
|
||||
|
||||
V_VT(®exp->last_index_var) = VT_I4;
|
||||
V_I4(®exp->last_index_var) = 0;
|
||||
|
||||
*ret = ®exp->dispex;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT regexp_constructor(script_ctx_t *ctx, DISPPARAMS *dp, VARIANT *retv)
|
||||
HRESULT create_regexp_var(script_ctx_t *ctx, VARIANT *src_arg, VARIANT *flags_arg, DispatchEx **ret)
|
||||
{
|
||||
const WCHAR *opt = emptyW, *src;
|
||||
DispatchEx *ret;
|
||||
VARIANT *arg;
|
||||
DWORD flags;
|
||||
HRESULT hres;
|
||||
|
||||
if(!arg_cnt(dp)) {
|
||||
FIXME("no args\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
arg = get_arg(dp,0);
|
||||
if(V_VT(arg) == VT_DISPATCH) {
|
||||
if(V_VT(src_arg) == VT_DISPATCH) {
|
||||
DispatchEx *obj;
|
||||
|
||||
obj = iface_to_jsdisp((IUnknown*)V_DISPATCH(arg));
|
||||
obj = iface_to_jsdisp((IUnknown*)V_DISPATCH(src_arg));
|
||||
if(obj) {
|
||||
if(is_class(obj, JSCLASS_REGEXP)) {
|
||||
RegExpInstance *regexp = (RegExpInstance*)obj;
|
||||
|
||||
hres = create_regexp(ctx, regexp->str, -1, regexp->jsregexp->flags, &ret);
|
||||
hres = create_regexp(ctx, regexp->str, -1, regexp->jsregexp->flags, ret);
|
||||
jsdisp_release(obj);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
V_VT(retv) = VT_DISPATCH;
|
||||
V_DISPATCH(retv) = (IDispatch*)_IDispatchEx_(ret);
|
||||
return S_OK;
|
||||
return hres;
|
||||
}
|
||||
|
||||
jsdisp_release(obj);
|
||||
}
|
||||
}
|
||||
|
||||
if(V_VT(arg) != VT_BSTR) {
|
||||
FIXME("vt arg0 = %d\n", V_VT(arg));
|
||||
if(V_VT(src_arg) != VT_BSTR) {
|
||||
FIXME("flags_arg = %s\n", debugstr_variant(flags_arg));
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
src = V_BSTR(arg);
|
||||
src = V_BSTR(src_arg);
|
||||
|
||||
if(arg_cnt(dp) >= 2) {
|
||||
arg = get_arg(dp,1);
|
||||
if(V_VT(arg) != VT_BSTR) {
|
||||
FIXME("unimplemented for vt %d\n", V_VT(arg));
|
||||
if(flags_arg) {
|
||||
if(V_VT(flags_arg) != VT_BSTR) {
|
||||
FIXME("unimplemented for vt %d\n", V_VT(flags_arg));
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
opt = V_BSTR(arg);
|
||||
opt = V_BSTR(flags_arg);
|
||||
}
|
||||
|
||||
hres = create_regexp_str(ctx, src, -1, opt, strlenW(opt), &ret);
|
||||
hres = parse_regexp_flags(opt, strlenW(opt), &flags);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
if(retv) {
|
||||
V_VT(retv) = VT_DISPATCH;
|
||||
V_DISPATCH(retv) = (IDispatch*)_IDispatchEx_(ret);
|
||||
}else {
|
||||
jsdisp_release(ret);
|
||||
}
|
||||
return S_OK;
|
||||
return create_regexp(ctx, src, -1, flags, ret);
|
||||
}
|
||||
|
||||
static HRESULT RegExpConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
|
||||
|
@ -3864,8 +3909,27 @@ static HRESULT RegExpConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags
|
|||
}
|
||||
}
|
||||
/* fall through */
|
||||
case DISPATCH_CONSTRUCT:
|
||||
return regexp_constructor(ctx, dp, retv);
|
||||
case DISPATCH_CONSTRUCT: {
|
||||
DispatchEx *ret;
|
||||
HRESULT hres;
|
||||
|
||||
if(!arg_cnt(dp)) {
|
||||
FIXME("no args\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
hres = create_regexp_var(ctx, get_arg(dp,0), arg_cnt(dp) > 1 ? get_arg(dp,1) : NULL, &ret);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
if(retv) {
|
||||
V_VT(retv) = VT_DISPATCH;
|
||||
V_DISPATCH(retv) = (IDispatch*)_IDispatchEx_(ret);
|
||||
}else {
|
||||
jsdisp_release(ret);
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
default:
|
||||
FIXME("unimplemented flags: %x\n", flags);
|
||||
return E_NOTIMPL;
|
||||
|
@ -3885,39 +3949,38 @@ HRESULT create_regexp_constr(script_ctx_t *ctx, DispatchEx *object_prototype, Di
|
|||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
hres = create_builtin_function(ctx, RegExpConstr_value, RegExpW, NULL, PROPF_CONSTR, ®exp->dispex, ret);
|
||||
hres = create_builtin_function(ctx, RegExpConstr_value, RegExpW, NULL,
|
||||
PROPF_CONSTR|2, ®exp->dispex, ret);
|
||||
|
||||
jsdisp_release(®exp->dispex);
|
||||
return hres;
|
||||
}
|
||||
|
||||
HRESULT create_regexp_str(script_ctx_t *ctx, const WCHAR *exp, DWORD exp_len, const WCHAR *opt,
|
||||
DWORD opt_len, DispatchEx **ret)
|
||||
HRESULT parse_regexp_flags(const WCHAR *str, DWORD str_len, DWORD *ret)
|
||||
{
|
||||
const WCHAR *p;
|
||||
DWORD flags = 0;
|
||||
|
||||
if(opt) {
|
||||
for (p = opt; p < opt+opt_len; p++) {
|
||||
switch (*p) {
|
||||
case 'g':
|
||||
flags |= JSREG_GLOB;
|
||||
break;
|
||||
case 'i':
|
||||
flags |= JSREG_FOLD;
|
||||
break;
|
||||
case 'm':
|
||||
flags |= JSREG_MULTILINE;
|
||||
break;
|
||||
case 'y':
|
||||
flags |= JSREG_STICKY;
|
||||
break;
|
||||
default:
|
||||
WARN("wrong flag %c\n", *p);
|
||||
return E_FAIL;
|
||||
}
|
||||
for (p = str; p < str+str_len; p++) {
|
||||
switch (*p) {
|
||||
case 'g':
|
||||
flags |= JSREG_GLOB;
|
||||
break;
|
||||
case 'i':
|
||||
flags |= JSREG_FOLD;
|
||||
break;
|
||||
case 'm':
|
||||
flags |= JSREG_MULTILINE;
|
||||
break;
|
||||
case 'y':
|
||||
flags |= JSREG_STICKY;
|
||||
break;
|
||||
default:
|
||||
WARN("wrong flag %c\n", *p);
|
||||
return E_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
return create_regexp(ctx, exp, exp_len, flags, ret);
|
||||
*ret = flags;
|
||||
return S_OK;
|
||||
}
|
||||
|
|
|
@ -37,5 +37,6 @@
|
|||
#define IDS_NOT_BOOL 0x1392
|
||||
#define IDS_JSCRIPT_EXPECTED 0x1396
|
||||
#define IDS_REGEXP_SYNTAX_ERROR 0x1399
|
||||
#define IDS_URI_INVALID_CHAR 0x13A0
|
||||
#define IDS_INVALID_LENGTH 0x13A5
|
||||
#define IDS_ARRAY_EXPECTED 0x13A7
|
||||
|
|
|
@ -25,6 +25,8 @@ REGINST REGINST jscript.inf
|
|||
#include "jscript_De.rc"
|
||||
#include "jscript_En.rc"
|
||||
#include "jscript_Fr.rc"
|
||||
#include "jscript_Ko.rc"
|
||||
#include "jscript_Lt.rc"
|
||||
#include "jscript_Nl.rc"
|
||||
#include "jscript_Pt.rc"
|
||||
#include "jscript_Ru.rc"
|
||||
|
|
|
@ -656,7 +656,7 @@ static HRESULT String_match(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISP
|
|||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
hres = create_regexp_str(ctx, match_str, SysStringLen(match_str), NULL, 0, ®exp);
|
||||
hres = create_regexp(ctx, match_str, SysStringLen(match_str), 0, ®exp);
|
||||
SysFreeString(match_str);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
@ -703,6 +703,7 @@ static HRESULT String_match(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISP
|
|||
break;
|
||||
}
|
||||
|
||||
heap_free(match_result);
|
||||
SysFreeString(val_str);
|
||||
|
||||
if(SUCCEEDED(hres) && retv) {
|
||||
|
@ -795,7 +796,7 @@ static HRESULT rep_call(script_ctx_t *ctx, DispatchEx *func, const WCHAR *str, m
|
|||
if(SUCCEEDED(hres))
|
||||
hres = jsdisp_call_value(func, DISPATCH_METHOD, &dp, &var, ei, caller);
|
||||
|
||||
for(i=0; i < parens_cnt+1; i++) {
|
||||
for(i=0; i < parens_cnt+3; i++) {
|
||||
if(i != parens_cnt+1)
|
||||
SysFreeString(V_BSTR(get_arg(&dp,i)));
|
||||
}
|
||||
|
@ -819,7 +820,7 @@ static HRESULT String_replace(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DI
|
|||
DispatchEx *rep_func = NULL, *regexp = NULL;
|
||||
match_result_t *parens = NULL, match, **parens_ptr = &parens;
|
||||
strbuf_t ret = {NULL,0,0};
|
||||
BOOL gcheck = FALSE;
|
||||
DWORD re_flags = 0;
|
||||
VARIANT *arg_var;
|
||||
HRESULT hres = S_OK;
|
||||
|
||||
|
@ -896,9 +897,9 @@ static HRESULT String_replace(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DI
|
|||
|
||||
while(1) {
|
||||
if(regexp) {
|
||||
hres = regexp_match_next(ctx, regexp, gcheck, str, length, &cp, parens_ptr,
|
||||
hres = regexp_match_next(ctx, regexp, re_flags, str, length, &cp, parens_ptr,
|
||||
&parens_size, &parens_cnt, &match);
|
||||
gcheck = TRUE;
|
||||
re_flags = REM_CHECK_GLOBAL;
|
||||
|
||||
if(hres == S_FALSE) {
|
||||
hres = S_OK;
|
||||
|
@ -965,7 +966,7 @@ static HRESULT String_replace(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DI
|
|||
}
|
||||
|
||||
idx = ptr2[1] - '0';
|
||||
if(isdigitW(ptr[3]) && idx*10 + (ptr[2]-'0') <= parens_cnt) {
|
||||
if(isdigitW(ptr2[2]) && idx*10 + (ptr2[2]-'0') <= parens_cnt) {
|
||||
idx = idx*10 + (ptr[2]-'0');
|
||||
ptr = ptr2+3;
|
||||
}else if(idx && idx <= parens_cnt) {
|
||||
|
@ -1031,8 +1032,58 @@ static HRESULT String_replace(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DI
|
|||
static HRESULT String_search(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
|
||||
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
|
||||
{
|
||||
FIXME("\n");
|
||||
return E_NOTIMPL;
|
||||
DispatchEx *regexp = NULL;
|
||||
const WCHAR *str, *cp;
|
||||
match_result_t match;
|
||||
VARIANT *arg;
|
||||
DWORD length;
|
||||
BSTR val_str;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("\n");
|
||||
|
||||
hres = get_string_val(ctx, jsthis, ei, &str, &length, &val_str);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
if(!arg_cnt(dp)) {
|
||||
if(retv)
|
||||
V_VT(retv) = VT_NULL;
|
||||
SysFreeString(val_str);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
arg = get_arg(dp,0);
|
||||
if(V_VT(arg) == VT_DISPATCH) {
|
||||
regexp = iface_to_jsdisp((IUnknown*)V_DISPATCH(arg));
|
||||
if(regexp) {
|
||||
if(!is_class(regexp, JSCLASS_REGEXP)) {
|
||||
jsdisp_release(regexp);
|
||||
regexp = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!regexp) {
|
||||
hres = create_regexp_var(ctx, arg, NULL, ®exp);
|
||||
if(FAILED(hres)) {
|
||||
SysFreeString(val_str);
|
||||
return hres;
|
||||
}
|
||||
}
|
||||
|
||||
cp = str;
|
||||
hres = regexp_match_next(ctx, regexp, REM_RESET_INDEX, str, length, &cp, NULL, NULL, NULL, &match);
|
||||
SysFreeString(val_str);
|
||||
jsdisp_release(regexp);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
if(retv) {
|
||||
V_VT(retv) = VT_I4;
|
||||
V_I4(retv) = hres == S_OK ? match.str-str : -1;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/* ECMA-262 3rd Edition 15.5.4.13 */
|
||||
|
@ -1129,6 +1180,7 @@ static HRESULT String_split(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISP
|
|||
match_result_t *match_result = NULL;
|
||||
DWORD length, match_cnt, i, match_len = 0;
|
||||
const WCHAR *str, *ptr, *ptr2;
|
||||
BOOL use_regexp = FALSE;
|
||||
VARIANT *arg, var;
|
||||
DispatchEx *array;
|
||||
BSTR val_str, match_str = NULL;
|
||||
|
@ -1153,6 +1205,7 @@ static HRESULT String_split(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISP
|
|||
regexp = iface_to_jsdisp((IUnknown*)V_DISPATCH(arg));
|
||||
if(regexp) {
|
||||
if(is_class(regexp, JSCLASS_REGEXP)) {
|
||||
use_regexp = TRUE;
|
||||
hres = regexp_match(ctx, regexp, str, length, TRUE, &match_result, &match_cnt);
|
||||
jsdisp_release(regexp);
|
||||
if(FAILED(hres)) {
|
||||
|
@ -1183,7 +1236,7 @@ static HRESULT String_split(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISP
|
|||
if(SUCCEEDED(hres)) {
|
||||
ptr = str;
|
||||
for(i=0;; i++) {
|
||||
if(match_result) {
|
||||
if(use_regexp) {
|
||||
if(i == match_cnt)
|
||||
break;
|
||||
ptr2 = match_result[i].str;
|
||||
|
@ -1209,7 +1262,7 @@ static HRESULT String_split(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISP
|
|||
if(FAILED(hres))
|
||||
break;
|
||||
|
||||
if(match_result)
|
||||
if(use_regexp)
|
||||
ptr = match_result[i].str + match_result[i].len;
|
||||
else if(match_str)
|
||||
ptr = ptr2 + match_len;
|
||||
|
@ -1218,7 +1271,7 @@ static HRESULT String_split(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISP
|
|||
}
|
||||
}
|
||||
|
||||
if(SUCCEEDED(hres) && (match_str || match_result)) {
|
||||
if(SUCCEEDED(hres) && (match_str || use_regexp)) {
|
||||
DWORD len = (str+length) - ptr;
|
||||
|
||||
if(len || match_str) {
|
||||
|
@ -1705,7 +1758,7 @@ HRESULT create_string_constr(script_ctx_t *ctx, DispatchEx *object_prototype, Di
|
|||
return hres;
|
||||
|
||||
hres = create_builtin_function(ctx, StringConstr_value, StringW, &StringConstr_info,
|
||||
PROPF_CONSTR, &string->dispex, ret);
|
||||
PROPF_CONSTR|1, &string->dispex, ret);
|
||||
|
||||
jsdisp_release(&string->dispex);
|
||||
return hres;
|
||||
|
|
Loading…
Reference in a new issue