]> gitweb.factorcode.org Git - factor.git/blobdiff - vm/os-macosx.mm
io.streams.256color: faster by caching styles
[factor.git] / vm / os-macosx.mm
index 7f692def0664daf08a316a002206a6862e772329..71c70f7a489cf505f1a90c4e7c5a317c64a5e83e 100644 (file)
@@ -1,87 +1,94 @@
 #import <Cocoa/Cocoa.h>
 
+#include <mach/mach_time.h>
+#include <sys/utsname.h>
+#include <unistd.h>
+#include <stdio.h>
+
 #include "master.hpp"
 
-namespace factor
-{
-
-void factorvm::c_to_factor_toplevel(cell quot)
-{
-       for(;;)
-       {
-NS_DURING
-               c_to_factor(quot,vm);
-               NS_VOIDRETURN;
-NS_HANDLER
-               dpush(vm->allot_alien(F,(cell)localException));
-               quot = vm->userenv[COCOA_EXCEPTION_ENV];
-               if(!tagged<object>(quot).type_p(QUOTATION_TYPE))
-               {
-                       /* No Cocoa exception handler was registered, so
-                       extra/cocoa/ is not loaded. So we pass the exception
-                       along. */
-                       [localException raise];
-               }
-NS_ENDHANDLER
-       }
-}
+namespace factor {
 
-void early_init(void)
-{
-       SInt32 version;
-       Gestalt(gestaltSystemVersion,&version);
-       if(version <= 0x1050)
-       {
-               printf("Factor requires Mac OS X 10.5 or later.\n");
-               exit(1);
-       }
-
-       [[NSAutoreleasePool alloc] init];
+void factor_vm::c_to_factor_toplevel(cell quot) { c_to_factor(quot); }
+
+// Darwin 9 is 10.5, Darwin 10 is 10.6
+// http://en.wikipedia.org/wiki/Darwin_(operating_system)#Release_history
+void early_init(void) {
+  struct utsname u;
+  int n;
+  uname(&u);
+  sscanf(u.release, "%d", &n);
+  if (n < 9) {
+    std::cout << "Factor requires Mac OS X 10.5 or later.\n";
+    exit(1);
+  }
 }
 
-const char *vm_executable_path(void)
-{
-       return [[[NSBundle mainBundle] executablePath] UTF8String];
+// You must free() this yourself.
+const char* vm_executable_path(void) {
+  return safe_strdup([[[NSBundle mainBundle] executablePath] UTF8String]);
 }
 
-const char *default_image_path(void)
-{
-       NSBundle *bundle = [NSBundle mainBundle];
-       NSString *path = [bundle bundlePath];
-       NSString *executable = [[bundle executablePath] lastPathComponent];
-       NSString *image = [executable stringByAppendingString:@".image"];
+const char* default_image_path(void) {
+  NSBundle* bundle = [NSBundle mainBundle];
+  NSString* path = [bundle bundlePath];
+  NSString* executablePath = [[bundle executablePath] stringByResolvingSymlinksInPath];
+  NSString* executable = [executablePath lastPathComponent];
+  NSString* image = [executable stringByAppendingString:@".image"];
+
+  NSString* returnVal;
 
-       NSString *returnVal;
+  if ([path hasSuffix:@".app"] || [path hasSuffix:@".app/"]) {
+    NSFileManager* mgr = [NSFileManager defaultManager];
+    NSString* root = [path stringByDeletingLastPathComponent];
+    NSString* resources = [path stringByAppendingPathComponent:@"Contents/Resources"];
 
-       if([path hasSuffix:@".app"] || [path hasSuffix:@".app/"])
-       {
-               NSFileManager *mgr = [NSFileManager defaultManager];
+    NSString* imageInBundle = [resources stringByAppendingPathComponent:image];
+    NSString* imageAlongBundle = [root stringByAppendingPathComponent:image];
 
-               NSString *imageInBundle = [[path stringByAppendingPathComponent:@"Contents/Resources"] stringByAppendingPathComponent:image];
-               NSString *imageAlongBundle = [[path stringByDeletingLastPathComponent] stringByAppendingPathComponent:image];
+    returnVal = ([mgr fileExistsAtPath:imageInBundle] ? imageInBundle
+                                                      : imageAlongBundle);
+  } else if ([executablePath hasSuffix:@".app/Contents/MacOS/factor"]) {
+    returnVal = executablePath;
+    returnVal = [returnVal stringByDeletingLastPathComponent];
+    returnVal = [returnVal stringByDeletingLastPathComponent];
+    returnVal = [returnVal stringByDeletingLastPathComponent];
+    returnVal = [returnVal stringByDeletingLastPathComponent];
+    returnVal = [returnVal stringByAppendingPathComponent:image];
 
-               returnVal = ([mgr fileExistsAtPath:imageInBundle]
-                       ? imageInBundle : imageAlongBundle);
-       }
-       else
-               returnVal = [path stringByAppendingPathComponent:image];
+  } else {
+    returnVal = [path stringByAppendingPathComponent:image];
+  }
 
-       return [returnVal UTF8String];
+  return [returnVal UTF8String];
 }
 
-void init_signals(void)
-{
-       unix_init_signals();
-       mach_initialize();
+void factor_vm::init_signals(void) {
+  unix_init_signals();
+  mach_initialize();
 }
 
-/* Amateurs at Apple: implement this function, properly! */
-Protocol *objc_getProtocol(char *name)
-{
-       if(strcmp(name,"NSTextInput") == 0)
-               return @protocol(NSTextInput);
-       else
-               return nil;
+// Amateurs at Apple: implement this function, properly!
+Protocol* objc_getProtocol(char* name) {
+  if (strcmp(name, "NSTextInput") == 0)
+    return @protocol(NSTextInput);
+  else
+    return nil;
+}
+
+uint64_t nano_count() {
+  uint64_t time = mach_absolute_time();
+
+  static uint64_t scaling_factor = 0;
+  if (!scaling_factor) {
+    mach_timebase_info_data_t info;
+    kern_return_t ret = mach_timebase_info(&info);
+    if (ret != 0)
+      fatal_error("mach_timebase_info failed", ret);
+    scaling_factor = info.numer / info.denom;
+  }
+
+  return time * scaling_factor;
 }
 
 }