Added implementation if Uint32::Value.
Review URL: http://codereview.chromium.org/661275 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4008 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
fca7b2cefa
commit
d51f2c96cb
13
include/v8.h
13
include/v8.h
@ -550,13 +550,13 @@ class V8EXPORT Script {
|
||||
* Compiles the specified script (context-independent).
|
||||
*
|
||||
* \param source Script source code.
|
||||
* \param origin Script origin, owned by caller, no references are kept
|
||||
* \param origin Script origin, owned by caller, no references are kept
|
||||
* when New() returns
|
||||
* \param pre_data Pre-parsing data, as obtained by ScriptData::PreCompile()
|
||||
* using pre_data speeds compilation if it's done multiple times.
|
||||
* Owned by caller, no references are kept when New() returns.
|
||||
* \param script_data Arbitrary data associated with script. Using
|
||||
* this has same effect as calling SetData(), but allows data to be
|
||||
* this has same effect as calling SetData(), but allows data to be
|
||||
* available to compile event handlers.
|
||||
* \return Compiled script object (context independent; when run it
|
||||
* will use the currently entered context).
|
||||
@ -571,7 +571,7 @@ class V8EXPORT Script {
|
||||
* object (typically a string) as the script's origin.
|
||||
*
|
||||
* \param source Script source code.
|
||||
* \patam file_name file name object (typically a string) to be used
|
||||
* \param file_name file name object (typically a string) to be used
|
||||
* as the script's origin.
|
||||
* \return Compiled script object (context independent; when run it
|
||||
* will use the currently entered context).
|
||||
@ -583,7 +583,7 @@ class V8EXPORT Script {
|
||||
* Compiles the specified script (bound to current context).
|
||||
*
|
||||
* \param source Script source code.
|
||||
* \param origin Script origin, owned by caller, no references are kept
|
||||
* \param origin Script origin, owned by caller, no references are kept
|
||||
* when Compile() returns
|
||||
* \param pre_data Pre-parsing data, as obtained by ScriptData::PreCompile()
|
||||
* using pre_data speeds compilation if it's done multiple times.
|
||||
@ -766,6 +766,11 @@ class V8EXPORT Value : public Data {
|
||||
*/
|
||||
bool IsInt32() const;
|
||||
|
||||
/**
|
||||
* Returns true if this value is a 32-bit signed integer.
|
||||
*/
|
||||
bool IsUint32() const;
|
||||
|
||||
/**
|
||||
* Returns true if this value is a Date.
|
||||
*/
|
||||
|
23
src/api.cc
23
src/api.cc
@ -1569,6 +1569,18 @@ bool Value::IsInt32() const {
|
||||
}
|
||||
|
||||
|
||||
bool Value::IsUint32() const {
|
||||
if (IsDeadCheck("v8::Value::IsUint32()")) return false;
|
||||
i::Handle<i::Object> obj = Utils::OpenHandle(this);
|
||||
if (obj->IsSmi()) return i::Smi::cast(*obj)->value() >= 0;
|
||||
if (obj->IsNumber()) {
|
||||
double value = obj->Number();
|
||||
return i::FastUI2D(i::FastD2UI(value)) == value;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool Value::IsDate() const {
|
||||
if (IsDeadCheck("v8::Value::IsDate()")) return false;
|
||||
i::Handle<i::Object> obj = Utils::OpenHandle(this);
|
||||
@ -2756,6 +2768,17 @@ int32_t Int32::Value() const {
|
||||
}
|
||||
|
||||
|
||||
uint32_t Uint32::Value() const {
|
||||
if (IsDeadCheck("v8::Uint32::Value()")) return 0;
|
||||
i::Handle<i::Object> obj = Utils::OpenHandle(this);
|
||||
if (obj->IsSmi()) {
|
||||
return i::Smi::cast(*obj)->value();
|
||||
} else {
|
||||
return static_cast<uint32_t>(obj->Number());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int v8::Object::InternalFieldCount() {
|
||||
if (IsDeadCheck("v8::Object::InternalFieldCount()")) return 0;
|
||||
i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
|
||||
|
@ -59,6 +59,32 @@ static inline int FastD2I(double x) {
|
||||
}
|
||||
|
||||
|
||||
// The fast double-to-unsigned-int conversion routine does not guarantee
|
||||
// rounding towards zero.
|
||||
static inline unsigned int FastD2UI(double x) {
|
||||
// There is no unsigned version of lrint, so there is no fast path
|
||||
// in this function as there is in FastD2I. Using lrint doesn't work
|
||||
// for values of 2^31 and above.
|
||||
|
||||
// Convert "small enough" doubles to uint32_t by fixing the 32
|
||||
// least significant non-fractional bits in the low 32 bits of the
|
||||
// double, and reading them from there.
|
||||
const double k2Pow52 = 4503599627370496.0;
|
||||
bool negative = x < 0;
|
||||
if (negative) {
|
||||
x = -x;
|
||||
}
|
||||
if (x < k2Pow52) {
|
||||
x += k2Pow52;
|
||||
uint32_t result;
|
||||
memcpy(&result, &x, sizeof(result)); // Copy low 32 bits.
|
||||
return negative ? ~result + 1 : result;
|
||||
}
|
||||
// Large number (outside uint32 range), Infinity or NaN.
|
||||
return 0x80000000u; // Return integer indefinite.
|
||||
}
|
||||
|
||||
|
||||
static inline double DoubleToInteger(double x) {
|
||||
if (isnan(x)) return 0;
|
||||
if (!isfinite(x) || x == 0) return x;
|
||||
|
@ -32,11 +32,12 @@ namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
|
||||
// The fast double-to-int conversion routine does not guarantee
|
||||
// The fast double-to-(unsigned-)int conversion routine does not guarantee
|
||||
// rounding towards zero.
|
||||
// The result is unspecified if x is infinite or NaN, or if the rounded
|
||||
// integer value is outside the range of type int.
|
||||
static inline int FastD2I(double x);
|
||||
static inline unsigned int FastD2UI(double x);
|
||||
|
||||
|
||||
static inline double FastI2D(int x) {
|
||||
|
@ -1960,6 +1960,95 @@ static void CheckUncle(v8::TryCatch* try_catch) {
|
||||
}
|
||||
|
||||
|
||||
THREADED_TEST(ConversionNumber) {
|
||||
v8::HandleScope scope;
|
||||
LocalContext env;
|
||||
// Very large number.
|
||||
CompileRun("var obj = Math.pow(2,32) * 1237;");
|
||||
Local<Value> obj = env->Global()->Get(v8_str("obj"));
|
||||
CHECK_EQ(5312874545152.0, obj->ToNumber()->Value());
|
||||
CHECK_EQ(0, obj->ToInt32()->Value());
|
||||
CHECK(0u == obj->ToUint32()->Value()); // NOLINT - no CHECK_EQ for unsigned.
|
||||
// Large number.
|
||||
CompileRun("var obj = -1234567890123;");
|
||||
obj = env->Global()->Get(v8_str("obj"));
|
||||
CHECK_EQ(-1234567890123.0, obj->ToNumber()->Value());
|
||||
CHECK_EQ(-1912276171, obj->ToInt32()->Value());
|
||||
CHECK(2382691125u == obj->ToUint32()->Value()); // NOLINT
|
||||
// Small positive integer.
|
||||
CompileRun("var obj = 42;");
|
||||
obj = env->Global()->Get(v8_str("obj"));
|
||||
CHECK_EQ(42.0, obj->ToNumber()->Value());
|
||||
CHECK_EQ(42, obj->ToInt32()->Value());
|
||||
CHECK(42u == obj->ToUint32()->Value()); // NOLINT
|
||||
// Negative integer.
|
||||
CompileRun("var obj = -37;");
|
||||
obj = env->Global()->Get(v8_str("obj"));
|
||||
CHECK_EQ(-37.0, obj->ToNumber()->Value());
|
||||
CHECK_EQ(-37, obj->ToInt32()->Value());
|
||||
CHECK(4294967259u == obj->ToUint32()->Value()); // NOLINT
|
||||
// Positive non-int32 integer.
|
||||
CompileRun("var obj = 0x81234567;");
|
||||
obj = env->Global()->Get(v8_str("obj"));
|
||||
CHECK_EQ(2166572391.0, obj->ToNumber()->Value());
|
||||
CHECK_EQ(-2128394905, obj->ToInt32()->Value());
|
||||
CHECK(2166572391u == obj->ToUint32()->Value()); // NOLINT
|
||||
// Fraction.
|
||||
CompileRun("var obj = 42.3;");
|
||||
obj = env->Global()->Get(v8_str("obj"));
|
||||
CHECK_EQ(42.3, obj->ToNumber()->Value());
|
||||
CHECK_EQ(42, obj->ToInt32()->Value());
|
||||
CHECK(42u == obj->ToUint32()->Value()); // NOLINT
|
||||
// Large negative fraction.
|
||||
CompileRun("var obj = -5726623061.75;");
|
||||
obj = env->Global()->Get(v8_str("obj"));
|
||||
CHECK_EQ(-5726623061.75, obj->ToNumber()->Value());
|
||||
CHECK_EQ(-1431655765, obj->ToInt32()->Value());
|
||||
CHECK(2863311531u == obj->ToUint32()->Value()); // NOLINT
|
||||
}
|
||||
|
||||
|
||||
THREADED_TEST(isNumberType) {
|
||||
v8::HandleScope scope;
|
||||
LocalContext env;
|
||||
// Very large number.
|
||||
CompileRun("var obj = Math.pow(2,32) * 1237;");
|
||||
Local<Value> obj = env->Global()->Get(v8_str("obj"));
|
||||
CHECK(!obj->IsInt32());
|
||||
CHECK(!obj->IsUint32());
|
||||
// Large negative number.
|
||||
CompileRun("var obj = -1234567890123;");
|
||||
obj = env->Global()->Get(v8_str("obj"));
|
||||
CHECK(!obj->IsInt32());
|
||||
CHECK(!obj->IsUint32());
|
||||
// Small positive integer.
|
||||
CompileRun("var obj = 42;");
|
||||
obj = env->Global()->Get(v8_str("obj"));
|
||||
CHECK(obj->IsInt32());
|
||||
CHECK(obj->IsUint32());
|
||||
// Negative integer.
|
||||
CompileRun("var obj = -37;");
|
||||
obj = env->Global()->Get(v8_str("obj"));
|
||||
CHECK(obj->IsInt32());
|
||||
CHECK(!obj->IsUint32());
|
||||
// Positive non-int32 integer.
|
||||
CompileRun("var obj = 0x81234567;");
|
||||
obj = env->Global()->Get(v8_str("obj"));
|
||||
CHECK(!obj->IsInt32());
|
||||
CHECK(obj->IsUint32());
|
||||
// Fraction.
|
||||
CompileRun("var obj = 42.3;");
|
||||
obj = env->Global()->Get(v8_str("obj"));
|
||||
CHECK(!obj->IsInt32());
|
||||
CHECK(!obj->IsUint32());
|
||||
// Large negative fraction.
|
||||
CompileRun("var obj = -5726623061.75;");
|
||||
obj = env->Global()->Get(v8_str("obj"));
|
||||
CHECK(!obj->IsInt32());
|
||||
CHECK(!obj->IsUint32());
|
||||
}
|
||||
|
||||
|
||||
THREADED_TEST(ConversionException) {
|
||||
v8::HandleScope scope;
|
||||
LocalContext env;
|
||||
|
Loading…
Reference in New Issue
Block a user