ValueRecovery should be moved out of the DFG JIT
[WebKit-https.git] / Source / JavaScriptCore / bytecode / DataFormat.h
1 /*
2  * Copyright (C) 2011 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  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #ifndef DataFormat_h
27 #define DataFormat_h
28
29 #include <wtf/Assertions.h>
30
31 namespace JSC {
32
33 // === DataFormat ===
34 //
35 // This enum tracks the current representation in which a value is being held.
36 // Values may be unboxed primitives (int32, double, or cell), or boxed as a JSValue.
37 // For boxed values, we may know the type of boxing that has taken place.
38 // (May also need bool, array, object, string types!)
39 enum DataFormat {
40     DataFormatNone = 0,
41     DataFormatInteger = 1,
42     DataFormatDouble = 2,
43     DataFormatBoolean = 3,
44     DataFormatCell = 4,
45     DataFormatStorage = 5,
46     DataFormatJS = 8,
47     DataFormatJSInteger = DataFormatJS | DataFormatInteger,
48     DataFormatJSDouble = DataFormatJS | DataFormatDouble,
49     DataFormatJSCell = DataFormatJS | DataFormatCell,
50     DataFormatJSBoolean = DataFormatJS | DataFormatBoolean
51 };
52
53 #ifndef NDEBUG
54 inline const char* dataFormatToString(DataFormat dataFormat)
55 {
56     switch (dataFormat) {
57     case DataFormatNone:
58         return "None";
59     case DataFormatInteger:
60         return "Integer";
61     case DataFormatDouble:
62         return "Double";
63     case DataFormatCell:
64         return "Cell";
65     case DataFormatBoolean:
66         return "Boolean";
67     case DataFormatStorage:
68         return "Storage";
69     case DataFormatJS:
70         return "JS";
71     case DataFormatJSInteger:
72         return "JSInteger";
73     case DataFormatJSDouble:
74         return "JSDouble";
75     case DataFormatJSCell:
76         return "JSCell";
77     case DataFormatJSBoolean:
78         return "JSBoolean";
79     default:
80         return "Unknown";
81     }
82 }
83 #endif
84
85 #if USE(JSVALUE64)
86 inline bool needDataFormatConversion(DataFormat from, DataFormat to)
87 {
88     ASSERT(from != DataFormatNone);
89     ASSERT(to != DataFormatNone);
90     switch (from) {
91     case DataFormatInteger:
92     case DataFormatDouble:
93         return to != from;
94     case DataFormatCell:
95     case DataFormatJS:
96     case DataFormatJSInteger:
97     case DataFormatJSDouble:
98     case DataFormatJSCell:
99     case DataFormatJSBoolean:
100         switch (to) {
101         case DataFormatInteger:
102         case DataFormatDouble:
103             return true;
104         case DataFormatCell:
105         case DataFormatJS:
106         case DataFormatJSInteger:
107         case DataFormatJSDouble:
108         case DataFormatJSCell:
109         case DataFormatJSBoolean:
110             return false;
111         default:
112             // This captures DataFormatBoolean, which is currently unused.
113             ASSERT_NOT_REACHED();
114         }
115     case DataFormatStorage:
116         ASSERT(to == DataFormatStorage);
117         return false;
118     default:
119         // This captures DataFormatBoolean, which is currently unused.
120         ASSERT_NOT_REACHED();
121     }
122     return true;
123 }
124
125 #elif USE(JSVALUE32_64)
126 inline bool needDataFormatConversion(DataFormat from, DataFormat to)
127 {
128     ASSERT(from != DataFormatNone);
129     ASSERT(to != DataFormatNone);
130     switch (from) {
131     case DataFormatInteger:
132     case DataFormatCell:
133     case DataFormatBoolean:
134         return ((to & DataFormatJS) || to == DataFormatDouble);
135     case DataFormatDouble:
136     case DataFormatJSDouble:
137         return (to != DataFormatDouble && to != DataFormatJSDouble);
138     case DataFormatJS:
139     case DataFormatJSInteger:
140     case DataFormatJSCell:
141     case DataFormatJSBoolean:
142         return (!(to & DataFormatJS) || to == DataFormatJSDouble);
143     case DataFormatStorage:
144         ASSERT(to == DataFormatStorage);
145         return false;
146     default:
147         ASSERT_NOT_REACHED();
148     }
149     return true;
150 }
151 #endif
152
153 inline bool isJSFormat(DataFormat format, DataFormat expectedFormat)
154 {
155     ASSERT(expectedFormat & DataFormatJS);
156     return (format | DataFormatJS) == expectedFormat;
157 }
158
159 inline bool isJSInteger(DataFormat format)
160 {
161     return isJSFormat(format, DataFormatJSInteger);
162 }
163
164 inline bool isJSDouble(DataFormat format)
165 {
166     return isJSFormat(format, DataFormatJSDouble);
167 }
168
169 inline bool isJSCell(DataFormat format)
170 {
171     return isJSFormat(format, DataFormatJSCell);
172 }
173
174 inline bool isJSBoolean(DataFormat format)
175 {
176     return isJSFormat(format, DataFormatJSBoolean);
177 }
178
179 }
180
181 #endif // DataFormat_h