+ if (string.isNull())
+ return nullptr;
+
+ return adoptRef(new OpaqueJSString(string));
+}
+
+OpaqueJSString::~OpaqueJSString()
+{
+ // m_characters is put in a local here to avoid an extra atomic load.
+ UChar* characters = m_characters;
+ if (!characters)
+ return;
+
+ if (!m_string.is8Bit() && m_string.characters16() == characters)
+ return;
+
+ fastFree(characters);
+}
+
+String OpaqueJSString::string() const
+{
+ // Return a copy of the wrapped string, because the caller may make it an Identifier.
+ return m_string.isolatedCopy();
+}
+
+Identifier OpaqueJSString::identifier(VM* vm) const
+{
+ if (m_string.isNull())
+ return Identifier();
+
+ if (m_string.isEmpty())
+ return Identifier(Identifier::EmptyIdentifier);
+
+ if (m_string.is8Bit())
+ return Identifier::fromString(vm, m_string.characters8(), m_string.length());
+
+ return Identifier::fromString(vm, m_string.characters16(), m_string.length());