+ // Skip leading white space.
+ for (; characters < endCharacters; ++characters) {
+ if (!isStrWhiteSpace(*characters))
+ break;
+ }
+
+ // Empty string.
+ if (characters == endCharacters)
+ return 0.0;
+
+ double number;
+ if (characters[0] == '0' && characters + 2 < endCharacters) {
+ if ((characters[1] | 0x20) == 'x' && isASCIIHexDigit(characters[2]))
+ number = jsHexIntegerLiteral(characters, endCharacters);
+ else if ((characters[1] | 0x20) == 'o' && isASCIIOctalDigit(characters[2]))
+ number = jsOctalIntegerLiteral(characters, endCharacters);
+ else if ((characters[1] | 0x20) == 'b' && isASCIIBinaryDigit(characters[2]))
+ number = jsBinaryIntegerLiteral(characters, endCharacters);
+ else
+ number = jsStrDecimalLiteral(characters, endCharacters);
+ } else
+ number = jsStrDecimalLiteral(characters, endCharacters);
+
+ // Allow trailing white space.
+ for (; characters < endCharacters; ++characters) {
+ if (!isStrWhiteSpace(*characters))
+ break;
+ }
+ if (characters != endCharacters)
+ return PNaN;
+
+ return number;
+}
+
+// See ecma-262 6th 11.8.3
+double jsToNumber(StringView s)
+{
+ unsigned size = s.length();
+
+ if (size == 1) {
+ UChar c = s[0];
+ if (isASCIIDigit(c))
+ return c - '0';
+ if (isStrWhiteSpace(c))
+ return 0;
+ return PNaN;
+ }
+
+ if (s.is8Bit())
+ return toDouble(s.characters8(), size);
+ return toDouble(s.characters16(), size);
+}
+
+static double parseFloat(StringView s)
+{
+ unsigned size = s.length();
+
+ if (size == 1) {
+ UChar c = s[0];
+ if (isASCIIDigit(c))
+ return c - '0';
+ return PNaN;
+ }
+
+ if (s.is8Bit()) {
+ const LChar* data = s.characters8();
+ const LChar* end = data + size;
+
+ // Skip leading white space.
+ for (; data < end; ++data) {
+ if (!isStrWhiteSpace(*data))
+ break;
+ }
+
+ // Empty string.
+ if (data == end)
+ return PNaN;
+
+ return jsStrDecimalLiteral(data, end);
+ }
+
+ const UChar* data = s.characters16();
+ const UChar* end = data + size;
+
+ // Skip leading white space.
+ for (; data < end; ++data) {
+ if (!isStrWhiteSpace(*data))
+ break;
+ }
+
+ // Empty string.
+ if (data == end)
+ return PNaN;
+
+ return jsStrDecimalLiteral(data, end);
+}
+
+EncodedJSValue JSC_HOST_CALL globalFuncEval(ExecState* exec)
+{
+ JSValue x = exec->argument(0);
+ if (!x.isString())
+ return JSValue::encode(x);
+
+ String s = x.toString(exec)->value(exec);
+
+ if (s.is8Bit()) {
+ LiteralParser<LChar> preparser(exec, s.characters8(), s.length(), NonStrictJSON);
+ if (JSValue parsedObject = preparser.tryLiteralParse())
+ return JSValue::encode(parsedObject);
+ } else {
+ LiteralParser<UChar> preparser(exec, s.characters16(), s.length(), NonStrictJSON);
+ if (JSValue parsedObject = preparser.tryLiteralParse())
+ return JSValue::encode(parsedObject);
+ }