29#ifndef OO_EXCLUDE_DEBUG_SUPPORT
49@interface Entity (OODebugInspector)
64static JSBool
ConsoleGetProperty(JSContext *context, JSObject *
this, jsid propID, jsval *value);
65static JSBool
ConsoleSetProperty(JSContext *context, JSObject *
this, jsid propID, JSBool strict, jsval *value);
74static JSBool ConsoleCallObjCMethod(JSContext *context, uintN argc, jsval *vp);
75static JSBool ConsoleSetUpCallObjC(JSContext *context, uintN argc, jsval *vp);
85static JSBool ConsoleDumpNamedRoots(JSContext *context, uintN argc, jsval *vp);
86static JSBool ConsoleDumpHeap(JSContext *context, uintN argc, jsval *vp);
89static JSBool
ConsoleProfile(JSContext *context, uintN argc, jsval *vp);
91static JSBool
ConsoleTrace(JSContext *context, uintN argc, jsval *vp);
99static JSBool
PerformProfiling(JSContext *context, NSString *nominalFunction, uintN argc, jsval *argv, jsval *rval, BOOL trace,
OOTimeProfile **profile);
116 JSCLASS_NO_OPTIONAL_MEMBERS
173#define DEBUG_FLAG_DECL(x) { #x, kConsole_##x, OOJS_PROP_READONLY_CB }
186#undef DEBUG_FLAG_DECL
200 {
"__setUpCallObjC", ConsoleSetUpCallObjC, 1 },
210 {
"dumpNamedRoots", ConsoleDumpNamedRoots, 0 },
211 {
"dumpHeap", ConsoleDumpHeap, 0 },
235 JSCLASS_NO_OPTIONAL_MEMBERS
260 JSObject *
object = NULL;
261 JSObject *settingsObject = NULL;
264 NSCAssert(JS_EnterLocalRootScope(context),
@"Failed to create JS GC root scope");
276 if (!JS_SetPrivate(context,
object, [monitor weakRetain]))
object = NULL;
283 if (settingsObject != NULL)
285 if (!JS_SetPrivate(context, settingsObject, [monitor weakRetain])) settingsObject = NULL;
287 if (settingsObject != NULL)
289 value = OBJECT_TO_JSVAL(settingsObject);
290 if (!JS_SetProperty(context,
object,
"settings", &value))
292 settingsObject = NULL;
296 if (settingsObject == NULL)
object = NULL;
299 JS_LeaveLocalRootScope(context);
310 if (!JSID_IS_INT(propID))
return YES;
314 switch (JSID_TO_INT(propID))
323 *value = [OOStringFromGraphicsDetail([UNIVERSE detailLevel]) oo_jsValueInContext:context];
340 uint32_t options = JS_GetOptions(context);
377#define DEBUG_FLAG_CASE(x) case kConsole_##x: *value = INT_TO_JSVAL(x); break;
390#undef DEBUG_FLAG_CASE
403static JSBool
ConsoleSetProperty(JSContext *context, JSObject *
this, jsid propID, JSBool strict, jsval *value)
405 if (!JSID_IS_INT(propID))
return YES;
413 switch (JSID_TO_INT(propID))
417 if (JS_ValueToInt32(context, *value, &iValue))
426 [UNIVERSE setDetailLevel:OOGraphicsDetailFromString(sValue)];
431 if (JS_ValueToBoolean(context, *value, &bValue))
433 [UNIVERSE setDisplayFPS:bValue];
438 if (JS_ValueToBoolean(context, *value, &bValue))
440 uint32_t options = JS_GetOptions(context);
441 if (bValue) options |= JSOPTION_STRICT;
442 else options &= ~JSOPTION_STRICT;
444 JS_SetOptions(context, options);
449 if (JS_ValueToBoolean(context, *value, &bValue))
456 if (JS_ValueToBoolean(context, *value, &bValue))
463 if (JS_ValueToBoolean(context, *value, &bValue))
470 if (JS_ValueToBoolean(context, *value, &bValue))
522 [(id)JS_GetPrivate(context, this) release];
523 JS_SetPrivate(context,
this,
nil);
536 if (!JSID_IS_STRING(propID))
return NO;
542 OOJSReportError(context,
@"Expected OODebugMonitor, got %@ in %s. %@", [monitor
class], __PRETTY_FUNCTION__,
@"This is an internal error, please report it.");
546 [monitor setConfigurationValue:nil forKey:key];
556 if (!JSID_IS_STRING(propID))
return YES;
561 id settingValue =
nil;
569 OOJSReportError(context,
@"Expected OODebugMonitor, got %@ in %s. %@", [monitor
class], __PRETTY_FUNCTION__,
@"This is an internal error, please report it.");
573 settingValue = [monitor configurationValueForKey:key];
574 if (settingValue != NULL) *value = [settingValue oo_jsValueInContext:context];
575 else *value = JSVAL_VOID;
585 if (!JSID_IS_STRING(propID))
return YES;
590 id settingValue =
nil;
598 OOJSReportError(context,
@"Expected OODebugMonitor, got %@ in %s. %@", [monitor
class], __PRETTY_FUNCTION__,
@"This is an internal error, please report it.");
604 if (JSVAL_IS_NULL(*value) || JSVAL_IS_VOID(*value))
606 [monitor setConfigurationValue:nil forKey:key];
611 if (settingValue !=
nil)
613 [monitor setConfigurationValue:settingValue forKey:key];
633 NSRange emphasisRange = {0, 0};
638 NSString *colorKey =
nil,
640 jsdouble location, length;
647 OOJSReportError(context,
@"Expected OODebugMonitor, got %@ in %s. %@", [monitor
class], __PRETTY_FUNCTION__,
@"This is an internal error, please report it.");
658 if (JS_ValueToNumber(context,
OOJS_ARGV[2], &location) &&
659 JS_ValueToNumber(context,
OOJS_ARGV[3], &length))
661 emphasisRange = (NSRange){location, length};
669 OOJSReportWarning(context,
@"Console.consoleMessage() called with no parameters.");
674 colorKey =
@"command-result";
680 [monitor appendJSConsoleLine:message
682 emphasisRange:emphasisRange];
702 OOJSReportError(context,
@"Expected OODebugMonitor, got %@ in %s. %@", [monitor
class], __PRETTY_FUNCTION__,
@"This is an internal error, please report it.");
706 [monitor clearJSConsole];
734 if ([entity respondsToSelector:
@selector(
inspect)])
749static JSBool ConsoleCallObjCMethod(JSContext *context, uintN argc, jsval *vp)
777static JSBool ConsoleSetUpCallObjC(JSContext *context, uintN argc, jsval *vp)
787 JSObject *obj = JSVAL_TO_OBJECT(
OOJS_ARGV[0]);
802 JSObject *target = NULL;
804 if (argc < 2 || !JS_ValueToObject(context,
OOJS_ARGV[0], &target) || !JSVAL_IS_STRING(
OOJS_ARGV[1]))
814 NSData *stringData = [string dataUsingEncoding:NSUTF8StringEncoding];
815 result = JS_BufferIsCompilableUnit(context, target, [stringData bytes], [stringData length]);
830 NSString *messageClass =
nil;
844 NSString *messageClass =
nil;
848 if (messageClass !=
nil && JS_ValueToBoolean(context,
OOJS_ARGV[1], &flag))
905 uint32_t bytesBefore = JS_GetGCParameter(JS_GetRuntime(context), JSGC_BYTES);
907 uint32_t bytesAfter = JS_GetGCParameter(JS_GetRuntime(context), JSGC_BYTES);
909 OOJS_RETURN_OBJECT(([NSString stringWithFormat:
@"Bytes before: %u Bytes after: %u", bytesBefore, bytesAfter]));
922static void DumpCallback(
const char *name,
void *rp, JSGCRootType type,
void *datap)
924 assert(type == JS_GC_ROOT_VALUE_PTR || type == JS_GC_ROOT_GCTHING_PTR);
926 DumpCallbackData *data = datap;
928 const char *typeString =
"unknown type";
932 case JS_GC_ROOT_VALUE_PTR:
933 typeString =
"value";
934 value = *(jsval *)rp;
937 case JS_GC_ROOT_GCTHING_PTR:
938 typeString =
"gc-thing";
939 value = OBJECT_TO_JSVAL(*(JSObject **)rp);
942 fprintf(data->file,
"%s @ %p (%s): %s\n", name, rp, typeString, [
OOJSDescribeValue(data->context, value, NO) UTF8String]);
946static JSBool ConsoleDumpNamedRoots(JSContext *context, uintN argc, jsval *vp)
950 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
954 FILE *file = fopen([path UTF8String],
"w");
957 DumpCallbackData data =
962 JS_DumpNamedRoots(JS_GetRuntime(context), DumpCallback, &data);
974static JSBool ConsoleDumpHeap(JSContext *context, uintN argc, jsval *vp)
980 FILE *file = fopen([path UTF8String],
"w");
983 OK = JS_DumpHeap(context, file, NULL, 0, NULL, SIZE_MAX, NULL);
1003 OOJSReportError(context,
@"Profiling functions may not be called while already profiling.");
1007 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
1031 OOJSReportError(context,
@"Profiling functions may not be called while already profiling.");
1035 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
1058 OOJSReportError(context,
@"Profiling functions may not be called while already profiling.");
1062 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
1081 jsval
function = argv[0];
1090 if (argc > 1)
this = argv[1];
1094 assert(JSVAL_IS_OBJECT(debugConsole) && !JSVAL_IS_NULL(debugConsole));
1095 JS_GetProperty(context, JSVAL_TO_OBJECT(debugConsole),
"script", &
this);
1099 if (!JS_ValueToObject(context,
this, &thisObj)) thisObj = NULL;
1102 if (outRval == NULL) outRval = &ignored;
1106#define LONG_TIME (1e7)
1115 BOOL result = JS_CallFunctionValue(context, thisObj,
function, 0, NULL, outRval);
1119 if (outProfile != NULL) *outProfile = profile;
1125 JS_ReportPendingException(context);
@ DEBUG_SHADER_VALIDATION
@ DEBUG_NO_SHADER_FALLBACK
BOOL OOJSCallObjCObjectMethod(JSContext *context, id object, NSString *oo_jsClassName, uintN argc, jsval *argv, jsval *outResult)
static JSFunctionSpec sConsoleMethods[]
static BOOL DoWeDefineAllDebugFlags(enum OODebugFlags flags) GCC_ATTR((unused))
static JSBool ConsoleIsExecutableJavaScript(JSContext *context, uintN argc, jsval *vp)
#define DEBUG_FLAG_CASE(x)
static JSObject * sConsolePrototype
static void InitOOJSConsole(JSContext *context, JSObject *global)
static JSBool ConsoleTrace(JSContext *context, uintN argc, jsval *vp)
static JSBool ConsoleWriteJSMemoryStats(JSContext *context, uintN argc, jsval *vp)
static JSBool ConsoleGetProfile(JSContext *context, uintN argc, jsval *vp)
static JSBool ConsoleConsoleMessage(JSContext *context, uintN argc, jsval *vp)
static JSBool PerformProfiling(JSContext *context, NSString *nominalFunction, uintN argc, jsval *argv, jsval *rval, BOOL trace, OOTimeProfile **profile)
static JSBool ConsoleSettingsSetProperty(JSContext *context, JSObject *this, jsid propID, JSBool strict, jsval *value)
static JSBool ConsoleScriptStack(JSContext *context, uintN argc, jsval *vp)
static JSBool ConsoleGetProperty(JSContext *context, JSObject *this, jsid propID, jsval *value)
@ kConsole_DEBUG_COLLISIONS
@ kConsole_platformDescription
@ kConsole_DEBUG_DRAW_NORMALS
@ kConsole_DEBUG_OCTREE_LOGGING
@ kConsole_glVendorString
@ kConsole_dumpStackForErrors
@ kConsole_dumpStackForWarnings
@ kConsole_showErrorLocations
@ kConsole_ignoreDroppedPackets
@ kConsole_DEBUG_SHADER_VALIDATION
@ kConsole_DEBUG_OCTREE_DRAW
@ kConsole_DEBUG_BOUNDING_BOXES
@ kConsole_DEBUG_NO_SHADER_FALLBACK
@ kConsole_glRendererString
@ kConsole_maximumDetailLevel
@ kConsole_glFixedFunctionTextureUnitCount
@ kConsole_glFragmentShaderTextureUnitCount
@ kConsole_DEBUG_LINKED_LISTS
static JSBool ConsoleGarbageCollect(JSContext *context, uintN argc, jsval *vp)
static JSBool ConsoleWriteMemoryStats(JSContext *context, uintN argc, jsval *vp)
static JSBool ConsoleDisplayMessagesInClass(JSContext *context, uintN argc, jsval *vp)
JSObject * DebugMonitorToJSConsole(JSContext *context, OODebugMonitor *monitor)
NSString * OOPlatformDescription(void)
static JSBool ConsoleSetDisplayMessagesInClass(JSContext *context, uintN argc, jsval *vp)
static JSClass sConsoleClass
static JSBool ConsoleSettingsGetProperty(JSContext *context, JSObject *this, jsid propID, jsval *value)
static JSBool ConsoleSettingsDeleteProperty(JSContext *context, JSObject *this, jsid propID, jsval *value)
static JSBool ConsoleInspectEntity(JSContext *context, uintN argc, jsval *vp)
static JSClass sConsoleSettingsClass
static JSBool ConsoleProfile(JSContext *context, uintN argc, jsval *vp)
static JSBool ConsoleWriteLogMarker(JSContext *context, uintN argc, jsval *vp)
static JSPropertySpec sConsoleProperties[]
static JSBool ConsoleClearConsole(JSContext *context, uintN argc, jsval *vp)
static void ConsoleFinalize(JSContext *context, JSObject *this)
void OOJSConsoleDestroy(void)
#define DEBUG_FLAG_DECL(x)
static JSBool ConsoleSetProperty(JSContext *context, JSObject *this, jsid propID, JSBool strict, jsval *value)
static JSObject * sConsoleSettingsPrototype
#define OOJS_PROFILE_EXIT
#define OOJS_PROFILE_EXIT_VOID
#define OOJS_END_FULL_NATIVE
#define OOJS_BEGIN_FULL_NATIVE(context)
#define OOJS_NATIVE_ENTER(cx)
#define OOJS_PROFILE_ENTER
OOTimeProfile * OOJSEndProfiling(void)
void OOJSResetTimeLimiter(void)
BOOL OOJSIsProfiling(void)
void OOJSBeginProfiling(BOOL trace)
OOTimeDelta OOJSGetTimeLimiterLimit(void)
void OOJSSetTimeLimiterLimit(OOTimeDelta limit)
BOOL JSValueToEntity(JSContext *context, jsval value, Entity **outEntity)
void OOJSPauseTimeLimiter(void)
id OOJSNativeObjectFromJSValue(JSContext *context, jsval value)
void OOJSReportWarning(JSContext *context, NSString *format,...)
#define OOJS_PROP_READWRITE_CB
void OOJSRegisterObjectConverter(JSClass *theClass, OOJSClassConverterCallback converter)
OOINLINE jsval OOJSValueFromNativeObject(JSContext *context, id object)
id OOJSNativeObjectFromJSObject(JSContext *context, JSObject *object)
#define OOJS_RETURN_OBJECT(o)
void OOJSReportBadPropertySelector(JSContext *context, JSObject *thisObj, jsid propID, JSPropertySpec *propertySpec)
#define OOJS_RETURN_BOOL(v)
NSString * OOStringFromJSValue(JSContext *context, jsval value)
JSBool OOJSUnconstructableConstruct(JSContext *context, uintN argc, jsval *vp)
OOINLINE BOOL OOJSValueIsFunction(JSContext *context, jsval value)
NSString * OOJSDescribeValue(JSContext *context, jsval value, BOOL abbreviateObjects)
void OOJSReportError(JSContext *context, NSString *format,...)
OOINLINE jsval OOJSValueFromBOOL(int b) INLINE_CONST_FUNC
NSString * OOStringFromJSValueEvenIfNull(JSContext *context, jsval value)
id OOJSBasicPrivateObjectConverter(JSContext *context, JSObject *object)
void OOJSReportBadArguments(JSContext *context, NSString *scriptClass, NSString *function, uintN argc, jsval *argv, NSString *message, NSString *expectedArgsDescription)
#define OOJS_PROP_READONLY_CB
void OOJSResumeTimeLimiter(void)
#define OOJS_PROP_HIDDEN_READWRITE_CB
NSString * OOStringFromJSString(JSContext *context, JSString *string)
#define OOJS_METHOD_READONLY
id OOJSNativeObjectOfClassFromJSObject(JSContext *context, JSObject *object, Class requiredClass)
BOOL OOLogWillDisplayMessagesInClass(NSString *inMessageClass)
void OOLogSetDisplayMessagesInClass(NSString *inClass, BOOL inFlag)
void OOLogInsertMarker(void)
void dumpMemoryStatistics()
void setTCPIgnoresDroppedPackets:(BOOL flag)
size_t dumpJSMemoryStatistics()
OODebugMonitor * sharedDebugMonitor()
void setDumpStackForWarnings:(BOOL value)
void setShowErrorLocations:(BOOL value)
OOJavaScriptEngine * sharedEngine()
void setDumpStackForErrors:(BOOL value)
OOGraphicsDetail maximumDetailLevel()
OOOpenGLExtensionManager * sharedManager()
NSString * diagnosticFileLocation()