diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2016-04-10 09:28:39 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2016-04-10 09:28:39 +0000 |
commit | 32761a6cee1d0dee366b885b7b9c777e67885688 (patch) | |
tree | d6bec92bebfb216f4126356e55518842c2f476a1 /Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp | |
parent | a4e969f4965059196ca948db781e52f7cfebf19e (diff) | |
download | WebKitGtk-tarball-32761a6cee1d0dee366b885b7b9c777e67885688.tar.gz |
webkitgtk-2.4.11webkitgtk-2.4.11
Diffstat (limited to 'Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp')
-rw-r--r-- | Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp | 241 |
1 files changed, 76 insertions, 165 deletions
diff --git a/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp b/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp index ca5e4b31b..be9425ad3 100644 --- a/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp +++ b/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp @@ -26,6 +26,7 @@ #include "JSGlobalObjectFunctions.h" #include "CallFrame.h" +#include "CallFrameInlines.h" #include "Interpreter.h" #include "JSFunction.h" #include "JSGlobalObject.h" @@ -34,7 +35,7 @@ #include "Lexer.h" #include "LiteralParser.h" #include "Nodes.h" -#include "JSCInlines.h" +#include "Operations.h" #include "Parser.h" #include "StackVisitor.h" #include <wtf/dtoa.h> @@ -42,7 +43,6 @@ #include <stdlib.h> #include <wtf/ASCIICType.h> #include <wtf/Assertions.h> -#include <wtf/HexNumber.h> #include <wtf/MathExtras.h> #include <wtf/StringExtras.h> #include <wtf/text/StringBuilder.h> @@ -53,18 +53,9 @@ using namespace Unicode; namespace JSC { -template<unsigned charactersCount> -static Bitmap<256> makeCharacterBitmap(const char (&characters)[charactersCount]) +static JSValue encode(ExecState* exec, const char* doNotEscape) { - Bitmap<256> bitmap; - for (unsigned i = 0; i < charactersCount; ++i) - bitmap.set(characters[i]); - return bitmap; -} - -static JSValue encode(ExecState* exec, const Bitmap<256>& doNotEscape) -{ - CString cstr = exec->argument(0).toString(exec)->view(exec).get().utf8(StrictConversion); + CString cstr = exec->argument(0).toString(exec)->value(exec).utf8(StrictConversion); if (!cstr.data()) return exec->vm().throwException(exec, createURIError(exec, ASCIILiteral("String contained an illegal UTF-16 sequence."))); @@ -72,11 +63,12 @@ static JSValue encode(ExecState* exec, const Bitmap<256>& doNotEscape) const char* p = cstr.data(); for (size_t k = 0; k < cstr.length(); k++, p++) { char c = *p; - if (c && doNotEscape.get(static_cast<LChar>(c))) - builder.append(static_cast<LChar>(c)); + if (c && strchr(doNotEscape, c)) + builder.append(c); else { - builder.append(static_cast<LChar>('%')); - appendByteAsHex(c, builder); + char tmp[4]; + snprintf(tmp, sizeof(tmp), "%%%02X", static_cast<unsigned char>(c)); + builder.append(tmp); } } return builder.build(exec); @@ -84,7 +76,7 @@ static JSValue encode(ExecState* exec, const Bitmap<256>& doNotEscape) template <typename CharType> ALWAYS_INLINE -static JSValue decode(ExecState* exec, const CharType* characters, int length, const Bitmap<256>& doNotUnescape, bool strict) +static JSValue decode(ExecState* exec, const CharType* characters, int length, const char* doNotUnescape, bool strict) { JSStringBuilder builder; int k = 0; @@ -136,8 +128,11 @@ static JSValue decode(ExecState* exec, const CharType* characters, int length, c u = Lexer<UChar>::convertUnicode(p[2], p[3], p[4], p[5]); } } - if (charLen && (u == 0 || u >= 128 || !doNotUnescape.get(static_cast<LChar>(u)))) { - builder.append(u); + if (charLen && (u == 0 || u >= 128 || !strchr(doNotUnescape, u))) { + if (u < 256) + builder.append(static_cast<LChar>(u)); + else + builder.append(u); k += charLen; continue; } @@ -148,9 +143,10 @@ static JSValue decode(ExecState* exec, const CharType* characters, int length, c return builder.build(exec); } -static JSValue decode(ExecState* exec, const Bitmap<256>& doNotUnescape, bool strict) +static JSValue decode(ExecState* exec, const char* doNotUnescape, bool strict) { - JSString::SafeView str = exec->argument(0).toString(exec)->view(exec); + JSStringBuilder builder; + String str = exec->argument(0).toString(exec)->value(exec); if (str.is8Bit()) return decode(exec, str.characters8(), str.length(), doNotUnescape, strict); @@ -194,7 +190,7 @@ static int parseDigit(unsigned short c, int radix) return digit; } -double parseIntOverflow(const LChar* s, unsigned length, int radix) +double parseIntOverflow(const LChar* s, int length, int radix) { double number = 0.0; double radixMultiplier = 1.0; @@ -216,7 +212,7 @@ double parseIntOverflow(const LChar* s, unsigned length, int radix) return number; } -static double parseIntOverflow(const UChar* s, unsigned length, int radix) +double parseIntOverflow(const UChar* s, int length, int radix) { double number = 0.0; double radixMultiplier = 1.0; @@ -238,17 +234,10 @@ static double parseIntOverflow(const UChar* s, unsigned length, int radix) return number; } -static double parseIntOverflow(StringView string, int radix) -{ - if (string.is8Bit()) - return parseIntOverflow(string.characters8(), string.length(), radix); - return parseIntOverflow(string.characters16(), string.length(), radix); -} - // ES5.1 15.1.2.2 template <typename CharType> ALWAYS_INLINE -static double parseInt(StringView s, const CharType* data, int radix) +static double parseInt(const String& s, const CharType* data, int radix) { // 1. Let inputString be ToString(string). // 2. Let S be a newly created substring of inputString consisting of the first character that is not a @@ -291,7 +280,7 @@ static double parseInt(StringView s, const CharType* data, int radix) // 8.a If R < 2 or R > 36, then return NaN. if (radix < 2 || radix > 36) - return PNaN; + return QNaN; // 13. Let mathInt be the mathematical integer value that is represented by Z in radix-R notation, using the letters // A-Z and a-z for digits with values 10 through 35. (However, if R is 10 and Z contains more than 20 significant @@ -314,22 +303,22 @@ static double parseInt(StringView s, const CharType* data, int radix) // 12. If Z is empty, return NaN. if (!sawDigit) - return PNaN; + return QNaN; // Alternate code path for certain large numbers. if (number >= mantissaOverflowLowerBound) { if (radix == 10) { size_t parsedLength; - number = parseDouble(s.substring(firstDigitPosition, p - firstDigitPosition), parsedLength); + number = parseDouble(s.deprecatedCharacters() + firstDigitPosition, p - firstDigitPosition, parsedLength); } else if (radix == 2 || radix == 4 || radix == 8 || radix == 16 || radix == 32) - number = parseIntOverflow(s.substring(firstDigitPosition, p - firstDigitPosition), radix); + number = parseIntOverflow(s.substringSharingImpl(firstDigitPosition, p - firstDigitPosition).utf8().data(), p - firstDigitPosition, radix); } // 15. Return sign x number. return sign * number; } -static double parseInt(StringView s, int radix) +static double parseInt(const String& s, int radix) { if (s.is8Bit()) return parseInt(s, s.characters8(), radix); @@ -352,51 +341,7 @@ static bool isInfinity(const CharType* data, const CharType* end) && data[7] == 'y'; } -// See ecma-262 6th 11.8.3 -template <typename CharType> -static double jsBinaryIntegerLiteral(const CharType*& data, const CharType* end) -{ - // Binary number. - data += 2; - const CharType* firstDigitPosition = data; - double number = 0; - while (true) { - number = number * 2 + (*data - '0'); - ++data; - if (data == end) - break; - if (!isASCIIBinaryDigit(*data)) - break; - } - if (number >= mantissaOverflowLowerBound) - number = parseIntOverflow(firstDigitPosition, data - firstDigitPosition, 2); - - return number; -} - -// See ecma-262 6th 11.8.3 -template <typename CharType> -static double jsOctalIntegerLiteral(const CharType*& data, const CharType* end) -{ - // Octal number. - data += 2; - const CharType* firstDigitPosition = data; - double number = 0; - while (true) { - number = number * 8 + (*data - '0'); - ++data; - if (data == end) - break; - if (!isASCIIOctalDigit(*data)) - break; - } - if (number >= mantissaOverflowLowerBound) - number = parseIntOverflow(firstDigitPosition, data - firstDigitPosition, 8); - - return number; -} - -// See ecma-262 6th 11.8.3 +// See ecma-262 9.3.1 template <typename CharType> static double jsHexIntegerLiteral(const CharType*& data, const CharType* end) { @@ -418,7 +363,7 @@ static double jsHexIntegerLiteral(const CharType*& data, const CharType* end) return number; } -// See ecma-262 6th 11.8.3 +// See ecma-262 9.3.1 template <typename CharType> static double jsStrDecimalLiteral(const CharType*& data, const CharType* end) { @@ -456,7 +401,7 @@ static double jsStrDecimalLiteral(const CharType*& data, const CharType* end) } // Not a number. - return PNaN; + return QNaN; } template <typename CharType> @@ -475,16 +420,9 @@ static double toDouble(const CharType* characters, unsigned size) 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 + if (characters[0] == '0' && characters + 2 < endCharacters && (characters[1] | 0x20) == 'x' && isASCIIHexDigit(characters[2])) + number = jsHexIntegerLiteral(characters, endCharacters); + else number = jsStrDecimalLiteral(characters, endCharacters); // Allow trailing white space. @@ -493,13 +431,13 @@ static double toDouble(const CharType* characters, unsigned size) break; } if (characters != endCharacters) - return PNaN; + return QNaN; return number; } -// See ecma-262 6th 11.8.3 -double jsToNumber(StringView s) +// See ecma-262 9.3.1 +double jsToNumber(const String& s) { unsigned size = s.length(); @@ -509,7 +447,7 @@ double jsToNumber(StringView s) return c - '0'; if (isStrWhiteSpace(c)) return 0; - return PNaN; + return QNaN; } if (s.is8Bit()) @@ -517,7 +455,7 @@ double jsToNumber(StringView s) return toDouble(s.characters16(), size); } -static double parseFloat(StringView s) +static double parseFloat(const String& s) { unsigned size = s.length(); @@ -525,7 +463,7 @@ static double parseFloat(StringView s) UChar c = s[0]; if (isASCIIDigit(c)) return c - '0'; - return PNaN; + return QNaN; } if (s.is8Bit()) { @@ -540,7 +478,7 @@ static double parseFloat(StringView s) // Empty string. if (data == end) - return PNaN; + return QNaN; return jsStrDecimalLiteral(data, end); } @@ -556,7 +494,7 @@ static double parseFloat(StringView s) // Empty string. if (data == end) - return PNaN; + return QNaN; return jsStrDecimalLiteral(data, end); } @@ -567,15 +505,7 @@ EncodedJSValue JSC_HOST_CALL globalFuncEval(ExecState* exec) if (!x.isString()) return JSValue::encode(x); - JSGlobalObject* globalObject = exec->lexicalGlobalObject(); - if (!globalObject->evalEnabled()) { - exec->vm().throwException(exec, createEvalError(exec, globalObject->evalDisabledErrorMessage())); - return JSValue::encode(jsUndefined()); - } - String s = x.toString(exec)->value(exec); - if (exec->hadException()) - return JSValue::encode(jsUndefined()); if (s.is8Bit()) { LiteralParser<LChar> preparser(exec, s.characters8(), s.length(), NonStrictJSON); @@ -588,12 +518,11 @@ EncodedJSValue JSC_HOST_CALL globalFuncEval(ExecState* exec) } JSGlobalObject* calleeGlobalObject = exec->callee()->globalObject(); - VariableEnvironment emptyTDZVariables; // Indirect eval does not have access to the lexical scope. - EvalExecutable* eval = EvalExecutable::create(exec, makeSource(s), false, ThisTDZMode::CheckIfNeeded, DerivedContextType::None, false, &emptyTDZVariables); + EvalExecutable* eval = EvalExecutable::create(exec, makeSource(s), false); if (!eval) return JSValue::encode(jsUndefined()); - return JSValue::encode(exec->interpreter()->execute(eval, exec, calleeGlobalObject->globalThis(), calleeGlobalObject->globalScope())); + return JSValue::encode(exec->interpreter()->execute(eval, exec, calleeGlobalObject->globalThis(), calleeGlobalObject)); } EncodedJSValue JSC_HOST_CALL globalFuncParseInt(ExecState* exec) @@ -619,16 +548,16 @@ EncodedJSValue JSC_HOST_CALL globalFuncParseInt(ExecState* exec) } // If ToString throws, we shouldn't call ToInt32. - JSString::SafeView s = value.toString(exec)->view(exec); + String s = value.toString(exec)->value(exec); if (exec->hadException()) return JSValue::encode(jsUndefined()); - return JSValue::encode(jsNumber(parseInt(s.get(), radixValue.toInt32(exec)))); + return JSValue::encode(jsNumber(parseInt(s, radixValue.toInt32(exec)))); } EncodedJSValue JSC_HOST_CALL globalFuncParseFloat(ExecState* exec) { - return JSValue::encode(jsNumber(parseFloat(exec->argument(0).toString(exec)->view(exec).get()))); + return JSValue::encode(jsNumber(parseFloat(exec->argument(0).toString(exec)->value(exec)))); } EncodedJSValue JSC_HOST_CALL globalFuncIsNaN(ExecState* exec) @@ -644,63 +573,59 @@ EncodedJSValue JSC_HOST_CALL globalFuncIsFinite(ExecState* exec) EncodedJSValue JSC_HOST_CALL globalFuncDecodeURI(ExecState* exec) { - static Bitmap<256> doNotUnescapeWhenDecodingURI = makeCharacterBitmap( - "#$&+,/:;=?@" - ); + static const char do_not_unescape_when_decoding_URI[] = + "#$&+,/:;=?@"; - return JSValue::encode(decode(exec, doNotUnescapeWhenDecodingURI, true)); + return JSValue::encode(decode(exec, do_not_unescape_when_decoding_URI, true)); } EncodedJSValue JSC_HOST_CALL globalFuncDecodeURIComponent(ExecState* exec) { - static Bitmap<256> emptyBitmap; - return JSValue::encode(decode(exec, emptyBitmap, true)); + return JSValue::encode(decode(exec, "", true)); } EncodedJSValue JSC_HOST_CALL globalFuncEncodeURI(ExecState* exec) { - static Bitmap<256> doNotEscapeWhenEncodingURI = makeCharacterBitmap( + static const char do_not_escape_when_encoding_URI[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789" - "!#$&'()*+,-./:;=?@_~" - ); + "!#$&'()*+,-./:;=?@_~"; - return JSValue::encode(encode(exec, doNotEscapeWhenEncodingURI)); + return JSValue::encode(encode(exec, do_not_escape_when_encoding_URI)); } EncodedJSValue JSC_HOST_CALL globalFuncEncodeURIComponent(ExecState* exec) { - static Bitmap<256> doNotEscapeWhenEncodingURIComponent = makeCharacterBitmap( + static const char do_not_escape_when_encoding_URI_component[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789" - "!'()*-._~" - ); + "!'()*-._~"; - return JSValue::encode(encode(exec, doNotEscapeWhenEncodingURIComponent)); + return JSValue::encode(encode(exec, do_not_escape_when_encoding_URI_component)); } EncodedJSValue JSC_HOST_CALL globalFuncEscape(ExecState* exec) { - static Bitmap<256> doNotEscape = makeCharacterBitmap( + static const char do_not_escape[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789" - "*+-./@_" - ); + "*+-./@_"; JSStringBuilder builder; - JSString::SafeView str = exec->argument(0).toString(exec)->view(exec); + String str = exec->argument(0).toString(exec)->value(exec); if (str.is8Bit()) { const LChar* c = str.characters8(); for (unsigned k = 0; k < str.length(); k++, c++) { int u = c[0]; - if (u && doNotEscape.get(static_cast<LChar>(u))) - builder.append(*c); + if (u && strchr(do_not_escape, static_cast<char>(u))) + builder.append(c, 1); else { - builder.append(static_cast<LChar>('%')); - appendByteAsHex(static_cast<LChar>(u), builder); + char tmp[4]; + snprintf(tmp, sizeof(tmp), "%%%02X", u); + builder.append(tmp); } } @@ -711,15 +636,15 @@ EncodedJSValue JSC_HOST_CALL globalFuncEscape(ExecState* exec) for (unsigned k = 0; k < str.length(); k++, c++) { int u = c[0]; if (u > 255) { - builder.append(static_cast<LChar>('%')); - builder.append(static_cast<LChar>('u')); - appendByteAsHex(u >> 8, builder); - appendByteAsHex(u & 0xFF, builder); - } else if (u != 0 && doNotEscape.get(static_cast<LChar>(u))) - builder.append(*c); + char tmp[7]; + snprintf(tmp, sizeof(tmp), "%%u%04X", u); + builder.append(tmp); + } else if (u != 0 && strchr(do_not_escape, static_cast<char>(u))) + builder.append(c, 1); else { - builder.append(static_cast<LChar>('%')); - appendByteAsHex(u, builder); + char tmp[4]; + snprintf(tmp, sizeof(tmp), "%%%02X", u); + builder.append(tmp); } } @@ -729,7 +654,7 @@ EncodedJSValue JSC_HOST_CALL globalFuncEscape(ExecState* exec) EncodedJSValue JSC_HOST_CALL globalFuncUnescape(ExecState* exec) { StringBuilder builder; - JSString::SafeView str = exec->argument(0).toString(exec)->view(exec); + String str = exec->argument(0).toString(exec)->value(exec); int k = 0; int len = str.length(); @@ -855,13 +780,6 @@ private: JSObject* m_thisObject; }; -bool checkProtoSetterAccessAllowed(ExecState* exec, JSObject* object) -{ - GlobalFuncProtoSetterFunctor functor(object); - exec->iterate(functor); - return functor.allowsAccess(); -} - EncodedJSValue JSC_HOST_CALL globalFuncProtoSetter(ExecState* exec) { if (exec->thisValue().isUndefinedOrNull()) @@ -875,27 +793,20 @@ EncodedJSValue JSC_HOST_CALL globalFuncProtoSetter(ExecState* exec) if (!thisObject) return JSValue::encode(jsUndefined()); - if (!checkProtoSetterAccessAllowed(exec, thisObject)) + GlobalFuncProtoSetterFunctor functor(thisObject); + exec->iterate(functor); + if (!functor.allowsAccess()) return JSValue::encode(jsUndefined()); // Setting __proto__ to a non-object, non-null value is silently ignored to match Mozilla. if (!value.isObject() && !value.isNull()) return JSValue::encode(jsUndefined()); - if (thisObject->prototype() == value) - return JSValue::encode(jsUndefined()); - if (!thisObject->isExtensible()) return throwVMError(exec, createTypeError(exec, StrictModeReadonlyPropertyWriteError)); if (!thisObject->setPrototypeWithCycleCheck(exec, value)) - exec->vm().throwException(exec, createError(exec, ASCIILiteral("cyclic __proto__ value"))); - return JSValue::encode(jsUndefined()); -} - -EncodedJSValue JSC_HOST_CALL globalFuncBuiltinLog(ExecState* exec) -{ - dataLog(exec->argument(0).toWTFString(exec), "\n"); + exec->vm().throwException(exec, createError(exec, "cyclic __proto__ value")); return JSValue::encode(jsUndefined()); } |