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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/builtins.h ('k') | src/execution.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/builtins.cc
diff --git a/src/builtins.cc b/src/builtins.cc
index c68de9ac794adc7b37fa23530fc822ca5bf70d8e..e8e7109d19d9610eac690e268503291bc1f2a989 100644
--- a/src/builtins.cc
+++ b/src/builtins.cc
@@ -419,6 +419,110 @@ BUILTIN(ArrayUnshift) {
}
+static Object* SlowArraySlice(Handle<Object> receiver,
+ Object** arg0,
+ Object** arg1 = NULL) {
+ HandleScope handleScope;
+
+ Handle<Object> slow_slice =
+ GetProperty(Handle<JSObject>(Top::global_context()->builtins()),
+ "ArraySlice");
+ ASSERT(slow_slice->IsJSFunction());
+ Handle<JSFunction> function(Handle<JSFunction>::cast(slow_slice));
+ Object** args[] = { arg0, arg1 };
+ bool pending_exception = false;
+ Handle<Object> result = Execution::Call(function,
+ receiver,
+ arg1 == NULL ? 1 : 2,
+ args,
+ &pending_exception);
+ if (pending_exception) return Failure::Exception();
+ return *result;
+}
+
+
+BUILTIN(ArraySlice) {
+ JSArray* array = JSArray::cast(*args.receiver());
+ ASSERT(array->HasFastElements());
+
+ int len = Smi::cast(array->length())->value();
+
+ int n_arguments = args.length() - 1;
+
+ // Note carefully choosen defaults---if argument is missing,
+ // it's undefined which gets converted to 0 for relativeStart
+ // and to len for relativeEnd.
+ int relativeStart = 0;
+ int relativeEnd = len;
+ if (n_arguments > 0) {
+ Object* arg1 = args[1];
+ if (arg1->IsSmi()) {
+ relativeStart = Smi::cast(arg1)->value();
+ } else if (!arg1->IsUndefined()) {
+ if (n_arguments > 1) {
+ return SlowArraySlice(args.receiver(), &args[1], &args[2]);
+ } else {
+ return SlowArraySlice(args.receiver(), &args[1]);
+ }
+ }
+ if (n_arguments > 1) {
+ Object* arg2 = args[2];
+ if (arg2->IsSmi()) {
+ relativeEnd = Smi::cast(arg2)->value();
+ } else if (!arg2->IsUndefined()) {
+ return SlowArraySlice(args.receiver(), &args[1], &args[2]);
+ }
+ }
+ }
+
+ // ECMAScript 232, 3rd Edition, Section 15.4.4.10, step 6.
+ int k = (relativeStart < 0) ? Max(len + relativeStart, 0)
+ : Min(relativeStart, len);
+
+ // ECMAScript 232, 3rd Edition, Section 15.4.4.10, step 8.
+ int final = (relativeEnd < 0) ? Max(len + relativeEnd, 0)
+ : Min(relativeEnd, len);
+
+ // Calculate the length of result array.
+ int result_len = final - k;
+ if (result_len < 0) {
+ result_len = 0;
+ }
+
+ JSFunction* array_function =
+ Top::context()->global_context()->array_function();
+ Object* result = Heap::AllocateJSObject(array_function);
+ if (result->IsFailure()) return result;
+ JSArray* result_array = JSArray::cast(result);
+
+ result = Heap::AllocateFixedArrayWithHoles(result_len);
+ if (result->IsFailure()) return result;
+ FixedArray* result_elms = FixedArray::cast(result);
+
+ FixedArray* elms = FixedArray::cast(array->elements());
+
+ // Fetch the prototype.
+ JSObject* prototype = JSObject::cast(array_function->prototype());
+
+ AssertNoAllocation no_gc;
+ WriteBarrierMode mode = result_elms->GetWriteBarrierMode(no_gc);
+
+ // Fill newly created array.
+ for (int i = 0; i < result_len; i++) {
+ result_elms->set(i,
+ GetElementToMove(k + i, elms, prototype),
+ mode);
+ }
+
+ // Set elements.
+ result_array->set_elements(result_elms);
+
+ // Set the length.
+ result_array->set_length(Smi::FromInt(result_len));
+ return result_array;
+}
+
+
// -----------------------------------------------------------------------------
//
« 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