Skip to content

Instantly share code, notes, and snippets.

@bluemoon
Created May 10, 2012 10:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bluemoon/2652360 to your computer and use it in GitHub Desktop.
Save bluemoon/2652360 to your computer and use it in GitHub Desktop.
RPython + ObjC runtime
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