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

Side by Side Diff: src/runtime.cc

Issue 46088: Revert 1469 and 1472 due to a bug with array literals. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 9 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 | Annotate | Revision Log
« no previous file with comments | « src/runtime.h ('k') | test/mjsunit/fuzz-natives.js » ('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 25 matching lines...) Expand all
36 #include "cpu.h" 36 #include "cpu.h"
37 #include "dateparser.h" 37 #include "dateparser.h"
38 #include "debug.h" 38 #include "debug.h"
39 #include "execution.h" 39 #include "execution.h"
40 #include "jsregexp.h" 40 #include "jsregexp.h"
41 #include "platform.h" 41 #include "platform.h"
42 #include "runtime.h" 42 #include "runtime.h"
43 #include "scopeinfo.h" 43 #include "scopeinfo.h"
44 #include "v8threads.h" 44 #include "v8threads.h"
45 #include "smart-pointer.h" 45 #include "smart-pointer.h"
46 #include "parser.h"
47 46
48 namespace v8 { namespace internal { 47 namespace v8 { namespace internal {
49 48
50 49
51 #define RUNTIME_ASSERT(value) do { \ 50 #define RUNTIME_ASSERT(value) do { \
52 if (!(value)) return IllegalOperation(); \ 51 if (!(value)) return IllegalOperation(); \
53 } while (false) 52 } while (false)
54 53
55 // Cast the given object to a value of the specified type and store 54 // Cast the given object to a value of the specified type and store
56 // it in a variable with the given name. If the object is not of the 55 // it in a variable with the given name. If the object is not of the
57 // expected type call IllegalOperation and return. 56 // expected type call IllegalOperation and return.
58 #define CONVERT_CHECKED(Type, name, obj) \ 57 #define CONVERT_CHECKED(Type, name, obj) \
59 RUNTIME_ASSERT(obj->Is##Type()); \ 58 RUNTIME_ASSERT(obj->Is##Type()); \
60 Type* name = Type::cast(obj); 59 Type* name = Type::cast(obj);
61 60
62 #define CONVERT_ARG_CHECKED(Type, name, index) \ 61 #define CONVERT_ARG_CHECKED(Type, name, index) \
63 RUNTIME_ASSERT(args[index]->Is##Type()); \ 62 RUNTIME_ASSERT(args[index]->Is##Type()); \
64 Handle<Type> name = args.at<Type>(index); 63 Handle<Type> name = args.at<Type>(index);
65 64
66 // Cast the given object to a boolean and store it in a variable with 65 // Cast the given object to a boolean and store it in a variable with
67 // the given name. If the object is not a boolean call IllegalOperation 66 // the given name. If the object is not a boolean call IllegalOperation
68 // and return. 67 // and return.
69 #define CONVERT_BOOLEAN_CHECKED(name, obj) \ 68 #define CONVERT_BOOLEAN_CHECKED(name, obj) \
70 RUNTIME_ASSERT(obj->IsBoolean()); \ 69 RUNTIME_ASSERT(obj->IsBoolean()); \
71 bool name = (obj)->IsTrue(); 70 bool name = (obj)->IsTrue();
72 71
73 // Cast the given object to an int and store it in a variable with
74 // the given name. If the object is not a Smi call IllegalOperation
75 // and return.
76 #define CONVERT_INT_CHECKED(name, obj) \
77 RUNTIME_ASSERT(obj->IsSmi()); \
78 int name = Smi::cast(obj)->value();
79
80 // Cast the given object to a double and store it in a variable with 72 // Cast the given object to a double and store it in a variable with
81 // the given name. If the object is not a number (as opposed to 73 // the given name. If the object is not a number (as opposed to
82 // the number not-a-number) call IllegalOperation and return. 74 // the number not-a-number) call IllegalOperation and return.
83 #define CONVERT_DOUBLE_CHECKED(name, obj) \ 75 #define CONVERT_DOUBLE_CHECKED(name, obj) \
84 RUNTIME_ASSERT(obj->IsNumber()); \ 76 RUNTIME_ASSERT(obj->IsNumber()); \
85 double name = (obj)->Number(); 77 double name = (obj)->Number();
86 78
87 // Call the specified converter on the object *comand store the result in 79 // Call the specified converter on the object *comand store the result in
88 // a variable of the specified type with the given name. If the 80 // a variable of the specified type with the given name. If the
89 // object is not a Number call IllegalOperation and return. 81 // object is not a Number call IllegalOperation and return.
90 #define CONVERT_NUMBER_CHECKED(type, name, Type, obj) \ 82 #define CONVERT_NUMBER_CHECKED(type, name, Type, obj) \
91 RUNTIME_ASSERT(obj->IsNumber()); \ 83 RUNTIME_ASSERT(obj->IsNumber()); \
92 type name = NumberTo##Type(obj); 84 type name = NumberTo##Type(obj);
93 85
94 // Non-reentrant string buffer for efficient general use in this file. 86 // Non-reentrant string buffer for efficient general use in this file.
95 static StaticResource<StringInputBuffer> runtime_string_input_buffer; 87 static StaticResource<StringInputBuffer> runtime_string_input_buffer;
96 88
97 89
98 static Object* IllegalOperation() { 90 static Object* IllegalOperation() {
99 return Top::Throw(Heap::illegal_access_symbol()); 91 return Top::Throw(Heap::illegal_access_symbol());
100 } 92 }
101 93
102 94
103 static Object* Runtime_CloneLiteralBoilerplate(Arguments args) { 95 static Object* Runtime_CloneObjectLiteralBoilerplate(Arguments args) {
104 CONVERT_CHECKED(JSObject, boilerplate, args[0]); 96 CONVERT_CHECKED(JSObject, boilerplate, args[0]);
105 return Heap::CopyJSObject(boilerplate); 97 return Heap::CopyJSObject(boilerplate);
106 } 98 }
107 99
108 100
109 static Handle<Map> ComputeObjectLiteralMap( 101 static Handle<Map> ComputeObjectLiteralMap(
110 Handle<Context> context, 102 Handle<Context> context,
111 Handle<FixedArray> constant_properties, 103 Handle<FixedArray> constant_properties,
112 bool* is_result_from_cache) { 104 bool* is_result_from_cache) {
113 int number_of_properties = constant_properties->length() / 2; 105 int number_of_properties = constant_properties->length() / 2;
(...skipping 18 matching lines...) Expand all
132 return Factory::ObjectLiteralMapFromCache(context, keys); 124 return Factory::ObjectLiteralMapFromCache(context, keys);
133 } 125 }
134 } 126 }
135 *is_result_from_cache = false; 127 *is_result_from_cache = false;
136 return Factory::CopyMap( 128 return Factory::CopyMap(
137 Handle<Map>(context->object_function()->initial_map()), 129 Handle<Map>(context->object_function()->initial_map()),
138 number_of_properties); 130 number_of_properties);
139 } 131 }
140 132
141 133
142 static Handle<Object> CreateLiteralBoilerplate( 134 static Object* Runtime_CreateObjectLiteralBoilerplate(Arguments args) {
143 Handle<FixedArray> literals, 135 HandleScope scope;
144 Handle<FixedArray> constant_properties); 136 ASSERT(args.length() == 3);
137 // Copy the arguments.
138 Handle<FixedArray> literals = args.at<FixedArray>(0);
139 int literals_index = Smi::cast(args[1])->value();
140 Handle<FixedArray> constant_properties = args.at<FixedArray>(2);
145 141
146
147 static Handle<Object> CreateObjectLiteralBoilerplate(
148 Handle<FixedArray> literals,
149 Handle<FixedArray> constant_properties) {
150 // Get the global context from the literals array. This is the 142 // Get the global context from the literals array. This is the
151 // context in which the function was created and we use the object 143 // context in which the function was created and we use the object
152 // function from this context to create the object literal. We do 144 // function from this context to create the object literal. We do
153 // not use the object function from the current global context 145 // not use the object function from the current global context
154 // because this might be the object function from another context 146 // because this might be the object function from another context
155 // which we should not have access to. 147 // which we should not have access to.
156 Handle<Context> context = 148 Handle<Context> context =
157 Handle<Context>(JSFunction::GlobalContextFromLiterals(*literals)); 149 Handle<Context>(JSFunction::GlobalContextFromLiterals(*literals));
158 150
159 bool is_result_from_cache; 151 bool is_result_from_cache;
160 Handle<Map> map = ComputeObjectLiteralMap(context, 152 Handle<Map> map = ComputeObjectLiteralMap(context,
161 constant_properties, 153 constant_properties,
162 &is_result_from_cache); 154 &is_result_from_cache);
163 155
164 Handle<JSObject> boilerplate = Factory::NewJSObjectFromMap(map); 156 Handle<JSObject> boilerplate = Factory::NewJSObjectFromMap(map);
165 { // Add the constant properties to the boilerplate. 157 { // Add the constant properties to the boilerplate.
166 int length = constant_properties->length(); 158 int length = constant_properties->length();
167 OptimizedObjectForAddingMultipleProperties opt(boilerplate, 159 OptimizedObjectForAddingMultipleProperties opt(boilerplate,
168 !is_result_from_cache); 160 !is_result_from_cache);
169 for (int index = 0; index < length; index +=2) { 161 for (int index = 0; index < length; index +=2) {
170 Handle<Object> key(constant_properties->get(index+0)); 162 Handle<Object> key(constant_properties->get(index+0));
171 Handle<Object> value(constant_properties->get(index+1)); 163 Handle<Object> value(constant_properties->get(index+1));
172 if (value->IsFixedArray()) {
173 // The value contains the constant_properties of a
174 // simple object literal.
175 Handle<FixedArray> array = Handle<FixedArray>::cast(value);
176 value = CreateLiteralBoilerplate(literals, array);
177 if (value.is_null()) return value;
178 }
179 Handle<Object> result; 164 Handle<Object> result;
180 uint32_t element_index = 0; 165 uint32_t element_index = 0;
181 if (key->IsSymbol()) { 166 if (key->IsSymbol()) {
182 // If key is a symbol it is not an array element. 167 // If key is a symbol it is not an array element.
183 Handle<String> name(String::cast(*key)); 168 Handle<String> name(String::cast(*key));
184 ASSERT(!name->AsArrayIndex(&element_index)); 169 ASSERT(!name->AsArrayIndex(&element_index));
185 result = SetProperty(boilerplate, name, value, NONE); 170 result = SetProperty(boilerplate, name, value, NONE);
186 } else if (Array::IndexFromObject(*key, &element_index)) { 171 } else if (Array::IndexFromObject(*key, &element_index)) {
187 // Array index (uint32). 172 // Array index (uint32).
188 result = SetElement(boilerplate, element_index, value); 173 result = SetElement(boilerplate, element_index, value);
189 } else { 174 } else {
190 // Non-uint32 number. 175 // Non-uint32 number.
191 ASSERT(key->IsNumber()); 176 ASSERT(key->IsNumber());
192 double num = key->Number(); 177 double num = key->Number();
193 char arr[100]; 178 char arr[100];
194 Vector<char> buffer(arr, ARRAY_SIZE(arr)); 179 Vector<char> buffer(arr, ARRAY_SIZE(arr));
195 const char* str = DoubleToCString(num, buffer); 180 const char* str = DoubleToCString(num, buffer);
196 Handle<String> name = Factory::NewStringFromAscii(CStrVector(str)); 181 Handle<String> name = Factory::NewStringFromAscii(CStrVector(str));
197 result = SetProperty(boilerplate, name, value, NONE); 182 result = SetProperty(boilerplate, name, value, NONE);
198 } 183 }
199 // If setting the property on the boilerplate throws an 184 // If setting the property on the boilerplate throws an
200 // exception, the exception is converted to an empty handle in 185 // exception, the exception is converted to an empty handle in
201 // the handle based operations. In that case, we need to 186 // the handle based operations. In that case, we need to
202 // convert back to an exception. 187 // convert back to an exception.
203 if (result.is_null()) return result; 188 if (result.is_null()) return Failure::Exception();
204 } 189 }
205 } 190 }
206 191
207 return boilerplate; 192 // Update the functions literal and return the boilerplate.
193 literals->set(literals_index, *boilerplate);
194
195 return *boilerplate;
208 } 196 }
209 197
210 198
211 static Handle<Object> CreateArrayLiteralBoilerplate( 199 static Object* Runtime_CreateArrayLiteral(Arguments args) {
212 Handle<FixedArray> literals,
213 Handle<FixedArray> elements) {
214 // Create the JSArray.
215 Handle<JSFunction> constructor(
216 JSFunction::GlobalContextFromLiterals(*literals)->array_function());
217 Handle<Object> object = Factory::NewJSObject(constructor);
218
219 Handle<Object> copied_elements = Factory::CopyFixedArray(elements);
220
221 Handle<FixedArray> content = Handle<FixedArray>::cast(copied_elements);
222 for (int i = 0; i < content->length(); i++) {
223 if (content->get(i)->IsFixedArray()) {
224 // The value contains the constant_properties of a
225 // simple object literal.
226 Handle<FixedArray> fa(FixedArray::cast(content->get(i)));
227 Handle<Object> result = CreateLiteralBoilerplate(literals, fa);
228 if (result.is_null()) return result;
229 content->set(i, *result);
230 }
231 }
232
233 // Set the elements.
234 Handle<JSArray>::cast(object)->SetContent(*content);
235 return object;
236 }
237
238
239 static Handle<Object> CreateLiteralBoilerplate(
240 Handle<FixedArray> literals,
241 Handle<FixedArray> array) {
242 Handle<FixedArray> elements = CompileTimeValue::GetElements(array);
243 switch (CompileTimeValue::GetType(array)) {
244 case CompileTimeValue::OBJECT_LITERAL:
245 return CreateObjectLiteralBoilerplate(literals, elements);
246 case CompileTimeValue::ARRAY_LITERAL:
247 return CreateArrayLiteralBoilerplate(literals, elements);
248 default:
249 UNREACHABLE();
250 return Handle<Object>::null();
251 }
252 }
253
254
255 static Object* Runtime_CreateObjectLiteralBoilerplate(Arguments args) {
256 HandleScope scope;
257 ASSERT(args.length() == 3);
258 // Copy the arguments.
259 CONVERT_ARG_CHECKED(FixedArray, literals, 0);
260 CONVERT_INT_CHECKED(literals_index, args[1]);
261 CONVERT_ARG_CHECKED(FixedArray, constant_properties, 2);
262
263 Handle<Object> result =
264 CreateObjectLiteralBoilerplate(literals, constant_properties);
265
266 if (result.is_null()) return Failure::Exception();
267
268 // Update the functions literal and return the boilerplate.
269 literals->set(literals_index, *result);
270
271 return *result;
272 }
273
274
275 static Object* Runtime_CreateArrayLiteralBoilerplate(Arguments args) {
276 // Takes a FixedArray of elements containing the literal elements of 200 // Takes a FixedArray of elements containing the literal elements of
277 // the array literal and produces JSArray with those elements. 201 // the array literal and produces JSArray with those elements.
278 // Additionally takes the literals array of the surrounding function 202 // Additionally takes the literals array of the surrounding function
279 // which contains the context from which to get the Array function 203 // which contains the context from which to get the Array function
280 // to use for creating the array literal. 204 // to use for creating the array literal.
281 HandleScope scope; 205 ASSERT(args.length() == 2);
282 ASSERT(args.length() == 3); 206 CONVERT_CHECKED(FixedArray, elements, args[0]);
283 CONVERT_ARG_CHECKED(FixedArray, literals, 0); 207 CONVERT_CHECKED(FixedArray, literals, args[1]);
284 CONVERT_INT_CHECKED(literals_index, args[1]); 208 JSFunction* constructor =
285 CONVERT_ARG_CHECKED(FixedArray, elements, 2); 209 JSFunction::GlobalContextFromLiterals(literals)->array_function();
210 // Create the JSArray.
211 Object* object = Heap::AllocateJSObject(constructor);
212 if (object->IsFailure()) return object;
286 213
287 Handle<Object> object = CreateArrayLiteralBoilerplate(literals, elements); 214 // Copy the elements.
288 if (object.is_null()) return Failure::Exception(); 215 Object* content = elements->Copy();
216 if (content->IsFailure()) return content;
289 217
290 // Update the functions literal and return the boilerplate. 218 // Set the elements.
291 literals->set(literals_index, *object); 219 JSArray::cast(object)->SetContent(FixedArray::cast(content));
292 return *object; 220 return object;
293 } 221 }
294 222
295 223
296 static Object* Runtime_CreateCatchExtensionObject(Arguments args) { 224 static Object* Runtime_CreateCatchExtensionObject(Arguments args) {
297 ASSERT(args.length() == 2); 225 ASSERT(args.length() == 2);
298 CONVERT_CHECKED(String, key, args[0]); 226 CONVERT_CHECKED(String, key, args[0]);
299 Object* value = args[1]; 227 Object* value = args[1];
300 // Create a catch context extension object. 228 // Create a catch context extension object.
301 JSFunction* constructor = 229 JSFunction* constructor =
302 Top::context()->global_context()->context_extension_function(); 230 Top::context()->global_context()->context_extension_function();
(...skipping 6421 matching lines...) Expand 10 before | Expand all | Expand 10 after
6724 } else { 6652 } else {
6725 // Handle last resort GC and make sure to allow future allocations 6653 // Handle last resort GC and make sure to allow future allocations
6726 // to grow the heap without causing GCs (if possible). 6654 // to grow the heap without causing GCs (if possible).
6727 Counters::gc_last_resort_from_js.Increment(); 6655 Counters::gc_last_resort_from_js.Increment();
6728 Heap::CollectAllGarbage(); 6656 Heap::CollectAllGarbage();
6729 } 6657 }
6730 } 6658 }
6731 6659
6732 6660
6733 } } // namespace v8::internal 6661 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/runtime.h ('k') | test/mjsunit/fuzz-natives.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698