-sync jscript with wine 1.1.31

svn path=/trunk/; revision=43607
This commit is contained in:
Christoph von Wittich 2009-10-19 17:03:21 +00:00
parent e182f235a1
commit ed2ac13f03
32 changed files with 3972 additions and 2169 deletions

View file

@ -0,0 +1,199 @@
/*
* Copyright 2009 Jacek Caban for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
#include "wine/port.h"
#include "jscript.h"
#include "objsafe.h"
#include "mshtmhst.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(jscript);
/* Defined as extern in urlmon.idl, but not exported by uuid.lib */
const GUID GUID_CUSTOM_CONFIRMOBJECTSAFETY =
{0x10200490,0xfa38,0x11d0,{0xac,0x0e,0x00,0xa0,0xc9,0xf,0xff,0xc0}};
static IInternetHostSecurityManager *get_sec_mgr(script_ctx_t *ctx)
{
IInternetHostSecurityManager *secmgr;
IServiceProvider *sp;
HRESULT hres;
if(!ctx->site)
return NULL;
if(ctx->secmgr)
return ctx->secmgr;
hres = IActiveScriptSite_QueryInterface(ctx->site, &IID_IServiceProvider, (void**)&sp);
if(FAILED(hres))
return NULL;
hres = IServiceProvider_QueryService(sp, &SID_SInternetHostSecurityManager, &IID_IInternetHostSecurityManager,
(void**)&secmgr);
IServiceProvider_Release(sp);
if(FAILED(hres))
return NULL;
return ctx->secmgr = secmgr;
}
static IUnknown *create_activex_object(script_ctx_t *ctx, const WCHAR *progid)
{
IInternetHostSecurityManager *secmgr;
IObjectWithSite *obj_site;
struct CONFIRMSAFETY cs;
IClassFactoryEx *cfex;
IClassFactory *cf;
DWORD policy_size;
BYTE *bpolicy;
IUnknown *obj;
DWORD policy;
GUID guid;
HRESULT hres;
hres = CLSIDFromProgID(progid, &guid);
if(FAILED(hres))
return NULL;
TRACE("GUID %s\n", debugstr_guid(&guid));
secmgr = get_sec_mgr(ctx);
if(!secmgr)
return NULL;
policy = 0;
hres = IInternetHostSecurityManager_ProcessUrlAction(secmgr, URLACTION_ACTIVEX_RUN, (BYTE*)&policy, sizeof(policy),
(BYTE*)&guid, sizeof(GUID), 0, 0);
if(FAILED(hres) || policy != URLPOLICY_ALLOW)
return NULL;
hres = CoGetClassObject(&guid, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER, NULL, &IID_IClassFactory, (void**)&cf);
if(FAILED(hres))
return NULL;
hres = IClassFactory_QueryInterface(cf, &IID_IClassFactoryEx, (void**)&cfex);
if(SUCCEEDED(hres)) {
FIXME("Use IClassFactoryEx\n");
IClassFactoryEx_Release(cfex);
}
hres = IClassFactory_CreateInstance(cf, NULL, &IID_IUnknown, (void**)&obj);
if(FAILED(hres))
return NULL;
cs.clsid = guid;
cs.pUnk = obj;
cs.dwFlags = 0;
hres = IInternetHostSecurityManager_QueryCustomPolicy(secmgr, &GUID_CUSTOM_CONFIRMOBJECTSAFETY, &bpolicy, &policy_size,
(BYTE*)&cs, sizeof(cs), 0);
if(SUCCEEDED(hres)) {
policy = policy_size >= sizeof(DWORD) ? *(DWORD*)bpolicy : URLPOLICY_DISALLOW;
CoTaskMemFree(bpolicy);
}
if(FAILED(hres) || policy != URLPOLICY_ALLOW) {
IUnknown_Release(obj);
return NULL;
}
hres = IUnknown_QueryInterface(obj, &IID_IObjectWithSite, (void**)&obj_site);
if(SUCCEEDED(hres)) {
IUnknown *ax_site;
ax_site = create_ax_site(ctx);
if(ax_site) {
hres = IObjectWithSite_SetSite(obj_site, ax_site);
IUnknown_Release(ax_site);
}
IObjectWithSite_Release(obj_site);
if(!ax_site || FAILED(hres)) {
IObjectWithSite_Release(obj_site);
IUnknown_Release(obj);
return NULL;
}
}
return obj;
}
static HRESULT ActiveXObject_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
{
IDispatch *disp;
IUnknown *obj;
BSTR progid;
HRESULT hres;
TRACE("\n");
if(flags != DISPATCH_CONSTRUCT) {
FIXME("unsupported flags %x\n", flags);
return E_NOTIMPL;
}
if(ctx->safeopt != (INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER)) {
FIXME("Unsupported safeopt %x\n", ctx->safeopt);
return E_NOTIMPL;
}
if(arg_cnt(dp) != 1) {
FIXME("unsupported arg_cnt %d\n", arg_cnt(dp));
return E_NOTIMPL;
}
hres = to_string(ctx, get_arg(dp,0), ei, &progid);
if(FAILED(hres))
return hres;
obj = create_activex_object(ctx, progid);
SysFreeString(progid);
if(!obj)
return throw_generic_error(ctx, ei, IDS_CREATE_OBJ_ERROR, NULL);
hres = IUnknown_QueryInterface(obj, &IID_IDispatch, (void**)&disp);
IUnknown_Release(obj);
if(FAILED(hres)) {
FIXME("Object does not support IDispatch\n");
return E_NOTIMPL;
}
V_VT(retv) = VT_DISPATCH;
V_DISPATCH(retv) = disp;
return S_OK;
}
HRESULT create_activex_constr(script_ctx_t *ctx, DispatchEx **ret)
{
DispatchEx *prototype;
HRESULT hres;
static const WCHAR ActiveXObjectW[] = {'A','c','t','i','v','e','X','O','b','j','e','c','t',0};
hres = create_object(ctx, NULL, &prototype);
if(FAILED(hres))
return hres;
hres = create_builtin_function(ctx, ActiveXObject_value, ActiveXObjectW, NULL, PROPF_CONSTR, prototype, ret);
jsdisp_release(prototype);
return hres;
}

View file

@ -46,10 +46,78 @@ static const WCHAR unshiftW[] = {'u','n','s','h','i','f','t',0};
static const WCHAR default_separatorW[] = {',',0};
static HRESULT Array_length(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static inline ArrayInstance *array_from_vdisp(vdisp_t *vdisp)
{
return (ArrayInstance*)vdisp->u.jsdisp;
}
static inline ArrayInstance *array_this(vdisp_t *jsthis)
{
return is_vclass(jsthis, JSCLASS_ARRAY) ? array_from_vdisp(jsthis) : NULL;
}
static HRESULT get_length(script_ctx_t *ctx, vdisp_t *vdisp, jsexcept_t *ei, DispatchEx **jsthis, DWORD *ret)
{
ArrayInstance *array;
VARIANT var;
HRESULT hres;
array = array_this(vdisp);
if(array) {
*jsthis = &array->dispex;
*ret = array->length;
return S_OK;
}
if(!is_jsdisp(vdisp))
return throw_type_error(ctx, ei, IDS_JSCRIPT_EXPECTED, NULL);
hres = jsdisp_propget_name(vdisp->u.jsdisp, lengthW, &var, ei, NULL/*FIXME*/);
if(FAILED(hres))
return hres;
hres = to_uint32(ctx, &var, ei, ret);
VariantClear(&var);
if(FAILED(hres))
return hres;
*jsthis = vdisp->u.jsdisp;
return S_OK;
}
static HRESULT set_length(DispatchEx *obj, jsexcept_t *ei, DWORD length)
{
VARIANT var;
if(is_class(obj, JSCLASS_ARRAY)) {
((ArrayInstance*)obj)->length = length;
return S_OK;
}
V_VT(&var) = VT_I4;
V_I4(&var) = length;
return jsdisp_propput_name(obj, lengthW, &var, ei, NULL/*FIXME*/);
}
static WCHAR *idx_to_str(DWORD idx, WCHAR *ptr)
{
if(!idx) {
*ptr = '0';
return ptr;
}
while(idx) {
*ptr-- = '0' + (idx%10);
idx /= 10;
}
return ptr+1;
}
static HRESULT Array_length(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
ArrayInstance *This = (ArrayInstance*)dispex;
ArrayInstance *This = array_from_vdisp(jsthis);
TRACE("%p %d\n", This, This->length);
@ -64,17 +132,17 @@ static HRESULT Array_length(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAM
DWORD i;
HRESULT hres;
hres = to_number(dispex->ctx, get_arg(dp, 0), ei, &num);
hres = to_number(ctx, get_arg(dp, 0), ei, &num);
if(V_VT(&num) == VT_I4)
len = V_I4(&num);
else
len = floor(V_R8(&num));
if(len!=(DWORD)len)
return throw_range_error(dispex->ctx, ei, IDS_INVALID_LENGTH, NULL);
return throw_range_error(ctx, ei, IDS_INVALID_LENGTH, NULL);
for(i=len; i<This->length; i++) {
hres = jsdisp_delete_idx(dispex, i);
hres = jsdisp_delete_idx(&This->dispex, i);
if(FAILED(hres))
return hres;
}
@ -90,7 +158,7 @@ static HRESULT Array_length(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAM
return S_OK;
}
static HRESULT concat_array(DispatchEx *array, ArrayInstance *obj, DWORD *len, LCID lcid,
static HRESULT concat_array(DispatchEx *array, ArrayInstance *obj, DWORD *len,
jsexcept_t *ei, IServiceProvider *caller)
{
VARIANT var;
@ -98,13 +166,13 @@ static HRESULT concat_array(DispatchEx *array, ArrayInstance *obj, DWORD *len, L
HRESULT hres;
for(i=0; i < obj->length; i++) {
hres = jsdisp_propget_idx(&obj->dispex, i, lcid, &var, ei, caller);
hres = jsdisp_propget_idx(&obj->dispex, i, &var, ei, caller);
if(hres == DISP_E_UNKNOWNNAME)
continue;
if(FAILED(hres))
return hres;
hres = jsdisp_propput_idx(array, *len+i, lcid, &var, ei, caller);
hres = jsdisp_propput_idx(array, *len+i, &var, ei, caller);
VariantClear(&var);
if(FAILED(hres))
return hres;
@ -114,7 +182,7 @@ static HRESULT concat_array(DispatchEx *array, ArrayInstance *obj, DWORD *len, L
return S_OK;
}
static HRESULT concat_obj(DispatchEx *array, IDispatch *obj, DWORD *len, LCID lcid, jsexcept_t *ei, IServiceProvider *caller)
static HRESULT concat_obj(DispatchEx *array, IDispatch *obj, DWORD *len, jsexcept_t *ei, IServiceProvider *caller)
{
DispatchEx *jsobj;
VARIANT var;
@ -123,7 +191,7 @@ static HRESULT concat_obj(DispatchEx *array, IDispatch *obj, DWORD *len, LCID lc
jsobj = iface_to_jsdisp((IUnknown*)obj);
if(jsobj) {
if(is_class(jsobj, JSCLASS_ARRAY)) {
hres = concat_array(array, (ArrayInstance*)jsobj, len, lcid, ei, caller);
hres = concat_array(array, (ArrayInstance*)jsobj, len, ei, caller);
jsdisp_release(jsobj);
return hres;
}
@ -132,10 +200,10 @@ static HRESULT concat_obj(DispatchEx *array, IDispatch *obj, DWORD *len, LCID lc
V_VT(&var) = VT_DISPATCH;
V_DISPATCH(&var) = obj;
return jsdisp_propput_idx(array, (*len)++, lcid, &var, ei, caller);
return jsdisp_propput_idx(array, (*len)++, &var, ei, caller);
}
static HRESULT Array_concat(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT Array_concat(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
{
DispatchEx *ret;
@ -144,11 +212,11 @@ static HRESULT Array_concat(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAM
TRACE("\n");
hres = create_array(dispex->ctx, 0, &ret);
hres = create_array(ctx, 0, &ret);
if(FAILED(hres))
return hres;
hres = concat_obj(ret, (IDispatch*)_IDispatchEx_(dispex), &len, lcid, ei, caller);
hres = concat_obj(ret, jsthis->u.disp, &len, ei, caller);
if(SUCCEEDED(hres)) {
VARIANT *arg;
DWORD i;
@ -156,9 +224,9 @@ static HRESULT Array_concat(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAM
for(i=0; i < arg_cnt(dp); i++) {
arg = get_arg(dp, i);
if(V_VT(arg) == VT_DISPATCH)
hres = concat_obj(ret, V_DISPATCH(arg), &len, lcid, ei, caller);
hres = concat_obj(ret, V_DISPATCH(arg), &len, ei, caller);
else
hres = jsdisp_propput_idx(ret, len++, lcid, arg, ei, caller);
hres = jsdisp_propput_idx(ret, len++, arg, ei, caller);
if(FAILED(hres))
break;
}
@ -176,7 +244,7 @@ static HRESULT Array_concat(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAM
return S_OK;
}
static HRESULT array_join(DispatchEx *array, LCID lcid, DWORD length, const WCHAR *sep, VARIANT *retv,
static HRESULT array_join(script_ctx_t *ctx, DispatchEx *array, DWORD length, const WCHAR *sep, VARIANT *retv,
jsexcept_t *ei, IServiceProvider *caller)
{
BSTR *str_tab, ret = NULL;
@ -199,12 +267,12 @@ static HRESULT array_join(DispatchEx *array, LCID lcid, DWORD length, const WCHA
return E_OUTOFMEMORY;
for(i=0; i < length; i++) {
hres = jsdisp_propget_idx(array, i, lcid, &var, ei, caller);
hres = jsdisp_propget_idx(array, i, &var, ei, caller);
if(FAILED(hres))
break;
if(V_VT(&var) != VT_EMPTY && V_VT(&var) != VT_NULL)
hres = to_string(array->ctx, &var, ei, str_tab+i);
hres = to_string(ctx, &var, ei, str_tab+i);
VariantClear(&var);
if(FAILED(hres))
break;
@ -274,7 +342,7 @@ static HRESULT array_join(DispatchEx *array, LCID lcid, DWORD length, const WCHA
}
/* ECMA-262 3rd Edition 15.4.4.5 */
static HRESULT Array_join(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT Array_join(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
{
DWORD length;
@ -282,8 +350,8 @@ static HRESULT Array_join(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS
TRACE("\n");
if(is_class(dispex, JSCLASS_ARRAY)) {
length = ((ArrayInstance*)dispex)->length;
if(is_vclass(jsthis, JSCLASS_ARRAY)) {
length = array_from_vdisp(jsthis)->length;
}else {
FIXME("dispid is not Array\n");
return E_NOTIMPL;
@ -292,21 +360,21 @@ static HRESULT Array_join(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS
if(arg_cnt(dp)) {
BSTR sep;
hres = to_string(dispex->ctx, dp->rgvarg + dp->cArgs-1, ei, &sep);
hres = to_string(ctx, get_arg(dp,0), ei, &sep);
if(FAILED(hres))
return hres;
hres = array_join(dispex, lcid, length, sep, retv, ei, caller);
hres = array_join(ctx, jsthis->u.jsdisp, length, sep, retv, ei, caller);
SysFreeString(sep);
}else {
hres = array_join(dispex, lcid, length, default_separatorW, retv, ei, caller);
hres = array_join(ctx, jsthis->u.jsdisp, length, default_separatorW, retv, ei, caller);
}
return hres;
}
static HRESULT Array_pop(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT Array_pop(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
{
VARIANT val;
@ -319,8 +387,8 @@ static HRESULT Array_pop(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *
TRACE("\n");
if(is_class(dispex, JSCLASS_ARRAY)) {
ArrayInstance *array = (ArrayInstance*)dispex;
if(is_vclass(jsthis, JSCLASS_ARRAY)) {
ArrayInstance *array = array_from_vdisp(jsthis);
length = array->length;
}else {
FIXME("not Array this\n");
@ -334,13 +402,13 @@ static HRESULT Array_pop(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *
}
sprintfW(buf, formatW, --length);
hres = jsdisp_get_id(dispex, buf, 0, &id);
hres = jsdisp_get_id(jsthis->u.jsdisp, buf, 0, &id);
if(SUCCEEDED(hres)) {
hres = jsdisp_propget(dispex, id, lcid, &val, ei, caller);
hres = jsdisp_propget(jsthis->u.jsdisp, id, &val, ei, caller);
if(FAILED(hres))
return hres;
hres = IDispatchEx_DeleteMemberByDispID(_IDispatchEx_(dispex), id);
hres = IDispatchEx_DeleteMemberByDispID(jsthis->u.dispex, id);
}else if(hres == DISP_E_UNKNOWNNAME) {
V_VT(&val) = VT_EMPTY;
hres = S_OK;
@ -349,10 +417,8 @@ static HRESULT Array_pop(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *
}
if(SUCCEEDED(hres)) {
if(is_class(dispex, JSCLASS_ARRAY)) {
ArrayInstance *array = (ArrayInstance*)dispex;
array->length = length;
}
ArrayInstance *array = array_from_vdisp(jsthis);
array->length = length;
}
if(FAILED(hres)) {
@ -368,29 +434,31 @@ static HRESULT Array_pop(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *
}
/* ECMA-262 3rd Edition 15.4.4.7 */
static HRESULT Array_push(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT Array_push(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
DispatchEx *jsthis;
DWORD length = 0;
int i, n;
HRESULT hres;
TRACE("\n");
if(dispex->builtin_info->class == JSCLASS_ARRAY) {
length = ((ArrayInstance*)dispex)->length;
}else {
FIXME("not Array this\n");
return E_NOTIMPL;
}
hres = get_length(ctx, vthis, ei, &jsthis, &length);
if(FAILED(hres))
return hres;
n = dp->cArgs - dp->cNamedArgs;
n = arg_cnt(dp);
for(i=0; i < n; i++) {
hres = jsdisp_propput_idx(dispex, length+i, lcid, get_arg(dp, i), ei, sp);
hres = jsdisp_propput_idx(jsthis, length+i, get_arg(dp, i), ei, sp);
if(FAILED(hres))
return hres;
}
hres = set_length(jsthis, ei, length+n);
if(FAILED(hres))
return hres;
if(retv) {
V_VT(retv) = VT_I4;
V_I4(retv) = length+n;
@ -398,24 +466,72 @@ static HRESULT Array_push(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS
return S_OK;
}
static HRESULT Array_reverse(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
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;
}
static HRESULT Array_shift(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
/* ECMA-262 3rd Edition 15.4.4.9 */
static HRESULT Array_shift(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
{
FIXME("\n");
return E_NOTIMPL;
DispatchEx *jsthis;
DWORD length = 0, i;
VARIANT v, ret;
HRESULT hres;
TRACE("\n");
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(!length) {
if(retv)
V_VT(retv) = VT_EMPTY;
return S_OK;
}
hres = jsdisp_propget_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);
if(hres == DISP_E_UNKNOWNNAME)
hres = jsdisp_delete_idx(jsthis, i-1);
else if(SUCCEEDED(hres))
hres = jsdisp_propput_idx(jsthis, i-1, &v, ei, caller);
}
if(SUCCEEDED(hres)) {
hres = jsdisp_delete_idx(jsthis, length-1);
if(SUCCEEDED(hres))
hres = set_length(jsthis, ei, length-1);
}
if(SUCCEEDED(hres) && retv)
*retv = ret;
else
VariantClear(&ret);
return hres;
}
static HRESULT Array_slice(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
/* ECMA-262 3rd Edition 15.4.4.10 */
static HRESULT Array_slice(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
DispatchEx *arr;
DispatchEx *arr, *jsthis;
VARIANT v;
DOUBLE range;
DWORD length, start, end, idx;
@ -423,15 +539,12 @@ static HRESULT Array_slice(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS
TRACE("\n");
if(is_class(dispex, JSCLASS_ARRAY)) {
length = ((ArrayInstance*)dispex)->length;
}else {
FIXME("not Array this\n");
return E_NOTIMPL;
}
hres = get_length(ctx, vthis, ei, &jsthis, &length);
if(FAILED(hres))
return hres;
if(arg_cnt(dp)) {
hres = to_number(dispex->ctx, get_arg(dp, 0), ei, &v);
hres = to_number(ctx, get_arg(dp, 0), ei, &v);
if(FAILED(hres))
return hres;
@ -448,7 +561,7 @@ static HRESULT Array_slice(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS
else start = 0;
if(arg_cnt(dp)>1) {
hres = to_number(dispex->ctx, get_arg(dp, 1), ei, &v);
hres = to_number(ctx, get_arg(dp, 1), ei, &v);
if(FAILED(hres))
return hres;
@ -464,17 +577,17 @@ static HRESULT Array_slice(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS
}
else end = length;
hres = create_array(dispex->ctx, (end>start)?end-start:0, &arr);
hres = create_array(ctx, (end>start)?end-start:0, &arr);
if(FAILED(hres))
return hres;
for(idx=start; idx<end; idx++) {
hres = jsdisp_propget_idx(dispex, idx, lcid, &v, ei, sp);
hres = jsdisp_propget_idx(jsthis, idx, &v, ei, sp);
if(hres == DISP_E_UNKNOWNNAME)
continue;
if(SUCCEEDED(hres))
hres = jsdisp_propput_idx(arr, idx-start, lcid, &v, ei, sp);
hres = jsdisp_propput_idx(arr, idx-start, &v, ei, sp);
if(FAILED(hres)) {
jsdisp_release(arr);
@ -506,7 +619,7 @@ static HRESULT sort_cmp(script_ctx_t *ctx, DispatchEx *cmp_func, VARIANT *v1, VA
args[0] = *v2;
args[1] = *v1;
hres = jsdisp_call_value(cmp_func, ctx->lcid, DISPATCH_METHOD, &dp, &res, ei, caller);
hres = jsdisp_call_value(cmp_func, DISPATCH_METHOD, &dp, &res, ei, caller);
if(FAILED(hres))
return hres;
@ -548,7 +661,7 @@ 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(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT Array_sort(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
{
DispatchEx *cmp_func = NULL;
@ -559,8 +672,8 @@ static HRESULT Array_sort(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS
TRACE("\n");
if(is_class(dispex, JSCLASS_ARRAY)) {
length = ((ArrayInstance*)dispex)->length;
if(is_vclass(jsthis, JSCLASS_ARRAY)) {
length = array_from_vdisp(jsthis)->length;
}else {
FIXME("unsupported this not array\n");
return E_NOTIMPL;
@ -594,8 +707,8 @@ static HRESULT Array_sort(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS
jsdisp_release(cmp_func);
if(retv) {
V_VT(retv) = VT_DISPATCH;
V_DISPATCH(retv) = (IDispatch*)_IDispatchEx_(dispex);
IDispatchEx_AddRef(_IDispatchEx_(dispex));
V_DISPATCH(retv) = jsthis->u.disp;
IDispatch_AddRef(jsthis->u.disp);
}
return S_OK;
}
@ -603,7 +716,7 @@ static HRESULT Array_sort(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS
vtab = heap_alloc_zero(length * sizeof(VARIANT));
if(vtab) {
for(i=0; i<length; i++) {
hres = jsdisp_propget_idx(dispex, i, lcid, vtab+i, ei, caller);
hres = jsdisp_propget_idx(jsthis->u.jsdisp, i, vtab+i, ei, caller);
if(FAILED(hres) && hres != DISP_E_UNKNOWNNAME) {
WARN("Could not get elem %d: %08x\n", i, hres);
break;
@ -629,7 +742,7 @@ static HRESULT Array_sort(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS
sorttab[i] = vtab+i;
for(i=0; i < length/2; i++) {
hres = sort_cmp(dispex->ctx, cmp_func, sorttab[2*i+1], sorttab[2*i], ei, caller, &cmp);
hres = sort_cmp(ctx, cmp_func, sorttab[2*i+1], sorttab[2*i], ei, caller, &cmp);
if(FAILED(hres))
break;
@ -654,7 +767,7 @@ static HRESULT Array_sort(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS
memcpy(tmpbuf, sorttab+i, k*sizeof(VARIANT*));
while(a < k && b < bend) {
hres = sort_cmp(dispex->ctx, cmp_func, tmpbuf[a], sorttab[i+k+b], ei, caller, &cmp);
hres = sort_cmp(ctx, cmp_func, tmpbuf[a], sorttab[i+k+b], ei, caller, &cmp);
if(FAILED(hres))
break;
@ -680,7 +793,7 @@ static HRESULT Array_sort(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS
}
for(i=0; SUCCEEDED(hres) && i < length; i++)
hres = jsdisp_propput_idx(dispex, i, lcid, sorttab[i], ei, caller);
hres = jsdisp_propput_idx(jsthis->u.jsdisp, i, sorttab[i], ei, caller);
}
if(vtab) {
@ -697,58 +810,217 @@ static HRESULT Array_sort(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS
if(retv) {
V_VT(retv) = VT_DISPATCH;
V_DISPATCH(retv) = (IDispatch*)_IDispatchEx_(dispex);
IDispatch_AddRef(_IDispatchEx_(dispex));
V_DISPATCH(retv) = jsthis->u.disp;
IDispatch_AddRef(jsthis->u.disp);
}
return S_OK;
}
static HRESULT Array_splice(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
/* ECMA-262 3rd Edition 15.4.4.12 */
static HRESULT Array_splice(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
{
FIXME("\n");
return E_NOTIMPL;
DWORD length, start=0, delete_cnt=0, argc, i, add_args = 0;
DispatchEx *ret_array = NULL, *jsthis;
VARIANT v;
HRESULT hres = S_OK;
TRACE("\n");
hres = get_length(ctx, vthis, ei, &jsthis, &length);
if(FAILED(hres))
return hres;
argc = arg_cnt(dp);
if(argc >= 1) {
hres = to_integer(ctx, get_arg(dp,0), ei, &v);
if(FAILED(hres))
return hres;
if(V_VT(&v) == VT_I4) {
if(V_I4(&v) >= 0)
start = min(V_I4(&v), length);
else
start = -V_I4(&v) > length ? 0 : length + V_I4(&v);
}else {
start = V_R8(&v) < 0.0 ? 0 : length;
}
}
if(argc >= 2) {
hres = to_integer(ctx, get_arg(dp,1), ei, &v);
if(FAILED(hres))
return hres;
if(V_VT(&v) == VT_I4) {
if(V_I4(&v) > 0)
delete_cnt = min(V_I4(&v), length-start);
}else if(V_R8(&v) > 0.0) {
delete_cnt = length-start;
}
add_args = argc-2;
}
if(retv) {
hres = create_array(ctx, 0, &ret_array);
if(FAILED(hres))
return hres;
for(i=0; SUCCEEDED(hres) && i < delete_cnt; i++) {
hres = jsdisp_propget_idx(jsthis, start+i, &v, ei, caller);
if(hres == DISP_E_UNKNOWNNAME)
hres = S_OK;
else if(SUCCEEDED(hres))
hres = jsdisp_propput_idx(ret_array, i, &v, ei, caller);
}
if(SUCCEEDED(hres)) {
V_VT(&v) = VT_I4;
V_I4(&v) = delete_cnt;
hres = jsdisp_propput_name(ret_array, lengthW, &v, ei, caller);
}
}
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);
if(hres == DISP_E_UNKNOWNNAME)
hres = jsdisp_delete_idx(jsthis, i+add_args);
else if(SUCCEEDED(hres))
hres = jsdisp_propput_idx(jsthis, i+add_args, &v, ei, caller);
}
for(i=length; SUCCEEDED(hres) && i != length-delete_cnt+add_args; i--)
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);
if(hres == DISP_E_UNKNOWNNAME)
hres = jsdisp_delete_idx(jsthis, i+add_args-1);
else if(SUCCEEDED(hres))
hres = jsdisp_propput_idx(jsthis, i+add_args-1, &v, ei, caller);
}
}
for(i=0; SUCCEEDED(hres) && i < add_args; i++)
hres = jsdisp_propput_idx(jsthis, start+i, get_arg(dp,i+2), ei, caller);
if(SUCCEEDED(hres)) {
V_VT(&v) = VT_I4;
V_I4(&v) = length-delete_cnt+add_args;
hres = jsdisp_propput_name(jsthis, lengthW, &v, ei, caller);
}
if(FAILED(hres)) {
if(ret_array)
jsdisp_release(ret_array);
return hres;
}
if(retv) {
V_VT(retv) = VT_DISPATCH;
V_DISPATCH(retv) = (IDispatch*)_IDispatchEx_(ret_array);
}
return S_OK;
}
/* ECMA-262 3rd Edition 15.4.4.2 */
static HRESULT Array_toString(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT Array_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
ArrayInstance *array;
TRACE("\n");
if(!is_class(dispex, JSCLASS_ARRAY)) {
WARN("not Array object\n");
return E_FAIL;
array = array_this(jsthis);
if(!array)
return throw_type_error(ctx, ei, IDS_ARRAY_EXPECTED, NULL);
return array_join(ctx, &array->dispex, array->length, default_separatorW, retv, ei, sp);
}
static HRESULT Array_toLocaleString(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
FIXME("\n");
return E_NOTIMPL;
}
/* ECMA-262 3rd Edition 15.4.4.13 */
static HRESULT Array_unshift(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
{
DispatchEx *jsthis;
WCHAR buf[14], *buf_end, *str;
DWORD argc, i, length;
VARIANT var;
DISPID id;
HRESULT hres;
TRACE("\n");
hres = get_length(ctx, vthis, ei, &jsthis, &length);
if(FAILED(hres))
return hres;
argc = arg_cnt(dp);
if(!argc) {
if(retv)
V_VT(retv) = VT_EMPTY;
return S_OK;
}
return array_join(dispex, lcid, ((ArrayInstance*)dispex)->length, default_separatorW, retv, ei, sp);
buf_end = buf + sizeof(buf)/sizeof(WCHAR)-1;
*buf_end-- = 0;
i = length;
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_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))
return hres;
}
for(i=0; i<argc; i++) {
hres = jsdisp_propput_idx(jsthis, i, get_arg(dp,i), ei, caller);
if(FAILED(hres))
return hres;
}
hres = set_length(jsthis, ei, length+argc);
if(FAILED(hres))
return hres;
if(retv)
V_VT(retv) = VT_EMPTY;
return S_OK;
}
static HRESULT Array_toLocaleString(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
FIXME("\n");
return E_NOTIMPL;
}
static HRESULT Array_unshift(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
FIXME("\n");
return E_NOTIMPL;
}
static HRESULT Array_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT Array_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
TRACE("\n");
switch(flags) {
case INVOKE_FUNC:
return throw_type_error(dispex->ctx, ei, IDS_NOT_FUNC, NULL);
return throw_type_error(ctx, ei, IDS_NOT_FUNC, NULL);
case INVOKE_PROPERTYGET:
return array_join(dispex, lcid, ((ArrayInstance*)dispex)->length, default_separatorW, retv, ei, sp);
return array_join(ctx, jsthis->u.jsdisp, array_from_vdisp(jsthis)->length, default_separatorW, retv, ei, sp);
default:
FIXME("unimplemented flags %x\n", flags);
return E_NOTIMPL;
@ -808,7 +1080,7 @@ static const builtin_info_t Array_info = {
Array_on_put
};
static HRESULT ArrayConstr_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT ArrayConstr_value(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
{
DispatchEx *obj;
@ -823,9 +1095,9 @@ static HRESULT ArrayConstr_value(DispatchEx *dispex, LCID lcid, WORD flags, DISP
case DISPATCH_CONSTRUCT: {
if(arg_cnt(dp) == 1 && V_VT((arg_var = get_arg(dp, 0))) == VT_I4) {
if(V_I4(arg_var) < 0)
return throw_range_error(dispex->ctx, ei, IDS_INVALID_LENGTH, NULL);
return throw_range_error(ctx, ei, IDS_INVALID_LENGTH, NULL);
hres = create_array(dispex->ctx, V_I4(arg_var), &obj);
hres = create_array(ctx, V_I4(arg_var), &obj);
if(FAILED(hres))
return hres;
@ -834,12 +1106,12 @@ static HRESULT ArrayConstr_value(DispatchEx *dispex, LCID lcid, WORD flags, DISP
return S_OK;
}
hres = create_array(dispex->ctx, arg_cnt(dp), &obj);
hres = create_array(ctx, arg_cnt(dp), &obj);
if(FAILED(hres))
return hres;
for(i=0; i < arg_cnt(dp); i++) {
hres = jsdisp_propput_idx(obj, i, lcid, get_arg(dp, i), ei, caller);
hres = jsdisp_propput_idx(obj, i, get_arg(dp, i), ei, caller);
if(FAILED(hres))
break;
}
@ -872,7 +1144,7 @@ static HRESULT alloc_array(script_ctx_t *ctx, DispatchEx *object_prototype, Arra
if(object_prototype)
hres = init_dispex(&array->dispex, ctx, &Array_info, object_prototype);
else
hres = init_dispex_from_constr(&array->dispex, ctx, &Array_info, ctx->object_constr);
hres = init_dispex_from_constr(&array->dispex, ctx, &Array_info, ctx->array_constr);
if(FAILED(hres)) {
heap_free(array);
@ -888,13 +1160,15 @@ HRESULT create_array_constr(script_ctx_t *ctx, DispatchEx *object_prototype, Dis
ArrayInstance *array;
HRESULT hres;
static const WCHAR ArrayW[] = {'A','r','r','a','y',0};
hres = alloc_array(ctx, object_prototype, &array);
if(FAILED(hres))
return hres;
hres = create_builtin_function(ctx, ArrayConstr_value, NULL, PROPF_CONSTR, &array->dispex, ret);
hres = create_builtin_function(ctx, ArrayConstr_value, ArrayW, NULL, PROPF_CONSTR, &array->dispex, ret);
IDispatchEx_Release(_IDispatchEx_(&array->dispex));
jsdisp_release(&array->dispex);
return hres;
}

View file

@ -32,20 +32,26 @@ typedef struct {
static const WCHAR toStringW[] = {'t','o','S','t','r','i','n','g',0};
static const WCHAR valueOfW[] = {'v','a','l','u','e','O','f',0};
static inline BoolInstance *bool_this(vdisp_t *jsthis)
{
return is_vclass(jsthis, JSCLASS_BOOLEAN) ? (BoolInstance*)jsthis->u.jsdisp : NULL;
}
/* ECMA-262 3rd Edition 15.6.4.2 */
static HRESULT Bool_toString(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT Bool_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
BoolInstance *bool;
static const WCHAR trueW[] = {'t','r','u','e',0};
static const WCHAR falseW[] = {'f','a','l','s','e',0};
TRACE("\n");
if(!is_class(dispex, JSCLASS_BOOLEAN))
return throw_type_error(dispex->ctx, ei, IDS_NOT_BOOL, NULL);
if(!(bool = bool_this(jsthis)))
return throw_type_error(ctx, ei, IDS_NOT_BOOL, NULL);
if(retv) {
BoolInstance *bool = (BoolInstance*)dispex;
BSTR val;
if(bool->val) val = SysAllocString(trueW);
@ -62,17 +68,17 @@ static HRESULT Bool_toString(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARA
}
/* ECMA-262 3rd Edition 15.6.4.3 */
static HRESULT Bool_valueOf(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT Bool_valueOf(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
BoolInstance *bool;
TRACE("\n");
if(!is_class(dispex, JSCLASS_BOOLEAN))
return throw_type_error(dispex->ctx, ei, IDS_NOT_BOOL, NULL);
if(!(bool = bool_this(jsthis)))
return throw_type_error(ctx, ei, IDS_NOT_BOOL, NULL);
if(retv) {
BoolInstance *bool = (BoolInstance*)dispex;
V_VT(retv) = VT_BOOL;
V_BOOL(retv) = bool->val;
}
@ -80,14 +86,14 @@ static HRESULT Bool_valueOf(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAM
return S_OK;
}
static HRESULT Bool_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT Bool_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
TRACE("\n");
switch(flags) {
case INVOKE_FUNC:
return throw_type_error(dispex->ctx, ei, IDS_NOT_FUNC, NULL);
return throw_type_error(ctx, ei, IDS_NOT_FUNC, NULL);
default:
FIXME("unimplemented flags %x\n", flags);
return E_NOTIMPL;
@ -111,7 +117,7 @@ static const builtin_info_t Bool_info = {
NULL
};
static HRESULT BoolConstr_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT BoolConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
HRESULT hres;
@ -127,7 +133,7 @@ static HRESULT BoolConstr_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPP
case DISPATCH_CONSTRUCT: {
DispatchEx *bool;
hres = create_bool(dispex->ctx, value, &bool);
hres = create_bool(ctx, value, &bool);
if(FAILED(hres))
return hres;
@ -179,11 +185,13 @@ HRESULT create_bool_constr(script_ctx_t *ctx, DispatchEx *object_prototype, Disp
BoolInstance *bool;
HRESULT hres;
static const WCHAR BooleanW[] = {'B','o','o','l','e','a','n',0};
hres = alloc_bool(ctx, object_prototype, &bool);
if(FAILED(hres))
return hres;
hres = create_builtin_function(ctx, BoolConstr_value, NULL, PROPF_CONSTR, &bool->dispex, ret);
hres = create_builtin_function(ctx, BoolConstr_value, BooleanW, NULL, PROPF_CONSTR, &bool->dispex, ret);
jsdisp_release(&bool->dispex);
return hres;

File diff suppressed because it is too large Load diff

View file

@ -239,20 +239,27 @@ static HRESULT set_this(DISPPARAMS *dp, DISPPARAMS *olddp, IDispatch *jsthis)
return S_OK;
}
static HRESULT invoke_prop_func(DispatchEx *This, DispatchEx *jsthis, dispex_prop_t *prop, LCID lcid, WORD flags,
static HRESULT invoke_prop_func(DispatchEx *This, DispatchEx *jsthis, dispex_prop_t *prop, WORD flags,
DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
{
HRESULT hres;
switch(prop->type) {
case PROP_BUILTIN:
case PROP_BUILTIN: {
vdisp_t vthis;
if(flags == DISPATCH_CONSTRUCT && (prop->flags & DISPATCH_METHOD)) {
WARN("%s is not a constructor\n", debugstr_w(prop->name));
return E_INVALIDARG;
}
return prop->u.p->invoke(jsthis, lcid, flags, dp, retv, ei, caller);
set_jsdisp(&vthis, jsthis);
hres = prop->u.p->invoke(This->ctx, &vthis, flags, dp, retv, ei, caller);
vdisp_release(&vthis);
return hres;
}
case PROP_PROTREF:
return invoke_prop_func(This->prototype, jsthis, This->prototype->props+prop->u.ref, lcid, flags, dp, retv, ei, caller);
return invoke_prop_func(This->prototype, jsthis, This->prototype->props+prop->u.ref, flags, dp, retv, ei, caller);
case PROP_VARIANT: {
DISPPARAMS new_dp;
@ -267,7 +274,7 @@ static HRESULT invoke_prop_func(DispatchEx *This, DispatchEx *jsthis, dispex_pro
if(FAILED(hres))
return hres;
hres = disp_call(V_DISPATCH(&prop->u.var), DISPID_VALUE, lcid, flags, &new_dp, retv, ei, caller);
hres = disp_call(This->ctx, V_DISPATCH(&prop->u.var), DISPID_VALUE, flags, &new_dp, retv, ei, caller);
if(new_dp.rgvarg != dp->rgvarg) {
heap_free(new_dp.rgvarg);
@ -284,7 +291,7 @@ static HRESULT invoke_prop_func(DispatchEx *This, DispatchEx *jsthis, dispex_pro
return E_FAIL;
}
static HRESULT prop_get(DispatchEx *This, dispex_prop_t *prop, LCID lcid, DISPPARAMS *dp,
static HRESULT prop_get(DispatchEx *This, dispex_prop_t *prop, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
{
HRESULT hres;
@ -293,7 +300,8 @@ static HRESULT prop_get(DispatchEx *This, dispex_prop_t *prop, LCID lcid, DISPPA
case PROP_BUILTIN:
if(prop->u.p->flags & PROPF_METHOD) {
DispatchEx *obj;
hres = create_builtin_function(This->ctx, prop->u.p->invoke, NULL, prop->u.p->flags, NULL, &obj);
hres = create_builtin_function(This->ctx, prop->u.p->invoke, prop->u.p->name, NULL,
prop->u.p->flags, NULL, &obj);
if(FAILED(hres))
break;
@ -303,11 +311,15 @@ static HRESULT prop_get(DispatchEx *This, dispex_prop_t *prop, LCID lcid, DISPPA
hres = VariantCopy(retv, &prop->u.var);
}else {
hres = prop->u.p->invoke(This, lcid, DISPATCH_PROPERTYGET, dp, retv, ei, caller);
vdisp_t vthis;
set_jsdisp(&vthis, This);
hres = prop->u.p->invoke(This->ctx, &vthis, DISPATCH_PROPERTYGET, dp, retv, ei, caller);
vdisp_release(&vthis);
}
break;
case PROP_PROTREF:
hres = prop_get(This->prototype, This->prototype->props+prop->u.ref, lcid, dp, retv, ei, caller);
hres = prop_get(This->prototype, This->prototype->props+prop->u.ref, dp, retv, ei, caller);
break;
case PROP_VARIANT:
hres = VariantCopy(retv, &prop->u.var);
@ -326,7 +338,7 @@ static HRESULT prop_get(DispatchEx *This, dispex_prop_t *prop, LCID lcid, DISPPA
return hres;
}
static HRESULT prop_put(DispatchEx *This, dispex_prop_t *prop, LCID lcid, DISPPARAMS *dp,
static HRESULT prop_put(DispatchEx *This, dispex_prop_t *prop, DISPPARAMS *dp,
jsexcept_t *ei, IServiceProvider *caller)
{
DWORD i;
@ -334,8 +346,14 @@ static HRESULT prop_put(DispatchEx *This, dispex_prop_t *prop, LCID lcid, DISPPA
switch(prop->type) {
case PROP_BUILTIN:
if(!(prop->flags & PROPF_METHOD))
return prop->u.p->invoke(This, lcid, DISPATCH_PROPERTYPUT, dp, NULL, ei, caller);
if(!(prop->flags & PROPF_METHOD)) {
vdisp_t vthis;
set_jsdisp(&vthis, This);
hres = prop->u.p->invoke(This->ctx, &vthis, DISPATCH_PROPERTYPUT, dp, NULL, ei, caller);
vdisp_release(&vthis);
return hres;
}
case PROP_PROTREF:
prop->type = PROP_VARIANT;
prop->flags = PROPF_ENUM;
@ -473,8 +491,8 @@ static HRESULT WINAPI DispatchEx_GetTypeInfoCount(IDispatchEx *iface, UINT *pcti
return S_OK;
}
static HRESULT WINAPI DispatchEx_GetTypeInfo(IDispatchEx *iface, UINT iTInfo,
LCID lcid, ITypeInfo **ppTInfo)
static HRESULT WINAPI DispatchEx_GetTypeInfo(IDispatchEx *iface, UINT iTInfo, LCID lcid,
ITypeInfo **ppTInfo)
{
DispatchEx *This = DISPATCHEX_THIS(iface);
FIXME("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
@ -482,8 +500,8 @@ static HRESULT WINAPI DispatchEx_GetTypeInfo(IDispatchEx *iface, UINT iTInfo,
}
static HRESULT WINAPI DispatchEx_GetIDsOfNames(IDispatchEx *iface, REFIID riid,
LPOLESTR *rgszNames, UINT cNames,
LCID lcid, DISPID *rgDispId)
LPOLESTR *rgszNames, UINT cNames, LCID lcid,
DISPID *rgDispId)
{
DispatchEx *This = DISPATCHEX_THIS(iface);
UINT i;
@ -502,7 +520,7 @@ static HRESULT WINAPI DispatchEx_GetIDsOfNames(IDispatchEx *iface, REFIID riid,
}
static HRESULT WINAPI DispatchEx_Invoke(IDispatchEx *iface, DISPID dispIdMember,
REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
{
DispatchEx *This = DISPATCHEX_THIS(iface);
@ -552,13 +570,13 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
switch(wFlags) {
case DISPATCH_METHOD:
case DISPATCH_CONSTRUCT:
hres = invoke_prop_func(This, This, prop, lcid, wFlags, pdp, pvarRes, &jsexcept, pspCaller);
hres = invoke_prop_func(This, This, prop, wFlags, pdp, pvarRes, &jsexcept, pspCaller);
break;
case DISPATCH_PROPERTYGET:
hres = prop_get(This, prop, lcid, pdp, pvarRes, &jsexcept, pspCaller);
hres = prop_get(This, prop, pdp, pvarRes, &jsexcept, pspCaller);
break;
case DISPATCH_PROPERTYPUT:
hres = prop_put(This, prop, lcid, pdp, &jsexcept, pspCaller);
hres = prop_put(This, prop, pdp, &jsexcept, pspCaller);
break;
default:
FIXME("Unimplemented flags %x\n", wFlags);
@ -774,7 +792,7 @@ HRESULT init_dispex_from_constr(DispatchEx *dispex, script_ctx_t *ctx, const bui
V_VT(&var) = VT_EMPTY;
memset(&jsexcept, 0, sizeof(jsexcept));
hres = prop_get(constr, prop, ctx->lcid, NULL, &var, &jsexcept, NULL/*FIXME*/);
hres = prop_get(constr, prop, NULL, &var, &jsexcept, NULL/*FIXME*/);
if(FAILED(hres)) {
ERR("Could not get prototype\n");
return hres;
@ -788,7 +806,7 @@ HRESULT init_dispex_from_constr(DispatchEx *dispex, script_ctx_t *ctx, const bui
hres = init_dispex(dispex, ctx, builtin_info, prot);
if(prot)
IDispatchEx_Release(_IDispatchEx_(prot));
jsdisp_release(prot);
return hres;
}
@ -822,13 +840,19 @@ HRESULT jsdisp_get_id(DispatchEx *jsdisp, const WCHAR *name, DWORD flags, DISPID
return DISP_E_UNKNOWNNAME;
}
HRESULT jsdisp_call_value(DispatchEx *disp, LCID lcid, WORD flags, DISPPARAMS *dp, VARIANT *retv,
HRESULT jsdisp_call_value(DispatchEx *jsthis, WORD flags, DISPPARAMS *dp, VARIANT *retv,
jsexcept_t *ei, IServiceProvider *caller)
{
return disp->builtin_info->value_prop.invoke(disp, lcid, flags, dp, retv, ei, caller);
vdisp_t vdisp;
HRESULT hres;
set_jsdisp(&vdisp, jsthis);
hres = jsthis->builtin_info->value_prop.invoke(jsthis->ctx, &vdisp, flags, dp, retv, ei, caller);
vdisp_release(&vdisp);
return hres;
}
HRESULT jsdisp_call(DispatchEx *disp, DISPID id, LCID lcid, WORD flags, DISPPARAMS *dp, VARIANT *retv,
HRESULT jsdisp_call(DispatchEx *disp, DISPID id, WORD flags, DISPPARAMS *dp, VARIANT *retv,
jsexcept_t *ei, IServiceProvider *caller)
{
dispex_prop_t *prop;
@ -841,10 +865,10 @@ HRESULT jsdisp_call(DispatchEx *disp, DISPID id, LCID lcid, WORD flags, DISPPARA
if(!prop)
return DISP_E_MEMBERNOTFOUND;
return invoke_prop_func(disp, disp, prop, lcid, flags, dp, retv, ei, caller);
return invoke_prop_func(disp, disp, prop, flags, dp, retv, ei, caller);
}
HRESULT jsdisp_call_name(DispatchEx *disp, const WCHAR *name, LCID lcid, WORD flags, DISPPARAMS *dp, VARIANT *retv,
HRESULT jsdisp_call_name(DispatchEx *disp, const WCHAR *name, WORD flags, DISPPARAMS *dp, VARIANT *retv,
jsexcept_t *ei, IServiceProvider *caller)
{
dispex_prop_t *prop;
@ -858,10 +882,10 @@ HRESULT jsdisp_call_name(DispatchEx *disp, const WCHAR *name, LCID lcid, WORD fl
if(retv)
V_VT(retv) = VT_EMPTY;
return invoke_prop_func(disp, disp, prop, lcid, flags, dp, retv, ei, caller);
return invoke_prop_func(disp, disp, prop, flags, dp, retv, ei, caller);
}
HRESULT disp_call(IDispatch *disp, DISPID id, LCID lcid, WORD flags, DISPPARAMS *dp, VARIANT *retv,
HRESULT disp_call(script_ctx_t *ctx, IDispatch *disp, DISPID id, WORD flags, DISPPARAMS *dp, VARIANT *retv,
jsexcept_t *ei, IServiceProvider *caller)
{
DispatchEx *jsdisp;
@ -870,8 +894,8 @@ HRESULT disp_call(IDispatch *disp, DISPID id, LCID lcid, WORD flags, DISPPARAMS
jsdisp = iface_to_jsdisp((IUnknown*)disp);
if(jsdisp) {
hres = jsdisp_call(jsdisp, id, lcid, flags, dp, retv, ei, caller);
IDispatchEx_Release(_IDispatchEx_(jsdisp));
hres = jsdisp_call(jsdisp, id, flags, dp, retv, ei, caller);
jsdisp_release(jsdisp);
return hres;
}
@ -889,16 +913,16 @@ HRESULT disp_call(IDispatch *disp, DISPID id, LCID lcid, WORD flags, DISPPARAMS
}
TRACE("using IDispatch\n");
return IDispatch_Invoke(disp, id, &IID_NULL, lcid, flags, dp, retv, &ei->ei, &err);
return IDispatch_Invoke(disp, id, &IID_NULL, ctx->lcid, flags, dp, retv, &ei->ei, &err);
}
hres = IDispatchEx_InvokeEx(dispex, id, lcid, flags, dp, retv, &ei->ei, caller);
hres = IDispatchEx_InvokeEx(dispex, id, ctx->lcid, flags, dp, retv, &ei->ei, caller);
IDispatchEx_Release(dispex);
return hres;
}
HRESULT jsdisp_propput_name(DispatchEx *obj, const WCHAR *name, LCID lcid, VARIANT *val, jsexcept_t *ei, IServiceProvider *caller)
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};
@ -909,20 +933,20 @@ HRESULT jsdisp_propput_name(DispatchEx *obj, const WCHAR *name, LCID lcid, VARIA
if(FAILED(hres))
return hres;
return prop_put(obj, prop, lcid, &dp, ei, caller);
return prop_put(obj, prop, &dp, ei, caller);
}
HRESULT jsdisp_propput_idx(DispatchEx *obj, DWORD idx, LCID lcid, VARIANT *val, jsexcept_t *ei, IServiceProvider *caller)
HRESULT jsdisp_propput_idx(DispatchEx *obj, DWORD idx, VARIANT *val, jsexcept_t *ei, IServiceProvider *caller)
{
WCHAR buf[12];
static const WCHAR formatW[] = {'%','d',0};
sprintfW(buf, formatW, idx);
return jsdisp_propput_name(obj, buf, lcid, val, ei, caller);
return jsdisp_propput_name(obj, buf, val, ei, caller);
}
HRESULT disp_propput(IDispatch *disp, DISPID id, LCID lcid, VARIANT *val, jsexcept_t *ei, IServiceProvider *caller)
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};
@ -936,11 +960,11 @@ HRESULT disp_propput(IDispatch *disp, DISPID id, LCID lcid, VARIANT *val, jsexce
prop = get_prop(jsdisp, id);
if(prop)
hres = prop_put(jsdisp, prop, lcid, &dp, ei, caller);
hres = prop_put(jsdisp, prop, &dp, ei, caller);
else
hres = DISP_E_MEMBERNOTFOUND;
IDispatchEx_Release(_IDispatchEx_(jsdisp));
jsdisp_release(jsdisp);
return hres;
}
@ -949,17 +973,16 @@ HRESULT disp_propput(IDispatch *disp, DISPID id, LCID lcid, VARIANT *val, jsexce
ULONG err = 0;
TRACE("using IDispatch\n");
return IDispatch_Invoke(disp, id, &IID_NULL, DISPATCH_PROPERTYPUT, lcid, &dp, NULL, &ei->ei, &err);
return IDispatch_Invoke(disp, id, &IID_NULL, ctx->lcid, DISPATCH_PROPERTYPUT, &dp, NULL, &ei->ei, &err);
}
hres = IDispatchEx_InvokeEx(dispex, id, lcid, DISPATCH_PROPERTYPUT, &dp, NULL, &ei->ei, caller);
hres = IDispatchEx_InvokeEx(dispex, id, ctx->lcid, DISPATCH_PROPERTYPUT, &dp, NULL, &ei->ei, caller);
IDispatchEx_Release(dispex);
return hres;
}
HRESULT jsdisp_propget_name(DispatchEx *obj, const WCHAR *name, LCID lcid, VARIANT *var,
jsexcept_t *ei, IServiceProvider *caller)
HRESULT jsdisp_propget_name(DispatchEx *obj, const WCHAR *name, VARIANT *var, jsexcept_t *ei, IServiceProvider *caller)
{
DISPPARAMS dp = {NULL, NULL, 0, 0};
dispex_prop_t *prop;
@ -973,21 +996,20 @@ HRESULT jsdisp_propget_name(DispatchEx *obj, const WCHAR *name, LCID lcid, VARIA
if(!prop)
return S_OK;
return prop_get(obj, prop, lcid, &dp, var, ei, caller);
return prop_get(obj, prop, &dp, var, ei, caller);
}
HRESULT jsdisp_propget_idx(DispatchEx *obj, DWORD idx, LCID lcid, VARIANT *var, jsexcept_t *ei, IServiceProvider *caller)
HRESULT jsdisp_propget_idx(DispatchEx *obj, DWORD idx, VARIANT *var, jsexcept_t *ei, IServiceProvider *caller)
{
WCHAR buf[12];
static const WCHAR formatW[] = {'%','d',0};
sprintfW(buf, formatW, idx);
return jsdisp_propget_name(obj, buf, lcid, var, ei, caller);
return jsdisp_propget_name(obj, buf, var, ei, caller);
}
HRESULT jsdisp_propget(DispatchEx *jsdisp, DISPID id, LCID lcid, VARIANT *val, jsexcept_t *ei,
IServiceProvider *caller)
HRESULT jsdisp_propget(DispatchEx *jsdisp, DISPID id, VARIANT *val, jsexcept_t *ei, IServiceProvider *caller)
{
DISPPARAMS dp = {NULL,NULL,0,0};
dispex_prop_t *prop;
@ -997,10 +1019,10 @@ HRESULT jsdisp_propget(DispatchEx *jsdisp, DISPID id, LCID lcid, VARIANT *val, j
return DISP_E_MEMBERNOTFOUND;
V_VT(val) = VT_EMPTY;
return prop_get(jsdisp, prop, lcid, &dp, val, ei, caller);
return prop_get(jsdisp, prop, &dp, val, ei, caller);
}
HRESULT disp_propget(IDispatch *disp, DISPID id, LCID lcid, VARIANT *val, jsexcept_t *ei, IServiceProvider *caller)
HRESULT disp_propget(script_ctx_t *ctx, IDispatch *disp, DISPID id, VARIANT *val, jsexcept_t *ei, IServiceProvider *caller)
{
DISPPARAMS dp = {NULL,NULL,0,0};
IDispatchEx *dispex;
@ -1009,8 +1031,8 @@ HRESULT disp_propget(IDispatch *disp, DISPID id, LCID lcid, VARIANT *val, jsexce
jsdisp = iface_to_jsdisp((IUnknown*)disp);
if(jsdisp) {
hres = jsdisp_propget(jsdisp, id, lcid, val, ei, caller);
IDispatchEx_Release(_IDispatchEx_(jsdisp));
hres = jsdisp_propget(jsdisp, id, val, ei, caller);
jsdisp_release(jsdisp);
return hres;
}
@ -1019,10 +1041,10 @@ HRESULT disp_propget(IDispatch *disp, DISPID id, LCID lcid, VARIANT *val, jsexce
ULONG err = 0;
TRACE("using IDispatch\n");
return IDispatch_Invoke(disp, id, &IID_NULL, lcid, INVOKE_PROPERTYGET, &dp, val, &ei->ei, &err);
return IDispatch_Invoke(disp, id, &IID_NULL, ctx->lcid, INVOKE_PROPERTYGET, &dp, val, &ei->ei, &err);
}
hres = IDispatchEx_InvokeEx(dispex, id, lcid, INVOKE_PROPERTYGET, &dp, val, &ei->ei, caller);
hres = IDispatchEx_InvokeEx(dispex, id, ctx->lcid, INVOKE_PROPERTYGET, &dp, val, &ei->ei, caller);
IDispatchEx_Release(dispex);
return hres;

View file

@ -57,6 +57,9 @@ static void exprval_release(exprval_t *val)
if(val->u.nameref.disp)
IDispatch_Release(val->u.nameref.disp);
SysFreeString(val->u.nameref.name);
return;
case EXPRVAL_INVALID:
SysFreeString(val->u.identifier);
}
}
@ -74,11 +77,15 @@ static HRESULT exprval_value(script_ctx_t *ctx, exprval_t *val, jsexcept_t *ei,
return E_FAIL;
}
return disp_propget(val->u.idref.disp, val->u.idref.id, ctx->lcid, ret, ei, NULL/*FIXME*/);
default:
ERR("type %d\n", val->type);
return E_FAIL;
return disp_propget(ctx, val->u.idref.disp, val->u.idref.id, ret, ei, NULL/*FIXME*/);
case EXPRVAL_NAMEREF:
break;
case EXPRVAL_INVALID:
return throw_type_error(ctx, ei, IDS_UNDEFINED, val->u.identifier);
}
ERR("type %d\n", val->type);
return E_FAIL;
}
static HRESULT exprval_to_value(script_ctx_t *ctx, exprval_t *val, jsexcept_t *ei, VARIANT *ret)
@ -167,11 +174,12 @@ void scope_release(scope_chain_t *scope)
if(scope->next)
scope_release(scope->next);
IDispatchEx_Release(_IDispatchEx_(scope->obj));
jsdisp_release(scope->obj);
heap_free(scope);
}
HRESULT create_exec_ctx(IDispatch *this_obj, DispatchEx *var_disp, scope_chain_t *scope, exec_ctx_t **ret)
HRESULT create_exec_ctx(script_ctx_t *script_ctx, IDispatch *this_obj, DispatchEx *var_disp,
scope_chain_t *scope, exec_ctx_t **ret)
{
exec_ctx_t *ctx;
@ -181,8 +189,13 @@ HRESULT create_exec_ctx(IDispatch *this_obj, DispatchEx *var_disp, scope_chain_t
ctx->ref = 1;
IDispatch_AddRef(this_obj);
ctx->this_obj = this_obj;
if(this_obj)
ctx->this_obj = this_obj;
else if(script_ctx->host_global)
ctx->this_obj = script_ctx->host_global;
else
ctx->this_obj = (IDispatch*)_IDispatchEx_(script_ctx->global);
IDispatch_AddRef(ctx->this_obj);
IDispatchEx_AddRef(_IDispatchEx_(var_disp));
ctx->var_disp = var_disp;
@ -204,7 +217,7 @@ void exec_release(exec_ctx_t *ctx)
if(ctx->scope_chain)
scope_release(ctx->scope_chain);
if(ctx->var_disp)
IDispatchEx_Release(_IDispatchEx_(ctx->var_disp));
jsdisp_release(ctx->var_disp);
if(ctx->this_obj)
IDispatch_Release(ctx->this_obj);
heap_free(ctx);
@ -235,7 +248,12 @@ static HRESULT put_value(script_ctx_t *ctx, exprval_t *ref, VARIANT *v, jsexcept
if(ref->type != EXPRVAL_IDREF)
return throw_reference_error(ctx, ei, IDS_ILLEGAL_ASSIGN, NULL);
return disp_propput(ref->u.idref.disp, ref->u.idref.id, ctx->lcid, v, ei, NULL/*FIXME*/);
return disp_propput(ctx, ref->u.idref.disp, ref->u.idref.id, v, ei, NULL/*FIXME*/);
}
static inline BOOL is_null(const VARIANT *v)
{
return V_VT(v) == VT_NULL || (V_VT(v) == VT_DISPATCH && !V_DISPATCH(v));
}
static HRESULT disp_cmp(IDispatch *disp1, IDispatch *disp2, BOOL *ret)
@ -249,6 +267,11 @@ static HRESULT disp_cmp(IDispatch *disp1, IDispatch *disp2, BOOL *ret)
return S_OK;
}
if(!disp1 || !disp2) {
*ret = FALSE;
return S_OK;
}
hres = IDispatch_QueryInterface(disp1, &IID_IUnknown, (void**)&unk1);
if(FAILED(hres))
return hres;
@ -283,12 +306,12 @@ static HRESULT equal2_values(VARIANT *lval, VARIANT *rval, BOOL *ret)
TRACE("\n");
if(V_VT(lval) != V_VT(rval)) {
if(is_num_vt(V_VT(lval)) && is_num_vt(V_VT(rval))) {
if(is_num_vt(V_VT(lval)) && is_num_vt(V_VT(rval)))
*ret = num_val(lval) == num_val(rval);
return S_OK;
}
*ret = FALSE;
else if(is_null(lval))
*ret = is_null(rval);
else
*ret = FALSE;
return S_OK;
}
@ -399,7 +422,7 @@ HRESULT exec_source(exec_ctx_t *ctx, parser_ctx_t *parser, source_elements_t *so
V_VT(&var) = VT_DISPATCH;
V_DISPATCH(&var) = (IDispatch*)_IDispatchEx_(func_obj);
hres = jsdisp_propput_name(ctx->var_disp, func->expr->identifier, script->lcid, &var, ei, NULL);
hres = jsdisp_propput_name(ctx->var_disp, func->expr->identifier, &var, ei, NULL);
jsdisp_release(func_obj);
if(FAILED(hres))
return hres;
@ -520,25 +543,24 @@ static HRESULT identifier_eval(exec_ctx_t *ctx, BSTR identifier, DWORD flags, js
}
}
hres = jsdisp_get_id(ctx->parser->script->script_disp, identifier, 0, &id);
if(SUCCEEDED(hres)) {
exprval_set_idref(ret, (IDispatch*)_IDispatchEx_(ctx->parser->script->script_disp), id);
return S_OK;
}
if(lookup_global_members(ctx->parser->script, identifier, ret))
return S_OK;
if(flags & EXPR_NEWREF) {
hres = jsdisp_get_id(ctx->var_disp, identifier, fdexNameEnsure, &id);
hres = jsdisp_get_id(ctx->parser->script->global, identifier, fdexNameEnsure, &id);
if(FAILED(hres))
return hres;
exprval_set_idref(ret, (IDispatch*)_IDispatchEx_(ctx->var_disp), id);
exprval_set_idref(ret, (IDispatch*)_IDispatchEx_(ctx->parser->script->global), id);
return S_OK;
}
return throw_type_error(ctx->var_disp->ctx, ei, IDS_UNDEFINED, identifier);
ret->type = EXPRVAL_INVALID;
ret->u.identifier = SysAllocString(identifier);
if(!ret->u.identifier)
return E_OUTOFMEMORY;
return S_OK;
}
/* ECMA-262 3rd Edition 12.1 */
@ -594,7 +616,7 @@ static HRESULT variable_list_eval(exec_ctx_t *ctx, variable_declaration_t *var_l
if(FAILED(hres))
break;
hres = jsdisp_propput_name(ctx->var_disp, iter->identifier, ctx->parser->script->lcid, &val, ei, NULL/*FIXME*/);
hres = jsdisp_propput_name(ctx->var_disp, iter->identifier, &val, ei, NULL/*FIXME*/);
VariantClear(&val);
if(FAILED(hres))
break;
@ -997,7 +1019,7 @@ HRESULT with_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *
if(FAILED(hres))
return hres;
hres = to_object(ctx, &val, &disp);
hres = to_object(ctx->parser->script, &val, &disp);
VariantClear(&val);
if(FAILED(hres))
return hres;
@ -1141,8 +1163,7 @@ static HRESULT catch_eval(exec_ctx_t *ctx, catch_block_t *block, return_type_t *
hres = create_dispex(ctx->parser->script, NULL, NULL, &var_disp);
if(SUCCEEDED(hres)) {
hres = jsdisp_propput_name(var_disp, block->identifier, ctx->parser->script->lcid,
&ex, &rt->ei, NULL/*FIXME*/);
hres = jsdisp_propput_name(var_disp, block->identifier, &ex, &rt->ei, NULL/*FIXME*/);
if(SUCCEEDED(hres)) {
hres = scope_push(ctx->scope_chain, var_disp, &ctx->scope_chain);
if(SUCCEEDED(hres)) {
@ -1304,7 +1325,7 @@ HRESULT function_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD fla
TRACE("\n");
if(expr->identifier) {
hres = jsdisp_propget_name(ctx->var_disp, expr->identifier, ctx->parser->script->lcid, &var, ei, NULL/*FIXME*/);
hres = jsdisp_propget_name(ctx->var_disp, expr->identifier, &var, ei, NULL/*FIXME*/);
if(FAILED(hres))
return hres;
}else {
@ -1375,7 +1396,7 @@ HRESULT array_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags,
}
if(SUCCEEDED(hres))
hres = to_object(ctx, &member, &obj);
hres = to_object(ctx->parser->script, &member, &obj);
VariantClear(&member);
if(SUCCEEDED(hres)) {
hres = to_string(ctx->parser->script, &val, ei, &str);
@ -1425,7 +1446,7 @@ HRESULT member_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags
if(FAILED(hres))
return hres;
hres = to_object(ctx, &member, &obj);
hres = to_object(ctx->parser->script, &member, &obj);
VariantClear(&member);
if(FAILED(hres))
return hres;
@ -1528,7 +1549,7 @@ HRESULT new_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, j
return E_FAIL;
}
hres = disp_call(V_DISPATCH(&constr), DISPID_VALUE, ctx->parser->script->lcid,
hres = disp_call(ctx->parser->script, V_DISPATCH(&constr), DISPID_VALUE,
DISPATCH_CONSTRUCT, &dp, &var, ei, NULL/*FIXME*/);
IDispatch_Release(V_DISPATCH(&constr));
if(FAILED(hres))
@ -1558,16 +1579,19 @@ HRESULT call_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags,
if(SUCCEEDED(hres)) {
switch(exprval.type) {
case EXPRVAL_VARIANT:
if(V_VT(&exprval.u.var) != VT_DISPATCH)
return throw_type_error(ctx->var_disp->ctx, ei, IDS_NO_PROPERTY, NULL);
hres = disp_call(V_DISPATCH(&exprval.u.var), DISPID_VALUE, ctx->parser->script->lcid,
DISPATCH_METHOD, &dp, flags & EXPR_NOVAL ? NULL : &var, ei, NULL/*FIXME*/);
if(V_VT(&exprval.u.var) == VT_DISPATCH)
hres = disp_call(ctx->parser->script, V_DISPATCH(&exprval.u.var), DISPID_VALUE,
DISPATCH_METHOD, &dp, flags & EXPR_NOVAL ? NULL : &var, ei, NULL/*FIXME*/);
else
hres = throw_type_error(ctx->parser->script, ei, IDS_NO_PROPERTY, NULL);
break;
case EXPRVAL_IDREF:
hres = disp_call(exprval.u.idref.disp, exprval.u.idref.id, ctx->parser->script->lcid,
hres = disp_call(ctx->parser->script, exprval.u.idref.disp, exprval.u.idref.id,
DISPATCH_METHOD, &dp, flags & EXPR_NOVAL ? NULL : &var, ei, NULL/*FIXME*/);
break;
case EXPRVAL_INVALID:
hres = throw_type_error(ctx->parser->script, ei, IDS_OBJECT_EXPECTED, NULL);
break;
default:
FIXME("unimplemented type %d\n", exprval.type);
hres = E_NOTIMPL;
@ -1672,7 +1696,7 @@ HRESULT array_literal_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWOR
if(FAILED(hres))
break;
hres = jsdisp_propput_idx(array, i, ctx->parser->script->lcid, &val, ei, NULL/*FIXME*/);
hres = jsdisp_propput_idx(array, i, &val, ei, NULL/*FIXME*/);
VariantClear(&val);
if(FAILED(hres))
break;
@ -1723,7 +1747,7 @@ HRESULT property_value_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWO
hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
exprval_release(&exprval);
if(SUCCEEDED(hres)) {
hres = jsdisp_propput_name(obj, name, ctx->parser->script->lcid, &val, ei, NULL/*FIXME*/);
hres = jsdisp_propput_name(obj, name, &val, ei, NULL/*FIXME*/);
VariantClear(&val);
}
}
@ -1942,17 +1966,115 @@ HRESULT binary_and_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD f
}
/* ECMA-262 3rd Edition 11.8.6 */
HRESULT instanceof_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
static HRESULT instanceof_eval(exec_ctx_t *ctx, VARIANT *inst, VARIANT *objv, jsexcept_t *ei, VARIANT *retv)
{
FIXME("\n");
return E_NOTIMPL;
DispatchEx *obj, *iter, *tmp = NULL;
VARIANT_BOOL ret = VARIANT_FALSE;
BOOL b;
VARIANT var;
HRESULT hres;
static const WCHAR prototypeW[] = {'p','r','o','t','o','t', 'y', 'p','e',0};
if(V_VT(objv) != VT_DISPATCH) {
FIXME("throw TypeError\n");
return E_FAIL;
}
obj = iface_to_jsdisp((IUnknown*)V_DISPATCH(objv));
if(!obj) {
FIXME("throw TypeError\n");
return E_FAIL;
}
if(is_class(obj, JSCLASS_FUNCTION)) {
hres = jsdisp_propget_name(obj, prototypeW, &var, ei, NULL/*FIXME*/);
}else {
FIXME("throw TypeError\n");
hres = E_FAIL;
}
jsdisp_release(obj);
if(FAILED(hres))
return hres;
if(V_VT(&var) == VT_DISPATCH) {
if(V_VT(inst) == VT_DISPATCH)
tmp = iface_to_jsdisp((IUnknown*)V_DISPATCH(inst));
for(iter = tmp; iter; iter = iter->prototype) {
hres = disp_cmp(V_DISPATCH(&var), (IDispatch*)_IDispatchEx_(iter), &b);
if(FAILED(hres))
break;
if(b) {
ret = VARIANT_TRUE;
break;
}
}
if(tmp)
jsdisp_release(tmp);
}else {
FIXME("prototype is not an object\n");
hres = E_FAIL;
}
VariantClear(&var);
if(FAILED(hres))
return hres;
V_VT(retv) = VT_BOOL;
V_BOOL(retv) = ret;
return S_OK;
}
/* ECMA-262 3rd Edition 11.8.6 */
HRESULT instanceof_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
{
binary_expression_t *expr = (binary_expression_t*)_expr;
TRACE("\n");
return binary_expr_eval(ctx, expr, instanceof_eval, ei, ret);
}
/* ECMA-262 3rd Edition 11.8.7 */
HRESULT in_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
static HRESULT in_eval(exec_ctx_t *ctx, VARIANT *lval, VARIANT *obj, jsexcept_t *ei, VARIANT *retv)
{
FIXME("\n");
return E_NOTIMPL;
VARIANT_BOOL ret;
DISPID id;
BSTR str;
HRESULT hres;
if(V_VT(obj) != VT_DISPATCH) {
FIXME("throw TypeError\n");
return E_FAIL;
}
hres = to_string(ctx->parser->script, lval, ei, &str);
if(FAILED(hres))
return hres;
hres = disp_get_id(V_DISPATCH(obj), str, 0, &id);
SysFreeString(str);
if(SUCCEEDED(hres))
ret = VARIANT_TRUE;
else if(hres == DISP_E_UNKNOWNNAME)
ret = VARIANT_FALSE;
else
return hres;
V_VT(retv) = VT_BOOL;
V_BOOL(retv) = ret;
return S_OK;
}
/* ECMA-262 3rd Edition 11.8.7 */
HRESULT in_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
{
binary_expression_t *expr = (binary_expression_t*)_expr;
TRACE("\n");
return binary_expr_eval(ctx, expr, in_eval, ei, ret);
}
/* ECMA-262 3rd Edition 11.6.1 */
@ -2216,11 +2338,8 @@ HRESULT void_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags,
}
/* ECMA-262 3rd Edition 11.4.3 */
HRESULT typeof_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
static HRESULT typeof_exprval(exec_ctx_t *ctx, exprval_t *exprval, jsexcept_t *ei, const WCHAR **ret)
{
unary_expression_t *expr = (unary_expression_t*)_expr;
const WCHAR *str;
exprval_t exprval;
VARIANT val;
HRESULT hres;
@ -2231,57 +2350,76 @@ HRESULT typeof_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags
static const WCHAR stringW[] = {'s','t','r','i','n','g',0};
static const WCHAR undefinedW[] = {'u','n','d','e','f','i','n','e','d',0};
if(exprval->type == EXPRVAL_INVALID) {
*ret = undefinedW;
return S_OK;
}
hres = exprval_to_value(ctx->parser->script, exprval, ei, &val);
if(FAILED(hres))
return hres;
switch(V_VT(&val)) {
case VT_EMPTY:
*ret = undefinedW;
break;
case VT_NULL:
*ret = objectW;
break;
case VT_BOOL:
*ret = booleanW;
break;
case VT_I4:
case VT_R8:
*ret = numberW;
break;
case VT_BSTR:
*ret = stringW;
break;
case VT_DISPATCH: {
DispatchEx *dispex;
if(V_DISPATCH(&val) && (dispex = iface_to_jsdisp((IUnknown*)V_DISPATCH(&val)))) {
*ret = is_class(dispex, JSCLASS_FUNCTION) ? functionW : objectW;
jsdisp_release(dispex);
}else {
*ret = objectW;
}
break;
}
default:
FIXME("unhandled vt %d\n", V_VT(&val));
hres = E_NOTIMPL;
}
VariantClear(&val);
return S_OK;
}
HRESULT typeof_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
{
unary_expression_t *expr = (unary_expression_t*)_expr;
const WCHAR *str = NULL;
exprval_t exprval;
HRESULT hres;
TRACE("\n");
hres = expr_eval(ctx, expr->expression, 0, ei, &exprval);
if(FAILED(hres))
return hres;
hres = exprval_to_value(ctx->parser->script, &exprval, ei, &val);
hres = typeof_exprval(ctx, &exprval, ei, &str);
exprval_release(&exprval);
if(FAILED(hres))
return hres;
switch(V_VT(&val)) {
case VT_EMPTY:
str = undefinedW;
break;
case VT_NULL:
str = objectW;
break;
case VT_BOOL:
str = booleanW;
break;
case VT_I4:
case VT_R8:
str = numberW;
break;
case VT_BSTR:
str = stringW;
break;
case VT_DISPATCH: {
DispatchEx *dispex;
dispex = iface_to_jsdisp((IUnknown*)V_DISPATCH(&val));
if(dispex) {
str = dispex->builtin_info->class == JSCLASS_FUNCTION ? functionW : objectW;
IDispatchEx_Release(_IDispatchEx_(dispex));
}else {
str = objectW;
}
break;
}
default:
FIXME("unhandled vt %d\n", V_VT(&val));
VariantClear(&val);
return E_NOTIMPL;
}
VariantClear(&val);
ret->type = EXPRVAL_VARIANT;
V_VT(&ret->u.var) = VT_BSTR;
V_BSTR(&ret->u.var) = SysAllocString(str);
if(!V_BSTR(&ret->u.var))
return E_OUTOFMEMORY;
return S_OK;
}

View file

@ -116,7 +116,7 @@ static inline void exec_addref(exec_ctx_t *ctx)
}
void exec_release(exec_ctx_t*);
HRESULT create_exec_ctx(IDispatch*,DispatchEx*,scope_chain_t*,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*);
typedef struct _statement_t statement_t;
@ -272,7 +272,8 @@ typedef struct {
enum {
EXPRVAL_VARIANT,
EXPRVAL_IDREF,
EXPRVAL_NAMEREF
EXPRVAL_NAMEREF,
EXPRVAL_INVALID
} type;
union {
VARIANT var;
@ -284,6 +285,7 @@ typedef struct {
IDispatch *disp;
BSTR name;
} nameref;
BSTR identifier;
} u;
} exprval_t;

View file

@ -39,10 +39,15 @@ static const WCHAR messageW[] = {'m','e','s','s','a','g','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};
static HRESULT Error_number(DispatchEx *dispex, LCID lcid, WORD flags,
static inline ErrorInstance *error_from_vdisp(vdisp_t *vdisp)
{
return (ErrorInstance*)vdisp->u.jsdisp;
}
static HRESULT Error_number(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
ErrorInstance *This = (ErrorInstance*)dispex;
ErrorInstance *This = error_from_vdisp(jsthis);
TRACE("\n");
@ -57,10 +62,10 @@ static HRESULT Error_number(DispatchEx *dispex, LCID lcid, WORD flags,
}
}
static HRESULT Error_description(DispatchEx *dispex, LCID lcid, WORD flags,
static HRESULT Error_description(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
ErrorInstance *This = (ErrorInstance*)dispex;
ErrorInstance *This = error_from_vdisp(jsthis);
TRACE("\n");
@ -76,10 +81,10 @@ static HRESULT Error_description(DispatchEx *dispex, LCID lcid, WORD flags,
}
/* ECMA-262 3rd Edition 15.11.4.3 */
static HRESULT Error_message(DispatchEx *dispex, LCID lcid, WORD flags,
static HRESULT Error_message(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
ErrorInstance *This = (ErrorInstance*)dispex;
ErrorInstance *This = error_from_vdisp(jsthis);
TRACE("\n");
@ -95,7 +100,7 @@ static HRESULT Error_message(DispatchEx *dispex, LCID lcid, WORD flags,
}
/* ECMA-262 3rd Edition 15.11.4.4 */
static HRESULT Error_toString(DispatchEx *dispex, LCID lcid, WORD flags,
static HRESULT Error_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
static const WCHAR str[] = {'[','o','b','j','e','c','t',' ','E','r','r','o','r',']',0};
@ -112,14 +117,14 @@ static HRESULT Error_toString(DispatchEx *dispex, LCID lcid, WORD flags,
return S_OK;
}
static HRESULT Error_value(DispatchEx *dispex, LCID lcid, WORD flags,
static HRESULT Error_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
TRACE("\n");
switch(flags) {
case INVOKE_FUNC:
return throw_type_error(dispex->ctx, ei, IDS_NOT_FUNC, NULL);
return throw_type_error(ctx, ei, IDS_NOT_FUNC, NULL);
default:
FIXME("unimplemented flags %x\n", flags);
return E_NOTIMPL;
@ -223,7 +228,7 @@ static HRESULT create_error(script_ctx_t *ctx, DispatchEx *constr,
return S_OK;
}
static HRESULT error_constr(DispatchEx *dispex, WORD flags, DISPPARAMS *dp,
static HRESULT error_constr(script_ctx_t *ctx, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, DispatchEx *constr) {
DispatchEx *err;
VARIANT numv;
@ -234,9 +239,9 @@ static HRESULT error_constr(DispatchEx *dispex, WORD flags, DISPPARAMS *dp,
V_VT(&numv) = VT_NULL;
if(arg_cnt(dp)) {
hres = to_number(dispex->ctx, get_arg(dp, 0), ei, &numv);
hres = to_number(ctx, get_arg(dp, 0), ei, &numv);
if(FAILED(hres) || (V_VT(&numv)==VT_R8 && isnan(V_R8(&numv))))
hres = to_string(dispex->ctx, get_arg(dp, 0), ei, &msg);
hres = to_string(ctx, get_arg(dp, 0), ei, &msg);
else if(V_VT(&numv) == VT_I4)
num = V_I4(&numv);
else
@ -247,7 +252,7 @@ static HRESULT error_constr(DispatchEx *dispex, WORD flags, DISPPARAMS *dp,
}
if(arg_cnt(dp)>1 && !msg) {
hres = to_string(dispex->ctx, get_arg(dp, 1), ei, &msg);
hres = to_string(ctx, get_arg(dp, 1), ei, &msg);
if(FAILED(hres))
return hres;
}
@ -256,9 +261,9 @@ static HRESULT error_constr(DispatchEx *dispex, WORD flags, DISPPARAMS *dp,
case INVOKE_FUNC:
case DISPATCH_CONSTRUCT:
if(V_VT(&numv) == VT_NULL)
hres = create_error(dispex->ctx, constr, NULL, msg, &err);
hres = create_error(ctx, constr, NULL, msg, &err);
else
hres = create_error(dispex->ctx, constr, &num, msg, &err);
hres = create_error(ctx, constr, &num, msg, &err);
if(FAILED(hres))
return hres;
@ -268,7 +273,7 @@ static HRESULT error_constr(DispatchEx *dispex, WORD flags, DISPPARAMS *dp,
V_DISPATCH(retv) = (IDispatch*)_IDispatchEx_(err);
}
else
IDispatchEx_Release(_IDispatchEx_(err));
jsdisp_release(err);
return S_OK;
@ -278,60 +283,60 @@ static HRESULT error_constr(DispatchEx *dispex, WORD flags, DISPPARAMS *dp,
}
}
static HRESULT ErrorConstr_value(DispatchEx *dispex, LCID lcid, WORD flags,
static HRESULT ErrorConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
TRACE("\n");
return error_constr(dispex, flags, dp, retv, ei,
dispex->ctx->error_constr);
return error_constr(ctx, flags, dp, retv, ei, ctx->error_constr);
}
static HRESULT EvalErrorConstr_value(DispatchEx *dispex, LCID lcid, WORD flags,
static HRESULT EvalErrorConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
TRACE("\n");
return error_constr(dispex, flags, dp, retv, ei,
dispex->ctx->eval_error_constr);
return error_constr(ctx, flags, dp, retv, ei, ctx->eval_error_constr);
}
static HRESULT RangeErrorConstr_value(DispatchEx *dispex, LCID lcid, WORD flags,
static HRESULT RangeErrorConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
TRACE("\n");
return error_constr(dispex, flags, dp, retv, ei,
dispex->ctx->range_error_constr);
return error_constr(ctx, flags, dp, retv, ei, ctx->range_error_constr);
}
static HRESULT ReferenceErrorConstr_value(DispatchEx *dispex, LCID lcid, WORD flags,
static HRESULT ReferenceErrorConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
TRACE("\n");
return error_constr(dispex, flags, dp, retv, ei,
dispex->ctx->reference_error_constr);
return error_constr(ctx, flags, dp, retv, ei, ctx->reference_error_constr);
}
static HRESULT SyntaxErrorConstr_value(DispatchEx *dispex, LCID lcid, WORD flags,
static HRESULT RegExpErrorConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
TRACE("\n");
return error_constr(dispex, flags, dp, retv, ei,
dispex->ctx->syntax_error_constr);
return error_constr(ctx, flags, dp, retv, ei, ctx->regexp_error_constr);
}
static HRESULT TypeErrorConstr_value(DispatchEx *dispex, LCID lcid, WORD flags,
static HRESULT SyntaxErrorConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
TRACE("\n");
return error_constr(dispex, flags, dp, retv, ei,
dispex->ctx->type_error_constr);
return error_constr(ctx, flags, dp, retv, ei, ctx->syntax_error_constr);
}
static HRESULT URIErrorConstr_value(DispatchEx *dispex, LCID lcid, WORD flags,
static HRESULT TypeErrorConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
TRACE("\n");
return error_constr(dispex, flags, dp, retv, ei,
dispex->ctx->uri_error_constr);
return error_constr(ctx, flags, dp, retv, ei, ctx->type_error_constr);
}
static HRESULT URIErrorConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
TRACE("\n");
return error_constr(ctx, flags, dp, retv, ei, ctx->uri_error_constr);
}
HRESULT init_error_constr(script_ctx_t *ctx, DispatchEx *object_prototype)
@ -341,25 +346,26 @@ HRESULT init_error_constr(script_ctx_t *ctx, DispatchEx *object_prototype)
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};
static const WCHAR ReferenceErrorW[] = {'R','e','f','e','r','e','n','c','e','E','r','r','o','r',0};
static const WCHAR RegExpErrorW[] = {'R','e','g','E','x','p','E','r','r','o','r',0};
static const WCHAR SyntaxErrorW[] = {'S','y','n','t','a','x','E','r','r','o','r',0};
static const WCHAR TypeErrorW[] = {'T','y','p','e','E','r','r','o','r',0};
static const WCHAR URIErrorW[] = {'U','R','I','E','r','r','o','r',0};
static const WCHAR *names[] = {ErrorW, EvalErrorW, RangeErrorW,
ReferenceErrorW, SyntaxErrorW, TypeErrorW, URIErrorW};
ReferenceErrorW, RegExpErrorW, SyntaxErrorW, TypeErrorW, URIErrorW};
DispatchEx **constr_addr[] = {&ctx->error_constr, &ctx->eval_error_constr,
&ctx->range_error_constr, &ctx->reference_error_constr,
&ctx->range_error_constr, &ctx->reference_error_constr, &ctx->regexp_error_constr,
&ctx->syntax_error_constr, &ctx->type_error_constr,
&ctx->uri_error_constr};
static builtin_invoke_t constr_val[] = {ErrorConstr_value, EvalErrorConstr_value,
RangeErrorConstr_value, ReferenceErrorConstr_value, SyntaxErrorConstr_value,
TypeErrorConstr_value, URIErrorConstr_value};
RangeErrorConstr_value, ReferenceErrorConstr_value, RegExpErrorConstr_value,
SyntaxErrorConstr_value, TypeErrorConstr_value, URIErrorConstr_value};
ErrorInstance *err;
INT i;
VARIANT v;
HRESULT hres;
for(i=0; i<7; i++) {
for(i=0; i < sizeof(names)/sizeof(names[0]); i++) {
hres = alloc_error(ctx, i==0 ? object_prototype : NULL, NULL, &err);
if(FAILED(hres))
return hres;
@ -367,17 +373,17 @@ HRESULT init_error_constr(script_ctx_t *ctx, DispatchEx *object_prototype)
V_VT(&v) = VT_BSTR;
V_BSTR(&v) = SysAllocString(names[i]);
if(!V_BSTR(&v)) {
IDispatchEx_Release(_IDispatchEx_(&err->dispex));
jsdisp_release(&err->dispex);
return E_OUTOFMEMORY;
}
hres = jsdisp_propput_name(&err->dispex, nameW, ctx->lcid, &v, NULL/*FIXME*/, NULL/*FIXME*/);
hres = jsdisp_propput_name(&err->dispex, nameW, &v, NULL/*FIXME*/, NULL/*FIXME*/);
if(SUCCEEDED(hres))
hres = create_builtin_function(ctx, constr_val[i], NULL,
hres = create_builtin_function(ctx, constr_val[i], names[i], NULL,
PROPF_CONSTR, &err->dispex, constr_addr[i]);
IDispatchEx_Release(_IDispatchEx_(&err->dispex));
jsdisp_release(&err->dispex);
VariantClear(&v);
if(FAILED(hres))
return hres;
@ -423,6 +429,11 @@ HRESULT throw_eval_error(script_ctx_t *ctx, jsexcept_t *ei, UINT id, const WCHAR
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);
}
HRESULT throw_range_error(script_ctx_t *ctx, jsexcept_t *ei, UINT id, const WCHAR *str)
{
return throw_error(ctx, ei, id, str, ctx->range_error_constr);
@ -433,6 +444,11 @@ HRESULT throw_reference_error(script_ctx_t *ctx, jsexcept_t *ei, UINT id, const
return throw_error(ctx, ei, id, str, ctx->reference_error_constr);
}
HRESULT throw_regexp_error(script_ctx_t *ctx, jsexcept_t *ei, UINT id, const WCHAR *str)
{
return throw_error(ctx, ei, id, str, ctx->regexp_error_constr);
}
HRESULT throw_syntax_error(script_ctx_t *ctx, jsexcept_t *ei, UINT id, const WCHAR *str)
{
return throw_error(ctx, ei, id, str, ctx->syntax_error_constr);

View file

@ -26,6 +26,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(jscript);
typedef struct {
DispatchEx dispex;
builtin_invoke_t value_proc;
const WCHAR *name;
DWORD flags;
source_elements_t *source;
parameter_t *parameters;
@ -36,6 +37,16 @@ typedef struct {
DWORD length;
} FunctionInstance;
static inline FunctionInstance *function_from_vdisp(vdisp_t *vdisp)
{
return (FunctionInstance*)vdisp->u.jsdisp;
}
static inline FunctionInstance *function_this(vdisp_t *jsthis)
{
return is_vclass(jsthis, JSCLASS_FUNCTION) ? function_from_vdisp(jsthis) : NULL;
}
static const WCHAR prototypeW[] = {'p','r','o','t','o','t', 'y', 'p','e',0};
static const WCHAR lengthW[] = {'l','e','n','g','t','h',0};
@ -61,7 +72,7 @@ static IDispatch *get_this(DISPPARAMS *dp)
return NULL;
}
static HRESULT init_parameters(DispatchEx *var_disp, FunctionInstance *function, LCID lcid, DISPPARAMS *dp,
static HRESULT init_parameters(DispatchEx *var_disp, FunctionInstance *function, DISPPARAMS *dp,
jsexcept_t *ei, IServiceProvider *caller)
{
parameter_t *param;
@ -70,12 +81,11 @@ static HRESULT init_parameters(DispatchEx *var_disp, FunctionInstance *function,
HRESULT hres;
V_VT(&var_empty) = VT_EMPTY;
cargs = dp->cArgs - dp->cNamedArgs;
cargs = arg_cnt(dp);
for(param = function->parameters; param; param = param->next) {
hres = jsdisp_propput_name(var_disp, param->identifier, lcid,
i < cargs ? dp->rgvarg + dp->cArgs-1 - i : &var_empty,
ei, caller);
hres = jsdisp_propput_name(var_disp, param->identifier,
i < cargs ? get_arg(dp,i) : &var_empty, ei, caller);
if(FAILED(hres))
return hres;
@ -85,25 +95,69 @@ static HRESULT init_parameters(DispatchEx *var_disp, FunctionInstance *function,
return S_OK;
}
static HRESULT init_arguments(DispatchEx *arg_disp, FunctionInstance *function, LCID lcid, DISPPARAMS *dp,
jsexcept_t *ei, IServiceProvider *caller)
static HRESULT Arguments_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
{
FIXME("\n");
return E_NOTIMPL;
}
static const builtin_info_t Arguments_info = {
JSCLASS_ARGUMENTS,
{NULL, Arguments_value, 0},
0, NULL,
NULL,
NULL
};
static HRESULT create_arguments(script_ctx_t *ctx, IDispatch *calee, DISPPARAMS *dp,
jsexcept_t *ei, IServiceProvider *caller, DispatchEx **ret)
{
DispatchEx *args;
VARIANT var;
DWORD i;
HRESULT hres;
for(i=0; i < dp->cArgs-dp->cNamedArgs; i++) {
hres = jsdisp_propput_idx(arg_disp, i, lcid, dp->rgvarg+dp->cArgs-1-i, ei, caller);
if(FAILED(hres))
return hres;
static const WCHAR caleeW[] = {'c','a','l','l','e','e',0};
args = heap_alloc_zero(sizeof(DispatchEx));
if(!args)
return E_OUTOFMEMORY;
hres = init_dispex_from_constr(args, ctx, &Arguments_info, ctx->object_constr);
if(FAILED(hres)) {
heap_free(args);
return hres;
}
V_VT(&var) = VT_I4;
V_I4(&var) = dp->cArgs - dp->cNamedArgs;
return jsdisp_propput_name(arg_disp, lengthW, lcid, &var, ei, caller);
for(i=0; i < arg_cnt(dp); i++) {
hres = jsdisp_propput_idx(args, i, get_arg(dp,i), ei, caller);
if(FAILED(hres))
break;
}
if(SUCCEEDED(hres)) {
V_VT(&var) = VT_I4;
V_I4(&var) = arg_cnt(dp);
hres = jsdisp_propput_name(args, lengthW, &var, ei, caller);
if(SUCCEEDED(hres)) {
V_VT(&var) = VT_DISPATCH;
V_DISPATCH(&var) = calee;
hres = jsdisp_propput_name(args, caleeW, &var, ei, caller);
}
}
if(FAILED(hres)) {
jsdisp_release(args);
return hres;
}
*ret = args;
return S_OK;
}
static HRESULT create_var_disp(FunctionInstance *function, LCID lcid, DISPPARAMS *dp, jsexcept_t *ei,
static HRESULT create_var_disp(script_ctx_t *ctx, FunctionInstance *function, DISPPARAMS *dp, jsexcept_t *ei,
IServiceProvider *caller, DispatchEx **ret)
{
DispatchEx *var_disp, *arg_disp;
@ -111,26 +165,23 @@ static HRESULT create_var_disp(FunctionInstance *function, LCID lcid, DISPPARAMS
static const WCHAR argumentsW[] = {'a','r','g','u','m','e','n','t','s',0};
hres = create_dispex(function->dispex.ctx, NULL, NULL, &var_disp);
hres = create_dispex(ctx, NULL, NULL, &var_disp);
if(FAILED(hres))
return hres;
hres = create_dispex(function->dispex.ctx, NULL, NULL, &arg_disp);
hres = create_arguments(ctx, (IDispatch*)_IDispatchEx_(&function->dispex),
dp, ei, caller, &arg_disp);
if(SUCCEEDED(hres)) {
hres = init_arguments(arg_disp, function, lcid, dp, ei, caller);
if(SUCCEEDED(hres)) {
VARIANT var;
V_VT(&var) = VT_DISPATCH;
V_DISPATCH(&var) = (IDispatch*)_IDispatchEx_(arg_disp);
hres = jsdisp_propput_name(var_disp, argumentsW, lcid, &var, ei, caller);
}
VARIANT var;
V_VT(&var) = VT_DISPATCH;
V_DISPATCH(&var) = (IDispatch*)_IDispatchEx_(arg_disp);
hres = jsdisp_propput_name(var_disp, argumentsW, &var, ei, caller);
jsdisp_release(arg_disp);
}
if(SUCCEEDED(hres))
hres = init_parameters(var_disp, function, lcid, dp, ei, caller);
hres = init_parameters(var_disp, function, dp, ei, caller);
if(FAILED(hres)) {
jsdisp_release(var_disp);
return hres;
@ -140,7 +191,7 @@ static HRESULT create_var_disp(FunctionInstance *function, LCID lcid, DISPPARAMS
return S_OK;
}
static HRESULT invoke_source(FunctionInstance *function, IDispatch *this_obj, LCID lcid, DISPPARAMS *dp,
static HRESULT invoke_source(script_ctx_t *ctx, FunctionInstance *function, IDispatch *this_obj, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
{
DispatchEx *var_disp;
@ -153,13 +204,13 @@ static HRESULT invoke_source(FunctionInstance *function, IDispatch *this_obj, LC
return E_FAIL;
}
hres = create_var_disp(function, lcid, dp, ei, caller, &var_disp);
hres = create_var_disp(ctx, function, dp, ei, caller, &var_disp);
if(FAILED(hres))
return hres;
hres = scope_push(function->scope_chain, var_disp, &scope);
if(SUCCEEDED(hres)) {
hres = create_exec_ctx(this_obj, var_disp, scope, &exec_ctx);
hres = create_exec_ctx(ctx, this_obj, var_disp, scope, &exec_ctx);
scope_release(scope);
}
if(FAILED(hres))
@ -171,28 +222,17 @@ static HRESULT invoke_source(FunctionInstance *function, IDispatch *this_obj, LC
return hres;
}
static HRESULT invoke_function(FunctionInstance *function, LCID lcid, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
{
IDispatch *this_obj;
if(!(this_obj = get_this(dp)))
this_obj = (IDispatch*)_IDispatchEx_(function->dispex.ctx->script_disp);
return invoke_source(function, this_obj, lcid, dp, retv, ei, caller);
}
static HRESULT invoke_constructor(FunctionInstance *function, LCID lcid, DISPPARAMS *dp,
static HRESULT invoke_constructor(script_ctx_t *ctx, FunctionInstance *function, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
{
DispatchEx *this_obj;
HRESULT hres;
hres = create_object(function->dispex.ctx, &function->dispex, &this_obj);
hres = create_object(ctx, &function->dispex, &this_obj);
if(FAILED(hres))
return hres;
hres = invoke_source(function, (IDispatch*)_IDispatchEx_(this_obj), lcid, dp, retv, ei, caller);
hres = invoke_source(ctx, function, (IDispatch*)_IDispatchEx_(this_obj), dp, retv, ei, caller);
if(FAILED(hres)) {
jsdisp_release(this_obj);
return hres;
@ -203,46 +243,67 @@ static HRESULT invoke_constructor(FunctionInstance *function, LCID lcid, DISPPAR
return S_OK;
}
static HRESULT invoke_value_proc(FunctionInstance *function, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT invoke_value_proc(script_ctx_t *ctx, FunctionInstance *function, IDispatch *this_disp, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
{
DispatchEx *this_obj = NULL;
IDispatch *this_disp;
vdisp_t vthis;
HRESULT hres;
this_disp = get_this(dp);
if(this_disp)
this_obj = iface_to_jsdisp((IUnknown*)this_disp);
set_disp(&vthis, this_disp);
else if(ctx->host_global)
set_disp(&vthis, ctx->host_global);
else
set_jsdisp(&vthis, ctx->global);
hres = function->value_proc(this_obj ? this_obj : function->dispex.ctx->script_disp, lcid,
flags, dp, retv, ei, caller);
hres = function->value_proc(ctx, &vthis, flags, dp, retv, ei, caller);
if(this_obj)
jsdisp_release(this_obj);
vdisp_release(&vthis);
return hres;
}
static HRESULT call_function(script_ctx_t *ctx, FunctionInstance *function, IDispatch *this_obj, DISPPARAMS *args,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
{
if(function->value_proc)
return invoke_value_proc(ctx, function, this_obj, DISPATCH_METHOD, args, retv, ei, caller);
return invoke_source(ctx, function, this_obj, args, retv, ei, caller);
}
static HRESULT function_to_string(FunctionInstance *function, BSTR *ret)
{
BSTR str;
if(function->value_proc) {
FIXME("Builtin functions not implemented\n");
return E_NOTIMPL;
}
static const WCHAR native_prefixW[] = {'\n','f','u','n','c','t','i','o','n',' '};
static const WCHAR native_suffixW[] =
{'(',')',' ','{','\n',' ',' ',' ',' ','[','n','a','t','i','v','e',' ','c','o','d','e',']','\n','}','\n'};
str = SysAllocStringLen(function->src_str, function->src_len);
if(!str)
return E_OUTOFMEMORY;
if(function->value_proc) {
DWORD name_len;
name_len = strlenW(function->name);
str = SysAllocStringLen(NULL, sizeof(native_prefixW) + name_len*sizeof(WCHAR) + sizeof(native_suffixW));
if(!str)
return E_OUTOFMEMORY;
memcpy(str, native_prefixW, sizeof(native_prefixW));
memcpy(str + sizeof(native_prefixW)/sizeof(WCHAR), function->name, name_len*sizeof(WCHAR));
memcpy(str + sizeof(native_prefixW)/sizeof(WCHAR) + name_len, native_suffixW, sizeof(native_suffixW));
}else {
str = SysAllocStringLen(function->src_str, function->src_len);
if(!str)
return E_OUTOFMEMORY;
}
*ret = str;
return S_OK;
}
static HRESULT Function_length(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT Function_length(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
FunctionInstance *This = (FunctionInstance*)dispex;
FunctionInstance *This = function_from_vdisp(jsthis);
TRACE("%p %d\n", This, This->length);
@ -259,7 +320,7 @@ static HRESULT Function_length(DispatchEx *dispex, LCID lcid, WORD flags, DISPPA
return S_OK;
}
static HRESULT Function_toString(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT Function_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
FunctionInstance *function;
@ -268,10 +329,8 @@ static HRESULT Function_toString(DispatchEx *dispex, LCID lcid, WORD flags, DISP
TRACE("\n");
if(!is_class(dispex, JSCLASS_FUNCTION))
return throw_type_error(dispex->ctx, ei, IDS_NOT_FUNC, NULL);
function = (FunctionInstance*)dispex;
if(!(function = function_this(jsthis)))
return throw_type_error(ctx, ei, IDS_NOT_FUNC, NULL);
hres = function_to_string(function, &str);
if(FAILED(hres))
@ -286,40 +345,145 @@ static HRESULT Function_toString(DispatchEx *dispex, LCID lcid, WORD flags, DISP
return S_OK;
}
static HRESULT Function_apply(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
static HRESULT array_to_args(script_ctx_t *ctx, DispatchEx *arg_array, jsexcept_t *ei, IServiceProvider *caller,
DISPPARAMS *args)
{
FIXME("\n");
return E_NOTIMPL;
VARIANT var, *argv;
DWORD length, i;
HRESULT hres;
hres = jsdisp_propget_name(arg_array, lengthW, &var, ei, NULL/*FIXME*/);
if(FAILED(hres))
return hres;
hres = to_uint32(ctx, &var, ei, &length);
VariantClear(&var);
if(FAILED(hres))
return hres;
argv = heap_alloc(length * sizeof(VARIANT));
if(!argv)
return E_OUTOFMEMORY;
for(i=0; i<length; i++) {
hres = jsdisp_propget_idx(arg_array, i, argv+i, ei, caller);
if(FAILED(hres)) {
while(i--)
VariantClear(argv+i);
heap_free(argv);
return hres;
}
}
args->cArgs = length;
args->rgvarg = argv;
return S_OK;
}
static HRESULT Function_call(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
static HRESULT Function_apply(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
{
FIXME("\n");
return E_NOTIMPL;
FunctionInstance *function;
DISPPARAMS args = {NULL,NULL,0,0};
DWORD argc, i;
IDispatch *this_obj = NULL;
HRESULT hres = S_OK;
TRACE("\n");
if(!(function = function_this(jsthis)))
return throw_type_error(ctx, ei, IDS_NOT_FUNC, NULL);
argc = arg_cnt(dp);
if(argc) {
hres = to_object(ctx, get_arg(dp,0), &this_obj);
if(FAILED(hres))
return hres;
}
if(argc >= 2) {
DispatchEx *arg_array = NULL;
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) )) {
jsdisp_release(arg_array);
arg_array = NULL;
}
}
if(arg_array) {
hres = array_to_args(ctx, arg_array, ei, caller, &args);
jsdisp_release(arg_array);
}else {
FIXME("throw TypeError\n");
hres = E_FAIL;
}
}
hres = call_function(ctx, function, this_obj, &args, retv, ei, caller);
if(this_obj)
IDispatch_Release(this_obj);
for(i=0; i<args.cArgs; i++)
VariantClear(args.rgvarg+i);
heap_free(args.rgvarg);
return hres;
}
HRESULT Function_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT Function_call(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
{
FunctionInstance *function;
DISPPARAMS args = {NULL,NULL,0,0};
IDispatch *this_obj = NULL;
DWORD argc;
HRESULT hres;
TRACE("\n");
if(!(function = function_this(jsthis)))
return throw_type_error(ctx, ei, IDS_NOT_FUNC, NULL);
argc = arg_cnt(dp);
if(argc) {
hres = to_object(ctx, get_arg(dp,0), &this_obj);
if(FAILED(hres))
return hres;
args.cArgs = argc-1;
}
if(args.cArgs)
args.rgvarg = dp->rgvarg + dp->cArgs - args.cArgs-1;
hres = call_function(ctx, function, this_obj, &args, retv, ei, caller);
if(this_obj)
IDispatch_Release(this_obj);
return hres;
}
HRESULT Function_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
{
FunctionInstance *function;
TRACE("\n");
if(dispex->builtin_info->class != JSCLASS_FUNCTION) {
if(!is_vclass(jsthis, JSCLASS_FUNCTION)) {
ERR("dispex is not a function\n");
return E_FAIL;
}
function = (FunctionInstance*)dispex;
function = (FunctionInstance*)jsthis->u.jsdisp;
switch(flags) {
case DISPATCH_METHOD:
if(function->value_proc)
return invoke_value_proc(function, lcid, flags, dp, retv, ei, caller);
return invoke_value_proc(ctx, function, get_this(dp), flags, dp, retv, ei, caller);
return invoke_function(function, lcid, dp, retv, ei, caller);
return invoke_source(ctx, function, get_this(dp), dp, retv, ei, caller);
case DISPATCH_PROPERTYGET: {
HRESULT hres;
@ -336,9 +500,9 @@ HRESULT Function_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp
case DISPATCH_CONSTRUCT:
if(function->value_proc)
return invoke_value_proc(function, lcid, flags, dp, retv, ei, caller);
return invoke_value_proc(ctx, function, get_this(dp), flags, dp, retv, ei, caller);
return invoke_constructor(function, lcid, dp, retv, ei, caller);
return invoke_constructor(ctx, function, dp, retv, ei, caller);
default:
FIXME("not implemented flags %x\n", flags);
@ -360,8 +524,8 @@ static void Function_destructor(DispatchEx *dispex)
}
static const builtin_prop_t Function_props[] = {
{applyW, Function_apply, PROPF_METHOD},
{callW, Function_call, PROPF_METHOD},
{applyW, Function_apply, PROPF_METHOD|2},
{callW, Function_call, PROPF_METHOD|1},
{lengthW, Function_length, 0},
{toStringW, Function_toString, PROPF_METHOD}
};
@ -375,14 +539,14 @@ static const builtin_info_t Function_info = {
NULL
};
static HRESULT FunctionConstr_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
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(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT FunctionProt_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
FIXME("\n");
@ -424,10 +588,10 @@ static HRESULT set_prototype(script_ctx_t *ctx, DispatchEx *dispex, DispatchEx *
V_DISPATCH(&var) = (IDispatch*)_IDispatchEx_(prototype);
memset(&jsexcept, 0, sizeof(jsexcept));
return jsdisp_propput_name(dispex, prototypeW, ctx->lcid, &var, &jsexcept, NULL/*FIXME*/);
return jsdisp_propput_name(dispex, prototypeW, &var, &jsexcept, NULL/*FIXME*/);
}
HRESULT create_builtin_function(script_ctx_t *ctx, builtin_invoke_t value_proc,
HRESULT create_builtin_function(script_ctx_t *ctx, builtin_invoke_t value_proc, const WCHAR *name,
const builtin_info_t *builtin_info, DWORD flags, DispatchEx *prototype, DispatchEx **ret)
{
FunctionInstance *function;
@ -444,6 +608,7 @@ HRESULT create_builtin_function(script_ctx_t *ctx, builtin_invoke_t value_proc,
}
function->value_proc = value_proc;
function->name = name;
*ret = &function->dispex;
return S_OK;
@ -499,15 +664,19 @@ HRESULT init_function_constr(script_ctx_t *ctx, DispatchEx *object_prototype)
FunctionInstance *prot, *constr;
HRESULT hres;
static const WCHAR FunctionW[] = {'F','u','n','c','t','i','o','n',0};
hres = create_function(ctx, NULL, PROPF_CONSTR, TRUE, object_prototype, &prot);
if(FAILED(hres))
return hres;
prot->value_proc = FunctionProt_value;
prot->name = prototypeW;
hres = create_function(ctx, NULL, PROPF_CONSTR, TRUE, &prot->dispex, &constr);
if(SUCCEEDED(hres)) {
constr->value_proc = FunctionConstr_value;
constr->name = FunctionW;
hres = set_prototype(ctx, &constr->dispex, &prot->dispex);
if(FAILED(hres))
jsdisp_release(&constr->dispex);

View file

@ -69,6 +69,9 @@ static const WCHAR ScriptEngineBuildVersionW[] =
static const WCHAR CollectGarbageW[] = {'C','o','l','l','e','c','t','G','a','r','b','a','g','e',0};
static const WCHAR MathW[] = {'M','a','t','h',0};
static const WCHAR encodeURIW[] = {'e','n','c','o','d','e','U','R','I',0};
static const WCHAR decodeURIW[] = {'d','e','c','o','d','e','U','R','I',0};
static const WCHAR encodeURIComponentW[] = {'e','n','c','o','d','e','U','R','I','C','o','m','p','o','n','e','n','t',0};
static const WCHAR decodeURIComponentW[] = {'d','e','c','o','d','e','U','R','I','C','o','m','p','o','n','e','n','t',0};
static const WCHAR undefinedW[] = {'u','n','d','e','f','i','n','e','d',0};
@ -103,11 +106,11 @@ static WCHAR int_to_char(int i)
return 'A'+i-10;
}
static HRESULT constructor_call(DispatchEx *constr, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT constructor_call(DispatchEx *constr, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
if(flags != DISPATCH_PROPERTYGET)
return jsdisp_call_value(constr, lcid, flags, dp, retv, ei, sp);
return jsdisp_call_value(constr, flags, dp, retv, ei, sp);
V_VT(retv) = VT_DISPATCH;
V_DISPATCH(retv) = (IDispatch*)_IDispatchEx_(constr);
@ -115,7 +118,7 @@ static HRESULT constructor_call(DispatchEx *constr, LCID lcid, WORD flags, DISPP
return S_OK;
}
static HRESULT JSGlobal_NaN(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT JSGlobal_NaN(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
TRACE("\n");
@ -133,7 +136,7 @@ static HRESULT JSGlobal_NaN(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAM
return S_OK;
}
static HRESULT JSGlobal_Infinity(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT JSGlobal_Infinity(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
TRACE("\n");
@ -151,156 +154,221 @@ static HRESULT JSGlobal_Infinity(DispatchEx *dispex, LCID lcid, WORD flags, DISP
return S_OK;
}
static HRESULT JSGlobal_Array(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT JSGlobal_Array(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
TRACE("\n");
return constructor_call(dispex->ctx->array_constr, lcid, flags, dp, retv, ei, sp);
return constructor_call(ctx->array_constr, flags, dp, retv, ei, sp);
}
static HRESULT JSGlobal_Boolean(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT JSGlobal_Boolean(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
TRACE("\n");
return constructor_call(dispex->ctx->bool_constr, lcid, flags, dp, retv, ei, sp);
return constructor_call(ctx->bool_constr, flags, dp, retv, ei, sp);
}
static HRESULT JSGlobal_Date(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT JSGlobal_Date(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
TRACE("\n");
return constructor_call(dispex->ctx->date_constr, lcid, flags, dp, retv, ei, sp);
return constructor_call(ctx->date_constr, flags, dp, retv, ei, sp);
}
static HRESULT JSGlobal_Error(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT JSGlobal_Error(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
TRACE("\n");
return constructor_call(dispex->ctx->error_constr, lcid, flags, dp, retv, ei, sp);
return constructor_call(ctx->error_constr, flags, dp, retv, ei, sp);
}
static HRESULT JSGlobal_EvalError(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT JSGlobal_EvalError(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
TRACE("\n");
return constructor_call(dispex->ctx->eval_error_constr, lcid, flags, dp, retv, ei, sp);
return constructor_call(ctx->eval_error_constr, flags, dp, retv, ei, sp);
}
static HRESULT JSGlobal_RangeError(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT JSGlobal_RangeError(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
TRACE("\n");
return constructor_call(dispex->ctx->range_error_constr, lcid, flags, dp, retv, ei, sp);
return constructor_call(ctx->range_error_constr, flags, dp, retv, ei, sp);
}
static HRESULT JSGlobal_ReferenceError(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT JSGlobal_ReferenceError(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
TRACE("\n");
return constructor_call(dispex->ctx->reference_error_constr, lcid, flags, dp, retv, ei, sp);
return constructor_call(ctx->reference_error_constr, flags, dp, retv, ei, sp);
}
static HRESULT JSGlobal_SyntaxError(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT JSGlobal_SyntaxError(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
TRACE("\n");
return constructor_call(dispex->ctx->syntax_error_constr, lcid, flags, dp, retv, ei, sp);
return constructor_call(ctx->syntax_error_constr, flags, dp, retv, ei, sp);
}
static HRESULT JSGlobal_TypeError(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT JSGlobal_TypeError(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
TRACE("\n");
return constructor_call(dispex->ctx->type_error_constr, lcid, flags, dp, retv, ei, sp);
return constructor_call(ctx->type_error_constr, flags, dp, retv, ei, sp);
}
static HRESULT JSGlobal_URIError(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT JSGlobal_URIError(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
TRACE("\n");
return constructor_call(dispex->ctx->uri_error_constr, lcid, flags, dp, retv, ei, sp);
return constructor_call(ctx->uri_error_constr, flags, dp, retv, ei, sp);
}
static HRESULT JSGlobal_Function(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT JSGlobal_Function(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
TRACE("\n");
return constructor_call(dispex->ctx->function_constr, lcid, flags, dp, retv, ei, sp);
return constructor_call(ctx->function_constr, flags, dp, retv, ei, sp);
}
static HRESULT JSGlobal_Number(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT JSGlobal_Number(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
TRACE("\n");
return constructor_call(dispex->ctx->number_constr, lcid, flags, dp, retv, ei, sp);
return constructor_call(ctx->number_constr, flags, dp, retv, ei, sp);
}
static HRESULT JSGlobal_Object(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT JSGlobal_Object(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
TRACE("\n");
return constructor_call(dispex->ctx->object_constr, lcid, flags, dp, retv, ei, sp);
return constructor_call(ctx->object_constr, flags, dp, retv, ei, sp);
}
static HRESULT JSGlobal_String(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT JSGlobal_String(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
TRACE("\n");
return constructor_call(dispex->ctx->string_constr, lcid, flags, dp, retv, ei, sp);
return constructor_call(ctx->string_constr, flags, dp, retv, ei, sp);
}
static HRESULT JSGlobal_RegExp(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT JSGlobal_RegExp(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
TRACE("\n");
return constructor_call(dispex->ctx->regexp_constr, lcid, flags, dp, retv, ei, sp);
return constructor_call(ctx->regexp_constr, flags, dp, retv, ei, sp);
}
static HRESULT JSGlobal_ActiveXObject(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT JSGlobal_ActiveXObject(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
TRACE("\n");
return constructor_call(ctx->activex_constr, flags, dp, retv, ei, sp);
}
static HRESULT JSGlobal_VBArray(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 JSGlobal_VBArray(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT JSGlobal_Enumerator(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 JSGlobal_Enumerator(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT JSGlobal_escape(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
FIXME("\n");
return E_NOTIMPL;
}
BSTR ret, str;
const WCHAR *ptr;
DWORD len = 0;
HRESULT hres;
static HRESULT JSGlobal_escape(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
FIXME("\n");
return E_NOTIMPL;
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(*ptr > 0xff)
len += 6;
else if(isalnum((char)*ptr) || *ptr=='*' || *ptr=='@' || *ptr=='-'
|| *ptr=='_' || *ptr=='+' || *ptr=='.' || *ptr=='/')
len++;
else
len += 3;
}
ret = SysAllocStringLen(NULL, len);
if(!ret)
return E_OUTOFMEMORY;
len = 0;
for(ptr=str; *ptr; ptr++) {
if(*ptr > 0xff) {
ret[len++] = '%';
ret[len++] = 'u';
ret[len++] = int_to_char(*ptr >> 12);
ret[len++] = int_to_char((*ptr >> 8) & 0xf);
ret[len++] = int_to_char((*ptr >> 4) & 0xf);
ret[len++] = int_to_char(*ptr & 0xf);
}
else if(isalnum((char)*ptr) || *ptr=='*' || *ptr=='@' || *ptr=='-'
|| *ptr=='_' || *ptr=='+' || *ptr=='.' || *ptr=='/')
ret[len++] = *ptr;
else {
ret[len++] = '%';
ret[len++] = int_to_char(*ptr >> 4);
ret[len++] = int_to_char(*ptr & 0xf);
}
}
if(retv) {
V_VT(retv) = VT_BSTR;
V_BSTR(retv) = ret;
}
else
SysFreeString(ret);
return S_OK;
}
/* ECMA-262 3rd Edition 15.1.2.1 */
static HRESULT JSGlobal_eval(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT JSGlobal_eval(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
parser_ctx_t *parser_ctx;
@ -324,25 +392,25 @@ static HRESULT JSGlobal_eval(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARA
return S_OK;
}
if(!dispex->ctx->exec_ctx) {
if(!ctx->exec_ctx) {
FIXME("No active exec_ctx\n");
return E_UNEXPECTED;
}
TRACE("parsing %s\n", debugstr_w(V_BSTR(arg)));
hres = script_parse(dispex->ctx, V_BSTR(arg), NULL, &parser_ctx);
hres = script_parse(ctx, V_BSTR(arg), NULL, &parser_ctx);
if(FAILED(hres)) {
WARN("parse (%s) failed: %08x\n", debugstr_w(V_BSTR(arg)), hres);
return throw_syntax_error(dispex->ctx, ei, hres, NULL);
return throw_syntax_error(ctx, ei, hres, NULL);
}
hres = exec_source(dispex->ctx->exec_ctx, parser_ctx, parser_ctx->source, ei, retv);
hres = exec_source(ctx->exec_ctx, parser_ctx, parser_ctx->source, ei, retv);
parser_release(parser_ctx);
return hres;
}
static HRESULT JSGlobal_isNaN(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT JSGlobal_isNaN(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
VARIANT_BOOL ret = VARIANT_FALSE;
@ -352,7 +420,7 @@ static HRESULT JSGlobal_isNaN(DispatchEx *dispex, LCID lcid, WORD flags, DISPPAR
TRACE("\n");
if(arg_cnt(dp)) {
hres = to_number(dispex->ctx, get_arg(dp,0), ei, &num);
hres = to_number(ctx, get_arg(dp,0), ei, &num);
if(FAILED(hres))
return hres;
@ -369,7 +437,7 @@ static HRESULT JSGlobal_isNaN(DispatchEx *dispex, LCID lcid, WORD flags, DISPPAR
return S_OK;
}
static HRESULT JSGlobal_isFinite(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT JSGlobal_isFinite(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
VARIANT_BOOL ret = VARIANT_FALSE;
@ -380,7 +448,7 @@ static HRESULT JSGlobal_isFinite(DispatchEx *dispex, LCID lcid, WORD flags, DISP
if(arg_cnt(dp)) {
VARIANT num;
hres = to_number(dispex->ctx, get_arg(dp,0), ei, &num);
hres = to_number(ctx, get_arg(dp,0), ei, &num);
if(FAILED(hres))
return hres;
@ -406,7 +474,7 @@ static INT char_to_int(WCHAR c)
return 100;
}
static HRESULT JSGlobal_parseInt(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT JSGlobal_parseInt(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
DOUBLE ret = 0.0;
@ -422,7 +490,7 @@ static HRESULT JSGlobal_parseInt(DispatchEx *dispex, LCID lcid, WORD flags, DISP
}
if(arg_cnt(dp) >= 2) {
hres = to_int32(dispex->ctx, get_arg(dp, 1), ei, &radix);
hres = to_int32(ctx, get_arg(dp, 1), ei, &radix);
if(FAILED(hres))
return hres;
@ -434,7 +502,7 @@ static HRESULT JSGlobal_parseInt(DispatchEx *dispex, LCID lcid, WORD flags, DISP
}
}
hres = to_string(dispex->ctx, get_arg(dp, 0), ei, &str);
hres = to_string(ctx, get_arg(dp, 0), ei, &str);
if(FAILED(hres))
return hres;
@ -474,7 +542,7 @@ static HRESULT JSGlobal_parseInt(DispatchEx *dispex, LCID lcid, WORD flags, DISP
return S_OK;
}
static HRESULT JSGlobal_parseFloat(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT JSGlobal_parseFloat(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
LONGLONG d = 0, hlp;
@ -492,7 +560,7 @@ static HRESULT JSGlobal_parseFloat(DispatchEx *dispex, LCID lcid, WORD flags, DI
}
arg = get_arg(dp, 0);
hres = to_string(dispex->ctx, arg, ei, &val_str);
hres = to_string(ctx, arg, ei, &val_str);
if(FAILED(hres))
return hres;
@ -576,56 +644,130 @@ static HRESULT JSGlobal_parseFloat(DispatchEx *dispex, LCID lcid, WORD flags, DI
return S_OK;
}
static HRESULT JSGlobal_unescape(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static inline int hex_to_int(const WCHAR wch) {
if(toupperW(wch)>='A' && toupperW(wch)<='F') return toupperW(wch)-'A'+10;
if(isdigitW(wch)) return wch-'0';
return -1;
}
static HRESULT JSGlobal_unescape(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
BSTR ret, str;
const WCHAR *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;
for(ptr=str; *ptr; ptr++) {
if(*ptr == '%') {
if(hex_to_int(*(ptr+1))!=-1 && hex_to_int(*(ptr+2))!=-1)
ptr += 2;
else if(*(ptr+1)=='u' && hex_to_int(*(ptr+2))!=-1 && hex_to_int(*(ptr+3))!=-1
&& hex_to_int(*(ptr+4))!=-1 && hex_to_int(*(ptr+5))!=-1)
ptr += 5;
}
len++;
}
ret = SysAllocStringLen(NULL, len);
if(!ret)
return E_OUTOFMEMORY;
len = 0;
for(ptr=str; *ptr; ptr++) {
if(*ptr == '%') {
if(hex_to_int(*(ptr+1))!=-1 && hex_to_int(*(ptr+2))!=-1) {
ret[len] = (hex_to_int(*(ptr+1))<<4) + hex_to_int(*(ptr+2));
ptr += 2;
}
else if(*(ptr+1)=='u' && hex_to_int(*(ptr+2))!=-1 && hex_to_int(*(ptr+3))!=-1
&& hex_to_int(*(ptr+4))!=-1 && hex_to_int(*(ptr+5))!=-1) {
ret[len] = (hex_to_int(*(ptr+2))<<12) + (hex_to_int(*(ptr+3))<<8)
+ (hex_to_int(*(ptr+4))<<4) + hex_to_int(*(ptr+5));
ptr += 5;
}
else
ret[len] = *ptr;
}
else
ret[len] = *ptr;
len++;
}
if(retv) {
V_VT(retv) = VT_BSTR;
V_BSTR(retv) = ret;
}
else
SysFreeString(ret);
return S_OK;
}
static HRESULT JSGlobal_GetObject(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 JSGlobal_GetObject(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT JSGlobal_ScriptEngine(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 JSGlobal_ScriptEngine(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT JSGlobal_ScriptEngineMajorVersion(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 JSGlobal_ScriptEngineMajorVersion(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT JSGlobal_ScriptEngineMinorVersion(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 JSGlobal_ScriptEngineMinorVersion(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT JSGlobal_ScriptEngineBuildVersion(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 JSGlobal_ScriptEngineBuildVersion(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT JSGlobal_CollectGarbage(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 JSGlobal_CollectGarbage(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
FIXME("\n");
return E_NOTIMPL;
}
static HRESULT JSGlobal_encodeURI(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT JSGlobal_encodeURI(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
const WCHAR *ptr;
@ -650,7 +792,7 @@ static HRESULT JSGlobal_encodeURI(DispatchEx *dispex, LCID lcid, WORD flags, DIS
return S_OK;
}
hres = to_string(dispex->ctx, get_arg(dp,0), ei, &str);
hres = to_string(ctx, get_arg(dp,0), ei, &str);
if(FAILED(hres))
return hres;
@ -695,8 +837,29 @@ static HRESULT JSGlobal_encodeURI(DispatchEx *dispex, LCID lcid, WORD flags, DIS
return S_OK;
}
static HRESULT JSGlobal_decodeURI(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 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;
}
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;
}
static const builtin_prop_t JSGlobal_props[] = {
{ActiveXObjectW, JSGlobal_ActiveXObject, PROPF_METHOD},
{ActiveXObjectW, JSGlobal_ActiveXObject, PROPF_CONSTR},
{ArrayW, JSGlobal_Array, PROPF_CONSTR},
{BooleanW, JSGlobal_Boolean, PROPF_CONSTR},
{CollectGarbageW, JSGlobal_CollectGarbage, PROPF_METHOD},
@ -723,7 +886,10 @@ static const builtin_prop_t JSGlobal_props[] = {
{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},
{evalW, JSGlobal_eval, PROPF_METHOD|1},
{isFiniteW, JSGlobal_isFinite, PROPF_METHOD},
@ -754,6 +920,10 @@ static HRESULT init_constructors(script_ctx_t *ctx, DispatchEx *object_prototype
if(FAILED(hres))
return hres;
hres = create_activex_constr(ctx, &ctx->activex_constr);
if(FAILED(hres))
return hres;
hres = create_array_constr(ctx, object_prototype, &ctx->array_constr);
if(FAILED(hres))
return hres;
@ -813,7 +983,7 @@ HRESULT init_global(script_ctx_t *ctx)
V_VT(&var) = VT_DISPATCH;
V_DISPATCH(&var) = (IDispatch*)_IDispatchEx_(math);
hres = jsdisp_propput_name(ctx->global, MathW, ctx->lcid, &var, NULL/*FIXME*/, NULL/*FIXME*/);
hres = jsdisp_propput_name(ctx->global, MathW, &var, NULL/*FIXME*/, NULL/*FIXME*/);
jsdisp_release(math);
return hres;

View file

@ -96,7 +96,7 @@ static HRESULT exec_global_code(JScript *This, parser_ctx_t *parser_ctx)
VARIANT var;
HRESULT hres;
hres = create_exec_ctx((IDispatch*)_IDispatchEx_(This->ctx->script_disp), This->ctx->script_disp, NULL, &exec_ctx);
hres = create_exec_ctx(This->ctx, NULL, This->ctx->global, NULL, &exec_ctx);
if(FAILED(hres))
return hres;
@ -148,12 +148,6 @@ static HRESULT set_ctx_site(JScript *This)
This->ctx->lcid = This->lcid;
if(!This->ctx->script_disp) {
hres = create_dispex(This->ctx, NULL, NULL, &This->ctx->script_disp);
if(FAILED(hres))
return hres;
}
hres = init_global(This->ctx);
if(FAILED(hres))
return hres;
@ -165,6 +159,105 @@ static HRESULT set_ctx_site(JScript *This)
return S_OK;
}
typedef struct {
const IServiceProviderVtbl *lpIServiceProviderVtbl;
LONG ref;
IServiceProvider *sp;
} AXSite;
#define SERVPROV(x) ((IServiceProvider*) &(x)->lpIServiceProviderVtbl)
#define SERVPROV_THIS(iface) DEFINE_THIS(AXSite, IServiceProvider, iface)
static HRESULT WINAPI AXSite_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppv)
{
AXSite *This = SERVPROV_THIS(iface);
if(IsEqualGUID(&IID_IUnknown, riid)) {
TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
*ppv = SERVPROV(This);
}else if(IsEqualGUID(&IID_IServiceProvider, riid)) {
TRACE("(%p)->(IID_IServiceProvider %p)\n", This, ppv);
*ppv = SERVPROV(This);
}else {
TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
*ppv = NULL;
return E_NOINTERFACE;
}
IUnknown_AddRef((IUnknown*)*ppv);
return S_OK;
}
static ULONG WINAPI AXSite_AddRef(IServiceProvider *iface)
{
AXSite *This = SERVPROV_THIS(iface);
LONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) ref=%d\n", This, ref);
return ref;
}
static ULONG WINAPI AXSite_Release(IServiceProvider *iface)
{
AXSite *This = SERVPROV_THIS(iface);
LONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) ref=%d\n", This, ref);
if(!ref)
heap_free(This);
return ref;
}
static HRESULT WINAPI AXSite_QueryService(IServiceProvider *iface,
REFGUID guidService, REFIID riid, void **ppv)
{
AXSite *This = SERVPROV_THIS(iface);
TRACE("(%p)->(%s %s %p)\n", This, debugstr_guid(guidService), debugstr_guid(riid), ppv);
return IServiceProvider_QueryService(This->sp, guidService, riid, ppv);
}
#undef SERVPROV_THIS
static IServiceProviderVtbl AXSiteVtbl = {
AXSite_QueryInterface,
AXSite_AddRef,
AXSite_Release,
AXSite_QueryService
};
IUnknown *create_ax_site(script_ctx_t *ctx)
{
IServiceProvider *sp;
AXSite *ret;
HRESULT hres;
hres = IActiveScriptSite_QueryInterface(ctx->site, &IID_IServiceProvider, (void**)&sp);
if(FAILED(hres)) {
ERR("Could not get IServiceProvider iface: %08x\n", hres);
return NULL;
}
ret = heap_alloc(sizeof(AXSite));
if(!ret) {
IServiceProvider_Release(sp);
return NULL;
}
ret->lpIServiceProviderVtbl = &AXSiteVtbl;
ret->ref = 1;
ret->sp = sp;
return (IUnknown*)SERVPROV(ret);
}
#define ACTSCRIPT_THIS(iface) DEFINE_THIS(JScript, IActiveScript, iface)
static HRESULT WINAPI JScript_QueryInterface(IActiveScript *iface, REFIID riid, void **ppv)
@ -335,6 +428,11 @@ static HRESULT WINAPI JScript_Close(IActiveScript *iface)
if(This->ctx->state == SCRIPTSTATE_DISCONNECTED)
change_state(This, SCRIPTSTATE_INITIALIZED);
if(This->ctx->host_global) {
IDispatch_Release(This->ctx->host_global);
This->ctx->host_global = NULL;
}
if(This->ctx->named_items) {
named_item_t *iter, *iter2;
@ -352,6 +450,11 @@ static HRESULT WINAPI JScript_Close(IActiveScript *iface)
This->ctx->named_items = NULL;
}
if(This->ctx->secmgr) {
IInternetHostSecurityManager_Release(This->ctx->secmgr);
This->ctx->secmgr = NULL;
}
if(This->ctx->site) {
IActiveScriptSite_Release(This->ctx->site);
This->ctx->site = NULL;
@ -360,13 +463,8 @@ static HRESULT WINAPI JScript_Close(IActiveScript *iface)
if (This->site)
change_state(This, SCRIPTSTATE_CLOSED);
if(This->ctx->script_disp) {
IDispatchEx_Release(_IDispatchEx_(This->ctx->script_disp));
This->ctx->script_disp = NULL;
}
if(This->ctx->global) {
IDispatchEx_Release(_IDispatchEx_(This->ctx->global));
jsdisp_release(This->ctx->global);
This->ctx->global = NULL;
}
}
@ -407,6 +505,11 @@ static HRESULT WINAPI JScript_AddNamedItem(IActiveScript *iface,
WARN("object does not implement IDispatch\n");
return hres;
}
if(This->ctx->host_global)
IDispatch_Release(This->ctx->host_global);
IDispatch_AddRef(disp);
This->ctx->host_global = disp;
}
item = heap_alloc(sizeof(*item));
@ -449,12 +552,12 @@ static HRESULT WINAPI JScript_GetScriptDispatch(IActiveScript *iface, LPCOLESTR
if(!ppdisp)
return E_POINTER;
if(This->thread_id != GetCurrentThreadId() || !This->ctx->script_disp) {
if(This->thread_id != GetCurrentThreadId() || !This->ctx->global) {
*ppdisp = NULL;
return E_UNEXPECTED;
}
*ppdisp = (IDispatch*)_IDispatchEx_(This->ctx->script_disp);
*ppdisp = (IDispatch*)_IDispatchEx_(This->ctx->global);
IDispatch_AddRef(*ppdisp);
return S_OK;
}
@ -555,6 +658,7 @@ static HRESULT WINAPI JScriptParse_InitNew(IActiveScriptParse *iface)
ctx->ref = 1;
ctx->state = SCRIPTSTATE_UNINITIALIZED;
ctx->safeopt = This->safeopt;
jsheap_init(&ctx->tmp_heap);
ctx = InterlockedCompareExchangePointer((void**)&This->ctx, ctx, NULL);

View file

@ -1,5 +1,5 @@
/*
* Copyright 2008 Jacek Caban for CodeWeavers
* Copyright 2008-2009 Jacek Caban for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -69,6 +69,7 @@ extern HINSTANCE jscript_hinstance;
#define PROPF_ENUM 0x0200
#define PROPF_CONSTR 0x0400
/* NOTE: Keep in sync with names in Object.toString implementation */
typedef enum {
JSCLASS_NONE,
JSCLASS_ARRAY,
@ -81,10 +82,77 @@ typedef enum {
JSCLASS_NUMBER,
JSCLASS_OBJECT,
JSCLASS_REGEXP,
JSCLASS_STRING
JSCLASS_STRING,
JSCLASS_ARGUMENTS
} jsclass_t;
typedef HRESULT (*builtin_invoke_t)(DispatchEx*,LCID,WORD,DISPPARAMS*,VARIANT*,jsexcept_t*,IServiceProvider*);
DispatchEx *iface_to_jsdisp(IUnknown*);
typedef struct {
union {
IDispatch *disp;
IDispatchEx *dispex;
DispatchEx *jsdisp;
} u;
DWORD flags;
} vdisp_t;
#define VDISP_DISPEX 0x0001
#define VDISP_JSDISP 0x0002
static inline void vdisp_release(vdisp_t *vdisp)
{
IDispatch_Release(vdisp->u.disp);
}
static inline BOOL is_jsdisp(vdisp_t *vdisp)
{
return (vdisp->flags & VDISP_JSDISP) != 0;
}
static inline BOOL is_dispex(vdisp_t *vdisp)
{
return (vdisp->flags & VDISP_DISPEX) != 0;
}
static inline void set_jsdisp(vdisp_t *vdisp, DispatchEx *jsdisp)
{
vdisp->u.jsdisp = jsdisp;
vdisp->flags = VDISP_JSDISP | VDISP_DISPEX;
IDispatch_AddRef(vdisp->u.disp);
}
static inline void set_disp(vdisp_t *vdisp, IDispatch *disp)
{
IDispatchEx *dispex;
DispatchEx *jsdisp;
HRESULT hres;
jsdisp = iface_to_jsdisp((IUnknown*)disp);
if(jsdisp) {
vdisp->u.jsdisp = jsdisp;
vdisp->flags = VDISP_JSDISP | VDISP_DISPEX;
return;
}
hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
if(SUCCEEDED(hres)) {
vdisp->u.dispex = dispex;
vdisp->flags = VDISP_DISPEX;
return;
}
IDispatch_AddRef(disp);
vdisp->u.disp = disp;
vdisp->flags = 0;
}
static inline DispatchEx *get_jsdisp(vdisp_t *vdisp)
{
return is_jsdisp(vdisp) ? vdisp->u.jsdisp : NULL;
}
typedef HRESULT (*builtin_invoke_t)(script_ctx_t*,vdisp_t*,WORD,DISPPARAMS*,VARIANT*,jsexcept_t*,IServiceProvider*);
typedef struct {
const WCHAR *name;
@ -126,34 +194,34 @@ static inline void jsdisp_release(DispatchEx *jsdisp)
HRESULT create_dispex(script_ctx_t*,const builtin_info_t*,DispatchEx*,DispatchEx**);
HRESULT init_dispex(DispatchEx*,script_ctx_t*,const builtin_info_t*,DispatchEx*);
HRESULT init_dispex_from_constr(DispatchEx*,script_ctx_t*,const builtin_info_t*,DispatchEx*);
DispatchEx *iface_to_jsdisp(IUnknown*);
HRESULT disp_call(IDispatch*,DISPID,LCID,WORD,DISPPARAMS*,VARIANT*,jsexcept_t*,IServiceProvider*);
HRESULT jsdisp_call_value(DispatchEx*,LCID,WORD,DISPPARAMS*,VARIANT*,jsexcept_t*,IServiceProvider*);
HRESULT jsdisp_call(DispatchEx*,DISPID,LCID,WORD,DISPPARAMS*,VARIANT*,jsexcept_t*,IServiceProvider*);
HRESULT jsdisp_call_name(DispatchEx*,const WCHAR*,LCID,WORD,DISPPARAMS*,VARIANT*,jsexcept_t*,IServiceProvider*);
HRESULT disp_propget(IDispatch*,DISPID,LCID,VARIANT*,jsexcept_t*,IServiceProvider*);
HRESULT disp_propput(IDispatch*,DISPID,LCID,VARIANT*,jsexcept_t*,IServiceProvider*);
HRESULT jsdisp_propget(DispatchEx*,DISPID,LCID,VARIANT*,jsexcept_t*,IServiceProvider*);
HRESULT jsdisp_propput_name(DispatchEx*,const WCHAR*,LCID,VARIANT*,jsexcept_t*,IServiceProvider*);
HRESULT jsdisp_propput_idx(DispatchEx*,DWORD,LCID,VARIANT*,jsexcept_t*,IServiceProvider*);
HRESULT jsdisp_propget_name(DispatchEx*,LPCWSTR,LCID,VARIANT*,jsexcept_t*,IServiceProvider*);
HRESULT jsdisp_propget_idx(DispatchEx*,DWORD,LCID,VARIANT*,jsexcept_t*,IServiceProvider*);
HRESULT disp_call(script_ctx_t*,IDispatch*,DISPID,WORD,DISPPARAMS*,VARIANT*,jsexcept_t*,IServiceProvider*);
HRESULT jsdisp_call_value(DispatchEx*,WORD,DISPPARAMS*,VARIANT*,jsexcept_t*,IServiceProvider*);
HRESULT jsdisp_call(DispatchEx*,DISPID,WORD,DISPPARAMS*,VARIANT*,jsexcept_t*,IServiceProvider*);
HRESULT jsdisp_call_name(DispatchEx*,const WCHAR*,WORD,DISPPARAMS*,VARIANT*,jsexcept_t*,IServiceProvider*);
HRESULT disp_propget(script_ctx_t*,IDispatch*,DISPID,VARIANT*,jsexcept_t*,IServiceProvider*);
HRESULT disp_propput(script_ctx_t*,IDispatch*,DISPID,VARIANT*,jsexcept_t*,IServiceProvider*);
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_id(DispatchEx*,const WCHAR*,DWORD,DISPID*);
HRESULT jsdisp_delete_idx(DispatchEx*,DWORD);
HRESULT create_builtin_function(script_ctx_t*,builtin_invoke_t,const builtin_info_t*,DWORD,
HRESULT create_builtin_function(script_ctx_t*,builtin_invoke_t,const WCHAR*,const builtin_info_t*,DWORD,
DispatchEx*,DispatchEx**);
HRESULT Function_value(DispatchEx*,LCID,WORD,DISPPARAMS*,VARIANT*,jsexcept_t*,IServiceProvider*);
HRESULT Function_value(script_ctx_t*,vdisp_t*,WORD,DISPPARAMS*,VARIANT*,jsexcept_t*,IServiceProvider*);
HRESULT throw_eval_error(script_ctx_t*,jsexcept_t*,UINT,const WCHAR*);
HRESULT throw_generic_error(script_ctx_t*,jsexcept_t*,UINT,const WCHAR*);
HRESULT throw_range_error(script_ctx_t*,jsexcept_t*,UINT,const WCHAR*);
HRESULT throw_reference_error(script_ctx_t*,jsexcept_t*,UINT,const WCHAR*);
HRESULT throw_regexp_error(script_ctx_t*,jsexcept_t*,UINT,const WCHAR*);
HRESULT throw_syntax_error(script_ctx_t*,jsexcept_t*,UINT,const WCHAR*);
HRESULT throw_type_error(script_ctx_t*,jsexcept_t*,UINT,const WCHAR*);
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**);
@ -175,7 +243,7 @@ HRESULT to_integer(script_ctx_t*,VARIANT*,jsexcept_t*,VARIANT*);
HRESULT to_int32(script_ctx_t*,VARIANT*,jsexcept_t*,INT*);
HRESULT to_uint32(script_ctx_t*,VARIANT*,jsexcept_t*,DWORD*);
HRESULT to_string(script_ctx_t*,VARIANT*,jsexcept_t*,BSTR*);
HRESULT to_object(exec_ctx_t*,VARIANT*,IDispatch**);
HRESULT to_object(script_ctx_t*,VARIANT*,IDispatch**);
typedef struct named_item_t {
IDispatch *disp;
@ -192,13 +260,17 @@ struct _script_ctx_t {
exec_ctx_t *exec_ctx;
named_item_t *named_items;
IActiveScriptSite *site;
IInternetHostSecurityManager *secmgr;
DWORD safeopt;
LCID lcid;
jsheap_t tmp_heap;
DispatchEx *script_disp;
IDispatch *host_global;
DispatchEx *global;
DispatchEx *function_constr;
DispatchEx *activex_constr;
DispatchEx *array_constr;
DispatchEx *bool_constr;
DispatchEx *date_constr;
@ -206,6 +278,7 @@ struct _script_ctx_t {
DispatchEx *eval_error_constr;
DispatchEx *range_error_constr;
DispatchEx *reference_error_constr;
DispatchEx *regexp_error_constr;
DispatchEx *syntax_error_constr;
DispatchEx *type_error_constr;
DispatchEx *uri_error_constr;
@ -226,6 +299,7 @@ HRESULT init_global(script_ctx_t*);
HRESULT init_function_constr(script_ctx_t*,DispatchEx*);
HRESULT create_object_prototype(script_ctx_t*,DispatchEx**);
HRESULT create_activex_constr(script_ctx_t*,DispatchEx**);
HRESULT create_array_constr(script_ctx_t*,DispatchEx*,DispatchEx**);
HRESULT create_bool_constr(script_ctx_t*,DispatchEx*,DispatchEx**);
HRESULT create_date_constr(script_ctx_t*,DispatchEx*,DispatchEx**);
@ -235,14 +309,16 @@ HRESULT create_object_constr(script_ctx_t*,DispatchEx*,DispatchEx**);
HRESULT create_regexp_constr(script_ctx_t*,DispatchEx*,DispatchEx**);
HRESULT create_string_constr(script_ctx_t*,DispatchEx*,DispatchEx**);
IUnknown *create_ax_site(script_ctx_t*);
typedef struct {
const WCHAR *str;
DWORD len;
} match_result_t;
HRESULT regexp_match_next(DispatchEx*,BOOL,const WCHAR*,DWORD,const WCHAR**,match_result_t**,
HRESULT regexp_match_next(script_ctx_t*,DispatchEx*,BOOL,const WCHAR*,DWORD,const WCHAR**,match_result_t**,
DWORD*,DWORD*,match_result_t*);
HRESULT regexp_match(DispatchEx*,const WCHAR*,DWORD,BOOL,match_result_t**,DWORD*);
HRESULT regexp_match(script_ctx_t*,DispatchEx*,const WCHAR*,DWORD,BOOL,match_result_t**,DWORD*);
static inline VARIANT *get_arg(DISPPARAMS *dp, DWORD i)
{
@ -259,6 +335,11 @@ static inline BOOL is_class(DispatchEx *jsdisp, jsclass_t class)
return jsdisp->builtin_info->class == class;
}
static inline BOOL is_vclass(vdisp_t *vdisp, jsclass_t class)
{
return is_jsdisp(vdisp) && is_class(vdisp->u.jsdisp, class);
}
static inline BOOL is_num_vt(enum VARENUM vt)
{
return vt == VT_I4 || vt == VT_R8;
@ -290,7 +371,7 @@ static inline void num_set_nan(VARIANT *v)
#endif
}
static inline DOUBLE ret_nan()
static inline DOUBLE ret_nan(void)
{
VARIANT v;
num_set_nan(&v);

View file

@ -11,8 +11,10 @@
<library>wine</library>
<library>kernel32</library>
<library>user32</library>
<library>ole32</library>
<library>oleaut32</library>
<library>advapi32</library>
<file>activex.c</file>
<file>date.c</file>
<file>dispex.c</file>
<file>engine.c</file>

View file

@ -26,6 +26,7 @@ STRINGTABLE DISCARDABLE
{
IDS_TO_PRIMITIVE "Fehler beim umwandeln des Objektes in einen Grundtyp"
IDS_INVALID_CALL_ARG "Ungültiger Funktionsaufruf oder Argument"
IDS_CREATE_OBJ_ERROR "Automatisierungsserver konnte das Objekt nicht erstellen"
IDS_NO_PROPERTY "Das Objekt unterstützt diese Eigenschaft oder Methode nicht"
IDS_ARG_NOT_OPT "Argument nicht optional"
IDS_SYNTAX_ERROR "Syntax Fehler"
@ -36,8 +37,12 @@ STRINGTABLE DISCARDABLE
IDS_NOT_FUNC "Funktion erwartet"
IDS_NOT_DATE "'[Objekt]' ist kein Datums-Objekt"
IDS_NOT_NUM "Nummer erwartet"
IDS_OBJECT_EXPECTED "Objekt erwartet"
IDS_ILLEGAL_ASSIGN "Unzulässige Zuweisung"
IDS_UNDEFINED "'|' nicht definiert"
IDS_NOT_BOOL "Boolisches Objekt erwartet"
IDS_JSCRIPT_EXPECTED "JScript Objekt erwartet"
IDS_REGEXP_SYNTAX_ERROR "Syntax Fehler in regulärem Ausdruck"
IDS_INVALID_LENGTH "Array-Größe muss eine endliche, positive Ganzzahl sein"
IDS_ARRAY_EXPECTED "Array Objekt erwartet"
}

View file

@ -24,6 +24,7 @@ STRINGTABLE DISCARDABLE
{
IDS_TO_PRIMITIVE "Error converting object to primitive type"
IDS_INVALID_CALL_ARG "Invalid procedure call or argument"
IDS_CREATE_OBJ_ERROR "Automation server can't create object"
IDS_NO_PROPERTY "Object doesn't support this property or method"
IDS_ARG_NOT_OPT "Argument not optional"
IDS_SYNTAX_ERROR "Syntax error"
@ -34,8 +35,12 @@ STRINGTABLE DISCARDABLE
IDS_NOT_FUNC "Function expected"
IDS_NOT_DATE "'[object]' is not a date object"
IDS_NOT_NUM "Number expected"
IDS_OBJECT_EXPECTED "Object expected"
IDS_ILLEGAL_ASSIGN "Illegal assignment"
IDS_UNDEFINED "'|' is undefined"
IDS_NOT_BOOL "Boolean object expected"
IDS_JSCRIPT_EXPECTED "JScript object expected"
IDS_REGEXP_SYNTAX_ERROR "Syntax error in regular expression"
IDS_INVALID_LENGTH "Array length must be a finite positive integer"
IDS_ARRAY_EXPECTED "Array object expected"
}

View file

@ -29,6 +29,7 @@ STRINGTABLE DISCARDABLE
{
IDS_TO_PRIMITIVE "Erreur lors de la conversion de l'objet vers un type primitif"
IDS_INVALID_CALL_ARG "Appel de procédure ou argument invalide"
IDS_CREATE_OBJ_ERROR "Le serveur d'automatisation ne peut créer l'objet"
IDS_NO_PROPERTY "Cet objet ne supporte pas cette propriété ou méthode"
IDS_ARG_NOT_OPT "Argument non optionnel"
IDS_SYNTAX_ERROR "Erreur de syntaxe"
@ -39,8 +40,12 @@ STRINGTABLE DISCARDABLE
IDS_NOT_FUNC "Fonction attendue"
IDS_NOT_DATE "« [objet] » n'est pas un objet de type date"
IDS_NOT_NUM "Nombre attendu"
IDS_OBJECT_EXPECTED "Objet attendu"
IDS_ILLEGAL_ASSIGN "Affectation illégale"
IDS_UNDEFINED "« | » n'est pas défini"
IDS_NOT_BOOL "Booléen attendu"
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_INVALID_LENGTH "La longueur d'un tableau doit être un entier positif"
IDS_ARRAY_EXPECTED "Objet tableau attendu"
}

View file

@ -27,6 +27,7 @@ STRINGTABLE DISCARDABLE
{
IDS_TO_PRIMITIVE "Klaida keičiant objektą į primityvų tipą"
IDS_INVALID_CALL_ARG "Netinkamas kreipinys į procedūrą ar argumentas"
IDS_CREATE_OBJ_ERROR "Automatizacijos serveriui nepavyko sukurti objekto"
IDS_NO_PROPERTY "Objektas nepalaiko šios savybės ar metodo"
IDS_ARG_NOT_OPT "Argumentas nėra neprivalomas"
IDS_SYNTAX_ERROR "Sintaksės klaida"
@ -37,8 +38,12 @@ STRINGTABLE DISCARDABLE
IDS_NOT_FUNC "Tikėtasi funkcijos"
IDS_NOT_DATE "„[objektas]“ nėra datos objektas"
IDS_NOT_NUM "Tikėtasi skaičiaus"
IDS_OBJECT_EXPECTED "Tikėtasi objekto"
IDS_ILLEGAL_ASSIGN "Neleistinas priskyrimas"
IDS_UNDEFINED "„|“ yra neapibrėžtas"
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_INVALID_LENGTH "Masyvo dydis turi būti teigiamas sveikasis skaičius"
IDS_ARRAY_EXPECTED "Tikėtasi masyvo objekto"
}

View file

@ -34,8 +34,12 @@ STRINGTABLE DISCARDABLE
IDS_NOT_FUNC "Functie verwacht"
IDS_NOT_DATE "'[object]' is geen datum object"
IDS_NOT_NUM "Getal verwacht"
IDS_OBJECT_EXPECTED "Object verwacht"
IDS_ILLEGAL_ASSIGN "Ongeldige toekenning"
IDS_UNDEFINED "'|' is ongedefinieerd"
IDS_NOT_BOOL "Boolean object verwacht"
IDS_JSCRIPT_EXPECTED "JScript object verwacht"
IDS_REGEXP_SYNTAX_ERROR "Syntax fout in reguliere expressie"
IDS_INVALID_LENGTH "Array lengte moet een eindig, positief geheel getal zijn"
IDS_ARRAY_EXPECTED "Array object verwacht"
}

View file

@ -24,6 +24,7 @@
#include "advpub.h"
#include "activaut.h"
#include "objsafe.h"
#include "mshtmhst.h"
#include "wine/debug.h"

View file

@ -31,11 +31,14 @@ WINE_DECLARE_DEBUG_CHANNEL(heap);
const char *debugstr_variant(const VARIANT *v)
{
if(!v)
return "(null)";
switch(V_VT(v)) {
case VT_EMPTY:
return wine_dbg_sprintf("{VT_EMPTY}");
return "{VT_EMPTY}";
case VT_NULL:
return wine_dbg_sprintf("{VT_NULL}");
return "{VT_NULL}";
case VT_I4:
return wine_dbg_sprintf("{VT_I4: %d}", V_I4(v));
case VT_R8:
@ -198,9 +201,16 @@ HRESULT to_primitive(script_ctx_t *ctx, VARIANT *v, jsexcept_t *ei, VARIANT *ret
static const WCHAR toStringW[] = {'t','o','S','t','r','i','n','g',0};
static const WCHAR valueOfW[] = {'v','a','l','u','e','O','f',0};
if(!V_DISPATCH(v)) {
V_VT(ret) = VT_NULL;
break;
}
jsdisp = iface_to_jsdisp((IUnknown*)V_DISPATCH(v));
if(!jsdisp)
return disp_propget(V_DISPATCH(v), DISPID_VALUE, ctx->lcid, ret, ei, NULL /*FIXME*/);
if(!jsdisp) {
V_VT(ret) = VT_EMPTY;
return disp_propget(ctx, V_DISPATCH(v), DISPID_VALUE, ret, ei, NULL /*FIXME*/);
}
if(hint == NO_HINT)
hint = is_class(jsdisp, JSCLASS_DATE) ? HINT_STRING : HINT_NUMBER;
@ -209,7 +219,7 @@ HRESULT to_primitive(script_ctx_t *ctx, VARIANT *v, jsexcept_t *ei, VARIANT *ret
hres = jsdisp_get_id(jsdisp, hint == HINT_STRING ? toStringW : valueOfW, 0, &id);
if(SUCCEEDED(hres)) {
hres = jsdisp_call(jsdisp, id, ctx->lcid, DISPATCH_METHOD, &dp, ret, ei, NULL /*FIXME*/);
hres = jsdisp_call(jsdisp, id, DISPATCH_METHOD, &dp, ret, ei, NULL /*FIXME*/);
if(FAILED(hres)) {
WARN("call error - forwarding exception\n");
jsdisp_release(jsdisp);
@ -225,7 +235,7 @@ HRESULT to_primitive(script_ctx_t *ctx, VARIANT *v, jsexcept_t *ei, VARIANT *ret
hres = jsdisp_get_id(jsdisp, hint == HINT_STRING ? valueOfW : toStringW, 0, &id);
if(SUCCEEDED(hres)) {
hres = jsdisp_call(jsdisp, id, ctx->lcid, DISPATCH_METHOD, &dp, ret, ei, NULL /*FIXME*/);
hres = jsdisp_call(jsdisp, id, DISPATCH_METHOD, &dp, ret, ei, NULL /*FIXME*/);
if(FAILED(hres)) {
WARN("call error - forwarding exception\n");
jsdisp_release(jsdisp);
@ -571,14 +581,14 @@ HRESULT to_string(script_ctx_t *ctx, VARIANT *v, jsexcept_t *ei, BSTR *str)
}
/* ECMA-262 3rd Edition 9.9 */
HRESULT to_object(exec_ctx_t *ctx, VARIANT *v, IDispatch **disp)
HRESULT to_object(script_ctx_t *ctx, VARIANT *v, IDispatch **disp)
{
DispatchEx *dispex;
HRESULT hres;
switch(V_VT(v)) {
case VT_BSTR:
hres = create_string(ctx->parser->script, V_BSTR(v), SysStringLen(V_BSTR(v)), &dispex);
hres = create_string(ctx, V_BSTR(v), SysStringLen(V_BSTR(v)), &dispex);
if(FAILED(hres))
return hres;
@ -586,18 +596,28 @@ HRESULT to_object(exec_ctx_t *ctx, VARIANT *v, IDispatch **disp)
break;
case VT_I4:
case VT_R8:
hres = create_number(ctx->parser->script, v, &dispex);
hres = create_number(ctx, v, &dispex);
if(FAILED(hres))
return hres;
*disp = (IDispatch*)_IDispatchEx_(dispex);
break;
case VT_DISPATCH:
IDispatch_AddRef(V_DISPATCH(v));
*disp = V_DISPATCH(v);
if(V_DISPATCH(v)) {
IDispatch_AddRef(V_DISPATCH(v));
*disp = V_DISPATCH(v);
}else {
DispatchEx *obj;
hres = create_object(ctx, NULL, &obj);
if(FAILED(hres))
return hres;
*disp = (IDispatch*)_IDispatchEx_(obj);
}
break;
case VT_BOOL:
hres = create_bool(ctx->parser->script, V_BOOL(v), &dispex);
hres = create_bool(ctx, V_BOOL(v), &dispex);
if(FAILED(hres))
return hres;

View file

@ -105,6 +105,12 @@ static int lex_error(parser_ctx_t *ctx, HRESULT hres)
return -1;
}
/* ECMA-262 3rd Edition 7.6 */
static BOOL is_identifier_char(WCHAR c)
{
return isalnumW(c) || c == '$' || c == '_' || c == '\\';
}
static int check_keyword(parser_ctx_t *ctx, const WCHAR *word, const WCHAR **lval)
{
const WCHAR *p1 = ctx->ptr;
@ -117,7 +123,7 @@ static int check_keyword(parser_ctx_t *ctx, const WCHAR *word, const WCHAR **lva
p2++;
}
if(*p2 || (p1 < ctx->end && isalnumW(*p1)))
if(*p2 || (p1 < ctx->end && is_identifier_char(*p1)))
return 1;
*lval = ctx->ptr;
@ -131,11 +137,6 @@ static BOOL is_endline(WCHAR c)
return c == '\n' || c == '\r' || c == 0x2028 || c == 0x2029;
}
static BOOL is_identifier_char(WCHAR c)
{
return isalnumW(c) || c == '$' || c == '_' || c == '\\';
}
static int hex_to_int(WCHAR c)
{
if('0' <= c && c <= '9')
@ -286,7 +287,7 @@ static BOOL unescape(WCHAR *str)
i = hex_to_int(*++p);
if(i == -1)
return FALSE;
c += 1 << 4;
c += i << 4;
i = hex_to_int(*++p);
if(i == -1)
@ -296,13 +297,15 @@ static BOOL unescape(WCHAR *str)
default:
if(isdigitW(*p)) {
c = *p++ - '0';
while(isdigitW(*p))
c = c*10 + (*p++ - '0');
*pd++ = c;
continue;
if(isdigitW(*p)) {
c = c*8 + (*p++ - '0');
if(isdigitW(*p))
c = c*8 + (*p++ - '0');
}
p--;
}
c = *p;
else
c = *p;
}
*pd++ = c;
@ -734,7 +737,7 @@ int parser_lex(void *lval, parser_ctx_t *ctx)
if(*ctx->ptr == '=') { /* /= */
ctx->ptr++;
*(int*)lval = EXPR_ASSIGNDIV;
return tAssignOper;
return kDIVEQ;
}
}
return '/';
@ -771,7 +774,10 @@ literal_t *parse_regexp(parser_ctx_t *ctx)
TRACE("\n");
re = ctx->ptr;
while(*ctx->ptr != '/')
ctx->ptr--;
re = ++ctx->ptr;
while(ctx->ptr < ctx->end && *ctx->ptr != '/') {
if(*ctx->ptr++ == '\\' && ctx->ptr < ctx->end)
ctx->ptr++;

View file

@ -73,7 +73,7 @@ static HRESULT math_constant(DOUBLE val, WORD flags, VARIANT *retv)
}
/* ECMA-262 3rd Edition 15.8.1.1 */
static HRESULT Math_E(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT Math_E(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
TRACE("\n");
@ -81,7 +81,7 @@ static HRESULT Math_E(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
}
/* ECMA-262 3rd Edition 15.8.1.4 */
static HRESULT Math_LOG2E(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT Math_LOG2E(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
TRACE("\n");
@ -89,21 +89,21 @@ static HRESULT Math_LOG2E(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS
}
/* ECMA-262 3rd Edition 15.8.1.4 */
static HRESULT Math_LOG10E(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT Math_LOG10E(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
TRACE("\n");
return math_constant(M_LOG10E, flags, retv);
}
static HRESULT Math_LN2(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT Math_LN2(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
TRACE("\n");
return math_constant(M_LN2, flags, retv);
}
static HRESULT Math_LN10(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT Math_LN10(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
TRACE("\n");
@ -111,21 +111,21 @@ static HRESULT Math_LN10(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *
}
/* ECMA-262 3rd Edition 15.8.1.6 */
static HRESULT Math_PI(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT Math_PI(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
TRACE("\n");
return math_constant(M_PI, flags, retv);
}
static HRESULT Math_SQRT2(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT Math_SQRT2(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
TRACE("\n");
return math_constant(M_SQRT2, flags, retv);
}
static HRESULT Math_SQRT1_2(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT Math_SQRT1_2(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
TRACE("\n");
@ -133,7 +133,7 @@ static HRESULT Math_SQRT1_2(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAM
}
/* ECMA-262 3rd Edition 15.8.2.12 */
static HRESULT Math_abs(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT Math_abs(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
VARIANT v;
@ -148,7 +148,7 @@ static HRESULT Math_abs(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *d
return S_OK;
}
hres = to_number(dispex->ctx, get_arg(dp, 0), ei, &v);
hres = to_number(ctx, get_arg(dp, 0), ei, &v);
if(FAILED(hres))
return hres;
@ -158,7 +158,7 @@ static HRESULT Math_abs(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *d
return S_OK;
}
static HRESULT Math_acos(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT Math_acos(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
VARIANT v;
@ -171,7 +171,7 @@ static HRESULT Math_acos(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *
return S_OK;
}
hres = to_number(dispex->ctx, get_arg(dp, 0), ei, &v);
hres = to_number(ctx, get_arg(dp, 0), ei, &v);
if(FAILED(hres))
return hres;
@ -179,7 +179,7 @@ static HRESULT Math_acos(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *
return S_OK;
}
static HRESULT Math_asin(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT Math_asin(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
VARIANT v;
@ -192,7 +192,7 @@ static HRESULT Math_asin(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *
return S_OK;
}
hres = to_number(dispex->ctx, get_arg(dp, 0), ei, &v);
hres = to_number(ctx, get_arg(dp, 0), ei, &v);
if(FAILED(hres))
return hres;
@ -200,7 +200,7 @@ static HRESULT Math_asin(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *
return S_OK;
}
static HRESULT Math_atan(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT Math_atan(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
VARIANT v;
@ -213,7 +213,7 @@ static HRESULT Math_atan(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *
return S_OK;
}
hres = to_number(dispex->ctx, get_arg(dp, 0), ei, &v);
hres = to_number(ctx, get_arg(dp, 0), ei, &v);
if(FAILED(hres))
return hres;
@ -221,7 +221,7 @@ static HRESULT Math_atan(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *
return S_OK;
}
static HRESULT Math_atan2(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT Math_atan2(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
VARIANT v1, v2;
@ -234,11 +234,11 @@ static HRESULT Math_atan2(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS
return S_OK;
}
hres = to_number(dispex->ctx, get_arg(dp, 0), ei, &v1);
hres = to_number(ctx, get_arg(dp, 0), ei, &v1);
if(FAILED(hres))
return hres;
hres = to_number(dispex->ctx, get_arg(dp, 1), ei, &v2);
hres = to_number(ctx, get_arg(dp, 1), ei, &v2);
if(FAILED(hres))
return hres;
@ -247,7 +247,7 @@ static HRESULT Math_atan2(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS
}
/* ECMA-262 3rd Edition 15.8.2.6 */
static HRESULT Math_ceil(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT Math_ceil(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
VARIANT v;
@ -261,7 +261,7 @@ static HRESULT Math_ceil(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *
return S_OK;
}
hres = to_number(dispex->ctx, get_arg(dp, 0), ei, &v);
hres = to_number(ctx, get_arg(dp, 0), ei, &v);
if(FAILED(hres))
return hres;
@ -270,7 +270,7 @@ static HRESULT Math_ceil(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *
return S_OK;
}
static HRESULT Math_cos(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT Math_cos(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
VARIANT v;
@ -283,7 +283,7 @@ static HRESULT Math_cos(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *d
return S_OK;
}
hres = to_number(dispex->ctx, get_arg(dp, 0), ei, &v);
hres = to_number(ctx, get_arg(dp, 0), ei, &v);
if(FAILED(hres))
return hres;
@ -291,7 +291,7 @@ static HRESULT Math_cos(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *d
return S_OK;
}
static HRESULT Math_exp(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT Math_exp(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
VARIANT v;
@ -304,7 +304,7 @@ static HRESULT Math_exp(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *d
return S_OK;
}
hres = to_number(dispex->ctx, get_arg(dp, 0), ei, &v);
hres = to_number(ctx, get_arg(dp, 0), ei, &v);
if(FAILED(hres))
return hres;
@ -312,7 +312,7 @@ static HRESULT Math_exp(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *d
return S_OK;
}
static HRESULT Math_floor(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT Math_floor(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
VARIANT v;
@ -326,7 +326,7 @@ static HRESULT Math_floor(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS
return S_OK;
}
hres = to_number(dispex->ctx, get_arg(dp, 0), ei, &v);
hres = to_number(ctx, get_arg(dp, 0), ei, &v);
if(FAILED(hres))
return hres;
@ -335,7 +335,7 @@ static HRESULT Math_floor(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS
return S_OK;
}
static HRESULT Math_log(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT Math_log(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
VARIANT v;
@ -349,7 +349,7 @@ static HRESULT Math_log(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *d
return S_OK;
}
hres = to_number(dispex->ctx, get_arg(dp, 0), ei, &v);
hres = to_number(ctx, get_arg(dp, 0), ei, &v);
if(FAILED(hres))
return hres;
@ -359,7 +359,7 @@ static HRESULT Math_log(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *d
}
/* ECMA-262 3rd Edition 15.8.2.11 */
static HRESULT Math_max(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT Math_max(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
DOUBLE max, d;
@ -375,13 +375,13 @@ static HRESULT Math_max(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *d
return S_OK;
}
hres = to_number(dispex->ctx, get_arg(dp, 0), ei, &v);
hres = to_number(ctx, get_arg(dp, 0), ei, &v);
if(FAILED(hres))
return hres;
max = num_val(&v);
for(i=1; i < arg_cnt(dp); i++) {
hres = to_number(dispex->ctx, get_arg(dp, i), ei, &v);
hres = to_number(ctx, get_arg(dp, i), ei, &v);
if(FAILED(hres))
return hres;
@ -396,7 +396,7 @@ static HRESULT Math_max(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *d
}
/* ECMA-262 3rd Edition 15.8.2.12 */
static HRESULT Math_min(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT Math_min(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
DOUBLE min, d;
@ -412,13 +412,13 @@ static HRESULT Math_min(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *d
return S_OK;
}
hres = to_number(dispex->ctx, get_arg(dp, 0), ei, &v);
hres = to_number(ctx, get_arg(dp, 0), ei, &v);
if(FAILED(hres))
return hres;
min = num_val(&v);
for(i=1; i < arg_cnt(dp); i++) {
hres = to_number(dispex->ctx, get_arg(dp, i), ei, &v);
hres = to_number(ctx, get_arg(dp, i), ei, &v);
if(FAILED(hres))
return hres;
@ -433,7 +433,7 @@ static HRESULT Math_min(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *d
}
/* ECMA-262 3rd Edition 15.8.2.13 */
static HRESULT Math_pow(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT Math_pow(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
VARIANT x, y;
@ -446,11 +446,11 @@ static HRESULT Math_pow(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *d
return S_OK;
}
hres = to_number(dispex->ctx, get_arg(dp, 0), ei, &x);
hres = to_number(ctx, get_arg(dp, 0), ei, &x);
if(FAILED(hres))
return hres;
hres = to_number(dispex->ctx, get_arg(dp, 1), ei, &y);
hres = to_number(ctx, get_arg(dp, 1), ei, &y);
if(FAILED(hres))
return hres;
@ -460,7 +460,7 @@ static HRESULT Math_pow(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *d
}
/* ECMA-262 3rd Edition 15.8.2.14 */
static HRESULT Math_random(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT Math_random(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
UINT r;
@ -477,7 +477,7 @@ static HRESULT Math_random(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS
}
/* ECMA-262 3rd Edition 15.8.2.15 */
static HRESULT Math_round(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT Math_round(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
VARIANT v;
@ -490,7 +490,7 @@ static HRESULT Math_round(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS
return S_OK;
}
hres = to_number(dispex->ctx, get_arg(dp, 0), ei, &v);
hres = to_number(ctx, get_arg(dp, 0), ei, &v);
if(FAILED(hres))
return hres;
@ -499,7 +499,7 @@ static HRESULT Math_round(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS
return S_OK;
}
static HRESULT Math_sin(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT Math_sin(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
VARIANT v;
@ -512,7 +512,7 @@ static HRESULT Math_sin(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *d
return S_OK;
}
hres = to_number(dispex->ctx, get_arg(dp, 0), ei, &v);
hres = to_number(ctx, get_arg(dp, 0), ei, &v);
if(FAILED(hres))
return hres;
@ -520,7 +520,7 @@ static HRESULT Math_sin(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *d
return S_OK;
}
static HRESULT Math_sqrt(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT Math_sqrt(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
VARIANT v;
@ -533,7 +533,7 @@ static HRESULT Math_sqrt(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *
return S_OK;
}
hres = to_number(dispex->ctx, get_arg(dp, 0), ei, &v);
hres = to_number(ctx, get_arg(dp, 0), ei, &v);
if(FAILED(hres))
return hres;
@ -541,7 +541,7 @@ static HRESULT Math_sqrt(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *
return S_OK;
}
static HRESULT Math_tan(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT Math_tan(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
VARIANT v;
@ -554,7 +554,7 @@ static HRESULT Math_tan(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *d
return S_OK;
}
hres = to_number(dispex->ctx, get_arg(dp, 0), ei, &v);
hres = to_number(ctx, get_arg(dp, 0), ei, &v);
if(FAILED(hres))
return hres;

View file

@ -41,8 +41,19 @@ static const WCHAR toPrecisionW[] = {'t','o','P','r','e','c','i','s','i','o','n'
static const WCHAR valueOfW[] = {'v','a','l','u','e','O','f',0};
#define NUMBER_TOSTRING_BUF_SIZE 64
static inline NumberInstance *number_from_vdisp(vdisp_t *vdisp)
{
return (NumberInstance*)vdisp->u.jsdisp;
}
static inline NumberInstance *number_this(vdisp_t *jsthis)
{
return is_vclass(jsthis, JSCLASS_NUMBER) ? number_from_vdisp(jsthis) : NULL;
}
/* ECMA-262 3rd Edition 15.7.4.2 */
static HRESULT Number_toString(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT Number_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
NumberInstance *number;
@ -53,18 +64,16 @@ static HRESULT Number_toString(DispatchEx *dispex, LCID lcid, WORD flags, DISPPA
TRACE("\n");
if(!is_class(dispex, JSCLASS_NUMBER))
return throw_type_error(dispex->ctx, ei, IDS_NOT_NUM, NULL);
number = (NumberInstance*)dispex;
if(!(number = number_this(jsthis)))
return throw_type_error(ctx, ei, IDS_NOT_NUM, NULL);
if(arg_cnt(dp)) {
hres = to_int32(dispex->ctx, get_arg(dp, 0), ei, &radix);
hres = to_int32(ctx, get_arg(dp, 0), ei, &radix);
if(FAILED(hres))
return hres;
if(radix<2 || radix>36)
return throw_type_error(dispex->ctx, ei, IDS_INVALID_CALL_ARG, NULL);
return throw_type_error(ctx, ei, IDS_INVALID_CALL_ARG, NULL);
}
if(V_VT(&number->num) == VT_I4)
@ -73,7 +82,7 @@ static HRESULT Number_toString(DispatchEx *dispex, LCID lcid, WORD flags, DISPPA
val = V_R8(&number->num);
if(radix==10 || isnan(val) || isinf(val)) {
hres = to_string(dispex->ctx, &number->num, ei, &str);
hres = to_string(ctx, &number->num, ei, &str);
if(FAILED(hres))
return hres;
}
@ -170,57 +179,57 @@ static HRESULT Number_toString(DispatchEx *dispex, LCID lcid, WORD flags, DISPPA
return S_OK;
}
static HRESULT Number_toLocaleString(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT Number_toLocaleString(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 Number_toFixed(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT Number_toFixed(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 Number_toExponential(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT Number_toExponential(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 Number_toPrecision(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT Number_toPrecision(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 Number_valueOf(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT Number_valueOf(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
NumberInstance *number;
TRACE("\n");
if(!is_class(dispex, JSCLASS_NUMBER))
return throw_type_error(dispex->ctx, ei, IDS_NOT_NUM, NULL);
if(!(number = number_this(jsthis)))
return throw_type_error(ctx, ei, IDS_NOT_NUM, NULL);
if(retv) {
NumberInstance *number = (NumberInstance*)dispex;
if(retv)
*retv = number->num;
}
return S_OK;
}
static HRESULT Number_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT Number_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
NumberInstance *number = (NumberInstance*)dispex;
NumberInstance *number = number_from_vdisp(jsthis);
switch(flags) {
case INVOKE_FUNC:
return throw_type_error(dispex->ctx, ei, IDS_NOT_FUNC, NULL);
return throw_type_error(ctx, ei, IDS_NOT_FUNC, NULL);
case DISPATCH_PROPERTYGET:
*retv = number->num;
break;
@ -251,7 +260,7 @@ static const builtin_info_t Number_info = {
NULL
};
static HRESULT NumberConstr_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT NumberConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
VARIANT num;
@ -269,7 +278,7 @@ static HRESULT NumberConstr_value(DispatchEx *dispex, LCID lcid, WORD flags, DIS
return S_OK;
}
hres = to_number(dispex->ctx, get_arg(dp, 0), ei, &num);
hres = to_number(ctx, get_arg(dp, 0), ei, &num);
if(FAILED(hres))
return hres;
@ -281,7 +290,7 @@ static HRESULT NumberConstr_value(DispatchEx *dispex, LCID lcid, WORD flags, DIS
DispatchEx *obj;
if(arg_cnt(dp)) {
hres = to_number(dispex->ctx, get_arg(dp, 0), ei, &num);
hres = to_number(ctx, get_arg(dp, 0), ei, &num);
if(FAILED(hres))
return hres;
}else {
@ -289,7 +298,7 @@ static HRESULT NumberConstr_value(DispatchEx *dispex, LCID lcid, WORD flags, DIS
V_I4(&num) = 0;
}
hres = create_number(dispex->ctx, &num, &obj);
hres = create_number(ctx, &num, &obj);
if(FAILED(hres))
return hres;
@ -330,12 +339,14 @@ HRESULT create_number_constr(script_ctx_t *ctx, DispatchEx *object_prototype, Di
NumberInstance *number;
HRESULT hres;
static const WCHAR NumberW[] = {'N','u','m','b','e','r',0};
hres = alloc_number(ctx, object_prototype, &number);
if(FAILED(hres))
return hres;
V_VT(&number->num) = VT_I4;
hres = create_builtin_function(ctx, NumberConstr_value, NULL, PROPF_CONSTR, &number->dispex, ret);
hres = create_builtin_function(ctx, NumberConstr_value, NumberW, NULL, PROPF_CONSTR, &number->dispex, ret);
jsdisp_release(&number->dispex);
return hres;

View file

@ -32,9 +32,12 @@ static const WCHAR isPrototypeOfW[] = {'i','s','P','r','o','t','o','t','y','p','
static const WCHAR default_valueW[] = {'[','o','b','j','e','c','t',' ','O','b','j','e','c','t',']',0};
static HRESULT Object_toString(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT Object_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
DispatchEx *jsdisp;
const WCHAR *str;
static const WCHAR formatW[] = {'[','o','b','j','e','c','t',' ','%','s',']',0};
static const WCHAR arrayW[] = {'A','r','r','a','y',0};
@ -48,83 +51,92 @@ static HRESULT Object_toString(DispatchEx *dispex, LCID lcid, WORD flags, DISPPA
static const WCHAR regexpW[] = {'R','e','g','E','x','p',0};
static const WCHAR stringW[] = {'S','t','r','i','n','g',0};
/* Keep in sync with jsclass_t enum */
static const WCHAR *names[] = {NULL, arrayW, booleanW, dateW, errorW,
functionW, NULL, mathW, numberW, objectW, regexpW, stringW};
static const WCHAR *names[] = {objectW, arrayW, booleanW, dateW, errorW,
functionW, NULL, mathW, numberW, objectW, regexpW, stringW, objectW};
TRACE("\n");
if(names[dispex->builtin_info->class] == NULL) {
ERR("dispex->builtin_info->class = %d\n",
dispex->builtin_info->class);
jsdisp = get_jsdisp(jsthis);
if(!jsdisp) {
str = objectW;
}else if(names[jsdisp->builtin_info->class]) {
str = names[jsdisp->builtin_info->class];
}else {
FIXME("jdisp->builtin_info->class = %d\n", jsdisp->builtin_info->class);
return E_FAIL;
}
if(retv) {
V_VT(retv) = VT_BSTR;
V_BSTR(retv) = SysAllocStringLen(NULL, 9+strlenW(names[dispex->builtin_info->class]));
V_BSTR(retv) = SysAllocStringLen(NULL, 9+strlenW(str));
if(!V_BSTR(retv))
return E_OUTOFMEMORY;
sprintfW(V_BSTR(retv), formatW, names[dispex->builtin_info->class]);
sprintfW(V_BSTR(retv), formatW, str);
}
return S_OK;
}
static HRESULT Object_toLocaleString(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT Object_toLocaleString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
DISPPARAMS params = {NULL, NULL, 0, 0};
TRACE("\n");
return jsdisp_call_name(dispex, toStringW, lcid, DISPATCH_METHOD, &params, retv, ei, sp);
if(!is_jsdisp(jsthis)) {
FIXME("Host object this\n");
return E_FAIL;
}
return jsdisp_call_name(jsthis->u.jsdisp, toStringW, DISPATCH_METHOD, &params, retv, ei, sp);
}
static HRESULT Object_valueOf(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT Object_valueOf(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
TRACE("\n");
if(retv) {
IDispatchEx_AddRef(_IDispatchEx_(dispex));
IDispatch_AddRef(jsthis->u.disp);
V_VT(retv) = VT_DISPATCH;
V_DISPATCH(retv) = (IDispatch*)_IDispatchEx_(dispex);
V_DISPATCH(retv) = jsthis->u.disp;
}
return S_OK;
}
static HRESULT Object_hasOwnProperty(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT Object_hasOwnProperty(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 Object_propertyIsEnumerable(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT Object_propertyIsEnumerable(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 Object_isPrototypeOf(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT Object_isPrototypeOf(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 Object_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT Object_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
TRACE("\n");
switch(flags) {
case INVOKE_FUNC:
return throw_type_error(dispex->ctx, ei, IDS_NOT_FUNC, NULL);
return throw_type_error(ctx, ei, IDS_NOT_FUNC, NULL);
case DISPATCH_PROPERTYGET:
V_VT(retv) = VT_BSTR;
V_BSTR(retv) = SysAllocString(default_valueW);
@ -162,18 +174,39 @@ static const builtin_info_t Object_info = {
NULL
};
static HRESULT ObjectConstr_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
static HRESULT ObjectConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
{
HRESULT hres;
TRACE("\n");
switch(flags) {
case DISPATCH_METHOD:
if(arg_cnt(dp)) {
VARIANT *arg = get_arg(dp,0);
if(V_VT(arg) != VT_EMPTY && V_VT(arg) != VT_NULL) {
IDispatch *disp;
hres = to_object(ctx, arg, &disp);
if(FAILED(hres))
return hres;
if(retv) {
V_VT(retv) = VT_DISPATCH;
V_DISPATCH(retv) = disp;
}else {
IDispatch_Release(disp);
}
return S_OK;
}
}
/* fall through */
case DISPATCH_CONSTRUCT: {
DispatchEx *obj;
hres = create_object(dispex->ctx, NULL, &obj);
hres = create_object(ctx, NULL, &obj);
if(FAILED(hres))
return hres;
@ -192,7 +225,9 @@ static HRESULT ObjectConstr_value(DispatchEx *dispex, LCID lcid, WORD flags, DIS
HRESULT create_object_constr(script_ctx_t *ctx, DispatchEx *object_prototype, DispatchEx **ret)
{
return create_builtin_function(ctx, ObjectConstr_value, NULL, PROPF_CONSTR,
static const WCHAR ObjectW[] = {'O','b','j','e','c','t',0};
return create_builtin_function(ctx, ObjectConstr_value, ObjectW, NULL, PROPF_CONSTR,
object_prototype, ret);
}

File diff suppressed because it is too large Load diff

View file

@ -72,15 +72,16 @@
tINC = 288,
tDEC = 289,
tHTMLCOMMENT = 290,
kFUNCTION = 291,
tIdentifier = 292,
tAssignOper = 293,
tEqOper = 294,
tShiftOper = 295,
tRelOper = 296,
tNumericLiteral = 297,
tStringLiteral = 298,
LOWER_THAN_ELSE = 299
kDIVEQ = 291,
kFUNCTION = 292,
tIdentifier = 293,
tAssignOper = 294,
tEqOper = 295,
tShiftOper = 296,
tRelOper = 297,
tNumericLiteral = 298,
tStringLiteral = 299,
LOWER_THAN_ELSE = 300
};
#endif
@ -115,7 +116,7 @@ typedef union YYSTYPE
/* Line 1676 of yacc.c */
#line 119 "parser.tab.h"
#line 120 "parser.tab.h"
} YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define yystype YYSTYPE /* obsolescent; will be withdrawn */

View file

@ -172,7 +172,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 tANDAND tOROR tINC tDEC tHTMLCOMMENT
%token tANDAND tOROR tINC tDEC tHTMLCOMMENT kDIVEQ
%token <srcptr> kFUNCTION '}'
@ -245,6 +245,7 @@ static source_elements_t *source_elements_add_statement(source_elements_t*,state
%type <literal> PropertyName
%type <literal> BooleanLiteral
%type <srcptr> KFunction
%type <ival> AssignOper
%nonassoc LOWER_THAN_ELSE
%nonassoc kELSE
@ -294,6 +295,7 @@ Statement
: Block { $$ = $1; }
| VariableStatement { $$ = $1; }
| EmptyStatement { $$ = $1; }
| FunctionExpression { $$ = new_empty_statement(ctx); } /* FIXME: return NULL */
| ExpressionStatement { $$ = $1; }
| IfStatement { $$ = $1; }
| IterationStatement { $$ = $1; }
@ -515,12 +517,16 @@ ExpressionNoIn
| ExpressionNoIn ',' AssignmentExpressionNoIn
{ $$ = new_binary_expression(ctx, EXPR_COMMA, $1, $3); }
AssignOper
: tAssignOper { $$ = $1; }
| kDIVEQ { $$ = EXPR_ASSIGNDIV; }
/* ECMA-262 3rd Edition 11.13 */
AssignmentExpression
: ConditionalExpression { $$ = $1; }
| LeftHandSideExpression '=' AssignmentExpression
{ $$ = new_binary_expression(ctx, EXPR_ASSIGN, $1, $3); }
| LeftHandSideExpression tAssignOper AssignmentExpression
| LeftHandSideExpression AssignOper AssignmentExpression
{ $$ = new_binary_expression(ctx, $2, $1, $3); }
/* ECMA-262 3rd Edition 11.13 */
@ -529,7 +535,7 @@ AssignmentExpressionNoIn
{ $$ = $1; }
| LeftHandSideExpression '=' AssignmentExpressionNoIn
{ $$ = new_binary_expression(ctx, EXPR_ASSIGN, $1, $3); }
| LeftHandSideExpression tAssignOper AssignmentExpressionNoIn
| LeftHandSideExpression AssignOper AssignmentExpressionNoIn
{ $$ = new_binary_expression(ctx, $2, $1, $3); }
/* ECMA-262 3rd Edition 11.12 */
@ -800,11 +806,13 @@ Literal
| tStringLiteral { $$ = new_string_literal(ctx, $1); }
| '/' { $$ = parse_regexp(ctx);
if(!$$) YYABORT; }
| kDIVEQ { $$ = parse_regexp(ctx);
if(!$$) YYABORT; }
/* ECMA-262 3rd Edition 7.8.2 */
BooleanLiteral
: kTRUE { $$ = new_boolean_literal(ctx, TRUE); }
| kFALSE { $$ = new_boolean_literal(ctx, FALSE); }
: kTRUE { $$ = new_boolean_literal(ctx, VARIANT_TRUE); }
| kFALSE { $$ = new_boolean_literal(ctx, VARIANT_FALSE); }
semicolon_opt
: ';'

View file

@ -82,6 +82,7 @@ typedef struct {
JSRegExp *jsregexp;
BSTR str;
DWORD last_index;
} RegExpInstance;
static const WCHAR sourceW[] = {'s','o','u','r','c','e',0};
@ -3293,7 +3294,12 @@ out:
return re;
}
static HRESULT do_regexp_match_next(RegExpInstance *regexp, const WCHAR *str, DWORD len,
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)
{
REMatchState *x, *result;
@ -3304,7 +3310,7 @@ static HRESULT do_regexp_match_next(RegExpInstance *regexp, const WCHAR *str, DW
gData.cpend = str + len;
gData.start = *cp-str;
gData.skipped = 0;
gData.pool = &regexp->dispex.ctx->tmp_heap;
gData.pool = &ctx->tmp_heap;
x = InitMatch(NULL, &gData, regexp->jsregexp, gData.cpend - gData.cpbegin);
if(!x) {
@ -3354,7 +3360,7 @@ static HRESULT do_regexp_match_next(RegExpInstance *regexp, const WCHAR *str, DW
return S_OK;
}
HRESULT regexp_match_next(DispatchEx *dispex, BOOL gcheck, const WCHAR *str, DWORD len,
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)
{
RegExpInstance *regexp = (RegExpInstance*)dispex;
@ -3364,16 +3370,16 @@ HRESULT regexp_match_next(DispatchEx *dispex, BOOL gcheck, const WCHAR *str, DWO
if(gcheck && !(regexp->jsregexp->flags & JSREG_GLOB))
return S_FALSE;
mark = jsheap_mark(&regexp->dispex.ctx->tmp_heap);
mark = jsheap_mark(&ctx->tmp_heap);
hres = do_regexp_match_next(regexp, str, len, cp, parens, parens_size, parens_cnt, ret);
hres = do_regexp_match_next(ctx, regexp, str, len, cp, parens, parens_size, parens_cnt, ret);
jsheap_clear(mark);
return hres;
}
HRESULT regexp_match(DispatchEx *dispex, const WCHAR *str, DWORD len, BOOL gflag, match_result_t **match_result,
DWORD *result_cnt)
HRESULT regexp_match(script_ctx_t *ctx, DispatchEx *dispex, const WCHAR *str, DWORD len, BOOL gflag,
match_result_t **match_result, DWORD *result_cnt)
{
RegExpInstance *This = (RegExpInstance*)dispex;
match_result_t *ret = NULL, cres;
@ -3382,10 +3388,10 @@ HRESULT regexp_match(DispatchEx *dispex, const WCHAR *str, DWORD len, BOOL gflag
jsheap_t *mark;
HRESULT hres;
mark = jsheap_mark(&This->dispex.ctx->tmp_heap);
mark = jsheap_mark(&ctx->tmp_heap);
while(1) {
hres = do_regexp_match_next(This, str, len, &cp, NULL, NULL, NULL, &cres);
hres = do_regexp_match_next(ctx, This, str, len, &cp, NULL, NULL, NULL, &cres);
if(hres == S_FALSE) {
hres = S_OK;
break;
@ -3424,14 +3430,14 @@ HRESULT regexp_match(DispatchEx *dispex, const WCHAR *str, DWORD len, BOOL gflag
return S_OK;
}
static HRESULT RegExp_source(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT RegExp_source(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
TRACE("\n");
switch(flags) {
case DISPATCH_PROPERTYGET: {
RegExpInstance *This = (RegExpInstance*)dispex;
RegExpInstance *This = regexp_from_vdisp(jsthis);
V_VT(retv) = VT_BSTR;
V_BSTR(retv) = SysAllocString(This->str);
@ -3447,63 +3453,229 @@ static HRESULT RegExp_source(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARA
return S_OK;
}
static HRESULT RegExp_global(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT RegExp_global(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 RegExp_ignoreCase(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT RegExp_ignoreCase(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 RegExp_multiline(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT RegExp_multiline(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 RegExp_lastIndex(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT RegExp_lastIndex(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
TRACE("\n");
switch(flags) {
case DISPATCH_PROPERTYGET: {
RegExpInstance *regexp = regexp_from_vdisp(jsthis);
V_VT(retv) = VT_I4;
V_I4(retv) = regexp->last_index;
break;
}
default:
FIXME("unimplemented flags: %x\n", flags);
return E_NOTIMPL;
}
return S_OK;
}
static HRESULT RegExp_toString(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 RegExp_toString(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
static HRESULT create_match_array(script_ctx_t *ctx, BSTR input, const match_result_t *result,
const match_result_t *parens, DWORD parens_cnt, jsexcept_t *ei, IDispatch **ret)
{
FIXME("\n");
return E_NOTIMPL;
DispatchEx *array;
VARIANT var;
int i;
HRESULT hres = S_OK;
static const WCHAR indexW[] = {'i','n','d','e','x',0};
static const WCHAR inputW[] = {'i','n','p','u','t',0};
static const WCHAR zeroW[] = {'0',0};
hres = create_array(ctx, parens_cnt+1, &array);
if(FAILED(hres))
return hres;
for(i=0; i < parens_cnt; i++) {
V_VT(&var) = VT_BSTR;
V_BSTR(&var) = SysAllocStringLen(parens[i].str, parens[i].len);
if(!V_BSTR(&var)) {
hres = E_OUTOFMEMORY;
break;
}
hres = jsdisp_propput_idx(array, i+1, &var, ei, NULL/*FIXME*/);
SysFreeString(V_BSTR(&var));
if(FAILED(hres))
break;
}
while(SUCCEEDED(hres)) {
V_VT(&var) = VT_I4;
V_I4(&var) = result->str-input;
hres = jsdisp_propput_name(array, indexW, &var, ei, NULL/*FIXME*/);
if(FAILED(hres))
break;
V_VT(&var) = VT_BSTR;
V_BSTR(&var) = input;
hres = jsdisp_propput_name(array, inputW, &var, ei, NULL/*FIXME*/);
if(FAILED(hres))
break;
V_BSTR(&var) = SysAllocStringLen(result->str, result->len);
if(!V_BSTR(&var)) {
hres = E_OUTOFMEMORY;
break;
}
hres = jsdisp_propput_name(array, zeroW, &var, ei, NULL/*FIXME*/);
SysFreeString(V_BSTR(&var));
break;
}
if(FAILED(hres)) {
jsdisp_release(array);
return hres;
}
*ret = (IDispatch*)_IDispatchEx_(array);
return S_OK;
}
static HRESULT RegExp_exec(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
static HRESULT run_exec(script_ctx_t *ctx, vdisp_t *jsthis, VARIANT *arg, jsexcept_t *ei, BSTR *input,
match_result_t *match, match_result_t **parens, DWORD *parens_cnt, VARIANT_BOOL *ret)
{
FIXME("\n");
return E_NOTIMPL;
RegExpInstance *regexp;
DWORD parens_size = 0, last_index = 0, length;
const WCHAR *cp;
BSTR string;
HRESULT hres;
if(!is_vclass(jsthis, JSCLASS_REGEXP)) {
FIXME("Not a RegExp\n");
return E_NOTIMPL;
}
regexp = regexp_from_vdisp(jsthis);
if(arg) {
hres = to_string(ctx, arg, ei, &string);
if(FAILED(hres))
return hres;
}else {
string = SysAllocStringLen(NULL, 0);
if(!string)
return E_OUTOFMEMORY;
}
length = SysStringLen(string);
if(regexp->jsregexp->flags & JSREG_GLOB)
last_index = regexp->last_index;
cp = string + last_index;
hres = regexp_match_next(ctx, &regexp->dispex, FALSE, 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)
*input = string;
return S_OK;
}
static HRESULT RegExp_test(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT RegExp_exec(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
FIXME("\n");
return E_NOTIMPL;
match_result_t *parens = NULL, match;
DWORD parens_cnt = 0;
VARIANT_BOOL b;
BSTR string;
HRESULT hres;
TRACE("\n");
hres = run_exec(ctx, jsthis, arg_cnt(dp) ? get_arg(dp,0) : NULL, ei, &string, &match, &parens, &parens_cnt, &b);
if(FAILED(hres))
return hres;
if(retv) {
if(b) {
IDispatch *ret;
hres = create_match_array(ctx, string, &match, parens, parens_cnt, ei, &ret);
if(SUCCEEDED(hres)) {
V_VT(retv) = VT_DISPATCH;
V_DISPATCH(retv) = ret;
}
}else {
V_VT(retv) = VT_NULL;
}
}
heap_free(parens);
SysFreeString(string);
return hres;
}
static HRESULT RegExp_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT RegExp_test(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
match_result_t match;
VARIANT_BOOL b;
HRESULT hres;
TRACE("\n");
hres = run_exec(ctx, jsthis, arg_cnt(dp) ? get_arg(dp,0) : NULL, ei, NULL, &match, NULL, NULL, &b);
if(FAILED(hres))
return hres;
if(retv) {
V_VT(retv) = VT_BOOL;
V_BOOL(retv) = b;
}
return S_OK;
}
static HRESULT RegExp_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
TRACE("\n");
switch(flags) {
case INVOKE_FUNC:
return throw_type_error(dispex->ctx, ei, IDS_NOT_FUNC, NULL);
return throw_type_error(ctx, ei, IDS_NOT_FUNC, NULL);
default:
FIXME("unimplemented flags %x\n", flags);
return E_NOTIMPL;
@ -3652,19 +3824,48 @@ static HRESULT regexp_constructor(script_ctx_t *ctx, DISPPARAMS *dp, VARIANT *re
if(FAILED(hres))
return hres;
V_VT(retv) = VT_DISPATCH;
V_DISPATCH(retv) = (IDispatch*)_IDispatchEx_(ret);
if(retv) {
V_VT(retv) = VT_DISPATCH;
V_DISPATCH(retv) = (IDispatch*)_IDispatchEx_(ret);
}else {
jsdisp_release(ret);
}
return S_OK;
}
static HRESULT RegExpConstr_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
static HRESULT RegExpConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
TRACE("\n");
switch(flags) {
case DISPATCH_METHOD:
if(arg_cnt(dp)) {
VARIANT *arg = get_arg(dp,0);
if(V_VT(arg) == VT_DISPATCH) {
DispatchEx *jsdisp = iface_to_jsdisp((IUnknown*)V_DISPATCH(arg));
if(jsdisp) {
if(is_class(jsdisp, JSCLASS_REGEXP)) {
if(arg_cnt(dp) > 1 && V_VT(get_arg(dp,1)) != VT_EMPTY) {
jsdisp_release(jsdisp);
return throw_regexp_error(ctx, ei, IDS_REGEXP_SYNTAX_ERROR, NULL);
}
if(retv) {
V_VT(retv) = VT_DISPATCH;
V_DISPATCH(retv) = (IDispatch*)_IDispatchEx_(jsdisp);
}else {
jsdisp_release(jsdisp);
}
return S_OK;
}
jsdisp_release(jsdisp);
}
}
}
/* fall through */
case DISPATCH_CONSTRUCT:
return regexp_constructor(dispex->ctx, dp, retv);
return regexp_constructor(ctx, dp, retv);
default:
FIXME("unimplemented flags: %x\n", flags);
return E_NOTIMPL;
@ -3678,11 +3879,13 @@ HRESULT create_regexp_constr(script_ctx_t *ctx, DispatchEx *object_prototype, Di
RegExpInstance *regexp;
HRESULT hres;
static const WCHAR RegExpW[] = {'R','e','g','E','x','p',0};
hres = alloc_regexp(ctx, object_prototype, &regexp);
if(FAILED(hres))
return hres;
hres = create_builtin_function(ctx, RegExpConstr_value, NULL, PROPF_CONSTR, &regexp->dispex, ret);
hres = create_builtin_function(ctx, RegExpConstr_value, RegExpW, NULL, PROPF_CONSTR, &regexp->dispex, ret);
jsdisp_release(&regexp->dispex);
return hres;

View file

@ -20,6 +20,7 @@
#define IDS_TO_PRIMITIVE 0x0001
#define IDS_INVALID_CALL_ARG 0x0005
#define IDS_CREATE_OBJ_ERROR 0x01AD
#define IDS_NO_PROPERTY 0x01B6
#define IDS_ARG_NOT_OPT 0x01c1
#define IDS_SYNTAX_ERROR 0x03EA
@ -30,7 +31,11 @@
#define IDS_NOT_FUNC 0x138A
#define IDS_NOT_DATE 0x138E
#define IDS_NOT_NUM 0x1389
#define IDS_OBJECT_EXPECTED 0x138F
#define IDS_ILLEGAL_ASSIGN 0x1390
#define IDS_UNDEFINED 0x1391
#define IDS_NOT_BOOL 0x1392
#define IDS_JSCRIPT_EXPECTED 0x1396
#define IDS_REGEXP_SYNTAX_ERROR 0x1399
#define IDS_INVALID_LENGTH 0x13A5
#define IDS_ARRAY_EXPECTED 0x13A7

File diff suppressed because it is too large Load diff

View file

@ -22,6 +22,7 @@ import "activscp.idl";
interface IDebugDocumentContext;
interface IRemoteDebugApplication;
interface IEnumDebugCodeContexts;
/* FIXME: */
interface IEnumDebugStackFrames;
@ -79,6 +80,88 @@ typedef enum tagERRORRESUMEACTION {
ERRORRESUMEACTION_SkipErrorStatement,
} ERRORRESUMEACTION;
typedef WORD SOURCE_TEXT_ATTR;
#ifdef INTEROPLIB
enum enum_SOURCE_TEXT_ATTR
{
SOURCETEXT_ATTR_KEYWORD = 0x01,
SOURCETEXT_ATTR_COMMENT = 0x02,
SOURCETEXT_ATTR_NONSOURCE = 0x04,
SOURCETEXT_ATTR_OPERATOR = 0x08,
SOURCETEXT_ATTR_NUMBER = 0x10,
SOURCETEXT_ATTR_STRING = 0x20,
SOURCETEXT_ATTR_FUNCTION_START = 0x40
};
#endif
const SOURCE_TEXT_ATTR SOURCETEXT_ATTR_KEYWORD = 0x01;
const SOURCE_TEXT_ATTR SOURCETEXT_ATTR_COMMENT = 0x02;
const SOURCE_TEXT_ATTR SOURCETEXT_ATTR_NONSOURCE = 0x04;
const SOURCE_TEXT_ATTR SOURCETEXT_ATTR_OPERATOR = 0x08;
const SOURCE_TEXT_ATTR SOURCETEXT_ATTR_NUMBER = 0x10;
const SOURCE_TEXT_ATTR SOURCETEXT_ATTR_STRING = 0x20;
const SOURCE_TEXT_ATTR SOURCETEXT_ATTR_FUNCTION_START = 0x40;
/************************************************************
* interface IActiveScriptDebug32
*/
[
object,
uuid(51973c10-cb0c-11d0-b5c9-00a0244a0e7a),
pointer_default(unique)
]
interface IActiveScriptDebug32 : IUnknown
{
HRESULT GetScriptTextAttributes(
[in, size_is(uNumCodeChars)] LPCOLESTR pstrCode,
[in] ULONG uNumCodeChars,
[in] LPCOLESTR pstrDelimiter,
[in] DWORD dwFlags,
[in, out, size_is(uNumCodeChars)] SOURCE_TEXT_ATTR *pattr);
HRESULT GetScriptletTextAttributes(
[in, size_is(uNumCodeChars)] LPCOLESTR pstrCode,
[in] ULONG uNumCodeChars,
[in] LPCOLESTR pstrDelimiter,
[in] DWORD dwFlags,
[in, out, size_is(uNumCodeChars)] SOURCE_TEXT_ATTR *pattr);
HRESULT EnumCodeContextsOfPosition(
[in] DWORD dwSourceContext,
[in] ULONG uCharacterOffset,
[in] ULONG uNumChars,
[out] IEnumDebugCodeContexts **ppescc);
}
[
object,
uuid(bc437e23-f5b8-47f4-bb79-7d1ce5483b86),
pointer_default(unique)
]
interface IActiveScriptDebug64 : IUnknown
{
HRESULT GetScriptTextAttributes(
[in, size_is(uNumCodeChars)] LPCOLESTR pstrCode,
[in] ULONG uNumCodeChars,
[in] LPCOLESTR pstrDelimiter,
[in] DWORD dwFlags,
[in, out, size_is(uNumCodeChars)] SOURCE_TEXT_ATTR *pattr);
HRESULT GetScriptletTextAttributes(
[in, size_is(uNumCodeChars)] LPCOLESTR pstrCode,
[in] ULONG uNumCodeChars,
[in] LPCOLESTR pstrDelimiter,
[in] DWORD dwFlags,
[in, out, size_is(uNumCodeChars)] SOURCE_TEXT_ATTR *pattr);
HRESULT EnumCodeContextsOfPosition(
[in] DWORDLONG dwSourceContext,
[in] ULONG uCharacterOffset,
[in] ULONG uNumChars,
[out] IEnumDebugCodeContexts **ppescc);
}
/************************************************************
* interface IDebugDocumentInfo
*/
@ -473,6 +556,9 @@ interface IActiveScriptSiteDebug64 : IUnknown
cpp_quote("#ifndef DISABLE_ACTIVDBG_INTERFACE_WRAPPERS")
cpp_quote("#ifdef _WIN64")
cpp_quote("#define IActiveScriptDebug IActiveScriptDebug64")
cpp_quote("#define IID_IActiveScriptDebug IID_IActiveScriptDebug64")
cpp_quote("#define IActiveScriptSiteDebug IActiveScriptSiteDebug64")
cpp_quote("#define IID_IActiveScriptSiteDebug IID_IActiveScriptSiteDebug64")
@ -481,6 +567,9 @@ cpp_quote("#define IID_IDebugApplication IID_IDebugApplication64")
cpp_quote("#else")
cpp_quote("#define IActiveScriptDebug IActiveScriptDebug32")
cpp_quote("#define IID_IActiveScriptDebug IID_IActiveScriptDebug32")
cpp_quote("#define IActiveScriptSiteDebug IActiveScriptSiteDebug32")
cpp_quote("#define IID_IActiveScriptSiteDebug IID_IActiveScriptSiteDebug32")

View file

@ -310,6 +310,45 @@ interface IBindStatusCallback : IUnknown
[in, iid_is(riid)] IUnknown* punk);
}
/*****************************************************************************
* IBindStatusCallbackEx interface
*/
[
object,
uuid(aaa74ef9-8ee7-4659-88d9-f8c504da73cc),
pointer_default(unique)
]
interface IBindStatusCallbackEx : IBindStatusCallback
{
typedef [unique] IBindStatusCallbackEx *LPBINDSTATUSCALLBACKEX;
typedef enum {
BINDF2_DISABLEBASICOVERHTTP = 0x00000001,
BINDF2_DISABLEAUTOCOOKIEHANDLING = 0x00000002,
BINDF2_READ_DATA_GREATER_THAN_4GB = 0x00000004,
BINDF2_DISABLE_HTTP_REDIRECT_XSECURITYID = 0x00000008,
BINDF2_RESERVED_3 = 0x20000000,
BINDF2_RESERVED_2 = 0x40000000,
BINDF2_RESERVED_1 = 0x80000000,
} BINDF2;
[local]
HRESULT GetBindInfoEx(
[out] DWORD *grfBINDF,
[in, out, unique] BINDINFO *pbindinfo,
[out] DWORD *grfBINDF2,
[out] DWORD *pdwReserved);
[call_as(GetBindInfoEx)]
HRESULT RemoteGetBindInfoEx(
[out] DWORD *grfBINDF,
[in, out, unique] RemBINDINFO *pbindinfo,
[in, out, unique] RemSTGMEDIUM *pstgmed,
[out] DWORD *grfBINDF2,
[out] DWORD *pdwReserved);
}
/*****************************************************************************
* IAuthenticate interface
*/
@ -1026,6 +1065,42 @@ cpp_quote("#define MAX_SIZE_SECURITY_ID 512")
[in] DWORD dwFlags);
}
/*****************************************************************************
* IInternetHostSecurityManager interface
*/
cpp_quote("#define SID_SInternetHostSecurityManager IID_IInternetHostSecurityManager")
[
local,
object,
uuid(3af280b6-cb3f-11d0-891e-00c04fb6bfc4),
pointer_default(unique)
]
interface IInternetHostSecurityManager : IUnknown
{
HRESULT GetSecurityId(
[out, size_is(*pcbSecurityId)] BYTE *pbSecurityId,
[in, out] DWORD *pcbSecurityId,
[in] DWORD_PTR dwReserved);
HRESULT ProcessUrlAction(
[in] DWORD dwAction,
[out, size_is(cbPolicy)] BYTE *pPolicy,
[in] DWORD cbPolicy,
[in] BYTE *pContext,
[in] DWORD cbContext,
[in] DWORD dwFlags,
[in] DWORD dwReserved);
HRESULT QueryCustomPolicy(
[in] REFGUID guidKey,
[out, size_is(,*pcbPolicy)] BYTE **ppPolicy,
[out] DWORD *pcbPolicy,
[in] BYTE *pContext,
[in] DWORD cbContext,
[in] DWORD dwReserved);
}
cpp_quote("#define URLACTION_MIN 0x00001000")
cpp_quote("#define URLACTION_DOWNLOAD_MIN 0x00001000")
cpp_quote("#define URLACTION_DOWNLOAD_SIGNED_ACTIVEX 0x00001001")
@ -1171,20 +1246,26 @@ interface IInternetZoneManager : IUnknown
URLTEMPLATE_CUSTOM = 0x00000,
URLTEMPLATE_PREDEFINED_MIN = 0x10000,
URLTEMPLATE_LOW = 0x10000,
URLTEMPLATE_MEDLOW = 0x10500,
URLTEMPLATE_MEDIUM = 0x11000,
URLTEMPLATE_MEDHIGH = 0x11500,
URLTEMPLATE_HIGH = 0x12000,
URLTEMPLATE_PREDEFINED_MAX = 0x20000,
} URLTEMPLATE ;
typedef enum {
ZAFLAGS_CUSTOM_EDIT = 0x00000001,
ZAFLAGS_ADD_SITES = 0x00000002,
ZAFLAGS_REQUIRE_VERIFICATION = 0x00000004,
ZAFLAGS_INCLUDE_PROXY_OVERRIDE = 0x00000008,
ZAFLAGS_INCLUDE_INTRANET_SITES = 0x00000010,
ZAFLAGS_NO_UI = 0x00000020,
ZAFLAGS_SUPPORTS_VERIFICATION = 0x00000040,
ZAFLAGS_UNC_AS_INTRANET = 0x00000080,
ZAFLAGS_CUSTOM_EDIT = 0x00000001,
ZAFLAGS_ADD_SITES = 0x00000002,
ZAFLAGS_REQUIRE_VERIFICATION = 0x00000004,
ZAFLAGS_INCLUDE_PROXY_OVERRIDE = 0x00000008,
ZAFLAGS_INCLUDE_INTRANET_SITES = 0x00000010,
ZAFLAGS_NO_UI = 0x00000020,
ZAFLAGS_SUPPORTS_VERIFICATION = 0x00000040,
ZAFLAGS_UNC_AS_INTRANET = 0x00000080,
ZAFLAGS_DETECT_INTRANET = 0x00000100,
ZAFLAGS_USE_LOCKED_ZONES = 0x00010000,
ZAFLAGS_VERIFY_TEMPLATE_SETTINGS = 0x00020000,
ZAFLAGS_NO_CACHE = 0x00040000,
} ZAFLAGS ;
enum {
@ -1277,6 +1358,72 @@ interface IInternetZoneManager : IUnknown
[in] DWORD dwReserved);
}
/*****************************************************************************
* IInternetZoneManagerEx interface
*/
[
local,
object,
uuid(A4C23339-8E06-431E-9BF4-7E711C085648),
pointer_default(unique)
]
interface IInternetZoneManagerEx : IInternetZoneManager
{
HRESULT GetZoneActionPolicyEx(
[in] DWORD dwZone,
[in] DWORD dwAction,
[out] BYTE* pPolicy,
[in] DWORD cbPolicy,
[in] URLZONEREG urlZoneReg,
[in] DWORD dwFlags);
HRESULT SetZoneActionPolicyEx(
[in] DWORD dwZone,
[in] DWORD dwAction,
[in] BYTE* pPolicy,
[in] DWORD cbPolicy,
[in] URLZONEREG urlZoneReg,
[in] DWORD dwFlags);
}
/*****************************************************************************
* IInternetZoneManagerEx2 interface
*/
cpp_quote("#define SECURITY_IE_STATE_GREEN 0")
cpp_quote("#define SECURITY_IE_STATE_RED 1")
[
local,
object,
uuid(EDC17559-DD5D-4846-8EEF-8BECBA5A4ABF),
pointer_default(unique)
]
interface IInternetZoneManagerEx2 : IInternetZoneManagerEx
{
HRESULT GetZoneAttributesEx(
[in] DWORD dwZone,
[in, out, unique] ZONEATTRIBUTES* pZoneAttributes,
[in] DWORD dwFlags);
HRESULT GetZoneSecurityState(
[in] DWORD dwZoneIndex,
[in] BOOL fRespectPolicy,
[in, out] LPDWORD pdwState,
[in, out] BOOL *pfPolicyEncountered);
HRESULT GetIESecurityState(
[in] BOOL fRespectPolicy,
[in, out] LPDWORD pdwState,
[in, out] BOOL *pfPolicyEncountered,
[in] BOOL fNoCache);
HRESULT FixInsecureSettings(void);
}
typedef struct _tagSOFTDISTINFO
{
ULONG cbSize;
@ -1532,6 +1679,17 @@ interface IInternetProtocolEx : IInternetProtocol
[in] HANDLE *dwReserved);
}
cpp_quote("#define CONFIRMSAFETYACTION_LOADOBJECT 0x00000001")
struct CONFIRMSAFETY
{
CLSID clsid;
IUnknown *pUnk;
DWORD dwFlags;
};
cpp_quote("EXTERN_C const GUID GUID_CUSTOM_CONFIRMOBJECTSAFETY;")
cpp_quote("DEFINE_GUID(CLSID_InternetSecurityManager, 0x7b8a2d94, 0x0ac9, 0x11d1, 0x89, 0x6c, 0x00, 0xc0, 0x4f, 0xB6, 0xbf, 0xc4);")
cpp_quote("DEFINE_GUID(CLSID_InternetZoneManager, 0x7B8A2D95, 0x0AC9, 0x11D1, 0x89, 0x6C, 0x00, 0xC0, 0x4F, 0xB6, 0xBF, 0xC4);")
cpp_quote("DEFINE_GUID(IID_IAsyncMoniker, 0x79EAC9D3, 0xBAF9, 0x11CE, 0x8C, 0x82, 0x00, 0xAA, 0x00, 0x4B, 0xA9, 0x0B);")