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
f95bd65f
Commit
f95bd65f
authored
Apr 27, 2015
by
Kevin Modzelewski
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #467 from undingen/pycrypto
Misc stuff for pycrypto
parents
a53ab1a8
1dc72576
Changes
29
Hide whitespace changes
Inline
Side-by-side
Showing
29 changed files
with
615 additions
and
181 deletions
+615
-181
CMakeLists.txt
CMakeLists.txt
+1
-1
Makefile
Makefile
+1
-1
from_cpython/Lib/platform.py
from_cpython/Lib/platform.py
+4
-0
libpypa
libpypa
+1
-1
src/capi/abstract.cpp
src/capi/abstract.cpp
+202
-19
src/codegen/entry.cpp
src/codegen/entry.cpp
+1
-1
src/runtime/builtin_modules/builtins.cpp
src/runtime/builtin_modules/builtins.cpp
+8
-0
src/runtime/capi.cpp
src/runtime/capi.cpp
+3
-3
src/runtime/classobj.cpp
src/runtime/classobj.cpp
+24
-0
src/runtime/float.cpp
src/runtime/float.cpp
+24
-4
src/runtime/import.cpp
src/runtime/import.cpp
+3
-1
src/runtime/inline/xrange.cpp
src/runtime/inline/xrange.cpp
+13
-15
src/runtime/int.cpp
src/runtime/int.cpp
+29
-5
src/runtime/list.cpp
src/runtime/list.cpp
+23
-14
src/runtime/long.cpp
src/runtime/long.cpp
+177
-24
src/runtime/long.h
src/runtime/long.h
+1
-1
src/runtime/objmodel.cpp
src/runtime/objmodel.cpp
+1
-0
src/runtime/str.cpp
src/runtime/str.cpp
+4
-3
src/runtime/tuple.cpp
src/runtime/tuple.cpp
+7
-3
src/runtime/types.cpp
src/runtime/types.cpp
+54
-9
src/runtime/util.cpp
src/runtime/util.cpp
+4
-73
test/tests/builtins.py
test/tests/builtins.py
+2
-0
test/tests/gcj_2014_2_d.py
test/tests/gcj_2014_2_d.py
+0
-3
test/tests/index_meth.py
test/tests/index_meth.py
+14
-0
test/tests/intmethods.py
test/tests/intmethods.py
+3
-0
test/tests/list.py
test/tests/list.py
+1
-0
test/tests/long.py
test/tests/long.py
+6
-0
test/tests/tuples.py
test/tests/tuples.py
+1
-0
test/tests/xrange.py
test/tests/xrange.py
+3
-0
No files found.
CMakeLists.txt
View file @
f95bd65f
...
@@ -93,7 +93,7 @@ endif()
...
@@ -93,7 +93,7 @@ endif()
add_subdirectory
(
${
DEPS_DIR
}
/llvm-trunk
${
CMAKE_BINARY_DIR
}
/llvm EXCLUDE_FROM_ALL
)
add_subdirectory
(
${
DEPS_DIR
}
/llvm-trunk
${
CMAKE_BINARY_DIR
}
/llvm EXCLUDE_FROM_ALL
)
set
(
CMAKE_MODULE_PATH
"
${
CMAKE_BINARY_DIR
}
/llvm/share/llvm/cmake/"
)
set
(
CMAKE_MODULE_PATH
"
${
CMAKE_BINARY_DIR
}
/llvm/share/llvm/cmake/"
)
include
(
LLVMConfig
)
include
(
LLVMConfig
)
llvm_map_components_to_libnames
(
LLVM_LIBS core mcjit native bitreader ipo irreader debuginfodwarf instrumentation
${
INTEL_JIT_EVENTS_LIB
}
)
llvm_map_components_to_libnames
(
LLVM_LIBS core mcjit native bitreader
bitwriter
ipo irreader debuginfodwarf instrumentation
${
INTEL_JIT_EVENTS_LIB
}
)
# libunwind
# libunwind
if
(
"
${
CMAKE_BUILD_TYPE
}
"
STREQUAL
"Debug"
)
if
(
"
${
CMAKE_BUILD_TYPE
}
"
STREQUAL
"Debug"
)
...
...
Makefile
View file @
f95bd65f
...
@@ -97,7 +97,7 @@ else
...
@@ -97,7 +97,7 @@ else
LLVM_BIN
:=
$(LLVM_BUILD)
/Release/bin
LLVM_BIN
:=
$(LLVM_BUILD)
/Release/bin
endif
endif
LLVM_LINK_LIBS
:=
core mcjit native bitreader ipo irreader debuginfodwarf instrumentation
LLVM_LINK_LIBS
:=
core mcjit native bitreader
bitwriter
ipo irreader debuginfodwarf instrumentation
ifneq
($(ENABLE_INTEL_JIT_EVENTS),0)
ifneq
($(ENABLE_INTEL_JIT_EVENTS),0)
LLVM_LINK_LIBS
+=
inteljitevents
LLVM_LINK_LIBS
+=
inteljitevents
endif
endif
...
...
from_cpython/Lib/platform.py
View file @
f95bd65f
...
@@ -155,6 +155,10 @@ def libc_ver(executable=sys.executable,lib='',version='',
...
@@ -155,6 +155,10 @@ def libc_ver(executable=sys.executable,lib='',version='',
The file is read and scanned in chunks of chunksize bytes.
The file is read and scanned in chunks of chunksize bytes.
"""
"""
# Pyston change: hard code pyston executable libc version
if
executable
==
sys
.
executable
:
return
(
"glibc"
,
"2.6"
)
if
hasattr
(
os
.
path
,
'realpath'
):
if
hasattr
(
os
.
path
,
'realpath'
):
# Python 2.2 introduced os.path.realpath(); it is used
# Python 2.2 introduced os.path.realpath(); it is used
# here to work around problems with Cygwin not being
# here to work around problems with Cygwin not being
...
...
libpypa
@
51f55dd4
Subproject commit
8f62d5d7440cff89f98ed5a2e7756321811a0f2d
Subproject commit
51f55dd4068f116ca287369cedddce624de73da6
src/capi/abstract.cpp
View file @
f95bd65f
...
@@ -1038,6 +1038,149 @@ static PyObject* binary_op(PyObject* v, PyObject* w, const int op_slot, const ch
...
@@ -1038,6 +1038,149 @@ static PyObject* binary_op(PyObject* v, PyObject* w, const int op_slot, const ch
return
result
;
return
result
;
}
}
/*
Calling scheme used for ternary operations:
*** In some cases, w.op is called before v.op; see binary_op1. ***
v w z Action
-------------------------------------------------------------------
new new new v.op(v,w,z), w.op(v,w,z), z.op(v,w,z)
new old new v.op(v,w,z), z.op(v,w,z), coerce(v,w,z), v.op(v,w,z)
old new new w.op(v,w,z), z.op(v,w,z), coerce(v,w,z), v.op(v,w,z)
old old new z.op(v,w,z), coerce(v,w,z), v.op(v,w,z)
new new old v.op(v,w,z), w.op(v,w,z), coerce(v,w,z), v.op(v,w,z)
new old old v.op(v,w,z), coerce(v,w,z), v.op(v,w,z)
old new old w.op(v,w,z), coerce(v,w,z), v.op(v,w,z)
old old old coerce(v,w,z), v.op(v,w,z)
Legend:
-------
* new == new style number
* old == old style number
* Action indicates the order in which operations are tried until either
a valid result is produced or an error occurs.
* coerce(v,w,z) actually does: coerce(v,w), coerce(v,z), coerce(w,z) and
only if z != Py_None; if z == Py_None, then it is treated as absent
variable and only coerce(v,w) is tried.
*/
static
PyObject
*
ternary_op
(
PyObject
*
v
,
PyObject
*
w
,
PyObject
*
z
,
const
int
op_slot
,
const
char
*
op_name
)
noexcept
{
PyNumberMethods
*
mv
,
*
mw
,
*
mz
;
PyObject
*
x
=
NULL
;
ternaryfunc
slotv
=
NULL
;
ternaryfunc
slotw
=
NULL
;
ternaryfunc
slotz
=
NULL
;
mv
=
v
->
cls
->
tp_as_number
;
mw
=
w
->
cls
->
tp_as_number
;
if
(
mv
!=
NULL
&&
NEW_STYLE_NUMBER
(
v
))
slotv
=
NB_TERNOP
(
mv
,
op_slot
);
if
(
w
->
cls
!=
v
->
cls
&&
mw
!=
NULL
&&
NEW_STYLE_NUMBER
(
w
))
{
slotw
=
NB_TERNOP
(
mw
,
op_slot
);
if
(
slotw
==
slotv
)
slotw
=
NULL
;
}
if
(
slotv
)
{
if
(
slotw
&&
PyType_IsSubtype
(
w
->
cls
,
v
->
cls
))
{
x
=
slotw
(
v
,
w
,
z
);
if
(
x
!=
Py_NotImplemented
)
return
x
;
Py_DECREF
(
x
);
/* can't do it */
slotw
=
NULL
;
}
x
=
slotv
(
v
,
w
,
z
);
if
(
x
!=
Py_NotImplemented
)
return
x
;
Py_DECREF
(
x
);
/* can't do it */
}
if
(
slotw
)
{
x
=
slotw
(
v
,
w
,
z
);
if
(
x
!=
Py_NotImplemented
)
return
x
;
Py_DECREF
(
x
);
/* can't do it */
}
mz
=
z
->
cls
->
tp_as_number
;
if
(
mz
!=
NULL
&&
NEW_STYLE_NUMBER
(
z
))
{
slotz
=
NB_TERNOP
(
mz
,
op_slot
);
if
(
slotz
==
slotv
||
slotz
==
slotw
)
slotz
=
NULL
;
if
(
slotz
)
{
x
=
slotz
(
v
,
w
,
z
);
if
(
x
!=
Py_NotImplemented
)
return
x
;
Py_DECREF
(
x
);
/* can't do it */
}
}
if
(
!
NEW_STYLE_NUMBER
(
v
)
||
!
NEW_STYLE_NUMBER
(
w
)
||
(
z
!=
Py_None
&&
!
NEW_STYLE_NUMBER
(
z
)))
{
/* we have an old style operand, coerce */
PyObject
*
v1
,
*
z1
,
*
w2
,
*
z2
;
int
c
;
c
=
PyNumber_Coerce
(
&
v
,
&
w
);
if
(
c
!=
0
)
goto
error3
;
/* Special case: if the third argument is None, it is
treated as absent argument and not coerced. */
if
(
z
==
Py_None
)
{
if
(
v
->
cls
->
tp_as_number
)
{
slotz
=
NB_TERNOP
(
v
->
cls
->
tp_as_number
,
op_slot
);
if
(
slotz
)
x
=
slotz
(
v
,
w
,
z
);
else
c
=
-
1
;
}
else
c
=
-
1
;
goto
error2
;
}
v1
=
v
;
z1
=
z
;
c
=
PyNumber_Coerce
(
&
v1
,
&
z1
);
if
(
c
!=
0
)
goto
error2
;
w2
=
w
;
z2
=
z1
;
c
=
PyNumber_Coerce
(
&
w2
,
&
z2
);
if
(
c
!=
0
)
goto
error1
;
if
(
v1
->
cls
->
tp_as_number
!=
NULL
)
{
slotv
=
NB_TERNOP
(
v1
->
cls
->
tp_as_number
,
op_slot
);
if
(
slotv
)
x
=
slotv
(
v1
,
w2
,
z2
);
else
c
=
-
1
;
}
else
c
=
-
1
;
Py_DECREF
(
w2
);
Py_DECREF
(
z2
);
error1:
Py_DECREF
(
v1
);
Py_DECREF
(
z1
);
error2:
Py_DECREF
(
v
);
Py_DECREF
(
w
);
error3:
if
(
c
>=
0
)
return
x
;
}
if
(
z
==
Py_None
)
PyErr_Format
(
PyExc_TypeError
,
"unsupported operand type(s) for ** or pow(): "
"'%.100s' and '%.100s'"
,
v
->
cls
->
tp_name
,
w
->
cls
->
tp_name
);
else
PyErr_Format
(
PyExc_TypeError
,
"unsupported operand type(s) for pow(): "
"'%.100s', '%.100s', '%.100s'"
,
v
->
cls
->
tp_name
,
w
->
cls
->
tp_name
,
z
->
cls
->
tp_name
);
return
NULL
;
}
extern
"C"
PyObject
*
PySequence_Concat
(
PyObject
*
s
,
PyObject
*
o
)
noexcept
{
extern
"C"
PyObject
*
PySequence_Concat
(
PyObject
*
s
,
PyObject
*
o
)
noexcept
{
PySequenceMethods
*
m
;
PySequenceMethods
*
m
;
...
@@ -1392,9 +1535,8 @@ extern "C" PyObject* PyNumber_Divmod(PyObject* lhs, PyObject* rhs) noexcept {
...
@@ -1392,9 +1535,8 @@ extern "C" PyObject* PyNumber_Divmod(PyObject* lhs, PyObject* rhs) noexcept {
}
}
}
}
extern
"C"
PyObject
*
PyNumber_Power
(
PyObject
*
,
PyObject
*
,
PyObject
*
o3
)
noexcept
{
extern
"C"
PyObject
*
PyNumber_Power
(
PyObject
*
v
,
PyObject
*
w
,
PyObject
*
z
)
noexcept
{
fatalOrError
(
PyExc_NotImplementedError
,
"unimplemented"
);
return
ternary_op
(
v
,
w
,
z
,
NB_SLOT
(
nb_power
),
"** or pow()"
);
return
nullptr
;
}
}
extern
"C"
PyObject
*
PyNumber_Negative
(
PyObject
*
o
)
noexcept
{
extern
"C"
PyObject
*
PyNumber_Negative
(
PyObject
*
o
)
noexcept
{
...
@@ -1421,9 +1563,13 @@ extern "C" PyObject* PyNumber_Invert(PyObject* o) noexcept {
...
@@ -1421,9 +1563,13 @@ extern "C" PyObject* PyNumber_Invert(PyObject* o) noexcept {
return
nullptr
;
return
nullptr
;
}
}
extern
"C"
PyObject
*
PyNumber_Lshift
(
PyObject
*
,
PyObject
*
)
noexcept
{
extern
"C"
PyObject
*
PyNumber_Lshift
(
PyObject
*
lhs
,
PyObject
*
rhs
)
noexcept
{
fatalOrError
(
PyExc_NotImplementedError
,
"unimplemented"
);
try
{
return
nullptr
;
return
binop
(
lhs
,
rhs
,
AST_TYPE
::
LShift
);
}
catch
(
ExcInfo
e
)
{
fatalOrError
(
PyExc_NotImplementedError
,
"unimplemented"
);
return
nullptr
;
}
}
}
extern
"C"
PyObject
*
PyNumber_Rshift
(
PyObject
*
lhs
,
PyObject
*
rhs
)
noexcept
{
extern
"C"
PyObject
*
PyNumber_Rshift
(
PyObject
*
lhs
,
PyObject
*
rhs
)
noexcept
{
...
@@ -1684,8 +1830,21 @@ extern "C" PyObject* PyNumber_Index(PyObject* o) noexcept {
...
@@ -1684,8 +1830,21 @@ extern "C" PyObject* PyNumber_Index(PyObject* o) noexcept {
return
o
;
return
o
;
}
}
fatalOrError
(
PyExc_NotImplementedError
,
"unimplemented"
);
if
(
PyIndex_Check
(
o
))
{
return
nullptr
;
result
=
o
->
cls
->
tp_as_number
->
nb_index
(
o
);
if
(
result
&&
!
PyInt_Check
(
result
)
&&
!
PyLong_Check
(
result
))
{
PyErr_Format
(
PyExc_TypeError
,
"__index__ returned non-(int,long) "
"(type %.200s)"
,
result
->
cls
->
tp_name
);
Py_DECREF
(
result
);
return
NULL
;
}
}
else
{
PyErr_Format
(
PyExc_TypeError
,
"'%.200s' object cannot be interpreted "
"as an index"
,
o
->
cls
->
tp_name
);
}
return
result
;
}
}
extern
"C"
PyObject
*
PyNumber_ToBase
(
PyObject
*
n
,
int
base
)
noexcept
{
extern
"C"
PyObject
*
PyNumber_ToBase
(
PyObject
*
n
,
int
base
)
noexcept
{
...
@@ -1693,18 +1852,42 @@ extern "C" PyObject* PyNumber_ToBase(PyObject* n, int base) noexcept {
...
@@ -1693,18 +1852,42 @@ extern "C" PyObject* PyNumber_ToBase(PyObject* n, int base) noexcept {
return
nullptr
;
return
nullptr
;
}
}
extern
"C"
Py_ssize_t
PyNumber_AsSsize_t
(
PyObject
*
o
,
PyObject
*
exc
)
noexcept
{
extern
"C"
Py_ssize_t
PyNumber_AsSsize_t
(
PyObject
*
item
,
PyObject
*
err
)
noexcept
{
if
(
isSubclass
(
o
->
cls
,
int_cls
))
{
Py_ssize_t
result
;
int64_t
n
=
static_cast
<
BoxedInt
*>
(
o
)
->
n
;
PyObject
*
runerr
;
static_assert
(
sizeof
(
n
)
==
sizeof
(
Py_ssize_t
),
""
);
PyObject
*
value
=
PyNumber_Index
(
item
);
return
n
;
if
(
value
==
NULL
)
}
else
if
(
isSubclass
(
o
->
cls
,
long_cls
))
{
return
-
1
;
return
PyLong_AsSsize_t
(
o
);
/* We're done if PyInt_AsSsize_t() returns without error. */
result
=
PyInt_AsSsize_t
(
value
);
if
(
result
!=
-
1
||
!
(
runerr
=
PyErr_Occurred
()))
goto
finish
;
/* Error handling code -- only manage OverflowError differently */
if
(
!
PyErr_GivenExceptionMatches
(
runerr
,
PyExc_OverflowError
))
goto
finish
;
PyErr_Clear
();
/* If no error-handling desired then the default clipping
is sufficient.
*/
if
(
!
err
)
{
assert
(
PyLong_Check
(
value
));
/* Whether or not it is less than or equal to
zero is determined by the sign of ob_size
*/
if
(
_PyLong_Sign
(
value
)
<
0
)
result
=
PY_SSIZE_T_MIN
;
else
result
=
PY_SSIZE_T_MAX
;
}
else
{
/* Otherwise replace the error with caller's error object. */
PyErr_Format
(
err
,
"cannot fit '%.200s' into an index-sized integer"
,
item
->
cls
->
tp_name
);
}
}
PyErr_Format
(
PyExc_TypeError
,
"'%.200s' object cannot be interpreted "
finish:
"as an index"
,
Py_DECREF
(
value
);
o
->
cls
->
tp_name
);
return
result
;
return
-
1
;
}
}
}
}
src/codegen/entry.cpp
View file @
f95bd65f
...
@@ -281,7 +281,7 @@ public:
...
@@ -281,7 +281,7 @@ public:
// Generate a hash for the module
// Generate a hash for the module
HashOStream
hash_stream
;
HashOStream
hash_stream
;
M
->
print
(
hash_stream
,
0
);
llvm
::
WriteBitcodeToFile
(
M
,
hash_stream
);
hash_before_codegen
=
hash_stream
.
getHash
();
hash_before_codegen
=
hash_stream
.
getHash
();
llvm
::
SmallString
<
128
>
cache_file
=
cache_dir
;
llvm
::
SmallString
<
128
>
cache_file
=
cache_dir
;
...
...
src/runtime/builtin_modules/builtins.cpp
View file @
f95bd65f
...
@@ -750,6 +750,12 @@ Box* divmod(Box* lhs, Box* rhs) {
...
@@ -750,6 +750,12 @@ Box* divmod(Box* lhs, Box* rhs) {
return
binopInternal
(
lhs
,
rhs
,
AST_TYPE
::
DivMod
,
false
,
NULL
);
return
binopInternal
(
lhs
,
rhs
,
AST_TYPE
::
DivMod
,
false
,
NULL
);
}
}
Box
*
powFunc
(
Box
*
x
,
Box
*
y
,
Box
*
z
)
{
Box
*
rtn
=
PyNumber_Power
(
x
,
y
,
z
);
checkAndThrowCAPIException
();
return
rtn
;
}
Box
*
execfile
(
Box
*
_fn
)
{
Box
*
execfile
(
Box
*
_fn
)
{
// The "globals" and "locals" arguments aren't implemented for now
// The "globals" and "locals" arguments aren't implemented for now
if
(
!
isSubclass
(
_fn
->
cls
,
str_cls
))
{
if
(
!
isSubclass
(
_fn
->
cls
,
str_cls
))
{
...
@@ -1082,6 +1088,8 @@ void setupBuiltins() {
...
@@ -1082,6 +1088,8 @@ void setupBuiltins() {
Box
*
hasattr_obj
=
new
BoxedBuiltinFunctionOrMethod
(
boxRTFunction
((
void
*
)
hasattr
,
BOXED_BOOL
,
2
),
"hasattr"
);
Box
*
hasattr_obj
=
new
BoxedBuiltinFunctionOrMethod
(
boxRTFunction
((
void
*
)
hasattr
,
BOXED_BOOL
,
2
),
"hasattr"
);
builtins_module
->
giveAttr
(
"hasattr"
,
hasattr_obj
);
builtins_module
->
giveAttr
(
"hasattr"
,
hasattr_obj
);
builtins_module
->
giveAttr
(
"pow"
,
new
BoxedBuiltinFunctionOrMethod
(
boxRTFunction
((
void
*
)
powFunc
,
UNKNOWN
,
3
,
1
,
false
,
false
),
"pow"
,
{
None
}));
Box
*
isinstance_obj
Box
*
isinstance_obj
=
new
BoxedBuiltinFunctionOrMethod
(
boxRTFunction
((
void
*
)
isinstance_func
,
BOXED_BOOL
,
2
),
"isinstance"
);
=
new
BoxedBuiltinFunctionOrMethod
(
boxRTFunction
((
void
*
)
isinstance_func
,
BOXED_BOOL
,
2
),
"isinstance"
);
...
...
src/runtime/capi.cpp
View file @
f95bd65f
...
@@ -38,9 +38,9 @@ namespace pyston {
...
@@ -38,9 +38,9 @@ namespace pyston {
BoxedClass
*
method_cls
;
BoxedClass
*
method_cls
;
extern
"C"
bool
_PyIndex_Check
(
PyObject
*
o
p
)
noexcept
{
extern
"C"
bool
_PyIndex_Check
(
PyObject
*
o
bj
)
noexcept
{
// TODO this is wrong (the CPython version checks for things that can be coerced to a number):
return
(
Py_TYPE
(
obj
)
->
tp_as_number
!=
NULL
&&
PyType_HasFeature
(
Py_TYPE
(
obj
),
Py_TPFLAGS_HAVE_INDEX
)
return
PyInt_Check
(
op
);
&&
Py_TYPE
(
obj
)
->
tp_as_number
->
nb_index
!=
NULL
);
}
}
extern
"C"
bool
_PyObject_CheckBuffer
(
PyObject
*
obj
)
noexcept
{
extern
"C"
bool
_PyObject_CheckBuffer
(
PyObject
*
obj
)
noexcept
{
...
...
src/runtime/classobj.cpp
View file @
f95bd65f
...
@@ -488,6 +488,29 @@ static Box* instanceHash(BoxedInstance* inst) {
...
@@ -488,6 +488,29 @@ static Box* instanceHash(BoxedInstance* inst) {
}
}
}
}
static
PyObject
*
instance_index
(
PyObject
*
self
)
noexcept
{
PyObject
*
func
,
*
res
;
/*
static PyObject* indexstr = NULL;
if (indexstr == NULL) {
indexstr = PyString_InternFromString("__index__");
if (indexstr == NULL)
return NULL;
}
*/
if
((
func
=
instance_getattro
(
self
,
boxString
(
"__index__"
)))
==
NULL
)
{
if
(
!
PyErr_ExceptionMatches
(
PyExc_AttributeError
))
return
NULL
;
PyErr_Clear
();
PyErr_SetString
(
PyExc_TypeError
,
"object cannot be interpreted as an index"
);
return
NULL
;
}
res
=
PyEval_CallObject
(
func
,
(
PyObject
*
)
NULL
);
Py_DECREF
(
func
);
return
res
;
}
Box
*
instanceCall
(
Box
*
_inst
,
Box
*
_args
,
Box
*
_kwargs
)
{
Box
*
instanceCall
(
Box
*
_inst
,
Box
*
_args
,
Box
*
_kwargs
)
{
assert
(
_inst
->
cls
==
instance_cls
);
assert
(
_inst
->
cls
==
instance_cls
);
BoxedInstance
*
inst
=
static_cast
<
BoxedInstance
*>
(
_inst
);
BoxedInstance
*
inst
=
static_cast
<
BoxedInstance
*>
(
_inst
);
...
@@ -541,5 +564,6 @@ void setupClassobj() {
...
@@ -541,5 +564,6 @@ void setupClassobj() {
instance_cls
->
freeze
();
instance_cls
->
freeze
();
instance_cls
->
tp_getattro
=
instance_getattro
;
instance_cls
->
tp_getattro
=
instance_getattro
;
instance_cls
->
tp_setattro
=
instance_setattro
;
instance_cls
->
tp_setattro
=
instance_setattro
;
instance_cls
->
tp_as_number
->
nb_index
=
instance_index
;
}
}
}
}
src/runtime/float.cpp
View file @
f95bd65f
...
@@ -390,20 +390,27 @@ extern "C" Box* floatRMod(BoxedFloat* lhs, Box* rhs) {
...
@@ -390,20 +390,27 @@ extern "C" Box* floatRMod(BoxedFloat* lhs, Box* rhs) {
}
}
}
}
extern
"C"
Box
*
floatPowFloat
(
BoxedFloat
*
lhs
,
BoxedFloat
*
rhs
)
{
extern
"C"
Box
*
floatPowFloat
(
BoxedFloat
*
lhs
,
BoxedFloat
*
rhs
,
Box
*
mod
=
None
)
{
assert
(
lhs
->
cls
==
float_cls
);
assert
(
lhs
->
cls
==
float_cls
);
assert
(
rhs
->
cls
==
float_cls
);
assert
(
rhs
->
cls
==
float_cls
);
if
(
mod
!=
None
)
raiseExcHelper
(
TypeError
,
"pow() 3rd argument not allowed unless all arguments are integers"
);
return
boxFloat
(
pow
(
lhs
->
d
,
rhs
->
d
));
return
boxFloat
(
pow
(
lhs
->
d
,
rhs
->
d
));
}
}
extern
"C"
Box
*
floatPowInt
(
BoxedFloat
*
lhs
,
BoxedInt
*
rhs
)
{
extern
"C"
Box
*
floatPowInt
(
BoxedFloat
*
lhs
,
BoxedInt
*
rhs
,
Box
*
mod
=
None
)
{
assert
(
lhs
->
cls
==
float_cls
);
assert
(
lhs
->
cls
==
float_cls
);
assert
(
isSubclass
(
rhs
->
cls
,
int_cls
));
assert
(
isSubclass
(
rhs
->
cls
,
int_cls
));
if
(
mod
!=
None
)
raiseExcHelper
(
TypeError
,
"pow() 3rd argument not allowed unless all arguments are integers"
);
return
boxFloat
(
pow
(
lhs
->
d
,
rhs
->
n
));
return
boxFloat
(
pow
(
lhs
->
d
,
rhs
->
n
));
}
}
extern
"C"
Box
*
floatPow
(
BoxedFloat
*
lhs
,
Box
*
rhs
)
{
extern
"C"
Box
*
floatPow
(
BoxedFloat
*
lhs
,
Box
*
rhs
,
Box
*
mod
)
{
assert
(
lhs
->
cls
==
float_cls
);
assert
(
lhs
->
cls
==
float_cls
);
if
(
mod
!=
None
)
raiseExcHelper
(
TypeError
,
"pow() 3rd argument not allowed unless all arguments are integers"
);
if
(
isSubclass
(
rhs
->
cls
,
int_cls
))
{
if
(
isSubclass
(
rhs
->
cls
,
int_cls
))
{
return
floatPowInt
(
lhs
,
static_cast
<
BoxedInt
*>
(
rhs
));
return
floatPowInt
(
lhs
,
static_cast
<
BoxedInt
*>
(
rhs
));
}
else
if
(
rhs
->
cls
==
float_cls
)
{
}
else
if
(
rhs
->
cls
==
float_cls
)
{
...
@@ -708,6 +715,19 @@ static void _addFunc(const char* name, ConcreteCompilerType* rtn_type, void* flo
...
@@ -708,6 +715,19 @@ static void _addFunc(const char* name, ConcreteCompilerType* rtn_type, void* flo
float_cls
->
giveAttr
(
name
,
new
BoxedFunction
(
cl
));
float_cls
->
giveAttr
(
name
,
new
BoxedFunction
(
cl
));
}
}
static
void
_addFuncPow
(
const
char
*
name
,
ConcreteCompilerType
*
rtn_type
,
void
*
float_func
,
void
*
int_func
,
void
*
boxed_func
)
{
std
::
vector
<
ConcreteCompilerType
*>
v_ffu
{
BOXED_FLOAT
,
BOXED_FLOAT
,
UNKNOWN
};
std
::
vector
<
ConcreteCompilerType
*>
v_fiu
{
BOXED_FLOAT
,
BOXED_INT
,
UNKNOWN
};
std
::
vector
<
ConcreteCompilerType
*>
v_fuu
{
BOXED_FLOAT
,
UNKNOWN
,
UNKNOWN
};
CLFunction
*
cl
=
createRTFunction
(
3
,
1
,
false
,
false
);
addRTFunction
(
cl
,
float_func
,
rtn_type
,
v_ffu
);
addRTFunction
(
cl
,
int_func
,
rtn_type
,
v_fiu
);
addRTFunction
(
cl
,
boxed_func
,
UNKNOWN
,
v_fuu
);
float_cls
->
giveAttr
(
name
,
new
BoxedFunction
(
cl
,
{
None
}));
}
void
setupFloat
()
{
void
setupFloat
()
{
_addFunc
(
"__add__"
,
BOXED_FLOAT
,
(
void
*
)
floatAddFloat
,
(
void
*
)
floatAddInt
,
(
void
*
)
floatAdd
);
_addFunc
(
"__add__"
,
BOXED_FLOAT
,
(
void
*
)
floatAddFloat
,
(
void
*
)
floatAddInt
,
(
void
*
)
floatAdd
);
float_cls
->
giveAttr
(
"__radd__"
,
float_cls
->
getattr
(
"__add__"
));
float_cls
->
giveAttr
(
"__radd__"
,
float_cls
->
getattr
(
"__add__"
));
...
@@ -729,7 +749,7 @@ void setupFloat() {
...
@@ -729,7 +749,7 @@ void setupFloat() {
_addFunc
(
"__mul__"
,
BOXED_FLOAT
,
(
void
*
)
floatMulFloat
,
(
void
*
)
floatMulInt
,
(
void
*
)
floatMul
);
_addFunc
(
"__mul__"
,
BOXED_FLOAT
,
(
void
*
)
floatMulFloat
,
(
void
*
)
floatMulInt
,
(
void
*
)
floatMul
);
float_cls
->
giveAttr
(
"__rmul__"
,
float_cls
->
getattr
(
"__mul__"
));
float_cls
->
giveAttr
(
"__rmul__"
,
float_cls
->
getattr
(
"__mul__"
));
_addFunc
(
"__pow__"
,
BOXED_FLOAT
,
(
void
*
)
floatPowFloat
,
(
void
*
)
floatPowInt
,
(
void
*
)
floatPow
);
_addFunc
Pow
(
"__pow__"
,
BOXED_FLOAT
,
(
void
*
)
floatPowFloat
,
(
void
*
)
floatPowInt
,
(
void
*
)
floatPow
);
_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
);
...
...
src/runtime/import.cpp
View file @
f95bd65f
...
@@ -589,7 +589,9 @@ extern "C" PyObject* PyImport_ImportModule(const char* name) noexcept {
...
@@ -589,7 +589,9 @@ extern "C" PyObject* PyImport_ImportModule(const char* name) noexcept {
try
{
try
{
// TODO: check if this has the same behaviour as the cpython implementation
// TODO: check if this has the same behaviour as the cpython implementation
std
::
string
str
=
name
;
std
::
string
str
=
name
;
return
import
(
0
,
None
,
&
str
);
BoxedList
*
silly_list
=
new
BoxedList
();
listAppendInternal
(
silly_list
,
boxString
(
"__doc__"
));
return
import
(
0
,
silly_list
,
&
str
);
}
catch
(
ExcInfo
e
)
{
}
catch
(
ExcInfo
e
)
{
setCAPIException
(
e
);
setCAPIException
(
e
);
return
NULL
;
return
NULL
;
...
...
src/runtime/inline/xrange.cpp
View file @
f95bd65f
...
@@ -13,6 +13,7 @@
...
@@ -13,6 +13,7 @@
// limitations under the License.
// limitations under the License.
#include "core/types.h"
#include "core/types.h"
#include "runtime/capi.h"
#include "runtime/objmodel.h"
#include "runtime/objmodel.h"
#include "runtime/types.h"
#include "runtime/types.h"
...
@@ -134,25 +135,22 @@ Box* xrange(Box* cls, Box* start, Box* stop, Box** args) {
...
@@ -134,25 +135,22 @@ Box* xrange(Box* cls, Box* start, Box* stop, Box** args) {
Box
*
step
=
args
[
0
];
Box
*
step
=
args
[
0
];
if
(
stop
==
NULL
)
{
if
(
stop
==
NULL
)
{
RELEASE_ASSERT
(
isSubclass
(
start
->
cls
,
int_cls
),
"%s"
,
getTypeName
(
start
));
i64
istop
=
PyLong_AsLong
(
start
);
checkAndThrowCAPIException
();
i64
istop
=
static_cast
<
BoxedInt
*>
(
start
)
->
n
;
return
new
BoxedXrange
(
0
,
istop
,
1
);
return
new
BoxedXrange
(
0
,
istop
,
1
);
}
else
if
(
step
==
NULL
)
{
}
else
if
(
step
==
NULL
)
{
RELEASE_ASSERT
(
isSubclass
(
start
->
cls
,
int_cls
),
"%s"
,
getTypeName
(
start
));
i64
istart
=
PyLong_AsLong
(
start
);
RELEASE_ASSERT
(
isSubclass
(
stop
->
cls
,
int_cls
),
"%s"
,
getTypeName
(
stop
));
checkAndThrowCAPIException
();
i64
istop
=
PyLong_AsLong
(
stop
);
i64
istart
=
static_cast
<
BoxedInt
*>
(
start
)
->
n
;
checkAndThrowCAPIException
();
i64
istop
=
static_cast
<
BoxedInt
*>
(
stop
)
->
n
;
return
new
BoxedXrange
(
istart
,
istop
,
1
);
return
new
BoxedXrange
(
istart
,
istop
,
1
);
}
else
{
}
else
{
RELEASE_ASSERT
(
isSubclass
(
start
->
cls
,
int_cls
),
"%s"
,
getTypeName
(
start
));
i64
istart
=
PyLong_AsLong
(
start
);
RELEASE_ASSERT
(
isSubclass
(
stop
->
cls
,
int_cls
),
"%s"
,
getTypeName
(
stop
));
checkAndThrowCAPIException
();
RELEASE_ASSERT
(
isSubclass
(
step
->
cls
,
int_cls
),
"%s"
,
getTypeName
(
step
));
i64
istop
=
PyLong_AsLong
(
stop
);
checkAndThrowCAPIException
();
i64
istart
=
static_cast
<
BoxedInt
*>
(
start
)
->
n
;
i64
istep
=
PyLong_AsLong
(
step
);
i64
istop
=
static_cast
<
BoxedInt
*>
(
stop
)
->
n
;
checkAndThrowCAPIException
();
i64
istep
=
static_cast
<
BoxedInt
*>
(
step
)
->
n
;
RELEASE_ASSERT
(
istep
!=
0
,
"step can't be 0"
);
RELEASE_ASSERT
(
istep
!=
0
,
"step can't be 0"
);
return
new
BoxedXrange
(
istart
,
istop
,
istep
);
return
new
BoxedXrange
(
istart
,
istop
,
istep
);
}
}
...
...
src/runtime/int.cpp
View file @
f95bd65f
...
@@ -58,8 +58,20 @@ extern "C" long PyInt_AsLong(PyObject* op) noexcept {
...
@@ -58,8 +58,20 @@ extern "C" long PyInt_AsLong(PyObject* op) noexcept {
}
}
extern
"C"
Py_ssize_t
PyInt_AsSsize_t
(
PyObject
*
op
)
noexcept
{
extern
"C"
Py_ssize_t
PyInt_AsSsize_t
(
PyObject
*
op
)
noexcept
{
RELEASE_ASSERT
(
isSubclass
(
op
->
cls
,
int_cls
),
""
);
if
(
op
==
NULL
)
{
return
static_cast
<
BoxedInt
*>
(
op
)
->
n
;
PyErr_SetString
(
PyExc_TypeError
,
"an integer is required"
);
return
-
1
;
}
if
(
PyInt_Check
(
op
))
return
((
BoxedInt
*
)
op
)
->
n
;
if
(
PyLong_Check
(
op
))
return
_PyLong_AsSsize_t
(
op
);
#if SIZEOF_SIZE_T == SIZEOF_LONG
return
PyInt_AsLong
(
op
);
#else
RELEASE_ASSERT
(
"not implemented"
,
""
);
#endif
}
}
extern
"C"
PyObject
*
PyInt_FromSize_t
(
size_t
ival
)
noexcept
{
extern
"C"
PyObject
*
PyInt_FromSize_t
(
size_t
ival
)
noexcept
{
...
@@ -758,14 +770,18 @@ extern "C" Box* intPowFloat(BoxedInt* lhs, BoxedFloat* rhs) {
...
@@ -758,14 +770,18 @@ extern "C" Box* intPowFloat(BoxedInt* lhs, BoxedFloat* rhs) {
return
boxFloat
(
pow
(
lhs
->
n
,
rhs
->
d
));
return
boxFloat
(
pow
(
lhs
->
n
,
rhs
->
d
));
}
}
extern
"C"
Box
*
intPow
(
BoxedInt
*
lhs
,
Box
*
rhs
)
{
extern
"C"
Box
*
intPow
(
BoxedInt
*
lhs
,
Box
*
rhs
,
Box
*
mod
)
{
if
(
!
isSubclass
(
lhs
->
cls
,
int_cls
))
if
(
!
isSubclass
(
lhs
->
cls
,
int_cls
))
raiseExcHelper
(
TypeError
,
"descriptor '__pow__' requires a 'int' object but received a '%s'"
,
getTypeName
(
lhs
));
raiseExcHelper
(
TypeError
,
"descriptor '__pow__' requires a 'int' object but received a '%s'"
,
getTypeName
(
lhs
));
if
(
isSubclass
(
rhs
->
cls
,
int_cls
))
{
if
(
isSubclass
(
rhs
->
cls
,
int_cls
))
{
BoxedInt
*
rhs_int
=
static_cast
<
BoxedInt
*>
(
rhs
);
BoxedInt
*
rhs_int
=
static_cast
<
BoxedInt
*>
(
rhs
);
return
intPowInt
(
lhs
,
rhs_int
);
Box
*
rtn
=
intPowInt
(
lhs
,
rhs_int
);
if
(
mod
==
None
)
return
rtn
;
return
binop
(
rtn
,
mod
,
AST_TYPE
::
Mod
);
}
else
if
(
rhs
->
cls
==
float_cls
)
{
}
else
if
(
rhs
->
cls
==
float_cls
)
{
RELEASE_ASSERT
(
mod
==
None
,
""
);
BoxedFloat
*
rhs_float
=
static_cast
<
BoxedFloat
*>
(
rhs
);
BoxedFloat
*
rhs_float
=
static_cast
<
BoxedFloat
*>
(
rhs
);
return
intPowFloat
(
lhs
,
rhs_float
);
return
intPowFloat
(
lhs
,
rhs_float
);
}
else
{
}
else
{
...
@@ -924,6 +940,12 @@ extern "C" Box* intTrunc(BoxedInt* self) {
...
@@ -924,6 +940,12 @@ extern "C" Box* intTrunc(BoxedInt* self) {
return
self
;
return
self
;
}
}
extern
"C"
Box
*
intIndex
(
BoxedInt
*
v
)
{
if
(
PyInt_CheckExact
(
v
))
return
v
;
return
boxInt
(
v
->
n
);
}
static
Box
*
_intNew
(
Box
*
val
,
Box
*
base
)
{
static
Box
*
_intNew
(
Box
*
val
,
Box
*
base
)
{
if
(
isSubclass
(
val
->
cls
,
int_cls
))
{
if
(
isSubclass
(
val
->
cls
,
int_cls
))
{
RELEASE_ASSERT
(
!
base
,
""
);
RELEASE_ASSERT
(
!
base
,
""
);
...
@@ -1057,7 +1079,8 @@ void setupInt() {
...
@@ -1057,7 +1079,8 @@ void setupInt() {
_addFuncIntFloatUnknown
(
"__truediv__"
,
(
void
*
)
intTruedivInt
,
(
void
*
)
intTruedivFloat
,
(
void
*
)
intTruediv
);
_addFuncIntFloatUnknown
(
"__truediv__"
,
(
void
*
)
intTruedivInt
,
(
void
*
)
intTruedivFloat
,
(
void
*
)
intTruediv
);
_addFuncIntFloatUnknown
(
"__mul__"
,
(
void
*
)
intMulInt
,
(
void
*
)
intMulFloat
,
(
void
*
)
intMul
);
_addFuncIntFloatUnknown
(
"__mul__"
,
(
void
*
)
intMulInt
,
(
void
*
)
intMulFloat
,
(
void
*
)
intMul
);
_addFuncIntUnknown
(
"__mod__"
,
BOXED_INT
,
(
void
*
)
intModInt
,
(
void
*
)
intMod
);
_addFuncIntUnknown
(
"__mod__"
,
BOXED_INT
,
(
void
*
)
intModInt
,
(
void
*
)
intMod
);
_addFuncIntFloatUnknown
(
"__pow__"
,
(
void
*
)
intPowInt
,
(
void
*
)
intPowFloat
,
(
void
*
)
intPow
);
int_cls
->
giveAttr
(
"__pow__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
intPow
,
UNKNOWN
,
3
,
1
,
false
,
false
),
{
None
}));
_addFuncIntUnknown
(
"__eq__"
,
BOXED_BOOL
,
(
void
*
)
intEqInt
,
(
void
*
)
intEq
);
_addFuncIntUnknown
(
"__eq__"
,
BOXED_BOOL
,
(
void
*
)
intEqInt
,
(
void
*
)
intEq
);
_addFuncIntUnknown
(
"__ne__"
,
BOXED_BOOL
,
(
void
*
)
intNeInt
,
(
void
*
)
intNe
);
_addFuncIntUnknown
(
"__ne__"
,
BOXED_BOOL
,
(
void
*
)
intNeInt
,
(
void
*
)
intNe
);
...
@@ -1081,6 +1104,7 @@ void setupInt() {
...
@@ -1081,6 +1104,7 @@ void setupInt() {
int_cls
->
giveAttr
(
"__oct__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
intOct
,
STR
,
1
)));
int_cls
->
giveAttr
(
"__oct__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
intOct
,
STR
,
1
)));
int_cls
->
giveAttr
(
"__trunc__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
intTrunc
,
BOXED_INT
,
1
)));
int_cls
->
giveAttr
(
"__trunc__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
intTrunc
,
BOXED_INT
,
1
)));
int_cls
->
giveAttr
(
"__index__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
intIndex
,
BOXED_INT
,
1
)));
int_cls
->
giveAttr
(
int_cls
->
giveAttr
(
"__new__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
intNew
,
UNKNOWN
,
3
,
2
,
false
,
false
),
{
boxInt
(
0
),
NULL
}));
"__new__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
intNew
,
UNKNOWN
,
3
,
2
,
false
,
false
),
{
boxInt
(
0
),
NULL
}));
...
...
src/runtime/list.cpp
View file @
f95bd65f
...
@@ -192,8 +192,11 @@ extern "C" Box* listGetitemSlice(BoxedList* self, BoxedSlice* slice) {
...
@@ -192,8 +192,11 @@ extern "C" Box* listGetitemSlice(BoxedList* self, BoxedSlice* slice) {
extern
"C"
Box
*
listGetitem
(
BoxedList
*
self
,
Box
*
slice
)
{
extern
"C"
Box
*
listGetitem
(
BoxedList
*
self
,
Box
*
slice
)
{
assert
(
isSubclass
(
self
->
cls
,
list_cls
));
assert
(
isSubclass
(
self
->
cls
,
list_cls
));
if
(
isSubclass
(
slice
->
cls
,
int_cls
))
{
if
(
PyIndex_Check
(
slice
))
{
return
listGetitemInt
(
self
,
static_cast
<
BoxedInt
*>
(
slice
));
Py_ssize_t
i
=
PyNumber_AsSsize_t
(
slice
,
PyExc_IndexError
);
if
(
i
==
-
1
&&
PyErr_Occurred
())
throwCAPIException
();
return
listGetitemUnboxed
(
self
,
i
);
}
else
if
(
slice
->
cls
==
slice_cls
)
{
}
else
if
(
slice
->
cls
==
slice_cls
)
{
return
listGetitemSlice
(
self
,
static_cast
<
BoxedSlice
*>
(
slice
));
return
listGetitemSlice
(
self
,
static_cast
<
BoxedSlice
*>
(
slice
));
}
else
{
}
else
{
...
@@ -212,23 +215,23 @@ static void _listSetitem(BoxedList* self, int64_t n, Box* v) {
...
@@ -212,23 +215,23 @@ static void _listSetitem(BoxedList* self, int64_t n, Box* v) {
self
->
elts
->
elts
[
n
]
=
v
;
self
->
elts
->
elts
[
n
]
=
v
;
}
}
extern
"C"
Box
*
listSetitem
Int
(
BoxedList
*
self
,
BoxedInt
*
slice
,
Box
*
v
)
{
extern
"C"
Box
*
listSetitem
Unboxed
(
BoxedList
*
self
,
int64_t
n
,
Box
*
v
)
{
// I think r lock is ok here, since we don't change the list structure:
// I think r lock is ok here, since we don't change the list structure:
LOCK_REGION
(
self
->
lock
.
asRead
());
LOCK_REGION
(
self
->
lock
.
asRead
());
assert
(
isSubclass
(
self
->
cls
,
list_cls
));
assert
(
isSubclass
(
self
->
cls
,
list_cls
));
assert
(
isSubclass
(
slice
->
cls
,
int_cls
));
int64_t
n
=
slice
->
n
;
_listSetitem
(
self
,
n
,
v
);
_listSetitem
(
self
,
n
,
v
);
return
None
;
return
None
;
}
}
extern
"C"
Box
*
listSetitemInt
(
BoxedList
*
self
,
BoxedInt
*
slice
,
Box
*
v
)
{
assert
(
isSubclass
(
slice
->
cls
,
int_cls
));
return
listSetitemUnboxed
(
self
,
slice
->
n
,
v
);
}
extern
"C"
int
PyList_SetItem
(
PyObject
*
op
,
Py_ssize_t
i
,
PyObject
*
newitem
)
noexcept
{
extern
"C"
int
PyList_SetItem
(
PyObject
*
op
,
Py_ssize_t
i
,
PyObject
*
newitem
)
noexcept
{
assert
(
isSubclass
(
op
->
cls
,
list_cls
));
assert
(
isSubclass
(
op
->
cls
,
list_cls
));
try
{
try
{
_listSetitem
(
static_cast
<
BoxedList
*>
(
op
),
i
,
newitem
);
listSetitemUnboxed
(
static_cast
<
BoxedList
*>
(
op
),
i
,
newitem
);
}
catch
(
ExcInfo
e
)
{
}
catch
(
ExcInfo
e
)
{
abort
();
abort
();
}
}
...
@@ -460,8 +463,12 @@ extern "C" Box* listSetitemSlice(BoxedList* self, BoxedSlice* slice, Box* v) {
...
@@ -460,8 +463,12 @@ extern "C" Box* listSetitemSlice(BoxedList* self, BoxedSlice* slice, Box* v) {
extern
"C"
Box
*
listSetitem
(
BoxedList
*
self
,
Box
*
slice
,
Box
*
v
)
{
extern
"C"
Box
*
listSetitem
(
BoxedList
*
self
,
Box
*
slice
,
Box
*
v
)
{
assert
(
isSubclass
(
self
->
cls
,
list_cls
));
assert
(
isSubclass
(
self
->
cls
,
list_cls
));
if
(
isSubclass
(
slice
->
cls
,
int_cls
))
{
if
(
PyIndex_Check
(
slice
))
{
return
listSetitemInt
(
self
,
static_cast
<
BoxedInt
*>
(
slice
),
v
);
Py_ssize_t
i
=
PyNumber_AsSsize_t
(
slice
,
PyExc_IndexError
);
if
(
i
==
-
1
&&
PyErr_Occurred
())
throwCAPIException
();
listSetitemUnboxed
(
self
,
i
,
v
);
return
None
;
}
else
if
(
slice
->
cls
==
slice_cls
)
{
}
else
if
(
slice
->
cls
==
slice_cls
)
{
return
listSetitemSlice
(
self
,
static_cast
<
BoxedSlice
*>
(
slice
),
v
);
return
listSetitemSlice
(
self
,
static_cast
<
BoxedSlice
*>
(
slice
),
v
);
}
else
{
}
else
{
...
@@ -492,9 +499,11 @@ extern "C" Box* listDelitem(BoxedList* self, Box* slice) {
...
@@ -492,9 +499,11 @@ extern "C" Box* listDelitem(BoxedList* self, Box* slice) {
LOCK_REGION
(
self
->
lock
.
asWrite
());
LOCK_REGION
(
self
->
lock
.
asWrite
());
Box
*
rtn
;
Box
*
rtn
;
if
(
PyIndex_Check
(
slice
))
{
if
(
isSubclass
(
slice
->
cls
,
int_cls
))
{
Py_ssize_t
i
=
PyNumber_AsSsize_t
(
slice
,
PyExc_IndexError
);
rtn
=
listDelitemInt
(
self
,
static_cast
<
BoxedInt
*>
(
slice
));
if
(
i
==
-
1
&&
PyErr_Occurred
())
throwCAPIException
();
rtn
=
listDelitemInt
(
self
,
(
BoxedInt
*
)
boxInt
(
i
));
}
else
if
(
slice
->
cls
==
slice_cls
)
{
}
else
if
(
slice
->
cls
==
slice_cls
)
{
rtn
=
listDelitemSlice
(
self
,
static_cast
<
BoxedSlice
*>
(
slice
));
rtn
=
listDelitemSlice
(
self
,
static_cast
<
BoxedSlice
*>
(
slice
));
}
else
{
}
else
{
...
...
src/runtime/long.cpp
View file @
f95bd65f
...
@@ -25,6 +25,7 @@
...
@@ -25,6 +25,7 @@
#include "core/stats.h"
#include "core/stats.h"
#include "core/types.h"
#include "core/types.h"
#include "gc/collector.h"
#include "gc/collector.h"
#include "runtime/capi.h"
#include "runtime/inline/boxing.h"
#include "runtime/inline/boxing.h"
#include "runtime/objmodel.h"
#include "runtime/objmodel.h"
#include "runtime/types.h"
#include "runtime/types.h"
...
@@ -104,12 +105,58 @@ extern "C" PY_LONG_LONG PyLong_AsLongLongAndOverflow(PyObject* obj, int* overflo
...
@@ -104,12 +105,58 @@ extern "C" PY_LONG_LONG PyLong_AsLongLongAndOverflow(PyObject* obj, int* overflo
extern
"C"
PyObject
*
PyLong_FromString
(
const
char
*
str
,
char
**
pend
,
int
base
)
noexcept
{
extern
"C"
PyObject
*
PyLong_FromString
(
const
char
*
str
,
char
**
pend
,
int
base
)
noexcept
{
RELEASE_ASSERT
(
pend
==
NULL
,
"unsupported"
);
RELEASE_ASSERT
(
pend
==
NULL
,
"unsupported"
);
// See comment in _longNew
int
sign
=
1
;
RELEASE_ASSERT
(
base
>=
0
,
"unsupported"
);
if
((
base
!=
0
&&
base
<
2
)
||
base
>
36
)
{
PyErr_SetString
(
PyExc_ValueError
,
"long() arg 2 must be >= 2 and <= 36"
);
return
NULL
;
}
while
(
*
str
!=
'\0'
&&
isspace
(
Py_CHARMASK
(
*
str
)))
str
++
;
if
(
*
str
==
'+'
)
++
str
;
else
if
(
*
str
==
'-'
)
{
++
str
;
sign
=
-
1
;
}
while
(
*
str
!=
'\0'
&&
isspace
(
Py_CHARMASK
(
*
str
)))
str
++
;
if
(
base
==
0
)
{
/* No base given. Deduce the base from the contents
of the string */
if
(
str
[
0
]
!=
'0'
)
base
=
10
;
else
if
(
str
[
1
]
==
'x'
||
str
[
1
]
==
'X'
)
base
=
16
;
else
if
(
str
[
1
]
==
'o'
||
str
[
1
]
==
'O'
)
base
=
8
;
else
if
(
str
[
1
]
==
'b'
||
str
[
1
]
==
'B'
)
base
=
2
;
else
/* "old" (C-style) octal literal, still valid in
2.x, although illegal in 3.x */
base
=
8
;
}
/* Whether or not we were deducing the base, skip leading chars
as needed */
if
(
str
[
0
]
==
'0'
&&
((
base
==
16
&&
(
str
[
1
]
==
'x'
||
str
[
1
]
==
'X'
))
||
(
base
==
8
&&
(
str
[
1
]
==
'o'
||
str
[
1
]
==
'O'
))
||
(
base
==
2
&&
(
str
[
1
]
==
'b'
||
str
[
1
]
==
'B'
))))
str
+=
2
;
BoxedLong
*
rtn
=
new
BoxedLong
();
BoxedLong
*
rtn
=
new
BoxedLong
();
int
r
=
mpz_init_set_str
(
rtn
->
n
,
str
,
base
);
if
(
str
[
strlen
(
str
)
-
1
]
==
'L'
)
{
RELEASE_ASSERT
(
r
==
0
,
""
);
std
::
string
without_l
(
str
,
strlen
(
str
)
-
1
);
int
r
=
mpz_init_set_str
(
rtn
->
n
,
without_l
.
c_str
(),
base
);
RELEASE_ASSERT
(
r
==
0
,
""
);
}
else
{
int
r
=
mpz_init_set_str
(
rtn
->
n
,
str
,
base
);
RELEASE_ASSERT
(
r
==
0
,
""
);
}
if
(
sign
==
-
1
)
mpz_neg
(
rtn
->
n
,
rtn
->
n
);
return
rtn
;
return
rtn
;
}
}
...
@@ -441,18 +488,8 @@ BoxedLong* _longNew(Box* val, Box* _base) {
...
@@ -441,18 +488,8 @@ BoxedLong* _longNew(Box* val, Box* _base) {
raiseExcHelper
(
TypeError
,
"long() can't convert non-string with explicit base"
);
raiseExcHelper
(
TypeError
,
"long() can't convert non-string with explicit base"
);
BoxedString
*
s
=
static_cast
<
BoxedString
*>
(
val
);
BoxedString
*
s
=
static_cast
<
BoxedString
*>
(
val
);
if
(
base
==
0
)
{
rtn
=
(
BoxedLong
*
)
PyLong_FromString
(
s
->
s
.
str
().
c_str
(),
NULL
,
base
);
// mpz_init_set_str has the ability to auto-detect the base, but I doubt it's
checkAndThrowCAPIException
();
// quite the same as Python's (ex might be missing octal or binary)
Py_FatalError
(
"unimplemented"
);
}
if
(
base
<
2
||
base
>
36
)
{
raiseExcHelper
(
TypeError
,
"long() arg2 must be >= 2 and <= 36"
);
}
int
r
=
mpz_init_set_str
(
rtn
->
n
,
s
->
data
(),
base
);
RELEASE_ASSERT
(
r
==
0
,
""
);
}
else
{
}
else
{
if
(
isSubclass
(
val
->
cls
,
long_cls
))
{
if
(
isSubclass
(
val
->
cls
,
long_cls
))
{
BoxedLong
*
l
=
static_cast
<
BoxedLong
*>
(
val
);
BoxedLong
*
l
=
static_cast
<
BoxedLong
*>
(
val
);
...
@@ -920,6 +957,51 @@ Box* longDiv(BoxedLong* v1, Box* _v2) {
...
@@ -920,6 +957,51 @@ Box* longDiv(BoxedLong* v1, Box* _v2) {
}
}
}
}
Box
*
longMod
(
BoxedLong
*
v1
,
Box
*
_v2
)
{
if
(
!
isSubclass
(
v1
->
cls
,
long_cls
))
raiseExcHelper
(
TypeError
,
"descriptor '__mod__' requires a 'long' object but received a '%s'"
,
getTypeName
(
v1
));
if
(
isSubclass
(
_v2
->
cls
,
long_cls
))
{
BoxedLong
*
v2
=
static_cast
<
BoxedLong
*>
(
_v2
);
if
(
mpz_cmp_si
(
v2
->
n
,
0
)
==
0
)
raiseExcHelper
(
ZeroDivisionError
,
"long division or modulo by zero"
);
BoxedLong
*
r
=
new
BoxedLong
();
mpz_init
(
r
->
n
);
mpz_mmod
(
r
->
n
,
v1
->
n
,
v2
->
n
);
return
r
;
}
else
if
(
isSubclass
(
_v2
->
cls
,
int_cls
))
{
BoxedInt
*
v2
=
static_cast
<
BoxedInt
*>
(
_v2
);
if
(
v2
->
n
==
0
)
raiseExcHelper
(
ZeroDivisionError
,
"long division or modulo by zero"
);
BoxedLong
*
r
=
new
BoxedLong
();
mpz_init_set_si
(
r
->
n
,
v2
->
n
);
mpz_mmod
(
r
->
n
,
v1
->
n
,
r
->
n
);
return
r
;
}
else
{
return
NotImplemented
;
}
}
Box
*
longRMod
(
BoxedLong
*
v1
,
Box
*
_v2
)
{
if
(
!
isSubclass
(
v1
->
cls
,
long_cls
))
raiseExcHelper
(
TypeError
,
"descriptor '__rmod__' requires a 'long' object but received a '%s'"
,
getTypeName
(
v1
));
Box
*
lhs
=
_v2
;
BoxedLong
*
rhs
=
v1
;
if
(
isSubclass
(
lhs
->
cls
,
long_cls
))
{
return
longMod
((
BoxedLong
*
)
lhs
,
rhs
);
}
else
if
(
isSubclass
(
lhs
->
cls
,
int_cls
))
{
return
longMod
(
boxLong
(((
BoxedInt
*
)
lhs
)
->
n
),
rhs
);
}
else
{
return
NotImplemented
;
}
}
extern
"C"
Box
*
longDivmod
(
BoxedLong
*
lhs
,
Box
*
_rhs
)
{
extern
"C"
Box
*
longDivmod
(
BoxedLong
*
lhs
,
Box
*
_rhs
)
{
if
(
!
isSubclass
(
lhs
->
cls
,
long_cls
))
if
(
!
isSubclass
(
lhs
->
cls
,
long_cls
))
raiseExcHelper
(
TypeError
,
"descriptor '__div__' requires a 'long' object but received a '%s'"
,
raiseExcHelper
(
TypeError
,
"descriptor '__div__' requires a 'long' object but received a '%s'"
,
...
@@ -1018,27 +1100,45 @@ Box* longRTrueDiv(BoxedLong* v1, Box* _v2) {
...
@@ -1018,27 +1100,45 @@ Box* longRTrueDiv(BoxedLong* v1, Box* _v2) {
return
boxFloat
(
lhs
/
(
double
)
rhs
);
return
boxFloat
(
lhs
/
(
double
)
rhs
);
}
}
Box
*
longPow
(
BoxedLong
*
v1
,
Box
*
_v2
)
{
Box
*
longPow
(
BoxedLong
*
v1
,
Box
*
_v2
,
Box
*
_v3
)
{
if
(
!
isSubclass
(
v1
->
cls
,
long_cls
))
if
(
!
isSubclass
(
v1
->
cls
,
long_cls
))
raiseExcHelper
(
TypeError
,
"descriptor '__pow__' requires a 'long' object but received a '%s'"
,
getTypeName
(
v1
));
raiseExcHelper
(
TypeError
,
"descriptor '__pow__' requires a 'long' object but received a '%s'"
,
getTypeName
(
v1
));
BoxedLong
*
mod
=
nullptr
;
if
(
_v3
!=
None
)
{
if
(
isSubclass
(
_v3
->
cls
,
int_cls
))
mod
=
boxLong
(((
BoxedInt
*
)
_v3
)
->
n
);
else
{
RELEASE_ASSERT
(
_v3
->
cls
==
long_cls
,
""
);
mod
=
(
BoxedLong
*
)
_v3
;
}
RELEASE_ASSERT
(
mpz_sgn
(
mod
->
n
)
>=
0
,
""
);
}
if
(
isSubclass
(
_v2
->
cls
,
long_cls
))
{
if
(
isSubclass
(
_v2
->
cls
,
long_cls
))
{
BoxedLong
*
v2
=
static_cast
<
BoxedLong
*>
(
_v2
);
BoxedLong
*
v2
=
static_cast
<
BoxedLong
*>
(
_v2
);
BoxedLong
*
r
=
new
BoxedLong
();
mpz_init
(
r
->
n
);
RELEASE_ASSERT
(
mpz_sgn
(
v2
->
n
)
>=
0
,
""
);
RELEASE_ASSERT
(
mpz_sgn
(
v2
->
n
)
>=
0
,
""
);
RELEASE_ASSERT
(
mpz_fits_ulong_p
(
v2
->
n
),
""
);
uint64_t
n2
=
mpz_get_ui
(
v2
->
n
);
BoxedLong
*
r
=
new
BoxedLong
();
if
(
mod
)
{
mpz_init
(
r
->
n
);
mpz_powm
(
r
->
n
,
v1
->
n
,
v2
->
n
,
mod
->
n
);
mpz_pow_ui
(
r
->
n
,
v1
->
n
,
n2
);
}
else
{
RELEASE_ASSERT
(
mpz_fits_ulong_p
(
v2
->
n
),
""
);
uint64_t
n2
=
mpz_get_ui
(
v2
->
n
);
mpz_pow_ui
(
r
->
n
,
v1
->
n
,
n2
);
}
return
r
;
return
r
;
}
else
if
(
isSubclass
(
_v2
->
cls
,
int_cls
))
{
}
else
if
(
isSubclass
(
_v2
->
cls
,
int_cls
))
{
BoxedInt
*
v2
=
static_cast
<
BoxedInt
*>
(
_v2
);
BoxedInt
*
v2
=
static_cast
<
BoxedInt
*>
(
_v2
);
RELEASE_ASSERT
(
v2
->
n
>=
0
,
""
);
RELEASE_ASSERT
(
v2
->
n
>=
0
,
""
);
BoxedLong
*
r
=
new
BoxedLong
();
BoxedLong
*
r
=
new
BoxedLong
();
mpz_init
(
r
->
n
);
mpz_init
(
r
->
n
);
mpz_pow_ui
(
r
->
n
,
v1
->
n
,
v2
->
n
);
if
(
mod
)
mpz_powm_ui
(
r
->
n
,
v1
->
n
,
v2
->
n
,
mod
->
n
);
else
mpz_pow_ui
(
r
->
n
,
v1
->
n
,
v2
->
n
);
return
r
;
return
r
;
}
else
{
}
else
{
return
NotImplemented
;
return
NotImplemented
;
...
@@ -1101,6 +1201,53 @@ void customised_free(void* ptr, size_t size) {
...
@@ -1101,6 +1201,53 @@ void customised_free(void* ptr, size_t size) {
gc
::
gc_free
(
ptr
);
gc
::
gc_free
(
ptr
);
}
}
extern
"C"
Box
*
longIndex
(
BoxedLong
*
v
)
noexcept
{
if
(
PyLong_CheckExact
(
v
))
return
v
;
BoxedLong
*
rtn
=
new
BoxedLong
();
mpz_init_set
(
rtn
->
n
,
v
->
n
);
return
rtn
;
}
static
int
convert_binop
(
PyObject
*
v
,
PyObject
*
w
,
PyLongObject
**
a
,
PyLongObject
**
b
)
noexcept
{
if
(
PyLong_Check
(
v
))
{
*
a
=
(
PyLongObject
*
)
v
;
Py_INCREF
(
v
);
}
else
if
(
PyInt_Check
(
v
))
{
*
a
=
(
PyLongObject
*
)
PyLong_FromLong
(
PyInt_AS_LONG
(
v
));
}
else
{
return
0
;
}
if
(
PyLong_Check
(
w
))
{
*
b
=
(
PyLongObject
*
)
w
;
Py_INCREF
(
w
);
}
else
if
(
PyInt_Check
(
w
))
{
*
b
=
(
PyLongObject
*
)
PyLong_FromLong
(
PyInt_AS_LONG
(
w
));
}
else
{
Py_DECREF
(
*
a
);
return
0
;
}
return
1
;
}
#define CONVERT_BINOP(v, w, a, b) \
do { \
if (!convert_binop(v, w, a, b)) { \
Py_INCREF(Py_NotImplemented); \
return Py_NotImplemented; \
} \
} while (0)
static
PyObject
*
long_pow
(
PyObject
*
v
,
PyObject
*
w
,
PyObject
*
x
)
noexcept
{
try
{
PyLongObject
*
a
,
*
b
;
CONVERT_BINOP
(
v
,
w
,
&
a
,
&
b
);
return
longPow
((
BoxedLong
*
)
a
,
(
BoxedLong
*
)
b
,
x
);
}
catch
(
ExcInfo
e
)
{
abort
();
}
}
void
setupLong
()
{
void
setupLong
()
{
mp_set_memory_functions
(
customised_allocation
,
customised_realloc
,
customised_free
);
mp_set_memory_functions
(
customised_allocation
,
customised_realloc
,
customised_free
);
...
@@ -1114,6 +1261,8 @@ void setupLong() {
...
@@ -1114,6 +1261,8 @@ void setupLong() {
long_cls
->
giveAttr
(
"__rdiv__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
longRdiv
,
UNKNOWN
,
2
)));
long_cls
->
giveAttr
(
"__rdiv__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
longRdiv
,
UNKNOWN
,
2
)));
long_cls
->
giveAttr
(
"__truediv__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
longTrueDiv
,
UNKNOWN
,
2
)));
long_cls
->
giveAttr
(
"__truediv__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
longTrueDiv
,
UNKNOWN
,
2
)));
long_cls
->
giveAttr
(
"__rtruediv__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
longRTrueDiv
,
UNKNOWN
,
2
)));
long_cls
->
giveAttr
(
"__rtruediv__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
longRTrueDiv
,
UNKNOWN
,
2
)));
long_cls
->
giveAttr
(
"__mod__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
longMod
,
UNKNOWN
,
2
)));
long_cls
->
giveAttr
(
"__rmod__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
longRMod
,
UNKNOWN
,
2
)));
long_cls
->
giveAttr
(
"__divmod__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
longDivmod
,
UNKNOWN
,
2
)));
long_cls
->
giveAttr
(
"__divmod__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
longDivmod
,
UNKNOWN
,
2
)));
...
@@ -1123,7 +1272,8 @@ void setupLong() {
...
@@ -1123,7 +1272,8 @@ void setupLong() {
long_cls
->
giveAttr
(
"__add__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
longAdd
,
UNKNOWN
,
2
)));
long_cls
->
giveAttr
(
"__add__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
longAdd
,
UNKNOWN
,
2
)));
long_cls
->
giveAttr
(
"__radd__"
,
long_cls
->
getattr
(
"__add__"
));
long_cls
->
giveAttr
(
"__radd__"
,
long_cls
->
getattr
(
"__add__"
));
long_cls
->
giveAttr
(
"__pow__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
longPow
,
UNKNOWN
,
2
)));
long_cls
->
giveAttr
(
"__pow__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
longPow
,
UNKNOWN
,
3
,
1
,
false
,
false
),
{
None
}));
long_cls
->
giveAttr
(
"__and__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
longAnd
,
UNKNOWN
,
2
)));
long_cls
->
giveAttr
(
"__and__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
longAnd
,
UNKNOWN
,
2
)));
long_cls
->
giveAttr
(
"__rand__"
,
long_cls
->
getattr
(
"__and__"
));
long_cls
->
giveAttr
(
"__rand__"
,
long_cls
->
getattr
(
"__and__"
));
...
@@ -1154,7 +1304,10 @@ void setupLong() {
...
@@ -1154,7 +1304,10 @@ void setupLong() {
long_cls
->
giveAttr
(
"__hash__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
longHash
,
BOXED_INT
,
1
)));
long_cls
->
giveAttr
(
"__hash__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
longHash
,
BOXED_INT
,
1
)));
long_cls
->
giveAttr
(
"__trunc__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
longTrunc
,
UNKNOWN
,
1
)));
long_cls
->
giveAttr
(
"__trunc__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
longTrunc
,
UNKNOWN
,
1
)));
long_cls
->
giveAttr
(
"__index__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
longIndex
,
LONG
,
1
)));
long_cls
->
freeze
();
long_cls
->
freeze
();
long_cls
->
tp_as_number
->
nb_power
=
long_pow
;
}
}
}
}
src/runtime/long.h
View file @
f95bd65f
...
@@ -47,7 +47,7 @@ Box* longAdd(BoxedLong* lhs, Box* rhs);
...
@@ -47,7 +47,7 @@ Box* longAdd(BoxedLong* lhs, Box* rhs);
Box
*
longSub
(
BoxedLong
*
lhs
,
Box
*
rhs
);
Box
*
longSub
(
BoxedLong
*
lhs
,
Box
*
rhs
);
Box
*
longMul
(
BoxedLong
*
lhs
,
Box
*
rhs
);
Box
*
longMul
(
BoxedLong
*
lhs
,
Box
*
rhs
);
Box
*
longDiv
(
BoxedLong
*
lhs
,
Box
*
rhs
);
Box
*
longDiv
(
BoxedLong
*
lhs
,
Box
*
rhs
);
Box
*
longPow
(
BoxedLong
*
lhs
,
Box
*
rhs
);
Box
*
longPow
(
BoxedLong
*
lhs
,
Box
*
rhs
,
Box
*
mod
=
None
);
Box
*
longLshift
(
BoxedLong
*
lhs
,
Box
*
rhs
);
Box
*
longLshift
(
BoxedLong
*
lhs
,
Box
*
rhs
);
Box
*
longRshift
(
BoxedLong
*
lhs
,
Box
*
rhs
);
Box
*
longRshift
(
BoxedLong
*
lhs
,
Box
*
rhs
);
...
...
src/runtime/objmodel.cpp
View file @
f95bd65f
...
@@ -326,6 +326,7 @@ BoxedClass::BoxedClass(BoxedClass* base, gcvisit_func gc_visit, int attrs_offset
...
@@ -326,6 +326,7 @@ BoxedClass::BoxedClass(BoxedClass* base, gcvisit_func gc_visit, int attrs_offset
tp_flags
|=
Py_TPFLAGS_HAVE_GC
;
tp_flags
|=
Py_TPFLAGS_HAVE_GC
;
tp_flags
|=
Py_TPFLAGS_HAVE_WEAKREFS
;
tp_flags
|=
Py_TPFLAGS_HAVE_WEAKREFS
;
tp_flags
|=
Py_TPFLAGS_HAVE_RICHCOMPARE
;
tp_flags
|=
Py_TPFLAGS_HAVE_RICHCOMPARE
;
tp_flags
|=
Py_TPFLAGS_HAVE_INDEX
;
if
(
base
&&
(
base
->
tp_flags
&
Py_TPFLAGS_HAVE_NEWBUFFER
))
if
(
base
&&
(
base
->
tp_flags
&
Py_TPFLAGS_HAVE_NEWBUFFER
))
tp_flags
|=
Py_TPFLAGS_HAVE_NEWBUFFER
;
tp_flags
|=
Py_TPFLAGS_HAVE_NEWBUFFER
;
...
...
src/runtime/str.cpp
View file @
f95bd65f
...
@@ -2240,9 +2240,10 @@ Box* strEncode(BoxedString* self, Box* encoding, Box* error) {
...
@@ -2240,9 +2240,10 @@ Box* strEncode(BoxedString* self, Box* encoding, Box* error) {
extern
"C"
Box
*
strGetitem
(
BoxedString
*
self
,
Box
*
slice
)
{
extern
"C"
Box
*
strGetitem
(
BoxedString
*
self
,
Box
*
slice
)
{
assert
(
isSubclass
(
self
->
cls
,
str_cls
));
assert
(
isSubclass
(
self
->
cls
,
str_cls
));
if
(
isSubclass
(
slice
->
cls
,
int_cls
))
{
if
(
PyIndex_Check
(
slice
))
{
BoxedInt
*
islice
=
static_cast
<
BoxedInt
*>
(
slice
);
Py_ssize_t
n
=
PyNumber_AsSsize_t
(
slice
,
PyExc_IndexError
);
int64_t
n
=
islice
->
n
;
if
(
n
==
-
1
&&
PyErr_Occurred
())
throwCAPIException
();
int
size
=
self
->
size
();
int
size
=
self
->
size
();
if
(
n
<
0
)
if
(
n
<
0
)
n
=
size
+
n
;
n
=
size
+
n
;
...
...
src/runtime/tuple.cpp
View file @
f95bd65f
...
@@ -23,6 +23,7 @@
...
@@ -23,6 +23,7 @@
#include "core/stats.h"
#include "core/stats.h"
#include "core/types.h"
#include "core/types.h"
#include "gc/collector.h"
#include "gc/collector.h"
#include "runtime/capi.h"
#include "runtime/objmodel.h"
#include "runtime/objmodel.h"
#include "runtime/types.h"
#include "runtime/types.h"
#include "runtime/util.h"
#include "runtime/util.h"
...
@@ -146,9 +147,12 @@ int BoxedTuple::Resize(BoxedTuple** pv, size_t newsize) noexcept {
...
@@ -146,9 +147,12 @@ int BoxedTuple::Resize(BoxedTuple** pv, size_t newsize) noexcept {
Box
*
tupleGetitem
(
BoxedTuple
*
self
,
Box
*
slice
)
{
Box
*
tupleGetitem
(
BoxedTuple
*
self
,
Box
*
slice
)
{
assert
(
self
->
cls
==
tuple_cls
);
assert
(
self
->
cls
==
tuple_cls
);
if
(
isSubclass
(
slice
->
cls
,
int_cls
))
if
(
PyIndex_Check
(
slice
))
{
return
tupleGetitemInt
(
self
,
static_cast
<
BoxedInt
*>
(
slice
));
Py_ssize_t
i
=
PyNumber_AsSsize_t
(
slice
,
PyExc_IndexError
);
else
if
(
slice
->
cls
==
slice_cls
)
if
(
i
==
-
1
&&
PyErr_Occurred
())
throwCAPIException
();
return
tupleGetitemUnboxed
(
self
,
i
);
}
else
if
(
slice
->
cls
==
slice_cls
)
return
tupleGetitemSlice
(
self
,
static_cast
<
BoxedSlice
*>
(
slice
));
return
tupleGetitemSlice
(
self
,
static_cast
<
BoxedSlice
*>
(
slice
));
else
else
raiseExcHelper
(
TypeError
,
"tuple indices must be integers, not %s"
,
getTypeName
(
slice
));
raiseExcHelper
(
TypeError
,
"tuple indices must be integers, not %s"
,
getTypeName
(
slice
));
...
...
src/runtime/types.cpp
View file @
f95bd65f
...
@@ -956,16 +956,61 @@ extern "C" int PySlice_GetIndices(PySliceObject* r, Py_ssize_t length, Py_ssize_
...
@@ -956,16 +956,61 @@ extern "C" int PySlice_GetIndices(PySliceObject* r, Py_ssize_t length, Py_ssize_
extern
"C"
int
PySlice_GetIndicesEx
(
PySliceObject
*
_r
,
Py_ssize_t
length
,
Py_ssize_t
*
start
,
Py_ssize_t
*
stop
,
extern
"C"
int
PySlice_GetIndicesEx
(
PySliceObject
*
_r
,
Py_ssize_t
length
,
Py_ssize_t
*
start
,
Py_ssize_t
*
stop
,
Py_ssize_t
*
step
,
Py_ssize_t
*
slicelength
)
noexcept
{
Py_ssize_t
*
step
,
Py_ssize_t
*
slicelength
)
noexcept
{
try
{
BoxedSlice
*
r
=
(
BoxedSlice
*
)
_r
;
BoxedSlice
*
r
=
(
BoxedSlice
*
)
_r
;
RELEASE_ASSERT
(
r
->
cls
==
slice_cls
,
""
);
assert
(
r
->
cls
==
slice_cls
);
// parseSlice has the exact same behaviour as CPythons PySlice_GetIndicesEx apart from throwing c++ exceptions
/* this is harder to get right than you might think */
// on error.
parseSlice
(
r
,
length
,
start
,
stop
,
step
,
slicelength
);
Py_ssize_t
defstart
,
defstop
;
}
catch
(
ExcInfo
e
)
{
setCAPIException
(
e
);
if
(
r
->
step
==
Py_None
)
{
return
-
1
;
*
step
=
1
;
}
else
{
if
(
!
_PyEval_SliceIndex
(
r
->
step
,
step
))
return
-
1
;
if
(
*
step
==
0
)
{
PyErr_SetString
(
PyExc_ValueError
,
"slice step cannot be zero"
);
return
-
1
;
}
}
}
defstart
=
*
step
<
0
?
length
-
1
:
0
;
defstop
=
*
step
<
0
?
-
1
:
length
;
if
(
r
->
start
==
Py_None
)
{
*
start
=
defstart
;
}
else
{
if
(
!
_PyEval_SliceIndex
(
r
->
start
,
start
))
return
-
1
;
if
(
*
start
<
0
)
*
start
+=
length
;
if
(
*
start
<
0
)
*
start
=
(
*
step
<
0
)
?
-
1
:
0
;
if
(
*
start
>=
length
)
*
start
=
(
*
step
<
0
)
?
length
-
1
:
length
;
}
if
(
r
->
stop
==
Py_None
)
{
*
stop
=
defstop
;
}
else
{
if
(
!
_PyEval_SliceIndex
(
r
->
stop
,
stop
))
return
-
1
;
if
(
*
stop
<
0
)
*
stop
+=
length
;
if
(
*
stop
<
0
)
*
stop
=
(
*
step
<
0
)
?
-
1
:
0
;
if
(
*
stop
>=
length
)
*
stop
=
(
*
step
<
0
)
?
length
-
1
:
length
;
}
if
((
*
step
<
0
&&
*
stop
>=
*
start
)
||
(
*
step
>
0
&&
*
start
>=
*
stop
))
{
*
slicelength
=
0
;
}
else
if
(
*
step
<
0
)
{
*
slicelength
=
(
*
stop
-
*
start
+
1
)
/
(
*
step
)
+
1
;
}
else
{
*
slicelength
=
(
*
stop
-
*
start
-
1
)
/
(
*
step
)
+
1
;
}
return
0
;
return
0
;
}
}
...
...
src/runtime/util.cpp
View file @
f95bd65f
...
@@ -15,84 +15,15 @@
...
@@ -15,84 +15,15 @@
#include "runtime/util.h"
#include "runtime/util.h"
#include "core/options.h"
#include "core/options.h"
#include "runtime/capi.h"
#include "runtime/objmodel.h"
#include "runtime/objmodel.h"
#include "runtime/types.h"
#include "runtime/types.h"
namespace
pyston
{
namespace
pyston
{
// Provides the exact same behaviour as CPythons PySlice_GetIndicesEx apart from throwing c++ exceptions on error
void
parseSlice
(
BoxedSlice
*
slice
,
int
size
,
i64
*
out_start
,
i64
*
out_stop
,
i64
*
out_step
,
i64
*
out_length
)
{
void
parseSlice
(
BoxedSlice
*
slice
,
int
size
,
i64
*
out_start
,
i64
*
out_stop
,
i64
*
out_step
,
i64
*
out_length
)
{
BoxedSlice
*
sslice
=
static_cast
<
BoxedSlice
*>
(
slice
);
int
ret
=
PySlice_GetIndicesEx
((
PySliceObject
*
)
slice
,
size
,
out_start
,
out_stop
,
out_step
,
out_length
);
if
(
ret
==
-
1
)
Box
*
start
=
sslice
->
start
;
throwCAPIException
();
assert
(
start
);
Box
*
stop
=
sslice
->
stop
;
assert
(
stop
);
Box
*
step
=
sslice
->
step
;
assert
(
step
);
RELEASE_ASSERT
(
isSubclass
(
start
->
cls
,
int_cls
)
||
start
->
cls
==
none_cls
,
""
);
RELEASE_ASSERT
(
isSubclass
(
stop
->
cls
,
int_cls
)
||
stop
->
cls
==
none_cls
,
""
);
RELEASE_ASSERT
(
isSubclass
(
step
->
cls
,
int_cls
)
||
step
->
cls
==
none_cls
,
""
);
int64_t
istart
;
int64_t
istop
;
int64_t
istep
=
1
;
if
(
isSubclass
(
step
->
cls
,
int_cls
))
{
istep
=
static_cast
<
BoxedInt
*>
(
step
)
->
n
;
if
(
istep
==
0
)
{
raiseExcHelper
(
ValueError
,
"slice step cannot be zero"
);
}
}
if
(
isSubclass
(
start
->
cls
,
int_cls
))
{
istart
=
static_cast
<
BoxedInt
*>
(
start
)
->
n
;
if
(
istart
<
0
)
istart
=
size
+
istart
;
}
else
{
if
(
istep
>
0
)
istart
=
0
;
else
istart
=
size
-
1
;
}
if
(
isSubclass
(
stop
->
cls
,
int_cls
))
{
istop
=
static_cast
<
BoxedInt
*>
(
stop
)
->
n
;
if
(
istop
<
0
)
istop
=
size
+
istop
;
}
else
{
if
(
istep
>
0
)
istop
=
size
;
else
istop
=
-
1
;
}
if
(
istep
>
0
)
{
if
(
istart
<
0
)
istart
=
0
;
if
(
istop
>
size
)
istop
=
size
;
}
else
{
if
(
istart
>=
size
)
istart
=
size
-
1
;
if
(
istop
<
0
)
istop
=
-
1
;
}
*
out_start
=
istart
;
*
out_stop
=
istop
;
*
out_step
=
istep
;
if
(
out_length
)
{
// This is adapted from CPython's PySlice_GetIndicesEx.
if
((
istep
<
0
&&
istop
>=
istart
)
||
(
istep
>
0
&&
istart
>=
istop
))
*
out_length
=
0
;
else
if
(
istep
<
0
)
*
out_length
=
(
istop
-
istart
+
1
)
/
istep
+
1
;
else
*
out_length
=
(
istop
-
istart
-
1
)
/
istep
+
1
;
RELEASE_ASSERT
(
*
out_length
>=
0
,
"negative length, should never happen"
);
}
}
}
}
}
test/tests/builtins.py
View file @
f95bd65f
...
@@ -40,6 +40,8 @@ print isinstance(1, int)
...
@@ -40,6 +40,8 @@ print isinstance(1, int)
print
isinstance
(
1
,
(
float
,
int
))
print
isinstance
(
1
,
(
float
,
int
))
print
isinstance
(
1
,
(
float
,
(),
(
int
,
3
),
4
))
print
isinstance
(
1
,
(
float
,
(),
(
int
,
3
),
4
))
print
pow
(
11
,
42
)
print
pow
(
11
,
42
,
75
)
print
divmod
(
5
,
2
)
print
divmod
(
5
,
2
)
print
divmod
(
5L
,
-
2
)
print
divmod
(
5L
,
-
2
)
try
:
try
:
...
...
test/tests/gcj_2014_2_d.py
View file @
f95bd65f
# expected: fail
# - long % int
import
sys
import
sys
P
=
1000000007
P
=
1000000007
...
...
test/tests/index_meth.py
0 → 100644
View file @
f95bd65f
class
Index
(
object
):
def
__init__
(
self
,
i
):
self
.
i
=
i
def
__index__
(
self
):
print
"called __index__"
return
self
.
i
s
=
"String"
l
=
[
1
,
2
,
"List"
]
t
=
(
1
,
2
,
"Tuple"
)
print
s
[
Index
(
2L
)]
print
l
[
Index
(
2L
)]
print
t
[
Index
(
2L
)]
test/tests/intmethods.py
View file @
f95bd65f
...
@@ -13,6 +13,9 @@ for i in xrange(1, 12):
...
@@ -13,6 +13,9 @@ for i in xrange(1, 12):
print
1
**
0
print
1
**
0
print
0
**
0
print
0
**
0
print
-
1
**
0
print
-
1
**
0
print
(
11
).
__pow__
(
5
,
50
)
print
(
11
).
__pow__
(
32
,
50
)
print
(
11
).
__index__
()
for
i
in
(
-
10
,
10
,
0
,
-
15
):
for
i
in
(
-
10
,
10
,
0
,
-
15
):
print
i
,
i
.
__hex__
(),
i
.
__oct__
()
print
i
,
i
.
__hex__
(),
i
.
__oct__
()
...
...
test/tests/list.py
View file @
f95bd65f
...
@@ -4,6 +4,7 @@ print l * 5
...
@@ -4,6 +4,7 @@ print l * 5
l
[
0
]
=
1
l
[
0
]
=
1
print
l
print
l
print
l
[
2
]
print
l
[
2
]
print
l
[
2L
]
l
=
range
(
5
)
l
=
range
(
5
)
while
l
:
while
l
:
...
...
test/tests/long.py
View file @
f95bd65f
...
@@ -13,6 +13,7 @@ def test(a, b):
...
@@ -13,6 +13,7 @@ def test(a, b):
print
a
-
b
,
b
-
a
,
a
.
__sub__
(
b
),
b
.
__sub__
(
a
)
print
a
-
b
,
b
-
a
,
a
.
__sub__
(
b
),
b
.
__sub__
(
a
)
print
a
*
b
,
b
*
a
,
a
.
__mul__
(
b
),
b
.
__mul__
(
a
)
print
a
*
b
,
b
*
a
,
a
.
__mul__
(
b
),
b
.
__mul__
(
a
)
print
a
/
b
,
b
/
a
,
a
.
__div__
(
b
),
b
.
__div__
(
a
)
print
a
/
b
,
b
/
a
,
a
.
__div__
(
b
),
b
.
__div__
(
a
)
print
a
%
b
,
b
%
a
,
a
.
__mod__
(
b
),
b
.
__mod__
(
a
)
print
repr
(
a
),
repr
(
b
),
a
<
b
,
a
>
b
,
a
<=
b
,
a
>=
b
,
a
==
b
,
a
!=
b
print
repr
(
a
),
repr
(
b
),
a
<
b
,
a
>
b
,
a
<=
b
,
a
>=
b
,
a
==
b
,
a
!=
b
if
not
isinstance
(
a
,
float
)
and
not
isinstance
(
b
,
float
):
if
not
isinstance
(
a
,
float
)
and
not
isinstance
(
b
,
float
):
print
a
^
b
,
a
|
b
,
a
&
b
print
a
^
b
,
a
|
b
,
a
&
b
...
@@ -55,10 +56,15 @@ print ~(-10L)
...
@@ -55,10 +56,15 @@ print ~(-10L)
print
-
(
1L
)
print
-
(
1L
)
print
1L
**
2L
print
1L
**
2L
print
1L
**
2
print
1L
**
2
print
(
11L
).
__pow__
(
32
,
50L
)
print
(
11L
).
__index__
()
print
long
(
"100"
,
16
)
print
long
(
"100"
,
16
)
print
long
(
"100"
,
10
)
print
long
(
"100"
,
10
)
print
long
(
"100"
,
26
)
print
long
(
"100"
,
26
)
print
long
(
"0x100"
,
16
),
long
(
"0100"
,
8
),
long
(
"0b100"
,
2
)
print
long
(
"0x100"
,
0
),
long
(
"0100"
,
0
),
long
(
"0b100"
,
0
)
print
long
(
"0b100"
,
16
),
long
(
"0b100L"
,
0
),
long
(
"-0b100L"
,
0
)
print
long
(
-
1.1
)
print
long
(
-
1.1
)
print
long
(
1.9
)
print
long
(
1.9
)
print
long
(
-
1.9
)
print
long
(
-
1.9
)
...
...
test/tests/tuples.py
View file @
f95bd65f
...
@@ -133,6 +133,7 @@ except TypeError, e:
...
@@ -133,6 +133,7 @@ except TypeError, e:
t
=
(
1
,
"2"
)
t
=
(
1
,
"2"
)
print
t
[
0
]
print
t
[
0
]
print
t
[
1
]
print
t
[
1
]
print
t
[
1L
]
t
=
(
1
,
2
,
'a'
,
'b'
,
'c'
)
t
=
(
1
,
2
,
'a'
,
'b'
,
'c'
)
print
t
[::
-
1
]
print
t
[::
-
1
]
...
...
test/tests/xrange.py
View file @
f95bd65f
...
@@ -15,3 +15,6 @@ for i in xrange(10, -10, -3):
...
@@ -15,3 +15,6 @@ for i in xrange(10, -10, -3):
for
i
in
xrange
(
0
):
for
i
in
xrange
(
0
):
print
i
print
i
for
i
in
xrange
(
10L
,
15L
,
1L
):
print
i
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