int IndexFreeListKey::compare(const IndexFreeListKey& other) { ASSERT(m_objectStoreId >= 0); ASSERT(m_indexId >= 0); if (int x = compareInts(m_objectStoreId, other.m_objectStoreId)) return x; return compareInts(m_indexId, other.m_indexId); }
int IndexMetaDataKey::compare(const IndexMetaDataKey& other) { ASSERT(m_objectStoreId >= 0); ASSERT(m_indexId >= 0); if (int x = compareInts(m_objectStoreId, other.m_objectStoreId)) return x; if (int x = compareInts(m_indexId, other.m_indexId)) return x; return m_metaDataType - other.m_metaDataType; }
int KeyPrefix::compare(const KeyPrefix& other) const { ASSERT(m_databaseId != InvalidId); ASSERT(m_objectStoreId != InvalidId); ASSERT(m_indexId != InvalidId); if (m_databaseId != other.m_databaseId) return compareInts(m_databaseId, other.m_databaseId); if (m_objectStoreId != other.m_objectStoreId) return compareInts(m_objectStoreId, other.m_objectStoreId); if (m_indexId != other.m_indexId) return compareInts(m_indexId, other.m_indexId); return 0; }
int IndexNamesKey::compare(const IndexNamesKey& other) { ASSERT(m_objectStoreId >= 0); if (int x = compareInts(m_objectStoreId, other.m_objectStoreId)) return x; return codePointCompare(m_indexName, other.m_indexName); }
int ObjectStoreFreeListKey::compare(const ObjectStoreFreeListKey& other) { // FIXME: It may seem strange that we're not comparing database id's, // but that comparison will have been made earlier. // We should probably make this more clear, though... ASSERT(m_objectStoreId >= 0); return compareInts(m_objectStoreId, other.m_objectStoreId); }
int ObjectStoreMetaDataKey::compare(const ObjectStoreMetaDataKey& other) { ASSERT(m_objectStoreId >= 0); ASSERT(m_metaDataType >= 0); if (int x = compareInts(m_objectStoreId, other.m_objectStoreId)) return x; int64_t result = m_metaDataType - other.m_metaDataType; if (result < 0) return -1; return (result > 0) ? 1 : result; }
int IndexDataKey::compare(const IndexDataKey& other, bool ignoreDuplicates) { ASSERT(m_databaseId >= 0); ASSERT(m_objectStoreId >= 0); ASSERT(m_indexId >= 0); if (int x = compareEncodedIDBKeys(m_encodedUserKey, other.m_encodedUserKey)) return x; if (ignoreDuplicates) return 0; if (int x = compareEncodedIDBKeys(m_encodedPrimaryKey, other.m_encodedPrimaryKey)) return x; return compareInts(m_sequenceNumber, other.m_sequenceNumber); }
int DatabaseFreeListKey::compare(const DatabaseFreeListKey& other) const { ASSERT(m_databaseId >= 0); return compareInts(m_databaseId, other.m_databaseId); }
int BSONElement::compareElements(const BSONElement& l, const BSONElement& r, ComparisonRulesSet rules, const StringData::ComparatorInterface* comparator) { switch (l.type()) { case BSONType::EOO: case BSONType::Undefined: // EOO and Undefined are same canonicalType case BSONType::jstNULL: case BSONType::MaxKey: case BSONType::MinKey: { auto f = l.canonicalType() - r.canonicalType(); if (f < 0) return -1; return f == 0 ? 0 : 1; } case BSONType::Bool: return *l.value() - *r.value(); case BSONType::bsonTimestamp: // unsigned compare for timestamps - note they are not really dates but (ordinal + // time_t) if (l.timestamp() < r.timestamp()) return -1; return l.timestamp() == r.timestamp() ? 0 : 1; case BSONType::Date: // Signed comparisons for Dates. { const Date_t a = l.Date(); const Date_t b = r.Date(); if (a < b) return -1; return a == b ? 0 : 1; } case BSONType::NumberInt: { // All types can precisely represent all NumberInts, so it is safe to simply convert to // whatever rhs's type is. switch (r.type()) { case NumberInt: return compareInts(l._numberInt(), r._numberInt()); case NumberLong: return compareLongs(l._numberInt(), r._numberLong()); case NumberDouble: return compareDoubles(l._numberInt(), r._numberDouble()); case NumberDecimal: return compareIntToDecimal(l._numberInt(), r._numberDecimal()); default: MONGO_UNREACHABLE; } } case BSONType::NumberLong: { switch (r.type()) { case NumberLong: return compareLongs(l._numberLong(), r._numberLong()); case NumberInt: return compareLongs(l._numberLong(), r._numberInt()); case NumberDouble: return compareLongToDouble(l._numberLong(), r._numberDouble()); case NumberDecimal: return compareLongToDecimal(l._numberLong(), r._numberDecimal()); default: MONGO_UNREACHABLE; } } case BSONType::NumberDouble: { switch (r.type()) { case NumberDouble: return compareDoubles(l._numberDouble(), r._numberDouble()); case NumberInt: return compareDoubles(l._numberDouble(), r._numberInt()); case NumberLong: return compareDoubleToLong(l._numberDouble(), r._numberLong()); case NumberDecimal: return compareDoubleToDecimal(l._numberDouble(), r._numberDecimal()); default: MONGO_UNREACHABLE; } } case BSONType::NumberDecimal: { switch (r.type()) { case NumberDecimal: return compareDecimals(l._numberDecimal(), r._numberDecimal()); case NumberInt: return compareDecimalToInt(l._numberDecimal(), r._numberInt()); case NumberLong: return compareDecimalToLong(l._numberDecimal(), r._numberLong()); case NumberDouble: return compareDecimalToDouble(l._numberDecimal(), r._numberDouble()); default: MONGO_UNREACHABLE; } } case BSONType::jstOID: return memcmp(l.value(), r.value(), OID::kOIDSize); case BSONType::Code: return compareElementStringValues(l, r); case BSONType::Symbol: case BSONType::String: { if (comparator) { return comparator->compare(l.valueStringData(), r.valueStringData()); } else { return compareElementStringValues(l, r); } } case BSONType::Object: case BSONType::Array: { return l.embeddedObject().woCompare( r.embeddedObject(), BSONObj(), rules | BSONElement::ComparisonRules::kConsiderFieldName, comparator); } case BSONType::DBRef: { int lsz = l.valuesize(); int rsz = r.valuesize(); if (lsz - rsz != 0) return lsz - rsz; return memcmp(l.value(), r.value(), lsz); } case BSONType::BinData: { int lsz = l.objsize(); // our bin data size in bytes, not including the subtype byte int rsz = r.objsize(); if (lsz - rsz != 0) return lsz - rsz; return memcmp(l.value() + 4, r.value() + 4, lsz + 1 /*+1 for subtype byte*/); } case BSONType::RegEx: { int c = strcmp(l.regex(), r.regex()); if (c) return c; return strcmp(l.regexFlags(), r.regexFlags()); } case BSONType::CodeWScope: { int cmp = StringData(l.codeWScopeCode(), l.codeWScopeCodeLen() - 1) .compare(StringData(r.codeWScopeCode(), r.codeWScopeCodeLen() - 1)); if (cmp) return cmp; // When comparing the scope object, we should consider field names. Special string // comparison semantics do not apply to strings nested inside the CodeWScope scope // object, so we do not pass through the string comparator. return l.codeWScopeObject().woCompare( r.codeWScopeObject(), BSONObj(), rules | BSONElement::ComparisonRules::kConsiderFieldName); } } MONGO_UNREACHABLE; }
void Interpreter::executeFun(uint16_t id) { _bc = ((BytecodeFunction*)_code->functionById(id))->bytecode(); _insPtr = 0; Instruction inst; while (true) { inst = nextInsn(); //cout << "Current instruction " << inst << endl; //cout << "__STACK:" << endl; //printStack(); switch (inst) { case BC_INVALID: _out << inst << " Invalid instruction" << endl; assert(false); break; case BC_DLOAD: loadDouble(); break; case BC_ILOAD: loadInt(); break; case BC_SLOAD: loadString(); break; case BC_DLOAD0: _out << inst << " Not implemented" << endl; assert(false); break; case BC_ILOAD0: pushInt(0); break; case BC_SLOAD0: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_DLOAD1: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_ILOAD1: pushInt(1); break; case BC_DLOADM1: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_ILOADM1: pushInt(-1); break; case BC_DADD: addDoubles(); break; case BC_IADD: addInts(); break; case BC_DSUB: subDoubles(); break; case BC_ISUB: subInts(); break; case BC_DMUL: dMul(); break; case BC_IMUL: iMul(); break; case BC_DDIV: divDoubles(); break; case BC_IDIV: divInts(); break; case BC_IMOD: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_DNEG: dNeg(); break; case BC_INEG: iNeg(); break; case BC_IPRINT: printInt(); break; case BC_DPRINT: printDouble(); break; case BC_SPRINT: printString(); break; case BC_I2D: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_D2I: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_S2I: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_SWAP: swap(); break; case BC_POP: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_LOADDVAR0: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_LOADDVAR1: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_LOADDVAR2: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_LOADDVAR3: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_LOADIVAR0: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_LOADIVAR1: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_LOADIVAR2: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_LOADIVAR3: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_LOADSVAR0: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_LOADSVAR1: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_LOADSVAR2: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_LOADSVAR3: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_STOREDVAR0: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_STOREDVAR1: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_STOREDVAR2: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_STOREDVAR3: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_STOREIVAR0: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_STOREIVAR1: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_STOREIVAR2: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_STOREIVAR3: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_STORESVAR0: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_STORESVAR1: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_STORESVAR2: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_STORESVAR3: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_LOADDVAR: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_LOADIVAR: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_LOADSVAR: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_STOREDVAR: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_STOREIVAR: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_STORESVAR: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_LOADCTXDVAR: loadCtxDouble(); break; case BC_LOADCTXIVAR: loadCtxInt(); break; case BC_LOADCTXSVAR: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_STORECTXDVAR: storeCtxDouble(); break; case BC_STORECTXIVAR: storeCtxInt(); break; case BC_STORECTXSVAR: _out << inst << " STORE STRING ? Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_DCMP: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_ICMP: compareInts(); break; case BC_JA: jumpAlways(); break; case BC_IFICMPNE: intsNotEqualJMP(); break; case BC_IFICMPE: intsEqualJMP(); break; case BC_IFICMPG: GJump(); break; case BC_IFICMPGE: GEJump(); break; case BC_IFICMPL: //cout << "IFLESS" << endl; assert(false); break; case BC_IFICMPLE: LEJump(); break; case BC_DUMP: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_STOP: this->popContext(); return; case BC_CALL: //cout << "CALLING. STACK SIZE: " << _stack.size() << endl; call(); break; case BC_CALLNATIVE: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; case BC_RETURN: doReturn(); break; case BC_BREAK: _out << inst << " Not implemented" << endl; exit(EXIT_FAILURE); break; default: _out << "Bad instruction" << endl; break; } } this->popContext(); }
void BytecodeGenerationVisitor::compareDoubles(Instruction insn) { bytecode -> addInsn(BC_DCMP); bytecode -> addInsn(BC_ILOAD0); compareInts(insn); }
void BytecodeGenerationVisitor::visitBinaryOpNode(BinaryOpNode* node) { node -> right() -> visit(this); VarType secondType = currentType; node -> left() -> visit(this); VarType firstType = currentType; VarType commonType; if (secondType == firstType && (firstType == VT_INT || firstType == VT_DOUBLE)) { commonType = firstType; } else if (firstType == VT_DOUBLE && secondType == VT_INT) { bytecode -> addInsn(BC_SWAP); bytecode -> addInsn(BC_I2D); bytecode -> addInsn(BC_SWAP); commonType = VT_DOUBLE; } else if (secondType == VT_DOUBLE && firstType == VT_INT) { bytecode -> addInsn(BC_I2D); commonType = VT_DOUBLE; } else { throw std::exception(); } TokenKind op = node -> kind(); switch (op) { case tRANGE: if (commonType == VT_INT) { currentType = VT_VOID; return; } else { throw std::exception(); } case tADD: case tSUB: case tMUL: case tDIV: case tMOD: { if (insnByToken[commonType].find(op) == insnByToken[commonType].end()) { throw std::exception(); } Instruction ins = insnByToken[commonType][op]; bytecode -> addInsn(ins); currentType = commonType; break; } case tAND: if (commonType != VT_INT) { throw std::exception(); } AND(); currentType = VT_INT; break; case tOR: if (commonType != VT_INT) { throw std::exception(); } OR(); currentType = VT_INT; break; case tEQ: case tNEQ: case tGT: case tGE: case tLT: case tLE: if (commonType == VT_INT) { compareInts(insnByToken[VT_INT][op]); } else if (commonType == VT_DOUBLE) { compareDoubles(insnByToken[VT_INT][op]); } currentType = VT_INT; break; default: throw std::exception(); } }