Title: [163590] trunk/Source/_javascript_Core
Revision
163590
Author
[email protected]
Date
2014-02-06 17:56:45 -0800 (Thu, 06 Feb 2014)

Log Message

+[JSContext currentCallee] should return the currently executing JS function
https://bugs.webkit.org/show_bug.cgi?id=122621

Reviewed by Geoffrey Garen.

It would be useful if there was a +[JSContext currentObject] API which was 
callable from ObjC API callbacks. Its purpose would be to allow convenient 
access to the JSValue wrapper for the currently-executing block callback.

* API/JSContext.h:
* API/JSContext.mm:
(+[JSContext currentCallee]):
(-[JSContext beginCallbackWithData:calleeValue:thisValue:argumentCount:arguments:]):
* API/JSContextInternal.h:
* API/ObjCCallbackFunction.mm:
(JSC::objCCallbackFunctionCallAsFunction):
(JSC::objCCallbackFunctionCallAsConstructor):
* API/tests/testapi.mm:

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/API/JSContext.h (163589 => 163590)


--- trunk/Source/_javascript_Core/API/JSContext.h	2014-02-07 01:55:24 UTC (rev 163589)
+++ trunk/Source/_javascript_Core/API/JSContext.h	2014-02-07 01:56:45 UTC (rev 163590)
@@ -27,6 +27,7 @@
 #define JSContext_h
 
 #include <_javascript_Core/_javascript_.h>
+#include <_javascript_Core/WebKitAvailability.h>
 
 #if JSC_OBJC_API_ENABLED
 
@@ -94,6 +95,24 @@
 
 /*!
 @method
+@abstract Get the _javascript_ function that is currently executing.
+@discussion This method may be called from within an Objective-C block or method invoked
+ as a callback from _javascript_ to retrieve the callback's context. Outside of
+ a callback from _javascript_ this method will return nil.
+@result The currently executing _javascript_ function or nil if there isn't one.
+*/
+#if TARGET_OS_IPHONE || __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
++ (JSValue *)currentCallee NS_AVAILABLE(10_10, 8_0);
+#else
+#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
++ (JSValue *)currentCallee __attribute__((availability(macosx,__NSi_10_10)));
+#else
++ (JSValue *)currentCallee __attribute__((availability(ios,__NSi_8_0)));
+#endif
+#endif // __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
+
+/*!
+@method
 @abstract Get the <code>this</code> value of the currently executing method.
 @discussion This method may be called from within an Objective-C block or method invoked
  as a callback from _javascript_ to retrieve the callback's this value. Outside

Modified: trunk/Source/_javascript_Core/API/JSContext.mm (163589 => 163590)


--- trunk/Source/_javascript_Core/API/JSContext.mm	2014-02-07 01:55:24 UTC (rev 163589)
+++ trunk/Source/_javascript_Core/API/JSContext.mm	2014-02-07 01:56:45 UTC (rev 163590)
@@ -141,6 +141,15 @@
     return [JSValue valueWithJSValueRef:entry->thisValue inContext:[JSContext currentContext]];
 }
 
++ (JSValue *)currentCallee
+{
+    WTFThreadData& threadData = wtfThreadData();
+    CallbackData *entry = (CallbackData *)threadData.m_apiData;
+    if (!entry)
+        return nil;
+    return [JSValue valueWithJSValueRef:entry->calleeValue inContext:[JSContext currentContext]];
+}
+
 + (NSArray *)currentArguments
 {
     WTFThreadData& threadData = wtfThreadData();
@@ -238,12 +247,12 @@
     return NO;
 }
 
-- (void)beginCallbackWithData:(CallbackData *)callbackData thisValue:(JSValueRef)thisValue argumentCount:(size_t)argumentCount arguments:(const JSValueRef *)arguments
+- (void)beginCallbackWithData:(CallbackData *)callbackData calleeValue:(JSValueRef)calleeValue thisValue:(JSValueRef)thisValue argumentCount:(size_t)argumentCount arguments:(const JSValueRef *)arguments
 {
     WTFThreadData& threadData = wtfThreadData();
     [self retain];
     CallbackData *prevStack = (CallbackData *)threadData.m_apiData;
-    *callbackData = (CallbackData){ prevStack, self, [self.exception retain], thisValue, argumentCount, arguments, nil };
+    *callbackData = (CallbackData){ prevStack, self, [self.exception retain], calleeValue, thisValue, argumentCount, arguments, nil };
     threadData.m_apiData = callbackData;
     self.exception = nil;
 }

Modified: trunk/Source/_javascript_Core/API/JSContextInternal.h (163589 => 163590)


--- trunk/Source/_javascript_Core/API/JSContextInternal.h	2014-02-07 01:55:24 UTC (rev 163589)
+++ trunk/Source/_javascript_Core/API/JSContextInternal.h	2014-02-07 01:56:45 UTC (rev 163590)
@@ -36,6 +36,7 @@
     CallbackData *next;
     JSContext *context;
     JSValue *preservedException;
+    JSValueRef calleeValue;
     JSValueRef thisValue;
     size_t argumentCount;
     const JSValueRef *arguments;
@@ -64,7 +65,7 @@
 - (JSValue *)valueFromNotifyException:(JSValueRef)exception;
 - (BOOL)boolFromNotifyException:(JSValueRef)exception;
 
-- (void)beginCallbackWithData:(CallbackData *)callbackData thisValue:(JSValueRef)thisValue argumentCount:(size_t)argumentCount arguments:(const JSValueRef *)arguments;
+- (void)beginCallbackWithData:(CallbackData *)callbackData calleeValue:(JSValueRef)calleeValue thisValue:(JSValueRef)thisValue argumentCount:(size_t)argumentCount arguments:(const JSValueRef *)arguments;
 - (void)endCallbackWithData:(CallbackData *)callbackData;
 
 - (JSValue *)wrapperForObjCObject:(id)object;

Modified: trunk/Source/_javascript_Core/API/ObjCCallbackFunction.mm (163589 => 163590)


--- trunk/Source/_javascript_Core/API/ObjCCallbackFunction.mm	2014-02-07 01:55:24 UTC (rev 163589)
+++ trunk/Source/_javascript_Core/API/ObjCCallbackFunction.mm	2014-02-07 01:56:45 UTC (rev 163590)
@@ -464,7 +464,7 @@
     CallbackData callbackData;
     JSValueRef result;
     @autoreleasepool {
-        [context beginCallbackWithData:&callbackData thisValue:thisObject argumentCount:argumentCount arguments:arguments];
+        [context beginCallbackWithData:&callbackData calleeValue:function thisValue:thisObject argumentCount:argumentCount arguments:arguments];
         result = impl->call(context, thisObject, argumentCount, arguments, exception);
         if (context.exception)
             *exception = valueInternalValue(context.exception);
@@ -484,7 +484,7 @@
     CallbackData callbackData;
     JSValueRef result;
     @autoreleasepool {
-        [context beginCallbackWithData:&callbackData thisValue:nil argumentCount:argumentCount arguments:arguments];
+        [context beginCallbackWithData:&callbackData calleeValue:constructor thisValue:nil argumentCount:argumentCount arguments:arguments];
         result = impl->call(context, NULL, argumentCount, arguments, exception);
         if (context.exception)
             *exception = valueInternalValue(context.exception);

Modified: trunk/Source/_javascript_Core/API/tests/testapi.mm (163589 => 163590)


--- trunk/Source/_javascript_Core/API/tests/testapi.mm	2014-02-07 01:55:24 UTC (rev 163589)
+++ trunk/Source/_javascript_Core/API/tests/testapi.mm	2014-02-07 01:56:45 UTC (rev 163590)
@@ -1141,8 +1141,30 @@
     @autoreleasepool {
         checkResult(@"[JSContext currentThis] == nil outside of callback", ![JSContext currentThis]);
         checkResult(@"[JSContext currentArguments] == nil outside of callback", ![JSContext currentArguments]);
+        if ([JSContext currentCallee])
+            checkResult(@"[JSContext currentCallee] == nil outside of callback", ![JSContext currentCallee]);
     }
 
+    if ([JSContext currentCallee]) {
+        @autoreleasepool {
+            JSContext *context = [[JSContext alloc] init];
+            context[@"testFunction"] = ^{
+                checkResult(@"testFunction.foo === 42", [[JSContext currentCallee][@"foo"] toInt32] == 42);
+            };
+            context[@"testFunction"][@"foo"] = @42;
+            [context[@"testFunction"] callWithArguments:nil];
+
+            context[@"TestConstructor"] = ^{
+                JSValue *newThis = [JSValue valueWithNewObjectInContext:[JSContext currentContext]];
+                JSGlobalContextRef contextRef = [[JSContext currentContext] JSGlobalContextRef];
+                JSObjectRef newThisRef = JSValueToObject(contextRef, [newThis JSValueRef], NULL);
+                JSObjectSetPrototype(contextRef, newThisRef, [[JSContext currentCallee][@"prototype"] JSValueRef]);
+                return newThis;
+            };
+            checkResult(@"(new TestConstructor) instanceof TestConstructor", [context evaluateScript:@"(new TestConstructor) instanceof TestConstructor"]);
+        }
+    }
+
     @autoreleasepool {
         JSContext *context = [[JSContext alloc] init];
         context[@"TestObject"] = [TestObject class];

Modified: trunk/Source/_javascript_Core/ChangeLog (163589 => 163590)


--- trunk/Source/_javascript_Core/ChangeLog	2014-02-07 01:55:24 UTC (rev 163589)
+++ trunk/Source/_javascript_Core/ChangeLog	2014-02-07 01:56:45 UTC (rev 163590)
@@ -1,5 +1,26 @@
 2014-02-06  Mark Hahnenberg  <[email protected]>
 
+        +[JSContext currentCallee] should return the currently executing JS function
+        https://bugs.webkit.org/show_bug.cgi?id=122621
+
+        Reviewed by Geoffrey Garen.
+
+        It would be useful if there was a +[JSContext currentObject] API which was 
+        callable from ObjC API callbacks. Its purpose would be to allow convenient 
+        access to the JSValue wrapper for the currently-executing block callback.
+
+        * API/JSContext.h:
+        * API/JSContext.mm:
+        (+[JSContext currentCallee]):
+        (-[JSContext beginCallbackWithData:calleeValue:thisValue:argumentCount:arguments:]):
+        * API/JSContextInternal.h:
+        * API/ObjCCallbackFunction.mm:
+        (JSC::objCCallbackFunctionCallAsFunction):
+        (JSC::objCCallbackFunctionCallAsConstructor):
+        * API/tests/testapi.mm:
+
+2014-02-06  Mark Hahnenberg  <[email protected]>
+
         Fix iOS builds after r163574
 
         * API/JSManagedValue.h:
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to