--- a/js/src/frontend/BinSource.cpp
+++ b/js/src/frontend/BinSource.cpp
@@ -2505,16 +2505,29 @@ ASTReader::readString(SimpleTokenReader*
if (!reader->readMaybeString(&out)) {
return false;
}
return true;
}
+bool
+ASTReader::readString(SimpleTokenReader* reader, Maybe<std::u16string>& out) {
+ if (out) {
+ return this->raiseError();
+ }
+
+ if (!reader->readMaybeString(&out)) {
+ return false;
+ }
+
+ return true;
+}
+
bool
ASTReader::readNumber(SimpleTokenReader* reader, Maybe<double>& out) {
if (out) {
return this->raiseError();
}
return reader->readMaybeF64(&out);
--- a/js/src/frontend/BinTokenReader.cpp
+++ b/js/src/frontend/BinTokenReader.cpp
@@ -190,31 +190,87 @@ SimpleTokenReader::readMaybeString(Maybe
std::string string(this->current, byteLen);
// FIXME: Should be faillible.
if (!this->readConst("</string>")) {
return false;
}
return true;
}
+
bool
SimpleTokenReader::readString(std::string* result) {
Maybe<std::string> maybe;
if (!this->readMaybeString(&maybe)) {
return false;
}
if (!maybe) {
return false;
}
maybe->swap(*result);
return true;
}
+bool
+SimpleTokenReader::readMaybeString(Maybe<std::u16string>* result) {
+ MOZ_ASSERT(initialized);
+ if (!this->readConst("<string>")) {
+ return false;
+ }
+
+ // 1. Read byteLength
+ uint32_t byteLen;
+ if (!this->readInternalUint32(&byteLen)) {
+ return false;
+ }
+
+ // 2. Reject if we can't read
+ if (this->current + byteLen > this->stop) {
+ this->raiseError();
+ return false;
+ }
+ if (byteLen % sizeof(char16_t) != 0) {
+ this->raiseError();
+ return false;
+ }
+
+ // 3. Check null string (no allocation)
+ if (byteLen == 2 && *current == -1 && *(current + 1) == 0) {
+ // Special case: null string.
+ result = nullptr;
+ return true;
+ }
+
+ // 4. Other strings (bytes are copied)
+ std::u16string string((const char16_t*)this->current, byteLen / sizeof(char16_t));
+ // FIXME: Should be faillible.
+ if (!this->readConst("</string>")) {
+ return false;
+ }
+
+ return true;
+}
+
+bool
+SimpleTokenReader::readString(std::u16string* result) {
+ Maybe<std::u16string> maybe;
+ if (!this->readMaybeString(&maybe)) {
+ return false;
+ }
+
+ if (!maybe) {
+ return false;
+ }
+
+ maybe->swap(*result);
+ return true;
+}
+
// Tagged tuples:
// - "<tuple>"
// - "<head>"
// - non-null string `name` (see `readString()`);
// - uint32_t number of fields;
// - array of `number of fields` non-null strings (see `readString()`);
// - "</head>"
// - content (specified by the higher-level grammar);
--- a/js/src/frontend/BinTokenReader.h
+++ b/js/src/frontend/BinTokenReader.h
@@ -241,26 +241,28 @@ public:
* Otherwise, `Some(x)`, where `x` is a `string`.
*
* WARNING: At this stage, the `string` encoding has NOT been validated.
*
* @return false If a string could not be read. In this case, an error
* has been raised.
*/
bool readMaybeString(Maybe<std::string>* out);
+ bool readMaybeString(Maybe<std::u16string>* out);
/**
* Read a single `string` value.
*
* WARNING: At this stage, the `string` encoding has NOT been validated.
*
* @return false If a string could not be read or if the value was `null`.
* In this case, an error has been raised.
*/
bool readString(std::string*);
+ bool readString(std::u16string*);
// --- Composite values.
//
// The underlying format does NOT allows for a `null` composite value.
//
// Reading a composite value returns a sub-`TokenReader` dedicated to
// the value.
//