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
5415879c
Commit
5415879c
authored
May 01, 2015
by
Kevin Modzelewski
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #480 from kmod/gflags
run gflags unittests
parents
610be9f5
6ec39445
Changes
25
Hide whitespace changes
Inline
Side-by-side
Showing
25 changed files
with
594 additions
and
35 deletions
+594
-35
.gitmodules
.gitmodules
+3
-0
Makefile
Makefile
+3
-0
from_cpython/CMakeLists.txt
from_cpython/CMakeLists.txt
+2
-0
from_cpython/Include/abstract.h
from_cpython/Include/abstract.h
+3
-3
from_cpython/Include/pyconfig.h
from_cpython/Include/pyconfig.h
+1
-0
from_cpython/Modules/posixmodule.c
from_cpython/Modules/posixmodule.c
+1
-1
from_cpython/Python/mystrtoul.c
from_cpython/Python/mystrtoul.c
+285
-0
src/codegen/unwinding.cpp
src/codegen/unwinding.cpp
+38
-7
src/codegen/unwinding.h
src/codegen/unwinding.h
+6
-1
src/runtime/classobj.cpp
src/runtime/classobj.cpp
+70
-0
src/runtime/file.cpp
src/runtime/file.cpp
+2
-0
src/runtime/frame.cpp
src/runtime/frame.cpp
+29
-13
src/runtime/list.cpp
src/runtime/list.cpp
+2
-0
src/runtime/long.cpp
src/runtime/long.cpp
+21
-0
src/runtime/objmodel.cpp
src/runtime/objmodel.cpp
+5
-4
src/runtime/types.cpp
src/runtime/types.cpp
+2
-0
test/integration/gflags
test/integration/gflags
+1
-0
test/integration/gflags_test.py
test/integration/gflags_test.py
+20
-0
test/tests/exec_in_test.py
test/tests/exec_in_test.py
+18
-0
test/tests/file.py
test/tests/file.py
+1
-0
test/tests/list.py
test/tests/list.py
+2
-0
test/tests/oldstyle_classes.py
test/tests/oldstyle_classes.py
+31
-1
test/tests/os_test.py
test/tests/os_test.py
+10
-5
test/tests/strop_test.py
test/tests/strop_test.py
+11
-0
test/tests/sys_getframe.py
test/tests/sys_getframe.py
+27
-0
No files found.
.gitmodules
View file @
5415879c
...
...
@@ -16,3 +16,6 @@
[submodule "test/integration/pycrypto"]
path = test/integration/pycrypto
url = https://github.com/dlitz/pycrypto.git
[submodule "test/integration/gflags"]
path = test/integration/gflags
url = https://github.com/google/python-gflags
Makefile
View file @
5415879c
...
...
@@ -356,6 +356,7 @@ STDMODULE_SRCS := \
_sqlite/row.c
\
_sqlite/statement.c
\
_sqlite/util.c
\
stropmodule.c
\
$(EXTRA_STDMODULE_SRCS)
STDOBJECT_SRCS
:=
\
...
...
@@ -383,6 +384,7 @@ STDPYTHON_SRCS := \
formatter_unicode.c
\
structmember.c
\
marshal.c
\
mystrtoul.c
\
$(EXTRA_STDPYTHON_SRCS)
STDPARSER_SRCS
:=
\
...
...
@@ -528,6 +530,7 @@ quick_check:
$(MAKE)
check_format
$(MAKE)
unittests
$(PYTHON)
$(TOOLS_DIR)
/tester.py
-R
pyston_dbg
-j
$(TEST_THREADS)
-a
=
-S
-k
--order-by-mtime
$(TESTS_DIR)
$(ARGS)
$(PYTHON)
$(TOOLS_DIR)
/tester.py
-R
pyston_dbg
-j
$(TEST_THREADS)
-a
=
-S
-k
--exit-code-only
--skip-failing
$(TEST_DIR)
/cpython
$(ARGS)
Makefile.local
:
echo
"Creating default Makefile.local"
...
...
from_cpython/CMakeLists.txt
View file @
5415879c
...
...
@@ -62,6 +62,7 @@ file(GLOB_RECURSE STDMODULE_SRCS Modules
socketmodule.c
statement.c
stringio.c
stropmodule.c
textio.c
timemodule.c
unicodedata.c
...
...
@@ -94,6 +95,7 @@ file(GLOB_RECURSE STDPYTHON_SRCS Python
formatter_unicode.c
getargs.c
marshal.c
mystrtoul.c
pyctype.c
pystrtod.c
structmember.c
...
...
from_cpython/Include/abstract.h
View file @
5415879c
...
...
@@ -636,9 +636,9 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
is an iterator, this returns itself. */
#define PyIter_Check(obj) \
(PyType_HasFeature(
(obj)->ob_type
, Py_TPFLAGS_HAVE_ITER) && \
(obj)->ob_type
->tp_iternext != NULL && \
(obj)->ob_type
->tp_iternext != &_PyObject_NextNotImplemented)
(PyType_HasFeature(
Py_TYPE((obj))
, Py_TPFLAGS_HAVE_ITER) && \
Py_TYPE((obj))
->tp_iternext != NULL && \
Py_TYPE((obj))
->tp_iternext != &_PyObject_NextNotImplemented)
PyAPI_FUNC
(
PyObject
*
)
PyIter_Next
(
PyObject
*
)
PYSTON_NOEXCEPT
;
/* Takes an iterator object and calls its tp_iternext slot,
...
...
from_cpython/Include/pyconfig.h
View file @
5415879c
...
...
@@ -124,6 +124,7 @@
#define HAVE_UNISTD_H 1
#define HAVE_UTIME_H 1
#define HAVE_WCHAR_H 1
#define HAVE_PUTENV 1
// Added this for some Pyston modifications:
#define MAX_PYSTRING_SIZE (PY_SSIZE_T_MAX/2 - (1<<20))
...
...
from_cpython/Modules/posixmodule.c
View file @
5415879c
...
...
@@ -9451,7 +9451,7 @@ INITFUNC(void)
#ifdef HAVE_PUTENV
if
(
posix_putenv_garbage
==
NULL
)
posix_putenv_garbage
=
Py
Dict_New
(
);
posix_putenv_garbage
=
Py
GC_AddRoot
(
PyDict_New
()
);
#endif
if
(
!
initialized
)
{
...
...
from_cpython/Python/mystrtoul.c
0 → 100644
View file @
5415879c
#include "Python.h"
#if defined(__sgi) && defined(WITH_THREAD) && !defined(_SGI_MP_SOURCE)
#define _SGI_MP_SOURCE
#endif
/* strtol and strtoul, renamed to avoid conflicts */
#include <ctype.h>
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
/* Static overflow check values for bases 2 through 36.
* smallmax[base] is the largest unsigned long i such that
* i * base doesn't overflow unsigned long.
*/
static
unsigned
long
smallmax
[]
=
{
0
,
/* bases 0 and 1 are invalid */
0
,
ULONG_MAX
/
2
,
ULONG_MAX
/
3
,
ULONG_MAX
/
4
,
ULONG_MAX
/
5
,
ULONG_MAX
/
6
,
ULONG_MAX
/
7
,
ULONG_MAX
/
8
,
ULONG_MAX
/
9
,
ULONG_MAX
/
10
,
ULONG_MAX
/
11
,
ULONG_MAX
/
12
,
ULONG_MAX
/
13
,
ULONG_MAX
/
14
,
ULONG_MAX
/
15
,
ULONG_MAX
/
16
,
ULONG_MAX
/
17
,
ULONG_MAX
/
18
,
ULONG_MAX
/
19
,
ULONG_MAX
/
20
,
ULONG_MAX
/
21
,
ULONG_MAX
/
22
,
ULONG_MAX
/
23
,
ULONG_MAX
/
24
,
ULONG_MAX
/
25
,
ULONG_MAX
/
26
,
ULONG_MAX
/
27
,
ULONG_MAX
/
28
,
ULONG_MAX
/
29
,
ULONG_MAX
/
30
,
ULONG_MAX
/
31
,
ULONG_MAX
/
32
,
ULONG_MAX
/
33
,
ULONG_MAX
/
34
,
ULONG_MAX
/
35
,
ULONG_MAX
/
36
,
};
/* maximum digits that can't ever overflow for bases 2 through 36,
* calculated by [int(math.floor(math.log(2**32, i))) for i in range(2, 37)].
* Note that this is pessimistic if sizeof(long) > 4.
*/
#if SIZEOF_LONG == 4
static
int
digitlimit
[]
=
{
0
,
0
,
32
,
20
,
16
,
13
,
12
,
11
,
10
,
10
,
/* 0 - 9 */
9
,
9
,
8
,
8
,
8
,
8
,
8
,
7
,
7
,
7
,
/* 10 - 19 */
7
,
7
,
7
,
7
,
6
,
6
,
6
,
6
,
6
,
6
,
/* 20 - 29 */
6
,
6
,
6
,
6
,
6
,
6
,
6
};
/* 30 - 36 */
#elif SIZEOF_LONG == 8
/* [int(math.floor(math.log(2**64, i))) for i in range(2, 37)] */
static
int
digitlimit
[]
=
{
0
,
0
,
64
,
40
,
32
,
27
,
24
,
22
,
21
,
20
,
/* 0 - 9 */
19
,
18
,
17
,
17
,
16
,
16
,
16
,
15
,
15
,
15
,
/* 10 - 19 */
14
,
14
,
14
,
14
,
13
,
13
,
13
,
13
,
13
,
13
,
/* 20 - 29 */
13
,
12
,
12
,
12
,
12
,
12
,
12
};
/* 30 - 36 */
#else
#error "Need table for SIZEOF_LONG"
#endif
/*
** strtoul
** This is a general purpose routine for converting
** an ascii string to an integer in an arbitrary base.
** Leading white space is ignored. If 'base' is zero
** it looks for a leading 0, 0b, 0B, 0o, 0O, 0x or 0X
** to tell which base. If these are absent it defaults
** to 10. Base must be 0 or between 2 and 36 (inclusive).
** If 'ptr' is non-NULL it will contain a pointer to
** the end of the scan.
** Errors due to bad pointers will probably result in
** exceptions - we don't check for them.
*/
unsigned
long
PyOS_strtoul
(
register
char
*
str
,
char
**
ptr
,
int
base
)
{
register
unsigned
long
result
=
0
;
/* return value of the function */
register
int
c
;
/* current input character */
register
int
ovlimit
;
/* required digits to overflow */
/* skip leading white space */
while
(
*
str
&&
isspace
(
Py_CHARMASK
(
*
str
)))
++
str
;
/* check for leading 0 or 0x for auto-base or base 16 */
switch
(
base
)
{
case
0
:
/* look for leading 0, 0b, 0o or 0x */
if
(
*
str
==
'0'
)
{
++
str
;
if
(
*
str
==
'x'
||
*
str
==
'X'
)
{
/* there must be at least one digit after 0x */
if
(
_PyLong_DigitValue
[
Py_CHARMASK
(
str
[
1
])]
>=
16
)
{
if
(
ptr
)
*
ptr
=
str
;
return
0
;
}
++
str
;
base
=
16
;
}
else
if
(
*
str
==
'o'
||
*
str
==
'O'
)
{
/* there must be at least one digit after 0o */
if
(
_PyLong_DigitValue
[
Py_CHARMASK
(
str
[
1
])]
>=
8
)
{
if
(
ptr
)
*
ptr
=
str
;
return
0
;
}
++
str
;
base
=
8
;
}
else
if
(
*
str
==
'b'
||
*
str
==
'B'
)
{
/* there must be at least one digit after 0b */
if
(
_PyLong_DigitValue
[
Py_CHARMASK
(
str
[
1
])]
>=
2
)
{
if
(
ptr
)
*
ptr
=
str
;
return
0
;
}
++
str
;
base
=
2
;
}
else
{
base
=
8
;
}
}
else
base
=
10
;
break
;
case
2
:
/* skip leading 0b or 0B */
if
(
*
str
==
'0'
)
{
++
str
;
if
(
*
str
==
'b'
||
*
str
==
'B'
)
{
/* there must be at least one digit after 0b */
if
(
_PyLong_DigitValue
[
Py_CHARMASK
(
str
[
1
])]
>=
2
)
{
if
(
ptr
)
*
ptr
=
str
;
return
0
;
}
++
str
;
}
}
break
;
case
8
:
/* skip leading 0o or 0O */
if
(
*
str
==
'0'
)
{
++
str
;
if
(
*
str
==
'o'
||
*
str
==
'O'
)
{
/* there must be at least one digit after 0o */
if
(
_PyLong_DigitValue
[
Py_CHARMASK
(
str
[
1
])]
>=
8
)
{
if
(
ptr
)
*
ptr
=
str
;
return
0
;
}
++
str
;
}
}
break
;
case
16
:
/* skip leading 0x or 0X */
if
(
*
str
==
'0'
)
{
++
str
;
if
(
*
str
==
'x'
||
*
str
==
'X'
)
{
/* there must be at least one digit after 0x */
if
(
_PyLong_DigitValue
[
Py_CHARMASK
(
str
[
1
])]
>=
16
)
{
if
(
ptr
)
*
ptr
=
str
;
return
0
;
}
++
str
;
}
}
break
;
}
/* catch silly bases */
if
(
base
<
2
||
base
>
36
)
{
if
(
ptr
)
*
ptr
=
str
;
return
0
;
}
/* skip leading zeroes */
while
(
*
str
==
'0'
)
++
str
;
/* base is guaranteed to be in [2, 36] at this point */
ovlimit
=
digitlimit
[
base
];
/* do the conversion until non-digit character encountered */
while
((
c
=
_PyLong_DigitValue
[
Py_CHARMASK
(
*
str
)])
<
base
)
{
if
(
ovlimit
>
0
)
/* no overflow check required */
result
=
result
*
base
+
c
;
else
{
/* requires overflow check */
register
unsigned
long
temp_result
;
if
(
ovlimit
<
0
)
/* guaranteed overflow */
goto
overflowed
;
/* there could be an overflow */
/* check overflow just from shifting */
if
(
result
>
smallmax
[
base
])
goto
overflowed
;
result
*=
base
;
/* check overflow from the digit's value */
temp_result
=
result
+
c
;
if
(
temp_result
<
result
)
goto
overflowed
;
result
=
temp_result
;
}
++
str
;
--
ovlimit
;
}
/* set pointer to point to the last character scanned */
if
(
ptr
)
*
ptr
=
str
;
return
result
;
overflowed:
if
(
ptr
)
{
/* spool through remaining digit characters */
while
(
_PyLong_DigitValue
[
Py_CHARMASK
(
*
str
)]
<
base
)
++
str
;
*
ptr
=
str
;
}
errno
=
ERANGE
;
return
(
unsigned
long
)
-
1
;
}
/* Checking for overflow in PyOS_strtol is a PITA; see comments
* about PY_ABS_LONG_MIN in longobject.c.
*/
#define PY_ABS_LONG_MIN (0-(unsigned long)LONG_MIN)
long
PyOS_strtol
(
char
*
str
,
char
**
ptr
,
int
base
)
{
long
result
;
unsigned
long
uresult
;
char
sign
;
while
(
*
str
&&
isspace
(
Py_CHARMASK
(
*
str
)))
str
++
;
sign
=
*
str
;
if
(
sign
==
'+'
||
sign
==
'-'
)
str
++
;
uresult
=
PyOS_strtoul
(
str
,
ptr
,
base
);
if
(
uresult
<=
(
unsigned
long
)
LONG_MAX
)
{
result
=
(
long
)
uresult
;
if
(
sign
==
'-'
)
result
=
-
result
;
}
else
if
(
sign
==
'-'
&&
uresult
==
PY_ABS_LONG_MIN
)
{
result
=
LONG_MIN
;
}
else
{
errno
=
ERANGE
;
result
=
LONG_MAX
;
}
return
result
;
}
src/codegen/unwinding.cpp
View file @
5415879c
...
...
@@ -346,6 +346,16 @@ public:
abort
();
}
Box
*
getGlobalsDict
()
{
Box
*
globals
=
getGlobals
();
if
(
!
globals
)
return
NULL
;
if
(
isSubclass
(
globals
->
cls
,
module_cls
))
return
globals
->
getAttrWrapper
();
return
globals
;
}
FrameInfo
*
getFrameInfo
()
{
if
(
id
.
type
==
PythonFrameId
::
COMPILED
)
{
CompiledFunction
*
cf
=
getCF
();
...
...
@@ -591,13 +601,7 @@ Box* getGlobals() {
}
Box
*
getGlobalsDict
()
{
Box
*
globals
=
getGlobals
();
if
(
!
globals
)
return
NULL
;
if
(
isSubclass
(
globals
->
cls
,
module_cls
))
return
globals
->
getAttrWrapper
();
return
globals
;
return
getTopPythonFrame
()
->
getGlobalsDict
();
}
BoxedModule
*
getCurrentModule
()
{
...
...
@@ -890,6 +894,10 @@ CompiledFunction* PythonFrameIterator::getCF() {
return
impl
->
getCF
();
}
Box
*
PythonFrameIterator
::
getGlobalsDict
()
{
return
impl
->
getGlobalsDict
();
}
FrameInfo
*
PythonFrameIterator
::
getFrameInfo
()
{
return
impl
->
getFrameInfo
();
}
...
...
@@ -907,6 +915,29 @@ PythonFrameIterator PythonFrameIterator::getCurrentVersion() {
return
PythonFrameIterator
(
std
::
move
(
rtn
));
}
PythonFrameIterator
PythonFrameIterator
::
back
()
{
// TODO this is ineffecient: the iterator is no longer valid for libunwind iteration, so
// we have to do a full stack crawl again.
// Hopefully examination of f_back is uncommon.
std
::
unique_ptr
<
PythonFrameIteratorImpl
>
rtn
(
nullptr
);
auto
&
impl
=
this
->
impl
;
bool
found
=
false
;
unwindPythonStack
([
&
](
std
::
unique_ptr
<
PythonFrameIteratorImpl
>
frame_iter
)
{
if
(
found
)
{
rtn
=
std
::
move
(
frame_iter
);
return
true
;
}
if
(
frame_iter
->
pointsToTheSameAs
(
*
impl
.
get
()))
found
=
true
;
return
false
;
});
RELEASE_ASSERT
(
found
,
"this wasn't a valid frame?"
);
return
PythonFrameIterator
(
std
::
move
(
rtn
));
}
llvm
::
JITEventListener
*
makeTracebacksListener
()
{
return
new
TracebacksEventListener
();
}
...
...
src/codegen/unwinding.h
View file @
5415879c
...
...
@@ -53,15 +53,20 @@ public:
bool
exists
()
{
return
impl
.
get
()
!=
NULL
;
}
std
::
unique_ptr
<
ExecutionPoint
>
getExecutionPoint
();
Box
*
fastLocalsToBoxedLocals
();
Box
*
getGlobalsDict
();
// Gets the "current version" of this frame: if the frame has executed since
// the iterator was obtained, the methods may return old values. This returns
// an updated copy that returns the updated values.
// The "current version" will live at the same stack location, but any other
// similarities need to be verified by the caller.
// similarities need to be verified by the caller, ie it is up to the caller
// to determine that we didn't leave and reenter the stack frame.
// This function can only be called from the thread that created this object.
PythonFrameIterator
getCurrentVersion
();
// Assuming this is a valid frame iterator, return the next frame back (ie older).
PythonFrameIterator
back
();
PythonFrameIterator
(
PythonFrameIterator
&&
rhs
);
void
operator
=
(
PythonFrameIterator
&&
rhs
);
PythonFrameIterator
(
std
::
unique_ptr
<
PythonFrameIteratorImpl
>
impl
);
...
...
src/runtime/classobj.cpp
View file @
5415879c
...
...
@@ -333,6 +333,34 @@ Box* instanceSetattr(Box* _inst, Box* _attr, Box* value) {
return
None
;
}
Box
*
instanceDelattr
(
Box
*
_inst
,
Box
*
_attr
)
{
RELEASE_ASSERT
(
_inst
->
cls
==
instance_cls
,
""
);
BoxedInstance
*
inst
=
static_cast
<
BoxedInstance
*>
(
_inst
);
RELEASE_ASSERT
(
_attr
->
cls
==
str_cls
,
""
);
BoxedString
*
attr
=
static_cast
<
BoxedString
*>
(
_attr
);
// These are special cases in CPython as well:
if
(
attr
->
s
[
0
]
==
'_'
&&
attr
->
s
[
1
]
==
'_'
)
{
if
(
attr
->
s
==
"__dict__"
)
raiseExcHelper
(
TypeError
,
"__dict__ must be set to a dictionary"
);
if
(
attr
->
s
==
"__class__"
)
raiseExcHelper
(
TypeError
,
"__class__ must be set to a class"
);
}
static
const
std
::
string
delattr_str
(
"__delattr__"
);
Box
*
delattr
=
classLookup
(
inst
->
inst_cls
,
delattr_str
);
if
(
delattr
)
{
delattr
=
processDescriptor
(
delattr
,
inst
,
inst
->
inst_cls
);
return
runtimeCall
(
delattr
,
ArgPassSpec
(
1
),
_attr
,
NULL
,
NULL
,
NULL
,
NULL
);
}
_inst
->
delattr
(
attr
->
s
,
NULL
);
return
None
;
}
static
int
instance_setattro
(
Box
*
cls
,
Box
*
attr
,
Box
*
value
)
noexcept
{
try
{
if
(
value
)
{
...
...
@@ -488,6 +516,45 @@ static Box* instanceHash(BoxedInstance* inst) {
}
}
static
Box
*
instanceIter
(
BoxedInstance
*
self
)
{
assert
(
self
->
cls
==
instance_cls
);
PyObject
*
func
;
if
((
func
=
_instanceGetattribute
(
self
,
boxStrConstant
(
"__iter__"
),
false
))
!=
NULL
)
{
PyObject
*
res
=
PyEval_CallObject
(
func
,
(
PyObject
*
)
NULL
);
if
(
!
res
)
throwCAPIException
();
if
(
!
PyIter_Check
(
res
))
raiseExcHelper
(
TypeError
,
"__iter__ returned non-iterator of type '%.100s'"
,
res
->
cls
->
tp_name
);
return
res
;
}
if
((
func
=
_instanceGetattribute
(
self
,
boxStrConstant
(
"__getitem__"
),
false
))
==
NULL
)
{
raiseExcHelper
(
TypeError
,
"iteration over non-sequence"
);
}
Box
*
r
=
PySeqIter_New
((
PyObject
*
)
self
);
if
(
!
r
)
throwCAPIException
();
return
r
;
}
static
Box
*
instanceNext
(
BoxedInstance
*
inst
)
{
assert
(
inst
->
cls
==
instance_cls
);
Box
*
next_func
=
_instanceGetattribute
(
inst
,
boxStrConstant
(
"next"
),
false
);
if
(
!
next_func
)
{
// not 100% sure why this is a different error:
raiseExcHelper
(
TypeError
,
"instance has no next() method"
);
}
Box
*
r
=
runtimeCall
(
next_func
,
ArgPassSpec
(
0
),
NULL
,
NULL
,
NULL
,
NULL
,
NULL
);
return
r
;
}
static
PyObject
*
instance_index
(
PyObject
*
self
)
noexcept
{
PyObject
*
func
,
*
res
;
/*
...
...
@@ -569,6 +636,7 @@ void setupClassobj() {
instance_cls
->
giveAttr
(
"__getattribute__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
instanceGetattribute
,
UNKNOWN
,
2
)));
instance_cls
->
giveAttr
(
"__setattr__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
instanceSetattr
,
UNKNOWN
,
3
)));
instance_cls
->
giveAttr
(
"__delattr__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
instanceDelattr
,
UNKNOWN
,
2
)));
instance_cls
->
giveAttr
(
"__str__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
instanceStr
,
UNKNOWN
,
1
)));
instance_cls
->
giveAttr
(
"__repr__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
instanceRepr
,
UNKNOWN
,
1
)));
instance_cls
->
giveAttr
(
"__nonzero__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
instanceNonzero
,
UNKNOWN
,
1
)));
...
...
@@ -578,6 +646,8 @@ void setupClassobj() {
instance_cls
->
giveAttr
(
"__delitem__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
instanceDelitem
,
UNKNOWN
,
2
)));
instance_cls
->
giveAttr
(
"__contains__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
instanceContains
,
UNKNOWN
,
2
)));
instance_cls
->
giveAttr
(
"__hash__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
instanceHash
,
UNKNOWN
,
1
)));
instance_cls
->
giveAttr
(
"__iter__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
instanceIter
,
UNKNOWN
,
1
)));
instance_cls
->
giveAttr
(
"next"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
instanceNext
,
UNKNOWN
,
1
)));
instance_cls
->
giveAttr
(
"__call__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
instanceCall
,
UNKNOWN
,
1
,
0
,
true
,
true
)));
instance_cls
->
giveAttr
(
"__eq__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
instanceEq
,
UNKNOWN
,
2
)));
...
...
src/runtime/file.cpp
View file @
5415879c
...
...
@@ -1647,6 +1647,8 @@ void setupFile() {
file_cls
->
giveAttr
(
"tell"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
fileTell
,
UNKNOWN
,
1
)));
file_cls
->
giveAttr
(
"softspace"
,
new
BoxedMemberDescriptor
(
BoxedMemberDescriptor
::
INT
,
offsetof
(
BoxedFile
,
f_softspace
),
false
));
file_cls
->
giveAttr
(
"name"
,
new
BoxedMemberDescriptor
(
BoxedMemberDescriptor
::
OBJECT
,
offsetof
(
BoxedFile
,
f_name
),
true
));
file_cls
->
giveAttr
(
"__new__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
fileNew
,
UNKNOWN
,
4
,
2
,
false
,
false
),
{
boxStrConstant
(
"r"
),
boxInt
(
-
1
)
}));
...
...
src/runtime/frame.cpp
View file @
5415879c
...
...
@@ -27,10 +27,12 @@ BoxedClass* frame_cls;
// - breaks c++ exceptions
// - we never free the trampolines
class
BoxedFrame
:
public
Box
{
public:
BoxedFrame
(
PythonFrameIterator
&&
it
)
__attribute__
((
visibility
(
"default"
)))
private:
// Call boxFrame to get a BoxedFrame object.
BoxedFrame
(
PythonFrameIterator
it
)
__attribute__
((
visibility
(
"default"
)))
:
it
(
std
::
move
(
it
)),
thread_id
(
PyThread_get_thread_ident
())
{}
public:
PythonFrameIterator
it
;
long
thread_id
;
...
...
@@ -105,6 +107,16 @@ public:
return
f
->
_globals
;
}
static
Box
*
back
(
Box
*
obj
,
void
*
)
{
auto
f
=
static_cast
<
BoxedFrame
*>
(
obj
);
f
->
update
();
PythonFrameIterator
it
=
f
->
it
.
back
();
if
(
!
it
.
exists
())
return
None
;
return
BoxedFrame
::
boxFrame
(
std
::
move
(
it
));
}
static
Box
*
lineno
(
Box
*
obj
,
void
*
)
{
auto
f
=
static_cast
<
BoxedFrame
*>
(
obj
);
f
->
update
();
...
...
@@ -113,6 +125,19 @@ public:
}
DEFAULT_CLASS
(
frame_cls
);
static
Box
*
boxFrame
(
PythonFrameIterator
it
)
{
FrameInfo
*
fi
=
it
.
getFrameInfo
();
if
(
fi
->
frame_obj
==
NULL
)
{
auto
cf
=
it
.
getCF
();
Box
*
globals
=
it
.
getGlobalsDict
();
BoxedFrame
*
f
=
fi
->
frame_obj
=
new
BoxedFrame
(
std
::
move
(
it
));
f
->
_globals
=
globals
;
f
->
_code
=
codeForCLFunction
(
cf
->
clfunc
);
}
return
fi
->
frame_obj
;
}
};
Box
*
getFrame
(
int
depth
)
{
...
...
@@ -120,19 +145,9 @@ Box* getFrame(int depth) {
if
(
!
it
.
exists
())
return
NULL
;
FrameInfo
*
fi
=
it
.
getFrameInfo
();
if
(
fi
->
frame_obj
==
NULL
)
{
auto
cf
=
it
.
getCF
();
BoxedFrame
*
f
=
fi
->
frame_obj
=
new
BoxedFrame
(
std
::
move
(
it
));
assert
(
cf
->
clfunc
->
source
->
scoping
->
areGlobalsFromModule
());
f
->
_globals
=
cf
->
clfunc
->
source
->
parent_module
->
getAttrWrapper
();
f
->
_code
=
codeForCLFunction
(
cf
->
clfunc
);
}
return
fi
->
frame_obj
;
return
BoxedFrame
::
boxFrame
(
std
::
move
(
it
));
}
void
setupFrame
()
{
frame_cls
=
BoxedHeapClass
::
create
(
type_cls
,
object_cls
,
&
BoxedFrame
::
gchandler
,
0
,
0
,
sizeof
(
BoxedFrame
),
false
,
"frame"
);
...
...
@@ -143,6 +158,7 @@ void setupFrame() {
frame_cls
->
giveAttr
(
"f_lineno"
,
new
(
pyston_getset_cls
)
BoxedGetsetDescriptor
(
BoxedFrame
::
lineno
,
NULL
,
NULL
));
frame_cls
->
giveAttr
(
"f_globals"
,
new
(
pyston_getset_cls
)
BoxedGetsetDescriptor
(
BoxedFrame
::
globals
,
NULL
,
NULL
));
frame_cls
->
giveAttr
(
"f_back"
,
new
(
pyston_getset_cls
)
BoxedGetsetDescriptor
(
BoxedFrame
::
back
,
NULL
,
NULL
));
frame_cls
->
freeze
();
}
...
...
src/runtime/list.cpp
View file @
5415879c
...
...
@@ -1103,6 +1103,8 @@ void setupList() {
"index"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
listIndex
,
BOXED_INT
,
4
,
2
,
false
,
false
),
{
NULL
,
NULL
}));
list_cls
->
giveAttr
(
"remove"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
listRemove
,
NONE
,
2
)));
list_cls
->
giveAttr
(
"reverse"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
listReverse
,
NONE
,
1
)));
list_cls
->
giveAttr
(
"__hash__"
,
None
);
list_cls
->
freeze
();
CLFunction
*
hasnext
=
boxRTFunction
((
void
*
)
listiterHasnextUnboxed
,
BOOL
,
1
);
...
...
src/runtime/long.cpp
View file @
5415879c
...
...
@@ -35,6 +35,27 @@ namespace pyston {
BoxedClass
*
long_cls
;
/* Table of digit values for 8-bit string -> integer conversion.
* '0' maps to 0, ..., '9' maps to 9.
* 'a' and 'A' map to 10, ..., 'z' and 'Z' map to 35.
* All other indices map to 37.
* Note that when converting a base B string, a char c is a legitimate
* base B digit iff _PyLong_DigitValue[Py_CHARMASK(c)] < B.
*/
extern
"C"
{
int
_PyLong_DigitValue
[
256
]
=
{
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
0
,
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
10
,
11
,
12
,
13
,
14
,
15
,
16
,
17
,
18
,
19
,
20
,
21
,
22
,
23
,
24
,
25
,
26
,
27
,
28
,
29
,
30
,
31
,
32
,
33
,
34
,
35
,
37
,
37
,
37
,
37
,
37
,
37
,
10
,
11
,
12
,
13
,
14
,
15
,
16
,
17
,
18
,
19
,
20
,
21
,
22
,
23
,
24
,
25
,
26
,
27
,
28
,
29
,
30
,
31
,
32
,
33
,
34
,
35
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
37
,
};
}
#define IS_LITTLE_ENDIAN (int)*(unsigned char*)&one
#define PY_ABS_LLONG_MIN (0 - (unsigned PY_LONG_LONG)PY_LLONG_MIN)
...
...
src/runtime/objmodel.cpp
View file @
5415879c
...
...
@@ -320,13 +320,10 @@ BoxedClass::BoxedClass(BoxedClass* base, gcvisit_func gc_visit, int attrs_offset
tp_basicsize
=
instance_size
;
tp_weaklistoffset
=
weaklist_offset
;
tp_flags
|=
Py_TPFLAGS_DEFAULT_EXTERNAL
;
tp_flags
|=
Py_TPFLAGS_CHECKTYPES
;
tp_flags
|=
Py_TPFLAGS_BASETYPE
;
tp_flags
|=
Py_TPFLAGS_HAVE_CLASS
;
tp_flags
|=
Py_TPFLAGS_HAVE_GC
;
tp_flags
|=
Py_TPFLAGS_HAVE_WEAKREFS
;
tp_flags
|=
Py_TPFLAGS_HAVE_RICHCOMPARE
;
tp_flags
|=
Py_TPFLAGS_HAVE_INDEX
;
if
(
base
&&
(
base
->
tp_flags
&
Py_TPFLAGS_HAVE_NEWBUFFER
))
tp_flags
|=
Py_TPFLAGS_HAVE_NEWBUFFER
;
...
...
@@ -2113,6 +2110,10 @@ extern "C" BoxedInt* hash(Box* obj) {
return
static_cast
<
BoxedInt
*>
(
boxInt
((
i64
)
obj
));
}
if
(
hash
==
None
)
{
raiseExcHelper
(
TypeError
,
"unhashable type: '%s'"
,
obj
->
cls
->
tp_name
);
}
Box
*
rtn
=
runtimeCall0
(
hash
,
ArgPassSpec
(
0
));
if
(
rtn
->
cls
!=
int_cls
)
{
raiseExcHelper
(
TypeError
,
"an integer is required"
);
...
...
src/runtime/types.cpp
View file @
5415879c
...
...
@@ -78,6 +78,7 @@ extern "C" void init_csv();
extern
"C"
void
init_ssl
();
extern
"C"
void
init_sqlite3
();
extern
"C"
void
PyMarshal_Init
();
extern
"C"
void
initstrop
();
namespace
pyston
{
...
...
@@ -2401,6 +2402,7 @@ void setupRuntime() {
init_ssl
();
init_sqlite3
();
PyMarshal_Init
();
initstrop
();
// some additional setup to ensure weakrefs participate in our GC
BoxedClass
*
weakref_ref_cls
=
&
_PyWeakref_RefType
;
...
...
gflags
@
1569dd1f
Subproject commit 1569dd1f3855abd262ea3a7741527d4413b35bc9
test/integration/gflags_test.py
0 → 100644
View file @
5415879c
import
glob
import
subprocess
,
sys
,
os
gflags_dir
=
os
.
path
.
dirname
(
os
.
path
.
abspath
(
__file__
))
+
"/gflags"
os
.
chdir
(
gflags_dir
)
env
=
os
.
environ
env
[
"PYTHONPATH"
]
=
"."
TESTS_DIR
=
"tests"
for
fn
in
glob
.
glob
(
"%s/*.py"
%
TESTS_DIR
):
# We don't support xml.dom.minidom yet
if
"helpxml_test.py"
in
fn
:
print
"Skipping"
,
fn
continue
print
"Running"
,
fn
subprocess
.
check_call
([
sys
.
executable
,
fn
])
print
"-- Tests finished"
test/tests/exec_in_test.py
View file @
5415879c
...
...
@@ -131,3 +131,21 @@ g = {}
l
=
{}
exec
(
"a=1; print a"
,
g
,
l
)
print
g
.
keys
(),
l
.
keys
()
s
=
"""
global a
a = 1
b = 2
def inner():
print sorted(globals().keys()), sorted(locals().keys())
print a
print b
print sorted(globals().keys()), sorted(locals().keys())
inner()
"""
exec
s
in
{}
try
:
exec
s
in
{},
{}
raise
Exception
()
except
NameError
as
e
:
print
e
test/tests/file.py
View file @
5415879c
...
...
@@ -3,6 +3,7 @@ import tempfile
f
=
open
(
"/dev/null"
)
print
repr
(
f
.
read
())
print
repr
(
f
.
name
)
f2
=
file
(
"/dev/null"
)
print
repr
(
f2
.
read
())
...
...
test/tests/list.py
View file @
5415879c
...
...
@@ -195,3 +195,5 @@ l.sort(cmp=mycmp, key=str)
print types_seen
print l
"""
print
repr
(
list
.
__hash__
)
test/tests/oldstyle_classes.py
View file @
5415879c
...
...
@@ -147,9 +147,13 @@ class SetattrTest:
def
__setattr__
(
self
,
attr
,
value
):
print
"setattr"
,
attr
,
value
def
__delattr__
(
self
,
attr
):
print
"delattr"
,
attr
s
=
SetattrTest
()
s
.
b
=
2
print
g
.
__dict__
.
items
()
print
s
.
__dict__
.
items
()
del
s
.
b
class
MappingTest
:
def
__getitem__
(
self
,
key
):
...
...
@@ -245,3 +249,29 @@ class E(C, object):
print
issubclass
(
D
,
C
),
isinstance
(
D
(),
C
)
print
issubclass
(
E
,
C
),
isinstance
(
E
(),
C
)
print
isinstance
(
E
,
object
),
isinstance
(
E
(),
object
)
class
SeqTest
:
class
Iterator
:
def
__init__
(
self
):
self
.
n
=
5
def
next
(
self
):
print
"next"
if
self
.
n
<=
0
:
raise
StopIteration
()
r
=
self
.
n
self
.
n
-=
1
return
r
def
__iter__
(
self
):
print
"iter"
return
SeqTest
.
Iterator
()
m
=
SeqTest
()
print
list
(
m
)
class
OldSeqTest
:
def
__getitem__
(
self
,
n
):
print
"getitem"
,
n
if
n
>
5
:
raise
IndexError
()
return
n
**
2
m
=
OldSeqTest
()
print
list
(
m
)
test/tests/os_test.py
View file @
5415879c
...
...
@@ -23,8 +23,13 @@ print e.strerror
print
e
.
filename
print
OSError
(
1
,
2
).
filename
# This part needs sys.exc_info() and the three-arg raise statement
# try:
# os.execvp("aoeuaoeu", ['aoeuaoeu'])
# except OSError, e:
# print e
try
:
os
.
execvp
(
"aoeuaoeu"
,
[
'aoeuaoeu'
])
except
OSError
,
e
:
print
e
# Changes to os.environ should show up in subprocesses:
import
subprocess
env
=
os
.
environ
env
[
"PYTHONPATH"
]
=
"."
subprocess
.
check_call
(
"echo PYTHONPATH is $PYTHONPATH"
,
shell
=
1
)
test/tests/strop_test.py
0 → 100644
View file @
5415879c
import
strop
print
repr
(
strop
.
whitespace
)
import
string
print
repr
(
string
.
whitespace
)
print
repr
(
string
.
lowercase
)
print
repr
(
string
.
uppercase
)
all_chars
=
''
.
join
(
chr
(
i
)
for
i
in
xrange
(
256
))
print
repr
(
strop
.
lower
(
all_chars
))
test/tests/sys_getframe.py
View file @
5415879c
...
...
@@ -72,3 +72,30 @@ assert sys._getframe(0).f_globals is globals()
def
f5
():
assert
sys
.
_getframe
(
0
).
f_globals
is
globals
()
f5
()
# A number of libraries have functions like this:
def
get_main_module
():
f
=
sys
.
_getframe
(
1
)
while
f
.
f_locals
is
not
globals
():
print
f
.
f_code
.
co_filename
,
f
.
f_lineno
,
sorted
(
f
.
f_locals
.
items
())
f
=
f
.
f_back
print
"Main module currently at:"
,
f
.
f_code
.
co_filename
,
f
.
f_lineno
print
"f_back:"
,
f
.
f_back
def
f6
(
n
):
if
n
:
f6
(
n
-
1
)
else
:
get_main_module
()
f6
(
10
)
def
custom_globals
():
s
=
"""
def inner():
import sys
return sys._getframe(1).f_globals
print sorted(inner().keys())
"""
.
strip
()
exec
s
exec
s
in
{
'a'
:
1
}
exec
s
in
{
'b'
:
2
},
{
'c'
:
3
}
custom_globals
()
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