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

Side by Side Diff: src/builtins.cc

Issue 604059: Introduce builtin for Array.slice function. (Closed)
Patch Set: Next round Created 10 years, 10 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/builtins.h ('k') | src/execution.cc » ('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-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
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
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
OLDNEW
« no previous file with comments | « src/builtins.h ('k') | src/execution.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698