JSCJSValue.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505
  1. /*
  2. * Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
  3. * Copyright (C) 2001 Peter Kelly (pmk@post.com)
  4. * Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009, 2012 Apple Inc. All rights reserved.
  5. *
  6. * This library is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Library General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2 of the License, or (at your option) any later version.
  10. *
  11. * This library is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Library General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Library General Public License
  17. * along with this library; see the file COPYING.LIB. If not, write to
  18. * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  19. * Boston, MA 02110-1301, USA.
  20. *
  21. */
  22. #ifndef JSCJSValue_h
  23. #define JSCJSValue_h
  24. #include <math.h>
  25. #include <stddef.h> // for size_t
  26. #include <stdint.h>
  27. #include <wtf/Assertions.h>
  28. #include <wtf/Forward.h>
  29. #include <wtf/HashMap.h>
  30. #include <wtf/HashTraits.h>
  31. #include <wtf/MathExtras.h>
  32. #include <wtf/StdLibExtras.h>
  33. #include <wtf/TriState.h>
  34. namespace JSC {
  35. // This is used a lot throughout JavaScriptCore for everything from value boxing to marking
  36. // values as being missing, so it is useful to have it abbreviated.
  37. #define QNaN (std::numeric_limits<double>::quiet_NaN())
  38. class ExecState;
  39. class JSCell;
  40. class VM;
  41. class JSGlobalObject;
  42. class JSObject;
  43. class JSString;
  44. class PropertyName;
  45. class PropertySlot;
  46. class PutPropertySlot;
  47. #if ENABLE(DFG_JIT)
  48. namespace DFG {
  49. class AssemblyHelpers;
  50. class JITCompiler;
  51. class JITCodeGenerator;
  52. class JSValueSource;
  53. class OSRExitCompiler;
  54. class SpeculativeJIT;
  55. }
  56. #endif
  57. #if ENABLE(LLINT_C_LOOP)
  58. namespace LLInt {
  59. class CLoop;
  60. }
  61. #endif
  62. struct ClassInfo;
  63. struct Instruction;
  64. struct MethodTable;
  65. template <class T> class WriteBarrierBase;
  66. enum PreferredPrimitiveType { NoPreference, PreferNumber, PreferString };
  67. typedef int64_t EncodedJSValue;
  68. union EncodedValueDescriptor {
  69. int64_t asInt64;
  70. #if USE(JSVALUE32_64)
  71. double asDouble;
  72. #elif USE(JSVALUE64)
  73. JSCell* ptr;
  74. #endif
  75. #if CPU(BIG_ENDIAN)
  76. struct {
  77. int32_t tag;
  78. int32_t payload;
  79. } asBits;
  80. #else
  81. struct {
  82. int32_t payload;
  83. int32_t tag;
  84. } asBits;
  85. #endif
  86. };
  87. // This implements ToInt32, defined in ECMA-262 9.5.
  88. JS_EXPORT_PRIVATE int32_t toInt32(double);
  89. #if ENABLE(DETACHED_JIT) && BUILDING_DETACHED_JIT
  90. JS_EXPORT_PRIVATE int32_t toInt32_vmstub(double);
  91. #else
  92. #define toInt32_vmstub toInt32
  93. #endif
  94. // This implements ToUInt32, defined in ECMA-262 9.6.
  95. inline uint32_t toUInt32(double number)
  96. {
  97. // As commented in the spec, the operation of ToInt32 and ToUint32 only differ
  98. // in how the result is interpreted; see NOTEs in sections 9.5 and 9.6.
  99. return toInt32(number);
  100. }
  101. class JSValue {
  102. friend struct EncodedJSValueHashTraits;
  103. friend class JIT;
  104. friend class JITStubs;
  105. friend class JITStubCall;
  106. friend class JSInterfaceJIT;
  107. friend class SpecializedThunkJIT;
  108. #if ENABLE(DFG_JIT)
  109. friend class DFG::AssemblyHelpers;
  110. friend class DFG::JITCompiler;
  111. friend class DFG::JITCodeGenerator;
  112. friend class DFG::JSValueSource;
  113. friend class DFG::OSRExitCompiler;
  114. friend class DFG::SpeculativeJIT;
  115. #endif
  116. #if ENABLE(LLINT_C_LOOP)
  117. friend class LLInt::CLoop;
  118. #endif
  119. public:
  120. #if USE(JSVALUE32_64)
  121. enum { Int32Tag = 0xffffffff };
  122. enum { BooleanTag = 0xfffffffe };
  123. enum { NullTag = 0xfffffffd };
  124. enum { UndefinedTag = 0xfffffffc };
  125. enum { CellTag = 0xfffffffb };
  126. enum { EmptyValueTag = 0xfffffffa };
  127. enum { DeletedValueTag = 0xfffffff9 };
  128. enum { LowestTag = DeletedValueTag };
  129. #endif
  130. static EncodedJSValue encode(JSValue);
  131. static JSValue decode(EncodedJSValue);
  132. enum JSNullTag { JSNull };
  133. enum JSUndefinedTag { JSUndefined };
  134. enum JSTrueTag { JSTrue };
  135. enum JSFalseTag { JSFalse };
  136. enum EncodeAsDoubleTag { EncodeAsDouble };
  137. JSValue();
  138. JSValue(JSNullTag);
  139. JSValue(JSUndefinedTag);
  140. JSValue(JSTrueTag);
  141. JSValue(JSFalseTag);
  142. JSValue(JSCell* ptr);
  143. JSValue(const JSCell* ptr);
  144. // Numbers
  145. JSValue(EncodeAsDoubleTag, double);
  146. explicit JSValue(double);
  147. explicit JSValue(char);
  148. explicit JSValue(unsigned char);
  149. explicit JSValue(short);
  150. explicit JSValue(unsigned short);
  151. explicit JSValue(int);
  152. explicit JSValue(unsigned);
  153. explicit JSValue(long);
  154. explicit JSValue(unsigned long);
  155. explicit JSValue(long long);
  156. explicit JSValue(unsigned long long);
  157. operator bool() const;
  158. bool operator==(const JSValue& other) const;
  159. bool operator!=(const JSValue& other) const;
  160. bool isInt32() const;
  161. bool isUInt32() const;
  162. bool isDouble() const;
  163. bool isTrue() const;
  164. bool isFalse() const;
  165. int32_t asInt32() const;
  166. uint32_t asUInt32() const;
  167. double asDouble() const;
  168. bool asBoolean() const;
  169. double asNumber() const;
  170. // Querying the type.
  171. bool isEmpty() const;
  172. bool isFunction() const;
  173. bool isUndefined() const;
  174. bool isNull() const;
  175. bool isUndefinedOrNull() const;
  176. bool isBoolean() const;
  177. bool isNumber() const;
  178. bool isString() const;
  179. bool isPrimitive() const;
  180. bool isGetterSetter() const;
  181. bool isObject() const;
  182. bool inherits(const ClassInfo*) const;
  183. // Extracting the value.
  184. bool getString(ExecState*, WTF::String&) const;
  185. WTF::String getString(ExecState*) const; // null string if not a string
  186. JSObject* getObject() const; // 0 if not an object
  187. // Extracting integer values.
  188. bool getUInt32(uint32_t&) const;
  189. // Basic conversions.
  190. JSValue toPrimitive(ExecState*, PreferredPrimitiveType = NoPreference) const;
  191. bool getPrimitiveNumber(ExecState*, double& number, JSValue&);
  192. bool toBoolean(ExecState*) const;
  193. TriState pureToBoolean() const;
  194. // toNumber conversion is expected to be side effect free if an exception has
  195. // been set in the ExecState already.
  196. double toNumber(ExecState*) const;
  197. JSString* toString(ExecState*) const;
  198. WTF::String toWTFString(ExecState*) const;
  199. WTF::String toWTFStringInline(ExecState*) const;
  200. JSObject* toObject(ExecState*) const;
  201. JSObject* toObject(ExecState*, JSGlobalObject*) const;
  202. // Integer conversions.
  203. JS_EXPORT_PRIVATE double toInteger(ExecState*) const;
  204. double toIntegerPreserveNaN(ExecState*) const;
  205. int32_t toInt32(ExecState*) const;
  206. uint32_t toUInt32(ExecState*) const;
  207. // Floating point conversions (this is a convenience method for webcore;
  208. // signle precision float is not a representation used in JS or JSC).
  209. float toFloat(ExecState* exec) const { return static_cast<float>(toNumber(exec)); }
  210. // Object operations, with the toObject operation included.
  211. JSValue get(ExecState*, PropertyName) const;
  212. JSValue get(ExecState*, PropertyName, PropertySlot&) const;
  213. JSValue get(ExecState*, unsigned propertyName) const;
  214. JSValue get(ExecState*, unsigned propertyName, PropertySlot&) const;
  215. void put(ExecState*, PropertyName, JSValue, PutPropertySlot&);
  216. void putToPrimitive(ExecState*, PropertyName, JSValue, PutPropertySlot&);
  217. void putToPrimitiveByIndex(ExecState*, unsigned propertyName, JSValue, bool shouldThrow);
  218. void putByIndex(ExecState*, unsigned propertyName, JSValue, bool shouldThrow);
  219. JSObject* toThisObject(ExecState*) const;
  220. static bool equal(ExecState*, JSValue v1, JSValue v2);
  221. static bool equalSlowCase(ExecState*, JSValue v1, JSValue v2);
  222. static bool equalSlowCaseInline(ExecState*, JSValue v1, JSValue v2);
  223. static bool strictEqual(ExecState*, JSValue v1, JSValue v2);
  224. static bool strictEqualSlowCase(ExecState*, JSValue v1, JSValue v2);
  225. static bool strictEqualSlowCaseInline(ExecState*, JSValue v1, JSValue v2);
  226. bool isCell() const;
  227. JSCell* asCell() const;
  228. JS_EXPORT_PRIVATE bool isValidCallee();
  229. JSValue structureOrUndefined() const;
  230. JS_EXPORT_PRIVATE void dump(PrintStream&) const;
  231. JS_EXPORT_PRIVATE JSObject* synthesizePrototype(ExecState*) const;
  232. private:
  233. template <class T> JSValue(WriteBarrierBase<T>);
  234. enum HashTableDeletedValueTag { HashTableDeletedValue };
  235. JSValue(HashTableDeletedValueTag);
  236. inline const JSValue asValue() const { return *this; }
  237. JS_EXPORT_PRIVATE double toNumberSlowCase(ExecState*) const;
  238. JS_EXPORT_PRIVATE JSString* toStringSlowCase(ExecState*) const;
  239. JS_EXPORT_PRIVATE WTF::String toWTFStringSlowCase(ExecState*) const;
  240. JS_EXPORT_PRIVATE JSObject* toObjectSlowCase(ExecState*, JSGlobalObject*) const;
  241. JS_EXPORT_PRIVATE JSObject* toThisObjectSlowCase(ExecState*) const;
  242. #if USE(JSVALUE32_64)
  243. /*
  244. * On 32-bit platforms USE(JSVALUE32_64) should be defined, and we use a NaN-encoded
  245. * form for immediates.
  246. *
  247. * The encoding makes use of unused NaN space in the IEEE754 representation. Any value
  248. * with the top 13 bits set represents a QNaN (with the sign bit set). QNaN values
  249. * can encode a 51-bit payload. Hardware produced and C-library payloads typically
  250. * have a payload of zero. We assume that non-zero payloads are available to encode
  251. * pointer and integer values. Since any 64-bit bit pattern where the top 15 bits are
  252. * all set represents a NaN with a non-zero payload, we can use this space in the NaN
  253. * ranges to encode other values (however there are also other ranges of NaN space that
  254. * could have been selected).
  255. *
  256. * For JSValues that do not contain a double value, the high 32 bits contain the tag
  257. * values listed in the enums below, which all correspond to NaN-space. In the case of
  258. * cell, integer and bool values the lower 32 bits (the 'payload') contain the pointer
  259. * integer or boolean value; in the case of all other tags the payload is 0.
  260. */
  261. uint32_t tag() const;
  262. int32_t payload() const;
  263. #if ENABLE(LLINT_C_LOOP)
  264. // This should only be used by the LLInt C Loop interpreter who needs
  265. // synthesize JSValue from its "register"s holding tag and payload
  266. // values.
  267. explicit JSValue(int32_t tag, int32_t payload);
  268. #endif
  269. #elif USE(JSVALUE64)
  270. /*
  271. * On 64-bit platforms USE(JSVALUE64) should be defined, and we use a NaN-encoded
  272. * form for immediates.
  273. *
  274. * The encoding makes use of unused NaN space in the IEEE754 representation. Any value
  275. * with the top 13 bits set represents a QNaN (with the sign bit set). QNaN values
  276. * can encode a 51-bit payload. Hardware produced and C-library payloads typically
  277. * have a payload of zero. We assume that non-zero payloads are available to encode
  278. * pointer and integer values. Since any 64-bit bit pattern where the top 15 bits are
  279. * all set represents a NaN with a non-zero payload, we can use this space in the NaN
  280. * ranges to encode other values (however there are also other ranges of NaN space that
  281. * could have been selected).
  282. *
  283. * This range of NaN space is represented by 64-bit numbers begining with the 16-bit
  284. * hex patterns 0xFFFE and 0xFFFF - we rely on the fact that no valid double-precision
  285. * numbers will begin fall in these ranges.
  286. *
  287. * The top 16-bits denote the type of the encoded JSValue:
  288. *
  289. * Pointer { 0000:PPPP:PPPP:PPPP
  290. * / 0001:****:****:****
  291. * Double { ...
  292. * \ FFFE:****:****:****
  293. * Integer { FFFF:0000:IIII:IIII
  294. *
  295. * The scheme we have implemented encodes double precision values by performing a
  296. * 64-bit integer addition of the value 2^48 to the number. After this manipulation
  297. * no encoded double-precision value will begin with the pattern 0x0000 or 0xFFFF.
  298. * Values must be decoded by reversing this operation before subsequent floating point
  299. * operations my be peformed.
  300. *
  301. * 32-bit signed integers are marked with the 16-bit tag 0xFFFF.
  302. *
  303. * The tag 0x0000 denotes a pointer, or another form of tagged immediate. Boolean,
  304. * null and undefined values are represented by specific, invalid pointer values:
  305. *
  306. * False: 0x06
  307. * True: 0x07
  308. * Undefined: 0x0a
  309. * Null: 0x02
  310. *
  311. * These values have the following properties:
  312. * - Bit 1 (TagBitTypeOther) is set for all four values, allowing real pointers to be
  313. * quickly distinguished from all immediate values, including these invalid pointers.
  314. * - With bit 3 is masked out (TagBitUndefined) Undefined and Null share the
  315. * same value, allowing null & undefined to be quickly detected.
  316. *
  317. * No valid JSValue will have the bit pattern 0x0, this is used to represent array
  318. * holes, and as a C++ 'no value' result (e.g. JSValue() has an internal value of 0).
  319. */
  320. // These values are #defines since using static const integers here is a ~1% regression!
  321. // This value is 2^48, used to encode doubles such that the encoded value will begin
  322. // with a 16-bit pattern within the range 0x0001..0xFFFE.
  323. #define DoubleEncodeOffset 0x1000000000000ll
  324. // If all bits in the mask are set, this indicates an integer number,
  325. // if any but not all are set this value is a double precision number.
  326. #define TagTypeNumber 0xffff000000000000ll
  327. // All non-numeric (bool, null, undefined) immediates have bit 2 set.
  328. #define TagBitTypeOther 0x2ll
  329. #define TagBitBool 0x4ll
  330. #define TagBitUndefined 0x8ll
  331. // Combined integer value for non-numeric immediates.
  332. #define ValueFalse (TagBitTypeOther | TagBitBool | false)
  333. #define ValueTrue (TagBitTypeOther | TagBitBool | true)
  334. #define ValueUndefined (TagBitTypeOther | TagBitUndefined)
  335. #define ValueNull (TagBitTypeOther)
  336. // TagMask is used to check for all types of immediate values (either number or 'other').
  337. #define TagMask (TagTypeNumber | TagBitTypeOther)
  338. // These special values are never visible to JavaScript code; Empty is used to represent
  339. // Array holes, and for uninitialized JSValues. Deleted is used in hash table code.
  340. // These values would map to cell types in the JSValue encoding, but not valid GC cell
  341. // pointer should have either of these values (Empty is null, deleted is at an invalid
  342. // alignment for a GC cell, and in the zero page).
  343. #define ValueEmpty 0x0ll
  344. #define ValueDeleted 0x4ll
  345. #endif
  346. EncodedValueDescriptor u;
  347. };
  348. typedef IntHash<EncodedJSValue> EncodedJSValueHash;
  349. #if USE(JSVALUE32_64)
  350. struct EncodedJSValueHashTraits : HashTraits<EncodedJSValue> {
  351. static const bool emptyValueIsZero = false;
  352. static EncodedJSValue emptyValue() { return JSValue::encode(JSValue()); }
  353. static void constructDeletedValue(EncodedJSValue& slot) { slot = JSValue::encode(JSValue(JSValue::HashTableDeletedValue)); }
  354. static bool isDeletedValue(EncodedJSValue value) { return value == JSValue::encode(JSValue(JSValue::HashTableDeletedValue)); }
  355. };
  356. #else
  357. struct EncodedJSValueHashTraits : HashTraits<EncodedJSValue> {
  358. static void constructDeletedValue(EncodedJSValue& slot) { slot = JSValue::encode(JSValue(JSValue::HashTableDeletedValue)); }
  359. static bool isDeletedValue(EncodedJSValue value) { return value == JSValue::encode(JSValue(JSValue::HashTableDeletedValue)); }
  360. };
  361. #endif
  362. typedef HashMap<EncodedJSValue, unsigned, EncodedJSValueHash, EncodedJSValueHashTraits> JSValueMap;
  363. // Stand-alone helper functions.
  364. inline JSValue jsNull()
  365. {
  366. return JSValue(JSValue::JSNull);
  367. }
  368. inline JSValue jsUndefined()
  369. {
  370. return JSValue(JSValue::JSUndefined);
  371. }
  372. inline JSValue jsBoolean(bool b)
  373. {
  374. return b ? JSValue(JSValue::JSTrue) : JSValue(JSValue::JSFalse);
  375. }
  376. ALWAYS_INLINE JSValue jsDoubleNumber(double d)
  377. {
  378. ASSERT(JSValue(JSValue::EncodeAsDouble, d).isNumber());
  379. return JSValue(JSValue::EncodeAsDouble, d);
  380. }
  381. ALWAYS_INLINE JSValue jsNumber(double d)
  382. {
  383. ASSERT(JSValue(d).isNumber());
  384. return JSValue(d);
  385. }
  386. ALWAYS_INLINE JSValue jsNumber(char i)
  387. {
  388. return JSValue(i);
  389. }
  390. ALWAYS_INLINE JSValue jsNumber(unsigned char i)
  391. {
  392. return JSValue(i);
  393. }
  394. ALWAYS_INLINE JSValue jsNumber(short i)
  395. {
  396. return JSValue(i);
  397. }
  398. ALWAYS_INLINE JSValue jsNumber(unsigned short i)
  399. {
  400. return JSValue(i);
  401. }
  402. ALWAYS_INLINE JSValue jsNumber(int i)
  403. {
  404. return JSValue(i);
  405. }
  406. ALWAYS_INLINE JSValue jsNumber(unsigned i)
  407. {
  408. return JSValue(i);
  409. }
  410. ALWAYS_INLINE JSValue jsNumber(long i)
  411. {
  412. return JSValue(i);
  413. }
  414. ALWAYS_INLINE JSValue jsNumber(unsigned long i)
  415. {
  416. return JSValue(i);
  417. }
  418. ALWAYS_INLINE JSValue jsNumber(long long i)
  419. {
  420. return JSValue(i);
  421. }
  422. ALWAYS_INLINE JSValue jsNumber(unsigned long long i)
  423. {
  424. return JSValue(i);
  425. }
  426. inline bool operator==(const JSValue a, const JSCell* b) { return a == JSValue(b); }
  427. inline bool operator==(const JSCell* a, const JSValue b) { return JSValue(a) == b; }
  428. inline bool operator!=(const JSValue a, const JSCell* b) { return a != JSValue(b); }
  429. inline bool operator!=(const JSCell* a, const JSValue b) { return JSValue(a) != b; }
  430. } // namespace JSC
  431. #endif // JSCJSValue_h