Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Gwenaël Samain
cython
Commits
9266b95e
Commit
9266b95e
authored
Jul 28, 2007
by
William Stein
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Merge in C/API patch from lxml-pyrex.
parent
76750ffb
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
153 additions
and
10 deletions
+153
-10
Cython/Compiler/ModuleNode.py
Cython/Compiler/ModuleNode.py
+107
-8
Cython/Compiler/Naming.py
Cython/Compiler/Naming.py
+1
-0
Cython/Compiler/Nodes.py
Cython/Compiler/Nodes.py
+45
-2
No files found.
Cython/Compiler/ModuleNode.py
View file @
9266b95e
...
@@ -39,24 +39,28 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -39,24 +39,28 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
self
.
generate_h_code
(
env
,
result
)
self
.
generate_h_code
(
env
,
result
)
def
generate_h_code
(
self
,
env
,
result
):
def
generate_h_code
(
self
,
env
,
result
):
public_vars_and_funcs
=
[]
public_vars
=
[]
public_funcs
=
[]
public_extension_types
=
[]
public_extension_types
=
[]
for
entry
in
env
.
var_entries
:
for
entry
in
env
.
var_entries
:
if
entry
.
visibility
==
'public'
:
if
entry
.
visibility
==
'public'
:
public_vars
_and_funcs
.
append
(
entry
)
public_vars
.
append
(
entry
)
for
entry
in
env
.
cfunc_entries
:
for
entry
in
env
.
cfunc_entries
:
if
entry
.
visibility
==
'public'
:
if
entry
.
visibility
==
'public'
:
public_
vars_and_
funcs
.
append
(
entry
)
public_funcs
.
append
(
entry
)
for
entry
in
env
.
c_class_entries
:
for
entry
in
env
.
c_class_entries
:
if
entry
.
visibility
==
'public'
:
if
entry
.
visibility
==
'public'
:
public_extension_types
.
append
(
entry
)
public_extension_types
.
append
(
entry
)
if
public_vars
_and
_funcs
or
public_extension_types
:
if
public_vars
or
public
_funcs
or
public_extension_types
:
result
.
h_file
=
replace_suffix
(
result
.
c_file
,
".h"
)
result
.
h_file
=
replace_suffix
(
result
.
c_file
,
".h"
)
result
.
i_file
=
replace_suffix
(
result
.
c_file
,
".pxi"
)
result
.
i_file
=
replace_suffix
(
result
.
c_file
,
".pxi"
)
h_code
=
Code
.
CCodeWriter
(
open_new_file
(
result
.
h_file
))
h_code
=
Code
.
CCodeWriter
(
open_new_file
(
result
.
h_file
))
i_code
=
Code
.
PyrexCodeWriter
(
result
.
i_file
)
i_code
=
Code
.
PyrexCodeWriter
(
result
.
i_file
)
header_barrier
=
"__HAS_PYX_"
+
env
.
module_name
h_code
.
putln
(
"#ifndef %s"
%
header_barrier
)
h_code
.
putln
(
"#define %s"
%
header_barrier
)
self
.
generate_extern_c_macro_definition
(
h_code
)
self
.
generate_extern_c_macro_definition
(
h_code
)
for
entry
in
public_vars
_and_funcs
:
for
entry
in
public_vars
:
h_code
.
putln
(
"%s %s;"
%
(
h_code
.
putln
(
"%s %s;"
%
(
Naming
.
extern_c_macro
,
Naming
.
extern_c_macro
,
entry
.
type
.
declaration_code
(
entry
.
type
.
declaration_code
(
...
@@ -66,7 +70,28 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -66,7 +70,28 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
for
entry
in
public_extension_types
:
for
entry
in
public_extension_types
:
self
.
generate_cclass_header_code
(
entry
.
type
,
h_code
)
self
.
generate_cclass_header_code
(
entry
.
type
,
h_code
)
self
.
generate_cclass_include_code
(
entry
.
type
,
i_code
)
self
.
generate_cclass_include_code
(
entry
.
type
,
i_code
)
if
public_funcs
:
sort_public_funcs
=
[
(
func
.
cname
,
func
)
for
func
in
public_funcs
]
sort_public_funcs
.
sort
()
public_funcs
=
[
func
[
1
]
for
func
in
sort_public_funcs
]
for
entry
in
public_funcs
:
h_code
.
putln
(
'static %s;'
%
entry
.
type
.
declaration_code
(
"(*%s)"
%
entry
.
cname
))
i_code
.
putln
(
"cdef extern %s"
%
entry
.
type
.
declaration_code
(
entry
.
cname
,
pyrex
=
1
))
h_code
.
putln
(
"static struct {char *s; void **p;} _%s_API[] = {"
%
env
.
module_name
)
for
entry
in
public_funcs
:
h_code
.
putln
(
'{"%s", (void*)(&%s)},'
%
(
entry
.
cname
,
entry
.
cname
))
h_code
.
putln
(
"{0, 0}"
)
h_code
.
putln
(
"};"
)
self
.
generate_c_api_import_code
(
env
,
h_code
)
h_code
.
putln
(
"PyMODINIT_FUNC init%s(void);"
%
env
.
module_name
)
h_code
.
putln
(
"PyMODINIT_FUNC init%s(void);"
%
env
.
module_name
)
h_code
.
putln
(
"#endif /* %s */"
%
header_barrier
)
def
generate_cclass_header_code
(
self
,
type
,
h_code
):
def
generate_cclass_header_code
(
self
,
type
,
h_code
):
#h_code.putln("extern DL_IMPORT(PyTypeObject) %s;" % type.typeobj_cname)
#h_code.putln("extern DL_IMPORT(PyTypeObject) %s;" % type.typeobj_cname)
...
@@ -106,6 +131,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -106,6 +131,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
self
.
body
.
generate_function_definitions
(
env
,
code
)
self
.
body
.
generate_function_definitions
(
env
,
code
)
self
.
generate_interned_name_table
(
env
,
code
)
self
.
generate_interned_name_table
(
env
,
code
)
self
.
generate_py_string_table
(
env
,
code
)
self
.
generate_py_string_table
(
env
,
code
)
self
.
generate_c_api_table
(
env
,
code
)
self
.
generate_typeobj_definitions
(
env
,
code
)
self
.
generate_typeobj_definitions
(
env
,
code
)
self
.
generate_method_table
(
env
,
code
)
self
.
generate_method_table
(
env
,
code
)
self
.
generate_filename_init_prototype
(
code
)
self
.
generate_filename_init_prototype
(
code
)
...
@@ -367,7 +393,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -367,7 +393,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
entry
.
type
.
typeptr_cname
)
entry
.
type
.
typeptr_cname
)
code
.
put_var_declarations
(
env
.
var_entries
,
static
=
1
,
code
.
put_var_declarations
(
env
.
var_entries
,
static
=
1
,
dll_linkage
=
"DL_EXPORT"
,
definition
=
definition
)
dll_linkage
=
"DL_EXPORT"
,
definition
=
definition
)
code
.
put_var_declarations
(
env
.
default_entries
,
static
=
1
)
code
.
put_var_declarations
(
env
.
default_entries
,
static
=
1
,
definition
=
definition
)
def
generate_cfunction_predeclarations
(
self
,
env
,
code
):
def
generate_cfunction_predeclarations
(
self
,
env
,
code
):
for
entry
in
env
.
cfunc_entries
:
for
entry
in
env
.
cfunc_entries
:
...
@@ -378,10 +405,12 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -378,10 +405,12 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
dll_linkage
=
None
dll_linkage
=
None
header
=
entry
.
type
.
declaration_code
(
entry
.
cname
,
header
=
entry
.
type
.
declaration_code
(
entry
.
cname
,
dll_linkage
=
dll_linkage
)
dll_linkage
=
dll_linkage
)
if
entry
.
visibility
<>
'private'
:
if
entry
.
visibility
==
'private'
:
storage_class
=
"static "
elif
entry
.
visibility
==
'extern'
:
storage_class
=
"%s "
%
Naming
.
extern_c_macro
storage_class
=
"%s "
%
Naming
.
extern_c_macro
else
:
else
:
storage_class
=
"
static
"
storage_class
=
""
code
.
putln
(
"%s%s; /*proto*/"
%
(
code
.
putln
(
"%s%s; /*proto*/"
%
(
storage_class
,
storage_class
,
header
))
header
))
...
@@ -1052,6 +1081,74 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -1052,6 +1081,74 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code
.
putln
(
code
.
putln
(
"};"
)
"};"
)
def
generate_c_api_table
(
self
,
env
,
code
):
public_funcs
=
[]
for
entry
in
env
.
cfunc_entries
:
if
entry
.
visibility
==
'public'
:
public_funcs
.
append
(
entry
.
cname
)
if
public_funcs
:
env
.
use_utility_code
(
Nodes
.
c_api_import_code
)
code
.
putln
(
"static __Pyx_CApiTabEntry %s[] = {"
%
Naming
.
c_api_tab_cname
)
public_funcs
.
sort
()
for
entry_cname
in
public_funcs
:
code
.
putln
(
'{"%s", %s},'
%
(
entry_cname
,
entry_cname
))
code
.
putln
(
"{0, 0}"
)
code
.
putln
(
"};"
)
def
generate_c_api_import_code
(
self
,
env
,
h_code
):
# this is written to the header file!
h_code
.
put
(
"""
/* Return -1 and set exception on error, 0 on success. */
static int
import_%(name)s(PyObject *module)
{
if (module != NULL)
{
int (*init)(struct {const char *s; const void **p;}*);
PyObject* c_api_init;
c_api_init = PyObject_GetAttrString(module,
"_import_c_api");
if (!c_api_init)
return -1;
if (!PyCObject_Check(c_api_init))
{
Py_DECREF(c_api_init);
PyErr_SetString(PyExc_RuntimeError,
"%(name)s module provided an invalid C-API reference");
return -1;
}
init = PyCObject_AsVoidPtr(c_api_init);
Py_DECREF(c_api_init);
if (!init)
{
PyErr_SetString(PyExc_RuntimeError,
"%(name)s module returned NULL pointer for C-API init function");
return -1;
}
if (init(_%(name)s_API))
return -1;
}
return 0;
}
"""
.
replace
(
'
\
n
'
,
'
\
n
'
)
%
{
'name'
:
env
.
module_name
})
def
generate_c_api_init_code
(
self
,
env
,
code
):
public_funcs
=
[]
for
entry
in
env
.
cfunc_entries
:
if
entry
.
visibility
==
'public'
:
public_funcs
.
append
(
entry
)
if
public_funcs
:
code
.
putln
(
'if (__Pyx_InitCApi(%s) < 0) %s'
%
(
Naming
.
module_cname
,
code
.
error_goto
(
self
.
pos
)))
def
generate_filename_init_prototype
(
self
,
code
):
def
generate_filename_init_prototype
(
self
,
code
):
code
.
putln
(
""
);
code
.
putln
(
""
);
code
.
putln
(
"static void %s(void); /*proto*/"
%
Naming
.
fileinit_cname
)
code
.
putln
(
"static void %s(void); /*proto*/"
%
Naming
.
fileinit_cname
)
...
@@ -1071,6 +1168,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
...
@@ -1071,6 +1168,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
self
.
generate_intern_code
(
env
,
code
)
self
.
generate_intern_code
(
env
,
code
)
#code.putln("/*--- String init code ---*/")
#code.putln("/*--- String init code ---*/")
self
.
generate_string_init_code
(
env
,
code
)
self
.
generate_string_init_code
(
env
,
code
)
#code.putln("/*--- External C API setup code ---*/")
self
.
generate_c_api_init_code
(
env
,
code
)
#code.putln("/*--- Builtin init code ---*/")
#code.putln("/*--- Builtin init code ---*/")
self
.
generate_builtin_init_code
(
env
,
code
)
self
.
generate_builtin_init_code
(
env
,
code
)
#code.putln("/*--- Global init code ---*/")
#code.putln("/*--- Global init code ---*/")
...
...
Cython/Compiler/Naming.py
View file @
9266b95e
...
@@ -52,5 +52,6 @@ retval_cname = pyrex_prefix + "r"
...
@@ -52,5 +52,6 @@ retval_cname = pyrex_prefix + "r"
self_cname
=
pyrex_prefix
+
"self"
self_cname
=
pyrex_prefix
+
"self"
stringtab_cname
=
pyrex_prefix
+
"string_tab"
stringtab_cname
=
pyrex_prefix
+
"string_tab"
vtabslot_cname
=
pyrex_prefix
+
"vtab"
vtabslot_cname
=
pyrex_prefix
+
"vtab"
c_api_tab_cname
=
pyrex_prefix
+
"c_api_tab"
extern_c_macro
=
pyrex_prefix
.
upper
()
+
"EXTERN_C"
extern_c_macro
=
pyrex_prefix
.
upper
()
+
"EXTERN_C"
Cython/Compiler/Nodes.py
View file @
9266b95e
...
@@ -709,10 +709,12 @@ class CFuncDefNode(FuncDefNode):
...
@@ -709,10 +709,12 @@ class CFuncDefNode(FuncDefNode):
dll_linkage
=
None
dll_linkage
=
None
header
=
self
.
return_type
.
declaration_code
(
entity
,
header
=
self
.
return_type
.
declaration_code
(
entity
,
dll_linkage
=
dll_linkage
)
dll_linkage
=
dll_linkage
)
if
self
.
visibility
<>
'private'
:
if
self
.
visibility
==
'private'
:
storage_class
=
"static "
elif
self
.
visibility
==
'extern'
:
storage_class
=
"%s "
%
Naming
.
extern_c_macro
storage_class
=
"%s "
%
Naming
.
extern_c_macro
else
:
else
:
storage_class
=
"
static
"
storage_class
=
""
code
.
putln
(
"%s%s%s {"
%
(
code
.
putln
(
"%s%s%s {"
%
(
storage_class
,
storage_class
,
self
.
modifiers
,
self
.
modifiers
,
...
@@ -1904,6 +1906,7 @@ class AssertStatNode(StatNode):
...
@@ -1904,6 +1906,7 @@ class AssertStatNode(StatNode):
#env.recycle_pending_temps() # TEMPORARY
#env.recycle_pending_temps() # TEMPORARY
def
generate_execution_code
(
self
,
code
):
def
generate_execution_code
(
self
,
code
):
code
.
putln
(
"#ifndef PYREX_WITHOUT_ASSERTIONS"
)
self
.
cond
.
generate_evaluation_code
(
code
)
self
.
cond
.
generate_evaluation_code
(
code
)
if
self
.
value
:
if
self
.
value
:
self
.
value
.
generate_evaluation_code
(
code
)
self
.
value
.
generate_evaluation_code
(
code
)
...
@@ -1924,6 +1927,7 @@ class AssertStatNode(StatNode):
...
@@ -1924,6 +1927,7 @@ class AssertStatNode(StatNode):
self
.
cond
.
generate_disposal_code
(
code
)
self
.
cond
.
generate_disposal_code
(
code
)
if
self
.
value
:
if
self
.
value
:
self
.
value
.
generate_disposal_code
(
code
)
self
.
value
.
generate_disposal_code
(
code
)
code
.
putln
(
"#endif"
)
class
IfStatNode
(
StatNode
):
class
IfStatNode
(
StatNode
):
...
@@ -2586,6 +2590,7 @@ class FromImportStatNode(StatNode):
...
@@ -2586,6 +2590,7 @@ class FromImportStatNode(StatNode):
utility_function_predeclarations
=
\
utility_function_predeclarations
=
\
"""
"""
typedef struct {const char *s; const void **p;} __Pyx_CApiTabEntry; /*proto*/
typedef struct {PyObject **p; char *s;} __Pyx_InternTabEntry; /*proto*/
typedef struct {PyObject **p; char *s;} __Pyx_InternTabEntry; /*proto*/
typedef struct {PyObject **p; char *s; long n;} __Pyx_StringTabEntry; /*proto*/
typedef struct {PyObject **p; char *s; long n;} __Pyx_StringTabEntry; /*proto*/
...
@@ -3096,3 +3101,41 @@ static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
...
@@ -3096,3 +3101,41 @@ static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
"""
]
"""
]
#------------------------------------------------------------------------------------
#------------------------------------------------------------------------------------
c_api_import_code
=
[
"""
static int __Pyx_InitCApi(PyObject *module); /*proto*/
static int __Pyx_ImportModuleCApi(__Pyx_CApiTabEntry *t); /*proto*/
"""
,
"""
static int __Pyx_ImportModuleCApi(__Pyx_CApiTabEntry *t) {
__Pyx_CApiTabEntry *api_t;
while (t->s) {
if (*t->s == '
\
\
0')
continue; /* shortcut for erased string entries */
api_t = %(API_TAB)s;
while ((api_t->s) && (strcmp(api_t->s, t->s) < 0))
++api_t;
if ((!api_t->p) || (strcmp(api_t->s, t->s) != 0)) {
PyErr_Format(PyExc_ValueError,
"Unknown function name in C API: %%s", t->s);
return -1;
}
*t->p = api_t->p;
++t;
}
return 0;
}
static int __Pyx_InitCApi(PyObject *module) {
int result;
PyObject* cobj = PyCObject_FromVoidPtr(&__Pyx_ImportModuleCApi, NULL);
if (!cobj)
return -1;
result = PyObject_SetAttrString(module, "_import_c_api", cobj);
Py_DECREF(cobj);
return result;
}
"""
%
{
'API_TAB'
:
Naming
.
c_api_tab_cname
}
]
#------------------------------------------------------------------------------------
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment