%PDF- %PDF-
Direktori : /home/vacivi36/vittasync.vacivitta.com.br/vittasync/node/deps/v8/src/objects/ |
Current File : /home/vacivi36/vittasync.vacivitta.com.br/vittasync/node/deps/v8/src/objects/intl-objects.tq |
// Copyright 2019 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include 'src/objects/js-objects.h' #include 'src/objects/intl-objects.h' extern macro IntlAsciiCollationWeightsL1(): RawPtr<uint8>; extern macro IntlAsciiCollationWeightsL3(): RawPtr<uint8>; const kIntlAsciiCollationWeightsLength: constexpr int31 generates 'Intl::kAsciiCollationWeightsLength'; macro IntlAsciiCollationWeightL1(c: char8): uint8 labels _Bailout { static_assert(kIntlAsciiCollationWeightsLength == 256); return IntlAsciiCollationWeightsL1()[Convert<intptr>(c)]; } macro IntlAsciiCollationWeightL1(c: char16): uint8 labels Bailout { if (Convert<uint32>(c) >= kIntlAsciiCollationWeightsLength) goto Bailout; return IntlAsciiCollationWeightsL1()[Convert<intptr>(c)]; } macro IntlAsciiCollationWeightL3(c: char8): uint8 labels _Bailout { static_assert(kIntlAsciiCollationWeightsLength == 256); return IntlAsciiCollationWeightsL3()[Convert<intptr>(c)]; } macro IntlAsciiCollationWeightL3(c: char16): uint8 labels Bailout { if (Convert<uint32>(c) >= kIntlAsciiCollationWeightsLength) goto Bailout; return IntlAsciiCollationWeightsL3()[Convert<intptr>(c)]; } macro CheckEmptyOr1Byte( _it: torque_internal::SliceIterator<char8, const &char8>): void labels _Bailout { // char8 is always within 0xFF. } macro CheckEmptyOr1Byte( it: torque_internal::SliceIterator<char16, const &char16>): void labels Bailout { let it = it; if ((it.Next() otherwise return) > 0xFF) goto Bailout; } // This fast path works for ASCII-only strings and is based on the assumption // that most strings are either bytewise equal or differ on L1 (i.e., not just // in capitalization). So we first compare the strings on L1 and only afterwards // consider L3. This makes use of the 256-entry L1 and L3 tables defined in // src/objects/intl-objects.cc. macro LocaleCompareFastPath<T1: type, T2: type>( left: ConstSlice<T1>, right: ConstSlice<T2>): Number labels Bailout { if (EqualContent(left, right)) return 0; let leftIt = left.Iterator(); let rightIt = right.Iterator(); while (true) { try { const lChar = leftIt.Next() otherwise goto LeftExhausted; const leftWeight = IntlAsciiCollationWeightL1(lChar) otherwise Bailout; if (leftWeight == 0) goto Bailout; // If rightIt is exhausted, we already checked that the next char of the // left string has non-zero weight, so it cannot be ignorable or a // combining character. // Return 1 because right string is shorter and L1 is equal. const rChar = rightIt.Next() otherwise return 1; const rightWeight = IntlAsciiCollationWeightL1(rChar) otherwise Bailout; if (rightWeight == 0) goto Bailout; if (leftWeight == rightWeight) continue; // The result is only valid if the last processed character is not // followed by a unicode combining character (we are overly strict and // restrict to code points up to 0xFF). CheckEmptyOr1Byte(leftIt) otherwise Bailout; CheckEmptyOr1Byte(rightIt) otherwise Bailout; if (leftWeight < rightWeight) return -1; return 1; } label LeftExhausted { const rChar = rightIt.Next() otherwise break; const rightWeight = IntlAsciiCollationWeightL1(rChar) otherwise Bailout; // If the following character might be ignorable or a combining character, // we bail out because the strings might still be considered equal. if (rightWeight == 0) goto Bailout; // Return -1 because left string is shorter and L1 is equal. return -1; } } leftIt = left.Iterator(); rightIt = right.Iterator(); while (true) { const lChar = leftIt.Next() otherwise unreachable; const leftWeight = IntlAsciiCollationWeightL3(lChar) otherwise unreachable; dcheck(leftWeight != 0); const rChar = rightIt.Next() otherwise unreachable; const rightWeight = IntlAsciiCollationWeightL3(rChar) otherwise unreachable; dcheck(rightWeight != 0); dcheck( IntlAsciiCollationWeightL1(lChar) otherwise unreachable == IntlAsciiCollationWeightL1(rChar) otherwise unreachable); if (leftWeight == rightWeight) continue; if (leftWeight < rightWeight) return -1; return 1; } VerifiedUnreachable(); } transitioning builtin StringFastLocaleCompare( implicit context: Context)(localeCompareFn: JSFunction, left: JSAny, right: JSAny, locales: JSAny): JSAny { try { const left = Cast<String>(left) otherwise Bailout; if (TaggedEqual(left, right)) return SmiConstant(0); StringToSlice(left) otherwise LeftOneByte, LeftTwoByte; } label LeftOneByte(leftSlice: ConstSlice<char8>) { try { const right = Cast<String>(right) otherwise Bailout; StringToSlice(right) otherwise RightOneByte, RightTwoByte; } label RightOneByte(rightSlice: ConstSlice<char8>) { return LocaleCompareFastPath(leftSlice, rightSlice) otherwise Bailout; } label RightTwoByte(rightSlice: ConstSlice<char16>) { return LocaleCompareFastPath(leftSlice, rightSlice) otherwise Bailout; } } label LeftTwoByte(leftSlice: ConstSlice<char16>) { try { const right = Cast<String>(right) otherwise Bailout; StringToSlice(right) otherwise RightOneByte, RightTwoByte; } label RightOneByte(rightSlice: ConstSlice<char8>) { return LocaleCompareFastPath(leftSlice, rightSlice) otherwise Bailout; } label RightTwoByte(rightSlice: ConstSlice<char16>) { return LocaleCompareFastPath(leftSlice, rightSlice) otherwise Bailout; } } label Bailout deferred { return Call(context, localeCompareFn, left, right, locales); } }