Fixed crash with repeated transient uses of JS EquipmentTypes - triggered by Cataclysm and almost certainly lots of others.

git-svn-id: http://svn.berlios.de/svnroot/repos/oolite-linux/trunk@3496 127b21dd-08f5-0310-b4b7-95ae10353056
This commit is contained in:
Jens Ayton 2010-06-11 10:36:08 +00:00
parent 6bf4d5dc7c
commit b2220bf4f8
5 changed files with 42 additions and 16 deletions

View File

@ -366,6 +366,12 @@ static JSBool EquipmentInfoGetAllEqipment(JSContext *context, JSObject *this, js
return @"EquipmentInfo";
}
- (void) oo_clearJSSelf:(JSObject *)selfVal
{
if (_jsSelf == selfVal) _jsSelf = NULL;
}
@end

View File

@ -129,16 +129,10 @@ static JSFunctionSpec sScriptMethods[] =
// Set up JS object
if (!problem)
{
// Do we actually want parent to be the global object here?
_jsSelf = JS_NewObject(context, &sScriptClass, sScriptPrototype, NULL /*JS_GetGlobalObject(context)*/);
_jsSelf = JS_NewObject(context, &sScriptClass, sScriptPrototype, NULL);
if (_jsSelf == NULL) problem = @"allocation failure";
}
if (!problem)
{
if (!JS_SetPrivate(context, _jsSelf, [self weakRetain])) problem = @"could not set private backreference";
}
if (!problem)
{
if (!OO_AddJSGCRoot(context, &_jsSelf, "Script object"))
@ -147,6 +141,11 @@ static JSFunctionSpec sScriptMethods[] =
}
}
if (!problem)
{
if (!JS_SetPrivate(context, _jsSelf, [self weakRetain])) problem = @"could not set private backreference";
}
// Push self on stack of running scripts.
RunningStack stackElement =
{
@ -356,7 +355,7 @@ static JSFunctionSpec sScriptMethods[] =
if (![notedChanges containsObject:key])
{
[notedChanges addObject:key];
OOReportJSWarning(context, @"The event handler %@ has been renamed to %@. The script %@ must be updated. The old form will not be supported in future versions of Oolite!", oldName, eventName, self->name);
OOReportJSWarning(context, @"The event handler %@ has been renamed to %@. The script %@ must be updated. The old form will not be supported in future versions of Oolite.", oldName, eventName, self->name);
}
}
}
@ -375,8 +374,8 @@ static JSFunctionSpec sScriptMethods[] =
- (BOOL)doEvent:(NSString *)eventName withArguments:(NSArray *)arguments
{
BOOL OK = YES;
jsval value;
JSFunction *function;
jsval value = JSVAL_VOID;
JSFunction *function = NULL;
uintN i, argc;
jsval *argv = NULL;
OOJavaScriptEngine *engine = nil;

View File

@ -243,8 +243,6 @@ static JSBool ShipGroupConstruct(JSContext *context, JSObject *inThis, uintN arg
{
if (!JS_SetPrivate(context, _jsSelf, [self retain])) _jsSelf = NULL;
}
if (_jsSelf != NULL) OO_AddJSGCRoot(context, &_jsSelf, "OOShipGroup");
}
if (_jsSelf != NULL) result = OBJECT_TO_JSVAL(_jsSelf);
@ -252,6 +250,12 @@ static JSBool ShipGroupConstruct(JSContext *context, JSObject *inThis, uintN arg
return result;
}
- (void) oo_clearJSSelf:(JSObject *)selfVal
{
if (_jsSelf == selfVal) _jsSelf = NULL;
}
@end

View File

@ -46,7 +46,7 @@ enum
};
@interface OOJavaScriptEngine : NSObject
@interface OOJavaScriptEngine: NSObject
{
JSRuntime *runtime;
JSContext *mainContext;
@ -145,7 +145,7 @@ BOOL JSSetNSProperty(JSContext *context, JSObject *object, NSString *name, jsval
BOOL JSDefineNSProperty(JSContext *context, JSObject *object, NSString *name, jsval value, JSPropertyOp getter, JSPropertyOp setter, uintN attrs);
@interface NSObject (OOJavaScriptConversion)
@interface NSObject (OOJavaScript)
/* -javaScriptValueInContext:
@ -165,6 +165,12 @@ BOOL JSDefineNSProperty(JSContext *context, JSObject *object, NSString *name, js
- (NSString *)javaScriptDescriptionWithClassName:(NSString *)className;
- (NSString *)jsClassName;
/* oo_clearJSSelf:
This is called by JSObjectWrapperFinalize() when a JS object wrapper is
collected. The default implementation does nothing.
*/
- (void) oo_clearJSSelf:(JSObject *)selfVal;
@end

View File

@ -859,6 +859,12 @@ static BOOL JSNewNSDictionaryValue(JSContext *context, NSDictionary *dictionary,
return description;
}
- (void) oo_clearJSSelf:(JSObject *)selfVal
{
}
@end
@ -1252,8 +1258,13 @@ JSBool JSObjectWrapperToString(JSContext *context, JSObject *this, uintN argc, j
void JSObjectWrapperFinalize(JSContext *context, JSObject *this)
{
[(id)JS_GetPrivate(context, this) release];
JS_SetPrivate(context, this, nil);
id object = JS_GetPrivate(context, this);
if (object != nil)
{
[[object weakRefUnderlyingObject] oo_clearJSSelf:this];
[object release];
JS_SetPrivate(context, this, nil);
}
}