18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/* 28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) 38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2001 Peter Kelly (pmk@post.com) 48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2003, 2007, 2008 Apple Inc. All rights reserved. 58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is free software; you can redistribute it and/or 78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modify it under the terms of the GNU Library General Public 88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * License as published by the Free Software Foundation; either 98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * version 2 of the License, or (at your option) any later version. 108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is distributed in the hope that it will be useful, 128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * but WITHOUT ANY WARRANTY; without even the implied warranty of 138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Library General Public License for more details. 158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * You should have received a copy of the GNU Library General Public License 178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * along with this library; see the file COPYING.LIB. If not, write to 188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Boston, MA 02110-1301, USA. 208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h" 248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSValue.h" 258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "BooleanConstructor.h" 270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "BooleanPrototype.h" 28545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch#include "Error.h" 290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "ExceptionHelpers.h" 300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "JSGlobalObject.h" 318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSFunction.h" 320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "JSNotAnObject.h" 330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "NumberObject.h" 348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <wtf/MathExtras.h> 350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include <wtf/StringExtras.h> 368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace JSC { 388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic const double D32 = 4294967296.0; 408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// ECMA 9.4 425f1ab04193ad0130ca8204aadaceae083aca9881Feng Qiandouble JSValue::toInteger(ExecState* exec) const 438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (isInt32()) 450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return asInt32(); 468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project double d = toNumber(exec); 478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return isnan(d) ? 0.0 : trunc(d); 488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 505f1ab04193ad0130ca8204aadaceae083aca9881Feng Qiandouble JSValue::toIntegerPreserveNaN(ExecState* exec) const 518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 520bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (isInt32()) 530bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return asInt32(); 548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return trunc(toNumber(exec)); 558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 572bde8e466a4451c7319e3a072d118917957d6554Steve BlockJSObject* JSValue::toObjectSlowCase(ExecState* exec, JSGlobalObject* globalObject) const 580bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch ASSERT(!isCell()); 600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (isInt32() || isDouble()) 622bde8e466a4451c7319e3a072d118917957d6554Steve Block return constructNumber(exec, globalObject, asValue()); 630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (isTrue() || isFalse()) 642bde8e466a4451c7319e3a072d118917957d6554Steve Block return constructBooleanFromImmediateBoolean(exec, globalObject, asValue()); 656b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch ASSERT(isUndefinedOrNull()); 676b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner throwError(exec, createNotAnObjectError(exec, *this)); 686b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner return new (exec) JSNotAnObject(exec); 690bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 700bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 710bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochJSObject* JSValue::toThisObjectSlowCase(ExecState* exec) const 720bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 730bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch ASSERT(!isCell()); 740bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 750bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (isInt32() || isDouble()) 762bde8e466a4451c7319e3a072d118917957d6554Steve Block return constructNumber(exec, exec->lexicalGlobalObject(), asValue()); 770bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (isTrue() || isFalse()) 782bde8e466a4451c7319e3a072d118917957d6554Steve Block return constructBooleanFromImmediateBoolean(exec, exec->lexicalGlobalObject(), asValue()); 790bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch ASSERT(isUndefinedOrNull()); 800bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return exec->globalThisValue(); 810bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 820bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 830bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochJSObject* JSValue::synthesizeObject(ExecState* exec) const 840bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 850bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch ASSERT(!isCell()); 860bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (isNumber()) 872bde8e466a4451c7319e3a072d118917957d6554Steve Block return constructNumber(exec, exec->lexicalGlobalObject(), asValue()); 880bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (isBoolean()) 892bde8e466a4451c7319e3a072d118917957d6554Steve Block return constructBooleanFromImmediateBoolean(exec, exec->lexicalGlobalObject(), asValue()); 906b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 916b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner ASSERT(isUndefinedOrNull()); 926b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner throwError(exec, createNotAnObjectError(exec, *this)); 936b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner return new (exec) JSNotAnObject(exec); 940bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 950bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 960bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochJSObject* JSValue::synthesizePrototype(ExecState* exec) const 970bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 980bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch ASSERT(!isCell()); 990bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (isNumber()) 1000bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return exec->lexicalGlobalObject()->numberPrototype(); 1010bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (isBoolean()) 1020bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return exec->lexicalGlobalObject()->booleanPrototype(); 1030bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1046b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner ASSERT(isUndefinedOrNull()); 1056b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner throwError(exec, createNotAnObjectError(exec, *this)); 1066b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner return new (exec) JSNotAnObject(exec); 1070bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 1080bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1090bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#ifndef NDEBUG 1100bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochchar* JSValue::description() 1110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 1120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch static const size_t size = 32; 1130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch static char description[size]; 114231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 115231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (!*this) 116231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block snprintf(description, size, "<JSValue()>"); 117231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block else if (isInt32()) 1180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch snprintf(description, size, "Int32: %d", asInt32()); 1190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch else if (isDouble()) 1200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch snprintf(description, size, "Double: %lf", asDouble()); 1210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch else if (isCell()) 1220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch snprintf(description, size, "Cell: %p", asCell()); 1230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch else if (isTrue()) 1240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch snprintf(description, size, "True"); 1250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch else if (isFalse()) 1260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch snprintf(description, size, "False"); 1270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch else if (isNull()) 1280bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch snprintf(description, size, "Null"); 12906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen else if (isUndefined()) 1300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch snprintf(description, size, "Undefined"); 13106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen else 13206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen snprintf(description, size, "INVALID"); 1330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return description; 1350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 1360bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#endif 1370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 13868513a70bcd92384395513322f1b801e7bf9c729Steve Block// This in the ToInt32 operation is defined in section 9.5 of the ECMA-262 spec. 13968513a70bcd92384395513322f1b801e7bf9c729Steve Block// Note that this operation is identical to ToUInt32 other than to interpretation 14068513a70bcd92384395513322f1b801e7bf9c729Steve Block// of the resulting bit-pattern (as such this metod is also called to implement 14168513a70bcd92384395513322f1b801e7bf9c729Steve Block// ToUInt32). 14268513a70bcd92384395513322f1b801e7bf9c729Steve Block// 14368513a70bcd92384395513322f1b801e7bf9c729Steve Block// The operation can be descibed as round towards zero, then select the 32 least 14468513a70bcd92384395513322f1b801e7bf9c729Steve Block// bits of the resulting value in 2s-complement representation. 14568513a70bcd92384395513322f1b801e7bf9c729Steve Blockint32_t toInt32(double number) 1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 14768513a70bcd92384395513322f1b801e7bf9c729Steve Block int64_t bits = WTF::bitwise_cast<int64_t>(number); 14868513a70bcd92384395513322f1b801e7bf9c729Steve Block int32_t exp = (static_cast<int32_t>(bits >> 52) & 0x7ff) - 0x3ff; 14968513a70bcd92384395513322f1b801e7bf9c729Steve Block 15068513a70bcd92384395513322f1b801e7bf9c729Steve Block // If exponent < 0 there will be no bits to the left of the decimal point 15168513a70bcd92384395513322f1b801e7bf9c729Steve Block // after rounding; if the exponent is > 83 then no bits of precision can be 15268513a70bcd92384395513322f1b801e7bf9c729Steve Block // left in the low 32-bit range of the result (IEEE-754 doubles have 52 bits 15368513a70bcd92384395513322f1b801e7bf9c729Steve Block // of fractional precision). 15468513a70bcd92384395513322f1b801e7bf9c729Steve Block // Note this case handles 0, -0, and all infinte, NaN, & denormal value. 15568513a70bcd92384395513322f1b801e7bf9c729Steve Block if (exp < 0 || exp > 83) 1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 15868513a70bcd92384395513322f1b801e7bf9c729Steve Block // Select the appropriate 32-bits from the floating point mantissa. If the 15968513a70bcd92384395513322f1b801e7bf9c729Steve Block // exponent is 52 then the bits we need to select are already aligned to the 16068513a70bcd92384395513322f1b801e7bf9c729Steve Block // lowest bits of the 64-bit integer representation of tghe number, no need 16168513a70bcd92384395513322f1b801e7bf9c729Steve Block // to shift. If the exponent is greater than 52 we need to shift the value 16268513a70bcd92384395513322f1b801e7bf9c729Steve Block // left by (exp - 52), if the value is less than 52 we need to shift right 16368513a70bcd92384395513322f1b801e7bf9c729Steve Block // accordingly. 16468513a70bcd92384395513322f1b801e7bf9c729Steve Block int32_t result = (exp > 52) 16568513a70bcd92384395513322f1b801e7bf9c729Steve Block ? static_cast<int32_t>(bits << (exp - 52)) 16668513a70bcd92384395513322f1b801e7bf9c729Steve Block : static_cast<int32_t>(bits >> (52 - exp)); 16768513a70bcd92384395513322f1b801e7bf9c729Steve Block 16868513a70bcd92384395513322f1b801e7bf9c729Steve Block // IEEE-754 double precision values are stored omitting an implicit 1 before 16968513a70bcd92384395513322f1b801e7bf9c729Steve Block // the decimal point; we need to reinsert this now. We may also the shifted 17068513a70bcd92384395513322f1b801e7bf9c729Steve Block // invalid bits into the result that are not a part of the mantissa (the sign 17168513a70bcd92384395513322f1b801e7bf9c729Steve Block // and exponent bits from the floatingpoint representation); mask these out. 17268513a70bcd92384395513322f1b801e7bf9c729Steve Block if (exp < 32) { 17368513a70bcd92384395513322f1b801e7bf9c729Steve Block int32_t missingOne = 1 << exp; 17468513a70bcd92384395513322f1b801e7bf9c729Steve Block result &= missingOne - 1; 17568513a70bcd92384395513322f1b801e7bf9c729Steve Block result += missingOne; 1768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 17868513a70bcd92384395513322f1b801e7bf9c729Steve Block // If the input value was negative (we could test either 'number' or 'bits', 17968513a70bcd92384395513322f1b801e7bf9c729Steve Block // but testing 'bits' is likely faster) invert the result appropriately. 18068513a70bcd92384395513322f1b801e7bf9c729Steve Block return bits < 0 ? -result : result; 1818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1830bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochNEVER_INLINE double nonInlineNaN() 1840bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 1858a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block#if OS(SYMBIAN) 1868a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block return nanval(); 1878a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block#else 1880bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return std::numeric_limits<double>::quiet_NaN(); 1898a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block#endif 1900bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 1910bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 192e78cbe89e6f337f2f1fe40315be88f742b547151Steve Blockbool JSValue::isValidCallee() 193e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block{ 194e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block return asObject(asObject(asCell())->getAnonymousValue(0))->isGlobalObject(); 195e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block} 196e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block 1978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace JSC 198