Commit 7e14a2ce authored by Vinzenz Feenstra's avatar Vinzenz Feenstra

Introduction of slice ast type & updated libpypa

parent 47d02706
Subproject commit 641585556b4fec9d6efced9813b45ae72055db7a
Subproject commit 31c96e5b6d940f1455a7d47015cc7685a6179d88
......@@ -43,6 +43,7 @@ public:
ConcreteCompilerType* getTypeAtBlockEnd(InternedString name, CFGBlock* block) override;
BoxedClass* speculatedExprClass(AST_expr*) override { return NULL; }
BoxedClass* speculatedExprClass(AST_slice*) override { return NULL; }
};
ConcreteCompilerType* NullTypeAnalysis::getTypeAtBlockStart(InternedString name, CFGBlock* block) {
......@@ -79,9 +80,9 @@ static BoxedClass* simpleCallSpeculation(AST_Call* node, CompilerType* rtn_type,
typedef llvm::DenseMap<InternedString, CompilerType*> TypeMap;
typedef llvm::DenseMap<CFGBlock*, TypeMap> AllTypeMap;
typedef llvm::DenseMap<AST_expr*, CompilerType*> ExprTypeMap;
typedef llvm::DenseMap<AST_expr*, BoxedClass*> TypeSpeculations;
class BasicBlockTypePropagator : public ExprVisitor, public StmtVisitor {
typedef llvm::DenseMap<AST*, CompilerType*> ExprTypeMap;
typedef llvm::DenseMap<AST*, BoxedClass*> TypeSpeculations;
class BasicBlockTypePropagator : public ExprVisitor, public StmtVisitor, public SliceVisitor {
private:
static const bool EXPAND_UNNEEDED = true;
......@@ -132,6 +133,21 @@ private:
return old_type;
}
CompilerType* getType(AST_slice* node) {
type_speculations.erase(node);
void* raw_rtn = node->accept_slice(this);
CompilerType* rtn = static_cast<CompilerType*>(raw_rtn);
if (VERBOSITY() >= 3) {
print_ast(node);
printf(" %s\n", rtn->debugName().c_str());
}
expr_types[node] = rtn;
return rtn;
}
CompilerType* getType(AST_expr* node) {
type_speculations.erase(node);
......@@ -682,6 +698,7 @@ public:
return rtn;
}
BoxedClass* speculatedExprClass(AST_slice* call) override { return type_speculations[call]; }
BoxedClass* speculatedExprClass(AST_expr* call) override { return type_speculations[call]; }
static bool merge(CompilerType* lhs, CompilerType*& rhs) {
......
......@@ -27,6 +27,7 @@ class ScopeInfo;
class CFGBlock;
class BoxedClass;
class AST_expr;
class AST_slice;
class OSREntryDescriptor;
class TypeAnalysis {
......@@ -41,6 +42,7 @@ public:
virtual ConcreteCompilerType* getTypeAtBlockStart(InternedString name, CFGBlock* block) = 0;
virtual ConcreteCompilerType* getTypeAtBlockEnd(InternedString name, CFGBlock* block) = 0;
virtual BoxedClass* speculatedExprClass(AST_expr*) = 0;
virtual BoxedClass* speculatedExprClass(AST_slice*) = 0;
};
TypeAnalysis* doTypeAnalysis(CFG* cfg, const ParamNames& param_names,
......
......@@ -110,9 +110,10 @@ private:
Value visit_num(AST_Num* node);
Value visit_repr(AST_Repr* node);
Value visit_set(AST_Set* node);
Value visit_slice(AST_Slice* node);
Value visit_str(AST_Str* node);
Value visit_subscript(AST_Subscript* node);
Value visit_slice(AST_Slice* node);
Value visit_slice(AST_slice* node);
Value visit_tuple(AST_Tuple* node);
Value visit_yield(AST_Yield* node);
......@@ -516,7 +517,7 @@ void ASTInterpreter::doStore(AST_expr* node, Value value) {
AST_Subscript* subscript = (AST_Subscript*)node;
Value target = visit_expr(subscript->value);
Value slice = visit_expr(subscript->slice);
Value slice = visit_slice(subscript->slice);
if (jit)
jit->emitSetItem(target, slice, value);
......@@ -544,6 +545,23 @@ Value ASTInterpreter::visit_binop(AST_BinOp* node) {
return doBinOp(left, right, node->op_type, BinExpType::BinOp);
}
Value ASTInterpreter::visit_slice(AST_slice* node) {
switch (node->type) {
case AST_TYPE::ExtSlice:
return visit_extslice(static_cast<AST_ExtSlice*>(node));
case AST_TYPE::Ellipsis:
RELEASE_ASSERT(0, "not implemented");
break;
case AST_TYPE::Index:
return visit_index(static_cast<AST_Index*>(node));
case AST_TYPE::Slice:
return visit_slice(static_cast<AST_Slice*>(node));
default:
RELEASE_ASSERT(0, "Attempt to handle invalid slice type");
}
return Value();
}
Value ASTInterpreter::visit_slice(AST_Slice* node) {
Value lower = node->lower ? visit_expr(node->lower) : getNone();
Value upper = node->upper ? visit_expr(node->upper) : getNone();
......@@ -562,7 +580,7 @@ Value ASTInterpreter::visit_extslice(AST_ExtSlice* node) {
int num_slices = node->dims.size();
BoxedTuple* rtn = BoxedTuple::create(num_slices);
for (int i = 0; i < num_slices; ++i) {
Value v = visit_expr(node->dims[i]);
Value v = visit_slice(node->dims[i]);
rtn->elts[i] = v.o;
items.push_back(v);
}
......@@ -1156,7 +1174,7 @@ Value ASTInterpreter::visit_delete(AST_Delete* node) {
case AST_TYPE::Subscript: {
AST_Subscript* sub = (AST_Subscript*)target_;
Value value = visit_expr(sub->value);
Value slice = visit_expr(sub->slice);
Value slice = visit_slice(sub->slice);
if (jit)
jit->emitDelItem(value, slice);
delitem(value.o, slice.o);
......@@ -1265,10 +1283,6 @@ Value ASTInterpreter::visit_expr(AST_expr* node) {
return visit_compare((AST_Compare*)node);
case AST_TYPE::Dict:
return visit_dict((AST_Dict*)node);
case AST_TYPE::ExtSlice:
return visit_extslice((AST_ExtSlice*)node);
case AST_TYPE::Index:
return visit_index((AST_Index*)node);
case AST_TYPE::Lambda:
return visit_lambda((AST_Lambda*)node);
case AST_TYPE::List:
......@@ -1281,8 +1295,6 @@ Value ASTInterpreter::visit_expr(AST_expr* node) {
return visit_repr((AST_Repr*)node);
case AST_TYPE::Set:
return visit_set((AST_Set*)node);
case AST_TYPE::Slice:
return visit_slice((AST_Slice*)node);
case AST_TYPE::Str:
return visit_str((AST_Str*)node);
case AST_TYPE::Subscript:
......@@ -1531,7 +1543,7 @@ Value ASTInterpreter::visit_name(AST_Name* node) {
Value ASTInterpreter::visit_subscript(AST_Subscript* node) {
Value value = visit_expr(node->value);
Value slice = visit_expr(node->slice);
Value slice = visit_slice(node->slice);
return Value(getitem(value.o, slice.o), jit ? jit->emitGetItem(value, slice) : NULL);
}
......
......@@ -581,8 +581,7 @@ private:
OpInfo getEmptyOpInfo(const UnwindInfo& unw_info) { return OpInfo(irstate->getEffortLevel(), NULL, unw_info); }
void createExprTypeGuard(llvm::Value* check_val, AST_expr* node, llvm::Value* node_value,
AST_stmt* current_statement) {
void createExprTypeGuard(llvm::Value* check_val, AST* node, llvm::Value* node_value, AST_stmt* current_statement) {
assert(check_val->getType() == g.i1);
llvm::Metadata* md_vals[]
......@@ -1266,7 +1265,7 @@ private:
CompilerVariable* evalExtSlice(AST_ExtSlice* node, const UnwindInfo& unw_info) {
std::vector<CompilerVariable*> elts;
for (auto* e : node->dims) {
elts.push_back(evalExpr(e, unw_info));
elts.push_back(evalSlice(e, unw_info));
}
// TODO makeTuple should probably just transfer the vref, but I want to keep things consistent
......@@ -1295,7 +1294,7 @@ private:
CompilerVariable* evalSubscript(AST_Subscript* node, const UnwindInfo& unw_info) {
CompilerVariable* value = evalExpr(node->value, unw_info);
CompilerVariable* slice = evalExpr(node->slice, unw_info);
CompilerVariable* slice = evalSlice(node->slice, unw_info);
CompilerVariable* rtn = value->getitem(emitter, getOpInfoForNode(node, unw_info), slice);
value->decvref(emitter);
......@@ -1529,6 +1528,68 @@ private:
return new ConcreteCompilerVariable(t, v, grabbed);
}
template <typename AstType>
CompilerVariable* evalSliceExprPost(AstType* node, const UnwindInfo& unw_info, CompilerVariable* rtn) {
assert(rtn);
// Out-guarding:
BoxedClass* speculated_class = types->speculatedExprClass(node);
if (speculated_class != NULL) {
assert(rtn);
ConcreteCompilerType* speculated_type = typeFromClass(speculated_class);
if (VERBOSITY("irgen") >= 2) {
printf("Speculating that %s is actually %s, at ", rtn->getConcreteType()->debugName().c_str(),
speculated_type->debugName().c_str());
PrintVisitor printer;
node->accept(&printer);
printf("\n");
}
// That's not really a speculation.... could potentially handle this here, but
// I think it's better to just not generate bad speculations:
assert(!rtn->canConvertTo(speculated_type));
ConcreteCompilerVariable* old_rtn = rtn->makeConverted(emitter, UNKNOWN);
rtn->decvref(emitter);
llvm::Value* guard_check = old_rtn->makeClassCheck(emitter, speculated_class);
assert(guard_check->getType() == g.i1);
createExprTypeGuard(guard_check, node, old_rtn->getValue(), unw_info.current_stmt);
rtn = unboxVar(speculated_type, old_rtn->getValue(), true);
}
assert(rtn);
return rtn;
}
CompilerVariable* evalSlice(AST_slice* node, const UnwindInfo& unw_info) {
// printf("%d expr: %d\n", node->type, node->lineno);
if (node->lineno) {
emitter.getBuilder()->SetCurrentDebugLocation(
llvm::DebugLoc::get(node->lineno, 0, irstate->getFuncDbgInfo()));
}
CompilerVariable* rtn = NULL;
switch (node->type) {
case AST_TYPE::ExtSlice:
rtn = evalExtSlice(ast_cast<AST_ExtSlice>(node), unw_info);
break;
case AST_TYPE::Index:
rtn = evalIndex(ast_cast<AST_Index>(node), unw_info);
break;
case AST_TYPE::Slice:
rtn = evalSlice(ast_cast<AST_Slice>(node), unw_info);
break;
default:
printf("Unhandled slice type: %d (irgenerator.cpp:" STRINGIFY(__LINE__) ")\n", node->type);
exit(1);
}
return evalSliceExprPost(node, unw_info, rtn);
}
CompilerVariable* evalExpr(AST_expr* node, const UnwindInfo& unw_info) {
// printf("%d expr: %d\n", node->type, node->lineno);
if (node->lineno) {
......@@ -1556,12 +1617,6 @@ private:
case AST_TYPE::Dict:
rtn = evalDict(ast_cast<AST_Dict>(node), unw_info);
break;
case AST_TYPE::ExtSlice:
rtn = evalExtSlice(ast_cast<AST_ExtSlice>(node), unw_info);
break;
case AST_TYPE::Index:
rtn = evalIndex(ast_cast<AST_Index>(node), unw_info);
break;
case AST_TYPE::Lambda:
rtn = evalLambda(ast_cast<AST_Lambda>(node), unw_info);
break;
......@@ -1580,9 +1635,6 @@ private:
case AST_TYPE::Set:
rtn = evalSet(ast_cast<AST_Set>(node), unw_info);
break;
case AST_TYPE::Slice:
rtn = evalSlice(ast_cast<AST_Slice>(node), unw_info);
break;
case AST_TYPE::Str:
rtn = evalStr(ast_cast<AST_Str>(node), unw_info);
break;
......@@ -1616,40 +1668,7 @@ private:
printf("Unhandled expr type: %d (irgenerator.cpp:" STRINGIFY(__LINE__) ")\n", node->type);
exit(1);
}
assert(rtn);
// Out-guarding:
BoxedClass* speculated_class = types->speculatedExprClass(node);
if (speculated_class != NULL) {
assert(rtn);
ConcreteCompilerType* speculated_type = typeFromClass(speculated_class);
if (VERBOSITY("irgen") >= 2) {
printf("Speculating that %s is actually %s, at ", rtn->getConcreteType()->debugName().c_str(),
speculated_type->debugName().c_str());
PrintVisitor printer;
node->accept(&printer);
printf("\n");
}
// That's not really a speculation.... could potentially handle this here, but
// I think it's better to just not generate bad speculations:
assert(!rtn->canConvertTo(speculated_type));
ConcreteCompilerVariable* old_rtn = rtn->makeConverted(emitter, UNKNOWN);
rtn->decvref(emitter);
llvm::Value* guard_check = old_rtn->makeClassCheck(emitter, speculated_class);
assert(guard_check->getType() == g.i1);
createExprTypeGuard(guard_check, node, old_rtn->getValue(), unw_info.current_stmt);
rtn = unboxVar(speculated_type, old_rtn->getValue(), true);
}
assert(rtn);
return rtn;
return evalSliceExprPost(node, unw_info, rtn);
}
void _setFake(InternedString name, CompilerVariable* val) {
......@@ -1740,7 +1759,7 @@ private:
void _doSetitem(AST_Subscript* target, CompilerVariable* val, const UnwindInfo& unw_info) {
CompilerVariable* tget = evalExpr(target->value, unw_info);
CompilerVariable* slice = evalExpr(target->slice, unw_info);
CompilerVariable* slice = evalSlice(target->slice, unw_info);
ConcreteCompilerVariable* converted_target = tget->makeConverted(emitter, tget->getBoxType());
ConcreteCompilerVariable* converted_slice = slice->makeConverted(emitter, slice->getBoxType());
......@@ -1871,7 +1890,7 @@ private:
// invoke delitem in objmodel.cpp, which will invoke the listDelitem of list
void _doDelitem(AST_Subscript* target, const UnwindInfo& unw_info) {
CompilerVariable* tget = evalExpr(target->value, unw_info);
CompilerVariable* slice = evalExpr(target->slice, unw_info);
CompilerVariable* slice = evalSlice(target->slice, unw_info);
ConcreteCompilerVariable* converted_target = tget->makeConverted(emitter, tget->getBoxType());
ConcreteCompilerVariable* converted_slice = slice->makeConverted(emitter, slice->getBoxType());
......
......@@ -112,6 +112,7 @@ std::unique_ptr<InternedStringPool> BufferedReader::createInternedPool() {
AST* readASTMisc(BufferedReader* reader);
AST_expr* readASTExpr(BufferedReader* reader);
AST_stmt* readASTStmt(BufferedReader* reader);
AST_slice* readASTSlice(BufferedReader* reader);
static std::string readString(BufferedReader* reader) {
int strlen = reader->readUInt();
......@@ -167,6 +168,15 @@ static void readExprVector(std::vector<AST_expr*>& vec, BufferedReader* reader)
}
}
static void readSliceVector(std::vector<AST_slice*>& vec, BufferedReader* reader) {
int num_elts = reader->readShort();
if (VERBOSITY("parsing") >= 3)
printf("%d elts to read\n", num_elts);
for (int i = 0; i < num_elts; i++) {
vec.push_back(readASTSlice(reader));
}
}
template <class T> static void readMiscVector(std::vector<T*>& vec, BufferedReader* reader) {
int num_elts = reader->readShort();
if (VERBOSITY("parsing") >= 3)
......@@ -429,7 +439,7 @@ AST_ExtSlice* read_extslice(BufferedReader* reader) {
rtn->col_offset = -1;
rtn->lineno = -1;
readExprVector(rtn->dims, reader);
readSliceVector(rtn->dims, reader);
return rtn;
}
......@@ -720,7 +730,7 @@ AST_Subscript* read_subscript(BufferedReader* reader) {
rtn->col_offset = readColOffset(reader);
rtn->ctx_type = (AST_TYPE::AST_TYPE)reader->readByte();
rtn->lineno = reader->readULL();
rtn->slice = readASTExpr(reader);
rtn->slice = readASTSlice(reader);
rtn->value = readASTExpr(reader);
return rtn;
......@@ -803,6 +813,32 @@ AST_Yield* read_yield(BufferedReader* reader) {
return rtn;
}
AST_slice* readASTSlice(BufferedReader* reader) {
uint8_t type = reader->readByte();
if (VERBOSITY("parsing") >= 3)
printf("type = %d\n", type);
if (type == 0)
return NULL;
uint8_t checkbyte = reader->readByte();
assert(checkbyte == 0xae);
switch (type) {
case AST_TYPE::Ellipsis:
return read_ellipsis(reader);
case AST_TYPE::ExtSlice:
return read_extslice(reader);
case AST_TYPE::Index:
return read_index(reader);
case AST_TYPE::Slice:
return read_slice(reader);
default:
fprintf(stderr, "Unknown slice node type (parser.cpp:" STRINGIFY(__LINE__) "): %d\n", type);
abort();
break;
}
}
AST_expr* readASTExpr(BufferedReader* reader) {
uint8_t type = reader->readByte();
if (VERBOSITY("parsing") >= 3)
......@@ -828,16 +864,10 @@ AST_expr* readASTExpr(BufferedReader* reader) {
return read_dict(reader);
case AST_TYPE::DictComp:
return read_dictcomp(reader);
case AST_TYPE::Ellipsis:
return read_ellipsis(reader);
case AST_TYPE::ExtSlice:
return read_extslice(reader);
case AST_TYPE::GeneratorExp:
return read_generatorexp(reader);
case AST_TYPE::IfExp:
return read_ifexp(reader);
case AST_TYPE::Index:
return read_index(reader);
case AST_TYPE::Lambda:
return read_lambda(reader);
case AST_TYPE::List:
......@@ -854,8 +884,6 @@ AST_expr* readASTExpr(BufferedReader* reader) {
return read_set(reader);
case AST_TYPE::SetComp:
return read_setcomp(reader);
case AST_TYPE::Slice:
return read_slice(reader);
case AST_TYPE::Str:
return read_str(reader);
case AST_TYPE::Subscript:
......
......@@ -49,6 +49,7 @@ void location(AST* t, pypa::Ast& a) {
}
AST_expr* readItem(pypa::AstExpression& e, InternedStringPool& interned_strings);
AST_slice* readItem(pypa::AstSliceType& e, InternedStringPool& interned_strings);
AST_stmt* readItem(pypa::AstStatement& s, InternedStringPool& interned_strings);
AST_ExceptHandler* readItem(pypa::AstExcept&, InternedStringPool& interned_strings);
AST_ExceptHandler* readItem(pypa::AstExceptPtr, InternedStringPool& interned_strings);
......@@ -224,6 +225,10 @@ void readVector(std::vector<AST_expr*>& t, pypa::AstExpression& u, InternedStrin
}
}
void readVector(std::vector<AST_slice*>& t, pypa::AstSliceType& u, InternedStringPool& interned_strings) {
t.push_back(readItem(u, interned_strings));
}
void readVector(std::vector<AST_stmt*>& t, pypa::AstStatement& u, InternedStringPool& interned_strings) {
if (u.type == pypa::AstType::Suite) {
pypa::AstSuite& e = static_cast<pypa::AstSuite&>(u);
......@@ -257,6 +262,12 @@ void readVector(std::vector<AST_comprehension*>& t, pypa::AstExprList& u, Intern
}
}
void readVector(std::vector<AST_slice*>& t, pypa::AstSliceTypePtr u, InternedStringPool& interned_strings) {
if (u) {
readVector(t, *u, interned_strings);
}
}
void readVector(std::vector<AST_stmt*>& t, pypa::AstStmt u, InternedStringPool& interned_strings) {
if (u) {
readVector(t, *u, interned_strings);
......@@ -292,6 +303,57 @@ AST_arguments* readItem(pypa::AstArguments& a, InternedStringPool& interned_stri
return ptr;
}
struct slice_dispatcher {
InternedStringPool& interned_strings;
slice_dispatcher(InternedStringPool& interned_strings) : interned_strings(interned_strings) {}
typedef AST_slice* ResultPtr;
template <typename T> ResultPtr operator()(std::shared_ptr<T> t) {
if (t)
return (*this)(*t);
return nullptr;
}
template <typename T> ResultPtr operator()(T& t) {
pypa::Ast& a = t;
return read(t);
}
template <typename T> ResultPtr read(T& item) {
pypa::Ast& a = item;
RELEASE_ASSERT(0, "Unhandled ast slice type caught: %d @%s\n", a.type, __PRETTY_FUNCTION__);
}
ResultPtr read(pypa::AstEllipsis& e) {
AST_Ellipsis* ptr = new AST_Ellipsis();
location(ptr, e);
return ptr;
}
ResultPtr read(pypa::AstExtSlice& e) {
AST_ExtSlice* ptr = new AST_ExtSlice();
location(ptr, e);
readVector(ptr->dims, e.dims, interned_strings);
return ptr;
}
ResultPtr read(pypa::AstIndex& i) {
AST_Index* ptr = new AST_Index();
location(ptr, i);
ptr->value = readItem(i.value, interned_strings);
return ptr;
}
ResultPtr read(pypa::AstSlice& s) {
AST_Slice* ptr = new AST_Slice();
location(ptr, s);
ptr->lower = readItem(s.lower, interned_strings);
ptr->upper = readItem(s.upper, interned_strings);
ptr->step = readItem(s.step, interned_strings);
return ptr;
}
};
struct expr_dispatcher {
InternedStringPool& interned_strings;
expr_dispatcher(InternedStringPool& interned_strings) : interned_strings(interned_strings) {}
......@@ -400,19 +462,6 @@ struct expr_dispatcher {
return ptr;
}
ResultPtr read(pypa::AstEllipsis& e) {
AST_Ellipsis* ptr = new AST_Ellipsis();
location(ptr, e);
return ptr;
}
ResultPtr read(pypa::AstExtSlice& e) {
AST_ExtSlice* ptr = new AST_ExtSlice();
location(ptr, e);
readVector(ptr->dims, e.dims, interned_strings);
return ptr;
}
ResultPtr read(pypa::AstIfExpr& i) {
AST_IfExp* ptr = new AST_IfExp();
location(ptr, i);
......@@ -430,13 +479,6 @@ struct expr_dispatcher {
return ptr;
}
ResultPtr read(pypa::AstIndex& i) {
AST_Index* ptr = new AST_Index();
location(ptr, i);
ptr->value = readItem(i.value, interned_strings);
return ptr;
}
ResultPtr read(pypa::AstLambda& l) {
AST_Lambda* ptr = new AST_Lambda();
location(ptr, l);
......@@ -513,15 +555,6 @@ struct expr_dispatcher {
return ptr;
}
ResultPtr read(pypa::AstSlice& s) {
AST_Slice* ptr = new AST_Slice();
location(ptr, s);
ptr->lower = readItem(s.lower, interned_strings);
ptr->upper = readItem(s.upper, interned_strings);
ptr->step = readItem(s.step, interned_strings);
return ptr;
}
ResultPtr read(pypa::AstStr& s) {
AST_Str* ptr = new AST_Str();
location(ptr, s);
......@@ -829,6 +862,10 @@ AST_expr* readItem(pypa::AstExpression& e, InternedStringPool& interned_strings)
return pypa::visit<AST_expr*>(expr_dispatcher(interned_strings), e);
}
AST_slice* readItem(pypa::AstSliceType& e, InternedStringPool& interned_strings) {
return pypa::visit<AST_slice*>(slice_dispatcher(interned_strings), e);
}
AST_stmt* readItem(pypa::AstStatement& s, InternedStringPool& interned_strings) {
return pypa::visit<AST_stmt*>(stmt_dispatcher(interned_strings), s);
}
......
......@@ -100,6 +100,22 @@ private:
}
}
void writeSlice(AST_slice* e) {
if (!e) {
writeByte(0x00);
} else {
writeByte(e->type);
writeByte(0xae); // check byte
e->accept(this);
}
}
void writeSliceVector(const std::vector<AST_slice*>& vec) {
writeShort(vec.size());
for (auto* e : vec) {
writeSlice(e);
}
}
void writeExprVector(const std::vector<AST_expr*>& vec) {
writeShort(vec.size());
for (auto* e : vec) {
......@@ -301,7 +317,7 @@ private:
return true;
}
virtual bool visit_extslice(AST_ExtSlice* node) {
writeExprVector(node->dims);
writeSliceVector(node->dims);
return true;
}
virtual bool visit_for(AST_For* node) {
......@@ -494,7 +510,7 @@ private:
writeColOffset(node->col_offset);
writeByte(node->ctx_type);
writeLineno(node->lineno);
writeExpr(node->slice);
writeSlice(node->slice);
writeExpr(node->value);
return true;
}
......
......@@ -481,7 +481,7 @@ void AST_Ellipsis::accept(ASTVisitor* v) {
return;
}
void* AST_Ellipsis::accept_expr(ExprVisitor* v) {
void* AST_Ellipsis::accept_slice(SliceVisitor* v) {
return v->visit_ellipsis(this);
}
......@@ -534,7 +534,7 @@ void AST_ExtSlice::accept(ASTVisitor* v) {
visitVector(dims, v);
}
void* AST_ExtSlice::accept_expr(ExprVisitor* v) {
void* AST_ExtSlice::accept_slice(SliceVisitor* v) {
return v->visit_extslice(this);
}
......@@ -653,7 +653,7 @@ void AST_Index::accept(ASTVisitor* v) {
this->value->accept(v);
}
void* AST_Index::accept_expr(ExprVisitor* v) {
void* AST_Index::accept_slice(SliceVisitor* v) {
return v->visit_index(this);
}
......@@ -875,7 +875,7 @@ void AST_Slice::accept(ASTVisitor* v) {
step->accept(v);
}
void* AST_Slice::accept_expr(ExprVisitor* v) {
void* AST_Slice::accept_slice(SliceVisitor* v) {
return v->visit_slice(this);
}
......
......@@ -143,6 +143,7 @@ enum AST_TYPE {
class ASTVisitor;
class ExprVisitor;
class StmtVisitor;
class SliceVisitor;
class AST_keyword;
class AST {
......@@ -187,7 +188,12 @@ public:
AST_stmt(AST_TYPE::AST_TYPE type) : AST(type) {}
};
class AST_slice : public AST {
public:
virtual void* accept_slice(SliceVisitor* s) = 0;
AST_slice(AST_TYPE::AST_TYPE type) : AST(type) {}
AST_slice(AST_TYPE::AST_TYPE type, uint32_t lineno, uint32_t col_offset = 0) : AST(type, lineno, col_offset) {}
};
class AST_alias : public AST {
public:
......@@ -422,12 +428,12 @@ public:
static const AST_TYPE::AST_TYPE TYPE = AST_TYPE::Delete;
};
class AST_Ellipsis : public AST_expr {
class AST_Ellipsis : public AST_slice {
public:
virtual void accept(ASTVisitor* v);
virtual void* accept_expr(ExprVisitor* v);
virtual void* accept_slice(SliceVisitor* v);
AST_Ellipsis() : AST_expr(AST_TYPE::Ellipsis) {}
AST_Ellipsis() : AST_slice(AST_TYPE::Ellipsis) {}
static const AST_TYPE::AST_TYPE TYPE = AST_TYPE::Ellipsis;
};
......@@ -486,14 +492,14 @@ public:
static const AST_TYPE::AST_TYPE TYPE = AST_TYPE::Expression;
};
class AST_ExtSlice : public AST_expr {
class AST_ExtSlice : public AST_slice {
public:
std::vector<AST_expr*> dims;
std::vector<AST_slice*> dims;
virtual void accept(ASTVisitor* v);
virtual void* accept_expr(ExprVisitor* v);
virtual void* accept_slice(SliceVisitor* v);
AST_ExtSlice() : AST_expr(AST_TYPE::ExtSlice) {}
AST_ExtSlice() : AST_slice(AST_TYPE::ExtSlice) {}
static const AST_TYPE::AST_TYPE TYPE = AST_TYPE::ExtSlice;
};
......@@ -602,14 +608,14 @@ public:
static const AST_TYPE::AST_TYPE TYPE = AST_TYPE::ImportFrom;
};
class AST_Index : public AST_expr {
class AST_Index : public AST_slice {
public:
AST_expr* value;
virtual void accept(ASTVisitor* v);
virtual void* accept_expr(ExprVisitor* v);
virtual void* accept_slice(SliceVisitor* v);
AST_Index() : AST_expr(AST_TYPE::Index) {}
AST_Index() : AST_slice(AST_TYPE::Index) {}
static const AST_TYPE::AST_TYPE TYPE = AST_TYPE::Index;
};
......@@ -837,14 +843,14 @@ public:
const static AST_TYPE::AST_TYPE TYPE = AST_TYPE::SetComp;
};
class AST_Slice : public AST_expr {
class AST_Slice : public AST_slice {
public:
AST_expr* lower, *upper, *step;
virtual void accept(ASTVisitor* v);
virtual void* accept_expr(ExprVisitor* v);
virtual void* accept_slice(SliceVisitor* v);
AST_Slice() : AST_expr(AST_TYPE::Slice) {}
AST_Slice() : AST_slice(AST_TYPE::Slice) {}
static const AST_TYPE::AST_TYPE TYPE = AST_TYPE::Slice;
};
......@@ -872,7 +878,8 @@ public:
class AST_Subscript : public AST_expr {
public:
AST_expr* value, *slice;
AST_expr* value;
AST_slice* slice;
AST_TYPE::AST_TYPE ctx_type;
virtual void accept(ASTVisitor* v);
......@@ -1256,11 +1263,8 @@ public:
virtual void* visit_compare(AST_Compare* node) { RELEASE_ASSERT(0, ""); }
virtual void* visit_dict(AST_Dict* node) { RELEASE_ASSERT(0, ""); }
virtual void* visit_dictcomp(AST_DictComp* node) { RELEASE_ASSERT(0, ""); }
virtual void* visit_ellipsis(AST_Ellipsis* node) { RELEASE_ASSERT(0, ""); }
virtual void* visit_extslice(AST_ExtSlice* node) { RELEASE_ASSERT(0, ""); }
virtual void* visit_generatorexp(AST_GeneratorExp* node) { RELEASE_ASSERT(0, ""); }
virtual void* visit_ifexp(AST_IfExp* node) { RELEASE_ASSERT(0, ""); }
virtual void* visit_index(AST_Index* node) { RELEASE_ASSERT(0, ""); }
virtual void* visit_lambda(AST_Lambda* node) { RELEASE_ASSERT(0, ""); }
virtual void* visit_langprimitive(AST_LangPrimitive* node) { RELEASE_ASSERT(0, ""); }
virtual void* visit_list(AST_List* node) { RELEASE_ASSERT(0, ""); }
......@@ -1270,7 +1274,6 @@ public:
virtual void* visit_repr(AST_Repr* node) { RELEASE_ASSERT(0, ""); }
virtual void* visit_set(AST_Set* node) { RELEASE_ASSERT(0, ""); }
virtual void* visit_setcomp(AST_SetComp* node) { RELEASE_ASSERT(0, ""); }
virtual void* visit_slice(AST_Slice* node) { RELEASE_ASSERT(0, ""); }
virtual void* visit_str(AST_Str* node) { RELEASE_ASSERT(0, ""); }
virtual void* visit_subscript(AST_Subscript* node) { RELEASE_ASSERT(0, ""); }
virtual void* visit_tuple(AST_Tuple* node) { RELEASE_ASSERT(0, ""); }
......@@ -1314,6 +1317,15 @@ public:
virtual void visit_jump(AST_Jump* node) { RELEASE_ASSERT(0, ""); }
};
class SliceVisitor {
public:
virtual ~SliceVisitor() {}
virtual void* visit_ellipsis(AST_Ellipsis* node) { RELEASE_ASSERT(0, ""); }
virtual void* visit_extslice(AST_ExtSlice* node) { RELEASE_ASSERT(0, ""); }
virtual void* visit_index(AST_Index* node) { RELEASE_ASSERT(0, ""); }
virtual void* visit_slice(AST_Slice* node) { RELEASE_ASSERT(0, ""); }
};
void print_ast(AST* ast);
class PrintVisitor : public ASTVisitor {
private:
......
......@@ -549,7 +549,7 @@ private:
AST_Subscript* s_target = new AST_Subscript();
s_target->value = remapExpr(s->value);
s_target->slice = remapExpr(s->slice);
s_target->slice = remapSlice(s->slice);
s_target->ctx_type = AST_TYPE::Store;
s_target->col_offset = s->col_offset;
s_target->lineno = s->lineno;
......@@ -645,6 +645,47 @@ private:
return rtn;
}
AST_slice* _dup(AST_slice* val) {
if (val == nullptr) {
return nullptr;
} else if (val->type == AST_TYPE::Ellipsis) {
AST_Ellipsis* orig = ast_cast<AST_Ellipsis>(val);
AST_Ellipsis* made = new AST_Ellipsis();
made->col_offset = orig->col_offset;
made->lineno = orig->lineno;
return made;
} else if (val->type == AST_TYPE::ExtSlice) {
AST_ExtSlice* orig = ast_cast<AST_ExtSlice>(val);
AST_ExtSlice* made = new AST_ExtSlice();
made->col_offset = orig->col_offset;
made->lineno = orig->lineno;
made->dims.reserve(orig->dims.size());
for (AST_slice* item : orig->dims) {
made->dims.push_back(_dup(item));
}
return made;
} else if (val->type == AST_TYPE::Index) {
AST_Index* orig = ast_cast<AST_Index>(val);
AST_Index* made = new AST_Index();
made->value = _dup(orig->value);
made->col_offset = orig->col_offset;
made->lineno = orig->lineno;
return made;
} else if (val->type == AST_TYPE::Slice) {
AST_Slice* orig = ast_cast<AST_Slice>(val);
AST_Slice* made = new AST_Slice();
made->col_offset = orig->col_offset;
made->lineno = orig->lineno;
made->lower = _dup(orig->lower);
made->upper = _dup(orig->upper);
made->step = _dup(orig->step);
return made;
} else {
RELEASE_ASSERT(0, "%d", val->type);
}
return nullptr;
}
// Sometimes we want to refer to the same object twice,
// but we require that no AST* object gets reused.
// So instead, just create a copy of it.
......@@ -675,13 +716,6 @@ private:
made->col_offset = orig->col_offset;
made->lineno = orig->lineno;
return made;
} else if (val->type == AST_TYPE::Index) {
AST_Index* orig = ast_cast<AST_Index>(val);
AST_Index* made = new AST_Index();
made->value = _dup(orig->value);
made->col_offset = orig->col_offset;
made->lineno = orig->lineno;
return made;
} else {
RELEASE_ASSERT(0, "%d", val->type);
}
......@@ -855,15 +889,15 @@ private:
return rtn;
}
AST_expr* remapEllipsis(AST_Ellipsis* node) { return node; }
AST_slice* remapEllipsis(AST_Ellipsis* node) { return node; }
AST_expr* remapExtSlice(AST_ExtSlice* node) {
AST_slice* remapExtSlice(AST_ExtSlice* node) {
AST_ExtSlice* rtn = new AST_ExtSlice();
rtn->lineno = node->lineno;
rtn->col_offset = node->col_offset;
for (auto* e : node->dims)
rtn->dims.push_back(remapExpr(e));
rtn->dims.push_back(remapSlice(e));
return rtn;
}
......@@ -1014,7 +1048,7 @@ private:
return makeLoad(rtn_name, node);
}
AST_expr* remapIndex(AST_Index* node) {
AST_slice* remapIndex(AST_Index* node) {
AST_Index* rtn = new AST_Index();
rtn->lineno = node->lineno;
rtn->col_offset = node->col_offset;
......@@ -1088,7 +1122,7 @@ private:
return rtn;
}
AST_expr* remapSlice(AST_Slice* node) {
AST_slice* remapSlice(AST_Slice* node) {
AST_Slice* rtn = new AST_Slice();
rtn->lineno = node->lineno;
rtn->col_offset = node->col_offset;
......@@ -1120,7 +1154,7 @@ private:
rtn->col_offset = node->col_offset;
rtn->ctx_type = node->ctx_type;
rtn->value = remapExpr(node->value);
rtn->slice = remapExpr(node->slice);
rtn->slice = remapSlice(node->slice);
return rtn;
}
......@@ -1150,6 +1184,32 @@ private:
return makeLoad(node_name, node);
}
AST_slice* remapSlice(AST_slice* node) {
if (node == nullptr)
return nullptr;
AST_slice* rtn = nullptr;
switch (node->type) {
case AST_TYPE::Ellipsis:
rtn = remapEllipsis(ast_cast<AST_Ellipsis>(node));
break;
case AST_TYPE::ExtSlice:
rtn = remapExtSlice(ast_cast<AST_ExtSlice>(node));
break;
case AST_TYPE::Index:
if (ast_cast<AST_Index>(node)->value->type == AST_TYPE::Num)
return node;
rtn = remapIndex(ast_cast<AST_Index>(node));
break;
case AST_TYPE::Slice:
rtn = remapSlice(ast_cast<AST_Slice>(node));
break;
default:
RELEASE_ASSERT(0, "%d", node->type);
}
return rtn;
}
// Flattens a nested expression into a flat one, emitting instructions &
// generating temporary variables as needed.
//
......@@ -1185,23 +1245,12 @@ private:
case AST_TYPE::DictComp:
rtn = remapScopedComprehension<AST_Dict>(ast_cast<AST_DictComp>(node));
break;
case AST_TYPE::Ellipsis:
rtn = remapEllipsis(ast_cast<AST_Ellipsis>(node));
break;
case AST_TYPE::ExtSlice:
rtn = remapExtSlice(ast_cast<AST_ExtSlice>(node));
break;
case AST_TYPE::GeneratorExp:
rtn = remapGeneratorExp(ast_cast<AST_GeneratorExp>(node));
break;
case AST_TYPE::IfExp:
rtn = remapIfExp(ast_cast<AST_IfExp>(node));
break;
case AST_TYPE::Index:
if (ast_cast<AST_Index>(node)->value->type == AST_TYPE::Num)
return node;
rtn = remapIndex(ast_cast<AST_Index>(node));
break;
case AST_TYPE::Lambda:
rtn = remapLambda(ast_cast<AST_Lambda>(node));
break;
......@@ -1228,9 +1277,6 @@ private:
case AST_TYPE::SetComp:
rtn = remapScopedComprehension<AST_Set>(ast_cast<AST_SetComp>(node));
break;
case AST_TYPE::Slice:
rtn = remapSlice(ast_cast<AST_Slice>(node));
break;
case AST_TYPE::Str:
return node;
case AST_TYPE::Subscript:
......@@ -1683,7 +1729,7 @@ public:
AST_Subscript* s_target = new AST_Subscript();
s_target->value = remapExpr(s->value);
s_target->slice = remapExpr(s->slice);
s_target->slice = remapSlice(s->slice);
s_target->ctx_type = AST_TYPE::Store;
s_target->col_offset = s->col_offset;
s_target->lineno = s->lineno;
......@@ -1757,7 +1803,7 @@ public:
AST_Subscript* s = static_cast<AST_Subscript*>(t);
AST_Subscript* astsubs = new AST_Subscript();
astsubs->value = remapExpr(s->value);
astsubs->slice = remapExpr(s->slice);
astsubs->slice = remapSlice(s->slice);
astsubs->ctx_type = AST_TYPE::Del;
target = astsubs;
break;
......
# expected: fail
# skip-if: '-x' in EXTRA_JIT_ARGS
# - CPython parser backend doesn't handle well the errors
# should_error
2 = 2
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