Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
P
Pyston
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
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Boxiang Sun
Pyston
Commits
b8b126e3
Commit
b8b126e3
authored
Jul 28, 2015
by
Kevin Modzelewski
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #769 from kmod/exceptions2
Templatize runtimeCall for different exception styles
parents
c011fb3a
a62ba58f
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
267 additions
and
119 deletions
+267
-119
src/codegen/codegen.cpp
src/codegen/codegen.cpp
+4
-2
src/codegen/irgen.cpp
src/codegen/irgen.cpp
+1
-1
src/codegen/irgen/hooks.cpp
src/codegen/irgen/hooks.cpp
+14
-8
src/core/types.h
src/core/types.h
+32
-8
src/runtime/builtin_modules/builtins.cpp
src/runtime/builtin_modules/builtins.cpp
+1
-1
src/runtime/capi.cpp
src/runtime/capi.cpp
+6
-9
src/runtime/generator.cpp
src/runtime/generator.cpp
+2
-2
src/runtime/inline/list.cpp
src/runtime/inline/list.cpp
+17
-4
src/runtime/list.cpp
src/runtime/list.cpp
+5
-2
src/runtime/list.h
src/runtime/list.h
+1
-1
src/runtime/objmodel.cpp
src/runtime/objmodel.cpp
+163
-70
src/runtime/objmodel.h
src/runtime/objmodel.h
+9
-3
src/runtime/types.cpp
src/runtime/types.cpp
+12
-8
No files found.
src/codegen/codegen.cpp
View file @
b8b126e3
...
...
@@ -43,7 +43,8 @@ CLFunction::CLFunction(int num_args, int num_defaults, bool takes_varargs, bool
param_names
(
this
->
source
->
ast
,
this
->
source
->
getInternedStrings
()),
always_use_version
(
NULL
),
code_obj
(
NULL
),
times_interpreted
(
0
)
{
times_interpreted
(
0
),
internal_callable
(
NULL
,
NULL
)
{
assert
(
num_args
>=
num_defaults
);
}
CLFunction
::
CLFunction
(
int
num_args
,
int
num_defaults
,
bool
takes_varargs
,
bool
takes_kwargs
,
...
...
@@ -53,7 +54,8 @@ CLFunction::CLFunction(int num_args, int num_defaults, bool takes_varargs, bool
param_names
(
param_names
),
always_use_version
(
NULL
),
code_obj
(
NULL
),
times_interpreted
(
0
)
{
times_interpreted
(
0
),
internal_callable
(
NULL
,
NULL
)
{
assert
(
num_args
>=
num_defaults
);
}
...
...
src/codegen/irgen.cpp
View file @
b8b126e3
...
...
@@ -1016,7 +1016,7 @@ CompiledFunction* doCompile(CLFunction* clfunc, SourceInfo* source, ParamNames*
}
CompiledFunction
*
cf
=
new
CompiledFunction
(
NULL
,
spec
,
NULL
,
effort
,
entry_descriptor
);
CompiledFunction
*
cf
=
new
CompiledFunction
(
NULL
,
spec
,
NULL
,
effort
,
ExceptionStyle
::
CXX
,
entry_descriptor
);
// Make sure that the instruction memory keeps the module object alive.
// TODO: implement this for real
...
...
src/codegen/irgen/hooks.cpp
View file @
b8b126e3
...
...
@@ -716,6 +716,7 @@ void CompiledFunction::speculationFailed() {
}
CompiledFunction
::
CompiledFunction
(
llvm
::
Function
*
func
,
FunctionSpecialization
*
spec
,
void
*
code
,
EffortLevel
effort
,
ExceptionStyle
::
ExceptionStyle
exception_style
,
const
OSREntryDescriptor
*
entry_descriptor
)
:
clfunc
(
NULL
),
func
(
func
),
...
...
@@ -723,6 +724,7 @@ CompiledFunction::CompiledFunction(llvm::Function* func, FunctionSpecialization*
entry_descriptor
(
entry_descriptor
),
code
(
code
),
effort
(
effort
),
exception_style
(
exception_style
),
times_called
(
0
),
times_speculation_failed
(
0
),
location_map
(
nullptr
)
{
...
...
@@ -831,29 +833,32 @@ CLFunction* createRTFunction(int num_args, int num_defaults, bool takes_varargs,
return
new
CLFunction
(
num_args
,
num_defaults
,
takes_varargs
,
takes_kwargs
,
param_names
);
}
CLFunction
*
boxRTFunction
(
void
*
f
,
ConcreteCompilerType
*
rtn_type
,
int
num_args
,
const
ParamNames
&
param_names
)
{
CLFunction
*
boxRTFunction
(
void
*
f
,
ConcreteCompilerType
*
rtn_type
,
int
num_args
,
const
ParamNames
&
param_names
,
ExceptionStyle
::
ExceptionStyle
exception_style
)
{
assert
(
!
param_names
.
takes_param_names
||
num_args
==
param_names
.
args
.
size
());
assert
(
param_names
.
vararg
.
str
()
==
""
);
assert
(
param_names
.
kwarg
.
str
()
==
""
);
return
boxRTFunction
(
f
,
rtn_type
,
num_args
,
0
,
false
,
false
,
param_names
);
return
boxRTFunction
(
f
,
rtn_type
,
num_args
,
0
,
false
,
false
,
param_names
,
exception_style
);
}
CLFunction
*
boxRTFunction
(
void
*
f
,
ConcreteCompilerType
*
rtn_type
,
int
num_args
,
int
num_defaults
,
bool
takes_varargs
,
bool
takes_kwargs
,
const
ParamNames
&
param_names
)
{
bool
takes_kwargs
,
const
ParamNames
&
param_names
,
ExceptionStyle
::
ExceptionStyle
exception_style
)
{
assert
(
!
param_names
.
takes_param_names
||
num_args
==
param_names
.
args
.
size
());
assert
(
takes_varargs
||
param_names
.
vararg
.
str
()
==
""
);
assert
(
takes_kwargs
||
param_names
.
kwarg
.
str
()
==
""
);
CLFunction
*
cl_f
=
createRTFunction
(
num_args
,
num_defaults
,
takes_varargs
,
takes_kwargs
,
param_names
);
addRTFunction
(
cl_f
,
f
,
rtn_type
);
addRTFunction
(
cl_f
,
f
,
rtn_type
,
exception_style
);
return
cl_f
;
}
void
addRTFunction
(
CLFunction
*
cl_f
,
void
*
f
,
ConcreteCompilerType
*
rtn_type
)
{
void
addRTFunction
(
CLFunction
*
cl_f
,
void
*
f
,
ConcreteCompilerType
*
rtn_type
,
ExceptionStyle
::
ExceptionStyle
exception_style
)
{
std
::
vector
<
ConcreteCompilerType
*>
arg_types
(
cl_f
->
numReceivedArgs
(),
UNKNOWN
);
return
addRTFunction
(
cl_f
,
f
,
rtn_type
,
arg_types
);
return
addRTFunction
(
cl_f
,
f
,
rtn_type
,
arg_types
,
exception_style
);
}
static
ConcreteCompilerType
*
processType
(
ConcreteCompilerType
*
type
)
{
...
...
@@ -862,7 +867,8 @@ static ConcreteCompilerType* processType(ConcreteCompilerType* type) {
}
void
addRTFunction
(
CLFunction
*
cl_f
,
void
*
f
,
ConcreteCompilerType
*
rtn_type
,
const
std
::
vector
<
ConcreteCompilerType
*>&
arg_types
)
{
const
std
::
vector
<
ConcreteCompilerType
*>&
arg_types
,
ExceptionStyle
::
ExceptionStyle
exception_style
)
{
assert
(
arg_types
.
size
()
==
cl_f
->
numReceivedArgs
());
#ifndef NDEBUG
for
(
ConcreteCompilerType
*
t
:
arg_types
)
...
...
@@ -870,6 +876,6 @@ void addRTFunction(CLFunction* cl_f, void* f, ConcreteCompilerType* rtn_type,
#endif
FunctionSpecialization
*
spec
=
new
FunctionSpecialization
(
processType
(
rtn_type
),
arg_types
);
cl_f
->
addVersion
(
new
CompiledFunction
(
NULL
,
spec
,
f
,
EffortLevel
::
MAXIMAL
,
NULL
));
cl_f
->
addVersion
(
new
CompiledFunction
(
NULL
,
spec
,
f
,
EffortLevel
::
MAXIMAL
,
exception_style
,
NULL
));
}
}
src/core/types.h
View file @
b8b126e3
...
...
@@ -75,6 +75,25 @@ enum ExceptionStyle {
};
};
template
<
typename
R
,
typename
...
Args
>
struct
ExceptionSwitchableFunction
{
public:
typedef
R
(
*
FTy
)(
Args
...);
FTy
capi_ptr
;
FTy
cxx_ptr
;
ExceptionSwitchableFunction
(
FTy
capi_ptr
,
FTy
cxx_ptr
)
:
capi_ptr
(
capi_ptr
),
cxx_ptr
(
cxx_ptr
)
{}
template
<
ExceptionStyle
::
ExceptionStyle
S
>
FTy
get
()
{
if
(
S
==
ExceptionStyle
::
CAPI
)
return
capi_ptr
;
else
return
cxx_ptr
;
}
template
<
ExceptionStyle
::
ExceptionStyle
S
>
R
call
(
Args
...
args
)
noexcept
(
S
==
ExceptionStyle
::
CAPI
)
{
return
get
()(
args
...);
}
};
class
CompilerType
;
template
<
class
V
>
class
ValuedCompilerType
;
typedef
ValuedCompilerType
<
llvm
::
Value
*>
ConcreteCompilerType
;
...
...
@@ -264,6 +283,7 @@ public:
int
code_size
;
EffortLevel
effort
;
ExceptionStyle
::
ExceptionStyle
exception_style
;
int64_t
times_called
,
times_speculation_failed
;
ICInvalidator
dependent_callsites
;
...
...
@@ -273,7 +293,7 @@ public:
std
::
vector
<
ICInfo
*>
ics
;
CompiledFunction
(
llvm
::
Function
*
func
,
FunctionSpecialization
*
spec
,
void
*
code
,
EffortLevel
effort
,
const
OSREntryDescriptor
*
entry_descriptor
);
ExceptionStyle
::
ExceptionStyle
exception_style
,
const
OSREntryDescriptor
*
entry_descriptor
);
ConcreteCompilerType
*
getReturnType
();
...
...
@@ -352,9 +372,9 @@ public:
// of the normal dispatch through the functionlist.
// This can be used to implement functions which know how to rewrite themselves,
// such as typeCall.
typedef
Box
*
(
*
InternalCallable
)(
BoxedFunctionBase
*
,
CallRewriteArgs
*
,
ArgPassSpec
,
Box
*
,
Box
*
,
Box
*
,
Box
*
*
,
const
std
::
vector
<
BoxedString
*>*
)
;
InternalCallable
internal_callable
=
NULL
;
typedef
ExceptionSwitchableFunction
<
Box
*
,
BoxedFunctionBase
*
,
CallRewriteArgs
*
,
ArgPassSpec
,
Box
*
,
Box
*
,
Box
*
,
Box
**
,
const
std
::
vector
<
BoxedString
*>*>
InternalCallable
;
InternalCallable
internal_callable
;
CLFunction
(
int
num_args
,
int
num_defaults
,
bool
takes_varargs
,
bool
takes_kwargs
,
std
::
unique_ptr
<
SourceInfo
>
source
);
...
...
@@ -393,12 +413,16 @@ public:
CLFunction
*
createRTFunction
(
int
num_args
,
int
num_defaults
,
bool
takes_varargs
,
bool
takes_kwargs
,
const
ParamNames
&
param_names
=
ParamNames
::
empty
());
CLFunction
*
boxRTFunction
(
void
*
f
,
ConcreteCompilerType
*
rtn_type
,
int
nargs
,
int
num_defaults
,
bool
takes_varargs
,
bool
takes_kwargs
,
const
ParamNames
&
param_names
=
ParamNames
::
empty
());
bool
takes_kwargs
,
const
ParamNames
&
param_names
=
ParamNames
::
empty
(),
ExceptionStyle
::
ExceptionStyle
exception_style
=
ExceptionStyle
::
CXX
);
CLFunction
*
boxRTFunction
(
void
*
f
,
ConcreteCompilerType
*
rtn_type
,
int
nargs
,
const
ParamNames
&
param_names
=
ParamNames
::
empty
());
void
addRTFunction
(
CLFunction
*
cf
,
void
*
f
,
ConcreteCompilerType
*
rtn_type
);
const
ParamNames
&
param_names
=
ParamNames
::
empty
(),
ExceptionStyle
::
ExceptionStyle
exception_style
=
ExceptionStyle
::
CXX
);
void
addRTFunction
(
CLFunction
*
cf
,
void
*
f
,
ConcreteCompilerType
*
rtn_type
,
ExceptionStyle
::
ExceptionStyle
exception_style
=
ExceptionStyle
::
CXX
);
void
addRTFunction
(
CLFunction
*
cf
,
void
*
f
,
ConcreteCompilerType
*
rtn_type
,
const
std
::
vector
<
ConcreteCompilerType
*>&
arg_types
);
const
std
::
vector
<
ConcreteCompilerType
*>&
arg_types
,
ExceptionStyle
::
ExceptionStyle
exception_style
=
ExceptionStyle
::
CXX
);
CLFunction
*
unboxRTFunction
(
Box
*
);
// Compiles a new version of the function with the given signature and adds it to the list;
...
...
src/runtime/builtin_modules/builtins.cpp
View file @
b8b126e3
...
...
@@ -1382,7 +1382,7 @@ void setupBuiltins() {
builtins_module
->
giveAttr
(
"repr"
,
repr_obj
);
auto
len_func
=
boxRTFunction
((
void
*
)
len
,
UNKNOWN
,
1
);
len_func
->
internal_callable
=
lenCallInternal
;
len_func
->
internal_callable
.
cxx_ptr
=
lenCallInternal
;
len_obj
=
new
BoxedBuiltinFunctionOrMethod
(
len_func
,
"len"
);
builtins_module
->
giveAttr
(
"len"
,
len_obj
);
...
...
src/runtime/capi.cpp
View file @
b8b126e3
...
...
@@ -578,15 +578,12 @@ extern "C" int PyObject_Not(PyObject* o) noexcept {
}
extern
"C"
PyObject
*
PyObject_Call
(
PyObject
*
callable_object
,
PyObject
*
args
,
PyObject
*
kw
)
noexcept
{
try
{
if
(
kw
)
return
runtimeCall
(
callable_object
,
ArgPassSpec
(
0
,
0
,
true
,
true
),
args
,
kw
,
NULL
,
NULL
,
NULL
);
else
return
runtimeCall
(
callable_object
,
ArgPassSpec
(
0
,
0
,
true
,
false
),
args
,
NULL
,
NULL
,
NULL
,
NULL
);
}
catch
(
ExcInfo
e
)
{
setCAPIException
(
e
);
return
NULL
;
}
if
(
kw
)
return
runtimeCallInternal
<
ExceptionStyle
::
CAPI
>
(
callable_object
,
NULL
,
ArgPassSpec
(
0
,
0
,
true
,
true
),
args
,
kw
,
NULL
,
NULL
,
NULL
);
else
return
runtimeCallInternal
<
ExceptionStyle
::
CAPI
>
(
callable_object
,
NULL
,
ArgPassSpec
(
0
,
0
,
true
,
false
),
args
,
NULL
,
NULL
,
NULL
,
NULL
);
}
extern
"C"
int
PyObject_GetBuffer
(
PyObject
*
obj
,
Py_buffer
*
view
,
int
flags
)
noexcept
{
...
...
src/runtime/generator.cpp
View file @
b8b126e3
...
...
@@ -98,8 +98,8 @@ void generatorEntry(BoxedGenerator* g) {
BoxedFunctionBase
*
func
=
g
->
function
;
Box
**
args
=
g
->
args
?
&
g
->
args
->
elts
[
0
]
:
nullptr
;
callCLFunc
(
func
->
f
,
nullptr
,
func
->
f
->
numReceivedArgs
(),
func
->
closure
,
g
,
func
->
globals
,
g
->
arg1
,
g
->
arg2
,
g
->
arg3
,
args
);
callCLFunc
<
ExceptionStyle
::
CXX
>
(
func
->
f
,
nullptr
,
func
->
f
->
numReceivedArgs
(),
func
->
closure
,
g
,
func
->
globals
,
g
->
arg1
,
g
->
arg2
,
g
->
arg3
,
args
);
}
catch
(
ExcInfo
e
)
{
// unhandled exception: propagate the exception to the caller
g
->
exception
=
e
;
...
...
src/runtime/inline/list.cpp
View file @
b8b126e3
...
...
@@ -22,6 +22,9 @@
namespace
pyston
{
using
namespace
pyston
::
ExceptionStyle
;
using
pyston
::
ExceptionStyle
::
ExceptionStyle
;
BoxedListIterator
::
BoxedListIterator
(
BoxedList
*
l
,
int
start
)
:
l
(
l
),
pos
(
start
)
{
}
...
...
@@ -65,24 +68,34 @@ i1 listiterHasnextUnboxed(Box* s) {
return
ans
;
}
Box
*
listiterNext
(
Box
*
s
)
{
template
<
enum
ExceptionStyle
S
>
Box
*
listiterNext
(
Box
*
s
)
noexcept
(
S
==
CAPI
)
{
assert
(
s
->
cls
==
list_iterator_cls
);
BoxedListIterator
*
self
=
static_cast
<
BoxedListIterator
*>
(
s
);
if
(
!
self
->
l
)
{
raiseExcHelper
(
StopIteration
,
""
);
if
(
S
==
CAPI
)
{
PyErr_SetObject
(
StopIteration
,
None
);
return
NULL
;
}
else
raiseExcHelper
(
StopIteration
,
""
);
}
if
(
!
(
self
->
pos
>=
0
&&
self
->
pos
<
self
->
l
->
size
))
{
self
->
l
=
NULL
;
raiseExcHelper
(
StopIteration
,
""
);
if
(
S
==
CAPI
)
{
PyErr_SetObject
(
StopIteration
,
None
);
return
NULL
;
}
else
raiseExcHelper
(
StopIteration
,
""
);
}
Box
*
rtn
=
self
->
l
->
elts
->
elts
[
self
->
pos
];
self
->
pos
++
;
return
rtn
;
}
// force instantiation:
template
Box
*
listiterNext
<
CAPI
>(
Box
*
);
template
Box
*
listiterNext
<
CXX
>(
Box
*
);
Box
*
listReversed
(
Box
*
s
)
{
assert
(
isSubclass
(
s
->
cls
,
list_cls
));
...
...
src/runtime/list.cpp
View file @
b8b126e3
...
...
@@ -704,7 +704,7 @@ private:
public:
PyCmpComparer
(
Box
*
cmp
)
:
cmp
(
cmp
)
{}
bool
operator
()(
Box
*
lhs
,
Box
*
rhs
)
{
Box
*
r
=
runtimeCallInternal
(
cmp
,
NULL
,
ArgPassSpec
(
2
),
lhs
,
rhs
,
NULL
,
NULL
,
NULL
);
Box
*
r
=
runtimeCallInternal
<
ExceptionStyle
::
CXX
>
(
cmp
,
NULL
,
ArgPassSpec
(
2
),
lhs
,
rhs
,
NULL
,
NULL
,
NULL
);
if
(
!
isSubclass
(
r
->
cls
,
int_cls
))
raiseExcHelper
(
TypeError
,
"comparison function must return int, not %.200s"
,
r
->
cls
->
tp_name
);
return
static_cast
<
BoxedInt
*>
(
r
)
->
n
<
0
;
...
...
@@ -1169,7 +1169,10 @@ void setupList() {
list_iterator_cls
->
giveAttr
(
"__hasnext__"
,
new
BoxedFunction
(
hasnext
));
list_iterator_cls
->
giveAttr
(
"__iter__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
listIterIter
,
typeFromClass
(
list_iterator_cls
),
1
)));
list_iterator_cls
->
giveAttr
(
"next"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
listiterNext
,
UNKNOWN
,
1
)));
CLFunction
*
listiter_next
=
boxRTFunction
((
void
*
)
listiterNext
<
ExceptionStyle
::
CXX
>
,
UNKNOWN
,
1
);
addRTFunction
(
listiter_next
,
(
void
*
)
listiterNext
<
ExceptionStyle
::
CAPI
>
,
UNKNOWN
,
ExceptionStyle
::
CAPI
);
list_iterator_cls
->
giveAttr
(
"next"
,
new
BoxedFunction
(
listiter_next
));
list_iterator_cls
->
freeze
();
list_iterator_cls
->
tpp_hasnext
=
listiterHasnextUnboxed
;
...
...
src/runtime/list.h
View file @
b8b126e3
...
...
@@ -35,7 +35,7 @@ Box* listIter(Box* self);
Box
*
listIterIter
(
Box
*
self
);
Box
*
listiterHasnext
(
Box
*
self
);
i1
listiterHasnextUnboxed
(
Box
*
self
);
Box
*
listiterNext
(
Box
*
self
);
template
<
ExceptionStyle
::
ExceptionStyle
S
>
Box
*
listiterNext
(
Box
*
self
)
noexcept
(
S
==
ExceptionStyle
::
CAPI
);
Box
*
listReversed
(
Box
*
self
);
Box
*
listreviterHasnext
(
Box
*
self
);
i1
listreviterHasnextUnboxed
(
Box
*
self
);
...
...
src/runtime/objmodel.cpp
View file @
b8b126e3
...
...
@@ -80,19 +80,23 @@ void REWRITE_ABORTED(const char* reason) {
#define REWRITE_ABORTED(reason) ((void)(reason))
#endif
template
<
enum
ExceptionStyle
S
>
static
inline
Box
*
runtimeCallInternal0
(
Box
*
obj
,
CallRewriteArgs
*
rewrite_args
,
ArgPassSpec
argspec
)
{
return
runtimeCallInternal
(
obj
,
rewrite_args
,
argspec
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
);
return
runtimeCallInternal
<
S
>
(
obj
,
rewrite_args
,
argspec
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
);
}
template
<
enum
ExceptionStyle
S
>
static
inline
Box
*
runtimeCallInternal1
(
Box
*
obj
,
CallRewriteArgs
*
rewrite_args
,
ArgPassSpec
argspec
,
Box
*
arg1
)
{
return
runtimeCallInternal
(
obj
,
rewrite_args
,
argspec
,
arg1
,
NULL
,
NULL
,
NULL
,
NULL
);
return
runtimeCallInternal
<
S
>
(
obj
,
rewrite_args
,
argspec
,
arg1
,
NULL
,
NULL
,
NULL
,
NULL
);
}
template
<
enum
ExceptionStyle
S
>
static
inline
Box
*
runtimeCallInternal2
(
Box
*
obj
,
CallRewriteArgs
*
rewrite_args
,
ArgPassSpec
argspec
,
Box
*
arg1
,
Box
*
arg2
)
{
return
runtimeCallInternal
(
obj
,
rewrite_args
,
argspec
,
arg1
,
arg2
,
NULL
,
NULL
,
NULL
);
return
runtimeCallInternal
<
S
>
(
obj
,
rewrite_args
,
argspec
,
arg1
,
arg2
,
NULL
,
NULL
,
NULL
);
}
template
<
enum
ExceptionStyle
S
>
static
inline
Box
*
runtimeCallInternal3
(
Box
*
obj
,
CallRewriteArgs
*
rewrite_args
,
ArgPassSpec
argspec
,
Box
*
arg1
,
Box
*
arg2
,
Box
*
arg3
)
{
return
runtimeCallInternal
(
obj
,
rewrite_args
,
argspec
,
arg1
,
arg2
,
arg3
,
NULL
,
NULL
);
return
runtimeCallInternal
<
S
>
(
obj
,
rewrite_args
,
argspec
,
arg1
,
arg2
,
arg3
,
NULL
,
NULL
);
}
bool
checkClass
(
LookupScope
scope
)
{
...
...
@@ -1430,7 +1434,7 @@ Box* dataDescriptorInstanceSpecialCases(GetattrRewriteArgs* rewrite_args, BoxedS
if
(
prop
->
prop_get
==
NULL
||
prop
->
prop_get
==
None
)
{
raiseExcHelper
(
AttributeError
,
"unreadable attribute"
);
}
return
runtimeCallInternal1
(
prop
->
prop_get
,
NULL
,
ArgPassSpec
(
1
),
obj
);
return
runtimeCallInternal1
<
CXX
>
(
prop
->
prop_get
,
NULL
,
ArgPassSpec
(
1
),
obj
);
}
// Special case: data descriptor: getset descriptor
...
...
@@ -1774,8 +1778,8 @@ Box* getattrInternalGeneric(Box* obj, BoxedString* attr, GetattrRewriteArgs* rew
crewrite_args
.
arg1
=
r_descr
;
crewrite_args
.
arg2
=
rewrite_args
->
obj
;
crewrite_args
.
arg3
=
rewrite_args
->
obj
->
getAttr
(
offsetof
(
Box
,
cls
),
Location
::
any
());
res
=
runtimeCallInternal
(
_get_
,
&
crewrite_args
,
ArgPassSpec
(
3
),
descr
,
obj
,
obj
->
cls
,
NULL
,
NULL
);
res
=
runtimeCallInternal
<
CXX
>
(
_get_
,
&
crewrite_args
,
ArgPassSpec
(
3
),
descr
,
obj
,
obj
->
cls
,
NULL
,
NULL
);
if
(
!
crewrite_args
.
out_success
)
{
rewrite_args
=
NULL
;
}
else
{
...
...
@@ -1886,8 +1890,8 @@ Box* getattrInternalGeneric(Box* obj, BoxedString* attr, GetattrRewriteArgs* rew
crewrite_args
.
arg1
=
r_val
;
crewrite_args
.
arg2
=
rewrite_args
->
rewriter
->
loadConst
((
intptr_t
)
None
,
Location
::
any
());
crewrite_args
.
arg3
=
rewrite_args
->
obj
;
res
=
runtimeCallInternal
(
local_get
,
&
crewrite_args
,
ArgPassSpec
(
3
),
val
,
None
,
obj
,
NULL
,
NULL
);
res
=
runtimeCallInternal
<
CXX
>
(
local_get
,
&
crewrite_args
,
ArgPassSpec
(
3
),
val
,
None
,
obj
,
NULL
,
NULL
);
if
(
!
crewrite_args
.
out_success
)
{
rewrite_args
=
NULL
;
}
else
{
...
...
@@ -1895,7 +1899,7 @@ Box* getattrInternalGeneric(Box* obj, BoxedString* attr, GetattrRewriteArgs* rew
rewrite_args
->
out_rtn
=
crewrite_args
.
out_rtn
;
}
}
else
{
res
=
runtimeCallInternal
(
local_get
,
NULL
,
ArgPassSpec
(
3
),
val
,
None
,
obj
,
NULL
,
NULL
);
res
=
runtimeCallInternal
<
CXX
>
(
local_get
,
NULL
,
ArgPassSpec
(
3
),
val
,
None
,
obj
,
NULL
,
NULL
);
}
return
res
;
}
...
...
@@ -1943,7 +1947,7 @@ Box* getattrInternalGeneric(Box* obj, BoxedString* attr, GetattrRewriteArgs* rew
crewrite_args
.
arg1
=
r_descr
;
crewrite_args
.
arg2
=
rewrite_args
->
obj
;
crewrite_args
.
arg3
=
rewrite_args
->
obj
->
getAttr
(
offsetof
(
Box
,
cls
),
Location
::
any
());
res
=
runtimeCallInternal
(
_get_
,
&
crewrite_args
,
ArgPassSpec
(
3
),
descr
,
obj
,
obj
->
cls
,
NULL
,
NULL
);
res
=
runtimeCallInternal
<
CXX
>
(
_get_
,
&
crewrite_args
,
ArgPassSpec
(
3
),
descr
,
obj
,
obj
->
cls
,
NULL
,
NULL
);
if
(
!
crewrite_args
.
out_success
)
{
rewrite_args
=
NULL
;
}
else
{
...
...
@@ -2211,12 +2215,12 @@ void setattrGeneric(Box* obj, BoxedString* attr, Box* val, SetattrRewriteArgs* r
crewrite_args
.
arg1
=
r_descr
;
crewrite_args
.
arg2
=
rewrite_args
->
obj
;
crewrite_args
.
arg3
=
rewrite_args
->
attrval
;
runtimeCallInternal
(
_set_
,
&
crewrite_args
,
ArgPassSpec
(
3
),
descr
,
obj
,
val
,
NULL
,
NULL
);
runtimeCallInternal
<
CXX
>
(
_set_
,
&
crewrite_args
,
ArgPassSpec
(
3
),
descr
,
obj
,
val
,
NULL
,
NULL
);
if
(
crewrite_args
.
out_success
)
{
rewrite_args
->
out_success
=
true
;
}
}
else
{
runtimeCallInternal
(
_set_
,
NULL
,
ArgPassSpec
(
3
),
descr
,
obj
,
val
,
NULL
,
NULL
);
runtimeCallInternal
<
CXX
>
(
_set_
,
NULL
,
ArgPassSpec
(
3
),
descr
,
obj
,
val
,
NULL
,
NULL
);
}
// We don't need to to the invalidation stuff in this case.
...
...
@@ -2327,7 +2331,7 @@ extern "C" void setattr(Box* obj, BoxedString* attr, Box* attr_val) {
// TODO actually rewrite this?
setattr
=
processDescriptor
(
setattr
,
obj
,
obj
->
cls
);
runtimeCallInternal
(
setattr
,
NULL
,
ArgPassSpec
(
2
),
attr
,
attr_val
,
NULL
,
NULL
,
NULL
);
runtimeCallInternal
<
CXX
>
(
setattr
,
NULL
,
ArgPassSpec
(
2
),
attr
,
attr_val
,
NULL
,
NULL
,
NULL
);
}
else
{
STAT_TIMER
(
t0
,
"us_timer_slowpath_tpsetattro"
,
10
);
int
r
=
tp_setattro
(
obj
,
attr
,
attr_val
);
...
...
@@ -2461,7 +2465,7 @@ extern "C" bool nonzero(Box* obj) {
return
true
;
}
Box
*
r
=
runtimeCallInternal
(
func
,
NULL
,
ArgPassSpec
(
0
),
NULL
,
NULL
,
NULL
,
NULL
,
NULL
);
Box
*
r
=
runtimeCallInternal
<
CXX
>
(
func
,
NULL
,
ArgPassSpec
(
0
),
NULL
,
NULL
,
NULL
,
NULL
,
NULL
);
// I believe this behavior is handled by the slot wrappers in CPython:
if
(
r
->
cls
==
bool_cls
)
{
BoxedBool
*
b
=
static_cast
<
BoxedBool
*>
(
r
);
...
...
@@ -2687,7 +2691,7 @@ template BoxedInt* lenInternal<CXX>(Box*, LenRewriteArgs*);
Box
*
lenCallInternal
(
BoxedFunctionBase
*
func
,
CallRewriteArgs
*
rewrite_args
,
ArgPassSpec
argspec
,
Box
*
arg1
,
Box
*
arg2
,
Box
*
arg3
,
Box
**
args
,
const
std
::
vector
<
BoxedString
*>*
keyword_names
)
{
if
(
argspec
!=
ArgPassSpec
(
1
))
return
callFunc
(
func
,
rewrite_args
,
argspec
,
arg1
,
arg2
,
arg3
,
args
,
keyword_names
);
return
callFunc
<
CXX
>
(
func
,
rewrite_args
,
argspec
,
arg1
,
arg2
,
arg3
,
args
,
keyword_names
);
if
(
rewrite_args
)
{
LenRewriteArgs
lrewrite_args
(
rewrite_args
->
rewriter
,
rewrite_args
->
arg1
,
rewrite_args
->
destination
);
...
...
@@ -2993,13 +2997,13 @@ extern "C" Box* callattrInternal(Box* obj, BoxedString* attr, LookupScope scope,
Box
*
rtn
;
ArgPassSpec
new_argspec
=
bindObjIntoArgs
(
bind_obj
,
r_bind_obj
,
rewrite_args
,
argspec
,
arg1
,
arg2
,
arg3
,
args
,
new_args
);
return
runtimeCallInternal
(
val
,
rewrite_args
,
new_argspec
,
arg1
,
arg2
,
arg3
,
new_args
,
keyword_names
);
return
runtimeCallInternal
<
CXX
>
(
val
,
rewrite_args
,
new_argspec
,
arg1
,
arg2
,
arg3
,
new_args
,
keyword_names
);
}
else
{
if
(
rewrite_args
)
{
rewrite_args
->
obj
=
r_val
;
}
Box
*
rtn
=
runtimeCallInternal
(
val
,
rewrite_args
,
argspec
,
arg1
,
arg2
,
arg3
,
args
,
keyword_names
);
Box
*
rtn
=
runtimeCallInternal
<
CXX
>
(
val
,
rewrite_args
,
argspec
,
arg1
,
arg2
,
arg3
,
args
,
keyword_names
);
assert
(
rtn
);
// not sure why we have this here
return
rtn
;
}
...
...
@@ -3100,42 +3104,49 @@ static inline RewriterVar* getArg(int idx, CallRewriteArgs* rewrite_args) {
}
static
StatCounter
slowpath_pickversion
(
"slowpath_pickversion"
);
static
CompiledFunction
*
pickVersion
(
CLFunction
*
f
,
int
num_output_args
,
Box
*
oarg1
,
Box
*
oarg2
,
Box
*
oarg3
,
Box
**
oargs
)
{
static
CompiledFunction
*
pickVersion
(
CLFunction
*
f
,
enum
ExceptionStyle
S
,
int
num_output_args
,
Box
*
oarg1
,
Box
*
oarg2
,
Box
*
oarg3
,
Box
*
*
oargs
)
{
LOCK_REGION
(
codegen_rwlock
.
asWrite
());
if
(
f
->
always_use_version
)
if
(
f
->
always_use_version
&&
f
->
always_use_version
->
exception_style
==
S
)
return
f
->
always_use_version
;
slowpath_pickversion
.
log
();
CompiledFunction
*
best_nonexcmatch
=
NULL
;
for
(
CompiledFunction
*
cf
:
f
->
versions
)
{
assert
(
cf
->
spec
->
arg_types
.
size
()
==
num_output_args
);
if
(
!
cf
->
spec
->
boxed_return_value
)
continue
;
if
(
cf
->
spec
->
accepts_all_inputs
)
return
cf
;
if
(
!
cf
->
spec
->
accepts_all_inputs
)
{
assert
(
cf
->
spec
->
rtn_type
->
llvmType
()
==
UNKNOWN
->
llvmType
())
;
assert
(
cf
->
spec
->
rtn_type
->
llvmType
()
==
UNKNOWN
->
llvmType
());
bool
works
=
true
;
for
(
int
i
=
0
;
i
<
num_output_args
;
i
++
)
{
Box
*
arg
=
getArg
(
i
,
oarg1
,
oarg2
,
oarg3
,
oargs
);
bool
works
=
true
;
for
(
int
i
=
0
;
i
<
num_output_args
;
i
++
)
{
Box
*
arg
=
getArg
(
i
,
oarg1
,
oarg2
,
oarg3
,
oargs
);
ConcreteCompilerType
*
t
=
cf
->
spec
->
arg_types
[
i
];
if
((
arg
&&
!
t
->
isFitBy
(
arg
->
cls
))
||
(
!
arg
&&
t
!=
UNKNOWN
))
{
works
=
false
;
break
;
ConcreteCompilerType
*
t
=
cf
->
spec
->
arg_types
[
i
];
if
((
arg
&&
!
t
->
isFitBy
(
arg
->
cls
))
||
(
!
arg
&&
t
!=
UNKNOWN
))
{
works
=
false
;
break
;
}
}
}
if
(
!
works
)
continue
;
if
(
!
works
)
continue
;
}
return
cf
;
if
(
cf
->
exception_style
==
S
)
return
cf
;
else
if
(
!
best_nonexcmatch
)
best_nonexcmatch
=
cf
;
}
if
(
best_nonexcmatch
)
return
best_nonexcmatch
;
if
(
f
->
source
==
NULL
)
{
// TODO I don't think this should be happening any more?
printf
(
"Error: couldn't find suitable function version and no source to recompile!
\n
"
);
...
...
@@ -3201,7 +3212,7 @@ static Box* _callFuncHelper(BoxedFunctionBase* func, ArgPassSpec argspec, Box* a
void
**
extra_args
)
{
Box
**
args
=
(
Box
**
)
extra_args
[
0
];
auto
keyword_names
=
(
const
std
::
vector
<
BoxedString
*>*
)
extra_args
[
1
];
return
callFunc
(
func
,
NULL
,
argspec
,
arg1
,
arg2
,
arg3
,
args
,
keyword_names
);
return
callFunc
<
CXX
>
(
func
,
NULL
,
argspec
,
arg1
,
arg2
,
arg3
,
args
,
keyword_names
);
}
typedef
std
::
function
<
Box
*
(
int
,
int
,
RewriterVar
*&
)
>
GetDefaultFunc
;
...
...
@@ -3556,14 +3567,20 @@ void rearrangeArguments(ParamReceiveSpec paramspec, const ParamNames* param_name
}
static
StatCounter
slowpath_callfunc
(
"slowpath_callfunc"
);
template
<
enum
ExceptionStyle
S
>
Box
*
callFunc
(
BoxedFunctionBase
*
func
,
CallRewriteArgs
*
rewrite_args
,
ArgPassSpec
argspec
,
Box
*
arg1
,
Box
*
arg2
,
Box
*
arg3
,
Box
**
args
,
const
std
::
vector
<
BoxedString
*>*
keyword_names
)
{
Box
*
arg3
,
Box
**
args
,
const
std
::
vector
<
BoxedString
*>*
keyword_names
)
noexcept
(
S
==
CAPI
)
{
#if STAT_TIMERS
StatTimer
::
assertActive
();
STAT_TIMER
(
t0
,
"us_timer_slowpath_callFunc"
,
0
);
#endif
slowpath_callfunc
.
log
();
if
(
S
==
CAPI
)
{
assert
(
!
rewrite_args
&&
"implement me"
);
rewrite_args
=
NULL
;
}
CLFunction
*
f
=
func
->
f
;
ParamReceiveSpec
paramspec
=
f
->
paramspec
;
...
...
@@ -3658,6 +3675,7 @@ Box* callFunc(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args, ArgPassSpe
arg_vec
.
push_back
(
args_array
);
for
(
auto
v
:
arg_vec
)
assert
(
v
);
assert
(
S
==
CXX
);
// _callFuncHelper currently is CXX-only
RewriterVar
*
r_rtn
=
rewriter
->
call
(
true
,
(
void
*
)
_callFuncHelper
,
arg_vec
);
rewrite_args
->
out_success
=
true
;
...
...
@@ -3676,14 +3694,31 @@ Box* callFunc(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args, ArgPassSpe
// rewrite up to the call to it:
res
=
createGenerator
(
func
,
oarg1
,
oarg2
,
oarg3
,
oargs
);
}
else
{
res
=
callCLFunc
(
f
,
rewrite_args
,
num_output_args
,
closure
,
NULL
,
func
->
globals
,
oarg1
,
oarg2
,
oarg3
,
oargs
);
res
=
callCLFunc
<
S
>
(
f
,
rewrite_args
,
num_output_args
,
closure
,
NULL
,
func
->
globals
,
oarg1
,
oarg2
,
oarg3
,
oargs
);
}
return
res
;
}
template
<
enum
ExceptionStyle
S
>
static
Box
*
callChosenCF
(
CompiledFunction
*
chosen_cf
,
BoxedClosure
*
closure
,
BoxedGenerator
*
generator
,
Box
*
oarg1
,
Box
*
oarg2
,
Box
*
oarg3
,
Box
**
oargs
)
{
Box
*
oarg2
,
Box
*
oarg3
,
Box
**
oargs
)
noexcept
(
S
==
CAPI
)
{
if
(
S
!=
chosen_cf
->
exception_style
)
{
if
(
S
==
CAPI
)
{
try
{
return
callChosenCF
<
CXX
>
(
chosen_cf
,
closure
,
generator
,
oarg1
,
oarg2
,
oarg3
,
oargs
);
}
catch
(
ExcInfo
e
)
{
setCAPIException
(
e
);
return
NULL
;
}
}
else
{
Box
*
r
=
callChosenCF
<
CAPI
>
(
chosen_cf
,
closure
,
generator
,
oarg1
,
oarg2
,
oarg3
,
oargs
);
if
(
!
r
)
throwCAPIException
();
return
r
;
}
}
if
(
closure
&&
generator
)
return
chosen_cf
->
closure_generator_call
(
closure
,
generator
,
oarg1
,
oarg2
,
oarg3
,
oargs
);
else
if
(
closure
)
...
...
@@ -3707,9 +3742,16 @@ static Box* astInterpretHelper(CLFunction* f, int num_args, BoxedClosure* closur
return
astInterpretFunction
(
f
,
num_args
,
closure
,
generator
,
globals
,
arg1
,
arg2
,
arg3
,
(
Box
**
)
args
);
}
template
<
enum
ExceptionStyle
S
>
Box
*
callCLFunc
(
CLFunction
*
f
,
CallRewriteArgs
*
rewrite_args
,
int
num_output_args
,
BoxedClosure
*
closure
,
BoxedGenerator
*
generator
,
Box
*
globals
,
Box
*
oarg1
,
Box
*
oarg2
,
Box
*
oarg3
,
Box
**
oargs
)
{
CompiledFunction
*
chosen_cf
=
pickVersion
(
f
,
num_output_args
,
oarg1
,
oarg2
,
oarg3
,
oargs
);
BoxedGenerator
*
generator
,
Box
*
globals
,
Box
*
oarg1
,
Box
*
oarg2
,
Box
*
oarg3
,
Box
**
oargs
)
noexcept
(
S
==
CAPI
)
{
if
(
S
==
CAPI
)
{
assert
(
!
rewrite_args
&&
"implement me"
);
rewrite_args
=
NULL
;
}
CompiledFunction
*
chosen_cf
=
pickVersion
(
f
,
S
,
num_output_args
,
oarg1
,
oarg2
,
oarg3
,
oargs
);
if
(
!
chosen_cf
)
{
if
(
rewrite_args
)
{
...
...
@@ -3739,11 +3781,22 @@ Box* callCLFunc(CLFunction* f, CallRewriteArgs* rewrite_args, int num_output_arg
if
(
num_output_args
>=
4
)
arg_array
->
setAttr
(
24
,
rewrite_args
->
args
);
assert
(
S
==
CXX
);
rewrite_args
->
out_rtn
=
rewrite_args
->
rewriter
->
call
(
true
,
(
void
*
)
astInterpretHelper
,
arg_vec
);
rewrite_args
->
out_success
=
true
;
}
return
astInterpretFunction
(
f
,
num_output_args
,
closure
,
generator
,
globals
,
oarg1
,
oarg2
,
oarg3
,
oargs
);
if
(
S
==
CAPI
)
{
try
{
return
astInterpretFunction
(
f
,
num_output_args
,
closure
,
generator
,
globals
,
oarg1
,
oarg2
,
oarg3
,
oargs
);
}
catch
(
ExcInfo
e
)
{
setCAPIException
(
e
);
return
NULL
;
}
}
else
{
return
astInterpretFunction
(
f
,
num_output_args
,
closure
,
generator
,
globals
,
oarg1
,
oarg2
,
oarg3
,
oargs
);
}
}
ASSERT
(
!
globals
,
"need to update the calling conventions if we want to pass globals"
);
...
...
@@ -3765,6 +3818,7 @@ Box* callCLFunc(CLFunction* f, CallRewriteArgs* rewrite_args, int num_output_arg
if
(
num_output_args
>=
4
)
arg_vec
.
push_back
(
rewrite_args
->
args
);
assert
(
S
==
CXX
&&
chosen_cf
->
exception_style
==
CXX
);
rewrite_args
->
out_rtn
=
rewrite_args
->
rewriter
->
call
(
true
,
(
void
*
)
chosen_cf
->
call
,
arg_vec
);
rewrite_args
->
out_success
=
true
;
}
...
...
@@ -3775,29 +3829,48 @@ Box* callCLFunc(CLFunction* f, CallRewriteArgs* rewrite_args, int num_output_arg
// code and calls that target to builtins.
if
(
f
->
source
)
{
UNAVOIDABLE_STAT_TIMER
(
t0
,
"us_timer_in_jitted_code"
);
r
=
callChosenCF
(
chosen_cf
,
closure
,
generator
,
oarg1
,
oarg2
,
oarg3
,
oargs
);
r
=
callChosenCF
<
S
>
(
chosen_cf
,
closure
,
generator
,
oarg1
,
oarg2
,
oarg3
,
oargs
);
}
else
{
UNAVOIDABLE_STAT_TIMER
(
t0
,
"us_timer_in_builtins"
);
r
=
callChosenCF
(
chosen_cf
,
closure
,
generator
,
oarg1
,
oarg2
,
oarg3
,
oargs
);
r
=
callChosenCF
<
S
>
(
chosen_cf
,
closure
,
generator
,
oarg1
,
oarg2
,
oarg3
,
oargs
);
}
ASSERT
(
chosen_cf
->
spec
->
rtn_type
->
isFitBy
(
r
->
cls
),
"%s (%p) was supposed to return %s, but gave a %s"
,
g
.
func_addr_registry
.
getFuncNameAtAddress
(
chosen_cf
->
code
,
true
,
NULL
).
c_str
(),
chosen_cf
->
code
,
chosen_cf
->
spec
->
rtn_type
->
debugName
().
c_str
(),
r
->
cls
->
tp_name
);
assert
(
!
PyErr_Occurred
());
if
(
!
r
)
{
assert
(
S
==
CAPI
);
}
else
{
ASSERT
(
chosen_cf
->
spec
->
rtn_type
->
isFitBy
(
r
->
cls
),
"%s (%p) was supposed to return %s, but gave a %s"
,
g
.
func_addr_registry
.
getFuncNameAtAddress
(
chosen_cf
->
code
,
true
,
NULL
).
c_str
(),
chosen_cf
->
code
,
chosen_cf
->
spec
->
rtn_type
->
debugName
().
c_str
(),
r
->
cls
->
tp_name
);
assert
(
!
PyErr_Occurred
());
}
return
r
;
}
template
<
enum
ExceptionStyle
S
>
Box
*
runtimeCallInternal
(
Box
*
obj
,
CallRewriteArgs
*
rewrite_args
,
ArgPassSpec
argspec
,
Box
*
arg1
,
Box
*
arg2
,
Box
*
arg3
,
Box
**
args
,
const
std
::
vector
<
BoxedString
*>*
keyword_names
)
{
Box
**
args
,
const
std
::
vector
<
BoxedString
*>*
keyword_names
)
noexcept
(
S
==
CAPI
)
{
int
npassed_args
=
argspec
.
totalPassed
();
if
(
S
==
CAPI
)
{
assert
(
!
rewrite_args
&&
"implement me"
);
rewrite_args
=
NULL
;
}
if
(
obj
->
cls
!=
function_cls
&&
obj
->
cls
!=
builtin_function_or_method_cls
&&
obj
->
cls
!=
instancemethod_cls
)
{
// TODO: maybe eventually runtimeCallInternal should just be the default tpp_call?
if
(
obj
->
cls
->
tpp_call
)
{
return
obj
->
cls
->
tpp_call
(
obj
,
rewrite_args
,
argspec
,
arg1
,
arg2
,
arg3
,
args
,
keyword_names
);
if
(
S
==
CAPI
)
{
try
{
return
obj
->
cls
->
tpp_call
(
obj
,
rewrite_args
,
argspec
,
arg1
,
arg2
,
arg3
,
args
,
keyword_names
);
}
catch
(
ExcInfo
e
)
{
setCAPIException
(
e
);
return
NULL
;
}
}
else
{
return
obj
->
cls
->
tpp_call
(
obj
,
rewrite_args
,
argspec
,
arg1
,
arg2
,
arg3
,
args
,
keyword_names
);
}
}
STAT_TIMER
(
t0
,
"us_timer_slowpath_runtimecall_nonfunction"
,
20
);
...
...
@@ -3818,14 +3891,28 @@ Box* runtimeCallInternal(Box* obj, CallRewriteArgs* rewrite_args, ArgPassSpec ar
assert
((
obj
->
cls
->
tp_call
==
NULL
)
==
(
typeLookup
(
obj
->
cls
,
call_str
,
NULL
)
==
NULL
));
}
if
(
rewrite_args
)
{
rtn
=
callattrInternal
(
obj
,
call_str
,
CLASS_ONLY
,
rewrite_args
,
argspec
,
arg1
,
arg2
,
arg3
,
args
,
keyword_names
);
}
else
{
rtn
=
callattrInternal
(
obj
,
call_str
,
CLASS_ONLY
,
NULL
,
argspec
,
arg1
,
arg2
,
arg3
,
args
,
keyword_names
);
try
{
if
(
rewrite_args
)
{
rtn
=
callattrInternal
(
obj
,
call_str
,
CLASS_ONLY
,
rewrite_args
,
argspec
,
arg1
,
arg2
,
arg3
,
args
,
keyword_names
);
}
else
{
rtn
=
callattrInternal
(
obj
,
call_str
,
CLASS_ONLY
,
NULL
,
argspec
,
arg1
,
arg2
,
arg3
,
args
,
keyword_names
);
}
}
catch
(
ExcInfo
e
)
{
if
(
S
==
CAPI
)
{
setCAPIException
(
e
);
return
NULL
;
}
else
throw
e
;
}
if
(
!
rtn
)
{
if
(
S
==
CAPI
)
{
PyErr_Format
(
TypeError
,
"'%s' object is not callable"
,
getTypeName
(
obj
));
return
NULL
;
}
else
raiseExcHelper
(
TypeError
,
"'%s' object is not callable"
,
getTypeName
(
obj
));
}
if
(
!
rtn
)
raiseExcHelper
(
TypeError
,
"'%s' object is not callable"
,
getTypeName
(
obj
));
return
rtn
;
}
...
...
@@ -3863,18 +3950,19 @@ Box* runtimeCallInternal(Box* obj, CallRewriteArgs* rewrite_args, ArgPassSpec ar
if
(
obj
->
cls
==
function_cls
||
obj
->
cls
==
builtin_function_or_method_cls
)
{
BoxedFunctionBase
*
f
=
static_cast
<
BoxedFunctionBase
*>
(
obj
);
// Some functions are sufficiently important that we want them to be able to patchpoint themselves;
// they can do this by setting the "internal_callable" field:
CLFunction
::
InternalCallable
callable
=
f
->
f
->
internal_callable
;
if
(
rewrite_args
&&
!
rewrite_args
->
func_guarded
)
{
rewrite_args
->
obj
->
addGuard
((
intptr_t
)
f
);
rewrite_args
->
func_guarded
=
true
;
rewrite_args
->
rewriter
->
addDependenceOn
(
f
->
dependent_ics
);
}
// Some functions are sufficiently important that we want them to be able to patchpoint themselves;
// they can do this by setting the "internal_callable" field:
auto
callable
=
f
->
f
->
internal_callable
.
get
<
S
>
();
if
(
callable
==
NULL
)
{
callable
=
callFunc
;
callable
=
callFunc
<
S
>
;
}
Box
*
res
=
callable
(
f
,
rewrite_args
,
argspec
,
arg1
,
arg2
,
arg3
,
args
,
keyword_names
);
return
res
;
}
else
if
(
obj
->
cls
==
instancemethod_cls
)
{
...
...
@@ -3902,7 +3990,7 @@ Box* runtimeCallInternal(Box* obj, CallRewriteArgs* rewrite_args, ArgPassSpec ar
if
(
rewrite_args
)
{
rewrite_args
->
obj
=
r_im_func
;
}
Box
*
res
=
runtimeCallInternal
(
f
,
rewrite_args
,
argspec
,
arg1
,
arg2
,
arg3
,
args
,
keyword_names
);
Box
*
res
=
runtimeCallInternal
<
S
>
(
f
,
rewrite_args
,
argspec
,
arg1
,
arg2
,
arg3
,
args
,
keyword_names
);
return
res
;
}
...
...
@@ -3919,11 +4007,16 @@ Box* runtimeCallInternal(Box* obj, CallRewriteArgs* rewrite_args, ArgPassSpec ar
ArgPassSpec
new_argspec
=
bindObjIntoArgs
(
im
->
obj
,
r_bind_obj
,
rewrite_args
,
argspec
,
arg1
,
arg2
,
arg3
,
args
,
new_args
);
return
runtimeCallInternal
(
im
->
func
,
rewrite_args
,
new_argspec
,
arg1
,
arg2
,
arg3
,
new_args
,
keyword_names
);
return
runtimeCallInternal
<
S
>
(
im
->
func
,
rewrite_args
,
new_argspec
,
arg1
,
arg2
,
arg3
,
new_args
,
keyword_names
);
}
assert
(
0
);
abort
();
}
// Force instantiation:
template
Box
*
runtimeCallInternal
<
CAPI
>(
Box
*
,
CallRewriteArgs
*
,
ArgPassSpec
,
Box
*
,
Box
*
,
Box
*
,
Box
**
,
const
std
::
vector
<
BoxedString
*>*
);
template
Box
*
runtimeCallInternal
<
CXX
>(
Box
*
,
CallRewriteArgs
*
,
ArgPassSpec
,
Box
*
,
Box
*
,
Box
*
,
Box
**
,
const
std
::
vector
<
BoxedString
*>*
);
extern
"C"
Box
*
runtimeCall
(
Box
*
obj
,
ArgPassSpec
argspec
,
Box
*
arg1
,
Box
*
arg2
,
Box
*
arg3
,
Box
**
args
,
const
std
::
vector
<
BoxedString
*>*
keyword_names
)
{
...
...
@@ -3979,7 +4072,7 @@ extern "C" Box* runtimeCall(Box* obj, ArgPassSpec argspec, Box* arg1, Box* arg2,
rewrite_args
.
arg3
=
rewriter
->
getArg
(
4
);
if
(
npassed_args
>=
4
)
rewrite_args
.
args
=
rewriter
->
getArg
(
5
);
rtn
=
runtimeCallInternal
(
obj
,
&
rewrite_args
,
argspec
,
arg1
,
arg2
,
arg3
,
args
,
keyword_names
);
rtn
=
runtimeCallInternal
<
CXX
>
(
obj
,
&
rewrite_args
,
argspec
,
arg1
,
arg2
,
arg3
,
args
,
keyword_names
);
if
(
!
rewrite_args
.
out_success
)
{
rewriter
.
reset
(
NULL
);
...
...
@@ -3987,7 +4080,7 @@ extern "C" Box* runtimeCall(Box* obj, ArgPassSpec argspec, Box* arg1, Box* arg2,
rewriter
->
commitReturning
(
rewrite_args
.
out_rtn
);
}
}
else
{
rtn
=
runtimeCallInternal
(
obj
,
NULL
,
argspec
,
arg1
,
arg2
,
arg3
,
args
,
keyword_names
);
rtn
=
runtimeCallInternal
<
CXX
>
(
obj
,
NULL
,
argspec
,
arg1
,
arg2
,
arg3
,
args
,
keyword_names
);
}
assert
(
rtn
);
...
...
@@ -4526,7 +4619,7 @@ extern "C" Box* unaryop(Box* operand, int op_type) {
// TODO: this code looks very old and like it should be a callattr instead?
Box
*
attr_func
=
getclsattrInternal
(
operand
,
op_name
,
NULL
);
RELEASE_ASSERT
(
attr_func
,
"%s.%s"
,
getTypeName
(
operand
),
op_name
->
c_str
());
Box
*
rtn
=
runtimeCallInternal
(
attr_func
,
NULL
,
ArgPassSpec
(
0
),
NULL
,
NULL
,
NULL
,
NULL
,
NULL
);
Box
*
rtn
=
runtimeCallInternal
<
CXX
>
(
attr_func
,
NULL
,
ArgPassSpec
(
0
),
NULL
,
NULL
,
NULL
,
NULL
,
NULL
);
return
rtn
;
}
...
...
@@ -4893,7 +4986,7 @@ extern "C" void delattrGeneric(Box* obj, BoxedString* attr, DelattrRewriteArgs*
Box
*
delAttr
=
typeLookup
(
static_cast
<
BoxedClass
*>
(
clsAttr
->
cls
),
delete_str
,
NULL
);
if
(
delAttr
!=
NULL
)
{
Box
*
rtn
=
runtimeCallInternal
(
delAttr
,
NULL
,
ArgPassSpec
(
2
),
clsAttr
,
obj
,
NULL
,
NULL
,
NULL
);
Box
*
rtn
=
runtimeCallInternal
<
CXX
>
(
delAttr
,
NULL
,
ArgPassSpec
(
2
),
clsAttr
,
obj
,
NULL
,
NULL
,
NULL
);
return
;
}
}
...
...
@@ -4937,7 +5030,7 @@ extern "C" void delattrInternal(Box* obj, BoxedString* attr, DelattrRewriteArgs*
static
BoxedString
*
delattr_str
=
internStringImmortal
(
"__delattr__"
);
Box
*
delAttr
=
typeLookup
(
obj
->
cls
,
delattr_str
,
NULL
);
if
(
delAttr
!=
NULL
)
{
Box
*
rtn
=
runtimeCallInternal
(
delAttr
,
NULL
,
ArgPassSpec
(
2
),
obj
,
attr
,
NULL
,
NULL
,
NULL
);
Box
*
rtn
=
runtimeCallInternal
<
CXX
>
(
delAttr
,
NULL
,
ArgPassSpec
(
2
),
obj
,
attr
,
NULL
,
NULL
,
NULL
);
return
;
}
...
...
@@ -5526,7 +5619,7 @@ extern "C" Box* importStar(Box* _from_module, Box* to_globals) {
while
(
true
)
{
Box
*
attr_name
;
try
{
attr_name
=
runtimeCallInternal2
(
all_getitem
,
NULL
,
ArgPassSpec
(
2
),
all
,
boxInt
(
idx
));
attr_name
=
runtimeCallInternal2
<
CXX
>
(
all_getitem
,
NULL
,
ArgPassSpec
(
2
),
all
,
boxInt
(
idx
));
}
catch
(
ExcInfo
e
)
{
if
(
e
.
matches
(
IndexError
))
break
;
...
...
src/runtime/objmodel.h
View file @
b8b126e3
...
...
@@ -111,8 +111,10 @@ struct BinopRewriteArgs;
extern
"C"
Box
*
binopInternal
(
Box
*
lhs
,
Box
*
rhs
,
int
op_type
,
bool
inplace
,
BinopRewriteArgs
*
rewrite_args
);
struct
CallRewriteArgs
;
template
<
ExceptionStyle
::
ExceptionStyle
S
>
Box
*
runtimeCallInternal
(
Box
*
obj
,
CallRewriteArgs
*
rewrite_args
,
ArgPassSpec
argspec
,
Box
*
arg1
,
Box
*
arg2
,
Box
*
arg3
,
Box
**
args
,
const
std
::
vector
<
BoxedString
*>*
keyword_names
);
Box
**
args
,
const
std
::
vector
<
BoxedString
*>*
keyword_names
)
noexcept
(
S
==
ExceptionStyle
::
CAPI
);
struct
GetitemRewriteArgs
;
template
<
ExceptionStyle
::
ExceptionStyle
S
>
...
...
@@ -124,8 +126,10 @@ BoxedInt* lenInternal(Box* obj, LenRewriteArgs* rewrite_args) noexcept(S == Exce
Box
*
lenCallInternal
(
BoxedFunctionBase
*
f
,
CallRewriteArgs
*
rewrite_args
,
ArgPassSpec
argspec
,
Box
*
arg1
,
Box
*
arg2
,
Box
*
arg3
,
Box
**
args
,
const
std
::
vector
<
BoxedString
*>*
keyword_names
);
template
<
ExceptionStyle
::
ExceptionStyle
S
>
Box
*
callFunc
(
BoxedFunctionBase
*
func
,
CallRewriteArgs
*
rewrite_args
,
ArgPassSpec
argspec
,
Box
*
arg1
,
Box
*
arg2
,
Box
*
arg3
,
Box
**
args
,
const
std
::
vector
<
BoxedString
*>*
keyword_names
);
Box
*
arg3
,
Box
**
args
,
const
std
::
vector
<
BoxedString
*>*
keyword_names
)
noexcept
(
S
==
ExceptionStyle
::
CAPI
);
enum
LookupScope
{
CLASS_ONLY
=
1
,
...
...
@@ -169,8 +173,10 @@ bool isUserDefined(BoxedClass* cls);
Box
*
processDescriptor
(
Box
*
obj
,
Box
*
inst
,
Box
*
owner
);
Box
*
processDescriptorOrNull
(
Box
*
obj
,
Box
*
inst
,
Box
*
owner
);
template
<
ExceptionStyle
::
ExceptionStyle
S
>
Box
*
callCLFunc
(
CLFunction
*
f
,
CallRewriteArgs
*
rewrite_args
,
int
num_output_args
,
BoxedClosure
*
closure
,
BoxedGenerator
*
generator
,
Box
*
globals
,
Box
*
oarg1
,
Box
*
oarg2
,
Box
*
oarg3
,
Box
**
oargs
);
BoxedGenerator
*
generator
,
Box
*
globals
,
Box
*
oarg1
,
Box
*
oarg2
,
Box
*
oarg3
,
Box
**
oargs
)
noexcept
(
S
==
ExceptionStyle
::
CAPI
);
static
const
char
*
objectNewParameterTypeErrorMsg
()
{
if
(
PYTHON_VERSION_HEX
>=
version_hex
(
2
,
7
,
4
))
{
...
...
src/runtime/types.cpp
View file @
b8b126e3
...
...
@@ -638,7 +638,7 @@ static Box* typeCallInternal(BoxedFunctionBase* f, CallRewriteArgs* rewrite_args
if
(
argspec
.
has_starargs
||
argspec
.
num_args
==
0
)
{
// Get callFunc to expand the arguments.
// TODO: update this to use rearrangeArguments instead.
return
callFunc
(
f
,
rewrite_args
,
argspec
,
arg1
,
arg2
,
arg3
,
args
,
keyword_names
);
return
callFunc
<
ExceptionStyle
::
CXX
>
(
f
,
rewrite_args
,
argspec
,
arg1
,
arg2
,
arg3
,
args
,
keyword_names
);
}
return
typeCallInner
(
rewrite_args
,
argspec
,
arg1
,
arg2
,
arg3
,
args
,
keyword_names
);
...
...
@@ -996,7 +996,8 @@ static Box* typeCallInner(CallRewriteArgs* rewrite_args, ArgPassSpec argspec, Bo
if
(
new_npassed_args
>=
4
)
srewrite_args
.
args
=
rewrite_args
->
args
;
made
=
runtimeCallInternal
(
new_attr
,
&
srewrite_args
,
new_argspec
,
cls
,
arg2
,
arg3
,
args
,
keyword_names
);
made
=
runtimeCallInternal
<
ExceptionStyle
::
CXX
>
(
new_attr
,
&
srewrite_args
,
new_argspec
,
cls
,
arg2
,
arg3
,
args
,
keyword_names
);
if
(
!
srewrite_args
.
out_success
)
{
rewrite_args
=
NULL
;
...
...
@@ -1013,7 +1014,8 @@ static Box* typeCallInner(CallRewriteArgs* rewrite_args, ArgPassSpec argspec, Bo
if
(
cls
->
tp_new
==
object_cls
->
tp_new
&&
cls
->
tp_init
!=
object_cls
->
tp_init
)
made
=
objectNewNoArgs
(
cls
);
else
made
=
runtimeCallInternal
(
new_attr
,
NULL
,
new_argspec
,
cls
,
arg2
,
arg3
,
args
,
keyword_names
);
made
=
runtimeCallInternal
<
ExceptionStyle
::
CXX
>
(
new_attr
,
NULL
,
new_argspec
,
cls
,
arg2
,
arg3
,
args
,
keyword_names
);
}
assert
(
made
);
...
...
@@ -1063,7 +1065,8 @@ static Box* typeCallInner(CallRewriteArgs* rewrite_args, ArgPassSpec argspec, Bo
// initrtn = callattrInternal(cls, _init_str, INST_ONLY, &srewrite_args, argspec, made, arg2, arg3, args,
// keyword_names);
initrtn
=
runtimeCallInternal
(
init_attr
,
&
srewrite_args
,
argspec
,
made
,
arg2
,
arg3
,
args
,
keyword_names
);
initrtn
=
runtimeCallInternal
<
ExceptionStyle
::
CXX
>
(
init_attr
,
&
srewrite_args
,
argspec
,
made
,
arg2
,
arg3
,
args
,
keyword_names
);
if
(
!
srewrite_args
.
out_success
)
{
rewrite_args
=
NULL
;
...
...
@@ -1082,10 +1085,11 @@ static Box* typeCallInner(CallRewriteArgs* rewrite_args, ArgPassSpec argspec, Bo
// If we weren't passed the args array, it's not safe to index into it
if
(
passed
<=
2
)
initrtn
=
runtimeCallInternal
(
init_attr
,
NULL
,
init_argspec
,
arg2
,
arg3
,
NULL
,
NULL
,
keyword_names
);
initrtn
=
runtimeCallInternal
<
ExceptionStyle
::
CXX
>
(
init_attr
,
NULL
,
init_argspec
,
arg2
,
arg3
,
NULL
,
NULL
,
keyword_names
);
else
initrtn
=
runtimeCallInternal
(
init_attr
,
NULL
,
init_argspec
,
arg2
,
arg3
,
args
[
0
],
&
args
[
1
],
keyword_names
);
initrtn
=
runtimeCallInternal
<
ExceptionStyle
::
CXX
>
(
init_attr
,
NULL
,
init_argspec
,
arg2
,
arg3
,
args
[
0
],
&
args
[
1
],
keyword_names
);
}
assertInitNone
(
initrtn
);
}
else
{
...
...
@@ -3414,7 +3418,7 @@ void setupRuntime() {
// Punting on that until needed; hopefully by then we will have better Pyston slots support.
auto
typeCallObj
=
boxRTFunction
((
void
*
)
typeCall
,
UNKNOWN
,
1
,
0
,
true
,
true
);
typeCallObj
->
internal_callable
=
&
typeCallInternal
;
typeCallObj
->
internal_callable
.
cxx_ptr
=
&
typeCallInternal
;
type_cls
->
giveAttr
(
"__name__"
,
new
(
pyston_getset_cls
)
BoxedGetsetDescriptor
(
typeName
,
typeSetName
,
NULL
));
type_cls
->
giveAttr
(
"__bases__"
,
new
(
pyston_getset_cls
)
BoxedGetsetDescriptor
(
typeBases
,
typeSetBases
,
NULL
));
...
...
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