bool PycDict::isEqual(PycRef<PycObject> obj) const { if (type() != obj->type()) return false; PycRef<PycDict> dictObj = obj.cast<PycDict>(); if (m_size != dictObj->m_size) return false; key_t::const_iterator ki1 = m_keys.begin(); key_t::const_iterator ki2 = dictObj->m_keys.begin(); while (ki1 != m_keys.end()) { if (!(*ki1)->isEqual(*ki2)) return false; ++ki1, ++ki2; } value_t::const_iterator vi1 = m_values.begin(); value_t::const_iterator vi2 = dictObj->m_values.begin(); while (vi1 != m_values.end()) { if (!(*vi1)->isEqual(*vi2)) return false; ++vi1, ++vi2; } return true; }
PycRef<PycObject> LoadObject(PycData* stream, PycModule* mod) { int type = stream->getByte(); PycRef<PycObject> obj; if (type == PycObject::TYPE_OBREF) { int index = stream->get32(); obj = mod->getRef(index); } else { obj = CreateObject(type & 0x7F); if (obj != NULL) { if (type & 0x80) mod->refObject(obj); obj->load(stream, mod); } } return obj; }
void bc_disasm(PycRef<PycCode> code, PycModule* mod, int indent) { PycBuffer source(code->code()->value(), code->code()->length()); int opcode, operand; int pos = 0; while (!source.atEof()) { for (int i=0; i<indent; i++) fprintf(pyc_output, " "); fprintf(pyc_output, "[%7X] ", pos); // Current bytecode position bc_next(source, mod, opcode, operand, pos); fprintf(pyc_output, "%-24s", Pyc::OpcodeName(opcode)); if (opcode >= Pyc::PYC_HAVE_ARG) { if (Pyc::IsConstArg(opcode)) { fprintf(pyc_output, "%d: ", operand); print_const(code->getConst(operand), mod); } else if (Pyc::IsNameArg(opcode)) { fprintf(pyc_output, "%d: %s", operand, code->getName(operand)->value()); } else if (Pyc::IsVarNameArg(opcode)) { fprintf(pyc_output, "%d: %s", operand, code->getVarName(operand)->value()); } else if (Pyc::IsCellArg(opcode)) { fprintf(pyc_output, "%d: ", operand); print_const(code->getCellVar(operand), mod); } else if (Pyc::IsJumpOffsetArg(opcode)) { fprintf(pyc_output, "%d (to %d)", operand, pos+operand); } else { fprintf(pyc_output, "%d", operand); } } fprintf(pyc_output, "\n"); } }
bool PycList::isEqual(PycRef<PycObject> obj) const { if (type() != obj->type()) return false; PycRef<PycList> listObj = obj.cast<PycList>(); if (m_size != listObj->m_size) return false; value_t::const_iterator it1 = m_values.begin(); value_t::const_iterator it2 = listObj->m_values.begin(); while (it1 != m_values.end()) { if (!(*it1)->isEqual(*it2)) return false; ++it1, ++it2; } return true; }
void print_const(PycRef<PycObject> obj, PycModule* mod) { switch (obj->type()) { case PycObject::TYPE_STRING: case PycObject::TYPE_STRINGREF: case PycObject::TYPE_INTERNED: OutputString(obj.cast<PycString>(), (mod->majorVer() == 3) ? 'b' : 0); break; case PycObject::TYPE_UNICODE: OutputString(obj.cast<PycString>(), (mod->majorVer() == 3) ? 0 : 'u'); break; case PycObject::TYPE_TUPLE: { fprintf(pyc_output, "("); PycTuple::value_t values = obj.cast<PycTuple>()->values(); PycTuple::value_t::const_iterator it = values.begin(); if (it != values.end()) { print_const(*it, mod); while (++it != values.end()) { fprintf(pyc_output, ", "); print_const(*it, mod); } } if (values.size() == 1) fprintf(pyc_output, ",)"); else fprintf(pyc_output, ")"); } break; case PycObject::TYPE_LIST: { fprintf(pyc_output, "["); PycList::value_t values = obj.cast<PycList>()->values(); PycList::value_t::const_iterator it = values.begin(); if (it != values.end()) { print_const(*it, mod); while (++it != values.end()) { fprintf(pyc_output, ", "); print_const(*it, mod); } } fprintf(pyc_output, "]"); } break; case PycObject::TYPE_DICT: { fprintf(pyc_output, "{"); PycDict::key_t keys = obj.cast<PycDict>()->keys(); PycDict::value_t values = obj.cast<PycDict>()->values(); PycDict::key_t::const_iterator ki = keys.begin(); PycDict::value_t::const_iterator vi = values.begin(); if (ki != keys.end()) { print_const(*ki, mod); fprintf(pyc_output, ": "); print_const(*vi, mod); while (++ki != keys.end()) { ++vi; fprintf(pyc_output, ", "); print_const(*ki, mod); fprintf(pyc_output, ": "); print_const(*vi, mod); } } fprintf(pyc_output, "}"); } break; case PycObject::TYPE_SET: { fprintf(pyc_output, "{"); PycSet::value_t values = obj.cast<PycSet>()->values(); PycSet::value_t::const_iterator it = values.begin(); if (it != values.end()) { print_const(*it, mod); while (++it != values.end()) { fprintf(pyc_output, ", "); print_const(*it, mod); } } fprintf(pyc_output, "}"); } break; case PycObject::TYPE_NONE: fprintf(pyc_output, "None"); break; case PycObject::TYPE_TRUE: fprintf(pyc_output, "True"); break; case PycObject::TYPE_FALSE: fprintf(pyc_output, "False"); break; case PycObject::TYPE_INT: fprintf(pyc_output, "%d", obj.cast<PycInt>()->value()); break; case PycObject::TYPE_LONG: fprintf(pyc_output, "%s", obj.cast<PycLong>()->repr().c_str()); break; case PycObject::TYPE_FLOAT: fprintf(pyc_output, "%s", obj.cast<PycFloat>()->value()); break; case PycObject::TYPE_COMPLEX: fprintf(pyc_output, "(%s+%sj)", obj.cast<PycComplex>()->value(), obj.cast<PycComplex>()->imag()); break; case PycObject::TYPE_BINARY_FLOAT: fprintf(pyc_output, "%g", obj.cast<PycCFloat>()->value()); break; case PycObject::TYPE_BINARY_COMPLEX: fprintf(pyc_output, "(%g+%gj)", obj.cast<PycCComplex>()->value(), obj.cast<PycCComplex>()->imag()); break; case PycObject::TYPE_CODE: case PycObject::TYPE_CODE2: fprintf(pyc_output, "<CODE> %s", obj.cast<PycCode>()->name()->value()); break; } }
void output_object(PycRef<PycObject> obj, PycModule* mod, int indent) { switch (obj->type()) { case PycObject::TYPE_CODE: case PycObject::TYPE_CODE2: { PycRef<PycCode> codeObj = obj.cast<PycCode>(); iprintf(indent, "[Code]\n"); iprintf(indent + 1, "File Name: %s\n", codeObj->fileName()->value()); iprintf(indent + 1, "Object Name: %s\n", codeObj->name()->value()); iprintf(indent + 1, "Arg Count: %d\n", codeObj->argCount()); if (mod->majorVer() >= 3) iprintf(indent + 1, "KW Only Arg Count: %d\n", codeObj->kwOnlyArgCount()); iprintf(indent + 1, "Locals: %d\n", codeObj->numLocals()); iprintf(indent + 1, "Stack Size: %d\n", codeObj->stackSize()); iprintf(indent + 1, "Flags: 0x%08X", codeObj->flags()); print_coflags(codeObj->flags()); if (codeObj->names() != Pyc_NULL) { iprintf(indent + 1, "[Names]\n"); for (int i=0; i<codeObj->names()->size(); i++) output_object(codeObj->names()->get(i), mod, indent + 2); } if (codeObj->varNames() != Pyc_NULL) { iprintf(indent + 1, "[Var Names]\n"); for (int i=0; i<codeObj->varNames()->size(); i++) output_object(codeObj->varNames()->get(i), mod, indent + 2); } if (codeObj->freeVars() != Pyc_NULL) { iprintf(indent + 1, "[Free Vars]\n"); for (int i=0; i<codeObj->freeVars()->size(); i++) output_object(codeObj->freeVars()->get(i), mod, indent + 2); } if (codeObj->cellVars() != Pyc_NULL) { iprintf(indent + 1, "[Cell Vars]\n"); for (int i=0; i<codeObj->cellVars()->size(); i++) output_object(codeObj->cellVars()->get(i), mod, indent + 2); } if (codeObj->consts() != Pyc_NULL) { iprintf(indent + 1, "[Constants]\n"); for (int i=0; i<codeObj->consts()->size(); i++) output_object(codeObj->consts()->get(i), mod, indent + 2); } iprintf(indent + 1, "[Disassembly]\n"); bc_disasm(codeObj, mod, indent + 2); } break; case PycObject::TYPE_STRING: iprintf(indent, ""); OutputString(obj.cast<PycString>(), (mod->majorVer() == 3) ? 'b' : 0); fprintf(pyc_output, "\n"); break; case PycObject::TYPE_UNICODE: iprintf(indent, ""); OutputString(obj.cast<PycString>(), (mod->majorVer() == 3) ? 0 : 'u'); fprintf(pyc_output, "\n"); break; case PycObject::TYPE_STRINGREF: case PycObject::TYPE_INTERNED: case PycObject::TYPE_ASCII: case PycObject::TYPE_ASCII_INTERNED: case PycObject::TYPE_SHORT_ASCII: case PycObject::TYPE_SHORT_ASCII_INTERNED: iprintf(indent, ""); OutputString(obj.cast<PycString>(), 0); fprintf(pyc_output, "\n"); break; case PycObject::TYPE_TUPLE: case PycObject::TYPE_SMALL_TUPLE: { iprintf(indent, "(\n"); PycTuple::value_t values = obj.cast<PycTuple>()->values(); for (PycTuple::value_t::const_iterator i = values.begin(); i != values.end(); i++) output_object(*i, mod, indent + 1); iprintf(indent, ")\n"); } break; case PycObject::TYPE_LIST: { iprintf(indent, "[\n"); PycList::value_t values = obj.cast<PycList>()->values(); for (PycList::value_t::const_iterator i = values.begin(); i != values.end(); i++) output_object(*i, mod, indent + 1); iprintf(indent, "]\n"); } break; case PycObject::TYPE_DICT: { iprintf(indent, "{\n"); PycDict::key_t keys = obj.cast<PycDict>()->keys(); PycDict::value_t values = obj.cast<PycDict>()->values(); PycDict::key_t::const_iterator ki = keys.begin(); PycDict::value_t::const_iterator vi = values.begin(); while (ki != keys.end()) { output_object(*ki, mod, indent + 1); output_object(*vi, mod, indent + 2); ++ki, ++vi; } iprintf(indent, "}\n"); } break; case PycObject::TYPE_SET: { iprintf(indent, "{\n"); PycSet::value_t values = obj.cast<PycSet>()->values(); for (PycSet::value_t::const_iterator i = values.begin(); i != values.end(); i++) output_object(*i, mod, indent + 1); iprintf(indent, "}\n"); } break; case PycObject::TYPE_NONE: iprintf(indent, "None\n"); break; case PycObject::TYPE_FALSE: iprintf(indent, "False\n"); break; case PycObject::TYPE_TRUE: iprintf(indent, "True\n"); break; case PycObject::TYPE_ELLIPSIS: iprintf(indent, "...\n"); break; case PycObject::TYPE_INT: iprintf(indent, "%d\n", obj.cast<PycInt>()->value()); break; case PycObject::TYPE_LONG: iprintf(indent, "%s\n", obj.cast<PycLong>()->repr().c_str()); break; case PycObject::TYPE_FLOAT: iprintf(indent, "%s\n", obj.cast<PycFloat>()->value()); break; case PycObject::TYPE_COMPLEX: iprintf(indent, "(%s+%sj)\n", obj.cast<PycComplex>()->value(), obj.cast<PycComplex>()->imag()); break; case PycObject::TYPE_BINARY_FLOAT: iprintf(indent, "%g\n", obj.cast<PycCFloat>()->value()); break; case PycObject::TYPE_BINARY_COMPLEX: iprintf(indent, "(%g+%gj)\n", obj.cast<PycCComplex>()->value(), obj.cast<PycCComplex>()->imag()); break; default: iprintf(indent, "<TYPE: %d>\n", obj->type()); } }