зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1440309: Call String_repeat with int32 values to avoid repeated bailouts. r=jandem
--HG-- extra : rebase_source : ba212385115460e23dcc344ba862c911beae6467
This commit is contained in:
Родитель
929f26580a
Коммит
762378da15
|
@ -23,6 +23,9 @@
|
|||
// NB: keep this in sync with the copy in vm/ArgumentsObject.h.
|
||||
#define MAX_ARGS_LENGTH (500 * 1000)
|
||||
|
||||
// NB: keep this in sync with the copy in vm/String.h.
|
||||
#define MAX_STRING_LENGTH ((1 << 28) - 1)
|
||||
|
||||
// Spread non-empty argument list of up to 15 elements.
|
||||
#define SPREAD(v, n) SPREAD_##n(v)
|
||||
#define SPREAD_1(v) v[0]
|
||||
|
|
|
@ -68,8 +68,7 @@ function String_generic_match(thisValue, regexp) {
|
|||
* A helper function implementing the logic for both String.prototype.padStart
|
||||
* and String.prototype.padEnd as described in ES7 Draft March 29, 2016
|
||||
*/
|
||||
function String_pad(maxLength, fillString, padEnd = false) {
|
||||
|
||||
function String_pad(maxLength, fillString, padEnd) {
|
||||
// Steps 1-2.
|
||||
RequireObjectCoercible(this);
|
||||
let str = ToString(this);
|
||||
|
@ -89,15 +88,21 @@ function String_pad(maxLength, fillString, padEnd = false) {
|
|||
if (filler === "")
|
||||
return str;
|
||||
|
||||
// Throw an error if the final string length exceeds the maximum string
|
||||
// length. Perform this check early so we can use int32 operations below.
|
||||
if (intMaxLength > MAX_STRING_LENGTH)
|
||||
ThrowRangeError(JSMSG_RESULTING_STRING_TOO_LARGE);
|
||||
|
||||
// Step 9.
|
||||
let fillLen = intMaxLength - strLen;
|
||||
|
||||
// Step 10.
|
||||
// Perform an int32 division to ensure String_repeat is not called with a
|
||||
// double to avoid repeated bailouts in ToInteger.
|
||||
let truncatedStringFiller = callFunction(String_repeat, filler,
|
||||
fillLen / filler.length);
|
||||
(fillLen / filler.length) | 0);
|
||||
|
||||
truncatedStringFiller += callFunction(String_substr, filler, 0,
|
||||
fillLen % filler.length);
|
||||
truncatedStringFiller += Substring(filler, 0, fillLen % filler.length);
|
||||
|
||||
// Step 11.
|
||||
if (padEnd === true)
|
||||
|
@ -503,11 +508,14 @@ function String_repeat(count) {
|
|||
if (n < 0)
|
||||
ThrowRangeError(JSMSG_NEGATIVE_REPETITION_COUNT);
|
||||
|
||||
if (!(n * S.length < (1 << 28)))
|
||||
// Inverted condition to handle |Infinity * 0 = NaN| correctly.
|
||||
if (!(n * S.length <= MAX_STRING_LENGTH))
|
||||
ThrowRangeError(JSMSG_RESULTING_STRING_TOO_LARGE);
|
||||
|
||||
// Communicate |n|'s possible range to the compiler.
|
||||
n = n & ((1 << 28) - 1);
|
||||
assert((MAX_STRING_LENGTH & (MAX_STRING_LENGTH + 1)) === 0,
|
||||
"MAX_STRING_LENGTH can be used as a bitmask");
|
||||
n = n & MAX_STRING_LENGTH;
|
||||
|
||||
// Steps 8-9.
|
||||
var T = "";
|
||||
|
|
|
@ -1683,11 +1683,11 @@ js::ReportInNotObjectError(JSContext* cx, HandleValue lref, int lindex,
|
|||
HandleValue rref, int rindex)
|
||||
{
|
||||
auto uniqueCharsFromString = [](JSContext* cx, HandleValue ref) -> UniqueChars {
|
||||
static const size_t MAX_STRING_LENGTH = 16;
|
||||
static const size_t MaxStringLength = 16;
|
||||
RootedString str(cx, ref.toString());
|
||||
if (str->length() > MAX_STRING_LENGTH) {
|
||||
if (str->length() > MaxStringLength) {
|
||||
StringBuffer buf(cx);
|
||||
if (!buf.appendSubstring(str, 0, MAX_STRING_LENGTH))
|
||||
if (!buf.appendSubstring(str, 0, MaxStringLength))
|
||||
return nullptr;
|
||||
if (!buf.append("..."))
|
||||
return nullptr;
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include "js/CharacterEncoding.h"
|
||||
#include "js/Date.h"
|
||||
#include "js/Wrapper.h"
|
||||
#include "vm/ArgumentsObject.h"
|
||||
#include "vm/Compression.h"
|
||||
#include "vm/GeneratorObject.h"
|
||||
#include "vm/Interpreter.h"
|
||||
|
@ -3194,3 +3195,9 @@ js::GetSelfHostedFunctionName(JSFunction* fun)
|
|||
static_assert(JSString::MAX_LENGTH <= INT32_MAX,
|
||||
"StringIteratorNext in builtin/String.js assumes the stored index "
|
||||
"into the string is an Int32Value");
|
||||
|
||||
static_assert(JSString::MAX_LENGTH == MAX_STRING_LENGTH,
|
||||
"JSString::MAX_LENGTH matches self-hosted constant for maximum string length");
|
||||
|
||||
static_assert(ARGS_LENGTH_MAX == MAX_ARGS_LENGTH,
|
||||
"ARGS_LENGTH_MAX matches self-hosted constant for maximum arguments length");
|
||||
|
|
Загрузка…
Ссылка в новой задаче