40#ifndef DEBUG_FCB_SIMPLE_TRACKING_IDS
41#define DEBUG_FCB_SIMPLE_TRACKING_IDS 0
44#ifndef DEBUG_FCB_VERBOSE_LOGGING
45#define DEBUG_FCB_VERBOSE_LOGGING 0
50#if defined (NDEBUG) && DEBUG_FCB_SIMPLE_TRACKING_IDS
51#error Deployment builds may not be built with DEBUG_FCB_SIMPLE_TRACKING_IDS.
54#if DEBUG_FCB_VERBOSE_LOGGING
56#define FCBLogIndentIf OOLogIndentIf
57#define FCBLogOutdentIf OOLogOutdentIf
59#define FCBLog(...) do {} while (0)
60#define FCBLogIndentIf(key) do {} while (0)
61#define FCBLogOutdentIf(key) do {} while (0)
69#if DEBUG_FCB_SIMPLE_TRACKING_IDS
103static BOOL
AddCallback(JSContext *context, jsval callback, uint32 trackingID, NSString **errorString);
123#if DEBUG_FCB_SIMPLE_TRACKING_IDS
127 sNextID = [[NSDate date] timeIntervalSinceReferenceDate];
134 NSCAssert1(!
sRunning,
@"%s cannot be called while frame callbacks are running.", __PRETTY_FUNCTION__);
138 const OOTimeDelta delta = inDeltaT * [UNIVERSE timeAccelerationFactor];
140 jsval deltaVal, result;
143 if (
EXPECT(JS_NewNumberValue(context, delta, &deltaVal)))
154 for (i = 0; i <
sCount; i++)
157 JS_CallFunctionValue(context, NULL,
sCallbacks[i].callback, 1, &deltaVal, &result);
158 JS_ReportPendingException(context);
177 NSCAssert1(!
sRunning,
@"%s cannot be called while frame callbacks are running.", __PRETTY_FUNCTION__);
210 NSString *errorString =
nil;
220 FCBLog(
@"script.frameCallback.debug.add.deferred",
@"Deferring addition of frame callback with tracking ID %u.", trackingID);
254 FCBLog(
@"script.frameCallback.debug.remove.deferred",
@"Deferring removal of frame callback with tracking ID %u.", trackingID);
291static BOOL
AddCallback(JSContext *context, jsval callback, uint32 trackingID, NSString **errorString)
294 NSCParameterAssert(errorString != NULL);
295 NSCAssert1(!
sRunning,
@"%s cannot be called while frame callbacks are running.", __PRETTY_FUNCTION__);
302 FCBLog(
@"script.frameCallback.debug.add",
@"Adding frame callback with tracking ID %u.", trackingID);
311 *errorString =
@"Failed to add GC root for frame callback.";
328 NSCParameterAssert(errorString != NULL);
333 if (newCallbacks == NULL)
return NO;
338 NSUInteger newHighWaterMark =
sCount;
340 for (i = 0; i < newHighWaterMark; i++)
346 for (j = 0; j < i; j++)
348 JS_RemoveValueRoot(context, &newCallbacks[j].callback);
352 *errorString =
@"Failed to add GC root for frame callback.";
355 newCallbacks[i] = oldCallbacks[i];
361 JS_RemoveValueRoot(context, &oldCallbacks[i].callback);
378 NSCParameterAssert(outIndex != NULL);
386 for (i = 0; i <
sCount; i++)
402 NSCAssert1(!
sRunning,
@"%s cannot be called while frame callbacks are running.", __PRETTY_FUNCTION__);
404 NSUInteger index = 0;
419 NSCAssert1(!
sRunning,
@"%s cannot be called while frame callbacks are running.", __PRETTY_FUNCTION__);
421 FCBLog(
@"script.frameCallback.debug.remove",
@"Removing frame callback with tracking ID %u.",
sCallbacks[index].trackingID);
428#if DEBUG_FCB_SIMPLE_TRACKING_IDS
431 OOLog(
@"script.frameCallback.debug.reset",
@"All frame callbacks removed, resetting next ID to 1.");
440 NSCAssert1(
sRunning,
@"%s can only be called while frame callbacks are running.", __PRETTY_FUNCTION__);
443 [sDeferredOps addObject:[NSDictionary dictionaryWithObjectsAndKeys:
444 opType, @"operation",
445 [NSNumber numberWithInt:trackingID], @"trackingID",
453 NSDictionary *operation =
nil;
454 NSEnumerator *operationEnum =
nil;
456 FCBLog(
@"script.frameCallback.debug.run-deferred",
@"Running %lu deferred frame callback operations.", (
long)[
sDeferredOps count]);
459 for (operationEnum = [
sDeferredOps objectEnumerator]; (operation = [operationEnum nextObject]); )
461 NSString *opType = [operation objectForKey:@"operation"];
462 uint32 trackingID = [operation oo_intForKey:@"trackingID"];
464 if ([opType isEqualToString:
@"add"])
466 OOJSValue *callbackObj = [operation objectForKey:@"value"];
467 NSString *errorString =
nil;
471 OOLogWARN(
@"script.frameCallback.deferredAdd.failed",
@"Deferred frame callback insertion failed: %@", errorString);
474 else if ([opType isEqualToString:
@"remove"])
#define OOJS_NATIVE_ENTER(cx)
#define OOJSStopTimeLimiter()
#define OOJSStartTimeLimiterWithTimeLimit(limit)
void InitOOJSFrameCallbacks(JSContext *context, JSObject *global)
static JSBool GlobalAddFrameCallback(JSContext *context, uintN argc, jsval *vp)
static void RemoveCallbackAtIndex(JSContext *context, NSUInteger index)
#define FCBLogOutdentIf(key)
static BOOL RemoveCallbackWithTrackingID(JSContext *context, uint32 trackingID)
static BOOL GetIndexForTrackingID(uint32 trackingID, NSUInteger *outIndex)
void OOJSFrameCallbacksRemoveAll(void)
static NSUInteger sHighWaterMark
static void QueueDeferredOperation(NSString *opType, uint32 trackingID, OOJSValue *value)
#define FCBLogIndentIf(key)
void OOJSFrameCallbacksInvoke(OOTimeDelta inDeltaT)
static CallbackEntry * sCallbacks
static BOOL AddCallback(JSContext *context, jsval callback, uint32 trackingID, NSString **errorString)
static JSBool GlobalRemoveFrameCallback(JSContext *context, uintN argc, jsval *vp)
static BOOL GrowCallbackList(JSContext *context, NSString **errorString)
static void RunDeferredOperations(JSContext *context)
static NSMutableArray * sDeferredOps
static JSBool GlobalIsValidFrameCallback(JSContext *context, uintN argc, jsval *vp)
void OOJSReportWarning(JSContext *context, NSString *format,...)
#define JS_IsInRequest(context)
OOINLINE jsval OOJSValueFromNativeObject(JSContext *context, id object)
#define OOJS_RETURN_BOOL(v)
OOINLINE BOOL OOJSValueIsFunction(JSContext *context, jsval value)
OOINLINE JSContext * OOJSAcquireContext(void)
void OOJSReportError(JSContext *context, NSString *format,...)
OOINLINE void OOJSRelinquishContext(JSContext *context)
void OOJSReportBadArguments(JSContext *context, NSString *scriptClass, NSString *function, uintN argc, jsval *argv, NSString *message, NSString *expectedArgsDescription)
#define OOJSAddGCValueRoot(context, root, name)
#define OOJS_RETURN_INT(v)
#define OOJS_METHOD_READONLY
#define OOLogWARN(class, format,...)
#define OOLog(class, format,...)