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
68af64c1
Commit
68af64c1
authored
Dec 17, 2014
by
Kevin Modzelewski
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'merge'
parents
b0aea029
1da4cefb
Changes
27
Hide whitespace changes
Inline
Side-by-side
Showing
27 changed files
with
314 additions
and
57 deletions
+314
-57
src/capi/descrobject.cpp
src/capi/descrobject.cpp
+3
-1
src/capi/types.h
src/capi/types.h
+11
-4
src/core/options.cpp
src/core/options.cpp
+3
-0
src/core/options.h
src/core/options.h
+1
-0
src/core/threading.cpp
src/core/threading.cpp
+7
-1
src/core/threading.h
src/core/threading.h
+10
-2
src/gc/root_finder.cpp
src/gc/root_finder.cpp
+17
-0
src/jit.cpp
src/jit.cpp
+1
-1
src/runtime/builtin_modules/builtins.cpp
src/runtime/builtin_modules/builtins.cpp
+21
-5
src/runtime/builtin_modules/sys.cpp
src/runtime/builtin_modules/sys.cpp
+29
-0
src/runtime/capi.cpp
src/runtime/capi.cpp
+21
-4
src/runtime/capi.h
src/runtime/capi.h
+3
-1
src/runtime/classobj.cpp
src/runtime/classobj.cpp
+30
-7
src/runtime/classobj.h
src/runtime/classobj.h
+1
-0
src/runtime/file.cpp
src/runtime/file.cpp
+12
-2
src/runtime/objmodel.cpp
src/runtime/objmodel.cpp
+53
-28
src/runtime/objmodel.h
src/runtime/objmodel.h
+1
-0
src/runtime/str.cpp
src/runtime/str.cpp
+17
-0
src/runtime/types.cpp
src/runtime/types.cpp
+16
-0
test/tests/builtins.py
test/tests/builtins.py
+4
-0
test/tests/collections_test.py
test/tests/collections_test.py
+4
-0
test/tests/distutils_test.py
test/tests/distutils_test.py
+3
-0
test/tests/file.py
test/tests/file.py
+6
-1
test/tests/oldstyle_classes.py
test/tests/oldstyle_classes.py
+24
-0
test/tests/os_test.py
test/tests/os_test.py
+3
-0
test/tests/str_functions.py
test/tests/str_functions.py
+4
-0
test/tests/sys_test.py
test/tests/sys_test.py
+9
-0
No files found.
src/capi/descrobject.cpp
View file @
68af64c1
...
...
@@ -48,7 +48,9 @@ Box* BoxedMethodDescriptor::__call__(BoxedMethodDescriptor* self, Box* obj, Boxe
}
else
{
RELEASE_ASSERT
(
0
,
"0x%x"
,
ml_flags
);
}
assert
(
rtn
);
checkAndThrowCAPIException
();
assert
(
rtn
&&
"should have set + thrown an exception!"
);
return
rtn
;
}
}
src/capi/types.h
View file @
68af64c1
...
...
@@ -15,6 +15,7 @@
#ifndef PYSTON_CAPI_TYPES_H
#define PYSTON_CAPI_TYPES_H
#include "runtime/capi.h"
#include "runtime/types.h"
namespace
pyston
{
...
...
@@ -74,7 +75,9 @@ public:
}
else
{
RELEASE_ASSERT
(
0
,
"0x%x"
,
self
->
ml_flags
);
}
RELEASE_ASSERT
(
rtn
,
"need to throw an exception"
);
checkAndThrowCAPIException
();
assert
(
rtn
&&
"should have set + thrown an exception!"
);
return
rtn
;
}
};
...
...
@@ -106,13 +109,17 @@ public:
wrapperfunc
wrapper
=
self
->
descr
->
wrapper
->
wrapper
;
assert
(
self
->
descr
->
wrapper
->
offset
>
0
);
Box
*
rtn
;
if
(
flags
&
PyWrapperFlag_KEYWORDS
)
{
wrapperfunc_kwds
wk
=
(
wrapperfunc_kwds
)
wrapper
;
r
eturn
(
*
wk
)(
self
->
obj
,
args
,
self
->
descr
->
wrapped
,
kwds
);
r
tn
=
(
*
wk
)(
self
->
obj
,
args
,
self
->
descr
->
wrapped
,
kwds
);
}
else
{
r
eturn
(
*
wrapper
)(
self
->
obj
,
args
,
self
->
descr
->
wrapped
);
r
tn
=
(
*
wrapper
)(
self
->
obj
,
args
,
self
->
descr
->
wrapped
);
}
abort
();
checkAndThrowCAPIException
();
assert
(
rtn
&&
"should have set + thrown an exception!"
);
return
rtn
;
}
};
...
...
src/core/options.cpp
View file @
68af64c1
...
...
@@ -18,6 +18,9 @@ namespace pyston {
int
GLOBAL_VERBOSITY
=
0
;
int
PYSTON_VERSION_MAJOR
=
0
;
int
PYSTON_VERSION_MINOR
=
2
;
int
PYTHON_VERSION_MAJOR
=
DEFAULT_PYTHON_MAJOR_VERSION
;
int
PYTHON_VERSION_MINOR
=
DEFAULT_PYTHON_MINOR_VERSION
;
int
PYTHON_VERSION_MICRO
=
DEFAULT_PYTHON_MICRO_VERSION
;
...
...
src/core/options.h
View file @
68af64c1
...
...
@@ -21,6 +21,7 @@ extern "C" {
extern
int
GLOBAL_VERBOSITY
;
#define VERBOSITY(x) GLOBAL_VERBOSITY
extern
int
PYSTON_VERSION_MAJOR
,
PYSTON_VERSION_MINOR
;
// Version number we're targeting:
extern
int
PYTHON_VERSION_MAJOR
,
PYTHON_VERSION_MINOR
,
PYTHON_VERSION_MICRO
,
PYTHON_VERSION_HEX
;
...
...
src/core/threading.cpp
View file @
68af64c1
...
...
@@ -32,6 +32,9 @@
namespace
pyston
{
namespace
threading
{
__thread
ThreadState
cur_thread_state
=
{
NULL
,
NULL
,
NULL
};
// not sure if we need to explicitly request zero-initialization
PthreadFastMutex
threading_lock
;
// Certain thread examination functions won't be valid for a brief
...
...
@@ -128,7 +131,7 @@ static void pushThreadState(pthread_t tid, ucontext_t* context) {
void
*
stack_end
=
(
void
*
)(
context
->
uc_mcontext
.
gregs
[
REG_RSP
]
+
sizeof
(
void
*
));
#endif
assert
(
stack_start
<
stack_end
);
thread_states
.
push_back
(
ThreadGCState
(
tid
,
context
,
stack_start
,
stack_end
));
thread_states
.
push_back
(
ThreadGCState
(
tid
,
context
,
stack_start
,
stack_end
,
&
cur_thread_state
));
}
std
::
vector
<
ThreadGCState
>
getAllThreadStates
()
{
...
...
@@ -252,6 +255,7 @@ static void* _thread_start(void* _arg) {
}
threading
::
GLReadRegion
_glock
;
assert
(
!
PyErr_Occurred
());
void
*
rtn
=
start_func
(
arg1
,
arg2
,
arg3
);
current_threads
[
current_thread
]
->
assertNoGenerators
();
...
...
@@ -350,6 +354,8 @@ void registerMainThread() {
int
code
=
sigaction
(
SIGUSR2
,
&
act
,
&
oldact
);
if
(
code
)
err
(
1
,
NULL
);
assert
(
!
PyErr_Occurred
());
}
void
finishMainThread
()
{
...
...
src/core/threading.h
View file @
68af64c1
...
...
@@ -28,8 +28,14 @@ class Box;
namespace
threading
{
// Whether or not a second thread was ever started:
bool
threadWasStarted
();
struct
ThreadState
{
Box
*
curexc_type
,
*
curexc_value
,
*
curexc_traceback
;
};
extern
__thread
ThreadState
cur_thread_state
;
// returns a thread id (currently, the pthread_t id)
intptr_t
start_thread
(
void
*
(
*
start_func
)(
Box
*
,
Box
*
,
Box
*
),
Box
*
arg1
,
Box
*
arg2
,
Box
*
arg3
);
...
...
@@ -45,8 +51,10 @@ struct ThreadGCState {
// in a generator, but those generators will be tracked separately.
void
*
stack_start
,
*
stack_end
;
ThreadGCState
(
pthread_t
tid
,
ucontext_t
*
ucontext
,
void
*
stack_start
,
void
*
stack_end
)
:
tid
(
tid
),
ucontext
(
ucontext
),
stack_start
(
stack_start
),
stack_end
(
stack_end
)
{}
ThreadState
*
thread_state
;
ThreadGCState
(
pthread_t
tid
,
ucontext_t
*
ucontext
,
void
*
stack_start
,
void
*
stack_end
,
ThreadState
*
thread_state
)
:
tid
(
tid
),
ucontext
(
ucontext
),
stack_start
(
stack_start
),
stack_end
(
stack_end
),
thread_state
(
thread_state
)
{}
};
// Gets a ThreadGCState per thread, not including the thread calling this function.
// For this call to make sense, the threads all should be blocked;
...
...
src/gc/root_finder.cpp
View file @
68af64c1
...
...
@@ -47,11 +47,20 @@ void collectRoots(void* start, void* end, TraceStack* stack) {
void
collectOtherThreadsStacks
(
TraceStack
*
stack
)
{
GCVisitor
v
(
stack
);
std
::
vector
<
threading
::
ThreadGCState
>
threads
=
threading
::
getAllThreadStates
();
for
(
threading
::
ThreadGCState
&
tstate
:
threads
)
{
collectRoots
(
tstate
.
stack_start
,
tstate
.
stack_end
,
stack
);
collectRoots
(
tstate
.
ucontext
,
tstate
.
ucontext
+
1
,
stack
);
if
(
tstate
.
thread_state
->
curexc_type
)
v
.
visit
(
tstate
.
thread_state
->
curexc_type
);
if
(
tstate
.
thread_state
->
curexc_value
)
v
.
visit
(
tstate
.
thread_state
->
curexc_value
);
if
(
tstate
.
thread_state
->
curexc_traceback
)
v
.
visit
(
tstate
.
thread_state
->
curexc_traceback
);
}
}
...
...
@@ -75,6 +84,14 @@ static void collectLocalStack(TraceStack* stack) {
#else
collectRoots
(
stack_bottom
,
stack_top
,
stack
);
#endif
GCVisitor
v
(
stack
);
if
(
threading
::
cur_thread_state
.
curexc_type
)
v
.
visit
(
threading
::
cur_thread_state
.
curexc_type
);
if
(
threading
::
cur_thread_state
.
curexc_value
)
v
.
visit
(
threading
::
cur_thread_state
.
curexc_value
);
if
(
threading
::
cur_thread_state
.
curexc_traceback
)
v
.
visit
(
threading
::
cur_thread_state
.
curexc_traceback
);
}
void
collectStackRoots
(
TraceStack
*
stack
)
{
...
...
src/jit.cpp
View file @
68af64c1
...
...
@@ -153,7 +153,7 @@ int main(int argc, char** argv) {
}
if
(
repl
)
{
printf
(
"Pyston v
0.2 (rev "
STRINGIFY
(
GITREV
)
")"
);
printf
(
"Pyston v
%d.%d (rev "
STRINGIFY
(
GITREV
)
")"
,
PYSTON_VERSION_MAJOR
,
PYSTON_VERSION_MINOR
);
printf
(
", targeting Python %d.%d.%d
\n
"
,
PYTHON_VERSION_MAJOR
,
PYTHON_VERSION_MINOR
,
PYTHON_VERSION_MICRO
);
if
(
!
main_module
)
{
...
...
src/runtime/builtin_modules/builtins.cpp
View file @
68af64c1
...
...
@@ -99,6 +99,12 @@ extern "C" Box* dir(Box* obj) {
return
result
;
}
extern
"C"
Box
*
vars
(
Box
*
obj
)
{
RELEASE_ASSERT
(
obj
,
"Don't support 0-arg vars() calls yet"
);
return
makeAttrWrapper
(
obj
);
}
extern
"C"
Box
*
abs_
(
Box
*
x
)
{
if
(
x
->
cls
==
int_cls
)
{
i64
n
=
static_cast
<
BoxedInt
*>
(
x
)
->
n
;
...
...
@@ -340,13 +346,21 @@ Box* isinstance_func(Box* obj, Box* cls) {
}
Box
*
issubclass_func
(
Box
*
child
,
Box
*
parent
)
{
if
(
parent
->
cls
==
classobj_cls
)
{
Py_FatalError
(
"don't handle issubclass for old style classes yet"
);
if
(
child
->
cls
!=
type_cls
&&
child
->
cls
!=
classobj_cls
)
raiseExcHelper
(
TypeError
,
"issubclass() arg 1 must be a class"
);
RELEASE_ASSERT
(
parent
->
cls
!=
tuple_cls
,
"unsupported"
);
if
(
child
->
cls
==
classobj_cls
)
{
if
(
parent
->
cls
!=
classobj_cls
)
return
False
;
return
boxBool
(
classobjIssubclass
(
static_cast
<
BoxedClassobj
*>
(
child
),
static_cast
<
BoxedClassobj
*>
(
parent
)));
}
RELEASE_ASSERT
(
child
->
cls
==
type_cls
,
""
);
// TODO parent can also be a tuple of classes
RELEASE_ASSERT
(
parent
->
cls
==
type_cls
,
""
)
;
assert
(
child
->
cls
==
type_cls
);
if
(
parent
->
cls
!=
type_cls
)
return
False
;
return
boxBool
(
isSubclass
(
static_cast
<
BoxedClass
*>
(
child
),
static_cast
<
BoxedClass
*>
(
parent
)));
}
...
...
@@ -911,6 +925,8 @@ void setupBuiltins() {
builtins_module
->
giveAttr
(
"filter"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
filter2
,
LIST
,
2
)));
builtins_module
->
giveAttr
(
"zip"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
zip2
,
LIST
,
2
)));
builtins_module
->
giveAttr
(
"dir"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
dir
,
LIST
,
1
,
1
,
false
,
false
),
{
NULL
}));
builtins_module
->
giveAttr
(
"vars"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
vars
,
LIST
,
1
,
1
,
false
,
false
),
{
NULL
}));
builtins_module
->
giveAttr
(
"object"
,
object_cls
);
builtins_module
->
giveAttr
(
"str"
,
str_cls
);
builtins_module
->
giveAttr
(
"basestring"
,
basestring_cls
);
...
...
src/runtime/builtin_modules/sys.cpp
View file @
68af64c1
...
...
@@ -14,6 +14,10 @@
#include <algorithm>
#include <cmath>
#include <sstream>
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "core/types.h"
#include "gc/collector.h"
...
...
@@ -99,6 +103,14 @@ public:
}
};
static
std
::
string
generateVersionString
()
{
std
::
ostringstream
oss
;
oss
<<
PYTHON_VERSION_MAJOR
<<
'.'
<<
PYTHON_VERSION_MINOR
<<
'.'
<<
PYTHON_VERSION_MICRO
;
oss
<<
'\n'
;
oss
<<
"[Pyston "
<<
PYSTON_VERSION_MAJOR
<<
'.'
<<
PYSTON_VERSION_MINOR
<<
"]"
;
return
oss
.
str
();
}
void
setupSys
()
{
sys_modules_dict
=
new
BoxedDict
();
gc
::
registerPermanentRoot
(
sys_modules_dict
);
...
...
@@ -122,6 +134,23 @@ void setupSys() {
sys_module
->
giveAttr
(
"platform"
,
boxStrConstant
(
"unknown"
));
// seems like a reasonable, if poor, default
llvm
::
SmallString
<
128
>
main_fn
;
// TODO supposed to pass argv0, main_addr to this function:
main_fn
=
llvm
::
sys
::
fs
::
getMainExecutable
(
NULL
,
NULL
);
sys_module
->
giveAttr
(
"executable"
,
boxString
(
main_fn
.
str
()));
// TODO: should configure this in a better way
sys_module
->
giveAttr
(
"prefix"
,
boxStrConstant
(
"/usr"
));
sys_module
->
giveAttr
(
"exec_prefix"
,
boxStrConstant
(
"/usr"
));
sys_module
->
giveAttr
(
"copyright"
,
boxStrConstant
(
"Copyright 2014 Dropbox.
\n
All Rights Reserved.
\n\n
Copyright (c) 2001-2014 "
"Python Software Foundation.
\n
All Rights Reserved.
\n\n
Copyright (c) 2000 "
"BeOpen.com.
\n
All Rights Reserved.
\n\n
Copyright (c) 1995-2001 Corporation for "
"National Research Initiatives.
\n
All Rights Reserved.
\n\n
Copyright (c) "
"1991-1995 Stichting Mathematisch Centrum, Amsterdam.
\n
All Rights Reserved."
));
sys_module
->
giveAttr
(
"version"
,
boxString
(
generateVersionString
()));
sys_module
->
giveAttr
(
"hexversion"
,
boxInt
(
PY_VERSION_HEX
));
sys_module
->
giveAttr
(
"maxint"
,
boxInt
(
PYSTON_INT_MAX
));
...
...
src/runtime/capi.cpp
View file @
68af64c1
...
...
@@ -482,9 +482,28 @@ extern "C" int PyCallable_Check(PyObject* x) {
return
typeLookup
(
x
->
cls
,
call_attr
,
NULL
)
!=
NULL
;
}
void
checkAndThrowCAPIException
()
{
Box
*
value
=
threading
::
cur_thread_state
.
curexc_value
;
if
(
value
)
{
RELEASE_ASSERT
(
threading
::
cur_thread_state
.
curexc_traceback
==
NULL
,
"unsupported"
);
// This doesn't seem like the right behavior...
if
(
value
->
cls
==
tuple_cls
)
{
BoxedTuple
*
args
=
static_cast
<
BoxedTuple
*>
(
value
);
value
=
runtimeCall
(
threading
::
cur_thread_state
.
curexc_type
,
ArgPassSpec
(
0
,
0
,
true
,
false
),
args
,
NULL
,
NULL
,
NULL
,
NULL
);
}
RELEASE_ASSERT
(
value
->
cls
==
threading
::
cur_thread_state
.
curexc_type
,
"unsupported"
);
PyErr_Clear
();
throw
value
;
}
}
extern
"C"
void
PyErr_Restore
(
PyObject
*
type
,
PyObject
*
value
,
PyObject
*
traceback
)
{
Py_FatalError
(
"setting exceptions from the C API is current unimplemented"
);
threading
::
cur_thread_state
.
curexc_type
=
type
;
threading
::
cur_thread_state
.
curexc_value
=
value
;
threading
::
cur_thread_state
.
curexc_traceback
=
traceback
;
}
extern
"C"
void
PyErr_Clear
()
{
...
...
@@ -516,9 +535,7 @@ extern "C" int PyErr_ExceptionMatches(PyObject* exc) {
}
extern
"C"
PyObject
*
PyErr_Occurred
()
{
// While there clearly needs to be more here, I think this is ok for now because all of the exception-setting
// functions will abort()
return
NULL
;
return
threading
::
cur_thread_state
.
curexc_type
;
}
extern
"C"
int
PyErr_WarnEx
(
PyObject
*
category
,
const
char
*
text
,
Py_ssize_t
stacklevel
)
{
...
...
src/runtime/capi.h
View file @
68af64c1
...
...
@@ -15,12 +15,14 @@
#ifndef PYSTON_RUNTIME_CAPI_H
#define PYSTON_RUNTIME_CAPI_H
#include <
c
string>
#include <string>
namespace
pyston
{
class
BoxedModule
;
BoxedModule
*
importTestExtension
(
const
std
::
string
&
);
void
checkAndThrowCAPIException
();
}
#endif
src/runtime/classobj.cpp
View file @
68af64c1
...
...
@@ -25,19 +25,19 @@ namespace pyston {
BoxedClass
*
classobj_cls
,
*
instance_cls
;
bool
classIssubclass
(
BoxedClassobj
*
child
,
BoxedClassobj
*
parent
)
{
bool
class
obj
Issubclass
(
BoxedClassobj
*
child
,
BoxedClassobj
*
parent
)
{
if
(
child
==
parent
)
return
true
;
for
(
auto
e
:
child
->
bases
->
elts
)
{
if
(
e
->
cls
==
classobj_cls
&&
classIssubclass
(
static_cast
<
BoxedClassobj
*>
(
e
),
parent
))
if
(
e
->
cls
==
classobj_cls
&&
class
obj
Issubclass
(
static_cast
<
BoxedClassobj
*>
(
e
),
parent
))
return
true
;
}
return
false
;
}
bool
instanceIsinstance
(
BoxedInstance
*
obj
,
BoxedClassobj
*
cls
)
{
return
classIssubclass
(
obj
->
inst_cls
,
cls
);
return
class
obj
Issubclass
(
obj
->
inst_cls
,
cls
);
}
static
Box
*
classLookup
(
BoxedClassobj
*
cls
,
const
std
::
string
&
attr
)
{
...
...
@@ -142,6 +142,13 @@ static Box* _instanceGetattribute(Box* _inst, Box* _attr, bool raise_on_missing)
BoxedString
*
attr
=
static_cast
<
BoxedString
*>
(
_attr
);
// TODO: special handling for accessing __dict__ and __class__
if
(
attr
->
s
[
0
]
==
'_'
&&
attr
->
s
[
1
]
==
'_'
)
{
if
(
attr
->
s
==
"__dict__"
)
return
makeAttrWrapper
(
inst
);
if
(
attr
->
s
==
"__class__"
)
return
inst
->
inst_cls
;
}
Box
*
r
=
inst
->
getattr
(
attr
->
s
);
if
(
r
)
...
...
@@ -155,7 +162,11 @@ static Box* _instanceGetattribute(Box* _inst, Box* _attr, bool raise_on_missing)
static
const
std
::
string
getattr_str
(
"__getattr__"
);
Box
*
getattr
=
classLookup
(
inst
->
inst_cls
,
getattr_str
);
RELEASE_ASSERT
(
getattr
==
NULL
,
"unimplemented"
);
if
(
getattr
)
{
getattr
=
processDescriptor
(
getattr
,
inst
,
inst
->
inst_cls
);
return
runtimeCall
(
getattr
,
ArgPassSpec
(
1
),
_attr
,
NULL
,
NULL
,
NULL
,
NULL
);
}
if
(
!
raise_on_missing
)
return
NULL
;
...
...
@@ -204,10 +215,22 @@ Box* instanceNonzero(Box* _inst) {
RELEASE_ASSERT
(
_inst
->
cls
==
instance_cls
,
""
);
BoxedInstance
*
inst
=
static_cast
<
BoxedInstance
*>
(
_inst
);
Box
*
nonzero_func
=
_instanceGetattribute
(
inst
,
boxStrConstant
(
"__nonzero__"
),
false
);
Box
*
nonzero_func
=
NULL
;
try
{
nonzero_func
=
_instanceGetattribute
(
inst
,
boxStrConstant
(
"__nonzero__"
),
false
);
}
catch
(
Box
*
b
)
{
if
(
!
isInstance
(
b
,
AttributeError
))
throw
;
}
if
(
nonzero_func
==
NULL
)
nonzero_func
=
_instanceGetattribute
(
inst
,
boxStrConstant
(
"__len__"
),
false
);
if
(
nonzero_func
==
NULL
)
{
try
{
nonzero_func
=
_instanceGetattribute
(
inst
,
boxStrConstant
(
"__len__"
),
false
);
}
catch
(
Box
*
b
)
{
if
(
!
isInstance
(
b
,
AttributeError
))
throw
;
}
}
if
(
nonzero_func
)
{
return
runtimeCall
(
nonzero_func
,
ArgPassSpec
(
0
),
NULL
,
NULL
,
NULL
,
NULL
,
NULL
);
...
...
src/runtime/classobj.h
View file @
68af64c1
...
...
@@ -27,6 +27,7 @@ class BoxedInstance;
extern
BoxedClass
*
classobj_cls
,
*
instance_cls
;
bool
instanceIsinstance
(
BoxedInstance
*
obj
,
BoxedClassobj
*
cls
);
bool
classobjIssubclass
(
BoxedClassobj
*
child
,
BoxedClassobj
*
parent
);
class
BoxedClassobj
:
public
Box
{
public:
...
...
src/runtime/file.cpp
View file @
68af64c1
...
...
@@ -94,8 +94,7 @@ Box* fileWrite(BoxedFile* self, Box* val) {
assert
(
self
->
cls
==
file_cls
);
if
(
self
->
closed
)
{
fprintf
(
stderr
,
"IOError: file is closed
\n
"
);
raiseExcHelper
(
IOError
,
""
);
raiseExcHelper
(
IOError
,
"file is closed"
);
}
...
...
@@ -129,6 +128,16 @@ Box* fileWrite(BoxedFile* self, Box* val) {
}
}
Box
*
fileFlush
(
BoxedFile
*
self
)
{
RELEASE_ASSERT
(
self
->
cls
==
file_cls
,
""
);
if
(
self
->
closed
)
raiseExcHelper
(
IOError
,
"file is closed"
);
fflush
(
self
->
f
);
return
None
;
}
Box
*
fileClose
(
BoxedFile
*
self
)
{
assert
(
self
->
cls
==
file_cls
);
if
(
self
->
closed
)
{
...
...
@@ -199,6 +208,7 @@ void setupFile() {
CLFunction
*
readline
=
boxRTFunction
((
void
*
)
fileReadline1
,
STR
,
1
);
file_cls
->
giveAttr
(
"readline"
,
new
BoxedFunction
(
readline
));
file_cls
->
giveAttr
(
"flush"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
fileFlush
,
NONE
,
1
)));
file_cls
->
giveAttr
(
"write"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
fileWrite
,
NONE
,
2
)));
file_cls
->
giveAttr
(
"close"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
fileClose
,
NONE
,
1
)));
...
...
src/runtime/objmodel.cpp
View file @
68af64c1
...
...
@@ -248,6 +248,10 @@ extern "C" void my_assert(bool b) {
assert
(
b
);
}
bool
isInstance
(
Box
*
obj
,
BoxedClass
*
cls
)
{
return
isSubclass
(
obj
->
cls
,
cls
);
}
extern
"C"
bool
isSubclass
(
BoxedClass
*
child
,
BoxedClass
*
parent
)
{
// TODO the class is allowed to override this using __subclasscheck__
while
(
child
)
{
...
...
@@ -2136,6 +2140,17 @@ static CompiledFunction* pickVersion(CLFunction* f, int num_output_args, Box* oa
return
chosen_cf
;
}
static
std
::
string
getFunctionName
(
CLFunction
*
f
)
{
if
(
f
->
source
)
return
f
->
source
->
getName
();
else
if
(
f
->
versions
.
size
())
{
std
::
ostringstream
oss
;
oss
<<
"<function at "
<<
f
->
versions
[
0
]
->
code
<<
">"
;
return
oss
.
str
();
}
return
"<unknown function>"
;
}
static
void
placeKeyword
(
const
std
::
vector
<
AST_expr
*>&
arg_names
,
std
::
vector
<
bool
>&
params_filled
,
const
std
::
string
&
kw_name
,
Box
*
kw_val
,
Box
*&
oarg1
,
Box
*&
oarg2
,
Box
*&
oarg3
,
Box
**
oargs
,
BoxedDict
*
okwargs
)
{
...
...
@@ -2316,17 +2331,9 @@ Box* callFunc(BoxedFunction* func, CallRewriteArgs* rewrite_args, ArgPassSpec ar
Box
*
ovarargs
=
new
BoxedTuple
(
unused_positional
);
getArg
(
varargs_idx
,
oarg1
,
oarg2
,
oarg3
,
oargs
)
=
ovarargs
;
}
else
if
(
unused_positional
.
size
())
{
std
::
string
name
=
"<unknown function>"
;
if
(
f
->
source
)
name
=
f
->
source
->
getName
();
else
if
(
f
->
versions
.
size
())
{
std
::
ostringstream
oss
;
oss
<<
"<function at "
<<
f
->
versions
[
0
]
->
code
<<
">"
;
name
=
oss
.
str
();
}
raiseExcHelper
(
TypeError
,
"%s() takes at most %d argument%s (%d given)"
,
name
.
c_str
(),
f
->
num_args
,
(
f
->
num_args
==
1
?
""
:
"s"
),
argspec
.
num_args
+
argspec
.
num_keywords
+
varargs
.
size
());
raiseExcHelper
(
TypeError
,
"%s() takes at most %d argument%s (%d given)"
,
getFunctionName
(
f
).
c_str
(),
f
->
num_args
,
(
f
->
num_args
==
1
?
""
:
"s"
),
argspec
.
num_args
+
argspec
.
num_keywords
+
varargs
.
size
());
}
////
...
...
@@ -2341,7 +2348,7 @@ Box* callFunc(BoxedFunction* func, CallRewriteArgs* rewrite_args, ArgPassSpec ar
const
std
::
vector
<
AST_expr
*>*
arg_names
=
f
->
source
?
f
->
source
->
arg_names
.
args
:
NULL
;
if
(
arg_names
==
nullptr
&&
argspec
.
num_keywords
&&
!
f
->
takes_kwargs
)
{
raiseExcHelper
(
TypeError
,
"
<function @%p>() doesn't take keyword arguments"
,
f
->
versions
[
0
]
->
code
);
raiseExcHelper
(
TypeError
,
"
%s() doesn't take keyword arguments"
,
getFunctionName
(
f
).
c_str
()
);
}
if
(
argspec
.
num_keywords
)
...
...
@@ -2374,7 +2381,7 @@ Box* callFunc(BoxedFunction* func, CallRewriteArgs* rewrite_args, ArgPassSpec ar
for
(
auto
&
p
:
d_kwargs
->
d
)
{
if
(
p
.
first
->
cls
!=
str_cls
)
raiseExcHelper
(
TypeError
,
"
<function>() keywords must be strings"
);
raiseExcHelper
(
TypeError
,
"
%s() keywords must be strings"
,
getFunctionName
(
f
).
c_str
()
);
BoxedString
*
s
=
static_cast
<
BoxedString
*>
(
p
.
first
);
...
...
@@ -2385,8 +2392,8 @@ Box* callFunc(BoxedFunction* func, CallRewriteArgs* rewrite_args, ArgPassSpec ar
Box
*&
v
=
okwargs
->
d
[
p
.
first
];
if
(
v
)
{
raiseExcHelper
(
TypeError
,
"
<function>
() got multiple values for keyword argument '%s'"
,
s
->
s
.
c_str
());
raiseExcHelper
(
TypeError
,
"
%s
() got multiple values for keyword argument '%s'"
,
getFunctionName
(
f
).
c_str
(),
s
->
s
.
c_str
());
}
v
=
p
.
second
;
}
...
...
@@ -2399,7 +2406,7 @@ Box* callFunc(BoxedFunction* func, CallRewriteArgs* rewrite_args, ArgPassSpec ar
if
(
params_filled
[
i
])
continue
;
// TODO not right error message
raiseExcHelper
(
TypeError
,
"
<function>() did not get a value for positional argument %d"
,
i
);
raiseExcHelper
(
TypeError
,
"
%s() did not get a value for positional argument %d"
,
getFunctionName
(
f
).
c_str
()
,
i
);
}
RewriterVar
*
r_defaults_array
=
NULL
;
...
...
@@ -3336,22 +3343,40 @@ Box* typeCallInternal(BoxedFunction* f, CallRewriteArgs* rewrite_args, ArgPassSp
if
(
argspec
.
has_starargs
)
{
rewrite_args
=
NULL
;
assert
(
argspec
.
num_args
==
0
);
// doesn't need to be true, but assumed here
Box
*
starargs
=
arg1
;
Box
*
starargs
;
if
(
argspec
.
num_args
==
0
)
starargs
=
arg1
;
else
if
(
argspec
.
num_args
==
1
)
starargs
=
arg2
;
else
abort
();
assert
(
starargs
->
cls
==
tuple_cls
);
BoxedTuple
*
targs
=
static_cast
<
BoxedTuple
*>
(
starargs
);
int
n
=
targs
->
elts
.
size
();
if
(
n
>=
1
)
arg1
=
targs
->
elts
[
0
];
if
(
n
>=
2
)
arg2
=
targs
->
elts
[
1
];
if
(
n
>=
3
)
arg3
=
targs
->
elts
[
2
];
if
(
n
>=
4
)
args
=
&
targs
->
elts
[
3
];
argspec
=
ArgPassSpec
(
n
);
if
(
argspec
.
num_args
==
0
)
{
if
(
n
>=
1
)
arg1
=
targs
->
elts
[
0
];
if
(
n
>=
2
)
arg2
=
targs
->
elts
[
1
];
if
(
n
>=
3
)
arg3
=
targs
->
elts
[
2
];
if
(
n
>=
4
)
args
=
&
targs
->
elts
[
3
];
}
else
if
(
argspec
.
num_args
==
1
)
{
if
(
n
>=
1
)
arg2
=
targs
->
elts
[
0
];
if
(
n
>=
2
)
arg3
=
targs
->
elts
[
1
];
if
(
n
>=
3
)
args
=
&
targs
->
elts
[
2
];
}
else
{
abort
();
// unhandled
}
argspec
=
ArgPassSpec
(
n
+
argspec
.
num_args
);
}
Box
*
_cls
=
arg1
;
...
...
src/runtime/objmodel.h
View file @
68af64c1
...
...
@@ -81,6 +81,7 @@ extern "C" Box* importStar(Box* from_module, BoxedModule* to_module);
extern
"C"
Box
**
unpackIntoArray
(
Box
*
obj
,
int64_t
expected_size
);
extern
"C"
void
assertNameDefined
(
bool
b
,
const
char
*
name
,
BoxedClass
*
exc_cls
,
bool
local_var_msg
);
extern
"C"
void
assertFail
(
BoxedModule
*
inModule
,
Box
*
msg
);
extern
"C"
bool
isInstance
(
Box
*
obj
,
BoxedClass
*
parent
);
extern
"C"
bool
isSubclass
(
BoxedClass
*
child
,
BoxedClass
*
parent
);
extern
"C"
BoxedClosure
*
createClosure
(
BoxedClosure
*
parent_closure
);
extern
"C"
Box
*
getiter
(
Box
*
o
);
...
...
src/runtime/str.cpp
View file @
68af64c1
...
...
@@ -637,6 +637,21 @@ Box* strReplace(Box* _self, Box* _old, Box* _new, Box** _args) {
return
rtn
;
}
Box
*
strPartition
(
BoxedString
*
self
,
BoxedString
*
sep
)
{
RELEASE_ASSERT
(
self
->
cls
==
str_cls
,
""
);
RELEASE_ASSERT
(
sep
->
cls
==
str_cls
,
""
);
size_t
found_idx
=
self
->
s
.
find
(
sep
->
s
);
if
(
found_idx
==
std
::
string
::
npos
)
return
new
BoxedTuple
({
self
,
boxStrConstant
(
""
),
boxStrConstant
(
""
)
});
return
new
BoxedTuple
({
boxStrConstantSize
(
self
->
s
.
c_str
(),
found_idx
),
boxStrConstantSize
(
self
->
s
.
c_str
()
+
found_idx
,
sep
->
s
.
size
()),
boxStrConstantSize
(
self
->
s
.
c_str
()
+
found_idx
+
sep
->
s
.
size
(),
self
->
s
.
size
()
-
found_idx
-
sep
->
s
.
size
())
});
}
Box
*
strSplit
(
BoxedString
*
self
,
BoxedString
*
sep
,
BoxedInt
*
_max_split
)
{
assert
(
self
->
cls
==
str_cls
);
if
(
_max_split
->
cls
!=
int_cls
)
...
...
@@ -1105,6 +1120,8 @@ void setupStr() {
new
BoxedFunction
(
boxRTFunction
((
void
*
)
strFind
,
BOXED_INT
,
3
,
1
,
false
,
false
),
{
boxInt
(
0
)
}));
str_cls
->
giveAttr
(
"rfind"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
strRfind
,
BOXED_INT
,
2
)));
str_cls
->
giveAttr
(
"partition"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
strPartition
,
UNKNOWN
,
2
)));
str_cls
->
giveAttr
(
"__add__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
strAdd
,
UNKNOWN
,
2
)));
str_cls
->
giveAttr
(
"__mod__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
strMod
,
STR
,
2
)));
str_cls
->
giveAttr
(
"__mul__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
strMul
,
UNKNOWN
,
2
)));
...
...
src/runtime/types.cpp
View file @
68af64c1
...
...
@@ -28,6 +28,7 @@
#include "runtime/classobj.h"
#include "runtime/ics.h"
#include "runtime/iterobject.h"
#include "runtime/list.h"
#include "runtime/long.h"
#include "runtime/objmodel.h"
#include "runtime/set.h"
...
...
@@ -726,6 +727,20 @@ public:
Box
*
r
=
self
->
b
->
getattr
(
key
->
s
);
return
r
?
True
:
False
;
}
static
Box
*
items
(
Box
*
_self
)
{
RELEASE_ASSERT
(
_self
->
cls
==
attrwrapper_cls
,
""
);
AttrWrapper
*
self
=
static_cast
<
AttrWrapper
*>
(
_self
);
BoxedList
*
rtn
=
new
BoxedList
();
HCAttrs
*
attrs
=
self
->
b
->
getAttrsPtr
();
for
(
const
auto
&
p
:
attrs
->
hcls
->
attr_offsets
)
{
BoxedTuple
*
t
=
new
BoxedTuple
({
boxString
(
p
.
first
),
attrs
->
attr_list
->
attrs
[
p
.
second
]
});
listAppend
(
rtn
,
t
);
}
return
rtn
;
}
};
Box
*
makeAttrWrapper
(
Box
*
b
)
{
...
...
@@ -937,6 +952,7 @@ void setupRuntime() {
attrwrapper_cls
->
giveAttr
(
"__str__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
AttrWrapper
::
str
,
UNKNOWN
,
1
)));
attrwrapper_cls
->
giveAttr
(
"__contains__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
AttrWrapper
::
contains
,
UNKNOWN
,
2
)));
attrwrapper_cls
->
giveAttr
(
"items"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
AttrWrapper
::
items
,
LIST
,
1
)));
attrwrapper_cls
->
freeze
();
// sys is the first module that needs to be set up, due to modules
...
...
test/tests/builtins.py
View file @
68af64c1
...
...
@@ -51,3 +51,7 @@ def G():
yield
"A"
;
yield
"B"
;
yield
"C"
print
list
(
enumerate
(
G
()))
class
C
(
object
):
def
__init__
(
self
):
self
.
a
=
1
print
vars
(
C
()).
items
()
test/tests/collections_test.py
0 → 100644
View file @
68af64c1
# skip-if: True
# - wip
import
collections
test/tests/distutils_test.py
0 → 100644
View file @
68af64c1
# skip-if: True
# - wip
from
distutils.core
import
setup
test/tests/file.py
View file @
68af64c1
...
...
@@ -34,7 +34,7 @@ f = open('/dev/null')
print
iter
(
f
)
is
f
f
.
close
()
with
open
(
'
../
README.md'
)
as
f
:
with
open
(
'README.md'
)
as
f
:
lines
=
list
(
f
)
print
lines
[:
5
]
print
lines
[
-
5
:]
...
...
@@ -44,3 +44,8 @@ try:
f
=
open
(
'this-should-definitely-not-exist.txt'
)
except
IOError
as
e
:
print
str
(
e
)
f
=
open
(
"/dev/null"
,
"w"
)
f
.
write
(
"hello world"
)
print
f
.
flush
()
f
.
close
()
test/tests/oldstyle_classes.py
View file @
68af64c1
...
...
@@ -102,3 +102,27 @@ print isinstance(D(), C)
print
str
(
f
)[:
26
]
print
repr
(
f
)[:
26
]
class
OldStyleClass
:
pass
print
issubclass
(
OldStyleClass
,
object
)
print
isinstance
(
OldStyleClass
(),
OldStyleClass
)
print
issubclass
(
OldStyleClass
,
OldStyleClass
)
class
GetattrTest
:
def
__getattr__
(
self
,
attr
):
print
"getattr"
,
attr
if
attr
.
startswith
(
"__"
):
raise
AttributeError
(
attr
)
return
1
g
=
GetattrTest
()
g
.
b
=
2
print
g
.
a
print
g
.
b
print
g
.
__class__
print
g
.
__dict__
.
items
()
print
bool
(
g
)
test/tests/os_test.py
View file @
68af64c1
...
...
@@ -13,4 +13,7 @@ print type(os.stat("/dev/null"))
print
os
.
path
.
expanduser
(
"~"
)
==
os
.
environ
[
"HOME"
]
print
os
.
path
.
isfile
(
"/dev/null"
)
print
os
.
path
.
isfile
(
"/should_not_exist!"
)
OSError
(
1
,
2
,
3
)
test/tests/str_functions.py
View file @
68af64c1
...
...
@@ -72,3 +72,7 @@ print "hello world".translate(translation_map, "")
for
i
in
xrange
(
-
10
,
10
):
print
i
,
"aaaaa"
.
find
(
"a"
,
i
)
print
"hello world"
.
partition
(
"hi"
)
print
"hello world"
.
partition
(
"hello"
)
print
"hello world"
.
partition
(
"o"
)
test/tests/sys_test.py
0 → 100644
View file @
68af64c1
# allow-warning: converting unicode literal to str
import
sys
import
os.path
print
sys
.
version
[:
3
]
print
os
.
path
.
exists
(
sys
.
executable
)
print
sys
.
prefix
,
sys
.
exec_prefix
print
sys
.
copyright
[
-
200
:]
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