Skip to content
This repository
Browse code

Fixed pointer leak (Test 49)

  • Loading branch information...
commit 735de68a9ec404fdeb999ba1897e2392ab5cc572 1 parent 71c1c7f
Patrick Geiller authored August 07, 2011
8  JSCocoa/JSCocoaController.h
@@ -114,9 +114,11 @@ typedef struct	JSValueRefAndContextRef JSValueRefAndContextRef;
114 114
 - (NSString*)expandJSMacros:(NSString*)script path:(NSString*)path;
115 115
 - (NSString*)expandJSMacros:(NSString*)script path:(NSString*)path errors:(NSMutableArray*)array;
116 116
 - (BOOL)isSyntaxValid:(NSString*)script error:(NSString**)error;
117  
-- (BOOL)setObject:(id)object withName:(id)name;
118  
-- (BOOL)setObject:(id)object withName:(id)name attributes:(JSPropertyAttributes)attributes;
119  
-- (BOOL)removeObjectWithName:(id)name;
  117
+- (BOOL)setObject:(id)object withName:(NSString*)name;
  118
+- (BOOL)setObject:(id)object withName:(NSString*)name attributes:(JSPropertyAttributes)attributes;
  119
+- (BOOL)setObjectNoRetain:(id)object withName:(NSString*)name attributes:(JSPropertyAttributes)attributes;
  120
+- (id)objectWithName:(NSString*)name;
  121
+- (BOOL)removeObjectWithName:(NSString*)name;
120 122
 // Get ObjC and raw values from Javascript
121 123
 - (id)unboxJSValueRef:(JSValueRef)jsValue;
122 124
 - (BOOL)toBool:(JSValueRef)value;
133  JSCocoa/JSCocoaController.m
@@ -135,7 +135,7 @@ @implementation JSCocoaController
135 135
 //
136 136
 - (id)initWithGlobalContext:(JSGlobalContextRef)_ctx
137 137
 {
138  
-	NSLog(@"JSCocoa : %p spawning with context %p", self, _ctx);
  138
+//	NSLog(@"JSCocoa : %p spawning with context %p", self, _ctx);
139 139
 	self	= [super init];
140 140
 	controllerCount++;
141 141
 
@@ -258,15 +258,7 @@ - (id)initWithGlobalContext:(JSGlobalContextRef)_ctx
258 258
 	[BurksPool setJSFunctionHash:jsFunctionHash];
259 259
 #endif
260 260
 	// Create a reference to ourselves, and make it read only, don't enum, don't delete
261  
-	[self setObject:self withName:@"__jsc__" attributes:kJSPropertyAttributeReadOnly|kJSPropertyAttributeDontEnum|kJSPropertyAttributeDontDelete];
262  
-	// Get reference back and set it to no retain
263  
-	JSValueRef jsSelf = [self evalJSString:@"__jsc__"];
264  
-	JSCocoaPrivateObject* private = JSObjectGetPrivate(JSValueToObject(ctx, jsSelf, NULL));
265  
-	// Overwrite settings
266  
-	[private setObjectNoRetain:self];
267  
-	// And discard private's retain
268  
-	[self release];
269  
-
  261
+	[self setObjectNoRetain:self withName:@"__jsc__" attributes:kJSPropertyAttributeReadOnly|kJSPropertyAttributeDontEnum|kJSPropertyAttributeDontDelete];
270 262
 
271 263
 	// Load class kit
272 264
 	if (!_ctx)
@@ -315,7 +307,6 @@ - (id)initWithGlobalContext:(JSGlobalContextRef)_ctx
315 307
 	ownsContext		= NO;
316 308
 
317 309
 	[JSCocoa updateCustomCallPaths];
318  
-	NSLog(@"JSCocoa spawned with context %p", ctx);
319 310
 	return	self;
320 311
 }
321 312
 
@@ -332,7 +323,7 @@ - (id)init
332 323
 //
333 324
 - (void)cleanUp
334 325
 {
335  
-	NSLog(@"JSCocoa : %p dying (ownsContext=%d)", self, ownsContext);
  326
+//	NSLog(@"JSCocoa : %p dying (ownsContext=%d)", self, ownsContext);
336 327
 	[self setUseSafeDealloc:NO];
337 328
 
338 329
 	// Cleanup if we created the JavascriptCore context.
@@ -344,6 +335,7 @@ - (void)cleanUp
344 335
 	if (ownsContext) {
345 336
 		[self unlinkAllReferences];
346 337
 		JSGarbageCollect(ctx);
  338
+		[self setObjectNoRetain:self withName:@"__jsc__" attributes:kJSPropertyAttributeReadOnly|kJSPropertyAttributeDontEnum|kJSPropertyAttributeDontDelete];
347 339
 	}
348 340
     
349 341
 	controllerCount--;
@@ -393,37 +385,13 @@ - (void)cleanUp
393 385
 		jsClasses = nil;
394 386
 	}
395 387
 
  388
+	[self removeObjectWithName:@"__jsc__"];
396 389
 	if (ownsContext)
397 390
 		JSGlobalContextRelease(ctx);	
398 391
 
399 392
 	[boxedObjects release];
400 393
 }
401 394
 
402  
-- (oneway void)release
403  
-{
404  
-	NSLog(@"jsc %p OUT\n***\n%@\n***\n", self, [NSThread callStackSymbols]);
405  
-//NSLog(@"RET!"); return;
406  
-	// Each controller adds itself to its Javascript context, therefore retain count will be two when user last calls release.
407  
-	// We check for this and clean up references then call GC, which will lower retain count to 1.
408  
-	// Use 'useSafeDealloc' to make sure we're not reentering this one-time code block when GC calls release.
409  
-	if ([self retainCount] == 2 && useSafeDealloc)
410  
-	{
411  
-		[self setUseSafeDealloc:NO];
412  
-
413  
-		// This will take retain count from 2 to 1, readying this instance for deallocation
414  
-		//	Only collect if we own the context, has a WebView might be deallocating us while it's collecting its garbage
415  
-		
416  
-		NSLog(@"COMMENTED RELEASE : need to remove our variable");
417  
-/*
418  
-		if (ownsContext) {
419  
-			[self unlinkAllReferences];
420  
-			[self garbageCollect];
421  
-		}
422  
-*/
423  
-	}
424  
-	[super release];
425  
-}
426  
-
427 395
 - (void)dealloc
428 396
 {
429 397
 	[self cleanUp];
@@ -897,31 +865,46 @@ - (id)toObject:(JSValueRef)value
897 865
 //
898 866
 // Add/Remove an ObjC object variable to the global context
899 867
 //
900  
-- (BOOL)setObject:(id)object withName:(id)name attributes:(JSPropertyAttributes)attributes
901  
-{
902  
-	JSObjectRef o = [self boxObject:object];
903  
-
  868
+- (BOOL)setObject:(id)object withName:(NSString*)name attributes:(JSPropertyAttributes)attributes {
  869
+	JSObjectRef o			= [self boxObject:object];
904 870
 	// Set
905  
-	JSValueRef	exception = NULL;
906  
-	JSStringRef	jsName = JSStringCreateWithUTF8CString([name UTF8String]);
  871
+	JSValueRef exception	= NULL;
  872
+	JSStringRef	jsName		= JSStringCreateWithUTF8CString([name UTF8String]);
907 873
 	JSObjectSetProperty(ctx, JSContextGetGlobalObject(ctx), jsName, o, attributes, &exception);
908 874
 	JSStringRelease(jsName);
909 875
 
910  
-	if (exception)	
911  
-	{
  876
+	if (exception) {
912 877
         [self callDelegateForException:exception];
913 878
 		return	NO;
914 879
 	}
915  
-
916 880
 	return	YES;
917 881
 }
918 882
 
919  
-- (BOOL)setObject:(id)object withName:(id)name
920  
-{
  883
+- (BOOL)setObject:(id)object withName:(NSString*)name {
921 884
 	return [self setObject:object withName:name attributes:kJSPropertyAttributeNone];
922 885
 }
923 886
 
924  
-- (BOOL)removeObjectWithName:(id)name
  887
+- (BOOL)setObjectNoRetain:(id)object withName:(NSString*)name attributes:(JSPropertyAttributes)attributes {
  888
+	if (![self setObject:self withName:name attributes:attributes])
  889
+		return NO;
  890
+	// Get reference back and set it to no retain
  891
+	JSValueRef jsSelf = [self evalJSString:name];
  892
+	JSCocoaPrivateObject* private = JSObjectGetPrivate(JSValueToObject(ctx, jsSelf, NULL));
  893
+	// Overwrite settings
  894
+	[private setObjectNoRetain:self];
  895
+	// And discard private's retain
  896
+	[self release];
  897
+	
  898
+	return YES;
  899
+}
  900
+
  901
+- (id)objectWithName:(NSString*)name {
  902
+	JSValueRef jsSelf = [self evalJSString:name];
  903
+	return [self toObject:jsSelf];
  904
+}
  905
+
  906
+
  907
+- (BOOL)removeObjectWithName:(NSString*)name
925 908
 {
926 909
 	JSValueRef	exception = NULL;
927 910
 	// Delete
@@ -3265,7 +3248,9 @@ static void jsCocoaObject_initialize(JSContextRef ctx, JSObjectRef object)
3265 3248
 //
3266 3249
 static void jsCocoaObject_finalize(JSObjectRef object)
3267 3250
 {
3268  
-	// if dealloc is overloaded, releasing now will trigger JS code and fail
  3251
+//	NSLog(@"finalizing %p", object);
  3252
+
  3253
+	// If dealloc is overloaded, releasing now will trigger JS code and fail
3269 3254
 	// As we're being called by GC, KJS might assert() in operationInProgress == NoOperation
3270 3255
 	JSCocoaPrivateObject* private = JSObjectGetPrivate(object);
3271 3256
 	
@@ -3285,42 +3270,25 @@ static void jsCocoaObject_finalize(JSObjectRef object)
3285 3270
 	// If a boxed object is being destroyed, remove it from the cache
3286 3271
 	//
3287 3272
 	id boxedObject = [private object]; 
3288  
-	if (boxedObject)
3289  
-	{
3290  
-//		id key = [NSString stringWithFormat:@"%p", boxedObject];
3291  
-		// Object may have been already deallocated
3292  
-//		id existingBoxedObject = [boxedObjects objectForKey:key];
3293  
-//		id existingBoxedObject = [jsc boxedObject];
3294  
-//		if (existingBoxedObject)
3295  
-		if ([jsc isObjectBoxed:boxedObject])
3296  
-		{
  3273
+	if (boxedObject) {
  3274
+		if ([jsc isObjectBoxed:boxedObject]) {
3297 3275
 			// Safe dealloc ?
3298  
-			if ([boxedObject retainCount] == 1)
3299  
-			{
3300  
-				if ([boxedObject respondsToSelector:@selector(safeDealloc)])
3301  
-				{
  3276
+			if ([boxedObject retainCount] == 1) {
  3277
+				if ([boxedObject respondsToSelector:@selector(safeDealloc)]) {
3302 3278
 					jsc = NULL;
3303 3279
 					object_getInstanceVariable(boxedObject, "__jsCocoaController", (void**)&jsc);
3304 3280
 					// Call safeDealloc if enabled (will be disabled upon last JSCocoaController release, to make sure the )
3305  
-					if (jsc)	
3306  
-					{
  3281
+					if (jsc) {
3307 3282
 						if ([jsc useSafeDealloc])
3308 3283
 							[jsc performSelector:@selector(safeDeallocInstance:) withObject:boxedObject afterDelay:0];
3309  
-					}
3310  
-					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);
  3284
+					} else
  3285
+						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);
3311 3286
 				}
3312  
-				
3313 3287
 			}
3314  
-//			[boxedObjects removeObjectForKey:key];
3315 3288
 			[jsc deleteBoxOfObject:boxedObject];
3316 3289
 		}
3317  
-		else
3318  
-		{
3319  
-//			BOOL retainObject = [private retainObject];
3320  
-//			NSLog(@"finalizing an UNBOXED object (retain=%d)", retainObject);
3321  
-		}
3322 3290
 	}
3323  
-
  3291
+	
3324 3292
 	// Immediate release if dealloc is not overloaded
3325 3293
 	[private release];
3326 3294
 	
@@ -3328,7 +3296,6 @@ static void jsCocoaObject_finalize(JSObjectRef object)
3328 3296
 	// Mark internal object as collectable
3329 3297
 	[[NSGarbageCollector defaultCollector] enableCollectorForPointer:private];
3330 3298
 #endif
3331  
-
3332 3299
 }
3333 3300
 
3334 3301
 /*
@@ -3818,21 +3785,20 @@ static JSValueRef jsCocoaObject_getProperty(JSContextRef ctx, JSObjectRef object
3818 3785
 		BOOL responds = NO;
3819 3786
 		id methodName = propertyName;
3820 3787
 		responds = [privateObject respondsToSelector:NSSelectorFromString(propertyName)];
3821  
-		if (!responds)
3822  
-		{
  3788
+		if (!responds) {
3823 3789
 			methodName = [NSString stringWithFormat:@"%@:", methodName];
3824 3790
 			responds = [privateObject respondsToSelector:NSSelectorFromString(methodName)];
3825 3791
 		}
3826  
-		if ([privateObject.type isEqualToString:@"rawPointer"] && responds)
  3792
+		if (responds)
3827 3793
 		{
3828 3794
 			// When calling a method with arguments, this will be used to get the instance on which to call
3829 3795
 			id callee = privateObject;
3830  
-			privateObject.object = callee;
3831  
-			// Box the private object
  3796
+			// Retaining the object leaks
  3797
+			[privateObject setObjectNoRetain:privateObject];
  3798
+
3832 3799
 			privateObject = [[JSCocoaPrivateObject new] autorelease];
3833 3800
 			privateObject.object = callee;
3834 3801
 			privateObject.type = @"@";
3835  
-			propertyName = methodName;
3836 3802
 			goto call;
3837 3803
 		}
3838 3804
 	}
@@ -4206,7 +4172,8 @@ static JSValueRef jsCocoaObject_callAsFunction_ffi(JSContextRef ctx, JSObjectRef
4206 4172
 	JSCocoaPrivateObject* thisPrivateObject = JSObjectGetPrivate(thisObject);
4207 4173
 
4208 4174
 	// Return an exception if calling on NULL
4209  
-	if ([thisPrivateObject object] == NULL && !privateObject.xml)	return	throwException(ctx, exception, @"jsCocoaObject_callAsFunction : call with null object"), NULL;
  4175
+	if (thisPrivateObject.object == NULL && !privateObject.xml)
  4176
+		return	throwException(ctx, exception, @"jsCocoaObject_callAsFunction : call with null object"), NULL;
4210 4177
 
4211 4178
 	// Function address
4212 4179
 	void* callAddress = NULL;
1  JSCocoa/JSCocoaFFIArgument.m
@@ -19,6 +19,7 @@
19 19
 
20 20
 @implementation JSCocoaFFIArgument
21 21
 
  22
+
22 23
 - (id)init
23 24
 {
24 25
 	self	= [super init];
6  JSCocoa/JSCocoaFFIClosure.m
@@ -45,9 +45,6 @@ - (void)cleanUp
45 45
 		JSValueUnprotect(ctx, jsFunction);
46 46
 		[JSCocoaController downJSValueProtectCount];
47 47
 	}
48  
-	//
49  
-	// A strange crash reporting ??? as the source address is a deleted closure being called (happens with the bindings mechanism)
50  
-	//
51 48
 #if !TARGET_OS_IPHONE
52 49
 	if (munmap(closure, sizeof(closure)) == -1)	NSLog(@"ffi closure munmap failed");
53 50
 #endif
@@ -170,7 +167,6 @@ - (void)calledByClosureWithArgs:(void**)closureArgs returnValue:(void*)returnVal
170 167
 			
171 168
 			args[i] = NULL;
172 169
 			[arg toJSValueRef:&args[i] inContext:ctx];
173  
-			
174 170
 			[arg release];
175 171
 		}
176 172
 	}
@@ -204,10 +200,8 @@ - (void)calledByClosureWithArgs:(void**)closureArgs returnValue:(void*)returnVal
204 200
 	}
205 201
 
206 202
 	if (effectiveArgumentCount)	free(args);
207  
-//	if (exception)	NSLog(@"%@", [[JSCocoaController controllerFromContext:ctx] formatJSException:exception]);
208 203
 	if (exception)
209 204
 	{
210  
-		NSLog(@"throwing");
211 205
 		@throw	[NSException exceptionWithName:@"JSCocoa exception"
212 206
 			reason:[[JSCocoaController controllerFromContext:ctx] formatJSException:exception]
213 207
 			userInfo:nil];
16  JSCocoa/JSCocoaPrivateObject.h
@@ -21,13 +21,14 @@
21 21
 // Boxing object
22 22
 //
23 23
 //	type
24  
-//	@			ObjC object
25  
-//	struct		C struct
26  
-//	method		ObjC method name
27  
-//	rawPointer	raw C pointer (_C_PTR)
28  
-//	jsFunction	Javascript function
29  
-//	jsValueRef	raw jsvalue
30  
-//	externalJSValueRef	EXPERIMENTAL from webView
  24
+//	@					ObjC object
  25
+//	struct				C struct
  26
+//	method				ObjC method name
  27
+//	function			C function
  28
+//	rawPointer			raw C pointer (_C_PTR)
  29
+//	jsFunction			Javascript function
  30
+//	jsValueRef			raw jsvalue
  31
+//	externalJSValueRef	jsvalue coming from an external context (eg, a WebView)
31 32
 //
32 33
 
33 34
 @interface JSCocoaPrivateObject : NSObject {
@@ -38,7 +39,6 @@
38 39
 	NSString*	structureName;
39 40
 	
40 41
 	NSString*	declaredType;
41  
-//	void*		ptr;
42 42
 	void*		rawPointer;
43 43
 
44 44
 	id			object;
25  JSCocoa/JSCocoaPrivateObject.m
@@ -94,6 +94,8 @@ - (void)finalize
94 94
 
95 95
 - (void)setObject:(id)o
96 96
 {
  97
+//	if (object && retainObject)
  98
+//		[object release];
97 99
 	object = o;
98 100
 	if (object && [object retainCount] == -1)	return;
99 101
 	[object retain];
@@ -110,7 +112,6 @@ - (BOOL)retainObject
110 112
 	return	retainObject;
111 113
 }
112 114
 
113  
-
114 115
 - (id)object
115 116
 {
116 117
 	return	object;
@@ -201,10 +202,10 @@ - (id)rawPointerEncoding
201 202
 }
202 203
 
203 204
 
204  
-- (id)description
205  
-{
  205
+- (id)description {
206 206
 	id extra = @"";
207  
-	if ([type isEqualToString:@"rawPointer"]) extra = [NSString stringWithFormat:@" (%p) %@", rawPointer, declaredType];
  207
+	if ([type isEqualToString:@"rawPointer"]) 
  208
+		extra = [NSString stringWithFormat:@" rawPointer=%p declaredType=%@", rawPointer, declaredType];
208 209
 	return	[NSString stringWithFormat:@"<%@: %p holding %@%@>",
209 210
 				[self class], 
210 211
 				self, 
@@ -213,21 +214,19 @@ - (id)description
213 214
 				];
214 215
 }
215 216
 
216  
-+ (id)description
217  
-{
  217
++ (id)description {
218 218
 	return @"<JSCocoaPrivateObject class>";
219 219
 }
220 220
 
221  
-- (id)dereferencedObject
222  
-{
223  
-	if (![type isEqualToString:@"rawPointer"] || !rawPointer)	return nil;
  221
+- (id)dereferencedObject {
  222
+	if (![type isEqualToString:@"rawPointer"] || !rawPointer)	
  223
+		return nil;
224 224
 	return *(void**)rawPointer;
225 225
 }
226 226
 
227  
-- (BOOL)referenceObject:(id)o
228  
-{
229  
-	if (![type isEqualToString:@"rawPointer"])	return NO;
230  
-//	void* v = *(void**)rawPointer;
  227
+- (BOOL)referenceObject:(id)o {
  228
+	if (![type isEqualToString:@"rawPointer"])	
  229
+		return NO;
231 230
 	*(id*)rawPointer = o;
232 231
 	return	YES;
233 232
 }
0  Tests/47 ObjJ syntax super.js → Tests/! stock/47 ObjJ syntax super.js
File renamed without changes
8  Tests/! stock/49 out pointer.js → Tests/49 out pointer.js
@@ -9,7 +9,6 @@
9 9
 		- (BOOL)someMethodReturningAnError:(NSError**)outError
10 10
 		{
11 11
 //			log('outError=' + outError)
12  
-		
13 12
 			// Init a memory buffer from pointer
14 13
 			var b = new memoryBuffer('^')
15 14
 			b[0] = outError
@@ -34,7 +33,7 @@
34 33
 			outError.referenceObject(error)
35 34
 			var readBackError4 = outError.dereferencedObject
36 35
 			if (readBackError4 != error)					throw 'NSError** read/write failed (4)'
37  
-			
  36
+
38 37
 			return	res
39 38
 		}
40 39
 	
@@ -44,14 +43,13 @@
44 43
 			var o = outError.dereferencedObject
45 44
 			if (o != null)									throw 'NSError** read/write failed (5)'
46 45
 
47  
-
48 46
 			// Init a memory buffer from pointer
49 47
 			var b = new memoryBuffer('^')
50 48
 			b[0] = outError
51 49
 
52 50
 			var readBackError = [b dereferenceObjectAtIndex:0]
53 51
 			if (readBackError != null)						throw 'NSError** read/write failed (6)'
54  
-			
  52
+
55 53
 			return	true
56 54
 		}
57 55
 
@@ -139,7 +137,7 @@
139 137
 	if (actualSig != expectedSig)					throw 'NSError** signature failed — expected ' + expectedSig + ', got ' + actualSig
140 138
 	
141 139
 
142  
-	
  140
+	oa = null
143 141
 	o = null
144 142
 	
145 143
 	
157  Tests/Resources/inited from WebView.nib/designable.nib
@@ -89,6 +89,7 @@
89 89
 							</object>
90 90
 							<string key="NSFrameSize">{400, 400}</string>
91 91
 							<reference key="NSSuperview" ref="1006"/>
  92
+							<reference key="NSWindow"/>
92 93
 							<reference key="NSNextKeyView"/>
93 94
 							<string key="FrameName"/>
94 95
 							<string key="GroupName"/>
@@ -116,6 +117,7 @@
116 117
 					</object>
117 118
 					<string key="NSFrameSize">{400, 400}</string>
118 119
 					<reference key="NSSuperview"/>
  120
+					<reference key="NSWindow"/>
119 121
 					<reference key="NSNextKeyView" ref="444077104"/>
120 122
 				</object>
121 123
 				<string key="NSScreenRect">{{0, 0}, {1920, 1058}}</string>
@@ -232,7 +234,160 @@
232 234
 			<nil key="sourceID"/>
233 235
 			<int key="maxID">6</int>
234 236
 		</object>
235  
-		<object class="IBClassDescriber" key="IBDocument.Classes"/>
  237
+		<object class="IBClassDescriber" key="IBDocument.Classes">
  238
+			<object class="NSMutableArray" key="referencedPartialClassDescriptions">
  239
+				<bool key="EncodedWithXMLCoder">YES</bool>
  240
+				<object class="IBPartialClassDescription">
  241
+					<string key="className">ApplicationController</string>
  242
+					<string key="superclassName">NSObject</string>
  243
+					<object class="NSMutableDictionary" key="actions">
  244
+						<bool key="EncodedWithXMLCoder">YES</bool>
  245
+						<object class="NSArray" key="dict.sortedKeys">
  246
+							<bool key="EncodedWithXMLCoder">YES</bool>
  247
+							<string>displayTestsWindow:</string>
  248
+							<string>eval:</string>
  249
+							<string>garbageCollect:</string>
  250
+							<string>logBoxedObjects:</string>
  251
+							<string>logInstanceStats:</string>
  252
+							<string>runJSTests:</string>
  253
+							<string>runJSTestsContinuously:</string>
  254
+							<string>runSimpleTestFile:</string>
  255
+							<string>stopContinuousJSTestsRun:</string>
  256
+							<string>unlinkAllReferences:</string>
  257
+						</object>
  258
+						<object class="NSMutableArray" key="dict.values">
  259
+							<bool key="EncodedWithXMLCoder">YES</bool>
  260
+							<string>id</string>
  261
+							<string>id</string>
  262
+							<string>id</string>
  263
+							<string>id</string>
  264
+							<string>id</string>
  265
+							<string>id</string>
  266
+							<string>id</string>
  267
+							<string>id</string>
  268
+							<string>id</string>
  269
+							<string>id</string>
  270
+						</object>
  271
+					</object>
  272
+					<object class="NSMutableDictionary" key="actionInfosByName">
  273
+						<bool key="EncodedWithXMLCoder">YES</bool>
  274
+						<object class="NSArray" key="dict.sortedKeys">
  275
+							<bool key="EncodedWithXMLCoder">YES</bool>
  276
+							<string>displayTestsWindow:</string>
  277
+							<string>eval:</string>
  278
+							<string>garbageCollect:</string>
  279
+							<string>logBoxedObjects:</string>
  280
+							<string>logInstanceStats:</string>
  281
+							<string>runJSTests:</string>
  282
+							<string>runJSTestsContinuously:</string>
  283
+							<string>runSimpleTestFile:</string>
  284
+							<string>stopContinuousJSTestsRun:</string>
  285
+							<string>unlinkAllReferences:</string>
  286
+						</object>
  287
+						<object class="NSMutableArray" key="dict.values">
  288
+							<bool key="EncodedWithXMLCoder">YES</bool>
  289
+							<object class="IBActionInfo">
  290
+								<string key="name">displayTestsWindow:</string>
  291
+								<string key="candidateClassName">id</string>
  292
+							</object>
  293
+							<object class="IBActionInfo">
  294
+								<string key="name">eval:</string>
  295
+								<string key="candidateClassName">id</string>
  296
+							</object>
  297
+							<object class="IBActionInfo">
  298
+								<string key="name">garbageCollect:</string>
  299
+								<string key="candidateClassName">id</string>
  300
+							</object>
  301
+							<object class="IBActionInfo">
  302
+								<string key="name">logBoxedObjects:</string>
  303
+								<string key="candidateClassName">id</string>
  304
+							</object>
  305
+							<object class="IBActionInfo">
  306
+								<string key="name">logInstanceStats:</string>
  307
+								<string key="candidateClassName">id</string>
  308
+							</object>
  309
+							<object class="IBActionInfo">
  310
+								<string key="name">runJSTests:</string>
  311
+								<string key="candidateClassName">id</string>
  312
+							</object>
  313
+							<object class="IBActionInfo">
  314
+								<string key="name">runJSTestsContinuously:</string>
  315
+								<string key="candidateClassName">id</string>
  316
+							</object>
  317
+							<object class="IBActionInfo">
  318
+								<string key="name">runSimpleTestFile:</string>
  319
+								<string key="candidateClassName">id</string>
  320
+							</object>
  321
+							<object class="IBActionInfo">
  322
+								<string key="name">stopContinuousJSTestsRun:</string>
  323
+								<string key="candidateClassName">id</string>
  324
+							</object>
  325
+							<object class="IBActionInfo">
  326
+								<string key="name">unlinkAllReferences:</string>
  327
+								<string key="candidateClassName">id</string>
  328
+							</object>
  329
+						</object>
  330
+					</object>
  331
+					<object class="NSMutableDictionary" key="outlets">
  332
+						<bool key="EncodedWithXMLCoder">YES</bool>
  333
+						<object class="NSArray" key="dict.sortedKeys">
  334
+							<bool key="EncodedWithXMLCoder">YES</bool>
  335
+							<string>evalResult</string>
  336
+							<string>evalText</string>
  337
+							<string>textField</string>
  338
+							<string>webViewUsedAsContextSource</string>
  339
+							<string>window</string>
  340
+						</object>
  341
+						<object class="NSMutableArray" key="dict.values">
  342
+							<bool key="EncodedWithXMLCoder">YES</bool>
  343
+							<string>NSTextField</string>
  344
+							<string>NSTextField</string>
  345
+							<string>id</string>
  346
+							<string>id</string>
  347
+							<string>id</string>
  348
+						</object>
  349
+					</object>
  350
+					<object class="NSMutableDictionary" key="toOneOutletInfosByName">
  351
+						<bool key="EncodedWithXMLCoder">YES</bool>
  352
+						<object class="NSArray" key="dict.sortedKeys">
  353
+							<bool key="EncodedWithXMLCoder">YES</bool>
  354
+							<string>evalResult</string>
  355
+							<string>evalText</string>
  356
+							<string>textField</string>
  357
+							<string>webViewUsedAsContextSource</string>
  358
+							<string>window</string>
  359
+						</object>
  360
+						<object class="NSMutableArray" key="dict.values">
  361
+							<bool key="EncodedWithXMLCoder">YES</bool>
  362
+							<object class="IBToOneOutletInfo">
  363
+								<string key="name">evalResult</string>
  364
+								<string key="candidateClassName">NSTextField</string>
  365
+							</object>
  366
+							<object class="IBToOneOutletInfo">
  367
+								<string key="name">evalText</string>
  368
+								<string key="candidateClassName">NSTextField</string>
  369
+							</object>
  370
+							<object class="IBToOneOutletInfo">
  371
+								<string key="name">textField</string>
  372
+								<string key="candidateClassName">id</string>
  373
+							</object>
  374
+							<object class="IBToOneOutletInfo">
  375
+								<string key="name">webViewUsedAsContextSource</string>
  376
+								<string key="candidateClassName">id</string>
  377
+							</object>
  378
+							<object class="IBToOneOutletInfo">
  379
+								<string key="name">window</string>
  380
+								<string key="candidateClassName">id</string>
  381
+							</object>
  382
+						</object>
  383
+					</object>
  384
+					<object class="IBClassDescriptionSource" key="sourceIdentifier">
  385
+						<string key="majorKey">IBProjectSource</string>
  386
+						<string key="minorKey">./Classes/ApplicationController.h</string>
  387
+					</object>
  388
+				</object>
  389
+			</object>
  390
+		</object>
236 391
 		<int key="IBDocument.localizationMode">0</int>
237 392
 		<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaFramework</string>
238 393
 		<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
BIN  Tests/Resources/inited from WebView.nib/keyedobjects.nib
Binary file not shown
2  TestsRunner/ApplicationController.h
@@ -33,6 +33,8 @@
33 33
 	BOOL		runningContinuously;
34 34
 	// If we cycle context each time, we can test bindings each time.
35 35
 	BOOL		cyclingContext;
  36
+	
  37
+	NSInteger	testCount;	// successful test count
36 38
 
37 39
 }
38 40
 
55  TestsRunner/ApplicationController.m
@@ -56,21 +56,23 @@ - (void)applicationWillTerminate:(NSNotification *)notification
56 56
 
57 57
 	[self disposeShadowBindingsClasses];
58 58
 
59  
-	// Retain count is 2 because a variable named __jsc__ holds the ObjC object in the Javascript context
60  
-	if ([jsc retainCount] == 2)	NSLog(@"willTerminate %@ JSCocoa retainCount=%lu (OK)", jsc, [jsc retainCount]);
  59
+	// Retain count should be 1, the variable named __jsc__ holding the JSCocoa object does not retain it
  60
+	if ([jsc retainCount] == 1)	NSLog(@"willTerminate %@ JSCocoa retainCount=%lu (OK)", jsc, [jsc retainCount]);
61 61
 	else						NSLog(@"willTerminate %@ JSCocoa retainCount=%lu", jsc, [jsc retainCount]);
62 62
 
63 63
 	// Check if JSCocoa can be released (retainCount got down to 1)
64 64
 	// Won't work under ObjC GC
65 65
 #ifndef __OBJC_GC__
66 66
 	// Must be 2 with new release method
67  
-	if ([jsc retainCount] && [jsc retainCount] != 2)									NSLog(@"***Invalid JSCocoa retainCount***");
  67
+	// ^fixed, the instance set in the js context is not released.
  68
+//	if ([jsc retainCount] && [jsc retainCount] != 2)									
  69
+//		NSLog(@"***Invalid JSCocoa retainCount***");
68 70
 #endif
69 71
 	[jsc release];
70 72
 	
71 73
 	id path = [NSString stringWithFormat:@"%@/Contents/Resources/Tests/! stock", [[NSBundle mainBundle] bundlePath]];
72 74
 	id files = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:nil];
73  
-	if ([files count])											NSLog(@"***warning, skipping tests in ./!stock***"), NSLog(@"%@", files);
  75
+	if ([files count])											NSLog(@"***Skipping tests in ./!stock***"), NSLog(@"%@", files);
74 76
 #ifdef __OBJC_GC__
75 77
 	if (![[NSGarbageCollector defaultCollector] isEnabled])		NSLog(@"***GC running but disabled***");
76 78
 #endif	
@@ -114,7 +116,7 @@ - (IBAction)_runJSTests:(id)sender {
114 116
 	id path = [[NSBundle mainBundle] bundlePath];
115 117
 	path = [NSString stringWithFormat:@"%@/Contents/Resources/Tests", path];
116 118
 //	NSLog(@"Run %d from %@", runCount, path);
117  
-	int testCount = 0;
  119
+	testCount = 0;
118 120
 	if (test_unit)
119 121
 		testCount = [jsc runTests:path];
120 122
 	BOOL b = !!testCount;
@@ -968,45 +970,16 @@ - (void)finishTest37:(BOOL)b
968 970
 	[jsc callJSFunctionNamed:@"completeDelayedTest" withArguments:@"37 init from webview", [NSNumber numberWithInt:1], nil];
969 971
 
970 972
 
971  
-	NSLog(@"JSC2 not deallocated");
972  
-	NSLog(@"unlinking...");
  973
+	// WebView context cleanup
973 974
 	[jsc2 unlinkAllReferences];
974  
-	NSLog(@"collecting...");
975 975
 	[jsc2 garbageCollect];
976  
-	NSLog(@"releasing...");
977 976
 	[jsc2 release];
978 977
 	jsc2 = nil;
979  
-	
980  
-	NSLog(@"JSC2 DEALLOCATED");
981  
-	
982  
-/*
983  
-	NSLog(@"COMMENTED test 37 !");
984  
-//	return;
985  
-	NSLog(@"jsc2 rc=%lu (%p)", [jsc2 retainCount], self);
986  
-	NSLog(@"get1 %@", [jsc2 eval:@"__jsc__"]);
987  
-//	b = [jsc2 removeObjectWithName:@"__jsc__"];
988  
-	[jsc2 garbageCollect];
989  
-	NSLog(@"jsc2 rc=%lu (POST REMOVE %d)", [jsc2 retainCount], b);
990  
-	NSLog(@"get2 %@", [jsc2 eval:@"__jsc__"]);
991  
-	[jsc2 release];
992  
-*/
993 978
 
994  
-	NSLog(@"jsc2 rc=%lu (%p)", [jsc2 retainCount], self);
995  
-	[topObjects release];
996  
-	NSLog(@"jsc2 rc=%lu (%p)", [jsc2 retainCount], self);
997 979
 
  980
+	// WebView nib cleanup
  981
+	[topObjects release];
998 982
 	topObjects	= nil;
999  
-	jsc2		= nil;
1000  
-
1001  
-	NSLog(@"***COMMENTED test 37 !");
1002  
-	
1003  
-	NSLog(@"AND, commented test37 html");
1004  
-/*	
1005  
-	NSLog(@"****************");
1006  
-	[JSCocoa logInstanceStats];
1007  
-	[JSCocoa logBoxedObjects];
1008  
-	NSLog(@"****************");
1009  
-*/	
1010 983
 }
1011 984
 
1012 985
 BOOL	bindingsAlreadyTested = NO;
@@ -1017,10 +990,14 @@ - (BOOL)bindingsAlreadyTested2				{	if (cyclingContext)	return	NO; return	bindin
1017 990
 - (void)setBindingsAlreadyTested:(BOOL)b	{	bindingsAlreadyTested	= b;	}
1018 991
 - (void)setBindingsAlreadyTested2:(BOOL)b	{	bindingsAlreadyTested2	= b;	}
1019 992
 
1020  
-- (void)allTestsRanOK
  993
+//- (void)allTestsRanOK
  994
+- (void)delayedTestsRan:(NSInteger)successful outof:(NSInteger)total
1021 995
 {
1022 996
 	[window makeKeyAndOrderFront:nil];
1023  
-	[textField setStringValue:@"All tests ran OK"];
  997
+	if (successful == total && testCount)
  998
+		[textField setStringValue:[NSString stringWithFormat:@"All tests ran OK (%d tests, %d delayed)", testCount, total]];
  999
+	else
  1000
+		[textField setStringValue:[NSString stringWithFormat:@"Tests failed (%d tests, %d delayed)", testCount, total]];
1024 1001
 }
1025 1002
 
1026 1003
 - (IBAction)displayTestsWindow:(id)sender {
31,093  ...ner/TestsRunner.xcodeproj/project.xcworkspace/xcuserdata/mini.xcuserdatad/UserInterfaceState.xcuserstate
17227 additions, 13866 deletions not shown
6  TestsRunner/TestsRunner.xcodeproj/xcuserdata/mini.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist
@@ -9,11 +9,11 @@
9 9
          continueAfterRunningActions = "No"
10 10
          isPathRelative = "1"
11 11
          filePath = "ApplicationController.m"
12  
-         timestampString = "334080414.751994"
  12
+         timestampString = "334261163.886137"
13 13
          startingColumnNumber = "9223372036854775807"
14 14
          endingColumnNumber = "9223372036854775807"
15  
-         startingLineNumber = "269"
16  
-         endingLineNumber = "269"
  15
+         startingLineNumber = "271"
  16
+         endingLineNumber = "271"
17 17
          landmarkName = "-validateMenuItem:"
18 18
          landmarkType = "5">
19 19
       </FileBreakpoint>
2  TestsRunner/test.js
@@ -40,7 +40,7 @@
40 40
 		if (delayedTestPendingCount() == 0)	
41 41
 		{
42 42
 			log('All pending tests ran, ' + delayedTestSuccessCount() + '/' + delayedTestCount() + ' successful')
43  
-			NSApplication.sharedApplication.delegate.allTestsRanOK
  43
+			NSApplication.sharedApplication.delegate.delayedTestsRan_outof_(delayedTestSuccessCount(), delayedTestCount())
44 44
 		}
45 45
 	}
46 46
 	

0 notes on commit 735de68

Please sign in to comment.
Something went wrong with that request. Please try again.