Fixed bad GC roots in OOJSFunction. Avoid extra allocation in JS Timer constructor.
git-svn-id: http://svn.berlios.de/svnroot/repos/oolite-linux/trunk@3472 127b21dd-08f5-0310-b4b7-95ae10353056
This commit is contained in:
parent
deee594006
commit
dcd183bae9
@ -213,6 +213,7 @@ JSObject *DebugMonitorToJSConsole(JSContext *context, OODebugMonitor *monitor)
|
||||
JSObject *settingsObject = NULL;
|
||||
jsval value;
|
||||
|
||||
NSCAssert(JS_EnterLocalRootScope(context), @"Failed to create JS GC root scope");
|
||||
engine = [OOJavaScriptEngine sharedEngine];
|
||||
|
||||
if (sConsolePrototype == NULL)
|
||||
@ -247,6 +248,8 @@ JSObject *DebugMonitorToJSConsole(JSContext *context, OODebugMonitor *monitor)
|
||||
if (settingsObject == NULL) object = NULL;
|
||||
}
|
||||
|
||||
JS_LeaveLocalRootScope(context);
|
||||
|
||||
return object;
|
||||
// Analyzer: object leaked. (x2) [Expected, objects are retained by JS object.]
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ MA 02110-1301, USA.
|
||||
JSFunction *_function;
|
||||
}
|
||||
|
||||
- (id) initWithFunction:(JSFunction *)function;
|
||||
- (id) initWithFunction:(JSFunction *)function context:(JSContext *)context;
|
||||
- (id) initWithName:(NSString *)name
|
||||
scope:(JSObject *)scope // may be NULL, in which case global object is used.
|
||||
code:(NSString *)code // full JS code for function, including function declaration.
|
||||
|
@ -29,8 +29,10 @@ MA 02110-1301, USA.
|
||||
|
||||
@implementation OOJSFunction
|
||||
|
||||
- (id) initWithFunction:(JSFunction *)function
|
||||
- (id) initWithFunction:(JSFunction *)function context:(JSContext *)context
|
||||
{
|
||||
NSParameterAssert(context != NULL);
|
||||
|
||||
if (function == NULL)
|
||||
{
|
||||
[self release];
|
||||
@ -40,7 +42,7 @@ MA 02110-1301, USA.
|
||||
if ((self = [super init]))
|
||||
{
|
||||
_function = function;
|
||||
[[OOJavaScriptEngine sharedEngine] addGCRoot:&function named:"OOJSFunction._function"];
|
||||
OO_AddJSGCRoot(context, _function, "OOJSFunction._function");
|
||||
}
|
||||
|
||||
return self;
|
||||
@ -92,7 +94,7 @@ MA 02110-1301, USA.
|
||||
|
||||
if (OK)
|
||||
{
|
||||
self = [self initWithFunction:function];
|
||||
self = [self initWithFunction:function context:context];
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -157,8 +159,8 @@ MA 02110-1301, USA.
|
||||
|
||||
for (i = 0; i < argc; i++)
|
||||
{
|
||||
OO_AddJSGCRoot(context, &argv[i], "OOJSFunction argv");
|
||||
argv[i] = [[arguments objectAtIndex:i] javaScriptValueInContext:context];
|
||||
OO_AddJSGCRoot(context, &argv[i], "OOJSFunction argv");
|
||||
}
|
||||
|
||||
JSObject *scopeObj = NULL;
|
||||
|
@ -41,7 +41,8 @@ static JSClass sTimerClass;
|
||||
- (id) initWithDelay:(OOTimeAbsolute)delay
|
||||
interval:(OOTimeDelta)interval
|
||||
function:(jsval)function
|
||||
this:(JSObject *)jsThis;
|
||||
this:(JSObject *)jsThis
|
||||
jsSelf:(JSObject *)jsSelf;
|
||||
|
||||
@end
|
||||
|
||||
@ -52,6 +53,7 @@ static JSClass sTimerClass;
|
||||
interval:(OOTimeDelta)interval
|
||||
function:(jsval)function
|
||||
this:(JSObject *)jsThis
|
||||
jsSelf:(JSObject *)jsSelf
|
||||
{
|
||||
JSContext *context = NULL;
|
||||
|
||||
@ -68,7 +70,7 @@ static JSClass sTimerClass;
|
||||
_function = function;
|
||||
OO_AddJSGCRoot(context, &_function, "OOJSTimer function");
|
||||
|
||||
_jsSelf = JS_NewObject(context, &sTimerClass, sTimerPrototype, NULL);
|
||||
_jsSelf = jsSelf;
|
||||
if (_jsSelf != NULL)
|
||||
{
|
||||
if (!JS_SetPrivate(context, _jsSelf, [self retain])) _jsSelf = NULL;
|
||||
@ -76,7 +78,7 @@ static JSClass sTimerClass;
|
||||
if (_jsSelf == NULL)
|
||||
{
|
||||
[self release];
|
||||
self = nil;
|
||||
return nil;
|
||||
}
|
||||
|
||||
_owningScript = [[OOJSScript currentlyRunningScript] weakRetain];
|
||||
@ -339,6 +341,12 @@ static JSBool TimerConstruct(JSContext *context, JSObject *inThis, uintN argc, j
|
||||
double interval = -1.0;
|
||||
OOJSTimer *timer = nil;
|
||||
|
||||
if (!JS_IsConstructing(context))
|
||||
{
|
||||
OOReportJSError(context, @"Timer() cannot be called as a function, it must be used as a constructor (as in new Timer(...)).");
|
||||
return NO;
|
||||
}
|
||||
|
||||
if (argc < 3)
|
||||
{
|
||||
OOReportJSBadArguments(context, nil, @"Timer", argc, argv, @"Invalid arguments in constructor", @"(object, function, number [, number])");
|
||||
@ -376,13 +384,21 @@ static JSBool TimerConstruct(JSContext *context, JSObject *inThis, uintN argc, j
|
||||
timer = [[OOJSTimer alloc] initWithDelay:delay
|
||||
interval:interval
|
||||
function:function
|
||||
this:this];
|
||||
*outResult = [timer javaScriptValueInContext:context];
|
||||
if (delay >= 0) // Leave in stopped state if delay is negative
|
||||
this:this
|
||||
jsSelf:JSVAL_TO_OBJECT(*outResult)];
|
||||
if (timer != nil)
|
||||
{
|
||||
[timer scheduleTimer];
|
||||
if (delay >= 0) // Leave in stopped state if delay is negative
|
||||
{
|
||||
[timer scheduleTimer];
|
||||
}
|
||||
[timer release]; // The JS object retains the ObjC object.
|
||||
}
|
||||
[timer release]; // The JS object retains the ObjC object.
|
||||
else
|
||||
{
|
||||
*outResult = JSVAL_NULL;
|
||||
}
|
||||
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
@ -79,8 +79,6 @@ enum
|
||||
- (JSContext *)acquireContext;
|
||||
- (void)releaseContext:(JSContext *)context;
|
||||
|
||||
- (BOOL) addGCRoot:(void *)rootPtr
|
||||
named:(const char *)name;
|
||||
- (void) removeGCRoot:(void *)rootPtr;
|
||||
|
||||
@end
|
||||
|
@ -413,19 +413,6 @@ static void ReportJSError(JSContext *context, const char *message, JSErrorReport
|
||||
}
|
||||
|
||||
|
||||
- (BOOL) addGCRoot:(void *)rootPtr
|
||||
named:(const char *)name
|
||||
{
|
||||
BOOL result;
|
||||
JSContext *context = NULL;
|
||||
|
||||
context = [self acquireContext];
|
||||
result = JS_AddNamedRoot(context, rootPtr, name);
|
||||
[self releaseContext:context];
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
- (void) removeGCRoot:(void *)rootPtr
|
||||
{
|
||||
JSContext *context = NULL;
|
||||
|
Loading…
x
Reference in New Issue
Block a user