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
96febb05
Commit
96febb05
authored
Aug 07, 2015
by
Kevin Modzelewski
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #811 from kmod/exceptions4
more capi exceptions
parents
232e05c4
26dabd18
Changes
27
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
27 changed files
with
732 additions
and
322 deletions
+732
-322
Makefile
Makefile
+6
-0
from_cpython/Include/object.h
from_cpython/Include/object.h
+2
-1
from_cpython/setup.py
from_cpython/setup.py
+6
-0
src/capi/typeobject.cpp
src/capi/typeobject.cpp
+24
-11
src/capi/types.h
src/capi/types.h
+2
-1
src/codegen/ast_interpreter.cpp
src/codegen/ast_interpreter.cpp
+2
-0
src/codegen/compvars.cpp
src/codegen/compvars.cpp
+40
-17
src/codegen/irgen/irgenerator.cpp
src/codegen/irgen/irgenerator.cpp
+29
-14
src/codegen/runtime_hooks.cpp
src/codegen/runtime_hooks.cpp
+49
-18
src/codegen/runtime_hooks.h
src/codegen/runtime_hooks.h
+2
-2
src/codegen/unwinding.cpp
src/codegen/unwinding.cpp
+2
-0
src/core/ast.h
src/core/ast.h
+2
-0
src/runtime/builtin_modules/builtins.cpp
src/runtime/builtin_modules/builtins.cpp
+19
-7
src/runtime/capi.cpp
src/runtime/capi.cpp
+16
-3
src/runtime/descr.cpp
src/runtime/descr.cpp
+30
-5
src/runtime/float.cpp
src/runtime/float.cpp
+58
-19
src/runtime/inline/link_forcer.cpp
src/runtime/inline/link_forcer.cpp
+2
-0
src/runtime/int.cpp
src/runtime/int.cpp
+62
-24
src/runtime/objmodel.cpp
src/runtime/objmodel.cpp
+215
-136
src/runtime/objmodel.h
src/runtime/objmodel.h
+7
-3
src/runtime/tuple.cpp
src/runtime/tuple.cpp
+1
-1
src/runtime/types.cpp
src/runtime/types.cpp
+125
-44
src/runtime/types.h
src/runtime/types.h
+6
-6
src/runtime/util.cpp
src/runtime/util.cpp
+2
-2
src/runtime/util.h
src/runtime/util.h
+2
-2
test/test_extension/setup.py
test/test_extension/setup.py
+20
-5
test/tests/varargs_ics.py
test/tests/varargs_ics.py
+1
-1
No files found.
Makefile
View file @
96febb05
...
@@ -1260,6 +1260,12 @@ $(FROM_CPYTHON_SRCS:.c=.prof.o): %.prof.o: %.c $(BUILD_SYSTEM_DEPS)
...
@@ -1260,6 +1260,12 @@ $(FROM_CPYTHON_SRCS:.c=.prof.o): %.prof.o: %.c $(BUILD_SYSTEM_DEPS)
$(ECHO)
Compiling C file to
$@
$(ECHO)
Compiling C file to
$@
$(VERB)
$(CC_PROFILE)
$(EXT_CFLAGS_PROFILE)
-c
$<
-o
$@
-g
-MMD
-MP
-MF
$(
patsubst
%.o,%.d,
$@
)
$(VERB)
$(CC_PROFILE)
$(EXT_CFLAGS_PROFILE)
-c
$<
-o
$@
-g
-MMD
-MP
-MF
$(
patsubst
%.o,%.d,
$@
)
.PHONY
:
update_section_ordering
update_section_ordering
:
pyston_release
perf record
-o
perf_section_ordering.data
--
./pyston_release
-q
minibenchmarks/combined.py
$(MAKE)
pyston_pgo
python tools/generate_section_ordering_from_pgo_build.py pyston_pgo perf_section_ordering.data
>
section_ordering.txt
rm
perf_section_ordering.data
...
...
from_cpython/Include/object.h
View file @
96febb05
...
@@ -460,7 +460,8 @@ struct _typeobject {
...
@@ -460,7 +460,8 @@ struct _typeobject {
bool
_flags
[
7
];
bool
_flags
[
7
];
void
*
_tpp_descr_get
;
void
*
_tpp_descr_get
;
void
*
_tpp_hasnext
;
void
*
_tpp_hasnext
;
void
*
_tpp_call
;
void
*
_tpp_call_capi
;
void
*
_tpp_call_cxx
;
};
};
/* The *real* layout of a type object when allocated on the heap */
/* The *real* layout of a type object when allocated on the heap */
...
...
from_cpython/setup.py
View file @
96febb05
# CPython has a 2kloc version of this file
# CPython has a 2kloc version of this file
from
distutils.core
import
setup
,
Extension
from
distutils.core
import
setup
,
Extension
import
glob
import
os
import
os
import
sysconfig
import
sysconfig
...
@@ -132,5 +133,10 @@ ext_modules = [future_builtins_ext(),
...
@@ -132,5 +133,10 @@ ext_modules = [future_builtins_ext(),
curses_ext
(),
curses_ext
(),
termios_ext
()]
termios_ext
()]
builtin_headers
=
map
(
relpath
,
glob
.
glob
(
"Include/*.h"
))
for
m
in
ext_modules
:
m
.
depends
+=
builtin_headers
setup
(
name
=
"Pyston"
,
version
=
"1.0"
,
description
=
"Pyston shared modules"
,
ext_modules
=
ext_modules
)
setup
(
name
=
"Pyston"
,
version
=
"1.0"
,
description
=
"Pyston shared modules"
,
ext_modules
=
ext_modules
)
src/capi/typeobject.cpp
View file @
96febb05
...
@@ -1068,8 +1068,8 @@ Box* slotTpGetattrHookInternal(Box* self, BoxedString* name, GetattrRewriteArgs*
...
@@ -1068,8 +1068,8 @@ Box* slotTpGetattrHookInternal(Box* self, BoxedString* name, GetattrRewriteArgs*
assert
(
PyString_CHECK_INTERNED
(
name
)
==
SSTATE_INTERNED_IMMORTAL
);
assert
(
PyString_CHECK_INTERNED
(
name
)
==
SSTATE_INTERNED_IMMORTAL
);
crewrite_args
.
arg1
=
rewrite_args
->
rewriter
->
loadConst
((
intptr_t
)
name
,
Location
::
forArg
(
1
));
crewrite_args
.
arg1
=
rewrite_args
->
rewriter
->
loadConst
((
intptr_t
)
name
,
Location
::
forArg
(
1
));
res
=
callattrInternal
(
self
,
_getattr_str
,
LookupScope
::
CLASS_ONLY
,
&
crewrite_args
,
ArgPassSpec
(
1
),
name
,
NULL
,
res
=
callattrInternal
<
CXX
>
(
self
,
_getattr_str
,
LookupScope
::
CLASS_ONLY
,
&
crewrite_args
,
ArgPassSpec
(
1
),
name
,
NULL
,
NULL
,
NULL
);
NULL
,
NULL
,
NULL
,
NULL
);
assert
(
res
);
assert
(
res
);
if
(
!
crewrite_args
.
out_success
)
if
(
!
crewrite_args
.
out_success
)
...
@@ -1082,8 +1082,8 @@ Box* slotTpGetattrHookInternal(Box* self, BoxedString* name, GetattrRewriteArgs*
...
@@ -1082,8 +1082,8 @@ Box* slotTpGetattrHookInternal(Box* self, BoxedString* name, GetattrRewriteArgs*
// the rewrite_args and non-rewrite_args case the same.
// the rewrite_args and non-rewrite_args case the same.
// Actually, we might have gotten to the point that doing a runtimeCall on an instancemethod is as
// Actually, we might have gotten to the point that doing a runtimeCall on an instancemethod is as
// fast as a callattr, but that hasn't typically been the case.
// fast as a callattr, but that hasn't typically been the case.
res
=
callattrInternal
(
self
,
_getattr_str
,
LookupScope
::
CLASS_ONLY
,
NULL
,
ArgPassSpec
(
1
),
name
,
NULL
,
NULL
,
res
=
callattrInternal
<
CXX
>
(
self
,
_getattr_str
,
LookupScope
::
CLASS_ONLY
,
NULL
,
ArgPassSpec
(
1
),
name
,
NULL
,
NULL
,
NULL
,
NULL
);
NULL
,
NULL
);
assert
(
res
);
assert
(
res
);
}
}
...
@@ -3184,8 +3184,10 @@ extern "C" void PyType_Modified(PyTypeObject* type) noexcept {
...
@@ -3184,8 +3184,10 @@ extern "C" void PyType_Modified(PyTypeObject* type) noexcept {
// We don't cache anything yet that would need to be invalidated:
// We don't cache anything yet that would need to be invalidated:
}
}
template
<
ExceptionStyle
S
>
static
Box
*
tppProxyToTpCall
(
Box
*
self
,
CallRewriteArgs
*
rewrite_args
,
ArgPassSpec
argspec
,
Box
*
arg1
,
Box
*
arg2
,
static
Box
*
tppProxyToTpCall
(
Box
*
self
,
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
)
{
ParamReceiveSpec
paramspec
(
0
,
0
,
true
,
true
);
ParamReceiveSpec
paramspec
(
0
,
0
,
true
,
true
);
if
(
!
argspec
.
has_kwargs
&&
argspec
.
num_keywords
==
0
)
{
if
(
!
argspec
.
has_kwargs
&&
argspec
.
num_keywords
==
0
)
{
paramspec
.
takes_kwargs
=
false
;
paramspec
.
takes_kwargs
=
false
;
...
@@ -3193,8 +3195,16 @@ static Box* tppProxyToTpCall(Box* self, CallRewriteArgs* rewrite_args, ArgPassSp
...
@@ -3193,8 +3195,16 @@ static Box* tppProxyToTpCall(Box* self, CallRewriteArgs* rewrite_args, ArgPassSp
bool
rewrite_success
=
false
;
bool
rewrite_success
=
false
;
Box
*
oarg1
,
*
oarg2
=
NULL
,
*
oarg3
,
**
oargs
=
NULL
;
Box
*
oarg1
,
*
oarg2
=
NULL
,
*
oarg3
,
**
oargs
=
NULL
;
rearrangeArguments
(
paramspec
,
NULL
,
""
,
NULL
,
rewrite_args
,
rewrite_success
,
argspec
,
arg1
,
arg2
,
arg3
,
args
,
try
{
keyword_names
,
oarg1
,
oarg2
,
oarg3
,
oargs
);
rearrangeArguments
(
paramspec
,
NULL
,
""
,
NULL
,
rewrite_args
,
rewrite_success
,
argspec
,
arg1
,
arg2
,
arg3
,
args
,
keyword_names
,
oarg1
,
oarg2
,
oarg3
,
oargs
);
}
catch
(
ExcInfo
e
)
{
if
(
S
==
CAPI
)
{
setCAPIException
(
e
);
return
NULL
;
}
else
throw
e
;
}
if
(
!
rewrite_success
)
if
(
!
rewrite_success
)
rewrite_args
=
NULL
;
rewrite_args
=
NULL
;
...
@@ -3213,12 +3223,13 @@ static Box* tppProxyToTpCall(Box* self, CallRewriteArgs* rewrite_args, ArgPassSp
...
@@ -3213,12 +3223,13 @@ static Box* tppProxyToTpCall(Box* self, CallRewriteArgs* rewrite_args, ArgPassSp
rewrite_args
->
out_rtn
=
rewrite_args
->
rewriter
->
call
(
true
,
(
void
*
)
self
->
cls
->
tp_call
,
rewrite_args
->
obj
,
rewrite_args
->
out_rtn
=
rewrite_args
->
rewriter
->
call
(
true
,
(
void
*
)
self
->
cls
->
tp_call
,
rewrite_args
->
obj
,
rewrite_args
->
arg1
,
rewrite_args
->
arg2
);
rewrite_args
->
arg1
,
rewrite_args
->
arg2
);
rewrite_args
->
rewriter
->
call
(
true
,
(
void
*
)
checkAndThrowCAPIException
);
if
(
S
==
CXX
)
rewrite_args
->
rewriter
->
call
(
true
,
(
void
*
)
checkAndThrowCAPIException
);
rewrite_args
->
out_success
=
true
;
rewrite_args
->
out_success
=
true
;
}
}
Box
*
r
=
self
->
cls
->
tp_call
(
self
,
oarg1
,
oarg2
);
Box
*
r
=
self
->
cls
->
tp_call
(
self
,
oarg1
,
oarg2
);
if
(
!
r
)
if
(
!
r
&&
S
==
CXX
)
throwCAPIException
();
throwCAPIException
();
return
r
;
return
r
;
}
}
...
@@ -3267,8 +3278,10 @@ extern "C" int PyType_Ready(PyTypeObject* cls) noexcept {
...
@@ -3267,8 +3278,10 @@ extern "C" int PyType_Ready(PyTypeObject* cls) noexcept {
assert
(
cls
->
tp_name
);
assert
(
cls
->
tp_name
);
if
(
cls
->
tp_call
)
if
(
cls
->
tp_call
)
{
cls
->
tpp_call
=
tppProxyToTpCall
;
cls
->
tpp_call
.
capi_val
=
tppProxyToTpCall
<
CAPI
>
;
cls
->
tpp_call
.
cxx_val
=
tppProxyToTpCall
<
CXX
>
;
}
try
{
try
{
add_operators
(
cls
);
add_operators
(
cls
);
...
...
src/capi/types.h
View file @
96febb05
...
@@ -43,8 +43,9 @@ public:
...
@@ -43,8 +43,9 @@ public:
}
}
static
Box
*
__call__
(
BoxedCApiFunction
*
self
,
BoxedTuple
*
varargs
,
BoxedDict
*
kwargs
);
static
Box
*
__call__
(
BoxedCApiFunction
*
self
,
BoxedTuple
*
varargs
,
BoxedDict
*
kwargs
);
template
<
ExceptionStyle
S
>
static
Box
*
tppCall
(
Box
*
_self
,
CallRewriteArgs
*
rewrite_args
,
ArgPassSpec
argspec
,
Box
*
arg1
,
Box
*
arg2
,
Box
*
arg3
,
static
Box
*
tppCall
(
Box
*
_self
,
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
)
;
static
Box
*
getname
(
Box
*
b
,
void
*
)
{
static
Box
*
getname
(
Box
*
b
,
void
*
)
{
RELEASE_ASSERT
(
b
->
cls
==
capifunc_cls
,
""
);
RELEASE_ASSERT
(
b
->
cls
==
capifunc_cls
,
""
);
...
...
src/codegen/ast_interpreter.cpp
View file @
96febb05
...
@@ -332,6 +332,7 @@ Box* ASTInterpreter::execJITedBlock(CFGBlock* b) {
...
@@ -332,6 +332,7 @@ Box* ASTInterpreter::execJITedBlock(CFGBlock* b) {
throw
e
;
throw
e
;
auto
source
=
getCL
()
->
source
.
get
();
auto
source
=
getCL
()
->
source
.
get
();
stmt
->
cxx_exception_count
++
;
exceptionCaughtInInterpreter
(
LineInfo
(
stmt
->
lineno
,
stmt
->
col_offset
,
source
->
fn
,
source
->
getName
()),
&
e
);
exceptionCaughtInInterpreter
(
LineInfo
(
stmt
->
lineno
,
stmt
->
col_offset
,
source
->
fn
,
source
->
getName
()),
&
e
);
next_block
=
((
AST_Invoke
*
)
stmt
)
->
exc_dest
;
next_block
=
((
AST_Invoke
*
)
stmt
)
->
exc_dest
;
...
@@ -764,6 +765,7 @@ Value ASTInterpreter::visit_invoke(AST_Invoke* node) {
...
@@ -764,6 +765,7 @@ Value ASTInterpreter::visit_invoke(AST_Invoke* node) {
abortJITing
();
abortJITing
();
auto
source
=
getCL
()
->
source
.
get
();
auto
source
=
getCL
()
->
source
.
get
();
node
->
cxx_exception_count
++
;
exceptionCaughtInInterpreter
(
LineInfo
(
node
->
lineno
,
node
->
col_offset
,
source
->
fn
,
source
->
getName
()),
&
e
);
exceptionCaughtInInterpreter
(
LineInfo
(
node
->
lineno
,
node
->
col_offset
,
source
->
fn
,
source
->
getName
()),
&
e
);
next_block
=
node
->
exc_dest
;
next_block
=
node
->
exc_dest
;
...
...
src/codegen/compvars.cpp
View file @
96febb05
...
@@ -613,7 +613,8 @@ static ConcreteCompilerVariable* _call(IREmitter& emitter, const OpInfo& info, l
...
@@ -613,7 +613,8 @@ static ConcreteCompilerVariable* _call(IREmitter& emitter, const OpInfo& info, l
// for (auto a : llvm_args)
// for (auto a : llvm_args)
// a->dump();
// a->dump();
bool
do_patchpoint
=
ENABLE_ICCALLSITES
&&
(
func_addr
==
runtimeCall
||
func_addr
==
pyston
::
callattr
);
bool
do_patchpoint
=
ENABLE_ICCALLSITES
&&
(
func_addr
==
runtimeCall
||
func_addr
==
runtimeCallCapi
||
func_addr
==
pyston
::
callattr
||
func_addr
==
callattrCapi
);
if
(
do_patchpoint
)
{
if
(
do_patchpoint
)
{
assert
(
func_addr
);
assert
(
func_addr
);
...
@@ -655,26 +656,32 @@ CompilerVariable* UnknownType::call(IREmitter& emitter, const OpInfo& info, Conc
...
@@ -655,26 +656,32 @@ CompilerVariable* UnknownType::call(IREmitter& emitter, const OpInfo& info, Conc
bool
pass_keywords
=
(
argspec
.
num_keywords
!=
0
);
bool
pass_keywords
=
(
argspec
.
num_keywords
!=
0
);
int
npassed_args
=
argspec
.
totalPassed
();
int
npassed_args
=
argspec
.
totalPassed
();
ExceptionStyle
exception_style
=
((
FORCE_LLVM_CAPI
&&
!
info
.
unw_info
.
cxx_exc_dest
)
||
info
.
unw_info
.
capi_exc_dest
)
?
ExceptionStyle
::
CAPI
:
ExceptionStyle
::
CXX
;
llvm
::
Value
*
func
;
llvm
::
Value
*
func
;
if
(
pass_keywords
)
if
(
pass_keywords
)
func
=
g
.
funcs
.
runtimeCall
;
func
=
g
.
funcs
.
runtimeCall
.
get
(
exception_style
)
;
else
if
(
npassed_args
==
0
)
else
if
(
npassed_args
==
0
)
func
=
g
.
funcs
.
runtimeCall0
;
func
=
g
.
funcs
.
runtimeCall0
.
get
(
exception_style
)
;
else
if
(
npassed_args
==
1
)
else
if
(
npassed_args
==
1
)
func
=
g
.
funcs
.
runtimeCall1
;
func
=
g
.
funcs
.
runtimeCall1
.
get
(
exception_style
)
;
else
if
(
npassed_args
==
2
)
else
if
(
npassed_args
==
2
)
func
=
g
.
funcs
.
runtimeCall2
;
func
=
g
.
funcs
.
runtimeCall2
.
get
(
exception_style
)
;
else
if
(
npassed_args
==
3
)
else
if
(
npassed_args
==
3
)
func
=
g
.
funcs
.
runtimeCall3
;
func
=
g
.
funcs
.
runtimeCall3
.
get
(
exception_style
)
;
else
else
func
=
g
.
funcs
.
runtimeCallN
;
func
=
g
.
funcs
.
runtimeCallN
.
get
(
exception_style
);
void
*
func_ptr
=
(
exception_style
==
ExceptionStyle
::
CXX
)
?
(
void
*
)
runtimeCall
:
(
void
*
)
runtimeCallCapi
;
std
::
vector
<
llvm
::
Value
*>
other_args
;
std
::
vector
<
llvm
::
Value
*>
other_args
;
other_args
.
push_back
(
var
->
getValue
());
other_args
.
push_back
(
var
->
getValue
());
llvm
::
Value
*
llvm_argspec
=
llvm
::
ConstantInt
::
get
(
g
.
i32
,
argspec
.
asInt
(),
false
);
llvm
::
Value
*
llvm_argspec
=
llvm
::
ConstantInt
::
get
(
g
.
i32
,
argspec
.
asInt
(),
false
);
other_args
.
push_back
(
llvm_argspec
);
other_args
.
push_back
(
llvm_argspec
);
return
_call
(
emitter
,
info
,
func
,
CXX
,
(
void
*
)
runtimeCall
,
other_args
,
argspec
,
args
,
keyword_names
,
UNKNOWN
);
return
_call
(
emitter
,
info
,
func
,
exception_style
,
func_ptr
,
other_args
,
argspec
,
args
,
keyword_names
,
UNKNOWN
);
}
}
CompilerVariable
*
UnknownType
::
callattr
(
IREmitter
&
emitter
,
const
OpInfo
&
info
,
ConcreteCompilerVariable
*
var
,
CompilerVariable
*
UnknownType
::
callattr
(
IREmitter
&
emitter
,
const
OpInfo
&
info
,
ConcreteCompilerVariable
*
var
,
...
@@ -684,25 +691,35 @@ CompilerVariable* UnknownType::callattr(IREmitter& emitter, const OpInfo& info,
...
@@ -684,25 +691,35 @@ CompilerVariable* UnknownType::callattr(IREmitter& emitter, const OpInfo& info,
bool
pass_keywords
=
(
flags
.
argspec
.
num_keywords
!=
0
);
bool
pass_keywords
=
(
flags
.
argspec
.
num_keywords
!=
0
);
int
npassed_args
=
flags
.
argspec
.
totalPassed
();
int
npassed_args
=
flags
.
argspec
.
totalPassed
();
ExceptionStyle
exception_style
=
((
FORCE_LLVM_CAPI
&&
!
info
.
unw_info
.
cxx_exc_dest
&&
!
flags
.
null_on_nonexistent
)
||
info
.
unw_info
.
capi_exc_dest
)
?
ExceptionStyle
::
CAPI
:
ExceptionStyle
::
CXX
;
if
(
exception_style
==
CAPI
)
assert
(
!
flags
.
null_on_nonexistent
);
// Will conflict with CAPI's null-on-exception
llvm
::
Value
*
func
;
llvm
::
Value
*
func
;
if
(
pass_keywords
)
if
(
pass_keywords
)
func
=
g
.
funcs
.
callattr
;
func
=
g
.
funcs
.
callattr
.
get
(
exception_style
)
;
else
if
(
npassed_args
==
0
)
else
if
(
npassed_args
==
0
)
func
=
g
.
funcs
.
callattr0
;
func
=
g
.
funcs
.
callattr0
.
get
(
exception_style
)
;
else
if
(
npassed_args
==
1
)
else
if
(
npassed_args
==
1
)
func
=
g
.
funcs
.
callattr1
;
func
=
g
.
funcs
.
callattr1
.
get
(
exception_style
)
;
else
if
(
npassed_args
==
2
)
else
if
(
npassed_args
==
2
)
func
=
g
.
funcs
.
callattr2
;
func
=
g
.
funcs
.
callattr2
.
get
(
exception_style
)
;
else
if
(
npassed_args
==
3
)
else
if
(
npassed_args
==
3
)
func
=
g
.
funcs
.
callattr3
;
func
=
g
.
funcs
.
callattr3
.
get
(
exception_style
)
;
else
else
func
=
g
.
funcs
.
callattrN
;
func
=
g
.
funcs
.
callattrN
.
get
(
exception_style
);
void
*
func_ptr
=
(
exception_style
==
ExceptionStyle
::
CXX
)
?
(
void
*
)
pyston
::
callattr
:
(
void
*
)
callattrCapi
;
std
::
vector
<
llvm
::
Value
*>
other_args
;
std
::
vector
<
llvm
::
Value
*>
other_args
;
other_args
.
push_back
(
var
->
getValue
());
other_args
.
push_back
(
var
->
getValue
());
other_args
.
push_back
(
embedRelocatablePtr
(
attr
,
g
.
llvm_boxedstring_type_ptr
));
other_args
.
push_back
(
embedRelocatablePtr
(
attr
,
g
.
llvm_boxedstring_type_ptr
));
other_args
.
push_back
(
getConstantInt
(
flags
.
asInt
(),
g
.
i64
));
other_args
.
push_back
(
getConstantInt
(
flags
.
asInt
(),
g
.
i64
));
return
_call
(
emitter
,
info
,
func
,
CXX
,
(
void
*
)
pyston
::
callat
tr
,
other_args
,
flags
.
argspec
,
args
,
keyword_names
,
return
_call
(
emitter
,
info
,
func
,
exception_style
,
func_p
tr
,
other_args
,
flags
.
argspec
,
args
,
keyword_names
,
UNKNOWN
);
UNKNOWN
);
}
}
...
@@ -1700,8 +1717,14 @@ public:
...
@@ -1700,8 +1717,14 @@ public:
CompilerVariable
*
callattr
(
IREmitter
&
emitter
,
const
OpInfo
&
info
,
ConcreteCompilerVariable
*
var
,
BoxedString
*
attr
,
CompilerVariable
*
callattr
(
IREmitter
&
emitter
,
const
OpInfo
&
info
,
ConcreteCompilerVariable
*
var
,
BoxedString
*
attr
,
CallattrFlags
flags
,
const
std
::
vector
<
CompilerVariable
*>&
args
,
CallattrFlags
flags
,
const
std
::
vector
<
CompilerVariable
*>&
args
,
const
std
::
vector
<
BoxedString
*>*
keyword_names
)
override
{
const
std
::
vector
<
BoxedString
*>*
keyword_names
)
override
{
ConcreteCompilerVariable
*
called_constant
ExceptionStyle
exception_style
=
CXX
;
=
tryCallattrConstant
(
emitter
,
info
,
var
,
attr
,
flags
.
cls_only
,
flags
.
argspec
,
args
,
keyword_names
);
// Not safe to force-capi here since most of the functions won't have capi variants:
if
(
/*FORCE_LLVM_CAPI ||*/
info
.
unw_info
.
capi_exc_dest
)
exception_style
=
CAPI
;
ConcreteCompilerVariable
*
called_constant
=
tryCallattrConstant
(
emitter
,
info
,
var
,
attr
,
flags
.
cls_only
,
flags
.
argspec
,
args
,
keyword_names
,
NULL
,
exception_style
);
if
(
called_constant
)
if
(
called_constant
)
return
called_constant
;
return
called_constant
;
...
...
src/codegen/irgen/irgenerator.cpp
View file @
96febb05
...
@@ -107,13 +107,23 @@ ExceptionStyle IRGenState::getLandingpadStyle(AST_Invoke* invoke) {
...
@@ -107,13 +107,23 @@ ExceptionStyle IRGenState::getLandingpadStyle(AST_Invoke* invoke) {
r
=
CXX
;
// default
r
=
CXX
;
// default
assert
(
invoke
->
stmt
->
cxx_exception_count
==
0
);
// could be ok but would be unexpected
// First, check if we think it makes sense:
bool
should
=
(
invoke
->
cxx_exception_count
>=
10
||
invoke
->
stmt
->
type
==
AST_TYPE
::
Raise
);
if
(
!
should
)
return
r
;
// Second, check if we are able to do it:
// (not all code paths support capi exceptions yet)
if
(
invoke
->
stmt
->
type
==
AST_TYPE
::
Raise
)
{
if
(
invoke
->
stmt
->
type
==
AST_TYPE
::
Raise
)
{
AST_Raise
*
raise_stmt
=
ast_cast
<
AST_Raise
>
(
invoke
->
stmt
);
AST_Raise
*
raise_stmt
=
ast_cast
<
AST_Raise
>
(
invoke
->
stmt
);
// Currently can't do a re-raise with a capi exception:
// Currently can't do a re-raise with a capi exception:
if
(
raise_stmt
->
arg0
&&
!
raise_stmt
->
arg2
)
{
if
(
raise_stmt
->
arg0
&&
!
raise_stmt
->
arg2
)
r
=
CAPI
;
r
=
CAPI
;
return
r
;
else
}
r
=
CXX
;
return
r
;
}
}
AST_expr
*
expr
=
NULL
;
AST_expr
*
expr
=
NULL
;
...
@@ -127,21 +137,18 @@ ExceptionStyle IRGenState::getLandingpadStyle(AST_Invoke* invoke) {
...
@@ -127,21 +137,18 @@ ExceptionStyle IRGenState::getLandingpadStyle(AST_Invoke* invoke) {
if
(
!
expr
)
if
(
!
expr
)
return
r
;
return
r
;
if
(
0
&&
expr
->
type
==
AST_TYPE
::
Call
)
{
if
(
expr
->
type
==
AST_TYPE
::
Call
)
{
AST_Call
*
call
=
ast_cast
<
AST_Call
>
(
expr
);
r
=
CAPI
;
if
(
call
->
func
->
type
!=
AST_TYPE
::
Attribute
&&
call
->
func
->
type
!=
AST_TYPE
::
ClsAttribute
)
{
r
=
CAPI
;
// printf("Doing a capi exception to %d\n", invoke->exc_dest->idx);
}
return
r
;
return
r
;
}
}
if
(
expr
->
type
==
AST_TYPE
::
Attribute
||
expr
->
type
==
AST_TYPE
::
Subscript
)
{
if
(
expr
->
type
==
AST_TYPE
::
Attribute
||
expr
->
type
==
AST_TYPE
::
Subscript
)
{
r
=
CAPI
;
r
=
CAPI
;
// printf("Doing a capi exception to %d\n", invoke->exc_dest->idx);
return
r
;
return
r
;
}
}
// Some expression type we haven't added yet -- might be worth looking into.
r
=
CXX
;
return
r
;
return
r
;
}
}
...
@@ -488,8 +495,7 @@ public:
...
@@ -488,8 +495,7 @@ public:
llvm
::
BasicBlock
*
exc_dest
;
llvm
::
BasicBlock
*
exc_dest
;
bool
exc_caught
;
bool
exc_caught
;
if
(
unw_info
.
hasHandler
())
{
if
(
unw_info
.
capi_exc_dest
)
{
assert
(
unw_info
.
capi_exc_dest
);
exc_dest
=
unw_info
.
capi_exc_dest
;
exc_dest
=
unw_info
.
capi_exc_dest
;
exc_caught
=
true
;
exc_caught
=
true
;
}
else
{
}
else
{
...
@@ -508,7 +514,13 @@ public:
...
@@ -508,7 +514,13 @@ public:
embedRelocatablePtr
(
irstate
->
getSourceInfo
(),
g
.
i8_ptr
));
embedRelocatablePtr
(
irstate
->
getSourceInfo
(),
g
.
i8_ptr
));
if
(
!
exc_caught
)
{
if
(
!
exc_caught
)
{
getBuilder
()
->
CreateCall
(
g
.
funcs
.
reraiseJitCapiExc
);
if
(
unw_info
.
cxx_exc_dest
)
{
// TODO: I'm not sure this gets the tracebacks quite right. this is only for testing though:
assert
(
FORCE_LLVM_CAPI
&&
"this shouldn't happen in non-FORCE mode"
);
createCall
(
unw_info
,
g
.
funcs
.
reraiseJitCapiExc
);
}
else
{
getBuilder
()
->
CreateCall
(
g
.
funcs
.
reraiseJitCapiExc
);
}
getBuilder
()
->
CreateUnreachable
();
getBuilder
()
->
CreateUnreachable
();
}
}
...
@@ -2429,8 +2441,11 @@ private:
...
@@ -2429,8 +2441,11 @@ private:
if
(
landingpad_style
==
CXX
)
if
(
landingpad_style
==
CXX
)
doStmt
(
invoke
->
stmt
,
UnwindInfo
(
node
,
NULL
,
entry_blocks
[
invoke
->
exc_dest
]));
doStmt
(
invoke
->
stmt
,
UnwindInfo
(
node
,
NULL
,
entry_blocks
[
invoke
->
exc_dest
]));
else
else
{
// print_ast(invoke);
// printf(" (%d exceptions)\n", invoke->cxx_exception_count);
doStmt
(
invoke
->
stmt
,
UnwindInfo
(
node
,
entry_blocks
[
invoke
->
exc_dest
],
NULL
));
doStmt
(
invoke
->
stmt
,
UnwindInfo
(
node
,
entry_blocks
[
invoke
->
exc_dest
],
NULL
));
}
assert
(
state
==
RUNNING
||
state
==
DEAD
);
assert
(
state
==
RUNNING
||
state
==
DEAD
);
if
(
state
==
RUNNING
)
{
if
(
state
==
RUNNING
)
{
...
...
src/codegen/runtime_hooks.cpp
View file @
96febb05
...
@@ -245,31 +245,62 @@ void initGlobalFuncs(GlobalState& g) {
...
@@ -245,31 +245,62 @@ void initGlobalFuncs(GlobalState& g) {
GET
(
boxedLocalsGet
);
GET
(
boxedLocalsGet
);
GET
(
boxedLocalsDel
);
GET
(
boxedLocalsDel
);
g
.
funcs
.
runtimeCall
=
getFunc
((
void
*
)
runtimeCall
,
"runtimeCall"
);
g
.
funcs
.
runtimeCall
.
cxx_val
=
getFunc
((
void
*
)
runtimeCall
,
"runtimeCall"
);
g
.
funcs
.
runtimeCall0
=
addFunc
((
void
*
)
runtimeCall
,
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
,
g
.
i32
);
g
.
funcs
.
runtimeCall0
.
cxx_val
=
addFunc
((
void
*
)
runtimeCall
,
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
,
g
.
i32
);
g
.
funcs
.
runtimeCall1
g
.
funcs
.
runtimeCall1
.
cxx_val
=
addFunc
((
void
*
)
runtimeCall
,
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
,
g
.
i32
,
g
.
llvm_value_type_ptr
);
=
addFunc
((
void
*
)
runtimeCall
,
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
,
g
.
i32
,
g
.
llvm_value_type_ptr
);
g
.
funcs
.
runtimeCall2
=
addFunc
((
void
*
)
runtimeCall
,
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
,
g
.
i32
,
g
.
funcs
.
runtimeCall2
.
cxx_val
=
addFunc
((
void
*
)
runtimeCall
,
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
,
g
.
i32
,
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
);
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
);
g
.
funcs
.
runtimeCall3
=
addFunc
((
void
*
)
runtimeCall
,
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
,
g
.
i32
,
g
.
funcs
.
runtimeCall3
.
cxx_val
=
addFunc
((
void
*
)
runtimeCall
,
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
,
g
.
i32
,
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
);
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
);
g
.
funcs
.
runtimeCallN
g
.
funcs
.
runtimeCallN
.
cxx_val
=
addFunc
((
void
*
)
runtimeCall
,
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
,
g
.
i32
,
g
.
llvm_value_type_ptr
,
=
addFunc
((
void
*
)
runtimeCall
,
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
,
g
.
i32
,
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
->
getPointerTo
());
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
->
getPointerTo
());
g
.
funcs
.
callattr
=
getFunc
((
void
*
)
callattr
,
"callattr"
);
g
.
funcs
.
runtimeCall
.
capi_val
=
getFunc
((
void
*
)
runtimeCallCapi
,
"runtimeCallCapi"
);
g
.
funcs
.
callattr0
g
.
funcs
.
runtimeCall0
.
capi_val
=
addFunc
((
void
*
)
runtimeCallCapi
,
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
,
g
.
i32
);
g
.
funcs
.
runtimeCall1
.
capi_val
=
addFunc
((
void
*
)
runtimeCallCapi
,
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
,
g
.
i32
,
g
.
llvm_value_type_ptr
);
g
.
funcs
.
runtimeCall2
.
capi_val
=
addFunc
((
void
*
)
runtimeCallCapi
,
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
,
g
.
i32
,
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
);
g
.
funcs
.
runtimeCall3
.
capi_val
=
addFunc
((
void
*
)
runtimeCallCapi
,
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
,
g
.
i32
,
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
);
g
.
funcs
.
runtimeCallN
.
capi_val
=
addFunc
((
void
*
)
runtimeCallCapi
,
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
,
g
.
i32
,
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
->
getPointerTo
());
g
.
funcs
.
callattr
.
cxx_val
=
getFunc
((
void
*
)
callattr
,
"callattr"
);
g
.
funcs
.
callattr0
.
cxx_val
=
addFunc
((
void
*
)
callattr
,
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
,
g
.
llvm_boxedstring_type_ptr
,
g
.
i64
);
=
addFunc
((
void
*
)
callattr
,
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
,
g
.
llvm_boxedstring_type_ptr
,
g
.
i64
);
g
.
funcs
.
callattr1
=
addFunc
((
void
*
)
callattr
,
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
,
g
.
funcs
.
callattr1
.
cxx_val
=
addFunc
((
void
*
)
callattr
,
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
,
g
.
llvm_boxedstring_type_ptr
,
g
.
i64
,
g
.
llvm_value_type_ptr
);
g
.
llvm_boxedstring_type_ptr
,
g
.
i64
,
g
.
llvm_value_type_ptr
);
g
.
funcs
.
callattr2
=
addFunc
((
void
*
)
callattr
,
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
,
g
.
funcs
.
callattr2
.
cxx_val
g
.
llvm_boxedstring_type_ptr
,
g
.
i64
,
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
);
g
.
funcs
.
callattr3
=
addFunc
((
void
*
)
callattr
,
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
,
g
.
llvm_boxedstring_type_ptr
,
g
.
i64
,
=
addFunc
((
void
*
)
callattr
,
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
,
g
.
llvm_boxedstring_type_ptr
,
g
.
i64
,
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
);
g
.
funcs
.
callattr3
.
cxx_val
=
addFunc
((
void
*
)
callattr
,
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
,
g
.
llvm_boxedstring_type_ptr
,
g
.
i64
,
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
);
g
.
funcs
.
callattrN
.
cxx_val
=
addFunc
(
(
void
*
)
callattr
,
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
,
g
.
llvm_boxedstring_type_ptr
,
g
.
i64
,
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
->
getPointerTo
());
g
.
funcs
.
callattr
.
capi_val
=
getFunc
((
void
*
)
callattrCapi
,
"callattrCapi"
);
g
.
funcs
.
callattr0
.
capi_val
=
addFunc
((
void
*
)
callattrCapi
,
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
,
g
.
llvm_boxedstring_type_ptr
,
g
.
i64
);
g
.
funcs
.
callattr1
.
capi_val
=
addFunc
((
void
*
)
callattrCapi
,
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
,
g
.
llvm_boxedstring_type_ptr
,
g
.
i64
,
g
.
llvm_value_type_ptr
);
g
.
funcs
.
callattr2
.
capi_val
=
addFunc
((
void
*
)
callattrCapi
,
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
,
g
.
llvm_boxedstring_type_ptr
,
g
.
i64
,
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
);
g
.
funcs
.
callattr3
.
capi_val
=
addFunc
((
void
*
)
callattrCapi
,
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
,
g
.
llvm_boxedstring_type_ptr
,
g
.
i64
,
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
);
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
);
g
.
funcs
.
callattrN
=
addFunc
((
void
*
)
callattr
,
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
,
g
.
funcs
.
callattrN
.
capi_val
=
addFunc
(
g
.
llvm_boxedstring_type_ptr
,
g
.
i64
,
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
,
(
void
*
)
callattrCapi
,
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
,
g
.
llvm_boxedstring_type_ptr
,
g
.
i64
,
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
->
getPointerTo
());
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
,
g
.
llvm_value_type_ptr
->
getPointerTo
());
g
.
funcs
.
reoptCompiledFunc
=
addFunc
((
void
*
)
reoptCompiledFunc
,
g
.
i8_ptr
,
g
.
i8_ptr
);
g
.
funcs
.
reoptCompiledFunc
=
addFunc
((
void
*
)
reoptCompiledFunc
,
g
.
i8_ptr
,
g
.
i8_ptr
);
g
.
funcs
.
compilePartialFunc
=
addFunc
((
void
*
)
compilePartialFunc
,
g
.
i8_ptr
,
g
.
i8_ptr
);
g
.
funcs
.
compilePartialFunc
=
addFunc
((
void
*
)
compilePartialFunc
,
g
.
i8_ptr
,
g
.
i8_ptr
);
...
...
src/codegen/runtime_hooks.h
View file @
96febb05
...
@@ -43,8 +43,8 @@ struct GlobalFuncs {
...
@@ -43,8 +43,8 @@ struct GlobalFuncs {
*
raiseAttributeErrorStrCapi
,
*
raiseNotIterableError
,
*
raiseIndexErrorStr
,
*
raiseIndexErrorStrCapi
,
*
raiseAttributeErrorStrCapi
,
*
raiseNotIterableError
,
*
raiseIndexErrorStr
,
*
raiseIndexErrorStrCapi
,
*
assertNameDefined
,
*
assertFail
,
*
assertFailDerefNameDefined
,
*
printExprHelper
;
*
assertNameDefined
,
*
assertFail
,
*
assertFailDerefNameDefined
,
*
printExprHelper
;
llvm
::
Value
*
printFloat
,
*
listAppendInternal
,
*
getSysStdout
;
llvm
::
Value
*
printFloat
,
*
listAppendInternal
,
*
getSysStdout
;
llvm
::
Value
*
runtimeCall0
,
*
runtimeCall1
,
*
runtimeCall2
,
*
runtimeCall3
,
*
runtimeCall
,
*
runtimeCallN
;
ExceptionSwitchable
<
llvm
::
Value
*>
runtimeCall0
,
runtimeCall1
,
runtimeCall2
,
runtimeCall3
,
runtimeCall
,
runtimeCallN
;
llvm
::
Value
*
callattr0
,
*
callattr1
,
*
callattr2
,
*
callattr3
,
*
callattr
,
*
callattrN
;
ExceptionSwitchable
<
llvm
::
Value
*>
callattr0
,
callattr1
,
callattr2
,
callattr3
,
callattr
,
callattrN
;
llvm
::
Value
*
reoptCompiledFunc
,
*
compilePartialFunc
;
llvm
::
Value
*
reoptCompiledFunc
,
*
compilePartialFunc
;
llvm
::
Value
*
exec
;
llvm
::
Value
*
exec
;
llvm
::
Value
*
boxedLocalsSet
,
*
boxedLocalsGet
,
*
boxedLocalsDel
;
llvm
::
Value
*
boxedLocalsSet
,
*
boxedLocalsGet
,
*
boxedLocalsDel
;
...
...
src/codegen/unwinding.cpp
View file @
96febb05
...
@@ -536,6 +536,8 @@ public:
...
@@ -536,6 +536,8 @@ public:
exc_info
.
reraise
=
false
;
exc_info
.
reraise
=
false
;
return
;
return
;
}
}
// TODO: shouldn't fetch this multiple times?
frame_iter
.
getCurrentStatement
()
->
cxx_exception_count
++
;
auto
line_info
=
lineInfoForFrame
(
&
frame_iter
);
auto
line_info
=
lineInfoForFrame
(
&
frame_iter
);
BoxedTraceback
::
here
(
line_info
,
&
exc_info
.
traceback
);
BoxedTraceback
::
here
(
line_info
,
&
exc_info
.
traceback
);
}
}
...
...
src/core/ast.h
View file @
96febb05
...
@@ -182,6 +182,8 @@ class AST_stmt : public AST {
...
@@ -182,6 +182,8 @@ class AST_stmt : public AST {
public:
public:
virtual
void
accept_stmt
(
StmtVisitor
*
v
)
=
0
;
virtual
void
accept_stmt
(
StmtVisitor
*
v
)
=
0
;
int
cxx_exception_count
=
0
;
AST_stmt
(
AST_TYPE
::
AST_TYPE
type
)
:
AST
(
type
)
{}
AST_stmt
(
AST_TYPE
::
AST_TYPE
type
)
:
AST
(
type
)
{}
};
};
...
...
src/runtime/builtin_modules/builtins.cpp
View file @
96febb05
...
@@ -457,11 +457,23 @@ Box* delattrFunc(Box* obj, Box* _str) {
...
@@ -457,11 +457,23 @@ Box* delattrFunc(Box* obj, Box* _str) {
return
None
;
return
None
;
}
}
Box
*
getattrFunc
(
Box
*
obj
,
Box
*
_str
,
Box
*
default_value
)
{
template
<
ExceptionStyle
S
>
Box
*
getattrFunc
(
Box
*
obj
,
Box
*
_str
,
Box
*
default_value
)
noexcept
(
S
==
CAPI
)
{
_str
=
coerceUnicodeToStr
(
_str
);
try
{
_str
=
coerceUnicodeToStr
(
_str
);
}
catch
(
ExcInfo
e
)
{
if
(
S
==
CAPI
)
{
setCAPIException
(
e
);
return
NULL
;
}
else
throw
e
;
}
if
(
!
isSubclass
(
_str
->
cls
,
str_cls
))
{
if
(
!
isSubclass
(
_str
->
cls
,
str_cls
))
{
raiseExcHelper
(
TypeError
,
"getattr(): attribute name must be string"
);
if
(
S
==
CAPI
)
{
PyErr_SetString
(
TypeError
,
"getattr(): attribute name must be string"
);
return
NULL
;
}
else
raiseExcHelper
(
TypeError
,
"getattr(): attribute name must be string"
);
}
}
Box
*
rtn
=
PyObject_GetAttr
(
obj
,
_str
);
Box
*
rtn
=
PyObject_GetAttr
(
obj
,
_str
);
...
@@ -470,7 +482,7 @@ Box* getattrFunc(Box* obj, Box* _str, Box* default_value) {
...
@@ -470,7 +482,7 @@ Box* getattrFunc(Box* obj, Box* _str, Box* default_value) {
return
default_value
;
return
default_value
;
}
}
if
(
!
rtn
)
if
(
S
==
CXX
&&
!
rtn
)
throwCAPIException
();
throwCAPIException
();
return
rtn
;
return
rtn
;
}
}
...
@@ -1437,9 +1449,9 @@ void setupBuiltins() {
...
@@ -1437,9 +1449,9 @@ void setupBuiltins() {
builtins_module
->
giveAttr
(
"delattr"
,
builtins_module
->
giveAttr
(
"delattr"
,
new
BoxedBuiltinFunctionOrMethod
(
boxRTFunction
((
void
*
)
delattrFunc
,
NONE
,
2
),
"delattr"
));
new
BoxedBuiltinFunctionOrMethod
(
boxRTFunction
((
void
*
)
delattrFunc
,
NONE
,
2
),
"delattr"
));
builtins_module
->
giveAttr
(
auto
getattr_func
=
boxRTFunction
((
void
*
)
getattrFunc
<
CXX
>
,
UNKNOWN
,
3
,
1
,
false
,
false
,
ParamNames
::
empty
(),
CXX
);
"getattr"
,
new
BoxedBuiltinFunctionOrMethod
(
boxRTFunction
((
void
*
)
getattrFunc
,
UNKNOWN
,
3
,
1
,
false
,
false
),
addRTFunction
(
getattr_func
,
(
void
*
)
getattrFunc
<
CAPI
>
,
UNKNOWN
,
CAPI
);
"getattr"
,
{
NULL
}));
builtins_module
->
giveAttr
(
"getattr"
,
new
BoxedBuiltinFunctionOrMethod
(
getattr_func
,
"getattr"
,
{
NULL
}));
builtins_module
->
giveAttr
(
builtins_module
->
giveAttr
(
"setattr"
,
"setattr"
,
...
...
src/runtime/capi.cpp
View file @
96febb05
...
@@ -1476,11 +1476,23 @@ Box* BoxedCApiFunction::__call__(BoxedCApiFunction* self, BoxedTuple* varargs, B
...
@@ -1476,11 +1476,23 @@ Box* BoxedCApiFunction::__call__(BoxedCApiFunction* self, BoxedTuple* varargs, B
// Kind of silly to have asked callFunc to rearrange the arguments for us, just to pass things
// Kind of silly to have asked callFunc to rearrange the arguments for us, just to pass things
// off to tppCall, but this case should be very uncommon (people explicitly asking for __call__)
// off to tppCall, but this case should be very uncommon (people explicitly asking for __call__)
return
BoxedCApiFunction
::
tppCall
(
self
,
NULL
,
ArgPassSpec
(
0
,
0
,
true
,
true
),
varargs
,
kwargs
,
NULL
,
NULL
,
NULL
);
return
BoxedCApiFunction
::
tppCall
<
CXX
>
(
self
,
NULL
,
ArgPassSpec
(
0
,
0
,
true
,
true
),
varargs
,
kwargs
,
NULL
,
NULL
,
NULL
);
}
}
template
<
ExceptionStyle
S
>
Box
*
BoxedCApiFunction
::
tppCall
(
Box
*
_self
,
CallRewriteArgs
*
rewrite_args
,
ArgPassSpec
argspec
,
Box
*
arg1
,
Box
*
arg2
,
Box
*
BoxedCApiFunction
::
tppCall
(
Box
*
_self
,
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
(
S
==
CAPI
)
{
try
{
return
tppCall
<
CXX
>
(
_self
,
NULL
,
argspec
,
arg1
,
arg2
,
arg3
,
args
,
keyword_names
);
}
catch
(
ExcInfo
e
)
{
setCAPIException
(
e
);
return
NULL
;
}
}
STAT_TIMER
(
t0
,
"us_timer_boxedcapifunction__call__"
,
10
);
STAT_TIMER
(
t0
,
"us_timer_boxedcapifunction__call__"
,
10
);
assert
(
_self
->
cls
==
capifunc_cls
);
assert
(
_self
->
cls
==
capifunc_cls
);
...
@@ -1634,7 +1646,8 @@ void setupCAPI() {
...
@@ -1634,7 +1646,8 @@ void setupCAPI() {
auto
capi_call
=
new
BoxedFunction
(
boxRTFunction
((
void
*
)
BoxedCApiFunction
::
__call__
,
UNKNOWN
,
1
,
0
,
true
,
true
));
auto
capi_call
=
new
BoxedFunction
(
boxRTFunction
((
void
*
)
BoxedCApiFunction
::
__call__
,
UNKNOWN
,
1
,
0
,
true
,
true
));
capifunc_cls
->
giveAttr
(
"__call__"
,
capi_call
);
capifunc_cls
->
giveAttr
(
"__call__"
,
capi_call
);
capifunc_cls
->
tpp_call
=
BoxedCApiFunction
::
tppCall
;
capifunc_cls
->
tpp_call
.
capi_val
=
BoxedCApiFunction
::
tppCall
<
CAPI
>
;
capifunc_cls
->
tpp_call
.
cxx_val
=
BoxedCApiFunction
::
tppCall
<
CXX
>
;
capifunc_cls
->
giveAttr
(
"__name__"
,
capifunc_cls
->
giveAttr
(
"__name__"
,
new
(
pyston_getset_cls
)
BoxedGetsetDescriptor
(
BoxedCApiFunction
::
getname
,
NULL
,
NULL
));
new
(
pyston_getset_cls
)
BoxedGetsetDescriptor
(
BoxedCApiFunction
::
getname
,
NULL
,
NULL
));
capifunc_cls
->
giveAttr
(
"__doc__"
,
capifunc_cls
->
giveAttr
(
"__doc__"
,
...
...
src/runtime/descr.cpp
View file @
96febb05
...
@@ -230,11 +230,23 @@ static Box* classmethodGet(Box* self, Box* obj, Box* type) {
...
@@ -230,11 +230,23 @@ static Box* classmethodGet(Box* self, Box* obj, Box* type) {
// TODO this should be auto-generated as a slot wrapper:
// TODO this should be auto-generated as a slot wrapper:
Box
*
BoxedMethodDescriptor
::
__call__
(
BoxedMethodDescriptor
*
self
,
Box
*
obj
,
BoxedTuple
*
varargs
,
Box
**
_args
)
{
Box
*
BoxedMethodDescriptor
::
__call__
(
BoxedMethodDescriptor
*
self
,
Box
*
obj
,
BoxedTuple
*
varargs
,
Box
**
_args
)
{
BoxedDict
*
kwargs
=
static_cast
<
BoxedDict
*>
(
_args
[
0
]);
BoxedDict
*
kwargs
=
static_cast
<
BoxedDict
*>
(
_args
[
0
]);
return
BoxedMethodDescriptor
::
tppCall
(
self
,
NULL
,
ArgPassSpec
(
1
,
0
,
true
,
true
),
obj
,
varargs
,
kwargs
,
NULL
,
NULL
);
return
BoxedMethodDescriptor
::
tppCall
<
CXX
>
(
self
,
NULL
,
ArgPassSpec
(
1
,
0
,
true
,
true
),
obj
,
varargs
,
kwargs
,
NULL
,
NULL
);
}
}
template
<
ExceptionStyle
S
>
Box
*
BoxedMethodDescriptor
::
tppCall
(
Box
*
_self
,
CallRewriteArgs
*
rewrite_args
,
ArgPassSpec
argspec
,
Box
*
arg1
,
Box
*
BoxedMethodDescriptor
::
tppCall
(
Box
*
_self
,
CallRewriteArgs
*
rewrite_args
,
ArgPassSpec
argspec
,
Box
*
arg1
,
Box
*
arg2
,
Box
*
arg3
,
Box
**
args
,
const
std
::
vector
<
BoxedString
*>*
keyword_names
)
{
Box
*
arg2
,
Box
*
arg3
,
Box
**
args
,
const
std
::
vector
<
BoxedString
*>*
keyword_names
)
noexcept
(
S
==
CAPI
)
{
if
(
S
==
CAPI
)
{
try
{
return
tppCall
<
CXX
>
(
_self
,
NULL
,
argspec
,
arg1
,
arg2
,
arg3
,
args
,
keyword_names
);
}
catch
(
ExcInfo
e
)
{
setCAPIException
(
e
);
return
NULL
;
}
}
STAT_TIMER
(
t0
,
"us_timer_boxedmethoddescriptor__call__"
,
10
);
STAT_TIMER
(
t0
,
"us_timer_boxedmethoddescriptor__call__"
,
10
);
assert
(
_self
->
cls
==
method_cls
);
assert
(
_self
->
cls
==
method_cls
);
...
@@ -489,8 +501,19 @@ Box* BoxedWrapperObject::__call__(BoxedWrapperObject* self, Box* args, Box* kwds
...
@@ -489,8 +501,19 @@ Box* BoxedWrapperObject::__call__(BoxedWrapperObject* self, Box* args, Box* kwds
return
rtn
;
return
rtn
;
}
}
template
<
ExceptionStyle
S
>
Box
*
BoxedWrapperObject
::
tppCall
(
Box
*
_self
,
CallRewriteArgs
*
rewrite_args
,
ArgPassSpec
argspec
,
Box
*
arg1
,
Box
*
arg2
,
Box
*
BoxedWrapperObject
::
tppCall
(
Box
*
_self
,
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
(
S
==
CAPI
)
{
try
{
return
tppCall
<
CXX
>
(
_self
,
NULL
,
argspec
,
arg1
,
arg2
,
arg3
,
args
,
keyword_names
);
}
catch
(
ExcInfo
e
)
{
setCAPIException
(
e
);
return
NULL
;
}
}
STAT_TIMER
(
t0
,
"us_timer_boxedwrapperobject_call"
,
(
_self
->
cls
->
is_user_defined
?
10
:
20
));
STAT_TIMER
(
t0
,
"us_timer_boxedwrapperobject_call"
,
(
_self
->
cls
->
is_user_defined
?
10
:
20
));
assert
(
_self
->
cls
==
wrapperobject_cls
);
assert
(
_self
->
cls
==
wrapperobject_cls
);
...
@@ -617,7 +640,8 @@ void setupDescr() {
...
@@ -617,7 +640,8 @@ void setupDescr() {
new
BoxedFunction
(
boxRTFunction
((
void
*
)
BoxedMethodDescriptor
::
__get__
,
UNKNOWN
,
3
)));
new
BoxedFunction
(
boxRTFunction
((
void
*
)
BoxedMethodDescriptor
::
__get__
,
UNKNOWN
,
3
)));
CLFunction
*
method_call_cl
=
boxRTFunction
((
void
*
)
BoxedMethodDescriptor
::
__call__
,
UNKNOWN
,
2
,
0
,
true
,
true
);
CLFunction
*
method_call_cl
=
boxRTFunction
((
void
*
)
BoxedMethodDescriptor
::
__call__
,
UNKNOWN
,
2
,
0
,
true
,
true
);
method_cls
->
giveAttr
(
"__call__"
,
new
BoxedFunction
(
method_call_cl
));
method_cls
->
giveAttr
(
"__call__"
,
new
BoxedFunction
(
method_call_cl
));
method_cls
->
tpp_call
=
BoxedMethodDescriptor
::
tppCall
;
method_cls
->
tpp_call
.
capi_val
=
BoxedMethodDescriptor
::
tppCall
<
CAPI
>
;
method_cls
->
tpp_call
.
cxx_val
=
BoxedMethodDescriptor
::
tppCall
<
CXX
>
;
method_cls
->
giveAttr
(
"__doc__"
,
new
(
pyston_getset_cls
)
BoxedGetsetDescriptor
(
methodGetDoc
,
NULL
,
NULL
));
method_cls
->
giveAttr
(
"__doc__"
,
new
(
pyston_getset_cls
)
BoxedGetsetDescriptor
(
methodGetDoc
,
NULL
,
NULL
));
method_cls
->
freeze
();
method_cls
->
freeze
();
...
@@ -632,7 +656,8 @@ void setupDescr() {
...
@@ -632,7 +656,8 @@ void setupDescr() {
wrapperobject_cls
->
giveAttr
(
wrapperobject_cls
->
giveAttr
(
"__call__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
BoxedWrapperObject
::
__call__
,
UNKNOWN
,
1
,
0
,
true
,
true
)));
"__call__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
BoxedWrapperObject
::
__call__
,
UNKNOWN
,
1
,
0
,
true
,
true
)));
wrapperobject_cls
->
tpp_call
=
BoxedWrapperObject
::
tppCall
;
wrapperobject_cls
->
tpp_call
.
capi_val
=
BoxedWrapperObject
::
tppCall
<
CAPI
>
;
wrapperobject_cls
->
tpp_call
.
cxx_val
=
BoxedWrapperObject
::
tppCall
<
CXX
>
;
wrapperobject_cls
->
freeze
();
wrapperobject_cls
->
freeze
();
}
}
...
...
src/runtime/float.cpp
View file @
96febb05
...
@@ -627,9 +627,17 @@ std::string floatFmt(double x, int precision, char code) {
...
@@ -627,9 +627,17 @@ std::string floatFmt(double x, int precision, char code) {
return
std
::
string
(
buf
,
n
);
return
std
::
string
(
buf
,
n
);
}
}
BoxedFloat
*
_floatNew
(
Box
*
a
)
{
template
<
ExceptionStyle
S
>
static
BoxedFloat
*
_floatNew
(
Box
*
a
)
noexcept
(
S
==
CAPI
)
{
// FIXME CPython uses PyUnicode_EncodeDecimal:
// FIXME CPython uses PyUnicode_EncodeDecimal:
a
=
coerceUnicodeToStr
(
a
);
try
{
a
=
coerceUnicodeToStr
(
a
);
}
catch
(
ExcInfo
e
)
{
if
(
S
==
CAPI
)
{
throwCAPIException
();
return
NULL
;
}
throw
e
;
}
if
(
a
->
cls
==
float_cls
)
{
if
(
a
->
cls
==
float_cls
)
{
return
static_cast
<
BoxedFloat
*>
(
a
);
return
static_cast
<
BoxedFloat
*>
(
a
);
...
@@ -653,40 +661,70 @@ BoxedFloat* _floatNew(Box* a) {
...
@@ -653,40 +661,70 @@ BoxedFloat* _floatNew(Box* a) {
assert
(
s
.
data
()[
s
.
size
()]
==
'\0'
);
assert
(
s
.
data
()[
s
.
size
()]
==
'\0'
);
const
char
*
startptr
=
s
.
data
();
const
char
*
startptr
=
s
.
data
();
double
r
=
strtod
(
startptr
,
&
endptr
);
double
r
=
strtod
(
startptr
,
&
endptr
);
if
(
endptr
!=
startptr
+
s
.
size
())
if
(
endptr
!=
startptr
+
s
.
size
())
{
raiseExcHelper
(
ValueError
,
"could not convert string to float: %s"
,
s
.
data
());
if
(
S
==
CAPI
)
{
PyErr_Format
(
ValueError
,
"could not convert string to float: %s"
,
s
.
data
());
return
NULL
;
}
else
raiseExcHelper
(
ValueError
,
"could not convert string to float: %s"
,
s
.
data
());
}
return
new
BoxedFloat
(
r
);
return
new
BoxedFloat
(
r
);
}
else
{
}
else
{
static
BoxedString
*
float_str
=
internStringImmortal
(
"__float__"
);
static
BoxedString
*
float_str
=
internStringImmortal
(
"__float__"
);
CallattrFlags
callattr_flags
{.
cls_only
=
true
,
.
null_on_nonexistent
=
true
,
.
argspec
=
ArgPassSpec
(
0
)
};
Box
*
r
=
callattrInternal
<
S
>
(
a
,
float_str
,
CLASS_ONLY
,
NULL
,
ArgPassSpec
(
0
),
NULL
,
NULL
,
NULL
,
NULL
,
NULL
);
Box
*
r
=
callattr
(
a
,
float_str
,
callattr_flags
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
);
if
(
!
r
)
{
if
(
!
r
)
{
fprintf
(
stderr
,
"TypeError: float() argument must be a string or a number, not '%s'
\n
"
,
getTypeName
(
a
));
if
(
S
==
CAPI
)
{
raiseExcHelper
(
TypeError
,
""
);
if
(
!
PyErr_Occurred
())
PyErr_Format
(
TypeError
,
"float() argument must be a string or a number, not '%s'
\n
"
,
getTypeName
(
a
));
return
NULL
;
}
else
{
raiseExcHelper
(
TypeError
,
"float() argument must be a string or a number, not '%s'
\n
"
,
getTypeName
(
a
));
}
}
}
if
(
!
isSubclass
(
r
->
cls
,
float_cls
))
{
if
(
!
isSubclass
(
r
->
cls
,
float_cls
))
{
raiseExcHelper
(
TypeError
,
"__float__ returned non-float (type %s)"
,
r
->
cls
->
tp_name
);
if
(
S
==
CAPI
)
{
PyErr_Format
(
TypeError
,
"__float__ returned non-float (type %s)"
,
r
->
cls
->
tp_name
);
return
NULL
;
}
else
raiseExcHelper
(
TypeError
,
"__float__ returned non-float (type %s)"
,
r
->
cls
->
tp_name
);
}
}
return
static_cast
<
BoxedFloat
*>
(
r
);
return
static_cast
<
BoxedFloat
*>
(
r
);
}
}
}
}
Box
*
floatNew
(
BoxedClass
*
_cls
,
Box
*
a
)
{
template
<
ExceptionStyle
S
>
Box
*
floatNew
(
BoxedClass
*
_cls
,
Box
*
a
)
noexcept
(
S
==
CAPI
)
{
if
(
!
isSubclass
(
_cls
->
cls
,
type_cls
))
if
(
!
isSubclass
(
_cls
->
cls
,
type_cls
))
{
raiseExcHelper
(
TypeError
,
"float.__new__(X): X is not a type object (%s)"
,
getTypeName
(
_cls
));
if
(
S
==
CAPI
)
{
PyErr_Format
(
TypeError
,
"float.__new__(X): X is not a type object (%s)"
,
getTypeName
(
_cls
));
return
NULL
;
}
else
raiseExcHelper
(
TypeError
,
"float.__new__(X): X is not a type object (%s)"
,
getTypeName
(
_cls
));
}
BoxedClass
*
cls
=
static_cast
<
BoxedClass
*>
(
_cls
);
BoxedClass
*
cls
=
static_cast
<
BoxedClass
*>
(
_cls
);
if
(
!
isSubclass
(
cls
,
float_cls
))
if
(
!
isSubclass
(
cls
,
float_cls
))
{
raiseExcHelper
(
TypeError
,
"float.__new__(%s): %s is not a subtype of float"
,
getNameOfClass
(
cls
),
if
(
S
==
CAPI
)
{
getNameOfClass
(
cls
));
PyErr_Format
(
TypeError
,
"float.__new__(%s): %s is not a subtype of float"
,
getNameOfClass
(
cls
),
getNameOfClass
(
cls
));
return
NULL
;
}
else
{
raiseExcHelper
(
TypeError
,
"float.__new__(%s): %s is not a subtype of float"
,
getNameOfClass
(
cls
),
getNameOfClass
(
cls
));
}
}
if
(
cls
==
float_cls
)
if
(
cls
==
float_cls
)
return
_floatNew
(
a
);
return
_floatNew
<
S
>
(
a
);
BoxedFloat
*
f
=
_floatNew
(
a
);
BoxedFloat
*
f
=
_floatNew
<
S
>
(
a
);
if
(
!
f
)
{
assert
(
S
==
CAPI
);
return
NULL
;
}
return
new
(
cls
)
BoxedFloat
(
f
->
d
);
return
new
(
cls
)
BoxedFloat
(
f
->
d
);
}
}
...
@@ -1476,8 +1514,9 @@ void setupFloat() {
...
@@ -1476,8 +1514,9 @@ void setupFloat() {
_addFunc
(
"__sub__"
,
BOXED_FLOAT
,
(
void
*
)
floatSubFloat
,
(
void
*
)
floatSubInt
,
(
void
*
)
floatSub
);
_addFunc
(
"__sub__"
,
BOXED_FLOAT
,
(
void
*
)
floatSubFloat
,
(
void
*
)
floatSubInt
,
(
void
*
)
floatSub
);
_addFunc
(
"__rsub__"
,
BOXED_FLOAT
,
(
void
*
)
floatRSubFloat
,
(
void
*
)
floatRSubInt
,
(
void
*
)
floatRSub
);
_addFunc
(
"__rsub__"
,
BOXED_FLOAT
,
(
void
*
)
floatRSubFloat
,
(
void
*
)
floatRSubInt
,
(
void
*
)
floatRSub
);
float_cls
->
giveAttr
(
auto
float_new
=
boxRTFunction
((
void
*
)
floatNew
<
CXX
>
,
UNKNOWN
,
2
,
1
,
false
,
false
,
ParamNames
::
empty
(),
CXX
);
"__new__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
floatNew
,
UNKNOWN
,
2
,
1
,
false
,
false
),
{
boxFloat
(
0.0
)
}));
addRTFunction
(
float_new
,
(
void
*
)
floatNew
<
CAPI
>
,
UNKNOWN
,
CAPI
);
float_cls
->
giveAttr
(
"__new__"
,
new
BoxedFunction
(
float_new
,
{
boxFloat
(
0.0
)
}));
float_cls
->
giveAttr
(
"__neg__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
floatNeg
,
BOXED_FLOAT
,
1
)));
float_cls
->
giveAttr
(
"__neg__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
floatNeg
,
BOXED_FLOAT
,
1
)));
float_cls
->
giveAttr
(
"__pos__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
floatPos
,
BOXED_FLOAT
,
1
)));
float_cls
->
giveAttr
(
"__pos__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
floatPos
,
BOXED_FLOAT
,
1
)));
...
...
src/runtime/inline/link_forcer.cpp
View file @
96febb05
...
@@ -120,7 +120,9 @@ void force() {
...
@@ -120,7 +120,9 @@ void force() {
FORCE
(
getSysStdout
);
FORCE
(
getSysStdout
);
FORCE
(
runtimeCall
);
FORCE
(
runtimeCall
);
FORCE
(
runtimeCallCapi
);
FORCE
(
callattr
);
FORCE
(
callattr
);
FORCE
(
callattrCapi
);
FORCE
(
raise0
);
FORCE
(
raise0
);
FORCE
(
raise3
);
FORCE
(
raise3
);
...
...
src/runtime/int.cpp
View file @
96febb05
...
@@ -884,7 +884,7 @@ extern "C" Box* intIndex(BoxedInt* v) {
...
@@ -884,7 +884,7 @@ extern "C" Box* intIndex(BoxedInt* v) {
return
boxInt
(
v
->
n
);
return
boxInt
(
v
->
n
);
}
}
static
Box
*
_intNew
(
Box
*
val
,
Box
*
base
)
{
template
<
ExceptionStyle
S
>
static
Box
*
_intNew
(
Box
*
val
,
Box
*
base
)
noexcept
(
S
==
CAPI
)
{
if
(
val
->
cls
==
int_cls
)
{
if
(
val
->
cls
==
int_cls
)
{
RELEASE_ASSERT
(
!
base
,
""
);
RELEASE_ASSERT
(
!
base
,
""
);
BoxedInt
*
n
=
static_cast
<
BoxedInt
*>
(
val
);
BoxedInt
*
n
=
static_cast
<
BoxedInt
*>
(
val
);
...
@@ -904,8 +904,12 @@ static Box* _intNew(Box* val, Box* base) {
...
@@ -904,8 +904,12 @@ static Box* _intNew(Box* val, Box* base) {
RELEASE_ASSERT
(
s
->
size
()
==
strlen
(
s
->
data
()),
""
);
RELEASE_ASSERT
(
s
->
size
()
==
strlen
(
s
->
data
()),
""
);
Box
*
r
=
PyInt_FromString
(
s
->
data
(),
NULL
,
base_n
);
Box
*
r
=
PyInt_FromString
(
s
->
data
(),
NULL
,
base_n
);
if
(
!
r
)
if
(
!
r
)
{
throwCAPIException
();
if
(
S
==
CAPI
)
return
NULL
;
else
throwCAPIException
();
}
return
r
;
return
r
;
}
else
if
(
isSubclass
(
val
->
cls
,
unicode_cls
))
{
}
else
if
(
isSubclass
(
val
->
cls
,
unicode_cls
))
{
int
base_n
;
int
base_n
;
...
@@ -917,8 +921,12 @@ static Box* _intNew(Box* val, Box* base) {
...
@@ -917,8 +921,12 @@ static Box* _intNew(Box* val, Box* base) {
}
}
Box
*
r
=
PyInt_FromUnicode
(
PyUnicode_AS_UNICODE
(
val
),
PyUnicode_GET_SIZE
(
val
),
base_n
);
Box
*
r
=
PyInt_FromUnicode
(
PyUnicode_AS_UNICODE
(
val
),
PyUnicode_GET_SIZE
(
val
),
base_n
);
if
(
!
r
)
if
(
!
r
)
{
throwCAPIException
();
if
(
S
==
CAPI
)
return
NULL
;
else
throwCAPIException
();
}
return
r
;
return
r
;
}
else
if
(
val
->
cls
==
float_cls
)
{
}
else
if
(
val
->
cls
==
float_cls
)
{
RELEASE_ASSERT
(
!
base
,
""
);
RELEASE_ASSERT
(
!
base
,
""
);
...
@@ -952,39 +960,68 @@ static Box* _intNew(Box* val, Box* base) {
...
@@ -952,39 +960,68 @@ static Box* _intNew(Box* val, Box* base) {
}
else
{
}
else
{
RELEASE_ASSERT
(
!
base
,
""
);
RELEASE_ASSERT
(
!
base
,
""
);
static
BoxedString
*
int_str
=
internStringImmortal
(
"__int__"
);
static
BoxedString
*
int_str
=
internStringImmortal
(
"__int__"
);
CallattrFlags
callattr_flags
{.
cls_only
=
true
,
.
null_on_nonexistent
=
true
,
.
argspec
=
ArgPassSpec
(
0
)
};
Box
*
r
=
callattrInternal
<
S
>
(
val
,
int_str
,
CLASS_ONLY
,
NULL
,
ArgPassSpec
(
0
),
NULL
,
NULL
,
NULL
,
NULL
,
NULL
);
Box
*
r
=
callattr
(
val
,
int_str
,
callattr_flags
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
);
if
(
!
r
)
{
if
(
!
r
)
{
fprintf
(
stderr
,
"TypeError: int() argument must be a string or a number, not '%s'
\n
"
,
getTypeName
(
val
));
if
(
S
==
CAPI
)
{
raiseExcHelper
(
TypeError
,
""
);
if
(
!
PyErr_Occurred
())
PyErr_Format
(
TypeError
,
"int() argument must be a string or a number, not '%s'
\n
"
,
getTypeName
(
val
));
return
NULL
;
}
else
{
raiseExcHelper
(
TypeError
,
"int() argument must be a string or a number, not '%s'
\n
"
,
getTypeName
(
val
));
}
}
}
if
(
!
isSubclass
(
r
->
cls
,
int_cls
)
&&
!
isSubclass
(
r
->
cls
,
long_cls
))
{
if
(
!
PyInt_Check
(
r
)
&&
!
PyLong_Check
(
r
))
{
raiseExcHelper
(
TypeError
,
"__int__ returned non-int (type %s)"
,
r
->
cls
->
tp_name
);
if
(
S
==
CAPI
)
{
PyErr_Format
(
TypeError
,
"__int__ returned non-int (type %s)"
,
r
->
cls
->
tp_name
);
return
NULL
;
}
else
raiseExcHelper
(
TypeError
,
"__int__ returned non-int (type %s)"
,
r
->
cls
->
tp_name
);
}
}
return
r
;
return
r
;
}
}
}
}
extern
"C"
Box
*
intNew
(
Box
*
_cls
,
Box
*
val
,
Box
*
base
)
{
template
<
ExceptionStyle
S
>
Box
*
intNew
(
Box
*
_cls
,
Box
*
val
,
Box
*
base
)
noexcept
(
S
==
CAPI
)
{
if
(
!
isSubclass
(
_cls
->
cls
,
type_cls
))
if
(
!
isSubclass
(
_cls
->
cls
,
type_cls
))
{
raiseExcHelper
(
TypeError
,
"int.__new__(X): X is not a type object (%s)"
,
getTypeName
(
_cls
));
if
(
S
==
CAPI
)
{
PyErr_Format
(
TypeError
,
"int.__new__(X): X is not a type object (%s)"
,
getTypeName
(
_cls
));
return
NULL
;
}
else
raiseExcHelper
(
TypeError
,
"int.__new__(X): X is not a type object (%s)"
,
getTypeName
(
_cls
));
}
BoxedClass
*
cls
=
static_cast
<
BoxedClass
*>
(
_cls
);
BoxedClass
*
cls
=
static_cast
<
BoxedClass
*>
(
_cls
);
if
(
!
isSubclass
(
cls
,
int_cls
))
if
(
!
isSubclass
(
cls
,
int_cls
))
{
raiseExcHelper
(
TypeError
,
"int.__new__(%s): %s is not a subtype of int"
,
getNameOfClass
(
cls
),
if
(
S
==
CAPI
)
{
getNameOfClass
(
cls
));
PyErr_Format
(
TypeError
,
"int.__new__(%s): %s is not a subtype of int"
,
getNameOfClass
(
cls
),
getNameOfClass
(
cls
));
return
NULL
;
}
else
raiseExcHelper
(
TypeError
,
"int.__new__(%s): %s is not a subtype of int"
,
getNameOfClass
(
cls
),
getNameOfClass
(
cls
));
}
if
(
cls
==
int_cls
)
if
(
cls
==
int_cls
)
return
_intNew
(
val
,
base
);
return
_intNew
<
S
>
(
val
,
base
);
BoxedInt
*
n
=
(
BoxedInt
*
)
_intNew
<
S
>
(
val
,
base
);
if
(
!
n
)
{
assert
(
S
==
CAPI
);
return
NULL
;
}
BoxedInt
*
n
=
(
BoxedInt
*
)
_intNew
(
val
,
base
);
if
(
n
->
cls
==
long_cls
)
{
if
(
n
->
cls
==
long_cls
)
{
if
(
cls
==
int_cls
)
if
(
cls
==
int_cls
)
return
n
;
return
n
;
raiseExcHelper
(
OverflowError
,
"Python int too large to convert to C long"
,
getNameOfClass
(
cls
),
getNameOfClass
(
cls
));
if
(
S
==
CAPI
)
{
PyErr_Format
(
OverflowError
,
"Python int too large to convert to C long"
);
return
NULL
;
}
else
raiseExcHelper
(
OverflowError
,
"Python int too large to convert to C long"
);
}
}
return
new
(
cls
)
BoxedInt
(
n
->
n
);
return
new
(
cls
)
BoxedInt
(
n
->
n
);
}
}
...
@@ -1138,9 +1175,10 @@ void setupInt() {
...
@@ -1138,9 +1175,10 @@ void setupInt() {
int_cls
->
giveAttr
(
"__index__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
intIndex
,
BOXED_INT
,
1
)));
int_cls
->
giveAttr
(
"__index__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
intIndex
,
BOXED_INT
,
1
)));
int_cls
->
giveAttr
(
"__int__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
intInt
,
BOXED_INT
,
1
)));
int_cls
->
giveAttr
(
"__int__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
intInt
,
BOXED_INT
,
1
)));
int_cls
->
giveAttr
(
"__new__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
intNew
,
UNKNOWN
,
3
,
2
,
false
,
false
,
auto
int_new
ParamNames
({
""
,
"x"
,
"base"
},
""
,
""
)),
=
boxRTFunction
((
void
*
)
intNew
<
CXX
>
,
UNKNOWN
,
3
,
2
,
false
,
false
,
ParamNames
({
""
,
"x"
,
"base"
},
""
,
""
),
CXX
);
{
boxInt
(
0
),
NULL
}));
addRTFunction
(
int_new
,
(
void
*
)
intNew
<
CAPI
>
,
UNKNOWN
,
CAPI
);
int_cls
->
giveAttr
(
"__new__"
,
new
BoxedFunction
(
int_new
,
{
boxInt
(
0
),
NULL
}));
int_cls
->
giveAttr
(
"bit_length"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
intBitLength
,
BOXED_INT
,
1
)));
int_cls
->
giveAttr
(
"bit_length"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
intBitLength
,
BOXED_INT
,
1
)));
...
...
src/runtime/objmodel.cpp
View file @
96febb05
This diff is collapsed.
Click to expand it.
src/runtime/objmodel.h
View file @
96febb05
...
@@ -65,7 +65,10 @@ extern "C" void delattrMaybeNonstring(Box* obj, Box* attr);
...
@@ -65,7 +65,10 @@ extern "C" void delattrMaybeNonstring(Box* obj, Box* attr);
extern
"C"
void
delattrGeneric
(
Box
*
obj
,
BoxedString
*
attr
,
DelattrRewriteArgs
*
rewrite_args
);
extern
"C"
void
delattrGeneric
(
Box
*
obj
,
BoxedString
*
attr
,
DelattrRewriteArgs
*
rewrite_args
);
extern
"C"
bool
nonzero
(
Box
*
obj
);
extern
"C"
bool
nonzero
(
Box
*
obj
);
extern
"C"
Box
*
runtimeCall
(
Box
*
,
ArgPassSpec
,
Box
*
,
Box
*
,
Box
*
,
Box
**
,
const
std
::
vector
<
BoxedString
*>*
);
extern
"C"
Box
*
runtimeCall
(
Box
*
,
ArgPassSpec
,
Box
*
,
Box
*
,
Box
*
,
Box
**
,
const
std
::
vector
<
BoxedString
*>*
);
extern
"C"
Box
*
runtimeCallCapi
(
Box
*
,
ArgPassSpec
,
Box
*
,
Box
*
,
Box
*
,
Box
**
,
const
std
::
vector
<
BoxedString
*>*
)
noexcept
;
extern
"C"
Box
*
callattr
(
Box
*
,
BoxedString
*
,
CallattrFlags
,
Box
*
,
Box
*
,
Box
*
,
Box
**
,
const
std
::
vector
<
BoxedString
*>*
);
extern
"C"
Box
*
callattr
(
Box
*
,
BoxedString
*
,
CallattrFlags
,
Box
*
,
Box
*
,
Box
*
,
Box
**
,
const
std
::
vector
<
BoxedString
*>*
);
extern
"C"
Box
*
callattrCapi
(
Box
*
,
BoxedString
*
,
CallattrFlags
,
Box
*
,
Box
*
,
Box
*
,
Box
**
,
const
std
::
vector
<
BoxedString
*>*
)
noexcept
;
extern
"C"
BoxedString
*
str
(
Box
*
obj
);
extern
"C"
BoxedString
*
str
(
Box
*
obj
);
extern
"C"
BoxedString
*
repr
(
Box
*
obj
);
extern
"C"
BoxedString
*
repr
(
Box
*
obj
);
extern
"C"
BoxedString
*
reprOrNull
(
Box
*
obj
);
// similar to repr, but returns NULL on exception
extern
"C"
BoxedString
*
reprOrNull
(
Box
*
obj
);
// similar to repr, but returns NULL on exception
...
@@ -132,9 +135,10 @@ enum LookupScope {
...
@@ -132,9 +135,10 @@ enum LookupScope {
INST_ONLY
=
2
,
INST_ONLY
=
2
,
CLASS_OR_INST
=
3
,
CLASS_OR_INST
=
3
,
};
};
extern
"C"
Box
*
callattrInternal
(
Box
*
obj
,
BoxedString
*
attr
,
LookupScope
,
CallRewriteArgs
*
rewrite_args
,
template
<
ExceptionStyle
S
>
ArgPassSpec
argspec
,
Box
*
arg1
,
Box
*
arg2
,
Box
*
arg3
,
Box
**
args
,
Box
*
callattrInternal
(
Box
*
obj
,
BoxedString
*
attr
,
LookupScope
,
CallRewriteArgs
*
rewrite_args
,
ArgPassSpec
argspec
,
const
std
::
vector
<
BoxedString
*>*
keyword_names
);
Box
*
arg1
,
Box
*
arg2
,
Box
*
arg3
,
Box
**
args
,
const
std
::
vector
<
BoxedString
*>*
keyword_names
)
noexcept
(
S
==
CAPI
);
extern
"C"
void
delattr_internal
(
Box
*
obj
,
BoxedString
*
attr
,
bool
allow_custom
,
DelattrRewriteArgs
*
rewrite_args
);
extern
"C"
void
delattr_internal
(
Box
*
obj
,
BoxedString
*
attr
,
bool
allow_custom
,
DelattrRewriteArgs
*
rewrite_args
);
struct
CompareRewriteArgs
;
struct
CompareRewriteArgs
;
Box
*
compareInternal
(
Box
*
lhs
,
Box
*
rhs
,
int
op_type
,
CompareRewriteArgs
*
rewrite_args
);
Box
*
compareInternal
(
Box
*
lhs
,
Box
*
rhs
,
int
op_type
,
CompareRewriteArgs
*
rewrite_args
);
...
...
src/runtime/tuple.cpp
View file @
96febb05
...
@@ -143,7 +143,7 @@ template <ExceptionStyle S> Box* tupleGetitem(BoxedTuple* self, Box* slice) {
...
@@ -143,7 +143,7 @@ template <ExceptionStyle S> Box* tupleGetitem(BoxedTuple* self, Box* slice) {
}
}
}
}
assert
(
self
->
cls
==
tuple_cls
);
assert
(
isSubclass
(
self
->
cls
,
tuple_cls
)
);
if
(
PyIndex_Check
(
slice
))
{
if
(
PyIndex_Check
(
slice
))
{
Py_ssize_t
i
=
PyNumber_AsSsize_t
(
slice
,
PyExc_IndexError
);
Py_ssize_t
i
=
PyNumber_AsSsize_t
(
slice
,
PyExc_IndexError
);
...
...
src/runtime/types.cpp
View file @
96febb05
This diff is collapsed.
Click to expand it.
src/runtime/types.h
View file @
96febb05
...
@@ -242,9 +242,8 @@ public:
...
@@ -242,9 +242,8 @@ public:
pyston_inquiry
tpp_hasnext
;
pyston_inquiry
tpp_hasnext
;
typedef
Box
*
(
*
pyston_call
)(
Box
*
,
CallRewriteArgs
*
,
ArgPassSpec
,
Box
*
,
Box
*
,
Box
*
,
Box
**
,
ExceptionSwitchableFunction
<
Box
*
,
Box
*
,
CallRewriteArgs
*
,
ArgPassSpec
,
Box
*
,
Box
*
,
Box
*
,
Box
**
,
const
std
::
vector
<
BoxedString
*>*
);
const
std
::
vector
<
BoxedString
*>*>
tpp_call
;
pyston_call
tpp_call
;
bool
hasGenericGetattr
()
{
bool
hasGenericGetattr
()
{
if
(
tp_getattr
||
tp_getattro
!=
object_cls
->
tp_getattro
)
if
(
tp_getattr
||
tp_getattro
!=
object_cls
->
tp_getattro
)
...
@@ -985,8 +984,9 @@ public:
...
@@ -985,8 +984,9 @@ public:
DEFAULT_CLASS
(
wrapperobject_cls
);
DEFAULT_CLASS
(
wrapperobject_cls
);
static
Box
*
__call__
(
BoxedWrapperObject
*
self
,
Box
*
args
,
Box
*
kwds
);
static
Box
*
__call__
(
BoxedWrapperObject
*
self
,
Box
*
args
,
Box
*
kwds
);
template
<
ExceptionStyle
S
>
static
Box
*
tppCall
(
Box
*
_self
,
CallRewriteArgs
*
rewrite_args
,
ArgPassSpec
argspec
,
Box
*
arg1
,
Box
*
arg2
,
Box
*
arg3
,
static
Box
*
tppCall
(
Box
*
_self
,
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
)
;
static
void
gcHandler
(
GCVisitor
*
v
,
Box
*
_o
);
static
void
gcHandler
(
GCVisitor
*
v
,
Box
*
_o
);
};
};
...
@@ -1001,12 +1001,12 @@ public:
...
@@ -1001,12 +1001,12 @@ public:
static
Box
*
__get__
(
BoxedMethodDescriptor
*
self
,
Box
*
inst
,
Box
*
owner
);
static
Box
*
__get__
(
BoxedMethodDescriptor
*
self
,
Box
*
inst
,
Box
*
owner
);
static
Box
*
__call__
(
BoxedMethodDescriptor
*
self
,
Box
*
obj
,
BoxedTuple
*
varargs
,
Box
**
_args
);
static
Box
*
__call__
(
BoxedMethodDescriptor
*
self
,
Box
*
obj
,
BoxedTuple
*
varargs
,
Box
**
_args
);
template
<
ExceptionStyle
S
>
static
Box
*
tppCall
(
Box
*
_self
,
CallRewriteArgs
*
rewrite_args
,
ArgPassSpec
argspec
,
Box
*
arg1
,
Box
*
arg2
,
Box
*
arg3
,
static
Box
*
tppCall
(
Box
*
_self
,
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
)
;
static
void
gcHandler
(
GCVisitor
*
v
,
Box
*
_o
);
static
void
gcHandler
(
GCVisitor
*
v
,
Box
*
_o
);
};
};
Box
*
objectNewNoArgs
(
BoxedClass
*
cls
);
Box
*
objectSetattr
(
Box
*
obj
,
Box
*
attr
,
Box
*
value
);
Box
*
objectSetattr
(
Box
*
obj
,
Box
*
attr
,
Box
*
value
);
Box
*
unwrapAttrWrapper
(
Box
*
b
);
Box
*
unwrapAttrWrapper
(
Box
*
b
);
...
...
src/runtime/util.cpp
View file @
96febb05
...
@@ -41,11 +41,11 @@ void parseSlice(BoxedSlice* slice, int size, i64* out_start, i64* out_stop, i64*
...
@@ -41,11 +41,11 @@ void parseSlice(BoxedSlice* slice, int size, i64* out_start, i64* out_stop, i64*
throwCAPIException
();
throwCAPIException
();
}
}
bool
isSliceIndex
(
Box
*
b
)
{
bool
isSliceIndex
(
Box
*
b
)
noexcept
{
return
b
->
cls
==
none_cls
||
b
->
cls
==
int_cls
||
PyIndex_Check
(
b
);
return
b
->
cls
==
none_cls
||
b
->
cls
==
int_cls
||
PyIndex_Check
(
b
);
}
}
void
adjustNegativeIndicesOnObject
(
Box
*
obj
,
i64
*
start_out
,
i64
*
stop_out
)
{
void
adjustNegativeIndicesOnObject
(
Box
*
obj
,
i64
*
start_out
,
i64
*
stop_out
)
noexcept
{
i64
start
=
*
start_out
;
i64
start
=
*
start_out
;
i64
stop
=
*
stop_out
;
i64
stop
=
*
stop_out
;
PySequenceMethods
*
m
;
PySequenceMethods
*
m
;
...
...
src/runtime/util.h
View file @
96febb05
...
@@ -36,9 +36,9 @@ inline void sliceIndex(Box* b, int64_t* out) {
...
@@ -36,9 +36,9 @@ inline void sliceIndex(Box* b, int64_t* out) {
throwCAPIException
();
throwCAPIException
();
}
}
bool
isSliceIndex
(
Box
*
b
);
bool
isSliceIndex
(
Box
*
b
)
noexcept
;
void
adjustNegativeIndicesOnObject
(
Box
*
obj
,
i64
*
start
,
i64
*
stop
);
void
adjustNegativeIndicesOnObject
(
Box
*
obj
,
i64
*
start
,
i64
*
stop
)
noexcept
;
// Adjust the start and stop bounds of the sequence we are slicing to its size.
// Adjust the start and stop bounds of the sequence we are slicing to its size.
// Ensure stop >= start and remain within bounds.
// Ensure stop >= start and remain within bounds.
...
...
test/test_extension/setup.py
View file @
96febb05
from
distutils.core
import
setup
,
Extension
from
distutils.core
import
setup
,
Extension
import
glob
import
os
extensions
=
[
Extension
(
"basic_test"
,
sources
=
[
"basic_test.c"
]),
Extension
(
"descr_test"
,
sources
=
[
"descr_test.c"
]),
Extension
(
"slots_test"
,
sources
=
[
"slots_test.c"
]),
]
def
relpath
(
fn
):
r
=
os
.
path
.
join
(
os
.
path
.
dirname
(
__file__
),
fn
)
return
r
print
glob
.
glob
(
"../from_cpython/Include/*.h"
)
builtin_headers
=
map
(
relpath
,
glob
.
glob
(
"../../from_cpython/Include/*.h"
))
for
m
in
extensions
:
m
.
depends
+=
builtin_headers
setup
(
name
=
"test"
,
setup
(
name
=
"test"
,
version
=
"1.0"
,
version
=
"1.0"
,
description
=
"test"
,
description
=
"test"
,
ext_modules
=
[
ext_modules
=
extensions
,
Extension
(
"basic_test"
,
sources
=
[
"basic_test.c"
]),
Extension
(
"descr_test"
,
sources
=
[
"descr_test.c"
]),
Extension
(
"slots_test"
,
sources
=
[
"slots_test.c"
]),
],
)
)
test/tests/varargs_ics.py
View file @
96febb05
# run_args: -n
# run_args: -n
# statcheck: 1 <= noninit_count("slowpath_runtimecall") < 20
# statcheck: 1 <= noninit_count("slowpath_runtimecall")
+ noninit_count("slowpath_runtimecall_capi")
< 20
# Make sure we can patch some basic varargs cases
# Make sure we can patch some basic varargs cases
...
...
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