Changed Object.keys to return strings for element indices.

Review URL: http://codereview.chromium.org/246077


git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3012 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 8cf14025
...@@ -673,6 +673,11 @@ Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo(Handle<String> name) { ...@@ -673,6 +673,11 @@ Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo(Handle<String> name) {
} }
Handle<String> Factory::NumberToString(Handle<Object> number) {
CALL_HEAP_FUNCTION(Heap::NumberToString(*number), String);
}
Handle<NumberDictionary> Factory::DictionaryAtNumberPut( Handle<NumberDictionary> Factory::DictionaryAtNumberPut(
Handle<NumberDictionary> dictionary, Handle<NumberDictionary> dictionary,
uint32_t key, uint32_t key,
......
...@@ -286,6 +286,8 @@ class Factory : public AllStatic { ...@@ -286,6 +286,8 @@ class Factory : public AllStatic {
Handle<Object> value, Handle<Object> value,
PropertyAttributes attributes); PropertyAttributes attributes);
static Handle<String> NumberToString(Handle<Object> number);
enum ApiInstanceType { enum ApiInstanceType {
JavaScriptObject, JavaScriptObject,
InnerGlobalObject, InnerGlobalObject,
......
...@@ -1587,6 +1587,31 @@ Object* Heap::SmiOrNumberFromDouble(double value, ...@@ -1587,6 +1587,31 @@ Object* Heap::SmiOrNumberFromDouble(double value,
} }
Object* Heap::NumberToString(Object* number) {
Object* cached = GetNumberStringCache(number);
if (cached != undefined_value()) {
return cached;
}
char arr[100];
Vector<char> buffer(arr, ARRAY_SIZE(arr));
const char* str;
if (number->IsSmi()) {
int num = Smi::cast(number)->value();
str = IntToCString(num, buffer);
} else {
double num = HeapNumber::cast(number)->value();
str = DoubleToCString(num, buffer);
}
Object* result = AllocateStringFromAscii(CStrVector(str));
if (!result->IsFailure()) {
SetNumberStringCache(number, String::cast(result));
}
return result;
}
Object* Heap::NewNumberFromDouble(double value, PretenureFlag pretenure) { Object* Heap::NewNumberFromDouble(double value, PretenureFlag pretenure) {
return SmiOrNumberFromDouble(value, return SmiOrNumberFromDouble(value,
true /* number object must be new */, true /* number object must be new */,
......
...@@ -882,6 +882,8 @@ class Heap : public AllStatic { ...@@ -882,6 +882,8 @@ class Heap : public AllStatic {
kRootListLength kRootListLength
}; };
static Object* NumberToString(Object* number);
private: private:
static int semispace_size_; static int semispace_size_;
static int initial_semispace_size_; static int initial_semispace_size_;
......
...@@ -3020,8 +3020,20 @@ static Object* Runtime_LocalKeys(Arguments args) { ...@@ -3020,8 +3020,20 @@ static Object* Runtime_LocalKeys(Arguments args) {
// Some fast paths through GetKeysInFixedArrayFor reuse a cached // Some fast paths through GetKeysInFixedArrayFor reuse a cached
// property array and since the result is mutable we have to create // property array and since the result is mutable we have to create
// a fresh clone on each invocation. // a fresh clone on each invocation.
Handle<FixedArray> copy = Factory::NewFixedArray(contents->length()); int length = contents->length();
contents->CopyTo(0, *copy, 0, contents->length()); Handle<FixedArray> copy = Factory::NewFixedArray(length);
for (int i = 0; i < length; i++) {
Object* entry = contents->get(i);
if (entry->IsString()) {
copy->set(i, entry);
} else {
ASSERT(entry->IsNumber());
HandleScope scope;
Handle<Object> entry_handle(entry);
Handle<Object> entry_str = Factory::NumberToString(entry_handle);
copy->set(i, *entry_str);
}
}
return *Factory::NewJSArrayWithElements(copy); return *Factory::NewJSArrayWithElements(copy);
} }
...@@ -3587,27 +3599,7 @@ static Object* Runtime_NumberToString(Arguments args) { ...@@ -3587,27 +3599,7 @@ static Object* Runtime_NumberToString(Arguments args) {
Object* number = args[0]; Object* number = args[0];
RUNTIME_ASSERT(number->IsNumber()); RUNTIME_ASSERT(number->IsNumber());
Object* cached = Heap::GetNumberStringCache(number); return Heap::NumberToString(number);
if (cached != Heap::undefined_value()) {
return cached;
}
char arr[100];
Vector<char> buffer(arr, ARRAY_SIZE(arr));
const char* str;
if (number->IsSmi()) {
int num = Smi::cast(number)->value();
str = IntToCString(num, buffer);
} else {
double num = HeapNumber::cast(number)->value();
str = DoubleToCString(num, buffer);
}
Object* result = Heap::AllocateStringFromAscii(CStrVector(str));
if (!result->IsFailure()) {
Heap::SetNumberStringCache(number, String::cast(result));
}
return result;
} }
......
...@@ -51,6 +51,8 @@ x.__proto__ = [1, 2, 3]; ...@@ -51,6 +51,8 @@ x.__proto__ = [1, 2, 3];
assertEquals(Object.keys(x), []); assertEquals(Object.keys(x), []);
assertEquals(Object.keys(function () {}), []); assertEquals(Object.keys(function () {}), []);
assertEquals('string', typeof(Object.keys([1])[0]));
function argsTest(a, b, c) { function argsTest(a, b, c) {
assertEquals([0, 1, 2], Object.keys(arguments)); assertEquals([0, 1, 2], Object.keys(arguments));
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment