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
Labels
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
nexedi
cython
Commits
218d5959
Commit
218d5959
authored
Aug 01, 2008
by
Dag Sverre Seljebotn
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Introduced code.globalstate and renamed code.func to code.funcstate
global is a reserved word...
parent
d28ddc7e
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
99 additions
and
89 deletions
+99
-89
Cython/Compiler/Buffer.py
Cython/Compiler/Buffer.py
+6
-6
Cython/Compiler/Code.py
Cython/Compiler/Code.py
+78
-68
Cython/Compiler/ExprNodes.py
Cython/Compiler/ExprNodes.py
+3
-3
Cython/Compiler/ModuleNode.py
Cython/Compiler/ModuleNode.py
+3
-3
Cython/Compiler/Nodes.py
Cython/Compiler/Nodes.py
+9
-9
No files found.
Cython/Compiler/Buffer.py
View file @
218d5959
...
...
@@ -209,7 +209,7 @@ def put_assign_to_buffer(lhs_cname, rhs_cname, buffer_aux, buffer_type,
lhs_cname
,
bufstruct
))
code
.
end_block
()
# Acquire
retcode_cname
=
code
.
func
.
allocate_temp
(
PyrexTypes
.
c_int_type
)
retcode_cname
=
code
.
func
state
.
allocate_temp
(
PyrexTypes
.
c_int_type
)
code
.
putln
(
"%s = %s;"
%
(
retcode_cname
,
getbuffer
%
rhs_cname
))
code
.
putln
(
'if (%s) '
%
(
code
.
unlikely
(
"%s < 0"
%
retcode_cname
)))
# If acquisition failed, attempt to reacquire the old buffer
...
...
@@ -217,7 +217,7 @@ def put_assign_to_buffer(lhs_cname, rhs_cname, buffer_aux, buffer_type,
# will cause the reacquisition exception to be reported, one
# can consider working around this later.
code
.
begin_block
()
type
,
value
,
tb
=
[
code
.
func
.
allocate_temp
(
PyrexTypes
.
py_object_type
)
type
,
value
,
tb
=
[
code
.
func
state
.
allocate_temp
(
PyrexTypes
.
py_object_type
)
for
i
in
range
(
3
)]
code
.
putln
(
'PyErr_Fetch(&%s, &%s, &%s);'
%
(
type
,
value
,
tb
))
code
.
put
(
'if (%s) '
%
code
.
unlikely
(
"%s == -1"
%
(
getbuffer
%
lhs_cname
)))
...
...
@@ -227,13 +227,13 @@ def put_assign_to_buffer(lhs_cname, rhs_cname, buffer_aux, buffer_type,
code
.
putln
(
'} else {'
)
code
.
putln
(
'PyErr_Restore(%s, %s, %s);'
%
(
type
,
value
,
tb
))
for
t
in
(
type
,
value
,
tb
):
code
.
func
.
release_temp
(
t
)
code
.
func
state
.
release_temp
(
t
)
code
.
end_block
()
# Unpack indices
code
.
end_block
()
put_unpack_buffer_aux_into_scope
(
buffer_aux
,
buffer_type
.
mode
,
code
)
code
.
putln
(
code
.
error_goto_if_neg
(
retcode_cname
,
pos
))
code
.
func
.
release_temp
(
retcode_cname
)
code
.
func
state
.
release_temp
(
retcode_cname
)
else
:
# Our entry had no previous value, so set to None when acquisition fails.
# In this case, auxiliary vars should be set up right in initialization to a zero-buffer,
...
...
@@ -261,7 +261,7 @@ def put_access(entry, index_signeds, index_cnames, pos, code):
# Check bounds and fix negative indices
boundscheck
=
True
nonegs
=
True
tmp_cname
=
code
.
func
.
allocate_temp
(
PyrexTypes
.
c_int_type
)
tmp_cname
=
code
.
func
state
.
allocate_temp
(
PyrexTypes
.
c_int_type
)
if
boundscheck
:
code
.
putln
(
"%s = -1;"
%
tmp_cname
)
for
idx
,
(
signed
,
cname
,
shape
)
in
enumerate
(
zip
(
index_signeds
,
index_cnames
,
...
...
@@ -288,7 +288,7 @@ def put_access(entry, index_signeds, index_cnames, pos, code):
code
.
putln
(
'__Pyx_BufferIndexError(%s);'
%
tmp_cname
)
code
.
putln
(
code
.
error_goto
(
pos
))
code
.
end_block
()
code
.
func
.
release_temp
(
tmp_cname
)
code
.
func
state
.
release_temp
(
tmp_cname
)
# Create buffer lookup and return it
params
=
[]
...
...
Cython/Compiler/Code.py
View file @
218d5959
...
...
@@ -12,7 +12,16 @@ from Scanning import SourceDescriptor
from
Cython.StringIOTree
import
StringIOTree
from
sets
import
Set
as
set
class
FunctionContext
(
object
):
class
FunctionState
(
object
):
# return_label string function return point label
# error_label string error catch point label
# continue_label string loop continue point label
# break_label string loop break point label
# return_from_error_cleanup_label string
# label_counter integer counter for naming labels
# in_try_finally boolean inside try of try...finally
# exc_vars (string * 3) exception variables for reraise, or None
# Not used for now, perhaps later
def
__init__
(
self
,
names_taken
=
set
()):
self
.
names_taken
=
names_taken
...
...
@@ -25,6 +34,9 @@ class FunctionContext(object):
self
.
continue_label
=
None
self
.
break_label
=
None
self
.
in_try_finally
=
0
self
.
exc_vars
=
None
self
.
temps_allocated
=
[]
# of (name, type)
self
.
temps_free
=
{}
# type -> list of free vars
self
.
temps_used_type
=
{}
# name -> type
...
...
@@ -118,11 +130,44 @@ class FunctionContext(object):
self
.
temps_free
[
type
]
=
freelist
freelist
.
append
(
name
)
class
GlobalState
(
object
):
# filename_table {string : int} for finding filename table indexes
# filename_list [string] filenames in filename table order
# input_file_contents dict contents (=list of lines) of any file that was used as input
# to create this output C code. This is
# used to annotate the comments.
def
__init__
(
self
):
self
.
filename_table
=
{}
self
.
filename_list
=
[]
self
.
input_file_contents
=
{}
def
lookup_filename
(
self
,
filename
):
try
:
index
=
self
.
filename_table
[
filename
]
except
KeyError
:
index
=
len
(
self
.
filename_list
)
self
.
filename_list
.
append
(
filename
)
self
.
filename_table
[
filename
]
=
index
return
index
def
commented_file_contents
(
self
,
source_desc
):
try
:
return
self
.
input_file_contents
[
source_desc
]
except
KeyError
:
F
=
[
u' * '
+
line
.
rstrip
().
replace
(
u'*/'
,
u'*[inserted by cython to avoid comment closer]/'
).
encode
(
'ASCII'
,
'replace'
)
# + Py2 auto-decode to unicode
for
line
in
source_desc
.
get_lines
()]
self
.
input_file_contents
[
source_desc
]
=
F
return
F
def
funccontext_property
(
name
):
def
get
(
self
):
return
getattr
(
self
.
func
,
name
)
return
getattr
(
self
.
func
state
,
name
)
def
set
(
self
,
value
):
setattr
(
self
.
func
,
name
,
value
)
setattr
(
self
.
func
state
,
name
,
value
)
return
property
(
get
,
set
)
class
CCodeWriter
(
object
):
...
...
@@ -148,47 +193,29 @@ class CCodeWriter(object):
# level int indentation level
# bol bool beginning of line?
# marker string comment to emit before next line
# return_label string function return point label
# error_label string error catch point label
# continue_label string loop continue point label
# break_label string loop break point label
# return_from_error_cleanup_label string
# label_counter integer counter for naming labels
# in_try_finally boolean inside try of try...finally
# filename_table {string : int} for finding filename table indexes
# filename_list [string] filenames in filename table order
# exc_vars (string * 3) exception variables for reraise, or None
# input_file_contents dict contents (=list of lines) of any file that was used as input
# to create this output C code. This is
# used to annotate the comments.
# func FunctionContext contains labels and temps context info
# funcstate FunctionState contains state local to a C function used for code
# generation (labels and temps state etc.)
# globalstate GlobalState contains state global for a C file (input file info,
# utility code, declared constants etc.)
in_try_finally
=
0
def
__init__
(
self
,
create_from
=
None
,
buffer
=
None
):
if
buffer
is
None
:
buffer
=
StringIOTree
()
self
.
buffer
=
buffer
self
.
marker
=
None
self
.
last_marker_line
=
0
self
.
func
=
None
self
.
funcstate
=
None
# always start with no function state
if
create_from
is
None
:
# Root CCodeWriter
self
.
level
=
0
self
.
bol
=
1
self
.
filename_table
=
{}
self
.
filename_list
=
[]
self
.
exc_vars
=
None
self
.
input_file_contents
=
{}
self
.
globalstate
=
GlobalState
()
else
:
# Use same global state
self
.
globalstate
=
create_from
.
globalstate
# Clone formatting state
c
=
create_from
self
.
level
=
c
.
level
self
.
bol
=
c
.
bol
# Note: NOT copying but sharing instance
self
.
filename_table
=
c
.
filename_table
self
.
filename_list
=
[]
self
.
input_file_contents
=
c
.
input_file_contents
# Leave other state alone
self
.
level
=
create_from
.
level
self
.
bol
=
create_from
.
bol
def
create_new
(
self
,
create_from
,
buffer
):
# polymorphic constructor -- very slightly more versatile
...
...
@@ -216,26 +243,26 @@ class CCodeWriter(object):
labels_used
=
funccontext_property
(
"labels_used"
)
continue_label
=
funccontext_property
(
"continue_label"
)
break_label
=
funccontext_property
(
"break_label"
)
return_from_error_cleanup_label
=
funccontext_property
(
"return_from_error_cleanup_label"
)
# Functions delegated to function scope
def
new_label
(
self
):
return
self
.
func
.
new_label
()
def
new_error_label
(
self
):
return
self
.
func
.
new_error_label
()
def
get_loop_labels
(
self
):
return
self
.
func
.
get_loop_labels
()
def
set_loop_labels
(
self
,
labels
):
return
self
.
func
.
set_loop_labels
(
labels
)
def
new_loop_labels
(
self
):
return
self
.
func
.
new_loop_labels
()
def
get_all_labels
(
self
):
return
self
.
func
.
get_all_labels
()
def
set_all_labels
(
self
,
labels
):
return
self
.
func
.
set_all_labels
(
labels
)
def
all_new_labels
(
self
):
return
self
.
func
.
all_new_labels
()
def
use_label
(
self
,
lbl
):
return
self
.
func
.
use_label
(
lbl
)
def
label_used
(
self
,
lbl
):
return
self
.
func
.
label_used
(
lbl
)
def
new_label
(
self
):
return
self
.
func
state
.
new_label
()
def
new_error_label
(
self
):
return
self
.
func
state
.
new_error_label
()
def
get_loop_labels
(
self
):
return
self
.
func
state
.
get_loop_labels
()
def
set_loop_labels
(
self
,
labels
):
return
self
.
func
state
.
set_loop_labels
(
labels
)
def
new_loop_labels
(
self
):
return
self
.
func
state
.
new_loop_labels
()
def
get_all_labels
(
self
):
return
self
.
func
state
.
get_all_labels
()
def
set_all_labels
(
self
,
labels
):
return
self
.
func
state
.
set_all_labels
(
labels
)
def
all_new_labels
(
self
):
return
self
.
func
state
.
all_new_labels
()
def
use_label
(
self
,
lbl
):
return
self
.
func
state
.
use_label
(
lbl
)
def
label_used
(
self
,
lbl
):
return
self
.
func
state
.
label_used
(
lbl
)
def
enter_cfunc_scope
(
self
):
self
.
func
=
FunctionContext
()
self
.
func
state
=
FunctionState
()
def
exit_cfunc_scope
(
self
):
self
.
func
=
None
self
.
func
state
=
None
def
putln
(
self
,
code
=
""
):
if
self
.
marker
and
self
.
bol
:
...
...
@@ -287,17 +314,6 @@ class CCodeWriter(object):
def
get_py_version_hex
(
self
,
pyversion
):
return
"0x%02X%02X%02X%02X"
%
(
tuple
(
pyversion
)
+
(
0
,
0
,
0
,
0
))[:
4
]
def
commented_file_contents
(
self
,
source_desc
):
try
:
return
self
.
input_file_contents
[
source_desc
]
except
KeyError
:
F
=
[
u' * '
+
line
.
rstrip
().
replace
(
u'*/'
,
u'*[inserted by cython to avoid comment closer]/'
).
encode
(
'ASCII'
,
'replace'
)
# + Py2 auto-decode to unicode
for
line
in
source_desc
.
get_lines
()]
self
.
input_file_contents
[
source_desc
]
=
F
return
F
def
mark_pos
(
self
,
pos
):
if
pos
is
None
:
return
...
...
@@ -305,7 +321,7 @@ class CCodeWriter(object):
if
self
.
last_marker_line
==
line
:
return
assert
isinstance
(
source_desc
,
SourceDescriptor
)
contents
=
self
.
commented_file_contents
(
source_desc
)
contents
=
self
.
globalstate
.
commented_file_contents
(
source_desc
)
lines
=
contents
[
max
(
0
,
line
-
3
):
line
]
# line numbers start at 1
lines
[
-
1
]
+=
u' # <<<<<<<<<<<<<<'
...
...
@@ -317,11 +333,11 @@ class CCodeWriter(object):
def
put_label
(
self
,
lbl
):
if
lbl
in
self
.
func
.
labels_used
:
if
lbl
in
self
.
func
state
.
labels_used
:
self
.
putln
(
"%s:;"
%
lbl
)
def
put_goto
(
self
,
lbl
):
self
.
func
.
use_label
(
lbl
)
self
.
func
state
.
use_label
(
lbl
)
self
.
putln
(
"goto %s;"
%
lbl
)
def
put_var_declarations
(
self
,
entries
,
static
=
0
,
dll_linkage
=
None
,
...
...
@@ -481,8 +497,8 @@ class CCodeWriter(object):
return
cond
def
error_goto
(
self
,
pos
):
lbl
=
self
.
func
.
error_label
self
.
func
.
use_label
(
lbl
)
lbl
=
self
.
func
state
.
error_label
self
.
func
state
.
use_label
(
lbl
)
if
Options
.
c_line_in_traceback
:
cinfo
=
" %s = %s;"
%
(
Naming
.
clineno_cname
,
Naming
.
line_c_macro
)
else
:
...
...
@@ -509,13 +525,7 @@ class CCodeWriter(object):
return
self
.
error_goto_if
(
"PyErr_Occurred()"
,
pos
)
def
lookup_filename
(
self
,
filename
):
try
:
index
=
self
.
filename_table
[
filename
]
except
KeyError
:
index
=
len
(
self
.
filename_list
)
self
.
filename_list
.
append
(
filename
)
self
.
filename_table
[
filename
]
=
index
return
index
return
self
.
globalstate
.
lookup_filename
(
filename
)
class
PyrexCodeWriter
:
...
...
Cython/Compiler/ExprNodes.py
View file @
218d5959
...
...
@@ -1065,7 +1065,7 @@ class NameNode(AtomicExprNode):
rhs
.
generate_post_assignment_code
(
code
)
def
generate_acquire_buffer
(
self
,
rhs
,
code
):
rhstmp
=
code
.
func
.
allocate_temp
(
self
.
entry
.
type
)
rhstmp
=
code
.
func
state
.
allocate_temp
(
self
.
entry
.
type
)
buffer_aux
=
self
.
entry
.
buffer_aux
bufstruct
=
buffer_aux
.
buffer_info_var
.
cname
code
.
putln
(
'%s = %s;'
%
(
rhstmp
,
rhs
.
result_as
(
self
.
ctype
())))
...
...
@@ -1075,7 +1075,7 @@ class NameNode(AtomicExprNode):
is_initialized
=
not
self
.
skip_assignment_decref
,
pos
=
self
.
pos
,
code
=
code
)
code
.
putln
(
"%s = 0;"
%
rhstmp
)
code
.
func
.
release_temp
(
rhstmp
)
code
.
func
state
.
release_temp
(
rhstmp
)
def
generate_deletion_code
(
self
,
code
):
if
self
.
entry
is
None
:
...
...
@@ -1520,7 +1520,7 @@ class IndexNode(ExprNode):
def
buffer_access_code
(
self
,
code
):
# Assign indices to temps
index_temps
=
[
code
.
func
.
allocate_temp
(
i
.
type
)
for
i
in
self
.
indices
]
index_temps
=
[
code
.
func
state
.
allocate_temp
(
i
.
type
)
for
i
in
self
.
indices
]
for
temp
,
index
in
zip
(
index_temps
,
self
.
indices
):
code
.
putln
(
"%s = %s;"
%
(
temp
,
index
.
result_code
))
# Generate buffer access code using these temps
...
...
Cython/Compiler/ModuleNode.py
View file @
218d5959
...
...
@@ -529,8 +529,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
def
generate_filename_table
(
self
,
code
):
code
.
putln
(
""
)
code
.
putln
(
"static const char *%s[] = {"
%
Naming
.
filenames_cname
)
if
code
.
filename_list
:
for
source_desc
in
code
.
filename_list
:
if
code
.
globalstate
.
filename_list
:
for
source_desc
in
code
.
globalstate
.
filename_list
:
filename
=
os
.
path
.
basename
(
source_desc
.
get_filenametable_entry
())
escaped_filename
=
filename
.
replace
(
"
\
\
"
,
"
\
\
\
\
"
).
replace
(
'"'
,
r'\"'
)
code
.
putln
(
'"%s",'
%
...
...
@@ -1610,7 +1610,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code
.
putln
(
'}'
)
tempdecl_code
.
put_var_declarations
(
env
.
temp_entries
)
tempdecl_code
.
put_temp_declarations
(
code
.
func
)
tempdecl_code
.
put_temp_declarations
(
code
.
func
state
)
code
.
exit_cfunc_scope
()
...
...
Cython/Compiler/Nodes.py
View file @
218d5959
...
...
@@ -969,7 +969,7 @@ class FuncDefNode(StatNode, BlockNode):
code
.
putln
(
"}"
)
# ----- Go back and insert temp variable declarations
tempvardecl_code
.
put_var_declarations
(
lenv
.
temp_entries
)
tempvardecl_code
.
put_temp_declarations
(
code
.
func
)
tempvardecl_code
.
put_temp_declarations
(
code
.
func
state
)
# ----- Python version
code
.
exit_cfunc_scope
()
if
self
.
py_func
:
...
...
@@ -2634,7 +2634,7 @@ class ContinueStatNode(StatNode):
pass
def
generate_execution_code
(
self
,
code
):
if
code
.
in_try_finally
:
if
code
.
funcstate
.
in_try_finally
:
error
(
self
.
pos
,
"continue statement inside try of try...finally"
)
elif
not
code
.
continue_label
:
error
(
self
.
pos
,
"continue statement not inside loop"
)
...
...
@@ -2797,7 +2797,7 @@ class ReraiseStatNode(StatNode):
gil_message
=
"Raising exception"
def
generate_execution_code
(
self
,
code
):
vars
=
code
.
exc_vars
vars
=
code
.
funcstate
.
exc_vars
if
vars
:
code
.
putln
(
"__Pyx_Raise(%s, %s, %s);"
%
tuple
(
vars
))
code
.
putln
(
code
.
error_goto
(
self
.
pos
))
...
...
@@ -3478,10 +3478,10 @@ class ExceptClauseNode(Node):
self
.
excinfo_tuple
.
generate_evaluation_code
(
code
)
self
.
excinfo_target
.
generate_assignment_code
(
self
.
excinfo_tuple
,
code
)
old_exc_vars
=
code
.
exc_vars
code
.
exc_vars
=
self
.
exc_vars
old_exc_vars
=
code
.
funcstate
.
exc_vars
code
.
funcstate
.
exc_vars
=
self
.
exc_vars
self
.
body
.
generate_execution_code
(
code
)
code
.
exc_vars
=
old_exc_vars
code
.
funcstate
.
exc_vars
=
old_exc_vars
for
var
in
self
.
exc_vars
:
code
.
putln
(
"Py_DECREF(%s); %s = 0;"
%
(
var
,
var
))
code
.
put_goto
(
end_label
)
...
...
@@ -3556,11 +3556,11 @@ class TryFinallyStatNode(StatNode):
code
.
putln
(
"/*try:*/ {"
)
if
self
.
disallow_continue_in_try_finally
:
was_in_try_finally
=
code
.
in_try_finally
code
.
in_try_finally
=
1
was_in_try_finally
=
code
.
funcstate
.
in_try_finally
code
.
funcstate
.
in_try_finally
=
1
self
.
body
.
generate_execution_code
(
code
)
if
self
.
disallow_continue_in_try_finally
:
code
.
in_try_finally
=
was_in_try_finally
code
.
funcstate
.
in_try_finally
=
was_in_try_finally
code
.
putln
(
"}"
)
code
.
putln
(
...
...
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