typeOfDoubleSum is wrong for when NaN can be produced
[WebKit-https.git] / Source / JavaScriptCore / bytecode / SpeculatedType.cpp
1 /*
2  * Copyright (C) 2011-2018 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1.  Redistributions of source code must retain the above copyright
9  *     notice, this list of conditions and the following disclaimer.
10  * 2.  Redistributions in binary form must reproduce the above copyright
11  *     notice, this list of conditions and the following disclaimer in the
12  *     documentation and/or other materials provided with the distribution.
13  * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
14  *     its contributors may be used to endorse or promote products derived
15  *     from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 #include "config.h"
30 #include "SpeculatedType.h"
31
32 #include "DirectArguments.h"
33 #include "JSArray.h"
34 #include "JSBigInt.h"
35 #include "JSBoundFunction.h"
36 #include "JSCInlines.h"
37 #include "JSFunction.h"
38 #include "JSMap.h"
39 #include "JSSet.h"
40 #include "JSWeakMap.h"
41 #include "JSWeakSet.h"
42 #include "ProxyObject.h"
43 #include "RegExpObject.h"
44 #include "ScopedArguments.h"
45 #include "StringObject.h"
46 #include "ValueProfile.h"
47 #include <wtf/CommaPrinter.h>
48 #include <wtf/StringPrintStream.h>
49
50 namespace JSC {
51
52 struct PrettyPrinter {
53     PrettyPrinter(PrintStream& out)
54         : out(out)
55         , separator("|")
56     { }
57     
58     template<typename T>
59     void print(const T& value)
60     {
61         out.print(separator, value);
62     }
63     
64     PrintStream& out;
65     CommaPrinter separator;
66 };
67     
68 void dumpSpeculation(PrintStream& outStream, SpeculatedType value)
69 {
70     StringPrintStream strStream;
71     PrettyPrinter out(outStream);
72     PrettyPrinter strOut(strStream);
73     
74     if (value == SpecNone) {
75         out.print("None");
76         return;
77     }
78     
79     bool isTop = true;
80     
81     if ((value & SpecCell) == SpecCell)
82         strOut.print("Cell");
83     else {
84         if ((value & SpecObject) == SpecObject)
85             strOut.print("Object");
86         else {
87             if (value & SpecCellOther)
88                 strOut.print("OtherCell");
89             else
90                 isTop = false;
91     
92             if (value & SpecObjectOther)
93                 strOut.print("OtherObj");
94             else
95                 isTop = false;
96     
97             if (value & SpecFinalObject)
98                 strOut.print("Final");
99             else
100                 isTop = false;
101
102             if (value & SpecArray)
103                 strOut.print("Array");
104             else
105                 isTop = false;
106     
107             if (value & SpecInt8Array)
108                 strOut.print("Int8Array");
109             else
110                 isTop = false;
111     
112             if (value & SpecInt16Array)
113                 strOut.print("Int16Array");
114             else
115                 isTop = false;
116     
117             if (value & SpecInt32Array)
118                 strOut.print("Int32Array");
119             else
120                 isTop = false;
121     
122             if (value & SpecUint8Array)
123                 strOut.print("Uint8Array");
124             else
125                 isTop = false;
126
127             if (value & SpecUint8ClampedArray)
128                 strOut.print("Uint8ClampedArray");
129             else
130                 isTop = false;
131     
132             if (value & SpecUint16Array)
133                 strOut.print("Uint16Array");
134             else
135                 isTop = false;
136     
137             if (value & SpecUint32Array)
138                 strOut.print("Uint32Array");
139             else
140                 isTop = false;
141     
142             if (value & SpecFloat32Array)
143                 strOut.print("Float32array");
144             else
145                 isTop = false;
146     
147             if (value & SpecFloat64Array)
148                 strOut.print("Float64Array");
149             else
150                 isTop = false;
151     
152             if (value & SpecFunction)
153                 strOut.print("Function");
154             else
155                 isTop = false;
156     
157             if (value & SpecDirectArguments)
158                 strOut.print("DirectArguments");
159             else
160                 isTop = false;
161     
162             if (value & SpecScopedArguments)
163                 strOut.print("ScopedArguments");
164             else
165                 isTop = false;
166     
167             if (value & SpecStringObject)
168                 strOut.print("StringObject");
169             else
170                 isTop = false;
171     
172             if (value & SpecRegExpObject)
173                 strOut.print("RegExpObject");
174             else
175                 isTop = false;
176
177             if (value & SpecMapObject)
178                 strOut.print("MapObject");
179             else
180                 isTop = false;
181
182             if (value & SpecSetObject)
183                 strOut.print("SetObject");
184             else
185                 isTop = false;
186
187             if (value & SpecWeakMapObject)
188                 strOut.print("WeakMapObject");
189             else
190                 isTop = false;
191
192             if (value & SpecWeakSetObject)
193                 strOut.print("WeakSetObject");
194             else
195                 isTop = false;
196
197             if (value & SpecProxyObject)
198                 strOut.print("ProxyObject");
199             else
200                 isTop = false;
201
202             if (value & SpecDerivedArray)
203                 strOut.print("DerivedArray");
204             else
205                 isTop = false;
206
207             if (value & SpecDataViewObject)
208                 strOut.print("DataView");
209             else
210                 isTop = false;
211         }
212
213         if ((value & SpecString) == SpecString)
214             strOut.print("String");
215         else {
216             if (value & SpecStringIdent)
217                 strOut.print("StringIdent");
218             else
219                 isTop = false;
220             
221             if (value & SpecStringVar)
222                 strOut.print("StringVar");
223             else
224                 isTop = false;
225         }
226
227         if (value & SpecSymbol)
228             strOut.print("Symbol");
229         else
230             isTop = false;
231
232         if (value & SpecBigInt)
233             strOut.print("BigInt");
234         else
235             isTop = false;
236     }
237     
238     if (value == SpecInt32Only)
239         strOut.print("Int32");
240     else {
241         if (value & SpecBoolInt32)
242             strOut.print("BoolInt32");
243         else
244             isTop = false;
245         
246         if (value & SpecNonBoolInt32)
247             strOut.print("NonBoolInt32");
248         else
249             isTop = false;
250     }
251     
252     if (value & SpecInt52Only)
253         strOut.print("Int52");
254         
255     if ((value & SpecBytecodeDouble) == SpecBytecodeDouble)
256         strOut.print("BytecodeDouble");
257     else {
258         if (value & SpecAnyIntAsDouble)
259             strOut.print("AnyIntAsDouble");
260         else
261             isTop = false;
262         
263         if (value & SpecNonIntAsDouble)
264             strOut.print("NonIntAsDouble");
265         else
266             isTop = false;
267         
268         if (value & SpecDoublePureNaN)
269             strOut.print("DoublePureNan");
270         else
271             isTop = false;
272     }
273     
274     if (value & SpecDoubleImpureNaN)
275         out.print("DoubleImpureNan");
276     
277     if (value & SpecBoolean)
278         strOut.print("Bool");
279     else
280         isTop = false;
281     
282     if (value & SpecOther)
283         strOut.print("Other");
284     else
285         isTop = false;
286     
287     if (isTop)
288         out.print("Top");
289     else
290         out.print(strStream.toCString());
291     
292     if (value & SpecEmpty)
293         out.print("Empty");
294 }
295
296 // We don't expose this because we don't want anyone relying on the fact that this method currently
297 // just returns string constants.
298 static const char* speculationToAbbreviatedString(SpeculatedType prediction)
299 {
300     if (isFinalObjectSpeculation(prediction))
301         return "<Final>";
302     if (isArraySpeculation(prediction))
303         return "<Array>";
304     if (isStringIdentSpeculation(prediction))
305         return "<StringIdent>";
306     if (isStringSpeculation(prediction))
307         return "<String>";
308     if (isFunctionSpeculation(prediction))
309         return "<Function>";
310     if (isInt8ArraySpeculation(prediction))
311         return "<Int8array>";
312     if (isInt16ArraySpeculation(prediction))
313         return "<Int16array>";
314     if (isInt32ArraySpeculation(prediction))
315         return "<Int32array>";
316     if (isUint8ArraySpeculation(prediction))
317         return "<Uint8array>";
318     if (isUint16ArraySpeculation(prediction))
319         return "<Uint16array>";
320     if (isUint32ArraySpeculation(prediction))
321         return "<Uint32array>";
322     if (isFloat32ArraySpeculation(prediction))
323         return "<Float32array>";
324     if (isFloat64ArraySpeculation(prediction))
325         return "<Float64array>";
326     if (isDirectArgumentsSpeculation(prediction))
327         return "<DirectArguments>";
328     if (isScopedArgumentsSpeculation(prediction))
329         return "<ScopedArguments>";
330     if (isStringObjectSpeculation(prediction))
331         return "<StringObject>";
332     if (isRegExpObjectSpeculation(prediction))
333         return "<RegExpObject>";
334     if (isStringOrStringObjectSpeculation(prediction))
335         return "<StringOrStringObject>";
336     if (isObjectSpeculation(prediction))
337         return "<Object>";
338     if (isCellSpeculation(prediction))
339         return "<Cell>";
340     if (isBoolInt32Speculation(prediction))
341         return "<BoolInt32>";
342     if (isInt32Speculation(prediction))
343         return "<Int32>";
344     if (isAnyIntAsDoubleSpeculation(prediction))
345         return "<AnyIntAsDouble>";
346     if (isInt52Speculation(prediction))
347         return "<Int52>";
348     if (isAnyIntSpeculation(prediction))
349         return "<AnyInt>";
350     if (isDoubleSpeculation(prediction))
351         return "<Double>";
352     if (isFullNumberSpeculation(prediction))
353         return "<Number>";
354     if (isBooleanSpeculation(prediction))
355         return "<Boolean>";
356     if (isOtherSpeculation(prediction))
357         return "<Other>";
358     if (isMiscSpeculation(prediction))
359         return "<Misc>";
360     return "";
361 }
362
363 void dumpSpeculationAbbreviated(PrintStream& out, SpeculatedType value)
364 {
365     out.print(speculationToAbbreviatedString(value));
366 }
367
368 SpeculatedType speculationFromTypedArrayType(TypedArrayType type)
369 {
370     switch (type) {
371     case TypeInt8:
372         return SpecInt8Array;
373     case TypeInt16:
374         return SpecInt16Array;
375     case TypeInt32:
376         return SpecInt32Array;
377     case TypeUint8:
378         return SpecUint8Array;
379     case TypeUint8Clamped:
380         return SpecUint8ClampedArray;
381     case TypeUint16:
382         return SpecUint16Array;
383     case TypeUint32:
384         return SpecUint32Array;
385     case TypeFloat32:
386         return SpecFloat32Array;
387     case TypeFloat64:
388         return SpecFloat64Array;
389     case NotTypedArray:
390     case TypeDataView:
391         break;
392     }
393     RELEASE_ASSERT_NOT_REACHED();
394     return SpecNone;
395 }
396
397 SpeculatedType speculationFromClassInfo(const ClassInfo* classInfo)
398 {
399     if (classInfo == JSString::info())
400         return SpecString;
401
402     if (classInfo == Symbol::info())
403         return SpecSymbol;
404     
405     if (classInfo == JSBigInt::info())
406         return SpecBigInt;
407
408     if (classInfo == JSFinalObject::info())
409         return SpecFinalObject;
410     
411     if (classInfo == JSArray::info())
412         return SpecArray;
413     
414     if (classInfo == DirectArguments::info())
415         return SpecDirectArguments;
416     
417     if (classInfo == ScopedArguments::info())
418         return SpecScopedArguments;
419     
420     if (classInfo == StringObject::info())
421         return SpecStringObject;
422
423     if (classInfo == RegExpObject::info())
424         return SpecRegExpObject;
425
426     if (classInfo == JSMap::info())
427         return SpecMapObject;
428
429     if (classInfo == JSSet::info())
430         return SpecSetObject;
431
432     if (classInfo == JSWeakMap::info())
433         return SpecWeakMapObject;
434
435     if (classInfo == JSWeakSet::info())
436         return SpecWeakSetObject;
437
438     if (classInfo == ProxyObject::info())
439         return SpecProxyObject;
440
441     if (classInfo == JSDataView::info())
442         return SpecDataViewObject;
443     
444     if (classInfo->isSubClassOf(JSFunction::info())) {
445         if (classInfo == JSBoundFunction::info())
446             return SpecFunctionWithNonDefaultHasInstance;
447         return SpecFunctionWithDefaultHasInstance;
448     }
449     
450     if (isTypedView(classInfo->typedArrayStorageType))
451         return speculationFromTypedArrayType(classInfo->typedArrayStorageType);
452
453     if (classInfo->isSubClassOf(JSArray::info()))
454         return SpecDerivedArray;
455     
456     if (classInfo->isSubClassOf(JSObject::info()))
457         return SpecObjectOther;
458     
459     return SpecCellOther;
460 }
461
462 SpeculatedType speculationFromStructure(Structure* structure)
463 {
464     if (structure->typeInfo().type() == StringType)
465         return SpecString;
466     if (structure->typeInfo().type() == SymbolType)
467         return SpecSymbol;
468     if (structure->typeInfo().type() == BigIntType)
469         return SpecBigInt;
470     if (structure->typeInfo().type() == DerivedArrayType)
471         return SpecDerivedArray;
472     return speculationFromClassInfo(structure->classInfo());
473 }
474
475 SpeculatedType speculationFromCell(JSCell* cell)
476 {
477     if (cell->isString()) {
478         JSString* string = jsCast<JSString*>(cell);
479         if (const StringImpl* impl = string->tryGetValueImpl()) {
480             if (impl->isAtomic())
481                 return SpecStringIdent;
482         }
483         return SpecString;
484     }
485     return speculationFromStructure(cell->structure());
486 }
487
488 SpeculatedType speculationFromValue(JSValue value)
489 {
490     if (value.isEmpty())
491         return SpecEmpty;
492     if (value.isInt32()) {
493         if (value.asInt32() & ~1)
494             return SpecNonBoolInt32;
495         return SpecBoolInt32;
496     }
497     if (value.isDouble()) {
498         double number = value.asNumber();
499         if (number != number)
500             return SpecDoublePureNaN;
501         if (value.isAnyInt())
502             return SpecAnyIntAsDouble;
503         return SpecNonIntAsDouble;
504     }
505     if (value.isCell())
506         return speculationFromCell(value.asCell());
507     if (value.isBoolean())
508         return SpecBoolean;
509     ASSERT(value.isUndefinedOrNull());
510     return SpecOther;
511 }
512
513 TypedArrayType typedArrayTypeFromSpeculation(SpeculatedType type)
514 {
515     if (isInt8ArraySpeculation(type))
516         return TypeInt8;
517         
518     if (isInt16ArraySpeculation(type))
519         return TypeInt16;
520         
521     if (isInt32ArraySpeculation(type))
522         return TypeInt32;
523         
524     if (isUint8ArraySpeculation(type))
525         return TypeUint8;
526         
527     if (isUint8ClampedArraySpeculation(type))
528         return TypeUint8Clamped;
529         
530     if (isUint16ArraySpeculation(type))
531         return TypeUint16;
532         
533     if (isUint32ArraySpeculation(type))
534         return TypeUint32;
535         
536     if (isFloat32ArraySpeculation(type))
537         return TypeFloat32;
538         
539     if (isFloat64ArraySpeculation(type))
540         return TypeFloat64;
541     
542     return NotTypedArray;
543 }
544
545 SpeculatedType speculationFromJSType(JSType type)
546 {
547     switch (type) {
548     case StringType:
549         return SpecString;
550     case SymbolType:
551         return SpecSymbol;
552     case BigIntType:
553         return SpecBigInt;
554     case ArrayType:
555         return SpecArray;
556     case DerivedArrayType:
557         return SpecDerivedArray;
558     case RegExpObjectType:
559         return SpecRegExpObject;
560     case ProxyObjectType:
561         return SpecProxyObject;
562     case JSMapType:
563         return SpecMapObject;
564     case JSSetType:
565         return SpecSetObject;
566     case JSWeakMapType:
567         return SpecWeakMapObject;
568     case JSWeakSetType:
569         return SpecWeakSetObject;
570     case DataViewType:
571         return SpecDataViewObject;
572     default:
573         ASSERT_NOT_REACHED();
574     }
575     return SpecNone;
576 }
577
578 SpeculatedType leastUpperBoundOfStrictlyEquivalentSpeculations(SpeculatedType type)
579 {
580     // SpecNonIntAsDouble includes negative zero (-0.0), which can be equal to 0 and 0.0 in the context of == and ===.
581     if (type & (SpecAnyInt | SpecAnyIntAsDouble | SpecNonIntAsDouble))
582         type |= (SpecAnyInt | SpecAnyIntAsDouble | SpecNonIntAsDouble);
583
584     if (type & SpecString)
585         type |= SpecString;
586     return type;
587 }
588
589 bool valuesCouldBeEqual(SpeculatedType a, SpeculatedType b)
590 {
591     a = leastUpperBoundOfStrictlyEquivalentSpeculations(a);
592     b = leastUpperBoundOfStrictlyEquivalentSpeculations(b);
593     
594     // Anything could be equal to a string.
595     if (a & SpecString)
596         return true;
597     if (b & SpecString)
598         return true;
599     
600     // If both sides are definitely only objects, then equality is fairly sane.
601     if (isObjectSpeculation(a) && isObjectSpeculation(b))
602         return !!(a & b);
603     
604     // If either side could be an object or not, then we could call toString or
605     // valueOf, which could return anything.
606     if (a & SpecObject)
607         return true;
608     if (b & SpecObject)
609         return true;
610     
611     // Neither side is an object or string, so the world is relatively sane.
612     return !!(a & b);
613 }
614
615 static SpeculatedType typeOfDoubleSumOrDifferenceOrProduct(SpeculatedType a, SpeculatedType b)
616 {
617     SpeculatedType result = a | b;
618
619     if (result & SpecNonIntAsDouble) {
620         // NaN can be produced by:
621         // Infinity - Infinity
622         // Infinity + (-Infinity)
623         // Infinity * 0
624         result |= SpecDoublePureNaN;
625     }
626
627     // Impure NaN could become pure NaN during addition because addition may clear bits.
628     if (result & SpecDoubleImpureNaN)
629         result |= SpecDoublePureNaN;
630     // Values could overflow, or fractions could become integers.
631     if (result & SpecDoubleReal)
632         result |= SpecDoubleReal;
633     return result;
634 }
635
636 SpeculatedType typeOfDoubleSum(SpeculatedType a, SpeculatedType b)
637 {
638     return typeOfDoubleSumOrDifferenceOrProduct(a, b);
639 }
640
641 SpeculatedType typeOfDoubleDifference(SpeculatedType a, SpeculatedType b)
642 {
643     return typeOfDoubleSumOrDifferenceOrProduct(a, b);
644 }
645
646 SpeculatedType typeOfDoubleProduct(SpeculatedType a, SpeculatedType b)
647 {
648     return typeOfDoubleSumOrDifferenceOrProduct(a, b);
649 }
650
651 static SpeculatedType polluteDouble(SpeculatedType value)
652 {
653     // Impure NaN could become pure NaN because the operation could clear some bits.
654     if (value & SpecDoubleImpureNaN)
655         value |= SpecDoubleNaN;
656     // Values could overflow, fractions could become integers, or an error could produce
657     // PureNaN.
658     if (value & SpecDoubleReal)
659         value |= SpecDoubleReal | SpecDoublePureNaN;
660     return value;
661 }
662
663 SpeculatedType typeOfDoubleQuotient(SpeculatedType a, SpeculatedType b)
664 {
665     return polluteDouble(a | b);
666 }
667
668 SpeculatedType typeOfDoubleMinMax(SpeculatedType a, SpeculatedType b)
669 {
670     SpeculatedType result = a | b;
671     // Impure NaN could become pure NaN during addition because addition may clear bits.
672     if (result & SpecDoubleImpureNaN)
673         result |= SpecDoublePureNaN;
674     return result;
675 }
676
677 SpeculatedType typeOfDoubleNegation(SpeculatedType value)
678 {
679     // Changing bits can make pure NaN impure and vice versa:
680     // 0xefff000000000000 (pure) - 0xffff000000000000 (impure)
681     if (value & SpecDoubleNaN)
682         value |= SpecDoubleNaN;
683     // We could get negative zero, which mixes SpecAnyIntAsDouble and SpecNotIntAsDouble.
684     // We could also overflow a large negative int into something that is no longer
685     // representable as an int.
686     if (value & SpecDoubleReal)
687         value |= SpecDoubleReal;
688     return value;
689 }
690
691 SpeculatedType typeOfDoubleAbs(SpeculatedType value)
692 {
693     return typeOfDoubleNegation(value);
694 }
695
696 SpeculatedType typeOfDoubleRounding(SpeculatedType value)
697 {
698     // Double Pure NaN can becomes impure when converted back from Float.
699     // and vice versa.
700     if (value & SpecDoubleNaN)
701         value |= SpecDoubleNaN;
702     // We might lose bits, which leads to a value becoming integer-representable.
703     if (value & SpecNonIntAsDouble)
704         value |= SpecAnyIntAsDouble;
705     return value;
706 }
707
708 SpeculatedType typeOfDoublePow(SpeculatedType xValue, SpeculatedType yValue)
709 {
710     // Math.pow() always return NaN if the exponent is NaN, unlike std::pow().
711     // We always set a pure NaN in that case.
712     if (yValue & SpecDoubleNaN)
713         xValue |= SpecDoublePureNaN;
714     // Handle the wierd case of NaN ^ 0, which returns 1. See https://tc39.github.io/ecma262/#sec-applying-the-exp-operator
715     if (xValue & SpecDoubleNaN)
716         xValue |= SpecFullDouble;
717     return polluteDouble(xValue);
718 }
719
720 SpeculatedType typeOfDoubleBinaryOp(SpeculatedType a, SpeculatedType b)
721 {
722     return polluteDouble(a | b);
723 }
724
725 SpeculatedType typeOfDoubleUnaryOp(SpeculatedType value)
726 {
727     return polluteDouble(value);
728 }
729
730 SpeculatedType speculationFromString(const char* speculation)
731 {
732     if (!strncmp(speculation, "SpecNone", strlen("SpecNone")))
733         return SpecNone;
734     if (!strncmp(speculation, "SpecFinalObject", strlen("SpecFinalObject")))
735         return SpecFinalObject;
736     if (!strncmp(speculation, "SpecArray", strlen("SpecArray")))
737         return SpecArray;
738     if (!strncmp(speculation, "SpecFunction", strlen("SpecFunction")))
739         return SpecFunction;
740     if (!strncmp(speculation, "SpecInt8Array", strlen("SpecInt8Array")))
741         return SpecInt8Array;
742     if (!strncmp(speculation, "SpecInt16Array", strlen("SpecInt16Array")))
743         return SpecInt16Array;
744     if (!strncmp(speculation, "SpecInt32Array", strlen("SpecInt32Array")))
745         return SpecInt32Array;
746     if (!strncmp(speculation, "SpecUint8Array", strlen("SpecUint8Array")))
747         return SpecUint8Array;
748     if (!strncmp(speculation, "SpecUint8ClampedArray", strlen("SpecUint8ClampedArray")))
749         return SpecUint8ClampedArray;
750     if (!strncmp(speculation, "SpecUint16Array", strlen("SpecUint16Array")))
751         return SpecUint16Array;
752     if (!strncmp(speculation, "SpecUint32Array", strlen("SpecUint32Array")))
753         return SpecUint32Array;
754     if (!strncmp(speculation, "SpecFloat32Array", strlen("SpecFloat32Array")))
755         return SpecFloat32Array;
756     if (!strncmp(speculation, "SpecFloat64Array", strlen("SpecFloat64Array")))
757         return SpecFloat64Array;
758     if (!strncmp(speculation, "SpecTypedArrayView", strlen("SpecTypedArrayView")))
759         return SpecTypedArrayView;
760     if (!strncmp(speculation, "SpecDirectArguments", strlen("SpecDirectArguments")))
761         return SpecDirectArguments;
762     if (!strncmp(speculation, "SpecScopedArguments", strlen("SpecScopedArguments")))
763         return SpecScopedArguments;
764     if (!strncmp(speculation, "SpecStringObject", strlen("SpecStringObject")))
765         return SpecStringObject;
766     if (!strncmp(speculation, "SpecRegExpObject", strlen("SpecRegExpObject")))
767         return SpecRegExpObject;
768     if (!strncmp(speculation, "SpecMapObject", strlen("SpecMapObject")))
769         return SpecMapObject;
770     if (!strncmp(speculation, "SpecSetObject", strlen("SpecSetObject")))
771         return SpecSetObject;
772     if (!strncmp(speculation, "SpecWeakMapObject", strlen("SpecWeakMapObject")))
773         return SpecWeakMapObject;
774     if (!strncmp(speculation, "SpecWeakSetObject", strlen("SpecWeakSetObject")))
775         return SpecWeakSetObject;
776     if (!strncmp(speculation, "SpecProxyObject", strlen("SpecProxyObject")))
777         return SpecProxyObject;
778     if (!strncmp(speculation, "SpecDerivedArray", strlen("SpecDerivedArray")))
779         return SpecDerivedArray;
780     if (!strncmp(speculation, "SpecDataViewObject", strlen("SpecDataViewObject")))
781         return SpecDataViewObject;
782     if (!strncmp(speculation, "SpecObjectOther", strlen("SpecObjectOther")))
783         return SpecObjectOther;
784     if (!strncmp(speculation, "SpecObject", strlen("SpecObject")))
785         return SpecObject;
786     if (!strncmp(speculation, "SpecStringIdent", strlen("SpecStringIdent")))
787         return SpecStringIdent;
788     if (!strncmp(speculation, "SpecStringVar", strlen("SpecStringVar")))
789         return SpecStringVar;
790     if (!strncmp(speculation, "SpecString", strlen("SpecString")))
791         return SpecString;
792     if (!strncmp(speculation, "SpecSymbol", strlen("SpecSymbol")))
793         return SpecSymbol;
794     if (!strncmp(speculation, "SpecBigInt", strlen("SpecBigInt")))
795         return SpecBigInt;
796     if (!strncmp(speculation, "SpecCellOther", strlen("SpecCellOther")))
797         return SpecCellOther;
798     if (!strncmp(speculation, "SpecCell", strlen("SpecCell")))
799         return SpecCell;
800     if (!strncmp(speculation, "SpecBoolInt32", strlen("SpecBoolInt32")))
801         return SpecBoolInt32;
802     if (!strncmp(speculation, "SpecNonBoolInt32", strlen("SpecNonBoolInt32")))
803         return SpecNonBoolInt32;
804     if (!strncmp(speculation, "SpecInt32Only", strlen("SpecInt32Only")))
805         return SpecInt32Only;
806     if (!strncmp(speculation, "SpecInt52Only", strlen("SpecInt52Only")))
807         return SpecInt52Only;
808     if (!strncmp(speculation, "SpecAnyInt", strlen("SpecAnyInt")))
809         return SpecAnyInt;
810     if (!strncmp(speculation, "SpecAnyIntAsDouble", strlen("SpecAnyIntAsDouble")))
811         return SpecAnyIntAsDouble;
812     if (!strncmp(speculation, "SpecNonIntAsDouble", strlen("SpecNonIntAsDouble")))
813         return SpecNonIntAsDouble;
814     if (!strncmp(speculation, "SpecDoubleReal", strlen("SpecDoubleReal")))
815         return SpecDoubleReal;
816     if (!strncmp(speculation, "SpecDoublePureNaN", strlen("SpecDoublePureNaN")))
817         return SpecDoublePureNaN;
818     if (!strncmp(speculation, "SpecDoubleImpureNaN", strlen("SpecDoubleImpureNaN")))
819         return SpecDoubleImpureNaN;
820     if (!strncmp(speculation, "SpecDoubleNaN", strlen("SpecDoubleNaN")))
821         return SpecDoubleNaN;
822     if (!strncmp(speculation, "SpecBytecodeDouble", strlen("SpecBytecodeDouble")))
823         return SpecBytecodeDouble;
824     if (!strncmp(speculation, "SpecFullDouble", strlen("SpecFullDouble")))
825         return SpecFullDouble;
826     if (!strncmp(speculation, "SpecBytecodeRealNumber", strlen("SpecBytecodeRealNumber")))
827         return SpecBytecodeRealNumber;
828     if (!strncmp(speculation, "SpecFullRealNumber", strlen("SpecFullRealNumber")))
829         return SpecFullRealNumber;
830     if (!strncmp(speculation, "SpecBytecodeNumber", strlen("SpecBytecodeNumber")))
831         return SpecBytecodeNumber;
832     if (!strncmp(speculation, "SpecFullNumber", strlen("SpecFullNumber")))
833         return SpecFullNumber;
834     if (!strncmp(speculation, "SpecBoolean", strlen("SpecBoolean")))
835         return SpecBoolean;
836     if (!strncmp(speculation, "SpecOther", strlen("SpecOther")))
837         return SpecOther;
838     if (!strncmp(speculation, "SpecMisc", strlen("SpecMisc")))
839         return SpecMisc;
840     if (!strncmp(speculation, "SpecHeapTop", strlen("SpecHeapTop")))
841         return SpecHeapTop;
842     if (!strncmp(speculation, "SpecPrimitive", strlen("SpecPrimitive")))
843         return SpecPrimitive;
844     if (!strncmp(speculation, "SpecEmpty", strlen("SpecEmpty")))
845         return SpecEmpty;
846     if (!strncmp(speculation, "SpecBytecodeTop", strlen("SpecBytecodeTop")))
847         return SpecBytecodeTop;
848     if (!strncmp(speculation, "SpecFullTop", strlen("SpecFullTop")))
849         return SpecFullTop;
850     if (!strncmp(speculation, "SpecCellCheck", strlen("SpecCellCheck")))
851         return SpecCellCheck;
852     RELEASE_ASSERT_NOT_REACHED();
853 }
854
855 } // namespace JSC
856