LCOV - code coverage report
Current view: top level - Core/Scripting - OOJavaScriptEngine.h (source / functions) Hit Total Coverage
Test: coverxygen.info Lines: 0 142 0.0 %
Date: 2025-05-28 07:50:54 Functions: 0 0 -

          Line data    Source code
       1           0 : /*
       2             : 
       3             : OOJavaScriptEngine.h
       4             : 
       5             : JavaScript support for Oolite
       6             : Copyright (C) 2007-2013 David Taylor and Jens Ayton.
       7             : 
       8             : This program is free software; you can redistribute it and/or
       9             : modify it under the terms of the GNU General Public License
      10             : as published by the Free Software Foundation; either version 2
      11             : of the License, or (at your option) any later version.
      12             : 
      13             : This program is distributed in the hope that it will be useful,
      14             : but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             : GNU General Public License for more details.
      17             : 
      18             : You should have received a copy of the GNU General Public License
      19             : along with this program; if not, write to the Free Software
      20             : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
      21             : MA 02110-1301, USA.
      22             : 
      23             : */
      24             : 
      25             : 
      26             : #import "OOCocoa.h"
      27             : #import "Universe.h"
      28             : #import "PlayerEntity.h"
      29             : #import "PlayerEntityLegacyScriptEngine.h"
      30             : #include <jsapi.h>
      31             : 
      32             : 
      33           0 : #define OOJSENGINE_MONITOR_SUPPORT OOLITE_DEBUG
      34             : 
      35             : 
      36             : #import "OOJSPropID.h"
      37             : 
      38             : 
      39             : @protocol OOJavaScriptEngineMonitor;
      40             : 
      41             : 
      42           0 : @interface OOJavaScriptEngine: NSObject
      43             : {
      44             : @private
      45           0 :         JSRuntime                                               *_runtime;
      46           0 :         JSObject                                                *_globalObject;
      47           0 :         BOOL                                                    _showErrorLocations;
      48             :         
      49           0 :         JSClass                                                 *_objectClass;
      50           0 :         JSClass                                                 *_stringClass;
      51           0 :         JSClass                                                 *_arrayClass;
      52           0 :         JSClass                                                 *_numberClass;
      53           0 :         JSClass                                                 *_booleanClass;
      54             :         
      55             : #ifndef NDEBUG
      56           0 :         BOOL                                                    _dumpStackForErrors;
      57           0 :         BOOL                                                    _dumpStackForWarnings;
      58             : #endif
      59             : #if OOJSENGINE_MONITOR_SUPPORT
      60             :         id<OOJavaScriptEngineMonitor>     _monitor;
      61             : #endif
      62             : }
      63             : 
      64           0 : + (OOJavaScriptEngine *) sharedEngine;
      65             : 
      66           0 : - (JSObject *) globalObject;
      67             : 
      68           0 : - (void) runMissionCallback;
      69             : 
      70             : /*      Tear down context and global object and rebuild them from scratch. This
      71             :         invalidates -globalObject and the main thread context.
      72             : */
      73           0 : - (BOOL) reset;
      74             : 
      75             : // Call a JS function, setting up new contexts as necessary. Caller is responsible for ensuring the jsval passed really is a function.
      76           0 : - (BOOL) callJSFunction:(jsval)function
      77             :                           forObject:(JSObject *)jsThis
      78             :                                    argc:(uintN)argc
      79             :                                    argv:(jsval *)argv
      80             :                                  result:(jsval *)outResult;
      81             : 
      82           0 : - (void) removeGCObjectRoot:(JSObject **)rootPtr;
      83           0 : - (void) removeGCValueRoot:(jsval *)rootPtr;
      84             : 
      85           0 : - (void) garbageCollectionOpportunity:(BOOL)force;
      86             : 
      87           0 : - (BOOL) showErrorLocations;
      88           0 : - (void) setShowErrorLocations:(BOOL)value;
      89             : 
      90           0 : - (JSClass *) objectClass;
      91           0 : - (JSClass *) stringClass;
      92           0 : - (JSClass *) arrayClass;
      93           0 : - (JSClass *) numberClass;
      94           0 : - (JSClass *) booleanClass;
      95             : 
      96             : #ifndef NDEBUG
      97           0 : - (BOOL) dumpStackForErrors;
      98           0 : - (void) setDumpStackForErrors:(BOOL)value;
      99             : 
     100           0 : - (BOOL) dumpStackForWarnings;
     101           0 : - (void) setDumpStackForWarnings:(BOOL)value;
     102             : 
     103             : // Install handler for JS "debugger" statment.
     104           0 : - (void) enableDebuggerStatement;
     105             : #endif
     106             : 
     107             : @end
     108             : 
     109             : 
     110             : #if !JS_THREADSAFE
     111           0 : #define JS_IsInRequest(context)         (((void)(context)), YES)
     112           0 : #define JS_BeginRequest(context)        do {} while (0)
     113           0 : #define JS_EndRequest(context)          do {} while (0)
     114             : #endif
     115             : 
     116             : 
     117             : // Get the main thread's JS context, and begin a request on it.
     118           0 : OOINLINE JSContext *OOJSAcquireContext(void)
     119             : {
     120             :         extern JSContext *gOOJSMainThreadContext;
     121             :         NSCAssert(gOOJSMainThreadContext != NULL, @"Attempt to use JavaScript context before JavaScript engine is initialized.");
     122             :         JS_BeginRequest(gOOJSMainThreadContext);
     123             :         return gOOJSMainThreadContext;
     124             : }
     125             : 
     126             : 
     127             : // End a request on the main thread's context.
     128           0 : OOINLINE void OOJSRelinquishContext(JSContext *context)
     129             : {
     130             : #ifndef NDEBUG
     131             :         extern JSContext *gOOJSMainThreadContext;
     132             :         NSCParameterAssert(context == gOOJSMainThreadContext && JS_IsInRequest(context));
     133             : #endif
     134             :         JS_EndRequest(context);
     135             : }
     136             : 
     137             : 
     138             : // Notifications sent when JavaScript engine is reset.
     139           0 : extern NSString * const kOOJavaScriptEngineWillResetNotification;
     140           0 : extern NSString * const kOOJavaScriptEngineDidResetNotification;
     141             : 
     142             : 
     143             : /*      Error and warning reporters.
     144             :         
     145             :         Note that after reporting an error in a JavaScript callback, the caller
     146             :         must return NO to signal an error.
     147             : */
     148           0 : void OOJSReportError(JSContext *context, NSString *format, ...);
     149           0 : void OOJSReportErrorWithArguments(JSContext *context, NSString *format, va_list args);
     150           0 : void OOJSReportErrorForCaller(JSContext *context, NSString *scriptClass, NSString *function, NSString *format, ...);
     151             : 
     152           0 : void OOJSReportWarning(JSContext *context, NSString *format, ...);
     153           0 : void OOJSReportWarningWithArguments(JSContext *context, NSString *format, va_list args);
     154           0 : void OOJSReportWarningForCaller(JSContext *context, NSString *scriptClass, NSString *function, NSString *format, ...);
     155             : 
     156           0 : void OOJSReportBadPropertySelector(JSContext *context, JSObject *thisObj, jsid propID, JSPropertySpec *propertySpec);
     157           0 : void OOJSReportBadPropertyValue(JSContext *context, JSObject *thisObj, jsid propID, JSPropertySpec *propertySpec, jsval value);
     158           0 : void OOJSReportBadArguments(JSContext *context, NSString *scriptClass, NSString *function, uintN argc, jsval *argv, NSString *message, NSString *expectedArgsDescription);
     159             : 
     160             : /*      OOJSSetWarningOrErrorStackSkip()
     161             :         
     162             :         Indicate that the direct call site is not relevant for error handler.
     163             :         Currently, if non-zero, no call site information is provided.
     164             :         Ideally, we'd stack crawl instead.
     165             : */
     166           0 : void OOJSSetWarningOrErrorStackSkip(unsigned skip);
     167             : 
     168             : 
     169             : /*      OOJSArgumentListGetNumber()
     170             :         
     171             :         Get a single number from an argument list. The optional outConsumed
     172             :         argument can be used to find out how many parameters were used (currently,
     173             :         this will be 0 on failure, otherwise 1).
     174             :         
     175             :         On failure, it will return NO and raise an error. If the caller is a JS
     176             :         callback, it must return NO to signal an error.
     177             : */
     178           0 : BOOL OOJSArgumentListGetNumber(JSContext *context, NSString *scriptClass, NSString *function, uintN argc, jsval *argv, double *outNumber, uintN *outConsumed);
     179             : 
     180             : /*      OOJSArgumentListGetNumberNoError()
     181             :         
     182             :         Like OOJSArgumentListGetNumber(), but does not report an error on failure.
     183             : */
     184           0 : BOOL OOJSArgumentListGetNumberNoError(JSContext *context, uintN argc, jsval *argv, double *outNumber, uintN *outConsumed);
     185             : 
     186             : 
     187             : // Typed as int rather than BOOL to work with more general expressions such as bitfield tests.
     188             : OOINLINE jsval OOJSValueFromBOOL(int b) INLINE_CONST_FUNC;
     189           0 : OOINLINE jsval OOJSValueFromBOOL(int b)
     190             : {
     191             :         return BOOLEAN_TO_JSVAL(b != NO);
     192             : }
     193             : 
     194             : 
     195             : @interface NSObject (OOJavaScript)
     196             : 
     197             : /*      -oo_jsValueInContext:
     198             :         
     199             :         Return the JavaScript value representation of an object. The default
     200             :         implementation returns JSVAL_VOID.
     201             :         
     202             :         SAFETY NOTE: if this message is sent to nil, the return value depends on
     203             :         the platform and whether JS_USE_JSVAL_JSID_STRUCT_TYPES is set. If the
     204             :         receiver may be nil, use OOJSValueFromNativeObject() instead.
     205             :         
     206             :         One case where it is safe to use oo_jsValueInContext: is with objects
     207             :         retrieved from Foundation collections, as they can never be nil.
     208             :         
     209             :         Requires a request on context.
     210             : */
     211           0 : - (jsval) oo_jsValueInContext:(JSContext *)context;
     212             : 
     213             : /*      -oo_jsDescription
     214             :         -oo_jsDescriptionWithClassName:
     215             :         -oo_jsClassName
     216             :         
     217             :         See comments for -descriptionComponents in OOCocoa.h.
     218             : */
     219           0 : - (NSString *) oo_jsDescription;
     220           0 : - (NSString *) oo_jsDescriptionWithClassName:(NSString *)className;
     221           0 : - (NSString *) oo_jsClassName;
     222             : 
     223             : /*      oo_clearJSSelf:
     224             :         This is called by OOJSObjectWrapperFinalize() when a JS object wrapper is
     225             :         collected. The default implementation does nothing.
     226             : */
     227           0 : - (void) oo_clearJSSelf:(JSObject *)selfVal;
     228             : 
     229             : @end
     230             : 
     231             : 
     232             : /*      OOJSValueFromNativeObject()
     233             :         Return a JavaScript value representation of an object, or null if passed
     234             :         nil.
     235             :         
     236             :         Requires a request on context.
     237             : */
     238           0 : OOINLINE jsval OOJSValueFromNativeObject(JSContext *context, id object)
     239             : {
     240             :         if (object != nil)  return [object oo_jsValueInContext:context];
     241             :         return  JSVAL_NULL;
     242             : }
     243             : 
     244             : 
     245             : /*      OOJSObjectFromNativeObject()
     246             :         Return a JavaScript object representation of an object, or null if passed
     247             :         nil. The value is boxed if necessary.
     248             :         
     249             :         Requires a request on context.
     250             : */
     251           0 : JSObject *OOJSObjectFromNativeObject(JSContext *context, id object);
     252             : 
     253             : 
     254             : /*      OOJSValue: an object whose purpose in life is to hold a JavaScript value.
     255             :         This is somewhat useful for putting JavaScript objects in ObjC collections,
     256             :         for instance to pass as properties to script loaders. The value is
     257             :         GC rooted for the lifetime of the OOJSValue.
     258             :         
     259             :         All methods take a context parameter, which must either be nil or a context
     260             :         in a request.
     261             : */
     262           0 : @interface OOJSValue: NSObject
     263             : {
     264           0 :         jsval                                   _val;
     265             : }
     266             : 
     267           0 : + (id) valueWithJSValue:(jsval)value inContext:(JSContext *)context;
     268           0 : + (id) valueWithJSObject:(JSObject *)object inContext:(JSContext *)context;
     269             : 
     270           0 : - (id) initWithJSValue:(jsval)value inContext:(JSContext *)context;
     271           0 : - (id) initWithJSObject:(JSObject *)object inContext:(JSContext *)context;
     272             : 
     273             : @end
     274             : 
     275             : 
     276             : 
     277             : /**** String utilities ****/
     278             : 
     279             : /*      OOJSSTR(const char * [literal])
     280             :         
     281             :         Create and cache a jsval referring to an interned string literal.
     282             : */
     283           0 : #define OOJSSTR(str) ({ static jsval strCache; static BOOL inited; if (EXPECT_NOT(!inited)) OOJSStrLiteralCachePRIVATE(""str, &strCache, &inited); strCache; })
     284           0 : void OOJSStrLiteralCachePRIVATE(const char *string, jsval *strCache, BOOL *inited);
     285             : 
     286             : 
     287             : // Convert a JSString to an NSString.
     288           0 : NSString *OOStringFromJSString(JSContext *context, JSString *string);
     289             : 
     290             : /*      Convert an arbitrary JS object to an NSString, calling JS_ValueToString.
     291             :         OOStringFromJSValue() returns nil if value is null or undefined,
     292             :         OOStringFromJSValueEvenIfNull() returns "null" or "undefined".
     293             : */
     294           0 : NSString *OOStringFromJSValue(JSContext *context, jsval value);
     295           0 : NSString *OOStringFromJSValueEvenIfNull(JSContext *context, jsval value);
     296             : 
     297             : 
     298             : /*      OOStringFromJSPropertyIDAndSpec(context, propID, propertySpec)
     299             :         
     300             :         Returns the name of a property given either a name or a tinyid. (Intended
     301             :         for error reporting inside JSPropertyOps.)
     302             : */
     303           0 : NSString *OOStringFromJSPropertyIDAndSpec(JSContext *context, jsid propID, JSPropertySpec *propertySpec);
     304             : 
     305             : 
     306             : /*      Describe a value for debugging or error reporting. Strings are quoted,
     307             :         escaped and limited in length. Functions are described as "function foo"
     308             :         (or just "function" if they're anonymous). Up to four elements of arrays
     309             :         are included, followed by total count of there are more than four.
     310             :         If abbreviateObjects, the description "[object Object]" is replaced with
     311             :         "{...}", which may or may not be clearer depending on context.
     312             : */
     313           0 : NSString *OOJSDescribeValue(JSContext *context, jsval value, BOOL abbreviateObjects);
     314             : 
     315             : 
     316             : // Convert a jsid to an NSString.
     317           0 : NSString *OOStringFromJSID(jsid propID);
     318             : 
     319             : // Convert an NSString to a jsid.
     320           0 : jsid OOJSIDFromString(NSString *string);
     321             : 
     322             : 
     323             : @interface NSString (OOJavaScriptExtensions)
     324             : 
     325             : // For diagnostic messages; produces things like @"(42, true, "a string", an object description)".
     326           0 : + (NSString *) stringWithJavaScriptParameters:(jsval *)params count:(uintN)count inContext:(JSContext *)context;
     327             : 
     328             : // Concatenate sequence of arbitrary JS objects into string.
     329           0 : + (NSString *) concatenationOfStringsFromJavaScriptValues:(jsval *)values count:(size_t)count separator:(NSString *)separator inContext:(JSContext *)context;
     330             : 
     331             : // Add escape codes for string so that it's a valid JavaScript literal (if you put "" or '' around it).
     332           0 : - (NSString *) escapedForJavaScriptLiteral;
     333             : 
     334             : @end
     335             : 
     336             : 
     337             : // OOEntityFilterPredicate wrapping a JavaScript function.
     338           0 : typedef struct
     339             : {
     340           0 :         JSContext                               *context;
     341           0 :         jsval                                   function;       // Caller is responsible for ensuring this is a function object (using OOJSValueIsFunction()).
     342           0 :         JSObject                                *jsThis;
     343           0 :         BOOL                                    errorFlag;      // Set if a JS exception occurs. The
     344             :                                                                                 // exception will have been reported.
     345             :                                                                                 // This also supresses further filtering.
     346             : } JSFunctionPredicateParameter;
     347           0 : BOOL JSFunctionPredicate(Entity *entity, void *parameter);
     348             : 
     349             : // YES for ships and (normal) planets. Parameter: ignored.
     350           0 : BOOL JSEntityIsJavaScriptVisiblePredicate(Entity *entity, void *parameter);
     351             : 
     352             : // YES for ships other than sub-entities and menu-display ships, and planets other than atmospheres and menu miniatures. Parameter: ignored.
     353           0 : BOOL JSEntityIsJavaScriptSearchablePredicate(Entity *entity, void *parameter);
     354             : 
     355             : // YES for menu-display ships. Parameter: ignored
     356           0 : BOOL JSEntityIsDemoShipPredicate(Entity *entity, void *parameter);
     357             : 
     358             : 
     359             : // These require a request on context.
     360           0 : id OOJSNativeObjectFromJSValue(JSContext *context, jsval value);
     361           0 : id OOJSNativeObjectFromJSObject(JSContext *context, JSObject *object);
     362           0 : id OOJSNativeObjectOfClassFromJSValue(JSContext *context, jsval value, Class requiredClass);
     363           0 : id OOJSNativeObjectOfClassFromJSObject(JSContext *context, JSObject *object, Class requiredClass);
     364             : 
     365             : 
     366             : OOINLINE JSClass *OOJSGetClass(JSContext *cx, JSObject *obj)  ALWAYS_INLINE_FUNC;
     367           0 : OOINLINE JSClass *OOJSGetClass(JSContext *cx, JSObject *obj)
     368             : {
     369             : #if JS_THREADSAFE
     370             :         return JS_GetClass(cx, obj);
     371             : #else
     372             :         return JS_GetClass(obj);
     373             : #endif
     374             : }
     375             : 
     376             : 
     377             : /*      OOJSValueIsFunction(context, value)
     378             :         
     379             :         Test whether a jsval is a function object. The main tripping point here
     380             :         is that JSVAL_IS_OBJECT() is true for JSVAL_NULL, but JS_ObjectIsFunction()
     381             :         crashes if passed null.
     382             : */
     383           0 : OOINLINE BOOL OOJSValueIsFunction(JSContext *context, jsval value)
     384             : {
     385             :         return JSVAL_IS_OBJECT(value) && !JSVAL_IS_NULL(value) && JS_ObjectIsFunction(context, JSVAL_TO_OBJECT(value));
     386             : }
     387             : 
     388             : 
     389             : /*      OOJSValueIsArray(context, value)
     390             :         
     391             :         Test whether a jsval is an array object. The main tripping point here
     392             :         is that JSVAL_IS_OBJECT() is true for JSVAL_NULL, but JS_IsArrayObject()
     393             :         crashes if passed null.
     394             :         
     395             :         Also, it should be called JS_ObjectIsArray() for consistency.
     396             : */
     397           0 : OOINLINE BOOL OOJSValueIsArray(JSContext *context, jsval value)
     398             : {
     399             :         return JSVAL_IS_OBJECT(value) && !JSVAL_IS_NULL(value) && JS_IsArrayObject(context, JSVAL_TO_OBJECT(value));
     400             : }
     401             : 
     402             : 
     403             : /*      OOJSDictionaryFromJSValue(context, value)
     404             :         OOJSDictionaryFromJSObject(context, object)
     405             :         
     406             :         Converts a JavaScript value to a dictionary by calling
     407             :         OOJSNativeObjectFromJSValue() on each of its values.
     408             :         
     409             :         Only enumerable own (i.e., not inherited) properties with string keys are
     410             :         included.
     411             :         
     412             :         Requires a request on context.
     413             : */
     414           0 : NSDictionary *OOJSDictionaryFromJSValue(JSContext *context, jsval value);
     415           0 : NSDictionary *OOJSDictionaryFromJSObject(JSContext *context, JSObject *object);
     416             : 
     417             : 
     418             : /*      OOJSDictionaryFromStringTable(context, value)
     419             :         
     420             :         Treat an arbitrary JavaScript object as a dictionary mapping strings to
     421             :         strings, and convert to a corresponding NSDictionary. The values are
     422             :         converted to strings using JS_ValueToString().
     423             :         
     424             :         Only enumerable own (i.e., not inherited) properties with string keys are
     425             :         included.
     426             :         
     427             :         Requires a request on context.
     428             : */
     429           0 : NSDictionary *OOJSDictionaryFromStringTable(JSContext *context, jsval value);
     430             : 
     431             : 
     432             : /*
     433             :         DEFINE_JS_OBJECT_GETTER()
     434             :         Defines a helper to extract Objective-C objects from the private field of
     435             :         JS objects, with runtime type checking. The generated accessor requires
     436             :         a request on context. Weakrefs are automatically unpacked.
     437             :         
     438             :         Types which extend other types, such as entity subtypes, must register
     439             :         their relationships with OOJSRegisterSubclass() below.
     440             :         
     441             :         The signature of the generator is:
     442             :         BOOL <name>(JSContext *context, JSObject *inObject, <class>** outObject)
     443             :         If it returns NO, inObject is of the wrong class and an error has been
     444             :         raised. Otherwise, outObject is either a native object of the specified
     445             :         class (or a subclass) or nil.
     446             : */
     447             : #ifndef NDEBUG
     448           0 : #define DEFINE_JS_OBJECT_GETTER(NAME, JSCLASS, JSPROTO, OBJCCLASSNAME) \
     449             : static BOOL NAME(JSContext *context, JSObject *inObject, OBJCCLASSNAME **outObject)  GCC_ATTR((unused)); \
     450             : static BOOL NAME(JSContext *context, JSObject *inObject, OBJCCLASSNAME **outObject) \
     451             : { \
     452             :         NSCParameterAssert(outObject != NULL); \
     453             :         static Class cls = Nil; \
     454             :         if (EXPECT_NOT(cls == Nil))  cls = [OBJCCLASSNAME class]; \
     455             :         return OOJSObjectGetterImplPRIVATE(context, inObject, JSCLASS, cls, #NAME, (id *)outObject); \
     456             : }
     457             : #else
     458             : #define DEFINE_JS_OBJECT_GETTER(NAME, JSCLASS, JSPROTO, OBJCCLASSNAME) \
     459             : OOINLINE BOOL NAME(JSContext *context, JSObject *inObject, OBJCCLASSNAME **outObject) \
     460             : { \
     461             :         return OOJSObjectGetterImplPRIVATE(context, inObject, JSCLASS, (id *)outObject); \
     462             : }
     463             : #endif
     464             : 
     465             : // For DEFINE_JS_OBJECT_GETTER()'s use.
     466             : #ifndef NDEBUG
     467           0 : BOOL OOJSObjectGetterImplPRIVATE(JSContext *context, JSObject *object, JSClass *requiredJSClass, Class requiredObjCClass, const char *name, id *outObject);
     468             : #else
     469             : BOOL OOJSObjectGetterImplPRIVATE(JSContext *context, JSObject *object, JSClass *requiredJSClass, id *outObject);
     470             : #endif
     471             : 
     472             : 
     473             : /*
     474             :         Subclass relationships.
     475             :         
     476             :         JSAPI doesn't have a concept of subclassing, as JavaScript doesn't have a
     477             :         concept of classes, but Oolite reflects part of its class hierarchy as
     478             :         related JSClasses whose prototypes inherit each other. For instance,
     479             :         JS Entity methods work on JS Ships. In order for this to work,
     480             :         OOJSEntityGetEntity() must be able to know that Ship is a subclass of
     481             :         Entity. This is done using OOJSIsSubclass().
     482             :         
     483             :         void OOJSRegisterSubclass(JSClass *subclass, JSClass *superclass)
     484             :         Register subclass as a subclass of superclass. Subclass must not previously
     485             :         have been registered as a subclass of any class (i.e., single inheritance
     486             :         is required).
     487             :  
     488             :         BOOL OOJSIsSubclass(JSClass *putativeSubclass, JSClass *superclass)
     489             :         Test whether putativeSubclass is a equal to superclass or a registered
     490             :         subclass of superclass, recursively.
     491             : */
     492           0 : void OOJSRegisterSubclass(JSClass *subclass, JSClass *superclass);
     493           0 : BOOL OOJSIsSubclass(JSClass *putativeSubclass, JSClass *superclass);
     494           0 : OOINLINE BOOL OOJSIsMemberOfSubclass(JSContext *context, JSObject *object, JSClass *superclass)
     495             : {
     496             :         return OOJSIsSubclass(OOJSGetClass(context, object), superclass);
     497             : }
     498             : 
     499             : 
     500             : /*      Support for OOJSNativeObjectFromJSValue() family
     501             :         
     502             :         OOJSClassConverterCallback specifies the prototype for a callback function
     503             :         which converts a JavaScript object to an Objective-C object.
     504             :         
     505             :         OOJSBasicPrivateObjectConverter() is a OOJSClassConverterCallback which
     506             :         returns the JS object's private storage value. It automatically unpacks
     507             :         OOWeakReferences if relevant.
     508             :         
     509             :         OOJSRegisterObjectConverter() registers a callback for a specific JS class.
     510             :         It is not automatically propagated to subclasses.
     511             : */
     512           0 : typedef id (*OOJSClassConverterCallback)(JSContext *context, JSObject *object);
     513           0 : id OOJSBasicPrivateObjectConverter(JSContext *context, JSObject *object);
     514             : 
     515           0 : void OOJSRegisterObjectConverter(JSClass *theClass, OOJSClassConverterCallback converter);
     516             : 
     517             : 
     518             : /*      JS root handling
     519             :         
     520             :         The name parameter to JS_AddNamed*Root is assigned with no overhead, not
     521             :         copied, but the strings serve no purpose in a release build so we may as
     522             :         well strip them out.
     523             :         
     524             :         In debug builds, this will deliberately cause an error if name is not a
     525             :         string literal.
     526             : */
     527             : #ifdef NDEBUG
     528             : #define OOJSAddGCValueRoot(context, root, name)         JS_AddValueRoot((context), (root))
     529             : #define OOJSAddGCStringRoot(context, root, name)        JS_AddStringRoot((context), (root))
     530             : #define OOJSAddGCObjectRoot(context, root, name)        JS_AddObjectRoot((context), (root))
     531             : #define OOJSAddGCThingRoot(context, root, name)         JS_AddGCThingRoot((context), (root))
     532             : #else
     533           0 : #define OOJSAddGCValueRoot(context, root, name)         JS_AddNamedValueRoot((context), (root), "" name)
     534           0 : #define OOJSAddGCStringRoot(context, root, name)        JS_AddNamedStringRoot((context), (root), "" name)
     535           0 : #define OOJSAddGCObjectRoot(context, root, name)        JS_AddNamedObjectRoot((context), (root), "" name)
     536           0 : #define OOJSAddGCThingRoot(context, root, name)         JS_AddNamedGCThingRoot((context), (root), "" name)
     537             : #endif
     538             : 
     539             : 
     540             : #if OOJSENGINE_MONITOR_SUPPORT
     541             : 
     542             : /*      Protocol for debugging "monitor" object.
     543             :         The monitor is an object -- in Oolite, or via Distributed Objects -- which
     544             :         is provided with debugging information by the OOJavaScriptEngine.
     545             : */
     546             : 
     547             : @protocol OOJavaScriptEngineMonitor <NSObject>
     548             : 
     549             : // Sent for JS errors or warnings.
     550             : - (oneway void)jsEngine:(in byref OOJavaScriptEngine *)engine
     551             :                                 context:(in JSContext *)context
     552             :                                   error:(in JSErrorReport *)errorReport
     553             :                           stackSkip:(in unsigned)stackSkip
     554             :                 showingLocation:(in BOOL)showLocation
     555             :                         withMessage:(in NSString *)message;
     556             : 
     557             : // Sent for JS log messages. Note: messageClass will be nil if Log() is used rather than LogWithClass().
     558             : - (oneway void)jsEngine:(in byref OOJavaScriptEngine *)engine
     559             :                                 context:(in JSContext *)context
     560             :                          logMessage:(in NSString *)message
     561             :                                 ofClass:(in NSString *)messageClass;
     562             : 
     563             : @end
     564             : 
     565             : 
     566             : @interface OOJavaScriptEngine (OOMonitorSupport)
     567             : 
     568             : - (void)setMonitor:(id<OOJavaScriptEngineMonitor>)monitor;
     569             : 
     570             : @end
     571             : 
     572             : #endif
     573             : 
     574             : 
     575             : #import "OOJSEngineNativeWrappers.h"
     576             : 
     577             : /*      See comments on time limiter in OOJSEngineTimeManagement.h.
     578             : */
     579           0 : void OOJSPauseTimeLimiter(void);
     580           0 : void OOJSResumeTimeLimiter(void);
     581             : 
     582             : 
     583             : /*      OOJSDumpStack()
     584             :         Write JavaScript stack to log.
     585             :         
     586             :         OOJSDescribeLocation()
     587             :         Get script and line number for a stack frame.
     588             :         
     589             :         OOJSMarkConsoleEvalLocation()
     590             :         Specify that a given stack frame identifies eval()ed code from the debug
     591             :         console, so that matching locations can be described specially by
     592             :         OOJSDescribeLocation().
     593             : */
     594             : #ifndef NDEBUG
     595           0 : void OOJSDumpStack(JSContext *context);
     596             : 
     597           0 : NSString *OOJSDescribeLocation(JSContext *context, JSStackFrame *stackFrame);
     598           0 : void OOJSMarkConsoleEvalLocation(JSContext *context, JSStackFrame *stackFrame);
     599             : #else
     600             : #define OOJSDumpStack(cx)                                               do {} while (0)
     601             : #define OOJSDescribeLocation(cx, frame)                 do {} while (0)
     602             : #define OOJSMarkConsoleEvalLocation(cx, frame)  do {} while (0)
     603             : #endif
     604             : 
     605             : 
     606             : 
     607             : 
     608             : /***** Reusable JS callbacks ****/
     609             : 
     610             : /*      OOJSUnconstructableConstruct
     611             :         
     612             :         Constructor callback for pseudo-classes which can't be constructed.
     613             : */
     614           0 : JSBool OOJSUnconstructableConstruct(JSContext *context, uintN argc, jsval *vp);
     615             : 
     616             : 
     617             : /*      OOJSObjectWrapperFinalize
     618             :         
     619             :         Finalizer for JS classes whose private storage is a retained object
     620             :         reference (generally an OOWeakReference, but doesn't have to be).
     621             : */
     622           0 : void OOJSObjectWrapperFinalize(JSContext *context, JSObject *this);
     623             : 
     624             : 
     625             : /*      OOJSObjectWrapperToString
     626             :         
     627             :         Implementation of toString() for JS classes whose private storage is an
     628             :         Objective-C object reference (generally an OOWeakReference).
     629             :         
     630             :         Calls -oo_jsDescription and, if that fails, -description.
     631             : */
     632           0 : JSBool OOJSObjectWrapperToString(JSContext *context, uintN argc, jsval *vp);
     633             : 
     634             : 
     635             : 
     636             : /***** Appropriate flags for host-defined read/write and read-only properties *****/
     637             : 
     638             : // Slot-based (defined with JS_Define{Property/Object/Function}() and no callbacks)
     639           0 : #define OOJS_PROP_READWRITE                             (JSPROP_PERMANENT | JSPROP_ENUMERATE)
     640           0 : #define OOJS_PROP_READONLY                              (JSPROP_PERMANENT | JSPROP_ENUMERATE | JSPROP_READONLY)
     641             : 
     642             : // Non-enumerable properties
     643           0 : #define OOJS_PROP_HIDDEN_READWRITE              (JSPROP_PERMANENT)
     644           0 : #define OOJS_PROP_HIDDEN_READONLY               (JSPROP_PERMANENT | JSPROP_READONLY)
     645             : 
     646             : // Methods should be non-enumerable
     647           0 : #define OOJS_METHOD_READONLY                    OOJS_PROP_HIDDEN_READONLY
     648             : 
     649             : // Callback-based (includes all properties specified in JSPropertySpecs)
     650           0 : #define OOJS_PROP_READWRITE_CB                  (OOJS_PROP_READWRITE | JSPROP_SHARED)
     651           0 : #define OOJS_PROP_READONLY_CB                   (OOJS_PROP_READONLY | JSPROP_SHARED)
     652             : 
     653           0 : #define OOJS_PROP_HIDDEN_READWRITE_CB   (OOJS_PROP_HIDDEN_READWRITE | JSPROP_SHARED)
     654           0 : #define OOJS_PROP_HIDDEN_READONLY_CB    (OOJS_PROP_HIDDEN_READONLY | JSPROP_SHARED)
     655             : 
     656             : 
     657             : 
     658             : 
     659             : /***** Helpers for native callbacks. *****/
     660           0 : #define OOJS_THIS                                               JS_THIS_OBJECT(context, vp)
     661           0 : #define OOJS_ARGV                                               JS_ARGV(context, vp)
     662           0 : #define OOJS_RVAL                                               JS_RVAL(context, vp)
     663           0 : #define OOJS_SET_RVAL(v)                                JS_SET_RVAL(context, vp, v)
     664             : 
     665           0 : #define OOJS_RETURN(v)                                  do { OOJS_SET_RVAL(v); return YES; } while (0)
     666           0 : #define OOJS_RETURN_JSOBJECT(o)                 OOJS_RETURN(OBJECT_TO_JSVAL(o))
     667           0 : #define OOJS_RETURN_VOID                                OOJS_RETURN(JSVAL_VOID)
     668           0 : #define OOJS_RETURN_NULL                                OOJS_RETURN(JSVAL_NULL)
     669           0 : #define OOJS_RETURN_BOOL(v)                             OOJS_RETURN(OOJSValueFromBOOL(v))
     670           0 : #define OOJS_RETURN_INT(v)                              OOJS_RETURN(INT_TO_JSVAL(v))
     671           0 : #define OOJS_RETURN_OBJECT(o)                   OOJS_RETURN(OOJSValueFromNativeObject(context, o))
     672             : 
     673           0 : #define OOJS_RETURN_WITH_HELPER(helper, value) \
     674             : do { \
     675             :         jsval jsresult; \
     676             :         BOOL OK = helper(context, value, &jsresult); \
     677             :         JS_SET_RVAL(context, vp, jsresult); return OK; \
     678             : } while (0)
     679             : 
     680           0 : #define OOJS_RETURN_VECTOR(value)               OOJS_RETURN_WITH_HELPER(VectorToJSValue, value)
     681           0 : #define OOJS_RETURN_HPVECTOR(value)             OOJS_RETURN_WITH_HELPER(HPVectorToJSValue, value)
     682           0 : #define OOJS_RETURN_QUATERNION(value)   OOJS_RETURN_WITH_HELPER(QuaternionToJSValue, value)
     683           0 : #define OOJS_RETURN_DOUBLE(value)               OOJS_RETURN_WITH_HELPER(JS_NewNumberValue, value)

Generated by: LCOV version 1.14