Created
May 10, 2012 10:39
-
-
Save bluemoon/2652360 to your computer and use it in GitHub Desktop.
RPython + ObjC runtime
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import sys, pdb, traceback | |
import os | |
import autopath | |
from pypy.rpython.lltypesystem import lltype, rffi | |
from pypy.rlib.rmmap import alloc, free | |
from pypy.translator.tool.cbuild import ExternalCompilationInfo | |
from pypy.translator.c.test.test_genc import compile as compile_c | |
from pypy.rpython.lltypesystem.rffi import * | |
from pypy.rpython.lltypesystem.llmemory import * | |
objc_runtime = ExternalCompilationInfo(includes=[ | |
'objc/objc.h', | |
'objc/runtime.h', | |
'objc/message.h'], | |
libraries=['objc']) | |
objc_ivar_list = COpaquePtr('struct objc_ivar_list', compilation_info=objc_runtime) | |
Class = COpaquePtr(typedef='Class', compilation_info=objc_runtime) | |
Method = COpaquePtr(typedef='Method', compilation_info=objc_runtime) | |
Ivar = COpaquePtr(typedef='Ivar', compilation_info=objc_runtime) | |
Category = COpaquePtr(typedef='Category', compilation_info=objc_runtime) | |
SEL = COpaquePtr(typedef='SEL', compilation_info=objc_runtime) | |
ID = COpaquePtr(typedef='id', compilation_info=objc_runtime) | |
CLASS_A = lltype.Array(Class, hints={'nolength': True}) | |
class_addIvar = rffi.llexternal( | |
'class_addIvar', [Class, CCHARP, SIZE_T, UINT, CCHARP], UINT, | |
compilation_info=objc_runtime | |
) | |
class_getIvarLayout = rffi.llexternal( | |
'class_getIvarLayout', [VOIDP], CCHARP, | |
compilation_info=objc_runtime | |
) | |
class_getName = rffi.llexternal( | |
'class_getName', | |
[VOIDP], | |
CCHARP, | |
compilation_info=objc_runtime | |
) | |
class_getSuperclass = rffi.llexternal( | |
'class_getSuperclass', | |
[Class], | |
CCHARP, | |
compilation_info=objc_runtime | |
) | |
class_createInstance = rffi.llexternal( | |
'class_createInstance', | |
[VOIDP, SIZE_T], | |
ID, | |
compilation_info=objc_runtime | |
) | |
objc_msgSend = rffi.llexternal( | |
'objc_msgSend', | |
[ID, SEL], | |
ID, | |
compilation_info=objc_runtime | |
) | |
objc_lookUpClass = rffi.llexternal( | |
'objc_lookUpClass', | |
[CCHARP], | |
Class, | |
compilation_info=objc_runtime | |
) | |
objc_getClassList = rffi.llexternal( | |
'objc_getClassList', | |
[VOIDP, INT], | |
INT, | |
compilation_info=objc_runtime | |
) | |
objc_allocateClassPair = rffi.llexternal( | |
'objc_allocateClassPair', | |
[VOIDP, CCHARP, SIZE_T], | |
Class, | |
compilation_info=objc_runtime | |
) | |
objc_registerClassPair = rffi.llexternal( | |
'objc_registerClassPair', | |
[VOIDP], | |
lltype.Void, | |
compilation_info=objc_runtime | |
) | |
class Objc_Class(object): | |
def __init__(self, ptr): | |
self.ptr = ptr | |
def __repr__(self): | |
return charp2str(class_getName(self.ptr)) | |
def name(self): | |
return charp2str(class_getName(self.ptr)) | |
def instance(self): | |
return class_createInstance(self.ptr) | |
class ObjC(object): | |
def compile(self, func, args, **kwds): | |
compile_c(func, args, **kwds) | |
def class_count(self): | |
class_count = objc_getClassList(None, 0) | |
return class_count | |
def get_class_lists(self): | |
count = self.class_count() | |
c_lists = [] | |
if count > 0: | |
#c_array = lltype.Ptr(CLASS) | |
class_alloc = lltype.malloc(CLASS_A, count, flavor='raw') | |
#classes = cast(lltype.Ptr(lltype.Void()), class_alloc) | |
objc_getClassList(class_alloc, count) | |
for i in xrange(count): | |
c = Objc_Class(class_alloc[i]) | |
d = c.name() | |
c_lists.append(d) | |
return c_lists | |
def msgSend(self, receiver, selector, **kwds): | |
pass | |
def get_class(self, class_name): | |
adr = objc_lookUpClass(str2charp(class_name)) | |
return adr | |
def allocate_class_pair(self, name, superclass=None): | |
_class = objc_allocateClassPair(superclass, str2charp(name), 0) | |
objc_registerClassPair(_class) | |
return _class | |
def instance(self, ClassPtr): | |
return class_createInstance(ClassPtr, 0) | |
def detect_sse2(): | |
data = alloc(4096) | |
pos = 0 | |
for c in ("\xB8\x01\x00\x00\x00" # MOV EAX, 1 | |
"\x53" # PUSH EBX | |
"\x0F\xA2" # CPUID | |
"\x5B" # POP EBX | |
"\x92" # XCHG EAX, EDX | |
"\xC3"): # RET | |
data[pos] = c | |
pos += 1 | |
fnptr = rffi.cast(lltype.Ptr(lltype.FuncType([], lltype.Signed)), data) | |
code = fnptr() | |
free(data, 4096) | |
return bool(code & (1<<25)) and bool(code & (1<<26)) | |
def entry_point(argv): | |
#ype = lltype.typeOf(objc_getClassList) | |
print objc_getClassList(None, 0) | |
o = ObjC() | |
o.class_count() | |
print o.get_class_lists() | |
c = o.allocate_class_pair('NSFuckYou') | |
o.get_class('NSFuckYou') | |
print o.instance(c) | |
print o.get_class_lists() | |
#print objc_getClassList(None, 0) | |
return 0 | |
def target(*args): | |
return entry_point, None | |
if __name__ == "__main__": | |
try: | |
entry_point(sys.argv) | |
except KeyboardInterrupt: | |
raise | |
except: | |
e, v, tb = sys.exc_info() | |
traceback.print_tb(tb) | |
print e, v | |
pdb.post_mortem(tb) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment