13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2011 the V8 project authors. All rights reserved.
2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file.
4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifndef V8_UNICODE_H_
6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define V8_UNICODE_H_
7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include <sys/types.h>
9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/globals.h"
10958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/utils.h"
11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/**
12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * \file
13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * Definitions and convenience functions for working with unicode.
14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block */
15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace unibrow {
17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocktypedef unsigned int uchar;
19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocktypedef unsigned char byte;
20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/**
22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * The max length of the result of converting the case of a single
23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * character.
24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block */
253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kMaxMappingSize = 4;
26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocktemplate <class T, int size = 256>
28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Predicate {
29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline Predicate() { }
31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline bool get(uchar c);
32958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  friend class Test;
35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool CalculateValue(uchar c);
36958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  class CacheEntry {
37958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier   public:
38958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    inline CacheEntry()
39958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        : bit_field_(CodePointField::encode(0) | ValueField::encode(0)) {}
40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    inline CacheEntry(uchar code_point, bool value)
41958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        : bit_field_(CodePointField::encode(code_point) |
42958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                     ValueField::encode(value)) {}
43958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
44958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    uchar code_point() const { return CodePointField::decode(bit_field_); }
45958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    bool value() const { return ValueField::decode(bit_field_); }
46958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
47958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier   private:
48958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    class CodePointField : public v8::internal::BitField<uchar, 0, 21> {};
49958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    class ValueField : public v8::internal::BitField<bool, 21, 1> {};
50958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
51958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    uint32_t bit_field_;
52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  };
53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kSize = size;
54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kMask = kSize - 1;
55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CacheEntry entries_[kSize];
56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
58958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A cache used in case conversion.  It caches the value for characters
60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// that either have no mapping or map to a single character independent
61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// of context.  Characters that map to more than one character or that
62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// map differently depending on context are always looked up.
63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocktemplate <class T, int size = 256>
64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Mapping {
65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline Mapping() { }
67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline int get(uchar c, uchar n, uchar* result);
68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  friend class Test;
70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int CalculateValue(uchar c, uchar n, uchar* result);
71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  struct CacheEntry {
72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    inline CacheEntry() : code_point_(kNoChar), offset_(0) { }
73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    inline CacheEntry(uchar code_point, signed offset)
74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      : code_point_(code_point),
75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        offset_(offset) { }
76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    uchar code_point_;
77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    signed offset_;
78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    static const int kNoChar = (1 << 21) - 1;
79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  };
80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kSize = size;
81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kMask = kSize - 1;
82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CacheEntry entries_[kSize];
83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
85958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass UnicodeData {
87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  friend class Test;
89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static int GetByteCount();
9044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static const uchar kMaxCodePoint;
91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
93958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass Utf16 {
953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public:
96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static inline bool IsSurrogatePair(int lead, int trail) {
97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return IsLeadSurrogate(lead) && IsTrailSurrogate(trail);
98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static inline bool IsLeadSurrogate(int code) {
1003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (code == kNoPreviousCharacter) return false;
1013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return (code & 0xfc00) == 0xd800;
1023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
1033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static inline bool IsTrailSurrogate(int code) {
1043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (code == kNoPreviousCharacter) return false;
1053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return (code & 0xfc00) == 0xdc00;
1063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
1073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static inline int CombineSurrogatePair(uchar lead, uchar trail) {
1093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return 0x10000 + ((lead & 0x3ff) << 10) + (trail & 0x3ff);
1103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
1113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kNoPreviousCharacter = -1;
1123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const uchar kMaxNonSurrogateCharCode = 0xffff;
1133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Encoding a single UTF-16 code unit will produce 1, 2 or 3 bytes
1143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // of UTF-8 data.  The special case where the unit is a surrogate
1153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // trail produces 1 byte net, because the encoding of the pair is
1163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // 4 bytes and the 3 bytes that were used to encode the lead surrogate
1173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // can be reclaimed.
1183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kMaxExtraUtf8BytesForOneUtf16CodeUnit = 3;
1193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // One UTF-16 surrogate is endoded (illegally) as 3 UTF-8 bytes.
1203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // The illegality stems from the surrogate not being part of a pair.
1213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kUtf8BytesToCodeASurrogate = 3;
122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static inline uint16_t LeadSurrogate(uint32_t char_code) {
1233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return 0xd800 + (((char_code - 0x10000) >> 10) & 0x3ff);
1243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static inline uint16_t TrailSurrogate(uint32_t char_code) {
1263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return 0xdc00 + (char_code & 0x3ff);
1273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
1283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch};
1293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Utf8 {
132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
1333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static inline uchar Length(uchar chr, int previous);
134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static inline unsigned EncodeOneByte(char* out, uint8_t c);
135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static inline unsigned Encode(char* out,
136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                uchar c,
137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                int previous,
138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                bool replace_invalid = false);
139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static uchar CalculateValue(const byte* str, size_t length, size_t* cursor);
140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The unicode replacement character, used to signal invalid unicode
142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // sequences (e.g. an orphan surrogate) when converting to a UTF-8 encoding.
143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const uchar kBadChar = 0xFFFD;
144f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  static const uchar kBufferEmpty = 0x0;
145f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  static const uchar kIncomplete = 0xFFFFFFFC;  // any non-valid code point.
146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const unsigned kMaxEncodedSize   = 4;
147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const unsigned kMaxOneByteChar   = 0x7f;
148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const unsigned kMaxTwoByteChar   = 0x7ff;
149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const unsigned kMaxThreeByteChar = 0xffff;
150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const unsigned kMaxFourByteChar  = 0x1fffff;
151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // A single surrogate is coded as a 3 byte UTF-8 sequence, but two together
1533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // that match are coded as a 4 byte UTF-8 sequence.
1543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const unsigned kBytesSavedByCombiningSurrogates = 2;
1553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const unsigned kSizeOfUnmatchedSurrogate = 3;
156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The maximum size a single UTF-16 code unit may take up when encoded as
157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // UTF-8.
158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const unsigned kMax16BitCodeUnitSize  = 3;
159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static inline uchar ValueOf(const byte* str, size_t length, size_t* cursor);
160bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
161f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  typedef uint32_t Utf8IncrementalBuffer;
162f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  static uchar ValueOfIncremental(byte next_byte,
163f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                  Utf8IncrementalBuffer* buffer);
164f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  static uchar ValueOfIncrementalFinish(Utf8IncrementalBuffer* buffer);
165f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
166bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  // Excludes non-characters from the set of valid code points.
167bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  static inline bool IsValidCharacter(uchar c);
168bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
169bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  static bool Validate(const byte* str, size_t length);
170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstruct Uppercase {
173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static bool Is(uchar c);
174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstruct Lowercase {
176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static bool Is(uchar c);
177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstruct Letter {
179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static bool Is(uchar c);
180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
181c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochstruct V8_EXPORT_PRIVATE ID_Start {
182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static bool Is(uchar c);
183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
184c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochstruct V8_EXPORT_PRIVATE ID_Continue {
185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static bool Is(uchar c);
186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
187c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochstruct V8_EXPORT_PRIVATE WhiteSpace {
188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static bool Is(uchar c);
189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
190c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochstruct V8_EXPORT_PRIVATE LineTerminator {
191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static bool Is(uchar c);
192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstruct ToLowercase {
194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kMaxWidth = 3;
195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const bool kIsToLower = true;
196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static int Convert(uchar c,
197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                     uchar n,
198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                     uchar* result,
199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                     bool* allow_caching_ptr);
200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstruct ToUppercase {
202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kMaxWidth = 3;
203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const bool kIsToLower = false;
204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static int Convert(uchar c,
205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                     uchar n,
206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                     uchar* result,
207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                     bool* allow_caching_ptr);
208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstruct Ecma262Canonicalize {
210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kMaxWidth = 1;
211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static int Convert(uchar c,
212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                     uchar n,
213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                     uchar* result,
214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                     bool* allow_caching_ptr);
215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstruct Ecma262UnCanonicalize {
217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kMaxWidth = 4;
218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static int Convert(uchar c,
219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                     uchar n,
220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                     uchar* result,
221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                     bool* allow_caching_ptr);
222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstruct CanonicalizationRange {
224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kMaxWidth = 1;
225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static int Convert(uchar c,
226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                     uchar n,
227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                     uchar* result,
228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                     bool* allow_caching_ptr);
229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}  // namespace unibrow
232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif  // V8_UNICODE_H_
234