jscript: Added Function.toString implementation for builtin functions.
diff --git a/dlls/jscript/array.c b/dlls/jscript/array.c
index f723931..34a5372 100644
--- a/dlls/jscript/array.c
+++ b/dlls/jscript/array.c
@@ -1101,11 +1101,13 @@
     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);
 
     jsdisp_release(&array->dispex);
     return hres;
diff --git a/dlls/jscript/bool.c b/dlls/jscript/bool.c
index 336f7e9..9393ffb 100644
--- a/dlls/jscript/bool.c
+++ b/dlls/jscript/bool.c
@@ -179,11 +179,13 @@
     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;
diff --git a/dlls/jscript/date.c b/dlls/jscript/date.c
index 7c240cd..1b1e26f 100644
--- a/dlls/jscript/date.c
+++ b/dlls/jscript/date.c
@@ -2603,11 +2603,13 @@
     DispatchEx *date;
     HRESULT hres;
 
+    static const WCHAR DateW[] = {'D','a','t','e',0};
+
     hres = create_date(ctx, object_prototype, 0.0, &date);
     if(FAILED(hres))
         return hres;
 
-    hres = create_builtin_function(ctx, DateConstr_value, &DateConstr_info, PROPF_CONSTR, date, ret);
+    hres = create_builtin_function(ctx, DateConstr_value, DateW, &DateConstr_info, PROPF_CONSTR, date, ret);
 
     jsdisp_release(date);
     return hres;
diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c
index 5e90e22..77a1fab 100644
--- a/dlls/jscript/dispex.c
+++ b/dlls/jscript/dispex.c
@@ -293,7 +293,8 @@
     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;
 
diff --git a/dlls/jscript/error.c b/dlls/jscript/error.c
index f3da405..2aa5436 100644
--- a/dlls/jscript/error.c
+++ b/dlls/jscript/error.c
@@ -374,7 +374,7 @@
         hres = jsdisp_propput_name(&err->dispex, nameW, ctx->lcid, &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]);
 
         jsdisp_release(&err->dispex);
diff --git a/dlls/jscript/function.c b/dlls/jscript/function.c
index 772c29a..83de7ca 100644
--- a/dlls/jscript/function.c
+++ b/dlls/jscript/function.c
@@ -26,6 +26,7 @@
 typedef struct {
     DispatchEx dispex;
     builtin_invoke_t value_proc;
+    const WCHAR *name;
     DWORD flags;
     source_elements_t *source;
     parameter_t *parameters;
@@ -285,14 +286,26 @@
 {
     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;
@@ -598,7 +611,7 @@
     return jsdisp_propput_name(dispex, prototypeW, ctx->lcid, &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;
@@ -615,6 +628,7 @@
     }
 
     function->value_proc = value_proc;
+    function->name = name;
 
     *ret = &function->dispex;
     return S_OK;
@@ -670,15 +684,19 @@
     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);
diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h
index 628cdfb..f09e257 100644
--- a/dlls/jscript/jscript.h
+++ b/dlls/jscript/jscript.h
@@ -144,7 +144,7 @@
 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*);
 
diff --git a/dlls/jscript/number.c b/dlls/jscript/number.c
index 30b7a56..3159eb1 100644
--- a/dlls/jscript/number.c
+++ b/dlls/jscript/number.c
@@ -330,12 +330,14 @@
     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;
diff --git a/dlls/jscript/object.c b/dlls/jscript/object.c
index a87fa1f..8170e71 100644
--- a/dlls/jscript/object.c
+++ b/dlls/jscript/object.c
@@ -192,7 +192,9 @@
 
 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);
 }
 
diff --git a/dlls/jscript/regexp.c b/dlls/jscript/regexp.c
index b675008..1c017b0 100644
--- a/dlls/jscript/regexp.c
+++ b/dlls/jscript/regexp.c
@@ -3845,11 +3845,13 @@
     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;
diff --git a/dlls/jscript/string.c b/dlls/jscript/string.c
index 4311aee..355961a 100644
--- a/dlls/jscript/string.c
+++ b/dlls/jscript/string.c
@@ -1869,11 +1869,14 @@
     StringInstance *string;
     HRESULT hres;
 
+    static const WCHAR StringW[] = {'S','t','r','i','n','g',0};
+
     hres = string_alloc(ctx, object_prototype, &string);
     if(FAILED(hres))
         return hres;
 
-    hres = create_builtin_function(ctx, StringConstr_value, &StringConstr_info, PROPF_CONSTR, &string->dispex, ret);
+    hres = create_builtin_function(ctx, StringConstr_value, StringW, &StringConstr_info,
+            PROPF_CONSTR, &string->dispex, ret);
 
     jsdisp_release(&string->dispex);
     return hres;
diff --git a/dlls/jscript/tests/api.js b/dlls/jscript/tests/api.js
index 5ece7d5..d3e08c8 100644
--- a/dlls/jscript/tests/api.js
+++ b/dlls/jscript/tests/api.js
@@ -1467,6 +1467,17 @@
 Math.SQRT1_2 = "test";
 ok(Math.floor(Math.SQRT1_2*100) === 70, "modified Math.SQRT1_2 = " + Math.SQRT1_2);
 
+ok(isNaN.toString() === "\nfunction isNaN() {\n    [native code]\n}\n",
+   "isNaN.toString = '" + isNaN.toString() + "'");
+ok(Array.toString() === "\nfunction Array() {\n    [native code]\n}\n",
+   "isNaN.toString = '" + Array.toString() + "'");
+ok(Function.toString() === "\nfunction Function() {\n    [native code]\n}\n",
+   "isNaN.toString = '" + Function.toString() + "'");
+ok(Function.prototype.toString() === "\nfunction prototype() {\n    [native code]\n}\n",
+   "isNaN.toString = '" + Function.prototype.toString() + "'");
+ok("".substr.toString() === "\nfunction substr() {\n    [native code]\n}\n",
+   "''.substr.toString = '" + "".substr.toString() + "'");
+
 var bool = new Boolean();
 ok(bool.toString() === "false", "bool.toString() = " + bool.toString());
 var bool = new Boolean("false");