jscript: Added Object constructor object implementation.

oldstable
Jacek Caban 2008-09-10 02:33:15 +02:00 committed by Alexandre Julliard
parent 68f63689cb
commit dd01f8b8f7
7 changed files with 226 additions and 22 deletions

View File

@ -15,7 +15,8 @@ C_SRCS = \
jscript.c \
jscript_main.c \
jsutils.c \
lex.c
lex.c \
object.c
IDL_TLB_SRCS = jsglobal.idl

View File

@ -715,8 +715,6 @@ HRESULT jsdisp_set_prototype(DispatchEx *dispex, DispatchEx *prototype)
HRESULT init_dispex(DispatchEx *dispex, script_ctx_t *ctx, const builtin_info_t *builtin_info, DispatchEx *prototype)
{
static const WCHAR prototypeW[] = {'p','r','o','t','o','t','y','p','e',0};
TRACE("%p (%p)\n", dispex, prototype);
dispex->lpIDispatchExVtbl = &DispatchExVtbl;
@ -731,7 +729,7 @@ HRESULT init_dispex(DispatchEx *dispex, script_ctx_t *ctx, const builtin_info_t
if(prototype)
IDispatchEx_AddRef(_IDispatchEx_(prototype));
dispex->prop_cnt = 2;
dispex->prop_cnt = 1;
dispex->props[0].name = NULL;
dispex->props[0].flags = 0;
if(builtin_info->value_prop.invoke) {
@ -741,20 +739,6 @@ HRESULT init_dispex(DispatchEx *dispex, script_ctx_t *ctx, const builtin_info_t
dispex->props[0].type = PROP_DELETED;
}
dispex->props[1].type = PROP_DELETED;
dispex->props[1].name = SysAllocString(prototypeW);
dispex->props[1].flags = 0;
if(prototype) {
HRESULT hres;
hres = jsdisp_set_prototype(dispex, prototype);
if(FAILED(hres)) {
IDispatchEx_Release(_IDispatchEx_(dispex));
return hres;
}
}
script_addref(ctx);
dispex->ctx = ctx;
@ -786,6 +770,39 @@ HRESULT create_dispex(script_ctx_t *ctx, const builtin_info_t *builtin_info, Dis
return S_OK;
}
HRESULT init_dispex_from_constr(DispatchEx *dispex, script_ctx_t *ctx, const builtin_info_t *builtin_info, DispatchEx *constr)
{
DispatchEx *prot = NULL;
dispex_prop_t *prop;
HRESULT hres;
static const WCHAR prototypeW[] = {'p','r','o','t','o','t','y','p','e',0};
hres = find_prop_name_prot(constr, prototypeW, FALSE, &prop);
if(SUCCEEDED(hres) && prop) {
jsexcept_t jsexcept;
VARIANT var;
V_VT(&var) = VT_EMPTY;
memset(&jsexcept, 0, sizeof(jsexcept));
hres = prop_get(constr, prop, ctx->lcid, NULL, &var, &jsexcept, NULL/*FIXME*/);
if(FAILED(hres)) {
ERR("Could not get prototype\n");
return hres;
}
if(V_VT(&var) == VT_DISPATCH)
prot = iface_to_jsdisp((IUnknown*)V_DISPATCH(&var));
VariantClear(&var);
}
hres = init_dispex(dispex, ctx, builtin_info, prot);
if(prot)
IDispatchEx_Release(_IDispatchEx_(prot));
return hres;
}
DispatchEx *iface_to_jsdisp(IUnknown *iface)
{
DispatchEx *ret;
@ -798,6 +815,12 @@ DispatchEx *iface_to_jsdisp(IUnknown *iface)
return ret;
}
HRESULT jsdisp_call_value(DispatchEx *disp, LCID lcid, 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);
}
HRESULT jsdisp_call(DispatchEx *disp, DISPID id, LCID lcid, WORD flags, DISPPARAMS *dp, VARIANT *retv,
jsexcept_t *ei, IServiceProvider *caller)
{

View File

@ -34,6 +34,8 @@ typedef struct {
DWORD length;
} FunctionInstance;
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};
static const WCHAR toStringW[] = {'t','o','S','t','r','i','n','g',0};
static const WCHAR toLocaleStringW[] = {'t','o','L','o','c','a','l','e','S','t','r','i','n','g',0};
@ -176,7 +178,14 @@ static HRESULT create_function(script_ctx_t *ctx, DWORD flags, DispatchEx *proto
function->length = flags & PROPF_ARGMASK;
if(prototype) {
hres = jsdisp_set_prototype(&function->dispex, prototype);
jsexcept_t jsexcept;
VARIANT var;
V_VT(&var) = VT_DISPATCH;
V_DISPATCH(&var) = (IDispatch*)_IDispatchEx_(prototype);
memset(&jsexcept, 0, sizeof(jsexcept));
hres = jsdisp_propput_name(&function->dispex, prototypeW, ctx->lcid, &var, &jsexcept, NULL/*FIXME*/);
if(FAILED(hres)) {
IDispatchEx_Release(_IDispatchEx_(&function->dispex));
return hres;

View File

@ -53,6 +53,18 @@ 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 HRESULT constructor_call(DispatchEx *constr, LCID lcid, 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);
V_VT(retv) = VT_DISPATCH;
V_DISPATCH(retv) = (IDispatch*)_IDispatchEx_(constr);
IDispatchEx_AddRef(_IDispatchEx_(constr));
return S_OK;
}
static HRESULT JSGlobal_NaN(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
@ -105,8 +117,9 @@ static HRESULT JSGlobal_Number(DispatchEx *dispex, LCID lcid, WORD flags, DISPPA
static HRESULT JSGlobal_Object(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
FIXME("\n");
return E_NOTIMPL;
TRACE("\n");
return constructor_call(dispex->ctx->object_constr, lcid, flags, dp, retv, ei, sp);
}
static HRESULT JSGlobal_String(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
@ -280,10 +293,27 @@ static const builtin_info_t JSGlobal_info = {
NULL
};
static HRESULT init_constructors(script_ctx_t *ctx)
{
HRESULT hres;
hres = create_object_constr(ctx, &ctx->object_constr);
if(FAILED(hres))
return hres;
return S_OK;
}
HRESULT init_global(script_ctx_t *ctx)
{
HRESULT hres;
if(ctx->global)
return S_OK;
hres = init_constructors(ctx);
if(FAILED(hres))
return hres;
return create_dispex(ctx, &JSGlobal_info, NULL, &ctx->global);
}

View File

@ -50,7 +50,8 @@ typedef struct DispatchEx DispatchEx;
typedef enum {
JSCLASS_NONE,
JSCLASS_FUNCTION,
JSCLASS_GLOBAL
JSCLASS_GLOBAL,
JSCLASS_OBJECT
} jsclass_t;
typedef HRESULT (*builtin_invoke_t)(DispatchEx*,LCID,WORD,DISPPARAMS*,VARIANT*,jsexcept_t*,IServiceProvider*);
@ -87,9 +88,18 @@ struct DispatchEx {
#define _IDispatchEx_(x) ((IDispatchEx*) &(x)->lpIDispatchExVtbl)
static inline void jsdisp_release(DispatchEx *jsdisp)
{
IDispatchEx_Release(_IDispatchEx_(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 disp_propget(IDispatch*,DISPID,LCID,VARIANT*,jsexcept_t*,IServiceProvider*);
HRESULT disp_propput(IDispatch*,DISPID,LCID,VARIANT*,jsexcept_t*,IServiceProvider*);
HRESULT jsdisp_propput_name(DispatchEx*,const WCHAR*,LCID,VARIANT*,jsexcept_t*,IServiceProvider*);
@ -117,6 +127,7 @@ struct _script_ctx_t {
DispatchEx *script_disp;
DispatchEx *global;
DispatchEx *object_constr;
};
void script_release(script_ctx_t*);
@ -128,6 +139,8 @@ static inline void script_addref(script_ctx_t *ctx)
HRESULT init_global(script_ctx_t*);
HRESULT create_object_constr(script_ctx_t*,DispatchEx**);
const char *debugstr_variant(const VARIANT*);
HRESULT WINAPI JScriptFactory_CreateInstance(IClassFactory*,IUnknown*,REFIID,void**);

View File

@ -0,0 +1,125 @@
/*
* Copyright 2008 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 "jscript.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(jscript);
static const WCHAR toStringW[] = {'t','o','S','t','r','i','n','g',0};
static const WCHAR toLocaleStringW[] = {'t','o','L','o','c','a','l','e','S','t','r','i','n','g',0};
static const WCHAR valueOfW[] = {'v','a','l','u','e','O','f',0};
static const WCHAR hasOwnPropertyW[] = {'h','a','s','O','w','n','P','r','o','p','e','r','t','y',0};
static const WCHAR propertyIsEnumerableW[] =
{'p','r','o','p','e','r','t','y','I','s','E','n','u','m','e','r','a','b','l','e',0};
static const WCHAR isPrototypeOfW[] = {'i','s','P','r','o','t','o','t','y','p','e','O','f',0};
static HRESULT Object_toString(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
FIXME("\n");
return E_NOTIMPL;
}
static HRESULT Object_toLocaleString(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
FIXME("\n");
return E_NOTIMPL;
}
static HRESULT Object_valueOf(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
FIXME("\n");
return E_NOTIMPL;
}
static HRESULT Object_hasOwnProperty(DispatchEx *dispex, LCID lcid, 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,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
FIXME("\n");
return E_NOTIMPL;
}
static HRESULT Object_isPrototypeOf(DispatchEx *dispex, LCID lcid, 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,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
FIXME("\n");
return E_NOTIMPL;
}
static void Object_destructor(DispatchEx *dispex)
{
heap_free(dispex);
}
static const builtin_prop_t Object_props[] = {
{hasOwnPropertyW, Object_hasOwnProperty, PROPF_METHOD},
{isPrototypeOfW, Object_isPrototypeOf, PROPF_METHOD},
{propertyIsEnumerableW, Object_propertyIsEnumerable, PROPF_METHOD},
{toLocaleStringW, Object_toLocaleString, PROPF_METHOD},
{toStringW, Object_toString, PROPF_METHOD},
{valueOfW, Object_valueOf, PROPF_METHOD}
};
static const builtin_info_t Object_info = {
JSCLASS_OBJECT,
{NULL, Object_value, 0},
sizeof(Object_props)/sizeof(*Object_props),
Object_props,
Object_destructor,
NULL
};
static HRESULT ObjectConstr_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
FIXME("\n");
return E_NOTIMPL;
}
HRESULT create_object_constr(script_ctx_t *ctx, DispatchEx **ret)
{
DispatchEx *object;
HRESULT hres;
hres = create_dispex(ctx, &Object_info, NULL, &object);
if(FAILED(hres))
return hres;
hres = create_builtin_function(ctx, ObjectConstr_value, PROPF_CONSTR, object, ret);
jsdisp_release(object);
return hres;
}

View File

@ -46,4 +46,7 @@ function testFunc1(x, y) {
ok(testFunc1.length === 2, "testFunc1.length is not 2");
ok(Object.prototype !== undefined, "Object.prototype is undefined");
ok(Object.prototype.prototype === undefined, "Object.prototype is not undefined");
reportSuccess();