Jacek Caban : jscript: Added function object stub implementation.

Alexandre Julliard julliard at winehq.org
Tue Sep 9 05:50:48 CDT 2008


Module: wine
Branch: master
Commit: 7c6bf428b5a7883de2ed0813f746e5c3704e2683
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=7c6bf428b5a7883de2ed0813f746e5c3704e2683

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Tue Sep  9 01:27:01 2008 +0200

jscript: Added function object stub implementation.

---

 dlls/jscript/Makefile.in |    1 +
 dlls/jscript/dispex.c    |   18 +++-
 dlls/jscript/function.c  |  182 ++++++++++++++++++++++++++++++++++++++++++++++
 dlls/jscript/jscript.h   |    5 +
 4 files changed, 201 insertions(+), 5 deletions(-)

diff --git a/dlls/jscript/Makefile.in b/dlls/jscript/Makefile.in
index ac64b7f..0288b4c 100644
--- a/dlls/jscript/Makefile.in
+++ b/dlls/jscript/Makefile.in
@@ -10,6 +10,7 @@ RC_SRCS = rsrc.rc
 C_SRCS = \
 	dispex.c \
 	engine.c \
+	function.c \
 	global.c \
 	jscript.c \
 	jscript_main.c \
diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c
index 7d24699..ae32f1a 100644
--- a/dlls/jscript/dispex.c
+++ b/dlls/jscript/dispex.c
@@ -292,8 +292,16 @@ static HRESULT prop_get(DispatchEx *This, dispex_prop_t *prop, LCID lcid, DISPPA
     switch(prop->type) {
     case PROP_BUILTIN:
         if(prop->u.p->flags & PROPF_METHOD) {
-            FIXME("function objects not supported\n");
-            return E_NOTIMPL;
+            DispatchEx *obj;
+            hres = create_builtin_function(This->ctx, prop->u.p->invoke, prop->u.p->flags, NULL, &obj);
+            if(FAILED(hres))
+                break;
+
+            prop->type = PROP_VARIANT;
+            V_VT(&prop->u.var) = VT_DISPATCH;
+            V_DISPATCH(&prop->u.var) = (IDispatch*)_IDispatchEx_(obj);
+
+            hres = VariantCopy(retv, &prop->u.var);
         }else {
             hres = prop->u.p->invoke(This, lcid, DISPATCH_PROPERTYGET, dp, retv, ei, caller);
         }
@@ -688,7 +696,7 @@ static IDispatchExVtbl DispatchExVtbl = {
     DispatchEx_GetNameSpaceParent
 };
 
-static HRESULT jsdisp_set_prot_prop(DispatchEx *dispex, DispatchEx *prototype)
+HRESULT jsdisp_set_prototype(DispatchEx *dispex, DispatchEx *prototype)
 {
     VARIANT *var;
 
@@ -705,7 +713,7 @@ static HRESULT jsdisp_set_prot_prop(DispatchEx *dispex, DispatchEx *prototype)
     return S_OK;
 }
 
-static HRESULT init_dispex(DispatchEx *dispex, script_ctx_t *ctx, const builtin_info_t *builtin_info, 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};
 
@@ -740,7 +748,7 @@ static HRESULT init_dispex(DispatchEx *dispex, script_ctx_t *ctx, const builtin_
     if(prototype) {
         HRESULT hres;
 
-        hres = jsdisp_set_prot_prop(dispex, prototype);
+        hres = jsdisp_set_prototype(dispex, prototype);
         if(FAILED(hres)) {
             IDispatchEx_Release(_IDispatchEx_(dispex));
             return hres;
diff --git a/dlls/jscript/function.c b/dlls/jscript/function.c
new file mode 100644
index 0000000..13a6711
--- /dev/null
+++ b/dlls/jscript/function.c
@@ -0,0 +1,182 @@
+/*
+ * 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);
+
+typedef struct {
+    DispatchEx dispex;
+    builtin_invoke_t value_proc;
+    DWORD flags;
+    DWORD length;
+} FunctionInstance;
+
+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};
+static const WCHAR valueOfW[] = {'v','a','l','u','e','O','f',0};
+static const WCHAR applyW[] = {'a','p','p','l','y',0};
+static const WCHAR callW[] = {'c','a','l','l',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 Function_length(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
+        VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
+{
+    FIXME("\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT Function_toString(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
+        VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
+{
+    FIXME("\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT Function_toLocaleString(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
+        VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
+{
+    FIXME("\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT Function_valueOf(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
+        VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
+{
+    FIXME("\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT Function_apply(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
+        VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
+{
+    FIXME("\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT Function_call(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
+        VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
+{
+    FIXME("\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT Function_hasOwnProperty(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
+        VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
+{
+    FIXME("\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT Function_propertyIsEnumerable(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
+        VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
+{
+    FIXME("\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT Function_isPrototypeOf(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
+        VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
+{
+    FIXME("\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT Function_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
+        VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
+{
+    FIXME("\n");
+    return E_NOTIMPL;
+}
+
+static void Function_destructor(DispatchEx *dispex)
+{
+    FunctionInstance *This = (FunctionInstance*)dispex;
+
+    heap_free(This);
+}
+
+static const builtin_prop_t Function_props[] = {
+    {applyW,                 Function_apply,                 PROPF_METHOD},
+    {callW,                  Function_call,                  PROPF_METHOD},
+    {hasOwnPropertyW,        Function_hasOwnProperty,        PROPF_METHOD},
+    {isPrototypeOfW,         Function_isPrototypeOf,         PROPF_METHOD},
+    {lengthW,                Function_length,                0},
+    {propertyIsEnumerableW,  Function_propertyIsEnumerable,  PROPF_METHOD},
+    {toLocaleStringW,        Function_toLocaleString,        PROPF_METHOD},
+    {toStringW,              Function_toString,              PROPF_METHOD},
+    {valueOfW,               Function_valueOf,               PROPF_METHOD}
+};
+
+static const builtin_info_t Function_info = {
+    JSCLASS_FUNCTION,
+    {NULL, Function_value, 0},
+    sizeof(Function_props)/sizeof(*Function_props),
+    Function_props,
+    Function_destructor,
+    NULL
+};
+
+static HRESULT create_function(script_ctx_t *ctx, DWORD flags, DispatchEx *prototype, FunctionInstance **ret)
+{
+    FunctionInstance *function;
+    HRESULT hres;
+
+    function = heap_alloc_zero(sizeof(FunctionInstance));
+    if(!function)
+        return E_OUTOFMEMORY;
+
+    hres = init_dispex(&function->dispex, ctx, &Function_info, NULL);
+    if(FAILED(hres))
+        return hres;
+
+    function->flags = flags;
+    function->length = flags & PROPF_ARGMASK;
+
+    if(prototype) {
+        hres = jsdisp_set_prototype(&function->dispex, prototype);
+        if(FAILED(hres)) {
+            IDispatchEx_Release(_IDispatchEx_(&function->dispex));
+            return hres;
+        }
+    }
+
+    *ret = function;
+    return S_OK;
+}
+
+HRESULT create_builtin_function(script_ctx_t *ctx, builtin_invoke_t value_proc, DWORD flags,
+        DispatchEx *prototype, DispatchEx **ret)
+{
+    FunctionInstance *function;
+    HRESULT hres;
+
+    hres = create_function(ctx, flags, prototype, &function);
+    if(FAILED(hres))
+        return hres;
+
+    function->value_proc = value_proc;
+
+    *ret = &function->dispex;
+    return S_OK;
+}
diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h
index 31812bf..a8fc379 100644
--- a/dlls/jscript/jscript.h
+++ b/dlls/jscript/jscript.h
@@ -49,6 +49,7 @@ typedef struct DispatchEx DispatchEx;
 
 typedef enum {
     JSCLASS_NONE,
+    JSCLASS_FUNCTION,
     JSCLASS_GLOBAL
 } jsclass_t;
 
@@ -87,10 +88,14 @@ struct DispatchEx {
 #define _IDispatchEx_(x) ((IDispatchEx*) &(x)->lpIDispatchExVtbl)
 
 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 disp_call(IDispatch*,DISPID,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*);
+HRESULT jsdisp_set_prototype(DispatchEx*,DispatchEx*);
+
+HRESULT create_builtin_function(script_ctx_t*,builtin_invoke_t,DWORD,DispatchEx*,DispatchEx**);
 
 HRESULT to_boolean(VARIANT*,VARIANT_BOOL*);
 




More information about the wine-cvs mailing list