@@ -770,19 +770,31 @@ bool LegacyFactoryFunctionJSNative(JSContext* cx, unsigned argc,
770
770
->mNative (cx, argc, vp);
771
771
}
772
772
773
- static JSObject* CreateLegacyFactoryFunction (JSContext* cx, jsid name,
774
- const JSNativeHolder* nativeHolder,
775
- unsigned ctorNargs) {
776
- JSFunction* fun = js::NewFunctionByIdWithReserved (
777
- cx, LegacyFactoryFunctionJSNative, ctorNargs, JSFUN_CONSTRUCTOR, name);
773
+ // This creates a JSFunction and sets its length and name properties in the
774
+ // order that ECMAScript's CreateBuiltinFunction does.
775
+ static JSObject* CreateBuiltinFunctionForConstructor (
776
+ JSContext* aCx, JSNative aNative, size_t aNativeReservedSlot,
777
+ void * aNativeReserved, unsigned int aNargs, jsid aName,
778
+ JS::Handle <JSObject*> aProto) {
779
+ JSFunction* fun = js::NewFunctionByIdWithReservedAndProto (
780
+ aCx, aNative, aProto, aNargs, JSFUN_CONSTRUCTOR, aName);
778
781
if (!fun) {
779
782
return nullptr ;
780
783
}
781
784
782
- JSObject* constructor = JS_GetFunctionObject (fun);
783
- js::SetFunctionNativeReserved (
784
- constructor, LEGACY_FACTORY_FUNCTION_NATIVE_HOLDER_RESERVED_SLOT,
785
- JS::PrivateValue (const_cast <JSNativeHolder*>(nativeHolder)));
785
+ JS::Rooted<JSObject*> constructor (aCx, JS_GetFunctionObject (fun));
786
+ js::SetFunctionNativeReserved (constructor, aNativeReservedSlot,
787
+ JS::PrivateValue (aNativeReserved));
788
+
789
+ // Eagerly force creation of the .length and .name properties, because
790
+ // SpiderMonkey creates them lazily (see
791
+ // https://bugzilla.mozilla.org/show_bug.cgi?id=1629803).
792
+ bool unused;
793
+ if (!JS_HasProperty (aCx, constructor, " length" , &unused) ||
794
+ !JS_HasProperty (aCx, constructor, " name" , &unused)) {
795
+ return nullptr ;
796
+ }
797
+
786
798
return constructor;
787
799
}
788
800
@@ -936,29 +948,12 @@ static JSObject* CreateInterfaceObject(
936
948
937
949
JS::Rooted<jsid> nameId (cx, JS::PropertyKey::NonIntAtom (name));
938
950
939
- JS::Rooted<JSObject*> constructor (cx);
940
- {
941
- JSFunction* fun = js::NewFunctionByIdWithReservedAndProto (
942
- cx, InterfaceObjectJSNative, interfaceProto, ctorNargs,
943
- JSFUN_CONSTRUCTOR, nameId);
944
- if (!fun) {
945
- return nullptr ;
946
- }
947
-
948
- constructor = JS_GetFunctionObject (fun);
949
- }
950
-
951
- js::SetFunctionNativeReserved (
952
- constructor, INTERFACE_OBJECT_INFO_RESERVED_SLOT,
953
- JS::PrivateValue (const_cast <DOMInterfaceInfo*>(interfaceInfo)));
954
-
955
- // Eagerly force creation of the .length and .name properties, because they
956
- // need to be defined before the .prototype property (CreateBuiltinFunction
957
- // called from the WebIDL spec sets them, and then the .prototype property is
958
- // defined in the WebIDL spec itself).
959
- bool unused;
960
- if (!JS_HasProperty (cx, constructor, " length" , &unused) ||
961
- !JS_HasProperty (cx, constructor, " name" , &unused)) {
951
+ JS::Rooted<JSObject*> constructor (
952
+ cx, CreateBuiltinFunctionForConstructor (
953
+ cx, InterfaceObjectJSNative, INTERFACE_OBJECT_INFO_RESERVED_SLOT,
954
+ const_cast <DOMInterfaceInfo*>(interfaceInfo), ctorNargs, nameId,
955
+ interfaceProto));
956
+ if (!constructor) {
962
957
return nullptr ;
963
958
}
964
959
@@ -1001,7 +996,11 @@ static JSObject* CreateInterfaceObject(
1001
996
nameId = JS::PropertyKey::NonIntAtom (fname);
1002
997
1003
998
JS::Rooted<JSObject*> legacyFactoryFunction (
1004
- cx, CreateLegacyFactoryFunction (cx, nameId, &lff.mHolder , lff.mNargs ));
999
+ cx, CreateBuiltinFunctionForConstructor (
1000
+ cx, LegacyFactoryFunctionJSNative,
1001
+ LEGACY_FACTORY_FUNCTION_NATIVE_HOLDER_RESERVED_SLOT,
1002
+ const_cast <JSNativeHolder*>(&lff.mHolder ), lff.mNargs , nameId,
1003
+ nullptr ));
1005
1004
if (!legacyFactoryFunction ||
1006
1005
!JS_DefineProperty (cx, legacyFactoryFunction, " prototype" , proto,
1007
1006
JSPROP_PERMANENT | JSPROP_READONLY) ||
0 commit comments