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