RawObject Marshal::Reader::readObject()

in runtime/marshal.cpp [139:255]


RawObject Marshal::Reader::readObject() {
  byte code = readByte();
  byte flag = code & FLAG_REF;
  byte type = code & ~FLAG_REF;
  isRef_ = flag;
  switch (type) {
    case TYPE_NULL:
      return SmallInt::fromWord(0);

    case TYPE_NONE:
      return NoneType::object();

    case TYPE_STOPITER:
      UNIMPLEMENTED("TYPE_STOPITER");

    case TYPE_ELLIPSIS:
      return runtime_->ellipsis();

    case TYPE_FALSE:
      return Bool::falseObj();

    case TYPE_TRUE:
      return Bool::trueObj();

    case TYPE_INT: {
      // NB: this will continue to work as long as SmallInt can contain the
      // full range of 32 bit signed integer values. Notably, this will break if
      // we need to support 32 bit machines.
      word n = readLong();
      if (!SmallInt::isValid(n)) {
        UNIMPLEMENTED("value '%ld' outside range supported by RawSmallInt", n);
      }
      HandleScope scope(thread_);
      Object result(&scope, SmallInt::fromWord(n));
      if (isRef_) {
        addRef(result);
      }
      return *result;
    }

    case TYPE_FLOAT:
      UNIMPLEMENTED("TYPE_FLOAT");

    case TYPE_BINARY_FLOAT: {
      double n = readBinaryFloat();
      HandleScope scope(thread_);
      Object result(&scope, runtime_->newFloat(n));
      if (isRef_) {
        addRef(result);
      }
      return *result;
    }

    case TYPE_COMPLEX:
      UNIMPLEMENTED("TYPE_COMPLEX");

    case TYPE_BINARY_COMPLEX: {
      double real = readBinaryFloat();
      double imag = readBinaryFloat();
      HandleScope scope(thread_);
      Object result(&scope, runtime_->newComplex(real, imag));
      if (isRef_) {
        addRef(result);
      }
      return *result;
    }

    case TYPE_STRING:  // Misnomer, should be TYPE_BYTES
      return readTypeString();

    case TYPE_INTERNED:
    case TYPE_ASCII_INTERNED:
      return readTypeAsciiInterned();

    case TYPE_UNICODE:
    case TYPE_ASCII: {
      return readTypeAscii();
    }

    case TYPE_SHORT_ASCII_INTERNED:
      return readTypeShortAsciiInterned();

    case TYPE_SHORT_ASCII:
      return readTypeShortAscii();

    case TYPE_SMALL_TUPLE:
      return readTypeSmallTuple();

    case TYPE_TUPLE:
      return readTypeTuple();

    case TYPE_LIST:
      UNIMPLEMENTED("TYPE_LIST");

    case TYPE_DICT:
      UNIMPLEMENTED("TYPE_DICT");

    case TYPE_SET:
      return readTypeSet();

    case TYPE_FROZENSET:
      return readTypeFrozenSet();

    case TYPE_CODE:
      return readTypeCode();

    case TYPE_REF:
      return readTypeRef();

    case TYPE_LONG:
      return readLongObject();

    default:
      UNREACHABLE("unknown type '%c' (flags=%x)", type, flag);
  }
  UNREACHABLE("all cases should be covered");
}