diff options
Diffstat (limited to 'JavaScriptCore/runtime/JSValue.cpp')
| -rw-r--r-- | JavaScriptCore/runtime/JSValue.cpp | 87 |
1 files changed, 50 insertions, 37 deletions
diff --git a/JavaScriptCore/runtime/JSValue.cpp b/JavaScriptCore/runtime/JSValue.cpp index 502312c..2a23a79 100644 --- a/JavaScriptCore/runtime/JSValue.cpp +++ b/JavaScriptCore/runtime/JSValue.cpp @@ -25,6 +25,7 @@ #include "BooleanConstructor.h" #include "BooleanPrototype.h" +#include "Error.h" #include "ExceptionHelpers.h" #include "JSGlobalObject.h" #include "JSFunction.h" @@ -63,7 +64,7 @@ JSObject* JSValue::toObjectSlowCase(ExecState* exec) const return constructBooleanFromImmediateBoolean(exec, asValue()); ASSERT(isUndefinedOrNull()); JSNotAnObjectErrorStub* exception = createNotAnObjectErrorStub(exec, isNull()); - exec->setException(exception); + throwError(exec, exception); return new (exec) JSNotAnObject(exec, exception); } @@ -88,7 +89,7 @@ JSObject* JSValue::synthesizeObject(ExecState* exec) const return constructBooleanFromImmediateBoolean(exec, asValue()); JSNotAnObjectErrorStub* exception = createNotAnObjectErrorStub(exec, isNull()); - exec->setException(exception); + throwError(exec, exception); return new (exec) JSNotAnObject(exec, exception); } @@ -101,7 +102,7 @@ JSObject* JSValue::synthesizePrototype(ExecState* exec) const return exec->lexicalGlobalObject()->booleanPrototype(); JSNotAnObjectErrorStub* exception = createNotAnObjectErrorStub(exec, isNull()); - exec->setException(exception); + throwError(exec, exception); return new (exec) JSNotAnObject(exec, exception); } @@ -125,51 +126,58 @@ char* JSValue::description() snprintf(description, size, "False"); else if (isNull()) snprintf(description, size, "Null"); - else { - ASSERT(isUndefined()); + else if (isUndefined()) snprintf(description, size, "Undefined"); - } + else + snprintf(description, size, "INVALID"); return description; } #endif -int32_t toInt32SlowCase(double d, bool& ok) +// This in the ToInt32 operation is defined in section 9.5 of the ECMA-262 spec. +// Note that this operation is identical to ToUInt32 other than to interpretation +// of the resulting bit-pattern (as such this metod is also called to implement +// ToUInt32). +// +// The operation can be descibed as round towards zero, then select the 32 least +// bits of the resulting value in 2s-complement representation. +int32_t toInt32(double number) { - ok = true; - - if (d >= -D32 / 2 && d < D32 / 2) - return static_cast<int32_t>(d); - - if (isnan(d) || isinf(d)) { - ok = false; + int64_t bits = WTF::bitwise_cast<int64_t>(number); + int32_t exp = (static_cast<int32_t>(bits >> 52) & 0x7ff) - 0x3ff; + + // If exponent < 0 there will be no bits to the left of the decimal point + // after rounding; if the exponent is > 83 then no bits of precision can be + // left in the low 32-bit range of the result (IEEE-754 doubles have 52 bits + // of fractional precision). + // Note this case handles 0, -0, and all infinte, NaN, & denormal value. + if (exp < 0 || exp > 83) return 0; - } - double d32 = fmod(trunc(d), D32); - if (d32 >= D32 / 2) - d32 -= D32; - else if (d32 < -D32 / 2) - d32 += D32; - return static_cast<int32_t>(d32); -} - -uint32_t toUInt32SlowCase(double d, bool& ok) -{ - ok = true; - - if (d >= 0.0 && d < D32) - return static_cast<uint32_t>(d); - - if (isnan(d) || isinf(d)) { - ok = false; - return 0; + // Select the appropriate 32-bits from the floating point mantissa. If the + // exponent is 52 then the bits we need to select are already aligned to the + // lowest bits of the 64-bit integer representation of tghe number, no need + // to shift. If the exponent is greater than 52 we need to shift the value + // left by (exp - 52), if the value is less than 52 we need to shift right + // accordingly. + int32_t result = (exp > 52) + ? static_cast<int32_t>(bits << (exp - 52)) + : static_cast<int32_t>(bits >> (52 - exp)); + + // IEEE-754 double precision values are stored omitting an implicit 1 before + // the decimal point; we need to reinsert this now. We may also the shifted + // invalid bits into the result that are not a part of the mantissa (the sign + // and exponent bits from the floatingpoint representation); mask these out. + if (exp < 32) { + int32_t missingOne = 1 << exp; + result &= missingOne - 1; + result += missingOne; } - double d32 = fmod(trunc(d), D32); - if (d32 < 0) - d32 += D32; - return static_cast<uint32_t>(d32); + // If the input value was negative (we could test either 'number' or 'bits', + // but testing 'bits' is likely faster) invert the result appropriately. + return bits < 0 ? -result : result; } NEVER_INLINE double nonInlineNaN() @@ -181,4 +189,9 @@ NEVER_INLINE double nonInlineNaN() #endif } +bool JSValue::isValidCallee() +{ + return asObject(asObject(asCell())->getAnonymousValue(0))->isGlobalObject(); +} + } // namespace JSC |
