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 401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
412 for (int i = 0; i < to_add; i++) { | 412 for (int i = 0; i < to_add; i++) { |
413 elms->set(i, args[i + 1], mode); | 413 elms->set(i, args[i + 1], mode); |
414 } | 414 } |
415 | 415 |
416 // Set the length. | 416 // Set the length. |
417 array->set_length(Smi::FromInt(new_length)); | 417 array->set_length(Smi::FromInt(new_length)); |
418 return Smi::FromInt(new_length); | 418 return Smi::FromInt(new_length); |
419 } | 419 } |
420 | 420 |
421 | 421 |
| 422 static Object* SlowArraySlice(Handle<Object> receiver, |
| 423 Object** arg0, |
| 424 Object** arg1 = NULL) { |
| 425 HandleScope handleScope; |
| 426 |
| 427 Handle<Object> slow_slice = |
| 428 GetProperty(Handle<JSObject>(Top::global_context()->builtins()), |
| 429 "ArraySlice"); |
| 430 ASSERT(slow_slice->IsJSFunction()); |
| 431 Handle<JSFunction> function(Handle<JSFunction>::cast(slow_slice)); |
| 432 Object** args[] = { arg0, arg1 }; |
| 433 bool pending_exception = false; |
| 434 Handle<Object> result = Execution::Call(function, |
| 435 receiver, |
| 436 arg1 == NULL ? 1 : 2, |
| 437 args, |
| 438 &pending_exception); |
| 439 if (pending_exception) return Failure::Exception(); |
| 440 return *result; |
| 441 } |
| 442 |
| 443 |
| 444 BUILTIN(ArraySlice) { |
| 445 JSArray* array = JSArray::cast(*args.receiver()); |
| 446 ASSERT(array->HasFastElements()); |
| 447 |
| 448 int len = Smi::cast(array->length())->value(); |
| 449 |
| 450 int n_arguments = args.length() - 1; |
| 451 |
| 452 // Note carefully choosen defaults---if argument is missing, |
| 453 // it's undefined which gets converted to 0 for relativeStart |
| 454 // and to len for relativeEnd. |
| 455 int relativeStart = 0; |
| 456 int relativeEnd = len; |
| 457 if (n_arguments > 0) { |
| 458 Object* arg1 = args[1]; |
| 459 if (arg1->IsSmi()) { |
| 460 relativeStart = Smi::cast(arg1)->value(); |
| 461 } else if (!arg1->IsUndefined()) { |
| 462 if (n_arguments > 1) { |
| 463 return SlowArraySlice(args.receiver(), &args[1], &args[2]); |
| 464 } else { |
| 465 return SlowArraySlice(args.receiver(), &args[1]); |
| 466 } |
| 467 } |
| 468 if (n_arguments > 1) { |
| 469 Object* arg2 = args[2]; |
| 470 if (arg2->IsSmi()) { |
| 471 relativeEnd = Smi::cast(arg2)->value(); |
| 472 } else if (!arg2->IsUndefined()) { |
| 473 return SlowArraySlice(args.receiver(), &args[1], &args[2]); |
| 474 } |
| 475 } |
| 476 } |
| 477 |
| 478 // ECMAScript 232, 3rd Edition, Section 15.4.4.10, step 6. |
| 479 int k = (relativeStart < 0) ? Max(len + relativeStart, 0) |
| 480 : Min(relativeStart, len); |
| 481 |
| 482 // ECMAScript 232, 3rd Edition, Section 15.4.4.10, step 8. |
| 483 int final = (relativeEnd < 0) ? Max(len + relativeEnd, 0) |
| 484 : Min(relativeEnd, len); |
| 485 |
| 486 // Calculate the length of result array. |
| 487 int result_len = final - k; |
| 488 if (result_len < 0) { |
| 489 result_len = 0; |
| 490 } |
| 491 |
| 492 JSFunction* array_function = |
| 493 Top::context()->global_context()->array_function(); |
| 494 Object* result = Heap::AllocateJSObject(array_function); |
| 495 if (result->IsFailure()) return result; |
| 496 JSArray* result_array = JSArray::cast(result); |
| 497 |
| 498 result = Heap::AllocateFixedArrayWithHoles(result_len); |
| 499 if (result->IsFailure()) return result; |
| 500 FixedArray* result_elms = FixedArray::cast(result); |
| 501 |
| 502 FixedArray* elms = FixedArray::cast(array->elements()); |
| 503 |
| 504 // Fetch the prototype. |
| 505 JSObject* prototype = JSObject::cast(array_function->prototype()); |
| 506 |
| 507 AssertNoAllocation no_gc; |
| 508 WriteBarrierMode mode = result_elms->GetWriteBarrierMode(no_gc); |
| 509 |
| 510 // Fill newly created array. |
| 511 for (int i = 0; i < result_len; i++) { |
| 512 result_elms->set(i, |
| 513 GetElementToMove(k + i, elms, prototype), |
| 514 mode); |
| 515 } |
| 516 |
| 517 // Set elements. |
| 518 result_array->set_elements(result_elms); |
| 519 |
| 520 // Set the length. |
| 521 result_array->set_length(Smi::FromInt(result_len)); |
| 522 return result_array; |
| 523 } |
| 524 |
| 525 |
422 // ----------------------------------------------------------------------------- | 526 // ----------------------------------------------------------------------------- |
423 // | 527 // |
424 | 528 |
425 | 529 |
426 // Returns the holder JSObject if the function can legally be called | 530 // Returns the holder JSObject if the function can legally be called |
427 // with this receiver. Returns Heap::null_value() if the call is | 531 // with this receiver. Returns Heap::null_value() if the call is |
428 // illegal. Any arguments that don't fit the expected type is | 532 // illegal. Any arguments that don't fit the expected type is |
429 // overwritten with undefined. Arguments that do fit the expected | 533 // overwritten with undefined. Arguments that do fit the expected |
430 // type is overwritten with the object in the prototype chain that | 534 // type is overwritten with the object in the prototype chain that |
431 // actually has that type. | 535 // actually has that type. |
(...skipping 626 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1058 if (entry->contains(pc)) { | 1162 if (entry->contains(pc)) { |
1059 return names_[i]; | 1163 return names_[i]; |
1060 } | 1164 } |
1061 } | 1165 } |
1062 } | 1166 } |
1063 return NULL; | 1167 return NULL; |
1064 } | 1168 } |
1065 | 1169 |
1066 | 1170 |
1067 } } // namespace v8::internal | 1171 } } // namespace v8::internal |
OLD | NEW |