Work on using jsids instead of strings to identify methods and properties, starting with the simple cases.
git-svn-id: http://svn.berlios.de/svnroot/repos/oolite-linux/trunk@4131 127b21dd-08f5-0310-b4b7-95ae10353056
This commit is contained in:
parent
0aba4b0971
commit
b636e923ce
@ -9161,7 +9161,7 @@ Vector positionOffsetForShipInRotationToAlignment(ShipEntity* ship, Quaternion q
|
||||
{
|
||||
args[0] = INT_TO_JSVAL(i);
|
||||
OOJSStartTimeLimiter();
|
||||
OK = [script callMethodNamed:"coordinatesForEscortPosition"
|
||||
OK = [script callMethodNamed:OOJS_PROPID(context, "coordinatesForEscortPosition")
|
||||
withArguments:args count:sizeof args / sizeof *args
|
||||
inContext:context
|
||||
gettingResult:&result];
|
||||
|
@ -722,7 +722,7 @@ NSString *OOStringFromDeciCredits(OOCreditsQuantity tenthsOfCredits, BOOL includ
|
||||
NSString *result = @"<error>";
|
||||
JS_BeginRequest(context);
|
||||
|
||||
if (JS_GetMethod(context, global, "formatCredits", &fakeRoot, &method))
|
||||
if (OOJSGetMethod(context, global, OOJS_PROPID(context, "formatCredits"), &fakeRoot, &method))
|
||||
{
|
||||
jsval args[3];
|
||||
if (JS_NewDoubleValue(context, tenthsOfCredits * 0.1, &args[0]))
|
||||
|
@ -68,6 +68,12 @@ OOINLINE const jschar *OOJSGetStringCharsAndLength(JSContext *context, JSString
|
||||
|
||||
#define OOJSVAL_TO_DOUBLE JSVAL_TO_DOUBLE
|
||||
|
||||
|
||||
#define OOJSGetMethod JS_GetMethodById
|
||||
#define OOJSGetProperty JS_GetPropertyById
|
||||
#define OOJSSetProperty JS_SetPropertyById
|
||||
#define OOJSDefineProperty JS_DefinePropertyById
|
||||
|
||||
#else // !OO_NEW_JS
|
||||
|
||||
// In old API, jsvals could be pointers to doubles; in new, they're actual doubles.
|
||||
@ -85,6 +91,19 @@ OOINLINE const jschar *OOJSGetStringCharsAndLength(JSContext *context, JSString
|
||||
}
|
||||
|
||||
#define OOJS_FF4B9 0
|
||||
|
||||
|
||||
#define OOJSGetMethod JS_GetMethod
|
||||
#define OOJSGetProperty JS_GetProperty
|
||||
#define OOJSSetProperty JS_SetProperty
|
||||
#define OOJSDefineProperty JS_DefineProperty
|
||||
|
||||
|
||||
OOINLINE BOOL OOJSGetProperty(JSContext *context, JSObject *object, OOJSPropID propID, jsval *value)
|
||||
{
|
||||
return JS_GetPropertyById(context, object, propID, value);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -57,14 +57,22 @@ MA 02110-1301, USA.
|
||||
|
||||
/* Low-level interface to call a JavaScript method.
|
||||
Requires a request on context.
|
||||
|
||||
FIXME: should take a jsid instead of string for name, but can't be done cleanly without requiring OO_NEW_JS.
|
||||
*/
|
||||
- (BOOL) callMethodNamed:(const char *)methodName
|
||||
- (BOOL) callMethodNamed:(OOJSPropID)methodID
|
||||
withArguments:(jsval *)argv count:(intN)argc
|
||||
inContext:(JSContext *)context
|
||||
gettingResult:(jsval *)outResult;
|
||||
|
||||
- (id) propertyWithID:(OOJSPropID)propID inContext:(JSContext *)context;
|
||||
// Set a property which can be modified or deleted by the script.
|
||||
- (BOOL) setProperty:(id)value withID:(OOJSPropID)propID inContext:(JSContext *)context;
|
||||
// Set a special property which cannot be modified or deleted by the script.
|
||||
- (BOOL) defineProperty:(id)value withID:(OOJSPropID)propID inContext:(JSContext *)context;
|
||||
|
||||
- (id) propertyNamed:(NSString *)name;
|
||||
- (BOOL) setProperty:(id)value named:(NSString *)name;
|
||||
- (BOOL) defineProperty:(id)value named:(NSString *)name;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
@ -183,7 +183,8 @@ static JSFunctionSpec sScriptMethods[] =
|
||||
the script object can't be renamed after the initial run. This could
|
||||
probably also be achieved by fiddling with JS property attributes.
|
||||
*/
|
||||
[self setProperty:[self scriptNameFromPath:path] named:@"name"];
|
||||
OOJSPropID nameID = OOJS_PROPID(context, "name");
|
||||
[self setProperty:[self scriptNameFromPath:path] withID:nameID inContext:context];
|
||||
|
||||
// Run the script (allowing it to set up the properties we need, as well as setting up those event handlers)
|
||||
if (!problem)
|
||||
@ -208,15 +209,15 @@ static JSFunctionSpec sScriptMethods[] =
|
||||
{
|
||||
// Get display attributes from script
|
||||
DESTROY(name);
|
||||
name = [StrippedName([[self propertyNamed:@"name"] description]) copy];
|
||||
name = [StrippedName([[self propertyWithID:nameID inContext:context] description]) copy];
|
||||
if (name == nil)
|
||||
{
|
||||
name = [[self scriptNameFromPath:path] retain];
|
||||
[self setProperty:name named:@"name"];
|
||||
[self setProperty:name withID:nameID inContext:context];
|
||||
}
|
||||
|
||||
version = [[[self propertyNamed:@"version"] description] copy];
|
||||
description = [[[self propertyNamed:@"description"] description] copy];
|
||||
version = [[[self propertyWithID:OOJS_PROPID(context, "version") inContext:context] description] copy];
|
||||
description = [[[self propertyWithID:OOJS_PROPID(context, "description") inContext:context] description] copy];
|
||||
|
||||
OOLog(@"script.javaScript.load.success", @"Loaded JavaScript OXP: %@ -- %@", [self displayName], description ? description : (NSString *)@"(no description)");
|
||||
}
|
||||
@ -421,7 +422,7 @@ static JSFunctionSpec sScriptMethods[] =
|
||||
}
|
||||
|
||||
|
||||
- (BOOL) callMethodNamed:(const char *)methodName
|
||||
- (BOOL) callMethodNamed:(OOJSPropID)methodID
|
||||
withArguments:(jsval *)argv count:(intN)argc
|
||||
inContext:(JSContext *)context
|
||||
gettingResult:(jsval *)outResult
|
||||
@ -431,10 +432,10 @@ static JSFunctionSpec sScriptMethods[] =
|
||||
BOOL OK = NO;
|
||||
JSObject *fakeRoot = NULL;
|
||||
jsval method;
|
||||
if (EXPECT(JS_GetMethod(context, _jsSelf, methodName, &fakeRoot, &method) && !JSVAL_IS_VOID(method)))
|
||||
if (EXPECT(OOJSGetMethod(context, _jsSelf, methodID, &fakeRoot, &method) && !JSVAL_IS_VOID(method)))
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
OOLog(@"script.trace.javaScript.callback", @"Calling [%@].%s()", [self name], methodName);
|
||||
OOLog(@"script.trace.javaScript.callback", @"Calling [%@].%@()", [self name], OOStringFromJSPropertyID(context, methodID, NULL));
|
||||
OOLogIndentIf(@"script.trace.javaScript.callback");
|
||||
#endif
|
||||
|
||||
@ -463,57 +464,78 @@ static JSFunctionSpec sScriptMethods[] =
|
||||
}
|
||||
|
||||
|
||||
- (id)propertyNamed:(NSString *)propName
|
||||
- (id) propertyWithID:(OOJSPropID)propID inContext:(JSContext *)context
|
||||
{
|
||||
BOOL OK;
|
||||
jsval value = JSVAL_VOID;
|
||||
JSContext *context = NULL;
|
||||
id result = nil;
|
||||
NSParameterAssert(context != NULL && JS_IsInRequest(context));
|
||||
|
||||
jsval jsValue = JSVAL_VOID;
|
||||
if (OOJSGetProperty(context, _jsSelf, propID, &jsValue))
|
||||
{
|
||||
return OOJSNativeObjectFromJSValue(context, jsValue);
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL) setProperty:(id)value withID:(OOJSPropID)propID inContext:(JSContext *)context
|
||||
{
|
||||
NSParameterAssert(context != NULL && JS_IsInRequest(context));
|
||||
|
||||
jsval jsValue = OOJSValueFromNativeObject(context, value);
|
||||
return OOJSSetProperty(context, _jsSelf, propID, &jsValue);
|
||||
}
|
||||
|
||||
|
||||
- (BOOL) defineProperty:(id)value withID:(OOJSPropID)propID inContext:(JSContext *)context
|
||||
{
|
||||
NSParameterAssert(context != NULL && JS_IsInRequest(context));
|
||||
|
||||
jsval jsValue = OOJSValueFromNativeObject(context, value);
|
||||
return OOJSDefineProperty(context, _jsSelf, propID, jsValue, NULL, NULL, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
|
||||
}
|
||||
|
||||
|
||||
- (id) propertyNamed:(NSString *)propName
|
||||
{
|
||||
if (propName == nil) return nil;
|
||||
|
||||
context = [[OOJavaScriptEngine sharedEngine] acquireContext];
|
||||
OK = OOJSGetProperty(context, _jsSelf, propName, &value);
|
||||
if (OK && !JSVAL_IS_VOID(value)) result = OOJSNativeObjectFromJSValue(context, value);
|
||||
JSContext *context = [[OOJavaScriptEngine sharedEngine] acquireContext];
|
||||
JS_BeginRequest(context);
|
||||
|
||||
id result = [self propertyWithID:OOJSPropIDFromString(context, propName) inContext:context];
|
||||
|
||||
JS_EndRequest(context);
|
||||
[[OOJavaScriptEngine sharedEngine] releaseContext:context];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)setProperty:(id)value named:(NSString *)propName
|
||||
- (BOOL) setProperty:(id)value named:(NSString *)propName
|
||||
{
|
||||
jsval jsValue;
|
||||
JSContext *context = NULL;
|
||||
BOOL result = NO;
|
||||
|
||||
if (value == nil || propName == nil) return NO;
|
||||
|
||||
context = [[OOJavaScriptEngine sharedEngine] acquireContext];
|
||||
jsValue = [value oo_jsValueInContext:context];
|
||||
if (!JSVAL_IS_VOID(jsValue))
|
||||
{
|
||||
result = OOJSDefineProperty(context, _jsSelf, propName, jsValue, NULL, NULL, JSPROP_ENUMERATE);
|
||||
}
|
||||
JSContext *context = [[OOJavaScriptEngine sharedEngine] acquireContext];
|
||||
JS_BeginRequest(context);
|
||||
|
||||
BOOL result = [self setProperty:value withID:OOJSPropIDFromString(context, propName) inContext:context];
|
||||
|
||||
JS_EndRequest(context);
|
||||
[[OOJavaScriptEngine sharedEngine] releaseContext:context];
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)defineProperty:(id)value named:(NSString *)propName
|
||||
- (BOOL) defineProperty:(id)value named:(NSString *)propName
|
||||
{
|
||||
jsval jsValue;
|
||||
JSContext *context = NULL;
|
||||
BOOL result = NO;
|
||||
|
||||
if (value == nil || propName == nil) return NO;
|
||||
|
||||
context = [[OOJavaScriptEngine sharedEngine] acquireContext];
|
||||
jsValue = [value oo_jsValueInContext:context];
|
||||
if (!JSVAL_IS_VOID(jsValue))
|
||||
{
|
||||
result = OOJSDefineProperty(context, _jsSelf, propName, jsValue, NULL, NULL, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
|
||||
}
|
||||
JSContext *context = [[OOJavaScriptEngine sharedEngine] acquireContext];
|
||||
JS_BeginRequest(context);
|
||||
|
||||
BOOL result = [self defineProperty:value withID:OOJSPropIDFromString(context, propName) inContext:context];
|
||||
|
||||
JS_EndRequest(context);
|
||||
[[OOJavaScriptEngine sharedEngine] releaseContext:context];
|
||||
return result;
|
||||
}
|
||||
|
@ -122,6 +122,25 @@ enum
|
||||
@end
|
||||
|
||||
|
||||
/* OOJSPropID
|
||||
A temporary type to identify JavaScript object properties/methods. When
|
||||
OO_NEW_JS is folded, it will be replaced with jsid.
|
||||
|
||||
OOJS_PROPID(context, const char *)
|
||||
Macro to create a string-based ID. The string is interned and converted
|
||||
into a string by a helper the first time the macro is hit, then cached.
|
||||
*/
|
||||
#if OO_NEW_JS
|
||||
typedef jsid OOJSPropID;
|
||||
#define OOJS_PROPID(context, str) ({ static jsid idCache; static BOOL inited; if (EXPECT_NOT(!inited)) OOJSInitPropIDCachePRIVATE(context, str, &idCache, &inited); idCache; })
|
||||
void OOJSInitPropIDCachePRIVATE(JSContext *context, const char *name, jsid *idCache, BOOL *inited);
|
||||
#else
|
||||
typedef const char *OOJSPropID;
|
||||
#define OOJS_PROPID(context, str) (str)
|
||||
#endif
|
||||
OOJSPropID OOJSPropIDFromString(JSContext *context, NSString *string);
|
||||
|
||||
|
||||
/* Error and warning reporters.
|
||||
|
||||
Note that after reporting an error in a JavaScript callback, the caller
|
||||
@ -173,18 +192,6 @@ OOINLINE jsval OOJSValueFromBOOL(int b)
|
||||
}
|
||||
|
||||
|
||||
/* OOJSFooProperty()
|
||||
|
||||
Wrappers to corresponding JS_FooProperty()/JS_FooUCProperty() functions,
|
||||
but taking an NSString.
|
||||
|
||||
Require a request on context.
|
||||
*/
|
||||
BOOL OOJSGetProperty(JSContext *context, JSObject *object, NSString *name, jsval *value);
|
||||
BOOL OOJSSetProperty(JSContext *context, JSObject *object, NSString *name, jsval *value);
|
||||
BOOL OOJSDefineProperty(JSContext *context, JSObject *object, NSString *name, jsval value, JSPropertyOp getter, JSPropertyOp setter, uintN attrs);
|
||||
|
||||
|
||||
@interface NSObject (OOJavaScript)
|
||||
|
||||
/* -oo_jsValueInContext:
|
||||
|
@ -900,7 +900,57 @@ void OOJSMarkConsoleEvalLocation(JSContext *context, JSStackFrame *stackFrame)
|
||||
{
|
||||
GetLocationNameAndLine(context, stackFrame, &sConsoleScriptName, &sConsoleEvalLineNo);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if OO_NEW_JS
|
||||
void OOJSInitPropIDCachePRIVATE(JSContext *context, const char *name, jsid *idCache, BOOL *inited)
|
||||
{
|
||||
NSCParameterAssert(context != NULL && JS_IsInRequest(context));
|
||||
NSCParameterAssert(name != NULL && idCache != NULL && inited != NULL && !*inited);
|
||||
|
||||
JSString *string = JS_InternString(context, name);
|
||||
if (EXPECT_NOT(string == NULL))
|
||||
{
|
||||
[NSException raise:NSGenericException format:@"Failed to initialize JS ID cache for \"%s\".", name];
|
||||
}
|
||||
|
||||
*idCache = INTERNED_STRING_TO_JSID(string);
|
||||
*inited = YES;
|
||||
}
|
||||
|
||||
|
||||
OOJSPropID OOJSPropIDFromString(JSContext *context, NSString *string)
|
||||
{
|
||||
NSCParameterAssert(context != NULL && JS_IsInRequest(context) && string != nil);
|
||||
|
||||
enum { kStackBufSize = 1024 };
|
||||
unichar stackBuf[kStackBufSize];
|
||||
unichar *buffer;
|
||||
size_t length = [string length];
|
||||
if (length < kStackBufSize)
|
||||
{
|
||||
buffer = stackBuf;
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer = malloc(sizeof (unichar) * length);
|
||||
if (EXPECT_NOT(buffer == NULL)) return JSID_VOID;
|
||||
}
|
||||
[string getCharacters:buffer];
|
||||
|
||||
JSString *jsString = JS_InternUCStringN(context, buffer, length);
|
||||
if (EXPECT_NOT(jsString == NULL)) return JSID_VOID;
|
||||
|
||||
if (EXPECT_NOT(buffer != stackBuf)) free(buffer);
|
||||
|
||||
return INTERNED_STRING_TO_JSID(jsString);
|
||||
}
|
||||
#else
|
||||
OOJSPropID OOJSPropIDFromString(JSContext *context, NSString *string)
|
||||
{
|
||||
return [string UTF8String];
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@ -1090,92 +1140,6 @@ BOOL OOJSArgumentListGetNumberNoError(JSContext *context, uintN argc, jsval *arg
|
||||
}
|
||||
|
||||
|
||||
static BOOL ExtractString(NSString *string, jschar **outString, size_t *outLength)
|
||||
{
|
||||
OOJS_PROFILE_ENTER
|
||||
|
||||
assert(outString != NULL && outLength != NULL);
|
||||
assert(sizeof (unichar) == sizeof (jschar)); // Should both be 16 bits
|
||||
|
||||
*outLength = [string length];
|
||||
if (*outLength == 0) return NO; // nil/empty strings not accepted.
|
||||
|
||||
*outString = malloc(sizeof (unichar) * *outLength);
|
||||
if (*outString == NULL) return NO;
|
||||
|
||||
[string getCharacters:(unichar *)*outString];
|
||||
return YES;
|
||||
|
||||
OOJS_PROFILE_EXIT
|
||||
}
|
||||
|
||||
|
||||
BOOL OOJSGetProperty(JSContext *context, JSObject *object, NSString *name, jsval *value)
|
||||
{
|
||||
OOJS_PROFILE_ENTER
|
||||
|
||||
jschar *buffer = NULL;
|
||||
size_t length;
|
||||
BOOL OK = NO;
|
||||
|
||||
NSCParameterAssert(context != NULL && name != nil);
|
||||
|
||||
if (ExtractString(name, &buffer, &length))
|
||||
{
|
||||
OK = JS_GetUCProperty(context, object, buffer, length, value);
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
return OK;
|
||||
|
||||
OOJS_PROFILE_EXIT
|
||||
}
|
||||
|
||||
|
||||
BOOL OOJSSetProperty(JSContext *context, JSObject *object, NSString *name, jsval *value)
|
||||
{
|
||||
OOJS_PROFILE_ENTER
|
||||
|
||||
jschar *buffer = NULL;
|
||||
size_t length;
|
||||
BOOL OK = NO;
|
||||
|
||||
NSCParameterAssert(context != NULL && name != nil);
|
||||
|
||||
if (ExtractString(name, &buffer, &length))
|
||||
{
|
||||
OK = JS_SetUCProperty(context, object, buffer, length, value);
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
return OK;
|
||||
|
||||
OOJS_PROFILE_EXIT
|
||||
}
|
||||
|
||||
|
||||
BOOL OOJSDefineProperty(JSContext *context, JSObject *object, NSString *name, jsval value, JSPropertyOp getter, JSPropertyOp setter, uintN attrs)
|
||||
{
|
||||
OOJS_PROFILE_ENTER
|
||||
|
||||
jschar *buffer = NULL;
|
||||
size_t length;
|
||||
BOOL OK = NO;
|
||||
|
||||
NSCParameterAssert(context != NULL && name != nil);
|
||||
|
||||
if (ExtractString(name, &buffer, &length))
|
||||
{
|
||||
OK = JS_DefineUCProperty(context, object, buffer, length, value, getter, setter, attrs);
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
return OK;
|
||||
|
||||
OOJS_PROFILE_EXIT
|
||||
}
|
||||
|
||||
|
||||
static JSObject *JSArrayFromNSArray(JSContext *context, NSArray *array)
|
||||
{
|
||||
OOJS_PROFILE_ENTER
|
||||
@ -1272,7 +1236,7 @@ static JSObject *JSObjectFromNSDictionary(JSContext *context, NSDictionary *dict
|
||||
value = [[dictionary objectForKey:key] oo_jsValueInContext:context];
|
||||
if (!JSVAL_IS_VOID(value))
|
||||
{
|
||||
OK = OOJSSetProperty(context, result, key, &value);
|
||||
OK = OOJSSetProperty(context, result, OOJSPropIDFromString(context, key), &value);
|
||||
if (EXPECT_NOT(!OK)) break;
|
||||
}
|
||||
}
|
||||
@ -1536,7 +1500,14 @@ NSString *OOStringFromJSPropertyID(JSContext *context, jsval propID, JSPropertyS
|
||||
}
|
||||
}
|
||||
|
||||
return @"<unknown>";
|
||||
jsval value;
|
||||
#if OO_NEW_JS
|
||||
if (!JS_IdToValue(context, propID, &value)) return @"unknown";
|
||||
#else
|
||||
value = propID;
|
||||
#endif
|
||||
|
||||
return OOStringFromJSString(context, JS_ValueToString(context, value));
|
||||
}
|
||||
|
||||
|
||||
|
@ -67,10 +67,4 @@ MA 02110-1301, USA.
|
||||
- (BOOL)doEvent:(NSString *)eventName withArguments:(NSArray *)arguments;
|
||||
- (BOOL)doEvent:(NSString *)eventName withArgument:(id)argument;
|
||||
|
||||
- (id)propertyNamed:(NSString *)name;
|
||||
// Set a property which can be modified or deleted by the script.
|
||||
- (BOOL)setProperty:(id)value named:(NSString *)name;
|
||||
// Set a special property which cannot be modified or deleted by the script.
|
||||
- (BOOL)defineProperty:(id)value named:(NSString *)name;
|
||||
|
||||
@end
|
||||
|
@ -280,22 +280,4 @@ static NSString * const kOOLogLoadScriptNone = @"script.load.none";
|
||||
return [self doEvent:eventName withArguments:[NSArray arrayWithObject:argument]];
|
||||
}
|
||||
|
||||
|
||||
- (id)propertyNamed:(NSString *)name
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)setProperty:(id)value named:(NSString *)name
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)defineProperty:(id)value named:(NSString *)name
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
@end
|
||||
|
Loading…
x
Reference in New Issue
Block a user