Chromium Code Reviews| Index: src/elements.cc |
| diff --git a/src/elements.cc b/src/elements.cc |
| index 0d4e2cb76fcbb956ba81f45ca6f5e5e0549b6551..20a9ceaf52a303d4b04a45935696c54851e1259c 100644 |
| --- a/src/elements.cc |
| +++ b/src/elements.cc |
| @@ -1680,7 +1680,52 @@ class SloppyArgumentsElementsAccessor : public ElementsAccessorBase< |
| FixedArrayBase* to, ElementsKind from_kind, |
| uint32_t to_start, int packed_size, |
| int copy_size) { |
| - UNREACHABLE(); |
| + DCHECK_LE(0, copy_size); |
| + if (copy_size == 0) return; |
| + Isolate* isolate = from->GetIsolate(); |
| + FixedArray* parameter_map = FixedArray::cast(from); |
| + FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
| + // Since we may need to call back into JS if arguments is a dictionary, |
| + // disallow copying it here. |
| + DCHECK(!arguments->IsDictionary()); |
| + Context* context = Context::cast(parameter_map->get(0)); |
| + Object* the_hole = isolate->heap()->the_hole_value(); |
| + |
| + int max_copy_size = to->length() - to_start; |
| + // Limit up to which we copy. |
| + int copy_length = Min(max_copy_size, copy_size) + from_start; |
| + // Portion of this limit that are mapped. |
| + int mapped = Min(copy_length, parameter_map->length() - 2); |
| + // Portion of the limit that is unmapped. |
| + int actual = Min(copy_length, arguments->length()); |
| + |
| + // Copy arguments that may be mapped. |
| + int limit = mapped - from_start; |
| + int i; |
| + for (i = 0; i < limit; i++) { |
| + Object* probe = parameter_map->get(from_start + 2 + i); |
| + Object* value; |
| + if (probe->IsTheHole()) { |
| + value = arguments->get(from_start + i); |
| + } else { |
| + int context_index = Smi::cast(probe)->value(); |
| + DCHECK(!context->get(context_index)->IsTheHole()); |
| + value = context->get(context_index); |
| + } |
| + FixedArray::cast(to)->set(to_start + i, value); |
|
Igor Sheludko
2015/01/30 14:13:29
I would suggest to move casts to FixedArray out of
|
| + } |
| + |
| + // Copy unmapped actual arguments. |
| + limit = actual - from_start; |
| + for (; i < limit; i++) { |
| + Object* value = arguments->get(from_start + i); |
| + FixedArray::cast(to)->set(to_start + i, value); |
| + } |
| + |
| + // Fill holes for "arguments" beyond the length of the actual arguments. |
| + for (i += to_start; i < to->length(); i++) { |
| + FixedArray::cast(to)->set(i, the_hole); |
| + } |
| } |
| static uint32_t GetCapacityImpl(Handle<FixedArrayBase> backing_store) { |