diff --git a/include/hermes/VM/PrimitiveBox.h b/include/hermes/VM/PrimitiveBox.h index deeb5c42fd7..a8f2564523a 100644 --- a/include/hermes/VM/PrimitiveBox.h +++ b/include/hermes/VM/PrimitiveBox.h @@ -300,7 +300,9 @@ class JSBoolean final : public JSObject { }; /// Symbol object. -class JSSymbol final : public PrimitiveBox { +class JSSymbol final : public JSObject { + friend void SymbolObjectBuildMeta(const GCCell *cell, Metadata::Builder &mb); + public: static const ObjectVTable vt; @@ -317,19 +319,24 @@ class JSSymbol final : public PrimitiveBox { return create(runtime, SymbolID{}, prototype); } - /// Return the [[PrimitiveValue]] internal property as a string. - static const PseudoHandle getPrimitiveSymbol(JSObject *self) { - return PseudoHandle::create(getPrimitiveValue(self).getSymbol()); + /// Return the [[PrimitiveValue]] internal property as a SymbolID. + PseudoHandle getPrimitiveSymbol() const { + return PseudoHandle::create(primitiveValue_); } #ifdef HERMESVM_SERIALIZE explicit JSSymbol(Deserializer &d); - - friend void SymbolObjectDeserialize(Deserializer &d, CellKind kind); #endif - JSSymbol(Runtime *runtime, Handle parent, Handle clazz) - : PrimitiveBox(runtime, &vt.base, *parent, *clazz) {} + JSSymbol( + Runtime *runtime, + SymbolID value, + Handle parent, + Handle clazz) + : JSObject(runtime, &vt.base, *parent, *clazz), primitiveValue_(value) {} + + private: + const GCSymbolID primitiveValue_; }; } // namespace vm diff --git a/lib/VM/JSLib/Symbol.cpp b/lib/VM/JSLib/Symbol.cpp index dab8660cbae..af6c7dac9af 100644 --- a/lib/VM/JSLib/Symbol.cpp +++ b/lib/VM/JSLib/Symbol.cpp @@ -242,7 +242,7 @@ symbolPrototypeDescriptionGetter(void *, Runtime *runtime, NativeArgs args) { if (args.getThisArg().isSymbol()) { sym = args.vmcastThis().get(); } else if (auto symHandle = args.dyncastThis()) { - sym = JSSymbol::getPrimitiveSymbol(*symHandle).get(); + sym = symHandle->getPrimitiveSymbol(); } else { return runtime->raiseTypeError( "Symbol.prototype.description can only be called on Symbol"); @@ -261,7 +261,7 @@ symbolPrototypeToString(void *, Runtime *runtime, NativeArgs args) { if (args.getThisArg().isSymbol()) { sym = args.vmcastThis().get(); } else if (auto symHandle = args.dyncastThis()) { - sym = JSSymbol::getPrimitiveSymbol(*symHandle).get(); + sym = symHandle->getPrimitiveSymbol(); } else { return runtime->raiseTypeError( "Symbol.prototype.toString can only be called on Symbol"); @@ -283,7 +283,7 @@ symbolPrototypeValueOf(void *, Runtime *runtime, NativeArgs args) { return args.getThisArg(); } if (auto jsSymbol = args.dyncastThis()) { - return JSSymbol::getPrimitiveSymbol(*jsSymbol).getHermesValue(); + return jsSymbol->getPrimitiveSymbol().getHermesValue(); } return runtime->raiseTypeError( "Symbol.prototype.valueOf can only be called on Symbol"); diff --git a/lib/VM/PrimitiveBox.cpp b/lib/VM/PrimitiveBox.cpp index 0b59f277485..05d2bb65d93 100644 --- a/lib/VM/PrimitiveBox.cpp +++ b/lib/VM/PrimitiveBox.cpp @@ -425,14 +425,20 @@ const ObjectVTable JSSymbol::vt{ void SymbolObjectBuildMeta(const GCCell *cell, Metadata::Builder &mb) { mb.addJSObjectOverlapSlots(JSObject::numOverlapSlots()); ObjectBuildMeta(cell, mb); + const auto *self = static_cast(cell); mb.setVTable(&JSSymbol::vt.base); + mb.addField(&self->primitiveValue_); } #ifdef HERMESVM_SERIALIZE -JSSymbol::JSSymbol(Deserializer &d) : PrimitiveBox(d, &vt.base) {} +JSSymbol::JSSymbol(Deserializer &d) + : JSObject(d, &vt.base), + primitiveValue_(SymbolID::unsafeCreate(d.readInt())) {} void SymbolObjectSerialize(Serializer &s, const GCCell *cell) { JSObject::serializeObjectImpl(s, cell, JSObject::numOverlapSlots()); + const auto *self = static_cast(cell); + s.writeInt(self->getPrimitiveSymbol().get().unsafeGetRaw()); s.endObject(cell); } @@ -449,15 +455,9 @@ PseudoHandle JSSymbol::create( Handle parentHandle) { auto clazzHandle = runtime->getHiddenClassForPrototype( *parentHandle, numOverlapSlots() + ANONYMOUS_PROPERTY_SLOTS); - auto *obj = runtime->makeAFixed(runtime, parentHandle, clazzHandle); - auto self = JSObjectInit::initToPseudoHandle(runtime, obj); - - JSObject::setDirectSlotValue( - self.get(), - SmallHermesValue::encodeSymbolValue(value), - &runtime->getHeap()); - - return self; + auto *obj = + runtime->makeAFixed(runtime, value, parentHandle, clazzHandle); + return JSObjectInit::initToPseudoHandle(runtime, obj); } } // namespace vm