// unescape_html: decode HTML character references like Python's // html.unescape, except that references to control characters and // noncharacters decode to that code point (as the WHATWG tokenizer does) // instead of being deleted. // // Design // - One buffer holds both output and input. The input sits IN_OFF bytes in, // and output is written from the start. Every reference expands by at most // 1.2x (≪⃒ is 5 bytes in, 6 out), so the write cursor stays at least // IN_OFF - 0.2 * 1 MiB (about 51 KiB) behind the read cursor: decoding in // place is safe and memory stays near 1.25 MiB. // - A sentinel '&' after the input stops every scan, so the inner loops need // no bounds checks. The fast path copies 32 bytes at a time with SIMD and // stops only at '&'. // - Named references use a minimal perfect hash of the 2125 names in // html.entities.html5, generated offline. A scalar loop finds the name's length, // the name (zero-padded to 32 bytes) is hashed as four 64-bit words, and // every hit is verified against the stored name with two vector compares. // Legacy names without ';' (&, ©, ...) use the longest legacy prefix // of the name, as html.unescape does. // // Tables generated from Python 3.14's html.entities.html5. // Build (zig 0.15.2): zig cc -target wasm32-freestanding // -mcpu=generic+simd128 -O3 -s -nostdlib -Wl,--no-entry // -Wl,-z,stack-size=4096 -Wl,--max-memory=1376256 -o unescape_html.wasm unescape_html.c #include typedef unsigned char u8; typedef unsigned short u16; typedef unsigned int u32; typedef unsigned long long u64; #define OUT_CAP 1310720u #define IN_CAP 1048576u #define IN_OFF (OUT_CAP - IN_CAP) static u8 buf[OUT_CAP + 64] __attribute__((aligned(16))); __attribute__((export_name("input_ptr"))) u32 input_ptr(void) { return (u32)(buf + IN_OFF); } __attribute__((export_name("input_utf8_cap"))) u32 input_utf8_cap(void) { return IN_CAP; } __attribute__((export_name("output_utf8_cap"))) u32 output_utf8_cap(void) { return OUT_CAP; } #define N 2125u #define B 600u static const u16 DISP[B] = { 13,1,9,9,33,6,15,2,9,60,6,105,2,59,91,8, 1,11,62,9,13,5,61,3,4,0,3,12,6,1,150,25, 42,18,17,10,32,155,5,138,2,4,38,6,3,47,1,30, 56,3,7,2,7,37,1,9,8,11,11,5,35,56,1,24, 7,25,2,70,1,41,36,1,84,19,15,1,21,28,16,37, 1,8,0,13,7,26,4,25,5,93,101,34,19,10,86,1, 23,56,20,3,1,1,7,1,148,0,196,14,6,5,120,31, 3,28,1,16,2,114,1,1,101,25,47,5,138,52,12,2, 110,14,77,6,2,1,26,92,25,32,12,17,19,27,1,18, 6,52,0,128,4,3,27,84,14,6,82,0,190,0,11,35, 153,26,5,1,1,3,70,249,2,11,4,1,7,0,30,70, 75,58,38,185,21,1,60,2,26,28,1,2,6,66,0,105, 27,32,3,79,112,7,6,12,13,4,0,1,34,160,248,98, 0,2,2,9,6,1,95,135,3,9,64,82,17,16,9,307, 131,245,16,17,0,25,4,17,9,1,0,6,70,2,3,158, 2,222,8,6,159,63,266,13,144,61,3,36,5,2,8,150, 99,12,1,46,57,1,1,3,155,7,3,46,23,234,9,106, 0,0,118,73,20,10,94,21,129,7,899,48,6,52,102,2, 5,202,776,317,15,16,0,14,12,145,49,15,129,51,31,61, 15,319,72,6,355,19,0,64,29,10,0,1,2,34,176,28, 19,154,618,9,426,101,69,65,2,213,1,4,3,1,1,1, 36,109,1,530,22,6,6,8,10,0,58,140,539,6,119,28, 61,13,19,72,17,9,102,12,27,1,84,24,14,43,14,213, 6,129,243,252,338,1,2,4,83,3,26,14,35,53,1,25, 194,2,180,27,66,72,267,12,14,1,18,1,79,133,0,64, 13,1,27,2,161,25,173,102,101,3,16,20,3,25,139,2, 139,1,8,157,64,110,53,24,5,157,94,263,3,530,686,2, 214,159,40,13,135,2,2,59,4,114,7,380,0,5,29,319, 20,6,147,120,327,326,10,170,1,315,0,1,143,60,76,0, 49,3,336,16,34,327,8,333,5,221,1,53,16,31,249,962, 326,27,78,448,0,133,617,6,65,1,32,53,5,6,41,4, 88,232,279,1,854,237,59,2,12,33,169,137,1,36,420,407, 906,230,109,48,133,731,3,290,480,70,118,222,70,92,392,57, 0,209,8,86,265,389,19,1,88,1,341,817,371,0,22,2, 111,22,45,71,682,2,397,954,161,8,683,100,1183,543,1,1221, 2,8,264,1154,667,1872,72,0,53,496,35,694,78,4,253,553, 332,8,248,44,50,566,672,869,82,33,331,7,21,128,523,421, 844,1,126,1,7,4,641,384 }; // Per slot, in byte planes so the tables compress well: name length, the // first code point's low and high bytes, and META: bit 0 is the code point's // bit 16, bits 1-4 are index+1 into SECOND (0 if none), and bit 5 marks a // legacy name that is also valid without ';'. static const u8 LENS[N + 16] = { 14,6,6,6,7,18,3,15,5,5,4,16,18,6,11,4,5,5,6,5,9,4,4,8,4,5,4,4,6,6,6,2, 17,3,4,5,6,10,13,5,6,5,4,5,6,13,6,5,5,4,14,11,6,7,10,7,12,6,4,5,5,4,5,6, 5,10,6,4,4,4,2,6,7,12,6,6,18,5,12,7,6,4,2,6,6,3,5,4,4,20,5,11,6,6,7,5, 17,8,8,5,14,5,5,4,4,7,12,5,4,3,5,5,14,4,13,4,4,6,6,4,4,2,3,5,3,9,4,5, 18,4,4,7,5,6,6,4,7,6,3,5,7,7,5,4,4,6,6,3,6,5,5,5,5,12,4,14,5,7,5,3, 5,6,6,5,5,16,6,21,2,3,10,6,5,3,7,14,5,5,8,17,11,6,5,6,5,8,6,5,6,4,4,4, 8,11,4,3,6,9,5,6,3,6,6,16,12,4,5,4,6,15,8,6,5,13,7,7,6,7,6,7,6,6,9,6, 2,3,6,2,9,8,6,4,5,6,8,5,5,8,6,5,13,5,6,5,5,3,5,4,5,6,6,18,10,5,4,6, 3,6,3,6,15,4,3,4,3,4,10,2,5,11,5,6,4,9,5,6,10,16,6,4,3,15,10,13,4,4,4,6, 4,7,14,6,4,3,5,7,8,6,3,9,14,13,3,5,15,4,5,3,22,6,4,3,5,8,31,14,3,7,6,10, 6,4,3,6,3,5,6,6,3,3,8,5,6,5,6,4,7,4,7,10,4,6,5,4,4,10,9,5,10,8,4,4, 15,8,6,4,11,19,6,5,6,4,4,16,6,9,5,5,6,4,2,8,6,3,17,3,9,9,5,3,3,14,4,5, 6,4,4,5,12,4,16,4,4,4,3,7,3,5,6,3,4,8,8,7,16,6,4,13,5,4,3,6,6,3,6,6, 7,9,5,7,6,3,16,6,14,6,6,8,11,5,2,4,12,7,5,3,4,5,3,6,5,3,6,6,5,3,17,6, 5,15,10,6,11,6,3,3,14,4,16,7,10,6,12,4,5,3,13,4,7,3,6,5,4,20,4,8,5,19,6,7, 14,5,5,7,19,8,6,8,6,5,5,4,4,14,6,3,6,4,8,3,4,3,6,5,4,18,8,15,6,6,5,5, 4,13,5,4,11,4,5,5,4,9,5,19,5,3,3,5,7,6,8,4,3,7,3,7,3,6,5,7,3,9,10,5, 6,6,5,3,6,6,16,4,4,6,4,4,15,8,14,5,10,5,5,14,6,6,13,4,6,5,5,5,8,4,4,8, 9,7,7,17,4,5,3,3,3,6,5,4,6,5,4,7,2,9,4,5,7,22,7,6,8,5,3,5,5,5,4,14, 5,7,5,13,5,10,17,6,4,7,18,5,13,4,10,8,11,10,15,4,7,6,4,6,14,12,6,5,8,2,7,14, 2,4,11,5,4,15,7,3,5,5,4,5,6,6,5,6,5,6,2,5,3,3,10,11,4,4,6,3,6,5,20,15, 8,7,5,5,4,6,9,4,14,4,6,6,18,13,6,13,4,3,4,4,5,4,14,4,7,21,5,2,6,4,6,3, 7,19,11,9,7,4,5,4,4,4,4,6,10,5,8,17,6,4,6,6,6,5,8,2,7,6,6,3,4,5,5,3, 8,15,4,20,3,6,8,7,6,4,11,11,3,5,4,9,10,16,5,9,15,7,3,7,6,9,8,12,19,4,8,3, 4,8,5,11,9,3,6,5,4,4,6,5,11,16,2,8,4,17,6,9,6,21,6,3,5,10,7,4,6,5,6,6, 5,7,3,5,6,13,4,5,6,4,5,17,11,6,4,20,4,6,4,6,15,4,7,6,3,7,3,8,6,6,3,4, 6,5,4,4,3,6,4,18,6,5,4,9,5,2,10,5,6,3,5,6,6,6,5,8,5,14,6,3,5,5,4,4, 3,6,7,5,8,7,3,6,8,5,6,4,4,14,3,8,3,3,8,6,7,9,5,6,3,6,8,6,3,6,5,14, 15,4,5,5,3,5,3,5,3,6,7,6,11,4,6,6,6,6,18,4,10,5,4,5,7,6,4,6,6,6,2,5, 6,9,5,4,6,4,4,5,6,3,3,6,4,6,5,4,3,5,4,7,8,6,4,4,2,5,6,6,3,5,5,4, 4,6,6,6,6,4,4,6,3,4,3,2,4,4,12,6,6,13,3,4,6,2,4,4,6,6,4,5,3,13,3,6, 5,5,6,10,4,2,4,6,8,5,5,4,4,4,6,5,13,3,5,15,14,6,5,4,3,4,6,4,8,3,4,5, 5,3,5,10,2,11,4,6,6,7,5,5,3,5,16,8,4,4,6,2,6,3,5,4,5,6,10,2,7,16,6,5, 3,7,5,6,5,16,9,7,9,7,14,3,2,4,17,5,7,7,4,6,6,4,7,2,5,6,8,3,3,2,4,3, 3,24,5,8,6,6,13,5,5,4,6,8,2,2,6,8,7,6,6,3,9,6,6,10,3,6,4,21,6,6,6,5, 3,5,5,4,4,3,7,6,8,13,5,4,4,5,4,3,6,10,6,3,14,2,14,5,4,9,16,16,5,5,6,11, 3,3,4,3,6,8,6,7,5,4,6,6,5,6,4,5,5,6,3,4,5,3,3,5,6,15,3,9,6,5,5,4, 4,5,6,6,7,3,7,5,8,5,3,4,5,4,9,11,5,3,6,6,5,5,8,9,4,6,3,8,3,6,5,4, 5,13,14,5,6,15,5,6,5,4,6,5,8,3,5,4,5,3,3,5,16,6,6,4,14,3,9,16,4,8,6,4, 4,6,7,7,9,6,5,3,4,6,4,6,5,6,3,6,4,5,6,6,5,4,5,13,7,3,5,12,6,5,13,5, 15,6,4,6,5,5,8,6,3,5,7,5,16,6,3,4,6,4,5,6,5,4,5,7,7,6,6,10,17,2,7,11, 9,5,14,4,13,4,4,7,4,7,16,7,2,10,20,5,4,6,4,3,5,4,4,6,5,5,6,5,8,9,6,18, 4,17,5,4,6,4,10,12,5,6,5,6,4,12,5,4,13,7,3,7,6,6,6,4,5,6,5,5,6,7,6,3, 13,2,3,5,17,8,3,3,12,8,7,5,4,13,4,6,4,5,8,5,7,7,7,11,5,5,19,11,5,3,7,5, 7,2,6,4,5,5,4,5,17,6,6,11,3,6,6,3,2,4,6,9,13,8,6,5,5,5,5,6,9,4,4,16, 11,4,4,5,4,8,4,6,3,5,6,2,4,5,6,4,7,5,17,6,6,3,6,17,8,3,6,8,4,4,3,7, 7,5,4,6,6,6,4,5,6,8,4,10,5,7,2,7,5,6,5,3,4,15,19,13,8,3,6,6,5,5,3,4, 5,3,8,5,5,6,3,5,6,7,2,6,8,2,12,16,6,7,5,13,3,20,6,12,14,4,10,5,6,8,6,6, 8,7,4,23,6,5,6,5,12,8,5,5,4,7,4,6,14,10,3,3,5,6,5,4,7,6,5,13,6,6,4,13, 5,6,5,15,7,3,6,5,8,5,9,5,6,12,11,4,4,4,6,5,4,15,5,11,5,7,4,7,3,4,5,17, 5,4,5,3,12,8,9,3,4,4,4,5,4,5,5,17,8,5,4,4,2,4,5,5,9,8,7,4,4,3,12,3, 4,5,14,15,5,3,5,5,2,18,8,6,4,4,7,6,3,4,16,6,4,3,8,4,4,5,9,5,5,3,5,4, 8,7,4,5,5,11,7,14,6,4,18,3,7,13,5,5,3,4,8,6,9,21,7,5,5,5,16,6,5,11,2,15, 17,6,13,6,5,8,11,9,4,14,5,4,3,6,6,12,5,5,7,6,3,5,5,15,15,21,6,13,11,5,9,5, 3,5,2,7,4,14,3,13,4,5,16,13,4,4,3,24,9,6,4,6,6,9,8,5,11,6,5,4,8,2,4,7, 7,11,4,4,5,5,15,4,6,12,4,5,5,3,3,7,7,5,5,4,5,4,10,12,5,6,3,5,7,6,6,12, 6,3,5,5,14,5,8,20,3,4,6,6,5,5,12,9,8,8,10,6,6,9,10,14,3,12,4,18,10,3,2,6, 4,5,5,5,4,7,6,7,10,4,2,17,3,6,5,4,5,4,5,20,5,11,5,8,5,5,6,6,14,6,2,7, 4,4,3,6,6,4,4,16,5,9,8,5,4,6,13,7,4,6,7,16,5,8,10,4,6,7,3,4,5,17,4,4, 5,3,5,3,3,5,8,5,6,6,4,5,4,7,4,4,11,4,14,4,3,4,7,6,5,4,3,9,6,8,7,18, 5,3,13,6,4,5,17,6,4,5,6,3,17,8,6,4,3,4,6,18,4,4,3,4,8,16,5,6,3,2,3,5, 7,12,15,6,9,5,7,5,14,4,10,6,9,8,6,4,8,7,8,15,4,4,3,6,15,14,13,6,5,6,5,4, 9,4,6,12,4,4,7,3,5,8,4,4,8,4,6,5,6,5,4,13,3,5,5,6,3,6,7,6,15,6,4,6, 6,5,3,4,3,7,5,10,3,5,5,6,4,6,5,8,4,4,3,11,3,3,11,10,3,5,5,5,3,5,3,4, 17,5,3,6,5,5,7,4,4,5,8,4,8,4,4,3,2,4,5,20,6,7,8,5,5,3,3,4,17,9,6,6, 6,5,19,5,8,4,5,6,4,4,4,5,6,3,6,8,4,2,6,5,6,5,6,3,3,5,15,5,5,4,21,6, 20,15,6,4,4,14,5,6,10,6,4,6,5 }; static const u8 LO[N] = { 36,9,170,212,221,181,20,189,60,200,214,84,93,195,8,78,44,75,237,45,147,172,187,134, 26,70,83,195,37,182,12,70,233,94,161,206,182,95,73,222,233,82,153,1,6,33,243,230, 186,166,121,125,221,176,188,62,101,165,56,51,114,206,254,211,130,154,201,115,181,78,187,215, 53,164,146,84,207,206,194,222,208,125,123,89,139,35,108,191,67,28,92,102,175,233,194,90, 11,6,36,28,98,145,108,38,146,39,228,197,90,34,185,147,24,79,245,28,195,185,45,220, 93,84,217,125,125,97,195,82,247,106,158,216,180,88,55,178,127,40,171,79,52,195,148,213, 237,88,177,37,68,63,47,7,217,191,235,162,12,53,121,23,107,60,22,55,14,92,111,11, 106,174,145,209,96,55,114,190,158,194,161,126,150,42,144,36,93,37,237,99,249,69,210,53, 209,129,252,60,220,142,77,189,50,141,106,221,145,54,34,56,155,117,73,53,117,68,221,145, 8,193,5,126,183,2,9,89,72,5,109,72,139,16,176,64,115,98,81,179,80,226,21,233, 135,105,23,193,214,101,24,7,20,7,236,147,204,4,92,214,236,199,106,12,178,104,170,38, 39,160,223,156,1,223,136,24,62,219,138,58,139,193,31,66,47,204,183,82,196,105,107,115, 89,167,235,107,135,18,128,190,51,172,129,144,202,180,208,186,186,213,231,218,227,159,193,7, 174,17,51,203,30,192,147,150,79,155,17,26,176,102,241,67,176,91,56,144,33,72,211,103, 164,178,61,133,40,232,88,172,15,11,125,239,252,181,167,171,245,11,94,33,246,196,233,31, 100,37,65,194,84,17,147,206,11,156,62,19,151,37,145,13,10,126,5,103,110,249,146,169, 71,100,181,199,143,39,245,146,95,39,53,144,73,152,37,48,123,171,131,87,127,26,170,234, 17,162,9,193,213,74,42,3,124,96,85,191,236,44,232,64,147,187,62,74,95,180,71,178, 29,253,202,216,122,143,11,152,103,61,192,243,146,200,107,113,214,208,198,239,128,194,166,176, 148,138,81,110,167,48,11,3,36,42,179,60,130,22,156,76,10,212,191,35,132,173,128,9, 38,223,126,0,198,180,227,138,167,255,155,255,23,172,33,15,38,112,21,65,21,40,164,16, 2,125,228,143,253,10,73,192,98,209,254,235,119,207,72,175,12,109,80,146,236,100,212,55, 31,93,18,169,217,154,26,80,42,240,231,15,175,197,67,9,54,96,201,111,10,85,187,184, 124,173,8,175,198,21,11,18,44,104,49,180,218,204,90,32,157,9,12,140,88,193,91,200, 2,143,159,125,134,97,169,75,55,46,194,22,213,184,85,175,102,79,169,102,227,221,184,161, 19,154,66,60,157,207,97,144,49,178,238,248,84,149,252,131,162,97,203,173,199,201,1,95, 148,210,189,2,103,138,13,232,148,98,6,246,13,160,196,212,103,246,186,244,66,151,60,35, 248,18,154,23,57,68,148,123,3,2,177,229,173,247,9,13,57,203,49,58,64,154,226,206, 65,33,238,84,74,80,38,173,144,81,52,52,250,190,64,188,218,32,61,183,185,41,91,182, 197,225,116,216,149,114,4,44,115,11,48,168,180,92,203,233,164,170,200,199,165,62,168,12, 242,205,101,68,16,218,122,189,120,188,99,63,106,215,228,47,206,194,213,236,23,166,46,57, 96,94,151,157,240,187,157,208,207,220,107,218,78,118,172,141,87,147,186,195,208,167,179,104, 67,175,247,72,211,145,194,102,235,111,40,122,149,179,97,109,10,37,94,4,253,170,41,61, 234,197,105,40,126,68,61,53,14,119,83,38,0,97,165,174,13,36,201,213,213,8,41,249, 86,175,148,34,234,106,226,87,168,49,202,174,27,13,219,22,161,199,6,15,167,18,87,11, 177,28,0,19,199,107,205,169,34,208,116,56,16,210,137,123,83,0,187,35,65,92,112,183, 62,150,245,7,2,77,56,14,58,187,203,190,185,11,33,23,27,25,182,30,158,198,111,29, 52,202,172,236,139,17,113,192,78,48,168,215,10,106,150,51,146,95,38,78,154,107,122,42, 3,220,184,175,55,151,102,79,72,55,182,90,171,41,188,117,120,144,124,66,127,113,1,223, 160,63,165,76,211,89,53,175,34,52,46,121,209,225,100,178,24,69,93,174,19,98,163,99, 35,118,147,71,176,77,149,70,210,85,19,8,153,195,83,11,125,191,60,88,72,158,219,212, 216,90,72,83,40,204,38,31,165,25,57,72,38,62,189,147,182,129,80,49,159,204,186,77, 229,161,142,25,246,40,76,46,43,252,22,136,232,168,207,58,41,40,8,146,217,149,45,54, 34,109,29,242,177,237,158,99,103,125,35,40,102,68,230,181,22,189,203,69,8,103,109,52, 43,142,30,231,210,237,26,177,183,22,163,39,122,91,79,60,246,131,2,72,44,90,53,60, 143,201,157,128,36,60,76,54,31,50,86,169,59,41,126,17,169,2,51,144,106,100,174,233, 119,116,95,42,92,44,3,49,164,200,123,29,60,112,32,150,211,214,2,173,59,183,12,126, 30,102,215,92,185,205,219,180,57,140,35,28,125,190,69,195,192,52,175,96,157,0,150,213, 165,192,55,77,243,221,22,20,134,196,121,205,103,5,181,203,111,91,67,34,226,57,107,161, 245,96,193,138,27,168,234,197,165,52,249,148,181,164,163,142,75,171,135,12,139,185,52,170, 110,113,21,97,145,250,173,183,34,70,102,192,168,25,128,70,145,176,136,15,245,196,180,241, 239,174,29,67,131,52,118,96,2,16,49,235,160,1,4,232,195,136,105,180,186,1,190,92, 52,46,10,151,114,227,101,51,42,84,75,166,198,56,209,169,208,246,213,170,253,87,163,175, 95,193,114,78,62,111,70,190,146,85,158,59,194,160,181,30,93,102,85,83,219,69,50,95, 91,59,32,204,179,179,5,210,247,56,198,72,190,188,42,192,177,36,120,172,245,239,9,4, 232,150,210,254,99,18,69,197,71,4,67,48,63,48,99,15,58,53,4,192,28,136,217,85, 92,204,36,2,250,235,176,112,39,148,163,30,124,71,6,21,203,96,140,149,247,3,75,54, 178,127,16,110,39,124,58,35,185,157,38,51,230,43,14,27,181,4,52,91,208,127,203,67, 184,245,96,153,5,130,32,118,42,172,80,185,162,105,14,60,181,28,151,61,82,24,132,210, 88,104,209,35,14,15,106,46,200,209,28,22,228,60,24,136,89,222,86,91,16,16,159,235, 24,44,43,149,93,159,183,45,38,207,194,30,26,204,103,137,53,12,86,240,241,36,81,71, 37,28,34,206,100,176,41,60,194,104,180,61,86,85,133,180,77,135,51,164,26,45,101,166, 50,26,221,32,150,88,248,66,240,17,69,48,204,249,151,10,93,9,28,248,9,98,29,251, 248,239,96,125,5,119,115,201,85,59,141,12,19,126,29,116,99,182,245,253,108,49,22,4, 76,209,15,162,22,147,92,76,124,31,190,20,105,110,251,25,153,200,133,179,54,183,196,180, 114,170,110,37,95,64,123,22,197,221,191,181,187,30,203,66,125,250,134,179,79,138,131,47, 86,84,108,189,33,183,173,106,217,73,121,123,176,90,94,97,61,18,96,131,9,72,19,126, 75,183,36,228,87,35,205,180,143,8,158,199,107,145,97,113,2,74,196,54,82,41,191,199, 16,14,83,195,184,20,37,191,62,95,160,0,69,40,108,15,26,61,208,86,1,149,229,37, 147,11,137,181,19,31,115,246,255,102,65,219,177,134,153,246,46,66,247,8,152,82,47,242, 64,197,22,224,222,237,123,114,66,110,197,200,34,207,98,157,89,209,166,105,25,137,219,29, 219,170,188,22,13,36,193,178,229,119,15,190,75,106,5,193,236,47,204,171,204,19,205,249, 45,105,19,56,82,150,24,110,198,0,218,179,170,68,17,250,153,95,144,225,51,53,174,195, 222,124,28,11,18,11,182,61,48,124,25,135,24,44,113,81,14,167,126,30,205,32,165,191, 20,13,78,210,131,194,155,235,50,74,112,0,201,110,130,71,145,198,91,177,6,197,132,107, 17,101,66,38,171,161,19,130,35,165,66,200,87,101,5,182,203,139,179,124,218,5,153,201, 98,191,195,35,101,176,232,145,146,176,17,160,4,63,139,81,152,185,190,111,34,180,71,5, 197,90,16,63,168,192,192,104,62,102,74,199,83,194,241,137,94,212,80,181,120,5,162,116, 54,15,27,251,249,194,18,34,23,214,28,189,117,94,109,80,216,45,46,193,168,230,126,29, 87,41,234,8,29,36,5,177,149,83,106,198,43,197,165,224,119,197,164,161,37,162,32,87, 165,51,64,30,250,216,194,162,41,55,220,161,161,245,125,101,59,27,86,231,181,70,134,202, 231,176,159,176,196,118,15,133,202,112,220,88,36,26,129,29,199,182,111,148,104,16,51,115, 73,215,16,207,219,12,25,188,174,217,169,195,127,29,212,228,219,47,65,79,120,89,34,112, 216,50,169,212,184,79,172,102,73,241,104,10,12,99,189,5,17,238,196,64,152,6,198,15, 163,245,18,11,166,84,198,146,16,4,95,191,86,230,219,54,16,37,24,244,7,174,155,184, 217,202,19,181,45,68,252,32,144,29,62,38,186,209,53,152,77,245,200,231,17,218,60,130, 154,80,144,171,189,218,29,244,146,33,49,166,203,51,13,2,19,43,103,181,38,196,198,117, 32,207,179,184,47,177,74,170,198,64,39,181,84,240,124,214,39,220,46,184,100,78,224,28, 38,211,25,29,3,189,146,101,177,20,160,12,87 }; static const u8 HI[N] = { 34,32,33,42,33,34,4,37,42,33,0,41,41,34,35,4,0,34,34,34,33,42,212,34, 33,34,4,41,42,34,35,33,39,0,33,33,33,32,34,34,39,37,3,251,42,34,34,0, 33,212,34,34,0,41,33,32,34,34,42,41,1,212,33,42,34,33,41,42,3,34,42,34, 34,33,34,33,41,0,34,41,34,42,34,1,34,4,37,37,42,32,37,38,42,34,42,37, 32,42,33,37,32,41,34,4,3,42,33,41,42,213,42,37,32,213,39,33,34,34,42,0, 213,42,2,34,42,34,212,34,39,34,42,42,0,1,1,33,34,1,42,34,42,42,3,34, 42,33,35,213,34,42,1,34,33,37,39,42,34,41,42,213,1,1,32,33,38,41,42,32, 34,0,34,0,0,4,41,33,34,37,42,42,34,41,33,0,1,41,0,38,0,4,3,4, 3,34,0,4,32,34,1,0,4,34,42,35,33,4,33,213,3,34,41,32,1,34,3,33, 32,42,32,34,33,1,32,33,34,213,1,33,34,33,35,213,39,34,34,34,34,35,35,42, 34,37,34,33,34,34,1,4,32,1,0,34,42,4,0,42,42,0,34,1,34,34,42,32, 213,0,35,3,1,34,34,33,213,32,34,1,42,33,35,42,213,34,42,41,0,34,213,34, 4,41,34,41,34,213,34,34,34,34,34,33,33,37,0,42,33,3,39,34,34,34,212,34, 33,33,34,34,4,42,42,42,34,34,33,32,42,42,0,1,33,42,34,42,34,34,0,34, 34,3,34,42,41,0,37,212,34,35,42,37,39,42,0,212,3,34,33,1,3,33,0,34, 1,34,34,33,1,3,34,34,35,212,0,35,34,34,34,213,35,42,34,34,34,39,1,42, 1,213,212,33,34,0,33,33,213,4,213,41,34,33,0,213,34,41,42,42,34,1,37,34, 42,0,0,34,3,34,4,34,42,38,37,3,34,34,39,1,33,3,1,41,32,34,33,212, 34,34,0,34,34,34,34,42,37,0,0,0,33,3,34,1,3,33,42,42,34,34,33,0, 33,42,41,34,33,32,33,32,1,0,37,213,42,213,41,42,1,33,212,42,37,33,42,34, 34,0,34,42,33,41,41,42,34,33,33,0,1,33,32,32,1,34,42,4,4,33,0,37, 33,34,41,34,0,32,1,34,41,33,0,0,34,212,34,0,4,34,34,34,39,34,33,34, 41,0,42,0,34,41,4,42,213,3,34,41,42,42,34,1,35,38,3,34,35,1,33,212, 0,34,34,212,33,33,32,1,33,34,34,34,0,42,41,39,33,34,41,41,42,34,0,39, 33,41,3,42,34,37,3,4,213,0,33,32,42,34,213,42,34,34,212,37,34,2,0,37, 42,33,4,34,33,33,213,33,1,41,42,39,4,34,37,34,212,34,33,42,34,212,34,0, 34,33,33,37,41,34,33,39,33,34,35,3,42,3,42,33,34,41,42,34,34,33,41,0, 37,34,34,39,32,42,34,0,34,42,0,0,0,0,34,33,213,212,1,4,0,3,34,33, 34,32,0,37,213,1,34,37,34,37,32,34,39,33,38,33,34,4,213,212,41,41,41,42, 3,34,34,34,41,34,32,213,41,32,33,0,34,34,33,39,41,212,212,42,33,32,41,34, 0,212,38,1,1,33,34,3,42,0,1,34,213,34,42,0,41,33,33,34,4,0,35,42, 1,213,34,34,0,33,42,33,34,2,37,34,34,34,0,41,1,33,34,37,41,42,41,34, 213,41,39,34,33,42,3,0,42,34,33,42,33,34,32,42,33,34,1,34,42,37,1,4, 0,42,41,4,41,34,0,34,4,34,42,34,34,32,34,42,41,34,33,33,33,4,34,39, 42,34,33,1,34,38,34,33,3,32,37,41,41,1,34,4,37,2,38,4,3,33,4,32, 0,32,37,39,2,34,33,34,34,34,1,1,32,0,34,34,37,37,34,34,32,1,42,34, 4,41,34,32,34,34,4,1,42,0,42,212,37,34,213,42,213,4,35,32,34,42,41,41, 213,34,41,37,42,1,42,33,41,1,34,33,213,1,42,1,42,42,42,34,34,34,1,0, 41,3,37,0,34,33,34,32,41,42,3,1,33,41,3,42,41,33,34,213,41,34,4,34, 34,4,0,4,33,34,1,42,4,37,4,41,3,0,34,0,33,42,33,37,4,37,3,41, 34,41,41,42,34,213,33,1,34,4,33,34,34,37,34,33,41,33,34,213,1,3,32,34, 0,33,4,34,213,42,0,1,34,32,41,33,34,0,0,34,42,34,34,33,33,212,34,42, 33,37,42,32,39,41,1,34,4,39,35,42,34,0,0,0,33,34,1,33,34,42,34,1, 32,42,32,42,33,39,33,38,213,0,41,34,1,4,34,42,34,34,42,33,34,34,41,33, 213,41,32,0,3,34,33,41,0,42,33,34,34,213,41,37,34,34,34,34,33,213,34,0, 42,0,41,34,4,0,213,213,4,34,37,41,34,42,34,33,3,32,33,34,34,34,34,34, 42,42,0,34,34,4,1,33,3,42,0,32,34,1,32,33,34,33,34,42,213,3,34,1, 35,34,0,213,0,41,42,42,1,42,35,213,42,3,34,34,212,34,42,0,34,42,34,3, 42,41,41,4,42,41,34,42,41,41,1,0,34,35,37,42,38,33,4,32,0,4,34,0, 0,41,34,34,1,42,34,3,212,1,34,42,34,42,34,34,41,34,42,32,34,212,34,37, 34,34,32,1,3,39,41,0,0,42,34,34,0,33,37,4,37,42,34,41,1,33,3,42, 34,212,34,34,34,4,1,213,251,4,213,34,0,42,42,42,33,42,34,0,0,42,42,4, 33,34,0,33,34,0,37,213,34,34,34,33,33,33,34,33,42,39,0,37,33,34,0,42, 34,41,42,34,34,1,33,41,33,33,212,1,0,42,37,1,42,38,34,1,34,41,213,4, 0,0,34,34,3,33,38,33,34,34,34,34,37,42,42,33,0,34,34,32,39,0,4,34, 39,33,33,34,32,41,33,33,4,41,34,4,0,33,213,35,34,33,34,33,33,34,0,41, 42,33,37,4,0,41,35,41,34,34,34,41,1,33,4,33,42,32,42,3,0,251,42,33, 34,42,41,41,1,35,32,213,37,3,0,32,39,34,213,4,35,42,33,37,33,34,0,32, 42,3,34,33,38,34,39,34,1,42,41,42,34,34,33,34,3,33,42,34,1,32,34,42, 39,1,34,34,32,33,41,213,36,33,41,34,42,34,34,37,37,0,4,1,34,33,212,34, 34,33,0,34,0,34,42,35,213,34,3,33,34,33,1,42,33,37,41,42,3,213,1,34, 34,33,35,34,41,212,34,42,41,37,35,1,1,34,34,37,34,34,33,33,34,33,34,41, 32,41,2,213,3,41,39,34,3,34,1,42,42,37,3,4,37,213,35,39,35,1,4,0, 0,37,34,0,34,34,34,33,42,42,42,33,213,42,32,34,32,212,3,42,41,42,33,251, 34,33,33,42,41,3,33,34,0,35,33,37,213,38,34,41,33,33,42,42,34,0,33,212, 34,34,1,34,1,42,1,34,0,3,34,34,41,213,34,34,42,37,42,37,34,34,34,33, 34,213,1,37,0,33,33,34,42,34,34,42,33,4,4,41,35,33,37,34,35,42,34,42, 213,41,33,33,213,35,33,34,34,34,33,212,34,33,34,41,42,34,34,41,4,213,33,3, 35,41,41,33,0,213,1,33,34,41,34,34,34,0,34,33,213,34,41,34,34,42,41,32, 33,4,34,1,32,213,1,0,39,41,213,0,37,34,33,39,42,38,39,213,33,34,42,34, 4,34,34,34,35,34,41,39,34,38,33,0,33,33,32,33,41,3,33,1,1,42,33,34, 2,33,33,1,32,41,0,34,33,1,34,0,1,37,1,33,34,34,0,33,33,1,34,39, 33,34,34,41,213,33,213,41,212,251,34,34,0,213,213,39,34,34,33,34,42,32,0,3, 34,0,1,1,35,34,0,41,34,34,33,42,37,37,34,4,35,33,42,34,34,34,34,42, 34,41,34,33,34,34,34,41,1,42,34,1,39,42,34,33,34,3,4,3,35,0,42,34, 34,41,1,32,0,34,41,34,34,33,34,34,32,38,34,33,37,34,212,34,33,41,42,34, 213,41,33,36,34,42,34,33,34,42,33,33,213,35,41,34,3,3,37,41,35,35,34,35, 42,34,34,1,34,34,3,41,0,213,1,34,33,212,3,34,37,34,34,41,34,34,33,41, 39,33,33,37,34,3,33,0,33,34,4,212,34,41,38,37,2,4,1,3,0,39,42,34, 34,4,39,35,33,42,4,212,33,213,34,42,34,42,3,0,42,212,34,34,41,34,41,41, 41,4,34,35,34,33,37,33,0,2,41,3,42,34,1,213,4,33,33,39,35,213,42,212, 35,42,42,42,3,34,213,41,37,34,35,4,34,32,42,1,33,41,34,41,34,42,41,34, 42,42,41,41,34,42,213,41,33,2,33,0,34,35,0,0,34,4,1,34,1,213,42,42, 2,34,0,33,34,4,33,34,4,34,213,32,33,37,33,33,4,34,34,34,33,1,2,1, 33,33,4,33,3,34,0,33,213,1,37,0,213,42,33,42,32,4,4,41,213,0,33,42, 34,33,39,33,213,32,34,1,34,33,34,41,3,42,42,34,34,39,36,42,41,2,0,34, 42,213,34,37,42,42,35,0,37,4,4,42,33,33,35,41,34,1,34,0,41,34,42,41, 34,42,0,3,34,33,4,41,34,34,41,34,34,34,41,3,33,2,34,37,37,213,34,35, 34,33,32,34,4,33,41,1,35,34,33,42,37 }; static const u8 META[N] = { 0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,0,0,8,0,0,0,0,1,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,10,0,0,0,0,0,0,0,0,0,32,0,1,0,0,32,0,0,0,0,0,0,0,0,1,0,0, 12,0,0,0,0,0,0,0,0,0,0,0,8,32,0,0,0,8,0,0,16,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,32,1,0,0,0,0,0,1,0, 0,8,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1, 0,0,0,0,0,0,0,0,0,32,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,32,0,0,0, 0,0,32,0,0,0,0,32,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,0, 0,32,12,0,0,16,0,0,1,32,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,32,16,1,0, 0,0,0,0,0,1,0,0,0,0,0,0,0,0,32,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,32,0,0,0,0,0,0,0,32,0,0,0,0,0,0,32,0,1,0,0,8,0,0,0,32,1, 0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,1,32,0,0,0,0,1,0,8,0,8,0,0,0,0, 0,1,1,0,0,0,0,0,1,0,1,0,0,0,0,1,0,0,0,0,8,0,0,0,0,32,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,32,8,0,0,0,0,0,14,32,32,0,0,8,0, 0,0,8,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,1,0,0,0,0,0, 0,32,0,0,0,0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,8,32,0,0,0, 0,0,32,32,0,1,0,0,0,0,8,0,0,0,0,0,0,0,0,32,8,0,0,0,1,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,32,16,0,0,8,0,0,0,0,0,0,0, 0,0,0,8,0,0,0,0,1,0,0,0,0,0,1,8,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0, 0,0,0,0,0,0,0,0,1,14,0,16,0,1,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,0,0,0,1,1,0,0,0,0,0,0, 0,0,32,0,1,0,0,0,0,0,0,0,0,0,0,0,16,0,1,1,0,0,0,0,0,0,0,0,0,0,0,1, 0,0,0,0,12,0,0,0,0,1,1,0,0,0,0,0,32,1,0,0,0,0,0,0,0,32,0,0,1,0,0,0, 0,0,0,0,0,32,0,0,0,1,0,0,32,0,0,0,0,0,0,0,8,0,32,0,0,0,0,0,8,0,0,0, 1,0,0,0,0,0,0,2,0,0,0,0,0,0,0,8,0,0,0,0,14,0,0,0,32,8,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,8,0, 0,0,0,0,0,0,0,0,0,32,16,1,0,0,1,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, 0,0,0,0,1,0,0,0,0,0,0,0,0,8,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,1,0,0,0,0,0,0,32,0,0,0,0,8,0,0,0,0,0,32,12,32,0,0,0,0,0,0,0,0, 0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,32,0,0,0,1,16,32,0, 0,0,0,0,0,32,0,16,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,0,0,32,0,0,0,0,0,0,0,0,0,1,0,0,0,12,0,0,0,1,0,32,0,32,0,0,0,32,1,1, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,8,0,1,0,0,0,0,0,32,1,32,0,0,0,0,0,0,1,0,0,0,0,1,0,8,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,32,8,0,0,0,0,0,0,0,32,0,12,32,32,0,0,0,0,0,0,0, 1,0,8,0,12,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,32,0,8,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,16,0,32,0,0,0, 0,0,0,0,0,32,0,1,16,0,0,0,0,0,0,0,0,0,32,0,0,0,32,0,0,0,0,0,0,0,0,0, 0,0,1,0,32,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,32,0, 0,0,0,0,32,0,0,0,0,16,0,0,0,0,0,0,16,0,0,0,32,0,0,0,0,0,0,0,0,0,0,1, 0,0,32,0,0,0,1,0,0,0,0,0,0,0,32,0,0,0,0,0,0,12,0,0,0,16,0,0,0,0,0,12, 0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,32,0,0,0,0,1,0, 0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,8,0,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,32,32,0,0,0,0,0,0,0,0,0,0,0,1,8,0,0,0,1,0,0,0,0,0,0, 0,0,0,8,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,32,0,1,0,0,0,0,0,0,0,0, 0,0,0,0,0,1,0,0,0,0,0,0,8,16,12,0,0,1,0,0,0,0,0,8,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0, 0,0,0,0,32,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,32, 0,0,1,32,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,32,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,32,0,0,0,0,0,0,32,0,0,0,0,0, 0,0,0,0,1,0,1,0,1,0,0,0,32,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0, 0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,8,0,12,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,32,0,0,0,0,0,0,32,0,0,12,0,0,0,0,0,0,0,0,0,16,1,0,0,0,0,0, 1,0,0,0,12,8,0,0,0,8,0,0,1,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0, 12,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,1,0,0,0,0, 0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,32,0,1,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,8,8,0,1,0,0,0,0,0,1,0,1,0,8,0,0,0,0,1,0, 0,0,0,0,0,0,0,0,0,0,0,0,16,0,8,0,0,0,0,0,16,0,1,0,0,0,0,32,0,0,32,32, 0,0,0,8,0,1,0,0,0,0,32,0,0,0,0,8,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,32,0,1,0,0,32,1,0,0,0,0,0,0,0,1,32,0,0,0,0,0,0,1,0,0,0, 8,0,6,0,0,0,0,0,12,0,0,0,0,0,12,0,0,1,0,0,0,0,0,32,0,0,0,0,0,0,0,0, 0,0,8,32,0,0,8,0,12,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0 }; // BLOB offset of every sixteenth slot's name. static const u16 BASE[(N + 15) / 16] = { 0,144,227,340,451,565,665,776,866,964,1059,1179,1284,1392,1512,1600, 1706,1796,1915,2026,2172,2251,2352,2481,2582,2672,2777,2892,2988,3120,3239,3358, 3464,3568,3661,3773,3881,3976,4087,4224,4355,4448,4556,4684,4780,4904,4986,5110, 5251,5358,5479,5600,5692,5788,5879,5976,6074,6168,6268,6348,6425,6505,6593,6676, 6778,6879,6970,7089,7166,7277,7387,7470,7602,7683,7770,7862,7948,8057,8169,8256, 8360,8464,8572,8703,8801,8910,9005,9118,9232,9328,9435,9516,9626,9718,9828,9927, 10058,10173,10283,10395,10501,10598,10685,10796,10884,11006,11134,11263,11399,11523,11623,11723, 11825,11941,12070,12164,12278,12382,12492,12569,12682,12794,12888,13015,13138,13231,13331,13416, 13498,13590,13700,13798,13899 }; // Names in slot order, padded so 32-byte loads stay inside. static const char BLOB[14004 + 32] = "NotVerticalBarthinsprarrhksupsubzigrarrRightTriangleEqualDcybigtriangledowniproduuarrOumlRightUp" "VectorBarRightDownTeeVectorbigcupLeftCeilingyucycommanapidnrtrieiiintDownArrowsmtefscrsubseteqQo" "pfsimnegjcycirEplusduorigofdrcropddRightAngleBracketHatDarrnhArrcularrThickSpaceNotTildeTildecue" "prrangleboxdRIotafiligxsqcupmeasuredangleisinsvaeligolarrKscrNotGreaterLesssucccurlyeqYacutebemp" "tyvLeftVectorOverBarGreaterEqualbottomodivrarrcUogonyscrroarrsubsupvnsubnleftarrowboxboxEsimepsi" "bumpPrgtrdotbecauseLeftTeeArrowsqsupefrac23NotLeftTriangleBarIcircIntersectionnvinfinSubsetnless" "crcaronvsupneUcyboxVHdtrincapOpenCurlyDoubleQuoteboxUldiamondsuitpreceqscnsimsupmultboxURNegativ" "eThinSpacebigsqcupintegersboxvrInvisibleTimeslangdtwixtTScyBetaplustwoLeftArrowBarbsolbandvefrpr" "napblk34OpenCurlyQuoteXopflongleftarrowrealxcupherconloplusUumllopfOrdotsccuelesCongruentnscrefD" "otlongleftrightarrownLtvsimgsupdsubacuteRcaronkcedilldshsuccsimItildelatbumpelotimessubedotDelta" "eparbNotfrac45rmousthfrnsimeqamalgiogonnablaswArrtriangledownRangGreaterGreaternotnicudarrrltcir" "TfrumacrlcedilVerbargimelphoneRightUpTeeVectorapacirNegativeVeryThinSpaceLtregsqsubseteqNtildegr" "avezcysimrarrupharpoonrightplusbltrifLessLessGreaterSlantEqualCircleMinusswnwarslarrdollarscirch" "ksearowiacuteclubsugravekhcyUpsiiecyvarthetaNotSucceedsuumlmcyDotDotUnionPlusomacrfrac12vcycupdo" "tsimdotUnderParenthesisShortUpArrowzhcyTRADEAopfLambdaNotGreaterTildeUarrocirbprimewcircNotTilde" "Equaldigammauparrowpuncspsubmultemsp14precsimcurarrAbreveThinSpacefrac16apBfrubreveiisupsetneqim" "aglinelmoustIopfrbbrknequivdoteqdotvrtridoteqtrpeziumtelrecvBarvSupersetEqualboxHUlowastrhardltd" "otgeqEogonYIcymdashcacuteigraveSquareIntersectionsupsetneqqJukcybsolsupsupNotCcedilnLtCcaronvart" "riangleleftlvnEsmtmldrjfrnbspUnderBraceMuamacrcurlyeqsuccnsubeweierpGopfTripleDotsubnelacuteless" "eqqgtrrightharpoondowndrcornncuprfrrightthreetimesprecapproxLeftVectorBarAumlgvnEzopfgtrsimljcyu" "wanglentrianglerightllhardsupeOfrnprecangrtvbawconintnvdashnscleftarrowdowndownarrowsblacktriang" "leETHscnapcirclearrowleftphivrobrklegNotSquareSupersetEqualminusblscrDelnharrimagpartCounterCloc" "kwiseContourIntegralleftthreetimesOcysuppluslesgeseqslantgtrbumpeqoastIfrlsquorscesdotentildeNac" "utelshorvdotminusgsimlangmsdthkapOacutegeqqDownTeebetabacksimlessapproxtoeaegraveboxuRQscrprodRi" "ghtFloornleqslantxcirclongmapstoprecneqqsectPscrstraightepsilonSuchThatfrac78gdotbackepsilonRigh" "tArrowLeftArroweacuteangrtTcaronsparnsimdownharpoonrightRacuteDownBrevesqcapcuveerfloorAscrGTpro" "fsurfotimesparSquareSubsetEqualJfrLeftFloorngeqslantemptyngEnltLongrightarrowfnofgesccNcaronsopf" "ZscrllarrSquareSubsetaposDownArrowUpArrowrarrnopfCHcyxfrrbrkslunapsearrpercntsfrsuccangmsdadlesd" "otororslopeNotSucceedsTildeEcaronsqufntriangleleftawintcentTabbigveevarphiapeHARDcyExistsgtquest" "spadesuitboxdLomicronnltrieIntLeftAngleBracketlmidotShortDownArrowlambdalcaronlurdsharMediumSpac" "eltrieeeWscrProportionalnotnivcEcircnLlprecsqsubnivegsdotboxHubneAgraveoacutesrarrpsiNotGreaterG" "reaterudblacvarpiDoubleLeftArrownsupseteqqcirmidNotPrecedesbigcapmapdegleftrightarrowgnapLeftUpD" "ownVectorNotLessmapstodownpermilHilbertSpaceemspHcircastbigtriangleupEopfgesdotoSfrvangrtccupsCd" "otDoubleLeftRightArrowjscrplusacirlhblkleftrightsquigarrowgesdotnotinvanshortparallelszligprsimb" "igodotLeftArrowRightArrowlaemptyveparslgnapproxmodelshoarrnrarryumledotlooparrowrightDaggerrlmHs" "troknleqpointintscyIEcyZfrcurrenboxdlCopfSucceedsSlantEqualsmeparslNotSquareSubsetyacutehairspna" "posWedgelHarDoubleUpArrowthorneumlGreaterLesszscrasympstrnsKJcyNotCupCapnedotSquareSupersetEqual" "loangleqiffColonlarrbfsrbrackrppolintcopynGgvzigzagKcyccupssmmfrkappavgnsimdbkarowpresubseteqqTi" "ldeEqualccirctopbotspadesomegangtlfloorracutecirclearrowrightcscrvertnvDashisinTscrleftrightarro" "wsnaturalsZeroWidthSpaceEmacrBernoullislneqqcwinttrianglelefteqUacutevsupnELeftTeeVectormaltnrar" "rwnotinlbarrrbrkeandslopexveelsqbbsolhsubcomplexeslbrksldOmicronNotLessSlantEqualsubeboxvLohmycy" "zfrperioddharrVertsubsubmumapdopfnpreceqlEHumpEqualNscrboxHDnsqsupeDiacriticalDoubleAcuteCedilla" "SquarescpolintnlarrtcyTilderarrwnrArrpopfShortLeftArrowimathcemptyvrnmidLongleftarrowjukcyCircle" "PlusFilledSmallSquaresupsetGscrbnequivReverseEquilibriumlatesdivideontimestscrcomplementUnderBar" "SquareUnionRightarrowleftharpoondownboxvldrdharvsubneHopflangleLeftRightArrowNotCongruentBarwedb" "epsifpartintPisupedotLeftrightarrowgEdsolsuccnapproxisinsesimUpperRightArrowcurarrmnumultriminus" "ocircrosslsaquocapandsqcuplbraceexistxotimepmaringshydivNotElementquaternionsBopfvscrinodotkcyco" "mmatKappaNotSquareSubsetEqualnLeftrightarrowNotTildeddaggericircboxDRSopfOdblacnparallelrectSqua" "reSupersetboxVtprimethere4LongleftrightarrowRightUpVectorfemaleleftharpoonuplesgRcyFopfbscroperp" "tosaRightTeeVectorscnEupsilonNotSucceedsSlantEqualnlsimLlgtlParlsimemsp13ofrlarrsimNegativeMediu" "mSpaceexpectationDoubleDotnvltrietrielrharrangangeOscrsscrsubsimUpTeeArrowolineangmsdaaNotRevers" "eElementogravexscrheartsnacuteDstroklAarrPrecedesnuequivDDfrac14tcedilacdyopfgtdotDashvsolrtrilt" "riRightDownVectorvArrNotLeftTriangleEqualZcybrvbarprofalartriplusScaronmopfCircleTimescircleddas" "hethorarrsimlLeftarrowcurlywedgeDiacriticalTildeboxVhlesseqgtrNotHumpDownHumplessgtrnotlbrkslurc" "edildownarrowintercaltriangleleftNotRightTriangleBargtccraemptyvlnELopfangmsdahxharrthickapproxD" "ownarrowlgEsigmaffjligVbarngtrzeetrfgtcirupdownarrowvartrianglerightafncongdotgscrDoubleVertical" "BarScedilNotExistsnparslFilledVerySmallSquareitildencyecircnsubseteqqrdldharSHcyufishtnsimeequal" "sbecausUbrcygtrlessAndnsparForAllApplyFunctionperpbumpEbkarownmidrrarrDoubleUpDownArrowUpdownarr" "owJsercycapsDoubleLongRightArroworornVDashharrGcedilNotLeftTrianglesungnsqsubefrac35Psipertenklo" "zangmsdaglAtailccarongelZHcysquarecaronstarDZcyChilagranyicyNegativeThickSpaceplusmnldquoboxhche" "ckmarkHacekggnLeftarrowVdashangsphSubWcirckgreenhyphenOgravensupeSucceedsboxDrHorizontalLineveeb" "armidcaretScircnapEimofocyltrParisindotnumspPartialDasympeqicyDcarontriminusraquovsubnEiscrrtriR" "everseElementdfrintlarhkXfrJcybbrktbrkldquorboxplussupseteqqduharlarrfswfrrtimesangmsdaetridotlE" "gdstrokeplusrightharpoonupLeftRightVectorIdotvDashneArrGfrUmacregsijligglEwedbarplussimBumpeqcir" "cledcircnGtvzacutemidastnvrArrGammadblacktrianglerightmacrProportionnearrleqqbsemiharrcirOtimesz" "etaSacutelarrlpseswarmuEqualgtrarrLeftArrowprcueKopfdfishtngeqIOcycuesctimesbpcyyensoftcydArrwed" "geqjcircnpreTcyboxhuYUcysubrarrthetasymaacutenvlesup2wpcuporfrac58markerGcyboxVlSigmauHarsmidltl" "arrlparltcapcupprurelVopfvarrncedilCapdscyellinodotltririsingdotseqhamiltrfishtupharpoonleftsimg" "opfncaronXitdotforkOslashfrac56shcyerDotkfrvarsupsetneqqAMPgbreveUpTeersquolarrplImaginaryInparg" "thalfsqcapssuccneqqnsuccesdotFscrUarrwscrintcalccapsRightArrowBarsqugsimeCloseCurlyQuotelongrigh" "tarrownesearOmacrointYcyxmaptargetgneqprecnsimDotIumlcoloniiotaveeCcircRightArrowGgeqslantlessti" "ntKcedilbulletcongdotrdquonhparRshroangtwoheadleftarrowclubsuitvopfrcubnwarhkorTstrokfcylnsimprn" "EsetmnbarveesubsetneqqDDElementGreaterFullEquallrhardordernfrrbrksldbdquoccedilupsihntrianglerig" "hteqrationalsdemptyvCenterDotquatintrightarrowtailandprjopfRightUpDownVectorboxvhnotinvcnsupsetp" "artapproxbernouiopfBecauseltlsimgEacuteangrtvbdnprFcyLTUopfyfrPcyClockwiseContourIntegralboxDlan" "gmsdabhomthtmcommaPrecedesTildeimageOmegaenspphmmatsqsupsetlllenVdashsuccnsimddotseqColonelowbar" "cuptriangleqSOFTcyabreveFouriertrfTausupsimlcubCloseCurlyDoubleQuotethksimUdblacdaggernwarrCupnw" "ArrnpartlateDopfetanotnivazcaronllcornerLessFullEqualtimeskopfsup1trisbmlcpscELacutegtreqqlessss" "mileYfrLessSlantEqualxiTildeFullEqualUnionkscrthereforeNotPrecedesEqualDiacriticalGraveodashxodo" "tominusstraightphiglaoltrdcaecyparsiminfintiessetmnnpolintroparsolbZacuteIacutengeqqbarwedutrisu" "bnEsharpfrac18ucybullacircjcynGtiexclotildeLeftUpTeeVectorVeesubsetneqecaronlesccnltriupsiJscrJc" "ircnotinEgeslesnvrtriegljLeftTeeuplusldrusharVDashlnezwnjsupnedscrThereforeblacksquarenlessngeho" "rbarscaronAlphaxhArrangmsdafcenterdotquotcupcapnlEbigwedgedieprimesuhblktscyblk14SucceedsEqualNo" "tSubsetEqualrBarrgacuterightleftarrowsdeltatopcirctdotSscrproptosimeqSupersetdcyYcircoopfflligAc" "ytfrnrtriNonBreakingSpacexoplusxuplusvBarLeftDownVectorgnegvertneqqDiacriticalAcuteordmbigopluss" "updotkjcyoscrconintNewLinenearrowLessTildeatildeboxhDvfrcupscoloneapidmapstolrarrdalethSuplarrhk" "csupxrarrOtildesquarfloarrcirepoundPrecedesEqualquesteqogtpluseHumpDownHumpmstposuringDifferenti" "alDolcirShortRightArrowfrac15CscrLcedilAcircsimgEtriangleGbreveorddiamseqcolonoeligGreaterEqualL" "essrarrplufrdzcylbracksemianglerthreegammardshstarfImpliesnotinvbminusdsstarfTildeTildeblacktria" "ngledownScminusduRightVectorPlusMinusnsmidNotLessGreatereuroLongLeftArrowiumlLJcynexistslangnwar" "rowDoubleRightArrownotnivbicUpArrowBarCapitalDifferentialDudarrchcynvHarrsimeacyquestEscrropfulc" "ropmDDotalephnexistrharurealpartnsubseteqUgraveRightDownVectorBaranddrightleftharpoonsboxvlDJcyu" "acutelozflmoustacheRoundImplieswedgesqcupsdashvrarrfszdotExponentialEIukcyNopfvarsubsetneqqNoBre" "akgElEpsilondivideffiligcapcapbethvltrilesdotRBarrudharhstrokangzarrrsaquoffrtrianglerightNuampP" "rimeLeftDoubleBracketIntegralKfrLcyUnderBracketbiguplusorderofboxuLlArrSucceedsTildeEumlhybullsc" "apepsivNotEqualswarrbigstarnsubsetmalteseLessGreaterImacrsmtesDownLeftRightVectorprecnapproxvdas" "hgnEplanckhnvsimepsilonReelsdotraceOEliglsquonsubcsupeVerticalSeparatorUtildeSupsetVerticalBarlr" "mhslashlharulqfroSuArrrAtailBackslashDoubleLeftTeethicksimcompfnblockboxUrTHORNiukcysacuteCoprod" "uctIscrDscrNotRightTriangleSmallCircleBscrplusoplusrsqbboxminusprapcylctyifrcuwedsigmavrxSqrtrlh" "artstroklnapalefsymboxdrDownLeftVectorBarmidcirvarrhogfrodblacNotTildeFullEqualparallelRfrsfrown" "curlyveerHarUscrcapintprodcirscirboxhUtbrkLcaronRcedilecolonnsuputrifCupCapsupseteqMscrmapstolef" "tradicCayleysgedwangleprimerataildblaccfrZetaLeftUpVectorBarDoubleLongLeftArrowNotEqualTildevark" "appaSumNcediltimesdsupnEurtriEtaNJcyboxULFfrulcornerxlArrrceilTcedilNcyucircoslashbigcircnerbrac" "eemptysetglGreaterTilderightrightarrowsandandtritimelsimePoincareplanePfrNotGreaterSlantEqualrdq" "uorNotLessTildeInvisibleCommaascrvarepsilonparslrharultimesbarnumerofflligbackcongUparrowhbarNot" "NestedGreaterGreaterRarrtlGammafrac38bcongVerticalLinelrcorneruharrboxurxopfnaturalxnislatailLow" "erLeftArrowupuparrowslapprEratiomiddotrlarrYscrlesssimVvdashUringshortparallelscedilcapdotZdotsm" "allsetminusangstgammadlrtritrianglerighteqolcrossafrlthreeeqsimleqslantlltrigtrapproxxutrinbumpe" "varsubsetneqNotSupersetescrecircopfUbrevexdtriexclcurvearrowrightharrwNotLessLessforkvnapproxntg" "lltquestLshnjcyubrcyLeftDownTeeVectorovbarLscrboxVRsupRightCeilingcupbrcapMinusPlusgesTopfoparZo" "pflarrbfopfsmilenlArrLeftTriangleEqualsqsubsetisinvLarrrscrGtuarrequiverarrbigotimesapproxeqdiam" "ondldcadjcylfrLeftUpVectorchibnotlBarrRightVectorBardownharpoonleftcedilQfrhcircuharlacDownRight" "TeeVectorboxtimesforallconglparbetweenplanckWfrbsimRightTriangleBareqcirccompelseqvparslnldrdarr" "TSHcynsupseteqimpedndashbfruogonoumldzigrarrluruharJopfUcircfltnsSubsetEqualswarrowLongRightArro" "wroplusmaleLongLeftRightArrowEfrsearrowfallingdotseqCrossdisinrcysdotsetminusnprcueOverBraceNotR" "ightTriangleEqualsuplarrlbbrknesimnaturUpArrowDownArrowEgravetradenRightarrowitrightsquigarrowLe" "ftDownVectorBarthetavRightTeeArrowutildeeogonlnapproxRrightarrowvarproptoogonhookrightarrowlharu" "EdotzwjnearhkAacuteLeftTrianglerarrbycircProductfrac34engboxvHaogonDownRightVectorntrianglelefte" "qDoubleContourIntegralIgravelooparrowleftEquilibriumemacrbacksimeqxrArrCfrgneqqmpcudarrlaopfUppe" "rLeftArrowUfrUpEquilibriumqscrffligLessEqualGreaterRightTriangleordfMopfNfrDoubleLongLeftRightAr" "rowCircleDotequestlarrnsccuesmashpbackprimecircledRsigmacurlyeqprecverbarGcirccdotproflinenipara" "cularrpCconintpreccurlyeqPopflneqboxulboxhdNotGreaterEqualiocyurcropDownTeeArrowngesinfinbsimean" "gbotsubplusdotplusrbarrnbumprArrvnsupxcapcircledastblacklozengeIJligcupcupnleAmacrsuphsoleasters" "ubsetexponentialesqsubephitshcyalphadoublebarwedgeAringgesdotolNestedGreaterGreatersumdHarlstrok" "helliplaquosdotbDownArrowBarNotSubsetshortmidmapstoupEqualTildebowtieqprimeheartsuitvarnothingcu" "rvearrowleftcirvarsupsetneqXscrPrecedesSlantEqualLleftarrowMapelltimesqopfofcirdharlblanknvgensu" "cceqprnsimUpArrowsqsupseteqnsceImtwoheadrightarrowAfrsolbarlbrkeeDotThetaiotadtrifReverseUpEquil" "ibriumfrownOverBracketncongbarwedgensubEveeeqcoprodLmidotDoubleRightTeexwedgepiruluharnvgtuopfEN" "Gdivonxfrac13mscrrhovNotSupersetEqualboxvRpitchforkDotEqualohbarntlgemptyvleftarrowtailrarrsimse" "xtplankvrealineEmptySmallSquareisinEvarsigmaLaplacetrfQUOTcopysrlessdotMcyhscrngsimDownLeftTeeVe" "ctorflatboxHBreveEcyIogonrhoumllobrkgeqslantvpropcirceqSHCHcyLanglceilRopfsimplusDScyVscrUpDownA" "rrowbopfNestedLessLesssupEintsubEUpsilonagraveeDDotpscrtopdotsquaresearhkRightTeerarrbfsDownRigh" "tVectorBarrangegcyVerticalTildedlcornnisdseArrblacktriangleleftlarrtlrparjmathiinfinRhoNotNested" "LessLessnotindotZcarontopflcyRscrfrac25RightDoubleBracketbbrkOopfgapuscrelintersNotSucceedsEqual" "simlEsucceqtaulgLfrloparlozengeNotLessEqualOverParenthesisjsercynshortmidsbquolesdotogcircleftle" "ftarrowsomidNotGreaterrpargtlvertneqqcirfnintnrarrcgsimcapbrcupsuphsubdrbkarowLeftTriangleBarges" "lqintVfrodsoldnleftrightarrowDiacriticalDothookleftarrowAtildescsimurcornOcircaumlgtreqlessYAcyL" "strokNotHumpEqualYumlhopfpluscirapEbrevecwconintCOPYhArrmultimapyacyrarrlpnleqqshchcydtdotwopfVe" "ryThinSpaceHfrboxVLlhardincareBcyvellipDiamondwreathLowerRightArrowCacutecircdcaronrarrtlduarrVc" "yHscrPhicoloneqAEligrightarrowMfrAogonboxVriquesteopfVdashlrAarrotimesasdashKHcyIcyRuleDelayedDf" "rREGnrightarrowsuccapproxgggddarrcheckcrarrpfrfraslnisGdotNotSquareSupersetrealsacEswarhkkappacs" "uberotimesosolnvapxlarrcircledSBarvDDotrahdringnvltsubegYopfsqsupEmptyVerySmallSquaresubdottopfo" "rkurcornerocircblk12ScybcyltccleftrightharpoonsMellintrfdlcropnvlArrmnplusimacrNotGreaterFullEqu" "almicrohkswarowdiamnsupErarrapnangcsubsup3thetaConintrshhardcyangmsdacStarwrnwnearrtrieAssignutd" "otlfishtpivmhotildeContourIntegralrtrifboxHdWopfNotPrecedesSlantEqualulcornNotDoubleVerticalBarD" "oubleDownArrowrsquorpropGJcyDownLeftVectorrangdtcaronrmoustacheplusdoRarriiiintboxDL"; static const u32 SECOND[] = { 106,817,819,824,8202,8402,8421,65024 }; static const u16 CP1252[32] = { 8364,129,8218,402,8222,8230,8224,8225,710,8240,352,8249,338,141,381,143, 144,8216,8217,8220,8221,8226,8211,8212,732,8482,353,8250,339,157,382,376 }; #define IOTA0 wasm_u8x16_const(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15) #define IOTA1 wasm_u8x16_const(16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31) static inline u32 mix(u32 x) { x ^= x >> 16; x *= 0x7FEB352Du; x ^= x >> 15; x *= 0x846CA68Bu; x ^= x >> 16; return x; } // Hash of a name zero-padded to 32 bytes in k0 and k1. static inline u32 name_hash(v128_t k0, v128_t k1, u32 len) { u64 h = (u64)wasm_i64x2_extract_lane(k0, 0) * 0x9E3779B97F4A7C15ull ^ (u64)wasm_i64x2_extract_lane(k0, 1) * 0xC2B2AE3D27D4EB4Full ^ (u64)wasm_i64x2_extract_lane(k1, 0) * 0x165667B19E3779F9ull ^ (u64)wasm_i64x2_extract_lane(k1, 1) * 0xD6E8FEB86659FD93ull ^ len; return mix((u32)(h >> 32) ^ (u32)h); } // Returns the slot whose name is the first len bytes of k0:k1, or -1. // m0 and m1 mask the first len bytes; k0 and k1 are zero beyond them. static inline int lookup(v128_t k0, v128_t k1, v128_t m0, v128_t m1, u32 len) { u32 h = name_hash(k0, k1, len); u32 b = (u32)(((u64)h * B) >> 32); u32 slot = (u32)(((u64)mix(h ^ DISP[b]) * N) >> 32); if (LENS[slot] != len) return -1; // Add the lengths of the names before this one in its group of 16. // Each 8-byte half sums to at most 8 * 31 < 256, so one multiply adds // its bytes. v128_t ls = wasm_v128_and(wasm_v128_load(LENS + (slot & ~15u)), wasm_u8x16_lt(IOTA0, wasm_u8x16_splat((u8)(slot & 15)))); const u64 ones = 0x0101010101010101ull; u32 off = BASE[slot >> 4] + (u32)(((u64)wasm_i64x2_extract_lane(ls, 0) * ones) >> 56) + (u32)(((u64)wasm_i64x2_extract_lane(ls, 1) * ones) >> 56); const u8 *name = (const u8 *)BLOB + off; v128_t e0 = wasm_i8x16_eq(wasm_v128_and(wasm_v128_load(name), m0), k0); v128_t e1 = wasm_i8x16_eq(wasm_v128_and(wasm_v128_load(name + 16), m1), k1); return wasm_i8x16_all_true(wasm_v128_and(e0, e1)) ? (int)slot : -1; } static inline v128_t is_alnum16(v128_t w) { v128_t l = wasm_i8x16_sub(wasm_v128_or(w, wasm_u8x16_splat(0x20)), wasm_u8x16_splat('a')); v128_t d = wasm_i8x16_sub(w, wasm_u8x16_splat('0')); return wasm_v128_or(wasm_u8x16_lt(l, wasm_u8x16_splat(26)), wasm_u8x16_lt(d, wasm_u8x16_splat(10))); } // Writes c as UTF-8. Always stores 4 bytes (the buffer has room) and // selects the encoding without branches. static inline u8 *put_utf8(u8 *o, u32 c) { u32 n = 1 + (c >= 0x80) + (c >= 0x800) + (c >= 0x10000); u32 t1 = 0x80 | (c & 63), t2 = 0x80 | (c >> 6 & 63), t3 = 0x80 | (c >> 12 & 63); u32 w2 = (0xC0 | c >> 6) | t1 << 8; u32 w3 = (0xE0 | c >> 12) | t2 << 8 | t1 << 16; u32 w4 = (0xF0 | c >> 18) | t3 << 8 | t2 << 16 | t1 << 24; u32 w = n == 1 ? c : n == 2 ? w2 : n == 3 ? w3 : w4; __builtin_memcpy(o, &w, 4); return o + n; } static inline u8 *put_named(u8 *o, u32 slot) { u32 m = META[slot]; o = put_utf8(o, LO[slot] | (u32)HI[slot] << 8 | (m & 1) << 16); u32 k = m >> 1 & 15; if (k) o = put_utf8(o, SECOND[k - 1]); return o; } static inline u32 hex_val(u8 c) { if ((u32)(c - '0') < 10) return c - '0'; u32 l = (u32)((c | 0x20) - 'a'); return l < 6 ? l + 10 : 16; } __attribute__((export_name("render"))) u64 render(u32 n) { const u8 *s = buf + IN_OFF; u8 *o = buf; u32 i = 0; buf[IN_OFF + n] = '&'; const v128_t amp = wasm_i8x16_splat('&'); for (;;) { v128_t a = wasm_v128_load(s + i); v128_t b = wasm_v128_load(s + i + 16); wasm_v128_store(o, a); wasm_v128_store(o + 16, b); u32 m = (u32)wasm_i8x16_bitmask(wasm_i8x16_eq(a, amp)) | (u32)wasm_i8x16_bitmask(wasm_i8x16_eq(b, amp)) << 16; if (!m) { i += 32; o += 32; continue; } u32 k = (u32)__builtin_ctz(m); i += k; o += k; if (i >= n) break; // s[i] is '&'. const u8 *p = s + i + 1; if (p[0] == '#') { const u8 *q; u32 v = 0; if ((u32)(p[1] - '0') < 10) { for (q = p + 1; (u32)(*q - '0') < 10; q++) { v = v * 10 + (u32)(*q - '0'); if (v > 0x10FFFF) v = 0x110000; } } else if ((p[1] | 0x20) == 'x' && hex_val(p[2]) < 16) { u32 dv; for (q = p + 2; (dv = hex_val(*q)) < 16; q++) { v = v << 4 | dv; if (v > 0x10FFFF) v = 0x110000; } } else { goto literal; } if (*q == ';') q++; if (v - 0x80 < 32) v = CP1252[v - 0x80]; else if (v == 0 || v - 0xD800 < 0x800 || v > 0x10FFFF) v = 0xFFFD; o = put_utf8(o, v); i = (u32)(q - s); continue; } else { // The name is the run of ASCII letters and digits after '&'. v128_t w0 = wasm_v128_load(p), w1 = wasm_v128_load(p + 16); u32 len = 0; while (len < 32) { u32 ch = p[len]; u32 letter = (ch | 0x20) - 'a'; u32 digit = ch - '0'; if (letter >= 26 && digit >= 10) break; len++; } if (len) { if (p[len] == ';' && len < 32) { v128_t lv = wasm_u8x16_splat((u8)len); v128_t m0 = wasm_u8x16_lt(IOTA0, lv), m1 = wasm_u8x16_lt(IOTA1, lv); int e = lookup(wasm_v128_and(w0, m0), wasm_v128_and(w1, m1), m0, m1, len); if (e >= 0) { o = put_named(o, (u32)e); i += len + 2; continue; } } // html.unescape falls back to the longest legacy name (at most 6 // bytes) that prefixes the name, used without ';'. const v128_t zero = wasm_i64x2_const(0, 0); for (u32 x = len < 6 ? len : 6; x >= 2; x--) { v128_t m0 = wasm_u8x16_lt(IOTA0, wasm_u8x16_splat((u8)x)); int e = lookup(wasm_v128_and(w0, m0), zero, m0, zero, x); if (e >= 0 && (META[e] >> 5 & 1)) { o = put_named(o, (u32)e); i += x + 1; goto next; } } } } literal: *o++ = '&'; i++; next:; } return (u64)(u32)(o - buf) | (u64)(u32)buf << 32; }