| OLD | NEW |
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 239 array->set_length(len); | 239 array->set_length(len); |
| 240 | 240 |
| 241 return array; | 241 return array; |
| 242 } | 242 } |
| 243 | 243 |
| 244 | 244 |
| 245 BUILTIN(ArrayPush) { | 245 BUILTIN(ArrayPush) { |
| 246 JSArray* array = JSArray::cast(*args.receiver()); | 246 JSArray* array = JSArray::cast(*args.receiver()); |
| 247 ASSERT(array->HasFastElements()); | 247 ASSERT(array->HasFastElements()); |
| 248 | 248 |
| 249 // Make sure we have space for the elements. | |
| 250 int len = Smi::cast(array->length())->value(); | 249 int len = Smi::cast(array->length())->value(); |
| 250 int to_add = args.length() - 1; |
| 251 if (to_add == 0) { |
| 252 return Smi::FromInt(len); |
| 253 } |
| 251 | 254 |
| 252 // Set new length. | 255 int new_length = len + to_add; |
| 253 int new_length = len + args.length() - 1; | |
| 254 FixedArray* elms = FixedArray::cast(array->elements()); | 256 FixedArray* elms = FixedArray::cast(array->elements()); |
| 255 | 257 |
| 256 if (new_length <= elms->length()) { | 258 if (new_length > elms->length()) { |
| 257 // Backing storage has extra space for the provided values. | |
| 258 for (int index = 0; index < args.length() - 1; index++) { | |
| 259 elms->set(index + len, args[index+1]); | |
| 260 } | |
| 261 } else { | |
| 262 // New backing storage is needed. | 259 // New backing storage is needed. |
| 263 int capacity = new_length + (new_length >> 1) + 16; | 260 int capacity = new_length + (new_length >> 1) + 16; |
| 264 Object* obj = Heap::AllocateFixedArrayWithHoles(capacity); | 261 Object* obj = Heap::AllocateFixedArrayWithHoles(capacity); |
| 265 if (obj->IsFailure()) return obj; | 262 if (obj->IsFailure()) return obj; |
| 266 | 263 |
| 267 AssertNoAllocation no_gc; | 264 AssertNoAllocation no_gc; |
| 268 FixedArray* new_elms = FixedArray::cast(obj); | 265 FixedArray* new_elms = FixedArray::cast(obj); |
| 269 WriteBarrierMode mode = new_elms->GetWriteBarrierMode(no_gc); | 266 WriteBarrierMode mode = new_elms->GetWriteBarrierMode(no_gc); |
| 270 // Fill out the new array with old elements. | 267 // Fill out the new array with old elements. |
| 271 for (int i = 0; i < len; i++) new_elms->set(i, elms->get(i), mode); | 268 for (int i = 0; i < len; i++) new_elms->set(i, elms->get(i), mode); |
| 272 // Add the provided values. | 269 elms = new_elms; |
| 273 for (int index = 0; index < args.length() - 1; index++) { | 270 array->set_elements(elms); |
| 274 new_elms->set(index + len, args[index+1], mode); | |
| 275 } | |
| 276 // Set the new backing storage. | |
| 277 array->set_elements(new_elms); | |
| 278 } | 271 } |
| 272 |
| 273 AssertNoAllocation no_gc; |
| 274 WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc); |
| 275 |
| 276 // Add the provided values. |
| 277 for (int index = 0; index < to_add; index++) { |
| 278 elms->set(index + len, args[index + 1], mode); |
| 279 } |
| 280 |
| 279 // Set the length. | 281 // Set the length. |
| 280 array->set_length(Smi::FromInt(new_length)); | 282 array->set_length(Smi::FromInt(new_length)); |
| 281 return array->length(); | 283 return Smi::FromInt(new_length); |
| 282 } | 284 } |
| 283 | 285 |
| 284 | 286 |
| 285 BUILTIN(ArrayPop) { | 287 BUILTIN(ArrayPop) { |
| 286 JSArray* array = JSArray::cast(*args.receiver()); | 288 JSArray* array = JSArray::cast(*args.receiver()); |
| 287 ASSERT(array->HasFastElements()); | 289 ASSERT(array->HasFastElements()); |
| 288 Object* undefined = Heap::undefined_value(); | 290 Object* undefined = Heap::undefined_value(); |
| 289 | 291 |
| 290 int len = Smi::cast(array->length())->value(); | 292 int len = Smi::cast(array->length())->value(); |
| 291 if (len == 0) return undefined; | 293 if (len == 0) return undefined; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 306 // Remember to check the prototype chain. | 308 // Remember to check the prototype chain. |
| 307 JSFunction* array_function = | 309 JSFunction* array_function = |
| 308 Top::context()->global_context()->array_function(); | 310 Top::context()->global_context()->array_function(); |
| 309 JSObject* prototype = JSObject::cast(array_function->prototype()); | 311 JSObject* prototype = JSObject::cast(array_function->prototype()); |
| 310 top = prototype->GetElement(len - 1); | 312 top = prototype->GetElement(len - 1); |
| 311 | 313 |
| 312 return top; | 314 return top; |
| 313 } | 315 } |
| 314 | 316 |
| 315 | 317 |
| 318 static Object* GetElementToMove(uint32_t index, |
| 319 FixedArray* elms, |
| 320 JSObject* prototype) { |
| 321 Object* e = elms->get(index); |
| 322 if (e->IsTheHole() && prototype->HasElement(index)) { |
| 323 e = prototype->GetElement(index); |
| 324 } |
| 325 return e; |
| 326 } |
| 327 |
| 328 |
| 316 BUILTIN(ArrayShift) { | 329 BUILTIN(ArrayShift) { |
| 317 JSArray* array = JSArray::cast(*args.receiver()); | 330 JSArray* array = JSArray::cast(*args.receiver()); |
| 318 ASSERT(array->HasFastElements()); | 331 ASSERT(array->HasFastElements()); |
| 319 | 332 |
| 320 int len = Smi::cast(array->length())->value(); | 333 int len = Smi::cast(array->length())->value(); |
| 321 if (len == 0) return Heap::undefined_value(); | 334 if (len == 0) return Heap::undefined_value(); |
| 322 | 335 |
| 323 // Fetch the prototype. | 336 // Fetch the prototype. |
| 324 JSFunction* array_function = | 337 JSFunction* array_function = |
| 325 Top::context()->global_context()->array_function(); | 338 Top::context()->global_context()->array_function(); |
| 326 JSObject* prototype = JSObject::cast(array_function->prototype()); | 339 JSObject* prototype = JSObject::cast(array_function->prototype()); |
| 327 | 340 |
| 341 FixedArray* elms = FixedArray::cast(array->elements()); |
| 342 |
| 328 // Get first element | 343 // Get first element |
| 329 FixedArray* elms = FixedArray::cast(array->elements()); | |
| 330 Object* first = elms->get(0); | 344 Object* first = elms->get(0); |
| 331 | |
| 332 if (first->IsTheHole()) { | 345 if (first->IsTheHole()) { |
| 333 first = prototype->GetElement(0); | 346 first = prototype->GetElement(0); |
| 334 } | 347 } |
| 335 | 348 |
| 336 // Shift the elements. | 349 // Shift the elements. |
| 337 for (int i = 0; i < len - 1; i++) { | 350 for (int i = 0; i < len - 1; i++) { |
| 338 Object* e = elms->get(i + 1); | 351 elms->set(i, GetElementToMove(i + 1, elms, prototype)); |
| 339 if (e->IsTheHole() && prototype->HasElement(i + 1)) { | |
| 340 e = prototype->GetElement(i + 1); | |
| 341 } | |
| 342 elms->set(i, e); | |
| 343 } | 352 } |
| 344 elms->set(len - 1, Heap::the_hole_value()); | 353 elms->set(len - 1, Heap::the_hole_value()); |
| 345 | 354 |
| 346 // Set the length. | 355 // Set the length. |
| 347 array->set_length(Smi::FromInt(len - 1)); | 356 array->set_length(Smi::FromInt(len - 1)); |
| 348 | 357 |
| 349 return first; | 358 return first; |
| 350 } | 359 } |
| 351 | 360 |
| 352 | 361 |
| 362 BUILTIN(ArrayUnshift) { |
| 363 JSArray* array = JSArray::cast(*args.receiver()); |
| 364 ASSERT(array->HasFastElements()); |
| 365 |
| 366 int len = Smi::cast(array->length())->value(); |
| 367 int to_add = args.length() - 1; |
| 368 // Note that we cannot quit early if to_add == 0 as |
| 369 // values should be lifted from prototype into |
| 370 // the array. |
| 371 |
| 372 int new_length = len + to_add; |
| 373 FixedArray* elms = FixedArray::cast(array->elements()); |
| 374 |
| 375 // Fetch the prototype. |
| 376 JSFunction* array_function = |
| 377 Top::context()->global_context()->array_function(); |
| 378 JSObject* prototype = JSObject::cast(array_function->prototype()); |
| 379 |
| 380 if (new_length > elms->length()) { |
| 381 // New backing storage is needed. |
| 382 int capacity = new_length + (new_length >> 1) + 16; |
| 383 Object* obj = Heap::AllocateFixedArrayWithHoles(capacity); |
| 384 if (obj->IsFailure()) return obj; |
| 385 |
| 386 AssertNoAllocation no_gc; |
| 387 FixedArray* new_elms = FixedArray::cast(obj); |
| 388 WriteBarrierMode mode = new_elms->GetWriteBarrierMode(no_gc); |
| 389 // Fill out the new array with old elements. |
| 390 for (int i = 0; i < len; i++) |
| 391 new_elms->set(to_add + i, |
| 392 GetElementToMove(i, elms, prototype), |
| 393 mode); |
| 394 |
| 395 elms = new_elms; |
| 396 array->set_elements(elms); |
| 397 } else { |
| 398 AssertNoAllocation no_gc; |
| 399 WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc); |
| 400 |
| 401 // Move elements to the right |
| 402 for (int i = 0; i < len; i++) { |
| 403 elms->set(new_length - i - 1, |
| 404 GetElementToMove(len - i - 1, elms, prototype), |
| 405 mode); |
| 406 } |
| 407 } |
| 408 |
| 409 // Add the provided values. |
| 410 AssertNoAllocation no_gc; |
| 411 WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc); |
| 412 for (int i = 0; i < to_add; i++) { |
| 413 elms->set(i, args[i + 1], mode); |
| 414 } |
| 415 |
| 416 // Set the length. |
| 417 array->set_length(Smi::FromInt(new_length)); |
| 418 return Smi::FromInt(new_length); |
| 419 } |
| 420 |
| 421 |
| 353 // ----------------------------------------------------------------------------- | 422 // ----------------------------------------------------------------------------- |
| 354 // | 423 // |
| 355 | 424 |
| 356 | 425 |
| 357 // Returns the holder JSObject if the function can legally be called | 426 // Returns the holder JSObject if the function can legally be called |
| 358 // with this receiver. Returns Heap::null_value() if the call is | 427 // with this receiver. Returns Heap::null_value() if the call is |
| 359 // illegal. Any arguments that don't fit the expected type is | 428 // illegal. Any arguments that don't fit the expected type is |
| 360 // overwritten with undefined. Arguments that do fit the expected | 429 // overwritten with undefined. Arguments that do fit the expected |
| 361 // type is overwritten with the object in the prototype chain that | 430 // type is overwritten with the object in the prototype chain that |
| 362 // actually has that type. | 431 // actually has that type. |
| (...skipping 626 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 989 if (entry->contains(pc)) { | 1058 if (entry->contains(pc)) { |
| 990 return names_[i]; | 1059 return names_[i]; |
| 991 } | 1060 } |
| 992 } | 1061 } |
| 993 } | 1062 } |
| 994 return NULL; | 1063 return NULL; |
| 995 } | 1064 } |
| 996 | 1065 |
| 997 | 1066 |
| 998 } } // namespace v8::internal | 1067 } } // namespace v8::internal |
| OLD | NEW |