Upstream version 8.37.186.0
[platform/framework/web/crosswalk.git] / src / v8 / src / runtime.cc
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
3 // found in the LICENSE file.
4
5 #include <stdlib.h>
6 #include <limits>
7
8 #include "src/v8.h"
9
10 #include "src/accessors.h"
11 #include "src/allocation-site-scopes.h"
12 #include "src/api.h"
13 #include "src/arguments.h"
14 #include "src/bootstrapper.h"
15 #include "src/codegen.h"
16 #include "src/compilation-cache.h"
17 #include "src/compiler.h"
18 #include "src/conversions.h"
19 #include "src/cpu.h"
20 #include "src/cpu-profiler.h"
21 #include "src/dateparser-inl.h"
22 #include "src/debug.h"
23 #include "src/deoptimizer.h"
24 #include "src/date.h"
25 #include "src/execution.h"
26 #include "src/full-codegen.h"
27 #include "src/global-handles.h"
28 #include "src/isolate-inl.h"
29 #include "src/jsregexp.h"
30 #include "src/jsregexp-inl.h"
31 #include "src/json-parser.h"
32 #include "src/json-stringifier.h"
33 #include "src/liveedit.h"
34 #include "src/misc-intrinsics.h"
35 #include "src/parser.h"
36 #include "src/platform.h"
37 #include "src/runtime-profiler.h"
38 #include "src/runtime.h"
39 #include "src/scopeinfo.h"
40 #include "src/smart-pointers.h"
41 #include "src/string-search.h"
42 #include "src/stub-cache.h"
43 #include "src/uri.h"
44 #include "src/v8threads.h"
45 #include "src/vm-state-inl.h"
46
47 #ifdef V8_I18N_SUPPORT
48 #include "src/i18n.h"
49 #include "unicode/brkiter.h"
50 #include "unicode/calendar.h"
51 #include "unicode/coll.h"
52 #include "unicode/curramt.h"
53 #include "unicode/datefmt.h"
54 #include "unicode/dcfmtsym.h"
55 #include "unicode/decimfmt.h"
56 #include "unicode/dtfmtsym.h"
57 #include "unicode/dtptngen.h"
58 #include "unicode/locid.h"
59 #include "unicode/numfmt.h"
60 #include "unicode/numsys.h"
61 #include "unicode/rbbi.h"
62 #include "unicode/smpdtfmt.h"
63 #include "unicode/timezone.h"
64 #include "unicode/uchar.h"
65 #include "unicode/ucol.h"
66 #include "unicode/ucurr.h"
67 #include "unicode/uloc.h"
68 #include "unicode/unum.h"
69 #include "unicode/uversion.h"
70 #endif
71
72 #ifndef _STLP_VENDOR_CSTD
73 // STLPort doesn't import fpclassify and isless into the std namespace.
74 using std::fpclassify;
75 using std::isless;
76 #endif
77
78 namespace v8 {
79 namespace internal {
80
81
82 #define RUNTIME_ASSERT(value) \
83   if (!(value)) return isolate->ThrowIllegalOperation();
84
85 #define RUNTIME_ASSERT_HANDLIFIED(value, T)                          \
86   if (!(value)) {                                                    \
87     isolate->ThrowIllegalOperation();                                \
88     return MaybeHandle<T>();                                         \
89   }
90
91 // Cast the given object to a value of the specified type and store
92 // it in a variable with the given name.  If the object is not of the
93 // expected type call IllegalOperation and return.
94 #define CONVERT_ARG_CHECKED(Type, name, index)                       \
95   RUNTIME_ASSERT(args[index]->Is##Type());                           \
96   Type* name = Type::cast(args[index]);
97
98 #define CONVERT_ARG_HANDLE_CHECKED(Type, name, index)                \
99   RUNTIME_ASSERT(args[index]->Is##Type());                           \
100   Handle<Type> name = args.at<Type>(index);
101
102 #define CONVERT_NUMBER_ARG_HANDLE_CHECKED(name, index)               \
103   RUNTIME_ASSERT(args[index]->IsNumber());                           \
104   Handle<Object> name = args.at<Object>(index);
105
106 // Cast the given object to a boolean and store it in a variable with
107 // the given name.  If the object is not a boolean call IllegalOperation
108 // and return.
109 #define CONVERT_BOOLEAN_ARG_CHECKED(name, index)                     \
110   RUNTIME_ASSERT(args[index]->IsBoolean());                          \
111   bool name = args[index]->IsTrue();
112
113 // Cast the given argument to a Smi and store its value in an int variable
114 // with the given name.  If the argument is not a Smi call IllegalOperation
115 // and return.
116 #define CONVERT_SMI_ARG_CHECKED(name, index)                         \
117   RUNTIME_ASSERT(args[index]->IsSmi());                              \
118   int name = args.smi_at(index);
119
120 // Cast the given argument to a double and store it in a variable with
121 // the given name.  If the argument is not a number (as opposed to
122 // the number not-a-number) call IllegalOperation and return.
123 #define CONVERT_DOUBLE_ARG_CHECKED(name, index)                      \
124   RUNTIME_ASSERT(args[index]->IsNumber());                           \
125   double name = args.number_at(index);
126
127 // Call the specified converter on the object *comand store the result in
128 // a variable of the specified type with the given name.  If the
129 // object is not a Number call IllegalOperation and return.
130 #define CONVERT_NUMBER_CHECKED(type, name, Type, obj)                \
131   RUNTIME_ASSERT(obj->IsNumber());                                   \
132   type name = NumberTo##Type(obj);
133
134
135 // Cast the given argument to PropertyDetails and store its value in a
136 // variable with the given name.  If the argument is not a Smi call
137 // IllegalOperation and return.
138 #define CONVERT_PROPERTY_DETAILS_CHECKED(name, index)                \
139   RUNTIME_ASSERT(args[index]->IsSmi());                              \
140   PropertyDetails name = PropertyDetails(Smi::cast(args[index]));
141
142
143 // Assert that the given argument has a valid value for a StrictMode
144 // and store it in a StrictMode variable with the given name.
145 #define CONVERT_STRICT_MODE_ARG_CHECKED(name, index)                 \
146   RUNTIME_ASSERT(args[index]->IsSmi());                              \
147   RUNTIME_ASSERT(args.smi_at(index) == STRICT ||                     \
148                  args.smi_at(index) == SLOPPY);                      \
149   StrictMode name = static_cast<StrictMode>(args.smi_at(index));
150
151
152 static Handle<Map> ComputeObjectLiteralMap(
153     Handle<Context> context,
154     Handle<FixedArray> constant_properties,
155     bool* is_result_from_cache) {
156   Isolate* isolate = context->GetIsolate();
157   int properties_length = constant_properties->length();
158   int number_of_properties = properties_length / 2;
159   // Check that there are only internal strings and array indices among keys.
160   int number_of_string_keys = 0;
161   for (int p = 0; p != properties_length; p += 2) {
162     Object* key = constant_properties->get(p);
163     uint32_t element_index = 0;
164     if (key->IsInternalizedString()) {
165       number_of_string_keys++;
166     } else if (key->ToArrayIndex(&element_index)) {
167       // An index key does not require space in the property backing store.
168       number_of_properties--;
169     } else {
170       // Bail out as a non-internalized-string non-index key makes caching
171       // impossible.
172       // ASSERT to make sure that the if condition after the loop is false.
173       ASSERT(number_of_string_keys != number_of_properties);
174       break;
175     }
176   }
177   // If we only have internalized strings and array indices among keys then we
178   // can use the map cache in the native context.
179   const int kMaxKeys = 10;
180   if ((number_of_string_keys == number_of_properties) &&
181       (number_of_string_keys < kMaxKeys)) {
182     // Create the fixed array with the key.
183     Handle<FixedArray> keys =
184         isolate->factory()->NewFixedArray(number_of_string_keys);
185     if (number_of_string_keys > 0) {
186       int index = 0;
187       for (int p = 0; p < properties_length; p += 2) {
188         Object* key = constant_properties->get(p);
189         if (key->IsInternalizedString()) {
190           keys->set(index++, key);
191         }
192       }
193       ASSERT(index == number_of_string_keys);
194     }
195     *is_result_from_cache = true;
196     return isolate->factory()->ObjectLiteralMapFromCache(context, keys);
197   }
198   *is_result_from_cache = false;
199   return Map::Create(handle(context->object_function()), number_of_properties);
200 }
201
202
203 MUST_USE_RESULT static MaybeHandle<Object> CreateLiteralBoilerplate(
204     Isolate* isolate,
205     Handle<FixedArray> literals,
206     Handle<FixedArray> constant_properties);
207
208
209 MUST_USE_RESULT static MaybeHandle<Object> CreateObjectLiteralBoilerplate(
210     Isolate* isolate,
211     Handle<FixedArray> literals,
212     Handle<FixedArray> constant_properties,
213     bool should_have_fast_elements,
214     bool has_function_literal) {
215   // Get the native context from the literals array.  This is the
216   // context in which the function was created and we use the object
217   // function from this context to create the object literal.  We do
218   // not use the object function from the current native context
219   // because this might be the object function from another context
220   // which we should not have access to.
221   Handle<Context> context =
222       Handle<Context>(JSFunction::NativeContextFromLiterals(*literals));
223
224   // In case we have function literals, we want the object to be in
225   // slow properties mode for now. We don't go in the map cache because
226   // maps with constant functions can't be shared if the functions are
227   // not the same (which is the common case).
228   bool is_result_from_cache = false;
229   Handle<Map> map = has_function_literal
230       ? Handle<Map>(context->object_function()->initial_map())
231       : ComputeObjectLiteralMap(context,
232                                 constant_properties,
233                                 &is_result_from_cache);
234
235   PretenureFlag pretenure_flag =
236       isolate->heap()->InNewSpace(*literals) ? NOT_TENURED : TENURED;
237
238   Handle<JSObject> boilerplate =
239       isolate->factory()->NewJSObjectFromMap(map, pretenure_flag);
240
241   // Normalize the elements of the boilerplate to save space if needed.
242   if (!should_have_fast_elements) JSObject::NormalizeElements(boilerplate);
243
244   // Add the constant properties to the boilerplate.
245   int length = constant_properties->length();
246   bool should_transform =
247       !is_result_from_cache && boilerplate->HasFastProperties();
248   bool should_normalize = should_transform || has_function_literal;
249   if (should_normalize) {
250     // TODO(verwaest): We might not want to ever normalize here.
251     JSObject::NormalizeProperties(
252         boilerplate, KEEP_INOBJECT_PROPERTIES, length / 2);
253   }
254   Object::ValueType value_type = should_normalize
255       ? Object::FORCE_TAGGED : Object::OPTIMAL_REPRESENTATION;
256
257   // TODO(verwaest): Support tracking representations in the boilerplate.
258   for (int index = 0; index < length; index +=2) {
259     Handle<Object> key(constant_properties->get(index+0), isolate);
260     Handle<Object> value(constant_properties->get(index+1), isolate);
261     if (value->IsFixedArray()) {
262       // The value contains the constant_properties of a
263       // simple object or array literal.
264       Handle<FixedArray> array = Handle<FixedArray>::cast(value);
265       ASSIGN_RETURN_ON_EXCEPTION(
266           isolate, value,
267           CreateLiteralBoilerplate(isolate, literals, array),
268           Object);
269     }
270     MaybeHandle<Object> maybe_result;
271     uint32_t element_index = 0;
272     StoreMode mode = value->IsJSObject() ? FORCE_FIELD : ALLOW_AS_CONSTANT;
273     if (key->IsInternalizedString()) {
274       if (Handle<String>::cast(key)->AsArrayIndex(&element_index)) {
275         // Array index as string (uint32).
276         maybe_result = JSObject::SetOwnElement(
277             boilerplate, element_index, value, SLOPPY);
278       } else {
279         Handle<String> name(String::cast(*key));
280         ASSERT(!name->AsArrayIndex(&element_index));
281         maybe_result = JSObject::SetOwnPropertyIgnoreAttributes(
282             boilerplate, name, value, NONE,
283             value_type, mode);
284       }
285     } else if (key->ToArrayIndex(&element_index)) {
286       // Array index (uint32).
287       maybe_result = JSObject::SetOwnElement(
288           boilerplate, element_index, value, SLOPPY);
289     } else {
290       // Non-uint32 number.
291       ASSERT(key->IsNumber());
292       double num = key->Number();
293       char arr[100];
294       Vector<char> buffer(arr, ARRAY_SIZE(arr));
295       const char* str = DoubleToCString(num, buffer);
296       Handle<String> name = isolate->factory()->NewStringFromAsciiChecked(str);
297       maybe_result = JSObject::SetOwnPropertyIgnoreAttributes(
298           boilerplate, name, value, NONE,
299           value_type, mode);
300     }
301     // If setting the property on the boilerplate throws an
302     // exception, the exception is converted to an empty handle in
303     // the handle based operations.  In that case, we need to
304     // convert back to an exception.
305     RETURN_ON_EXCEPTION(isolate, maybe_result, Object);
306   }
307
308   // Transform to fast properties if necessary. For object literals with
309   // containing function literals we defer this operation until after all
310   // computed properties have been assigned so that we can generate
311   // constant function properties.
312   if (should_transform && !has_function_literal) {
313     JSObject::TransformToFastProperties(
314         boilerplate, boilerplate->map()->unused_property_fields());
315   }
316
317   return boilerplate;
318 }
319
320
321 MUST_USE_RESULT static MaybeHandle<Object> TransitionElements(
322     Handle<Object> object,
323     ElementsKind to_kind,
324     Isolate* isolate) {
325   HandleScope scope(isolate);
326   if (!object->IsJSObject()) {
327     isolate->ThrowIllegalOperation();
328     return MaybeHandle<Object>();
329   }
330   ElementsKind from_kind =
331       Handle<JSObject>::cast(object)->map()->elements_kind();
332   if (Map::IsValidElementsTransition(from_kind, to_kind)) {
333     JSObject::TransitionElementsKind(Handle<JSObject>::cast(object), to_kind);
334     return object;
335   }
336   isolate->ThrowIllegalOperation();
337   return MaybeHandle<Object>();
338 }
339
340
341 static const int kSmiLiteralMinimumLength = 1024;
342
343
344 MaybeHandle<Object> Runtime::CreateArrayLiteralBoilerplate(
345     Isolate* isolate,
346     Handle<FixedArray> literals,
347     Handle<FixedArray> elements) {
348   // Create the JSArray.
349   Handle<JSFunction> constructor(
350       JSFunction::NativeContextFromLiterals(*literals)->array_function());
351
352   PretenureFlag pretenure_flag =
353       isolate->heap()->InNewSpace(*literals) ? NOT_TENURED : TENURED;
354
355   Handle<JSArray> object = Handle<JSArray>::cast(
356       isolate->factory()->NewJSObject(constructor, pretenure_flag));
357
358   ElementsKind constant_elements_kind =
359       static_cast<ElementsKind>(Smi::cast(elements->get(0))->value());
360   Handle<FixedArrayBase> constant_elements_values(
361       FixedArrayBase::cast(elements->get(1)));
362
363   { DisallowHeapAllocation no_gc;
364     ASSERT(IsFastElementsKind(constant_elements_kind));
365     Context* native_context = isolate->context()->native_context();
366     Object* maps_array = native_context->js_array_maps();
367     ASSERT(!maps_array->IsUndefined());
368     Object* map = FixedArray::cast(maps_array)->get(constant_elements_kind);
369     object->set_map(Map::cast(map));
370   }
371
372   Handle<FixedArrayBase> copied_elements_values;
373   if (IsFastDoubleElementsKind(constant_elements_kind)) {
374     ASSERT(FLAG_smi_only_arrays);
375     copied_elements_values = isolate->factory()->CopyFixedDoubleArray(
376         Handle<FixedDoubleArray>::cast(constant_elements_values));
377   } else {
378     ASSERT(IsFastSmiOrObjectElementsKind(constant_elements_kind));
379     const bool is_cow =
380         (constant_elements_values->map() ==
381          isolate->heap()->fixed_cow_array_map());
382     if (is_cow) {
383       copied_elements_values = constant_elements_values;
384 #if DEBUG
385       Handle<FixedArray> fixed_array_values =
386           Handle<FixedArray>::cast(copied_elements_values);
387       for (int i = 0; i < fixed_array_values->length(); i++) {
388         ASSERT(!fixed_array_values->get(i)->IsFixedArray());
389       }
390 #endif
391     } else {
392       Handle<FixedArray> fixed_array_values =
393           Handle<FixedArray>::cast(constant_elements_values);
394       Handle<FixedArray> fixed_array_values_copy =
395           isolate->factory()->CopyFixedArray(fixed_array_values);
396       copied_elements_values = fixed_array_values_copy;
397       for (int i = 0; i < fixed_array_values->length(); i++) {
398         if (fixed_array_values->get(i)->IsFixedArray()) {
399           // The value contains the constant_properties of a
400           // simple object or array literal.
401           Handle<FixedArray> fa(FixedArray::cast(fixed_array_values->get(i)));
402           Handle<Object> result;
403           ASSIGN_RETURN_ON_EXCEPTION(
404               isolate, result,
405               CreateLiteralBoilerplate(isolate, literals, fa),
406               Object);
407           fixed_array_values_copy->set(i, *result);
408         }
409       }
410     }
411   }
412   object->set_elements(*copied_elements_values);
413   object->set_length(Smi::FromInt(copied_elements_values->length()));
414
415   //  Ensure that the boilerplate object has FAST_*_ELEMENTS, unless the flag is
416   //  on or the object is larger than the threshold.
417   if (!FLAG_smi_only_arrays &&
418       constant_elements_values->length() < kSmiLiteralMinimumLength) {
419     ElementsKind elements_kind = object->GetElementsKind();
420     if (!IsFastObjectElementsKind(elements_kind)) {
421       if (IsFastHoleyElementsKind(elements_kind)) {
422         TransitionElements(object, FAST_HOLEY_ELEMENTS, isolate).Check();
423       } else {
424         TransitionElements(object, FAST_ELEMENTS, isolate).Check();
425       }
426     }
427   }
428
429   JSObject::ValidateElements(object);
430   return object;
431 }
432
433
434 MUST_USE_RESULT static MaybeHandle<Object> CreateLiteralBoilerplate(
435     Isolate* isolate,
436     Handle<FixedArray> literals,
437     Handle<FixedArray> array) {
438   Handle<FixedArray> elements = CompileTimeValue::GetElements(array);
439   const bool kHasNoFunctionLiteral = false;
440   switch (CompileTimeValue::GetLiteralType(array)) {
441     case CompileTimeValue::OBJECT_LITERAL_FAST_ELEMENTS:
442       return CreateObjectLiteralBoilerplate(isolate,
443                                             literals,
444                                             elements,
445                                             true,
446                                             kHasNoFunctionLiteral);
447     case CompileTimeValue::OBJECT_LITERAL_SLOW_ELEMENTS:
448       return CreateObjectLiteralBoilerplate(isolate,
449                                             literals,
450                                             elements,
451                                             false,
452                                             kHasNoFunctionLiteral);
453     case CompileTimeValue::ARRAY_LITERAL:
454       return Runtime::CreateArrayLiteralBoilerplate(
455           isolate, literals, elements);
456     default:
457       UNREACHABLE();
458       return MaybeHandle<Object>();
459   }
460 }
461
462
463 RUNTIME_FUNCTION(RuntimeHidden_CreateObjectLiteral) {
464   HandleScope scope(isolate);
465   ASSERT(args.length() == 4);
466   CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
467   CONVERT_SMI_ARG_CHECKED(literals_index, 1);
468   CONVERT_ARG_HANDLE_CHECKED(FixedArray, constant_properties, 2);
469   CONVERT_SMI_ARG_CHECKED(flags, 3);
470   bool should_have_fast_elements = (flags & ObjectLiteral::kFastElements) != 0;
471   bool has_function_literal = (flags & ObjectLiteral::kHasFunction) != 0;
472
473   RUNTIME_ASSERT(literals_index >= 0 && literals_index < literals->length());
474
475   // Check if boilerplate exists. If not, create it first.
476   Handle<Object> literal_site(literals->get(literals_index), isolate);
477   Handle<AllocationSite> site;
478   Handle<JSObject> boilerplate;
479   if (*literal_site == isolate->heap()->undefined_value()) {
480     Handle<Object> raw_boilerplate;
481     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
482         isolate, raw_boilerplate,
483         CreateObjectLiteralBoilerplate(
484             isolate,
485             literals,
486             constant_properties,
487             should_have_fast_elements,
488             has_function_literal));
489     boilerplate = Handle<JSObject>::cast(raw_boilerplate);
490
491     AllocationSiteCreationContext creation_context(isolate);
492     site = creation_context.EnterNewScope();
493     RETURN_FAILURE_ON_EXCEPTION(
494         isolate,
495         JSObject::DeepWalk(boilerplate, &creation_context));
496     creation_context.ExitScope(site, boilerplate);
497
498     // Update the functions literal and return the boilerplate.
499     literals->set(literals_index, *site);
500   } else {
501     site = Handle<AllocationSite>::cast(literal_site);
502     boilerplate = Handle<JSObject>(JSObject::cast(site->transition_info()),
503                                    isolate);
504   }
505
506   AllocationSiteUsageContext usage_context(isolate, site, true);
507   usage_context.EnterNewScope();
508   MaybeHandle<Object> maybe_copy = JSObject::DeepCopy(
509       boilerplate, &usage_context);
510   usage_context.ExitScope(site, boilerplate);
511   Handle<Object> copy;
512   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, copy, maybe_copy);
513   return *copy;
514 }
515
516
517 MUST_USE_RESULT static MaybeHandle<AllocationSite> GetLiteralAllocationSite(
518     Isolate* isolate,
519     Handle<FixedArray> literals,
520     int literals_index,
521     Handle<FixedArray> elements) {
522   // Check if boilerplate exists. If not, create it first.
523   Handle<Object> literal_site(literals->get(literals_index), isolate);
524   Handle<AllocationSite> site;
525   if (*literal_site == isolate->heap()->undefined_value()) {
526     ASSERT(*elements != isolate->heap()->empty_fixed_array());
527     Handle<Object> boilerplate;
528     ASSIGN_RETURN_ON_EXCEPTION(
529         isolate, boilerplate,
530         Runtime::CreateArrayLiteralBoilerplate(isolate, literals, elements),
531         AllocationSite);
532
533     AllocationSiteCreationContext creation_context(isolate);
534     site = creation_context.EnterNewScope();
535     if (JSObject::DeepWalk(Handle<JSObject>::cast(boilerplate),
536                            &creation_context).is_null()) {
537       return Handle<AllocationSite>::null();
538     }
539     creation_context.ExitScope(site, Handle<JSObject>::cast(boilerplate));
540
541     literals->set(literals_index, *site);
542   } else {
543     site = Handle<AllocationSite>::cast(literal_site);
544   }
545
546   return site;
547 }
548
549
550 static MaybeHandle<JSObject> CreateArrayLiteralImpl(Isolate* isolate,
551                                            Handle<FixedArray> literals,
552                                            int literals_index,
553                                            Handle<FixedArray> elements,
554                                            int flags) {
555   RUNTIME_ASSERT_HANDLIFIED(literals_index >= 0 &&
556                             literals_index < literals->length(), JSObject);
557   Handle<AllocationSite> site;
558   ASSIGN_RETURN_ON_EXCEPTION(
559       isolate, site,
560       GetLiteralAllocationSite(isolate, literals, literals_index, elements),
561       JSObject);
562
563   bool enable_mementos = (flags & ArrayLiteral::kDisableMementos) == 0;
564   Handle<JSObject> boilerplate(JSObject::cast(site->transition_info()));
565   AllocationSiteUsageContext usage_context(isolate, site, enable_mementos);
566   usage_context.EnterNewScope();
567   JSObject::DeepCopyHints hints = (flags & ArrayLiteral::kShallowElements) == 0
568       ? JSObject::kNoHints
569       : JSObject::kObjectIsShallowArray;
570   MaybeHandle<JSObject> copy = JSObject::DeepCopy(boilerplate, &usage_context,
571                                                   hints);
572   usage_context.ExitScope(site, boilerplate);
573   return copy;
574 }
575
576
577 RUNTIME_FUNCTION(RuntimeHidden_CreateArrayLiteral) {
578   HandleScope scope(isolate);
579   ASSERT(args.length() == 4);
580   CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
581   CONVERT_SMI_ARG_CHECKED(literals_index, 1);
582   CONVERT_ARG_HANDLE_CHECKED(FixedArray, elements, 2);
583   CONVERT_SMI_ARG_CHECKED(flags, 3);
584
585   Handle<JSObject> result;
586   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
587       CreateArrayLiteralImpl(isolate, literals, literals_index, elements,
588                              flags));
589   return *result;
590 }
591
592
593 RUNTIME_FUNCTION(RuntimeHidden_CreateArrayLiteralStubBailout) {
594   HandleScope scope(isolate);
595   ASSERT(args.length() == 3);
596   CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
597   CONVERT_SMI_ARG_CHECKED(literals_index, 1);
598   CONVERT_ARG_HANDLE_CHECKED(FixedArray, elements, 2);
599
600   Handle<JSObject> result;
601   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
602      CreateArrayLiteralImpl(isolate, literals, literals_index, elements,
603                             ArrayLiteral::kShallowElements));
604   return *result;
605 }
606
607
608 RUNTIME_FUNCTION(Runtime_CreateSymbol) {
609   HandleScope scope(isolate);
610   ASSERT(args.length() == 1);
611   CONVERT_ARG_HANDLE_CHECKED(Object, name, 0);
612   RUNTIME_ASSERT(name->IsString() || name->IsUndefined());
613   Handle<Symbol> symbol = isolate->factory()->NewSymbol();
614   if (name->IsString()) symbol->set_name(*name);
615   return *symbol;
616 }
617
618
619 RUNTIME_FUNCTION(Runtime_CreatePrivateSymbol) {
620   HandleScope scope(isolate);
621   ASSERT(args.length() == 1);
622   CONVERT_ARG_HANDLE_CHECKED(Object, name, 0);
623   RUNTIME_ASSERT(name->IsString() || name->IsUndefined());
624   Handle<Symbol> symbol = isolate->factory()->NewPrivateSymbol();
625   if (name->IsString()) symbol->set_name(*name);
626   return *symbol;
627 }
628
629
630 RUNTIME_FUNCTION(Runtime_CreateGlobalPrivateSymbol) {
631   HandleScope scope(isolate);
632   ASSERT(args.length() == 1);
633   CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
634   Handle<JSObject> registry = isolate->GetSymbolRegistry();
635   Handle<String> part = isolate->factory()->private_intern_string();
636   Handle<Object> privates;
637   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
638       isolate, privates, Object::GetPropertyOrElement(registry, part));
639   Handle<Object> symbol;
640   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
641       isolate, symbol, Object::GetPropertyOrElement(privates, name));
642   if (!symbol->IsSymbol()) {
643     ASSERT(symbol->IsUndefined());
644     symbol = isolate->factory()->NewPrivateSymbol();
645     Handle<Symbol>::cast(symbol)->set_name(*name);
646     JSObject::SetProperty(Handle<JSObject>::cast(privates),
647                           name, symbol, NONE, STRICT).Assert();
648   }
649   return *symbol;
650 }
651
652
653 RUNTIME_FUNCTION(Runtime_NewSymbolWrapper) {
654   HandleScope scope(isolate);
655   ASSERT(args.length() == 1);
656   CONVERT_ARG_HANDLE_CHECKED(Symbol, symbol, 0);
657   return *Object::ToObject(isolate, symbol).ToHandleChecked();
658 }
659
660
661 RUNTIME_FUNCTION(Runtime_SymbolDescription) {
662   SealHandleScope shs(isolate);
663   ASSERT(args.length() == 1);
664   CONVERT_ARG_CHECKED(Symbol, symbol, 0);
665   return symbol->name();
666 }
667
668
669 RUNTIME_FUNCTION(Runtime_SymbolRegistry) {
670   HandleScope scope(isolate);
671   ASSERT(args.length() == 0);
672   return *isolate->GetSymbolRegistry();
673 }
674
675
676 RUNTIME_FUNCTION(Runtime_SymbolIsPrivate) {
677   SealHandleScope shs(isolate);
678   ASSERT(args.length() == 1);
679   CONVERT_ARG_CHECKED(Symbol, symbol, 0);
680   return isolate->heap()->ToBoolean(symbol->is_private());
681 }
682
683
684 RUNTIME_FUNCTION(Runtime_CreateJSProxy) {
685   HandleScope scope(isolate);
686   ASSERT(args.length() == 2);
687   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, handler, 0);
688   CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
689   if (!prototype->IsJSReceiver()) prototype = isolate->factory()->null_value();
690   return *isolate->factory()->NewJSProxy(handler, prototype);
691 }
692
693
694 RUNTIME_FUNCTION(Runtime_CreateJSFunctionProxy) {
695   HandleScope scope(isolate);
696   ASSERT(args.length() == 4);
697   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, handler, 0);
698   CONVERT_ARG_HANDLE_CHECKED(Object, call_trap, 1);
699   RUNTIME_ASSERT(call_trap->IsJSFunction() || call_trap->IsJSFunctionProxy());
700   CONVERT_ARG_HANDLE_CHECKED(JSFunction, construct_trap, 2);
701   CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 3);
702   if (!prototype->IsJSReceiver()) prototype = isolate->factory()->null_value();
703   return *isolate->factory()->NewJSFunctionProxy(
704       handler, call_trap, construct_trap, prototype);
705 }
706
707
708 RUNTIME_FUNCTION(Runtime_IsJSProxy) {
709   SealHandleScope shs(isolate);
710   ASSERT(args.length() == 1);
711   CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0);
712   return isolate->heap()->ToBoolean(obj->IsJSProxy());
713 }
714
715
716 RUNTIME_FUNCTION(Runtime_IsJSFunctionProxy) {
717   SealHandleScope shs(isolate);
718   ASSERT(args.length() == 1);
719   CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0);
720   return isolate->heap()->ToBoolean(obj->IsJSFunctionProxy());
721 }
722
723
724 RUNTIME_FUNCTION(Runtime_GetHandler) {
725   SealHandleScope shs(isolate);
726   ASSERT(args.length() == 1);
727   CONVERT_ARG_CHECKED(JSProxy, proxy, 0);
728   return proxy->handler();
729 }
730
731
732 RUNTIME_FUNCTION(Runtime_GetCallTrap) {
733   SealHandleScope shs(isolate);
734   ASSERT(args.length() == 1);
735   CONVERT_ARG_CHECKED(JSFunctionProxy, proxy, 0);
736   return proxy->call_trap();
737 }
738
739
740 RUNTIME_FUNCTION(Runtime_GetConstructTrap) {
741   SealHandleScope shs(isolate);
742   ASSERT(args.length() == 1);
743   CONVERT_ARG_CHECKED(JSFunctionProxy, proxy, 0);
744   return proxy->construct_trap();
745 }
746
747
748 RUNTIME_FUNCTION(Runtime_Fix) {
749   HandleScope scope(isolate);
750   ASSERT(args.length() == 1);
751   CONVERT_ARG_HANDLE_CHECKED(JSProxy, proxy, 0);
752   JSProxy::Fix(proxy);
753   return isolate->heap()->undefined_value();
754 }
755
756
757 void Runtime::FreeArrayBuffer(Isolate* isolate,
758                               JSArrayBuffer* phantom_array_buffer) {
759   if (phantom_array_buffer->should_be_freed()) {
760     ASSERT(phantom_array_buffer->is_external());
761     free(phantom_array_buffer->backing_store());
762   }
763   if (phantom_array_buffer->is_external()) return;
764
765   size_t allocated_length = NumberToSize(
766       isolate, phantom_array_buffer->byte_length());
767
768   reinterpret_cast<v8::Isolate*>(isolate)
769       ->AdjustAmountOfExternalAllocatedMemory(
770           -static_cast<int64_t>(allocated_length));
771   CHECK(V8::ArrayBufferAllocator() != NULL);
772   V8::ArrayBufferAllocator()->Free(
773       phantom_array_buffer->backing_store(),
774       allocated_length);
775 }
776
777
778 void Runtime::SetupArrayBuffer(Isolate* isolate,
779                                Handle<JSArrayBuffer> array_buffer,
780                                bool is_external,
781                                void* data,
782                                size_t allocated_length) {
783   ASSERT(array_buffer->GetInternalFieldCount() ==
784       v8::ArrayBuffer::kInternalFieldCount);
785   for (int i = 0; i < v8::ArrayBuffer::kInternalFieldCount; i++) {
786     array_buffer->SetInternalField(i, Smi::FromInt(0));
787   }
788   array_buffer->set_backing_store(data);
789   array_buffer->set_flag(Smi::FromInt(0));
790   array_buffer->set_is_external(is_external);
791
792   Handle<Object> byte_length =
793       isolate->factory()->NewNumberFromSize(allocated_length);
794   CHECK(byte_length->IsSmi() || byte_length->IsHeapNumber());
795   array_buffer->set_byte_length(*byte_length);
796
797   array_buffer->set_weak_next(isolate->heap()->array_buffers_list());
798   isolate->heap()->set_array_buffers_list(*array_buffer);
799   array_buffer->set_weak_first_view(isolate->heap()->undefined_value());
800 }
801
802
803 bool Runtime::SetupArrayBufferAllocatingData(
804     Isolate* isolate,
805     Handle<JSArrayBuffer> array_buffer,
806     size_t allocated_length,
807     bool initialize) {
808   void* data;
809   CHECK(V8::ArrayBufferAllocator() != NULL);
810   if (allocated_length != 0) {
811     if (initialize) {
812       data = V8::ArrayBufferAllocator()->Allocate(allocated_length);
813     } else {
814       data =
815           V8::ArrayBufferAllocator()->AllocateUninitialized(allocated_length);
816     }
817     if (data == NULL) return false;
818   } else {
819     data = NULL;
820   }
821
822   SetupArrayBuffer(isolate, array_buffer, false, data, allocated_length);
823
824   reinterpret_cast<v8::Isolate*>(isolate)
825       ->AdjustAmountOfExternalAllocatedMemory(allocated_length);
826
827   return true;
828 }
829
830
831 void Runtime::NeuterArrayBuffer(Handle<JSArrayBuffer> array_buffer) {
832   Isolate* isolate = array_buffer->GetIsolate();
833   for (Handle<Object> view_obj(array_buffer->weak_first_view(), isolate);
834        !view_obj->IsUndefined();) {
835     Handle<JSArrayBufferView> view(JSArrayBufferView::cast(*view_obj));
836     if (view->IsJSTypedArray()) {
837       JSTypedArray::cast(*view)->Neuter();
838     } else if (view->IsJSDataView()) {
839       JSDataView::cast(*view)->Neuter();
840     } else {
841       UNREACHABLE();
842     }
843     view_obj = handle(view->weak_next(), isolate);
844   }
845   array_buffer->Neuter();
846 }
847
848
849 RUNTIME_FUNCTION(Runtime_ArrayBufferInitialize) {
850   HandleScope scope(isolate);
851   ASSERT(args.length() == 2);
852   CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, holder, 0);
853   CONVERT_NUMBER_ARG_HANDLE_CHECKED(byteLength, 1);
854   if (!holder->byte_length()->IsUndefined()) {
855     // ArrayBuffer is already initialized; probably a fuzz test.
856     return *holder;
857   }
858   size_t allocated_length = 0;
859   if (!TryNumberToSize(isolate, *byteLength, &allocated_length)) {
860     return isolate->Throw(
861         *isolate->factory()->NewRangeError("invalid_array_buffer_length",
862                                            HandleVector<Object>(NULL, 0)));
863   }
864   if (!Runtime::SetupArrayBufferAllocatingData(isolate,
865                                                holder, allocated_length)) {
866     return isolate->Throw(
867         *isolate->factory()->NewRangeError("invalid_array_buffer_length",
868                                            HandleVector<Object>(NULL, 0)));
869   }
870   return *holder;
871 }
872
873
874 RUNTIME_FUNCTION(Runtime_ArrayBufferGetByteLength) {
875   SealHandleScope shs(isolate);
876   ASSERT(args.length() == 1);
877   CONVERT_ARG_CHECKED(JSArrayBuffer, holder, 0);
878   return holder->byte_length();
879 }
880
881
882 RUNTIME_FUNCTION(Runtime_ArrayBufferSliceImpl) {
883   HandleScope scope(isolate);
884   ASSERT(args.length() == 3);
885   CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, source, 0);
886   CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, target, 1);
887   CONVERT_NUMBER_ARG_HANDLE_CHECKED(first, 2);
888   RUNTIME_ASSERT(!source.is_identical_to(target));
889   size_t start = 0;
890   RUNTIME_ASSERT(TryNumberToSize(isolate, *first, &start));
891   size_t target_length = NumberToSize(isolate, target->byte_length());
892
893   if (target_length == 0) return isolate->heap()->undefined_value();
894
895   size_t source_byte_length = NumberToSize(isolate, source->byte_length());
896   RUNTIME_ASSERT(start <= source_byte_length);
897   RUNTIME_ASSERT(source_byte_length - start >= target_length);
898   uint8_t* source_data = reinterpret_cast<uint8_t*>(source->backing_store());
899   uint8_t* target_data = reinterpret_cast<uint8_t*>(target->backing_store());
900   CopyBytes(target_data, source_data + start, target_length);
901   return isolate->heap()->undefined_value();
902 }
903
904
905 RUNTIME_FUNCTION(Runtime_ArrayBufferIsView) {
906   HandleScope scope(isolate);
907   ASSERT(args.length() == 1);
908   CONVERT_ARG_CHECKED(Object, object, 0);
909   return isolate->heap()->ToBoolean(object->IsJSArrayBufferView());
910 }
911
912
913 RUNTIME_FUNCTION(Runtime_ArrayBufferNeuter) {
914   HandleScope scope(isolate);
915   ASSERT(args.length() == 1);
916   CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, array_buffer, 0);
917   if (array_buffer->backing_store() == NULL) {
918     CHECK(Smi::FromInt(0) == array_buffer->byte_length());
919     return isolate->heap()->undefined_value();
920   }
921   ASSERT(!array_buffer->is_external());
922   void* backing_store = array_buffer->backing_store();
923   size_t byte_length = NumberToSize(isolate, array_buffer->byte_length());
924   array_buffer->set_is_external(true);
925   Runtime::NeuterArrayBuffer(array_buffer);
926   V8::ArrayBufferAllocator()->Free(backing_store, byte_length);
927   return isolate->heap()->undefined_value();
928 }
929
930
931 void Runtime::ArrayIdToTypeAndSize(
932     int arrayId,
933     ExternalArrayType* array_type,
934     ElementsKind* external_elements_kind,
935     ElementsKind* fixed_elements_kind,
936     size_t* element_size) {
937   switch (arrayId) {
938 #define ARRAY_ID_CASE(Type, type, TYPE, ctype, size)                           \
939     case ARRAY_ID_##TYPE:                                                      \
940       *array_type = kExternal##Type##Array;                                    \
941       *external_elements_kind = EXTERNAL_##TYPE##_ELEMENTS;                    \
942       *fixed_elements_kind = TYPE##_ELEMENTS;                                  \
943       *element_size = size;                                                    \
944       break;
945
946     TYPED_ARRAYS(ARRAY_ID_CASE)
947 #undef ARRAY_ID_CASE
948
949     default:
950       UNREACHABLE();
951   }
952 }
953
954
955 RUNTIME_FUNCTION(Runtime_TypedArrayInitialize) {
956   HandleScope scope(isolate);
957   ASSERT(args.length() == 5);
958   CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0);
959   CONVERT_SMI_ARG_CHECKED(arrayId, 1);
960   CONVERT_ARG_HANDLE_CHECKED(Object, maybe_buffer, 2);
961   CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_offset_object, 3);
962   CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_length_object, 4);
963
964   RUNTIME_ASSERT(arrayId >= Runtime::ARRAY_ID_FIRST &&
965                  arrayId <= Runtime::ARRAY_ID_LAST);
966
967   ExternalArrayType array_type = kExternalInt8Array;  // Bogus initialization.
968   size_t element_size = 1;  // Bogus initialization.
969   ElementsKind external_elements_kind =
970       EXTERNAL_INT8_ELEMENTS;  // Bogus initialization.
971   ElementsKind fixed_elements_kind = INT8_ELEMENTS;  // Bogus initialization.
972   Runtime::ArrayIdToTypeAndSize(arrayId,
973       &array_type,
974       &external_elements_kind,
975       &fixed_elements_kind,
976       &element_size);
977   RUNTIME_ASSERT(holder->map()->elements_kind() == fixed_elements_kind);
978
979   size_t byte_offset = 0;
980   size_t byte_length = 0;
981   RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_offset_object, &byte_offset));
982   RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_length_object, &byte_length));
983
984   if (maybe_buffer->IsJSArrayBuffer()) {
985     Handle<JSArrayBuffer> buffer = Handle<JSArrayBuffer>::cast(maybe_buffer);
986     size_t array_buffer_byte_length =
987         NumberToSize(isolate, buffer->byte_length());
988     RUNTIME_ASSERT(byte_offset <= array_buffer_byte_length);
989     RUNTIME_ASSERT(array_buffer_byte_length - byte_offset >= byte_length);
990   } else {
991     RUNTIME_ASSERT(maybe_buffer->IsNull());
992   }
993
994   RUNTIME_ASSERT(byte_length % element_size == 0);
995   size_t length = byte_length / element_size;
996
997   if (length > static_cast<unsigned>(Smi::kMaxValue)) {
998     return isolate->Throw(
999         *isolate->factory()->NewRangeError("invalid_typed_array_length",
1000                                            HandleVector<Object>(NULL, 0)));
1001   }
1002
1003   // All checks are done, now we can modify objects.
1004
1005   ASSERT(holder->GetInternalFieldCount() ==
1006       v8::ArrayBufferView::kInternalFieldCount);
1007   for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) {
1008     holder->SetInternalField(i, Smi::FromInt(0));
1009   }
1010   Handle<Object> length_obj = isolate->factory()->NewNumberFromSize(length);
1011   holder->set_length(*length_obj);
1012   holder->set_byte_offset(*byte_offset_object);
1013   holder->set_byte_length(*byte_length_object);
1014
1015   if (!maybe_buffer->IsNull()) {
1016     Handle<JSArrayBuffer> buffer = Handle<JSArrayBuffer>::cast(maybe_buffer);
1017     holder->set_buffer(*buffer);
1018     holder->set_weak_next(buffer->weak_first_view());
1019     buffer->set_weak_first_view(*holder);
1020
1021     Handle<ExternalArray> elements =
1022         isolate->factory()->NewExternalArray(
1023             static_cast<int>(length), array_type,
1024             static_cast<uint8_t*>(buffer->backing_store()) + byte_offset);
1025     Handle<Map> map =
1026         JSObject::GetElementsTransitionMap(holder, external_elements_kind);
1027     JSObject::SetMapAndElements(holder, map, elements);
1028     ASSERT(IsExternalArrayElementsKind(holder->map()->elements_kind()));
1029   } else {
1030     holder->set_buffer(Smi::FromInt(0));
1031     holder->set_weak_next(isolate->heap()->undefined_value());
1032     Handle<FixedTypedArrayBase> elements =
1033         isolate->factory()->NewFixedTypedArray(
1034             static_cast<int>(length), array_type);
1035     holder->set_elements(*elements);
1036   }
1037   return isolate->heap()->undefined_value();
1038 }
1039
1040
1041 // Initializes a typed array from an array-like object.
1042 // If an array-like object happens to be a typed array of the same type,
1043 // initializes backing store using memove.
1044 //
1045 // Returns true if backing store was initialized or false otherwise.
1046 RUNTIME_FUNCTION(Runtime_TypedArrayInitializeFromArrayLike) {
1047   HandleScope scope(isolate);
1048   ASSERT(args.length() == 4);
1049   CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0);
1050   CONVERT_SMI_ARG_CHECKED(arrayId, 1);
1051   CONVERT_ARG_HANDLE_CHECKED(Object, source, 2);
1052   CONVERT_NUMBER_ARG_HANDLE_CHECKED(length_obj, 3);
1053
1054   RUNTIME_ASSERT(arrayId >= Runtime::ARRAY_ID_FIRST &&
1055                  arrayId <= Runtime::ARRAY_ID_LAST);
1056
1057   ExternalArrayType array_type = kExternalInt8Array;  // Bogus initialization.
1058   size_t element_size = 1;  // Bogus initialization.
1059   ElementsKind external_elements_kind =
1060       EXTERNAL_INT8_ELEMENTS;  // Bogus intialization.
1061   ElementsKind fixed_elements_kind = INT8_ELEMENTS;  // Bogus initialization.
1062   Runtime::ArrayIdToTypeAndSize(arrayId,
1063       &array_type,
1064       &external_elements_kind,
1065       &fixed_elements_kind,
1066       &element_size);
1067
1068   RUNTIME_ASSERT(holder->map()->elements_kind() == fixed_elements_kind);
1069
1070   Handle<JSArrayBuffer> buffer = isolate->factory()->NewJSArrayBuffer();
1071   if (source->IsJSTypedArray() &&
1072       JSTypedArray::cast(*source)->type() == array_type) {
1073     length_obj = Handle<Object>(JSTypedArray::cast(*source)->length(), isolate);
1074   }
1075   size_t length = 0;
1076   RUNTIME_ASSERT(TryNumberToSize(isolate, *length_obj, &length));
1077
1078   if ((length > static_cast<unsigned>(Smi::kMaxValue)) ||
1079       (length > (kMaxInt / element_size))) {
1080     return isolate->Throw(*isolate->factory()->
1081           NewRangeError("invalid_typed_array_length",
1082             HandleVector<Object>(NULL, 0)));
1083   }
1084   size_t byte_length = length * element_size;
1085
1086   ASSERT(holder->GetInternalFieldCount() ==
1087       v8::ArrayBufferView::kInternalFieldCount);
1088   for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) {
1089     holder->SetInternalField(i, Smi::FromInt(0));
1090   }
1091
1092   // NOTE: not initializing backing store.
1093   // We assume that the caller of this function will initialize holder
1094   // with the loop
1095   //      for(i = 0; i < length; i++) { holder[i] = source[i]; }
1096   // We assume that the caller of this function is always a typed array
1097   // constructor.
1098   // If source is a typed array, this loop will always run to completion,
1099   // so we are sure that the backing store will be initialized.
1100   // Otherwise, the indexing operation might throw, so the loop will not
1101   // run to completion and the typed array might remain partly initialized.
1102   // However we further assume that the caller of this function is a typed array
1103   // constructor, and the exception will propagate out of the constructor,
1104   // therefore uninitialized memory will not be accessible by a user program.
1105   //
1106   // TODO(dslomov): revise this once we support subclassing.
1107
1108   if (!Runtime::SetupArrayBufferAllocatingData(
1109         isolate, buffer, byte_length, false)) {
1110     return isolate->Throw(*isolate->factory()->
1111           NewRangeError("invalid_array_buffer_length",
1112             HandleVector<Object>(NULL, 0)));
1113   }
1114
1115   holder->set_buffer(*buffer);
1116   holder->set_byte_offset(Smi::FromInt(0));
1117   Handle<Object> byte_length_obj(
1118       isolate->factory()->NewNumberFromSize(byte_length));
1119   holder->set_byte_length(*byte_length_obj);
1120   holder->set_length(*length_obj);
1121   holder->set_weak_next(buffer->weak_first_view());
1122   buffer->set_weak_first_view(*holder);
1123
1124   Handle<ExternalArray> elements =
1125       isolate->factory()->NewExternalArray(
1126           static_cast<int>(length), array_type,
1127           static_cast<uint8_t*>(buffer->backing_store()));
1128   Handle<Map> map = JSObject::GetElementsTransitionMap(
1129       holder, external_elements_kind);
1130   JSObject::SetMapAndElements(holder, map, elements);
1131
1132   if (source->IsJSTypedArray()) {
1133     Handle<JSTypedArray> typed_array(JSTypedArray::cast(*source));
1134
1135     if (typed_array->type() == holder->type()) {
1136       uint8_t* backing_store =
1137         static_cast<uint8_t*>(
1138           typed_array->GetBuffer()->backing_store());
1139       size_t source_byte_offset =
1140           NumberToSize(isolate, typed_array->byte_offset());
1141       memcpy(
1142           buffer->backing_store(),
1143           backing_store + source_byte_offset,
1144           byte_length);
1145       return isolate->heap()->true_value();
1146     }
1147   }
1148
1149   return isolate->heap()->false_value();
1150 }
1151
1152
1153 #define BUFFER_VIEW_GETTER(Type, getter, accessor) \
1154   RUNTIME_FUNCTION(Runtime_##Type##Get##getter) {                    \
1155     HandleScope scope(isolate);                                               \
1156     ASSERT(args.length() == 1);                                               \
1157     CONVERT_ARG_HANDLE_CHECKED(JS##Type, holder, 0);                          \
1158     return holder->accessor();                                                \
1159   }
1160
1161 BUFFER_VIEW_GETTER(ArrayBufferView, ByteLength, byte_length)
1162 BUFFER_VIEW_GETTER(ArrayBufferView, ByteOffset, byte_offset)
1163 BUFFER_VIEW_GETTER(TypedArray, Length, length)
1164 BUFFER_VIEW_GETTER(DataView, Buffer, buffer)
1165
1166 #undef BUFFER_VIEW_GETTER
1167
1168 RUNTIME_FUNCTION(Runtime_TypedArrayGetBuffer) {
1169   HandleScope scope(isolate);
1170   ASSERT(args.length() == 1);
1171   CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0);
1172   return *holder->GetBuffer();
1173 }
1174
1175
1176 // Return codes for Runtime_TypedArraySetFastCases.
1177 // Should be synchronized with typedarray.js natives.
1178 enum TypedArraySetResultCodes {
1179   // Set from typed array of the same type.
1180   // This is processed by TypedArraySetFastCases
1181   TYPED_ARRAY_SET_TYPED_ARRAY_SAME_TYPE = 0,
1182   // Set from typed array of the different type, overlapping in memory.
1183   TYPED_ARRAY_SET_TYPED_ARRAY_OVERLAPPING = 1,
1184   // Set from typed array of the different type, non-overlapping.
1185   TYPED_ARRAY_SET_TYPED_ARRAY_NONOVERLAPPING = 2,
1186   // Set from non-typed array.
1187   TYPED_ARRAY_SET_NON_TYPED_ARRAY = 3
1188 };
1189
1190
1191 RUNTIME_FUNCTION(Runtime_TypedArraySetFastCases) {
1192   HandleScope scope(isolate);
1193   ASSERT(args.length() == 3);
1194   if (!args[0]->IsJSTypedArray())
1195     return isolate->Throw(*isolate->factory()->NewTypeError(
1196         "not_typed_array", HandleVector<Object>(NULL, 0)));
1197
1198   if (!args[1]->IsJSTypedArray())
1199     return Smi::FromInt(TYPED_ARRAY_SET_NON_TYPED_ARRAY);
1200
1201   CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, target_obj, 0);
1202   CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, source_obj, 1);
1203   CONVERT_NUMBER_ARG_HANDLE_CHECKED(offset_obj, 2);
1204
1205   Handle<JSTypedArray> target(JSTypedArray::cast(*target_obj));
1206   Handle<JSTypedArray> source(JSTypedArray::cast(*source_obj));
1207   size_t offset = 0;
1208   RUNTIME_ASSERT(TryNumberToSize(isolate, *offset_obj, &offset));
1209   size_t target_length = NumberToSize(isolate, target->length());
1210   size_t source_length = NumberToSize(isolate, source->length());
1211   size_t target_byte_length = NumberToSize(isolate, target->byte_length());
1212   size_t source_byte_length = NumberToSize(isolate, source->byte_length());
1213   if (offset > target_length ||
1214       offset + source_length > target_length ||
1215       offset + source_length < offset)  // overflow
1216     return isolate->Throw(*isolate->factory()->NewRangeError(
1217           "typed_array_set_source_too_large", HandleVector<Object>(NULL, 0)));
1218
1219   size_t target_offset = NumberToSize(isolate, target->byte_offset());
1220   size_t source_offset = NumberToSize(isolate, source->byte_offset());
1221   uint8_t* target_base =
1222       static_cast<uint8_t*>(
1223         target->GetBuffer()->backing_store()) + target_offset;
1224   uint8_t* source_base =
1225       static_cast<uint8_t*>(
1226         source->GetBuffer()->backing_store()) + source_offset;
1227
1228   // Typed arrays of the same type: use memmove.
1229   if (target->type() == source->type()) {
1230     memmove(target_base + offset * target->element_size(),
1231         source_base, source_byte_length);
1232     return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_SAME_TYPE);
1233   }
1234
1235   // Typed arrays of different types over the same backing store
1236   if ((source_base <= target_base &&
1237         source_base + source_byte_length > target_base) ||
1238       (target_base <= source_base &&
1239         target_base + target_byte_length > source_base)) {
1240     // We do not support overlapping ArrayBuffers
1241     ASSERT(
1242       target->GetBuffer()->backing_store() ==
1243       source->GetBuffer()->backing_store());
1244     return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_OVERLAPPING);
1245   } else {  // Non-overlapping typed arrays
1246     return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_NONOVERLAPPING);
1247   }
1248 }
1249
1250
1251 RUNTIME_FUNCTION(Runtime_TypedArrayMaxSizeInHeap) {
1252   ASSERT(args.length() == 0);
1253   ASSERT_OBJECT_SIZE(
1254       FLAG_typed_array_max_size_in_heap + FixedTypedArrayBase::kDataOffset);
1255   return Smi::FromInt(FLAG_typed_array_max_size_in_heap);
1256 }
1257
1258
1259 RUNTIME_FUNCTION(Runtime_DataViewInitialize) {
1260   HandleScope scope(isolate);
1261   ASSERT(args.length() == 4);
1262   CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0);
1263   CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, buffer, 1);
1264   CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_offset, 2);
1265   CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_length, 3);
1266
1267   ASSERT(holder->GetInternalFieldCount() ==
1268       v8::ArrayBufferView::kInternalFieldCount);
1269   for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) {
1270     holder->SetInternalField(i, Smi::FromInt(0));
1271   }
1272   size_t buffer_length = 0;
1273   size_t offset = 0;
1274   size_t length = 0;
1275   RUNTIME_ASSERT(
1276       TryNumberToSize(isolate, buffer->byte_length(), &buffer_length));
1277   RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_offset, &offset));
1278   RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_length, &length));
1279
1280   // TODO(jkummerow): When we have a "safe numerics" helper class, use it here.
1281   // Entire range [offset, offset + length] must be in bounds.
1282   RUNTIME_ASSERT(offset <= buffer_length);
1283   RUNTIME_ASSERT(offset + length <= buffer_length);
1284   // No overflow.
1285   RUNTIME_ASSERT(offset + length >= offset);
1286
1287   holder->set_buffer(*buffer);
1288   holder->set_byte_offset(*byte_offset);
1289   holder->set_byte_length(*byte_length);
1290
1291   holder->set_weak_next(buffer->weak_first_view());
1292   buffer->set_weak_first_view(*holder);
1293
1294   return isolate->heap()->undefined_value();
1295 }
1296
1297
1298 inline static bool NeedToFlipBytes(bool is_little_endian) {
1299 #ifdef V8_TARGET_LITTLE_ENDIAN
1300   return !is_little_endian;
1301 #else
1302   return is_little_endian;
1303 #endif
1304 }
1305
1306
1307 template<int n>
1308 inline void CopyBytes(uint8_t* target, uint8_t* source) {
1309   for (int i = 0; i < n; i++) {
1310     *(target++) = *(source++);
1311   }
1312 }
1313
1314
1315 template<int n>
1316 inline void FlipBytes(uint8_t* target, uint8_t* source) {
1317   source = source + (n-1);
1318   for (int i = 0; i < n; i++) {
1319     *(target++) = *(source--);
1320   }
1321 }
1322
1323
1324 template<typename T>
1325 inline static bool DataViewGetValue(
1326     Isolate* isolate,
1327     Handle<JSDataView> data_view,
1328     Handle<Object> byte_offset_obj,
1329     bool is_little_endian,
1330     T* result) {
1331   size_t byte_offset = 0;
1332   if (!TryNumberToSize(isolate, *byte_offset_obj, &byte_offset)) {
1333     return false;
1334   }
1335   Handle<JSArrayBuffer> buffer(JSArrayBuffer::cast(data_view->buffer()));
1336
1337   size_t data_view_byte_offset =
1338       NumberToSize(isolate, data_view->byte_offset());
1339   size_t data_view_byte_length =
1340       NumberToSize(isolate, data_view->byte_length());
1341   if (byte_offset + sizeof(T) > data_view_byte_length ||
1342       byte_offset + sizeof(T) < byte_offset)  {  // overflow
1343     return false;
1344   }
1345
1346   union Value {
1347     T data;
1348     uint8_t bytes[sizeof(T)];
1349   };
1350
1351   Value value;
1352   size_t buffer_offset = data_view_byte_offset + byte_offset;
1353   ASSERT(
1354       NumberToSize(isolate, buffer->byte_length())
1355       >= buffer_offset + sizeof(T));
1356   uint8_t* source =
1357         static_cast<uint8_t*>(buffer->backing_store()) + buffer_offset;
1358   if (NeedToFlipBytes(is_little_endian)) {
1359     FlipBytes<sizeof(T)>(value.bytes, source);
1360   } else {
1361     CopyBytes<sizeof(T)>(value.bytes, source);
1362   }
1363   *result = value.data;
1364   return true;
1365 }
1366
1367
1368 template<typename T>
1369 static bool DataViewSetValue(
1370     Isolate* isolate,
1371     Handle<JSDataView> data_view,
1372     Handle<Object> byte_offset_obj,
1373     bool is_little_endian,
1374     T data) {
1375   size_t byte_offset = 0;
1376   if (!TryNumberToSize(isolate, *byte_offset_obj, &byte_offset)) {
1377     return false;
1378   }
1379   Handle<JSArrayBuffer> buffer(JSArrayBuffer::cast(data_view->buffer()));
1380
1381   size_t data_view_byte_offset =
1382       NumberToSize(isolate, data_view->byte_offset());
1383   size_t data_view_byte_length =
1384       NumberToSize(isolate, data_view->byte_length());
1385   if (byte_offset + sizeof(T) > data_view_byte_length ||
1386       byte_offset + sizeof(T) < byte_offset)  {  // overflow
1387     return false;
1388   }
1389
1390   union Value {
1391     T data;
1392     uint8_t bytes[sizeof(T)];
1393   };
1394
1395   Value value;
1396   value.data = data;
1397   size_t buffer_offset = data_view_byte_offset + byte_offset;
1398   ASSERT(
1399       NumberToSize(isolate, buffer->byte_length())
1400       >= buffer_offset + sizeof(T));
1401   uint8_t* target =
1402         static_cast<uint8_t*>(buffer->backing_store()) + buffer_offset;
1403   if (NeedToFlipBytes(is_little_endian)) {
1404     FlipBytes<sizeof(T)>(target, value.bytes);
1405   } else {
1406     CopyBytes<sizeof(T)>(target, value.bytes);
1407   }
1408   return true;
1409 }
1410
1411
1412 #define DATA_VIEW_GETTER(TypeName, Type, Converter)                           \
1413   RUNTIME_FUNCTION(Runtime_DataViewGet##TypeName) {                           \
1414     HandleScope scope(isolate);                                               \
1415     ASSERT(args.length() == 3);                                               \
1416     CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0);                        \
1417     CONVERT_NUMBER_ARG_HANDLE_CHECKED(offset, 1);                             \
1418     CONVERT_BOOLEAN_ARG_CHECKED(is_little_endian, 2);                         \
1419     Type result;                                                              \
1420     if (DataViewGetValue(                                                     \
1421           isolate, holder, offset, is_little_endian, &result)) {              \
1422       return *isolate->factory()->Converter(result);                          \
1423     } else {                                                                  \
1424       return isolate->Throw(*isolate->factory()->NewRangeError(               \
1425           "invalid_data_view_accessor_offset",                                \
1426           HandleVector<Object>(NULL, 0)));                                    \
1427     }                                                                         \
1428   }
1429
1430 DATA_VIEW_GETTER(Uint8, uint8_t, NewNumberFromUint)
1431 DATA_VIEW_GETTER(Int8, int8_t, NewNumberFromInt)
1432 DATA_VIEW_GETTER(Uint16, uint16_t, NewNumberFromUint)
1433 DATA_VIEW_GETTER(Int16, int16_t, NewNumberFromInt)
1434 DATA_VIEW_GETTER(Uint32, uint32_t, NewNumberFromUint)
1435 DATA_VIEW_GETTER(Int32, int32_t, NewNumberFromInt)
1436 DATA_VIEW_GETTER(Float32, float, NewNumber)
1437 DATA_VIEW_GETTER(Float64, double, NewNumber)
1438
1439 #undef DATA_VIEW_GETTER
1440
1441
1442 template <typename T>
1443 static T DataViewConvertValue(double value);
1444
1445
1446 template <>
1447 int8_t DataViewConvertValue<int8_t>(double value) {
1448   return static_cast<int8_t>(DoubleToInt32(value));
1449 }
1450
1451
1452 template <>
1453 int16_t DataViewConvertValue<int16_t>(double value) {
1454   return static_cast<int16_t>(DoubleToInt32(value));
1455 }
1456
1457
1458 template <>
1459 int32_t DataViewConvertValue<int32_t>(double value) {
1460   return DoubleToInt32(value);
1461 }
1462
1463
1464 template <>
1465 uint8_t DataViewConvertValue<uint8_t>(double value) {
1466   return static_cast<uint8_t>(DoubleToUint32(value));
1467 }
1468
1469
1470 template <>
1471 uint16_t DataViewConvertValue<uint16_t>(double value) {
1472   return static_cast<uint16_t>(DoubleToUint32(value));
1473 }
1474
1475
1476 template <>
1477 uint32_t DataViewConvertValue<uint32_t>(double value) {
1478   return DoubleToUint32(value);
1479 }
1480
1481
1482 template <>
1483 float DataViewConvertValue<float>(double value) {
1484   return static_cast<float>(value);
1485 }
1486
1487
1488 template <>
1489 double DataViewConvertValue<double>(double value) {
1490   return value;
1491 }
1492
1493
1494 #define DATA_VIEW_SETTER(TypeName, Type)                                      \
1495   RUNTIME_FUNCTION(Runtime_DataViewSet##TypeName) {                           \
1496     HandleScope scope(isolate);                                               \
1497     ASSERT(args.length() == 4);                                               \
1498     CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0);                        \
1499     CONVERT_NUMBER_ARG_HANDLE_CHECKED(offset, 1);                             \
1500     CONVERT_NUMBER_ARG_HANDLE_CHECKED(value, 2);                              \
1501     CONVERT_BOOLEAN_ARG_CHECKED(is_little_endian, 3);                         \
1502     Type v = DataViewConvertValue<Type>(value->Number());                     \
1503     if (DataViewSetValue(                                                     \
1504           isolate, holder, offset, is_little_endian, v)) {                    \
1505       return isolate->heap()->undefined_value();                              \
1506     } else {                                                                  \
1507       return isolate->Throw(*isolate->factory()->NewRangeError(               \
1508           "invalid_data_view_accessor_offset",                                \
1509           HandleVector<Object>(NULL, 0)));                                    \
1510     }                                                                         \
1511   }
1512
1513 DATA_VIEW_SETTER(Uint8, uint8_t)
1514 DATA_VIEW_SETTER(Int8, int8_t)
1515 DATA_VIEW_SETTER(Uint16, uint16_t)
1516 DATA_VIEW_SETTER(Int16, int16_t)
1517 DATA_VIEW_SETTER(Uint32, uint32_t)
1518 DATA_VIEW_SETTER(Int32, int32_t)
1519 DATA_VIEW_SETTER(Float32, float)
1520 DATA_VIEW_SETTER(Float64, double)
1521
1522 #undef DATA_VIEW_SETTER
1523
1524
1525 RUNTIME_FUNCTION(Runtime_SetInitialize) {
1526   HandleScope scope(isolate);
1527   ASSERT(args.length() == 1);
1528   CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
1529   Handle<OrderedHashSet> table = isolate->factory()->NewOrderedHashSet();
1530   holder->set_table(*table);
1531   return *holder;
1532 }
1533
1534
1535 RUNTIME_FUNCTION(Runtime_SetAdd) {
1536   HandleScope scope(isolate);
1537   ASSERT(args.length() == 2);
1538   CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
1539   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
1540   Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
1541   table = OrderedHashSet::Add(table, key);
1542   holder->set_table(*table);
1543   return isolate->heap()->undefined_value();
1544 }
1545
1546
1547 RUNTIME_FUNCTION(Runtime_SetHas) {
1548   HandleScope scope(isolate);
1549   ASSERT(args.length() == 2);
1550   CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
1551   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
1552   Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
1553   return isolate->heap()->ToBoolean(table->Contains(key));
1554 }
1555
1556
1557 RUNTIME_FUNCTION(Runtime_SetDelete) {
1558   HandleScope scope(isolate);
1559   ASSERT(args.length() == 2);
1560   CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
1561   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
1562   Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
1563   bool was_present = false;
1564   table = OrderedHashSet::Remove(table, key, &was_present);
1565   holder->set_table(*table);
1566   return isolate->heap()->ToBoolean(was_present);
1567 }
1568
1569
1570 RUNTIME_FUNCTION(Runtime_SetClear) {
1571   HandleScope scope(isolate);
1572   ASSERT(args.length() == 1);
1573   CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
1574   Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
1575   table = OrderedHashSet::Clear(table);
1576   holder->set_table(*table);
1577   return isolate->heap()->undefined_value();
1578 }
1579
1580
1581 RUNTIME_FUNCTION(Runtime_SetGetSize) {
1582   HandleScope scope(isolate);
1583   ASSERT(args.length() == 1);
1584   CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
1585   Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
1586   return Smi::FromInt(table->NumberOfElements());
1587 }
1588
1589
1590 RUNTIME_FUNCTION(Runtime_SetIteratorInitialize) {
1591   HandleScope scope(isolate);
1592   ASSERT(args.length() == 3);
1593   CONVERT_ARG_HANDLE_CHECKED(JSSetIterator, holder, 0);
1594   CONVERT_ARG_HANDLE_CHECKED(JSSet, set, 1);
1595   CONVERT_SMI_ARG_CHECKED(kind, 2)
1596   RUNTIME_ASSERT(kind == JSSetIterator::kKindValues ||
1597                  kind == JSSetIterator::kKindEntries);
1598   Handle<OrderedHashSet> table(OrderedHashSet::cast(set->table()));
1599   holder->set_table(*table);
1600   holder->set_index(Smi::FromInt(0));
1601   holder->set_kind(Smi::FromInt(kind));
1602   return isolate->heap()->undefined_value();
1603 }
1604
1605
1606 RUNTIME_FUNCTION(Runtime_SetIteratorNext) {
1607   HandleScope scope(isolate);
1608   ASSERT(args.length() == 1);
1609   CONVERT_ARG_HANDLE_CHECKED(JSSetIterator, holder, 0);
1610   return *JSSetIterator::Next(holder);
1611 }
1612
1613
1614 RUNTIME_FUNCTION(Runtime_MapInitialize) {
1615   HandleScope scope(isolate);
1616   ASSERT(args.length() == 1);
1617   CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
1618   Handle<OrderedHashMap> table = isolate->factory()->NewOrderedHashMap();
1619   holder->set_table(*table);
1620   return *holder;
1621 }
1622
1623
1624 RUNTIME_FUNCTION(Runtime_MapGet) {
1625   HandleScope scope(isolate);
1626   ASSERT(args.length() == 2);
1627   CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
1628   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
1629   Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
1630   Handle<Object> lookup(table->Lookup(key), isolate);
1631   return lookup->IsTheHole() ? isolate->heap()->undefined_value() : *lookup;
1632 }
1633
1634
1635 RUNTIME_FUNCTION(Runtime_MapHas) {
1636   HandleScope scope(isolate);
1637   ASSERT(args.length() == 2);
1638   CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
1639   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
1640   Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
1641   Handle<Object> lookup(table->Lookup(key), isolate);
1642   return isolate->heap()->ToBoolean(!lookup->IsTheHole());
1643 }
1644
1645
1646 RUNTIME_FUNCTION(Runtime_MapDelete) {
1647   HandleScope scope(isolate);
1648   ASSERT(args.length() == 2);
1649   CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
1650   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
1651   Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
1652   bool was_present = false;
1653   Handle<OrderedHashMap> new_table =
1654       OrderedHashMap::Remove(table, key, &was_present);
1655   holder->set_table(*new_table);
1656   return isolate->heap()->ToBoolean(was_present);
1657 }
1658
1659
1660 RUNTIME_FUNCTION(Runtime_MapClear) {
1661   HandleScope scope(isolate);
1662   ASSERT(args.length() == 1);
1663   CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
1664   Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
1665   table = OrderedHashMap::Clear(table);
1666   holder->set_table(*table);
1667   return isolate->heap()->undefined_value();
1668 }
1669
1670
1671 RUNTIME_FUNCTION(Runtime_MapSet) {
1672   HandleScope scope(isolate);
1673   ASSERT(args.length() == 3);
1674   CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
1675   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
1676   CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
1677   Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
1678   Handle<OrderedHashMap> new_table = OrderedHashMap::Put(table, key, value);
1679   holder->set_table(*new_table);
1680   return isolate->heap()->undefined_value();
1681 }
1682
1683
1684 RUNTIME_FUNCTION(Runtime_MapGetSize) {
1685   HandleScope scope(isolate);
1686   ASSERT(args.length() == 1);
1687   CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
1688   Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
1689   return Smi::FromInt(table->NumberOfElements());
1690 }
1691
1692
1693 RUNTIME_FUNCTION(Runtime_MapIteratorInitialize) {
1694   HandleScope scope(isolate);
1695   ASSERT(args.length() == 3);
1696   CONVERT_ARG_HANDLE_CHECKED(JSMapIterator, holder, 0);
1697   CONVERT_ARG_HANDLE_CHECKED(JSMap, map, 1);
1698   CONVERT_SMI_ARG_CHECKED(kind, 2)
1699   RUNTIME_ASSERT(kind == JSMapIterator::kKindKeys
1700       || kind == JSMapIterator::kKindValues
1701       || kind == JSMapIterator::kKindEntries);
1702   Handle<OrderedHashMap> table(OrderedHashMap::cast(map->table()));
1703   holder->set_table(*table);
1704   holder->set_index(Smi::FromInt(0));
1705   holder->set_kind(Smi::FromInt(kind));
1706   return isolate->heap()->undefined_value();
1707 }
1708
1709
1710 RUNTIME_FUNCTION(Runtime_MapIteratorNext) {
1711   HandleScope scope(isolate);
1712   ASSERT(args.length() == 1);
1713   CONVERT_ARG_HANDLE_CHECKED(JSMapIterator, holder, 0);
1714   return *JSMapIterator::Next(holder);
1715 }
1716
1717
1718 static Handle<JSWeakCollection> WeakCollectionInitialize(
1719     Isolate* isolate,
1720     Handle<JSWeakCollection> weak_collection) {
1721   ASSERT(weak_collection->map()->inobject_properties() == 0);
1722   Handle<ObjectHashTable> table = ObjectHashTable::New(isolate, 0);
1723   weak_collection->set_table(*table);
1724   return weak_collection;
1725 }
1726
1727
1728 RUNTIME_FUNCTION(Runtime_WeakCollectionInitialize) {
1729   HandleScope scope(isolate);
1730   ASSERT(args.length() == 1);
1731   CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
1732   return *WeakCollectionInitialize(isolate, weak_collection);
1733 }
1734
1735
1736 RUNTIME_FUNCTION(Runtime_WeakCollectionGet) {
1737   HandleScope scope(isolate);
1738   ASSERT(args.length() == 2);
1739   CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
1740   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
1741   RUNTIME_ASSERT(key->IsJSReceiver() || key->IsSymbol());
1742   Handle<ObjectHashTable> table(
1743       ObjectHashTable::cast(weak_collection->table()));
1744   RUNTIME_ASSERT(table->IsKey(*key));
1745   Handle<Object> lookup(table->Lookup(key), isolate);
1746   return lookup->IsTheHole() ? isolate->heap()->undefined_value() : *lookup;
1747 }
1748
1749
1750 RUNTIME_FUNCTION(Runtime_WeakCollectionHas) {
1751   HandleScope scope(isolate);
1752   ASSERT(args.length() == 2);
1753   CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
1754   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
1755   RUNTIME_ASSERT(key->IsJSReceiver() || key->IsSymbol());
1756   Handle<ObjectHashTable> table(
1757       ObjectHashTable::cast(weak_collection->table()));
1758   RUNTIME_ASSERT(table->IsKey(*key));
1759   Handle<Object> lookup(table->Lookup(key), isolate);
1760   return isolate->heap()->ToBoolean(!lookup->IsTheHole());
1761 }
1762
1763
1764 RUNTIME_FUNCTION(Runtime_WeakCollectionDelete) {
1765   HandleScope scope(isolate);
1766   ASSERT(args.length() == 2);
1767   CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
1768   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
1769   RUNTIME_ASSERT(key->IsJSReceiver() || key->IsSymbol());
1770   Handle<ObjectHashTable> table(ObjectHashTable::cast(
1771       weak_collection->table()));
1772   RUNTIME_ASSERT(table->IsKey(*key));
1773   bool was_present = false;
1774   Handle<ObjectHashTable> new_table =
1775       ObjectHashTable::Remove(table, key, &was_present);
1776   weak_collection->set_table(*new_table);
1777   return isolate->heap()->ToBoolean(was_present);
1778 }
1779
1780
1781 RUNTIME_FUNCTION(Runtime_WeakCollectionSet) {
1782   HandleScope scope(isolate);
1783   ASSERT(args.length() == 3);
1784   CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
1785   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
1786   RUNTIME_ASSERT(key->IsJSReceiver() || key->IsSymbol());
1787   CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
1788   Handle<ObjectHashTable> table(
1789       ObjectHashTable::cast(weak_collection->table()));
1790   RUNTIME_ASSERT(table->IsKey(*key));
1791   Handle<ObjectHashTable> new_table = ObjectHashTable::Put(table, key, value);
1792   weak_collection->set_table(*new_table);
1793   return isolate->heap()->undefined_value();
1794 }
1795
1796
1797 RUNTIME_FUNCTION(Runtime_ClassOf) {
1798   SealHandleScope shs(isolate);
1799   ASSERT(args.length() == 1);
1800   CONVERT_ARG_CHECKED(Object, obj, 0);
1801   if (!obj->IsJSObject()) return isolate->heap()->null_value();
1802   return JSObject::cast(obj)->class_name();
1803 }
1804
1805
1806 RUNTIME_FUNCTION(Runtime_GetPrototype) {
1807   HandleScope scope(isolate);
1808   ASSERT(args.length() == 1);
1809   CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0);
1810   // We don't expect access checks to be needed on JSProxy objects.
1811   ASSERT(!obj->IsAccessCheckNeeded() || obj->IsJSObject());
1812   do {
1813     if (obj->IsAccessCheckNeeded() &&
1814         !isolate->MayNamedAccess(Handle<JSObject>::cast(obj),
1815                                  isolate->factory()->proto_string(),
1816                                  v8::ACCESS_GET)) {
1817       isolate->ReportFailedAccessCheck(Handle<JSObject>::cast(obj),
1818                                        v8::ACCESS_GET);
1819       RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
1820       return isolate->heap()->undefined_value();
1821     }
1822     obj = Object::GetPrototype(isolate, obj);
1823   } while (obj->IsJSObject() &&
1824            JSObject::cast(*obj)->map()->is_hidden_prototype());
1825   return *obj;
1826 }
1827
1828
1829 static inline Handle<Object> GetPrototypeSkipHiddenPrototypes(
1830     Isolate* isolate, Handle<Object> receiver) {
1831   Handle<Object> current = Object::GetPrototype(isolate, receiver);
1832   while (current->IsJSObject() &&
1833          JSObject::cast(*current)->map()->is_hidden_prototype()) {
1834     current = Object::GetPrototype(isolate, current);
1835   }
1836   return current;
1837 }
1838
1839
1840 RUNTIME_FUNCTION(Runtime_SetPrototype) {
1841   HandleScope scope(isolate);
1842   ASSERT(args.length() == 2);
1843   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
1844   CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
1845   if (obj->IsAccessCheckNeeded() &&
1846       !isolate->MayNamedAccess(
1847           obj, isolate->factory()->proto_string(), v8::ACCESS_SET)) {
1848     isolate->ReportFailedAccessCheck(obj, v8::ACCESS_SET);
1849     RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
1850     return isolate->heap()->undefined_value();
1851   }
1852   if (obj->map()->is_observed()) {
1853     Handle<Object> old_value = GetPrototypeSkipHiddenPrototypes(isolate, obj);
1854     Handle<Object> result;
1855     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
1856         isolate, result,
1857         JSObject::SetPrototype(obj, prototype, true));
1858
1859     Handle<Object> new_value = GetPrototypeSkipHiddenPrototypes(isolate, obj);
1860     if (!new_value->SameValue(*old_value)) {
1861       JSObject::EnqueueChangeRecord(obj, "setPrototype",
1862                                     isolate->factory()->proto_string(),
1863                                     old_value);
1864     }
1865     return *result;
1866   }
1867   Handle<Object> result;
1868   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
1869       isolate, result,
1870       JSObject::SetPrototype(obj, prototype, true));
1871   return *result;
1872 }
1873
1874
1875 RUNTIME_FUNCTION(Runtime_IsInPrototypeChain) {
1876   HandleScope shs(isolate);
1877   ASSERT(args.length() == 2);
1878   // See ECMA-262, section 15.3.5.3, page 88 (steps 5 - 8).
1879   CONVERT_ARG_HANDLE_CHECKED(Object, O, 0);
1880   CONVERT_ARG_HANDLE_CHECKED(Object, V, 1);
1881   while (true) {
1882     Handle<Object> prototype = Object::GetPrototype(isolate, V);
1883     if (prototype->IsNull()) return isolate->heap()->false_value();
1884     if (*O == *prototype) return isolate->heap()->true_value();
1885     V = prototype;
1886   }
1887 }
1888
1889
1890 static bool CheckAccessException(Object* callback,
1891                                  v8::AccessType access_type) {
1892   DisallowHeapAllocation no_gc;
1893   ASSERT(!callback->IsForeign());
1894   if (callback->IsAccessorInfo()) {
1895     AccessorInfo* info = AccessorInfo::cast(callback);
1896     return
1897         (access_type == v8::ACCESS_HAS &&
1898            (info->all_can_read() || info->all_can_write())) ||
1899         (access_type == v8::ACCESS_GET && info->all_can_read()) ||
1900         (access_type == v8::ACCESS_SET && info->all_can_write());
1901   }
1902   if (callback->IsAccessorPair()) {
1903     AccessorPair* info = AccessorPair::cast(callback);
1904     return
1905         (access_type == v8::ACCESS_HAS &&
1906            (info->all_can_read() || info->all_can_write())) ||
1907         (access_type == v8::ACCESS_GET && info->all_can_read()) ||
1908         (access_type == v8::ACCESS_SET && info->all_can_write());
1909   }
1910   return false;
1911 }
1912
1913
1914 template<class Key>
1915 static bool CheckGenericAccess(
1916     Handle<JSObject> receiver,
1917     Handle<JSObject> holder,
1918     Key key,
1919     v8::AccessType access_type,
1920     bool (Isolate::*mayAccess)(Handle<JSObject>, Key, v8::AccessType)) {
1921   Isolate* isolate = receiver->GetIsolate();
1922   for (Handle<JSObject> current = receiver;
1923        true;
1924        current = handle(JSObject::cast(current->GetPrototype()), isolate)) {
1925     if (current->IsAccessCheckNeeded() &&
1926         !(isolate->*mayAccess)(current, key, access_type)) {
1927       return false;
1928     }
1929     if (current.is_identical_to(holder)) break;
1930   }
1931   return true;
1932 }
1933
1934
1935 enum AccessCheckResult {
1936   ACCESS_FORBIDDEN,
1937   ACCESS_ALLOWED,
1938   ACCESS_ABSENT
1939 };
1940
1941
1942 static AccessCheckResult CheckPropertyAccess(Handle<JSObject> obj,
1943                                              Handle<Name> name,
1944                                              v8::AccessType access_type) {
1945   uint32_t index;
1946   if (name->AsArrayIndex(&index)) {
1947     // TODO(1095): we should traverse hidden prototype hierachy as well.
1948     if (CheckGenericAccess(
1949             obj, obj, index, access_type, &Isolate::MayIndexedAccess)) {
1950       return ACCESS_ALLOWED;
1951     }
1952
1953     obj->GetIsolate()->ReportFailedAccessCheck(obj, access_type);
1954     return ACCESS_FORBIDDEN;
1955   }
1956
1957   Isolate* isolate = obj->GetIsolate();
1958   LookupResult lookup(isolate);
1959   obj->LookupOwn(name, &lookup, true);
1960
1961   if (!lookup.IsProperty()) return ACCESS_ABSENT;
1962   Handle<JSObject> holder(lookup.holder(), isolate);
1963   if (CheckGenericAccess<Handle<Object> >(
1964           obj, holder, name, access_type, &Isolate::MayNamedAccess)) {
1965     return ACCESS_ALLOWED;
1966   }
1967
1968   // Access check callback denied the access, but some properties
1969   // can have a special permissions which override callbacks descision
1970   // (currently see v8::AccessControl).
1971   // API callbacks can have per callback access exceptions.
1972   switch (lookup.type()) {
1973     case CALLBACKS:
1974       if (CheckAccessException(lookup.GetCallbackObject(), access_type)) {
1975         return ACCESS_ALLOWED;
1976       }
1977       break;
1978     case INTERCEPTOR:
1979       // If the object has an interceptor, try real named properties.
1980       // Overwrite the result to fetch the correct property later.
1981       holder->LookupRealNamedProperty(name, &lookup);
1982       if (lookup.IsProperty() && lookup.IsPropertyCallbacks()) {
1983         if (CheckAccessException(lookup.GetCallbackObject(), access_type)) {
1984           return ACCESS_ALLOWED;
1985         }
1986       }
1987       break;
1988     default:
1989       break;
1990   }
1991
1992   isolate->ReportFailedAccessCheck(obj, access_type);
1993   return ACCESS_FORBIDDEN;
1994 }
1995
1996
1997 // Enumerator used as indices into the array returned from GetOwnProperty
1998 enum PropertyDescriptorIndices {
1999   IS_ACCESSOR_INDEX,
2000   VALUE_INDEX,
2001   GETTER_INDEX,
2002   SETTER_INDEX,
2003   WRITABLE_INDEX,
2004   ENUMERABLE_INDEX,
2005   CONFIGURABLE_INDEX,
2006   DESCRIPTOR_SIZE
2007 };
2008
2009
2010 MUST_USE_RESULT static MaybeHandle<Object> GetOwnProperty(Isolate* isolate,
2011                                                           Handle<JSObject> obj,
2012                                                           Handle<Name> name) {
2013   Heap* heap = isolate->heap();
2014   Factory* factory = isolate->factory();
2015   // Due to some WebKit tests, we want to make sure that we do not log
2016   // more than one access failure here.
2017   AccessCheckResult access_check_result =
2018       CheckPropertyAccess(obj, name, v8::ACCESS_HAS);
2019   RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
2020   switch (access_check_result) {
2021     case ACCESS_FORBIDDEN: return factory->false_value();
2022     case ACCESS_ALLOWED: break;
2023     case ACCESS_ABSENT: return factory->undefined_value();
2024   }
2025
2026   PropertyAttributes attrs = JSReceiver::GetOwnPropertyAttributes(obj, name);
2027   if (attrs == ABSENT) {
2028     RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
2029     return factory->undefined_value();
2030   }
2031   ASSERT(!isolate->has_scheduled_exception());
2032   Handle<AccessorPair> accessors;
2033   bool has_accessors =
2034       JSObject::GetOwnPropertyAccessorPair(obj, name).ToHandle(&accessors);
2035   Handle<FixedArray> elms = isolate->factory()->NewFixedArray(DESCRIPTOR_SIZE);
2036   elms->set(ENUMERABLE_INDEX, heap->ToBoolean((attrs & DONT_ENUM) == 0));
2037   elms->set(CONFIGURABLE_INDEX, heap->ToBoolean((attrs & DONT_DELETE) == 0));
2038   elms->set(IS_ACCESSOR_INDEX, heap->ToBoolean(has_accessors));
2039
2040   if (!has_accessors) {
2041     elms->set(WRITABLE_INDEX, heap->ToBoolean((attrs & READ_ONLY) == 0));
2042     // Runtime::GetObjectProperty does access check.
2043     Handle<Object> value;
2044     ASSIGN_RETURN_ON_EXCEPTION(
2045         isolate, value, Runtime::GetObjectProperty(isolate, obj, name),
2046         Object);
2047     elms->set(VALUE_INDEX, *value);
2048   } else {
2049     // Access checks are performed for both accessors separately.
2050     // When they fail, the respective field is not set in the descriptor.
2051     Handle<Object> getter(accessors->GetComponent(ACCESSOR_GETTER), isolate);
2052     Handle<Object> setter(accessors->GetComponent(ACCESSOR_SETTER), isolate);
2053
2054     if (!getter->IsMap() && CheckPropertyAccess(obj, name, v8::ACCESS_GET)) {
2055       ASSERT(!isolate->has_scheduled_exception());
2056       elms->set(GETTER_INDEX, *getter);
2057     } else {
2058       RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
2059     }
2060
2061     if (!setter->IsMap() && CheckPropertyAccess(obj, name, v8::ACCESS_SET)) {
2062       ASSERT(!isolate->has_scheduled_exception());
2063       elms->set(SETTER_INDEX, *setter);
2064     } else {
2065       RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
2066     }
2067   }
2068
2069   return isolate->factory()->NewJSArrayWithElements(elms);
2070 }
2071
2072
2073 // Returns an array with the property description:
2074 //  if args[1] is not a property on args[0]
2075 //          returns undefined
2076 //  if args[1] is a data property on args[0]
2077 //         [false, value, Writeable, Enumerable, Configurable]
2078 //  if args[1] is an accessor on args[0]
2079 //         [true, GetFunction, SetFunction, Enumerable, Configurable]
2080 RUNTIME_FUNCTION(Runtime_GetOwnProperty) {
2081   HandleScope scope(isolate);
2082   ASSERT(args.length() == 2);
2083   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
2084   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
2085   Handle<Object> result;
2086   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
2087       isolate, result, GetOwnProperty(isolate, obj, name));
2088   return *result;
2089 }
2090
2091
2092 RUNTIME_FUNCTION(Runtime_PreventExtensions) {
2093   HandleScope scope(isolate);
2094   ASSERT(args.length() == 1);
2095   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
2096   Handle<Object> result;
2097   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
2098       isolate, result, JSObject::PreventExtensions(obj));
2099   return *result;
2100 }
2101
2102
2103 RUNTIME_FUNCTION(Runtime_IsExtensible) {
2104   SealHandleScope shs(isolate);
2105   ASSERT(args.length() == 1);
2106   CONVERT_ARG_CHECKED(JSObject, obj, 0);
2107   if (obj->IsJSGlobalProxy()) {
2108     Object* proto = obj->GetPrototype();
2109     if (proto->IsNull()) return isolate->heap()->false_value();
2110     ASSERT(proto->IsJSGlobalObject());
2111     obj = JSObject::cast(proto);
2112   }
2113   return isolate->heap()->ToBoolean(obj->map()->is_extensible());
2114 }
2115
2116
2117 RUNTIME_FUNCTION(Runtime_RegExpCompile) {
2118   HandleScope scope(isolate);
2119   ASSERT(args.length() == 3);
2120   CONVERT_ARG_HANDLE_CHECKED(JSRegExp, re, 0);
2121   CONVERT_ARG_HANDLE_CHECKED(String, pattern, 1);
2122   CONVERT_ARG_HANDLE_CHECKED(String, flags, 2);
2123   Handle<Object> result;
2124   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
2125       isolate, result, RegExpImpl::Compile(re, pattern, flags));
2126   return *result;
2127 }
2128
2129
2130 RUNTIME_FUNCTION(Runtime_CreateApiFunction) {
2131   HandleScope scope(isolate);
2132   ASSERT(args.length() == 2);
2133   CONVERT_ARG_HANDLE_CHECKED(FunctionTemplateInfo, data, 0);
2134   CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
2135   return *isolate->factory()->CreateApiFunction(data, prototype);
2136 }
2137
2138
2139 RUNTIME_FUNCTION(Runtime_IsTemplate) {
2140   SealHandleScope shs(isolate);
2141   ASSERT(args.length() == 1);
2142   CONVERT_ARG_HANDLE_CHECKED(Object, arg, 0);
2143   bool result = arg->IsObjectTemplateInfo() || arg->IsFunctionTemplateInfo();
2144   return isolate->heap()->ToBoolean(result);
2145 }
2146
2147
2148 RUNTIME_FUNCTION(Runtime_GetTemplateField) {
2149   SealHandleScope shs(isolate);
2150   ASSERT(args.length() == 2);
2151   CONVERT_ARG_CHECKED(HeapObject, templ, 0);
2152   CONVERT_SMI_ARG_CHECKED(index, 1);
2153   int offset = index * kPointerSize + HeapObject::kHeaderSize;
2154   InstanceType type = templ->map()->instance_type();
2155   RUNTIME_ASSERT(type == FUNCTION_TEMPLATE_INFO_TYPE ||
2156                  type == OBJECT_TEMPLATE_INFO_TYPE);
2157   RUNTIME_ASSERT(offset > 0);
2158   if (type == FUNCTION_TEMPLATE_INFO_TYPE) {
2159     RUNTIME_ASSERT(offset < FunctionTemplateInfo::kSize);
2160   } else {
2161     RUNTIME_ASSERT(offset < ObjectTemplateInfo::kSize);
2162   }
2163   return *HeapObject::RawField(templ, offset);
2164 }
2165
2166
2167 RUNTIME_FUNCTION(Runtime_DisableAccessChecks) {
2168   HandleScope scope(isolate);
2169   ASSERT(args.length() == 1);
2170   CONVERT_ARG_HANDLE_CHECKED(HeapObject, object, 0);
2171   Handle<Map> old_map(object->map());
2172   bool needs_access_checks = old_map->is_access_check_needed();
2173   if (needs_access_checks) {
2174     // Copy map so it won't interfere constructor's initial map.
2175     Handle<Map> new_map = Map::Copy(old_map);
2176     new_map->set_is_access_check_needed(false);
2177     if (object->IsJSObject()) {
2178       JSObject::MigrateToMap(Handle<JSObject>::cast(object), new_map);
2179     } else {
2180       object->set_map(*new_map);
2181     }
2182   }
2183   return isolate->heap()->ToBoolean(needs_access_checks);
2184 }
2185
2186
2187 RUNTIME_FUNCTION(Runtime_EnableAccessChecks) {
2188   HandleScope scope(isolate);
2189   ASSERT(args.length() == 1);
2190   CONVERT_ARG_HANDLE_CHECKED(HeapObject, object, 0);
2191   Handle<Map> old_map(object->map());
2192   if (!old_map->is_access_check_needed()) {
2193     // Copy map so it won't interfere constructor's initial map.
2194     Handle<Map> new_map = Map::Copy(old_map);
2195     new_map->set_is_access_check_needed(true);
2196     if (object->IsJSObject()) {
2197       JSObject::MigrateToMap(Handle<JSObject>::cast(object), new_map);
2198     } else {
2199       object->set_map(*new_map);
2200     }
2201   }
2202   return isolate->heap()->undefined_value();
2203 }
2204
2205
2206 // Transform getter or setter into something DefineAccessor can handle.
2207 static Handle<Object> InstantiateAccessorComponent(Isolate* isolate,
2208                                                    Handle<Object> component) {
2209   if (component->IsUndefined()) return isolate->factory()->null_value();
2210   Handle<FunctionTemplateInfo> info =
2211       Handle<FunctionTemplateInfo>::cast(component);
2212   return Utils::OpenHandle(*Utils::ToLocal(info)->GetFunction());
2213 }
2214
2215
2216 RUNTIME_FUNCTION(Runtime_SetAccessorProperty) {
2217   HandleScope scope(isolate);
2218   ASSERT(args.length() == 6);
2219   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
2220   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
2221   CONVERT_ARG_HANDLE_CHECKED(Object, getter, 2);
2222   CONVERT_ARG_HANDLE_CHECKED(Object, setter, 3);
2223   CONVERT_SMI_ARG_CHECKED(attribute, 4);
2224   CONVERT_SMI_ARG_CHECKED(access_control, 5);
2225   RUNTIME_ASSERT(getter->IsUndefined() || getter->IsFunctionTemplateInfo());
2226   RUNTIME_ASSERT(setter->IsUndefined() || setter->IsFunctionTemplateInfo());
2227   RUNTIME_ASSERT(PropertyDetails::AttributesField::is_valid(
2228       static_cast<PropertyAttributes>(attribute)));
2229   JSObject::DefineAccessor(object,
2230                            name,
2231                            InstantiateAccessorComponent(isolate, getter),
2232                            InstantiateAccessorComponent(isolate, setter),
2233                            static_cast<PropertyAttributes>(attribute),
2234                            static_cast<v8::AccessControl>(access_control));
2235   return isolate->heap()->undefined_value();
2236 }
2237
2238
2239 static Object* ThrowRedeclarationError(Isolate* isolate, Handle<String> name) {
2240   HandleScope scope(isolate);
2241   Handle<Object> args[1] = { name };
2242   Handle<Object> error = isolate->factory()->NewTypeError(
2243       "var_redeclaration", HandleVector(args, 1));
2244   return isolate->Throw(*error);
2245 }
2246
2247
2248 RUNTIME_FUNCTION(RuntimeHidden_DeclareGlobals) {
2249   HandleScope scope(isolate);
2250   ASSERT(args.length() == 3);
2251   Handle<GlobalObject> global = Handle<GlobalObject>(
2252       isolate->context()->global_object());
2253
2254   CONVERT_ARG_HANDLE_CHECKED(Context, context, 0);
2255   CONVERT_ARG_HANDLE_CHECKED(FixedArray, pairs, 1);
2256   CONVERT_SMI_ARG_CHECKED(flags, 2);
2257
2258   // Traverse the name/value pairs and set the properties.
2259   int length = pairs->length();
2260   for (int i = 0; i < length; i += 2) {
2261     HandleScope scope(isolate);
2262     Handle<String> name(String::cast(pairs->get(i)));
2263     Handle<Object> value(pairs->get(i + 1), isolate);
2264
2265     // We have to declare a global const property. To capture we only
2266     // assign to it when evaluating the assignment for "const x =
2267     // <expr>" the initial value is the hole.
2268     bool is_var = value->IsUndefined();
2269     bool is_const = value->IsTheHole();
2270     bool is_function = value->IsSharedFunctionInfo();
2271     ASSERT(is_var + is_const + is_function == 1);
2272
2273     if (is_var || is_const) {
2274       // Lookup the property in the global object, and don't set the
2275       // value of the variable if the property is already there.
2276       // Do the lookup own properties only, see ES5 erratum.
2277       LookupResult lookup(isolate);
2278       global->LookupOwn(name, &lookup, true);
2279       if (lookup.IsFound()) {
2280         // We found an existing property. Unless it was an interceptor
2281         // that claims the property is absent, skip this declaration.
2282         if (!lookup.IsInterceptor()) continue;
2283         if (JSReceiver::GetPropertyAttributes(global, name) != ABSENT) continue;
2284         // Fall-through and introduce the absent property by using
2285         // SetProperty.
2286       }
2287     } else if (is_function) {
2288       // Copy the function and update its context. Use it as value.
2289       Handle<SharedFunctionInfo> shared =
2290           Handle<SharedFunctionInfo>::cast(value);
2291       Handle<JSFunction> function =
2292           isolate->factory()->NewFunctionFromSharedFunctionInfo(
2293               shared, context, TENURED);
2294       value = function;
2295     }
2296
2297     LookupResult lookup(isolate);
2298     global->LookupOwn(name, &lookup, true);
2299
2300     // Compute the property attributes. According to ECMA-262,
2301     // the property must be non-configurable except in eval.
2302     int attr = NONE;
2303     bool is_eval = DeclareGlobalsEvalFlag::decode(flags);
2304     if (!is_eval) {
2305       attr |= DONT_DELETE;
2306     }
2307     bool is_native = DeclareGlobalsNativeFlag::decode(flags);
2308     if (is_const || (is_native && is_function)) {
2309       attr |= READ_ONLY;
2310     }
2311
2312     StrictMode strict_mode = DeclareGlobalsStrictMode::decode(flags);
2313
2314     if (!lookup.IsFound() || is_function) {
2315       // If the own property exists, check that we can reconfigure it
2316       // as required for function declarations.
2317       if (lookup.IsFound() && lookup.IsDontDelete()) {
2318         if (lookup.IsReadOnly() || lookup.IsDontEnum() ||
2319             lookup.IsPropertyCallbacks()) {
2320           return ThrowRedeclarationError(isolate, name);
2321         }
2322         // If the existing property is not configurable, keep its attributes.
2323         attr = lookup.GetAttributes();
2324       }
2325       // Define or redefine own property.
2326       RETURN_FAILURE_ON_EXCEPTION(isolate,
2327           JSObject::SetOwnPropertyIgnoreAttributes(
2328               global, name, value, static_cast<PropertyAttributes>(attr)));
2329     } else {
2330       // Do a [[Put]] on the existing (own) property.
2331       RETURN_FAILURE_ON_EXCEPTION(
2332           isolate,
2333           JSObject::SetProperty(
2334               global, name, value, static_cast<PropertyAttributes>(attr),
2335               strict_mode));
2336     }
2337   }
2338
2339   ASSERT(!isolate->has_pending_exception());
2340   return isolate->heap()->undefined_value();
2341 }
2342
2343
2344 RUNTIME_FUNCTION(RuntimeHidden_DeclareContextSlot) {
2345   HandleScope scope(isolate);
2346   ASSERT(args.length() == 4);
2347
2348   // Declarations are always made in a function or native context.  In the
2349   // case of eval code, the context passed is the context of the caller,
2350   // which may be some nested context and not the declaration context.
2351   CONVERT_ARG_HANDLE_CHECKED(Context, context_arg, 0);
2352   Handle<Context> context(context_arg->declaration_context());
2353   CONVERT_ARG_HANDLE_CHECKED(String, name, 1);
2354   CONVERT_SMI_ARG_CHECKED(mode_arg, 2);
2355   PropertyAttributes mode = static_cast<PropertyAttributes>(mode_arg);
2356   RUNTIME_ASSERT(mode == READ_ONLY || mode == NONE);
2357   CONVERT_ARG_HANDLE_CHECKED(Object, initial_value, 3);
2358
2359   int index;
2360   PropertyAttributes attributes;
2361   ContextLookupFlags flags = DONT_FOLLOW_CHAINS;
2362   BindingFlags binding_flags;
2363   Handle<Object> holder =
2364       context->Lookup(name, flags, &index, &attributes, &binding_flags);
2365
2366   if (attributes != ABSENT) {
2367     // The name was declared before; check for conflicting re-declarations.
2368     // Note: this is actually inconsistent with what happens for globals (where
2369     // we silently ignore such declarations).
2370     if (((attributes & READ_ONLY) != 0) || (mode == READ_ONLY)) {
2371       // Functions are not read-only.
2372       ASSERT(mode != READ_ONLY || initial_value->IsTheHole());
2373       return ThrowRedeclarationError(isolate, name);
2374     }
2375
2376     // Initialize it if necessary.
2377     if (*initial_value != NULL) {
2378       if (index >= 0) {
2379         ASSERT(holder.is_identical_to(context));
2380         if (((attributes & READ_ONLY) == 0) ||
2381             context->get(index)->IsTheHole()) {
2382           context->set(index, *initial_value);
2383         }
2384       } else {
2385         // Slow case: The property is in the context extension object of a
2386         // function context or the global object of a native context.
2387         Handle<JSObject> object = Handle<JSObject>::cast(holder);
2388         RETURN_FAILURE_ON_EXCEPTION(
2389             isolate,
2390             JSReceiver::SetProperty(object, name, initial_value, mode, SLOPPY));
2391       }
2392     }
2393
2394   } else {
2395     // The property is not in the function context. It needs to be
2396     // "declared" in the function context's extension context or as a
2397     // property of the the global object.
2398     Handle<JSObject> object;
2399     if (context->has_extension()) {
2400       object = Handle<JSObject>(JSObject::cast(context->extension()));
2401     } else {
2402       // Context extension objects are allocated lazily.
2403       ASSERT(context->IsFunctionContext());
2404       object = isolate->factory()->NewJSObject(
2405           isolate->context_extension_function());
2406       context->set_extension(*object);
2407     }
2408     ASSERT(*object != NULL);
2409
2410     // Declare the property by setting it to the initial value if provided,
2411     // or undefined, and use the correct mode (e.g. READ_ONLY attribute for
2412     // constant declarations).
2413     ASSERT(!JSReceiver::HasOwnProperty(object, name));
2414     Handle<Object> value(isolate->heap()->undefined_value(), isolate);
2415     if (*initial_value != NULL) value = initial_value;
2416     // Declaring a const context slot is a conflicting declaration if
2417     // there is a callback with that name in a prototype. It is
2418     // allowed to introduce const variables in
2419     // JSContextExtensionObjects. They are treated specially in
2420     // SetProperty and no setters are invoked for those since they are
2421     // not real JSObjects.
2422     if (initial_value->IsTheHole() &&
2423         !object->IsJSContextExtensionObject()) {
2424       LookupResult lookup(isolate);
2425       object->Lookup(name, &lookup);
2426       if (lookup.IsPropertyCallbacks()) {
2427         return ThrowRedeclarationError(isolate, name);
2428       }
2429     }
2430     if (object->IsJSGlobalObject()) {
2431       // Define own property on the global object.
2432       RETURN_FAILURE_ON_EXCEPTION(isolate,
2433          JSObject::SetOwnPropertyIgnoreAttributes(object, name, value, mode));
2434     } else {
2435       RETURN_FAILURE_ON_EXCEPTION(isolate,
2436          JSReceiver::SetProperty(object, name, value, mode, SLOPPY));
2437     }
2438   }
2439
2440   return isolate->heap()->undefined_value();
2441 }
2442
2443
2444 RUNTIME_FUNCTION(Runtime_InitializeVarGlobal) {
2445   HandleScope scope(isolate);
2446   // args[0] == name
2447   // args[1] == language_mode
2448   // args[2] == value (optional)
2449
2450   // Determine if we need to assign to the variable if it already
2451   // exists (based on the number of arguments).
2452   RUNTIME_ASSERT(args.length() == 2 || args.length() == 3);
2453   bool assign = args.length() == 3;
2454
2455   CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
2456   CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 1);
2457
2458   // According to ECMA-262, section 12.2, page 62, the property must
2459   // not be deletable.
2460   PropertyAttributes attributes = DONT_DELETE;
2461
2462   // Lookup the property as own on the global object. If it isn't
2463   // there, there is a property with this name in the prototype chain.
2464   // We follow Safari and Firefox behavior and only set the property
2465   // if there is an explicit initialization value that we have
2466   // to assign to the property.
2467   // Note that objects can have hidden prototypes, so we need to traverse
2468   // the whole chain of hidden prototypes to do an 'own' lookup.
2469   LookupResult lookup(isolate);
2470   isolate->context()->global_object()->LookupOwn(name, &lookup, true);
2471   if (lookup.IsInterceptor()) {
2472     Handle<JSObject> holder(lookup.holder());
2473     PropertyAttributes intercepted =
2474         JSReceiver::GetPropertyAttributes(holder, name);
2475     if (intercepted != ABSENT && (intercepted & READ_ONLY) == 0) {
2476       // Found an interceptor that's not read only.
2477       if (assign) {
2478         CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
2479         Handle<Object> result;
2480         ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
2481             isolate, result,
2482             JSObject::SetPropertyForResult(
2483                 holder, &lookup, name, value, attributes, strict_mode));
2484         return *result;
2485       } else {
2486         return isolate->heap()->undefined_value();
2487       }
2488     }
2489   }
2490
2491   if (assign) {
2492     CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
2493     Handle<GlobalObject> global(isolate->context()->global_object());
2494     Handle<Object> result;
2495     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
2496         isolate, result,
2497         JSReceiver::SetProperty(global, name, value, attributes, strict_mode));
2498     return *result;
2499   }
2500   return isolate->heap()->undefined_value();
2501 }
2502
2503
2504 RUNTIME_FUNCTION(RuntimeHidden_InitializeConstGlobal) {
2505   SealHandleScope shs(isolate);
2506   // All constants are declared with an initial value. The name
2507   // of the constant is the first argument and the initial value
2508   // is the second.
2509   RUNTIME_ASSERT(args.length() == 2);
2510   CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
2511   CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
2512
2513   // Get the current global object from top.
2514   GlobalObject* global = isolate->context()->global_object();
2515
2516   // According to ECMA-262, section 12.2, page 62, the property must
2517   // not be deletable. Since it's a const, it must be READ_ONLY too.
2518   PropertyAttributes attributes =
2519       static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY);
2520
2521   // Lookup the property as own on the global object. If it isn't
2522   // there, we add the property and take special precautions to always
2523   // add it even in case of callbacks in the prototype chain (this rules
2524   // out using SetProperty). We use SetOwnPropertyIgnoreAttributes instead
2525   LookupResult lookup(isolate);
2526   global->LookupOwn(name, &lookup);
2527   if (!lookup.IsFound()) {
2528     HandleScope handle_scope(isolate);
2529     Handle<GlobalObject> global(isolate->context()->global_object());
2530     RETURN_FAILURE_ON_EXCEPTION(
2531         isolate,
2532         JSObject::SetOwnPropertyIgnoreAttributes(global, name, value,
2533                                                  attributes));
2534     return *value;
2535   }
2536
2537   if (!lookup.IsReadOnly()) {
2538     // Restore global object from context (in case of GC) and continue
2539     // with setting the value.
2540     HandleScope handle_scope(isolate);
2541     Handle<GlobalObject> global(isolate->context()->global_object());
2542
2543     // BUG 1213575: Handle the case where we have to set a read-only
2544     // property through an interceptor and only do it if it's
2545     // uninitialized, e.g. the hole. Nirk...
2546     // Passing sloppy mode because the property is writable.
2547     RETURN_FAILURE_ON_EXCEPTION(
2548         isolate,
2549         JSReceiver::SetProperty(global, name, value, attributes, SLOPPY));
2550     return *value;
2551   }
2552
2553   // Set the value, but only if we're assigning the initial value to a
2554   // constant. For now, we determine this by checking if the
2555   // current value is the hole.
2556   // Strict mode handling not needed (const is disallowed in strict mode).
2557   if (lookup.IsField()) {
2558     FixedArray* properties = global->properties();
2559     int index = lookup.GetFieldIndex().outobject_array_index();
2560     if (properties->get(index)->IsTheHole() || !lookup.IsReadOnly()) {
2561       properties->set(index, *value);
2562     }
2563   } else if (lookup.IsNormal()) {
2564     if (global->GetNormalizedProperty(&lookup)->IsTheHole() ||
2565         !lookup.IsReadOnly()) {
2566       HandleScope scope(isolate);
2567       JSObject::SetNormalizedProperty(Handle<JSObject>(global), &lookup, value);
2568     }
2569   } else {
2570     // Ignore re-initialization of constants that have already been
2571     // assigned a constant value.
2572     ASSERT(lookup.IsReadOnly() && lookup.IsConstant());
2573   }
2574
2575   // Use the set value as the result of the operation.
2576   return *value;
2577 }
2578
2579
2580 RUNTIME_FUNCTION(RuntimeHidden_InitializeConstContextSlot) {
2581   HandleScope scope(isolate);
2582   ASSERT(args.length() == 3);
2583
2584   CONVERT_ARG_HANDLE_CHECKED(Object, value, 0);
2585   ASSERT(!value->IsTheHole());
2586   // Initializations are always done in a function or native context.
2587   CONVERT_ARG_HANDLE_CHECKED(Context, context_arg, 1);
2588   Handle<Context> context(context_arg->declaration_context());
2589   CONVERT_ARG_HANDLE_CHECKED(String, name, 2);
2590
2591   int index;
2592   PropertyAttributes attributes;
2593   ContextLookupFlags flags = FOLLOW_CHAINS;
2594   BindingFlags binding_flags;
2595   Handle<Object> holder =
2596       context->Lookup(name, flags, &index, &attributes, &binding_flags);
2597
2598   if (index >= 0) {
2599     ASSERT(holder->IsContext());
2600     // Property was found in a context.  Perform the assignment if we
2601     // found some non-constant or an uninitialized constant.
2602     Handle<Context> context = Handle<Context>::cast(holder);
2603     if ((attributes & READ_ONLY) == 0 || context->get(index)->IsTheHole()) {
2604       context->set(index, *value);
2605     }
2606     return *value;
2607   }
2608
2609   // The property could not be found, we introduce it as a property of the
2610   // global object.
2611   if (attributes == ABSENT) {
2612     Handle<JSObject> global = Handle<JSObject>(
2613         isolate->context()->global_object());
2614     // Strict mode not needed (const disallowed in strict mode).
2615     RETURN_FAILURE_ON_EXCEPTION(
2616         isolate,
2617         JSReceiver::SetProperty(global, name, value, NONE, SLOPPY));
2618     return *value;
2619   }
2620
2621   // The property was present in some function's context extension object,
2622   // as a property on the subject of a with, or as a property of the global
2623   // object.
2624   //
2625   // In most situations, eval-introduced consts should still be present in
2626   // the context extension object.  However, because declaration and
2627   // initialization are separate, the property might have been deleted
2628   // before we reach the initialization point.
2629   //
2630   // Example:
2631   //
2632   //    function f() { eval("delete x; const x;"); }
2633   //
2634   // In that case, the initialization behaves like a normal assignment.
2635   Handle<JSObject> object = Handle<JSObject>::cast(holder);
2636
2637   if (*object == context->extension()) {
2638     // This is the property that was introduced by the const declaration.
2639     // Set it if it hasn't been set before.  NOTE: We cannot use
2640     // GetProperty() to get the current value as it 'unholes' the value.
2641     LookupResult lookup(isolate);
2642     object->LookupOwnRealNamedProperty(name, &lookup);
2643     ASSERT(lookup.IsFound());  // the property was declared
2644     ASSERT(lookup.IsReadOnly());  // and it was declared as read-only
2645
2646     if (lookup.IsField()) {
2647       FixedArray* properties = object->properties();
2648       FieldIndex index = lookup.GetFieldIndex();
2649       ASSERT(!index.is_inobject());
2650       if (properties->get(index.outobject_array_index())->IsTheHole()) {
2651         properties->set(index.outobject_array_index(), *value);
2652       }
2653     } else if (lookup.IsNormal()) {
2654       if (object->GetNormalizedProperty(&lookup)->IsTheHole()) {
2655         JSObject::SetNormalizedProperty(object, &lookup, value);
2656       }
2657     } else {
2658       // We should not reach here. Any real, named property should be
2659       // either a field or a dictionary slot.
2660       UNREACHABLE();
2661     }
2662   } else {
2663     // The property was found on some other object.  Set it if it is not a
2664     // read-only property.
2665     if ((attributes & READ_ONLY) == 0) {
2666       // Strict mode not needed (const disallowed in strict mode).
2667       RETURN_FAILURE_ON_EXCEPTION(
2668           isolate,
2669           JSReceiver::SetProperty(object, name, value, attributes, SLOPPY));
2670     }
2671   }
2672
2673   return *value;
2674 }
2675
2676
2677 RUNTIME_FUNCTION(Runtime_OptimizeObjectForAddingMultipleProperties) {
2678   HandleScope scope(isolate);
2679   ASSERT(args.length() == 2);
2680   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
2681   CONVERT_SMI_ARG_CHECKED(properties, 1);
2682   // Conservative upper limit to prevent fuzz tests from going OOM.
2683   RUNTIME_ASSERT(properties <= 100000);
2684   if (object->HasFastProperties() && !object->IsJSGlobalProxy()) {
2685     JSObject::NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, properties);
2686   }
2687   return *object;
2688 }
2689
2690
2691 RUNTIME_FUNCTION(RuntimeHidden_RegExpExec) {
2692   HandleScope scope(isolate);
2693   ASSERT(args.length() == 4);
2694   CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0);
2695   CONVERT_ARG_HANDLE_CHECKED(String, subject, 1);
2696   // Due to the way the JS calls are constructed this must be less than the
2697   // length of a string, i.e. it is always a Smi.  We check anyway for security.
2698   CONVERT_SMI_ARG_CHECKED(index, 2);
2699   CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 3);
2700   RUNTIME_ASSERT(index >= 0);
2701   RUNTIME_ASSERT(index <= subject->length());
2702   isolate->counters()->regexp_entry_runtime()->Increment();
2703   Handle<Object> result;
2704   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
2705       isolate, result,
2706       RegExpImpl::Exec(regexp, subject, index, last_match_info));
2707   return *result;
2708 }
2709
2710
2711 RUNTIME_FUNCTION(RuntimeHidden_RegExpConstructResult) {
2712   HandleScope handle_scope(isolate);
2713   ASSERT(args.length() == 3);
2714   CONVERT_SMI_ARG_CHECKED(size, 0);
2715   RUNTIME_ASSERT(size >= 0 && size <= FixedArray::kMaxLength);
2716   CONVERT_ARG_HANDLE_CHECKED(Object, index, 1);
2717   CONVERT_ARG_HANDLE_CHECKED(Object, input, 2);
2718   Handle<FixedArray> elements =  isolate->factory()->NewFixedArray(size);
2719   Handle<Map> regexp_map(isolate->native_context()->regexp_result_map());
2720   Handle<JSObject> object =
2721       isolate->factory()->NewJSObjectFromMap(regexp_map, NOT_TENURED, false);
2722   Handle<JSArray> array = Handle<JSArray>::cast(object);
2723   array->set_elements(*elements);
2724   array->set_length(Smi::FromInt(size));
2725   // Write in-object properties after the length of the array.
2726   array->InObjectPropertyAtPut(JSRegExpResult::kIndexIndex, *index);
2727   array->InObjectPropertyAtPut(JSRegExpResult::kInputIndex, *input);
2728   return *array;
2729 }
2730
2731
2732 RUNTIME_FUNCTION(Runtime_RegExpInitializeObject) {
2733   HandleScope scope(isolate);
2734   ASSERT(args.length() == 5);
2735   CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0);
2736   CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
2737   // If source is the empty string we set it to "(?:)" instead as
2738   // suggested by ECMA-262, 5th, section 15.10.4.1.
2739   if (source->length() == 0) source = isolate->factory()->query_colon_string();
2740
2741   CONVERT_ARG_HANDLE_CHECKED(Object, global, 2);
2742   if (!global->IsTrue()) global = isolate->factory()->false_value();
2743
2744   CONVERT_ARG_HANDLE_CHECKED(Object, ignoreCase, 3);
2745   if (!ignoreCase->IsTrue()) ignoreCase = isolate->factory()->false_value();
2746
2747   CONVERT_ARG_HANDLE_CHECKED(Object, multiline, 4);
2748   if (!multiline->IsTrue()) multiline = isolate->factory()->false_value();
2749
2750   Map* map = regexp->map();
2751   Object* constructor = map->constructor();
2752   if (constructor->IsJSFunction() &&
2753       JSFunction::cast(constructor)->initial_map() == map) {
2754     // If we still have the original map, set in-object properties directly.
2755     regexp->InObjectPropertyAtPut(JSRegExp::kSourceFieldIndex, *source);
2756     // Both true and false are immovable immortal objects so no need for write
2757     // barrier.
2758     regexp->InObjectPropertyAtPut(
2759         JSRegExp::kGlobalFieldIndex, *global, SKIP_WRITE_BARRIER);
2760     regexp->InObjectPropertyAtPut(
2761         JSRegExp::kIgnoreCaseFieldIndex, *ignoreCase, SKIP_WRITE_BARRIER);
2762     regexp->InObjectPropertyAtPut(
2763         JSRegExp::kMultilineFieldIndex, *multiline, SKIP_WRITE_BARRIER);
2764     regexp->InObjectPropertyAtPut(
2765         JSRegExp::kLastIndexFieldIndex, Smi::FromInt(0), SKIP_WRITE_BARRIER);
2766     return *regexp;
2767   }
2768
2769   // Map has changed, so use generic, but slower, method.
2770   PropertyAttributes final =
2771       static_cast<PropertyAttributes>(READ_ONLY | DONT_ENUM | DONT_DELETE);
2772   PropertyAttributes writable =
2773       static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
2774   Handle<Object> zero(Smi::FromInt(0), isolate);
2775   Factory* factory = isolate->factory();
2776   JSObject::SetOwnPropertyIgnoreAttributes(
2777       regexp, factory->source_string(), source, final).Check();
2778   JSObject::SetOwnPropertyIgnoreAttributes(
2779       regexp, factory->global_string(), global, final).Check();
2780   JSObject::SetOwnPropertyIgnoreAttributes(
2781       regexp, factory->ignore_case_string(), ignoreCase, final).Check();
2782   JSObject::SetOwnPropertyIgnoreAttributes(
2783       regexp, factory->multiline_string(), multiline, final).Check();
2784   JSObject::SetOwnPropertyIgnoreAttributes(
2785       regexp, factory->last_index_string(), zero, writable).Check();
2786   return *regexp;
2787 }
2788
2789
2790 RUNTIME_FUNCTION(Runtime_FinishArrayPrototypeSetup) {
2791   HandleScope scope(isolate);
2792   ASSERT(args.length() == 1);
2793   CONVERT_ARG_HANDLE_CHECKED(JSArray, prototype, 0);
2794   Object* length = prototype->length();
2795   RUNTIME_ASSERT(length->IsSmi() && Smi::cast(length)->value() == 0);
2796   RUNTIME_ASSERT(prototype->HasFastSmiOrObjectElements());
2797   // This is necessary to enable fast checks for absence of elements
2798   // on Array.prototype and below.
2799   prototype->set_elements(isolate->heap()->empty_fixed_array());
2800   return Smi::FromInt(0);
2801 }
2802
2803
2804 static void InstallBuiltin(Isolate* isolate,
2805                            Handle<JSObject> holder,
2806                            const char* name,
2807                            Builtins::Name builtin_name) {
2808   Handle<String> key = isolate->factory()->InternalizeUtf8String(name);
2809   Handle<Code> code(isolate->builtins()->builtin(builtin_name));
2810   Handle<JSFunction> optimized =
2811       isolate->factory()->NewFunctionWithoutPrototype(key, code);
2812   optimized->shared()->DontAdaptArguments();
2813   JSReceiver::SetProperty(holder, key, optimized, NONE, STRICT).Assert();
2814 }
2815
2816
2817 RUNTIME_FUNCTION(Runtime_SpecialArrayFunctions) {
2818   HandleScope scope(isolate);
2819   ASSERT(args.length() == 0);
2820   Handle<JSObject> holder =
2821       isolate->factory()->NewJSObject(isolate->object_function());
2822
2823   InstallBuiltin(isolate, holder, "pop", Builtins::kArrayPop);
2824   InstallBuiltin(isolate, holder, "push", Builtins::kArrayPush);
2825   InstallBuiltin(isolate, holder, "shift", Builtins::kArrayShift);
2826   InstallBuiltin(isolate, holder, "unshift", Builtins::kArrayUnshift);
2827   InstallBuiltin(isolate, holder, "slice", Builtins::kArraySlice);
2828   InstallBuiltin(isolate, holder, "splice", Builtins::kArraySplice);
2829   InstallBuiltin(isolate, holder, "concat", Builtins::kArrayConcat);
2830
2831   return *holder;
2832 }
2833
2834
2835 RUNTIME_FUNCTION(Runtime_IsSloppyModeFunction) {
2836   SealHandleScope shs(isolate);
2837   ASSERT(args.length() == 1);
2838   CONVERT_ARG_CHECKED(JSReceiver, callable, 0);
2839   if (!callable->IsJSFunction()) {
2840     HandleScope scope(isolate);
2841     Handle<Object> delegate;
2842     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
2843         isolate, delegate,
2844         Execution::TryGetFunctionDelegate(
2845             isolate, Handle<JSReceiver>(callable)));
2846     callable = JSFunction::cast(*delegate);
2847   }
2848   JSFunction* function = JSFunction::cast(callable);
2849   SharedFunctionInfo* shared = function->shared();
2850   return isolate->heap()->ToBoolean(shared->strict_mode() == SLOPPY);
2851 }
2852
2853
2854 RUNTIME_FUNCTION(Runtime_GetDefaultReceiver) {
2855   SealHandleScope shs(isolate);
2856   ASSERT(args.length() == 1);
2857   CONVERT_ARG_CHECKED(JSReceiver, callable, 0);
2858
2859   if (!callable->IsJSFunction()) {
2860     HandleScope scope(isolate);
2861     Handle<Object> delegate;
2862     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
2863         isolate, delegate,
2864         Execution::TryGetFunctionDelegate(
2865             isolate, Handle<JSReceiver>(callable)));
2866     callable = JSFunction::cast(*delegate);
2867   }
2868   JSFunction* function = JSFunction::cast(callable);
2869
2870   SharedFunctionInfo* shared = function->shared();
2871   if (shared->native() || shared->strict_mode() == STRICT) {
2872     return isolate->heap()->undefined_value();
2873   }
2874   // Returns undefined for strict or native functions, or
2875   // the associated global receiver for "normal" functions.
2876
2877   Context* native_context =
2878       function->context()->global_object()->native_context();
2879   return native_context->global_object()->global_receiver();
2880 }
2881
2882
2883 RUNTIME_FUNCTION(RuntimeHidden_MaterializeRegExpLiteral) {
2884   HandleScope scope(isolate);
2885   ASSERT(args.length() == 4);
2886   CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
2887   CONVERT_SMI_ARG_CHECKED(index, 1);
2888   CONVERT_ARG_HANDLE_CHECKED(String, pattern, 2);
2889   CONVERT_ARG_HANDLE_CHECKED(String, flags, 3);
2890
2891   // Get the RegExp function from the context in the literals array.
2892   // This is the RegExp function from the context in which the
2893   // function was created.  We do not use the RegExp function from the
2894   // current native context because this might be the RegExp function
2895   // from another context which we should not have access to.
2896   Handle<JSFunction> constructor =
2897       Handle<JSFunction>(
2898           JSFunction::NativeContextFromLiterals(*literals)->regexp_function());
2899   // Compute the regular expression literal.
2900   Handle<Object> regexp;
2901   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
2902       isolate, regexp,
2903       RegExpImpl::CreateRegExpLiteral(constructor, pattern, flags));
2904   literals->set(index, *regexp);
2905   return *regexp;
2906 }
2907
2908
2909 RUNTIME_FUNCTION(Runtime_FunctionGetName) {
2910   SealHandleScope shs(isolate);
2911   ASSERT(args.length() == 1);
2912
2913   CONVERT_ARG_CHECKED(JSFunction, f, 0);
2914   return f->shared()->name();
2915 }
2916
2917
2918 RUNTIME_FUNCTION(Runtime_FunctionSetName) {
2919   SealHandleScope shs(isolate);
2920   ASSERT(args.length() == 2);
2921
2922   CONVERT_ARG_CHECKED(JSFunction, f, 0);
2923   CONVERT_ARG_CHECKED(String, name, 1);
2924   f->shared()->set_name(name);
2925   return isolate->heap()->undefined_value();
2926 }
2927
2928
2929 RUNTIME_FUNCTION(Runtime_FunctionNameShouldPrintAsAnonymous) {
2930   SealHandleScope shs(isolate);
2931   ASSERT(args.length() == 1);
2932   CONVERT_ARG_CHECKED(JSFunction, f, 0);
2933   return isolate->heap()->ToBoolean(
2934       f->shared()->name_should_print_as_anonymous());
2935 }
2936
2937
2938 RUNTIME_FUNCTION(Runtime_FunctionMarkNameShouldPrintAsAnonymous) {
2939   SealHandleScope shs(isolate);
2940   ASSERT(args.length() == 1);
2941   CONVERT_ARG_CHECKED(JSFunction, f, 0);
2942   f->shared()->set_name_should_print_as_anonymous(true);
2943   return isolate->heap()->undefined_value();
2944 }
2945
2946
2947 RUNTIME_FUNCTION(Runtime_FunctionIsGenerator) {
2948   SealHandleScope shs(isolate);
2949   ASSERT(args.length() == 1);
2950   CONVERT_ARG_CHECKED(JSFunction, f, 0);
2951   return isolate->heap()->ToBoolean(f->shared()->is_generator());
2952 }
2953
2954
2955 RUNTIME_FUNCTION(Runtime_FunctionRemovePrototype) {
2956   SealHandleScope shs(isolate);
2957   ASSERT(args.length() == 1);
2958
2959   CONVERT_ARG_CHECKED(JSFunction, f, 0);
2960   RUNTIME_ASSERT(f->RemovePrototype());
2961
2962   return isolate->heap()->undefined_value();
2963 }
2964
2965
2966 RUNTIME_FUNCTION(Runtime_FunctionGetScript) {
2967   HandleScope scope(isolate);
2968   ASSERT(args.length() == 1);
2969
2970   CONVERT_ARG_CHECKED(JSFunction, fun, 0);
2971   Handle<Object> script = Handle<Object>(fun->shared()->script(), isolate);
2972   if (!script->IsScript()) return isolate->heap()->undefined_value();
2973
2974   return *Script::GetWrapper(Handle<Script>::cast(script));
2975 }
2976
2977
2978 RUNTIME_FUNCTION(Runtime_FunctionGetSourceCode) {
2979   HandleScope scope(isolate);
2980   ASSERT(args.length() == 1);
2981
2982   CONVERT_ARG_HANDLE_CHECKED(JSFunction, f, 0);
2983   Handle<SharedFunctionInfo> shared(f->shared());
2984   return *shared->GetSourceCode();
2985 }
2986
2987
2988 RUNTIME_FUNCTION(Runtime_FunctionGetScriptSourcePosition) {
2989   SealHandleScope shs(isolate);
2990   ASSERT(args.length() == 1);
2991
2992   CONVERT_ARG_CHECKED(JSFunction, fun, 0);
2993   int pos = fun->shared()->start_position();
2994   return Smi::FromInt(pos);
2995 }
2996
2997
2998 RUNTIME_FUNCTION(Runtime_FunctionGetPositionForOffset) {
2999   SealHandleScope shs(isolate);
3000   ASSERT(args.length() == 2);
3001
3002   CONVERT_ARG_CHECKED(Code, code, 0);
3003   CONVERT_NUMBER_CHECKED(int, offset, Int32, args[1]);
3004
3005   RUNTIME_ASSERT(0 <= offset && offset < code->Size());
3006
3007   Address pc = code->address() + offset;
3008   return Smi::FromInt(code->SourcePosition(pc));
3009 }
3010
3011
3012 RUNTIME_FUNCTION(Runtime_FunctionSetInstanceClassName) {
3013   SealHandleScope shs(isolate);
3014   ASSERT(args.length() == 2);
3015
3016   CONVERT_ARG_CHECKED(JSFunction, fun, 0);
3017   CONVERT_ARG_CHECKED(String, name, 1);
3018   fun->SetInstanceClassName(name);
3019   return isolate->heap()->undefined_value();
3020 }
3021
3022
3023 RUNTIME_FUNCTION(Runtime_FunctionSetLength) {
3024   SealHandleScope shs(isolate);
3025   ASSERT(args.length() == 2);
3026
3027   CONVERT_ARG_CHECKED(JSFunction, fun, 0);
3028   CONVERT_SMI_ARG_CHECKED(length, 1);
3029   RUNTIME_ASSERT((length & 0xC0000000) == 0xC0000000 ||
3030                  (length & 0xC0000000) == 0x0);
3031   fun->shared()->set_length(length);
3032   return isolate->heap()->undefined_value();
3033 }
3034
3035
3036 RUNTIME_FUNCTION(Runtime_FunctionSetPrototype) {
3037   HandleScope scope(isolate);
3038   ASSERT(args.length() == 2);
3039
3040   CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
3041   CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
3042   RUNTIME_ASSERT(fun->should_have_prototype());
3043   Accessors::FunctionSetPrototype(fun, value);
3044   return args[0];  // return TOS
3045 }
3046
3047
3048 RUNTIME_FUNCTION(Runtime_FunctionIsAPIFunction) {
3049   SealHandleScope shs(isolate);
3050   ASSERT(args.length() == 1);
3051
3052   CONVERT_ARG_CHECKED(JSFunction, f, 0);
3053   return isolate->heap()->ToBoolean(f->shared()->IsApiFunction());
3054 }
3055
3056
3057 RUNTIME_FUNCTION(Runtime_FunctionIsBuiltin) {
3058   SealHandleScope shs(isolate);
3059   ASSERT(args.length() == 1);
3060
3061   CONVERT_ARG_CHECKED(JSFunction, f, 0);
3062   return isolate->heap()->ToBoolean(f->IsBuiltin());
3063 }
3064
3065
3066 RUNTIME_FUNCTION(Runtime_SetCode) {
3067   HandleScope scope(isolate);
3068   ASSERT(args.length() == 2);
3069
3070   CONVERT_ARG_HANDLE_CHECKED(JSFunction, target, 0);
3071   CONVERT_ARG_HANDLE_CHECKED(JSFunction, source, 1);
3072
3073   Handle<SharedFunctionInfo> target_shared(target->shared());
3074   Handle<SharedFunctionInfo> source_shared(source->shared());
3075   RUNTIME_ASSERT(!source_shared->bound());
3076
3077   if (!Compiler::EnsureCompiled(source, KEEP_EXCEPTION)) {
3078     return isolate->heap()->exception();
3079   }
3080
3081   // Mark both, the source and the target, as un-flushable because the
3082   // shared unoptimized code makes them impossible to enqueue in a list.
3083   ASSERT(target_shared->code()->gc_metadata() == NULL);
3084   ASSERT(source_shared->code()->gc_metadata() == NULL);
3085   target_shared->set_dont_flush(true);
3086   source_shared->set_dont_flush(true);
3087
3088   // Set the code, scope info, formal parameter count, and the length
3089   // of the target shared function info.
3090   target_shared->ReplaceCode(source_shared->code());
3091   target_shared->set_scope_info(source_shared->scope_info());
3092   target_shared->set_length(source_shared->length());
3093   target_shared->set_feedback_vector(source_shared->feedback_vector());
3094   target_shared->set_formal_parameter_count(
3095       source_shared->formal_parameter_count());
3096   target_shared->set_script(source_shared->script());
3097   target_shared->set_start_position_and_type(
3098       source_shared->start_position_and_type());
3099   target_shared->set_end_position(source_shared->end_position());
3100   bool was_native = target_shared->native();
3101   target_shared->set_compiler_hints(source_shared->compiler_hints());
3102   target_shared->set_native(was_native);
3103   target_shared->set_profiler_ticks(source_shared->profiler_ticks());
3104
3105   // Set the code of the target function.
3106   target->ReplaceCode(source_shared->code());
3107   ASSERT(target->next_function_link()->IsUndefined());
3108
3109   // Make sure we get a fresh copy of the literal vector to avoid cross
3110   // context contamination.
3111   Handle<Context> context(source->context());
3112   int number_of_literals = source->NumberOfLiterals();
3113   Handle<FixedArray> literals =
3114       isolate->factory()->NewFixedArray(number_of_literals, TENURED);
3115   if (number_of_literals > 0) {
3116     literals->set(JSFunction::kLiteralNativeContextIndex,
3117                   context->native_context());
3118   }
3119   target->set_context(*context);
3120   target->set_literals(*literals);
3121
3122   if (isolate->logger()->is_logging_code_events() ||
3123       isolate->cpu_profiler()->is_profiling()) {
3124     isolate->logger()->LogExistingFunction(
3125         source_shared, Handle<Code>(source_shared->code()));
3126   }
3127
3128   return *target;
3129 }
3130
3131
3132 RUNTIME_FUNCTION(RuntimeHidden_CreateJSGeneratorObject) {
3133   HandleScope scope(isolate);
3134   ASSERT(args.length() == 0);
3135
3136   JavaScriptFrameIterator it(isolate);
3137   JavaScriptFrame* frame = it.frame();
3138   Handle<JSFunction> function(frame->function());
3139   RUNTIME_ASSERT(function->shared()->is_generator());
3140
3141   Handle<JSGeneratorObject> generator;
3142   if (frame->IsConstructor()) {
3143     generator = handle(JSGeneratorObject::cast(frame->receiver()));
3144   } else {
3145     generator = isolate->factory()->NewJSGeneratorObject(function);
3146   }
3147   generator->set_function(*function);
3148   generator->set_context(Context::cast(frame->context()));
3149   generator->set_receiver(frame->receiver());
3150   generator->set_continuation(0);
3151   generator->set_operand_stack(isolate->heap()->empty_fixed_array());
3152   generator->set_stack_handler_index(-1);
3153
3154   return *generator;
3155 }
3156
3157
3158 RUNTIME_FUNCTION(RuntimeHidden_SuspendJSGeneratorObject) {
3159   HandleScope handle_scope(isolate);
3160   ASSERT(args.length() == 1);
3161   CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator_object, 0);
3162
3163   JavaScriptFrameIterator stack_iterator(isolate);
3164   JavaScriptFrame* frame = stack_iterator.frame();
3165   RUNTIME_ASSERT(frame->function()->shared()->is_generator());
3166   ASSERT_EQ(frame->function(), generator_object->function());
3167
3168   // The caller should have saved the context and continuation already.
3169   ASSERT_EQ(generator_object->context(), Context::cast(frame->context()));
3170   ASSERT_LT(0, generator_object->continuation());
3171
3172   // We expect there to be at least two values on the operand stack: the return
3173   // value of the yield expression, and the argument to this runtime call.
3174   // Neither of those should be saved.
3175   int operands_count = frame->ComputeOperandsCount();
3176   ASSERT_GE(operands_count, 2);
3177   operands_count -= 2;
3178
3179   if (operands_count == 0) {
3180     // Although it's semantically harmless to call this function with an
3181     // operands_count of zero, it is also unnecessary.
3182     ASSERT_EQ(generator_object->operand_stack(),
3183               isolate->heap()->empty_fixed_array());
3184     ASSERT_EQ(generator_object->stack_handler_index(), -1);
3185     // If there are no operands on the stack, there shouldn't be a handler
3186     // active either.
3187     ASSERT(!frame->HasHandler());
3188   } else {
3189     int stack_handler_index = -1;
3190     Handle<FixedArray> operand_stack =
3191         isolate->factory()->NewFixedArray(operands_count);
3192     frame->SaveOperandStack(*operand_stack, &stack_handler_index);
3193     generator_object->set_operand_stack(*operand_stack);
3194     generator_object->set_stack_handler_index(stack_handler_index);
3195   }
3196
3197   return isolate->heap()->undefined_value();
3198 }
3199
3200
3201 // Note that this function is the slow path for resuming generators.  It is only
3202 // called if the suspended activation had operands on the stack, stack handlers
3203 // needing rewinding, or if the resume should throw an exception.  The fast path
3204 // is handled directly in FullCodeGenerator::EmitGeneratorResume(), which is
3205 // inlined into GeneratorNext and GeneratorThrow.  EmitGeneratorResumeResume is
3206 // called in any case, as it needs to reconstruct the stack frame and make space
3207 // for arguments and operands.
3208 RUNTIME_FUNCTION(RuntimeHidden_ResumeJSGeneratorObject) {
3209   SealHandleScope shs(isolate);
3210   ASSERT(args.length() == 3);
3211   CONVERT_ARG_CHECKED(JSGeneratorObject, generator_object, 0);
3212   CONVERT_ARG_CHECKED(Object, value, 1);
3213   CONVERT_SMI_ARG_CHECKED(resume_mode_int, 2);
3214   JavaScriptFrameIterator stack_iterator(isolate);
3215   JavaScriptFrame* frame = stack_iterator.frame();
3216
3217   ASSERT_EQ(frame->function(), generator_object->function());
3218   ASSERT(frame->function()->is_compiled());
3219
3220   STATIC_ASSERT(JSGeneratorObject::kGeneratorExecuting < 0);
3221   STATIC_ASSERT(JSGeneratorObject::kGeneratorClosed == 0);
3222
3223   Address pc = generator_object->function()->code()->instruction_start();
3224   int offset = generator_object->continuation();
3225   ASSERT(offset > 0);
3226   frame->set_pc(pc + offset);
3227   if (FLAG_enable_ool_constant_pool) {
3228     frame->set_constant_pool(
3229         generator_object->function()->code()->constant_pool());
3230   }
3231   generator_object->set_continuation(JSGeneratorObject::kGeneratorExecuting);
3232
3233   FixedArray* operand_stack = generator_object->operand_stack();
3234   int operands_count = operand_stack->length();
3235   if (operands_count != 0) {
3236     frame->RestoreOperandStack(operand_stack,
3237                                generator_object->stack_handler_index());
3238     generator_object->set_operand_stack(isolate->heap()->empty_fixed_array());
3239     generator_object->set_stack_handler_index(-1);
3240   }
3241
3242   JSGeneratorObject::ResumeMode resume_mode =
3243       static_cast<JSGeneratorObject::ResumeMode>(resume_mode_int);
3244   switch (resume_mode) {
3245     case JSGeneratorObject::NEXT:
3246       return value;
3247     case JSGeneratorObject::THROW:
3248       return isolate->Throw(value);
3249   }
3250
3251   UNREACHABLE();
3252   return isolate->ThrowIllegalOperation();
3253 }
3254
3255
3256 RUNTIME_FUNCTION(RuntimeHidden_ThrowGeneratorStateError) {
3257   HandleScope scope(isolate);
3258   ASSERT(args.length() == 1);
3259   CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0);
3260   int continuation = generator->continuation();
3261   const char* message = continuation == JSGeneratorObject::kGeneratorClosed ?
3262       "generator_finished" : "generator_running";
3263   Vector< Handle<Object> > argv = HandleVector<Object>(NULL, 0);
3264   Handle<Object> error = isolate->factory()->NewError(message, argv);
3265   return isolate->Throw(*error);
3266 }
3267
3268
3269 RUNTIME_FUNCTION(Runtime_ObjectFreeze) {
3270   HandleScope scope(isolate);
3271   ASSERT(args.length() == 1);
3272   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
3273
3274   // %ObjectFreeze is a fast path and these cases are handled elsewhere.
3275   RUNTIME_ASSERT(!object->HasSloppyArgumentsElements() &&
3276                  !object->map()->is_observed() &&
3277                  !object->IsJSProxy());
3278
3279   Handle<Object> result;
3280   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, JSObject::Freeze(object));
3281   return *result;
3282 }
3283
3284
3285 RUNTIME_FUNCTION(RuntimeHidden_StringCharCodeAt) {
3286   HandleScope handle_scope(isolate);
3287   ASSERT(args.length() == 2);
3288
3289   CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
3290   CONVERT_NUMBER_CHECKED(uint32_t, i, Uint32, args[1]);
3291
3292   // Flatten the string.  If someone wants to get a char at an index
3293   // in a cons string, it is likely that more indices will be
3294   // accessed.
3295   subject = String::Flatten(subject);
3296
3297   if (i >= static_cast<uint32_t>(subject->length())) {
3298     return isolate->heap()->nan_value();
3299   }
3300
3301   return Smi::FromInt(subject->Get(i));
3302 }
3303
3304
3305 RUNTIME_FUNCTION(Runtime_CharFromCode) {
3306   HandleScope handlescope(isolate);
3307   ASSERT(args.length() == 1);
3308   if (args[0]->IsNumber()) {
3309     CONVERT_NUMBER_CHECKED(uint32_t, code, Uint32, args[0]);
3310     code &= 0xffff;
3311     return *isolate->factory()->LookupSingleCharacterStringFromCode(code);
3312   }
3313   return isolate->heap()->empty_string();
3314 }
3315
3316
3317 class FixedArrayBuilder {
3318  public:
3319   explicit FixedArrayBuilder(Isolate* isolate, int initial_capacity)
3320       : array_(isolate->factory()->NewFixedArrayWithHoles(initial_capacity)),
3321         length_(0),
3322         has_non_smi_elements_(false) {
3323     // Require a non-zero initial size. Ensures that doubling the size to
3324     // extend the array will work.
3325     ASSERT(initial_capacity > 0);
3326   }
3327
3328   explicit FixedArrayBuilder(Handle<FixedArray> backing_store)
3329       : array_(backing_store),
3330         length_(0),
3331         has_non_smi_elements_(false) {
3332     // Require a non-zero initial size. Ensures that doubling the size to
3333     // extend the array will work.
3334     ASSERT(backing_store->length() > 0);
3335   }
3336
3337   bool HasCapacity(int elements) {
3338     int length = array_->length();
3339     int required_length = length_ + elements;
3340     return (length >= required_length);
3341   }
3342
3343   void EnsureCapacity(int elements) {
3344     int length = array_->length();
3345     int required_length = length_ + elements;
3346     if (length < required_length) {
3347       int new_length = length;
3348       do {
3349         new_length *= 2;
3350       } while (new_length < required_length);
3351       Handle<FixedArray> extended_array =
3352           array_->GetIsolate()->factory()->NewFixedArrayWithHoles(new_length);
3353       array_->CopyTo(0, *extended_array, 0, length_);
3354       array_ = extended_array;
3355     }
3356   }
3357
3358   void Add(Object* value) {
3359     ASSERT(!value->IsSmi());
3360     ASSERT(length_ < capacity());
3361     array_->set(length_, value);
3362     length_++;
3363     has_non_smi_elements_ = true;
3364   }
3365
3366   void Add(Smi* value) {
3367     ASSERT(value->IsSmi());
3368     ASSERT(length_ < capacity());
3369     array_->set(length_, value);
3370     length_++;
3371   }
3372
3373   Handle<FixedArray> array() {
3374     return array_;
3375   }
3376
3377   int length() {
3378     return length_;
3379   }
3380
3381   int capacity() {
3382     return array_->length();
3383   }
3384
3385   Handle<JSArray> ToJSArray(Handle<JSArray> target_array) {
3386     JSArray::SetContent(target_array, array_);
3387     target_array->set_length(Smi::FromInt(length_));
3388     return target_array;
3389   }
3390
3391
3392  private:
3393   Handle<FixedArray> array_;
3394   int length_;
3395   bool has_non_smi_elements_;
3396 };
3397
3398
3399 // Forward declarations.
3400 const int kStringBuilderConcatHelperLengthBits = 11;
3401 const int kStringBuilderConcatHelperPositionBits = 19;
3402
3403 template <typename schar>
3404 static inline void StringBuilderConcatHelper(String*,
3405                                              schar*,
3406                                              FixedArray*,
3407                                              int);
3408
3409 typedef BitField<int, 0, kStringBuilderConcatHelperLengthBits>
3410     StringBuilderSubstringLength;
3411 typedef BitField<int,
3412                  kStringBuilderConcatHelperLengthBits,
3413                  kStringBuilderConcatHelperPositionBits>
3414     StringBuilderSubstringPosition;
3415
3416
3417 class ReplacementStringBuilder {
3418  public:
3419   ReplacementStringBuilder(Heap* heap,
3420                            Handle<String> subject,
3421                            int estimated_part_count)
3422       : heap_(heap),
3423         array_builder_(heap->isolate(), estimated_part_count),
3424         subject_(subject),
3425         character_count_(0),
3426         is_ascii_(subject->IsOneByteRepresentation()) {
3427     // Require a non-zero initial size. Ensures that doubling the size to
3428     // extend the array will work.
3429     ASSERT(estimated_part_count > 0);
3430   }
3431
3432   static inline void AddSubjectSlice(FixedArrayBuilder* builder,
3433                                      int from,
3434                                      int to) {
3435     ASSERT(from >= 0);
3436     int length = to - from;
3437     ASSERT(length > 0);
3438     if (StringBuilderSubstringLength::is_valid(length) &&
3439         StringBuilderSubstringPosition::is_valid(from)) {
3440       int encoded_slice = StringBuilderSubstringLength::encode(length) |
3441           StringBuilderSubstringPosition::encode(from);
3442       builder->Add(Smi::FromInt(encoded_slice));
3443     } else {
3444       // Otherwise encode as two smis.
3445       builder->Add(Smi::FromInt(-length));
3446       builder->Add(Smi::FromInt(from));
3447     }
3448   }
3449
3450
3451   void EnsureCapacity(int elements) {
3452     array_builder_.EnsureCapacity(elements);
3453   }
3454
3455
3456   void AddSubjectSlice(int from, int to) {
3457     AddSubjectSlice(&array_builder_, from, to);
3458     IncrementCharacterCount(to - from);
3459   }
3460
3461
3462   void AddString(Handle<String> string) {
3463     int length = string->length();
3464     ASSERT(length > 0);
3465     AddElement(*string);
3466     if (!string->IsOneByteRepresentation()) {
3467       is_ascii_ = false;
3468     }
3469     IncrementCharacterCount(length);
3470   }
3471
3472
3473   MaybeHandle<String> ToString() {
3474     Isolate* isolate = heap_->isolate();
3475     if (array_builder_.length() == 0) {
3476       return isolate->factory()->empty_string();
3477     }
3478
3479     Handle<String> joined_string;
3480     if (is_ascii_) {
3481       Handle<SeqOneByteString> seq;
3482       ASSIGN_RETURN_ON_EXCEPTION(
3483           isolate, seq,
3484           isolate->factory()->NewRawOneByteString(character_count_),
3485           String);
3486
3487       DisallowHeapAllocation no_gc;
3488       uint8_t* char_buffer = seq->GetChars();
3489       StringBuilderConcatHelper(*subject_,
3490                                 char_buffer,
3491                                 *array_builder_.array(),
3492                                 array_builder_.length());
3493       joined_string = Handle<String>::cast(seq);
3494     } else {
3495       // Non-ASCII.
3496       Handle<SeqTwoByteString> seq;
3497       ASSIGN_RETURN_ON_EXCEPTION(
3498           isolate, seq,
3499           isolate->factory()->NewRawTwoByteString(character_count_),
3500           String);
3501
3502       DisallowHeapAllocation no_gc;
3503       uc16* char_buffer = seq->GetChars();
3504       StringBuilderConcatHelper(*subject_,
3505                                 char_buffer,
3506                                 *array_builder_.array(),
3507                                 array_builder_.length());
3508       joined_string = Handle<String>::cast(seq);
3509     }
3510     return joined_string;
3511   }
3512
3513
3514   void IncrementCharacterCount(int by) {
3515     if (character_count_ > String::kMaxLength - by) {
3516       STATIC_ASSERT(String::kMaxLength < kMaxInt);
3517       character_count_ = kMaxInt;
3518     } else {
3519       character_count_ += by;
3520     }
3521   }
3522
3523  private:
3524   void AddElement(Object* element) {
3525     ASSERT(element->IsSmi() || element->IsString());
3526     ASSERT(array_builder_.capacity() > array_builder_.length());
3527     array_builder_.Add(element);
3528   }
3529
3530   Heap* heap_;
3531   FixedArrayBuilder array_builder_;
3532   Handle<String> subject_;
3533   int character_count_;
3534   bool is_ascii_;
3535 };
3536
3537
3538 class CompiledReplacement {
3539  public:
3540   explicit CompiledReplacement(Zone* zone)
3541       : parts_(1, zone), replacement_substrings_(0, zone), zone_(zone) {}
3542
3543   // Return whether the replacement is simple.
3544   bool Compile(Handle<String> replacement,
3545                int capture_count,
3546                int subject_length);
3547
3548   // Use Apply only if Compile returned false.
3549   void Apply(ReplacementStringBuilder* builder,
3550              int match_from,
3551              int match_to,
3552              int32_t* match);
3553
3554   // Number of distinct parts of the replacement pattern.
3555   int parts() {
3556     return parts_.length();
3557   }
3558
3559   Zone* zone() const { return zone_; }
3560
3561  private:
3562   enum PartType {
3563     SUBJECT_PREFIX = 1,
3564     SUBJECT_SUFFIX,
3565     SUBJECT_CAPTURE,
3566     REPLACEMENT_SUBSTRING,
3567     REPLACEMENT_STRING,
3568
3569     NUMBER_OF_PART_TYPES
3570   };
3571
3572   struct ReplacementPart {
3573     static inline ReplacementPart SubjectMatch() {
3574       return ReplacementPart(SUBJECT_CAPTURE, 0);
3575     }
3576     static inline ReplacementPart SubjectCapture(int capture_index) {
3577       return ReplacementPart(SUBJECT_CAPTURE, capture_index);
3578     }
3579     static inline ReplacementPart SubjectPrefix() {
3580       return ReplacementPart(SUBJECT_PREFIX, 0);
3581     }
3582     static inline ReplacementPart SubjectSuffix(int subject_length) {
3583       return ReplacementPart(SUBJECT_SUFFIX, subject_length);
3584     }
3585     static inline ReplacementPart ReplacementString() {
3586       return ReplacementPart(REPLACEMENT_STRING, 0);
3587     }
3588     static inline ReplacementPart ReplacementSubString(int from, int to) {
3589       ASSERT(from >= 0);
3590       ASSERT(to > from);
3591       return ReplacementPart(-from, to);
3592     }
3593
3594     // If tag <= 0 then it is the negation of a start index of a substring of
3595     // the replacement pattern, otherwise it's a value from PartType.
3596     ReplacementPart(int tag, int data)
3597         : tag(tag), data(data) {
3598       // Must be non-positive or a PartType value.
3599       ASSERT(tag < NUMBER_OF_PART_TYPES);
3600     }
3601     // Either a value of PartType or a non-positive number that is
3602     // the negation of an index into the replacement string.
3603     int tag;
3604     // The data value's interpretation depends on the value of tag:
3605     // tag == SUBJECT_PREFIX ||
3606     // tag == SUBJECT_SUFFIX:  data is unused.
3607     // tag == SUBJECT_CAPTURE: data is the number of the capture.
3608     // tag == REPLACEMENT_SUBSTRING ||
3609     // tag == REPLACEMENT_STRING:    data is index into array of substrings
3610     //                               of the replacement string.
3611     // tag <= 0: Temporary representation of the substring of the replacement
3612     //           string ranging over -tag .. data.
3613     //           Is replaced by REPLACEMENT_{SUB,}STRING when we create the
3614     //           substring objects.
3615     int data;
3616   };
3617
3618   template<typename Char>
3619   bool ParseReplacementPattern(ZoneList<ReplacementPart>* parts,
3620                                Vector<Char> characters,
3621                                int capture_count,
3622                                int subject_length,
3623                                Zone* zone) {
3624     int length = characters.length();
3625     int last = 0;
3626     for (int i = 0; i < length; i++) {
3627       Char c = characters[i];
3628       if (c == '$') {
3629         int next_index = i + 1;
3630         if (next_index == length) {  // No next character!
3631           break;
3632         }
3633         Char c2 = characters[next_index];
3634         switch (c2) {
3635         case '$':
3636           if (i > last) {
3637             // There is a substring before. Include the first "$".
3638             parts->Add(ReplacementPart::ReplacementSubString(last, next_index),
3639                        zone);
3640             last = next_index + 1;  // Continue after the second "$".
3641           } else {
3642             // Let the next substring start with the second "$".
3643             last = next_index;
3644           }
3645           i = next_index;
3646           break;
3647         case '`':
3648           if (i > last) {
3649             parts->Add(ReplacementPart::ReplacementSubString(last, i), zone);
3650           }
3651           parts->Add(ReplacementPart::SubjectPrefix(), zone);
3652           i = next_index;
3653           last = i + 1;
3654           break;
3655         case '\'':
3656           if (i > last) {
3657             parts->Add(ReplacementPart::ReplacementSubString(last, i), zone);
3658           }
3659           parts->Add(ReplacementPart::SubjectSuffix(subject_length), zone);
3660           i = next_index;
3661           last = i + 1;
3662           break;
3663         case '&':
3664           if (i > last) {
3665             parts->Add(ReplacementPart::ReplacementSubString(last, i), zone);
3666           }
3667           parts->Add(ReplacementPart::SubjectMatch(), zone);
3668           i = next_index;
3669           last = i + 1;
3670           break;
3671         case '0':
3672         case '1':
3673         case '2':
3674         case '3':
3675         case '4':
3676         case '5':
3677         case '6':
3678         case '7':
3679         case '8':
3680         case '9': {
3681           int capture_ref = c2 - '0';
3682           if (capture_ref > capture_count) {
3683             i = next_index;
3684             continue;
3685           }
3686           int second_digit_index = next_index + 1;
3687           if (second_digit_index < length) {
3688             // Peek ahead to see if we have two digits.
3689             Char c3 = characters[second_digit_index];
3690             if ('0' <= c3 && c3 <= '9') {  // Double digits.
3691               int double_digit_ref = capture_ref * 10 + c3 - '0';
3692               if (double_digit_ref <= capture_count) {
3693                 next_index = second_digit_index;
3694                 capture_ref = double_digit_ref;
3695               }
3696             }
3697           }
3698           if (capture_ref > 0) {
3699             if (i > last) {
3700               parts->Add(ReplacementPart::ReplacementSubString(last, i), zone);
3701             }
3702             ASSERT(capture_ref <= capture_count);
3703             parts->Add(ReplacementPart::SubjectCapture(capture_ref), zone);
3704             last = next_index + 1;
3705           }
3706           i = next_index;
3707           break;
3708         }
3709         default:
3710           i = next_index;
3711           break;
3712         }
3713       }
3714     }
3715     if (length > last) {
3716       if (last == 0) {
3717         // Replacement is simple.  Do not use Apply to do the replacement.
3718         return true;
3719       } else {
3720         parts->Add(ReplacementPart::ReplacementSubString(last, length), zone);
3721       }
3722     }
3723     return false;
3724   }
3725
3726   ZoneList<ReplacementPart> parts_;
3727   ZoneList<Handle<String> > replacement_substrings_;
3728   Zone* zone_;
3729 };
3730
3731
3732 bool CompiledReplacement::Compile(Handle<String> replacement,
3733                                   int capture_count,
3734                                   int subject_length) {
3735   {
3736     DisallowHeapAllocation no_gc;
3737     String::FlatContent content = replacement->GetFlatContent();
3738     ASSERT(content.IsFlat());
3739     bool simple = false;
3740     if (content.IsAscii()) {
3741       simple = ParseReplacementPattern(&parts_,
3742                                        content.ToOneByteVector(),
3743                                        capture_count,
3744                                        subject_length,
3745                                        zone());
3746     } else {
3747       ASSERT(content.IsTwoByte());
3748       simple = ParseReplacementPattern(&parts_,
3749                                        content.ToUC16Vector(),
3750                                        capture_count,
3751                                        subject_length,
3752                                        zone());
3753     }
3754     if (simple) return true;
3755   }
3756
3757   Isolate* isolate = replacement->GetIsolate();
3758   // Find substrings of replacement string and create them as String objects.
3759   int substring_index = 0;
3760   for (int i = 0, n = parts_.length(); i < n; i++) {
3761     int tag = parts_[i].tag;
3762     if (tag <= 0) {  // A replacement string slice.
3763       int from = -tag;
3764       int to = parts_[i].data;
3765       replacement_substrings_.Add(
3766           isolate->factory()->NewSubString(replacement, from, to), zone());
3767       parts_[i].tag = REPLACEMENT_SUBSTRING;
3768       parts_[i].data = substring_index;
3769       substring_index++;
3770     } else if (tag == REPLACEMENT_STRING) {
3771       replacement_substrings_.Add(replacement, zone());
3772       parts_[i].data = substring_index;
3773       substring_index++;
3774     }
3775   }
3776   return false;
3777 }
3778
3779
3780 void CompiledReplacement::Apply(ReplacementStringBuilder* builder,
3781                                 int match_from,
3782                                 int match_to,
3783                                 int32_t* match) {
3784   ASSERT_LT(0, parts_.length());
3785   for (int i = 0, n = parts_.length(); i < n; i++) {
3786     ReplacementPart part = parts_[i];
3787     switch (part.tag) {
3788       case SUBJECT_PREFIX:
3789         if (match_from > 0) builder->AddSubjectSlice(0, match_from);
3790         break;
3791       case SUBJECT_SUFFIX: {
3792         int subject_length = part.data;
3793         if (match_to < subject_length) {
3794           builder->AddSubjectSlice(match_to, subject_length);
3795         }
3796         break;
3797       }
3798       case SUBJECT_CAPTURE: {
3799         int capture = part.data;
3800         int from = match[capture * 2];
3801         int to = match[capture * 2 + 1];
3802         if (from >= 0 && to > from) {
3803           builder->AddSubjectSlice(from, to);
3804         }
3805         break;
3806       }
3807       case REPLACEMENT_SUBSTRING:
3808       case REPLACEMENT_STRING:
3809         builder->AddString(replacement_substrings_[part.data]);
3810         break;
3811       default:
3812         UNREACHABLE();
3813     }
3814   }
3815 }
3816
3817
3818 void FindAsciiStringIndices(Vector<const uint8_t> subject,
3819                             char pattern,
3820                             ZoneList<int>* indices,
3821                             unsigned int limit,
3822                             Zone* zone) {
3823   ASSERT(limit > 0);
3824   // Collect indices of pattern in subject using memchr.
3825   // Stop after finding at most limit values.
3826   const uint8_t* subject_start = subject.start();
3827   const uint8_t* subject_end = subject_start + subject.length();
3828   const uint8_t* pos = subject_start;
3829   while (limit > 0) {
3830     pos = reinterpret_cast<const uint8_t*>(
3831         memchr(pos, pattern, subject_end - pos));
3832     if (pos == NULL) return;
3833     indices->Add(static_cast<int>(pos - subject_start), zone);
3834     pos++;
3835     limit--;
3836   }
3837 }
3838
3839
3840 void FindTwoByteStringIndices(const Vector<const uc16> subject,
3841                               uc16 pattern,
3842                               ZoneList<int>* indices,
3843                               unsigned int limit,
3844                               Zone* zone) {
3845   ASSERT(limit > 0);
3846   const uc16* subject_start = subject.start();
3847   const uc16* subject_end = subject_start + subject.length();
3848   for (const uc16* pos = subject_start; pos < subject_end && limit > 0; pos++) {
3849     if (*pos == pattern) {
3850       indices->Add(static_cast<int>(pos - subject_start), zone);
3851       limit--;
3852     }
3853   }
3854 }
3855
3856
3857 template <typename SubjectChar, typename PatternChar>
3858 void FindStringIndices(Isolate* isolate,
3859                        Vector<const SubjectChar> subject,
3860                        Vector<const PatternChar> pattern,
3861                        ZoneList<int>* indices,
3862                        unsigned int limit,
3863                        Zone* zone) {
3864   ASSERT(limit > 0);
3865   // Collect indices of pattern in subject.
3866   // Stop after finding at most limit values.
3867   int pattern_length = pattern.length();
3868   int index = 0;
3869   StringSearch<PatternChar, SubjectChar> search(isolate, pattern);
3870   while (limit > 0) {
3871     index = search.Search(subject, index);
3872     if (index < 0) return;
3873     indices->Add(index, zone);
3874     index += pattern_length;
3875     limit--;
3876   }
3877 }
3878
3879
3880 void FindStringIndicesDispatch(Isolate* isolate,
3881                                String* subject,
3882                                String* pattern,
3883                                ZoneList<int>* indices,
3884                                unsigned int limit,
3885                                Zone* zone) {
3886   {
3887     DisallowHeapAllocation no_gc;
3888     String::FlatContent subject_content = subject->GetFlatContent();
3889     String::FlatContent pattern_content = pattern->GetFlatContent();
3890     ASSERT(subject_content.IsFlat());
3891     ASSERT(pattern_content.IsFlat());
3892     if (subject_content.IsAscii()) {
3893       Vector<const uint8_t> subject_vector = subject_content.ToOneByteVector();
3894       if (pattern_content.IsAscii()) {
3895         Vector<const uint8_t> pattern_vector =
3896             pattern_content.ToOneByteVector();
3897         if (pattern_vector.length() == 1) {
3898           FindAsciiStringIndices(subject_vector,
3899                                  pattern_vector[0],
3900                                  indices,
3901                                  limit,
3902                                  zone);
3903         } else {
3904           FindStringIndices(isolate,
3905                             subject_vector,
3906                             pattern_vector,
3907                             indices,
3908                             limit,
3909                             zone);
3910         }
3911       } else {
3912         FindStringIndices(isolate,
3913                           subject_vector,
3914                           pattern_content.ToUC16Vector(),
3915                           indices,
3916                           limit,
3917                           zone);
3918       }
3919     } else {
3920       Vector<const uc16> subject_vector = subject_content.ToUC16Vector();
3921       if (pattern_content.IsAscii()) {
3922         Vector<const uint8_t> pattern_vector =
3923             pattern_content.ToOneByteVector();
3924         if (pattern_vector.length() == 1) {
3925           FindTwoByteStringIndices(subject_vector,
3926                                    pattern_vector[0],
3927                                    indices,
3928                                    limit,
3929                                    zone);
3930         } else {
3931           FindStringIndices(isolate,
3932                             subject_vector,
3933                             pattern_vector,
3934                             indices,
3935                             limit,
3936                             zone);
3937         }
3938       } else {
3939         Vector<const uc16> pattern_vector = pattern_content.ToUC16Vector();
3940         if (pattern_vector.length() == 1) {
3941           FindTwoByteStringIndices(subject_vector,
3942                                    pattern_vector[0],
3943                                    indices,
3944                                    limit,
3945                                    zone);
3946         } else {
3947           FindStringIndices(isolate,
3948                             subject_vector,
3949                             pattern_vector,
3950                             indices,
3951                             limit,
3952                             zone);
3953         }
3954       }
3955     }
3956   }
3957 }
3958
3959
3960 template<typename ResultSeqString>
3961 MUST_USE_RESULT static Object* StringReplaceGlobalAtomRegExpWithString(
3962     Isolate* isolate,
3963     Handle<String> subject,
3964     Handle<JSRegExp> pattern_regexp,
3965     Handle<String> replacement,
3966     Handle<JSArray> last_match_info) {
3967   ASSERT(subject->IsFlat());
3968   ASSERT(replacement->IsFlat());
3969
3970   ZoneScope zone_scope(isolate->runtime_zone());
3971   ZoneList<int> indices(8, zone_scope.zone());
3972   ASSERT_EQ(JSRegExp::ATOM, pattern_regexp->TypeTag());
3973   String* pattern =
3974       String::cast(pattern_regexp->DataAt(JSRegExp::kAtomPatternIndex));
3975   int subject_len = subject->length();
3976   int pattern_len = pattern->length();
3977   int replacement_len = replacement->length();
3978
3979   FindStringIndicesDispatch(
3980       isolate, *subject, pattern, &indices, 0xffffffff, zone_scope.zone());
3981
3982   int matches = indices.length();
3983   if (matches == 0) return *subject;
3984
3985   // Detect integer overflow.
3986   int64_t result_len_64 =
3987       (static_cast<int64_t>(replacement_len) -
3988        static_cast<int64_t>(pattern_len)) *
3989       static_cast<int64_t>(matches) +
3990       static_cast<int64_t>(subject_len);
3991   int result_len;
3992   if (result_len_64 > static_cast<int64_t>(String::kMaxLength)) {
3993     STATIC_ASSERT(String::kMaxLength < kMaxInt);
3994     result_len = kMaxInt;  // Provoke exception.
3995   } else {
3996     result_len = static_cast<int>(result_len_64);
3997   }
3998
3999   int subject_pos = 0;
4000   int result_pos = 0;
4001
4002   MaybeHandle<SeqString> maybe_res;
4003   if (ResultSeqString::kHasAsciiEncoding) {
4004     maybe_res = isolate->factory()->NewRawOneByteString(result_len);
4005   } else {
4006     maybe_res = isolate->factory()->NewRawTwoByteString(result_len);
4007   }
4008   Handle<SeqString> untyped_res;
4009   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, untyped_res, maybe_res);
4010   Handle<ResultSeqString> result = Handle<ResultSeqString>::cast(untyped_res);
4011
4012   for (int i = 0; i < matches; i++) {
4013     // Copy non-matched subject content.
4014     if (subject_pos < indices.at(i)) {
4015       String::WriteToFlat(*subject,
4016                           result->GetChars() + result_pos,
4017                           subject_pos,
4018                           indices.at(i));
4019       result_pos += indices.at(i) - subject_pos;
4020     }
4021
4022     // Replace match.
4023     if (replacement_len > 0) {
4024       String::WriteToFlat(*replacement,
4025                           result->GetChars() + result_pos,
4026                           0,
4027                           replacement_len);
4028       result_pos += replacement_len;
4029     }
4030
4031     subject_pos = indices.at(i) + pattern_len;
4032   }
4033   // Add remaining subject content at the end.
4034   if (subject_pos < subject_len) {
4035     String::WriteToFlat(*subject,
4036                         result->GetChars() + result_pos,
4037                         subject_pos,
4038                         subject_len);
4039   }
4040
4041   int32_t match_indices[] = { indices.at(matches - 1),
4042                               indices.at(matches - 1) + pattern_len };
4043   RegExpImpl::SetLastMatchInfo(last_match_info, subject, 0, match_indices);
4044
4045   return *result;
4046 }
4047
4048
4049 MUST_USE_RESULT static Object* StringReplaceGlobalRegExpWithString(
4050     Isolate* isolate,
4051     Handle<String> subject,
4052     Handle<JSRegExp> regexp,
4053     Handle<String> replacement,
4054     Handle<JSArray> last_match_info) {
4055   ASSERT(subject->IsFlat());
4056   ASSERT(replacement->IsFlat());
4057
4058   int capture_count = regexp->CaptureCount();
4059   int subject_length = subject->length();
4060
4061   // CompiledReplacement uses zone allocation.
4062   ZoneScope zone_scope(isolate->runtime_zone());
4063   CompiledReplacement compiled_replacement(zone_scope.zone());
4064   bool simple_replace = compiled_replacement.Compile(replacement,
4065                                                      capture_count,
4066                                                      subject_length);
4067
4068   // Shortcut for simple non-regexp global replacements
4069   if (regexp->TypeTag() == JSRegExp::ATOM && simple_replace) {
4070     if (subject->HasOnlyOneByteChars() &&
4071         replacement->HasOnlyOneByteChars()) {
4072       return StringReplaceGlobalAtomRegExpWithString<SeqOneByteString>(
4073           isolate, subject, regexp, replacement, last_match_info);
4074     } else {
4075       return StringReplaceGlobalAtomRegExpWithString<SeqTwoByteString>(
4076           isolate, subject, regexp, replacement, last_match_info);
4077     }
4078   }
4079
4080   RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate);
4081   if (global_cache.HasException()) return isolate->heap()->exception();
4082
4083   int32_t* current_match = global_cache.FetchNext();
4084   if (current_match == NULL) {
4085     if (global_cache.HasException()) return isolate->heap()->exception();
4086     return *subject;
4087   }
4088
4089   // Guessing the number of parts that the final result string is built
4090   // from. Global regexps can match any number of times, so we guess
4091   // conservatively.
4092   int expected_parts = (compiled_replacement.parts() + 1) * 4 + 1;
4093   ReplacementStringBuilder builder(isolate->heap(),
4094                                    subject,
4095                                    expected_parts);
4096
4097   // Number of parts added by compiled replacement plus preceeding
4098   // string and possibly suffix after last match.  It is possible for
4099   // all components to use two elements when encoded as two smis.
4100   const int parts_added_per_loop = 2 * (compiled_replacement.parts() + 2);
4101
4102   int prev = 0;
4103
4104   do {
4105     builder.EnsureCapacity(parts_added_per_loop);
4106
4107     int start = current_match[0];
4108     int end = current_match[1];
4109
4110     if (prev < start) {
4111       builder.AddSubjectSlice(prev, start);
4112     }
4113
4114     if (simple_replace) {
4115       builder.AddString(replacement);
4116     } else {
4117       compiled_replacement.Apply(&builder,
4118                                  start,
4119                                  end,
4120                                  current_match);
4121     }
4122     prev = end;
4123
4124     current_match = global_cache.FetchNext();
4125   } while (current_match != NULL);
4126
4127   if (global_cache.HasException()) return isolate->heap()->exception();
4128
4129   if (prev < subject_length) {
4130     builder.EnsureCapacity(2);
4131     builder.AddSubjectSlice(prev, subject_length);
4132   }
4133
4134   RegExpImpl::SetLastMatchInfo(last_match_info,
4135                                subject,
4136                                capture_count,
4137                                global_cache.LastSuccessfulMatch());
4138
4139   Handle<String> result;
4140   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, builder.ToString());
4141   return *result;
4142 }
4143
4144
4145 template <typename ResultSeqString>
4146 MUST_USE_RESULT static Object* StringReplaceGlobalRegExpWithEmptyString(
4147     Isolate* isolate,
4148     Handle<String> subject,
4149     Handle<JSRegExp> regexp,
4150     Handle<JSArray> last_match_info) {
4151   ASSERT(subject->IsFlat());
4152
4153   // Shortcut for simple non-regexp global replacements
4154   if (regexp->TypeTag() == JSRegExp::ATOM) {
4155     Handle<String> empty_string = isolate->factory()->empty_string();
4156     if (subject->IsOneByteRepresentation()) {
4157       return StringReplaceGlobalAtomRegExpWithString<SeqOneByteString>(
4158           isolate, subject, regexp, empty_string, last_match_info);
4159     } else {
4160       return StringReplaceGlobalAtomRegExpWithString<SeqTwoByteString>(
4161           isolate, subject, regexp, empty_string, last_match_info);
4162     }
4163   }
4164
4165   RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate);
4166   if (global_cache.HasException()) return isolate->heap()->exception();
4167
4168   int32_t* current_match = global_cache.FetchNext();
4169   if (current_match == NULL) {
4170     if (global_cache.HasException()) return isolate->heap()->exception();
4171     return *subject;
4172   }
4173
4174   int start = current_match[0];
4175   int end = current_match[1];
4176   int capture_count = regexp->CaptureCount();
4177   int subject_length = subject->length();
4178
4179   int new_length = subject_length - (end - start);
4180   if (new_length == 0) return isolate->heap()->empty_string();
4181
4182   Handle<ResultSeqString> answer;
4183   if (ResultSeqString::kHasAsciiEncoding) {
4184     answer = Handle<ResultSeqString>::cast(
4185         isolate->factory()->NewRawOneByteString(new_length).ToHandleChecked());
4186   } else {
4187     answer = Handle<ResultSeqString>::cast(
4188         isolate->factory()->NewRawTwoByteString(new_length).ToHandleChecked());
4189   }
4190
4191   int prev = 0;
4192   int position = 0;
4193
4194   do {
4195     start = current_match[0];
4196     end = current_match[1];
4197     if (prev < start) {
4198       // Add substring subject[prev;start] to answer string.
4199       String::WriteToFlat(*subject, answer->GetChars() + position, prev, start);
4200       position += start - prev;
4201     }
4202     prev = end;
4203
4204     current_match = global_cache.FetchNext();
4205   } while (current_match != NULL);
4206
4207   if (global_cache.HasException()) return isolate->heap()->exception();
4208
4209   RegExpImpl::SetLastMatchInfo(last_match_info,
4210                                subject,
4211                                capture_count,
4212                                global_cache.LastSuccessfulMatch());
4213
4214   if (prev < subject_length) {
4215     // Add substring subject[prev;length] to answer string.
4216     String::WriteToFlat(
4217         *subject, answer->GetChars() + position, prev, subject_length);
4218     position += subject_length - prev;
4219   }
4220
4221   if (position == 0) return isolate->heap()->empty_string();
4222
4223   // Shorten string and fill
4224   int string_size = ResultSeqString::SizeFor(position);
4225   int allocated_string_size = ResultSeqString::SizeFor(new_length);
4226   int delta = allocated_string_size - string_size;
4227
4228   answer->set_length(position);
4229   if (delta == 0) return *answer;
4230
4231   Address end_of_string = answer->address() + string_size;
4232   Heap* heap = isolate->heap();
4233
4234   // The trimming is performed on a newly allocated object, which is on a
4235   // fresly allocated page or on an already swept page. Hence, the sweeper
4236   // thread can not get confused with the filler creation. No synchronization
4237   // needed.
4238   heap->CreateFillerObjectAt(end_of_string, delta);
4239   heap->AdjustLiveBytes(answer->address(), -delta, Heap::FROM_MUTATOR);
4240   return *answer;
4241 }
4242
4243
4244 RUNTIME_FUNCTION(Runtime_StringReplaceGlobalRegExpWithString) {
4245   HandleScope scope(isolate);
4246   ASSERT(args.length() == 4);
4247
4248   CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
4249   CONVERT_ARG_HANDLE_CHECKED(String, replacement, 2);
4250   CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 1);
4251   CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 3);
4252
4253   RUNTIME_ASSERT(regexp->GetFlags().is_global());
4254   RUNTIME_ASSERT(last_match_info->HasFastObjectElements());
4255
4256   subject = String::Flatten(subject);
4257
4258   if (replacement->length() == 0) {
4259     if (subject->HasOnlyOneByteChars()) {
4260       return StringReplaceGlobalRegExpWithEmptyString<SeqOneByteString>(
4261           isolate, subject, regexp, last_match_info);
4262     } else {
4263       return StringReplaceGlobalRegExpWithEmptyString<SeqTwoByteString>(
4264           isolate, subject, regexp, last_match_info);
4265     }
4266   }
4267
4268   replacement = String::Flatten(replacement);
4269
4270   return StringReplaceGlobalRegExpWithString(
4271       isolate, subject, regexp, replacement, last_match_info);
4272 }
4273
4274
4275 // This may return an empty MaybeHandle if an exception is thrown or
4276 // we abort due to reaching the recursion limit.
4277 MaybeHandle<String> StringReplaceOneCharWithString(Isolate* isolate,
4278                                                    Handle<String> subject,
4279                                                    Handle<String> search,
4280                                                    Handle<String> replace,
4281                                                    bool* found,
4282                                                    int recursion_limit) {
4283   StackLimitCheck stackLimitCheck(isolate);
4284   if (stackLimitCheck.HasOverflowed() || (recursion_limit == 0)) {
4285     return MaybeHandle<String>();
4286   }
4287   recursion_limit--;
4288   if (subject->IsConsString()) {
4289     ConsString* cons = ConsString::cast(*subject);
4290     Handle<String> first = Handle<String>(cons->first());
4291     Handle<String> second = Handle<String>(cons->second());
4292     Handle<String> new_first;
4293     if (!StringReplaceOneCharWithString(
4294             isolate, first, search, replace, found, recursion_limit)
4295             .ToHandle(&new_first)) {
4296       return MaybeHandle<String>();
4297     }
4298     if (*found) return isolate->factory()->NewConsString(new_first, second);
4299
4300     Handle<String> new_second;
4301     if (!StringReplaceOneCharWithString(
4302             isolate, second, search, replace, found, recursion_limit)
4303             .ToHandle(&new_second)) {
4304       return MaybeHandle<String>();
4305     }
4306     if (*found) return isolate->factory()->NewConsString(first, new_second);
4307
4308     return subject;
4309   } else {
4310     int index = Runtime::StringMatch(isolate, subject, search, 0);
4311     if (index == -1) return subject;
4312     *found = true;
4313     Handle<String> first = isolate->factory()->NewSubString(subject, 0, index);
4314     Handle<String> cons1;
4315     ASSIGN_RETURN_ON_EXCEPTION(
4316         isolate, cons1,
4317         isolate->factory()->NewConsString(first, replace),
4318         String);
4319     Handle<String> second =
4320         isolate->factory()->NewSubString(subject, index + 1, subject->length());
4321     return isolate->factory()->NewConsString(cons1, second);
4322   }
4323 }
4324
4325
4326 RUNTIME_FUNCTION(Runtime_StringReplaceOneCharWithString) {
4327   HandleScope scope(isolate);
4328   ASSERT(args.length() == 3);
4329   CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
4330   CONVERT_ARG_HANDLE_CHECKED(String, search, 1);
4331   CONVERT_ARG_HANDLE_CHECKED(String, replace, 2);
4332
4333   // If the cons string tree is too deep, we simply abort the recursion and
4334   // retry with a flattened subject string.
4335   const int kRecursionLimit = 0x1000;
4336   bool found = false;
4337   Handle<String> result;
4338   if (StringReplaceOneCharWithString(
4339           isolate, subject, search, replace, &found, kRecursionLimit)
4340           .ToHandle(&result)) {
4341     return *result;
4342   }
4343   if (isolate->has_pending_exception()) return isolate->heap()->exception();
4344
4345   subject = String::Flatten(subject);
4346   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
4347       isolate, result,
4348       StringReplaceOneCharWithString(
4349           isolate, subject, search, replace, &found, kRecursionLimit));
4350   return *result;
4351 }
4352
4353
4354 // Perform string match of pattern on subject, starting at start index.
4355 // Caller must ensure that 0 <= start_index <= sub->length(),
4356 // and should check that pat->length() + start_index <= sub->length().
4357 int Runtime::StringMatch(Isolate* isolate,
4358                          Handle<String> sub,
4359                          Handle<String> pat,
4360                          int start_index) {
4361   ASSERT(0 <= start_index);
4362   ASSERT(start_index <= sub->length());
4363
4364   int pattern_length = pat->length();
4365   if (pattern_length == 0) return start_index;
4366
4367   int subject_length = sub->length();
4368   if (start_index + pattern_length > subject_length) return -1;
4369
4370   sub = String::Flatten(sub);
4371   pat = String::Flatten(pat);
4372
4373   DisallowHeapAllocation no_gc;  // ensure vectors stay valid
4374   // Extract flattened substrings of cons strings before determining asciiness.
4375   String::FlatContent seq_sub = sub->GetFlatContent();
4376   String::FlatContent seq_pat = pat->GetFlatContent();
4377
4378   // dispatch on type of strings
4379   if (seq_pat.IsAscii()) {
4380     Vector<const uint8_t> pat_vector = seq_pat.ToOneByteVector();
4381     if (seq_sub.IsAscii()) {
4382       return SearchString(isolate,
4383                           seq_sub.ToOneByteVector(),
4384                           pat_vector,
4385                           start_index);
4386     }
4387     return SearchString(isolate,
4388                         seq_sub.ToUC16Vector(),
4389                         pat_vector,
4390                         start_index);
4391   }
4392   Vector<const uc16> pat_vector = seq_pat.ToUC16Vector();
4393   if (seq_sub.IsAscii()) {
4394     return SearchString(isolate,
4395                         seq_sub.ToOneByteVector(),
4396                         pat_vector,
4397                         start_index);
4398   }
4399   return SearchString(isolate,
4400                       seq_sub.ToUC16Vector(),
4401                       pat_vector,
4402                       start_index);
4403 }
4404
4405
4406 RUNTIME_FUNCTION(Runtime_StringIndexOf) {
4407   HandleScope scope(isolate);
4408   ASSERT(args.length() == 3);
4409
4410   CONVERT_ARG_HANDLE_CHECKED(String, sub, 0);
4411   CONVERT_ARG_HANDLE_CHECKED(String, pat, 1);
4412   CONVERT_ARG_HANDLE_CHECKED(Object, index, 2);
4413
4414   uint32_t start_index;
4415   if (!index->ToArrayIndex(&start_index)) return Smi::FromInt(-1);
4416
4417   RUNTIME_ASSERT(start_index <= static_cast<uint32_t>(sub->length()));
4418   int position = Runtime::StringMatch(isolate, sub, pat, start_index);
4419   return Smi::FromInt(position);
4420 }
4421
4422
4423 template <typename schar, typename pchar>
4424 static int StringMatchBackwards(Vector<const schar> subject,
4425                                 Vector<const pchar> pattern,
4426                                 int idx) {
4427   int pattern_length = pattern.length();
4428   ASSERT(pattern_length >= 1);
4429   ASSERT(idx + pattern_length <= subject.length());
4430
4431   if (sizeof(schar) == 1 && sizeof(pchar) > 1) {
4432     for (int i = 0; i < pattern_length; i++) {
4433       uc16 c = pattern[i];
4434       if (c > String::kMaxOneByteCharCode) {
4435         return -1;
4436       }
4437     }
4438   }
4439
4440   pchar pattern_first_char = pattern[0];
4441   for (int i = idx; i >= 0; i--) {
4442     if (subject[i] != pattern_first_char) continue;
4443     int j = 1;
4444     while (j < pattern_length) {
4445       if (pattern[j] != subject[i+j]) {
4446         break;
4447       }
4448       j++;
4449     }
4450     if (j == pattern_length) {
4451       return i;
4452     }
4453   }
4454   return -1;
4455 }
4456
4457
4458 RUNTIME_FUNCTION(Runtime_StringLastIndexOf) {
4459   HandleScope scope(isolate);
4460   ASSERT(args.length() == 3);
4461
4462   CONVERT_ARG_HANDLE_CHECKED(String, sub, 0);
4463   CONVERT_ARG_HANDLE_CHECKED(String, pat, 1);
4464   CONVERT_ARG_HANDLE_CHECKED(Object, index, 2);
4465
4466   uint32_t start_index;
4467   if (!index->ToArrayIndex(&start_index)) return Smi::FromInt(-1);
4468
4469   uint32_t pat_length = pat->length();
4470   uint32_t sub_length = sub->length();
4471
4472   if (start_index + pat_length > sub_length) {
4473     start_index = sub_length - pat_length;
4474   }
4475
4476   if (pat_length == 0) {
4477     return Smi::FromInt(start_index);
4478   }
4479
4480   sub = String::Flatten(sub);
4481   pat = String::Flatten(pat);
4482
4483   int position = -1;
4484   DisallowHeapAllocation no_gc;  // ensure vectors stay valid
4485
4486   String::FlatContent sub_content = sub->GetFlatContent();
4487   String::FlatContent pat_content = pat->GetFlatContent();
4488
4489   if (pat_content.IsAscii()) {
4490     Vector<const uint8_t> pat_vector = pat_content.ToOneByteVector();
4491     if (sub_content.IsAscii()) {
4492       position = StringMatchBackwards(sub_content.ToOneByteVector(),
4493                                       pat_vector,
4494                                       start_index);
4495     } else {
4496       position = StringMatchBackwards(sub_content.ToUC16Vector(),
4497                                       pat_vector,
4498                                       start_index);
4499     }
4500   } else {
4501     Vector<const uc16> pat_vector = pat_content.ToUC16Vector();
4502     if (sub_content.IsAscii()) {
4503       position = StringMatchBackwards(sub_content.ToOneByteVector(),
4504                                       pat_vector,
4505                                       start_index);
4506     } else {
4507       position = StringMatchBackwards(sub_content.ToUC16Vector(),
4508                                       pat_vector,
4509                                       start_index);
4510     }
4511   }
4512
4513   return Smi::FromInt(position);
4514 }
4515
4516
4517 RUNTIME_FUNCTION(Runtime_StringLocaleCompare) {
4518   HandleScope handle_scope(isolate);
4519   ASSERT(args.length() == 2);
4520
4521   CONVERT_ARG_HANDLE_CHECKED(String, str1, 0);
4522   CONVERT_ARG_HANDLE_CHECKED(String, str2, 1);
4523
4524   if (str1.is_identical_to(str2)) return Smi::FromInt(0);  // Equal.
4525   int str1_length = str1->length();
4526   int str2_length = str2->length();
4527
4528   // Decide trivial cases without flattening.
4529   if (str1_length == 0) {
4530     if (str2_length == 0) return Smi::FromInt(0);  // Equal.
4531     return Smi::FromInt(-str2_length);
4532   } else {
4533     if (str2_length == 0) return Smi::FromInt(str1_length);
4534   }
4535
4536   int end = str1_length < str2_length ? str1_length : str2_length;
4537
4538   // No need to flatten if we are going to find the answer on the first
4539   // character.  At this point we know there is at least one character
4540   // in each string, due to the trivial case handling above.
4541   int d = str1->Get(0) - str2->Get(0);
4542   if (d != 0) return Smi::FromInt(d);
4543
4544   str1 = String::Flatten(str1);
4545   str2 = String::Flatten(str2);
4546
4547   DisallowHeapAllocation no_gc;
4548   String::FlatContent flat1 = str1->GetFlatContent();
4549   String::FlatContent flat2 = str2->GetFlatContent();
4550
4551   for (int i = 0; i < end; i++) {
4552     if (flat1.Get(i) != flat2.Get(i)) {
4553       return Smi::FromInt(flat1.Get(i) - flat2.Get(i));
4554     }
4555   }
4556
4557   return Smi::FromInt(str1_length - str2_length);
4558 }
4559
4560
4561 RUNTIME_FUNCTION(RuntimeHidden_SubString) {
4562   HandleScope scope(isolate);
4563   ASSERT(args.length() == 3);
4564
4565   CONVERT_ARG_HANDLE_CHECKED(String, string, 0);
4566   int start, end;
4567   // We have a fast integer-only case here to avoid a conversion to double in
4568   // the common case where from and to are Smis.
4569   if (args[1]->IsSmi() && args[2]->IsSmi()) {
4570     CONVERT_SMI_ARG_CHECKED(from_number, 1);
4571     CONVERT_SMI_ARG_CHECKED(to_number, 2);
4572     start = from_number;
4573     end = to_number;
4574   } else {
4575     CONVERT_DOUBLE_ARG_CHECKED(from_number, 1);
4576     CONVERT_DOUBLE_ARG_CHECKED(to_number, 2);
4577     start = FastD2IChecked(from_number);
4578     end = FastD2IChecked(to_number);
4579   }
4580   RUNTIME_ASSERT(end >= start);
4581   RUNTIME_ASSERT(start >= 0);
4582   RUNTIME_ASSERT(end <= string->length());
4583   isolate->counters()->sub_string_runtime()->Increment();
4584
4585   return *isolate->factory()->NewSubString(string, start, end);
4586 }
4587
4588
4589 RUNTIME_FUNCTION(Runtime_StringMatch) {
4590   HandleScope handles(isolate);
4591   ASSERT(args.length() == 3);
4592
4593   CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
4594   CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 1);
4595   CONVERT_ARG_HANDLE_CHECKED(JSArray, regexp_info, 2);
4596
4597   RUNTIME_ASSERT(regexp_info->HasFastObjectElements());
4598
4599   RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate);
4600   if (global_cache.HasException()) return isolate->heap()->exception();
4601
4602   int capture_count = regexp->CaptureCount();
4603
4604   ZoneScope zone_scope(isolate->runtime_zone());
4605   ZoneList<int> offsets(8, zone_scope.zone());
4606
4607   while (true) {
4608     int32_t* match = global_cache.FetchNext();
4609     if (match == NULL) break;
4610     offsets.Add(match[0], zone_scope.zone());  // start
4611     offsets.Add(match[1], zone_scope.zone());  // end
4612   }
4613
4614   if (global_cache.HasException()) return isolate->heap()->exception();
4615
4616   if (offsets.length() == 0) {
4617     // Not a single match.
4618     return isolate->heap()->null_value();
4619   }
4620
4621   RegExpImpl::SetLastMatchInfo(regexp_info,
4622                                subject,
4623                                capture_count,
4624                                global_cache.LastSuccessfulMatch());
4625
4626   int matches = offsets.length() / 2;
4627   Handle<FixedArray> elements = isolate->factory()->NewFixedArray(matches);
4628   Handle<String> substring =
4629       isolate->factory()->NewSubString(subject, offsets.at(0), offsets.at(1));
4630   elements->set(0, *substring);
4631   for (int i = 1; i < matches; i++) {
4632     HandleScope temp_scope(isolate);
4633     int from = offsets.at(i * 2);
4634     int to = offsets.at(i * 2 + 1);
4635     Handle<String> substring =
4636         isolate->factory()->NewProperSubString(subject, from, to);
4637     elements->set(i, *substring);
4638   }
4639   Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements(elements);
4640   result->set_length(Smi::FromInt(matches));
4641   return *result;
4642 }
4643
4644
4645 // Only called from Runtime_RegExpExecMultiple so it doesn't need to maintain
4646 // separate last match info.  See comment on that function.
4647 template<bool has_capture>
4648 static Object* SearchRegExpMultiple(
4649     Isolate* isolate,
4650     Handle<String> subject,
4651     Handle<JSRegExp> regexp,
4652     Handle<JSArray> last_match_array,
4653     Handle<JSArray> result_array) {
4654   ASSERT(subject->IsFlat());
4655   ASSERT_NE(has_capture, regexp->CaptureCount() == 0);
4656
4657   int capture_count = regexp->CaptureCount();
4658   int subject_length = subject->length();
4659
4660   static const int kMinLengthToCache = 0x1000;
4661
4662   if (subject_length > kMinLengthToCache) {
4663     Handle<Object> cached_answer(RegExpResultsCache::Lookup(
4664         isolate->heap(),
4665         *subject,
4666         regexp->data(),
4667         RegExpResultsCache::REGEXP_MULTIPLE_INDICES), isolate);
4668     if (*cached_answer != Smi::FromInt(0)) {
4669       Handle<FixedArray> cached_fixed_array =
4670           Handle<FixedArray>(FixedArray::cast(*cached_answer));
4671       // The cache FixedArray is a COW-array and can therefore be reused.
4672       JSArray::SetContent(result_array, cached_fixed_array);
4673       // The actual length of the result array is stored in the last element of
4674       // the backing store (the backing FixedArray may have a larger capacity).
4675       Object* cached_fixed_array_last_element =
4676           cached_fixed_array->get(cached_fixed_array->length() - 1);
4677       Smi* js_array_length = Smi::cast(cached_fixed_array_last_element);
4678       result_array->set_length(js_array_length);
4679       RegExpImpl::SetLastMatchInfo(
4680           last_match_array, subject, capture_count, NULL);
4681       return *result_array;
4682     }
4683   }
4684
4685   RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate);
4686   if (global_cache.HasException()) return isolate->heap()->exception();
4687
4688   // Ensured in Runtime_RegExpExecMultiple.
4689   ASSERT(result_array->HasFastObjectElements());
4690   Handle<FixedArray> result_elements(
4691       FixedArray::cast(result_array->elements()));
4692   if (result_elements->length() < 16) {
4693     result_elements = isolate->factory()->NewFixedArrayWithHoles(16);
4694   }
4695
4696   FixedArrayBuilder builder(result_elements);
4697
4698   // Position to search from.
4699   int match_start = -1;
4700   int match_end = 0;
4701   bool first = true;
4702
4703   // Two smis before and after the match, for very long strings.
4704   static const int kMaxBuilderEntriesPerRegExpMatch = 5;
4705
4706   while (true) {
4707     int32_t* current_match = global_cache.FetchNext();
4708     if (current_match == NULL) break;
4709     match_start = current_match[0];
4710     builder.EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch);
4711     if (match_end < match_start) {
4712       ReplacementStringBuilder::AddSubjectSlice(&builder,
4713                                                 match_end,
4714                                                 match_start);
4715     }
4716     match_end = current_match[1];
4717     {
4718       // Avoid accumulating new handles inside loop.
4719       HandleScope temp_scope(isolate);
4720       Handle<String> match;
4721       if (!first) {
4722         match = isolate->factory()->NewProperSubString(subject,
4723                                                        match_start,
4724                                                        match_end);
4725       } else {
4726         match = isolate->factory()->NewSubString(subject,
4727                                                  match_start,
4728                                                  match_end);
4729         first = false;
4730       }
4731
4732       if (has_capture) {
4733         // Arguments array to replace function is match, captures, index and
4734         // subject, i.e., 3 + capture count in total.
4735         Handle<FixedArray> elements =
4736             isolate->factory()->NewFixedArray(3 + capture_count);
4737
4738         elements->set(0, *match);
4739         for (int i = 1; i <= capture_count; i++) {
4740           int start = current_match[i * 2];
4741           if (start >= 0) {
4742             int end = current_match[i * 2 + 1];
4743             ASSERT(start <= end);
4744             Handle<String> substring =
4745                 isolate->factory()->NewSubString(subject, start, end);
4746             elements->set(i, *substring);
4747           } else {
4748             ASSERT(current_match[i * 2 + 1] < 0);
4749             elements->set(i, isolate->heap()->undefined_value());
4750           }
4751         }
4752         elements->set(capture_count + 1, Smi::FromInt(match_start));
4753         elements->set(capture_count + 2, *subject);
4754         builder.Add(*isolate->factory()->NewJSArrayWithElements(elements));
4755       } else {
4756         builder.Add(*match);
4757       }
4758     }
4759   }
4760
4761   if (global_cache.HasException()) return isolate->heap()->exception();
4762
4763   if (match_start >= 0) {
4764     // Finished matching, with at least one match.
4765     if (match_end < subject_length) {
4766       ReplacementStringBuilder::AddSubjectSlice(&builder,
4767                                                 match_end,
4768                                                 subject_length);
4769     }
4770
4771     RegExpImpl::SetLastMatchInfo(
4772         last_match_array, subject, capture_count, NULL);
4773
4774     if (subject_length > kMinLengthToCache) {
4775       // Store the length of the result array into the last element of the
4776       // backing FixedArray.
4777       builder.EnsureCapacity(1);
4778       Handle<FixedArray> fixed_array = builder.array();
4779       fixed_array->set(fixed_array->length() - 1,
4780                        Smi::FromInt(builder.length()));
4781       // Cache the result and turn the FixedArray into a COW array.
4782       RegExpResultsCache::Enter(isolate,
4783                                 subject,
4784                                 handle(regexp->data(), isolate),
4785                                 fixed_array,
4786                                 RegExpResultsCache::REGEXP_MULTIPLE_INDICES);
4787     }
4788     return *builder.ToJSArray(result_array);
4789   } else {
4790     return isolate->heap()->null_value();  // No matches at all.
4791   }
4792 }
4793
4794
4795 // This is only called for StringReplaceGlobalRegExpWithFunction.  This sets
4796 // lastMatchInfoOverride to maintain the last match info, so we don't need to
4797 // set any other last match array info.
4798 RUNTIME_FUNCTION(Runtime_RegExpExecMultiple) {
4799   HandleScope handles(isolate);
4800   ASSERT(args.length() == 4);
4801
4802   CONVERT_ARG_HANDLE_CHECKED(String, subject, 1);
4803   CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0);
4804   CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 2);
4805   CONVERT_ARG_HANDLE_CHECKED(JSArray, result_array, 3);
4806   RUNTIME_ASSERT(last_match_info->HasFastObjectElements());
4807   RUNTIME_ASSERT(result_array->HasFastObjectElements());
4808
4809   subject = String::Flatten(subject);
4810   RUNTIME_ASSERT(regexp->GetFlags().is_global());
4811
4812   if (regexp->CaptureCount() == 0) {
4813     return SearchRegExpMultiple<false>(
4814         isolate, subject, regexp, last_match_info, result_array);
4815   } else {
4816     return SearchRegExpMultiple<true>(
4817         isolate, subject, regexp, last_match_info, result_array);
4818   }
4819 }
4820
4821
4822 RUNTIME_FUNCTION(Runtime_NumberToRadixString) {
4823   HandleScope scope(isolate);
4824   ASSERT(args.length() == 2);
4825   CONVERT_SMI_ARG_CHECKED(radix, 1);
4826   RUNTIME_ASSERT(2 <= radix && radix <= 36);
4827
4828   // Fast case where the result is a one character string.
4829   if (args[0]->IsSmi()) {
4830     int value = args.smi_at(0);
4831     if (value >= 0 && value < radix) {
4832       // Character array used for conversion.
4833       static const char kCharTable[] = "0123456789abcdefghijklmnopqrstuvwxyz";
4834       return *isolate->factory()->
4835           LookupSingleCharacterStringFromCode(kCharTable[value]);
4836     }
4837   }
4838
4839   // Slow case.
4840   CONVERT_DOUBLE_ARG_CHECKED(value, 0);
4841   if (std::isnan(value)) {
4842     return isolate->heap()->nan_string();
4843   }
4844   if (std::isinf(value)) {
4845     if (value < 0) {
4846       return isolate->heap()->minus_infinity_string();
4847     }
4848     return isolate->heap()->infinity_string();
4849   }
4850   char* str = DoubleToRadixCString(value, radix);
4851   Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(str);
4852   DeleteArray(str);
4853   return *result;
4854 }
4855
4856
4857 RUNTIME_FUNCTION(Runtime_NumberToFixed) {
4858   HandleScope scope(isolate);
4859   ASSERT(args.length() == 2);
4860
4861   CONVERT_DOUBLE_ARG_CHECKED(value, 0);
4862   CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
4863   int f = FastD2IChecked(f_number);
4864   // See DoubleToFixedCString for these constants:
4865   RUNTIME_ASSERT(f >= 0 && f <= 20);
4866   RUNTIME_ASSERT(!Double(value).IsSpecial());
4867   char* str = DoubleToFixedCString(value, f);
4868   Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(str);
4869   DeleteArray(str);
4870   return *result;
4871 }
4872
4873
4874 RUNTIME_FUNCTION(Runtime_NumberToExponential) {
4875   HandleScope scope(isolate);
4876   ASSERT(args.length() == 2);
4877
4878   CONVERT_DOUBLE_ARG_CHECKED(value, 0);
4879   CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
4880   int f = FastD2IChecked(f_number);
4881   RUNTIME_ASSERT(f >= -1 && f <= 20);
4882   RUNTIME_ASSERT(!Double(value).IsSpecial());
4883   char* str = DoubleToExponentialCString(value, f);
4884   Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(str);
4885   DeleteArray(str);
4886   return *result;
4887 }
4888
4889
4890 RUNTIME_FUNCTION(Runtime_NumberToPrecision) {
4891   HandleScope scope(isolate);
4892   ASSERT(args.length() == 2);
4893
4894   CONVERT_DOUBLE_ARG_CHECKED(value, 0);
4895   CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
4896   int f = FastD2IChecked(f_number);
4897   RUNTIME_ASSERT(f >= 1 && f <= 21);
4898   RUNTIME_ASSERT(!Double(value).IsSpecial());
4899   char* str = DoubleToPrecisionCString(value, f);
4900   Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(str);
4901   DeleteArray(str);
4902   return *result;
4903 }
4904
4905
4906 RUNTIME_FUNCTION(Runtime_IsValidSmi) {
4907   SealHandleScope shs(isolate);
4908   ASSERT(args.length() == 1);
4909
4910   CONVERT_NUMBER_CHECKED(int32_t, number, Int32, args[0]);
4911   return isolate->heap()->ToBoolean(Smi::IsValid(number));
4912 }
4913
4914
4915 // Returns a single character string where first character equals
4916 // string->Get(index).
4917 static Handle<Object> GetCharAt(Handle<String> string, uint32_t index) {
4918   if (index < static_cast<uint32_t>(string->length())) {
4919     Factory* factory = string->GetIsolate()->factory();
4920     return factory->LookupSingleCharacterStringFromCode(
4921         String::Flatten(string)->Get(index));
4922   }
4923   return Execution::CharAt(string, index);
4924 }
4925
4926
4927 MaybeHandle<Object> Runtime::GetElementOrCharAt(Isolate* isolate,
4928                                                 Handle<Object> object,
4929                                                 uint32_t index) {
4930   // Handle [] indexing on Strings
4931   if (object->IsString()) {
4932     Handle<Object> result = GetCharAt(Handle<String>::cast(object), index);
4933     if (!result->IsUndefined()) return result;
4934   }
4935
4936   // Handle [] indexing on String objects
4937   if (object->IsStringObjectWithCharacterAt(index)) {
4938     Handle<JSValue> js_value = Handle<JSValue>::cast(object);
4939     Handle<Object> result =
4940         GetCharAt(Handle<String>(String::cast(js_value->value())), index);
4941     if (!result->IsUndefined()) return result;
4942   }
4943
4944   Handle<Object> result;
4945   if (object->IsString() || object->IsNumber() || object->IsBoolean()) {
4946     Handle<Object> proto(object->GetPrototype(isolate), isolate);
4947     return Object::GetElement(isolate, proto, index);
4948   } else {
4949     return Object::GetElement(isolate, object, index);
4950   }
4951 }
4952
4953
4954 MUST_USE_RESULT
4955 static MaybeHandle<Name> ToName(Isolate* isolate, Handle<Object> key) {
4956   if (key->IsName()) {
4957     return Handle<Name>::cast(key);
4958   } else {
4959     Handle<Object> converted;
4960     ASSIGN_RETURN_ON_EXCEPTION(
4961         isolate, converted, Execution::ToString(isolate, key), Name);
4962     return Handle<Name>::cast(converted);
4963   }
4964 }
4965
4966
4967 MaybeHandle<Object> Runtime::HasObjectProperty(Isolate* isolate,
4968                                                Handle<JSReceiver> object,
4969                                                Handle<Object> key) {
4970   // Check if the given key is an array index.
4971   uint32_t index;
4972   if (key->ToArrayIndex(&index)) {
4973     return isolate->factory()->ToBoolean(JSReceiver::HasElement(object, index));
4974   }
4975
4976   // Convert the key to a name - possibly by calling back into JavaScript.
4977   Handle<Name> name;
4978   ASSIGN_RETURN_ON_EXCEPTION(isolate, name, ToName(isolate, key), Object);
4979
4980   return isolate->factory()->ToBoolean(JSReceiver::HasProperty(object, name));
4981 }
4982
4983
4984 MaybeHandle<Object> Runtime::GetObjectProperty(Isolate* isolate,
4985                                                Handle<Object> object,
4986                                                Handle<Object> key) {
4987   if (object->IsUndefined() || object->IsNull()) {
4988     Handle<Object> args[2] = { key, object };
4989     return isolate->Throw<Object>(
4990         isolate->factory()->NewTypeError("non_object_property_load",
4991                                          HandleVector(args, 2)));
4992   }
4993
4994   // Check if the given key is an array index.
4995   uint32_t index;
4996   if (key->ToArrayIndex(&index)) {
4997     return GetElementOrCharAt(isolate, object, index);
4998   }
4999
5000   // Convert the key to a name - possibly by calling back into JavaScript.
5001   Handle<Name> name;
5002   ASSIGN_RETURN_ON_EXCEPTION(isolate, name, ToName(isolate, key), Object);
5003
5004   // Check if the name is trivially convertible to an index and get
5005   // the element if so.
5006   if (name->AsArrayIndex(&index)) {
5007     return GetElementOrCharAt(isolate, object, index);
5008   } else {
5009     return Object::GetProperty(object, name);
5010   }
5011 }
5012
5013
5014 RUNTIME_FUNCTION(Runtime_GetProperty) {
5015   HandleScope scope(isolate);
5016   ASSERT(args.length() == 2);
5017
5018   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
5019   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
5020   Handle<Object> result;
5021   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
5022       isolate, result,
5023       Runtime::GetObjectProperty(isolate, object, key));
5024   return *result;
5025 }
5026
5027
5028 // KeyedGetProperty is called from KeyedLoadIC::GenerateGeneric.
5029 RUNTIME_FUNCTION(Runtime_KeyedGetProperty) {
5030   HandleScope scope(isolate);
5031   ASSERT(args.length() == 2);
5032
5033   CONVERT_ARG_HANDLE_CHECKED(Object, receiver_obj, 0);
5034   CONVERT_ARG_HANDLE_CHECKED(Object, key_obj, 1);
5035
5036   // Fast cases for getting named properties of the receiver JSObject
5037   // itself.
5038   //
5039   // The global proxy objects has to be excluded since LookupOwn on
5040   // the global proxy object can return a valid result even though the
5041   // global proxy object never has properties.  This is the case
5042   // because the global proxy object forwards everything to its hidden
5043   // prototype including own lookups.
5044   //
5045   // Additionally, we need to make sure that we do not cache results
5046   // for objects that require access checks.
5047   if (receiver_obj->IsJSObject()) {
5048     if (!receiver_obj->IsJSGlobalProxy() &&
5049         !receiver_obj->IsAccessCheckNeeded() &&
5050         key_obj->IsName()) {
5051       DisallowHeapAllocation no_allocation;
5052       Handle<JSObject> receiver = Handle<JSObject>::cast(receiver_obj);
5053       Handle<Name> key = Handle<Name>::cast(key_obj);
5054       if (receiver->HasFastProperties()) {
5055         // Attempt to use lookup cache.
5056         Handle<Map> receiver_map(receiver->map(), isolate);
5057         KeyedLookupCache* keyed_lookup_cache = isolate->keyed_lookup_cache();
5058         int index = keyed_lookup_cache->Lookup(receiver_map, key);
5059         if (index != -1) {
5060           // Doubles are not cached, so raw read the value.
5061           Object* value = receiver->RawFastPropertyAt(
5062               FieldIndex::ForKeyedLookupCacheIndex(*receiver_map, index));
5063           return value->IsTheHole()
5064               ? isolate->heap()->undefined_value()
5065               : value;
5066         }
5067         // Lookup cache miss.  Perform lookup and update the cache if
5068         // appropriate.
5069         LookupResult result(isolate);
5070         receiver->LookupOwn(key, &result);
5071         if (result.IsField()) {
5072           FieldIndex field_index = result.GetFieldIndex();
5073           // Do not track double fields in the keyed lookup cache. Reading
5074           // double values requires boxing.
5075           if (!result.representation().IsDouble()) {
5076             keyed_lookup_cache->Update(receiver_map, key,
5077                 field_index.GetKeyedLookupCacheIndex());
5078           }
5079           AllowHeapAllocation allow_allocation;
5080           return *JSObject::FastPropertyAt(receiver, result.representation(),
5081                                            field_index);
5082         }
5083       } else {
5084         // Attempt dictionary lookup.
5085         NameDictionary* dictionary = receiver->property_dictionary();
5086         int entry = dictionary->FindEntry(key);
5087         if ((entry != NameDictionary::kNotFound) &&
5088             (dictionary->DetailsAt(entry).type() == NORMAL)) {
5089           Object* value = dictionary->ValueAt(entry);
5090           if (!receiver->IsGlobalObject()) return value;
5091           value = PropertyCell::cast(value)->value();
5092           if (!value->IsTheHole()) return value;
5093           // If value is the hole do the general lookup.
5094         }
5095       }
5096     } else if (FLAG_smi_only_arrays && key_obj->IsSmi()) {
5097       // JSObject without a name key. If the key is a Smi, check for a
5098       // definite out-of-bounds access to elements, which is a strong indicator
5099       // that subsequent accesses will also call the runtime. Proactively
5100       // transition elements to FAST_*_ELEMENTS to avoid excessive boxing of
5101       // doubles for those future calls in the case that the elements would
5102       // become FAST_DOUBLE_ELEMENTS.
5103       Handle<JSObject> js_object = Handle<JSObject>::cast(receiver_obj);
5104       ElementsKind elements_kind = js_object->GetElementsKind();
5105       if (IsFastDoubleElementsKind(elements_kind)) {
5106         Handle<Smi> key = Handle<Smi>::cast(key_obj);
5107         if (key->value() >= js_object->elements()->length()) {
5108           if (IsFastHoleyElementsKind(elements_kind)) {
5109             elements_kind = FAST_HOLEY_ELEMENTS;
5110           } else {
5111             elements_kind = FAST_ELEMENTS;
5112           }
5113           RETURN_FAILURE_ON_EXCEPTION(
5114               isolate, TransitionElements(js_object, elements_kind, isolate));
5115         }
5116       } else {
5117         ASSERT(IsFastSmiOrObjectElementsKind(elements_kind) ||
5118                !IsFastElementsKind(elements_kind));
5119       }
5120     }
5121   } else if (receiver_obj->IsString() && key_obj->IsSmi()) {
5122     // Fast case for string indexing using [] with a smi index.
5123     Handle<String> str = Handle<String>::cast(receiver_obj);
5124     int index = args.smi_at(1);
5125     if (index >= 0 && index < str->length()) {
5126       return *GetCharAt(str, index);
5127     }
5128   }
5129
5130   // Fall back to GetObjectProperty.
5131   Handle<Object> result;
5132   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
5133       isolate, result,
5134       Runtime::GetObjectProperty(isolate, receiver_obj, key_obj));
5135   return *result;
5136 }
5137
5138
5139 static bool IsValidAccessor(Handle<Object> obj) {
5140   return obj->IsUndefined() || obj->IsSpecFunction() || obj->IsNull();
5141 }
5142
5143
5144 // Implements part of 8.12.9 DefineOwnProperty.
5145 // There are 3 cases that lead here:
5146 // Step 4b - define a new accessor property.
5147 // Steps 9c & 12 - replace an existing data property with an accessor property.
5148 // Step 12 - update an existing accessor property with an accessor or generic
5149 //           descriptor.
5150 RUNTIME_FUNCTION(Runtime_DefineOrRedefineAccessorProperty) {
5151   HandleScope scope(isolate);
5152   ASSERT(args.length() == 5);
5153   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
5154   RUNTIME_ASSERT(!obj->IsNull());
5155   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
5156   CONVERT_ARG_HANDLE_CHECKED(Object, getter, 2);
5157   RUNTIME_ASSERT(IsValidAccessor(getter));
5158   CONVERT_ARG_HANDLE_CHECKED(Object, setter, 3);
5159   RUNTIME_ASSERT(IsValidAccessor(setter));
5160   CONVERT_SMI_ARG_CHECKED(unchecked, 4);
5161   RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
5162   PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked);
5163
5164   bool fast = obj->HasFastProperties();
5165   // DefineAccessor checks access rights.
5166   JSObject::DefineAccessor(obj, name, getter, setter, attr);
5167   RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
5168   if (fast) JSObject::TransformToFastProperties(obj, 0);
5169   return isolate->heap()->undefined_value();
5170 }
5171
5172
5173 // Implements part of 8.12.9 DefineOwnProperty.
5174 // There are 3 cases that lead here:
5175 // Step 4a - define a new data property.
5176 // Steps 9b & 12 - replace an existing accessor property with a data property.
5177 // Step 12 - update an existing data property with a data or generic
5178 //           descriptor.
5179 RUNTIME_FUNCTION(Runtime_DefineOrRedefineDataProperty) {
5180   HandleScope scope(isolate);
5181   ASSERT(args.length() == 4);
5182   CONVERT_ARG_HANDLE_CHECKED(JSObject, js_object, 0);
5183   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
5184   CONVERT_ARG_HANDLE_CHECKED(Object, obj_value, 2);
5185   CONVERT_SMI_ARG_CHECKED(unchecked, 3);
5186   RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
5187   PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked);
5188
5189   // Check access rights if needed.
5190   if (js_object->IsAccessCheckNeeded() &&
5191       !isolate->MayNamedAccess(js_object, name, v8::ACCESS_SET)) {
5192     return isolate->heap()->undefined_value();
5193   }
5194
5195   LookupResult lookup(isolate);
5196   js_object->LookupOwnRealNamedProperty(name, &lookup);
5197
5198   // Take special care when attributes are different and there is already
5199   // a property. For simplicity we normalize the property which enables us
5200   // to not worry about changing the instance_descriptor and creating a new
5201   // map. The current version of SetObjectProperty does not handle attributes
5202   // correctly in the case where a property is a field and is reset with
5203   // new attributes.
5204   if (lookup.IsFound() &&
5205       (attr != lookup.GetAttributes() || lookup.IsPropertyCallbacks())) {
5206     // New attributes - normalize to avoid writing to instance descriptor
5207     if (js_object->IsJSGlobalProxy()) {
5208       // Since the result is a property, the prototype will exist so
5209       // we don't have to check for null.
5210       js_object = Handle<JSObject>(JSObject::cast(js_object->GetPrototype()));
5211     }
5212
5213     if (attr != lookup.GetAttributes() ||
5214         (lookup.IsPropertyCallbacks() &&
5215          !lookup.GetCallbackObject()->IsAccessorInfo())) {
5216       JSObject::NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0);
5217     }
5218
5219     // Use IgnoreAttributes version since a readonly property may be
5220     // overridden and SetProperty does not allow this.
5221     Handle<Object> result;
5222     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
5223         isolate, result,
5224         JSObject::SetOwnPropertyIgnoreAttributes(
5225             js_object, name, obj_value, attr,
5226             Object::OPTIMAL_REPRESENTATION,
5227             ALLOW_AS_CONSTANT,
5228             JSReceiver::PERFORM_EXTENSIBILITY_CHECK,
5229             JSReceiver::MAY_BE_STORE_FROM_KEYED,
5230             JSObject::DONT_FORCE_FIELD));
5231     return *result;
5232   }
5233
5234   Handle<Object> result;
5235   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
5236       isolate, result,
5237       Runtime::ForceSetObjectProperty(
5238           js_object, name, obj_value, attr,
5239           JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED));
5240   return *result;
5241 }
5242
5243
5244 // Return property without being observable by accessors or interceptors.
5245 RUNTIME_FUNCTION(Runtime_GetDataProperty) {
5246   HandleScope scope(isolate);
5247   ASSERT(args.length() == 2);
5248   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
5249   CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
5250   return *JSObject::GetDataProperty(object, key);
5251 }
5252
5253
5254 MaybeHandle<Object> Runtime::SetObjectProperty(Isolate* isolate,
5255                                                Handle<Object> object,
5256                                                Handle<Object> key,
5257                                                Handle<Object> value,
5258                                                PropertyAttributes attr,
5259                                                StrictMode strict_mode) {
5260   SetPropertyMode set_mode = attr == NONE ? SET_PROPERTY : DEFINE_PROPERTY;
5261
5262   if (object->IsUndefined() || object->IsNull()) {
5263     Handle<Object> args[2] = { key, object };
5264     Handle<Object> error =
5265         isolate->factory()->NewTypeError("non_object_property_store",
5266                                          HandleVector(args, 2));
5267     return isolate->Throw<Object>(error);
5268   }
5269
5270   if (object->IsJSProxy()) {
5271     Handle<Object> name_object;
5272     if (key->IsSymbol()) {
5273       name_object = key;
5274     } else {
5275       ASSIGN_RETURN_ON_EXCEPTION(
5276           isolate, name_object, Execution::ToString(isolate, key), Object);
5277     }
5278     Handle<Name> name = Handle<Name>::cast(name_object);
5279     return JSReceiver::SetProperty(Handle<JSProxy>::cast(object), name, value,
5280                                    attr,
5281                                    strict_mode);
5282   }
5283
5284   // If the object isn't a JavaScript object, we ignore the store.
5285   if (!object->IsJSObject()) return value;
5286
5287   Handle<JSObject> js_object = Handle<JSObject>::cast(object);
5288
5289   // Check if the given key is an array index.
5290   uint32_t index;
5291   if (key->ToArrayIndex(&index)) {
5292     // In Firefox/SpiderMonkey, Safari and Opera you can access the characters
5293     // of a string using [] notation.  We need to support this too in
5294     // JavaScript.
5295     // In the case of a String object we just need to redirect the assignment to
5296     // the underlying string if the index is in range.  Since the underlying
5297     // string does nothing with the assignment then we can ignore such
5298     // assignments.
5299     if (js_object->IsStringObjectWithCharacterAt(index)) {
5300       return value;
5301     }
5302
5303     JSObject::ValidateElements(js_object);
5304     if (js_object->HasExternalArrayElements() ||
5305         js_object->HasFixedTypedArrayElements()) {
5306       if (!value->IsNumber() &&  !value->IsFloat32x4() &&
5307           !value->IsFloat64x2() && !value->IsInt32x4() &&
5308           !value->IsUndefined()) {
5309         ASSIGN_RETURN_ON_EXCEPTION(
5310             isolate, value, Execution::ToNumber(isolate, value), Object);
5311       }
5312     }
5313
5314     MaybeHandle<Object> result = JSObject::SetElement(
5315         js_object, index, value, attr, strict_mode, true, set_mode);
5316     JSObject::ValidateElements(js_object);
5317
5318     return result.is_null() ? result : value;
5319   }
5320
5321   if (key->IsName()) {
5322     Handle<Name> name = Handle<Name>::cast(key);
5323     if (name->AsArrayIndex(&index)) {
5324       if (js_object->HasExternalArrayElements()) {
5325         if (!value->IsNumber() &&  !value->IsFloat32x4() &&
5326             !value->IsFloat64x2() && !value->IsInt32x4() &&
5327             !value->IsUndefined()) {
5328           ASSIGN_RETURN_ON_EXCEPTION(
5329               isolate, value, Execution::ToNumber(isolate, value), Object);
5330         }
5331       }
5332       return JSObject::SetElement(js_object, index, value, attr,
5333                                   strict_mode, true, set_mode);
5334     } else {
5335       if (name->IsString()) name = String::Flatten(Handle<String>::cast(name));
5336       return JSReceiver::SetProperty(js_object, name, value, attr, strict_mode);
5337     }
5338   }
5339
5340   // Call-back into JavaScript to convert the key to a string.
5341   Handle<Object> converted;
5342   ASSIGN_RETURN_ON_EXCEPTION(
5343       isolate, converted, Execution::ToString(isolate, key), Object);
5344   Handle<String> name = Handle<String>::cast(converted);
5345
5346   if (name->AsArrayIndex(&index)) {
5347     return JSObject::SetElement(js_object, index, value, attr,
5348                                 strict_mode, true, set_mode);
5349   } else {
5350     return JSReceiver::SetProperty(js_object, name, value, attr, strict_mode);
5351   }
5352 }
5353
5354
5355 MaybeHandle<Object> Runtime::ForceSetObjectProperty(
5356     Handle<JSObject> js_object,
5357     Handle<Object> key,
5358     Handle<Object> value,
5359     PropertyAttributes attr,
5360     JSReceiver::StoreFromKeyed store_from_keyed) {
5361   Isolate* isolate = js_object->GetIsolate();
5362   // Check if the given key is an array index.
5363   uint32_t index;
5364   if (key->ToArrayIndex(&index)) {
5365     // In Firefox/SpiderMonkey, Safari and Opera you can access the characters
5366     // of a string using [] notation.  We need to support this too in
5367     // JavaScript.
5368     // In the case of a String object we just need to redirect the assignment to
5369     // the underlying string if the index is in range.  Since the underlying
5370     // string does nothing with the assignment then we can ignore such
5371     // assignments.
5372     if (js_object->IsStringObjectWithCharacterAt(index)) {
5373       return value;
5374     }
5375
5376     return JSObject::SetElement(js_object, index, value, attr,
5377                                 SLOPPY, false, DEFINE_PROPERTY);
5378   }
5379
5380   if (key->IsName()) {
5381     Handle<Name> name = Handle<Name>::cast(key);
5382     if (name->AsArrayIndex(&index)) {
5383       return JSObject::SetElement(js_object, index, value, attr,
5384                                   SLOPPY, false, DEFINE_PROPERTY);
5385     } else {
5386       if (name->IsString()) name = String::Flatten(Handle<String>::cast(name));
5387       return JSObject::SetOwnPropertyIgnoreAttributes(
5388           js_object, name, value, attr, Object::OPTIMAL_REPRESENTATION,
5389           ALLOW_AS_CONSTANT, JSReceiver::PERFORM_EXTENSIBILITY_CHECK,
5390           store_from_keyed);
5391     }
5392   }
5393
5394   // Call-back into JavaScript to convert the key to a string.
5395   Handle<Object> converted;
5396   ASSIGN_RETURN_ON_EXCEPTION(
5397       isolate, converted, Execution::ToString(isolate, key), Object);
5398   Handle<String> name = Handle<String>::cast(converted);
5399
5400   if (name->AsArrayIndex(&index)) {
5401     return JSObject::SetElement(js_object, index, value, attr,
5402                                 SLOPPY, false, DEFINE_PROPERTY);
5403   } else {
5404     return JSObject::SetOwnPropertyIgnoreAttributes(
5405         js_object, name, value, attr, Object::OPTIMAL_REPRESENTATION,
5406         ALLOW_AS_CONSTANT, JSReceiver::PERFORM_EXTENSIBILITY_CHECK,
5407         store_from_keyed);
5408   }
5409 }
5410
5411
5412 MaybeHandle<Object> Runtime::DeleteObjectProperty(Isolate* isolate,
5413                                                   Handle<JSReceiver> receiver,
5414                                                   Handle<Object> key,
5415                                                   JSReceiver::DeleteMode mode) {
5416   // Check if the given key is an array index.
5417   uint32_t index;
5418   if (key->ToArrayIndex(&index)) {
5419     // In Firefox/SpiderMonkey, Safari and Opera you can access the
5420     // characters of a string using [] notation.  In the case of a
5421     // String object we just need to redirect the deletion to the
5422     // underlying string if the index is in range.  Since the
5423     // underlying string does nothing with the deletion, we can ignore
5424     // such deletions.
5425     if (receiver->IsStringObjectWithCharacterAt(index)) {
5426       return isolate->factory()->true_value();
5427     }
5428
5429     return JSReceiver::DeleteElement(receiver, index, mode);
5430   }
5431
5432   Handle<Name> name;
5433   if (key->IsName()) {
5434     name = Handle<Name>::cast(key);
5435   } else {
5436     // Call-back into JavaScript to convert the key to a string.
5437     Handle<Object> converted;
5438     ASSIGN_RETURN_ON_EXCEPTION(
5439         isolate, converted, Execution::ToString(isolate, key), Object);
5440     name = Handle<String>::cast(converted);
5441   }
5442
5443   if (name->IsString()) name = String::Flatten(Handle<String>::cast(name));
5444   return JSReceiver::DeleteProperty(receiver, name, mode);
5445 }
5446
5447
5448 RUNTIME_FUNCTION(Runtime_SetHiddenProperty) {
5449   HandleScope scope(isolate);
5450   RUNTIME_ASSERT(args.length() == 3);
5451
5452   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
5453   CONVERT_ARG_HANDLE_CHECKED(String, key, 1);
5454   CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
5455   RUNTIME_ASSERT(key->IsUniqueName());
5456   return *JSObject::SetHiddenProperty(object, key, value);
5457 }
5458
5459
5460 RUNTIME_FUNCTION(Runtime_SetProperty) {
5461   HandleScope scope(isolate);
5462   RUNTIME_ASSERT(args.length() == 4 || args.length() == 5);
5463
5464   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
5465   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
5466   CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
5467   CONVERT_SMI_ARG_CHECKED(unchecked_attributes, 3);
5468   RUNTIME_ASSERT(
5469       (unchecked_attributes & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
5470   // Compute attributes.
5471   PropertyAttributes attributes =
5472       static_cast<PropertyAttributes>(unchecked_attributes);
5473
5474   StrictMode strict_mode = SLOPPY;
5475   if (args.length() == 5) {
5476     CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode_arg, 4);
5477     strict_mode = strict_mode_arg;
5478   }
5479
5480   Handle<Object> result;
5481   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
5482       isolate, result,
5483       Runtime::SetObjectProperty(
5484           isolate, object, key, value, attributes, strict_mode));
5485   return *result;
5486 }
5487
5488
5489 RUNTIME_FUNCTION(Runtime_TransitionElementsKind) {
5490   HandleScope scope(isolate);
5491   RUNTIME_ASSERT(args.length() == 2);
5492   CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
5493   CONVERT_ARG_HANDLE_CHECKED(Map, map, 1);
5494   JSObject::TransitionElementsKind(array, map->elements_kind());
5495   return *array;
5496 }
5497
5498
5499 // Set the native flag on the function.
5500 // This is used to decide if we should transform null and undefined
5501 // into the global object when doing call and apply.
5502 RUNTIME_FUNCTION(Runtime_SetNativeFlag) {
5503   SealHandleScope shs(isolate);
5504   RUNTIME_ASSERT(args.length() == 1);
5505
5506   CONVERT_ARG_CHECKED(Object, object, 0);
5507
5508   if (object->IsJSFunction()) {
5509     JSFunction* func = JSFunction::cast(object);
5510     func->shared()->set_native(true);
5511   }
5512   return isolate->heap()->undefined_value();
5513 }
5514
5515
5516 RUNTIME_FUNCTION(Runtime_SetInlineBuiltinFlag) {
5517   SealHandleScope shs(isolate);
5518   RUNTIME_ASSERT(args.length() == 1);
5519   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
5520
5521   if (object->IsJSFunction()) {
5522     JSFunction* func = JSFunction::cast(*object);
5523     func->shared()->set_inline_builtin(true);
5524   }
5525   return isolate->heap()->undefined_value();
5526 }
5527
5528
5529 RUNTIME_FUNCTION(Runtime_StoreArrayLiteralElement) {
5530   HandleScope scope(isolate);
5531   RUNTIME_ASSERT(args.length() == 5);
5532   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
5533   CONVERT_SMI_ARG_CHECKED(store_index, 1);
5534   CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
5535   CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 3);
5536   CONVERT_SMI_ARG_CHECKED(literal_index, 4);
5537
5538   Object* raw_literal_cell = literals->get(literal_index);
5539   JSArray* boilerplate = NULL;
5540   if (raw_literal_cell->IsAllocationSite()) {
5541     AllocationSite* site = AllocationSite::cast(raw_literal_cell);
5542     boilerplate = JSArray::cast(site->transition_info());
5543   } else {
5544     boilerplate = JSArray::cast(raw_literal_cell);
5545   }
5546   Handle<JSArray> boilerplate_object(boilerplate);
5547   ElementsKind elements_kind = object->GetElementsKind();
5548   ASSERT(IsFastElementsKind(elements_kind));
5549   // Smis should never trigger transitions.
5550   ASSERT(!value->IsSmi());
5551
5552   if (value->IsNumber()) {
5553     ASSERT(IsFastSmiElementsKind(elements_kind));
5554     ElementsKind transitioned_kind = IsFastHoleyElementsKind(elements_kind)
5555         ? FAST_HOLEY_DOUBLE_ELEMENTS
5556         : FAST_DOUBLE_ELEMENTS;
5557     if (IsMoreGeneralElementsKindTransition(
5558             boilerplate_object->GetElementsKind(),
5559             transitioned_kind)) {
5560       JSObject::TransitionElementsKind(boilerplate_object, transitioned_kind);
5561     }
5562     JSObject::TransitionElementsKind(object, transitioned_kind);
5563     ASSERT(IsFastDoubleElementsKind(object->GetElementsKind()));
5564     FixedDoubleArray* double_array = FixedDoubleArray::cast(object->elements());
5565     HeapNumber* number = HeapNumber::cast(*value);
5566     double_array->set(store_index, number->Number());
5567   } else {
5568     if (!IsFastObjectElementsKind(elements_kind)) {
5569       ElementsKind transitioned_kind = IsFastHoleyElementsKind(elements_kind)
5570           ? FAST_HOLEY_ELEMENTS
5571           : FAST_ELEMENTS;
5572       JSObject::TransitionElementsKind(object, transitioned_kind);
5573       ElementsKind boilerplate_elements_kind =
5574           boilerplate_object->GetElementsKind();
5575       if (IsMoreGeneralElementsKindTransition(boilerplate_elements_kind,
5576                                               transitioned_kind)) {
5577         JSObject::TransitionElementsKind(boilerplate_object, transitioned_kind);
5578       }
5579     }
5580     FixedArray* object_array = FixedArray::cast(object->elements());
5581     object_array->set(store_index, *value);
5582   }
5583   return *object;
5584 }
5585
5586
5587 // Check whether debugger and is about to step into the callback that is passed
5588 // to a built-in function such as Array.forEach.
5589 RUNTIME_FUNCTION(Runtime_DebugCallbackSupportsStepping) {
5590   ASSERT(args.length() == 1);
5591   if (!isolate->debug()->is_active() || !isolate->debug()->StepInActive()) {
5592     return isolate->heap()->false_value();
5593   }
5594   CONVERT_ARG_CHECKED(Object, callback, 0);
5595   // We do not step into the callback if it's a builtin or not even a function.
5596   return isolate->heap()->ToBoolean(
5597       callback->IsJSFunction() && !JSFunction::cast(callback)->IsBuiltin());
5598 }
5599
5600
5601 // Set one shot breakpoints for the callback function that is passed to a
5602 // built-in function such as Array.forEach to enable stepping into the callback.
5603 RUNTIME_FUNCTION(Runtime_DebugPrepareStepInIfStepping) {
5604   ASSERT(args.length() == 1);
5605   Debug* debug = isolate->debug();
5606   if (!debug->IsStepping()) return isolate->heap()->undefined_value();
5607   CONVERT_ARG_HANDLE_CHECKED(JSFunction, callback, 0);
5608   HandleScope scope(isolate);
5609   // When leaving the callback, step out has been activated, but not performed
5610   // if we do not leave the builtin.  To be able to step into the callback
5611   // again, we need to clear the step out at this point.
5612   debug->ClearStepOut();
5613   debug->FloodWithOneShot(callback);
5614   return isolate->heap()->undefined_value();
5615 }
5616
5617
5618 // The argument is a closure that is kept until the epilogue is called.
5619 // On exception, the closure is called, which returns the promise if the
5620 // exception is considered uncaught, or undefined otherwise.
5621 RUNTIME_FUNCTION(Runtime_DebugPromiseHandlePrologue) {
5622   ASSERT(args.length() == 1);
5623   HandleScope scope(isolate);
5624   CONVERT_ARG_HANDLE_CHECKED(JSFunction, promise_getter, 0);
5625   isolate->debug()->PromiseHandlePrologue(promise_getter);
5626   return isolate->heap()->undefined_value();
5627 }
5628
5629
5630 RUNTIME_FUNCTION(Runtime_DebugPromiseHandleEpilogue) {
5631   ASSERT(args.length() == 0);
5632   SealHandleScope shs(isolate);
5633   isolate->debug()->PromiseHandleEpilogue();
5634   return isolate->heap()->undefined_value();
5635 }
5636
5637
5638 // Set an own property, even if it is READ_ONLY.  If the property does not
5639 // exist, it will be added with attributes NONE.
5640 RUNTIME_FUNCTION(Runtime_IgnoreAttributesAndSetProperty) {
5641   HandleScope scope(isolate);
5642   RUNTIME_ASSERT(args.length() == 3 || args.length() == 4);
5643   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
5644   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
5645   CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
5646   // Compute attributes.
5647   PropertyAttributes attributes = NONE;
5648   if (args.length() == 4) {
5649     CONVERT_SMI_ARG_CHECKED(unchecked_value, 3);
5650     // Only attribute bits should be set.
5651     RUNTIME_ASSERT(
5652         (unchecked_value & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
5653     attributes = static_cast<PropertyAttributes>(unchecked_value);
5654   }
5655   Handle<Object> result;
5656   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
5657       isolate, result,
5658       JSObject::SetOwnPropertyIgnoreAttributes(
5659           object, name, value, attributes));
5660   return *result;
5661 }
5662
5663
5664 RUNTIME_FUNCTION(Runtime_DeleteProperty) {
5665   HandleScope scope(isolate);
5666   ASSERT(args.length() == 3);
5667   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
5668   CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
5669   CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 2);
5670   JSReceiver::DeleteMode delete_mode = strict_mode == STRICT
5671       ? JSReceiver::STRICT_DELETION : JSReceiver::NORMAL_DELETION;
5672   Handle<Object> result;
5673   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
5674       isolate, result,
5675       JSReceiver::DeleteProperty(object, key, delete_mode));
5676   return *result;
5677 }
5678
5679
5680 static Object* HasOwnPropertyImplementation(Isolate* isolate,
5681                                             Handle<JSObject> object,
5682                                             Handle<Name> key) {
5683   if (JSReceiver::HasOwnProperty(object, key)) {
5684     return isolate->heap()->true_value();
5685   }
5686   // Handle hidden prototypes.  If there's a hidden prototype above this thing
5687   // then we have to check it for properties, because they are supposed to
5688   // look like they are on this object.
5689   Handle<Object> proto(object->GetPrototype(), isolate);
5690   if (proto->IsJSObject() &&
5691       Handle<JSObject>::cast(proto)->map()->is_hidden_prototype()) {
5692     return HasOwnPropertyImplementation(isolate,
5693                                         Handle<JSObject>::cast(proto),
5694                                         key);
5695   }
5696   RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
5697   return isolate->heap()->false_value();
5698 }
5699
5700
5701 RUNTIME_FUNCTION(Runtime_HasOwnProperty) {
5702   HandleScope scope(isolate);
5703   ASSERT(args.length() == 2);
5704   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0)
5705   CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
5706
5707   uint32_t index;
5708   const bool key_is_array_index = key->AsArrayIndex(&index);
5709
5710   // Only JS objects can have properties.
5711   if (object->IsJSObject()) {
5712     Handle<JSObject> js_obj = Handle<JSObject>::cast(object);
5713     // Fast case: either the key is a real named property or it is not
5714     // an array index and there are no interceptors or hidden
5715     // prototypes.
5716     if (JSObject::HasRealNamedProperty(js_obj, key)) {
5717       ASSERT(!isolate->has_scheduled_exception());
5718       return isolate->heap()->true_value();
5719     } else {
5720       RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
5721     }
5722     Map* map = js_obj->map();
5723     if (!key_is_array_index &&
5724         !map->has_named_interceptor() &&
5725         !HeapObject::cast(map->prototype())->map()->is_hidden_prototype()) {
5726       return isolate->heap()->false_value();
5727     }
5728     // Slow case.
5729     return HasOwnPropertyImplementation(isolate,
5730                                         Handle<JSObject>(js_obj),
5731                                         Handle<Name>(key));
5732   } else if (object->IsString() && key_is_array_index) {
5733     // Well, there is one exception:  Handle [] on strings.
5734     Handle<String> string = Handle<String>::cast(object);
5735     if (index < static_cast<uint32_t>(string->length())) {
5736       return isolate->heap()->true_value();
5737     }
5738   }
5739   return isolate->heap()->false_value();
5740 }
5741
5742
5743 RUNTIME_FUNCTION(Runtime_HasProperty) {
5744   HandleScope scope(isolate);
5745   ASSERT(args.length() == 2);
5746   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
5747   CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
5748
5749   bool result = JSReceiver::HasProperty(receiver, key);
5750   RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
5751   if (isolate->has_pending_exception()) return isolate->heap()->exception();
5752   return isolate->heap()->ToBoolean(result);
5753 }
5754
5755
5756 RUNTIME_FUNCTION(Runtime_HasElement) {
5757   HandleScope scope(isolate);
5758   ASSERT(args.length() == 2);
5759   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
5760   CONVERT_SMI_ARG_CHECKED(index, 1);
5761
5762   bool result = JSReceiver::HasElement(receiver, index);
5763   RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
5764   return isolate->heap()->ToBoolean(result);
5765 }
5766
5767
5768 RUNTIME_FUNCTION(Runtime_IsPropertyEnumerable) {
5769   HandleScope scope(isolate);
5770   ASSERT(args.length() == 2);
5771
5772   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
5773   CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
5774
5775   PropertyAttributes att = JSReceiver::GetOwnPropertyAttributes(object, key);
5776   if (att == ABSENT || (att & DONT_ENUM) != 0) {
5777     RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
5778     return isolate->heap()->false_value();
5779   }
5780   ASSERT(!isolate->has_scheduled_exception());
5781   return isolate->heap()->true_value();
5782 }
5783
5784
5785 RUNTIME_FUNCTION(Runtime_GetPropertyNames) {
5786   HandleScope scope(isolate);
5787   ASSERT(args.length() == 1);
5788   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
5789   Handle<JSArray> result;
5790
5791   isolate->counters()->for_in()->Increment();
5792   Handle<FixedArray> elements;
5793   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
5794       isolate, elements,
5795       JSReceiver::GetKeys(object, JSReceiver::INCLUDE_PROTOS));
5796   return *isolate->factory()->NewJSArrayWithElements(elements);
5797 }
5798
5799
5800 // Returns either a FixedArray as Runtime_GetPropertyNames,
5801 // or, if the given object has an enum cache that contains
5802 // all enumerable properties of the object and its prototypes
5803 // have none, the map of the object. This is used to speed up
5804 // the check for deletions during a for-in.
5805 RUNTIME_FUNCTION(Runtime_GetPropertyNamesFast) {
5806   SealHandleScope shs(isolate);
5807   ASSERT(args.length() == 1);
5808
5809   CONVERT_ARG_CHECKED(JSReceiver, raw_object, 0);
5810
5811   if (raw_object->IsSimpleEnum()) return raw_object->map();
5812
5813   HandleScope scope(isolate);
5814   Handle<JSReceiver> object(raw_object);
5815   Handle<FixedArray> content;
5816   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
5817       isolate, content,
5818       JSReceiver::GetKeys(object, JSReceiver::INCLUDE_PROTOS));
5819
5820   // Test again, since cache may have been built by preceding call.
5821   if (object->IsSimpleEnum()) return object->map();
5822
5823   return *content;
5824 }
5825
5826
5827 // Find the length of the prototype chain that is to be handled as one. If a
5828 // prototype object is hidden it is to be viewed as part of the the object it
5829 // is prototype for.
5830 static int OwnPrototypeChainLength(JSObject* obj) {
5831   int count = 1;
5832   Object* proto = obj->GetPrototype();
5833   while (proto->IsJSObject() &&
5834          JSObject::cast(proto)->map()->is_hidden_prototype()) {
5835     count++;
5836     proto = JSObject::cast(proto)->GetPrototype();
5837   }
5838   return count;
5839 }
5840
5841
5842 // Return the names of the own named properties.
5843 // args[0]: object
5844 // args[1]: PropertyAttributes as int
5845 RUNTIME_FUNCTION(Runtime_GetOwnPropertyNames) {
5846   HandleScope scope(isolate);
5847   ASSERT(args.length() == 2);
5848   if (!args[0]->IsJSObject()) {
5849     return isolate->heap()->undefined_value();
5850   }
5851   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
5852   CONVERT_SMI_ARG_CHECKED(filter_value, 1);
5853   PropertyAttributes filter = static_cast<PropertyAttributes>(filter_value);
5854
5855   // Skip the global proxy as it has no properties and always delegates to the
5856   // real global object.
5857   if (obj->IsJSGlobalProxy()) {
5858     // Only collect names if access is permitted.
5859     if (obj->IsAccessCheckNeeded() &&
5860         !isolate->MayNamedAccess(
5861             obj, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) {
5862       isolate->ReportFailedAccessCheck(obj, v8::ACCESS_KEYS);
5863       RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
5864       return *isolate->factory()->NewJSArray(0);
5865     }
5866     obj = Handle<JSObject>(JSObject::cast(obj->GetPrototype()));
5867   }
5868
5869   // Find the number of objects making up this.
5870   int length = OwnPrototypeChainLength(*obj);
5871
5872   // Find the number of own properties for each of the objects.
5873   ScopedVector<int> own_property_count(length);
5874   int total_property_count = 0;
5875   Handle<JSObject> jsproto = obj;
5876   for (int i = 0; i < length; i++) {
5877     // Only collect names if access is permitted.
5878     if (jsproto->IsAccessCheckNeeded() &&
5879         !isolate->MayNamedAccess(
5880             jsproto, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) {
5881       isolate->ReportFailedAccessCheck(jsproto, v8::ACCESS_KEYS);
5882       RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
5883       return *isolate->factory()->NewJSArray(0);
5884     }
5885     int n;
5886     n = jsproto->NumberOfOwnProperties(filter);
5887     own_property_count[i] = n;
5888     total_property_count += n;
5889     if (i < length - 1) {
5890       jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype()));
5891     }
5892   }
5893
5894   // Allocate an array with storage for all the property names.
5895   Handle<FixedArray> names =
5896       isolate->factory()->NewFixedArray(total_property_count);
5897
5898   // Get the property names.
5899   jsproto = obj;
5900   int next_copy_index = 0;
5901   int hidden_strings = 0;
5902   for (int i = 0; i < length; i++) {
5903     jsproto->GetOwnPropertyNames(*names, next_copy_index, filter);
5904     if (i > 0) {
5905       // Names from hidden prototypes may already have been added
5906       // for inherited function template instances. Count the duplicates
5907       // and stub them out; the final copy pass at the end ignores holes.
5908       for (int j = next_copy_index;
5909            j < next_copy_index + own_property_count[i];
5910            j++) {
5911         Object* name_from_hidden_proto = names->get(j);
5912         for (int k = 0; k < next_copy_index; k++) {
5913           if (names->get(k) != isolate->heap()->hidden_string()) {
5914             Object* name = names->get(k);
5915             if (name_from_hidden_proto == name) {
5916               names->set(j, isolate->heap()->hidden_string());
5917               hidden_strings++;
5918               break;
5919             }
5920           }
5921         }
5922       }
5923     }
5924     next_copy_index += own_property_count[i];
5925
5926     // Hidden properties only show up if the filter does not skip strings.
5927     if ((filter & STRING) == 0 && JSObject::HasHiddenProperties(jsproto)) {
5928       hidden_strings++;
5929     }
5930     if (i < length - 1) {
5931       jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype()));
5932     }
5933   }
5934
5935   // Filter out name of hidden properties object and
5936   // hidden prototype duplicates.
5937   if (hidden_strings > 0) {
5938     Handle<FixedArray> old_names = names;
5939     names = isolate->factory()->NewFixedArray(
5940         names->length() - hidden_strings);
5941     int dest_pos = 0;
5942     for (int i = 0; i < total_property_count; i++) {
5943       Object* name = old_names->get(i);
5944       if (name == isolate->heap()->hidden_string()) {
5945         hidden_strings--;
5946         continue;
5947       }
5948       names->set(dest_pos++, name);
5949     }
5950     ASSERT_EQ(0, hidden_strings);
5951   }
5952
5953   return *isolate->factory()->NewJSArrayWithElements(names);
5954 }
5955
5956
5957 // Return the names of the own indexed properties.
5958 // args[0]: object
5959 RUNTIME_FUNCTION(Runtime_GetOwnElementNames) {
5960   HandleScope scope(isolate);
5961   ASSERT(args.length() == 1);
5962   if (!args[0]->IsJSObject()) {
5963     return isolate->heap()->undefined_value();
5964   }
5965   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
5966
5967   int n = obj->NumberOfOwnElements(static_cast<PropertyAttributes>(NONE));
5968   Handle<FixedArray> names = isolate->factory()->NewFixedArray(n);
5969   obj->GetOwnElementKeys(*names, static_cast<PropertyAttributes>(NONE));
5970   return *isolate->factory()->NewJSArrayWithElements(names);
5971 }
5972
5973
5974 // Return information on whether an object has a named or indexed interceptor.
5975 // args[0]: object
5976 RUNTIME_FUNCTION(Runtime_GetInterceptorInfo) {
5977   HandleScope scope(isolate);
5978   ASSERT(args.length() == 1);
5979   if (!args[0]->IsJSObject()) {
5980     return Smi::FromInt(0);
5981   }
5982   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
5983
5984   int result = 0;
5985   if (obj->HasNamedInterceptor()) result |= 2;
5986   if (obj->HasIndexedInterceptor()) result |= 1;
5987
5988   return Smi::FromInt(result);
5989 }
5990
5991
5992 // Return property names from named interceptor.
5993 // args[0]: object
5994 RUNTIME_FUNCTION(Runtime_GetNamedInterceptorPropertyNames) {
5995   HandleScope scope(isolate);
5996   ASSERT(args.length() == 1);
5997   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
5998
5999   if (obj->HasNamedInterceptor()) {
6000     Handle<JSObject> result;
6001     if (JSObject::GetKeysForNamedInterceptor(obj, obj).ToHandle(&result)) {
6002       return *result;
6003     }
6004   }
6005   return isolate->heap()->undefined_value();
6006 }
6007
6008
6009 // Return element names from indexed interceptor.
6010 // args[0]: object
6011 RUNTIME_FUNCTION(Runtime_GetIndexedInterceptorElementNames) {
6012   HandleScope scope(isolate);
6013   ASSERT(args.length() == 1);
6014   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
6015
6016   if (obj->HasIndexedInterceptor()) {
6017     Handle<JSObject> result;
6018     if (JSObject::GetKeysForIndexedInterceptor(obj, obj).ToHandle(&result)) {
6019       return *result;
6020     }
6021   }
6022   return isolate->heap()->undefined_value();
6023 }
6024
6025
6026 RUNTIME_FUNCTION(Runtime_OwnKeys) {
6027   HandleScope scope(isolate);
6028   ASSERT(args.length() == 1);
6029   CONVERT_ARG_CHECKED(JSObject, raw_object, 0);
6030   Handle<JSObject> object(raw_object);
6031
6032   if (object->IsJSGlobalProxy()) {
6033     // Do access checks before going to the global object.
6034     if (object->IsAccessCheckNeeded() &&
6035         !isolate->MayNamedAccess(
6036             object, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) {
6037       isolate->ReportFailedAccessCheck(object, v8::ACCESS_KEYS);
6038       RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
6039       return *isolate->factory()->NewJSArray(0);
6040     }
6041
6042     Handle<Object> proto(object->GetPrototype(), isolate);
6043     // If proxy is detached we simply return an empty array.
6044     if (proto->IsNull()) return *isolate->factory()->NewJSArray(0);
6045     object = Handle<JSObject>::cast(proto);
6046   }
6047
6048   Handle<FixedArray> contents;
6049   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
6050       isolate, contents,
6051       JSReceiver::GetKeys(object, JSReceiver::OWN_ONLY));
6052
6053   // Some fast paths through GetKeysInFixedArrayFor reuse a cached
6054   // property array and since the result is mutable we have to create
6055   // a fresh clone on each invocation.
6056   int length = contents->length();
6057   Handle<FixedArray> copy = isolate->factory()->NewFixedArray(length);
6058   for (int i = 0; i < length; i++) {
6059     Object* entry = contents->get(i);
6060     if (entry->IsString()) {
6061       copy->set(i, entry);
6062     } else {
6063       ASSERT(entry->IsNumber());
6064       HandleScope scope(isolate);
6065       Handle<Object> entry_handle(entry, isolate);
6066       Handle<Object> entry_str =
6067           isolate->factory()->NumberToString(entry_handle);
6068       copy->set(i, *entry_str);
6069     }
6070   }
6071   return *isolate->factory()->NewJSArrayWithElements(copy);
6072 }
6073
6074
6075 RUNTIME_FUNCTION(Runtime_GetArgumentsProperty) {
6076   SealHandleScope shs(isolate);
6077   ASSERT(args.length() == 1);
6078   CONVERT_ARG_HANDLE_CHECKED(Object, raw_key, 0);
6079
6080   // Compute the frame holding the arguments.
6081   JavaScriptFrameIterator it(isolate);
6082   it.AdvanceToArgumentsFrame();
6083   JavaScriptFrame* frame = it.frame();
6084
6085   // Get the actual number of provided arguments.
6086   const uint32_t n = frame->ComputeParametersCount();
6087
6088   // Try to convert the key to an index. If successful and within
6089   // index return the the argument from the frame.
6090   uint32_t index;
6091   if (raw_key->ToArrayIndex(&index) && index < n) {
6092     return frame->GetParameter(index);
6093   }
6094
6095   HandleScope scope(isolate);
6096   if (raw_key->IsSymbol()) {
6097     // Lookup in the initial Object.prototype object.
6098     Handle<Object> result;
6099     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
6100         isolate, result,
6101         Object::GetProperty(isolate->initial_object_prototype(),
6102                             Handle<Symbol>::cast(raw_key)));
6103     return *result;
6104   }
6105
6106   // Convert the key to a string.
6107   Handle<Object> converted;
6108   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
6109       isolate, converted, Execution::ToString(isolate, raw_key));
6110   Handle<String> key = Handle<String>::cast(converted);
6111
6112   // Try to convert the string key into an array index.
6113   if (key->AsArrayIndex(&index)) {
6114     if (index < n) {
6115       return frame->GetParameter(index);
6116     } else {
6117       Handle<Object> initial_prototype(isolate->initial_object_prototype());
6118       Handle<Object> result;
6119       ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
6120           isolate, result,
6121           Object::GetElement(isolate, initial_prototype, index));
6122       return *result;
6123     }
6124   }
6125
6126   // Handle special arguments properties.
6127   if (String::Equals(isolate->factory()->length_string(), key)) {
6128     return Smi::FromInt(n);
6129   }
6130   if (String::Equals(isolate->factory()->callee_string(), key)) {
6131     JSFunction* function = frame->function();
6132     if (function->shared()->strict_mode() == STRICT) {
6133       return isolate->Throw(*isolate->factory()->NewTypeError(
6134           "strict_arguments_callee", HandleVector<Object>(NULL, 0)));
6135     }
6136     return function;
6137   }
6138
6139   // Lookup in the initial Object.prototype object.
6140   Handle<Object> result;
6141   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
6142       isolate, result,
6143       Object::GetProperty(isolate->initial_object_prototype(), key));
6144   return *result;
6145 }
6146
6147
6148 RUNTIME_FUNCTION(Runtime_ToFastProperties) {
6149   HandleScope scope(isolate);
6150   ASSERT(args.length() == 1);
6151   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
6152   if (object->IsJSObject() && !object->IsGlobalObject()) {
6153     JSObject::TransformToFastProperties(Handle<JSObject>::cast(object), 0);
6154   }
6155   return *object;
6156 }
6157
6158
6159 RUNTIME_FUNCTION(Runtime_ToBool) {
6160   SealHandleScope shs(isolate);
6161   ASSERT(args.length() == 1);
6162   CONVERT_ARG_CHECKED(Object, object, 0);
6163
6164   return isolate->heap()->ToBoolean(object->BooleanValue());
6165 }
6166
6167
6168 // Returns the type string of a value; see ECMA-262, 11.4.3 (p 47).
6169 // Possible optimizations: put the type string into the oddballs.
6170 RUNTIME_FUNCTION(Runtime_Typeof) {
6171   SealHandleScope shs(isolate);
6172   ASSERT(args.length() == 1);
6173   CONVERT_ARG_CHECKED(Object, obj, 0);
6174   if (obj->IsNumber()) return isolate->heap()->number_string();
6175   HeapObject* heap_obj = HeapObject::cast(obj);
6176
6177   // typeof an undetectable object is 'undefined'
6178   if (heap_obj->map()->is_undetectable()) {
6179     return isolate->heap()->undefined_string();
6180   }
6181
6182   InstanceType instance_type = heap_obj->map()->instance_type();
6183   if (instance_type < FIRST_NONSTRING_TYPE) {
6184     return isolate->heap()->string_string();
6185   }
6186
6187   switch (instance_type) {
6188     case ODDBALL_TYPE:
6189       if (heap_obj->IsTrue() || heap_obj->IsFalse()) {
6190         return isolate->heap()->boolean_string();
6191       }
6192       if (heap_obj->IsNull()) {
6193         return FLAG_harmony_typeof
6194             ? isolate->heap()->null_string()
6195             : isolate->heap()->object_string();
6196       }
6197       ASSERT(heap_obj->IsUndefined());
6198       return isolate->heap()->undefined_string();
6199     case SYMBOL_TYPE:
6200       return isolate->heap()->symbol_string();
6201     case JS_FUNCTION_TYPE:
6202     case JS_FUNCTION_PROXY_TYPE:
6203       return isolate->heap()->function_string();
6204     default:
6205       // For any kind of object not handled above, the spec rule for
6206       // host objects gives that it is okay to return "object"
6207       return isolate->heap()->object_string();
6208   }
6209 }
6210
6211
6212 static bool AreDigits(const uint8_t*s, int from, int to) {
6213   for (int i = from; i < to; i++) {
6214     if (s[i] < '0' || s[i] > '9') return false;
6215   }
6216
6217   return true;
6218 }
6219
6220
6221 static int ParseDecimalInteger(const uint8_t*s, int from, int to) {
6222   ASSERT(to - from < 10);  // Overflow is not possible.
6223   ASSERT(from < to);
6224   int d = s[from] - '0';
6225
6226   for (int i = from + 1; i < to; i++) {
6227     d = 10 * d + (s[i] - '0');
6228   }
6229
6230   return d;
6231 }
6232
6233
6234 RUNTIME_FUNCTION(Runtime_StringToNumber) {
6235   HandleScope handle_scope(isolate);
6236   ASSERT(args.length() == 1);
6237   CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
6238   subject = String::Flatten(subject);
6239
6240   // Fast case: short integer or some sorts of junk values.
6241   if (subject->IsSeqOneByteString()) {
6242     int len = subject->length();
6243     if (len == 0) return Smi::FromInt(0);
6244
6245     DisallowHeapAllocation no_gc;
6246     uint8_t const* data = Handle<SeqOneByteString>::cast(subject)->GetChars();
6247     bool minus = (data[0] == '-');
6248     int start_pos = (minus ? 1 : 0);
6249
6250     if (start_pos == len) {
6251       return isolate->heap()->nan_value();
6252     } else if (data[start_pos] > '9') {
6253       // Fast check for a junk value. A valid string may start from a
6254       // whitespace, a sign ('+' or '-'), the decimal point, a decimal digit
6255       // or the 'I' character ('Infinity'). All of that have codes not greater
6256       // than '9' except 'I' and &nbsp;.
6257       if (data[start_pos] != 'I' && data[start_pos] != 0xa0) {
6258         return isolate->heap()->nan_value();
6259       }
6260     } else if (len - start_pos < 10 && AreDigits(data, start_pos, len)) {
6261       // The maximal/minimal smi has 10 digits. If the string has less digits
6262       // we know it will fit into the smi-data type.
6263       int d = ParseDecimalInteger(data, start_pos, len);
6264       if (minus) {
6265         if (d == 0) return isolate->heap()->minus_zero_value();
6266         d = -d;
6267       } else if (!subject->HasHashCode() &&
6268                  len <= String::kMaxArrayIndexSize &&
6269                  (len == 1 || data[0] != '0')) {
6270         // String hash is not calculated yet but all the data are present.
6271         // Update the hash field to speed up sequential convertions.
6272         uint32_t hash = StringHasher::MakeArrayIndexHash(d, len);
6273 #ifdef DEBUG
6274         subject->Hash();  // Force hash calculation.
6275         ASSERT_EQ(static_cast<int>(subject->hash_field()),
6276                   static_cast<int>(hash));
6277 #endif
6278         subject->set_hash_field(hash);
6279       }
6280       return Smi::FromInt(d);
6281     }
6282   }
6283
6284   // Slower case.
6285   int flags = ALLOW_HEX;
6286   if (FLAG_harmony_numeric_literals) {
6287     // The current spec draft has not updated "ToNumber Applied to the String
6288     // Type", https://bugs.ecmascript.org/show_bug.cgi?id=1584
6289     flags |= ALLOW_OCTAL | ALLOW_BINARY;
6290   }
6291
6292   return *isolate->factory()->NewNumber(StringToDouble(
6293       isolate->unicode_cache(), *subject, flags));
6294 }
6295
6296
6297 RUNTIME_FUNCTION(Runtime_NewString) {
6298   HandleScope scope(isolate);
6299   ASSERT(args.length() == 2);
6300   CONVERT_SMI_ARG_CHECKED(length, 0);
6301   CONVERT_BOOLEAN_ARG_CHECKED(is_one_byte, 1);
6302   if (length == 0) return isolate->heap()->empty_string();
6303   Handle<String> result;
6304   if (is_one_byte) {
6305     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
6306         isolate, result, isolate->factory()->NewRawOneByteString(length));
6307   } else {
6308     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
6309         isolate, result, isolate->factory()->NewRawTwoByteString(length));
6310   }
6311   return *result;
6312 }
6313
6314
6315 RUNTIME_FUNCTION(Runtime_TruncateString) {
6316   HandleScope scope(isolate);
6317   ASSERT(args.length() == 2);
6318   CONVERT_ARG_HANDLE_CHECKED(SeqString, string, 0);
6319   CONVERT_SMI_ARG_CHECKED(new_length, 1);
6320   RUNTIME_ASSERT(new_length >= 0);
6321   return *SeqString::Truncate(string, new_length);
6322 }
6323
6324
6325 RUNTIME_FUNCTION(Runtime_URIEscape) {
6326   HandleScope scope(isolate);
6327   ASSERT(args.length() == 1);
6328   CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
6329   Handle<String> string = String::Flatten(source);
6330   ASSERT(string->IsFlat());
6331   Handle<String> result;
6332   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
6333       isolate, result,
6334       string->IsOneByteRepresentationUnderneath()
6335             ? URIEscape::Escape<uint8_t>(isolate, source)
6336             : URIEscape::Escape<uc16>(isolate, source));
6337   return *result;
6338 }
6339
6340
6341 RUNTIME_FUNCTION(Runtime_URIUnescape) {
6342   HandleScope scope(isolate);
6343   ASSERT(args.length() == 1);
6344   CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
6345   Handle<String> string = String::Flatten(source);
6346   ASSERT(string->IsFlat());
6347   Handle<String> result;
6348   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
6349       isolate, result,
6350       string->IsOneByteRepresentationUnderneath()
6351             ? URIUnescape::Unescape<uint8_t>(isolate, source)
6352             : URIUnescape::Unescape<uc16>(isolate, source));
6353   return *result;
6354 }
6355
6356
6357 RUNTIME_FUNCTION(Runtime_QuoteJSONString) {
6358   HandleScope scope(isolate);
6359   CONVERT_ARG_HANDLE_CHECKED(String, string, 0);
6360   ASSERT(args.length() == 1);
6361   Handle<Object> result;
6362   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
6363       isolate, result, BasicJsonStringifier::StringifyString(isolate, string));
6364   return *result;
6365 }
6366
6367
6368 RUNTIME_FUNCTION(Runtime_BasicJSONStringify) {
6369   HandleScope scope(isolate);
6370   ASSERT(args.length() == 1);
6371   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
6372   BasicJsonStringifier stringifier(isolate);
6373   Handle<Object> result;
6374   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
6375       isolate, result, stringifier.Stringify(object));
6376   return *result;
6377 }
6378
6379
6380 RUNTIME_FUNCTION(Runtime_StringParseInt) {
6381   HandleScope handle_scope(isolate);
6382   ASSERT(args.length() == 2);
6383   CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
6384   CONVERT_NUMBER_CHECKED(int, radix, Int32, args[1]);
6385   RUNTIME_ASSERT(radix == 0 || (2 <= radix && radix <= 36));
6386
6387   subject = String::Flatten(subject);
6388   double value;
6389
6390   { DisallowHeapAllocation no_gc;
6391     String::FlatContent flat = subject->GetFlatContent();
6392
6393     // ECMA-262 section 15.1.2.3, empty string is NaN
6394     if (flat.IsAscii()) {
6395       value = StringToInt(
6396           isolate->unicode_cache(), flat.ToOneByteVector(), radix);
6397     } else {
6398       value = StringToInt(
6399           isolate->unicode_cache(), flat.ToUC16Vector(), radix);
6400     }
6401   }
6402
6403   return *isolate->factory()->NewNumber(value);
6404 }
6405
6406
6407 RUNTIME_FUNCTION(Runtime_StringParseFloat) {
6408   HandleScope shs(isolate);
6409   ASSERT(args.length() == 1);
6410   CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
6411
6412   subject = String::Flatten(subject);
6413   double value = StringToDouble(
6414       isolate->unicode_cache(), *subject, ALLOW_TRAILING_JUNK, OS::nan_value());
6415
6416   return *isolate->factory()->NewNumber(value);
6417 }
6418
6419
6420 static inline bool ToUpperOverflows(uc32 character) {
6421   // y with umlauts and the micro sign are the only characters that stop
6422   // fitting into one-byte when converting to uppercase.
6423   static const uc32 yuml_code = 0xff;
6424   static const uc32 micro_code = 0xb5;
6425   return (character == yuml_code || character == micro_code);
6426 }
6427
6428
6429 template <class Converter>
6430 MUST_USE_RESULT static Object* ConvertCaseHelper(
6431     Isolate* isolate,
6432     String* string,
6433     SeqString* result,
6434     int result_length,
6435     unibrow::Mapping<Converter, 128>* mapping) {
6436   DisallowHeapAllocation no_gc;
6437   // We try this twice, once with the assumption that the result is no longer
6438   // than the input and, if that assumption breaks, again with the exact
6439   // length.  This may not be pretty, but it is nicer than what was here before
6440   // and I hereby claim my vaffel-is.
6441   //
6442   // NOTE: This assumes that the upper/lower case of an ASCII
6443   // character is also ASCII.  This is currently the case, but it
6444   // might break in the future if we implement more context and locale
6445   // dependent upper/lower conversions.
6446   bool has_changed_character = false;
6447
6448   // Convert all characters to upper case, assuming that they will fit
6449   // in the buffer
6450   Access<ConsStringIteratorOp> op(
6451       isolate->runtime_state()->string_iterator());
6452   StringCharacterStream stream(string, op.value());
6453   unibrow::uchar chars[Converter::kMaxWidth];
6454   // We can assume that the string is not empty
6455   uc32 current = stream.GetNext();
6456   bool ignore_overflow = Converter::kIsToLower || result->IsSeqTwoByteString();
6457   for (int i = 0; i < result_length;) {
6458     bool has_next = stream.HasMore();
6459     uc32 next = has_next ? stream.GetNext() : 0;
6460     int char_length = mapping->get(current, next, chars);
6461     if (char_length == 0) {
6462       // The case conversion of this character is the character itself.
6463       result->Set(i, current);
6464       i++;
6465     } else if (char_length == 1 &&
6466                (ignore_overflow || !ToUpperOverflows(current))) {
6467       // Common case: converting the letter resulted in one character.
6468       ASSERT(static_cast<uc32>(chars[0]) != current);
6469       result->Set(i, chars[0]);
6470       has_changed_character = true;
6471       i++;
6472     } else if (result_length == string->length()) {
6473       bool overflows = ToUpperOverflows(current);
6474       // We've assumed that the result would be as long as the
6475       // input but here is a character that converts to several
6476       // characters.  No matter, we calculate the exact length
6477       // of the result and try the whole thing again.
6478       //
6479       // Note that this leaves room for optimization.  We could just
6480       // memcpy what we already have to the result string.  Also,
6481       // the result string is the last object allocated we could
6482       // "realloc" it and probably, in the vast majority of cases,
6483       // extend the existing string to be able to hold the full
6484       // result.
6485       int next_length = 0;
6486       if (has_next) {
6487         next_length = mapping->get(next, 0, chars);
6488         if (next_length == 0) next_length = 1;
6489       }
6490       int current_length = i + char_length + next_length;
6491       while (stream.HasMore()) {
6492         current = stream.GetNext();
6493         overflows |= ToUpperOverflows(current);
6494         // NOTE: we use 0 as the next character here because, while
6495         // the next character may affect what a character converts to,
6496         // it does not in any case affect the length of what it convert
6497         // to.
6498         int char_length = mapping->get(current, 0, chars);
6499         if (char_length == 0) char_length = 1;
6500         current_length += char_length;
6501         if (current_length > String::kMaxLength) {
6502           AllowHeapAllocation allocate_error_and_return;
6503           return isolate->ThrowInvalidStringLength();
6504         }
6505       }
6506       // Try again with the real length.  Return signed if we need
6507       // to allocate a two-byte string for to uppercase.
6508       return (overflows && !ignore_overflow) ? Smi::FromInt(-current_length)
6509                                              : Smi::FromInt(current_length);
6510     } else {
6511       for (int j = 0; j < char_length; j++) {
6512         result->Set(i, chars[j]);
6513         i++;
6514       }
6515       has_changed_character = true;
6516     }
6517     current = next;
6518   }
6519   if (has_changed_character) {
6520     return result;
6521   } else {
6522     // If we didn't actually change anything in doing the conversion
6523     // we simple return the result and let the converted string
6524     // become garbage; there is no reason to keep two identical strings
6525     // alive.
6526     return string;
6527   }
6528 }
6529
6530
6531 namespace {
6532
6533 static const uintptr_t kOneInEveryByte = kUintptrAllBitsSet / 0xFF;
6534 static const uintptr_t kAsciiMask = kOneInEveryByte << 7;
6535
6536 // Given a word and two range boundaries returns a word with high bit
6537 // set in every byte iff the corresponding input byte was strictly in
6538 // the range (m, n). All the other bits in the result are cleared.
6539 // This function is only useful when it can be inlined and the
6540 // boundaries are statically known.
6541 // Requires: all bytes in the input word and the boundaries must be
6542 // ASCII (less than 0x7F).
6543 static inline uintptr_t AsciiRangeMask(uintptr_t w, char m, char n) {
6544   // Use strict inequalities since in edge cases the function could be
6545   // further simplified.
6546   ASSERT(0 < m && m < n);
6547   // Has high bit set in every w byte less than n.
6548   uintptr_t tmp1 = kOneInEveryByte * (0x7F + n) - w;
6549   // Has high bit set in every w byte greater than m.
6550   uintptr_t tmp2 = w + kOneInEveryByte * (0x7F - m);
6551   return (tmp1 & tmp2 & (kOneInEveryByte * 0x80));
6552 }
6553
6554
6555 #ifdef DEBUG
6556 static bool CheckFastAsciiConvert(char* dst,
6557                                   const char* src,
6558                                   int length,
6559                                   bool changed,
6560                                   bool is_to_lower) {
6561   bool expected_changed = false;
6562   for (int i = 0; i < length; i++) {
6563     if (dst[i] == src[i]) continue;
6564     expected_changed = true;
6565     if (is_to_lower) {
6566       ASSERT('A' <= src[i] && src[i] <= 'Z');
6567       ASSERT(dst[i] == src[i] + ('a' - 'A'));
6568     } else {
6569       ASSERT('a' <= src[i] && src[i] <= 'z');
6570       ASSERT(dst[i] == src[i] - ('a' - 'A'));
6571     }
6572   }
6573   return (expected_changed == changed);
6574 }
6575 #endif
6576
6577
6578 template<class Converter>
6579 static bool FastAsciiConvert(char* dst,
6580                              const char* src,
6581                              int length,
6582                              bool* changed_out) {
6583 #ifdef DEBUG
6584     char* saved_dst = dst;
6585     const char* saved_src = src;
6586 #endif
6587   DisallowHeapAllocation no_gc;
6588   // We rely on the distance between upper and lower case letters
6589   // being a known power of 2.
6590   ASSERT('a' - 'A' == (1 << 5));
6591   // Boundaries for the range of input characters than require conversion.
6592   static const char lo = Converter::kIsToLower ? 'A' - 1 : 'a' - 1;
6593   static const char hi = Converter::kIsToLower ? 'Z' + 1 : 'z' + 1;
6594   bool changed = false;
6595   uintptr_t or_acc = 0;
6596   const char* const limit = src + length;
6597 #ifdef V8_HOST_CAN_READ_UNALIGNED
6598   // Process the prefix of the input that requires no conversion one
6599   // (machine) word at a time.
6600   while (src <= limit - sizeof(uintptr_t)) {
6601     const uintptr_t w = *reinterpret_cast<const uintptr_t*>(src);
6602     or_acc |= w;
6603     if (AsciiRangeMask(w, lo, hi) != 0) {
6604       changed = true;
6605       break;
6606     }
6607     *reinterpret_cast<uintptr_t*>(dst) = w;
6608     src += sizeof(uintptr_t);
6609     dst += sizeof(uintptr_t);
6610   }
6611   // Process the remainder of the input performing conversion when
6612   // required one word at a time.
6613   while (src <= limit - sizeof(uintptr_t)) {
6614     const uintptr_t w = *reinterpret_cast<const uintptr_t*>(src);
6615     or_acc |= w;
6616     uintptr_t m = AsciiRangeMask(w, lo, hi);
6617     // The mask has high (7th) bit set in every byte that needs
6618     // conversion and we know that the distance between cases is
6619     // 1 << 5.
6620     *reinterpret_cast<uintptr_t*>(dst) = w ^ (m >> 2);
6621     src += sizeof(uintptr_t);
6622     dst += sizeof(uintptr_t);
6623   }
6624 #endif
6625   // Process the last few bytes of the input (or the whole input if
6626   // unaligned access is not supported).
6627   while (src < limit) {
6628     char c = *src;
6629     or_acc |= c;
6630     if (lo < c && c < hi) {
6631       c ^= (1 << 5);
6632       changed = true;
6633     }
6634     *dst = c;
6635     ++src;
6636     ++dst;
6637   }
6638   if ((or_acc & kAsciiMask) != 0) {
6639     return false;
6640   }
6641
6642   ASSERT(CheckFastAsciiConvert(
6643              saved_dst, saved_src, length, changed, Converter::kIsToLower));
6644
6645   *changed_out = changed;
6646   return true;
6647 }
6648
6649 }  // namespace
6650
6651
6652 template <class Converter>
6653 MUST_USE_RESULT static Object* ConvertCase(
6654     Handle<String> s,
6655     Isolate* isolate,
6656     unibrow::Mapping<Converter, 128>* mapping) {
6657   s = String::Flatten(s);
6658   int length = s->length();
6659   // Assume that the string is not empty; we need this assumption later
6660   if (length == 0) return *s;
6661
6662   // Simpler handling of ASCII strings.
6663   //
6664   // NOTE: This assumes that the upper/lower case of an ASCII
6665   // character is also ASCII.  This is currently the case, but it
6666   // might break in the future if we implement more context and locale
6667   // dependent upper/lower conversions.
6668   if (s->IsOneByteRepresentationUnderneath()) {
6669     // Same length as input.
6670     Handle<SeqOneByteString> result =
6671         isolate->factory()->NewRawOneByteString(length).ToHandleChecked();
6672     DisallowHeapAllocation no_gc;
6673     String::FlatContent flat_content = s->GetFlatContent();
6674     ASSERT(flat_content.IsFlat());
6675     bool has_changed_character = false;
6676     bool is_ascii = FastAsciiConvert<Converter>(
6677         reinterpret_cast<char*>(result->GetChars()),
6678         reinterpret_cast<const char*>(flat_content.ToOneByteVector().start()),
6679         length,
6680         &has_changed_character);
6681     // If not ASCII, we discard the result and take the 2 byte path.
6682     if (is_ascii) return has_changed_character ? *result : *s;
6683   }
6684
6685   Handle<SeqString> result;  // Same length as input.
6686   if (s->IsOneByteRepresentation()) {
6687     result = isolate->factory()->NewRawOneByteString(length).ToHandleChecked();
6688   } else {
6689     result = isolate->factory()->NewRawTwoByteString(length).ToHandleChecked();
6690   }
6691
6692   Object* answer = ConvertCaseHelper(isolate, *s, *result, length, mapping);
6693   if (answer->IsException() || answer->IsString()) return answer;
6694
6695   ASSERT(answer->IsSmi());
6696   length = Smi::cast(answer)->value();
6697   if (s->IsOneByteRepresentation() && length > 0) {
6698     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
6699         isolate, result, isolate->factory()->NewRawOneByteString(length));
6700   } else {
6701     if (length < 0) length = -length;
6702     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
6703         isolate, result, isolate->factory()->NewRawTwoByteString(length));
6704   }
6705   return ConvertCaseHelper(isolate, *s, *result, length, mapping);
6706 }
6707
6708
6709 RUNTIME_FUNCTION(Runtime_StringToLowerCase) {
6710   HandleScope scope(isolate);
6711   ASSERT(args.length() == 1);
6712   CONVERT_ARG_HANDLE_CHECKED(String, s, 0);
6713   return ConvertCase(
6714       s, isolate, isolate->runtime_state()->to_lower_mapping());
6715 }
6716
6717
6718 RUNTIME_FUNCTION(Runtime_StringToUpperCase) {
6719   HandleScope scope(isolate);
6720   ASSERT(args.length() == 1);
6721   CONVERT_ARG_HANDLE_CHECKED(String, s, 0);
6722   return ConvertCase(
6723       s, isolate, isolate->runtime_state()->to_upper_mapping());
6724 }
6725
6726
6727 RUNTIME_FUNCTION(Runtime_StringTrim) {
6728   HandleScope scope(isolate);
6729   ASSERT(args.length() == 3);
6730
6731   CONVERT_ARG_HANDLE_CHECKED(String, string, 0);
6732   CONVERT_BOOLEAN_ARG_CHECKED(trimLeft, 1);
6733   CONVERT_BOOLEAN_ARG_CHECKED(trimRight, 2);
6734
6735   string = String::Flatten(string);
6736   int length = string->length();
6737
6738   int left = 0;
6739   UnicodeCache* unicode_cache = isolate->unicode_cache();
6740   if (trimLeft) {
6741     while (left < length &&
6742            unicode_cache->IsWhiteSpaceOrLineTerminator(string->Get(left))) {
6743       left++;
6744     }
6745   }
6746
6747   int right = length;
6748   if (trimRight) {
6749     while (right > left &&
6750            unicode_cache->IsWhiteSpaceOrLineTerminator(
6751                string->Get(right - 1))) {
6752       right--;
6753     }
6754   }
6755
6756   return *isolate->factory()->NewSubString(string, left, right);
6757 }
6758
6759
6760 RUNTIME_FUNCTION(Runtime_StringSplit) {
6761   HandleScope handle_scope(isolate);
6762   ASSERT(args.length() == 3);
6763   CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
6764   CONVERT_ARG_HANDLE_CHECKED(String, pattern, 1);
6765   CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[2]);
6766   RUNTIME_ASSERT(limit > 0);
6767
6768   int subject_length = subject->length();
6769   int pattern_length = pattern->length();
6770   RUNTIME_ASSERT(pattern_length > 0);
6771
6772   if (limit == 0xffffffffu) {
6773     Handle<Object> cached_answer(
6774         RegExpResultsCache::Lookup(isolate->heap(),
6775                                    *subject,
6776                                    *pattern,
6777                                    RegExpResultsCache::STRING_SPLIT_SUBSTRINGS),
6778         isolate);
6779     if (*cached_answer != Smi::FromInt(0)) {
6780       // The cache FixedArray is a COW-array and can therefore be reused.
6781       Handle<JSArray> result =
6782           isolate->factory()->NewJSArrayWithElements(
6783               Handle<FixedArray>::cast(cached_answer));
6784       return *result;
6785     }
6786   }
6787
6788   // The limit can be very large (0xffffffffu), but since the pattern
6789   // isn't empty, we can never create more parts than ~half the length
6790   // of the subject.
6791
6792   subject = String::Flatten(subject);
6793   pattern = String::Flatten(pattern);
6794
6795   static const int kMaxInitialListCapacity = 16;
6796
6797   ZoneScope zone_scope(isolate->runtime_zone());
6798
6799   // Find (up to limit) indices of separator and end-of-string in subject
6800   int initial_capacity = Min<uint32_t>(kMaxInitialListCapacity, limit);
6801   ZoneList<int> indices(initial_capacity, zone_scope.zone());
6802
6803   FindStringIndicesDispatch(isolate, *subject, *pattern,
6804                             &indices, limit, zone_scope.zone());
6805
6806   if (static_cast<uint32_t>(indices.length()) < limit) {
6807     indices.Add(subject_length, zone_scope.zone());
6808   }
6809
6810   // The list indices now contains the end of each part to create.
6811
6812   // Create JSArray of substrings separated by separator.
6813   int part_count = indices.length();
6814
6815   Handle<JSArray> result = isolate->factory()->NewJSArray(part_count);
6816   JSObject::EnsureCanContainHeapObjectElements(result);
6817   result->set_length(Smi::FromInt(part_count));
6818
6819   ASSERT(result->HasFastObjectElements());
6820
6821   if (part_count == 1 && indices.at(0) == subject_length) {
6822     FixedArray::cast(result->elements())->set(0, *subject);
6823     return *result;
6824   }
6825
6826   Handle<FixedArray> elements(FixedArray::cast(result->elements()));
6827   int part_start = 0;
6828   for (int i = 0; i < part_count; i++) {
6829     HandleScope local_loop_handle(isolate);
6830     int part_end = indices.at(i);
6831     Handle<String> substring =
6832         isolate->factory()->NewProperSubString(subject, part_start, part_end);
6833     elements->set(i, *substring);
6834     part_start = part_end + pattern_length;
6835   }
6836
6837   if (limit == 0xffffffffu) {
6838     if (result->HasFastObjectElements()) {
6839       RegExpResultsCache::Enter(isolate,
6840                                 subject,
6841                                 pattern,
6842                                 elements,
6843                                 RegExpResultsCache::STRING_SPLIT_SUBSTRINGS);
6844     }
6845   }
6846
6847   return *result;
6848 }
6849
6850
6851 // Copies ASCII characters to the given fixed array looking up
6852 // one-char strings in the cache. Gives up on the first char that is
6853 // not in the cache and fills the remainder with smi zeros. Returns
6854 // the length of the successfully copied prefix.
6855 static int CopyCachedAsciiCharsToArray(Heap* heap,
6856                                        const uint8_t* chars,
6857                                        FixedArray* elements,
6858                                        int length) {
6859   DisallowHeapAllocation no_gc;
6860   FixedArray* ascii_cache = heap->single_character_string_cache();
6861   Object* undefined = heap->undefined_value();
6862   int i;
6863   WriteBarrierMode mode = elements->GetWriteBarrierMode(no_gc);
6864   for (i = 0; i < length; ++i) {
6865     Object* value = ascii_cache->get(chars[i]);
6866     if (value == undefined) break;
6867     elements->set(i, value, mode);
6868   }
6869   if (i < length) {
6870     ASSERT(Smi::FromInt(0) == 0);
6871     memset(elements->data_start() + i, 0, kPointerSize * (length - i));
6872   }
6873 #ifdef DEBUG
6874   for (int j = 0; j < length; ++j) {
6875     Object* element = elements->get(j);
6876     ASSERT(element == Smi::FromInt(0) ||
6877            (element->IsString() && String::cast(element)->LooksValid()));
6878   }
6879 #endif
6880   return i;
6881 }
6882
6883
6884 // Converts a String to JSArray.
6885 // For example, "foo" => ["f", "o", "o"].
6886 RUNTIME_FUNCTION(Runtime_StringToArray) {
6887   HandleScope scope(isolate);
6888   ASSERT(args.length() == 2);
6889   CONVERT_ARG_HANDLE_CHECKED(String, s, 0);
6890   CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]);
6891
6892   s = String::Flatten(s);
6893   const int length = static_cast<int>(Min<uint32_t>(s->length(), limit));
6894
6895   Handle<FixedArray> elements;
6896   int position = 0;
6897   if (s->IsFlat() && s->IsOneByteRepresentation()) {
6898     // Try using cached chars where possible.
6899     elements = isolate->factory()->NewUninitializedFixedArray(length);
6900
6901     DisallowHeapAllocation no_gc;
6902     String::FlatContent content = s->GetFlatContent();
6903     if (content.IsAscii()) {
6904       Vector<const uint8_t> chars = content.ToOneByteVector();
6905       // Note, this will initialize all elements (not only the prefix)
6906       // to prevent GC from seeing partially initialized array.
6907       position = CopyCachedAsciiCharsToArray(isolate->heap(),
6908                                              chars.start(),
6909                                              *elements,
6910                                              length);
6911     } else {
6912       MemsetPointer(elements->data_start(),
6913                     isolate->heap()->undefined_value(),
6914                     length);
6915     }
6916   } else {
6917     elements = isolate->factory()->NewFixedArray(length);
6918   }
6919   for (int i = position; i < length; ++i) {
6920     Handle<Object> str =
6921         isolate->factory()->LookupSingleCharacterStringFromCode(s->Get(i));
6922     elements->set(i, *str);
6923   }
6924
6925 #ifdef DEBUG
6926   for (int i = 0; i < length; ++i) {
6927     ASSERT(String::cast(elements->get(i))->length() == 1);
6928   }
6929 #endif
6930
6931   return *isolate->factory()->NewJSArrayWithElements(elements);
6932 }
6933
6934
6935 RUNTIME_FUNCTION(Runtime_NewStringWrapper) {
6936   HandleScope scope(isolate);
6937   ASSERT(args.length() == 1);
6938   CONVERT_ARG_HANDLE_CHECKED(String, value, 0);
6939   return *Object::ToObject(isolate, value).ToHandleChecked();
6940 }
6941
6942
6943 bool Runtime::IsUpperCaseChar(RuntimeState* runtime_state, uint16_t ch) {
6944   unibrow::uchar chars[unibrow::ToUppercase::kMaxWidth];
6945   int char_length = runtime_state->to_upper_mapping()->get(ch, 0, chars);
6946   return char_length == 0;
6947 }
6948
6949
6950 RUNTIME_FUNCTION(RuntimeHidden_NumberToString) {
6951   HandleScope scope(isolate);
6952   ASSERT(args.length() == 1);
6953   CONVERT_NUMBER_ARG_HANDLE_CHECKED(number, 0);
6954
6955   return *isolate->factory()->NumberToString(number);
6956 }
6957
6958
6959 RUNTIME_FUNCTION(RuntimeHidden_NumberToStringSkipCache) {
6960   HandleScope scope(isolate);
6961   ASSERT(args.length() == 1);
6962   CONVERT_NUMBER_ARG_HANDLE_CHECKED(number, 0);
6963
6964   return *isolate->factory()->NumberToString(number, false);
6965 }
6966
6967
6968 RUNTIME_FUNCTION(Runtime_NumberToInteger) {
6969   HandleScope scope(isolate);
6970   ASSERT(args.length() == 1);
6971
6972   CONVERT_DOUBLE_ARG_CHECKED(number, 0);
6973   return *isolate->factory()->NewNumber(DoubleToInteger(number));
6974 }
6975
6976
6977 RUNTIME_FUNCTION(Runtime_NumberToIntegerMapMinusZero) {
6978   HandleScope scope(isolate);
6979   ASSERT(args.length() == 1);
6980
6981   CONVERT_DOUBLE_ARG_CHECKED(number, 0);
6982   double double_value = DoubleToInteger(number);
6983   // Map both -0 and +0 to +0.
6984   if (double_value == 0) double_value = 0;
6985
6986   return *isolate->factory()->NewNumber(double_value);
6987 }
6988
6989
6990 RUNTIME_FUNCTION(Runtime_NumberToJSUint32) {
6991   HandleScope scope(isolate);
6992   ASSERT(args.length() == 1);
6993
6994   CONVERT_NUMBER_CHECKED(int32_t, number, Uint32, args[0]);
6995   return *isolate->factory()->NewNumberFromUint(number);
6996 }
6997
6998
6999 RUNTIME_FUNCTION(Runtime_NumberToJSInt32) {
7000   HandleScope scope(isolate);
7001   ASSERT(args.length() == 1);
7002
7003   CONVERT_DOUBLE_ARG_CHECKED(number, 0);
7004   return *isolate->factory()->NewNumberFromInt(DoubleToInt32(number));
7005 }
7006
7007
7008 // Converts a Number to a Smi, if possible. Returns NaN if the number is not
7009 // a small integer.
7010 RUNTIME_FUNCTION(RuntimeHidden_NumberToSmi) {
7011   SealHandleScope shs(isolate);
7012   ASSERT(args.length() == 1);
7013   CONVERT_ARG_CHECKED(Object, obj, 0);
7014   if (obj->IsSmi()) {
7015     return obj;
7016   }
7017   if (obj->IsHeapNumber()) {
7018     double value = HeapNumber::cast(obj)->value();
7019     int int_value = FastD2I(value);
7020     if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
7021       return Smi::FromInt(int_value);
7022     }
7023   }
7024   return isolate->heap()->nan_value();
7025 }
7026
7027
7028 RUNTIME_FUNCTION(RuntimeHidden_AllocateHeapNumber) {
7029   HandleScope scope(isolate);
7030   ASSERT(args.length() == 0);
7031   return *isolate->factory()->NewHeapNumber(0);
7032 }
7033
7034
7035 RUNTIME_FUNCTION(Runtime_AllocateFloat32x4) {
7036   HandleScope scope(isolate);
7037   ASSERT(args.length() == 0);
7038
7039   float32x4_value_t zero = {{0, 0, 0, 0}};
7040   return *isolate->factory()->NewFloat32x4(zero);
7041 }
7042
7043
7044 RUNTIME_FUNCTION(Runtime_AllocateFloat64x2) {
7045   HandleScope scope(isolate);
7046   ASSERT(args.length() == 0);
7047
7048   float64x2_value_t zero = {{0, 0}};
7049   return *isolate->factory()->NewFloat64x2(zero);
7050 }
7051
7052
7053 RUNTIME_FUNCTION(Runtime_AllocateInt32x4) {
7054   HandleScope scope(isolate);
7055   ASSERT(args.length() == 0);
7056
7057   int32x4_value_t zero = {{0, 0, 0, 0}};
7058   return *isolate->factory()->NewInt32x4(zero);
7059 }
7060
7061
7062 RUNTIME_FUNCTION(Runtime_NumberAdd) {
7063   HandleScope scope(isolate);
7064   ASSERT(args.length() == 2);
7065
7066   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7067   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
7068   return *isolate->factory()->NewNumber(x + y);
7069 }
7070
7071
7072 RUNTIME_FUNCTION(Runtime_NumberSub) {
7073   HandleScope scope(isolate);
7074   ASSERT(args.length() == 2);
7075
7076   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7077   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
7078   return *isolate->factory()->NewNumber(x - y);
7079 }
7080
7081
7082 RUNTIME_FUNCTION(Runtime_NumberMul) {
7083   HandleScope scope(isolate);
7084   ASSERT(args.length() == 2);
7085
7086   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7087   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
7088   return *isolate->factory()->NewNumber(x * y);
7089 }
7090
7091
7092 RUNTIME_FUNCTION(Runtime_NumberUnaryMinus) {
7093   HandleScope scope(isolate);
7094   ASSERT(args.length() == 1);
7095
7096   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7097   return *isolate->factory()->NewNumber(-x);
7098 }
7099
7100
7101 RUNTIME_FUNCTION(Runtime_NumberDiv) {
7102   HandleScope scope(isolate);
7103   ASSERT(args.length() == 2);
7104
7105   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7106   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
7107   return *isolate->factory()->NewNumber(x / y);
7108 }
7109
7110
7111 RUNTIME_FUNCTION(Runtime_NumberMod) {
7112   HandleScope scope(isolate);
7113   ASSERT(args.length() == 2);
7114
7115   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7116   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
7117   return *isolate->factory()->NewNumber(modulo(x, y));
7118 }
7119
7120
7121 RUNTIME_FUNCTION(Runtime_NumberImul) {
7122   HandleScope scope(isolate);
7123   ASSERT(args.length() == 2);
7124
7125   CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
7126   CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
7127   return *isolate->factory()->NewNumberFromInt(x * y);
7128 }
7129
7130
7131 RUNTIME_FUNCTION(RuntimeHidden_StringAdd) {
7132   HandleScope scope(isolate);
7133   ASSERT(args.length() == 2);
7134   CONVERT_ARG_HANDLE_CHECKED(String, str1, 0);
7135   CONVERT_ARG_HANDLE_CHECKED(String, str2, 1);
7136   isolate->counters()->string_add_runtime()->Increment();
7137   Handle<String> result;
7138   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
7139       isolate, result, isolate->factory()->NewConsString(str1, str2));
7140   return *result;
7141 }
7142
7143
7144 template <typename sinkchar>
7145 static inline void StringBuilderConcatHelper(String* special,
7146                                              sinkchar* sink,
7147                                              FixedArray* fixed_array,
7148                                              int array_length) {
7149   DisallowHeapAllocation no_gc;
7150   int position = 0;
7151   for (int i = 0; i < array_length; i++) {
7152     Object* element = fixed_array->get(i);
7153     if (element->IsSmi()) {
7154       // Smi encoding of position and length.
7155       int encoded_slice = Smi::cast(element)->value();
7156       int pos;
7157       int len;
7158       if (encoded_slice > 0) {
7159         // Position and length encoded in one smi.
7160         pos = StringBuilderSubstringPosition::decode(encoded_slice);
7161         len = StringBuilderSubstringLength::decode(encoded_slice);
7162       } else {
7163         // Position and length encoded in two smis.
7164         Object* obj = fixed_array->get(++i);
7165         ASSERT(obj->IsSmi());
7166         pos = Smi::cast(obj)->value();
7167         len = -encoded_slice;
7168       }
7169       String::WriteToFlat(special,
7170                           sink + position,
7171                           pos,
7172                           pos + len);
7173       position += len;
7174     } else {
7175       String* string = String::cast(element);
7176       int element_length = string->length();
7177       String::WriteToFlat(string, sink + position, 0, element_length);
7178       position += element_length;
7179     }
7180   }
7181 }
7182
7183
7184 // Returns the result length of the concatenation.
7185 // On illegal argument, -1 is returned.
7186 static inline int StringBuilderConcatLength(int special_length,
7187                                             FixedArray* fixed_array,
7188                                             int array_length,
7189                                             bool* one_byte) {
7190   DisallowHeapAllocation no_gc;
7191   int position = 0;
7192   for (int i = 0; i < array_length; i++) {
7193     int increment = 0;
7194     Object* elt = fixed_array->get(i);
7195     if (elt->IsSmi()) {
7196       // Smi encoding of position and length.
7197       int smi_value = Smi::cast(elt)->value();
7198       int pos;
7199       int len;
7200       if (smi_value > 0) {
7201         // Position and length encoded in one smi.
7202         pos = StringBuilderSubstringPosition::decode(smi_value);
7203         len = StringBuilderSubstringLength::decode(smi_value);
7204       } else {
7205         // Position and length encoded in two smis.
7206         len = -smi_value;
7207         // Get the position and check that it is a positive smi.
7208         i++;
7209         if (i >= array_length) return -1;
7210         Object* next_smi = fixed_array->get(i);
7211         if (!next_smi->IsSmi()) return -1;
7212         pos = Smi::cast(next_smi)->value();
7213         if (pos < 0) return -1;
7214       }
7215       ASSERT(pos >= 0);
7216       ASSERT(len >= 0);
7217       if (pos > special_length || len > special_length - pos) return -1;
7218       increment = len;
7219     } else if (elt->IsString()) {
7220       String* element = String::cast(elt);
7221       int element_length = element->length();
7222       increment = element_length;
7223       if (*one_byte && !element->HasOnlyOneByteChars()) {
7224         *one_byte = false;
7225       }
7226     } else {
7227       return -1;
7228     }
7229     if (increment > String::kMaxLength - position) {
7230       return kMaxInt;  // Provoke throw on allocation.
7231     }
7232     position += increment;
7233   }
7234   return position;
7235 }
7236
7237
7238 RUNTIME_FUNCTION(Runtime_StringBuilderConcat) {
7239   HandleScope scope(isolate);
7240   ASSERT(args.length() == 3);
7241   CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
7242   if (!args[1]->IsSmi()) return isolate->ThrowInvalidStringLength();
7243   CONVERT_SMI_ARG_CHECKED(array_length, 1);
7244   CONVERT_ARG_HANDLE_CHECKED(String, special, 2);
7245
7246   size_t actual_array_length = 0;
7247   RUNTIME_ASSERT(
7248       TryNumberToSize(isolate, array->length(), &actual_array_length));
7249   RUNTIME_ASSERT(array_length >= 0);
7250   RUNTIME_ASSERT(static_cast<size_t>(array_length) <= actual_array_length);
7251
7252   // This assumption is used by the slice encoding in one or two smis.
7253   ASSERT(Smi::kMaxValue >= String::kMaxLength);
7254
7255   RUNTIME_ASSERT(array->HasFastElements());
7256   JSObject::EnsureCanContainHeapObjectElements(array);
7257
7258   int special_length = special->length();
7259   if (!array->HasFastObjectElements()) {
7260     return isolate->Throw(isolate->heap()->illegal_argument_string());
7261   }
7262
7263   int length;
7264   bool one_byte = special->HasOnlyOneByteChars();
7265
7266   { DisallowHeapAllocation no_gc;
7267     FixedArray* fixed_array = FixedArray::cast(array->elements());
7268     if (fixed_array->length() < array_length) {
7269       array_length = fixed_array->length();
7270     }
7271
7272     if (array_length == 0) {
7273       return isolate->heap()->empty_string();
7274     } else if (array_length == 1) {
7275       Object* first = fixed_array->get(0);
7276       if (first->IsString()) return first;
7277     }
7278     length = StringBuilderConcatLength(
7279         special_length, fixed_array, array_length, &one_byte);
7280   }
7281
7282   if (length == -1) {
7283     return isolate->Throw(isolate->heap()->illegal_argument_string());
7284   }
7285
7286   if (one_byte) {
7287     Handle<SeqOneByteString> answer;
7288     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
7289         isolate, answer,
7290         isolate->factory()->NewRawOneByteString(length));
7291     StringBuilderConcatHelper(*special,
7292                               answer->GetChars(),
7293                               FixedArray::cast(array->elements()),
7294                               array_length);
7295     return *answer;
7296   } else {
7297     Handle<SeqTwoByteString> answer;
7298     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
7299         isolate, answer,
7300         isolate->factory()->NewRawTwoByteString(length));
7301     StringBuilderConcatHelper(*special,
7302                               answer->GetChars(),
7303                               FixedArray::cast(array->elements()),
7304                               array_length);
7305     return *answer;
7306   }
7307 }
7308
7309
7310 RUNTIME_FUNCTION(Runtime_StringBuilderJoin) {
7311   HandleScope scope(isolate);
7312   ASSERT(args.length() == 3);
7313   CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
7314   if (!args[1]->IsSmi()) return isolate->ThrowInvalidStringLength();
7315   CONVERT_SMI_ARG_CHECKED(array_length, 1);
7316   CONVERT_ARG_HANDLE_CHECKED(String, separator, 2);
7317   RUNTIME_ASSERT(array->HasFastObjectElements());
7318   RUNTIME_ASSERT(array_length >= 0);
7319
7320   Handle<FixedArray> fixed_array(FixedArray::cast(array->elements()));
7321   if (fixed_array->length() < array_length) {
7322     array_length = fixed_array->length();
7323   }
7324
7325   if (array_length == 0) {
7326     return isolate->heap()->empty_string();
7327   } else if (array_length == 1) {
7328     Object* first = fixed_array->get(0);
7329     RUNTIME_ASSERT(first->IsString());
7330     return first;
7331   }
7332
7333   int separator_length = separator->length();
7334   RUNTIME_ASSERT(separator_length > 0);
7335   int max_nof_separators =
7336       (String::kMaxLength + separator_length - 1) / separator_length;
7337   if (max_nof_separators < (array_length - 1)) {
7338     return isolate->ThrowInvalidStringLength();
7339   }
7340   int length = (array_length - 1) * separator_length;
7341   for (int i = 0; i < array_length; i++) {
7342     Object* element_obj = fixed_array->get(i);
7343     RUNTIME_ASSERT(element_obj->IsString());
7344     String* element = String::cast(element_obj);
7345     int increment = element->length();
7346     if (increment > String::kMaxLength - length) {
7347       STATIC_ASSERT(String::kMaxLength < kMaxInt);
7348       length = kMaxInt;  // Provoke exception;
7349       break;
7350     }
7351     length += increment;
7352   }
7353
7354   Handle<SeqTwoByteString> answer;
7355   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
7356       isolate, answer,
7357       isolate->factory()->NewRawTwoByteString(length));
7358
7359   DisallowHeapAllocation no_gc;
7360
7361   uc16* sink = answer->GetChars();
7362 #ifdef DEBUG
7363   uc16* end = sink + length;
7364 #endif
7365
7366   RUNTIME_ASSERT(fixed_array->get(0)->IsString());
7367   String* first = String::cast(fixed_array->get(0));
7368   String* separator_raw = *separator;
7369   int first_length = first->length();
7370   String::WriteToFlat(first, sink, 0, first_length);
7371   sink += first_length;
7372
7373   for (int i = 1; i < array_length; i++) {
7374     ASSERT(sink + separator_length <= end);
7375     String::WriteToFlat(separator_raw, sink, 0, separator_length);
7376     sink += separator_length;
7377
7378     RUNTIME_ASSERT(fixed_array->get(i)->IsString());
7379     String* element = String::cast(fixed_array->get(i));
7380     int element_length = element->length();
7381     ASSERT(sink + element_length <= end);
7382     String::WriteToFlat(element, sink, 0, element_length);
7383     sink += element_length;
7384   }
7385   ASSERT(sink == end);
7386
7387   // Use %_FastAsciiArrayJoin instead.
7388   ASSERT(!answer->IsOneByteRepresentation());
7389   return *answer;
7390 }
7391
7392 template <typename Char>
7393 static void JoinSparseArrayWithSeparator(FixedArray* elements,
7394                                          int elements_length,
7395                                          uint32_t array_length,
7396                                          String* separator,
7397                                          Vector<Char> buffer) {
7398   DisallowHeapAllocation no_gc;
7399   int previous_separator_position = 0;
7400   int separator_length = separator->length();
7401   int cursor = 0;
7402   for (int i = 0; i < elements_length; i += 2) {
7403     int position = NumberToInt32(elements->get(i));
7404     String* string = String::cast(elements->get(i + 1));
7405     int string_length = string->length();
7406     if (string->length() > 0) {
7407       while (previous_separator_position < position) {
7408         String::WriteToFlat<Char>(separator, &buffer[cursor],
7409                                   0, separator_length);
7410         cursor += separator_length;
7411         previous_separator_position++;
7412       }
7413       String::WriteToFlat<Char>(string, &buffer[cursor],
7414                                 0, string_length);
7415       cursor += string->length();
7416     }
7417   }
7418   if (separator_length > 0) {
7419     // Array length must be representable as a signed 32-bit number,
7420     // otherwise the total string length would have been too large.
7421     ASSERT(array_length <= 0x7fffffff);  // Is int32_t.
7422     int last_array_index = static_cast<int>(array_length - 1);
7423     while (previous_separator_position < last_array_index) {
7424       String::WriteToFlat<Char>(separator, &buffer[cursor],
7425                                 0, separator_length);
7426       cursor += separator_length;
7427       previous_separator_position++;
7428     }
7429   }
7430   ASSERT(cursor <= buffer.length());
7431 }
7432
7433
7434 RUNTIME_FUNCTION(Runtime_SparseJoinWithSeparator) {
7435   HandleScope scope(isolate);
7436   ASSERT(args.length() == 3);
7437   CONVERT_ARG_HANDLE_CHECKED(JSArray, elements_array, 0);
7438   CONVERT_NUMBER_CHECKED(uint32_t, array_length, Uint32, args[1]);
7439   CONVERT_ARG_HANDLE_CHECKED(String, separator, 2);
7440   // elements_array is fast-mode JSarray of alternating positions
7441   // (increasing order) and strings.
7442   RUNTIME_ASSERT(elements_array->HasFastSmiOrObjectElements());
7443   // array_length is length of original array (used to add separators);
7444   // separator is string to put between elements. Assumed to be non-empty.
7445   RUNTIME_ASSERT(array_length > 0);
7446
7447   // Find total length of join result.
7448   int string_length = 0;
7449   bool is_ascii = separator->IsOneByteRepresentation();
7450   bool overflow = false;
7451   CONVERT_NUMBER_CHECKED(int, elements_length, Int32, elements_array->length());
7452   RUNTIME_ASSERT(elements_length <= elements_array->elements()->length());
7453   RUNTIME_ASSERT((elements_length & 1) == 0);  // Even length.
7454   FixedArray* elements = FixedArray::cast(elements_array->elements());
7455   for (int i = 0; i < elements_length; i += 2) {
7456     RUNTIME_ASSERT(elements->get(i)->IsNumber());
7457     CONVERT_NUMBER_CHECKED(uint32_t, position, Uint32, elements->get(i));
7458     RUNTIME_ASSERT(position < array_length);
7459     RUNTIME_ASSERT(elements->get(i + 1)->IsString());
7460   }
7461
7462   { DisallowHeapAllocation no_gc;
7463     for (int i = 0; i < elements_length; i += 2) {
7464       String* string = String::cast(elements->get(i + 1));
7465       int length = string->length();
7466       if (is_ascii && !string->IsOneByteRepresentation()) {
7467         is_ascii = false;
7468       }
7469       if (length > String::kMaxLength ||
7470           String::kMaxLength - length < string_length) {
7471         overflow = true;
7472         break;
7473       }
7474       string_length += length;
7475     }
7476   }
7477
7478   int separator_length = separator->length();
7479   if (!overflow && separator_length > 0) {
7480     if (array_length <= 0x7fffffffu) {
7481       int separator_count = static_cast<int>(array_length) - 1;
7482       int remaining_length = String::kMaxLength - string_length;
7483       if ((remaining_length / separator_length) >= separator_count) {
7484         string_length += separator_length * (array_length - 1);
7485       } else {
7486         // Not room for the separators within the maximal string length.
7487         overflow = true;
7488       }
7489     } else {
7490       // Nonempty separator and at least 2^31-1 separators necessary
7491       // means that the string is too large to create.
7492       STATIC_ASSERT(String::kMaxLength < 0x7fffffff);
7493       overflow = true;
7494     }
7495   }
7496   if (overflow) {
7497     // Throw an exception if the resulting string is too large. See
7498     // https://code.google.com/p/chromium/issues/detail?id=336820
7499     // for details.
7500     return isolate->ThrowInvalidStringLength();
7501   }
7502
7503   if (is_ascii) {
7504     Handle<SeqOneByteString> result = isolate->factory()->NewRawOneByteString(
7505         string_length).ToHandleChecked();
7506     JoinSparseArrayWithSeparator<uint8_t>(
7507         FixedArray::cast(elements_array->elements()),
7508         elements_length,
7509         array_length,
7510         *separator,
7511         Vector<uint8_t>(result->GetChars(), string_length));
7512     return *result;
7513   } else {
7514     Handle<SeqTwoByteString> result = isolate->factory()->NewRawTwoByteString(
7515         string_length).ToHandleChecked();
7516     JoinSparseArrayWithSeparator<uc16>(
7517         FixedArray::cast(elements_array->elements()),
7518         elements_length,
7519         array_length,
7520         *separator,
7521         Vector<uc16>(result->GetChars(), string_length));
7522     return *result;
7523   }
7524 }
7525
7526
7527 RUNTIME_FUNCTION(Runtime_NumberOr) {
7528   HandleScope scope(isolate);
7529   ASSERT(args.length() == 2);
7530
7531   CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
7532   CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
7533   return *isolate->factory()->NewNumberFromInt(x | y);
7534 }
7535
7536
7537 RUNTIME_FUNCTION(Runtime_NumberAnd) {
7538   HandleScope scope(isolate);
7539   ASSERT(args.length() == 2);
7540
7541   CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
7542   CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
7543   return *isolate->factory()->NewNumberFromInt(x & y);
7544 }
7545
7546
7547 RUNTIME_FUNCTION(Runtime_NumberXor) {
7548   HandleScope scope(isolate);
7549   ASSERT(args.length() == 2);
7550
7551   CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
7552   CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
7553   return *isolate->factory()->NewNumberFromInt(x ^ y);
7554 }
7555
7556
7557 RUNTIME_FUNCTION(Runtime_NumberShl) {
7558   HandleScope scope(isolate);
7559   ASSERT(args.length() == 2);
7560
7561   CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
7562   CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
7563   return *isolate->factory()->NewNumberFromInt(x << (y & 0x1f));
7564 }
7565
7566
7567 RUNTIME_FUNCTION(Runtime_NumberShr) {
7568   HandleScope scope(isolate);
7569   ASSERT(args.length() == 2);
7570
7571   CONVERT_NUMBER_CHECKED(uint32_t, x, Uint32, args[0]);
7572   CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
7573   return *isolate->factory()->NewNumberFromUint(x >> (y & 0x1f));
7574 }
7575
7576
7577 RUNTIME_FUNCTION(Runtime_NumberSar) {
7578   HandleScope scope(isolate);
7579   ASSERT(args.length() == 2);
7580
7581   CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
7582   CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
7583   return *isolate->factory()->NewNumberFromInt(
7584       ArithmeticShiftRight(x, y & 0x1f));
7585 }
7586
7587
7588 RUNTIME_FUNCTION(Runtime_NumberEquals) {
7589   SealHandleScope shs(isolate);
7590   ASSERT(args.length() == 2);
7591
7592   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7593   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
7594   if (std::isnan(x)) return Smi::FromInt(NOT_EQUAL);
7595   if (std::isnan(y)) return Smi::FromInt(NOT_EQUAL);
7596   if (x == y) return Smi::FromInt(EQUAL);
7597   Object* result;
7598   if ((fpclassify(x) == FP_ZERO) && (fpclassify(y) == FP_ZERO)) {
7599     result = Smi::FromInt(EQUAL);
7600   } else {
7601     result = Smi::FromInt(NOT_EQUAL);
7602   }
7603   return result;
7604 }
7605
7606
7607 RUNTIME_FUNCTION(Runtime_StringEquals) {
7608   HandleScope handle_scope(isolate);
7609   ASSERT(args.length() == 2);
7610
7611   CONVERT_ARG_HANDLE_CHECKED(String, x, 0);
7612   CONVERT_ARG_HANDLE_CHECKED(String, y, 1);
7613
7614   bool not_equal = !String::Equals(x, y);
7615   // This is slightly convoluted because the value that signifies
7616   // equality is 0 and inequality is 1 so we have to negate the result
7617   // from String::Equals.
7618   ASSERT(not_equal == 0 || not_equal == 1);
7619   STATIC_ASSERT(EQUAL == 0);
7620   STATIC_ASSERT(NOT_EQUAL == 1);
7621   return Smi::FromInt(not_equal);
7622 }
7623
7624
7625 RUNTIME_FUNCTION(Runtime_NumberCompare) {
7626   SealHandleScope shs(isolate);
7627   ASSERT(args.length() == 3);
7628
7629   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7630   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
7631   CONVERT_ARG_HANDLE_CHECKED(Object, uncomparable_result, 2)
7632   if (std::isnan(x) || std::isnan(y)) return *uncomparable_result;
7633   if (x == y) return Smi::FromInt(EQUAL);
7634   if (isless(x, y)) return Smi::FromInt(LESS);
7635   return Smi::FromInt(GREATER);
7636 }
7637
7638
7639 // Compare two Smis as if they were converted to strings and then
7640 // compared lexicographically.
7641 RUNTIME_FUNCTION(Runtime_SmiLexicographicCompare) {
7642   SealHandleScope shs(isolate);
7643   ASSERT(args.length() == 2);
7644   CONVERT_SMI_ARG_CHECKED(x_value, 0);
7645   CONVERT_SMI_ARG_CHECKED(y_value, 1);
7646
7647   // If the integers are equal so are the string representations.
7648   if (x_value == y_value) return Smi::FromInt(EQUAL);
7649
7650   // If one of the integers is zero the normal integer order is the
7651   // same as the lexicographic order of the string representations.
7652   if (x_value == 0 || y_value == 0)
7653     return Smi::FromInt(x_value < y_value ? LESS : GREATER);
7654
7655   // If only one of the integers is negative the negative number is
7656   // smallest because the char code of '-' is less than the char code
7657   // of any digit.  Otherwise, we make both values positive.
7658
7659   // Use unsigned values otherwise the logic is incorrect for -MIN_INT on
7660   // architectures using 32-bit Smis.
7661   uint32_t x_scaled = x_value;
7662   uint32_t y_scaled = y_value;
7663   if (x_value < 0 || y_value < 0) {
7664     if (y_value >= 0) return Smi::FromInt(LESS);
7665     if (x_value >= 0) return Smi::FromInt(GREATER);
7666     x_scaled = -x_value;
7667     y_scaled = -y_value;
7668   }
7669
7670   static const uint32_t kPowersOf10[] = {
7671     1, 10, 100, 1000, 10*1000, 100*1000,
7672     1000*1000, 10*1000*1000, 100*1000*1000,
7673     1000*1000*1000
7674   };
7675
7676   // If the integers have the same number of decimal digits they can be
7677   // compared directly as the numeric order is the same as the
7678   // lexicographic order.  If one integer has fewer digits, it is scaled
7679   // by some power of 10 to have the same number of digits as the longer
7680   // integer.  If the scaled integers are equal it means the shorter
7681   // integer comes first in the lexicographic order.
7682
7683   // From http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
7684   int x_log2 = IntegerLog2(x_scaled);
7685   int x_log10 = ((x_log2 + 1) * 1233) >> 12;
7686   x_log10 -= x_scaled < kPowersOf10[x_log10];
7687
7688   int y_log2 = IntegerLog2(y_scaled);
7689   int y_log10 = ((y_log2 + 1) * 1233) >> 12;
7690   y_log10 -= y_scaled < kPowersOf10[y_log10];
7691
7692   int tie = EQUAL;
7693
7694   if (x_log10 < y_log10) {
7695     // X has fewer digits.  We would like to simply scale up X but that
7696     // might overflow, e.g when comparing 9 with 1_000_000_000, 9 would
7697     // be scaled up to 9_000_000_000. So we scale up by the next
7698     // smallest power and scale down Y to drop one digit. It is OK to
7699     // drop one digit from the longer integer since the final digit is
7700     // past the length of the shorter integer.
7701     x_scaled *= kPowersOf10[y_log10 - x_log10 - 1];
7702     y_scaled /= 10;
7703     tie = LESS;
7704   } else if (y_log10 < x_log10) {
7705     y_scaled *= kPowersOf10[x_log10 - y_log10 - 1];
7706     x_scaled /= 10;
7707     tie = GREATER;
7708   }
7709
7710   if (x_scaled < y_scaled) return Smi::FromInt(LESS);
7711   if (x_scaled > y_scaled) return Smi::FromInt(GREATER);
7712   return Smi::FromInt(tie);
7713 }
7714
7715
7716 RUNTIME_FUNCTION(RuntimeHidden_StringCompare) {
7717   HandleScope handle_scope(isolate);
7718   ASSERT(args.length() == 2);
7719
7720   CONVERT_ARG_HANDLE_CHECKED(String, x, 0);
7721   CONVERT_ARG_HANDLE_CHECKED(String, y, 1);
7722
7723   isolate->counters()->string_compare_runtime()->Increment();
7724
7725   // A few fast case tests before we flatten.
7726   if (x.is_identical_to(y)) return Smi::FromInt(EQUAL);
7727   if (y->length() == 0) {
7728     if (x->length() == 0) return Smi::FromInt(EQUAL);
7729     return Smi::FromInt(GREATER);
7730   } else if (x->length() == 0) {
7731     return Smi::FromInt(LESS);
7732   }
7733
7734   int d = x->Get(0) - y->Get(0);
7735   if (d < 0) return Smi::FromInt(LESS);
7736   else if (d > 0) return Smi::FromInt(GREATER);
7737
7738   // Slow case.
7739   x = String::Flatten(x);
7740   y = String::Flatten(y);
7741
7742   DisallowHeapAllocation no_gc;
7743   Object* equal_prefix_result = Smi::FromInt(EQUAL);
7744   int prefix_length = x->length();
7745   if (y->length() < prefix_length) {
7746     prefix_length = y->length();
7747     equal_prefix_result = Smi::FromInt(GREATER);
7748   } else if (y->length() > prefix_length) {
7749     equal_prefix_result = Smi::FromInt(LESS);
7750   }
7751   int r;
7752   String::FlatContent x_content = x->GetFlatContent();
7753   String::FlatContent y_content = y->GetFlatContent();
7754   if (x_content.IsAscii()) {
7755     Vector<const uint8_t> x_chars = x_content.ToOneByteVector();
7756     if (y_content.IsAscii()) {
7757       Vector<const uint8_t> y_chars = y_content.ToOneByteVector();
7758       r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
7759     } else {
7760       Vector<const uc16> y_chars = y_content.ToUC16Vector();
7761       r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
7762     }
7763   } else {
7764     Vector<const uc16> x_chars = x_content.ToUC16Vector();
7765     if (y_content.IsAscii()) {
7766       Vector<const uint8_t> y_chars = y_content.ToOneByteVector();
7767       r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
7768     } else {
7769       Vector<const uc16> y_chars = y_content.ToUC16Vector();
7770       r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
7771     }
7772   }
7773   Object* result;
7774   if (r == 0) {
7775     result = equal_prefix_result;
7776   } else {
7777     result = (r < 0) ? Smi::FromInt(LESS) : Smi::FromInt(GREATER);
7778   }
7779   return result;
7780 }
7781
7782
7783 #define RUNTIME_UNARY_MATH(Name, name)                                         \
7784 RUNTIME_FUNCTION(Runtime_Math##Name) {                           \
7785   HandleScope scope(isolate);                                                  \
7786   ASSERT(args.length() == 1);                                                  \
7787   isolate->counters()->math_##name()->Increment();                             \
7788   CONVERT_DOUBLE_ARG_CHECKED(x, 0);                                            \
7789   return *isolate->factory()->NewHeapNumber(std::name(x));                     \
7790 }
7791
7792 RUNTIME_UNARY_MATH(Acos, acos)
7793 RUNTIME_UNARY_MATH(Asin, asin)
7794 RUNTIME_UNARY_MATH(Atan, atan)
7795 RUNTIME_UNARY_MATH(LogRT, log)
7796 #undef RUNTIME_UNARY_MATH
7797
7798
7799 RUNTIME_FUNCTION(Runtime_DoubleHi) {
7800   HandleScope scope(isolate);
7801   ASSERT(args.length() == 1);
7802   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7803   uint64_t integer = double_to_uint64(x);
7804   integer = (integer >> 32) & 0xFFFFFFFFu;
7805   return *isolate->factory()->NewNumber(static_cast<int32_t>(integer));
7806 }
7807
7808
7809 RUNTIME_FUNCTION(Runtime_DoubleLo) {
7810   HandleScope scope(isolate);
7811   ASSERT(args.length() == 1);
7812   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7813   return *isolate->factory()->NewNumber(
7814       static_cast<int32_t>(double_to_uint64(x) & 0xFFFFFFFFu));
7815 }
7816
7817
7818 RUNTIME_FUNCTION(Runtime_ConstructDouble) {
7819   HandleScope scope(isolate);
7820   ASSERT(args.length() == 2);
7821   CONVERT_NUMBER_CHECKED(uint32_t, hi, Uint32, args[0]);
7822   CONVERT_NUMBER_CHECKED(uint32_t, lo, Uint32, args[1]);
7823   uint64_t result = (static_cast<uint64_t>(hi) << 32) | lo;
7824   return *isolate->factory()->NewNumber(uint64_to_double(result));
7825 }
7826
7827
7828 static const double kPiDividedBy4 = 0.78539816339744830962;
7829
7830
7831 RUNTIME_FUNCTION(Runtime_MathAtan2) {
7832   HandleScope scope(isolate);
7833   ASSERT(args.length() == 2);
7834   isolate->counters()->math_atan2()->Increment();
7835
7836   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7837   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
7838   double result;
7839   if (std::isinf(x) && std::isinf(y)) {
7840     // Make sure that the result in case of two infinite arguments
7841     // is a multiple of Pi / 4. The sign of the result is determined
7842     // by the first argument (x) and the sign of the second argument
7843     // determines the multiplier: one or three.
7844     int multiplier = (x < 0) ? -1 : 1;
7845     if (y < 0) multiplier *= 3;
7846     result = multiplier * kPiDividedBy4;
7847   } else {
7848     result = std::atan2(x, y);
7849   }
7850   return *isolate->factory()->NewNumber(result);
7851 }
7852
7853
7854 RUNTIME_FUNCTION(Runtime_MathExpRT) {
7855   HandleScope scope(isolate);
7856   ASSERT(args.length() == 1);
7857   isolate->counters()->math_exp()->Increment();
7858
7859   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7860   lazily_initialize_fast_exp();
7861   return *isolate->factory()->NewNumber(fast_exp(x));
7862 }
7863
7864
7865 RUNTIME_FUNCTION(Runtime_MathFloorRT) {
7866   HandleScope scope(isolate);
7867   ASSERT(args.length() == 1);
7868   isolate->counters()->math_floor()->Increment();
7869
7870   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7871   return *isolate->factory()->NewNumber(std::floor(x));
7872 }
7873
7874
7875 // Slow version of Math.pow.  We check for fast paths for special cases.
7876 // Used if VFP3 is not available.
7877 RUNTIME_FUNCTION(RuntimeHidden_MathPowSlow) {
7878   HandleScope scope(isolate);
7879   ASSERT(args.length() == 2);
7880   isolate->counters()->math_pow()->Increment();
7881
7882   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7883
7884   // If the second argument is a smi, it is much faster to call the
7885   // custom powi() function than the generic pow().
7886   if (args[1]->IsSmi()) {
7887     int y = args.smi_at(1);
7888     return *isolate->factory()->NewNumber(power_double_int(x, y));
7889   }
7890
7891   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
7892   double result = power_helper(x, y);
7893   if (std::isnan(result)) return isolate->heap()->nan_value();
7894   return *isolate->factory()->NewNumber(result);
7895 }
7896
7897
7898 // Fast version of Math.pow if we know that y is not an integer and y is not
7899 // -0.5 or 0.5.  Used as slow case from full codegen.
7900 RUNTIME_FUNCTION(RuntimeHidden_MathPow) {
7901   HandleScope scope(isolate);
7902   ASSERT(args.length() == 2);
7903   isolate->counters()->math_pow()->Increment();
7904
7905   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7906   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
7907   if (y == 0) {
7908     return Smi::FromInt(1);
7909   } else {
7910     double result = power_double_double(x, y);
7911     if (std::isnan(result)) return isolate->heap()->nan_value();
7912     return *isolate->factory()->NewNumber(result);
7913   }
7914 }
7915
7916
7917 RUNTIME_FUNCTION(Runtime_RoundNumber) {
7918   HandleScope scope(isolate);
7919   ASSERT(args.length() == 1);
7920   CONVERT_NUMBER_ARG_HANDLE_CHECKED(input, 0);
7921   isolate->counters()->math_round()->Increment();
7922
7923   if (!input->IsHeapNumber()) {
7924     ASSERT(input->IsSmi());
7925     return *input;
7926   }
7927
7928   Handle<HeapNumber> number = Handle<HeapNumber>::cast(input);
7929
7930   double value = number->value();
7931   int exponent = number->get_exponent();
7932   int sign = number->get_sign();
7933
7934   if (exponent < -1) {
7935     // Number in range ]-0.5..0.5[. These always round to +/-zero.
7936     if (sign) return isolate->heap()->minus_zero_value();
7937     return Smi::FromInt(0);
7938   }
7939
7940   // We compare with kSmiValueSize - 2 because (2^30 - 0.1) has exponent 29 and
7941   // should be rounded to 2^30, which is not smi (for 31-bit smis, similar
7942   // argument holds for 32-bit smis).
7943   if (!sign && exponent < kSmiValueSize - 2) {
7944     return Smi::FromInt(static_cast<int>(value + 0.5));
7945   }
7946
7947   // If the magnitude is big enough, there's no place for fraction part. If we
7948   // try to add 0.5 to this number, 1.0 will be added instead.
7949   if (exponent >= 52) {
7950     return *number;
7951   }
7952
7953   if (sign && value >= -0.5) return isolate->heap()->minus_zero_value();
7954
7955   // Do not call NumberFromDouble() to avoid extra checks.
7956   return *isolate->factory()->NewNumber(std::floor(value + 0.5));
7957 }
7958
7959
7960 RUNTIME_FUNCTION(Runtime_MathSqrtRT) {
7961   HandleScope scope(isolate);
7962   ASSERT(args.length() == 1);
7963   isolate->counters()->math_sqrt()->Increment();
7964
7965   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7966   return *isolate->factory()->NewNumber(fast_sqrt(x));
7967 }
7968
7969
7970 RUNTIME_FUNCTION(Runtime_MathFround) {
7971   HandleScope scope(isolate);
7972   ASSERT(args.length() == 1);
7973
7974   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7975   float xf = static_cast<float>(x);
7976   return *isolate->factory()->NewNumber(xf);
7977 }
7978
7979
7980 RUNTIME_FUNCTION(Runtime_DateMakeDay) {
7981   SealHandleScope shs(isolate);
7982   ASSERT(args.length() == 2);
7983
7984   CONVERT_SMI_ARG_CHECKED(year, 0);
7985   CONVERT_SMI_ARG_CHECKED(month, 1);
7986
7987   int days = isolate->date_cache()->DaysFromYearMonth(year, month);
7988   RUNTIME_ASSERT(Smi::IsValid(days));
7989   return Smi::FromInt(days);
7990 }
7991
7992
7993 RUNTIME_FUNCTION(Runtime_DateSetValue) {
7994   HandleScope scope(isolate);
7995   ASSERT(args.length() == 3);
7996
7997   CONVERT_ARG_HANDLE_CHECKED(JSDate, date, 0);
7998   CONVERT_DOUBLE_ARG_CHECKED(time, 1);
7999   CONVERT_SMI_ARG_CHECKED(is_utc, 2);
8000
8001   DateCache* date_cache = isolate->date_cache();
8002
8003   Handle<Object> value;;
8004   bool is_value_nan = false;
8005   if (std::isnan(time)) {
8006     value = isolate->factory()->nan_value();
8007     is_value_nan = true;
8008   } else if (!is_utc &&
8009              (time < -DateCache::kMaxTimeBeforeUTCInMs ||
8010               time > DateCache::kMaxTimeBeforeUTCInMs)) {
8011     value = isolate->factory()->nan_value();
8012     is_value_nan = true;
8013   } else {
8014     time = is_utc ? time : date_cache->ToUTC(static_cast<int64_t>(time));
8015     if (time < -DateCache::kMaxTimeInMs ||
8016         time > DateCache::kMaxTimeInMs) {
8017       value = isolate->factory()->nan_value();
8018       is_value_nan = true;
8019     } else  {
8020       value = isolate->factory()->NewNumber(DoubleToInteger(time));
8021     }
8022   }
8023   date->SetValue(*value, is_value_nan);
8024   return *value;
8025 }
8026
8027
8028 RUNTIME_FUNCTION(RuntimeHidden_NewSloppyArguments) {
8029   HandleScope scope(isolate);
8030   ASSERT(args.length() == 3);
8031
8032   CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0);
8033   Object** parameters = reinterpret_cast<Object**>(args[1]);
8034   CONVERT_SMI_ARG_CHECKED(argument_count, 2);
8035
8036   Handle<JSObject> result =
8037       isolate->factory()->NewArgumentsObject(callee, argument_count);
8038   // Allocate the elements if needed.
8039   int parameter_count = callee->shared()->formal_parameter_count();
8040   if (argument_count > 0) {
8041     if (parameter_count > 0) {
8042       int mapped_count = Min(argument_count, parameter_count);
8043       Handle<FixedArray> parameter_map =
8044           isolate->factory()->NewFixedArray(mapped_count + 2, NOT_TENURED);
8045       parameter_map->set_map(
8046           isolate->heap()->sloppy_arguments_elements_map());
8047
8048       Handle<Map> map = Map::Copy(handle(result->map()));
8049       map->set_elements_kind(SLOPPY_ARGUMENTS_ELEMENTS);
8050
8051       result->set_map(*map);
8052       result->set_elements(*parameter_map);
8053
8054       // Store the context and the arguments array at the beginning of the
8055       // parameter map.
8056       Handle<Context> context(isolate->context());
8057       Handle<FixedArray> arguments =
8058           isolate->factory()->NewFixedArray(argument_count, NOT_TENURED);
8059       parameter_map->set(0, *context);
8060       parameter_map->set(1, *arguments);
8061
8062       // Loop over the actual parameters backwards.
8063       int index = argument_count - 1;
8064       while (index >= mapped_count) {
8065         // These go directly in the arguments array and have no
8066         // corresponding slot in the parameter map.
8067         arguments->set(index, *(parameters - index - 1));
8068         --index;
8069       }
8070
8071       Handle<ScopeInfo> scope_info(callee->shared()->scope_info());
8072       while (index >= 0) {
8073         // Detect duplicate names to the right in the parameter list.
8074         Handle<String> name(scope_info->ParameterName(index));
8075         int context_local_count = scope_info->ContextLocalCount();
8076         bool duplicate = false;
8077         for (int j = index + 1; j < parameter_count; ++j) {
8078           if (scope_info->ParameterName(j) == *name) {
8079             duplicate = true;
8080             break;
8081           }
8082         }
8083
8084         if (duplicate) {
8085           // This goes directly in the arguments array with a hole in the
8086           // parameter map.
8087           arguments->set(index, *(parameters - index - 1));
8088           parameter_map->set_the_hole(index + 2);
8089         } else {
8090           // The context index goes in the parameter map with a hole in the
8091           // arguments array.
8092           int context_index = -1;
8093           for (int j = 0; j < context_local_count; ++j) {
8094             if (scope_info->ContextLocalName(j) == *name) {
8095               context_index = j;
8096               break;
8097             }
8098           }
8099           ASSERT(context_index >= 0);
8100           arguments->set_the_hole(index);
8101           parameter_map->set(index + 2, Smi::FromInt(
8102               Context::MIN_CONTEXT_SLOTS + context_index));
8103         }
8104
8105         --index;
8106       }
8107     } else {
8108       // If there is no aliasing, the arguments object elements are not
8109       // special in any way.
8110       Handle<FixedArray> elements =
8111           isolate->factory()->NewFixedArray(argument_count, NOT_TENURED);
8112       result->set_elements(*elements);
8113       for (int i = 0; i < argument_count; ++i) {
8114         elements->set(i, *(parameters - i - 1));
8115       }
8116     }
8117   }
8118   return *result;
8119 }
8120
8121
8122 RUNTIME_FUNCTION(RuntimeHidden_NewStrictArguments) {
8123   HandleScope scope(isolate);
8124   ASSERT(args.length() == 3);
8125   CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0)
8126   Object** parameters = reinterpret_cast<Object**>(args[1]);
8127   CONVERT_SMI_ARG_CHECKED(length, 2);
8128
8129   Handle<JSObject> result =
8130         isolate->factory()->NewArgumentsObject(callee, length);
8131
8132   if (length > 0) {
8133     Handle<FixedArray> array =
8134         isolate->factory()->NewUninitializedFixedArray(length);
8135     DisallowHeapAllocation no_gc;
8136     WriteBarrierMode mode = array->GetWriteBarrierMode(no_gc);
8137     for (int i = 0; i < length; i++) {
8138       array->set(i, *--parameters, mode);
8139     }
8140     result->set_elements(*array);
8141   }
8142   return *result;
8143 }
8144
8145
8146 RUNTIME_FUNCTION(RuntimeHidden_NewClosureFromStubFailure) {
8147   HandleScope scope(isolate);
8148   ASSERT(args.length() == 1);
8149   CONVERT_ARG_HANDLE_CHECKED(SharedFunctionInfo, shared, 0);
8150   Handle<Context> context(isolate->context());
8151   PretenureFlag pretenure_flag = NOT_TENURED;
8152   return *isolate->factory()->NewFunctionFromSharedFunctionInfo(
8153       shared,  context, pretenure_flag);
8154 }
8155
8156
8157 RUNTIME_FUNCTION(RuntimeHidden_NewClosure) {
8158   HandleScope scope(isolate);
8159   ASSERT(args.length() == 3);
8160   CONVERT_ARG_HANDLE_CHECKED(Context, context, 0);
8161   CONVERT_ARG_HANDLE_CHECKED(SharedFunctionInfo, shared, 1);
8162   CONVERT_BOOLEAN_ARG_CHECKED(pretenure, 2);
8163
8164   // The caller ensures that we pretenure closures that are assigned
8165   // directly to properties.
8166   PretenureFlag pretenure_flag = pretenure ? TENURED : NOT_TENURED;
8167   return *isolate->factory()->NewFunctionFromSharedFunctionInfo(
8168       shared, context, pretenure_flag);
8169 }
8170
8171
8172 // Find the arguments of the JavaScript function invocation that called
8173 // into C++ code. Collect these in a newly allocated array of handles (possibly
8174 // prefixed by a number of empty handles).
8175 static SmartArrayPointer<Handle<Object> > GetCallerArguments(
8176     Isolate* isolate,
8177     int prefix_argc,
8178     int* total_argc) {
8179   // Find frame containing arguments passed to the caller.
8180   JavaScriptFrameIterator it(isolate);
8181   JavaScriptFrame* frame = it.frame();
8182   List<JSFunction*> functions(2);
8183   frame->GetFunctions(&functions);
8184   if (functions.length() > 1) {
8185     int inlined_jsframe_index = functions.length() - 1;
8186     JSFunction* inlined_function = functions[inlined_jsframe_index];
8187     SlotRefValueBuilder slot_refs(
8188         frame,
8189         inlined_jsframe_index,
8190         inlined_function->shared()->formal_parameter_count());
8191
8192     int args_count = slot_refs.args_length();
8193
8194     *total_argc = prefix_argc + args_count;
8195     SmartArrayPointer<Handle<Object> > param_data(
8196         NewArray<Handle<Object> >(*total_argc));
8197     slot_refs.Prepare(isolate);
8198     for (int i = 0; i < args_count; i++) {
8199       Handle<Object> val = slot_refs.GetNext(isolate, 0);
8200       param_data[prefix_argc + i] = val;
8201     }
8202     slot_refs.Finish(isolate);
8203
8204     return param_data;
8205   } else {
8206     it.AdvanceToArgumentsFrame();
8207     frame = it.frame();
8208     int args_count = frame->ComputeParametersCount();
8209
8210     *total_argc = prefix_argc + args_count;
8211     SmartArrayPointer<Handle<Object> > param_data(
8212         NewArray<Handle<Object> >(*total_argc));
8213     for (int i = 0; i < args_count; i++) {
8214       Handle<Object> val = Handle<Object>(frame->GetParameter(i), isolate);
8215       param_data[prefix_argc + i] = val;
8216     }
8217     return param_data;
8218   }
8219 }
8220
8221
8222 RUNTIME_FUNCTION(Runtime_FunctionBindArguments) {
8223   HandleScope scope(isolate);
8224   ASSERT(args.length() == 4);
8225   CONVERT_ARG_HANDLE_CHECKED(JSFunction, bound_function, 0);
8226   CONVERT_ARG_HANDLE_CHECKED(Object, bindee, 1);
8227   CONVERT_ARG_HANDLE_CHECKED(Object, this_object, 2);
8228   CONVERT_NUMBER_ARG_HANDLE_CHECKED(new_length, 3);
8229
8230   // TODO(lrn): Create bound function in C++ code from premade shared info.
8231   bound_function->shared()->set_bound(true);
8232   // Get all arguments of calling function (Function.prototype.bind).
8233   int argc = 0;
8234   SmartArrayPointer<Handle<Object> > arguments =
8235       GetCallerArguments(isolate, 0, &argc);
8236   // Don't count the this-arg.
8237   if (argc > 0) {
8238     RUNTIME_ASSERT(arguments[0].is_identical_to(this_object));
8239     argc--;
8240   } else {
8241     RUNTIME_ASSERT(this_object->IsUndefined());
8242   }
8243   // Initialize array of bindings (function, this, and any existing arguments
8244   // if the function was already bound).
8245   Handle<FixedArray> new_bindings;
8246   int i;
8247   if (bindee->IsJSFunction() && JSFunction::cast(*bindee)->shared()->bound()) {
8248     Handle<FixedArray> old_bindings(
8249         JSFunction::cast(*bindee)->function_bindings());
8250     RUNTIME_ASSERT(old_bindings->length() > JSFunction::kBoundFunctionIndex);
8251     new_bindings =
8252         isolate->factory()->NewFixedArray(old_bindings->length() + argc);
8253     bindee = Handle<Object>(old_bindings->get(JSFunction::kBoundFunctionIndex),
8254                             isolate);
8255     i = 0;
8256     for (int n = old_bindings->length(); i < n; i++) {
8257       new_bindings->set(i, old_bindings->get(i));
8258     }
8259   } else {
8260     int array_size = JSFunction::kBoundArgumentsStartIndex + argc;
8261     new_bindings = isolate->factory()->NewFixedArray(array_size);
8262     new_bindings->set(JSFunction::kBoundFunctionIndex, *bindee);
8263     new_bindings->set(JSFunction::kBoundThisIndex, *this_object);
8264     i = 2;
8265   }
8266   // Copy arguments, skipping the first which is "this_arg".
8267   for (int j = 0; j < argc; j++, i++) {
8268     new_bindings->set(i, *arguments[j + 1]);
8269   }
8270   new_bindings->set_map_no_write_barrier(
8271       isolate->heap()->fixed_cow_array_map());
8272   bound_function->set_function_bindings(*new_bindings);
8273
8274   // Update length. Have to remove the prototype first so that map migration
8275   // is happy about the number of fields.
8276   RUNTIME_ASSERT(bound_function->RemovePrototype());
8277   Handle<Map> bound_function_map(
8278       isolate->native_context()->bound_function_map());
8279   JSObject::MigrateToMap(bound_function, bound_function_map);
8280   Handle<String> length_string = isolate->factory()->length_string();
8281   PropertyAttributes attr =
8282       static_cast<PropertyAttributes>(DONT_DELETE | DONT_ENUM | READ_ONLY);
8283   RETURN_FAILURE_ON_EXCEPTION(
8284       isolate,
8285       JSObject::SetOwnPropertyIgnoreAttributes(bound_function, length_string,
8286                                                new_length, attr));
8287   return *bound_function;
8288 }
8289
8290
8291 RUNTIME_FUNCTION(Runtime_BoundFunctionGetBindings) {
8292   HandleScope handles(isolate);
8293   ASSERT(args.length() == 1);
8294   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, callable, 0);
8295   if (callable->IsJSFunction()) {
8296     Handle<JSFunction> function = Handle<JSFunction>::cast(callable);
8297     if (function->shared()->bound()) {
8298       Handle<FixedArray> bindings(function->function_bindings());
8299       RUNTIME_ASSERT(bindings->map() == isolate->heap()->fixed_cow_array_map());
8300       return *isolate->factory()->NewJSArrayWithElements(bindings);
8301     }
8302   }
8303   return isolate->heap()->undefined_value();
8304 }
8305
8306
8307 RUNTIME_FUNCTION(Runtime_NewObjectFromBound) {
8308   HandleScope scope(isolate);
8309   ASSERT(args.length() == 1);
8310   // First argument is a function to use as a constructor.
8311   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
8312   RUNTIME_ASSERT(function->shared()->bound());
8313
8314   // The argument is a bound function. Extract its bound arguments
8315   // and callable.
8316   Handle<FixedArray> bound_args =
8317       Handle<FixedArray>(FixedArray::cast(function->function_bindings()));
8318   int bound_argc = bound_args->length() - JSFunction::kBoundArgumentsStartIndex;
8319   Handle<Object> bound_function(
8320       JSReceiver::cast(bound_args->get(JSFunction::kBoundFunctionIndex)),
8321       isolate);
8322   ASSERT(!bound_function->IsJSFunction() ||
8323          !Handle<JSFunction>::cast(bound_function)->shared()->bound());
8324
8325   int total_argc = 0;
8326   SmartArrayPointer<Handle<Object> > param_data =
8327       GetCallerArguments(isolate, bound_argc, &total_argc);
8328   for (int i = 0; i < bound_argc; i++) {
8329     param_data[i] = Handle<Object>(bound_args->get(
8330         JSFunction::kBoundArgumentsStartIndex + i), isolate);
8331   }
8332
8333   if (!bound_function->IsJSFunction()) {
8334     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
8335         isolate, bound_function,
8336         Execution::TryGetConstructorDelegate(isolate, bound_function));
8337   }
8338   ASSERT(bound_function->IsJSFunction());
8339
8340   Handle<Object> result;
8341   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
8342       isolate, result,
8343       Execution::New(Handle<JSFunction>::cast(bound_function),
8344                      total_argc, param_data.get()));
8345   return *result;
8346 }
8347
8348
8349 static Object* Runtime_NewObjectHelper(Isolate* isolate,
8350                                             Handle<Object> constructor,
8351                                             Handle<AllocationSite> site) {
8352   // If the constructor isn't a proper function we throw a type error.
8353   if (!constructor->IsJSFunction()) {
8354     Vector< Handle<Object> > arguments = HandleVector(&constructor, 1);
8355     Handle<Object> type_error =
8356         isolate->factory()->NewTypeError("not_constructor", arguments);
8357     return isolate->Throw(*type_error);
8358   }
8359
8360   Handle<JSFunction> function = Handle<JSFunction>::cast(constructor);
8361
8362   // If function should not have prototype, construction is not allowed. In this
8363   // case generated code bailouts here, since function has no initial_map.
8364   if (!function->should_have_prototype() && !function->shared()->bound()) {
8365     Vector< Handle<Object> > arguments = HandleVector(&constructor, 1);
8366     Handle<Object> type_error =
8367         isolate->factory()->NewTypeError("not_constructor", arguments);
8368     return isolate->Throw(*type_error);
8369   }
8370
8371   Debug* debug = isolate->debug();
8372   // Handle stepping into constructors if step into is active.
8373   if (debug->StepInActive()) {
8374     debug->HandleStepIn(function, Handle<Object>::null(), 0, true);
8375   }
8376
8377   if (function->has_initial_map()) {
8378     if (function->initial_map()->instance_type() == JS_FUNCTION_TYPE) {
8379       // The 'Function' function ignores the receiver object when
8380       // called using 'new' and creates a new JSFunction object that
8381       // is returned.  The receiver object is only used for error
8382       // reporting if an error occurs when constructing the new
8383       // JSFunction. Factory::NewJSObject() should not be used to
8384       // allocate JSFunctions since it does not properly initialize
8385       // the shared part of the function. Since the receiver is
8386       // ignored anyway, we use the global object as the receiver
8387       // instead of a new JSFunction object. This way, errors are
8388       // reported the same way whether or not 'Function' is called
8389       // using 'new'.
8390       return isolate->context()->global_object();
8391     }
8392   }
8393
8394   // The function should be compiled for the optimization hints to be
8395   // available.
8396   Compiler::EnsureCompiled(function, CLEAR_EXCEPTION);
8397
8398   Handle<JSObject> result;
8399   if (site.is_null()) {
8400     result = isolate->factory()->NewJSObject(function);
8401   } else {
8402     result = isolate->factory()->NewJSObjectWithMemento(function, site);
8403   }
8404
8405   isolate->counters()->constructed_objects()->Increment();
8406   isolate->counters()->constructed_objects_runtime()->Increment();
8407
8408   return *result;
8409 }
8410
8411
8412 RUNTIME_FUNCTION(RuntimeHidden_NewObject) {
8413   HandleScope scope(isolate);
8414   ASSERT(args.length() == 1);
8415   CONVERT_ARG_HANDLE_CHECKED(Object, constructor, 0);
8416   return Runtime_NewObjectHelper(isolate,
8417                                  constructor,
8418                                  Handle<AllocationSite>::null());
8419 }
8420
8421
8422 RUNTIME_FUNCTION(RuntimeHidden_NewObjectWithAllocationSite) {
8423   HandleScope scope(isolate);
8424   ASSERT(args.length() == 2);
8425   CONVERT_ARG_HANDLE_CHECKED(Object, constructor, 1);
8426   CONVERT_ARG_HANDLE_CHECKED(Object, feedback, 0);
8427   Handle<AllocationSite> site;
8428   if (feedback->IsAllocationSite()) {
8429     // The feedback can be an AllocationSite or undefined.
8430     site = Handle<AllocationSite>::cast(feedback);
8431   }
8432   return Runtime_NewObjectHelper(isolate, constructor, site);
8433 }
8434
8435
8436 RUNTIME_FUNCTION(RuntimeHidden_FinalizeInstanceSize) {
8437   HandleScope scope(isolate);
8438   ASSERT(args.length() == 1);
8439
8440   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
8441   function->CompleteInobjectSlackTracking();
8442
8443   return isolate->heap()->undefined_value();
8444 }
8445
8446
8447 RUNTIME_FUNCTION(RuntimeHidden_CompileUnoptimized) {
8448   HandleScope scope(isolate);
8449   ASSERT(args.length() == 1);
8450   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
8451 #ifdef DEBUG
8452   if (FLAG_trace_lazy && !function->shared()->is_compiled()) {
8453     PrintF("[unoptimized: ");
8454     function->PrintName();
8455     PrintF("]\n");
8456   }
8457 #endif
8458
8459   // Compile the target function.
8460   ASSERT(function->shared()->allows_lazy_compilation());
8461
8462   Handle<Code> code;
8463   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, code,
8464                                      Compiler::GetUnoptimizedCode(function));
8465   function->ReplaceCode(*code);
8466
8467   // All done. Return the compiled code.
8468   ASSERT(function->is_compiled());
8469   ASSERT(function->code()->kind() == Code::FUNCTION ||
8470          (FLAG_always_opt &&
8471           function->code()->kind() == Code::OPTIMIZED_FUNCTION));
8472   return *code;
8473 }
8474
8475
8476 RUNTIME_FUNCTION(RuntimeHidden_CompileOptimized) {
8477   HandleScope scope(isolate);
8478   ASSERT(args.length() == 2);
8479   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
8480   CONVERT_BOOLEAN_ARG_CHECKED(concurrent, 1);
8481
8482   Handle<Code> unoptimized(function->shared()->code());
8483   if (!function->shared()->is_compiled()) {
8484     // If the function is not compiled, do not optimize.
8485     // This can happen if the debugger is activated and
8486     // the function is returned to the not compiled state.
8487     // TODO(yangguo): reconsider this.
8488     function->ReplaceCode(function->shared()->code());
8489   } else if (!isolate->use_crankshaft() ||
8490              function->shared()->optimization_disabled() ||
8491              isolate->DebuggerHasBreakPoints()) {
8492     // If the function is not optimizable or debugger is active continue
8493     // using the code from the full compiler.
8494     if (FLAG_trace_opt) {
8495       PrintF("[failed to optimize ");
8496       function->PrintName();
8497       PrintF(": is code optimizable: %s, is debugger enabled: %s]\n",
8498           function->shared()->optimization_disabled() ? "F" : "T",
8499           isolate->DebuggerHasBreakPoints() ? "T" : "F");
8500     }
8501     function->ReplaceCode(*unoptimized);
8502   } else {
8503     Compiler::ConcurrencyMode mode = concurrent ? Compiler::CONCURRENT
8504                                                 : Compiler::NOT_CONCURRENT;
8505     Handle<Code> code;
8506     if (Compiler::GetOptimizedCode(
8507             function, unoptimized, mode).ToHandle(&code)) {
8508       function->ReplaceCode(*code);
8509     } else {
8510       function->ReplaceCode(*unoptimized);
8511     }
8512   }
8513
8514   ASSERT(function->code()->kind() == Code::FUNCTION ||
8515          function->code()->kind() == Code::OPTIMIZED_FUNCTION ||
8516          function->IsInOptimizationQueue());
8517   return function->code();
8518 }
8519
8520
8521 class ActivationsFinder : public ThreadVisitor {
8522  public:
8523   Code* code_;
8524   bool has_code_activations_;
8525
8526   explicit ActivationsFinder(Code* code)
8527     : code_(code),
8528       has_code_activations_(false) { }
8529
8530   void VisitThread(Isolate* isolate, ThreadLocalTop* top) {
8531     JavaScriptFrameIterator it(isolate, top);
8532     VisitFrames(&it);
8533   }
8534
8535   void VisitFrames(JavaScriptFrameIterator* it) {
8536     for (; !it->done(); it->Advance()) {
8537       JavaScriptFrame* frame = it->frame();
8538       if (code_->contains(frame->pc())) has_code_activations_ = true;
8539     }
8540   }
8541 };
8542
8543
8544 RUNTIME_FUNCTION(RuntimeHidden_NotifyStubFailure) {
8545   HandleScope scope(isolate);
8546   ASSERT(args.length() == 0);
8547   Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate);
8548   ASSERT(AllowHeapAllocation::IsAllowed());
8549   delete deoptimizer;
8550   return isolate->heap()->undefined_value();
8551 }
8552
8553
8554 RUNTIME_FUNCTION(RuntimeHidden_NotifyDeoptimized) {
8555   HandleScope scope(isolate);
8556   ASSERT(args.length() == 1);
8557   CONVERT_SMI_ARG_CHECKED(type_arg, 0);
8558   Deoptimizer::BailoutType type =
8559       static_cast<Deoptimizer::BailoutType>(type_arg);
8560   Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate);
8561   ASSERT(AllowHeapAllocation::IsAllowed());
8562
8563   Handle<JSFunction> function = deoptimizer->function();
8564   Handle<Code> optimized_code = deoptimizer->compiled_code();
8565
8566   ASSERT(optimized_code->kind() == Code::OPTIMIZED_FUNCTION);
8567   ASSERT(type == deoptimizer->bailout_type());
8568
8569   // Make sure to materialize objects before causing any allocation.
8570   JavaScriptFrameIterator it(isolate);
8571   deoptimizer->MaterializeHeapObjects(&it);
8572   delete deoptimizer;
8573
8574   JavaScriptFrame* frame = it.frame();
8575   RUNTIME_ASSERT(frame->function()->IsJSFunction());
8576   ASSERT(frame->function() == *function);
8577
8578   // Avoid doing too much work when running with --always-opt and keep
8579   // the optimized code around.
8580   if (FLAG_always_opt || type == Deoptimizer::LAZY) {
8581     return isolate->heap()->undefined_value();
8582   }
8583
8584   // Search for other activations of the same function and code.
8585   ActivationsFinder activations_finder(*optimized_code);
8586   activations_finder.VisitFrames(&it);
8587   isolate->thread_manager()->IterateArchivedThreads(&activations_finder);
8588
8589   if (!activations_finder.has_code_activations_) {
8590     if (function->code() == *optimized_code) {
8591       if (FLAG_trace_deopt) {
8592         PrintF("[removing optimized code for: ");
8593         function->PrintName();
8594         PrintF("]\n");
8595       }
8596       function->ReplaceCode(function->shared()->code());
8597       // Evict optimized code for this function from the cache so that it
8598       // doesn't get used for new closures.
8599       function->shared()->EvictFromOptimizedCodeMap(*optimized_code,
8600                                                     "notify deoptimized");
8601     }
8602   } else {
8603     // TODO(titzer): we should probably do DeoptimizeCodeList(code)
8604     // unconditionally if the code is not already marked for deoptimization.
8605     // If there is an index by shared function info, all the better.
8606     Deoptimizer::DeoptimizeFunction(*function);
8607   }
8608
8609   return isolate->heap()->undefined_value();
8610 }
8611
8612
8613 RUNTIME_FUNCTION(Runtime_DeoptimizeFunction) {
8614   HandleScope scope(isolate);
8615   ASSERT(args.length() == 1);
8616   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
8617   if (!function->IsOptimized()) return isolate->heap()->undefined_value();
8618
8619   Deoptimizer::DeoptimizeFunction(*function);
8620
8621   return isolate->heap()->undefined_value();
8622 }
8623
8624
8625 RUNTIME_FUNCTION(Runtime_ClearFunctionTypeFeedback) {
8626   HandleScope scope(isolate);
8627   ASSERT(args.length() == 1);
8628   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
8629   function->shared()->ClearTypeFeedbackInfo();
8630   Code* unoptimized = function->shared()->code();
8631   if (unoptimized->kind() == Code::FUNCTION) {
8632     unoptimized->ClearInlineCaches();
8633   }
8634   return isolate->heap()->undefined_value();
8635 }
8636
8637
8638 RUNTIME_FUNCTION(Runtime_RunningInSimulator) {
8639   SealHandleScope shs(isolate);
8640   ASSERT(args.length() == 0);
8641 #if defined(USE_SIMULATOR)
8642   return isolate->heap()->true_value();
8643 #else
8644   return isolate->heap()->false_value();
8645 #endif
8646 }
8647
8648
8649 RUNTIME_FUNCTION(Runtime_IsConcurrentRecompilationSupported) {
8650   SealHandleScope shs(isolate);
8651   ASSERT(args.length() == 0);
8652   return isolate->heap()->ToBoolean(
8653       isolate->concurrent_recompilation_enabled());
8654 }
8655
8656
8657 RUNTIME_FUNCTION(Runtime_OptimizeFunctionOnNextCall) {
8658   HandleScope scope(isolate);
8659   RUNTIME_ASSERT(args.length() == 1 || args.length() == 2);
8660   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
8661
8662   if (!function->IsOptimizable() &&
8663       !function->IsMarkedForConcurrentOptimization() &&
8664       !function->IsInOptimizationQueue()) {
8665     return isolate->heap()->undefined_value();
8666   }
8667
8668   function->MarkForOptimization();
8669
8670   Code* unoptimized = function->shared()->code();
8671   if (args.length() == 2 &&
8672       unoptimized->kind() == Code::FUNCTION) {
8673     CONVERT_ARG_HANDLE_CHECKED(String, type, 1);
8674     if (type->IsOneByteEqualTo(STATIC_ASCII_VECTOR("osr"))) {
8675       // Start patching from the currently patched loop nesting level.
8676       int current_level = unoptimized->allow_osr_at_loop_nesting_level();
8677       ASSERT(BackEdgeTable::Verify(isolate, unoptimized, current_level));
8678       if (FLAG_use_osr) {
8679         for (int i = current_level + 1; i <= Code::kMaxLoopNestingMarker; i++) {
8680           unoptimized->set_allow_osr_at_loop_nesting_level(i);
8681           isolate->runtime_profiler()->AttemptOnStackReplacement(*function);
8682         }
8683       }
8684     } else if (type->IsOneByteEqualTo(STATIC_ASCII_VECTOR("concurrent")) &&
8685                isolate->concurrent_recompilation_enabled()) {
8686       function->MarkForConcurrentOptimization();
8687     }
8688   }
8689
8690   return isolate->heap()->undefined_value();
8691 }
8692
8693
8694 RUNTIME_FUNCTION(Runtime_NeverOptimizeFunction) {
8695   HandleScope scope(isolate);
8696   ASSERT(args.length() == 1);
8697   CONVERT_ARG_CHECKED(JSFunction, function, 0);
8698   function->shared()->set_optimization_disabled(true);
8699   return isolate->heap()->undefined_value();
8700 }
8701
8702
8703 RUNTIME_FUNCTION(Runtime_GetOptimizationStatus) {
8704   HandleScope scope(isolate);
8705   RUNTIME_ASSERT(args.length() == 1 || args.length() == 2);
8706   if (!isolate->use_crankshaft()) {
8707     return Smi::FromInt(4);  // 4 == "never".
8708   }
8709   bool sync_with_compiler_thread = true;
8710   if (args.length() == 2) {
8711     CONVERT_ARG_HANDLE_CHECKED(String, sync, 1);
8712     if (sync->IsOneByteEqualTo(STATIC_ASCII_VECTOR("no sync"))) {
8713       sync_with_compiler_thread = false;
8714     }
8715   }
8716   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
8717   if (isolate->concurrent_recompilation_enabled() &&
8718       sync_with_compiler_thread) {
8719     while (function->IsInOptimizationQueue()) {
8720       isolate->optimizing_compiler_thread()->InstallOptimizedFunctions();
8721       OS::Sleep(50);
8722     }
8723   }
8724   if (FLAG_always_opt) {
8725     // We may have always opt, but that is more best-effort than a real
8726     // promise, so we still say "no" if it is not optimized.
8727     return function->IsOptimized() ? Smi::FromInt(3)   // 3 == "always".
8728                                    : Smi::FromInt(2);  // 2 == "no".
8729   }
8730   if (FLAG_deopt_every_n_times) {
8731     return Smi::FromInt(6);  // 6 == "maybe deopted".
8732   }
8733   return function->IsOptimized() ? Smi::FromInt(1)   // 1 == "yes".
8734                                  : Smi::FromInt(2);  // 2 == "no".
8735 }
8736
8737
8738 RUNTIME_FUNCTION(Runtime_UnblockConcurrentRecompilation) {
8739   ASSERT(args.length() == 0);
8740   RUNTIME_ASSERT(FLAG_block_concurrent_recompilation);
8741   RUNTIME_ASSERT(isolate->concurrent_recompilation_enabled());
8742   isolate->optimizing_compiler_thread()->Unblock();
8743   return isolate->heap()->undefined_value();
8744 }
8745
8746
8747 RUNTIME_FUNCTION(Runtime_GetOptimizationCount) {
8748   HandleScope scope(isolate);
8749   ASSERT(args.length() == 1);
8750   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
8751   return Smi::FromInt(function->shared()->opt_count());
8752 }
8753
8754
8755 static bool IsSuitableForOnStackReplacement(Isolate* isolate,
8756                                             Handle<JSFunction> function,
8757                                             Handle<Code> current_code) {
8758   // Keep track of whether we've succeeded in optimizing.
8759   if (!isolate->use_crankshaft() || !current_code->optimizable()) return false;
8760   // If we are trying to do OSR when there are already optimized
8761   // activations of the function, it means (a) the function is directly or
8762   // indirectly recursive and (b) an optimized invocation has been
8763   // deoptimized so that we are currently in an unoptimized activation.
8764   // Check for optimized activations of this function.
8765   for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) {
8766     JavaScriptFrame* frame = it.frame();
8767     if (frame->is_optimized() && frame->function() == *function) return false;
8768   }
8769
8770   return true;
8771 }
8772
8773
8774 RUNTIME_FUNCTION(Runtime_CompileForOnStackReplacement) {
8775   HandleScope scope(isolate);
8776   ASSERT(args.length() == 1);
8777   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
8778   Handle<Code> caller_code(function->shared()->code());
8779
8780   // We're not prepared to handle a function with arguments object.
8781   ASSERT(!function->shared()->uses_arguments());
8782
8783   RUNTIME_ASSERT(FLAG_use_osr);
8784
8785   // Passing the PC in the javascript frame from the caller directly is
8786   // not GC safe, so we walk the stack to get it.
8787   JavaScriptFrameIterator it(isolate);
8788   JavaScriptFrame* frame = it.frame();
8789   if (!caller_code->contains(frame->pc())) {
8790     // Code on the stack may not be the code object referenced by the shared
8791     // function info.  It may have been replaced to include deoptimization data.
8792     caller_code = Handle<Code>(frame->LookupCode());
8793   }
8794
8795   uint32_t pc_offset = static_cast<uint32_t>(
8796       frame->pc() - caller_code->instruction_start());
8797
8798 #ifdef DEBUG
8799   ASSERT_EQ(frame->function(), *function);
8800   ASSERT_EQ(frame->LookupCode(), *caller_code);
8801   ASSERT(caller_code->contains(frame->pc()));
8802 #endif  // DEBUG
8803
8804
8805   BailoutId ast_id = caller_code->TranslatePcOffsetToAstId(pc_offset);
8806   ASSERT(!ast_id.IsNone());
8807
8808   Compiler::ConcurrencyMode mode =
8809       isolate->concurrent_osr_enabled() &&
8810       (function->shared()->ast_node_count() > 512) ? Compiler::CONCURRENT
8811                                                    : Compiler::NOT_CONCURRENT;
8812   Handle<Code> result = Handle<Code>::null();
8813
8814   OptimizedCompileJob* job = NULL;
8815   if (mode == Compiler::CONCURRENT) {
8816     // Gate the OSR entry with a stack check.
8817     BackEdgeTable::AddStackCheck(caller_code, pc_offset);
8818     // Poll already queued compilation jobs.
8819     OptimizingCompilerThread* thread = isolate->optimizing_compiler_thread();
8820     if (thread->IsQueuedForOSR(function, ast_id)) {
8821       if (FLAG_trace_osr) {
8822         PrintF("[OSR - Still waiting for queued: ");
8823         function->PrintName();
8824         PrintF(" at AST id %d]\n", ast_id.ToInt());
8825       }
8826       return NULL;
8827     }
8828
8829     job = thread->FindReadyOSRCandidate(function, ast_id);
8830   }
8831
8832   if (job != NULL) {
8833     if (FLAG_trace_osr) {
8834       PrintF("[OSR - Found ready: ");
8835       function->PrintName();
8836       PrintF(" at AST id %d]\n", ast_id.ToInt());
8837     }
8838     result = Compiler::GetConcurrentlyOptimizedCode(job);
8839   } else if (IsSuitableForOnStackReplacement(isolate, function, caller_code)) {
8840     if (FLAG_trace_osr) {
8841       PrintF("[OSR - Compiling: ");
8842       function->PrintName();
8843       PrintF(" at AST id %d]\n", ast_id.ToInt());
8844     }
8845     MaybeHandle<Code> maybe_result = Compiler::GetOptimizedCode(
8846         function, caller_code, mode, ast_id);
8847     if (maybe_result.ToHandle(&result) &&
8848         result.is_identical_to(isolate->builtins()->InOptimizationQueue())) {
8849       // Optimization is queued.  Return to check later.
8850       return NULL;
8851     }
8852   }
8853
8854   // Revert the patched back edge table, regardless of whether OSR succeeds.
8855   BackEdgeTable::Revert(isolate, *caller_code);
8856
8857   // Check whether we ended up with usable optimized code.
8858   if (!result.is_null() && result->kind() == Code::OPTIMIZED_FUNCTION) {
8859     DeoptimizationInputData* data =
8860         DeoptimizationInputData::cast(result->deoptimization_data());
8861
8862     if (data->OsrPcOffset()->value() >= 0) {
8863       ASSERT(BailoutId(data->OsrAstId()->value()) == ast_id);
8864       if (FLAG_trace_osr) {
8865         PrintF("[OSR - Entry at AST id %d, offset %d in optimized code]\n",
8866                ast_id.ToInt(), data->OsrPcOffset()->value());
8867       }
8868       // TODO(titzer): this is a massive hack to make the deopt counts
8869       // match. Fix heuristics for reenabling optimizations!
8870       function->shared()->increment_deopt_count();
8871
8872       // TODO(titzer): Do not install code into the function.
8873       function->ReplaceCode(*result);
8874       return *result;
8875     }
8876   }
8877
8878   // Failed.
8879   if (FLAG_trace_osr) {
8880     PrintF("[OSR - Failed: ");
8881     function->PrintName();
8882     PrintF(" at AST id %d]\n", ast_id.ToInt());
8883   }
8884
8885   if (!function->IsOptimized()) {
8886     function->ReplaceCode(function->shared()->code());
8887   }
8888   return NULL;
8889 }
8890
8891
8892 RUNTIME_FUNCTION(Runtime_SetAllocationTimeout) {
8893   SealHandleScope shs(isolate);
8894   ASSERT(args.length() == 2 || args.length() == 3);
8895 #ifdef DEBUG
8896   CONVERT_SMI_ARG_CHECKED(interval, 0);
8897   CONVERT_SMI_ARG_CHECKED(timeout, 1);
8898   isolate->heap()->set_allocation_timeout(timeout);
8899   FLAG_gc_interval = interval;
8900   if (args.length() == 3) {
8901     // Enable/disable inline allocation if requested.
8902     CONVERT_BOOLEAN_ARG_CHECKED(inline_allocation, 2);
8903     if (inline_allocation) {
8904       isolate->heap()->EnableInlineAllocation();
8905     } else {
8906       isolate->heap()->DisableInlineAllocation();
8907     }
8908   }
8909 #endif
8910   return isolate->heap()->undefined_value();
8911 }
8912
8913
8914 RUNTIME_FUNCTION(Runtime_CheckIsBootstrapping) {
8915   SealHandleScope shs(isolate);
8916   ASSERT(args.length() == 0);
8917   RUNTIME_ASSERT(isolate->bootstrapper()->IsActive());
8918   return isolate->heap()->undefined_value();
8919 }
8920
8921
8922 RUNTIME_FUNCTION(Runtime_GetRootNaN) {
8923   SealHandleScope shs(isolate);
8924   ASSERT(args.length() == 0);
8925   RUNTIME_ASSERT(isolate->bootstrapper()->IsActive());
8926   return isolate->heap()->nan_value();
8927 }
8928
8929
8930 RUNTIME_FUNCTION(Runtime_Call) {
8931   HandleScope scope(isolate);
8932   ASSERT(args.length() >= 2);
8933   int argc = args.length() - 2;
8934   CONVERT_ARG_CHECKED(JSReceiver, fun, argc + 1);
8935   Object* receiver = args[0];
8936
8937   // If there are too many arguments, allocate argv via malloc.
8938   const int argv_small_size = 10;
8939   Handle<Object> argv_small_buffer[argv_small_size];
8940   SmartArrayPointer<Handle<Object> > argv_large_buffer;
8941   Handle<Object>* argv = argv_small_buffer;
8942   if (argc > argv_small_size) {
8943     argv = new Handle<Object>[argc];
8944     if (argv == NULL) return isolate->StackOverflow();
8945     argv_large_buffer = SmartArrayPointer<Handle<Object> >(argv);
8946   }
8947
8948   for (int i = 0; i < argc; ++i) {
8949      argv[i] = Handle<Object>(args[1 + i], isolate);
8950   }
8951
8952   Handle<JSReceiver> hfun(fun);
8953   Handle<Object> hreceiver(receiver, isolate);
8954   Handle<Object> result;
8955   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
8956       isolate, result,
8957       Execution::Call(isolate, hfun, hreceiver, argc, argv, true));
8958   return *result;
8959 }
8960
8961
8962 RUNTIME_FUNCTION(Runtime_Apply) {
8963   HandleScope scope(isolate);
8964   ASSERT(args.length() == 5);
8965   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, fun, 0);
8966   CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 1);
8967   CONVERT_ARG_HANDLE_CHECKED(JSObject, arguments, 2);
8968   CONVERT_SMI_ARG_CHECKED(offset, 3);
8969   CONVERT_SMI_ARG_CHECKED(argc, 4);
8970   RUNTIME_ASSERT(offset >= 0);
8971   // Loose upper bound to allow fuzzing. We'll most likely run out of
8972   // stack space before hitting this limit.
8973   static int kMaxArgc = 1000000;
8974   RUNTIME_ASSERT(argc >= 0 && argc <= kMaxArgc);
8975
8976   // If there are too many arguments, allocate argv via malloc.
8977   const int argv_small_size = 10;
8978   Handle<Object> argv_small_buffer[argv_small_size];
8979   SmartArrayPointer<Handle<Object> > argv_large_buffer;
8980   Handle<Object>* argv = argv_small_buffer;
8981   if (argc > argv_small_size) {
8982     argv = new Handle<Object>[argc];
8983     if (argv == NULL) return isolate->StackOverflow();
8984     argv_large_buffer = SmartArrayPointer<Handle<Object> >(argv);
8985   }
8986
8987   for (int i = 0; i < argc; ++i) {
8988     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
8989         isolate, argv[i],
8990         Object::GetElement(isolate, arguments, offset + i));
8991   }
8992
8993   Handle<Object> result;
8994   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
8995       isolate, result,
8996       Execution::Call(isolate, fun, receiver, argc, argv, true));
8997   return *result;
8998 }
8999
9000
9001 RUNTIME_FUNCTION(Runtime_GetFunctionDelegate) {
9002   HandleScope scope(isolate);
9003   ASSERT(args.length() == 1);
9004   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
9005   RUNTIME_ASSERT(!object->IsJSFunction());
9006   return *Execution::GetFunctionDelegate(isolate, object);
9007 }
9008
9009
9010 RUNTIME_FUNCTION(Runtime_GetConstructorDelegate) {
9011   HandleScope scope(isolate);
9012   ASSERT(args.length() == 1);
9013   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
9014   RUNTIME_ASSERT(!object->IsJSFunction());
9015   return *Execution::GetConstructorDelegate(isolate, object);
9016 }
9017
9018
9019 RUNTIME_FUNCTION(RuntimeHidden_NewGlobalContext) {
9020   HandleScope scope(isolate);
9021   ASSERT(args.length() == 2);
9022
9023   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
9024   CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 1);
9025   Handle<Context> result =
9026       isolate->factory()->NewGlobalContext(function, scope_info);
9027
9028   ASSERT(function->context() == isolate->context());
9029   ASSERT(function->context()->global_object() == result->global_object());
9030   result->global_object()->set_global_context(*result);
9031   return *result;
9032 }
9033
9034
9035 RUNTIME_FUNCTION(RuntimeHidden_NewFunctionContext) {
9036   HandleScope scope(isolate);
9037   ASSERT(args.length() == 1);
9038
9039   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
9040   int length = function->shared()->scope_info()->ContextLength();
9041   return *isolate->factory()->NewFunctionContext(length, function);
9042 }
9043
9044
9045 RUNTIME_FUNCTION(RuntimeHidden_PushWithContext) {
9046   HandleScope scope(isolate);
9047   ASSERT(args.length() == 2);
9048   Handle<JSReceiver> extension_object;
9049   if (args[0]->IsJSReceiver()) {
9050     extension_object = args.at<JSReceiver>(0);
9051   } else {
9052     // Try to convert the object to a proper JavaScript object.
9053     MaybeHandle<JSReceiver> maybe_object =
9054         Object::ToObject(isolate, args.at<Object>(0));
9055     if (!maybe_object.ToHandle(&extension_object)) {
9056       Handle<Object> handle = args.at<Object>(0);
9057       Handle<Object> result =
9058           isolate->factory()->NewTypeError("with_expression",
9059                                            HandleVector(&handle, 1));
9060       return isolate->Throw(*result);
9061     }
9062   }
9063
9064   Handle<JSFunction> function;
9065   if (args[1]->IsSmi()) {
9066     // A smi sentinel indicates a context nested inside global code rather
9067     // than some function.  There is a canonical empty function that can be
9068     // gotten from the native context.
9069     function = handle(isolate->context()->native_context()->closure());
9070   } else {
9071     function = args.at<JSFunction>(1);
9072   }
9073
9074   Handle<Context> current(isolate->context());
9075   Handle<Context> context = isolate->factory()->NewWithContext(
9076       function, current, extension_object);
9077   isolate->set_context(*context);
9078   return *context;
9079 }
9080
9081
9082 RUNTIME_FUNCTION(RuntimeHidden_PushCatchContext) {
9083   HandleScope scope(isolate);
9084   ASSERT(args.length() == 3);
9085   CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
9086   CONVERT_ARG_HANDLE_CHECKED(Object, thrown_object, 1);
9087   Handle<JSFunction> function;
9088   if (args[2]->IsSmi()) {
9089     // A smi sentinel indicates a context nested inside global code rather
9090     // than some function.  There is a canonical empty function that can be
9091     // gotten from the native context.
9092     function = handle(isolate->context()->native_context()->closure());
9093   } else {
9094     function = args.at<JSFunction>(2);
9095   }
9096   Handle<Context> current(isolate->context());
9097   Handle<Context> context = isolate->factory()->NewCatchContext(
9098       function, current, name, thrown_object);
9099   isolate->set_context(*context);
9100   return *context;
9101 }
9102
9103
9104 RUNTIME_FUNCTION(RuntimeHidden_PushBlockContext) {
9105   HandleScope scope(isolate);
9106   ASSERT(args.length() == 2);
9107   CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 0);
9108   Handle<JSFunction> function;
9109   if (args[1]->IsSmi()) {
9110     // A smi sentinel indicates a context nested inside global code rather
9111     // than some function.  There is a canonical empty function that can be
9112     // gotten from the native context.
9113     function = handle(isolate->context()->native_context()->closure());
9114   } else {
9115     function = args.at<JSFunction>(1);
9116   }
9117   Handle<Context> current(isolate->context());
9118   Handle<Context> context = isolate->factory()->NewBlockContext(
9119       function, current, scope_info);
9120   isolate->set_context(*context);
9121   return *context;
9122 }
9123
9124
9125 RUNTIME_FUNCTION(Runtime_IsJSModule) {
9126   SealHandleScope shs(isolate);
9127   ASSERT(args.length() == 1);
9128   CONVERT_ARG_CHECKED(Object, obj, 0);
9129   return isolate->heap()->ToBoolean(obj->IsJSModule());
9130 }
9131
9132
9133 RUNTIME_FUNCTION(RuntimeHidden_PushModuleContext) {
9134   SealHandleScope shs(isolate);
9135   ASSERT(args.length() == 2);
9136   CONVERT_SMI_ARG_CHECKED(index, 0);
9137
9138   if (!args[1]->IsScopeInfo()) {
9139     // Module already initialized. Find hosting context and retrieve context.
9140     Context* host = Context::cast(isolate->context())->global_context();
9141     Context* context = Context::cast(host->get(index));
9142     ASSERT(context->previous() == isolate->context());
9143     isolate->set_context(context);
9144     return context;
9145   }
9146
9147   CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 1);
9148
9149   // Allocate module context.
9150   HandleScope scope(isolate);
9151   Factory* factory = isolate->factory();
9152   Handle<Context> context = factory->NewModuleContext(scope_info);
9153   Handle<JSModule> module = factory->NewJSModule(context, scope_info);
9154   context->set_module(*module);
9155   Context* previous = isolate->context();
9156   context->set_previous(previous);
9157   context->set_closure(previous->closure());
9158   context->set_global_object(previous->global_object());
9159   isolate->set_context(*context);
9160
9161   // Find hosting scope and initialize internal variable holding module there.
9162   previous->global_context()->set(index, *context);
9163
9164   return *context;
9165 }
9166
9167
9168 RUNTIME_FUNCTION(RuntimeHidden_DeclareModules) {
9169   HandleScope scope(isolate);
9170   ASSERT(args.length() == 1);
9171   CONVERT_ARG_HANDLE_CHECKED(FixedArray, descriptions, 0);
9172   Context* host_context = isolate->context();
9173
9174   for (int i = 0; i < descriptions->length(); ++i) {
9175     Handle<ModuleInfo> description(ModuleInfo::cast(descriptions->get(i)));
9176     int host_index = description->host_index();
9177     Handle<Context> context(Context::cast(host_context->get(host_index)));
9178     Handle<JSModule> module(context->module());
9179
9180     for (int j = 0; j < description->length(); ++j) {
9181       Handle<String> name(description->name(j));
9182       VariableMode mode = description->mode(j);
9183       int index = description->index(j);
9184       switch (mode) {
9185         case VAR:
9186         case LET:
9187         case CONST:
9188         case CONST_LEGACY: {
9189           PropertyAttributes attr =
9190               IsImmutableVariableMode(mode) ? FROZEN : SEALED;
9191           Handle<AccessorInfo> info =
9192               Accessors::MakeModuleExport(name, index, attr);
9193           Handle<Object> result =
9194               JSObject::SetAccessor(module, info).ToHandleChecked();
9195           ASSERT(!result->IsUndefined());
9196           USE(result);
9197           break;
9198         }
9199         case MODULE: {
9200           Object* referenced_context = Context::cast(host_context)->get(index);
9201           Handle<JSModule> value(Context::cast(referenced_context)->module());
9202           JSReceiver::SetProperty(module, name, value, FROZEN, STRICT).Assert();
9203           break;
9204         }
9205         case INTERNAL:
9206         case TEMPORARY:
9207         case DYNAMIC:
9208         case DYNAMIC_GLOBAL:
9209         case DYNAMIC_LOCAL:
9210           UNREACHABLE();
9211       }
9212     }
9213
9214     JSObject::PreventExtensions(module).Assert();
9215   }
9216
9217   ASSERT(!isolate->has_pending_exception());
9218   return isolate->heap()->undefined_value();
9219 }
9220
9221
9222 RUNTIME_FUNCTION(RuntimeHidden_DeleteContextSlot) {
9223   HandleScope scope(isolate);
9224   ASSERT(args.length() == 2);
9225
9226   CONVERT_ARG_HANDLE_CHECKED(Context, context, 0);
9227   CONVERT_ARG_HANDLE_CHECKED(String, name, 1);
9228
9229   int index;
9230   PropertyAttributes attributes;
9231   ContextLookupFlags flags = FOLLOW_CHAINS;
9232   BindingFlags binding_flags;
9233   Handle<Object> holder = context->Lookup(name,
9234                                           flags,
9235                                           &index,
9236                                           &attributes,
9237                                           &binding_flags);
9238
9239   // If the slot was not found the result is true.
9240   if (holder.is_null()) {
9241     return isolate->heap()->true_value();
9242   }
9243
9244   // If the slot was found in a context, it should be DONT_DELETE.
9245   if (holder->IsContext()) {
9246     return isolate->heap()->false_value();
9247   }
9248
9249   // The slot was found in a JSObject, either a context extension object,
9250   // the global object, or the subject of a with.  Try to delete it
9251   // (respecting DONT_DELETE).
9252   Handle<JSObject> object = Handle<JSObject>::cast(holder);
9253   Handle<Object> result;
9254   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
9255       isolate, result,
9256       JSReceiver::DeleteProperty(object, name));
9257   return *result;
9258 }
9259
9260
9261 // A mechanism to return a pair of Object pointers in registers (if possible).
9262 // How this is achieved is calling convention-dependent.
9263 // All currently supported x86 compiles uses calling conventions that are cdecl
9264 // variants where a 64-bit value is returned in two 32-bit registers
9265 // (edx:eax on ia32, r1:r0 on ARM).
9266 // In AMD-64 calling convention a struct of two pointers is returned in rdx:rax.
9267 // In Win64 calling convention, a struct of two pointers is returned in memory,
9268 // allocated by the caller, and passed as a pointer in a hidden first parameter.
9269 #ifdef V8_HOST_ARCH_64_BIT
9270 struct ObjectPair {
9271   Object* x;
9272   Object* y;
9273 };
9274
9275
9276 static inline ObjectPair MakePair(Object* x, Object* y) {
9277   ObjectPair result = {x, y};
9278   // Pointers x and y returned in rax and rdx, in AMD-x64-abi.
9279   // In Win64 they are assigned to a hidden first argument.
9280   return result;
9281 }
9282 #else
9283 typedef uint64_t ObjectPair;
9284 static inline ObjectPair MakePair(Object* x, Object* y) {
9285 #if defined(V8_TARGET_LITTLE_ENDIAN)
9286   return reinterpret_cast<uint32_t>(x) |
9287       (reinterpret_cast<ObjectPair>(y) << 32);
9288 #elif defined(V8_TARGET_BIG_ENDIAN)
9289     return reinterpret_cast<uint32_t>(y) |
9290         (reinterpret_cast<ObjectPair>(x) << 32);
9291 #else
9292 #error Unknown endianness
9293 #endif
9294 }
9295 #endif
9296
9297
9298 static Object* ComputeReceiverForNonGlobal(Isolate* isolate,
9299                                            JSObject* holder) {
9300   ASSERT(!holder->IsGlobalObject());
9301   Context* top = isolate->context();
9302   // Get the context extension function.
9303   JSFunction* context_extension_function =
9304       top->native_context()->context_extension_function();
9305   // If the holder isn't a context extension object, we just return it
9306   // as the receiver. This allows arguments objects to be used as
9307   // receivers, but only if they are put in the context scope chain
9308   // explicitly via a with-statement.
9309   Object* constructor = holder->map()->constructor();
9310   if (constructor != context_extension_function) return holder;
9311   // Fall back to using the global object as the implicit receiver if
9312   // the property turns out to be a local variable allocated in a
9313   // context extension object - introduced via eval.
9314   return isolate->heap()->undefined_value();
9315 }
9316
9317
9318 static ObjectPair LoadContextSlotHelper(Arguments args,
9319                                         Isolate* isolate,
9320                                         bool throw_error) {
9321   HandleScope scope(isolate);
9322   ASSERT_EQ(2, args.length());
9323
9324   if (!args[0]->IsContext() || !args[1]->IsString()) {
9325     return MakePair(isolate->ThrowIllegalOperation(), NULL);
9326   }
9327   Handle<Context> context = args.at<Context>(0);
9328   Handle<String> name = args.at<String>(1);
9329
9330   int index;
9331   PropertyAttributes attributes;
9332   ContextLookupFlags flags = FOLLOW_CHAINS;
9333   BindingFlags binding_flags;
9334   Handle<Object> holder = context->Lookup(name,
9335                                           flags,
9336                                           &index,
9337                                           &attributes,
9338                                           &binding_flags);
9339   if (isolate->has_pending_exception()) {
9340     return MakePair(isolate->heap()->exception(), NULL);
9341   }
9342
9343   // If the index is non-negative, the slot has been found in a context.
9344   if (index >= 0) {
9345     ASSERT(holder->IsContext());
9346     // If the "property" we were looking for is a local variable, the
9347     // receiver is the global object; see ECMA-262, 3rd., 10.1.6 and 10.2.3.
9348     Handle<Object> receiver = isolate->factory()->undefined_value();
9349     Object* value = Context::cast(*holder)->get(index);
9350     // Check for uninitialized bindings.
9351     switch (binding_flags) {
9352       case MUTABLE_CHECK_INITIALIZED:
9353       case IMMUTABLE_CHECK_INITIALIZED_HARMONY:
9354         if (value->IsTheHole()) {
9355           Handle<Object> reference_error =
9356               isolate->factory()->NewReferenceError("not_defined",
9357                                                     HandleVector(&name, 1));
9358           return MakePair(isolate->Throw(*reference_error), NULL);
9359         }
9360         // FALLTHROUGH
9361       case MUTABLE_IS_INITIALIZED:
9362       case IMMUTABLE_IS_INITIALIZED:
9363       case IMMUTABLE_IS_INITIALIZED_HARMONY:
9364         ASSERT(!value->IsTheHole());
9365         return MakePair(value, *receiver);
9366       case IMMUTABLE_CHECK_INITIALIZED:
9367         if (value->IsTheHole()) {
9368           ASSERT((attributes & READ_ONLY) != 0);
9369           value = isolate->heap()->undefined_value();
9370         }
9371         return MakePair(value, *receiver);
9372       case MISSING_BINDING:
9373         UNREACHABLE();
9374         return MakePair(NULL, NULL);
9375     }
9376   }
9377
9378   // Otherwise, if the slot was found the holder is a context extension
9379   // object, subject of a with, or a global object.  We read the named
9380   // property from it.
9381   if (!holder.is_null()) {
9382     Handle<JSReceiver> object = Handle<JSReceiver>::cast(holder);
9383     ASSERT(object->IsJSProxy() || JSReceiver::HasProperty(object, name));
9384     // GetProperty below can cause GC.
9385     Handle<Object> receiver_handle(
9386         object->IsGlobalObject()
9387             ? Object::cast(isolate->heap()->undefined_value())
9388             : object->IsJSProxy() ? static_cast<Object*>(*object)
9389                 : ComputeReceiverForNonGlobal(isolate, JSObject::cast(*object)),
9390         isolate);
9391
9392     // No need to unhole the value here.  This is taken care of by the
9393     // GetProperty function.
9394     Handle<Object> value;
9395     ASSIGN_RETURN_ON_EXCEPTION_VALUE(
9396         isolate, value,
9397         Object::GetProperty(object, name),
9398         MakePair(isolate->heap()->exception(), NULL));
9399     return MakePair(*value, *receiver_handle);
9400   }
9401
9402   if (throw_error) {
9403     // The property doesn't exist - throw exception.
9404     Handle<Object> reference_error =
9405         isolate->factory()->NewReferenceError("not_defined",
9406                                               HandleVector(&name, 1));
9407     return MakePair(isolate->Throw(*reference_error), NULL);
9408   } else {
9409     // The property doesn't exist - return undefined.
9410     return MakePair(isolate->heap()->undefined_value(),
9411                     isolate->heap()->undefined_value());
9412   }
9413 }
9414
9415
9416 RUNTIME_FUNCTION_RETURN_PAIR(RuntimeHidden_LoadContextSlot) {
9417   return LoadContextSlotHelper(args, isolate, true);
9418 }
9419
9420
9421 RUNTIME_FUNCTION_RETURN_PAIR(RuntimeHidden_LoadContextSlotNoReferenceError) {
9422   return LoadContextSlotHelper(args, isolate, false);
9423 }
9424
9425
9426 RUNTIME_FUNCTION(RuntimeHidden_StoreContextSlot) {
9427   HandleScope scope(isolate);
9428   ASSERT(args.length() == 4);
9429
9430   CONVERT_ARG_HANDLE_CHECKED(Object, value, 0);
9431   CONVERT_ARG_HANDLE_CHECKED(Context, context, 1);
9432   CONVERT_ARG_HANDLE_CHECKED(String, name, 2);
9433   CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 3);
9434
9435   int index;
9436   PropertyAttributes attributes;
9437   ContextLookupFlags flags = FOLLOW_CHAINS;
9438   BindingFlags binding_flags;
9439   Handle<Object> holder = context->Lookup(name,
9440                                           flags,
9441                                           &index,
9442                                           &attributes,
9443                                           &binding_flags);
9444   if (isolate->has_pending_exception()) return isolate->heap()->exception();
9445
9446   if (index >= 0) {
9447     // The property was found in a context slot.
9448     Handle<Context> context = Handle<Context>::cast(holder);
9449     if (binding_flags == MUTABLE_CHECK_INITIALIZED &&
9450         context->get(index)->IsTheHole()) {
9451       Handle<Object> error =
9452           isolate->factory()->NewReferenceError("not_defined",
9453                                                 HandleVector(&name, 1));
9454       return isolate->Throw(*error);
9455     }
9456     // Ignore if read_only variable.
9457     if ((attributes & READ_ONLY) == 0) {
9458       // Context is a fixed array and set cannot fail.
9459       context->set(index, *value);
9460     } else if (strict_mode == STRICT) {
9461       // Setting read only property in strict mode.
9462       Handle<Object> error =
9463           isolate->factory()->NewTypeError("strict_cannot_assign",
9464                                            HandleVector(&name, 1));
9465       return isolate->Throw(*error);
9466     }
9467     return *value;
9468   }
9469
9470   // Slow case: The property is not in a context slot.  It is either in a
9471   // context extension object, a property of the subject of a with, or a
9472   // property of the global object.
9473   Handle<JSReceiver> object;
9474
9475   if (!holder.is_null()) {
9476     // The property exists on the holder.
9477     object = Handle<JSReceiver>::cast(holder);
9478   } else {
9479     // The property was not found.
9480     ASSERT(attributes == ABSENT);
9481
9482     if (strict_mode == STRICT) {
9483       // Throw in strict mode (assignment to undefined variable).
9484       Handle<Object> error =
9485           isolate->factory()->NewReferenceError(
9486               "not_defined", HandleVector(&name, 1));
9487       return isolate->Throw(*error);
9488     }
9489     // In sloppy mode, the property is added to the global object.
9490     attributes = NONE;
9491     object = Handle<JSReceiver>(isolate->context()->global_object());
9492   }
9493
9494   // Set the property if it's not read only or doesn't yet exist.
9495   if ((attributes & READ_ONLY) == 0 ||
9496       (JSReceiver::GetOwnPropertyAttributes(object, name) == ABSENT)) {
9497     RETURN_FAILURE_ON_EXCEPTION(
9498         isolate,
9499         JSReceiver::SetProperty(object, name, value, NONE, strict_mode));
9500   } else if (strict_mode == STRICT && (attributes & READ_ONLY) != 0) {
9501     // Setting read only property in strict mode.
9502     Handle<Object> error =
9503       isolate->factory()->NewTypeError(
9504           "strict_cannot_assign", HandleVector(&name, 1));
9505     return isolate->Throw(*error);
9506   }
9507   return *value;
9508 }
9509
9510
9511 RUNTIME_FUNCTION(RuntimeHidden_Throw) {
9512   HandleScope scope(isolate);
9513   ASSERT(args.length() == 1);
9514
9515   return isolate->Throw(args[0]);
9516 }
9517
9518
9519 RUNTIME_FUNCTION(RuntimeHidden_ReThrow) {
9520   HandleScope scope(isolate);
9521   ASSERT(args.length() == 1);
9522
9523   return isolate->ReThrow(args[0]);
9524 }
9525
9526
9527 RUNTIME_FUNCTION(RuntimeHidden_PromoteScheduledException) {
9528   SealHandleScope shs(isolate);
9529   ASSERT(args.length() == 0);
9530   return isolate->PromoteScheduledException();
9531 }
9532
9533
9534 RUNTIME_FUNCTION(RuntimeHidden_ThrowReferenceError) {
9535   HandleScope scope(isolate);
9536   ASSERT(args.length() == 1);
9537   CONVERT_ARG_HANDLE_CHECKED(Object, name, 0);
9538   Handle<Object> reference_error =
9539     isolate->factory()->NewReferenceError("not_defined",
9540                                           HandleVector(&name, 1));
9541   return isolate->Throw(*reference_error);
9542 }
9543
9544
9545 RUNTIME_FUNCTION(RuntimeHidden_ThrowNotDateError) {
9546   HandleScope scope(isolate);
9547   ASSERT(args.length() == 0);
9548   return isolate->Throw(*isolate->factory()->NewTypeError(
9549       "not_date_object", HandleVector<Object>(NULL, 0)));
9550 }
9551
9552
9553 RUNTIME_FUNCTION(RuntimeHidden_StackGuard) {
9554   SealHandleScope shs(isolate);
9555   ASSERT(args.length() == 0);
9556
9557   // First check if this is a real stack overflow.
9558   StackLimitCheck check(isolate);
9559   if (check.JsHasOverflowed()) {
9560     return isolate->StackOverflow();
9561   }
9562
9563   return isolate->stack_guard()->HandleInterrupts();
9564 }
9565
9566
9567 RUNTIME_FUNCTION(RuntimeHidden_TryInstallOptimizedCode) {
9568   HandleScope scope(isolate);
9569   ASSERT(args.length() == 1);
9570   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
9571
9572   // First check if this is a real stack overflow.
9573   StackLimitCheck check(isolate);
9574   if (check.JsHasOverflowed()) {
9575     SealHandleScope shs(isolate);
9576     return isolate->StackOverflow();
9577   }
9578
9579   isolate->optimizing_compiler_thread()->InstallOptimizedFunctions();
9580   return (function->IsOptimized()) ? function->code()
9581                                    : function->shared()->code();
9582 }
9583
9584
9585 RUNTIME_FUNCTION(RuntimeHidden_Interrupt) {
9586   SealHandleScope shs(isolate);
9587   ASSERT(args.length() == 0);
9588   return isolate->stack_guard()->HandleInterrupts();
9589 }
9590
9591
9592 static int StackSize(Isolate* isolate) {
9593   int n = 0;
9594   for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) n++;
9595   return n;
9596 }
9597
9598
9599 static void PrintTransition(Isolate* isolate, Object* result) {
9600   // indentation
9601   { const int nmax = 80;
9602     int n = StackSize(isolate);
9603     if (n <= nmax)
9604       PrintF("%4d:%*s", n, n, "");
9605     else
9606       PrintF("%4d:%*s", n, nmax, "...");
9607   }
9608
9609   if (result == NULL) {
9610     JavaScriptFrame::PrintTop(isolate, stdout, true, false);
9611     PrintF(" {\n");
9612   } else {
9613     // function result
9614     PrintF("} -> ");
9615     result->ShortPrint();
9616     PrintF("\n");
9617   }
9618 }
9619
9620
9621 RUNTIME_FUNCTION(Runtime_TraceEnter) {
9622   SealHandleScope shs(isolate);
9623   ASSERT(args.length() == 0);
9624   PrintTransition(isolate, NULL);
9625   return isolate->heap()->undefined_value();
9626 }
9627
9628
9629 RUNTIME_FUNCTION(Runtime_TraceExit) {
9630   SealHandleScope shs(isolate);
9631   ASSERT(args.length() == 1);
9632   CONVERT_ARG_CHECKED(Object, obj, 0);
9633   PrintTransition(isolate, obj);
9634   return obj;  // return TOS
9635 }
9636
9637
9638 RUNTIME_FUNCTION(Runtime_DebugPrint) {
9639   SealHandleScope shs(isolate);
9640   ASSERT(args.length() == 1);
9641
9642 #ifdef DEBUG
9643   if (args[0]->IsString()) {
9644     // If we have a string, assume it's a code "marker"
9645     // and print some interesting cpu debugging info.
9646     JavaScriptFrameIterator it(isolate);
9647     JavaScriptFrame* frame = it.frame();
9648     PrintF("fp = %p, sp = %p, caller_sp = %p: ",
9649            frame->fp(), frame->sp(), frame->caller_sp());
9650   } else {
9651     PrintF("DebugPrint: ");
9652   }
9653   args[0]->Print();
9654   if (args[0]->IsHeapObject()) {
9655     PrintF("\n");
9656     HeapObject::cast(args[0])->map()->Print();
9657   }
9658 #else
9659   // ShortPrint is available in release mode. Print is not.
9660   args[0]->ShortPrint();
9661 #endif
9662   PrintF("\n");
9663   Flush();
9664
9665   return args[0];  // return TOS
9666 }
9667
9668
9669 RUNTIME_FUNCTION(Runtime_DebugTrace) {
9670   SealHandleScope shs(isolate);
9671   ASSERT(args.length() == 0);
9672   isolate->PrintStack(stdout);
9673   return isolate->heap()->undefined_value();
9674 }
9675
9676
9677 RUNTIME_FUNCTION(Runtime_DateCurrentTime) {
9678   HandleScope scope(isolate);
9679   ASSERT(args.length() == 0);
9680   if (FLAG_log_timer_events) LOG(isolate, CurrentTimeEvent());
9681
9682   // According to ECMA-262, section 15.9.1, page 117, the precision of
9683   // the number in a Date object representing a particular instant in
9684   // time is milliseconds. Therefore, we floor the result of getting
9685   // the OS time.
9686   double millis = std::floor(OS::TimeCurrentMillis());
9687   return *isolate->factory()->NewNumber(millis);
9688 }
9689
9690
9691 RUNTIME_FUNCTION(Runtime_DateParseString) {
9692   HandleScope scope(isolate);
9693   ASSERT(args.length() == 2);
9694   CONVERT_ARG_HANDLE_CHECKED(String, str, 0);
9695   CONVERT_ARG_HANDLE_CHECKED(JSArray, output, 1);
9696
9697   RUNTIME_ASSERT(output->HasFastElements());
9698   JSObject::EnsureCanContainHeapObjectElements(output);
9699   RUNTIME_ASSERT(output->HasFastObjectElements());
9700   Handle<FixedArray> output_array(FixedArray::cast(output->elements()));
9701   RUNTIME_ASSERT(output_array->length() >= DateParser::OUTPUT_SIZE);
9702
9703   str = String::Flatten(str);
9704   DisallowHeapAllocation no_gc;
9705
9706   bool result;
9707   String::FlatContent str_content = str->GetFlatContent();
9708   if (str_content.IsAscii()) {
9709     result = DateParser::Parse(str_content.ToOneByteVector(),
9710                                *output_array,
9711                                isolate->unicode_cache());
9712   } else {
9713     ASSERT(str_content.IsTwoByte());
9714     result = DateParser::Parse(str_content.ToUC16Vector(),
9715                                *output_array,
9716                                isolate->unicode_cache());
9717   }
9718
9719   if (result) {
9720     return *output;
9721   } else {
9722     return isolate->heap()->null_value();
9723   }
9724 }
9725
9726
9727 RUNTIME_FUNCTION(Runtime_DateLocalTimezone) {
9728   HandleScope scope(isolate);
9729   ASSERT(args.length() == 1);
9730
9731   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
9732   RUNTIME_ASSERT(x >= -DateCache::kMaxTimeBeforeUTCInMs &&
9733                  x <= DateCache::kMaxTimeBeforeUTCInMs);
9734   const char* zone =
9735       isolate->date_cache()->LocalTimezone(static_cast<int64_t>(x));
9736   Handle<String> result = isolate->factory()->NewStringFromUtf8(
9737       CStrVector(zone)).ToHandleChecked();
9738   return *result;
9739 }
9740
9741
9742 RUNTIME_FUNCTION(Runtime_DateToUTC) {
9743   HandleScope scope(isolate);
9744   ASSERT(args.length() == 1);
9745
9746   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
9747   RUNTIME_ASSERT(x >= -DateCache::kMaxTimeBeforeUTCInMs &&
9748                  x <= DateCache::kMaxTimeBeforeUTCInMs);
9749   int64_t time = isolate->date_cache()->ToUTC(static_cast<int64_t>(x));
9750
9751   return *isolate->factory()->NewNumber(static_cast<double>(time));
9752 }
9753
9754
9755 RUNTIME_FUNCTION(Runtime_DateCacheVersion) {
9756   HandleScope hs(isolate);
9757   ASSERT(args.length() == 0);
9758   if (!isolate->eternal_handles()->Exists(EternalHandles::DATE_CACHE_VERSION)) {
9759     Handle<FixedArray> date_cache_version =
9760         isolate->factory()->NewFixedArray(1, TENURED);
9761     date_cache_version->set(0, Smi::FromInt(0));
9762     isolate->eternal_handles()->CreateSingleton(
9763         isolate, *date_cache_version, EternalHandles::DATE_CACHE_VERSION);
9764   }
9765   Handle<FixedArray> date_cache_version =
9766       Handle<FixedArray>::cast(isolate->eternal_handles()->GetSingleton(
9767           EternalHandles::DATE_CACHE_VERSION));
9768   // Return result as a JS array.
9769   Handle<JSObject> result =
9770       isolate->factory()->NewJSObject(isolate->array_function());
9771   JSArray::SetContent(Handle<JSArray>::cast(result), date_cache_version);
9772   return *result;
9773 }
9774
9775
9776 RUNTIME_FUNCTION(Runtime_GlobalReceiver) {
9777   SealHandleScope shs(isolate);
9778   ASSERT(args.length() == 1);
9779   CONVERT_ARG_CHECKED(Object, global, 0);
9780   if (!global->IsJSGlobalObject()) return isolate->heap()->null_value();
9781   return JSGlobalObject::cast(global)->global_receiver();
9782 }
9783
9784
9785 RUNTIME_FUNCTION(Runtime_IsAttachedGlobal) {
9786   SealHandleScope shs(isolate);
9787   ASSERT(args.length() == 1);
9788   CONVERT_ARG_CHECKED(Object, global, 0);
9789   if (!global->IsJSGlobalObject()) return isolate->heap()->false_value();
9790   return isolate->heap()->ToBoolean(
9791       !JSGlobalObject::cast(global)->IsDetached());
9792 }
9793
9794
9795 RUNTIME_FUNCTION(Runtime_ParseJson) {
9796   HandleScope scope(isolate);
9797   ASSERT(args.length() == 1);
9798   CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
9799
9800   source = String::Flatten(source);
9801   // Optimized fast case where we only have ASCII characters.
9802   Handle<Object> result;
9803   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
9804       isolate, result,
9805       source->IsSeqOneByteString() ? JsonParser<true>::Parse(source)
9806                                    : JsonParser<false>::Parse(source));
9807   return *result;
9808 }
9809
9810
9811 bool CodeGenerationFromStringsAllowed(Isolate* isolate,
9812                                       Handle<Context> context) {
9813   ASSERT(context->allow_code_gen_from_strings()->IsFalse());
9814   // Check with callback if set.
9815   AllowCodeGenerationFromStringsCallback callback =
9816       isolate->allow_code_gen_callback();
9817   if (callback == NULL) {
9818     // No callback set and code generation disallowed.
9819     return false;
9820   } else {
9821     // Callback set. Let it decide if code generation is allowed.
9822     VMState<EXTERNAL> state(isolate);
9823     return callback(v8::Utils::ToLocal(context));
9824   }
9825 }
9826
9827
9828 // Walk up the stack expecting:
9829 //  - Runtime_CompileString
9830 //  - JSFunction callee (eval, Function constructor, etc)
9831 //  - call() (maybe)
9832 //  - apply() (maybe)
9833 //  - bind() (maybe)
9834 // - JSFunction caller (maybe)
9835 //
9836 // return true if the caller has the same security token as the callee
9837 // or if an exit frame was hit, in which case allow it through, as it could
9838 // have come through the api.
9839 static bool TokensMatchForCompileString(Isolate* isolate) {
9840   MaybeHandle<JSFunction> callee;
9841   bool exit_handled = true;
9842   bool tokens_match = true;
9843   bool done = false;
9844   for (StackFrameIterator it(isolate); !it.done() && !done; it.Advance()) {
9845     StackFrame* raw_frame = it.frame();
9846     if (!raw_frame->is_java_script()) {
9847       if (raw_frame->is_exit()) exit_handled = false;
9848       continue;
9849     }
9850     JavaScriptFrame* outer_frame = JavaScriptFrame::cast(raw_frame);
9851     List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
9852     outer_frame->Summarize(&frames);
9853     for (int i = frames.length() - 1; i >= 0 && !done; --i) {
9854       FrameSummary& frame = frames[i];
9855       Handle<JSFunction> fun = frame.function();
9856       // Capture the callee function.
9857       if (callee.is_null()) {
9858         callee = fun;
9859         exit_handled = true;
9860         continue;
9861       }
9862       // Exit condition.
9863       Handle<Context> context(callee.ToHandleChecked()->context());
9864       if (!fun->context()->HasSameSecurityTokenAs(*context)) {
9865         tokens_match = false;
9866         done = true;
9867         continue;
9868       }
9869       // Skip bound functions in correct origin.
9870       if (fun->shared()->bound()) {
9871         exit_handled = true;
9872         continue;
9873       }
9874       done = true;
9875     }
9876   }
9877   return !exit_handled || tokens_match;
9878 }
9879
9880
9881 RUNTIME_FUNCTION(Runtime_CompileString) {
9882   HandleScope scope(isolate);
9883   ASSERT(args.length() == 2);
9884   CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
9885   CONVERT_BOOLEAN_ARG_CHECKED(function_literal_only, 1);
9886
9887   // Extract native context.
9888   Handle<Context> context(isolate->context()->native_context());
9889
9890   // Filter cross security context calls.
9891   if (!TokensMatchForCompileString(isolate)) {
9892     return isolate->heap()->undefined_value();
9893   }
9894
9895   // Check if native context allows code generation from
9896   // strings. Throw an exception if it doesn't.
9897   if (context->allow_code_gen_from_strings()->IsFalse() &&
9898       !CodeGenerationFromStringsAllowed(isolate, context)) {
9899     Handle<Object> error_message =
9900         context->ErrorMessageForCodeGenerationFromStrings();
9901     return isolate->Throw(*isolate->factory()->NewEvalError(
9902         "code_gen_from_strings", HandleVector<Object>(&error_message, 1)));
9903   }
9904
9905   // Compile source string in the native context.
9906   ParseRestriction restriction = function_literal_only
9907       ? ONLY_SINGLE_FUNCTION_LITERAL : NO_PARSE_RESTRICTION;
9908   Handle<JSFunction> fun;
9909   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
9910       isolate, fun,
9911       Compiler::GetFunctionFromEval(
9912           source, context, SLOPPY, restriction, RelocInfo::kNoPosition));
9913   return *fun;
9914 }
9915
9916
9917 static ObjectPair CompileGlobalEval(Isolate* isolate,
9918                                     Handle<String> source,
9919                                     Handle<Object> receiver,
9920                                     StrictMode strict_mode,
9921                                     int scope_position) {
9922   Handle<Context> context = Handle<Context>(isolate->context());
9923   Handle<Context> native_context = Handle<Context>(context->native_context());
9924
9925   // Check if native context allows code generation from
9926   // strings. Throw an exception if it doesn't.
9927   if (native_context->allow_code_gen_from_strings()->IsFalse() &&
9928       !CodeGenerationFromStringsAllowed(isolate, native_context)) {
9929     Handle<Object> error_message =
9930         native_context->ErrorMessageForCodeGenerationFromStrings();
9931     isolate->Throw(*isolate->factory()->NewEvalError(
9932         "code_gen_from_strings", HandleVector<Object>(&error_message, 1)));
9933     return MakePair(isolate->heap()->exception(), NULL);
9934   }
9935
9936   // Deal with a normal eval call with a string argument. Compile it
9937   // and return the compiled function bound in the local context.
9938   static const ParseRestriction restriction = NO_PARSE_RESTRICTION;
9939   Handle<JSFunction> compiled;
9940   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
9941       isolate, compiled,
9942       Compiler::GetFunctionFromEval(
9943           source, context, strict_mode, restriction, scope_position),
9944       MakePair(isolate->heap()->exception(), NULL));
9945   return MakePair(*compiled, *receiver);
9946 }
9947
9948
9949 RUNTIME_FUNCTION_RETURN_PAIR(RuntimeHidden_ResolvePossiblyDirectEval) {
9950   HandleScope scope(isolate);
9951   ASSERT(args.length() == 5);
9952
9953   Handle<Object> callee = args.at<Object>(0);
9954
9955   // If "eval" didn't refer to the original GlobalEval, it's not a
9956   // direct call to eval.
9957   // (And even if it is, but the first argument isn't a string, just let
9958   // execution default to an indirect call to eval, which will also return
9959   // the first argument without doing anything).
9960   if (*callee != isolate->native_context()->global_eval_fun() ||
9961       !args[1]->IsString()) {
9962     return MakePair(*callee, isolate->heap()->undefined_value());
9963   }
9964
9965   ASSERT(args[3]->IsSmi());
9966   ASSERT(args.smi_at(3) == SLOPPY || args.smi_at(3) == STRICT);
9967   StrictMode strict_mode = static_cast<StrictMode>(args.smi_at(3));
9968   ASSERT(args[4]->IsSmi());
9969   return CompileGlobalEval(isolate,
9970                            args.at<String>(1),
9971                            args.at<Object>(2),
9972                            strict_mode,
9973                            args.smi_at(4));
9974 }
9975
9976
9977 RUNTIME_FUNCTION(RuntimeHidden_AllocateInNewSpace) {
9978   HandleScope scope(isolate);
9979   ASSERT(args.length() == 1);
9980   CONVERT_SMI_ARG_CHECKED(size, 0);
9981   RUNTIME_ASSERT(IsAligned(size, kPointerSize));
9982   RUNTIME_ASSERT(size > 0);
9983   RUNTIME_ASSERT(size <= Page::kMaxRegularHeapObjectSize);
9984   return *isolate->factory()->NewFillerObject(size, false, NEW_SPACE);
9985 }
9986
9987
9988 RUNTIME_FUNCTION(RuntimeHidden_AllocateInTargetSpace) {
9989   HandleScope scope(isolate);
9990   ASSERT(args.length() == 2);
9991   CONVERT_SMI_ARG_CHECKED(size, 0);
9992   CONVERT_SMI_ARG_CHECKED(flags, 1);
9993   RUNTIME_ASSERT(IsAligned(size, kPointerSize));
9994   RUNTIME_ASSERT(size > 0);
9995   RUNTIME_ASSERT(size <= Page::kMaxRegularHeapObjectSize);
9996   bool double_align = AllocateDoubleAlignFlag::decode(flags);
9997   AllocationSpace space = AllocateTargetSpace::decode(flags);
9998   return *isolate->factory()->NewFillerObject(size, double_align, space);
9999 }
10000
10001
10002 // Push an object unto an array of objects if it is not already in the
10003 // array.  Returns true if the element was pushed on the stack and
10004 // false otherwise.
10005 RUNTIME_FUNCTION(Runtime_PushIfAbsent) {
10006   HandleScope scope(isolate);
10007   ASSERT(args.length() == 2);
10008   CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
10009   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, element, 1);
10010   RUNTIME_ASSERT(array->HasFastSmiOrObjectElements());
10011   int length = Smi::cast(array->length())->value();
10012   FixedArray* elements = FixedArray::cast(array->elements());
10013   for (int i = 0; i < length; i++) {
10014     if (elements->get(i) == *element) return isolate->heap()->false_value();
10015   }
10016
10017   // Strict not needed. Used for cycle detection in Array join implementation.
10018   RETURN_FAILURE_ON_EXCEPTION(
10019       isolate,
10020       JSObject::SetFastElement(array, length, element, SLOPPY, true));
10021   return isolate->heap()->true_value();
10022 }
10023
10024
10025 /**
10026  * A simple visitor visits every element of Array's.
10027  * The backend storage can be a fixed array for fast elements case,
10028  * or a dictionary for sparse array. Since Dictionary is a subtype
10029  * of FixedArray, the class can be used by both fast and slow cases.
10030  * The second parameter of the constructor, fast_elements, specifies
10031  * whether the storage is a FixedArray or Dictionary.
10032  *
10033  * An index limit is used to deal with the situation that a result array
10034  * length overflows 32-bit non-negative integer.
10035  */
10036 class ArrayConcatVisitor {
10037  public:
10038   ArrayConcatVisitor(Isolate* isolate,
10039                      Handle<FixedArray> storage,
10040                      bool fast_elements) :
10041       isolate_(isolate),
10042       storage_(Handle<FixedArray>::cast(
10043           isolate->global_handles()->Create(*storage))),
10044       index_offset_(0u),
10045       fast_elements_(fast_elements),
10046       exceeds_array_limit_(false) { }
10047
10048   ~ArrayConcatVisitor() {
10049     clear_storage();
10050   }
10051
10052   void visit(uint32_t i, Handle<Object> elm) {
10053     if (i > JSObject::kMaxElementCount - index_offset_) {
10054       exceeds_array_limit_ = true;
10055       return;
10056     }
10057     uint32_t index = index_offset_ + i;
10058
10059     if (fast_elements_) {
10060       if (index < static_cast<uint32_t>(storage_->length())) {
10061         storage_->set(index, *elm);
10062         return;
10063       }
10064       // Our initial estimate of length was foiled, possibly by
10065       // getters on the arrays increasing the length of later arrays
10066       // during iteration.
10067       // This shouldn't happen in anything but pathological cases.
10068       SetDictionaryMode();
10069       // Fall-through to dictionary mode.
10070     }
10071     ASSERT(!fast_elements_);
10072     Handle<SeededNumberDictionary> dict(
10073         SeededNumberDictionary::cast(*storage_));
10074     Handle<SeededNumberDictionary> result =
10075         SeededNumberDictionary::AtNumberPut(dict, index, elm);
10076     if (!result.is_identical_to(dict)) {
10077       // Dictionary needed to grow.
10078       clear_storage();
10079       set_storage(*result);
10080     }
10081   }
10082
10083   void increase_index_offset(uint32_t delta) {
10084     if (JSObject::kMaxElementCount - index_offset_ < delta) {
10085       index_offset_ = JSObject::kMaxElementCount;
10086     } else {
10087       index_offset_ += delta;
10088     }
10089     // If the initial length estimate was off (see special case in visit()),
10090     // but the array blowing the limit didn't contain elements beyond the
10091     // provided-for index range, go to dictionary mode now.
10092     if (fast_elements_ &&
10093         index_offset_ >= static_cast<uint32_t>(
10094             FixedArrayBase::cast(*storage_)->length())) {
10095       SetDictionaryMode();
10096     }
10097   }
10098
10099   bool exceeds_array_limit() {
10100     return exceeds_array_limit_;
10101   }
10102
10103   Handle<JSArray> ToArray() {
10104     Handle<JSArray> array = isolate_->factory()->NewJSArray(0);
10105     Handle<Object> length =
10106         isolate_->factory()->NewNumber(static_cast<double>(index_offset_));
10107     Handle<Map> map = JSObject::GetElementsTransitionMap(
10108         array,
10109         fast_elements_ ? FAST_HOLEY_ELEMENTS : DICTIONARY_ELEMENTS);
10110     array->set_map(*map);
10111     array->set_length(*length);
10112     array->set_elements(*storage_);
10113     return array;
10114   }
10115
10116  private:
10117   // Convert storage to dictionary mode.
10118   void SetDictionaryMode() {
10119     ASSERT(fast_elements_);
10120     Handle<FixedArray> current_storage(*storage_);
10121     Handle<SeededNumberDictionary> slow_storage(
10122         SeededNumberDictionary::New(isolate_, current_storage->length()));
10123     uint32_t current_length = static_cast<uint32_t>(current_storage->length());
10124     for (uint32_t i = 0; i < current_length; i++) {
10125       HandleScope loop_scope(isolate_);
10126       Handle<Object> element(current_storage->get(i), isolate_);
10127       if (!element->IsTheHole()) {
10128         Handle<SeededNumberDictionary> new_storage =
10129             SeededNumberDictionary::AtNumberPut(slow_storage, i, element);
10130         if (!new_storage.is_identical_to(slow_storage)) {
10131           slow_storage = loop_scope.CloseAndEscape(new_storage);
10132         }
10133       }
10134     }
10135     clear_storage();
10136     set_storage(*slow_storage);
10137     fast_elements_ = false;
10138   }
10139
10140   inline void clear_storage() {
10141     GlobalHandles::Destroy(Handle<Object>::cast(storage_).location());
10142   }
10143
10144   inline void set_storage(FixedArray* storage) {
10145     storage_ = Handle<FixedArray>::cast(
10146         isolate_->global_handles()->Create(storage));
10147   }
10148
10149   Isolate* isolate_;
10150   Handle<FixedArray> storage_;  // Always a global handle.
10151   // Index after last seen index. Always less than or equal to
10152   // JSObject::kMaxElementCount.
10153   uint32_t index_offset_;
10154   bool fast_elements_ : 1;
10155   bool exceeds_array_limit_ : 1;
10156 };
10157
10158
10159 static uint32_t EstimateElementCount(Handle<JSArray> array) {
10160   uint32_t length = static_cast<uint32_t>(array->length()->Number());
10161   int element_count = 0;
10162   switch (array->GetElementsKind()) {
10163     case FAST_SMI_ELEMENTS:
10164     case FAST_HOLEY_SMI_ELEMENTS:
10165     case FAST_ELEMENTS:
10166     case FAST_HOLEY_ELEMENTS: {
10167       // Fast elements can't have lengths that are not representable by
10168       // a 32-bit signed integer.
10169       ASSERT(static_cast<int32_t>(FixedArray::kMaxLength) >= 0);
10170       int fast_length = static_cast<int>(length);
10171       Handle<FixedArray> elements(FixedArray::cast(array->elements()));
10172       for (int i = 0; i < fast_length; i++) {
10173         if (!elements->get(i)->IsTheHole()) element_count++;
10174       }
10175       break;
10176     }
10177     case FAST_DOUBLE_ELEMENTS:
10178     case FAST_HOLEY_DOUBLE_ELEMENTS: {
10179       // Fast elements can't have lengths that are not representable by
10180       // a 32-bit signed integer.
10181       ASSERT(static_cast<int32_t>(FixedDoubleArray::kMaxLength) >= 0);
10182       int fast_length = static_cast<int>(length);
10183       if (array->elements()->IsFixedArray()) {
10184         ASSERT(FixedArray::cast(array->elements())->length() == 0);
10185         break;
10186       }
10187       Handle<FixedDoubleArray> elements(
10188           FixedDoubleArray::cast(array->elements()));
10189       for (int i = 0; i < fast_length; i++) {
10190         if (!elements->is_the_hole(i)) element_count++;
10191       }
10192       break;
10193     }
10194     case DICTIONARY_ELEMENTS: {
10195       Handle<SeededNumberDictionary> dictionary(
10196           SeededNumberDictionary::cast(array->elements()));
10197       int capacity = dictionary->Capacity();
10198       for (int i = 0; i < capacity; i++) {
10199         Handle<Object> key(dictionary->KeyAt(i), array->GetIsolate());
10200         if (dictionary->IsKey(*key)) {
10201           element_count++;
10202         }
10203       }
10204       break;
10205     }
10206     case SLOPPY_ARGUMENTS_ELEMENTS:
10207 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size)                      \
10208     case EXTERNAL_##TYPE##_ELEMENTS:                                         \
10209     case TYPE##_ELEMENTS:                                                    \
10210
10211     TYPED_ARRAYS(TYPED_ARRAY_CASE)
10212 #undef TYPED_ARRAY_CASE
10213       // External arrays are always dense.
10214       return length;
10215   }
10216   // As an estimate, we assume that the prototype doesn't contain any
10217   // inherited elements.
10218   return element_count;
10219 }
10220
10221
10222
10223 template<class ExternalArrayClass, class ElementType>
10224 static void IterateExternalArrayElements(Isolate* isolate,
10225                                          Handle<JSObject> receiver,
10226                                          bool elements_are_ints,
10227                                          bool elements_are_guaranteed_smis,
10228                                          ArrayConcatVisitor* visitor) {
10229   Handle<ExternalArrayClass> array(
10230       ExternalArrayClass::cast(receiver->elements()));
10231   uint32_t len = static_cast<uint32_t>(array->length());
10232
10233   ASSERT(visitor != NULL);
10234   if (elements_are_ints) {
10235     if (elements_are_guaranteed_smis) {
10236       for (uint32_t j = 0; j < len; j++) {
10237         HandleScope loop_scope(isolate);
10238         Handle<Smi> e(Smi::FromInt(static_cast<int>(array->get_scalar(j))),
10239                       isolate);
10240         visitor->visit(j, e);
10241       }
10242     } else {
10243       for (uint32_t j = 0; j < len; j++) {
10244         HandleScope loop_scope(isolate);
10245         int64_t val = static_cast<int64_t>(array->get_scalar(j));
10246         if (Smi::IsValid(static_cast<intptr_t>(val))) {
10247           Handle<Smi> e(Smi::FromInt(static_cast<int>(val)), isolate);
10248           visitor->visit(j, e);
10249         } else {
10250           Handle<Object> e =
10251               isolate->factory()->NewNumber(static_cast<ElementType>(val));
10252           visitor->visit(j, e);
10253         }
10254       }
10255     }
10256   } else {
10257     for (uint32_t j = 0; j < len; j++) {
10258       HandleScope loop_scope(isolate);
10259       Handle<Object> e = isolate->factory()->NewNumber(array->get_scalar(j));
10260       visitor->visit(j, e);
10261     }
10262   }
10263 }
10264
10265
10266 static void IterateExternalFloat32x4ArrayElements(Isolate* isolate,
10267                                                   Handle<JSObject> receiver,
10268                                                   ArrayConcatVisitor* visitor) {
10269   Handle<ExternalFloat32x4Array> array(
10270       ExternalFloat32x4Array::cast(receiver->elements()));
10271   uint32_t len = static_cast<uint32_t>(array->length());
10272
10273   ASSERT(visitor != NULL);
10274   for (uint32_t j = 0; j < len; j++) {
10275     HandleScope loop_scope(isolate);
10276     Handle<Object> e = isolate->factory()->NewFloat32x4(array->get_scalar(j));
10277     visitor->visit(j, e);
10278   }
10279 }
10280
10281
10282 static void IterateExternalFloat64x2ArrayElements(Isolate* isolate,
10283                                                   Handle<JSObject> receiver,
10284                                                   ArrayConcatVisitor* visitor) {
10285   Handle<ExternalFloat64x2Array> array(
10286       ExternalFloat64x2Array::cast(receiver->elements()));
10287   uint32_t len = static_cast<uint32_t>(array->length());
10288
10289   ASSERT(visitor != NULL);
10290   for (uint32_t j = 0; j < len; j++) {
10291     HandleScope loop_scope(isolate);
10292     Handle<Object> e = isolate->factory()->NewFloat64x2(array->get_scalar(j));
10293     visitor->visit(j, e);
10294   }
10295 }
10296
10297
10298 static void IterateExternalInt32x4ArrayElements(Isolate* isolate,
10299                                                  Handle<JSObject> receiver,
10300                                                  ArrayConcatVisitor* visitor) {
10301   Handle<ExternalInt32x4Array> array(
10302       ExternalInt32x4Array::cast(receiver->elements()));
10303   uint32_t len = static_cast<uint32_t>(array->length());
10304
10305   ASSERT(visitor != NULL);
10306   for (uint32_t j = 0; j < len; j++) {
10307     HandleScope loop_scope(isolate);
10308     Handle<Object> e = isolate->factory()->NewInt32x4(array->get_scalar(j));
10309     visitor->visit(j, e);
10310   }
10311 }
10312
10313
10314 // Used for sorting indices in a List<uint32_t>.
10315 static int compareUInt32(const uint32_t* ap, const uint32_t* bp) {
10316   uint32_t a = *ap;
10317   uint32_t b = *bp;
10318   return (a == b) ? 0 : (a < b) ? -1 : 1;
10319 }
10320
10321
10322 static void CollectElementIndices(Handle<JSObject> object,
10323                                   uint32_t range,
10324                                   List<uint32_t>* indices) {
10325   Isolate* isolate = object->GetIsolate();
10326   ElementsKind kind = object->GetElementsKind();
10327   switch (kind) {
10328     case FAST_SMI_ELEMENTS:
10329     case FAST_ELEMENTS:
10330     case FAST_HOLEY_SMI_ELEMENTS:
10331     case FAST_HOLEY_ELEMENTS: {
10332       Handle<FixedArray> elements(FixedArray::cast(object->elements()));
10333       uint32_t length = static_cast<uint32_t>(elements->length());
10334       if (range < length) length = range;
10335       for (uint32_t i = 0; i < length; i++) {
10336         if (!elements->get(i)->IsTheHole()) {
10337           indices->Add(i);
10338         }
10339       }
10340       break;
10341     }
10342     case FAST_HOLEY_DOUBLE_ELEMENTS:
10343     case FAST_DOUBLE_ELEMENTS: {
10344       // TODO(1810): Decide if it's worthwhile to implement this.
10345       UNREACHABLE();
10346       break;
10347     }
10348     case DICTIONARY_ELEMENTS: {
10349       Handle<SeededNumberDictionary> dict(
10350           SeededNumberDictionary::cast(object->elements()));
10351       uint32_t capacity = dict->Capacity();
10352       for (uint32_t j = 0; j < capacity; j++) {
10353         HandleScope loop_scope(isolate);
10354         Handle<Object> k(dict->KeyAt(j), isolate);
10355         if (dict->IsKey(*k)) {
10356           ASSERT(k->IsNumber());
10357           uint32_t index = static_cast<uint32_t>(k->Number());
10358           if (index < range) {
10359             indices->Add(index);
10360           }
10361         }
10362       }
10363       break;
10364     }
10365     default: {
10366       int dense_elements_length;
10367       switch (kind) {
10368 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size)                        \
10369         case EXTERNAL_##TYPE##_ELEMENTS: {                                     \
10370           dense_elements_length =                                              \
10371               External##Type##Array::cast(object->elements())->length();       \
10372           break;                                                               \
10373         }
10374
10375         TYPED_ARRAYS(TYPED_ARRAY_CASE)
10376 #undef TYPED_ARRAY_CASE
10377
10378         default:
10379           UNREACHABLE();
10380           dense_elements_length = 0;
10381           break;
10382       }
10383       uint32_t length = static_cast<uint32_t>(dense_elements_length);
10384       if (range <= length) {
10385         length = range;
10386         // We will add all indices, so we might as well clear it first
10387         // and avoid duplicates.
10388         indices->Clear();
10389       }
10390       for (uint32_t i = 0; i < length; i++) {
10391         indices->Add(i);
10392       }
10393       if (length == range) return;  // All indices accounted for already.
10394       break;
10395     }
10396   }
10397
10398   Handle<Object> prototype(object->GetPrototype(), isolate);
10399   if (prototype->IsJSObject()) {
10400     // The prototype will usually have no inherited element indices,
10401     // but we have to check.
10402     CollectElementIndices(Handle<JSObject>::cast(prototype), range, indices);
10403   }
10404 }
10405
10406
10407 /**
10408  * A helper function that visits elements of a JSArray in numerical
10409  * order.
10410  *
10411  * The visitor argument called for each existing element in the array
10412  * with the element index and the element's value.
10413  * Afterwards it increments the base-index of the visitor by the array
10414  * length.
10415  * Returns false if any access threw an exception, otherwise true.
10416  */
10417 static bool IterateElements(Isolate* isolate,
10418                             Handle<JSArray> receiver,
10419                             ArrayConcatVisitor* visitor) {
10420   uint32_t length = static_cast<uint32_t>(receiver->length()->Number());
10421   switch (receiver->GetElementsKind()) {
10422     case FAST_SMI_ELEMENTS:
10423     case FAST_ELEMENTS:
10424     case FAST_HOLEY_SMI_ELEMENTS:
10425     case FAST_HOLEY_ELEMENTS: {
10426       // Run through the elements FixedArray and use HasElement and GetElement
10427       // to check the prototype for missing elements.
10428       Handle<FixedArray> elements(FixedArray::cast(receiver->elements()));
10429       int fast_length = static_cast<int>(length);
10430       ASSERT(fast_length <= elements->length());
10431       for (int j = 0; j < fast_length; j++) {
10432         HandleScope loop_scope(isolate);
10433         Handle<Object> element_value(elements->get(j), isolate);
10434         if (!element_value->IsTheHole()) {
10435           visitor->visit(j, element_value);
10436         } else if (JSReceiver::HasElement(receiver, j)) {
10437           // Call GetElement on receiver, not its prototype, or getters won't
10438           // have the correct receiver.
10439           ASSIGN_RETURN_ON_EXCEPTION_VALUE(
10440               isolate, element_value,
10441               Object::GetElement(isolate, receiver, j),
10442               false);
10443           visitor->visit(j, element_value);
10444         }
10445       }
10446       break;
10447     }
10448     case FAST_HOLEY_DOUBLE_ELEMENTS:
10449     case FAST_DOUBLE_ELEMENTS: {
10450       // Empty array is FixedArray but not FixedDoubleArray.
10451       if (length == 0) break;
10452       // Run through the elements FixedArray and use HasElement and GetElement
10453       // to check the prototype for missing elements.
10454       if (receiver->elements()->IsFixedArray()) {
10455         ASSERT(receiver->elements()->length() == 0);
10456         break;
10457       }
10458       Handle<FixedDoubleArray> elements(
10459           FixedDoubleArray::cast(receiver->elements()));
10460       int fast_length = static_cast<int>(length);
10461       ASSERT(fast_length <= elements->length());
10462       for (int j = 0; j < fast_length; j++) {
10463         HandleScope loop_scope(isolate);
10464         if (!elements->is_the_hole(j)) {
10465           double double_value = elements->get_scalar(j);
10466           Handle<Object> element_value =
10467               isolate->factory()->NewNumber(double_value);
10468           visitor->visit(j, element_value);
10469         } else if (JSReceiver::HasElement(receiver, j)) {
10470           // Call GetElement on receiver, not its prototype, or getters won't
10471           // have the correct receiver.
10472           Handle<Object> element_value;
10473           ASSIGN_RETURN_ON_EXCEPTION_VALUE(
10474               isolate, element_value,
10475               Object::GetElement(isolate, receiver, j),
10476               false);
10477           visitor->visit(j, element_value);
10478         }
10479       }
10480       break;
10481     }
10482     case DICTIONARY_ELEMENTS: {
10483       Handle<SeededNumberDictionary> dict(receiver->element_dictionary());
10484       List<uint32_t> indices(dict->Capacity() / 2);
10485       // Collect all indices in the object and the prototypes less
10486       // than length. This might introduce duplicates in the indices list.
10487       CollectElementIndices(receiver, length, &indices);
10488       indices.Sort(&compareUInt32);
10489       int j = 0;
10490       int n = indices.length();
10491       while (j < n) {
10492         HandleScope loop_scope(isolate);
10493         uint32_t index = indices[j];
10494         Handle<Object> element;
10495         ASSIGN_RETURN_ON_EXCEPTION_VALUE(
10496             isolate, element,
10497             Object::GetElement(isolate, receiver, index),
10498             false);
10499         visitor->visit(index, element);
10500         // Skip to next different index (i.e., omit duplicates).
10501         do {
10502           j++;
10503         } while (j < n && indices[j] == index);
10504       }
10505       break;
10506     }
10507     case EXTERNAL_UINT8_CLAMPED_ELEMENTS: {
10508       Handle<ExternalUint8ClampedArray> pixels(ExternalUint8ClampedArray::cast(
10509           receiver->elements()));
10510       for (uint32_t j = 0; j < length; j++) {
10511         Handle<Smi> e(Smi::FromInt(pixels->get_scalar(j)), isolate);
10512         visitor->visit(j, e);
10513       }
10514       break;
10515     }
10516     case EXTERNAL_INT8_ELEMENTS: {
10517       IterateExternalArrayElements<ExternalInt8Array, int8_t>(
10518           isolate, receiver, true, true, visitor);
10519       break;
10520     }
10521     case EXTERNAL_UINT8_ELEMENTS: {
10522       IterateExternalArrayElements<ExternalUint8Array, uint8_t>(
10523           isolate, receiver, true, true, visitor);
10524       break;
10525     }
10526     case EXTERNAL_INT16_ELEMENTS: {
10527       IterateExternalArrayElements<ExternalInt16Array, int16_t>(
10528           isolate, receiver, true, true, visitor);
10529       break;
10530     }
10531     case EXTERNAL_UINT16_ELEMENTS: {
10532       IterateExternalArrayElements<ExternalUint16Array, uint16_t>(
10533           isolate, receiver, true, true, visitor);
10534       break;
10535     }
10536     case EXTERNAL_INT32_ELEMENTS: {
10537       IterateExternalArrayElements<ExternalInt32Array, int32_t>(
10538           isolate, receiver, true, false, visitor);
10539       break;
10540     }
10541     case EXTERNAL_UINT32_ELEMENTS: {
10542       IterateExternalArrayElements<ExternalUint32Array, uint32_t>(
10543           isolate, receiver, true, false, visitor);
10544       break;
10545     }
10546     case EXTERNAL_FLOAT32_ELEMENTS: {
10547       IterateExternalArrayElements<ExternalFloat32Array, float>(
10548           isolate, receiver, false, false, visitor);
10549       break;
10550     }
10551     case EXTERNAL_FLOAT32x4_ELEMENTS: {
10552       IterateExternalFloat32x4ArrayElements(isolate, receiver, visitor);
10553       break;
10554     }
10555     case EXTERNAL_FLOAT64x2_ELEMENTS: {
10556       IterateExternalFloat64x2ArrayElements(isolate, receiver, visitor);
10557       break;
10558     }
10559     case EXTERNAL_INT32x4_ELEMENTS: {
10560       IterateExternalInt32x4ArrayElements(isolate, receiver, visitor);
10561       break;
10562     }
10563     case EXTERNAL_FLOAT64_ELEMENTS: {
10564       IterateExternalArrayElements<ExternalFloat64Array, double>(
10565           isolate, receiver, false, false, visitor);
10566       break;
10567     }
10568     default:
10569       UNREACHABLE();
10570       break;
10571   }
10572   visitor->increase_index_offset(length);
10573   return true;
10574 }
10575
10576
10577 /**
10578  * Array::concat implementation.
10579  * See ECMAScript 262, 15.4.4.4.
10580  * TODO(581): Fix non-compliance for very large concatenations and update to
10581  * following the ECMAScript 5 specification.
10582  */
10583 RUNTIME_FUNCTION(Runtime_ArrayConcat) {
10584   HandleScope handle_scope(isolate);
10585   ASSERT(args.length() == 1);
10586
10587   CONVERT_ARG_HANDLE_CHECKED(JSArray, arguments, 0);
10588   int argument_count = static_cast<int>(arguments->length()->Number());
10589   RUNTIME_ASSERT(arguments->HasFastObjectElements());
10590   Handle<FixedArray> elements(FixedArray::cast(arguments->elements()));
10591
10592   // Pass 1: estimate the length and number of elements of the result.
10593   // The actual length can be larger if any of the arguments have getters
10594   // that mutate other arguments (but will otherwise be precise).
10595   // The number of elements is precise if there are no inherited elements.
10596
10597   ElementsKind kind = FAST_SMI_ELEMENTS;
10598
10599   uint32_t estimate_result_length = 0;
10600   uint32_t estimate_nof_elements = 0;
10601   for (int i = 0; i < argument_count; i++) {
10602     HandleScope loop_scope(isolate);
10603     Handle<Object> obj(elements->get(i), isolate);
10604     uint32_t length_estimate;
10605     uint32_t element_estimate;
10606     if (obj->IsJSArray()) {
10607       Handle<JSArray> array(Handle<JSArray>::cast(obj));
10608       length_estimate = static_cast<uint32_t>(array->length()->Number());
10609       if (length_estimate != 0) {
10610         ElementsKind array_kind =
10611             GetPackedElementsKind(array->map()->elements_kind());
10612         if (IsMoreGeneralElementsKindTransition(kind, array_kind)) {
10613           kind = array_kind;
10614         }
10615       }
10616       element_estimate = EstimateElementCount(array);
10617     } else {
10618       if (obj->IsHeapObject()) {
10619         if (obj->IsNumber()) {
10620           if (IsMoreGeneralElementsKindTransition(kind, FAST_DOUBLE_ELEMENTS)) {
10621             kind = FAST_DOUBLE_ELEMENTS;
10622           }
10623         } else if (IsMoreGeneralElementsKindTransition(kind, FAST_ELEMENTS)) {
10624           kind = FAST_ELEMENTS;
10625         }
10626       }
10627       length_estimate = 1;
10628       element_estimate = 1;
10629     }
10630     // Avoid overflows by capping at kMaxElementCount.
10631     if (JSObject::kMaxElementCount - estimate_result_length <
10632         length_estimate) {
10633       estimate_result_length = JSObject::kMaxElementCount;
10634     } else {
10635       estimate_result_length += length_estimate;
10636     }
10637     if (JSObject::kMaxElementCount - estimate_nof_elements <
10638         element_estimate) {
10639       estimate_nof_elements = JSObject::kMaxElementCount;
10640     } else {
10641       estimate_nof_elements += element_estimate;
10642     }
10643   }
10644
10645   // If estimated number of elements is more than half of length, a
10646   // fixed array (fast case) is more time and space-efficient than a
10647   // dictionary.
10648   bool fast_case = (estimate_nof_elements * 2) >= estimate_result_length;
10649
10650   if (fast_case && kind == FAST_DOUBLE_ELEMENTS) {
10651     Handle<FixedArrayBase> storage =
10652         isolate->factory()->NewFixedDoubleArray(estimate_result_length);
10653     int j = 0;
10654     if (estimate_result_length > 0) {
10655       Handle<FixedDoubleArray> double_storage =
10656           Handle<FixedDoubleArray>::cast(storage);
10657       bool failure = false;
10658       for (int i = 0; i < argument_count; i++) {
10659         Handle<Object> obj(elements->get(i), isolate);
10660         if (obj->IsSmi()) {
10661           double_storage->set(j, Smi::cast(*obj)->value());
10662           j++;
10663         } else if (obj->IsNumber()) {
10664           double_storage->set(j, obj->Number());
10665           j++;
10666         } else {
10667           JSArray* array = JSArray::cast(*obj);
10668           uint32_t length = static_cast<uint32_t>(array->length()->Number());
10669           switch (array->map()->elements_kind()) {
10670             case FAST_HOLEY_DOUBLE_ELEMENTS:
10671             case FAST_DOUBLE_ELEMENTS: {
10672               // Empty array is FixedArray but not FixedDoubleArray.
10673               if (length == 0) break;
10674               FixedDoubleArray* elements =
10675                   FixedDoubleArray::cast(array->elements());
10676               for (uint32_t i = 0; i < length; i++) {
10677                 if (elements->is_the_hole(i)) {
10678                   failure = true;
10679                   break;
10680                 }
10681                 double double_value = elements->get_scalar(i);
10682                 double_storage->set(j, double_value);
10683                 j++;
10684               }
10685               break;
10686             }
10687             case FAST_HOLEY_SMI_ELEMENTS:
10688             case FAST_SMI_ELEMENTS: {
10689               FixedArray* elements(
10690                   FixedArray::cast(array->elements()));
10691               for (uint32_t i = 0; i < length; i++) {
10692                 Object* element = elements->get(i);
10693                 if (element->IsTheHole()) {
10694                   failure = true;
10695                   break;
10696                 }
10697                 int32_t int_value = Smi::cast(element)->value();
10698                 double_storage->set(j, int_value);
10699                 j++;
10700               }
10701               break;
10702             }
10703             case FAST_HOLEY_ELEMENTS:
10704               ASSERT_EQ(0, length);
10705               break;
10706             default:
10707               UNREACHABLE();
10708           }
10709         }
10710         if (failure) break;
10711       }
10712     }
10713     Handle<JSArray> array = isolate->factory()->NewJSArray(0);
10714     Smi* length = Smi::FromInt(j);
10715     Handle<Map> map;
10716     map = JSObject::GetElementsTransitionMap(array, kind);
10717     array->set_map(*map);
10718     array->set_length(length);
10719     array->set_elements(*storage);
10720     return *array;
10721   }
10722
10723   Handle<FixedArray> storage;
10724   if (fast_case) {
10725     // The backing storage array must have non-existing elements to preserve
10726     // holes across concat operations.
10727     storage = isolate->factory()->NewFixedArrayWithHoles(
10728         estimate_result_length);
10729   } else {
10730     // TODO(126): move 25% pre-allocation logic into Dictionary::Allocate
10731     uint32_t at_least_space_for = estimate_nof_elements +
10732                                   (estimate_nof_elements >> 2);
10733     storage = Handle<FixedArray>::cast(
10734         SeededNumberDictionary::New(isolate, at_least_space_for));
10735   }
10736
10737   ArrayConcatVisitor visitor(isolate, storage, fast_case);
10738
10739   for (int i = 0; i < argument_count; i++) {
10740     Handle<Object> obj(elements->get(i), isolate);
10741     if (obj->IsJSArray()) {
10742       Handle<JSArray> array = Handle<JSArray>::cast(obj);
10743       if (!IterateElements(isolate, array, &visitor)) {
10744         return isolate->heap()->exception();
10745       }
10746     } else {
10747       visitor.visit(0, obj);
10748       visitor.increase_index_offset(1);
10749     }
10750   }
10751
10752   if (visitor.exceeds_array_limit()) {
10753     return isolate->Throw(
10754         *isolate->factory()->NewRangeError("invalid_array_length",
10755                                            HandleVector<Object>(NULL, 0)));
10756   }
10757   return *visitor.ToArray();
10758 }
10759
10760
10761 // This will not allocate (flatten the string), but it may run
10762 // very slowly for very deeply nested ConsStrings.  For debugging use only.
10763 RUNTIME_FUNCTION(Runtime_GlobalPrint) {
10764   SealHandleScope shs(isolate);
10765   ASSERT(args.length() == 1);
10766
10767   CONVERT_ARG_CHECKED(String, string, 0);
10768   ConsStringIteratorOp op;
10769   StringCharacterStream stream(string, &op);
10770   while (stream.HasMore()) {
10771     uint16_t character = stream.GetNext();
10772     PrintF("%c", character);
10773   }
10774   return string;
10775 }
10776
10777
10778 // Moves all own elements of an object, that are below a limit, to positions
10779 // starting at zero. All undefined values are placed after non-undefined values,
10780 // and are followed by non-existing element. Does not change the length
10781 // property.
10782 // Returns the number of non-undefined elements collected.
10783 // Returns -1 if hole removal is not supported by this method.
10784 RUNTIME_FUNCTION(Runtime_RemoveArrayHoles) {
10785   HandleScope scope(isolate);
10786   ASSERT(args.length() == 2);
10787   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
10788   CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]);
10789   return *JSObject::PrepareElementsForSort(object, limit);
10790 }
10791
10792
10793 // Move contents of argument 0 (an array) to argument 1 (an array)
10794 RUNTIME_FUNCTION(Runtime_MoveArrayContents) {
10795   HandleScope scope(isolate);
10796   ASSERT(args.length() == 2);
10797   CONVERT_ARG_HANDLE_CHECKED(JSArray, from, 0);
10798   CONVERT_ARG_HANDLE_CHECKED(JSArray, to, 1);
10799   JSObject::ValidateElements(from);
10800   JSObject::ValidateElements(to);
10801
10802   Handle<FixedArrayBase> new_elements(from->elements());
10803   ElementsKind from_kind = from->GetElementsKind();
10804   Handle<Map> new_map = JSObject::GetElementsTransitionMap(to, from_kind);
10805   JSObject::SetMapAndElements(to, new_map, new_elements);
10806   to->set_length(from->length());
10807
10808   JSObject::ResetElements(from);
10809   from->set_length(Smi::FromInt(0));
10810
10811   JSObject::ValidateElements(to);
10812   return *to;
10813 }
10814
10815
10816 // How many elements does this object/array have?
10817 RUNTIME_FUNCTION(Runtime_EstimateNumberOfElements) {
10818   SealHandleScope shs(isolate);
10819   ASSERT(args.length() == 1);
10820   CONVERT_ARG_CHECKED(JSArray, object, 0);
10821   HeapObject* elements = object->elements();
10822   if (elements->IsDictionary()) {
10823     int result = SeededNumberDictionary::cast(elements)->NumberOfElements();
10824     return Smi::FromInt(result);
10825   } else {
10826     return object->length();
10827   }
10828 }
10829
10830
10831 // Returns an array that tells you where in the [0, length) interval an array
10832 // might have elements.  Can either return an array of keys (positive integers
10833 // or undefined) or a number representing the positive length of an interval
10834 // starting at index 0.
10835 // Intervals can span over some keys that are not in the object.
10836 RUNTIME_FUNCTION(Runtime_GetArrayKeys) {
10837   HandleScope scope(isolate);
10838   ASSERT(args.length() == 2);
10839   CONVERT_ARG_HANDLE_CHECKED(JSObject, array, 0);
10840   CONVERT_NUMBER_CHECKED(uint32_t, length, Uint32, args[1]);
10841   if (array->elements()->IsDictionary()) {
10842     Handle<FixedArray> keys = isolate->factory()->empty_fixed_array();
10843     for (Handle<Object> p = array;
10844          !p->IsNull();
10845          p = Handle<Object>(p->GetPrototype(isolate), isolate)) {
10846       if (p->IsJSProxy() || JSObject::cast(*p)->HasIndexedInterceptor()) {
10847         // Bail out if we find a proxy or interceptor, likely not worth
10848         // collecting keys in that case.
10849         return *isolate->factory()->NewNumberFromUint(length);
10850       }
10851       Handle<JSObject> current = Handle<JSObject>::cast(p);
10852       Handle<FixedArray> current_keys =
10853           isolate->factory()->NewFixedArray(current->NumberOfOwnElements(NONE));
10854       current->GetOwnElementKeys(*current_keys, NONE);
10855       ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
10856           isolate, keys, FixedArray::UnionOfKeys(keys, current_keys));
10857     }
10858     // Erase any keys >= length.
10859     // TODO(adamk): Remove this step when the contract of %GetArrayKeys
10860     // is changed to let this happen on the JS side.
10861     for (int i = 0; i < keys->length(); i++) {
10862       if (NumberToUint32(keys->get(i)) >= length) keys->set_undefined(i);
10863     }
10864     return *isolate->factory()->NewJSArrayWithElements(keys);
10865   } else {
10866     RUNTIME_ASSERT(array->HasFastSmiOrObjectElements() ||
10867                    array->HasFastDoubleElements());
10868     uint32_t actual_length = static_cast<uint32_t>(array->elements()->length());
10869     return *isolate->factory()->NewNumberFromUint(Min(actual_length, length));
10870   }
10871 }
10872
10873
10874 RUNTIME_FUNCTION(Runtime_LookupAccessor) {
10875   HandleScope scope(isolate);
10876   ASSERT(args.length() == 3);
10877   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
10878   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
10879   CONVERT_SMI_ARG_CHECKED(flag, 2);
10880   AccessorComponent component = flag == 0 ? ACCESSOR_GETTER : ACCESSOR_SETTER;
10881   if (!receiver->IsJSObject()) return isolate->heap()->undefined_value();
10882   Handle<Object> result;
10883   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
10884       isolate, result,
10885       JSObject::GetAccessor(Handle<JSObject>::cast(receiver), name, component));
10886   return *result;
10887 }
10888
10889
10890 RUNTIME_FUNCTION(Runtime_DebugBreak) {
10891   SealHandleScope shs(isolate);
10892   ASSERT(args.length() == 0);
10893   isolate->debug()->HandleDebugBreak();
10894   return isolate->heap()->undefined_value();
10895 }
10896
10897
10898 // Helper functions for wrapping and unwrapping stack frame ids.
10899 static Smi* WrapFrameId(StackFrame::Id id) {
10900   ASSERT(IsAligned(OffsetFrom(id), static_cast<intptr_t>(4)));
10901   return Smi::FromInt(id >> 2);
10902 }
10903
10904
10905 static StackFrame::Id UnwrapFrameId(int wrapped) {
10906   return static_cast<StackFrame::Id>(wrapped << 2);
10907 }
10908
10909
10910 // Adds a JavaScript function as a debug event listener.
10911 // args[0]: debug event listener function to set or null or undefined for
10912 //          clearing the event listener function
10913 // args[1]: object supplied during callback
10914 RUNTIME_FUNCTION(Runtime_SetDebugEventListener) {
10915   SealHandleScope shs(isolate);
10916   ASSERT(args.length() == 2);
10917   RUNTIME_ASSERT(args[0]->IsJSFunction() ||
10918                  args[0]->IsUndefined() ||
10919                  args[0]->IsNull());
10920   CONVERT_ARG_HANDLE_CHECKED(Object, callback, 0);
10921   CONVERT_ARG_HANDLE_CHECKED(Object, data, 1);
10922   isolate->debug()->SetEventListener(callback, data);
10923
10924   return isolate->heap()->undefined_value();
10925 }
10926
10927
10928 RUNTIME_FUNCTION(Runtime_Break) {
10929   SealHandleScope shs(isolate);
10930   ASSERT(args.length() == 0);
10931   isolate->stack_guard()->RequestDebugBreak();
10932   return isolate->heap()->undefined_value();
10933 }
10934
10935
10936 static Handle<Object> DebugLookupResultValue(Isolate* isolate,
10937                                              Handle<Object> receiver,
10938                                              Handle<Name> name,
10939                                              LookupResult* result,
10940                                              bool* has_caught = NULL) {
10941   Handle<Object> value = isolate->factory()->undefined_value();
10942   if  (!result->IsFound()) return value;
10943   switch (result->type()) {
10944     case NORMAL:
10945       value = JSObject::GetNormalizedProperty(
10946           handle(result->holder(), isolate), result);
10947       break;
10948     case FIELD:
10949       value = JSObject::FastPropertyAt(handle(result->holder(), isolate),
10950                                        result->representation(),
10951                                        result->GetFieldIndex());
10952       break;
10953     case CONSTANT:
10954       return handle(result->GetConstant(), isolate);
10955     case CALLBACKS: {
10956       Handle<Object> structure(result->GetCallbackObject(), isolate);
10957       ASSERT(!structure->IsForeign());
10958       if (structure->IsAccessorInfo()) {
10959         MaybeHandle<Object> obj = JSObject::GetPropertyWithAccessor(
10960             receiver, name, handle(result->holder(), isolate), structure);
10961         if (!obj.ToHandle(&value)) {
10962           value = handle(isolate->pending_exception(), isolate);
10963           isolate->clear_pending_exception();
10964           if (has_caught != NULL) *has_caught = true;
10965           return value;
10966         }
10967       }
10968       break;
10969     }
10970     case INTERCEPTOR:
10971     case HANDLER:
10972       break;
10973     case NONEXISTENT:
10974       UNREACHABLE();
10975       break;
10976   }
10977   ASSERT(!value->IsTheHole() || result->IsReadOnly());
10978   return value->IsTheHole()
10979       ? Handle<Object>::cast(isolate->factory()->undefined_value()) : value;
10980 }
10981
10982
10983 // Get debugger related details for an object property.
10984 // args[0]: object holding property
10985 // args[1]: name of the property
10986 //
10987 // The array returned contains the following information:
10988 // 0: Property value
10989 // 1: Property details
10990 // 2: Property value is exception
10991 // 3: Getter function if defined
10992 // 4: Setter function if defined
10993 // Items 2-4 are only filled if the property has either a getter or a setter
10994 // defined through __defineGetter__ and/or __defineSetter__.
10995 RUNTIME_FUNCTION(Runtime_DebugGetPropertyDetails) {
10996   HandleScope scope(isolate);
10997
10998   ASSERT(args.length() == 2);
10999
11000   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
11001   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
11002
11003   // Make sure to set the current context to the context before the debugger was
11004   // entered (if the debugger is entered). The reason for switching context here
11005   // is that for some property lookups (accessors and interceptors) callbacks
11006   // into the embedding application can occour, and the embedding application
11007   // could have the assumption that its own native context is the current
11008   // context and not some internal debugger context.
11009   SaveContext save(isolate);
11010   if (isolate->debug()->in_debug_scope()) {
11011     isolate->set_context(*isolate->debug()->debugger_entry()->GetContext());
11012   }
11013
11014   // Skip the global proxy as it has no properties and always delegates to the
11015   // real global object.
11016   if (obj->IsJSGlobalProxy()) {
11017     obj = Handle<JSObject>(JSObject::cast(obj->GetPrototype()));
11018   }
11019
11020
11021   // Check if the name is trivially convertible to an index and get the element
11022   // if so.
11023   uint32_t index;
11024   if (name->AsArrayIndex(&index)) {
11025     Handle<FixedArray> details = isolate->factory()->NewFixedArray(2);
11026     Handle<Object> element_or_char;
11027     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
11028         isolate, element_or_char,
11029         Runtime::GetElementOrCharAt(isolate, obj, index));
11030     details->set(0, *element_or_char);
11031     details->set(
11032         1, PropertyDetails(NONE, NORMAL, Representation::None()).AsSmi());
11033     return *isolate->factory()->NewJSArrayWithElements(details);
11034   }
11035
11036   // Find the number of objects making up this.
11037   int length = OwnPrototypeChainLength(*obj);
11038
11039   // Try own lookup on each of the objects.
11040   Handle<JSObject> jsproto = obj;
11041   for (int i = 0; i < length; i++) {
11042     LookupResult result(isolate);
11043     jsproto->LookupOwn(name, &result);
11044     if (result.IsFound()) {
11045       // LookupResult is not GC safe as it holds raw object pointers.
11046       // GC can happen later in this code so put the required fields into
11047       // local variables using handles when required for later use.
11048       Handle<Object> result_callback_obj;
11049       if (result.IsPropertyCallbacks()) {
11050         result_callback_obj = Handle<Object>(result.GetCallbackObject(),
11051                                              isolate);
11052       }
11053
11054
11055       bool has_caught = false;
11056       Handle<Object> value = DebugLookupResultValue(
11057           isolate, obj, name, &result, &has_caught);
11058
11059       // If the callback object is a fixed array then it contains JavaScript
11060       // getter and/or setter.
11061       bool has_js_accessors = result.IsPropertyCallbacks() &&
11062                               result_callback_obj->IsAccessorPair();
11063       Handle<FixedArray> details =
11064           isolate->factory()->NewFixedArray(has_js_accessors ? 5 : 2);
11065       details->set(0, *value);
11066       details->set(1, result.GetPropertyDetails().AsSmi());
11067       if (has_js_accessors) {
11068         AccessorPair* accessors = AccessorPair::cast(*result_callback_obj);
11069         details->set(2, isolate->heap()->ToBoolean(has_caught));
11070         details->set(3, accessors->GetComponent(ACCESSOR_GETTER));
11071         details->set(4, accessors->GetComponent(ACCESSOR_SETTER));
11072       }
11073
11074       return *isolate->factory()->NewJSArrayWithElements(details);
11075     }
11076     if (i < length - 1) {
11077       jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype()));
11078     }
11079   }
11080
11081   return isolate->heap()->undefined_value();
11082 }
11083
11084
11085 RUNTIME_FUNCTION(Runtime_DebugGetProperty) {
11086   HandleScope scope(isolate);
11087
11088   ASSERT(args.length() == 2);
11089
11090   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
11091   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
11092
11093   LookupResult result(isolate);
11094   obj->Lookup(name, &result);
11095   return *DebugLookupResultValue(isolate, obj, name, &result);
11096 }
11097
11098
11099 // Return the property type calculated from the property details.
11100 // args[0]: smi with property details.
11101 RUNTIME_FUNCTION(Runtime_DebugPropertyTypeFromDetails) {
11102   SealHandleScope shs(isolate);
11103   ASSERT(args.length() == 1);
11104   CONVERT_PROPERTY_DETAILS_CHECKED(details, 0);
11105   return Smi::FromInt(static_cast<int>(details.type()));
11106 }
11107
11108
11109 // Return the property attribute calculated from the property details.
11110 // args[0]: smi with property details.
11111 RUNTIME_FUNCTION(Runtime_DebugPropertyAttributesFromDetails) {
11112   SealHandleScope shs(isolate);
11113   ASSERT(args.length() == 1);
11114   CONVERT_PROPERTY_DETAILS_CHECKED(details, 0);
11115   return Smi::FromInt(static_cast<int>(details.attributes()));
11116 }
11117
11118
11119 // Return the property insertion index calculated from the property details.
11120 // args[0]: smi with property details.
11121 RUNTIME_FUNCTION(Runtime_DebugPropertyIndexFromDetails) {
11122   SealHandleScope shs(isolate);
11123   ASSERT(args.length() == 1);
11124   CONVERT_PROPERTY_DETAILS_CHECKED(details, 0);
11125   // TODO(verwaest): Depends on the type of details.
11126   return Smi::FromInt(details.dictionary_index());
11127 }
11128
11129
11130 // Return property value from named interceptor.
11131 // args[0]: object
11132 // args[1]: property name
11133 RUNTIME_FUNCTION(Runtime_DebugNamedInterceptorPropertyValue) {
11134   HandleScope scope(isolate);
11135   ASSERT(args.length() == 2);
11136   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
11137   RUNTIME_ASSERT(obj->HasNamedInterceptor());
11138   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
11139
11140   Handle<Object> result;
11141   LookupIterator it(obj, name, obj);
11142   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
11143       isolate, result, JSObject::GetProperty(&it));
11144   return *result;
11145 }
11146
11147
11148 // Return element value from indexed interceptor.
11149 // args[0]: object
11150 // args[1]: index
11151 RUNTIME_FUNCTION(Runtime_DebugIndexedInterceptorElementValue) {
11152   HandleScope scope(isolate);
11153   ASSERT(args.length() == 2);
11154   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
11155   RUNTIME_ASSERT(obj->HasIndexedInterceptor());
11156   CONVERT_NUMBER_CHECKED(uint32_t, index, Uint32, args[1]);
11157   Handle<Object> result;
11158   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
11159       isolate, result, JSObject::GetElementWithInterceptor(obj, obj, index));
11160   return *result;
11161 }
11162
11163
11164 static bool CheckExecutionState(Isolate* isolate, int break_id) {
11165   return !isolate->debug()->debug_context().is_null() &&
11166          isolate->debug()->break_id() != 0 &&
11167          isolate->debug()->break_id() == break_id;
11168 }
11169
11170
11171 RUNTIME_FUNCTION(Runtime_CheckExecutionState) {
11172   SealHandleScope shs(isolate);
11173   ASSERT(args.length() == 1);
11174   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
11175   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
11176   return isolate->heap()->true_value();
11177 }
11178
11179
11180 RUNTIME_FUNCTION(Runtime_GetFrameCount) {
11181   HandleScope scope(isolate);
11182   ASSERT(args.length() == 1);
11183   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
11184   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
11185
11186   // Count all frames which are relevant to debugging stack trace.
11187   int n = 0;
11188   StackFrame::Id id = isolate->debug()->break_frame_id();
11189   if (id == StackFrame::NO_ID) {
11190     // If there is no JavaScript stack frame count is 0.
11191     return Smi::FromInt(0);
11192   }
11193
11194   for (JavaScriptFrameIterator it(isolate, id); !it.done(); it.Advance()) {
11195     n += it.frame()->GetInlineCount();
11196   }
11197   return Smi::FromInt(n);
11198 }
11199
11200
11201 class FrameInspector {
11202  public:
11203   FrameInspector(JavaScriptFrame* frame,
11204                  int inlined_jsframe_index,
11205                  Isolate* isolate)
11206       : frame_(frame), deoptimized_frame_(NULL), isolate_(isolate) {
11207     // Calculate the deoptimized frame.
11208     if (frame->is_optimized()) {
11209       deoptimized_frame_ = Deoptimizer::DebuggerInspectableFrame(
11210           frame, inlined_jsframe_index, isolate);
11211     }
11212     has_adapted_arguments_ = frame_->has_adapted_arguments();
11213     is_bottommost_ = inlined_jsframe_index == 0;
11214     is_optimized_ = frame_->is_optimized();
11215   }
11216
11217   ~FrameInspector() {
11218     // Get rid of the calculated deoptimized frame if any.
11219     if (deoptimized_frame_ != NULL) {
11220       Deoptimizer::DeleteDebuggerInspectableFrame(deoptimized_frame_,
11221                                                   isolate_);
11222     }
11223   }
11224
11225   int GetParametersCount() {
11226     return is_optimized_
11227         ? deoptimized_frame_->parameters_count()
11228         : frame_->ComputeParametersCount();
11229   }
11230   int expression_count() { return deoptimized_frame_->expression_count(); }
11231   Object* GetFunction() {
11232     return is_optimized_
11233         ? deoptimized_frame_->GetFunction()
11234         : frame_->function();
11235   }
11236   Object* GetParameter(int index) {
11237     return is_optimized_
11238         ? deoptimized_frame_->GetParameter(index)
11239         : frame_->GetParameter(index);
11240   }
11241   Object* GetExpression(int index) {
11242     return is_optimized_
11243         ? deoptimized_frame_->GetExpression(index)
11244         : frame_->GetExpression(index);
11245   }
11246   int GetSourcePosition() {
11247     return is_optimized_
11248         ? deoptimized_frame_->GetSourcePosition()
11249         : frame_->LookupCode()->SourcePosition(frame_->pc());
11250   }
11251   bool IsConstructor() {
11252     return is_optimized_ && !is_bottommost_
11253         ? deoptimized_frame_->HasConstructStub()
11254         : frame_->IsConstructor();
11255   }
11256
11257   // To inspect all the provided arguments the frame might need to be
11258   // replaced with the arguments frame.
11259   void SetArgumentsFrame(JavaScriptFrame* frame) {
11260     ASSERT(has_adapted_arguments_);
11261     frame_ = frame;
11262     is_optimized_ = frame_->is_optimized();
11263     ASSERT(!is_optimized_);
11264   }
11265
11266  private:
11267   JavaScriptFrame* frame_;
11268   DeoptimizedFrameInfo* deoptimized_frame_;
11269   Isolate* isolate_;
11270   bool is_optimized_;
11271   bool is_bottommost_;
11272   bool has_adapted_arguments_;
11273
11274   DISALLOW_COPY_AND_ASSIGN(FrameInspector);
11275 };
11276
11277
11278 static const int kFrameDetailsFrameIdIndex = 0;
11279 static const int kFrameDetailsReceiverIndex = 1;
11280 static const int kFrameDetailsFunctionIndex = 2;
11281 static const int kFrameDetailsArgumentCountIndex = 3;
11282 static const int kFrameDetailsLocalCountIndex = 4;
11283 static const int kFrameDetailsSourcePositionIndex = 5;
11284 static const int kFrameDetailsConstructCallIndex = 6;
11285 static const int kFrameDetailsAtReturnIndex = 7;
11286 static const int kFrameDetailsFlagsIndex = 8;
11287 static const int kFrameDetailsFirstDynamicIndex = 9;
11288
11289
11290 static SaveContext* FindSavedContextForFrame(Isolate* isolate,
11291                                              JavaScriptFrame* frame) {
11292   SaveContext* save = isolate->save_context();
11293   while (save != NULL && !save->IsBelowFrame(frame)) {
11294     save = save->prev();
11295   }
11296   ASSERT(save != NULL);
11297   return save;
11298 }
11299
11300
11301 // Return an array with frame details
11302 // args[0]: number: break id
11303 // args[1]: number: frame index
11304 //
11305 // The array returned contains the following information:
11306 // 0: Frame id
11307 // 1: Receiver
11308 // 2: Function
11309 // 3: Argument count
11310 // 4: Local count
11311 // 5: Source position
11312 // 6: Constructor call
11313 // 7: Is at return
11314 // 8: Flags
11315 // Arguments name, value
11316 // Locals name, value
11317 // Return value if any
11318 RUNTIME_FUNCTION(Runtime_GetFrameDetails) {
11319   HandleScope scope(isolate);
11320   ASSERT(args.length() == 2);
11321   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
11322   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
11323
11324   CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
11325   Heap* heap = isolate->heap();
11326
11327   // Find the relevant frame with the requested index.
11328   StackFrame::Id id = isolate->debug()->break_frame_id();
11329   if (id == StackFrame::NO_ID) {
11330     // If there are no JavaScript stack frames return undefined.
11331     return heap->undefined_value();
11332   }
11333
11334   int count = 0;
11335   JavaScriptFrameIterator it(isolate, id);
11336   for (; !it.done(); it.Advance()) {
11337     if (index < count + it.frame()->GetInlineCount()) break;
11338     count += it.frame()->GetInlineCount();
11339   }
11340   if (it.done()) return heap->undefined_value();
11341
11342   bool is_optimized = it.frame()->is_optimized();
11343
11344   int inlined_jsframe_index = 0;  // Inlined frame index in optimized frame.
11345   if (is_optimized) {
11346     inlined_jsframe_index =
11347         it.frame()->GetInlineCount() - (index - count) - 1;
11348   }
11349   FrameInspector frame_inspector(it.frame(), inlined_jsframe_index, isolate);
11350
11351   // Traverse the saved contexts chain to find the active context for the
11352   // selected frame.
11353   SaveContext* save = FindSavedContextForFrame(isolate, it.frame());
11354
11355   // Get the frame id.
11356   Handle<Object> frame_id(WrapFrameId(it.frame()->id()), isolate);
11357
11358   // Find source position in unoptimized code.
11359   int position = frame_inspector.GetSourcePosition();
11360
11361   // Check for constructor frame.
11362   bool constructor = frame_inspector.IsConstructor();
11363
11364   // Get scope info and read from it for local variable information.
11365   Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction()));
11366   Handle<SharedFunctionInfo> shared(function->shared());
11367   Handle<ScopeInfo> scope_info(shared->scope_info());
11368   ASSERT(*scope_info != ScopeInfo::Empty(isolate));
11369
11370   // Get the locals names and values into a temporary array.
11371   int local_count = scope_info->LocalCount();
11372   for (int slot = 0; slot < scope_info->LocalCount(); ++slot) {
11373     // Hide compiler-introduced temporary variables, whether on the stack or on
11374     // the context.
11375     if (scope_info->LocalIsSynthetic(slot))
11376       local_count--;
11377   }
11378
11379   Handle<FixedArray> locals =
11380       isolate->factory()->NewFixedArray(local_count * 2);
11381
11382   // Fill in the values of the locals.
11383   int local = 0;
11384   int i = 0;
11385   for (; i < scope_info->StackLocalCount(); ++i) {
11386     // Use the value from the stack.
11387     if (scope_info->LocalIsSynthetic(i))
11388       continue;
11389     locals->set(local * 2, scope_info->LocalName(i));
11390     locals->set(local * 2 + 1, frame_inspector.GetExpression(i));
11391     local++;
11392   }
11393   if (local < local_count) {
11394     // Get the context containing declarations.
11395     Handle<Context> context(
11396         Context::cast(it.frame()->context())->declaration_context());
11397     for (; i < scope_info->LocalCount(); ++i) {
11398       if (scope_info->LocalIsSynthetic(i))
11399         continue;
11400       Handle<String> name(scope_info->LocalName(i));
11401       VariableMode mode;
11402       InitializationFlag init_flag;
11403       locals->set(local * 2, *name);
11404       int context_slot_index =
11405           ScopeInfo::ContextSlotIndex(scope_info, name, &mode, &init_flag);
11406       Object* value = context->get(context_slot_index);
11407       locals->set(local * 2 + 1, value);
11408       local++;
11409     }
11410   }
11411
11412   // Check whether this frame is positioned at return. If not top
11413   // frame or if the frame is optimized it cannot be at a return.
11414   bool at_return = false;
11415   if (!is_optimized && index == 0) {
11416     at_return = isolate->debug()->IsBreakAtReturn(it.frame());
11417   }
11418
11419   // If positioned just before return find the value to be returned and add it
11420   // to the frame information.
11421   Handle<Object> return_value = isolate->factory()->undefined_value();
11422   if (at_return) {
11423     StackFrameIterator it2(isolate);
11424     Address internal_frame_sp = NULL;
11425     while (!it2.done()) {
11426       if (it2.frame()->is_internal()) {
11427         internal_frame_sp = it2.frame()->sp();
11428       } else {
11429         if (it2.frame()->is_java_script()) {
11430           if (it2.frame()->id() == it.frame()->id()) {
11431             // The internal frame just before the JavaScript frame contains the
11432             // value to return on top. A debug break at return will create an
11433             // internal frame to store the return value (eax/rax/r0) before
11434             // entering the debug break exit frame.
11435             if (internal_frame_sp != NULL) {
11436               return_value =
11437                   Handle<Object>(Memory::Object_at(internal_frame_sp),
11438                                  isolate);
11439               break;
11440             }
11441           }
11442         }
11443
11444         // Indicate that the previous frame was not an internal frame.
11445         internal_frame_sp = NULL;
11446       }
11447       it2.Advance();
11448     }
11449   }
11450
11451   // Now advance to the arguments adapter frame (if any). It contains all
11452   // the provided parameters whereas the function frame always have the number
11453   // of arguments matching the functions parameters. The rest of the
11454   // information (except for what is collected above) is the same.
11455   if ((inlined_jsframe_index == 0) && it.frame()->has_adapted_arguments()) {
11456     it.AdvanceToArgumentsFrame();
11457     frame_inspector.SetArgumentsFrame(it.frame());
11458   }
11459
11460   // Find the number of arguments to fill. At least fill the number of
11461   // parameters for the function and fill more if more parameters are provided.
11462   int argument_count = scope_info->ParameterCount();
11463   if (argument_count < frame_inspector.GetParametersCount()) {
11464     argument_count = frame_inspector.GetParametersCount();
11465   }
11466
11467   // Calculate the size of the result.
11468   int details_size = kFrameDetailsFirstDynamicIndex +
11469                      2 * (argument_count + local_count) +
11470                      (at_return ? 1 : 0);
11471   Handle<FixedArray> details = isolate->factory()->NewFixedArray(details_size);
11472
11473   // Add the frame id.
11474   details->set(kFrameDetailsFrameIdIndex, *frame_id);
11475
11476   // Add the function (same as in function frame).
11477   details->set(kFrameDetailsFunctionIndex, frame_inspector.GetFunction());
11478
11479   // Add the arguments count.
11480   details->set(kFrameDetailsArgumentCountIndex, Smi::FromInt(argument_count));
11481
11482   // Add the locals count
11483   details->set(kFrameDetailsLocalCountIndex,
11484                Smi::FromInt(local_count));
11485
11486   // Add the source position.
11487   if (position != RelocInfo::kNoPosition) {
11488     details->set(kFrameDetailsSourcePositionIndex, Smi::FromInt(position));
11489   } else {
11490     details->set(kFrameDetailsSourcePositionIndex, heap->undefined_value());
11491   }
11492
11493   // Add the constructor information.
11494   details->set(kFrameDetailsConstructCallIndex, heap->ToBoolean(constructor));
11495
11496   // Add the at return information.
11497   details->set(kFrameDetailsAtReturnIndex, heap->ToBoolean(at_return));
11498
11499   // Add flags to indicate information on whether this frame is
11500   //   bit 0: invoked in the debugger context.
11501   //   bit 1: optimized frame.
11502   //   bit 2: inlined in optimized frame
11503   int flags = 0;
11504   if (*save->context() == *isolate->debug()->debug_context()) {
11505     flags |= 1 << 0;
11506   }
11507   if (is_optimized) {
11508     flags |= 1 << 1;
11509     flags |= inlined_jsframe_index << 2;
11510   }
11511   details->set(kFrameDetailsFlagsIndex, Smi::FromInt(flags));
11512
11513   // Fill the dynamic part.
11514   int details_index = kFrameDetailsFirstDynamicIndex;
11515
11516   // Add arguments name and value.
11517   for (int i = 0; i < argument_count; i++) {
11518     // Name of the argument.
11519     if (i < scope_info->ParameterCount()) {
11520       details->set(details_index++, scope_info->ParameterName(i));
11521     } else {
11522       details->set(details_index++, heap->undefined_value());
11523     }
11524
11525     // Parameter value.
11526     if (i < frame_inspector.GetParametersCount()) {
11527       // Get the value from the stack.
11528       details->set(details_index++, frame_inspector.GetParameter(i));
11529     } else {
11530       details->set(details_index++, heap->undefined_value());
11531     }
11532   }
11533
11534   // Add locals name and value from the temporary copy from the function frame.
11535   for (int i = 0; i < local_count * 2; i++) {
11536     details->set(details_index++, locals->get(i));
11537   }
11538
11539   // Add the value being returned.
11540   if (at_return) {
11541     details->set(details_index++, *return_value);
11542   }
11543
11544   // Add the receiver (same as in function frame).
11545   // THIS MUST BE DONE LAST SINCE WE MIGHT ADVANCE
11546   // THE FRAME ITERATOR TO WRAP THE RECEIVER.
11547   Handle<Object> receiver(it.frame()->receiver(), isolate);
11548   if (!receiver->IsJSObject() &&
11549       shared->strict_mode() == SLOPPY &&
11550       !function->IsBuiltin()) {
11551     // If the receiver is not a JSObject and the function is not a
11552     // builtin or strict-mode we have hit an optimization where a
11553     // value object is not converted into a wrapped JS objects. To
11554     // hide this optimization from the debugger, we wrap the receiver
11555     // by creating correct wrapper object based on the calling frame's
11556     // native context.
11557     it.Advance();
11558     if (receiver->IsUndefined()) {
11559       Context* context = function->context();
11560       receiver = handle(context->global_object()->global_receiver());
11561     } else {
11562       ASSERT(!receiver->IsNull());
11563       Context* context = Context::cast(it.frame()->context());
11564       Handle<Context> native_context(Context::cast(context->native_context()));
11565       receiver = Object::ToObject(
11566           isolate, receiver, native_context).ToHandleChecked();
11567     }
11568   }
11569   details->set(kFrameDetailsReceiverIndex, *receiver);
11570
11571   ASSERT_EQ(details_size, details_index);
11572   return *isolate->factory()->NewJSArrayWithElements(details);
11573 }
11574
11575
11576 static bool ParameterIsShadowedByContextLocal(Handle<ScopeInfo> info,
11577                                               Handle<String> parameter_name) {
11578   VariableMode mode;
11579   InitializationFlag flag;
11580   return ScopeInfo::ContextSlotIndex(info, parameter_name, &mode, &flag) != -1;
11581 }
11582
11583
11584 // Create a plain JSObject which materializes the local scope for the specified
11585 // frame.
11586 MUST_USE_RESULT
11587 static MaybeHandle<JSObject> MaterializeStackLocalsWithFrameInspector(
11588     Isolate* isolate,
11589     Handle<JSObject> target,
11590     Handle<JSFunction> function,
11591     FrameInspector* frame_inspector) {
11592   Handle<SharedFunctionInfo> shared(function->shared());
11593   Handle<ScopeInfo> scope_info(shared->scope_info());
11594
11595   // First fill all parameters.
11596   for (int i = 0; i < scope_info->ParameterCount(); ++i) {
11597     // Do not materialize the parameter if it is shadowed by a context local.
11598     Handle<String> name(scope_info->ParameterName(i));
11599     if (ParameterIsShadowedByContextLocal(scope_info, name)) continue;
11600
11601     HandleScope scope(isolate);
11602     Handle<Object> value(i < frame_inspector->GetParametersCount()
11603                              ? frame_inspector->GetParameter(i)
11604                              : isolate->heap()->undefined_value(),
11605                          isolate);
11606     ASSERT(!value->IsTheHole());
11607
11608     RETURN_ON_EXCEPTION(
11609         isolate,
11610         Runtime::SetObjectProperty(isolate, target, name, value, NONE, SLOPPY),
11611         JSObject);
11612   }
11613
11614   // Second fill all stack locals.
11615   for (int i = 0; i < scope_info->StackLocalCount(); ++i) {
11616     if (scope_info->LocalIsSynthetic(i)) continue;
11617     Handle<String> name(scope_info->StackLocalName(i));
11618     Handle<Object> value(frame_inspector->GetExpression(i), isolate);
11619     if (value->IsTheHole()) continue;
11620
11621     RETURN_ON_EXCEPTION(
11622         isolate,
11623         Runtime::SetObjectProperty(isolate, target, name, value, NONE, SLOPPY),
11624         JSObject);
11625   }
11626
11627   return target;
11628 }
11629
11630
11631 static void UpdateStackLocalsFromMaterializedObject(Isolate* isolate,
11632                                                     Handle<JSObject> target,
11633                                                     Handle<JSFunction> function,
11634                                                     JavaScriptFrame* frame,
11635                                                     int inlined_jsframe_index) {
11636   if (inlined_jsframe_index != 0 || frame->is_optimized()) {
11637     // Optimized frames are not supported.
11638     // TODO(yangguo): make sure all code deoptimized when debugger is active
11639     //                and assert that this cannot happen.
11640     return;
11641   }
11642
11643   Handle<SharedFunctionInfo> shared(function->shared());
11644   Handle<ScopeInfo> scope_info(shared->scope_info());
11645
11646   // Parameters.
11647   for (int i = 0; i < scope_info->ParameterCount(); ++i) {
11648     // Shadowed parameters were not materialized.
11649     Handle<String> name(scope_info->ParameterName(i));
11650     if (ParameterIsShadowedByContextLocal(scope_info, name)) continue;
11651
11652     ASSERT(!frame->GetParameter(i)->IsTheHole());
11653     HandleScope scope(isolate);
11654     Handle<Object> value =
11655         Object::GetPropertyOrElement(target, name).ToHandleChecked();
11656     frame->SetParameterValue(i, *value);
11657   }
11658
11659   // Stack locals.
11660   for (int i = 0; i < scope_info->StackLocalCount(); ++i) {
11661     if (scope_info->LocalIsSynthetic(i)) continue;
11662     if (frame->GetExpression(i)->IsTheHole()) continue;
11663     HandleScope scope(isolate);
11664     Handle<Object> value = Object::GetPropertyOrElement(
11665         target,
11666         handle(scope_info->StackLocalName(i), isolate)).ToHandleChecked();
11667     frame->SetExpression(i, *value);
11668   }
11669 }
11670
11671
11672 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeLocalContext(
11673     Isolate* isolate,
11674     Handle<JSObject> target,
11675     Handle<JSFunction> function,
11676     JavaScriptFrame* frame) {
11677   HandleScope scope(isolate);
11678   Handle<SharedFunctionInfo> shared(function->shared());
11679   Handle<ScopeInfo> scope_info(shared->scope_info());
11680
11681   if (!scope_info->HasContext()) return target;
11682
11683   // Third fill all context locals.
11684   Handle<Context> frame_context(Context::cast(frame->context()));
11685   Handle<Context> function_context(frame_context->declaration_context());
11686   if (!ScopeInfo::CopyContextLocalsToScopeObject(
11687           scope_info, function_context, target)) {
11688     return MaybeHandle<JSObject>();
11689   }
11690
11691   // Finally copy any properties from the function context extension.
11692   // These will be variables introduced by eval.
11693   if (function_context->closure() == *function) {
11694     if (function_context->has_extension() &&
11695         !function_context->IsNativeContext()) {
11696       Handle<JSObject> ext(JSObject::cast(function_context->extension()));
11697       Handle<FixedArray> keys;
11698       ASSIGN_RETURN_ON_EXCEPTION(
11699           isolate, keys,
11700           JSReceiver::GetKeys(ext, JSReceiver::INCLUDE_PROTOS),
11701           JSObject);
11702
11703       for (int i = 0; i < keys->length(); i++) {
11704         // Names of variables introduced by eval are strings.
11705         ASSERT(keys->get(i)->IsString());
11706         Handle<String> key(String::cast(keys->get(i)));
11707         Handle<Object> value;
11708         ASSIGN_RETURN_ON_EXCEPTION(
11709             isolate, value, Object::GetPropertyOrElement(ext, key), JSObject);
11710         RETURN_ON_EXCEPTION(
11711             isolate,
11712             Runtime::SetObjectProperty(
11713                 isolate, target, key, value, NONE, SLOPPY),
11714             JSObject);
11715       }
11716     }
11717   }
11718
11719   return target;
11720 }
11721
11722
11723 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeLocalScope(
11724     Isolate* isolate,
11725     JavaScriptFrame* frame,
11726     int inlined_jsframe_index) {
11727   FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate);
11728   Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction()));
11729
11730   Handle<JSObject> local_scope =
11731       isolate->factory()->NewJSObject(isolate->object_function());
11732   ASSIGN_RETURN_ON_EXCEPTION(
11733       isolate, local_scope,
11734       MaterializeStackLocalsWithFrameInspector(
11735           isolate, local_scope, function, &frame_inspector),
11736       JSObject);
11737
11738   return MaterializeLocalContext(isolate, local_scope, function, frame);
11739 }
11740
11741
11742 // Set the context local variable value.
11743 static bool SetContextLocalValue(Isolate* isolate,
11744                                  Handle<ScopeInfo> scope_info,
11745                                  Handle<Context> context,
11746                                  Handle<String> variable_name,
11747                                  Handle<Object> new_value) {
11748   for (int i = 0; i < scope_info->ContextLocalCount(); i++) {
11749     Handle<String> next_name(scope_info->ContextLocalName(i));
11750     if (String::Equals(variable_name, next_name)) {
11751       VariableMode mode;
11752       InitializationFlag init_flag;
11753       int context_index =
11754           ScopeInfo::ContextSlotIndex(scope_info, next_name, &mode, &init_flag);
11755       context->set(context_index, *new_value);
11756       return true;
11757     }
11758   }
11759
11760   return false;
11761 }
11762
11763
11764 static bool SetLocalVariableValue(Isolate* isolate,
11765                                   JavaScriptFrame* frame,
11766                                   int inlined_jsframe_index,
11767                                   Handle<String> variable_name,
11768                                   Handle<Object> new_value) {
11769   if (inlined_jsframe_index != 0 || frame->is_optimized()) {
11770     // Optimized frames are not supported.
11771     return false;
11772   }
11773
11774   Handle<JSFunction> function(frame->function());
11775   Handle<SharedFunctionInfo> shared(function->shared());
11776   Handle<ScopeInfo> scope_info(shared->scope_info());
11777
11778   bool default_result = false;
11779
11780   // Parameters.
11781   for (int i = 0; i < scope_info->ParameterCount(); ++i) {
11782     HandleScope scope(isolate);
11783     if (String::Equals(handle(scope_info->ParameterName(i)), variable_name)) {
11784       frame->SetParameterValue(i, *new_value);
11785       // Argument might be shadowed in heap context, don't stop here.
11786       default_result = true;
11787     }
11788   }
11789
11790   // Stack locals.
11791   for (int i = 0; i < scope_info->StackLocalCount(); ++i) {
11792     HandleScope scope(isolate);
11793     if (String::Equals(handle(scope_info->StackLocalName(i)), variable_name)) {
11794       frame->SetExpression(i, *new_value);
11795       return true;
11796     }
11797   }
11798
11799   if (scope_info->HasContext()) {
11800     // Context locals.
11801     Handle<Context> frame_context(Context::cast(frame->context()));
11802     Handle<Context> function_context(frame_context->declaration_context());
11803     if (SetContextLocalValue(
11804         isolate, scope_info, function_context, variable_name, new_value)) {
11805       return true;
11806     }
11807
11808     // Function context extension. These are variables introduced by eval.
11809     if (function_context->closure() == *function) {
11810       if (function_context->has_extension() &&
11811           !function_context->IsNativeContext()) {
11812         Handle<JSObject> ext(JSObject::cast(function_context->extension()));
11813
11814         if (JSReceiver::HasProperty(ext, variable_name)) {
11815           // We don't expect this to do anything except replacing
11816           // property value.
11817           Runtime::SetObjectProperty(isolate, ext, variable_name, new_value,
11818                                      NONE, SLOPPY).Assert();
11819           return true;
11820         }
11821       }
11822     }
11823   }
11824
11825   return default_result;
11826 }
11827
11828
11829 // Create a plain JSObject which materializes the closure content for the
11830 // context.
11831 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeClosure(
11832     Isolate* isolate,
11833     Handle<Context> context) {
11834   ASSERT(context->IsFunctionContext());
11835
11836   Handle<SharedFunctionInfo> shared(context->closure()->shared());
11837   Handle<ScopeInfo> scope_info(shared->scope_info());
11838
11839   // Allocate and initialize a JSObject with all the content of this function
11840   // closure.
11841   Handle<JSObject> closure_scope =
11842       isolate->factory()->NewJSObject(isolate->object_function());
11843
11844   // Fill all context locals to the context extension.
11845   if (!ScopeInfo::CopyContextLocalsToScopeObject(
11846           scope_info, context, closure_scope)) {
11847     return MaybeHandle<JSObject>();
11848   }
11849
11850   // Finally copy any properties from the function context extension. This will
11851   // be variables introduced by eval.
11852   if (context->has_extension()) {
11853     Handle<JSObject> ext(JSObject::cast(context->extension()));
11854     Handle<FixedArray> keys;
11855     ASSIGN_RETURN_ON_EXCEPTION(
11856         isolate, keys,
11857         JSReceiver::GetKeys(ext, JSReceiver::INCLUDE_PROTOS), JSObject);
11858
11859     for (int i = 0; i < keys->length(); i++) {
11860       HandleScope scope(isolate);
11861       // Names of variables introduced by eval are strings.
11862       ASSERT(keys->get(i)->IsString());
11863       Handle<String> key(String::cast(keys->get(i)));
11864       Handle<Object> value;
11865       ASSIGN_RETURN_ON_EXCEPTION(
11866           isolate, value, Object::GetPropertyOrElement(ext, key), JSObject);
11867       RETURN_ON_EXCEPTION(
11868           isolate,
11869           Runtime::SetObjectProperty(
11870               isolate, closure_scope, key, value, NONE, SLOPPY),
11871           JSObject);
11872     }
11873   }
11874
11875   return closure_scope;
11876 }
11877
11878
11879 // This method copies structure of MaterializeClosure method above.
11880 static bool SetClosureVariableValue(Isolate* isolate,
11881                                     Handle<Context> context,
11882                                     Handle<String> variable_name,
11883                                     Handle<Object> new_value) {
11884   ASSERT(context->IsFunctionContext());
11885
11886   Handle<SharedFunctionInfo> shared(context->closure()->shared());
11887   Handle<ScopeInfo> scope_info(shared->scope_info());
11888
11889   // Context locals to the context extension.
11890   if (SetContextLocalValue(
11891           isolate, scope_info, context, variable_name, new_value)) {
11892     return true;
11893   }
11894
11895   // Properties from the function context extension. This will
11896   // be variables introduced by eval.
11897   if (context->has_extension()) {
11898     Handle<JSObject> ext(JSObject::cast(context->extension()));
11899     if (JSReceiver::HasProperty(ext, variable_name)) {
11900       // We don't expect this to do anything except replacing property value.
11901       Runtime::SetObjectProperty(isolate, ext, variable_name, new_value,
11902                                  NONE, SLOPPY).Assert();
11903       return true;
11904     }
11905   }
11906
11907   return false;
11908 }
11909
11910
11911 // Create a plain JSObject which materializes the scope for the specified
11912 // catch context.
11913 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeCatchScope(
11914     Isolate* isolate,
11915     Handle<Context> context) {
11916   ASSERT(context->IsCatchContext());
11917   Handle<String> name(String::cast(context->extension()));
11918   Handle<Object> thrown_object(context->get(Context::THROWN_OBJECT_INDEX),
11919                                isolate);
11920   Handle<JSObject> catch_scope =
11921       isolate->factory()->NewJSObject(isolate->object_function());
11922   RETURN_ON_EXCEPTION(
11923       isolate,
11924       Runtime::SetObjectProperty(isolate, catch_scope, name, thrown_object,
11925                                  NONE, SLOPPY),
11926       JSObject);
11927   return catch_scope;
11928 }
11929
11930
11931 static bool SetCatchVariableValue(Isolate* isolate,
11932                                   Handle<Context> context,
11933                                   Handle<String> variable_name,
11934                                   Handle<Object> new_value) {
11935   ASSERT(context->IsCatchContext());
11936   Handle<String> name(String::cast(context->extension()));
11937   if (!String::Equals(name, variable_name)) {
11938     return false;
11939   }
11940   context->set(Context::THROWN_OBJECT_INDEX, *new_value);
11941   return true;
11942 }
11943
11944
11945 // Create a plain JSObject which materializes the block scope for the specified
11946 // block context.
11947 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeBlockScope(
11948     Isolate* isolate,
11949     Handle<Context> context) {
11950   ASSERT(context->IsBlockContext());
11951   Handle<ScopeInfo> scope_info(ScopeInfo::cast(context->extension()));
11952
11953   // Allocate and initialize a JSObject with all the arguments, stack locals
11954   // heap locals and extension properties of the debugged function.
11955   Handle<JSObject> block_scope =
11956       isolate->factory()->NewJSObject(isolate->object_function());
11957
11958   // Fill all context locals.
11959   if (!ScopeInfo::CopyContextLocalsToScopeObject(
11960           scope_info, context, block_scope)) {
11961     return MaybeHandle<JSObject>();
11962   }
11963
11964   return block_scope;
11965 }
11966
11967
11968 // Create a plain JSObject which materializes the module scope for the specified
11969 // module context.
11970 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeModuleScope(
11971     Isolate* isolate,
11972     Handle<Context> context) {
11973   ASSERT(context->IsModuleContext());
11974   Handle<ScopeInfo> scope_info(ScopeInfo::cast(context->extension()));
11975
11976   // Allocate and initialize a JSObject with all the members of the debugged
11977   // module.
11978   Handle<JSObject> module_scope =
11979       isolate->factory()->NewJSObject(isolate->object_function());
11980
11981   // Fill all context locals.
11982   if (!ScopeInfo::CopyContextLocalsToScopeObject(
11983           scope_info, context, module_scope)) {
11984     return MaybeHandle<JSObject>();
11985   }
11986
11987   return module_scope;
11988 }
11989
11990
11991 // Iterate over the actual scopes visible from a stack frame or from a closure.
11992 // The iteration proceeds from the innermost visible nested scope outwards.
11993 // All scopes are backed by an actual context except the local scope,
11994 // which is inserted "artificially" in the context chain.
11995 class ScopeIterator {
11996  public:
11997   enum ScopeType {
11998     ScopeTypeGlobal = 0,
11999     ScopeTypeLocal,
12000     ScopeTypeWith,
12001     ScopeTypeClosure,
12002     ScopeTypeCatch,
12003     ScopeTypeBlock,
12004     ScopeTypeModule
12005   };
12006
12007   ScopeIterator(Isolate* isolate,
12008                 JavaScriptFrame* frame,
12009                 int inlined_jsframe_index,
12010                 bool ignore_nested_scopes = false)
12011     : isolate_(isolate),
12012       frame_(frame),
12013       inlined_jsframe_index_(inlined_jsframe_index),
12014       function_(frame->function()),
12015       context_(Context::cast(frame->context())),
12016       nested_scope_chain_(4),
12017       failed_(false) {
12018
12019     // Catch the case when the debugger stops in an internal function.
12020     Handle<SharedFunctionInfo> shared_info(function_->shared());
12021     Handle<ScopeInfo> scope_info(shared_info->scope_info());
12022     if (shared_info->script() == isolate->heap()->undefined_value()) {
12023       while (context_->closure() == *function_) {
12024         context_ = Handle<Context>(context_->previous(), isolate_);
12025       }
12026       return;
12027     }
12028
12029     // Get the debug info (create it if it does not exist).
12030     if (!isolate->debug()->EnsureDebugInfo(shared_info, function_)) {
12031       // Return if ensuring debug info failed.
12032       return;
12033     }
12034
12035     // Currently it takes too much time to find nested scopes due to script
12036     // parsing. Sometimes we want to run the ScopeIterator as fast as possible
12037     // (for example, while collecting async call stacks on every
12038     // addEventListener call), even if we drop some nested scopes.
12039     // Later we may optimize getting the nested scopes (cache the result?)
12040     // and include nested scopes into the "fast" iteration case as well.
12041     if (!ignore_nested_scopes) {
12042       Handle<DebugInfo> debug_info = Debug::GetDebugInfo(shared_info);
12043
12044       // Find the break point where execution has stopped.
12045       BreakLocationIterator break_location_iterator(debug_info,
12046                                                     ALL_BREAK_LOCATIONS);
12047       // pc points to the instruction after the current one, possibly a break
12048       // location as well. So the "- 1" to exclude it from the search.
12049       break_location_iterator.FindBreakLocationFromAddress(frame->pc() - 1);
12050
12051       // Within the return sequence at the moment it is not possible to
12052       // get a source position which is consistent with the current scope chain.
12053       // Thus all nested with, catch and block contexts are skipped and we only
12054       // provide the function scope.
12055       ignore_nested_scopes = break_location_iterator.IsExit();
12056     }
12057
12058     if (ignore_nested_scopes) {
12059       if (scope_info->HasContext()) {
12060         context_ = Handle<Context>(context_->declaration_context(), isolate_);
12061       } else {
12062         while (context_->closure() == *function_) {
12063           context_ = Handle<Context>(context_->previous(), isolate_);
12064         }
12065       }
12066       if (scope_info->scope_type() == FUNCTION_SCOPE) {
12067         nested_scope_chain_.Add(scope_info);
12068       }
12069     } else {
12070       // Reparse the code and analyze the scopes.
12071       Handle<Script> script(Script::cast(shared_info->script()));
12072       Scope* scope = NULL;
12073
12074       // Check whether we are in global, eval or function code.
12075       Handle<ScopeInfo> scope_info(shared_info->scope_info());
12076       if (scope_info->scope_type() != FUNCTION_SCOPE) {
12077         // Global or eval code.
12078         CompilationInfoWithZone info(script);
12079         if (scope_info->scope_type() == GLOBAL_SCOPE) {
12080           info.MarkAsGlobal();
12081         } else {
12082           ASSERT(scope_info->scope_type() == EVAL_SCOPE);
12083           info.MarkAsEval();
12084           info.SetContext(Handle<Context>(function_->context()));
12085         }
12086         if (Parser::Parse(&info) && Scope::Analyze(&info)) {
12087           scope = info.function()->scope();
12088         }
12089         RetrieveScopeChain(scope, shared_info);
12090       } else {
12091         // Function code
12092         CompilationInfoWithZone info(shared_info);
12093         if (Parser::Parse(&info) && Scope::Analyze(&info)) {
12094           scope = info.function()->scope();
12095         }
12096         RetrieveScopeChain(scope, shared_info);
12097       }
12098     }
12099   }
12100
12101   ScopeIterator(Isolate* isolate,
12102                 Handle<JSFunction> function)
12103     : isolate_(isolate),
12104       frame_(NULL),
12105       inlined_jsframe_index_(0),
12106       function_(function),
12107       context_(function->context()),
12108       failed_(false) {
12109     if (function->IsBuiltin()) {
12110       context_ = Handle<Context>();
12111     }
12112   }
12113
12114   // More scopes?
12115   bool Done() {
12116     ASSERT(!failed_);
12117     return context_.is_null();
12118   }
12119
12120   bool Failed() { return failed_; }
12121
12122   // Move to the next scope.
12123   void Next() {
12124     ASSERT(!failed_);
12125     ScopeType scope_type = Type();
12126     if (scope_type == ScopeTypeGlobal) {
12127       // The global scope is always the last in the chain.
12128       ASSERT(context_->IsNativeContext());
12129       context_ = Handle<Context>();
12130       return;
12131     }
12132     if (nested_scope_chain_.is_empty()) {
12133       context_ = Handle<Context>(context_->previous(), isolate_);
12134     } else {
12135       if (nested_scope_chain_.last()->HasContext()) {
12136         ASSERT(context_->previous() != NULL);
12137         context_ = Handle<Context>(context_->previous(), isolate_);
12138       }
12139       nested_scope_chain_.RemoveLast();
12140     }
12141   }
12142
12143   // Return the type of the current scope.
12144   ScopeType Type() {
12145     ASSERT(!failed_);
12146     if (!nested_scope_chain_.is_empty()) {
12147       Handle<ScopeInfo> scope_info = nested_scope_chain_.last();
12148       switch (scope_info->scope_type()) {
12149         case FUNCTION_SCOPE:
12150           ASSERT(context_->IsFunctionContext() ||
12151                  !scope_info->HasContext());
12152           return ScopeTypeLocal;
12153         case MODULE_SCOPE:
12154           ASSERT(context_->IsModuleContext());
12155           return ScopeTypeModule;
12156         case GLOBAL_SCOPE:
12157           ASSERT(context_->IsNativeContext());
12158           return ScopeTypeGlobal;
12159         case WITH_SCOPE:
12160           ASSERT(context_->IsWithContext());
12161           return ScopeTypeWith;
12162         case CATCH_SCOPE:
12163           ASSERT(context_->IsCatchContext());
12164           return ScopeTypeCatch;
12165         case BLOCK_SCOPE:
12166           ASSERT(!scope_info->HasContext() ||
12167                  context_->IsBlockContext());
12168           return ScopeTypeBlock;
12169         case EVAL_SCOPE:
12170           UNREACHABLE();
12171       }
12172     }
12173     if (context_->IsNativeContext()) {
12174       ASSERT(context_->global_object()->IsGlobalObject());
12175       return ScopeTypeGlobal;
12176     }
12177     if (context_->IsFunctionContext()) {
12178       return ScopeTypeClosure;
12179     }
12180     if (context_->IsCatchContext()) {
12181       return ScopeTypeCatch;
12182     }
12183     if (context_->IsBlockContext()) {
12184       return ScopeTypeBlock;
12185     }
12186     if (context_->IsModuleContext()) {
12187       return ScopeTypeModule;
12188     }
12189     ASSERT(context_->IsWithContext());
12190     return ScopeTypeWith;
12191   }
12192
12193   // Return the JavaScript object with the content of the current scope.
12194   MaybeHandle<JSObject> ScopeObject() {
12195     ASSERT(!failed_);
12196     switch (Type()) {
12197       case ScopeIterator::ScopeTypeGlobal:
12198         return Handle<JSObject>(CurrentContext()->global_object());
12199       case ScopeIterator::ScopeTypeLocal:
12200         // Materialize the content of the local scope into a JSObject.
12201         ASSERT(nested_scope_chain_.length() == 1);
12202         return MaterializeLocalScope(isolate_, frame_, inlined_jsframe_index_);
12203       case ScopeIterator::ScopeTypeWith:
12204         // Return the with object.
12205         return Handle<JSObject>(JSObject::cast(CurrentContext()->extension()));
12206       case ScopeIterator::ScopeTypeCatch:
12207         return MaterializeCatchScope(isolate_, CurrentContext());
12208       case ScopeIterator::ScopeTypeClosure:
12209         // Materialize the content of the closure scope into a JSObject.
12210         return MaterializeClosure(isolate_, CurrentContext());
12211       case ScopeIterator::ScopeTypeBlock:
12212         return MaterializeBlockScope(isolate_, CurrentContext());
12213       case ScopeIterator::ScopeTypeModule:
12214         return MaterializeModuleScope(isolate_, CurrentContext());
12215     }
12216     UNREACHABLE();
12217     return Handle<JSObject>();
12218   }
12219
12220   bool SetVariableValue(Handle<String> variable_name,
12221                         Handle<Object> new_value) {
12222     ASSERT(!failed_);
12223     switch (Type()) {
12224       case ScopeIterator::ScopeTypeGlobal:
12225         break;
12226       case ScopeIterator::ScopeTypeLocal:
12227         return SetLocalVariableValue(isolate_, frame_, inlined_jsframe_index_,
12228             variable_name, new_value);
12229       case ScopeIterator::ScopeTypeWith:
12230         break;
12231       case ScopeIterator::ScopeTypeCatch:
12232         return SetCatchVariableValue(isolate_, CurrentContext(),
12233             variable_name, new_value);
12234       case ScopeIterator::ScopeTypeClosure:
12235         return SetClosureVariableValue(isolate_, CurrentContext(),
12236             variable_name, new_value);
12237       case ScopeIterator::ScopeTypeBlock:
12238         // TODO(2399): should we implement it?
12239         break;
12240       case ScopeIterator::ScopeTypeModule:
12241         // TODO(2399): should we implement it?
12242         break;
12243     }
12244     return false;
12245   }
12246
12247   Handle<ScopeInfo> CurrentScopeInfo() {
12248     ASSERT(!failed_);
12249     if (!nested_scope_chain_.is_empty()) {
12250       return nested_scope_chain_.last();
12251     } else if (context_->IsBlockContext()) {
12252       return Handle<ScopeInfo>(ScopeInfo::cast(context_->extension()));
12253     } else if (context_->IsFunctionContext()) {
12254       return Handle<ScopeInfo>(context_->closure()->shared()->scope_info());
12255     }
12256     return Handle<ScopeInfo>::null();
12257   }
12258
12259   // Return the context for this scope. For the local context there might not
12260   // be an actual context.
12261   Handle<Context> CurrentContext() {
12262     ASSERT(!failed_);
12263     if (Type() == ScopeTypeGlobal ||
12264         nested_scope_chain_.is_empty()) {
12265       return context_;
12266     } else if (nested_scope_chain_.last()->HasContext()) {
12267       return context_;
12268     } else {
12269       return Handle<Context>();
12270     }
12271   }
12272
12273 #ifdef DEBUG
12274   // Debug print of the content of the current scope.
12275   void DebugPrint() {
12276     ASSERT(!failed_);
12277     switch (Type()) {
12278       case ScopeIterator::ScopeTypeGlobal:
12279         PrintF("Global:\n");
12280         CurrentContext()->Print();
12281         break;
12282
12283       case ScopeIterator::ScopeTypeLocal: {
12284         PrintF("Local:\n");
12285         function_->shared()->scope_info()->Print();
12286         if (!CurrentContext().is_null()) {
12287           CurrentContext()->Print();
12288           if (CurrentContext()->has_extension()) {
12289             Handle<Object> extension(CurrentContext()->extension(), isolate_);
12290             if (extension->IsJSContextExtensionObject()) {
12291               extension->Print();
12292             }
12293           }
12294         }
12295         break;
12296       }
12297
12298       case ScopeIterator::ScopeTypeWith:
12299         PrintF("With:\n");
12300         CurrentContext()->extension()->Print();
12301         break;
12302
12303       case ScopeIterator::ScopeTypeCatch:
12304         PrintF("Catch:\n");
12305         CurrentContext()->extension()->Print();
12306         CurrentContext()->get(Context::THROWN_OBJECT_INDEX)->Print();
12307         break;
12308
12309       case ScopeIterator::ScopeTypeClosure:
12310         PrintF("Closure:\n");
12311         CurrentContext()->Print();
12312         if (CurrentContext()->has_extension()) {
12313           Handle<Object> extension(CurrentContext()->extension(), isolate_);
12314           if (extension->IsJSContextExtensionObject()) {
12315             extension->Print();
12316           }
12317         }
12318         break;
12319
12320       default:
12321         UNREACHABLE();
12322     }
12323     PrintF("\n");
12324   }
12325 #endif
12326
12327  private:
12328   Isolate* isolate_;
12329   JavaScriptFrame* frame_;
12330   int inlined_jsframe_index_;
12331   Handle<JSFunction> function_;
12332   Handle<Context> context_;
12333   List<Handle<ScopeInfo> > nested_scope_chain_;
12334   bool failed_;
12335
12336   void RetrieveScopeChain(Scope* scope,
12337                           Handle<SharedFunctionInfo> shared_info) {
12338     if (scope != NULL) {
12339       int source_position = shared_info->code()->SourcePosition(frame_->pc());
12340       scope->GetNestedScopeChain(&nested_scope_chain_, source_position);
12341     } else {
12342       // A failed reparse indicates that the preparser has diverged from the
12343       // parser or that the preparse data given to the initial parse has been
12344       // faulty. We fail in debug mode but in release mode we only provide the
12345       // information we get from the context chain but nothing about
12346       // completely stack allocated scopes or stack allocated locals.
12347       // Or it could be due to stack overflow.
12348       ASSERT(isolate_->has_pending_exception());
12349       failed_ = true;
12350     }
12351   }
12352
12353   DISALLOW_IMPLICIT_CONSTRUCTORS(ScopeIterator);
12354 };
12355
12356
12357 RUNTIME_FUNCTION(Runtime_GetScopeCount) {
12358   HandleScope scope(isolate);
12359   ASSERT(args.length() == 2);
12360   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
12361   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
12362
12363   CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
12364
12365   // Get the frame where the debugging is performed.
12366   StackFrame::Id id = UnwrapFrameId(wrapped_id);
12367   JavaScriptFrameIterator it(isolate, id);
12368   JavaScriptFrame* frame = it.frame();
12369
12370   // Count the visible scopes.
12371   int n = 0;
12372   for (ScopeIterator it(isolate, frame, 0);
12373        !it.Done();
12374        it.Next()) {
12375     n++;
12376   }
12377
12378   return Smi::FromInt(n);
12379 }
12380
12381
12382 // Returns the list of step-in positions (text offset) in a function of the
12383 // stack frame in a range from the current debug break position to the end
12384 // of the corresponding statement.
12385 RUNTIME_FUNCTION(Runtime_GetStepInPositions) {
12386   HandleScope scope(isolate);
12387   ASSERT(args.length() == 2);
12388   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
12389   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
12390
12391   CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
12392
12393   // Get the frame where the debugging is performed.
12394   StackFrame::Id id = UnwrapFrameId(wrapped_id);
12395   JavaScriptFrameIterator frame_it(isolate, id);
12396   RUNTIME_ASSERT(!frame_it.done());
12397
12398   JavaScriptFrame* frame = frame_it.frame();
12399
12400   Handle<JSFunction> fun =
12401       Handle<JSFunction>(frame->function());
12402   Handle<SharedFunctionInfo> shared =
12403       Handle<SharedFunctionInfo>(fun->shared());
12404
12405   if (!isolate->debug()->EnsureDebugInfo(shared, fun)) {
12406     return isolate->heap()->undefined_value();
12407   }
12408
12409   Handle<DebugInfo> debug_info = Debug::GetDebugInfo(shared);
12410
12411   int len = 0;
12412   Handle<JSArray> array(isolate->factory()->NewJSArray(10));
12413   // Find the break point where execution has stopped.
12414   BreakLocationIterator break_location_iterator(debug_info,
12415                                                 ALL_BREAK_LOCATIONS);
12416
12417   break_location_iterator.FindBreakLocationFromAddress(frame->pc() - 1);
12418   int current_statement_pos = break_location_iterator.statement_position();
12419
12420   while (!break_location_iterator.Done()) {
12421     bool accept;
12422     if (break_location_iterator.pc() > frame->pc()) {
12423       accept = true;
12424     } else {
12425       StackFrame::Id break_frame_id = isolate->debug()->break_frame_id();
12426       // The break point is near our pc. Could be a step-in possibility,
12427       // that is currently taken by active debugger call.
12428       if (break_frame_id == StackFrame::NO_ID) {
12429         // We are not stepping.
12430         accept = false;
12431       } else {
12432         JavaScriptFrameIterator additional_frame_it(isolate, break_frame_id);
12433         // If our frame is a top frame and we are stepping, we can do step-in
12434         // at this place.
12435         accept = additional_frame_it.frame()->id() == id;
12436       }
12437     }
12438     if (accept) {
12439       if (break_location_iterator.IsStepInLocation(isolate)) {
12440         Smi* position_value = Smi::FromInt(break_location_iterator.position());
12441         RETURN_FAILURE_ON_EXCEPTION(
12442             isolate,
12443             JSObject::SetElement(array, len,
12444                                  Handle<Object>(position_value, isolate),
12445                                  NONE, SLOPPY));
12446         len++;
12447       }
12448     }
12449     // Advance iterator.
12450     break_location_iterator.Next();
12451     if (current_statement_pos !=
12452         break_location_iterator.statement_position()) {
12453       break;
12454     }
12455   }
12456   return *array;
12457 }
12458
12459
12460 static const int kScopeDetailsTypeIndex = 0;
12461 static const int kScopeDetailsObjectIndex = 1;
12462 static const int kScopeDetailsSize = 2;
12463
12464
12465 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeScopeDetails(
12466     Isolate* isolate,
12467     ScopeIterator* it) {
12468   // Calculate the size of the result.
12469   int details_size = kScopeDetailsSize;
12470   Handle<FixedArray> details = isolate->factory()->NewFixedArray(details_size);
12471
12472   // Fill in scope details.
12473   details->set(kScopeDetailsTypeIndex, Smi::FromInt(it->Type()));
12474   Handle<JSObject> scope_object;
12475   ASSIGN_RETURN_ON_EXCEPTION(
12476       isolate, scope_object, it->ScopeObject(), JSObject);
12477   details->set(kScopeDetailsObjectIndex, *scope_object);
12478
12479   return isolate->factory()->NewJSArrayWithElements(details);
12480 }
12481
12482
12483 // Return an array with scope details
12484 // args[0]: number: break id
12485 // args[1]: number: frame index
12486 // args[2]: number: inlined frame index
12487 // args[3]: number: scope index
12488 //
12489 // The array returned contains the following information:
12490 // 0: Scope type
12491 // 1: Scope object
12492 RUNTIME_FUNCTION(Runtime_GetScopeDetails) {
12493   HandleScope scope(isolate);
12494   ASSERT(args.length() == 4);
12495   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
12496   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
12497
12498   CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
12499   CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
12500   CONVERT_NUMBER_CHECKED(int, index, Int32, args[3]);
12501
12502   // Get the frame where the debugging is performed.
12503   StackFrame::Id id = UnwrapFrameId(wrapped_id);
12504   JavaScriptFrameIterator frame_it(isolate, id);
12505   JavaScriptFrame* frame = frame_it.frame();
12506
12507   // Find the requested scope.
12508   int n = 0;
12509   ScopeIterator it(isolate, frame, inlined_jsframe_index);
12510   for (; !it.Done() && n < index; it.Next()) {
12511     n++;
12512   }
12513   if (it.Done()) {
12514     return isolate->heap()->undefined_value();
12515   }
12516   Handle<JSObject> details;
12517   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
12518       isolate, details, MaterializeScopeDetails(isolate, &it));
12519   return *details;
12520 }
12521
12522
12523 // Return an array of scope details
12524 // args[0]: number: break id
12525 // args[1]: number: frame index
12526 // args[2]: number: inlined frame index
12527 // args[3]: boolean: ignore nested scopes
12528 //
12529 // The array returned contains arrays with the following information:
12530 // 0: Scope type
12531 // 1: Scope object
12532 RUNTIME_FUNCTION(Runtime_GetAllScopesDetails) {
12533   HandleScope scope(isolate);
12534   ASSERT(args.length() == 3 || args.length() == 4);
12535   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
12536   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
12537
12538   CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
12539   CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
12540
12541   bool ignore_nested_scopes = false;
12542   if (args.length() == 4) {
12543     CONVERT_BOOLEAN_ARG_CHECKED(flag, 3);
12544     ignore_nested_scopes = flag;
12545   }
12546
12547   // Get the frame where the debugging is performed.
12548   StackFrame::Id id = UnwrapFrameId(wrapped_id);
12549   JavaScriptFrameIterator frame_it(isolate, id);
12550   JavaScriptFrame* frame = frame_it.frame();
12551
12552   List<Handle<JSObject> > result(4);
12553   ScopeIterator it(isolate, frame, inlined_jsframe_index, ignore_nested_scopes);
12554   for (; !it.Done(); it.Next()) {
12555     Handle<JSObject> details;
12556     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
12557         isolate, details, MaterializeScopeDetails(isolate, &it));
12558     result.Add(details);
12559   }
12560
12561   Handle<FixedArray> array = isolate->factory()->NewFixedArray(result.length());
12562   for (int i = 0; i < result.length(); ++i) {
12563     array->set(i, *result[i]);
12564   }
12565   return *isolate->factory()->NewJSArrayWithElements(array);
12566 }
12567
12568
12569 RUNTIME_FUNCTION(Runtime_GetFunctionScopeCount) {
12570   HandleScope scope(isolate);
12571   ASSERT(args.length() == 1);
12572
12573   // Check arguments.
12574   CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
12575
12576   // Count the visible scopes.
12577   int n = 0;
12578   for (ScopeIterator it(isolate, fun); !it.Done(); it.Next()) {
12579     n++;
12580   }
12581
12582   return Smi::FromInt(n);
12583 }
12584
12585
12586 RUNTIME_FUNCTION(Runtime_GetFunctionScopeDetails) {
12587   HandleScope scope(isolate);
12588   ASSERT(args.length() == 2);
12589
12590   // Check arguments.
12591   CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
12592   CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
12593
12594   // Find the requested scope.
12595   int n = 0;
12596   ScopeIterator it(isolate, fun);
12597   for (; !it.Done() && n < index; it.Next()) {
12598     n++;
12599   }
12600   if (it.Done()) {
12601     return isolate->heap()->undefined_value();
12602   }
12603
12604   Handle<JSObject> details;
12605   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
12606       isolate, details, MaterializeScopeDetails(isolate, &it));
12607   return *details;
12608 }
12609
12610
12611 static bool SetScopeVariableValue(ScopeIterator* it, int index,
12612                                   Handle<String> variable_name,
12613                                   Handle<Object> new_value) {
12614   for (int n = 0; !it->Done() && n < index; it->Next()) {
12615     n++;
12616   }
12617   if (it->Done()) {
12618     return false;
12619   }
12620   return it->SetVariableValue(variable_name, new_value);
12621 }
12622
12623
12624 // Change variable value in closure or local scope
12625 // args[0]: number or JsFunction: break id or function
12626 // args[1]: number: frame index (when arg[0] is break id)
12627 // args[2]: number: inlined frame index (when arg[0] is break id)
12628 // args[3]: number: scope index
12629 // args[4]: string: variable name
12630 // args[5]: object: new value
12631 //
12632 // Return true if success and false otherwise
12633 RUNTIME_FUNCTION(Runtime_SetScopeVariableValue) {
12634   HandleScope scope(isolate);
12635   ASSERT(args.length() == 6);
12636
12637   // Check arguments.
12638   CONVERT_NUMBER_CHECKED(int, index, Int32, args[3]);
12639   CONVERT_ARG_HANDLE_CHECKED(String, variable_name, 4);
12640   CONVERT_ARG_HANDLE_CHECKED(Object, new_value, 5);
12641
12642   bool res;
12643   if (args[0]->IsNumber()) {
12644     CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
12645     RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
12646
12647     CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
12648     CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
12649
12650     // Get the frame where the debugging is performed.
12651     StackFrame::Id id = UnwrapFrameId(wrapped_id);
12652     JavaScriptFrameIterator frame_it(isolate, id);
12653     JavaScriptFrame* frame = frame_it.frame();
12654
12655     ScopeIterator it(isolate, frame, inlined_jsframe_index);
12656     res = SetScopeVariableValue(&it, index, variable_name, new_value);
12657   } else {
12658     CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
12659     ScopeIterator it(isolate, fun);
12660     res = SetScopeVariableValue(&it, index, variable_name, new_value);
12661   }
12662
12663   return isolate->heap()->ToBoolean(res);
12664 }
12665
12666
12667 RUNTIME_FUNCTION(Runtime_DebugPrintScopes) {
12668   HandleScope scope(isolate);
12669   ASSERT(args.length() == 0);
12670
12671 #ifdef DEBUG
12672   // Print the scopes for the top frame.
12673   StackFrameLocator locator(isolate);
12674   JavaScriptFrame* frame = locator.FindJavaScriptFrame(0);
12675   for (ScopeIterator it(isolate, frame, 0);
12676        !it.Done();
12677        it.Next()) {
12678     it.DebugPrint();
12679   }
12680 #endif
12681   return isolate->heap()->undefined_value();
12682 }
12683
12684
12685 RUNTIME_FUNCTION(Runtime_GetThreadCount) {
12686   HandleScope scope(isolate);
12687   ASSERT(args.length() == 1);
12688   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
12689   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
12690
12691   // Count all archived V8 threads.
12692   int n = 0;
12693   for (ThreadState* thread =
12694           isolate->thread_manager()->FirstThreadStateInUse();
12695        thread != NULL;
12696        thread = thread->Next()) {
12697     n++;
12698   }
12699
12700   // Total number of threads is current thread and archived threads.
12701   return Smi::FromInt(n + 1);
12702 }
12703
12704
12705 static const int kThreadDetailsCurrentThreadIndex = 0;
12706 static const int kThreadDetailsThreadIdIndex = 1;
12707 static const int kThreadDetailsSize = 2;
12708
12709 // Return an array with thread details
12710 // args[0]: number: break id
12711 // args[1]: number: thread index
12712 //
12713 // The array returned contains the following information:
12714 // 0: Is current thread?
12715 // 1: Thread id
12716 RUNTIME_FUNCTION(Runtime_GetThreadDetails) {
12717   HandleScope scope(isolate);
12718   ASSERT(args.length() == 2);
12719   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
12720   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
12721
12722   CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
12723
12724   // Allocate array for result.
12725   Handle<FixedArray> details =
12726       isolate->factory()->NewFixedArray(kThreadDetailsSize);
12727
12728   // Thread index 0 is current thread.
12729   if (index == 0) {
12730     // Fill the details.
12731     details->set(kThreadDetailsCurrentThreadIndex,
12732                  isolate->heap()->true_value());
12733     details->set(kThreadDetailsThreadIdIndex,
12734                  Smi::FromInt(ThreadId::Current().ToInteger()));
12735   } else {
12736     // Find the thread with the requested index.
12737     int n = 1;
12738     ThreadState* thread =
12739         isolate->thread_manager()->FirstThreadStateInUse();
12740     while (index != n && thread != NULL) {
12741       thread = thread->Next();
12742       n++;
12743     }
12744     if (thread == NULL) {
12745       return isolate->heap()->undefined_value();
12746     }
12747
12748     // Fill the details.
12749     details->set(kThreadDetailsCurrentThreadIndex,
12750                  isolate->heap()->false_value());
12751     details->set(kThreadDetailsThreadIdIndex,
12752                  Smi::FromInt(thread->id().ToInteger()));
12753   }
12754
12755   // Convert to JS array and return.
12756   return *isolate->factory()->NewJSArrayWithElements(details);
12757 }
12758
12759
12760 // Sets the disable break state
12761 // args[0]: disable break state
12762 RUNTIME_FUNCTION(Runtime_SetDisableBreak) {
12763   HandleScope scope(isolate);
12764   ASSERT(args.length() == 1);
12765   CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 0);
12766   isolate->debug()->set_disable_break(disable_break);
12767   return  isolate->heap()->undefined_value();
12768 }
12769
12770
12771 static bool IsPositionAlignmentCodeCorrect(int alignment) {
12772   return alignment == STATEMENT_ALIGNED || alignment == BREAK_POSITION_ALIGNED;
12773 }
12774
12775
12776 RUNTIME_FUNCTION(Runtime_GetBreakLocations) {
12777   HandleScope scope(isolate);
12778   ASSERT(args.length() == 2);
12779
12780   CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
12781   CONVERT_NUMBER_CHECKED(int32_t, statement_aligned_code, Int32, args[1]);
12782
12783   if (!IsPositionAlignmentCodeCorrect(statement_aligned_code)) {
12784     return isolate->ThrowIllegalOperation();
12785   }
12786   BreakPositionAlignment alignment =
12787       static_cast<BreakPositionAlignment>(statement_aligned_code);
12788
12789   Handle<SharedFunctionInfo> shared(fun->shared());
12790   // Find the number of break points
12791   Handle<Object> break_locations =
12792       Debug::GetSourceBreakLocations(shared, alignment);
12793   if (break_locations->IsUndefined()) return isolate->heap()->undefined_value();
12794   // Return array as JS array
12795   return *isolate->factory()->NewJSArrayWithElements(
12796       Handle<FixedArray>::cast(break_locations));
12797 }
12798
12799
12800 // Set a break point in a function.
12801 // args[0]: function
12802 // args[1]: number: break source position (within the function source)
12803 // args[2]: number: break point object
12804 RUNTIME_FUNCTION(Runtime_SetFunctionBreakPoint) {
12805   HandleScope scope(isolate);
12806   ASSERT(args.length() == 3);
12807   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
12808   CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
12809   RUNTIME_ASSERT(source_position >= function->shared()->start_position() &&
12810                  source_position <= function->shared()->end_position());
12811   CONVERT_ARG_HANDLE_CHECKED(Object, break_point_object_arg, 2);
12812
12813   // Set break point.
12814   RUNTIME_ASSERT(isolate->debug()->SetBreakPoint(
12815       function, break_point_object_arg, &source_position));
12816
12817   return Smi::FromInt(source_position);
12818 }
12819
12820
12821 // Changes the state of a break point in a script and returns source position
12822 // where break point was set. NOTE: Regarding performance see the NOTE for
12823 // GetScriptFromScriptData.
12824 // args[0]: script to set break point in
12825 // args[1]: number: break source position (within the script source)
12826 // args[2]: number, breakpoint position alignment
12827 // args[3]: number: break point object
12828 RUNTIME_FUNCTION(Runtime_SetScriptBreakPoint) {
12829   HandleScope scope(isolate);
12830   ASSERT(args.length() == 4);
12831   CONVERT_ARG_HANDLE_CHECKED(JSValue, wrapper, 0);
12832   CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
12833   RUNTIME_ASSERT(source_position >= 0);
12834   CONVERT_NUMBER_CHECKED(int32_t, statement_aligned_code, Int32, args[2]);
12835   CONVERT_ARG_HANDLE_CHECKED(Object, break_point_object_arg, 3);
12836
12837   if (!IsPositionAlignmentCodeCorrect(statement_aligned_code)) {
12838     return isolate->ThrowIllegalOperation();
12839   }
12840   BreakPositionAlignment alignment =
12841       static_cast<BreakPositionAlignment>(statement_aligned_code);
12842
12843   // Get the script from the script wrapper.
12844   RUNTIME_ASSERT(wrapper->value()->IsScript());
12845   Handle<Script> script(Script::cast(wrapper->value()));
12846
12847   // Set break point.
12848   if (!isolate->debug()->SetBreakPointForScript(script, break_point_object_arg,
12849                                                 &source_position,
12850                                                 alignment)) {
12851     return isolate->heap()->undefined_value();
12852   }
12853
12854   return Smi::FromInt(source_position);
12855 }
12856
12857
12858 // Clear a break point
12859 // args[0]: number: break point object
12860 RUNTIME_FUNCTION(Runtime_ClearBreakPoint) {
12861   HandleScope scope(isolate);
12862   ASSERT(args.length() == 1);
12863   CONVERT_ARG_HANDLE_CHECKED(Object, break_point_object_arg, 0);
12864
12865   // Clear break point.
12866   isolate->debug()->ClearBreakPoint(break_point_object_arg);
12867
12868   return isolate->heap()->undefined_value();
12869 }
12870
12871
12872 // Change the state of break on exceptions.
12873 // args[0]: Enum value indicating whether to affect caught/uncaught exceptions.
12874 // args[1]: Boolean indicating on/off.
12875 RUNTIME_FUNCTION(Runtime_ChangeBreakOnException) {
12876   HandleScope scope(isolate);
12877   ASSERT(args.length() == 2);
12878   CONVERT_NUMBER_CHECKED(uint32_t, type_arg, Uint32, args[0]);
12879   CONVERT_BOOLEAN_ARG_CHECKED(enable, 1);
12880
12881   // If the number doesn't match an enum value, the ChangeBreakOnException
12882   // function will default to affecting caught exceptions.
12883   ExceptionBreakType type = static_cast<ExceptionBreakType>(type_arg);
12884   // Update break point state.
12885   isolate->debug()->ChangeBreakOnException(type, enable);
12886   return isolate->heap()->undefined_value();
12887 }
12888
12889
12890 // Returns the state of break on exceptions
12891 // args[0]: boolean indicating uncaught exceptions
12892 RUNTIME_FUNCTION(Runtime_IsBreakOnException) {
12893   HandleScope scope(isolate);
12894   ASSERT(args.length() == 1);
12895   CONVERT_NUMBER_CHECKED(uint32_t, type_arg, Uint32, args[0]);
12896
12897   ExceptionBreakType type = static_cast<ExceptionBreakType>(type_arg);
12898   bool result = isolate->debug()->IsBreakOnException(type);
12899   return Smi::FromInt(result);
12900 }
12901
12902
12903 // Prepare for stepping
12904 // args[0]: break id for checking execution state
12905 // args[1]: step action from the enumeration StepAction
12906 // args[2]: number of times to perform the step, for step out it is the number
12907 //          of frames to step down.
12908 RUNTIME_FUNCTION(Runtime_PrepareStep) {
12909   HandleScope scope(isolate);
12910   ASSERT(args.length() == 4);
12911   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
12912   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
12913
12914   if (!args[1]->IsNumber() || !args[2]->IsNumber()) {
12915     return isolate->Throw(isolate->heap()->illegal_argument_string());
12916   }
12917
12918   CONVERT_NUMBER_CHECKED(int, wrapped_frame_id, Int32, args[3]);
12919
12920   StackFrame::Id frame_id;
12921   if (wrapped_frame_id == 0) {
12922     frame_id = StackFrame::NO_ID;
12923   } else {
12924     frame_id = UnwrapFrameId(wrapped_frame_id);
12925   }
12926
12927   // Get the step action and check validity.
12928   StepAction step_action = static_cast<StepAction>(NumberToInt32(args[1]));
12929   if (step_action != StepIn &&
12930       step_action != StepNext &&
12931       step_action != StepOut &&
12932       step_action != StepInMin &&
12933       step_action != StepMin) {
12934     return isolate->Throw(isolate->heap()->illegal_argument_string());
12935   }
12936
12937   if (frame_id != StackFrame::NO_ID && step_action != StepNext &&
12938       step_action != StepMin && step_action != StepOut) {
12939     return isolate->ThrowIllegalOperation();
12940   }
12941
12942   // Get the number of steps.
12943   int step_count = NumberToInt32(args[2]);
12944   if (step_count < 1) {
12945     return isolate->Throw(isolate->heap()->illegal_argument_string());
12946   }
12947
12948   // Clear all current stepping setup.
12949   isolate->debug()->ClearStepping();
12950
12951   // Prepare step.
12952   isolate->debug()->PrepareStep(static_cast<StepAction>(step_action),
12953                                 step_count,
12954                                 frame_id);
12955   return isolate->heap()->undefined_value();
12956 }
12957
12958
12959 // Clear all stepping set by PrepareStep.
12960 RUNTIME_FUNCTION(Runtime_ClearStepping) {
12961   HandleScope scope(isolate);
12962   ASSERT(args.length() == 0);
12963   isolate->debug()->ClearStepping();
12964   return isolate->heap()->undefined_value();
12965 }
12966
12967
12968 // Helper function to find or create the arguments object for
12969 // Runtime_DebugEvaluate.
12970 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeArgumentsObject(
12971     Isolate* isolate,
12972     Handle<JSObject> target,
12973     Handle<JSFunction> function) {
12974   // Do not materialize the arguments object for eval or top-level code.
12975   // Skip if "arguments" is already taken.
12976   if (!function->shared()->is_function() ||
12977       JSReceiver::HasOwnProperty(
12978           target, isolate->factory()->arguments_string())) {
12979     return target;
12980   }
12981
12982   // FunctionGetArguments can't throw an exception.
12983   Handle<JSObject> arguments = Handle<JSObject>::cast(
12984       Accessors::FunctionGetArguments(function));
12985   Handle<String> arguments_str = isolate->factory()->arguments_string();
12986   RETURN_ON_EXCEPTION(
12987       isolate,
12988       Runtime::SetObjectProperty(
12989           isolate, target, arguments_str, arguments, ::NONE, SLOPPY),
12990       JSObject);
12991   return target;
12992 }
12993
12994
12995 // Compile and evaluate source for the given context.
12996 static MaybeHandle<Object> DebugEvaluate(Isolate* isolate,
12997                                          Handle<Context> context,
12998                                          Handle<Object> context_extension,
12999                                          Handle<Object> receiver,
13000                                          Handle<String> source) {
13001   if (context_extension->IsJSObject()) {
13002     Handle<JSObject> extension = Handle<JSObject>::cast(context_extension);
13003     Handle<JSFunction> closure(context->closure(), isolate);
13004     context = isolate->factory()->NewWithContext(closure, context, extension);
13005   }
13006
13007   Handle<JSFunction> eval_fun;
13008   ASSIGN_RETURN_ON_EXCEPTION(
13009       isolate, eval_fun,
13010       Compiler::GetFunctionFromEval(source,
13011                                     context,
13012                                     SLOPPY,
13013                                     NO_PARSE_RESTRICTION,
13014                                     RelocInfo::kNoPosition),
13015       Object);
13016
13017   Handle<Object> result;
13018   ASSIGN_RETURN_ON_EXCEPTION(
13019       isolate, result,
13020       Execution::Call(isolate, eval_fun, receiver, 0, NULL),
13021       Object);
13022
13023   // Skip the global proxy as it has no properties and always delegates to the
13024   // real global object.
13025   if (result->IsJSGlobalProxy()) {
13026     result = Handle<JSObject>(JSObject::cast(result->GetPrototype(isolate)));
13027   }
13028
13029   // Clear the oneshot breakpoints so that the debugger does not step further.
13030   isolate->debug()->ClearStepping();
13031   return result;
13032 }
13033
13034
13035 // Evaluate a piece of JavaScript in the context of a stack frame for
13036 // debugging.  Things that need special attention are:
13037 // - Parameters and stack-allocated locals need to be materialized.  Altered
13038 //   values need to be written back to the stack afterwards.
13039 // - The arguments object needs to materialized.
13040 RUNTIME_FUNCTION(Runtime_DebugEvaluate) {
13041   HandleScope scope(isolate);
13042
13043   // Check the execution state and decode arguments frame and source to be
13044   // evaluated.
13045   ASSERT(args.length() == 6);
13046   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
13047   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
13048
13049   CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
13050   CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
13051   CONVERT_ARG_HANDLE_CHECKED(String, source, 3);
13052   CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 4);
13053   CONVERT_ARG_HANDLE_CHECKED(Object, context_extension, 5);
13054
13055   // Handle the processing of break.
13056   DisableBreak disable_break_scope(isolate->debug(), disable_break);
13057
13058   // Get the frame where the debugging is performed.
13059   StackFrame::Id id = UnwrapFrameId(wrapped_id);
13060   JavaScriptFrameIterator it(isolate, id);
13061   JavaScriptFrame* frame = it.frame();
13062   FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate);
13063   Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction()));
13064
13065   // Traverse the saved contexts chain to find the active context for the
13066   // selected frame.
13067   SaveContext* save = FindSavedContextForFrame(isolate, frame);
13068
13069   SaveContext savex(isolate);
13070   isolate->set_context(*(save->context()));
13071
13072   // Evaluate on the context of the frame.
13073   Handle<Context> context(Context::cast(frame->context()));
13074   ASSERT(!context.is_null());
13075
13076   // Materialize stack locals and the arguments object.
13077   Handle<JSObject> materialized =
13078       isolate->factory()->NewJSObject(isolate->object_function());
13079
13080   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
13081       isolate, materialized,
13082       MaterializeStackLocalsWithFrameInspector(
13083           isolate, materialized, function, &frame_inspector));
13084
13085   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
13086       isolate, materialized,
13087       MaterializeArgumentsObject(isolate, materialized, function));
13088
13089   // Add the materialized object in a with-scope to shadow the stack locals.
13090   context = isolate->factory()->NewWithContext(function, context, materialized);
13091
13092   Handle<Object> receiver(frame->receiver(), isolate);
13093   Handle<Object> result;
13094   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
13095       isolate, result,
13096       DebugEvaluate(isolate, context, context_extension, receiver, source));
13097
13098   // Write back potential changes to materialized stack locals to the stack.
13099   UpdateStackLocalsFromMaterializedObject(
13100       isolate, materialized, function, frame, inlined_jsframe_index);
13101
13102   return *result;
13103 }
13104
13105
13106 RUNTIME_FUNCTION(Runtime_DebugEvaluateGlobal) {
13107   HandleScope scope(isolate);
13108
13109   // Check the execution state and decode arguments frame and source to be
13110   // evaluated.
13111   ASSERT(args.length() == 4);
13112   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
13113   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
13114
13115   CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
13116   CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 2);
13117   CONVERT_ARG_HANDLE_CHECKED(Object, context_extension, 3);
13118
13119   // Handle the processing of break.
13120   DisableBreak disable_break_scope(isolate->debug(), disable_break);
13121
13122   // Enter the top context from before the debugger was invoked.
13123   SaveContext save(isolate);
13124   SaveContext* top = &save;
13125   while (top != NULL && *top->context() == *isolate->debug()->debug_context()) {
13126     top = top->prev();
13127   }
13128   if (top != NULL) {
13129     isolate->set_context(*top->context());
13130   }
13131
13132   // Get the native context now set to the top context from before the
13133   // debugger was invoked.
13134   Handle<Context> context = isolate->native_context();
13135   Handle<Object> receiver = isolate->global_object();
13136   Handle<Object> result;
13137   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
13138       isolate, result,
13139       DebugEvaluate(isolate, context, context_extension, receiver, source));
13140   return *result;
13141 }
13142
13143
13144 RUNTIME_FUNCTION(Runtime_DebugGetLoadedScripts) {
13145   HandleScope scope(isolate);
13146   ASSERT(args.length() == 0);
13147
13148   // Fill the script objects.
13149   Handle<FixedArray> instances = isolate->debug()->GetLoadedScripts();
13150
13151   // Convert the script objects to proper JS objects.
13152   for (int i = 0; i < instances->length(); i++) {
13153     Handle<Script> script = Handle<Script>(Script::cast(instances->get(i)));
13154     // Get the script wrapper in a local handle before calling GetScriptWrapper,
13155     // because using
13156     //   instances->set(i, *GetScriptWrapper(script))
13157     // is unsafe as GetScriptWrapper might call GC and the C++ compiler might
13158     // already have dereferenced the instances handle.
13159     Handle<JSObject> wrapper = Script::GetWrapper(script);
13160     instances->set(i, *wrapper);
13161   }
13162
13163   // Return result as a JS array.
13164   Handle<JSObject> result =
13165       isolate->factory()->NewJSObject(isolate->array_function());
13166   JSArray::SetContent(Handle<JSArray>::cast(result), instances);
13167   return *result;
13168 }
13169
13170
13171 // Helper function used by Runtime_DebugReferencedBy below.
13172 static int DebugReferencedBy(HeapIterator* iterator,
13173                              JSObject* target,
13174                              Object* instance_filter, int max_references,
13175                              FixedArray* instances, int instances_size,
13176                              JSFunction* arguments_function) {
13177   Isolate* isolate = target->GetIsolate();
13178   SealHandleScope shs(isolate);
13179   DisallowHeapAllocation no_allocation;
13180
13181   // Iterate the heap.
13182   int count = 0;
13183   JSObject* last = NULL;
13184   HeapObject* heap_obj = NULL;
13185   while (((heap_obj = iterator->next()) != NULL) &&
13186          (max_references == 0 || count < max_references)) {
13187     // Only look at all JSObjects.
13188     if (heap_obj->IsJSObject()) {
13189       // Skip context extension objects and argument arrays as these are
13190       // checked in the context of functions using them.
13191       JSObject* obj = JSObject::cast(heap_obj);
13192       if (obj->IsJSContextExtensionObject() ||
13193           obj->map()->constructor() == arguments_function) {
13194         continue;
13195       }
13196
13197       // Check if the JS object has a reference to the object looked for.
13198       if (obj->ReferencesObject(target)) {
13199         // Check instance filter if supplied. This is normally used to avoid
13200         // references from mirror objects (see Runtime_IsInPrototypeChain).
13201         if (!instance_filter->IsUndefined()) {
13202           Object* V = obj;
13203           while (true) {
13204             Object* prototype = V->GetPrototype(isolate);
13205             if (prototype->IsNull()) {
13206               break;
13207             }
13208             if (instance_filter == prototype) {
13209               obj = NULL;  // Don't add this object.
13210               break;
13211             }
13212             V = prototype;
13213           }
13214         }
13215
13216         if (obj != NULL) {
13217           // Valid reference found add to instance array if supplied an update
13218           // count.
13219           if (instances != NULL && count < instances_size) {
13220             instances->set(count, obj);
13221           }
13222           last = obj;
13223           count++;
13224         }
13225       }
13226     }
13227   }
13228
13229   // Check for circular reference only. This can happen when the object is only
13230   // referenced from mirrors and has a circular reference in which case the
13231   // object is not really alive and would have been garbage collected if not
13232   // referenced from the mirror.
13233   if (count == 1 && last == target) {
13234     count = 0;
13235   }
13236
13237   // Return the number of referencing objects found.
13238   return count;
13239 }
13240
13241
13242 // Scan the heap for objects with direct references to an object
13243 // args[0]: the object to find references to
13244 // args[1]: constructor function for instances to exclude (Mirror)
13245 // args[2]: the the maximum number of objects to return
13246 RUNTIME_FUNCTION(Runtime_DebugReferencedBy) {
13247   HandleScope scope(isolate);
13248   ASSERT(args.length() == 3);
13249
13250   // Check parameters.
13251   CONVERT_ARG_HANDLE_CHECKED(JSObject, target, 0);
13252   CONVERT_ARG_HANDLE_CHECKED(Object, instance_filter, 1);
13253   RUNTIME_ASSERT(instance_filter->IsUndefined() ||
13254                  instance_filter->IsJSObject());
13255   CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[2]);
13256   RUNTIME_ASSERT(max_references >= 0);
13257
13258
13259   // Get the constructor function for context extension and arguments array.
13260   Handle<JSObject> arguments_boilerplate(
13261       isolate->context()->native_context()->sloppy_arguments_boilerplate());
13262   Handle<JSFunction> arguments_function(
13263       JSFunction::cast(arguments_boilerplate->map()->constructor()));
13264
13265   // Get the number of referencing objects.
13266   int count;
13267   // First perform a full GC in order to avoid dead objects and to make the heap
13268   // iterable.
13269   Heap* heap = isolate->heap();
13270   heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "%DebugConstructedBy");
13271   {
13272     HeapIterator heap_iterator(heap);
13273     count = DebugReferencedBy(&heap_iterator,
13274                               *target, *instance_filter, max_references,
13275                               NULL, 0, *arguments_function);
13276   }
13277
13278   // Allocate an array to hold the result.
13279   Handle<FixedArray> instances = isolate->factory()->NewFixedArray(count);
13280
13281   // Fill the referencing objects.
13282   {
13283     HeapIterator heap_iterator(heap);
13284     count = DebugReferencedBy(&heap_iterator,
13285                               *target, *instance_filter, max_references,
13286                               *instances, count, *arguments_function);
13287   }
13288
13289   // Return result as JS array.
13290   Handle<JSFunction> constructor(
13291       isolate->context()->native_context()->array_function());
13292
13293   Handle<JSObject> result = isolate->factory()->NewJSObject(constructor);
13294   JSArray::SetContent(Handle<JSArray>::cast(result), instances);
13295   return *result;
13296 }
13297
13298
13299 // Helper function used by Runtime_DebugConstructedBy below.
13300 static int DebugConstructedBy(HeapIterator* iterator,
13301                               JSFunction* constructor,
13302                               int max_references,
13303                               FixedArray* instances,
13304                               int instances_size) {
13305   DisallowHeapAllocation no_allocation;
13306
13307   // Iterate the heap.
13308   int count = 0;
13309   HeapObject* heap_obj = NULL;
13310   while (((heap_obj = iterator->next()) != NULL) &&
13311          (max_references == 0 || count < max_references)) {
13312     // Only look at all JSObjects.
13313     if (heap_obj->IsJSObject()) {
13314       JSObject* obj = JSObject::cast(heap_obj);
13315       if (obj->map()->constructor() == constructor) {
13316         // Valid reference found add to instance array if supplied an update
13317         // count.
13318         if (instances != NULL && count < instances_size) {
13319           instances->set(count, obj);
13320         }
13321         count++;
13322       }
13323     }
13324   }
13325
13326   // Return the number of referencing objects found.
13327   return count;
13328 }
13329
13330
13331 // Scan the heap for objects constructed by a specific function.
13332 // args[0]: the constructor to find instances of
13333 // args[1]: the the maximum number of objects to return
13334 RUNTIME_FUNCTION(Runtime_DebugConstructedBy) {
13335   HandleScope scope(isolate);
13336   ASSERT(args.length() == 2);
13337
13338
13339   // Check parameters.
13340   CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, 0);
13341   CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[1]);
13342   RUNTIME_ASSERT(max_references >= 0);
13343
13344   // Get the number of referencing objects.
13345   int count;
13346   // First perform a full GC in order to avoid dead objects and to make the heap
13347   // iterable.
13348   Heap* heap = isolate->heap();
13349   heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "%DebugConstructedBy");
13350   {
13351     HeapIterator heap_iterator(heap);
13352     count = DebugConstructedBy(&heap_iterator,
13353                                *constructor,
13354                                max_references,
13355                                NULL,
13356                                0);
13357   }
13358
13359   // Allocate an array to hold the result.
13360   Handle<FixedArray> instances = isolate->factory()->NewFixedArray(count);
13361
13362   // Fill the referencing objects.
13363   {
13364     HeapIterator heap_iterator2(heap);
13365     count = DebugConstructedBy(&heap_iterator2,
13366                                *constructor,
13367                                max_references,
13368                                *instances,
13369                                count);
13370   }
13371
13372   // Return result as JS array.
13373   Handle<JSFunction> array_function(
13374       isolate->context()->native_context()->array_function());
13375   Handle<JSObject> result = isolate->factory()->NewJSObject(array_function);
13376   JSArray::SetContent(Handle<JSArray>::cast(result), instances);
13377   return *result;
13378 }
13379
13380
13381 // Find the effective prototype object as returned by __proto__.
13382 // args[0]: the object to find the prototype for.
13383 RUNTIME_FUNCTION(Runtime_DebugGetPrototype) {
13384   HandleScope shs(isolate);
13385   ASSERT(args.length() == 1);
13386   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
13387   return *GetPrototypeSkipHiddenPrototypes(isolate, obj);
13388 }
13389
13390
13391 // Patches script source (should be called upon BeforeCompile event).
13392 RUNTIME_FUNCTION(Runtime_DebugSetScriptSource) {
13393   HandleScope scope(isolate);
13394   ASSERT(args.length() == 2);
13395
13396   CONVERT_ARG_HANDLE_CHECKED(JSValue, script_wrapper, 0);
13397   CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
13398
13399   RUNTIME_ASSERT(script_wrapper->value()->IsScript());
13400   Handle<Script> script(Script::cast(script_wrapper->value()));
13401
13402   int compilation_state = script->compilation_state();
13403   RUNTIME_ASSERT(compilation_state == Script::COMPILATION_STATE_INITIAL);
13404   script->set_source(*source);
13405
13406   return isolate->heap()->undefined_value();
13407 }
13408
13409
13410 RUNTIME_FUNCTION(Runtime_SystemBreak) {
13411   SealHandleScope shs(isolate);
13412   ASSERT(args.length() == 0);
13413   OS::DebugBreak();
13414   return isolate->heap()->undefined_value();
13415 }
13416
13417
13418 RUNTIME_FUNCTION(Runtime_DebugDisassembleFunction) {
13419   HandleScope scope(isolate);
13420 #ifdef DEBUG
13421   ASSERT(args.length() == 1);
13422   // Get the function and make sure it is compiled.
13423   CONVERT_ARG_HANDLE_CHECKED(JSFunction, func, 0);
13424   if (!Compiler::EnsureCompiled(func, KEEP_EXCEPTION)) {
13425     return isolate->heap()->exception();
13426   }
13427   func->code()->PrintLn();
13428 #endif  // DEBUG
13429   return isolate->heap()->undefined_value();
13430 }
13431
13432
13433 RUNTIME_FUNCTION(Runtime_DebugDisassembleConstructor) {
13434   HandleScope scope(isolate);
13435 #ifdef DEBUG
13436   ASSERT(args.length() == 1);
13437   // Get the function and make sure it is compiled.
13438   CONVERT_ARG_HANDLE_CHECKED(JSFunction, func, 0);
13439   if (!Compiler::EnsureCompiled(func, KEEP_EXCEPTION)) {
13440     return isolate->heap()->exception();
13441   }
13442   func->shared()->construct_stub()->PrintLn();
13443 #endif  // DEBUG
13444   return isolate->heap()->undefined_value();
13445 }
13446
13447
13448 RUNTIME_FUNCTION(Runtime_FunctionGetInferredName) {
13449   SealHandleScope shs(isolate);
13450   ASSERT(args.length() == 1);
13451
13452   CONVERT_ARG_CHECKED(JSFunction, f, 0);
13453   return f->shared()->inferred_name();
13454 }
13455
13456
13457 static int FindSharedFunctionInfosForScript(HeapIterator* iterator,
13458                                             Script* script,
13459                                             FixedArray* buffer) {
13460   DisallowHeapAllocation no_allocation;
13461   int counter = 0;
13462   int buffer_size = buffer->length();
13463   for (HeapObject* obj = iterator->next();
13464        obj != NULL;
13465        obj = iterator->next()) {
13466     ASSERT(obj != NULL);
13467     if (!obj->IsSharedFunctionInfo()) {
13468       continue;
13469     }
13470     SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj);
13471     if (shared->script() != script) {
13472       continue;
13473     }
13474     if (counter < buffer_size) {
13475       buffer->set(counter, shared);
13476     }
13477     counter++;
13478   }
13479   return counter;
13480 }
13481
13482
13483 // For a script finds all SharedFunctionInfo's in the heap that points
13484 // to this script. Returns JSArray of SharedFunctionInfo wrapped
13485 // in OpaqueReferences.
13486 RUNTIME_FUNCTION(Runtime_LiveEditFindSharedFunctionInfosForScript) {
13487   HandleScope scope(isolate);
13488   CHECK(isolate->debug()->live_edit_enabled());
13489   ASSERT(args.length() == 1);
13490   CONVERT_ARG_CHECKED(JSValue, script_value, 0);
13491
13492   RUNTIME_ASSERT(script_value->value()->IsScript());
13493   Handle<Script> script = Handle<Script>(Script::cast(script_value->value()));
13494
13495   const int kBufferSize = 32;
13496
13497   Handle<FixedArray> array;
13498   array = isolate->factory()->NewFixedArray(kBufferSize);
13499   int number;
13500   Heap* heap = isolate->heap();
13501   {
13502     HeapIterator heap_iterator(heap);
13503     Script* scr = *script;
13504     FixedArray* arr = *array;
13505     number = FindSharedFunctionInfosForScript(&heap_iterator, scr, arr);
13506   }
13507   if (number > kBufferSize) {
13508     array = isolate->factory()->NewFixedArray(number);
13509     HeapIterator heap_iterator(heap);
13510     Script* scr = *script;
13511     FixedArray* arr = *array;
13512     FindSharedFunctionInfosForScript(&heap_iterator, scr, arr);
13513   }
13514
13515   Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements(array);
13516   result->set_length(Smi::FromInt(number));
13517
13518   LiveEdit::WrapSharedFunctionInfos(result);
13519
13520   return *result;
13521 }
13522
13523
13524 // For a script calculates compilation information about all its functions.
13525 // The script source is explicitly specified by the second argument.
13526 // The source of the actual script is not used, however it is important that
13527 // all generated code keeps references to this particular instance of script.
13528 // Returns a JSArray of compilation infos. The array is ordered so that
13529 // each function with all its descendant is always stored in a continues range
13530 // with the function itself going first. The root function is a script function.
13531 RUNTIME_FUNCTION(Runtime_LiveEditGatherCompileInfo) {
13532   HandleScope scope(isolate);
13533   CHECK(isolate->debug()->live_edit_enabled());
13534   ASSERT(args.length() == 2);
13535   CONVERT_ARG_CHECKED(JSValue, script, 0);
13536   CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
13537
13538   RUNTIME_ASSERT(script->value()->IsScript());
13539   Handle<Script> script_handle = Handle<Script>(Script::cast(script->value()));
13540
13541   Handle<JSArray> result;
13542   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
13543       isolate, result, LiveEdit::GatherCompileInfo(script_handle, source));
13544   return *result;
13545 }
13546
13547
13548 // Changes the source of the script to a new_source.
13549 // If old_script_name is provided (i.e. is a String), also creates a copy of
13550 // the script with its original source and sends notification to debugger.
13551 RUNTIME_FUNCTION(Runtime_LiveEditReplaceScript) {
13552   HandleScope scope(isolate);
13553   CHECK(isolate->debug()->live_edit_enabled());
13554   ASSERT(args.length() == 3);
13555   CONVERT_ARG_CHECKED(JSValue, original_script_value, 0);
13556   CONVERT_ARG_HANDLE_CHECKED(String, new_source, 1);
13557   CONVERT_ARG_HANDLE_CHECKED(Object, old_script_name, 2);
13558
13559   RUNTIME_ASSERT(original_script_value->value()->IsScript());
13560   Handle<Script> original_script(Script::cast(original_script_value->value()));
13561
13562   Handle<Object> old_script = LiveEdit::ChangeScriptSource(
13563       original_script,  new_source,  old_script_name);
13564
13565   if (old_script->IsScript()) {
13566     Handle<Script> script_handle = Handle<Script>::cast(old_script);
13567     return *Script::GetWrapper(script_handle);
13568   } else {
13569     return isolate->heap()->null_value();
13570   }
13571 }
13572
13573
13574 RUNTIME_FUNCTION(Runtime_LiveEditFunctionSourceUpdated) {
13575   HandleScope scope(isolate);
13576   CHECK(isolate->debug()->live_edit_enabled());
13577   ASSERT(args.length() == 1);
13578   CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_info, 0);
13579   RUNTIME_ASSERT(SharedInfoWrapper::IsInstance(shared_info));
13580
13581   LiveEdit::FunctionSourceUpdated(shared_info);
13582   return isolate->heap()->undefined_value();
13583 }
13584
13585
13586 // Replaces code of SharedFunctionInfo with a new one.
13587 RUNTIME_FUNCTION(Runtime_LiveEditReplaceFunctionCode) {
13588   HandleScope scope(isolate);
13589   CHECK(isolate->debug()->live_edit_enabled());
13590   ASSERT(args.length() == 2);
13591   CONVERT_ARG_HANDLE_CHECKED(JSArray, new_compile_info, 0);
13592   CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_info, 1);
13593   RUNTIME_ASSERT(SharedInfoWrapper::IsInstance(shared_info));
13594
13595   LiveEdit::ReplaceFunctionCode(new_compile_info, shared_info);
13596   return isolate->heap()->undefined_value();
13597 }
13598
13599
13600 // Connects SharedFunctionInfo to another script.
13601 RUNTIME_FUNCTION(Runtime_LiveEditFunctionSetScript) {
13602   HandleScope scope(isolate);
13603   CHECK(isolate->debug()->live_edit_enabled());
13604   ASSERT(args.length() == 2);
13605   CONVERT_ARG_HANDLE_CHECKED(Object, function_object, 0);
13606   CONVERT_ARG_HANDLE_CHECKED(Object, script_object, 1);
13607
13608   if (function_object->IsJSValue()) {
13609     Handle<JSValue> function_wrapper = Handle<JSValue>::cast(function_object);
13610     if (script_object->IsJSValue()) {
13611       RUNTIME_ASSERT(JSValue::cast(*script_object)->value()->IsScript());
13612       Script* script = Script::cast(JSValue::cast(*script_object)->value());
13613       script_object = Handle<Object>(script, isolate);
13614     }
13615     RUNTIME_ASSERT(function_wrapper->value()->IsSharedFunctionInfo());
13616     LiveEdit::SetFunctionScript(function_wrapper, script_object);
13617   } else {
13618     // Just ignore this. We may not have a SharedFunctionInfo for some functions
13619     // and we check it in this function.
13620   }
13621
13622   return isolate->heap()->undefined_value();
13623 }
13624
13625
13626 // In a code of a parent function replaces original function as embedded object
13627 // with a substitution one.
13628 RUNTIME_FUNCTION(Runtime_LiveEditReplaceRefToNestedFunction) {
13629   HandleScope scope(isolate);
13630   CHECK(isolate->debug()->live_edit_enabled());
13631   ASSERT(args.length() == 3);
13632
13633   CONVERT_ARG_HANDLE_CHECKED(JSValue, parent_wrapper, 0);
13634   CONVERT_ARG_HANDLE_CHECKED(JSValue, orig_wrapper, 1);
13635   CONVERT_ARG_HANDLE_CHECKED(JSValue, subst_wrapper, 2);
13636   RUNTIME_ASSERT(parent_wrapper->value()->IsSharedFunctionInfo());
13637   RUNTIME_ASSERT(orig_wrapper->value()->IsSharedFunctionInfo());
13638   RUNTIME_ASSERT(subst_wrapper->value()->IsSharedFunctionInfo());
13639
13640   LiveEdit::ReplaceRefToNestedFunction(
13641       parent_wrapper, orig_wrapper, subst_wrapper);
13642   return isolate->heap()->undefined_value();
13643 }
13644
13645
13646 // Updates positions of a shared function info (first parameter) according
13647 // to script source change. Text change is described in second parameter as
13648 // array of groups of 3 numbers:
13649 // (change_begin, change_end, change_end_new_position).
13650 // Each group describes a change in text; groups are sorted by change_begin.
13651 RUNTIME_FUNCTION(Runtime_LiveEditPatchFunctionPositions) {
13652   HandleScope scope(isolate);
13653   CHECK(isolate->debug()->live_edit_enabled());
13654   ASSERT(args.length() == 2);
13655   CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_array, 0);
13656   CONVERT_ARG_HANDLE_CHECKED(JSArray, position_change_array, 1);
13657   RUNTIME_ASSERT(SharedInfoWrapper::IsInstance(shared_array))
13658
13659   LiveEdit::PatchFunctionPositions(shared_array, position_change_array);
13660   return isolate->heap()->undefined_value();
13661 }
13662
13663
13664 // For array of SharedFunctionInfo's (each wrapped in JSValue)
13665 // checks that none of them have activations on stacks (of any thread).
13666 // Returns array of the same length with corresponding results of
13667 // LiveEdit::FunctionPatchabilityStatus type.
13668 RUNTIME_FUNCTION(Runtime_LiveEditCheckAndDropActivations) {
13669   HandleScope scope(isolate);
13670   CHECK(isolate->debug()->live_edit_enabled());
13671   ASSERT(args.length() == 2);
13672   CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_array, 0);
13673   CONVERT_BOOLEAN_ARG_CHECKED(do_drop, 1);
13674   RUNTIME_ASSERT(shared_array->length()->IsSmi());
13675   int array_length = Smi::cast(shared_array->length())->value();
13676   for (int i = 0; i < array_length; i++) {
13677     Handle<Object> element =
13678         Object::GetElement(isolate, shared_array, i).ToHandleChecked();
13679     RUNTIME_ASSERT(
13680         element->IsJSValue() &&
13681         Handle<JSValue>::cast(element)->value()->IsSharedFunctionInfo());
13682   }
13683
13684   return *LiveEdit::CheckAndDropActivations(shared_array, do_drop);
13685 }
13686
13687
13688 // Compares 2 strings line-by-line, then token-wise and returns diff in form
13689 // of JSArray of triplets (pos1, pos1_end, pos2_end) describing list
13690 // of diff chunks.
13691 RUNTIME_FUNCTION(Runtime_LiveEditCompareStrings) {
13692   HandleScope scope(isolate);
13693   CHECK(isolate->debug()->live_edit_enabled());
13694   ASSERT(args.length() == 2);
13695   CONVERT_ARG_HANDLE_CHECKED(String, s1, 0);
13696   CONVERT_ARG_HANDLE_CHECKED(String, s2, 1);
13697
13698   return *LiveEdit::CompareStrings(s1, s2);
13699 }
13700
13701
13702 // Restarts a call frame and completely drops all frames above.
13703 // Returns true if successful. Otherwise returns undefined or an error message.
13704 RUNTIME_FUNCTION(Runtime_LiveEditRestartFrame) {
13705   HandleScope scope(isolate);
13706   CHECK(isolate->debug()->live_edit_enabled());
13707   ASSERT(args.length() == 2);
13708   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
13709   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
13710
13711   CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
13712   Heap* heap = isolate->heap();
13713
13714   // Find the relevant frame with the requested index.
13715   StackFrame::Id id = isolate->debug()->break_frame_id();
13716   if (id == StackFrame::NO_ID) {
13717     // If there are no JavaScript stack frames return undefined.
13718     return heap->undefined_value();
13719   }
13720
13721   int count = 0;
13722   JavaScriptFrameIterator it(isolate, id);
13723   for (; !it.done(); it.Advance()) {
13724     if (index < count + it.frame()->GetInlineCount()) break;
13725     count += it.frame()->GetInlineCount();
13726   }
13727   if (it.done()) return heap->undefined_value();
13728
13729   const char* error_message = LiveEdit::RestartFrame(it.frame());
13730   if (error_message) {
13731     return *(isolate->factory()->InternalizeUtf8String(error_message));
13732   }
13733   return heap->true_value();
13734 }
13735
13736
13737 // A testing entry. Returns statement position which is the closest to
13738 // source_position.
13739 RUNTIME_FUNCTION(Runtime_GetFunctionCodePositionFromSource) {
13740   HandleScope scope(isolate);
13741   CHECK(isolate->debug()->live_edit_enabled());
13742   ASSERT(args.length() == 2);
13743   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
13744   CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
13745
13746   Handle<Code> code(function->code(), isolate);
13747
13748   if (code->kind() != Code::FUNCTION &&
13749       code->kind() != Code::OPTIMIZED_FUNCTION) {
13750     return isolate->heap()->undefined_value();
13751   }
13752
13753   RelocIterator it(*code, RelocInfo::ModeMask(RelocInfo::STATEMENT_POSITION));
13754   int closest_pc = 0;
13755   int distance = kMaxInt;
13756   while (!it.done()) {
13757     int statement_position = static_cast<int>(it.rinfo()->data());
13758     // Check if this break point is closer that what was previously found.
13759     if (source_position <= statement_position &&
13760         statement_position - source_position < distance) {
13761       closest_pc =
13762           static_cast<int>(it.rinfo()->pc() - code->instruction_start());
13763       distance = statement_position - source_position;
13764       // Check whether we can't get any closer.
13765       if (distance == 0) break;
13766     }
13767     it.next();
13768   }
13769
13770   return Smi::FromInt(closest_pc);
13771 }
13772
13773
13774 // Calls specified function with or without entering the debugger.
13775 // This is used in unit tests to run code as if debugger is entered or simply
13776 // to have a stack with C++ frame in the middle.
13777 RUNTIME_FUNCTION(Runtime_ExecuteInDebugContext) {
13778   HandleScope scope(isolate);
13779   ASSERT(args.length() == 2);
13780   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
13781   CONVERT_BOOLEAN_ARG_CHECKED(without_debugger, 1);
13782
13783   MaybeHandle<Object> maybe_result;
13784   if (without_debugger) {
13785     maybe_result = Execution::Call(isolate,
13786                                    function,
13787                                    isolate->global_object(),
13788                                    0,
13789                                    NULL);
13790   } else {
13791     DebugScope debug_scope(isolate->debug());
13792     maybe_result = Execution::Call(isolate,
13793                                    function,
13794                                    isolate->global_object(),
13795                                    0,
13796                                    NULL);
13797   }
13798   Handle<Object> result;
13799   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, maybe_result);
13800   return *result;
13801 }
13802
13803
13804 // Sets a v8 flag.
13805 RUNTIME_FUNCTION(Runtime_SetFlags) {
13806   SealHandleScope shs(isolate);
13807   ASSERT(args.length() == 1);
13808   CONVERT_ARG_CHECKED(String, arg, 0);
13809   SmartArrayPointer<char> flags =
13810       arg->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
13811   FlagList::SetFlagsFromString(flags.get(), StrLength(flags.get()));
13812   return isolate->heap()->undefined_value();
13813 }
13814
13815
13816 // Performs a GC.
13817 // Presently, it only does a full GC.
13818 RUNTIME_FUNCTION(Runtime_CollectGarbage) {
13819   SealHandleScope shs(isolate);
13820   ASSERT(args.length() == 1);
13821   isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, "%CollectGarbage");
13822   return isolate->heap()->undefined_value();
13823 }
13824
13825
13826 // Gets the current heap usage.
13827 RUNTIME_FUNCTION(Runtime_GetHeapUsage) {
13828   SealHandleScope shs(isolate);
13829   ASSERT(args.length() == 0);
13830   int usage = static_cast<int>(isolate->heap()->SizeOfObjects());
13831   if (!Smi::IsValid(usage)) {
13832     return *isolate->factory()->NewNumberFromInt(usage);
13833   }
13834   return Smi::FromInt(usage);
13835 }
13836
13837
13838 #ifdef V8_I18N_SUPPORT
13839 RUNTIME_FUNCTION(Runtime_CanonicalizeLanguageTag) {
13840   HandleScope scope(isolate);
13841   Factory* factory = isolate->factory();
13842
13843   ASSERT(args.length() == 1);
13844   CONVERT_ARG_HANDLE_CHECKED(String, locale_id_str, 0);
13845
13846   v8::String::Utf8Value locale_id(v8::Utils::ToLocal(locale_id_str));
13847
13848   // Return value which denotes invalid language tag.
13849   const char* const kInvalidTag = "invalid-tag";
13850
13851   UErrorCode error = U_ZERO_ERROR;
13852   char icu_result[ULOC_FULLNAME_CAPACITY];
13853   int icu_length = 0;
13854
13855   uloc_forLanguageTag(*locale_id, icu_result, ULOC_FULLNAME_CAPACITY,
13856                       &icu_length, &error);
13857   if (U_FAILURE(error) || icu_length == 0) {
13858     return *factory->NewStringFromAsciiChecked(kInvalidTag);
13859   }
13860
13861   char result[ULOC_FULLNAME_CAPACITY];
13862
13863   // Force strict BCP47 rules.
13864   uloc_toLanguageTag(icu_result, result, ULOC_FULLNAME_CAPACITY, TRUE, &error);
13865
13866   if (U_FAILURE(error)) {
13867     return *factory->NewStringFromAsciiChecked(kInvalidTag);
13868   }
13869
13870   return *factory->NewStringFromAsciiChecked(result);
13871 }
13872
13873
13874 RUNTIME_FUNCTION(Runtime_AvailableLocalesOf) {
13875   HandleScope scope(isolate);
13876   Factory* factory = isolate->factory();
13877
13878   ASSERT(args.length() == 1);
13879   CONVERT_ARG_HANDLE_CHECKED(String, service, 0);
13880
13881   const icu::Locale* available_locales = NULL;
13882   int32_t count = 0;
13883
13884   if (service->IsUtf8EqualTo(CStrVector("collator"))) {
13885     available_locales = icu::Collator::getAvailableLocales(count);
13886   } else if (service->IsUtf8EqualTo(CStrVector("numberformat"))) {
13887     available_locales = icu::NumberFormat::getAvailableLocales(count);
13888   } else if (service->IsUtf8EqualTo(CStrVector("dateformat"))) {
13889     available_locales = icu::DateFormat::getAvailableLocales(count);
13890   } else if (service->IsUtf8EqualTo(CStrVector("breakiterator"))) {
13891     available_locales = icu::BreakIterator::getAvailableLocales(count);
13892   }
13893
13894   UErrorCode error = U_ZERO_ERROR;
13895   char result[ULOC_FULLNAME_CAPACITY];
13896   Handle<JSObject> locales =
13897       factory->NewJSObject(isolate->object_function());
13898
13899   for (int32_t i = 0; i < count; ++i) {
13900     const char* icu_name = available_locales[i].getName();
13901
13902     error = U_ZERO_ERROR;
13903     // No need to force strict BCP47 rules.
13904     uloc_toLanguageTag(icu_name, result, ULOC_FULLNAME_CAPACITY, FALSE, &error);
13905     if (U_FAILURE(error)) {
13906       // This shouldn't happen, but lets not break the user.
13907       continue;
13908     }
13909
13910     RETURN_FAILURE_ON_EXCEPTION(isolate,
13911         JSObject::SetOwnPropertyIgnoreAttributes(
13912             locales,
13913             factory->NewStringFromAsciiChecked(result),
13914             factory->NewNumber(i),
13915             NONE));
13916   }
13917
13918   return *locales;
13919 }
13920
13921
13922 RUNTIME_FUNCTION(Runtime_GetDefaultICULocale) {
13923   HandleScope scope(isolate);
13924   Factory* factory = isolate->factory();
13925
13926   ASSERT(args.length() == 0);
13927
13928   icu::Locale default_locale;
13929
13930   // Set the locale
13931   char result[ULOC_FULLNAME_CAPACITY];
13932   UErrorCode status = U_ZERO_ERROR;
13933   uloc_toLanguageTag(
13934       default_locale.getName(), result, ULOC_FULLNAME_CAPACITY, FALSE, &status);
13935   if (U_SUCCESS(status)) {
13936     return *factory->NewStringFromAsciiChecked(result);
13937   }
13938
13939   return *factory->NewStringFromStaticAscii("und");
13940 }
13941
13942
13943 RUNTIME_FUNCTION(Runtime_GetLanguageTagVariants) {
13944   HandleScope scope(isolate);
13945   Factory* factory = isolate->factory();
13946
13947   ASSERT(args.length() == 1);
13948
13949   CONVERT_ARG_HANDLE_CHECKED(JSArray, input, 0);
13950
13951   uint32_t length = static_cast<uint32_t>(input->length()->Number());
13952   // Set some limit to prevent fuzz tests from going OOM.
13953   // Can be bumped when callers' requirements change.
13954   RUNTIME_ASSERT(length < 100);
13955   Handle<FixedArray> output = factory->NewFixedArray(length);
13956   Handle<Name> maximized = factory->NewStringFromStaticAscii("maximized");
13957   Handle<Name> base = factory->NewStringFromStaticAscii("base");
13958   for (unsigned int i = 0; i < length; ++i) {
13959     Handle<Object> locale_id;
13960     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
13961         isolate, locale_id, Object::GetElement(isolate, input, i));
13962     if (!locale_id->IsString()) {
13963       return isolate->Throw(*factory->illegal_argument_string());
13964     }
13965
13966     v8::String::Utf8Value utf8_locale_id(
13967         v8::Utils::ToLocal(Handle<String>::cast(locale_id)));
13968
13969     UErrorCode error = U_ZERO_ERROR;
13970
13971     // Convert from BCP47 to ICU format.
13972     // de-DE-u-co-phonebk -> de_DE@collation=phonebook
13973     char icu_locale[ULOC_FULLNAME_CAPACITY];
13974     int icu_locale_length = 0;
13975     uloc_forLanguageTag(*utf8_locale_id, icu_locale, ULOC_FULLNAME_CAPACITY,
13976                         &icu_locale_length, &error);
13977     if (U_FAILURE(error) || icu_locale_length == 0) {
13978       return isolate->Throw(*factory->illegal_argument_string());
13979     }
13980
13981     // Maximize the locale.
13982     // de_DE@collation=phonebook -> de_Latn_DE@collation=phonebook
13983     char icu_max_locale[ULOC_FULLNAME_CAPACITY];
13984     uloc_addLikelySubtags(
13985         icu_locale, icu_max_locale, ULOC_FULLNAME_CAPACITY, &error);
13986
13987     // Remove extensions from maximized locale.
13988     // de_Latn_DE@collation=phonebook -> de_Latn_DE
13989     char icu_base_max_locale[ULOC_FULLNAME_CAPACITY];
13990     uloc_getBaseName(
13991         icu_max_locale, icu_base_max_locale, ULOC_FULLNAME_CAPACITY, &error);
13992
13993     // Get original name without extensions.
13994     // de_DE@collation=phonebook -> de_DE
13995     char icu_base_locale[ULOC_FULLNAME_CAPACITY];
13996     uloc_getBaseName(
13997         icu_locale, icu_base_locale, ULOC_FULLNAME_CAPACITY, &error);
13998
13999     // Convert from ICU locale format to BCP47 format.
14000     // de_Latn_DE -> de-Latn-DE
14001     char base_max_locale[ULOC_FULLNAME_CAPACITY];
14002     uloc_toLanguageTag(icu_base_max_locale, base_max_locale,
14003                        ULOC_FULLNAME_CAPACITY, FALSE, &error);
14004
14005     // de_DE -> de-DE
14006     char base_locale[ULOC_FULLNAME_CAPACITY];
14007     uloc_toLanguageTag(
14008         icu_base_locale, base_locale, ULOC_FULLNAME_CAPACITY, FALSE, &error);
14009
14010     if (U_FAILURE(error)) {
14011       return isolate->Throw(*factory->illegal_argument_string());
14012     }
14013
14014     Handle<JSObject> result = factory->NewJSObject(isolate->object_function());
14015     RETURN_FAILURE_ON_EXCEPTION(isolate,
14016         JSObject::SetOwnPropertyIgnoreAttributes(
14017             result,
14018             maximized,
14019             factory->NewStringFromAsciiChecked(base_max_locale),
14020             NONE));
14021     RETURN_FAILURE_ON_EXCEPTION(isolate,
14022         JSObject::SetOwnPropertyIgnoreAttributes(
14023             result,
14024             base,
14025             factory->NewStringFromAsciiChecked(base_locale),
14026             NONE));
14027     output->set(i, *result);
14028   }
14029
14030   Handle<JSArray> result = factory->NewJSArrayWithElements(output);
14031   result->set_length(Smi::FromInt(length));
14032   return *result;
14033 }
14034
14035
14036 RUNTIME_FUNCTION(Runtime_IsInitializedIntlObject) {
14037   HandleScope scope(isolate);
14038
14039   ASSERT(args.length() == 1);
14040
14041   CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
14042
14043   if (!input->IsJSObject()) return isolate->heap()->false_value();
14044   Handle<JSObject> obj = Handle<JSObject>::cast(input);
14045
14046   Handle<String> marker = isolate->factory()->intl_initialized_marker_string();
14047   Handle<Object> tag(obj->GetHiddenProperty(marker), isolate);
14048   return isolate->heap()->ToBoolean(!tag->IsTheHole());
14049 }
14050
14051
14052 RUNTIME_FUNCTION(Runtime_IsInitializedIntlObjectOfType) {
14053   HandleScope scope(isolate);
14054
14055   ASSERT(args.length() == 2);
14056
14057   CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
14058   CONVERT_ARG_HANDLE_CHECKED(String, expected_type, 1);
14059
14060   if (!input->IsJSObject()) return isolate->heap()->false_value();
14061   Handle<JSObject> obj = Handle<JSObject>::cast(input);
14062
14063   Handle<String> marker = isolate->factory()->intl_initialized_marker_string();
14064   Handle<Object> tag(obj->GetHiddenProperty(marker), isolate);
14065   return isolate->heap()->ToBoolean(
14066       tag->IsString() && String::cast(*tag)->Equals(*expected_type));
14067 }
14068
14069
14070 RUNTIME_FUNCTION(Runtime_MarkAsInitializedIntlObjectOfType) {
14071   HandleScope scope(isolate);
14072
14073   ASSERT(args.length() == 3);
14074
14075   CONVERT_ARG_HANDLE_CHECKED(JSObject, input, 0);
14076   CONVERT_ARG_HANDLE_CHECKED(String, type, 1);
14077   CONVERT_ARG_HANDLE_CHECKED(JSObject, impl, 2);
14078
14079   Handle<String> marker = isolate->factory()->intl_initialized_marker_string();
14080   JSObject::SetHiddenProperty(input, marker, type);
14081
14082   marker = isolate->factory()->intl_impl_object_string();
14083   JSObject::SetHiddenProperty(input, marker, impl);
14084
14085   return isolate->heap()->undefined_value();
14086 }
14087
14088
14089 RUNTIME_FUNCTION(Runtime_GetImplFromInitializedIntlObject) {
14090   HandleScope scope(isolate);
14091
14092   ASSERT(args.length() == 1);
14093
14094   CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
14095
14096   if (!input->IsJSObject()) {
14097     Vector< Handle<Object> > arguments = HandleVector(&input, 1);
14098     Handle<Object> type_error =
14099         isolate->factory()->NewTypeError("not_intl_object", arguments);
14100     return isolate->Throw(*type_error);
14101   }
14102
14103   Handle<JSObject> obj = Handle<JSObject>::cast(input);
14104
14105   Handle<String> marker = isolate->factory()->intl_impl_object_string();
14106   Handle<Object> impl(obj->GetHiddenProperty(marker), isolate);
14107   if (impl->IsTheHole()) {
14108     Vector< Handle<Object> > arguments = HandleVector(&obj, 1);
14109     Handle<Object> type_error =
14110         isolate->factory()->NewTypeError("not_intl_object", arguments);
14111     return isolate->Throw(*type_error);
14112   }
14113   return *impl;
14114 }
14115
14116
14117 RUNTIME_FUNCTION(Runtime_CreateDateTimeFormat) {
14118   HandleScope scope(isolate);
14119
14120   ASSERT(args.length() == 3);
14121
14122   CONVERT_ARG_HANDLE_CHECKED(String, locale, 0);
14123   CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1);
14124   CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2);
14125
14126   Handle<ObjectTemplateInfo> date_format_template =
14127       I18N::GetTemplate(isolate);
14128
14129   // Create an empty object wrapper.
14130   Handle<JSObject> local_object;
14131   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
14132       isolate, local_object,
14133       Execution::InstantiateObject(date_format_template));
14134
14135   // Set date time formatter as internal field of the resulting JS object.
14136   icu::SimpleDateFormat* date_format = DateFormat::InitializeDateTimeFormat(
14137       isolate, locale, options, resolved);
14138
14139   if (!date_format) return isolate->ThrowIllegalOperation();
14140
14141   local_object->SetInternalField(0, reinterpret_cast<Smi*>(date_format));
14142
14143   RETURN_FAILURE_ON_EXCEPTION(isolate,
14144       JSObject::SetOwnPropertyIgnoreAttributes(
14145           local_object,
14146           isolate->factory()->NewStringFromStaticAscii("dateFormat"),
14147           isolate->factory()->NewStringFromStaticAscii("valid"),
14148           NONE));
14149
14150   // Make object handle weak so we can delete the data format once GC kicks in.
14151   Handle<Object> wrapper = isolate->global_handles()->Create(*local_object);
14152   GlobalHandles::MakeWeak(wrapper.location(),
14153                           reinterpret_cast<void*>(wrapper.location()),
14154                           DateFormat::DeleteDateFormat);
14155   return *local_object;
14156 }
14157
14158
14159 RUNTIME_FUNCTION(Runtime_InternalDateFormat) {
14160   HandleScope scope(isolate);
14161
14162   ASSERT(args.length() == 2);
14163
14164   CONVERT_ARG_HANDLE_CHECKED(JSObject, date_format_holder, 0);
14165   CONVERT_ARG_HANDLE_CHECKED(JSDate, date, 1);
14166
14167   Handle<Object> value;
14168   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
14169       isolate, value, Execution::ToNumber(isolate, date));
14170
14171   icu::SimpleDateFormat* date_format =
14172       DateFormat::UnpackDateFormat(isolate, date_format_holder);
14173   if (!date_format) return isolate->ThrowIllegalOperation();
14174
14175   icu::UnicodeString result;
14176   date_format->format(value->Number(), result);
14177
14178   Handle<String> result_str;
14179   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
14180       isolate, result_str,
14181       isolate->factory()->NewStringFromTwoByte(
14182           Vector<const uint16_t>(
14183               reinterpret_cast<const uint16_t*>(result.getBuffer()),
14184               result.length())));
14185   return *result_str;
14186 }
14187
14188
14189 RUNTIME_FUNCTION(Runtime_InternalDateParse) {
14190   HandleScope scope(isolate);
14191
14192   ASSERT(args.length() == 2);
14193
14194   CONVERT_ARG_HANDLE_CHECKED(JSObject, date_format_holder, 0);
14195   CONVERT_ARG_HANDLE_CHECKED(String, date_string, 1);
14196
14197   v8::String::Utf8Value utf8_date(v8::Utils::ToLocal(date_string));
14198   icu::UnicodeString u_date(icu::UnicodeString::fromUTF8(*utf8_date));
14199   icu::SimpleDateFormat* date_format =
14200       DateFormat::UnpackDateFormat(isolate, date_format_holder);
14201   if (!date_format) return isolate->ThrowIllegalOperation();
14202
14203   UErrorCode status = U_ZERO_ERROR;
14204   UDate date = date_format->parse(u_date, status);
14205   if (U_FAILURE(status)) return isolate->heap()->undefined_value();
14206
14207   Handle<Object> result;
14208   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
14209       isolate, result,
14210       Execution::NewDate(isolate, static_cast<double>(date)));
14211   ASSERT(result->IsJSDate());
14212   return *result;
14213 }
14214
14215
14216 RUNTIME_FUNCTION(Runtime_CreateNumberFormat) {
14217   HandleScope scope(isolate);
14218
14219   ASSERT(args.length() == 3);
14220
14221   CONVERT_ARG_HANDLE_CHECKED(String, locale, 0);
14222   CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1);
14223   CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2);
14224
14225   Handle<ObjectTemplateInfo> number_format_template =
14226       I18N::GetTemplate(isolate);
14227
14228   // Create an empty object wrapper.
14229   Handle<JSObject> local_object;
14230   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
14231       isolate, local_object,
14232       Execution::InstantiateObject(number_format_template));
14233
14234   // Set number formatter as internal field of the resulting JS object.
14235   icu::DecimalFormat* number_format = NumberFormat::InitializeNumberFormat(
14236       isolate, locale, options, resolved);
14237
14238   if (!number_format) return isolate->ThrowIllegalOperation();
14239
14240   local_object->SetInternalField(0, reinterpret_cast<Smi*>(number_format));
14241
14242   RETURN_FAILURE_ON_EXCEPTION(isolate,
14243       JSObject::SetOwnPropertyIgnoreAttributes(
14244           local_object,
14245           isolate->factory()->NewStringFromStaticAscii("numberFormat"),
14246           isolate->factory()->NewStringFromStaticAscii("valid"),
14247           NONE));
14248
14249   Handle<Object> wrapper = isolate->global_handles()->Create(*local_object);
14250   GlobalHandles::MakeWeak(wrapper.location(),
14251                           reinterpret_cast<void*>(wrapper.location()),
14252                           NumberFormat::DeleteNumberFormat);
14253   return *local_object;
14254 }
14255
14256
14257 RUNTIME_FUNCTION(Runtime_InternalNumberFormat) {
14258   HandleScope scope(isolate);
14259
14260   ASSERT(args.length() == 2);
14261
14262   CONVERT_ARG_HANDLE_CHECKED(JSObject, number_format_holder, 0);
14263   CONVERT_ARG_HANDLE_CHECKED(Object, number, 1);
14264
14265   Handle<Object> value;
14266   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
14267       isolate, value, Execution::ToNumber(isolate, number));
14268
14269   icu::DecimalFormat* number_format =
14270       NumberFormat::UnpackNumberFormat(isolate, number_format_holder);
14271   if (!number_format) return isolate->ThrowIllegalOperation();
14272
14273   icu::UnicodeString result;
14274   number_format->format(value->Number(), result);
14275
14276   Handle<String> result_str;
14277   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
14278       isolate, result_str,
14279       isolate->factory()->NewStringFromTwoByte(
14280           Vector<const uint16_t>(
14281               reinterpret_cast<const uint16_t*>(result.getBuffer()),
14282               result.length())));
14283   return *result_str;
14284 }
14285
14286
14287 RUNTIME_FUNCTION(Runtime_InternalNumberParse) {
14288   HandleScope scope(isolate);
14289
14290   ASSERT(args.length() == 2);
14291
14292   CONVERT_ARG_HANDLE_CHECKED(JSObject, number_format_holder, 0);
14293   CONVERT_ARG_HANDLE_CHECKED(String, number_string, 1);
14294
14295   v8::String::Utf8Value utf8_number(v8::Utils::ToLocal(number_string));
14296   icu::UnicodeString u_number(icu::UnicodeString::fromUTF8(*utf8_number));
14297   icu::DecimalFormat* number_format =
14298       NumberFormat::UnpackNumberFormat(isolate, number_format_holder);
14299   if (!number_format) return isolate->ThrowIllegalOperation();
14300
14301   UErrorCode status = U_ZERO_ERROR;
14302   icu::Formattable result;
14303   // ICU 4.6 doesn't support parseCurrency call. We need to wait for ICU49
14304   // to be part of Chrome.
14305   // TODO(cira): Include currency parsing code using parseCurrency call.
14306   // We need to check if the formatter parses all currencies or only the
14307   // one it was constructed with (it will impact the API - how to return ISO
14308   // code and the value).
14309   number_format->parse(u_number, result, status);
14310   if (U_FAILURE(status)) return isolate->heap()->undefined_value();
14311
14312   switch (result.getType()) {
14313   case icu::Formattable::kDouble:
14314     return *isolate->factory()->NewNumber(result.getDouble());
14315   case icu::Formattable::kLong:
14316     return *isolate->factory()->NewNumberFromInt(result.getLong());
14317   case icu::Formattable::kInt64:
14318     return *isolate->factory()->NewNumber(
14319         static_cast<double>(result.getInt64()));
14320   default:
14321     return isolate->heap()->undefined_value();
14322   }
14323 }
14324
14325
14326 RUNTIME_FUNCTION(Runtime_CreateCollator) {
14327   HandleScope scope(isolate);
14328
14329   ASSERT(args.length() == 3);
14330
14331   CONVERT_ARG_HANDLE_CHECKED(String, locale, 0);
14332   CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1);
14333   CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2);
14334
14335   Handle<ObjectTemplateInfo> collator_template = I18N::GetTemplate(isolate);
14336
14337   // Create an empty object wrapper.
14338   Handle<JSObject> local_object;
14339   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
14340       isolate, local_object, Execution::InstantiateObject(collator_template));
14341
14342   // Set collator as internal field of the resulting JS object.
14343   icu::Collator* collator = Collator::InitializeCollator(
14344       isolate, locale, options, resolved);
14345
14346   if (!collator) return isolate->ThrowIllegalOperation();
14347
14348   local_object->SetInternalField(0, reinterpret_cast<Smi*>(collator));
14349
14350   RETURN_FAILURE_ON_EXCEPTION(isolate,
14351       JSObject::SetOwnPropertyIgnoreAttributes(
14352           local_object,
14353           isolate->factory()->NewStringFromStaticAscii("collator"),
14354           isolate->factory()->NewStringFromStaticAscii("valid"),
14355           NONE));
14356
14357   Handle<Object> wrapper = isolate->global_handles()->Create(*local_object);
14358   GlobalHandles::MakeWeak(wrapper.location(),
14359                           reinterpret_cast<void*>(wrapper.location()),
14360                           Collator::DeleteCollator);
14361   return *local_object;
14362 }
14363
14364
14365 RUNTIME_FUNCTION(Runtime_InternalCompare) {
14366   HandleScope scope(isolate);
14367
14368   ASSERT(args.length() == 3);
14369
14370   CONVERT_ARG_HANDLE_CHECKED(JSObject, collator_holder, 0);
14371   CONVERT_ARG_HANDLE_CHECKED(String, string1, 1);
14372   CONVERT_ARG_HANDLE_CHECKED(String, string2, 2);
14373
14374   icu::Collator* collator = Collator::UnpackCollator(isolate, collator_holder);
14375   if (!collator) return isolate->ThrowIllegalOperation();
14376
14377   v8::String::Value string_value1(v8::Utils::ToLocal(string1));
14378   v8::String::Value string_value2(v8::Utils::ToLocal(string2));
14379   const UChar* u_string1 = reinterpret_cast<const UChar*>(*string_value1);
14380   const UChar* u_string2 = reinterpret_cast<const UChar*>(*string_value2);
14381   UErrorCode status = U_ZERO_ERROR;
14382   UCollationResult result = collator->compare(u_string1,
14383                                               string_value1.length(),
14384                                               u_string2,
14385                                               string_value2.length(),
14386                                               status);
14387   if (U_FAILURE(status)) return isolate->ThrowIllegalOperation();
14388
14389   return *isolate->factory()->NewNumberFromInt(result);
14390 }
14391
14392
14393 RUNTIME_FUNCTION(Runtime_StringNormalize) {
14394   HandleScope scope(isolate);
14395   static const UNormalizationMode normalizationForms[] =
14396       { UNORM_NFC, UNORM_NFD, UNORM_NFKC, UNORM_NFKD };
14397
14398   ASSERT(args.length() == 2);
14399
14400   CONVERT_ARG_HANDLE_CHECKED(String, stringValue, 0);
14401   CONVERT_NUMBER_CHECKED(int, form_id, Int32, args[1]);
14402   RUNTIME_ASSERT(form_id >= 0 &&
14403                  static_cast<size_t>(form_id) < ARRAY_SIZE(normalizationForms));
14404
14405   v8::String::Value string_value(v8::Utils::ToLocal(stringValue));
14406   const UChar* u_value = reinterpret_cast<const UChar*>(*string_value);
14407
14408   // TODO(mnita): check Normalizer2 (not available in ICU 46)
14409   UErrorCode status = U_ZERO_ERROR;
14410   icu::UnicodeString result;
14411   icu::Normalizer::normalize(u_value, normalizationForms[form_id], 0,
14412       result, status);
14413   if (U_FAILURE(status)) {
14414     return isolate->heap()->undefined_value();
14415   }
14416
14417   Handle<String> result_str;
14418   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
14419       isolate, result_str,
14420       isolate->factory()->NewStringFromTwoByte(
14421           Vector<const uint16_t>(
14422               reinterpret_cast<const uint16_t*>(result.getBuffer()),
14423               result.length())));
14424   return *result_str;
14425 }
14426
14427
14428 RUNTIME_FUNCTION(Runtime_CreateBreakIterator) {
14429   HandleScope scope(isolate);
14430
14431   ASSERT(args.length() == 3);
14432
14433   CONVERT_ARG_HANDLE_CHECKED(String, locale, 0);
14434   CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1);
14435   CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2);
14436
14437   Handle<ObjectTemplateInfo> break_iterator_template =
14438       I18N::GetTemplate2(isolate);
14439
14440   // Create an empty object wrapper.
14441   Handle<JSObject> local_object;
14442   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
14443       isolate, local_object,
14444       Execution::InstantiateObject(break_iterator_template));
14445
14446   // Set break iterator as internal field of the resulting JS object.
14447   icu::BreakIterator* break_iterator = BreakIterator::InitializeBreakIterator(
14448       isolate, locale, options, resolved);
14449
14450   if (!break_iterator) return isolate->ThrowIllegalOperation();
14451
14452   local_object->SetInternalField(0, reinterpret_cast<Smi*>(break_iterator));
14453   // Make sure that the pointer to adopted text is NULL.
14454   local_object->SetInternalField(1, reinterpret_cast<Smi*>(NULL));
14455
14456   RETURN_FAILURE_ON_EXCEPTION(isolate,
14457       JSObject::SetOwnPropertyIgnoreAttributes(
14458           local_object,
14459           isolate->factory()->NewStringFromStaticAscii("breakIterator"),
14460           isolate->factory()->NewStringFromStaticAscii("valid"),
14461           NONE));
14462
14463   // Make object handle weak so we can delete the break iterator once GC kicks
14464   // in.
14465   Handle<Object> wrapper = isolate->global_handles()->Create(*local_object);
14466   GlobalHandles::MakeWeak(wrapper.location(),
14467                           reinterpret_cast<void*>(wrapper.location()),
14468                           BreakIterator::DeleteBreakIterator);
14469   return *local_object;
14470 }
14471
14472
14473 RUNTIME_FUNCTION(Runtime_BreakIteratorAdoptText) {
14474   HandleScope scope(isolate);
14475
14476   ASSERT(args.length() == 2);
14477
14478   CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
14479   CONVERT_ARG_HANDLE_CHECKED(String, text, 1);
14480
14481   icu::BreakIterator* break_iterator =
14482       BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder);
14483   if (!break_iterator) return isolate->ThrowIllegalOperation();
14484
14485   icu::UnicodeString* u_text = reinterpret_cast<icu::UnicodeString*>(
14486       break_iterator_holder->GetInternalField(1));
14487   delete u_text;
14488
14489   v8::String::Value text_value(v8::Utils::ToLocal(text));
14490   u_text = new icu::UnicodeString(
14491       reinterpret_cast<const UChar*>(*text_value), text_value.length());
14492   break_iterator_holder->SetInternalField(1, reinterpret_cast<Smi*>(u_text));
14493
14494   break_iterator->setText(*u_text);
14495
14496   return isolate->heap()->undefined_value();
14497 }
14498
14499
14500 RUNTIME_FUNCTION(Runtime_BreakIteratorFirst) {
14501   HandleScope scope(isolate);
14502
14503   ASSERT(args.length() == 1);
14504
14505   CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
14506
14507   icu::BreakIterator* break_iterator =
14508       BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder);
14509   if (!break_iterator) return isolate->ThrowIllegalOperation();
14510
14511   return *isolate->factory()->NewNumberFromInt(break_iterator->first());
14512 }
14513
14514
14515 RUNTIME_FUNCTION(Runtime_BreakIteratorNext) {
14516   HandleScope scope(isolate);
14517
14518   ASSERT(args.length() == 1);
14519
14520   CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
14521
14522   icu::BreakIterator* break_iterator =
14523       BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder);
14524   if (!break_iterator) return isolate->ThrowIllegalOperation();
14525
14526   return *isolate->factory()->NewNumberFromInt(break_iterator->next());
14527 }
14528
14529
14530 RUNTIME_FUNCTION(Runtime_BreakIteratorCurrent) {
14531   HandleScope scope(isolate);
14532
14533   ASSERT(args.length() == 1);
14534
14535   CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
14536
14537   icu::BreakIterator* break_iterator =
14538       BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder);
14539   if (!break_iterator) return isolate->ThrowIllegalOperation();
14540
14541   return *isolate->factory()->NewNumberFromInt(break_iterator->current());
14542 }
14543
14544
14545 RUNTIME_FUNCTION(Runtime_BreakIteratorBreakType) {
14546   HandleScope scope(isolate);
14547
14548   ASSERT(args.length() == 1);
14549
14550   CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
14551
14552   icu::BreakIterator* break_iterator =
14553       BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder);
14554   if (!break_iterator) return isolate->ThrowIllegalOperation();
14555
14556   // TODO(cira): Remove cast once ICU fixes base BreakIterator class.
14557   icu::RuleBasedBreakIterator* rule_based_iterator =
14558       static_cast<icu::RuleBasedBreakIterator*>(break_iterator);
14559   int32_t status = rule_based_iterator->getRuleStatus();
14560   // Keep return values in sync with JavaScript BreakType enum.
14561   if (status >= UBRK_WORD_NONE && status < UBRK_WORD_NONE_LIMIT) {
14562     return *isolate->factory()->NewStringFromStaticAscii("none");
14563   } else if (status >= UBRK_WORD_NUMBER && status < UBRK_WORD_NUMBER_LIMIT) {
14564     return *isolate->factory()->NewStringFromStaticAscii("number");
14565   } else if (status >= UBRK_WORD_LETTER && status < UBRK_WORD_LETTER_LIMIT) {
14566     return *isolate->factory()->NewStringFromStaticAscii("letter");
14567   } else if (status >= UBRK_WORD_KANA && status < UBRK_WORD_KANA_LIMIT) {
14568     return *isolate->factory()->NewStringFromStaticAscii("kana");
14569   } else if (status >= UBRK_WORD_IDEO && status < UBRK_WORD_IDEO_LIMIT) {
14570     return *isolate->factory()->NewStringFromStaticAscii("ideo");
14571   } else {
14572     return *isolate->factory()->NewStringFromStaticAscii("unknown");
14573   }
14574 }
14575 #endif  // V8_I18N_SUPPORT
14576
14577
14578 // Finds the script object from the script data. NOTE: This operation uses
14579 // heap traversal to find the function generated for the source position
14580 // for the requested break point. For lazily compiled functions several heap
14581 // traversals might be required rendering this operation as a rather slow
14582 // operation. However for setting break points which is normally done through
14583 // some kind of user interaction the performance is not crucial.
14584 static Handle<Object> Runtime_GetScriptFromScriptName(
14585     Handle<String> script_name) {
14586   // Scan the heap for Script objects to find the script with the requested
14587   // script data.
14588   Handle<Script> script;
14589   Factory* factory = script_name->GetIsolate()->factory();
14590   Heap* heap = script_name->GetHeap();
14591   HeapIterator iterator(heap);
14592   HeapObject* obj = NULL;
14593   while (script.is_null() && ((obj = iterator.next()) != NULL)) {
14594     // If a script is found check if it has the script data requested.
14595     if (obj->IsScript()) {
14596       if (Script::cast(obj)->name()->IsString()) {
14597         if (String::cast(Script::cast(obj)->name())->Equals(*script_name)) {
14598           script = Handle<Script>(Script::cast(obj));
14599         }
14600       }
14601     }
14602   }
14603
14604   // If no script with the requested script data is found return undefined.
14605   if (script.is_null()) return factory->undefined_value();
14606
14607   // Return the script found.
14608   return Script::GetWrapper(script);
14609 }
14610
14611
14612 // Get the script object from script data. NOTE: Regarding performance
14613 // see the NOTE for GetScriptFromScriptData.
14614 // args[0]: script data for the script to find the source for
14615 RUNTIME_FUNCTION(Runtime_GetScript) {
14616   HandleScope scope(isolate);
14617
14618   ASSERT(args.length() == 1);
14619
14620   CONVERT_ARG_CHECKED(String, script_name, 0);
14621
14622   // Find the requested script.
14623   Handle<Object> result =
14624       Runtime_GetScriptFromScriptName(Handle<String>(script_name));
14625   return *result;
14626 }
14627
14628
14629 // Collect the raw data for a stack trace.  Returns an array of 4
14630 // element segments each containing a receiver, function, code and
14631 // native code offset.
14632 RUNTIME_FUNCTION(Runtime_CollectStackTrace) {
14633   HandleScope scope(isolate);
14634   ASSERT(args.length() == 3);
14635   CONVERT_ARG_HANDLE_CHECKED(JSObject, error_object, 0);
14636   CONVERT_ARG_HANDLE_CHECKED(Object, caller, 1);
14637   CONVERT_NUMBER_CHECKED(int32_t, limit, Int32, args[2]);
14638
14639   // Optionally capture a more detailed stack trace for the message.
14640   isolate->CaptureAndSetDetailedStackTrace(error_object);
14641   // Capture a simple stack trace for the stack property.
14642   return *isolate->CaptureSimpleStackTrace(error_object, caller, limit);
14643 }
14644
14645
14646 // Retrieve the stack trace.  This is the raw stack trace that yet has to
14647 // be formatted.  Since we only need this once, clear it afterwards.
14648 RUNTIME_FUNCTION(Runtime_GetAndClearOverflowedStackTrace) {
14649   HandleScope scope(isolate);
14650   ASSERT(args.length() == 1);
14651   CONVERT_ARG_HANDLE_CHECKED(JSObject, error_object, 0);
14652   Handle<String> key = isolate->factory()->hidden_stack_trace_string();
14653   Handle<Object> result(error_object->GetHiddenProperty(key), isolate);
14654   if (result->IsTheHole()) return isolate->heap()->undefined_value();
14655   RUNTIME_ASSERT(result->IsJSArray() || result->IsUndefined());
14656   JSObject::DeleteHiddenProperty(error_object, key);
14657   return *result;
14658 }
14659
14660
14661 // Returns V8 version as a string.
14662 RUNTIME_FUNCTION(Runtime_GetV8Version) {
14663   HandleScope scope(isolate);
14664   ASSERT(args.length() == 0);
14665
14666   const char* version_string = v8::V8::GetVersion();
14667
14668   return *isolate->factory()->NewStringFromAsciiChecked(version_string);
14669 }
14670
14671
14672 RUNTIME_FUNCTION(Runtime_Abort) {
14673   SealHandleScope shs(isolate);
14674   ASSERT(args.length() == 1);
14675   CONVERT_SMI_ARG_CHECKED(message_id, 0);
14676   const char* message = GetBailoutReason(
14677       static_cast<BailoutReason>(message_id));
14678   OS::PrintError("abort: %s\n", message);
14679   isolate->PrintStack(stderr);
14680   OS::Abort();
14681   UNREACHABLE();
14682   return NULL;
14683 }
14684
14685
14686 RUNTIME_FUNCTION(Runtime_AbortJS) {
14687   HandleScope scope(isolate);
14688   ASSERT(args.length() == 1);
14689   CONVERT_ARG_HANDLE_CHECKED(String, message, 0);
14690   OS::PrintError("abort: %s\n", message->ToCString().get());
14691   isolate->PrintStack(stderr);
14692   OS::Abort();
14693   UNREACHABLE();
14694   return NULL;
14695 }
14696
14697
14698 RUNTIME_FUNCTION(Runtime_FlattenString) {
14699   HandleScope scope(isolate);
14700   ASSERT(args.length() == 1);
14701   CONVERT_ARG_HANDLE_CHECKED(String, str, 0);
14702   return *String::Flatten(str);
14703 }
14704
14705
14706 RUNTIME_FUNCTION(Runtime_NotifyContextDisposed) {
14707   HandleScope scope(isolate);
14708   ASSERT(args.length() == 0);
14709   isolate->heap()->NotifyContextDisposed();
14710   return isolate->heap()->undefined_value();
14711 }
14712
14713
14714 RUNTIME_FUNCTION(Runtime_LoadMutableDouble) {
14715   HandleScope scope(isolate);
14716   ASSERT(args.length() == 2);
14717   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
14718   CONVERT_ARG_HANDLE_CHECKED(Smi, index, 1);
14719   RUNTIME_ASSERT((index->value() & 1) == 1);
14720   FieldIndex field_index =
14721       FieldIndex::ForLoadByFieldIndex(object->map(), index->value());
14722   if (field_index.is_inobject()) {
14723     RUNTIME_ASSERT(field_index.property_index() <
14724                    object->map()->inobject_properties());
14725   } else {
14726     RUNTIME_ASSERT(field_index.outobject_array_index() <
14727                    object->properties()->length());
14728   }
14729   Handle<Object> raw_value(object->RawFastPropertyAt(field_index), isolate);
14730   RUNTIME_ASSERT(raw_value->IsNumber() || raw_value->IsUninitialized());
14731   return *Object::NewStorageFor(isolate, raw_value, Representation::Double());
14732 }
14733
14734
14735 RUNTIME_FUNCTION(Runtime_TryMigrateInstance) {
14736   HandleScope scope(isolate);
14737   ASSERT(args.length() == 1);
14738   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
14739   if (!object->IsJSObject()) return Smi::FromInt(0);
14740   Handle<JSObject> js_object = Handle<JSObject>::cast(object);
14741   if (!js_object->map()->is_deprecated()) return Smi::FromInt(0);
14742   // This call must not cause lazy deopts, because it's called from deferred
14743   // code where we can't handle lazy deopts for lack of a suitable bailout
14744   // ID. So we just try migration and signal failure if necessary,
14745   // which will also trigger a deopt.
14746   if (!JSObject::TryMigrateInstance(js_object)) return Smi::FromInt(0);
14747   return *object;
14748 }
14749
14750
14751 RUNTIME_FUNCTION(RuntimeHidden_GetFromCache) {
14752   SealHandleScope shs(isolate);
14753   // This is only called from codegen, so checks might be more lax.
14754   CONVERT_ARG_CHECKED(JSFunctionResultCache, cache, 0);
14755   CONVERT_ARG_CHECKED(Object, key, 1);
14756
14757   {
14758     DisallowHeapAllocation no_alloc;
14759
14760     int finger_index = cache->finger_index();
14761     Object* o = cache->get(finger_index);
14762     if (o == key) {
14763       // The fastest case: hit the same place again.
14764       return cache->get(finger_index + 1);
14765     }
14766
14767     for (int i = finger_index - 2;
14768          i >= JSFunctionResultCache::kEntriesIndex;
14769          i -= 2) {
14770       o = cache->get(i);
14771       if (o == key) {
14772         cache->set_finger_index(i);
14773         return cache->get(i + 1);
14774       }
14775     }
14776
14777     int size = cache->size();
14778     ASSERT(size <= cache->length());
14779
14780     for (int i = size - 2; i > finger_index; i -= 2) {
14781       o = cache->get(i);
14782       if (o == key) {
14783         cache->set_finger_index(i);
14784         return cache->get(i + 1);
14785       }
14786     }
14787   }
14788
14789   // There is no value in the cache.  Invoke the function and cache result.
14790   HandleScope scope(isolate);
14791
14792   Handle<JSFunctionResultCache> cache_handle(cache);
14793   Handle<Object> key_handle(key, isolate);
14794   Handle<Object> value;
14795   {
14796     Handle<JSFunction> factory(JSFunction::cast(
14797           cache_handle->get(JSFunctionResultCache::kFactoryIndex)));
14798     // TODO(antonm): consider passing a receiver when constructing a cache.
14799     Handle<Object> receiver(isolate->native_context()->global_object(),
14800                             isolate);
14801     // This handle is nor shared, nor used later, so it's safe.
14802     Handle<Object> argv[] = { key_handle };
14803     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
14804         isolate, value,
14805         Execution::Call(isolate, factory, receiver, ARRAY_SIZE(argv), argv));
14806   }
14807
14808 #ifdef VERIFY_HEAP
14809   if (FLAG_verify_heap) {
14810     cache_handle->JSFunctionResultCacheVerify();
14811   }
14812 #endif
14813
14814   // Function invocation may have cleared the cache.  Reread all the data.
14815   int finger_index = cache_handle->finger_index();
14816   int size = cache_handle->size();
14817
14818   // If we have spare room, put new data into it, otherwise evict post finger
14819   // entry which is likely to be the least recently used.
14820   int index = -1;
14821   if (size < cache_handle->length()) {
14822     cache_handle->set_size(size + JSFunctionResultCache::kEntrySize);
14823     index = size;
14824   } else {
14825     index = finger_index + JSFunctionResultCache::kEntrySize;
14826     if (index == cache_handle->length()) {
14827       index = JSFunctionResultCache::kEntriesIndex;
14828     }
14829   }
14830
14831   ASSERT(index % 2 == 0);
14832   ASSERT(index >= JSFunctionResultCache::kEntriesIndex);
14833   ASSERT(index < cache_handle->length());
14834
14835   cache_handle->set(index, *key_handle);
14836   cache_handle->set(index + 1, *value);
14837   cache_handle->set_finger_index(index);
14838
14839 #ifdef VERIFY_HEAP
14840   if (FLAG_verify_heap) {
14841     cache_handle->JSFunctionResultCacheVerify();
14842   }
14843 #endif
14844
14845   return *value;
14846 }
14847
14848
14849 RUNTIME_FUNCTION(Runtime_MessageGetStartPosition) {
14850   SealHandleScope shs(isolate);
14851   ASSERT(args.length() == 1);
14852   CONVERT_ARG_CHECKED(JSMessageObject, message, 0);
14853   return Smi::FromInt(message->start_position());
14854 }
14855
14856
14857 RUNTIME_FUNCTION(Runtime_MessageGetScript) {
14858   SealHandleScope shs(isolate);
14859   ASSERT(args.length() == 1);
14860   CONVERT_ARG_CHECKED(JSMessageObject, message, 0);
14861   return message->script();
14862 }
14863
14864
14865 #ifdef DEBUG
14866 // ListNatives is ONLY used by the fuzz-natives.js in debug mode
14867 // Exclude the code in release mode.
14868 RUNTIME_FUNCTION(Runtime_ListNatives) {
14869   HandleScope scope(isolate);
14870   ASSERT(args.length() == 0);
14871 #define COUNT_ENTRY(Name, argc, ressize) + 1
14872   int entry_count = 0
14873       RUNTIME_FUNCTION_LIST(COUNT_ENTRY)
14874       RUNTIME_HIDDEN_FUNCTION_LIST(COUNT_ENTRY)
14875       INLINE_FUNCTION_LIST(COUNT_ENTRY)
14876       INLINE_OPTIMIZED_FUNCTION_LIST(COUNT_ENTRY);
14877 #undef COUNT_ENTRY
14878   Factory* factory = isolate->factory();
14879   Handle<FixedArray> elements = factory->NewFixedArray(entry_count);
14880   int index = 0;
14881   bool inline_runtime_functions = false;
14882 #define ADD_ENTRY(Name, argc, ressize)                                       \
14883   {                                                                          \
14884     HandleScope inner(isolate);                                              \
14885     Handle<String> name;                                                     \
14886     /* Inline runtime functions have an underscore in front of the name. */  \
14887     if (inline_runtime_functions) {                                          \
14888       name = factory->NewStringFromStaticAscii("_" #Name);                   \
14889     } else {                                                                 \
14890       name = factory->NewStringFromStaticAscii(#Name);                       \
14891     }                                                                        \
14892     Handle<FixedArray> pair_elements = factory->NewFixedArray(2);            \
14893     pair_elements->set(0, *name);                                            \
14894     pair_elements->set(1, Smi::FromInt(argc));                               \
14895     Handle<JSArray> pair = factory->NewJSArrayWithElements(pair_elements);   \
14896     elements->set(index++, *pair);                                           \
14897   }
14898   inline_runtime_functions = false;
14899   RUNTIME_FUNCTION_LIST(ADD_ENTRY)
14900   INLINE_OPTIMIZED_FUNCTION_LIST(ADD_ENTRY)
14901   // Calling hidden runtime functions should just throw.
14902   RUNTIME_HIDDEN_FUNCTION_LIST(ADD_ENTRY)
14903   inline_runtime_functions = true;
14904   INLINE_FUNCTION_LIST(ADD_ENTRY)
14905 #undef ADD_ENTRY
14906   ASSERT_EQ(index, entry_count);
14907   Handle<JSArray> result = factory->NewJSArrayWithElements(elements);
14908   return *result;
14909 }
14910 #endif
14911
14912
14913 RUNTIME_FUNCTION(Runtime_IS_VAR) {
14914   UNREACHABLE();  // implemented as macro in the parser
14915   return NULL;
14916 }
14917
14918
14919 #define ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(Name)        \
14920   RUNTIME_FUNCTION(Runtime_Has##Name) {          \
14921     CONVERT_ARG_CHECKED(JSObject, obj, 0);                \
14922     return isolate->heap()->ToBoolean(obj->Has##Name());  \
14923   }
14924
14925 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastSmiElements)
14926 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastObjectElements)
14927 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastSmiOrObjectElements)
14928 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastDoubleElements)
14929 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastHoleyElements)
14930 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(DictionaryElements)
14931 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(SloppyArgumentsElements)
14932 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalArrayElements)
14933 // Properties test sitting with elements tests - not fooling anyone.
14934 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastProperties)
14935
14936 #undef ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION
14937
14938
14939 #define TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION(Type, type, TYPE, ctype, size)     \
14940   RUNTIME_FUNCTION(Runtime_HasExternal##Type##Elements) {             \
14941     CONVERT_ARG_CHECKED(JSObject, obj, 0);                                     \
14942     return isolate->heap()->ToBoolean(obj->HasExternal##Type##Elements());     \
14943   }
14944
14945 TYPED_ARRAYS(TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION)
14946
14947 #undef TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION
14948
14949
14950 #define FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION(Type, type, TYPE, ctype, s)  \
14951   RUNTIME_FUNCTION(Runtime_HasFixed##Type##Elements) {                \
14952     CONVERT_ARG_CHECKED(JSObject, obj, 0);                                     \
14953     return isolate->heap()->ToBoolean(obj->HasFixed##Type##Elements());        \
14954   }
14955
14956 TYPED_ARRAYS(FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION)
14957
14958 #undef FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION
14959
14960
14961 RUNTIME_FUNCTION(Runtime_HaveSameMap) {
14962   SealHandleScope shs(isolate);
14963   ASSERT(args.length() == 2);
14964   CONVERT_ARG_CHECKED(JSObject, obj1, 0);
14965   CONVERT_ARG_CHECKED(JSObject, obj2, 1);
14966   return isolate->heap()->ToBoolean(obj1->map() == obj2->map());
14967 }
14968
14969
14970 RUNTIME_FUNCTION(Runtime_IsJSGlobalProxy) {
14971   SealHandleScope shs(isolate);
14972   ASSERT(args.length() == 1);
14973   CONVERT_ARG_CHECKED(Object, obj, 0);
14974   return isolate->heap()->ToBoolean(obj->IsJSGlobalProxy());
14975 }
14976
14977
14978 RUNTIME_FUNCTION(Runtime_IsObserved) {
14979   SealHandleScope shs(isolate);
14980   ASSERT(args.length() == 1);
14981
14982   if (!args[0]->IsJSReceiver()) return isolate->heap()->false_value();
14983   CONVERT_ARG_CHECKED(JSReceiver, obj, 0);
14984   ASSERT(!obj->IsJSGlobalProxy() || !obj->map()->is_observed());
14985   return isolate->heap()->ToBoolean(obj->map()->is_observed());
14986 }
14987
14988
14989 RUNTIME_FUNCTION(Runtime_SetIsObserved) {
14990   HandleScope scope(isolate);
14991   ASSERT(args.length() == 1);
14992   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, obj, 0);
14993   RUNTIME_ASSERT(!obj->IsJSGlobalProxy());
14994   if (obj->IsJSProxy()) return isolate->heap()->undefined_value();
14995   RUNTIME_ASSERT(!obj->map()->is_observed());
14996
14997   ASSERT(obj->IsJSObject());
14998   JSObject::SetObserved(Handle<JSObject>::cast(obj));
14999   return isolate->heap()->undefined_value();
15000 }
15001
15002
15003 RUNTIME_FUNCTION(Runtime_EnqueueMicrotask) {
15004   HandleScope scope(isolate);
15005   ASSERT(args.length() == 1);
15006   CONVERT_ARG_HANDLE_CHECKED(JSFunction, microtask, 0);
15007   isolate->EnqueueMicrotask(microtask);
15008   return isolate->heap()->undefined_value();
15009 }
15010
15011
15012 RUNTIME_FUNCTION(Runtime_RunMicrotasks) {
15013   HandleScope scope(isolate);
15014   ASSERT(args.length() == 0);
15015   isolate->RunMicrotasks();
15016   return isolate->heap()->undefined_value();
15017 }
15018
15019
15020 RUNTIME_FUNCTION(Runtime_GetObservationState) {
15021   SealHandleScope shs(isolate);
15022   ASSERT(args.length() == 0);
15023   return isolate->heap()->observation_state();
15024 }
15025
15026
15027 RUNTIME_FUNCTION(Runtime_ObservationWeakMapCreate) {
15028   HandleScope scope(isolate);
15029   ASSERT(args.length() == 0);
15030   // TODO(adamk): Currently this runtime function is only called three times per
15031   // isolate. If it's called more often, the map should be moved into the
15032   // strong root list.
15033   Handle<Map> map =
15034       isolate->factory()->NewMap(JS_WEAK_MAP_TYPE, JSWeakMap::kSize);
15035   Handle<JSWeakMap> weakmap =
15036       Handle<JSWeakMap>::cast(isolate->factory()->NewJSObjectFromMap(map));
15037   return *WeakCollectionInitialize(isolate, weakmap);
15038 }
15039
15040
15041 static bool ContextsHaveSameOrigin(Handle<Context> context1,
15042                                    Handle<Context> context2) {
15043   return context1->security_token() == context2->security_token();
15044 }
15045
15046
15047 RUNTIME_FUNCTION(Runtime_ObserverObjectAndRecordHaveSameOrigin) {
15048   HandleScope scope(isolate);
15049   ASSERT(args.length() == 3);
15050   CONVERT_ARG_HANDLE_CHECKED(JSFunction, observer, 0);
15051   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 1);
15052   CONVERT_ARG_HANDLE_CHECKED(JSObject, record, 2);
15053
15054   Handle<Context> observer_context(observer->context()->native_context(),
15055       isolate);
15056   Handle<Context> object_context(object->GetCreationContext());
15057   Handle<Context> record_context(record->GetCreationContext());
15058
15059   return isolate->heap()->ToBoolean(
15060       ContextsHaveSameOrigin(object_context, observer_context) &&
15061       ContextsHaveSameOrigin(object_context, record_context));
15062 }
15063
15064
15065 RUNTIME_FUNCTION(Runtime_ObjectWasCreatedInCurrentOrigin) {
15066   HandleScope scope(isolate);
15067   ASSERT(args.length() == 1);
15068   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
15069
15070   Handle<Context> creation_context(object->GetCreationContext(), isolate);
15071   return isolate->heap()->ToBoolean(
15072       ContextsHaveSameOrigin(creation_context, isolate->native_context()));
15073 }
15074
15075
15076 RUNTIME_FUNCTION(Runtime_GetObjectContextObjectObserve) {
15077   HandleScope scope(isolate);
15078   ASSERT(args.length() == 1);
15079   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
15080
15081   Handle<Context> context(object->GetCreationContext(), isolate);
15082   return context->native_object_observe();
15083 }
15084
15085
15086 RUNTIME_FUNCTION(Runtime_GetObjectContextObjectGetNotifier) {
15087   HandleScope scope(isolate);
15088   ASSERT(args.length() == 1);
15089   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
15090
15091   Handle<Context> context(object->GetCreationContext(), isolate);
15092   return context->native_object_get_notifier();
15093 }
15094
15095
15096 RUNTIME_FUNCTION(Runtime_GetObjectContextNotifierPerformChange) {
15097   HandleScope scope(isolate);
15098   ASSERT(args.length() == 1);
15099   CONVERT_ARG_HANDLE_CHECKED(JSObject, object_info, 0);
15100
15101   Handle<Context> context(object_info->GetCreationContext(), isolate);
15102   return context->native_object_notifier_perform_change();
15103 }
15104
15105
15106 static Object* ArrayConstructorCommon(Isolate* isolate,
15107                                            Handle<JSFunction> constructor,
15108                                            Handle<AllocationSite> site,
15109                                            Arguments* caller_args) {
15110   Factory* factory = isolate->factory();
15111
15112   bool holey = false;
15113   bool can_use_type_feedback = true;
15114   if (caller_args->length() == 1) {
15115     Handle<Object> argument_one = caller_args->at<Object>(0);
15116     if (argument_one->IsSmi()) {
15117       int value = Handle<Smi>::cast(argument_one)->value();
15118       if (value < 0 || value >= JSObject::kInitialMaxFastElementArray) {
15119         // the array is a dictionary in this case.
15120         can_use_type_feedback = false;
15121       } else if (value != 0) {
15122         holey = true;
15123       }
15124     } else {
15125       // Non-smi length argument produces a dictionary
15126       can_use_type_feedback = false;
15127     }
15128   }
15129
15130   Handle<JSArray> array;
15131   if (!site.is_null() && can_use_type_feedback) {
15132     ElementsKind to_kind = site->GetElementsKind();
15133     if (holey && !IsFastHoleyElementsKind(to_kind)) {
15134       to_kind = GetHoleyElementsKind(to_kind);
15135       // Update the allocation site info to reflect the advice alteration.
15136       site->SetElementsKind(to_kind);
15137     }
15138
15139     // We should allocate with an initial map that reflects the allocation site
15140     // advice. Therefore we use AllocateJSObjectFromMap instead of passing
15141     // the constructor.
15142     Handle<Map> initial_map(constructor->initial_map(), isolate);
15143     if (to_kind != initial_map->elements_kind()) {
15144       initial_map = Map::AsElementsKind(initial_map, to_kind);
15145     }
15146
15147     // If we don't care to track arrays of to_kind ElementsKind, then
15148     // don't emit a memento for them.
15149     Handle<AllocationSite> allocation_site;
15150     if (AllocationSite::GetMode(to_kind) == TRACK_ALLOCATION_SITE) {
15151       allocation_site = site;
15152     }
15153
15154     array = Handle<JSArray>::cast(factory->NewJSObjectFromMap(
15155         initial_map, NOT_TENURED, true, allocation_site));
15156   } else {
15157     array = Handle<JSArray>::cast(factory->NewJSObject(constructor));
15158
15159     // We might need to transition to holey
15160     ElementsKind kind = constructor->initial_map()->elements_kind();
15161     if (holey && !IsFastHoleyElementsKind(kind)) {
15162       kind = GetHoleyElementsKind(kind);
15163       JSObject::TransitionElementsKind(array, kind);
15164     }
15165   }
15166
15167   factory->NewJSArrayStorage(array, 0, 0, DONT_INITIALIZE_ARRAY_ELEMENTS);
15168
15169   ElementsKind old_kind = array->GetElementsKind();
15170   RETURN_FAILURE_ON_EXCEPTION(
15171       isolate, ArrayConstructInitializeElements(array, caller_args));
15172   if (!site.is_null() &&
15173       (old_kind != array->GetElementsKind() ||
15174        !can_use_type_feedback)) {
15175     // The arguments passed in caused a transition. This kind of complexity
15176     // can't be dealt with in the inlined hydrogen array constructor case.
15177     // We must mark the allocationsite as un-inlinable.
15178     site->SetDoNotInlineCall();
15179   }
15180   return *array;
15181 }
15182
15183
15184 RUNTIME_FUNCTION(RuntimeHidden_ArrayConstructor) {
15185   HandleScope scope(isolate);
15186   // If we get 2 arguments then they are the stub parameters (constructor, type
15187   // info).  If we get 4, then the first one is a pointer to the arguments
15188   // passed by the caller, and the last one is the length of the arguments
15189   // passed to the caller (redundant, but useful to check on the deoptimizer
15190   // with an assert).
15191   Arguments empty_args(0, NULL);
15192   bool no_caller_args = args.length() == 2;
15193   ASSERT(no_caller_args || args.length() == 4);
15194   int parameters_start = no_caller_args ? 0 : 1;
15195   Arguments* caller_args = no_caller_args
15196       ? &empty_args
15197       : reinterpret_cast<Arguments*>(args[0]);
15198   CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, parameters_start);
15199   CONVERT_ARG_HANDLE_CHECKED(Object, type_info, parameters_start + 1);
15200 #ifdef DEBUG
15201   if (!no_caller_args) {
15202     CONVERT_SMI_ARG_CHECKED(arg_count, parameters_start + 2);
15203     ASSERT(arg_count == caller_args->length());
15204   }
15205 #endif
15206
15207   Handle<AllocationSite> site;
15208   if (!type_info.is_null() &&
15209       *type_info != isolate->heap()->undefined_value()) {
15210     site = Handle<AllocationSite>::cast(type_info);
15211     ASSERT(!site->SitePointsToLiteral());
15212   }
15213
15214   return ArrayConstructorCommon(isolate,
15215                                 constructor,
15216                                 site,
15217                                 caller_args);
15218 }
15219
15220
15221 RUNTIME_FUNCTION(RuntimeHidden_InternalArrayConstructor) {
15222   HandleScope scope(isolate);
15223   Arguments empty_args(0, NULL);
15224   bool no_caller_args = args.length() == 1;
15225   ASSERT(no_caller_args || args.length() == 3);
15226   int parameters_start = no_caller_args ? 0 : 1;
15227   Arguments* caller_args = no_caller_args
15228       ? &empty_args
15229       : reinterpret_cast<Arguments*>(args[0]);
15230   CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, parameters_start);
15231 #ifdef DEBUG
15232   if (!no_caller_args) {
15233     CONVERT_SMI_ARG_CHECKED(arg_count, parameters_start + 1);
15234     ASSERT(arg_count == caller_args->length());
15235   }
15236 #endif
15237   return ArrayConstructorCommon(isolate,
15238                                 constructor,
15239                                 Handle<AllocationSite>::null(),
15240                                 caller_args);
15241 }
15242
15243
15244 RUNTIME_FUNCTION(Runtime_MaxSmi) {
15245   ASSERT(args.length() == 0);
15246   return Smi::FromInt(Smi::kMaxValue);
15247 }
15248
15249
15250 #define RETURN_Float32x4_RESULT(value)                                         \
15251   return *isolate->factory()->NewFloat32x4(value);
15252
15253
15254 #define RETURN_Float64x2_RESULT(value)                                         \
15255   return *isolate->factory()->NewFloat64x2(value);
15256
15257
15258 #define RETURN_Int32x4_RESULT(value)                                           \
15259   return *isolate->factory()->NewInt32x4(value);
15260
15261
15262 RUNTIME_FUNCTION(Runtime_CreateFloat32x4) {
15263   HandleScope scope(isolate);
15264   ASSERT(args.length() == 4);
15265   RUNTIME_ASSERT(args[0]->IsNumber());
15266   RUNTIME_ASSERT(args[1]->IsNumber());
15267   RUNTIME_ASSERT(args[2]->IsNumber());
15268   RUNTIME_ASSERT(args[3]->IsNumber());
15269
15270   float32x4_value_t value;
15271   value.storage[0] = static_cast<float>(args.number_at(0));
15272   value.storage[1] = static_cast<float>(args.number_at(1));
15273   value.storage[2] = static_cast<float>(args.number_at(2));
15274   value.storage[3] = static_cast<float>(args.number_at(3));
15275
15276   RETURN_Float32x4_RESULT(value);
15277 }
15278
15279
15280 RUNTIME_FUNCTION(Runtime_CreateFloat64x2) {
15281   HandleScope scope(isolate);
15282   ASSERT(args.length() == 2);
15283   RUNTIME_ASSERT(args[0]->IsNumber());
15284   RUNTIME_ASSERT(args[1]->IsNumber());
15285
15286   float64x2_value_t value;
15287   value.storage[0] = args.number_at(0);
15288   value.storage[1] = args.number_at(1);
15289
15290   RETURN_Float64x2_RESULT(value);
15291 }
15292
15293
15294 RUNTIME_FUNCTION(Runtime_CreateInt32x4) {
15295   HandleScope scope(isolate);
15296   ASSERT(args.length() == 4);
15297   RUNTIME_ASSERT(args[0]->IsNumber());
15298   RUNTIME_ASSERT(args[1]->IsNumber());
15299   RUNTIME_ASSERT(args[2]->IsNumber());
15300   RUNTIME_ASSERT(args[3]->IsNumber());
15301
15302   int32x4_value_t value;
15303   value.storage[0] = NumberToInt32(args[0]);
15304   value.storage[1] = NumberToInt32(args[1]);
15305   value.storage[2] = NumberToInt32(args[2]);
15306   value.storage[3] = NumberToInt32(args[3]);
15307
15308   RETURN_Int32x4_RESULT(value);
15309 }
15310
15311
15312 // Used to convert between uint32_t and float32 without breaking strict
15313 // aliasing rules.
15314 union float32_uint32 {
15315   float f;
15316   uint32_t u;
15317   float32_uint32(float v) {
15318     f = v;
15319   }
15320   float32_uint32(uint32_t v) {
15321     u = v;
15322   }
15323 };
15324
15325
15326 union float64_uint64 {
15327   double f;
15328   uint64_t u;
15329   float64_uint64(double v) {
15330     f = v;
15331   }
15332   float64_uint64(uint64_t v) {
15333     u = v;
15334   }
15335 };
15336
15337
15338 RUNTIME_FUNCTION(Runtime_Float32x4GetSignMask) {
15339   HandleScope scope(isolate);
15340   ASSERT(args.length() == 1);
15341   CONVERT_ARG_CHECKED(Float32x4, self, 0);
15342   float32_uint32 x(self->x());
15343   float32_uint32 y(self->y());
15344   float32_uint32 z(self->z());
15345   float32_uint32 w(self->w());
15346   uint32_t mx = (x.u & 0x80000000) >> 31;
15347   uint32_t my = (y.u & 0x80000000) >> 31;
15348   uint32_t mz = (z.u & 0x80000000) >> 31;
15349   uint32_t mw = (w.u & 0x80000000) >> 31;
15350   uint32_t value = mx | (my << 1) | (mz << 2) | (mw << 3);
15351   return *isolate->factory()->NewNumberFromUint(value);
15352 }
15353
15354
15355 RUNTIME_FUNCTION(Runtime_Float64x2GetSignMask) {
15356   HandleScope scope(isolate);
15357   ASSERT(args.length() == 1);
15358   CONVERT_ARG_CHECKED(Float64x2, self, 0);
15359   float64_uint64 x(self->x());
15360   float64_uint64 y(self->y());
15361   uint64_t mx = x.u >> 63;
15362   uint64_t my = y.u >> 63;
15363   uint32_t value = static_cast<uint32_t>(mx | (my << 1));
15364   return *isolate->factory()->NewNumberFromUint(value);
15365 }
15366
15367
15368 RUNTIME_FUNCTION(Runtime_Int32x4GetSignMask) {
15369   HandleScope scope(isolate);
15370   ASSERT(args.length() == 1);
15371   CONVERT_ARG_CHECKED(Int32x4, self, 0);
15372   uint32_t mx = (self->x() & 0x80000000) >> 31;
15373   uint32_t my = (self->y() & 0x80000000) >> 31;
15374   uint32_t mz = (self->z() & 0x80000000) >> 31;
15375   uint32_t mw = (self->w() & 0x80000000) >> 31;
15376   uint32_t value = mx | (my << 1) | (mz << 2) | (mw << 3);
15377   return *isolate->factory()->NewNumberFromUint(value);
15378 }
15379
15380
15381 #define LANE_VALUE(VALUE, LANE) \
15382   VALUE->LANE()
15383
15384
15385 #define LANE_FLAG(VALUE, LANE)  \
15386   VALUE->LANE() != 0
15387
15388
15389 #define SIMD128_LANE_ACCESS_FUNCTIONS(V)                      \
15390   V(Float32x4, GetX, NewNumber, x, LANE_VALUE)       \
15391   V(Float32x4, GetY, NewNumber, y, LANE_VALUE)       \
15392   V(Float32x4, GetZ, NewNumber, z, LANE_VALUE)       \
15393   V(Float32x4, GetW, NewNumber, w, LANE_VALUE)       \
15394   V(Float64x2, GetX, NewNumber, x, LANE_VALUE)       \
15395   V(Float64x2, GetY, NewNumber, y, LANE_VALUE)       \
15396   V(Int32x4, GetX, NewNumberFromInt, x, LANE_VALUE)            \
15397   V(Int32x4, GetY, NewNumberFromInt, y, LANE_VALUE)            \
15398   V(Int32x4, GetZ, NewNumberFromInt, z, LANE_VALUE)            \
15399   V(Int32x4, GetW, NewNumberFromInt, w, LANE_VALUE)            \
15400   V(Int32x4, GetFlagX, ToBoolean, x, LANE_FLAG)               \
15401   V(Int32x4, GetFlagY, ToBoolean, y, LANE_FLAG)               \
15402   V(Int32x4, GetFlagZ, ToBoolean, z, LANE_FLAG)               \
15403   V(Int32x4, GetFlagW, ToBoolean, w, LANE_FLAG)
15404
15405
15406 #define DECLARE_SIMD_LANE_ACCESS_FUNCTION(                    \
15407     TYPE, NAME, HEAP_FUNCTION, LANE, ACCESS_FUNCTION)         \
15408 RUNTIME_FUNCTION(Runtime_##TYPE##NAME) {        \
15409   HandleScope scope(isolate);                                 \
15410   ASSERT(args.length() == 1);                                 \
15411                                                               \
15412   CONVERT_ARG_CHECKED(TYPE, a, 0);                            \
15413                                                               \
15414   return *isolate->factory()->HEAP_FUNCTION(                  \
15415       ACCESS_FUNCTION(a, LANE));                              \
15416 }
15417
15418
15419 SIMD128_LANE_ACCESS_FUNCTIONS(DECLARE_SIMD_LANE_ACCESS_FUNCTION)
15420
15421
15422 template<typename T>
15423 static inline T Neg(T a) {
15424   return -a;
15425 }
15426
15427
15428 template<typename T>
15429 static inline T Not(T a) {
15430   return ~a;
15431 }
15432
15433
15434 template<typename T>
15435 static inline T Reciprocal(T a) {
15436   UNIMPLEMENTED();
15437 }
15438
15439
15440 template<>
15441 inline float Reciprocal<float>(float a) {
15442   return 1.0f / a;
15443 }
15444
15445
15446 template<typename T>
15447 static inline T ReciprocalSqrt(T a) {
15448   UNIMPLEMENTED();
15449 }
15450
15451
15452 template<>
15453 inline float ReciprocalSqrt<float>(float a) {
15454   return sqrtf(1.0f / a);
15455 }
15456
15457
15458 template<typename T>
15459 static inline T Sqrt(T a) {
15460   UNIMPLEMENTED();
15461 }
15462
15463
15464 template<>
15465 inline float Sqrt<float>(float a) {
15466   return sqrtf(a);
15467 }
15468
15469
15470 template<>
15471 inline double Sqrt<double>(double a) {
15472   return sqrt(a);
15473 }
15474
15475
15476 #define SIMD128_UNARY_FUNCTIONS(V)                            \
15477   V(Float32x4, Abs)                                           \
15478   V(Float32x4, Neg)                                           \
15479   V(Float32x4, Reciprocal)                                    \
15480   V(Float32x4, ReciprocalSqrt)                                \
15481   V(Float32x4, Sqrt)                                          \
15482   V(Float64x2, Abs)                                           \
15483   V(Float64x2, Neg)                                           \
15484   V(Float64x2, Sqrt)                                          \
15485   V(Int32x4, Neg)                                             \
15486   V(Int32x4, Not)
15487
15488
15489 #define DECLARE_SIMD_UNARY_FUNCTION(TYPE, FUNCTION)           \
15490 RUNTIME_FUNCTION(Runtime_##TYPE##FUNCTION) {    \
15491   HandleScope scope(isolate);                                 \
15492   ASSERT(args.length() == 1);                                 \
15493                                                               \
15494   CONVERT_ARG_CHECKED(TYPE, a, 0);                            \
15495                                                               \
15496   TYPE::value_t result;                                       \
15497   for (int i = 0; i < TYPE::kLanes; i++) {                    \
15498     result.storage[i] = FUNCTION(a->getAt(i));                \
15499   }                                                           \
15500                                                               \
15501   RETURN_##TYPE##_RESULT(result);                             \
15502 }
15503
15504
15505 SIMD128_UNARY_FUNCTIONS(DECLARE_SIMD_UNARY_FUNCTION)
15506
15507
15508 template<typename T1, typename T2>
15509 inline void BitsTo(T1 s, T2* t) {
15510   memcpy(t, &s, sizeof(T2));
15511 }
15512
15513
15514 template<typename T1, typename T2>
15515 inline void To(T1 s, T2* t) {
15516 }
15517
15518
15519 template<>
15520 inline void To<int32_t, float>(int32_t s, float* t) {
15521   *t = static_cast<float>(s);
15522 }
15523
15524
15525 template<>
15526 inline void To<float, int32_t>(float s, int32_t* t) {
15527   *t = DoubleToInt32(static_cast<double>(s));
15528 }
15529
15530
15531 #define SIMD128_CONVERSION_FUNCTIONS(V)                       \
15532   V(Float32x4, BitsTo, Int32x4)                               \
15533   V(Float32x4, To, Int32x4)                                   \
15534   V(Int32x4, BitsTo, Float32x4)                               \
15535   V(Int32x4, To, Float32x4)
15536
15537
15538 #define DECLARE_SIMD_CONVERSION_FUNCTION(                     \
15539     SOURCE_TYPE, FUNCTION, TARGET_TYPE)                       \
15540 RUNTIME_FUNCTION(                               \
15541     Runtime_##SOURCE_TYPE##FUNCTION##TARGET_TYPE) {           \
15542   HandleScope scope(isolate);                                 \
15543   ASSERT(args.length() == 1);                                 \
15544                                                               \
15545   CONVERT_ARG_CHECKED(SOURCE_TYPE, a, 0);                     \
15546                                                               \
15547   TARGET_TYPE::value_t result;                                \
15548   for (int i = 0; i < SOURCE_TYPE::kLanes; i++) {             \
15549     FUNCTION(a->getAt(i), &result.storage[i]);                \
15550   }                                                           \
15551                                                               \
15552   RETURN_##TARGET_TYPE##_RESULT(result);                      \
15553 }
15554
15555
15556 SIMD128_CONVERSION_FUNCTIONS(DECLARE_SIMD_CONVERSION_FUNCTION)
15557
15558
15559 template<typename T>
15560 static inline T Add(T a, T b) {
15561   return a + b;
15562 }
15563
15564
15565 template<typename T>
15566 static inline T Div(T a, T b) {
15567   return a / b;
15568 }
15569
15570
15571 template<typename T>
15572 static inline T Mul(T a, T b) {
15573   return a * b;
15574 }
15575
15576
15577 template<typename T>
15578 static inline T Sub(T a, T b) {
15579   return a - b;
15580 }
15581
15582
15583 template<typename T>
15584 static inline int32_t Equal(T a, T b) {
15585   return a == b ? -1 : 0;
15586 }
15587
15588
15589 template<typename T>
15590 static inline int32_t NotEqual(T a, T b) {
15591   return a != b ? -1 : 0;
15592 }
15593
15594
15595 template<typename T>
15596 static inline int32_t GreaterThanOrEqual(T a, T b) {
15597   return a >= b ? -1 : 0;
15598 }
15599
15600
15601 template<typename T>
15602 static inline int32_t GreaterThan(T a, T b) {
15603   return a > b ? -1 : 0;
15604 }
15605
15606
15607 template<typename T>
15608 static inline int32_t LessThan(T a, T b) {
15609   return a < b ? -1 : 0;
15610 }
15611
15612
15613 template<typename T>
15614 static inline int32_t LessThanOrEqual(T a, T b) {
15615   return a <= b ? -1 : 0;
15616 }
15617
15618
15619 template<typename T>
15620 static inline T And(T a, T b) {
15621   return a & b;
15622 }
15623
15624
15625 template<typename T>
15626 static inline T Or(T a, T b) {
15627   return a | b;
15628 }
15629
15630
15631 template<typename T>
15632 static inline T Xor(T a, T b) {
15633   return a ^ b;
15634 }
15635
15636
15637 #define SIMD128_BINARY_FUNCTIONS(V)                           \
15638   V(Float32x4, Add, Float32x4)                                \
15639   V(Float32x4, Div, Float32x4)                                \
15640   V(Float32x4, Max, Float32x4)                                \
15641   V(Float32x4, Min, Float32x4)                                \
15642   V(Float32x4, Mul, Float32x4)                                \
15643   V(Float32x4, Sub, Float32x4)                                \
15644   V(Float32x4, Equal, Int32x4)                                \
15645   V(Float32x4, NotEqual, Int32x4)                             \
15646   V(Float32x4, GreaterThanOrEqual, Int32x4)                   \
15647   V(Float32x4, GreaterThan, Int32x4)                          \
15648   V(Float32x4, LessThan, Int32x4)                             \
15649   V(Float32x4, LessThanOrEqual, Int32x4)                      \
15650   V(Float64x2, Add, Float64x2)                                \
15651   V(Float64x2, Div, Float64x2)                                \
15652   V(Float64x2, Max, Float64x2)                                \
15653   V(Float64x2, Min, Float64x2)                                \
15654   V(Float64x2, Mul, Float64x2)                                \
15655   V(Float64x2, Sub, Float64x2)                                \
15656   V(Int32x4, Add, Int32x4)                                    \
15657   V(Int32x4, And, Int32x4)                                    \
15658   V(Int32x4, Mul, Int32x4)                                    \
15659   V(Int32x4, Or, Int32x4)                                     \
15660   V(Int32x4, Sub, Int32x4)                                    \
15661   V(Int32x4, Xor, Int32x4)                                    \
15662   V(Int32x4, Equal, Int32x4)                                  \
15663   V(Int32x4, GreaterThan, Int32x4)                            \
15664   V(Int32x4, LessThan, Int32x4)
15665
15666
15667 #define DECLARE_SIMD_BINARY_FUNCTION(                         \
15668     TYPE, FUNCTION, RETURN_TYPE)                              \
15669 RUNTIME_FUNCTION(Runtime_##TYPE##FUNCTION) {    \
15670   HandleScope scope(isolate);                                 \
15671   ASSERT(args.length() == 2);                                 \
15672                                                               \
15673   CONVERT_ARG_CHECKED(TYPE, a, 0);                            \
15674   CONVERT_ARG_CHECKED(TYPE, b, 1);                            \
15675                                                               \
15676   RETURN_TYPE::value_t result;                                \
15677   for (int i = 0; i < TYPE::kLanes; i++) {                    \
15678     result.storage[i] = FUNCTION(a->getAt(i), b->getAt(i));   \
15679   }                                                           \
15680                                                               \
15681   RETURN_##RETURN_TYPE##_RESULT(result);                      \
15682 }
15683
15684
15685 SIMD128_BINARY_FUNCTIONS(DECLARE_SIMD_BINARY_FUNCTION)
15686
15687
15688 #define SIMD128_SHUFFLE_FUNCTIONS(V)                          \
15689   V(Float32x4)                                                \
15690   V(Int32x4)
15691
15692
15693 #define DECLARE_SIMD_SHUFFLE_FUNCTION(TYPE)                   \
15694 RUNTIME_FUNCTION(Runtime_##TYPE##Shuffle) {     \
15695   HandleScope scope(isolate);                                 \
15696   ASSERT(args.length() == 2);                                 \
15697                                                               \
15698   CONVERT_ARG_CHECKED(TYPE, a, 0);                            \
15699   RUNTIME_ASSERT(args[1]->IsNumber());                        \
15700   uint32_t m = NumberToUint32(args[1]);                       \
15701                                                               \
15702   TYPE::value_t result;                                       \
15703   for (int i = 0; i < TYPE::kLanes; i++) {                    \
15704     result.storage[i] = a->getAt((m >> (i * 2)) & 0x3);       \
15705   }                                                           \
15706                                                               \
15707   RETURN_##TYPE##_RESULT(result);                             \
15708 }
15709
15710
15711 SIMD128_SHUFFLE_FUNCTIONS(DECLARE_SIMD_SHUFFLE_FUNCTION)
15712
15713
15714 RUNTIME_FUNCTION(Runtime_Float32x4Scale) {
15715   HandleScope scope(isolate);
15716   ASSERT(args.length() == 2);
15717
15718   CONVERT_ARG_CHECKED(Float32x4, self, 0);
15719   RUNTIME_ASSERT(args[1]->IsNumber());
15720
15721   float _s = static_cast<float>(args.number_at(1));
15722   float32x4_value_t result;
15723   result.storage[0] = self->x() * _s;
15724   result.storage[1] = self->y() * _s;
15725   result.storage[2] = self->z() * _s;
15726   result.storage[3] = self->w() * _s;
15727
15728   RETURN_Float32x4_RESULT(result);
15729 }
15730
15731
15732 RUNTIME_FUNCTION(Runtime_Float64x2Scale) {
15733   HandleScope scope(isolate);
15734   ASSERT(args.length() == 2);
15735
15736   CONVERT_ARG_CHECKED(Float64x2, self, 0);
15737   RUNTIME_ASSERT(args[1]->IsNumber());
15738
15739   double _s = args.number_at(1);
15740   float64x2_value_t result;
15741   result.storage[0] = self->x() * _s;
15742   result.storage[1] = self->y() * _s;
15743
15744   RETURN_Float64x2_RESULT(result);
15745 }
15746
15747
15748 #define ARG_TO_FLOAT32(x) \
15749   CONVERT_DOUBLE_ARG_CHECKED(t, 1); \
15750   float x = static_cast<float>(t);
15751
15752
15753 #define ARG_TO_FLOAT64(x) \
15754   CONVERT_DOUBLE_ARG_CHECKED(x, 1); \
15755
15756
15757 #define ARG_TO_INT32(x) \
15758   RUNTIME_ASSERT(args[1]->IsNumber()); \
15759   int32_t x = NumberToInt32(args[1]);
15760
15761
15762 #define ARG_TO_BOOLEAN(x) \
15763   CONVERT_BOOLEAN_ARG_CHECKED(flag, 1); \
15764   int32_t x = flag ? -1 : 0;
15765
15766 #define SIMD128_SET_LANE_FUNCTIONS(V)                         \
15767   V(Float32x4, WithX, ARG_TO_FLOAT32, 0)                      \
15768   V(Float32x4, WithY, ARG_TO_FLOAT32, 1)                      \
15769   V(Float32x4, WithZ, ARG_TO_FLOAT32, 2)                      \
15770   V(Float32x4, WithW, ARG_TO_FLOAT32, 3)                      \
15771   V(Float64x2, WithX, ARG_TO_FLOAT64, 0)                      \
15772   V(Float64x2, WithY, ARG_TO_FLOAT64, 1)                      \
15773   V(Int32x4, WithX, ARG_TO_INT32, 0)                          \
15774   V(Int32x4, WithY, ARG_TO_INT32, 1)                          \
15775   V(Int32x4, WithZ, ARG_TO_INT32, 2)                          \
15776   V(Int32x4, WithW, ARG_TO_INT32, 3)                          \
15777   V(Int32x4, WithFlagX, ARG_TO_BOOLEAN, 0)                    \
15778   V(Int32x4, WithFlagY, ARG_TO_BOOLEAN, 1)                    \
15779   V(Int32x4, WithFlagZ, ARG_TO_BOOLEAN, 2)                    \
15780   V(Int32x4, WithFlagW, ARG_TO_BOOLEAN, 3)
15781
15782
15783 #define DECLARE_SIMD_SET_LANE_FUNCTION(                       \
15784     TYPE, NAME, ARG_FUNCTION, LANE)                           \
15785 RUNTIME_FUNCTION(Runtime_##TYPE##NAME) {        \
15786   HandleScope scope(isolate);                                 \
15787   ASSERT(args.length() == 2);                                 \
15788                                                               \
15789   CONVERT_ARG_CHECKED(TYPE, a, 0);                            \
15790   ARG_FUNCTION(value);                                        \
15791                                                               \
15792   TYPE::value_t result;                                       \
15793   for (int i = 0; i < TYPE::kLanes; i++) {                    \
15794     if (i != LANE)                                            \
15795       result.storage[i] = a->getAt(i);                        \
15796     else                                                      \
15797       result.storage[i] = value;                              \
15798   }                                                           \
15799                                                               \
15800   RETURN_##TYPE##_RESULT(result);                             \
15801 }
15802
15803
15804 SIMD128_SET_LANE_FUNCTIONS(DECLARE_SIMD_SET_LANE_FUNCTION)
15805
15806
15807 RUNTIME_FUNCTION(Runtime_Float32x4Clamp) {
15808   HandleScope scope(isolate);
15809   ASSERT(args.length() == 3);
15810
15811   CONVERT_ARG_CHECKED(Float32x4, self, 0);
15812   CONVERT_ARG_CHECKED(Float32x4, lo, 1);
15813   CONVERT_ARG_CHECKED(Float32x4, hi, 2);
15814
15815   float32x4_value_t result;
15816   float _x = self->x() > lo->x() ? self->x() : lo->x();
15817   float _y = self->y() > lo->y() ? self->y() : lo->y();
15818   float _z = self->z() > lo->z() ? self->z() : lo->z();
15819   float _w = self->w() > lo->w() ? self->w() : lo->w();
15820   result.storage[0] = _x > hi->x() ? hi->x() : _x;
15821   result.storage[1] = _y > hi->y() ? hi->y() : _y;
15822   result.storage[2] = _z > hi->z() ? hi->z() : _z;
15823   result.storage[3] = _w > hi->w() ? hi->w() : _w;
15824
15825   RETURN_Float32x4_RESULT(result);
15826 }
15827
15828
15829 RUNTIME_FUNCTION(Runtime_Float64x2Clamp) {
15830   HandleScope scope(isolate);
15831   ASSERT(args.length() == 3);
15832
15833   CONVERT_ARG_CHECKED(Float64x2, self, 0);
15834   CONVERT_ARG_CHECKED(Float64x2, lo, 1);
15835   CONVERT_ARG_CHECKED(Float64x2, hi, 2);
15836
15837   float64x2_value_t result;
15838   double _x = self->x() > lo->x() ? self->x() : lo->x();
15839   double _y = self->y() > lo->y() ? self->y() : lo->y();
15840   result.storage[0] = _x > hi->x() ? hi->x() : _x;
15841   result.storage[1] = _y > hi->y() ? hi->y() : _y;
15842
15843   RETURN_Float64x2_RESULT(result);
15844 }
15845
15846
15847 RUNTIME_FUNCTION(Runtime_Float32x4ShuffleMix) {
15848   HandleScope scope(isolate);
15849   ASSERT(args.length() == 3);
15850
15851   CONVERT_ARG_CHECKED(Float32x4, first, 0);
15852   CONVERT_ARG_CHECKED(Float32x4, second, 1);
15853   RUNTIME_ASSERT(args[2]->IsNumber());
15854
15855   uint32_t m = NumberToUint32(args[2]);
15856   float32x4_value_t result;
15857   float data1[4] = { first->x(), first->y(), first->z(), first->w() };
15858   float data2[4] = { second->x(), second->y(), second->z(), second->w() };
15859   result.storage[0] = data1[m & 0x3];
15860   result.storage[1] = data1[(m >> 2) & 0x3];
15861   result.storage[2] = data2[(m >> 4) & 0x3];
15862   result.storage[3] = data2[(m >> 6) & 0x3];
15863
15864   RETURN_Float32x4_RESULT(result);
15865 }
15866
15867
15868 RUNTIME_FUNCTION(Runtime_Int32x4Select) {
15869   HandleScope scope(isolate);
15870   ASSERT(args.length() == 3);
15871
15872   CONVERT_ARG_CHECKED(Int32x4, self, 0);
15873   CONVERT_ARG_CHECKED(Float32x4, tv, 1);
15874   CONVERT_ARG_CHECKED(Float32x4, fv, 2);
15875
15876   uint32_t _maskX = self->x();
15877   uint32_t _maskY = self->y();
15878   uint32_t _maskZ = self->z();
15879   uint32_t _maskW = self->w();
15880   // Extract floats and interpret them as masks.
15881   float32_uint32 tvx(tv->x());
15882   float32_uint32 tvy(tv->y());
15883   float32_uint32 tvz(tv->z());
15884   float32_uint32 tvw(tv->w());
15885   float32_uint32 fvx(fv->x());
15886   float32_uint32 fvy(fv->y());
15887   float32_uint32 fvz(fv->z());
15888   float32_uint32 fvw(fv->w());
15889   // Perform select.
15890   float32_uint32 tempX((_maskX & tvx.u) | (~_maskX & fvx.u));
15891   float32_uint32 tempY((_maskY & tvy.u) | (~_maskY & fvy.u));
15892   float32_uint32 tempZ((_maskZ & tvz.u) | (~_maskZ & fvz.u));
15893   float32_uint32 tempW((_maskW & tvw.u) | (~_maskW & fvw.u));
15894
15895   float32x4_value_t result;
15896   result.storage[0] = tempX.f;
15897   result.storage[1] = tempY.f;
15898   result.storage[2] = tempZ.f;
15899   result.storage[3] = tempW.f;
15900
15901   RETURN_Float32x4_RESULT(result);
15902 }
15903
15904
15905 // ----------------------------------------------------------------------------
15906 // Implementation of Runtime
15907
15908 #define F(name, number_of_args, result_size)                             \
15909   { Runtime::k##name, Runtime::RUNTIME, #name,   \
15910     FUNCTION_ADDR(Runtime_##name), number_of_args, result_size },
15911
15912
15913 #define FH(name, number_of_args, result_size)                             \
15914   { Runtime::kHidden##name, Runtime::RUNTIME_HIDDEN, NULL,   \
15915     FUNCTION_ADDR(RuntimeHidden_##name), number_of_args, result_size },
15916
15917
15918 #define I(name, number_of_args, result_size)                             \
15919   { Runtime::kInline##name, Runtime::INLINE,     \
15920     "_" #name, NULL, number_of_args, result_size },
15921
15922
15923 #define IO(name, number_of_args, result_size) \
15924   { Runtime::kInlineOptimized##name, Runtime::INLINE_OPTIMIZED, \
15925     "_" #name, FUNCTION_ADDR(Runtime_##name), number_of_args, result_size },
15926
15927
15928 static const Runtime::Function kIntrinsicFunctions[] = {
15929   RUNTIME_FUNCTION_LIST(F)
15930   INLINE_OPTIMIZED_FUNCTION_LIST(F)
15931   RUNTIME_HIDDEN_FUNCTION_LIST(FH)
15932   INLINE_FUNCTION_LIST(I)
15933   INLINE_OPTIMIZED_FUNCTION_LIST(IO)
15934 };
15935
15936 #undef IO
15937 #undef I
15938 #undef FH
15939 #undef F
15940
15941
15942 void Runtime::InitializeIntrinsicFunctionNames(Isolate* isolate,
15943                                                Handle<NameDictionary> dict) {
15944   ASSERT(dict->NumberOfElements() == 0);
15945   HandleScope scope(isolate);
15946   for (int i = 0; i < kNumFunctions; ++i) {
15947     const char* name = kIntrinsicFunctions[i].name;
15948     if (name == NULL) continue;
15949     Handle<NameDictionary> new_dict = NameDictionary::Add(
15950         dict,
15951         isolate->factory()->InternalizeUtf8String(name),
15952         Handle<Smi>(Smi::FromInt(i), isolate),
15953         PropertyDetails(NONE, NORMAL, Representation::None()));
15954     // The dictionary does not need to grow.
15955     CHECK(new_dict.is_identical_to(dict));
15956   }
15957 }
15958
15959
15960 const Runtime::Function* Runtime::FunctionForName(Handle<String> name) {
15961   Heap* heap = name->GetHeap();
15962   int entry = heap->intrinsic_function_names()->FindEntry(name);
15963   if (entry != kNotFound) {
15964     Object* smi_index = heap->intrinsic_function_names()->ValueAt(entry);
15965     int function_index = Smi::cast(smi_index)->value();
15966     return &(kIntrinsicFunctions[function_index]);
15967   }
15968   return NULL;
15969 }
15970
15971
15972 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) {
15973   return &(kIntrinsicFunctions[static_cast<int>(id)]);
15974 }
15975
15976 } }  // namespace v8::internal