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

Side by Side Diff: src/runtime.cc

Issue 8836: Check that an index is in the range of 0 to array length in ArrayConcatVisito... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 12 years, 1 month 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | 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 3976 matching lines...) Expand 10 before | Expand all | Expand 10 after
3987 } 3987 }
3988 3988
3989 3989
3990 /** 3990 /**
3991 * A simple visitor visits every element of Array's. 3991 * A simple visitor visits every element of Array's.
3992 * The backend storage can be a fixed array for fast elements case, 3992 * The backend storage can be a fixed array for fast elements case,
3993 * or a dictionary for sparse array. Since Dictionary is a subtype 3993 * or a dictionary for sparse array. Since Dictionary is a subtype
3994 * of FixedArray, the class can be used by both fast and slow cases. 3994 * of FixedArray, the class can be used by both fast and slow cases.
3995 * The second parameter of the constructor, fast_elements, specifies 3995 * The second parameter of the constructor, fast_elements, specifies
3996 * whether the storage is a FixedArray or Dictionary. 3996 * whether the storage is a FixedArray or Dictionary.
3997 *
3998 * An index limit is used to deal with the situation that a result array
3999 * length overflows 32-bit non-negative integer.
3997 */ 4000 */
3998 class ArrayConcatVisitor { 4001 class ArrayConcatVisitor {
3999 public: 4002 public:
4000 ArrayConcatVisitor(Handle<FixedArray> storage, bool fast_elements) 4003 ArrayConcatVisitor(Handle<FixedArray> storage,
4001 : storage_(storage), fast_elements_(fast_elements), index_offset_(0) { } 4004 uint32_t index_limit,
4005 bool fast_elements) :
4006 storage_(storage), index_limit_(index_limit),
4007 fast_elements_(fast_elements), index_offset_(0) { }
4002 4008
4003 void visit(uint32_t i, Handle<Object> elm) { 4009 void visit(uint32_t i, Handle<Object> elm) {
4004 uint32_t index = i + index_offset_; 4010 uint32_t index = i + index_offset_;
4005 4011 if (index >= index_limit_) return;
4012
4006 if (fast_elements_) { 4013 if (fast_elements_) {
4007 ASSERT(index < static_cast<uint32_t>(storage_->length())); 4014 ASSERT(index < static_cast<uint32_t>(storage_->length()));
4008 storage_->set(index, *elm); 4015 storage_->set(index, *elm);
4009 4016
4010 } else { 4017 } else {
4011 Handle<Dictionary> dict = Handle<Dictionary>::cast(storage_); 4018 Handle<Dictionary> dict = Handle<Dictionary>::cast(storage_);
4012 Handle<Dictionary> result = 4019 Handle<Dictionary> result =
4013 Factory::DictionaryAtNumberPut(dict, index, elm); 4020 Factory::DictionaryAtNumberPut(dict, index, elm);
4014 if (!result.is_identical_to(dict)) 4021 if (!result.is_identical_to(dict))
4015 storage_ = result; 4022 storage_ = result;
4016 } 4023 }
4017 } 4024 }
4018 4025
4019 void increase_index_offset(uint32_t delta) { 4026 void increase_index_offset(uint32_t delta) {
4020 index_offset_ += delta; 4027 index_offset_ += delta;
4021 } 4028 }
4022 4029
4023 private: 4030 private:
4024 Handle<FixedArray> storage_; 4031 Handle<FixedArray> storage_;
4032 uint32_t index_limit_;
4025 bool fast_elements_; 4033 bool fast_elements_;
4026 uint32_t index_offset_; 4034 uint32_t index_offset_;
4027 }; 4035 };
4028 4036
4029 4037
4030 /** 4038 /**
4031 * A helper function that visits elements of a JSObject. Only elements 4039 * A helper function that visits elements of a JSObject. Only elements
4032 * whose index between 0 and range (exclusive) are visited. 4040 * whose index between 0 and range (exclusive) are visited.
4033 * 4041 *
4034 * If the third parameter, visitor, is not NULL, the visitor is called 4042 * If the third parameter, visitor, is not NULL, the visitor is called
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
4119 4127
4120 /** 4128 /**
4121 * A helper function of Runtime_ArrayConcat. 4129 * A helper function of Runtime_ArrayConcat.
4122 * 4130 *
4123 * The first argument is an Array of Arrays and objects. It is the same as 4131 * The first argument is an Array of Arrays and objects. It is the same as
4124 * the arguments array of Array::concat JS function. 4132 * the arguments array of Array::concat JS function.
4125 * 4133 *
4126 * If an argument is an Array object, the function visits array elements. 4134 * If an argument is an Array object, the function visits array elements.
4127 * If an argument is not an Array object, the function visits the object 4135 * If an argument is not an Array object, the function visits the object
4128 * as if it is an one-element array. 4136 * as if it is an one-element array.
4137 *
4138 * If the result array index overflows 32-bit integer, the rounded non-negative
4139 * number is used as new length. For example, if one array length is 2^32 - 1,
4140 * second array length is 1, the concatenated array length is 0.
4129 */ 4141 */
4130 static uint32_t IterateArguments(Handle<JSArray> arguments, 4142 static uint32_t IterateArguments(Handle<JSArray> arguments,
4131 ArrayConcatVisitor* visitor) { 4143 ArrayConcatVisitor* visitor) {
4132 uint32_t visited_elements = 0; 4144 uint32_t visited_elements = 0;
4133 uint32_t num_of_args = static_cast<uint32_t>(arguments->length()->Number()); 4145 uint32_t num_of_args = static_cast<uint32_t>(arguments->length()->Number());
4134 4146
4135 for (uint32_t i = 0; i < num_of_args; i++) { 4147 for (uint32_t i = 0; i < num_of_args; i++) {
4136 Handle<Object> obj(arguments->GetElement(i)); 4148 Handle<Object> obj(arguments->GetElement(i));
4137 if (obj->IsJSArray()) { 4149 if (obj->IsJSArray()) {
4138 Handle<JSArray> array = Handle<JSArray>::cast(obj); 4150 Handle<JSArray> array = Handle<JSArray>::cast(obj);
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
4200 } else { 4212 } else {
4201 // TODO(126): move 25% pre-allocation logic into Dictionary::Allocate 4213 // TODO(126): move 25% pre-allocation logic into Dictionary::Allocate
4202 uint32_t at_least_space_for = estimate_nof_elements + 4214 uint32_t at_least_space_for = estimate_nof_elements +
4203 (estimate_nof_elements >> 2); 4215 (estimate_nof_elements >> 2);
4204 storage = Handle<FixedArray>::cast( 4216 storage = Handle<FixedArray>::cast(
4205 Factory::NewDictionary(at_least_space_for)); 4217 Factory::NewDictionary(at_least_space_for));
4206 } 4218 }
4207 4219
4208 Handle<Object> len = Factory::NewNumber(static_cast<double>(result_length)); 4220 Handle<Object> len = Factory::NewNumber(static_cast<double>(result_length));
4209 4221
4210 ArrayConcatVisitor visitor(storage, fast_case); 4222 ArrayConcatVisitor visitor(storage, result_length, fast_case);
4211 4223
4212 IterateArguments(arguments, &visitor); 4224 IterateArguments(arguments, &visitor);
4213 4225
4214 result->set_length(*len); 4226 result->set_length(*len);
4215 result->set_elements(*storage); 4227 result->set_elements(*storage);
4216 4228
4217 return *result; 4229 return *result;
4218 } 4230 }
4219 4231
4220 4232
(...skipping 1533 matching lines...) Expand 10 before | Expand all | Expand 10 after
5754 5766
5755 void Runtime::PerformGC(Object* result) { 5767 void Runtime::PerformGC(Object* result) {
5756 Failure* failure = Failure::cast(result); 5768 Failure* failure = Failure::cast(result);
5757 // Try to do a garbage collection; ignore it if it fails. The C 5769 // Try to do a garbage collection; ignore it if it fails. The C
5758 // entry stub will throw an out-of-memory exception in that case. 5770 // entry stub will throw an out-of-memory exception in that case.
5759 Heap::CollectGarbage(failure->requested(), failure->allocation_space()); 5771 Heap::CollectGarbage(failure->requested(), failure->allocation_space());
5760 } 5772 }
5761 5773
5762 5774
5763 } } // namespace v8::internal 5775 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698