Commit 6acfb996 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Implement defaults, keywords, varargs and kwargs

Not all exposed to python code yet

This commit is pretty large because it contains two separate but interrelated changes:
- Rewrite the function argument handling code (callCompiledFunction and resolveCLFunc)
  into a single callFunc that does its own rewriting, and support the new features.
-- this required a change of data representations, so instead of having each function
   consist of variants with unrelated signatures, we can only have a single signature,
   but multiple type specializations of that signature
- To do that, had to rewrite all of the stdlib functions that used signature-variation
  (ex range1 + range2 + range3) to be a single function that took default arguments, and
  then took action appropriately.
parent 31f7002a
This diff is collapsed.
......@@ -115,6 +115,9 @@ public:
abort();
}
virtual CompilerVariable* getitem(IREmitter& emitter, const OpInfo& info, VAR* value, CompilerVariable* v) {
// Can almost do this, except for error messages + types:
// static const std::string attr("__getitem__");
// return callattr(emitter, info, value, &attr, true, ArgPassSpec(1, 0, 0, 0), {v}, NULL);
printf("getitem not defined for %s\n", debugName().c_str());
abort();
}
......@@ -314,7 +317,7 @@ ConcreteCompilerVariable* makeFloat(double);
ConcreteCompilerVariable* makeBool(bool);
CompilerVariable* makeStr(std::string*);
CompilerVariable* makeFunction(IREmitter& emitter, CLFunction*);
CompilerVariable* undefVariable();
ConcreteCompilerVariable* undefVariable();
CompilerVariable* makeTuple(const std::vector<CompilerVariable*>& elts);
ConcreteCompilerType* typeFromClass(BoxedClass*);
......
......@@ -563,7 +563,7 @@ static void emitBBs(IRGenState* irstate, const char* bb_type, GuardList& out_gua
emitter->getBuilder()->SetInsertPoint(llvm_entry_blocks[source->cfg->getStartingBlock()]);
}
generator->unpackArguments(arg_names, cf->sig->arg_types);
generator->unpackArguments(arg_names, cf->spec->arg_types);
} else if (entry_descriptor && block == entry_descriptor->backedge->target) {
assert(block->predecessors.size() > 1);
assert(osr_entry_block);
......@@ -882,7 +882,7 @@ static std::string getUniqueFunctionName(std::string nameprefix, EffortLevel::Ef
}
CompiledFunction* doCompile(SourceInfo* source, const OSREntryDescriptor* entry_descriptor,
EffortLevel::EffortLevel effort, FunctionSignature* sig,
EffortLevel::EffortLevel effort, FunctionSpecialization* spec,
const std::vector<AST_expr*>& arg_names, std::string nameprefix) {
Timer _t("in doCompile");
......@@ -899,7 +899,7 @@ CompiledFunction* doCompile(SourceInfo* source, const OSREntryDescriptor* entry_
// Initializing the llvm-level structures:
int nargs = arg_names.size();
ASSERT(nargs == sig->arg_types.size(), "%d %ld", nargs, sig->arg_types.size());
ASSERT(nargs == spec->arg_types.size(), "%d %ld", nargs, spec->arg_types.size());
std::vector<llvm::Type*> llvm_arg_types;
if (entry_descriptor == NULL) {
......@@ -908,7 +908,7 @@ CompiledFunction* doCompile(SourceInfo* source, const OSREntryDescriptor* entry_
llvm_arg_types.push_back(g.llvm_value_type_ptr->getPointerTo());
break;
}
llvm_arg_types.push_back(sig->arg_types[i]->llvmType());
llvm_arg_types.push_back(spec->arg_types[i]->llvmType());
}
} else {
int arg_num = -1;
......@@ -924,20 +924,20 @@ CompiledFunction* doCompile(SourceInfo* source, const OSREntryDescriptor* entry_
}
}
llvm::FunctionType* ft = llvm::FunctionType::get(sig->rtn_type->llvmType(), llvm_arg_types, false /*vararg*/);
llvm::FunctionType* ft = llvm::FunctionType::get(spec->rtn_type->llvmType(), llvm_arg_types, false /*vararg*/);
llvm::Function* f = llvm::Function::Create(ft, llvm::Function::ExternalLinkage, name, g.cur_module);
// g.func_registry.registerFunction(f, g.cur_module);
CompiledFunction* cf
= new CompiledFunction(f, sig, (effort == EffortLevel::INTERPRETED), NULL, NULL, effort, entry_descriptor);
= new CompiledFunction(f, spec, (effort == EffortLevel::INTERPRETED), NULL, NULL, effort, entry_descriptor);
llvm::MDNode* dbg_funcinfo = setupDebugInfo(source, f, nameprefix);
TypeAnalysis::SpeculationLevel speculation_level = TypeAnalysis::NONE;
if (ENABLE_SPECULATION && effort >= EffortLevel::MODERATE)
speculation_level = TypeAnalysis::SOME;
TypeAnalysis* types = doTypeAnalysis(source->cfg, arg_names, sig->arg_types, speculation_level,
TypeAnalysis* types = doTypeAnalysis(source->cfg, arg_names, spec->arg_types, speculation_level,
source->scoping->getScopeInfoForNode(source->ast));
GuardList guards;
......@@ -973,7 +973,7 @@ CompiledFunction* doCompile(SourceInfo* source, const OSREntryDescriptor* entry_
assert(deopt_full_blocks.size() || deopt_partial_blocks.size());
TypeAnalysis* deopt_types = doTypeAnalysis(source->cfg, arg_names, sig->arg_types, TypeAnalysis::NONE,
TypeAnalysis* deopt_types = doTypeAnalysis(source->cfg, arg_names, spec->arg_types, TypeAnalysis::NONE,
source->scoping->getScopeInfoForNode(source->ast));
emitBBs(&irstate, "deopt", deopt_guards, guards, deopt_types, arg_names, NULL, deopt_full_blocks,
deopt_partial_blocks);
......
......@@ -77,7 +77,7 @@ public:
};
CompiledFunction* doCompile(SourceInfo* source, const OSREntryDescriptor* entry_descriptor,
EffortLevel::EffortLevel effort, FunctionSignature* sig,
EffortLevel::EffortLevel effort, FunctionSpecialization* spec,
const std::vector<AST_expr*>& arg_names, std::string nameprefix);
class TypeRecorder;
......
......@@ -68,7 +68,6 @@ AST_arguments* SourceInfo::getArgsAST() {
const std::vector<AST_expr*>& SourceInfo::getArgNames() {
static std::vector<AST_expr*> empty;
assert(this);
AST_arguments* args = getArgsAST();
if (args == NULL)
......@@ -76,6 +75,12 @@ const std::vector<AST_expr*>& SourceInfo::getArgNames() {
return args->args;
}
const std::vector<AST_expr*>* CLFunction::getArgNames() {
if (!source)
return NULL;
return &source->getArgNames();
}
const std::vector<AST_stmt*>& SourceInfo::getBody() {
assert(ast);
switch (ast->type) {
......@@ -135,10 +140,10 @@ static void compileIR(CompiledFunction* cf, EffortLevel::EffortLevel effort) {
// Compiles a new version of the function with the given signature and adds it to the list;
// should only be called after checking to see if the other versions would work.
CompiledFunction* compileFunction(CLFunction* f, FunctionSignature* sig, EffortLevel::EffortLevel effort,
CompiledFunction* compileFunction(CLFunction* f, FunctionSpecialization* spec, EffortLevel::EffortLevel effort,
const OSREntryDescriptor* entry) {
Timer _t("for compileFunction()");
assert(sig);
assert(spec);
ASSERT(f->versions.size() < 20, "%ld", f->versions.size());
SourceInfo* source = f->source;
......@@ -160,15 +165,15 @@ CompiledFunction* compileFunction(CLFunction* f, FunctionSignature* sig, EffortL
llvm::raw_string_ostream ss(s);
ss << "\033[34;1mJIT'ing " << name << " with signature (";
for (int i = 0; i < sig->arg_types.size(); i++) {
for (int i = 0; i < spec->arg_types.size(); i++) {
if (i > 0)
ss << ", ";
ss << sig->arg_types[i]->debugName();
// sig->arg_types[i]->llvmType()->print(ss);
ss << spec->arg_types[i]->debugName();
// spec->arg_types[i]->llvmType()->print(ss);
}
ss << ") -> ";
ss << sig->rtn_type->debugName();
// sig->rtn_type->llvmType()->print(ss);
ss << spec->rtn_type->debugName();
// spec->rtn_type->llvmType()->print(ss);
ss << " at effort level " << effort;
if (entry != NULL) {
ss << "\nDoing OSR-entry partial compile, starting with backedge to block " << entry->backedge->target->idx
......@@ -187,7 +192,7 @@ CompiledFunction* compileFunction(CLFunction* f, FunctionSignature* sig, EffortL
source->scoping->getScopeInfoForNode(source->ast));
}
CompiledFunction* cf = doCompile(source, entry, effort, sig, arg_names, name);
CompiledFunction* cf = doCompile(source, entry, effort, spec, arg_names, name);
compileIR(cf, effort);
f->addVersion(cf);
......@@ -244,12 +249,11 @@ void compileAndRunModule(AST_Module* m, BoxedModule* bm) {
si->liveness = computeLivenessInfo(si->cfg);
si->phis = computeRequiredPhis(NULL, si->cfg, si->liveness, si->scoping->getScopeInfoForNode(si->ast));
CLFunction* cl_f = new CLFunction(si);
CLFunction* cl_f = new CLFunction(0, 0, false, false, si);
EffortLevel::EffortLevel effort = initialEffort();
CompiledFunction* cf
= compileFunction(cl_f, new FunctionSignature(VOID, &si->getArgNames(), 0, false, false), effort, NULL);
CompiledFunction* cf = compileFunction(cl_f, new FunctionSpecialization(VOID), effort, NULL);
assert(cf->clfunc->versions.size());
_t.end();
......@@ -268,7 +272,7 @@ static CompiledFunction* _doReopt(CompiledFunction* cf, EffortLevel::EffortLevel
assert(cf);
assert(cf->entry_descriptor == NULL && "We can't reopt an osr-entry compile!");
assert(cf->sig);
assert(cf->spec);
CLFunction* clfunc = cf->clfunc;
assert(clfunc);
......@@ -281,7 +285,7 @@ static CompiledFunction* _doReopt(CompiledFunction* cf, EffortLevel::EffortLevel
versions.erase(versions.begin() + i);
CompiledFunction* new_cf
= compileFunction(clfunc, cf->sig, new_effort,
= compileFunction(clfunc, cf->spec, new_effort,
NULL); // this pushes the new CompiledVersion to the back of the version list
cf->dependent_callsites.invalidateAll();
......@@ -289,6 +293,11 @@ static CompiledFunction* _doReopt(CompiledFunction* cf, EffortLevel::EffortLevel
return new_cf;
}
}
printf("Couldn't find a version; %ld exist:\n", versions.size());
for (auto cf : versions) {
printf("%p\n", cf);
}
assert(0 && "Couldn't find a version to reopt! Probably reopt'd already?");
abort();
}
......@@ -311,7 +320,7 @@ void* compilePartialFunc(OSRExit* exit) {
// EffortLevel::EffortLevel new_effort = (EffortLevel::EffortLevel)(exit->parent_cf->effort + 1);
// new_effort = EffortLevel::MAXIMAL;
CompiledFunction* compiled
= compileFunction(exit->parent_cf->clfunc, exit->parent_cf->sig, new_effort, exit->entry);
= compileFunction(exit->parent_cf->clfunc, exit->parent_cf->spec, new_effort, exit->entry);
assert(compiled = new_cf);
}
......@@ -331,55 +340,56 @@ extern "C" char* reoptCompiledFunc(CompiledFunction* cf) {
return (char*)new_cf->code;
}
CLFunction* createRTFunction() {
return new CLFunction(NULL);
CLFunction* createRTFunction(int num_args, int num_defaults, bool takes_varargs, bool takes_kwargs) {
return new CLFunction(num_args, num_defaults, takes_varargs, takes_kwargs, NULL);
}
extern "C" CLFunction* boxRTFunction(void* f, ConcreteCompilerType* rtn_type, int nargs, bool takes_varargs,
bool takes_kwargs) {
CLFunction* cl_f = createRTFunction();
CLFunction* boxRTFunction(void* f, ConcreteCompilerType* rtn_type, int num_args) {
return boxRTFunction(f, rtn_type, num_args, 0, false, false);
}
CLFunction* boxRTFunction(void* f, ConcreteCompilerType* rtn_type, int num_args, int num_defaults, bool takes_varargs,
bool takes_kwargs) {
CLFunction* cl_f = createRTFunction(num_args, num_defaults, takes_varargs, takes_kwargs);
addRTFunction(cl_f, f, rtn_type, nargs, takes_varargs, takes_kwargs);
addRTFunction(cl_f, f, rtn_type);
return cl_f;
}
void addRTFunction(CLFunction* cl_f, void* f, ConcreteCompilerType* rtn_type, int nargs, bool takes_varargs,
bool takes_kwargs) {
std::vector<ConcreteCompilerType*> arg_types(nargs, NULL);
return addRTFunction(cl_f, f, rtn_type, arg_types, takes_varargs, takes_kwargs);
void addRTFunction(CLFunction* cl_f, void* f, ConcreteCompilerType* rtn_type) {
std::vector<ConcreteCompilerType*> arg_types(cl_f->numReceivedArgs(), UNKNOWN);
return addRTFunction(cl_f, f, rtn_type, arg_types);
}
static ConcreteCompilerType* processType(ConcreteCompilerType* type) {
if (type == NULL)
return UNKNOWN;
assert(type);
return type;
}
void addRTFunction(CLFunction* cl_f, void* f, ConcreteCompilerType* rtn_type,
const std::vector<ConcreteCompilerType*>& arg_types, bool takes_varargs, bool takes_kwargs) {
FunctionSignature* sig = new FunctionSignature(processType(rtn_type), NULL, 0, takes_varargs, takes_kwargs);
const std::vector<ConcreteCompilerType*>& arg_types) {
assert(arg_types.size() == cl_f->numReceivedArgs());
#ifndef NDEBUG
for (ConcreteCompilerType* t : arg_types)
assert(t);
#endif
for (int i = 0; i < arg_types.size(); i++) {
sig->arg_types.push_back(processType(arg_types[i]));
}
FunctionSpecialization* spec = new FunctionSpecialization(processType(rtn_type), arg_types);
std::vector<llvm::Type*> llvm_arg_types;
int npassed_args = arg_types.size();
if (takes_varargs)
npassed_args++;
if (takes_kwargs)
npassed_args++;
assert(npassed_args == cl_f->numReceivedArgs());
for (int i = 0; i < npassed_args; i++) {
if (i == 3) {
llvm_arg_types.push_back(g.llvm_value_type_ptr->getPointerTo());
llvm_arg_types.push_back(g.i8_ptr->getPointerTo());
break;
}
llvm_arg_types.push_back(g.llvm_value_type_ptr);
llvm_arg_types.push_back(arg_types[i]->llvmType());
}
llvm::FunctionType* ft = llvm::FunctionType::get(g.llvm_value_type_ptr, llvm_arg_types, false);
cl_f->addVersion(
new CompiledFunction(NULL, sig, false, f, embedConstantPtr(f, ft->getPointerTo()), EffortLevel::MAXIMAL, NULL));
cl_f->addVersion(new CompiledFunction(NULL, spec, false, f, embedConstantPtr(f, ft->getPointerTo()),
EffortLevel::MAXIMAL, NULL));
}
}
......@@ -659,6 +659,15 @@ private:
std::vector<const std::string*>* keyword_names;
if (node->keywords.size()) {
keyword_names = getKeywordNameStorage(node);
// Only add the keywords to the array the first time, since
// the later times we will hit the cache which will have the
// keyword names already populated:
if (!keyword_names->size()) {
for (auto kw : node->keywords) {
keyword_names->push_back(&kw->arg);
}
}
} else {
keyword_names = NULL;
}
......@@ -671,7 +680,6 @@ private:
for (int i = 0; i < node->keywords.size(); i++) {
CompilerVariable* a = evalExpr(node->keywords[i]->value, exc_info);
args.push_back(a);
keyword_names->push_back(&node->keywords[i]->arg);
}
if (node->starargs)
......@@ -1246,6 +1254,9 @@ private:
ConcreteCompilerVariable* converted_val = val->makeConverted(emitter, val->getBoxType());
// TODO add a CompilerVariable::setattr, which can (similar to getitem)
// statically-resolve the function if possible, and only fall back to
// patchpoints if it couldn't.
bool do_patchpoint = ENABLE_ICSETITEMS && (irstate->getEffortLevel() != EffortLevel::INTERPRETED);
if (do_patchpoint) {
PatchpointSetupInfo* pp = patchpoints::createSetitemPatchpoint(emitter.currentFunction(),
......@@ -1431,7 +1442,8 @@ private:
if (cl == NULL) {
SourceInfo* si = new SourceInfo(irstate->getSourceInfo()->parent_module, irstate->getSourceInfo()->scoping);
si->ast = node;
cl = new CLFunction(si);
cl = new CLFunction(node->args->args.size(), node->args->defaults.size(), node->args->vararg.size(),
node->args->kwarg.size(), si);
}
return cl;
}
......
......@@ -72,8 +72,8 @@ public:
llvm::Value* getScratchSpace(int min_bytes);
ConcreteCompilerType* getReturnType() {
assert(cf->sig);
return cf->sig->rtn_type;
assert(cf->spec);
return cf->spec->rtn_type;
}
SourceInfo* getSourceInfo() { return source_info; }
......
......@@ -152,32 +152,17 @@ public:
// Codegen types:
struct FunctionSignature {
struct FunctionSpecialization {
ConcreteCompilerType* rtn_type;
const std::vector<AST_expr*>* arg_names;
std::vector<ConcreteCompilerType*> arg_types;
int ndefaults;
bool takes_varargs, takes_kwargs;
FunctionSignature(ConcreteCompilerType* rtn_type, const std::vector<AST_expr*>* arg_names, int ndefaults,
bool takes_varargs, bool takes_kwargs)
: rtn_type(rtn_type), arg_names(arg_names), ndefaults(ndefaults), takes_varargs(takes_varargs),
takes_kwargs(takes_kwargs) {}
FunctionSignature(ConcreteCompilerType* rtn_type, const std::vector<AST_expr*>* arg_names,
ConcreteCompilerType* arg1, ConcreteCompilerType* arg2, int ndefaults, bool takes_varargs,
bool takes_kwargs)
: rtn_type(rtn_type), arg_names(arg_names), ndefaults(ndefaults), takes_varargs(takes_varargs),
takes_kwargs(takes_kwargs) {
arg_types.push_back(arg1);
arg_types.push_back(arg2);
}
FunctionSpecialization(ConcreteCompilerType* rtn_type) : rtn_type(rtn_type) {}
FunctionSignature(ConcreteCompilerType* rtn_type, const std::vector<AST_expr*>* arg_names,
std::vector<ConcreteCompilerType*>& arg_types, int ndefaults, bool takes_varargs,
bool takes_kwargs)
: rtn_type(rtn_type), arg_names(arg_names), arg_types(arg_types), ndefaults(ndefaults),
takes_varargs(takes_varargs), takes_kwargs(takes_kwargs) {}
FunctionSpecialization(ConcreteCompilerType* rtn_type, ConcreteCompilerType* arg1, ConcreteCompilerType* arg2)
: rtn_type(rtn_type), arg_types({ arg1, arg2 }) {}
FunctionSpecialization(ConcreteCompilerType* rtn_type, const std::vector<ConcreteCompilerType*>& arg_types)
: rtn_type(rtn_type), arg_types(arg_types) {}
};
struct CompiledFunction {
......@@ -185,7 +170,7 @@ private:
public:
CLFunction* clfunc;
llvm::Function* func; // the llvm IR object
FunctionSignature* sig;
FunctionSpecialization* spec;
const OSREntryDescriptor* entry_descriptor;
bool is_interpreted;
......@@ -200,10 +185,10 @@ public:
int64_t times_called;
ICInvalidator dependent_callsites;
CompiledFunction(llvm::Function* func, FunctionSignature* sig, bool is_interpreted, void* code,
CompiledFunction(llvm::Function* func, FunctionSpecialization* spec, bool is_interpreted, void* code,
llvm::Value* llvm_code, EffortLevel::EffortLevel effort,
const OSREntryDescriptor* entry_descriptor)
: clfunc(NULL), func(func), sig(sig), entry_descriptor(entry_descriptor), is_interpreted(is_interpreted),
: clfunc(NULL), func(func), spec(spec), entry_descriptor(entry_descriptor), is_interpreted(is_interpreted),
code(code), llvm_code(llvm_code), effort(effort), times_called(0) {}
};
......@@ -229,6 +214,10 @@ public:
typedef std::vector<CompiledFunction*> FunctionList;
class CallRewriteArgs;
struct CLFunction {
int num_args;
int num_defaults;
bool takes_varargs, takes_kwargs;
SourceInfo* source;
FunctionList
versions; // any compiled versions along with their type parameters; in order from most preferred to least
......@@ -242,12 +231,21 @@ struct CLFunction {
const std::vector<const std::string*>*);
InternalCallable internal_callable = NULL;
CLFunction(SourceInfo* source) : source(source) {}
CLFunction(int num_args, int num_defaults, bool takes_varargs, bool takes_kwargs, SourceInfo* source)
: num_args(num_args), num_defaults(num_defaults), takes_varargs(takes_varargs), takes_kwargs(takes_kwargs),
source(source) {
assert(num_args >= num_defaults);
}
int numReceivedArgs() { return num_args + (takes_varargs ? 1 : 0) + (takes_kwargs ? 1 : 0); }
const std::vector<AST_expr*>* getArgNames();
void addVersion(CompiledFunction* compiled) {
assert(compiled);
assert((source == NULL) == (compiled->func == NULL));
assert(compiled->sig);
assert(compiled->spec);
assert(compiled->spec->arg_types.size() == num_args + (takes_varargs ? 1 : 0) + (takes_kwargs ? 1 : 0));
assert(compiled->clfunc == NULL);
assert(compiled->is_interpreted == (compiled->code == NULL));
assert(compiled->is_interpreted == (compiled->llvm_code == NULL));
......@@ -259,19 +257,18 @@ struct CLFunction {
}
};
extern "C" CLFunction* createRTFunction();
extern "C" CLFunction* boxRTFunction(void* f, ConcreteCompilerType* rtn_type, int nargs, bool takes_varargs = false,
bool takes_kwargs = false);
void addRTFunction(CLFunction* cf, void* f, ConcreteCompilerType* rtn_type, int nargs, bool takes_varargs = false,
bool takes_kwargs = false);
CLFunction* createRTFunction(int num_args, int num_defaults, bool takes_varargs, bool takes_kwargs);
CLFunction* boxRTFunction(void* f, ConcreteCompilerType* rtn_type, int nargs, int num_defaults, bool takes_varargs,
bool takes_kwargs);
CLFunction* boxRTFunction(void* f, ConcreteCompilerType* rtn_type, int nargs);
void addRTFunction(CLFunction* cf, void* f, ConcreteCompilerType* rtn_type);
void addRTFunction(CLFunction* cf, void* f, ConcreteCompilerType* rtn_type,
const std::vector<ConcreteCompilerType*>& arg_types, bool takes_varargs = false,
bool takes_kwargs = false);
const std::vector<ConcreteCompilerType*>& arg_types);
CLFunction* unboxRTFunction(Box*);
// Compiles a new version of the function with the given signature and adds it to the list;
// should only be called after checking to see if the other versions would work.
CompiledFunction* compileFunction(CLFunction* f, FunctionSignature* sig, EffortLevel::EffortLevel effort,
CompiledFunction* compileFunction(CLFunction* f, FunctionSpecialization* spec, EffortLevel::EffortLevel effort,
const OSREntryDescriptor* entry);
EffortLevel::EffortLevel initialEffort();
......@@ -280,6 +277,7 @@ typedef int64_t i64;
extern "C" void* rt_alloc(size_t);
extern "C" void rt_free(void*);
extern "C" void* rt_realloc(void* ptr, size_t new_size);
extern "C" const std::string* getNameOfClass(BoxedClass* cls);
......
......@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "codegen/compvars.h"
#include "core/common.h"
#include "core/types.h"
#include "gc/collector.h"
......@@ -45,12 +46,7 @@ extern "C" Box* boolRepr(BoxedBool* v) {
return boxStrConstant("False");
}
extern "C" Box* boolNew1(Box* cls) {
assert(cls == bool_cls);
return False;
}
extern "C" Box* boolNew2(Box* cls, Box* val) {
extern "C" Box* boolNew(Box* cls, Box* val) {
assert(cls == bool_cls);
bool b = nonzero(val);
......@@ -60,16 +56,15 @@ extern "C" Box* boolNew2(Box* cls, Box* val) {
void setupBool() {
bool_cls->giveAttr("__name__", boxStrConstant("bool"));
bool_cls->giveAttr("__invert__", new BoxedFunction(boxRTFunction((void*)boolInvert, NULL, 1, false)));
bool_cls->giveAttr("__pos__", new BoxedFunction(boxRTFunction((void*)boolPos, NULL, 1, false)));
bool_cls->giveAttr("__neg__", new BoxedFunction(boxRTFunction((void*)boolNeg, NULL, 1, false)));
bool_cls->giveAttr("__nonzero__", new BoxedFunction(boxRTFunction((void*)boolNonzero, NULL, 1, false)));
bool_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)boolRepr, NULL, 1, false)));
bool_cls->giveAttr("__invert__", new BoxedFunction(boxRTFunction((void*)boolInvert, BOXED_INT, 1)));
bool_cls->giveAttr("__pos__", new BoxedFunction(boxRTFunction((void*)boolPos, BOXED_INT, 1)));
bool_cls->giveAttr("__neg__", new BoxedFunction(boxRTFunction((void*)boolNeg, BOXED_INT, 1)));
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("__str__", bool_cls->getattr("__repr__"));
CLFunction* __new__ = boxRTFunction((void*)boolNew1, NULL, 1, false);
addRTFunction(__new__, (void*)boolNew2, NULL, 2, false);
bool_cls->giveAttr("__new__", new BoxedFunction(__new__));
bool_cls->giveAttr("__new__",
new BoxedFunction(boxRTFunction((void*)boolNew, UNKNOWN, 2, 1, false, false), { None }));
bool_cls->freeze();
......
This diff is collapsed.
......@@ -89,12 +89,12 @@ static void _addFunc(const char* name, void* int_func, void* float_func, void* b
assert(BOXED_INT);
v_i.push_back(BOXED_INT);
v_f.push_back(BOXED_FLOAT);
v_u.push_back(NULL);
v_u.push_back(UNKNOWN);
CLFunction* cl = createRTFunction();
addRTFunction(cl, int_func, BOXED_FLOAT, v_i, false);
addRTFunction(cl, float_func, BOXED_FLOAT, v_f, false);
addRTFunction(cl, boxed_func, NULL, v_u, false);
CLFunction* cl = createRTFunction(1, 0, false, false);
addRTFunction(cl, int_func, BOXED_FLOAT, v_i);
addRTFunction(cl, float_func, BOXED_FLOAT, v_f);
addRTFunction(cl, boxed_func, UNKNOWN, v_u);
math_module->giveAttr(name, new BoxedFunction(cl));
}
......@@ -103,6 +103,6 @@ void setupMath() {
math_module->giveAttr("pi", boxFloat(M_PI));
_addFunc("sqrt", (void*)mathSqrtInt, (void*)mathSqrtFloat, (void*)mathSqrt);
_addFunc("tan", (void*)mathTanInt, (void*)mathTanFloat, (void*)mathSqrt);
_addFunc("tan", (void*)mathTanInt, (void*)mathTanFloat, (void*)mathTan);
}
}
......@@ -15,6 +15,7 @@
#include <ctime>
#include <sys/time.h>
#include "codegen/compvars.h"
#include "core/types.h"
#include "runtime/gc_runtime.h"
#include "runtime/types.h"
......@@ -33,6 +34,6 @@ Box* timeTime() {
void setupTime() {
time_module = createModule("time", "__builtin__");
time_module->giveAttr("time", new BoxedFunction(boxRTFunction((void*)timeTime, NULL, 0, false)));
time_module->giveAttr("time", new BoxedFunction(boxRTFunction((void*)timeTime, BOXED_FLOAT, 0)));
}
}
......@@ -18,6 +18,7 @@
#include "Python.h"
#include "codegen/compvars.h"
#include "core/types.h"
#include "runtime/types.h"
......@@ -41,9 +42,9 @@ public:
return boxStrConstant(self->name);
}
static Box* __call__(BoxedCApiFunction* self, BoxedList* varargs) {
static Box* __call__(BoxedCApiFunction* self, BoxedTuple* varargs) {
assert(self->cls == capifunc_cls);
assert(varargs->cls == list_cls);
assert(varargs->cls == tuple_cls);
Box* rtn = (Box*)self->func(test_module, varargs);
assert(rtn);
......@@ -78,14 +79,14 @@ extern "C" bool PyArg_ParseTuple(void* tuple, const char* fmt, ...) {
assert(strcmp("O", fmt) == 0);
BoxedList* varargs = (BoxedList*)tuple;
assert(varargs->size == 1);
BoxedTuple* varargs = (BoxedTuple*)tuple;
assert(varargs->elts.size() == 1);
va_list ap;
va_start(ap, fmt);
Box** arg0 = va_arg(ap, Box**);
*arg0 = varargs->elts->elts[0];
*arg0 = varargs->elts[0];
va_end(ap);
......@@ -124,11 +125,11 @@ void setupCAPI() {
capifunc_cls->giveAttr("__name__", boxStrConstant("capifunc"));
capifunc_cls->giveAttr("__repr__",
new BoxedFunction(boxRTFunction((void*)BoxedCApiFunction::__repr__, NULL, 1, false)));
new BoxedFunction(boxRTFunction((void*)BoxedCApiFunction::__repr__, UNKNOWN, 1)));
capifunc_cls->giveAttr("__str__", capifunc_cls->getattr("__repr__"));
capifunc_cls->giveAttr("__call__",
new BoxedFunction(boxRTFunction((void*)BoxedCApiFunction::__call__, NULL, 1, true)));
capifunc_cls->giveAttr(
"__call__", new BoxedFunction(boxRTFunction((void*)BoxedCApiFunction::__call__, UNKNOWN, 1, 0, true, false)));
capifunc_cls->freeze();
}
......
......@@ -104,11 +104,14 @@ Box* dictSetitem(BoxedDict* self, Box* k, Box* v) {
return None;
}
Box* dictPop2(BoxedDict* self, Box* k) {
Box* dictPop(BoxedDict* self, Box* k, Box* d) {
assert(self->cls == dict_cls);
auto it = self->d.find(k);
if (it == self->d.end()) {
if (d)
return d;
BoxedString* s = reprOrNull(k);
if (s)
......@@ -122,19 +125,7 @@ Box* dictPop2(BoxedDict* self, Box* k) {
return rtn;
}
Box* dictPop3(BoxedDict* self, Box* k, Box* d) {
assert(self->cls == dict_cls);
auto it = self->d.find(k);
if (it == self->d.end())
return d;
Box* rtn = it->second;
self->d.erase(it);
return rtn;
}
Box* dictGet3(BoxedDict* self, Box* k, Box* d) {
Box* dictGet(BoxedDict* self, Box* k, Box* d) {
assert(self->cls == dict_cls);
auto it = self->d.find(k);
......@@ -144,11 +135,7 @@ Box* dictGet3(BoxedDict* self, Box* k, Box* d) {
return it->second;
}
Box* dictGet2(BoxedDict* self, Box* k) {
return dictGet3(self, k, None);
}
Box* dictSetdefault3(BoxedDict* self, Box* k, Box* v) {
Box* dictSetdefault(BoxedDict* self, Box* k, Box* v) {
assert(self->cls == dict_cls);
auto it = self->d.find(k);
......@@ -159,10 +146,6 @@ Box* dictSetdefault3(BoxedDict* self, Box* k, Box* v) {
return v;
}
Box* dictSetdefault2(BoxedDict* self, Box* k) {
return dictSetdefault3(self, k, None);
}
BoxedClass* dict_iterator_cls = NULL;
extern "C" void dictIteratorGCHandler(GCVisitor* v, void* p) {
boxGCHandler(v, p);
......@@ -176,53 +159,48 @@ void setupDict() {
dict_iterator_cls = new BoxedClass(object_cls, 0, sizeof(BoxedDict), false);
dict_cls->giveAttr("__name__", boxStrConstant("dict"));
// dict_cls->giveAttr("__len__", new BoxedFunction(boxRTFunction((void*)dictLen, NULL, 1, false)));
// dict_cls->giveAttr("__getitem__", new BoxedFunction(boxRTFunction((void*)dictGetitem, NULL, 2, false)));
// dict_cls->giveAttr("__new__", new BoxedFunction(boxRTFunction((void*)dictNew, NULL, 1, false)));
// dict_cls->giveAttr("__init__", new BoxedFunction(boxRTFunction((void*)dictInit, NULL, 1, false)));
dict_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)dictRepr, NULL, 1, false)));
// dict_cls->giveAttr("__len__", new BoxedFunction(boxRTFunction((void*)dictLen, NULL, 1)));
// dict_cls->giveAttr("__getitem__", new BoxedFunction(boxRTFunction((void*)dictGetitem, NULL, 2)));
// dict_cls->giveAttr("__new__", new BoxedFunction(boxRTFunction((void*)dictNew, NULL, 1)));
// dict_cls->giveAttr("__init__", new BoxedFunction(boxRTFunction((void*)dictInit, NULL, 1)));
dict_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)dictRepr, STR, 1)));
dict_cls->giveAttr("__str__", dict_cls->getattr("__repr__"));
dict_cls->giveAttr(
"__iter__", new BoxedFunction(boxRTFunction((void*)dictIterKeys, typeFromClass(dict_iterator_cls), 1, false)));
dict_cls->giveAttr("__iter__",
new BoxedFunction(boxRTFunction((void*)dictIterKeys, typeFromClass(dict_iterator_cls), 1)));
dict_cls->giveAttr("items", new BoxedFunction(boxRTFunction((void*)dictItems, NULL, 1, false)));
dict_cls->giveAttr("iteritems", new BoxedFunction(boxRTFunction((void*)dictIterItems,
typeFromClass(dict_iterator_cls), 1, false)));
dict_cls->giveAttr("items", new BoxedFunction(boxRTFunction((void*)dictItems, LIST, 1)));
dict_cls->giveAttr("iteritems",
new BoxedFunction(boxRTFunction((void*)dictIterItems, typeFromClass(dict_iterator_cls), 1)));
dict_cls->giveAttr("values", new BoxedFunction(boxRTFunction((void*)dictValues, NULL, 1, false)));
dict_cls->giveAttr("itervalues", new BoxedFunction(boxRTFunction((void*)dictIterValues,
typeFromClass(dict_iterator_cls), 1, false)));
dict_cls->giveAttr("values", new BoxedFunction(boxRTFunction((void*)dictValues, LIST, 1)));
dict_cls->giveAttr("itervalues",
new BoxedFunction(boxRTFunction((void*)dictIterValues, typeFromClass(dict_iterator_cls), 1)));
dict_cls->giveAttr("keys", new BoxedFunction(boxRTFunction((void*)dictKeys, NULL, 1, false)));
dict_cls->giveAttr("keys", new BoxedFunction(boxRTFunction((void*)dictKeys, LIST, 1)));
dict_cls->giveAttr("iterkeys", dict_cls->getattr("__iter__"));
CLFunction* pop = boxRTFunction((void*)dictPop2, UNKNOWN, 2, false);
addRTFunction(pop, (void*)dictPop3, UNKNOWN, 3, false);
dict_cls->giveAttr("pop", new BoxedFunction(pop));
dict_cls->giveAttr("pop", new BoxedFunction(boxRTFunction((void*)dictPop, UNKNOWN, 3, 1, false, false), { NULL }));
CLFunction* get = boxRTFunction((void*)dictGet2, UNKNOWN, 2, false);
addRTFunction(get, (void*)dictGet3, UNKNOWN, 3, false);
dict_cls->giveAttr("get", new BoxedFunction(get));
dict_cls->giveAttr("get", new BoxedFunction(boxRTFunction((void*)dictGet, UNKNOWN, 3, 1, false, false), { None }));
CLFunction* setdefault = boxRTFunction((void*)dictSetdefault2, UNKNOWN, 2, false);
addRTFunction(setdefault, (void*)dictSetdefault3, UNKNOWN, 3, false);
dict_cls->giveAttr("setdefault", new BoxedFunction(setdefault));
dict_cls->giveAttr("setdefault",
new BoxedFunction(boxRTFunction((void*)dictSetdefault, UNKNOWN, 3, 1, false, false), { None }));
dict_cls->giveAttr("__getitem__", new BoxedFunction(boxRTFunction((void*)dictGetitem, NULL, 2, false)));
dict_cls->giveAttr("__setitem__", new BoxedFunction(boxRTFunction((void*)dictSetitem, NULL, 3, false)));
dict_cls->giveAttr("__getitem__", new BoxedFunction(boxRTFunction((void*)dictGetitem, UNKNOWN, 2)));
dict_cls->giveAttr("__setitem__", new BoxedFunction(boxRTFunction((void*)dictSetitem, NONE, 3)));
dict_cls->freeze();
gc::registerStaticRootObj(dict_iterator_cls);
dict_iterator_cls->giveAttr("__name__", boxStrConstant("dictiterator"));
CLFunction* hasnext = boxRTFunction((void*)dictIterHasnextUnboxed, BOOL, 1, false);
addRTFunction(hasnext, (void*)dictIterHasnext, BOXED_BOOL, 1, false);
CLFunction* hasnext = boxRTFunction((void*)dictIterHasnextUnboxed, BOOL, 1);
addRTFunction(hasnext, (void*)dictIterHasnext, BOXED_BOOL);
dict_iterator_cls->giveAttr("__hasnext__", new BoxedFunction(hasnext));
dict_iterator_cls->giveAttr(
"__iter__", new BoxedFunction(boxRTFunction((void*)dictIterIter, typeFromClass(dict_iterator_cls), 1, false)));
dict_iterator_cls->giveAttr("next", new BoxedFunction(boxRTFunction((void*)dictIterNext, UNKNOWN, 1, false)));
"__iter__", new BoxedFunction(boxRTFunction((void*)dictIterIter, typeFromClass(dict_iterator_cls), 1)));
dict_iterator_cls->giveAttr("next", new BoxedFunction(boxRTFunction((void*)dictIterNext, UNKNOWN, 1)));
dict_iterator_cls->freeze();
}
......
......@@ -31,7 +31,14 @@ Box* fileRepr(BoxedFile* self) {
RELEASE_ASSERT(0, "");
}
static Box* _fileRead(BoxedFile* self, i64 size) {
Box* fileRead(BoxedFile* self, Box* _size) {
assert(self->cls == file_cls);
if (_size->cls != int_cls) {
fprintf(stderr, "TypeError: an integer is required\n");
raiseExcHelper(TypeError, "");
}
int64_t size = static_cast<BoxedInt*>(_size)->n;
if (self->closed) {
fprintf(stderr, "IOError: file not open for reading\n");
raiseExcHelper(IOError, "");
......@@ -59,11 +66,6 @@ static Box* _fileRead(BoxedFile* self, i64 size) {
return boxString(os.str());
}
Box* fileRead1(BoxedFile* self) {
assert(self->cls == file_cls);
return _fileRead(self, -1);
}
Box* fileReadline1(BoxedFile* self) {
assert(self->cls == file_cls);
......@@ -82,15 +84,6 @@ Box* fileReadline1(BoxedFile* self) {
return boxString(os.str());
}
Box* fileRead2(BoxedFile* self, Box* size) {
assert(self->cls == file_cls);
if (size->cls != int_cls) {
fprintf(stderr, "TypeError: an integer is required\n");
raiseExcHelper(TypeError, "");
}
return _fileRead(self, static_cast<BoxedInt*>(size)->n);
}
Box* fileWrite(BoxedFile* self, Box* val) {
assert(self->cls == file_cls);
......@@ -158,38 +151,31 @@ Box* fileExit(BoxedFile* self, Box* exc_type, Box* exc_val, Box** args) {
return fileClose(self);
}
Box* fileNew2(BoxedClass* cls, Box* s) {
assert(cls == file_cls);
return open1(s);
}
Box* fileNew3(BoxedClass* cls, Box* s, Box* m) {
Box* fileNew(BoxedClass* cls, Box* s, Box* m) {
assert(cls == file_cls);
return open2(s, m);
return open(s, m);
}
void setupFile() {
file_cls->giveAttr("__name__", boxStrConstant("file"));
CLFunction* read = boxRTFunction((void*)fileRead1, NULL, 1, false);
addRTFunction(read, (void*)fileRead2, NULL, 2, false);
file_cls->giveAttr("read", new BoxedFunction(read));
file_cls->giveAttr("read",
new BoxedFunction(boxRTFunction((void*)fileRead, STR, 2, 1, false, false), { boxInt(-1) }));
CLFunction* readline = boxRTFunction((void*)fileReadline1, STR, 1, false);
CLFunction* readline = boxRTFunction((void*)fileReadline1, STR, 1);
file_cls->giveAttr("readline", new BoxedFunction(readline));
file_cls->giveAttr("write", new BoxedFunction(boxRTFunction((void*)fileWrite, NULL, 2, false)));
file_cls->giveAttr("close", new BoxedFunction(boxRTFunction((void*)fileClose, NULL, 1, false)));
file_cls->giveAttr("write", new BoxedFunction(boxRTFunction((void*)fileWrite, NONE, 2)));
file_cls->giveAttr("close", new BoxedFunction(boxRTFunction((void*)fileClose, NONE, 1)));
file_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)fileRepr, NULL, 1, false)));
file_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)fileRepr, STR, 1)));
file_cls->giveAttr("__str__", file_cls->getattr("__repr__"));
file_cls->giveAttr("__enter__", new BoxedFunction(boxRTFunction((void*)fileEnter, NULL, 1, false)));
file_cls->giveAttr("__exit__", new BoxedFunction(boxRTFunction((void*)fileExit, NULL, 4, false)));
file_cls->giveAttr("__enter__", new BoxedFunction(boxRTFunction((void*)fileEnter, typeFromClass(file_cls), 1)));
file_cls->giveAttr("__exit__", new BoxedFunction(boxRTFunction((void*)fileExit, UNKNOWN, 4)));
CLFunction* __new__ = boxRTFunction((void*)fileNew2, NULL, 2, false);
addRTFunction(__new__, (void*)fileNew3, NULL, 3, false);
file_cls->giveAttr("__new__", new BoxedFunction(__new__));
file_cls->giveAttr("__new__", new BoxedFunction(boxRTFunction((void*)fileNew, UNKNOWN, 3, 1, false, false),
{ boxStrConstant("r") }));
file_cls->freeze();
}
......
......@@ -502,13 +502,7 @@ std::string floatFmt(double x, int precision, char code) {
return std::string(buf, n);
}
Box* floatNew1(BoxedClass* cls) {
assert(cls == float_cls);
// TODO intern this?
return boxFloat(0.0);
}
Box* floatNew2(BoxedClass* cls, Box* a) {
Box* floatNew(BoxedClass* cls, Box* a) {
assert(cls == float_cls);
if (a->cls == float_cls) {
......@@ -552,12 +546,12 @@ static void _addFunc(const char* name, ConcreteCompilerType* rtn_type, void* flo
v_fi.push_back(BOXED_FLOAT);
v_fi.push_back(BOXED_INT);
v_fu.push_back(BOXED_FLOAT);
v_fu.push_back(NULL);
v_fu.push_back(UNKNOWN);
CLFunction* cl = createRTFunction();
addRTFunction(cl, float_func, rtn_type, v_ff, false);
addRTFunction(cl, int_func, rtn_type, v_fi, false);
addRTFunction(cl, boxed_func, NULL, v_fu, false);
CLFunction* cl = createRTFunction(2, 0, false, false);
addRTFunction(cl, float_func, rtn_type, v_ff);
addRTFunction(cl, int_func, rtn_type, v_fi);
addRTFunction(cl, boxed_func, UNKNOWN, v_fu);
float_cls->giveAttr(name, new BoxedFunction(cl));
}
......@@ -569,7 +563,7 @@ void setupFloat() {
_addFunc("__div__", BOXED_FLOAT, (void*)floatDivFloat, (void*)floatDivInt, (void*)floatDiv);
_addFunc("__rdiv__", BOXED_FLOAT, (void*)floatRDivFloat, (void*)floatRDivInt, (void*)floatRDiv);
float_cls->giveAttr("__floordiv__", new BoxedFunction(boxRTFunction((void*)floatFloorDiv, NULL, 2, false)));
float_cls->giveAttr("__floordiv__", new BoxedFunction(boxRTFunction((void*)floatFloorDiv, UNKNOWN, 2)));
_addFunc("__eq__", BOXED_BOOL, (void*)floatEqFloat, (void*)floatEqInt, (void*)floatEq);
_addFunc("__ge__", BOXED_BOOL, (void*)floatGeFloat, (void*)floatGeInt, (void*)floatGe);
......@@ -587,17 +581,18 @@ void setupFloat() {
_addFunc("__sub__", BOXED_FLOAT, (void*)floatSubFloat, (void*)floatSubInt, (void*)floatSub);
_addFunc("__rsub__", BOXED_FLOAT, (void*)floatRSubFloat, (void*)floatRSubInt, (void*)floatRSub);
CLFunction* __new__ = boxRTFunction((void*)floatNew1, NULL, 1, false);
addRTFunction(__new__, (void*)floatNew2, NULL, 2, false);
float_cls->giveAttr("__new__", new BoxedFunction(__new__));
float_cls->giveAttr(
"__new__", new BoxedFunction(boxRTFunction((void*)floatNew, UNKNOWN, 2, 1, false, false), { boxFloat(0.0) }));
float_cls->giveAttr("__neg__", new BoxedFunction(boxRTFunction((void*)floatNeg, NULL, 1, false)));
CLFunction* nonzero = boxRTFunction((void*)floatNonzeroUnboxed, BOOL, 1, false);
addRTFunction(nonzero, (void*)floatNonzero, UNKNOWN, 1, false);
float_cls->giveAttr("__neg__", new BoxedFunction(boxRTFunction((void*)floatNeg, BOXED_FLOAT, 1)));
CLFunction* nonzero = boxRTFunction((void*)floatNonzeroUnboxed, BOOL, 1);
addRTFunction(nonzero, (void*)floatNonzero, UNKNOWN);
float_cls->giveAttr("__nonzero__", new BoxedFunction(nonzero));
// float_cls->giveAttr("__nonzero__", new BoxedFunction(boxRTFunction((void*)floatNonzero, NULL, 1, false)));
float_cls->giveAttr("__str__", new BoxedFunction(boxRTFunction((void*)floatStr, NULL, 1, false)));
float_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)floatRepr, NULL, 1, false)));
// float_cls->giveAttr("__nonzero__", new BoxedFunction(boxRTFunction((void*)floatNonzero, NULL, 1)));
float_cls->giveAttr("__str__", new BoxedFunction(boxRTFunction((void*)floatStr, STR, 1)));
float_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)floatRepr, STR, 1)));
float_cls->freeze();
}
......
......@@ -69,8 +69,7 @@ void BoxedList::shrink() {
if (capacity > size * 3) {
int new_capacity = std::max(static_cast<int64_t>(INITIAL_CAPACITY), capacity / 2);
if (size > 0) {
elts = (BoxedList::ElementArray*)rt_realloc(elts,
new_capacity * sizeof(Box*) + sizeof(BoxedList::ElementArray));
elts = GCdArray::realloc(elts, new_capacity);
capacity = new_capacity;
} else if (size == 0) {
rt_free(elts);
......@@ -85,12 +84,11 @@ void BoxedList::ensure(int space) {
if (capacity == 0) {
const int INITIAL_CAPACITY = 8;
int initial = std::max(INITIAL_CAPACITY, space);
elts = new (initial) BoxedList::ElementArray();
elts = new (initial) GCdArray();
capacity = initial;
} else {
int new_capacity = std::max(capacity * 2, size + space);
elts = (BoxedList::ElementArray*)rt_realloc(elts,
new_capacity * sizeof(Box*) + sizeof(BoxedList::ElementArray));
elts = GCdArray::realloc(elts, new_capacity);
capacity = new_capacity;
}
}
......
......@@ -79,37 +79,34 @@ public:
};
extern "C" const ObjectFlavor xrange_iterator_flavor(&BoxedXrangeIterator::xrangeIteratorGCHandler, NULL);
Box* xrange1(Box* cls, Box* stop) {
Box* xrange(Box* cls, Box* start, Box* stop, Box** args) {
assert(cls == xrange_cls);
RELEASE_ASSERT(stop->cls == int_cls, "%s", getTypeName(stop)->c_str());
i64 istop = static_cast<BoxedInt*>(stop)->n;
return new BoxedXrange(0, istop, 1);
}
Box* xrange2(Box* cls, Box* start, Box* stop) {
assert(cls == xrange_cls);
RELEASE_ASSERT(start->cls == int_cls, "%s", getTypeName(start)->c_str());
RELEASE_ASSERT(stop->cls == int_cls, "%s", getTypeName(stop)->c_str());
i64 istart = static_cast<BoxedInt*>(start)->n;
i64 istop = static_cast<BoxedInt*>(stop)->n;
return new BoxedXrange(istart, istop, 1);
}
Box* xrange3(Box* cls, Box* start, Box* stop, Box** args) {
Box* step = args[0];
assert(cls == xrange_cls);
RELEASE_ASSERT(start->cls == int_cls, "%s", getTypeName(start)->c_str());
RELEASE_ASSERT(stop->cls == int_cls, "%s", getTypeName(stop)->c_str());
RELEASE_ASSERT(step->cls == int_cls, "%s", getTypeName(step)->c_str());
i64 istart = static_cast<BoxedInt*>(start)->n;
i64 istop = static_cast<BoxedInt*>(stop)->n;
i64 istep = static_cast<BoxedInt*>(step)->n;
RELEASE_ASSERT(istep != 0, "step can't be 0");
return new BoxedXrange(istart, istop, istep);
if (stop == NULL) {
RELEASE_ASSERT(start->cls == int_cls, "%s", getTypeName(start)->c_str());
i64 istop = static_cast<BoxedInt*>(start)->n;
return new BoxedXrange(0, istop, 1);
} else if (step == NULL) {
RELEASE_ASSERT(start->cls == int_cls, "%s", getTypeName(start)->c_str());
RELEASE_ASSERT(stop->cls == int_cls, "%s", getTypeName(stop)->c_str());
i64 istart = static_cast<BoxedInt*>(start)->n;
i64 istop = static_cast<BoxedInt*>(stop)->n;
return new BoxedXrange(istart, istop, 1);
} else {
RELEASE_ASSERT(start->cls == int_cls, "%s", getTypeName(start)->c_str());
RELEASE_ASSERT(stop->cls == int_cls, "%s", getTypeName(stop)->c_str());
RELEASE_ASSERT(step->cls == int_cls, "%s", getTypeName(step)->c_str());
i64 istart = static_cast<BoxedInt*>(start)->n;
i64 istop = static_cast<BoxedInt*>(stop)->n;
i64 istep = static_cast<BoxedInt*>(step)->n;
RELEASE_ASSERT(istep != 0, "step can't be 0");
return new BoxedXrange(istart, istop, istep);
}
}
Box* xrangeIter(Box* self) {
......@@ -125,19 +122,18 @@ void setupXrange() {
xrange_iterator_cls = new BoxedClass(object_cls, 0, sizeof(BoxedXrangeIterator), false);
xrange_iterator_cls->giveAttr("__name__", boxStrConstant("rangeiterator"));
CLFunction* xrange_clf = boxRTFunction((void*)xrange1, NULL, 2, false);
addRTFunction(xrange_clf, (void*)xrange2, NULL, 3, false);
addRTFunction(xrange_clf, (void*)xrange3, NULL, 4, false);
xrange_cls->giveAttr("__new__", new BoxedFunction(xrange_clf));
xrange_cls->giveAttr(
"__iter__", new BoxedFunction(boxRTFunction((void*)xrangeIter, typeFromClass(xrange_iterator_cls), 1, false)));
"__new__",
new BoxedFunction(boxRTFunction((void*)xrange, typeFromClass(xrange_cls), 4, 2, false, false), { NULL, NULL }));
xrange_cls->giveAttr("__iter__",
new BoxedFunction(boxRTFunction((void*)xrangeIter, typeFromClass(xrange_iterator_cls), 1)));
CLFunction* hasnext = boxRTFunction((void*)BoxedXrangeIterator::xrangeIteratorHasnextUnboxed, BOOL, 1, false);
addRTFunction(hasnext, (void*)BoxedXrangeIterator::xrangeIteratorHasnext, BOXED_BOOL, 1, false);
CLFunction* hasnext = boxRTFunction((void*)BoxedXrangeIterator::xrangeIteratorHasnextUnboxed, BOOL, 1);
addRTFunction(hasnext, (void*)BoxedXrangeIterator::xrangeIteratorHasnext, BOXED_BOOL);
xrange_iterator_cls->giveAttr("__hasnext__", new BoxedFunction(hasnext));
CLFunction* next = boxRTFunction((void*)BoxedXrangeIterator::xrangeIteratorNextUnboxed, INT, 1, false);
addRTFunction(next, (void*)BoxedXrangeIterator::xrangeIteratorNext, BOXED_INT, 1, false);
CLFunction* next = boxRTFunction((void*)BoxedXrangeIterator::xrangeIteratorNextUnboxed, INT, 1);
addRTFunction(next, (void*)BoxedXrangeIterator::xrangeIteratorNext, BOXED_INT);
xrange_iterator_cls->giveAttr("next", new BoxedFunction(next));
// TODO this is pretty hacky, but stuff the iterator cls into xrange to make sure it gets decref'd at the end
......
......@@ -447,14 +447,7 @@ extern "C" Box* intHash(BoxedInt* self) {
return self;
}
extern "C" Box* intNew1(Box* _cls) {
if (!isSubclass(_cls->cls, type_cls))
raiseExcHelper(TypeError, "int.__new__(X): X is not a type object (%s)", getTypeName(_cls)->c_str());
return boxInt(0);
}
extern "C" Box* intNew2(Box* _cls, Box* val) {
extern "C" Box* intNew(Box* _cls, Box* val) {
if (!isSubclass(_cls->cls, type_cls))
raiseExcHelper(TypeError, "int.__new__(X): X is not a type object (%s)", getTypeName(_cls)->c_str());
......@@ -489,12 +482,7 @@ extern "C" Box* intNew2(Box* _cls, Box* val) {
return rtn;
}
extern "C" Box* intInit1(Box* self) {
// int.__init__ will actually let you call it with anything
return None;
}
extern "C" Box* intInit2(BoxedInt* self, Box* val) {
extern "C" Box* intInit(BoxedInt* self, Box* val, Box* args) {
// int.__init__ will actually let you call it with anything
return None;
}
......@@ -510,10 +498,10 @@ static void _addFuncIntFloatUnknown(const char* name, void* int_func, void* floa
v_iu.push_back(UNKNOWN);
v_iu.push_back(UNKNOWN);
CLFunction* cl = createRTFunction();
addRTFunction(cl, int_func, BOXED_INT, v_ii, false);
addRTFunction(cl, float_func, BOXED_FLOAT, v_if, false);
addRTFunction(cl, boxed_func, NULL, v_iu, false);
CLFunction* cl = createRTFunction(2, 0, false, false);
addRTFunction(cl, int_func, BOXED_INT, v_ii);
addRTFunction(cl, float_func, BOXED_FLOAT, v_if);
addRTFunction(cl, boxed_func, UNKNOWN, v_iu);
int_cls->giveAttr(name, new BoxedFunction(cl));
}
......@@ -523,15 +511,20 @@ static void _addFuncIntUnknown(const char* name, ConcreteCompilerType* rtn_type,
v_ii.push_back(BOXED_INT);
v_ii.push_back(BOXED_INT);
v_iu.push_back(BOXED_INT);
v_iu.push_back(NULL);
v_iu.push_back(UNKNOWN);
CLFunction* cl = createRTFunction();
addRTFunction(cl, int_func, rtn_type, v_ii, false);
addRTFunction(cl, boxed_func, NULL, v_iu, false);
CLFunction* cl = createRTFunction(2, 0, false, false);
addRTFunction(cl, int_func, rtn_type, v_ii);
addRTFunction(cl, boxed_func, UNKNOWN, v_iu);
int_cls->giveAttr(name, new BoxedFunction(cl));
}
void setupInt() {
for (int i = 0; i < NUM_INTERNED_INTS; i++) {
interned_ints[i] = new BoxedInt(int_cls, i);
gc::registerStaticRootObj(interned_ints[i]);
}
int_cls->giveAttr("__name__", boxStrConstant("int"));
_addFuncIntFloatUnknown("__add__", (void*)intAddInt, (void*)intAddFloat, (void*)intAdd);
......@@ -552,29 +545,22 @@ void setupInt() {
_addFuncIntUnknown("__lshift__", BOXED_INT, (void*)intLShiftInt, (void*)intLShift);
_addFuncIntUnknown("__rshift__", BOXED_INT, (void*)intRShiftInt, (void*)intRShift);
int_cls->giveAttr("__invert__", new BoxedFunction(boxRTFunction((void*)intInvert, BOXED_INT, 1, false)));
int_cls->giveAttr("__pos__", new BoxedFunction(boxRTFunction((void*)intPos, BOXED_INT, 1, false)));
int_cls->giveAttr("__neg__", new BoxedFunction(boxRTFunction((void*)intNeg, BOXED_INT, 1, false)));
int_cls->giveAttr("__nonzero__", new BoxedFunction(boxRTFunction((void*)intNonzero, BOXED_BOOL, 1, false)));
int_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)intRepr, STR, 1, false)));
int_cls->giveAttr("__invert__", new BoxedFunction(boxRTFunction((void*)intInvert, BOXED_INT, 1)));
int_cls->giveAttr("__pos__", new BoxedFunction(boxRTFunction((void*)intPos, BOXED_INT, 1)));
int_cls->giveAttr("__neg__", new BoxedFunction(boxRTFunction((void*)intNeg, BOXED_INT, 1)));
int_cls->giveAttr("__nonzero__", new BoxedFunction(boxRTFunction((void*)intNonzero, BOXED_BOOL, 1)));
int_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)intRepr, STR, 1)));
int_cls->giveAttr("__str__", int_cls->getattr("__repr__"));
int_cls->giveAttr("__hash__", new BoxedFunction(boxRTFunction((void*)intHash, BOXED_INT, 1, false)));
int_cls->giveAttr("__divmod__", new BoxedFunction(boxRTFunction((void*)intDivmod, BOXED_TUPLE, 2, false)));
int_cls->giveAttr("__hash__", new BoxedFunction(boxRTFunction((void*)intHash, BOXED_INT, 1)));
int_cls->giveAttr("__divmod__", new BoxedFunction(boxRTFunction((void*)intDivmod, BOXED_TUPLE, 2)));
CLFunction* __new__ = boxRTFunction((void*)intNew1, NULL, 1, false);
addRTFunction(__new__, (void*)intNew2, NULL, 2, false);
int_cls->giveAttr("__new__", new BoxedFunction(__new__));
int_cls->giveAttr("__new__",
new BoxedFunction(boxRTFunction((void*)intNew, BOXED_INT, 2, 1, false, false), { boxInt(0) }));
CLFunction* __init__ = boxRTFunction((void*)intInit1, NULL, 1, false);
addRTFunction(__init__, (void*)intInit2, NULL, 2, false);
int_cls->giveAttr("__init__", new BoxedFunction(__init__));
int_cls->giveAttr("__init__",
new BoxedFunction(boxRTFunction((void*)intInit, NONE, 2, 1, true, false), { boxInt(0) }));
int_cls->freeze();
for (int i = 0; i < NUM_INTERNED_INTS; i++) {
interned_ints[i] = new BoxedInt(int_cls, i);
gc::registerStaticRootObj(interned_ints[i]);
}
}
void teardownInt() {
......
......@@ -50,17 +50,17 @@ extern "C" Box* listNonzero(BoxedList* self) {
return boxBool(self->size != 0);
}
extern "C" Box* listPop1(BoxedList* self) {
if (self->size == 0) {
raiseExcHelper(IndexError, "pop from empty list");
}
extern "C" Box* listPop(BoxedList* self, Box* idx) {
if (idx == None) {
if (self->size == 0) {
raiseExcHelper(IndexError, "pop from empty list");
}
self->size--;
Box* rtn = self->elts->elts[self->size];
return rtn;
}
self->size--;
Box* rtn = self->elts->elts[self->size];
return rtn;
}
extern "C" Box* listPop2(BoxedList* self, Box* idx) {
if (idx->cls != int_cls) {
raiseExcHelper(TypeError, "an integer is required");
}
......@@ -417,13 +417,11 @@ extern "C" void listIteratorGCHandler(GCVisitor* v, void* p) {
extern "C" const ObjectFlavor list_iterator_flavor(&listIteratorGCHandler, NULL);
extern "C" Box* listNew1(Box* cls) {
extern "C" Box* listNew(Box* cls, Box* container) {
assert(cls == list_cls);
return new BoxedList();
}
extern "C" Box* listNew2(Box* cls, Box* container) {
assert(cls == list_cls);
if (container == None)
return new BoxedList();
BoxedList* rtn = new BoxedList();
for (Box* e : container->pyElements()) {
......@@ -485,72 +483,67 @@ void setupList() {
list_cls->giveAttr("__name__", boxStrConstant("list"));
list_cls->giveAttr("__len__", new BoxedFunction(boxRTFunction((void*)listLen, BOXED_INT, 1, false)));
list_cls->giveAttr("__len__", new BoxedFunction(boxRTFunction((void*)listLen, BOXED_INT, 1)));
CLFunction* getitem = createRTFunction();
addRTFunction(getitem, (void*)listGetitemInt, NULL, std::vector<ConcreteCompilerType*>{ LIST, BOXED_INT }, false);
addRTFunction(getitem, (void*)listGetitemSlice, NULL, std::vector<ConcreteCompilerType*>{ LIST, SLICE }, false);
addRTFunction(getitem, (void*)listGetitem, NULL, std::vector<ConcreteCompilerType*>{ LIST, NULL }, false);
CLFunction* getitem = createRTFunction(2, 0, 0, 0);
addRTFunction(getitem, (void*)listGetitemInt, UNKNOWN, std::vector<ConcreteCompilerType*>{ LIST, BOXED_INT });
addRTFunction(getitem, (void*)listGetitemSlice, LIST, std::vector<ConcreteCompilerType*>{ LIST, SLICE });
addRTFunction(getitem, (void*)listGetitem, UNKNOWN, std::vector<ConcreteCompilerType*>{ LIST, UNKNOWN });
list_cls->giveAttr("__getitem__", new BoxedFunction(getitem));
list_cls->giveAttr("__iter__",
new BoxedFunction(boxRTFunction((void*)listIter, typeFromClass(list_iterator_cls), 1, false)));
new BoxedFunction(boxRTFunction((void*)listIter, typeFromClass(list_iterator_cls), 1)));
list_cls->giveAttr("__eq__", new BoxedFunction(boxRTFunction((void*)listEq, NULL, 2, false)));
list_cls->giveAttr("__eq__", new BoxedFunction(boxRTFunction((void*)listEq, UNKNOWN, 2)));
list_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)listRepr, STR, 1, false)));
list_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)listRepr, STR, 1)));
list_cls->giveAttr("__str__", list_cls->getattr("__repr__"));
list_cls->giveAttr("__nonzero__", new BoxedFunction(boxRTFunction((void*)listNonzero, BOXED_BOOL, 1, false)));
list_cls->giveAttr("__nonzero__", new BoxedFunction(boxRTFunction((void*)listNonzero, BOXED_BOOL, 1)));
CLFunction* pop = boxRTFunction((void*)listPop1, NULL, 1, false);
addRTFunction(pop, (void*)listPop2, NULL, 2, false);
list_cls->giveAttr("pop", new BoxedFunction(pop));
list_cls->giveAttr("pop", new BoxedFunction(boxRTFunction((void*)listPop, UNKNOWN, 2, 1, false, false), { None }));
list_cls->giveAttr("append", new BoxedFunction(boxRTFunction((void*)listAppend, NULL, 2, false)));
list_cls->giveAttr("append", new BoxedFunction(boxRTFunction((void*)listAppend, NONE, 2)));
CLFunction* setitem = createRTFunction();
addRTFunction(setitem, (void*)listSetitemInt, NULL, std::vector<ConcreteCompilerType*>{ LIST, BOXED_INT, NULL },
false);
addRTFunction(setitem, (void*)listSetitemSlice, NULL, std::vector<ConcreteCompilerType*>{ LIST, SLICE, NULL },
false);
addRTFunction(setitem, (void*)listSetitem, NULL, std::vector<ConcreteCompilerType*>{ LIST, NULL, NULL }, false);
CLFunction* setitem = createRTFunction(3, 0, false, false);
addRTFunction(setitem, (void*)listSetitemInt, NONE, std::vector<ConcreteCompilerType*>{ LIST, BOXED_INT, UNKNOWN });
addRTFunction(setitem, (void*)listSetitemSlice, NONE, std::vector<ConcreteCompilerType*>{ LIST, SLICE, UNKNOWN });
addRTFunction(setitem, (void*)listSetitem, NONE, std::vector<ConcreteCompilerType*>{ LIST, UNKNOWN, UNKNOWN });
list_cls->giveAttr("__setitem__", new BoxedFunction(setitem));
CLFunction* delitem = createRTFunction();
addRTFunction(delitem, (void*)listDelitemInt, NULL, std::vector<ConcreteCompilerType*>{ LIST, BOXED_INT }, false);
addRTFunction(delitem, (void*)listDelitemSlice, NULL, std::vector<ConcreteCompilerType*>{ LIST, SLICE }, false);
addRTFunction(delitem, (void*)listDelitem, NULL, std::vector<ConcreteCompilerType*>{ LIST, NULL }, false);
CLFunction* delitem = createRTFunction(2, 0, false, false);
addRTFunction(delitem, (void*)listDelitemInt, NONE, std::vector<ConcreteCompilerType*>{ LIST, BOXED_INT });
addRTFunction(delitem, (void*)listDelitemSlice, NONE, std::vector<ConcreteCompilerType*>{ LIST, SLICE });
addRTFunction(delitem, (void*)listDelitem, NONE, std::vector<ConcreteCompilerType*>{ LIST, UNKNOWN });
list_cls->giveAttr("__delitem__", new BoxedFunction(delitem));
list_cls->giveAttr("insert", new BoxedFunction(boxRTFunction((void*)listInsert, NULL, 3, false)));
list_cls->giveAttr("__mul__", new BoxedFunction(boxRTFunction((void*)listMul, NULL, 2, false)));
list_cls->giveAttr("insert", new BoxedFunction(boxRTFunction((void*)listInsert, NONE, 3)));
list_cls->giveAttr("__mul__", new BoxedFunction(boxRTFunction((void*)listMul, NONE, 2)));
list_cls->giveAttr("__iadd__", new BoxedFunction(boxRTFunction((void*)listIAdd, NULL, 2, false)));
list_cls->giveAttr("__add__", new BoxedFunction(boxRTFunction((void*)listAdd, NULL, 2, false)));
list_cls->giveAttr("__iadd__", new BoxedFunction(boxRTFunction((void*)listIAdd, UNKNOWN, 2)));
list_cls->giveAttr("__add__", new BoxedFunction(boxRTFunction((void*)listAdd, UNKNOWN, 2)));
list_cls->giveAttr("sort", new BoxedFunction(boxRTFunction((void*)listSort1, NULL, 1, false)));
list_cls->giveAttr("__contains__", new BoxedFunction(boxRTFunction((void*)listContains, BOXED_BOOL, 2, false)));
list_cls->giveAttr("sort", new BoxedFunction(boxRTFunction((void*)listSort1, NONE, 1)));
list_cls->giveAttr("__contains__", new BoxedFunction(boxRTFunction((void*)listContains, BOXED_BOOL, 2)));
CLFunction* new_ = boxRTFunction((void*)listNew1, NULL, 1, false);
addRTFunction(new_, (void*)listNew2, NULL, 2, false);
list_cls->giveAttr("__new__", new BoxedFunction(new_));
list_cls->giveAttr("__new__",
new BoxedFunction(boxRTFunction((void*)listNew, UNKNOWN, 2, 1, false, false), { None }));
list_cls->giveAttr("count", new BoxedFunction(boxRTFunction((void*)listCount, BOXED_INT, 2, false)));
list_cls->giveAttr("index", new BoxedFunction(boxRTFunction((void*)listIndex, NULL, 2, false)));
list_cls->giveAttr("remove", new BoxedFunction(boxRTFunction((void*)listRemove, NONE, 2, false)));
list_cls->giveAttr("reverse", new BoxedFunction(boxRTFunction((void*)listReverse, NONE, 1, false)));
list_cls->giveAttr("count", new BoxedFunction(boxRTFunction((void*)listCount, BOXED_INT, 2)));
list_cls->giveAttr("index", new BoxedFunction(boxRTFunction((void*)listIndex, BOXED_INT, 2)));
list_cls->giveAttr("remove", new BoxedFunction(boxRTFunction((void*)listRemove, NONE, 2)));
list_cls->giveAttr("reverse", new BoxedFunction(boxRTFunction((void*)listReverse, NONE, 1)));
list_cls->freeze();
gc::registerStaticRootObj(list_iterator_cls);
list_iterator_cls->giveAttr("__name__", boxStrConstant("listiterator"));
CLFunction* hasnext = boxRTFunction((void*)listiterHasnextUnboxed, BOOL, 1, false);
addRTFunction(hasnext, (void*)listiterHasnext, BOXED_BOOL, 1, false);
CLFunction* hasnext = boxRTFunction((void*)listiterHasnextUnboxed, BOOL, 1);
addRTFunction(hasnext, (void*)listiterHasnext, BOXED_BOOL);
list_iterator_cls->giveAttr("__hasnext__", new BoxedFunction(hasnext));
list_iterator_cls->giveAttr(
"__iter__", new BoxedFunction(boxRTFunction((void*)listIterIter, typeFromClass(list_iterator_cls), 1, false)));
list_iterator_cls->giveAttr("next", new BoxedFunction(boxRTFunction((void*)listiterNext, UNKNOWN, 1, false)));
"__iter__", new BoxedFunction(boxRTFunction((void*)listIterIter, typeFromClass(list_iterator_cls), 1)));
list_iterator_cls->giveAttr("next", new BoxedFunction(boxRTFunction((void*)listiterNext, UNKNOWN, 1)));
list_iterator_cls->freeze();
}
......
This diff is collapsed.
......@@ -49,8 +49,7 @@ extern "C" BoxedString* strOrNull(Box* obj); // similar to str, but returns NUL
extern "C" bool isinstance(Box* obj, Box* cls, int64_t flags);
extern "C" BoxedInt* hash(Box* obj);
// extern "C" Box* abs_(Box* obj);
extern "C" Box* open1(Box* arg);
extern "C" Box* open2(Box* arg1, Box* arg2);
Box* open(Box* arg1, Box* arg2);
// extern "C" Box* chr(Box* arg);
extern "C" Box* compare(Box*, Box*, int);
extern "C" BoxedInt* len(Box* obj);
......
......@@ -89,13 +89,11 @@ Box* setAdd2(Box* _self, Box* b) {
return None;
}
Box* setNew1(Box* cls) {
Box* setNew(Box* cls, Box* container) {
assert(cls == set_cls);
return new BoxedSet();
}
Box* setNew2(Box* cls, Box* container) {
assert(cls == set_cls);
if (container == None)
return new BoxedSet();
Box* rtn = new BoxedSet();
for (Box* e : container->pyElements()) {
......@@ -212,16 +210,15 @@ void setupSet() {
set_iterator_cls = new BoxedClass(object_cls, 0, sizeof(BoxedSet), false);
set_iterator_cls->giveAttr("__name__", boxStrConstant("setiterator"));
set_iterator_cls->giveAttr("__hasnext__",
new BoxedFunction(boxRTFunction((void*)setiteratorHasnext, BOXED_BOOL, 1, false)));
set_iterator_cls->giveAttr("next", new BoxedFunction(boxRTFunction((void*)setiteratorNext, UNKNOWN, 1, false)));
new BoxedFunction(boxRTFunction((void*)setiteratorHasnext, BOXED_BOOL, 1)));
set_iterator_cls->giveAttr("next", new BoxedFunction(boxRTFunction((void*)setiteratorNext, UNKNOWN, 1)));
set_iterator_cls->freeze();
gc::registerStaticRootObj(set_iterator_cls);
CLFunction* new_ = boxRTFunction((void*)setNew1, SET, 1, false);
addRTFunction(new_, (void*)setNew2, SET, 2, false);
set_cls->giveAttr("__new__", new BoxedFunction(new_));
set_cls->giveAttr("__new__",
new BoxedFunction(boxRTFunction((void*)setNew, UNKNOWN, 2, 1, false, false), { None }));
Box* repr = new BoxedFunction(boxRTFunction((void*)setRepr, STR, 1, false));
Box* repr = new BoxedFunction(boxRTFunction((void*)setRepr, STR, 1));
set_cls->giveAttr("__repr__", repr);
set_cls->giveAttr("__str__", repr);
......@@ -231,28 +228,27 @@ void setupSet() {
v_su.push_back(SET);
v_su.push_back(UNKNOWN);
CLFunction* or_ = createRTFunction();
addRTFunction(or_, (void*)setOrSet, SET, v_ss, false);
CLFunction* or_ = createRTFunction(2, 0, false, false);
addRTFunction(or_, (void*)setOrSet, SET, v_ss);
set_cls->giveAttr("__or__", new BoxedFunction(or_));
CLFunction* sub_ = createRTFunction();
addRTFunction(sub_, (void*)setSubSet, SET, v_ss, false);
CLFunction* sub_ = createRTFunction(2, 0, false, false);
addRTFunction(sub_, (void*)setSubSet, SET, v_ss);
set_cls->giveAttr("__sub__", new BoxedFunction(sub_));
CLFunction* xor_ = createRTFunction();
addRTFunction(xor_, (void*)setXorSet, SET, v_ss, false);
CLFunction* xor_ = createRTFunction(2, 0, false, false);
addRTFunction(xor_, (void*)setXorSet, SET, v_ss);
set_cls->giveAttr("__xor__", new BoxedFunction(xor_));
CLFunction* and_ = createRTFunction();
addRTFunction(and_, (void*)setAndSet, SET, v_ss, false);
CLFunction* and_ = createRTFunction(2, 0, false, false);
addRTFunction(and_, (void*)setAndSet, SET, v_ss);
set_cls->giveAttr("__and__", new BoxedFunction(and_));
set_cls->giveAttr("__iter__",
new BoxedFunction(boxRTFunction((void*)setIter, typeFromClass(set_iterator_cls), 1, false)));
set_cls->giveAttr("__iter__", new BoxedFunction(boxRTFunction((void*)setIter, typeFromClass(set_iterator_cls), 1)));
set_cls->giveAttr("__len__", new BoxedFunction(boxRTFunction((void*)setLen, BOXED_INT, 1, false)));
set_cls->giveAttr("__len__", new BoxedFunction(boxRTFunction((void*)setLen, BOXED_INT, 1)));
set_cls->giveAttr("add", new BoxedFunction(boxRTFunction((void*)setAdd, NONE, 2, false)));
set_cls->giveAttr("add", new BoxedFunction(boxRTFunction((void*)setAdd, NONE, 2)));
set_cls->freeze();
}
......
......@@ -293,12 +293,7 @@ extern "C" Box* strNonzero(BoxedString* self) {
return boxBool(self->s.size() != 0);
}
extern "C" Box* strNew1(BoxedClass* cls) {
assert(cls == str_cls);
return boxStrConstant("");
}
extern "C" Box* strNew2(BoxedClass* cls, Box* obj) {
extern "C" Box* strNew(BoxedClass* cls, Box* obj) {
assert(cls == str_cls);
return str(obj);
......@@ -354,29 +349,7 @@ Box* strJoin(BoxedString* self, Box* rhs) {
}
}
Box* strSplit1(BoxedString* self) {
assert(self->cls == str_cls);
BoxedList* rtn = new BoxedList();
std::ostringstream os("");
for (char c : self->s) {
if (c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\f' || c == '\v') {
if (os.tellp()) {
listAppendInternal(rtn, boxString(os.str()));
os.str("");
}
} else {
os << c;
}
}
if (os.tellp()) {
listAppendInternal(rtn, boxString(os.str()));
}
return rtn;
}
Box* strSplit2(BoxedString* self, BoxedString* sep) {
Box* strSplit(BoxedString* self, BoxedString* sep) {
assert(self->cls == str_cls);
if (sep->cls == str_cls) {
......@@ -392,58 +365,59 @@ Box* strSplit2(BoxedString* self, BoxedString* sep) {
raiseExcHelper(ValueError, "empty separator");
}
} else if (sep->cls == none_cls) {
return strSplit1(self);
BoxedList* rtn = new BoxedList();
std::ostringstream os("");
for (char c : self->s) {
if (c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\f' || c == '\v') {
if (os.tellp()) {
listAppendInternal(rtn, boxString(os.str()));
os.str("");
}
} else {
os << c;
}
}
if (os.tellp()) {
listAppendInternal(rtn, boxString(os.str()));
}
return rtn;
} else {
raiseExcHelper(TypeError, "expected a character buffer object");
}
}
Box* strStrip1(BoxedString* self) {
assert(self->cls == str_cls);
return new BoxedString(llvm::StringRef(self->s).trim(" \t\n\r\f\v"));
}
Box* strStrip2(BoxedString* self, Box* chars) {
Box* strStrip(BoxedString* self, Box* chars) {
assert(self->cls == str_cls);
if (chars->cls == str_cls) {
return new BoxedString(llvm::StringRef(self->s).trim(static_cast<BoxedString*>(chars)->s));
} else if (chars->cls == none_cls) {
return strStrip1(self);
return new BoxedString(llvm::StringRef(self->s).trim(" \t\n\r\f\v"));
} else {
raiseExcHelper(TypeError, "strip arg must be None, str or unicode");
}
}
Box* strLStrip1(BoxedString* self) {
assert(self->cls == str_cls);
return new BoxedString(llvm::StringRef(self->s).ltrim(" \t\n\r\f\v"));
}
Box* strLStrip2(BoxedString* self, Box* chars) {
Box* strLStrip(BoxedString* self, Box* chars) {
assert(self->cls == str_cls);
if (chars->cls == str_cls) {
return new BoxedString(llvm::StringRef(self->s).ltrim(static_cast<BoxedString*>(chars)->s));
} else if (chars->cls == none_cls) {
return strLStrip1(self);
return new BoxedString(llvm::StringRef(self->s).ltrim(" \t\n\r\f\v"));
} else {
raiseExcHelper(TypeError, "lstrip arg must be None, str or unicode");
}
}
Box* strRStrip1(BoxedString* self) {
assert(self->cls == str_cls);
return new BoxedString(llvm::StringRef(self->s).rtrim(" \t\n\r\f\v"));
}
Box* strRStrip2(BoxedString* self, Box* chars) {
Box* strRStrip(BoxedString* self, Box* chars) {
assert(self->cls == str_cls);
if (chars->cls == str_cls) {
return new BoxedString(llvm::StringRef(self->s).rtrim(static_cast<BoxedString*>(chars)->s));
} else if (chars->cls == none_cls) {
return strRStrip1(self);
return new BoxedString(llvm::StringRef(self->s).rtrim(" \t\n\r\f\v"));
} else {
raiseExcHelper(TypeError, "rstrip arg must be None, str or unicode");
}
......@@ -569,58 +543,47 @@ void setupStr() {
gc::registerStaticRootObj(str_iterator_cls);
str_iterator_cls->giveAttr("__name__", boxStrConstant("striterator"));
str_iterator_cls->giveAttr("__hasnext__",
new BoxedFunction(boxRTFunction((void*)BoxedStringIterator::hasnext, NULL, 1, false)));
str_iterator_cls->giveAttr("next",
new BoxedFunction(boxRTFunction((void*)BoxedStringIterator::next, STR, 1, false)));
new BoxedFunction(boxRTFunction((void*)BoxedStringIterator::hasnext, BOXED_BOOL, 1)));
str_iterator_cls->giveAttr("next", new BoxedFunction(boxRTFunction((void*)BoxedStringIterator::next, STR, 1)));
str_iterator_cls->freeze();
str_cls->giveAttr("__name__", boxStrConstant("str"));
str_cls->giveAttr("__len__", new BoxedFunction(boxRTFunction((void*)strLen, NULL, 1, false)));
str_cls->giveAttr("__str__", new BoxedFunction(boxRTFunction((void*)strStr, NULL, 1, false)));
str_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)strRepr, NULL, 1, false)));
str_cls->giveAttr("__hash__", new BoxedFunction(boxRTFunction((void*)strHash, NULL, 1, false)));
str_cls->giveAttr("__nonzero__", new BoxedFunction(boxRTFunction((void*)strNonzero, NULL, 1, false)));
str_cls->giveAttr("__len__", new BoxedFunction(boxRTFunction((void*)strLen, BOXED_INT, 1)));
str_cls->giveAttr("__str__", new BoxedFunction(boxRTFunction((void*)strStr, STR, 1)));
str_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)strRepr, STR, 1)));
str_cls->giveAttr("__hash__", new BoxedFunction(boxRTFunction((void*)strHash, BOXED_INT, 1)));
str_cls->giveAttr("__nonzero__", new BoxedFunction(boxRTFunction((void*)strNonzero, BOXED_BOOL, 1)));
str_cls->giveAttr("lower", new BoxedFunction(boxRTFunction((void*)strLower, STR, 1, false)));
str_cls->giveAttr("lower", new BoxedFunction(boxRTFunction((void*)strLower, STR, 1)));
CLFunction* strStrip = boxRTFunction((void*)strStrip1, STR, 1, false);
addRTFunction(strStrip, (void*)strStrip2, STR, 2, false);
str_cls->giveAttr("strip", new BoxedFunction(strStrip));
str_cls->giveAttr("strip", new BoxedFunction(boxRTFunction((void*)strStrip, STR, 2, 1, false, false), { None }));
CLFunction* strLStrip = boxRTFunction((void*)strLStrip1, STR, 1, false);
addRTFunction(strLStrip, (void*)strLStrip2, STR, 2, false);
str_cls->giveAttr("lstrip", new BoxedFunction(strLStrip));
str_cls->giveAttr("lstrip", new BoxedFunction(boxRTFunction((void*)strLStrip, STR, 2, 1, false, false), { None }));
CLFunction* strRStrip = boxRTFunction((void*)strRStrip1, STR, 1, false);
addRTFunction(strRStrip, (void*)strRStrip2, STR, 2, false);
str_cls->giveAttr("rstrip", new BoxedFunction(strRStrip));
str_cls->giveAttr("rstrip", new BoxedFunction(boxRTFunction((void*)strRStrip, STR, 2, 1, false, false), { None }));
str_cls->giveAttr("__contains__", new BoxedFunction(boxRTFunction((void*)strContains, BOXED_BOOL, 2, false)));
str_cls->giveAttr("__contains__", new BoxedFunction(boxRTFunction((void*)strContains, BOXED_BOOL, 2)));
str_cls->giveAttr("__add__", new BoxedFunction(boxRTFunction((void*)strAdd, NULL, 2, false)));
str_cls->giveAttr("__mod__", new BoxedFunction(boxRTFunction((void*)strMod, NULL, 2, false)));
str_cls->giveAttr("__mul__", new BoxedFunction(boxRTFunction((void*)strMul, NULL, 2, false)));
str_cls->giveAttr("__eq__", new BoxedFunction(boxRTFunction((void*)strEq, NULL, 2, false)));
str_cls->giveAttr("__getitem__", new BoxedFunction(boxRTFunction((void*)strGetitem, NULL, 2, false)));
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)));
str_cls->giveAttr("__eq__", new BoxedFunction(boxRTFunction((void*)strEq, UNKNOWN, 2)));
str_cls->giveAttr("__getitem__", new BoxedFunction(boxRTFunction((void*)strGetitem, STR, 2)));
str_cls->giveAttr("__iter__",
new BoxedFunction(boxRTFunction((void*)strIter, typeFromClass(str_iterator_cls), 1, false)));
str_cls->giveAttr("__iter__", new BoxedFunction(boxRTFunction((void*)strIter, typeFromClass(str_iterator_cls), 1)));
str_cls->giveAttr("join", new BoxedFunction(boxRTFunction((void*)strJoin, NULL, 2, false)));
str_cls->giveAttr("join", new BoxedFunction(boxRTFunction((void*)strJoin, STR, 2)));
CLFunction* strSplit = boxRTFunction((void*)strSplit1, LIST, 1, false);
addRTFunction(strSplit, (void*)strSplit2, LIST, 2, false);
str_cls->giveAttr("split", new BoxedFunction(strSplit));
str_cls->giveAttr("split", new BoxedFunction(boxRTFunction((void*)strSplit, LIST, 2, 1, false, false), { None }));
str_cls->giveAttr("rsplit", str_cls->getattr("split"));
CLFunction* count = boxRTFunction((void*)strCount2Unboxed, INT, 2, false);
addRTFunction(count, (void*)strCount2, BOXED_INT, 2, false);
CLFunction* count = boxRTFunction((void*)strCount2Unboxed, INT, 2);
addRTFunction(count, (void*)strCount2, BOXED_INT);
str_cls->giveAttr("count", new BoxedFunction(count));
CLFunction* __new__ = boxRTFunction((void*)strNew1, NULL, 1, false);
addRTFunction(__new__, (void*)strNew2, NULL, 2, false);
str_cls->giveAttr("__new__", new BoxedFunction(__new__));
str_cls->giveAttr("__new__", new BoxedFunction(boxRTFunction((void*)strNew, UNKNOWN, 2, 1, false, false),
{ boxStrConstant("") }));
str_cls->freeze();
}
......
......@@ -205,23 +205,23 @@ void setupTuple() {
tuple_cls->giveAttr("__name__", boxStrConstant("tuple"));
tuple_cls->giveAttr("__getitem__", new BoxedFunction(boxRTFunction((void*)tupleGetitem, NULL, 2, false)));
tuple_cls->giveAttr("__contains__", new BoxedFunction(boxRTFunction((void*)tupleContains, NULL, 2, false)));
tuple_cls->giveAttr("__getitem__", new BoxedFunction(boxRTFunction((void*)tupleGetitem, UNKNOWN, 2)));
tuple_cls->giveAttr("__contains__", new BoxedFunction(boxRTFunction((void*)tupleContains, BOXED_BOOL, 2)));
tuple_cls->giveAttr(
"__iter__", new BoxedFunction(boxRTFunction((void*)tupleIter, typeFromClass(tuple_iterator_cls), 1, false)));
tuple_cls->giveAttr("__iter__",
new BoxedFunction(boxRTFunction((void*)tupleIter, typeFromClass(tuple_iterator_cls), 1)));
tuple_cls->giveAttr("__lt__", new BoxedFunction(boxRTFunction((void*)tupleLt, NULL, 2, false)));
tuple_cls->giveAttr("__le__", new BoxedFunction(boxRTFunction((void*)tupleLe, NULL, 2, false)));
tuple_cls->giveAttr("__gt__", new BoxedFunction(boxRTFunction((void*)tupleGt, NULL, 2, false)));
tuple_cls->giveAttr("__ge__", new BoxedFunction(boxRTFunction((void*)tupleGe, NULL, 2, false)));
tuple_cls->giveAttr("__eq__", new BoxedFunction(boxRTFunction((void*)tupleEq, NULL, 2, false)));
tuple_cls->giveAttr("__ne__", new BoxedFunction(boxRTFunction((void*)tupleNe, NULL, 2, false)));
tuple_cls->giveAttr("__lt__", new BoxedFunction(boxRTFunction((void*)tupleLt, UNKNOWN, 2)));
tuple_cls->giveAttr("__le__", new BoxedFunction(boxRTFunction((void*)tupleLe, UNKNOWN, 2)));
tuple_cls->giveAttr("__gt__", new BoxedFunction(boxRTFunction((void*)tupleGt, UNKNOWN, 2)));
tuple_cls->giveAttr("__ge__", new BoxedFunction(boxRTFunction((void*)tupleGe, UNKNOWN, 2)));
tuple_cls->giveAttr("__eq__", new BoxedFunction(boxRTFunction((void*)tupleEq, UNKNOWN, 2)));
tuple_cls->giveAttr("__ne__", new BoxedFunction(boxRTFunction((void*)tupleNe, UNKNOWN, 2)));
tuple_cls->giveAttr("__hash__", new BoxedFunction(boxRTFunction((void*)tupleHash, BOXED_INT, 1, false)));
tuple_cls->giveAttr("__len__", new BoxedFunction(boxRTFunction((void*)tupleLen, NULL, 1, false)));
tuple_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)tupleRepr, NULL, 1, false)));
tuple_cls->giveAttr("__hash__", new BoxedFunction(boxRTFunction((void*)tupleHash, BOXED_INT, 1)));
tuple_cls->giveAttr("__len__", new BoxedFunction(boxRTFunction((void*)tupleLen, BOXED_INT, 1)));
tuple_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)tupleRepr, STR, 1)));
tuple_cls->giveAttr("__str__", tuple_cls->getattr("__repr__"));
tuple_cls->freeze();
......@@ -229,12 +229,12 @@ void setupTuple() {
gc::registerStaticRootObj(tuple_iterator_cls);
tuple_iterator_cls->giveAttr("__name__", boxStrConstant("tupleiterator"));
CLFunction* hasnext = boxRTFunction((void*)tupleiterHasnextUnboxed, BOOL, 1, false);
addRTFunction(hasnext, (void*)tupleiterHasnext, BOXED_BOOL, 1, false);
CLFunction* hasnext = boxRTFunction((void*)tupleiterHasnextUnboxed, BOOL, 1);
addRTFunction(hasnext, (void*)tupleiterHasnext, BOXED_BOOL);
tuple_iterator_cls->giveAttr("__hasnext__", new BoxedFunction(hasnext));
tuple_iterator_cls->giveAttr("__iter__", new BoxedFunction(boxRTFunction(
(void*)tupleIterIter, typeFromClass(tuple_iterator_cls), 1, false)));
tuple_iterator_cls->giveAttr("next", new BoxedFunction(boxRTFunction((void*)tupleiterNext, UNKNOWN, 1, false)));
tuple_iterator_cls->giveAttr(
"__iter__", new BoxedFunction(boxRTFunction((void*)tupleIterIter, typeFromClass(tuple_iterator_cls), 1)));
tuple_iterator_cls->giveAttr("next", new BoxedFunction(boxRTFunction((void*)tupleiterNext, UNKNOWN, 1)));
tuple_iterator_cls->freeze();
}
......
This diff is collapsed.
......@@ -196,21 +196,26 @@ public:
: Box(&instancemethod_flavor, instancemethod_cls), obj(obj), func(func) {}
};
class BoxedList : public Box {
class GCdArray : public GCObject {
public:
class ElementArray : public GCObject {
public:
Box* elts[0];
Box* elts[0];
GCdArray() : GCObject(&untracked_kind) {}
ElementArray() : GCObject(&untracked_kind) {}
void* operator new(size_t size, int capacity) {
assert(size == sizeof(GCdArray));
return rt_alloc(capacity * sizeof(Box*) + size);
}
void* operator new(size_t size, int capacity) {
return rt_alloc(capacity * sizeof(Box*) + sizeof(BoxedList::ElementArray));
}
};
static GCdArray* realloc(GCdArray* array, int capacity) {
return (GCdArray*)rt_realloc(array, capacity * sizeof(Box*) + sizeof(GCdArray));
}
};
class BoxedList : public Box {
public:
int64_t size, capacity;
ElementArray* elts;
GCdArray* elts;
BoxedList() __attribute__((visibility("default"))) : Box(&list_flavor, list_cls), size(0), capacity(0) {}
......@@ -229,6 +234,7 @@ public:
BoxedTuple(std::vector<Box*, StlCompatAllocator<Box*> >&& elts) __attribute__((visibility("default")))
: Box(&tuple_flavor, tuple_cls), elts(std::move(elts)) {}
};
extern "C" BoxedTuple* EmptyTuple;
class BoxedFile : public Box {
public:
......@@ -263,7 +269,11 @@ public:
HCAttrs attrs;
CLFunction* f;
int ndefaults;
GCdArray* defaults;
BoxedFunction(CLFunction* f);
BoxedFunction(CLFunction* f, std::initializer_list<Box*> defaults);
};
class BoxedModule : public Box {
......
d = {}
print d.get(1)
print d.setdefault(2)
print d
d[2] = 5
print d.pop(2)
print d.pop(2, None)
print d.pop(2, None)
print range(5)
print range(5, 10)
print list(xrange(5))
print list(xrange(5, 10))
# expected: fail
# - with statements
# Test for various defaults arguments in builtin functions:
class ExpectationFailedException(Exception):
pass
class ExpectedException(object):
def __init__(self, excs):
if isinstance(excs, BaseException):
excs = (excs,)
self.excs = excs
def __enter__(self):
pass
def __exit__(self, type, val, tback):
if not val:
raise ExpectationFailedException("Didn't raise any exception")
if not isinstance(val, self.excs):
raise ExpectationFailedException("Raised %s instead of %s" % (val, self.excs))
print "Caught", type.__name__
return True
expected_exception = ExpectedException
d = {}
print d.get(1)
print d.setdefault(2)
print d.pop(2)
print d.pop(2, None)
print d.pop(2, None)
with expected_exception(KeyError):
print d.pop(2)
print min([1])
print min([1], None)
class Int(int):
def __add__(self, rhs):
print "Int.__add__", rhs
return int.__add__(self, rhs)
def __radd__(self, rhs):
print "Int.__radd__", rhs
return int.__radd__(self, rhs)
print sum([Int(2)])
with expected_exception(AttributeError):
print getattr(object(), "")
print getattr(object(), "", None)
print range(5)
with expected_exception(TypeError):
print range(5, None)
print range(5, 10)
print list(xrange(5))
with expected_exception(TypeError):
print list(xrange(5, None))
print list(xrange(5, 10))
# expected: fail
# - keywords
def f(a, b, c):
print a, b, c
......
# expected: statfail
# - rewriter bails on keywords for now
# statcheck: stats['slowpath_runtimecall'] <= 20
# statcheck: stats.get("slowpath_callclfunc", 0) <= 20
# statcheck: stats['rewriter_nopatch'] <= 20
def f(a, b):
print a, b
for i in xrange(10000):
f(a=1, b=2)
f(b=1, a=2)
# expected: fail
# - not supported yet
class C(object):
def __len__(self):
print "__len__"
return 2
def __iter__(self):
print "__iter__"
return self
def next(self):
print "Next"
raise StopIteration()
def __getitem__(self, k):
print "getitem", k
return k
def keys(self):
print "keys"
return ["a", "c", "b"]
def f(a, b, c):
print a, b, c
f(**C())
# run_args: -n
# statcheck: stats['slowpath_getitem'] <= 20
# statcheck: stats.get('slowpath_getitem', 0) <= 20
# statcheck: stats['slowpath_setitem'] <= 20
def sort(l):
......
# expected: fail
# - not supported yet
class C(object):
def __len__(self):
print "__len__"
return 2
def __iter__(self):
print "__iter__"
return self
def next(self):
print "Next"
raise StopIteration()
def f(a, b, c):
print a, b, c
f(*C())
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