OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <stdlib.h> | 5 #include <stdlib.h> |
6 #include <limits> | 6 #include <limits> |
7 | 7 |
8 #include "src/v8.h" | 8 #include "src/v8.h" |
9 | 9 |
10 #include "src/accessors.h" | 10 #include "src/accessors.h" |
(...skipping 18 matching lines...) Expand all Loading... |
29 #include "src/global-handles.h" | 29 #include "src/global-handles.h" |
30 #include "src/isolate-inl.h" | 30 #include "src/isolate-inl.h" |
31 #include "src/json-parser.h" | 31 #include "src/json-parser.h" |
32 #include "src/json-stringifier.h" | 32 #include "src/json-stringifier.h" |
33 #include "src/jsregexp-inl.h" | 33 #include "src/jsregexp-inl.h" |
34 #include "src/jsregexp.h" | 34 #include "src/jsregexp.h" |
35 #include "src/liveedit.h" | 35 #include "src/liveedit.h" |
36 #include "src/misc-intrinsics.h" | 36 #include "src/misc-intrinsics.h" |
37 #include "src/parser.h" | 37 #include "src/parser.h" |
38 #include "src/prototype.h" | 38 #include "src/prototype.h" |
39 #include "src/runtime.h" | 39 #include "src/runtime/runtime.h" |
| 40 #include "src/runtime/runtime-utils.h" |
40 #include "src/runtime-profiler.h" | 41 #include "src/runtime-profiler.h" |
41 #include "src/scopeinfo.h" | 42 #include "src/scopeinfo.h" |
42 #include "src/smart-pointers.h" | 43 #include "src/smart-pointers.h" |
43 #include "src/string-search.h" | 44 #include "src/string-search.h" |
44 #include "src/uri.h" | 45 #include "src/uri.h" |
45 #include "src/utils.h" | 46 #include "src/utils.h" |
46 #include "src/v8threads.h" | 47 #include "src/v8threads.h" |
47 #include "src/vm-state-inl.h" | 48 #include "src/vm-state-inl.h" |
48 #include "third_party/fdlibm/fdlibm.h" | 49 #include "third_party/fdlibm/fdlibm.h" |
49 | 50 |
50 #ifdef V8_I18N_SUPPORT | |
51 #include "src/i18n.h" | |
52 #include "unicode/brkiter.h" | |
53 #include "unicode/calendar.h" | |
54 #include "unicode/coll.h" | |
55 #include "unicode/curramt.h" | |
56 #include "unicode/datefmt.h" | |
57 #include "unicode/dcfmtsym.h" | |
58 #include "unicode/decimfmt.h" | |
59 #include "unicode/dtfmtsym.h" | |
60 #include "unicode/dtptngen.h" | |
61 #include "unicode/locid.h" | |
62 #include "unicode/numfmt.h" | |
63 #include "unicode/numsys.h" | |
64 #include "unicode/rbbi.h" | |
65 #include "unicode/smpdtfmt.h" | |
66 #include "unicode/timezone.h" | |
67 #include "unicode/uchar.h" | |
68 #include "unicode/ucol.h" | |
69 #include "unicode/ucurr.h" | |
70 #include "unicode/uloc.h" | |
71 #include "unicode/unum.h" | |
72 #include "unicode/uversion.h" | |
73 #endif | |
74 | 51 |
75 #ifndef _STLP_VENDOR_CSTD | 52 #ifndef _STLP_VENDOR_CSTD |
76 // STLPort doesn't import fpclassify and isless into the std namespace. | 53 // STLPort doesn't import fpclassify and isless into the std namespace. |
77 using std::fpclassify; | 54 using std::fpclassify; |
78 using std::isless; | 55 using std::isless; |
79 #endif | 56 #endif |
80 | 57 |
81 namespace v8 { | 58 namespace v8 { |
82 namespace internal { | 59 namespace internal { |
83 | 60 |
| 61 // Header of runtime functions. |
| 62 #define F(name, number_of_args, result_size) \ |
| 63 Object* Runtime_##name(int args_length, Object** args_object, \ |
| 64 Isolate* isolate); |
84 | 65 |
85 #define RUNTIME_ASSERT(value) \ | 66 #define P(name, number_of_args, result_size) \ |
86 if (!(value)) return isolate->ThrowIllegalOperation(); | 67 ObjectPair Runtime_##name(int args_length, Object** args_object, \ |
| 68 Isolate* isolate); |
87 | 69 |
88 #define RUNTIME_ASSERT_HANDLIFIED(value, T) \ | 70 #define I(name, number_of_args, result_size) \ |
89 if (!(value)) { \ | 71 Object* RuntimeReference_##name(int args_length, Object** args_object, \ |
90 isolate->ThrowIllegalOperation(); \ | 72 Isolate* isolate); |
91 return MaybeHandle<T>(); \ | |
92 } | |
93 | 73 |
94 // Cast the given object to a value of the specified type and store | 74 RUNTIME_FUNCTION_LIST_RETURN_OBJECT(F) |
95 // it in a variable with the given name. If the object is not of the | 75 RUNTIME_FUNCTION_LIST_RETURN_PAIR(P) |
96 // expected type call IllegalOperation and return. | 76 INLINE_OPTIMIZED_FUNCTION_LIST(F) |
97 #define CONVERT_ARG_CHECKED(Type, name, index) \ | 77 INLINE_FUNCTION_LIST(I) |
98 RUNTIME_ASSERT(args[index]->Is##Type()); \ | |
99 Type* name = Type::cast(args[index]); | |
100 | 78 |
101 #define CONVERT_ARG_HANDLE_CHECKED(Type, name, index) \ | 79 #undef I |
102 RUNTIME_ASSERT(args[index]->Is##Type()); \ | 80 #undef F |
103 Handle<Type> name = args.at<Type>(index); | 81 #undef P |
104 | |
105 #define CONVERT_NUMBER_ARG_HANDLE_CHECKED(name, index) \ | |
106 RUNTIME_ASSERT(args[index]->IsNumber()); \ | |
107 Handle<Object> name = args.at<Object>(index); | |
108 | |
109 // Cast the given object to a boolean and store it in a variable with | |
110 // the given name. If the object is not a boolean call IllegalOperation | |
111 // and return. | |
112 #define CONVERT_BOOLEAN_ARG_CHECKED(name, index) \ | |
113 RUNTIME_ASSERT(args[index]->IsBoolean()); \ | |
114 bool name = args[index]->IsTrue(); | |
115 | |
116 // Cast the given argument to a Smi and store its value in an int variable | |
117 // with the given name. If the argument is not a Smi call IllegalOperation | |
118 // and return. | |
119 #define CONVERT_SMI_ARG_CHECKED(name, index) \ | |
120 RUNTIME_ASSERT(args[index]->IsSmi()); \ | |
121 int name = args.smi_at(index); | |
122 | |
123 // Cast the given argument to a double and store it in a variable with | |
124 // the given name. If the argument is not a number (as opposed to | |
125 // the number not-a-number) call IllegalOperation and return. | |
126 #define CONVERT_DOUBLE_ARG_CHECKED(name, index) \ | |
127 RUNTIME_ASSERT(args[index]->IsNumber()); \ | |
128 double name = args.number_at(index); | |
129 | |
130 // Call the specified converter on the object *comand store the result in | |
131 // a variable of the specified type with the given name. If the | |
132 // object is not a Number call IllegalOperation and return. | |
133 #define CONVERT_NUMBER_CHECKED(type, name, Type, obj) \ | |
134 RUNTIME_ASSERT(obj->IsNumber()); \ | |
135 type name = NumberTo##Type(obj); | |
136 | |
137 | |
138 // Cast the given argument to PropertyDetails and store its value in a | |
139 // variable with the given name. If the argument is not a Smi call | |
140 // IllegalOperation and return. | |
141 #define CONVERT_PROPERTY_DETAILS_CHECKED(name, index) \ | |
142 RUNTIME_ASSERT(args[index]->IsSmi()); \ | |
143 PropertyDetails name = PropertyDetails(Smi::cast(args[index])); | |
144 | |
145 | |
146 // Assert that the given argument has a valid value for a StrictMode | |
147 // and store it in a StrictMode variable with the given name. | |
148 #define CONVERT_STRICT_MODE_ARG_CHECKED(name, index) \ | |
149 RUNTIME_ASSERT(args[index]->IsSmi()); \ | |
150 RUNTIME_ASSERT(args.smi_at(index) == STRICT || \ | |
151 args.smi_at(index) == SLOPPY); \ | |
152 StrictMode name = static_cast<StrictMode>(args.smi_at(index)); | |
153 | |
154 | |
155 // Assert that the given argument is a number within the Int32 range | |
156 // and convert it to int32_t. If the argument is not an Int32 call | |
157 // IllegalOperation and return. | |
158 #define CONVERT_INT32_ARG_CHECKED(name, index) \ | |
159 RUNTIME_ASSERT(args[index]->IsNumber()); \ | |
160 int32_t name = 0; \ | |
161 RUNTIME_ASSERT(args[index]->ToInt32(&name)); | |
162 | 82 |
163 | 83 |
164 static Handle<Map> ComputeObjectLiteralMap( | 84 static Handle<Map> ComputeObjectLiteralMap( |
165 Handle<Context> context, | 85 Handle<Context> context, Handle<FixedArray> constant_properties, |
166 Handle<FixedArray> constant_properties, | |
167 bool* is_result_from_cache) { | 86 bool* is_result_from_cache) { |
168 Isolate* isolate = context->GetIsolate(); | 87 Isolate* isolate = context->GetIsolate(); |
169 int properties_length = constant_properties->length(); | 88 int properties_length = constant_properties->length(); |
170 int number_of_properties = properties_length / 2; | 89 int number_of_properties = properties_length / 2; |
171 // Check that there are only internal strings and array indices among keys. | 90 // Check that there are only internal strings and array indices among keys. |
172 int number_of_string_keys = 0; | 91 int number_of_string_keys = 0; |
173 for (int p = 0; p != properties_length; p += 2) { | 92 for (int p = 0; p != properties_length; p += 2) { |
174 Object* key = constant_properties->get(p); | 93 Object* key = constant_properties->get(p); |
175 uint32_t element_index = 0; | 94 uint32_t element_index = 0; |
176 if (key->IsInternalizedString()) { | 95 if (key->IsInternalizedString()) { |
(...skipping 29 matching lines...) Expand all Loading... |
206 } | 125 } |
207 *is_result_from_cache = true; | 126 *is_result_from_cache = true; |
208 return isolate->factory()->ObjectLiteralMapFromCache(context, keys); | 127 return isolate->factory()->ObjectLiteralMapFromCache(context, keys); |
209 } | 128 } |
210 *is_result_from_cache = false; | 129 *is_result_from_cache = false; |
211 return Map::Create(isolate, number_of_properties); | 130 return Map::Create(isolate, number_of_properties); |
212 } | 131 } |
213 | 132 |
214 | 133 |
215 MUST_USE_RESULT static MaybeHandle<Object> CreateLiteralBoilerplate( | 134 MUST_USE_RESULT static MaybeHandle<Object> CreateLiteralBoilerplate( |
216 Isolate* isolate, | 135 Isolate* isolate, Handle<FixedArray> literals, |
217 Handle<FixedArray> literals, | |
218 Handle<FixedArray> constant_properties); | 136 Handle<FixedArray> constant_properties); |
219 | 137 |
220 | 138 |
221 MUST_USE_RESULT static MaybeHandle<Object> CreateObjectLiteralBoilerplate( | 139 MUST_USE_RESULT static MaybeHandle<Object> CreateObjectLiteralBoilerplate( |
222 Isolate* isolate, | 140 Isolate* isolate, Handle<FixedArray> literals, |
223 Handle<FixedArray> literals, | 141 Handle<FixedArray> constant_properties, bool should_have_fast_elements, |
224 Handle<FixedArray> constant_properties, | |
225 bool should_have_fast_elements, | |
226 bool has_function_literal) { | 142 bool has_function_literal) { |
227 // Get the native context from the literals array. This is the | 143 // Get the native context from the literals array. This is the |
228 // context in which the function was created and we use the object | 144 // context in which the function was created and we use the object |
229 // function from this context to create the object literal. We do | 145 // function from this context to create the object literal. We do |
230 // not use the object function from the current native context | 146 // not use the object function from the current native context |
231 // because this might be the object function from another context | 147 // because this might be the object function from another context |
232 // which we should not have access to. | 148 // which we should not have access to. |
233 Handle<Context> context = | 149 Handle<Context> context = |
234 Handle<Context>(JSFunction::NativeContextFromLiterals(*literals)); | 150 Handle<Context>(JSFunction::NativeContextFromLiterals(*literals)); |
235 | 151 |
236 // In case we have function literals, we want the object to be in | 152 // In case we have function literals, we want the object to be in |
237 // slow properties mode for now. We don't go in the map cache because | 153 // slow properties mode for now. We don't go in the map cache because |
238 // maps with constant functions can't be shared if the functions are | 154 // maps with constant functions can't be shared if the functions are |
239 // not the same (which is the common case). | 155 // not the same (which is the common case). |
240 bool is_result_from_cache = false; | 156 bool is_result_from_cache = false; |
241 Handle<Map> map = has_function_literal | 157 Handle<Map> map = has_function_literal |
242 ? Handle<Map>(context->object_function()->initial_map()) | 158 ? Handle<Map>(context->object_function()->initial_map()) |
243 : ComputeObjectLiteralMap(context, | 159 : ComputeObjectLiteralMap(context, constant_properties, |
244 constant_properties, | 160 &is_result_from_cache); |
245 &is_result_from_cache); | |
246 | 161 |
247 PretenureFlag pretenure_flag = | 162 PretenureFlag pretenure_flag = |
248 isolate->heap()->InNewSpace(*literals) ? NOT_TENURED : TENURED; | 163 isolate->heap()->InNewSpace(*literals) ? NOT_TENURED : TENURED; |
249 | 164 |
250 Handle<JSObject> boilerplate = | 165 Handle<JSObject> boilerplate = |
251 isolate->factory()->NewJSObjectFromMap(map, pretenure_flag); | 166 isolate->factory()->NewJSObjectFromMap(map, pretenure_flag); |
252 | 167 |
253 // Normalize the elements of the boilerplate to save space if needed. | 168 // Normalize the elements of the boilerplate to save space if needed. |
254 if (!should_have_fast_elements) JSObject::NormalizeElements(boilerplate); | 169 if (!should_have_fast_elements) JSObject::NormalizeElements(boilerplate); |
255 | 170 |
256 // Add the constant properties to the boilerplate. | 171 // Add the constant properties to the boilerplate. |
257 int length = constant_properties->length(); | 172 int length = constant_properties->length(); |
258 bool should_transform = | 173 bool should_transform = |
259 !is_result_from_cache && boilerplate->HasFastProperties(); | 174 !is_result_from_cache && boilerplate->HasFastProperties(); |
260 bool should_normalize = should_transform || has_function_literal; | 175 bool should_normalize = should_transform || has_function_literal; |
261 if (should_normalize) { | 176 if (should_normalize) { |
262 // TODO(verwaest): We might not want to ever normalize here. | 177 // TODO(verwaest): We might not want to ever normalize here. |
263 JSObject::NormalizeProperties( | 178 JSObject::NormalizeProperties(boilerplate, KEEP_INOBJECT_PROPERTIES, |
264 boilerplate, KEEP_INOBJECT_PROPERTIES, length / 2); | 179 length / 2); |
265 } | 180 } |
266 // TODO(verwaest): Support tracking representations in the boilerplate. | 181 // TODO(verwaest): Support tracking representations in the boilerplate. |
267 for (int index = 0; index < length; index +=2) { | 182 for (int index = 0; index < length; index += 2) { |
268 Handle<Object> key(constant_properties->get(index+0), isolate); | 183 Handle<Object> key(constant_properties->get(index + 0), isolate); |
269 Handle<Object> value(constant_properties->get(index+1), isolate); | 184 Handle<Object> value(constant_properties->get(index + 1), isolate); |
270 if (value->IsFixedArray()) { | 185 if (value->IsFixedArray()) { |
271 // The value contains the constant_properties of a | 186 // The value contains the constant_properties of a |
272 // simple object or array literal. | 187 // simple object or array literal. |
273 Handle<FixedArray> array = Handle<FixedArray>::cast(value); | 188 Handle<FixedArray> array = Handle<FixedArray>::cast(value); |
274 ASSIGN_RETURN_ON_EXCEPTION( | 189 ASSIGN_RETURN_ON_EXCEPTION( |
275 isolate, value, | 190 isolate, value, CreateLiteralBoilerplate(isolate, literals, array), |
276 CreateLiteralBoilerplate(isolate, literals, array), | |
277 Object); | 191 Object); |
278 } | 192 } |
279 MaybeHandle<Object> maybe_result; | 193 MaybeHandle<Object> maybe_result; |
280 uint32_t element_index = 0; | 194 uint32_t element_index = 0; |
281 if (key->IsInternalizedString()) { | 195 if (key->IsInternalizedString()) { |
282 if (Handle<String>::cast(key)->AsArrayIndex(&element_index)) { | 196 if (Handle<String>::cast(key)->AsArrayIndex(&element_index)) { |
283 // Array index as string (uint32). | 197 // Array index as string (uint32). |
284 if (value->IsUninitialized()) value = handle(Smi::FromInt(0), isolate); | 198 if (value->IsUninitialized()) value = handle(Smi::FromInt(0), isolate); |
285 maybe_result = | 199 maybe_result = |
286 JSObject::SetOwnElement(boilerplate, element_index, value, SLOPPY); | 200 JSObject::SetOwnElement(boilerplate, element_index, value, SLOPPY); |
(...skipping 24 matching lines...) Expand all Loading... |
311 // the handle based operations. In that case, we need to | 225 // the handle based operations. In that case, we need to |
312 // convert back to an exception. | 226 // convert back to an exception. |
313 RETURN_ON_EXCEPTION(isolate, maybe_result, Object); | 227 RETURN_ON_EXCEPTION(isolate, maybe_result, Object); |
314 } | 228 } |
315 | 229 |
316 // Transform to fast properties if necessary. For object literals with | 230 // Transform to fast properties if necessary. For object literals with |
317 // containing function literals we defer this operation until after all | 231 // containing function literals we defer this operation until after all |
318 // computed properties have been assigned so that we can generate | 232 // computed properties have been assigned so that we can generate |
319 // constant function properties. | 233 // constant function properties. |
320 if (should_transform && !has_function_literal) { | 234 if (should_transform && !has_function_literal) { |
321 JSObject::MigrateSlowToFast( | 235 JSObject::MigrateSlowToFast(boilerplate, |
322 boilerplate, boilerplate->map()->unused_property_fields()); | 236 boilerplate->map()->unused_property_fields()); |
323 } | 237 } |
324 | 238 |
325 return boilerplate; | 239 return boilerplate; |
326 } | 240 } |
327 | 241 |
328 | 242 |
329 MUST_USE_RESULT static MaybeHandle<Object> TransitionElements( | 243 MUST_USE_RESULT static MaybeHandle<Object> TransitionElements( |
330 Handle<Object> object, | 244 Handle<Object> object, ElementsKind to_kind, Isolate* isolate) { |
331 ElementsKind to_kind, | |
332 Isolate* isolate) { | |
333 HandleScope scope(isolate); | 245 HandleScope scope(isolate); |
334 if (!object->IsJSObject()) { | 246 if (!object->IsJSObject()) { |
335 isolate->ThrowIllegalOperation(); | 247 isolate->ThrowIllegalOperation(); |
336 return MaybeHandle<Object>(); | 248 return MaybeHandle<Object>(); |
337 } | 249 } |
338 ElementsKind from_kind = | 250 ElementsKind from_kind = |
339 Handle<JSObject>::cast(object)->map()->elements_kind(); | 251 Handle<JSObject>::cast(object)->map()->elements_kind(); |
340 if (Map::IsValidElementsTransition(from_kind, to_kind)) { | 252 if (Map::IsValidElementsTransition(from_kind, to_kind)) { |
341 JSObject::TransitionElementsKind(Handle<JSObject>::cast(object), to_kind); | 253 JSObject::TransitionElementsKind(Handle<JSObject>::cast(object), to_kind); |
342 return object; | 254 return object; |
343 } | 255 } |
344 isolate->ThrowIllegalOperation(); | 256 isolate->ThrowIllegalOperation(); |
345 return MaybeHandle<Object>(); | 257 return MaybeHandle<Object>(); |
346 } | 258 } |
347 | 259 |
348 | 260 |
349 MaybeHandle<Object> Runtime::CreateArrayLiteralBoilerplate( | 261 MaybeHandle<Object> Runtime::CreateArrayLiteralBoilerplate( |
350 Isolate* isolate, | 262 Isolate* isolate, Handle<FixedArray> literals, |
351 Handle<FixedArray> literals, | |
352 Handle<FixedArray> elements) { | 263 Handle<FixedArray> elements) { |
353 // Create the JSArray. | 264 // Create the JSArray. |
354 Handle<JSFunction> constructor( | 265 Handle<JSFunction> constructor( |
355 JSFunction::NativeContextFromLiterals(*literals)->array_function()); | 266 JSFunction::NativeContextFromLiterals(*literals)->array_function()); |
356 | 267 |
357 PretenureFlag pretenure_flag = | 268 PretenureFlag pretenure_flag = |
358 isolate->heap()->InNewSpace(*literals) ? NOT_TENURED : TENURED; | 269 isolate->heap()->InNewSpace(*literals) ? NOT_TENURED : TENURED; |
359 | 270 |
360 Handle<JSArray> object = Handle<JSArray>::cast( | 271 Handle<JSArray> object = Handle<JSArray>::cast( |
361 isolate->factory()->NewJSObject(constructor, pretenure_flag)); | 272 isolate->factory()->NewJSObject(constructor, pretenure_flag)); |
362 | 273 |
363 ElementsKind constant_elements_kind = | 274 ElementsKind constant_elements_kind = |
364 static_cast<ElementsKind>(Smi::cast(elements->get(0))->value()); | 275 static_cast<ElementsKind>(Smi::cast(elements->get(0))->value()); |
365 Handle<FixedArrayBase> constant_elements_values( | 276 Handle<FixedArrayBase> constant_elements_values( |
366 FixedArrayBase::cast(elements->get(1))); | 277 FixedArrayBase::cast(elements->get(1))); |
367 | 278 |
368 { DisallowHeapAllocation no_gc; | 279 { |
| 280 DisallowHeapAllocation no_gc; |
369 DCHECK(IsFastElementsKind(constant_elements_kind)); | 281 DCHECK(IsFastElementsKind(constant_elements_kind)); |
370 Context* native_context = isolate->context()->native_context(); | 282 Context* native_context = isolate->context()->native_context(); |
371 Object* maps_array = native_context->js_array_maps(); | 283 Object* maps_array = native_context->js_array_maps(); |
372 DCHECK(!maps_array->IsUndefined()); | 284 DCHECK(!maps_array->IsUndefined()); |
373 Object* map = FixedArray::cast(maps_array)->get(constant_elements_kind); | 285 Object* map = FixedArray::cast(maps_array)->get(constant_elements_kind); |
374 object->set_map(Map::cast(map)); | 286 object->set_map(Map::cast(map)); |
375 } | 287 } |
376 | 288 |
377 Handle<FixedArrayBase> copied_elements_values; | 289 Handle<FixedArrayBase> copied_elements_values; |
378 if (IsFastDoubleElementsKind(constant_elements_kind)) { | 290 if (IsFastDoubleElementsKind(constant_elements_kind)) { |
379 copied_elements_values = isolate->factory()->CopyFixedDoubleArray( | 291 copied_elements_values = isolate->factory()->CopyFixedDoubleArray( |
380 Handle<FixedDoubleArray>::cast(constant_elements_values)); | 292 Handle<FixedDoubleArray>::cast(constant_elements_values)); |
381 } else { | 293 } else { |
382 DCHECK(IsFastSmiOrObjectElementsKind(constant_elements_kind)); | 294 DCHECK(IsFastSmiOrObjectElementsKind(constant_elements_kind)); |
383 const bool is_cow = | 295 const bool is_cow = (constant_elements_values->map() == |
384 (constant_elements_values->map() == | 296 isolate->heap()->fixed_cow_array_map()); |
385 isolate->heap()->fixed_cow_array_map()); | |
386 if (is_cow) { | 297 if (is_cow) { |
387 copied_elements_values = constant_elements_values; | 298 copied_elements_values = constant_elements_values; |
388 #if DEBUG | 299 #if DEBUG |
389 Handle<FixedArray> fixed_array_values = | 300 Handle<FixedArray> fixed_array_values = |
390 Handle<FixedArray>::cast(copied_elements_values); | 301 Handle<FixedArray>::cast(copied_elements_values); |
391 for (int i = 0; i < fixed_array_values->length(); i++) { | 302 for (int i = 0; i < fixed_array_values->length(); i++) { |
392 DCHECK(!fixed_array_values->get(i)->IsFixedArray()); | 303 DCHECK(!fixed_array_values->get(i)->IsFixedArray()); |
393 } | 304 } |
394 #endif | 305 #endif |
395 } else { | 306 } else { |
396 Handle<FixedArray> fixed_array_values = | 307 Handle<FixedArray> fixed_array_values = |
397 Handle<FixedArray>::cast(constant_elements_values); | 308 Handle<FixedArray>::cast(constant_elements_values); |
398 Handle<FixedArray> fixed_array_values_copy = | 309 Handle<FixedArray> fixed_array_values_copy = |
399 isolate->factory()->CopyFixedArray(fixed_array_values); | 310 isolate->factory()->CopyFixedArray(fixed_array_values); |
400 copied_elements_values = fixed_array_values_copy; | 311 copied_elements_values = fixed_array_values_copy; |
401 for (int i = 0; i < fixed_array_values->length(); i++) { | 312 for (int i = 0; i < fixed_array_values->length(); i++) { |
402 if (fixed_array_values->get(i)->IsFixedArray()) { | 313 if (fixed_array_values->get(i)->IsFixedArray()) { |
403 // The value contains the constant_properties of a | 314 // The value contains the constant_properties of a |
404 // simple object or array literal. | 315 // simple object or array literal. |
405 Handle<FixedArray> fa(FixedArray::cast(fixed_array_values->get(i))); | 316 Handle<FixedArray> fa(FixedArray::cast(fixed_array_values->get(i))); |
406 Handle<Object> result; | 317 Handle<Object> result; |
407 ASSIGN_RETURN_ON_EXCEPTION( | 318 ASSIGN_RETURN_ON_EXCEPTION( |
408 isolate, result, | 319 isolate, result, CreateLiteralBoilerplate(isolate, literals, fa), |
409 CreateLiteralBoilerplate(isolate, literals, fa), | |
410 Object); | 320 Object); |
411 fixed_array_values_copy->set(i, *result); | 321 fixed_array_values_copy->set(i, *result); |
412 } | 322 } |
413 } | 323 } |
414 } | 324 } |
415 } | 325 } |
416 object->set_elements(*copied_elements_values); | 326 object->set_elements(*copied_elements_values); |
417 object->set_length(Smi::FromInt(copied_elements_values->length())); | 327 object->set_length(Smi::FromInt(copied_elements_values->length())); |
418 | 328 |
419 JSObject::ValidateElements(object); | 329 JSObject::ValidateElements(object); |
420 return object; | 330 return object; |
421 } | 331 } |
422 | 332 |
423 | 333 |
424 MUST_USE_RESULT static MaybeHandle<Object> CreateLiteralBoilerplate( | 334 MUST_USE_RESULT static MaybeHandle<Object> CreateLiteralBoilerplate( |
425 Isolate* isolate, | 335 Isolate* isolate, Handle<FixedArray> literals, Handle<FixedArray> array) { |
426 Handle<FixedArray> literals, | |
427 Handle<FixedArray> array) { | |
428 Handle<FixedArray> elements = CompileTimeValue::GetElements(array); | 336 Handle<FixedArray> elements = CompileTimeValue::GetElements(array); |
429 const bool kHasNoFunctionLiteral = false; | 337 const bool kHasNoFunctionLiteral = false; |
430 switch (CompileTimeValue::GetLiteralType(array)) { | 338 switch (CompileTimeValue::GetLiteralType(array)) { |
431 case CompileTimeValue::OBJECT_LITERAL_FAST_ELEMENTS: | 339 case CompileTimeValue::OBJECT_LITERAL_FAST_ELEMENTS: |
432 return CreateObjectLiteralBoilerplate(isolate, | 340 return CreateObjectLiteralBoilerplate(isolate, literals, elements, true, |
433 literals, | |
434 elements, | |
435 true, | |
436 kHasNoFunctionLiteral); | 341 kHasNoFunctionLiteral); |
437 case CompileTimeValue::OBJECT_LITERAL_SLOW_ELEMENTS: | 342 case CompileTimeValue::OBJECT_LITERAL_SLOW_ELEMENTS: |
438 return CreateObjectLiteralBoilerplate(isolate, | 343 return CreateObjectLiteralBoilerplate(isolate, literals, elements, false, |
439 literals, | |
440 elements, | |
441 false, | |
442 kHasNoFunctionLiteral); | 344 kHasNoFunctionLiteral); |
443 case CompileTimeValue::ARRAY_LITERAL: | 345 case CompileTimeValue::ARRAY_LITERAL: |
444 return Runtime::CreateArrayLiteralBoilerplate( | 346 return Runtime::CreateArrayLiteralBoilerplate(isolate, literals, |
445 isolate, literals, elements); | 347 elements); |
446 default: | 348 default: |
447 UNREACHABLE(); | 349 UNREACHABLE(); |
448 return MaybeHandle<Object>(); | 350 return MaybeHandle<Object>(); |
449 } | 351 } |
450 } | 352 } |
451 | 353 |
452 | 354 |
453 RUNTIME_FUNCTION(Runtime_CreateObjectLiteral) { | 355 RUNTIME_FUNCTION(Runtime_CreateObjectLiteral) { |
454 HandleScope scope(isolate); | 356 HandleScope scope(isolate); |
455 DCHECK(args.length() == 4); | 357 DCHECK(args.length() == 4); |
456 CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0); | 358 CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0); |
457 CONVERT_SMI_ARG_CHECKED(literals_index, 1); | 359 CONVERT_SMI_ARG_CHECKED(literals_index, 1); |
458 CONVERT_ARG_HANDLE_CHECKED(FixedArray, constant_properties, 2); | 360 CONVERT_ARG_HANDLE_CHECKED(FixedArray, constant_properties, 2); |
459 CONVERT_SMI_ARG_CHECKED(flags, 3); | 361 CONVERT_SMI_ARG_CHECKED(flags, 3); |
460 bool should_have_fast_elements = (flags & ObjectLiteral::kFastElements) != 0; | 362 bool should_have_fast_elements = (flags & ObjectLiteral::kFastElements) != 0; |
461 bool has_function_literal = (flags & ObjectLiteral::kHasFunction) != 0; | 363 bool has_function_literal = (flags & ObjectLiteral::kHasFunction) != 0; |
462 | 364 |
463 RUNTIME_ASSERT(literals_index >= 0 && literals_index < literals->length()); | 365 RUNTIME_ASSERT(literals_index >= 0 && literals_index < literals->length()); |
464 | 366 |
465 // Check if boilerplate exists. If not, create it first. | 367 // Check if boilerplate exists. If not, create it first. |
466 Handle<Object> literal_site(literals->get(literals_index), isolate); | 368 Handle<Object> literal_site(literals->get(literals_index), isolate); |
467 Handle<AllocationSite> site; | 369 Handle<AllocationSite> site; |
468 Handle<JSObject> boilerplate; | 370 Handle<JSObject> boilerplate; |
469 if (*literal_site == isolate->heap()->undefined_value()) { | 371 if (*literal_site == isolate->heap()->undefined_value()) { |
470 Handle<Object> raw_boilerplate; | 372 Handle<Object> raw_boilerplate; |
471 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 373 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
472 isolate, raw_boilerplate, | 374 isolate, raw_boilerplate, |
473 CreateObjectLiteralBoilerplate( | 375 CreateObjectLiteralBoilerplate(isolate, literals, constant_properties, |
474 isolate, | 376 should_have_fast_elements, |
475 literals, | 377 has_function_literal)); |
476 constant_properties, | |
477 should_have_fast_elements, | |
478 has_function_literal)); | |
479 boilerplate = Handle<JSObject>::cast(raw_boilerplate); | 378 boilerplate = Handle<JSObject>::cast(raw_boilerplate); |
480 | 379 |
481 AllocationSiteCreationContext creation_context(isolate); | 380 AllocationSiteCreationContext creation_context(isolate); |
482 site = creation_context.EnterNewScope(); | 381 site = creation_context.EnterNewScope(); |
483 RETURN_FAILURE_ON_EXCEPTION( | 382 RETURN_FAILURE_ON_EXCEPTION( |
484 isolate, | 383 isolate, JSObject::DeepWalk(boilerplate, &creation_context)); |
485 JSObject::DeepWalk(boilerplate, &creation_context)); | |
486 creation_context.ExitScope(site, boilerplate); | 384 creation_context.ExitScope(site, boilerplate); |
487 | 385 |
488 // Update the functions literal and return the boilerplate. | 386 // Update the functions literal and return the boilerplate. |
489 literals->set(literals_index, *site); | 387 literals->set(literals_index, *site); |
490 } else { | 388 } else { |
491 site = Handle<AllocationSite>::cast(literal_site); | 389 site = Handle<AllocationSite>::cast(literal_site); |
492 boilerplate = Handle<JSObject>(JSObject::cast(site->transition_info()), | 390 boilerplate = |
493 isolate); | 391 Handle<JSObject>(JSObject::cast(site->transition_info()), isolate); |
494 } | 392 } |
495 | 393 |
496 AllocationSiteUsageContext usage_context(isolate, site, true); | 394 AllocationSiteUsageContext usage_context(isolate, site, true); |
497 usage_context.EnterNewScope(); | 395 usage_context.EnterNewScope(); |
498 MaybeHandle<Object> maybe_copy = JSObject::DeepCopy( | 396 MaybeHandle<Object> maybe_copy = |
499 boilerplate, &usage_context); | 397 JSObject::DeepCopy(boilerplate, &usage_context); |
500 usage_context.ExitScope(site, boilerplate); | 398 usage_context.ExitScope(site, boilerplate); |
501 Handle<Object> copy; | 399 Handle<Object> copy; |
502 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, copy, maybe_copy); | 400 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, copy, maybe_copy); |
503 return *copy; | 401 return *copy; |
504 } | 402 } |
505 | 403 |
506 | 404 |
507 MUST_USE_RESULT static MaybeHandle<AllocationSite> GetLiteralAllocationSite( | 405 MUST_USE_RESULT static MaybeHandle<AllocationSite> GetLiteralAllocationSite( |
508 Isolate* isolate, | 406 Isolate* isolate, Handle<FixedArray> literals, int literals_index, |
509 Handle<FixedArray> literals, | |
510 int literals_index, | |
511 Handle<FixedArray> elements) { | 407 Handle<FixedArray> elements) { |
512 // Check if boilerplate exists. If not, create it first. | 408 // Check if boilerplate exists. If not, create it first. |
513 Handle<Object> literal_site(literals->get(literals_index), isolate); | 409 Handle<Object> literal_site(literals->get(literals_index), isolate); |
514 Handle<AllocationSite> site; | 410 Handle<AllocationSite> site; |
515 if (*literal_site == isolate->heap()->undefined_value()) { | 411 if (*literal_site == isolate->heap()->undefined_value()) { |
516 DCHECK(*elements != isolate->heap()->empty_fixed_array()); | 412 DCHECK(*elements != isolate->heap()->empty_fixed_array()); |
517 Handle<Object> boilerplate; | 413 Handle<Object> boilerplate; |
518 ASSIGN_RETURN_ON_EXCEPTION( | 414 ASSIGN_RETURN_ON_EXCEPTION( |
519 isolate, boilerplate, | 415 isolate, boilerplate, |
520 Runtime::CreateArrayLiteralBoilerplate(isolate, literals, elements), | 416 Runtime::CreateArrayLiteralBoilerplate(isolate, literals, elements), |
(...skipping 10 matching lines...) Expand all Loading... |
531 literals->set(literals_index, *site); | 427 literals->set(literals_index, *site); |
532 } else { | 428 } else { |
533 site = Handle<AllocationSite>::cast(literal_site); | 429 site = Handle<AllocationSite>::cast(literal_site); |
534 } | 430 } |
535 | 431 |
536 return site; | 432 return site; |
537 } | 433 } |
538 | 434 |
539 | 435 |
540 static MaybeHandle<JSObject> CreateArrayLiteralImpl(Isolate* isolate, | 436 static MaybeHandle<JSObject> CreateArrayLiteralImpl(Isolate* isolate, |
541 Handle<FixedArray> literals, | 437 Handle<FixedArray> literals, |
542 int literals_index, | 438 int literals_index, |
543 Handle<FixedArray> elements, | 439 Handle<FixedArray> elements, |
544 int flags) { | 440 int flags) { |
545 RUNTIME_ASSERT_HANDLIFIED(literals_index >= 0 && | 441 RUNTIME_ASSERT_HANDLIFIED( |
546 literals_index < literals->length(), JSObject); | 442 literals_index >= 0 && literals_index < literals->length(), JSObject); |
547 Handle<AllocationSite> site; | 443 Handle<AllocationSite> site; |
548 ASSIGN_RETURN_ON_EXCEPTION( | 444 ASSIGN_RETURN_ON_EXCEPTION( |
549 isolate, site, | 445 isolate, site, |
550 GetLiteralAllocationSite(isolate, literals, literals_index, elements), | 446 GetLiteralAllocationSite(isolate, literals, literals_index, elements), |
551 JSObject); | 447 JSObject); |
552 | 448 |
553 bool enable_mementos = (flags & ArrayLiteral::kDisableMementos) == 0; | 449 bool enable_mementos = (flags & ArrayLiteral::kDisableMementos) == 0; |
554 Handle<JSObject> boilerplate(JSObject::cast(site->transition_info())); | 450 Handle<JSObject> boilerplate(JSObject::cast(site->transition_info())); |
555 AllocationSiteUsageContext usage_context(isolate, site, enable_mementos); | 451 AllocationSiteUsageContext usage_context(isolate, site, enable_mementos); |
556 usage_context.EnterNewScope(); | 452 usage_context.EnterNewScope(); |
557 JSObject::DeepCopyHints hints = (flags & ArrayLiteral::kShallowElements) == 0 | 453 JSObject::DeepCopyHints hints = (flags & ArrayLiteral::kShallowElements) == 0 |
558 ? JSObject::kNoHints | 454 ? JSObject::kNoHints |
559 : JSObject::kObjectIsShallow; | 455 : JSObject::kObjectIsShallow; |
560 MaybeHandle<JSObject> copy = JSObject::DeepCopy(boilerplate, &usage_context, | 456 MaybeHandle<JSObject> copy = |
561 hints); | 457 JSObject::DeepCopy(boilerplate, &usage_context, hints); |
562 usage_context.ExitScope(site, boilerplate); | 458 usage_context.ExitScope(site, boilerplate); |
563 return copy; | 459 return copy; |
564 } | 460 } |
565 | 461 |
566 | 462 |
567 RUNTIME_FUNCTION(Runtime_CreateArrayLiteral) { | 463 RUNTIME_FUNCTION(Runtime_CreateArrayLiteral) { |
568 HandleScope scope(isolate); | 464 HandleScope scope(isolate); |
569 DCHECK(args.length() == 4); | 465 DCHECK(args.length() == 4); |
570 CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0); | 466 CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0); |
571 CONVERT_SMI_ARG_CHECKED(literals_index, 1); | 467 CONVERT_SMI_ARG_CHECKED(literals_index, 1); |
572 CONVERT_ARG_HANDLE_CHECKED(FixedArray, elements, 2); | 468 CONVERT_ARG_HANDLE_CHECKED(FixedArray, elements, 2); |
573 CONVERT_SMI_ARG_CHECKED(flags, 3); | 469 CONVERT_SMI_ARG_CHECKED(flags, 3); |
574 | 470 |
575 Handle<JSObject> result; | 471 Handle<JSObject> result; |
576 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, | 472 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
577 CreateArrayLiteralImpl(isolate, literals, literals_index, elements, | 473 isolate, result, CreateArrayLiteralImpl(isolate, literals, literals_index, |
578 flags)); | 474 elements, flags)); |
579 return *result; | 475 return *result; |
580 } | 476 } |
581 | 477 |
582 | 478 |
583 RUNTIME_FUNCTION(Runtime_CreateArrayLiteralStubBailout) { | 479 RUNTIME_FUNCTION(Runtime_CreateArrayLiteralStubBailout) { |
584 HandleScope scope(isolate); | 480 HandleScope scope(isolate); |
585 DCHECK(args.length() == 3); | 481 DCHECK(args.length() == 3); |
586 CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0); | 482 CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0); |
587 CONVERT_SMI_ARG_CHECKED(literals_index, 1); | 483 CONVERT_SMI_ARG_CHECKED(literals_index, 1); |
588 CONVERT_ARG_HANDLE_CHECKED(FixedArray, elements, 2); | 484 CONVERT_ARG_HANDLE_CHECKED(FixedArray, elements, 2); |
589 | 485 |
590 Handle<JSObject> result; | 486 Handle<JSObject> result; |
591 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, | 487 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
592 CreateArrayLiteralImpl(isolate, literals, literals_index, elements, | 488 isolate, result, |
593 ArrayLiteral::kShallowElements)); | 489 CreateArrayLiteralImpl(isolate, literals, literals_index, elements, |
| 490 ArrayLiteral::kShallowElements)); |
594 return *result; | 491 return *result; |
595 } | 492 } |
596 | 493 |
597 | 494 |
598 RUNTIME_FUNCTION(Runtime_CreateSymbol) { | 495 RUNTIME_FUNCTION(Runtime_CreateSymbol) { |
599 HandleScope scope(isolate); | 496 HandleScope scope(isolate); |
600 DCHECK(args.length() == 1); | 497 DCHECK(args.length() == 1); |
601 CONVERT_ARG_HANDLE_CHECKED(Object, name, 0); | 498 CONVERT_ARG_HANDLE_CHECKED(Object, name, 0); |
602 RUNTIME_ASSERT(name->IsString() || name->IsUndefined()); | 499 RUNTIME_ASSERT(name->IsString() || name->IsUndefined()); |
603 Handle<Symbol> symbol = isolate->factory()->NewSymbol(); | 500 Handle<Symbol> symbol = isolate->factory()->NewSymbol(); |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
695 | 592 |
696 RUNTIME_FUNCTION(Runtime_CreateJSFunctionProxy) { | 593 RUNTIME_FUNCTION(Runtime_CreateJSFunctionProxy) { |
697 HandleScope scope(isolate); | 594 HandleScope scope(isolate); |
698 DCHECK(args.length() == 4); | 595 DCHECK(args.length() == 4); |
699 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, handler, 0); | 596 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, handler, 0); |
700 CONVERT_ARG_HANDLE_CHECKED(Object, call_trap, 1); | 597 CONVERT_ARG_HANDLE_CHECKED(Object, call_trap, 1); |
701 RUNTIME_ASSERT(call_trap->IsJSFunction() || call_trap->IsJSFunctionProxy()); | 598 RUNTIME_ASSERT(call_trap->IsJSFunction() || call_trap->IsJSFunctionProxy()); |
702 CONVERT_ARG_HANDLE_CHECKED(JSFunction, construct_trap, 2); | 599 CONVERT_ARG_HANDLE_CHECKED(JSFunction, construct_trap, 2); |
703 CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 3); | 600 CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 3); |
704 if (!prototype->IsJSReceiver()) prototype = isolate->factory()->null_value(); | 601 if (!prototype->IsJSReceiver()) prototype = isolate->factory()->null_value(); |
705 return *isolate->factory()->NewJSFunctionProxy( | 602 return *isolate->factory()->NewJSFunctionProxy(handler, call_trap, |
706 handler, call_trap, construct_trap, prototype); | 603 construct_trap, prototype); |
707 } | 604 } |
708 | 605 |
709 | 606 |
710 RUNTIME_FUNCTION(Runtime_IsJSProxy) { | 607 RUNTIME_FUNCTION(Runtime_IsJSProxy) { |
711 SealHandleScope shs(isolate); | 608 SealHandleScope shs(isolate); |
712 DCHECK(args.length() == 1); | 609 DCHECK(args.length() == 1); |
713 CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0); | 610 CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0); |
714 return isolate->heap()->ToBoolean(obj->IsJSProxy()); | 611 return isolate->heap()->ToBoolean(obj->IsJSProxy()); |
715 } | 612 } |
716 | 613 |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
757 | 654 |
758 | 655 |
759 void Runtime::FreeArrayBuffer(Isolate* isolate, | 656 void Runtime::FreeArrayBuffer(Isolate* isolate, |
760 JSArrayBuffer* phantom_array_buffer) { | 657 JSArrayBuffer* phantom_array_buffer) { |
761 if (phantom_array_buffer->should_be_freed()) { | 658 if (phantom_array_buffer->should_be_freed()) { |
762 DCHECK(phantom_array_buffer->is_external()); | 659 DCHECK(phantom_array_buffer->is_external()); |
763 free(phantom_array_buffer->backing_store()); | 660 free(phantom_array_buffer->backing_store()); |
764 } | 661 } |
765 if (phantom_array_buffer->is_external()) return; | 662 if (phantom_array_buffer->is_external()) return; |
766 | 663 |
767 size_t allocated_length = NumberToSize( | 664 size_t allocated_length = |
768 isolate, phantom_array_buffer->byte_length()); | 665 NumberToSize(isolate, phantom_array_buffer->byte_length()); |
769 | 666 |
770 reinterpret_cast<v8::Isolate*>(isolate) | 667 reinterpret_cast<v8::Isolate*>(isolate) |
771 ->AdjustAmountOfExternalAllocatedMemory( | 668 ->AdjustAmountOfExternalAllocatedMemory( |
772 -static_cast<int64_t>(allocated_length)); | 669 -static_cast<int64_t>(allocated_length)); |
773 CHECK(V8::ArrayBufferAllocator() != NULL); | 670 CHECK(V8::ArrayBufferAllocator() != NULL); |
774 V8::ArrayBufferAllocator()->Free( | 671 V8::ArrayBufferAllocator()->Free(phantom_array_buffer->backing_store(), |
775 phantom_array_buffer->backing_store(), | 672 allocated_length); |
776 allocated_length); | |
777 } | 673 } |
778 | 674 |
779 | 675 |
780 void Runtime::SetupArrayBuffer(Isolate* isolate, | 676 void Runtime::SetupArrayBuffer(Isolate* isolate, |
781 Handle<JSArrayBuffer> array_buffer, | 677 Handle<JSArrayBuffer> array_buffer, |
782 bool is_external, | 678 bool is_external, void* data, |
783 void* data, | |
784 size_t allocated_length) { | 679 size_t allocated_length) { |
785 DCHECK(array_buffer->GetInternalFieldCount() == | 680 DCHECK(array_buffer->GetInternalFieldCount() == |
786 v8::ArrayBuffer::kInternalFieldCount); | 681 v8::ArrayBuffer::kInternalFieldCount); |
787 for (int i = 0; i < v8::ArrayBuffer::kInternalFieldCount; i++) { | 682 for (int i = 0; i < v8::ArrayBuffer::kInternalFieldCount; i++) { |
788 array_buffer->SetInternalField(i, Smi::FromInt(0)); | 683 array_buffer->SetInternalField(i, Smi::FromInt(0)); |
789 } | 684 } |
790 array_buffer->set_backing_store(data); | 685 array_buffer->set_backing_store(data); |
791 array_buffer->set_flag(Smi::FromInt(0)); | 686 array_buffer->set_flag(Smi::FromInt(0)); |
792 array_buffer->set_is_external(is_external); | 687 array_buffer->set_is_external(is_external); |
793 | 688 |
794 Handle<Object> byte_length = | 689 Handle<Object> byte_length = |
795 isolate->factory()->NewNumberFromSize(allocated_length); | 690 isolate->factory()->NewNumberFromSize(allocated_length); |
796 CHECK(byte_length->IsSmi() || byte_length->IsHeapNumber()); | 691 CHECK(byte_length->IsSmi() || byte_length->IsHeapNumber()); |
797 array_buffer->set_byte_length(*byte_length); | 692 array_buffer->set_byte_length(*byte_length); |
798 | 693 |
799 array_buffer->set_weak_next(isolate->heap()->array_buffers_list()); | 694 array_buffer->set_weak_next(isolate->heap()->array_buffers_list()); |
800 isolate->heap()->set_array_buffers_list(*array_buffer); | 695 isolate->heap()->set_array_buffers_list(*array_buffer); |
801 array_buffer->set_weak_first_view(isolate->heap()->undefined_value()); | 696 array_buffer->set_weak_first_view(isolate->heap()->undefined_value()); |
802 } | 697 } |
803 | 698 |
804 | 699 |
805 bool Runtime::SetupArrayBufferAllocatingData( | 700 bool Runtime::SetupArrayBufferAllocatingData(Isolate* isolate, |
806 Isolate* isolate, | 701 Handle<JSArrayBuffer> array_buffer, |
807 Handle<JSArrayBuffer> array_buffer, | 702 size_t allocated_length, |
808 size_t allocated_length, | 703 bool initialize) { |
809 bool initialize) { | |
810 void* data; | 704 void* data; |
811 CHECK(V8::ArrayBufferAllocator() != NULL); | 705 CHECK(V8::ArrayBufferAllocator() != NULL); |
812 if (allocated_length != 0) { | 706 if (allocated_length != 0) { |
813 if (initialize) { | 707 if (initialize) { |
814 data = V8::ArrayBufferAllocator()->Allocate(allocated_length); | 708 data = V8::ArrayBufferAllocator()->Allocate(allocated_length); |
815 } else { | 709 } else { |
816 data = | 710 data = |
817 V8::ArrayBufferAllocator()->AllocateUninitialized(allocated_length); | 711 V8::ArrayBufferAllocator()->AllocateUninitialized(allocated_length); |
818 } | 712 } |
819 if (data == NULL) return false; | 713 if (data == NULL) return false; |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
856 if (!holder->byte_length()->IsUndefined()) { | 750 if (!holder->byte_length()->IsUndefined()) { |
857 // ArrayBuffer is already initialized; probably a fuzz test. | 751 // ArrayBuffer is already initialized; probably a fuzz test. |
858 return *holder; | 752 return *holder; |
859 } | 753 } |
860 size_t allocated_length = 0; | 754 size_t allocated_length = 0; |
861 if (!TryNumberToSize(isolate, *byteLength, &allocated_length)) { | 755 if (!TryNumberToSize(isolate, *byteLength, &allocated_length)) { |
862 THROW_NEW_ERROR_RETURN_FAILURE( | 756 THROW_NEW_ERROR_RETURN_FAILURE( |
863 isolate, NewRangeError("invalid_array_buffer_length", | 757 isolate, NewRangeError("invalid_array_buffer_length", |
864 HandleVector<Object>(NULL, 0))); | 758 HandleVector<Object>(NULL, 0))); |
865 } | 759 } |
866 if (!Runtime::SetupArrayBufferAllocatingData(isolate, | 760 if (!Runtime::SetupArrayBufferAllocatingData(isolate, holder, |
867 holder, allocated_length)) { | 761 allocated_length)) { |
868 THROW_NEW_ERROR_RETURN_FAILURE( | 762 THROW_NEW_ERROR_RETURN_FAILURE( |
869 isolate, NewRangeError("invalid_array_buffer_length", | 763 isolate, NewRangeError("invalid_array_buffer_length", |
870 HandleVector<Object>(NULL, 0))); | 764 HandleVector<Object>(NULL, 0))); |
871 } | 765 } |
872 return *holder; | 766 return *holder; |
873 } | 767 } |
874 | 768 |
875 | 769 |
876 RUNTIME_FUNCTION(Runtime_ArrayBufferGetByteLength) { | 770 RUNTIME_FUNCTION(Runtime_ArrayBufferGetByteLength) { |
877 SealHandleScope shs(isolate); | 771 SealHandleScope shs(isolate); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
923 DCHECK(!array_buffer->is_external()); | 817 DCHECK(!array_buffer->is_external()); |
924 void* backing_store = array_buffer->backing_store(); | 818 void* backing_store = array_buffer->backing_store(); |
925 size_t byte_length = NumberToSize(isolate, array_buffer->byte_length()); | 819 size_t byte_length = NumberToSize(isolate, array_buffer->byte_length()); |
926 array_buffer->set_is_external(true); | 820 array_buffer->set_is_external(true); |
927 Runtime::NeuterArrayBuffer(array_buffer); | 821 Runtime::NeuterArrayBuffer(array_buffer); |
928 V8::ArrayBufferAllocator()->Free(backing_store, byte_length); | 822 V8::ArrayBufferAllocator()->Free(backing_store, byte_length); |
929 return isolate->heap()->undefined_value(); | 823 return isolate->heap()->undefined_value(); |
930 } | 824 } |
931 | 825 |
932 | 826 |
933 void Runtime::ArrayIdToTypeAndSize( | 827 void Runtime::ArrayIdToTypeAndSize(int arrayId, ExternalArrayType* array_type, |
934 int arrayId, | 828 ElementsKind* external_elements_kind, |
935 ExternalArrayType* array_type, | 829 ElementsKind* fixed_elements_kind, |
936 ElementsKind* external_elements_kind, | 830 size_t* element_size) { |
937 ElementsKind* fixed_elements_kind, | |
938 size_t* element_size) { | |
939 switch (arrayId) { | 831 switch (arrayId) { |
940 #define ARRAY_ID_CASE(Type, type, TYPE, ctype, size) \ | 832 #define ARRAY_ID_CASE(Type, type, TYPE, ctype, size) \ |
941 case ARRAY_ID_##TYPE: \ | 833 case ARRAY_ID_##TYPE: \ |
942 *array_type = kExternal##Type##Array; \ | 834 *array_type = kExternal##Type##Array; \ |
943 *external_elements_kind = EXTERNAL_##TYPE##_ELEMENTS; \ | 835 *external_elements_kind = EXTERNAL_##TYPE##_ELEMENTS; \ |
944 *fixed_elements_kind = TYPE##_ELEMENTS; \ | 836 *fixed_elements_kind = TYPE##_ELEMENTS; \ |
945 *element_size = size; \ | 837 *element_size = size; \ |
946 break; | 838 break; |
947 | 839 |
948 TYPED_ARRAYS(ARRAY_ID_CASE) | 840 TYPED_ARRAYS(ARRAY_ID_CASE) |
949 #undef ARRAY_ID_CASE | 841 #undef ARRAY_ID_CASE |
950 | 842 |
951 default: | 843 default: |
952 UNREACHABLE(); | 844 UNREACHABLE(); |
953 } | 845 } |
954 } | 846 } |
955 | 847 |
956 | 848 |
957 RUNTIME_FUNCTION(Runtime_TypedArrayInitialize) { | 849 RUNTIME_FUNCTION(Runtime_TypedArrayInitialize) { |
958 HandleScope scope(isolate); | 850 HandleScope scope(isolate); |
959 DCHECK(args.length() == 5); | 851 DCHECK(args.length() == 5); |
960 CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0); | 852 CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0); |
961 CONVERT_SMI_ARG_CHECKED(arrayId, 1); | 853 CONVERT_SMI_ARG_CHECKED(arrayId, 1); |
962 CONVERT_ARG_HANDLE_CHECKED(Object, maybe_buffer, 2); | 854 CONVERT_ARG_HANDLE_CHECKED(Object, maybe_buffer, 2); |
963 CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_offset_object, 3); | 855 CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_offset_object, 3); |
964 CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_length_object, 4); | 856 CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_length_object, 4); |
965 | 857 |
966 RUNTIME_ASSERT(arrayId >= Runtime::ARRAY_ID_FIRST && | 858 RUNTIME_ASSERT(arrayId >= Runtime::ARRAY_ID_FIRST && |
967 arrayId <= Runtime::ARRAY_ID_LAST); | 859 arrayId <= Runtime::ARRAY_ID_LAST); |
968 | 860 |
969 ExternalArrayType array_type = kExternalInt8Array; // Bogus initialization. | 861 ExternalArrayType array_type = kExternalInt8Array; // Bogus initialization. |
970 size_t element_size = 1; // Bogus initialization. | 862 size_t element_size = 1; // Bogus initialization. |
971 ElementsKind external_elements_kind = | 863 ElementsKind external_elements_kind = |
972 EXTERNAL_INT8_ELEMENTS; // Bogus initialization. | 864 EXTERNAL_INT8_ELEMENTS; // Bogus initialization. |
973 ElementsKind fixed_elements_kind = INT8_ELEMENTS; // Bogus initialization. | 865 ElementsKind fixed_elements_kind = INT8_ELEMENTS; // Bogus initialization. |
974 Runtime::ArrayIdToTypeAndSize(arrayId, | 866 Runtime::ArrayIdToTypeAndSize(arrayId, &array_type, &external_elements_kind, |
975 &array_type, | 867 &fixed_elements_kind, &element_size); |
976 &external_elements_kind, | |
977 &fixed_elements_kind, | |
978 &element_size); | |
979 RUNTIME_ASSERT(holder->map()->elements_kind() == fixed_elements_kind); | 868 RUNTIME_ASSERT(holder->map()->elements_kind() == fixed_elements_kind); |
980 | 869 |
981 size_t byte_offset = 0; | 870 size_t byte_offset = 0; |
982 size_t byte_length = 0; | 871 size_t byte_length = 0; |
983 RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_offset_object, &byte_offset)); | 872 RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_offset_object, &byte_offset)); |
984 RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_length_object, &byte_length)); | 873 RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_length_object, &byte_length)); |
985 | 874 |
986 if (maybe_buffer->IsJSArrayBuffer()) { | 875 if (maybe_buffer->IsJSArrayBuffer()) { |
987 Handle<JSArrayBuffer> buffer = Handle<JSArrayBuffer>::cast(maybe_buffer); | 876 Handle<JSArrayBuffer> buffer = Handle<JSArrayBuffer>::cast(maybe_buffer); |
988 size_t array_buffer_byte_length = | 877 size_t array_buffer_byte_length = |
989 NumberToSize(isolate, buffer->byte_length()); | 878 NumberToSize(isolate, buffer->byte_length()); |
990 RUNTIME_ASSERT(byte_offset <= array_buffer_byte_length); | 879 RUNTIME_ASSERT(byte_offset <= array_buffer_byte_length); |
991 RUNTIME_ASSERT(array_buffer_byte_length - byte_offset >= byte_length); | 880 RUNTIME_ASSERT(array_buffer_byte_length - byte_offset >= byte_length); |
992 } else { | 881 } else { |
993 RUNTIME_ASSERT(maybe_buffer->IsNull()); | 882 RUNTIME_ASSERT(maybe_buffer->IsNull()); |
994 } | 883 } |
995 | 884 |
996 RUNTIME_ASSERT(byte_length % element_size == 0); | 885 RUNTIME_ASSERT(byte_length % element_size == 0); |
997 size_t length = byte_length / element_size; | 886 size_t length = byte_length / element_size; |
998 | 887 |
999 if (length > static_cast<unsigned>(Smi::kMaxValue)) { | 888 if (length > static_cast<unsigned>(Smi::kMaxValue)) { |
1000 THROW_NEW_ERROR_RETURN_FAILURE( | 889 THROW_NEW_ERROR_RETURN_FAILURE( |
1001 isolate, NewRangeError("invalid_typed_array_length", | 890 isolate, NewRangeError("invalid_typed_array_length", |
1002 HandleVector<Object>(NULL, 0))); | 891 HandleVector<Object>(NULL, 0))); |
1003 } | 892 } |
1004 | 893 |
1005 // All checks are done, now we can modify objects. | 894 // All checks are done, now we can modify objects. |
1006 | 895 |
1007 DCHECK(holder->GetInternalFieldCount() == | 896 DCHECK(holder->GetInternalFieldCount() == |
1008 v8::ArrayBufferView::kInternalFieldCount); | 897 v8::ArrayBufferView::kInternalFieldCount); |
1009 for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) { | 898 for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) { |
1010 holder->SetInternalField(i, Smi::FromInt(0)); | 899 holder->SetInternalField(i, Smi::FromInt(0)); |
1011 } | 900 } |
1012 Handle<Object> length_obj = isolate->factory()->NewNumberFromSize(length); | 901 Handle<Object> length_obj = isolate->factory()->NewNumberFromSize(length); |
1013 holder->set_length(*length_obj); | 902 holder->set_length(*length_obj); |
1014 holder->set_byte_offset(*byte_offset_object); | 903 holder->set_byte_offset(*byte_offset_object); |
1015 holder->set_byte_length(*byte_length_object); | 904 holder->set_byte_length(*byte_length_object); |
1016 | 905 |
1017 if (!maybe_buffer->IsNull()) { | 906 if (!maybe_buffer->IsNull()) { |
1018 Handle<JSArrayBuffer> buffer = Handle<JSArrayBuffer>::cast(maybe_buffer); | 907 Handle<JSArrayBuffer> buffer = Handle<JSArrayBuffer>::cast(maybe_buffer); |
1019 holder->set_buffer(*buffer); | 908 holder->set_buffer(*buffer); |
1020 holder->set_weak_next(buffer->weak_first_view()); | 909 holder->set_weak_next(buffer->weak_first_view()); |
1021 buffer->set_weak_first_view(*holder); | 910 buffer->set_weak_first_view(*holder); |
1022 | 911 |
1023 Handle<ExternalArray> elements = | 912 Handle<ExternalArray> elements = isolate->factory()->NewExternalArray( |
1024 isolate->factory()->NewExternalArray( | 913 static_cast<int>(length), array_type, |
1025 static_cast<int>(length), array_type, | 914 static_cast<uint8_t*>(buffer->backing_store()) + byte_offset); |
1026 static_cast<uint8_t*>(buffer->backing_store()) + byte_offset); | |
1027 Handle<Map> map = | 915 Handle<Map> map = |
1028 JSObject::GetElementsTransitionMap(holder, external_elements_kind); | 916 JSObject::GetElementsTransitionMap(holder, external_elements_kind); |
1029 JSObject::SetMapAndElements(holder, map, elements); | 917 JSObject::SetMapAndElements(holder, map, elements); |
1030 DCHECK(IsExternalArrayElementsKind(holder->map()->elements_kind())); | 918 DCHECK(IsExternalArrayElementsKind(holder->map()->elements_kind())); |
1031 } else { | 919 } else { |
1032 holder->set_buffer(Smi::FromInt(0)); | 920 holder->set_buffer(Smi::FromInt(0)); |
1033 holder->set_weak_next(isolate->heap()->undefined_value()); | 921 holder->set_weak_next(isolate->heap()->undefined_value()); |
1034 Handle<FixedTypedArrayBase> elements = | 922 Handle<FixedTypedArrayBase> elements = |
1035 isolate->factory()->NewFixedTypedArray( | 923 isolate->factory()->NewFixedTypedArray(static_cast<int>(length), |
1036 static_cast<int>(length), array_type); | 924 array_type); |
1037 holder->set_elements(*elements); | 925 holder->set_elements(*elements); |
1038 } | 926 } |
1039 return isolate->heap()->undefined_value(); | 927 return isolate->heap()->undefined_value(); |
1040 } | 928 } |
1041 | 929 |
1042 | 930 |
1043 // Initializes a typed array from an array-like object. | 931 // Initializes a typed array from an array-like object. |
1044 // If an array-like object happens to be a typed array of the same type, | 932 // If an array-like object happens to be a typed array of the same type, |
1045 // initializes backing store using memove. | 933 // initializes backing store using memove. |
1046 // | 934 // |
1047 // Returns true if backing store was initialized or false otherwise. | 935 // Returns true if backing store was initialized or false otherwise. |
1048 RUNTIME_FUNCTION(Runtime_TypedArrayInitializeFromArrayLike) { | 936 RUNTIME_FUNCTION(Runtime_TypedArrayInitializeFromArrayLike) { |
1049 HandleScope scope(isolate); | 937 HandleScope scope(isolate); |
1050 DCHECK(args.length() == 4); | 938 DCHECK(args.length() == 4); |
1051 CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0); | 939 CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0); |
1052 CONVERT_SMI_ARG_CHECKED(arrayId, 1); | 940 CONVERT_SMI_ARG_CHECKED(arrayId, 1); |
1053 CONVERT_ARG_HANDLE_CHECKED(Object, source, 2); | 941 CONVERT_ARG_HANDLE_CHECKED(Object, source, 2); |
1054 CONVERT_NUMBER_ARG_HANDLE_CHECKED(length_obj, 3); | 942 CONVERT_NUMBER_ARG_HANDLE_CHECKED(length_obj, 3); |
1055 | 943 |
1056 RUNTIME_ASSERT(arrayId >= Runtime::ARRAY_ID_FIRST && | 944 RUNTIME_ASSERT(arrayId >= Runtime::ARRAY_ID_FIRST && |
1057 arrayId <= Runtime::ARRAY_ID_LAST); | 945 arrayId <= Runtime::ARRAY_ID_LAST); |
1058 | 946 |
1059 ExternalArrayType array_type = kExternalInt8Array; // Bogus initialization. | 947 ExternalArrayType array_type = kExternalInt8Array; // Bogus initialization. |
1060 size_t element_size = 1; // Bogus initialization. | 948 size_t element_size = 1; // Bogus initialization. |
1061 ElementsKind external_elements_kind = | 949 ElementsKind external_elements_kind = |
1062 EXTERNAL_INT8_ELEMENTS; // Bogus intialization. | 950 EXTERNAL_INT8_ELEMENTS; // Bogus intialization. |
1063 ElementsKind fixed_elements_kind = INT8_ELEMENTS; // Bogus initialization. | 951 ElementsKind fixed_elements_kind = INT8_ELEMENTS; // Bogus initialization. |
1064 Runtime::ArrayIdToTypeAndSize(arrayId, | 952 Runtime::ArrayIdToTypeAndSize(arrayId, &array_type, &external_elements_kind, |
1065 &array_type, | 953 &fixed_elements_kind, &element_size); |
1066 &external_elements_kind, | |
1067 &fixed_elements_kind, | |
1068 &element_size); | |
1069 | 954 |
1070 RUNTIME_ASSERT(holder->map()->elements_kind() == fixed_elements_kind); | 955 RUNTIME_ASSERT(holder->map()->elements_kind() == fixed_elements_kind); |
1071 | 956 |
1072 Handle<JSArrayBuffer> buffer = isolate->factory()->NewJSArrayBuffer(); | 957 Handle<JSArrayBuffer> buffer = isolate->factory()->NewJSArrayBuffer(); |
1073 if (source->IsJSTypedArray() && | 958 if (source->IsJSTypedArray() && |
1074 JSTypedArray::cast(*source)->type() == array_type) { | 959 JSTypedArray::cast(*source)->type() == array_type) { |
1075 length_obj = Handle<Object>(JSTypedArray::cast(*source)->length(), isolate); | 960 length_obj = Handle<Object>(JSTypedArray::cast(*source)->length(), isolate); |
1076 } | 961 } |
1077 size_t length = 0; | 962 size_t length = 0; |
1078 RUNTIME_ASSERT(TryNumberToSize(isolate, *length_obj, &length)); | 963 RUNTIME_ASSERT(TryNumberToSize(isolate, *length_obj, &length)); |
1079 | 964 |
1080 if ((length > static_cast<unsigned>(Smi::kMaxValue)) || | 965 if ((length > static_cast<unsigned>(Smi::kMaxValue)) || |
1081 (length > (kMaxInt / element_size))) { | 966 (length > (kMaxInt / element_size))) { |
1082 THROW_NEW_ERROR_RETURN_FAILURE( | 967 THROW_NEW_ERROR_RETURN_FAILURE( |
1083 isolate, NewRangeError("invalid_typed_array_length", | 968 isolate, NewRangeError("invalid_typed_array_length", |
1084 HandleVector<Object>(NULL, 0))); | 969 HandleVector<Object>(NULL, 0))); |
1085 } | 970 } |
1086 size_t byte_length = length * element_size; | 971 size_t byte_length = length * element_size; |
1087 | 972 |
1088 DCHECK(holder->GetInternalFieldCount() == | 973 DCHECK(holder->GetInternalFieldCount() == |
1089 v8::ArrayBufferView::kInternalFieldCount); | 974 v8::ArrayBufferView::kInternalFieldCount); |
1090 for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) { | 975 for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) { |
1091 holder->SetInternalField(i, Smi::FromInt(0)); | 976 holder->SetInternalField(i, Smi::FromInt(0)); |
1092 } | 977 } |
1093 | 978 |
1094 // NOTE: not initializing backing store. | 979 // NOTE: not initializing backing store. |
1095 // We assume that the caller of this function will initialize holder | 980 // We assume that the caller of this function will initialize holder |
1096 // with the loop | 981 // with the loop |
1097 // for(i = 0; i < length; i++) { holder[i] = source[i]; } | 982 // for(i = 0; i < length; i++) { holder[i] = source[i]; } |
1098 // We assume that the caller of this function is always a typed array | 983 // We assume that the caller of this function is always a typed array |
1099 // constructor. | 984 // constructor. |
1100 // If source is a typed array, this loop will always run to completion, | 985 // If source is a typed array, this loop will always run to completion, |
1101 // so we are sure that the backing store will be initialized. | 986 // so we are sure that the backing store will be initialized. |
1102 // Otherwise, the indexing operation might throw, so the loop will not | 987 // Otherwise, the indexing operation might throw, so the loop will not |
1103 // run to completion and the typed array might remain partly initialized. | 988 // run to completion and the typed array might remain partly initialized. |
1104 // However we further assume that the caller of this function is a typed array | 989 // However we further assume that the caller of this function is a typed array |
1105 // constructor, and the exception will propagate out of the constructor, | 990 // constructor, and the exception will propagate out of the constructor, |
1106 // therefore uninitialized memory will not be accessible by a user program. | 991 // therefore uninitialized memory will not be accessible by a user program. |
1107 // | 992 // |
1108 // TODO(dslomov): revise this once we support subclassing. | 993 // TODO(dslomov): revise this once we support subclassing. |
1109 | 994 |
1110 if (!Runtime::SetupArrayBufferAllocatingData( | 995 if (!Runtime::SetupArrayBufferAllocatingData(isolate, buffer, byte_length, |
1111 isolate, buffer, byte_length, false)) { | 996 false)) { |
1112 THROW_NEW_ERROR_RETURN_FAILURE( | 997 THROW_NEW_ERROR_RETURN_FAILURE( |
1113 isolate, NewRangeError("invalid_array_buffer_length", | 998 isolate, NewRangeError("invalid_array_buffer_length", |
1114 HandleVector<Object>(NULL, 0))); | 999 HandleVector<Object>(NULL, 0))); |
1115 } | 1000 } |
1116 | 1001 |
1117 holder->set_buffer(*buffer); | 1002 holder->set_buffer(*buffer); |
1118 holder->set_byte_offset(Smi::FromInt(0)); | 1003 holder->set_byte_offset(Smi::FromInt(0)); |
1119 Handle<Object> byte_length_obj( | 1004 Handle<Object> byte_length_obj( |
1120 isolate->factory()->NewNumberFromSize(byte_length)); | 1005 isolate->factory()->NewNumberFromSize(byte_length)); |
1121 holder->set_byte_length(*byte_length_obj); | 1006 holder->set_byte_length(*byte_length_obj); |
1122 holder->set_length(*length_obj); | 1007 holder->set_length(*length_obj); |
1123 holder->set_weak_next(buffer->weak_first_view()); | 1008 holder->set_weak_next(buffer->weak_first_view()); |
1124 buffer->set_weak_first_view(*holder); | 1009 buffer->set_weak_first_view(*holder); |
1125 | 1010 |
1126 Handle<ExternalArray> elements = | 1011 Handle<ExternalArray> elements = isolate->factory()->NewExternalArray( |
1127 isolate->factory()->NewExternalArray( | 1012 static_cast<int>(length), array_type, |
1128 static_cast<int>(length), array_type, | 1013 static_cast<uint8_t*>(buffer->backing_store())); |
1129 static_cast<uint8_t*>(buffer->backing_store())); | 1014 Handle<Map> map = |
1130 Handle<Map> map = JSObject::GetElementsTransitionMap( | 1015 JSObject::GetElementsTransitionMap(holder, external_elements_kind); |
1131 holder, external_elements_kind); | |
1132 JSObject::SetMapAndElements(holder, map, elements); | 1016 JSObject::SetMapAndElements(holder, map, elements); |
1133 | 1017 |
1134 if (source->IsJSTypedArray()) { | 1018 if (source->IsJSTypedArray()) { |
1135 Handle<JSTypedArray> typed_array(JSTypedArray::cast(*source)); | 1019 Handle<JSTypedArray> typed_array(JSTypedArray::cast(*source)); |
1136 | 1020 |
1137 if (typed_array->type() == holder->type()) { | 1021 if (typed_array->type() == holder->type()) { |
1138 uint8_t* backing_store = | 1022 uint8_t* backing_store = |
1139 static_cast<uint8_t*>( | 1023 static_cast<uint8_t*>(typed_array->GetBuffer()->backing_store()); |
1140 typed_array->GetBuffer()->backing_store()); | |
1141 size_t source_byte_offset = | 1024 size_t source_byte_offset = |
1142 NumberToSize(isolate, typed_array->byte_offset()); | 1025 NumberToSize(isolate, typed_array->byte_offset()); |
1143 memcpy( | 1026 memcpy(buffer->backing_store(), backing_store + source_byte_offset, |
1144 buffer->backing_store(), | 1027 byte_length); |
1145 backing_store + source_byte_offset, | |
1146 byte_length); | |
1147 return isolate->heap()->true_value(); | 1028 return isolate->heap()->true_value(); |
1148 } | 1029 } |
1149 } | 1030 } |
1150 | 1031 |
1151 return isolate->heap()->false_value(); | 1032 return isolate->heap()->false_value(); |
1152 } | 1033 } |
1153 | 1034 |
1154 | 1035 |
1155 #define BUFFER_VIEW_GETTER(Type, getter, accessor) \ | 1036 #define BUFFER_VIEW_GETTER(Type, getter, accessor) \ |
1156 RUNTIME_FUNCTION(Runtime_##Type##Get##getter) { \ | 1037 RUNTIME_FUNCTION(Runtime_##Type##Get##getter) { \ |
1157 HandleScope scope(isolate); \ | 1038 HandleScope scope(isolate); \ |
1158 DCHECK(args.length() == 1); \ | 1039 DCHECK(args.length() == 1); \ |
1159 CONVERT_ARG_HANDLE_CHECKED(JS##Type, holder, 0); \ | 1040 CONVERT_ARG_HANDLE_CHECKED(JS##Type, holder, 0); \ |
1160 return holder->accessor(); \ | 1041 return holder->accessor(); \ |
1161 } | 1042 } |
1162 | 1043 |
1163 BUFFER_VIEW_GETTER(ArrayBufferView, ByteLength, byte_length) | 1044 BUFFER_VIEW_GETTER(ArrayBufferView, ByteLength, byte_length) |
1164 BUFFER_VIEW_GETTER(ArrayBufferView, ByteOffset, byte_offset) | 1045 BUFFER_VIEW_GETTER(ArrayBufferView, ByteOffset, byte_offset) |
1165 BUFFER_VIEW_GETTER(TypedArray, Length, length) | 1046 BUFFER_VIEW_GETTER(TypedArray, Length, length) |
1166 BUFFER_VIEW_GETTER(DataView, Buffer, buffer) | 1047 BUFFER_VIEW_GETTER(DataView, Buffer, buffer) |
1167 | 1048 |
1168 #undef BUFFER_VIEW_GETTER | 1049 #undef BUFFER_VIEW_GETTER |
1169 | 1050 |
1170 RUNTIME_FUNCTION(Runtime_TypedArrayGetBuffer) { | 1051 RUNTIME_FUNCTION(Runtime_TypedArrayGetBuffer) { |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1217 if (offset > target_length || offset + source_length > target_length || | 1098 if (offset > target_length || offset + source_length > target_length || |
1218 offset + source_length < offset) { // overflow | 1099 offset + source_length < offset) { // overflow |
1219 THROW_NEW_ERROR_RETURN_FAILURE( | 1100 THROW_NEW_ERROR_RETURN_FAILURE( |
1220 isolate, NewRangeError("typed_array_set_source_too_large", | 1101 isolate, NewRangeError("typed_array_set_source_too_large", |
1221 HandleVector<Object>(NULL, 0))); | 1102 HandleVector<Object>(NULL, 0))); |
1222 } | 1103 } |
1223 | 1104 |
1224 size_t target_offset = NumberToSize(isolate, target->byte_offset()); | 1105 size_t target_offset = NumberToSize(isolate, target->byte_offset()); |
1225 size_t source_offset = NumberToSize(isolate, source->byte_offset()); | 1106 size_t source_offset = NumberToSize(isolate, source->byte_offset()); |
1226 uint8_t* target_base = | 1107 uint8_t* target_base = |
1227 static_cast<uint8_t*>( | 1108 static_cast<uint8_t*>(target->GetBuffer()->backing_store()) + |
1228 target->GetBuffer()->backing_store()) + target_offset; | 1109 target_offset; |
1229 uint8_t* source_base = | 1110 uint8_t* source_base = |
1230 static_cast<uint8_t*>( | 1111 static_cast<uint8_t*>(source->GetBuffer()->backing_store()) + |
1231 source->GetBuffer()->backing_store()) + source_offset; | 1112 source_offset; |
1232 | 1113 |
1233 // Typed arrays of the same type: use memmove. | 1114 // Typed arrays of the same type: use memmove. |
1234 if (target->type() == source->type()) { | 1115 if (target->type() == source->type()) { |
1235 memmove(target_base + offset * target->element_size(), | 1116 memmove(target_base + offset * target->element_size(), source_base, |
1236 source_base, source_byte_length); | 1117 source_byte_length); |
1237 return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_SAME_TYPE); | 1118 return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_SAME_TYPE); |
1238 } | 1119 } |
1239 | 1120 |
1240 // Typed arrays of different types over the same backing store | 1121 // Typed arrays of different types over the same backing store |
1241 if ((source_base <= target_base && | 1122 if ((source_base <= target_base && |
1242 source_base + source_byte_length > target_base) || | 1123 source_base + source_byte_length > target_base) || |
1243 (target_base <= source_base && | 1124 (target_base <= source_base && |
1244 target_base + target_byte_length > source_base)) { | 1125 target_base + target_byte_length > source_base)) { |
1245 // We do not support overlapping ArrayBuffers | 1126 // We do not support overlapping ArrayBuffers |
1246 DCHECK( | 1127 DCHECK(target->GetBuffer()->backing_store() == |
1247 target->GetBuffer()->backing_store() == | 1128 source->GetBuffer()->backing_store()); |
1248 source->GetBuffer()->backing_store()); | |
1249 return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_OVERLAPPING); | 1129 return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_OVERLAPPING); |
1250 } else { // Non-overlapping typed arrays | 1130 } else { // Non-overlapping typed arrays |
1251 return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_NONOVERLAPPING); | 1131 return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_NONOVERLAPPING); |
1252 } | 1132 } |
1253 } | 1133 } |
1254 | 1134 |
1255 | 1135 |
1256 RUNTIME_FUNCTION(Runtime_TypedArrayMaxSizeInHeap) { | 1136 RUNTIME_FUNCTION(Runtime_TypedArrayMaxSizeInHeap) { |
1257 DCHECK(args.length() == 0); | 1137 DCHECK(args.length() == 0); |
1258 DCHECK_OBJECT_SIZE( | 1138 DCHECK_OBJECT_SIZE(FLAG_typed_array_max_size_in_heap + |
1259 FLAG_typed_array_max_size_in_heap + FixedTypedArrayBase::kDataOffset); | 1139 FixedTypedArrayBase::kDataOffset); |
1260 return Smi::FromInt(FLAG_typed_array_max_size_in_heap); | 1140 return Smi::FromInt(FLAG_typed_array_max_size_in_heap); |
1261 } | 1141 } |
1262 | 1142 |
1263 | 1143 |
1264 RUNTIME_FUNCTION(Runtime_DataViewInitialize) { | 1144 RUNTIME_FUNCTION(Runtime_DataViewInitialize) { |
1265 HandleScope scope(isolate); | 1145 HandleScope scope(isolate); |
1266 DCHECK(args.length() == 4); | 1146 DCHECK(args.length() == 4); |
1267 CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0); | 1147 CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0); |
1268 CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, buffer, 1); | 1148 CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, buffer, 1); |
1269 CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_offset, 2); | 1149 CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_offset, 2); |
1270 CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_length, 3); | 1150 CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_length, 3); |
1271 | 1151 |
1272 DCHECK(holder->GetInternalFieldCount() == | 1152 DCHECK(holder->GetInternalFieldCount() == |
1273 v8::ArrayBufferView::kInternalFieldCount); | 1153 v8::ArrayBufferView::kInternalFieldCount); |
1274 for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) { | 1154 for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) { |
1275 holder->SetInternalField(i, Smi::FromInt(0)); | 1155 holder->SetInternalField(i, Smi::FromInt(0)); |
1276 } | 1156 } |
1277 size_t buffer_length = 0; | 1157 size_t buffer_length = 0; |
1278 size_t offset = 0; | 1158 size_t offset = 0; |
1279 size_t length = 0; | 1159 size_t length = 0; |
1280 RUNTIME_ASSERT( | 1160 RUNTIME_ASSERT( |
1281 TryNumberToSize(isolate, buffer->byte_length(), &buffer_length)); | 1161 TryNumberToSize(isolate, buffer->byte_length(), &buffer_length)); |
1282 RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_offset, &offset)); | 1162 RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_offset, &offset)); |
1283 RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_length, &length)); | 1163 RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_length, &length)); |
(...skipping 18 matching lines...) Expand all Loading... |
1302 | 1182 |
1303 inline static bool NeedToFlipBytes(bool is_little_endian) { | 1183 inline static bool NeedToFlipBytes(bool is_little_endian) { |
1304 #ifdef V8_TARGET_LITTLE_ENDIAN | 1184 #ifdef V8_TARGET_LITTLE_ENDIAN |
1305 return !is_little_endian; | 1185 return !is_little_endian; |
1306 #else | 1186 #else |
1307 return is_little_endian; | 1187 return is_little_endian; |
1308 #endif | 1188 #endif |
1309 } | 1189 } |
1310 | 1190 |
1311 | 1191 |
1312 template<int n> | 1192 template <int n> |
1313 inline void CopyBytes(uint8_t* target, uint8_t* source) { | 1193 inline void CopyBytes(uint8_t* target, uint8_t* source) { |
1314 for (int i = 0; i < n; i++) { | 1194 for (int i = 0; i < n; i++) { |
1315 *(target++) = *(source++); | 1195 *(target++) = *(source++); |
1316 } | 1196 } |
1317 } | 1197 } |
1318 | 1198 |
1319 | 1199 |
1320 template<int n> | 1200 template <int n> |
1321 inline void FlipBytes(uint8_t* target, uint8_t* source) { | 1201 inline void FlipBytes(uint8_t* target, uint8_t* source) { |
1322 source = source + (n-1); | 1202 source = source + (n - 1); |
1323 for (int i = 0; i < n; i++) { | 1203 for (int i = 0; i < n; i++) { |
1324 *(target++) = *(source--); | 1204 *(target++) = *(source--); |
1325 } | 1205 } |
1326 } | 1206 } |
1327 | 1207 |
1328 | 1208 |
1329 template<typename T> | 1209 template <typename T> |
1330 inline static bool DataViewGetValue( | 1210 inline static bool DataViewGetValue(Isolate* isolate, |
1331 Isolate* isolate, | 1211 Handle<JSDataView> data_view, |
1332 Handle<JSDataView> data_view, | 1212 Handle<Object> byte_offset_obj, |
1333 Handle<Object> byte_offset_obj, | 1213 bool is_little_endian, T* result) { |
1334 bool is_little_endian, | |
1335 T* result) { | |
1336 size_t byte_offset = 0; | 1214 size_t byte_offset = 0; |
1337 if (!TryNumberToSize(isolate, *byte_offset_obj, &byte_offset)) { | 1215 if (!TryNumberToSize(isolate, *byte_offset_obj, &byte_offset)) { |
1338 return false; | 1216 return false; |
1339 } | 1217 } |
1340 Handle<JSArrayBuffer> buffer(JSArrayBuffer::cast(data_view->buffer())); | 1218 Handle<JSArrayBuffer> buffer(JSArrayBuffer::cast(data_view->buffer())); |
1341 | 1219 |
1342 size_t data_view_byte_offset = | 1220 size_t data_view_byte_offset = |
1343 NumberToSize(isolate, data_view->byte_offset()); | 1221 NumberToSize(isolate, data_view->byte_offset()); |
1344 size_t data_view_byte_length = | 1222 size_t data_view_byte_length = |
1345 NumberToSize(isolate, data_view->byte_length()); | 1223 NumberToSize(isolate, data_view->byte_length()); |
1346 if (byte_offset + sizeof(T) > data_view_byte_length || | 1224 if (byte_offset + sizeof(T) > data_view_byte_length || |
1347 byte_offset + sizeof(T) < byte_offset) { // overflow | 1225 byte_offset + sizeof(T) < byte_offset) { // overflow |
1348 return false; | 1226 return false; |
1349 } | 1227 } |
1350 | 1228 |
1351 union Value { | 1229 union Value { |
1352 T data; | 1230 T data; |
1353 uint8_t bytes[sizeof(T)]; | 1231 uint8_t bytes[sizeof(T)]; |
1354 }; | 1232 }; |
1355 | 1233 |
1356 Value value; | 1234 Value value; |
1357 size_t buffer_offset = data_view_byte_offset + byte_offset; | 1235 size_t buffer_offset = data_view_byte_offset + byte_offset; |
1358 DCHECK( | 1236 DCHECK(NumberToSize(isolate, buffer->byte_length()) >= |
1359 NumberToSize(isolate, buffer->byte_length()) | 1237 buffer_offset + sizeof(T)); |
1360 >= buffer_offset + sizeof(T)); | |
1361 uint8_t* source = | 1238 uint8_t* source = |
1362 static_cast<uint8_t*>(buffer->backing_store()) + buffer_offset; | 1239 static_cast<uint8_t*>(buffer->backing_store()) + buffer_offset; |
1363 if (NeedToFlipBytes(is_little_endian)) { | 1240 if (NeedToFlipBytes(is_little_endian)) { |
1364 FlipBytes<sizeof(T)>(value.bytes, source); | 1241 FlipBytes<sizeof(T)>(value.bytes, source); |
1365 } else { | 1242 } else { |
1366 CopyBytes<sizeof(T)>(value.bytes, source); | 1243 CopyBytes<sizeof(T)>(value.bytes, source); |
1367 } | 1244 } |
1368 *result = value.data; | 1245 *result = value.data; |
1369 return true; | 1246 return true; |
1370 } | 1247 } |
1371 | 1248 |
1372 | 1249 |
1373 template<typename T> | 1250 template <typename T> |
1374 static bool DataViewSetValue( | 1251 static bool DataViewSetValue(Isolate* isolate, Handle<JSDataView> data_view, |
1375 Isolate* isolate, | 1252 Handle<Object> byte_offset_obj, |
1376 Handle<JSDataView> data_view, | 1253 bool is_little_endian, T data) { |
1377 Handle<Object> byte_offset_obj, | |
1378 bool is_little_endian, | |
1379 T data) { | |
1380 size_t byte_offset = 0; | 1254 size_t byte_offset = 0; |
1381 if (!TryNumberToSize(isolate, *byte_offset_obj, &byte_offset)) { | 1255 if (!TryNumberToSize(isolate, *byte_offset_obj, &byte_offset)) { |
1382 return false; | 1256 return false; |
1383 } | 1257 } |
1384 Handle<JSArrayBuffer> buffer(JSArrayBuffer::cast(data_view->buffer())); | 1258 Handle<JSArrayBuffer> buffer(JSArrayBuffer::cast(data_view->buffer())); |
1385 | 1259 |
1386 size_t data_view_byte_offset = | 1260 size_t data_view_byte_offset = |
1387 NumberToSize(isolate, data_view->byte_offset()); | 1261 NumberToSize(isolate, data_view->byte_offset()); |
1388 size_t data_view_byte_length = | 1262 size_t data_view_byte_length = |
1389 NumberToSize(isolate, data_view->byte_length()); | 1263 NumberToSize(isolate, data_view->byte_length()); |
1390 if (byte_offset + sizeof(T) > data_view_byte_length || | 1264 if (byte_offset + sizeof(T) > data_view_byte_length || |
1391 byte_offset + sizeof(T) < byte_offset) { // overflow | 1265 byte_offset + sizeof(T) < byte_offset) { // overflow |
1392 return false; | 1266 return false; |
1393 } | 1267 } |
1394 | 1268 |
1395 union Value { | 1269 union Value { |
1396 T data; | 1270 T data; |
1397 uint8_t bytes[sizeof(T)]; | 1271 uint8_t bytes[sizeof(T)]; |
1398 }; | 1272 }; |
1399 | 1273 |
1400 Value value; | 1274 Value value; |
1401 value.data = data; | 1275 value.data = data; |
1402 size_t buffer_offset = data_view_byte_offset + byte_offset; | 1276 size_t buffer_offset = data_view_byte_offset + byte_offset; |
1403 DCHECK( | 1277 DCHECK(NumberToSize(isolate, buffer->byte_length()) >= |
1404 NumberToSize(isolate, buffer->byte_length()) | 1278 buffer_offset + sizeof(T)); |
1405 >= buffer_offset + sizeof(T)); | |
1406 uint8_t* target = | 1279 uint8_t* target = |
1407 static_cast<uint8_t*>(buffer->backing_store()) + buffer_offset; | 1280 static_cast<uint8_t*>(buffer->backing_store()) + buffer_offset; |
1408 if (NeedToFlipBytes(is_little_endian)) { | 1281 if (NeedToFlipBytes(is_little_endian)) { |
1409 FlipBytes<sizeof(T)>(target, value.bytes); | 1282 FlipBytes<sizeof(T)>(target, value.bytes); |
1410 } else { | 1283 } else { |
1411 CopyBytes<sizeof(T)>(target, value.bytes); | 1284 CopyBytes<sizeof(T)>(target, value.bytes); |
1412 } | 1285 } |
1413 return true; | 1286 return true; |
1414 } | 1287 } |
1415 | 1288 |
1416 | 1289 |
1417 #define DATA_VIEW_GETTER(TypeName, Type, Converter) \ | 1290 #define DATA_VIEW_GETTER(TypeName, Type, Converter) \ |
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1694 return Smi::FromInt(table->NumberOfElements()); | 1567 return Smi::FromInt(table->NumberOfElements()); |
1695 } | 1568 } |
1696 | 1569 |
1697 | 1570 |
1698 RUNTIME_FUNCTION(Runtime_MapIteratorInitialize) { | 1571 RUNTIME_FUNCTION(Runtime_MapIteratorInitialize) { |
1699 HandleScope scope(isolate); | 1572 HandleScope scope(isolate); |
1700 DCHECK(args.length() == 3); | 1573 DCHECK(args.length() == 3); |
1701 CONVERT_ARG_HANDLE_CHECKED(JSMapIterator, holder, 0); | 1574 CONVERT_ARG_HANDLE_CHECKED(JSMapIterator, holder, 0); |
1702 CONVERT_ARG_HANDLE_CHECKED(JSMap, map, 1); | 1575 CONVERT_ARG_HANDLE_CHECKED(JSMap, map, 1); |
1703 CONVERT_SMI_ARG_CHECKED(kind, 2) | 1576 CONVERT_SMI_ARG_CHECKED(kind, 2) |
1704 RUNTIME_ASSERT(kind == JSMapIterator::kKindKeys | 1577 RUNTIME_ASSERT(kind == JSMapIterator::kKindKeys || |
1705 || kind == JSMapIterator::kKindValues | 1578 kind == JSMapIterator::kKindValues || |
1706 || kind == JSMapIterator::kKindEntries); | 1579 kind == JSMapIterator::kKindEntries); |
1707 Handle<OrderedHashMap> table(OrderedHashMap::cast(map->table())); | 1580 Handle<OrderedHashMap> table(OrderedHashMap::cast(map->table())); |
1708 holder->set_table(*table); | 1581 holder->set_table(*table); |
1709 holder->set_index(Smi::FromInt(0)); | 1582 holder->set_index(Smi::FromInt(0)); |
1710 holder->set_kind(Smi::FromInt(kind)); | 1583 holder->set_kind(Smi::FromInt(kind)); |
1711 return isolate->heap()->undefined_value(); | 1584 return isolate->heap()->undefined_value(); |
1712 } | 1585 } |
1713 | 1586 |
1714 | 1587 |
1715 RUNTIME_FUNCTION(Runtime_GetWeakMapEntries) { | 1588 RUNTIME_FUNCTION(Runtime_GetWeakMapEntries) { |
1716 HandleScope scope(isolate); | 1589 HandleScope scope(isolate); |
(...skipping 22 matching lines...) Expand all Loading... |
1739 RUNTIME_FUNCTION(Runtime_MapIteratorNext) { | 1612 RUNTIME_FUNCTION(Runtime_MapIteratorNext) { |
1740 SealHandleScope shs(isolate); | 1613 SealHandleScope shs(isolate); |
1741 DCHECK(args.length() == 2); | 1614 DCHECK(args.length() == 2); |
1742 CONVERT_ARG_CHECKED(JSMapIterator, holder, 0); | 1615 CONVERT_ARG_CHECKED(JSMapIterator, holder, 0); |
1743 CONVERT_ARG_CHECKED(JSArray, value_array, 1); | 1616 CONVERT_ARG_CHECKED(JSArray, value_array, 1); |
1744 return holder->Next(value_array); | 1617 return holder->Next(value_array); |
1745 } | 1618 } |
1746 | 1619 |
1747 | 1620 |
1748 static Handle<JSWeakCollection> WeakCollectionInitialize( | 1621 static Handle<JSWeakCollection> WeakCollectionInitialize( |
1749 Isolate* isolate, | 1622 Isolate* isolate, Handle<JSWeakCollection> weak_collection) { |
1750 Handle<JSWeakCollection> weak_collection) { | |
1751 DCHECK(weak_collection->map()->inobject_properties() == 0); | 1623 DCHECK(weak_collection->map()->inobject_properties() == 0); |
1752 Handle<ObjectHashTable> table = ObjectHashTable::New(isolate, 0); | 1624 Handle<ObjectHashTable> table = ObjectHashTable::New(isolate, 0); |
1753 weak_collection->set_table(*table); | 1625 weak_collection->set_table(*table); |
1754 return weak_collection; | 1626 return weak_collection; |
1755 } | 1627 } |
1756 | 1628 |
1757 | 1629 |
1758 RUNTIME_FUNCTION(Runtime_WeakCollectionInitialize) { | 1630 RUNTIME_FUNCTION(Runtime_WeakCollectionInitialize) { |
1759 HandleScope scope(isolate); | 1631 HandleScope scope(isolate); |
1760 DCHECK(args.length() == 1); | 1632 DCHECK(args.length() == 1); |
(...skipping 29 matching lines...) Expand all Loading... |
1790 return isolate->heap()->ToBoolean(!lookup->IsTheHole()); | 1662 return isolate->heap()->ToBoolean(!lookup->IsTheHole()); |
1791 } | 1663 } |
1792 | 1664 |
1793 | 1665 |
1794 RUNTIME_FUNCTION(Runtime_WeakCollectionDelete) { | 1666 RUNTIME_FUNCTION(Runtime_WeakCollectionDelete) { |
1795 HandleScope scope(isolate); | 1667 HandleScope scope(isolate); |
1796 DCHECK(args.length() == 2); | 1668 DCHECK(args.length() == 2); |
1797 CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0); | 1669 CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0); |
1798 CONVERT_ARG_HANDLE_CHECKED(Object, key, 1); | 1670 CONVERT_ARG_HANDLE_CHECKED(Object, key, 1); |
1799 RUNTIME_ASSERT(key->IsJSReceiver() || key->IsSymbol()); | 1671 RUNTIME_ASSERT(key->IsJSReceiver() || key->IsSymbol()); |
1800 Handle<ObjectHashTable> table(ObjectHashTable::cast( | 1672 Handle<ObjectHashTable> table( |
1801 weak_collection->table())); | 1673 ObjectHashTable::cast(weak_collection->table())); |
1802 RUNTIME_ASSERT(table->IsKey(*key)); | 1674 RUNTIME_ASSERT(table->IsKey(*key)); |
1803 bool was_present = false; | 1675 bool was_present = false; |
1804 Handle<ObjectHashTable> new_table = | 1676 Handle<ObjectHashTable> new_table = |
1805 ObjectHashTable::Remove(table, key, &was_present); | 1677 ObjectHashTable::Remove(table, key, &was_present); |
1806 weak_collection->set_table(*new_table); | 1678 weak_collection->set_table(*new_table); |
1807 return isolate->heap()->ToBoolean(was_present); | 1679 return isolate->heap()->ToBoolean(was_present); |
1808 } | 1680 } |
1809 | 1681 |
1810 | 1682 |
1811 RUNTIME_FUNCTION(Runtime_WeakCollectionSet) { | 1683 RUNTIME_FUNCTION(Runtime_WeakCollectionSet) { |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1899 return *result; | 1771 return *result; |
1900 } | 1772 } |
1901 | 1773 |
1902 | 1774 |
1903 RUNTIME_FUNCTION(Runtime_SetPrototype) { | 1775 RUNTIME_FUNCTION(Runtime_SetPrototype) { |
1904 HandleScope scope(isolate); | 1776 HandleScope scope(isolate); |
1905 DCHECK(args.length() == 2); | 1777 DCHECK(args.length() == 2); |
1906 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); | 1778 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); |
1907 CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1); | 1779 CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1); |
1908 if (obj->IsAccessCheckNeeded() && | 1780 if (obj->IsAccessCheckNeeded() && |
1909 !isolate->MayNamedAccess( | 1781 !isolate->MayNamedAccess(obj, isolate->factory()->proto_string(), |
1910 obj, isolate->factory()->proto_string(), v8::ACCESS_SET)) { | 1782 v8::ACCESS_SET)) { |
1911 isolate->ReportFailedAccessCheck(obj, v8::ACCESS_SET); | 1783 isolate->ReportFailedAccessCheck(obj, v8::ACCESS_SET); |
1912 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); | 1784 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); |
1913 return isolate->heap()->undefined_value(); | 1785 return isolate->heap()->undefined_value(); |
1914 } | 1786 } |
1915 if (obj->map()->is_observed()) { | 1787 if (obj->map()->is_observed()) { |
1916 Handle<Object> old_value = GetPrototypeSkipHiddenPrototypes(isolate, obj); | 1788 Handle<Object> old_value = GetPrototypeSkipHiddenPrototypes(isolate, obj); |
1917 Handle<Object> result; | 1789 Handle<Object> result; |
1918 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 1790 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
1919 isolate, result, | 1791 isolate, result, JSObject::SetPrototype(obj, prototype, true)); |
1920 JSObject::SetPrototype(obj, prototype, true)); | |
1921 | 1792 |
1922 Handle<Object> new_value = GetPrototypeSkipHiddenPrototypes(isolate, obj); | 1793 Handle<Object> new_value = GetPrototypeSkipHiddenPrototypes(isolate, obj); |
1923 if (!new_value->SameValue(*old_value)) { | 1794 if (!new_value->SameValue(*old_value)) { |
1924 JSObject::EnqueueChangeRecord(obj, "setPrototype", | 1795 JSObject::EnqueueChangeRecord( |
1925 isolate->factory()->proto_string(), | 1796 obj, "setPrototype", isolate->factory()->proto_string(), old_value); |
1926 old_value); | |
1927 } | 1797 } |
1928 return *result; | 1798 return *result; |
1929 } | 1799 } |
1930 Handle<Object> result; | 1800 Handle<Object> result; |
1931 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 1801 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
1932 isolate, result, | 1802 isolate, result, JSObject::SetPrototype(obj, prototype, true)); |
1933 JSObject::SetPrototype(obj, prototype, true)); | |
1934 return *result; | 1803 return *result; |
1935 } | 1804 } |
1936 | 1805 |
1937 | 1806 |
1938 RUNTIME_FUNCTION(Runtime_IsInPrototypeChain) { | 1807 RUNTIME_FUNCTION(Runtime_IsInPrototypeChain) { |
1939 HandleScope shs(isolate); | 1808 HandleScope shs(isolate); |
1940 DCHECK(args.length() == 2); | 1809 DCHECK(args.length() == 2); |
1941 // See ECMA-262, section 15.3.5.3, page 88 (steps 5 - 8). | 1810 // See ECMA-262, section 15.3.5.3, page 88 (steps 5 - 8). |
1942 CONVERT_ARG_HANDLE_CHECKED(Object, O, 0); | 1811 CONVERT_ARG_HANDLE_CHECKED(Object, O, 0); |
1943 CONVERT_ARG_HANDLE_CHECKED(Object, V, 1); | 1812 CONVERT_ARG_HANDLE_CHECKED(Object, V, 1); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1981 JSReceiver::GetOwnElementAttribute(obj, index); | 1850 JSReceiver::GetOwnElementAttribute(obj, index); |
1982 if (!maybe.has_value) return MaybeHandle<Object>(); | 1851 if (!maybe.has_value) return MaybeHandle<Object>(); |
1983 attrs = maybe.value; | 1852 attrs = maybe.value; |
1984 if (attrs == ABSENT) return factory->undefined_value(); | 1853 if (attrs == ABSENT) return factory->undefined_value(); |
1985 | 1854 |
1986 // Get AccessorPair if present. | 1855 // Get AccessorPair if present. |
1987 maybe_accessors = JSObject::GetOwnElementAccessorPair(obj, index); | 1856 maybe_accessors = JSObject::GetOwnElementAccessorPair(obj, index); |
1988 | 1857 |
1989 // Get value if not an AccessorPair. | 1858 // Get value if not an AccessorPair. |
1990 if (maybe_accessors.is_null()) { | 1859 if (maybe_accessors.is_null()) { |
1991 ASSIGN_RETURN_ON_EXCEPTION(isolate, value, | 1860 ASSIGN_RETURN_ON_EXCEPTION( |
1992 Runtime::GetElementOrCharAt(isolate, obj, index), Object); | 1861 isolate, value, Runtime::GetElementOrCharAt(isolate, obj, index), |
| 1862 Object); |
1993 } | 1863 } |
1994 } else { | 1864 } else { |
1995 // Get attributes. | 1865 // Get attributes. |
1996 LookupIterator it(obj, name, LookupIterator::HIDDEN); | 1866 LookupIterator it(obj, name, LookupIterator::HIDDEN); |
1997 Maybe<PropertyAttributes> maybe = JSObject::GetPropertyAttributes(&it); | 1867 Maybe<PropertyAttributes> maybe = JSObject::GetPropertyAttributes(&it); |
1998 if (!maybe.has_value) return MaybeHandle<Object>(); | 1868 if (!maybe.has_value) return MaybeHandle<Object>(); |
1999 attrs = maybe.value; | 1869 attrs = maybe.value; |
2000 if (attrs == ABSENT) return factory->undefined_value(); | 1870 if (attrs == ABSENT) return factory->undefined_value(); |
2001 | 1871 |
2002 // Get AccessorPair if present. | 1872 // Get AccessorPair if present. |
2003 if (it.state() == LookupIterator::ACCESSOR && | 1873 if (it.state() == LookupIterator::ACCESSOR && |
2004 it.GetAccessors()->IsAccessorPair()) { | 1874 it.GetAccessors()->IsAccessorPair()) { |
2005 maybe_accessors = Handle<AccessorPair>::cast(it.GetAccessors()); | 1875 maybe_accessors = Handle<AccessorPair>::cast(it.GetAccessors()); |
2006 } | 1876 } |
2007 | 1877 |
2008 // Get value if not an AccessorPair. | 1878 // Get value if not an AccessorPair. |
2009 if (maybe_accessors.is_null()) { | 1879 if (maybe_accessors.is_null()) { |
2010 ASSIGN_RETURN_ON_EXCEPTION( | 1880 ASSIGN_RETURN_ON_EXCEPTION(isolate, value, Object::GetProperty(&it), |
2011 isolate, value, Object::GetProperty(&it), Object); | 1881 Object); |
2012 } | 1882 } |
2013 } | 1883 } |
2014 DCHECK(!isolate->has_pending_exception()); | 1884 DCHECK(!isolate->has_pending_exception()); |
2015 Handle<FixedArray> elms = factory->NewFixedArray(DESCRIPTOR_SIZE); | 1885 Handle<FixedArray> elms = factory->NewFixedArray(DESCRIPTOR_SIZE); |
2016 elms->set(ENUMERABLE_INDEX, heap->ToBoolean((attrs & DONT_ENUM) == 0)); | 1886 elms->set(ENUMERABLE_INDEX, heap->ToBoolean((attrs & DONT_ENUM) == 0)); |
2017 elms->set(CONFIGURABLE_INDEX, heap->ToBoolean((attrs & DONT_DELETE) == 0)); | 1887 elms->set(CONFIGURABLE_INDEX, heap->ToBoolean((attrs & DONT_DELETE) == 0)); |
2018 elms->set(IS_ACCESSOR_INDEX, heap->ToBoolean(!maybe_accessors.is_null())); | 1888 elms->set(IS_ACCESSOR_INDEX, heap->ToBoolean(!maybe_accessors.is_null())); |
2019 | 1889 |
2020 Handle<AccessorPair> accessors; | 1890 Handle<AccessorPair> accessors; |
2021 if (maybe_accessors.ToHandle(&accessors)) { | 1891 if (maybe_accessors.ToHandle(&accessors)) { |
(...skipping 16 matching lines...) Expand all Loading... |
2038 // if args[1] is a data property on args[0] | 1908 // if args[1] is a data property on args[0] |
2039 // [false, value, Writeable, Enumerable, Configurable] | 1909 // [false, value, Writeable, Enumerable, Configurable] |
2040 // if args[1] is an accessor on args[0] | 1910 // if args[1] is an accessor on args[0] |
2041 // [true, GetFunction, SetFunction, Enumerable, Configurable] | 1911 // [true, GetFunction, SetFunction, Enumerable, Configurable] |
2042 RUNTIME_FUNCTION(Runtime_GetOwnProperty) { | 1912 RUNTIME_FUNCTION(Runtime_GetOwnProperty) { |
2043 HandleScope scope(isolate); | 1913 HandleScope scope(isolate); |
2044 DCHECK(args.length() == 2); | 1914 DCHECK(args.length() == 2); |
2045 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); | 1915 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); |
2046 CONVERT_ARG_HANDLE_CHECKED(Name, name, 1); | 1916 CONVERT_ARG_HANDLE_CHECKED(Name, name, 1); |
2047 Handle<Object> result; | 1917 Handle<Object> result; |
2048 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 1918 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, |
2049 isolate, result, GetOwnProperty(isolate, obj, name)); | 1919 GetOwnProperty(isolate, obj, name)); |
2050 return *result; | 1920 return *result; |
2051 } | 1921 } |
2052 | 1922 |
2053 | 1923 |
2054 RUNTIME_FUNCTION(Runtime_PreventExtensions) { | 1924 RUNTIME_FUNCTION(Runtime_PreventExtensions) { |
2055 HandleScope scope(isolate); | 1925 HandleScope scope(isolate); |
2056 DCHECK(args.length() == 1); | 1926 DCHECK(args.length() == 1); |
2057 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); | 1927 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); |
2058 Handle<Object> result; | 1928 Handle<Object> result; |
2059 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 1929 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, |
2060 isolate, result, JSObject::PreventExtensions(obj)); | 1930 JSObject::PreventExtensions(obj)); |
2061 return *result; | 1931 return *result; |
2062 } | 1932 } |
2063 | 1933 |
2064 | 1934 |
2065 RUNTIME_FUNCTION(Runtime_ToMethod) { | 1935 RUNTIME_FUNCTION(Runtime_ToMethod) { |
2066 HandleScope scope(isolate); | 1936 HandleScope scope(isolate); |
2067 DCHECK(args.length() == 2); | 1937 DCHECK(args.length() == 2); |
2068 CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0); | 1938 CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0); |
2069 CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1); | 1939 CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1); |
2070 Handle<JSFunction> clone = JSFunction::CloneClosure(fun); | 1940 Handle<JSFunction> clone = JSFunction::CloneClosure(fun); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2119 } | 1989 } |
2120 | 1990 |
2121 | 1991 |
2122 RUNTIME_FUNCTION(Runtime_RegExpCompile) { | 1992 RUNTIME_FUNCTION(Runtime_RegExpCompile) { |
2123 HandleScope scope(isolate); | 1993 HandleScope scope(isolate); |
2124 DCHECK(args.length() == 3); | 1994 DCHECK(args.length() == 3); |
2125 CONVERT_ARG_HANDLE_CHECKED(JSRegExp, re, 0); | 1995 CONVERT_ARG_HANDLE_CHECKED(JSRegExp, re, 0); |
2126 CONVERT_ARG_HANDLE_CHECKED(String, pattern, 1); | 1996 CONVERT_ARG_HANDLE_CHECKED(String, pattern, 1); |
2127 CONVERT_ARG_HANDLE_CHECKED(String, flags, 2); | 1997 CONVERT_ARG_HANDLE_CHECKED(String, flags, 2); |
2128 Handle<Object> result; | 1998 Handle<Object> result; |
2129 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 1999 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, |
2130 isolate, result, RegExpImpl::Compile(re, pattern, flags)); | 2000 RegExpImpl::Compile(re, pattern, flags)); |
2131 return *result; | 2001 return *result; |
2132 } | 2002 } |
2133 | 2003 |
2134 | 2004 |
2135 RUNTIME_FUNCTION(Runtime_CreateApiFunction) { | 2005 RUNTIME_FUNCTION(Runtime_CreateApiFunction) { |
2136 HandleScope scope(isolate); | 2006 HandleScope scope(isolate); |
2137 DCHECK(args.length() == 2); | 2007 DCHECK(args.length() == 2); |
2138 CONVERT_ARG_HANDLE_CHECKED(FunctionTemplateInfo, data, 0); | 2008 CONVERT_ARG_HANDLE_CHECKED(FunctionTemplateInfo, data, 0); |
2139 CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1); | 2009 CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1); |
2140 return *isolate->factory()->CreateApiFunction(data, prototype); | 2010 return *isolate->factory()->CreateApiFunction(data, prototype); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2194 // Copy map so it won't interfere constructor's initial map. | 2064 // Copy map so it won't interfere constructor's initial map. |
2195 Handle<Map> new_map = Map::Copy(old_map); | 2065 Handle<Map> new_map = Map::Copy(old_map); |
2196 new_map->set_is_access_check_needed(true); | 2066 new_map->set_is_access_check_needed(true); |
2197 JSObject::MigrateToMap(object, new_map); | 2067 JSObject::MigrateToMap(object, new_map); |
2198 return isolate->heap()->undefined_value(); | 2068 return isolate->heap()->undefined_value(); |
2199 } | 2069 } |
2200 | 2070 |
2201 | 2071 |
2202 static Object* ThrowRedeclarationError(Isolate* isolate, Handle<String> name) { | 2072 static Object* ThrowRedeclarationError(Isolate* isolate, Handle<String> name) { |
2203 HandleScope scope(isolate); | 2073 HandleScope scope(isolate); |
2204 Handle<Object> args[1] = { name }; | 2074 Handle<Object> args[1] = {name}; |
2205 THROW_NEW_ERROR_RETURN_FAILURE( | 2075 THROW_NEW_ERROR_RETURN_FAILURE( |
2206 isolate, NewTypeError("var_redeclaration", HandleVector(args, 1))); | 2076 isolate, NewTypeError("var_redeclaration", HandleVector(args, 1))); |
2207 } | 2077 } |
2208 | 2078 |
2209 | 2079 |
2210 // May throw a RedeclarationError. | 2080 // May throw a RedeclarationError. |
2211 static Object* DeclareGlobals(Isolate* isolate, Handle<GlobalObject> global, | 2081 static Object* DeclareGlobals(Isolate* isolate, Handle<GlobalObject> global, |
2212 Handle<String> name, Handle<Object> value, | 2082 Handle<String> name, Handle<Object> value, |
2213 PropertyAttributes attr, bool is_var, | 2083 PropertyAttributes attr, bool is_var, |
2214 bool is_const, bool is_function) { | 2084 bool is_const, bool is_function) { |
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2550 } | 2420 } |
2551 | 2421 |
2552 | 2422 |
2553 RUNTIME_FUNCTION(Runtime_RegExpConstructResult) { | 2423 RUNTIME_FUNCTION(Runtime_RegExpConstructResult) { |
2554 HandleScope handle_scope(isolate); | 2424 HandleScope handle_scope(isolate); |
2555 DCHECK(args.length() == 3); | 2425 DCHECK(args.length() == 3); |
2556 CONVERT_SMI_ARG_CHECKED(size, 0); | 2426 CONVERT_SMI_ARG_CHECKED(size, 0); |
2557 RUNTIME_ASSERT(size >= 0 && size <= FixedArray::kMaxLength); | 2427 RUNTIME_ASSERT(size >= 0 && size <= FixedArray::kMaxLength); |
2558 CONVERT_ARG_HANDLE_CHECKED(Object, index, 1); | 2428 CONVERT_ARG_HANDLE_CHECKED(Object, index, 1); |
2559 CONVERT_ARG_HANDLE_CHECKED(Object, input, 2); | 2429 CONVERT_ARG_HANDLE_CHECKED(Object, input, 2); |
2560 Handle<FixedArray> elements = isolate->factory()->NewFixedArray(size); | 2430 Handle<FixedArray> elements = isolate->factory()->NewFixedArray(size); |
2561 Handle<Map> regexp_map(isolate->native_context()->regexp_result_map()); | 2431 Handle<Map> regexp_map(isolate->native_context()->regexp_result_map()); |
2562 Handle<JSObject> object = | 2432 Handle<JSObject> object = |
2563 isolate->factory()->NewJSObjectFromMap(regexp_map, NOT_TENURED, false); | 2433 isolate->factory()->NewJSObjectFromMap(regexp_map, NOT_TENURED, false); |
2564 Handle<JSArray> array = Handle<JSArray>::cast(object); | 2434 Handle<JSArray> array = Handle<JSArray>::cast(object); |
2565 array->set_elements(*elements); | 2435 array->set_elements(*elements); |
2566 array->set_length(Smi::FromInt(size)); | 2436 array->set_length(Smi::FromInt(size)); |
2567 // Write in-object properties after the length of the array. | 2437 // Write in-object properties after the length of the array. |
2568 array->InObjectPropertyAtPut(JSRegExpResult::kIndexIndex, *index); | 2438 array->InObjectPropertyAtPut(JSRegExpResult::kIndexIndex, *index); |
2569 array->InObjectPropertyAtPut(JSRegExpResult::kInputIndex, *input); | 2439 array->InObjectPropertyAtPut(JSRegExpResult::kInputIndex, *input); |
2570 return *array; | 2440 return *array; |
(...skipping 16 matching lines...) Expand all Loading... |
2587 if (!ignoreCase->IsTrue()) ignoreCase = isolate->factory()->false_value(); | 2457 if (!ignoreCase->IsTrue()) ignoreCase = isolate->factory()->false_value(); |
2588 | 2458 |
2589 CONVERT_ARG_HANDLE_CHECKED(Object, multiline, 4); | 2459 CONVERT_ARG_HANDLE_CHECKED(Object, multiline, 4); |
2590 if (!multiline->IsTrue()) multiline = isolate->factory()->false_value(); | 2460 if (!multiline->IsTrue()) multiline = isolate->factory()->false_value(); |
2591 | 2461 |
2592 CONVERT_ARG_HANDLE_CHECKED(Object, sticky, 5); | 2462 CONVERT_ARG_HANDLE_CHECKED(Object, sticky, 5); |
2593 if (!sticky->IsTrue()) sticky = isolate->factory()->false_value(); | 2463 if (!sticky->IsTrue()) sticky = isolate->factory()->false_value(); |
2594 | 2464 |
2595 Map* map = regexp->map(); | 2465 Map* map = regexp->map(); |
2596 Object* constructor = map->constructor(); | 2466 Object* constructor = map->constructor(); |
2597 if (!FLAG_harmony_regexps && | 2467 if (!FLAG_harmony_regexps && constructor->IsJSFunction() && |
2598 constructor->IsJSFunction() && | |
2599 JSFunction::cast(constructor)->initial_map() == map) { | 2468 JSFunction::cast(constructor)->initial_map() == map) { |
2600 // If we still have the original map, set in-object properties directly. | 2469 // If we still have the original map, set in-object properties directly. |
2601 regexp->InObjectPropertyAtPut(JSRegExp::kSourceFieldIndex, *source); | 2470 regexp->InObjectPropertyAtPut(JSRegExp::kSourceFieldIndex, *source); |
2602 // Both true and false are immovable immortal objects so no need for write | 2471 // Both true and false are immovable immortal objects so no need for write |
2603 // barrier. | 2472 // barrier. |
2604 regexp->InObjectPropertyAtPut( | 2473 regexp->InObjectPropertyAtPut(JSRegExp::kGlobalFieldIndex, *global, |
2605 JSRegExp::kGlobalFieldIndex, *global, SKIP_WRITE_BARRIER); | 2474 SKIP_WRITE_BARRIER); |
2606 regexp->InObjectPropertyAtPut( | 2475 regexp->InObjectPropertyAtPut(JSRegExp::kIgnoreCaseFieldIndex, *ignoreCase, |
2607 JSRegExp::kIgnoreCaseFieldIndex, *ignoreCase, SKIP_WRITE_BARRIER); | 2476 SKIP_WRITE_BARRIER); |
2608 regexp->InObjectPropertyAtPut( | 2477 regexp->InObjectPropertyAtPut(JSRegExp::kMultilineFieldIndex, *multiline, |
2609 JSRegExp::kMultilineFieldIndex, *multiline, SKIP_WRITE_BARRIER); | 2478 SKIP_WRITE_BARRIER); |
2610 regexp->InObjectPropertyAtPut( | 2479 regexp->InObjectPropertyAtPut(JSRegExp::kLastIndexFieldIndex, |
2611 JSRegExp::kLastIndexFieldIndex, Smi::FromInt(0), SKIP_WRITE_BARRIER); | 2480 Smi::FromInt(0), SKIP_WRITE_BARRIER); |
2612 return *regexp; | 2481 return *regexp; |
2613 } | 2482 } |
2614 | 2483 |
2615 // Map has changed, so use generic, but slower, method. We also end here if | 2484 // Map has changed, so use generic, but slower, method. We also end here if |
2616 // the --harmony-regexp flag is set, because the initial map does not have | 2485 // the --harmony-regexp flag is set, because the initial map does not have |
2617 // space for the 'sticky' flag, since it is from the snapshot, but must work | 2486 // space for the 'sticky' flag, since it is from the snapshot, but must work |
2618 // both with and without --harmony-regexp. When sticky comes out from under | 2487 // both with and without --harmony-regexp. When sticky comes out from under |
2619 // the flag, we will be able to use the fast initial map. | 2488 // the flag, we will be able to use the fast initial map. |
2620 PropertyAttributes final = | 2489 PropertyAttributes final = |
2621 static_cast<PropertyAttributes>(READ_ONLY | DONT_ENUM | DONT_DELETE); | 2490 static_cast<PropertyAttributes>(READ_ONLY | DONT_ENUM | DONT_DELETE); |
2622 PropertyAttributes writable = | 2491 PropertyAttributes writable = |
2623 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE); | 2492 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE); |
2624 Handle<Object> zero(Smi::FromInt(0), isolate); | 2493 Handle<Object> zero(Smi::FromInt(0), isolate); |
2625 Factory* factory = isolate->factory(); | 2494 Factory* factory = isolate->factory(); |
2626 JSObject::SetOwnPropertyIgnoreAttributes( | 2495 JSObject::SetOwnPropertyIgnoreAttributes(regexp, factory->source_string(), |
2627 regexp, factory->source_string(), source, final).Check(); | 2496 source, final).Check(); |
2628 JSObject::SetOwnPropertyIgnoreAttributes( | 2497 JSObject::SetOwnPropertyIgnoreAttributes(regexp, factory->global_string(), |
2629 regexp, factory->global_string(), global, final).Check(); | 2498 global, final).Check(); |
2630 JSObject::SetOwnPropertyIgnoreAttributes( | 2499 JSObject::SetOwnPropertyIgnoreAttributes( |
2631 regexp, factory->ignore_case_string(), ignoreCase, final).Check(); | 2500 regexp, factory->ignore_case_string(), ignoreCase, final).Check(); |
2632 JSObject::SetOwnPropertyIgnoreAttributes( | 2501 JSObject::SetOwnPropertyIgnoreAttributes(regexp, factory->multiline_string(), |
2633 regexp, factory->multiline_string(), multiline, final).Check(); | 2502 multiline, final).Check(); |
2634 if (FLAG_harmony_regexps) { | 2503 if (FLAG_harmony_regexps) { |
2635 JSObject::SetOwnPropertyIgnoreAttributes( | 2504 JSObject::SetOwnPropertyIgnoreAttributes(regexp, factory->sticky_string(), |
2636 regexp, factory->sticky_string(), sticky, final).Check(); | 2505 sticky, final).Check(); |
2637 } | 2506 } |
2638 JSObject::SetOwnPropertyIgnoreAttributes( | 2507 JSObject::SetOwnPropertyIgnoreAttributes(regexp, factory->last_index_string(), |
2639 regexp, factory->last_index_string(), zero, writable).Check(); | 2508 zero, writable).Check(); |
2640 return *regexp; | 2509 return *regexp; |
2641 } | 2510 } |
2642 | 2511 |
2643 | 2512 |
2644 RUNTIME_FUNCTION(Runtime_FinishArrayPrototypeSetup) { | 2513 RUNTIME_FUNCTION(Runtime_FinishArrayPrototypeSetup) { |
2645 HandleScope scope(isolate); | 2514 HandleScope scope(isolate); |
2646 DCHECK(args.length() == 1); | 2515 DCHECK(args.length() == 1); |
2647 CONVERT_ARG_HANDLE_CHECKED(JSArray, prototype, 0); | 2516 CONVERT_ARG_HANDLE_CHECKED(JSArray, prototype, 0); |
2648 Object* length = prototype->length(); | 2517 Object* length = prototype->length(); |
2649 RUNTIME_ASSERT(length->IsSmi() && Smi::cast(length)->value() == 0); | 2518 RUNTIME_ASSERT(length->IsSmi() && Smi::cast(length)->value() == 0); |
2650 RUNTIME_ASSERT(prototype->HasFastSmiOrObjectElements()); | 2519 RUNTIME_ASSERT(prototype->HasFastSmiOrObjectElements()); |
2651 // This is necessary to enable fast checks for absence of elements | 2520 // This is necessary to enable fast checks for absence of elements |
2652 // on Array.prototype and below. | 2521 // on Array.prototype and below. |
2653 prototype->set_elements(isolate->heap()->empty_fixed_array()); | 2522 prototype->set_elements(isolate->heap()->empty_fixed_array()); |
2654 return Smi::FromInt(0); | 2523 return Smi::FromInt(0); |
2655 } | 2524 } |
2656 | 2525 |
2657 | 2526 |
2658 static void InstallBuiltin(Isolate* isolate, | 2527 static void InstallBuiltin(Isolate* isolate, Handle<JSObject> holder, |
2659 Handle<JSObject> holder, | 2528 const char* name, Builtins::Name builtin_name) { |
2660 const char* name, | |
2661 Builtins::Name builtin_name) { | |
2662 Handle<String> key = isolate->factory()->InternalizeUtf8String(name); | 2529 Handle<String> key = isolate->factory()->InternalizeUtf8String(name); |
2663 Handle<Code> code(isolate->builtins()->builtin(builtin_name)); | 2530 Handle<Code> code(isolate->builtins()->builtin(builtin_name)); |
2664 Handle<JSFunction> optimized = | 2531 Handle<JSFunction> optimized = |
2665 isolate->factory()->NewFunctionWithoutPrototype(key, code); | 2532 isolate->factory()->NewFunctionWithoutPrototype(key, code); |
2666 optimized->shared()->DontAdaptArguments(); | 2533 optimized->shared()->DontAdaptArguments(); |
2667 JSObject::AddProperty(holder, key, optimized, NONE); | 2534 JSObject::AddProperty(holder, key, optimized, NONE); |
2668 } | 2535 } |
2669 | 2536 |
2670 | 2537 |
2671 RUNTIME_FUNCTION(Runtime_SpecialArrayFunctions) { | 2538 RUNTIME_FUNCTION(Runtime_SpecialArrayFunctions) { |
(...skipping 15 matching lines...) Expand all Loading... |
2687 | 2554 |
2688 | 2555 |
2689 RUNTIME_FUNCTION(Runtime_IsSloppyModeFunction) { | 2556 RUNTIME_FUNCTION(Runtime_IsSloppyModeFunction) { |
2690 SealHandleScope shs(isolate); | 2557 SealHandleScope shs(isolate); |
2691 DCHECK(args.length() == 1); | 2558 DCHECK(args.length() == 1); |
2692 CONVERT_ARG_CHECKED(JSReceiver, callable, 0); | 2559 CONVERT_ARG_CHECKED(JSReceiver, callable, 0); |
2693 if (!callable->IsJSFunction()) { | 2560 if (!callable->IsJSFunction()) { |
2694 HandleScope scope(isolate); | 2561 HandleScope scope(isolate); |
2695 Handle<Object> delegate; | 2562 Handle<Object> delegate; |
2696 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 2563 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
2697 isolate, delegate, | 2564 isolate, delegate, Execution::TryGetFunctionDelegate( |
2698 Execution::TryGetFunctionDelegate( | 2565 isolate, Handle<JSReceiver>(callable))); |
2699 isolate, Handle<JSReceiver>(callable))); | |
2700 callable = JSFunction::cast(*delegate); | 2566 callable = JSFunction::cast(*delegate); |
2701 } | 2567 } |
2702 JSFunction* function = JSFunction::cast(callable); | 2568 JSFunction* function = JSFunction::cast(callable); |
2703 SharedFunctionInfo* shared = function->shared(); | 2569 SharedFunctionInfo* shared = function->shared(); |
2704 return isolate->heap()->ToBoolean(shared->strict_mode() == SLOPPY); | 2570 return isolate->heap()->ToBoolean(shared->strict_mode() == SLOPPY); |
2705 } | 2571 } |
2706 | 2572 |
2707 | 2573 |
2708 RUNTIME_FUNCTION(Runtime_GetDefaultReceiver) { | 2574 RUNTIME_FUNCTION(Runtime_GetDefaultReceiver) { |
2709 SealHandleScope shs(isolate); | 2575 SealHandleScope shs(isolate); |
2710 DCHECK(args.length() == 1); | 2576 DCHECK(args.length() == 1); |
2711 CONVERT_ARG_CHECKED(JSReceiver, callable, 0); | 2577 CONVERT_ARG_CHECKED(JSReceiver, callable, 0); |
2712 | 2578 |
2713 if (!callable->IsJSFunction()) { | 2579 if (!callable->IsJSFunction()) { |
2714 HandleScope scope(isolate); | 2580 HandleScope scope(isolate); |
2715 Handle<Object> delegate; | 2581 Handle<Object> delegate; |
2716 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 2582 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
2717 isolate, delegate, | 2583 isolate, delegate, Execution::TryGetFunctionDelegate( |
2718 Execution::TryGetFunctionDelegate( | 2584 isolate, Handle<JSReceiver>(callable))); |
2719 isolate, Handle<JSReceiver>(callable))); | |
2720 callable = JSFunction::cast(*delegate); | 2585 callable = JSFunction::cast(*delegate); |
2721 } | 2586 } |
2722 JSFunction* function = JSFunction::cast(callable); | 2587 JSFunction* function = JSFunction::cast(callable); |
2723 | 2588 |
2724 SharedFunctionInfo* shared = function->shared(); | 2589 SharedFunctionInfo* shared = function->shared(); |
2725 if (shared->native() || shared->strict_mode() == STRICT) { | 2590 if (shared->native() || shared->strict_mode() == STRICT) { |
2726 return isolate->heap()->undefined_value(); | 2591 return isolate->heap()->undefined_value(); |
2727 } | 2592 } |
2728 // Returns undefined for strict or native functions, or | 2593 // Returns undefined for strict or native functions, or |
2729 // the associated global receiver for "normal" functions. | 2594 // the associated global receiver for "normal" functions. |
2730 | 2595 |
2731 return function->global_proxy(); | 2596 return function->global_proxy(); |
2732 } | 2597 } |
2733 | 2598 |
2734 | 2599 |
2735 RUNTIME_FUNCTION(Runtime_MaterializeRegExpLiteral) { | 2600 RUNTIME_FUNCTION(Runtime_MaterializeRegExpLiteral) { |
2736 HandleScope scope(isolate); | 2601 HandleScope scope(isolate); |
2737 DCHECK(args.length() == 4); | 2602 DCHECK(args.length() == 4); |
2738 CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0); | 2603 CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0); |
2739 CONVERT_SMI_ARG_CHECKED(index, 1); | 2604 CONVERT_SMI_ARG_CHECKED(index, 1); |
2740 CONVERT_ARG_HANDLE_CHECKED(String, pattern, 2); | 2605 CONVERT_ARG_HANDLE_CHECKED(String, pattern, 2); |
2741 CONVERT_ARG_HANDLE_CHECKED(String, flags, 3); | 2606 CONVERT_ARG_HANDLE_CHECKED(String, flags, 3); |
2742 | 2607 |
2743 // Get the RegExp function from the context in the literals array. | 2608 // Get the RegExp function from the context in the literals array. |
2744 // This is the RegExp function from the context in which the | 2609 // This is the RegExp function from the context in which the |
2745 // function was created. We do not use the RegExp function from the | 2610 // function was created. We do not use the RegExp function from the |
2746 // current native context because this might be the RegExp function | 2611 // current native context because this might be the RegExp function |
2747 // from another context which we should not have access to. | 2612 // from another context which we should not have access to. |
2748 Handle<JSFunction> constructor = | 2613 Handle<JSFunction> constructor = Handle<JSFunction>( |
2749 Handle<JSFunction>( | 2614 JSFunction::NativeContextFromLiterals(*literals)->regexp_function()); |
2750 JSFunction::NativeContextFromLiterals(*literals)->regexp_function()); | |
2751 // Compute the regular expression literal. | 2615 // Compute the regular expression literal. |
2752 Handle<Object> regexp; | 2616 Handle<Object> regexp; |
2753 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 2617 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
2754 isolate, regexp, | 2618 isolate, regexp, |
2755 RegExpImpl::CreateRegExpLiteral(constructor, pattern, flags)); | 2619 RegExpImpl::CreateRegExpLiteral(constructor, pattern, flags)); |
2756 literals->set(index, *regexp); | 2620 literals->set(index, *regexp); |
2757 return *regexp; | 2621 return *regexp; |
2758 } | 2622 } |
2759 | 2623 |
2760 | 2624 |
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2982 isolate->factory()->NewFixedArray(number_of_literals, TENURED); | 2846 isolate->factory()->NewFixedArray(number_of_literals, TENURED); |
2983 if (number_of_literals > 0) { | 2847 if (number_of_literals > 0) { |
2984 literals->set(JSFunction::kLiteralNativeContextIndex, | 2848 literals->set(JSFunction::kLiteralNativeContextIndex, |
2985 context->native_context()); | 2849 context->native_context()); |
2986 } | 2850 } |
2987 target->set_context(*context); | 2851 target->set_context(*context); |
2988 target->set_literals(*literals); | 2852 target->set_literals(*literals); |
2989 | 2853 |
2990 if (isolate->logger()->is_logging_code_events() || | 2854 if (isolate->logger()->is_logging_code_events() || |
2991 isolate->cpu_profiler()->is_profiling()) { | 2855 isolate->cpu_profiler()->is_profiling()) { |
2992 isolate->logger()->LogExistingFunction( | 2856 isolate->logger()->LogExistingFunction(source_shared, |
2993 source_shared, Handle<Code>(source_shared->code())); | 2857 Handle<Code>(source_shared->code())); |
2994 } | 2858 } |
2995 | 2859 |
2996 return *target; | 2860 return *target; |
2997 } | 2861 } |
2998 | 2862 |
2999 | 2863 |
3000 RUNTIME_FUNCTION(Runtime_CreateJSGeneratorObject) { | 2864 RUNTIME_FUNCTION(Runtime_CreateJSGeneratorObject) { |
3001 HandleScope scope(isolate); | 2865 HandleScope scope(isolate); |
3002 DCHECK(args.length() == 0); | 2866 DCHECK(args.length() == 0); |
3003 | 2867 |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3119 UNREACHABLE(); | 2983 UNREACHABLE(); |
3120 return isolate->ThrowIllegalOperation(); | 2984 return isolate->ThrowIllegalOperation(); |
3121 } | 2985 } |
3122 | 2986 |
3123 | 2987 |
3124 RUNTIME_FUNCTION(Runtime_ThrowGeneratorStateError) { | 2988 RUNTIME_FUNCTION(Runtime_ThrowGeneratorStateError) { |
3125 HandleScope scope(isolate); | 2989 HandleScope scope(isolate); |
3126 DCHECK(args.length() == 1); | 2990 DCHECK(args.length() == 1); |
3127 CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0); | 2991 CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0); |
3128 int continuation = generator->continuation(); | 2992 int continuation = generator->continuation(); |
3129 const char* message = continuation == JSGeneratorObject::kGeneratorClosed ? | 2993 const char* message = continuation == JSGeneratorObject::kGeneratorClosed |
3130 "generator_finished" : "generator_running"; | 2994 ? "generator_finished" |
3131 Vector< Handle<Object> > argv = HandleVector<Object>(NULL, 0); | 2995 : "generator_running"; |
| 2996 Vector<Handle<Object> > argv = HandleVector<Object>(NULL, 0); |
3132 THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewError(message, argv)); | 2997 THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewError(message, argv)); |
3133 } | 2998 } |
3134 | 2999 |
3135 | 3000 |
3136 RUNTIME_FUNCTION(Runtime_ObjectFreeze) { | 3001 RUNTIME_FUNCTION(Runtime_ObjectFreeze) { |
3137 HandleScope scope(isolate); | 3002 HandleScope scope(isolate); |
3138 DCHECK(args.length() == 1); | 3003 DCHECK(args.length() == 1); |
3139 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); | 3004 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); |
3140 | 3005 |
3141 // %ObjectFreeze is a fast path and these cases are handled elsewhere. | 3006 // %ObjectFreeze is a fast path and these cases are handled elsewhere. |
3142 RUNTIME_ASSERT(!object->HasSloppyArgumentsElements() && | 3007 RUNTIME_ASSERT(!object->HasSloppyArgumentsElements() && |
3143 !object->map()->is_observed() && | 3008 !object->map()->is_observed() && !object->IsJSProxy()); |
3144 !object->IsJSProxy()); | |
3145 | 3009 |
3146 Handle<Object> result; | 3010 Handle<Object> result; |
3147 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, JSObject::Freeze(object)); | 3011 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, JSObject::Freeze(object)); |
3148 return *result; | 3012 return *result; |
3149 } | 3013 } |
3150 | 3014 |
3151 | 3015 |
3152 RUNTIME_FUNCTION(Runtime_StringCharCodeAtRT) { | 3016 RUNTIME_FUNCTION(Runtime_StringCharCodeAtRT) { |
3153 HandleScope handle_scope(isolate); | 3017 HandleScope handle_scope(isolate); |
3154 DCHECK(args.length() == 2); | 3018 DCHECK(args.length() == 2); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3186 explicit FixedArrayBuilder(Isolate* isolate, int initial_capacity) | 3050 explicit FixedArrayBuilder(Isolate* isolate, int initial_capacity) |
3187 : array_(isolate->factory()->NewFixedArrayWithHoles(initial_capacity)), | 3051 : array_(isolate->factory()->NewFixedArrayWithHoles(initial_capacity)), |
3188 length_(0), | 3052 length_(0), |
3189 has_non_smi_elements_(false) { | 3053 has_non_smi_elements_(false) { |
3190 // Require a non-zero initial size. Ensures that doubling the size to | 3054 // Require a non-zero initial size. Ensures that doubling the size to |
3191 // extend the array will work. | 3055 // extend the array will work. |
3192 DCHECK(initial_capacity > 0); | 3056 DCHECK(initial_capacity > 0); |
3193 } | 3057 } |
3194 | 3058 |
3195 explicit FixedArrayBuilder(Handle<FixedArray> backing_store) | 3059 explicit FixedArrayBuilder(Handle<FixedArray> backing_store) |
3196 : array_(backing_store), | 3060 : array_(backing_store), length_(0), has_non_smi_elements_(false) { |
3197 length_(0), | |
3198 has_non_smi_elements_(false) { | |
3199 // Require a non-zero initial size. Ensures that doubling the size to | 3061 // Require a non-zero initial size. Ensures that doubling the size to |
3200 // extend the array will work. | 3062 // extend the array will work. |
3201 DCHECK(backing_store->length() > 0); | 3063 DCHECK(backing_store->length() > 0); |
3202 } | 3064 } |
3203 | 3065 |
3204 bool HasCapacity(int elements) { | 3066 bool HasCapacity(int elements) { |
3205 int length = array_->length(); | 3067 int length = array_->length(); |
3206 int required_length = length_ + elements; | 3068 int required_length = length_ + elements; |
3207 return (length >= required_length); | 3069 return (length >= required_length); |
3208 } | 3070 } |
(...skipping 21 matching lines...) Expand all Loading... |
3230 has_non_smi_elements_ = true; | 3092 has_non_smi_elements_ = true; |
3231 } | 3093 } |
3232 | 3094 |
3233 void Add(Smi* value) { | 3095 void Add(Smi* value) { |
3234 DCHECK(value->IsSmi()); | 3096 DCHECK(value->IsSmi()); |
3235 DCHECK(length_ < capacity()); | 3097 DCHECK(length_ < capacity()); |
3236 array_->set(length_, value); | 3098 array_->set(length_, value); |
3237 length_++; | 3099 length_++; |
3238 } | 3100 } |
3239 | 3101 |
3240 Handle<FixedArray> array() { | 3102 Handle<FixedArray> array() { return array_; } |
3241 return array_; | |
3242 } | |
3243 | 3103 |
3244 int length() { | 3104 int length() { return length_; } |
3245 return length_; | |
3246 } | |
3247 | 3105 |
3248 int capacity() { | 3106 int capacity() { return array_->length(); } |
3249 return array_->length(); | |
3250 } | |
3251 | 3107 |
3252 Handle<JSArray> ToJSArray(Handle<JSArray> target_array) { | 3108 Handle<JSArray> ToJSArray(Handle<JSArray> target_array) { |
3253 JSArray::SetContent(target_array, array_); | 3109 JSArray::SetContent(target_array, array_); |
3254 target_array->set_length(Smi::FromInt(length_)); | 3110 target_array->set_length(Smi::FromInt(length_)); |
3255 return target_array; | 3111 return target_array; |
3256 } | 3112 } |
3257 | 3113 |
3258 | 3114 |
3259 private: | 3115 private: |
3260 Handle<FixedArray> array_; | 3116 Handle<FixedArray> array_; |
3261 int length_; | 3117 int length_; |
3262 bool has_non_smi_elements_; | 3118 bool has_non_smi_elements_; |
3263 }; | 3119 }; |
3264 | 3120 |
3265 | 3121 |
3266 // Forward declarations. | 3122 // Forward declarations. |
3267 const int kStringBuilderConcatHelperLengthBits = 11; | 3123 const int kStringBuilderConcatHelperLengthBits = 11; |
3268 const int kStringBuilderConcatHelperPositionBits = 19; | 3124 const int kStringBuilderConcatHelperPositionBits = 19; |
3269 | 3125 |
3270 template <typename schar> | 3126 template <typename schar> |
3271 static inline void StringBuilderConcatHelper(String*, | 3127 static inline void StringBuilderConcatHelper(String*, schar*, FixedArray*, int); |
3272 schar*, | |
3273 FixedArray*, | |
3274 int); | |
3275 | 3128 |
3276 typedef BitField<int, 0, kStringBuilderConcatHelperLengthBits> | 3129 typedef BitField<int, 0, kStringBuilderConcatHelperLengthBits> |
3277 StringBuilderSubstringLength; | 3130 StringBuilderSubstringLength; |
3278 typedef BitField<int, | 3131 typedef BitField<int, kStringBuilderConcatHelperLengthBits, |
3279 kStringBuilderConcatHelperLengthBits, | |
3280 kStringBuilderConcatHelperPositionBits> | 3132 kStringBuilderConcatHelperPositionBits> |
3281 StringBuilderSubstringPosition; | 3133 StringBuilderSubstringPosition; |
3282 | 3134 |
3283 | 3135 |
3284 class ReplacementStringBuilder { | 3136 class ReplacementStringBuilder { |
3285 public: | 3137 public: |
3286 ReplacementStringBuilder(Heap* heap, Handle<String> subject, | 3138 ReplacementStringBuilder(Heap* heap, Handle<String> subject, |
3287 int estimated_part_count) | 3139 int estimated_part_count) |
3288 : heap_(heap), | 3140 : heap_(heap), |
3289 array_builder_(heap->isolate(), estimated_part_count), | 3141 array_builder_(heap->isolate(), estimated_part_count), |
3290 subject_(subject), | 3142 subject_(subject), |
3291 character_count_(0), | 3143 character_count_(0), |
3292 is_one_byte_(subject->IsOneByteRepresentation()) { | 3144 is_one_byte_(subject->IsOneByteRepresentation()) { |
3293 // Require a non-zero initial size. Ensures that doubling the size to | 3145 // Require a non-zero initial size. Ensures that doubling the size to |
3294 // extend the array will work. | 3146 // extend the array will work. |
3295 DCHECK(estimated_part_count > 0); | 3147 DCHECK(estimated_part_count > 0); |
3296 } | 3148 } |
3297 | 3149 |
3298 static inline void AddSubjectSlice(FixedArrayBuilder* builder, | 3150 static inline void AddSubjectSlice(FixedArrayBuilder* builder, int from, |
3299 int from, | |
3300 int to) { | 3151 int to) { |
3301 DCHECK(from >= 0); | 3152 DCHECK(from >= 0); |
3302 int length = to - from; | 3153 int length = to - from; |
3303 DCHECK(length > 0); | 3154 DCHECK(length > 0); |
3304 if (StringBuilderSubstringLength::is_valid(length) && | 3155 if (StringBuilderSubstringLength::is_valid(length) && |
3305 StringBuilderSubstringPosition::is_valid(from)) { | 3156 StringBuilderSubstringPosition::is_valid(from)) { |
3306 int encoded_slice = StringBuilderSubstringLength::encode(length) | | 3157 int encoded_slice = StringBuilderSubstringLength::encode(length) | |
3307 StringBuilderSubstringPosition::encode(from); | 3158 StringBuilderSubstringPosition::encode(from); |
3308 builder->Add(Smi::FromInt(encoded_slice)); | 3159 builder->Add(Smi::FromInt(encoded_slice)); |
3309 } else { | 3160 } else { |
3310 // Otherwise encode as two smis. | 3161 // Otherwise encode as two smis. |
3311 builder->Add(Smi::FromInt(-length)); | 3162 builder->Add(Smi::FromInt(-length)); |
3312 builder->Add(Smi::FromInt(from)); | 3163 builder->Add(Smi::FromInt(from)); |
3313 } | 3164 } |
3314 } | 3165 } |
3315 | 3166 |
3316 | 3167 |
3317 void EnsureCapacity(int elements) { | 3168 void EnsureCapacity(int elements) { array_builder_.EnsureCapacity(elements); } |
3318 array_builder_.EnsureCapacity(elements); | |
3319 } | |
3320 | 3169 |
3321 | 3170 |
3322 void AddSubjectSlice(int from, int to) { | 3171 void AddSubjectSlice(int from, int to) { |
3323 AddSubjectSlice(&array_builder_, from, to); | 3172 AddSubjectSlice(&array_builder_, from, to); |
3324 IncrementCharacterCount(to - from); | 3173 IncrementCharacterCount(to - from); |
3325 } | 3174 } |
3326 | 3175 |
3327 | 3176 |
3328 void AddString(Handle<String> string) { | 3177 void AddString(Handle<String> string) { |
3329 int length = string->length(); | 3178 int length = string->length(); |
(...skipping 10 matching lines...) Expand all Loading... |
3340 Isolate* isolate = heap_->isolate(); | 3189 Isolate* isolate = heap_->isolate(); |
3341 if (array_builder_.length() == 0) { | 3190 if (array_builder_.length() == 0) { |
3342 return isolate->factory()->empty_string(); | 3191 return isolate->factory()->empty_string(); |
3343 } | 3192 } |
3344 | 3193 |
3345 Handle<String> joined_string; | 3194 Handle<String> joined_string; |
3346 if (is_one_byte_) { | 3195 if (is_one_byte_) { |
3347 Handle<SeqOneByteString> seq; | 3196 Handle<SeqOneByteString> seq; |
3348 ASSIGN_RETURN_ON_EXCEPTION( | 3197 ASSIGN_RETURN_ON_EXCEPTION( |
3349 isolate, seq, | 3198 isolate, seq, |
3350 isolate->factory()->NewRawOneByteString(character_count_), | 3199 isolate->factory()->NewRawOneByteString(character_count_), String); |
3351 String); | |
3352 | 3200 |
3353 DisallowHeapAllocation no_gc; | 3201 DisallowHeapAllocation no_gc; |
3354 uint8_t* char_buffer = seq->GetChars(); | 3202 uint8_t* char_buffer = seq->GetChars(); |
3355 StringBuilderConcatHelper(*subject_, | 3203 StringBuilderConcatHelper(*subject_, char_buffer, *array_builder_.array(), |
3356 char_buffer, | |
3357 *array_builder_.array(), | |
3358 array_builder_.length()); | 3204 array_builder_.length()); |
3359 joined_string = Handle<String>::cast(seq); | 3205 joined_string = Handle<String>::cast(seq); |
3360 } else { | 3206 } else { |
3361 // Two-byte. | 3207 // Two-byte. |
3362 Handle<SeqTwoByteString> seq; | 3208 Handle<SeqTwoByteString> seq; |
3363 ASSIGN_RETURN_ON_EXCEPTION( | 3209 ASSIGN_RETURN_ON_EXCEPTION( |
3364 isolate, seq, | 3210 isolate, seq, |
3365 isolate->factory()->NewRawTwoByteString(character_count_), | 3211 isolate->factory()->NewRawTwoByteString(character_count_), String); |
3366 String); | |
3367 | 3212 |
3368 DisallowHeapAllocation no_gc; | 3213 DisallowHeapAllocation no_gc; |
3369 uc16* char_buffer = seq->GetChars(); | 3214 uc16* char_buffer = seq->GetChars(); |
3370 StringBuilderConcatHelper(*subject_, | 3215 StringBuilderConcatHelper(*subject_, char_buffer, *array_builder_.array(), |
3371 char_buffer, | |
3372 *array_builder_.array(), | |
3373 array_builder_.length()); | 3216 array_builder_.length()); |
3374 joined_string = Handle<String>::cast(seq); | 3217 joined_string = Handle<String>::cast(seq); |
3375 } | 3218 } |
3376 return joined_string; | 3219 return joined_string; |
3377 } | 3220 } |
3378 | 3221 |
3379 | 3222 |
3380 void IncrementCharacterCount(int by) { | 3223 void IncrementCharacterCount(int by) { |
3381 if (character_count_ > String::kMaxLength - by) { | 3224 if (character_count_ > String::kMaxLength - by) { |
3382 STATIC_ASSERT(String::kMaxLength < kMaxInt); | 3225 STATIC_ASSERT(String::kMaxLength < kMaxInt); |
(...skipping 17 matching lines...) Expand all Loading... |
3400 bool is_one_byte_; | 3243 bool is_one_byte_; |
3401 }; | 3244 }; |
3402 | 3245 |
3403 | 3246 |
3404 class CompiledReplacement { | 3247 class CompiledReplacement { |
3405 public: | 3248 public: |
3406 explicit CompiledReplacement(Zone* zone) | 3249 explicit CompiledReplacement(Zone* zone) |
3407 : parts_(1, zone), replacement_substrings_(0, zone), zone_(zone) {} | 3250 : parts_(1, zone), replacement_substrings_(0, zone), zone_(zone) {} |
3408 | 3251 |
3409 // Return whether the replacement is simple. | 3252 // Return whether the replacement is simple. |
3410 bool Compile(Handle<String> replacement, | 3253 bool Compile(Handle<String> replacement, int capture_count, |
3411 int capture_count, | |
3412 int subject_length); | 3254 int subject_length); |
3413 | 3255 |
3414 // Use Apply only if Compile returned false. | 3256 // Use Apply only if Compile returned false. |
3415 void Apply(ReplacementStringBuilder* builder, | 3257 void Apply(ReplacementStringBuilder* builder, int match_from, int match_to, |
3416 int match_from, | |
3417 int match_to, | |
3418 int32_t* match); | 3258 int32_t* match); |
3419 | 3259 |
3420 // Number of distinct parts of the replacement pattern. | 3260 // Number of distinct parts of the replacement pattern. |
3421 int parts() { | 3261 int parts() { return parts_.length(); } |
3422 return parts_.length(); | |
3423 } | |
3424 | 3262 |
3425 Zone* zone() const { return zone_; } | 3263 Zone* zone() const { return zone_; } |
3426 | 3264 |
3427 private: | 3265 private: |
3428 enum PartType { | 3266 enum PartType { |
3429 SUBJECT_PREFIX = 1, | 3267 SUBJECT_PREFIX = 1, |
3430 SUBJECT_SUFFIX, | 3268 SUBJECT_SUFFIX, |
3431 SUBJECT_CAPTURE, | 3269 SUBJECT_CAPTURE, |
3432 REPLACEMENT_SUBSTRING, | 3270 REPLACEMENT_SUBSTRING, |
3433 REPLACEMENT_STRING, | 3271 REPLACEMENT_STRING, |
3434 | |
3435 NUMBER_OF_PART_TYPES | 3272 NUMBER_OF_PART_TYPES |
3436 }; | 3273 }; |
3437 | 3274 |
3438 struct ReplacementPart { | 3275 struct ReplacementPart { |
3439 static inline ReplacementPart SubjectMatch() { | 3276 static inline ReplacementPart SubjectMatch() { |
3440 return ReplacementPart(SUBJECT_CAPTURE, 0); | 3277 return ReplacementPart(SUBJECT_CAPTURE, 0); |
3441 } | 3278 } |
3442 static inline ReplacementPart SubjectCapture(int capture_index) { | 3279 static inline ReplacementPart SubjectCapture(int capture_index) { |
3443 return ReplacementPart(SUBJECT_CAPTURE, capture_index); | 3280 return ReplacementPart(SUBJECT_CAPTURE, capture_index); |
3444 } | 3281 } |
3445 static inline ReplacementPart SubjectPrefix() { | 3282 static inline ReplacementPart SubjectPrefix() { |
3446 return ReplacementPart(SUBJECT_PREFIX, 0); | 3283 return ReplacementPart(SUBJECT_PREFIX, 0); |
3447 } | 3284 } |
3448 static inline ReplacementPart SubjectSuffix(int subject_length) { | 3285 static inline ReplacementPart SubjectSuffix(int subject_length) { |
3449 return ReplacementPart(SUBJECT_SUFFIX, subject_length); | 3286 return ReplacementPart(SUBJECT_SUFFIX, subject_length); |
3450 } | 3287 } |
3451 static inline ReplacementPart ReplacementString() { | 3288 static inline ReplacementPart ReplacementString() { |
3452 return ReplacementPart(REPLACEMENT_STRING, 0); | 3289 return ReplacementPart(REPLACEMENT_STRING, 0); |
3453 } | 3290 } |
3454 static inline ReplacementPart ReplacementSubString(int from, int to) { | 3291 static inline ReplacementPart ReplacementSubString(int from, int to) { |
3455 DCHECK(from >= 0); | 3292 DCHECK(from >= 0); |
3456 DCHECK(to > from); | 3293 DCHECK(to > from); |
3457 return ReplacementPart(-from, to); | 3294 return ReplacementPart(-from, to); |
3458 } | 3295 } |
3459 | 3296 |
3460 // If tag <= 0 then it is the negation of a start index of a substring of | 3297 // If tag <= 0 then it is the negation of a start index of a substring of |
3461 // the replacement pattern, otherwise it's a value from PartType. | 3298 // the replacement pattern, otherwise it's a value from PartType. |
3462 ReplacementPart(int tag, int data) | 3299 ReplacementPart(int tag, int data) : tag(tag), data(data) { |
3463 : tag(tag), data(data) { | |
3464 // Must be non-positive or a PartType value. | 3300 // Must be non-positive or a PartType value. |
3465 DCHECK(tag < NUMBER_OF_PART_TYPES); | 3301 DCHECK(tag < NUMBER_OF_PART_TYPES); |
3466 } | 3302 } |
3467 // Either a value of PartType or a non-positive number that is | 3303 // Either a value of PartType or a non-positive number that is |
3468 // the negation of an index into the replacement string. | 3304 // the negation of an index into the replacement string. |
3469 int tag; | 3305 int tag; |
3470 // The data value's interpretation depends on the value of tag: | 3306 // The data value's interpretation depends on the value of tag: |
3471 // tag == SUBJECT_PREFIX || | 3307 // tag == SUBJECT_PREFIX || |
3472 // tag == SUBJECT_SUFFIX: data is unused. | 3308 // tag == SUBJECT_SUFFIX: data is unused. |
3473 // tag == SUBJECT_CAPTURE: data is the number of the capture. | 3309 // tag == SUBJECT_CAPTURE: data is the number of the capture. |
3474 // tag == REPLACEMENT_SUBSTRING || | 3310 // tag == REPLACEMENT_SUBSTRING || |
3475 // tag == REPLACEMENT_STRING: data is index into array of substrings | 3311 // tag == REPLACEMENT_STRING: data is index into array of substrings |
3476 // of the replacement string. | 3312 // of the replacement string. |
3477 // tag <= 0: Temporary representation of the substring of the replacement | 3313 // tag <= 0: Temporary representation of the substring of the replacement |
3478 // string ranging over -tag .. data. | 3314 // string ranging over -tag .. data. |
3479 // Is replaced by REPLACEMENT_{SUB,}STRING when we create the | 3315 // Is replaced by REPLACEMENT_{SUB,}STRING when we create the |
3480 // substring objects. | 3316 // substring objects. |
3481 int data; | 3317 int data; |
3482 }; | 3318 }; |
3483 | 3319 |
3484 template<typename Char> | 3320 template <typename Char> |
3485 bool ParseReplacementPattern(ZoneList<ReplacementPart>* parts, | 3321 bool ParseReplacementPattern(ZoneList<ReplacementPart>* parts, |
3486 Vector<Char> characters, | 3322 Vector<Char> characters, int capture_count, |
3487 int capture_count, | 3323 int subject_length, Zone* zone) { |
3488 int subject_length, | |
3489 Zone* zone) { | |
3490 int length = characters.length(); | 3324 int length = characters.length(); |
3491 int last = 0; | 3325 int last = 0; |
3492 for (int i = 0; i < length; i++) { | 3326 for (int i = 0; i < length; i++) { |
3493 Char c = characters[i]; | 3327 Char c = characters[i]; |
3494 if (c == '$') { | 3328 if (c == '$') { |
3495 int next_index = i + 1; | 3329 int next_index = i + 1; |
3496 if (next_index == length) { // No next character! | 3330 if (next_index == length) { // No next character! |
3497 break; | 3331 break; |
3498 } | 3332 } |
3499 Char c2 = characters[next_index]; | 3333 Char c2 = characters[next_index]; |
3500 switch (c2) { | 3334 switch (c2) { |
3501 case '$': | 3335 case '$': |
3502 if (i > last) { | 3336 if (i > last) { |
3503 // There is a substring before. Include the first "$". | 3337 // There is a substring before. Include the first "$". |
3504 parts->Add(ReplacementPart::ReplacementSubString(last, next_index), | 3338 parts->Add( |
3505 zone); | 3339 ReplacementPart::ReplacementSubString(last, next_index), |
3506 last = next_index + 1; // Continue after the second "$". | 3340 zone); |
3507 } else { | 3341 last = next_index + 1; // Continue after the second "$". |
3508 // Let the next substring start with the second "$". | 3342 } else { |
3509 last = next_index; | 3343 // Let the next substring start with the second "$". |
3510 } | 3344 last = next_index; |
3511 i = next_index; | 3345 } |
3512 break; | |
3513 case '`': | |
3514 if (i > last) { | |
3515 parts->Add(ReplacementPart::ReplacementSubString(last, i), zone); | |
3516 } | |
3517 parts->Add(ReplacementPart::SubjectPrefix(), zone); | |
3518 i = next_index; | |
3519 last = i + 1; | |
3520 break; | |
3521 case '\'': | |
3522 if (i > last) { | |
3523 parts->Add(ReplacementPart::ReplacementSubString(last, i), zone); | |
3524 } | |
3525 parts->Add(ReplacementPart::SubjectSuffix(subject_length), zone); | |
3526 i = next_index; | |
3527 last = i + 1; | |
3528 break; | |
3529 case '&': | |
3530 if (i > last) { | |
3531 parts->Add(ReplacementPart::ReplacementSubString(last, i), zone); | |
3532 } | |
3533 parts->Add(ReplacementPart::SubjectMatch(), zone); | |
3534 i = next_index; | |
3535 last = i + 1; | |
3536 break; | |
3537 case '0': | |
3538 case '1': | |
3539 case '2': | |
3540 case '3': | |
3541 case '4': | |
3542 case '5': | |
3543 case '6': | |
3544 case '7': | |
3545 case '8': | |
3546 case '9': { | |
3547 int capture_ref = c2 - '0'; | |
3548 if (capture_ref > capture_count) { | |
3549 i = next_index; | 3346 i = next_index; |
3550 continue; | 3347 break; |
3551 } | 3348 case '`': |
3552 int second_digit_index = next_index + 1; | |
3553 if (second_digit_index < length) { | |
3554 // Peek ahead to see if we have two digits. | |
3555 Char c3 = characters[second_digit_index]; | |
3556 if ('0' <= c3 && c3 <= '9') { // Double digits. | |
3557 int double_digit_ref = capture_ref * 10 + c3 - '0'; | |
3558 if (double_digit_ref <= capture_count) { | |
3559 next_index = second_digit_index; | |
3560 capture_ref = double_digit_ref; | |
3561 } | |
3562 } | |
3563 } | |
3564 if (capture_ref > 0) { | |
3565 if (i > last) { | 3349 if (i > last) { |
3566 parts->Add(ReplacementPart::ReplacementSubString(last, i), zone); | 3350 parts->Add(ReplacementPart::ReplacementSubString(last, i), zone); |
3567 } | 3351 } |
3568 DCHECK(capture_ref <= capture_count); | 3352 parts->Add(ReplacementPart::SubjectPrefix(), zone); |
3569 parts->Add(ReplacementPart::SubjectCapture(capture_ref), zone); | 3353 i = next_index; |
3570 last = next_index + 1; | 3354 last = i + 1; |
| 3355 break; |
| 3356 case '\'': |
| 3357 if (i > last) { |
| 3358 parts->Add(ReplacementPart::ReplacementSubString(last, i), zone); |
| 3359 } |
| 3360 parts->Add(ReplacementPart::SubjectSuffix(subject_length), zone); |
| 3361 i = next_index; |
| 3362 last = i + 1; |
| 3363 break; |
| 3364 case '&': |
| 3365 if (i > last) { |
| 3366 parts->Add(ReplacementPart::ReplacementSubString(last, i), zone); |
| 3367 } |
| 3368 parts->Add(ReplacementPart::SubjectMatch(), zone); |
| 3369 i = next_index; |
| 3370 last = i + 1; |
| 3371 break; |
| 3372 case '0': |
| 3373 case '1': |
| 3374 case '2': |
| 3375 case '3': |
| 3376 case '4': |
| 3377 case '5': |
| 3378 case '6': |
| 3379 case '7': |
| 3380 case '8': |
| 3381 case '9': { |
| 3382 int capture_ref = c2 - '0'; |
| 3383 if (capture_ref > capture_count) { |
| 3384 i = next_index; |
| 3385 continue; |
| 3386 } |
| 3387 int second_digit_index = next_index + 1; |
| 3388 if (second_digit_index < length) { |
| 3389 // Peek ahead to see if we have two digits. |
| 3390 Char c3 = characters[second_digit_index]; |
| 3391 if ('0' <= c3 && c3 <= '9') { // Double digits. |
| 3392 int double_digit_ref = capture_ref * 10 + c3 - '0'; |
| 3393 if (double_digit_ref <= capture_count) { |
| 3394 next_index = second_digit_index; |
| 3395 capture_ref = double_digit_ref; |
| 3396 } |
| 3397 } |
| 3398 } |
| 3399 if (capture_ref > 0) { |
| 3400 if (i > last) { |
| 3401 parts->Add(ReplacementPart::ReplacementSubString(last, i), |
| 3402 zone); |
| 3403 } |
| 3404 DCHECK(capture_ref <= capture_count); |
| 3405 parts->Add(ReplacementPart::SubjectCapture(capture_ref), zone); |
| 3406 last = next_index + 1; |
| 3407 } |
| 3408 i = next_index; |
| 3409 break; |
3571 } | 3410 } |
3572 i = next_index; | 3411 default: |
3573 break; | 3412 i = next_index; |
3574 } | 3413 break; |
3575 default: | |
3576 i = next_index; | |
3577 break; | |
3578 } | 3414 } |
3579 } | 3415 } |
3580 } | 3416 } |
3581 if (length > last) { | 3417 if (length > last) { |
3582 if (last == 0) { | 3418 if (last == 0) { |
3583 // Replacement is simple. Do not use Apply to do the replacement. | 3419 // Replacement is simple. Do not use Apply to do the replacement. |
3584 return true; | 3420 return true; |
3585 } else { | 3421 } else { |
3586 parts->Add(ReplacementPart::ReplacementSubString(last, length), zone); | 3422 parts->Add(ReplacementPart::ReplacementSubString(last, length), zone); |
3587 } | 3423 } |
3588 } | 3424 } |
3589 return false; | 3425 return false; |
3590 } | 3426 } |
3591 | 3427 |
3592 ZoneList<ReplacementPart> parts_; | 3428 ZoneList<ReplacementPart> parts_; |
3593 ZoneList<Handle<String> > replacement_substrings_; | 3429 ZoneList<Handle<String> > replacement_substrings_; |
3594 Zone* zone_; | 3430 Zone* zone_; |
3595 }; | 3431 }; |
3596 | 3432 |
3597 | 3433 |
3598 bool CompiledReplacement::Compile(Handle<String> replacement, | 3434 bool CompiledReplacement::Compile(Handle<String> replacement, int capture_count, |
3599 int capture_count, | |
3600 int subject_length) { | 3435 int subject_length) { |
3601 { | 3436 { |
3602 DisallowHeapAllocation no_gc; | 3437 DisallowHeapAllocation no_gc; |
3603 String::FlatContent content = replacement->GetFlatContent(); | 3438 String::FlatContent content = replacement->GetFlatContent(); |
3604 DCHECK(content.IsFlat()); | 3439 DCHECK(content.IsFlat()); |
3605 bool simple = false; | 3440 bool simple = false; |
3606 if (content.IsOneByte()) { | 3441 if (content.IsOneByte()) { |
3607 simple = ParseReplacementPattern(&parts_, | 3442 simple = ParseReplacementPattern(&parts_, content.ToOneByteVector(), |
3608 content.ToOneByteVector(), | 3443 capture_count, subject_length, zone()); |
3609 capture_count, | |
3610 subject_length, | |
3611 zone()); | |
3612 } else { | 3444 } else { |
3613 DCHECK(content.IsTwoByte()); | 3445 DCHECK(content.IsTwoByte()); |
3614 simple = ParseReplacementPattern(&parts_, | 3446 simple = ParseReplacementPattern(&parts_, content.ToUC16Vector(), |
3615 content.ToUC16Vector(), | 3447 capture_count, subject_length, zone()); |
3616 capture_count, | |
3617 subject_length, | |
3618 zone()); | |
3619 } | 3448 } |
3620 if (simple) return true; | 3449 if (simple) return true; |
3621 } | 3450 } |
3622 | 3451 |
3623 Isolate* isolate = replacement->GetIsolate(); | 3452 Isolate* isolate = replacement->GetIsolate(); |
3624 // Find substrings of replacement string and create them as String objects. | 3453 // Find substrings of replacement string and create them as String objects. |
3625 int substring_index = 0; | 3454 int substring_index = 0; |
3626 for (int i = 0, n = parts_.length(); i < n; i++) { | 3455 for (int i = 0, n = parts_.length(); i < n; i++) { |
3627 int tag = parts_[i].tag; | 3456 int tag = parts_[i].tag; |
3628 if (tag <= 0) { // A replacement string slice. | 3457 if (tag <= 0) { // A replacement string slice. |
3629 int from = -tag; | 3458 int from = -tag; |
3630 int to = parts_[i].data; | 3459 int to = parts_[i].data; |
3631 replacement_substrings_.Add( | 3460 replacement_substrings_.Add( |
3632 isolate->factory()->NewSubString(replacement, from, to), zone()); | 3461 isolate->factory()->NewSubString(replacement, from, to), zone()); |
3633 parts_[i].tag = REPLACEMENT_SUBSTRING; | 3462 parts_[i].tag = REPLACEMENT_SUBSTRING; |
3634 parts_[i].data = substring_index; | 3463 parts_[i].data = substring_index; |
3635 substring_index++; | 3464 substring_index++; |
3636 } else if (tag == REPLACEMENT_STRING) { | 3465 } else if (tag == REPLACEMENT_STRING) { |
3637 replacement_substrings_.Add(replacement, zone()); | 3466 replacement_substrings_.Add(replacement, zone()); |
3638 parts_[i].data = substring_index; | 3467 parts_[i].data = substring_index; |
3639 substring_index++; | 3468 substring_index++; |
3640 } | 3469 } |
3641 } | 3470 } |
3642 return false; | 3471 return false; |
3643 } | 3472 } |
3644 | 3473 |
3645 | 3474 |
3646 void CompiledReplacement::Apply(ReplacementStringBuilder* builder, | 3475 void CompiledReplacement::Apply(ReplacementStringBuilder* builder, |
3647 int match_from, | 3476 int match_from, int match_to, int32_t* match) { |
3648 int match_to, | |
3649 int32_t* match) { | |
3650 DCHECK_LT(0, parts_.length()); | 3477 DCHECK_LT(0, parts_.length()); |
3651 for (int i = 0, n = parts_.length(); i < n; i++) { | 3478 for (int i = 0, n = parts_.length(); i < n; i++) { |
3652 ReplacementPart part = parts_[i]; | 3479 ReplacementPart part = parts_[i]; |
3653 switch (part.tag) { | 3480 switch (part.tag) { |
3654 case SUBJECT_PREFIX: | 3481 case SUBJECT_PREFIX: |
3655 if (match_from > 0) builder->AddSubjectSlice(0, match_from); | 3482 if (match_from > 0) builder->AddSubjectSlice(0, match_from); |
3656 break; | 3483 break; |
3657 case SUBJECT_SUFFIX: { | 3484 case SUBJECT_SUFFIX: { |
3658 int subject_length = part.data; | 3485 int subject_length = part.data; |
3659 if (match_to < subject_length) { | 3486 if (match_to < subject_length) { |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3694 pos = reinterpret_cast<const uint8_t*>( | 3521 pos = reinterpret_cast<const uint8_t*>( |
3695 memchr(pos, pattern, subject_end - pos)); | 3522 memchr(pos, pattern, subject_end - pos)); |
3696 if (pos == NULL) return; | 3523 if (pos == NULL) return; |
3697 indices->Add(static_cast<int>(pos - subject_start), zone); | 3524 indices->Add(static_cast<int>(pos - subject_start), zone); |
3698 pos++; | 3525 pos++; |
3699 limit--; | 3526 limit--; |
3700 } | 3527 } |
3701 } | 3528 } |
3702 | 3529 |
3703 | 3530 |
3704 void FindTwoByteStringIndices(const Vector<const uc16> subject, | 3531 void FindTwoByteStringIndices(const Vector<const uc16> subject, uc16 pattern, |
3705 uc16 pattern, | 3532 ZoneList<int>* indices, unsigned int limit, |
3706 ZoneList<int>* indices, | |
3707 unsigned int limit, | |
3708 Zone* zone) { | 3533 Zone* zone) { |
3709 DCHECK(limit > 0); | 3534 DCHECK(limit > 0); |
3710 const uc16* subject_start = subject.start(); | 3535 const uc16* subject_start = subject.start(); |
3711 const uc16* subject_end = subject_start + subject.length(); | 3536 const uc16* subject_end = subject_start + subject.length(); |
3712 for (const uc16* pos = subject_start; pos < subject_end && limit > 0; pos++) { | 3537 for (const uc16* pos = subject_start; pos < subject_end && limit > 0; pos++) { |
3713 if (*pos == pattern) { | 3538 if (*pos == pattern) { |
3714 indices->Add(static_cast<int>(pos - subject_start), zone); | 3539 indices->Add(static_cast<int>(pos - subject_start), zone); |
3715 limit--; | 3540 limit--; |
3716 } | 3541 } |
3717 } | 3542 } |
3718 } | 3543 } |
3719 | 3544 |
3720 | 3545 |
3721 template <typename SubjectChar, typename PatternChar> | 3546 template <typename SubjectChar, typename PatternChar> |
3722 void FindStringIndices(Isolate* isolate, | 3547 void FindStringIndices(Isolate* isolate, Vector<const SubjectChar> subject, |
3723 Vector<const SubjectChar> subject, | |
3724 Vector<const PatternChar> pattern, | 3548 Vector<const PatternChar> pattern, |
3725 ZoneList<int>* indices, | 3549 ZoneList<int>* indices, unsigned int limit, Zone* zone) { |
3726 unsigned int limit, | |
3727 Zone* zone) { | |
3728 DCHECK(limit > 0); | 3550 DCHECK(limit > 0); |
3729 // Collect indices of pattern in subject. | 3551 // Collect indices of pattern in subject. |
3730 // Stop after finding at most limit values. | 3552 // Stop after finding at most limit values. |
3731 int pattern_length = pattern.length(); | 3553 int pattern_length = pattern.length(); |
3732 int index = 0; | 3554 int index = 0; |
3733 StringSearch<PatternChar, SubjectChar> search(isolate, pattern); | 3555 StringSearch<PatternChar, SubjectChar> search(isolate, pattern); |
3734 while (limit > 0) { | 3556 while (limit > 0) { |
3735 index = search.Search(subject, index); | 3557 index = search.Search(subject, index); |
3736 if (index < 0) return; | 3558 if (index < 0) return; |
3737 indices->Add(index, zone); | 3559 indices->Add(index, zone); |
3738 index += pattern_length; | 3560 index += pattern_length; |
3739 limit--; | 3561 limit--; |
3740 } | 3562 } |
3741 } | 3563 } |
3742 | 3564 |
3743 | 3565 |
3744 void FindStringIndicesDispatch(Isolate* isolate, | 3566 void FindStringIndicesDispatch(Isolate* isolate, String* subject, |
3745 String* subject, | 3567 String* pattern, ZoneList<int>* indices, |
3746 String* pattern, | 3568 unsigned int limit, Zone* zone) { |
3747 ZoneList<int>* indices, | |
3748 unsigned int limit, | |
3749 Zone* zone) { | |
3750 { | 3569 { |
3751 DisallowHeapAllocation no_gc; | 3570 DisallowHeapAllocation no_gc; |
3752 String::FlatContent subject_content = subject->GetFlatContent(); | 3571 String::FlatContent subject_content = subject->GetFlatContent(); |
3753 String::FlatContent pattern_content = pattern->GetFlatContent(); | 3572 String::FlatContent pattern_content = pattern->GetFlatContent(); |
3754 DCHECK(subject_content.IsFlat()); | 3573 DCHECK(subject_content.IsFlat()); |
3755 DCHECK(pattern_content.IsFlat()); | 3574 DCHECK(pattern_content.IsFlat()); |
3756 if (subject_content.IsOneByte()) { | 3575 if (subject_content.IsOneByte()) { |
3757 Vector<const uint8_t> subject_vector = subject_content.ToOneByteVector(); | 3576 Vector<const uint8_t> subject_vector = subject_content.ToOneByteVector(); |
3758 if (pattern_content.IsOneByte()) { | 3577 if (pattern_content.IsOneByte()) { |
3759 Vector<const uint8_t> pattern_vector = | 3578 Vector<const uint8_t> pattern_vector = |
3760 pattern_content.ToOneByteVector(); | 3579 pattern_content.ToOneByteVector(); |
3761 if (pattern_vector.length() == 1) { | 3580 if (pattern_vector.length() == 1) { |
3762 FindOneByteStringIndices(subject_vector, pattern_vector[0], indices, | 3581 FindOneByteStringIndices(subject_vector, pattern_vector[0], indices, |
3763 limit, zone); | 3582 limit, zone); |
3764 } else { | 3583 } else { |
3765 FindStringIndices(isolate, | 3584 FindStringIndices(isolate, subject_vector, pattern_vector, indices, |
3766 subject_vector, | 3585 limit, zone); |
3767 pattern_vector, | |
3768 indices, | |
3769 limit, | |
3770 zone); | |
3771 } | 3586 } |
3772 } else { | 3587 } else { |
3773 FindStringIndices(isolate, | 3588 FindStringIndices(isolate, subject_vector, |
3774 subject_vector, | 3589 pattern_content.ToUC16Vector(), indices, limit, zone); |
3775 pattern_content.ToUC16Vector(), | |
3776 indices, | |
3777 limit, | |
3778 zone); | |
3779 } | 3590 } |
3780 } else { | 3591 } else { |
3781 Vector<const uc16> subject_vector = subject_content.ToUC16Vector(); | 3592 Vector<const uc16> subject_vector = subject_content.ToUC16Vector(); |
3782 if (pattern_content.IsOneByte()) { | 3593 if (pattern_content.IsOneByte()) { |
3783 Vector<const uint8_t> pattern_vector = | 3594 Vector<const uint8_t> pattern_vector = |
3784 pattern_content.ToOneByteVector(); | 3595 pattern_content.ToOneByteVector(); |
3785 if (pattern_vector.length() == 1) { | 3596 if (pattern_vector.length() == 1) { |
3786 FindTwoByteStringIndices(subject_vector, | 3597 FindTwoByteStringIndices(subject_vector, pattern_vector[0], indices, |
3787 pattern_vector[0], | 3598 limit, zone); |
3788 indices, | |
3789 limit, | |
3790 zone); | |
3791 } else { | 3599 } else { |
3792 FindStringIndices(isolate, | 3600 FindStringIndices(isolate, subject_vector, pattern_vector, indices, |
3793 subject_vector, | 3601 limit, zone); |
3794 pattern_vector, | |
3795 indices, | |
3796 limit, | |
3797 zone); | |
3798 } | 3602 } |
3799 } else { | 3603 } else { |
3800 Vector<const uc16> pattern_vector = pattern_content.ToUC16Vector(); | 3604 Vector<const uc16> pattern_vector = pattern_content.ToUC16Vector(); |
3801 if (pattern_vector.length() == 1) { | 3605 if (pattern_vector.length() == 1) { |
3802 FindTwoByteStringIndices(subject_vector, | 3606 FindTwoByteStringIndices(subject_vector, pattern_vector[0], indices, |
3803 pattern_vector[0], | 3607 limit, zone); |
3804 indices, | |
3805 limit, | |
3806 zone); | |
3807 } else { | 3608 } else { |
3808 FindStringIndices(isolate, | 3609 FindStringIndices(isolate, subject_vector, pattern_vector, indices, |
3809 subject_vector, | 3610 limit, zone); |
3810 pattern_vector, | |
3811 indices, | |
3812 limit, | |
3813 zone); | |
3814 } | 3611 } |
3815 } | 3612 } |
3816 } | 3613 } |
3817 } | 3614 } |
3818 } | 3615 } |
3819 | 3616 |
3820 | 3617 |
3821 template<typename ResultSeqString> | 3618 template <typename ResultSeqString> |
3822 MUST_USE_RESULT static Object* StringReplaceGlobalAtomRegExpWithString( | 3619 MUST_USE_RESULT static Object* StringReplaceGlobalAtomRegExpWithString( |
3823 Isolate* isolate, | 3620 Isolate* isolate, Handle<String> subject, Handle<JSRegExp> pattern_regexp, |
3824 Handle<String> subject, | 3621 Handle<String> replacement, Handle<JSArray> last_match_info) { |
3825 Handle<JSRegExp> pattern_regexp, | |
3826 Handle<String> replacement, | |
3827 Handle<JSArray> last_match_info) { | |
3828 DCHECK(subject->IsFlat()); | 3622 DCHECK(subject->IsFlat()); |
3829 DCHECK(replacement->IsFlat()); | 3623 DCHECK(replacement->IsFlat()); |
3830 | 3624 |
3831 ZoneScope zone_scope(isolate->runtime_zone()); | 3625 ZoneScope zone_scope(isolate->runtime_zone()); |
3832 ZoneList<int> indices(8, zone_scope.zone()); | 3626 ZoneList<int> indices(8, zone_scope.zone()); |
3833 DCHECK_EQ(JSRegExp::ATOM, pattern_regexp->TypeTag()); | 3627 DCHECK_EQ(JSRegExp::ATOM, pattern_regexp->TypeTag()); |
3834 String* pattern = | 3628 String* pattern = |
3835 String::cast(pattern_regexp->DataAt(JSRegExp::kAtomPatternIndex)); | 3629 String::cast(pattern_regexp->DataAt(JSRegExp::kAtomPatternIndex)); |
3836 int subject_len = subject->length(); | 3630 int subject_len = subject->length(); |
3837 int pattern_len = pattern->length(); | 3631 int pattern_len = pattern->length(); |
3838 int replacement_len = replacement->length(); | 3632 int replacement_len = replacement->length(); |
3839 | 3633 |
3840 FindStringIndicesDispatch( | 3634 FindStringIndicesDispatch(isolate, *subject, pattern, &indices, 0xffffffff, |
3841 isolate, *subject, pattern, &indices, 0xffffffff, zone_scope.zone()); | 3635 zone_scope.zone()); |
3842 | 3636 |
3843 int matches = indices.length(); | 3637 int matches = indices.length(); |
3844 if (matches == 0) return *subject; | 3638 if (matches == 0) return *subject; |
3845 | 3639 |
3846 // Detect integer overflow. | 3640 // Detect integer overflow. |
3847 int64_t result_len_64 = | 3641 int64_t result_len_64 = (static_cast<int64_t>(replacement_len) - |
3848 (static_cast<int64_t>(replacement_len) - | 3642 static_cast<int64_t>(pattern_len)) * |
3849 static_cast<int64_t>(pattern_len)) * | 3643 static_cast<int64_t>(matches) + |
3850 static_cast<int64_t>(matches) + | 3644 static_cast<int64_t>(subject_len); |
3851 static_cast<int64_t>(subject_len); | |
3852 int result_len; | 3645 int result_len; |
3853 if (result_len_64 > static_cast<int64_t>(String::kMaxLength)) { | 3646 if (result_len_64 > static_cast<int64_t>(String::kMaxLength)) { |
3854 STATIC_ASSERT(String::kMaxLength < kMaxInt); | 3647 STATIC_ASSERT(String::kMaxLength < kMaxInt); |
3855 result_len = kMaxInt; // Provoke exception. | 3648 result_len = kMaxInt; // Provoke exception. |
3856 } else { | 3649 } else { |
3857 result_len = static_cast<int>(result_len_64); | 3650 result_len = static_cast<int>(result_len_64); |
3858 } | 3651 } |
3859 | 3652 |
3860 int subject_pos = 0; | 3653 int subject_pos = 0; |
3861 int result_pos = 0; | 3654 int result_pos = 0; |
3862 | 3655 |
3863 MaybeHandle<SeqString> maybe_res; | 3656 MaybeHandle<SeqString> maybe_res; |
3864 if (ResultSeqString::kHasOneByteEncoding) { | 3657 if (ResultSeqString::kHasOneByteEncoding) { |
3865 maybe_res = isolate->factory()->NewRawOneByteString(result_len); | 3658 maybe_res = isolate->factory()->NewRawOneByteString(result_len); |
3866 } else { | 3659 } else { |
3867 maybe_res = isolate->factory()->NewRawTwoByteString(result_len); | 3660 maybe_res = isolate->factory()->NewRawTwoByteString(result_len); |
3868 } | 3661 } |
3869 Handle<SeqString> untyped_res; | 3662 Handle<SeqString> untyped_res; |
3870 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, untyped_res, maybe_res); | 3663 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, untyped_res, maybe_res); |
3871 Handle<ResultSeqString> result = Handle<ResultSeqString>::cast(untyped_res); | 3664 Handle<ResultSeqString> result = Handle<ResultSeqString>::cast(untyped_res); |
3872 | 3665 |
3873 for (int i = 0; i < matches; i++) { | 3666 for (int i = 0; i < matches; i++) { |
3874 // Copy non-matched subject content. | 3667 // Copy non-matched subject content. |
3875 if (subject_pos < indices.at(i)) { | 3668 if (subject_pos < indices.at(i)) { |
3876 String::WriteToFlat(*subject, | 3669 String::WriteToFlat(*subject, result->GetChars() + result_pos, |
3877 result->GetChars() + result_pos, | 3670 subject_pos, indices.at(i)); |
3878 subject_pos, | |
3879 indices.at(i)); | |
3880 result_pos += indices.at(i) - subject_pos; | 3671 result_pos += indices.at(i) - subject_pos; |
3881 } | 3672 } |
3882 | 3673 |
3883 // Replace match. | 3674 // Replace match. |
3884 if (replacement_len > 0) { | 3675 if (replacement_len > 0) { |
3885 String::WriteToFlat(*replacement, | 3676 String::WriteToFlat(*replacement, result->GetChars() + result_pos, 0, |
3886 result->GetChars() + result_pos, | |
3887 0, | |
3888 replacement_len); | 3677 replacement_len); |
3889 result_pos += replacement_len; | 3678 result_pos += replacement_len; |
3890 } | 3679 } |
3891 | 3680 |
3892 subject_pos = indices.at(i) + pattern_len; | 3681 subject_pos = indices.at(i) + pattern_len; |
3893 } | 3682 } |
3894 // Add remaining subject content at the end. | 3683 // Add remaining subject content at the end. |
3895 if (subject_pos < subject_len) { | 3684 if (subject_pos < subject_len) { |
3896 String::WriteToFlat(*subject, | 3685 String::WriteToFlat(*subject, result->GetChars() + result_pos, subject_pos, |
3897 result->GetChars() + result_pos, | |
3898 subject_pos, | |
3899 subject_len); | 3686 subject_len); |
3900 } | 3687 } |
3901 | 3688 |
3902 int32_t match_indices[] = { indices.at(matches - 1), | 3689 int32_t match_indices[] = {indices.at(matches - 1), |
3903 indices.at(matches - 1) + pattern_len }; | 3690 indices.at(matches - 1) + pattern_len}; |
3904 RegExpImpl::SetLastMatchInfo(last_match_info, subject, 0, match_indices); | 3691 RegExpImpl::SetLastMatchInfo(last_match_info, subject, 0, match_indices); |
3905 | 3692 |
3906 return *result; | 3693 return *result; |
3907 } | 3694 } |
3908 | 3695 |
3909 | 3696 |
3910 MUST_USE_RESULT static Object* StringReplaceGlobalRegExpWithString( | 3697 MUST_USE_RESULT static Object* StringReplaceGlobalRegExpWithString( |
3911 Isolate* isolate, | 3698 Isolate* isolate, Handle<String> subject, Handle<JSRegExp> regexp, |
3912 Handle<String> subject, | 3699 Handle<String> replacement, Handle<JSArray> last_match_info) { |
3913 Handle<JSRegExp> regexp, | |
3914 Handle<String> replacement, | |
3915 Handle<JSArray> last_match_info) { | |
3916 DCHECK(subject->IsFlat()); | 3700 DCHECK(subject->IsFlat()); |
3917 DCHECK(replacement->IsFlat()); | 3701 DCHECK(replacement->IsFlat()); |
3918 | 3702 |
3919 int capture_count = regexp->CaptureCount(); | 3703 int capture_count = regexp->CaptureCount(); |
3920 int subject_length = subject->length(); | 3704 int subject_length = subject->length(); |
3921 | 3705 |
3922 // CompiledReplacement uses zone allocation. | 3706 // CompiledReplacement uses zone allocation. |
3923 ZoneScope zone_scope(isolate->runtime_zone()); | 3707 ZoneScope zone_scope(isolate->runtime_zone()); |
3924 CompiledReplacement compiled_replacement(zone_scope.zone()); | 3708 CompiledReplacement compiled_replacement(zone_scope.zone()); |
3925 bool simple_replace = compiled_replacement.Compile(replacement, | 3709 bool simple_replace = |
3926 capture_count, | 3710 compiled_replacement.Compile(replacement, capture_count, subject_length); |
3927 subject_length); | |
3928 | 3711 |
3929 // Shortcut for simple non-regexp global replacements | 3712 // Shortcut for simple non-regexp global replacements |
3930 if (regexp->TypeTag() == JSRegExp::ATOM && simple_replace) { | 3713 if (regexp->TypeTag() == JSRegExp::ATOM && simple_replace) { |
3931 if (subject->HasOnlyOneByteChars() && | 3714 if (subject->HasOnlyOneByteChars() && replacement->HasOnlyOneByteChars()) { |
3932 replacement->HasOnlyOneByteChars()) { | |
3933 return StringReplaceGlobalAtomRegExpWithString<SeqOneByteString>( | 3715 return StringReplaceGlobalAtomRegExpWithString<SeqOneByteString>( |
3934 isolate, subject, regexp, replacement, last_match_info); | 3716 isolate, subject, regexp, replacement, last_match_info); |
3935 } else { | 3717 } else { |
3936 return StringReplaceGlobalAtomRegExpWithString<SeqTwoByteString>( | 3718 return StringReplaceGlobalAtomRegExpWithString<SeqTwoByteString>( |
3937 isolate, subject, regexp, replacement, last_match_info); | 3719 isolate, subject, regexp, replacement, last_match_info); |
3938 } | 3720 } |
3939 } | 3721 } |
3940 | 3722 |
3941 RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate); | 3723 RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate); |
3942 if (global_cache.HasException()) return isolate->heap()->exception(); | 3724 if (global_cache.HasException()) return isolate->heap()->exception(); |
3943 | 3725 |
3944 int32_t* current_match = global_cache.FetchNext(); | 3726 int32_t* current_match = global_cache.FetchNext(); |
3945 if (current_match == NULL) { | 3727 if (current_match == NULL) { |
3946 if (global_cache.HasException()) return isolate->heap()->exception(); | 3728 if (global_cache.HasException()) return isolate->heap()->exception(); |
3947 return *subject; | 3729 return *subject; |
3948 } | 3730 } |
3949 | 3731 |
3950 // Guessing the number of parts that the final result string is built | 3732 // Guessing the number of parts that the final result string is built |
3951 // from. Global regexps can match any number of times, so we guess | 3733 // from. Global regexps can match any number of times, so we guess |
3952 // conservatively. | 3734 // conservatively. |
3953 int expected_parts = (compiled_replacement.parts() + 1) * 4 + 1; | 3735 int expected_parts = (compiled_replacement.parts() + 1) * 4 + 1; |
3954 ReplacementStringBuilder builder(isolate->heap(), | 3736 ReplacementStringBuilder builder(isolate->heap(), subject, expected_parts); |
3955 subject, | |
3956 expected_parts); | |
3957 | 3737 |
3958 // Number of parts added by compiled replacement plus preceeding | 3738 // Number of parts added by compiled replacement plus preceeding |
3959 // string and possibly suffix after last match. It is possible for | 3739 // string and possibly suffix after last match. It is possible for |
3960 // all components to use two elements when encoded as two smis. | 3740 // all components to use two elements when encoded as two smis. |
3961 const int parts_added_per_loop = 2 * (compiled_replacement.parts() + 2); | 3741 const int parts_added_per_loop = 2 * (compiled_replacement.parts() + 2); |
3962 | 3742 |
3963 int prev = 0; | 3743 int prev = 0; |
3964 | 3744 |
3965 do { | 3745 do { |
3966 builder.EnsureCapacity(parts_added_per_loop); | 3746 builder.EnsureCapacity(parts_added_per_loop); |
3967 | 3747 |
3968 int start = current_match[0]; | 3748 int start = current_match[0]; |
3969 int end = current_match[1]; | 3749 int end = current_match[1]; |
3970 | 3750 |
3971 if (prev < start) { | 3751 if (prev < start) { |
3972 builder.AddSubjectSlice(prev, start); | 3752 builder.AddSubjectSlice(prev, start); |
3973 } | 3753 } |
3974 | 3754 |
3975 if (simple_replace) { | 3755 if (simple_replace) { |
3976 builder.AddString(replacement); | 3756 builder.AddString(replacement); |
3977 } else { | 3757 } else { |
3978 compiled_replacement.Apply(&builder, | 3758 compiled_replacement.Apply(&builder, start, end, current_match); |
3979 start, | |
3980 end, | |
3981 current_match); | |
3982 } | 3759 } |
3983 prev = end; | 3760 prev = end; |
3984 | 3761 |
3985 current_match = global_cache.FetchNext(); | 3762 current_match = global_cache.FetchNext(); |
3986 } while (current_match != NULL); | 3763 } while (current_match != NULL); |
3987 | 3764 |
3988 if (global_cache.HasException()) return isolate->heap()->exception(); | 3765 if (global_cache.HasException()) return isolate->heap()->exception(); |
3989 | 3766 |
3990 if (prev < subject_length) { | 3767 if (prev < subject_length) { |
3991 builder.EnsureCapacity(2); | 3768 builder.EnsureCapacity(2); |
3992 builder.AddSubjectSlice(prev, subject_length); | 3769 builder.AddSubjectSlice(prev, subject_length); |
3993 } | 3770 } |
3994 | 3771 |
3995 RegExpImpl::SetLastMatchInfo(last_match_info, | 3772 RegExpImpl::SetLastMatchInfo(last_match_info, subject, capture_count, |
3996 subject, | |
3997 capture_count, | |
3998 global_cache.LastSuccessfulMatch()); | 3773 global_cache.LastSuccessfulMatch()); |
3999 | 3774 |
4000 Handle<String> result; | 3775 Handle<String> result; |
4001 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, builder.ToString()); | 3776 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, builder.ToString()); |
4002 return *result; | 3777 return *result; |
4003 } | 3778 } |
4004 | 3779 |
4005 | 3780 |
4006 template <typename ResultSeqString> | 3781 template <typename ResultSeqString> |
4007 MUST_USE_RESULT static Object* StringReplaceGlobalRegExpWithEmptyString( | 3782 MUST_USE_RESULT static Object* StringReplaceGlobalRegExpWithEmptyString( |
4008 Isolate* isolate, | 3783 Isolate* isolate, Handle<String> subject, Handle<JSRegExp> regexp, |
4009 Handle<String> subject, | |
4010 Handle<JSRegExp> regexp, | |
4011 Handle<JSArray> last_match_info) { | 3784 Handle<JSArray> last_match_info) { |
4012 DCHECK(subject->IsFlat()); | 3785 DCHECK(subject->IsFlat()); |
4013 | 3786 |
4014 // Shortcut for simple non-regexp global replacements | 3787 // Shortcut for simple non-regexp global replacements |
4015 if (regexp->TypeTag() == JSRegExp::ATOM) { | 3788 if (regexp->TypeTag() == JSRegExp::ATOM) { |
4016 Handle<String> empty_string = isolate->factory()->empty_string(); | 3789 Handle<String> empty_string = isolate->factory()->empty_string(); |
4017 if (subject->IsOneByteRepresentation()) { | 3790 if (subject->IsOneByteRepresentation()) { |
4018 return StringReplaceGlobalAtomRegExpWithString<SeqOneByteString>( | 3791 return StringReplaceGlobalAtomRegExpWithString<SeqOneByteString>( |
4019 isolate, subject, regexp, empty_string, last_match_info); | 3792 isolate, subject, regexp, empty_string, last_match_info); |
4020 } else { | 3793 } else { |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4060 String::WriteToFlat(*subject, answer->GetChars() + position, prev, start); | 3833 String::WriteToFlat(*subject, answer->GetChars() + position, prev, start); |
4061 position += start - prev; | 3834 position += start - prev; |
4062 } | 3835 } |
4063 prev = end; | 3836 prev = end; |
4064 | 3837 |
4065 current_match = global_cache.FetchNext(); | 3838 current_match = global_cache.FetchNext(); |
4066 } while (current_match != NULL); | 3839 } while (current_match != NULL); |
4067 | 3840 |
4068 if (global_cache.HasException()) return isolate->heap()->exception(); | 3841 if (global_cache.HasException()) return isolate->heap()->exception(); |
4069 | 3842 |
4070 RegExpImpl::SetLastMatchInfo(last_match_info, | 3843 RegExpImpl::SetLastMatchInfo(last_match_info, subject, capture_count, |
4071 subject, | |
4072 capture_count, | |
4073 global_cache.LastSuccessfulMatch()); | 3844 global_cache.LastSuccessfulMatch()); |
4074 | 3845 |
4075 if (prev < subject_length) { | 3846 if (prev < subject_length) { |
4076 // Add substring subject[prev;length] to answer string. | 3847 // Add substring subject[prev;length] to answer string. |
4077 String::WriteToFlat( | 3848 String::WriteToFlat(*subject, answer->GetChars() + position, prev, |
4078 *subject, answer->GetChars() + position, prev, subject_length); | 3849 subject_length); |
4079 position += subject_length - prev; | 3850 position += subject_length - prev; |
4080 } | 3851 } |
4081 | 3852 |
4082 if (position == 0) return isolate->heap()->empty_string(); | 3853 if (position == 0) return isolate->heap()->empty_string(); |
4083 | 3854 |
4084 // Shorten string and fill | 3855 // Shorten string and fill |
4085 int string_size = ResultSeqString::SizeFor(position); | 3856 int string_size = ResultSeqString::SizeFor(position); |
4086 int allocated_string_size = ResultSeqString::SizeFor(new_length); | 3857 int allocated_string_size = ResultSeqString::SizeFor(new_length); |
4087 int delta = allocated_string_size - string_size; | 3858 int delta = allocated_string_size - string_size; |
4088 | 3859 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4121 return StringReplaceGlobalRegExpWithEmptyString<SeqOneByteString>( | 3892 return StringReplaceGlobalRegExpWithEmptyString<SeqOneByteString>( |
4122 isolate, subject, regexp, last_match_info); | 3893 isolate, subject, regexp, last_match_info); |
4123 } else { | 3894 } else { |
4124 return StringReplaceGlobalRegExpWithEmptyString<SeqTwoByteString>( | 3895 return StringReplaceGlobalRegExpWithEmptyString<SeqTwoByteString>( |
4125 isolate, subject, regexp, last_match_info); | 3896 isolate, subject, regexp, last_match_info); |
4126 } | 3897 } |
4127 } | 3898 } |
4128 | 3899 |
4129 replacement = String::Flatten(replacement); | 3900 replacement = String::Flatten(replacement); |
4130 | 3901 |
4131 return StringReplaceGlobalRegExpWithString( | 3902 return StringReplaceGlobalRegExpWithString(isolate, subject, regexp, |
4132 isolate, subject, regexp, replacement, last_match_info); | 3903 replacement, last_match_info); |
4133 } | 3904 } |
4134 | 3905 |
4135 | 3906 |
4136 // This may return an empty MaybeHandle if an exception is thrown or | 3907 // This may return an empty MaybeHandle if an exception is thrown or |
4137 // we abort due to reaching the recursion limit. | 3908 // we abort due to reaching the recursion limit. |
4138 MaybeHandle<String> StringReplaceOneCharWithString(Isolate* isolate, | 3909 MaybeHandle<String> StringReplaceOneCharWithString( |
4139 Handle<String> subject, | 3910 Isolate* isolate, Handle<String> subject, Handle<String> search, |
4140 Handle<String> search, | 3911 Handle<String> replace, bool* found, int recursion_limit) { |
4141 Handle<String> replace, | |
4142 bool* found, | |
4143 int recursion_limit) { | |
4144 StackLimitCheck stackLimitCheck(isolate); | 3912 StackLimitCheck stackLimitCheck(isolate); |
4145 if (stackLimitCheck.HasOverflowed() || (recursion_limit == 0)) { | 3913 if (stackLimitCheck.HasOverflowed() || (recursion_limit == 0)) { |
4146 return MaybeHandle<String>(); | 3914 return MaybeHandle<String>(); |
4147 } | 3915 } |
4148 recursion_limit--; | 3916 recursion_limit--; |
4149 if (subject->IsConsString()) { | 3917 if (subject->IsConsString()) { |
4150 ConsString* cons = ConsString::cast(*subject); | 3918 ConsString* cons = ConsString::cast(*subject); |
4151 Handle<String> first = Handle<String>(cons->first()); | 3919 Handle<String> first = Handle<String>(cons->first()); |
4152 Handle<String> second = Handle<String>(cons->second()); | 3920 Handle<String> second = Handle<String>(cons->second()); |
4153 Handle<String> new_first; | 3921 Handle<String> new_first; |
4154 if (!StringReplaceOneCharWithString( | 3922 if (!StringReplaceOneCharWithString(isolate, first, search, replace, found, |
4155 isolate, first, search, replace, found, recursion_limit) | 3923 recursion_limit).ToHandle(&new_first)) { |
4156 .ToHandle(&new_first)) { | |
4157 return MaybeHandle<String>(); | 3924 return MaybeHandle<String>(); |
4158 } | 3925 } |
4159 if (*found) return isolate->factory()->NewConsString(new_first, second); | 3926 if (*found) return isolate->factory()->NewConsString(new_first, second); |
4160 | 3927 |
4161 Handle<String> new_second; | 3928 Handle<String> new_second; |
4162 if (!StringReplaceOneCharWithString( | 3929 if (!StringReplaceOneCharWithString(isolate, second, search, replace, found, |
4163 isolate, second, search, replace, found, recursion_limit) | 3930 recursion_limit) |
4164 .ToHandle(&new_second)) { | 3931 .ToHandle(&new_second)) { |
4165 return MaybeHandle<String>(); | 3932 return MaybeHandle<String>(); |
4166 } | 3933 } |
4167 if (*found) return isolate->factory()->NewConsString(first, new_second); | 3934 if (*found) return isolate->factory()->NewConsString(first, new_second); |
4168 | 3935 |
4169 return subject; | 3936 return subject; |
4170 } else { | 3937 } else { |
4171 int index = Runtime::StringMatch(isolate, subject, search, 0); | 3938 int index = Runtime::StringMatch(isolate, subject, search, 0); |
4172 if (index == -1) return subject; | 3939 if (index == -1) return subject; |
4173 *found = true; | 3940 *found = true; |
4174 Handle<String> first = isolate->factory()->NewSubString(subject, 0, index); | 3941 Handle<String> first = isolate->factory()->NewSubString(subject, 0, index); |
4175 Handle<String> cons1; | 3942 Handle<String> cons1; |
4176 ASSIGN_RETURN_ON_EXCEPTION( | 3943 ASSIGN_RETURN_ON_EXCEPTION( |
4177 isolate, cons1, | 3944 isolate, cons1, isolate->factory()->NewConsString(first, replace), |
4178 isolate->factory()->NewConsString(first, replace), | |
4179 String); | 3945 String); |
4180 Handle<String> second = | 3946 Handle<String> second = |
4181 isolate->factory()->NewSubString(subject, index + 1, subject->length()); | 3947 isolate->factory()->NewSubString(subject, index + 1, subject->length()); |
4182 return isolate->factory()->NewConsString(cons1, second); | 3948 return isolate->factory()->NewConsString(cons1, second); |
4183 } | 3949 } |
4184 } | 3950 } |
4185 | 3951 |
4186 | 3952 |
4187 RUNTIME_FUNCTION(Runtime_StringReplaceOneCharWithString) { | 3953 RUNTIME_FUNCTION(Runtime_StringReplaceOneCharWithString) { |
4188 HandleScope scope(isolate); | 3954 HandleScope scope(isolate); |
4189 DCHECK(args.length() == 3); | 3955 DCHECK(args.length() == 3); |
4190 CONVERT_ARG_HANDLE_CHECKED(String, subject, 0); | 3956 CONVERT_ARG_HANDLE_CHECKED(String, subject, 0); |
4191 CONVERT_ARG_HANDLE_CHECKED(String, search, 1); | 3957 CONVERT_ARG_HANDLE_CHECKED(String, search, 1); |
4192 CONVERT_ARG_HANDLE_CHECKED(String, replace, 2); | 3958 CONVERT_ARG_HANDLE_CHECKED(String, replace, 2); |
4193 | 3959 |
4194 // If the cons string tree is too deep, we simply abort the recursion and | 3960 // If the cons string tree is too deep, we simply abort the recursion and |
4195 // retry with a flattened subject string. | 3961 // retry with a flattened subject string. |
4196 const int kRecursionLimit = 0x1000; | 3962 const int kRecursionLimit = 0x1000; |
4197 bool found = false; | 3963 bool found = false; |
4198 Handle<String> result; | 3964 Handle<String> result; |
4199 if (StringReplaceOneCharWithString( | 3965 if (StringReplaceOneCharWithString(isolate, subject, search, replace, &found, |
4200 isolate, subject, search, replace, &found, kRecursionLimit) | 3966 kRecursionLimit).ToHandle(&result)) { |
4201 .ToHandle(&result)) { | |
4202 return *result; | 3967 return *result; |
4203 } | 3968 } |
4204 if (isolate->has_pending_exception()) return isolate->heap()->exception(); | 3969 if (isolate->has_pending_exception()) return isolate->heap()->exception(); |
4205 | 3970 |
4206 subject = String::Flatten(subject); | 3971 subject = String::Flatten(subject); |
4207 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 3972 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
4208 isolate, result, | 3973 isolate, result, |
4209 StringReplaceOneCharWithString( | 3974 StringReplaceOneCharWithString(isolate, subject, search, replace, &found, |
4210 isolate, subject, search, replace, &found, kRecursionLimit)); | 3975 kRecursionLimit)); |
4211 return *result; | 3976 return *result; |
4212 } | 3977 } |
4213 | 3978 |
4214 | 3979 |
4215 // Perform string match of pattern on subject, starting at start index. | 3980 // Perform string match of pattern on subject, starting at start index. |
4216 // Caller must ensure that 0 <= start_index <= sub->length(), | 3981 // Caller must ensure that 0 <= start_index <= sub->length(), |
4217 // and should check that pat->length() + start_index <= sub->length(). | 3982 // and should check that pat->length() + start_index <= sub->length(). |
4218 int Runtime::StringMatch(Isolate* isolate, | 3983 int Runtime::StringMatch(Isolate* isolate, Handle<String> sub, |
4219 Handle<String> sub, | 3984 Handle<String> pat, int start_index) { |
4220 Handle<String> pat, | |
4221 int start_index) { | |
4222 DCHECK(0 <= start_index); | 3985 DCHECK(0 <= start_index); |
4223 DCHECK(start_index <= sub->length()); | 3986 DCHECK(start_index <= sub->length()); |
4224 | 3987 |
4225 int pattern_length = pat->length(); | 3988 int pattern_length = pat->length(); |
4226 if (pattern_length == 0) return start_index; | 3989 if (pattern_length == 0) return start_index; |
4227 | 3990 |
4228 int subject_length = sub->length(); | 3991 int subject_length = sub->length(); |
4229 if (start_index + pattern_length > subject_length) return -1; | 3992 if (start_index + pattern_length > subject_length) return -1; |
4230 | 3993 |
4231 sub = String::Flatten(sub); | 3994 sub = String::Flatten(sub); |
4232 pat = String::Flatten(pat); | 3995 pat = String::Flatten(pat); |
4233 | 3996 |
4234 DisallowHeapAllocation no_gc; // ensure vectors stay valid | 3997 DisallowHeapAllocation no_gc; // ensure vectors stay valid |
4235 // Extract flattened substrings of cons strings before getting encoding. | 3998 // Extract flattened substrings of cons strings before getting encoding. |
4236 String::FlatContent seq_sub = sub->GetFlatContent(); | 3999 String::FlatContent seq_sub = sub->GetFlatContent(); |
4237 String::FlatContent seq_pat = pat->GetFlatContent(); | 4000 String::FlatContent seq_pat = pat->GetFlatContent(); |
4238 | 4001 |
4239 // dispatch on type of strings | 4002 // dispatch on type of strings |
4240 if (seq_pat.IsOneByte()) { | 4003 if (seq_pat.IsOneByte()) { |
4241 Vector<const uint8_t> pat_vector = seq_pat.ToOneByteVector(); | 4004 Vector<const uint8_t> pat_vector = seq_pat.ToOneByteVector(); |
4242 if (seq_sub.IsOneByte()) { | 4005 if (seq_sub.IsOneByte()) { |
4243 return SearchString(isolate, | 4006 return SearchString(isolate, seq_sub.ToOneByteVector(), pat_vector, |
4244 seq_sub.ToOneByteVector(), | |
4245 pat_vector, | |
4246 start_index); | 4007 start_index); |
4247 } | 4008 } |
4248 return SearchString(isolate, | 4009 return SearchString(isolate, seq_sub.ToUC16Vector(), pat_vector, |
4249 seq_sub.ToUC16Vector(), | |
4250 pat_vector, | |
4251 start_index); | 4010 start_index); |
4252 } | 4011 } |
4253 Vector<const uc16> pat_vector = seq_pat.ToUC16Vector(); | 4012 Vector<const uc16> pat_vector = seq_pat.ToUC16Vector(); |
4254 if (seq_sub.IsOneByte()) { | 4013 if (seq_sub.IsOneByte()) { |
4255 return SearchString(isolate, | 4014 return SearchString(isolate, seq_sub.ToOneByteVector(), pat_vector, |
4256 seq_sub.ToOneByteVector(), | |
4257 pat_vector, | |
4258 start_index); | 4015 start_index); |
4259 } | 4016 } |
4260 return SearchString(isolate, | 4017 return SearchString(isolate, seq_sub.ToUC16Vector(), pat_vector, start_index); |
4261 seq_sub.ToUC16Vector(), | |
4262 pat_vector, | |
4263 start_index); | |
4264 } | 4018 } |
4265 | 4019 |
4266 | 4020 |
4267 RUNTIME_FUNCTION(Runtime_StringIndexOf) { | 4021 RUNTIME_FUNCTION(Runtime_StringIndexOf) { |
4268 HandleScope scope(isolate); | 4022 HandleScope scope(isolate); |
4269 DCHECK(args.length() == 3); | 4023 DCHECK(args.length() == 3); |
4270 | 4024 |
4271 CONVERT_ARG_HANDLE_CHECKED(String, sub, 0); | 4025 CONVERT_ARG_HANDLE_CHECKED(String, sub, 0); |
4272 CONVERT_ARG_HANDLE_CHECKED(String, pat, 1); | 4026 CONVERT_ARG_HANDLE_CHECKED(String, pat, 1); |
4273 CONVERT_ARG_HANDLE_CHECKED(Object, index, 2); | 4027 CONVERT_ARG_HANDLE_CHECKED(Object, index, 2); |
4274 | 4028 |
4275 uint32_t start_index; | 4029 uint32_t start_index; |
4276 if (!index->ToArrayIndex(&start_index)) return Smi::FromInt(-1); | 4030 if (!index->ToArrayIndex(&start_index)) return Smi::FromInt(-1); |
4277 | 4031 |
4278 RUNTIME_ASSERT(start_index <= static_cast<uint32_t>(sub->length())); | 4032 RUNTIME_ASSERT(start_index <= static_cast<uint32_t>(sub->length())); |
4279 int position = Runtime::StringMatch(isolate, sub, pat, start_index); | 4033 int position = Runtime::StringMatch(isolate, sub, pat, start_index); |
4280 return Smi::FromInt(position); | 4034 return Smi::FromInt(position); |
4281 } | 4035 } |
4282 | 4036 |
4283 | 4037 |
4284 template <typename schar, typename pchar> | 4038 template <typename schar, typename pchar> |
4285 static int StringMatchBackwards(Vector<const schar> subject, | 4039 static int StringMatchBackwards(Vector<const schar> subject, |
4286 Vector<const pchar> pattern, | 4040 Vector<const pchar> pattern, int idx) { |
4287 int idx) { | |
4288 int pattern_length = pattern.length(); | 4041 int pattern_length = pattern.length(); |
4289 DCHECK(pattern_length >= 1); | 4042 DCHECK(pattern_length >= 1); |
4290 DCHECK(idx + pattern_length <= subject.length()); | 4043 DCHECK(idx + pattern_length <= subject.length()); |
4291 | 4044 |
4292 if (sizeof(schar) == 1 && sizeof(pchar) > 1) { | 4045 if (sizeof(schar) == 1 && sizeof(pchar) > 1) { |
4293 for (int i = 0; i < pattern_length; i++) { | 4046 for (int i = 0; i < pattern_length; i++) { |
4294 uc16 c = pattern[i]; | 4047 uc16 c = pattern[i]; |
4295 if (c > String::kMaxOneByteCharCode) { | 4048 if (c > String::kMaxOneByteCharCode) { |
4296 return -1; | 4049 return -1; |
4297 } | 4050 } |
4298 } | 4051 } |
4299 } | 4052 } |
4300 | 4053 |
4301 pchar pattern_first_char = pattern[0]; | 4054 pchar pattern_first_char = pattern[0]; |
4302 for (int i = idx; i >= 0; i--) { | 4055 for (int i = idx; i >= 0; i--) { |
4303 if (subject[i] != pattern_first_char) continue; | 4056 if (subject[i] != pattern_first_char) continue; |
4304 int j = 1; | 4057 int j = 1; |
4305 while (j < pattern_length) { | 4058 while (j < pattern_length) { |
4306 if (pattern[j] != subject[i+j]) { | 4059 if (pattern[j] != subject[i + j]) { |
4307 break; | 4060 break; |
4308 } | 4061 } |
4309 j++; | 4062 j++; |
4310 } | 4063 } |
4311 if (j == pattern_length) { | 4064 if (j == pattern_length) { |
4312 return i; | 4065 return i; |
4313 } | 4066 } |
4314 } | 4067 } |
4315 return -1; | 4068 return -1; |
4316 } | 4069 } |
(...skipping 26 matching lines...) Expand all Loading... |
4343 | 4096 |
4344 int position = -1; | 4097 int position = -1; |
4345 DisallowHeapAllocation no_gc; // ensure vectors stay valid | 4098 DisallowHeapAllocation no_gc; // ensure vectors stay valid |
4346 | 4099 |
4347 String::FlatContent sub_content = sub->GetFlatContent(); | 4100 String::FlatContent sub_content = sub->GetFlatContent(); |
4348 String::FlatContent pat_content = pat->GetFlatContent(); | 4101 String::FlatContent pat_content = pat->GetFlatContent(); |
4349 | 4102 |
4350 if (pat_content.IsOneByte()) { | 4103 if (pat_content.IsOneByte()) { |
4351 Vector<const uint8_t> pat_vector = pat_content.ToOneByteVector(); | 4104 Vector<const uint8_t> pat_vector = pat_content.ToOneByteVector(); |
4352 if (sub_content.IsOneByte()) { | 4105 if (sub_content.IsOneByte()) { |
4353 position = StringMatchBackwards(sub_content.ToOneByteVector(), | 4106 position = StringMatchBackwards(sub_content.ToOneByteVector(), pat_vector, |
4354 pat_vector, | |
4355 start_index); | 4107 start_index); |
4356 } else { | 4108 } else { |
4357 position = StringMatchBackwards(sub_content.ToUC16Vector(), | 4109 position = StringMatchBackwards(sub_content.ToUC16Vector(), pat_vector, |
4358 pat_vector, | |
4359 start_index); | 4110 start_index); |
4360 } | 4111 } |
4361 } else { | 4112 } else { |
4362 Vector<const uc16> pat_vector = pat_content.ToUC16Vector(); | 4113 Vector<const uc16> pat_vector = pat_content.ToUC16Vector(); |
4363 if (sub_content.IsOneByte()) { | 4114 if (sub_content.IsOneByte()) { |
4364 position = StringMatchBackwards(sub_content.ToOneByteVector(), | 4115 position = StringMatchBackwards(sub_content.ToOneByteVector(), pat_vector, |
4365 pat_vector, | |
4366 start_index); | 4116 start_index); |
4367 } else { | 4117 } else { |
4368 position = StringMatchBackwards(sub_content.ToUC16Vector(), | 4118 position = StringMatchBackwards(sub_content.ToUC16Vector(), pat_vector, |
4369 pat_vector, | |
4370 start_index); | 4119 start_index); |
4371 } | 4120 } |
4372 } | 4121 } |
4373 | 4122 |
4374 return Smi::FromInt(position); | 4123 return Smi::FromInt(position); |
4375 } | 4124 } |
4376 | 4125 |
4377 | 4126 |
4378 RUNTIME_FUNCTION(Runtime_StringLocaleCompare) { | 4127 RUNTIME_FUNCTION(Runtime_StringLocaleCompare) { |
4379 HandleScope handle_scope(isolate); | 4128 HandleScope handle_scope(isolate); |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4480 offsets.Add(match[1], zone_scope.zone()); // end | 4229 offsets.Add(match[1], zone_scope.zone()); // end |
4481 } | 4230 } |
4482 | 4231 |
4483 if (global_cache.HasException()) return isolate->heap()->exception(); | 4232 if (global_cache.HasException()) return isolate->heap()->exception(); |
4484 | 4233 |
4485 if (offsets.length() == 0) { | 4234 if (offsets.length() == 0) { |
4486 // Not a single match. | 4235 // Not a single match. |
4487 return isolate->heap()->null_value(); | 4236 return isolate->heap()->null_value(); |
4488 } | 4237 } |
4489 | 4238 |
4490 RegExpImpl::SetLastMatchInfo(regexp_info, | 4239 RegExpImpl::SetLastMatchInfo(regexp_info, subject, capture_count, |
4491 subject, | |
4492 capture_count, | |
4493 global_cache.LastSuccessfulMatch()); | 4240 global_cache.LastSuccessfulMatch()); |
4494 | 4241 |
4495 int matches = offsets.length() / 2; | 4242 int matches = offsets.length() / 2; |
4496 Handle<FixedArray> elements = isolate->factory()->NewFixedArray(matches); | 4243 Handle<FixedArray> elements = isolate->factory()->NewFixedArray(matches); |
4497 Handle<String> substring = | 4244 Handle<String> substring = |
4498 isolate->factory()->NewSubString(subject, offsets.at(0), offsets.at(1)); | 4245 isolate->factory()->NewSubString(subject, offsets.at(0), offsets.at(1)); |
4499 elements->set(0, *substring); | 4246 elements->set(0, *substring); |
4500 for (int i = 1; i < matches; i++) { | 4247 for (int i = 1; i < matches; i++) { |
4501 HandleScope temp_scope(isolate); | 4248 HandleScope temp_scope(isolate); |
4502 int from = offsets.at(i * 2); | 4249 int from = offsets.at(i * 2); |
4503 int to = offsets.at(i * 2 + 1); | 4250 int to = offsets.at(i * 2 + 1); |
4504 Handle<String> substring = | 4251 Handle<String> substring = |
4505 isolate->factory()->NewProperSubString(subject, from, to); | 4252 isolate->factory()->NewProperSubString(subject, from, to); |
4506 elements->set(i, *substring); | 4253 elements->set(i, *substring); |
4507 } | 4254 } |
4508 Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements(elements); | 4255 Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements(elements); |
4509 result->set_length(Smi::FromInt(matches)); | 4256 result->set_length(Smi::FromInt(matches)); |
4510 return *result; | 4257 return *result; |
4511 } | 4258 } |
4512 | 4259 |
4513 | 4260 |
4514 // Only called from Runtime_RegExpExecMultiple so it doesn't need to maintain | 4261 // Only called from Runtime_RegExpExecMultiple so it doesn't need to maintain |
4515 // separate last match info. See comment on that function. | 4262 // separate last match info. See comment on that function. |
4516 template<bool has_capture> | 4263 template <bool has_capture> |
4517 static Object* SearchRegExpMultiple( | 4264 static Object* SearchRegExpMultiple(Isolate* isolate, Handle<String> subject, |
4518 Isolate* isolate, | 4265 Handle<JSRegExp> regexp, |
4519 Handle<String> subject, | 4266 Handle<JSArray> last_match_array, |
4520 Handle<JSRegExp> regexp, | 4267 Handle<JSArray> result_array) { |
4521 Handle<JSArray> last_match_array, | |
4522 Handle<JSArray> result_array) { | |
4523 DCHECK(subject->IsFlat()); | 4268 DCHECK(subject->IsFlat()); |
4524 DCHECK_NE(has_capture, regexp->CaptureCount() == 0); | 4269 DCHECK_NE(has_capture, regexp->CaptureCount() == 0); |
4525 | 4270 |
4526 int capture_count = regexp->CaptureCount(); | 4271 int capture_count = regexp->CaptureCount(); |
4527 int subject_length = subject->length(); | 4272 int subject_length = subject->length(); |
4528 | 4273 |
4529 static const int kMinLengthToCache = 0x1000; | 4274 static const int kMinLengthToCache = 0x1000; |
4530 | 4275 |
4531 if (subject_length > kMinLengthToCache) { | 4276 if (subject_length > kMinLengthToCache) { |
4532 Handle<Object> cached_answer(RegExpResultsCache::Lookup( | 4277 Handle<Object> cached_answer( |
4533 isolate->heap(), | 4278 RegExpResultsCache::Lookup(isolate->heap(), *subject, regexp->data(), |
4534 *subject, | 4279 RegExpResultsCache::REGEXP_MULTIPLE_INDICES), |
4535 regexp->data(), | 4280 isolate); |
4536 RegExpResultsCache::REGEXP_MULTIPLE_INDICES), isolate); | |
4537 if (*cached_answer != Smi::FromInt(0)) { | 4281 if (*cached_answer != Smi::FromInt(0)) { |
4538 Handle<FixedArray> cached_fixed_array = | 4282 Handle<FixedArray> cached_fixed_array = |
4539 Handle<FixedArray>(FixedArray::cast(*cached_answer)); | 4283 Handle<FixedArray>(FixedArray::cast(*cached_answer)); |
4540 // The cache FixedArray is a COW-array and can therefore be reused. | 4284 // The cache FixedArray is a COW-array and can therefore be reused. |
4541 JSArray::SetContent(result_array, cached_fixed_array); | 4285 JSArray::SetContent(result_array, cached_fixed_array); |
4542 // The actual length of the result array is stored in the last element of | 4286 // The actual length of the result array is stored in the last element of |
4543 // the backing store (the backing FixedArray may have a larger capacity). | 4287 // the backing store (the backing FixedArray may have a larger capacity). |
4544 Object* cached_fixed_array_last_element = | 4288 Object* cached_fixed_array_last_element = |
4545 cached_fixed_array->get(cached_fixed_array->length() - 1); | 4289 cached_fixed_array->get(cached_fixed_array->length() - 1); |
4546 Smi* js_array_length = Smi::cast(cached_fixed_array_last_element); | 4290 Smi* js_array_length = Smi::cast(cached_fixed_array_last_element); |
4547 result_array->set_length(js_array_length); | 4291 result_array->set_length(js_array_length); |
4548 RegExpImpl::SetLastMatchInfo( | 4292 RegExpImpl::SetLastMatchInfo(last_match_array, subject, capture_count, |
4549 last_match_array, subject, capture_count, NULL); | 4293 NULL); |
4550 return *result_array; | 4294 return *result_array; |
4551 } | 4295 } |
4552 } | 4296 } |
4553 | 4297 |
4554 RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate); | 4298 RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate); |
4555 if (global_cache.HasException()) return isolate->heap()->exception(); | 4299 if (global_cache.HasException()) return isolate->heap()->exception(); |
4556 | 4300 |
4557 // Ensured in Runtime_RegExpExecMultiple. | 4301 // Ensured in Runtime_RegExpExecMultiple. |
4558 DCHECK(result_array->HasFastObjectElements()); | 4302 DCHECK(result_array->HasFastObjectElements()); |
4559 Handle<FixedArray> result_elements( | 4303 Handle<FixedArray> result_elements( |
(...skipping 11 matching lines...) Expand all Loading... |
4571 | 4315 |
4572 // Two smis before and after the match, for very long strings. | 4316 // Two smis before and after the match, for very long strings. |
4573 static const int kMaxBuilderEntriesPerRegExpMatch = 5; | 4317 static const int kMaxBuilderEntriesPerRegExpMatch = 5; |
4574 | 4318 |
4575 while (true) { | 4319 while (true) { |
4576 int32_t* current_match = global_cache.FetchNext(); | 4320 int32_t* current_match = global_cache.FetchNext(); |
4577 if (current_match == NULL) break; | 4321 if (current_match == NULL) break; |
4578 match_start = current_match[0]; | 4322 match_start = current_match[0]; |
4579 builder.EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch); | 4323 builder.EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch); |
4580 if (match_end < match_start) { | 4324 if (match_end < match_start) { |
4581 ReplacementStringBuilder::AddSubjectSlice(&builder, | 4325 ReplacementStringBuilder::AddSubjectSlice(&builder, match_end, |
4582 match_end, | |
4583 match_start); | 4326 match_start); |
4584 } | 4327 } |
4585 match_end = current_match[1]; | 4328 match_end = current_match[1]; |
4586 { | 4329 { |
4587 // Avoid accumulating new handles inside loop. | 4330 // Avoid accumulating new handles inside loop. |
4588 HandleScope temp_scope(isolate); | 4331 HandleScope temp_scope(isolate); |
4589 Handle<String> match; | 4332 Handle<String> match; |
4590 if (!first) { | 4333 if (!first) { |
4591 match = isolate->factory()->NewProperSubString(subject, | 4334 match = isolate->factory()->NewProperSubString(subject, match_start, |
4592 match_start, | |
4593 match_end); | 4335 match_end); |
4594 } else { | 4336 } else { |
4595 match = isolate->factory()->NewSubString(subject, | 4337 match = |
4596 match_start, | 4338 isolate->factory()->NewSubString(subject, match_start, match_end); |
4597 match_end); | |
4598 first = false; | 4339 first = false; |
4599 } | 4340 } |
4600 | 4341 |
4601 if (has_capture) { | 4342 if (has_capture) { |
4602 // Arguments array to replace function is match, captures, index and | 4343 // Arguments array to replace function is match, captures, index and |
4603 // subject, i.e., 3 + capture count in total. | 4344 // subject, i.e., 3 + capture count in total. |
4604 Handle<FixedArray> elements = | 4345 Handle<FixedArray> elements = |
4605 isolate->factory()->NewFixedArray(3 + capture_count); | 4346 isolate->factory()->NewFixedArray(3 + capture_count); |
4606 | 4347 |
4607 elements->set(0, *match); | 4348 elements->set(0, *match); |
(...skipping 17 matching lines...) Expand all Loading... |
4625 builder.Add(*match); | 4366 builder.Add(*match); |
4626 } | 4367 } |
4627 } | 4368 } |
4628 } | 4369 } |
4629 | 4370 |
4630 if (global_cache.HasException()) return isolate->heap()->exception(); | 4371 if (global_cache.HasException()) return isolate->heap()->exception(); |
4631 | 4372 |
4632 if (match_start >= 0) { | 4373 if (match_start >= 0) { |
4633 // Finished matching, with at least one match. | 4374 // Finished matching, with at least one match. |
4634 if (match_end < subject_length) { | 4375 if (match_end < subject_length) { |
4635 ReplacementStringBuilder::AddSubjectSlice(&builder, | 4376 ReplacementStringBuilder::AddSubjectSlice(&builder, match_end, |
4636 match_end, | |
4637 subject_length); | 4377 subject_length); |
4638 } | 4378 } |
4639 | 4379 |
4640 RegExpImpl::SetLastMatchInfo( | 4380 RegExpImpl::SetLastMatchInfo(last_match_array, subject, capture_count, |
4641 last_match_array, subject, capture_count, NULL); | 4381 NULL); |
4642 | 4382 |
4643 if (subject_length > kMinLengthToCache) { | 4383 if (subject_length > kMinLengthToCache) { |
4644 // Store the length of the result array into the last element of the | 4384 // Store the length of the result array into the last element of the |
4645 // backing FixedArray. | 4385 // backing FixedArray. |
4646 builder.EnsureCapacity(1); | 4386 builder.EnsureCapacity(1); |
4647 Handle<FixedArray> fixed_array = builder.array(); | 4387 Handle<FixedArray> fixed_array = builder.array(); |
4648 fixed_array->set(fixed_array->length() - 1, | 4388 fixed_array->set(fixed_array->length() - 1, |
4649 Smi::FromInt(builder.length())); | 4389 Smi::FromInt(builder.length())); |
4650 // Cache the result and turn the FixedArray into a COW array. | 4390 // Cache the result and turn the FixedArray into a COW array. |
4651 RegExpResultsCache::Enter(isolate, | 4391 RegExpResultsCache::Enter(isolate, subject, |
4652 subject, | 4392 handle(regexp->data(), isolate), fixed_array, |
4653 handle(regexp->data(), isolate), | |
4654 fixed_array, | |
4655 RegExpResultsCache::REGEXP_MULTIPLE_INDICES); | 4393 RegExpResultsCache::REGEXP_MULTIPLE_INDICES); |
4656 } | 4394 } |
4657 return *builder.ToJSArray(result_array); | 4395 return *builder.ToJSArray(result_array); |
4658 } else { | 4396 } else { |
4659 return isolate->heap()->null_value(); // No matches at all. | 4397 return isolate->heap()->null_value(); // No matches at all. |
4660 } | 4398 } |
4661 } | 4399 } |
4662 | 4400 |
4663 | 4401 |
4664 // This is only called for StringReplaceGlobalRegExpWithFunction. This sets | 4402 // This is only called for StringReplaceGlobalRegExpWithFunction. This sets |
4665 // lastMatchInfoOverride to maintain the last match info, so we don't need to | 4403 // lastMatchInfoOverride to maintain the last match info, so we don't need to |
4666 // set any other last match array info. | 4404 // set any other last match array info. |
4667 RUNTIME_FUNCTION(Runtime_RegExpExecMultiple) { | 4405 RUNTIME_FUNCTION(Runtime_RegExpExecMultiple) { |
4668 HandleScope handles(isolate); | 4406 HandleScope handles(isolate); |
4669 DCHECK(args.length() == 4); | 4407 DCHECK(args.length() == 4); |
4670 | 4408 |
4671 CONVERT_ARG_HANDLE_CHECKED(String, subject, 1); | 4409 CONVERT_ARG_HANDLE_CHECKED(String, subject, 1); |
4672 CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0); | 4410 CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0); |
4673 CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 2); | 4411 CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 2); |
4674 CONVERT_ARG_HANDLE_CHECKED(JSArray, result_array, 3); | 4412 CONVERT_ARG_HANDLE_CHECKED(JSArray, result_array, 3); |
4675 RUNTIME_ASSERT(last_match_info->HasFastObjectElements()); | 4413 RUNTIME_ASSERT(last_match_info->HasFastObjectElements()); |
4676 RUNTIME_ASSERT(result_array->HasFastObjectElements()); | 4414 RUNTIME_ASSERT(result_array->HasFastObjectElements()); |
4677 | 4415 |
4678 subject = String::Flatten(subject); | 4416 subject = String::Flatten(subject); |
4679 RUNTIME_ASSERT(regexp->GetFlags().is_global()); | 4417 RUNTIME_ASSERT(regexp->GetFlags().is_global()); |
4680 | 4418 |
4681 if (regexp->CaptureCount() == 0) { | 4419 if (regexp->CaptureCount() == 0) { |
4682 return SearchRegExpMultiple<false>( | 4420 return SearchRegExpMultiple<false>(isolate, subject, regexp, |
4683 isolate, subject, regexp, last_match_info, result_array); | 4421 last_match_info, result_array); |
4684 } else { | 4422 } else { |
4685 return SearchRegExpMultiple<true>( | 4423 return SearchRegExpMultiple<true>(isolate, subject, regexp, last_match_info, |
4686 isolate, subject, regexp, last_match_info, result_array); | 4424 result_array); |
4687 } | 4425 } |
4688 } | 4426 } |
4689 | 4427 |
4690 | 4428 |
4691 RUNTIME_FUNCTION(Runtime_NumberToRadixString) { | 4429 RUNTIME_FUNCTION(Runtime_NumberToRadixString) { |
4692 HandleScope scope(isolate); | 4430 HandleScope scope(isolate); |
4693 DCHECK(args.length() == 2); | 4431 DCHECK(args.length() == 2); |
4694 CONVERT_SMI_ARG_CHECKED(radix, 1); | 4432 CONVERT_SMI_ARG_CHECKED(radix, 1); |
4695 RUNTIME_ASSERT(2 <= radix && radix <= 36); | 4433 RUNTIME_ASSERT(2 <= radix && radix <= 36); |
4696 | 4434 |
4697 // Fast case where the result is a one character string. | 4435 // Fast case where the result is a one character string. |
4698 if (args[0]->IsSmi()) { | 4436 if (args[0]->IsSmi()) { |
4699 int value = args.smi_at(0); | 4437 int value = args.smi_at(0); |
4700 if (value >= 0 && value < radix) { | 4438 if (value >= 0 && value < radix) { |
4701 // Character array used for conversion. | 4439 // Character array used for conversion. |
4702 static const char kCharTable[] = "0123456789abcdefghijklmnopqrstuvwxyz"; | 4440 static const char kCharTable[] = "0123456789abcdefghijklmnopqrstuvwxyz"; |
4703 return *isolate->factory()-> | 4441 return *isolate->factory()->LookupSingleCharacterStringFromCode( |
4704 LookupSingleCharacterStringFromCode(kCharTable[value]); | 4442 kCharTable[value]); |
4705 } | 4443 } |
4706 } | 4444 } |
4707 | 4445 |
4708 // Slow case. | 4446 // Slow case. |
4709 CONVERT_DOUBLE_ARG_CHECKED(value, 0); | 4447 CONVERT_DOUBLE_ARG_CHECKED(value, 0); |
4710 if (std::isnan(value)) { | 4448 if (std::isnan(value)) { |
4711 return isolate->heap()->nan_string(); | 4449 return isolate->heap()->nan_string(); |
4712 } | 4450 } |
4713 if (std::isinf(value)) { | 4451 if (std::isinf(value)) { |
4714 if (value < 0) { | 4452 if (value < 0) { |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4820 } | 4558 } |
4821 } | 4559 } |
4822 | 4560 |
4823 | 4561 |
4824 MUST_USE_RESULT | 4562 MUST_USE_RESULT |
4825 static MaybeHandle<Name> ToName(Isolate* isolate, Handle<Object> key) { | 4563 static MaybeHandle<Name> ToName(Isolate* isolate, Handle<Object> key) { |
4826 if (key->IsName()) { | 4564 if (key->IsName()) { |
4827 return Handle<Name>::cast(key); | 4565 return Handle<Name>::cast(key); |
4828 } else { | 4566 } else { |
4829 Handle<Object> converted; | 4567 Handle<Object> converted; |
4830 ASSIGN_RETURN_ON_EXCEPTION( | 4568 ASSIGN_RETURN_ON_EXCEPTION(isolate, converted, |
4831 isolate, converted, Execution::ToString(isolate, key), Name); | 4569 Execution::ToString(isolate, key), Name); |
4832 return Handle<Name>::cast(converted); | 4570 return Handle<Name>::cast(converted); |
4833 } | 4571 } |
4834 } | 4572 } |
4835 | 4573 |
4836 | 4574 |
4837 MaybeHandle<Object> Runtime::HasObjectProperty(Isolate* isolate, | 4575 MaybeHandle<Object> Runtime::HasObjectProperty(Isolate* isolate, |
4838 Handle<JSReceiver> object, | 4576 Handle<JSReceiver> object, |
4839 Handle<Object> key) { | 4577 Handle<Object> key) { |
4840 Maybe<bool> maybe; | 4578 Maybe<bool> maybe; |
4841 // Check if the given key is an array index. | 4579 // Check if the given key is an array index. |
(...skipping 10 matching lines...) Expand all Loading... |
4852 | 4590 |
4853 if (!maybe.has_value) return MaybeHandle<Object>(); | 4591 if (!maybe.has_value) return MaybeHandle<Object>(); |
4854 return isolate->factory()->ToBoolean(maybe.value); | 4592 return isolate->factory()->ToBoolean(maybe.value); |
4855 } | 4593 } |
4856 | 4594 |
4857 | 4595 |
4858 MaybeHandle<Object> Runtime::GetObjectProperty(Isolate* isolate, | 4596 MaybeHandle<Object> Runtime::GetObjectProperty(Isolate* isolate, |
4859 Handle<Object> object, | 4597 Handle<Object> object, |
4860 Handle<Object> key) { | 4598 Handle<Object> key) { |
4861 if (object->IsUndefined() || object->IsNull()) { | 4599 if (object->IsUndefined() || object->IsNull()) { |
4862 Handle<Object> args[2] = { key, object }; | 4600 Handle<Object> args[2] = {key, object}; |
4863 THROW_NEW_ERROR(isolate, NewTypeError("non_object_property_load", | 4601 THROW_NEW_ERROR(isolate, NewTypeError("non_object_property_load", |
4864 HandleVector(args, 2)), | 4602 HandleVector(args, 2)), |
4865 Object); | 4603 Object); |
4866 } | 4604 } |
4867 | 4605 |
4868 // Check if the given key is an array index. | 4606 // Check if the given key is an array index. |
4869 uint32_t index; | 4607 uint32_t index; |
4870 if (key->ToArrayIndex(&index)) { | 4608 if (key->ToArrayIndex(&index)) { |
4871 return GetElementOrCharAt(isolate, object, index); | 4609 return GetElementOrCharAt(isolate, object, index); |
4872 } | 4610 } |
(...skipping 13 matching lines...) Expand all Loading... |
4886 | 4624 |
4887 | 4625 |
4888 RUNTIME_FUNCTION(Runtime_GetProperty) { | 4626 RUNTIME_FUNCTION(Runtime_GetProperty) { |
4889 HandleScope scope(isolate); | 4627 HandleScope scope(isolate); |
4890 DCHECK(args.length() == 2); | 4628 DCHECK(args.length() == 2); |
4891 | 4629 |
4892 CONVERT_ARG_HANDLE_CHECKED(Object, object, 0); | 4630 CONVERT_ARG_HANDLE_CHECKED(Object, object, 0); |
4893 CONVERT_ARG_HANDLE_CHECKED(Object, key, 1); | 4631 CONVERT_ARG_HANDLE_CHECKED(Object, key, 1); |
4894 Handle<Object> result; | 4632 Handle<Object> result; |
4895 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 4633 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
4896 isolate, result, | 4634 isolate, result, Runtime::GetObjectProperty(isolate, object, key)); |
4897 Runtime::GetObjectProperty(isolate, object, key)); | |
4898 return *result; | 4635 return *result; |
4899 } | 4636 } |
4900 | 4637 |
4901 | 4638 |
4902 // KeyedGetProperty is called from KeyedLoadIC::GenerateGeneric. | 4639 // KeyedGetProperty is called from KeyedLoadIC::GenerateGeneric. |
4903 RUNTIME_FUNCTION(Runtime_KeyedGetProperty) { | 4640 RUNTIME_FUNCTION(Runtime_KeyedGetProperty) { |
4904 HandleScope scope(isolate); | 4641 HandleScope scope(isolate); |
4905 DCHECK(args.length() == 2); | 4642 DCHECK(args.length() == 2); |
4906 | 4643 |
4907 CONVERT_ARG_HANDLE_CHECKED(Object, receiver_obj, 0); | 4644 CONVERT_ARG_HANDLE_CHECKED(Object, receiver_obj, 0); |
4908 CONVERT_ARG_HANDLE_CHECKED(Object, key_obj, 1); | 4645 CONVERT_ARG_HANDLE_CHECKED(Object, key_obj, 1); |
4909 | 4646 |
4910 // Fast cases for getting named properties of the receiver JSObject | 4647 // Fast cases for getting named properties of the receiver JSObject |
4911 // itself. | 4648 // itself. |
4912 // | 4649 // |
4913 // The global proxy objects has to be excluded since LookupOwn on | 4650 // The global proxy objects has to be excluded since LookupOwn on |
4914 // the global proxy object can return a valid result even though the | 4651 // the global proxy object can return a valid result even though the |
4915 // global proxy object never has properties. This is the case | 4652 // global proxy object never has properties. This is the case |
4916 // because the global proxy object forwards everything to its hidden | 4653 // because the global proxy object forwards everything to its hidden |
4917 // prototype including own lookups. | 4654 // prototype including own lookups. |
4918 // | 4655 // |
4919 // Additionally, we need to make sure that we do not cache results | 4656 // Additionally, we need to make sure that we do not cache results |
4920 // for objects that require access checks. | 4657 // for objects that require access checks. |
4921 if (receiver_obj->IsJSObject()) { | 4658 if (receiver_obj->IsJSObject()) { |
4922 if (!receiver_obj->IsJSGlobalProxy() && | 4659 if (!receiver_obj->IsJSGlobalProxy() && |
4923 !receiver_obj->IsAccessCheckNeeded() && | 4660 !receiver_obj->IsAccessCheckNeeded() && key_obj->IsName()) { |
4924 key_obj->IsName()) { | |
4925 DisallowHeapAllocation no_allocation; | 4661 DisallowHeapAllocation no_allocation; |
4926 Handle<JSObject> receiver = Handle<JSObject>::cast(receiver_obj); | 4662 Handle<JSObject> receiver = Handle<JSObject>::cast(receiver_obj); |
4927 Handle<Name> key = Handle<Name>::cast(key_obj); | 4663 Handle<Name> key = Handle<Name>::cast(key_obj); |
4928 if (receiver->HasFastProperties()) { | 4664 if (receiver->HasFastProperties()) { |
4929 // Attempt to use lookup cache. | 4665 // Attempt to use lookup cache. |
4930 Handle<Map> receiver_map(receiver->map(), isolate); | 4666 Handle<Map> receiver_map(receiver->map(), isolate); |
4931 KeyedLookupCache* keyed_lookup_cache = isolate->keyed_lookup_cache(); | 4667 KeyedLookupCache* keyed_lookup_cache = isolate->keyed_lookup_cache(); |
4932 int index = keyed_lookup_cache->Lookup(receiver_map, key); | 4668 int index = keyed_lookup_cache->Lookup(receiver_map, key); |
4933 if (index != -1) { | 4669 if (index != -1) { |
4934 // Doubles are not cached, so raw read the value. | 4670 // Doubles are not cached, so raw read the value. |
4935 return receiver->RawFastPropertyAt( | 4671 return receiver->RawFastPropertyAt( |
4936 FieldIndex::ForKeyedLookupCacheIndex(*receiver_map, index)); | 4672 FieldIndex::ForKeyedLookupCacheIndex(*receiver_map, index)); |
4937 } | 4673 } |
4938 // Lookup cache miss. Perform lookup and update the cache if | 4674 // Lookup cache miss. Perform lookup and update the cache if |
4939 // appropriate. | 4675 // appropriate. |
4940 LookupIterator it(receiver, key, LookupIterator::OWN); | 4676 LookupIterator it(receiver, key, LookupIterator::OWN); |
4941 if (it.state() == LookupIterator::DATA && | 4677 if (it.state() == LookupIterator::DATA && |
4942 it.property_details().type() == FIELD) { | 4678 it.property_details().type() == FIELD) { |
4943 FieldIndex field_index = it.GetFieldIndex(); | 4679 FieldIndex field_index = it.GetFieldIndex(); |
4944 // Do not track double fields in the keyed lookup cache. Reading | 4680 // Do not track double fields in the keyed lookup cache. Reading |
4945 // double values requires boxing. | 4681 // double values requires boxing. |
4946 if (!it.representation().IsDouble()) { | 4682 if (!it.representation().IsDouble()) { |
4947 keyed_lookup_cache->Update(receiver_map, key, | 4683 keyed_lookup_cache->Update(receiver_map, key, |
4948 field_index.GetKeyedLookupCacheIndex()); | 4684 field_index.GetKeyedLookupCacheIndex()); |
4949 } | 4685 } |
4950 AllowHeapAllocation allow_allocation; | 4686 AllowHeapAllocation allow_allocation; |
4951 return *JSObject::FastPropertyAt(receiver, it.representation(), | 4687 return *JSObject::FastPropertyAt(receiver, it.representation(), |
4952 field_index); | 4688 field_index); |
4953 } | 4689 } |
4954 } else { | 4690 } else { |
4955 // Attempt dictionary lookup. | 4691 // Attempt dictionary lookup. |
4956 NameDictionary* dictionary = receiver->property_dictionary(); | 4692 NameDictionary* dictionary = receiver->property_dictionary(); |
4957 int entry = dictionary->FindEntry(key); | 4693 int entry = dictionary->FindEntry(key); |
4958 if ((entry != NameDictionary::kNotFound) && | 4694 if ((entry != NameDictionary::kNotFound) && |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5097 | 4833 |
5098 // Take special care when attributes are different and there is already | 4834 // Take special care when attributes are different and there is already |
5099 // a property. | 4835 // a property. |
5100 if (it.state() == LookupIterator::ACCESSOR) { | 4836 if (it.state() == LookupIterator::ACCESSOR) { |
5101 // Use IgnoreAttributes version since a readonly property may be | 4837 // Use IgnoreAttributes version since a readonly property may be |
5102 // overridden and SetProperty does not allow this. | 4838 // overridden and SetProperty does not allow this. |
5103 Handle<Object> result; | 4839 Handle<Object> result; |
5104 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 4840 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
5105 isolate, result, | 4841 isolate, result, |
5106 JSObject::SetOwnPropertyIgnoreAttributes( | 4842 JSObject::SetOwnPropertyIgnoreAttributes( |
5107 js_object, name, obj_value, attr, | 4843 js_object, name, obj_value, attr, JSObject::DONT_FORCE_FIELD)); |
5108 JSObject::DONT_FORCE_FIELD)); | |
5109 return *result; | 4844 return *result; |
5110 } | 4845 } |
5111 | 4846 |
5112 Handle<Object> result; | 4847 Handle<Object> result; |
5113 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 4848 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
5114 isolate, result, | 4849 isolate, result, |
5115 Runtime::DefineObjectProperty(js_object, name, obj_value, attr)); | 4850 Runtime::DefineObjectProperty(js_object, name, obj_value, attr)); |
5116 return *result; | 4851 return *result; |
5117 } | 4852 } |
5118 | 4853 |
5119 | 4854 |
5120 // Return property without being observable by accessors or interceptors. | 4855 // Return property without being observable by accessors or interceptors. |
5121 RUNTIME_FUNCTION(Runtime_GetDataProperty) { | 4856 RUNTIME_FUNCTION(Runtime_GetDataProperty) { |
5122 HandleScope scope(isolate); | 4857 HandleScope scope(isolate); |
5123 DCHECK(args.length() == 2); | 4858 DCHECK(args.length() == 2); |
5124 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); | 4859 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); |
5125 CONVERT_ARG_HANDLE_CHECKED(Name, key, 1); | 4860 CONVERT_ARG_HANDLE_CHECKED(Name, key, 1); |
5126 return *JSObject::GetDataProperty(object, key); | 4861 return *JSObject::GetDataProperty(object, key); |
5127 } | 4862 } |
5128 | 4863 |
5129 | 4864 |
5130 MaybeHandle<Object> Runtime::SetObjectProperty(Isolate* isolate, | 4865 MaybeHandle<Object> Runtime::SetObjectProperty(Isolate* isolate, |
5131 Handle<Object> object, | 4866 Handle<Object> object, |
5132 Handle<Object> key, | 4867 Handle<Object> key, |
5133 Handle<Object> value, | 4868 Handle<Object> value, |
5134 StrictMode strict_mode) { | 4869 StrictMode strict_mode) { |
5135 if (object->IsUndefined() || object->IsNull()) { | 4870 if (object->IsUndefined() || object->IsNull()) { |
5136 Handle<Object> args[2] = { key, object }; | 4871 Handle<Object> args[2] = {key, object}; |
5137 THROW_NEW_ERROR(isolate, NewTypeError("non_object_property_store", | 4872 THROW_NEW_ERROR(isolate, NewTypeError("non_object_property_store", |
5138 HandleVector(args, 2)), | 4873 HandleVector(args, 2)), |
5139 Object); | 4874 Object); |
5140 } | 4875 } |
5141 | 4876 |
5142 if (object->IsJSProxy()) { | 4877 if (object->IsJSProxy()) { |
5143 Handle<Object> name_object; | 4878 Handle<Object> name_object; |
5144 if (key->IsSymbol()) { | 4879 if (key->IsSymbol()) { |
5145 name_object = key; | 4880 name_object = key; |
5146 } else { | 4881 } else { |
5147 ASSIGN_RETURN_ON_EXCEPTION( | 4882 ASSIGN_RETURN_ON_EXCEPTION(isolate, name_object, |
5148 isolate, name_object, Execution::ToString(isolate, key), Object); | 4883 Execution::ToString(isolate, key), Object); |
5149 } | 4884 } |
5150 Handle<Name> name = Handle<Name>::cast(name_object); | 4885 Handle<Name> name = Handle<Name>::cast(name_object); |
5151 return Object::SetProperty(Handle<JSProxy>::cast(object), name, value, | 4886 return Object::SetProperty(Handle<JSProxy>::cast(object), name, value, |
5152 strict_mode); | 4887 strict_mode); |
5153 } | 4888 } |
5154 | 4889 |
5155 // Check if the given key is an array index. | 4890 // Check if the given key is an array index. |
5156 uint32_t index; | 4891 uint32_t index; |
5157 if (key->ToArrayIndex(&index)) { | 4892 if (key->ToArrayIndex(&index)) { |
5158 // TODO(verwaest): Support non-JSObject receivers. | 4893 // TODO(verwaest): Support non-JSObject receivers. |
5159 if (!object->IsJSObject()) return value; | 4894 if (!object->IsJSObject()) return value; |
5160 Handle<JSObject> js_object = Handle<JSObject>::cast(object); | 4895 Handle<JSObject> js_object = Handle<JSObject>::cast(object); |
5161 | 4896 |
5162 // In Firefox/SpiderMonkey, Safari and Opera you can access the characters | 4897 // In Firefox/SpiderMonkey, Safari and Opera you can access the characters |
5163 // of a string using [] notation. We need to support this too in | 4898 // of a string using [] notation. We need to support this too in |
5164 // JavaScript. | 4899 // JavaScript. |
5165 // In the case of a String object we just need to redirect the assignment to | 4900 // In the case of a String object we just need to redirect the assignment to |
5166 // the underlying string if the index is in range. Since the underlying | 4901 // the underlying string if the index is in range. Since the underlying |
5167 // string does nothing with the assignment then we can ignore such | 4902 // string does nothing with the assignment then we can ignore such |
5168 // assignments. | 4903 // assignments. |
5169 if (js_object->IsStringObjectWithCharacterAt(index)) { | 4904 if (js_object->IsStringObjectWithCharacterAt(index)) { |
5170 return value; | 4905 return value; |
5171 } | 4906 } |
5172 | 4907 |
5173 JSObject::ValidateElements(js_object); | 4908 JSObject::ValidateElements(js_object); |
5174 if (js_object->HasExternalArrayElements() || | 4909 if (js_object->HasExternalArrayElements() || |
5175 js_object->HasFixedTypedArrayElements()) { | 4910 js_object->HasFixedTypedArrayElements()) { |
5176 if (!value->IsNumber() && !value->IsUndefined()) { | 4911 if (!value->IsNumber() && !value->IsUndefined()) { |
5177 ASSIGN_RETURN_ON_EXCEPTION( | 4912 ASSIGN_RETURN_ON_EXCEPTION(isolate, value, |
5178 isolate, value, Execution::ToNumber(isolate, value), Object); | 4913 Execution::ToNumber(isolate, value), Object); |
5179 } | 4914 } |
5180 } | 4915 } |
5181 | 4916 |
5182 MaybeHandle<Object> result = JSObject::SetElement( | 4917 MaybeHandle<Object> result = JSObject::SetElement( |
5183 js_object, index, value, NONE, strict_mode, true, SET_PROPERTY); | 4918 js_object, index, value, NONE, strict_mode, true, SET_PROPERTY); |
5184 JSObject::ValidateElements(js_object); | 4919 JSObject::ValidateElements(js_object); |
5185 | 4920 |
5186 return result.is_null() ? result : value; | 4921 return result.is_null() ? result : value; |
5187 } | 4922 } |
5188 | 4923 |
(...skipping 12 matching lines...) Expand all Loading... |
5201 return JSObject::SetElement(js_object, index, value, NONE, strict_mode, | 4936 return JSObject::SetElement(js_object, index, value, NONE, strict_mode, |
5202 true, SET_PROPERTY); | 4937 true, SET_PROPERTY); |
5203 } else { | 4938 } else { |
5204 if (name->IsString()) name = String::Flatten(Handle<String>::cast(name)); | 4939 if (name->IsString()) name = String::Flatten(Handle<String>::cast(name)); |
5205 return Object::SetProperty(object, name, value, strict_mode); | 4940 return Object::SetProperty(object, name, value, strict_mode); |
5206 } | 4941 } |
5207 } | 4942 } |
5208 | 4943 |
5209 // Call-back into JavaScript to convert the key to a string. | 4944 // Call-back into JavaScript to convert the key to a string. |
5210 Handle<Object> converted; | 4945 Handle<Object> converted; |
5211 ASSIGN_RETURN_ON_EXCEPTION( | 4946 ASSIGN_RETURN_ON_EXCEPTION(isolate, converted, |
5212 isolate, converted, Execution::ToString(isolate, key), Object); | 4947 Execution::ToString(isolate, key), Object); |
5213 Handle<String> name = Handle<String>::cast(converted); | 4948 Handle<String> name = Handle<String>::cast(converted); |
5214 | 4949 |
5215 if (name->AsArrayIndex(&index)) { | 4950 if (name->AsArrayIndex(&index)) { |
5216 // TODO(verwaest): Support non-JSObject receivers. | 4951 // TODO(verwaest): Support non-JSObject receivers. |
5217 if (!object->IsJSObject()) return value; | 4952 if (!object->IsJSObject()) return value; |
5218 Handle<JSObject> js_object = Handle<JSObject>::cast(object); | 4953 Handle<JSObject> js_object = Handle<JSObject>::cast(object); |
5219 return JSObject::SetElement(js_object, index, value, NONE, strict_mode, | 4954 return JSObject::SetElement(js_object, index, value, NONE, strict_mode, |
5220 true, SET_PROPERTY); | 4955 true, SET_PROPERTY); |
5221 } | 4956 } |
5222 return Object::SetProperty(object, name, value, strict_mode); | 4957 return Object::SetProperty(object, name, value, strict_mode); |
(...skipping 12 matching lines...) Expand all Loading... |
5235 // of a string using [] notation. We need to support this too in | 4970 // of a string using [] notation. We need to support this too in |
5236 // JavaScript. | 4971 // JavaScript. |
5237 // In the case of a String object we just need to redirect the assignment to | 4972 // In the case of a String object we just need to redirect the assignment to |
5238 // the underlying string if the index is in range. Since the underlying | 4973 // the underlying string if the index is in range. Since the underlying |
5239 // string does nothing with the assignment then we can ignore such | 4974 // string does nothing with the assignment then we can ignore such |
5240 // assignments. | 4975 // assignments. |
5241 if (js_object->IsStringObjectWithCharacterAt(index)) { | 4976 if (js_object->IsStringObjectWithCharacterAt(index)) { |
5242 return value; | 4977 return value; |
5243 } | 4978 } |
5244 | 4979 |
5245 return JSObject::SetElement(js_object, index, value, attr, | 4980 return JSObject::SetElement(js_object, index, value, attr, SLOPPY, false, |
5246 SLOPPY, false, DEFINE_PROPERTY); | 4981 DEFINE_PROPERTY); |
5247 } | 4982 } |
5248 | 4983 |
5249 if (key->IsName()) { | 4984 if (key->IsName()) { |
5250 Handle<Name> name = Handle<Name>::cast(key); | 4985 Handle<Name> name = Handle<Name>::cast(key); |
5251 if (name->AsArrayIndex(&index)) { | 4986 if (name->AsArrayIndex(&index)) { |
5252 return JSObject::SetElement(js_object, index, value, attr, | 4987 return JSObject::SetElement(js_object, index, value, attr, SLOPPY, false, |
5253 SLOPPY, false, DEFINE_PROPERTY); | 4988 DEFINE_PROPERTY); |
5254 } else { | 4989 } else { |
5255 if (name->IsString()) name = String::Flatten(Handle<String>::cast(name)); | 4990 if (name->IsString()) name = String::Flatten(Handle<String>::cast(name)); |
5256 return JSObject::SetOwnPropertyIgnoreAttributes(js_object, name, value, | 4991 return JSObject::SetOwnPropertyIgnoreAttributes(js_object, name, value, |
5257 attr); | 4992 attr); |
5258 } | 4993 } |
5259 } | 4994 } |
5260 | 4995 |
5261 // Call-back into JavaScript to convert the key to a string. | 4996 // Call-back into JavaScript to convert the key to a string. |
5262 Handle<Object> converted; | 4997 Handle<Object> converted; |
5263 ASSIGN_RETURN_ON_EXCEPTION( | 4998 ASSIGN_RETURN_ON_EXCEPTION(isolate, converted, |
5264 isolate, converted, Execution::ToString(isolate, key), Object); | 4999 Execution::ToString(isolate, key), Object); |
5265 Handle<String> name = Handle<String>::cast(converted); | 5000 Handle<String> name = Handle<String>::cast(converted); |
5266 | 5001 |
5267 if (name->AsArrayIndex(&index)) { | 5002 if (name->AsArrayIndex(&index)) { |
5268 return JSObject::SetElement(js_object, index, value, attr, | 5003 return JSObject::SetElement(js_object, index, value, attr, SLOPPY, false, |
5269 SLOPPY, false, DEFINE_PROPERTY); | 5004 DEFINE_PROPERTY); |
5270 } else { | 5005 } else { |
5271 return JSObject::SetOwnPropertyIgnoreAttributes(js_object, name, value, | 5006 return JSObject::SetOwnPropertyIgnoreAttributes(js_object, name, value, |
5272 attr); | 5007 attr); |
5273 } | 5008 } |
5274 } | 5009 } |
5275 | 5010 |
5276 | 5011 |
5277 MaybeHandle<Object> Runtime::DeleteObjectProperty(Isolate* isolate, | 5012 MaybeHandle<Object> Runtime::DeleteObjectProperty(Isolate* isolate, |
5278 Handle<JSReceiver> receiver, | 5013 Handle<JSReceiver> receiver, |
5279 Handle<Object> key, | 5014 Handle<Object> key, |
(...skipping 13 matching lines...) Expand all Loading... |
5293 | 5028 |
5294 return JSReceiver::DeleteElement(receiver, index, mode); | 5029 return JSReceiver::DeleteElement(receiver, index, mode); |
5295 } | 5030 } |
5296 | 5031 |
5297 Handle<Name> name; | 5032 Handle<Name> name; |
5298 if (key->IsName()) { | 5033 if (key->IsName()) { |
5299 name = Handle<Name>::cast(key); | 5034 name = Handle<Name>::cast(key); |
5300 } else { | 5035 } else { |
5301 // Call-back into JavaScript to convert the key to a string. | 5036 // Call-back into JavaScript to convert the key to a string. |
5302 Handle<Object> converted; | 5037 Handle<Object> converted; |
5303 ASSIGN_RETURN_ON_EXCEPTION( | 5038 ASSIGN_RETURN_ON_EXCEPTION(isolate, converted, |
5304 isolate, converted, Execution::ToString(isolate, key), Object); | 5039 Execution::ToString(isolate, key), Object); |
5305 name = Handle<String>::cast(converted); | 5040 name = Handle<String>::cast(converted); |
5306 } | 5041 } |
5307 | 5042 |
5308 if (name->IsString()) name = String::Flatten(Handle<String>::cast(name)); | 5043 if (name->IsString()) name = String::Flatten(Handle<String>::cast(name)); |
5309 return JSReceiver::DeleteProperty(receiver, name, mode); | 5044 return JSReceiver::DeleteProperty(receiver, name, mode); |
5310 } | 5045 } |
5311 | 5046 |
5312 | 5047 |
5313 RUNTIME_FUNCTION(Runtime_SetHiddenProperty) { | 5048 RUNTIME_FUNCTION(Runtime_SetHiddenProperty) { |
5314 HandleScope scope(isolate); | 5049 HandleScope scope(isolate); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5376 DCHECK(maybe.has_value); | 5111 DCHECK(maybe.has_value); |
5377 duplicate = it.IsFound(); | 5112 duplicate = it.IsFound(); |
5378 } else { | 5113 } else { |
5379 uint32_t index = 0; | 5114 uint32_t index = 0; |
5380 RUNTIME_ASSERT(key->ToArrayIndex(&index)); | 5115 RUNTIME_ASSERT(key->ToArrayIndex(&index)); |
5381 Maybe<bool> maybe = JSReceiver::HasOwnElement(object, index); | 5116 Maybe<bool> maybe = JSReceiver::HasOwnElement(object, index); |
5382 if (!maybe.has_value) return isolate->heap()->exception(); | 5117 if (!maybe.has_value) return isolate->heap()->exception(); |
5383 duplicate = maybe.value; | 5118 duplicate = maybe.value; |
5384 } | 5119 } |
5385 if (duplicate) { | 5120 if (duplicate) { |
5386 Handle<Object> args[1] = { key }; | 5121 Handle<Object> args[1] = {key}; |
5387 THROW_NEW_ERROR_RETURN_FAILURE( | 5122 THROW_NEW_ERROR_RETURN_FAILURE( |
5388 isolate, | 5123 isolate, |
5389 NewTypeError("duplicate_template_property", HandleVector(args, 1))); | 5124 NewTypeError("duplicate_template_property", HandleVector(args, 1))); |
5390 } | 5125 } |
5391 #endif | 5126 #endif |
5392 | 5127 |
5393 Handle<Object> result; | 5128 Handle<Object> result; |
5394 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 5129 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
5395 isolate, result, | 5130 isolate, result, |
5396 Runtime::DefineObjectProperty(object, key, value, attributes)); | 5131 Runtime::DefineObjectProperty(object, key, value, attributes)); |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5502 } | 5237 } |
5503 Handle<JSArray> boilerplate_object(boilerplate); | 5238 Handle<JSArray> boilerplate_object(boilerplate); |
5504 ElementsKind elements_kind = object->GetElementsKind(); | 5239 ElementsKind elements_kind = object->GetElementsKind(); |
5505 DCHECK(IsFastElementsKind(elements_kind)); | 5240 DCHECK(IsFastElementsKind(elements_kind)); |
5506 // Smis should never trigger transitions. | 5241 // Smis should never trigger transitions. |
5507 DCHECK(!value->IsSmi()); | 5242 DCHECK(!value->IsSmi()); |
5508 | 5243 |
5509 if (value->IsNumber()) { | 5244 if (value->IsNumber()) { |
5510 DCHECK(IsFastSmiElementsKind(elements_kind)); | 5245 DCHECK(IsFastSmiElementsKind(elements_kind)); |
5511 ElementsKind transitioned_kind = IsFastHoleyElementsKind(elements_kind) | 5246 ElementsKind transitioned_kind = IsFastHoleyElementsKind(elements_kind) |
5512 ? FAST_HOLEY_DOUBLE_ELEMENTS | 5247 ? FAST_HOLEY_DOUBLE_ELEMENTS |
5513 : FAST_DOUBLE_ELEMENTS; | 5248 : FAST_DOUBLE_ELEMENTS; |
5514 if (IsMoreGeneralElementsKindTransition( | 5249 if (IsMoreGeneralElementsKindTransition( |
5515 boilerplate_object->GetElementsKind(), | 5250 boilerplate_object->GetElementsKind(), transitioned_kind)) { |
5516 transitioned_kind)) { | |
5517 JSObject::TransitionElementsKind(boilerplate_object, transitioned_kind); | 5251 JSObject::TransitionElementsKind(boilerplate_object, transitioned_kind); |
5518 } | 5252 } |
5519 JSObject::TransitionElementsKind(object, transitioned_kind); | 5253 JSObject::TransitionElementsKind(object, transitioned_kind); |
5520 DCHECK(IsFastDoubleElementsKind(object->GetElementsKind())); | 5254 DCHECK(IsFastDoubleElementsKind(object->GetElementsKind())); |
5521 FixedDoubleArray* double_array = FixedDoubleArray::cast(object->elements()); | 5255 FixedDoubleArray* double_array = FixedDoubleArray::cast(object->elements()); |
5522 HeapNumber* number = HeapNumber::cast(*value); | 5256 HeapNumber* number = HeapNumber::cast(*value); |
5523 double_array->set(store_index, number->Number()); | 5257 double_array->set(store_index, number->Number()); |
5524 } else { | 5258 } else { |
5525 if (!IsFastObjectElementsKind(elements_kind)) { | 5259 if (!IsFastObjectElementsKind(elements_kind)) { |
5526 ElementsKind transitioned_kind = IsFastHoleyElementsKind(elements_kind) | 5260 ElementsKind transitioned_kind = IsFastHoleyElementsKind(elements_kind) |
5527 ? FAST_HOLEY_ELEMENTS | 5261 ? FAST_HOLEY_ELEMENTS |
5528 : FAST_ELEMENTS; | 5262 : FAST_ELEMENTS; |
5529 JSObject::TransitionElementsKind(object, transitioned_kind); | 5263 JSObject::TransitionElementsKind(object, transitioned_kind); |
5530 ElementsKind boilerplate_elements_kind = | 5264 ElementsKind boilerplate_elements_kind = |
5531 boilerplate_object->GetElementsKind(); | 5265 boilerplate_object->GetElementsKind(); |
5532 if (IsMoreGeneralElementsKindTransition(boilerplate_elements_kind, | 5266 if (IsMoreGeneralElementsKindTransition(boilerplate_elements_kind, |
5533 transitioned_kind)) { | 5267 transitioned_kind)) { |
5534 JSObject::TransitionElementsKind(boilerplate_object, transitioned_kind); | 5268 JSObject::TransitionElementsKind(boilerplate_object, transitioned_kind); |
5535 } | 5269 } |
5536 } | 5270 } |
5537 FixedArray* object_array = FixedArray::cast(object->elements()); | 5271 FixedArray* object_array = FixedArray::cast(object->elements()); |
5538 object_array->set(store_index, *value); | 5272 object_array->set(store_index, *value); |
5539 } | 5273 } |
5540 return *object; | 5274 return *object; |
5541 } | 5275 } |
5542 | 5276 |
5543 | 5277 |
5544 // Check whether debugger and is about to step into the callback that is passed | 5278 // Check whether debugger and is about to step into the callback that is passed |
5545 // to a built-in function such as Array.forEach. | 5279 // to a built-in function such as Array.forEach. |
5546 RUNTIME_FUNCTION(Runtime_DebugCallbackSupportsStepping) { | 5280 RUNTIME_FUNCTION(Runtime_DebugCallbackSupportsStepping) { |
5547 DCHECK(args.length() == 1); | 5281 DCHECK(args.length() == 1); |
5548 if (!isolate->debug()->is_active() || !isolate->debug()->StepInActive()) { | 5282 if (!isolate->debug()->is_active() || !isolate->debug()->StepInActive()) { |
5549 return isolate->heap()->false_value(); | 5283 return isolate->heap()->false_value(); |
5550 } | 5284 } |
5551 CONVERT_ARG_CHECKED(Object, callback, 0); | 5285 CONVERT_ARG_CHECKED(Object, callback, 0); |
5552 // We do not step into the callback if it's a builtin or not even a function. | 5286 // We do not step into the callback if it's a builtin or not even a function. |
5553 return isolate->heap()->ToBoolean( | 5287 return isolate->heap()->ToBoolean(callback->IsJSFunction() && |
5554 callback->IsJSFunction() && !JSFunction::cast(callback)->IsBuiltin()); | 5288 !JSFunction::cast(callback)->IsBuiltin()); |
5555 } | 5289 } |
5556 | 5290 |
5557 | 5291 |
5558 // Set one shot breakpoints for the callback function that is passed to a | 5292 // Set one shot breakpoints for the callback function that is passed to a |
5559 // built-in function such as Array.forEach to enable stepping into the callback. | 5293 // built-in function such as Array.forEach to enable stepping into the callback. |
5560 RUNTIME_FUNCTION(Runtime_DebugPrepareStepInIfStepping) { | 5294 RUNTIME_FUNCTION(Runtime_DebugPrepareStepInIfStepping) { |
5561 DCHECK(args.length() == 1); | 5295 DCHECK(args.length() == 1); |
5562 Debug* debug = isolate->debug(); | 5296 Debug* debug = isolate->debug(); |
5563 if (!debug->IsStepping()) return isolate->heap()->undefined_value(); | 5297 if (!debug->IsStepping()) return isolate->heap()->undefined_value(); |
5564 | 5298 |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5626 } | 5360 } |
5627 | 5361 |
5628 | 5362 |
5629 RUNTIME_FUNCTION(Runtime_DeleteProperty) { | 5363 RUNTIME_FUNCTION(Runtime_DeleteProperty) { |
5630 HandleScope scope(isolate); | 5364 HandleScope scope(isolate); |
5631 DCHECK(args.length() == 3); | 5365 DCHECK(args.length() == 3); |
5632 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0); | 5366 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0); |
5633 CONVERT_ARG_HANDLE_CHECKED(Name, key, 1); | 5367 CONVERT_ARG_HANDLE_CHECKED(Name, key, 1); |
5634 CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 2); | 5368 CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 2); |
5635 JSReceiver::DeleteMode delete_mode = strict_mode == STRICT | 5369 JSReceiver::DeleteMode delete_mode = strict_mode == STRICT |
5636 ? JSReceiver::STRICT_DELETION : JSReceiver::NORMAL_DELETION; | 5370 ? JSReceiver::STRICT_DELETION |
| 5371 : JSReceiver::NORMAL_DELETION; |
5637 Handle<Object> result; | 5372 Handle<Object> result; |
5638 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 5373 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
5639 isolate, result, | 5374 isolate, result, JSReceiver::DeleteProperty(object, key, delete_mode)); |
5640 JSReceiver::DeleteProperty(object, key, delete_mode)); | |
5641 return *result; | 5375 return *result; |
5642 } | 5376 } |
5643 | 5377 |
5644 | 5378 |
5645 static Object* HasOwnPropertyImplementation(Isolate* isolate, | 5379 static Object* HasOwnPropertyImplementation(Isolate* isolate, |
5646 Handle<JSObject> object, | 5380 Handle<JSObject> object, |
5647 Handle<Name> key) { | 5381 Handle<Name> key) { |
5648 Maybe<bool> maybe = JSReceiver::HasOwnProperty(object, key); | 5382 Maybe<bool> maybe = JSReceiver::HasOwnProperty(object, key); |
5649 if (!maybe.has_value) return isolate->heap()->exception(); | 5383 if (!maybe.has_value) return isolate->heap()->exception(); |
5650 if (maybe.value) return isolate->heap()->true_value(); | 5384 if (maybe.value) return isolate->heap()->true_value(); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5682 // Fast case: either the key is a real named property or it is not | 5416 // Fast case: either the key is a real named property or it is not |
5683 // an array index and there are no interceptors or hidden | 5417 // an array index and there are no interceptors or hidden |
5684 // prototypes. | 5418 // prototypes. |
5685 Maybe<bool> maybe = JSObject::HasRealNamedProperty(js_obj, key); | 5419 Maybe<bool> maybe = JSObject::HasRealNamedProperty(js_obj, key); |
5686 if (!maybe.has_value) return isolate->heap()->exception(); | 5420 if (!maybe.has_value) return isolate->heap()->exception(); |
5687 DCHECK(!isolate->has_pending_exception()); | 5421 DCHECK(!isolate->has_pending_exception()); |
5688 if (maybe.value) { | 5422 if (maybe.value) { |
5689 return isolate->heap()->true_value(); | 5423 return isolate->heap()->true_value(); |
5690 } | 5424 } |
5691 Map* map = js_obj->map(); | 5425 Map* map = js_obj->map(); |
5692 if (!key_is_array_index && | 5426 if (!key_is_array_index && !map->has_named_interceptor() && |
5693 !map->has_named_interceptor() && | |
5694 !HeapObject::cast(map->prototype())->map()->is_hidden_prototype()) { | 5427 !HeapObject::cast(map->prototype())->map()->is_hidden_prototype()) { |
5695 return isolate->heap()->false_value(); | 5428 return isolate->heap()->false_value(); |
5696 } | 5429 } |
5697 // Slow case. | 5430 // Slow case. |
5698 return HasOwnPropertyImplementation(isolate, | 5431 return HasOwnPropertyImplementation(isolate, Handle<JSObject>(js_obj), |
5699 Handle<JSObject>(js_obj), | |
5700 Handle<Name>(key)); | 5432 Handle<Name>(key)); |
5701 } else if (object->IsString() && key_is_array_index) { | 5433 } else if (object->IsString() && key_is_array_index) { |
5702 // Well, there is one exception: Handle [] on strings. | 5434 // Well, there is one exception: Handle [] on strings. |
5703 Handle<String> string = Handle<String>::cast(object); | 5435 Handle<String> string = Handle<String>::cast(object); |
5704 if (index < static_cast<uint32_t>(string->length())) { | 5436 if (index < static_cast<uint32_t>(string->length())) { |
5705 return isolate->heap()->true_value(); | 5437 return isolate->heap()->true_value(); |
5706 } | 5438 } |
5707 } | 5439 } |
5708 return isolate->heap()->false_value(); | 5440 return isolate->heap()->false_value(); |
5709 } | 5441 } |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5814 } | 5546 } |
5815 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); | 5547 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); |
5816 CONVERT_SMI_ARG_CHECKED(filter_value, 1); | 5548 CONVERT_SMI_ARG_CHECKED(filter_value, 1); |
5817 PropertyAttributes filter = static_cast<PropertyAttributes>(filter_value); | 5549 PropertyAttributes filter = static_cast<PropertyAttributes>(filter_value); |
5818 | 5550 |
5819 // Skip the global proxy as it has no properties and always delegates to the | 5551 // Skip the global proxy as it has no properties and always delegates to the |
5820 // real global object. | 5552 // real global object. |
5821 if (obj->IsJSGlobalProxy()) { | 5553 if (obj->IsJSGlobalProxy()) { |
5822 // Only collect names if access is permitted. | 5554 // Only collect names if access is permitted. |
5823 if (obj->IsAccessCheckNeeded() && | 5555 if (obj->IsAccessCheckNeeded() && |
5824 !isolate->MayNamedAccess( | 5556 !isolate->MayNamedAccess(obj, isolate->factory()->undefined_value(), |
5825 obj, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) { | 5557 v8::ACCESS_KEYS)) { |
5826 isolate->ReportFailedAccessCheck(obj, v8::ACCESS_KEYS); | 5558 isolate->ReportFailedAccessCheck(obj, v8::ACCESS_KEYS); |
5827 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); | 5559 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); |
5828 return *isolate->factory()->NewJSArray(0); | 5560 return *isolate->factory()->NewJSArray(0); |
5829 } | 5561 } |
5830 PrototypeIterator iter(isolate, obj); | 5562 PrototypeIterator iter(isolate, obj); |
5831 obj = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); | 5563 obj = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); |
5832 } | 5564 } |
5833 | 5565 |
5834 // Find the number of objects making up this. | 5566 // Find the number of objects making up this. |
5835 int length = OwnPrototypeChainLength(*obj); | 5567 int length = OwnPrototypeChainLength(*obj); |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5900 hidden_strings++; | 5632 hidden_strings++; |
5901 } | 5633 } |
5902 iter.Advance(); | 5634 iter.Advance(); |
5903 } | 5635 } |
5904 } | 5636 } |
5905 | 5637 |
5906 // Filter out name of hidden properties object and | 5638 // Filter out name of hidden properties object and |
5907 // hidden prototype duplicates. | 5639 // hidden prototype duplicates. |
5908 if (hidden_strings > 0) { | 5640 if (hidden_strings > 0) { |
5909 Handle<FixedArray> old_names = names; | 5641 Handle<FixedArray> old_names = names; |
5910 names = isolate->factory()->NewFixedArray( | 5642 names = isolate->factory()->NewFixedArray(names->length() - hidden_strings); |
5911 names->length() - hidden_strings); | |
5912 int dest_pos = 0; | 5643 int dest_pos = 0; |
5913 for (int i = 0; i < total_property_count; i++) { | 5644 for (int i = 0; i < total_property_count; i++) { |
5914 Object* name = old_names->get(i); | 5645 Object* name = old_names->get(i); |
5915 if (name == isolate->heap()->hidden_string()) { | 5646 if (name == isolate->heap()->hidden_string()) { |
5916 hidden_strings--; | 5647 hidden_strings--; |
5917 continue; | 5648 continue; |
5918 } | 5649 } |
5919 names->set(dest_pos++, name); | 5650 names->set(dest_pos++, name); |
5920 } | 5651 } |
5921 DCHECK_EQ(0, hidden_strings); | 5652 DCHECK_EQ(0, hidden_strings); |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5996 | 5727 |
5997 RUNTIME_FUNCTION(Runtime_OwnKeys) { | 5728 RUNTIME_FUNCTION(Runtime_OwnKeys) { |
5998 HandleScope scope(isolate); | 5729 HandleScope scope(isolate); |
5999 DCHECK(args.length() == 1); | 5730 DCHECK(args.length() == 1); |
6000 CONVERT_ARG_CHECKED(JSObject, raw_object, 0); | 5731 CONVERT_ARG_CHECKED(JSObject, raw_object, 0); |
6001 Handle<JSObject> object(raw_object); | 5732 Handle<JSObject> object(raw_object); |
6002 | 5733 |
6003 if (object->IsJSGlobalProxy()) { | 5734 if (object->IsJSGlobalProxy()) { |
6004 // Do access checks before going to the global object. | 5735 // Do access checks before going to the global object. |
6005 if (object->IsAccessCheckNeeded() && | 5736 if (object->IsAccessCheckNeeded() && |
6006 !isolate->MayNamedAccess( | 5737 !isolate->MayNamedAccess(object, isolate->factory()->undefined_value(), |
6007 object, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) { | 5738 v8::ACCESS_KEYS)) { |
6008 isolate->ReportFailedAccessCheck(object, v8::ACCESS_KEYS); | 5739 isolate->ReportFailedAccessCheck(object, v8::ACCESS_KEYS); |
6009 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); | 5740 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); |
6010 return *isolate->factory()->NewJSArray(0); | 5741 return *isolate->factory()->NewJSArray(0); |
6011 } | 5742 } |
6012 | 5743 |
6013 PrototypeIterator iter(isolate, object); | 5744 PrototypeIterator iter(isolate, object); |
6014 // If proxy is detached we simply return an empty array. | 5745 // If proxy is detached we simply return an empty array. |
6015 if (iter.IsAtEnd()) return *isolate->factory()->NewJSArray(0); | 5746 if (iter.IsAtEnd()) return *isolate->factory()->NewJSArray(0); |
6016 object = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); | 5747 object = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); |
6017 } | 5748 } |
6018 | 5749 |
6019 Handle<FixedArray> contents; | 5750 Handle<FixedArray> contents; |
6020 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 5751 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
6021 isolate, contents, | 5752 isolate, contents, JSReceiver::GetKeys(object, JSReceiver::OWN_ONLY)); |
6022 JSReceiver::GetKeys(object, JSReceiver::OWN_ONLY)); | |
6023 | 5753 |
6024 // Some fast paths through GetKeysInFixedArrayFor reuse a cached | 5754 // Some fast paths through GetKeysInFixedArrayFor reuse a cached |
6025 // property array and since the result is mutable we have to create | 5755 // property array and since the result is mutable we have to create |
6026 // a fresh clone on each invocation. | 5756 // a fresh clone on each invocation. |
6027 int length = contents->length(); | 5757 int length = contents->length(); |
6028 Handle<FixedArray> copy = isolate->factory()->NewFixedArray(length); | 5758 Handle<FixedArray> copy = isolate->factory()->NewFixedArray(length); |
6029 for (int i = 0; i < length; i++) { | 5759 for (int i = 0; i < length; i++) { |
6030 Object* entry = contents->get(i); | 5760 Object* entry = contents->get(i); |
6031 if (entry->IsString()) { | 5761 if (entry->IsString()) { |
6032 copy->set(i, entry); | 5762 copy->set(i, entry); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6073 Handle<Object> result; | 5803 Handle<Object> result; |
6074 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 5804 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
6075 isolate, result, | 5805 isolate, result, |
6076 Object::GetProperty(isolate->initial_object_prototype(), | 5806 Object::GetProperty(isolate->initial_object_prototype(), |
6077 Handle<Symbol>::cast(raw_key))); | 5807 Handle<Symbol>::cast(raw_key))); |
6078 return *result; | 5808 return *result; |
6079 } | 5809 } |
6080 | 5810 |
6081 // Convert the key to a string. | 5811 // Convert the key to a string. |
6082 Handle<Object> converted; | 5812 Handle<Object> converted; |
6083 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 5813 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, converted, |
6084 isolate, converted, Execution::ToString(isolate, raw_key)); | 5814 Execution::ToString(isolate, raw_key)); |
6085 Handle<String> key = Handle<String>::cast(converted); | 5815 Handle<String> key = Handle<String>::cast(converted); |
6086 | 5816 |
6087 // Try to convert the string key into an array index. | 5817 // Try to convert the string key into an array index. |
6088 if (key->AsArrayIndex(&index)) { | 5818 if (key->AsArrayIndex(&index)) { |
6089 if (index < n) { | 5819 if (index < n) { |
6090 return frame->GetParameter(index); | 5820 return frame->GetParameter(index); |
6091 } else { | 5821 } else { |
6092 Handle<Object> initial_prototype(isolate->initial_object_prototype()); | 5822 Handle<Object> initial_prototype(isolate->initial_object_prototype()); |
6093 Handle<Object> result; | 5823 Handle<Object> result; |
6094 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 5824 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6205 return isolate->heap()->ToBoolean(value <= 0); | 5935 return isolate->heap()->ToBoolean(value <= 0); |
6206 case Token::GTE: | 5936 case Token::GTE: |
6207 return isolate->heap()->ToBoolean(value >= 0); | 5937 return isolate->heap()->ToBoolean(value >= 0); |
6208 default: | 5938 default: |
6209 // This should only happen during natives fuzzing. | 5939 // This should only happen during natives fuzzing. |
6210 return isolate->heap()->undefined_value(); | 5940 return isolate->heap()->undefined_value(); |
6211 } | 5941 } |
6212 } | 5942 } |
6213 | 5943 |
6214 | 5944 |
6215 static bool AreDigits(const uint8_t*s, int from, int to) { | 5945 static bool AreDigits(const uint8_t* s, int from, int to) { |
6216 for (int i = from; i < to; i++) { | 5946 for (int i = from; i < to; i++) { |
6217 if (s[i] < '0' || s[i] > '9') return false; | 5947 if (s[i] < '0' || s[i] > '9') return false; |
6218 } | 5948 } |
6219 | 5949 |
6220 return true; | 5950 return true; |
6221 } | 5951 } |
6222 | 5952 |
6223 | 5953 |
6224 static int ParseDecimalInteger(const uint8_t*s, int from, int to) { | 5954 static int ParseDecimalInteger(const uint8_t* s, int from, int to) { |
6225 DCHECK(to - from < 10); // Overflow is not possible. | 5955 DCHECK(to - from < 10); // Overflow is not possible. |
6226 DCHECK(from < to); | 5956 DCHECK(from < to); |
6227 int d = s[from] - '0'; | 5957 int d = s[from] - '0'; |
6228 | 5958 |
6229 for (int i = from + 1; i < to; i++) { | 5959 for (int i = from + 1; i < to; i++) { |
6230 d = 10 * d + (s[i] - '0'); | 5960 d = 10 * d + (s[i] - '0'); |
6231 } | 5961 } |
6232 | 5962 |
6233 return d; | 5963 return d; |
6234 } | 5964 } |
(...skipping 25 matching lines...) Expand all Loading... |
6260 if (data[start_pos] != 'I' && data[start_pos] != 0xa0) { | 5990 if (data[start_pos] != 'I' && data[start_pos] != 0xa0) { |
6261 return isolate->heap()->nan_value(); | 5991 return isolate->heap()->nan_value(); |
6262 } | 5992 } |
6263 } else if (len - start_pos < 10 && AreDigits(data, start_pos, len)) { | 5993 } else if (len - start_pos < 10 && AreDigits(data, start_pos, len)) { |
6264 // The maximal/minimal smi has 10 digits. If the string has less digits | 5994 // The maximal/minimal smi has 10 digits. If the string has less digits |
6265 // we know it will fit into the smi-data type. | 5995 // we know it will fit into the smi-data type. |
6266 int d = ParseDecimalInteger(data, start_pos, len); | 5996 int d = ParseDecimalInteger(data, start_pos, len); |
6267 if (minus) { | 5997 if (minus) { |
6268 if (d == 0) return isolate->heap()->minus_zero_value(); | 5998 if (d == 0) return isolate->heap()->minus_zero_value(); |
6269 d = -d; | 5999 d = -d; |
6270 } else if (!subject->HasHashCode() && | 6000 } else if (!subject->HasHashCode() && len <= String::kMaxArrayIndexSize && |
6271 len <= String::kMaxArrayIndexSize && | |
6272 (len == 1 || data[0] != '0')) { | 6001 (len == 1 || data[0] != '0')) { |
6273 // String hash is not calculated yet but all the data are present. | 6002 // String hash is not calculated yet but all the data are present. |
6274 // Update the hash field to speed up sequential convertions. | 6003 // Update the hash field to speed up sequential convertions. |
6275 uint32_t hash = StringHasher::MakeArrayIndexHash(d, len); | 6004 uint32_t hash = StringHasher::MakeArrayIndexHash(d, len); |
6276 #ifdef DEBUG | 6005 #ifdef DEBUG |
6277 subject->Hash(); // Force hash calculation. | 6006 subject->Hash(); // Force hash calculation. |
6278 DCHECK_EQ(static_cast<int>(subject->hash_field()), | 6007 DCHECK_EQ(static_cast<int>(subject->hash_field()), |
6279 static_cast<int>(hash)); | 6008 static_cast<int>(hash)); |
6280 #endif | 6009 #endif |
6281 subject->set_hash_field(hash); | 6010 subject->set_hash_field(hash); |
6282 } | 6011 } |
6283 return Smi::FromInt(d); | 6012 return Smi::FromInt(d); |
6284 } | 6013 } |
6285 } | 6014 } |
6286 | 6015 |
6287 // Slower case. | 6016 // Slower case. |
6288 int flags = ALLOW_HEX; | 6017 int flags = ALLOW_HEX; |
6289 if (FLAG_harmony_numeric_literals) { | 6018 if (FLAG_harmony_numeric_literals) { |
6290 // The current spec draft has not updated "ToNumber Applied to the String | 6019 // The current spec draft has not updated "ToNumber Applied to the String |
6291 // Type", https://bugs.ecmascript.org/show_bug.cgi?id=1584 | 6020 // Type", https://bugs.ecmascript.org/show_bug.cgi?id=1584 |
6292 flags |= ALLOW_OCTAL | ALLOW_BINARY; | 6021 flags |= ALLOW_OCTAL | ALLOW_BINARY; |
6293 } | 6022 } |
6294 | 6023 |
6295 return *isolate->factory()->NewNumber(StringToDouble( | 6024 return *isolate->factory()->NewNumber( |
6296 isolate->unicode_cache(), *subject, flags)); | 6025 StringToDouble(isolate->unicode_cache(), *subject, flags)); |
6297 } | 6026 } |
6298 | 6027 |
6299 | 6028 |
6300 RUNTIME_FUNCTION(Runtime_NewString) { | 6029 RUNTIME_FUNCTION(Runtime_NewString) { |
6301 HandleScope scope(isolate); | 6030 HandleScope scope(isolate); |
6302 DCHECK(args.length() == 2); | 6031 DCHECK(args.length() == 2); |
6303 CONVERT_INT32_ARG_CHECKED(length, 0); | 6032 CONVERT_INT32_ARG_CHECKED(length, 0); |
6304 CONVERT_BOOLEAN_ARG_CHECKED(is_one_byte, 1); | 6033 CONVERT_BOOLEAN_ARG_CHECKED(is_one_byte, 1); |
6305 if (length == 0) return isolate->heap()->empty_string(); | 6034 if (length == 0) return isolate->heap()->empty_string(); |
6306 Handle<String> result; | 6035 Handle<String> result; |
(...skipping 19 matching lines...) Expand all Loading... |
6326 | 6055 |
6327 | 6056 |
6328 RUNTIME_FUNCTION(Runtime_URIEscape) { | 6057 RUNTIME_FUNCTION(Runtime_URIEscape) { |
6329 HandleScope scope(isolate); | 6058 HandleScope scope(isolate); |
6330 DCHECK(args.length() == 1); | 6059 DCHECK(args.length() == 1); |
6331 CONVERT_ARG_HANDLE_CHECKED(String, source, 0); | 6060 CONVERT_ARG_HANDLE_CHECKED(String, source, 0); |
6332 Handle<String> string = String::Flatten(source); | 6061 Handle<String> string = String::Flatten(source); |
6333 DCHECK(string->IsFlat()); | 6062 DCHECK(string->IsFlat()); |
6334 Handle<String> result; | 6063 Handle<String> result; |
6335 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 6064 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
6336 isolate, result, | 6065 isolate, result, string->IsOneByteRepresentationUnderneath() |
6337 string->IsOneByteRepresentationUnderneath() | 6066 ? URIEscape::Escape<uint8_t>(isolate, source) |
6338 ? URIEscape::Escape<uint8_t>(isolate, source) | 6067 : URIEscape::Escape<uc16>(isolate, source)); |
6339 : URIEscape::Escape<uc16>(isolate, source)); | |
6340 return *result; | 6068 return *result; |
6341 } | 6069 } |
6342 | 6070 |
6343 | 6071 |
6344 RUNTIME_FUNCTION(Runtime_URIUnescape) { | 6072 RUNTIME_FUNCTION(Runtime_URIUnescape) { |
6345 HandleScope scope(isolate); | 6073 HandleScope scope(isolate); |
6346 DCHECK(args.length() == 1); | 6074 DCHECK(args.length() == 1); |
6347 CONVERT_ARG_HANDLE_CHECKED(String, source, 0); | 6075 CONVERT_ARG_HANDLE_CHECKED(String, source, 0); |
6348 Handle<String> string = String::Flatten(source); | 6076 Handle<String> string = String::Flatten(source); |
6349 DCHECK(string->IsFlat()); | 6077 DCHECK(string->IsFlat()); |
6350 Handle<String> result; | 6078 Handle<String> result; |
6351 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 6079 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
6352 isolate, result, | 6080 isolate, result, string->IsOneByteRepresentationUnderneath() |
6353 string->IsOneByteRepresentationUnderneath() | 6081 ? URIUnescape::Unescape<uint8_t>(isolate, source) |
6354 ? URIUnescape::Unescape<uint8_t>(isolate, source) | 6082 : URIUnescape::Unescape<uc16>(isolate, source)); |
6355 : URIUnescape::Unescape<uc16>(isolate, source)); | |
6356 return *result; | 6083 return *result; |
6357 } | 6084 } |
6358 | 6085 |
6359 | 6086 |
6360 RUNTIME_FUNCTION(Runtime_QuoteJSONString) { | 6087 RUNTIME_FUNCTION(Runtime_QuoteJSONString) { |
6361 HandleScope scope(isolate); | 6088 HandleScope scope(isolate); |
6362 CONVERT_ARG_HANDLE_CHECKED(String, string, 0); | 6089 CONVERT_ARG_HANDLE_CHECKED(String, string, 0); |
6363 DCHECK(args.length() == 1); | 6090 DCHECK(args.length() == 1); |
6364 Handle<Object> result; | 6091 Handle<Object> result; |
6365 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 6092 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
6366 isolate, result, BasicJsonStringifier::StringifyString(isolate, string)); | 6093 isolate, result, BasicJsonStringifier::StringifyString(isolate, string)); |
6367 return *result; | 6094 return *result; |
6368 } | 6095 } |
6369 | 6096 |
6370 | 6097 |
6371 RUNTIME_FUNCTION(Runtime_BasicJSONStringify) { | 6098 RUNTIME_FUNCTION(Runtime_BasicJSONStringify) { |
6372 HandleScope scope(isolate); | 6099 HandleScope scope(isolate); |
6373 DCHECK(args.length() == 1); | 6100 DCHECK(args.length() == 1); |
6374 CONVERT_ARG_HANDLE_CHECKED(Object, object, 0); | 6101 CONVERT_ARG_HANDLE_CHECKED(Object, object, 0); |
6375 BasicJsonStringifier stringifier(isolate); | 6102 BasicJsonStringifier stringifier(isolate); |
6376 Handle<Object> result; | 6103 Handle<Object> result; |
6377 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 6104 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, |
6378 isolate, result, stringifier.Stringify(object)); | 6105 stringifier.Stringify(object)); |
6379 return *result; | 6106 return *result; |
6380 } | 6107 } |
6381 | 6108 |
6382 | 6109 |
6383 RUNTIME_FUNCTION(Runtime_StringParseInt) { | 6110 RUNTIME_FUNCTION(Runtime_StringParseInt) { |
6384 HandleScope handle_scope(isolate); | 6111 HandleScope handle_scope(isolate); |
6385 DCHECK(args.length() == 2); | 6112 DCHECK(args.length() == 2); |
6386 CONVERT_ARG_HANDLE_CHECKED(String, subject, 0); | 6113 CONVERT_ARG_HANDLE_CHECKED(String, subject, 0); |
6387 CONVERT_NUMBER_CHECKED(int, radix, Int32, args[1]); | 6114 CONVERT_NUMBER_CHECKED(int, radix, Int32, args[1]); |
6388 RUNTIME_ASSERT(radix == 0 || (2 <= radix && radix <= 36)); | 6115 RUNTIME_ASSERT(radix == 0 || (2 <= radix && radix <= 36)); |
6389 | 6116 |
6390 subject = String::Flatten(subject); | 6117 subject = String::Flatten(subject); |
6391 double value; | 6118 double value; |
6392 | 6119 |
6393 { DisallowHeapAllocation no_gc; | 6120 { |
| 6121 DisallowHeapAllocation no_gc; |
6394 String::FlatContent flat = subject->GetFlatContent(); | 6122 String::FlatContent flat = subject->GetFlatContent(); |
6395 | 6123 |
6396 // ECMA-262 section 15.1.2.3, empty string is NaN | 6124 // ECMA-262 section 15.1.2.3, empty string is NaN |
6397 if (flat.IsOneByte()) { | 6125 if (flat.IsOneByte()) { |
6398 value = StringToInt( | 6126 value = |
6399 isolate->unicode_cache(), flat.ToOneByteVector(), radix); | 6127 StringToInt(isolate->unicode_cache(), flat.ToOneByteVector(), radix); |
6400 } else { | 6128 } else { |
6401 value = StringToInt( | 6129 value = StringToInt(isolate->unicode_cache(), flat.ToUC16Vector(), radix); |
6402 isolate->unicode_cache(), flat.ToUC16Vector(), radix); | |
6403 } | 6130 } |
6404 } | 6131 } |
6405 | 6132 |
6406 return *isolate->factory()->NewNumber(value); | 6133 return *isolate->factory()->NewNumber(value); |
6407 } | 6134 } |
6408 | 6135 |
6409 | 6136 |
6410 RUNTIME_FUNCTION(Runtime_StringParseFloat) { | 6137 RUNTIME_FUNCTION(Runtime_StringParseFloat) { |
6411 HandleScope shs(isolate); | 6138 HandleScope shs(isolate); |
6412 DCHECK(args.length() == 1); | 6139 DCHECK(args.length() == 1); |
(...skipping 11 matching lines...) Expand all Loading... |
6424 // y with umlauts and the micro sign are the only characters that stop | 6151 // y with umlauts and the micro sign are the only characters that stop |
6425 // fitting into one-byte when converting to uppercase. | 6152 // fitting into one-byte when converting to uppercase. |
6426 static const uc32 yuml_code = 0xff; | 6153 static const uc32 yuml_code = 0xff; |
6427 static const uc32 micro_code = 0xb5; | 6154 static const uc32 micro_code = 0xb5; |
6428 return (character == yuml_code || character == micro_code); | 6155 return (character == yuml_code || character == micro_code); |
6429 } | 6156 } |
6430 | 6157 |
6431 | 6158 |
6432 template <class Converter> | 6159 template <class Converter> |
6433 MUST_USE_RESULT static Object* ConvertCaseHelper( | 6160 MUST_USE_RESULT static Object* ConvertCaseHelper( |
6434 Isolate* isolate, | 6161 Isolate* isolate, String* string, SeqString* result, int result_length, |
6435 String* string, | |
6436 SeqString* result, | |
6437 int result_length, | |
6438 unibrow::Mapping<Converter, 128>* mapping) { | 6162 unibrow::Mapping<Converter, 128>* mapping) { |
6439 DisallowHeapAllocation no_gc; | 6163 DisallowHeapAllocation no_gc; |
6440 // We try this twice, once with the assumption that the result is no longer | 6164 // We try this twice, once with the assumption that the result is no longer |
6441 // than the input and, if that assumption breaks, again with the exact | 6165 // than the input and, if that assumption breaks, again with the exact |
6442 // length. This may not be pretty, but it is nicer than what was here before | 6166 // length. This may not be pretty, but it is nicer than what was here before |
6443 // and I hereby claim my vaffel-is. | 6167 // and I hereby claim my vaffel-is. |
6444 // | 6168 // |
6445 // NOTE: This assumes that the upper/lower case of an ASCII | 6169 // NOTE: This assumes that the upper/lower case of an ASCII |
6446 // character is also ASCII. This is currently the case, but it | 6170 // character is also ASCII. This is currently the case, but it |
6447 // might break in the future if we implement more context and locale | 6171 // might break in the future if we implement more context and locale |
6448 // dependent upper/lower conversions. | 6172 // dependent upper/lower conversions. |
6449 bool has_changed_character = false; | 6173 bool has_changed_character = false; |
6450 | 6174 |
6451 // Convert all characters to upper case, assuming that they will fit | 6175 // Convert all characters to upper case, assuming that they will fit |
6452 // in the buffer | 6176 // in the buffer |
6453 Access<ConsStringIteratorOp> op( | 6177 Access<ConsStringIteratorOp> op(isolate->runtime_state()->string_iterator()); |
6454 isolate->runtime_state()->string_iterator()); | |
6455 StringCharacterStream stream(string, op.value()); | 6178 StringCharacterStream stream(string, op.value()); |
6456 unibrow::uchar chars[Converter::kMaxWidth]; | 6179 unibrow::uchar chars[Converter::kMaxWidth]; |
6457 // We can assume that the string is not empty | 6180 // We can assume that the string is not empty |
6458 uc32 current = stream.GetNext(); | 6181 uc32 current = stream.GetNext(); |
6459 bool ignore_overflow = Converter::kIsToLower || result->IsSeqTwoByteString(); | 6182 bool ignore_overflow = Converter::kIsToLower || result->IsSeqTwoByteString(); |
6460 for (int i = 0; i < result_length;) { | 6183 for (int i = 0; i < result_length;) { |
6461 bool has_next = stream.HasMore(); | 6184 bool has_next = stream.HasMore(); |
6462 uc32 next = has_next ? stream.GetNext() : 0; | 6185 uc32 next = has_next ? stream.GetNext() : 0; |
6463 int char_length = mapping->get(current, next, chars); | 6186 int char_length = mapping->get(current, next, chars); |
6464 if (char_length == 0) { | 6187 if (char_length == 0) { |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6550 DCHECK(0 < m && m < n); | 6273 DCHECK(0 < m && m < n); |
6551 // Has high bit set in every w byte less than n. | 6274 // Has high bit set in every w byte less than n. |
6552 uintptr_t tmp1 = kOneInEveryByte * (0x7F + n) - w; | 6275 uintptr_t tmp1 = kOneInEveryByte * (0x7F + n) - w; |
6553 // Has high bit set in every w byte greater than m. | 6276 // Has high bit set in every w byte greater than m. |
6554 uintptr_t tmp2 = w + kOneInEveryByte * (0x7F - m); | 6277 uintptr_t tmp2 = w + kOneInEveryByte * (0x7F - m); |
6555 return (tmp1 & tmp2 & (kOneInEveryByte * 0x80)); | 6278 return (tmp1 & tmp2 & (kOneInEveryByte * 0x80)); |
6556 } | 6279 } |
6557 | 6280 |
6558 | 6281 |
6559 #ifdef DEBUG | 6282 #ifdef DEBUG |
6560 static bool CheckFastAsciiConvert(char* dst, | 6283 static bool CheckFastAsciiConvert(char* dst, const char* src, int length, |
6561 const char* src, | 6284 bool changed, bool is_to_lower) { |
6562 int length, | |
6563 bool changed, | |
6564 bool is_to_lower) { | |
6565 bool expected_changed = false; | 6285 bool expected_changed = false; |
6566 for (int i = 0; i < length; i++) { | 6286 for (int i = 0; i < length; i++) { |
6567 if (dst[i] == src[i]) continue; | 6287 if (dst[i] == src[i]) continue; |
6568 expected_changed = true; | 6288 expected_changed = true; |
6569 if (is_to_lower) { | 6289 if (is_to_lower) { |
6570 DCHECK('A' <= src[i] && src[i] <= 'Z'); | 6290 DCHECK('A' <= src[i] && src[i] <= 'Z'); |
6571 DCHECK(dst[i] == src[i] + ('a' - 'A')); | 6291 DCHECK(dst[i] == src[i] + ('a' - 'A')); |
6572 } else { | 6292 } else { |
6573 DCHECK('a' <= src[i] && src[i] <= 'z'); | 6293 DCHECK('a' <= src[i] && src[i] <= 'z'); |
6574 DCHECK(dst[i] == src[i] - ('a' - 'A')); | 6294 DCHECK(dst[i] == src[i] - ('a' - 'A')); |
6575 } | 6295 } |
6576 } | 6296 } |
6577 return (expected_changed == changed); | 6297 return (expected_changed == changed); |
6578 } | 6298 } |
6579 #endif | 6299 #endif |
6580 | 6300 |
6581 | 6301 |
6582 template<class Converter> | 6302 template <class Converter> |
6583 static bool FastAsciiConvert(char* dst, | 6303 static bool FastAsciiConvert(char* dst, const char* src, int length, |
6584 const char* src, | |
6585 int length, | |
6586 bool* changed_out) { | 6304 bool* changed_out) { |
6587 #ifdef DEBUG | 6305 #ifdef DEBUG |
6588 char* saved_dst = dst; | 6306 char* saved_dst = dst; |
6589 const char* saved_src = src; | 6307 const char* saved_src = src; |
6590 #endif | 6308 #endif |
6591 DisallowHeapAllocation no_gc; | 6309 DisallowHeapAllocation no_gc; |
6592 // We rely on the distance between upper and lower case letters | 6310 // We rely on the distance between upper and lower case letters |
6593 // being a known power of 2. | 6311 // being a known power of 2. |
6594 DCHECK('a' - 'A' == (1 << 5)); | 6312 DCHECK('a' - 'A' == (1 << 5)); |
6595 // Boundaries for the range of input characters than require conversion. | 6313 // Boundaries for the range of input characters than require conversion. |
6596 static const char lo = Converter::kIsToLower ? 'A' - 1 : 'a' - 1; | 6314 static const char lo = Converter::kIsToLower ? 'A' - 1 : 'a' - 1; |
6597 static const char hi = Converter::kIsToLower ? 'Z' + 1 : 'z' + 1; | 6315 static const char hi = Converter::kIsToLower ? 'Z' + 1 : 'z' + 1; |
6598 bool changed = false; | 6316 bool changed = false; |
6599 uintptr_t or_acc = 0; | 6317 uintptr_t or_acc = 0; |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6639 c ^= (1 << 5); | 6357 c ^= (1 << 5); |
6640 changed = true; | 6358 changed = true; |
6641 } | 6359 } |
6642 *dst = c; | 6360 *dst = c; |
6643 ++src; | 6361 ++src; |
6644 ++dst; | 6362 ++dst; |
6645 } | 6363 } |
6646 | 6364 |
6647 if ((or_acc & kAsciiMask) != 0) return false; | 6365 if ((or_acc & kAsciiMask) != 0) return false; |
6648 | 6366 |
6649 DCHECK(CheckFastAsciiConvert( | 6367 DCHECK(CheckFastAsciiConvert(saved_dst, saved_src, length, changed, |
6650 saved_dst, saved_src, length, changed, Converter::kIsToLower)); | 6368 Converter::kIsToLower)); |
6651 | 6369 |
6652 *changed_out = changed; | 6370 *changed_out = changed; |
6653 return true; | 6371 return true; |
6654 } | 6372 } |
6655 | 6373 |
6656 } // namespace | 6374 } // namespace |
6657 | 6375 |
6658 | 6376 |
6659 template <class Converter> | 6377 template <class Converter> |
6660 MUST_USE_RESULT static Object* ConvertCase( | 6378 MUST_USE_RESULT static Object* ConvertCase( |
6661 Handle<String> s, | 6379 Handle<String> s, Isolate* isolate, |
6662 Isolate* isolate, | |
6663 unibrow::Mapping<Converter, 128>* mapping) { | 6380 unibrow::Mapping<Converter, 128>* mapping) { |
6664 s = String::Flatten(s); | 6381 s = String::Flatten(s); |
6665 int length = s->length(); | 6382 int length = s->length(); |
6666 // Assume that the string is not empty; we need this assumption later | 6383 // Assume that the string is not empty; we need this assumption later |
6667 if (length == 0) return *s; | 6384 if (length == 0) return *s; |
6668 | 6385 |
6669 // Simpler handling of ASCII strings. | 6386 // Simpler handling of ASCII strings. |
6670 // | 6387 // |
6671 // NOTE: This assumes that the upper/lower case of an ASCII | 6388 // NOTE: This assumes that the upper/lower case of an ASCII |
6672 // character is also ASCII. This is currently the case, but it | 6389 // character is also ASCII. This is currently the case, but it |
6673 // might break in the future if we implement more context and locale | 6390 // might break in the future if we implement more context and locale |
6674 // dependent upper/lower conversions. | 6391 // dependent upper/lower conversions. |
6675 if (s->IsOneByteRepresentationUnderneath()) { | 6392 if (s->IsOneByteRepresentationUnderneath()) { |
6676 // Same length as input. | 6393 // Same length as input. |
6677 Handle<SeqOneByteString> result = | 6394 Handle<SeqOneByteString> result = |
6678 isolate->factory()->NewRawOneByteString(length).ToHandleChecked(); | 6395 isolate->factory()->NewRawOneByteString(length).ToHandleChecked(); |
6679 DisallowHeapAllocation no_gc; | 6396 DisallowHeapAllocation no_gc; |
6680 String::FlatContent flat_content = s->GetFlatContent(); | 6397 String::FlatContent flat_content = s->GetFlatContent(); |
6681 DCHECK(flat_content.IsFlat()); | 6398 DCHECK(flat_content.IsFlat()); |
6682 bool has_changed_character = false; | 6399 bool has_changed_character = false; |
6683 bool is_ascii = FastAsciiConvert<Converter>( | 6400 bool is_ascii = FastAsciiConvert<Converter>( |
6684 reinterpret_cast<char*>(result->GetChars()), | 6401 reinterpret_cast<char*>(result->GetChars()), |
6685 reinterpret_cast<const char*>(flat_content.ToOneByteVector().start()), | 6402 reinterpret_cast<const char*>(flat_content.ToOneByteVector().start()), |
6686 length, | 6403 length, &has_changed_character); |
6687 &has_changed_character); | |
6688 // If not ASCII, we discard the result and take the 2 byte path. | 6404 // If not ASCII, we discard the result and take the 2 byte path. |
6689 if (is_ascii) return has_changed_character ? *result : *s; | 6405 if (is_ascii) return has_changed_character ? *result : *s; |
6690 } | 6406 } |
6691 | 6407 |
6692 Handle<SeqString> result; // Same length as input. | 6408 Handle<SeqString> result; // Same length as input. |
6693 if (s->IsOneByteRepresentation()) { | 6409 if (s->IsOneByteRepresentation()) { |
6694 result = isolate->factory()->NewRawOneByteString(length).ToHandleChecked(); | 6410 result = isolate->factory()->NewRawOneByteString(length).ToHandleChecked(); |
6695 } else { | 6411 } else { |
6696 result = isolate->factory()->NewRawTwoByteString(length).ToHandleChecked(); | 6412 result = isolate->factory()->NewRawTwoByteString(length).ToHandleChecked(); |
6697 } | 6413 } |
(...skipping 12 matching lines...) Expand all Loading... |
6710 isolate, result, isolate->factory()->NewRawTwoByteString(length)); | 6426 isolate, result, isolate->factory()->NewRawTwoByteString(length)); |
6711 } | 6427 } |
6712 return ConvertCaseHelper(isolate, *s, *result, length, mapping); | 6428 return ConvertCaseHelper(isolate, *s, *result, length, mapping); |
6713 } | 6429 } |
6714 | 6430 |
6715 | 6431 |
6716 RUNTIME_FUNCTION(Runtime_StringToLowerCase) { | 6432 RUNTIME_FUNCTION(Runtime_StringToLowerCase) { |
6717 HandleScope scope(isolate); | 6433 HandleScope scope(isolate); |
6718 DCHECK(args.length() == 1); | 6434 DCHECK(args.length() == 1); |
6719 CONVERT_ARG_HANDLE_CHECKED(String, s, 0); | 6435 CONVERT_ARG_HANDLE_CHECKED(String, s, 0); |
6720 return ConvertCase( | 6436 return ConvertCase(s, isolate, isolate->runtime_state()->to_lower_mapping()); |
6721 s, isolate, isolate->runtime_state()->to_lower_mapping()); | |
6722 } | 6437 } |
6723 | 6438 |
6724 | 6439 |
6725 RUNTIME_FUNCTION(Runtime_StringToUpperCase) { | 6440 RUNTIME_FUNCTION(Runtime_StringToUpperCase) { |
6726 HandleScope scope(isolate); | 6441 HandleScope scope(isolate); |
6727 DCHECK(args.length() == 1); | 6442 DCHECK(args.length() == 1); |
6728 CONVERT_ARG_HANDLE_CHECKED(String, s, 0); | 6443 CONVERT_ARG_HANDLE_CHECKED(String, s, 0); |
6729 return ConvertCase( | 6444 return ConvertCase(s, isolate, isolate->runtime_state()->to_upper_mapping()); |
6730 s, isolate, isolate->runtime_state()->to_upper_mapping()); | |
6731 } | 6445 } |
6732 | 6446 |
6733 | 6447 |
6734 RUNTIME_FUNCTION(Runtime_StringTrim) { | 6448 RUNTIME_FUNCTION(Runtime_StringTrim) { |
6735 HandleScope scope(isolate); | 6449 HandleScope scope(isolate); |
6736 DCHECK(args.length() == 3); | 6450 DCHECK(args.length() == 3); |
6737 | 6451 |
6738 CONVERT_ARG_HANDLE_CHECKED(String, string, 0); | 6452 CONVERT_ARG_HANDLE_CHECKED(String, string, 0); |
6739 CONVERT_BOOLEAN_ARG_CHECKED(trimLeft, 1); | 6453 CONVERT_BOOLEAN_ARG_CHECKED(trimLeft, 1); |
6740 CONVERT_BOOLEAN_ARG_CHECKED(trimRight, 2); | 6454 CONVERT_BOOLEAN_ARG_CHECKED(trimRight, 2); |
6741 | 6455 |
6742 string = String::Flatten(string); | 6456 string = String::Flatten(string); |
6743 int length = string->length(); | 6457 int length = string->length(); |
6744 | 6458 |
6745 int left = 0; | 6459 int left = 0; |
6746 UnicodeCache* unicode_cache = isolate->unicode_cache(); | 6460 UnicodeCache* unicode_cache = isolate->unicode_cache(); |
6747 if (trimLeft) { | 6461 if (trimLeft) { |
6748 while (left < length && | 6462 while (left < length && |
6749 unicode_cache->IsWhiteSpaceOrLineTerminator(string->Get(left))) { | 6463 unicode_cache->IsWhiteSpaceOrLineTerminator(string->Get(left))) { |
6750 left++; | 6464 left++; |
6751 } | 6465 } |
6752 } | 6466 } |
6753 | 6467 |
6754 int right = length; | 6468 int right = length; |
6755 if (trimRight) { | 6469 if (trimRight) { |
6756 while (right > left && | 6470 while ( |
6757 unicode_cache->IsWhiteSpaceOrLineTerminator( | 6471 right > left && |
6758 string->Get(right - 1))) { | 6472 unicode_cache->IsWhiteSpaceOrLineTerminator(string->Get(right - 1))) { |
6759 right--; | 6473 right--; |
6760 } | 6474 } |
6761 } | 6475 } |
6762 | 6476 |
6763 return *isolate->factory()->NewSubString(string, left, right); | 6477 return *isolate->factory()->NewSubString(string, left, right); |
6764 } | 6478 } |
6765 | 6479 |
6766 | 6480 |
6767 RUNTIME_FUNCTION(Runtime_StringSplit) { | 6481 RUNTIME_FUNCTION(Runtime_StringSplit) { |
6768 HandleScope handle_scope(isolate); | 6482 HandleScope handle_scope(isolate); |
6769 DCHECK(args.length() == 3); | 6483 DCHECK(args.length() == 3); |
6770 CONVERT_ARG_HANDLE_CHECKED(String, subject, 0); | 6484 CONVERT_ARG_HANDLE_CHECKED(String, subject, 0); |
6771 CONVERT_ARG_HANDLE_CHECKED(String, pattern, 1); | 6485 CONVERT_ARG_HANDLE_CHECKED(String, pattern, 1); |
6772 CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[2]); | 6486 CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[2]); |
6773 RUNTIME_ASSERT(limit > 0); | 6487 RUNTIME_ASSERT(limit > 0); |
6774 | 6488 |
6775 int subject_length = subject->length(); | 6489 int subject_length = subject->length(); |
6776 int pattern_length = pattern->length(); | 6490 int pattern_length = pattern->length(); |
6777 RUNTIME_ASSERT(pattern_length > 0); | 6491 RUNTIME_ASSERT(pattern_length > 0); |
6778 | 6492 |
6779 if (limit == 0xffffffffu) { | 6493 if (limit == 0xffffffffu) { |
6780 Handle<Object> cached_answer( | 6494 Handle<Object> cached_answer( |
6781 RegExpResultsCache::Lookup(isolate->heap(), | 6495 RegExpResultsCache::Lookup(isolate->heap(), *subject, *pattern, |
6782 *subject, | |
6783 *pattern, | |
6784 RegExpResultsCache::STRING_SPLIT_SUBSTRINGS), | 6496 RegExpResultsCache::STRING_SPLIT_SUBSTRINGS), |
6785 isolate); | 6497 isolate); |
6786 if (*cached_answer != Smi::FromInt(0)) { | 6498 if (*cached_answer != Smi::FromInt(0)) { |
6787 // The cache FixedArray is a COW-array and can therefore be reused. | 6499 // The cache FixedArray is a COW-array and can therefore be reused. |
6788 Handle<JSArray> result = | 6500 Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements( |
6789 isolate->factory()->NewJSArrayWithElements( | 6501 Handle<FixedArray>::cast(cached_answer)); |
6790 Handle<FixedArray>::cast(cached_answer)); | |
6791 return *result; | 6502 return *result; |
6792 } | 6503 } |
6793 } | 6504 } |
6794 | 6505 |
6795 // The limit can be very large (0xffffffffu), but since the pattern | 6506 // The limit can be very large (0xffffffffu), but since the pattern |
6796 // isn't empty, we can never create more parts than ~half the length | 6507 // isn't empty, we can never create more parts than ~half the length |
6797 // of the subject. | 6508 // of the subject. |
6798 | 6509 |
6799 subject = String::Flatten(subject); | 6510 subject = String::Flatten(subject); |
6800 pattern = String::Flatten(pattern); | 6511 pattern = String::Flatten(pattern); |
6801 | 6512 |
6802 static const int kMaxInitialListCapacity = 16; | 6513 static const int kMaxInitialListCapacity = 16; |
6803 | 6514 |
6804 ZoneScope zone_scope(isolate->runtime_zone()); | 6515 ZoneScope zone_scope(isolate->runtime_zone()); |
6805 | 6516 |
6806 // Find (up to limit) indices of separator and end-of-string in subject | 6517 // Find (up to limit) indices of separator and end-of-string in subject |
6807 int initial_capacity = Min<uint32_t>(kMaxInitialListCapacity, limit); | 6518 int initial_capacity = Min<uint32_t>(kMaxInitialListCapacity, limit); |
6808 ZoneList<int> indices(initial_capacity, zone_scope.zone()); | 6519 ZoneList<int> indices(initial_capacity, zone_scope.zone()); |
6809 | 6520 |
6810 FindStringIndicesDispatch(isolate, *subject, *pattern, | 6521 FindStringIndicesDispatch(isolate, *subject, *pattern, &indices, limit, |
6811 &indices, limit, zone_scope.zone()); | 6522 zone_scope.zone()); |
6812 | 6523 |
6813 if (static_cast<uint32_t>(indices.length()) < limit) { | 6524 if (static_cast<uint32_t>(indices.length()) < limit) { |
6814 indices.Add(subject_length, zone_scope.zone()); | 6525 indices.Add(subject_length, zone_scope.zone()); |
6815 } | 6526 } |
6816 | 6527 |
6817 // The list indices now contains the end of each part to create. | 6528 // The list indices now contains the end of each part to create. |
6818 | 6529 |
6819 // Create JSArray of substrings separated by separator. | 6530 // Create JSArray of substrings separated by separator. |
6820 int part_count = indices.length(); | 6531 int part_count = indices.length(); |
6821 | 6532 |
(...skipping 14 matching lines...) Expand all Loading... |
6836 HandleScope local_loop_handle(isolate); | 6547 HandleScope local_loop_handle(isolate); |
6837 int part_end = indices.at(i); | 6548 int part_end = indices.at(i); |
6838 Handle<String> substring = | 6549 Handle<String> substring = |
6839 isolate->factory()->NewProperSubString(subject, part_start, part_end); | 6550 isolate->factory()->NewProperSubString(subject, part_start, part_end); |
6840 elements->set(i, *substring); | 6551 elements->set(i, *substring); |
6841 part_start = part_end + pattern_length; | 6552 part_start = part_end + pattern_length; |
6842 } | 6553 } |
6843 | 6554 |
6844 if (limit == 0xffffffffu) { | 6555 if (limit == 0xffffffffu) { |
6845 if (result->HasFastObjectElements()) { | 6556 if (result->HasFastObjectElements()) { |
6846 RegExpResultsCache::Enter(isolate, | 6557 RegExpResultsCache::Enter(isolate, subject, pattern, elements, |
6847 subject, | |
6848 pattern, | |
6849 elements, | |
6850 RegExpResultsCache::STRING_SPLIT_SUBSTRINGS); | 6558 RegExpResultsCache::STRING_SPLIT_SUBSTRINGS); |
6851 } | 6559 } |
6852 } | 6560 } |
6853 | 6561 |
6854 return *result; | 6562 return *result; |
6855 } | 6563 } |
6856 | 6564 |
6857 | 6565 |
6858 // Copies Latin1 characters to the given fixed array looking up | 6566 // Copies Latin1 characters to the given fixed array looking up |
6859 // one-char strings in the cache. Gives up on the first char that is | 6567 // one-char strings in the cache. Gives up on the first char that is |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6905 | 6613 |
6906 DisallowHeapAllocation no_gc; | 6614 DisallowHeapAllocation no_gc; |
6907 String::FlatContent content = s->GetFlatContent(); | 6615 String::FlatContent content = s->GetFlatContent(); |
6908 if (content.IsOneByte()) { | 6616 if (content.IsOneByte()) { |
6909 Vector<const uint8_t> chars = content.ToOneByteVector(); | 6617 Vector<const uint8_t> chars = content.ToOneByteVector(); |
6910 // Note, this will initialize all elements (not only the prefix) | 6618 // Note, this will initialize all elements (not only the prefix) |
6911 // to prevent GC from seeing partially initialized array. | 6619 // to prevent GC from seeing partially initialized array. |
6912 position = CopyCachedOneByteCharsToArray(isolate->heap(), chars.start(), | 6620 position = CopyCachedOneByteCharsToArray(isolate->heap(), chars.start(), |
6913 *elements, length); | 6621 *elements, length); |
6914 } else { | 6622 } else { |
6915 MemsetPointer(elements->data_start(), | 6623 MemsetPointer(elements->data_start(), isolate->heap()->undefined_value(), |
6916 isolate->heap()->undefined_value(), | |
6917 length); | 6624 length); |
6918 } | 6625 } |
6919 } else { | 6626 } else { |
6920 elements = isolate->factory()->NewFixedArray(length); | 6627 elements = isolate->factory()->NewFixedArray(length); |
6921 } | 6628 } |
6922 for (int i = position; i < length; ++i) { | 6629 for (int i = position; i < length; ++i) { |
6923 Handle<Object> str = | 6630 Handle<Object> str = |
6924 isolate->factory()->LookupSingleCharacterStringFromCode(s->Get(i)); | 6631 isolate->factory()->LookupSingleCharacterStringFromCode(s->Get(i)); |
6925 elements->set(i, *str); | 6632 elements->set(i, *str); |
6926 } | 6633 } |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7114 CONVERT_ARG_HANDLE_CHECKED(String, str2, 1); | 6821 CONVERT_ARG_HANDLE_CHECKED(String, str2, 1); |
7115 isolate->counters()->string_add_runtime()->Increment(); | 6822 isolate->counters()->string_add_runtime()->Increment(); |
7116 Handle<String> result; | 6823 Handle<String> result; |
7117 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 6824 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
7118 isolate, result, isolate->factory()->NewConsString(str1, str2)); | 6825 isolate, result, isolate->factory()->NewConsString(str1, str2)); |
7119 return *result; | 6826 return *result; |
7120 } | 6827 } |
7121 | 6828 |
7122 | 6829 |
7123 template <typename sinkchar> | 6830 template <typename sinkchar> |
7124 static inline void StringBuilderConcatHelper(String* special, | 6831 static inline void StringBuilderConcatHelper(String* special, sinkchar* sink, |
7125 sinkchar* sink, | |
7126 FixedArray* fixed_array, | 6832 FixedArray* fixed_array, |
7127 int array_length) { | 6833 int array_length) { |
7128 DisallowHeapAllocation no_gc; | 6834 DisallowHeapAllocation no_gc; |
7129 int position = 0; | 6835 int position = 0; |
7130 for (int i = 0; i < array_length; i++) { | 6836 for (int i = 0; i < array_length; i++) { |
7131 Object* element = fixed_array->get(i); | 6837 Object* element = fixed_array->get(i); |
7132 if (element->IsSmi()) { | 6838 if (element->IsSmi()) { |
7133 // Smi encoding of position and length. | 6839 // Smi encoding of position and length. |
7134 int encoded_slice = Smi::cast(element)->value(); | 6840 int encoded_slice = Smi::cast(element)->value(); |
7135 int pos; | 6841 int pos; |
7136 int len; | 6842 int len; |
7137 if (encoded_slice > 0) { | 6843 if (encoded_slice > 0) { |
7138 // Position and length encoded in one smi. | 6844 // Position and length encoded in one smi. |
7139 pos = StringBuilderSubstringPosition::decode(encoded_slice); | 6845 pos = StringBuilderSubstringPosition::decode(encoded_slice); |
7140 len = StringBuilderSubstringLength::decode(encoded_slice); | 6846 len = StringBuilderSubstringLength::decode(encoded_slice); |
7141 } else { | 6847 } else { |
7142 // Position and length encoded in two smis. | 6848 // Position and length encoded in two smis. |
7143 Object* obj = fixed_array->get(++i); | 6849 Object* obj = fixed_array->get(++i); |
7144 DCHECK(obj->IsSmi()); | 6850 DCHECK(obj->IsSmi()); |
7145 pos = Smi::cast(obj)->value(); | 6851 pos = Smi::cast(obj)->value(); |
7146 len = -encoded_slice; | 6852 len = -encoded_slice; |
7147 } | 6853 } |
7148 String::WriteToFlat(special, | 6854 String::WriteToFlat(special, sink + position, pos, pos + len); |
7149 sink + position, | |
7150 pos, | |
7151 pos + len); | |
7152 position += len; | 6855 position += len; |
7153 } else { | 6856 } else { |
7154 String* string = String::cast(element); | 6857 String* string = String::cast(element); |
7155 int element_length = string->length(); | 6858 int element_length = string->length(); |
7156 String::WriteToFlat(string, sink + position, 0, element_length); | 6859 String::WriteToFlat(string, sink + position, 0, element_length); |
7157 position += element_length; | 6860 position += element_length; |
7158 } | 6861 } |
7159 } | 6862 } |
7160 } | 6863 } |
7161 | 6864 |
7162 | 6865 |
7163 // Returns the result length of the concatenation. | 6866 // Returns the result length of the concatenation. |
7164 // On illegal argument, -1 is returned. | 6867 // On illegal argument, -1 is returned. |
7165 static inline int StringBuilderConcatLength(int special_length, | 6868 static inline int StringBuilderConcatLength(int special_length, |
7166 FixedArray* fixed_array, | 6869 FixedArray* fixed_array, |
7167 int array_length, | 6870 int array_length, bool* one_byte) { |
7168 bool* one_byte) { | |
7169 DisallowHeapAllocation no_gc; | 6871 DisallowHeapAllocation no_gc; |
7170 int position = 0; | 6872 int position = 0; |
7171 for (int i = 0; i < array_length; i++) { | 6873 for (int i = 0; i < array_length; i++) { |
7172 int increment = 0; | 6874 int increment = 0; |
7173 Object* elt = fixed_array->get(i); | 6875 Object* elt = fixed_array->get(i); |
7174 if (elt->IsSmi()) { | 6876 if (elt->IsSmi()) { |
7175 // Smi encoding of position and length. | 6877 // Smi encoding of position and length. |
7176 int smi_value = Smi::cast(elt)->value(); | 6878 int smi_value = Smi::cast(elt)->value(); |
7177 int pos; | 6879 int pos; |
7178 int len; | 6880 int len; |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7237 JSObject::EnsureCanContainHeapObjectElements(array); | 6939 JSObject::EnsureCanContainHeapObjectElements(array); |
7238 | 6940 |
7239 int special_length = special->length(); | 6941 int special_length = special->length(); |
7240 if (!array->HasFastObjectElements()) { | 6942 if (!array->HasFastObjectElements()) { |
7241 return isolate->Throw(isolate->heap()->illegal_argument_string()); | 6943 return isolate->Throw(isolate->heap()->illegal_argument_string()); |
7242 } | 6944 } |
7243 | 6945 |
7244 int length; | 6946 int length; |
7245 bool one_byte = special->HasOnlyOneByteChars(); | 6947 bool one_byte = special->HasOnlyOneByteChars(); |
7246 | 6948 |
7247 { DisallowHeapAllocation no_gc; | 6949 { |
| 6950 DisallowHeapAllocation no_gc; |
7248 FixedArray* fixed_array = FixedArray::cast(array->elements()); | 6951 FixedArray* fixed_array = FixedArray::cast(array->elements()); |
7249 if (fixed_array->length() < array_length) { | 6952 if (fixed_array->length() < array_length) { |
7250 array_length = fixed_array->length(); | 6953 array_length = fixed_array->length(); |
7251 } | 6954 } |
7252 | 6955 |
7253 if (array_length == 0) { | 6956 if (array_length == 0) { |
7254 return isolate->heap()->empty_string(); | 6957 return isolate->heap()->empty_string(); |
7255 } else if (array_length == 1) { | 6958 } else if (array_length == 1) { |
7256 Object* first = fixed_array->get(0); | 6959 Object* first = fixed_array->get(0); |
7257 if (first->IsString()) return first; | 6960 if (first->IsString()) return first; |
7258 } | 6961 } |
7259 length = StringBuilderConcatLength( | 6962 length = StringBuilderConcatLength(special_length, fixed_array, |
7260 special_length, fixed_array, array_length, &one_byte); | 6963 array_length, &one_byte); |
7261 } | 6964 } |
7262 | 6965 |
7263 if (length == -1) { | 6966 if (length == -1) { |
7264 return isolate->Throw(isolate->heap()->illegal_argument_string()); | 6967 return isolate->Throw(isolate->heap()->illegal_argument_string()); |
7265 } | 6968 } |
7266 | 6969 |
7267 if (one_byte) { | 6970 if (one_byte) { |
7268 Handle<SeqOneByteString> answer; | 6971 Handle<SeqOneByteString> answer; |
7269 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 6972 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
7270 isolate, answer, | 6973 isolate, answer, isolate->factory()->NewRawOneByteString(length)); |
7271 isolate->factory()->NewRawOneByteString(length)); | 6974 StringBuilderConcatHelper(*special, answer->GetChars(), |
7272 StringBuilderConcatHelper(*special, | |
7273 answer->GetChars(), | |
7274 FixedArray::cast(array->elements()), | 6975 FixedArray::cast(array->elements()), |
7275 array_length); | 6976 array_length); |
7276 return *answer; | 6977 return *answer; |
7277 } else { | 6978 } else { |
7278 Handle<SeqTwoByteString> answer; | 6979 Handle<SeqTwoByteString> answer; |
7279 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 6980 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
7280 isolate, answer, | 6981 isolate, answer, isolate->factory()->NewRawTwoByteString(length)); |
7281 isolate->factory()->NewRawTwoByteString(length)); | 6982 StringBuilderConcatHelper(*special, answer->GetChars(), |
7282 StringBuilderConcatHelper(*special, | |
7283 answer->GetChars(), | |
7284 FixedArray::cast(array->elements()), | 6983 FixedArray::cast(array->elements()), |
7285 array_length); | 6984 array_length); |
7286 return *answer; | 6985 return *answer; |
7287 } | 6986 } |
7288 } | 6987 } |
7289 | 6988 |
7290 | 6989 |
7291 RUNTIME_FUNCTION(Runtime_StringBuilderJoin) { | 6990 RUNTIME_FUNCTION(Runtime_StringBuilderJoin) { |
7292 HandleScope scope(isolate); | 6991 HandleScope scope(isolate); |
7293 DCHECK(args.length() == 3); | 6992 DCHECK(args.length() == 3); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7329 if (increment > String::kMaxLength - length) { | 7028 if (increment > String::kMaxLength - length) { |
7330 STATIC_ASSERT(String::kMaxLength < kMaxInt); | 7029 STATIC_ASSERT(String::kMaxLength < kMaxInt); |
7331 length = kMaxInt; // Provoke exception; | 7030 length = kMaxInt; // Provoke exception; |
7332 break; | 7031 break; |
7333 } | 7032 } |
7334 length += increment; | 7033 length += increment; |
7335 } | 7034 } |
7336 | 7035 |
7337 Handle<SeqTwoByteString> answer; | 7036 Handle<SeqTwoByteString> answer; |
7338 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 7037 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
7339 isolate, answer, | 7038 isolate, answer, isolate->factory()->NewRawTwoByteString(length)); |
7340 isolate->factory()->NewRawTwoByteString(length)); | |
7341 | 7039 |
7342 DisallowHeapAllocation no_gc; | 7040 DisallowHeapAllocation no_gc; |
7343 | 7041 |
7344 uc16* sink = answer->GetChars(); | 7042 uc16* sink = answer->GetChars(); |
7345 #ifdef DEBUG | 7043 #ifdef DEBUG |
7346 uc16* end = sink + length; | 7044 uc16* end = sink + length; |
7347 #endif | 7045 #endif |
7348 | 7046 |
7349 RUNTIME_ASSERT(fixed_array->get(0)->IsString()); | 7047 RUNTIME_ASSERT(fixed_array->get(0)->IsString()); |
7350 String* first = String::cast(fixed_array->get(0)); | 7048 String* first = String::cast(fixed_array->get(0)); |
(...skipping 30 matching lines...) Expand all Loading... |
7381 DisallowHeapAllocation no_gc; | 7079 DisallowHeapAllocation no_gc; |
7382 int previous_separator_position = 0; | 7080 int previous_separator_position = 0; |
7383 int separator_length = separator->length(); | 7081 int separator_length = separator->length(); |
7384 int cursor = 0; | 7082 int cursor = 0; |
7385 for (int i = 0; i < elements_length; i += 2) { | 7083 for (int i = 0; i < elements_length; i += 2) { |
7386 int position = NumberToInt32(elements->get(i)); | 7084 int position = NumberToInt32(elements->get(i)); |
7387 String* string = String::cast(elements->get(i + 1)); | 7085 String* string = String::cast(elements->get(i + 1)); |
7388 int string_length = string->length(); | 7086 int string_length = string->length(); |
7389 if (string->length() > 0) { | 7087 if (string->length() > 0) { |
7390 while (previous_separator_position < position) { | 7088 while (previous_separator_position < position) { |
7391 String::WriteToFlat<Char>(separator, &buffer[cursor], | 7089 String::WriteToFlat<Char>(separator, &buffer[cursor], 0, |
7392 0, separator_length); | 7090 separator_length); |
7393 cursor += separator_length; | 7091 cursor += separator_length; |
7394 previous_separator_position++; | 7092 previous_separator_position++; |
7395 } | 7093 } |
7396 String::WriteToFlat<Char>(string, &buffer[cursor], | 7094 String::WriteToFlat<Char>(string, &buffer[cursor], 0, string_length); |
7397 0, string_length); | |
7398 cursor += string->length(); | 7095 cursor += string->length(); |
7399 } | 7096 } |
7400 } | 7097 } |
7401 if (separator_length > 0) { | 7098 if (separator_length > 0) { |
7402 // Array length must be representable as a signed 32-bit number, | 7099 // Array length must be representable as a signed 32-bit number, |
7403 // otherwise the total string length would have been too large. | 7100 // otherwise the total string length would have been too large. |
7404 DCHECK(array_length <= 0x7fffffff); // Is int32_t. | 7101 DCHECK(array_length <= 0x7fffffff); // Is int32_t. |
7405 int last_array_index = static_cast<int>(array_length - 1); | 7102 int last_array_index = static_cast<int>(array_length - 1); |
7406 while (previous_separator_position < last_array_index) { | 7103 while (previous_separator_position < last_array_index) { |
7407 String::WriteToFlat<Char>(separator, &buffer[cursor], | 7104 String::WriteToFlat<Char>(separator, &buffer[cursor], 0, |
7408 0, separator_length); | 7105 separator_length); |
7409 cursor += separator_length; | 7106 cursor += separator_length; |
7410 previous_separator_position++; | 7107 previous_separator_position++; |
7411 } | 7108 } |
7412 } | 7109 } |
7413 DCHECK(cursor <= buffer.length()); | 7110 DCHECK(cursor <= buffer.length()); |
7414 } | 7111 } |
7415 | 7112 |
7416 | 7113 |
7417 RUNTIME_FUNCTION(Runtime_SparseJoinWithSeparator) { | 7114 RUNTIME_FUNCTION(Runtime_SparseJoinWithSeparator) { |
7418 HandleScope scope(isolate); | 7115 HandleScope scope(isolate); |
(...skipping 16 matching lines...) Expand all Loading... |
7435 RUNTIME_ASSERT(elements_length <= elements_array->elements()->length()); | 7132 RUNTIME_ASSERT(elements_length <= elements_array->elements()->length()); |
7436 RUNTIME_ASSERT((elements_length & 1) == 0); // Even length. | 7133 RUNTIME_ASSERT((elements_length & 1) == 0); // Even length. |
7437 FixedArray* elements = FixedArray::cast(elements_array->elements()); | 7134 FixedArray* elements = FixedArray::cast(elements_array->elements()); |
7438 for (int i = 0; i < elements_length; i += 2) { | 7135 for (int i = 0; i < elements_length; i += 2) { |
7439 RUNTIME_ASSERT(elements->get(i)->IsNumber()); | 7136 RUNTIME_ASSERT(elements->get(i)->IsNumber()); |
7440 CONVERT_NUMBER_CHECKED(uint32_t, position, Uint32, elements->get(i)); | 7137 CONVERT_NUMBER_CHECKED(uint32_t, position, Uint32, elements->get(i)); |
7441 RUNTIME_ASSERT(position < array_length); | 7138 RUNTIME_ASSERT(position < array_length); |
7442 RUNTIME_ASSERT(elements->get(i + 1)->IsString()); | 7139 RUNTIME_ASSERT(elements->get(i + 1)->IsString()); |
7443 } | 7140 } |
7444 | 7141 |
7445 { DisallowHeapAllocation no_gc; | 7142 { |
| 7143 DisallowHeapAllocation no_gc; |
7446 for (int i = 0; i < elements_length; i += 2) { | 7144 for (int i = 0; i < elements_length; i += 2) { |
7447 String* string = String::cast(elements->get(i + 1)); | 7145 String* string = String::cast(elements->get(i + 1)); |
7448 int length = string->length(); | 7146 int length = string->length(); |
7449 if (is_one_byte && !string->IsOneByteRepresentation()) { | 7147 if (is_one_byte && !string->IsOneByteRepresentation()) { |
7450 is_one_byte = false; | 7148 is_one_byte = false; |
7451 } | 7149 } |
7452 if (length > String::kMaxLength || | 7150 if (length > String::kMaxLength || |
7453 String::kMaxLength - length < string_length) { | 7151 String::kMaxLength - length < string_length) { |
7454 overflow = true; | 7152 overflow = true; |
7455 break; | 7153 break; |
(...skipping 21 matching lines...) Expand all Loading... |
7477 } | 7175 } |
7478 } | 7176 } |
7479 if (overflow) { | 7177 if (overflow) { |
7480 // Throw an exception if the resulting string is too large. See | 7178 // Throw an exception if the resulting string is too large. See |
7481 // https://code.google.com/p/chromium/issues/detail?id=336820 | 7179 // https://code.google.com/p/chromium/issues/detail?id=336820 |
7482 // for details. | 7180 // for details. |
7483 THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewInvalidStringLengthError()); | 7181 THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewInvalidStringLengthError()); |
7484 } | 7182 } |
7485 | 7183 |
7486 if (is_one_byte) { | 7184 if (is_one_byte) { |
7487 Handle<SeqOneByteString> result = isolate->factory()->NewRawOneByteString( | 7185 Handle<SeqOneByteString> result = isolate->factory() |
7488 string_length).ToHandleChecked(); | 7186 ->NewRawOneByteString(string_length) |
| 7187 .ToHandleChecked(); |
7489 JoinSparseArrayWithSeparator<uint8_t>( | 7188 JoinSparseArrayWithSeparator<uint8_t>( |
7490 FixedArray::cast(elements_array->elements()), | 7189 FixedArray::cast(elements_array->elements()), elements_length, |
7491 elements_length, | 7190 array_length, *separator, |
7492 array_length, | |
7493 *separator, | |
7494 Vector<uint8_t>(result->GetChars(), string_length)); | 7191 Vector<uint8_t>(result->GetChars(), string_length)); |
7495 return *result; | 7192 return *result; |
7496 } else { | 7193 } else { |
7497 Handle<SeqTwoByteString> result = isolate->factory()->NewRawTwoByteString( | 7194 Handle<SeqTwoByteString> result = isolate->factory() |
7498 string_length).ToHandleChecked(); | 7195 ->NewRawTwoByteString(string_length) |
| 7196 .ToHandleChecked(); |
7499 JoinSparseArrayWithSeparator<uc16>( | 7197 JoinSparseArrayWithSeparator<uc16>( |
7500 FixedArray::cast(elements_array->elements()), | 7198 FixedArray::cast(elements_array->elements()), elements_length, |
7501 elements_length, | 7199 array_length, *separator, |
7502 array_length, | |
7503 *separator, | |
7504 Vector<uc16>(result->GetChars(), string_length)); | 7200 Vector<uc16>(result->GetChars(), string_length)); |
7505 return *result; | 7201 return *result; |
7506 } | 7202 } |
7507 } | 7203 } |
7508 | 7204 |
7509 | 7205 |
7510 RUNTIME_FUNCTION(Runtime_NumberOr) { | 7206 RUNTIME_FUNCTION(Runtime_NumberOr) { |
7511 HandleScope scope(isolate); | 7207 HandleScope scope(isolate); |
7512 DCHECK(args.length() == 2); | 7208 DCHECK(args.length() == 2); |
7513 | 7209 |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7644 uint32_t x_scaled = x_value; | 7340 uint32_t x_scaled = x_value; |
7645 uint32_t y_scaled = y_value; | 7341 uint32_t y_scaled = y_value; |
7646 if (x_value < 0 || y_value < 0) { | 7342 if (x_value < 0 || y_value < 0) { |
7647 if (y_value >= 0) return Smi::FromInt(LESS); | 7343 if (y_value >= 0) return Smi::FromInt(LESS); |
7648 if (x_value >= 0) return Smi::FromInt(GREATER); | 7344 if (x_value >= 0) return Smi::FromInt(GREATER); |
7649 x_scaled = -x_value; | 7345 x_scaled = -x_value; |
7650 y_scaled = -y_value; | 7346 y_scaled = -y_value; |
7651 } | 7347 } |
7652 | 7348 |
7653 static const uint32_t kPowersOf10[] = { | 7349 static const uint32_t kPowersOf10[] = { |
7654 1, 10, 100, 1000, 10*1000, 100*1000, | 7350 1, 10, 100, 1000, |
7655 1000*1000, 10*1000*1000, 100*1000*1000, | 7351 10 * 1000, 100 * 1000, 1000 * 1000, 10 * 1000 * 1000, |
7656 1000*1000*1000 | 7352 100 * 1000 * 1000, 1000 * 1000 * 1000}; |
7657 }; | |
7658 | 7353 |
7659 // If the integers have the same number of decimal digits they can be | 7354 // If the integers have the same number of decimal digits they can be |
7660 // compared directly as the numeric order is the same as the | 7355 // compared directly as the numeric order is the same as the |
7661 // lexicographic order. If one integer has fewer digits, it is scaled | 7356 // lexicographic order. If one integer has fewer digits, it is scaled |
7662 // by some power of 10 to have the same number of digits as the longer | 7357 // by some power of 10 to have the same number of digits as the longer |
7663 // integer. If the scaled integers are equal it means the shorter | 7358 // integer. If the scaled integers are equal it means the shorter |
7664 // integer comes first in the lexicographic order. | 7359 // integer comes first in the lexicographic order. |
7665 | 7360 |
7666 // From http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10 | 7361 // From http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10 |
7667 int x_log2 = IntegerLog2(x_scaled); | 7362 int x_log2 = IntegerLog2(x_scaled); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7708 // A few fast case tests before we flatten. | 7403 // A few fast case tests before we flatten. |
7709 if (x.is_identical_to(y)) return Smi::FromInt(EQUAL); | 7404 if (x.is_identical_to(y)) return Smi::FromInt(EQUAL); |
7710 if (y->length() == 0) { | 7405 if (y->length() == 0) { |
7711 if (x->length() == 0) return Smi::FromInt(EQUAL); | 7406 if (x->length() == 0) return Smi::FromInt(EQUAL); |
7712 return Smi::FromInt(GREATER); | 7407 return Smi::FromInt(GREATER); |
7713 } else if (x->length() == 0) { | 7408 } else if (x->length() == 0) { |
7714 return Smi::FromInt(LESS); | 7409 return Smi::FromInt(LESS); |
7715 } | 7410 } |
7716 | 7411 |
7717 int d = x->Get(0) - y->Get(0); | 7412 int d = x->Get(0) - y->Get(0); |
7718 if (d < 0) return Smi::FromInt(LESS); | 7413 if (d < 0) |
7719 else if (d > 0) return Smi::FromInt(GREATER); | 7414 return Smi::FromInt(LESS); |
| 7415 else if (d > 0) |
| 7416 return Smi::FromInt(GREATER); |
7720 | 7417 |
7721 // Slow case. | 7418 // Slow case. |
7722 x = String::Flatten(x); | 7419 x = String::Flatten(x); |
7723 y = String::Flatten(y); | 7420 y = String::Flatten(y); |
7724 | 7421 |
7725 DisallowHeapAllocation no_gc; | 7422 DisallowHeapAllocation no_gc; |
7726 Object* equal_prefix_result = Smi::FromInt(EQUAL); | 7423 Object* equal_prefix_result = Smi::FromInt(EQUAL); |
7727 int prefix_length = x->length(); | 7424 int prefix_length = x->length(); |
7728 if (y->length() < prefix_length) { | 7425 if (y->length() < prefix_length) { |
7729 prefix_length = y->length(); | 7426 prefix_length = y->length(); |
(...skipping 26 matching lines...) Expand all Loading... |
7756 Object* result; | 7453 Object* result; |
7757 if (r == 0) { | 7454 if (r == 0) { |
7758 result = equal_prefix_result; | 7455 result = equal_prefix_result; |
7759 } else { | 7456 } else { |
7760 result = (r < 0) ? Smi::FromInt(LESS) : Smi::FromInt(GREATER); | 7457 result = (r < 0) ? Smi::FromInt(LESS) : Smi::FromInt(GREATER); |
7761 } | 7458 } |
7762 return result; | 7459 return result; |
7763 } | 7460 } |
7764 | 7461 |
7765 | 7462 |
7766 #define RUNTIME_UNARY_MATH(Name, name) \ | 7463 #define RUNTIME_UNARY_MATH(Name, name) \ |
7767 RUNTIME_FUNCTION(Runtime_Math##Name) { \ | 7464 RUNTIME_FUNCTION(Runtime_Math##Name) { \ |
7768 HandleScope scope(isolate); \ | 7465 HandleScope scope(isolate); \ |
7769 DCHECK(args.length() == 1); \ | 7466 DCHECK(args.length() == 1); \ |
7770 isolate->counters()->math_##name()->Increment(); \ | 7467 isolate->counters()->math_##name()->Increment(); \ |
7771 CONVERT_DOUBLE_ARG_CHECKED(x, 0); \ | 7468 CONVERT_DOUBLE_ARG_CHECKED(x, 0); \ |
7772 return *isolate->factory()->NewHeapNumber(std::name(x)); \ | 7469 return *isolate->factory()->NewHeapNumber(std::name(x)); \ |
7773 } | 7470 } |
7774 | 7471 |
7775 RUNTIME_UNARY_MATH(Acos, acos) | 7472 RUNTIME_UNARY_MATH(Acos, acos) |
7776 RUNTIME_UNARY_MATH(Asin, asin) | 7473 RUNTIME_UNARY_MATH(Asin, asin) |
7777 RUNTIME_UNARY_MATH(Atan, atan) | 7474 RUNTIME_UNARY_MATH(Atan, atan) |
7778 RUNTIME_UNARY_MATH(LogRT, log) | 7475 RUNTIME_UNARY_MATH(LogRT, log) |
7779 #undef RUNTIME_UNARY_MATH | 7476 #undef RUNTIME_UNARY_MATH |
7780 | 7477 |
7781 | 7478 |
7782 RUNTIME_FUNCTION(Runtime_DoubleHi) { | 7479 RUNTIME_FUNCTION(Runtime_DoubleHi) { |
7783 HandleScope scope(isolate); | 7480 HandleScope scope(isolate); |
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7993 RUNTIME_FUNCTION(Runtime_DateSetValue) { | 7690 RUNTIME_FUNCTION(Runtime_DateSetValue) { |
7994 HandleScope scope(isolate); | 7691 HandleScope scope(isolate); |
7995 DCHECK(args.length() == 3); | 7692 DCHECK(args.length() == 3); |
7996 | 7693 |
7997 CONVERT_ARG_HANDLE_CHECKED(JSDate, date, 0); | 7694 CONVERT_ARG_HANDLE_CHECKED(JSDate, date, 0); |
7998 CONVERT_DOUBLE_ARG_CHECKED(time, 1); | 7695 CONVERT_DOUBLE_ARG_CHECKED(time, 1); |
7999 CONVERT_SMI_ARG_CHECKED(is_utc, 2); | 7696 CONVERT_SMI_ARG_CHECKED(is_utc, 2); |
8000 | 7697 |
8001 DateCache* date_cache = isolate->date_cache(); | 7698 DateCache* date_cache = isolate->date_cache(); |
8002 | 7699 |
8003 Handle<Object> value;; | 7700 Handle<Object> value; |
| 7701 ; |
8004 bool is_value_nan = false; | 7702 bool is_value_nan = false; |
8005 if (std::isnan(time)) { | 7703 if (std::isnan(time)) { |
8006 value = isolate->factory()->nan_value(); | 7704 value = isolate->factory()->nan_value(); |
8007 is_value_nan = true; | 7705 is_value_nan = true; |
8008 } else if (!is_utc && | 7706 } else if (!is_utc && (time < -DateCache::kMaxTimeBeforeUTCInMs || |
8009 (time < -DateCache::kMaxTimeBeforeUTCInMs || | 7707 time > DateCache::kMaxTimeBeforeUTCInMs)) { |
8010 time > DateCache::kMaxTimeBeforeUTCInMs)) { | |
8011 value = isolate->factory()->nan_value(); | 7708 value = isolate->factory()->nan_value(); |
8012 is_value_nan = true; | 7709 is_value_nan = true; |
8013 } else { | 7710 } else { |
8014 time = is_utc ? time : date_cache->ToUTC(static_cast<int64_t>(time)); | 7711 time = is_utc ? time : date_cache->ToUTC(static_cast<int64_t>(time)); |
8015 if (time < -DateCache::kMaxTimeInMs || | 7712 if (time < -DateCache::kMaxTimeInMs || time > DateCache::kMaxTimeInMs) { |
8016 time > DateCache::kMaxTimeInMs) { | |
8017 value = isolate->factory()->nan_value(); | 7713 value = isolate->factory()->nan_value(); |
8018 is_value_nan = true; | 7714 is_value_nan = true; |
8019 } else { | 7715 } else { |
8020 value = isolate->factory()->NewNumber(DoubleToInteger(time)); | 7716 value = isolate->factory()->NewNumber(DoubleToInteger(time)); |
8021 } | 7717 } |
8022 } | 7718 } |
8023 date->SetValue(*value, is_value_nan); | 7719 date->SetValue(*value, is_value_nan); |
8024 return *value; | 7720 return *value; |
8025 } | 7721 } |
8026 | 7722 |
8027 | 7723 |
8028 static Handle<JSObject> NewSloppyArguments(Isolate* isolate, | 7724 static Handle<JSObject> NewSloppyArguments(Isolate* isolate, |
8029 Handle<JSFunction> callee, | 7725 Handle<JSFunction> callee, |
8030 Object** parameters, | 7726 Object** parameters, |
8031 int argument_count) { | 7727 int argument_count) { |
8032 Handle<JSObject> result = | 7728 Handle<JSObject> result = |
8033 isolate->factory()->NewArgumentsObject(callee, argument_count); | 7729 isolate->factory()->NewArgumentsObject(callee, argument_count); |
8034 | 7730 |
8035 // Allocate the elements if needed. | 7731 // Allocate the elements if needed. |
8036 int parameter_count = callee->shared()->formal_parameter_count(); | 7732 int parameter_count = callee->shared()->formal_parameter_count(); |
8037 if (argument_count > 0) { | 7733 if (argument_count > 0) { |
8038 if (parameter_count > 0) { | 7734 if (parameter_count > 0) { |
8039 int mapped_count = Min(argument_count, parameter_count); | 7735 int mapped_count = Min(argument_count, parameter_count); |
8040 Handle<FixedArray> parameter_map = | 7736 Handle<FixedArray> parameter_map = |
8041 isolate->factory()->NewFixedArray(mapped_count + 2, NOT_TENURED); | 7737 isolate->factory()->NewFixedArray(mapped_count + 2, NOT_TENURED); |
8042 parameter_map->set_map( | 7738 parameter_map->set_map(isolate->heap()->sloppy_arguments_elements_map()); |
8043 isolate->heap()->sloppy_arguments_elements_map()); | |
8044 | 7739 |
8045 Handle<Map> map = Map::Copy(handle(result->map())); | 7740 Handle<Map> map = Map::Copy(handle(result->map())); |
8046 map->set_elements_kind(SLOPPY_ARGUMENTS_ELEMENTS); | 7741 map->set_elements_kind(SLOPPY_ARGUMENTS_ELEMENTS); |
8047 | 7742 |
8048 result->set_map(*map); | 7743 result->set_map(*map); |
8049 result->set_elements(*parameter_map); | 7744 result->set_elements(*parameter_map); |
8050 | 7745 |
8051 // Store the context and the arguments array at the beginning of the | 7746 // Store the context and the arguments array at the beginning of the |
8052 // parameter map. | 7747 // parameter map. |
8053 Handle<Context> context(isolate->context()); | 7748 Handle<Context> context(isolate->context()); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8088 // arguments array. | 7783 // arguments array. |
8089 int context_index = -1; | 7784 int context_index = -1; |
8090 for (int j = 0; j < context_local_count; ++j) { | 7785 for (int j = 0; j < context_local_count; ++j) { |
8091 if (scope_info->ContextLocalName(j) == *name) { | 7786 if (scope_info->ContextLocalName(j) == *name) { |
8092 context_index = j; | 7787 context_index = j; |
8093 break; | 7788 break; |
8094 } | 7789 } |
8095 } | 7790 } |
8096 DCHECK(context_index >= 0); | 7791 DCHECK(context_index >= 0); |
8097 arguments->set_the_hole(index); | 7792 arguments->set_the_hole(index); |
8098 parameter_map->set(index + 2, Smi::FromInt( | 7793 parameter_map->set( |
8099 Context::MIN_CONTEXT_SLOTS + context_index)); | 7794 index + 2, |
| 7795 Smi::FromInt(Context::MIN_CONTEXT_SLOTS + context_index)); |
8100 } | 7796 } |
8101 | 7797 |
8102 --index; | 7798 --index; |
8103 } | 7799 } |
8104 } else { | 7800 } else { |
8105 // If there is no aliasing, the arguments object elements are not | 7801 // If there is no aliasing, the arguments object elements are not |
8106 // special in any way. | 7802 // special in any way. |
8107 Handle<FixedArray> elements = | 7803 Handle<FixedArray> elements = |
8108 isolate->factory()->NewFixedArray(argument_count, NOT_TENURED); | 7804 isolate->factory()->NewFixedArray(argument_count, NOT_TENURED); |
8109 result->set_elements(*elements); | 7805 result->set_elements(*elements); |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8190 RUNTIME_FUNCTION(Runtime_NewClosure) { | 7886 RUNTIME_FUNCTION(Runtime_NewClosure) { |
8191 HandleScope scope(isolate); | 7887 HandleScope scope(isolate); |
8192 DCHECK(args.length() == 3); | 7888 DCHECK(args.length() == 3); |
8193 CONVERT_ARG_HANDLE_CHECKED(Context, context, 0); | 7889 CONVERT_ARG_HANDLE_CHECKED(Context, context, 0); |
8194 CONVERT_ARG_HANDLE_CHECKED(SharedFunctionInfo, shared, 1); | 7890 CONVERT_ARG_HANDLE_CHECKED(SharedFunctionInfo, shared, 1); |
8195 CONVERT_BOOLEAN_ARG_CHECKED(pretenure, 2); | 7891 CONVERT_BOOLEAN_ARG_CHECKED(pretenure, 2); |
8196 | 7892 |
8197 // The caller ensures that we pretenure closures that are assigned | 7893 // The caller ensures that we pretenure closures that are assigned |
8198 // directly to properties. | 7894 // directly to properties. |
8199 PretenureFlag pretenure_flag = pretenure ? TENURED : NOT_TENURED; | 7895 PretenureFlag pretenure_flag = pretenure ? TENURED : NOT_TENURED; |
8200 return *isolate->factory()->NewFunctionFromSharedFunctionInfo( | 7896 return *isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, context, |
8201 shared, context, pretenure_flag); | 7897 pretenure_flag); |
8202 } | 7898 } |
8203 | 7899 |
8204 | 7900 |
8205 // Find the arguments of the JavaScript function invocation that called | 7901 // Find the arguments of the JavaScript function invocation that called |
8206 // into C++ code. Collect these in a newly allocated array of handles (possibly | 7902 // into C++ code. Collect these in a newly allocated array of handles (possibly |
8207 // prefixed by a number of empty handles). | 7903 // prefixed by a number of empty handles). |
8208 static SmartArrayPointer<Handle<Object> > GetCallerArguments( | 7904 static SmartArrayPointer<Handle<Object> > GetCallerArguments(Isolate* isolate, |
8209 Isolate* isolate, | 7905 int prefix_argc, |
8210 int prefix_argc, | 7906 int* total_argc) { |
8211 int* total_argc) { | |
8212 // Find frame containing arguments passed to the caller. | 7907 // Find frame containing arguments passed to the caller. |
8213 JavaScriptFrameIterator it(isolate); | 7908 JavaScriptFrameIterator it(isolate); |
8214 JavaScriptFrame* frame = it.frame(); | 7909 JavaScriptFrame* frame = it.frame(); |
8215 List<JSFunction*> functions(2); | 7910 List<JSFunction*> functions(2); |
8216 frame->GetFunctions(&functions); | 7911 frame->GetFunctions(&functions); |
8217 if (functions.length() > 1) { | 7912 if (functions.length() > 1) { |
8218 int inlined_jsframe_index = functions.length() - 1; | 7913 int inlined_jsframe_index = functions.length() - 1; |
8219 JSFunction* inlined_function = functions[inlined_jsframe_index]; | 7914 JSFunction* inlined_function = functions[inlined_jsframe_index]; |
8220 SlotRefValueBuilder slot_refs( | 7915 SlotRefValueBuilder slot_refs( |
8221 frame, | 7916 frame, inlined_jsframe_index, |
8222 inlined_jsframe_index, | |
8223 inlined_function->shared()->formal_parameter_count()); | 7917 inlined_function->shared()->formal_parameter_count()); |
8224 | 7918 |
8225 int args_count = slot_refs.args_length(); | 7919 int args_count = slot_refs.args_length(); |
8226 | 7920 |
8227 *total_argc = prefix_argc + args_count; | 7921 *total_argc = prefix_argc + args_count; |
8228 SmartArrayPointer<Handle<Object> > param_data( | 7922 SmartArrayPointer<Handle<Object> > param_data( |
8229 NewArray<Handle<Object> >(*total_argc)); | 7923 NewArray<Handle<Object> >(*total_argc)); |
8230 slot_refs.Prepare(isolate); | 7924 slot_refs.Prepare(isolate); |
8231 for (int i = 0; i < args_count; i++) { | 7925 for (int i = 0; i < args_count; i++) { |
8232 Handle<Object> val = slot_refs.GetNext(isolate, 0); | 7926 Handle<Object> val = slot_refs.GetNext(isolate, 0); |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8307 // Update length. Have to remove the prototype first so that map migration | 8001 // Update length. Have to remove the prototype first so that map migration |
8308 // is happy about the number of fields. | 8002 // is happy about the number of fields. |
8309 RUNTIME_ASSERT(bound_function->RemovePrototype()); | 8003 RUNTIME_ASSERT(bound_function->RemovePrototype()); |
8310 Handle<Map> bound_function_map( | 8004 Handle<Map> bound_function_map( |
8311 isolate->native_context()->bound_function_map()); | 8005 isolate->native_context()->bound_function_map()); |
8312 JSObject::MigrateToMap(bound_function, bound_function_map); | 8006 JSObject::MigrateToMap(bound_function, bound_function_map); |
8313 Handle<String> length_string = isolate->factory()->length_string(); | 8007 Handle<String> length_string = isolate->factory()->length_string(); |
8314 PropertyAttributes attr = | 8008 PropertyAttributes attr = |
8315 static_cast<PropertyAttributes>(DONT_DELETE | DONT_ENUM | READ_ONLY); | 8009 static_cast<PropertyAttributes>(DONT_DELETE | DONT_ENUM | READ_ONLY); |
8316 RETURN_FAILURE_ON_EXCEPTION( | 8010 RETURN_FAILURE_ON_EXCEPTION( |
8317 isolate, | 8011 isolate, JSObject::SetOwnPropertyIgnoreAttributes( |
8318 JSObject::SetOwnPropertyIgnoreAttributes( | 8012 bound_function, length_string, new_length, attr)); |
8319 bound_function, length_string, new_length, attr)); | |
8320 return *bound_function; | 8013 return *bound_function; |
8321 } | 8014 } |
8322 | 8015 |
8323 | 8016 |
8324 RUNTIME_FUNCTION(Runtime_BoundFunctionGetBindings) { | 8017 RUNTIME_FUNCTION(Runtime_BoundFunctionGetBindings) { |
8325 HandleScope handles(isolate); | 8018 HandleScope handles(isolate); |
8326 DCHECK(args.length() == 1); | 8019 DCHECK(args.length() == 1); |
8327 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, callable, 0); | 8020 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, callable, 0); |
8328 if (callable->IsJSFunction()) { | 8021 if (callable->IsJSFunction()) { |
8329 Handle<JSFunction> function = Handle<JSFunction>::cast(callable); | 8022 Handle<JSFunction> function = Handle<JSFunction>::cast(callable); |
(...skipping 22 matching lines...) Expand all Loading... |
8352 Handle<Object> bound_function( | 8045 Handle<Object> bound_function( |
8353 JSReceiver::cast(bound_args->get(JSFunction::kBoundFunctionIndex)), | 8046 JSReceiver::cast(bound_args->get(JSFunction::kBoundFunctionIndex)), |
8354 isolate); | 8047 isolate); |
8355 DCHECK(!bound_function->IsJSFunction() || | 8048 DCHECK(!bound_function->IsJSFunction() || |
8356 !Handle<JSFunction>::cast(bound_function)->shared()->bound()); | 8049 !Handle<JSFunction>::cast(bound_function)->shared()->bound()); |
8357 | 8050 |
8358 int total_argc = 0; | 8051 int total_argc = 0; |
8359 SmartArrayPointer<Handle<Object> > param_data = | 8052 SmartArrayPointer<Handle<Object> > param_data = |
8360 GetCallerArguments(isolate, bound_argc, &total_argc); | 8053 GetCallerArguments(isolate, bound_argc, &total_argc); |
8361 for (int i = 0; i < bound_argc; i++) { | 8054 for (int i = 0; i < bound_argc; i++) { |
8362 param_data[i] = Handle<Object>(bound_args->get( | 8055 param_data[i] = Handle<Object>( |
8363 JSFunction::kBoundArgumentsStartIndex + i), isolate); | 8056 bound_args->get(JSFunction::kBoundArgumentsStartIndex + i), isolate); |
8364 } | 8057 } |
8365 | 8058 |
8366 if (!bound_function->IsJSFunction()) { | 8059 if (!bound_function->IsJSFunction()) { |
8367 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 8060 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
8368 isolate, bound_function, | 8061 isolate, bound_function, |
8369 Execution::TryGetConstructorDelegate(isolate, bound_function)); | 8062 Execution::TryGetConstructorDelegate(isolate, bound_function)); |
8370 } | 8063 } |
8371 DCHECK(bound_function->IsJSFunction()); | 8064 DCHECK(bound_function->IsJSFunction()); |
8372 | 8065 |
8373 Handle<Object> result; | 8066 Handle<Object> result; |
8374 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 8067 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
8375 isolate, result, | 8068 isolate, result, Execution::New(Handle<JSFunction>::cast(bound_function), |
8376 Execution::New(Handle<JSFunction>::cast(bound_function), | 8069 total_argc, param_data.get())); |
8377 total_argc, param_data.get())); | |
8378 return *result; | 8070 return *result; |
8379 } | 8071 } |
8380 | 8072 |
8381 | 8073 |
8382 static Object* Runtime_NewObjectHelper(Isolate* isolate, | 8074 static Object* Runtime_NewObjectHelper(Isolate* isolate, |
8383 Handle<Object> constructor, | 8075 Handle<Object> constructor, |
8384 Handle<AllocationSite> site) { | 8076 Handle<AllocationSite> site) { |
8385 // If the constructor isn't a proper function we throw a type error. | 8077 // If the constructor isn't a proper function we throw a type error. |
8386 if (!constructor->IsJSFunction()) { | 8078 if (!constructor->IsJSFunction()) { |
8387 Vector< Handle<Object> > arguments = HandleVector(&constructor, 1); | 8079 Vector<Handle<Object> > arguments = HandleVector(&constructor, 1); |
8388 THROW_NEW_ERROR_RETURN_FAILURE(isolate, | 8080 THROW_NEW_ERROR_RETURN_FAILURE(isolate, |
8389 NewTypeError("not_constructor", arguments)); | 8081 NewTypeError("not_constructor", arguments)); |
8390 } | 8082 } |
8391 | 8083 |
8392 Handle<JSFunction> function = Handle<JSFunction>::cast(constructor); | 8084 Handle<JSFunction> function = Handle<JSFunction>::cast(constructor); |
8393 | 8085 |
8394 // If function should not have prototype, construction is not allowed. In this | 8086 // If function should not have prototype, construction is not allowed. In this |
8395 // case generated code bailouts here, since function has no initial_map. | 8087 // case generated code bailouts here, since function has no initial_map. |
8396 if (!function->should_have_prototype() && !function->shared()->bound()) { | 8088 if (!function->should_have_prototype() && !function->shared()->bound()) { |
8397 Vector< Handle<Object> > arguments = HandleVector(&constructor, 1); | 8089 Vector<Handle<Object> > arguments = HandleVector(&constructor, 1); |
8398 THROW_NEW_ERROR_RETURN_FAILURE(isolate, | 8090 THROW_NEW_ERROR_RETURN_FAILURE(isolate, |
8399 NewTypeError("not_constructor", arguments)); | 8091 NewTypeError("not_constructor", arguments)); |
8400 } | 8092 } |
8401 | 8093 |
8402 Debug* debug = isolate->debug(); | 8094 Debug* debug = isolate->debug(); |
8403 // Handle stepping into constructors if step into is active. | 8095 // Handle stepping into constructors if step into is active. |
8404 if (debug->StepInActive()) { | 8096 if (debug->StepInActive()) { |
8405 debug->HandleStepIn(function, Handle<Object>::null(), 0, true); | 8097 debug->HandleStepIn(function, Handle<Object>::null(), 0, true); |
8406 } | 8098 } |
8407 | 8099 |
(...skipping 29 matching lines...) Expand all Loading... |
8437 isolate->counters()->constructed_objects_runtime()->Increment(); | 8129 isolate->counters()->constructed_objects_runtime()->Increment(); |
8438 | 8130 |
8439 return *result; | 8131 return *result; |
8440 } | 8132 } |
8441 | 8133 |
8442 | 8134 |
8443 RUNTIME_FUNCTION(Runtime_NewObject) { | 8135 RUNTIME_FUNCTION(Runtime_NewObject) { |
8444 HandleScope scope(isolate); | 8136 HandleScope scope(isolate); |
8445 DCHECK(args.length() == 1); | 8137 DCHECK(args.length() == 1); |
8446 CONVERT_ARG_HANDLE_CHECKED(Object, constructor, 0); | 8138 CONVERT_ARG_HANDLE_CHECKED(Object, constructor, 0); |
8447 return Runtime_NewObjectHelper(isolate, | 8139 return Runtime_NewObjectHelper(isolate, constructor, |
8448 constructor, | |
8449 Handle<AllocationSite>::null()); | 8140 Handle<AllocationSite>::null()); |
8450 } | 8141 } |
8451 | 8142 |
8452 | 8143 |
8453 RUNTIME_FUNCTION(Runtime_NewObjectWithAllocationSite) { | 8144 RUNTIME_FUNCTION(Runtime_NewObjectWithAllocationSite) { |
8454 HandleScope scope(isolate); | 8145 HandleScope scope(isolate); |
8455 DCHECK(args.length() == 2); | 8146 DCHECK(args.length() == 2); |
8456 CONVERT_ARG_HANDLE_CHECKED(Object, constructor, 1); | 8147 CONVERT_ARG_HANDLE_CHECKED(Object, constructor, 1); |
8457 CONVERT_ARG_HANDLE_CHECKED(Object, feedback, 0); | 8148 CONVERT_ARG_HANDLE_CHECKED(Object, feedback, 0); |
8458 Handle<AllocationSite> site; | 8149 Handle<AllocationSite> site; |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8509 Handle<Code> unoptimized(function->shared()->code()); | 8200 Handle<Code> unoptimized(function->shared()->code()); |
8510 if (!isolate->use_crankshaft() || | 8201 if (!isolate->use_crankshaft() || |
8511 function->shared()->optimization_disabled() || | 8202 function->shared()->optimization_disabled() || |
8512 isolate->DebuggerHasBreakPoints()) { | 8203 isolate->DebuggerHasBreakPoints()) { |
8513 // If the function is not optimizable or debugger is active continue | 8204 // If the function is not optimizable or debugger is active continue |
8514 // using the code from the full compiler. | 8205 // using the code from the full compiler. |
8515 if (FLAG_trace_opt) { | 8206 if (FLAG_trace_opt) { |
8516 PrintF("[failed to optimize "); | 8207 PrintF("[failed to optimize "); |
8517 function->PrintName(); | 8208 function->PrintName(); |
8518 PrintF(": is code optimizable: %s, is debugger enabled: %s]\n", | 8209 PrintF(": is code optimizable: %s, is debugger enabled: %s]\n", |
8519 function->shared()->optimization_disabled() ? "F" : "T", | 8210 function->shared()->optimization_disabled() ? "F" : "T", |
8520 isolate->DebuggerHasBreakPoints() ? "T" : "F"); | 8211 isolate->DebuggerHasBreakPoints() ? "T" : "F"); |
8521 } | 8212 } |
8522 function->ReplaceCode(*unoptimized); | 8213 function->ReplaceCode(*unoptimized); |
8523 return function->code(); | 8214 return function->code(); |
8524 } | 8215 } |
8525 | 8216 |
8526 Compiler::ConcurrencyMode mode = | 8217 Compiler::ConcurrencyMode mode = |
8527 concurrent ? Compiler::CONCURRENT : Compiler::NOT_CONCURRENT; | 8218 concurrent ? Compiler::CONCURRENT : Compiler::NOT_CONCURRENT; |
8528 Handle<Code> code; | 8219 Handle<Code> code; |
8529 if (Compiler::GetOptimizedCode(function, unoptimized, mode).ToHandle(&code)) { | 8220 if (Compiler::GetOptimizedCode(function, unoptimized, mode).ToHandle(&code)) { |
8530 function->ReplaceCode(*code); | 8221 function->ReplaceCode(*code); |
8531 } else { | 8222 } else { |
8532 function->ReplaceCode(function->shared()->code()); | 8223 function->ReplaceCode(function->shared()->code()); |
8533 } | 8224 } |
8534 | 8225 |
8535 DCHECK(function->code()->kind() == Code::FUNCTION || | 8226 DCHECK(function->code()->kind() == Code::FUNCTION || |
8536 function->code()->kind() == Code::OPTIMIZED_FUNCTION || | 8227 function->code()->kind() == Code::OPTIMIZED_FUNCTION || |
8537 function->IsInOptimizationQueue()); | 8228 function->IsInOptimizationQueue()); |
8538 return function->code(); | 8229 return function->code(); |
8539 } | 8230 } |
8540 | 8231 |
8541 | 8232 |
8542 class ActivationsFinder : public ThreadVisitor { | 8233 class ActivationsFinder : public ThreadVisitor { |
8543 public: | 8234 public: |
8544 Code* code_; | 8235 Code* code_; |
8545 bool has_code_activations_; | 8236 bool has_code_activations_; |
8546 | 8237 |
8547 explicit ActivationsFinder(Code* code) | 8238 explicit ActivationsFinder(Code* code) |
8548 : code_(code), | 8239 : code_(code), has_code_activations_(false) {} |
8549 has_code_activations_(false) { } | |
8550 | 8240 |
8551 void VisitThread(Isolate* isolate, ThreadLocalTop* top) { | 8241 void VisitThread(Isolate* isolate, ThreadLocalTop* top) { |
8552 JavaScriptFrameIterator it(isolate, top); | 8242 JavaScriptFrameIterator it(isolate, top); |
8553 VisitFrames(&it); | 8243 VisitFrames(&it); |
8554 } | 8244 } |
8555 | 8245 |
8556 void VisitFrames(JavaScriptFrameIterator* it) { | 8246 void VisitFrames(JavaScriptFrameIterator* it) { |
8557 for (; !it->done(); it->Advance()) { | 8247 for (; !it->done(); it->Advance()) { |
8558 JavaScriptFrame* frame = it->frame(); | 8248 JavaScriptFrame* frame = it->frame(); |
8559 if (code_->contains(frame->pc())) has_code_activations_ = true; | 8249 if (code_->contains(frame->pc())) has_code_activations_ = true; |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8690 RUNTIME_ASSERT(function->shared()->allows_lazy_compilation() || | 8380 RUNTIME_ASSERT(function->shared()->allows_lazy_compilation() || |
8691 (function->code()->kind() == Code::FUNCTION && | 8381 (function->code()->kind() == Code::FUNCTION && |
8692 function->code()->optimizable())); | 8382 function->code()->optimizable())); |
8693 | 8383 |
8694 // If the function is optimized, just return. | 8384 // If the function is optimized, just return. |
8695 if (function->IsOptimized()) return isolate->heap()->undefined_value(); | 8385 if (function->IsOptimized()) return isolate->heap()->undefined_value(); |
8696 | 8386 |
8697 function->MarkForOptimization(); | 8387 function->MarkForOptimization(); |
8698 | 8388 |
8699 Code* unoptimized = function->shared()->code(); | 8389 Code* unoptimized = function->shared()->code(); |
8700 if (args.length() == 2 && | 8390 if (args.length() == 2 && unoptimized->kind() == Code::FUNCTION) { |
8701 unoptimized->kind() == Code::FUNCTION) { | |
8702 CONVERT_ARG_HANDLE_CHECKED(String, type, 1); | 8391 CONVERT_ARG_HANDLE_CHECKED(String, type, 1); |
8703 if (type->IsOneByteEqualTo(STATIC_CHAR_VECTOR("osr")) && FLAG_use_osr) { | 8392 if (type->IsOneByteEqualTo(STATIC_CHAR_VECTOR("osr")) && FLAG_use_osr) { |
8704 // Start patching from the currently patched loop nesting level. | 8393 // Start patching from the currently patched loop nesting level. |
8705 DCHECK(BackEdgeTable::Verify(isolate, unoptimized)); | 8394 DCHECK(BackEdgeTable::Verify(isolate, unoptimized)); |
8706 isolate->runtime_profiler()->AttemptOnStackReplacement( | 8395 isolate->runtime_profiler()->AttemptOnStackReplacement( |
8707 *function, Code::kMaxLoopNestingMarker); | 8396 *function, Code::kMaxLoopNestingMarker); |
8708 } else if (type->IsOneByteEqualTo(STATIC_CHAR_VECTOR("concurrent")) && | 8397 } else if (type->IsOneByteEqualTo(STATIC_CHAR_VECTOR("concurrent")) && |
8709 isolate->concurrent_recompilation_enabled()) { | 8398 isolate->concurrent_recompilation_enabled()) { |
8710 function->MarkForConcurrentOptimization(); | 8399 function->MarkForConcurrentOptimization(); |
8711 } | 8400 } |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8812 // Passing the PC in the javascript frame from the caller directly is | 8501 // Passing the PC in the javascript frame from the caller directly is |
8813 // not GC safe, so we walk the stack to get it. | 8502 // not GC safe, so we walk the stack to get it. |
8814 JavaScriptFrameIterator it(isolate); | 8503 JavaScriptFrameIterator it(isolate); |
8815 JavaScriptFrame* frame = it.frame(); | 8504 JavaScriptFrame* frame = it.frame(); |
8816 if (!caller_code->contains(frame->pc())) { | 8505 if (!caller_code->contains(frame->pc())) { |
8817 // Code on the stack may not be the code object referenced by the shared | 8506 // Code on the stack may not be the code object referenced by the shared |
8818 // function info. It may have been replaced to include deoptimization data. | 8507 // function info. It may have been replaced to include deoptimization data. |
8819 caller_code = Handle<Code>(frame->LookupCode()); | 8508 caller_code = Handle<Code>(frame->LookupCode()); |
8820 } | 8509 } |
8821 | 8510 |
8822 uint32_t pc_offset = static_cast<uint32_t>( | 8511 uint32_t pc_offset = |
8823 frame->pc() - caller_code->instruction_start()); | 8512 static_cast<uint32_t>(frame->pc() - caller_code->instruction_start()); |
8824 | 8513 |
8825 #ifdef DEBUG | 8514 #ifdef DEBUG |
8826 DCHECK_EQ(frame->function(), *function); | 8515 DCHECK_EQ(frame->function(), *function); |
8827 DCHECK_EQ(frame->LookupCode(), *caller_code); | 8516 DCHECK_EQ(frame->LookupCode(), *caller_code); |
8828 DCHECK(caller_code->contains(frame->pc())); | 8517 DCHECK(caller_code->contains(frame->pc())); |
8829 #endif // DEBUG | 8518 #endif // DEBUG |
8830 | 8519 |
8831 | 8520 |
8832 BailoutId ast_id = caller_code->TranslatePcOffsetToAstId(pc_offset); | 8521 BailoutId ast_id = caller_code->TranslatePcOffsetToAstId(pc_offset); |
8833 DCHECK(!ast_id.IsNone()); | 8522 DCHECK(!ast_id.IsNone()); |
8834 | 8523 |
8835 Compiler::ConcurrencyMode mode = | 8524 Compiler::ConcurrencyMode mode = |
8836 isolate->concurrent_osr_enabled() && | 8525 isolate->concurrent_osr_enabled() && |
8837 (function->shared()->ast_node_count() > 512) ? Compiler::CONCURRENT | 8526 (function->shared()->ast_node_count() > 512) |
8838 : Compiler::NOT_CONCURRENT; | 8527 ? Compiler::CONCURRENT |
| 8528 : Compiler::NOT_CONCURRENT; |
8839 Handle<Code> result = Handle<Code>::null(); | 8529 Handle<Code> result = Handle<Code>::null(); |
8840 | 8530 |
8841 OptimizedCompileJob* job = NULL; | 8531 OptimizedCompileJob* job = NULL; |
8842 if (mode == Compiler::CONCURRENT) { | 8532 if (mode == Compiler::CONCURRENT) { |
8843 // Gate the OSR entry with a stack check. | 8533 // Gate the OSR entry with a stack check. |
8844 BackEdgeTable::AddStackCheck(caller_code, pc_offset); | 8534 BackEdgeTable::AddStackCheck(caller_code, pc_offset); |
8845 // Poll already queued compilation jobs. | 8535 // Poll already queued compilation jobs. |
8846 OptimizingCompilerThread* thread = isolate->optimizing_compiler_thread(); | 8536 OptimizingCompilerThread* thread = isolate->optimizing_compiler_thread(); |
8847 if (thread->IsQueuedForOSR(function, ast_id)) { | 8537 if (thread->IsQueuedForOSR(function, ast_id)) { |
8848 if (FLAG_trace_osr) { | 8538 if (FLAG_trace_osr) { |
(...skipping 13 matching lines...) Expand all Loading... |
8862 function->PrintName(); | 8552 function->PrintName(); |
8863 PrintF(" at AST id %d]\n", ast_id.ToInt()); | 8553 PrintF(" at AST id %d]\n", ast_id.ToInt()); |
8864 } | 8554 } |
8865 result = Compiler::GetConcurrentlyOptimizedCode(job); | 8555 result = Compiler::GetConcurrentlyOptimizedCode(job); |
8866 } else if (IsSuitableForOnStackReplacement(isolate, function, caller_code)) { | 8556 } else if (IsSuitableForOnStackReplacement(isolate, function, caller_code)) { |
8867 if (FLAG_trace_osr) { | 8557 if (FLAG_trace_osr) { |
8868 PrintF("[OSR - Compiling: "); | 8558 PrintF("[OSR - Compiling: "); |
8869 function->PrintName(); | 8559 function->PrintName(); |
8870 PrintF(" at AST id %d]\n", ast_id.ToInt()); | 8560 PrintF(" at AST id %d]\n", ast_id.ToInt()); |
8871 } | 8561 } |
8872 MaybeHandle<Code> maybe_result = Compiler::GetOptimizedCode( | 8562 MaybeHandle<Code> maybe_result = |
8873 function, caller_code, mode, ast_id); | 8563 Compiler::GetOptimizedCode(function, caller_code, mode, ast_id); |
8874 if (maybe_result.ToHandle(&result) && | 8564 if (maybe_result.ToHandle(&result) && |
8875 result.is_identical_to(isolate->builtins()->InOptimizationQueue())) { | 8565 result.is_identical_to(isolate->builtins()->InOptimizationQueue())) { |
8876 // Optimization is queued. Return to check later. | 8566 // Optimization is queued. Return to check later. |
8877 return NULL; | 8567 return NULL; |
8878 } | 8568 } |
8879 } | 8569 } |
8880 | 8570 |
8881 // Revert the patched back edge table, regardless of whether OSR succeeds. | 8571 // Revert the patched back edge table, regardless of whether OSR succeeds. |
8882 BackEdgeTable::Revert(isolate, *caller_code); | 8572 BackEdgeTable::Revert(isolate, *caller_code); |
8883 | 8573 |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8966 Handle<Object> argv_small_buffer[argv_small_size]; | 8656 Handle<Object> argv_small_buffer[argv_small_size]; |
8967 SmartArrayPointer<Handle<Object> > argv_large_buffer; | 8657 SmartArrayPointer<Handle<Object> > argv_large_buffer; |
8968 Handle<Object>* argv = argv_small_buffer; | 8658 Handle<Object>* argv = argv_small_buffer; |
8969 if (argc > argv_small_size) { | 8659 if (argc > argv_small_size) { |
8970 argv = new Handle<Object>[argc]; | 8660 argv = new Handle<Object>[argc]; |
8971 if (argv == NULL) return isolate->StackOverflow(); | 8661 if (argv == NULL) return isolate->StackOverflow(); |
8972 argv_large_buffer = SmartArrayPointer<Handle<Object> >(argv); | 8662 argv_large_buffer = SmartArrayPointer<Handle<Object> >(argv); |
8973 } | 8663 } |
8974 | 8664 |
8975 for (int i = 0; i < argc; ++i) { | 8665 for (int i = 0; i < argc; ++i) { |
8976 argv[i] = Handle<Object>(args[1 + i], isolate); | 8666 argv[i] = Handle<Object>(args[1 + i], isolate); |
8977 } | 8667 } |
8978 | 8668 |
8979 Handle<JSReceiver> hfun(fun); | 8669 Handle<JSReceiver> hfun(fun); |
8980 Handle<Object> hreceiver(receiver, isolate); | 8670 Handle<Object> hreceiver(receiver, isolate); |
8981 Handle<Object> result; | 8671 Handle<Object> result; |
8982 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 8672 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
8983 isolate, result, | 8673 isolate, result, |
8984 Execution::Call(isolate, hfun, hreceiver, argc, argv, true)); | 8674 Execution::Call(isolate, hfun, hreceiver, argc, argv, true)); |
8985 return *result; | 8675 return *result; |
8986 } | 8676 } |
(...skipping 19 matching lines...) Expand all Loading... |
9006 SmartArrayPointer<Handle<Object> > argv_large_buffer; | 8696 SmartArrayPointer<Handle<Object> > argv_large_buffer; |
9007 Handle<Object>* argv = argv_small_buffer; | 8697 Handle<Object>* argv = argv_small_buffer; |
9008 if (argc > argv_small_size) { | 8698 if (argc > argv_small_size) { |
9009 argv = new Handle<Object>[argc]; | 8699 argv = new Handle<Object>[argc]; |
9010 if (argv == NULL) return isolate->StackOverflow(); | 8700 if (argv == NULL) return isolate->StackOverflow(); |
9011 argv_large_buffer = SmartArrayPointer<Handle<Object> >(argv); | 8701 argv_large_buffer = SmartArrayPointer<Handle<Object> >(argv); |
9012 } | 8702 } |
9013 | 8703 |
9014 for (int i = 0; i < argc; ++i) { | 8704 for (int i = 0; i < argc; ++i) { |
9015 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 8705 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
9016 isolate, argv[i], | 8706 isolate, argv[i], Object::GetElement(isolate, arguments, offset + i)); |
9017 Object::GetElement(isolate, arguments, offset + i)); | |
9018 } | 8707 } |
9019 | 8708 |
9020 Handle<Object> result; | 8709 Handle<Object> result; |
9021 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 8710 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
9022 isolate, result, | 8711 isolate, result, |
9023 Execution::Call(isolate, fun, receiver, argc, argv, true)); | 8712 Execution::Call(isolate, fun, receiver, argc, argv, true)); |
9024 return *result; | 8713 return *result; |
9025 } | 8714 } |
9026 | 8715 |
9027 | 8716 |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9092 if (args[1]->IsSmi()) { | 8781 if (args[1]->IsSmi()) { |
9093 // A smi sentinel indicates a context nested inside global code rather | 8782 // A smi sentinel indicates a context nested inside global code rather |
9094 // than some function. There is a canonical empty function that can be | 8783 // than some function. There is a canonical empty function that can be |
9095 // gotten from the native context. | 8784 // gotten from the native context. |
9096 function = handle(isolate->native_context()->closure()); | 8785 function = handle(isolate->native_context()->closure()); |
9097 } else { | 8786 } else { |
9098 function = args.at<JSFunction>(1); | 8787 function = args.at<JSFunction>(1); |
9099 } | 8788 } |
9100 | 8789 |
9101 Handle<Context> current(isolate->context()); | 8790 Handle<Context> current(isolate->context()); |
9102 Handle<Context> context = isolate->factory()->NewWithContext( | 8791 Handle<Context> context = |
9103 function, current, extension_object); | 8792 isolate->factory()->NewWithContext(function, current, extension_object); |
9104 isolate->set_context(*context); | 8793 isolate->set_context(*context); |
9105 return *context; | 8794 return *context; |
9106 } | 8795 } |
9107 | 8796 |
9108 | 8797 |
9109 RUNTIME_FUNCTION(Runtime_PushCatchContext) { | 8798 RUNTIME_FUNCTION(Runtime_PushCatchContext) { |
9110 HandleScope scope(isolate); | 8799 HandleScope scope(isolate); |
9111 DCHECK(args.length() == 3); | 8800 DCHECK(args.length() == 3); |
9112 CONVERT_ARG_HANDLE_CHECKED(String, name, 0); | 8801 CONVERT_ARG_HANDLE_CHECKED(String, name, 0); |
9113 CONVERT_ARG_HANDLE_CHECKED(Object, thrown_object, 1); | 8802 CONVERT_ARG_HANDLE_CHECKED(Object, thrown_object, 1); |
(...skipping 21 matching lines...) Expand all Loading... |
9135 Handle<JSFunction> function; | 8824 Handle<JSFunction> function; |
9136 if (args[1]->IsSmi()) { | 8825 if (args[1]->IsSmi()) { |
9137 // A smi sentinel indicates a context nested inside global code rather | 8826 // A smi sentinel indicates a context nested inside global code rather |
9138 // than some function. There is a canonical empty function that can be | 8827 // than some function. There is a canonical empty function that can be |
9139 // gotten from the native context. | 8828 // gotten from the native context. |
9140 function = handle(isolate->native_context()->closure()); | 8829 function = handle(isolate->native_context()->closure()); |
9141 } else { | 8830 } else { |
9142 function = args.at<JSFunction>(1); | 8831 function = args.at<JSFunction>(1); |
9143 } | 8832 } |
9144 Handle<Context> current(isolate->context()); | 8833 Handle<Context> current(isolate->context()); |
9145 Handle<Context> context = isolate->factory()->NewBlockContext( | 8834 Handle<Context> context = |
9146 function, current, scope_info); | 8835 isolate->factory()->NewBlockContext(function, current, scope_info); |
9147 isolate->set_context(*context); | 8836 isolate->set_context(*context); |
9148 return *context; | 8837 return *context; |
9149 } | 8838 } |
9150 | 8839 |
9151 | 8840 |
9152 RUNTIME_FUNCTION(Runtime_IsJSModule) { | 8841 RUNTIME_FUNCTION(Runtime_IsJSModule) { |
9153 SealHandleScope shs(isolate); | 8842 SealHandleScope shs(isolate); |
9154 DCHECK(args.length() == 1); | 8843 DCHECK(args.length() == 1); |
9155 CONVERT_ARG_CHECKED(Object, obj, 0); | 8844 CONVERT_ARG_CHECKED(Object, obj, 0); |
9156 return isolate->heap()->ToBoolean(obj->IsJSModule()); | 8845 return isolate->heap()->ToBoolean(obj->IsJSModule()); |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9251 HandleScope scope(isolate); | 8940 HandleScope scope(isolate); |
9252 DCHECK(args.length() == 2); | 8941 DCHECK(args.length() == 2); |
9253 | 8942 |
9254 CONVERT_ARG_HANDLE_CHECKED(Context, context, 0); | 8943 CONVERT_ARG_HANDLE_CHECKED(Context, context, 0); |
9255 CONVERT_ARG_HANDLE_CHECKED(String, name, 1); | 8944 CONVERT_ARG_HANDLE_CHECKED(String, name, 1); |
9256 | 8945 |
9257 int index; | 8946 int index; |
9258 PropertyAttributes attributes; | 8947 PropertyAttributes attributes; |
9259 ContextLookupFlags flags = FOLLOW_CHAINS; | 8948 ContextLookupFlags flags = FOLLOW_CHAINS; |
9260 BindingFlags binding_flags; | 8949 BindingFlags binding_flags; |
9261 Handle<Object> holder = context->Lookup(name, | 8950 Handle<Object> holder = |
9262 flags, | 8951 context->Lookup(name, flags, &index, &attributes, &binding_flags); |
9263 &index, | |
9264 &attributes, | |
9265 &binding_flags); | |
9266 | 8952 |
9267 // If the slot was not found the result is true. | 8953 // If the slot was not found the result is true. |
9268 if (holder.is_null()) { | 8954 if (holder.is_null()) { |
9269 return isolate->heap()->true_value(); | 8955 return isolate->heap()->true_value(); |
9270 } | 8956 } |
9271 | 8957 |
9272 // If the slot was found in a context, it should be DONT_DELETE. | 8958 // If the slot was found in a context, it should be DONT_DELETE. |
9273 if (holder->IsContext()) { | 8959 if (holder->IsContext()) { |
9274 return isolate->heap()->false_value(); | 8960 return isolate->heap()->false_value(); |
9275 } | 8961 } |
9276 | 8962 |
9277 // The slot was found in a JSObject, either a context extension object, | 8963 // The slot was found in a JSObject, either a context extension object, |
9278 // the global object, or the subject of a with. Try to delete it | 8964 // the global object, or the subject of a with. Try to delete it |
9279 // (respecting DONT_DELETE). | 8965 // (respecting DONT_DELETE). |
9280 Handle<JSObject> object = Handle<JSObject>::cast(holder); | 8966 Handle<JSObject> object = Handle<JSObject>::cast(holder); |
9281 Handle<Object> result; | 8967 Handle<Object> result; |
9282 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 8968 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, |
9283 isolate, result, | 8969 JSReceiver::DeleteProperty(object, name)); |
9284 JSReceiver::DeleteProperty(object, name)); | |
9285 return *result; | 8970 return *result; |
9286 } | 8971 } |
9287 | 8972 |
9288 | 8973 |
9289 // A mechanism to return a pair of Object pointers in registers (if possible). | 8974 static Object* ComputeReceiverForNonGlobal(Isolate* isolate, JSObject* holder) { |
9290 // How this is achieved is calling convention-dependent. | |
9291 // All currently supported x86 compiles uses calling conventions that are cdecl | |
9292 // variants where a 64-bit value is returned in two 32-bit registers | |
9293 // (edx:eax on ia32, r1:r0 on ARM). | |
9294 // In AMD-64 calling convention a struct of two pointers is returned in rdx:rax. | |
9295 // In Win64 calling convention, a struct of two pointers is returned in memory, | |
9296 // allocated by the caller, and passed as a pointer in a hidden first parameter. | |
9297 #ifdef V8_HOST_ARCH_64_BIT | |
9298 struct ObjectPair { | |
9299 Object* x; | |
9300 Object* y; | |
9301 }; | |
9302 | |
9303 | |
9304 static inline ObjectPair MakePair(Object* x, Object* y) { | |
9305 ObjectPair result = {x, y}; | |
9306 // Pointers x and y returned in rax and rdx, in AMD-x64-abi. | |
9307 // In Win64 they are assigned to a hidden first argument. | |
9308 return result; | |
9309 } | |
9310 #elif V8_TARGET_ARCH_X64 && V8_TARGET_ARCH_32_BIT | |
9311 // For x32 a 128-bit struct return is done as rax and rdx from the ObjectPair | |
9312 // are used in the full codegen and Crankshaft compiler. An alternative is | |
9313 // using uint64_t and modifying full codegen and Crankshaft compiler. | |
9314 struct ObjectPair { | |
9315 Object* x; | |
9316 uint32_t x_upper; | |
9317 Object* y; | |
9318 uint32_t y_upper; | |
9319 }; | |
9320 | |
9321 | |
9322 static inline ObjectPair MakePair(Object* x, Object* y) { | |
9323 ObjectPair result = {x, 0, y, 0}; | |
9324 // Pointers x and y returned in rax and rdx, in x32-abi. | |
9325 return result; | |
9326 } | |
9327 #else | |
9328 typedef uint64_t ObjectPair; | |
9329 static inline ObjectPair MakePair(Object* x, Object* y) { | |
9330 #if defined(V8_TARGET_LITTLE_ENDIAN) | |
9331 return reinterpret_cast<uint32_t>(x) | | |
9332 (reinterpret_cast<ObjectPair>(y) << 32); | |
9333 #elif defined(V8_TARGET_BIG_ENDIAN) | |
9334 return reinterpret_cast<uint32_t>(y) | | |
9335 (reinterpret_cast<ObjectPair>(x) << 32); | |
9336 #else | |
9337 #error Unknown endianness | |
9338 #endif | |
9339 } | |
9340 #endif | |
9341 | |
9342 | |
9343 static Object* ComputeReceiverForNonGlobal(Isolate* isolate, | |
9344 JSObject* holder) { | |
9345 DCHECK(!holder->IsGlobalObject()); | 8975 DCHECK(!holder->IsGlobalObject()); |
9346 Context* top = isolate->context(); | 8976 Context* top = isolate->context(); |
9347 // Get the context extension function. | 8977 // Get the context extension function. |
9348 JSFunction* context_extension_function = | 8978 JSFunction* context_extension_function = |
9349 top->native_context()->context_extension_function(); | 8979 top->native_context()->context_extension_function(); |
9350 // If the holder isn't a context extension object, we just return it | 8980 // If the holder isn't a context extension object, we just return it |
9351 // as the receiver. This allows arguments objects to be used as | 8981 // as the receiver. This allows arguments objects to be used as |
9352 // receivers, but only if they are put in the context scope chain | 8982 // receivers, but only if they are put in the context scope chain |
9353 // explicitly via a with-statement. | 8983 // explicitly via a with-statement. |
9354 Object* constructor = holder->map()->constructor(); | 8984 Object* constructor = holder->map()->constructor(); |
(...skipping 13 matching lines...) Expand all Loading... |
9368 if (!args[0]->IsContext() || !args[1]->IsString()) { | 8998 if (!args[0]->IsContext() || !args[1]->IsString()) { |
9369 return MakePair(isolate->ThrowIllegalOperation(), NULL); | 8999 return MakePair(isolate->ThrowIllegalOperation(), NULL); |
9370 } | 9000 } |
9371 Handle<Context> context = args.at<Context>(0); | 9001 Handle<Context> context = args.at<Context>(0); |
9372 Handle<String> name = args.at<String>(1); | 9002 Handle<String> name = args.at<String>(1); |
9373 | 9003 |
9374 int index; | 9004 int index; |
9375 PropertyAttributes attributes; | 9005 PropertyAttributes attributes; |
9376 ContextLookupFlags flags = FOLLOW_CHAINS; | 9006 ContextLookupFlags flags = FOLLOW_CHAINS; |
9377 BindingFlags binding_flags; | 9007 BindingFlags binding_flags; |
9378 Handle<Object> holder = context->Lookup(name, | 9008 Handle<Object> holder = |
9379 flags, | 9009 context->Lookup(name, flags, &index, &attributes, &binding_flags); |
9380 &index, | |
9381 &attributes, | |
9382 &binding_flags); | |
9383 if (isolate->has_pending_exception()) { | 9010 if (isolate->has_pending_exception()) { |
9384 return MakePair(isolate->heap()->exception(), NULL); | 9011 return MakePair(isolate->heap()->exception(), NULL); |
9385 } | 9012 } |
9386 | 9013 |
9387 // If the index is non-negative, the slot has been found in a context. | 9014 // If the index is non-negative, the slot has been found in a context. |
9388 if (index >= 0) { | 9015 if (index >= 0) { |
9389 DCHECK(holder->IsContext()); | 9016 DCHECK(holder->IsContext()); |
9390 // If the "property" we were looking for is a local variable, the | 9017 // If the "property" we were looking for is a local variable, the |
9391 // receiver is the global object; see ECMA-262, 3rd., 10.1.6 and 10.2.3. | 9018 // receiver is the global object; see ECMA-262, 3rd., 10.1.6 and 10.2.3. |
9392 Handle<Object> receiver = isolate->factory()->undefined_value(); | 9019 Handle<Object> receiver = isolate->factory()->undefined_value(); |
9393 Object* value = Context::cast(*holder)->get(index); | 9020 Object* value = Context::cast(*holder)->get(index); |
9394 // Check for uninitialized bindings. | 9021 // Check for uninitialized bindings. |
9395 switch (binding_flags) { | 9022 switch (binding_flags) { |
9396 case MUTABLE_CHECK_INITIALIZED: | 9023 case MUTABLE_CHECK_INITIALIZED: |
9397 case IMMUTABLE_CHECK_INITIALIZED_HARMONY: | 9024 case IMMUTABLE_CHECK_INITIALIZED_HARMONY: |
9398 if (value->IsTheHole()) { | 9025 if (value->IsTheHole()) { |
9399 Handle<Object> error; | 9026 Handle<Object> error; |
9400 MaybeHandle<Object> maybe_error = | 9027 MaybeHandle<Object> maybe_error = |
9401 isolate->factory()->NewReferenceError("not_defined", | 9028 isolate->factory()->NewReferenceError("not_defined", |
9402 HandleVector(&name, 1)); | 9029 HandleVector(&name, 1)); |
9403 if (maybe_error.ToHandle(&error)) isolate->Throw(*error); | 9030 if (maybe_error.ToHandle(&error)) isolate->Throw(*error); |
9404 return MakePair(isolate->heap()->exception(), NULL); | 9031 return MakePair(isolate->heap()->exception(), NULL); |
9405 } | 9032 } |
9406 // FALLTHROUGH | 9033 // FALLTHROUGH |
9407 case MUTABLE_IS_INITIALIZED: | 9034 case MUTABLE_IS_INITIALIZED: |
9408 case IMMUTABLE_IS_INITIALIZED: | 9035 case IMMUTABLE_IS_INITIALIZED: |
9409 case IMMUTABLE_IS_INITIALIZED_HARMONY: | 9036 case IMMUTABLE_IS_INITIALIZED_HARMONY: |
9410 DCHECK(!value->IsTheHole()); | 9037 DCHECK(!value->IsTheHole()); |
9411 return MakePair(value, *receiver); | 9038 return MakePair(value, *receiver); |
9412 case IMMUTABLE_CHECK_INITIALIZED: | 9039 case IMMUTABLE_CHECK_INITIALIZED: |
9413 if (value->IsTheHole()) { | 9040 if (value->IsTheHole()) { |
9414 DCHECK((attributes & READ_ONLY) != 0); | 9041 DCHECK((attributes & READ_ONLY) != 0); |
9415 value = isolate->heap()->undefined_value(); | 9042 value = isolate->heap()->undefined_value(); |
9416 } | 9043 } |
(...skipping 14 matching lines...) Expand all Loading... |
9431 Maybe<bool> maybe = JSReceiver::HasProperty(object, name); | 9058 Maybe<bool> maybe = JSReceiver::HasProperty(object, name); |
9432 DCHECK(maybe.has_value); | 9059 DCHECK(maybe.has_value); |
9433 DCHECK(maybe.value); | 9060 DCHECK(maybe.value); |
9434 } | 9061 } |
9435 #endif | 9062 #endif |
9436 // GetProperty below can cause GC. | 9063 // GetProperty below can cause GC. |
9437 Handle<Object> receiver_handle( | 9064 Handle<Object> receiver_handle( |
9438 object->IsGlobalObject() | 9065 object->IsGlobalObject() |
9439 ? Object::cast(isolate->heap()->undefined_value()) | 9066 ? Object::cast(isolate->heap()->undefined_value()) |
9440 : object->IsJSProxy() ? static_cast<Object*>(*object) | 9067 : object->IsJSProxy() ? static_cast<Object*>(*object) |
9441 : ComputeReceiverForNonGlobal(isolate, JSObject::cast(*object)), | 9068 : ComputeReceiverForNonGlobal( |
| 9069 isolate, JSObject::cast(*object)), |
9442 isolate); | 9070 isolate); |
9443 | 9071 |
9444 // No need to unhole the value here. This is taken care of by the | 9072 // No need to unhole the value here. This is taken care of by the |
9445 // GetProperty function. | 9073 // GetProperty function. |
9446 Handle<Object> value; | 9074 Handle<Object> value; |
9447 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 9075 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
9448 isolate, value, | 9076 isolate, value, Object::GetProperty(object, name), |
9449 Object::GetProperty(object, name), | |
9450 MakePair(isolate->heap()->exception(), NULL)); | 9077 MakePair(isolate->heap()->exception(), NULL)); |
9451 return MakePair(*value, *receiver_handle); | 9078 return MakePair(*value, *receiver_handle); |
9452 } | 9079 } |
9453 | 9080 |
9454 if (throw_error) { | 9081 if (throw_error) { |
9455 // The property doesn't exist - throw exception. | 9082 // The property doesn't exist - throw exception. |
9456 Handle<Object> error; | 9083 Handle<Object> error; |
9457 MaybeHandle<Object> maybe_error = isolate->factory()->NewReferenceError( | 9084 MaybeHandle<Object> maybe_error = isolate->factory()->NewReferenceError( |
9458 "not_defined", HandleVector(&name, 1)); | 9085 "not_defined", HandleVector(&name, 1)); |
9459 if (maybe_error.ToHandle(&error)) isolate->Throw(*error); | 9086 if (maybe_error.ToHandle(&error)) isolate->Throw(*error); |
(...skipping 22 matching lines...) Expand all Loading... |
9482 | 9109 |
9483 CONVERT_ARG_HANDLE_CHECKED(Object, value, 0); | 9110 CONVERT_ARG_HANDLE_CHECKED(Object, value, 0); |
9484 CONVERT_ARG_HANDLE_CHECKED(Context, context, 1); | 9111 CONVERT_ARG_HANDLE_CHECKED(Context, context, 1); |
9485 CONVERT_ARG_HANDLE_CHECKED(String, name, 2); | 9112 CONVERT_ARG_HANDLE_CHECKED(String, name, 2); |
9486 CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 3); | 9113 CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 3); |
9487 | 9114 |
9488 int index; | 9115 int index; |
9489 PropertyAttributes attributes; | 9116 PropertyAttributes attributes; |
9490 ContextLookupFlags flags = FOLLOW_CHAINS; | 9117 ContextLookupFlags flags = FOLLOW_CHAINS; |
9491 BindingFlags binding_flags; | 9118 BindingFlags binding_flags; |
9492 Handle<Object> holder = context->Lookup(name, | 9119 Handle<Object> holder = |
9493 flags, | 9120 context->Lookup(name, flags, &index, &attributes, &binding_flags); |
9494 &index, | |
9495 &attributes, | |
9496 &binding_flags); | |
9497 // In case of JSProxy, an exception might have been thrown. | 9121 // In case of JSProxy, an exception might have been thrown. |
9498 if (isolate->has_pending_exception()) return isolate->heap()->exception(); | 9122 if (isolate->has_pending_exception()) return isolate->heap()->exception(); |
9499 | 9123 |
9500 // The property was found in a context slot. | 9124 // The property was found in a context slot. |
9501 if (index >= 0) { | 9125 if (index >= 0) { |
9502 if ((attributes & READ_ONLY) == 0) { | 9126 if ((attributes & READ_ONLY) == 0) { |
9503 Handle<Context>::cast(holder)->set(index, *value); | 9127 Handle<Context>::cast(holder)->set(index, *value); |
9504 } else if (strict_mode == STRICT) { | 9128 } else if (strict_mode == STRICT) { |
9505 // Setting read only property in strict mode. | 9129 // Setting read only property in strict mode. |
9506 THROW_NEW_ERROR_RETURN_FAILURE( | 9130 THROW_NEW_ERROR_RETURN_FAILURE( |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9631 | 9255 |
9632 static int StackSize(Isolate* isolate) { | 9256 static int StackSize(Isolate* isolate) { |
9633 int n = 0; | 9257 int n = 0; |
9634 for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) n++; | 9258 for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) n++; |
9635 return n; | 9259 return n; |
9636 } | 9260 } |
9637 | 9261 |
9638 | 9262 |
9639 static void PrintTransition(Isolate* isolate, Object* result) { | 9263 static void PrintTransition(Isolate* isolate, Object* result) { |
9640 // indentation | 9264 // indentation |
9641 { const int nmax = 80; | 9265 { |
| 9266 const int nmax = 80; |
9642 int n = StackSize(isolate); | 9267 int n = StackSize(isolate); |
9643 if (n <= nmax) | 9268 if (n <= nmax) |
9644 PrintF("%4d:%*s", n, n, ""); | 9269 PrintF("%4d:%*s", n, n, ""); |
9645 else | 9270 else |
9646 PrintF("%4d:%*s", n, nmax, "..."); | 9271 PrintF("%4d:%*s", n, nmax, "..."); |
9647 } | 9272 } |
9648 | 9273 |
9649 if (result == NULL) { | 9274 if (result == NULL) { |
9650 JavaScriptFrame::PrintTop(isolate, stdout, true, false); | 9275 JavaScriptFrame::PrintTop(isolate, stdout, true, false); |
9651 PrintF(" {\n"); | 9276 PrintF(" {\n"); |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9745 RUNTIME_ASSERT(output->HasFastObjectElements()); | 9370 RUNTIME_ASSERT(output->HasFastObjectElements()); |
9746 Handle<FixedArray> output_array(FixedArray::cast(output->elements())); | 9371 Handle<FixedArray> output_array(FixedArray::cast(output->elements())); |
9747 RUNTIME_ASSERT(output_array->length() >= DateParser::OUTPUT_SIZE); | 9372 RUNTIME_ASSERT(output_array->length() >= DateParser::OUTPUT_SIZE); |
9748 | 9373 |
9749 str = String::Flatten(str); | 9374 str = String::Flatten(str); |
9750 DisallowHeapAllocation no_gc; | 9375 DisallowHeapAllocation no_gc; |
9751 | 9376 |
9752 bool result; | 9377 bool result; |
9753 String::FlatContent str_content = str->GetFlatContent(); | 9378 String::FlatContent str_content = str->GetFlatContent(); |
9754 if (str_content.IsOneByte()) { | 9379 if (str_content.IsOneByte()) { |
9755 result = DateParser::Parse(str_content.ToOneByteVector(), | 9380 result = DateParser::Parse(str_content.ToOneByteVector(), *output_array, |
9756 *output_array, | |
9757 isolate->unicode_cache()); | 9381 isolate->unicode_cache()); |
9758 } else { | 9382 } else { |
9759 DCHECK(str_content.IsTwoByte()); | 9383 DCHECK(str_content.IsTwoByte()); |
9760 result = DateParser::Parse(str_content.ToUC16Vector(), | 9384 result = DateParser::Parse(str_content.ToUC16Vector(), *output_array, |
9761 *output_array, | |
9762 isolate->unicode_cache()); | 9385 isolate->unicode_cache()); |
9763 } | 9386 } |
9764 | 9387 |
9765 if (result) { | 9388 if (result) { |
9766 return *output; | 9389 return *output; |
9767 } else { | 9390 } else { |
9768 return isolate->heap()->null_value(); | 9391 return isolate->heap()->null_value(); |
9769 } | 9392 } |
9770 } | 9393 } |
9771 | 9394 |
9772 | 9395 |
9773 RUNTIME_FUNCTION(Runtime_DateLocalTimezone) { | 9396 RUNTIME_FUNCTION(Runtime_DateLocalTimezone) { |
9774 HandleScope scope(isolate); | 9397 HandleScope scope(isolate); |
9775 DCHECK(args.length() == 1); | 9398 DCHECK(args.length() == 1); |
9776 | 9399 |
9777 CONVERT_DOUBLE_ARG_CHECKED(x, 0); | 9400 CONVERT_DOUBLE_ARG_CHECKED(x, 0); |
9778 RUNTIME_ASSERT(x >= -DateCache::kMaxTimeBeforeUTCInMs && | 9401 RUNTIME_ASSERT(x >= -DateCache::kMaxTimeBeforeUTCInMs && |
9779 x <= DateCache::kMaxTimeBeforeUTCInMs); | 9402 x <= DateCache::kMaxTimeBeforeUTCInMs); |
9780 const char* zone = | 9403 const char* zone = |
9781 isolate->date_cache()->LocalTimezone(static_cast<int64_t>(x)); | 9404 isolate->date_cache()->LocalTimezone(static_cast<int64_t>(x)); |
9782 Handle<String> result = isolate->factory()->NewStringFromUtf8( | 9405 Handle<String> result = |
9783 CStrVector(zone)).ToHandleChecked(); | 9406 isolate->factory()->NewStringFromUtf8(CStrVector(zone)).ToHandleChecked(); |
9784 return *result; | 9407 return *result; |
9785 } | 9408 } |
9786 | 9409 |
9787 | 9410 |
9788 RUNTIME_FUNCTION(Runtime_DateToUTC) { | 9411 RUNTIME_FUNCTION(Runtime_DateToUTC) { |
9789 HandleScope scope(isolate); | 9412 HandleScope scope(isolate); |
9790 DCHECK(args.length() == 1); | 9413 DCHECK(args.length() == 1); |
9791 | 9414 |
9792 CONVERT_DOUBLE_ARG_CHECKED(x, 0); | 9415 CONVERT_DOUBLE_ARG_CHECKED(x, 0); |
9793 RUNTIME_ASSERT(x >= -DateCache::kMaxTimeBeforeUTCInMs && | 9416 RUNTIME_ASSERT(x >= -DateCache::kMaxTimeBeforeUTCInMs && |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9839 | 9462 |
9840 | 9463 |
9841 RUNTIME_FUNCTION(Runtime_ParseJson) { | 9464 RUNTIME_FUNCTION(Runtime_ParseJson) { |
9842 HandleScope scope(isolate); | 9465 HandleScope scope(isolate); |
9843 DCHECK(args.length() == 1); | 9466 DCHECK(args.length() == 1); |
9844 CONVERT_ARG_HANDLE_CHECKED(String, source, 0); | 9467 CONVERT_ARG_HANDLE_CHECKED(String, source, 0); |
9845 | 9468 |
9846 source = String::Flatten(source); | 9469 source = String::Flatten(source); |
9847 // Optimized fast case where we only have Latin1 characters. | 9470 // Optimized fast case where we only have Latin1 characters. |
9848 Handle<Object> result; | 9471 Handle<Object> result; |
9849 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 9472 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, |
9850 isolate, result, | 9473 source->IsSeqOneByteString() |
9851 source->IsSeqOneByteString() ? JsonParser<true>::Parse(source) | 9474 ? JsonParser<true>::Parse(source) |
9852 : JsonParser<false>::Parse(source)); | 9475 : JsonParser<false>::Parse(source)); |
9853 return *result; | 9476 return *result; |
9854 } | 9477 } |
9855 | 9478 |
9856 | 9479 |
9857 bool CodeGenerationFromStringsAllowed(Isolate* isolate, | 9480 bool CodeGenerationFromStringsAllowed(Isolate* isolate, |
9858 Handle<Context> context) { | 9481 Handle<Context> context) { |
9859 DCHECK(context->allow_code_gen_from_strings()->IsFalse()); | 9482 DCHECK(context->allow_code_gen_from_strings()->IsFalse()); |
9860 // Check with callback if set. | 9483 // Check with callback if set. |
9861 AllowCodeGenerationFromStringsCallback callback = | 9484 AllowCodeGenerationFromStringsCallback callback = |
9862 isolate->allow_code_gen_callback(); | 9485 isolate->allow_code_gen_callback(); |
(...skipping 23 matching lines...) Expand all Loading... |
9886 !CodeGenerationFromStringsAllowed(isolate, context)) { | 9509 !CodeGenerationFromStringsAllowed(isolate, context)) { |
9887 Handle<Object> error_message = | 9510 Handle<Object> error_message = |
9888 context->ErrorMessageForCodeGenerationFromStrings(); | 9511 context->ErrorMessageForCodeGenerationFromStrings(); |
9889 THROW_NEW_ERROR_RETURN_FAILURE( | 9512 THROW_NEW_ERROR_RETURN_FAILURE( |
9890 isolate, NewEvalError("code_gen_from_strings", | 9513 isolate, NewEvalError("code_gen_from_strings", |
9891 HandleVector<Object>(&error_message, 1))); | 9514 HandleVector<Object>(&error_message, 1))); |
9892 } | 9515 } |
9893 | 9516 |
9894 // Compile source string in the native context. | 9517 // Compile source string in the native context. |
9895 ParseRestriction restriction = function_literal_only | 9518 ParseRestriction restriction = function_literal_only |
9896 ? ONLY_SINGLE_FUNCTION_LITERAL : NO_PARSE_RESTRICTION; | 9519 ? ONLY_SINGLE_FUNCTION_LITERAL |
| 9520 : NO_PARSE_RESTRICTION; |
9897 Handle<JSFunction> fun; | 9521 Handle<JSFunction> fun; |
9898 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 9522 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
9899 isolate, fun, | 9523 isolate, fun, |
9900 Compiler::GetFunctionFromEval( | 9524 Compiler::GetFunctionFromEval(source, context, SLOPPY, restriction, |
9901 source, context, SLOPPY, restriction, RelocInfo::kNoPosition)); | 9525 RelocInfo::kNoPosition)); |
9902 return *fun; | 9526 return *fun; |
9903 } | 9527 } |
9904 | 9528 |
9905 | 9529 |
9906 static ObjectPair CompileGlobalEval(Isolate* isolate, | 9530 static ObjectPair CompileGlobalEval(Isolate* isolate, Handle<String> source, |
9907 Handle<String> source, | |
9908 Handle<Object> receiver, | 9531 Handle<Object> receiver, |
9909 StrictMode strict_mode, | 9532 StrictMode strict_mode, |
9910 int scope_position) { | 9533 int scope_position) { |
9911 Handle<Context> context = Handle<Context>(isolate->context()); | 9534 Handle<Context> context = Handle<Context>(isolate->context()); |
9912 Handle<Context> native_context = Handle<Context>(context->native_context()); | 9535 Handle<Context> native_context = Handle<Context>(context->native_context()); |
9913 | 9536 |
9914 // Check if native context allows code generation from | 9537 // Check if native context allows code generation from |
9915 // strings. Throw an exception if it doesn't. | 9538 // strings. Throw an exception if it doesn't. |
9916 if (native_context->allow_code_gen_from_strings()->IsFalse() && | 9539 if (native_context->allow_code_gen_from_strings()->IsFalse() && |
9917 !CodeGenerationFromStringsAllowed(isolate, native_context)) { | 9540 !CodeGenerationFromStringsAllowed(isolate, native_context)) { |
9918 Handle<Object> error_message = | 9541 Handle<Object> error_message = |
9919 native_context->ErrorMessageForCodeGenerationFromStrings(); | 9542 native_context->ErrorMessageForCodeGenerationFromStrings(); |
9920 Handle<Object> error; | 9543 Handle<Object> error; |
9921 MaybeHandle<Object> maybe_error = isolate->factory()->NewEvalError( | 9544 MaybeHandle<Object> maybe_error = isolate->factory()->NewEvalError( |
9922 "code_gen_from_strings", HandleVector<Object>(&error_message, 1)); | 9545 "code_gen_from_strings", HandleVector<Object>(&error_message, 1)); |
9923 if (maybe_error.ToHandle(&error)) isolate->Throw(*error); | 9546 if (maybe_error.ToHandle(&error)) isolate->Throw(*error); |
9924 return MakePair(isolate->heap()->exception(), NULL); | 9547 return MakePair(isolate->heap()->exception(), NULL); |
9925 } | 9548 } |
9926 | 9549 |
9927 // Deal with a normal eval call with a string argument. Compile it | 9550 // Deal with a normal eval call with a string argument. Compile it |
9928 // and return the compiled function bound in the local context. | 9551 // and return the compiled function bound in the local context. |
9929 static const ParseRestriction restriction = NO_PARSE_RESTRICTION; | 9552 static const ParseRestriction restriction = NO_PARSE_RESTRICTION; |
9930 Handle<JSFunction> compiled; | 9553 Handle<JSFunction> compiled; |
9931 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 9554 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
9932 isolate, compiled, | 9555 isolate, compiled, |
9933 Compiler::GetFunctionFromEval( | 9556 Compiler::GetFunctionFromEval(source, context, strict_mode, restriction, |
9934 source, context, strict_mode, restriction, scope_position), | 9557 scope_position), |
9935 MakePair(isolate->heap()->exception(), NULL)); | 9558 MakePair(isolate->heap()->exception(), NULL)); |
9936 return MakePair(*compiled, *receiver); | 9559 return MakePair(*compiled, *receiver); |
9937 } | 9560 } |
9938 | 9561 |
9939 | 9562 |
9940 RUNTIME_FUNCTION_RETURN_PAIR(Runtime_ResolvePossiblyDirectEval) { | 9563 RUNTIME_FUNCTION_RETURN_PAIR(Runtime_ResolvePossiblyDirectEval) { |
9941 HandleScope scope(isolate); | 9564 HandleScope scope(isolate); |
9942 DCHECK(args.length() == 5); | 9565 DCHECK(args.length() == 5); |
9943 | 9566 |
9944 Handle<Object> callee = args.at<Object>(0); | 9567 Handle<Object> callee = args.at<Object>(0); |
9945 | 9568 |
9946 // If "eval" didn't refer to the original GlobalEval, it's not a | 9569 // If "eval" didn't refer to the original GlobalEval, it's not a |
9947 // direct call to eval. | 9570 // direct call to eval. |
9948 // (And even if it is, but the first argument isn't a string, just let | 9571 // (And even if it is, but the first argument isn't a string, just let |
9949 // execution default to an indirect call to eval, which will also return | 9572 // execution default to an indirect call to eval, which will also return |
9950 // the first argument without doing anything). | 9573 // the first argument without doing anything). |
9951 if (*callee != isolate->native_context()->global_eval_fun() || | 9574 if (*callee != isolate->native_context()->global_eval_fun() || |
9952 !args[1]->IsString()) { | 9575 !args[1]->IsString()) { |
9953 return MakePair(*callee, isolate->heap()->undefined_value()); | 9576 return MakePair(*callee, isolate->heap()->undefined_value()); |
9954 } | 9577 } |
9955 | 9578 |
9956 DCHECK(args[3]->IsSmi()); | 9579 DCHECK(args[3]->IsSmi()); |
9957 DCHECK(args.smi_at(3) == SLOPPY || args.smi_at(3) == STRICT); | 9580 DCHECK(args.smi_at(3) == SLOPPY || args.smi_at(3) == STRICT); |
9958 StrictMode strict_mode = static_cast<StrictMode>(args.smi_at(3)); | 9581 StrictMode strict_mode = static_cast<StrictMode>(args.smi_at(3)); |
9959 DCHECK(args[4]->IsSmi()); | 9582 DCHECK(args[4]->IsSmi()); |
9960 return CompileGlobalEval(isolate, | 9583 return CompileGlobalEval(isolate, args.at<String>(1), args.at<Object>(2), |
9961 args.at<String>(1), | 9584 strict_mode, args.smi_at(4)); |
9962 args.at<Object>(2), | |
9963 strict_mode, | |
9964 args.smi_at(4)); | |
9965 } | 9585 } |
9966 | 9586 |
9967 | 9587 |
9968 RUNTIME_FUNCTION(Runtime_AllocateInNewSpace) { | 9588 RUNTIME_FUNCTION(Runtime_AllocateInNewSpace) { |
9969 HandleScope scope(isolate); | 9589 HandleScope scope(isolate); |
9970 DCHECK(args.length() == 1); | 9590 DCHECK(args.length() == 1); |
9971 CONVERT_SMI_ARG_CHECKED(size, 0); | 9591 CONVERT_SMI_ARG_CHECKED(size, 0); |
9972 RUNTIME_ASSERT(IsAligned(size, kPointerSize)); | 9592 RUNTIME_ASSERT(IsAligned(size, kPointerSize)); |
9973 RUNTIME_ASSERT(size > 0); | 9593 RUNTIME_ASSERT(size > 0); |
9974 RUNTIME_ASSERT(size <= Page::kMaxRegularHeapObjectSize); | 9594 RUNTIME_ASSERT(size <= Page::kMaxRegularHeapObjectSize); |
(...skipping 25 matching lines...) Expand all Loading... |
10000 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, element, 1); | 9620 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, element, 1); |
10001 RUNTIME_ASSERT(array->HasFastSmiOrObjectElements()); | 9621 RUNTIME_ASSERT(array->HasFastSmiOrObjectElements()); |
10002 int length = Smi::cast(array->length())->value(); | 9622 int length = Smi::cast(array->length())->value(); |
10003 FixedArray* elements = FixedArray::cast(array->elements()); | 9623 FixedArray* elements = FixedArray::cast(array->elements()); |
10004 for (int i = 0; i < length; i++) { | 9624 for (int i = 0; i < length; i++) { |
10005 if (elements->get(i) == *element) return isolate->heap()->false_value(); | 9625 if (elements->get(i) == *element) return isolate->heap()->false_value(); |
10006 } | 9626 } |
10007 | 9627 |
10008 // Strict not needed. Used for cycle detection in Array join implementation. | 9628 // Strict not needed. Used for cycle detection in Array join implementation. |
10009 RETURN_FAILURE_ON_EXCEPTION( | 9629 RETURN_FAILURE_ON_EXCEPTION( |
10010 isolate, | 9630 isolate, JSObject::SetFastElement(array, length, element, SLOPPY, true)); |
10011 JSObject::SetFastElement(array, length, element, SLOPPY, true)); | |
10012 return isolate->heap()->true_value(); | 9631 return isolate->heap()->true_value(); |
10013 } | 9632 } |
10014 | 9633 |
10015 | 9634 |
10016 /** | 9635 /** |
10017 * A simple visitor visits every element of Array's. | 9636 * A simple visitor visits every element of Array's. |
10018 * The backend storage can be a fixed array for fast elements case, | 9637 * The backend storage can be a fixed array for fast elements case, |
10019 * or a dictionary for sparse array. Since Dictionary is a subtype | 9638 * or a dictionary for sparse array. Since Dictionary is a subtype |
10020 * of FixedArray, the class can be used by both fast and slow cases. | 9639 * of FixedArray, the class can be used by both fast and slow cases. |
10021 * The second parameter of the constructor, fast_elements, specifies | 9640 * The second parameter of the constructor, fast_elements, specifies |
10022 * whether the storage is a FixedArray or Dictionary. | 9641 * whether the storage is a FixedArray or Dictionary. |
10023 * | 9642 * |
10024 * An index limit is used to deal with the situation that a result array | 9643 * An index limit is used to deal with the situation that a result array |
10025 * length overflows 32-bit non-negative integer. | 9644 * length overflows 32-bit non-negative integer. |
10026 */ | 9645 */ |
10027 class ArrayConcatVisitor { | 9646 class ArrayConcatVisitor { |
10028 public: | 9647 public: |
10029 ArrayConcatVisitor(Isolate* isolate, | 9648 ArrayConcatVisitor(Isolate* isolate, Handle<FixedArray> storage, |
10030 Handle<FixedArray> storage, | 9649 bool fast_elements) |
10031 bool fast_elements) : | 9650 : isolate_(isolate), |
10032 isolate_(isolate), | 9651 storage_(Handle<FixedArray>::cast( |
10033 storage_(Handle<FixedArray>::cast( | 9652 isolate->global_handles()->Create(*storage))), |
10034 isolate->global_handles()->Create(*storage))), | 9653 index_offset_(0u), |
10035 index_offset_(0u), | 9654 fast_elements_(fast_elements), |
10036 fast_elements_(fast_elements), | 9655 exceeds_array_limit_(false) {} |
10037 exceeds_array_limit_(false) { } | |
10038 | 9656 |
10039 ~ArrayConcatVisitor() { | 9657 ~ArrayConcatVisitor() { clear_storage(); } |
10040 clear_storage(); | |
10041 } | |
10042 | 9658 |
10043 void visit(uint32_t i, Handle<Object> elm) { | 9659 void visit(uint32_t i, Handle<Object> elm) { |
10044 if (i > JSObject::kMaxElementCount - index_offset_) { | 9660 if (i > JSObject::kMaxElementCount - index_offset_) { |
10045 exceeds_array_limit_ = true; | 9661 exceeds_array_limit_ = true; |
10046 return; | 9662 return; |
10047 } | 9663 } |
10048 uint32_t index = index_offset_ + i; | 9664 uint32_t index = index_offset_ + i; |
10049 | 9665 |
10050 if (fast_elements_) { | 9666 if (fast_elements_) { |
10051 if (index < static_cast<uint32_t>(storage_->length())) { | 9667 if (index < static_cast<uint32_t>(storage_->length())) { |
(...skipping 28 matching lines...) Expand all Loading... |
10080 // If the initial length estimate was off (see special case in visit()), | 9696 // If the initial length estimate was off (see special case in visit()), |
10081 // but the array blowing the limit didn't contain elements beyond the | 9697 // but the array blowing the limit didn't contain elements beyond the |
10082 // provided-for index range, go to dictionary mode now. | 9698 // provided-for index range, go to dictionary mode now. |
10083 if (fast_elements_ && | 9699 if (fast_elements_ && |
10084 index_offset_ > | 9700 index_offset_ > |
10085 static_cast<uint32_t>(FixedArrayBase::cast(*storage_)->length())) { | 9701 static_cast<uint32_t>(FixedArrayBase::cast(*storage_)->length())) { |
10086 SetDictionaryMode(); | 9702 SetDictionaryMode(); |
10087 } | 9703 } |
10088 } | 9704 } |
10089 | 9705 |
10090 bool exceeds_array_limit() { | 9706 bool exceeds_array_limit() { return exceeds_array_limit_; } |
10091 return exceeds_array_limit_; | |
10092 } | |
10093 | 9707 |
10094 Handle<JSArray> ToArray() { | 9708 Handle<JSArray> ToArray() { |
10095 Handle<JSArray> array = isolate_->factory()->NewJSArray(0); | 9709 Handle<JSArray> array = isolate_->factory()->NewJSArray(0); |
10096 Handle<Object> length = | 9710 Handle<Object> length = |
10097 isolate_->factory()->NewNumber(static_cast<double>(index_offset_)); | 9711 isolate_->factory()->NewNumber(static_cast<double>(index_offset_)); |
10098 Handle<Map> map = JSObject::GetElementsTransitionMap( | 9712 Handle<Map> map = JSObject::GetElementsTransitionMap( |
10099 array, | 9713 array, fast_elements_ ? FAST_HOLEY_ELEMENTS : DICTIONARY_ELEMENTS); |
10100 fast_elements_ ? FAST_HOLEY_ELEMENTS : DICTIONARY_ELEMENTS); | |
10101 array->set_map(*map); | 9714 array->set_map(*map); |
10102 array->set_length(*length); | 9715 array->set_length(*length); |
10103 array->set_elements(*storage_); | 9716 array->set_elements(*storage_); |
10104 return array; | 9717 return array; |
10105 } | 9718 } |
10106 | 9719 |
10107 private: | 9720 private: |
10108 // Convert storage to dictionary mode. | 9721 // Convert storage to dictionary mode. |
10109 void SetDictionaryMode() { | 9722 void SetDictionaryMode() { |
10110 DCHECK(fast_elements_); | 9723 DCHECK(fast_elements_); |
(...skipping 15 matching lines...) Expand all Loading... |
10126 clear_storage(); | 9739 clear_storage(); |
10127 set_storage(*slow_storage); | 9740 set_storage(*slow_storage); |
10128 fast_elements_ = false; | 9741 fast_elements_ = false; |
10129 } | 9742 } |
10130 | 9743 |
10131 inline void clear_storage() { | 9744 inline void clear_storage() { |
10132 GlobalHandles::Destroy(Handle<Object>::cast(storage_).location()); | 9745 GlobalHandles::Destroy(Handle<Object>::cast(storage_).location()); |
10133 } | 9746 } |
10134 | 9747 |
10135 inline void set_storage(FixedArray* storage) { | 9748 inline void set_storage(FixedArray* storage) { |
10136 storage_ = Handle<FixedArray>::cast( | 9749 storage_ = |
10137 isolate_->global_handles()->Create(storage)); | 9750 Handle<FixedArray>::cast(isolate_->global_handles()->Create(storage)); |
10138 } | 9751 } |
10139 | 9752 |
10140 Isolate* isolate_; | 9753 Isolate* isolate_; |
10141 Handle<FixedArray> storage_; // Always a global handle. | 9754 Handle<FixedArray> storage_; // Always a global handle. |
10142 // Index after last seen index. Always less than or equal to | 9755 // Index after last seen index. Always less than or equal to |
10143 // JSObject::kMaxElementCount. | 9756 // JSObject::kMaxElementCount. |
10144 uint32_t index_offset_; | 9757 uint32_t index_offset_; |
10145 bool fast_elements_ : 1; | 9758 bool fast_elements_ : 1; |
10146 bool exceeds_array_limit_ : 1; | 9759 bool exceeds_array_limit_ : 1; |
10147 }; | 9760 }; |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10188 int capacity = dictionary->Capacity(); | 9801 int capacity = dictionary->Capacity(); |
10189 for (int i = 0; i < capacity; i++) { | 9802 for (int i = 0; i < capacity; i++) { |
10190 Handle<Object> key(dictionary->KeyAt(i), array->GetIsolate()); | 9803 Handle<Object> key(dictionary->KeyAt(i), array->GetIsolate()); |
10191 if (dictionary->IsKey(*key)) { | 9804 if (dictionary->IsKey(*key)) { |
10192 element_count++; | 9805 element_count++; |
10193 } | 9806 } |
10194 } | 9807 } |
10195 break; | 9808 break; |
10196 } | 9809 } |
10197 case SLOPPY_ARGUMENTS_ELEMENTS: | 9810 case SLOPPY_ARGUMENTS_ELEMENTS: |
10198 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ | 9811 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ |
10199 case EXTERNAL_##TYPE##_ELEMENTS: \ | 9812 case EXTERNAL_##TYPE##_ELEMENTS: \ |
10200 case TYPE##_ELEMENTS: \ | 9813 case TYPE##_ELEMENTS: |
10201 | 9814 |
10202 TYPED_ARRAYS(TYPED_ARRAY_CASE) | 9815 TYPED_ARRAYS(TYPED_ARRAY_CASE) |
10203 #undef TYPED_ARRAY_CASE | 9816 #undef TYPED_ARRAY_CASE |
10204 // External arrays are always dense. | 9817 // External arrays are always dense. |
10205 return length; | 9818 return length; |
10206 } | 9819 } |
10207 // As an estimate, we assume that the prototype doesn't contain any | 9820 // As an estimate, we assume that the prototype doesn't contain any |
10208 // inherited elements. | 9821 // inherited elements. |
10209 return element_count; | 9822 return element_count; |
10210 } | 9823 } |
10211 | 9824 |
10212 | 9825 |
10213 | 9826 template <class ExternalArrayClass, class ElementType> |
10214 template<class ExternalArrayClass, class ElementType> | |
10215 static void IterateExternalArrayElements(Isolate* isolate, | 9827 static void IterateExternalArrayElements(Isolate* isolate, |
10216 Handle<JSObject> receiver, | 9828 Handle<JSObject> receiver, |
10217 bool elements_are_ints, | 9829 bool elements_are_ints, |
10218 bool elements_are_guaranteed_smis, | 9830 bool elements_are_guaranteed_smis, |
10219 ArrayConcatVisitor* visitor) { | 9831 ArrayConcatVisitor* visitor) { |
10220 Handle<ExternalArrayClass> array( | 9832 Handle<ExternalArrayClass> array( |
10221 ExternalArrayClass::cast(receiver->elements())); | 9833 ExternalArrayClass::cast(receiver->elements())); |
10222 uint32_t len = static_cast<uint32_t>(array->length()); | 9834 uint32_t len = static_cast<uint32_t>(array->length()); |
10223 | 9835 |
10224 DCHECK(visitor != NULL); | 9836 DCHECK(visitor != NULL); |
(...skipping 30 matching lines...) Expand all Loading... |
10255 | 9867 |
10256 | 9868 |
10257 // Used for sorting indices in a List<uint32_t>. | 9869 // Used for sorting indices in a List<uint32_t>. |
10258 static int compareUInt32(const uint32_t* ap, const uint32_t* bp) { | 9870 static int compareUInt32(const uint32_t* ap, const uint32_t* bp) { |
10259 uint32_t a = *ap; | 9871 uint32_t a = *ap; |
10260 uint32_t b = *bp; | 9872 uint32_t b = *bp; |
10261 return (a == b) ? 0 : (a < b) ? -1 : 1; | 9873 return (a == b) ? 0 : (a < b) ? -1 : 1; |
10262 } | 9874 } |
10263 | 9875 |
10264 | 9876 |
10265 static void CollectElementIndices(Handle<JSObject> object, | 9877 static void CollectElementIndices(Handle<JSObject> object, uint32_t range, |
10266 uint32_t range, | |
10267 List<uint32_t>* indices) { | 9878 List<uint32_t>* indices) { |
10268 Isolate* isolate = object->GetIsolate(); | 9879 Isolate* isolate = object->GetIsolate(); |
10269 ElementsKind kind = object->GetElementsKind(); | 9880 ElementsKind kind = object->GetElementsKind(); |
10270 switch (kind) { | 9881 switch (kind) { |
10271 case FAST_SMI_ELEMENTS: | 9882 case FAST_SMI_ELEMENTS: |
10272 case FAST_ELEMENTS: | 9883 case FAST_ELEMENTS: |
10273 case FAST_HOLEY_SMI_ELEMENTS: | 9884 case FAST_HOLEY_SMI_ELEMENTS: |
10274 case FAST_HOLEY_ELEMENTS: { | 9885 case FAST_HOLEY_ELEMENTS: { |
10275 Handle<FixedArray> elements(FixedArray::cast(object->elements())); | 9886 Handle<FixedArray> elements(FixedArray::cast(object->elements())); |
10276 uint32_t length = static_cast<uint32_t>(elements->length()); | 9887 uint32_t length = static_cast<uint32_t>(elements->length()); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10310 DCHECK(k->IsNumber()); | 9921 DCHECK(k->IsNumber()); |
10311 uint32_t index = static_cast<uint32_t>(k->Number()); | 9922 uint32_t index = static_cast<uint32_t>(k->Number()); |
10312 if (index < range) { | 9923 if (index < range) { |
10313 indices->Add(index); | 9924 indices->Add(index); |
10314 } | 9925 } |
10315 } | 9926 } |
10316 } | 9927 } |
10317 break; | 9928 break; |
10318 } | 9929 } |
10319 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ | 9930 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ |
10320 case TYPE##_ELEMENTS: \ | 9931 case TYPE##_ELEMENTS: \ |
10321 case EXTERNAL_##TYPE##_ELEMENTS: | 9932 case EXTERNAL_##TYPE##_ELEMENTS: |
10322 | 9933 |
10323 TYPED_ARRAYS(TYPED_ARRAY_CASE) | 9934 TYPED_ARRAYS(TYPED_ARRAY_CASE) |
10324 #undef TYPED_ARRAY_CASE | 9935 #undef TYPED_ARRAY_CASE |
10325 { | 9936 { |
10326 uint32_t length = static_cast<uint32_t>( | 9937 uint32_t length = static_cast<uint32_t>( |
10327 FixedArrayBase::cast(object->elements())->length()); | 9938 FixedArrayBase::cast(object->elements())->length()); |
10328 if (range <= length) { | 9939 if (range <= length) { |
10329 length = range; | 9940 length = range; |
10330 // We will add all indices, so we might as well clear it first | 9941 // We will add all indices, so we might as well clear it first |
10331 // and avoid duplicates. | 9942 // and avoid duplicates. |
10332 indices->Clear(); | 9943 indices->Clear(); |
| 9944 } |
| 9945 for (uint32_t i = 0; i < length; i++) { |
| 9946 indices->Add(i); |
| 9947 } |
| 9948 if (length == range) return; // All indices accounted for already. |
| 9949 break; |
10333 } | 9950 } |
10334 for (uint32_t i = 0; i < length; i++) { | |
10335 indices->Add(i); | |
10336 } | |
10337 if (length == range) return; // All indices accounted for already. | |
10338 break; | |
10339 } | |
10340 case SLOPPY_ARGUMENTS_ELEMENTS: { | 9951 case SLOPPY_ARGUMENTS_ELEMENTS: { |
10341 MaybeHandle<Object> length_obj = | 9952 MaybeHandle<Object> length_obj = |
10342 Object::GetProperty(object, isolate->factory()->length_string()); | 9953 Object::GetProperty(object, isolate->factory()->length_string()); |
10343 double length_num = length_obj.ToHandleChecked()->Number(); | 9954 double length_num = length_obj.ToHandleChecked()->Number(); |
10344 uint32_t length = static_cast<uint32_t>(DoubleToInt32(length_num)); | 9955 uint32_t length = static_cast<uint32_t>(DoubleToInt32(length_num)); |
10345 ElementsAccessor* accessor = object->GetElementsAccessor(); | 9956 ElementsAccessor* accessor = object->GetElementsAccessor(); |
10346 for (uint32_t i = 0; i < length; i++) { | 9957 for (uint32_t i = 0; i < length; i++) { |
10347 if (accessor->HasElement(object, object, i)) { | 9958 if (accessor->HasElement(object, object, i)) { |
10348 indices->Add(i); | 9959 indices->Add(i); |
10349 } | 9960 } |
(...skipping 16 matching lines...) Expand all Loading... |
10366 /** | 9977 /** |
10367 * A helper function that visits elements of a JSArray in numerical | 9978 * A helper function that visits elements of a JSArray in numerical |
10368 * order. | 9979 * order. |
10369 * | 9980 * |
10370 * The visitor argument called for each existing element in the array | 9981 * The visitor argument called for each existing element in the array |
10371 * with the element index and the element's value. | 9982 * with the element index and the element's value. |
10372 * Afterwards it increments the base-index of the visitor by the array | 9983 * Afterwards it increments the base-index of the visitor by the array |
10373 * length. | 9984 * length. |
10374 * Returns false if any access threw an exception, otherwise true. | 9985 * Returns false if any access threw an exception, otherwise true. |
10375 */ | 9986 */ |
10376 static bool IterateElements(Isolate* isolate, | 9987 static bool IterateElements(Isolate* isolate, Handle<JSArray> receiver, |
10377 Handle<JSArray> receiver, | |
10378 ArrayConcatVisitor* visitor) { | 9988 ArrayConcatVisitor* visitor) { |
10379 uint32_t length = static_cast<uint32_t>(receiver->length()->Number()); | 9989 uint32_t length = static_cast<uint32_t>(receiver->length()->Number()); |
10380 switch (receiver->GetElementsKind()) { | 9990 switch (receiver->GetElementsKind()) { |
10381 case FAST_SMI_ELEMENTS: | 9991 case FAST_SMI_ELEMENTS: |
10382 case FAST_ELEMENTS: | 9992 case FAST_ELEMENTS: |
10383 case FAST_HOLEY_SMI_ELEMENTS: | 9993 case FAST_HOLEY_SMI_ELEMENTS: |
10384 case FAST_HOLEY_ELEMENTS: { | 9994 case FAST_HOLEY_ELEMENTS: { |
10385 // Run through the elements FixedArray and use HasElement and GetElement | 9995 // Run through the elements FixedArray and use HasElement and GetElement |
10386 // to check the prototype for missing elements. | 9996 // to check the prototype for missing elements. |
10387 Handle<FixedArray> elements(FixedArray::cast(receiver->elements())); | 9997 Handle<FixedArray> elements(FixedArray::cast(receiver->elements())); |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10451 // than length. This might introduce duplicates in the indices list. | 10061 // than length. This might introduce duplicates in the indices list. |
10452 CollectElementIndices(receiver, length, &indices); | 10062 CollectElementIndices(receiver, length, &indices); |
10453 indices.Sort(&compareUInt32); | 10063 indices.Sort(&compareUInt32); |
10454 int j = 0; | 10064 int j = 0; |
10455 int n = indices.length(); | 10065 int n = indices.length(); |
10456 while (j < n) { | 10066 while (j < n) { |
10457 HandleScope loop_scope(isolate); | 10067 HandleScope loop_scope(isolate); |
10458 uint32_t index = indices[j]; | 10068 uint32_t index = indices[j]; |
10459 Handle<Object> element; | 10069 Handle<Object> element; |
10460 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 10070 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
10461 isolate, element, | 10071 isolate, element, Object::GetElement(isolate, receiver, index), |
10462 Object::GetElement(isolate, receiver, index), | |
10463 false); | 10072 false); |
10464 visitor->visit(index, element); | 10073 visitor->visit(index, element); |
10465 // Skip to next different index (i.e., omit duplicates). | 10074 // Skip to next different index (i.e., omit duplicates). |
10466 do { | 10075 do { |
10467 j++; | 10076 j++; |
10468 } while (j < n && indices[j] == index); | 10077 } while (j < n && indices[j] == index); |
10469 } | 10078 } |
10470 break; | 10079 break; |
10471 } | 10080 } |
10472 case EXTERNAL_UINT8_CLAMPED_ELEMENTS: { | 10081 case EXTERNAL_UINT8_CLAMPED_ELEMENTS: { |
10473 Handle<ExternalUint8ClampedArray> pixels(ExternalUint8ClampedArray::cast( | 10082 Handle<ExternalUint8ClampedArray> pixels( |
10474 receiver->elements())); | 10083 ExternalUint8ClampedArray::cast(receiver->elements())); |
10475 for (uint32_t j = 0; j < length; j++) { | 10084 for (uint32_t j = 0; j < length; j++) { |
10476 Handle<Smi> e(Smi::FromInt(pixels->get_scalar(j)), isolate); | 10085 Handle<Smi> e(Smi::FromInt(pixels->get_scalar(j)), isolate); |
10477 visitor->visit(j, e); | 10086 visitor->visit(j, e); |
10478 } | 10087 } |
10479 break; | 10088 break; |
10480 } | 10089 } |
10481 case EXTERNAL_INT8_ELEMENTS: { | 10090 case EXTERNAL_INT8_ELEMENTS: { |
10482 IterateExternalArrayElements<ExternalInt8Array, int8_t>( | 10091 IterateExternalArrayElements<ExternalInt8Array, int8_t>( |
10483 isolate, receiver, true, true, visitor); | 10092 isolate, receiver, true, true, visitor); |
10484 break; | 10093 break; |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10574 kind = FAST_DOUBLE_ELEMENTS; | 10183 kind = FAST_DOUBLE_ELEMENTS; |
10575 } | 10184 } |
10576 } else if (IsMoreGeneralElementsKindTransition(kind, FAST_ELEMENTS)) { | 10185 } else if (IsMoreGeneralElementsKindTransition(kind, FAST_ELEMENTS)) { |
10577 kind = FAST_ELEMENTS; | 10186 kind = FAST_ELEMENTS; |
10578 } | 10187 } |
10579 } | 10188 } |
10580 length_estimate = 1; | 10189 length_estimate = 1; |
10581 element_estimate = 1; | 10190 element_estimate = 1; |
10582 } | 10191 } |
10583 // Avoid overflows by capping at kMaxElementCount. | 10192 // Avoid overflows by capping at kMaxElementCount. |
10584 if (JSObject::kMaxElementCount - estimate_result_length < | 10193 if (JSObject::kMaxElementCount - estimate_result_length < length_estimate) { |
10585 length_estimate) { | |
10586 estimate_result_length = JSObject::kMaxElementCount; | 10194 estimate_result_length = JSObject::kMaxElementCount; |
10587 } else { | 10195 } else { |
10588 estimate_result_length += length_estimate; | 10196 estimate_result_length += length_estimate; |
10589 } | 10197 } |
10590 if (JSObject::kMaxElementCount - estimate_nof_elements < | 10198 if (JSObject::kMaxElementCount - estimate_nof_elements < element_estimate) { |
10591 element_estimate) { | |
10592 estimate_nof_elements = JSObject::kMaxElementCount; | 10199 estimate_nof_elements = JSObject::kMaxElementCount; |
10593 } else { | 10200 } else { |
10594 estimate_nof_elements += element_estimate; | 10201 estimate_nof_elements += element_estimate; |
10595 } | 10202 } |
10596 } | 10203 } |
10597 | 10204 |
10598 // If estimated number of elements is more than half of length, a | 10205 // If estimated number of elements is more than half of length, a |
10599 // fixed array (fast case) is more time and space-efficient than a | 10206 // fixed array (fast case) is more time and space-efficient than a |
10600 // dictionary. | 10207 // dictionary. |
10601 bool fast_case = (estimate_nof_elements * 2) >= estimate_result_length; | 10208 bool fast_case = (estimate_nof_elements * 2) >= estimate_result_length; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10637 break; | 10244 break; |
10638 } | 10245 } |
10639 double double_value = elements->get_scalar(i); | 10246 double double_value = elements->get_scalar(i); |
10640 double_storage->set(j, double_value); | 10247 double_storage->set(j, double_value); |
10641 j++; | 10248 j++; |
10642 } | 10249 } |
10643 break; | 10250 break; |
10644 } | 10251 } |
10645 case FAST_HOLEY_SMI_ELEMENTS: | 10252 case FAST_HOLEY_SMI_ELEMENTS: |
10646 case FAST_SMI_ELEMENTS: { | 10253 case FAST_SMI_ELEMENTS: { |
10647 FixedArray* elements( | 10254 FixedArray* elements(FixedArray::cast(array->elements())); |
10648 FixedArray::cast(array->elements())); | |
10649 for (uint32_t i = 0; i < length; i++) { | 10255 for (uint32_t i = 0; i < length; i++) { |
10650 Object* element = elements->get(i); | 10256 Object* element = elements->get(i); |
10651 if (element->IsTheHole()) { | 10257 if (element->IsTheHole()) { |
10652 failure = true; | 10258 failure = true; |
10653 break; | 10259 break; |
10654 } | 10260 } |
10655 int32_t int_value = Smi::cast(element)->value(); | 10261 int32_t int_value = Smi::cast(element)->value(); |
10656 double_storage->set(j, int_value); | 10262 double_storage->set(j, int_value); |
10657 j++; | 10263 j++; |
10658 } | 10264 } |
(...skipping 20 matching lines...) Expand all Loading... |
10679 array->set_elements(*storage); | 10285 array->set_elements(*storage); |
10680 return *array; | 10286 return *array; |
10681 } | 10287 } |
10682 // In case of failure, fall through. | 10288 // In case of failure, fall through. |
10683 } | 10289 } |
10684 | 10290 |
10685 Handle<FixedArray> storage; | 10291 Handle<FixedArray> storage; |
10686 if (fast_case) { | 10292 if (fast_case) { |
10687 // The backing storage array must have non-existing elements to preserve | 10293 // The backing storage array must have non-existing elements to preserve |
10688 // holes across concat operations. | 10294 // holes across concat operations. |
10689 storage = isolate->factory()->NewFixedArrayWithHoles( | 10295 storage = |
10690 estimate_result_length); | 10296 isolate->factory()->NewFixedArrayWithHoles(estimate_result_length); |
10691 } else { | 10297 } else { |
10692 // TODO(126): move 25% pre-allocation logic into Dictionary::Allocate | 10298 // TODO(126): move 25% pre-allocation logic into Dictionary::Allocate |
10693 uint32_t at_least_space_for = estimate_nof_elements + | 10299 uint32_t at_least_space_for = |
10694 (estimate_nof_elements >> 2); | 10300 estimate_nof_elements + (estimate_nof_elements >> 2); |
10695 storage = Handle<FixedArray>::cast( | 10301 storage = Handle<FixedArray>::cast( |
10696 SeededNumberDictionary::New(isolate, at_least_space_for)); | 10302 SeededNumberDictionary::New(isolate, at_least_space_for)); |
10697 } | 10303 } |
10698 | 10304 |
10699 ArrayConcatVisitor visitor(isolate, storage, fast_case); | 10305 ArrayConcatVisitor visitor(isolate, storage, fast_case); |
10700 | 10306 |
10701 for (int i = 0; i < argument_count; i++) { | 10307 for (int i = 0; i < argument_count; i++) { |
10702 Handle<Object> obj(elements->get(i), isolate); | 10308 Handle<Object> obj(elements->get(i), isolate); |
10703 if (obj->IsJSArray()) { | 10309 if (obj->IsJSArray()) { |
10704 Handle<JSArray> array = Handle<JSArray>::cast(obj); | 10310 Handle<JSArray> array = Handle<JSArray>::cast(obj); |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10896 } | 10502 } |
10897 | 10503 |
10898 | 10504 |
10899 // Adds a JavaScript function as a debug event listener. | 10505 // Adds a JavaScript function as a debug event listener. |
10900 // args[0]: debug event listener function to set or null or undefined for | 10506 // args[0]: debug event listener function to set or null or undefined for |
10901 // clearing the event listener function | 10507 // clearing the event listener function |
10902 // args[1]: object supplied during callback | 10508 // args[1]: object supplied during callback |
10903 RUNTIME_FUNCTION(Runtime_SetDebugEventListener) { | 10509 RUNTIME_FUNCTION(Runtime_SetDebugEventListener) { |
10904 SealHandleScope shs(isolate); | 10510 SealHandleScope shs(isolate); |
10905 DCHECK(args.length() == 2); | 10511 DCHECK(args.length() == 2); |
10906 RUNTIME_ASSERT(args[0]->IsJSFunction() || | 10512 RUNTIME_ASSERT(args[0]->IsJSFunction() || args[0]->IsUndefined() || |
10907 args[0]->IsUndefined() || | |
10908 args[0]->IsNull()); | 10513 args[0]->IsNull()); |
10909 CONVERT_ARG_HANDLE_CHECKED(Object, callback, 0); | 10514 CONVERT_ARG_HANDLE_CHECKED(Object, callback, 0); |
10910 CONVERT_ARG_HANDLE_CHECKED(Object, data, 1); | 10515 CONVERT_ARG_HANDLE_CHECKED(Object, data, 1); |
10911 isolate->debug()->SetEventListener(callback, data); | 10516 isolate->debug()->SetEventListener(callback, data); |
10912 | 10517 |
10913 return isolate->heap()->undefined_value(); | 10518 return isolate->heap()->undefined_value(); |
10914 } | 10519 } |
10915 | 10520 |
10916 | 10521 |
10917 RUNTIME_FUNCTION(Runtime_Break) { | 10522 RUNTIME_FUNCTION(Runtime_Break) { |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10990 // Check if the name is trivially convertible to an index and get the element | 10595 // Check if the name is trivially convertible to an index and get the element |
10991 // if so. | 10596 // if so. |
10992 uint32_t index; | 10597 uint32_t index; |
10993 if (name->AsArrayIndex(&index)) { | 10598 if (name->AsArrayIndex(&index)) { |
10994 Handle<FixedArray> details = isolate->factory()->NewFixedArray(2); | 10599 Handle<FixedArray> details = isolate->factory()->NewFixedArray(2); |
10995 Handle<Object> element_or_char; | 10600 Handle<Object> element_or_char; |
10996 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 10601 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
10997 isolate, element_or_char, | 10602 isolate, element_or_char, |
10998 Runtime::GetElementOrCharAt(isolate, obj, index)); | 10603 Runtime::GetElementOrCharAt(isolate, obj, index)); |
10999 details->set(0, *element_or_char); | 10604 details->set(0, *element_or_char); |
11000 details->set( | 10605 details->set(1, |
11001 1, PropertyDetails(NONE, NORMAL, Representation::None()).AsSmi()); | 10606 PropertyDetails(NONE, NORMAL, Representation::None()).AsSmi()); |
11002 return *isolate->factory()->NewJSArrayWithElements(details); | 10607 return *isolate->factory()->NewJSArrayWithElements(details); |
11003 } | 10608 } |
11004 | 10609 |
11005 LookupIterator it(obj, name, LookupIterator::HIDDEN); | 10610 LookupIterator it(obj, name, LookupIterator::HIDDEN); |
11006 bool has_caught = false; | 10611 bool has_caught = false; |
11007 Handle<Object> value = DebugGetProperty(&it, &has_caught); | 10612 Handle<Object> value = DebugGetProperty(&it, &has_caught); |
11008 if (!it.IsFound()) return isolate->heap()->undefined_value(); | 10613 if (!it.IsFound()) return isolate->heap()->undefined_value(); |
11009 | 10614 |
11010 Handle<Object> maybe_pair; | 10615 Handle<Object> maybe_pair; |
11011 if (it.state() == LookupIterator::ACCESSOR) { | 10616 if (it.state() == LookupIterator::ACCESSOR) { |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11084 // args[0]: object | 10689 // args[0]: object |
11085 // args[1]: property name | 10690 // args[1]: property name |
11086 RUNTIME_FUNCTION(Runtime_DebugNamedInterceptorPropertyValue) { | 10691 RUNTIME_FUNCTION(Runtime_DebugNamedInterceptorPropertyValue) { |
11087 HandleScope scope(isolate); | 10692 HandleScope scope(isolate); |
11088 DCHECK(args.length() == 2); | 10693 DCHECK(args.length() == 2); |
11089 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); | 10694 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); |
11090 RUNTIME_ASSERT(obj->HasNamedInterceptor()); | 10695 RUNTIME_ASSERT(obj->HasNamedInterceptor()); |
11091 CONVERT_ARG_HANDLE_CHECKED(Name, name, 1); | 10696 CONVERT_ARG_HANDLE_CHECKED(Name, name, 1); |
11092 | 10697 |
11093 Handle<Object> result; | 10698 Handle<Object> result; |
11094 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 10699 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, |
11095 isolate, result, JSObject::GetProperty(obj, name)); | 10700 JSObject::GetProperty(obj, name)); |
11096 return *result; | 10701 return *result; |
11097 } | 10702 } |
11098 | 10703 |
11099 | 10704 |
11100 // Return element value from indexed interceptor. | 10705 // Return element value from indexed interceptor. |
11101 // args[0]: object | 10706 // args[0]: object |
11102 // args[1]: index | 10707 // args[1]: index |
11103 RUNTIME_FUNCTION(Runtime_DebugIndexedInterceptorElementValue) { | 10708 RUNTIME_FUNCTION(Runtime_DebugIndexedInterceptorElementValue) { |
11104 HandleScope scope(isolate); | 10709 HandleScope scope(isolate); |
11105 DCHECK(args.length() == 2); | 10710 DCHECK(args.length() == 2); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11150 // Omit functions from native scripts. | 10755 // Omit functions from native scripts. |
11151 if (!frames[i].function()->IsFromNativeScript()) n++; | 10756 if (!frames[i].function()->IsFromNativeScript()) n++; |
11152 } | 10757 } |
11153 } | 10758 } |
11154 return Smi::FromInt(n); | 10759 return Smi::FromInt(n); |
11155 } | 10760 } |
11156 | 10761 |
11157 | 10762 |
11158 class FrameInspector { | 10763 class FrameInspector { |
11159 public: | 10764 public: |
11160 FrameInspector(JavaScriptFrame* frame, | 10765 FrameInspector(JavaScriptFrame* frame, int inlined_jsframe_index, |
11161 int inlined_jsframe_index, | |
11162 Isolate* isolate) | 10766 Isolate* isolate) |
11163 : frame_(frame), deoptimized_frame_(NULL), isolate_(isolate) { | 10767 : frame_(frame), deoptimized_frame_(NULL), isolate_(isolate) { |
11164 // Calculate the deoptimized frame. | 10768 // Calculate the deoptimized frame. |
11165 if (frame->is_optimized()) { | 10769 if (frame->is_optimized()) { |
11166 deoptimized_frame_ = Deoptimizer::DebuggerInspectableFrame( | 10770 deoptimized_frame_ = Deoptimizer::DebuggerInspectableFrame( |
11167 frame, inlined_jsframe_index, isolate); | 10771 frame, inlined_jsframe_index, isolate); |
11168 } | 10772 } |
11169 has_adapted_arguments_ = frame_->has_adapted_arguments(); | 10773 has_adapted_arguments_ = frame_->has_adapted_arguments(); |
11170 is_bottommost_ = inlined_jsframe_index == 0; | 10774 is_bottommost_ = inlined_jsframe_index == 0; |
11171 is_optimized_ = frame_->is_optimized(); | 10775 is_optimized_ = frame_->is_optimized(); |
11172 } | 10776 } |
11173 | 10777 |
11174 ~FrameInspector() { | 10778 ~FrameInspector() { |
11175 // Get rid of the calculated deoptimized frame if any. | 10779 // Get rid of the calculated deoptimized frame if any. |
11176 if (deoptimized_frame_ != NULL) { | 10780 if (deoptimized_frame_ != NULL) { |
11177 Deoptimizer::DeleteDebuggerInspectableFrame(deoptimized_frame_, | 10781 Deoptimizer::DeleteDebuggerInspectableFrame(deoptimized_frame_, isolate_); |
11178 isolate_); | |
11179 } | 10782 } |
11180 } | 10783 } |
11181 | 10784 |
11182 int GetParametersCount() { | 10785 int GetParametersCount() { |
11183 return is_optimized_ | 10786 return is_optimized_ ? deoptimized_frame_->parameters_count() |
11184 ? deoptimized_frame_->parameters_count() | 10787 : frame_->ComputeParametersCount(); |
11185 : frame_->ComputeParametersCount(); | |
11186 } | 10788 } |
11187 int expression_count() { return deoptimized_frame_->expression_count(); } | 10789 int expression_count() { return deoptimized_frame_->expression_count(); } |
11188 Object* GetFunction() { | 10790 Object* GetFunction() { |
11189 return is_optimized_ | 10791 return is_optimized_ ? deoptimized_frame_->GetFunction() |
11190 ? deoptimized_frame_->GetFunction() | 10792 : frame_->function(); |
11191 : frame_->function(); | |
11192 } | 10793 } |
11193 Object* GetParameter(int index) { | 10794 Object* GetParameter(int index) { |
11194 return is_optimized_ | 10795 return is_optimized_ ? deoptimized_frame_->GetParameter(index) |
11195 ? deoptimized_frame_->GetParameter(index) | 10796 : frame_->GetParameter(index); |
11196 : frame_->GetParameter(index); | |
11197 } | 10797 } |
11198 Object* GetExpression(int index) { | 10798 Object* GetExpression(int index) { |
11199 return is_optimized_ | 10799 return is_optimized_ ? deoptimized_frame_->GetExpression(index) |
11200 ? deoptimized_frame_->GetExpression(index) | 10800 : frame_->GetExpression(index); |
11201 : frame_->GetExpression(index); | |
11202 } | 10801 } |
11203 int GetSourcePosition() { | 10802 int GetSourcePosition() { |
11204 return is_optimized_ | 10803 return is_optimized_ ? deoptimized_frame_->GetSourcePosition() |
11205 ? deoptimized_frame_->GetSourcePosition() | 10804 : frame_->LookupCode()->SourcePosition(frame_->pc()); |
11206 : frame_->LookupCode()->SourcePosition(frame_->pc()); | |
11207 } | 10805 } |
11208 bool IsConstructor() { | 10806 bool IsConstructor() { |
11209 return is_optimized_ && !is_bottommost_ | 10807 return is_optimized_ && !is_bottommost_ |
11210 ? deoptimized_frame_->HasConstructStub() | 10808 ? deoptimized_frame_->HasConstructStub() |
11211 : frame_->IsConstructor(); | 10809 : frame_->IsConstructor(); |
11212 } | 10810 } |
11213 Object* GetContext() { | 10811 Object* GetContext() { |
11214 return is_optimized_ ? deoptimized_frame_->GetContext() : frame_->context(); | 10812 return is_optimized_ ? deoptimized_frame_->GetContext() : frame_->context(); |
11215 } | 10813 } |
11216 | 10814 |
11217 // To inspect all the provided arguments the frame might need to be | 10815 // To inspect all the provided arguments the frame might need to be |
11218 // replaced with the arguments frame. | 10816 // replaced with the arguments frame. |
11219 void SetArgumentsFrame(JavaScriptFrame* frame) { | 10817 void SetArgumentsFrame(JavaScriptFrame* frame) { |
11220 DCHECK(has_adapted_arguments_); | 10818 DCHECK(has_adapted_arguments_); |
11221 frame_ = frame; | 10819 frame_ = frame; |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11333 Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction())); | 10931 Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction())); |
11334 Handle<SharedFunctionInfo> shared(function->shared()); | 10932 Handle<SharedFunctionInfo> shared(function->shared()); |
11335 Handle<ScopeInfo> scope_info(shared->scope_info()); | 10933 Handle<ScopeInfo> scope_info(shared->scope_info()); |
11336 DCHECK(*scope_info != ScopeInfo::Empty(isolate)); | 10934 DCHECK(*scope_info != ScopeInfo::Empty(isolate)); |
11337 | 10935 |
11338 // Get the locals names and values into a temporary array. | 10936 // Get the locals names and values into a temporary array. |
11339 int local_count = scope_info->LocalCount(); | 10937 int local_count = scope_info->LocalCount(); |
11340 for (int slot = 0; slot < scope_info->LocalCount(); ++slot) { | 10938 for (int slot = 0; slot < scope_info->LocalCount(); ++slot) { |
11341 // Hide compiler-introduced temporary variables, whether on the stack or on | 10939 // Hide compiler-introduced temporary variables, whether on the stack or on |
11342 // the context. | 10940 // the context. |
11343 if (scope_info->LocalIsSynthetic(slot)) | 10941 if (scope_info->LocalIsSynthetic(slot)) local_count--; |
11344 local_count--; | |
11345 } | 10942 } |
11346 | 10943 |
11347 Handle<FixedArray> locals = | 10944 Handle<FixedArray> locals = |
11348 isolate->factory()->NewFixedArray(local_count * 2); | 10945 isolate->factory()->NewFixedArray(local_count * 2); |
11349 | 10946 |
11350 // Fill in the values of the locals. | 10947 // Fill in the values of the locals. |
11351 int local = 0; | 10948 int local = 0; |
11352 int i = 0; | 10949 int i = 0; |
11353 for (; i < scope_info->StackLocalCount(); ++i) { | 10950 for (; i < scope_info->StackLocalCount(); ++i) { |
11354 // Use the value from the stack. | 10951 // Use the value from the stack. |
11355 if (scope_info->LocalIsSynthetic(i)) | 10952 if (scope_info->LocalIsSynthetic(i)) continue; |
11356 continue; | |
11357 locals->set(local * 2, scope_info->LocalName(i)); | 10953 locals->set(local * 2, scope_info->LocalName(i)); |
11358 locals->set(local * 2 + 1, frame_inspector.GetExpression(i)); | 10954 locals->set(local * 2 + 1, frame_inspector.GetExpression(i)); |
11359 local++; | 10955 local++; |
11360 } | 10956 } |
11361 if (local < local_count) { | 10957 if (local < local_count) { |
11362 // Get the context containing declarations. | 10958 // Get the context containing declarations. |
11363 Handle<Context> context( | 10959 Handle<Context> context( |
11364 Context::cast(frame_inspector.GetContext())->declaration_context()); | 10960 Context::cast(frame_inspector.GetContext())->declaration_context()); |
11365 for (; i < scope_info->LocalCount(); ++i) { | 10961 for (; i < scope_info->LocalCount(); ++i) { |
11366 if (scope_info->LocalIsSynthetic(i)) | 10962 if (scope_info->LocalIsSynthetic(i)) continue; |
11367 continue; | |
11368 Handle<String> name(scope_info->LocalName(i)); | 10963 Handle<String> name(scope_info->LocalName(i)); |
11369 VariableMode mode; | 10964 VariableMode mode; |
11370 InitializationFlag init_flag; | 10965 InitializationFlag init_flag; |
11371 MaybeAssignedFlag maybe_assigned_flag; | 10966 MaybeAssignedFlag maybe_assigned_flag; |
11372 locals->set(local * 2, *name); | 10967 locals->set(local * 2, *name); |
11373 int context_slot_index = ScopeInfo::ContextSlotIndex( | 10968 int context_slot_index = ScopeInfo::ContextSlotIndex( |
11374 scope_info, name, &mode, &init_flag, &maybe_assigned_flag); | 10969 scope_info, name, &mode, &init_flag, &maybe_assigned_flag); |
11375 Object* value = context->get(context_slot_index); | 10970 Object* value = context->get(context_slot_index); |
11376 locals->set(local * 2 + 1, value); | 10971 locals->set(local * 2 + 1, value); |
11377 local++; | 10972 local++; |
(...skipping 18 matching lines...) Expand all Loading... |
11396 internal_frame_sp = it2.frame()->sp(); | 10991 internal_frame_sp = it2.frame()->sp(); |
11397 } else { | 10992 } else { |
11398 if (it2.frame()->is_java_script()) { | 10993 if (it2.frame()->is_java_script()) { |
11399 if (it2.frame()->id() == it.frame()->id()) { | 10994 if (it2.frame()->id() == it.frame()->id()) { |
11400 // The internal frame just before the JavaScript frame contains the | 10995 // The internal frame just before the JavaScript frame contains the |
11401 // value to return on top. A debug break at return will create an | 10996 // value to return on top. A debug break at return will create an |
11402 // internal frame to store the return value (eax/rax/r0) before | 10997 // internal frame to store the return value (eax/rax/r0) before |
11403 // entering the debug break exit frame. | 10998 // entering the debug break exit frame. |
11404 if (internal_frame_sp != NULL) { | 10999 if (internal_frame_sp != NULL) { |
11405 return_value = | 11000 return_value = |
11406 Handle<Object>(Memory::Object_at(internal_frame_sp), | 11001 Handle<Object>(Memory::Object_at(internal_frame_sp), isolate); |
11407 isolate); | |
11408 break; | 11002 break; |
11409 } | 11003 } |
11410 } | 11004 } |
11411 } | 11005 } |
11412 | 11006 |
11413 // Indicate that the previous frame was not an internal frame. | 11007 // Indicate that the previous frame was not an internal frame. |
11414 internal_frame_sp = NULL; | 11008 internal_frame_sp = NULL; |
11415 } | 11009 } |
11416 it2.Advance(); | 11010 it2.Advance(); |
11417 } | 11011 } |
(...skipping 10 matching lines...) Expand all Loading... |
11428 | 11022 |
11429 // Find the number of arguments to fill. At least fill the number of | 11023 // Find the number of arguments to fill. At least fill the number of |
11430 // parameters for the function and fill more if more parameters are provided. | 11024 // parameters for the function and fill more if more parameters are provided. |
11431 int argument_count = scope_info->ParameterCount(); | 11025 int argument_count = scope_info->ParameterCount(); |
11432 if (argument_count < frame_inspector.GetParametersCount()) { | 11026 if (argument_count < frame_inspector.GetParametersCount()) { |
11433 argument_count = frame_inspector.GetParametersCount(); | 11027 argument_count = frame_inspector.GetParametersCount(); |
11434 } | 11028 } |
11435 | 11029 |
11436 // Calculate the size of the result. | 11030 // Calculate the size of the result. |
11437 int details_size = kFrameDetailsFirstDynamicIndex + | 11031 int details_size = kFrameDetailsFirstDynamicIndex + |
11438 2 * (argument_count + local_count) + | 11032 2 * (argument_count + local_count) + (at_return ? 1 : 0); |
11439 (at_return ? 1 : 0); | |
11440 Handle<FixedArray> details = isolate->factory()->NewFixedArray(details_size); | 11033 Handle<FixedArray> details = isolate->factory()->NewFixedArray(details_size); |
11441 | 11034 |
11442 // Add the frame id. | 11035 // Add the frame id. |
11443 details->set(kFrameDetailsFrameIdIndex, *frame_id); | 11036 details->set(kFrameDetailsFrameIdIndex, *frame_id); |
11444 | 11037 |
11445 // Add the function (same as in function frame). | 11038 // Add the function (same as in function frame). |
11446 details->set(kFrameDetailsFunctionIndex, frame_inspector.GetFunction()); | 11039 details->set(kFrameDetailsFunctionIndex, frame_inspector.GetFunction()); |
11447 | 11040 |
11448 // Add the arguments count. | 11041 // Add the arguments count. |
11449 details->set(kFrameDetailsArgumentCountIndex, Smi::FromInt(argument_count)); | 11042 details->set(kFrameDetailsArgumentCountIndex, Smi::FromInt(argument_count)); |
11450 | 11043 |
11451 // Add the locals count | 11044 // Add the locals count |
11452 details->set(kFrameDetailsLocalCountIndex, | 11045 details->set(kFrameDetailsLocalCountIndex, Smi::FromInt(local_count)); |
11453 Smi::FromInt(local_count)); | |
11454 | 11046 |
11455 // Add the source position. | 11047 // Add the source position. |
11456 if (position != RelocInfo::kNoPosition) { | 11048 if (position != RelocInfo::kNoPosition) { |
11457 details->set(kFrameDetailsSourcePositionIndex, Smi::FromInt(position)); | 11049 details->set(kFrameDetailsSourcePositionIndex, Smi::FromInt(position)); |
11458 } else { | 11050 } else { |
11459 details->set(kFrameDetailsSourcePositionIndex, heap->undefined_value()); | 11051 details->set(kFrameDetailsSourcePositionIndex, heap->undefined_value()); |
11460 } | 11052 } |
11461 | 11053 |
11462 // Add the constructor information. | 11054 // Add the constructor information. |
11463 details->set(kFrameDetailsConstructCallIndex, heap->ToBoolean(constructor)); | 11055 details->set(kFrameDetailsConstructCallIndex, heap->ToBoolean(constructor)); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11507 | 11099 |
11508 // Add the value being returned. | 11100 // Add the value being returned. |
11509 if (at_return) { | 11101 if (at_return) { |
11510 details->set(details_index++, *return_value); | 11102 details->set(details_index++, *return_value); |
11511 } | 11103 } |
11512 | 11104 |
11513 // Add the receiver (same as in function frame). | 11105 // Add the receiver (same as in function frame). |
11514 // THIS MUST BE DONE LAST SINCE WE MIGHT ADVANCE | 11106 // THIS MUST BE DONE LAST SINCE WE MIGHT ADVANCE |
11515 // THE FRAME ITERATOR TO WRAP THE RECEIVER. | 11107 // THE FRAME ITERATOR TO WRAP THE RECEIVER. |
11516 Handle<Object> receiver(it.frame()->receiver(), isolate); | 11108 Handle<Object> receiver(it.frame()->receiver(), isolate); |
11517 if (!receiver->IsJSObject() && | 11109 if (!receiver->IsJSObject() && shared->strict_mode() == SLOPPY && |
11518 shared->strict_mode() == SLOPPY && | |
11519 !function->IsBuiltin()) { | 11110 !function->IsBuiltin()) { |
11520 // If the receiver is not a JSObject and the function is not a | 11111 // If the receiver is not a JSObject and the function is not a |
11521 // builtin or strict-mode we have hit an optimization where a | 11112 // builtin or strict-mode we have hit an optimization where a |
11522 // value object is not converted into a wrapped JS objects. To | 11113 // value object is not converted into a wrapped JS objects. To |
11523 // hide this optimization from the debugger, we wrap the receiver | 11114 // hide this optimization from the debugger, we wrap the receiver |
11524 // by creating correct wrapper object based on the calling frame's | 11115 // by creating correct wrapper object based on the calling frame's |
11525 // native context. | 11116 // native context. |
11526 it.Advance(); | 11117 it.Advance(); |
11527 if (receiver->IsUndefined()) { | 11118 if (receiver->IsUndefined()) { |
11528 receiver = handle(function->global_proxy()); | 11119 receiver = handle(function->global_proxy()); |
(...skipping 21 matching lines...) Expand all Loading... |
11550 MaybeAssignedFlag maybe_assigned_flag; | 11141 MaybeAssignedFlag maybe_assigned_flag; |
11551 return ScopeInfo::ContextSlotIndex(info, parameter_name, &mode, &init_flag, | 11142 return ScopeInfo::ContextSlotIndex(info, parameter_name, &mode, &init_flag, |
11552 &maybe_assigned_flag) != -1; | 11143 &maybe_assigned_flag) != -1; |
11553 } | 11144 } |
11554 | 11145 |
11555 | 11146 |
11556 // Create a plain JSObject which materializes the local scope for the specified | 11147 // Create a plain JSObject which materializes the local scope for the specified |
11557 // frame. | 11148 // frame. |
11558 MUST_USE_RESULT | 11149 MUST_USE_RESULT |
11559 static MaybeHandle<JSObject> MaterializeStackLocalsWithFrameInspector( | 11150 static MaybeHandle<JSObject> MaterializeStackLocalsWithFrameInspector( |
11560 Isolate* isolate, | 11151 Isolate* isolate, Handle<JSObject> target, Handle<JSFunction> function, |
11561 Handle<JSObject> target, | |
11562 Handle<JSFunction> function, | |
11563 FrameInspector* frame_inspector) { | 11152 FrameInspector* frame_inspector) { |
11564 Handle<SharedFunctionInfo> shared(function->shared()); | 11153 Handle<SharedFunctionInfo> shared(function->shared()); |
11565 Handle<ScopeInfo> scope_info(shared->scope_info()); | 11154 Handle<ScopeInfo> scope_info(shared->scope_info()); |
11566 | 11155 |
11567 // First fill all parameters. | 11156 // First fill all parameters. |
11568 for (int i = 0; i < scope_info->ParameterCount(); ++i) { | 11157 for (int i = 0; i < scope_info->ParameterCount(); ++i) { |
11569 // Do not materialize the parameter if it is shadowed by a context local. | 11158 // Do not materialize the parameter if it is shadowed by a context local. |
11570 Handle<String> name(scope_info->ParameterName(i)); | 11159 Handle<String> name(scope_info->ParameterName(i)); |
11571 if (ParameterIsShadowedByContextLocal(scope_info, name)) continue; | 11160 if (ParameterIsShadowedByContextLocal(scope_info, name)) continue; |
11572 | 11161 |
11573 HandleScope scope(isolate); | 11162 HandleScope scope(isolate); |
11574 Handle<Object> value(i < frame_inspector->GetParametersCount() | 11163 Handle<Object> value(i < frame_inspector->GetParametersCount() |
11575 ? frame_inspector->GetParameter(i) | 11164 ? frame_inspector->GetParameter(i) |
11576 : isolate->heap()->undefined_value(), | 11165 : isolate->heap()->undefined_value(), |
11577 isolate); | 11166 isolate); |
11578 DCHECK(!value->IsTheHole()); | 11167 DCHECK(!value->IsTheHole()); |
11579 | 11168 |
11580 RETURN_ON_EXCEPTION( | 11169 RETURN_ON_EXCEPTION(isolate, Runtime::SetObjectProperty( |
11581 isolate, | 11170 isolate, target, name, value, SLOPPY), |
11582 Runtime::SetObjectProperty(isolate, target, name, value, SLOPPY), | 11171 JSObject); |
11583 JSObject); | |
11584 } | 11172 } |
11585 | 11173 |
11586 // Second fill all stack locals. | 11174 // Second fill all stack locals. |
11587 for (int i = 0; i < scope_info->StackLocalCount(); ++i) { | 11175 for (int i = 0; i < scope_info->StackLocalCount(); ++i) { |
11588 if (scope_info->LocalIsSynthetic(i)) continue; | 11176 if (scope_info->LocalIsSynthetic(i)) continue; |
11589 Handle<String> name(scope_info->StackLocalName(i)); | 11177 Handle<String> name(scope_info->StackLocalName(i)); |
11590 Handle<Object> value(frame_inspector->GetExpression(i), isolate); | 11178 Handle<Object> value(frame_inspector->GetExpression(i), isolate); |
11591 if (value->IsTheHole()) continue; | 11179 if (value->IsTheHole()) continue; |
11592 | 11180 |
11593 RETURN_ON_EXCEPTION( | 11181 RETURN_ON_EXCEPTION(isolate, Runtime::SetObjectProperty( |
11594 isolate, | 11182 isolate, target, name, value, SLOPPY), |
11595 Runtime::SetObjectProperty(isolate, target, name, value, SLOPPY), | 11183 JSObject); |
11596 JSObject); | |
11597 } | 11184 } |
11598 | 11185 |
11599 return target; | 11186 return target; |
11600 } | 11187 } |
11601 | 11188 |
11602 | 11189 |
11603 static void UpdateStackLocalsFromMaterializedObject(Isolate* isolate, | 11190 static void UpdateStackLocalsFromMaterializedObject(Isolate* isolate, |
11604 Handle<JSObject> target, | 11191 Handle<JSObject> target, |
11605 Handle<JSFunction> function, | 11192 Handle<JSFunction> function, |
11606 JavaScriptFrame* frame, | 11193 JavaScriptFrame* frame, |
(...skipping 20 matching lines...) Expand all Loading... |
11627 Object::GetPropertyOrElement(target, name).ToHandleChecked(); | 11214 Object::GetPropertyOrElement(target, name).ToHandleChecked(); |
11628 frame->SetParameterValue(i, *value); | 11215 frame->SetParameterValue(i, *value); |
11629 } | 11216 } |
11630 | 11217 |
11631 // Stack locals. | 11218 // Stack locals. |
11632 for (int i = 0; i < scope_info->StackLocalCount(); ++i) { | 11219 for (int i = 0; i < scope_info->StackLocalCount(); ++i) { |
11633 if (scope_info->LocalIsSynthetic(i)) continue; | 11220 if (scope_info->LocalIsSynthetic(i)) continue; |
11634 if (frame->GetExpression(i)->IsTheHole()) continue; | 11221 if (frame->GetExpression(i)->IsTheHole()) continue; |
11635 HandleScope scope(isolate); | 11222 HandleScope scope(isolate); |
11636 Handle<Object> value = Object::GetPropertyOrElement( | 11223 Handle<Object> value = Object::GetPropertyOrElement( |
11637 target, | 11224 target, handle(scope_info->StackLocalName(i), |
11638 handle(scope_info->StackLocalName(i), isolate)).ToHandleChecked(); | 11225 isolate)).ToHandleChecked(); |
11639 frame->SetExpression(i, *value); | 11226 frame->SetExpression(i, *value); |
11640 } | 11227 } |
11641 } | 11228 } |
11642 | 11229 |
11643 | 11230 |
11644 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeLocalContext( | 11231 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeLocalContext( |
11645 Isolate* isolate, | 11232 Isolate* isolate, Handle<JSObject> target, Handle<JSFunction> function, |
11646 Handle<JSObject> target, | |
11647 Handle<JSFunction> function, | |
11648 JavaScriptFrame* frame) { | 11233 JavaScriptFrame* frame) { |
11649 HandleScope scope(isolate); | 11234 HandleScope scope(isolate); |
11650 Handle<SharedFunctionInfo> shared(function->shared()); | 11235 Handle<SharedFunctionInfo> shared(function->shared()); |
11651 Handle<ScopeInfo> scope_info(shared->scope_info()); | 11236 Handle<ScopeInfo> scope_info(shared->scope_info()); |
11652 | 11237 |
11653 if (!scope_info->HasContext()) return target; | 11238 if (!scope_info->HasContext()) return target; |
11654 | 11239 |
11655 // Third fill all context locals. | 11240 // Third fill all context locals. |
11656 Handle<Context> frame_context(Context::cast(frame->context())); | 11241 Handle<Context> frame_context(Context::cast(frame->context())); |
11657 Handle<Context> function_context(frame_context->declaration_context()); | 11242 Handle<Context> function_context(frame_context->declaration_context()); |
11658 if (!ScopeInfo::CopyContextLocalsToScopeObject( | 11243 if (!ScopeInfo::CopyContextLocalsToScopeObject(scope_info, function_context, |
11659 scope_info, function_context, target)) { | 11244 target)) { |
11660 return MaybeHandle<JSObject>(); | 11245 return MaybeHandle<JSObject>(); |
11661 } | 11246 } |
11662 | 11247 |
11663 // Finally copy any properties from the function context extension. | 11248 // Finally copy any properties from the function context extension. |
11664 // These will be variables introduced by eval. | 11249 // These will be variables introduced by eval. |
11665 if (function_context->closure() == *function) { | 11250 if (function_context->closure() == *function) { |
11666 if (function_context->has_extension() && | 11251 if (function_context->has_extension() && |
11667 !function_context->IsNativeContext()) { | 11252 !function_context->IsNativeContext()) { |
11668 Handle<JSObject> ext(JSObject::cast(function_context->extension())); | 11253 Handle<JSObject> ext(JSObject::cast(function_context->extension())); |
11669 Handle<FixedArray> keys; | 11254 Handle<FixedArray> keys; |
11670 ASSIGN_RETURN_ON_EXCEPTION( | 11255 ASSIGN_RETURN_ON_EXCEPTION( |
11671 isolate, keys, | 11256 isolate, keys, JSReceiver::GetKeys(ext, JSReceiver::INCLUDE_PROTOS), |
11672 JSReceiver::GetKeys(ext, JSReceiver::INCLUDE_PROTOS), | |
11673 JSObject); | 11257 JSObject); |
11674 | 11258 |
11675 for (int i = 0; i < keys->length(); i++) { | 11259 for (int i = 0; i < keys->length(); i++) { |
11676 // Names of variables introduced by eval are strings. | 11260 // Names of variables introduced by eval are strings. |
11677 DCHECK(keys->get(i)->IsString()); | 11261 DCHECK(keys->get(i)->IsString()); |
11678 Handle<String> key(String::cast(keys->get(i))); | 11262 Handle<String> key(String::cast(keys->get(i))); |
11679 Handle<Object> value; | 11263 Handle<Object> value; |
11680 ASSIGN_RETURN_ON_EXCEPTION( | 11264 ASSIGN_RETURN_ON_EXCEPTION( |
11681 isolate, value, Object::GetPropertyOrElement(ext, key), JSObject); | 11265 isolate, value, Object::GetPropertyOrElement(ext, key), JSObject); |
11682 RETURN_ON_EXCEPTION( | 11266 RETURN_ON_EXCEPTION(isolate, Runtime::SetObjectProperty( |
11683 isolate, | 11267 isolate, target, key, value, SLOPPY), |
11684 Runtime::SetObjectProperty(isolate, target, key, value, SLOPPY), | 11268 JSObject); |
11685 JSObject); | |
11686 } | 11269 } |
11687 } | 11270 } |
11688 } | 11271 } |
11689 | 11272 |
11690 return target; | 11273 return target; |
11691 } | 11274 } |
11692 | 11275 |
11693 | 11276 |
11694 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeLocalScope( | 11277 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeLocalScope( |
11695 Isolate* isolate, | 11278 Isolate* isolate, JavaScriptFrame* frame, int inlined_jsframe_index) { |
11696 JavaScriptFrame* frame, | |
11697 int inlined_jsframe_index) { | |
11698 FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate); | 11279 FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate); |
11699 Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction())); | 11280 Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction())); |
11700 | 11281 |
11701 Handle<JSObject> local_scope = | 11282 Handle<JSObject> local_scope = |
11702 isolate->factory()->NewJSObject(isolate->object_function()); | 11283 isolate->factory()->NewJSObject(isolate->object_function()); |
11703 ASSIGN_RETURN_ON_EXCEPTION( | 11284 ASSIGN_RETURN_ON_EXCEPTION( |
11704 isolate, local_scope, | 11285 isolate, local_scope, |
11705 MaterializeStackLocalsWithFrameInspector( | 11286 MaterializeStackLocalsWithFrameInspector(isolate, local_scope, function, |
11706 isolate, local_scope, function, &frame_inspector), | 11287 &frame_inspector), |
11707 JSObject); | 11288 JSObject); |
11708 | 11289 |
11709 return MaterializeLocalContext(isolate, local_scope, function, frame); | 11290 return MaterializeLocalContext(isolate, local_scope, function, frame); |
11710 } | 11291 } |
11711 | 11292 |
11712 | 11293 |
11713 // Set the context local variable value. | 11294 // Set the context local variable value. |
11714 static bool SetContextLocalValue(Isolate* isolate, | 11295 static bool SetContextLocalValue(Isolate* isolate, Handle<ScopeInfo> scope_info, |
11715 Handle<ScopeInfo> scope_info, | |
11716 Handle<Context> context, | 11296 Handle<Context> context, |
11717 Handle<String> variable_name, | 11297 Handle<String> variable_name, |
11718 Handle<Object> new_value) { | 11298 Handle<Object> new_value) { |
11719 for (int i = 0; i < scope_info->ContextLocalCount(); i++) { | 11299 for (int i = 0; i < scope_info->ContextLocalCount(); i++) { |
11720 Handle<String> next_name(scope_info->ContextLocalName(i)); | 11300 Handle<String> next_name(scope_info->ContextLocalName(i)); |
11721 if (String::Equals(variable_name, next_name)) { | 11301 if (String::Equals(variable_name, next_name)) { |
11722 VariableMode mode; | 11302 VariableMode mode; |
11723 InitializationFlag init_flag; | 11303 InitializationFlag init_flag; |
11724 MaybeAssignedFlag maybe_assigned_flag; | 11304 MaybeAssignedFlag maybe_assigned_flag; |
11725 int context_index = ScopeInfo::ContextSlotIndex( | 11305 int context_index = ScopeInfo::ContextSlotIndex( |
11726 scope_info, next_name, &mode, &init_flag, &maybe_assigned_flag); | 11306 scope_info, next_name, &mode, &init_flag, &maybe_assigned_flag); |
11727 context->set(context_index, *new_value); | 11307 context->set(context_index, *new_value); |
11728 return true; | 11308 return true; |
11729 } | 11309 } |
11730 } | 11310 } |
11731 | 11311 |
11732 return false; | 11312 return false; |
11733 } | 11313 } |
11734 | 11314 |
11735 | 11315 |
11736 static bool SetLocalVariableValue(Isolate* isolate, | 11316 static bool SetLocalVariableValue(Isolate* isolate, JavaScriptFrame* frame, |
11737 JavaScriptFrame* frame, | |
11738 int inlined_jsframe_index, | 11317 int inlined_jsframe_index, |
11739 Handle<String> variable_name, | 11318 Handle<String> variable_name, |
11740 Handle<Object> new_value) { | 11319 Handle<Object> new_value) { |
11741 if (inlined_jsframe_index != 0 || frame->is_optimized()) { | 11320 if (inlined_jsframe_index != 0 || frame->is_optimized()) { |
11742 // Optimized frames are not supported. | 11321 // Optimized frames are not supported. |
11743 return false; | 11322 return false; |
11744 } | 11323 } |
11745 | 11324 |
11746 Handle<JSFunction> function(frame->function()); | 11325 Handle<JSFunction> function(frame->function()); |
11747 Handle<SharedFunctionInfo> shared(function->shared()); | 11326 Handle<SharedFunctionInfo> shared(function->shared()); |
(...skipping 17 matching lines...) Expand all Loading... |
11765 if (String::Equals(handle(scope_info->StackLocalName(i)), variable_name)) { | 11344 if (String::Equals(handle(scope_info->StackLocalName(i)), variable_name)) { |
11766 frame->SetExpression(i, *new_value); | 11345 frame->SetExpression(i, *new_value); |
11767 return true; | 11346 return true; |
11768 } | 11347 } |
11769 } | 11348 } |
11770 | 11349 |
11771 if (scope_info->HasContext()) { | 11350 if (scope_info->HasContext()) { |
11772 // Context locals. | 11351 // Context locals. |
11773 Handle<Context> frame_context(Context::cast(frame->context())); | 11352 Handle<Context> frame_context(Context::cast(frame->context())); |
11774 Handle<Context> function_context(frame_context->declaration_context()); | 11353 Handle<Context> function_context(frame_context->declaration_context()); |
11775 if (SetContextLocalValue( | 11354 if (SetContextLocalValue(isolate, scope_info, function_context, |
11776 isolate, scope_info, function_context, variable_name, new_value)) { | 11355 variable_name, new_value)) { |
11777 return true; | 11356 return true; |
11778 } | 11357 } |
11779 | 11358 |
11780 // Function context extension. These are variables introduced by eval. | 11359 // Function context extension. These are variables introduced by eval. |
11781 if (function_context->closure() == *function) { | 11360 if (function_context->closure() == *function) { |
11782 if (function_context->has_extension() && | 11361 if (function_context->has_extension() && |
11783 !function_context->IsNativeContext()) { | 11362 !function_context->IsNativeContext()) { |
11784 Handle<JSObject> ext(JSObject::cast(function_context->extension())); | 11363 Handle<JSObject> ext(JSObject::cast(function_context->extension())); |
11785 | 11364 |
11786 Maybe<bool> maybe = JSReceiver::HasProperty(ext, variable_name); | 11365 Maybe<bool> maybe = JSReceiver::HasProperty(ext, variable_name); |
11787 DCHECK(maybe.has_value); | 11366 DCHECK(maybe.has_value); |
11788 if (maybe.value) { | 11367 if (maybe.value) { |
11789 // We don't expect this to do anything except replacing | 11368 // We don't expect this to do anything except replacing |
11790 // property value. | 11369 // property value. |
11791 Runtime::SetObjectProperty(isolate, ext, variable_name, new_value, | 11370 Runtime::SetObjectProperty(isolate, ext, variable_name, new_value, |
11792 SLOPPY).Assert(); | 11371 SLOPPY).Assert(); |
11793 return true; | 11372 return true; |
11794 } | 11373 } |
11795 } | 11374 } |
11796 } | 11375 } |
11797 } | 11376 } |
11798 | 11377 |
11799 return default_result; | 11378 return default_result; |
11800 } | 11379 } |
11801 | 11380 |
11802 | 11381 |
11803 // Create a plain JSObject which materializes the closure content for the | 11382 // Create a plain JSObject which materializes the closure content for the |
11804 // context. | 11383 // context. |
11805 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeClosure( | 11384 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeClosure( |
11806 Isolate* isolate, | 11385 Isolate* isolate, Handle<Context> context) { |
11807 Handle<Context> context) { | |
11808 DCHECK(context->IsFunctionContext()); | 11386 DCHECK(context->IsFunctionContext()); |
11809 | 11387 |
11810 Handle<SharedFunctionInfo> shared(context->closure()->shared()); | 11388 Handle<SharedFunctionInfo> shared(context->closure()->shared()); |
11811 Handle<ScopeInfo> scope_info(shared->scope_info()); | 11389 Handle<ScopeInfo> scope_info(shared->scope_info()); |
11812 | 11390 |
11813 // Allocate and initialize a JSObject with all the content of this function | 11391 // Allocate and initialize a JSObject with all the content of this function |
11814 // closure. | 11392 // closure. |
11815 Handle<JSObject> closure_scope = | 11393 Handle<JSObject> closure_scope = |
11816 isolate->factory()->NewJSObject(isolate->object_function()); | 11394 isolate->factory()->NewJSObject(isolate->object_function()); |
11817 | 11395 |
11818 // Fill all context locals to the context extension. | 11396 // Fill all context locals to the context extension. |
11819 if (!ScopeInfo::CopyContextLocalsToScopeObject( | 11397 if (!ScopeInfo::CopyContextLocalsToScopeObject(scope_info, context, |
11820 scope_info, context, closure_scope)) { | 11398 closure_scope)) { |
11821 return MaybeHandle<JSObject>(); | 11399 return MaybeHandle<JSObject>(); |
11822 } | 11400 } |
11823 | 11401 |
11824 // Finally copy any properties from the function context extension. This will | 11402 // Finally copy any properties from the function context extension. This will |
11825 // be variables introduced by eval. | 11403 // be variables introduced by eval. |
11826 if (context->has_extension()) { | 11404 if (context->has_extension()) { |
11827 Handle<JSObject> ext(JSObject::cast(context->extension())); | 11405 Handle<JSObject> ext(JSObject::cast(context->extension())); |
11828 Handle<FixedArray> keys; | 11406 Handle<FixedArray> keys; |
11829 ASSIGN_RETURN_ON_EXCEPTION( | 11407 ASSIGN_RETURN_ON_EXCEPTION( |
11830 isolate, keys, | 11408 isolate, keys, JSReceiver::GetKeys(ext, JSReceiver::INCLUDE_PROTOS), |
11831 JSReceiver::GetKeys(ext, JSReceiver::INCLUDE_PROTOS), JSObject); | 11409 JSObject); |
11832 | 11410 |
11833 for (int i = 0; i < keys->length(); i++) { | 11411 for (int i = 0; i < keys->length(); i++) { |
11834 HandleScope scope(isolate); | 11412 HandleScope scope(isolate); |
11835 // Names of variables introduced by eval are strings. | 11413 // Names of variables introduced by eval are strings. |
11836 DCHECK(keys->get(i)->IsString()); | 11414 DCHECK(keys->get(i)->IsString()); |
11837 Handle<String> key(String::cast(keys->get(i))); | 11415 Handle<String> key(String::cast(keys->get(i))); |
11838 Handle<Object> value; | 11416 Handle<Object> value; |
11839 ASSIGN_RETURN_ON_EXCEPTION( | 11417 ASSIGN_RETURN_ON_EXCEPTION( |
11840 isolate, value, Object::GetPropertyOrElement(ext, key), JSObject); | 11418 isolate, value, Object::GetPropertyOrElement(ext, key), JSObject); |
11841 RETURN_ON_EXCEPTION( | 11419 RETURN_ON_EXCEPTION(isolate, Runtime::DefineObjectProperty( |
11842 isolate, | 11420 closure_scope, key, value, NONE), |
11843 Runtime::DefineObjectProperty(closure_scope, key, value, NONE), | 11421 JSObject); |
11844 JSObject); | |
11845 } | 11422 } |
11846 } | 11423 } |
11847 | 11424 |
11848 return closure_scope; | 11425 return closure_scope; |
11849 } | 11426 } |
11850 | 11427 |
11851 | 11428 |
11852 // This method copies structure of MaterializeClosure method above. | 11429 // This method copies structure of MaterializeClosure method above. |
11853 static bool SetClosureVariableValue(Isolate* isolate, | 11430 static bool SetClosureVariableValue(Isolate* isolate, Handle<Context> context, |
11854 Handle<Context> context, | |
11855 Handle<String> variable_name, | 11431 Handle<String> variable_name, |
11856 Handle<Object> new_value) { | 11432 Handle<Object> new_value) { |
11857 DCHECK(context->IsFunctionContext()); | 11433 DCHECK(context->IsFunctionContext()); |
11858 | 11434 |
11859 Handle<SharedFunctionInfo> shared(context->closure()->shared()); | 11435 Handle<SharedFunctionInfo> shared(context->closure()->shared()); |
11860 Handle<ScopeInfo> scope_info(shared->scope_info()); | 11436 Handle<ScopeInfo> scope_info(shared->scope_info()); |
11861 | 11437 |
11862 // Context locals to the context extension. | 11438 // Context locals to the context extension. |
11863 if (SetContextLocalValue( | 11439 if (SetContextLocalValue(isolate, scope_info, context, variable_name, |
11864 isolate, scope_info, context, variable_name, new_value)) { | 11440 new_value)) { |
11865 return true; | 11441 return true; |
11866 } | 11442 } |
11867 | 11443 |
11868 // Properties from the function context extension. This will | 11444 // Properties from the function context extension. This will |
11869 // be variables introduced by eval. | 11445 // be variables introduced by eval. |
11870 if (context->has_extension()) { | 11446 if (context->has_extension()) { |
11871 Handle<JSObject> ext(JSObject::cast(context->extension())); | 11447 Handle<JSObject> ext(JSObject::cast(context->extension())); |
11872 Maybe<bool> maybe = JSReceiver::HasProperty(ext, variable_name); | 11448 Maybe<bool> maybe = JSReceiver::HasProperty(ext, variable_name); |
11873 DCHECK(maybe.has_value); | 11449 DCHECK(maybe.has_value); |
11874 if (maybe.value) { | 11450 if (maybe.value) { |
11875 // We don't expect this to do anything except replacing property value. | 11451 // We don't expect this to do anything except replacing property value. |
11876 Runtime::DefineObjectProperty( | 11452 Runtime::DefineObjectProperty(ext, variable_name, new_value, NONE) |
11877 ext, variable_name, new_value, NONE).Assert(); | 11453 .Assert(); |
11878 return true; | 11454 return true; |
11879 } | 11455 } |
11880 } | 11456 } |
11881 | 11457 |
11882 return false; | 11458 return false; |
11883 } | 11459 } |
11884 | 11460 |
11885 | 11461 |
11886 // Create a plain JSObject which materializes the scope for the specified | 11462 // Create a plain JSObject which materializes the scope for the specified |
11887 // catch context. | 11463 // catch context. |
11888 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeCatchScope( | 11464 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeCatchScope( |
11889 Isolate* isolate, | 11465 Isolate* isolate, Handle<Context> context) { |
11890 Handle<Context> context) { | |
11891 DCHECK(context->IsCatchContext()); | 11466 DCHECK(context->IsCatchContext()); |
11892 Handle<String> name(String::cast(context->extension())); | 11467 Handle<String> name(String::cast(context->extension())); |
11893 Handle<Object> thrown_object(context->get(Context::THROWN_OBJECT_INDEX), | 11468 Handle<Object> thrown_object(context->get(Context::THROWN_OBJECT_INDEX), |
11894 isolate); | 11469 isolate); |
11895 Handle<JSObject> catch_scope = | 11470 Handle<JSObject> catch_scope = |
11896 isolate->factory()->NewJSObject(isolate->object_function()); | 11471 isolate->factory()->NewJSObject(isolate->object_function()); |
11897 RETURN_ON_EXCEPTION( | 11472 RETURN_ON_EXCEPTION(isolate, Runtime::DefineObjectProperty( |
11898 isolate, | 11473 catch_scope, name, thrown_object, NONE), |
11899 Runtime::DefineObjectProperty(catch_scope, name, thrown_object, NONE), | 11474 JSObject); |
11900 JSObject); | |
11901 return catch_scope; | 11475 return catch_scope; |
11902 } | 11476 } |
11903 | 11477 |
11904 | 11478 |
11905 static bool SetCatchVariableValue(Isolate* isolate, | 11479 static bool SetCatchVariableValue(Isolate* isolate, Handle<Context> context, |
11906 Handle<Context> context, | |
11907 Handle<String> variable_name, | 11480 Handle<String> variable_name, |
11908 Handle<Object> new_value) { | 11481 Handle<Object> new_value) { |
11909 DCHECK(context->IsCatchContext()); | 11482 DCHECK(context->IsCatchContext()); |
11910 Handle<String> name(String::cast(context->extension())); | 11483 Handle<String> name(String::cast(context->extension())); |
11911 if (!String::Equals(name, variable_name)) { | 11484 if (!String::Equals(name, variable_name)) { |
11912 return false; | 11485 return false; |
11913 } | 11486 } |
11914 context->set(Context::THROWN_OBJECT_INDEX, *new_value); | 11487 context->set(Context::THROWN_OBJECT_INDEX, *new_value); |
11915 return true; | 11488 return true; |
11916 } | 11489 } |
11917 | 11490 |
11918 | 11491 |
11919 // Create a plain JSObject which materializes the block scope for the specified | 11492 // Create a plain JSObject which materializes the block scope for the specified |
11920 // block context. | 11493 // block context. |
11921 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeBlockScope( | 11494 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeBlockScope( |
11922 Isolate* isolate, | 11495 Isolate* isolate, Handle<Context> context) { |
11923 Handle<Context> context) { | |
11924 DCHECK(context->IsBlockContext()); | 11496 DCHECK(context->IsBlockContext()); |
11925 Handle<ScopeInfo> scope_info(ScopeInfo::cast(context->extension())); | 11497 Handle<ScopeInfo> scope_info(ScopeInfo::cast(context->extension())); |
11926 | 11498 |
11927 // Allocate and initialize a JSObject with all the arguments, stack locals | 11499 // Allocate and initialize a JSObject with all the arguments, stack locals |
11928 // heap locals and extension properties of the debugged function. | 11500 // heap locals and extension properties of the debugged function. |
11929 Handle<JSObject> block_scope = | 11501 Handle<JSObject> block_scope = |
11930 isolate->factory()->NewJSObject(isolate->object_function()); | 11502 isolate->factory()->NewJSObject(isolate->object_function()); |
11931 | 11503 |
11932 // Fill all context locals. | 11504 // Fill all context locals. |
11933 if (!ScopeInfo::CopyContextLocalsToScopeObject( | 11505 if (!ScopeInfo::CopyContextLocalsToScopeObject(scope_info, context, |
11934 scope_info, context, block_scope)) { | 11506 block_scope)) { |
11935 return MaybeHandle<JSObject>(); | 11507 return MaybeHandle<JSObject>(); |
11936 } | 11508 } |
11937 | 11509 |
11938 return block_scope; | 11510 return block_scope; |
11939 } | 11511 } |
11940 | 11512 |
11941 | 11513 |
11942 // Create a plain JSObject which materializes the module scope for the specified | 11514 // Create a plain JSObject which materializes the module scope for the specified |
11943 // module context. | 11515 // module context. |
11944 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeModuleScope( | 11516 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeModuleScope( |
11945 Isolate* isolate, | 11517 Isolate* isolate, Handle<Context> context) { |
11946 Handle<Context> context) { | |
11947 DCHECK(context->IsModuleContext()); | 11518 DCHECK(context->IsModuleContext()); |
11948 Handle<ScopeInfo> scope_info(ScopeInfo::cast(context->extension())); | 11519 Handle<ScopeInfo> scope_info(ScopeInfo::cast(context->extension())); |
11949 | 11520 |
11950 // Allocate and initialize a JSObject with all the members of the debugged | 11521 // Allocate and initialize a JSObject with all the members of the debugged |
11951 // module. | 11522 // module. |
11952 Handle<JSObject> module_scope = | 11523 Handle<JSObject> module_scope = |
11953 isolate->factory()->NewJSObject(isolate->object_function()); | 11524 isolate->factory()->NewJSObject(isolate->object_function()); |
11954 | 11525 |
11955 // Fill all context locals. | 11526 // Fill all context locals. |
11956 if (!ScopeInfo::CopyContextLocalsToScopeObject( | 11527 if (!ScopeInfo::CopyContextLocalsToScopeObject(scope_info, context, |
11957 scope_info, context, module_scope)) { | 11528 module_scope)) { |
11958 return MaybeHandle<JSObject>(); | 11529 return MaybeHandle<JSObject>(); |
11959 } | 11530 } |
11960 | 11531 |
11961 return module_scope; | 11532 return module_scope; |
11962 } | 11533 } |
11963 | 11534 |
11964 | 11535 |
11965 // Iterate over the actual scopes visible from a stack frame or from a closure. | 11536 // Iterate over the actual scopes visible from a stack frame or from a closure. |
11966 // The iteration proceeds from the innermost visible nested scope outwards. | 11537 // The iteration proceeds from the innermost visible nested scope outwards. |
11967 // All scopes are backed by an actual context except the local scope, | 11538 // All scopes are backed by an actual context except the local scope, |
11968 // which is inserted "artificially" in the context chain. | 11539 // which is inserted "artificially" in the context chain. |
11969 class ScopeIterator { | 11540 class ScopeIterator { |
11970 public: | 11541 public: |
11971 enum ScopeType { | 11542 enum ScopeType { |
11972 ScopeTypeGlobal = 0, | 11543 ScopeTypeGlobal = 0, |
11973 ScopeTypeLocal, | 11544 ScopeTypeLocal, |
11974 ScopeTypeWith, | 11545 ScopeTypeWith, |
11975 ScopeTypeClosure, | 11546 ScopeTypeClosure, |
11976 ScopeTypeCatch, | 11547 ScopeTypeCatch, |
11977 ScopeTypeBlock, | 11548 ScopeTypeBlock, |
11978 ScopeTypeModule | 11549 ScopeTypeModule |
11979 }; | 11550 }; |
11980 | 11551 |
11981 ScopeIterator(Isolate* isolate, | 11552 ScopeIterator(Isolate* isolate, JavaScriptFrame* frame, |
11982 JavaScriptFrame* frame, | 11553 int inlined_jsframe_index, bool ignore_nested_scopes = false) |
11983 int inlined_jsframe_index, | 11554 : isolate_(isolate), |
11984 bool ignore_nested_scopes = false) | 11555 frame_(frame), |
11985 : isolate_(isolate), | 11556 inlined_jsframe_index_(inlined_jsframe_index), |
11986 frame_(frame), | 11557 function_(frame->function()), |
11987 inlined_jsframe_index_(inlined_jsframe_index), | 11558 context_(Context::cast(frame->context())), |
11988 function_(frame->function()), | 11559 nested_scope_chain_(4), |
11989 context_(Context::cast(frame->context())), | 11560 failed_(false) { |
11990 nested_scope_chain_(4), | |
11991 failed_(false) { | |
11992 | |
11993 // Catch the case when the debugger stops in an internal function. | 11561 // Catch the case when the debugger stops in an internal function. |
11994 Handle<SharedFunctionInfo> shared_info(function_->shared()); | 11562 Handle<SharedFunctionInfo> shared_info(function_->shared()); |
11995 Handle<ScopeInfo> scope_info(shared_info->scope_info()); | 11563 Handle<ScopeInfo> scope_info(shared_info->scope_info()); |
11996 if (shared_info->script() == isolate->heap()->undefined_value()) { | 11564 if (shared_info->script() == isolate->heap()->undefined_value()) { |
11997 while (context_->closure() == *function_) { | 11565 while (context_->closure() == *function_) { |
11998 context_ = Handle<Context>(context_->previous(), isolate_); | 11566 context_ = Handle<Context>(context_->previous(), isolate_); |
11999 } | 11567 } |
12000 return; | 11568 return; |
12001 } | 11569 } |
12002 | 11570 |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12065 // Function code | 11633 // Function code |
12066 CompilationInfoWithZone info(shared_info); | 11634 CompilationInfoWithZone info(shared_info); |
12067 if (Parser::Parse(&info) && Scope::Analyze(&info)) { | 11635 if (Parser::Parse(&info) && Scope::Analyze(&info)) { |
12068 scope = info.function()->scope(); | 11636 scope = info.function()->scope(); |
12069 } | 11637 } |
12070 RetrieveScopeChain(scope, shared_info); | 11638 RetrieveScopeChain(scope, shared_info); |
12071 } | 11639 } |
12072 } | 11640 } |
12073 } | 11641 } |
12074 | 11642 |
12075 ScopeIterator(Isolate* isolate, | 11643 ScopeIterator(Isolate* isolate, Handle<JSFunction> function) |
12076 Handle<JSFunction> function) | 11644 : isolate_(isolate), |
12077 : isolate_(isolate), | 11645 frame_(NULL), |
12078 frame_(NULL), | 11646 inlined_jsframe_index_(0), |
12079 inlined_jsframe_index_(0), | 11647 function_(function), |
12080 function_(function), | 11648 context_(function->context()), |
12081 context_(function->context()), | 11649 failed_(false) { |
12082 failed_(false) { | |
12083 if (function->IsBuiltin()) { | 11650 if (function->IsBuiltin()) { |
12084 context_ = Handle<Context>(); | 11651 context_ = Handle<Context>(); |
12085 } | 11652 } |
12086 } | 11653 } |
12087 | 11654 |
12088 // More scopes? | 11655 // More scopes? |
12089 bool Done() { | 11656 bool Done() { |
12090 DCHECK(!failed_); | 11657 DCHECK(!failed_); |
12091 return context_.is_null(); | 11658 return context_.is_null(); |
12092 } | 11659 } |
(...skipping 21 matching lines...) Expand all Loading... |
12114 } | 11681 } |
12115 } | 11682 } |
12116 | 11683 |
12117 // Return the type of the current scope. | 11684 // Return the type of the current scope. |
12118 ScopeType Type() { | 11685 ScopeType Type() { |
12119 DCHECK(!failed_); | 11686 DCHECK(!failed_); |
12120 if (!nested_scope_chain_.is_empty()) { | 11687 if (!nested_scope_chain_.is_empty()) { |
12121 Handle<ScopeInfo> scope_info = nested_scope_chain_.last(); | 11688 Handle<ScopeInfo> scope_info = nested_scope_chain_.last(); |
12122 switch (scope_info->scope_type()) { | 11689 switch (scope_info->scope_type()) { |
12123 case FUNCTION_SCOPE: | 11690 case FUNCTION_SCOPE: |
12124 DCHECK(context_->IsFunctionContext() || | 11691 DCHECK(context_->IsFunctionContext() || !scope_info->HasContext()); |
12125 !scope_info->HasContext()); | |
12126 return ScopeTypeLocal; | 11692 return ScopeTypeLocal; |
12127 case MODULE_SCOPE: | 11693 case MODULE_SCOPE: |
12128 DCHECK(context_->IsModuleContext()); | 11694 DCHECK(context_->IsModuleContext()); |
12129 return ScopeTypeModule; | 11695 return ScopeTypeModule; |
12130 case GLOBAL_SCOPE: | 11696 case GLOBAL_SCOPE: |
12131 DCHECK(context_->IsNativeContext()); | 11697 DCHECK(context_->IsNativeContext()); |
12132 return ScopeTypeGlobal; | 11698 return ScopeTypeGlobal; |
12133 case WITH_SCOPE: | 11699 case WITH_SCOPE: |
12134 DCHECK(context_->IsWithContext()); | 11700 DCHECK(context_->IsWithContext()); |
12135 return ScopeTypeWith; | 11701 return ScopeTypeWith; |
12136 case CATCH_SCOPE: | 11702 case CATCH_SCOPE: |
12137 DCHECK(context_->IsCatchContext()); | 11703 DCHECK(context_->IsCatchContext()); |
12138 return ScopeTypeCatch; | 11704 return ScopeTypeCatch; |
12139 case BLOCK_SCOPE: | 11705 case BLOCK_SCOPE: |
12140 DCHECK(!scope_info->HasContext() || | 11706 DCHECK(!scope_info->HasContext() || context_->IsBlockContext()); |
12141 context_->IsBlockContext()); | |
12142 return ScopeTypeBlock; | 11707 return ScopeTypeBlock; |
12143 case EVAL_SCOPE: | 11708 case EVAL_SCOPE: |
12144 UNREACHABLE(); | 11709 UNREACHABLE(); |
12145 } | 11710 } |
12146 } | 11711 } |
12147 if (context_->IsNativeContext()) { | 11712 if (context_->IsNativeContext()) { |
12148 DCHECK(context_->global_object()->IsGlobalObject()); | 11713 DCHECK(context_->global_object()->IsGlobalObject()); |
12149 return ScopeTypeGlobal; | 11714 return ScopeTypeGlobal; |
12150 } | 11715 } |
12151 if (context_->IsFunctionContext()) { | 11716 if (context_->IsFunctionContext()) { |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12192 } | 11757 } |
12193 | 11758 |
12194 bool SetVariableValue(Handle<String> variable_name, | 11759 bool SetVariableValue(Handle<String> variable_name, |
12195 Handle<Object> new_value) { | 11760 Handle<Object> new_value) { |
12196 DCHECK(!failed_); | 11761 DCHECK(!failed_); |
12197 switch (Type()) { | 11762 switch (Type()) { |
12198 case ScopeIterator::ScopeTypeGlobal: | 11763 case ScopeIterator::ScopeTypeGlobal: |
12199 break; | 11764 break; |
12200 case ScopeIterator::ScopeTypeLocal: | 11765 case ScopeIterator::ScopeTypeLocal: |
12201 return SetLocalVariableValue(isolate_, frame_, inlined_jsframe_index_, | 11766 return SetLocalVariableValue(isolate_, frame_, inlined_jsframe_index_, |
12202 variable_name, new_value); | 11767 variable_name, new_value); |
12203 case ScopeIterator::ScopeTypeWith: | 11768 case ScopeIterator::ScopeTypeWith: |
12204 break; | 11769 break; |
12205 case ScopeIterator::ScopeTypeCatch: | 11770 case ScopeIterator::ScopeTypeCatch: |
12206 return SetCatchVariableValue(isolate_, CurrentContext(), | 11771 return SetCatchVariableValue(isolate_, CurrentContext(), variable_name, |
12207 variable_name, new_value); | 11772 new_value); |
12208 case ScopeIterator::ScopeTypeClosure: | 11773 case ScopeIterator::ScopeTypeClosure: |
12209 return SetClosureVariableValue(isolate_, CurrentContext(), | 11774 return SetClosureVariableValue(isolate_, CurrentContext(), |
12210 variable_name, new_value); | 11775 variable_name, new_value); |
12211 case ScopeIterator::ScopeTypeBlock: | 11776 case ScopeIterator::ScopeTypeBlock: |
12212 // TODO(2399): should we implement it? | 11777 // TODO(2399): should we implement it? |
12213 break; | 11778 break; |
12214 case ScopeIterator::ScopeTypeModule: | 11779 case ScopeIterator::ScopeTypeModule: |
12215 // TODO(2399): should we implement it? | 11780 // TODO(2399): should we implement it? |
12216 break; | 11781 break; |
12217 } | 11782 } |
12218 return false; | 11783 return false; |
12219 } | 11784 } |
12220 | 11785 |
12221 Handle<ScopeInfo> CurrentScopeInfo() { | 11786 Handle<ScopeInfo> CurrentScopeInfo() { |
12222 DCHECK(!failed_); | 11787 DCHECK(!failed_); |
12223 if (!nested_scope_chain_.is_empty()) { | 11788 if (!nested_scope_chain_.is_empty()) { |
12224 return nested_scope_chain_.last(); | 11789 return nested_scope_chain_.last(); |
12225 } else if (context_->IsBlockContext()) { | 11790 } else if (context_->IsBlockContext()) { |
12226 return Handle<ScopeInfo>(ScopeInfo::cast(context_->extension())); | 11791 return Handle<ScopeInfo>(ScopeInfo::cast(context_->extension())); |
12227 } else if (context_->IsFunctionContext()) { | 11792 } else if (context_->IsFunctionContext()) { |
12228 return Handle<ScopeInfo>(context_->closure()->shared()->scope_info()); | 11793 return Handle<ScopeInfo>(context_->closure()->shared()->scope_info()); |
12229 } | 11794 } |
12230 return Handle<ScopeInfo>::null(); | 11795 return Handle<ScopeInfo>::null(); |
12231 } | 11796 } |
12232 | 11797 |
12233 // Return the context for this scope. For the local context there might not | 11798 // Return the context for this scope. For the local context there might not |
12234 // be an actual context. | 11799 // be an actual context. |
12235 Handle<Context> CurrentContext() { | 11800 Handle<Context> CurrentContext() { |
12236 DCHECK(!failed_); | 11801 DCHECK(!failed_); |
12237 if (Type() == ScopeTypeGlobal || | 11802 if (Type() == ScopeTypeGlobal || nested_scope_chain_.is_empty()) { |
12238 nested_scope_chain_.is_empty()) { | |
12239 return context_; | 11803 return context_; |
12240 } else if (nested_scope_chain_.last()->HasContext()) { | 11804 } else if (nested_scope_chain_.last()->HasContext()) { |
12241 return context_; | 11805 return context_; |
12242 } else { | 11806 } else { |
12243 return Handle<Context>(); | 11807 return Handle<Context>(); |
12244 } | 11808 } |
12245 } | 11809 } |
12246 | 11810 |
12247 #ifdef DEBUG | 11811 #ifdef DEBUG |
12248 // Debug print of the content of the current scope. | 11812 // Debug print of the content of the current scope. |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12337 | 11901 |
12338 CONVERT_SMI_ARG_CHECKED(wrapped_id, 1); | 11902 CONVERT_SMI_ARG_CHECKED(wrapped_id, 1); |
12339 | 11903 |
12340 // Get the frame where the debugging is performed. | 11904 // Get the frame where the debugging is performed. |
12341 StackFrame::Id id = UnwrapFrameId(wrapped_id); | 11905 StackFrame::Id id = UnwrapFrameId(wrapped_id); |
12342 JavaScriptFrameIterator it(isolate, id); | 11906 JavaScriptFrameIterator it(isolate, id); |
12343 JavaScriptFrame* frame = it.frame(); | 11907 JavaScriptFrame* frame = it.frame(); |
12344 | 11908 |
12345 // Count the visible scopes. | 11909 // Count the visible scopes. |
12346 int n = 0; | 11910 int n = 0; |
12347 for (ScopeIterator it(isolate, frame, 0); | 11911 for (ScopeIterator it(isolate, frame, 0); !it.Done(); it.Next()) { |
12348 !it.Done(); | |
12349 it.Next()) { | |
12350 n++; | 11912 n++; |
12351 } | 11913 } |
12352 | 11914 |
12353 return Smi::FromInt(n); | 11915 return Smi::FromInt(n); |
12354 } | 11916 } |
12355 | 11917 |
12356 | 11918 |
12357 // Returns the list of step-in positions (text offset) in a function of the | 11919 // Returns the list of step-in positions (text offset) in a function of the |
12358 // stack frame in a range from the current debug break position to the end | 11920 // stack frame in a range from the current debug break position to the end |
12359 // of the corresponding statement. | 11921 // of the corresponding statement. |
12360 RUNTIME_FUNCTION(Runtime_GetStepInPositions) { | 11922 RUNTIME_FUNCTION(Runtime_GetStepInPositions) { |
12361 HandleScope scope(isolate); | 11923 HandleScope scope(isolate); |
12362 DCHECK(args.length() == 2); | 11924 DCHECK(args.length() == 2); |
12363 CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]); | 11925 CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]); |
12364 RUNTIME_ASSERT(CheckExecutionState(isolate, break_id)); | 11926 RUNTIME_ASSERT(CheckExecutionState(isolate, break_id)); |
12365 | 11927 |
12366 CONVERT_SMI_ARG_CHECKED(wrapped_id, 1); | 11928 CONVERT_SMI_ARG_CHECKED(wrapped_id, 1); |
12367 | 11929 |
12368 // Get the frame where the debugging is performed. | 11930 // Get the frame where the debugging is performed. |
12369 StackFrame::Id id = UnwrapFrameId(wrapped_id); | 11931 StackFrame::Id id = UnwrapFrameId(wrapped_id); |
12370 JavaScriptFrameIterator frame_it(isolate, id); | 11932 JavaScriptFrameIterator frame_it(isolate, id); |
12371 RUNTIME_ASSERT(!frame_it.done()); | 11933 RUNTIME_ASSERT(!frame_it.done()); |
12372 | 11934 |
12373 JavaScriptFrame* frame = frame_it.frame(); | 11935 JavaScriptFrame* frame = frame_it.frame(); |
12374 | 11936 |
12375 Handle<JSFunction> fun = | 11937 Handle<JSFunction> fun = Handle<JSFunction>(frame->function()); |
12376 Handle<JSFunction>(frame->function()); | 11938 Handle<SharedFunctionInfo> shared = Handle<SharedFunctionInfo>(fun->shared()); |
12377 Handle<SharedFunctionInfo> shared = | |
12378 Handle<SharedFunctionInfo>(fun->shared()); | |
12379 | 11939 |
12380 if (!isolate->debug()->EnsureDebugInfo(shared, fun)) { | 11940 if (!isolate->debug()->EnsureDebugInfo(shared, fun)) { |
12381 return isolate->heap()->undefined_value(); | 11941 return isolate->heap()->undefined_value(); |
12382 } | 11942 } |
12383 | 11943 |
12384 Handle<DebugInfo> debug_info = Debug::GetDebugInfo(shared); | 11944 Handle<DebugInfo> debug_info = Debug::GetDebugInfo(shared); |
12385 | 11945 |
12386 int len = 0; | 11946 int len = 0; |
12387 Handle<JSArray> array(isolate->factory()->NewJSArray(10)); | 11947 Handle<JSArray> array(isolate->factory()->NewJSArray(10)); |
12388 // Find the break point where execution has stopped. | 11948 // Find the break point where execution has stopped. |
(...skipping 18 matching lines...) Expand all Loading... |
12407 JavaScriptFrameIterator additional_frame_it(isolate, break_frame_id); | 11967 JavaScriptFrameIterator additional_frame_it(isolate, break_frame_id); |
12408 // If our frame is a top frame and we are stepping, we can do step-in | 11968 // If our frame is a top frame and we are stepping, we can do step-in |
12409 // at this place. | 11969 // at this place. |
12410 accept = additional_frame_it.frame()->id() == id; | 11970 accept = additional_frame_it.frame()->id() == id; |
12411 } | 11971 } |
12412 } | 11972 } |
12413 if (accept) { | 11973 if (accept) { |
12414 if (break_location_iterator.IsStepInLocation(isolate)) { | 11974 if (break_location_iterator.IsStepInLocation(isolate)) { |
12415 Smi* position_value = Smi::FromInt(break_location_iterator.position()); | 11975 Smi* position_value = Smi::FromInt(break_location_iterator.position()); |
12416 RETURN_FAILURE_ON_EXCEPTION( | 11976 RETURN_FAILURE_ON_EXCEPTION( |
12417 isolate, | 11977 isolate, JSObject::SetElement( |
12418 JSObject::SetElement(array, len, | 11978 array, len, Handle<Object>(position_value, isolate), |
12419 Handle<Object>(position_value, isolate), | 11979 NONE, SLOPPY)); |
12420 NONE, SLOPPY)); | |
12421 len++; | 11980 len++; |
12422 } | 11981 } |
12423 } | 11982 } |
12424 // Advance iterator. | 11983 // Advance iterator. |
12425 break_location_iterator.Next(); | 11984 break_location_iterator.Next(); |
12426 if (current_statement_pos != | 11985 if (current_statement_pos != break_location_iterator.statement_position()) { |
12427 break_location_iterator.statement_position()) { | |
12428 break; | 11986 break; |
12429 } | 11987 } |
12430 } | 11988 } |
12431 return *array; | 11989 return *array; |
12432 } | 11990 } |
12433 | 11991 |
12434 | 11992 |
12435 static const int kScopeDetailsTypeIndex = 0; | 11993 static const int kScopeDetailsTypeIndex = 0; |
12436 static const int kScopeDetailsObjectIndex = 1; | 11994 static const int kScopeDetailsObjectIndex = 1; |
12437 static const int kScopeDetailsSize = 2; | 11995 static const int kScopeDetailsSize = 2; |
12438 | 11996 |
12439 | 11997 |
12440 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeScopeDetails( | 11998 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeScopeDetails( |
12441 Isolate* isolate, | 11999 Isolate* isolate, ScopeIterator* it) { |
12442 ScopeIterator* it) { | |
12443 // Calculate the size of the result. | 12000 // Calculate the size of the result. |
12444 int details_size = kScopeDetailsSize; | 12001 int details_size = kScopeDetailsSize; |
12445 Handle<FixedArray> details = isolate->factory()->NewFixedArray(details_size); | 12002 Handle<FixedArray> details = isolate->factory()->NewFixedArray(details_size); |
12446 | 12003 |
12447 // Fill in scope details. | 12004 // Fill in scope details. |
12448 details->set(kScopeDetailsTypeIndex, Smi::FromInt(it->Type())); | 12005 details->set(kScopeDetailsTypeIndex, Smi::FromInt(it->Type())); |
12449 Handle<JSObject> scope_object; | 12006 Handle<JSObject> scope_object; |
12450 ASSIGN_RETURN_ON_EXCEPTION( | 12007 ASSIGN_RETURN_ON_EXCEPTION(isolate, scope_object, it->ScopeObject(), |
12451 isolate, scope_object, it->ScopeObject(), JSObject); | 12008 JSObject); |
12452 details->set(kScopeDetailsObjectIndex, *scope_object); | 12009 details->set(kScopeDetailsObjectIndex, *scope_object); |
12453 | 12010 |
12454 return isolate->factory()->NewJSArrayWithElements(details); | 12011 return isolate->factory()->NewJSArrayWithElements(details); |
12455 } | 12012 } |
12456 | 12013 |
12457 | 12014 |
12458 // Return an array with scope details | 12015 // Return an array with scope details |
12459 // args[0]: number: break id | 12016 // args[0]: number: break id |
12460 // args[1]: number: frame index | 12017 // args[1]: number: frame index |
12461 // args[2]: number: inlined frame index | 12018 // args[2]: number: inlined frame index |
(...skipping 20 matching lines...) Expand all Loading... |
12482 // Find the requested scope. | 12039 // Find the requested scope. |
12483 int n = 0; | 12040 int n = 0; |
12484 ScopeIterator it(isolate, frame, inlined_jsframe_index); | 12041 ScopeIterator it(isolate, frame, inlined_jsframe_index); |
12485 for (; !it.Done() && n < index; it.Next()) { | 12042 for (; !it.Done() && n < index; it.Next()) { |
12486 n++; | 12043 n++; |
12487 } | 12044 } |
12488 if (it.Done()) { | 12045 if (it.Done()) { |
12489 return isolate->heap()->undefined_value(); | 12046 return isolate->heap()->undefined_value(); |
12490 } | 12047 } |
12491 Handle<JSObject> details; | 12048 Handle<JSObject> details; |
12492 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 12049 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, details, |
12493 isolate, details, MaterializeScopeDetails(isolate, &it)); | 12050 MaterializeScopeDetails(isolate, &it)); |
12494 return *details; | 12051 return *details; |
12495 } | 12052 } |
12496 | 12053 |
12497 | 12054 |
12498 // Return an array of scope details | 12055 // Return an array of scope details |
12499 // args[0]: number: break id | 12056 // args[0]: number: break id |
12500 // args[1]: number: frame index | 12057 // args[1]: number: frame index |
12501 // args[2]: number: inlined frame index | 12058 // args[2]: number: inlined frame index |
12502 // args[3]: boolean: ignore nested scopes | 12059 // args[3]: boolean: ignore nested scopes |
12503 // | 12060 // |
(...skipping 17 matching lines...) Expand all Loading... |
12521 | 12078 |
12522 // Get the frame where the debugging is performed. | 12079 // Get the frame where the debugging is performed. |
12523 StackFrame::Id id = UnwrapFrameId(wrapped_id); | 12080 StackFrame::Id id = UnwrapFrameId(wrapped_id); |
12524 JavaScriptFrameIterator frame_it(isolate, id); | 12081 JavaScriptFrameIterator frame_it(isolate, id); |
12525 JavaScriptFrame* frame = frame_it.frame(); | 12082 JavaScriptFrame* frame = frame_it.frame(); |
12526 | 12083 |
12527 List<Handle<JSObject> > result(4); | 12084 List<Handle<JSObject> > result(4); |
12528 ScopeIterator it(isolate, frame, inlined_jsframe_index, ignore_nested_scopes); | 12085 ScopeIterator it(isolate, frame, inlined_jsframe_index, ignore_nested_scopes); |
12529 for (; !it.Done(); it.Next()) { | 12086 for (; !it.Done(); it.Next()) { |
12530 Handle<JSObject> details; | 12087 Handle<JSObject> details; |
12531 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 12088 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, details, |
12532 isolate, details, MaterializeScopeDetails(isolate, &it)); | 12089 MaterializeScopeDetails(isolate, &it)); |
12533 result.Add(details); | 12090 result.Add(details); |
12534 } | 12091 } |
12535 | 12092 |
12536 Handle<FixedArray> array = isolate->factory()->NewFixedArray(result.length()); | 12093 Handle<FixedArray> array = isolate->factory()->NewFixedArray(result.length()); |
12537 for (int i = 0; i < result.length(); ++i) { | 12094 for (int i = 0; i < result.length(); ++i) { |
12538 array->set(i, *result[i]); | 12095 array->set(i, *result[i]); |
12539 } | 12096 } |
12540 return *isolate->factory()->NewJSArrayWithElements(array); | 12097 return *isolate->factory()->NewJSArrayWithElements(array); |
12541 } | 12098 } |
12542 | 12099 |
(...skipping 27 matching lines...) Expand all Loading... |
12570 int n = 0; | 12127 int n = 0; |
12571 ScopeIterator it(isolate, fun); | 12128 ScopeIterator it(isolate, fun); |
12572 for (; !it.Done() && n < index; it.Next()) { | 12129 for (; !it.Done() && n < index; it.Next()) { |
12573 n++; | 12130 n++; |
12574 } | 12131 } |
12575 if (it.Done()) { | 12132 if (it.Done()) { |
12576 return isolate->heap()->undefined_value(); | 12133 return isolate->heap()->undefined_value(); |
12577 } | 12134 } |
12578 | 12135 |
12579 Handle<JSObject> details; | 12136 Handle<JSObject> details; |
12580 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 12137 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, details, |
12581 isolate, details, MaterializeScopeDetails(isolate, &it)); | 12138 MaterializeScopeDetails(isolate, &it)); |
12582 return *details; | 12139 return *details; |
12583 } | 12140 } |
12584 | 12141 |
12585 | 12142 |
12586 static bool SetScopeVariableValue(ScopeIterator* it, int index, | 12143 static bool SetScopeVariableValue(ScopeIterator* it, int index, |
12587 Handle<String> variable_name, | 12144 Handle<String> variable_name, |
12588 Handle<Object> new_value) { | 12145 Handle<Object> new_value) { |
12589 for (int n = 0; !it->Done() && n < index; it->Next()) { | 12146 for (int n = 0; !it->Done() && n < index; it->Next()) { |
12590 n++; | 12147 n++; |
12591 } | 12148 } |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12640 | 12197 |
12641 | 12198 |
12642 RUNTIME_FUNCTION(Runtime_DebugPrintScopes) { | 12199 RUNTIME_FUNCTION(Runtime_DebugPrintScopes) { |
12643 HandleScope scope(isolate); | 12200 HandleScope scope(isolate); |
12644 DCHECK(args.length() == 0); | 12201 DCHECK(args.length() == 0); |
12645 | 12202 |
12646 #ifdef DEBUG | 12203 #ifdef DEBUG |
12647 // Print the scopes for the top frame. | 12204 // Print the scopes for the top frame. |
12648 StackFrameLocator locator(isolate); | 12205 StackFrameLocator locator(isolate); |
12649 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0); | 12206 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0); |
12650 for (ScopeIterator it(isolate, frame, 0); | 12207 for (ScopeIterator it(isolate, frame, 0); !it.Done(); it.Next()) { |
12651 !it.Done(); | |
12652 it.Next()) { | |
12653 it.DebugPrint(); | 12208 it.DebugPrint(); |
12654 } | 12209 } |
12655 #endif | 12210 #endif |
12656 return isolate->heap()->undefined_value(); | 12211 return isolate->heap()->undefined_value(); |
12657 } | 12212 } |
12658 | 12213 |
12659 | 12214 |
12660 RUNTIME_FUNCTION(Runtime_GetThreadCount) { | 12215 RUNTIME_FUNCTION(Runtime_GetThreadCount) { |
12661 HandleScope scope(isolate); | 12216 HandleScope scope(isolate); |
12662 DCHECK(args.length() == 1); | 12217 DCHECK(args.length() == 1); |
12663 CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]); | 12218 CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]); |
12664 RUNTIME_ASSERT(CheckExecutionState(isolate, break_id)); | 12219 RUNTIME_ASSERT(CheckExecutionState(isolate, break_id)); |
12665 | 12220 |
12666 // Count all archived V8 threads. | 12221 // Count all archived V8 threads. |
12667 int n = 0; | 12222 int n = 0; |
12668 for (ThreadState* thread = | 12223 for (ThreadState* thread = isolate->thread_manager()->FirstThreadStateInUse(); |
12669 isolate->thread_manager()->FirstThreadStateInUse(); | 12224 thread != NULL; thread = thread->Next()) { |
12670 thread != NULL; | |
12671 thread = thread->Next()) { | |
12672 n++; | 12225 n++; |
12673 } | 12226 } |
12674 | 12227 |
12675 // Total number of threads is current thread and archived threads. | 12228 // Total number of threads is current thread and archived threads. |
12676 return Smi::FromInt(n + 1); | 12229 return Smi::FromInt(n + 1); |
12677 } | 12230 } |
12678 | 12231 |
12679 | 12232 |
12680 static const int kThreadDetailsCurrentThreadIndex = 0; | 12233 static const int kThreadDetailsCurrentThreadIndex = 0; |
12681 static const int kThreadDetailsThreadIdIndex = 1; | 12234 static const int kThreadDetailsThreadIdIndex = 1; |
(...skipping 21 matching lines...) Expand all Loading... |
12703 // Thread index 0 is current thread. | 12256 // Thread index 0 is current thread. |
12704 if (index == 0) { | 12257 if (index == 0) { |
12705 // Fill the details. | 12258 // Fill the details. |
12706 details->set(kThreadDetailsCurrentThreadIndex, | 12259 details->set(kThreadDetailsCurrentThreadIndex, |
12707 isolate->heap()->true_value()); | 12260 isolate->heap()->true_value()); |
12708 details->set(kThreadDetailsThreadIdIndex, | 12261 details->set(kThreadDetailsThreadIdIndex, |
12709 Smi::FromInt(ThreadId::Current().ToInteger())); | 12262 Smi::FromInt(ThreadId::Current().ToInteger())); |
12710 } else { | 12263 } else { |
12711 // Find the thread with the requested index. | 12264 // Find the thread with the requested index. |
12712 int n = 1; | 12265 int n = 1; |
12713 ThreadState* thread = | 12266 ThreadState* thread = isolate->thread_manager()->FirstThreadStateInUse(); |
12714 isolate->thread_manager()->FirstThreadStateInUse(); | |
12715 while (index != n && thread != NULL) { | 12267 while (index != n && thread != NULL) { |
12716 thread = thread->Next(); | 12268 thread = thread->Next(); |
12717 n++; | 12269 n++; |
12718 } | 12270 } |
12719 if (thread == NULL) { | 12271 if (thread == NULL) { |
12720 return isolate->heap()->undefined_value(); | 12272 return isolate->heap()->undefined_value(); |
12721 } | 12273 } |
12722 | 12274 |
12723 // Fill the details. | 12275 // Fill the details. |
12724 details->set(kThreadDetailsCurrentThreadIndex, | 12276 details->set(kThreadDetailsCurrentThreadIndex, |
12725 isolate->heap()->false_value()); | 12277 isolate->heap()->false_value()); |
12726 details->set(kThreadDetailsThreadIdIndex, | 12278 details->set(kThreadDetailsThreadIdIndex, |
12727 Smi::FromInt(thread->id().ToInteger())); | 12279 Smi::FromInt(thread->id().ToInteger())); |
12728 } | 12280 } |
12729 | 12281 |
12730 // Convert to JS array and return. | 12282 // Convert to JS array and return. |
12731 return *isolate->factory()->NewJSArrayWithElements(details); | 12283 return *isolate->factory()->NewJSArrayWithElements(details); |
12732 } | 12284 } |
12733 | 12285 |
12734 | 12286 |
12735 // Sets the disable break state | 12287 // Sets the disable break state |
12736 // args[0]: disable break state | 12288 // args[0]: disable break state |
12737 RUNTIME_FUNCTION(Runtime_SetDisableBreak) { | 12289 RUNTIME_FUNCTION(Runtime_SetDisableBreak) { |
12738 HandleScope scope(isolate); | 12290 HandleScope scope(isolate); |
12739 DCHECK(args.length() == 1); | 12291 DCHECK(args.length() == 1); |
12740 CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 0); | 12292 CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 0); |
12741 isolate->debug()->set_disable_break(disable_break); | 12293 isolate->debug()->set_disable_break(disable_break); |
12742 return isolate->heap()->undefined_value(); | 12294 return isolate->heap()->undefined_value(); |
12743 } | 12295 } |
12744 | 12296 |
12745 | 12297 |
12746 static bool IsPositionAlignmentCodeCorrect(int alignment) { | 12298 static bool IsPositionAlignmentCodeCorrect(int alignment) { |
12747 return alignment == STATEMENT_ALIGNED || alignment == BREAK_POSITION_ALIGNED; | 12299 return alignment == STATEMENT_ALIGNED || alignment == BREAK_POSITION_ALIGNED; |
12748 } | 12300 } |
12749 | 12301 |
12750 | 12302 |
12751 RUNTIME_FUNCTION(Runtime_GetBreakLocations) { | 12303 RUNTIME_FUNCTION(Runtime_GetBreakLocations) { |
12752 HandleScope scope(isolate); | 12304 HandleScope scope(isolate); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12814 } | 12366 } |
12815 BreakPositionAlignment alignment = | 12367 BreakPositionAlignment alignment = |
12816 static_cast<BreakPositionAlignment>(statement_aligned_code); | 12368 static_cast<BreakPositionAlignment>(statement_aligned_code); |
12817 | 12369 |
12818 // Get the script from the script wrapper. | 12370 // Get the script from the script wrapper. |
12819 RUNTIME_ASSERT(wrapper->value()->IsScript()); | 12371 RUNTIME_ASSERT(wrapper->value()->IsScript()); |
12820 Handle<Script> script(Script::cast(wrapper->value())); | 12372 Handle<Script> script(Script::cast(wrapper->value())); |
12821 | 12373 |
12822 // Set break point. | 12374 // Set break point. |
12823 if (!isolate->debug()->SetBreakPointForScript(script, break_point_object_arg, | 12375 if (!isolate->debug()->SetBreakPointForScript(script, break_point_object_arg, |
12824 &source_position, | 12376 &source_position, alignment)) { |
12825 alignment)) { | |
12826 return isolate->heap()->undefined_value(); | 12377 return isolate->heap()->undefined_value(); |
12827 } | 12378 } |
12828 | 12379 |
12829 return Smi::FromInt(source_position); | 12380 return Smi::FromInt(source_position); |
12830 } | 12381 } |
12831 | 12382 |
12832 | 12383 |
12833 // Clear a break point | 12384 // Clear a break point |
12834 // args[0]: number: break point object | 12385 // args[0]: number: break point object |
12835 RUNTIME_FUNCTION(Runtime_ClearBreakPoint) { | 12386 RUNTIME_FUNCTION(Runtime_ClearBreakPoint) { |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12894 | 12445 |
12895 StackFrame::Id frame_id; | 12446 StackFrame::Id frame_id; |
12896 if (wrapped_frame_id == 0) { | 12447 if (wrapped_frame_id == 0) { |
12897 frame_id = StackFrame::NO_ID; | 12448 frame_id = StackFrame::NO_ID; |
12898 } else { | 12449 } else { |
12899 frame_id = UnwrapFrameId(wrapped_frame_id); | 12450 frame_id = UnwrapFrameId(wrapped_frame_id); |
12900 } | 12451 } |
12901 | 12452 |
12902 // Get the step action and check validity. | 12453 // Get the step action and check validity. |
12903 StepAction step_action = static_cast<StepAction>(NumberToInt32(args[1])); | 12454 StepAction step_action = static_cast<StepAction>(NumberToInt32(args[1])); |
12904 if (step_action != StepIn && | 12455 if (step_action != StepIn && step_action != StepNext && |
12905 step_action != StepNext && | 12456 step_action != StepOut && step_action != StepInMin && |
12906 step_action != StepOut && | |
12907 step_action != StepInMin && | |
12908 step_action != StepMin) { | 12457 step_action != StepMin) { |
12909 return isolate->Throw(isolate->heap()->illegal_argument_string()); | 12458 return isolate->Throw(isolate->heap()->illegal_argument_string()); |
12910 } | 12459 } |
12911 | 12460 |
12912 if (frame_id != StackFrame::NO_ID && step_action != StepNext && | 12461 if (frame_id != StackFrame::NO_ID && step_action != StepNext && |
12913 step_action != StepMin && step_action != StepOut) { | 12462 step_action != StepMin && step_action != StepOut) { |
12914 return isolate->ThrowIllegalOperation(); | 12463 return isolate->ThrowIllegalOperation(); |
12915 } | 12464 } |
12916 | 12465 |
12917 // Get the number of steps. | 12466 // Get the number of steps. |
12918 int step_count = NumberToInt32(args[2]); | 12467 int step_count = NumberToInt32(args[2]); |
12919 if (step_count < 1) { | 12468 if (step_count < 1) { |
12920 return isolate->Throw(isolate->heap()->illegal_argument_string()); | 12469 return isolate->Throw(isolate->heap()->illegal_argument_string()); |
12921 } | 12470 } |
12922 | 12471 |
12923 // Clear all current stepping setup. | 12472 // Clear all current stepping setup. |
12924 isolate->debug()->ClearStepping(); | 12473 isolate->debug()->ClearStepping(); |
12925 | 12474 |
12926 // Prepare step. | 12475 // Prepare step. |
12927 isolate->debug()->PrepareStep(static_cast<StepAction>(step_action), | 12476 isolate->debug()->PrepareStep(static_cast<StepAction>(step_action), |
12928 step_count, | 12477 step_count, frame_id); |
12929 frame_id); | |
12930 return isolate->heap()->undefined_value(); | 12478 return isolate->heap()->undefined_value(); |
12931 } | 12479 } |
12932 | 12480 |
12933 | 12481 |
12934 // Clear all stepping set by PrepareStep. | 12482 // Clear all stepping set by PrepareStep. |
12935 RUNTIME_FUNCTION(Runtime_ClearStepping) { | 12483 RUNTIME_FUNCTION(Runtime_ClearStepping) { |
12936 HandleScope scope(isolate); | 12484 HandleScope scope(isolate); |
12937 DCHECK(args.length() == 0); | 12485 DCHECK(args.length() == 0); |
12938 isolate->debug()->ClearStepping(); | 12486 isolate->debug()->ClearStepping(); |
12939 return isolate->heap()->undefined_value(); | 12487 return isolate->heap()->undefined_value(); |
12940 } | 12488 } |
12941 | 12489 |
12942 | 12490 |
12943 // Helper function to find or create the arguments object for | 12491 // Helper function to find or create the arguments object for |
12944 // Runtime_DebugEvaluate. | 12492 // Runtime_DebugEvaluate. |
12945 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeArgumentsObject( | 12493 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeArgumentsObject( |
12946 Isolate* isolate, | 12494 Isolate* isolate, Handle<JSObject> target, Handle<JSFunction> function) { |
12947 Handle<JSObject> target, | |
12948 Handle<JSFunction> function) { | |
12949 // Do not materialize the arguments object for eval or top-level code. | 12495 // Do not materialize the arguments object for eval or top-level code. |
12950 // Skip if "arguments" is already taken. | 12496 // Skip if "arguments" is already taken. |
12951 if (!function->shared()->is_function()) return target; | 12497 if (!function->shared()->is_function()) return target; |
12952 Maybe<bool> maybe = JSReceiver::HasOwnProperty( | 12498 Maybe<bool> maybe = JSReceiver::HasOwnProperty( |
12953 target, isolate->factory()->arguments_string()); | 12499 target, isolate->factory()->arguments_string()); |
12954 if (!maybe.has_value) return MaybeHandle<JSObject>(); | 12500 if (!maybe.has_value) return MaybeHandle<JSObject>(); |
12955 if (maybe.value) return target; | 12501 if (maybe.value) return target; |
12956 | 12502 |
12957 // FunctionGetArguments can't throw an exception. | 12503 // FunctionGetArguments can't throw an exception. |
12958 Handle<JSObject> arguments = Handle<JSObject>::cast( | 12504 Handle<JSObject> arguments = |
12959 Accessors::FunctionGetArguments(function)); | 12505 Handle<JSObject>::cast(Accessors::FunctionGetArguments(function)); |
12960 Handle<String> arguments_str = isolate->factory()->arguments_string(); | 12506 Handle<String> arguments_str = isolate->factory()->arguments_string(); |
12961 RETURN_ON_EXCEPTION( | 12507 RETURN_ON_EXCEPTION(isolate, Runtime::DefineObjectProperty( |
12962 isolate, | 12508 target, arguments_str, arguments, NONE), |
12963 Runtime::DefineObjectProperty(target, arguments_str, arguments, NONE), | 12509 JSObject); |
12964 JSObject); | |
12965 return target; | 12510 return target; |
12966 } | 12511 } |
12967 | 12512 |
12968 | 12513 |
12969 // Compile and evaluate source for the given context. | 12514 // Compile and evaluate source for the given context. |
12970 static MaybeHandle<Object> DebugEvaluate(Isolate* isolate, | 12515 static MaybeHandle<Object> DebugEvaluate(Isolate* isolate, |
12971 Handle<Context> context, | 12516 Handle<Context> context, |
12972 Handle<Object> context_extension, | 12517 Handle<Object> context_extension, |
12973 Handle<Object> receiver, | 12518 Handle<Object> receiver, |
12974 Handle<String> source) { | 12519 Handle<String> source) { |
12975 if (context_extension->IsJSObject()) { | 12520 if (context_extension->IsJSObject()) { |
12976 Handle<JSObject> extension = Handle<JSObject>::cast(context_extension); | 12521 Handle<JSObject> extension = Handle<JSObject>::cast(context_extension); |
12977 Handle<JSFunction> closure(context->closure(), isolate); | 12522 Handle<JSFunction> closure(context->closure(), isolate); |
12978 context = isolate->factory()->NewWithContext(closure, context, extension); | 12523 context = isolate->factory()->NewWithContext(closure, context, extension); |
12979 } | 12524 } |
12980 | 12525 |
12981 Handle<JSFunction> eval_fun; | 12526 Handle<JSFunction> eval_fun; |
12982 ASSIGN_RETURN_ON_EXCEPTION( | 12527 ASSIGN_RETURN_ON_EXCEPTION( |
12983 isolate, eval_fun, | 12528 isolate, eval_fun, Compiler::GetFunctionFromEval(source, context, SLOPPY, |
12984 Compiler::GetFunctionFromEval(source, | 12529 NO_PARSE_RESTRICTION, |
12985 context, | 12530 RelocInfo::kNoPosition), |
12986 SLOPPY, | |
12987 NO_PARSE_RESTRICTION, | |
12988 RelocInfo::kNoPosition), | |
12989 Object); | 12531 Object); |
12990 | 12532 |
12991 Handle<Object> result; | 12533 Handle<Object> result; |
12992 ASSIGN_RETURN_ON_EXCEPTION( | 12534 ASSIGN_RETURN_ON_EXCEPTION( |
12993 isolate, result, | 12535 isolate, result, Execution::Call(isolate, eval_fun, receiver, 0, NULL), |
12994 Execution::Call(isolate, eval_fun, receiver, 0, NULL), | |
12995 Object); | 12536 Object); |
12996 | 12537 |
12997 // Skip the global proxy as it has no properties and always delegates to the | 12538 // Skip the global proxy as it has no properties and always delegates to the |
12998 // real global object. | 12539 // real global object. |
12999 if (result->IsJSGlobalProxy()) { | 12540 if (result->IsJSGlobalProxy()) { |
13000 PrototypeIterator iter(isolate, result); | 12541 PrototypeIterator iter(isolate, result); |
13001 // TODO(verwaest): This will crash when the global proxy is detached. | 12542 // TODO(verwaest): This will crash when the global proxy is detached. |
13002 result = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); | 12543 result = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); |
13003 } | 12544 } |
13004 | 12545 |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13057 | 12598 |
13058 // Evaluate on the context of the frame. | 12599 // Evaluate on the context of the frame. |
13059 Handle<Context> context(Context::cast(frame_inspector.GetContext())); | 12600 Handle<Context> context(Context::cast(frame_inspector.GetContext())); |
13060 DCHECK(!context.is_null()); | 12601 DCHECK(!context.is_null()); |
13061 | 12602 |
13062 // Materialize stack locals and the arguments object. | 12603 // Materialize stack locals and the arguments object. |
13063 Handle<JSObject> materialized = NewJSObjectWithNullProto(isolate); | 12604 Handle<JSObject> materialized = NewJSObjectWithNullProto(isolate); |
13064 | 12605 |
13065 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 12606 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
13066 isolate, materialized, | 12607 isolate, materialized, |
13067 MaterializeStackLocalsWithFrameInspector( | 12608 MaterializeStackLocalsWithFrameInspector(isolate, materialized, function, |
13068 isolate, materialized, function, &frame_inspector)); | 12609 &frame_inspector)); |
13069 | 12610 |
13070 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 12611 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
13071 isolate, materialized, | 12612 isolate, materialized, |
13072 MaterializeArgumentsObject(isolate, materialized, function)); | 12613 MaterializeArgumentsObject(isolate, materialized, function)); |
13073 | 12614 |
13074 // Add the materialized object in a with-scope to shadow the stack locals. | 12615 // Add the materialized object in a with-scope to shadow the stack locals. |
13075 context = isolate->factory()->NewWithContext(function, context, materialized); | 12616 context = isolate->factory()->NewWithContext(function, context, materialized); |
13076 | 12617 |
13077 Handle<Object> receiver(frame->receiver(), isolate); | 12618 Handle<Object> receiver(frame->receiver(), isolate); |
13078 Handle<Object> result; | 12619 Handle<Object> result; |
13079 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 12620 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
13080 isolate, result, | 12621 isolate, result, |
13081 DebugEvaluate(isolate, context, context_extension, receiver, source)); | 12622 DebugEvaluate(isolate, context, context_extension, receiver, source)); |
13082 | 12623 |
13083 // Write back potential changes to materialized stack locals to the stack. | 12624 // Write back potential changes to materialized stack locals to the stack. |
13084 UpdateStackLocalsFromMaterializedObject( | 12625 UpdateStackLocalsFromMaterializedObject(isolate, materialized, function, |
13085 isolate, materialized, function, frame, inlined_jsframe_index); | 12626 frame, inlined_jsframe_index); |
13086 | 12627 |
13087 return *result; | 12628 return *result; |
13088 } | 12629 } |
13089 | 12630 |
13090 | 12631 |
13091 RUNTIME_FUNCTION(Runtime_DebugEvaluateGlobal) { | 12632 RUNTIME_FUNCTION(Runtime_DebugEvaluateGlobal) { |
13092 HandleScope scope(isolate); | 12633 HandleScope scope(isolate); |
13093 | 12634 |
13094 // Check the execution state and decode arguments frame and source to be | 12635 // Check the execution state and decode arguments frame and source to be |
13095 // evaluated. | 12636 // evaluated. |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13147 | 12688 |
13148 // Return result as a JS array. | 12689 // Return result as a JS array. |
13149 Handle<JSObject> result = | 12690 Handle<JSObject> result = |
13150 isolate->factory()->NewJSObject(isolate->array_function()); | 12691 isolate->factory()->NewJSObject(isolate->array_function()); |
13151 JSArray::SetContent(Handle<JSArray>::cast(result), instances); | 12692 JSArray::SetContent(Handle<JSArray>::cast(result), instances); |
13152 return *result; | 12693 return *result; |
13153 } | 12694 } |
13154 | 12695 |
13155 | 12696 |
13156 // Helper function used by Runtime_DebugReferencedBy below. | 12697 // Helper function used by Runtime_DebugReferencedBy below. |
13157 static int DebugReferencedBy(HeapIterator* iterator, | 12698 static int DebugReferencedBy(HeapIterator* iterator, JSObject* target, |
13158 JSObject* target, | |
13159 Object* instance_filter, int max_references, | 12699 Object* instance_filter, int max_references, |
13160 FixedArray* instances, int instances_size, | 12700 FixedArray* instances, int instances_size, |
13161 JSFunction* arguments_function) { | 12701 JSFunction* arguments_function) { |
13162 Isolate* isolate = target->GetIsolate(); | 12702 Isolate* isolate = target->GetIsolate(); |
13163 SealHandleScope shs(isolate); | 12703 SealHandleScope shs(isolate); |
13164 DisallowHeapAllocation no_allocation; | 12704 DisallowHeapAllocation no_allocation; |
13165 | 12705 |
13166 // Iterate the heap. | 12706 // Iterate the heap. |
13167 int count = 0; | 12707 int count = 0; |
13168 JSObject* last = NULL; | 12708 JSObject* last = NULL; |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13241 JSFunction::cast(isolate->sloppy_arguments_map()->constructor())); | 12781 JSFunction::cast(isolate->sloppy_arguments_map()->constructor())); |
13242 | 12782 |
13243 // Get the number of referencing objects. | 12783 // Get the number of referencing objects. |
13244 int count; | 12784 int count; |
13245 // First perform a full GC in order to avoid dead objects and to make the heap | 12785 // First perform a full GC in order to avoid dead objects and to make the heap |
13246 // iterable. | 12786 // iterable. |
13247 Heap* heap = isolate->heap(); | 12787 Heap* heap = isolate->heap(); |
13248 heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "%DebugConstructedBy"); | 12788 heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "%DebugConstructedBy"); |
13249 { | 12789 { |
13250 HeapIterator heap_iterator(heap); | 12790 HeapIterator heap_iterator(heap); |
13251 count = DebugReferencedBy(&heap_iterator, | 12791 count = DebugReferencedBy(&heap_iterator, *target, *instance_filter, |
13252 *target, *instance_filter, max_references, | 12792 max_references, NULL, 0, *arguments_function); |
13253 NULL, 0, *arguments_function); | |
13254 } | 12793 } |
13255 | 12794 |
13256 // Allocate an array to hold the result. | 12795 // Allocate an array to hold the result. |
13257 Handle<FixedArray> instances = isolate->factory()->NewFixedArray(count); | 12796 Handle<FixedArray> instances = isolate->factory()->NewFixedArray(count); |
13258 | 12797 |
13259 // Fill the referencing objects. | 12798 // Fill the referencing objects. |
13260 { | 12799 { |
13261 HeapIterator heap_iterator(heap); | 12800 HeapIterator heap_iterator(heap); |
13262 count = DebugReferencedBy(&heap_iterator, | 12801 count = DebugReferencedBy(&heap_iterator, *target, *instance_filter, |
13263 *target, *instance_filter, max_references, | 12802 max_references, *instances, count, |
13264 *instances, count, *arguments_function); | 12803 *arguments_function); |
13265 } | 12804 } |
13266 | 12805 |
13267 // Return result as JS array. | 12806 // Return result as JS array. |
13268 Handle<JSFunction> constructor = isolate->array_function(); | 12807 Handle<JSFunction> constructor = isolate->array_function(); |
13269 | 12808 |
13270 Handle<JSObject> result = isolate->factory()->NewJSObject(constructor); | 12809 Handle<JSObject> result = isolate->factory()->NewJSObject(constructor); |
13271 JSArray::SetContent(Handle<JSArray>::cast(result), instances); | 12810 JSArray::SetContent(Handle<JSArray>::cast(result), instances); |
13272 return *result; | 12811 return *result; |
13273 } | 12812 } |
13274 | 12813 |
13275 | 12814 |
13276 // Helper function used by Runtime_DebugConstructedBy below. | 12815 // Helper function used by Runtime_DebugConstructedBy below. |
13277 static int DebugConstructedBy(HeapIterator* iterator, | 12816 static int DebugConstructedBy(HeapIterator* iterator, JSFunction* constructor, |
13278 JSFunction* constructor, | 12817 int max_references, FixedArray* instances, |
13279 int max_references, | |
13280 FixedArray* instances, | |
13281 int instances_size) { | 12818 int instances_size) { |
13282 DisallowHeapAllocation no_allocation; | 12819 DisallowHeapAllocation no_allocation; |
13283 | 12820 |
13284 // Iterate the heap. | 12821 // Iterate the heap. |
13285 int count = 0; | 12822 int count = 0; |
13286 HeapObject* heap_obj = NULL; | 12823 HeapObject* heap_obj = NULL; |
13287 while (((heap_obj = iterator->next()) != NULL) && | 12824 while (((heap_obj = iterator->next()) != NULL) && |
13288 (max_references == 0 || count < max_references)) { | 12825 (max_references == 0 || count < max_references)) { |
13289 // Only look at all JSObjects. | 12826 // Only look at all JSObjects. |
13290 if (heap_obj->IsJSObject()) { | 12827 if (heap_obj->IsJSObject()) { |
(...skipping 28 matching lines...) Expand all Loading... |
13319 RUNTIME_ASSERT(max_references >= 0); | 12856 RUNTIME_ASSERT(max_references >= 0); |
13320 | 12857 |
13321 // Get the number of referencing objects. | 12858 // Get the number of referencing objects. |
13322 int count; | 12859 int count; |
13323 // First perform a full GC in order to avoid dead objects and to make the heap | 12860 // First perform a full GC in order to avoid dead objects and to make the heap |
13324 // iterable. | 12861 // iterable. |
13325 Heap* heap = isolate->heap(); | 12862 Heap* heap = isolate->heap(); |
13326 heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "%DebugConstructedBy"); | 12863 heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "%DebugConstructedBy"); |
13327 { | 12864 { |
13328 HeapIterator heap_iterator(heap); | 12865 HeapIterator heap_iterator(heap); |
13329 count = DebugConstructedBy(&heap_iterator, | 12866 count = DebugConstructedBy(&heap_iterator, *constructor, max_references, |
13330 *constructor, | 12867 NULL, 0); |
13331 max_references, | |
13332 NULL, | |
13333 0); | |
13334 } | 12868 } |
13335 | 12869 |
13336 // Allocate an array to hold the result. | 12870 // Allocate an array to hold the result. |
13337 Handle<FixedArray> instances = isolate->factory()->NewFixedArray(count); | 12871 Handle<FixedArray> instances = isolate->factory()->NewFixedArray(count); |
13338 | 12872 |
13339 // Fill the referencing objects. | 12873 // Fill the referencing objects. |
13340 { | 12874 { |
13341 HeapIterator heap_iterator2(heap); | 12875 HeapIterator heap_iterator2(heap); |
13342 count = DebugConstructedBy(&heap_iterator2, | 12876 count = DebugConstructedBy(&heap_iterator2, *constructor, max_references, |
13343 *constructor, | 12877 *instances, count); |
13344 max_references, | |
13345 *instances, | |
13346 count); | |
13347 } | 12878 } |
13348 | 12879 |
13349 // Return result as JS array. | 12880 // Return result as JS array. |
13350 Handle<JSFunction> array_function = isolate->array_function(); | 12881 Handle<JSFunction> array_function = isolate->array_function(); |
13351 Handle<JSObject> result = isolate->factory()->NewJSObject(array_function); | 12882 Handle<JSObject> result = isolate->factory()->NewJSObject(array_function); |
13352 JSArray::SetContent(Handle<JSArray>::cast(result), instances); | 12883 JSArray::SetContent(Handle<JSArray>::cast(result), instances); |
13353 return *result; | 12884 return *result; |
13354 } | 12885 } |
13355 | 12886 |
13356 | 12887 |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13433 return f->shared()->inferred_name(); | 12964 return f->shared()->inferred_name(); |
13434 } | 12965 } |
13435 | 12966 |
13436 | 12967 |
13437 static int FindSharedFunctionInfosForScript(HeapIterator* iterator, | 12968 static int FindSharedFunctionInfosForScript(HeapIterator* iterator, |
13438 Script* script, | 12969 Script* script, |
13439 FixedArray* buffer) { | 12970 FixedArray* buffer) { |
13440 DisallowHeapAllocation no_allocation; | 12971 DisallowHeapAllocation no_allocation; |
13441 int counter = 0; | 12972 int counter = 0; |
13442 int buffer_size = buffer->length(); | 12973 int buffer_size = buffer->length(); |
13443 for (HeapObject* obj = iterator->next(); | 12974 for (HeapObject* obj = iterator->next(); obj != NULL; |
13444 obj != NULL; | |
13445 obj = iterator->next()) { | 12975 obj = iterator->next()) { |
13446 DCHECK(obj != NULL); | 12976 DCHECK(obj != NULL); |
13447 if (!obj->IsSharedFunctionInfo()) { | 12977 if (!obj->IsSharedFunctionInfo()) { |
13448 continue; | 12978 continue; |
13449 } | 12979 } |
13450 SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj); | 12980 SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj); |
13451 if (shared->script() != script) { | 12981 if (shared->script() != script) { |
13452 continue; | 12982 continue; |
13453 } | 12983 } |
13454 if (counter < buffer_size) { | 12984 if (counter < buffer_size) { |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13533 CHECK(isolate->debug()->live_edit_enabled()); | 13063 CHECK(isolate->debug()->live_edit_enabled()); |
13534 DCHECK(args.length() == 3); | 13064 DCHECK(args.length() == 3); |
13535 CONVERT_ARG_CHECKED(JSValue, original_script_value, 0); | 13065 CONVERT_ARG_CHECKED(JSValue, original_script_value, 0); |
13536 CONVERT_ARG_HANDLE_CHECKED(String, new_source, 1); | 13066 CONVERT_ARG_HANDLE_CHECKED(String, new_source, 1); |
13537 CONVERT_ARG_HANDLE_CHECKED(Object, old_script_name, 2); | 13067 CONVERT_ARG_HANDLE_CHECKED(Object, old_script_name, 2); |
13538 | 13068 |
13539 RUNTIME_ASSERT(original_script_value->value()->IsScript()); | 13069 RUNTIME_ASSERT(original_script_value->value()->IsScript()); |
13540 Handle<Script> original_script(Script::cast(original_script_value->value())); | 13070 Handle<Script> original_script(Script::cast(original_script_value->value())); |
13541 | 13071 |
13542 Handle<Object> old_script = LiveEdit::ChangeScriptSource( | 13072 Handle<Object> old_script = LiveEdit::ChangeScriptSource( |
13543 original_script, new_source, old_script_name); | 13073 original_script, new_source, old_script_name); |
13544 | 13074 |
13545 if (old_script->IsScript()) { | 13075 if (old_script->IsScript()) { |
13546 Handle<Script> script_handle = Handle<Script>::cast(old_script); | 13076 Handle<Script> script_handle = Handle<Script>::cast(old_script); |
13547 return *Script::GetWrapper(script_handle); | 13077 return *Script::GetWrapper(script_handle); |
13548 } else { | 13078 } else { |
13549 return isolate->heap()->null_value(); | 13079 return isolate->heap()->null_value(); |
13550 } | 13080 } |
13551 } | 13081 } |
13552 | 13082 |
13553 | 13083 |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13610 CHECK(isolate->debug()->live_edit_enabled()); | 13140 CHECK(isolate->debug()->live_edit_enabled()); |
13611 DCHECK(args.length() == 3); | 13141 DCHECK(args.length() == 3); |
13612 | 13142 |
13613 CONVERT_ARG_HANDLE_CHECKED(JSValue, parent_wrapper, 0); | 13143 CONVERT_ARG_HANDLE_CHECKED(JSValue, parent_wrapper, 0); |
13614 CONVERT_ARG_HANDLE_CHECKED(JSValue, orig_wrapper, 1); | 13144 CONVERT_ARG_HANDLE_CHECKED(JSValue, orig_wrapper, 1); |
13615 CONVERT_ARG_HANDLE_CHECKED(JSValue, subst_wrapper, 2); | 13145 CONVERT_ARG_HANDLE_CHECKED(JSValue, subst_wrapper, 2); |
13616 RUNTIME_ASSERT(parent_wrapper->value()->IsSharedFunctionInfo()); | 13146 RUNTIME_ASSERT(parent_wrapper->value()->IsSharedFunctionInfo()); |
13617 RUNTIME_ASSERT(orig_wrapper->value()->IsSharedFunctionInfo()); | 13147 RUNTIME_ASSERT(orig_wrapper->value()->IsSharedFunctionInfo()); |
13618 RUNTIME_ASSERT(subst_wrapper->value()->IsSharedFunctionInfo()); | 13148 RUNTIME_ASSERT(subst_wrapper->value()->IsSharedFunctionInfo()); |
13619 | 13149 |
13620 LiveEdit::ReplaceRefToNestedFunction( | 13150 LiveEdit::ReplaceRefToNestedFunction(parent_wrapper, orig_wrapper, |
13621 parent_wrapper, orig_wrapper, subst_wrapper); | 13151 subst_wrapper); |
13622 return isolate->heap()->undefined_value(); | 13152 return isolate->heap()->undefined_value(); |
13623 } | 13153 } |
13624 | 13154 |
13625 | 13155 |
13626 // Updates positions of a shared function info (first parameter) according | 13156 // Updates positions of a shared function info (first parameter) according |
13627 // to script source change. Text change is described in second parameter as | 13157 // to script source change. Text change is described in second parameter as |
13628 // array of groups of 3 numbers: | 13158 // array of groups of 3 numbers: |
13629 // (change_begin, change_end, change_end_new_position). | 13159 // (change_begin, change_end, change_end_new_position). |
13630 // Each group describes a change in text; groups are sorted by change_begin. | 13160 // Each group describes a change in text; groups are sorted by change_begin. |
13631 RUNTIME_FUNCTION(Runtime_LiveEditPatchFunctionPositions) { | 13161 RUNTIME_FUNCTION(Runtime_LiveEditPatchFunctionPositions) { |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13753 // This is used in unit tests to run code as if debugger is entered or simply | 13283 // This is used in unit tests to run code as if debugger is entered or simply |
13754 // to have a stack with C++ frame in the middle. | 13284 // to have a stack with C++ frame in the middle. |
13755 RUNTIME_FUNCTION(Runtime_ExecuteInDebugContext) { | 13285 RUNTIME_FUNCTION(Runtime_ExecuteInDebugContext) { |
13756 HandleScope scope(isolate); | 13286 HandleScope scope(isolate); |
13757 DCHECK(args.length() == 2); | 13287 DCHECK(args.length() == 2); |
13758 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); | 13288 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); |
13759 CONVERT_BOOLEAN_ARG_CHECKED(without_debugger, 1); | 13289 CONVERT_BOOLEAN_ARG_CHECKED(without_debugger, 1); |
13760 | 13290 |
13761 MaybeHandle<Object> maybe_result; | 13291 MaybeHandle<Object> maybe_result; |
13762 if (without_debugger) { | 13292 if (without_debugger) { |
13763 maybe_result = Execution::Call(isolate, | 13293 maybe_result = Execution::Call(isolate, function, |
13764 function, | 13294 handle(function->global_proxy()), 0, NULL); |
13765 handle(function->global_proxy()), | |
13766 0, | |
13767 NULL); | |
13768 } else { | 13295 } else { |
13769 DebugScope debug_scope(isolate->debug()); | 13296 DebugScope debug_scope(isolate->debug()); |
13770 maybe_result = Execution::Call(isolate, | 13297 maybe_result = Execution::Call(isolate, function, |
13771 function, | 13298 handle(function->global_proxy()), 0, NULL); |
13772 handle(function->global_proxy()), | |
13773 0, | |
13774 NULL); | |
13775 } | 13299 } |
13776 Handle<Object> result; | 13300 Handle<Object> result; |
13777 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, maybe_result); | 13301 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, maybe_result); |
13778 return *result; | 13302 return *result; |
13779 } | 13303 } |
13780 | 13304 |
13781 | 13305 |
13782 // Sets a v8 flag. | 13306 // Sets a v8 flag. |
13783 RUNTIME_FUNCTION(Runtime_SetFlags) { | 13307 RUNTIME_FUNCTION(Runtime_SetFlags) { |
13784 SealHandleScope shs(isolate); | 13308 SealHandleScope shs(isolate); |
(...skipping 21 matching lines...) Expand all Loading... |
13806 SealHandleScope shs(isolate); | 13330 SealHandleScope shs(isolate); |
13807 DCHECK(args.length() == 0); | 13331 DCHECK(args.length() == 0); |
13808 int usage = static_cast<int>(isolate->heap()->SizeOfObjects()); | 13332 int usage = static_cast<int>(isolate->heap()->SizeOfObjects()); |
13809 if (!Smi::IsValid(usage)) { | 13333 if (!Smi::IsValid(usage)) { |
13810 return *isolate->factory()->NewNumberFromInt(usage); | 13334 return *isolate->factory()->NewNumberFromInt(usage); |
13811 } | 13335 } |
13812 return Smi::FromInt(usage); | 13336 return Smi::FromInt(usage); |
13813 } | 13337 } |
13814 | 13338 |
13815 | 13339 |
13816 #ifdef V8_I18N_SUPPORT | |
13817 RUNTIME_FUNCTION(Runtime_CanonicalizeLanguageTag) { | |
13818 HandleScope scope(isolate); | |
13819 Factory* factory = isolate->factory(); | |
13820 | |
13821 DCHECK(args.length() == 1); | |
13822 CONVERT_ARG_HANDLE_CHECKED(String, locale_id_str, 0); | |
13823 | |
13824 v8::String::Utf8Value locale_id(v8::Utils::ToLocal(locale_id_str)); | |
13825 | |
13826 // Return value which denotes invalid language tag. | |
13827 const char* const kInvalidTag = "invalid-tag"; | |
13828 | |
13829 UErrorCode error = U_ZERO_ERROR; | |
13830 char icu_result[ULOC_FULLNAME_CAPACITY]; | |
13831 int icu_length = 0; | |
13832 | |
13833 uloc_forLanguageTag(*locale_id, icu_result, ULOC_FULLNAME_CAPACITY, | |
13834 &icu_length, &error); | |
13835 if (U_FAILURE(error) || icu_length == 0) { | |
13836 return *factory->NewStringFromAsciiChecked(kInvalidTag); | |
13837 } | |
13838 | |
13839 char result[ULOC_FULLNAME_CAPACITY]; | |
13840 | |
13841 // Force strict BCP47 rules. | |
13842 uloc_toLanguageTag(icu_result, result, ULOC_FULLNAME_CAPACITY, TRUE, &error); | |
13843 | |
13844 if (U_FAILURE(error)) { | |
13845 return *factory->NewStringFromAsciiChecked(kInvalidTag); | |
13846 } | |
13847 | |
13848 return *factory->NewStringFromAsciiChecked(result); | |
13849 } | |
13850 | |
13851 | |
13852 RUNTIME_FUNCTION(Runtime_AvailableLocalesOf) { | |
13853 HandleScope scope(isolate); | |
13854 Factory* factory = isolate->factory(); | |
13855 | |
13856 DCHECK(args.length() == 1); | |
13857 CONVERT_ARG_HANDLE_CHECKED(String, service, 0); | |
13858 | |
13859 const icu::Locale* available_locales = NULL; | |
13860 int32_t count = 0; | |
13861 | |
13862 if (service->IsUtf8EqualTo(CStrVector("collator"))) { | |
13863 available_locales = icu::Collator::getAvailableLocales(count); | |
13864 } else if (service->IsUtf8EqualTo(CStrVector("numberformat"))) { | |
13865 available_locales = icu::NumberFormat::getAvailableLocales(count); | |
13866 } else if (service->IsUtf8EqualTo(CStrVector("dateformat"))) { | |
13867 available_locales = icu::DateFormat::getAvailableLocales(count); | |
13868 } else if (service->IsUtf8EqualTo(CStrVector("breakiterator"))) { | |
13869 available_locales = icu::BreakIterator::getAvailableLocales(count); | |
13870 } | |
13871 | |
13872 UErrorCode error = U_ZERO_ERROR; | |
13873 char result[ULOC_FULLNAME_CAPACITY]; | |
13874 Handle<JSObject> locales = | |
13875 factory->NewJSObject(isolate->object_function()); | |
13876 | |
13877 for (int32_t i = 0; i < count; ++i) { | |
13878 const char* icu_name = available_locales[i].getName(); | |
13879 | |
13880 error = U_ZERO_ERROR; | |
13881 // No need to force strict BCP47 rules. | |
13882 uloc_toLanguageTag(icu_name, result, ULOC_FULLNAME_CAPACITY, FALSE, &error); | |
13883 if (U_FAILURE(error)) { | |
13884 // This shouldn't happen, but lets not break the user. | |
13885 continue; | |
13886 } | |
13887 | |
13888 RETURN_FAILURE_ON_EXCEPTION(isolate, | |
13889 JSObject::SetOwnPropertyIgnoreAttributes( | |
13890 locales, | |
13891 factory->NewStringFromAsciiChecked(result), | |
13892 factory->NewNumber(i), | |
13893 NONE)); | |
13894 } | |
13895 | |
13896 return *locales; | |
13897 } | |
13898 | |
13899 | |
13900 RUNTIME_FUNCTION(Runtime_GetDefaultICULocale) { | |
13901 HandleScope scope(isolate); | |
13902 Factory* factory = isolate->factory(); | |
13903 | |
13904 DCHECK(args.length() == 0); | |
13905 | |
13906 icu::Locale default_locale; | |
13907 | |
13908 // Set the locale | |
13909 char result[ULOC_FULLNAME_CAPACITY]; | |
13910 UErrorCode status = U_ZERO_ERROR; | |
13911 uloc_toLanguageTag( | |
13912 default_locale.getName(), result, ULOC_FULLNAME_CAPACITY, FALSE, &status); | |
13913 if (U_SUCCESS(status)) { | |
13914 return *factory->NewStringFromAsciiChecked(result); | |
13915 } | |
13916 | |
13917 return *factory->NewStringFromStaticChars("und"); | |
13918 } | |
13919 | |
13920 | |
13921 RUNTIME_FUNCTION(Runtime_GetLanguageTagVariants) { | |
13922 HandleScope scope(isolate); | |
13923 Factory* factory = isolate->factory(); | |
13924 | |
13925 DCHECK(args.length() == 1); | |
13926 | |
13927 CONVERT_ARG_HANDLE_CHECKED(JSArray, input, 0); | |
13928 | |
13929 uint32_t length = static_cast<uint32_t>(input->length()->Number()); | |
13930 // Set some limit to prevent fuzz tests from going OOM. | |
13931 // Can be bumped when callers' requirements change. | |
13932 RUNTIME_ASSERT(length < 100); | |
13933 Handle<FixedArray> output = factory->NewFixedArray(length); | |
13934 Handle<Name> maximized = factory->NewStringFromStaticChars("maximized"); | |
13935 Handle<Name> base = factory->NewStringFromStaticChars("base"); | |
13936 for (unsigned int i = 0; i < length; ++i) { | |
13937 Handle<Object> locale_id; | |
13938 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | |
13939 isolate, locale_id, Object::GetElement(isolate, input, i)); | |
13940 if (!locale_id->IsString()) { | |
13941 return isolate->Throw(*factory->illegal_argument_string()); | |
13942 } | |
13943 | |
13944 v8::String::Utf8Value utf8_locale_id( | |
13945 v8::Utils::ToLocal(Handle<String>::cast(locale_id))); | |
13946 | |
13947 UErrorCode error = U_ZERO_ERROR; | |
13948 | |
13949 // Convert from BCP47 to ICU format. | |
13950 // de-DE-u-co-phonebk -> de_DE@collation=phonebook | |
13951 char icu_locale[ULOC_FULLNAME_CAPACITY]; | |
13952 int icu_locale_length = 0; | |
13953 uloc_forLanguageTag(*utf8_locale_id, icu_locale, ULOC_FULLNAME_CAPACITY, | |
13954 &icu_locale_length, &error); | |
13955 if (U_FAILURE(error) || icu_locale_length == 0) { | |
13956 return isolate->Throw(*factory->illegal_argument_string()); | |
13957 } | |
13958 | |
13959 // Maximize the locale. | |
13960 // de_DE@collation=phonebook -> de_Latn_DE@collation=phonebook | |
13961 char icu_max_locale[ULOC_FULLNAME_CAPACITY]; | |
13962 uloc_addLikelySubtags( | |
13963 icu_locale, icu_max_locale, ULOC_FULLNAME_CAPACITY, &error); | |
13964 | |
13965 // Remove extensions from maximized locale. | |
13966 // de_Latn_DE@collation=phonebook -> de_Latn_DE | |
13967 char icu_base_max_locale[ULOC_FULLNAME_CAPACITY]; | |
13968 uloc_getBaseName( | |
13969 icu_max_locale, icu_base_max_locale, ULOC_FULLNAME_CAPACITY, &error); | |
13970 | |
13971 // Get original name without extensions. | |
13972 // de_DE@collation=phonebook -> de_DE | |
13973 char icu_base_locale[ULOC_FULLNAME_CAPACITY]; | |
13974 uloc_getBaseName( | |
13975 icu_locale, icu_base_locale, ULOC_FULLNAME_CAPACITY, &error); | |
13976 | |
13977 // Convert from ICU locale format to BCP47 format. | |
13978 // de_Latn_DE -> de-Latn-DE | |
13979 char base_max_locale[ULOC_FULLNAME_CAPACITY]; | |
13980 uloc_toLanguageTag(icu_base_max_locale, base_max_locale, | |
13981 ULOC_FULLNAME_CAPACITY, FALSE, &error); | |
13982 | |
13983 // de_DE -> de-DE | |
13984 char base_locale[ULOC_FULLNAME_CAPACITY]; | |
13985 uloc_toLanguageTag( | |
13986 icu_base_locale, base_locale, ULOC_FULLNAME_CAPACITY, FALSE, &error); | |
13987 | |
13988 if (U_FAILURE(error)) { | |
13989 return isolate->Throw(*factory->illegal_argument_string()); | |
13990 } | |
13991 | |
13992 Handle<JSObject> result = factory->NewJSObject(isolate->object_function()); | |
13993 Handle<String> value = factory->NewStringFromAsciiChecked(base_max_locale); | |
13994 JSObject::AddProperty(result, maximized, value, NONE); | |
13995 value = factory->NewStringFromAsciiChecked(base_locale); | |
13996 JSObject::AddProperty(result, base, value, NONE); | |
13997 output->set(i, *result); | |
13998 } | |
13999 | |
14000 Handle<JSArray> result = factory->NewJSArrayWithElements(output); | |
14001 result->set_length(Smi::FromInt(length)); | |
14002 return *result; | |
14003 } | |
14004 | |
14005 | |
14006 RUNTIME_FUNCTION(Runtime_IsInitializedIntlObject) { | |
14007 HandleScope scope(isolate); | |
14008 | |
14009 DCHECK(args.length() == 1); | |
14010 | |
14011 CONVERT_ARG_HANDLE_CHECKED(Object, input, 0); | |
14012 | |
14013 if (!input->IsJSObject()) return isolate->heap()->false_value(); | |
14014 Handle<JSObject> obj = Handle<JSObject>::cast(input); | |
14015 | |
14016 Handle<String> marker = isolate->factory()->intl_initialized_marker_string(); | |
14017 Handle<Object> tag(obj->GetHiddenProperty(marker), isolate); | |
14018 return isolate->heap()->ToBoolean(!tag->IsTheHole()); | |
14019 } | |
14020 | |
14021 | |
14022 RUNTIME_FUNCTION(Runtime_IsInitializedIntlObjectOfType) { | |
14023 HandleScope scope(isolate); | |
14024 | |
14025 DCHECK(args.length() == 2); | |
14026 | |
14027 CONVERT_ARG_HANDLE_CHECKED(Object, input, 0); | |
14028 CONVERT_ARG_HANDLE_CHECKED(String, expected_type, 1); | |
14029 | |
14030 if (!input->IsJSObject()) return isolate->heap()->false_value(); | |
14031 Handle<JSObject> obj = Handle<JSObject>::cast(input); | |
14032 | |
14033 Handle<String> marker = isolate->factory()->intl_initialized_marker_string(); | |
14034 Handle<Object> tag(obj->GetHiddenProperty(marker), isolate); | |
14035 return isolate->heap()->ToBoolean( | |
14036 tag->IsString() && String::cast(*tag)->Equals(*expected_type)); | |
14037 } | |
14038 | |
14039 | |
14040 RUNTIME_FUNCTION(Runtime_MarkAsInitializedIntlObjectOfType) { | |
14041 HandleScope scope(isolate); | |
14042 | |
14043 DCHECK(args.length() == 3); | |
14044 | |
14045 CONVERT_ARG_HANDLE_CHECKED(JSObject, input, 0); | |
14046 CONVERT_ARG_HANDLE_CHECKED(String, type, 1); | |
14047 CONVERT_ARG_HANDLE_CHECKED(JSObject, impl, 2); | |
14048 | |
14049 Handle<String> marker = isolate->factory()->intl_initialized_marker_string(); | |
14050 JSObject::SetHiddenProperty(input, marker, type); | |
14051 | |
14052 marker = isolate->factory()->intl_impl_object_string(); | |
14053 JSObject::SetHiddenProperty(input, marker, impl); | |
14054 | |
14055 return isolate->heap()->undefined_value(); | |
14056 } | |
14057 | |
14058 | |
14059 RUNTIME_FUNCTION(Runtime_GetImplFromInitializedIntlObject) { | |
14060 HandleScope scope(isolate); | |
14061 | |
14062 DCHECK(args.length() == 1); | |
14063 | |
14064 CONVERT_ARG_HANDLE_CHECKED(Object, input, 0); | |
14065 | |
14066 if (!input->IsJSObject()) { | |
14067 Vector< Handle<Object> > arguments = HandleVector(&input, 1); | |
14068 THROW_NEW_ERROR_RETURN_FAILURE(isolate, | |
14069 NewTypeError("not_intl_object", arguments)); | |
14070 } | |
14071 | |
14072 Handle<JSObject> obj = Handle<JSObject>::cast(input); | |
14073 | |
14074 Handle<String> marker = isolate->factory()->intl_impl_object_string(); | |
14075 Handle<Object> impl(obj->GetHiddenProperty(marker), isolate); | |
14076 if (impl->IsTheHole()) { | |
14077 Vector< Handle<Object> > arguments = HandleVector(&obj, 1); | |
14078 THROW_NEW_ERROR_RETURN_FAILURE(isolate, | |
14079 NewTypeError("not_intl_object", arguments)); | |
14080 } | |
14081 return *impl; | |
14082 } | |
14083 | |
14084 | |
14085 RUNTIME_FUNCTION(Runtime_CreateDateTimeFormat) { | |
14086 HandleScope scope(isolate); | |
14087 | |
14088 DCHECK(args.length() == 3); | |
14089 | |
14090 CONVERT_ARG_HANDLE_CHECKED(String, locale, 0); | |
14091 CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1); | |
14092 CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2); | |
14093 | |
14094 Handle<ObjectTemplateInfo> date_format_template = | |
14095 I18N::GetTemplate(isolate); | |
14096 | |
14097 // Create an empty object wrapper. | |
14098 Handle<JSObject> local_object; | |
14099 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | |
14100 isolate, local_object, | |
14101 Execution::InstantiateObject(date_format_template)); | |
14102 | |
14103 // Set date time formatter as internal field of the resulting JS object. | |
14104 icu::SimpleDateFormat* date_format = DateFormat::InitializeDateTimeFormat( | |
14105 isolate, locale, options, resolved); | |
14106 | |
14107 if (!date_format) return isolate->ThrowIllegalOperation(); | |
14108 | |
14109 local_object->SetInternalField(0, reinterpret_cast<Smi*>(date_format)); | |
14110 | |
14111 Factory* factory = isolate->factory(); | |
14112 Handle<String> key = factory->NewStringFromStaticChars("dateFormat"); | |
14113 Handle<String> value = factory->NewStringFromStaticChars("valid"); | |
14114 JSObject::AddProperty(local_object, key, value, NONE); | |
14115 | |
14116 // Make object handle weak so we can delete the data format once GC kicks in. | |
14117 Handle<Object> wrapper = isolate->global_handles()->Create(*local_object); | |
14118 GlobalHandles::MakeWeak(wrapper.location(), | |
14119 reinterpret_cast<void*>(wrapper.location()), | |
14120 DateFormat::DeleteDateFormat); | |
14121 return *local_object; | |
14122 } | |
14123 | |
14124 | |
14125 RUNTIME_FUNCTION(Runtime_InternalDateFormat) { | |
14126 HandleScope scope(isolate); | |
14127 | |
14128 DCHECK(args.length() == 2); | |
14129 | |
14130 CONVERT_ARG_HANDLE_CHECKED(JSObject, date_format_holder, 0); | |
14131 CONVERT_ARG_HANDLE_CHECKED(JSDate, date, 1); | |
14132 | |
14133 Handle<Object> value; | |
14134 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | |
14135 isolate, value, Execution::ToNumber(isolate, date)); | |
14136 | |
14137 icu::SimpleDateFormat* date_format = | |
14138 DateFormat::UnpackDateFormat(isolate, date_format_holder); | |
14139 if (!date_format) return isolate->ThrowIllegalOperation(); | |
14140 | |
14141 icu::UnicodeString result; | |
14142 date_format->format(value->Number(), result); | |
14143 | |
14144 Handle<String> result_str; | |
14145 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | |
14146 isolate, result_str, | |
14147 isolate->factory()->NewStringFromTwoByte( | |
14148 Vector<const uint16_t>( | |
14149 reinterpret_cast<const uint16_t*>(result.getBuffer()), | |
14150 result.length()))); | |
14151 return *result_str; | |
14152 } | |
14153 | |
14154 | |
14155 RUNTIME_FUNCTION(Runtime_InternalDateParse) { | |
14156 HandleScope scope(isolate); | |
14157 | |
14158 DCHECK(args.length() == 2); | |
14159 | |
14160 CONVERT_ARG_HANDLE_CHECKED(JSObject, date_format_holder, 0); | |
14161 CONVERT_ARG_HANDLE_CHECKED(String, date_string, 1); | |
14162 | |
14163 v8::String::Utf8Value utf8_date(v8::Utils::ToLocal(date_string)); | |
14164 icu::UnicodeString u_date(icu::UnicodeString::fromUTF8(*utf8_date)); | |
14165 icu::SimpleDateFormat* date_format = | |
14166 DateFormat::UnpackDateFormat(isolate, date_format_holder); | |
14167 if (!date_format) return isolate->ThrowIllegalOperation(); | |
14168 | |
14169 UErrorCode status = U_ZERO_ERROR; | |
14170 UDate date = date_format->parse(u_date, status); | |
14171 if (U_FAILURE(status)) return isolate->heap()->undefined_value(); | |
14172 | |
14173 Handle<Object> result; | |
14174 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | |
14175 isolate, result, | |
14176 Execution::NewDate(isolate, static_cast<double>(date))); | |
14177 DCHECK(result->IsJSDate()); | |
14178 return *result; | |
14179 } | |
14180 | |
14181 | |
14182 RUNTIME_FUNCTION(Runtime_CreateNumberFormat) { | |
14183 HandleScope scope(isolate); | |
14184 | |
14185 DCHECK(args.length() == 3); | |
14186 | |
14187 CONVERT_ARG_HANDLE_CHECKED(String, locale, 0); | |
14188 CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1); | |
14189 CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2); | |
14190 | |
14191 Handle<ObjectTemplateInfo> number_format_template = | |
14192 I18N::GetTemplate(isolate); | |
14193 | |
14194 // Create an empty object wrapper. | |
14195 Handle<JSObject> local_object; | |
14196 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | |
14197 isolate, local_object, | |
14198 Execution::InstantiateObject(number_format_template)); | |
14199 | |
14200 // Set number formatter as internal field of the resulting JS object. | |
14201 icu::DecimalFormat* number_format = NumberFormat::InitializeNumberFormat( | |
14202 isolate, locale, options, resolved); | |
14203 | |
14204 if (!number_format) return isolate->ThrowIllegalOperation(); | |
14205 | |
14206 local_object->SetInternalField(0, reinterpret_cast<Smi*>(number_format)); | |
14207 | |
14208 Factory* factory = isolate->factory(); | |
14209 Handle<String> key = factory->NewStringFromStaticChars("numberFormat"); | |
14210 Handle<String> value = factory->NewStringFromStaticChars("valid"); | |
14211 JSObject::AddProperty(local_object, key, value, NONE); | |
14212 | |
14213 Handle<Object> wrapper = isolate->global_handles()->Create(*local_object); | |
14214 GlobalHandles::MakeWeak(wrapper.location(), | |
14215 reinterpret_cast<void*>(wrapper.location()), | |
14216 NumberFormat::DeleteNumberFormat); | |
14217 return *local_object; | |
14218 } | |
14219 | |
14220 | |
14221 RUNTIME_FUNCTION(Runtime_InternalNumberFormat) { | |
14222 HandleScope scope(isolate); | |
14223 | |
14224 DCHECK(args.length() == 2); | |
14225 | |
14226 CONVERT_ARG_HANDLE_CHECKED(JSObject, number_format_holder, 0); | |
14227 CONVERT_ARG_HANDLE_CHECKED(Object, number, 1); | |
14228 | |
14229 Handle<Object> value; | |
14230 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | |
14231 isolate, value, Execution::ToNumber(isolate, number)); | |
14232 | |
14233 icu::DecimalFormat* number_format = | |
14234 NumberFormat::UnpackNumberFormat(isolate, number_format_holder); | |
14235 if (!number_format) return isolate->ThrowIllegalOperation(); | |
14236 | |
14237 icu::UnicodeString result; | |
14238 number_format->format(value->Number(), result); | |
14239 | |
14240 Handle<String> result_str; | |
14241 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | |
14242 isolate, result_str, | |
14243 isolate->factory()->NewStringFromTwoByte( | |
14244 Vector<const uint16_t>( | |
14245 reinterpret_cast<const uint16_t*>(result.getBuffer()), | |
14246 result.length()))); | |
14247 return *result_str; | |
14248 } | |
14249 | |
14250 | |
14251 RUNTIME_FUNCTION(Runtime_InternalNumberParse) { | |
14252 HandleScope scope(isolate); | |
14253 | |
14254 DCHECK(args.length() == 2); | |
14255 | |
14256 CONVERT_ARG_HANDLE_CHECKED(JSObject, number_format_holder, 0); | |
14257 CONVERT_ARG_HANDLE_CHECKED(String, number_string, 1); | |
14258 | |
14259 v8::String::Utf8Value utf8_number(v8::Utils::ToLocal(number_string)); | |
14260 icu::UnicodeString u_number(icu::UnicodeString::fromUTF8(*utf8_number)); | |
14261 icu::DecimalFormat* number_format = | |
14262 NumberFormat::UnpackNumberFormat(isolate, number_format_holder); | |
14263 if (!number_format) return isolate->ThrowIllegalOperation(); | |
14264 | |
14265 UErrorCode status = U_ZERO_ERROR; | |
14266 icu::Formattable result; | |
14267 // ICU 4.6 doesn't support parseCurrency call. We need to wait for ICU49 | |
14268 // to be part of Chrome. | |
14269 // TODO(cira): Include currency parsing code using parseCurrency call. | |
14270 // We need to check if the formatter parses all currencies or only the | |
14271 // one it was constructed with (it will impact the API - how to return ISO | |
14272 // code and the value). | |
14273 number_format->parse(u_number, result, status); | |
14274 if (U_FAILURE(status)) return isolate->heap()->undefined_value(); | |
14275 | |
14276 switch (result.getType()) { | |
14277 case icu::Formattable::kDouble: | |
14278 return *isolate->factory()->NewNumber(result.getDouble()); | |
14279 case icu::Formattable::kLong: | |
14280 return *isolate->factory()->NewNumberFromInt(result.getLong()); | |
14281 case icu::Formattable::kInt64: | |
14282 return *isolate->factory()->NewNumber( | |
14283 static_cast<double>(result.getInt64())); | |
14284 default: | |
14285 return isolate->heap()->undefined_value(); | |
14286 } | |
14287 } | |
14288 | |
14289 | |
14290 RUNTIME_FUNCTION(Runtime_CreateCollator) { | |
14291 HandleScope scope(isolate); | |
14292 | |
14293 DCHECK(args.length() == 3); | |
14294 | |
14295 CONVERT_ARG_HANDLE_CHECKED(String, locale, 0); | |
14296 CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1); | |
14297 CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2); | |
14298 | |
14299 Handle<ObjectTemplateInfo> collator_template = I18N::GetTemplate(isolate); | |
14300 | |
14301 // Create an empty object wrapper. | |
14302 Handle<JSObject> local_object; | |
14303 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | |
14304 isolate, local_object, Execution::InstantiateObject(collator_template)); | |
14305 | |
14306 // Set collator as internal field of the resulting JS object. | |
14307 icu::Collator* collator = Collator::InitializeCollator( | |
14308 isolate, locale, options, resolved); | |
14309 | |
14310 if (!collator) return isolate->ThrowIllegalOperation(); | |
14311 | |
14312 local_object->SetInternalField(0, reinterpret_cast<Smi*>(collator)); | |
14313 | |
14314 Factory* factory = isolate->factory(); | |
14315 Handle<String> key = factory->NewStringFromStaticChars("collator"); | |
14316 Handle<String> value = factory->NewStringFromStaticChars("valid"); | |
14317 JSObject::AddProperty(local_object, key, value, NONE); | |
14318 | |
14319 Handle<Object> wrapper = isolate->global_handles()->Create(*local_object); | |
14320 GlobalHandles::MakeWeak(wrapper.location(), | |
14321 reinterpret_cast<void*>(wrapper.location()), | |
14322 Collator::DeleteCollator); | |
14323 return *local_object; | |
14324 } | |
14325 | |
14326 | |
14327 RUNTIME_FUNCTION(Runtime_InternalCompare) { | |
14328 HandleScope scope(isolate); | |
14329 | |
14330 DCHECK(args.length() == 3); | |
14331 | |
14332 CONVERT_ARG_HANDLE_CHECKED(JSObject, collator_holder, 0); | |
14333 CONVERT_ARG_HANDLE_CHECKED(String, string1, 1); | |
14334 CONVERT_ARG_HANDLE_CHECKED(String, string2, 2); | |
14335 | |
14336 icu::Collator* collator = Collator::UnpackCollator(isolate, collator_holder); | |
14337 if (!collator) return isolate->ThrowIllegalOperation(); | |
14338 | |
14339 v8::String::Value string_value1(v8::Utils::ToLocal(string1)); | |
14340 v8::String::Value string_value2(v8::Utils::ToLocal(string2)); | |
14341 const UChar* u_string1 = reinterpret_cast<const UChar*>(*string_value1); | |
14342 const UChar* u_string2 = reinterpret_cast<const UChar*>(*string_value2); | |
14343 UErrorCode status = U_ZERO_ERROR; | |
14344 UCollationResult result = collator->compare(u_string1, | |
14345 string_value1.length(), | |
14346 u_string2, | |
14347 string_value2.length(), | |
14348 status); | |
14349 if (U_FAILURE(status)) return isolate->ThrowIllegalOperation(); | |
14350 | |
14351 return *isolate->factory()->NewNumberFromInt(result); | |
14352 } | |
14353 | |
14354 | |
14355 RUNTIME_FUNCTION(Runtime_StringNormalize) { | |
14356 HandleScope scope(isolate); | |
14357 static const UNormalizationMode normalizationForms[] = | |
14358 { UNORM_NFC, UNORM_NFD, UNORM_NFKC, UNORM_NFKD }; | |
14359 | |
14360 DCHECK(args.length() == 2); | |
14361 | |
14362 CONVERT_ARG_HANDLE_CHECKED(String, stringValue, 0); | |
14363 CONVERT_NUMBER_CHECKED(int, form_id, Int32, args[1]); | |
14364 RUNTIME_ASSERT(form_id >= 0 && | |
14365 static_cast<size_t>(form_id) < arraysize(normalizationForms)); | |
14366 | |
14367 v8::String::Value string_value(v8::Utils::ToLocal(stringValue)); | |
14368 const UChar* u_value = reinterpret_cast<const UChar*>(*string_value); | |
14369 | |
14370 // TODO(mnita): check Normalizer2 (not available in ICU 46) | |
14371 UErrorCode status = U_ZERO_ERROR; | |
14372 icu::UnicodeString result; | |
14373 icu::Normalizer::normalize(u_value, normalizationForms[form_id], 0, | |
14374 result, status); | |
14375 if (U_FAILURE(status)) { | |
14376 return isolate->heap()->undefined_value(); | |
14377 } | |
14378 | |
14379 Handle<String> result_str; | |
14380 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | |
14381 isolate, result_str, | |
14382 isolate->factory()->NewStringFromTwoByte( | |
14383 Vector<const uint16_t>( | |
14384 reinterpret_cast<const uint16_t*>(result.getBuffer()), | |
14385 result.length()))); | |
14386 return *result_str; | |
14387 } | |
14388 | |
14389 | |
14390 RUNTIME_FUNCTION(Runtime_CreateBreakIterator) { | |
14391 HandleScope scope(isolate); | |
14392 | |
14393 DCHECK(args.length() == 3); | |
14394 | |
14395 CONVERT_ARG_HANDLE_CHECKED(String, locale, 0); | |
14396 CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1); | |
14397 CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2); | |
14398 | |
14399 Handle<ObjectTemplateInfo> break_iterator_template = | |
14400 I18N::GetTemplate2(isolate); | |
14401 | |
14402 // Create an empty object wrapper. | |
14403 Handle<JSObject> local_object; | |
14404 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | |
14405 isolate, local_object, | |
14406 Execution::InstantiateObject(break_iterator_template)); | |
14407 | |
14408 // Set break iterator as internal field of the resulting JS object. | |
14409 icu::BreakIterator* break_iterator = BreakIterator::InitializeBreakIterator( | |
14410 isolate, locale, options, resolved); | |
14411 | |
14412 if (!break_iterator) return isolate->ThrowIllegalOperation(); | |
14413 | |
14414 local_object->SetInternalField(0, reinterpret_cast<Smi*>(break_iterator)); | |
14415 // Make sure that the pointer to adopted text is NULL. | |
14416 local_object->SetInternalField(1, reinterpret_cast<Smi*>(NULL)); | |
14417 | |
14418 Factory* factory = isolate->factory(); | |
14419 Handle<String> key = factory->NewStringFromStaticChars("breakIterator"); | |
14420 Handle<String> value = factory->NewStringFromStaticChars("valid"); | |
14421 JSObject::AddProperty(local_object, key, value, NONE); | |
14422 | |
14423 // Make object handle weak so we can delete the break iterator once GC kicks | |
14424 // in. | |
14425 Handle<Object> wrapper = isolate->global_handles()->Create(*local_object); | |
14426 GlobalHandles::MakeWeak(wrapper.location(), | |
14427 reinterpret_cast<void*>(wrapper.location()), | |
14428 BreakIterator::DeleteBreakIterator); | |
14429 return *local_object; | |
14430 } | |
14431 | |
14432 | |
14433 RUNTIME_FUNCTION(Runtime_BreakIteratorAdoptText) { | |
14434 HandleScope scope(isolate); | |
14435 | |
14436 DCHECK(args.length() == 2); | |
14437 | |
14438 CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0); | |
14439 CONVERT_ARG_HANDLE_CHECKED(String, text, 1); | |
14440 | |
14441 icu::BreakIterator* break_iterator = | |
14442 BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder); | |
14443 if (!break_iterator) return isolate->ThrowIllegalOperation(); | |
14444 | |
14445 icu::UnicodeString* u_text = reinterpret_cast<icu::UnicodeString*>( | |
14446 break_iterator_holder->GetInternalField(1)); | |
14447 delete u_text; | |
14448 | |
14449 v8::String::Value text_value(v8::Utils::ToLocal(text)); | |
14450 u_text = new icu::UnicodeString( | |
14451 reinterpret_cast<const UChar*>(*text_value), text_value.length()); | |
14452 break_iterator_holder->SetInternalField(1, reinterpret_cast<Smi*>(u_text)); | |
14453 | |
14454 break_iterator->setText(*u_text); | |
14455 | |
14456 return isolate->heap()->undefined_value(); | |
14457 } | |
14458 | |
14459 | |
14460 RUNTIME_FUNCTION(Runtime_BreakIteratorFirst) { | |
14461 HandleScope scope(isolate); | |
14462 | |
14463 DCHECK(args.length() == 1); | |
14464 | |
14465 CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0); | |
14466 | |
14467 icu::BreakIterator* break_iterator = | |
14468 BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder); | |
14469 if (!break_iterator) return isolate->ThrowIllegalOperation(); | |
14470 | |
14471 return *isolate->factory()->NewNumberFromInt(break_iterator->first()); | |
14472 } | |
14473 | |
14474 | |
14475 RUNTIME_FUNCTION(Runtime_BreakIteratorNext) { | |
14476 HandleScope scope(isolate); | |
14477 | |
14478 DCHECK(args.length() == 1); | |
14479 | |
14480 CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0); | |
14481 | |
14482 icu::BreakIterator* break_iterator = | |
14483 BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder); | |
14484 if (!break_iterator) return isolate->ThrowIllegalOperation(); | |
14485 | |
14486 return *isolate->factory()->NewNumberFromInt(break_iterator->next()); | |
14487 } | |
14488 | |
14489 | |
14490 RUNTIME_FUNCTION(Runtime_BreakIteratorCurrent) { | |
14491 HandleScope scope(isolate); | |
14492 | |
14493 DCHECK(args.length() == 1); | |
14494 | |
14495 CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0); | |
14496 | |
14497 icu::BreakIterator* break_iterator = | |
14498 BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder); | |
14499 if (!break_iterator) return isolate->ThrowIllegalOperation(); | |
14500 | |
14501 return *isolate->factory()->NewNumberFromInt(break_iterator->current()); | |
14502 } | |
14503 | |
14504 | |
14505 RUNTIME_FUNCTION(Runtime_BreakIteratorBreakType) { | |
14506 HandleScope scope(isolate); | |
14507 | |
14508 DCHECK(args.length() == 1); | |
14509 | |
14510 CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0); | |
14511 | |
14512 icu::BreakIterator* break_iterator = | |
14513 BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder); | |
14514 if (!break_iterator) return isolate->ThrowIllegalOperation(); | |
14515 | |
14516 // TODO(cira): Remove cast once ICU fixes base BreakIterator class. | |
14517 icu::RuleBasedBreakIterator* rule_based_iterator = | |
14518 static_cast<icu::RuleBasedBreakIterator*>(break_iterator); | |
14519 int32_t status = rule_based_iterator->getRuleStatus(); | |
14520 // Keep return values in sync with JavaScript BreakType enum. | |
14521 if (status >= UBRK_WORD_NONE && status < UBRK_WORD_NONE_LIMIT) { | |
14522 return *isolate->factory()->NewStringFromStaticChars("none"); | |
14523 } else if (status >= UBRK_WORD_NUMBER && status < UBRK_WORD_NUMBER_LIMIT) { | |
14524 return *isolate->factory()->number_string(); | |
14525 } else if (status >= UBRK_WORD_LETTER && status < UBRK_WORD_LETTER_LIMIT) { | |
14526 return *isolate->factory()->NewStringFromStaticChars("letter"); | |
14527 } else if (status >= UBRK_WORD_KANA && status < UBRK_WORD_KANA_LIMIT) { | |
14528 return *isolate->factory()->NewStringFromStaticChars("kana"); | |
14529 } else if (status >= UBRK_WORD_IDEO && status < UBRK_WORD_IDEO_LIMIT) { | |
14530 return *isolate->factory()->NewStringFromStaticChars("ideo"); | |
14531 } else { | |
14532 return *isolate->factory()->NewStringFromStaticChars("unknown"); | |
14533 } | |
14534 } | |
14535 #endif // V8_I18N_SUPPORT | |
14536 | |
14537 | |
14538 // Finds the script object from the script data. NOTE: This operation uses | 13340 // Finds the script object from the script data. NOTE: This operation uses |
14539 // heap traversal to find the function generated for the source position | 13341 // heap traversal to find the function generated for the source position |
14540 // for the requested break point. For lazily compiled functions several heap | 13342 // for the requested break point. For lazily compiled functions several heap |
14541 // traversals might be required rendering this operation as a rather slow | 13343 // traversals might be required rendering this operation as a rather slow |
14542 // operation. However for setting break points which is normally done through | 13344 // operation. However for setting break points which is normally done through |
14543 // some kind of user interaction the performance is not crucial. | 13345 // some kind of user interaction the performance is not crucial. |
14544 static Handle<Object> Runtime_GetScriptFromScriptName( | 13346 static Handle<Object> Runtime_GetScriptFromScriptName( |
14545 Handle<String> script_name) { | 13347 Handle<String> script_name) { |
14546 // Scan the heap for Script objects to find the script with the requested | 13348 // Scan the heap for Script objects to find the script with the requested |
14547 // script data. | 13349 // script data. |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14672 } | 13474 } |
14673 | 13475 |
14674 return isolate->heap()->undefined_value(); | 13476 return isolate->heap()->undefined_value(); |
14675 } | 13477 } |
14676 | 13478 |
14677 | 13479 |
14678 RUNTIME_FUNCTION(Runtime_Abort) { | 13480 RUNTIME_FUNCTION(Runtime_Abort) { |
14679 SealHandleScope shs(isolate); | 13481 SealHandleScope shs(isolate); |
14680 DCHECK(args.length() == 1); | 13482 DCHECK(args.length() == 1); |
14681 CONVERT_SMI_ARG_CHECKED(message_id, 0); | 13483 CONVERT_SMI_ARG_CHECKED(message_id, 0); |
14682 const char* message = GetBailoutReason( | 13484 const char* message = |
14683 static_cast<BailoutReason>(message_id)); | 13485 GetBailoutReason(static_cast<BailoutReason>(message_id)); |
14684 base::OS::PrintError("abort: %s\n", message); | 13486 base::OS::PrintError("abort: %s\n", message); |
14685 isolate->PrintStack(stderr); | 13487 isolate->PrintStack(stderr); |
14686 base::OS::Abort(); | 13488 base::OS::Abort(); |
14687 UNREACHABLE(); | 13489 UNREACHABLE(); |
14688 return NULL; | 13490 return NULL; |
14689 } | 13491 } |
14690 | 13492 |
14691 | 13493 |
14692 RUNTIME_FUNCTION(Runtime_AbortJS) { | 13494 RUNTIME_FUNCTION(Runtime_AbortJS) { |
14693 HandleScope scope(isolate); | 13495 HandleScope scope(isolate); |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14763 { | 13565 { |
14764 DisallowHeapAllocation no_alloc; | 13566 DisallowHeapAllocation no_alloc; |
14765 | 13567 |
14766 int finger_index = cache->finger_index(); | 13568 int finger_index = cache->finger_index(); |
14767 Object* o = cache->get(finger_index); | 13569 Object* o = cache->get(finger_index); |
14768 if (o == key) { | 13570 if (o == key) { |
14769 // The fastest case: hit the same place again. | 13571 // The fastest case: hit the same place again. |
14770 return cache->get(finger_index + 1); | 13572 return cache->get(finger_index + 1); |
14771 } | 13573 } |
14772 | 13574 |
14773 for (int i = finger_index - 2; | 13575 for (int i = finger_index - 2; i >= JSFunctionResultCache::kEntriesIndex; |
14774 i >= JSFunctionResultCache::kEntriesIndex; | |
14775 i -= 2) { | 13576 i -= 2) { |
14776 o = cache->get(i); | 13577 o = cache->get(i); |
14777 if (o == key) { | 13578 if (o == key) { |
14778 cache->set_finger_index(i); | 13579 cache->set_finger_index(i); |
14779 return cache->get(i + 1); | 13580 return cache->get(i + 1); |
14780 } | 13581 } |
14781 } | 13582 } |
14782 | 13583 |
14783 int size = cache->size(); | 13584 int size = cache->size(); |
14784 DCHECK(size <= cache->length()); | 13585 DCHECK(size <= cache->length()); |
14785 | 13586 |
14786 for (int i = size - 2; i > finger_index; i -= 2) { | 13587 for (int i = size - 2; i > finger_index; i -= 2) { |
14787 o = cache->get(i); | 13588 o = cache->get(i); |
14788 if (o == key) { | 13589 if (o == key) { |
14789 cache->set_finger_index(i); | 13590 cache->set_finger_index(i); |
14790 return cache->get(i + 1); | 13591 return cache->get(i + 1); |
14791 } | 13592 } |
14792 } | 13593 } |
14793 } | 13594 } |
14794 | 13595 |
14795 // There is no value in the cache. Invoke the function and cache result. | 13596 // There is no value in the cache. Invoke the function and cache result. |
14796 HandleScope scope(isolate); | 13597 HandleScope scope(isolate); |
14797 | 13598 |
14798 Handle<JSFunctionResultCache> cache_handle(cache); | 13599 Handle<JSFunctionResultCache> cache_handle(cache); |
14799 Handle<Object> key_handle(key, isolate); | 13600 Handle<Object> key_handle(key, isolate); |
14800 Handle<Object> value; | 13601 Handle<Object> value; |
14801 { | 13602 { |
14802 Handle<JSFunction> factory(JSFunction::cast( | 13603 Handle<JSFunction> factory(JSFunction::cast( |
14803 cache_handle->get(JSFunctionResultCache::kFactoryIndex))); | 13604 cache_handle->get(JSFunctionResultCache::kFactoryIndex))); |
14804 // TODO(antonm): consider passing a receiver when constructing a cache. | 13605 // TODO(antonm): consider passing a receiver when constructing a cache. |
14805 Handle<JSObject> receiver(isolate->global_proxy()); | 13606 Handle<JSObject> receiver(isolate->global_proxy()); |
14806 // This handle is nor shared, nor used later, so it's safe. | 13607 // This handle is nor shared, nor used later, so it's safe. |
14807 Handle<Object> argv[] = { key_handle }; | 13608 Handle<Object> argv[] = {key_handle}; |
14808 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 13609 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
14809 isolate, value, | 13610 isolate, value, |
14810 Execution::Call(isolate, factory, receiver, arraysize(argv), argv)); | 13611 Execution::Call(isolate, factory, receiver, arraysize(argv), argv)); |
14811 } | 13612 } |
14812 | 13613 |
14813 #ifdef VERIFY_HEAP | 13614 #ifdef VERIFY_HEAP |
14814 if (FLAG_verify_heap) { | 13615 if (FLAG_verify_heap) { |
14815 cache_handle->JSFunctionResultCacheVerify(); | 13616 cache_handle->JSFunctionResultCacheVerify(); |
14816 } | 13617 } |
14817 #endif | 13618 #endif |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14866 return message->script(); | 13667 return message->script(); |
14867 } | 13668 } |
14868 | 13669 |
14869 | 13670 |
14870 #ifdef DEBUG | 13671 #ifdef DEBUG |
14871 // ListNatives is ONLY used by the fuzz-natives.js in debug mode | 13672 // ListNatives is ONLY used by the fuzz-natives.js in debug mode |
14872 // Exclude the code in release mode. | 13673 // Exclude the code in release mode. |
14873 RUNTIME_FUNCTION(Runtime_ListNatives) { | 13674 RUNTIME_FUNCTION(Runtime_ListNatives) { |
14874 HandleScope scope(isolate); | 13675 HandleScope scope(isolate); |
14875 DCHECK(args.length() == 0); | 13676 DCHECK(args.length() == 0); |
14876 #define COUNT_ENTRY(Name, argc, ressize) + 1 | 13677 #define COUNT_ENTRY(Name, argc, ressize) +1 |
14877 int entry_count = 0 | 13678 int entry_count = |
14878 RUNTIME_FUNCTION_LIST(COUNT_ENTRY) | 13679 0 RUNTIME_FUNCTION_LIST(COUNT_ENTRY) INLINE_FUNCTION_LIST(COUNT_ENTRY) |
14879 INLINE_FUNCTION_LIST(COUNT_ENTRY) | |
14880 INLINE_OPTIMIZED_FUNCTION_LIST(COUNT_ENTRY); | 13680 INLINE_OPTIMIZED_FUNCTION_LIST(COUNT_ENTRY); |
14881 #undef COUNT_ENTRY | 13681 #undef COUNT_ENTRY |
14882 Factory* factory = isolate->factory(); | 13682 Factory* factory = isolate->factory(); |
14883 Handle<FixedArray> elements = factory->NewFixedArray(entry_count); | 13683 Handle<FixedArray> elements = factory->NewFixedArray(entry_count); |
14884 int index = 0; | 13684 int index = 0; |
14885 bool inline_runtime_functions = false; | 13685 bool inline_runtime_functions = false; |
14886 #define ADD_ENTRY(Name, argc, ressize) \ | 13686 #define ADD_ENTRY(Name, argc, ressize) \ |
14887 { \ | 13687 { \ |
14888 HandleScope inner(isolate); \ | 13688 HandleScope inner(isolate); \ |
14889 Handle<String> name; \ | 13689 Handle<String> name; \ |
(...skipping 21 matching lines...) Expand all Loading... |
14911 } | 13711 } |
14912 #endif | 13712 #endif |
14913 | 13713 |
14914 | 13714 |
14915 RUNTIME_FUNCTION(Runtime_IS_VAR) { | 13715 RUNTIME_FUNCTION(Runtime_IS_VAR) { |
14916 UNREACHABLE(); // implemented as macro in the parser | 13716 UNREACHABLE(); // implemented as macro in the parser |
14917 return NULL; | 13717 return NULL; |
14918 } | 13718 } |
14919 | 13719 |
14920 | 13720 |
14921 #define ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(Name) \ | 13721 #define ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(Name) \ |
14922 RUNTIME_FUNCTION(Runtime_Has##Name) { \ | 13722 RUNTIME_FUNCTION(Runtime_Has##Name) { \ |
14923 CONVERT_ARG_CHECKED(JSObject, obj, 0); \ | 13723 CONVERT_ARG_CHECKED(JSObject, obj, 0); \ |
14924 return isolate->heap()->ToBoolean(obj->Has##Name()); \ | 13724 return isolate->heap()->ToBoolean(obj->Has##Name()); \ |
14925 } | 13725 } |
14926 | 13726 |
14927 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastSmiElements) | 13727 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastSmiElements) |
14928 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastObjectElements) | 13728 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastObjectElements) |
14929 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastSmiOrObjectElements) | 13729 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastSmiOrObjectElements) |
14930 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastDoubleElements) | 13730 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastDoubleElements) |
14931 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastHoleyElements) | 13731 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastHoleyElements) |
14932 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(DictionaryElements) | 13732 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(DictionaryElements) |
14933 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(SloppyArgumentsElements) | 13733 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(SloppyArgumentsElements) |
14934 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalArrayElements) | 13734 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalArrayElements) |
14935 // Properties test sitting with elements tests - not fooling anyone. | 13735 // Properties test sitting with elements tests - not fooling anyone. |
14936 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastProperties) | 13736 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastProperties) |
14937 | 13737 |
14938 #undef ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION | 13738 #undef ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION |
14939 | 13739 |
14940 | 13740 |
14941 #define TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION(Type, type, TYPE, ctype, size) \ | 13741 #define TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION(Type, type, TYPE, ctype, size) \ |
14942 RUNTIME_FUNCTION(Runtime_HasExternal##Type##Elements) { \ | 13742 RUNTIME_FUNCTION(Runtime_HasExternal##Type##Elements) { \ |
14943 CONVERT_ARG_CHECKED(JSObject, obj, 0); \ | 13743 CONVERT_ARG_CHECKED(JSObject, obj, 0); \ |
14944 return isolate->heap()->ToBoolean(obj->HasExternal##Type##Elements()); \ | 13744 return isolate->heap()->ToBoolean(obj->HasExternal##Type##Elements()); \ |
14945 } | 13745 } |
14946 | 13746 |
14947 TYPED_ARRAYS(TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION) | 13747 TYPED_ARRAYS(TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION) |
14948 | 13748 |
14949 #undef TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION | 13749 #undef TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION |
14950 | 13750 |
14951 | 13751 |
14952 #define FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION(Type, type, TYPE, ctype, s) \ | 13752 #define FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION(Type, type, TYPE, ctype, s) \ |
14953 RUNTIME_FUNCTION(Runtime_HasFixed##Type##Elements) { \ | 13753 RUNTIME_FUNCTION(Runtime_HasFixed##Type##Elements) { \ |
14954 CONVERT_ARG_CHECKED(JSObject, obj, 0); \ | 13754 CONVERT_ARG_CHECKED(JSObject, obj, 0); \ |
14955 return isolate->heap()->ToBoolean(obj->HasFixed##Type##Elements()); \ | 13755 return isolate->heap()->ToBoolean(obj->HasFixed##Type##Elements()); \ |
14956 } | 13756 } |
14957 | 13757 |
14958 TYPED_ARRAYS(FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION) | 13758 TYPED_ARRAYS(FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION) |
14959 | 13759 |
14960 #undef FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION | 13760 #undef FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION |
14961 | 13761 |
14962 | 13762 |
14963 RUNTIME_FUNCTION(Runtime_HaveSameMap) { | 13763 RUNTIME_FUNCTION(Runtime_HaveSameMap) { |
14964 SealHandleScope shs(isolate); | 13764 SealHandleScope shs(isolate); |
14965 DCHECK(args.length() == 2); | 13765 DCHECK(args.length() == 2); |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15098 HandleScope scope(isolate); | 13898 HandleScope scope(isolate); |
15099 DCHECK(args.length() == 1); | 13899 DCHECK(args.length() == 1); |
15100 CONVERT_ARG_HANDLE_CHECKED(JSObject, object_info, 0); | 13900 CONVERT_ARG_HANDLE_CHECKED(JSObject, object_info, 0); |
15101 | 13901 |
15102 Handle<Context> context(object_info->GetCreationContext(), isolate); | 13902 Handle<Context> context(object_info->GetCreationContext(), isolate); |
15103 return context->native_object_notifier_perform_change(); | 13903 return context->native_object_notifier_perform_change(); |
15104 } | 13904 } |
15105 | 13905 |
15106 | 13906 |
15107 static Object* ArrayConstructorCommon(Isolate* isolate, | 13907 static Object* ArrayConstructorCommon(Isolate* isolate, |
15108 Handle<JSFunction> constructor, | 13908 Handle<JSFunction> constructor, |
15109 Handle<AllocationSite> site, | 13909 Handle<AllocationSite> site, |
15110 Arguments* caller_args) { | 13910 Arguments* caller_args) { |
15111 Factory* factory = isolate->factory(); | 13911 Factory* factory = isolate->factory(); |
15112 | 13912 |
15113 bool holey = false; | 13913 bool holey = false; |
15114 bool can_use_type_feedback = true; | 13914 bool can_use_type_feedback = true; |
15115 if (caller_args->length() == 1) { | 13915 if (caller_args->length() == 1) { |
15116 Handle<Object> argument_one = caller_args->at<Object>(0); | 13916 Handle<Object> argument_one = caller_args->at<Object>(0); |
15117 if (argument_one->IsSmi()) { | 13917 if (argument_one->IsSmi()) { |
15118 int value = Handle<Smi>::cast(argument_one)->value(); | 13918 int value = Handle<Smi>::cast(argument_one)->value(); |
15119 if (value < 0 || value >= JSObject::kInitialMaxFastElementArray) { | 13919 if (value < 0 || value >= JSObject::kInitialMaxFastElementArray) { |
15120 // the array is a dictionary in this case. | 13920 // the array is a dictionary in this case. |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15164 JSObject::TransitionElementsKind(array, kind); | 13964 JSObject::TransitionElementsKind(array, kind); |
15165 } | 13965 } |
15166 } | 13966 } |
15167 | 13967 |
15168 factory->NewJSArrayStorage(array, 0, 0, DONT_INITIALIZE_ARRAY_ELEMENTS); | 13968 factory->NewJSArrayStorage(array, 0, 0, DONT_INITIALIZE_ARRAY_ELEMENTS); |
15169 | 13969 |
15170 ElementsKind old_kind = array->GetElementsKind(); | 13970 ElementsKind old_kind = array->GetElementsKind(); |
15171 RETURN_FAILURE_ON_EXCEPTION( | 13971 RETURN_FAILURE_ON_EXCEPTION( |
15172 isolate, ArrayConstructInitializeElements(array, caller_args)); | 13972 isolate, ArrayConstructInitializeElements(array, caller_args)); |
15173 if (!site.is_null() && | 13973 if (!site.is_null() && |
15174 (old_kind != array->GetElementsKind() || | 13974 (old_kind != array->GetElementsKind() || !can_use_type_feedback)) { |
15175 !can_use_type_feedback)) { | |
15176 // The arguments passed in caused a transition. This kind of complexity | 13975 // The arguments passed in caused a transition. This kind of complexity |
15177 // can't be dealt with in the inlined hydrogen array constructor case. | 13976 // can't be dealt with in the inlined hydrogen array constructor case. |
15178 // We must mark the allocationsite as un-inlinable. | 13977 // We must mark the allocationsite as un-inlinable. |
15179 site->SetDoNotInlineCall(); | 13978 site->SetDoNotInlineCall(); |
15180 } | 13979 } |
15181 return *array; | 13980 return *array; |
15182 } | 13981 } |
15183 | 13982 |
15184 | 13983 |
15185 RUNTIME_FUNCTION(Runtime_ArrayConstructor) { | 13984 RUNTIME_FUNCTION(Runtime_ArrayConstructor) { |
15186 HandleScope scope(isolate); | 13985 HandleScope scope(isolate); |
15187 // If we get 2 arguments then they are the stub parameters (constructor, type | 13986 // If we get 2 arguments then they are the stub parameters (constructor, type |
15188 // info). If we get 4, then the first one is a pointer to the arguments | 13987 // info). If we get 4, then the first one is a pointer to the arguments |
15189 // passed by the caller, and the last one is the length of the arguments | 13988 // passed by the caller, and the last one is the length of the arguments |
15190 // passed to the caller (redundant, but useful to check on the deoptimizer | 13989 // passed to the caller (redundant, but useful to check on the deoptimizer |
15191 // with an assert). | 13990 // with an assert). |
15192 Arguments empty_args(0, NULL); | 13991 Arguments empty_args(0, NULL); |
15193 bool no_caller_args = args.length() == 2; | 13992 bool no_caller_args = args.length() == 2; |
15194 DCHECK(no_caller_args || args.length() == 4); | 13993 DCHECK(no_caller_args || args.length() == 4); |
15195 int parameters_start = no_caller_args ? 0 : 1; | 13994 int parameters_start = no_caller_args ? 0 : 1; |
15196 Arguments* caller_args = no_caller_args | 13995 Arguments* caller_args = |
15197 ? &empty_args | 13996 no_caller_args ? &empty_args : reinterpret_cast<Arguments*>(args[0]); |
15198 : reinterpret_cast<Arguments*>(args[0]); | |
15199 CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, parameters_start); | 13997 CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, parameters_start); |
15200 CONVERT_ARG_HANDLE_CHECKED(Object, type_info, parameters_start + 1); | 13998 CONVERT_ARG_HANDLE_CHECKED(Object, type_info, parameters_start + 1); |
15201 #ifdef DEBUG | 13999 #ifdef DEBUG |
15202 if (!no_caller_args) { | 14000 if (!no_caller_args) { |
15203 CONVERT_SMI_ARG_CHECKED(arg_count, parameters_start + 2); | 14001 CONVERT_SMI_ARG_CHECKED(arg_count, parameters_start + 2); |
15204 DCHECK(arg_count == caller_args->length()); | 14002 DCHECK(arg_count == caller_args->length()); |
15205 } | 14003 } |
15206 #endif | 14004 #endif |
15207 | 14005 |
15208 Handle<AllocationSite> site; | 14006 Handle<AllocationSite> site; |
15209 if (!type_info.is_null() && | 14007 if (!type_info.is_null() && |
15210 *type_info != isolate->heap()->undefined_value()) { | 14008 *type_info != isolate->heap()->undefined_value()) { |
15211 site = Handle<AllocationSite>::cast(type_info); | 14009 site = Handle<AllocationSite>::cast(type_info); |
15212 DCHECK(!site->SitePointsToLiteral()); | 14010 DCHECK(!site->SitePointsToLiteral()); |
15213 } | 14011 } |
15214 | 14012 |
15215 return ArrayConstructorCommon(isolate, | 14013 return ArrayConstructorCommon(isolate, constructor, site, caller_args); |
15216 constructor, | |
15217 site, | |
15218 caller_args); | |
15219 } | 14014 } |
15220 | 14015 |
15221 | 14016 |
15222 RUNTIME_FUNCTION(Runtime_InternalArrayConstructor) { | 14017 RUNTIME_FUNCTION(Runtime_InternalArrayConstructor) { |
15223 HandleScope scope(isolate); | 14018 HandleScope scope(isolate); |
15224 Arguments empty_args(0, NULL); | 14019 Arguments empty_args(0, NULL); |
15225 bool no_caller_args = args.length() == 1; | 14020 bool no_caller_args = args.length() == 1; |
15226 DCHECK(no_caller_args || args.length() == 3); | 14021 DCHECK(no_caller_args || args.length() == 3); |
15227 int parameters_start = no_caller_args ? 0 : 1; | 14022 int parameters_start = no_caller_args ? 0 : 1; |
15228 Arguments* caller_args = no_caller_args | 14023 Arguments* caller_args = |
15229 ? &empty_args | 14024 no_caller_args ? &empty_args : reinterpret_cast<Arguments*>(args[0]); |
15230 : reinterpret_cast<Arguments*>(args[0]); | |
15231 CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, parameters_start); | 14025 CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, parameters_start); |
15232 #ifdef DEBUG | 14026 #ifdef DEBUG |
15233 if (!no_caller_args) { | 14027 if (!no_caller_args) { |
15234 CONVERT_SMI_ARG_CHECKED(arg_count, parameters_start + 1); | 14028 CONVERT_SMI_ARG_CHECKED(arg_count, parameters_start + 1); |
15235 DCHECK(arg_count == caller_args->length()); | 14029 DCHECK(arg_count == caller_args->length()); |
15236 } | 14030 } |
15237 #endif | 14031 #endif |
15238 return ArrayConstructorCommon(isolate, | 14032 return ArrayConstructorCommon(isolate, constructor, |
15239 constructor, | 14033 Handle<AllocationSite>::null(), caller_args); |
15240 Handle<AllocationSite>::null(), | |
15241 caller_args); | |
15242 } | 14034 } |
15243 | 14035 |
15244 | 14036 |
15245 RUNTIME_FUNCTION(Runtime_NormalizeElements) { | 14037 RUNTIME_FUNCTION(Runtime_NormalizeElements) { |
15246 HandleScope scope(isolate); | 14038 HandleScope scope(isolate); |
15247 DCHECK(args.length() == 1); | 14039 DCHECK(args.length() == 1); |
15248 CONVERT_ARG_HANDLE_CHECKED(JSObject, array, 0); | 14040 CONVERT_ARG_HANDLE_CHECKED(JSObject, array, 0); |
15249 RUNTIME_ASSERT(!array->HasExternalArrayElements() && | 14041 RUNTIME_ASSERT(!array->HasExternalArrayElements() && |
15250 !array->HasFixedTypedArrayElements()); | 14042 !array->HasFixedTypedArrayElements()); |
15251 JSObject::NormalizeElements(array); | 14043 JSObject::NormalizeElements(array); |
(...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15693 | 14485 |
15694 #define IO(name, number_of_args, result_size) \ | 14486 #define IO(name, number_of_args, result_size) \ |
15695 { \ | 14487 { \ |
15696 Runtime::kInlineOptimized##name, Runtime::INLINE_OPTIMIZED, "_" #name, \ | 14488 Runtime::kInlineOptimized##name, Runtime::INLINE_OPTIMIZED, "_" #name, \ |
15697 FUNCTION_ADDR(Runtime_##name), number_of_args, result_size \ | 14489 FUNCTION_ADDR(Runtime_##name), number_of_args, result_size \ |
15698 } \ | 14490 } \ |
15699 , | 14491 , |
15700 | 14492 |
15701 | 14493 |
15702 static const Runtime::Function kIntrinsicFunctions[] = { | 14494 static const Runtime::Function kIntrinsicFunctions[] = { |
15703 RUNTIME_FUNCTION_LIST(F) | 14495 RUNTIME_FUNCTION_LIST(F) INLINE_OPTIMIZED_FUNCTION_LIST(F) |
15704 INLINE_OPTIMIZED_FUNCTION_LIST(F) | 14496 INLINE_FUNCTION_LIST(I) INLINE_OPTIMIZED_FUNCTION_LIST(IO)}; |
15705 INLINE_FUNCTION_LIST(I) | |
15706 INLINE_OPTIMIZED_FUNCTION_LIST(IO) | |
15707 }; | |
15708 | 14497 |
15709 #undef IO | 14498 #undef IO |
15710 #undef I | 14499 #undef I |
15711 #undef F | 14500 #undef F |
15712 | 14501 |
15713 | 14502 |
15714 void Runtime::InitializeIntrinsicFunctionNames(Isolate* isolate, | 14503 void Runtime::InitializeIntrinsicFunctionNames(Isolate* isolate, |
15715 Handle<NameDictionary> dict) { | 14504 Handle<NameDictionary> dict) { |
15716 DCHECK(dict->NumberOfElements() == 0); | 14505 DCHECK(dict->NumberOfElements() == 0); |
15717 HandleScope scope(isolate); | 14506 HandleScope scope(isolate); |
15718 for (int i = 0; i < kNumFunctions; ++i) { | 14507 for (int i = 0; i < kNumFunctions; ++i) { |
15719 const char* name = kIntrinsicFunctions[i].name; | 14508 const char* name = kIntrinsicFunctions[i].name; |
15720 if (name == NULL) continue; | 14509 if (name == NULL) continue; |
15721 Handle<NameDictionary> new_dict = NameDictionary::Add( | 14510 Handle<NameDictionary> new_dict = NameDictionary::Add( |
15722 dict, | 14511 dict, isolate->factory()->InternalizeUtf8String(name), |
15723 isolate->factory()->InternalizeUtf8String(name), | |
15724 Handle<Smi>(Smi::FromInt(i), isolate), | 14512 Handle<Smi>(Smi::FromInt(i), isolate), |
15725 PropertyDetails(NONE, NORMAL, Representation::None())); | 14513 PropertyDetails(NONE, NORMAL, Representation::None())); |
15726 // The dictionary does not need to grow. | 14514 // The dictionary does not need to grow. |
15727 CHECK(new_dict.is_identical_to(dict)); | 14515 CHECK(new_dict.is_identical_to(dict)); |
15728 } | 14516 } |
15729 } | 14517 } |
15730 | 14518 |
15731 | 14519 |
15732 const Runtime::Function* Runtime::FunctionForName(Handle<String> name) { | 14520 const Runtime::Function* Runtime::FunctionForName(Handle<String> name) { |
15733 Heap* heap = name->GetHeap(); | 14521 Heap* heap = name->GetHeap(); |
(...skipping 13 matching lines...) Expand all Loading... |
15747 return &(kIntrinsicFunctions[i]); | 14535 return &(kIntrinsicFunctions[i]); |
15748 } | 14536 } |
15749 } | 14537 } |
15750 return NULL; | 14538 return NULL; |
15751 } | 14539 } |
15752 | 14540 |
15753 | 14541 |
15754 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { | 14542 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { |
15755 return &(kIntrinsicFunctions[static_cast<int>(id)]); | 14543 return &(kIntrinsicFunctions[static_cast<int>(id)]); |
15756 } | 14544 } |
15757 | 14545 } |
15758 } } // namespace v8::internal | 14546 } // namespace v8::internal |
OLD | NEW |