Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Side by Side Diff: src/runtime.cc

Issue 542092: Submit Object.getOwnPropertyNames patch by Pavel Feldman. See http://codereview.chromium.org/549050. (Closed)
Patch Set: Created 10 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/runtime.h ('k') | src/v8natives.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-2009 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 3195 matching lines...) Expand 10 before | Expand all | Expand 10 after
3206 Handle<FixedArray> content = GetKeysInFixedArrayFor(object, 3206 Handle<FixedArray> content = GetKeysInFixedArrayFor(object,
3207 INCLUDE_PROTOS); 3207 INCLUDE_PROTOS);
3208 3208
3209 // Test again, since cache may have been built by preceding call. 3209 // Test again, since cache may have been built by preceding call.
3210 if (object->IsSimpleEnum()) return object->map(); 3210 if (object->IsSimpleEnum()) return object->map();
3211 3211
3212 return *content; 3212 return *content;
3213 } 3213 }
3214 3214
3215 3215
3216 // Find the length of the prototype chain that is to to handled as one. If a
3217 // prototype object is hidden it is to be viewed as part of the the object it
3218 // is prototype for.
3219 static int LocalPrototypeChainLength(JSObject* obj) {
3220 int count = 1;
3221 Object* proto = obj->GetPrototype();
3222 while (proto->IsJSObject() &&
3223 JSObject::cast(proto)->map()->is_hidden_prototype()) {
3224 count++;
3225 proto = JSObject::cast(proto)->GetPrototype();
3226 }
3227 return count;
3228 }
3229
3230
3231 // Return the names of the local named properties.
3232 // args[0]: object
3233 static Object* Runtime_GetLocalPropertyNames(Arguments args) {
3234 HandleScope scope;
3235 ASSERT(args.length() == 1);
3236 if (!args[0]->IsJSObject()) {
3237 return Heap::undefined_value();
3238 }
3239 CONVERT_ARG_CHECKED(JSObject, obj, 0);
3240
3241 // Skip the global proxy as it has no properties and always delegates to the
3242 // real global object.
3243 if (obj->IsJSGlobalProxy()) {
3244 obj = Handle<JSObject>(JSObject::cast(obj->GetPrototype()));
3245 }
3246
3247 // Find the number of objects making up this.
3248 int length = LocalPrototypeChainLength(*obj);
3249
3250 // Find the number of local properties for each of the objects.
3251 int* local_property_count = NewArray<int>(length);
3252 int total_property_count = 0;
3253 Handle<JSObject> jsproto = obj;
3254 for (int i = 0; i < length; i++) {
3255 int n;
3256 n = jsproto->NumberOfLocalProperties(static_cast<PropertyAttributes>(NONE));
3257 local_property_count[i] = n;
3258 total_property_count += n;
3259 if (i < length - 1) {
3260 jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype()));
3261 }
3262 }
3263
3264 // Allocate an array with storage for all the property names.
3265 Handle<FixedArray> names = Factory::NewFixedArray(total_property_count);
3266
3267 // Get the property names.
3268 jsproto = obj;
3269 int proto_with_hidden_properties = 0;
3270 for (int i = 0; i < length; i++) {
3271 jsproto->GetLocalPropertyNames(*names,
3272 i == 0 ? 0 : local_property_count[i - 1]);
3273 if (!GetHiddenProperties(jsproto, false)->IsUndefined()) {
3274 proto_with_hidden_properties++;
3275 }
3276 if (i < length - 1) {
3277 jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype()));
3278 }
3279 }
3280
3281 // Filter out name of hidden propeties object.
3282 if (proto_with_hidden_properties > 0) {
3283 Handle<FixedArray> old_names = names;
3284 names = Factory::NewFixedArray(
3285 names->length() - proto_with_hidden_properties);
3286 int dest_pos = 0;
3287 for (int i = 0; i < total_property_count; i++) {
3288 Object* name = old_names->get(i);
3289 if (name == Heap::hidden_symbol()) {
3290 continue;
3291 }
3292 names->set(dest_pos++, name);
3293 }
3294 }
3295
3296 DeleteArray(local_property_count);
3297 return *Factory::NewJSArrayWithElements(names);
3298 }
3299
3300
3301 // Return the names of the local indexed properties.
3302 // args[0]: object
3303 static Object* Runtime_GetLocalElementNames(Arguments args) {
3304 HandleScope scope;
3305 ASSERT(args.length() == 1);
3306 if (!args[0]->IsJSObject()) {
3307 return Heap::undefined_value();
3308 }
3309 CONVERT_ARG_CHECKED(JSObject, obj, 0);
3310
3311 int n = obj->NumberOfLocalElements(static_cast<PropertyAttributes>(NONE));
3312 Handle<FixedArray> names = Factory::NewFixedArray(n);
3313 obj->GetLocalElementKeys(*names, static_cast<PropertyAttributes>(NONE));
3314 return *Factory::NewJSArrayWithElements(names);
3315 }
3316
3317
3318 // Return information on whether an object has a named or indexed interceptor.
3319 // args[0]: object
3320 static Object* Runtime_GetInterceptorInfo(Arguments args) {
3321 HandleScope scope;
3322 ASSERT(args.length() == 1);
3323 if (!args[0]->IsJSObject()) {
3324 return Smi::FromInt(0);
3325 }
3326 CONVERT_ARG_CHECKED(JSObject, obj, 0);
3327
3328 int result = 0;
3329 if (obj->HasNamedInterceptor()) result |= 2;
3330 if (obj->HasIndexedInterceptor()) result |= 1;
3331
3332 return Smi::FromInt(result);
3333 }
3334
3335
3336 // Return property names from named interceptor.
3337 // args[0]: object
3338 static Object* Runtime_GetNamedInterceptorPropertyNames(Arguments args) {
3339 HandleScope scope;
3340 ASSERT(args.length() == 1);
3341 CONVERT_ARG_CHECKED(JSObject, obj, 0);
3342
3343 if (obj->HasNamedInterceptor()) {
3344 v8::Handle<v8::Array> result = GetKeysForNamedInterceptor(obj, obj);
3345 if (!result.IsEmpty()) return *v8::Utils::OpenHandle(*result);
3346 }
3347 return Heap::undefined_value();
3348 }
3349
3350
3351 // Return element names from indexed interceptor.
3352 // args[0]: object
3353 static Object* Runtime_GetIndexedInterceptorElementNames(Arguments args) {
3354 HandleScope scope;
3355 ASSERT(args.length() == 1);
3356 CONVERT_ARG_CHECKED(JSObject, obj, 0);
3357
3358 if (obj->HasIndexedInterceptor()) {
3359 v8::Handle<v8::Array> result = GetKeysForIndexedInterceptor(obj, obj);
3360 if (!result.IsEmpty()) return *v8::Utils::OpenHandle(*result);
3361 }
3362 return Heap::undefined_value();
3363 }
3364
3365
3216 static Object* Runtime_LocalKeys(Arguments args) { 3366 static Object* Runtime_LocalKeys(Arguments args) {
3217 ASSERT_EQ(args.length(), 1); 3367 ASSERT_EQ(args.length(), 1);
3218 CONVERT_CHECKED(JSObject, raw_object, args[0]); 3368 CONVERT_CHECKED(JSObject, raw_object, args[0]);
3219 HandleScope scope; 3369 HandleScope scope;
3220 Handle<JSObject> object(raw_object); 3370 Handle<JSObject> object(raw_object);
3221 Handle<FixedArray> contents = GetKeysInFixedArrayFor(object, 3371 Handle<FixedArray> contents = GetKeysInFixedArrayFor(object,
3222 LOCAL_ONLY); 3372 LOCAL_ONLY);
3223 // Some fast paths through GetKeysInFixedArrayFor reuse a cached 3373 // Some fast paths through GetKeysInFixedArrayFor reuse a cached
3224 // property array and since the result is mutable we have to create 3374 // property array and since the result is mutable we have to create
3225 // a fresh clone on each invocation. 3375 // a fresh clone on each invocation.
(...skipping 2772 matching lines...) Expand 10 before | Expand all | Expand 10 after
5998 } 6148 }
5999 6149
6000 6150
6001 static Object* Runtime_Break(Arguments args) { 6151 static Object* Runtime_Break(Arguments args) {
6002 ASSERT(args.length() == 0); 6152 ASSERT(args.length() == 0);
6003 StackGuard::DebugBreak(); 6153 StackGuard::DebugBreak();
6004 return Heap::undefined_value(); 6154 return Heap::undefined_value();
6005 } 6155 }
6006 6156
6007 6157
6008 // Find the length of the prototype chain that is to to handled as one. If a
6009 // prototype object is hidden it is to be viewed as part of the the object it
6010 // is prototype for.
6011 static int LocalPrototypeChainLength(JSObject* obj) {
6012 int count = 1;
6013 Object* proto = obj->GetPrototype();
6014 while (proto->IsJSObject() &&
6015 JSObject::cast(proto)->map()->is_hidden_prototype()) {
6016 count++;
6017 proto = JSObject::cast(proto)->GetPrototype();
6018 }
6019 return count;
6020 }
6021
6022
6023 static Object* DebugLookupResultValue(Object* receiver, String* name, 6158 static Object* DebugLookupResultValue(Object* receiver, String* name,
6024 LookupResult* result, 6159 LookupResult* result,
6025 bool* caught_exception) { 6160 bool* caught_exception) {
6026 Object* value; 6161 Object* value;
6027 switch (result->type()) { 6162 switch (result->type()) {
6028 case NORMAL: 6163 case NORMAL:
6029 value = result->holder()->GetNormalizedProperty(result); 6164 value = result->holder()->GetNormalizedProperty(result);
6030 if (value->IsTheHole()) { 6165 if (value->IsTheHole()) {
6031 return Heap::undefined_value(); 6166 return Heap::undefined_value();
6032 } 6167 }
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
6182 6317
6183 LookupResult result; 6318 LookupResult result;
6184 obj->Lookup(*name, &result); 6319 obj->Lookup(*name, &result);
6185 if (result.IsProperty()) { 6320 if (result.IsProperty()) {
6186 return DebugLookupResultValue(*obj, *name, &result, NULL); 6321 return DebugLookupResultValue(*obj, *name, &result, NULL);
6187 } 6322 }
6188 return Heap::undefined_value(); 6323 return Heap::undefined_value();
6189 } 6324 }
6190 6325
6191 6326
6192 // Return the names of the local named properties.
6193 // args[0]: object
6194 static Object* Runtime_DebugLocalPropertyNames(Arguments args) {
6195 HandleScope scope;
6196 ASSERT(args.length() == 1);
6197 if (!args[0]->IsJSObject()) {
6198 return Heap::undefined_value();
6199 }
6200 CONVERT_ARG_CHECKED(JSObject, obj, 0);
6201
6202 // Skip the global proxy as it has no properties and always delegates to the
6203 // real global object.
6204 if (obj->IsJSGlobalProxy()) {
6205 obj = Handle<JSObject>(JSObject::cast(obj->GetPrototype()));
6206 }
6207
6208 // Find the number of objects making up this.
6209 int length = LocalPrototypeChainLength(*obj);
6210
6211 // Find the number of local properties for each of the objects.
6212 int* local_property_count = NewArray<int>(length);
6213 int total_property_count = 0;
6214 Handle<JSObject> jsproto = obj;
6215 for (int i = 0; i < length; i++) {
6216 int n;
6217 n = jsproto->NumberOfLocalProperties(static_cast<PropertyAttributes>(NONE));
6218 local_property_count[i] = n;
6219 total_property_count += n;
6220 if (i < length - 1) {
6221 jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype()));
6222 }
6223 }
6224
6225 // Allocate an array with storage for all the property names.
6226 Handle<FixedArray> names = Factory::NewFixedArray(total_property_count);
6227
6228 // Get the property names.
6229 jsproto = obj;
6230 int proto_with_hidden_properties = 0;
6231 for (int i = 0; i < length; i++) {
6232 jsproto->GetLocalPropertyNames(*names,
6233 i == 0 ? 0 : local_property_count[i - 1]);
6234 if (!GetHiddenProperties(jsproto, false)->IsUndefined()) {
6235 proto_with_hidden_properties++;
6236 }
6237 if (i < length - 1) {
6238 jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype()));
6239 }
6240 }
6241
6242 // Filter out name of hidden propeties object.
6243 if (proto_with_hidden_properties > 0) {
6244 Handle<FixedArray> old_names = names;
6245 names = Factory::NewFixedArray(
6246 names->length() - proto_with_hidden_properties);
6247 int dest_pos = 0;
6248 for (int i = 0; i < total_property_count; i++) {
6249 Object* name = old_names->get(i);
6250 if (name == Heap::hidden_symbol()) {
6251 continue;
6252 }
6253 names->set(dest_pos++, name);
6254 }
6255 }
6256
6257 DeleteArray(local_property_count);
6258 return *Factory::NewJSArrayWithElements(names);
6259 }
6260
6261
6262 // Return the names of the local indexed properties.
6263 // args[0]: object
6264 static Object* Runtime_DebugLocalElementNames(Arguments args) {
6265 HandleScope scope;
6266 ASSERT(args.length() == 1);
6267 if (!args[0]->IsJSObject()) {
6268 return Heap::undefined_value();
6269 }
6270 CONVERT_ARG_CHECKED(JSObject, obj, 0);
6271
6272 int n = obj->NumberOfLocalElements(static_cast<PropertyAttributes>(NONE));
6273 Handle<FixedArray> names = Factory::NewFixedArray(n);
6274 obj->GetLocalElementKeys(*names, static_cast<PropertyAttributes>(NONE));
6275 return *Factory::NewJSArrayWithElements(names);
6276 }
6277
6278
6279 // Return the property type calculated from the property details. 6327 // Return the property type calculated from the property details.
6280 // args[0]: smi with property details. 6328 // args[0]: smi with property details.
6281 static Object* Runtime_DebugPropertyTypeFromDetails(Arguments args) { 6329 static Object* Runtime_DebugPropertyTypeFromDetails(Arguments args) {
6282 ASSERT(args.length() == 1); 6330 ASSERT(args.length() == 1);
6283 CONVERT_CHECKED(Smi, details, args[0]); 6331 CONVERT_CHECKED(Smi, details, args[0]);
6284 PropertyType type = PropertyDetails(details).type(); 6332 PropertyType type = PropertyDetails(details).type();
6285 return Smi::FromInt(static_cast<int>(type)); 6333 return Smi::FromInt(static_cast<int>(type));
6286 } 6334 }
6287 6335
6288 6336
(...skipping 10 matching lines...) Expand all
6299 // Return the property insertion index calculated from the property details. 6347 // Return the property insertion index calculated from the property details.
6300 // args[0]: smi with property details. 6348 // args[0]: smi with property details.
6301 static Object* Runtime_DebugPropertyIndexFromDetails(Arguments args) { 6349 static Object* Runtime_DebugPropertyIndexFromDetails(Arguments args) {
6302 ASSERT(args.length() == 1); 6350 ASSERT(args.length() == 1);
6303 CONVERT_CHECKED(Smi, details, args[0]); 6351 CONVERT_CHECKED(Smi, details, args[0]);
6304 int index = PropertyDetails(details).index(); 6352 int index = PropertyDetails(details).index();
6305 return Smi::FromInt(index); 6353 return Smi::FromInt(index);
6306 } 6354 }
6307 6355
6308 6356
6309 // Return information on whether an object has a named or indexed interceptor.
6310 // args[0]: object
6311 static Object* Runtime_DebugInterceptorInfo(Arguments args) {
6312 HandleScope scope;
6313 ASSERT(args.length() == 1);
6314 if (!args[0]->IsJSObject()) {
6315 return Smi::FromInt(0);
6316 }
6317 CONVERT_ARG_CHECKED(JSObject, obj, 0);
6318
6319 int result = 0;
6320 if (obj->HasNamedInterceptor()) result |= 2;
6321 if (obj->HasIndexedInterceptor()) result |= 1;
6322
6323 return Smi::FromInt(result);
6324 }
6325
6326
6327 // Return property names from named interceptor.
6328 // args[0]: object
6329 static Object* Runtime_DebugNamedInterceptorPropertyNames(Arguments args) {
6330 HandleScope scope;
6331 ASSERT(args.length() == 1);
6332 CONVERT_ARG_CHECKED(JSObject, obj, 0);
6333
6334 if (obj->HasNamedInterceptor()) {
6335 v8::Handle<v8::Array> result = GetKeysForNamedInterceptor(obj, obj);
6336 if (!result.IsEmpty()) return *v8::Utils::OpenHandle(*result);
6337 }
6338 return Heap::undefined_value();
6339 }
6340
6341
6342 // Return element names from indexed interceptor.
6343 // args[0]: object
6344 static Object* Runtime_DebugIndexedInterceptorElementNames(Arguments args) {
6345 HandleScope scope;
6346 ASSERT(args.length() == 1);
6347 CONVERT_ARG_CHECKED(JSObject, obj, 0);
6348
6349 if (obj->HasIndexedInterceptor()) {
6350 v8::Handle<v8::Array> result = GetKeysForIndexedInterceptor(obj, obj);
6351 if (!result.IsEmpty()) return *v8::Utils::OpenHandle(*result);
6352 }
6353 return Heap::undefined_value();
6354 }
6355
6356
6357 // Return property value from named interceptor. 6357 // Return property value from named interceptor.
6358 // args[0]: object 6358 // args[0]: object
6359 // args[1]: property name 6359 // args[1]: property name
6360 static Object* Runtime_DebugNamedInterceptorPropertyValue(Arguments args) { 6360 static Object* Runtime_DebugNamedInterceptorPropertyValue(Arguments args) {
6361 HandleScope scope; 6361 HandleScope scope;
6362 ASSERT(args.length() == 2); 6362 ASSERT(args.length() == 2);
6363 CONVERT_ARG_CHECKED(JSObject, obj, 0); 6363 CONVERT_ARG_CHECKED(JSObject, obj, 0);
6364 RUNTIME_ASSERT(obj->HasNamedInterceptor()); 6364 RUNTIME_ASSERT(obj->HasNamedInterceptor());
6365 CONVERT_ARG_CHECKED(String, name, 1); 6365 CONVERT_ARG_CHECKED(String, name, 1);
6366 6366
(...skipping 1787 matching lines...) Expand 10 before | Expand all | Expand 10 after
8154 } else { 8154 } else {
8155 // Handle last resort GC and make sure to allow future allocations 8155 // Handle last resort GC and make sure to allow future allocations
8156 // to grow the heap without causing GCs (if possible). 8156 // to grow the heap without causing GCs (if possible).
8157 Counters::gc_last_resort_from_js.Increment(); 8157 Counters::gc_last_resort_from_js.Increment();
8158 Heap::CollectAllGarbage(false); 8158 Heap::CollectAllGarbage(false);
8159 } 8159 }
8160 } 8160 }
8161 8161
8162 8162
8163 } } // namespace v8::internal 8163 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/runtime.h ('k') | src/v8natives.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698