More work on Python extension, build libupb PIC.

pull/13171/head
Joshua Haberman 16 years ago
parent f00091f340
commit a223f9af30
  1. 148
      lang_ext/python/definition.c
  2. 4
      lang_ext/python/setup.py

@ -22,6 +22,7 @@
#include "definition.h" #include "definition.h"
#include "upb_context.h" #include "upb_context.h"
#include "upb_msg.h"
#if PY_MAJOR_VERSION > 3 #if PY_MAJOR_VERSION > 3
const char *bytes_format = "y#"; const char *bytes_format = "y#";
@ -32,17 +33,39 @@ const char *bytes_format = "s#";
/* upb.def.MessageDefinition **************************************************/ /* upb.def.MessageDefinition **************************************************/
#if 0 typedef struct {
PyObject_HEAD
struct upb_msgdef *def;
} PyUpb_MsgDef;
PyTypeObject PyUpb_MsgDefType; /* forward decl. */
/* Not implemented yet, but these methods will expose information about the /* Not implemented yet, but these methods will expose information about the
* message definition (the upb_msgdef). */ * message definition (the upb_msgdef). */
static PyMethodDef PyUpb_MessageDefinitionMethods[] = { static PyMethodDef msgdef_methods[] = {
{NULL, NULL}
}; };
PyTypeObject PyUpb_MessageDefinitionType = { static PyObject *msgdef_new(struct upb_msgdef *m)
{
PyUpb_MsgDef *md_obj = (void*)PyType_GenericAlloc(&PyUpb_MsgDefType, 0);
md_obj->def = m;
upb_msgdef_ref(md_obj->def);
return (void*)md_obj;
}
static void msgdef_dealloc(PyObject *obj)
{
PyUpb_MsgDef *md_obj = (void*)obj;
upb_msgdef_unref(md_obj->def);
obj->ob_type->tp_free(obj);
}
PyTypeObject PyUpb_MsgDefType = {
PyObject_HEAD_INIT(NULL) PyObject_HEAD_INIT(NULL)
0, /* ob_size */ 0, /* ob_size */
"upb.definition.MessageDefinition", /* tp_name */ "upb.definition.MessageDefinition", /* tp_name */
sizeof(PyUpb_MessageDefinition), /* tp_basicsize */ sizeof(PyUpb_MsgDef), /* tp_basicsize */
0, /* tp_itemsize */ 0, /* tp_itemsize */
msgdef_dealloc, /* tp_dealloc */ msgdef_dealloc, /* tp_dealloc */
0, /* tp_print */ 0, /* tp_print */
@ -80,13 +103,13 @@ PyTypeObject PyUpb_MessageDefinitionType = {
0, /* Can't be created in Python. */ /* tp_new */ 0, /* Can't be created in Python. */ /* tp_new */
0, /* tp_free */ 0, /* tp_free */
}; };
#endif
/* upb.Context ****************************************************************/ /* upb.Context ****************************************************************/
typedef struct { typedef struct {
PyObject_HEAD PyObject_HEAD
struct upb_context *context; struct upb_context *context;
PyObject *created_defs;
} PyUpb_Context; } PyUpb_Context;
static PyTypeObject PyUpb_ContextType; /* forward decl. */ static PyTypeObject PyUpb_ContextType; /* forward decl. */
@ -115,37 +138,70 @@ static PyObject *context_parsefds(PyObject *_context, PyObject *args)
Py_RETURN_NONE; Py_RETURN_NONE;
} }
//static PyObject *context_lookup(PyObject *self, PyObject *args) static PyObject *get_or_create_def(PyUpb_Context *context,
//{ struct upb_symtab_entry *e)
// PyUpb_Context *context = CheckContext(self); {
// struct upb_string str; /* Check out internal dictionary of Python classes we have already created
// if(!PyArg_ParseTuple(args, "s#", &str.ptr, &str.byte_len)) * (keyed by the address of the obj we are referencing). */
// return NULL; #if PY_MAJOR_VERSION > 3
// str.byte_size = 0; /* We don't own that mem. */ PyObject *str = PyBytes_FromStringAndSize((char*)&e->ref, sizeof(void*));
// #else
// struct upb_symtab_entry e; PyObject *str = PyString_FromStringAndSize((char*)&e->ref, sizeof(void*));
// if(upb_context_lookup(context->context, &str, &e)) { #endif
// return get_or_create_def(&e); /* Would use PyDict_GetItemStringAndSize() if it existed, but only
// } else { * PyDict_GetItemString() exists, and pointers could have NULL bytes. */
// Py_RETURN_NONE; PyObject *def = PyDict_GetItem(context->created_defs, str);
// } if(!def) {
//} switch(e->type) {
// case UPB_SYM_MESSAGE:
//static PyObject *context_resolve(PyObject *self, PyObject *args) def = msgdef_new(e->ref.msg);
//{ break;
// PyUpb_Context *context = CheckContext(self); case UPB_SYM_ENUM:
// struct upb_string str; case UPB_SYM_SERVICE:
// if(!PyArg_ParseTuple(args, "s#", &str.ptr, &str.byte_len)) case UPB_SYM_EXTENSION:
// return NULL; default:
// str.byte_size = 0; /* We don't own that mem. */ def = NULL;
// break;
// struct upb_symtab_entry e; }
// if(upb_context_resolve(context->context, &str, &e)) { if(def) PyDict_SetItem(context->created_defs, str, def);
// return get_or_create_def(&e); }
// } else { Py_DECREF(str);
// Py_RETURN_NONE; return def;
// } }
//}
static PyObject *context_lookup(PyObject *self, PyObject *args)
{
PyUpb_Context *context = CheckContext(self);
struct upb_string str;
if(!PyArg_ParseTuple(args, "s#", &str.ptr, &str.byte_len))
return NULL;
str.byte_size = 0; /* We don't own that mem. */
struct upb_symtab_entry e;
if(upb_context_lookup(context->context, &str, &e)) {
return get_or_create_def(context, &e);
} else {
Py_RETURN_NONE;
}
}
static PyObject *context_resolve(PyObject *self, PyObject *args)
{
PyUpb_Context *context = CheckContext(self);
struct upb_string str;
struct upb_string base;
if(!PyArg_ParseTuple(args, "s#s#", &base.ptr, &base.byte_len,
&str.ptr, &str.byte_len))
return NULL;
str.byte_size = 0; /* We don't own that mem. */
struct upb_symtab_entry e;
if(upb_context_resolve(context->context, &base, &str, &e)) {
return get_or_create_def(context, &e);
} else {
Py_RETURN_NONE;
}
}
static void add_string(void *udata, struct upb_symtab_entry *entry) static void add_string(void *udata, struct upb_symtab_entry *entry)
{ {
@ -154,6 +210,7 @@ static void add_string(void *udata, struct upb_symtab_entry *entry)
/* TODO: check return. */ /* TODO: check return. */
PyObject *str = PyString_FromStringAndSize(s->ptr, s->byte_len); PyObject *str = PyString_FromStringAndSize(s->ptr, s->byte_len);
PyList_Append(list, str); PyList_Append(list, str);
Py_DECREF(str);
} }
static PyObject *context_symbols(PyObject *self, PyObject *args) static PyObject *context_symbols(PyObject *self, PyObject *args)
@ -169,13 +226,13 @@ static PyMethodDef context_methods[] = {
"Parses a string containing a serialized FileDescriptorSet and adds its " "Parses a string containing a serialized FileDescriptorSet and adds its "
"definitions to the context." "definitions to the context."
}, },
//{"lookup", context_lookup, METH_VARARGS, {"lookup", context_lookup, METH_VARARGS,
// "Finds a symbol by fully-qualified name (eg. foo.bar.MyType)." "Finds a symbol by fully-qualified name (eg. foo.bar.MyType)."
//}, },
//{"resolve", context_resolve, METH_VARARGS, {"resolve", context_resolve, METH_VARARGS,
// "Finds a symbol by a possibly-relative name, which will be interpreted " "Finds a symbol by a possibly-relative name, which will be interpreted "
// "in the context of the given base." "in the context of the given base."
//} },
{"symbols", context_symbols, METH_NOARGS, {"symbols", context_symbols, METH_NOARGS,
"Returns a list of symbol names that are defined in this context." "Returns a list of symbol names that are defined in this context."
}, },
@ -187,6 +244,7 @@ static PyObject *context_new(PyTypeObject *subtype,
{ {
PyUpb_Context *obj = (void*)subtype->tp_alloc(subtype, 0); PyUpb_Context *obj = (void*)subtype->tp_alloc(subtype, 0);
obj->context = upb_context_new(); obj->context = upb_context_new();
obj->created_defs = PyDict_New();
return (void*)obj; return (void*)obj;
} }
@ -194,6 +252,8 @@ static void context_dealloc(PyObject *obj)
{ {
PyUpb_Context *c = (void*)obj; PyUpb_Context *c = (void*)obj;
upb_context_unref(c->context); upb_context_unref(c->context);
Py_DECREF(c->created_defs);
obj->ob_type->tp_free(obj);
} }
static PyTypeObject PyUpb_ContextType = { static PyTypeObject PyUpb_ContextType = {
@ -247,6 +307,8 @@ initdefinition(void)
{ {
if(PyType_Ready(&PyUpb_ContextType) < 0) return; if(PyType_Ready(&PyUpb_ContextType) < 0) return;
Py_INCREF(&PyUpb_ContextType); /* TODO: necessary? */ Py_INCREF(&PyUpb_ContextType); /* TODO: necessary? */
if(PyType_Ready(&PyUpb_MsgDefType) < 0) return;
Py_INCREF(&PyUpb_MsgDefType); /* TODO: necessary? */
PyObject *mod = Py_InitModule("upb.definition", methods); PyObject *mod = Py_InitModule("upb.definition", methods);
PyModule_AddObject(mod, "Context", (PyObject*)&PyUpb_ContextType); PyModule_AddObject(mod, "Context", (PyObject*)&PyUpb_ContextType);

@ -2,10 +2,10 @@ from distutils.core import setup, Extension
setup(name='upb', setup(name='upb',
version='0.1', version='0.1',
ext_modules=[Extension('upb.definition', ['definition.c'], ext_modules=[Extension('upb.definition', ['definition.c'],
include_dirs=['../../src'], include_dirs=['../../src', '../../descriptor'],
define_macros=[("UPB_USE_PTHREADS", 1), define_macros=[("UPB_USE_PTHREADS", 1),
("UPB_UNALIGNED_READS_OK", 1)], ("UPB_UNALIGNED_READS_OK", 1)],
library_dirs=['../../src'], library_dirs=['../../src'],
libraries=['upb'] libraries=['upb_pic']
)], )],
) )

Loading…
Cancel
Save