From b9dd99d5185db82ba15f774abc85aa04d162d4d9 Mon Sep 17 00:00:00 2001 From: Michael Hansen Date: Wed, 5 Jul 2017 16:36:04 -0700 Subject: [PATCH] Don't create special objects for NULL, just use NULL directly. Also move null check into PycRef for nullable references. --- ASTNode.cpp | 2 - ASTNode.h | 15 ++-- ASTree.cpp | 226 +++++++++++++++++++++++------------------------ FastStack.h | 4 +- bytecode.cpp | 5 ++ pyc_numeric.cpp | 4 +- pyc_numeric.h | 4 +- pyc_object.cpp | 7 +- pyc_object.h | 19 ++-- pyc_sequence.cpp | 12 +-- pyc_string.cpp | 2 +- pycdas.cpp | 15 ++-- 12 files changed, 160 insertions(+), 155 deletions(-) diff --git a/ASTNode.cpp b/ASTNode.cpp index 1de26b6..efb9911 100644 --- a/ASTNode.cpp +++ b/ASTNode.cpp @@ -1,7 +1,5 @@ #include "ASTNode.h" -PycRef Node_NULL = (ASTNode*)0; - /* ASTNodeList */ void ASTNodeList::removeLast() { diff --git a/ASTNode.h b/ASTNode.h index fee0dc7..4bd1b06 100644 --- a/ASTNode.h +++ b/ASTNode.h @@ -52,9 +52,6 @@ public: void delRef() { internalDelRef(this); } }; -/* A NULL node for comparison */ -extern PycRef Node_NULL; - class ASTNodeList : public ASTNode { public: @@ -157,8 +154,8 @@ public: SLICE0, SLICE1, SLICE2, SLICE3 }; - ASTSlice(int op, PycRef left = Node_NULL, - PycRef right = Node_NULL) + ASTSlice(int op, PycRef left = NULL, + PycRef right = NULL) : ASTBinary(left, right, op, NODE_SLICE) { } }; @@ -258,7 +255,7 @@ public: ASTCall(PycRef func, pparam_t pparams, kwparam_t kwparams) : ASTNode(NODE_CALL), m_func(func), m_pparams(pparams), m_kwparams(kwparams), - m_var(Node_NULL), m_kw(Node_NULL) { } + m_var(), m_kw() { } PycRef func() const { return m_func; } const pparam_t& pparams() const { return m_pparams; } @@ -266,8 +263,8 @@ public: PycRef var() const { return m_var; } PycRef kw() const { return m_kw; } - bool hasVar() const { return m_var != Node_NULL; } - bool hasKW() const { return m_kw != Node_NULL; } + bool hasVar() const { return m_var != NULL; } + bool hasKW() const { return m_kw != NULL; } void setVar(PycRef var) { m_var = var; } void setKW(PycRef kw) { m_kw = kw; } @@ -363,7 +360,7 @@ private: class ASTPrint : public ASTNode { public: - ASTPrint(PycRef value, PycRef stream = Node_NULL) + ASTPrint(PycRef value, PycRef stream = NULL) : ASTNode(NODE_PRINT), m_value(value), m_stream(stream) { } PycRef value() const { return m_value; } diff --git a/ASTree.cpp b/ASTree.cpp index 90e75ae..ff8f5c2 100644 --- a/ASTree.cpp +++ b/ASTree.cpp @@ -293,21 +293,21 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) PycRef start = stack.top(); stack.pop(); - if (start->type() == ASTNode::NODE_OBJECT + if (start.type() == ASTNode::NODE_OBJECT && start.cast()->object() == Pyc_None) { - start = Node_NULL; + start = NULL; } - if (end->type() == ASTNode::NODE_OBJECT + if (end.type() == ASTNode::NODE_OBJECT && end.cast()->object() == Pyc_None) { - end = Node_NULL; + end = NULL; } - if (start == Node_NULL && end == Node_NULL) { + if (start == NULL && end == NULL) { stack.push(new ASTSlice(ASTSlice::SLICE0)); - } else if (start == Node_NULL) { + } else if (start == NULL) { stack.push(new ASTSlice(ASTSlice::SLICE2, start, end)); - } else if (end == Node_NULL) { + } else if (end == NULL) { stack.push(new ASTSlice(ASTSlice::SLICE1, start, end)); } else { stack.push(new ASTSlice(ASTSlice::SLICE3, start, end)); @@ -320,29 +320,29 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) PycRef start = stack.top(); stack.pop(); - if (start->type() == ASTNode::NODE_OBJECT + if (start.type() == ASTNode::NODE_OBJECT && start.cast()->object() == Pyc_None) { - start = Node_NULL; + start = NULL; } - if (end->type() == ASTNode::NODE_OBJECT + if (end.type() == ASTNode::NODE_OBJECT && end.cast()->object() == Pyc_None) { - end = Node_NULL; + end = NULL; } - if (step->type() == ASTNode::NODE_OBJECT + if (step.type() == ASTNode::NODE_OBJECT && step.cast()->object() == Pyc_None) { - step = Node_NULL; + step = NULL; } /* We have to do this as a slice where one side is another slice */ /* [[a:b]:c] */ - if (start == Node_NULL && end == Node_NULL) { + if (start == NULL && end == NULL) { stack.push(new ASTSlice(ASTSlice::SLICE0)); - } else if (start == Node_NULL) { + } else if (start == NULL) { stack.push(new ASTSlice(ASTSlice::SLICE2, start, end)); - } else if (end == Node_NULL) { + } else if (end == NULL) { stack.push(new ASTSlice(ASTSlice::SLICE1, start, end)); } else { stack.push(new ASTSlice(ASTSlice::SLICE3, start, end)); @@ -351,7 +351,7 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) PycRef lhs = stack.top(); stack.pop(); - if (step == Node_NULL) { + if (step == NULL) { stack.push(new ASTSlice(ASTSlice::SLICE1, lhs, step)); } else { stack.push(new ASTSlice(ASTSlice::SLICE3, lhs, step)); @@ -383,7 +383,7 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) ASTTuple::value_t bases; bases.resize(basecnt); PycRef TOS = stack.top(); - int TOS_type = TOS->type(); + int TOS_type = TOS.type(); // bases are NODE_NAME at TOS while (TOS_type == ASTNode::NODE_NAME) { bases.resize(basecnt + 1); @@ -391,7 +391,7 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) basecnt++; stack.pop(); TOS = stack.top(); - TOS_type = TOS->type(); + TOS_type = TOS.type(); } // qualified name is PycString at TOS PycRef name = stack.top(); @@ -400,7 +400,7 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) stack.pop(); PycRef loadbuild = stack.top(); stack.pop(); - int loadbuild_type = loadbuild->type(); + int loadbuild_type = loadbuild.type(); if (loadbuild_type == ASTNode::NODE_LOADBUILDCLASS) { PycRef call = new ASTCall(function, pparamList, kwparamList); stack.push(new ASTClass(call, new ASTTuple(bases), name)); @@ -423,7 +423,7 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) for (int i=0; i param = stack.top(); stack.pop(); - if (param->type() == ASTNode::NODE_FUNCTION) { + if (param.type() == ASTNode::NODE_FUNCTION) { PycRef code = param.cast()->code(); PycRef code_src = code.cast()->object().cast(); PycRef function_name = code_src->name(); @@ -607,7 +607,7 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) PycRef name = stack.top(); stack.pop(); - curblock->append(new ASTDelete(new ASTSubscr(name, new ASTSlice(ASTSlice::SLICE2, Node_NULL, lower)))); + curblock->append(new ASTDelete(new ASTSubscr(name, new ASTSlice(ASTSlice::SLICE2, NULL, lower)))); } break; case Pyc::DELETE_SLICE_3: @@ -744,7 +744,7 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) blocks.push(forblk.cast()); curblock = blocks.top(); - stack.push(Node_NULL); + stack.push(NULL); } break; case Pyc::FOR_LOOP_A: @@ -771,7 +771,7 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) and the current item onto the stack." */ stack.push(iter); stack.push(curidx); - stack.push(Node_NULL); // We can totally hack this >_> + stack.push(NULL); // We can totally hack this >_> } break; case Pyc::GET_ITER: @@ -779,7 +779,7 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) break; case Pyc::IMPORT_NAME_A: if (mod->majorVer() == 1) { - stack.push(new ASTImport(new ASTName(code->getName(operand)), Node_NULL)); + stack.push(new ASTImport(new ASTName(code->getName(operand)), NULL)); } else { PycRef fromlist = stack.top(); stack.pop(); @@ -795,7 +795,7 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) { PycRef import = stack.top(); stack.pop(); - curblock->append(new ASTStore(import, Node_NULL)); + curblock->append(new ASTStore(import, NULL)); } break; case Pyc::INPLACE_ADD: @@ -964,10 +964,10 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) offs = pos + operand; } - if (cond->type() == ASTNode::NODE_COMPARE + if (cond.type() == ASTNode::NODE_COMPARE && cond.cast()->op() == ASTCompare::CMP_EXCEPTION) { if (curblock->blktype() == ASTBlock::BLK_EXCEPT - && curblock.cast()->cond() == Node_NULL) { + && curblock.cast()->cond() == NULL) { blocks.pop(); curblock = blocks.top(); @@ -1036,7 +1036,7 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) && curblock.cast()->isComprehension()) { PycRef top = stack.top(); - if (top->type() == ASTNode::NODE_COMPREHENSION) { + if (top.type() == ASTNode::NODE_COMPREHENSION) { PycRef comp = top.cast(); comp->addGenerator(curblock.cast()); @@ -1070,7 +1070,7 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) if (curblock->blktype() == ASTBlock::BLK_CONTAINER) { PycRef cont = curblock.cast(); if (cont->hasExcept() && pos < cont->except()) { - PycRef except = new ASTCondBlock(ASTBlock::BLK_EXCEPT, 0, Node_NULL, false); + PycRef except = new ASTCondBlock(ASTBlock::BLK_EXCEPT, 0, NULL, false); except->init(); blocks.push(except); curblock = blocks.top(); @@ -1106,7 +1106,7 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) if (push) { stack_hist.push(stack); } - PycRef next = new ASTCondBlock(ASTBlock::BLK_EXCEPT, blocks.top()->end(), Node_NULL, false); + PycRef next = new ASTCondBlock(ASTBlock::BLK_EXCEPT, blocks.top()->end(), NULL, false); next->init(); blocks.push(next.cast()); @@ -1136,7 +1136,7 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) stack_hist.push(stack); curblock->setEnd(pos+operand); - PycRef except = new ASTCondBlock(ASTBlock::BLK_EXCEPT, pos+operand, Node_NULL, false); + PycRef except = new ASTCondBlock(ASTBlock::BLK_EXCEPT, pos+operand, NULL, false); except->init(); blocks.push(except); curblock = blocks.top(); @@ -1196,7 +1196,7 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) if (push) { stack_hist.push(stack); } - PycRef next = new ASTCondBlock(ASTBlock::BLK_EXCEPT, pos+operand, Node_NULL, false); + PycRef next = new ASTCondBlock(ASTBlock::BLK_EXCEPT, pos+operand, NULL, false); next->init(); blocks.push(next.cast()); @@ -1227,7 +1227,7 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) stack_hist.push(stack); } - PycRef except = new ASTCondBlock(ASTBlock::BLK_EXCEPT, pos+operand, Node_NULL, false); + PycRef except = new ASTCondBlock(ASTBlock::BLK_EXCEPT, pos+operand, NULL, false); except->init(); blocks.push(except); } @@ -1268,7 +1268,7 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) case Pyc::LOAD_ATTR_A: { PycRef name = stack.top(); - if (name->type() != ASTNode::NODE_IMPORT) { + if (name.type() != ASTNode::NODE_IMPORT) { stack.pop(); stack.push(new ASTBinary(name, new ASTName(code->getName(operand)), ASTBinary::BIN_ATTR)); } @@ -1281,13 +1281,13 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) { PycRef t_ob = new ASTObject(code->getConst(operand)); - if ((t_ob->object()->type() == PycObject::TYPE_TUPLE || - t_ob->object()->type() == PycObject::TYPE_SMALL_TUPLE) && + if ((t_ob->object().type() == PycObject::TYPE_TUPLE || + t_ob->object().type() == PycObject::TYPE_SMALL_TUPLE) && !t_ob->object().cast()->values().size()) { ASTTuple::value_t values; stack.push(new ASTTuple(values)); - } else if (t_ob->object()->type() == PycObject::TYPE_NONE) { - stack.push(Node_NULL); + } else if (t_ob->object().type() == PycObject::TYPE_NONE) { + stack.push(NULL); } else { stack.push(t_ob.cast()); } @@ -1318,7 +1318,7 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) stack.pop(); /* Test for the qualified name of the function (at TOS) */ - int tos_type = code.cast()->object()->type(); + int tos_type = code.cast()->object().type(); if (tos_type != PycObject::TYPE_CODE && tos_type != PycObject::TYPE_CODE2) { code = stack.top(); @@ -1351,7 +1351,7 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) PycRef tmp; if (curblock->nodes().size() && - curblock->nodes().back()->type() == ASTNode::NODE_KEYWORD) { + curblock->nodes().back().type() == ASTNode::NODE_KEYWORD) { curblock->removeLast(); } @@ -1444,11 +1444,11 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) curblock.cast()->init(); } break; - } else if (value->type() == ASTNode::NODE_INVALID - || value->type() == ASTNode::NODE_BINARY - || value->type() == ASTNode::NODE_NAME) { + } else if (value.type() == ASTNode::NODE_INVALID + || value.type() == ASTNode::NODE_BINARY + || value.type() == ASTNode::NODE_NAME) { break; - } else if (value->type() == ASTNode::NODE_COMPARE + } else if (value.type() == ASTNode::NODE_COMPARE && value.cast()->op() == ASTCompare::CMP_EXCEPTION) { break; } @@ -1461,7 +1461,7 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) * If it's a comprehension, the only POP_TOP should be * a call to append the iter to the list. */ - if (value->type() == ASTNode::NODE_CALL) { + if (value.type() == ASTNode::NODE_CALL) { PycRef res = value.cast()->pparams().front(); stack.push(new ASTComprehension(res)); @@ -1483,10 +1483,10 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) break; } case Pyc::PRINT_NEWLINE: - curblock->append(new ASTPrint(Node_NULL)); + curblock->append(new ASTPrint(NULL)); break; case Pyc::PRINT_NEWLINE_TO: - curblock->append(new ASTPrint(Node_NULL, stack.top())); + curblock->append(new ASTPrint(NULL, stack.top())); stack.pop(); break; case Pyc::RAISE_VARARGS_A: @@ -1592,7 +1592,7 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) PycRef none = stack.top(); stack.pop(); - if (none != Node_NULL) { + if (none != NULL) { fprintf(stderr, "Something TERRIBLE happened!\n"); break; } @@ -1638,7 +1638,7 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) break; case Pyc::SETUP_LOOP_A: { - PycRef next = new ASTCondBlock(ASTBlock::BLK_WHILE, pos+operand, Node_NULL, false); + PycRef next = new ASTCondBlock(ASTBlock::BLK_WHILE, pos+operand, NULL, false); blocks.push(next.cast()); curblock = blocks.top(); } @@ -1670,7 +1670,7 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) PycRef name = stack.top(); stack.pop(); - PycRef slice = new ASTSlice(ASTSlice::SLICE2, Node_NULL, upper); + PycRef slice = new ASTSlice(ASTSlice::SLICE2, NULL, upper); stack.push(new ASTSubscr(name, slice)); } break; @@ -1695,7 +1695,7 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) PycRef attr = new ASTBinary(name, new ASTName(code->getName(operand)), ASTBinary::BIN_ATTR); PycRef tup = stack.top(); - if (tup->type() == ASTNode::NODE_TUPLE) { + if (tup.type() == ASTNode::NODE_TUPLE) { stack.pop(); PycRef tuple = tup.cast(); @@ -1731,7 +1731,7 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) PycRef name = new ASTName(code->getCellVar(operand).cast()); PycRef tup = stack.top(); - if (tup->type() == ASTNode::NODE_TUPLE) { + if (tup.type() == ASTNode::NODE_TUPLE) { stack.pop(); PycRef tuple = tup.cast(); @@ -1769,7 +1769,7 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) name = new ASTName(code->getVarName(operand)); PycRef tup = stack.top(); - if (tup->type() == ASTNode::NODE_TUPLE) { + if (tup.type() == ASTNode::NODE_TUPLE) { stack.pop(); PycRef tuple = tup.cast(); @@ -1828,7 +1828,7 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) if (unpack) { PycRef tup = stack.top(); - if (tup->type() == ASTNode::NODE_TUPLE) { + if (tup.type() == ASTNode::NODE_TUPLE) { stack.pop(); PycRef tuple = tup.cast(); @@ -1868,7 +1868,7 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) PycRef name = new ASTName(code->getName(operand)); PycRef tup = stack.top(); - if (tup->type() == ASTNode::NODE_TUPLE) { + if (tup.type() == ASTNode::NODE_TUPLE) { stack.pop(); PycRef tuple = tup.cast(); @@ -1907,7 +1907,7 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) if (curblock->blktype() == ASTBlock::BLK_FOR && !curblock->inited()) { curblock.cast()->setIndex(name); - } else if (stack.top()->type() == ASTNode::NODE_IMPORT) { + } else if (stack.top().type() == ASTNode::NODE_IMPORT) { PycRef import = stack.top().cast(); import->add_store(new ASTStore(value, name)); @@ -1918,7 +1918,7 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) } else { curblock->append(new ASTStore(value, name)); - if (value->type() == ASTNode::NODE_INVALID) + if (value.type() == ASTNode::NODE_INVALID) break; } } @@ -1955,7 +1955,7 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) PycRef value = stack.top(); stack.pop(); - curblock->append(new ASTStore(value, new ASTSubscr(dest, new ASTSlice(ASTSlice::SLICE2, Node_NULL, lower)))); + curblock->append(new ASTStore(value, new ASTSubscr(dest, new ASTSlice(ASTSlice::SLICE2, NULL, lower)))); } break; case Pyc::STORE_SLICE_3: @@ -1983,7 +1983,7 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) PycRef save = new ASTSubscr(dest, subscr); PycRef tup = stack.top(); - if (tup->type() == ASTNode::NODE_TUPLE) { + if (tup.type() == ASTNode::NODE_TUPLE) { stack.pop(); PycRef tuple = tup.cast(); @@ -2010,7 +2010,7 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) PycRef src = stack.top(); stack.pop(); - if (dest->type() == ASTNode::NODE_MAP) { + if (dest.type() == ASTNode::NODE_MAP) { dest.cast()->add(subscr, src); } else { curblock->append(new ASTStore(src, new ASTSubscr(dest, subscr))); @@ -2125,20 +2125,20 @@ static int cmp_prec(PycRef parent, PycRef child) Else we'd have expressions like (((a + b) + c) + d) when therefore equivalent, a + b + c + d would suffice. */ - if (parent->type() == ASTNode::NODE_UNARY && parent.cast()->op() == ASTUnary::UN_NOT) + if (parent.type() == ASTNode::NODE_UNARY && parent.cast()->op() == ASTUnary::UN_NOT) return 1; // Always parenthesize not(x) - if (child->type() == ASTNode::NODE_BINARY) { + if (child.type() == ASTNode::NODE_BINARY) { PycRef binChild = child.cast(); - if (parent->type() == ASTNode::NODE_BINARY) + if (parent.type() == ASTNode::NODE_BINARY) return binChild->op() - parent.cast()->op(); - else if (parent->type() == ASTNode::NODE_COMPARE) + else if (parent.type() == ASTNode::NODE_COMPARE) return (binChild->op() == ASTBinary::BIN_LOG_AND || binChild->op() == ASTBinary::BIN_LOG_OR) ? 1 : -1; - else if (parent->type() == ASTNode::NODE_UNARY) + else if (parent.type() == ASTNode::NODE_UNARY) return (binChild->op() == ASTBinary::BIN_POWER) ? -1 : 1; - } else if (child->type() == ASTNode::NODE_UNARY) { + } else if (child.type() == ASTNode::NODE_UNARY) { PycRef unChild = child.cast(); - if (parent->type() == ASTNode::NODE_BINARY) { + if (parent.type() == ASTNode::NODE_BINARY) { PycRef binParent = parent.cast(); if (binParent->op() == ASTBinary::BIN_LOG_AND || binParent->op() == ASTBinary::BIN_LOG_OR) @@ -2149,19 +2149,19 @@ static int cmp_prec(PycRef parent, PycRef child) return 1; else return -1; - } else if (parent->type() == ASTNode::NODE_COMPARE) { + } else if (parent.type() == ASTNode::NODE_COMPARE) { return (unChild->op() == ASTUnary::UN_NOT) ? 1 : -1; - } else if (parent->type() == ASTNode::NODE_UNARY) { + } else if (parent.type() == ASTNode::NODE_UNARY) { return unChild->op() - parent.cast()->op(); } - } else if (child->type() == ASTNode::NODE_COMPARE) { + } else if (child.type() == ASTNode::NODE_COMPARE) { PycRef cmpChild = child.cast(); - if (parent->type() == ASTNode::NODE_BINARY) + if (parent.type() == ASTNode::NODE_BINARY) return (parent.cast()->op() == ASTBinary::BIN_LOG_AND || parent.cast()->op() == ASTBinary::BIN_LOG_OR) ? -1 : 1; - else if (parent->type() == ASTNode::NODE_COMPARE) + else if (parent.type() == ASTNode::NODE_COMPARE) return cmpChild->op() - parent.cast()->op(); - else if (parent->type() == ASTNode::NODE_UNARY) + else if (parent.type() == ASTNode::NODE_UNARY) return (parent.cast()->op() == ASTUnary::UN_NOT) ? -1 : 1; } @@ -2172,8 +2172,8 @@ static int cmp_prec(PycRef parent, PycRef child) static void print_ordered(PycRef parent, PycRef child, PycModule* mod) { - if (child->type() == ASTNode::NODE_BINARY || - child->type() == ASTNode::NODE_COMPARE) { + if (child.type() == ASTNode::NODE_BINARY || + child.type() == ASTNode::NODE_COMPARE) { if (cmp_prec(parent, child) > 0) { fprintf(pyc_output, "("); print_src(child, mod); @@ -2181,7 +2181,7 @@ static void print_ordered(PycRef parent, PycRef child, } else { print_src(child, mod); } - } else if (child->type() == ASTNode::NODE_UNARY) { + } else if (child.type() == ASTNode::NODE_UNARY) { if (cmp_prec(parent, child) > 0) { fprintf(pyc_output, "("); print_src(child, mod); @@ -2220,7 +2220,7 @@ static void print_block(PycRef blk, PycModule* mod) { } for (ASTBlock::list_t::const_iterator ln = lines.begin(); ln != lines.end();) { - if ((*ln).cast()->type() != ASTNode::NODE_NODELIST) { + if ((*ln).cast().type() != ASTNode::NODE_NODELIST) { start_line(cur_indent); } print_src(*ln, mod); @@ -2232,7 +2232,7 @@ static void print_block(PycRef blk, PycModule* mod) { void print_src(PycRef node, PycModule* mod) { - if (node == Node_NULL) { + if (node == NULL) { fprintf(pyc_output, "None"); cleanBuild = true; return; @@ -2303,11 +2303,11 @@ void print_src(PycRef node, PycModule* mod) fprintf(pyc_output, "exec "); print_src(exec->statement(), mod); - if (exec->globals() != Node_NULL) { + if (exec->globals() != NULL) { fprintf(pyc_output, " in "); print_src(exec->globals(), mod); - if (exec->locals() != Node_NULL + if (exec->locals() != NULL && exec->globals() != exec->locals()) { fprintf(pyc_output, ", "); print_src(exec->locals(), mod); @@ -2383,7 +2383,7 @@ void print_src(PycRef node, PycModule* mod) cur_indent++; ASTNodeList::list_t lines = node.cast()->nodes(); for (ASTNodeList::list_t::const_iterator ln = lines.begin(); ln != lines.end(); ++ln) { - if ((*ln).cast()->type() != ASTNode::NODE_NODELIST) { + if ((*ln).cast().type() != ASTNode::NODE_NODELIST) { start_line(cur_indent); } print_src(*ln, mod); @@ -2424,14 +2424,14 @@ void print_src(PycRef node, PycModule* mod) fprintf(pyc_output, " in "); print_src(blk.cast()->iter(), mod); } else if (blk->blktype() == ASTBlock::BLK_EXCEPT && - blk.cast()->cond() != Node_NULL) { + blk.cast()->cond() != NULL) { fprintf(pyc_output, " "); print_src(blk.cast()->cond(), mod); } else if (blk->blktype() == ASTBlock::BLK_WITH) { fprintf(pyc_output, " "); print_src(blk.cast()->expr(), mod); PycRef var = blk.cast()->var(); - if (var != Node_NULL) { + if (var != NULL) { fprintf(pyc_output, " as "); print_src(var, mod); } @@ -2450,7 +2450,7 @@ void print_src(PycRef node, PycModule* mod) case ASTNode::NODE_OBJECT: { PycRef obj = node.cast()->object(); - if (obj->type() == PycObject::TYPE_CODE) { + if (obj.type() == PycObject::TYPE_CODE) { PycRef code = obj.cast(); decompyle(code, mod); } else { @@ -2462,10 +2462,10 @@ void print_src(PycRef node, PycModule* mod) fprintf(pyc_output, "pass"); break; case ASTNode::NODE_PRINT: - if (node.cast()->value() == Node_NULL) { + if (node.cast()->value() == NULL) { if (!inPrint) { fprintf(pyc_output, "print "); - if (node.cast()->stream() != Node_NULL) { + if (node.cast()->stream() != NULL) { fprintf(pyc_output, ">>"); print_src(node.cast()->stream(), mod); } @@ -2473,7 +2473,7 @@ void print_src(PycRef node, PycModule* mod) inPrint = false; } else if (!inPrint) { fprintf(pyc_output, "print "); - if (node.cast()->stream() != Node_NULL) { + if (node.cast()->stream() != NULL) { fprintf(pyc_output, ">>"); print_src(node.cast()->stream(), mod); fprintf(pyc_output, ", "); @@ -2534,7 +2534,7 @@ void print_src(PycRef node, PycModule* mod) ASTImport::list_t stores = import->stores(); fprintf(pyc_output, "from "); - if (import->name()->type() == ASTNode::NODE_IMPORT) + if (import->name().type() == ASTNode::NODE_IMPORT) print_src(import->name().cast()->name(), mod); else print_src(import->name(), mod); @@ -2598,7 +2598,7 @@ void print_src(PycRef node, PycModule* mod) { PycRef src = node.cast()->src(); PycRef dest = node.cast()->dest(); - if (src->type() == ASTNode::NODE_FUNCTION) { + if (src.type() == ASTNode::NODE_FUNCTION) { PycRef code = src.cast()->code(); PycRef code_src = code.cast()->object().cast(); bool isLambda = false; @@ -2663,7 +2663,7 @@ void print_src(PycRef node, PycModule* mod) print_src(code, mod); inLambda = preLambda; - } else if (src->type() == ASTNode::NODE_CLASS) { + } else if (src.type() == ASTNode::NODE_CLASS) { fprintf(pyc_output, "\n"); start_line(cur_indent); fprintf(pyc_output, "class "); @@ -2687,19 +2687,19 @@ void print_src(PycRef node, PycModule* mod) PycRef code = src.cast()->code().cast() ->func().cast()->code(); print_src(code, mod); - } else if (src->type() == ASTNode::NODE_IMPORT) { + } else if (src.type() == ASTNode::NODE_IMPORT) { PycRef import = src.cast(); - if (import->fromlist() != Node_NULL) { + if (import->fromlist() != NULL) { PycRef fromlist = import->fromlist().cast()->object(); if (fromlist != Pyc_None) { fprintf(pyc_output, "from "); - if (import->name()->type() == ASTNode::NODE_IMPORT) + if (import->name().type() == ASTNode::NODE_IMPORT) print_src(import->name().cast()->name(), mod); else print_src(import->name(), mod); fprintf(pyc_output, " import "); - if (fromlist->type() == PycObject::TYPE_TUPLE || - fromlist->type() == PycObject::TYPE_SMALL_TUPLE) { + if (fromlist.type() == PycObject::TYPE_TUPLE || + fromlist.type() == PycObject::TYPE_SMALL_TUPLE) { bool first = true; PycTuple::value_t::const_iterator ii = fromlist.cast()->values().begin(); for (; ii != fromlist.cast()->values().end(); ++ii) { @@ -2724,7 +2724,7 @@ void print_src(PycRef node, PycModule* mod) print_src(dest, mod); } } - } else if (src->type() == ASTNode::NODE_BINARY && + } else if (src.type() == ASTNode::NODE_BINARY && src.cast()->is_inplace() == true) { print_src(src, mod); } else { @@ -2780,16 +2780,16 @@ bool print_docstring(PycRef obj, int indent, PycModule* mod) { // docstrings are translated from the bytecode __doc__ = 'string' to simply '''string''' signed char prefix = -1; - if (obj->type() == PycObject::TYPE_STRING) + if (obj.type() == PycObject::TYPE_STRING) prefix = mod->majorVer() == 3 ? 'b' : 0; - else if (obj->type() == PycObject::TYPE_UNICODE) + else if (obj.type() == PycObject::TYPE_UNICODE) prefix = mod->majorVer() == 3 ? 0 : 'u'; - else if (obj->type() == PycObject::TYPE_INTERNED || - obj->type() == PycObject::TYPE_STRINGREF || - obj->type() == PycObject::TYPE_ASCII || - obj->type() == PycObject::TYPE_ASCII_INTERNED || - obj->type() == PycObject::TYPE_SHORT_ASCII || - obj->type() == PycObject::TYPE_SHORT_ASCII_INTERNED) + else if (obj.type() == PycObject::TYPE_INTERNED || + obj.type() == PycObject::TYPE_STRINGREF || + obj.type() == PycObject::TYPE_ASCII || + obj.type() == PycObject::TYPE_ASCII_INTERNED || + obj.type() == PycObject::TYPE_SHORT_ASCII || + obj.type() == PycObject::TYPE_SHORT_ASCII_INTERNED) prefix = 0; if (prefix != -1) { start_line(indent); @@ -2810,10 +2810,10 @@ void decompyle(PycRef code, PycModule* mod) // about, and would add extra code for re-compilation anyway. // We strip these lines out here, and then add a "pass" statement // if the cleaned up code is empty - if (clean->nodes().front()->type() == ASTNode::NODE_STORE) { + if (clean->nodes().front().type() == ASTNode::NODE_STORE) { PycRef store = clean->nodes().front().cast(); - if (store->src()->type() == ASTNode::NODE_NAME && - store->dest()->type() == ASTNode::NODE_NAME) { + if (store->src().type() == ASTNode::NODE_NAME && + store->dest().type() == ASTNode::NODE_NAME) { PycRef src = store->src().cast(); PycRef dest = store->dest().cast(); if (src->name()->isEqual("__name__") && @@ -2825,20 +2825,20 @@ void decompyle(PycRef code, PycModule* mod) } } // Class and module docstrings may only appear at the beginning of their source - if (printClassDocstring && clean->nodes().front()->type() == ASTNode::NODE_STORE) { + if (printClassDocstring && clean->nodes().front().type() == ASTNode::NODE_STORE) { PycRef store = clean->nodes().front().cast(); - if (store->dest()->type() == ASTNode::NODE_NAME && + if (store->dest().type() == ASTNode::NODE_NAME && store->dest().cast()->name()->isEqual("__doc__") && - store->src()->type() == ASTNode::NODE_OBJECT) { + store->src().type() == ASTNode::NODE_OBJECT) { if (print_docstring(store->src().cast()->object(), cur_indent + (code->name()->isEqual("") ? 0 : 1), mod)) clean->removeFirst(); } } - if (clean->nodes().back()->type() == ASTNode::NODE_RETURN) { + if (clean->nodes().back().type() == ASTNode::NODE_RETURN) { PycRef ret = clean->nodes().back().cast(); - if (ret->value() == Node_NULL || ret->value()->type() == ASTNode::NODE_LOCALS) { + if (ret->value() == NULL || ret->value().type() == ASTNode::NODE_LOCALS) { clean->removeLast(); // Always an extraneous return statement } } diff --git a/FastStack.h b/FastStack.h index f0e552f..edb06d2 100644 --- a/FastStack.h +++ b/FastStack.h @@ -35,7 +35,7 @@ public: void pop() { if (m_ptr > -1) - m_stack[m_ptr--] = Node_NULL; + m_stack[m_ptr--] = NULL; } PycRef top() const @@ -43,7 +43,7 @@ public: if (m_ptr > -1) return m_stack[m_ptr]; else - return Node_NULL; + return NULL; } void replace(const FastStack& copy) diff --git a/bytecode.cpp b/bytecode.cpp index 85e1a21..93aea19 100644 --- a/bytecode.cpp +++ b/bytecode.cpp @@ -141,6 +141,11 @@ bool Pyc::IsCompareArg(int opcode) void print_const(PycRef obj, PycModule* mod) { + if (obj == NULL) { + fprintf(pyc_output, ""); + return; + } + switch (obj->type()) { case PycObject::TYPE_STRING: OutputString(obj.cast(), (mod->majorVer() == 3) ? 'b' : 0); diff --git a/pyc_numeric.cpp b/pyc_numeric.cpp index 02f9801..4616f66 100644 --- a/pyc_numeric.cpp +++ b/pyc_numeric.cpp @@ -35,7 +35,7 @@ void PycLong::load(PycData* stream, PycModule*) bool PycLong::isEqual(PycRef obj) const { - if (type() != obj->type()) + if (type() != obj.type()) return false; PycRef longObj = obj.cast(); @@ -110,7 +110,7 @@ void PycFloat::load(PycData* stream, PycModule*) bool PycFloat::isEqual(PycRef obj) const { - if (type() != obj->type()) + if (type() != obj.type()) return false; PycRef floatObj = obj.cast(); diff --git a/pyc_numeric.h b/pyc_numeric.h index e08eab8..d12b4ba 100644 --- a/pyc_numeric.h +++ b/pyc_numeric.h @@ -13,7 +13,7 @@ public: bool isEqual(PycRef obj) const { - return (type() == obj->type()) && + return (type() == obj.type()) && (m_value == obj.cast()->m_value); } @@ -85,7 +85,7 @@ public: bool isEqual(PycRef obj) const { - return (type() == obj->type()) && + return (type() == obj.type()) && (m_value == obj.cast()->m_value); } diff --git a/pyc_object.cpp b/pyc_object.cpp index cf05b44..54a8b73 100644 --- a/pyc_object.cpp +++ b/pyc_object.cpp @@ -5,7 +5,6 @@ #include "data.h" #include -PycRef Pyc_NULL = (PycObject*)0; PycRef Pyc_None = new PycObject(PycObject::TYPE_NONE); PycRef Pyc_Ellipsis = new PycObject(PycObject::TYPE_ELLIPSIS); PycRef Pyc_StopIteration = new PycObject(PycObject::TYPE_STOPITER); @@ -16,7 +15,7 @@ PycRef CreateObject(int type) { switch (type) { case PycObject::TYPE_NULL: - return Pyc_NULL; + return NULL; case PycObject::TYPE_NONE: return Pyc_None; case PycObject::TYPE_FALSE: @@ -65,7 +64,7 @@ PycRef CreateObject(int type) return new PycSet(type); default: fprintf(stderr, "CreateObject: Got unsupported type 0x%X\n", type); - return Pyc_NULL; + return NULL; } } @@ -79,7 +78,7 @@ PycRef LoadObject(PycData* stream, PycModule* mod) obj = mod->getRef(index); } else { obj = CreateObject(type & 0x7F); - if (obj != Pyc_NULL) { + if (obj != NULL) { if (type & 0x80) mod->refObject(obj); obj->load(stream, mod); diff --git a/pyc_object.h b/pyc_object.h index 6a2a6ec..72e25a4 100644 --- a/pyc_object.h +++ b/pyc_object.h @@ -53,10 +53,14 @@ public: _Obj* operator->() const { return m_obj; } operator _Obj*() const { return m_obj; } + inline int type() const; + /* This is just for coding convenience -- no type checking is done! */ template PycRef<_Cast> cast() const { return static_cast<_Cast*>(m_obj); } + bool isIdent(const _Obj* obj) { return m_obj == obj; } + private: _Obj* m_obj; }; @@ -106,10 +110,10 @@ public: PycObject(int type = TYPE_UNKNOWN) : m_refs(0), m_type(type) { } virtual ~PycObject() { } - int type() const { return internalGetType(this); } + int type() const { return m_type; } virtual bool isEqual(PycRef obj) const - { return (this == (PycObject*)obj); } + { return obj.isIdent(this); } virtual void load(PycData*, PycModule*) { } @@ -117,22 +121,19 @@ private: int m_refs; int m_type; - // Hack to make clang happy :( - static int internalGetType(const PycObject *obj) - { - return obj ? obj->m_type : TYPE_NULL; - } - public: void addRef() { ++m_refs; } void delRef() { if (--m_refs == 0) delete this; } }; +template +int PycRef<_Obj>::type() const +{ return m_obj ? m_obj->type() : PycObject::TYPE_NULL; } + PycRef CreateObject(int type); PycRef LoadObject(PycData* stream, PycModule* mod); /* Static Singleton objects */ -extern PycRef Pyc_NULL; extern PycRef Pyc_None; extern PycRef Pyc_Ellipsis; extern PycRef Pyc_StopIteration; diff --git a/pyc_sequence.cpp b/pyc_sequence.cpp index 13b7f84..5f32f34 100644 --- a/pyc_sequence.cpp +++ b/pyc_sequence.cpp @@ -17,7 +17,7 @@ void PycTuple::load(PycData* stream, PycModule* mod) bool PycTuple::isEqual(PycRef obj) const { - if (type() != obj->type()) + if (type() != obj.type()) return false; PycRef tupleObj = obj.cast(); @@ -44,7 +44,7 @@ void PycList::load(PycData* stream, PycModule* mod) bool PycList::isEqual(PycRef obj) const { - if (type() != obj->type()) + if (type() != obj.type()) return false; PycRef listObj = obj.cast(); @@ -67,7 +67,7 @@ void PycDict::load(PycData* stream, PycModule* mod) PycRef key, val; for (;;) { key = LoadObject(stream, mod); - if (key == Pyc_NULL) + if (key == NULL) break; val = LoadObject(stream, mod); m_keys.push_back(key); @@ -77,7 +77,7 @@ void PycDict::load(PycData* stream, PycModule* mod) bool PycDict::isEqual(PycRef obj) const { - if (type() != obj->type()) + if (type() != obj.type()) return false; PycRef dictObj = obj.cast(); @@ -111,7 +111,7 @@ PycRef PycDict::get(PycRef key) const return *vi; ++ki, ++vi; } - return Pyc_NULL; // Disassembly shouldn't get non-existant keys + return NULL; // Disassembly shouldn't get non-existant keys } @@ -125,7 +125,7 @@ void PycSet::load(PycData* stream, PycModule* mod) bool PycSet::isEqual(PycRef obj) const { - if (type() != obj->type()) + if (type() != obj.type()) return false; PycRef setObj = obj.cast(); diff --git a/pyc_string.cpp b/pyc_string.cpp index 0391058..6c2f5d5 100644 --- a/pyc_string.cpp +++ b/pyc_string.cpp @@ -84,7 +84,7 @@ void PycString::load(PycData* stream, PycModule* mod) bool PycString::isEqual(PycRef obj) const { - if (type() != obj->type()) + if (type() != obj.type()) return false; PycRef strObj = obj.cast(); diff --git a/pycdas.cpp b/pycdas.cpp index 0eb9256..e5352b3 100644 --- a/pycdas.cpp +++ b/pycdas.cpp @@ -65,6 +65,11 @@ static void iprintf(int indent, const char* fmt, ...) void output_object(PycRef obj, PycModule* mod, int indent) { + if (obj == NULL) { + iprintf(indent, ""); + return; + } + switch (obj->type()) { case PycObject::TYPE_CODE: case PycObject::TYPE_CODE2: @@ -81,31 +86,31 @@ void output_object(PycRef obj, PycModule* mod, int indent) iprintf(indent + 1, "Flags: 0x%08X", codeObj->flags()); print_coflags(codeObj->flags()); - if (codeObj->names() != Pyc_NULL) { + if (codeObj->names() != NULL) { iprintf(indent + 1, "[Names]\n"); for (int i=0; inames()->size(); i++) output_object(codeObj->names()->get(i), mod, indent + 2); } - if (codeObj->varNames() != Pyc_NULL) { + if (codeObj->varNames() != NULL) { iprintf(indent + 1, "[Var Names]\n"); for (int i=0; ivarNames()->size(); i++) output_object(codeObj->varNames()->get(i), mod, indent + 2); } - if (codeObj->freeVars() != Pyc_NULL) { + if (codeObj->freeVars() != NULL) { iprintf(indent + 1, "[Free Vars]\n"); for (int i=0; ifreeVars()->size(); i++) output_object(codeObj->freeVars()->get(i), mod, indent + 2); } - if (codeObj->cellVars() != Pyc_NULL) { + if (codeObj->cellVars() != NULL) { iprintf(indent + 1, "[Cell Vars]\n"); for (int i=0; icellVars()->size(); i++) output_object(codeObj->cellVars()->get(i), mod, indent + 2); } - if (codeObj->consts() != Pyc_NULL) { + if (codeObj->consts() != NULL) { iprintf(indent + 1, "[Constants]\n"); for (int i=0; iconsts()->size(); i++) output_object(codeObj->consts()->get(i), mod, indent + 2);