+// 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);
+ }
+
+ JSGlobalObject* calleeGlobalObject = exec->callee()->globalObject();
+ EvalExecutable* eval = EvalExecutable::create(exec, makeSource(s), false, ThisTDZMode::CheckIfNeeded);
+ if (!eval)
+ return JSValue::encode(jsUndefined());
+
+ return JSValue::encode(exec->interpreter()->execute(eval, exec, calleeGlobalObject->globalThis(), calleeGlobalObject));
+}
+
+EncodedJSValue JSC_HOST_CALL globalFuncParseInt(ExecState* exec)
+{
+ JSValue value = exec->argument(0);
+ JSValue radixValue = exec->argument(1);
+
+ // Optimized handling for numbers:
+ // If the argument is 0 or a number in range 10^-6 <= n < INT_MAX+1, then parseInt
+ // results in a truncation to integer. In the case of -0, this is converted to 0.
+ //
+ // This is also a truncation for values in the range INT_MAX+1 <= n < 10^21,
+ // however these values cannot be trivially truncated to int since 10^21 exceeds
+ // even the int64_t range. Negative numbers are a little trickier, the case for
+ // values in the range -10^21 < n <= -1 are similar to those for integer, but
+ // values in the range -1 < n <= -10^-6 need to truncate to -0, not 0.
+ static const double tenToTheMinus6 = 0.000001;
+ static const double intMaxPlusOne = 2147483648.0;
+ if (value.isNumber()) {
+ double n = value.asNumber();
+ if (((n < intMaxPlusOne && n >= tenToTheMinus6) || !n) && radixValue.isUndefinedOrNull())
+ return JSValue::encode(jsNumber(static_cast<int32_t>(n)));
+ }
+
+ // If ToString throws, we shouldn't call ToInt32.
+ StringView s = value.toString(exec)->view(exec);
+ if (exec->hadException())
+ return JSValue::encode(jsUndefined());
+
+ return JSValue::encode(jsNumber(parseInt(s, radixValue.toInt32(exec))));