jscript: Added Object constructor object implementation.
This commit is contained in:
parent
68f63689cb
commit
dd01f8b8f7
|
@ -15,7 +15,8 @@ C_SRCS = \
|
|||
jscript.c \
|
||||
jscript_main.c \
|
||||
jsutils.c \
|
||||
lex.c
|
||||
lex.c \
|
||||
object.c
|
||||
|
||||
IDL_TLB_SRCS = jsglobal.idl
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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**);
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue