Reviewed by Maciej.
authorggaren <ggaren@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 17 Jul 2006 10:49:28 +0000 (10:49 +0000)
committerggaren <ggaren@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 17 Jul 2006 10:49:28 +0000 (10:49 +0000)
        - Removed the exception parameter from the initialize callback and, by extension,
        JSObjectMake. We have never had a need for exceptions when iniitializing,
        so the parameter seemed likely to "get in the way."

        Also, an exception in JavaScript is thrown in response to input --
        "invalid URL", "index not a number", etc., so it's the job of the
        constructor function, not the initialize method, to throw.

        If initialize *really* wants to throw, it can communicate the throw to
        the constructor through the constructed object's private data (e.g., set
        it to NULL, signaling to the consntructor that initialization failed.)

        - Added JSObjectMakeWithData, which enables a constructor to set private
        data on an object *before* it has been initialized. That way, the initialize
        methods can properly operate on the data.

        * API/JSNode.c: Moved ref into the initialize method, for better encapsulation,
        now that it's possible.
        * API/JSNodeList.c: ditto
        * API/minidom.c:
        (main): Do more aggressive garbage collection to test ref/deref and
        initialize/finalize.
        * API/minidom.js: store childNodes in a temporary so it doesn't get re-created
        like a thousand times. This makes debugging ref/deref easier

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@15484 268f45cc-cd09-0410-ab3c-d52691b4dbfc

12 files changed:
JavaScriptCore/API/JSCallbackObject.cpp
JavaScriptCore/API/JSCallbackObject.h
JavaScriptCore/API/JSContextRef.cpp
JavaScriptCore/API/JSNode.c
JavaScriptCore/API/JSNodeList.c
JavaScriptCore/API/JSObjectRef.cpp
JavaScriptCore/API/JSObjectRef.h
JavaScriptCore/API/minidom.c
JavaScriptCore/API/minidom.js
JavaScriptCore/API/testapi.c
JavaScriptCore/ChangeLog
JavaScriptCore/JavaScriptCore.exp

index d150fb7030496dc3cb571f6bc22563e4050323e2..e58894b3ed7d45dde01eab32caf7b59c4cb8cd64 100644 (file)
@@ -37,21 +37,15 @@ namespace KJS {
 
 const ClassInfo JSCallbackObject::info = { "CallbackObject", 0, 0, 0 };
 
-JSCallbackObject::JSCallbackObject(ExecState* exec, JSClassRef jsClass)
-    : JSObject()
-{
-    init(exec, jsClass);
-}
-
-JSCallbackObject::JSCallbackObject(ExecState* exec, JSClassRef jsClass, JSValue* prototype)
+JSCallbackObject::JSCallbackObject(ExecState* exec, JSClassRef jsClass, JSValue* prototype, void* data)
     : JSObject(prototype)
 {
-    init(exec, jsClass);
+    init(exec, jsClass, data);
 }
 
-void JSCallbackObject::init(ExecState* exec, JSClassRef jsClass)
+void JSCallbackObject::init(ExecState* exec, JSClassRef jsClass, void* data)
 {
-    m_privateData = 0;
+    m_privateData = data;
     m_class = JSClassRetain(jsClass);
 
     Vector<JSObjectInitializeCallback, 16> initRoutines;
@@ -63,7 +57,7 @@ void JSCallbackObject::init(ExecState* exec, JSClassRef jsClass)
     // initialize from base to derived
     for (int i = initRoutines.size() - 1; i >= 0; i--) {
         JSObjectInitializeCallback initialize = initRoutines[i];
-        initialize(toRef(exec), toRef(this), toRef(exec->exceptionSlot()));
+        initialize(toRef(exec), toRef(this));
     }
 }
 
index 569e84425fcd5a08c979c9614393831c7eefe4ad..066b63da2b6513ddf51a43c64b02ea889dbaf373 100644 (file)
@@ -36,8 +36,7 @@ namespace KJS {
 class JSCallbackObject : public JSObject
 {
 public:
-    JSCallbackObject(ExecState*, JSClassRef);
-    JSCallbackObject(ExecState*, JSClassRef, JSValue* prototype);
+    JSCallbackObject(ExecState*, JSClassRef, JSValue* prototype, void* data);
     virtual ~JSCallbackObject();
         
     virtual UString className() const;
@@ -77,7 +76,7 @@ private:
     JSCallbackObject(); // prevent default construction
     JSCallbackObject(const JSCallbackObject&);
 
-    void init(ExecState*, JSClassRef);
+    void init(ExecState*, JSClassRef jsClass, void*);
     
     static JSValue* cachedValueGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot&);
     static JSValue* staticValueGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot& slot);
index d6444cf09b8b4e73550c02b944b18618e29e1d8e..3dbd705b6b201ef03498dcfbe2855779a5f0d193 100644 (file)
@@ -41,7 +41,7 @@ JSGlobalContextRef JSGlobalContextCreate(JSClassRef globalObjectClass)
     JSObject* globalObject;
     if (globalObjectClass)
         // FIXME: We need to pass a real ExecState here to support an initialize callback in globalObjectClass
-        globalObject = new JSCallbackObject(0, globalObjectClass);
+        globalObject = new JSCallbackObject(0, globalObjectClass, 0, 0);
     else
         globalObject = new JSObject();
 
index 6b286f4c2d79954428d0b7896c76faaf27733929..d5eb357671b89ae444ef58fb1d48e6e32de69b4b 100644 (file)
@@ -156,6 +156,14 @@ static JSStaticValue JSNode_staticValues[] = {
     { 0, 0, 0, 0 }
 };
 
+static void JSNode_initialize(JSContextRef context, JSObjectRef object)
+{
+    Node* node = JSObjectGetPrivate(object);
+    assert(node);
+
+    Node_ref(node);
+}
+
 static void JSNode_finalize(JSObjectRef object)
 {
     Node* node = JSObjectGetPrivate(object);
@@ -170,6 +178,7 @@ static JSClassRef JSNode_class(JSContextRef context)
     if (!jsClass) {
         JSClassDefinition definition = kJSClassDefinitionNull;
         definition.staticValues = JSNode_staticValues;
+        definition.initialize = JSNode_initialize;
         definition.finalize = JSNode_finalize;
 
         jsClass = JSClassCreate(&definition);
@@ -181,7 +190,7 @@ JSObjectRef JSNode_prototype(JSContextRef context)
 {
     static JSObjectRef prototype;
     if (!prototype) {
-        prototype = JSObjectMake(context, JSNodePrototype_class(context), NULL, NULL);
+        prototype = JSObjectMake(context, JSNodePrototype_class(context), NULL);
         JSValueProtect(context, prototype);
     }
     return prototype;
@@ -189,11 +198,7 @@ JSObjectRef JSNode_prototype(JSContextRef context)
 
 JSObjectRef JSNode_new(JSContextRef context, Node* node)
 {
-    Node_ref(node);
-
-    JSObjectRef jsNode = JSObjectMake(context, JSNode_class(context), JSNode_prototype(context), NULL);
-    JSObjectSetPrivate(jsNode, node);
-    return jsNode;
+    return JSObjectMakeWithData(context, JSNode_class(context), JSNode_prototype(context), node);
 }
 
 JSObjectRef JSNode_construct(JSContextRef context, JSObjectRef object, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
index df4c1c330645287fe81805fd0fbb37e34bda7111..d77584083bca3fdeb71827c0aad2550330bb112a 100644 (file)
@@ -88,10 +88,19 @@ static JSValueRef JSNodeList_getProperty(JSContextRef context, JSObjectRef thisO
     return NULL;
 }
 
+static void JSNodeList_initialize(JSContextRef context, JSObjectRef thisObject)
+{
+    NodeList* nodeList = JSObjectGetPrivate(thisObject);
+    assert(nodeList);
+    
+    NodeList_ref(nodeList);
+}
+
 static void JSNodeList_finalize(JSObjectRef thisObject)
 {
     NodeList* nodeList = JSObjectGetPrivate(thisObject);
     assert(nodeList);
+
     NodeList_deref(nodeList);
 }
 
@@ -102,6 +111,7 @@ static JSClassRef JSNodeList_class(JSContextRef context)
         JSClassDefinition definition = kJSClassDefinitionNull;
         definition.staticValues = JSNodeList_staticValues;
         definition.getProperty = JSNodeList_getProperty;
+        definition.initialize = JSNodeList_initialize;
         definition.finalize = JSNodeList_finalize;
 
         jsClass = JSClassCreate(&definition);
@@ -114,7 +124,7 @@ static JSObjectRef JSNodeList_prototype(JSContextRef context)
 {
     static JSObjectRef prototype;
     if (!prototype) {
-        prototype = JSObjectMake(context, JSNodeListPrototype_class(context), NULL, NULL);
+        prototype = JSObjectMake(context, JSNodeListPrototype_class(context), NULL);
         JSValueProtect(context, prototype);
     }
     return prototype;
@@ -122,9 +132,5 @@ static JSObjectRef JSNodeList_prototype(JSContextRef context)
 
 JSObjectRef JSNodeList_new(JSContextRef context, NodeList* nodeList)
 {
-    NodeList_ref(nodeList);
-    
-    JSObjectRef jsNodeList = JSObjectMake(context, JSNodeList_class(context), JSNodeList_prototype(context), NULL);
-    JSObjectSetPrivate(jsNodeList, nodeList);
-    return jsNodeList;
+    return JSObjectMakeWithData(context, JSNodeList_class(context), JSNodeList_prototype(context), nodeList);
 }
index e2d64063eb816a6ff516e084cc37e5d71e876d1d..691750ac517fbc30246043cd85ec2cb3936c8bc7 100644 (file)
@@ -59,7 +59,12 @@ void JSClassRelease(JSClassRef jsClass)
         delete jsClass;
 }
 
-JSObjectRef JSObjectMake(JSContextRef ctx, JSClassRef jsClass, JSValueRef prototype, JSValueRef* exception)
+JSObjectRef JSObjectMake(JSContextRef ctx, JSClassRef jsClass, JSValueRef prototype)
+{
+    return JSObjectMakeWithData(ctx, jsClass, prototype, 0);
+}
+
+JSObjectRef JSObjectMakeWithData(JSContextRef ctx, JSClassRef jsClass, JSValueRef prototype, void* data)
 {
     JSLock lock;
 
@@ -69,18 +74,10 @@ JSObjectRef JSObjectMake(JSContextRef ctx, JSClassRef jsClass, JSValueRef protot
     if (!prototype)
         jsPrototype = exec->lexicalInterpreter()->builtinObjectPrototype();
 
-    JSObjectRef result;
-    if (jsClass) {
-        result = toRef(new JSCallbackObject(exec, jsClass, jsPrototype));
-        if (exec->hadException()) {
-            if (exception)
-                *exception = toRef(exec->exception());
-            exec->clearException();
-        }
-    } else
-        result = toRef(new JSObject(jsPrototype)); // slightly more efficient -- and can't throw
-        
-    return result;
+    if (!jsClass)
+        return toRef(new JSObject(jsPrototype)); // slightly more efficient
+    
+    return toRef(new JSCallbackObject(exec, jsClass, jsPrototype, data)); // initialize can't throw
 }
 
 JSObjectRef JSObjectMakeFunctionWithCallback(JSContextRef ctx, JSStringRef name, JSObjectCallAsFunctionCallback callAsFunction)
index 3068085c17ee9201a612b787ca18f28945e62cc3..9d951e82b75f4f1c1430f85a598d45289ea9fed8 100644 (file)
@@ -62,16 +62,15 @@ typedef unsigned JSPropertyAttributes;
 @abstract The callback invoked when an object is first created.
 @param ctx The execution context to use.
 @param object The JSObject being created.
-@param exception A pointer to a JSValueRef in which to return an exception, if any.
 @discussion If you named your function Initialize, you would declare it like this:
 
-void Initialize(JSContextRef ctx, JSObjectRef object, JSValueRef* exception);
+void Initialize(JSContextRef ctx, JSObjectRef object);
 
 Unlike the other object callbacks, the initialize callback is called on the least
 derived class (the parent class) first, and the most derived class last.
 */
 typedef void
-(*JSObjectInitializeCallback) (JSContextRef ctx, JSObjectRef object, JSValueRef* exception);
+(*JSObjectInitializeCallback) (JSContextRef ctx, JSObjectRef object);
 
 /*! 
 @typedef JSObjectFinalizeCallback
@@ -379,14 +378,29 @@ void JSClassRelease(JSClassRef jsClass);
 
 /*!
 @function
-@abstract Creates a JavaScript object with a given class and prototype.
+@abstract Creates a JavaScript object.
+@param ctx The execution context to use.
+@param jsClass The JSClass to assign to the object. Pass NULL to use the default object class.
+@param prototype The prototype to assign to the object. Pass NULL to use the default object prototype.
+@result A JSObject with the given class, prototype, and private data.
+@discussion The default object class does not allocate storage for private data, so you must provide a non-NULL JSClass if you want your object to be able to store private data.
+*/
+JSObjectRef JSObjectMake(JSContextRef ctx, JSClassRef jsClass, JSValueRef prototype);
+
+/*!
+@function
+@abstract Creates a JavaScript object.
 @param ctx The execution context to use.
 @param jsClass The JSClass to assign to the object. Pass NULL to use the default object class.
 @param prototype The prototype to assign to the object. Pass NULL to use the default object prototype.
+@param data A void* to set as the object's private data. Pass NULL to specify no private data.
 @param exception A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception.
-@result A JSObject with the given class and prototype.
+@result A JSObject with the given class, prototype, and private data.
+@discussion The default object class does not allocate storage for private data, so you must provide a non-NULL JSClass if you want your object to be able to store private data.
+data will be set on the created object before the intialize methods in its class chain are called. This enables the initialize methods to retrieve and manipulate data through JSObjectGetPrivate.
 */
-JSObjectRef JSObjectMake(JSContextRef ctx, JSClassRef jsClass, JSValueRef prototype, JSValueRef* exception);
+JSObjectRef JSObjectMakeWithData(JSContextRef ctx, JSClassRef jsClass, JSValueRef prototype, void* data);
 
 /*!
 @function
@@ -511,9 +525,9 @@ void JSObjectSetPropertyAtIndex(JSContextRef ctx, JSObjectRef object, unsigned p
 
 /*!
 @function
-@abstract Gets a pointer to private data from an object.
+@abstract Gets an object's private data.
 @param object A JSObject whose private data you want to get.
-@result A void* that points to the object's private data, if the object has private data, otherwise NULL.
+@result A void* that is the object's private data, if the object has private data, otherwise NULL.
 */
 void* JSObjectGetPrivate(JSObjectRef object);
 
@@ -521,9 +535,9 @@ void* JSObjectGetPrivate(JSObjectRef object);
 @function
 @abstract Sets a pointer to private data on an object.
 @param object A JSObject whose private data you want to set.
-@param data A void* that points to the object's private data.
+@param data A void* to set as the object's private data.
 @result true if the object can store private data, otherwise false.
-@discussion Only custom objects created with a JSClass can store private data.
+@discussion The default object class does not allocate storage for private data. Only objects created with a non-NULL JSClass can store private data.
 */
 bool JSObjectSetPrivate(JSObjectRef object, void* data);
 
index 7ce08fe9e2faa7366d8080cdd80f8783261d3869..9f535e464d53614af23ed97118e9ad9e949cc98c 100644 (file)
@@ -64,16 +64,9 @@ int main(int argc, char* argv[])
     JSStringRelease(script);
     free(scriptUTF8);
 
-#if 0 // used for leak/finalize debugging    
-    int i;
-    for (i = 0; i < 1000; i++) {
-        JSObjectRef o = JSObjectMake(context, NULL, NULL);
-        (void)o;
-    }
-    JSGarbageCollect();
-#endif
-    
+    globalObject = 0;
     JSGlobalContextRelease(context);
+    JSGarbageCollect(context);
     printf("PASS: Program exited normally.\n");
     return 0;
 }
index a68da9401da6515534d44c2e34fd4ca06eaf7355..3a058c0d589d8e9b5d8b9b677f1ec6cd2b3bd3b8 100644 (file)
@@ -198,23 +198,25 @@ function test()
     node.appendChild(child1);
     node.appendChild(child2);
 
-    for (var i = 0; i < node.childNodes.length + 1; i++) {
-        print("item " + i + ": " + node.childNodes.item(i));
+    var childNodes = node.childNodes;
+    
+    for (var i = 0; i < childNodes.length + 1; i++) {
+        print("item " + i + ": " + childNodes.item(i));
     }
     
-    for (var i = 0; i < node.childNodes.length + 1; i++) {
-        print(i + ": " + node.childNodes[i]);
+    for (var i = 0; i < childNodes.length + 1; i++) {
+        print(i + ": " + childNodes[i]);
     }
 
     node.removeChild(child1);
     node.replaceChild(child3, child2);
     
-    for (var i = 0; i < node.childNodes.length + 1; i++) {
-        print("item " + i + ": " + node.childNodes.item(i));
+    for (var i = 0; i < childNodes.length + 1; i++) {
+        print("item " + i + ": " + childNodes.item(i));
     }
 
-    for (var i = 0; i < node.childNodes.length + 1; i++) {
-        print(i + ": " + node.childNodes[i]);
+    for (var i = 0; i < childNodes.length + 1; i++) {
+        print(i + ": " + childNodes[i]);
     }
 
     try {
index 46dd285be15111d066893a378ac19f016f9dd045..582654f01219fcf6178dc50620442caf5a516c22 100644 (file)
@@ -100,7 +100,7 @@ static JSValueRef jsGlobalValue; // non-stack value for testing JSValueProtect()
 /* MyObject pseudo-class */
 
 static bool didInitialize = false;
-static void MyObject_initialize(JSContextRef context, JSObjectRef object, JSValueRef* exception)
+static void MyObject_initialize(JSContextRef context, JSObjectRef object)
 {
     UNUSED_PARAM(context);
     UNUSED_PARAM(object);
@@ -290,7 +290,7 @@ static JSClassRef MyObject_class(JSContextRef context)
     return jsClass;
 }
 
-static void Base_initialize(JSContextRef context, JSObjectRef object, JSValueRef* exception)
+static void Base_initialize(JSContextRef context, JSObjectRef object)
 {
     assert(!JSObjectGetPrivate(object));
     JSObjectSetPrivate(object, (void*)1);
@@ -315,7 +315,7 @@ static JSClassRef Base_class(JSContextRef context)
     return jsClass;
 }
 
-static void Derived_initialize(JSContextRef context, JSObjectRef object, JSValueRef* exception)
+static void Derived_initialize(JSContextRef context, JSObjectRef object)
 {
     assert((void*)1 == JSObjectGetPrivate(object));
     JSObjectSetPrivate(object, (void*)2);
@@ -361,7 +361,7 @@ static JSObjectRef myConstructor_callAsConstructor(JSContextRef context, JSObjec
 {
     UNUSED_PARAM(constructorObject);
     
-    JSObjectRef result = JSObjectMake(context, NULL, 0, NULL);
+    JSObjectRef result = JSObjectMake(context, NULL, NULL);
     if (argumentCount > 0) {
         JSStringRef value = JSStringCreateWithUTF8CString("value");
         JSObjectSetProperty(context, result, value, arguments[0], kJSPropertyAttributeNone, NULL);
@@ -390,7 +390,7 @@ int main(int argc, char* argv[])
     JSValueRef jsZero = JSValueMakeNumber(context, 0);
     JSValueRef jsOne = JSValueMakeNumber(context, 1);
     JSValueRef jsOneThird = JSValueMakeNumber(context, 1.0 / 3.0);
-    JSObjectRef jsObjectNoProto = JSObjectMake(context, NULL, JSValueMakeNull(context), NULL);
+    JSObjectRef jsObjectNoProto = JSObjectMake(context, NULL, JSValueMakeNull(context));
 
     // FIXME: test funny utf8 characters
     JSStringRef jsEmptyIString = JSStringCreateWithUTF8CString("");
@@ -444,7 +444,7 @@ int main(int argc, char* argv[])
     assert(JSValueGetType(context, jsCFEmptyStringWithCharacters) == kJSTypeString);
 #endif // __APPLE__
 
-    JSObjectRef myObject = JSObjectMake(context, MyObject_class(context), NULL, NULL);
+    JSObjectRef myObject = JSObjectMake(context, MyObject_class(context), NULL);
     assert(didInitialize);
     JSStringRef myObjectIString = JSStringCreateWithUTF8CString("MyObject");
     JSObjectSetProperty(context, globalObject, myObjectIString, myObject, kJSPropertyAttributeNone, NULL);
@@ -558,7 +558,7 @@ int main(int argc, char* argv[])
     CFRelease(cfEmptyString);
 #endif // __APPLE__
     
-    jsGlobalValue = JSObjectMake(context, NULL, NULL, NULL);
+    jsGlobalValue = JSObjectMake(context, NULL, NULL);
     JSValueProtect(context, jsGlobalValue);
     JSGarbageCollect(context);
     assert(JSValueIsObject(context, jsGlobalValue));
@@ -666,7 +666,7 @@ int main(int argc, char* argv[])
     assert(!JSObjectSetPrivate(myConstructor, (void*)1));
     assert(!JSObjectGetPrivate(myConstructor));
     
-    o = JSObjectMake(context, NULL, NULL, NULL);
+    o = JSObjectMake(context, NULL, NULL);
     JSObjectSetProperty(context, o, jsOneIString, JSValueMakeNumber(context, 1), kJSPropertyAttributeNone, NULL);
     JSObjectSetProperty(context, o, jsCFIString,  JSValueMakeNumber(context, 1), kJSPropertyAttributeDontEnum, NULL);
     JSPropertyNameArrayRef nameArray = JSObjectCopyPropertyNames(context, o);
@@ -689,9 +689,7 @@ int main(int argc, char* argv[])
     v = JSObjectCallAsFunction(context, function, o, 0, NULL, NULL);
     assert(JSValueIsEqual(context, v, o, NULL));
     
-    exception = NULL;
-    o = JSObjectMake(context, Derived_class(context), NULL, &exception);
-    assert(!exception);
+    o = JSObjectMake(context, Derived_class(context), NULL);
     assert(JSObjectGetPrivate(o) == (void*)2);
     o = NULL;
     
@@ -712,8 +710,8 @@ int main(int argc, char* argv[])
     free(scriptUTF8);
 
     // Allocate a few dummies so that at least one will be collected
-    JSObjectMake(context, MyObject_class(context), NULL, NULL);
-    JSObjectMake(context, MyObject_class(context), NULL, NULL);
+    JSObjectMake(context, MyObject_class(context), NULL);
+    JSObjectMake(context, MyObject_class(context), NULL);
     JSGarbageCollect(context);
     assert(MyObject_didFinalize);
     assert(Base_didFinalize);
index 7419ce63675ee8a40fa79f42a3812c7e23387edf..e00f9a8fc36793b7a29e8756fb3aed18604afa84 100644 (file)
@@ -1,3 +1,32 @@
+2006-07-17  Geoffrey Garen  <ggaren@apple.com>
+
+        Reviewed by Maciej.
+        
+        - Removed the exception parameter from the initialize callback and, by extension,
+        JSObjectMake. We have never had a need for exceptions when iniitializing,
+        so the parameter seemed likely to "get in the way." 
+        
+        Also, an exception in JavaScript is thrown in response to input -- 
+        "invalid URL", "index not a number", etc., so it's the job of the 
+        constructor function, not the initialize method, to throw.
+        
+        If initialize *really* wants to throw, it can communicate the throw to
+        the constructor through the constructed object's private data (e.g., set
+        it to NULL, signaling to the consntructor that initialization failed.)
+        
+        - Added JSObjectMakeWithData, which enables a constructor to set private
+        data on an object *before* it has been initialized. That way, the initialize
+        methods can properly operate on the data. 
+
+        * API/JSNode.c: Moved ref into the initialize method, for better encapsulation,
+        now that it's possible.
+        * API/JSNodeList.c: ditto
+        * API/minidom.c:
+        (main): Do more aggressive garbage collection to test ref/deref and 
+        initialize/finalize.
+        * API/minidom.js: store childNodes in a temporary so it doesn't get re-created
+        like a thousand times. This makes debugging ref/deref easier
+
 2006-07-17  Geoffrey Garen  <ggaren@apple.com>
 
         Reviewed by Maciej.
index 3570a326413182ac7fdf3ddcf24f8321bf2df8f6..c92ce6f4d080c33ea3c7e673026e59a664395082 100644 (file)
@@ -26,6 +26,7 @@ _JSObjectMake
 _JSObjectMakeConstructorWithCallback
 _JSObjectMakeFunctionWithCallback
 _JSObjectMakeFunction
+_JSObjectMakeWithData
 _JSObjectSetPrivate
 _JSObjectSetProperty
 _JSObjectSetPropertyAtIndex