Permalink
Browse files

Fixed pointer leak (Test 49)

  • Loading branch information...
1 parent 71c1c7f commit 735de68a9ec404fdeb999ba1897e2392ab5cc572 @parmanoir committed Aug 7, 2011
View
8 JSCocoa/JSCocoaController.h
@@ -114,9 +114,11 @@ typedef struct JSValueRefAndContextRef JSValueRefAndContextRef;
- (NSString*)expandJSMacros:(NSString*)script path:(NSString*)path;
- (NSString*)expandJSMacros:(NSString*)script path:(NSString*)path errors:(NSMutableArray*)array;
- (BOOL)isSyntaxValid:(NSString*)script error:(NSString**)error;
-- (BOOL)setObject:(id)object withName:(id)name;
-- (BOOL)setObject:(id)object withName:(id)name attributes:(JSPropertyAttributes)attributes;
-- (BOOL)removeObjectWithName:(id)name;
+- (BOOL)setObject:(id)object withName:(NSString*)name;
+- (BOOL)setObject:(id)object withName:(NSString*)name attributes:(JSPropertyAttributes)attributes;
+- (BOOL)setObjectNoRetain:(id)object withName:(NSString*)name attributes:(JSPropertyAttributes)attributes;
+- (id)objectWithName:(NSString*)name;
+- (BOOL)removeObjectWithName:(NSString*)name;
// Get ObjC and raw values from Javascript
- (id)unboxJSValueRef:(JSValueRef)jsValue;
- (BOOL)toBool:(JSValueRef)value;
View
133 JSCocoa/JSCocoaController.m
@@ -135,7 +135,7 @@ @implementation JSCocoaController
//
- (id)initWithGlobalContext:(JSGlobalContextRef)_ctx
{
- NSLog(@"JSCocoa : %p spawning with context %p", self, _ctx);
+// NSLog(@"JSCocoa : %p spawning with context %p", self, _ctx);
self = [super init];
controllerCount++;
@@ -258,15 +258,7 @@ - (id)initWithGlobalContext:(JSGlobalContextRef)_ctx
[BurksPool setJSFunctionHash:jsFunctionHash];
#endif
// Create a reference to ourselves, and make it read only, don't enum, don't delete
- [self setObject:self withName:@"__jsc__" attributes:kJSPropertyAttributeReadOnly|kJSPropertyAttributeDontEnum|kJSPropertyAttributeDontDelete];
- // Get reference back and set it to no retain
- JSValueRef jsSelf = [self evalJSString:@"__jsc__"];
- JSCocoaPrivateObject* private = JSObjectGetPrivate(JSValueToObject(ctx, jsSelf, NULL));
- // Overwrite settings
- [private setObjectNoRetain:self];
- // And discard private's retain
- [self release];
-
+ [self setObjectNoRetain:self withName:@"__jsc__" attributes:kJSPropertyAttributeReadOnly|kJSPropertyAttributeDontEnum|kJSPropertyAttributeDontDelete];
// Load class kit
if (!_ctx)
@@ -315,7 +307,6 @@ - (id)initWithGlobalContext:(JSGlobalContextRef)_ctx
ownsContext = NO;
[JSCocoa updateCustomCallPaths];
- NSLog(@"JSCocoa spawned with context %p", ctx);
return self;
}
@@ -332,7 +323,7 @@ - (id)init
//
- (void)cleanUp
{
- NSLog(@"JSCocoa : %p dying (ownsContext=%d)", self, ownsContext);
+// NSLog(@"JSCocoa : %p dying (ownsContext=%d)", self, ownsContext);
[self setUseSafeDealloc:NO];
// Cleanup if we created the JavascriptCore context.
@@ -344,6 +335,7 @@ - (void)cleanUp
if (ownsContext) {
[self unlinkAllReferences];
JSGarbageCollect(ctx);
+ [self setObjectNoRetain:self withName:@"__jsc__" attributes:kJSPropertyAttributeReadOnly|kJSPropertyAttributeDontEnum|kJSPropertyAttributeDontDelete];
}
controllerCount--;
@@ -393,37 +385,13 @@ - (void)cleanUp
jsClasses = nil;
}
+ [self removeObjectWithName:@"__jsc__"];
if (ownsContext)
JSGlobalContextRelease(ctx);
[boxedObjects release];
}
-- (oneway void)release
-{
- NSLog(@"jsc %p OUT\n***\n%@\n***\n", self, [NSThread callStackSymbols]);
-//NSLog(@"RET!"); return;
- // Each controller adds itself to its Javascript context, therefore retain count will be two when user last calls release.
- // We check for this and clean up references then call GC, which will lower retain count to 1.
- // Use 'useSafeDealloc' to make sure we're not reentering this one-time code block when GC calls release.
- if ([self retainCount] == 2 && useSafeDealloc)
- {
- [self setUseSafeDealloc:NO];
-
- // This will take retain count from 2 to 1, readying this instance for deallocation
- // Only collect if we own the context, has a WebView might be deallocating us while it's collecting its garbage
-
- NSLog(@"COMMENTED RELEASE : need to remove our variable");
-/*
- if (ownsContext) {
- [self unlinkAllReferences];
- [self garbageCollect];
- }
-*/
- }
- [super release];
-}
-
- (void)dealloc
{
[self cleanUp];
@@ -897,31 +865,46 @@ - (id)toObject:(JSValueRef)value
//
// Add/Remove an ObjC object variable to the global context
//
-- (BOOL)setObject:(id)object withName:(id)name attributes:(JSPropertyAttributes)attributes
-{
- JSObjectRef o = [self boxObject:object];
-
+- (BOOL)setObject:(id)object withName:(NSString*)name attributes:(JSPropertyAttributes)attributes {
+ JSObjectRef o = [self boxObject:object];
// Set
- JSValueRef exception = NULL;
- JSStringRef jsName = JSStringCreateWithUTF8CString([name UTF8String]);
+ JSValueRef exception = NULL;
+ JSStringRef jsName = JSStringCreateWithUTF8CString([name UTF8String]);
JSObjectSetProperty(ctx, JSContextGetGlobalObject(ctx), jsName, o, attributes, &exception);
JSStringRelease(jsName);
- if (exception)
- {
+ if (exception) {
[self callDelegateForException:exception];
return NO;
}
-
return YES;
}
-- (BOOL)setObject:(id)object withName:(id)name
-{
+- (BOOL)setObject:(id)object withName:(NSString*)name {
return [self setObject:object withName:name attributes:kJSPropertyAttributeNone];
}
-- (BOOL)removeObjectWithName:(id)name
+- (BOOL)setObjectNoRetain:(id)object withName:(NSString*)name attributes:(JSPropertyAttributes)attributes {
+ if (![self setObject:self withName:name attributes:attributes])
+ return NO;
+ // Get reference back and set it to no retain
+ JSValueRef jsSelf = [self evalJSString:name];
+ JSCocoaPrivateObject* private = JSObjectGetPrivate(JSValueToObject(ctx, jsSelf, NULL));
+ // Overwrite settings
+ [private setObjectNoRetain:self];
+ // And discard private's retain
+ [self release];
+
+ return YES;
+}
+
+- (id)objectWithName:(NSString*)name {
+ JSValueRef jsSelf = [self evalJSString:name];
+ return [self toObject:jsSelf];
+}
+
+
+- (BOOL)removeObjectWithName:(NSString*)name
{
JSValueRef exception = NULL;
// Delete
@@ -3265,7 +3248,9 @@ static void jsCocoaObject_initialize(JSContextRef ctx, JSObjectRef object)
//
static void jsCocoaObject_finalize(JSObjectRef object)
{
- // if dealloc is overloaded, releasing now will trigger JS code and fail
+// NSLog(@"finalizing %p", object);
+
+ // If dealloc is overloaded, releasing now will trigger JS code and fail
// As we're being called by GC, KJS might assert() in operationInProgress == NoOperation
JSCocoaPrivateObject* private = JSObjectGetPrivate(object);
@@ -3285,50 +3270,32 @@ static void jsCocoaObject_finalize(JSObjectRef object)
// If a boxed object is being destroyed, remove it from the cache
//
id boxedObject = [private object];
- if (boxedObject)
- {
-// id key = [NSString stringWithFormat:@"%p", boxedObject];
- // Object may have been already deallocated
-// id existingBoxedObject = [boxedObjects objectForKey:key];
-// id existingBoxedObject = [jsc boxedObject];
-// if (existingBoxedObject)
- if ([jsc isObjectBoxed:boxedObject])
- {
+ if (boxedObject) {
+ if ([jsc isObjectBoxed:boxedObject]) {
// Safe dealloc ?
- if ([boxedObject retainCount] == 1)
- {
- if ([boxedObject respondsToSelector:@selector(safeDealloc)])
- {
+ if ([boxedObject retainCount] == 1) {
+ if ([boxedObject respondsToSelector:@selector(safeDealloc)]) {
jsc = NULL;
object_getInstanceVariable(boxedObject, "__jsCocoaController", (void**)&jsc);
// Call safeDealloc if enabled (will be disabled upon last JSCocoaController release, to make sure the )
- if (jsc)
- {
+ if (jsc) {
if ([jsc useSafeDealloc])
[jsc performSelector:@selector(safeDeallocInstance:) withObject:boxedObject afterDelay:0];
- }
- else NSLog(@"safeDealloc could not find the context attached to %@.%p - allocate this object with instance, or add a Javascript variable to it (obj.hello = 'world')", [boxedObject class], boxedObject);
+ } else
+ NSLog(@"safeDealloc could not find the context attached to %@.%p - allocate this object with instance, or add a Javascript variable to it (obj.hello = 'world')", [boxedObject class], boxedObject);
}
-
}
-// [boxedObjects removeObjectForKey:key];
[jsc deleteBoxOfObject:boxedObject];
}
- else
- {
-// BOOL retainObject = [private retainObject];
-// NSLog(@"finalizing an UNBOXED object (retain=%d)", retainObject);
- }
}
-
+
// Immediate release if dealloc is not overloaded
[private release];
#ifdef __OBJC_GC__
// Mark internal object as collectable
[[NSGarbageCollector defaultCollector] enableCollectorForPointer:private];
#endif
-
}
/*
@@ -3818,21 +3785,20 @@ static JSValueRef jsCocoaObject_getProperty(JSContextRef ctx, JSObjectRef object
BOOL responds = NO;
id methodName = propertyName;
responds = [privateObject respondsToSelector:NSSelectorFromString(propertyName)];
- if (!responds)
- {
+ if (!responds) {
methodName = [NSString stringWithFormat:@"%@:", methodName];
responds = [privateObject respondsToSelector:NSSelectorFromString(methodName)];
}
- if ([privateObject.type isEqualToString:@"rawPointer"] && responds)
+ if (responds)
{
// When calling a method with arguments, this will be used to get the instance on which to call
id callee = privateObject;
- privateObject.object = callee;
- // Box the private object
+ // Retaining the object leaks
+ [privateObject setObjectNoRetain:privateObject];
+
privateObject = [[JSCocoaPrivateObject new] autorelease];
privateObject.object = callee;
privateObject.type = @"@";
- propertyName = methodName;
goto call;
}
}
@@ -4206,7 +4172,8 @@ static JSValueRef jsCocoaObject_callAsFunction_ffi(JSContextRef ctx, JSObjectRef
JSCocoaPrivateObject* thisPrivateObject = JSObjectGetPrivate(thisObject);
// Return an exception if calling on NULL
- if ([thisPrivateObject object] == NULL && !privateObject.xml) return throwException(ctx, exception, @"jsCocoaObject_callAsFunction : call with null object"), NULL;
+ if (thisPrivateObject.object == NULL && !privateObject.xml)
+ return throwException(ctx, exception, @"jsCocoaObject_callAsFunction : call with null object"), NULL;
// Function address
void* callAddress = NULL;
View
1 JSCocoa/JSCocoaFFIArgument.m
@@ -19,6 +19,7 @@
@implementation JSCocoaFFIArgument
+
- (id)init
{
self = [super init];
View
6 JSCocoa/JSCocoaFFIClosure.m
@@ -45,9 +45,6 @@ - (void)cleanUp
JSValueUnprotect(ctx, jsFunction);
[JSCocoaController downJSValueProtectCount];
}
- //
- // A strange crash reporting ??? as the source address is a deleted closure being called (happens with the bindings mechanism)
- //
#if !TARGET_OS_IPHONE
if (munmap(closure, sizeof(closure)) == -1) NSLog(@"ffi closure munmap failed");
#endif
@@ -170,7 +167,6 @@ - (void)calledByClosureWithArgs:(void**)closureArgs returnValue:(void*)returnVal
args[i] = NULL;
[arg toJSValueRef:&args[i] inContext:ctx];
-
[arg release];
}
}
@@ -204,10 +200,8 @@ - (void)calledByClosureWithArgs:(void**)closureArgs returnValue:(void*)returnVal
}
if (effectiveArgumentCount) free(args);
-// if (exception) NSLog(@"%@", [[JSCocoaController controllerFromContext:ctx] formatJSException:exception]);
if (exception)
{
- NSLog(@"throwing");
@throw [NSException exceptionWithName:@"JSCocoa exception"
reason:[[JSCocoaController controllerFromContext:ctx] formatJSException:exception]
userInfo:nil];
View
16 JSCocoa/JSCocoaPrivateObject.h
@@ -21,13 +21,14 @@
// Boxing object
//
// type
-// @ ObjC object
-// struct C struct
-// method ObjC method name
-// rawPointer raw C pointer (_C_PTR)
-// jsFunction Javascript function
-// jsValueRef raw jsvalue
-// externalJSValueRef EXPERIMENTAL from webView
+// @ ObjC object
+// struct C struct
+// method ObjC method name
+// function C function
+// rawPointer raw C pointer (_C_PTR)
+// jsFunction Javascript function
+// jsValueRef raw jsvalue
+// externalJSValueRef jsvalue coming from an external context (eg, a WebView)
//
@interface JSCocoaPrivateObject : NSObject {
@@ -38,7 +39,6 @@
NSString* structureName;
NSString* declaredType;
-// void* ptr;
void* rawPointer;
id object;
View
25 JSCocoa/JSCocoaPrivateObject.m
@@ -94,6 +94,8 @@ - (void)finalize
- (void)setObject:(id)o
{
+// if (object && retainObject)
+// [object release];
object = o;
if (object && [object retainCount] == -1) return;
[object retain];
@@ -110,7 +112,6 @@ - (BOOL)retainObject
return retainObject;
}
-
- (id)object
{
return object;
@@ -201,10 +202,10 @@ - (id)rawPointerEncoding
}
-- (id)description
-{
+- (id)description {
id extra = @"";
- if ([type isEqualToString:@"rawPointer"]) extra = [NSString stringWithFormat:@" (%p) %@", rawPointer, declaredType];
+ if ([type isEqualToString:@"rawPointer"])
+ extra = [NSString stringWithFormat:@" rawPointer=%p declaredType=%@", rawPointer, declaredType];
return [NSString stringWithFormat:@"<%@: %p holding %@%@>",
[self class],
self,
@@ -213,21 +214,19 @@ - (id)description
];
}
-+ (id)description
-{
++ (id)description {
return @"<JSCocoaPrivateObject class>";
}
-- (id)dereferencedObject
-{
- if (![type isEqualToString:@"rawPointer"] || !rawPointer) return nil;
+- (id)dereferencedObject {
+ if (![type isEqualToString:@"rawPointer"] || !rawPointer)
+ return nil;
return *(void**)rawPointer;
}
-- (BOOL)referenceObject:(id)o
-{
- if (![type isEqualToString:@"rawPointer"]) return NO;
-// void* v = *(void**)rawPointer;
+- (BOOL)referenceObject:(id)o {
+ if (![type isEqualToString:@"rawPointer"])
+ return NO;
*(id*)rawPointer = o;
return YES;
}
View
0 Tests/47 ObjJ syntax super.js → Tests/! stock/47 ObjJ syntax super.js
File renamed without changes.
View
8 Tests/! stock/49 out pointer.js → Tests/49 out pointer.js
@@ -9,7 +9,6 @@
- (BOOL)someMethodReturningAnError:(NSError**)outError
{
// log('outError=' + outError)
-
// Init a memory buffer from pointer
var b = new memoryBuffer('^')
b[0] = outError
@@ -34,7 +33,7 @@
outError.referenceObject(error)
var readBackError4 = outError.dereferencedObject
if (readBackError4 != error) throw 'NSError** read/write failed (4)'
-
+
return res
}
@@ -44,14 +43,13 @@
var o = outError.dereferencedObject
if (o != null) throw 'NSError** read/write failed (5)'
-
// Init a memory buffer from pointer
var b = new memoryBuffer('^')
b[0] = outError
var readBackError = [b dereferenceObjectAtIndex:0]
if (readBackError != null) throw 'NSError** read/write failed (6)'
-
+
return true
}
@@ -139,7 +137,7 @@
if (actualSig != expectedSig) throw 'NSError** signature failed — expected ' + expectedSig + ', got ' + actualSig
-
+ oa = null
o = null
View
157 Tests/Resources/inited from WebView.nib/designable.nib
@@ -89,6 +89,7 @@
</object>
<string key="NSFrameSize">{400, 400}</string>
<reference key="NSSuperview" ref="1006"/>
+ <reference key="NSWindow"/>
<reference key="NSNextKeyView"/>
<string key="FrameName"/>
<string key="GroupName"/>
@@ -116,6 +117,7 @@
</object>
<string key="NSFrameSize">{400, 400}</string>
<reference key="NSSuperview"/>
+ <reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="444077104"/>
</object>
<string key="NSScreenRect">{{0, 0}, {1920, 1058}}</string>
@@ -232,7 +234,160 @@
<nil key="sourceID"/>
<int key="maxID">6</int>
</object>
- <object class="IBClassDescriber" key="IBDocument.Classes"/>
+ <object class="IBClassDescriber" key="IBDocument.Classes">
+ <object class="NSMutableArray" key="referencedPartialClassDescriptions">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBPartialClassDescription">
+ <string key="className">ApplicationController</string>
+ <string key="superclassName">NSObject</string>
+ <object class="NSMutableDictionary" key="actions">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>displayTestsWindow:</string>
+ <string>eval:</string>
+ <string>garbageCollect:</string>
+ <string>logBoxedObjects:</string>
+ <string>logInstanceStats:</string>
+ <string>runJSTests:</string>
+ <string>runJSTestsContinuously:</string>
+ <string>runSimpleTestFile:</string>
+ <string>stopContinuousJSTestsRun:</string>
+ <string>unlinkAllReferences:</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>id</string>
+ <string>id</string>
+ <string>id</string>
+ <string>id</string>
+ <string>id</string>
+ <string>id</string>
+ <string>id</string>
+ <string>id</string>
+ <string>id</string>
+ <string>id</string>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="actionInfosByName">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>displayTestsWindow:</string>
+ <string>eval:</string>
+ <string>garbageCollect:</string>
+ <string>logBoxedObjects:</string>
+ <string>logInstanceStats:</string>
+ <string>runJSTests:</string>
+ <string>runJSTestsContinuously:</string>
+ <string>runSimpleTestFile:</string>
+ <string>stopContinuousJSTestsRun:</string>
+ <string>unlinkAllReferences:</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBActionInfo">
+ <string key="name">displayTestsWindow:</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ <object class="IBActionInfo">
+ <string key="name">eval:</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ <object class="IBActionInfo">
+ <string key="name">garbageCollect:</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ <object class="IBActionInfo">
+ <string key="name">logBoxedObjects:</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ <object class="IBActionInfo">
+ <string key="name">logInstanceStats:</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ <object class="IBActionInfo">
+ <string key="name">runJSTests:</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ <object class="IBActionInfo">
+ <string key="name">runJSTestsContinuously:</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ <object class="IBActionInfo">
+ <string key="name">runSimpleTestFile:</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ <object class="IBActionInfo">
+ <string key="name">stopContinuousJSTestsRun:</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ <object class="IBActionInfo">
+ <string key="name">unlinkAllReferences:</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="outlets">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>evalResult</string>
+ <string>evalText</string>
+ <string>textField</string>
+ <string>webViewUsedAsContextSource</string>
+ <string>window</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>NSTextField</string>
+ <string>NSTextField</string>
+ <string>id</string>
+ <string>id</string>
+ <string>id</string>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="toOneOutletInfosByName">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>evalResult</string>
+ <string>evalText</string>
+ <string>textField</string>
+ <string>webViewUsedAsContextSource</string>
+ <string>window</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBToOneOutletInfo">
+ <string key="name">evalResult</string>
+ <string key="candidateClassName">NSTextField</string>
+ </object>
+ <object class="IBToOneOutletInfo">
+ <string key="name">evalText</string>
+ <string key="candidateClassName">NSTextField</string>
+ </object>
+ <object class="IBToOneOutletInfo">
+ <string key="name">textField</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ <object class="IBToOneOutletInfo">
+ <string key="name">webViewUsedAsContextSource</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ <object class="IBToOneOutletInfo">
+ <string key="name">window</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ </object>
+ </object>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">./Classes/ApplicationController.h</string>
+ </object>
+ </object>
+ </object>
+ </object>
<int key="IBDocument.localizationMode">0</int>
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaFramework</string>
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
View
BIN Tests/Resources/inited from WebView.nib/keyedobjects.nib
Binary file not shown.
View
2 TestsRunner/ApplicationController.h
@@ -33,6 +33,8 @@
BOOL runningContinuously;
// If we cycle context each time, we can test bindings each time.
BOOL cyclingContext;
+
+ NSInteger testCount; // successful test count
}
View
55 TestsRunner/ApplicationController.m
@@ -56,21 +56,23 @@ - (void)applicationWillTerminate:(NSNotification *)notification
[self disposeShadowBindingsClasses];
- // Retain count is 2 because a variable named __jsc__ holds the ObjC object in the Javascript context
- if ([jsc retainCount] == 2) NSLog(@"willTerminate %@ JSCocoa retainCount=%lu (OK)", jsc, [jsc retainCount]);
+ // Retain count should be 1, the variable named __jsc__ holding the JSCocoa object does not retain it
+ if ([jsc retainCount] == 1) NSLog(@"willTerminate %@ JSCocoa retainCount=%lu (OK)", jsc, [jsc retainCount]);
else NSLog(@"willTerminate %@ JSCocoa retainCount=%lu", jsc, [jsc retainCount]);
// Check if JSCocoa can be released (retainCount got down to 1)
// Won't work under ObjC GC
#ifndef __OBJC_GC__
// Must be 2 with new release method
- if ([jsc retainCount] && [jsc retainCount] != 2) NSLog(@"***Invalid JSCocoa retainCount***");
+ // ^fixed, the instance set in the js context is not released.
+// if ([jsc retainCount] && [jsc retainCount] != 2)
+// NSLog(@"***Invalid JSCocoa retainCount***");
#endif
[jsc release];
id path = [NSString stringWithFormat:@"%@/Contents/Resources/Tests/! stock", [[NSBundle mainBundle] bundlePath]];
id files = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:nil];
- if ([files count]) NSLog(@"***warning, skipping tests in ./!stock***"), NSLog(@"%@", files);
+ if ([files count]) NSLog(@"***Skipping tests in ./!stock***"), NSLog(@"%@", files);
#ifdef __OBJC_GC__
if (![[NSGarbageCollector defaultCollector] isEnabled]) NSLog(@"***GC running but disabled***");
#endif
@@ -114,7 +116,7 @@ - (IBAction)_runJSTests:(id)sender {
id path = [[NSBundle mainBundle] bundlePath];
path = [NSString stringWithFormat:@"%@/Contents/Resources/Tests", path];
// NSLog(@"Run %d from %@", runCount, path);
- int testCount = 0;
+ testCount = 0;
if (test_unit)
testCount = [jsc runTests:path];
BOOL b = !!testCount;
@@ -968,45 +970,16 @@ - (void)finishTest37:(BOOL)b
[jsc callJSFunctionNamed:@"completeDelayedTest" withArguments:@"37 init from webview", [NSNumber numberWithInt:1], nil];
- NSLog(@"JSC2 not deallocated");
- NSLog(@"unlinking...");
+ // WebView context cleanup
[jsc2 unlinkAllReferences];
- NSLog(@"collecting...");
[jsc2 garbageCollect];
- NSLog(@"releasing...");
[jsc2 release];
jsc2 = nil;
-
- NSLog(@"JSC2 DEALLOCATED");
-
-/*
- NSLog(@"COMMENTED test 37 !");
-// return;
- NSLog(@"jsc2 rc=%lu (%p)", [jsc2 retainCount], self);
- NSLog(@"get1 %@", [jsc2 eval:@"__jsc__"]);
-// b = [jsc2 removeObjectWithName:@"__jsc__"];
- [jsc2 garbageCollect];
- NSLog(@"jsc2 rc=%lu (POST REMOVE %d)", [jsc2 retainCount], b);
- NSLog(@"get2 %@", [jsc2 eval:@"__jsc__"]);
- [jsc2 release];
-*/
- NSLog(@"jsc2 rc=%lu (%p)", [jsc2 retainCount], self);
- [topObjects release];
- NSLog(@"jsc2 rc=%lu (%p)", [jsc2 retainCount], self);
+ // WebView nib cleanup
+ [topObjects release];
topObjects = nil;
- jsc2 = nil;
-
- NSLog(@"***COMMENTED test 37 !");
-
- NSLog(@"AND, commented test37 html");
-/*
- NSLog(@"****************");
- [JSCocoa logInstanceStats];
- [JSCocoa logBoxedObjects];
- NSLog(@"****************");
-*/
}
BOOL bindingsAlreadyTested = NO;
@@ -1017,10 +990,14 @@ - (BOOL)bindingsAlreadyTested2 { if (cyclingContext) return NO; return bindin
- (void)setBindingsAlreadyTested:(BOOL)b { bindingsAlreadyTested = b; }
- (void)setBindingsAlreadyTested2:(BOOL)b { bindingsAlreadyTested2 = b; }
-- (void)allTestsRanOK
+//- (void)allTestsRanOK
+- (void)delayedTestsRan:(NSInteger)successful outof:(NSInteger)total
{
[window makeKeyAndOrderFront:nil];
- [textField setStringValue:@"All tests ran OK"];
+ if (successful == total && testCount)
+ [textField setStringValue:[NSString stringWithFormat:@"All tests ran OK (%d tests, %d delayed)", testCount, total]];
+ else
+ [textField setStringValue:[NSString stringWithFormat:@"Tests failed (%d tests, %d delayed)", testCount, total]];
}
- (IBAction)displayTestsWindow:(id)sender {
View
31,093 ....xcodeproj/project.xcworkspace/xcuserdata/mini.xcuserdatad/UserInterfaceState.xcuserstate
17,227 additions, 13,866 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
View
6 ...unner/TestsRunner.xcodeproj/xcuserdata/mini.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist
@@ -9,11 +9,11 @@
continueAfterRunningActions = "No"
isPathRelative = "1"
filePath = "ApplicationController.m"
- timestampString = "334080414.751994"
+ timestampString = "334261163.886137"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
- startingLineNumber = "269"
- endingLineNumber = "269"
+ startingLineNumber = "271"
+ endingLineNumber = "271"
landmarkName = "-validateMenuItem:"
landmarkType = "5">
</FileBreakpoint>
View
2 TestsRunner/test.js
@@ -40,7 +40,7 @@
if (delayedTestPendingCount() == 0)
{
log('All pending tests ran, ' + delayedTestSuccessCount() + '/' + delayedTestCount() + ' successful')
- NSApplication.sharedApplication.delegate.allTestsRanOK
+ NSApplication.sharedApplication.delegate.delayedTestsRan_outof_(delayedTestSuccessCount(), delayedTestCount())
}
}

0 comments on commit 735de68

Please sign in to comment.