gecko-dev/js/js2/utilities.cpp

2551 строка
94 KiB
C++

// -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
//
// The contents of this file are subject to the Netscape Public
// License Version 1.1 (the "License"); you may not use this file
// except in compliance with the License. You may obtain a copy of
// the License at http://www.mozilla.org/NPL/
//
// Software distributed under the License is distributed on an "AS
// IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
// implied. See the License for the specific language governing
// rights and limitations under the License.
//
// The Original Code is the JavaScript 2 Prototype.
//
// The Initial Developer of the Original Code is Netscape
// Communications Corporation. Portions created by Netscape are
// Copyright (C) 1998 Netscape Communications Corporation. All
// Rights Reserved.
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include "utilities.h"
#ifdef WIN32
#include <windows.h>
#endif
#ifdef XP_MAC
#include <cstdarg>
#include <Types.h>
#endif
namespace JS = JavaScript;
//
// Assertions
//
#ifdef DEBUG
#ifdef XP_MAC
// PStrFromCStr converts the source C string to a destination
// pascal string as it copies. The dest string will
// be truncated to fit into an Str255 if necessary.
// If the C String pointer is NULL, the pascal string's length is
// set to zero.
static void PStrFromCStr(const char* src, Str255 &dst)
{
int length = 0;
if (src)
{
char *p = reinterpret_cast<char *>(&dst[1]);
int spaceLeft = 255;
char ch;
while ((ch = *src++) != 0) {
*p++ = ch;
if (--spaceLeft == 0)
break;
}
length = 255 - spaceLeft;
}
dst[0] = (uchar)length;
}
static void jsdebugstr(const char *debuggerMsg)
{
Str255 pStr;
PStrFromCStr(debuggerMsg, pStr);
DebugStr(pStr);
}
static void dprintf(const char *format, ...)
{
std::va_list ap;
char buffer[4096];
va_start(ap, format);
std::vsprintf(buffer, format, ap);
va_end(ap);
jsdebugstr(buffer);
}
#endif /* XP_MAC */
void JS::Assert(const char *s, const char *file, int line)
{
#if defined(XP_UNIX) || defined(XP_OS2)
fprintf(std::stderr, "Assertion failure: %s, at %s:%d\n", s, file, line);
#endif
#ifdef XP_MAC
dprintf("Assertion failure: %s, at %s:%d\n", s, file, line);
#endif
#ifdef WIN32
DebugBreak();
#endif
#ifndef XP_MAC
abort();
#endif
}
#endif /* DEBUG */
//
// Bit manipulation
//
// Return lg2 of the least power of 2 greater than or equal to n.
// Return 0 if n is 0 or 1.
uint JS::ceilingLog2(uint32 n)
{
uint log2 = 0;
if (n & (n-1))
log2++;
if (n >> 16)
log2 += 16, n >>= 16;
if (n >> 8)
log2 += 8, n >>= 8;
if (n >> 4)
log2 += 4, n >>= 4;
if (n >> 2)
log2 += 2, n >>= 2;
if (n >> 1)
log2++;
return log2;
}
// Return lg2 of the greatest power of 2 less than or equal to n.
// This really just finds the highest set bit in the word.
// Return 0 if n is 0 or 1.
uint JS::floorLog2(uint32 n)
{
uint log2 = 0;
if (n >> 16)
log2 += 16, n >>= 16;
if (n >> 8)
log2 += 8, n >>= 8;
if (n >> 4)
log2 += 4, n >>= 4;
if (n >> 2)
log2 += 2, n >>= 2;
if (n >> 1)
log2++;
return log2;
}
//
// Unicode UTF-16 characters and strings
//
#ifdef _WIN32 // Microsoft VC6 bug: String constructor and append limited to char16 iterators
// Return a String containing the characters of the null-terminated C string cstr
// (without the trailing null).
JS::String JS::widenCString(const char *cstr)
{
size_t len = strlen(cstr);
String s(len, uni::null);
std::transform(cstr, cstr+len, s.begin(), widen);
return s;
}
// Widen and append length characters starting at chars to the end of str.
void JS::appendChars(String &str, const char *chars, size_t length)
{
String::size_type strLen = str.size();
str.append(length, uni::null);
std::transform(chars, chars+length, str.begin()+strLen, widen);
}
// Widen and insert length characters starting at chars into the given position of str.
void JS::insertChars(String &str, String::size_type pos, const char *chars, size_t length)
{
str.insert(pos, length, uni::null);
std::transform(chars, chars+length, str.begin()+pos, widen);
}
#endif
// Widen and insert the null-terminated string cstr into the given position of str.
void JS::insertChars(String &str, String::size_type pos, const char *cstr)
{
insertChars(str, pos, cstr, strlen(cstr));
}
// Widen and append the null-terminated string cstr to the end of str.
// Return str.
JS::String &JS::operator+=(String &str, const char *cstr)
{
appendChars(str, cstr, strlen(cstr));
return str;
}
// Return the concatenation of str and the null-terminated string cstr.
JS::String JS::operator+(const String &str, const char *cstr)
{
return str + widenCString(cstr);
}
// Return the concatenation of the null-terminated string cstr and str.
JS::String JS::operator+(const char *cstr, const String &str)
{
String s = widenCString(cstr);
s += str;
return s;
}
// From java.lang.Character:
//
// The character properties are currently encoded into 32 bits in the
// following manner:
//
// 10 bits signed offset used for converting case
// 1 bit if 1, adding the signed offset converts the character to
// lowercase
// 1 bit if 1, subtracting the signed offset converts the character to
// uppercase
// 1 bit if 1, character has a titlecase equivalent (possibly itself)
// 3 bits 0 May not be part of an identifier
// 1 Format control
// 2 May start or continue a JS identifier (includes $ and _)
// 3 May continue a JS identifier
// 4 Behaves like a white space character (but not line break)
// 5 Behaves like a line break character
// 2 bits 0 this character has no numeric property
// 1 adding the digit offset to the character code and then
// masking with 0x1F will produce the desired numeric value
// 2 this character has a "strange" numeric value
// 3 a JS supradecimal digit: adding the digit offset to the
// character code, then masking with 0x1F, then adding 10
// will produce the desired numeric value
// 5 bits digit offset
// 4 bits reserved for future use
// 5 bits character type
// The X table has 1024 entries for a total of 1024 bytes.
const uint8 JS::CharInfo::x[] = {
0, 1, 2, 3, 4, 5, 6, 7, // 0x0000
8, 9, 10, 11, 12, 13, 14, 15, // 0x0200
16, 17, 18, 19, 20, 21, 22, 23, // 0x0400
24, 25, 26, 27, 28, 28, 28, 28, // 0x0600
28, 28, 28, 28, 29, 30, 31, 32, // 0x0800
33, 34, 35, 36, 37, 38, 39, 40, // 0x0A00
41, 42, 43, 44, 45, 46, 28, 28, // 0x0C00
47, 48, 49, 50, 51, 52, 53, 28, // 0x0E00
28, 28, 54, 55, 56, 57, 58, 59, // 0x1000
28, 28, 28, 28, 28, 28, 28, 28, // 0x1200
28, 28, 28, 28, 28, 28, 28, 28, // 0x1400
28, 28, 28, 28, 28, 28, 28, 28, // 0x1600
28, 28, 28, 28, 28, 28, 28, 28, // 0x1800
28, 28, 28, 28, 28, 28, 28, 28, // 0x1A00
28, 28, 28, 28, 28, 28, 28, 28, // 0x1C00
60, 60, 61, 62, 63, 64, 65, 66, // 0x1E00
67, 68, 69, 70, 71, 72, 73, 74, // 0x2000
75, 75, 75, 76, 77, 78, 28, 28, // 0x2200
79, 80, 81, 82, 83, 83, 84, 85, // 0x2400
86, 85, 28, 28, 87, 88, 89, 28, // 0x2600
28, 28, 28, 28, 28, 28, 28, 28, // 0x2800
28, 28, 28, 28, 28, 28, 28, 28, // 0x2A00
28, 28, 28, 28, 28, 28, 28, 28, // 0x2C00
28, 28, 28, 28, 28, 28, 28, 28, // 0x2E00
90, 91, 92, 93, 94, 56, 95, 28, // 0x3000
96, 97, 98, 99, 83, 100, 83, 101, // 0x3200
28, 28, 28, 28, 28, 28, 28, 28, // 0x3400
28, 28, 28, 28, 28, 28, 28, 28, // 0x3600
28, 28, 28, 28, 28, 28, 28, 28, // 0x3800
28, 28, 28, 28, 28, 28, 28, 28, // 0x3A00
28, 28, 28, 28, 28, 28, 28, 28, // 0x3C00
28, 28, 28, 28, 28, 28, 28, 28, // 0x3E00
28, 28, 28, 28, 28, 28, 28, 28, // 0x4000
28, 28, 28, 28, 28, 28, 28, 28, // 0x4200
28, 28, 28, 28, 28, 28, 28, 28, // 0x4400
28, 28, 28, 28, 28, 28, 28, 28, // 0x4600
28, 28, 28, 28, 28, 28, 28, 28, // 0x4800
28, 28, 28, 28, 28, 28, 28, 28, // 0x4A00
28, 28, 28, 28, 28, 28, 28, 28, // 0x4C00
56, 56, 56, 56, 56, 56, 56, 56, // 0x4E00
56, 56, 56, 56, 56, 56, 56, 56, // 0x5000
56, 56, 56, 56, 56, 56, 56, 56, // 0x5200
56, 56, 56, 56, 56, 56, 56, 56, // 0x5400
56, 56, 56, 56, 56, 56, 56, 56, // 0x5600
56, 56, 56, 56, 56, 56, 56, 56, // 0x5800
56, 56, 56, 56, 56, 56, 56, 56, // 0x5A00
56, 56, 56, 56, 56, 56, 56, 56, // 0x5C00
56, 56, 56, 56, 56, 56, 56, 56, // 0x5E00
56, 56, 56, 56, 56, 56, 56, 56, // 0x6000
56, 56, 56, 56, 56, 56, 56, 56, // 0x6200
56, 56, 56, 56, 56, 56, 56, 56, // 0x6400
56, 56, 56, 56, 56, 56, 56, 56, // 0x6600
56, 56, 56, 56, 56, 56, 56, 56, // 0x6800
56, 56, 56, 56, 56, 56, 56, 56, // 0x6A00
56, 56, 56, 56, 56, 56, 56, 56, // 0x6C00
56, 56, 56, 56, 56, 56, 56, 56, // 0x6E00
56, 56, 56, 56, 56, 56, 56, 56, // 0x7000
56, 56, 56, 56, 56, 56, 56, 56, // 0x7200
56, 56, 56, 56, 56, 56, 56, 56, // 0x7400
56, 56, 56, 56, 56, 56, 56, 56, // 0x7600
56, 56, 56, 56, 56, 56, 56, 56, // 0x7800
56, 56, 56, 56, 56, 56, 56, 56, // 0x7A00
56, 56, 56, 56, 56, 56, 56, 56, // 0x7C00
56, 56, 56, 56, 56, 56, 56, 56, // 0x7E00
56, 56, 56, 56, 56, 56, 56, 56, // 0x8000
56, 56, 56, 56, 56, 56, 56, 56, // 0x8200
56, 56, 56, 56, 56, 56, 56, 56, // 0x8400
56, 56, 56, 56, 56, 56, 56, 56, // 0x8600
56, 56, 56, 56, 56, 56, 56, 56, // 0x8800
56, 56, 56, 56, 56, 56, 56, 56, // 0x8A00
56, 56, 56, 56, 56, 56, 56, 56, // 0x8C00
56, 56, 56, 56, 56, 56, 56, 56, // 0x8E00
56, 56, 56, 56, 56, 56, 56, 56, // 0x9000
56, 56, 56, 56, 56, 56, 56, 56, // 0x9200
56, 56, 56, 56, 56, 56, 56, 56, // 0x9400
56, 56, 56, 56, 56, 56, 56, 56, // 0x9600
56, 56, 56, 56, 56, 56, 56, 56, // 0x9800
56, 56, 56, 56, 56, 56, 56, 56, // 0x9A00
56, 56, 56, 56, 56, 56, 56, 56, // 0x9C00
56, 56, 56, 56, 56, 56, 102, 28, // 0x9E00
28, 28, 28, 28, 28, 28, 28, 28, // 0xA000
28, 28, 28, 28, 28, 28, 28, 28, // 0xA200
28, 28, 28, 28, 28, 28, 28, 28, // 0xA400
28, 28, 28, 28, 28, 28, 28, 28, // 0xA600
28, 28, 28, 28, 28, 28, 28, 28, // 0xA800
28, 28, 28, 28, 28, 28, 28, 28, // 0xAA00
56, 56, 56, 56, 56, 56, 56, 56, // 0xAC00
56, 56, 56, 56, 56, 56, 56, 56, // 0xAE00
56, 56, 56, 56, 56, 56, 56, 56, // 0xB000
56, 56, 56, 56, 56, 56, 56, 56, // 0xB200
56, 56, 56, 56, 56, 56, 56, 56, // 0xB400
56, 56, 56, 56, 56, 56, 56, 56, // 0xB600
56, 56, 56, 56, 56, 56, 56, 56, // 0xB800
56, 56, 56, 56, 56, 56, 56, 56, // 0xBA00
56, 56, 56, 56, 56, 56, 56, 56, // 0xBC00
56, 56, 56, 56, 56, 56, 56, 56, // 0xBE00
56, 56, 56, 56, 56, 56, 56, 56, // 0xC000
56, 56, 56, 56, 56, 56, 56, 56, // 0xC200
56, 56, 56, 56, 56, 56, 56, 56, // 0xC400
56, 56, 56, 56, 56, 56, 56, 56, // 0xC600
56, 56, 56, 56, 56, 56, 56, 56, // 0xC800
56, 56, 56, 56, 56, 56, 56, 56, // 0xCA00
56, 56, 56, 56, 56, 56, 56, 56, // 0xCC00
56, 56, 56, 56, 56, 56, 56, 56, // 0xCE00
56, 56, 56, 56, 56, 56, 56, 56, // 0xD000
56, 56, 56, 56, 56, 56, 56, 56, // 0xD200
56, 56, 56, 56, 56, 56, 56, 56, // 0xD400
56, 56, 56, 56, 56, 56, 103, 28, // 0xD600
104, 104, 104, 104, 104, 104, 104, 104, // 0xD800
104, 104, 104, 104, 104, 104, 104, 104, // 0xDA00
104, 104, 104, 104, 104, 104, 104, 104, // 0xDC00
104, 104, 104, 104, 104, 104, 104, 104, // 0xDE00
105, 105, 105, 105, 105, 105, 105, 105, // 0xE000
105, 105, 105, 105, 105, 105, 105, 105, // 0xE200
105, 105, 105, 105, 105, 105, 105, 105, // 0xE400
105, 105, 105, 105, 105, 105, 105, 105, // 0xE600
105, 105, 105, 105, 105, 105, 105, 105, // 0xE800
105, 105, 105, 105, 105, 105, 105, 105, // 0xEA00
105, 105, 105, 105, 105, 105, 105, 105, // 0xEC00
105, 105, 105, 105, 105, 105, 105, 105, // 0xEE00
105, 105, 105, 105, 105, 105, 105, 105, // 0xF000
105, 105, 105, 105, 105, 105, 105, 105, // 0xF200
105, 105, 105, 105, 105, 105, 105, 105, // 0xF400
105, 105, 105, 105, 105, 105, 105, 105, // 0xF600
105, 105, 105, 105, 56, 56, 56, 56, // 0xF800
106, 28, 28, 28, 107, 108, 109, 110, // 0xFA00
56, 56, 56, 56, 111, 112, 113, 114, // 0xFC00
115, 116, 56, 117, 118, 119, 120, 121 // 0xFE00
};
// The Y table has 7808 entries for a total of 7808 bytes.
const uint8 JS::CharInfo::y[] = {
0, 0, 0, 0, 0, 0, 0, 0, // 0
0, 1, 14, 1, 1, 14, 0, 0, // 0
0, 0, 0, 0, 0, 0, 0, 0, // 0
0, 0, 0, 0, 0, 0, 0, 0, // 0
2, 3, 3, 3, 4, 3, 3, 3, // 0
5, 6, 3, 7, 3, 8, 3, 3, // 0
9, 9, 9, 9, 9, 9, 9, 9, // 0
9, 9, 3, 3, 7, 7, 7, 3, // 0
3, 10, 10, 10, 10, 10, 10, 10, // 1
10, 10, 10, 10, 10, 10, 10, 10, // 1
10, 10, 10, 10, 10, 10, 10, 10, // 1
10, 10, 10, 5, 3, 6, 11, 12, // 1
11, 13, 13, 13, 13, 13, 13, 13, // 1
13, 13, 13, 13, 13, 13, 13, 13, // 1
13, 13, 13, 13, 13, 13, 13, 13, // 1
13, 13, 13, 5, 7, 6, 7, 0, // 1
0, 0, 0, 0, 0, 0, 0, 0, // 2
0, 0, 0, 0, 0, 0, 0, 0, // 2
0, 0, 0, 0, 0, 0, 0, 0, // 2
0, 0, 0, 0, 0, 0, 0, 0, // 2
2, 3, 4, 4, 4, 4, 15, 15, // 2
11, 15, 16, 5, 7, 8, 15, 11, // 2
15, 7, 17, 17, 11, 16, 15, 3, // 2
11, 18, 16, 6, 19, 19, 19, 3, // 2
20, 20, 20, 20, 20, 20, 20, 20, // 3
20, 20, 20, 20, 20, 20, 20, 20, // 3
20, 20, 20, 20, 20, 20, 20, 7, // 3
20, 20, 20, 20, 20, 20, 20, 16, // 3
21, 21, 21, 21, 21, 21, 21, 21, // 3
21, 21, 21, 21, 21, 21, 21, 21, // 3
21, 21, 21, 21, 21, 21, 21, 7, // 3
21, 21, 21, 21, 21, 21, 21, 22, // 3
23, 24, 23, 24, 23, 24, 23, 24, // 4
23, 24, 23, 24, 23, 24, 23, 24, // 4
23, 24, 23, 24, 23, 24, 23, 24, // 4
23, 24, 23, 24, 23, 24, 23, 24, // 4
23, 24, 23, 24, 23, 24, 23, 24, // 4
23, 24, 23, 24, 23, 24, 23, 24, // 4
25, 26, 23, 24, 23, 24, 23, 24, // 4
16, 23, 24, 23, 24, 23, 24, 23, // 4
24, 23, 24, 23, 24, 23, 24, 23, // 5
24, 16, 23, 24, 23, 24, 23, 24, // 5
23, 24, 23, 24, 23, 24, 23, 24, // 5
23, 24, 23, 24, 23, 24, 23, 24, // 5
23, 24, 23, 24, 23, 24, 23, 24, // 5
23, 24, 23, 24, 23, 24, 23, 24, // 5
23, 24, 23, 24, 23, 24, 23, 24, // 5
27, 23, 24, 23, 24, 23, 24, 28, // 5
16, 29, 23, 24, 23, 24, 30, 23, // 6
24, 31, 31, 23, 24, 16, 32, 32, // 6
33, 23, 24, 31, 34, 16, 35, 36, // 6
23, 24, 16, 16, 35, 37, 16, 38, // 6
23, 24, 23, 24, 23, 24, 38, 23, // 6
24, 39, 40, 16, 23, 24, 39, 23, // 6
24, 41, 41, 23, 24, 23, 24, 42, // 6
23, 24, 16, 40, 23, 24, 40, 40, // 6
40, 40, 40, 40, 43, 44, 45, 43, // 7
44, 45, 43, 44, 45, 23, 24, 23, // 7
24, 23, 24, 23, 24, 23, 24, 23, // 7
24, 23, 24, 23, 24, 16, 23, 24, // 7
23, 24, 23, 24, 23, 24, 23, 24, // 7
23, 24, 23, 24, 23, 24, 23, 24, // 7
16, 43, 44, 45, 23, 24, 46, 46, // 7
46, 46, 23, 24, 23, 24, 23, 24, // 7
23, 24, 23, 24, 23, 24, 23, 24, // 8
23, 24, 23, 24, 23, 24, 23, 24, // 8
23, 24, 23, 24, 23, 24, 23, 24, // 8
46, 46, 46, 46, 46, 46, 46, 46, // 8
46, 46, 46, 46, 46, 46, 46, 46, // 8
46, 46, 46, 46, 46, 46, 46, 46, // 8
46, 46, 46, 46, 46, 46, 46, 46, // 8
46, 46, 46, 46, 46, 46, 46, 46, // 8
46, 46, 46, 46, 46, 46, 46, 46, // 9
46, 46, 46, 46, 46, 46, 46, 46, // 9
16, 16, 16, 47, 48, 16, 49, 49, // 9
50, 50, 16, 51, 16, 16, 16, 16, // 9
49, 16, 16, 52, 16, 16, 16, 16, // 9
53, 54, 16, 16, 16, 16, 16, 54, // 9
16, 16, 55, 16, 16, 16, 16, 16, // 9
16, 16, 16, 16, 16, 16, 16, 16, // 9
16, 16, 16, 56, 16, 16, 16, 16, // 10
56, 16, 57, 57, 16, 16, 16, 16, // 10
16, 16, 58, 16, 16, 16, 16, 16, // 10
16, 16, 16, 16, 16, 16, 16, 16, // 10
16, 16, 16, 16, 16, 16, 16, 16, // 10
16, 46, 46, 46, 46, 46, 46, 46, // 10
59, 59, 59, 59, 59, 59, 59, 59, // 10
59, 11, 11, 59, 59, 59, 59, 59, // 10
59, 59, 11, 11, 11, 11, 11, 11, // 11
11, 11, 11, 11, 11, 11, 11, 11, // 11
59, 59, 11, 11, 11, 11, 11, 11, // 11
11, 11, 11, 11, 11, 11, 11, 46, // 11
59, 59, 59, 59, 59, 11, 11, 11, // 11
11, 11, 46, 46, 46, 46, 46, 46, // 11
46, 46, 46, 46, 46, 46, 46, 46, // 11
46, 46, 46, 46, 46, 46, 46, 46, // 11
60, 60, 60, 60, 60, 60, 60, 60, // 12
60, 60, 60, 60, 60, 60, 60, 60, // 12
60, 60, 60, 60, 60, 60, 60, 60, // 12
60, 60, 60, 60, 60, 60, 60, 60, // 12
60, 60, 60, 60, 60, 60, 60, 60, // 12
60, 60, 60, 60, 60, 60, 60, 60, // 12
60, 60, 60, 60, 60, 60, 60, 60, // 12
60, 60, 60, 60, 60, 60, 60, 60, // 12
60, 60, 60, 60, 60, 60, 46, 46, // 13
46, 46, 46, 46, 46, 46, 46, 46, // 13
46, 46, 46, 46, 46, 46, 46, 46, // 13
46, 46, 46, 46, 46, 46, 46, 46, // 13
60, 60, 46, 46, 46, 46, 46, 46, // 13
46, 46, 46, 46, 46, 46, 46, 46, // 13
46, 46, 46, 46, 3, 3, 46, 46, // 13
46, 46, 59, 46, 46, 46, 3, 46, // 13
46, 46, 46, 46, 11, 11, 61, 3, // 14
62, 62, 62, 46, 63, 46, 64, 64, // 14
16, 20, 20, 20, 20, 20, 20, 20, // 14
20, 20, 20, 20, 20, 20, 20, 20, // 14
20, 20, 46, 20, 20, 20, 20, 20, // 14
20, 20, 20, 20, 65, 66, 66, 66, // 14
16, 21, 21, 21, 21, 21, 21, 21, // 14
21, 21, 21, 21, 21, 21, 21, 21, // 14
21, 21, 16, 21, 21, 21, 21, 21, // 15
21, 21, 21, 21, 67, 68, 68, 46, // 15
69, 70, 38, 38, 38, 71, 72, 46, // 15
46, 46, 38, 46, 38, 46, 38, 46, // 15
38, 46, 23, 24, 23, 24, 23, 24, // 15
23, 24, 23, 24, 23, 24, 23, 24, // 15
73, 74, 16, 40, 46, 46, 46, 46, // 15
46, 46, 46, 46, 46, 46, 46, 46, // 15
46, 75, 75, 75, 75, 75, 75, 75, // 16
75, 75, 75, 75, 75, 46, 75, 75, // 16
20, 20, 20, 20, 20, 20, 20, 20, // 16
20, 20, 20, 20, 20, 20, 20, 20, // 16
20, 20, 20, 20, 20, 20, 20, 20, // 16
20, 20, 20, 20, 20, 20, 20, 20, // 16
21, 21, 21, 21, 21, 21, 21, 21, // 16
21, 21, 21, 21, 21, 21, 21, 21, // 16
21, 21, 21, 21, 21, 21, 21, 21, // 17
21, 21, 21, 21, 21, 21, 21, 21, // 17
46, 74, 74, 74, 74, 74, 74, 74, // 17
74, 74, 74, 74, 74, 46, 74, 74, // 17
23, 24, 23, 24, 23, 24, 23, 24, // 17
23, 24, 23, 24, 23, 24, 23, 24, // 17
23, 24, 23, 24, 23, 24, 23, 24, // 17
23, 24, 23, 24, 23, 24, 23, 24, // 17
23, 24, 15, 60, 60, 60, 60, 46, // 18
46, 46, 46, 46, 46, 46, 46, 46, // 18
23, 24, 23, 24, 23, 24, 23, 24, // 18
23, 24, 23, 24, 23, 24, 23, 24, // 18
23, 24, 23, 24, 23, 24, 23, 24, // 18
23, 24, 23, 24, 23, 24, 23, 24, // 18
23, 24, 23, 24, 23, 24, 23, 24, // 18
23, 24, 23, 24, 23, 24, 23, 24, // 18
40, 23, 24, 23, 24, 46, 46, 23, // 19
24, 46, 46, 23, 24, 46, 46, 46, // 19
23, 24, 23, 24, 23, 24, 23, 24, // 19
23, 24, 23, 24, 23, 24, 23, 24, // 19
23, 24, 23, 24, 23, 24, 23, 24, // 19
23, 24, 23, 24, 46, 46, 23, 24, // 19
23, 24, 23, 24, 23, 24, 46, 46, // 19
23, 24, 46, 46, 46, 46, 46, 46, // 19
46, 46, 46, 46, 46, 46, 46, 46, // 20
46, 46, 46, 46, 46, 46, 46, 46, // 20
46, 46, 46, 46, 46, 46, 46, 46, // 20
46, 46, 46, 46, 46, 46, 46, 46, // 20
46, 46, 46, 46, 46, 46, 46, 46, // 20
46, 46, 46, 46, 46, 46, 46, 46, // 20
46, 76, 76, 76, 76, 76, 76, 76, // 20
76, 76, 76, 76, 76, 76, 76, 76, // 20
76, 76, 76, 76, 76, 76, 76, 76, // 21
76, 76, 76, 76, 76, 76, 76, 76, // 21
76, 76, 76, 76, 76, 76, 76, 46, // 21
46, 59, 3, 3, 3, 3, 3, 3, // 21
46, 77, 77, 77, 77, 77, 77, 77, // 21
77, 77, 77, 77, 77, 77, 77, 77, // 21
77, 77, 77, 77, 77, 77, 77, 77, // 21
77, 77, 77, 77, 77, 77, 77, 77, // 21
77, 77, 77, 77, 77, 77, 77, 16, // 22
46, 3, 46, 46, 46, 46, 46, 46, // 22
46, 60, 60, 60, 60, 60, 60, 60, // 22
60, 60, 60, 60, 60, 60, 60, 60, // 22
60, 60, 46, 60, 60, 60, 60, 60, // 22
60, 60, 60, 60, 60, 60, 60, 60, // 22
60, 60, 60, 60, 60, 60, 60, 60, // 22
60, 60, 46, 60, 60, 60, 3, 60, // 22
3, 60, 60, 3, 60, 46, 46, 46, // 23
46, 46, 46, 46, 46, 46, 46, 46, // 23
40, 40, 40, 40, 40, 40, 40, 40, // 23
40, 40, 40, 40, 40, 40, 40, 40, // 23
40, 40, 40, 40, 40, 40, 40, 40, // 23
40, 40, 40, 46, 46, 46, 46, 46, // 23
40, 40, 40, 3, 3, 46, 46, 46, // 23
46, 46, 46, 46, 46, 46, 46, 46, // 23
46, 46, 46, 46, 46, 46, 46, 46, // 24
46, 46, 46, 46, 3, 46, 46, 46, // 24
46, 46, 46, 46, 46, 46, 46, 46, // 24
46, 46, 46, 3, 46, 46, 46, 3, // 24
46, 40, 40, 40, 40, 40, 40, 40, // 24
40, 40, 40, 40, 40, 40, 40, 40, // 24
40, 40, 40, 40, 40, 40, 40, 40, // 24
40, 40, 40, 46, 46, 46, 46, 46, // 24
59, 40, 40, 40, 40, 40, 40, 40, // 25
40, 40, 40, 60, 60, 60, 60, 60, // 25
60, 60, 60, 46, 46, 46, 46, 46, // 25
46, 46, 46, 46, 46, 46, 46, 46, // 25
78, 78, 78, 78, 78, 78, 78, 78, // 25
78, 78, 3, 3, 3, 3, 46, 46, // 25
60, 40, 40, 40, 40, 40, 40, 40, // 25
40, 40, 40, 40, 40, 40, 40, 40, // 25
40, 40, 40, 40, 40, 40, 40, 40, // 26
40, 40, 40, 40, 40, 40, 40, 40, // 26
40, 40, 40, 40, 40, 40, 40, 40, // 26
40, 40, 40, 40, 40, 40, 40, 40, // 26
40, 40, 40, 40, 40, 40, 40, 40, // 26
40, 40, 40, 40, 40, 40, 40, 40, // 26
40, 40, 40, 40, 40, 40, 40, 40, // 26
46, 46, 40, 40, 40, 40, 40, 46, // 26
40, 40, 40, 40, 40, 40, 40, 40, // 27
40, 40, 40, 40, 40, 40, 40, 46, // 27
40, 40, 40, 40, 3, 40, 60, 60, // 27
60, 60, 60, 60, 60, 79, 79, 60, // 27
60, 60, 60, 60, 60, 59, 59, 60, // 27
60, 15, 60, 60, 60, 60, 46, 46, // 27
9, 9, 9, 9, 9, 9, 9, 9, // 27
9, 9, 46, 46, 46, 46, 46, 46, // 27
46, 46, 46, 46, 46, 46, 46, 46, // 28
46, 46, 46, 46, 46, 46, 46, 46, // 28
46, 46, 46, 46, 46, 46, 46, 46, // 28
46, 46, 46, 46, 46, 46, 46, 46, // 28
46, 46, 46, 46, 46, 46, 46, 46, // 28
46, 46, 46, 46, 46, 46, 46, 46, // 28
46, 46, 46, 46, 46, 46, 46, 46, // 28
46, 46, 46, 46, 46, 46, 46, 46, // 28
46, 60, 60, 80, 46, 40, 40, 40, // 29
40, 40, 40, 40, 40, 40, 40, 40, // 29
40, 40, 40, 40, 40, 40, 40, 40, // 29
40, 40, 40, 40, 40, 40, 40, 40, // 29
40, 40, 40, 40, 40, 40, 40, 40, // 29
40, 40, 40, 40, 40, 40, 40, 40, // 29
40, 40, 40, 40, 40, 40, 40, 40, // 29
40, 40, 46, 46, 60, 40, 80, 80, // 29
80, 60, 60, 60, 60, 60, 60, 60, // 30
60, 80, 80, 80, 80, 60, 46, 46, // 30
15, 60, 60, 60, 60, 46, 46, 46, // 30
40, 40, 40, 40, 40, 40, 40, 40, // 30
40, 40, 60, 60, 3, 3, 81, 81, // 30
81, 81, 81, 81, 81, 81, 81, 81, // 30
3, 46, 46, 46, 46, 46, 46, 46, // 30
46, 46, 46, 46, 46, 46, 46, 46, // 30
46, 60, 80, 80, 46, 40, 40, 40, // 31
40, 40, 40, 40, 40, 46, 46, 40, // 31
40, 46, 46, 40, 40, 40, 40, 40, // 31
40, 40, 40, 40, 40, 40, 40, 40, // 31
40, 40, 40, 40, 40, 40, 40, 40, // 31
40, 46, 40, 40, 40, 40, 40, 40, // 31
40, 46, 40, 46, 46, 46, 40, 40, // 31
40, 40, 46, 46, 60, 46, 80, 80, // 31
80, 60, 60, 60, 60, 46, 46, 80, // 32
80, 46, 46, 80, 80, 60, 46, 46, // 32
46, 46, 46, 46, 46, 46, 46, 80, // 32
46, 46, 46, 46, 40, 40, 46, 40, // 32
40, 40, 60, 60, 46, 46, 81, 81, // 32
81, 81, 81, 81, 81, 81, 81, 81, // 32
40, 40, 4, 4, 82, 82, 82, 82, // 32
19, 83, 15, 46, 46, 46, 46, 46, // 32
46, 46, 60, 46, 46, 40, 40, 40, // 33
40, 40, 40, 46, 46, 46, 46, 40, // 33
40, 46, 46, 40, 40, 40, 40, 40, // 33
40, 40, 40, 40, 40, 40, 40, 40, // 33
40, 40, 40, 40, 40, 40, 40, 40, // 33
40, 46, 40, 40, 40, 40, 40, 40, // 33
40, 46, 40, 40, 46, 40, 40, 46, // 33
40, 40, 46, 46, 60, 46, 80, 80, // 33
80, 60, 60, 46, 46, 46, 46, 60, // 34
60, 46, 46, 60, 60, 60, 46, 46, // 34
46, 46, 46, 46, 46, 46, 46, 46, // 34
46, 40, 40, 40, 40, 46, 40, 46, // 34
46, 46, 46, 46, 46, 46, 81, 81, // 34
81, 81, 81, 81, 81, 81, 81, 81, // 34
60, 60, 40, 40, 40, 46, 46, 46, // 34
46, 46, 46, 46, 46, 46, 46, 46, // 34
46, 60, 60, 80, 46, 40, 40, 40, // 35
40, 40, 40, 40, 46, 40, 46, 40, // 35
40, 40, 46, 40, 40, 40, 40, 40, // 35
40, 40, 40, 40, 40, 40, 40, 40, // 35
40, 40, 40, 40, 40, 40, 40, 40, // 35
40, 46, 40, 40, 40, 40, 40, 40, // 35
40, 46, 40, 40, 46, 40, 40, 40, // 35
40, 40, 46, 46, 60, 40, 80, 80, // 35
80, 60, 60, 60, 60, 60, 46, 60, // 36
60, 80, 46, 80, 80, 60, 46, 46, // 36
15, 46, 46, 46, 46, 46, 46, 46, // 36
46, 46, 46, 46, 46, 46, 46, 46, // 36
40, 46, 46, 46, 46, 46, 81, 81, // 36
81, 81, 81, 81, 81, 81, 81, 81, // 36
46, 46, 46, 46, 46, 46, 46, 46, // 36
46, 46, 46, 46, 46, 46, 46, 46, // 36
46, 60, 80, 80, 46, 40, 40, 40, // 37
40, 40, 40, 40, 40, 46, 46, 40, // 37
40, 46, 46, 40, 40, 40, 40, 40, // 37
40, 40, 40, 40, 40, 40, 40, 40, // 37
40, 40, 40, 40, 40, 40, 40, 40, // 37
40, 46, 40, 40, 40, 40, 40, 40, // 37
40, 46, 40, 40, 46, 46, 40, 40, // 37
40, 40, 46, 46, 60, 40, 80, 60, // 37
80, 60, 60, 60, 46, 46, 46, 80, // 38
80, 46, 46, 80, 80, 60, 46, 46, // 38
46, 46, 46, 46, 46, 46, 60, 80, // 38
46, 46, 46, 46, 40, 40, 46, 40, // 38
40, 40, 46, 46, 46, 46, 81, 81, // 38
81, 81, 81, 81, 81, 81, 81, 81, // 38
15, 46, 46, 46, 46, 46, 46, 46, // 38
46, 46, 46, 46, 46, 46, 46, 46, // 38
46, 46, 60, 80, 46, 40, 40, 40, // 39
40, 40, 40, 46, 46, 46, 40, 40, // 39
40, 46, 40, 40, 40, 40, 46, 46, // 39
46, 40, 40, 46, 40, 46, 40, 40, // 39
46, 46, 46, 40, 40, 46, 46, 46, // 39
40, 40, 40, 46, 46, 46, 40, 40, // 39
40, 40, 40, 40, 40, 40, 46, 40, // 39
40, 40, 46, 46, 46, 46, 80, 80, // 39
60, 80, 80, 46, 46, 46, 80, 80, // 40
80, 46, 80, 80, 80, 60, 46, 46, // 40
46, 46, 46, 46, 46, 46, 46, 80, // 40
46, 46, 46, 46, 46, 46, 46, 46, // 40
46, 46, 46, 46, 46, 46, 46, 81, // 40
81, 81, 81, 81, 81, 81, 81, 81, // 40
84, 19, 19, 46, 46, 46, 46, 46, // 40
46, 46, 46, 46, 46, 46, 46, 46, // 40
46, 80, 80, 80, 46, 40, 40, 40, // 41
40, 40, 40, 40, 40, 46, 40, 40, // 41
40, 46, 40, 40, 40, 40, 40, 40, // 41
40, 40, 40, 40, 40, 40, 40, 40, // 41
40, 40, 40, 40, 40, 40, 40, 40, // 41
40, 46, 40, 40, 40, 40, 40, 40, // 41
40, 40, 40, 40, 46, 40, 40, 40, // 41
40, 40, 46, 46, 46, 46, 60, 60, // 41
60, 80, 80, 80, 80, 46, 60, 60, // 42
60, 46, 60, 60, 60, 60, 46, 46, // 42
46, 46, 46, 46, 46, 60, 60, 46, // 42
46, 46, 46, 46, 46, 46, 46, 46, // 42
40, 40, 46, 46, 46, 46, 81, 81, // 42
81, 81, 81, 81, 81, 81, 81, 81, // 42
46, 46, 46, 46, 46, 46, 46, 46, // 42
46, 46, 46, 46, 46, 46, 46, 46, // 42
46, 46, 80, 80, 46, 40, 40, 40, // 43
40, 40, 40, 40, 40, 46, 40, 40, // 43
40, 46, 40, 40, 40, 40, 40, 40, // 43
40, 40, 40, 40, 40, 40, 40, 40, // 43
40, 40, 40, 40, 40, 40, 40, 40, // 43
40, 46, 40, 40, 40, 40, 40, 40, // 43
40, 40, 40, 40, 46, 40, 40, 40, // 43
40, 40, 46, 46, 46, 46, 80, 60, // 43
80, 80, 80, 80, 80, 46, 60, 80, // 44
80, 46, 80, 80, 60, 60, 46, 46, // 44
46, 46, 46, 46, 46, 80, 80, 46, // 44
46, 46, 46, 46, 46, 46, 40, 46, // 44
40, 40, 46, 46, 46, 46, 81, 81, // 44
81, 81, 81, 81, 81, 81, 81, 81, // 44
46, 46, 46, 46, 46, 46, 46, 46, // 44
46, 46, 46, 46, 46, 46, 46, 46, // 44
46, 46, 80, 80, 46, 40, 40, 40, // 45
40, 40, 40, 40, 40, 46, 40, 40, // 45
40, 46, 40, 40, 40, 40, 40, 40, // 45
40, 40, 40, 40, 40, 40, 40, 40, // 45
40, 40, 40, 40, 40, 40, 40, 40, // 45
40, 46, 40, 40, 40, 40, 40, 40, // 45
40, 40, 40, 40, 40, 40, 40, 40, // 45
40, 40, 46, 46, 46, 46, 80, 80, // 45
80, 60, 60, 60, 46, 46, 80, 80, // 46
80, 46, 80, 80, 80, 60, 46, 46, // 46
46, 46, 46, 46, 46, 46, 46, 80, // 46
46, 46, 46, 46, 46, 46, 46, 46, // 46
40, 40, 46, 46, 46, 46, 81, 81, // 46
81, 81, 81, 81, 81, 81, 81, 81, // 46
46, 46, 46, 46, 46, 46, 46, 46, // 46
46, 46, 46, 46, 46, 46, 46, 46, // 46
46, 40, 40, 40, 40, 40, 40, 40, // 47
40, 40, 40, 40, 40, 40, 40, 40, // 47
40, 40, 40, 40, 40, 40, 40, 40, // 47
40, 40, 40, 40, 40, 40, 40, 40, // 47
40, 40, 40, 40, 40, 40, 40, 40, // 47
40, 40, 40, 40, 40, 40, 40, 3, // 47
40, 60, 40, 40, 60, 60, 60, 60, // 47
60, 60, 60, 46, 46, 46, 46, 4, // 47
40, 40, 40, 40, 40, 40, 59, 60, // 48
60, 60, 60, 60, 60, 60, 60, 15, // 48
9, 9, 9, 9, 9, 9, 9, 9, // 48
9, 9, 3, 3, 46, 46, 46, 46, // 48
46, 46, 46, 46, 46, 46, 46, 46, // 48
46, 46, 46, 46, 46, 46, 46, 46, // 48
46, 46, 46, 46, 46, 46, 46, 46, // 48
46, 46, 46, 46, 46, 46, 46, 46, // 48
46, 40, 40, 46, 40, 46, 46, 40, // 49
40, 46, 40, 46, 46, 40, 46, 46, // 49
46, 46, 46, 46, 40, 40, 40, 40, // 49
46, 40, 40, 40, 40, 40, 40, 40, // 49
46, 40, 40, 40, 46, 40, 46, 40, // 49
46, 46, 40, 40, 46, 40, 40, 3, // 49
40, 60, 40, 40, 60, 60, 60, 60, // 49
60, 60, 46, 60, 60, 40, 46, 46, // 49
40, 40, 40, 40, 40, 46, 59, 46, // 50
60, 60, 60, 60, 60, 60, 46, 46, // 50
9, 9, 9, 9, 9, 9, 9, 9, // 50
9, 9, 46, 46, 40, 40, 46, 46, // 50
46, 46, 46, 46, 46, 46, 46, 46, // 50
46, 46, 46, 46, 46, 46, 46, 46, // 50
46, 46, 46, 46, 46, 46, 46, 46, // 50
46, 46, 46, 46, 46, 46, 46, 46, // 50
15, 15, 15, 15, 3, 3, 3, 3, // 51
3, 3, 3, 3, 3, 3, 3, 3, // 51
3, 3, 3, 15, 15, 15, 15, 15, // 51
60, 60, 15, 15, 15, 15, 15, 15, // 51
78, 78, 78, 78, 78, 78, 78, 78, // 51
78, 78, 85, 85, 85, 85, 85, 85, // 51
85, 85, 85, 85, 15, 60, 15, 60, // 51
15, 60, 5, 6, 5, 6, 80, 80, // 51
40, 40, 40, 40, 40, 40, 40, 40, // 52
46, 40, 40, 40, 40, 40, 40, 40, // 52
40, 40, 40, 40, 40, 40, 40, 40, // 52
40, 40, 40, 40, 40, 40, 40, 40, // 52
40, 40, 40, 40, 40, 40, 40, 40, // 52
40, 40, 46, 46, 46, 46, 46, 46, // 52
46, 60, 60, 60, 60, 60, 60, 60, // 52
60, 60, 60, 60, 60, 60, 60, 80, // 52
60, 60, 60, 60, 60, 3, 60, 60, // 53
60, 60, 60, 60, 46, 46, 46, 46, // 53
60, 60, 60, 60, 60, 60, 46, 60, // 53
46, 60, 60, 60, 60, 60, 60, 60, // 53
60, 60, 60, 60, 60, 60, 60, 60, // 53
60, 60, 60, 60, 60, 60, 46, 46, // 53
46, 60, 60, 60, 60, 60, 60, 60, // 53
46, 60, 46, 46, 46, 46, 46, 46, // 53
46, 46, 46, 46, 46, 46, 46, 46, // 54
46, 46, 46, 46, 46, 46, 46, 46, // 54
46, 46, 46, 46, 46, 46, 46, 46, // 54
46, 46, 46, 46, 46, 46, 46, 46, // 54
76, 76, 76, 76, 76, 76, 76, 76, // 54
76, 76, 76, 76, 76, 76, 76, 76, // 54
76, 76, 76, 76, 76, 76, 76, 76, // 54
76, 76, 76, 76, 76, 76, 76, 76, // 54
76, 76, 76, 76, 76, 76, 46, 46, // 55
46, 46, 46, 46, 46, 46, 46, 46, // 55
16, 16, 16, 16, 16, 16, 16, 16, // 55
16, 16, 16, 16, 16, 16, 16, 16, // 55
16, 16, 16, 16, 16, 16, 16, 16, // 55
16, 16, 16, 16, 16, 16, 16, 16, // 55
16, 16, 16, 16, 16, 16, 16, 46, // 55
46, 46, 46, 3, 46, 46, 46, 46, // 55
40, 40, 40, 40, 40, 40, 40, 40, // 56
40, 40, 40, 40, 40, 40, 40, 40, // 56
40, 40, 40, 40, 40, 40, 40, 40, // 56
40, 40, 40, 40, 40, 40, 40, 40, // 56
40, 40, 40, 40, 40, 40, 40, 40, // 56
40, 40, 40, 40, 40, 40, 40, 40, // 56
40, 40, 40, 40, 40, 40, 40, 40, // 56
40, 40, 40, 40, 40, 40, 40, 40, // 56
40, 40, 40, 40, 40, 40, 40, 40, // 57
40, 40, 40, 40, 40, 40, 40, 40, // 57
40, 40, 40, 40, 40, 40, 40, 40, // 57
40, 40, 46, 46, 46, 46, 46, 40, // 57
40, 40, 40, 40, 40, 40, 40, 40, // 57
40, 40, 40, 40, 40, 40, 40, 40, // 57
40, 40, 40, 40, 40, 40, 40, 40, // 57
40, 40, 40, 40, 40, 40, 40, 40, // 57
40, 40, 40, 40, 40, 40, 40, 40, // 58
40, 40, 40, 40, 40, 40, 40, 40, // 58
40, 40, 40, 40, 40, 40, 40, 40, // 58
40, 40, 40, 40, 40, 40, 40, 40, // 58
40, 40, 40, 46, 46, 46, 46, 46, // 58
40, 40, 40, 40, 40, 40, 40, 40, // 58
40, 40, 40, 40, 40, 40, 40, 40, // 58
40, 40, 40, 40, 40, 40, 40, 40, // 58
40, 40, 40, 40, 40, 40, 40, 40, // 59
40, 40, 40, 40, 40, 40, 40, 40, // 59
40, 40, 40, 40, 40, 40, 40, 40, // 59
40, 40, 40, 40, 40, 40, 40, 40, // 59
40, 40, 40, 40, 40, 40, 40, 40, // 59
40, 40, 40, 40, 40, 40, 40, 40, // 59
40, 40, 40, 40, 40, 40, 40, 40, // 59
40, 40, 46, 46, 46, 46, 46, 46, // 59
23, 24, 23, 24, 23, 24, 23, 24, // 60
23, 24, 23, 24, 23, 24, 23, 24, // 60
23, 24, 23, 24, 23, 24, 23, 24, // 60
23, 24, 23, 24, 23, 24, 23, 24, // 60
23, 24, 23, 24, 23, 24, 23, 24, // 60
23, 24, 23, 24, 23, 24, 23, 24, // 60
23, 24, 23, 24, 23, 24, 23, 24, // 60
23, 24, 23, 24, 23, 24, 23, 24, // 60
23, 24, 23, 24, 23, 24, 23, 24, // 61
23, 24, 23, 24, 23, 24, 23, 24, // 61
23, 24, 23, 24, 23, 24, 16, 16, // 61
16, 16, 16, 16, 46, 46, 46, 46, // 61
23, 24, 23, 24, 23, 24, 23, 24, // 61
23, 24, 23, 24, 23, 24, 23, 24, // 61
23, 24, 23, 24, 23, 24, 23, 24, // 61
23, 24, 23, 24, 23, 24, 23, 24, // 61
23, 24, 23, 24, 23, 24, 23, 24, // 62
23, 24, 23, 24, 23, 24, 23, 24, // 62
23, 24, 23, 24, 23, 24, 23, 24, // 62
23, 24, 23, 24, 23, 24, 23, 24, // 62
23, 24, 23, 24, 23, 24, 23, 24, // 62
23, 24, 23, 24, 23, 24, 23, 24, // 62
23, 24, 23, 24, 23, 24, 23, 24, // 62
23, 24, 46, 46, 46, 46, 46, 46, // 62
86, 86, 86, 86, 86, 86, 86, 86, // 63
87, 87, 87, 87, 87, 87, 87, 87, // 63
86, 86, 86, 86, 86, 86, 46, 46, // 63
87, 87, 87, 87, 87, 87, 46, 46, // 63
86, 86, 86, 86, 86, 86, 86, 86, // 63
87, 87, 87, 87, 87, 87, 87, 87, // 63
86, 86, 86, 86, 86, 86, 86, 86, // 63
87, 87, 87, 87, 87, 87, 87, 87, // 63
86, 86, 86, 86, 86, 86, 46, 46, // 64
87, 87, 87, 87, 87, 87, 46, 46, // 64
16, 86, 16, 86, 16, 86, 16, 86, // 64
46, 87, 46, 87, 46, 87, 46, 87, // 64
86, 86, 86, 86, 86, 86, 86, 86, // 64
87, 87, 87, 87, 87, 87, 87, 87, // 64
88, 88, 89, 89, 89, 89, 90, 90, // 64
91, 91, 92, 92, 93, 93, 46, 46, // 64
86, 86, 86, 86, 86, 86, 86, 86, // 65
87, 87, 87, 87, 87, 87, 87, 87, // 65
86, 86, 86, 86, 86, 86, 86, 86, // 65
87, 87, 87, 87, 87, 87, 87, 87, // 65
86, 86, 86, 86, 86, 86, 86, 86, // 65
87, 87, 87, 87, 87, 87, 87, 87, // 65
86, 86, 16, 94, 16, 46, 16, 16, // 65
87, 87, 95, 95, 96, 11, 38, 11, // 65
11, 11, 16, 94, 16, 46, 16, 16, // 66
97, 97, 97, 97, 96, 11, 11, 11, // 66
86, 86, 16, 16, 46, 46, 16, 16, // 66
87, 87, 98, 98, 46, 11, 11, 11, // 66
86, 86, 16, 16, 16, 99, 16, 16, // 66
87, 87, 100, 100, 101, 11, 11, 11, // 66
46, 46, 16, 94, 16, 46, 16, 16, // 66
102, 102, 103, 103, 96, 11, 11, 46, // 66
2, 2, 2, 2, 2, 2, 2, 2, // 67
2, 2, 2, 2, 104, 104, 104, 104, // 67
8, 8, 8, 8, 8, 8, 3, 3, // 67
5, 6, 5, 5, 5, 6, 5, 5, // 67
3, 3, 3, 3, 3, 3, 3, 3, // 67
105, 106, 104, 104, 104, 104, 104, 46, // 67
3, 3, 3, 3, 3, 3, 3, 3, // 67
3, 5, 6, 3, 3, 3, 3, 12, // 67
12, 3, 3, 3, 7, 5, 6, 46, // 68
46, 46, 46, 46, 46, 46, 46, 46, // 68
46, 46, 46, 46, 46, 46, 46, 46, // 68
46, 46, 46, 46, 46, 46, 46, 46, // 68
46, 46, 46, 46, 46, 46, 46, 46, // 68
46, 46, 104, 104, 104, 104, 104, 104, // 68
17, 46, 46, 46, 17, 17, 17, 17, // 68
17, 17, 7, 7, 7, 5, 6, 16, // 68
107, 107, 107, 107, 107, 107, 107, 107, // 69
107, 107, 7, 7, 7, 5, 6, 46, // 69
46, 46, 46, 46, 46, 46, 46, 46, // 69
46, 46, 46, 46, 46, 46, 46, 46, // 69
4, 4, 4, 4, 4, 4, 4, 4, // 69
4, 4, 4, 4, 46, 46, 46, 46, // 69
46, 46, 46, 46, 46, 46, 46, 46, // 69
46, 46, 46, 46, 46, 46, 46, 46, // 69
46, 46, 46, 46, 46, 46, 46, 46, // 70
46, 46, 46, 46, 46, 46, 46, 46, // 70
60, 60, 60, 60, 60, 60, 60, 60, // 70
60, 60, 60, 60, 60, 79, 79, 79, // 70
79, 60, 46, 46, 46, 46, 46, 46, // 70
46, 46, 46, 46, 46, 46, 46, 46, // 70
46, 46, 46, 46, 46, 46, 46, 46, // 70
46, 46, 46, 46, 46, 46, 46, 46, // 70
15, 15, 38, 15, 15, 15, 15, 38, // 71
15, 15, 16, 38, 38, 38, 16, 16, // 71
38, 38, 38, 16, 15, 38, 15, 15, // 71
38, 38, 38, 38, 38, 38, 15, 15, // 71
15, 15, 15, 15, 38, 15, 38, 15, // 71
38, 15, 38, 38, 38, 38, 16, 16, // 71
38, 38, 15, 38, 16, 40, 40, 40, // 71
40, 46, 46, 46, 46, 46, 46, 46, // 71
46, 46, 46, 46, 46, 46, 46, 46, // 72
46, 46, 46, 46, 46, 46, 46, 46, // 72
46, 46, 46, 19, 19, 19, 19, 19, // 72
19, 19, 19, 19, 19, 19, 19, 108, // 72
109, 109, 109, 109, 109, 109, 109, 109, // 72
109, 109, 109, 109, 110, 110, 110, 110, // 72
111, 111, 111, 111, 111, 111, 111, 111, // 72
111, 111, 111, 111, 112, 112, 112, 112, // 72
113, 113, 113, 46, 46, 46, 46, 46, // 73
46, 46, 46, 46, 46, 46, 46, 46, // 73
7, 7, 7, 7, 7, 15, 15, 15, // 73
15, 15, 15, 15, 15, 15, 15, 15, // 73
15, 15, 15, 15, 15, 15, 15, 15, // 73
15, 15, 15, 15, 15, 15, 15, 15, // 73
15, 15, 15, 15, 15, 15, 15, 15, // 73
15, 15, 15, 15, 15, 15, 15, 15, // 73
15, 15, 15, 15, 15, 15, 15, 15, // 74
15, 15, 15, 15, 15, 15, 15, 15, // 74
15, 15, 7, 15, 7, 15, 15, 15, // 74
15, 15, 15, 15, 15, 15, 15, 15, // 74
15, 15, 15, 15, 15, 15, 15, 15, // 74
15, 15, 15, 46, 46, 46, 46, 46, // 74
46, 46, 46, 46, 46, 46, 46, 46, // 74
46, 46, 46, 46, 46, 46, 46, 46, // 74
7, 7, 7, 7, 7, 7, 7, 7, // 75
7, 7, 7, 7, 7, 7, 7, 7, // 75
7, 7, 7, 7, 7, 7, 7, 7, // 75
7, 7, 7, 7, 7, 7, 7, 7, // 75
7, 7, 7, 7, 7, 7, 7, 7, // 75
7, 7, 7, 7, 7, 7, 7, 7, // 75
7, 7, 7, 7, 7, 7, 7, 7, // 75
7, 7, 7, 7, 7, 7, 7, 7, // 75
7, 7, 7, 7, 7, 7, 7, 7, // 76
7, 7, 7, 7, 7, 7, 7, 7, // 76
7, 7, 7, 7, 7, 7, 7, 7, // 76
7, 7, 7, 7, 7, 7, 7, 7, // 76
7, 7, 7, 7, 7, 7, 7, 7, // 76
7, 7, 7, 7, 7, 7, 7, 7, // 76
7, 7, 46, 46, 46, 46, 46, 46, // 76
46, 46, 46, 46, 46, 46, 46, 46, // 76
15, 46, 15, 15, 15, 15, 15, 15, // 77
7, 7, 7, 7, 15, 15, 15, 15, // 77
15, 15, 15, 15, 15, 15, 15, 15, // 77
15, 15, 15, 15, 15, 15, 15, 15, // 77
7, 7, 15, 15, 15, 15, 15, 15, // 77
15, 5, 6, 15, 15, 15, 15, 15, // 77
15, 15, 15, 15, 15, 15, 15, 15, // 77
15, 15, 15, 15, 15, 15, 15, 15, // 77
15, 15, 15, 15, 15, 15, 15, 15, // 78
15, 15, 15, 15, 15, 15, 15, 15, // 78
15, 15, 15, 15, 15, 15, 15, 15, // 78
15, 15, 15, 15, 15, 15, 15, 15, // 78
15, 15, 15, 15, 15, 15, 15, 15, // 78
15, 15, 15, 15, 15, 15, 15, 15, // 78
15, 15, 15, 15, 15, 15, 15, 15, // 78
15, 15, 15, 46, 46, 46, 46, 46, // 78
15, 15, 15, 15, 15, 15, 15, 15, // 79
15, 15, 15, 15, 15, 15, 15, 15, // 79
15, 15, 15, 15, 15, 15, 15, 15, // 79
15, 15, 15, 15, 15, 15, 15, 15, // 79
15, 15, 15, 15, 15, 46, 46, 46, // 79
46, 46, 46, 46, 46, 46, 46, 46, // 79
46, 46, 46, 46, 46, 46, 46, 46, // 79
46, 46, 46, 46, 46, 46, 46, 46, // 79
15, 15, 15, 15, 15, 15, 15, 15, // 80
15, 15, 15, 46, 46, 46, 46, 46, // 80
46, 46, 46, 46, 46, 46, 46, 46, // 80
46, 46, 46, 46, 46, 46, 46, 46, // 80
114, 114, 114, 114, 114, 114, 114, 114, // 80
114, 114, 114, 114, 114, 114, 114, 114, // 80
114, 114, 114, 114, 82, 82, 82, 82, // 80
82, 82, 82, 82, 82, 82, 82, 82, // 80
82, 82, 82, 82, 82, 82, 82, 82, // 81
115, 115, 115, 115, 115, 115, 115, 115, // 81
115, 115, 115, 115, 115, 115, 115, 115, // 81
115, 115, 115, 115, 15, 15, 15, 15, // 81
15, 15, 15, 15, 15, 15, 15, 15, // 81
15, 15, 15, 15, 15, 15, 15, 15, // 81
15, 15, 15, 15, 15, 15, 116, 116, // 81
116, 116, 116, 116, 116, 116, 116, 116, // 81
116, 116, 116, 116, 116, 116, 116, 116, // 82
116, 116, 116, 116, 116, 116, 116, 116, // 82
117, 117, 117, 117, 117, 117, 117, 117, // 82
117, 117, 117, 117, 117, 117, 117, 117, // 82
117, 117, 117, 117, 117, 117, 117, 117, // 82
117, 117, 118, 46, 46, 46, 46, 46, // 82
46, 46, 46, 46, 46, 46, 46, 46, // 82
46, 46, 46, 46, 46, 46, 46, 46, // 82
15, 15, 15, 15, 15, 15, 15, 15, // 83
15, 15, 15, 15, 15, 15, 15, 15, // 83
15, 15, 15, 15, 15, 15, 15, 15, // 83
15, 15, 15, 15, 15, 15, 15, 15, // 83
15, 15, 15, 15, 15, 15, 15, 15, // 83
15, 15, 15, 15, 15, 15, 15, 15, // 83
15, 15, 15, 15, 15, 15, 15, 15, // 83
15, 15, 15, 15, 15, 15, 15, 15, // 83
15, 15, 15, 15, 15, 15, 15, 15, // 84
15, 15, 15, 15, 15, 15, 15, 15, // 84
15, 15, 15, 15, 15, 15, 46, 46, // 84
46, 46, 46, 46, 46, 46, 46, 46, // 84
15, 15, 15, 15, 15, 15, 15, 15, // 84
15, 15, 15, 15, 15, 15, 15, 15, // 84
15, 15, 15, 15, 15, 15, 15, 15, // 84
15, 15, 15, 15, 15, 15, 15, 15, // 84
15, 15, 15, 15, 15, 15, 15, 15, // 85
15, 15, 15, 15, 15, 15, 15, 15, // 85
15, 15, 15, 15, 15, 15, 15, 15, // 85
15, 15, 15, 15, 15, 15, 15, 15, // 85
15, 15, 15, 15, 15, 15, 15, 15, // 85
15, 15, 15, 15, 15, 15, 15, 15, // 85
46, 46, 46, 46, 46, 46, 46, 46, // 85
46, 46, 46, 46, 46, 46, 46, 46, // 85
15, 15, 15, 15, 15, 15, 15, 15, // 86
15, 15, 15, 15, 15, 15, 15, 15, // 86
15, 15, 15, 15, 46, 46, 46, 46, // 86
46, 46, 15, 15, 15, 15, 15, 15, // 86
15, 15, 15, 15, 15, 15, 15, 15, // 86
15, 15, 15, 15, 15, 15, 15, 15, // 86
15, 15, 15, 15, 15, 15, 15, 15, // 86
15, 15, 15, 15, 15, 15, 15, 15, // 86
46, 15, 15, 15, 15, 46, 15, 15, // 87
15, 15, 46, 46, 15, 15, 15, 15, // 87
15, 15, 15, 15, 15, 15, 15, 15, // 87
15, 15, 15, 15, 15, 15, 15, 15, // 87
15, 15, 15, 15, 15, 15, 15, 15, // 87
46, 15, 15, 15, 15, 15, 15, 15, // 87
15, 15, 15, 15, 15, 15, 15, 15, // 87
15, 15, 15, 15, 15, 15, 15, 15, // 87
15, 15, 15, 15, 15, 15, 15, 15, // 88
15, 15, 15, 15, 46, 15, 46, 15, // 88
15, 15, 15, 46, 46, 46, 15, 46, // 88
15, 15, 15, 15, 15, 15, 15, 46, // 88
46, 15, 15, 15, 15, 15, 15, 15, // 88
46, 46, 46, 46, 46, 46, 46, 46, // 88
46, 46, 46, 46, 46, 46, 119, 119, // 88
119, 119, 119, 119, 119, 119, 119, 119, // 88
114, 114, 114, 114, 114, 114, 114, 114, // 89
114, 114, 83, 83, 83, 83, 83, 83, // 89
83, 83, 83, 83, 15, 46, 46, 46, // 89
15, 15, 15, 15, 15, 15, 15, 15, // 89
15, 15, 15, 15, 15, 15, 15, 15, // 89
15, 15, 15, 15, 15, 15, 15, 15, // 89
46, 15, 15, 15, 15, 15, 15, 15, // 89
15, 15, 15, 15, 15, 15, 15, 46, // 89
2, 3, 3, 3, 15, 59, 3, 120, // 90
5, 6, 5, 6, 5, 6, 5, 6, // 90
5, 6, 15, 15, 5, 6, 5, 6, // 90
5, 6, 5, 6, 8, 5, 6, 5, // 90
15, 121, 121, 121, 121, 121, 121, 121, // 90
121, 121, 60, 60, 60, 60, 60, 60, // 90
8, 59, 59, 59, 59, 59, 15, 15, // 90
46, 46, 46, 46, 46, 46, 46, 15, // 90
46, 40, 40, 40, 40, 40, 40, 40, // 91
40, 40, 40, 40, 40, 40, 40, 40, // 91
40, 40, 40, 40, 40, 40, 40, 40, // 91
40, 40, 40, 40, 40, 40, 40, 40, // 91
40, 40, 40, 40, 40, 40, 40, 40, // 91
40, 40, 40, 40, 40, 40, 40, 40, // 91
40, 40, 40, 40, 40, 40, 40, 40, // 91
40, 40, 40, 40, 40, 40, 40, 40, // 91
40, 40, 40, 40, 40, 40, 40, 40, // 92
40, 40, 40, 40, 40, 40, 40, 40, // 92
40, 40, 40, 40, 40, 46, 46, 46, // 92
46, 60, 60, 59, 59, 59, 59, 46, // 92
46, 40, 40, 40, 40, 40, 40, 40, // 92
40, 40, 40, 40, 40, 40, 40, 40, // 92
40, 40, 40, 40, 40, 40, 40, 40, // 92
40, 40, 40, 40, 40, 40, 40, 40, // 92
40, 40, 40, 40, 40, 40, 40, 40, // 93
40, 40, 40, 40, 40, 40, 40, 40, // 93
40, 40, 40, 40, 40, 40, 40, 40, // 93
40, 40, 40, 40, 40, 40, 40, 40, // 93
40, 40, 40, 40, 40, 40, 40, 40, // 93
40, 40, 40, 40, 40, 40, 40, 40, // 93
40, 40, 40, 40, 40, 40, 40, 40, // 93
40, 40, 40, 3, 59, 59, 59, 46, // 93
46, 46, 46, 46, 46, 40, 40, 40, // 94
40, 40, 40, 40, 40, 40, 40, 40, // 94
40, 40, 40, 40, 40, 40, 40, 40, // 94
40, 40, 40, 40, 40, 40, 40, 40, // 94
40, 40, 40, 40, 40, 40, 40, 40, // 94
40, 40, 40, 40, 40, 46, 46, 46, // 94
46, 40, 40, 40, 40, 40, 40, 40, // 94
40, 40, 40, 40, 40, 40, 40, 40, // 94
40, 40, 40, 40, 40, 40, 40, 40, // 95
40, 40, 40, 40, 40, 40, 40, 46, // 95
15, 15, 85, 85, 85, 85, 15, 15, // 95
15, 15, 15, 15, 15, 15, 15, 15, // 95
46, 46, 46, 46, 46, 46, 46, 46, // 95
46, 46, 46, 46, 46, 46, 46, 46, // 95
46, 46, 46, 46, 46, 46, 46, 46, // 95
46, 46, 46, 46, 46, 46, 46, 46, // 95
15, 15, 15, 15, 15, 15, 15, 15, // 96
15, 15, 15, 15, 15, 15, 15, 15, // 96
15, 15, 15, 15, 15, 15, 15, 15, // 96
15, 15, 15, 15, 15, 46, 46, 46, // 96
85, 85, 85, 85, 85, 85, 85, 85, // 96
85, 85, 15, 15, 15, 15, 15, 15, // 96
15, 15, 15, 15, 15, 15, 15, 15, // 96
15, 15, 15, 15, 15, 15, 15, 15, // 96
15, 15, 15, 15, 46, 46, 46, 46, // 97
46, 46, 46, 46, 46, 46, 46, 46, // 97
46, 46, 46, 46, 46, 46, 46, 46, // 97
46, 46, 46, 46, 46, 46, 46, 46, // 97
15, 15, 15, 15, 15, 15, 15, 15, // 97
15, 15, 15, 15, 15, 15, 15, 15, // 97
15, 15, 15, 15, 15, 15, 15, 15, // 97
15, 15, 15, 15, 46, 46, 46, 15, // 97
114, 114, 114, 114, 114, 114, 114, 114, // 98
114, 114, 15, 15, 15, 15, 15, 15, // 98
15, 15, 15, 15, 15, 15, 15, 15, // 98
15, 15, 15, 15, 15, 15, 15, 15, // 98
15, 15, 15, 15, 15, 15, 15, 15, // 98
15, 15, 15, 15, 15, 15, 15, 15, // 98
15, 46, 46, 46, 46, 46, 46, 46, // 98
46, 46, 46, 46, 46, 46, 46, 46, // 98
15, 15, 15, 15, 15, 15, 15, 15, // 99
15, 15, 15, 15, 46, 46, 46, 46, // 99
15, 15, 15, 15, 15, 15, 15, 15, // 99
15, 15, 15, 15, 15, 15, 15, 15, // 99
15, 15, 15, 15, 15, 15, 15, 15, // 99
15, 15, 15, 15, 15, 15, 15, 15, // 99
15, 15, 15, 15, 15, 15, 15, 15, // 99
15, 15, 15, 15, 15, 15, 15, 46, // 99
15, 15, 15, 15, 15, 15, 15, 15, // 100
15, 15, 15, 15, 15, 15, 15, 15, // 100
15, 15, 15, 15, 15, 15, 15, 15, // 100
15, 15, 15, 15, 15, 15, 15, 15, // 100
15, 15, 15, 15, 15, 15, 15, 15, // 100
15, 15, 15, 15, 15, 15, 15, 15, // 100
15, 15, 15, 15, 15, 15, 15, 46, // 100
46, 46, 46, 15, 15, 15, 15, 15, // 100
15, 15, 15, 15, 15, 15, 15, 15, // 101
15, 15, 15, 15, 15, 15, 15, 15, // 101
15, 15, 15, 15, 15, 15, 15, 15, // 101
15, 15, 15, 15, 15, 15, 46, 46, // 101
15, 15, 15, 15, 15, 15, 15, 15, // 101
15, 15, 15, 15, 15, 15, 15, 15, // 101
15, 15, 15, 15, 15, 15, 15, 15, // 101
15, 15, 15, 15, 15, 15, 15, 46, // 101
40, 40, 40, 40, 40, 40, 40, 40, // 102
40, 40, 40, 40, 40, 40, 40, 40, // 102
40, 40, 40, 40, 40, 40, 40, 40, // 102
40, 40, 40, 40, 40, 40, 40, 40, // 102
40, 40, 40, 40, 40, 40, 46, 46, // 102
46, 46, 46, 46, 46, 46, 46, 46, // 102
46, 46, 46, 46, 46, 46, 46, 46, // 102
46, 46, 46, 46, 46, 46, 46, 46, // 102
40, 40, 40, 40, 40, 40, 40, 40, // 103
40, 40, 40, 40, 40, 40, 40, 40, // 103
40, 40, 40, 40, 40, 40, 40, 40, // 103
40, 40, 40, 40, 40, 40, 40, 40, // 103
40, 40, 40, 40, 46, 46, 46, 46, // 103
46, 46, 46, 46, 46, 46, 46, 46, // 103
46, 46, 46, 46, 46, 46, 46, 46, // 103
46, 46, 46, 46, 46, 46, 46, 46, // 103
122, 122, 122, 122, 122, 122, 122, 122, // 104
122, 122, 122, 122, 122, 122, 122, 122, // 104
122, 122, 122, 122, 122, 122, 122, 122, // 104
122, 122, 122, 122, 122, 122, 122, 122, // 104
122, 122, 122, 122, 122, 122, 122, 122, // 104
122, 122, 122, 122, 122, 122, 122, 122, // 104
122, 122, 122, 122, 122, 122, 122, 122, // 104
122, 122, 122, 122, 122, 122, 122, 122, // 104
123, 123, 123, 123, 123, 123, 123, 123, // 105
123, 123, 123, 123, 123, 123, 123, 123, // 105
123, 123, 123, 123, 123, 123, 123, 123, // 105
123, 123, 123, 123, 123, 123, 123, 123, // 105
123, 123, 123, 123, 123, 123, 123, 123, // 105
123, 123, 123, 123, 123, 123, 123, 123, // 105
123, 123, 123, 123, 123, 123, 123, 123, // 105
123, 123, 123, 123, 123, 123, 123, 123, // 105
40, 40, 40, 40, 40, 40, 40, 40, // 106
40, 40, 40, 40, 40, 40, 40, 40, // 106
40, 40, 40, 40, 40, 40, 40, 40, // 106
40, 40, 40, 40, 40, 40, 40, 40, // 106
40, 40, 40, 40, 40, 40, 40, 40, // 106
40, 40, 40, 40, 40, 40, 46, 46, // 106
46, 46, 46, 46, 46, 46, 46, 46, // 106
46, 46, 46, 46, 46, 46, 46, 46, // 106
16, 16, 16, 16, 16, 16, 16, 46, // 107
46, 46, 46, 46, 46, 46, 46, 46, // 107
46, 46, 46, 16, 16, 16, 16, 16, // 107
46, 46, 46, 46, 46, 46, 60, 40, // 107
40, 40, 40, 40, 40, 40, 40, 40, // 107
40, 7, 40, 40, 40, 40, 40, 40, // 107
40, 40, 40, 40, 40, 40, 40, 46, // 107
40, 40, 40, 40, 40, 46, 40, 46, // 107
40, 40, 46, 40, 40, 46, 40, 40, // 108
40, 40, 40, 40, 40, 40, 40, 40, // 108
40, 40, 40, 40, 40, 40, 40, 40, // 108
40, 40, 40, 40, 40, 40, 40, 40, // 108
40, 40, 40, 40, 40, 40, 40, 40, // 108
40, 40, 40, 40, 40, 40, 40, 40, // 108
40, 40, 40, 40, 40, 40, 40, 40, // 108
40, 40, 40, 40, 40, 40, 40, 40, // 108
40, 40, 40, 40, 40, 40, 40, 40, // 109
40, 40, 40, 40, 40, 40, 40, 40, // 109
40, 40, 40, 40, 40, 40, 40, 40, // 109
40, 40, 40, 40, 40, 40, 40, 40, // 109
40, 40, 40, 40, 40, 40, 40, 40, // 109
40, 40, 40, 40, 40, 40, 40, 40, // 109
40, 40, 46, 46, 46, 46, 46, 46, // 109
46, 46, 46, 46, 46, 46, 46, 46, // 109
46, 46, 46, 46, 46, 46, 46, 46, // 110
46, 46, 46, 46, 46, 46, 46, 46, // 110
46, 46, 46, 40, 40, 40, 40, 40, // 110
40, 40, 40, 40, 40, 40, 40, 40, // 110
40, 40, 40, 40, 40, 40, 40, 40, // 110
40, 40, 40, 40, 40, 40, 40, 40, // 110
40, 40, 40, 40, 40, 40, 40, 40, // 110
40, 40, 40, 40, 40, 40, 40, 40, // 110
40, 40, 40, 40, 40, 40, 40, 40, // 111
40, 40, 40, 40, 40, 40, 40, 40, // 111
40, 40, 40, 40, 40, 40, 40, 40, // 111
40, 40, 40, 40, 40, 40, 40, 40, // 111
40, 40, 40, 40, 40, 40, 40, 40, // 111
40, 40, 40, 40, 40, 40, 40, 40, // 111
40, 40, 40, 40, 40, 40, 40, 40, // 111
40, 40, 40, 40, 40, 40, 5, 6, // 111
46, 46, 46, 46, 46, 46, 46, 46, // 112
46, 46, 46, 46, 46, 46, 46, 46, // 112
40, 40, 40, 40, 40, 40, 40, 40, // 112
40, 40, 40, 40, 40, 40, 40, 40, // 112
40, 40, 40, 40, 40, 40, 40, 40, // 112
40, 40, 40, 40, 40, 40, 40, 40, // 112
40, 40, 40, 40, 40, 40, 40, 40, // 112
40, 40, 40, 40, 40, 40, 40, 40, // 112
40, 40, 40, 40, 40, 40, 40, 40, // 113
40, 40, 40, 40, 40, 40, 40, 40, // 113
46, 46, 40, 40, 40, 40, 40, 40, // 113
40, 40, 40, 40, 40, 40, 40, 40, // 113
40, 40, 40, 40, 40, 40, 40, 40, // 113
40, 40, 40, 40, 40, 40, 40, 40, // 113
40, 40, 40, 40, 40, 40, 40, 40, // 113
40, 40, 40, 40, 40, 40, 40, 40, // 113
40, 40, 40, 40, 40, 40, 40, 40, // 114
46, 46, 46, 46, 46, 46, 46, 46, // 114
46, 46, 46, 46, 46, 46, 46, 46, // 114
46, 46, 46, 46, 46, 46, 46, 46, // 114
46, 46, 46, 46, 46, 46, 46, 46, // 114
46, 46, 46, 46, 46, 46, 46, 46, // 114
40, 40, 40, 40, 40, 40, 40, 40, // 114
40, 40, 40, 40, 46, 46, 46, 46, // 114
46, 46, 46, 46, 46, 46, 46, 46, // 115
46, 46, 46, 46, 46, 46, 46, 46, // 115
46, 46, 46, 46, 46, 46, 46, 46, // 115
46, 46, 46, 46, 46, 46, 46, 46, // 115
60, 60, 60, 60, 46, 46, 46, 46, // 115
46, 46, 46, 46, 46, 46, 46, 46, // 115
3, 8, 8, 12, 12, 5, 6, 5, // 115
6, 5, 6, 5, 6, 5, 6, 5, // 115
6, 5, 6, 5, 6, 46, 46, 46, // 116
46, 3, 3, 3, 3, 12, 12, 12, // 116
3, 3, 3, 46, 3, 3, 3, 3, // 116
8, 5, 6, 5, 6, 5, 6, 3, // 116
3, 3, 7, 8, 7, 7, 7, 46, // 116
3, 4, 3, 3, 46, 46, 46, 46, // 116
40, 40, 40, 46, 40, 46, 40, 40, // 116
40, 40, 40, 40, 40, 40, 40, 40, // 116
40, 40, 40, 40, 40, 40, 40, 40, // 117
40, 40, 40, 40, 40, 40, 40, 40, // 117
40, 40, 40, 40, 40, 40, 40, 40, // 117
40, 40, 40, 40, 40, 40, 40, 40, // 117
40, 40, 40, 40, 40, 40, 40, 40, // 117
40, 40, 40, 40, 40, 40, 40, 40, // 117
40, 40, 40, 40, 40, 40, 40, 40, // 117
40, 40, 40, 40, 40, 46, 46, 104, // 117
46, 3, 3, 3, 4, 3, 3, 3, // 118
5, 6, 3, 7, 3, 8, 3, 3, // 118
9, 9, 9, 9, 9, 9, 9, 9, // 118
9, 9, 3, 3, 7, 7, 7, 3, // 118
3, 10, 10, 10, 10, 10, 10, 10, // 118
10, 10, 10, 10, 10, 10, 10, 10, // 118
10, 10, 10, 10, 10, 10, 10, 10, // 118
10, 10, 10, 5, 3, 6, 11, 12, // 118
11, 13, 13, 13, 13, 13, 13, 13, // 119
13, 13, 13, 13, 13, 13, 13, 13, // 119
13, 13, 13, 13, 13, 13, 13, 13, // 119
13, 13, 13, 5, 7, 6, 7, 46, // 119
46, 3, 5, 6, 3, 3, 40, 40, // 119
40, 40, 40, 40, 40, 40, 40, 40, // 119
59, 40, 40, 40, 40, 40, 40, 40, // 119
40, 40, 40, 40, 40, 40, 40, 40, // 119
40, 40, 40, 40, 40, 40, 40, 40, // 120
40, 40, 40, 40, 40, 40, 40, 40, // 120
40, 40, 40, 40, 40, 40, 40, 40, // 120
40, 40, 40, 40, 40, 40, 59, 59, // 120
40, 40, 40, 40, 40, 40, 40, 40, // 120
40, 40, 40, 40, 40, 40, 40, 40, // 120
40, 40, 40, 40, 40, 40, 40, 40, // 120
40, 40, 40, 40, 40, 40, 40, 46, // 120
46, 46, 40, 40, 40, 40, 40, 40, // 121
46, 46, 40, 40, 40, 40, 40, 40, // 121
46, 46, 40, 40, 40, 40, 40, 40, // 121
46, 46, 40, 40, 40, 46, 46, 46, // 121
4, 4, 7, 11, 15, 4, 4, 46, // 121
7, 7, 7, 7, 7, 15, 15, 46, // 121
46, 46, 46, 46, 46, 46, 46, 46, // 121
46, 46, 46, 46, 46, 15, 46, 46 // 121
};
// The A table has 124 entries for a total of 496 bytes.
const uint32 JS::CharInfo::a[] = {
0x0000000F, // 0 Cc
0x0004000F, // 1 Cc, whitespace
0x0004000C, // 2 Zs, whitespace
0x00000018, // 3 Po
0x0002001A, // 4 Sc, currency
0x00000015, // 5 Ps
0x00000016, // 6 Pe
0x00000019, // 7 Sm
0x00000014, // 8 Pd
0x00036009, // 9 Nd, identifier part, decimal 16
0x0822FE01, // 10 Lu, hasLower (add 32), identifier start, supradecimal 31
0x0000001B, // 11 Sk
0x00020017, // 12 Pc, underscore
0x0812FE02, // 13 Ll, hasUpper (subtract 32), identifier start, supradecimal 31
0x0005000F, // 14 Cc, break
0x0000001C, // 15 So
0x00020002, // 16 Ll, identifier start
0x0000600B, // 17 No, decimal 16
0x0000500B, // 18 No, decimal 8
0x0000800B, // 19 No, strange
0x08220001, // 20 Lu, hasLower (add 32), identifier start
0x08120002, // 21 Ll, hasUpper (subtract 32), identifier start
0xE1D20002, // 22 Ll, hasUpper (subtract -121), identifier start
0x00620001, // 23 Lu, hasLower (add 1), identifier start
0x00520002, // 24 Ll, hasUpper (subtract 1), identifier start
0xCE620001, // 25 Lu, hasLower (add -199), identifier start
0x3A120002, // 26 Ll, hasUpper (subtract 232), identifier start
0xE1E20001, // 27 Lu, hasLower (add -121), identifier start
0x4B120002, // 28 Ll, hasUpper (subtract 300), identifier start
0x34A20001, // 29 Lu, hasLower (add 210), identifier start
0x33A20001, // 30 Lu, hasLower (add 206), identifier start
0x33620001, // 31 Lu, hasLower (add 205), identifier start
0x32A20001, // 32 Lu, hasLower (add 202), identifier start
0x32E20001, // 33 Lu, hasLower (add 203), identifier start
0x33E20001, // 34 Lu, hasLower (add 207), identifier start
0x34E20001, // 35 Lu, hasLower (add 211), identifier start
0x34620001, // 36 Lu, hasLower (add 209), identifier start
0x35620001, // 37 Lu, hasLower (add 213), identifier start
0x00020001, // 38 Lu, identifier start
0x36A20001, // 39 Lu, hasLower (add 218), identifier start
0x00020005, // 40 Lo, identifier start
0x36620001, // 41 Lu, hasLower (add 217), identifier start
0x36E20001, // 42 Lu, hasLower (add 219), identifier start
0x00AA0001, // 43 Lu, hasLower (add 2), hasTitle, identifier start
0x007A0003, // 44 Lt, hasUpper (subtract 1), hasLower (add 1), hasTitle, identifier start
0x009A0002, // 45 Ll, hasUpper (subtract 2), hasTitle, identifier start
0x00000000, // 46 unassigned
0x34920002, // 47 Ll, hasUpper (subtract 210), identifier start
0x33920002, // 48 Ll, hasUpper (subtract 206), identifier start
0x33520002, // 49 Ll, hasUpper (subtract 205), identifier start
0x32920002, // 50 Ll, hasUpper (subtract 202), identifier start
0x32D20002, // 51 Ll, hasUpper (subtract 203), identifier start
0x33D20002, // 52 Ll, hasUpper (subtract 207), identifier start
0x34520002, // 53 Ll, hasUpper (subtract 209), identifier start
0x34D20002, // 54 Ll, hasUpper (subtract 211), identifier start
0x35520002, // 55 Ll, hasUpper (subtract 213), identifier start
0x36920002, // 56 Ll, hasUpper (subtract 218), identifier start
0x36520002, // 57 Ll, hasUpper (subtract 217), identifier start
0x36D20002, // 58 Ll, hasUpper (subtract 219), identifier start
0x00020004, // 59 Lm, identifier start
0x00030006, // 60 Mn, identifier part
0x09A20001, // 61 Lu, hasLower (add 38), identifier start
0x09620001, // 62 Lu, hasLower (add 37), identifier start
0x10220001, // 63 Lu, hasLower (add 64), identifier start
0x0FE20001, // 64 Lu, hasLower (add 63), identifier start
0x09920002, // 65 Ll, hasUpper (subtract 38), identifier start
0x09520002, // 66 Ll, hasUpper (subtract 37), identifier start
0x10120002, // 67 Ll, hasUpper (subtract 64), identifier start
0x0FD20002, // 68 Ll, hasUpper (subtract 63), identifier start
0x0F920002, // 69 Ll, hasUpper (subtract 62), identifier start
0x0E520002, // 70 Ll, hasUpper (subtract 57), identifier start
0x0BD20002, // 71 Ll, hasUpper (subtract 47), identifier start
0x0D920002, // 72 Ll, hasUpper (subtract 54), identifier start
0x15920002, // 73 Ll, hasUpper (subtract 86), identifier start
0x14120002, // 74 Ll, hasUpper (subtract 80), identifier start
0x14220001, // 75 Lu, hasLower (add 80), identifier start
0x0C220001, // 76 Lu, hasLower (add 48), identifier start
0x0C120002, // 77 Ll, hasUpper (subtract 48), identifier start
0x00034009, // 78 Nd, identifier part, decimal 0
0x00000007, // 79 Me
0x00030008, // 80 Mc, identifier part
0x00037409, // 81 Nd, identifier part, decimal 26
0x00005A0B, // 82 No, decimal 13
0x00006E0B, // 83 No, decimal 23
0x0000740B, // 84 No, decimal 26
0x0000000B, // 85 No
0xFE120002, // 86 Ll, hasUpper (subtract -8), identifier start
0xFE220001, // 87 Lu, hasLower (add -8), identifier start
0xED920002, // 88 Ll, hasUpper (subtract -74), identifier start
0xEA920002, // 89 Ll, hasUpper (subtract -86), identifier start
0xE7120002, // 90 Ll, hasUpper (subtract -100), identifier start
0xE0120002, // 91 Ll, hasUpper (subtract -128), identifier start
0xE4120002, // 92 Ll, hasUpper (subtract -112), identifier start
0xE0920002, // 93 Ll, hasUpper (subtract -126), identifier start
0xFDD20002, // 94 Ll, hasUpper (subtract -9), identifier start
0xEDA20001, // 95 Lu, hasLower (add -74), identifier start
0xFDE20001, // 96 Lu, hasLower (add -9), identifier start
0xEAA20001, // 97 Lu, hasLower (add -86), identifier start
0xE7220001, // 98 Lu, hasLower (add -100), identifier start
0xFE520002, // 99 Ll, hasUpper (subtract -7), identifier start
0xE4220001, // 100 Lu, hasLower (add -112), identifier start
0xFE620001, // 101 Lu, hasLower (add -7), identifier start
0xE0220001, // 102 Lu, hasLower (add -128), identifier start
0xE0A20001, // 103 Lu, hasLower (add -126), identifier start
0x00010010, // 104 Cf, ignorable
0x0005000D, // 105 Zl, break
0x0005000E, // 106 Zp, break
0x0000400B, // 107 No, decimal 0
0x0000440B, // 108 No, decimal 2
0x0422420A, // 109 Nl, hasLower (add 16), identifier start, decimal 1
0x0422800A, // 110 Nl, hasLower (add 16), identifier start, strange
0x0412620A, // 111 Nl, hasUpper (subtract 16), identifier start, decimal 17
0x0412800A, // 112 Nl, hasUpper (subtract 16), identifier start, strange
0x0002800A, // 113 Nl, identifier start, strange
0x0000420B, // 114 No, decimal 1
0x0000720B, // 115 No, decimal 25
0x06A0001C, // 116 So, hasLower (add 26)
0x0690001C, // 117 So, hasUpper (subtract 26)
0x00006C0B, // 118 No, decimal 22
0x0000560B, // 119 No, decimal 11
0x0002720A, // 120 Nl, identifier start, decimal 25
0x0002400A, // 121 Nl, identifier start, decimal 0
0x00000013, // 122 Cs
0x00000012 // 123 Co
};
// Return c converted to upper case. If c cannot be converted to upper case,
// return c unchanged.
char16 JS::toUpper(char16 c)
{
CharInfo ci(c);
if (ci.info & 0x00100000)
c = static_cast<char16>(static_cast<int32>(c) - (static_cast<int32>(ci.info) >> 22));
return c;
}
// Return c converted to lower case. If c cannot be converted to lower case,
// return c unchanged.
char16 JS::toLower(char16 c)
{
CharInfo ci(c);
if (ci.info & 0x00200000)
c = static_cast<char16>(static_cast<int32>(c) + (static_cast<int32>(ci.info) >> 22));
return c;
}
// Return true if c is an ASCII hexadecimal digit, in which case store the digit's numeric value in d.
bool JS::isASCIIHexDigit(char16 c, uint &digit)
{
uint cv = c;
if (cv < '0')
return false;
if (cv <= '9') {
digit = cv - '0';
return true;
}
cv |= 0x20;
if (cv >= 'a' && cv <= 'f') {
digit = cv - 'a' + 10;
return true;
}
return false;
}
// Return str advanced past white space characters, but no further than strEnd.
const char16 *JS::skipWhiteSpace(const char16 *str, const char16 *strEnd)
{
while (str != strEnd && isSpace(*str))
str++;
return str;
}
//
// Zones
//
// #define DEBUG_ZONE to allocate each object in its own malloc block.
// This allows tools such as Purify to do bounds checking on all blocks.
// Construct a Zone that allocates memory in chunks of the given size.
JS::Zone::Zone(size_t blockSize): headers(0), freeBegin(0), freeEnd(0), blockSize(blockSize)
{
ASSERT(blockSize && !(blockSize & basicAlignment-1));
}
// Deallocate the Zone's blocks.
void JS::Zone::clear()
{
Header *h = headers;
while (h) {
Header *next = h->next;
STD::free(h);
h = next;
}
headers = 0;
}
// Allocate a fully aligned block of the given size.
// Throw bad_alloc if out of memory, without corrupting any of the Zone data structures.
void *JS::Zone::newBlock(size_t size)
{
Header *h = static_cast<Header *>(STD::malloc(sizeof(Header) + size));
h->next = headers;
headers = h;
return h+1;
}
// Allocate a naturally-aligned object of the given size (in bytes). Throw
// bad_alloc if out of memory, without corrupting any of the Zone data structures.
void *JS::Zone::allocate(size_t size)
{
ASSERT(size); // Can't allocate zero-size blocks.
#ifdef DEBUG_ZONE
return newBlock(size);
#else
size = size + (basicAlignment-1) & -basicAlignment; // Round up to natural alignment if necessary
char *p = freeBegin;
size_t freeBytes = static_cast<size_t>(freeEnd - p);
if (size > freeBytes) {
// If freeBytes is at least a quarter of blockSize, allocate a separate block.
if (freeBytes<<2 >= blockSize || size >= blockSize)
return newBlock(size);
p = static_cast<char *>(newBlock(blockSize));
freeEnd = p + blockSize;
}
freeBegin = p + size;
return p;
#endif
}
// Same as allocate but does not align size up to basicAlignment. Thus, the next
// object allocated in the zone will immediately follow this one if it falls in the same zone block.
// Use this when all objects in the zone have the same size.
void *JS::Zone::allocateUnaligned(size_t size)
{
ASSERT(size); // Can't allocate zero-size blocks.
#ifdef DEBUG_ZONE
return newBlock(size);
#else
char *p = freeBegin;
size_t freeBytes = static_cast<size_t>(freeEnd - p);
if (size > freeBytes) {
// If freeBytes is at least a quarter of blockSize, allocate a separate block.
if (freeBytes<<2 >= blockSize || size >= blockSize)
return newBlock(size);
p = static_cast<char *>(newBlock(blockSize));
freeEnd = p + blockSize;
}
freeBegin = p + size;
return p;
#endif
}
//
// Arenas
//
struct JS::Arena::DestructorEntry: JS::ArenaObject {
DestructorEntry *next; // Next destructor registration in linked list
void (*destructor)(void *); // Destructor function
void *object; // Object on which to call the destructor
DestructorEntry(void (*destructor)(void *), void *object): destructor(destructor), object(object) {}
};
// Call the Arena's registered destructors.
void JS::Arena::runDestructors()
{
DestructorEntry *e = destructorEntries;
while (e) {
e->destructor(e->object);
e = e->next;
}
destructorEntries = 0;
}
// Ensure that object's destructor is called at the time the arena is deallocated or cleared.
// The destructors will be called in reverse order of being registered.
// registerDestructor might itself runs out of memory, in which case it immediately
// calls object's destructor before throwing bad_alloc.
void JS::Arena::newDestructorEntry(void (*destructor)(void *), void *object)
{
try {
DestructorEntry *e = new(*this) DestructorEntry(destructor, object);
e->next = destructorEntries;
destructorEntries = e;
} catch (...) {
destructor(object);
throw;
}
}
// Allocate a String in the Arena and register that String so that it is deallocated at
// the same time as the Arena.
// DO NOT CALL DELETE ON THE RESULT!
JS::String &JS::newArenaString(Arena &arena)
{
String *s = new(arena) String();
arena.registerDestructor(s);
return *s;
}
JS::String &JS::newArenaString(Arena &arena, const String &str)
{
String *s = new(arena) String(str);
arena.registerDestructor(s);
return *s;
}
//
// Input
//
// Read a line from the input file, including the trailing line break character.
// Return the total number of characters read, which is str's length.
// Translate <CR> and <CR><LF> sequences to <LF> characters; a <CR><LF> sequence
// only counts as one character.
size_t JS::LineReader::readLine(string &str)
{
int ch;
bool oldCRWasLast = crWasLast;
crWasLast = false;
str.resize(0);
while ((ch = getc(in)) != EOF) {
if (ch == '\n') {
if (!str.size() && oldCRWasLast)
continue;
str += '\n';
break;
}
if (ch == '\r') {
crWasLast = true;
str += '\n';
break;
}
str += static_cast<char>(ch);
}
return str.size();
}
size_t JS::LineReader::readLine(String &wstr)
{
string str;
size_t n = readLine(str);
wstr.resize(n);
std::transform(str.begin(), str.end(), wstr.begin(), widen);
return n;
}
//
// Output
//
#ifdef XP_MAC_MPW
// Macintosh MPW replacements for the ANSI routines. These translate LF's to CR's because
// the MPW libraries supplied by Metrowerks don't do that for some reason.
static void translateLFtoCR(char *begin, char *end)
{
while (begin != end) {
if (*begin == '\n')
*begin = '\r';
++begin;
}
}
size_t JS::printChars(FILE *file, const char *begin, const char *end)
{
ASSERT(end >= begin);
size_t n = static_cast<size_t>(end - begin);
size_t extra = 0;
char buffer[1024];
while (n > sizeof buffer) {
std::memcpy(buffer, begin, sizeof buffer);
translateLFtoCR(buffer, buffer + sizeof buffer);
extra += fwrite(buffer, 1, sizeof buffer, file);
n -= sizeof buffer;
begin += sizeof buffer;
}
std::memcpy(buffer, begin, n);
translateLFtoCR(buffer, buffer + n);
return extra + fwrite(buffer, 1, n, file);
}
int std::fputc(int c, FILE *file)
{
char buffer = static_cast<char>(c);
if (buffer == '\n')
buffer = '\r';
return static_cast<int>(fwrite(&buffer, 1, 1, file));
}
int std::fputs(const char *s, FILE *file)
{
return static_cast<int>(JS::printChars(file, s, s + strlen(s)));
}
int std::fprintf(FILE* file, const char *format, ...)
{
JS::Buffer<char, 1024> b;
while (true) {
va_list args;
va_start(args, format);
int n = vsnprintf(b.buffer, b.size, format, args);
va_end(args);
if (n >= 0 && n < b.size) {
translateLFtoCR(b.buffer, b.buffer + n);
return static_cast<int>(fwrite(b.buffer, 1, static_cast<size_t>(n), file));
}
b.expand(b.size*2);
}
}
#endif // XP_MAC_MPW
// Write ch.
void JS::Formatter::printChar8(char ch)
{
printStr8(&ch, &ch + 1);
}
// Write ch.
void JS::Formatter::printChar16(char16 ch)
{
printStr16(&ch, &ch + 1);
}
// Write the null-terminated string str.
void JS::Formatter::printZStr8(const char *str)
{
printStr8(str, str + strlen(str));
}
// Write the String s.
void JS::Formatter::printString16(const String &s)
{
const char16 *begin = s.data();
printStr16(begin, begin + s.size());
}
// Write the printf format using the supplied args.
void JS::Formatter::printVFormat8(const char *format, va_list args)
{
Buffer<char, 1024> b;
while (true) {
int n = vsnprintf(b.buffer, b.size, format, args);
if (n >= 0 && n < b.size) {
printStr8(b.buffer, b.buffer + n);
return;
}
b.expand(b.size*2);
}
}
static const int printCharBufferSize = 64;
// Print ch count times.
void JS::printChar(Formatter &f, char ch, int count)
{
char str[printCharBufferSize];
while (count > 0) {
int c = count;
if (c > printCharBufferSize)
c = printCharBufferSize;
count -= c;
STD::memset(str, ch, static_cast<size_t>(c));
printString(f, str, str+c);
}
}
// Print ch count times.
void JS::printChar(Formatter &f, char16 ch, int count)
{
char16 str[printCharBufferSize];
while (count > 0) {
int c = count;
if (c > printCharBufferSize)
c = printCharBufferSize;
count -= c;
char16 *strEnd = str + c;
std::fill(str, strEnd, ch);
printString(f, str, strEnd);
}
}
// Print i using the given formatting string, padding on the left with pad characters
// to use at least nDigits characters.
void JS::printNum(Formatter &f, uint32 i, int nDigits, char pad, const char *format)
{
char str[20];
int n = sprintf(str, format, i);
if (n < nDigits)
printChar(f, pad, nDigits - n);
printString(f, str, str+n);
}
// Print p as a pointer.
void JS::printPtr(Formatter &f, void *p)
{
char str[20];
int n = sprintf(str, "%p", p);
printString(f, str, str+n);
}
// printf formats for printing non-ASCII characters on an ASCII stream
#ifdef XP_MAC
static const char unprintableFormat[] = "\xC7%.4X\xC8"; // Use angle quotes
#elif defined _WIN32
static const char unprintableFormat[] = "\xAB%.4X\xBB"; // Use angle quotes
#else
static const char unprintableFormat[] = "<%.4X>";
#endif
static const uint16 defaultFilterRanges[] = {
0x00, 0x09, // Filter all control characters except \t and \n
0x0B, 0x20,
0x7F, 0x100, // Filter all non-ASCII characters
0, 0
};
JS::BitSet<256> JS::AsciiFileFormatter::defaultFilter(defaultFilterRanges);
// Construct an AsciiFileFormatter using the given file and filter f.
// If f is nil, use the default filter.
JS::AsciiFileFormatter::AsciiFileFormatter(FILE *file, BitSet<256> *f):
file(file)
#ifndef _WIN32 // Microsoft Visual C++ 6.0 bug
, filter(f ? *f : defaultFilter)
#endif
{
#ifdef _WIN32 // Microsoft Visual C++ 6.0 bug
if (f)
filter = *f;
else
filter = defaultFilter;
#endif
filterEmpty = filter.none();
}
// Write ch, escaping non-ASCII characters.
void JS::AsciiFileFormatter::printChar8(char ch)
{
if (filterChar(ch))
fprintf(file, unprintableFormat, static_cast<uchar>(ch));
else
fputc(ch, file);
}
// Write ch, escaping non-ASCII characters.
void JS::AsciiFileFormatter::printChar16(char16 ch)
{
if (filterChar(ch))
fprintf(file, unprintableFormat, char16Value(ch));
else
fputc(static_cast<char>(ch), file);
}
// Write the null-terminated string str, escaping non-ASCII characters.
void JS::AsciiFileFormatter::printZStr8(const char *str)
{
if (filterEmpty)
fputs(str, file);
else
printStr8(str, str + strlen(str));
}
// Write the string between strBegin and strEnd, escaping non-ASCII characters.
void JS::AsciiFileFormatter::printStr8(const char *strBegin, const char *strEnd)
{
if (filterEmpty)
printChars(file, strBegin, strEnd);
else {
ASSERT(strEnd >= strBegin);
const char *p = strBegin;
while (strBegin != strEnd) {
char ch = *strBegin;
if (filterChar(ch)) {
if (p != strBegin) {
printChars(file, p, strBegin);
p = strBegin;
}
fprintf(file, unprintableFormat, static_cast<uchar>(ch));
}
++strBegin;
}
if (p != strBegin)
printChars(file, p, strBegin);
}
}
// Write the string between strBegin and strEnd, escaping non-ASCII characters.
void JS::AsciiFileFormatter::printStr16(const char16 *strBegin, const char16 *strEnd)
{
char buffer[512];
ASSERT(strEnd >= strBegin);
char *q = buffer;
while (strBegin != strEnd) {
char16 ch = *strBegin++;
if (filterChar(ch)) {
if (q != buffer) {
printChars(file, buffer, q);
q = buffer;
}
fprintf(file, unprintableFormat, char16Value(ch));
} else {
*q++ = static_cast<char>(ch);
if (q == buffer + sizeof buffer) {
printChars(file, buffer, buffer + sizeof buffer);
q = buffer;
}
}
}
if (q != buffer)
printChars(file, buffer, q);
}
JS::AsciiFileFormatter JS::stdOut(stdout);
JS::AsciiFileFormatter JS::stdErr(stderr);
// Write ch.
void JS::StringFormatter::printChar8(char ch)
{
s += ch;
}
// Write ch.
void JS::StringFormatter::printChar16(char16 ch)
{
s += ch;
}
// Write the null-terminated string str.
void JS::StringFormatter::printZStr8(const char *str)
{
s += str;
}
// Write the string between strBegin and strEnd.
void JS::StringFormatter::printStr8(const char *strBegin, const char *strEnd)
{
appendChars(s, strBegin, strEnd);
}
// Write the string between strBegin and strEnd.
void JS::StringFormatter::printStr16(const char16 *strBegin, const char16 *strEnd)
{
s.append(strBegin, strEnd);
}
// Write the String str.
void JS::StringFormatter::printString16(const String &str)
{
s += str;
}
//
// Formatted Output
//
// See "Prettyprinting" by Derek Oppen in ACM Transactions on Programming Languages and Systems 2:4,
// October 1980, pages 477-482 for the algorithm.
// The default line width for pretty printing
uint32 JS::PrettyPrinter::defaultLineWidth = 20;
// Create a PrettyPrinter that outputs to Formatter f. The PrettyPrinter breaks lines at
// optional breaks so as to try not to exceed lines of width lineWidth, although it may not
// always be able to do so. Formatter f should be at the beginning of a line.
// Call end before destroying the Formatter; otherwise the last line may not be output to f.
JS::PrettyPrinter::PrettyPrinter(Formatter &f, uint32 lineWidth):
lineWidth(min(lineWidth, unlimitedLineWidth)),
outputFormatter(f),
outputPos(0),
lineNum(0),
lastBreak(0),
margin(0),
nNestedBlocks(0),
leftSerialPos(0),
rightSerialPos(0),
itemPool(20)
{
#ifdef DEBUG
topRegion = 0;
#endif
}
// Destroy the PrettyPrinter. Because it's a very bad idea for a destructor to throw
// exceptions, this destructor does not flush any buffered output. Call end just before
// destroying the PrettyPrinter to do that.
JS::PrettyPrinter::~PrettyPrinter()
{
ASSERT(!topRegion && !nNestedBlocks);
}
// Output either a line break (if sameLine is false) or length spaces (if sameLine is true).
// Also advance leftSerialPos by length.
//
// If this method throws an exception, it is guaranteed to already have updated all of the
// PrettyPrinter state; all that might be missing would be some output to outputFormatter.
void JS::PrettyPrinter::outputBreak(bool sameLine, uint32 length)
{
leftSerialPos += length;
if (sameLine) {
outputPos += length;
// Exceptions may be thrown below.
printChar(outputFormatter, ' ', static_cast<int>(length));
} else {
lastBreak = ++lineNum;
outputPos = margin;
// Exceptions may be thrown below.
outputFormatter << '\n';
printChar(outputFormatter, ' ', static_cast<int>(margin));
}
}
// Check to see whether (rightSerialPos+rightOffset)-leftSerialPos has gotten so large that we may pop items
// off the left end of activeItems because their totalLengths are known to be larger than the
// amount of space left on the current line.
// Return true if there are any items left on activeItems.
//
// If this method throws an exception, it leaves the PrettyPrinter in a consistent state, having
// atomically popped off one or more items from the left end of activeItems.
bool JS::PrettyPrinter::reduceLeftActiveItems(uint32 rightOffset)
{
uint32 newRightSerialPos = rightSerialPos + rightOffset;
while (activeItems) {
Item *leftItem = &activeItems.front();
if (itemStack && leftItem == itemStack.front()) {
if (outputPos + newRightSerialPos - leftSerialPos > lineWidth) {
itemStack.pop_front();
leftItem->lengthKnown = true;
leftItem->totalLength = infiniteLength;
} else if (leftItem->lengthKnown)
itemStack.pop_front();
}
if (!leftItem->lengthKnown)
return true;
activeItems.pop_front();
try {
uint32 length = leftItem->length;
switch (leftItem->kind) {
case Item::text:
{
outputPos += length;
leftSerialPos += length;
// Exceptions may be thrown below.
char16 *textBegin;
char16 *textEnd;
do {
length -= itemText.pop_front(length, textBegin, textEnd);
printString(outputFormatter, textBegin, textEnd);
} while (length);
}
break;
case Item::blockBegin:
case Item::indentBlockBegin:
{
BlockInfo *b = savedBlocks.advance_back();
b->margin = margin;
b->lastBreak = lastBreak;
b->fits = outputPos + leftItem->totalLength <= lineWidth;
if (leftItem->hasKind(Item::blockBegin))
margin = outputPos;
else
margin += length;
}
break;
case Item::blockEnd:
{
BlockInfo &b = savedBlocks.pop_back();
margin = b.margin;
lastBreak = b.lastBreak;
}
break;
case Item::indent:
margin += length;
ASSERT(static_cast<int32>(margin) >= 0);
break;
case Item::linearBreak:
// Exceptions may be thrown below, but only after updating the PrettyPrinter.
outputBreak(lastBreak == lineNum && outputPos + leftItem->totalLength <= lineWidth, length);
break;
case Item::fillBreak:
// Exceptions may be thrown below, but only after updating the PrettyPrinter.
outputBreak(savedBlocks.back().fits, length);
break;
}
} catch (...) {
itemPool.destroy(leftItem);
throw;
}
itemPool.destroy(leftItem);
}
return false;
}
// A break or end of input is about to be processed. Check whether there are any complete
// blocks or clumps on the itemStack whose lengths we can now compute; if so, compute these
// and pop them off the itemStack.
// The current rightSerialPos must be the beginning of the break or end of input.
//
// This method can't throw exceptions.
void JS::PrettyPrinter::reduceRightActiveItems()
{
uint32 nUnmatchedBlockEnds = 0;
while (itemStack) {
Item *rightItem = itemStack.pop_back();
switch (rightItem->kind) {
case Item::blockBegin:
case Item::indentBlockBegin:
if (!nUnmatchedBlockEnds) {
itemStack.fast_push_back(rightItem);
return;
}
rightItem->computeTotalLength(rightSerialPos);
--nUnmatchedBlockEnds;
break;
case Item::blockEnd:
++nUnmatchedBlockEnds;
break;
case Item::linearBreak:
case Item::fillBreak:
rightItem->computeTotalLength(rightSerialPos);
if (!nUnmatchedBlockEnds)
return; // There can be at most one consecutive break posted on the itemStack.
break;
default:
ASSERT(false); // Other kinds can't be pushed onto the itemStack.
}
}
}
// Indent the beginning of every new line after this one by offset until the corresponding endIndent
// call. Return an Item to pass to endIndent that will end this indentation.
// This method may throw an exception, in which case the PrettyPrinter is left unchanged.
JS::PrettyPrinter::Item &JS::PrettyPrinter::beginIndent(int32 offset)
{
Item *unindent = new(itemPool) Item(Item::indent, static_cast<uint32>(-offset));
if (activeItems) {
try {
activeItems.push_back(*new(itemPool) Item(Item::indent, static_cast<uint32>(offset)));
} catch (...) {
itemPool.destroy(unindent);
throw;
}
} else {
margin += offset;
ASSERT(static_cast<int32>(margin) >= 0);
}
return *unindent;
}
// End an indent began by beginIndent. i should be the result of a beginIndent.
// This method can't throw exceptions (it's called by the Indent destructor).
void JS::PrettyPrinter::endIndent(Item &i)
{
if (activeItems)
activeItems.push_back(i);
else {
margin += i.length;
ASSERT(static_cast<int32>(margin) >= 0);
itemPool.destroy(&i);
}
}
// Begin a logical block. If kind is Item::indentBlockBegin, offset is the indent to use for
// the second and subsequent lines of this block.
// Return an Item to pass to endBlock that will end this block.
// This method may throw an exception, in which case the PrettyPrinter is left unchanged.
JS::PrettyPrinter::Item &JS::PrettyPrinter::beginBlock(Item::Kind kind, int32 offset)
{
uint32 newNNestedBlocks = nNestedBlocks + 1;
savedBlocks.reserve(newNNestedBlocks);
itemStack.reserve_back(1 + newNNestedBlocks);
Item *endItem = new(itemPool) Item(Item::blockEnd);
Item *beginItem;
try {
beginItem = new(itemPool) Item(kind, static_cast<uint32>(offset), rightSerialPos);
} catch (...) {
itemPool.destroy(endItem);
throw;
}
// No state modifications before this point.
// No exceptions after this point.
activeItems.push_back(*beginItem);
itemStack.fast_push_back(beginItem);
nNestedBlocks = newNNestedBlocks;
return *endItem;
}
// End a logical block began by beginBlock. i should be the result of a beginBlock.
// This method can't throw exceptions (it's called by the Block destructor).
void JS::PrettyPrinter::endBlock(Item &i)
{
activeItems.push_back(i);
itemStack.fast_push_back(&i);
--nNestedBlocks;
}
// Write a conditional line break. This kind of a line break can only be emitted inside a block.
//
// A linear line break starts a new line if the containing block cannot be put all one one line;
// otherwise the line break is replaced by nSpaces spaces.
// Typically a block contains several linear breaks; either they all start new lines or none of them do.
// Moreover, if a block directly contains a required break then linear breaks become required breaks.
//
// A fill line break starts a new line if either the preceding clump or the following clump cannot
// be placed entirely on one line or if the following clump would not fit on the current line. A
// clump is a consecutive sequence of strings and nested blocks delimited by either a break or the
// beginning or end of the currently enclosing block.
//
// If this method throws an exception, it leaves the PrettyPrinter in a consistent state.
void JS::PrettyPrinter::conditionalBreak(uint32 nSpaces, Item::Kind kind)
{
ASSERT(nSpaces <= unlimitedLineWidth && nNestedBlocks);
reduceRightActiveItems();
itemStack.reserve_back(1 + nNestedBlocks);
// Begin of exception-atomic stack update. Only new(itemPool) can throw an exception here,
// in which case nothing is updated.
Item *i = new(itemPool) Item(kind, nSpaces, rightSerialPos);
activeItems.push_back(*i);
itemStack.fast_push_back(i);
rightSerialPos += nSpaces;
// End of exception-atomic stack update.
reduceLeftActiveItems(0);
}
// Write the string between strBegin and strEnd. Any embedded newlines ('\n' only)
// become required line breaks.
//
// If this method throws an exception, it may have partially formatted the string but
// leaves the PrettyPrinter in a consistent state.
void JS::PrettyPrinter::printStr8(const char *strBegin, const char *strEnd)
{
while (strBegin != strEnd) {
const char *sectionEnd = findValue(strBegin, strEnd, '\n');
uint32 sectionLength = static_cast<uint32>(sectionEnd - strBegin);
if (sectionLength) {
if (reduceLeftActiveItems(sectionLength)) {
itemText.reserve_back(sectionLength);
Item &backItem = activeItems.back();
// Begin of exception-atomic update. Only new(itemPool)
// can throw an exception here, in which case nothing is updated.
if (backItem.hasKind(Item::text))
backItem.length += sectionLength;
else
activeItems.push_back(*new(itemPool) Item(Item::text, sectionLength));
rightSerialPos += sectionLength;
itemText.fast_append(reinterpret_cast<const uchar *>(strBegin), reinterpret_cast<const uchar *>(sectionEnd));
// End of exception-atomic update.
} else {
ASSERT(!itemStack && !activeItems && !itemText && leftSerialPos == rightSerialPos);
outputPos += sectionLength;
printString(outputFormatter, strBegin, sectionEnd);
}
strBegin = sectionEnd;
if (strBegin == strEnd)
break;
}
requiredBreak();
++strBegin;
}
}
// Write the string between strBegin and strEnd. Any embedded newlines ('\n' only)
// become required line breaks.
//
// If this method throws an exception, it may have partially formatted the string but
// leaves the PrettyPrinter in a consistent state.
void JS::PrettyPrinter::printStr16(const char16 *strBegin, const char16 *strEnd)
{
while (strBegin != strEnd) {
const char16 *sectionEnd = findValue(strBegin, strEnd, uni::lf);
uint32 sectionLength = static_cast<uint32>(sectionEnd - strBegin);
if (sectionLength) {
if (reduceLeftActiveItems(sectionLength)) {
itemText.reserve_back(sectionLength);
Item &backItem = activeItems.back();
// Begin of exception-atomic update. Only new(itemPool)
// can throw an exception here, in which case nothing is updated.
if (backItem.hasKind(Item::text))
backItem.length += sectionLength;
else
activeItems.push_back(*new(itemPool) Item(Item::text, sectionLength));
rightSerialPos += sectionLength;
itemText.fast_append(strBegin, sectionEnd);
// End of exception-atomic update.
} else {
ASSERT(!itemStack && !activeItems && !itemText && leftSerialPos == rightSerialPos);
outputPos += sectionLength;
printString(outputFormatter, strBegin, sectionEnd);
}
strBegin = sectionEnd;
if (strBegin == strEnd)
break;
}
requiredBreak();
++strBegin;
}
}
// Write a required line break.
//
// If this method throws an exception, it may have emitted partial output but
// leaves the PrettyPrinter in a consistent state.
void JS::PrettyPrinter::requiredBreak()
{
reduceRightActiveItems();
reduceLeftActiveItems(infiniteLength);
ASSERT(!itemStack && !activeItems && !itemText && leftSerialPos == rightSerialPos);
outputBreak(false, 0);
}
// Flush any saved output in the PrettyPrinter to the output. Call this just before
// destroying the PrettyPrinter. All Indent and Block objects must have been exited already.
//
// If this method throws an exception, it may have emitted partial output but
// leaves the PrettyPrinter in a consistent state.
void JS::PrettyPrinter::end()
{
ASSERT(!topRegion);
reduceRightActiveItems();
reduceLeftActiveItems(infiniteLength);
ASSERT(!savedBlocks && !itemStack && !activeItems && !itemText && rightSerialPos == leftSerialPos && !margin);
}
//
// Exceptions
//
static const char *const kindStrings[] = {
"Syntax error", // syntaxError
"Stack overflow" // stackOverflow
};
// Return a null-terminated string describing the exception's kind.
const char *JS::Exception::kindString() const
{
return kindStrings[kind];
}
// Return the full error message.
JS::String JS::Exception::fullMessage() const
{
String m(widenCString("In "));
m += sourceFile;
if (lineNum) {
char b[32];
sprintf(b, ", line %d:\n", lineNum);
m += b;
m += sourceLine;
m += '\n';
String sourceLine2(sourceLine);
insertChars(sourceLine2, charNum, "[ERROR]");
m += sourceLine2;
m += '\n';
} else
m += ":\n";
m += kindString();
m += ": ";
m += message;
m += '\n';
return m;
}
//
// Static Initializers
//
#ifndef _WIN32
static void jsNewHandler()
{
std::bad_alloc outOfMemory;
throw outOfMemory;
}
struct InitUtilities
{
InitUtilities() {std::set_new_handler(&jsNewHandler);}
};
#else
#include <new.h>
static int jsNewHandler(size_t)
{
std::bad_alloc outOfMemory;
throw outOfMemory;
}
struct InitUtilities
{
InitUtilities() {_set_new_handler(&jsNewHandler);}
};
#endif
InitUtilities initUtilities;