Commit de7fb378 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Merge up to master

parents 0ec4a8fa 2b374d67
......@@ -130,7 +130,7 @@ if(ENABLE_OPROFILE)
endif()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Werror -Wreturn-type -Wno-sign-compare -Wno-unused -Wno-sign-compare -Wno-unused-parameter -fno-omit-frame-pointer")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_C_FLAGS} -std=c++11 -fPIC -fno-rtti -fexceptions -fvisibility-inlines-hidden -ffunction-sections -fdata-sections -Woverloaded-virtual -Wno-invalid-offsetof -Wcast-qual -Wno-sign-conversion -Wnon-virtual-dtor -Winit-self -Wmissing-include-dirs -Wstrict-overflow=5 -Wpointer-arith -Wtype-limits -Wwrite-strings -Wempty-body -Waggregate-return -Wmissing-field-initializers -Wredundant-decls -Winline -Wint-to-pointer-cast -Wlong-long -Wvla -Wno-attributes")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_C_FLAGS} -std=c++11 -fno-rtti -fexceptions -fvisibility-inlines-hidden -ffunction-sections -fdata-sections -Woverloaded-virtual -Wno-invalid-offsetof -Wcast-qual -Wno-sign-conversion -Wnon-virtual-dtor -Winit-self -Wmissing-include-dirs -Wstrict-overflow=5 -Wpointer-arith -Wtype-limits -Wwrite-strings -Wempty-body -Waggregate-return -Wmissing-field-initializers -Wredundant-decls -Winline -Wint-to-pointer-cast -Wlong-long -Wvla -Wno-attributes")
set(CLANG_FLAGS "${CLANG_FLAGS} -Wimplicit-int -Wstrict-prototypes -Wold-style-definition -Wnested-externs -Wpointer-to-int-cast -Wno-mismatched-tags -Wno-extern-c-compat")
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
......
......@@ -290,7 +290,7 @@ SRCS := $(MAIN_SRCS) $(STDLIB_SRCS)
STDLIB_OBJS := stdlib.bc.o stdlib.stripped.bc.o
STDLIB_RELEASE_OBJS := stdlib.release.bc.o
STDMODULE_SRCS := errnomodule.c shamodule.c sha256module.c sha512module.c _math.c mathmodule.c md5.c md5module.c _randommodule.c _sre.c operator.c binascii.c pwdmodule.c posixmodule.c _struct.c datetimemodule.c _functoolsmodule.c _collectionsmodule.c itertoolsmodule.c resource.c signalmodule.c selectmodule.c fcntlmodule.c $(EXTRA_STDMODULE_SRCS)
STDMODULE_SRCS := errnomodule.c shamodule.c sha256module.c sha512module.c _math.c mathmodule.c md5.c md5module.c _randommodule.c _sre.c operator.c binascii.c pwdmodule.c posixmodule.c _struct.c datetimemodule.c _functoolsmodule.c _collectionsmodule.c itertoolsmodule.c resource.c signalmodule.c selectmodule.c fcntlmodule.c timemodule.c arraymodule.c $(EXTRA_STDMODULE_SRCS)
STDOBJECT_SRCS := structseq.c capsule.c stringobject.c $(EXTRA_STDOBJECT_SRCS)
STDPYTHON_SRCS := pyctype.c getargs.c formatter_string.c pystrtod.c dtoa.c $(EXTRA_STDPYTHON_SRCS)
FROM_CPYTHON_SRCS := $(addprefix from_cpython/Modules/,$(STDMODULE_SRCS)) $(addprefix from_cpython/Objects/,$(STDOBJECT_SRCS)) $(addprefix from_cpython/Python/,$(STDPYTHON_SRCS))
......
......@@ -15,7 +15,7 @@ endforeach(STDLIB_FILE)
add_custom_target(copy_stdlib ALL DEPENDS ${STDLIB_TARGETS})
# compile specified files in from_cpython/Modules
file(GLOB_RECURSE STDMODULE_SRCS Modules errnomodule.c shamodule.c sha256module.c sha512module.c _math.c mathmodule.c md5.c md5module.c _randommodule.c _sre.c operator.c binascii.c pwdmodule.c posixmodule.c _struct.c datetimemodule.c _functoolsmodule.c _collectionsmodule.c itertoolsmodule.c resource.c signalmodule.c selectmodule.c fcntlmodule.c)
file(GLOB_RECURSE STDMODULE_SRCS Modules errnomodule.c shamodule.c sha256module.c sha512module.c _math.c mathmodule.c md5.c md5module.c _randommodule.c _sre.c operator.c binascii.c pwdmodule.c posixmodule.c _struct.c datetimemodule.c _functoolsmodule.c _collectionsmodule.c itertoolsmodule.c resource.c signalmodule.c selectmodule.c fcntlmodule.c timemodule.c arraymodule.c)
# compile specified files in from_cpython/Objects
file(GLOB_RECURSE STDOBJECT_SRCS Objects structseq.c capsule.c stringobject.c)
......
......@@ -46,6 +46,7 @@
#define HAVE_EPOLL 1
#define HAVE_POLL 1
#define HAVE_SELECT 1
#define HAVE_ALARM 1
#define PY_FORMAT_LONG_LONG "ll"
#define PY_FORMAT_SIZE_T "z"
......@@ -62,11 +63,13 @@
#define HAVE_ALLOCA_H 1
#define HAVE_ASM_TYPES_H 1
#define HAVE_CLOCK 1
#define HAVE_CURSES_H 1
#define HAVE_DIRENT_H 1
#define HAVE_DLFCN_H 1
#define HAVE_ERRNO_H 1
#define HAVE_FCNTL_H 1
#define HAVE_FTIME 1
#define HAVE_GRP_H 1
#define HAVE_INTTYPES_H 1
#define HAVE_LANGINFO_H 1
......@@ -99,7 +102,6 @@
#define HAVE_SYS_STATVFS_H 1
#define HAVE_SYS_STAT_H 1
#define HAVE_SYS_TIMES_H 1
#define HAVE_SYS_TIME_H 1
#define HAVE_SYS_TYPES_H 1
#define HAVE_SYS_UN_H 1
#define HAVE_SYS_UTSNAME_H 1
......
......@@ -292,6 +292,20 @@ typedef ssize_t Py_ssize_t;
#define Py_MEMCPY memcpy
#endif
/********************************************
* WRAPPER FOR <time.h> and/or <sys/time.h> *
********************************************/
#ifdef TIME_WITH_SYS_TIME
#include <sys/time.h>
#include <time.h>
#else /* !TIME_WITH_SYS_TIME */
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#else /* !HAVE_SYS_TIME_H */
#include <time.h>
#endif /* !HAVE_SYS_TIME_H */
#endif /* !TIME_WITH_SYS_TIME */
#endif /* Py_PYPORT_H */
"""Extract, format and print information about Python stack traces."""
# This module has been heavily modified for Pyston, since we don't provide the
# same traceback objects as CPython.
import linecache
import sys
import types
......@@ -56,7 +59,20 @@ def print_tb(tb, limit=None, file=None):
if limit is None:
if hasattr(sys, 'tracebacklimit'):
limit = sys.tracebacklimit
n = 0
# Pyston change:
for (filename, name, lineno) in tb.getLines():
if limit and n >= limit:
break
_print(file,
' File "%s", line %d, in %s' % (filename, lineno, name))
linecache.checkcache(filename)
line = linecache.getline(filename, lineno, None)
if line: _print(file, ' ' + line.strip())
n = n+1
"""
while tb is not None and (limit is None or n < limit):
f = tb.tb_frame
lineno = tb.tb_lineno
......@@ -70,6 +86,7 @@ def print_tb(tb, limit=None, file=None):
if line: _print(file, ' ' + line.strip())
tb = tb.tb_next
n = n+1
"""
def format_tb(tb, limit = None):
"""A shorthand for 'format_list(extract_tb(tb, limit))'."""
......@@ -91,6 +108,18 @@ def extract_tb(tb, limit = None):
limit = sys.tracebacklimit
list = []
n = 0
# Pyston change:
for (filename, name, lineno) in tb.getLines():
if limit and n >= limit:
break
linecache.checkcache(filename)
line = linecache.getline(filename, lineno, None)
if line: line = line.strip()
else: line = None
list.append((filename, lineno, name, line))
n = n+1
"""
while tb is not None and (limit is None or n < limit):
f = tb.tb_frame
lineno = tb.tb_lineno
......@@ -104,6 +133,7 @@ def extract_tb(tb, limit = None):
list.append((filename, lineno, name, line))
tb = tb.tb_next
n = n+1
"""
return list
......@@ -262,6 +292,8 @@ def print_stack(f=None, limit=None, file=None):
stack frame at which to start. The optional 'limit' and 'file'
arguments have the same meaning as for print_exception().
"""
raise NotImplementedError("This function is currently not implemented in Pyston")
if f is None:
try:
raise ZeroDivisionError
......@@ -271,6 +303,8 @@ def print_stack(f=None, limit=None, file=None):
def format_stack(f=None, limit=None):
"""Shorthand for 'format_list(extract_stack(f, limit))'."""
raise NotImplementedError("This function is currently not implemented in Pyston")
if f is None:
try:
raise ZeroDivisionError
......@@ -287,6 +321,8 @@ def extract_stack(f=None, limit = None):
line number, function name, text), and the entries are in order
from oldest to newest stack frame.
"""
raise NotImplementedError("This function is currently not implemented in Pyston")
if f is None:
try:
raise ZeroDivisionError
......@@ -317,4 +353,6 @@ def tb_lineno(tb):
Obsolete in 2.3.
"""
raise NotImplementedError("This function is currently not implemented in Pyston")
return tb.tb_lineno
......@@ -2249,6 +2249,13 @@ initarray(void)
Arraytype.ob_type = &PyType_Type;
PyArrayIter_Type.ob_type = &PyType_Type;
// Pyston change: let the GC know about our type
if (PyType_Ready(&Arraytype))
return;
if (PyType_Ready(&PyArrayIter_Type))
return;
m = Py_InitModule3("array", a_methods, module_doc);
if (m == NULL)
return;
......
# sre_parse._parse() is a pretty hard function for us to jit
#
# It's hard to call directly, so instead call sre_compile.compile which (indirectly) calls _parse()
import sre_compile
for i in xrange(1000):
sre_compile.compile("", 0)
This diff is collapsed.
# -*- coding: utf-8 -*-
# The Computer Language Benchmarks Game
# http://shootout.alioth.debian.org/
#
# modified by Ian Osgood
# modified again by Heinrich Acker
import sys, bisect
# pyston change:
import hashlib
class HashOutput:
def __init__(self):
self.m = hashlib.md5()
def write(self, string):
self.m.update(string)
def md5hash(self):
return self.m.hexdigest()
hash_output = HashOutput()
old_stdout = sys.stdout
sys.stdout = hash_output
alu = (
'GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGG'
'GAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGA'
'CCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAAT'
'ACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCA'
'GCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGG'
'AGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCC'
'AGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAA')
iub = zip('acgtBDHKMNRSVWY', [0.27, 0.12, 0.12, 0.27] + [0.02]*11)
homosapiens = [
('a', 0.3029549426680),
('c', 0.1979883004921),
('g', 0.1975473066391),
('t', 0.3015094502008),
]
def genRandom(lim, ia = 3877, ic = 29573, im = 139968):
seed = 42
imf = float(im)
while 1:
seed = (seed * ia + ic) % im
yield lim * seed / imf
Random = genRandom(1.)
def makeCumulative(table):
P = []
C = []
prob = 0.
for char, p in table:
prob += p
P += [prob]
C += [char]
return (P, C)
def repeatFasta(src, n):
width = 60
r = len(src)
s = src + src + src[:n % r]
for j in xrange(n // width):
i = j*width % r
print s[i:i+width]
if n % width:
print s[-(n % width):]
def randomFasta(table, n):
width = 60
r = xrange(width)
gR = Random.next
bb = bisect.bisect
jn = ''.join
probs, chars = makeCumulative(table)
for j in xrange(n // width):
print jn([chars[bb(probs, gR())] for i in r])
if n % width:
print jn([chars[bb(probs, gR())] for i in xrange(n % width)])
#n = int(sys.argv[1])
#for i in range(int(sys.argv[2])):
n = 1000
for i in range(int(1000)):
print '>ONE Homo sapiens alu'
repeatFasta(alu, n*2)
print '>TWO IUB ambiguity codes'
randomFasta(iub, n*3)
print '>THREE Homo sapiens frequency'
randomFasta(homosapiens, n*5)
sys.stdout = old_stdout
print hash_output.md5hash()
This diff is collapsed.
......@@ -14,6 +14,8 @@
#include "analysis/scoping_analysis.h"
#include "llvm/ADT/DenseSet.h"
#include "core/ast.h"
#include "core/common.h"
#include "core/util.h"
......@@ -113,7 +115,7 @@ struct ScopingAnalysis::ScopeNameUsage {
const std::string* private_name;
ScopingAnalysis* scoping;
typedef std::unordered_set<InternedString> StrSet;
typedef llvm::DenseSet<InternedString> StrSet;
// Properties determined from crawling the scope:
StrSet read;
......
......@@ -508,6 +508,12 @@ void Rewriter::_loadConst(RewriterVar* result, int64_t val, Location dest) {
assertConsistent();
}
RewriterVar* Rewriter::call(bool can_call_into_python, void* func_addr) {
std::vector<RewriterVar*> args = {};
std::vector<RewriterVar*> args_xmm = {};
return call(can_call_into_python, func_addr, args, args_xmm);
}
RewriterVar* Rewriter::call(bool can_call_into_python, void* func_addr, RewriterVar* arg0) {
std::vector<RewriterVar*> args = { arg0 };
std::vector<RewriterVar*> args_xmm = {};
......
......@@ -445,6 +445,7 @@ public:
RewriterVar* loadConst(int64_t val, Location loc = Location::any());
RewriterVar* call(bool can_call_into_python, void* func_addr, const std::vector<RewriterVar*>& args,
const std::vector<RewriterVar*>& args_xmm = std::vector<RewriterVar*>());
RewriterVar* call(bool can_call_into_python, void* func_addr);
RewriterVar* call(bool can_call_into_python, void* func_addr, RewriterVar* arg0);
RewriterVar* call(bool can_call_into_python, void* func_addr, RewriterVar* arg0, RewriterVar* arg1);
RewriterVar* add(RewriterVar* a, int64_t b, Location dest);
......
......@@ -284,6 +284,116 @@ extern "C" PyObject* PyObject_CallFunctionObjArgs(PyObject* callable, ...) noexc
return tmp;
}
extern "C" PyObject* PyObject_CallObject(PyObject* obj, PyObject* args) noexcept {
RELEASE_ASSERT(args, ""); // actually it looks like this is allowed to be NULL
RELEASE_ASSERT(args->cls == tuple_cls, "");
// TODO do something like this? not sure if this is safe; will people expect that calling into a known function
// won't end up doing a GIL check?
// threading::GLDemoteRegion _gil_demote;
try {
Box* r = runtimeCall(obj, ArgPassSpec(0, 0, true, false), args, NULL, NULL, NULL, NULL);
return r;
} catch (ExcInfo e) {
Py_FatalError("unimplemented");
}
}
static PyObject* call_function_tail(PyObject* callable, PyObject* args) {
PyObject* retval;
if (args == NULL)
return NULL;
if (!PyTuple_Check(args)) {
PyObject* a;
a = PyTuple_New(1);
if (a == NULL) {
Py_DECREF(args);
return NULL;
}
PyTuple_SET_ITEM(a, 0, args);
args = a;
}
retval = PyObject_Call(callable, args, NULL);
Py_DECREF(args);
return retval;
}
extern "C" PyObject* PyObject_CallMethod(PyObject* o, char* name, char* format, ...) noexcept {
Py_FatalError("unimplemented");
}
extern "C" PyObject* _PyObject_CallMethod_SizeT(PyObject* o, char* name, char* format, ...) noexcept {
// TODO it looks like this could be made much more efficient by calling our callattr(), but
// I haven't taken the time to verify that that has the same behavior
va_list va;
PyObject* args;
PyObject* func = NULL;
PyObject* retval = NULL;
if (o == NULL || name == NULL)
return null_error();
func = PyObject_GetAttrString(o, name);
if (func == NULL) {
PyErr_SetString(PyExc_AttributeError, name);
return 0;
}
if (!PyCallable_Check(func)) {
type_error("attribute of type '%.200s' is not callable", func);
goto exit;
}
if (format && *format) {
va_start(va, format);
args = _Py_VaBuildValue_SizeT(format, va);
va_end(va);
} else
args = PyTuple_New(0);
retval = call_function_tail(func, args);
exit:
/* args gets consumed in call_function_tail */
Py_XDECREF(func);
return retval;
}
extern "C" Py_ssize_t PyObject_Size(PyObject* o) noexcept {
try {
return len(o)->n;
} catch (ExcInfo e) {
setCAPIException(e);
return -1;
}
}
extern "C" PyObject* PyObject_GetIter(PyObject* o) noexcept {
try {
return getiter(o);
} catch (ExcInfo e) {
setCAPIException(e);
return NULL;
}
}
extern "C" PyObject* PyObject_Repr(PyObject* obj) noexcept {
try {
return repr(obj);
} catch (ExcInfo e) {
setCAPIException(e);
return NULL;
}
}
static int recursive_issubclass(PyObject* derived, PyObject* cls) noexcept {
int retval;
......@@ -508,4 +618,44 @@ extern "C" PyObject* PySequence_List(PyObject* v) noexcept {
extern "C" PyObject* PyObject_CallFunction(PyObject* callable, char* format, ...) noexcept {
Py_FatalError("unimplemented");
}
extern "C" int PyMapping_Check(PyObject* o) noexcept {
if (o && PyInstance_Check(o))
return PyObject_HasAttrString(o, "__getitem__");
return o && o->cls->tp_as_mapping && o->cls->tp_as_mapping->mp_subscript
&& !(o->cls->tp_as_sequence && o->cls->tp_as_sequence->sq_slice);
}
extern "C" Py_ssize_t PyMapping_Size(PyObject* o) noexcept {
PyMappingMethods* m;
if (o == NULL) {
null_error();
return -1;
}
m = o->cls->tp_as_mapping;
if (m && m->mp_length)
return m->mp_length(o);
type_error("object of type '%.200s' has no len()", o);
return -1;
}
extern "C" int PyMapping_HasKeyString(PyObject* o, char* key) noexcept {
Py_FatalError("unimplemented");
}
extern "C" int PyMapping_HasKey(PyObject* o, PyObject* key) noexcept {
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyMapping_GetItemString(PyObject* o, char* key) noexcept {
Py_FatalError("unimplemented");
}
extern "C" int PyMapping_SetItemString(PyObject* o, char* key, PyObject* v) noexcept {
Py_FatalError("unimplemented");
}
}
......@@ -218,6 +218,10 @@ extern "C" PyObject* Py_VaBuildValue(const char* format, va_list va) noexcept {
return va_build_value(format, va, 0);
}
extern "C" PyObject* _Py_VaBuildValue_SizeT(const char* format, va_list va) noexcept {
return va_build_value(format, va, FLAG_SIZE_T);
}
extern "C" PyObject* _Py_BuildValue_SizeT(const char* fmt, ...) noexcept {
va_list ap;
va_start(ap, fmt);
......
......@@ -1337,15 +1337,6 @@ void fixup_slot_dispatchers(BoxedClass* self) noexcept {
const slotdef* p = slotdefs;
while (p->name)
p = update_one_slot(self, p);
// TODO: CPython handles this by having the __name__ attribute wrap (via a getset object)
// the tp_name field, whereas we're (needlessly?) doing the opposite.
if (!self->tp_name) {
Box* b = self->getattr("__name__");
assert(b);
assert(b->cls == str_cls);
self->tp_name = static_cast<BoxedString*>(b)->s.c_str();
}
}
static PyObject* tp_new_wrapper(PyTypeObject* self, BoxedTuple* args, Box* kwds) noexcept {
......@@ -1729,7 +1720,6 @@ extern "C" int PyType_Ready(PyTypeObject* cls) noexcept {
RELEASE_ASSERT(cls->tp_getattro == NULL || cls->tp_getattro == PyObject_GenericGetAttr, "");
RELEASE_ASSERT(cls->tp_setattro == NULL || cls->tp_setattro == PyObject_GenericSetAttr, "");
RELEASE_ASSERT(cls->tp_as_buffer == NULL, "");
int ALLOWABLE_FLAGS = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_CHECKTYPES;
RELEASE_ASSERT((cls->tp_flags & ~ALLOWABLE_FLAGS) == 0, "");
......@@ -1771,7 +1761,6 @@ extern "C" int PyType_Ready(PyTypeObject* cls) noexcept {
cls->tp_dict = makeAttrWrapper(cls);
assert(cls->tp_name);
cls->giveAttr("__name__", boxStrConstant(cls->tp_name));
// tp_name
// tp_basicsize, tp_itemsize
// tp_doc
......
......@@ -82,6 +82,9 @@ public:
assert(rtn && "should have set + thrown an exception!");
return rtn;
}
static Box* callInternal(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args, ArgPassSpec argspec, Box* arg1,
Box* arg2, Box* arg3, Box** args, const std::vector<const std::string*>* keyword_names);
};
class BoxedWrapperDescriptor : public Box {
......
This diff is collapsed.
......@@ -1219,7 +1219,7 @@ private:
KnownClassobjType(BoxedClass* cls) : cls(cls) { assert(cls); }
public:
std::string debugName() override { return "class '" + *getNameOfClass(cls) + "'"; }
std::string debugName() override { return "class '" + std::string(getNameOfClass(cls)) + "'"; }
void assertMatches(BoxedClass* cls) override { assert(cls == this->cls); }
......@@ -1276,7 +1276,7 @@ public:
assert(cls);
// TODO add getTypeName
return "NormalType(" + *getNameOfClass(cls) + ")";
return "NormalType(" + std::string(getNameOfClass(cls)) + ")";
}
ConcreteCompilerVariable* makeConverted(IREmitter& emitter, ConcreteCompilerVariable* var,
ConcreteCompilerType* other_type) override {
......@@ -1332,7 +1332,7 @@ public:
Box* rtattr = cls->getattr(*attr);
if (rtattr == NULL) {
llvm::CallSite call = emitter.createCall2(info.unw_info, g.funcs.raiseAttributeErrorStr,
getStringConstantPtr(*getNameOfClass(cls) + "\0"),
getStringConstantPtr(std::string(getNameOfClass(cls)) + "\0"),
getStringConstantPtr(*attr + '\0'));
call.setDoesNotReturn();
return undefVariable();
......@@ -1383,7 +1383,7 @@ public:
*no_attribute = true;
} else {
llvm::CallSite call = emitter.createCall2(info.unw_info, g.funcs.raiseAttributeErrorStr,
getStringConstantPtr(*getNameOfClass(cls) + "\0"),
getStringConstantPtr(std::string(getNameOfClass(cls)) + "\0"),
getStringConstantPtr(*attr + '\0'));
call.setDoesNotReturn();
}
......@@ -1578,9 +1578,16 @@ public:
ConcreteCompilerVariable* nonzero(IREmitter& emitter, const OpInfo& info, ConcreteCompilerVariable* var) override {
static const std::string attr("__nonzero__");
bool no_attribute = false;
ConcreteCompilerVariable* called_constant
= tryCallattrConstant(emitter, info, var, &attr, true, ArgPassSpec(0, 0, 0, 0), {}, NULL);
if (called_constant)
= tryCallattrConstant(emitter, info, var, &attr, true, ArgPassSpec(0, 0, 0, 0), {}, NULL, &no_attribute);
// TODO: if no_attribute, we could optimize by continuing the dispatch process and trying
// to call __len__ (and if that doesn't exist, returning a static true).
// For now, I'd rather not duplicate the dispatch behavior between here and objmodel.cpp::nonzero.
if (called_constant && !no_attribute)
return called_constant;
if (cls == bool_cls) {
......
......@@ -93,7 +93,7 @@ const std::string SourceInfo::getName() {
case AST_TYPE::Lambda:
return "<lambda>";
case AST_TYPE::Module:
return this->parent_module->name();
return "<module>";
default:
RELEASE_ASSERT(0, "%d", ast->type);
}
......@@ -104,6 +104,8 @@ ScopeInfo* SourceInfo::getScopeInfo() {
}
EffortLevel::EffortLevel initialEffort() {
if (FORCE_INTERPRETER)
return EffortLevel::INTERPRETED;
if (FORCE_OPTIMIZE)
return EffortLevel::MAXIMAL;
if (ENABLE_INTERPRETER)
......
......@@ -29,6 +29,7 @@
#include "codegen/irgen/hooks.h"
#include "codegen/stackmaps.h"
#include "core/util.h"
#include "runtime/traceback.h"
#include "runtime/types.h"
......@@ -438,22 +439,22 @@ static const LineInfo* lineInfoForFrame(PythonFrameIterator& frame_it) {
AST_stmt* current_stmt = frame_it.getCurrentStatement();
auto* cf = frame_it.getCF();
assert(cf);
return new LineInfo(current_stmt->lineno, current_stmt->col_offset, cf->clfunc->source->parent_module->fn,
cf->clfunc->source->getName());
}
std::vector<const LineInfo*> getTracebackEntries() {
std::vector<const LineInfo*> entries;
auto source = cf->clfunc->source;
return new LineInfo(current_stmt->lineno, current_stmt->col_offset, source->parent_module->fn, source->getName());
}
BoxedTraceback* getTraceback() {
if (!ENABLE_FRAME_INTROSPECTION) {
static bool printed_warning = false;
if (!printed_warning) {
printed_warning = true;
fprintf(stderr, "Warning: can't get traceback since ENABLE_FRAME_INTROSPECTION=0\n");
}
return entries;
return new BoxedTraceback();
}
std::vector<const LineInfo*> entries;
for (auto& frame_info : unwindPythonFrames()) {
const LineInfo* line_info = lineInfoForFrame(frame_info);
if (line_info)
......@@ -461,12 +462,7 @@ std::vector<const LineInfo*> getTracebackEntries() {
}
std::reverse(entries.begin(), entries.end());
return entries;
}
const LineInfo* getMostRecentLineInfo() {
std::unique_ptr<PythonFrameIterator> frame = getTopPythonFrame();
return lineInfoForFrame(*frame);
return new BoxedTraceback(std::move(entries));
}
ExcInfo* getFrameExcInfo() {
......
......@@ -21,11 +21,12 @@
namespace pyston {
std::vector<const LineInfo*> getTracebackEntries();
const LineInfo* getMostRecentLineInfo();
class BoxedModule;
BoxedModule* getCurrentModule();
class BoxedTraceback;
BoxedTraceback* getTraceback();
class BoxedDict;
BoxedDict* getLocals(bool only_user_visible);
......
......@@ -662,11 +662,23 @@ public:
AST_TYPE::AST_TYPE ctx_type;
InternedString id;
// The resolved scope of this name. Kind of hacky to be storing it in the AST node;
// in CPython it ends up getting "cached" by being translated into one of a number of
// different bytecodes.
// We don't have a separate bytecode representation, so just store it in here for now.
enum LookupType {
UNKNOWN,
GLOBAL,
CLOSURE,
FAST_LOCAL,
LOCAL,
} lookup_type;
virtual void accept(ASTVisitor* v);
virtual void* accept_expr(ExprVisitor* v);
AST_Name(InternedString id, AST_TYPE::AST_TYPE ctx_type, int lineno, int col_offset = 0)
: AST_expr(AST_TYPE::Name, lineno, col_offset), ctx_type(ctx_type), id(id) {}
: AST_expr(AST_TYPE::Name, lineno, col_offset), ctx_type(ctx_type), id(id), lookup_type(UNKNOWN) {}
static const AST_TYPE::AST_TYPE TYPE = AST_TYPE::Name;
};
......
......@@ -29,6 +29,7 @@ int PYTHON_VERSION_HEX = version_hex(PYTHON_VERSION_MAJOR, PYTHON_VERSION_MINOR,
int MAX_OPT_ITERATIONS = 1;
bool FORCE_INTERPRETER = false;
bool FORCE_OPTIMIZE = false;
bool SHOW_DISASM = false;
bool PROFILE = false;
......@@ -63,4 +64,8 @@ bool ENABLE_RUNTIME_ICS = 1 && _GLOBAL_ENABLE;
bool ENABLE_FRAME_INTROSPECTION = 1;
bool BOOLS_AS_I64 = ENABLE_FRAME_INTROSPECTION;
extern "C" {
int Py_IgnoreEnvironmentFlag = 1;
}
}
......@@ -31,8 +31,8 @@ inline int version_hex(int major, int minor, int micro, int level = 0, int seria
extern int MAX_OPT_ITERATIONS;
extern bool SHOW_DISASM, FORCE_OPTIMIZE, PROFILE, DUMPJIT, TRAP, USE_STRIPPED_STDLIB, ENABLE_INTERPRETER,
ENABLE_PYPA_PARSER, USE_REGALLOC_BASIC;
extern bool SHOW_DISASM, FORCE_INTERPRETER, FORCE_OPTIMIZE, PROFILE, DUMPJIT, TRAP, USE_STRIPPED_STDLIB,
ENABLE_INTERPRETER, ENABLE_PYPA_PARSER, USE_REGALLOC_BASIC;
extern bool ENABLE_ICS, ENABLE_ICGENERICS, ENABLE_ICGETITEMS, ENABLE_ICSETITEMS, ENABLE_ICDELITEMS, ENABLE_ICBINEXPS,
ENABLE_ICNONZEROS, ENABLE_ICCALLSITES, ENABLE_ICSETATTRS, ENABLE_ICGETATTRS, ENALBE_ICDELATTRS, ENABLE_ICGETGLOBALS,
......
......@@ -19,6 +19,7 @@
#include <cstdio>
#include <sys/time.h>
#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/StringRef.h"
......@@ -41,6 +42,8 @@ private:
// Only for testing purposes:
InternedStringPool* pool;
InternedString(const std::string* str, InternedStringPool* pool) : _str(str), pool(pool) {}
static InternedStringPool* invalidPool() { return reinterpret_cast<InternedStringPool*>(-1); }
#else
InternedString(const std::string* str) : _str(str) {}
#endif
......@@ -64,8 +67,9 @@ public:
}
bool operator==(InternedString rhs) const {
assert(this->_str);
assert(this->pool == rhs.pool);
assert(this->_str || this->pool == invalidPool());
assert(rhs._str || rhs.pool == invalidPool());
assert(this->pool == rhs.pool || this->pool == invalidPool() || rhs.pool == invalidPool());
return this->_str == rhs._str;
}
......@@ -78,6 +82,7 @@ public:
friend class InternedStringPool;
friend struct std::hash<InternedString>;
friend struct std::less<InternedString>;
friend struct llvm::DenseMapInfo<pyston::InternedString>;
};
class InternedStringPool {
......@@ -130,4 +135,25 @@ template <> struct less<pyston::InternedString> {
};
}
namespace llvm {
template <> struct DenseMapInfo<pyston::InternedString> {
static inline pyston::InternedString getEmptyKey() {
#ifndef NDEBUG
return pyston::InternedString(nullptr, pyston::InternedString::invalidPool());
#else
return pyston::InternedString(nullptr);
#endif
}
static inline pyston::InternedString getTombstoneKey() {
#ifndef NDEBUG
return pyston::InternedString((const std::string*)-1, pyston::InternedString::invalidPool());
#else
return pyston::InternedString((const std::string*)-1);
#endif
}
static unsigned getHashValue(const pyston::InternedString& val) { return std::hash<pyston::InternedString>()(val); }
static bool isEqual(const pyston::InternedString& lhs, const pyston::InternedString& rhs) { return lhs == rhs; }
};
}
#endif
......@@ -62,6 +62,8 @@ struct ArgPassSpec {
&& num_args == rhs.num_args;
}
bool operator!=(ArgPassSpec rhs) { return !(*this == rhs); }
int totalPassed() { return num_args + num_keywords + (has_starargs ? 1 : 0) + (has_kwargs ? 1 : 0); }
uintptr_t asInt() const { return *reinterpret_cast<const uintptr_t*>(this); }
......@@ -119,7 +121,7 @@ typedef ValuedCompilerVariable<llvm::Value*> ConcreteCompilerVariable;
class Box;
class BoxedClass;
class BoxedModule;
class BoxedFunction;
class BoxedFunctionBase;
class ICGetattr;
struct ICSlotInfo;
......@@ -280,7 +282,7 @@ public:
// of the normal dispatch through the functionlist.
// This can be used to implement functions which know how to rewrite themselves,
// such as typeCall.
typedef Box* (*InternalCallable)(BoxedFunction*, CallRewriteArgs*, ArgPassSpec, Box*, Box*, Box*, Box**,
typedef Box* (*InternalCallable)(BoxedFunctionBase*, CallRewriteArgs*, ArgPassSpec, Box*, Box*, Box*, Box**,
const std::vector<const std::string*>*);
InternalCallable internal_callable = NULL;
......@@ -332,7 +334,7 @@ EffortLevel::EffortLevel initialEffort();
typedef bool i1;
typedef int64_t i64;
extern "C" const std::string* getNameOfClass(BoxedClass* cls);
const char* getNameOfClass(BoxedClass* cls);
std::string getFullNameOfClass(BoxedClass* cls);
class Rewriter;
......@@ -454,10 +456,8 @@ public:
};
static_assert(offsetof(BoxVar, ob_size) == offsetof(struct _varobject, ob_size), "");
extern "C" const std::string* getTypeName(Box* o);
std::string getFullTypeName(Box* o);
const char* getTypeName(Box* b);
class BoxedClass;
......@@ -473,7 +473,6 @@ void prependToSysPath(const std::string& path);
void addToSysArgv(const char* str);
std::string formatException(Box* e);
void printLastTraceback();
// Raise a SyntaxError that occurs at a specific location.
// The traceback given to the user will include this,
......@@ -498,6 +497,7 @@ struct ExcInfo {
ExcInfo(Box* type, Box* value, Box* traceback) : type(type), value(value), traceback(traceback) {}
#endif
bool matches(BoxedClass* cls) const;
void printExcAndTraceback() const;
};
struct FrameInfo {
......
......@@ -232,7 +232,7 @@ static void markPhase() {
BoxedClass* cls = b->cls;
if (cls) {
ASSERT(cls->gc_visit, "%s", getTypeName(b)->c_str());
ASSERT(cls->gc_visit, "%s", getTypeName(b));
cls->gc_visit(&visitor, b);
}
}
......@@ -268,7 +268,7 @@ static void markPhase() {
// An arbitrary amount of stuff can happen between the 'new' and
// the call to the constructor (ie the args get evaluated), which
// can trigger a collection.
ASSERT(cls->gc_visit, "%s", getTypeName(b)->c_str());
ASSERT(cls->gc_visit, "%s", getTypeName(b));
cls->gc_visit(&visitor, b);
}
} else if (kind_id == GCKind::HIDDEN_CLASS) {
......
......@@ -42,7 +42,8 @@ extern "C" void* gc_compat_realloc(void* ptr, size_t sz) noexcept {
}
extern "C" void gc_compat_free(void* ptr) noexcept {
gc_free(ptr);
if (ptr)
gc_free(ptr);
}
// We may need to hook malloc as well. For now, these definitions serve
......
......@@ -300,7 +300,7 @@ static void _doFree(GCAllocation* al) {
if (al->kind_id == GCKind::PYTHON) {
Box* b = (Box*)al->user_data;
ASSERT(b->cls->tp_dealloc == NULL, "%s", getTypeName(b)->c_str());
ASSERT(b->cls->tp_dealloc == NULL, "%s", getTypeName(b));
}
}
......
......@@ -58,7 +58,7 @@ int main(int argc, char** argv) {
bool force_repl = false;
bool repl = true;
bool stats = false;
while ((code = getopt(argc, argv, "+Oqcdibpjtrsvnx")) != -1) {
while ((code = getopt(argc, argv, "+OqcdIibpjtrsvnx")) != -1) {
if (code == 'O')
FORCE_OPTIMIZE = true;
else if (code == 't')
......@@ -71,6 +71,8 @@ int main(int argc, char** argv) {
// caching = true;
else if (code == 'd')
SHOW_DISASM = true;
else if (code == 'I')
FORCE_INTERPRETER = true;
else if (code == 'i')
force_repl = true;
else if (code == 'n') {
......@@ -155,9 +157,7 @@ int main(int argc, char** argv) {
printf("Warning: ignoring SystemExit code\n");
return 1;
} else {
std::string msg = formatException(e.value);
printLastTraceback();
fprintf(stderr, "%s\n", msg.c_str());
e.printExcAndTraceback();
return 1;
}
}
......@@ -224,9 +224,7 @@ int main(int argc, char** argv) {
printf("Warning: ignoring SystemExit code\n");
return 1;
} else {
std::string msg = formatException(e.value);
printLastTraceback();
fprintf(stderr, "%s\n", msg.c_str());
e.printExcAndTraceback();
}
}
}
......
......@@ -48,8 +48,6 @@ extern "C" Box* boolNew(Box* cls, Box* val) {
}
void setupBool() {
bool_cls->giveAttr("__name__", boxStrConstant("bool"));
bool_cls->giveAttr("__nonzero__", new BoxedFunction(boxRTFunction((void*)boolNonzero, BOXED_BOOL, 1)));
bool_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)boolRepr, STR, 1)));
bool_cls->giveAttr("__hash__", new BoxedFunction(boxRTFunction((void*)boolHash, BOXED_INT, 1)));
......
This diff is collapsed.
......@@ -40,9 +40,9 @@ static Box* enable() {
void setupGC() {
BoxedModule* gc_module = createModule("gc", "__builtin__");
gc_module->giveAttr("__hex__", new BoxedFunction(boxRTFunction((void*)gcCollect, NONE, 0)));
gc_module->giveAttr("isenabled", new BoxedFunction(boxRTFunction((void*)isEnabled, BOXED_BOOL, 0)));
gc_module->giveAttr("disable", new BoxedFunction(boxRTFunction((void*)disable, NONE, 0)));
gc_module->giveAttr("enable", new BoxedFunction(boxRTFunction((void*)enable, NONE, 0)));
gc_module->giveAttr("__hex__", new BoxedBuiltinFunctionOrMethod(boxRTFunction((void*)gcCollect, NONE, 0)));
gc_module->giveAttr("isenabled", new BoxedBuiltinFunctionOrMethod(boxRTFunction((void*)isEnabled, BOXED_BOOL, 0)));
gc_module->giveAttr("disable", new BoxedBuiltinFunctionOrMethod(boxRTFunction((void*)disable, NONE, 0)));
gc_module->giveAttr("enable", new BoxedBuiltinFunctionOrMethod(boxRTFunction((void*)enable, NONE, 0)));
}
}
// Copyright (c) 2014-2015 Dropbox, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "core/types.h"
#include "runtime/objmodel.h"
#include "runtime/types.h"
namespace pyston {
BoxedModule* pyston_module;
static Box* setOption(Box* option, Box* value) {
if (option->cls != str_cls)
raiseExcHelper(TypeError, "option must be a 'string' object but received a '%s'", getTypeName(option));
BoxedString* option_string = (BoxedString*)option;
if (value->cls != int_cls)
raiseExcHelper(TypeError, "value must be a 'int' object but received a '%s'", getTypeName(value));
bool enable = ((BoxedInt*)value)->n;
if (option_string->s == "ENABLE_INTERPRETER")
ENABLE_INTERPRETER = enable;
else if (option_string->s == "ENABLE_OSR")
ENABLE_OSR = enable;
else if (option_string->s == "ENABLE_REOPT")
ENABLE_REOPT = enable;
else if (option_string->s == "FORCE_INTERPRETER")
FORCE_INTERPRETER = enable;
else
raiseExcHelper(ValueError, "unknown option name '%s", option_string->s.c_str());
return None;
}
void setupPyston() {
pyston_module = createModule("__pyston__", "__builtin__");
pyston_module->giveAttr("setOption", new BoxedBuiltinFunctionOrMethod(boxRTFunction((void*)setOption, UNKNOWN, 2)));
}
}
......@@ -22,6 +22,7 @@
#include "codegen/unwinding.h"
#include "core/types.h"
#include "gc/collector.h"
#include "runtime/file.h"
#include "runtime/inline/boxing.h"
#include "runtime/int.h"
#include "runtime/types.h"
......@@ -224,9 +225,11 @@ void setupSys() {
sys_module->giveAttr("stdin", new BoxedFile(stdin, "<stdin>", "r"));
sys_module->giveAttr("stderr", new BoxedFile(stderr, "<stderr>", "w"));
sys_module->giveAttr("exc_info", new BoxedFunction(boxRTFunction((void*)sysExcInfo, BOXED_TUPLE, 0)));
sys_module->giveAttr("exc_clear", new BoxedFunction(boxRTFunction((void*)sysExcClear, NONE, 0)));
sys_module->giveAttr("exit", new BoxedFunction(boxRTFunction((void*)sysExit, NONE, 1, 1, false, false), { None }));
sys_module->giveAttr("exc_info",
new BoxedBuiltinFunctionOrMethod(boxRTFunction((void*)sysExcInfo, BOXED_TUPLE, 0)));
sys_module->giveAttr("exc_clear", new BoxedBuiltinFunctionOrMethod(boxRTFunction((void*)sysExcClear, NONE, 0)));
sys_module->giveAttr(
"exit", new BoxedBuiltinFunctionOrMethod(boxRTFunction((void*)sysExit, NONE, 1, 1, false, false), { None }));
sys_module->giveAttr("warnoptions", new BoxedList());
sys_module->giveAttr("py3kwarning", False);
......@@ -254,8 +257,7 @@ void setupSys() {
sys_module->giveAttr("maxint", boxInt(PYSTON_INT_MAX));
sys_flags_cls = new BoxedHeapClass(object_cls, BoxedSysFlags::gcHandler, 0, sizeof(BoxedSysFlags), false);
sys_flags_cls->giveAttr("__name__", boxStrConstant("flags"));
sys_flags_cls = new BoxedHeapClass(object_cls, BoxedSysFlags::gcHandler, 0, sizeof(BoxedSysFlags), false, "flags");
sys_flags_cls->giveAttr("__new__",
new BoxedFunction(boxRTFunction((void*)BoxedSysFlags::__new__, UNKNOWN, 1, 0, true, true)));
#define ADD(name) \
......
......@@ -32,9 +32,7 @@ static void* thread_start(Box* target, Box* varargs, Box* kwargs) {
try {
runtimeCall(target, ArgPassSpec(0, 0, true, kwargs != NULL), varargs, kwargs, NULL, NULL, NULL);
} catch (ExcInfo e) {
std::string msg = formatException(e.value);
printLastTraceback();
fprintf(stderr, "%s\n", msg.c_str());
e.printExcAndTraceback();
}
return NULL;
}
......@@ -139,13 +137,16 @@ Box* stackSize() {
void setupThread() {
thread_module = createModule("thread", "__builtin__");
thread_module->giveAttr("start_new_thread", new BoxedFunction(boxRTFunction((void*)startNewThread, BOXED_INT, 2)));
thread_module->giveAttr("allocate_lock", new BoxedFunction(boxRTFunction((void*)allocateLock, UNKNOWN, 0)));
thread_module->giveAttr("get_ident", new BoxedFunction(boxRTFunction((void*)getIdent, BOXED_INT, 0)));
thread_module->giveAttr("stack_size", new BoxedFunction(boxRTFunction((void*)stackSize, BOXED_INT, 0)));
thread_module->giveAttr("start_new_thread",
new BoxedBuiltinFunctionOrMethod(boxRTFunction((void*)startNewThread, BOXED_INT, 2)));
thread_module->giveAttr("allocate_lock",
new BoxedBuiltinFunctionOrMethod(boxRTFunction((void*)allocateLock, UNKNOWN, 0)));
thread_module->giveAttr("get_ident",
new BoxedBuiltinFunctionOrMethod(boxRTFunction((void*)getIdent, BOXED_INT, 0)));
thread_module->giveAttr("stack_size",
new BoxedBuiltinFunctionOrMethod(boxRTFunction((void*)stackSize, BOXED_INT, 0)));
thread_lock_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedThreadLock), false);
thread_lock_cls->giveAttr("__name__", boxStrConstant("lock"));
thread_lock_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedThreadLock), false, "lock");
thread_lock_cls->giveAttr("__module__", boxStrConstant("thread"));
thread_lock_cls->giveAttr(
"acquire",
......@@ -157,15 +158,13 @@ void setupThread() {
thread_lock_cls->giveAttr("__exit__", new BoxedFunction(boxRTFunction((void*)BoxedThreadLock::exit, NONE, 4)));
thread_lock_cls->freeze();
thread_local_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedThreadLocal), false);
thread_local_cls->giveAttr("__name__", boxStrConstant("_local"));
thread_local_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedThreadLocal), false, "_local");
thread_local_cls->giveAttr("__module__", boxStrConstant("thread"));
thread_local_cls->freeze();
thread_module->giveAttr("_local", thread_local_cls);
BoxedClass* ThreadError
= new BoxedHeapClass(Exception, NULL, Exception->attrs_offset, Exception->tp_basicsize, false);
ThreadError->giveAttr("__name__", boxStrConstant("error"));
= new BoxedHeapClass(Exception, NULL, Exception->attrs_offset, Exception->tp_basicsize, false, "error");
ThreadError->giveAttr("__module__", boxStrConstant("thread"));
ThreadError->freeze();
......
// Copyright (c) 2014-2015 Dropbox, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <cmath>
#include <ctime>
#include <err.h>
#include <sys/time.h>
#include "core/threading.h"
#include "core/types.h"
#include "runtime/objmodel.h"
#include "runtime/types.h"
namespace pyston {
BoxedModule* time_module;
/* Exposed in timefuncs.h. */
extern "C" time_t _PyTime_DoubleToTimet(double x) noexcept {
time_t result;
double diff;
result = (time_t)x;
/* How much info did we lose? time_t may be an integral or
* floating type, and we don't know which. If it's integral,
* we don't know whether C truncates, rounds, returns the floor,
* etc. If we lost a second or more, the C rounding is
* unreasonable, or the input just doesn't fit in a time_t;
* call it an error regardless. Note that the original cast to
* time_t can cause a C error too, but nothing we can do to
* worm around that.
*/
diff = x - (double)result;
if (diff <= -1.0 || diff >= 1.0) {
PyErr_SetString(PyExc_ValueError, "timestamp out of range for platform time_t");
result = (time_t)-1;
}
return result;
}
Box* timeTime() {
struct timeval now;
gettimeofday(&now, NULL);
double t = now.tv_sec + .000001 * now.tv_usec;
return boxFloat(t);
}
Box* timeSleep(Box* arg) {
double secs;
if (isSubclass(arg->cls, int_cls))
secs = static_cast<BoxedInt*>(arg)->n;
else if (arg->cls == float_cls)
secs = static_cast<BoxedFloat*>(arg)->d;
else {
raiseExcHelper(TypeError, "a float is required");
}
double fullsecs;
double nanosecs = modf(secs, &fullsecs);
struct timespec req;
req.tv_sec = (int)(fullsecs + 0.01);
req.tv_nsec = (int)(nanosecs * 1000000000);
{
threading::GLAllowThreadsReadRegion _allow_threads;
int code = nanosleep(&req, NULL);
if (code)
err(1, NULL);
}
return None;
}
void setupTime() {
time_module = createModule("time", "__builtin__");
time_module->giveAttr("time", new BoxedFunction(boxRTFunction((void*)timeTime, BOXED_FLOAT, 0)));
time_module->giveAttr("sleep", new BoxedFunction(boxRTFunction((void*)timeSleep, NONE, 1)));
}
}
......@@ -25,8 +25,11 @@
#include "core/threading.h"
#include "core/types.h"
#include "runtime/classobj.h"
#include "runtime/file.h"
#include "runtime/import.h"
#include "runtime/objmodel.h"
#include "runtime/rewrite_args.h"
#include "runtime/traceback.h"
#include "runtime/types.h"
namespace pyston {
......@@ -78,6 +81,10 @@ Box* BoxedWrapperDescriptor::__get__(BoxedWrapperDescriptor* self, Box* inst, Bo
return new BoxedWrapperObject(self, inst);
}
extern "C" int PyObject_AsCharBuffer(PyObject* obj, const char** buffer, Py_ssize_t* buffer_len) noexcept {
Py_FatalError("unimplemented");
}
// copied from CPython's getargs.c:
extern "C" int PyBuffer_FillInfo(Py_buffer* view, PyObject* obj, void* buf, Py_ssize_t len, int readonly,
int flags) noexcept {
......@@ -147,57 +154,6 @@ extern "C" void PyObject_Free(void* p) noexcept {
ASSERT(0, "I think this is good enough but I'm not sure; should test");
}
extern "C" PyObject* PyObject_CallObject(PyObject* obj, PyObject* args) noexcept {
RELEASE_ASSERT(args, ""); // actually it looks like this is allowed to be NULL
RELEASE_ASSERT(args->cls == tuple_cls, "");
// TODO do something like this? not sure if this is safe; will people expect that calling into a known function
// won't end up doing a GIL check?
// threading::GLDemoteRegion _gil_demote;
try {
Box* r = runtimeCall(obj, ArgPassSpec(0, 0, true, false), args, NULL, NULL, NULL, NULL);
return r;
} catch (ExcInfo e) {
Py_FatalError("unimplemented");
}
}
extern "C" PyObject* PyObject_CallMethod(PyObject* o, char* name, char* format, ...) noexcept {
Py_FatalError("unimplemented");
}
extern "C" PyObject* _PyObject_CallMethod_SizeT(PyObject* o, char* name, char* format, ...) noexcept {
Py_FatalError("unimplemented");
}
extern "C" Py_ssize_t PyObject_Size(PyObject* o) noexcept {
try {
return len(o)->n;
} catch (ExcInfo e) {
setCAPIException(e);
return -1;
}
}
extern "C" PyObject* PyObject_GetIter(PyObject* o) noexcept {
try {
return getiter(o);
} catch (ExcInfo e) {
setCAPIException(e);
return NULL;
}
}
extern "C" PyObject* PyObject_Repr(PyObject* obj) noexcept {
try {
return repr(obj);
} catch (ExcInfo e) {
setCAPIException(e);
return NULL;
}
}
extern "C" PyObject* PyObject_Format(PyObject* obj, PyObject* format_spec) noexcept {
PyObject* empty = NULL;
PyObject* result = NULL;
......@@ -536,6 +492,9 @@ extern "C" Py_ssize_t PySequence_Index(PyObject* o, PyObject* value) noexcept {
}
extern "C" PyObject* PySequence_Tuple(PyObject* o) noexcept {
if (o->cls == tuple_cls)
return o;
Py_FatalError("unimplemented");
}
......@@ -686,8 +645,6 @@ void checkAndThrowCAPIException() {
assert(!cur_thread_state.curexc_value);
if (_type) {
RELEASE_ASSERT(cur_thread_state.curexc_traceback == NULL || cur_thread_state.curexc_traceback == None,
"unsupported");
BoxedClass* type = static_cast<BoxedClass*>(_type);
assert(isInstance(_type, type_cls) && isSubclass(static_cast<BoxedClass*>(type), BaseException)
&& "Only support throwing subclass of BaseException for now");
......@@ -696,6 +653,10 @@ void checkAndThrowCAPIException() {
if (!value)
value = None;
Box* tb = cur_thread_state.curexc_traceback;
if (!tb)
tb = None;
// This is similar to PyErr_NormalizeException:
if (!isInstance(value, type)) {
if (value->cls == tuple_cls) {
......@@ -711,6 +672,8 @@ void checkAndThrowCAPIException() {
RELEASE_ASSERT(value->cls == type, "unsupported");
PyErr_Clear();
if (tb != None)
raiseRaw(ExcInfo(value->cls, value, tb));
raiseExc(value);
}
}
......@@ -737,6 +700,12 @@ extern "C" PyObject* PyErr_Format(PyObject* exception, const char* format, ...)
Py_FatalError("unimplemented");
}
extern "C" int PyErr_BadArgument() noexcept {
// TODO this is untested
PyErr_SetString(PyExc_TypeError, "bad argument type for built-in operation");
return 0;
}
extern "C" PyObject* PyErr_NoMemory() noexcept {
Py_FatalError("unimplemented");
}
......@@ -759,7 +728,10 @@ extern "C" PyObject* PyExceptionInstance_Class(PyObject* o) noexcept {
}
extern "C" int PyTraceBack_Print(PyObject* v, PyObject* f) noexcept {
Py_FatalError("unimplemented");
RELEASE_ASSERT(f->cls == file_cls && static_cast<BoxedFile*>(f)->f_fp == stderr,
"sorry will only print tracebacks to stderr right now");
printTraceback(v);
return 0;
}
#define Py_DEFAULT_RECURSION_LIMIT 1000
......@@ -1441,34 +1413,56 @@ BoxedModule* importTestExtension(const std::string& name) {
return m;
}
Box* BoxedCApiFunction::callInternal(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args, ArgPassSpec argspec,
Box* arg1, Box* arg2, Box* arg3, Box** args,
const std::vector<const std::string*>* keyword_names) {
if (argspec != ArgPassSpec(2))
return callFunc(func, rewrite_args, argspec, arg1, arg2, arg3, args, keyword_names);
assert(arg1->cls == capifunc_cls);
BoxedCApiFunction* capifunc = static_cast<BoxedCApiFunction*>(arg1);
if (capifunc->ml_flags != METH_O)
return callFunc(func, rewrite_args, argspec, arg1, arg2, arg3, args, keyword_names);
if (rewrite_args) {
rewrite_args->arg1->addGuard((intptr_t)arg1);
rewrite_args->out_rtn
= rewrite_args->rewriter->call(true, (void*)capifunc->func, rewrite_args->arg1, rewrite_args->arg2);
rewrite_args->rewriter->call(true, (void*)checkAndThrowCAPIException);
rewrite_args->out_success = true;
}
Box* r = capifunc->func(arg1, arg2);
checkAndThrowCAPIException();
assert(r);
return r;
}
void setupCAPI() {
capifunc_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedCApiFunction), false);
capifunc_cls->giveAttr("__name__", boxStrConstant("capifunc"));
capifunc_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedCApiFunction), false, "capifunc");
capifunc_cls->giveAttr("__repr__",
new BoxedFunction(boxRTFunction((void*)BoxedCApiFunction::__repr__, UNKNOWN, 1)));
capifunc_cls->giveAttr(
"__call__", new BoxedFunction(boxRTFunction((void*)BoxedCApiFunction::__call__, UNKNOWN, 1, 0, true, true)));
auto capi_call = new BoxedFunction(boxRTFunction((void*)BoxedCApiFunction::__call__, UNKNOWN, 1, 0, true, true));
capi_call->f->internal_callable = BoxedCApiFunction::callInternal;
capifunc_cls->giveAttr("__call__", capi_call);
capifunc_cls->freeze();
method_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedMethodDescriptor), false);
method_cls->giveAttr("__name__", boxStrConstant("method"));
method_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedMethodDescriptor), false, "method");
method_cls->giveAttr("__get__",
new BoxedFunction(boxRTFunction((void*)BoxedMethodDescriptor::__get__, UNKNOWN, 3)));
method_cls->giveAttr("__call__", new BoxedFunction(boxRTFunction((void*)BoxedMethodDescriptor::__call__, UNKNOWN, 2,
0, true, true)));
method_cls->freeze();
wrapperdescr_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedWrapperDescriptor), false);
wrapperdescr_cls->giveAttr("__name__", boxStrConstant("wrapper_descriptor"));
wrapperdescr_cls
= new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedWrapperDescriptor), false, "wrapper_descriptor");
wrapperdescr_cls->giveAttr("__get__",
new BoxedFunction(boxRTFunction((void*)BoxedWrapperDescriptor::__get__, UNKNOWN, 3)));
wrapperdescr_cls->freeze();
wrapperobject_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedWrapperObject), false);
wrapperobject_cls->giveAttr("__name__", boxStrConstant("method-wrapper"));
wrapperobject_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedWrapperObject), false, "method-wrapper");
wrapperobject_cls->giveAttr(
"__call__", new BoxedFunction(boxRTFunction((void*)BoxedWrapperObject::__call__, UNKNOWN, 1, 0, true, true)));
wrapperobject_cls->freeze();
......
......@@ -63,12 +63,12 @@ extern "C" int PyClass_IsSubclass(PyObject* klass, PyObject* base) noexcept {
Box* classobjNew(Box* _cls, Box* _name, Box* _bases, Box** _args) {
if (!isSubclass(_cls->cls, type_cls))
raiseExcHelper(TypeError, "classobj.__new__(X): X is not a type object (%s)", getTypeName(_cls)->c_str());
raiseExcHelper(TypeError, "classobj.__new__(X): X is not a type object (%s)", getTypeName(_cls));
BoxedClass* cls = static_cast<BoxedClass*>(_cls);
if (!isSubclass(cls, classobj_cls))
raiseExcHelper(TypeError, "classobj.__new__(%s): %s is not a subtype of classobj", getNameOfClass(cls)->c_str(),
getNameOfClass(cls)->c_str());
raiseExcHelper(TypeError, "classobj.__new__(%s): %s is not a subtype of classobj", getNameOfClass(cls),
getNameOfClass(cls));
if (_name->cls != str_cls)
raiseExcHelper(TypeError, "argument 1 must be string, not %s", getTypeName(_name));
......@@ -129,7 +129,7 @@ Box* classobjCall(Box* _cls, Box* _args, Box* _kwargs) {
Box* classobjStr(Box* _obj) {
if (!isSubclass(_obj->cls, classobj_cls)) {
raiseExcHelper(TypeError, "descriptor '__str__' requires a 'classobj' object but received an '%s'",
getTypeName(_obj)->c_str());
getTypeName(_obj));
}
BoxedClassobj* cls = static_cast<BoxedClassobj*>(_obj);
......@@ -271,11 +271,9 @@ Box* instanceSetitem(Box* _inst, Box* key, Box* value) {
void setupClassobj() {
classobj_cls = new BoxedHeapClass(object_cls, &BoxedClassobj::gcHandler, offsetof(BoxedClassobj, attrs),
sizeof(BoxedClassobj), false);
sizeof(BoxedClassobj), false, "classobj");
instance_cls = new BoxedHeapClass(object_cls, &BoxedInstance::gcHandler, offsetof(BoxedInstance, attrs),
sizeof(BoxedInstance), false);
classobj_cls->giveAttr("__name__", boxStrConstant("classobj"));
sizeof(BoxedInstance), false, "instance");
classobj_cls->giveAttr("__new__",
new BoxedFunction(boxRTFunction((void*)classobjNew, UNKNOWN, 4, 0, false, false)));
......@@ -288,8 +286,6 @@ void setupClassobj() {
classobj_cls->freeze();
instance_cls->giveAttr("__name__", boxStrConstant("instance"));
instance_cls->giveAttr("__getattribute__",
new BoxedFunction(boxRTFunction((void*)instanceGetattribute, UNKNOWN, 2)));
instance_cls->giveAttr("__str__", new BoxedFunction(boxRTFunction((void*)instanceStr, UNKNOWN, 1)));
......
......@@ -252,8 +252,6 @@ Box* complexNew(Box* _cls, Box* real, Box* imag) {
}
void setupComplex() {
complex_cls->giveAttr("__name__", boxStrConstant("complex"));
complex_cls->giveAttr("__new__", new BoxedFunction(boxRTFunction((void*)complexNew, UNKNOWN, 3, 2, false, false),
{ boxInt(0), boxInt(0) }));
......
......@@ -168,11 +168,9 @@ static Box* classmethodGet(Box* self, Box* obj, Box* type) {
}
void setupDescr() {
member_cls->giveAttr("__name__", boxStrConstant("member"));
member_cls->giveAttr("__get__", new BoxedFunction(boxRTFunction((void*)memberGet, UNKNOWN, 3)));
member_cls->freeze();
property_cls->giveAttr("__name__", boxStrConstant("property"));
property_cls->giveAttr(
"__init__",
new BoxedFunction(boxRTFunction((void*)propertyInit, UNKNOWN, 5, 4, false, false), { NULL, NULL, NULL, NULL }));
......@@ -192,7 +190,6 @@ void setupDescr() {
new BoxedMemberDescriptor(BoxedMemberDescriptor::OBJECT, offsetof(BoxedProperty, prop_doc)));
property_cls->freeze();
staticmethod_cls->giveAttr("__name__", boxStrConstant("staticmethod"));
staticmethod_cls->giveAttr("__init__",
new BoxedFunction(boxRTFunction((void*)staticmethodInit, UNKNOWN, 5, 4, false, false),
{ None, None, None, None }));
......@@ -201,7 +198,6 @@ void setupDescr() {
staticmethod_cls->freeze();
classmethod_cls->giveAttr("__name__", boxStrConstant("classmethod"));
classmethod_cls->giveAttr("__init__",
new BoxedFunction(boxRTFunction((void*)classmethodInit, UNKNOWN, 5, 4, false, false),
{ None, None, None, None }));
......
This diff is collapsed.
This diff is collapsed.
// Copyright (c) 2014-2015 Dropbox, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef PYSTON_RUNTIME_FILE_H
#define PYSTON_RUNTIME_FILE_H
#include "core/types.h"
#include "runtime/types.h"
namespace pyston {
class BoxedFile : public Box {
public:
PyObject_HEAD FILE* f_fp;
PyObject* f_name;
PyObject* f_mode;
int (*f_close)(FILE*);
int f_softspace; /* Flag used by 'print' command */
int f_binary; /* Flag which indicates whether the file is
open in binary (1) or text (0) mode */
char* f_buf; /* Allocated readahead buffer */
char* f_bufend; /* Points after last occupied position */
char* f_bufptr; /* Current buffer position */
char* f_setbuf; /* Buffer for setbuf(3) and setvbuf(3) */
int f_univ_newline; /* Handle any newline convention */
int f_newlinetypes; /* Types of newlines seen */
int f_skipnextlf; /* Skip next \n */
PyObject* f_encoding;
PyObject* f_errors;
#if 0
PyObject* weakreflist; /* List of weak references */
#endif
int unlocked_count; /* Num. currently running sections of code
using f_fp with the GIL released. */
int readable;
int writable;
BoxedFile(FILE* f, std::string fname, const char* fmode, int (*close)(FILE*) = fclose)
__attribute__((visibility("default")));
DEFAULT_CLASS(file_cls);
};
}
#endif
......@@ -569,8 +569,7 @@ BoxedFloat* _floatNew(Box* a) {
ArgPassSpec(0), NULL, NULL, NULL, NULL, NULL);
if (!r) {
fprintf(stderr, "TypeError: float() argument must be a string or a number, not '%s'\n",
getTypeName(a)->c_str());
fprintf(stderr, "TypeError: float() argument must be a string or a number, not '%s'\n", getTypeName(a));
raiseExcHelper(TypeError, "");
}
......@@ -583,12 +582,12 @@ BoxedFloat* _floatNew(Box* a) {
Box* floatNew(BoxedClass* _cls, Box* a) {
if (!isSubclass(_cls->cls, type_cls))
raiseExcHelper(TypeError, "float.__new__(X): X is not a type object (%s)", getTypeName(_cls)->c_str());
raiseExcHelper(TypeError, "float.__new__(X): X is not a type object (%s)", getTypeName(_cls));
BoxedClass* cls = static_cast<BoxedClass*>(_cls);
if (!isSubclass(cls, float_cls))
raiseExcHelper(TypeError, "float.__new__(%s): %s is not a subtype of float", getNameOfClass(cls)->c_str(),
getNameOfClass(cls)->c_str());
raiseExcHelper(TypeError, "float.__new__(%s): %s is not a subtype of float", getNameOfClass(cls),
getNameOfClass(cls));
if (cls == float_cls)
......@@ -602,7 +601,7 @@ Box* floatNew(BoxedClass* _cls, Box* a) {
Box* floatStr(BoxedFloat* self) {
if (!isSubclass(self->cls, float_cls))
raiseExcHelper(TypeError, "descriptor '__str__' requires a 'float' object but received a '%s'",
getTypeName(self)->c_str());
getTypeName(self));
return boxString(floatFmt(self->d, 12, 'g'));
}
......@@ -635,8 +634,6 @@ static void _addFunc(const char* name, ConcreteCompilerType* rtn_type, void* flo
}
void setupFloat() {
float_cls->giveAttr("__name__", boxStrConstant("float"));
_addFunc("__add__", BOXED_FLOAT, (void*)floatAddFloat, (void*)floatAddInt, (void*)floatAdd);
float_cls->giveAttr("__radd__", float_cls->getattr("__add__"));
......
......@@ -49,7 +49,7 @@ static void generatorEntry(BoxedGenerator* g) {
try {
// call body of the generator
BoxedFunction* func = g->function;
BoxedFunctionBase* func = g->function;
Box** args = g->args ? &g->args->elts[0] : nullptr;
callCLFunc(func->f, nullptr, func->f->numReceivedArgs(), func->closure, g, g->arg1, g->arg2, g->arg3, args);
......@@ -138,14 +138,14 @@ extern "C" Box* yield(BoxedGenerator* obj, Box* value) {
}
extern "C" BoxedGenerator* createGenerator(BoxedFunction* function, Box* arg1, Box* arg2, Box* arg3, Box** args) {
extern "C" BoxedGenerator* createGenerator(BoxedFunctionBase* function, Box* arg1, Box* arg2, Box* arg3, Box** args) {
assert(function);
assert(function->cls == function_cls);
return new BoxedGenerator(function, arg1, arg2, arg3, args);
}
extern "C" BoxedGenerator::BoxedGenerator(BoxedFunction* function, Box* arg1, Box* arg2, Box* arg3, Box** args)
extern "C" BoxedGenerator::BoxedGenerator(BoxedFunctionBase* function, Box* arg1, Box* arg2, Box* arg3, Box** args)
: function(function), arg1(arg1), arg2(arg2), arg3(arg3), args(nullptr), entryExited(false), running(false),
returnValue(nullptr), exception(nullptr, nullptr, nullptr) {
......@@ -237,8 +237,7 @@ extern "C" void generatorGCHandler(GCVisitor* v, Box* b) {
void setupGenerator() {
generator_cls = new BoxedHeapClass(object_cls, &generatorGCHandler, offsetof(BoxedGenerator, attrs),
sizeof(BoxedGenerator), false);
generator_cls->giveAttr("__name__", boxStrConstant("generator"));
sizeof(BoxedGenerator), false, "generator");
generator_cls->giveAttr("__iter__",
new BoxedFunction(boxRTFunction((void*)generatorIter, typeFromClass(generator_cls), 1)));
......
......@@ -25,7 +25,7 @@ extern BoxedClass* generator_cls;
void setupGenerator();
extern "C" Box* yield(BoxedGenerator* obj, Box* value);
extern "C" BoxedGenerator* createGenerator(BoxedFunction* function, Box* arg1, Box* arg2, Box* arg3, Box** args);
extern "C" BoxedGenerator* createGenerator(BoxedFunctionBase* function, Box* arg1, Box* arg2, Box* arg3, Box** args);
}
#endif
......@@ -48,13 +48,13 @@ Box* boxString(std::string&& s) {
}
extern "C" double unboxFloat(Box* b) {
ASSERT(b->cls == float_cls, "%s", getTypeName(b)->c_str());
ASSERT(b->cls == float_cls, "%s", getTypeName(b));
BoxedFloat* f = (BoxedFloat*)b;
return f->d;
}
i64 unboxInt(Box* b) {
ASSERT(b->cls == int_cls, "%s", getTypeName(b)->c_str());
ASSERT(b->cls == int_cls, "%s", getTypeName(b));
return ((BoxedInt*)b)->n;
}
......
......@@ -88,21 +88,21 @@ Box* xrange(Box* cls, Box* start, Box* stop, Box** args) {
Box* step = args[0];
if (stop == NULL) {
RELEASE_ASSERT(isSubclass(start->cls, int_cls), "%s", getTypeName(start)->c_str());
RELEASE_ASSERT(isSubclass(start->cls, int_cls), "%s", getTypeName(start));
i64 istop = static_cast<BoxedInt*>(start)->n;
return new BoxedXrange(0, istop, 1);
} else if (step == NULL) {
RELEASE_ASSERT(isSubclass(start->cls, int_cls), "%s", getTypeName(start)->c_str());
RELEASE_ASSERT(isSubclass(stop->cls, int_cls), "%s", getTypeName(stop)->c_str());
RELEASE_ASSERT(isSubclass(start->cls, int_cls), "%s", getTypeName(start));
RELEASE_ASSERT(isSubclass(stop->cls, int_cls), "%s", getTypeName(stop));
i64 istart = static_cast<BoxedInt*>(start)->n;
i64 istop = static_cast<BoxedInt*>(stop)->n;
return new BoxedXrange(istart, istop, 1);
} else {
RELEASE_ASSERT(isSubclass(start->cls, int_cls), "%s", getTypeName(start)->c_str());
RELEASE_ASSERT(isSubclass(stop->cls, int_cls), "%s", getTypeName(stop)->c_str());
RELEASE_ASSERT(isSubclass(step->cls, int_cls), "%s", getTypeName(step)->c_str());
RELEASE_ASSERT(isSubclass(start->cls, int_cls), "%s", getTypeName(start));
RELEASE_ASSERT(isSubclass(stop->cls, int_cls), "%s", getTypeName(stop));
RELEASE_ASSERT(isSubclass(step->cls, int_cls), "%s", getTypeName(step));
i64 istart = static_cast<BoxedInt*>(start)->n;
i64 istop = static_cast<BoxedInt*>(stop)->n;
......@@ -120,11 +120,9 @@ Box* xrangeIter(Box* self) {
}
void setupXrange() {
xrange_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedXrange), false);
xrange_cls->giveAttr("__name__", boxStrConstant("xrange"));
xrange_cls = new BoxedHeapClass(object_cls, NULL, 0, sizeof(BoxedXrange), false, "xrange");
xrange_iterator_cls = new BoxedHeapClass(object_cls, &BoxedXrangeIterator::xrangeIteratorGCHandler, 0,
sizeof(BoxedXrangeIterator), false);
xrange_iterator_cls->giveAttr("__name__", boxStrConstant("rangeiterator"));
sizeof(BoxedXrangeIterator), false, "rangeiterator");
xrange_cls->giveAttr(
"__new__",
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -100,9 +100,12 @@ struct BinopRewriteArgs;
extern "C" Box* binopInternal(Box* lhs, Box* rhs, int op_type, bool inplace, BinopRewriteArgs* rewrite_args);
struct CallRewriteArgs;
Box* typeCallInternal(BoxedFunction* f, CallRewriteArgs* rewrite_args, ArgPassSpec argspec, Box* arg1, Box* arg2,
Box* typeCallInternal(BoxedFunctionBase* f, CallRewriteArgs* rewrite_args, ArgPassSpec argspec, Box* arg1, Box* arg2,
Box* arg3, Box** args, const std::vector<const std::string*>* keyword_names);
Box* callFunc(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args, ArgPassSpec argspec, Box* arg1, Box* arg2,
Box* arg3, Box** args, const std::vector<const std::string*>* keyword_names);
enum LookupScope {
CLASS_ONLY = 1,
INST_ONLY = 2,
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -3,3 +3,4 @@ print type(time)
time.sleep(0)
time.sleep(False)
time.clock()
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment