Commit c203163d authored by Jakob Kummerow's avatar Jakob Kummerow Committed by Commit Bot

[strings] Introduce "is not integer index" bit

This is useful for the upcoming "huge TypedArrays" support, to be able
to quickly decide in stubs/generated code whether a string used as the
key for a property load/store can possibly be an exotic integer index.

Bug: v8:4153
Change-Id: I50ce655d2f78fb36e5615fd580f22c9290216c84
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1821460
Commit-Queue: Jakob Kummerow <jkummerow@chromium.org>
Reviewed-by: 's avatarBenedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#64165}
parent ac94b07a
...@@ -2482,8 +2482,6 @@ enum AccessorAssembler::StubCacheTable : int { ...@@ -2482,8 +2482,6 @@ enum AccessorAssembler::StubCacheTable : int {
}; };
Node* AccessorAssembler::StubCachePrimaryOffset(Node* name, Node* map) { Node* AccessorAssembler::StubCachePrimaryOffset(Node* name, Node* map) {
// See v8::internal::StubCache::PrimaryOffset().
STATIC_ASSERT(StubCache::kCacheIndexShift == Name::kHashShift);
// Compute the hash of the name (use entire hash field). // Compute the hash of the name (use entire hash field).
TNode<Uint32T> hash_field = LoadNameHashField(name); TNode<Uint32T> hash_field = LoadNameHashField(name);
CSA_ASSERT(this, CSA_ASSERT(this,
...@@ -2524,7 +2522,8 @@ void AccessorAssembler::TryProbeStubCacheTable( ...@@ -2524,7 +2522,8 @@ void AccessorAssembler::TryProbeStubCacheTable(
StubCache::Table table = static_cast<StubCache::Table>(table_id); StubCache::Table table = static_cast<StubCache::Table>(table_id);
// The {table_offset} holds the entry offset times four (due to masking // The {table_offset} holds the entry offset times four (due to masking
// and shifting optimizations). // and shifting optimizations).
const int kMultiplier = sizeof(StubCache::Entry) >> Name::kHashShift; const int kMultiplier =
sizeof(StubCache::Entry) >> StubCache::kCacheIndexShift;
entry_offset = IntPtrMul(entry_offset, IntPtrConstant(kMultiplier)); entry_offset = IntPtrMul(entry_offset, IntPtrConstant(kMultiplier));
TNode<ExternalReference> key_base = ExternalConstant( TNode<ExternalReference> key_base = ExternalConstant(
......
...@@ -26,11 +26,10 @@ void StubCache::Initialize() { ...@@ -26,11 +26,10 @@ void StubCache::Initialize() {
Clear(); Clear();
} }
// Hash algorithm for the primary table. This algorithm is replicated in // Hash algorithm for the primary table. This algorithm is replicated in
// assembler for every architecture. Returns an index into the table that // the AccessorAssembler. Returns an index into the table that
// is scaled by 1 << kCacheIndexShift. // is scaled by 1 << kCacheIndexShift.
int StubCache::PrimaryOffset(Name name, Map map) { int StubCache::PrimaryOffset(Name name, Map map) {
STATIC_ASSERT(kCacheIndexShift == Name::kHashShift);
// Compute the hash of the name (use entire hash field). // Compute the hash of the name (use entire hash field).
DCHECK(name.HasHashCode()); DCHECK(name.HasHashCode());
uint32_t field = name.hash_field(); uint32_t field = name.hash_field();
......
...@@ -78,10 +78,15 @@ class V8_EXPORT_PRIVATE StubCache { ...@@ -78,10 +78,15 @@ class V8_EXPORT_PRIVATE StubCache {
Isolate* isolate() { return isolate_; } Isolate* isolate() { return isolate_; }
// Setting the entry size such that the index is shifted by Name::kHashShift // Ideally we would set kCacheIndexShift to Name::kHashShift, such that
// is convenient; shifting down the length field (to extract the hash code) // the bit field inside the hash field gets shifted out implicitly. However,
// automatically discards the hash bit field. // sizeof(Entry) needs to be a multiple of 1 << kCacheIndexShift, and it
static const int kCacheIndexShift = Name::kHashShift; // isn't clear whether letting one bit of the bit field leak into the index
// computation is bad enough to warrant an additional shift to get rid of it.
static const int kCacheIndexShift = 2;
// The purpose of the static assert is to make us reconsider this choice
// if the bit field ever grows even more.
STATIC_ASSERT(kCacheIndexShift == Name::kHashShift - 1);
static const int kPrimaryTableBits = 11; static const int kPrimaryTableBits = 11;
static const int kPrimaryTableSize = (1 << kPrimaryTableBits); static const int kPrimaryTableSize = (1 << kPrimaryTableBits);
...@@ -125,7 +130,10 @@ class V8_EXPORT_PRIVATE StubCache { ...@@ -125,7 +130,10 @@ class V8_EXPORT_PRIVATE StubCache {
// of sizeof(Entry). This makes it easier to avoid making mistakes // of sizeof(Entry). This makes it easier to avoid making mistakes
// in the hashed offset computations. // in the hashed offset computations.
static Entry* entry(Entry* table, int offset) { static Entry* entry(Entry* table, int offset) {
const int multiplier = sizeof(*table) >> Name::kHashShift; // The size of {Entry} must be a multiple of 1 << kCacheIndexShift.
STATIC_ASSERT((sizeof(*table) >> kCacheIndexShift) << kCacheIndexShift ==
sizeof(*table));
const int multiplier = sizeof(*table) >> kCacheIndexShift;
return reinterpret_cast<Entry*>(reinterpret_cast<Address>(table) + return reinterpret_cast<Entry*>(reinterpret_cast<Address>(table) +
offset * multiplier); offset * multiplier);
} }
......
...@@ -567,7 +567,7 @@ class FeedbackMetadata : public HeapObject { ...@@ -567,7 +567,7 @@ class FeedbackMetadata : public HeapObject {
// possibly be confused with a pointer. // possibly be confused with a pointer.
// NOLINTNEXTLINE(runtime/references) (false positive) // NOLINTNEXTLINE(runtime/references) (false positive)
STATIC_ASSERT((Name::kEmptyHashField & kHeapObjectTag) == kHeapObjectTag); STATIC_ASSERT((Name::kEmptyHashField & kHeapObjectTag) == kHeapObjectTag);
STATIC_ASSERT(Name::kEmptyHashField == 0x3); STATIC_ASSERT(Name::kEmptyHashField == 0x7);
// Verify that a set hash field will not look like a tagged object. // Verify that a set hash field will not look like a tagged object.
STATIC_ASSERT(Name::kHashNotComputedMask == kHeapObjectTag); STATIC_ASSERT(Name::kHashNotComputedMask == kHeapObjectTag);
......
...@@ -100,6 +100,10 @@ bool Name::AsArrayIndex(uint32_t* index) { ...@@ -100,6 +100,10 @@ bool Name::AsArrayIndex(uint32_t* index) {
return IsString() && String::cast(*this).AsArrayIndex(index); return IsString() && String::cast(*this).AsArrayIndex(index);
} }
bool Name::AsIntegerIndex(size_t* index) {
return IsString() && String::cast(*this).AsIntegerIndex(index);
}
// static // static
bool Name::ContainsCachedArrayIndex(uint32_t hash) { bool Name::ContainsCachedArrayIndex(uint32_t hash) {
return (hash & Name::kDoesNotContainCachedArrayIndexMask) == 0; return (hash & Name::kDoesNotContainCachedArrayIndexMask) == 0;
......
...@@ -32,6 +32,7 @@ class Name : public TorqueGeneratedName<Name, HeapObject> { ...@@ -32,6 +32,7 @@ class Name : public TorqueGeneratedName<Name, HeapObject> {
// Conversion. // Conversion.
inline bool AsArrayIndex(uint32_t* index); inline bool AsArrayIndex(uint32_t* index);
inline bool AsIntegerIndex(size_t* index);
// An "interesting symbol" is a well-known symbol, like @@toStringTag, // An "interesting symbol" is a well-known symbol, like @@toStringTag,
// that's often looked up on random objects but is usually not present. // that's often looked up on random objects but is usually not present.
...@@ -73,7 +74,8 @@ class Name : public TorqueGeneratedName<Name, HeapObject> { ...@@ -73,7 +74,8 @@ class Name : public TorqueGeneratedName<Name, HeapObject> {
// array index. // array index.
static const int kHashNotComputedMask = 1; static const int kHashNotComputedMask = 1;
static const int kIsNotArrayIndexMask = 1 << 1; static const int kIsNotArrayIndexMask = 1 << 1;
static const int kNofHashBitFields = 2; static const int kIsNotIntegerIndexMask = 1 << 2;
static const int kNofHashBitFields = 3;
// Shift constant retrieving hash code from hash field. // Shift constant retrieving hash code from hash field.
static const int kHashShift = kNofHashBitFields; static const int kHashShift = kNofHashBitFields;
...@@ -88,6 +90,14 @@ class Name : public TorqueGeneratedName<Name, HeapObject> { ...@@ -88,6 +90,14 @@ class Name : public TorqueGeneratedName<Name, HeapObject> {
// Maximum number of characters to consider when trying to convert a string // Maximum number of characters to consider when trying to convert a string
// value into an array index. // value into an array index.
static const int kMaxArrayIndexSize = 10; static const int kMaxArrayIndexSize = 10;
// Maximum number of characters that might be parsed into a size_t:
// 10 characters per 32 bits of size_t width.
// We choose this as large as possible (rather than MAX_SAFE_INTEGER range)
// because TypedArray accesses will treat all string keys that are
// canonical representations of numbers in the range [MAX_SAFE_INTEGER ..
// size_t::max] as out-of-bounds accesses, and we can handle those in the
// fast path if we tag them as such (see kIsNotIntegerIndexMask).
static const int kMaxIntegerIndexSize = 10 * (sizeof(size_t) / 4);
// For strings which are array indexes the hash value has the string length // For strings which are array indexes the hash value has the string length
// mixed into the hash, mainly to avoid a hash value of zero which would be // mixed into the hash, mainly to avoid a hash value of zero which would be
...@@ -120,7 +130,7 @@ class Name : public TorqueGeneratedName<Name, HeapObject> { ...@@ -120,7 +130,7 @@ class Name : public TorqueGeneratedName<Name, HeapObject> {
// Value of empty hash field indicating that the hash is not computed. // Value of empty hash field indicating that the hash is not computed.
static const int kEmptyHashField = static const int kEmptyHashField =
kIsNotArrayIndexMask | kHashNotComputedMask; kIsNotIntegerIndexMask | kIsNotArrayIndexMask | kHashNotComputedMask;
protected: protected:
static inline bool IsHashFieldComputed(uint32_t field); static inline bool IsHashFieldComputed(uint32_t field);
......
...@@ -4505,6 +4505,7 @@ uint32_t StringHasher::MakeArrayIndexHash(uint32_t value, int length) { ...@@ -4505,6 +4505,7 @@ uint32_t StringHasher::MakeArrayIndexHash(uint32_t value, int length) {
value |= length << String::ArrayIndexLengthBits::kShift; value |= length << String::ArrayIndexLengthBits::kShift;
DCHECK_EQ(value & String::kIsNotArrayIndexMask, 0); DCHECK_EQ(value & String::kIsNotArrayIndexMask, 0);
DCHECK_EQ(value & String::kIsNotIntegerIndexMask, 0);
DCHECK_EQ(length <= String::kMaxCachedArrayIndexLength, DCHECK_EQ(length <= String::kMaxCachedArrayIndexLength,
Name::ContainsCachedArrayIndex(value)); Name::ContainsCachedArrayIndex(value));
return value; return value;
......
...@@ -778,6 +778,14 @@ bool String::AsArrayIndex(uint32_t* index) { ...@@ -778,6 +778,14 @@ bool String::AsArrayIndex(uint32_t* index) {
return SlowAsArrayIndex(index); return SlowAsArrayIndex(index);
} }
bool String::AsIntegerIndex(size_t* index) {
uint32_t field = hash_field();
if (IsHashFieldComputed(field) && (field & kIsNotIntegerIndexMask)) {
return false;
}
return SlowAsIntegerIndex(index);
}
SubStringRange::SubStringRange(String string, SubStringRange::SubStringRange(String string,
const DisallowHeapAllocation& no_gc, int first, const DisallowHeapAllocation& no_gc, int first,
int length) int length)
......
...@@ -1355,25 +1355,39 @@ uint32_t String::ComputeAndSetHash() { ...@@ -1355,25 +1355,39 @@ uint32_t String::ComputeAndSetHash() {
return result; return result;
} }
bool String::ComputeArrayIndex(uint32_t* index) { bool String::SlowAsArrayIndex(uint32_t* index) {
DisallowHeapAllocation no_gc;
int length = this->length(); int length = this->length();
if (length <= kMaxCachedArrayIndexLength) {
Hash(); // Force computation of hash code.
uint32_t field = hash_field();
if ((field & kIsNotArrayIndexMask) != 0) return false;
*index = ArrayIndexValueBits::decode(field);
return true;
}
if (length == 0 || length > kMaxArrayIndexSize) return false; if (length == 0 || length > kMaxArrayIndexSize) return false;
StringCharacterStream stream(*this); StringCharacterStream stream(*this);
return StringToArrayIndex(&stream, index); return StringToArrayIndex(&stream, index);
} }
bool String::SlowAsArrayIndex(uint32_t* index) { bool String::SlowAsIntegerIndex(size_t* index) {
DisallowHeapAllocation no_gc; DisallowHeapAllocation no_gc;
if (length() <= kMaxCachedArrayIndexLength) { int length = this->length();
Hash(); // force computation of hash code if (length <= kMaxCachedArrayIndexLength) {
Hash(); // Force computation of hash code.
uint32_t field = hash_field(); uint32_t field = hash_field();
if ((field & kIsNotArrayIndexMask) != 0) return false; if ((field & kIsNotArrayIndexMask) != 0) {
// Isolate the array index form the full hash field. // If it was short but it's not an array index, then it can't be an
// integer index either.
DCHECK_NE(0, field & kIsNotIntegerIndexMask);
return false;
}
*index = ArrayIndexValueBits::decode(field); *index = ArrayIndexValueBits::decode(field);
return true; return true;
} else {
return ComputeArrayIndex(index);
} }
if (length == 0 || length > kMaxIntegerIndexSize) return false;
StringCharacterStream stream(*this);
return StringToArrayIndex(&stream, index);
} }
void String::PrintOn(FILE* file) { void String::PrintOn(FILE* file) {
......
...@@ -308,8 +308,6 @@ class String : public TorqueGeneratedString<String, Name> { ...@@ -308,8 +308,6 @@ class String : public TorqueGeneratedString<String, Name> {
RobustnessFlag robustness_flag = FAST_STRING_TRAVERSAL, RobustnessFlag robustness_flag = FAST_STRING_TRAVERSAL,
int* length_output = nullptr); int* length_output = nullptr);
bool ComputeArrayIndex(uint32_t* index);
// Externalization. // Externalization.
V8_EXPORT_PRIVATE bool MakeExternal( V8_EXPORT_PRIVATE bool MakeExternal(
v8::String::ExternalStringResource* resource); v8::String::ExternalStringResource* resource);
...@@ -318,8 +316,12 @@ class String : public TorqueGeneratedString<String, Name> { ...@@ -318,8 +316,12 @@ class String : public TorqueGeneratedString<String, Name> {
bool SupportsExternalization(); bool SupportsExternalization();
// Conversion. // Conversion.
// "array index": an index allowed by the ES spec for JSArrays.
inline bool AsArrayIndex(uint32_t* index); inline bool AsArrayIndex(uint32_t* index);
uint32_t inline ToValidIndex(Object number); uint32_t inline ToValidIndex(Object number);
// "integer index": the string is the decimal representation of an
// integer in the range of a size_t. Useful for TypedArray accesses.
inline bool AsIntegerIndex(size_t* index);
// Trimming. // Trimming.
enum TrimMode { kTrim, kTrimStart, kTrimEnd }; enum TrimMode { kTrim, kTrimStart, kTrimEnd };
...@@ -450,6 +452,7 @@ class String : public TorqueGeneratedString<String, Name> { ...@@ -450,6 +452,7 @@ class String : public TorqueGeneratedString<String, Name> {
// Slow case of AsArrayIndex. // Slow case of AsArrayIndex.
V8_EXPORT_PRIVATE bool SlowAsArrayIndex(uint32_t* index); V8_EXPORT_PRIVATE bool SlowAsArrayIndex(uint32_t* index);
V8_EXPORT_PRIVATE bool SlowAsIntegerIndex(size_t* index);
// Compute and set the hash code. // Compute and set the hash code.
V8_EXPORT_PRIVATE uint32_t ComputeAndSetHash(); V8_EXPORT_PRIVATE uint32_t ComputeAndSetHash();
......
...@@ -34,32 +34,63 @@ uint32_t StringHasher::GetHashCore(uint32_t running_hash) { ...@@ -34,32 +34,63 @@ uint32_t StringHasher::GetHashCore(uint32_t running_hash) {
uint32_t StringHasher::GetTrivialHash(int length) { uint32_t StringHasher::GetTrivialHash(int length) {
DCHECK_GT(length, String::kMaxHashCalcLength); DCHECK_GT(length, String::kMaxHashCalcLength);
// String hash of a large string is simply the length. // String hash of a large string is simply the length.
return (length << String::kHashShift) | String::kIsNotArrayIndexMask; return (length << String::kHashShift) | String::kIsNotArrayIndexMask |
String::kIsNotIntegerIndexMask;
} }
template <typename schar> template <typename schar>
uint32_t StringHasher::HashSequentialString(const schar* chars, int length, uint32_t StringHasher::HashSequentialString(const schar* chars, int length,
uint64_t seed) { uint64_t seed) {
// Check whether the string is a valid array index. In that case, compute the DCHECK_LE(0, length);
// array index hash. It'll fall through to compute a regular string hash from DCHECK_IMPLIES(0 < length, chars != nullptr);
// the start if it turns out that the string isn't a valid array index. if (length >= 1) {
if (IsInRange(length, 1, String::kMaxArrayIndexSize)) {
if (IsDecimalDigit(chars[0]) && (length == 1 || chars[0] != '0')) { if (IsDecimalDigit(chars[0]) && (length == 1 || chars[0] != '0')) {
uint32_t index = chars[0] - '0'; uint32_t index = 0;
int i = 1; if (length <= String::kMaxArrayIndexSize) {
do { // Possible array index; try to compute the array index hash.
if (i == length) { index = chars[0] - '0';
return MakeArrayIndexHash(index, length); int i = 1;
do {
if (i == length) {
return MakeArrayIndexHash(index, length);
}
} while (TryAddIndexChar(&index, chars[i++]));
}
// The following block wouldn't do anything on 32-bit platforms,
// because kMaxArrayIndexSize == kMaxIntegerIndexSize there, and
// if we wanted to compile it everywhere, then {index_big} would
// have to be a {size_t}, which the Mac compiler doesn't like to
// implicitly cast to uint64_t for the {TryAddIndexChar} call.
#if V8_HOST_ARCH_64_BIT
// No "else" here: if the block above was entered and fell through,
// we'll have to take this branch.
if (length <= String::kMaxIntegerIndexSize) {
// Not an array index, but it could still be an integer index.
// Perform a regular hash computation, and additionally check
// if there are non-digit characters.
uint32_t is_integer_index = 0;
uint32_t running_hash = static_cast<uint32_t>(seed);
uint64_t index_big = index;
const schar* end = &chars[length];
while (chars != end) {
if (is_integer_index == 0 && !TryAddIndexChar(&index_big, *chars)) {
is_integer_index = String::kIsNotIntegerIndexMask;
}
running_hash = AddCharacterCore(running_hash, *chars++);
} }
} while (TryAddIndexChar(&index, chars[i++])); return (GetHashCore(running_hash) << String::kHashShift) |
String::kIsNotArrayIndexMask | is_integer_index;
}
#endif
}
// No "else" here: if the first character was a decimal digit, we might
// still have to take this branch.
if (length > String::kMaxHashCalcLength) {
return GetTrivialHash(length);
} }
} else if (length > String::kMaxHashCalcLength) {
return GetTrivialHash(length);
} }
// Non-array-index hash. // Non-index hash.
DCHECK_LE(0, length);
DCHECK_IMPLIES(0 < length, chars != nullptr);
uint32_t running_hash = static_cast<uint32_t>(seed); uint32_t running_hash = static_cast<uint32_t>(seed);
const schar* end = &chars[length]; const schar* end = &chars[length];
while (chars != end) { while (chars != end) {
...@@ -67,7 +98,7 @@ uint32_t StringHasher::HashSequentialString(const schar* chars, int length, ...@@ -67,7 +98,7 @@ uint32_t StringHasher::HashSequentialString(const schar* chars, int length,
} }
return (GetHashCore(running_hash) << String::kHashShift) | return (GetHashCore(running_hash) << String::kHashShift) |
String::kIsNotArrayIndexMask; String::kIsNotArrayIndexMask | String::kIsNotIntegerIndexMask;
} }
std::size_t SeededStringHasher::operator()(const char* name) const { std::size_t SeededStringHasher::operator()(const char* name) const {
......
...@@ -36,13 +36,30 @@ template <typename Char> ...@@ -36,13 +36,30 @@ template <typename Char>
bool TryAddIndexChar(uint32_t* index, Char c) { bool TryAddIndexChar(uint32_t* index, Char c) {
if (!IsDecimalDigit(c)) return false; if (!IsDecimalDigit(c)) return false;
int d = c - '0'; int d = c - '0';
// The maximum index is 4294967294; for the computation below to not
// exceed that, the previous index value must be <= 429496729 if d <= 4,
// or <= 429496728 if d >= 5. The (d+3)>>3 computation is a branch-free
// way to express that.
if (*index > 429496729U - ((d + 3) >> 3)) return false; if (*index > 429496729U - ((d + 3) >> 3)) return false;
*index = (*index) * 10 + d; *index = (*index) * 10 + d;
return true; return true;
} }
template <typename Stream> template <typename Char>
bool StringToArrayIndex(Stream* stream, uint32_t* index) { bool TryAddIndexChar(uint64_t* index, Char c) {
if (!IsDecimalDigit(c)) return false;
int d = c - '0';
// The maximum uint64_t is 18446744073709551615; for the computation below to
// not exceed that, the previous index value must be <= 1844674407370955161
// if d <= 5, or <= 1844674407370955160 if d >= 6. The (d+2)>>3 computation
// is a branch-free way to express that.
if (*index > 1844674407370955161ull - ((d + 2) >> 3)) return false;
*index = (*index) * 10 + d;
return true;
}
template <typename Stream, typename index_t>
bool StringToArrayIndex(Stream* stream, index_t* index) {
uint16_t ch = stream->GetNext(); uint16_t ch = stream->GetNext();
// If the string begins with a '0' character, it must only consist // If the string begins with a '0' character, it must only consist
...@@ -55,9 +72,20 @@ bool StringToArrayIndex(Stream* stream, uint32_t* index) { ...@@ -55,9 +72,20 @@ bool StringToArrayIndex(Stream* stream, uint32_t* index) {
// Convert string to uint32 array index; character by character. // Convert string to uint32 array index; character by character.
if (!IsDecimalDigit(ch)) return false; if (!IsDecimalDigit(ch)) return false;
int d = ch - '0'; int d = ch - '0';
uint32_t result = d; index_t result = d;
while (stream->HasMore()) { while (stream->HasMore()) {
if (!TryAddIndexChar(&result, stream->GetNext())) return false; // Clang on Mac doesn't think that size_t and uint*_t should be
// implicitly convertible.
if (sizeof(index_t) == 8) {
if (!TryAddIndexChar(reinterpret_cast<uint64_t*>(&result),
stream->GetNext())) {
return false;
}
} else {
if (!TryAddIndexChar(reinterpret_cast<uint32_t*>(&result),
stream->GetNext()))
return false;
}
} }
*index = result; *index = result;
......
...@@ -973,8 +973,8 @@ bool DoubleToBoolean(double d); ...@@ -973,8 +973,8 @@ bool DoubleToBoolean(double d);
template <typename Char> template <typename Char>
bool TryAddIndexChar(uint32_t* index, Char c); bool TryAddIndexChar(uint32_t* index, Char c);
template <typename Stream> template <typename Stream, typename index_t>
bool StringToArrayIndex(Stream* stream, uint32_t* index); bool StringToArrayIndex(Stream* stream, index_t* index);
// Returns the current stack top. Works correctly with ASAN and SafeStack. // Returns the current stack top. Works correctly with ASAN and SafeStack.
// GetCurrentStackPosition() should not be inlined, because it works on stack // GetCurrentStackPosition() should not be inlined, because it works on stack
......
...@@ -1857,6 +1857,48 @@ GC_INSIDE_NEW_STRING_FROM_UTF8_SUB_STRING( ...@@ -1857,6 +1857,48 @@ GC_INSIDE_NEW_STRING_FROM_UTF8_SUB_STRING(
#undef GC_INSIDE_NEW_STRING_FROM_UTF8_SUB_STRING #undef GC_INSIDE_NEW_STRING_FROM_UTF8_SUB_STRING
namespace {
struct IndexData {
const char* string;
bool is_array_index;
uint32_t array_index;
bool is_integer_index;
size_t integer_index;
};
void TestString(i::Isolate* isolate, const IndexData& data) {
Handle<String> s = isolate->factory()->NewStringFromAsciiChecked(data.string);
if (data.is_array_index) {
uint32_t index;
CHECK(s->AsArrayIndex(&index));
CHECK_EQ(data.array_index, index);
// AsArrayIndex only forces hash computation for cacheable indices;
// so trigger hash computation for longer strings manually.
if (s->length() > String::kMaxCachedArrayIndexLength) s->Hash();
CHECK_EQ(0, s->hash_field() & String::kIsNotArrayIndexMask);
CHECK(s->HasHashCode());
}
if (data.is_integer_index) {
size_t index;
CHECK(s->AsIntegerIndex(&index));
CHECK_EQ(data.integer_index, index);
s->Hash();
CHECK_EQ(0, s->hash_field() & String::kIsNotIntegerIndexMask);
CHECK(s->HasHashCode());
}
if (!s->HasHashCode()) s->Hash();
CHECK(s->HasHashCode());
if (!data.is_array_index) {
CHECK_NE(0, s->hash_field() & String::kIsNotArrayIndexMask);
}
if (!data.is_integer_index) {
CHECK_NE(0, s->hash_field() & String::kIsNotIntegerIndexMask);
}
}
} // namespace
TEST(HashArrayIndexStrings) { TEST(HashArrayIndexStrings) {
CcTest::InitializeVM(); CcTest::InitializeVM();
LocalContext context; LocalContext context;
...@@ -1870,6 +1912,27 @@ TEST(HashArrayIndexStrings) { ...@@ -1870,6 +1912,27 @@ TEST(HashArrayIndexStrings) {
CHECK_EQ(StringHasher::MakeArrayIndexHash(1 /* value */, 1 /* length */) >> CHECK_EQ(StringHasher::MakeArrayIndexHash(1 /* value */, 1 /* length */) >>
Name::kHashShift, Name::kHashShift,
isolate->factory()->one_string()->Hash()); isolate->factory()->one_string()->Hash());
IndexData tests[] = {
{"", false, 0, false, 0},
{"123no", false, 0, false, 0},
{"12345", true, 12345, true, 12345},
{"12345678", true, 12345678, true, 12345678},
{"4294967294", true, 4294967294u, true, 4294967294u},
#if V8_TARGET_ARCH_32_BIT
{"4294967295", false, 0, false, 0}, // Valid length but not index.
{"4294967296", false, 0, false, 0},
{"18446744073709551615", false, 0, false, 0},
#else
{"4294967295", false, 0, true, 4294967295u},
{"4294967296", false, 0, true, 4294967296ull},
{"18446744073709551615", false, 0, true, 18446744073709551615ull},
#endif
{"18446744073709551616", false, 0, false, 0}
};
for (int i = 0, n = arraysize(tests); i < n; i++) {
TestString(isolate, tests[i]);
}
} }
TEST(StringEquals) { TEST(StringEquals) {
......
Tests that cloning a module notifies the debugger Tests that cloning a module notifies the debugger
Got URL: wasm://wasm/wasm-cae8f226/wasm-cae8f226-0 Got URL: wasm://wasm/wasm-95d1e44e/wasm-95d1e44e-0
Got URL: wasm://wasm/wasm-cae8f226/wasm-cae8f226-0 Got URL: wasm://wasm/wasm-95d1e44e/wasm-95d1e44e-0
Got URL: wasm://wasm/wasm-cae8f226/wasm-cae8f226-0 Got URL: wasm://wasm/wasm-95d1e44e/wasm-95d1e44e-0
Done! Done!
...@@ -2,9 +2,9 @@ Tests breakable locations in wasm ...@@ -2,9 +2,9 @@ Tests breakable locations in wasm
Running testFunction... Running testFunction...
Script nr 0 parsed. URL: v8://test/setup Script nr 0 parsed. URL: v8://test/setup
Script nr 1 parsed. URL: v8://test/runTestFunction Script nr 1 parsed. URL: v8://test/runTestFunction
Script nr 2 parsed. URL: wasm://wasm/wasm-354ada0e/wasm-354ada0e-0 Script nr 2 parsed. URL: wasm://wasm/wasm-6a95b41e/wasm-6a95b41e-0
This is a wasm script (nr 0). This is a wasm script (nr 0).
Script nr 3 parsed. URL: wasm://wasm/wasm-354ada0e/wasm-354ada0e-1 Script nr 3 parsed. URL: wasm://wasm/wasm-6a95b41e/wasm-6a95b41e-1
This is a wasm script (nr 1). This is a wasm script (nr 1).
Querying breakable locations for all wasm scripts now... Querying breakable locations for all wasm scripts now...
Requesting all breakable locations in wasm script 0 Requesting all breakable locations in wasm script 0
...@@ -38,51 +38,51 @@ Requesting breakable locations in lines [4,6) ...@@ -38,51 +38,51 @@ Requesting breakable locations in lines [4,6)
[0] 4:6 || >call 0 [0] 4:6 || >call 0
[1] 5:4 || >end [1] 5:4 || >end
Setting a breakpoint on each breakable location... Setting a breakpoint on each breakable location...
Setting at wasm://wasm/wasm-354ada0e/wasm-354ada0e-0:2:2 Setting at wasm://wasm/wasm-6a95b41e/wasm-6a95b41e-0:2:2
Success! Success!
Setting at wasm://wasm/wasm-354ada0e/wasm-354ada0e-0:3:2 Setting at wasm://wasm/wasm-6a95b41e/wasm-6a95b41e-0:3:2
Success! Success!
Setting at wasm://wasm/wasm-354ada0e/wasm-354ada0e-0:4:2 Setting at wasm://wasm/wasm-6a95b41e/wasm-6a95b41e-0:4:2
Success! Success!
Setting at wasm://wasm/wasm-354ada0e/wasm-354ada0e-0:5:0 Setting at wasm://wasm/wasm-6a95b41e/wasm-6a95b41e-0:5:0
Success! Success!
Setting at wasm://wasm/wasm-354ada0e/wasm-354ada0e-1:1:2 Setting at wasm://wasm/wasm-6a95b41e/wasm-6a95b41e-1:1:2
Success! Success!
Setting at wasm://wasm/wasm-354ada0e/wasm-354ada0e-1:2:2 Setting at wasm://wasm/wasm-6a95b41e/wasm-6a95b41e-1:2:2
Success! Success!
Setting at wasm://wasm/wasm-354ada0e/wasm-354ada0e-1:3:4 Setting at wasm://wasm/wasm-6a95b41e/wasm-6a95b41e-1:3:4
Success! Success!
Setting at wasm://wasm/wasm-354ada0e/wasm-354ada0e-1:4:6 Setting at wasm://wasm/wasm-6a95b41e/wasm-6a95b41e-1:4:6
Success! Success!
Setting at wasm://wasm/wasm-354ada0e/wasm-354ada0e-1:5:4 Setting at wasm://wasm/wasm-6a95b41e/wasm-6a95b41e-1:5:4
Success! Success!
Setting at wasm://wasm/wasm-354ada0e/wasm-354ada0e-1:6:2 Setting at wasm://wasm/wasm-6a95b41e/wasm-6a95b41e-1:6:2
Success! Success!
Setting at wasm://wasm/wasm-354ada0e/wasm-354ada0e-1:7:0 Setting at wasm://wasm/wasm-6a95b41e/wasm-6a95b41e-1:7:0
Success! Success!
Running wasm code... Running wasm code...
Missing breakpoints: 11 Missing breakpoints: 11
Script nr 4 parsed. URL: v8://test/runWasm Script nr 4 parsed. URL: v8://test/runWasm
Stopped at wasm://wasm/wasm-354ada0e/wasm-354ada0e-1:1:2 Stopped at wasm://wasm/wasm-6a95b41e/wasm-6a95b41e-1:1:2
Missing breakpoints: 10 Missing breakpoints: 10
Stopped at wasm://wasm/wasm-354ada0e/wasm-354ada0e-1:2:2 Stopped at wasm://wasm/wasm-6a95b41e/wasm-6a95b41e-1:2:2
Missing breakpoints: 9 Missing breakpoints: 9
Stopped at wasm://wasm/wasm-354ada0e/wasm-354ada0e-1:3:4 Stopped at wasm://wasm/wasm-6a95b41e/wasm-6a95b41e-1:3:4
Missing breakpoints: 8 Missing breakpoints: 8
Stopped at wasm://wasm/wasm-354ada0e/wasm-354ada0e-1:4:6 Stopped at wasm://wasm/wasm-6a95b41e/wasm-6a95b41e-1:4:6
Missing breakpoints: 7 Missing breakpoints: 7
Stopped at wasm://wasm/wasm-354ada0e/wasm-354ada0e-0:2:2 Stopped at wasm://wasm/wasm-6a95b41e/wasm-6a95b41e-0:2:2
Missing breakpoints: 6 Missing breakpoints: 6
Stopped at wasm://wasm/wasm-354ada0e/wasm-354ada0e-0:3:2 Stopped at wasm://wasm/wasm-6a95b41e/wasm-6a95b41e-0:3:2
Missing breakpoints: 5 Missing breakpoints: 5
Stopped at wasm://wasm/wasm-354ada0e/wasm-354ada0e-0:4:2 Stopped at wasm://wasm/wasm-6a95b41e/wasm-6a95b41e-0:4:2
Missing breakpoints: 4 Missing breakpoints: 4
Stopped at wasm://wasm/wasm-354ada0e/wasm-354ada0e-0:5:0 Stopped at wasm://wasm/wasm-6a95b41e/wasm-6a95b41e-0:5:0
Missing breakpoints: 3 Missing breakpoints: 3
Stopped at wasm://wasm/wasm-354ada0e/wasm-354ada0e-1:5:4 Stopped at wasm://wasm/wasm-6a95b41e/wasm-6a95b41e-1:5:4
Missing breakpoints: 2 Missing breakpoints: 2
Stopped at wasm://wasm/wasm-354ada0e/wasm-354ada0e-1:6:2 Stopped at wasm://wasm/wasm-6a95b41e/wasm-6a95b41e-1:6:2
Missing breakpoints: 1 Missing breakpoints: 1
Stopped at wasm://wasm/wasm-354ada0e/wasm-354ada0e-1:7:0 Stopped at wasm://wasm/wasm-6a95b41e/wasm-6a95b41e-1:7:0
Missing breakpoints: 0 Missing breakpoints: 0
Finished! Finished!
Tests how wasm scripts are reported Tests how wasm scripts are reported
Check that each inspector gets two wasm scripts at module creation time. Check that each inspector gets two wasm scripts at module creation time.
Session #1: Script #0 parsed. URL: wasm://wasm/wasm-7b04570e/wasm-7b04570e-0. Source map URL: Session #1: Script #0 parsed. URL: wasm://wasm/wasm-f608ae1e/wasm-f608ae1e-0. Source map URL:
Session #1: Script #1 parsed. URL: wasm://wasm/wasm-7b04570e/wasm-7b04570e-1. Source map URL: Session #1: Script #1 parsed. URL: wasm://wasm/wasm-f608ae1e/wasm-f608ae1e-1. Source map URL:
Session #2: Script #0 parsed. URL: wasm://wasm/wasm-7b04570e/wasm-7b04570e-0. Source map URL: Session #2: Script #0 parsed. URL: wasm://wasm/wasm-f608ae1e/wasm-f608ae1e-0. Source map URL:
Session #2: Script #1 parsed. URL: wasm://wasm/wasm-7b04570e/wasm-7b04570e-1. Source map URL: Session #2: Script #1 parsed. URL: wasm://wasm/wasm-f608ae1e/wasm-f608ae1e-1. Source map URL:
Session #1: Script #2 parsed. URL: wasm://wasm/wasm-77a937ae. Source map URL: wasm://dwarf Session #1: Script #2 parsed. URL: wasm://wasm/wasm-ef526f5e. Source map URL: wasm://dwarf
Session #2: Script #2 parsed. URL: wasm://wasm/wasm-77a937ae. Source map URL: wasm://dwarf Session #2: Script #2 parsed. URL: wasm://wasm/wasm-ef526f5e. Source map URL: wasm://dwarf
Session #1: Source for wasm://wasm/wasm-7b04570e/wasm-7b04570e-0: Session #1: Source for wasm://wasm/wasm-f608ae1e/wasm-f608ae1e-0:
func $nopFunction func $nopFunction
nop nop
end end
Session #1: Source for wasm://wasm/wasm-7b04570e/wasm-7b04570e-1: Session #1: Source for wasm://wasm/wasm-f608ae1e/wasm-f608ae1e-1:
func $main func $main
block block
i32.const 2 i32.const 2
...@@ -19,12 +19,12 @@ func $main ...@@ -19,12 +19,12 @@ func $main
end end
end end
Session #2: Source for wasm://wasm/wasm-7b04570e/wasm-7b04570e-0: Session #2: Source for wasm://wasm/wasm-f608ae1e/wasm-f608ae1e-0:
func $nopFunction func $nopFunction
nop nop
end end
Session #2: Source for wasm://wasm/wasm-7b04570e/wasm-7b04570e-1: Session #2: Source for wasm://wasm/wasm-f608ae1e/wasm-f608ae1e-1:
func $main func $main
block block
i32.const 2 i32.const 2
...@@ -32,11 +32,11 @@ func $main ...@@ -32,11 +32,11 @@ func $main
end end
end end
Session #1: Source for wasm://wasm/wasm-77a937ae: Session #1: Source for wasm://wasm/wasm-ef526f5e:
Raw: 00 61 73 6d 01 00 00 00 01 07 02 60 00 00 60 00 00 03 03 02 00 01 07 08 01 04 6d 61 69 6e 00 01 0a 0e 02 03 00 01 0b 08 00 02 40 41 02 1a 0b 0b 00 0c 0b 2e 64 65 62 75 67 5f 69 6e 66 6f 00 1b 04 6e 61 6d 65 01 14 02 00 0b 6e 6f 70 46 75 6e 63 74 69 6f 6e 01 04 6d 61 69 6e Raw: 00 61 73 6d 01 00 00 00 01 07 02 60 00 00 60 00 00 03 03 02 00 01 07 08 01 04 6d 61 69 6e 00 01 0a 0e 02 03 00 01 0b 08 00 02 40 41 02 1a 0b 0b 00 0c 0b 2e 64 65 62 75 67 5f 69 6e 66 6f 00 1b 04 6e 61 6d 65 01 14 02 00 0b 6e 6f 70 46 75 6e 63 74 69 6f 6e 01 04 6d 61 69 6e
Imports: [] Imports: []
Exports: [main: function] Exports: [main: function]
Session #2: Source for wasm://wasm/wasm-77a937ae: Session #2: Source for wasm://wasm/wasm-ef526f5e:
Raw: 00 61 73 6d 01 00 00 00 01 07 02 60 00 00 60 00 00 03 03 02 00 01 07 08 01 04 6d 61 69 6e 00 01 0a 0e 02 03 00 01 0b 08 00 02 40 41 02 1a 0b 0b 00 0c 0b 2e 64 65 62 75 67 5f 69 6e 66 6f 00 1b 04 6e 61 6d 65 01 14 02 00 0b 6e 6f 70 46 75 6e 63 74 69 6f 6e 01 04 6d 61 69 6e Raw: 00 61 73 6d 01 00 00 00 01 07 02 60 00 00 60 00 00 03 03 02 00 01 07 08 01 04 6d 61 69 6e 00 01 0a 0e 02 03 00 01 0b 08 00 02 40 41 02 1a 0b 0b 00 0c 0b 2e 64 65 62 75 67 5f 69 6e 66 6f 00 1b 04 6e 61 6d 65 01 14 02 00 0b 6e 6f 70 46 75 6e 63 74 69 6f 6e 01 04 6d 61 69 6e
Imports: [] Imports: []
Exports: [main: function] Exports: [main: function]
Tests stepping through wasm scripts. Tests stepping through wasm scripts.
Instantiating. Instantiating.
Waiting for two wasm scripts (ignoring first non-wasm script). Waiting for two wasm scripts (ignoring first non-wasm script).
Source of script wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-0: Source of script wasm://wasm/wasm-18214bfe/wasm-18214bfe-0:
1: func $wasm_A 1: func $wasm_A
2: nop 2: nop
3: nop 3: nop
4: end 4: end
Source of script wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1: Source of script wasm://wasm/wasm-18214bfe/wasm-18214bfe-1:
1: func $wasm_B (param i32) 1: func $wasm_B (param i32)
2: loop 2: loop
3: local.get 0 3: local.get 0
...@@ -22,12 +22,12 @@ Source of script wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1: ...@@ -22,12 +22,12 @@ Source of script wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:
12: end 12: end
13: end 13: end
Setting breakpoint on line 8 on script wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1 Setting breakpoint on line 8 on script wasm://wasm/wasm-18214bfe/wasm-18214bfe-1
Setting breakpoint on line 7 on script wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1 Setting breakpoint on line 7 on script wasm://wasm/wasm-18214bfe/wasm-18214bfe-1
Setting breakpoint on line 6 on script wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1 Setting breakpoint on line 6 on script wasm://wasm/wasm-18214bfe/wasm-18214bfe-1
Setting breakpoint on line 5 on script wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1 Setting breakpoint on line 5 on script wasm://wasm/wasm-18214bfe/wasm-18214bfe-1
Setting breakpoint on line 3 on script wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1 Setting breakpoint on line 3 on script wasm://wasm/wasm-18214bfe/wasm-18214bfe-1
Setting breakpoint on line 4 on script wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1 Setting breakpoint on line 4 on script wasm://wasm/wasm-18214bfe/wasm-18214bfe-1
Calling main(4) Calling main(4)
Breaking on line 3 Breaking on line 3
Breaking on line 4 Breaking on line 4
......
...@@ -3,10 +3,10 @@ Installing code an global variable. ...@@ -3,10 +3,10 @@ Installing code an global variable.
Calling instantiate function. Calling instantiate function.
Waiting for two wasm scripts to be parsed. Waiting for two wasm scripts to be parsed.
Ignoring script with url v8://test/callInstantiate Ignoring script with url v8://test/callInstantiate
Got wasm script: wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-0 Got wasm script: wasm://wasm/wasm-18214bfe/wasm-18214bfe-0
Requesting source for wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-0... Requesting source for wasm://wasm/wasm-18214bfe/wasm-18214bfe-0...
Got wasm script: wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1 Got wasm script: wasm://wasm/wasm-18214bfe/wasm-18214bfe-1
Requesting source for wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1... Requesting source for wasm://wasm/wasm-18214bfe/wasm-18214bfe-1...
func $wasm_A func $wasm_A
nop nop
nop nop
...@@ -26,13 +26,13 @@ func $wasm_B (param i32) ...@@ -26,13 +26,13 @@ func $wasm_B (param i32)
end end
end end
Setting breakpoint on line 7 (on the setlocal before the call), url wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1 Setting breakpoint on line 7 (on the setlocal before the call), url wasm://wasm/wasm-18214bfe/wasm-18214bfe-1
{ {
columnNumber : 6 columnNumber : 6
lineNumber : 7 lineNumber : 7
scriptId : <scriptId> scriptId : <scriptId>
} }
Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:7:6: >local.set 0 Paused at wasm://wasm/wasm-18214bfe/wasm-18214bfe-1:7:6: >local.set 0
at wasm_B (7:6): at wasm_B (7:6):
- scope (global): - scope (global):
-- skipped -- skipped
...@@ -43,7 +43,7 @@ at (anonymous) (0:17): ...@@ -43,7 +43,7 @@ at (anonymous) (0:17):
- scope (global): - scope (global):
-- skipped -- skipped
Debugger.stepInto called Debugger.stepInto called
Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:8:6: >call 0 Paused at wasm://wasm/wasm-18214bfe/wasm-18214bfe-1:8:6: >call 0
at wasm_B (8:6): at wasm_B (8:6):
- scope (global): - scope (global):
-- skipped -- skipped
...@@ -54,7 +54,7 @@ at (anonymous) (0:17): ...@@ -54,7 +54,7 @@ at (anonymous) (0:17):
- scope (global): - scope (global):
-- skipped -- skipped
Debugger.stepInto called Debugger.stepInto called
Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-0:1:2: >nop Paused at wasm://wasm/wasm-18214bfe/wasm-18214bfe-0:1:2: >nop
at wasm_A (1:2): at wasm_A (1:2):
- scope (global): - scope (global):
-- skipped -- skipped
...@@ -70,7 +70,7 @@ at (anonymous) (0:17): ...@@ -70,7 +70,7 @@ at (anonymous) (0:17):
- scope (global): - scope (global):
-- skipped -- skipped
Debugger.stepOver called Debugger.stepOver called
Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-0:2:2: >nop Paused at wasm://wasm/wasm-18214bfe/wasm-18214bfe-0:2:2: >nop
at wasm_A (2:2): at wasm_A (2:2):
- scope (global): - scope (global):
-- skipped -- skipped
...@@ -86,7 +86,7 @@ at (anonymous) (0:17): ...@@ -86,7 +86,7 @@ at (anonymous) (0:17):
- scope (global): - scope (global):
-- skipped -- skipped
Debugger.stepOut called Debugger.stepOut called
Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:9:6: >br 1 Paused at wasm://wasm/wasm-18214bfe/wasm-18214bfe-1:9:6: >br 1
at wasm_B (9:6): at wasm_B (9:6):
- scope (global): - scope (global):
-- skipped -- skipped
...@@ -97,7 +97,7 @@ at (anonymous) (0:17): ...@@ -97,7 +97,7 @@ at (anonymous) (0:17):
- scope (global): - scope (global):
-- skipped -- skipped
Debugger.stepOut called Debugger.stepOut called
Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:7:6: >local.set 0 Paused at wasm://wasm/wasm-18214bfe/wasm-18214bfe-1:7:6: >local.set 0
at wasm_B (7:6): at wasm_B (7:6):
- scope (global): - scope (global):
-- skipped -- skipped
...@@ -108,7 +108,7 @@ at (anonymous) (0:17): ...@@ -108,7 +108,7 @@ at (anonymous) (0:17):
- scope (global): - scope (global):
-- skipped -- skipped
Debugger.stepOver called Debugger.stepOver called
Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:8:6: >call 0 Paused at wasm://wasm/wasm-18214bfe/wasm-18214bfe-1:8:6: >call 0
at wasm_B (8:6): at wasm_B (8:6):
- scope (global): - scope (global):
-- skipped -- skipped
...@@ -119,7 +119,7 @@ at (anonymous) (0:17): ...@@ -119,7 +119,7 @@ at (anonymous) (0:17):
- scope (global): - scope (global):
-- skipped -- skipped
Debugger.stepOver called Debugger.stepOver called
Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:9:6: >br 1 Paused at wasm://wasm/wasm-18214bfe/wasm-18214bfe-1:9:6: >br 1
at wasm_B (9:6): at wasm_B (9:6):
- scope (global): - scope (global):
-- skipped -- skipped
...@@ -130,7 +130,7 @@ at (anonymous) (0:17): ...@@ -130,7 +130,7 @@ at (anonymous) (0:17):
- scope (global): - scope (global):
-- skipped -- skipped
Debugger.resume called Debugger.resume called
Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:7:6: >local.set 0 Paused at wasm://wasm/wasm-18214bfe/wasm-18214bfe-1:7:6: >local.set 0
at wasm_B (7:6): at wasm_B (7:6):
- scope (global): - scope (global):
-- skipped -- skipped
...@@ -141,7 +141,7 @@ at (anonymous) (0:17): ...@@ -141,7 +141,7 @@ at (anonymous) (0:17):
- scope (global): - scope (global):
-- skipped -- skipped
Debugger.stepInto called Debugger.stepInto called
Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:8:6: >call 0 Paused at wasm://wasm/wasm-18214bfe/wasm-18214bfe-1:8:6: >call 0
at wasm_B (8:6): at wasm_B (8:6):
- scope (global): - scope (global):
-- skipped -- skipped
...@@ -152,7 +152,7 @@ at (anonymous) (0:17): ...@@ -152,7 +152,7 @@ at (anonymous) (0:17):
- scope (global): - scope (global):
-- skipped -- skipped
Debugger.stepInto called Debugger.stepInto called
Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-0:1:2: >nop Paused at wasm://wasm/wasm-18214bfe/wasm-18214bfe-0:1:2: >nop
at wasm_A (1:2): at wasm_A (1:2):
- scope (global): - scope (global):
-- skipped -- skipped
...@@ -168,7 +168,7 @@ at (anonymous) (0:17): ...@@ -168,7 +168,7 @@ at (anonymous) (0:17):
- scope (global): - scope (global):
-- skipped -- skipped
Debugger.stepOut called Debugger.stepOut called
Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:9:6: >br 1 Paused at wasm://wasm/wasm-18214bfe/wasm-18214bfe-1:9:6: >br 1
at wasm_B (9:6): at wasm_B (9:6):
- scope (global): - scope (global):
-- skipped -- skipped
...@@ -179,7 +179,7 @@ at (anonymous) (0:17): ...@@ -179,7 +179,7 @@ at (anonymous) (0:17):
- scope (global): - scope (global):
-- skipped -- skipped
Debugger.stepInto called Debugger.stepInto called
Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:1:2: >loop Paused at wasm://wasm/wasm-18214bfe/wasm-18214bfe-1:1:2: >loop
at wasm_B (1:2): at wasm_B (1:2):
- scope (global): - scope (global):
-- skipped -- skipped
...@@ -190,7 +190,7 @@ at (anonymous) (0:17): ...@@ -190,7 +190,7 @@ at (anonymous) (0:17):
- scope (global): - scope (global):
-- skipped -- skipped
Debugger.stepInto called Debugger.stepInto called
Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:2:4: >local.get 0 Paused at wasm://wasm/wasm-18214bfe/wasm-18214bfe-1:2:4: >local.get 0
at wasm_B (2:4): at wasm_B (2:4):
- scope (global): - scope (global):
-- skipped -- skipped
...@@ -201,7 +201,7 @@ at (anonymous) (0:17): ...@@ -201,7 +201,7 @@ at (anonymous) (0:17):
- scope (global): - scope (global):
-- skipped -- skipped
Debugger.stepInto called Debugger.stepInto called
Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:3:4: >if Paused at wasm://wasm/wasm-18214bfe/wasm-18214bfe-1:3:4: >if
at wasm_B (3:4): at wasm_B (3:4):
- scope (global): - scope (global):
-- skipped -- skipped
...@@ -212,7 +212,7 @@ at (anonymous) (0:17): ...@@ -212,7 +212,7 @@ at (anonymous) (0:17):
- scope (global): - scope (global):
-- skipped -- skipped
Debugger.stepInto called Debugger.stepInto called
Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:4:6: >local.get 0 Paused at wasm://wasm/wasm-18214bfe/wasm-18214bfe-1:4:6: >local.get 0
at wasm_B (4:6): at wasm_B (4:6):
- scope (global): - scope (global):
-- skipped -- skipped
...@@ -223,7 +223,7 @@ at (anonymous) (0:17): ...@@ -223,7 +223,7 @@ at (anonymous) (0:17):
- scope (global): - scope (global):
-- skipped -- skipped
Debugger.stepInto called Debugger.stepInto called
Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:5:6: >i32.const 1 Paused at wasm://wasm/wasm-18214bfe/wasm-18214bfe-1:5:6: >i32.const 1
at wasm_B (5:6): at wasm_B (5:6):
- scope (global): - scope (global):
-- skipped -- skipped
...@@ -234,7 +234,7 @@ at (anonymous) (0:17): ...@@ -234,7 +234,7 @@ at (anonymous) (0:17):
- scope (global): - scope (global):
-- skipped -- skipped
Debugger.stepInto called Debugger.stepInto called
Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:6:6: >i32.sub Paused at wasm://wasm/wasm-18214bfe/wasm-18214bfe-1:6:6: >i32.sub
at wasm_B (6:6): at wasm_B (6:6):
- scope (global): - scope (global):
-- skipped -- skipped
...@@ -245,7 +245,7 @@ at (anonymous) (0:17): ...@@ -245,7 +245,7 @@ at (anonymous) (0:17):
- scope (global): - scope (global):
-- skipped -- skipped
Debugger.stepInto called Debugger.stepInto called
Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:7:6: >local.set 0 Paused at wasm://wasm/wasm-18214bfe/wasm-18214bfe-1:7:6: >local.set 0
at wasm_B (7:6): at wasm_B (7:6):
- scope (global): - scope (global):
-- skipped -- skipped
...@@ -256,7 +256,7 @@ at (anonymous) (0:17): ...@@ -256,7 +256,7 @@ at (anonymous) (0:17):
- scope (global): - scope (global):
-- skipped -- skipped
Debugger.stepInto called Debugger.stepInto called
Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:8:6: >call 0 Paused at wasm://wasm/wasm-18214bfe/wasm-18214bfe-1:8:6: >call 0
at wasm_B (8:6): at wasm_B (8:6):
- scope (global): - scope (global):
-- skipped -- skipped
...@@ -267,7 +267,7 @@ at (anonymous) (0:17): ...@@ -267,7 +267,7 @@ at (anonymous) (0:17):
- scope (global): - scope (global):
-- skipped -- skipped
Debugger.stepInto called Debugger.stepInto called
Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-0:1:2: >nop Paused at wasm://wasm/wasm-18214bfe/wasm-18214bfe-0:1:2: >nop
at wasm_A (1:2): at wasm_A (1:2):
- scope (global): - scope (global):
-- skipped -- skipped
...@@ -283,7 +283,7 @@ at (anonymous) (0:17): ...@@ -283,7 +283,7 @@ at (anonymous) (0:17):
- scope (global): - scope (global):
-- skipped -- skipped
Debugger.stepInto called Debugger.stepInto called
Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-0:2:2: >nop Paused at wasm://wasm/wasm-18214bfe/wasm-18214bfe-0:2:2: >nop
at wasm_A (2:2): at wasm_A (2:2):
- scope (global): - scope (global):
-- skipped -- skipped
...@@ -299,7 +299,7 @@ at (anonymous) (0:17): ...@@ -299,7 +299,7 @@ at (anonymous) (0:17):
- scope (global): - scope (global):
-- skipped -- skipped
Debugger.stepInto called Debugger.stepInto called
Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-0:3:0: >end Paused at wasm://wasm/wasm-18214bfe/wasm-18214bfe-0:3:0: >end
at wasm_A (3:0): at wasm_A (3:0):
- scope (global): - scope (global):
-- skipped -- skipped
...@@ -315,7 +315,7 @@ at (anonymous) (0:17): ...@@ -315,7 +315,7 @@ at (anonymous) (0:17):
- scope (global): - scope (global):
-- skipped -- skipped
Debugger.stepInto called Debugger.stepInto called
Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:9:6: >br 1 Paused at wasm://wasm/wasm-18214bfe/wasm-18214bfe-1:9:6: >br 1
at wasm_B (9:6): at wasm_B (9:6):
- scope (global): - scope (global):
-- skipped -- skipped
......
Tests stepping through wasm scripts with source maps Tests stepping through wasm scripts with source maps
Installing code an global variable and instantiate. Installing code an global variable and instantiate.
Got wasm script: wasm://wasm/wasm-9b4bf87e Got wasm script: wasm://wasm/wasm-3697f0fe
Script sourceMapURL: abc Script sourceMapURL: abc
Requesting source for wasm://wasm/wasm-9b4bf87e... Requesting source for wasm://wasm/wasm-3697f0fe...
Source retrieved without error: true Source retrieved without error: true
Setting breakpoint on offset 54 (on the setlocal before the call), url wasm://wasm/wasm-9b4bf87e Setting breakpoint on offset 54 (on the setlocal before the call), url wasm://wasm/wasm-3697f0fe
{ {
columnNumber : 54 columnNumber : 54
lineNumber : 0 lineNumber : 0
scriptId : <scriptId> scriptId : <scriptId>
} }
Paused at wasm://wasm/wasm-9b4bf87e:0:54 Paused at wasm://wasm/wasm-3697f0fe:0:54
at wasm_B (0:54): at wasm_B (0:54):
- scope (global): - scope (global):
-- skipped -- skipped
...@@ -21,7 +21,7 @@ at (anonymous) (0:17): ...@@ -21,7 +21,7 @@ at (anonymous) (0:17):
- scope (global): - scope (global):
-- skipped -- skipped
Debugger.stepInto called Debugger.stepInto called
Paused at wasm://wasm/wasm-9b4bf87e:0:56 Paused at wasm://wasm/wasm-3697f0fe:0:56
at wasm_B (0:56): at wasm_B (0:56):
- scope (global): - scope (global):
-- skipped -- skipped
...@@ -32,7 +32,7 @@ at (anonymous) (0:17): ...@@ -32,7 +32,7 @@ at (anonymous) (0:17):
- scope (global): - scope (global):
-- skipped -- skipped
Debugger.stepInto called Debugger.stepInto called
Paused at wasm://wasm/wasm-9b4bf87e:0:38 Paused at wasm://wasm/wasm-3697f0fe:0:38
at wasm_A (0:38): at wasm_A (0:38):
- scope (global): - scope (global):
-- skipped -- skipped
...@@ -48,7 +48,7 @@ at (anonymous) (0:17): ...@@ -48,7 +48,7 @@ at (anonymous) (0:17):
- scope (global): - scope (global):
-- skipped -- skipped
Debugger.stepOver called Debugger.stepOver called
Paused at wasm://wasm/wasm-9b4bf87e:0:39 Paused at wasm://wasm/wasm-3697f0fe:0:39
at wasm_A (0:39): at wasm_A (0:39):
- scope (global): - scope (global):
-- skipped -- skipped
...@@ -64,7 +64,7 @@ at (anonymous) (0:17): ...@@ -64,7 +64,7 @@ at (anonymous) (0:17):
- scope (global): - scope (global):
-- skipped -- skipped
Debugger.stepOut called Debugger.stepOut called
Paused at wasm://wasm/wasm-9b4bf87e:0:58 Paused at wasm://wasm/wasm-3697f0fe:0:58
at wasm_B (0:58): at wasm_B (0:58):
- scope (global): - scope (global):
-- skipped -- skipped
...@@ -75,7 +75,7 @@ at (anonymous) (0:17): ...@@ -75,7 +75,7 @@ at (anonymous) (0:17):
- scope (global): - scope (global):
-- skipped -- skipped
Debugger.stepOut called Debugger.stepOut called
Paused at wasm://wasm/wasm-9b4bf87e:0:54 Paused at wasm://wasm/wasm-3697f0fe:0:54
at wasm_B (0:54): at wasm_B (0:54):
- scope (global): - scope (global):
-- skipped -- skipped
...@@ -86,7 +86,7 @@ at (anonymous) (0:17): ...@@ -86,7 +86,7 @@ at (anonymous) (0:17):
- scope (global): - scope (global):
-- skipped -- skipped
Debugger.stepOver called Debugger.stepOver called
Paused at wasm://wasm/wasm-9b4bf87e:0:56 Paused at wasm://wasm/wasm-3697f0fe:0:56
at wasm_B (0:56): at wasm_B (0:56):
- scope (global): - scope (global):
-- skipped -- skipped
...@@ -97,7 +97,7 @@ at (anonymous) (0:17): ...@@ -97,7 +97,7 @@ at (anonymous) (0:17):
- scope (global): - scope (global):
-- skipped -- skipped
Debugger.stepOver called Debugger.stepOver called
Paused at wasm://wasm/wasm-9b4bf87e:0:58 Paused at wasm://wasm/wasm-3697f0fe:0:58
at wasm_B (0:58): at wasm_B (0:58):
- scope (global): - scope (global):
-- skipped -- skipped
...@@ -108,7 +108,7 @@ at (anonymous) (0:17): ...@@ -108,7 +108,7 @@ at (anonymous) (0:17):
- scope (global): - scope (global):
-- skipped -- skipped
Debugger.resume called Debugger.resume called
Paused at wasm://wasm/wasm-9b4bf87e:0:54 Paused at wasm://wasm/wasm-3697f0fe:0:54
at wasm_B (0:54): at wasm_B (0:54):
- scope (global): - scope (global):
-- skipped -- skipped
...@@ -119,7 +119,7 @@ at (anonymous) (0:17): ...@@ -119,7 +119,7 @@ at (anonymous) (0:17):
- scope (global): - scope (global):
-- skipped -- skipped
Debugger.stepInto called Debugger.stepInto called
Paused at wasm://wasm/wasm-9b4bf87e:0:56 Paused at wasm://wasm/wasm-3697f0fe:0:56
at wasm_B (0:56): at wasm_B (0:56):
- scope (global): - scope (global):
-- skipped -- skipped
...@@ -130,7 +130,7 @@ at (anonymous) (0:17): ...@@ -130,7 +130,7 @@ at (anonymous) (0:17):
- scope (global): - scope (global):
-- skipped -- skipped
Debugger.stepInto called Debugger.stepInto called
Paused at wasm://wasm/wasm-9b4bf87e:0:38 Paused at wasm://wasm/wasm-3697f0fe:0:38
at wasm_A (0:38): at wasm_A (0:38):
- scope (global): - scope (global):
-- skipped -- skipped
...@@ -146,7 +146,7 @@ at (anonymous) (0:17): ...@@ -146,7 +146,7 @@ at (anonymous) (0:17):
- scope (global): - scope (global):
-- skipped -- skipped
Debugger.stepOut called Debugger.stepOut called
Paused at wasm://wasm/wasm-9b4bf87e:0:58 Paused at wasm://wasm/wasm-3697f0fe:0:58
at wasm_B (0:58): at wasm_B (0:58):
- scope (global): - scope (global):
-- skipped -- skipped
...@@ -157,7 +157,7 @@ at (anonymous) (0:17): ...@@ -157,7 +157,7 @@ at (anonymous) (0:17):
- scope (global): - scope (global):
-- skipped -- skipped
Debugger.stepInto called Debugger.stepInto called
Paused at wasm://wasm/wasm-9b4bf87e:0:43 Paused at wasm://wasm/wasm-3697f0fe:0:43
at wasm_B (0:43): at wasm_B (0:43):
- scope (global): - scope (global):
-- skipped -- skipped
...@@ -168,7 +168,7 @@ at (anonymous) (0:17): ...@@ -168,7 +168,7 @@ at (anonymous) (0:17):
- scope (global): - scope (global):
-- skipped -- skipped
Debugger.stepInto called Debugger.stepInto called
Paused at wasm://wasm/wasm-9b4bf87e:0:45 Paused at wasm://wasm/wasm-3697f0fe:0:45
at wasm_B (0:45): at wasm_B (0:45):
- scope (global): - scope (global):
-- skipped -- skipped
...@@ -179,7 +179,7 @@ at (anonymous) (0:17): ...@@ -179,7 +179,7 @@ at (anonymous) (0:17):
- scope (global): - scope (global):
-- skipped -- skipped
Debugger.stepInto called Debugger.stepInto called
Paused at wasm://wasm/wasm-9b4bf87e:0:47 Paused at wasm://wasm/wasm-3697f0fe:0:47
at wasm_B (0:47): at wasm_B (0:47):
- scope (global): - scope (global):
-- skipped -- skipped
...@@ -190,7 +190,7 @@ at (anonymous) (0:17): ...@@ -190,7 +190,7 @@ at (anonymous) (0:17):
- scope (global): - scope (global):
-- skipped -- skipped
Debugger.stepInto called Debugger.stepInto called
Paused at wasm://wasm/wasm-9b4bf87e:0:49 Paused at wasm://wasm/wasm-3697f0fe:0:49
at wasm_B (0:49): at wasm_B (0:49):
- scope (global): - scope (global):
-- skipped -- skipped
...@@ -201,7 +201,7 @@ at (anonymous) (0:17): ...@@ -201,7 +201,7 @@ at (anonymous) (0:17):
- scope (global): - scope (global):
-- skipped -- skipped
Debugger.stepInto called Debugger.stepInto called
Paused at wasm://wasm/wasm-9b4bf87e:0:51 Paused at wasm://wasm/wasm-3697f0fe:0:51
at wasm_B (0:51): at wasm_B (0:51):
- scope (global): - scope (global):
-- skipped -- skipped
...@@ -212,7 +212,7 @@ at (anonymous) (0:17): ...@@ -212,7 +212,7 @@ at (anonymous) (0:17):
- scope (global): - scope (global):
-- skipped -- skipped
Debugger.stepInto called Debugger.stepInto called
Paused at wasm://wasm/wasm-9b4bf87e:0:53 Paused at wasm://wasm/wasm-3697f0fe:0:53
at wasm_B (0:53): at wasm_B (0:53):
- scope (global): - scope (global):
-- skipped -- skipped
...@@ -223,7 +223,7 @@ at (anonymous) (0:17): ...@@ -223,7 +223,7 @@ at (anonymous) (0:17):
- scope (global): - scope (global):
-- skipped -- skipped
Debugger.stepInto called Debugger.stepInto called
Paused at wasm://wasm/wasm-9b4bf87e:0:54 Paused at wasm://wasm/wasm-3697f0fe:0:54
at wasm_B (0:54): at wasm_B (0:54):
- scope (global): - scope (global):
-- skipped -- skipped
...@@ -234,7 +234,7 @@ at (anonymous) (0:17): ...@@ -234,7 +234,7 @@ at (anonymous) (0:17):
- scope (global): - scope (global):
-- skipped -- skipped
Debugger.stepInto called Debugger.stepInto called
Paused at wasm://wasm/wasm-9b4bf87e:0:56 Paused at wasm://wasm/wasm-3697f0fe:0:56
at wasm_B (0:56): at wasm_B (0:56):
- scope (global): - scope (global):
-- skipped -- skipped
...@@ -245,7 +245,7 @@ at (anonymous) (0:17): ...@@ -245,7 +245,7 @@ at (anonymous) (0:17):
- scope (global): - scope (global):
-- skipped -- skipped
Debugger.stepInto called Debugger.stepInto called
Paused at wasm://wasm/wasm-9b4bf87e:0:38 Paused at wasm://wasm/wasm-3697f0fe:0:38
at wasm_A (0:38): at wasm_A (0:38):
- scope (global): - scope (global):
-- skipped -- skipped
...@@ -261,7 +261,7 @@ at (anonymous) (0:17): ...@@ -261,7 +261,7 @@ at (anonymous) (0:17):
- scope (global): - scope (global):
-- skipped -- skipped
Debugger.stepInto called Debugger.stepInto called
Paused at wasm://wasm/wasm-9b4bf87e:0:39 Paused at wasm://wasm/wasm-3697f0fe:0:39
at wasm_A (0:39): at wasm_A (0:39):
- scope (global): - scope (global):
-- skipped -- skipped
...@@ -277,7 +277,7 @@ at (anonymous) (0:17): ...@@ -277,7 +277,7 @@ at (anonymous) (0:17):
- scope (global): - scope (global):
-- skipped -- skipped
Debugger.stepInto called Debugger.stepInto called
Paused at wasm://wasm/wasm-9b4bf87e:0:40 Paused at wasm://wasm/wasm-3697f0fe:0:40
at wasm_A (0:40): at wasm_A (0:40):
- scope (global): - scope (global):
-- skipped -- skipped
...@@ -293,7 +293,7 @@ at (anonymous) (0:17): ...@@ -293,7 +293,7 @@ at (anonymous) (0:17):
- scope (global): - scope (global):
-- skipped -- skipped
Debugger.stepInto called Debugger.stepInto called
Paused at wasm://wasm/wasm-9b4bf87e:0:58 Paused at wasm://wasm/wasm-3697f0fe:0:58
at wasm_B (0:58): at wasm_B (0:58):
- scope (global): - scope (global):
-- skipped -- skipped
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment