jscript: Added Object constructor object implementation.
diff --git a/dlls/jscript/Makefile.in b/dlls/jscript/Makefile.in
index 0288b4c..183a09e 100644
--- a/dlls/jscript/Makefile.in
+++ b/dlls/jscript/Makefile.in
@@ -15,7 +15,8 @@
 	jscript.c \
 	jscript_main.c \
 	jsutils.c \
-	lex.c
+	lex.c \
+	object.c
 
 IDL_TLB_SRCS = jsglobal.idl
 
diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c
index ae32f1a..ad7b988 100644
--- a/dlls/jscript/dispex.c
+++ b/dlls/jscript/dispex.c
@@ -715,8 +715,6 @@
 
 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 @@
     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 @@
         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 @@
     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 @@
     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)
 {
diff --git a/dlls/jscript/function.c b/dlls/jscript/function.c
index 96fbf78..a9c61e0 100644
--- a/dlls/jscript/function.c
+++ b/dlls/jscript/function.c
@@ -34,6 +34,8 @@
     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 @@
     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;
diff --git a/dlls/jscript/global.c b/dlls/jscript/global.c
index b16ca8c..5ed7d1d 100644
--- a/dlls/jscript/global.c
+++ b/dlls/jscript/global.c
@@ -53,6 +53,18 @@
 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_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 @@
     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);
 }
diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h
index 0144dbf..0deafc9 100644
--- a/dlls/jscript/jscript.h
+++ b/dlls/jscript/jscript.h
@@ -50,7 +50,8 @@
 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 @@
 
 #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 @@
 
     DispatchEx *script_disp;
     DispatchEx *global;
+    DispatchEx *object_constr;
 };
 
 void script_release(script_ctx_t*);
@@ -128,6 +139,8 @@
 
 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**);
diff --git a/dlls/jscript/object.c b/dlls/jscript/object.c
new file mode 100644
index 0000000..2cca6e9
--- /dev/null
+++ b/dlls/jscript/object.c
@@ -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;
+}
diff --git a/dlls/jscript/tests/lang.js b/dlls/jscript/tests/lang.js
index 67ed686..ef3d4d5 100644
--- a/dlls/jscript/tests/lang.js
+++ b/dlls/jscript/tests/lang.js
@@ -46,4 +46,7 @@
 
 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();