# Default arch variant for MIPS.
'mips_arch_variant%': 'mips32r2',
- 'v8_enable_latin_1%': 1,
-
'v8_enable_debugger_support%': 1,
'v8_enable_backtrace%': 0,
},
'target_defaults': {
'conditions': [
- ['v8_enable_latin_1==1', {
- 'defines': ['ENABLE_LATIN_1',],
- }],
['v8_enable_debugger_support==1', {
'defines': ['ENABLE_DEBUGGER_SUPPORT',],
}],
#ifndef V8_H_
#define V8_H_
-// TODO(dcarney): Remove once Latin-1 transitions in WebKit has stuck.
-#define V8_ONE_BYTE_STRINGS_ENABLED 1
-
#include "v8stdint.h"
#ifdef _WIN32
__ b(ne, &fail);
__ sub(r3, r3, Operand('a'));
__ cmp(r3, Operand('z' - 'a')); // Is r3 a lowercase letter?
-#ifndef ENABLE_LATIN_1
- __ b(hi, &fail);
-#else
__ b(ls, &loop_check); // In range 'a'-'z'.
// Latin-1: Check for values in range [224,254] but not 247.
__ sub(r3, r3, Operand(224 - 'a'));
__ b(hi, &fail); // Weren't Latin-1 letters.
__ cmp(r3, Operand(247 - 224)); // Check for 247.
__ b(eq, &fail);
-#endif
__ bind(&loop_check);
__ cmp(r0, r1);
// TODO(yangguo): check that the object is indeed an external string.
ASSERT(heap_->InNewSpace(obj));
ASSERT(obj != HEAP->the_hole_value());
-#ifndef ENABLE_LATIN_1
- if (obj->IsExternalAsciiString()) {
- ExternalAsciiString* string = ExternalAsciiString::cast(obj);
- ASSERT(String::IsAscii(string->GetChars(), string->length()));
- }
-#endif
}
for (int i = 0; i < old_space_strings_.length(); ++i) {
Object* obj = Object::cast(old_space_strings_[i]);
// TODO(yangguo): check that the object is indeed an external string.
ASSERT(!heap_->InNewSpace(obj));
ASSERT(obj != HEAP->the_hole_value());
-#ifndef ENABLE_LATIN_1
- if (obj->IsExternalAsciiString()) {
- ExternalAsciiString* string = ExternalAsciiString::cast(obj);
- ASSERT(String::IsAscii(string->GetChars(), string->length()));
- }
-#endif
}
#endif
}
return Failure::OutOfMemoryException(0x5);
}
-#ifndef ENABLE_LATIN_1
- ASSERT(String::IsAscii(resource->data(), static_cast<int>(length)));
-#endif // ENABLE_LATIN_1
-
Map* map = external_ascii_string_map();
Object* result;
{ MaybeObject* maybe_result = Allocate(map, NEW_SPACE);
String::cast(result)->set_hash_field(String::kEmptyHashField);
ASSERT_EQ(size, HeapObject::cast(result)->Size());
-#ifndef ENABLE_LATIN_1
-#ifdef VERIFY_HEAP
- if (FLAG_verify_heap) {
- // Initialize string's content to ensure ASCII-ness (character range 0-127)
- // as required when verifying the heap.
- uint8_t* dest = SeqOneByteString::cast(result)->GetChars();
- memset(dest, 0x0F, length * kCharSize);
- }
-#endif
-#endif
-
return result;
}
// Compare lengths - strings up to min-length are equal.
__ bind(&compare_lengths);
__ test(length_delta, length_delta);
-#ifndef ENABLE_LATIN_1
- __ j(not_zero, &result_not_equal, Label::kNear);
-#else
Label length_not_equal;
__ j(not_zero, &length_not_equal, Label::kNear);
-#endif
// Result is EQUAL.
STATIC_ASSERT(EQUAL == 0);
__ ret(0);
Label result_greater;
-#ifdef ENABLE_LATIN_1
Label result_less;
__ bind(&length_not_equal);
__ j(greater, &result_greater, Label::kNear);
__ jmp(&result_less, Label::kNear);
-#endif
__ bind(&result_not_equal);
-#ifndef ENABLE_LATIN_1
- __ j(greater, &result_greater, Label::kNear);
-#else
__ j(above, &result_greater, Label::kNear);
__ bind(&result_less);
-#endif
// Result is LESS.
__ Set(eax, Immediate(Smi::FromInt(LESS)));
__ or_(eax, 0x20); // Convert match character to lower-case.
__ lea(ecx, Operand(eax, -'a'));
__ cmp(ecx, static_cast<int32_t>('z' - 'a')); // Is eax a lowercase letter?
-#ifndef ENABLE_LATIN_1
- __ j(above, &fail); // Weren't letters anyway.
-#else
Label convert_capture;
__ j(below_equal, &convert_capture); // In range 'a'-'z'.
// Latin-1: Check for values in range [224,254] but not 247.
__ cmp(ecx, Immediate(247 - 224)); // Check for 247.
__ j(equal, &fail);
__ bind(&convert_capture);
-#endif
// Also convert capture character.
__ movzx_b(ecx, Operand(edx, 0));
__ or_(ecx, 0x20);
// For 2-character preloads in ASCII mode or 1-character preloads in
// TWO_BYTE mode we also use a 16 bit load with zero extend.
if (details->characters() == 2 && compiler->ascii()) {
-#ifndef ENABLE_LATIN_1
- if ((mask & 0x7f7f) == 0xffff) need_mask = false;
-#else
if ((mask & 0xffff) == 0xffff) need_mask = false;
-#endif
} else if (details->characters() == 1 && !compiler->ascii()) {
if ((mask & 0xffff) == 0xffff) need_mask = false;
} else {
// We need to check for the following characters: 0x39c 0x3bc 0x178.
static inline bool RangeContainsLatin1Equivalents(CharacterRange range) {
-#ifdef ENABLE_LATIN_1
// TODO(dcarney): this could be a lot more efficient.
return range.Contains(0x39c) ||
range.Contains(0x3bc) || range.Contains(0x178);
-#else
- return false;
-#endif
}
-#ifdef ENABLE_LATIN_1
static bool RangesContainLatin1Equivalents(ZoneList<CharacterRange>* ranges) {
for (int i = 0; i < ranges->length(); i++) {
// TODO(dcarney): this could be a lot more efficient.
}
return false;
}
-#endif
RegExpNode* TextNode::FilterASCII(int depth, bool ignore_case) {
if (elm.type == TextElement::ATOM) {
Vector<const uc16> quarks = elm.data.u_atom->data();
for (int j = 0; j < quarks.length(); j++) {
-#ifndef ENABLE_LATIN_1
- if (quarks[j] > String::kMaxOneByteCharCode) {
- return set_replacement(NULL);
- }
-#else
uint16_t c = quarks[j];
if (c <= String::kMaxOneByteCharCode) continue;
if (!ignore_case) return set_replacement(NULL);
// Convert quark to Latin-1 in place.
uint16_t* copy = const_cast<uint16_t*>(quarks.start());
copy[j] = converted;
-#endif
}
} else {
ASSERT(elm.type == TextElement::CHAR_CLASS);
if (range_count != 0 &&
ranges->at(0).from() == 0 &&
ranges->at(0).to() >= String::kMaxOneByteCharCode) {
-#ifdef ENABLE_LATIN_1
// This will be handled in a later filter.
if (ignore_case && RangesContainLatin1Equivalents(ranges)) continue;
-#endif
return set_replacement(NULL);
}
} else {
if (range_count == 0 ||
ranges->at(0).from() > String::kMaxOneByteCharCode) {
-#ifdef ENABLE_LATIN_1
// This will be handled in a later filter.
if (ignore_case && RangesContainLatin1Equivalents(ranges)) continue;
-#endif
return set_replacement(NULL);
}
}
__ Or(t0, t0, Operand(0x20)); // Also convert input character.
__ Branch(&fail, ne, t0, Operand(a3));
__ Subu(a3, a3, Operand('a'));
-#ifndef ENABLE_LATIN_1
- __ Branch(&fail, hi, a3, Operand('z' - 'a')); // Is a3 a lowercase letter?
-#else
__ Branch(&loop_check, ls, a3, Operand('z' - 'a'));
// Latin-1: Check for values in range [224,254] but not 247.
__ Subu(a3, a3, Operand(224 - 'a'));
__ Branch(&fail, hi, a3, Operand(254 - 224));
// Check for 247.
__ Branch(&fail, eq, a3, Operand(247 - 224));
-#endif
__ bind(&loop_check);
__ Branch(&loop, lt, a0, Operand(a1));
ConsString::cast(this)->ConsStringVerify();
} else if (IsSlicedString()) {
SlicedString::cast(this)->SlicedStringVerify();
- } else if (IsSeqOneByteString()) {
- SeqOneByteString::cast(this)->SeqOneByteStringVerify();
}
}
-void SeqOneByteString::SeqOneByteStringVerify() {
-#ifndef ENABLE_LATIN_1
- CHECK(String::IsAscii(GetChars(), length()));
-#endif
-}
-
-
void ConsString::ConsStringVerify() {
CHECK(this->first()->IsString());
CHECK(this->second() == GetHeap()->empty_string() ||
bool String::HasOnlyAsciiChars() {
uint32_t type = map()->instance_type();
-#ifndef ENABLE_LATIN_1
- return (type & kStringEncodingMask) == kOneByteStringTag ||
- (type & kAsciiDataHintMask) == kAsciiDataHintTag;
-#else
return (type & kAsciiDataHintMask) == kAsciiDataHintTag;
-#endif
}
// Q.v. String::kMaxLength which is the maximal size of concatenated strings.
static const int kMaxLength = (kMaxSize - kHeaderSize);
- DECLARE_VERIFIER(SeqOneByteString)
-
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(SeqOneByteString);
};
namespace {
static const uintptr_t kOneInEveryByte = kUintptrAllBitsSet / 0xFF;
-#ifdef ENABLE_LATIN_1
static const uintptr_t kAsciiMask = kOneInEveryByte << 7;
-#endif
// Given a word and two range boundaries returns a word with high bit
// set in every byte iff the corresponding input byte was strictly in
// Use strict inequalities since in edge cases the function could be
// further simplified.
ASSERT(0 < m && m < n);
-#ifndef ENABLE_LATIN_1
- // Every byte in an ASCII string is less than or equal to 0x7F.
- ASSERT((w & (kOneInEveryByte * 0x7F)) == w);
- ASSERT(n < 0x7F);
-#endif
// Has high bit set in every w byte less than n.
uintptr_t tmp1 = kOneInEveryByte * (0x7F + n) - w;
// Has high bit set in every w byte greater than m.
template <AsciiCaseConversion dir>
struct FastAsciiConverter {
-#ifdef ENABLE_LATIN_1
static bool Convert(char* dst, char* src, int length, bool* changed_out) {
-#else
- static bool Convert(char* dst, char* src, int length) {
-#endif
#ifdef DEBUG
char* saved_dst = dst;
char* saved_src = src;
const char lo = (dir == ASCII_TO_LOWER) ? 'A' - 1 : 'a' - 1;
const char hi = (dir == ASCII_TO_LOWER) ? 'Z' + 1 : 'z' + 1;
bool changed = false;
-#ifdef ENABLE_LATIN_1
uintptr_t or_acc = 0;
-#endif
char* const limit = src + length;
#ifdef V8_HOST_CAN_READ_UNALIGNED
// Process the prefix of the input that requires no conversion one
// (machine) word at a time.
while (src <= limit - sizeof(uintptr_t)) {
uintptr_t w = *reinterpret_cast<uintptr_t*>(src);
-#ifdef ENABLE_LATIN_1
or_acc |= w;
-#endif
if (AsciiRangeMask(w, lo, hi) != 0) {
changed = true;
break;
// required one word at a time.
while (src <= limit - sizeof(uintptr_t)) {
uintptr_t w = *reinterpret_cast<uintptr_t*>(src);
-#ifdef ENABLE_LATIN_1
or_acc |= w;
-#endif
uintptr_t m = AsciiRangeMask(w, lo, hi);
// The mask has high (7th) bit set in every byte that needs
// conversion and we know that the distance between cases is
// unaligned access is not supported).
while (src < limit) {
char c = *src;
-#ifdef ENABLE_LATIN_1
or_acc |= c;
-#endif
if (lo < c && c < hi) {
c ^= (1 << 5);
changed = true;
++src;
++dst;
}
-#ifdef ENABLE_LATIN_1
if ((or_acc & kAsciiMask) != 0) {
return false;
}
-#endif
#ifdef DEBUG
CheckConvert(saved_dst, saved_src, length, changed);
#endif
-#ifdef ENABLE_LATIN_1
*changed_out = changed;
return true;
-#else
- return changed;
-#endif
}
#ifdef DEBUG
if (!maybe_o->ToObject(&o)) return maybe_o;
}
SeqOneByteString* result = SeqOneByteString::cast(o);
-#ifndef ENABLE_LATIN_1
- bool has_changed_character = ConvertTraits::AsciiConverter::Convert(
- reinterpret_cast<char*>(result->GetChars()),
- reinterpret_cast<char*>(SeqOneByteString::cast(s)->GetChars()),
- length);
- return has_changed_character ? result : s;
-#else
bool has_changed_character;
bool is_ascii = ConvertTraits::AsciiConverter::Convert(
reinterpret_cast<char*>(result->GetChars()),
if (is_ascii) {
return has_changed_character ? result : s;
}
-#endif
}
Object* answer;
// a potentially less efficient searching, but is a safe approximation.
// For needles using only characters in the same Unicode 256-code point page,
// there is no search speed degradation.
-#ifndef ENABLE_LATIN_1
- static const int kAsciiAlphabetSize = 128;
-#else
static const int kAsciiAlphabetSize = 256;
-#endif
static const int kUC16AlphabetSize = Isolate::kUC16AlphabetSize;
// Bad-char shift table stored in the state. It's length is the alphabet size.
void PopulateBoyerMooreTable();
static inline bool exceedsOneByte(uint8_t c) {
-#ifdef ENABLE_LATIN_1
return false;
-#else
- return c > String::kMaxOneByteCharCodeU;
-#endif
}
static inline bool exceedsOneByte(uint16_t c) {
class Latin1 {
public:
-#ifndef ENABLE_LATIN_1
- static const unsigned kMaxChar = 0x7f;
-#else
static const unsigned kMaxChar = 0xff;
-#endif
// Returns 0 if character does not convert to single latin-1 character
// or if the character doesn't not convert back to latin-1 via inverse
// operation (upper to lower, etc).
// Compare lengths (precomputed).
__ bind(&compare_lengths);
__ SmiTest(length_difference);
-#ifndef ENABLE_LATIN_1
- __ j(not_zero, &result_not_equal, Label::kNear);
-#else
Label length_not_equal;
__ j(not_zero, &length_not_equal, Label::kNear);
-#endif
// Result is EQUAL.
__ Move(rax, Smi::FromInt(EQUAL));
__ ret(0);
Label result_greater;
-#ifdef ENABLE_LATIN_1
Label result_less;
__ bind(&length_not_equal);
__ j(greater, &result_greater, Label::kNear);
__ jmp(&result_less, Label::kNear);
-#endif
__ bind(&result_not_equal);
// Unequal comparison of left to right, either character or length.
-#ifndef ENABLE_LATIN_1
- __ j(greater, &result_greater, Label::kNear);
-#else
__ j(above, &result_greater, Label::kNear);
__ bind(&result_less);
-#endif
// Result is LESS.
__ Move(rax, Smi::FromInt(LESS));
__ j(not_equal, on_no_match); // Definitely not equal.
__ subb(rax, Immediate('a'));
__ cmpb(rax, Immediate('z' - 'a'));
-#ifndef ENABLE_LATIN_1
- __ j(above, on_no_match); // Weren't letters anyway.
-#else
__ j(below_equal, &loop_increment); // In range 'a'-'z'.
// Latin-1: Check for values in range [224,254] but not 247.
__ subb(rax, Immediate(224 - 'a'));
__ j(above, on_no_match); // Weren't Latin-1 letters.
__ cmpb(rax, Immediate(247 - 224)); // Check for 247.
__ j(equal, on_no_match);
-#endif
__ bind(&loop_increment);
// Increment pointers into match and capture strings.
__ addq(r11, Immediate(1));
Local<v8::String>::Cast(a->Get(i));
Local<v8::Number> expected_len =
Local<v8::Number>::Cast(alens->Get(i));
-#ifndef ENABLE_LATIN_1
- CHECK_EQ(expected_len->Value() != string->Length(),
- string->MayContainNonAscii());
-#endif
int length = GetUtf8Length(string);
CHECK_EQ(static_cast<int>(expected_len->Value()), length);
}
"var slice = lhs.substring(1, lhs.length - 1);"
"var slice_on_cons = (lhs + rhs).substring(1, lhs.length *2 - 1);");
-#ifndef ENABLE_LATIN_1
- CHECK(!lhs->MayContainNonAscii());
- CHECK(!rhs->MayContainNonAscii());
-#endif
+ CHECK(lhs->IsOneByte());
+ CHECK(rhs->IsOneByte());
MorphAString(*v8::Utils::OpenHandle(*lhs), &ascii_resource, &uc16_resource);
MorphAString(*v8::Utils::OpenHandle(*rhs), &ascii_resource, &uc16_resource);
-#ifdef ENABLE_LATIN_1
template<typename Op, bool return_first>
static uint16_t ConvertLatin1(uint16_t c) {
uint32_t result[Op::kMaxWidth];
TEST(Latin1IgnoreCase) {
- if (true) return;
using namespace unibrow;
for (uint16_t c = Latin1::kMaxChar + 1; c != 0; c++) {
uint16_t lower = ConvertLatin1<ToLowercase, false>(c);
CHECK_EQ(Min(upper, lower), test);
}
}
-#endif // ENABLE_LATIN_1