65static JSScript *
LoadScriptWithName(JSContext *context, NSString *path, JSObject *
object, JSObject **outScriptObject, NSString **outErrorMessage);
67#if OO_CACHE_JS_SCRIPTS
75static JSBool
ScriptAddProperty(JSContext *context, JSObject *
this, jsid propID, jsval *value);
86 JS_StrictPropertyStub,
102@interface OOJSScript (OOPrivate)
104- (NSString *)scriptNameFromPath:(NSString *)path;
105- (NSDictionary *)defaultPropertiesFromPath:(NSString *)path;
112+ (id) scriptWithPath:(NSString *)path properties:(NSDictionary *)properties
114 return [[[
self alloc] initWithPath:path properties:properties] autorelease];
118- (id) initWithPath:(NSString *)path properties:(NSDictionary *)properties
120 JSContext *context = NULL;
121 NSString *problem =
nil;
122 JSScript *script = NULL;
123 JSObject *scriptObject = NULL;
124 jsval returnValue = JSVAL_VOID;
125 NSEnumerator *keyEnum =
nil;
130 if (
self ==
nil) problem =
@"allocation failure";
135 if (JS_IsExceptionPending(context))
137 JS_ClearPendingException(context);
138 OOLogERR(
@"script.javaScript.load.waitingException",
@"Prior to loading script %@, there was a pending JavaScript exception, which has been cleared. This is an internal error, please report it.", path);
145 if (_jsSelf == NULL) problem =
@"allocation failure";
150 problem =
@"could not add JavaScript root object";
155 problem =
@"could not add JavaScript root object";
162 problem =
@"could not set private backreference";
174 filePath = [path retain];
178 OOLog(
@"script.javaScript.willLoad",
@"About to load JavaScript %@", path);
184 NSDictionary *defaultProperties = [
self defaultPropertiesFromPath:path];
185 for (keyEnum = [defaultProperties keyEnumerator]; (key = [keyEnum nextObject]); )
187 if ([key isKindOfClass:[NSString
class]])
189 property = [defaultProperties objectForKey:key];
193 [
self defineProperty:property named:key];
198 [
self setProperty:property named:key];
204 if (!problem && properties !=
nil)
206 for (keyEnum = [properties keyEnumerator]; (key = [keyEnum nextObject]); )
208 if ([key isKindOfClass:[NSString
class]])
210 property = [properties objectForKey:key];
211 [
self defineProperty:property named:key];
222 jsid nameID =
OOJSID(
"name");
223 [
self setProperty:[
self scriptNameFromPath:path] withID:nameID inContext:context];
229 if (!JS_ExecuteScript(context, _jsSelf, script, &returnValue))
231 problem =
@"could not run script";
236 JS_DestroyScript(context, script);
239 JS_RemoveObjectRoot(context, &scriptObject);
247 name = [StrippedName([[
self propertyWithID:nameID inContext:context] description]) copy];
250 name = [[
self scriptNameFromPath:path] retain];
251 [
self setProperty:name withID:nameID inContext:context];
254 version = [[[
self propertyWithID:OOJSID("version") inContext:context] description] copy];
255 description = [[[
self propertyWithID:OOJSID("description") inContext:context] description] copy];
257 OOLog(
@"script.javaScript.load.success",
@"Loaded JavaScript: %@ -- %@", [
self displayName], description ? description : (NSString *)
@"(no description)");
267 OOLog(
@"script.javaScript.load.failed",
@"***** Error loading JavaScript script %@ -- %@", path, problem);
268 JS_ReportPendingException(context);
276 [[NSNotificationCenter defaultCenter] addObserver:self
277 selector:@selector(javaScriptEngineWillReset:)
278 name:kOOJavaScriptEngineWillResetNotification
288 [[NSNotificationCenter defaultCenter] removeObserver:self
289 name:kOOJavaScriptEngineWillResetNotification
302 JS_RemoveObjectRoot(context, &_jsSelf);
307 [weakSelf weakRefDrop];
313- (NSString *) oo_jsClassName
319- (NSString *)descriptionComponents
321 if (_jsSelf != NULL)
return [
super descriptionComponents];
322 else return @"invalid script";
326- (void) javaScriptEngineWillReset:(NSNotification *)notification
333 JS_RemoveObjectRoot(context, &_jsSelf);
346+ (NSArray *) scriptStack
348 NSMutableArray *result =
nil;
350 result = [NSMutableArray array];
359 return [weakSelf retain];
365 if (weakRef == weakSelf) weakSelf =
nil;
371 if (name ==
nil) name = [[
self propertyNamed:@"name"] copy];
372 if (name ==
nil)
return [
self scriptNameFromPath:filePath];
377- (NSString *) scriptDescription
383- (NSString *) version
389- (void)runWithTarget:(
Entity *)target
395- (BOOL) callMethod:(jsid)methodID
396 inContext:(JSContext *)context
397 withArguments:(jsval *)argv count:(intN)argc
398 result:(jsval *)outResult
400 NSParameterAssert(name != NULL && (argv != NULL || argc == 0) && context != NULL &&
JS_IsInRequest(context));
401 if (_jsSelf == NULL)
return NO;
403 JSObject *root = NULL;
406 jsval ignoredResult = JSVAL_VOID;
408 if (outResult == NULL) outResult = &ignoredResult;
411 if (
EXPECT(JS_GetMethodById(context, _jsSelf, methodID, &root, &method) && !JSVAL_IS_VOID(method)))
414 if (JS_IsExceptionPending(context))
416 OOLog(
@"script.internalBug",
@"Exception pending on context before calling method in %s, clearing. This is an internal error, please report it.", __PRETTY_FUNCTION__);
417 JS_ClearPendingException(context);
434 OK = JS_CallFunctionValue(context, _jsSelf, method, argc, argv, outResult);
437 if (JS_IsExceptionPending(context))
439 JS_ReportPendingException(context);
451 JS_RemoveObjectRoot(context, &root);
698static JSScript *
LoadScriptWithName(JSContext *context, NSString *path, JSObject *
object, JSObject **outScriptObject, NSString **outErrorMessage)
700#if OO_CACHE_JS_SCRIPTS
703 NSString *fileContents =
nil;
705 JSScript *script = NULL;
707 NSCParameterAssert(outScriptObject != NULL && outErrorMessage != NULL);
708 *outErrorMessage =
nil;
710#if OO_CACHE_JS_SCRIPTS
722 fileContents = [NSString stringWithContentsOfUnicodeFile:path];
724 if (fileContents !=
nil)
731 if ([fileContents rangeOfString:
@"\"use strict\
";"].location == NSNotFound && [fileContents rangeOfString:
@"'use strict';"].location == NSNotFound)
738 fileContents = [@"\"use strict\";\n" stringByAppendingString:fileContents];
742 data = [fileContents utf16DataWithBOM:NO];
744 if (data ==
nil) *outErrorMessage =
@"could not load file";
747 script = JS_CompileUCScript(context,
object, [data bytes], [data length] /
sizeof(unichar), [path UTF8String], 1);
748 if (script != NULL) *outScriptObject = JS_NewScriptObject(context, script);
749 else *outErrorMessage =
@"compilation failed";
752#if OO_CACHE_JS_SCRIPTS