Permalink
Browse files

Add manual memory management to Cappuccino.

  • Loading branch information...
1 parent acac29d commit 6678bba94f7778b245d8219292b3a6ac85d31678 Ross Boucher committed Apr 1, 2010
View
16 Foundation/CPArray.j
@@ -105,15 +105,19 @@
*/
+ (id)alloc
{
- return [];
+ var a = [];
+ a._retainCount = 1;
+ a._UID = objj_generateObjectUID();
+ OBJJ_MEMORY_TABLE[a._UID] = a;
+ return a;
}
/*!
Returns a new initialized CPArray.
*/
+ (id)array
{
- return [[self alloc] init];
+ return [[[self alloc] init] autorelease];
}
/*!
@@ -123,7 +127,7 @@
*/
+ (id)arrayWithArray:(CPArray)anArray
{
- return [[self alloc] initWithArray:anArray];
+ return [[[self alloc] initWithArray:anArray] autorelease];
}
/*!
@@ -133,7 +137,7 @@
*/
+ (id)arrayWithObject:(id)anObject
{
- return [[self alloc] initWithObjects:anObject];
+ return [[[self alloc] initWithObjects:anObject] autorelease];
}
/*!
@@ -150,7 +154,7 @@
for(; i < arguments.length && (argument = arguments[i]) != nil; ++i)
array.push(argument);
- return array;
+ return [array autorelease];
}
/*!
@@ -161,7 +165,7 @@
*/
+ (id)arrayWithObjects:(id)objects count:(unsigned)aCount
{
- return [[self alloc] initWithObjects:objects count:aCount];
+ return [[[self alloc] initWithObjects:objects count:aCount] autorelease];
}
/*!
View
56 Foundation/CPAutoreleasePool.j
@@ -0,0 +1,56 @@
+
+@import "CPObject.j"
+
+var MAIN_POOL = nil;
+
+@implementation CPAutoreleasePool : CPObject
+{
+ CPArray _objects;
+}
+
++ (void)initialize
+{
+ MAIN_POOL = [CPAutoreleasePool new];
+}
+
++ (id)_mainAutoreleasePool
+{
+ return MAIN_POOL;
+}
+
++ (void)addObject:(id)anObject
+{
+ [[self _mainAutoreleasePool] addObject:anObject];
+}
+
+- (id)init
+{
+ if (self = [super init])
+ {
+ _objects = [];
+ [[CPRunLoop currentRunLoop] performSelector:@selector(drain) target:self argument:nil order:0 modes:[CPDefaultRunLoopMode]];
+ }
+
+ return self;
+}
+
+- (void)addObject:(id)anObject
+{
+ _objects.push(anObject);
+}
+
+- (void)drain
+{
+ for (var i = 0, count = [_objects count]; i < count; i++)
+ [_objects.pop() release];
+
+ [[CPRunLoop currentRunLoop] performSelector:@selector(drain) target:self argument:nil order:0 modes:[CPDefaultRunLoopMode]];
+}
+
+- (void)dealloc
+{
+ [self drain];
+ [super dealloc];
+}
+
+@end
View
2 Foundation/CPBundle.j
@@ -72,7 +72,7 @@ var CPBundlesForURLStrings = { };
if (self)
{
_bundle = new CFBundle(aURL);
- CPBundlesForURLStrings[URLString] = self;
+ CPBundlesForURLStrings[URLString] = [self retain];
}
return self;
View
10 Foundation/CPData.j
@@ -40,27 +40,27 @@
+ (CPData)data
{
- return [[self alloc] init];
+ return [[[self alloc] init] autorelease];
}
+ (CPData)dataWithRawString:(CPString)aString
{
- return [[self alloc] initWithRawString:aString];
+ return [[[self alloc] initWithRawString:aString] autorelease];
}
+ (CPData)dataWithPlistObject:(id)aPlistObject
{
- return [[self alloc] initWithPlistObject:aPlistObject];
+ return [[[self alloc] initWithPlistObject:aPlistObject] autorelease];
}
+ (CPData)dataWithPlistObject:(id)aPlistObject format:(CPPropertyListFormat)aFormat
{
- return [[self alloc] initWithPlistObject:aPlistObject format:aFormat];
+ return [[[self alloc] initWithPlistObject:aPlistObject format:aFormat] autorelease];
}
+ (CPData)dataWithJSONObject:(Object)anObject
{
- return [[self alloc] initWithJSONObject:anObject];
+ return [[[self alloc] initWithJSONObject:anObject] autorelease];
}
- (id)initWithRawString:(CPString)aString
View
32 Foundation/CPDate.j
@@ -24,7 +24,13 @@
@import "CPString.j"
-var CPDateReferenceDate = new Date(Date.UTC(2001,1,1,0,0,0,0));
+var CPDateReferenceDate = new Date(Date.UTC(2001,1,1,0,0,0,0)),
+ _CPDateAllocator = function(a) {
+ a._retainCount = 1;
+ a._UID = objj_generateObjectUID();
+ OBJJ_MEMORY_TABLE[a._UID] = a;
+ return a;
+ };
/*!
@class CPDate
@@ -39,48 +45,48 @@ var CPDateReferenceDate = new Date(Date.UTC(2001,1,1,0,0,0,0));
+ (id)alloc
{
- return new Date;
+ return _CPDateAllocator(new Date);
}
+ (id)date
{
- return [[self alloc] init];
+ return [[[self alloc] init] autorelease];
}
+ (id)dateWithTimeIntervalSinceNow:(CPTimeInterval)seconds
{
- return [[CPDate alloc] initWithTimeIntervalSinceNow:seconds];
+ return [[[CPDate alloc] initWithTimeIntervalSinceNow:seconds] autorelease];
}
+ (id)dateWithTimeIntervalSince1970:(CPTimeInterval)seconds
{
- return [[CPDate alloc] initWithTimeIntervalSince1970:seconds];
+ return [[[CPDate alloc] initWithTimeIntervalSince1970:seconds] autorelease];
}
+ (id)dateWithTimeIntervalSinceReferenceDate:(CPTimeInterval)seconds
{
- return [[CPDate alloc] initWithTimeIntervalSinceReferenceDate:seconds];
+ return [[[CPDate alloc] initWithTimeIntervalSinceReferenceDate:seconds] autorelease];
}
+ (id)distantPast
{
- return new Date(-10000,1,1,0,0,0,0);
+ return [_CPDateAllocator(new Date(-10000,1,1,0,0,0,0)) autorelease];
}
+ (id)distantFuture
{
- return new Date(10000,1,1,0,0,0,0);
+ return [_CPDateAllocator(new Date(10000,1,1,0,0,0,0)) autorelease];
}
- (id)initWithTimeIntervalSinceNow:(CPTimeInterval)seconds
{
- self = new Date((new Date()).getTime() + seconds * 1000);
+ self = _CPDateAllocator(new Date((new Date()).getTime() + seconds * 1000));
return self;
}
- (id)initWithTimeIntervalSince1970:(CPTimeInterval)seconds
{
- self = new Date(seconds * 1000);
+ self = _CPDateAllocator(new Date(seconds * 1000));
return self;
}
@@ -92,7 +98,7 @@ var CPDateReferenceDate = new Date(Date.UTC(2001,1,1,0,0,0,0));
- (id)initWithTimeInterval:(CPTimeInterval)seconds sinceDate:(CPDate)refDate
{
- self = new Date(refDate.getTime() + seconds * 1000);
+ self = _CPDateAllocator(new Date(refDate.getTime() + seconds * 1000));
return self;
}
@@ -117,7 +123,7 @@ var CPDateReferenceDate = new Date(Date.UTC(2001,1,1,0,0,0,0));
date.setMinutes(d[5]);
date.setSeconds(d[6]);
- self = new Date(date.getTime() + (timeZoneOffset - date.getTimezoneOffset()) * 60 * 1000);
+ self = _CPDateAllocator(new Date(date.getTime() + (timeZoneOffset - date.getTimezoneOffset()) * 60 * 1000));
return self;
}
@@ -185,7 +191,7 @@ var CPDateReferenceDate = new Date(Date.UTC(2001,1,1,0,0,0,0));
- (id)copy
{
- return new Date(self.getTime());
+ return _CPDateAllocator(new Date(self.getTime()));
}
@end
View
14 Foundation/CPDictionary.j
@@ -92,7 +92,7 @@
*/
+ (id)dictionary
{
- return [[self alloc] init];
+ return [[[self alloc] init] autorelease];;
}
/*!
@@ -102,7 +102,7 @@
*/
+ (id)dictionaryWithDictionary:(CPDictionary)aDictionary
{
- return [[self alloc] initWithDictionary:aDictionary];
+ return [[[self alloc] initWithDictionary:aDictionary] autorelease];
}
/*!
@@ -113,7 +113,7 @@
*/
+ (id)dictionaryWithObject:(id)anObject forKey:(id)aKey
{
- return [[self alloc] initWithObjects:[anObject] forKeys:[aKey]];
+ return [[[self alloc] initWithObjects:[anObject] forKeys:[aKey]] autorelease];
}
/*!
@@ -125,7 +125,7 @@
*/
+ (id)dictionaryWithObjects:(CPArray)objects forKeys:(CPArray)keys
{
- return [[self alloc] initWithObjects:objects forKeys:keys];
+ return [[[self alloc] initWithObjects:objects forKeys:keys] autorelease];
}
/*!
@@ -135,7 +135,7 @@
*/
+ (id)dictionaryWithJSObject:(JSObject)object
{
- return [self dictionaryWithJSObject:object recursively:NO];
+ return [[self dictionaryWithJSObject:object recursively:NO] autorelease];
}
/*!
@@ -145,7 +145,7 @@
*/
+ (id)dictionaryWithJSObject:(JSObject)object recursively:(BOOL)recursively
{
- var dictionary = [[self alloc] init];
+ var dictionary = [[[self alloc] init] autorelease];
for (var key in object)
{
@@ -209,7 +209,7 @@
arguments[0] = [self alloc];
arguments[1] = @selector(initWithObjectsAndKeys:);
- return objj_msgSend.apply(this, arguments);
+ return [objj_msgSend.apply(this, arguments) autorelease];
}
/*!
View
6 Foundation/CPIndexSet.j
@@ -47,15 +47,15 @@
*/
+ (id)indexSet
{
- return [[self alloc] init];
+ return [[[self alloc] init] autorelease];
}
/*!
Returns a new index set with just one index.
*/
+ (id)indexSetWithIndex:(int)anIndex
{
- return [[self alloc] initWithIndex:anIndex];
+ return [[[self alloc] initWithIndex:anIndex] autorelease];
}
/*!
@@ -64,7 +64,7 @@
*/
+ (id)indexSetWithIndexesInRange:(CPRange)aRange
{
- return [[self alloc] initWithIndexesInRange:aRange];
+ return [[[self alloc] initWithIndexesInRange:aRange] autorelease];
}
// Initializing and Index Set
View
2 Foundation/CPInvocation.j
@@ -46,7 +46,7 @@
*/
+ (id)invocationWithMethodSignature:(CPMethodSignature)aMethodSignature
{
- return [[self alloc] initWithMethodSignature:aMethodSignature];
+ return [[[self alloc] initWithMethodSignature:aMethodSignature] autorelease];
}
/*!
View
2 Foundation/CPJSONPConnection.j
@@ -56,7 +56,7 @@ CPJSONPCallbackReplacementString = @"${JSONP_CALLBACK}";
+ (CPJSONPConnection)connectionWithRequest:(CPURLRequest)aRequest callback:(CPString)callbackParameter delegate:(id)aDelegate
{
- return [[[self class] alloc] initWithRequest:aRequest callback:callbackParameter delegate:aDelegate startImmediately:YES];;
+ return [[[[self class] alloc] initWithRequest:aRequest callback:callbackParameter delegate:aDelegate startImmediately:YES] autorelease];
}
- (id)initWithRequest:(CPURLRequest)aRequest callback:(CPString)aString delegate:(id)aDelegate
View
2 Foundation/CPKeyedArchiver.j
@@ -148,7 +148,7 @@ var _CPKeyedArchiverStringClass = Nil,
+ (CPData)archivedDataWithRootObject:(id)anObject
{
var data = [CPData dataWithPlistObject:nil],
- archiver = [[self alloc] initForWritingWithMutableData:data];
+ archiver = [[[self alloc] initForWritingWithMutableData:data] autorelease];
[archiver encodeObject:anObject forKey:@"root"];
[archiver finishEncoding];
View
2 Foundation/CPKeyedUnarchiver.j
@@ -171,7 +171,7 @@ var CPArrayClass = Ni
return nil;
}
- var unarchiver = [[self alloc] initForReadingWithData:aData],
+ var unarchiver = [[[self alloc] initForReadingWithData:aData] autorelease],
object = [unarchiver decodeObjectForKey:@"root"];
[unarchiver finishDecoding];
View
4 Foundation/CPNotification.j
@@ -53,7 +53,7 @@
*/
+ (CPNotification)notificationWithName:(CPString)aNotificationName object:(id)anObject userInfo:(CPDictionary)aUserInfo
{
- return [[self alloc] initWithName:aNotificationName object:anObject userInfo:aUserInfo];
+ return [[[self alloc] initWithName:aNotificationName object:anObject userInfo:aUserInfo] autorelease];
}
/*!
@@ -64,7 +64,7 @@
*/
+ (CPNotification)notificationWithName:(CPString)aNotificationName object:(id)anObject
{
- return [[self alloc] initWithName:aNotificationName object:anObject userInfo:nil];
+ return [[[self alloc] initWithName:aNotificationName object:anObject userInfo:nil] autorelease];
}
/*!
View
3 Foundation/CPNumber.j
@@ -333,4 +333,7 @@ FIXME: Do we need this?
Number.prototype.isa = CPNumber;
Boolean.prototype.isa = CPNumber;
+Number.prototype._retainCount = Infinity;
+Boolean.prototype._retainCount = Infinity;
+
[CPNumber initialize];
View
11 Foundation/CPObject.j
@@ -89,7 +89,6 @@ CPLog(@"Got some class: %@", inst);
*/
+ (id)alloc
{
-// CPLog("calling alloc on " + self.name + ".");
return class_createInstance(self);
}
@@ -130,6 +129,7 @@ CPLog(@"Got some class: %@", inst);
*/
- (void)dealloc
{
+ delete OBJJ_MEMORY_TABLE[[self UID]];
}
// Identifying classes
@@ -464,6 +464,7 @@ CPLog(@"Got some class: %@", inst);
*/
- (id)autorelease
{
+ [CPAutoreleasePool addObject:self];
return self;
}
@@ -498,6 +499,7 @@ CPLog(@"Got some class: %@", inst);
*/
- (id)retain
{
+ _retainCount++;
return self;
}
@@ -506,6 +508,11 @@ CPLog(@"Got some class: %@", inst);
*/
- (void)release
{
+ _retainCount--;
+ if (_retainCount === 0)
+ [self dealloc];
+ else if (OBJJ_ZOMBIE_DETECTION && _retainCount < 0)
+ throw ("Released a zombie object: "+self);
}
/*!
@@ -535,3 +542,5 @@ objj_class.prototype.toString = objj_object.prototype.toString = function()
else
return String(this) + " (-description not implemented)";
}
+
+@import "CPAutoreleasePool.j"
View
2 Foundation/CPRunLoop.j
@@ -73,7 +73,7 @@ var _CPRunLoopPerformPool = [],
return perform;
}
- return [[self alloc] initWithSelector:aSelector target:aTarget argument:anArgument order:anOrder modes:modes];
+ return [[[self alloc] initWithSelector:aSelector target:aTarget argument:anArgument order:anOrder modes:modes] autorelease];
}
- (id)initWithSelector:(SEL)aSelector target:(SEL)aTarget argument:(id)anArgument order:(unsigned)anOrder modes:(CPArray)modes
View
12 Foundation/CPSet.j
@@ -45,7 +45,7 @@
*/
+ (id)set
{
- return [[self alloc] init];
+ return [[[self alloc] init] autorelease];
}
/*
@@ -54,7 +54,7 @@
*/
+ (id)setWithArray:(CPArray)array
{
- return [[self alloc] initWithArray:array];
+ return [[[self alloc] initWithArray:array] autorelease];
}
/*
@@ -63,7 +63,7 @@
*/
+ (id)setWithObject:(id)anObject
{
- return [[self alloc] initWithArray:[anObject]];
+ return [[[self alloc] initWithArray:[anObject]] autorelease];
}
/*
@@ -73,7 +73,7 @@
*/
+ (id)setWithObjects:(id)objects count:(unsigned)count
{
- return [[self alloc] initWithObjects:objects count:count];
+ return [[[self alloc] initWithObjects:objects count:count] autorelease];
}
/*
@@ -90,7 +90,7 @@
for(; i < argLength && ((argument = arguments[i]) !== nil); ++i)
[set addObject:argument];
- return set;
+ return [set autorelease];
}
/*
@@ -99,7 +99,7 @@
*/
+ (id)setWithSet:(CPSet)set
{
- return [[self alloc] initWithSet:set];
+ return [[[self alloc] initWithSet:set] autorelease];
}
/*
View
2 Foundation/CPSortDescriptor.j
@@ -78,7 +78,7 @@ CPOrderedDescending = 1;
+ (id)sortDescriptorWithKey:(CPString)aKey ascending:(BOOL)isAscending selector:(SEL)aSelector
{
- return [[self alloc] initWithKey:aKey ascending:isAscending selector:aSelector];
+ return [[[self alloc] initWithKey:aKey ascending:isAscending selector:aSelector] autorelease];
}
/*!
View
1 Foundation/CPString.j
@@ -769,3 +769,4 @@ var CPStringRegexSpecialCharacters = [
@end
String.prototype.isa = CPString;
+String.prototype._retainCount = Infinity;
View
12 Foundation/CPTimer.j
@@ -48,7 +48,7 @@
*/
+ (CPTimer)scheduledTimerWithTimeInterval:(CPTimeInterval)seconds invocation:(CPInvocation)anInvocation repeats:(BOOL)shouldRepeat
{
- var timer = [[self alloc] initWithFireDate:[CPDate dateWithTimeIntervalSinceNow:seconds] interval:seconds invocation:anInvocation repeats:shouldRepeat];
+ var timer = [[[self alloc] initWithFireDate:[CPDate dateWithTimeIntervalSinceNow:seconds] interval:seconds invocation:anInvocation repeats:shouldRepeat] autorelease];
//add to the runloop
[[CPRunLoop currentRunLoop] addTimer:timer forMode:CPDefaultRunLoopMode];
@@ -61,7 +61,7 @@
*/
+ (CPTimer)scheduledTimerWithTimeInterval:(CPTimeInterval)seconds target:(id)aTarget selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)shouldRepeat
{
- var timer = [[self alloc] initWithFireDate:[CPDate dateWithTimeIntervalSinceNow:seconds] interval:seconds target:aTarget selector:aSelector userInfo:userInfo repeats:shouldRepeat]
+ var timer = [[[self alloc] initWithFireDate:[CPDate dateWithTimeIntervalSinceNow:seconds] interval:seconds target:aTarget selector:aSelector userInfo:userInfo repeats:shouldRepeat] autorelease];
//add to the runloop
[[CPRunLoop currentRunLoop] addTimer:timer forMode:CPDefaultRunLoopMode];
@@ -74,7 +74,7 @@
*/
+ (CPTimer)scheduledTimerWithTimeInterval:(CPTimeInterval)seconds callback:(Function)aFunction repeats:(BOOL)shouldRepeat
{
- var timer = [[self alloc] initWithFireDate:[CPDate dateWithTimeIntervalSinceNow:seconds] interval:seconds callback:aFunction repeats:shouldRepeat];
+ var timer = [[[self alloc] initWithFireDate:[CPDate dateWithTimeIntervalSinceNow:seconds] interval:seconds callback:aFunction repeats:shouldRepeat] autorelease];
//add to the runloop
[[CPRunLoop currentRunLoop] addTimer:timer forMode:CPDefaultRunLoopMode];
@@ -87,23 +87,23 @@
*/
+ (CPTimer)timerWithTimeInterval:(CPTimeInterval)seconds invocation:(CPInvocation)anInvocation repeats:(BOOL)shouldRepeat
{
- return [[self alloc] initWithFireDate:[CPDate dateWithTimeIntervalSinceNow:seconds] interval:seconds invocation:anInvocation repeats:shouldRepeat];
+ return [[[self alloc] initWithFireDate:[CPDate dateWithTimeIntervalSinceNow:seconds] interval:seconds invocation:anInvocation repeats:shouldRepeat] autorelease];
}
/*!
Returns a new NSTimer that, when added to a run loop, will fire after seconds.
*/
+ (CPTimer)timerWithTimeInterval:(CPTimeInterval)seconds target:(id)aTarget selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)shouldRepeat
{
- return [[self alloc] initWithFireDate:[CPDate dateWithTimeIntervalSinceNow:seconds] interval:seconds target:aTarget selector:aSelector userInfo:userInfo repeats:shouldRepeat];
+ return [[[self alloc] initWithFireDate:[CPDate dateWithTimeIntervalSinceNow:seconds] interval:seconds target:aTarget selector:aSelector userInfo:userInfo repeats:shouldRepeat] autorelease];
}
/*!
Returns a new NSTimer that, when added to a run loop, will fire after seconds.
*/
+ (CPTimer)timerWithTimeInterval:(CPTimeInterval)seconds callback:(Function)aFunction repeats:(BOOL)shouldRepeat
{
- return [[self alloc] initWithFireDate:[CPDate dateWithTimeIntervalSinceNow:seconds] interval:seconds callback:aFunction repeats:shouldRepeat];
+ return [[[self alloc] initWithFireDate:[CPDate dateWithTimeIntervalSinceNow:seconds] interval:seconds callback:aFunction repeats:shouldRepeat] autorelease];
}
/*!
View
2 Foundation/CPURL.j
@@ -55,7 +55,7 @@ CPURLCustomIconKey = @"CPURLCustomIconKey";
+ (id)URLWithString:(CPString)URLString
{
- return [[self alloc] initWithString:URLString];
+ return [[[self alloc] initWithString:URLString] autorelease];
}
- (id)initWithString:(CPString)URLString relativeToURL:(CPURL)aBaseURL
View
2 Foundation/CPURLConnection.j
@@ -128,7 +128,7 @@ var CPURLConnectionDelegate = nil;
*/
+ (CPURLConnection)connectionWithRequest:(CPURLRequest)aRequest delegate:(id)aDelegate
{
- return [[self alloc] initWithRequest:aRequest delegate:aDelegate];
+ return [[[self alloc] initWithRequest:aRequest delegate:aDelegate] autorelease];
}
/*
View
2 Foundation/CPURLRequest.j
@@ -48,7 +48,7 @@
*/
+ (id)requestWithURL:(CPURL)aURL
{
- return [[CPURLRequest alloc] initWithURL:aURL];
+ return [[[CPURLRequest alloc] initWithURL:aURL] autorelease];
}
/*!
View
2 Foundation/CPUndoManager.j
@@ -71,7 +71,7 @@ var _CPUndoGroupingPool = [],
return grouping;
}
- return [[self alloc] initWithParent:anUndoGrouping];
+ return [[[self alloc] initWithParent:anUndoGrouping] autorelease];
}
- (id)initWithParent:(_CPUndoGrouping)anUndoGrouping
View
2 Foundation/CPValue.j
@@ -43,7 +43,7 @@
*/
+ (id)valueWithJSObject:(JSObject)aJSObject
{
- return [[self alloc] initWithJSObject:aJSObject];
+ return [[[self alloc] initWithJSObject:aJSObject] autorelease];
}
/*!
View
1 Foundation/Foundation.j
@@ -20,6 +20,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+@import "CPAutoreleasePool.j"
@import "CPArray.j"
@import "CPBundle.j"
@import "CPCoder.j"
View
4 Objective-J/CFBundle.js
@@ -57,6 +57,10 @@ GLOBAL(CFBundle) = function(/*CFURL|String*/ aURL)
this._infoDictionary = new CFDictionary();
this._eventDispatcher = new EventDispatcher(this);
+
+ this._UID = objj_generateObjectUID();
+ this._retainCount = 1;
+ OBJJ_MEMORY_TABLE[this._UID] = this;
}
DISPLAY_NAME(CFBundle);
View
4 Objective-J/CFData.js
@@ -31,6 +31,10 @@ GLOBAL(CFData) = function()
this._bytes = NULL;
this._base64 = NULL;
+
+ this._UID = objj_generateObjectUID();
+ this._retainCount = 1;
+ OBJJ_MEMORY_TABLE[this._UID] = this;
}
CFData.prototype.propertyList = function()
View
2 Objective-J/CFDictionary.js
@@ -26,6 +26,8 @@ GLOBAL(CFDictionary) = function(/*CFDictionary*/ aDictionary)
this._count = 0;
this._buckets = { };
this._UID = objj_generateObjectUID();
+ this._retainCount = 1;
+ OBJJ_MEMORY_TABLE[this._UID] = this;
}
var indexOf = Array.prototype.indexOf,
View
2 Objective-J/CFURL.js
@@ -199,6 +199,8 @@ GLOBAL(CFURL) = function(/*CFURL|String*/ aURL, /*CFURL*/ aBaseURL)
}
this._UID = objj_generateObjectUID();
+ this._retainCount = 1;
+ OBJJ_MEMORY_TABLE[this._UID] = this;
this._string = aURL;
this._baseURL = aBaseURL;
View
5 Objective-J/Constants.js
@@ -73,3 +73,8 @@ GLOBAL(PI_2) = Math.PI / 2.0;
GLOBAL(SQRT1_2) = Math.SQRT1_2;
GLOBAL(SQRT2) = Math.SQRT2;
+
+GLOBAL(OBJJ_MEMORY_TABLE) = [];
+
+GLOBAL($) = function(pointer) { return OBJJ_MEMORY_TABLE[pointer]; }
+GLOBAL($$) = function(object) { return object._UID; }
View
3 Objective-J/Debug.js
@@ -217,3 +217,6 @@ GLOBAL(objj_debug_typecheck) = function(expectedType, object)
throw ("expected=" + expectedType + ", actual=" + actualType);
}
+
+if (typeof window.OBJJ_ZOMBIE_DETECTION === "undefined")
+ OBJJ_ZOMBIE_DETECTION = false;
View
5 Objective-J/Runtime.js
@@ -392,6 +392,8 @@ GLOBAL(class_createInstance) = function(/*Class*/ aClass)
object.isa = aClass;
object._UID = objj_generateObjectUID();
+ object._retainCount = 1;
+ OBJJ_MEMORY_TABLE[object._UID] = object;
return object;
}
@@ -514,6 +516,9 @@ GLOBAL(objj_msgSend) = function(/*id*/ aReceiver, /*SEL*/ aSelector)
if (aReceiver == nil)
return nil;
+ if (OBJJ_ZOMBIE_DETECTION && typeof aReceiver._retainCount !== "undefined" && aReceiver._retainCount < 1 && $($$(aReceiver)) !== aReceiver)
+ throw ("Sending a message to a zombie object: "+$$(aReceiver));
+
var isa = aReceiver.isa;
CLASS_GET_METHOD_IMPLEMENTATION(var implementation, isa, aSelector);

0 comments on commit 6678bba

Please sign in to comment.