Upstream version 9.38.207.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/base/cpu.h"
15 #include "src/base/platform/platform.h"
16 #include "src/bootstrapper.h"
17 #include "src/codegen.h"
18 #include "src/compilation-cache.h"
19 #include "src/compiler.h"
20 #include "src/conversions.h"
21 #include "src/cpu-profiler.h"
22 #include "src/date.h"
23 #include "src/dateparser-inl.h"
24 #include "src/debug.h"
25 #include "src/deoptimizer.h"
26 #include "src/execution.h"
27 #include "src/full-codegen.h"
28 #include "src/global-handles.h"
29 #include "src/isolate-inl.h"
30 #include "src/json-parser.h"
31 #include "src/json-stringifier.h"
32 #include "src/jsregexp-inl.h"
33 #include "src/jsregexp.h"
34 #include "src/liveedit.h"
35 #include "src/misc-intrinsics.h"
36 #include "src/parser.h"
37 #include "src/prototype.h"
38 #include "src/runtime.h"
39 #include "src/runtime-profiler.h"
40 #include "src/scopeinfo.h"
41 #include "src/smart-pointers.h"
42 #include "src/string-search.h"
43 #include "src/stub-cache.h"
44 #include "src/uri.h"
45 #include "src/utils.h"
46 #include "src/v8threads.h"
47 #include "src/vm-state-inl.h"
48 #include "third_party/fdlibm/fdlibm.h"
49
50 #ifdef V8_I18N_SUPPORT
51 #include "src/i18n.h"
52 #include "unicode/brkiter.h"
53 #include "unicode/calendar.h"
54 #include "unicode/coll.h"
55 #include "unicode/curramt.h"
56 #include "unicode/datefmt.h"
57 #include "unicode/dcfmtsym.h"
58 #include "unicode/decimfmt.h"
59 #include "unicode/dtfmtsym.h"
60 #include "unicode/dtptngen.h"
61 #include "unicode/locid.h"
62 #include "unicode/numfmt.h"
63 #include "unicode/numsys.h"
64 #include "unicode/rbbi.h"
65 #include "unicode/smpdtfmt.h"
66 #include "unicode/timezone.h"
67 #include "unicode/uchar.h"
68 #include "unicode/ucol.h"
69 #include "unicode/ucurr.h"
70 #include "unicode/uloc.h"
71 #include "unicode/unum.h"
72 #include "unicode/uversion.h"
73 #endif
74
75 #ifndef _STLP_VENDOR_CSTD
76 // STLPort doesn't import fpclassify and isless into the std namespace.
77 using std::fpclassify;
78 using std::isless;
79 #endif
80
81 namespace v8 {
82 namespace internal {
83
84
85 #define RUNTIME_ASSERT(value) \
86   if (!(value)) return isolate->ThrowIllegalOperation();
87
88 #define RUNTIME_ASSERT_HANDLIFIED(value, T)                          \
89   if (!(value)) {                                                    \
90     isolate->ThrowIllegalOperation();                                \
91     return MaybeHandle<T>();                                         \
92   }
93
94 // Cast the given object to a value of the specified type and store
95 // it in a variable with the given name.  If the object is not of the
96 // expected type call IllegalOperation and return.
97 #define CONVERT_ARG_CHECKED(Type, name, index)                       \
98   RUNTIME_ASSERT(args[index]->Is##Type());                           \
99   Type* name = Type::cast(args[index]);
100
101 #define CONVERT_ARG_HANDLE_CHECKED(Type, name, index)                \
102   RUNTIME_ASSERT(args[index]->Is##Type());                           \
103   Handle<Type> name = args.at<Type>(index);
104
105 #define CONVERT_NUMBER_ARG_HANDLE_CHECKED(name, index)               \
106   RUNTIME_ASSERT(args[index]->IsNumber());                           \
107   Handle<Object> name = args.at<Object>(index);
108
109 // Cast the given object to a boolean and store it in a variable with
110 // the given name.  If the object is not a boolean call IllegalOperation
111 // and return.
112 #define CONVERT_BOOLEAN_ARG_CHECKED(name, index)                     \
113   RUNTIME_ASSERT(args[index]->IsBoolean());                          \
114   bool name = args[index]->IsTrue();
115
116 // Cast the given argument to a Smi and store its value in an int variable
117 // with the given name.  If the argument is not a Smi call IllegalOperation
118 // and return.
119 #define CONVERT_SMI_ARG_CHECKED(name, index)                         \
120   RUNTIME_ASSERT(args[index]->IsSmi());                              \
121   int name = args.smi_at(index);
122
123 // Cast the given argument to a double and store it in a variable with
124 // the given name.  If the argument is not a number (as opposed to
125 // the number not-a-number) call IllegalOperation and return.
126 #define CONVERT_DOUBLE_ARG_CHECKED(name, index)                      \
127   RUNTIME_ASSERT(args[index]->IsNumber());                           \
128   double name = args.number_at(index);
129
130 // Call the specified converter on the object *comand store the result in
131 // a variable of the specified type with the given name.  If the
132 // object is not a Number call IllegalOperation and return.
133 #define CONVERT_NUMBER_CHECKED(type, name, Type, obj)                \
134   RUNTIME_ASSERT(obj->IsNumber());                                   \
135   type name = NumberTo##Type(obj);
136
137
138 // Cast the given argument to PropertyDetails and store its value in a
139 // variable with the given name.  If the argument is not a Smi call
140 // IllegalOperation and return.
141 #define CONVERT_PROPERTY_DETAILS_CHECKED(name, index)                \
142   RUNTIME_ASSERT(args[index]->IsSmi());                              \
143   PropertyDetails name = PropertyDetails(Smi::cast(args[index]));
144
145
146 // Assert that the given argument has a valid value for a StrictMode
147 // and store it in a StrictMode variable with the given name.
148 #define CONVERT_STRICT_MODE_ARG_CHECKED(name, index)                 \
149   RUNTIME_ASSERT(args[index]->IsSmi());                              \
150   RUNTIME_ASSERT(args.smi_at(index) == STRICT ||                     \
151                  args.smi_at(index) == SLOPPY);                      \
152   StrictMode name = static_cast<StrictMode>(args.smi_at(index));
153
154
155 static Handle<Map> ComputeObjectLiteralMap(
156     Handle<Context> context,
157     Handle<FixedArray> constant_properties,
158     bool* is_result_from_cache) {
159   Isolate* isolate = context->GetIsolate();
160   int properties_length = constant_properties->length();
161   int number_of_properties = properties_length / 2;
162   // Check that there are only internal strings and array indices among keys.
163   int number_of_string_keys = 0;
164   for (int p = 0; p != properties_length; p += 2) {
165     Object* key = constant_properties->get(p);
166     uint32_t element_index = 0;
167     if (key->IsInternalizedString()) {
168       number_of_string_keys++;
169     } else if (key->ToArrayIndex(&element_index)) {
170       // An index key does not require space in the property backing store.
171       number_of_properties--;
172     } else {
173       // Bail out as a non-internalized-string non-index key makes caching
174       // impossible.
175       // DCHECK to make sure that the if condition after the loop is false.
176       DCHECK(number_of_string_keys != number_of_properties);
177       break;
178     }
179   }
180   // If we only have internalized strings and array indices among keys then we
181   // can use the map cache in the native context.
182   const int kMaxKeys = 10;
183   if ((number_of_string_keys == number_of_properties) &&
184       (number_of_string_keys < kMaxKeys)) {
185     // Create the fixed array with the key.
186     Handle<FixedArray> keys =
187         isolate->factory()->NewFixedArray(number_of_string_keys);
188     if (number_of_string_keys > 0) {
189       int index = 0;
190       for (int p = 0; p < properties_length; p += 2) {
191         Object* key = constant_properties->get(p);
192         if (key->IsInternalizedString()) {
193           keys->set(index++, key);
194         }
195       }
196       DCHECK(index == number_of_string_keys);
197     }
198     *is_result_from_cache = true;
199     return isolate->factory()->ObjectLiteralMapFromCache(context, keys);
200   }
201   *is_result_from_cache = false;
202   return Map::Create(handle(context->object_function()), number_of_properties);
203 }
204
205
206 MUST_USE_RESULT static MaybeHandle<Object> CreateLiteralBoilerplate(
207     Isolate* isolate,
208     Handle<FixedArray> literals,
209     Handle<FixedArray> constant_properties);
210
211
212 MUST_USE_RESULT static MaybeHandle<Object> CreateObjectLiteralBoilerplate(
213     Isolate* isolate,
214     Handle<FixedArray> literals,
215     Handle<FixedArray> constant_properties,
216     bool should_have_fast_elements,
217     bool has_function_literal) {
218   // Get the native context from the literals array.  This is the
219   // context in which the function was created and we use the object
220   // function from this context to create the object literal.  We do
221   // not use the object function from the current native context
222   // because this might be the object function from another context
223   // which we should not have access to.
224   Handle<Context> context =
225       Handle<Context>(JSFunction::NativeContextFromLiterals(*literals));
226
227   // In case we have function literals, we want the object to be in
228   // slow properties mode for now. We don't go in the map cache because
229   // maps with constant functions can't be shared if the functions are
230   // not the same (which is the common case).
231   bool is_result_from_cache = false;
232   Handle<Map> map = has_function_literal
233       ? Handle<Map>(context->object_function()->initial_map())
234       : ComputeObjectLiteralMap(context,
235                                 constant_properties,
236                                 &is_result_from_cache);
237
238   PretenureFlag pretenure_flag =
239       isolate->heap()->InNewSpace(*literals) ? NOT_TENURED : TENURED;
240
241   Handle<JSObject> boilerplate =
242       isolate->factory()->NewJSObjectFromMap(map, pretenure_flag);
243
244   // Normalize the elements of the boilerplate to save space if needed.
245   if (!should_have_fast_elements) JSObject::NormalizeElements(boilerplate);
246
247   // Add the constant properties to the boilerplate.
248   int length = constant_properties->length();
249   bool should_transform =
250       !is_result_from_cache && boilerplate->HasFastProperties();
251   bool should_normalize = should_transform || has_function_literal;
252   if (should_normalize) {
253     // TODO(verwaest): We might not want to ever normalize here.
254     JSObject::NormalizeProperties(
255         boilerplate, KEEP_INOBJECT_PROPERTIES, length / 2);
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     if (key->IsInternalizedString()) {
273       if (Handle<String>::cast(key)->AsArrayIndex(&element_index)) {
274         // Array index as string (uint32).
275         if (value->IsUninitialized()) value = handle(Smi::FromInt(0), isolate);
276         maybe_result =
277             JSObject::SetOwnElement(boilerplate, element_index, value, SLOPPY);
278       } else {
279         Handle<String> name(String::cast(*key));
280         DCHECK(!name->AsArrayIndex(&element_index));
281         maybe_result = JSObject::SetOwnPropertyIgnoreAttributes(
282             boilerplate, name, value, NONE);
283       }
284     } else if (key->ToArrayIndex(&element_index)) {
285       // Array index (uint32).
286       if (value->IsUninitialized()) value = handle(Smi::FromInt(0), isolate);
287       maybe_result =
288           JSObject::SetOwnElement(boilerplate, element_index, value, SLOPPY);
289     } else {
290       // Non-uint32 number.
291       DCHECK(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(boilerplate, name,
298                                                               value, NONE);
299     }
300     // If setting the property on the boilerplate throws an
301     // exception, the exception is converted to an empty handle in
302     // the handle based operations.  In that case, we need to
303     // convert back to an exception.
304     RETURN_ON_EXCEPTION(isolate, maybe_result, Object);
305   }
306
307   // Transform to fast properties if necessary. For object literals with
308   // containing function literals we defer this operation until after all
309   // computed properties have been assigned so that we can generate
310   // constant function properties.
311   if (should_transform && !has_function_literal) {
312     JSObject::MigrateSlowToFast(
313         boilerplate, boilerplate->map()->unused_property_fields());
314   }
315
316   return boilerplate;
317 }
318
319
320 MUST_USE_RESULT static MaybeHandle<Object> TransitionElements(
321     Handle<Object> object,
322     ElementsKind to_kind,
323     Isolate* isolate) {
324   HandleScope scope(isolate);
325   if (!object->IsJSObject()) {
326     isolate->ThrowIllegalOperation();
327     return MaybeHandle<Object>();
328   }
329   ElementsKind from_kind =
330       Handle<JSObject>::cast(object)->map()->elements_kind();
331   if (Map::IsValidElementsTransition(from_kind, to_kind)) {
332     JSObject::TransitionElementsKind(Handle<JSObject>::cast(object), to_kind);
333     return object;
334   }
335   isolate->ThrowIllegalOperation();
336   return MaybeHandle<Object>();
337 }
338
339
340 MaybeHandle<Object> Runtime::CreateArrayLiteralBoilerplate(
341     Isolate* isolate,
342     Handle<FixedArray> literals,
343     Handle<FixedArray> elements) {
344   // Create the JSArray.
345   Handle<JSFunction> constructor(
346       JSFunction::NativeContextFromLiterals(*literals)->array_function());
347
348   PretenureFlag pretenure_flag =
349       isolate->heap()->InNewSpace(*literals) ? NOT_TENURED : TENURED;
350
351   Handle<JSArray> object = Handle<JSArray>::cast(
352       isolate->factory()->NewJSObject(constructor, pretenure_flag));
353
354   ElementsKind constant_elements_kind =
355       static_cast<ElementsKind>(Smi::cast(elements->get(0))->value());
356   Handle<FixedArrayBase> constant_elements_values(
357       FixedArrayBase::cast(elements->get(1)));
358
359   { DisallowHeapAllocation no_gc;
360     DCHECK(IsFastElementsKind(constant_elements_kind));
361     Context* native_context = isolate->context()->native_context();
362     Object* maps_array = native_context->js_array_maps();
363     DCHECK(!maps_array->IsUndefined());
364     Object* map = FixedArray::cast(maps_array)->get(constant_elements_kind);
365     object->set_map(Map::cast(map));
366   }
367
368   Handle<FixedArrayBase> copied_elements_values;
369   if (IsFastDoubleElementsKind(constant_elements_kind)) {
370     copied_elements_values = isolate->factory()->CopyFixedDoubleArray(
371         Handle<FixedDoubleArray>::cast(constant_elements_values));
372   } else {
373     DCHECK(IsFastSmiOrObjectElementsKind(constant_elements_kind));
374     const bool is_cow =
375         (constant_elements_values->map() ==
376          isolate->heap()->fixed_cow_array_map());
377     if (is_cow) {
378       copied_elements_values = constant_elements_values;
379 #if DEBUG
380       Handle<FixedArray> fixed_array_values =
381           Handle<FixedArray>::cast(copied_elements_values);
382       for (int i = 0; i < fixed_array_values->length(); i++) {
383         DCHECK(!fixed_array_values->get(i)->IsFixedArray());
384       }
385 #endif
386     } else {
387       Handle<FixedArray> fixed_array_values =
388           Handle<FixedArray>::cast(constant_elements_values);
389       Handle<FixedArray> fixed_array_values_copy =
390           isolate->factory()->CopyFixedArray(fixed_array_values);
391       copied_elements_values = fixed_array_values_copy;
392       for (int i = 0; i < fixed_array_values->length(); i++) {
393         if (fixed_array_values->get(i)->IsFixedArray()) {
394           // The value contains the constant_properties of a
395           // simple object or array literal.
396           Handle<FixedArray> fa(FixedArray::cast(fixed_array_values->get(i)));
397           Handle<Object> result;
398           ASSIGN_RETURN_ON_EXCEPTION(
399               isolate, result,
400               CreateLiteralBoilerplate(isolate, literals, fa),
401               Object);
402           fixed_array_values_copy->set(i, *result);
403         }
404       }
405     }
406   }
407   object->set_elements(*copied_elements_values);
408   object->set_length(Smi::FromInt(copied_elements_values->length()));
409
410   JSObject::ValidateElements(object);
411   return object;
412 }
413
414
415 MUST_USE_RESULT static MaybeHandle<Object> CreateLiteralBoilerplate(
416     Isolate* isolate,
417     Handle<FixedArray> literals,
418     Handle<FixedArray> array) {
419   Handle<FixedArray> elements = CompileTimeValue::GetElements(array);
420   const bool kHasNoFunctionLiteral = false;
421   switch (CompileTimeValue::GetLiteralType(array)) {
422     case CompileTimeValue::OBJECT_LITERAL_FAST_ELEMENTS:
423       return CreateObjectLiteralBoilerplate(isolate,
424                                             literals,
425                                             elements,
426                                             true,
427                                             kHasNoFunctionLiteral);
428     case CompileTimeValue::OBJECT_LITERAL_SLOW_ELEMENTS:
429       return CreateObjectLiteralBoilerplate(isolate,
430                                             literals,
431                                             elements,
432                                             false,
433                                             kHasNoFunctionLiteral);
434     case CompileTimeValue::ARRAY_LITERAL:
435       return Runtime::CreateArrayLiteralBoilerplate(
436           isolate, literals, elements);
437     default:
438       UNREACHABLE();
439       return MaybeHandle<Object>();
440   }
441 }
442
443
444 RUNTIME_FUNCTION(Runtime_CreateObjectLiteral) {
445   HandleScope scope(isolate);
446   DCHECK(args.length() == 4);
447   CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
448   CONVERT_SMI_ARG_CHECKED(literals_index, 1);
449   CONVERT_ARG_HANDLE_CHECKED(FixedArray, constant_properties, 2);
450   CONVERT_SMI_ARG_CHECKED(flags, 3);
451   bool should_have_fast_elements = (flags & ObjectLiteral::kFastElements) != 0;
452   bool has_function_literal = (flags & ObjectLiteral::kHasFunction) != 0;
453
454   RUNTIME_ASSERT(literals_index >= 0 && literals_index < literals->length());
455
456   // Check if boilerplate exists. If not, create it first.
457   Handle<Object> literal_site(literals->get(literals_index), isolate);
458   Handle<AllocationSite> site;
459   Handle<JSObject> boilerplate;
460   if (*literal_site == isolate->heap()->undefined_value()) {
461     Handle<Object> raw_boilerplate;
462     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
463         isolate, raw_boilerplate,
464         CreateObjectLiteralBoilerplate(
465             isolate,
466             literals,
467             constant_properties,
468             should_have_fast_elements,
469             has_function_literal));
470     boilerplate = Handle<JSObject>::cast(raw_boilerplate);
471
472     AllocationSiteCreationContext creation_context(isolate);
473     site = creation_context.EnterNewScope();
474     RETURN_FAILURE_ON_EXCEPTION(
475         isolate,
476         JSObject::DeepWalk(boilerplate, &creation_context));
477     creation_context.ExitScope(site, boilerplate);
478
479     // Update the functions literal and return the boilerplate.
480     literals->set(literals_index, *site);
481   } else {
482     site = Handle<AllocationSite>::cast(literal_site);
483     boilerplate = Handle<JSObject>(JSObject::cast(site->transition_info()),
484                                    isolate);
485   }
486
487   AllocationSiteUsageContext usage_context(isolate, site, true);
488   usage_context.EnterNewScope();
489   MaybeHandle<Object> maybe_copy = JSObject::DeepCopy(
490       boilerplate, &usage_context);
491   usage_context.ExitScope(site, boilerplate);
492   Handle<Object> copy;
493   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, copy, maybe_copy);
494   return *copy;
495 }
496
497
498 MUST_USE_RESULT static MaybeHandle<AllocationSite> GetLiteralAllocationSite(
499     Isolate* isolate,
500     Handle<FixedArray> literals,
501     int literals_index,
502     Handle<FixedArray> elements) {
503   // Check if boilerplate exists. If not, create it first.
504   Handle<Object> literal_site(literals->get(literals_index), isolate);
505   Handle<AllocationSite> site;
506   if (*literal_site == isolate->heap()->undefined_value()) {
507     DCHECK(*elements != isolate->heap()->empty_fixed_array());
508     Handle<Object> boilerplate;
509     ASSIGN_RETURN_ON_EXCEPTION(
510         isolate, boilerplate,
511         Runtime::CreateArrayLiteralBoilerplate(isolate, literals, elements),
512         AllocationSite);
513
514     AllocationSiteCreationContext creation_context(isolate);
515     site = creation_context.EnterNewScope();
516     if (JSObject::DeepWalk(Handle<JSObject>::cast(boilerplate),
517                            &creation_context).is_null()) {
518       return Handle<AllocationSite>::null();
519     }
520     creation_context.ExitScope(site, Handle<JSObject>::cast(boilerplate));
521
522     literals->set(literals_index, *site);
523   } else {
524     site = Handle<AllocationSite>::cast(literal_site);
525   }
526
527   return site;
528 }
529
530
531 static MaybeHandle<JSObject> CreateArrayLiteralImpl(Isolate* isolate,
532                                            Handle<FixedArray> literals,
533                                            int literals_index,
534                                            Handle<FixedArray> elements,
535                                            int flags) {
536   RUNTIME_ASSERT_HANDLIFIED(literals_index >= 0 &&
537                             literals_index < literals->length(), JSObject);
538   Handle<AllocationSite> site;
539   ASSIGN_RETURN_ON_EXCEPTION(
540       isolate, site,
541       GetLiteralAllocationSite(isolate, literals, literals_index, elements),
542       JSObject);
543
544   bool enable_mementos = (flags & ArrayLiteral::kDisableMementos) == 0;
545   Handle<JSObject> boilerplate(JSObject::cast(site->transition_info()));
546   AllocationSiteUsageContext usage_context(isolate, site, enable_mementos);
547   usage_context.EnterNewScope();
548   JSObject::DeepCopyHints hints = (flags & ArrayLiteral::kShallowElements) == 0
549                                       ? JSObject::kNoHints
550                                       : JSObject::kObjectIsShallow;
551   MaybeHandle<JSObject> copy = JSObject::DeepCopy(boilerplate, &usage_context,
552                                                   hints);
553   usage_context.ExitScope(site, boilerplate);
554   return copy;
555 }
556
557
558 RUNTIME_FUNCTION(Runtime_CreateArrayLiteral) {
559   HandleScope scope(isolate);
560   DCHECK(args.length() == 4);
561   CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
562   CONVERT_SMI_ARG_CHECKED(literals_index, 1);
563   CONVERT_ARG_HANDLE_CHECKED(FixedArray, elements, 2);
564   CONVERT_SMI_ARG_CHECKED(flags, 3);
565
566   Handle<JSObject> result;
567   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
568       CreateArrayLiteralImpl(isolate, literals, literals_index, elements,
569                              flags));
570   return *result;
571 }
572
573
574 RUNTIME_FUNCTION(Runtime_CreateArrayLiteralStubBailout) {
575   HandleScope scope(isolate);
576   DCHECK(args.length() == 3);
577   CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
578   CONVERT_SMI_ARG_CHECKED(literals_index, 1);
579   CONVERT_ARG_HANDLE_CHECKED(FixedArray, elements, 2);
580
581   Handle<JSObject> result;
582   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
583      CreateArrayLiteralImpl(isolate, literals, literals_index, elements,
584                             ArrayLiteral::kShallowElements));
585   return *result;
586 }
587
588
589 RUNTIME_FUNCTION(Runtime_CreateSymbol) {
590   HandleScope scope(isolate);
591   DCHECK(args.length() == 1);
592   CONVERT_ARG_HANDLE_CHECKED(Object, name, 0);
593   RUNTIME_ASSERT(name->IsString() || name->IsUndefined());
594   Handle<Symbol> symbol = isolate->factory()->NewSymbol();
595   if (name->IsString()) symbol->set_name(*name);
596   return *symbol;
597 }
598
599
600 RUNTIME_FUNCTION(Runtime_CreatePrivateSymbol) {
601   HandleScope scope(isolate);
602   DCHECK(args.length() == 1);
603   CONVERT_ARG_HANDLE_CHECKED(Object, name, 0);
604   RUNTIME_ASSERT(name->IsString() || name->IsUndefined());
605   Handle<Symbol> symbol = isolate->factory()->NewPrivateSymbol();
606   if (name->IsString()) symbol->set_name(*name);
607   return *symbol;
608 }
609
610
611 RUNTIME_FUNCTION(Runtime_CreateGlobalPrivateSymbol) {
612   HandleScope scope(isolate);
613   DCHECK(args.length() == 1);
614   CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
615   Handle<JSObject> registry = isolate->GetSymbolRegistry();
616   Handle<String> part = isolate->factory()->private_intern_string();
617   Handle<Object> privates;
618   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
619       isolate, privates, Object::GetPropertyOrElement(registry, part));
620   Handle<Object> symbol;
621   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
622       isolate, symbol, Object::GetPropertyOrElement(privates, name));
623   if (!symbol->IsSymbol()) {
624     DCHECK(symbol->IsUndefined());
625     symbol = isolate->factory()->NewPrivateSymbol();
626     Handle<Symbol>::cast(symbol)->set_name(*name);
627     JSObject::SetProperty(Handle<JSObject>::cast(privates), name, symbol,
628                           STRICT).Assert();
629   }
630   return *symbol;
631 }
632
633
634 RUNTIME_FUNCTION(Runtime_NewSymbolWrapper) {
635   HandleScope scope(isolate);
636   DCHECK(args.length() == 1);
637   CONVERT_ARG_HANDLE_CHECKED(Symbol, symbol, 0);
638   return *Object::ToObject(isolate, symbol).ToHandleChecked();
639 }
640
641
642 RUNTIME_FUNCTION(Runtime_SymbolDescription) {
643   SealHandleScope shs(isolate);
644   DCHECK(args.length() == 1);
645   CONVERT_ARG_CHECKED(Symbol, symbol, 0);
646   return symbol->name();
647 }
648
649
650 RUNTIME_FUNCTION(Runtime_SymbolRegistry) {
651   HandleScope scope(isolate);
652   DCHECK(args.length() == 0);
653   return *isolate->GetSymbolRegistry();
654 }
655
656
657 RUNTIME_FUNCTION(Runtime_SymbolIsPrivate) {
658   SealHandleScope shs(isolate);
659   DCHECK(args.length() == 1);
660   CONVERT_ARG_CHECKED(Symbol, symbol, 0);
661   return isolate->heap()->ToBoolean(symbol->is_private());
662 }
663
664
665 RUNTIME_FUNCTION(Runtime_CreateJSProxy) {
666   HandleScope scope(isolate);
667   DCHECK(args.length() == 2);
668   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, handler, 0);
669   CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
670   if (!prototype->IsJSReceiver()) prototype = isolate->factory()->null_value();
671   return *isolate->factory()->NewJSProxy(handler, prototype);
672 }
673
674
675 RUNTIME_FUNCTION(Runtime_CreateJSFunctionProxy) {
676   HandleScope scope(isolate);
677   DCHECK(args.length() == 4);
678   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, handler, 0);
679   CONVERT_ARG_HANDLE_CHECKED(Object, call_trap, 1);
680   RUNTIME_ASSERT(call_trap->IsJSFunction() || call_trap->IsJSFunctionProxy());
681   CONVERT_ARG_HANDLE_CHECKED(JSFunction, construct_trap, 2);
682   CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 3);
683   if (!prototype->IsJSReceiver()) prototype = isolate->factory()->null_value();
684   return *isolate->factory()->NewJSFunctionProxy(
685       handler, call_trap, construct_trap, prototype);
686 }
687
688
689 RUNTIME_FUNCTION(Runtime_IsJSProxy) {
690   SealHandleScope shs(isolate);
691   DCHECK(args.length() == 1);
692   CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0);
693   return isolate->heap()->ToBoolean(obj->IsJSProxy());
694 }
695
696
697 RUNTIME_FUNCTION(Runtime_IsJSFunctionProxy) {
698   SealHandleScope shs(isolate);
699   DCHECK(args.length() == 1);
700   CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0);
701   return isolate->heap()->ToBoolean(obj->IsJSFunctionProxy());
702 }
703
704
705 RUNTIME_FUNCTION(Runtime_GetHandler) {
706   SealHandleScope shs(isolate);
707   DCHECK(args.length() == 1);
708   CONVERT_ARG_CHECKED(JSProxy, proxy, 0);
709   return proxy->handler();
710 }
711
712
713 RUNTIME_FUNCTION(Runtime_GetCallTrap) {
714   SealHandleScope shs(isolate);
715   DCHECK(args.length() == 1);
716   CONVERT_ARG_CHECKED(JSFunctionProxy, proxy, 0);
717   return proxy->call_trap();
718 }
719
720
721 RUNTIME_FUNCTION(Runtime_GetConstructTrap) {
722   SealHandleScope shs(isolate);
723   DCHECK(args.length() == 1);
724   CONVERT_ARG_CHECKED(JSFunctionProxy, proxy, 0);
725   return proxy->construct_trap();
726 }
727
728
729 RUNTIME_FUNCTION(Runtime_Fix) {
730   HandleScope scope(isolate);
731   DCHECK(args.length() == 1);
732   CONVERT_ARG_HANDLE_CHECKED(JSProxy, proxy, 0);
733   JSProxy::Fix(proxy);
734   return isolate->heap()->undefined_value();
735 }
736
737
738 void Runtime::FreeArrayBuffer(Isolate* isolate,
739                               JSArrayBuffer* phantom_array_buffer) {
740   if (phantom_array_buffer->should_be_freed()) {
741     DCHECK(phantom_array_buffer->is_external());
742     free(phantom_array_buffer->backing_store());
743   }
744   if (phantom_array_buffer->is_external()) return;
745
746   size_t allocated_length = NumberToSize(
747       isolate, phantom_array_buffer->byte_length());
748
749   reinterpret_cast<v8::Isolate*>(isolate)
750       ->AdjustAmountOfExternalAllocatedMemory(
751           -static_cast<int64_t>(allocated_length));
752   CHECK(V8::ArrayBufferAllocator() != NULL);
753   V8::ArrayBufferAllocator()->Free(
754       phantom_array_buffer->backing_store(),
755       allocated_length);
756 }
757
758
759 void Runtime::SetupArrayBuffer(Isolate* isolate,
760                                Handle<JSArrayBuffer> array_buffer,
761                                bool is_external,
762                                void* data,
763                                size_t allocated_length) {
764   DCHECK(array_buffer->GetInternalFieldCount() ==
765       v8::ArrayBuffer::kInternalFieldCount);
766   for (int i = 0; i < v8::ArrayBuffer::kInternalFieldCount; i++) {
767     array_buffer->SetInternalField(i, Smi::FromInt(0));
768   }
769   array_buffer->set_backing_store(data);
770   array_buffer->set_flag(Smi::FromInt(0));
771   array_buffer->set_is_external(is_external);
772
773   Handle<Object> byte_length =
774       isolate->factory()->NewNumberFromSize(allocated_length);
775   CHECK(byte_length->IsSmi() || byte_length->IsHeapNumber());
776   array_buffer->set_byte_length(*byte_length);
777
778   array_buffer->set_weak_next(isolate->heap()->array_buffers_list());
779   isolate->heap()->set_array_buffers_list(*array_buffer);
780   array_buffer->set_weak_first_view(isolate->heap()->undefined_value());
781 }
782
783
784 bool Runtime::SetupArrayBufferAllocatingData(
785     Isolate* isolate,
786     Handle<JSArrayBuffer> array_buffer,
787     size_t allocated_length,
788     bool initialize) {
789   void* data;
790   CHECK(V8::ArrayBufferAllocator() != NULL);
791   if (allocated_length != 0) {
792     if (initialize) {
793       data = V8::ArrayBufferAllocator()->Allocate(allocated_length);
794     } else {
795       data =
796           V8::ArrayBufferAllocator()->AllocateUninitialized(allocated_length);
797     }
798     if (data == NULL) return false;
799   } else {
800     data = NULL;
801   }
802
803   SetupArrayBuffer(isolate, array_buffer, false, data, allocated_length);
804
805   reinterpret_cast<v8::Isolate*>(isolate)
806       ->AdjustAmountOfExternalAllocatedMemory(allocated_length);
807
808   return true;
809 }
810
811
812 void Runtime::NeuterArrayBuffer(Handle<JSArrayBuffer> array_buffer) {
813   Isolate* isolate = array_buffer->GetIsolate();
814   for (Handle<Object> view_obj(array_buffer->weak_first_view(), isolate);
815        !view_obj->IsUndefined();) {
816     Handle<JSArrayBufferView> view(JSArrayBufferView::cast(*view_obj));
817     if (view->IsJSTypedArray()) {
818       JSTypedArray::cast(*view)->Neuter();
819     } else if (view->IsJSDataView()) {
820       JSDataView::cast(*view)->Neuter();
821     } else {
822       UNREACHABLE();
823     }
824     view_obj = handle(view->weak_next(), isolate);
825   }
826   array_buffer->Neuter();
827 }
828
829
830 RUNTIME_FUNCTION(Runtime_ArrayBufferInitialize) {
831   HandleScope scope(isolate);
832   DCHECK(args.length() == 2);
833   CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, holder, 0);
834   CONVERT_NUMBER_ARG_HANDLE_CHECKED(byteLength, 1);
835   if (!holder->byte_length()->IsUndefined()) {
836     // ArrayBuffer is already initialized; probably a fuzz test.
837     return *holder;
838   }
839   size_t allocated_length = 0;
840   if (!TryNumberToSize(isolate, *byteLength, &allocated_length)) {
841     return isolate->Throw(
842         *isolate->factory()->NewRangeError("invalid_array_buffer_length",
843                                            HandleVector<Object>(NULL, 0)));
844   }
845   if (!Runtime::SetupArrayBufferAllocatingData(isolate,
846                                                holder, allocated_length)) {
847     return isolate->Throw(
848         *isolate->factory()->NewRangeError("invalid_array_buffer_length",
849                                            HandleVector<Object>(NULL, 0)));
850   }
851   return *holder;
852 }
853
854
855 RUNTIME_FUNCTION(Runtime_ArrayBufferGetByteLength) {
856   SealHandleScope shs(isolate);
857   DCHECK(args.length() == 1);
858   CONVERT_ARG_CHECKED(JSArrayBuffer, holder, 0);
859   return holder->byte_length();
860 }
861
862
863 RUNTIME_FUNCTION(Runtime_ArrayBufferSliceImpl) {
864   HandleScope scope(isolate);
865   DCHECK(args.length() == 3);
866   CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, source, 0);
867   CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, target, 1);
868   CONVERT_NUMBER_ARG_HANDLE_CHECKED(first, 2);
869   RUNTIME_ASSERT(!source.is_identical_to(target));
870   size_t start = 0;
871   RUNTIME_ASSERT(TryNumberToSize(isolate, *first, &start));
872   size_t target_length = NumberToSize(isolate, target->byte_length());
873
874   if (target_length == 0) return isolate->heap()->undefined_value();
875
876   size_t source_byte_length = NumberToSize(isolate, source->byte_length());
877   RUNTIME_ASSERT(start <= source_byte_length);
878   RUNTIME_ASSERT(source_byte_length - start >= target_length);
879   uint8_t* source_data = reinterpret_cast<uint8_t*>(source->backing_store());
880   uint8_t* target_data = reinterpret_cast<uint8_t*>(target->backing_store());
881   CopyBytes(target_data, source_data + start, target_length);
882   return isolate->heap()->undefined_value();
883 }
884
885
886 RUNTIME_FUNCTION(Runtime_ArrayBufferIsView) {
887   HandleScope scope(isolate);
888   DCHECK(args.length() == 1);
889   CONVERT_ARG_CHECKED(Object, object, 0);
890   return isolate->heap()->ToBoolean(object->IsJSArrayBufferView());
891 }
892
893
894 RUNTIME_FUNCTION(Runtime_ArrayBufferNeuter) {
895   HandleScope scope(isolate);
896   DCHECK(args.length() == 1);
897   CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, array_buffer, 0);
898   if (array_buffer->backing_store() == NULL) {
899     CHECK(Smi::FromInt(0) == array_buffer->byte_length());
900     return isolate->heap()->undefined_value();
901   }
902   DCHECK(!array_buffer->is_external());
903   void* backing_store = array_buffer->backing_store();
904   size_t byte_length = NumberToSize(isolate, array_buffer->byte_length());
905   array_buffer->set_is_external(true);
906   Runtime::NeuterArrayBuffer(array_buffer);
907   V8::ArrayBufferAllocator()->Free(backing_store, byte_length);
908   return isolate->heap()->undefined_value();
909 }
910
911
912 void Runtime::ArrayIdToTypeAndSize(
913     int arrayId,
914     ExternalArrayType* array_type,
915     ElementsKind* external_elements_kind,
916     ElementsKind* fixed_elements_kind,
917     size_t* element_size) {
918   switch (arrayId) {
919 #define ARRAY_ID_CASE(Type, type, TYPE, ctype, size)                           \
920     case ARRAY_ID_##TYPE:                                                      \
921       *array_type = kExternal##Type##Array;                                    \
922       *external_elements_kind = EXTERNAL_##TYPE##_ELEMENTS;                    \
923       *fixed_elements_kind = TYPE##_ELEMENTS;                                  \
924       *element_size = size;                                                    \
925       break;
926
927     TYPED_ARRAYS(ARRAY_ID_CASE)
928 #undef ARRAY_ID_CASE
929
930     default:
931       UNREACHABLE();
932   }
933 }
934
935
936 RUNTIME_FUNCTION(Runtime_TypedArrayInitialize) {
937   HandleScope scope(isolate);
938   DCHECK(args.length() == 5);
939   CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0);
940   CONVERT_SMI_ARG_CHECKED(arrayId, 1);
941   CONVERT_ARG_HANDLE_CHECKED(Object, maybe_buffer, 2);
942   CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_offset_object, 3);
943   CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_length_object, 4);
944
945   RUNTIME_ASSERT(arrayId >= Runtime::ARRAY_ID_FIRST &&
946                  arrayId <= Runtime::ARRAY_ID_LAST);
947
948   ExternalArrayType array_type = kExternalInt8Array;  // Bogus initialization.
949   size_t element_size = 1;  // Bogus initialization.
950   ElementsKind external_elements_kind =
951       EXTERNAL_INT8_ELEMENTS;  // Bogus initialization.
952   ElementsKind fixed_elements_kind = INT8_ELEMENTS;  // Bogus initialization.
953   Runtime::ArrayIdToTypeAndSize(arrayId,
954       &array_type,
955       &external_elements_kind,
956       &fixed_elements_kind,
957       &element_size);
958   RUNTIME_ASSERT(holder->map()->elements_kind() == fixed_elements_kind);
959
960   size_t byte_offset = 0;
961   size_t byte_length = 0;
962   RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_offset_object, &byte_offset));
963   RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_length_object, &byte_length));
964
965   if (maybe_buffer->IsJSArrayBuffer()) {
966     Handle<JSArrayBuffer> buffer = Handle<JSArrayBuffer>::cast(maybe_buffer);
967     size_t array_buffer_byte_length =
968         NumberToSize(isolate, buffer->byte_length());
969     RUNTIME_ASSERT(byte_offset <= array_buffer_byte_length);
970     RUNTIME_ASSERT(array_buffer_byte_length - byte_offset >= byte_length);
971   } else {
972     RUNTIME_ASSERT(maybe_buffer->IsNull());
973   }
974
975   RUNTIME_ASSERT(byte_length % element_size == 0);
976   size_t length = byte_length / element_size;
977
978   if (length > static_cast<unsigned>(Smi::kMaxValue)) {
979     return isolate->Throw(
980         *isolate->factory()->NewRangeError("invalid_typed_array_length",
981                                            HandleVector<Object>(NULL, 0)));
982   }
983
984   // All checks are done, now we can modify objects.
985
986   DCHECK(holder->GetInternalFieldCount() ==
987       v8::ArrayBufferView::kInternalFieldCount);
988   for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) {
989     holder->SetInternalField(i, Smi::FromInt(0));
990   }
991   Handle<Object> length_obj = isolate->factory()->NewNumberFromSize(length);
992   holder->set_length(*length_obj);
993   holder->set_byte_offset(*byte_offset_object);
994   holder->set_byte_length(*byte_length_object);
995
996   if (!maybe_buffer->IsNull()) {
997     Handle<JSArrayBuffer> buffer = Handle<JSArrayBuffer>::cast(maybe_buffer);
998     holder->set_buffer(*buffer);
999     holder->set_weak_next(buffer->weak_first_view());
1000     buffer->set_weak_first_view(*holder);
1001
1002     Handle<ExternalArray> elements =
1003         isolate->factory()->NewExternalArray(
1004             static_cast<int>(length), array_type,
1005             static_cast<uint8_t*>(buffer->backing_store()) + byte_offset);
1006     Handle<Map> map =
1007         JSObject::GetElementsTransitionMap(holder, external_elements_kind);
1008     JSObject::SetMapAndElements(holder, map, elements);
1009     DCHECK(IsExternalArrayElementsKind(holder->map()->elements_kind()));
1010   } else {
1011     holder->set_buffer(Smi::FromInt(0));
1012     holder->set_weak_next(isolate->heap()->undefined_value());
1013     Handle<FixedTypedArrayBase> elements =
1014         isolate->factory()->NewFixedTypedArray(
1015             static_cast<int>(length), array_type);
1016     holder->set_elements(*elements);
1017   }
1018   return isolate->heap()->undefined_value();
1019 }
1020
1021
1022 // Initializes a typed array from an array-like object.
1023 // If an array-like object happens to be a typed array of the same type,
1024 // initializes backing store using memove.
1025 //
1026 // Returns true if backing store was initialized or false otherwise.
1027 RUNTIME_FUNCTION(Runtime_TypedArrayInitializeFromArrayLike) {
1028   HandleScope scope(isolate);
1029   DCHECK(args.length() == 4);
1030   CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0);
1031   CONVERT_SMI_ARG_CHECKED(arrayId, 1);
1032   CONVERT_ARG_HANDLE_CHECKED(Object, source, 2);
1033   CONVERT_NUMBER_ARG_HANDLE_CHECKED(length_obj, 3);
1034
1035   RUNTIME_ASSERT(arrayId >= Runtime::ARRAY_ID_FIRST &&
1036                  arrayId <= Runtime::ARRAY_ID_LAST);
1037
1038   ExternalArrayType array_type = kExternalInt8Array;  // Bogus initialization.
1039   size_t element_size = 1;  // Bogus initialization.
1040   ElementsKind external_elements_kind =
1041       EXTERNAL_INT8_ELEMENTS;  // Bogus intialization.
1042   ElementsKind fixed_elements_kind = INT8_ELEMENTS;  // Bogus initialization.
1043   Runtime::ArrayIdToTypeAndSize(arrayId,
1044       &array_type,
1045       &external_elements_kind,
1046       &fixed_elements_kind,
1047       &element_size);
1048
1049   RUNTIME_ASSERT(holder->map()->elements_kind() == fixed_elements_kind);
1050
1051   Handle<JSArrayBuffer> buffer = isolate->factory()->NewJSArrayBuffer();
1052   if (source->IsJSTypedArray() &&
1053       JSTypedArray::cast(*source)->type() == array_type) {
1054     length_obj = Handle<Object>(JSTypedArray::cast(*source)->length(), isolate);
1055   }
1056   size_t length = 0;
1057   RUNTIME_ASSERT(TryNumberToSize(isolate, *length_obj, &length));
1058
1059   if ((length > static_cast<unsigned>(Smi::kMaxValue)) ||
1060       (length > (kMaxInt / element_size))) {
1061     return isolate->Throw(*isolate->factory()->
1062           NewRangeError("invalid_typed_array_length",
1063             HandleVector<Object>(NULL, 0)));
1064   }
1065   size_t byte_length = length * element_size;
1066
1067   DCHECK(holder->GetInternalFieldCount() ==
1068       v8::ArrayBufferView::kInternalFieldCount);
1069   for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) {
1070     holder->SetInternalField(i, Smi::FromInt(0));
1071   }
1072
1073   // NOTE: not initializing backing store.
1074   // We assume that the caller of this function will initialize holder
1075   // with the loop
1076   //      for(i = 0; i < length; i++) { holder[i] = source[i]; }
1077   // We assume that the caller of this function is always a typed array
1078   // constructor.
1079   // If source is a typed array, this loop will always run to completion,
1080   // so we are sure that the backing store will be initialized.
1081   // Otherwise, the indexing operation might throw, so the loop will not
1082   // run to completion and the typed array might remain partly initialized.
1083   // However we further assume that the caller of this function is a typed array
1084   // constructor, and the exception will propagate out of the constructor,
1085   // therefore uninitialized memory will not be accessible by a user program.
1086   //
1087   // TODO(dslomov): revise this once we support subclassing.
1088
1089   if (!Runtime::SetupArrayBufferAllocatingData(
1090         isolate, buffer, byte_length, false)) {
1091     return isolate->Throw(*isolate->factory()->
1092           NewRangeError("invalid_array_buffer_length",
1093             HandleVector<Object>(NULL, 0)));
1094   }
1095
1096   holder->set_buffer(*buffer);
1097   holder->set_byte_offset(Smi::FromInt(0));
1098   Handle<Object> byte_length_obj(
1099       isolate->factory()->NewNumberFromSize(byte_length));
1100   holder->set_byte_length(*byte_length_obj);
1101   holder->set_length(*length_obj);
1102   holder->set_weak_next(buffer->weak_first_view());
1103   buffer->set_weak_first_view(*holder);
1104
1105   Handle<ExternalArray> elements =
1106       isolate->factory()->NewExternalArray(
1107           static_cast<int>(length), array_type,
1108           static_cast<uint8_t*>(buffer->backing_store()));
1109   Handle<Map> map = JSObject::GetElementsTransitionMap(
1110       holder, external_elements_kind);
1111   JSObject::SetMapAndElements(holder, map, elements);
1112
1113   if (source->IsJSTypedArray()) {
1114     Handle<JSTypedArray> typed_array(JSTypedArray::cast(*source));
1115
1116     if (typed_array->type() == holder->type()) {
1117       uint8_t* backing_store =
1118         static_cast<uint8_t*>(
1119           typed_array->GetBuffer()->backing_store());
1120       size_t source_byte_offset =
1121           NumberToSize(isolate, typed_array->byte_offset());
1122       memcpy(
1123           buffer->backing_store(),
1124           backing_store + source_byte_offset,
1125           byte_length);
1126       return isolate->heap()->true_value();
1127     }
1128   }
1129
1130   return isolate->heap()->false_value();
1131 }
1132
1133
1134 #define BUFFER_VIEW_GETTER(Type, getter, accessor) \
1135   RUNTIME_FUNCTION(Runtime_##Type##Get##getter) {                    \
1136     HandleScope scope(isolate);                                               \
1137     DCHECK(args.length() == 1);                                               \
1138     CONVERT_ARG_HANDLE_CHECKED(JS##Type, holder, 0);                          \
1139     return holder->accessor();                                                \
1140   }
1141
1142 BUFFER_VIEW_GETTER(ArrayBufferView, ByteLength, byte_length)
1143 BUFFER_VIEW_GETTER(ArrayBufferView, ByteOffset, byte_offset)
1144 BUFFER_VIEW_GETTER(TypedArray, Length, length)
1145 BUFFER_VIEW_GETTER(DataView, Buffer, buffer)
1146
1147 #undef BUFFER_VIEW_GETTER
1148
1149 RUNTIME_FUNCTION(Runtime_TypedArrayGetBuffer) {
1150   HandleScope scope(isolate);
1151   DCHECK(args.length() == 1);
1152   CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0);
1153   return *holder->GetBuffer();
1154 }
1155
1156
1157 // Return codes for Runtime_TypedArraySetFastCases.
1158 // Should be synchronized with typedarray.js natives.
1159 enum TypedArraySetResultCodes {
1160   // Set from typed array of the same type.
1161   // This is processed by TypedArraySetFastCases
1162   TYPED_ARRAY_SET_TYPED_ARRAY_SAME_TYPE = 0,
1163   // Set from typed array of the different type, overlapping in memory.
1164   TYPED_ARRAY_SET_TYPED_ARRAY_OVERLAPPING = 1,
1165   // Set from typed array of the different type, non-overlapping.
1166   TYPED_ARRAY_SET_TYPED_ARRAY_NONOVERLAPPING = 2,
1167   // Set from non-typed array.
1168   TYPED_ARRAY_SET_NON_TYPED_ARRAY = 3
1169 };
1170
1171
1172 RUNTIME_FUNCTION(Runtime_TypedArraySetFastCases) {
1173   HandleScope scope(isolate);
1174   DCHECK(args.length() == 3);
1175   if (!args[0]->IsJSTypedArray())
1176     return isolate->Throw(*isolate->factory()->NewTypeError(
1177         "not_typed_array", HandleVector<Object>(NULL, 0)));
1178
1179   if (!args[1]->IsJSTypedArray())
1180     return Smi::FromInt(TYPED_ARRAY_SET_NON_TYPED_ARRAY);
1181
1182   CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, target_obj, 0);
1183   CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, source_obj, 1);
1184   CONVERT_NUMBER_ARG_HANDLE_CHECKED(offset_obj, 2);
1185
1186   Handle<JSTypedArray> target(JSTypedArray::cast(*target_obj));
1187   Handle<JSTypedArray> source(JSTypedArray::cast(*source_obj));
1188   size_t offset = 0;
1189   RUNTIME_ASSERT(TryNumberToSize(isolate, *offset_obj, &offset));
1190   size_t target_length = NumberToSize(isolate, target->length());
1191   size_t source_length = NumberToSize(isolate, source->length());
1192   size_t target_byte_length = NumberToSize(isolate, target->byte_length());
1193   size_t source_byte_length = NumberToSize(isolate, source->byte_length());
1194   if (offset > target_length ||
1195       offset + source_length > target_length ||
1196       offset + source_length < offset)  // overflow
1197     return isolate->Throw(*isolate->factory()->NewRangeError(
1198           "typed_array_set_source_too_large", HandleVector<Object>(NULL, 0)));
1199
1200   size_t target_offset = NumberToSize(isolate, target->byte_offset());
1201   size_t source_offset = NumberToSize(isolate, source->byte_offset());
1202   uint8_t* target_base =
1203       static_cast<uint8_t*>(
1204         target->GetBuffer()->backing_store()) + target_offset;
1205   uint8_t* source_base =
1206       static_cast<uint8_t*>(
1207         source->GetBuffer()->backing_store()) + source_offset;
1208
1209   // Typed arrays of the same type: use memmove.
1210   if (target->type() == source->type()) {
1211     memmove(target_base + offset * target->element_size(),
1212         source_base, source_byte_length);
1213     return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_SAME_TYPE);
1214   }
1215
1216   // Typed arrays of different types over the same backing store
1217   if ((source_base <= target_base &&
1218         source_base + source_byte_length > target_base) ||
1219       (target_base <= source_base &&
1220         target_base + target_byte_length > source_base)) {
1221     // We do not support overlapping ArrayBuffers
1222     DCHECK(
1223       target->GetBuffer()->backing_store() ==
1224       source->GetBuffer()->backing_store());
1225     return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_OVERLAPPING);
1226   } else {  // Non-overlapping typed arrays
1227     return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_NONOVERLAPPING);
1228   }
1229 }
1230
1231
1232 RUNTIME_FUNCTION(Runtime_TypedArrayMaxSizeInHeap) {
1233   DCHECK(args.length() == 0);
1234   DCHECK_OBJECT_SIZE(
1235       FLAG_typed_array_max_size_in_heap + FixedTypedArrayBase::kDataOffset);
1236   return Smi::FromInt(FLAG_typed_array_max_size_in_heap);
1237 }
1238
1239
1240 RUNTIME_FUNCTION(Runtime_DataViewInitialize) {
1241   HandleScope scope(isolate);
1242   DCHECK(args.length() == 4);
1243   CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0);
1244   CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, buffer, 1);
1245   CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_offset, 2);
1246   CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_length, 3);
1247
1248   DCHECK(holder->GetInternalFieldCount() ==
1249       v8::ArrayBufferView::kInternalFieldCount);
1250   for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) {
1251     holder->SetInternalField(i, Smi::FromInt(0));
1252   }
1253   size_t buffer_length = 0;
1254   size_t offset = 0;
1255   size_t length = 0;
1256   RUNTIME_ASSERT(
1257       TryNumberToSize(isolate, buffer->byte_length(), &buffer_length));
1258   RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_offset, &offset));
1259   RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_length, &length));
1260
1261   // TODO(jkummerow): When we have a "safe numerics" helper class, use it here.
1262   // Entire range [offset, offset + length] must be in bounds.
1263   RUNTIME_ASSERT(offset <= buffer_length);
1264   RUNTIME_ASSERT(offset + length <= buffer_length);
1265   // No overflow.
1266   RUNTIME_ASSERT(offset + length >= offset);
1267
1268   holder->set_buffer(*buffer);
1269   holder->set_byte_offset(*byte_offset);
1270   holder->set_byte_length(*byte_length);
1271
1272   holder->set_weak_next(buffer->weak_first_view());
1273   buffer->set_weak_first_view(*holder);
1274
1275   return isolate->heap()->undefined_value();
1276 }
1277
1278
1279 inline static bool NeedToFlipBytes(bool is_little_endian) {
1280 #ifdef V8_TARGET_LITTLE_ENDIAN
1281   return !is_little_endian;
1282 #else
1283   return is_little_endian;
1284 #endif
1285 }
1286
1287
1288 template<int n>
1289 inline void CopyBytes(uint8_t* target, uint8_t* source) {
1290   for (int i = 0; i < n; i++) {
1291     *(target++) = *(source++);
1292   }
1293 }
1294
1295
1296 template<int n>
1297 inline void FlipBytes(uint8_t* target, uint8_t* source) {
1298   source = source + (n-1);
1299   for (int i = 0; i < n; i++) {
1300     *(target++) = *(source--);
1301   }
1302 }
1303
1304
1305 template<typename T>
1306 inline static bool DataViewGetValue(
1307     Isolate* isolate,
1308     Handle<JSDataView> data_view,
1309     Handle<Object> byte_offset_obj,
1310     bool is_little_endian,
1311     T* result) {
1312   size_t byte_offset = 0;
1313   if (!TryNumberToSize(isolate, *byte_offset_obj, &byte_offset)) {
1314     return false;
1315   }
1316   Handle<JSArrayBuffer> buffer(JSArrayBuffer::cast(data_view->buffer()));
1317
1318   size_t data_view_byte_offset =
1319       NumberToSize(isolate, data_view->byte_offset());
1320   size_t data_view_byte_length =
1321       NumberToSize(isolate, data_view->byte_length());
1322   if (byte_offset + sizeof(T) > data_view_byte_length ||
1323       byte_offset + sizeof(T) < byte_offset)  {  // overflow
1324     return false;
1325   }
1326
1327   union Value {
1328     T data;
1329     uint8_t bytes[sizeof(T)];
1330   };
1331
1332   Value value;
1333   size_t buffer_offset = data_view_byte_offset + byte_offset;
1334   DCHECK(
1335       NumberToSize(isolate, buffer->byte_length())
1336       >= buffer_offset + sizeof(T));
1337   uint8_t* source =
1338         static_cast<uint8_t*>(buffer->backing_store()) + buffer_offset;
1339   if (NeedToFlipBytes(is_little_endian)) {
1340     FlipBytes<sizeof(T)>(value.bytes, source);
1341   } else {
1342     CopyBytes<sizeof(T)>(value.bytes, source);
1343   }
1344   *result = value.data;
1345   return true;
1346 }
1347
1348
1349 template<typename T>
1350 static bool DataViewSetValue(
1351     Isolate* isolate,
1352     Handle<JSDataView> data_view,
1353     Handle<Object> byte_offset_obj,
1354     bool is_little_endian,
1355     T data) {
1356   size_t byte_offset = 0;
1357   if (!TryNumberToSize(isolate, *byte_offset_obj, &byte_offset)) {
1358     return false;
1359   }
1360   Handle<JSArrayBuffer> buffer(JSArrayBuffer::cast(data_view->buffer()));
1361
1362   size_t data_view_byte_offset =
1363       NumberToSize(isolate, data_view->byte_offset());
1364   size_t data_view_byte_length =
1365       NumberToSize(isolate, data_view->byte_length());
1366   if (byte_offset + sizeof(T) > data_view_byte_length ||
1367       byte_offset + sizeof(T) < byte_offset)  {  // overflow
1368     return false;
1369   }
1370
1371   union Value {
1372     T data;
1373     uint8_t bytes[sizeof(T)];
1374   };
1375
1376   Value value;
1377   value.data = data;
1378   size_t buffer_offset = data_view_byte_offset + byte_offset;
1379   DCHECK(
1380       NumberToSize(isolate, buffer->byte_length())
1381       >= buffer_offset + sizeof(T));
1382   uint8_t* target =
1383         static_cast<uint8_t*>(buffer->backing_store()) + buffer_offset;
1384   if (NeedToFlipBytes(is_little_endian)) {
1385     FlipBytes<sizeof(T)>(target, value.bytes);
1386   } else {
1387     CopyBytes<sizeof(T)>(target, value.bytes);
1388   }
1389   return true;
1390 }
1391
1392
1393 #define DATA_VIEW_GETTER(TypeName, Type, Converter)                           \
1394   RUNTIME_FUNCTION(Runtime_DataViewGet##TypeName) {                           \
1395     HandleScope scope(isolate);                                               \
1396     DCHECK(args.length() == 3);                                               \
1397     CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0);                        \
1398     CONVERT_NUMBER_ARG_HANDLE_CHECKED(offset, 1);                             \
1399     CONVERT_BOOLEAN_ARG_CHECKED(is_little_endian, 2);                         \
1400     Type result;                                                              \
1401     if (DataViewGetValue(                                                     \
1402           isolate, holder, offset, is_little_endian, &result)) {              \
1403       return *isolate->factory()->Converter(result);                          \
1404     } else {                                                                  \
1405       return isolate->Throw(*isolate->factory()->NewRangeError(               \
1406           "invalid_data_view_accessor_offset",                                \
1407           HandleVector<Object>(NULL, 0)));                                    \
1408     }                                                                         \
1409   }
1410
1411 DATA_VIEW_GETTER(Uint8, uint8_t, NewNumberFromUint)
1412 DATA_VIEW_GETTER(Int8, int8_t, NewNumberFromInt)
1413 DATA_VIEW_GETTER(Uint16, uint16_t, NewNumberFromUint)
1414 DATA_VIEW_GETTER(Int16, int16_t, NewNumberFromInt)
1415 DATA_VIEW_GETTER(Uint32, uint32_t, NewNumberFromUint)
1416 DATA_VIEW_GETTER(Int32, int32_t, NewNumberFromInt)
1417 DATA_VIEW_GETTER(Float32, float, NewNumber)
1418 DATA_VIEW_GETTER(Float64, double, NewNumber)
1419
1420 #undef DATA_VIEW_GETTER
1421
1422
1423 template <typename T>
1424 static T DataViewConvertValue(double value);
1425
1426
1427 template <>
1428 int8_t DataViewConvertValue<int8_t>(double value) {
1429   return static_cast<int8_t>(DoubleToInt32(value));
1430 }
1431
1432
1433 template <>
1434 int16_t DataViewConvertValue<int16_t>(double value) {
1435   return static_cast<int16_t>(DoubleToInt32(value));
1436 }
1437
1438
1439 template <>
1440 int32_t DataViewConvertValue<int32_t>(double value) {
1441   return DoubleToInt32(value);
1442 }
1443
1444
1445 template <>
1446 uint8_t DataViewConvertValue<uint8_t>(double value) {
1447   return static_cast<uint8_t>(DoubleToUint32(value));
1448 }
1449
1450
1451 template <>
1452 uint16_t DataViewConvertValue<uint16_t>(double value) {
1453   return static_cast<uint16_t>(DoubleToUint32(value));
1454 }
1455
1456
1457 template <>
1458 uint32_t DataViewConvertValue<uint32_t>(double value) {
1459   return DoubleToUint32(value);
1460 }
1461
1462
1463 template <>
1464 float DataViewConvertValue<float>(double value) {
1465   return static_cast<float>(value);
1466 }
1467
1468
1469 template <>
1470 double DataViewConvertValue<double>(double value) {
1471   return value;
1472 }
1473
1474
1475 #define DATA_VIEW_SETTER(TypeName, Type)                                      \
1476   RUNTIME_FUNCTION(Runtime_DataViewSet##TypeName) {                           \
1477     HandleScope scope(isolate);                                               \
1478     DCHECK(args.length() == 4);                                               \
1479     CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0);                        \
1480     CONVERT_NUMBER_ARG_HANDLE_CHECKED(offset, 1);                             \
1481     CONVERT_NUMBER_ARG_HANDLE_CHECKED(value, 2);                              \
1482     CONVERT_BOOLEAN_ARG_CHECKED(is_little_endian, 3);                         \
1483     Type v = DataViewConvertValue<Type>(value->Number());                     \
1484     if (DataViewSetValue(                                                     \
1485           isolate, holder, offset, is_little_endian, v)) {                    \
1486       return isolate->heap()->undefined_value();                              \
1487     } else {                                                                  \
1488       return isolate->Throw(*isolate->factory()->NewRangeError(               \
1489           "invalid_data_view_accessor_offset",                                \
1490           HandleVector<Object>(NULL, 0)));                                    \
1491     }                                                                         \
1492   }
1493
1494 DATA_VIEW_SETTER(Uint8, uint8_t)
1495 DATA_VIEW_SETTER(Int8, int8_t)
1496 DATA_VIEW_SETTER(Uint16, uint16_t)
1497 DATA_VIEW_SETTER(Int16, int16_t)
1498 DATA_VIEW_SETTER(Uint32, uint32_t)
1499 DATA_VIEW_SETTER(Int32, int32_t)
1500 DATA_VIEW_SETTER(Float32, float)
1501 DATA_VIEW_SETTER(Float64, double)
1502
1503 #undef DATA_VIEW_SETTER
1504
1505
1506 RUNTIME_FUNCTION(Runtime_SetInitialize) {
1507   HandleScope scope(isolate);
1508   DCHECK(args.length() == 1);
1509   CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
1510   Handle<OrderedHashSet> table = isolate->factory()->NewOrderedHashSet();
1511   holder->set_table(*table);
1512   return *holder;
1513 }
1514
1515
1516 RUNTIME_FUNCTION(Runtime_SetAdd) {
1517   HandleScope scope(isolate);
1518   DCHECK(args.length() == 2);
1519   CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
1520   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
1521   Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
1522   table = OrderedHashSet::Add(table, key);
1523   holder->set_table(*table);
1524   return *holder;
1525 }
1526
1527
1528 RUNTIME_FUNCTION(Runtime_SetHas) {
1529   HandleScope scope(isolate);
1530   DCHECK(args.length() == 2);
1531   CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
1532   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
1533   Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
1534   return isolate->heap()->ToBoolean(table->Contains(key));
1535 }
1536
1537
1538 RUNTIME_FUNCTION(Runtime_SetDelete) {
1539   HandleScope scope(isolate);
1540   DCHECK(args.length() == 2);
1541   CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
1542   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
1543   Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
1544   bool was_present = false;
1545   table = OrderedHashSet::Remove(table, key, &was_present);
1546   holder->set_table(*table);
1547   return isolate->heap()->ToBoolean(was_present);
1548 }
1549
1550
1551 RUNTIME_FUNCTION(Runtime_SetClear) {
1552   HandleScope scope(isolate);
1553   DCHECK(args.length() == 1);
1554   CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
1555   Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
1556   table = OrderedHashSet::Clear(table);
1557   holder->set_table(*table);
1558   return isolate->heap()->undefined_value();
1559 }
1560
1561
1562 RUNTIME_FUNCTION(Runtime_SetGetSize) {
1563   HandleScope scope(isolate);
1564   DCHECK(args.length() == 1);
1565   CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
1566   Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
1567   return Smi::FromInt(table->NumberOfElements());
1568 }
1569
1570
1571 RUNTIME_FUNCTION(Runtime_SetIteratorInitialize) {
1572   HandleScope scope(isolate);
1573   DCHECK(args.length() == 3);
1574   CONVERT_ARG_HANDLE_CHECKED(JSSetIterator, holder, 0);
1575   CONVERT_ARG_HANDLE_CHECKED(JSSet, set, 1);
1576   CONVERT_SMI_ARG_CHECKED(kind, 2)
1577   RUNTIME_ASSERT(kind == JSSetIterator::kKindValues ||
1578                  kind == JSSetIterator::kKindEntries);
1579   Handle<OrderedHashSet> table(OrderedHashSet::cast(set->table()));
1580   holder->set_table(*table);
1581   holder->set_index(Smi::FromInt(0));
1582   holder->set_kind(Smi::FromInt(kind));
1583   return isolate->heap()->undefined_value();
1584 }
1585
1586
1587 RUNTIME_FUNCTION(Runtime_SetIteratorNext) {
1588   SealHandleScope shs(isolate);
1589   DCHECK(args.length() == 2);
1590   CONVERT_ARG_CHECKED(JSSetIterator, holder, 0);
1591   CONVERT_ARG_CHECKED(JSArray, value_array, 1);
1592   return holder->Next(value_array);
1593 }
1594
1595
1596 RUNTIME_FUNCTION(Runtime_MapInitialize) {
1597   HandleScope scope(isolate);
1598   DCHECK(args.length() == 1);
1599   CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
1600   Handle<OrderedHashMap> table = isolate->factory()->NewOrderedHashMap();
1601   holder->set_table(*table);
1602   return *holder;
1603 }
1604
1605
1606 RUNTIME_FUNCTION(Runtime_MapGet) {
1607   HandleScope scope(isolate);
1608   DCHECK(args.length() == 2);
1609   CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
1610   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
1611   Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
1612   Handle<Object> lookup(table->Lookup(key), isolate);
1613   return lookup->IsTheHole() ? isolate->heap()->undefined_value() : *lookup;
1614 }
1615
1616
1617 RUNTIME_FUNCTION(Runtime_MapHas) {
1618   HandleScope scope(isolate);
1619   DCHECK(args.length() == 2);
1620   CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
1621   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
1622   Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
1623   Handle<Object> lookup(table->Lookup(key), isolate);
1624   return isolate->heap()->ToBoolean(!lookup->IsTheHole());
1625 }
1626
1627
1628 RUNTIME_FUNCTION(Runtime_MapDelete) {
1629   HandleScope scope(isolate);
1630   DCHECK(args.length() == 2);
1631   CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
1632   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
1633   Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
1634   bool was_present = false;
1635   Handle<OrderedHashMap> new_table =
1636       OrderedHashMap::Remove(table, key, &was_present);
1637   holder->set_table(*new_table);
1638   return isolate->heap()->ToBoolean(was_present);
1639 }
1640
1641
1642 RUNTIME_FUNCTION(Runtime_MapClear) {
1643   HandleScope scope(isolate);
1644   DCHECK(args.length() == 1);
1645   CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
1646   Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
1647   table = OrderedHashMap::Clear(table);
1648   holder->set_table(*table);
1649   return isolate->heap()->undefined_value();
1650 }
1651
1652
1653 RUNTIME_FUNCTION(Runtime_MapSet) {
1654   HandleScope scope(isolate);
1655   DCHECK(args.length() == 3);
1656   CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
1657   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
1658   CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
1659   Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
1660   Handle<OrderedHashMap> new_table = OrderedHashMap::Put(table, key, value);
1661   holder->set_table(*new_table);
1662   return *holder;
1663 }
1664
1665
1666 RUNTIME_FUNCTION(Runtime_MapGetSize) {
1667   HandleScope scope(isolate);
1668   DCHECK(args.length() == 1);
1669   CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
1670   Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
1671   return Smi::FromInt(table->NumberOfElements());
1672 }
1673
1674
1675 RUNTIME_FUNCTION(Runtime_MapIteratorInitialize) {
1676   HandleScope scope(isolate);
1677   DCHECK(args.length() == 3);
1678   CONVERT_ARG_HANDLE_CHECKED(JSMapIterator, holder, 0);
1679   CONVERT_ARG_HANDLE_CHECKED(JSMap, map, 1);
1680   CONVERT_SMI_ARG_CHECKED(kind, 2)
1681   RUNTIME_ASSERT(kind == JSMapIterator::kKindKeys
1682       || kind == JSMapIterator::kKindValues
1683       || kind == JSMapIterator::kKindEntries);
1684   Handle<OrderedHashMap> table(OrderedHashMap::cast(map->table()));
1685   holder->set_table(*table);
1686   holder->set_index(Smi::FromInt(0));
1687   holder->set_kind(Smi::FromInt(kind));
1688   return isolate->heap()->undefined_value();
1689 }
1690
1691
1692 RUNTIME_FUNCTION(Runtime_GetWeakMapEntries) {
1693   HandleScope scope(isolate);
1694   DCHECK(args.length() == 1);
1695   CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, holder, 0);
1696   Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
1697   Handle<FixedArray> entries =
1698       isolate->factory()->NewFixedArray(table->NumberOfElements() * 2);
1699   {
1700     DisallowHeapAllocation no_gc;
1701     int number_of_non_hole_elements = 0;
1702     for (int i = 0; i < table->Capacity(); i++) {
1703       Handle<Object> key(table->KeyAt(i), isolate);
1704       if (table->IsKey(*key)) {
1705         entries->set(number_of_non_hole_elements++, *key);
1706         entries->set(number_of_non_hole_elements++, table->Lookup(key));
1707       }
1708     }
1709     DCHECK_EQ(table->NumberOfElements() * 2, number_of_non_hole_elements);
1710   }
1711   return *isolate->factory()->NewJSArrayWithElements(entries);
1712 }
1713
1714
1715 RUNTIME_FUNCTION(Runtime_MapIteratorNext) {
1716   SealHandleScope shs(isolate);
1717   DCHECK(args.length() == 2);
1718   CONVERT_ARG_CHECKED(JSMapIterator, holder, 0);
1719   CONVERT_ARG_CHECKED(JSArray, value_array, 1);
1720   return holder->Next(value_array);
1721 }
1722
1723
1724 static Handle<JSWeakCollection> WeakCollectionInitialize(
1725     Isolate* isolate,
1726     Handle<JSWeakCollection> weak_collection) {
1727   DCHECK(weak_collection->map()->inobject_properties() == 0);
1728   Handle<ObjectHashTable> table = ObjectHashTable::New(isolate, 0);
1729   weak_collection->set_table(*table);
1730   return weak_collection;
1731 }
1732
1733
1734 RUNTIME_FUNCTION(Runtime_WeakCollectionInitialize) {
1735   HandleScope scope(isolate);
1736   DCHECK(args.length() == 1);
1737   CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
1738   return *WeakCollectionInitialize(isolate, weak_collection);
1739 }
1740
1741
1742 RUNTIME_FUNCTION(Runtime_WeakCollectionGet) {
1743   HandleScope scope(isolate);
1744   DCHECK(args.length() == 2);
1745   CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
1746   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
1747   RUNTIME_ASSERT(key->IsJSReceiver() || key->IsSymbol());
1748   Handle<ObjectHashTable> table(
1749       ObjectHashTable::cast(weak_collection->table()));
1750   RUNTIME_ASSERT(table->IsKey(*key));
1751   Handle<Object> lookup(table->Lookup(key), isolate);
1752   return lookup->IsTheHole() ? isolate->heap()->undefined_value() : *lookup;
1753 }
1754
1755
1756 RUNTIME_FUNCTION(Runtime_WeakCollectionHas) {
1757   HandleScope scope(isolate);
1758   DCHECK(args.length() == 2);
1759   CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
1760   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
1761   RUNTIME_ASSERT(key->IsJSReceiver() || key->IsSymbol());
1762   Handle<ObjectHashTable> table(
1763       ObjectHashTable::cast(weak_collection->table()));
1764   RUNTIME_ASSERT(table->IsKey(*key));
1765   Handle<Object> lookup(table->Lookup(key), isolate);
1766   return isolate->heap()->ToBoolean(!lookup->IsTheHole());
1767 }
1768
1769
1770 RUNTIME_FUNCTION(Runtime_WeakCollectionDelete) {
1771   HandleScope scope(isolate);
1772   DCHECK(args.length() == 2);
1773   CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
1774   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
1775   RUNTIME_ASSERT(key->IsJSReceiver() || key->IsSymbol());
1776   Handle<ObjectHashTable> table(ObjectHashTable::cast(
1777       weak_collection->table()));
1778   RUNTIME_ASSERT(table->IsKey(*key));
1779   bool was_present = false;
1780   Handle<ObjectHashTable> new_table =
1781       ObjectHashTable::Remove(table, key, &was_present);
1782   weak_collection->set_table(*new_table);
1783   return isolate->heap()->ToBoolean(was_present);
1784 }
1785
1786
1787 RUNTIME_FUNCTION(Runtime_WeakCollectionSet) {
1788   HandleScope scope(isolate);
1789   DCHECK(args.length() == 3);
1790   CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
1791   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
1792   RUNTIME_ASSERT(key->IsJSReceiver() || key->IsSymbol());
1793   CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
1794   Handle<ObjectHashTable> table(
1795       ObjectHashTable::cast(weak_collection->table()));
1796   RUNTIME_ASSERT(table->IsKey(*key));
1797   Handle<ObjectHashTable> new_table = ObjectHashTable::Put(table, key, value);
1798   weak_collection->set_table(*new_table);
1799   return *weak_collection;
1800 }
1801
1802
1803 RUNTIME_FUNCTION(Runtime_GetWeakSetValues) {
1804   HandleScope scope(isolate);
1805   DCHECK(args.length() == 1);
1806   CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, holder, 0);
1807   Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
1808   Handle<FixedArray> values =
1809       isolate->factory()->NewFixedArray(table->NumberOfElements());
1810   {
1811     DisallowHeapAllocation no_gc;
1812     int number_of_non_hole_elements = 0;
1813     for (int i = 0; i < table->Capacity(); i++) {
1814       Handle<Object> key(table->KeyAt(i), isolate);
1815       if (table->IsKey(*key)) {
1816         values->set(number_of_non_hole_elements++, *key);
1817       }
1818     }
1819     DCHECK_EQ(table->NumberOfElements(), number_of_non_hole_elements);
1820   }
1821   return *isolate->factory()->NewJSArrayWithElements(values);
1822 }
1823
1824
1825 RUNTIME_FUNCTION(Runtime_GetPrototype) {
1826   HandleScope scope(isolate);
1827   DCHECK(args.length() == 1);
1828   CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0);
1829   // We don't expect access checks to be needed on JSProxy objects.
1830   DCHECK(!obj->IsAccessCheckNeeded() || obj->IsJSObject());
1831   PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER);
1832   do {
1833     if (PrototypeIterator::GetCurrent(iter)->IsAccessCheckNeeded() &&
1834         !isolate->MayNamedAccess(
1835             Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)),
1836             isolate->factory()->proto_string(), v8::ACCESS_GET)) {
1837       isolate->ReportFailedAccessCheck(
1838           Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)),
1839           v8::ACCESS_GET);
1840       RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
1841       return isolate->heap()->undefined_value();
1842     }
1843     iter.AdvanceIgnoringProxies();
1844     if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) {
1845       return *PrototypeIterator::GetCurrent(iter);
1846     }
1847   } while (!iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN));
1848   return *PrototypeIterator::GetCurrent(iter);
1849 }
1850
1851
1852 static inline Handle<Object> GetPrototypeSkipHiddenPrototypes(
1853     Isolate* isolate, Handle<Object> receiver) {
1854   PrototypeIterator iter(isolate, receiver);
1855   while (!iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN)) {
1856     if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) {
1857       return PrototypeIterator::GetCurrent(iter);
1858     }
1859     iter.Advance();
1860   }
1861   return PrototypeIterator::GetCurrent(iter);
1862 }
1863
1864
1865 RUNTIME_FUNCTION(Runtime_InternalSetPrototype) {
1866   HandleScope scope(isolate);
1867   DCHECK(args.length() == 2);
1868   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
1869   CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
1870   DCHECK(!obj->IsAccessCheckNeeded());
1871   DCHECK(!obj->map()->is_observed());
1872   Handle<Object> result;
1873   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
1874       isolate, result, JSObject::SetPrototype(obj, prototype, false));
1875   return *result;
1876 }
1877
1878
1879 RUNTIME_FUNCTION(Runtime_SetPrototype) {
1880   HandleScope scope(isolate);
1881   DCHECK(args.length() == 2);
1882   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
1883   CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
1884   if (obj->IsAccessCheckNeeded() &&
1885       !isolate->MayNamedAccess(
1886           obj, isolate->factory()->proto_string(), v8::ACCESS_SET)) {
1887     isolate->ReportFailedAccessCheck(obj, v8::ACCESS_SET);
1888     RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
1889     return isolate->heap()->undefined_value();
1890   }
1891   if (obj->map()->is_observed()) {
1892     Handle<Object> old_value = GetPrototypeSkipHiddenPrototypes(isolate, obj);
1893     Handle<Object> result;
1894     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
1895         isolate, result,
1896         JSObject::SetPrototype(obj, prototype, true));
1897
1898     Handle<Object> new_value = GetPrototypeSkipHiddenPrototypes(isolate, obj);
1899     if (!new_value->SameValue(*old_value)) {
1900       JSObject::EnqueueChangeRecord(obj, "setPrototype",
1901                                     isolate->factory()->proto_string(),
1902                                     old_value);
1903     }
1904     return *result;
1905   }
1906   Handle<Object> result;
1907   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
1908       isolate, result,
1909       JSObject::SetPrototype(obj, prototype, true));
1910   return *result;
1911 }
1912
1913
1914 RUNTIME_FUNCTION(Runtime_IsInPrototypeChain) {
1915   HandleScope shs(isolate);
1916   DCHECK(args.length() == 2);
1917   // See ECMA-262, section 15.3.5.3, page 88 (steps 5 - 8).
1918   CONVERT_ARG_HANDLE_CHECKED(Object, O, 0);
1919   CONVERT_ARG_HANDLE_CHECKED(Object, V, 1);
1920   PrototypeIterator iter(isolate, V, PrototypeIterator::START_AT_RECEIVER);
1921   while (true) {
1922     iter.AdvanceIgnoringProxies();
1923     if (iter.IsAtEnd()) return isolate->heap()->false_value();
1924     if (iter.IsAtEnd(O)) return isolate->heap()->true_value();
1925   }
1926 }
1927
1928
1929 // Enumerator used as indices into the array returned from GetOwnProperty
1930 enum PropertyDescriptorIndices {
1931   IS_ACCESSOR_INDEX,
1932   VALUE_INDEX,
1933   GETTER_INDEX,
1934   SETTER_INDEX,
1935   WRITABLE_INDEX,
1936   ENUMERABLE_INDEX,
1937   CONFIGURABLE_INDEX,
1938   DESCRIPTOR_SIZE
1939 };
1940
1941
1942 MUST_USE_RESULT static MaybeHandle<Object> GetOwnProperty(Isolate* isolate,
1943                                                           Handle<JSObject> obj,
1944                                                           Handle<Name> name) {
1945   Heap* heap = isolate->heap();
1946   Factory* factory = isolate->factory();
1947
1948   PropertyAttributes attrs;
1949   uint32_t index = 0;
1950   Handle<Object> value;
1951   MaybeHandle<AccessorPair> maybe_accessors;
1952   // TODO(verwaest): Unify once indexed properties can be handled by the
1953   // LookupIterator.
1954   if (name->AsArrayIndex(&index)) {
1955     // Get attributes.
1956     Maybe<PropertyAttributes> maybe =
1957         JSReceiver::GetOwnElementAttribute(obj, index);
1958     if (!maybe.has_value) return MaybeHandle<Object>();
1959     attrs = maybe.value;
1960     if (attrs == ABSENT) return factory->undefined_value();
1961
1962     // Get AccessorPair if present.
1963     maybe_accessors = JSObject::GetOwnElementAccessorPair(obj, index);
1964
1965     // Get value if not an AccessorPair.
1966     if (maybe_accessors.is_null()) {
1967       ASSIGN_RETURN_ON_EXCEPTION(isolate, value,
1968           Runtime::GetElementOrCharAt(isolate, obj, index), Object);
1969     }
1970   } else {
1971     // Get attributes.
1972     LookupIterator it(obj, name, LookupIterator::CHECK_OWN);
1973     Maybe<PropertyAttributes> maybe = JSObject::GetPropertyAttributes(&it);
1974     if (!maybe.has_value) return MaybeHandle<Object>();
1975     attrs = maybe.value;
1976     if (attrs == ABSENT) return factory->undefined_value();
1977
1978     // Get AccessorPair if present.
1979     if (it.state() == LookupIterator::PROPERTY &&
1980         it.property_kind() == LookupIterator::ACCESSOR &&
1981         it.GetAccessors()->IsAccessorPair()) {
1982       maybe_accessors = Handle<AccessorPair>::cast(it.GetAccessors());
1983     }
1984
1985     // Get value if not an AccessorPair.
1986     if (maybe_accessors.is_null()) {
1987       ASSIGN_RETURN_ON_EXCEPTION(
1988           isolate, value, Object::GetProperty(&it), Object);
1989     }
1990   }
1991   DCHECK(!isolate->has_pending_exception());
1992   Handle<FixedArray> elms = factory->NewFixedArray(DESCRIPTOR_SIZE);
1993   elms->set(ENUMERABLE_INDEX, heap->ToBoolean((attrs & DONT_ENUM) == 0));
1994   elms->set(CONFIGURABLE_INDEX, heap->ToBoolean((attrs & DONT_DELETE) == 0));
1995   elms->set(IS_ACCESSOR_INDEX, heap->ToBoolean(!maybe_accessors.is_null()));
1996
1997   Handle<AccessorPair> accessors;
1998   if (maybe_accessors.ToHandle(&accessors)) {
1999     Handle<Object> getter(accessors->GetComponent(ACCESSOR_GETTER), isolate);
2000     Handle<Object> setter(accessors->GetComponent(ACCESSOR_SETTER), isolate);
2001     elms->set(GETTER_INDEX, *getter);
2002     elms->set(SETTER_INDEX, *setter);
2003   } else {
2004     elms->set(WRITABLE_INDEX, heap->ToBoolean((attrs & READ_ONLY) == 0));
2005     elms->set(VALUE_INDEX, *value);
2006   }
2007
2008   return factory->NewJSArrayWithElements(elms);
2009 }
2010
2011
2012 // Returns an array with the property description:
2013 //  if args[1] is not a property on args[0]
2014 //          returns undefined
2015 //  if args[1] is a data property on args[0]
2016 //         [false, value, Writeable, Enumerable, Configurable]
2017 //  if args[1] is an accessor on args[0]
2018 //         [true, GetFunction, SetFunction, Enumerable, Configurable]
2019 RUNTIME_FUNCTION(Runtime_GetOwnProperty) {
2020   HandleScope scope(isolate);
2021   DCHECK(args.length() == 2);
2022   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
2023   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
2024   Handle<Object> result;
2025   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
2026       isolate, result, GetOwnProperty(isolate, obj, name));
2027   return *result;
2028 }
2029
2030
2031 RUNTIME_FUNCTION(Runtime_PreventExtensions) {
2032   HandleScope scope(isolate);
2033   DCHECK(args.length() == 1);
2034   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
2035   Handle<Object> result;
2036   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
2037       isolate, result, JSObject::PreventExtensions(obj));
2038   return *result;
2039 }
2040
2041
2042 RUNTIME_FUNCTION(Runtime_IsExtensible) {
2043   SealHandleScope shs(isolate);
2044   DCHECK(args.length() == 1);
2045   CONVERT_ARG_CHECKED(JSObject, obj, 0);
2046   if (obj->IsJSGlobalProxy()) {
2047     PrototypeIterator iter(isolate, obj);
2048     if (iter.IsAtEnd()) return isolate->heap()->false_value();
2049     DCHECK(iter.GetCurrent()->IsJSGlobalObject());
2050     obj = JSObject::cast(iter.GetCurrent());
2051   }
2052   return isolate->heap()->ToBoolean(obj->map()->is_extensible());
2053 }
2054
2055
2056 RUNTIME_FUNCTION(Runtime_RegExpCompile) {
2057   HandleScope scope(isolate);
2058   DCHECK(args.length() == 3);
2059   CONVERT_ARG_HANDLE_CHECKED(JSRegExp, re, 0);
2060   CONVERT_ARG_HANDLE_CHECKED(String, pattern, 1);
2061   CONVERT_ARG_HANDLE_CHECKED(String, flags, 2);
2062   Handle<Object> result;
2063   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
2064       isolate, result, RegExpImpl::Compile(re, pattern, flags));
2065   return *result;
2066 }
2067
2068
2069 RUNTIME_FUNCTION(Runtime_CreateApiFunction) {
2070   HandleScope scope(isolate);
2071   DCHECK(args.length() == 2);
2072   CONVERT_ARG_HANDLE_CHECKED(FunctionTemplateInfo, data, 0);
2073   CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
2074   return *isolate->factory()->CreateApiFunction(data, prototype);
2075 }
2076
2077
2078 RUNTIME_FUNCTION(Runtime_IsTemplate) {
2079   SealHandleScope shs(isolate);
2080   DCHECK(args.length() == 1);
2081   CONVERT_ARG_HANDLE_CHECKED(Object, arg, 0);
2082   bool result = arg->IsObjectTemplateInfo() || arg->IsFunctionTemplateInfo();
2083   return isolate->heap()->ToBoolean(result);
2084 }
2085
2086
2087 RUNTIME_FUNCTION(Runtime_GetTemplateField) {
2088   SealHandleScope shs(isolate);
2089   DCHECK(args.length() == 2);
2090   CONVERT_ARG_CHECKED(HeapObject, templ, 0);
2091   CONVERT_SMI_ARG_CHECKED(index, 1);
2092   int offset = index * kPointerSize + HeapObject::kHeaderSize;
2093   InstanceType type = templ->map()->instance_type();
2094   RUNTIME_ASSERT(type == FUNCTION_TEMPLATE_INFO_TYPE ||
2095                  type == OBJECT_TEMPLATE_INFO_TYPE);
2096   RUNTIME_ASSERT(offset > 0);
2097   if (type == FUNCTION_TEMPLATE_INFO_TYPE) {
2098     RUNTIME_ASSERT(offset < FunctionTemplateInfo::kSize);
2099   } else {
2100     RUNTIME_ASSERT(offset < ObjectTemplateInfo::kSize);
2101   }
2102   return *HeapObject::RawField(templ, offset);
2103 }
2104
2105
2106 RUNTIME_FUNCTION(Runtime_DisableAccessChecks) {
2107   HandleScope scope(isolate);
2108   DCHECK(args.length() == 1);
2109   CONVERT_ARG_HANDLE_CHECKED(HeapObject, object, 0);
2110   Handle<Map> old_map(object->map());
2111   bool needs_access_checks = old_map->is_access_check_needed();
2112   if (needs_access_checks) {
2113     // Copy map so it won't interfere constructor's initial map.
2114     Handle<Map> new_map = Map::Copy(old_map);
2115     new_map->set_is_access_check_needed(false);
2116     JSObject::MigrateToMap(Handle<JSObject>::cast(object), new_map);
2117   }
2118   return isolate->heap()->ToBoolean(needs_access_checks);
2119 }
2120
2121
2122 RUNTIME_FUNCTION(Runtime_EnableAccessChecks) {
2123   HandleScope scope(isolate);
2124   DCHECK(args.length() == 1);
2125   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
2126   Handle<Map> old_map(object->map());
2127   RUNTIME_ASSERT(!old_map->is_access_check_needed());
2128   // Copy map so it won't interfere constructor's initial map.
2129   Handle<Map> new_map = Map::Copy(old_map);
2130   new_map->set_is_access_check_needed(true);
2131   JSObject::MigrateToMap(object, new_map);
2132   return isolate->heap()->undefined_value();
2133 }
2134
2135
2136 static Object* ThrowRedeclarationError(Isolate* isolate, Handle<String> name) {
2137   HandleScope scope(isolate);
2138   Handle<Object> args[1] = { name };
2139   Handle<Object> error = isolate->factory()->NewTypeError(
2140       "var_redeclaration", HandleVector(args, 1));
2141   return isolate->Throw(*error);
2142 }
2143
2144
2145 // May throw a RedeclarationError.
2146 static Object* DeclareGlobals(Isolate* isolate, Handle<GlobalObject> global,
2147                               Handle<String> name, Handle<Object> value,
2148                               PropertyAttributes attr, bool is_var,
2149                               bool is_const, bool is_function) {
2150   // Do the lookup own properties only, see ES5 erratum.
2151   LookupIterator it(global, name, LookupIterator::CHECK_HIDDEN);
2152   Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
2153   DCHECK(maybe.has_value);
2154   PropertyAttributes old_attributes = maybe.value;
2155
2156   if (old_attributes != ABSENT) {
2157     // The name was declared before; check for conflicting re-declarations.
2158     if (is_const) return ThrowRedeclarationError(isolate, name);
2159
2160     // Skip var re-declarations.
2161     if (is_var) return isolate->heap()->undefined_value();
2162
2163     DCHECK(is_function);
2164     if ((old_attributes & DONT_DELETE) != 0) {
2165       // Only allow reconfiguring globals to functions in user code (no
2166       // natives, which are marked as read-only).
2167       DCHECK((attr & READ_ONLY) == 0);
2168
2169       // Check whether we can reconfigure the existing property into a
2170       // function.
2171       PropertyDetails old_details = it.property_details();
2172       // TODO(verwaest): CALLBACKS invalidly includes ExecutableAccessInfo,
2173       // which are actually data properties, not accessor properties.
2174       if (old_details.IsReadOnly() || old_details.IsDontEnum() ||
2175           old_details.type() == CALLBACKS) {
2176         return ThrowRedeclarationError(isolate, name);
2177       }
2178       // If the existing property is not configurable, keep its attributes. Do
2179       attr = old_attributes;
2180     }
2181   }
2182
2183   // Define or redefine own property.
2184   RETURN_FAILURE_ON_EXCEPTION(isolate, JSObject::SetOwnPropertyIgnoreAttributes(
2185                                            global, name, value, attr));
2186
2187   return isolate->heap()->undefined_value();
2188 }
2189
2190
2191 RUNTIME_FUNCTION(Runtime_DeclareGlobals) {
2192   HandleScope scope(isolate);
2193   DCHECK(args.length() == 3);
2194   Handle<GlobalObject> global(isolate->global_object());
2195
2196   CONVERT_ARG_HANDLE_CHECKED(Context, context, 0);
2197   CONVERT_ARG_HANDLE_CHECKED(FixedArray, pairs, 1);
2198   CONVERT_SMI_ARG_CHECKED(flags, 2);
2199
2200   // Traverse the name/value pairs and set the properties.
2201   int length = pairs->length();
2202   for (int i = 0; i < length; i += 2) {
2203     HandleScope scope(isolate);
2204     Handle<String> name(String::cast(pairs->get(i)));
2205     Handle<Object> initial_value(pairs->get(i + 1), isolate);
2206
2207     // We have to declare a global const property. To capture we only
2208     // assign to it when evaluating the assignment for "const x =
2209     // <expr>" the initial value is the hole.
2210     bool is_var = initial_value->IsUndefined();
2211     bool is_const = initial_value->IsTheHole();
2212     bool is_function = initial_value->IsSharedFunctionInfo();
2213     DCHECK(is_var + is_const + is_function == 1);
2214
2215     Handle<Object> value;
2216     if (is_function) {
2217       // Copy the function and update its context. Use it as value.
2218       Handle<SharedFunctionInfo> shared =
2219           Handle<SharedFunctionInfo>::cast(initial_value);
2220       Handle<JSFunction> function =
2221           isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, context,
2222                                                                 TENURED);
2223       value = function;
2224     } else {
2225       value = isolate->factory()->undefined_value();
2226     }
2227
2228     // Compute the property attributes. According to ECMA-262,
2229     // the property must be non-configurable except in eval.
2230     bool is_native = DeclareGlobalsNativeFlag::decode(flags);
2231     bool is_eval = DeclareGlobalsEvalFlag::decode(flags);
2232     int attr = NONE;
2233     if (is_const) attr |= READ_ONLY;
2234     if (is_function && is_native) attr |= READ_ONLY;
2235     if (!is_const && !is_eval) attr |= DONT_DELETE;
2236
2237     Object* result = DeclareGlobals(isolate, global, name, value,
2238                                     static_cast<PropertyAttributes>(attr),
2239                                     is_var, is_const, is_function);
2240     if (isolate->has_pending_exception()) return result;
2241   }
2242
2243   return isolate->heap()->undefined_value();
2244 }
2245
2246
2247 RUNTIME_FUNCTION(Runtime_InitializeVarGlobal) {
2248   HandleScope scope(isolate);
2249   // args[0] == name
2250   // args[1] == language_mode
2251   // args[2] == value (optional)
2252
2253   // Determine if we need to assign to the variable if it already
2254   // exists (based on the number of arguments).
2255   RUNTIME_ASSERT(args.length() == 3);
2256
2257   CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
2258   CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 1);
2259   CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
2260
2261   Handle<GlobalObject> global(isolate->context()->global_object());
2262   Handle<Object> result;
2263   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
2264       isolate, result, Object::SetProperty(global, name, value, strict_mode));
2265   return *result;
2266 }
2267
2268
2269 RUNTIME_FUNCTION(Runtime_InitializeConstGlobal) {
2270   HandleScope handle_scope(isolate);
2271   // All constants are declared with an initial value. The name
2272   // of the constant is the first argument and the initial value
2273   // is the second.
2274   RUNTIME_ASSERT(args.length() == 2);
2275   CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
2276   CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
2277
2278   Handle<GlobalObject> global = isolate->global_object();
2279
2280   // Lookup the property as own on the global object.
2281   LookupIterator it(global, name, LookupIterator::CHECK_HIDDEN);
2282   Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
2283   DCHECK(maybe.has_value);
2284   PropertyAttributes old_attributes = maybe.value;
2285
2286   PropertyAttributes attr =
2287       static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY);
2288   // Set the value if the property is either missing, or the property attributes
2289   // allow setting the value without invoking an accessor.
2290   if (it.IsFound()) {
2291     // Ignore if we can't reconfigure the value.
2292     if ((old_attributes & DONT_DELETE) != 0) {
2293       if ((old_attributes & READ_ONLY) != 0 ||
2294           it.property_kind() == LookupIterator::ACCESSOR) {
2295         return *value;
2296       }
2297       attr = static_cast<PropertyAttributes>(old_attributes | READ_ONLY);
2298     }
2299   }
2300
2301   RETURN_FAILURE_ON_EXCEPTION(isolate, JSObject::SetOwnPropertyIgnoreAttributes(
2302                                            global, name, value, attr));
2303
2304   return *value;
2305 }
2306
2307
2308 RUNTIME_FUNCTION(Runtime_DeclareLookupSlot) {
2309   HandleScope scope(isolate);
2310   DCHECK(args.length() == 4);
2311
2312   // Declarations are always made in a function, native, or global context. In
2313   // the case of eval code, the context passed is the context of the caller,
2314   // which may be some nested context and not the declaration context.
2315   CONVERT_ARG_HANDLE_CHECKED(Context, context_arg, 0);
2316   Handle<Context> context(context_arg->declaration_context());
2317   CONVERT_ARG_HANDLE_CHECKED(String, name, 1);
2318   CONVERT_SMI_ARG_CHECKED(attr_arg, 2);
2319   PropertyAttributes attr = static_cast<PropertyAttributes>(attr_arg);
2320   RUNTIME_ASSERT(attr == READ_ONLY || attr == NONE);
2321   CONVERT_ARG_HANDLE_CHECKED(Object, initial_value, 3);
2322
2323   // TODO(verwaest): Unify the encoding indicating "var" with DeclareGlobals.
2324   bool is_var = *initial_value == NULL;
2325   bool is_const = initial_value->IsTheHole();
2326   bool is_function = initial_value->IsJSFunction();
2327   DCHECK(is_var + is_const + is_function == 1);
2328
2329   int index;
2330   PropertyAttributes attributes;
2331   ContextLookupFlags flags = DONT_FOLLOW_CHAINS;
2332   BindingFlags binding_flags;
2333   Handle<Object> holder =
2334       context->Lookup(name, flags, &index, &attributes, &binding_flags);
2335
2336   Handle<JSObject> object;
2337   Handle<Object> value =
2338       is_function ? initial_value
2339                   : Handle<Object>::cast(isolate->factory()->undefined_value());
2340
2341   // TODO(verwaest): This case should probably not be covered by this function,
2342   // but by DeclareGlobals instead.
2343   if ((attributes != ABSENT && holder->IsJSGlobalObject()) ||
2344       (context_arg->has_extension() &&
2345        context_arg->extension()->IsJSGlobalObject())) {
2346     return DeclareGlobals(isolate, Handle<JSGlobalObject>::cast(holder), name,
2347                           value, attr, is_var, is_const, is_function);
2348   }
2349
2350   if (attributes != ABSENT) {
2351     // The name was declared before; check for conflicting re-declarations.
2352     if (is_const || (attributes & READ_ONLY) != 0) {
2353       return ThrowRedeclarationError(isolate, name);
2354     }
2355
2356     // Skip var re-declarations.
2357     if (is_var) return isolate->heap()->undefined_value();
2358
2359     DCHECK(is_function);
2360     if (index >= 0) {
2361       DCHECK(holder.is_identical_to(context));
2362       context->set(index, *initial_value);
2363       return isolate->heap()->undefined_value();
2364     }
2365
2366     object = Handle<JSObject>::cast(holder);
2367
2368   } else if (context->has_extension()) {
2369     object = handle(JSObject::cast(context->extension()));
2370     DCHECK(object->IsJSContextExtensionObject() || object->IsJSGlobalObject());
2371   } else {
2372     DCHECK(context->IsFunctionContext());
2373     object =
2374         isolate->factory()->NewJSObject(isolate->context_extension_function());
2375     context->set_extension(*object);
2376   }
2377
2378   RETURN_FAILURE_ON_EXCEPTION(isolate, JSObject::SetOwnPropertyIgnoreAttributes(
2379                                            object, name, value, attr));
2380
2381   return isolate->heap()->undefined_value();
2382 }
2383
2384
2385 RUNTIME_FUNCTION(Runtime_InitializeLegacyConstLookupSlot) {
2386   HandleScope scope(isolate);
2387   DCHECK(args.length() == 3);
2388
2389   CONVERT_ARG_HANDLE_CHECKED(Object, value, 0);
2390   DCHECK(!value->IsTheHole());
2391   // Initializations are always done in a function or native context.
2392   CONVERT_ARG_HANDLE_CHECKED(Context, context_arg, 1);
2393   Handle<Context> context(context_arg->declaration_context());
2394   CONVERT_ARG_HANDLE_CHECKED(String, name, 2);
2395
2396   int index;
2397   PropertyAttributes attributes;
2398   ContextLookupFlags flags = DONT_FOLLOW_CHAINS;
2399   BindingFlags binding_flags;
2400   Handle<Object> holder =
2401       context->Lookup(name, flags, &index, &attributes, &binding_flags);
2402
2403   if (index >= 0) {
2404     DCHECK(holder->IsContext());
2405     // Property was found in a context.  Perform the assignment if the constant
2406     // was uninitialized.
2407     Handle<Context> context = Handle<Context>::cast(holder);
2408     DCHECK((attributes & READ_ONLY) != 0);
2409     if (context->get(index)->IsTheHole()) context->set(index, *value);
2410     return *value;
2411   }
2412
2413   PropertyAttributes attr =
2414       static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY);
2415
2416   // Strict mode handling not needed (legacy const is disallowed in strict
2417   // mode).
2418
2419   // The declared const was configurable, and may have been deleted in the
2420   // meanwhile. If so, re-introduce the variable in the context extension.
2421   DCHECK(context_arg->has_extension());
2422   if (attributes == ABSENT) {
2423     holder = handle(context_arg->extension(), isolate);
2424   } else {
2425     // For JSContextExtensionObjects, the initializer can be run multiple times
2426     // if in a for loop: for (var i = 0; i < 2; i++) { const x = i; }. Only the
2427     // first assignment should go through. For JSGlobalObjects, additionally any
2428     // code can run in between that modifies the declared property.
2429     DCHECK(holder->IsJSGlobalObject() || holder->IsJSContextExtensionObject());
2430
2431     LookupIterator it(holder, name, LookupIterator::CHECK_HIDDEN);
2432     Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
2433     if (!maybe.has_value) return isolate->heap()->exception();
2434     PropertyAttributes old_attributes = maybe.value;
2435
2436     // Ignore if we can't reconfigure the value.
2437     if ((old_attributes & DONT_DELETE) != 0) {
2438       if ((old_attributes & READ_ONLY) != 0 ||
2439           it.property_kind() == LookupIterator::ACCESSOR) {
2440         return *value;
2441       }
2442       attr = static_cast<PropertyAttributes>(old_attributes | READ_ONLY);
2443     }
2444   }
2445
2446   RETURN_FAILURE_ON_EXCEPTION(
2447       isolate, JSObject::SetOwnPropertyIgnoreAttributes(
2448                    Handle<JSObject>::cast(holder), name, value, attr));
2449
2450   return *value;
2451 }
2452
2453
2454 RUNTIME_FUNCTION(Runtime_OptimizeObjectForAddingMultipleProperties) {
2455   HandleScope scope(isolate);
2456   DCHECK(args.length() == 2);
2457   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
2458   CONVERT_SMI_ARG_CHECKED(properties, 1);
2459   // Conservative upper limit to prevent fuzz tests from going OOM.
2460   RUNTIME_ASSERT(properties <= 100000);
2461   if (object->HasFastProperties() && !object->IsJSGlobalProxy()) {
2462     JSObject::NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, properties);
2463   }
2464   return *object;
2465 }
2466
2467
2468 RUNTIME_FUNCTION(Runtime_RegExpExecRT) {
2469   HandleScope scope(isolate);
2470   DCHECK(args.length() == 4);
2471   CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0);
2472   CONVERT_ARG_HANDLE_CHECKED(String, subject, 1);
2473   // Due to the way the JS calls are constructed this must be less than the
2474   // length of a string, i.e. it is always a Smi.  We check anyway for security.
2475   CONVERT_SMI_ARG_CHECKED(index, 2);
2476   CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 3);
2477   RUNTIME_ASSERT(index >= 0);
2478   RUNTIME_ASSERT(index <= subject->length());
2479   isolate->counters()->regexp_entry_runtime()->Increment();
2480   Handle<Object> result;
2481   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
2482       isolate, result,
2483       RegExpImpl::Exec(regexp, subject, index, last_match_info));
2484   return *result;
2485 }
2486
2487
2488 RUNTIME_FUNCTION(Runtime_RegExpConstructResult) {
2489   HandleScope handle_scope(isolate);
2490   DCHECK(args.length() == 3);
2491   CONVERT_SMI_ARG_CHECKED(size, 0);
2492   RUNTIME_ASSERT(size >= 0 && size <= FixedArray::kMaxLength);
2493   CONVERT_ARG_HANDLE_CHECKED(Object, index, 1);
2494   CONVERT_ARG_HANDLE_CHECKED(Object, input, 2);
2495   Handle<FixedArray> elements =  isolate->factory()->NewFixedArray(size);
2496   Handle<Map> regexp_map(isolate->native_context()->regexp_result_map());
2497   Handle<JSObject> object =
2498       isolate->factory()->NewJSObjectFromMap(regexp_map, NOT_TENURED, false);
2499   Handle<JSArray> array = Handle<JSArray>::cast(object);
2500   array->set_elements(*elements);
2501   array->set_length(Smi::FromInt(size));
2502   // Write in-object properties after the length of the array.
2503   array->InObjectPropertyAtPut(JSRegExpResult::kIndexIndex, *index);
2504   array->InObjectPropertyAtPut(JSRegExpResult::kInputIndex, *input);
2505   return *array;
2506 }
2507
2508
2509 RUNTIME_FUNCTION(Runtime_RegExpInitializeObject) {
2510   HandleScope scope(isolate);
2511   DCHECK(args.length() == 5);
2512   CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0);
2513   CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
2514   // If source is the empty string we set it to "(?:)" instead as
2515   // suggested by ECMA-262, 5th, section 15.10.4.1.
2516   if (source->length() == 0) source = isolate->factory()->query_colon_string();
2517
2518   CONVERT_ARG_HANDLE_CHECKED(Object, global, 2);
2519   if (!global->IsTrue()) global = isolate->factory()->false_value();
2520
2521   CONVERT_ARG_HANDLE_CHECKED(Object, ignoreCase, 3);
2522   if (!ignoreCase->IsTrue()) ignoreCase = isolate->factory()->false_value();
2523
2524   CONVERT_ARG_HANDLE_CHECKED(Object, multiline, 4);
2525   if (!multiline->IsTrue()) multiline = isolate->factory()->false_value();
2526
2527   Map* map = regexp->map();
2528   Object* constructor = map->constructor();
2529   if (constructor->IsJSFunction() &&
2530       JSFunction::cast(constructor)->initial_map() == map) {
2531     // If we still have the original map, set in-object properties directly.
2532     regexp->InObjectPropertyAtPut(JSRegExp::kSourceFieldIndex, *source);
2533     // Both true and false are immovable immortal objects so no need for write
2534     // barrier.
2535     regexp->InObjectPropertyAtPut(
2536         JSRegExp::kGlobalFieldIndex, *global, SKIP_WRITE_BARRIER);
2537     regexp->InObjectPropertyAtPut(
2538         JSRegExp::kIgnoreCaseFieldIndex, *ignoreCase, SKIP_WRITE_BARRIER);
2539     regexp->InObjectPropertyAtPut(
2540         JSRegExp::kMultilineFieldIndex, *multiline, SKIP_WRITE_BARRIER);
2541     regexp->InObjectPropertyAtPut(
2542         JSRegExp::kLastIndexFieldIndex, Smi::FromInt(0), SKIP_WRITE_BARRIER);
2543     return *regexp;
2544   }
2545
2546   // Map has changed, so use generic, but slower, method.
2547   PropertyAttributes final =
2548       static_cast<PropertyAttributes>(READ_ONLY | DONT_ENUM | DONT_DELETE);
2549   PropertyAttributes writable =
2550       static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
2551   Handle<Object> zero(Smi::FromInt(0), isolate);
2552   Factory* factory = isolate->factory();
2553   JSObject::SetOwnPropertyIgnoreAttributes(
2554       regexp, factory->source_string(), source, final).Check();
2555   JSObject::SetOwnPropertyIgnoreAttributes(
2556       regexp, factory->global_string(), global, final).Check();
2557   JSObject::SetOwnPropertyIgnoreAttributes(
2558       regexp, factory->ignore_case_string(), ignoreCase, final).Check();
2559   JSObject::SetOwnPropertyIgnoreAttributes(
2560       regexp, factory->multiline_string(), multiline, final).Check();
2561   JSObject::SetOwnPropertyIgnoreAttributes(
2562       regexp, factory->last_index_string(), zero, writable).Check();
2563   return *regexp;
2564 }
2565
2566
2567 RUNTIME_FUNCTION(Runtime_FinishArrayPrototypeSetup) {
2568   HandleScope scope(isolate);
2569   DCHECK(args.length() == 1);
2570   CONVERT_ARG_HANDLE_CHECKED(JSArray, prototype, 0);
2571   Object* length = prototype->length();
2572   RUNTIME_ASSERT(length->IsSmi() && Smi::cast(length)->value() == 0);
2573   RUNTIME_ASSERT(prototype->HasFastSmiOrObjectElements());
2574   // This is necessary to enable fast checks for absence of elements
2575   // on Array.prototype and below.
2576   prototype->set_elements(isolate->heap()->empty_fixed_array());
2577   return Smi::FromInt(0);
2578 }
2579
2580
2581 static void InstallBuiltin(Isolate* isolate,
2582                            Handle<JSObject> holder,
2583                            const char* name,
2584                            Builtins::Name builtin_name) {
2585   Handle<String> key = isolate->factory()->InternalizeUtf8String(name);
2586   Handle<Code> code(isolate->builtins()->builtin(builtin_name));
2587   Handle<JSFunction> optimized =
2588       isolate->factory()->NewFunctionWithoutPrototype(key, code);
2589   optimized->shared()->DontAdaptArguments();
2590   JSObject::AddProperty(holder, key, optimized, NONE);
2591 }
2592
2593
2594 RUNTIME_FUNCTION(Runtime_SpecialArrayFunctions) {
2595   HandleScope scope(isolate);
2596   DCHECK(args.length() == 0);
2597   Handle<JSObject> holder =
2598       isolate->factory()->NewJSObject(isolate->object_function());
2599
2600   InstallBuiltin(isolate, holder, "pop", Builtins::kArrayPop);
2601   InstallBuiltin(isolate, holder, "push", Builtins::kArrayPush);
2602   InstallBuiltin(isolate, holder, "shift", Builtins::kArrayShift);
2603   InstallBuiltin(isolate, holder, "unshift", Builtins::kArrayUnshift);
2604   InstallBuiltin(isolate, holder, "slice", Builtins::kArraySlice);
2605   InstallBuiltin(isolate, holder, "splice", Builtins::kArraySplice);
2606   InstallBuiltin(isolate, holder, "concat", Builtins::kArrayConcat);
2607
2608   return *holder;
2609 }
2610
2611
2612 RUNTIME_FUNCTION(Runtime_IsSloppyModeFunction) {
2613   SealHandleScope shs(isolate);
2614   DCHECK(args.length() == 1);
2615   CONVERT_ARG_CHECKED(JSReceiver, callable, 0);
2616   if (!callable->IsJSFunction()) {
2617     HandleScope scope(isolate);
2618     Handle<Object> delegate;
2619     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
2620         isolate, delegate,
2621         Execution::TryGetFunctionDelegate(
2622             isolate, Handle<JSReceiver>(callable)));
2623     callable = JSFunction::cast(*delegate);
2624   }
2625   JSFunction* function = JSFunction::cast(callable);
2626   SharedFunctionInfo* shared = function->shared();
2627   return isolate->heap()->ToBoolean(shared->strict_mode() == SLOPPY);
2628 }
2629
2630
2631 RUNTIME_FUNCTION(Runtime_GetDefaultReceiver) {
2632   SealHandleScope shs(isolate);
2633   DCHECK(args.length() == 1);
2634   CONVERT_ARG_CHECKED(JSReceiver, callable, 0);
2635
2636   if (!callable->IsJSFunction()) {
2637     HandleScope scope(isolate);
2638     Handle<Object> delegate;
2639     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
2640         isolate, delegate,
2641         Execution::TryGetFunctionDelegate(
2642             isolate, Handle<JSReceiver>(callable)));
2643     callable = JSFunction::cast(*delegate);
2644   }
2645   JSFunction* function = JSFunction::cast(callable);
2646
2647   SharedFunctionInfo* shared = function->shared();
2648   if (shared->native() || shared->strict_mode() == STRICT) {
2649     return isolate->heap()->undefined_value();
2650   }
2651   // Returns undefined for strict or native functions, or
2652   // the associated global receiver for "normal" functions.
2653
2654   return function->global_proxy();
2655 }
2656
2657
2658 RUNTIME_FUNCTION(Runtime_MaterializeRegExpLiteral) {
2659   HandleScope scope(isolate);
2660   DCHECK(args.length() == 4);
2661   CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
2662   CONVERT_SMI_ARG_CHECKED(index, 1);
2663   CONVERT_ARG_HANDLE_CHECKED(String, pattern, 2);
2664   CONVERT_ARG_HANDLE_CHECKED(String, flags, 3);
2665
2666   // Get the RegExp function from the context in the literals array.
2667   // This is the RegExp function from the context in which the
2668   // function was created.  We do not use the RegExp function from the
2669   // current native context because this might be the RegExp function
2670   // from another context which we should not have access to.
2671   Handle<JSFunction> constructor =
2672       Handle<JSFunction>(
2673           JSFunction::NativeContextFromLiterals(*literals)->regexp_function());
2674   // Compute the regular expression literal.
2675   Handle<Object> regexp;
2676   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
2677       isolate, regexp,
2678       RegExpImpl::CreateRegExpLiteral(constructor, pattern, flags));
2679   literals->set(index, *regexp);
2680   return *regexp;
2681 }
2682
2683
2684 RUNTIME_FUNCTION(Runtime_FunctionGetName) {
2685   SealHandleScope shs(isolate);
2686   DCHECK(args.length() == 1);
2687
2688   CONVERT_ARG_CHECKED(JSFunction, f, 0);
2689   return f->shared()->name();
2690 }
2691
2692
2693 RUNTIME_FUNCTION(Runtime_FunctionSetName) {
2694   SealHandleScope shs(isolate);
2695   DCHECK(args.length() == 2);
2696
2697   CONVERT_ARG_CHECKED(JSFunction, f, 0);
2698   CONVERT_ARG_CHECKED(String, name, 1);
2699   f->shared()->set_name(name);
2700   return isolate->heap()->undefined_value();
2701 }
2702
2703
2704 RUNTIME_FUNCTION(Runtime_FunctionNameShouldPrintAsAnonymous) {
2705   SealHandleScope shs(isolate);
2706   DCHECK(args.length() == 1);
2707   CONVERT_ARG_CHECKED(JSFunction, f, 0);
2708   return isolate->heap()->ToBoolean(
2709       f->shared()->name_should_print_as_anonymous());
2710 }
2711
2712
2713 RUNTIME_FUNCTION(Runtime_FunctionMarkNameShouldPrintAsAnonymous) {
2714   SealHandleScope shs(isolate);
2715   DCHECK(args.length() == 1);
2716   CONVERT_ARG_CHECKED(JSFunction, f, 0);
2717   f->shared()->set_name_should_print_as_anonymous(true);
2718   return isolate->heap()->undefined_value();
2719 }
2720
2721
2722 RUNTIME_FUNCTION(Runtime_FunctionIsGenerator) {
2723   SealHandleScope shs(isolate);
2724   DCHECK(args.length() == 1);
2725   CONVERT_ARG_CHECKED(JSFunction, f, 0);
2726   return isolate->heap()->ToBoolean(f->shared()->is_generator());
2727 }
2728
2729
2730 RUNTIME_FUNCTION(Runtime_FunctionIsArrow) {
2731   SealHandleScope shs(isolate);
2732   DCHECK(args.length() == 1);
2733   CONVERT_ARG_CHECKED(JSFunction, f, 0);
2734   return isolate->heap()->ToBoolean(f->shared()->is_arrow());
2735 }
2736
2737
2738 RUNTIME_FUNCTION(Runtime_FunctionRemovePrototype) {
2739   SealHandleScope shs(isolate);
2740   DCHECK(args.length() == 1);
2741
2742   CONVERT_ARG_CHECKED(JSFunction, f, 0);
2743   RUNTIME_ASSERT(f->RemovePrototype());
2744
2745   return isolate->heap()->undefined_value();
2746 }
2747
2748
2749 RUNTIME_FUNCTION(Runtime_FunctionGetScript) {
2750   HandleScope scope(isolate);
2751   DCHECK(args.length() == 1);
2752
2753   CONVERT_ARG_CHECKED(JSFunction, fun, 0);
2754   Handle<Object> script = Handle<Object>(fun->shared()->script(), isolate);
2755   if (!script->IsScript()) return isolate->heap()->undefined_value();
2756
2757   return *Script::GetWrapper(Handle<Script>::cast(script));
2758 }
2759
2760
2761 RUNTIME_FUNCTION(Runtime_FunctionGetSourceCode) {
2762   HandleScope scope(isolate);
2763   DCHECK(args.length() == 1);
2764
2765   CONVERT_ARG_HANDLE_CHECKED(JSFunction, f, 0);
2766   Handle<SharedFunctionInfo> shared(f->shared());
2767   return *shared->GetSourceCode();
2768 }
2769
2770
2771 RUNTIME_FUNCTION(Runtime_FunctionGetScriptSourcePosition) {
2772   SealHandleScope shs(isolate);
2773   DCHECK(args.length() == 1);
2774
2775   CONVERT_ARG_CHECKED(JSFunction, fun, 0);
2776   int pos = fun->shared()->start_position();
2777   return Smi::FromInt(pos);
2778 }
2779
2780
2781 RUNTIME_FUNCTION(Runtime_FunctionGetPositionForOffset) {
2782   SealHandleScope shs(isolate);
2783   DCHECK(args.length() == 2);
2784
2785   CONVERT_ARG_CHECKED(Code, code, 0);
2786   CONVERT_NUMBER_CHECKED(int, offset, Int32, args[1]);
2787
2788   RUNTIME_ASSERT(0 <= offset && offset < code->Size());
2789
2790   Address pc = code->address() + offset;
2791   return Smi::FromInt(code->SourcePosition(pc));
2792 }
2793
2794
2795 RUNTIME_FUNCTION(Runtime_FunctionSetInstanceClassName) {
2796   SealHandleScope shs(isolate);
2797   DCHECK(args.length() == 2);
2798
2799   CONVERT_ARG_CHECKED(JSFunction, fun, 0);
2800   CONVERT_ARG_CHECKED(String, name, 1);
2801   fun->SetInstanceClassName(name);
2802   return isolate->heap()->undefined_value();
2803 }
2804
2805
2806 RUNTIME_FUNCTION(Runtime_FunctionSetLength) {
2807   SealHandleScope shs(isolate);
2808   DCHECK(args.length() == 2);
2809
2810   CONVERT_ARG_CHECKED(JSFunction, fun, 0);
2811   CONVERT_SMI_ARG_CHECKED(length, 1);
2812   RUNTIME_ASSERT((length & 0xC0000000) == 0xC0000000 ||
2813                  (length & 0xC0000000) == 0x0);
2814   fun->shared()->set_length(length);
2815   return isolate->heap()->undefined_value();
2816 }
2817
2818
2819 RUNTIME_FUNCTION(Runtime_FunctionSetPrototype) {
2820   HandleScope scope(isolate);
2821   DCHECK(args.length() == 2);
2822
2823   CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
2824   CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
2825   RUNTIME_ASSERT(fun->should_have_prototype());
2826   Accessors::FunctionSetPrototype(fun, value);
2827   return args[0];  // return TOS
2828 }
2829
2830
2831 RUNTIME_FUNCTION(Runtime_FunctionIsAPIFunction) {
2832   SealHandleScope shs(isolate);
2833   DCHECK(args.length() == 1);
2834
2835   CONVERT_ARG_CHECKED(JSFunction, f, 0);
2836   return isolate->heap()->ToBoolean(f->shared()->IsApiFunction());
2837 }
2838
2839
2840 RUNTIME_FUNCTION(Runtime_FunctionIsBuiltin) {
2841   SealHandleScope shs(isolate);
2842   DCHECK(args.length() == 1);
2843
2844   CONVERT_ARG_CHECKED(JSFunction, f, 0);
2845   return isolate->heap()->ToBoolean(f->IsBuiltin());
2846 }
2847
2848
2849 RUNTIME_FUNCTION(Runtime_SetCode) {
2850   HandleScope scope(isolate);
2851   DCHECK(args.length() == 2);
2852
2853   CONVERT_ARG_HANDLE_CHECKED(JSFunction, target, 0);
2854   CONVERT_ARG_HANDLE_CHECKED(JSFunction, source, 1);
2855
2856   Handle<SharedFunctionInfo> target_shared(target->shared());
2857   Handle<SharedFunctionInfo> source_shared(source->shared());
2858   RUNTIME_ASSERT(!source_shared->bound());
2859
2860   if (!Compiler::EnsureCompiled(source, KEEP_EXCEPTION)) {
2861     return isolate->heap()->exception();
2862   }
2863
2864   // Mark both, the source and the target, as un-flushable because the
2865   // shared unoptimized code makes them impossible to enqueue in a list.
2866   DCHECK(target_shared->code()->gc_metadata() == NULL);
2867   DCHECK(source_shared->code()->gc_metadata() == NULL);
2868   target_shared->set_dont_flush(true);
2869   source_shared->set_dont_flush(true);
2870
2871   // Set the code, scope info, formal parameter count, and the length
2872   // of the target shared function info.
2873   target_shared->ReplaceCode(source_shared->code());
2874   target_shared->set_scope_info(source_shared->scope_info());
2875   target_shared->set_length(source_shared->length());
2876   target_shared->set_feedback_vector(source_shared->feedback_vector());
2877   target_shared->set_formal_parameter_count(
2878       source_shared->formal_parameter_count());
2879   target_shared->set_script(source_shared->script());
2880   target_shared->set_start_position_and_type(
2881       source_shared->start_position_and_type());
2882   target_shared->set_end_position(source_shared->end_position());
2883   bool was_native = target_shared->native();
2884   target_shared->set_compiler_hints(source_shared->compiler_hints());
2885   target_shared->set_native(was_native);
2886   target_shared->set_profiler_ticks(source_shared->profiler_ticks());
2887
2888   // Set the code of the target function.
2889   target->ReplaceCode(source_shared->code());
2890   DCHECK(target->next_function_link()->IsUndefined());
2891
2892   // Make sure we get a fresh copy of the literal vector to avoid cross
2893   // context contamination.
2894   Handle<Context> context(source->context());
2895   int number_of_literals = source->NumberOfLiterals();
2896   Handle<FixedArray> literals =
2897       isolate->factory()->NewFixedArray(number_of_literals, TENURED);
2898   if (number_of_literals > 0) {
2899     literals->set(JSFunction::kLiteralNativeContextIndex,
2900                   context->native_context());
2901   }
2902   target->set_context(*context);
2903   target->set_literals(*literals);
2904
2905   if (isolate->logger()->is_logging_code_events() ||
2906       isolate->cpu_profiler()->is_profiling()) {
2907     isolate->logger()->LogExistingFunction(
2908         source_shared, Handle<Code>(source_shared->code()));
2909   }
2910
2911   return *target;
2912 }
2913
2914
2915 RUNTIME_FUNCTION(Runtime_CreateJSGeneratorObject) {
2916   HandleScope scope(isolate);
2917   DCHECK(args.length() == 0);
2918
2919   JavaScriptFrameIterator it(isolate);
2920   JavaScriptFrame* frame = it.frame();
2921   Handle<JSFunction> function(frame->function());
2922   RUNTIME_ASSERT(function->shared()->is_generator());
2923
2924   Handle<JSGeneratorObject> generator;
2925   if (frame->IsConstructor()) {
2926     generator = handle(JSGeneratorObject::cast(frame->receiver()));
2927   } else {
2928     generator = isolate->factory()->NewJSGeneratorObject(function);
2929   }
2930   generator->set_function(*function);
2931   generator->set_context(Context::cast(frame->context()));
2932   generator->set_receiver(frame->receiver());
2933   generator->set_continuation(0);
2934   generator->set_operand_stack(isolate->heap()->empty_fixed_array());
2935   generator->set_stack_handler_index(-1);
2936
2937   return *generator;
2938 }
2939
2940
2941 RUNTIME_FUNCTION(Runtime_SuspendJSGeneratorObject) {
2942   HandleScope handle_scope(isolate);
2943   DCHECK(args.length() == 1);
2944   CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator_object, 0);
2945
2946   JavaScriptFrameIterator stack_iterator(isolate);
2947   JavaScriptFrame* frame = stack_iterator.frame();
2948   RUNTIME_ASSERT(frame->function()->shared()->is_generator());
2949   DCHECK_EQ(frame->function(), generator_object->function());
2950
2951   // The caller should have saved the context and continuation already.
2952   DCHECK_EQ(generator_object->context(), Context::cast(frame->context()));
2953   DCHECK_LT(0, generator_object->continuation());
2954
2955   // We expect there to be at least two values on the operand stack: the return
2956   // value of the yield expression, and the argument to this runtime call.
2957   // Neither of those should be saved.
2958   int operands_count = frame->ComputeOperandsCount();
2959   DCHECK_GE(operands_count, 2);
2960   operands_count -= 2;
2961
2962   if (operands_count == 0) {
2963     // Although it's semantically harmless to call this function with an
2964     // operands_count of zero, it is also unnecessary.
2965     DCHECK_EQ(generator_object->operand_stack(),
2966               isolate->heap()->empty_fixed_array());
2967     DCHECK_EQ(generator_object->stack_handler_index(), -1);
2968     // If there are no operands on the stack, there shouldn't be a handler
2969     // active either.
2970     DCHECK(!frame->HasHandler());
2971   } else {
2972     int stack_handler_index = -1;
2973     Handle<FixedArray> operand_stack =
2974         isolate->factory()->NewFixedArray(operands_count);
2975     frame->SaveOperandStack(*operand_stack, &stack_handler_index);
2976     generator_object->set_operand_stack(*operand_stack);
2977     generator_object->set_stack_handler_index(stack_handler_index);
2978   }
2979
2980   return isolate->heap()->undefined_value();
2981 }
2982
2983
2984 // Note that this function is the slow path for resuming generators.  It is only
2985 // called if the suspended activation had operands on the stack, stack handlers
2986 // needing rewinding, or if the resume should throw an exception.  The fast path
2987 // is handled directly in FullCodeGenerator::EmitGeneratorResume(), which is
2988 // inlined into GeneratorNext and GeneratorThrow.  EmitGeneratorResumeResume is
2989 // called in any case, as it needs to reconstruct the stack frame and make space
2990 // for arguments and operands.
2991 RUNTIME_FUNCTION(Runtime_ResumeJSGeneratorObject) {
2992   SealHandleScope shs(isolate);
2993   DCHECK(args.length() == 3);
2994   CONVERT_ARG_CHECKED(JSGeneratorObject, generator_object, 0);
2995   CONVERT_ARG_CHECKED(Object, value, 1);
2996   CONVERT_SMI_ARG_CHECKED(resume_mode_int, 2);
2997   JavaScriptFrameIterator stack_iterator(isolate);
2998   JavaScriptFrame* frame = stack_iterator.frame();
2999
3000   DCHECK_EQ(frame->function(), generator_object->function());
3001   DCHECK(frame->function()->is_compiled());
3002
3003   STATIC_ASSERT(JSGeneratorObject::kGeneratorExecuting < 0);
3004   STATIC_ASSERT(JSGeneratorObject::kGeneratorClosed == 0);
3005
3006   Address pc = generator_object->function()->code()->instruction_start();
3007   int offset = generator_object->continuation();
3008   DCHECK(offset > 0);
3009   frame->set_pc(pc + offset);
3010   if (FLAG_enable_ool_constant_pool) {
3011     frame->set_constant_pool(
3012         generator_object->function()->code()->constant_pool());
3013   }
3014   generator_object->set_continuation(JSGeneratorObject::kGeneratorExecuting);
3015
3016   FixedArray* operand_stack = generator_object->operand_stack();
3017   int operands_count = operand_stack->length();
3018   if (operands_count != 0) {
3019     frame->RestoreOperandStack(operand_stack,
3020                                generator_object->stack_handler_index());
3021     generator_object->set_operand_stack(isolate->heap()->empty_fixed_array());
3022     generator_object->set_stack_handler_index(-1);
3023   }
3024
3025   JSGeneratorObject::ResumeMode resume_mode =
3026       static_cast<JSGeneratorObject::ResumeMode>(resume_mode_int);
3027   switch (resume_mode) {
3028     case JSGeneratorObject::NEXT:
3029       return value;
3030     case JSGeneratorObject::THROW:
3031       return isolate->Throw(value);
3032   }
3033
3034   UNREACHABLE();
3035   return isolate->ThrowIllegalOperation();
3036 }
3037
3038
3039 RUNTIME_FUNCTION(Runtime_ThrowGeneratorStateError) {
3040   HandleScope scope(isolate);
3041   DCHECK(args.length() == 1);
3042   CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0);
3043   int continuation = generator->continuation();
3044   const char* message = continuation == JSGeneratorObject::kGeneratorClosed ?
3045       "generator_finished" : "generator_running";
3046   Vector< Handle<Object> > argv = HandleVector<Object>(NULL, 0);
3047   Handle<Object> error = isolate->factory()->NewError(message, argv);
3048   return isolate->Throw(*error);
3049 }
3050
3051
3052 RUNTIME_FUNCTION(Runtime_ObjectFreeze) {
3053   HandleScope scope(isolate);
3054   DCHECK(args.length() == 1);
3055   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
3056
3057   // %ObjectFreeze is a fast path and these cases are handled elsewhere.
3058   RUNTIME_ASSERT(!object->HasSloppyArgumentsElements() &&
3059                  !object->map()->is_observed() &&
3060                  !object->IsJSProxy());
3061
3062   Handle<Object> result;
3063   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, JSObject::Freeze(object));
3064   return *result;
3065 }
3066
3067
3068 RUNTIME_FUNCTION(Runtime_StringCharCodeAtRT) {
3069   HandleScope handle_scope(isolate);
3070   DCHECK(args.length() == 2);
3071
3072   CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
3073   CONVERT_NUMBER_CHECKED(uint32_t, i, Uint32, args[1]);
3074
3075   // Flatten the string.  If someone wants to get a char at an index
3076   // in a cons string, it is likely that more indices will be
3077   // accessed.
3078   subject = String::Flatten(subject);
3079
3080   if (i >= static_cast<uint32_t>(subject->length())) {
3081     return isolate->heap()->nan_value();
3082   }
3083
3084   return Smi::FromInt(subject->Get(i));
3085 }
3086
3087
3088 RUNTIME_FUNCTION(Runtime_CharFromCode) {
3089   HandleScope handlescope(isolate);
3090   DCHECK(args.length() == 1);
3091   if (args[0]->IsNumber()) {
3092     CONVERT_NUMBER_CHECKED(uint32_t, code, Uint32, args[0]);
3093     code &= 0xffff;
3094     return *isolate->factory()->LookupSingleCharacterStringFromCode(code);
3095   }
3096   return isolate->heap()->empty_string();
3097 }
3098
3099
3100 class FixedArrayBuilder {
3101  public:
3102   explicit FixedArrayBuilder(Isolate* isolate, int initial_capacity)
3103       : array_(isolate->factory()->NewFixedArrayWithHoles(initial_capacity)),
3104         length_(0),
3105         has_non_smi_elements_(false) {
3106     // Require a non-zero initial size. Ensures that doubling the size to
3107     // extend the array will work.
3108     DCHECK(initial_capacity > 0);
3109   }
3110
3111   explicit FixedArrayBuilder(Handle<FixedArray> backing_store)
3112       : array_(backing_store),
3113         length_(0),
3114         has_non_smi_elements_(false) {
3115     // Require a non-zero initial size. Ensures that doubling the size to
3116     // extend the array will work.
3117     DCHECK(backing_store->length() > 0);
3118   }
3119
3120   bool HasCapacity(int elements) {
3121     int length = array_->length();
3122     int required_length = length_ + elements;
3123     return (length >= required_length);
3124   }
3125
3126   void EnsureCapacity(int elements) {
3127     int length = array_->length();
3128     int required_length = length_ + elements;
3129     if (length < required_length) {
3130       int new_length = length;
3131       do {
3132         new_length *= 2;
3133       } while (new_length < required_length);
3134       Handle<FixedArray> extended_array =
3135           array_->GetIsolate()->factory()->NewFixedArrayWithHoles(new_length);
3136       array_->CopyTo(0, *extended_array, 0, length_);
3137       array_ = extended_array;
3138     }
3139   }
3140
3141   void Add(Object* value) {
3142     DCHECK(!value->IsSmi());
3143     DCHECK(length_ < capacity());
3144     array_->set(length_, value);
3145     length_++;
3146     has_non_smi_elements_ = true;
3147   }
3148
3149   void Add(Smi* value) {
3150     DCHECK(value->IsSmi());
3151     DCHECK(length_ < capacity());
3152     array_->set(length_, value);
3153     length_++;
3154   }
3155
3156   Handle<FixedArray> array() {
3157     return array_;
3158   }
3159
3160   int length() {
3161     return length_;
3162   }
3163
3164   int capacity() {
3165     return array_->length();
3166   }
3167
3168   Handle<JSArray> ToJSArray(Handle<JSArray> target_array) {
3169     JSArray::SetContent(target_array, array_);
3170     target_array->set_length(Smi::FromInt(length_));
3171     return target_array;
3172   }
3173
3174
3175  private:
3176   Handle<FixedArray> array_;
3177   int length_;
3178   bool has_non_smi_elements_;
3179 };
3180
3181
3182 // Forward declarations.
3183 const int kStringBuilderConcatHelperLengthBits = 11;
3184 const int kStringBuilderConcatHelperPositionBits = 19;
3185
3186 template <typename schar>
3187 static inline void StringBuilderConcatHelper(String*,
3188                                              schar*,
3189                                              FixedArray*,
3190                                              int);
3191
3192 typedef BitField<int, 0, kStringBuilderConcatHelperLengthBits>
3193     StringBuilderSubstringLength;
3194 typedef BitField<int,
3195                  kStringBuilderConcatHelperLengthBits,
3196                  kStringBuilderConcatHelperPositionBits>
3197     StringBuilderSubstringPosition;
3198
3199
3200 class ReplacementStringBuilder {
3201  public:
3202   ReplacementStringBuilder(Heap* heap,
3203                            Handle<String> subject,
3204                            int estimated_part_count)
3205       : heap_(heap),
3206         array_builder_(heap->isolate(), estimated_part_count),
3207         subject_(subject),
3208         character_count_(0),
3209         is_ascii_(subject->IsOneByteRepresentation()) {
3210     // Require a non-zero initial size. Ensures that doubling the size to
3211     // extend the array will work.
3212     DCHECK(estimated_part_count > 0);
3213   }
3214
3215   static inline void AddSubjectSlice(FixedArrayBuilder* builder,
3216                                      int from,
3217                                      int to) {
3218     DCHECK(from >= 0);
3219     int length = to - from;
3220     DCHECK(length > 0);
3221     if (StringBuilderSubstringLength::is_valid(length) &&
3222         StringBuilderSubstringPosition::is_valid(from)) {
3223       int encoded_slice = StringBuilderSubstringLength::encode(length) |
3224           StringBuilderSubstringPosition::encode(from);
3225       builder->Add(Smi::FromInt(encoded_slice));
3226     } else {
3227       // Otherwise encode as two smis.
3228       builder->Add(Smi::FromInt(-length));
3229       builder->Add(Smi::FromInt(from));
3230     }
3231   }
3232
3233
3234   void EnsureCapacity(int elements) {
3235     array_builder_.EnsureCapacity(elements);
3236   }
3237
3238
3239   void AddSubjectSlice(int from, int to) {
3240     AddSubjectSlice(&array_builder_, from, to);
3241     IncrementCharacterCount(to - from);
3242   }
3243
3244
3245   void AddString(Handle<String> string) {
3246     int length = string->length();
3247     DCHECK(length > 0);
3248     AddElement(*string);
3249     if (!string->IsOneByteRepresentation()) {
3250       is_ascii_ = false;
3251     }
3252     IncrementCharacterCount(length);
3253   }
3254
3255
3256   MaybeHandle<String> ToString() {
3257     Isolate* isolate = heap_->isolate();
3258     if (array_builder_.length() == 0) {
3259       return isolate->factory()->empty_string();
3260     }
3261
3262     Handle<String> joined_string;
3263     if (is_ascii_) {
3264       Handle<SeqOneByteString> seq;
3265       ASSIGN_RETURN_ON_EXCEPTION(
3266           isolate, seq,
3267           isolate->factory()->NewRawOneByteString(character_count_),
3268           String);
3269
3270       DisallowHeapAllocation no_gc;
3271       uint8_t* char_buffer = seq->GetChars();
3272       StringBuilderConcatHelper(*subject_,
3273                                 char_buffer,
3274                                 *array_builder_.array(),
3275                                 array_builder_.length());
3276       joined_string = Handle<String>::cast(seq);
3277     } else {
3278       // Non-ASCII.
3279       Handle<SeqTwoByteString> seq;
3280       ASSIGN_RETURN_ON_EXCEPTION(
3281           isolate, seq,
3282           isolate->factory()->NewRawTwoByteString(character_count_),
3283           String);
3284
3285       DisallowHeapAllocation no_gc;
3286       uc16* char_buffer = seq->GetChars();
3287       StringBuilderConcatHelper(*subject_,
3288                                 char_buffer,
3289                                 *array_builder_.array(),
3290                                 array_builder_.length());
3291       joined_string = Handle<String>::cast(seq);
3292     }
3293     return joined_string;
3294   }
3295
3296
3297   void IncrementCharacterCount(int by) {
3298     if (character_count_ > String::kMaxLength - by) {
3299       STATIC_ASSERT(String::kMaxLength < kMaxInt);
3300       character_count_ = kMaxInt;
3301     } else {
3302       character_count_ += by;
3303     }
3304   }
3305
3306  private:
3307   void AddElement(Object* element) {
3308     DCHECK(element->IsSmi() || element->IsString());
3309     DCHECK(array_builder_.capacity() > array_builder_.length());
3310     array_builder_.Add(element);
3311   }
3312
3313   Heap* heap_;
3314   FixedArrayBuilder array_builder_;
3315   Handle<String> subject_;
3316   int character_count_;
3317   bool is_ascii_;
3318 };
3319
3320
3321 class CompiledReplacement {
3322  public:
3323   explicit CompiledReplacement(Zone* zone)
3324       : parts_(1, zone), replacement_substrings_(0, zone), zone_(zone) {}
3325
3326   // Return whether the replacement is simple.
3327   bool Compile(Handle<String> replacement,
3328                int capture_count,
3329                int subject_length);
3330
3331   // Use Apply only if Compile returned false.
3332   void Apply(ReplacementStringBuilder* builder,
3333              int match_from,
3334              int match_to,
3335              int32_t* match);
3336
3337   // Number of distinct parts of the replacement pattern.
3338   int parts() {
3339     return parts_.length();
3340   }
3341
3342   Zone* zone() const { return zone_; }
3343
3344  private:
3345   enum PartType {
3346     SUBJECT_PREFIX = 1,
3347     SUBJECT_SUFFIX,
3348     SUBJECT_CAPTURE,
3349     REPLACEMENT_SUBSTRING,
3350     REPLACEMENT_STRING,
3351
3352     NUMBER_OF_PART_TYPES
3353   };
3354
3355   struct ReplacementPart {
3356     static inline ReplacementPart SubjectMatch() {
3357       return ReplacementPart(SUBJECT_CAPTURE, 0);
3358     }
3359     static inline ReplacementPart SubjectCapture(int capture_index) {
3360       return ReplacementPart(SUBJECT_CAPTURE, capture_index);
3361     }
3362     static inline ReplacementPart SubjectPrefix() {
3363       return ReplacementPart(SUBJECT_PREFIX, 0);
3364     }
3365     static inline ReplacementPart SubjectSuffix(int subject_length) {
3366       return ReplacementPart(SUBJECT_SUFFIX, subject_length);
3367     }
3368     static inline ReplacementPart ReplacementString() {
3369       return ReplacementPart(REPLACEMENT_STRING, 0);
3370     }
3371     static inline ReplacementPart ReplacementSubString(int from, int to) {
3372       DCHECK(from >= 0);
3373       DCHECK(to > from);
3374       return ReplacementPart(-from, to);
3375     }
3376
3377     // If tag <= 0 then it is the negation of a start index of a substring of
3378     // the replacement pattern, otherwise it's a value from PartType.
3379     ReplacementPart(int tag, int data)
3380         : tag(tag), data(data) {
3381       // Must be non-positive or a PartType value.
3382       DCHECK(tag < NUMBER_OF_PART_TYPES);
3383     }
3384     // Either a value of PartType or a non-positive number that is
3385     // the negation of an index into the replacement string.
3386     int tag;
3387     // The data value's interpretation depends on the value of tag:
3388     // tag == SUBJECT_PREFIX ||
3389     // tag == SUBJECT_SUFFIX:  data is unused.
3390     // tag == SUBJECT_CAPTURE: data is the number of the capture.
3391     // tag == REPLACEMENT_SUBSTRING ||
3392     // tag == REPLACEMENT_STRING:    data is index into array of substrings
3393     //                               of the replacement string.
3394     // tag <= 0: Temporary representation of the substring of the replacement
3395     //           string ranging over -tag .. data.
3396     //           Is replaced by REPLACEMENT_{SUB,}STRING when we create the
3397     //           substring objects.
3398     int data;
3399   };
3400
3401   template<typename Char>
3402   bool ParseReplacementPattern(ZoneList<ReplacementPart>* parts,
3403                                Vector<Char> characters,
3404                                int capture_count,
3405                                int subject_length,
3406                                Zone* zone) {
3407     int length = characters.length();
3408     int last = 0;
3409     for (int i = 0; i < length; i++) {
3410       Char c = characters[i];
3411       if (c == '$') {
3412         int next_index = i + 1;
3413         if (next_index == length) {  // No next character!
3414           break;
3415         }
3416         Char c2 = characters[next_index];
3417         switch (c2) {
3418         case '$':
3419           if (i > last) {
3420             // There is a substring before. Include the first "$".
3421             parts->Add(ReplacementPart::ReplacementSubString(last, next_index),
3422                        zone);
3423             last = next_index + 1;  // Continue after the second "$".
3424           } else {
3425             // Let the next substring start with the second "$".
3426             last = next_index;
3427           }
3428           i = next_index;
3429           break;
3430         case '`':
3431           if (i > last) {
3432             parts->Add(ReplacementPart::ReplacementSubString(last, i), zone);
3433           }
3434           parts->Add(ReplacementPart::SubjectPrefix(), zone);
3435           i = next_index;
3436           last = i + 1;
3437           break;
3438         case '\'':
3439           if (i > last) {
3440             parts->Add(ReplacementPart::ReplacementSubString(last, i), zone);
3441           }
3442           parts->Add(ReplacementPart::SubjectSuffix(subject_length), zone);
3443           i = next_index;
3444           last = i + 1;
3445           break;
3446         case '&':
3447           if (i > last) {
3448             parts->Add(ReplacementPart::ReplacementSubString(last, i), zone);
3449           }
3450           parts->Add(ReplacementPart::SubjectMatch(), zone);
3451           i = next_index;
3452           last = i + 1;
3453           break;
3454         case '0':
3455         case '1':
3456         case '2':
3457         case '3':
3458         case '4':
3459         case '5':
3460         case '6':
3461         case '7':
3462         case '8':
3463         case '9': {
3464           int capture_ref = c2 - '0';
3465           if (capture_ref > capture_count) {
3466             i = next_index;
3467             continue;
3468           }
3469           int second_digit_index = next_index + 1;
3470           if (second_digit_index < length) {
3471             // Peek ahead to see if we have two digits.
3472             Char c3 = characters[second_digit_index];
3473             if ('0' <= c3 && c3 <= '9') {  // Double digits.
3474               int double_digit_ref = capture_ref * 10 + c3 - '0';
3475               if (double_digit_ref <= capture_count) {
3476                 next_index = second_digit_index;
3477                 capture_ref = double_digit_ref;
3478               }
3479             }
3480           }
3481           if (capture_ref > 0) {
3482             if (i > last) {
3483               parts->Add(ReplacementPart::ReplacementSubString(last, i), zone);
3484             }
3485             DCHECK(capture_ref <= capture_count);
3486             parts->Add(ReplacementPart::SubjectCapture(capture_ref), zone);
3487             last = next_index + 1;
3488           }
3489           i = next_index;
3490           break;
3491         }
3492         default:
3493           i = next_index;
3494           break;
3495         }
3496       }
3497     }
3498     if (length > last) {
3499       if (last == 0) {
3500         // Replacement is simple.  Do not use Apply to do the replacement.
3501         return true;
3502       } else {
3503         parts->Add(ReplacementPart::ReplacementSubString(last, length), zone);
3504       }
3505     }
3506     return false;
3507   }
3508
3509   ZoneList<ReplacementPart> parts_;
3510   ZoneList<Handle<String> > replacement_substrings_;
3511   Zone* zone_;
3512 };
3513
3514
3515 bool CompiledReplacement::Compile(Handle<String> replacement,
3516                                   int capture_count,
3517                                   int subject_length) {
3518   {
3519     DisallowHeapAllocation no_gc;
3520     String::FlatContent content = replacement->GetFlatContent();
3521     DCHECK(content.IsFlat());
3522     bool simple = false;
3523     if (content.IsAscii()) {
3524       simple = ParseReplacementPattern(&parts_,
3525                                        content.ToOneByteVector(),
3526                                        capture_count,
3527                                        subject_length,
3528                                        zone());
3529     } else {
3530       DCHECK(content.IsTwoByte());
3531       simple = ParseReplacementPattern(&parts_,
3532                                        content.ToUC16Vector(),
3533                                        capture_count,
3534                                        subject_length,
3535                                        zone());
3536     }
3537     if (simple) return true;
3538   }
3539
3540   Isolate* isolate = replacement->GetIsolate();
3541   // Find substrings of replacement string and create them as String objects.
3542   int substring_index = 0;
3543   for (int i = 0, n = parts_.length(); i < n; i++) {
3544     int tag = parts_[i].tag;
3545     if (tag <= 0) {  // A replacement string slice.
3546       int from = -tag;
3547       int to = parts_[i].data;
3548       replacement_substrings_.Add(
3549           isolate->factory()->NewSubString(replacement, from, to), zone());
3550       parts_[i].tag = REPLACEMENT_SUBSTRING;
3551       parts_[i].data = substring_index;
3552       substring_index++;
3553     } else if (tag == REPLACEMENT_STRING) {
3554       replacement_substrings_.Add(replacement, zone());
3555       parts_[i].data = substring_index;
3556       substring_index++;
3557     }
3558   }
3559   return false;
3560 }
3561
3562
3563 void CompiledReplacement::Apply(ReplacementStringBuilder* builder,
3564                                 int match_from,
3565                                 int match_to,
3566                                 int32_t* match) {
3567   DCHECK_LT(0, parts_.length());
3568   for (int i = 0, n = parts_.length(); i < n; i++) {
3569     ReplacementPart part = parts_[i];
3570     switch (part.tag) {
3571       case SUBJECT_PREFIX:
3572         if (match_from > 0) builder->AddSubjectSlice(0, match_from);
3573         break;
3574       case SUBJECT_SUFFIX: {
3575         int subject_length = part.data;
3576         if (match_to < subject_length) {
3577           builder->AddSubjectSlice(match_to, subject_length);
3578         }
3579         break;
3580       }
3581       case SUBJECT_CAPTURE: {
3582         int capture = part.data;
3583         int from = match[capture * 2];
3584         int to = match[capture * 2 + 1];
3585         if (from >= 0 && to > from) {
3586           builder->AddSubjectSlice(from, to);
3587         }
3588         break;
3589       }
3590       case REPLACEMENT_SUBSTRING:
3591       case REPLACEMENT_STRING:
3592         builder->AddString(replacement_substrings_[part.data]);
3593         break;
3594       default:
3595         UNREACHABLE();
3596     }
3597   }
3598 }
3599
3600
3601 void FindAsciiStringIndices(Vector<const uint8_t> subject,
3602                             char pattern,
3603                             ZoneList<int>* indices,
3604                             unsigned int limit,
3605                             Zone* zone) {
3606   DCHECK(limit > 0);
3607   // Collect indices of pattern in subject using memchr.
3608   // Stop after finding at most limit values.
3609   const uint8_t* subject_start = subject.start();
3610   const uint8_t* subject_end = subject_start + subject.length();
3611   const uint8_t* pos = subject_start;
3612   while (limit > 0) {
3613     pos = reinterpret_cast<const uint8_t*>(
3614         memchr(pos, pattern, subject_end - pos));
3615     if (pos == NULL) return;
3616     indices->Add(static_cast<int>(pos - subject_start), zone);
3617     pos++;
3618     limit--;
3619   }
3620 }
3621
3622
3623 void FindTwoByteStringIndices(const Vector<const uc16> subject,
3624                               uc16 pattern,
3625                               ZoneList<int>* indices,
3626                               unsigned int limit,
3627                               Zone* zone) {
3628   DCHECK(limit > 0);
3629   const uc16* subject_start = subject.start();
3630   const uc16* subject_end = subject_start + subject.length();
3631   for (const uc16* pos = subject_start; pos < subject_end && limit > 0; pos++) {
3632     if (*pos == pattern) {
3633       indices->Add(static_cast<int>(pos - subject_start), zone);
3634       limit--;
3635     }
3636   }
3637 }
3638
3639
3640 template <typename SubjectChar, typename PatternChar>
3641 void FindStringIndices(Isolate* isolate,
3642                        Vector<const SubjectChar> subject,
3643                        Vector<const PatternChar> pattern,
3644                        ZoneList<int>* indices,
3645                        unsigned int limit,
3646                        Zone* zone) {
3647   DCHECK(limit > 0);
3648   // Collect indices of pattern in subject.
3649   // Stop after finding at most limit values.
3650   int pattern_length = pattern.length();
3651   int index = 0;
3652   StringSearch<PatternChar, SubjectChar> search(isolate, pattern);
3653   while (limit > 0) {
3654     index = search.Search(subject, index);
3655     if (index < 0) return;
3656     indices->Add(index, zone);
3657     index += pattern_length;
3658     limit--;
3659   }
3660 }
3661
3662
3663 void FindStringIndicesDispatch(Isolate* isolate,
3664                                String* subject,
3665                                String* pattern,
3666                                ZoneList<int>* indices,
3667                                unsigned int limit,
3668                                Zone* zone) {
3669   {
3670     DisallowHeapAllocation no_gc;
3671     String::FlatContent subject_content = subject->GetFlatContent();
3672     String::FlatContent pattern_content = pattern->GetFlatContent();
3673     DCHECK(subject_content.IsFlat());
3674     DCHECK(pattern_content.IsFlat());
3675     if (subject_content.IsAscii()) {
3676       Vector<const uint8_t> subject_vector = subject_content.ToOneByteVector();
3677       if (pattern_content.IsAscii()) {
3678         Vector<const uint8_t> pattern_vector =
3679             pattern_content.ToOneByteVector();
3680         if (pattern_vector.length() == 1) {
3681           FindAsciiStringIndices(subject_vector,
3682                                  pattern_vector[0],
3683                                  indices,
3684                                  limit,
3685                                  zone);
3686         } else {
3687           FindStringIndices(isolate,
3688                             subject_vector,
3689                             pattern_vector,
3690                             indices,
3691                             limit,
3692                             zone);
3693         }
3694       } else {
3695         FindStringIndices(isolate,
3696                           subject_vector,
3697                           pattern_content.ToUC16Vector(),
3698                           indices,
3699                           limit,
3700                           zone);
3701       }
3702     } else {
3703       Vector<const uc16> subject_vector = subject_content.ToUC16Vector();
3704       if (pattern_content.IsAscii()) {
3705         Vector<const uint8_t> pattern_vector =
3706             pattern_content.ToOneByteVector();
3707         if (pattern_vector.length() == 1) {
3708           FindTwoByteStringIndices(subject_vector,
3709                                    pattern_vector[0],
3710                                    indices,
3711                                    limit,
3712                                    zone);
3713         } else {
3714           FindStringIndices(isolate,
3715                             subject_vector,
3716                             pattern_vector,
3717                             indices,
3718                             limit,
3719                             zone);
3720         }
3721       } else {
3722         Vector<const uc16> pattern_vector = pattern_content.ToUC16Vector();
3723         if (pattern_vector.length() == 1) {
3724           FindTwoByteStringIndices(subject_vector,
3725                                    pattern_vector[0],
3726                                    indices,
3727                                    limit,
3728                                    zone);
3729         } else {
3730           FindStringIndices(isolate,
3731                             subject_vector,
3732                             pattern_vector,
3733                             indices,
3734                             limit,
3735                             zone);
3736         }
3737       }
3738     }
3739   }
3740 }
3741
3742
3743 template<typename ResultSeqString>
3744 MUST_USE_RESULT static Object* StringReplaceGlobalAtomRegExpWithString(
3745     Isolate* isolate,
3746     Handle<String> subject,
3747     Handle<JSRegExp> pattern_regexp,
3748     Handle<String> replacement,
3749     Handle<JSArray> last_match_info) {
3750   DCHECK(subject->IsFlat());
3751   DCHECK(replacement->IsFlat());
3752
3753   ZoneScope zone_scope(isolate->runtime_zone());
3754   ZoneList<int> indices(8, zone_scope.zone());
3755   DCHECK_EQ(JSRegExp::ATOM, pattern_regexp->TypeTag());
3756   String* pattern =
3757       String::cast(pattern_regexp->DataAt(JSRegExp::kAtomPatternIndex));
3758   int subject_len = subject->length();
3759   int pattern_len = pattern->length();
3760   int replacement_len = replacement->length();
3761
3762   FindStringIndicesDispatch(
3763       isolate, *subject, pattern, &indices, 0xffffffff, zone_scope.zone());
3764
3765   int matches = indices.length();
3766   if (matches == 0) return *subject;
3767
3768   // Detect integer overflow.
3769   int64_t result_len_64 =
3770       (static_cast<int64_t>(replacement_len) -
3771        static_cast<int64_t>(pattern_len)) *
3772       static_cast<int64_t>(matches) +
3773       static_cast<int64_t>(subject_len);
3774   int result_len;
3775   if (result_len_64 > static_cast<int64_t>(String::kMaxLength)) {
3776     STATIC_ASSERT(String::kMaxLength < kMaxInt);
3777     result_len = kMaxInt;  // Provoke exception.
3778   } else {
3779     result_len = static_cast<int>(result_len_64);
3780   }
3781
3782   int subject_pos = 0;
3783   int result_pos = 0;
3784
3785   MaybeHandle<SeqString> maybe_res;
3786   if (ResultSeqString::kHasAsciiEncoding) {
3787     maybe_res = isolate->factory()->NewRawOneByteString(result_len);
3788   } else {
3789     maybe_res = isolate->factory()->NewRawTwoByteString(result_len);
3790   }
3791   Handle<SeqString> untyped_res;
3792   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, untyped_res, maybe_res);
3793   Handle<ResultSeqString> result = Handle<ResultSeqString>::cast(untyped_res);
3794
3795   for (int i = 0; i < matches; i++) {
3796     // Copy non-matched subject content.
3797     if (subject_pos < indices.at(i)) {
3798       String::WriteToFlat(*subject,
3799                           result->GetChars() + result_pos,
3800                           subject_pos,
3801                           indices.at(i));
3802       result_pos += indices.at(i) - subject_pos;
3803     }
3804
3805     // Replace match.
3806     if (replacement_len > 0) {
3807       String::WriteToFlat(*replacement,
3808                           result->GetChars() + result_pos,
3809                           0,
3810                           replacement_len);
3811       result_pos += replacement_len;
3812     }
3813
3814     subject_pos = indices.at(i) + pattern_len;
3815   }
3816   // Add remaining subject content at the end.
3817   if (subject_pos < subject_len) {
3818     String::WriteToFlat(*subject,
3819                         result->GetChars() + result_pos,
3820                         subject_pos,
3821                         subject_len);
3822   }
3823
3824   int32_t match_indices[] = { indices.at(matches - 1),
3825                               indices.at(matches - 1) + pattern_len };
3826   RegExpImpl::SetLastMatchInfo(last_match_info, subject, 0, match_indices);
3827
3828   return *result;
3829 }
3830
3831
3832 MUST_USE_RESULT static Object* StringReplaceGlobalRegExpWithString(
3833     Isolate* isolate,
3834     Handle<String> subject,
3835     Handle<JSRegExp> regexp,
3836     Handle<String> replacement,
3837     Handle<JSArray> last_match_info) {
3838   DCHECK(subject->IsFlat());
3839   DCHECK(replacement->IsFlat());
3840
3841   int capture_count = regexp->CaptureCount();
3842   int subject_length = subject->length();
3843
3844   // CompiledReplacement uses zone allocation.
3845   ZoneScope zone_scope(isolate->runtime_zone());
3846   CompiledReplacement compiled_replacement(zone_scope.zone());
3847   bool simple_replace = compiled_replacement.Compile(replacement,
3848                                                      capture_count,
3849                                                      subject_length);
3850
3851   // Shortcut for simple non-regexp global replacements
3852   if (regexp->TypeTag() == JSRegExp::ATOM && simple_replace) {
3853     if (subject->HasOnlyOneByteChars() &&
3854         replacement->HasOnlyOneByteChars()) {
3855       return StringReplaceGlobalAtomRegExpWithString<SeqOneByteString>(
3856           isolate, subject, regexp, replacement, last_match_info);
3857     } else {
3858       return StringReplaceGlobalAtomRegExpWithString<SeqTwoByteString>(
3859           isolate, subject, regexp, replacement, last_match_info);
3860     }
3861   }
3862
3863   RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate);
3864   if (global_cache.HasException()) return isolate->heap()->exception();
3865
3866   int32_t* current_match = global_cache.FetchNext();
3867   if (current_match == NULL) {
3868     if (global_cache.HasException()) return isolate->heap()->exception();
3869     return *subject;
3870   }
3871
3872   // Guessing the number of parts that the final result string is built
3873   // from. Global regexps can match any number of times, so we guess
3874   // conservatively.
3875   int expected_parts = (compiled_replacement.parts() + 1) * 4 + 1;
3876   ReplacementStringBuilder builder(isolate->heap(),
3877                                    subject,
3878                                    expected_parts);
3879
3880   // Number of parts added by compiled replacement plus preceeding
3881   // string and possibly suffix after last match.  It is possible for
3882   // all components to use two elements when encoded as two smis.
3883   const int parts_added_per_loop = 2 * (compiled_replacement.parts() + 2);
3884
3885   int prev = 0;
3886
3887   do {
3888     builder.EnsureCapacity(parts_added_per_loop);
3889
3890     int start = current_match[0];
3891     int end = current_match[1];
3892
3893     if (prev < start) {
3894       builder.AddSubjectSlice(prev, start);
3895     }
3896
3897     if (simple_replace) {
3898       builder.AddString(replacement);
3899     } else {
3900       compiled_replacement.Apply(&builder,
3901                                  start,
3902                                  end,
3903                                  current_match);
3904     }
3905     prev = end;
3906
3907     current_match = global_cache.FetchNext();
3908   } while (current_match != NULL);
3909
3910   if (global_cache.HasException()) return isolate->heap()->exception();
3911
3912   if (prev < subject_length) {
3913     builder.EnsureCapacity(2);
3914     builder.AddSubjectSlice(prev, subject_length);
3915   }
3916
3917   RegExpImpl::SetLastMatchInfo(last_match_info,
3918                                subject,
3919                                capture_count,
3920                                global_cache.LastSuccessfulMatch());
3921
3922   Handle<String> result;
3923   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, builder.ToString());
3924   return *result;
3925 }
3926
3927
3928 template <typename ResultSeqString>
3929 MUST_USE_RESULT static Object* StringReplaceGlobalRegExpWithEmptyString(
3930     Isolate* isolate,
3931     Handle<String> subject,
3932     Handle<JSRegExp> regexp,
3933     Handle<JSArray> last_match_info) {
3934   DCHECK(subject->IsFlat());
3935
3936   // Shortcut for simple non-regexp global replacements
3937   if (regexp->TypeTag() == JSRegExp::ATOM) {
3938     Handle<String> empty_string = isolate->factory()->empty_string();
3939     if (subject->IsOneByteRepresentation()) {
3940       return StringReplaceGlobalAtomRegExpWithString<SeqOneByteString>(
3941           isolate, subject, regexp, empty_string, last_match_info);
3942     } else {
3943       return StringReplaceGlobalAtomRegExpWithString<SeqTwoByteString>(
3944           isolate, subject, regexp, empty_string, last_match_info);
3945     }
3946   }
3947
3948   RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate);
3949   if (global_cache.HasException()) return isolate->heap()->exception();
3950
3951   int32_t* current_match = global_cache.FetchNext();
3952   if (current_match == NULL) {
3953     if (global_cache.HasException()) return isolate->heap()->exception();
3954     return *subject;
3955   }
3956
3957   int start = current_match[0];
3958   int end = current_match[1];
3959   int capture_count = regexp->CaptureCount();
3960   int subject_length = subject->length();
3961
3962   int new_length = subject_length - (end - start);
3963   if (new_length == 0) return isolate->heap()->empty_string();
3964
3965   Handle<ResultSeqString> answer;
3966   if (ResultSeqString::kHasAsciiEncoding) {
3967     answer = Handle<ResultSeqString>::cast(
3968         isolate->factory()->NewRawOneByteString(new_length).ToHandleChecked());
3969   } else {
3970     answer = Handle<ResultSeqString>::cast(
3971         isolate->factory()->NewRawTwoByteString(new_length).ToHandleChecked());
3972   }
3973
3974   int prev = 0;
3975   int position = 0;
3976
3977   do {
3978     start = current_match[0];
3979     end = current_match[1];
3980     if (prev < start) {
3981       // Add substring subject[prev;start] to answer string.
3982       String::WriteToFlat(*subject, answer->GetChars() + position, prev, start);
3983       position += start - prev;
3984     }
3985     prev = end;
3986
3987     current_match = global_cache.FetchNext();
3988   } while (current_match != NULL);
3989
3990   if (global_cache.HasException()) return isolate->heap()->exception();
3991
3992   RegExpImpl::SetLastMatchInfo(last_match_info,
3993                                subject,
3994                                capture_count,
3995                                global_cache.LastSuccessfulMatch());
3996
3997   if (prev < subject_length) {
3998     // Add substring subject[prev;length] to answer string.
3999     String::WriteToFlat(
4000         *subject, answer->GetChars() + position, prev, subject_length);
4001     position += subject_length - prev;
4002   }
4003
4004   if (position == 0) return isolate->heap()->empty_string();
4005
4006   // Shorten string and fill
4007   int string_size = ResultSeqString::SizeFor(position);
4008   int allocated_string_size = ResultSeqString::SizeFor(new_length);
4009   int delta = allocated_string_size - string_size;
4010
4011   answer->set_length(position);
4012   if (delta == 0) return *answer;
4013
4014   Address end_of_string = answer->address() + string_size;
4015   Heap* heap = isolate->heap();
4016
4017   // The trimming is performed on a newly allocated object, which is on a
4018   // fresly allocated page or on an already swept page. Hence, the sweeper
4019   // thread can not get confused with the filler creation. No synchronization
4020   // needed.
4021   heap->CreateFillerObjectAt(end_of_string, delta);
4022   heap->AdjustLiveBytes(answer->address(), -delta, Heap::FROM_MUTATOR);
4023   return *answer;
4024 }
4025
4026
4027 RUNTIME_FUNCTION(Runtime_StringReplaceGlobalRegExpWithString) {
4028   HandleScope scope(isolate);
4029   DCHECK(args.length() == 4);
4030
4031   CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
4032   CONVERT_ARG_HANDLE_CHECKED(String, replacement, 2);
4033   CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 1);
4034   CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 3);
4035
4036   RUNTIME_ASSERT(regexp->GetFlags().is_global());
4037   RUNTIME_ASSERT(last_match_info->HasFastObjectElements());
4038
4039   subject = String::Flatten(subject);
4040
4041   if (replacement->length() == 0) {
4042     if (subject->HasOnlyOneByteChars()) {
4043       return StringReplaceGlobalRegExpWithEmptyString<SeqOneByteString>(
4044           isolate, subject, regexp, last_match_info);
4045     } else {
4046       return StringReplaceGlobalRegExpWithEmptyString<SeqTwoByteString>(
4047           isolate, subject, regexp, last_match_info);
4048     }
4049   }
4050
4051   replacement = String::Flatten(replacement);
4052
4053   return StringReplaceGlobalRegExpWithString(
4054       isolate, subject, regexp, replacement, last_match_info);
4055 }
4056
4057
4058 // This may return an empty MaybeHandle if an exception is thrown or
4059 // we abort due to reaching the recursion limit.
4060 MaybeHandle<String> StringReplaceOneCharWithString(Isolate* isolate,
4061                                                    Handle<String> subject,
4062                                                    Handle<String> search,
4063                                                    Handle<String> replace,
4064                                                    bool* found,
4065                                                    int recursion_limit) {
4066   StackLimitCheck stackLimitCheck(isolate);
4067   if (stackLimitCheck.HasOverflowed() || (recursion_limit == 0)) {
4068     return MaybeHandle<String>();
4069   }
4070   recursion_limit--;
4071   if (subject->IsConsString()) {
4072     ConsString* cons = ConsString::cast(*subject);
4073     Handle<String> first = Handle<String>(cons->first());
4074     Handle<String> second = Handle<String>(cons->second());
4075     Handle<String> new_first;
4076     if (!StringReplaceOneCharWithString(
4077             isolate, first, search, replace, found, recursion_limit)
4078             .ToHandle(&new_first)) {
4079       return MaybeHandle<String>();
4080     }
4081     if (*found) return isolate->factory()->NewConsString(new_first, second);
4082
4083     Handle<String> new_second;
4084     if (!StringReplaceOneCharWithString(
4085             isolate, second, search, replace, found, recursion_limit)
4086             .ToHandle(&new_second)) {
4087       return MaybeHandle<String>();
4088     }
4089     if (*found) return isolate->factory()->NewConsString(first, new_second);
4090
4091     return subject;
4092   } else {
4093     int index = Runtime::StringMatch(isolate, subject, search, 0);
4094     if (index == -1) return subject;
4095     *found = true;
4096     Handle<String> first = isolate->factory()->NewSubString(subject, 0, index);
4097     Handle<String> cons1;
4098     ASSIGN_RETURN_ON_EXCEPTION(
4099         isolate, cons1,
4100         isolate->factory()->NewConsString(first, replace),
4101         String);
4102     Handle<String> second =
4103         isolate->factory()->NewSubString(subject, index + 1, subject->length());
4104     return isolate->factory()->NewConsString(cons1, second);
4105   }
4106 }
4107
4108
4109 RUNTIME_FUNCTION(Runtime_StringReplaceOneCharWithString) {
4110   HandleScope scope(isolate);
4111   DCHECK(args.length() == 3);
4112   CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
4113   CONVERT_ARG_HANDLE_CHECKED(String, search, 1);
4114   CONVERT_ARG_HANDLE_CHECKED(String, replace, 2);
4115
4116   // If the cons string tree is too deep, we simply abort the recursion and
4117   // retry with a flattened subject string.
4118   const int kRecursionLimit = 0x1000;
4119   bool found = false;
4120   Handle<String> result;
4121   if (StringReplaceOneCharWithString(
4122           isolate, subject, search, replace, &found, kRecursionLimit)
4123           .ToHandle(&result)) {
4124     return *result;
4125   }
4126   if (isolate->has_pending_exception()) return isolate->heap()->exception();
4127
4128   subject = String::Flatten(subject);
4129   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
4130       isolate, result,
4131       StringReplaceOneCharWithString(
4132           isolate, subject, search, replace, &found, kRecursionLimit));
4133   return *result;
4134 }
4135
4136
4137 // Perform string match of pattern on subject, starting at start index.
4138 // Caller must ensure that 0 <= start_index <= sub->length(),
4139 // and should check that pat->length() + start_index <= sub->length().
4140 int Runtime::StringMatch(Isolate* isolate,
4141                          Handle<String> sub,
4142                          Handle<String> pat,
4143                          int start_index) {
4144   DCHECK(0 <= start_index);
4145   DCHECK(start_index <= sub->length());
4146
4147   int pattern_length = pat->length();
4148   if (pattern_length == 0) return start_index;
4149
4150   int subject_length = sub->length();
4151   if (start_index + pattern_length > subject_length) return -1;
4152
4153   sub = String::Flatten(sub);
4154   pat = String::Flatten(pat);
4155
4156   DisallowHeapAllocation no_gc;  // ensure vectors stay valid
4157   // Extract flattened substrings of cons strings before determining asciiness.
4158   String::FlatContent seq_sub = sub->GetFlatContent();
4159   String::FlatContent seq_pat = pat->GetFlatContent();
4160
4161   // dispatch on type of strings
4162   if (seq_pat.IsAscii()) {
4163     Vector<const uint8_t> pat_vector = seq_pat.ToOneByteVector();
4164     if (seq_sub.IsAscii()) {
4165       return SearchString(isolate,
4166                           seq_sub.ToOneByteVector(),
4167                           pat_vector,
4168                           start_index);
4169     }
4170     return SearchString(isolate,
4171                         seq_sub.ToUC16Vector(),
4172                         pat_vector,
4173                         start_index);
4174   }
4175   Vector<const uc16> pat_vector = seq_pat.ToUC16Vector();
4176   if (seq_sub.IsAscii()) {
4177     return SearchString(isolate,
4178                         seq_sub.ToOneByteVector(),
4179                         pat_vector,
4180                         start_index);
4181   }
4182   return SearchString(isolate,
4183                       seq_sub.ToUC16Vector(),
4184                       pat_vector,
4185                       start_index);
4186 }
4187
4188
4189 RUNTIME_FUNCTION(Runtime_StringIndexOf) {
4190   HandleScope scope(isolate);
4191   DCHECK(args.length() == 3);
4192
4193   CONVERT_ARG_HANDLE_CHECKED(String, sub, 0);
4194   CONVERT_ARG_HANDLE_CHECKED(String, pat, 1);
4195   CONVERT_ARG_HANDLE_CHECKED(Object, index, 2);
4196
4197   uint32_t start_index;
4198   if (!index->ToArrayIndex(&start_index)) return Smi::FromInt(-1);
4199
4200   RUNTIME_ASSERT(start_index <= static_cast<uint32_t>(sub->length()));
4201   int position = Runtime::StringMatch(isolate, sub, pat, start_index);
4202   return Smi::FromInt(position);
4203 }
4204
4205
4206 template <typename schar, typename pchar>
4207 static int StringMatchBackwards(Vector<const schar> subject,
4208                                 Vector<const pchar> pattern,
4209                                 int idx) {
4210   int pattern_length = pattern.length();
4211   DCHECK(pattern_length >= 1);
4212   DCHECK(idx + pattern_length <= subject.length());
4213
4214   if (sizeof(schar) == 1 && sizeof(pchar) > 1) {
4215     for (int i = 0; i < pattern_length; i++) {
4216       uc16 c = pattern[i];
4217       if (c > String::kMaxOneByteCharCode) {
4218         return -1;
4219       }
4220     }
4221   }
4222
4223   pchar pattern_first_char = pattern[0];
4224   for (int i = idx; i >= 0; i--) {
4225     if (subject[i] != pattern_first_char) continue;
4226     int j = 1;
4227     while (j < pattern_length) {
4228       if (pattern[j] != subject[i+j]) {
4229         break;
4230       }
4231       j++;
4232     }
4233     if (j == pattern_length) {
4234       return i;
4235     }
4236   }
4237   return -1;
4238 }
4239
4240
4241 RUNTIME_FUNCTION(Runtime_StringLastIndexOf) {
4242   HandleScope scope(isolate);
4243   DCHECK(args.length() == 3);
4244
4245   CONVERT_ARG_HANDLE_CHECKED(String, sub, 0);
4246   CONVERT_ARG_HANDLE_CHECKED(String, pat, 1);
4247   CONVERT_ARG_HANDLE_CHECKED(Object, index, 2);
4248
4249   uint32_t start_index;
4250   if (!index->ToArrayIndex(&start_index)) return Smi::FromInt(-1);
4251
4252   uint32_t pat_length = pat->length();
4253   uint32_t sub_length = sub->length();
4254
4255   if (start_index + pat_length > sub_length) {
4256     start_index = sub_length - pat_length;
4257   }
4258
4259   if (pat_length == 0) {
4260     return Smi::FromInt(start_index);
4261   }
4262
4263   sub = String::Flatten(sub);
4264   pat = String::Flatten(pat);
4265
4266   int position = -1;
4267   DisallowHeapAllocation no_gc;  // ensure vectors stay valid
4268
4269   String::FlatContent sub_content = sub->GetFlatContent();
4270   String::FlatContent pat_content = pat->GetFlatContent();
4271
4272   if (pat_content.IsAscii()) {
4273     Vector<const uint8_t> pat_vector = pat_content.ToOneByteVector();
4274     if (sub_content.IsAscii()) {
4275       position = StringMatchBackwards(sub_content.ToOneByteVector(),
4276                                       pat_vector,
4277                                       start_index);
4278     } else {
4279       position = StringMatchBackwards(sub_content.ToUC16Vector(),
4280                                       pat_vector,
4281                                       start_index);
4282     }
4283   } else {
4284     Vector<const uc16> pat_vector = pat_content.ToUC16Vector();
4285     if (sub_content.IsAscii()) {
4286       position = StringMatchBackwards(sub_content.ToOneByteVector(),
4287                                       pat_vector,
4288                                       start_index);
4289     } else {
4290       position = StringMatchBackwards(sub_content.ToUC16Vector(),
4291                                       pat_vector,
4292                                       start_index);
4293     }
4294   }
4295
4296   return Smi::FromInt(position);
4297 }
4298
4299
4300 RUNTIME_FUNCTION(Runtime_StringLocaleCompare) {
4301   HandleScope handle_scope(isolate);
4302   DCHECK(args.length() == 2);
4303
4304   CONVERT_ARG_HANDLE_CHECKED(String, str1, 0);
4305   CONVERT_ARG_HANDLE_CHECKED(String, str2, 1);
4306
4307   if (str1.is_identical_to(str2)) return Smi::FromInt(0);  // Equal.
4308   int str1_length = str1->length();
4309   int str2_length = str2->length();
4310
4311   // Decide trivial cases without flattening.
4312   if (str1_length == 0) {
4313     if (str2_length == 0) return Smi::FromInt(0);  // Equal.
4314     return Smi::FromInt(-str2_length);
4315   } else {
4316     if (str2_length == 0) return Smi::FromInt(str1_length);
4317   }
4318
4319   int end = str1_length < str2_length ? str1_length : str2_length;
4320
4321   // No need to flatten if we are going to find the answer on the first
4322   // character.  At this point we know there is at least one character
4323   // in each string, due to the trivial case handling above.
4324   int d = str1->Get(0) - str2->Get(0);
4325   if (d != 0) return Smi::FromInt(d);
4326
4327   str1 = String::Flatten(str1);
4328   str2 = String::Flatten(str2);
4329
4330   DisallowHeapAllocation no_gc;
4331   String::FlatContent flat1 = str1->GetFlatContent();
4332   String::FlatContent flat2 = str2->GetFlatContent();
4333
4334   for (int i = 0; i < end; i++) {
4335     if (flat1.Get(i) != flat2.Get(i)) {
4336       return Smi::FromInt(flat1.Get(i) - flat2.Get(i));
4337     }
4338   }
4339
4340   return Smi::FromInt(str1_length - str2_length);
4341 }
4342
4343
4344 RUNTIME_FUNCTION(Runtime_SubString) {
4345   HandleScope scope(isolate);
4346   DCHECK(args.length() == 3);
4347
4348   CONVERT_ARG_HANDLE_CHECKED(String, string, 0);
4349   int start, end;
4350   // We have a fast integer-only case here to avoid a conversion to double in
4351   // the common case where from and to are Smis.
4352   if (args[1]->IsSmi() && args[2]->IsSmi()) {
4353     CONVERT_SMI_ARG_CHECKED(from_number, 1);
4354     CONVERT_SMI_ARG_CHECKED(to_number, 2);
4355     start = from_number;
4356     end = to_number;
4357   } else {
4358     CONVERT_DOUBLE_ARG_CHECKED(from_number, 1);
4359     CONVERT_DOUBLE_ARG_CHECKED(to_number, 2);
4360     start = FastD2IChecked(from_number);
4361     end = FastD2IChecked(to_number);
4362   }
4363   RUNTIME_ASSERT(end >= start);
4364   RUNTIME_ASSERT(start >= 0);
4365   RUNTIME_ASSERT(end <= string->length());
4366   isolate->counters()->sub_string_runtime()->Increment();
4367
4368   return *isolate->factory()->NewSubString(string, start, end);
4369 }
4370
4371
4372 RUNTIME_FUNCTION(Runtime_InternalizeString) {
4373   HandleScope handles(isolate);
4374   RUNTIME_ASSERT(args.length() == 1);
4375   CONVERT_ARG_HANDLE_CHECKED(String, string, 0);
4376   return *isolate->factory()->InternalizeString(string);
4377 }
4378
4379
4380 RUNTIME_FUNCTION(Runtime_StringMatch) {
4381   HandleScope handles(isolate);
4382   DCHECK(args.length() == 3);
4383
4384   CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
4385   CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 1);
4386   CONVERT_ARG_HANDLE_CHECKED(JSArray, regexp_info, 2);
4387
4388   RUNTIME_ASSERT(regexp_info->HasFastObjectElements());
4389
4390   RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate);
4391   if (global_cache.HasException()) return isolate->heap()->exception();
4392
4393   int capture_count = regexp->CaptureCount();
4394
4395   ZoneScope zone_scope(isolate->runtime_zone());
4396   ZoneList<int> offsets(8, zone_scope.zone());
4397
4398   while (true) {
4399     int32_t* match = global_cache.FetchNext();
4400     if (match == NULL) break;
4401     offsets.Add(match[0], zone_scope.zone());  // start
4402     offsets.Add(match[1], zone_scope.zone());  // end
4403   }
4404
4405   if (global_cache.HasException()) return isolate->heap()->exception();
4406
4407   if (offsets.length() == 0) {
4408     // Not a single match.
4409     return isolate->heap()->null_value();
4410   }
4411
4412   RegExpImpl::SetLastMatchInfo(regexp_info,
4413                                subject,
4414                                capture_count,
4415                                global_cache.LastSuccessfulMatch());
4416
4417   int matches = offsets.length() / 2;
4418   Handle<FixedArray> elements = isolate->factory()->NewFixedArray(matches);
4419   Handle<String> substring =
4420       isolate->factory()->NewSubString(subject, offsets.at(0), offsets.at(1));
4421   elements->set(0, *substring);
4422   for (int i = 1; i < matches; i++) {
4423     HandleScope temp_scope(isolate);
4424     int from = offsets.at(i * 2);
4425     int to = offsets.at(i * 2 + 1);
4426     Handle<String> substring =
4427         isolate->factory()->NewProperSubString(subject, from, to);
4428     elements->set(i, *substring);
4429   }
4430   Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements(elements);
4431   result->set_length(Smi::FromInt(matches));
4432   return *result;
4433 }
4434
4435
4436 // Only called from Runtime_RegExpExecMultiple so it doesn't need to maintain
4437 // separate last match info.  See comment on that function.
4438 template<bool has_capture>
4439 static Object* SearchRegExpMultiple(
4440     Isolate* isolate,
4441     Handle<String> subject,
4442     Handle<JSRegExp> regexp,
4443     Handle<JSArray> last_match_array,
4444     Handle<JSArray> result_array) {
4445   DCHECK(subject->IsFlat());
4446   DCHECK_NE(has_capture, regexp->CaptureCount() == 0);
4447
4448   int capture_count = regexp->CaptureCount();
4449   int subject_length = subject->length();
4450
4451   static const int kMinLengthToCache = 0x1000;
4452
4453   if (subject_length > kMinLengthToCache) {
4454     Handle<Object> cached_answer(RegExpResultsCache::Lookup(
4455         isolate->heap(),
4456         *subject,
4457         regexp->data(),
4458         RegExpResultsCache::REGEXP_MULTIPLE_INDICES), isolate);
4459     if (*cached_answer != Smi::FromInt(0)) {
4460       Handle<FixedArray> cached_fixed_array =
4461           Handle<FixedArray>(FixedArray::cast(*cached_answer));
4462       // The cache FixedArray is a COW-array and can therefore be reused.
4463       JSArray::SetContent(result_array, cached_fixed_array);
4464       // The actual length of the result array is stored in the last element of
4465       // the backing store (the backing FixedArray may have a larger capacity).
4466       Object* cached_fixed_array_last_element =
4467           cached_fixed_array->get(cached_fixed_array->length() - 1);
4468       Smi* js_array_length = Smi::cast(cached_fixed_array_last_element);
4469       result_array->set_length(js_array_length);
4470       RegExpImpl::SetLastMatchInfo(
4471           last_match_array, subject, capture_count, NULL);
4472       return *result_array;
4473     }
4474   }
4475
4476   RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate);
4477   if (global_cache.HasException()) return isolate->heap()->exception();
4478
4479   // Ensured in Runtime_RegExpExecMultiple.
4480   DCHECK(result_array->HasFastObjectElements());
4481   Handle<FixedArray> result_elements(
4482       FixedArray::cast(result_array->elements()));
4483   if (result_elements->length() < 16) {
4484     result_elements = isolate->factory()->NewFixedArrayWithHoles(16);
4485   }
4486
4487   FixedArrayBuilder builder(result_elements);
4488
4489   // Position to search from.
4490   int match_start = -1;
4491   int match_end = 0;
4492   bool first = true;
4493
4494   // Two smis before and after the match, for very long strings.
4495   static const int kMaxBuilderEntriesPerRegExpMatch = 5;
4496
4497   while (true) {
4498     int32_t* current_match = global_cache.FetchNext();
4499     if (current_match == NULL) break;
4500     match_start = current_match[0];
4501     builder.EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch);
4502     if (match_end < match_start) {
4503       ReplacementStringBuilder::AddSubjectSlice(&builder,
4504                                                 match_end,
4505                                                 match_start);
4506     }
4507     match_end = current_match[1];
4508     {
4509       // Avoid accumulating new handles inside loop.
4510       HandleScope temp_scope(isolate);
4511       Handle<String> match;
4512       if (!first) {
4513         match = isolate->factory()->NewProperSubString(subject,
4514                                                        match_start,
4515                                                        match_end);
4516       } else {
4517         match = isolate->factory()->NewSubString(subject,
4518                                                  match_start,
4519                                                  match_end);
4520         first = false;
4521       }
4522
4523       if (has_capture) {
4524         // Arguments array to replace function is match, captures, index and
4525         // subject, i.e., 3 + capture count in total.
4526         Handle<FixedArray> elements =
4527             isolate->factory()->NewFixedArray(3 + capture_count);
4528
4529         elements->set(0, *match);
4530         for (int i = 1; i <= capture_count; i++) {
4531           int start = current_match[i * 2];
4532           if (start >= 0) {
4533             int end = current_match[i * 2 + 1];
4534             DCHECK(start <= end);
4535             Handle<String> substring =
4536                 isolate->factory()->NewSubString(subject, start, end);
4537             elements->set(i, *substring);
4538           } else {
4539             DCHECK(current_match[i * 2 + 1] < 0);
4540             elements->set(i, isolate->heap()->undefined_value());
4541           }
4542         }
4543         elements->set(capture_count + 1, Smi::FromInt(match_start));
4544         elements->set(capture_count + 2, *subject);
4545         builder.Add(*isolate->factory()->NewJSArrayWithElements(elements));
4546       } else {
4547         builder.Add(*match);
4548       }
4549     }
4550   }
4551
4552   if (global_cache.HasException()) return isolate->heap()->exception();
4553
4554   if (match_start >= 0) {
4555     // Finished matching, with at least one match.
4556     if (match_end < subject_length) {
4557       ReplacementStringBuilder::AddSubjectSlice(&builder,
4558                                                 match_end,
4559                                                 subject_length);
4560     }
4561
4562     RegExpImpl::SetLastMatchInfo(
4563         last_match_array, subject, capture_count, NULL);
4564
4565     if (subject_length > kMinLengthToCache) {
4566       // Store the length of the result array into the last element of the
4567       // backing FixedArray.
4568       builder.EnsureCapacity(1);
4569       Handle<FixedArray> fixed_array = builder.array();
4570       fixed_array->set(fixed_array->length() - 1,
4571                        Smi::FromInt(builder.length()));
4572       // Cache the result and turn the FixedArray into a COW array.
4573       RegExpResultsCache::Enter(isolate,
4574                                 subject,
4575                                 handle(regexp->data(), isolate),
4576                                 fixed_array,
4577                                 RegExpResultsCache::REGEXP_MULTIPLE_INDICES);
4578     }
4579     return *builder.ToJSArray(result_array);
4580   } else {
4581     return isolate->heap()->null_value();  // No matches at all.
4582   }
4583 }
4584
4585
4586 // This is only called for StringReplaceGlobalRegExpWithFunction.  This sets
4587 // lastMatchInfoOverride to maintain the last match info, so we don't need to
4588 // set any other last match array info.
4589 RUNTIME_FUNCTION(Runtime_RegExpExecMultiple) {
4590   HandleScope handles(isolate);
4591   DCHECK(args.length() == 4);
4592
4593   CONVERT_ARG_HANDLE_CHECKED(String, subject, 1);
4594   CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0);
4595   CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 2);
4596   CONVERT_ARG_HANDLE_CHECKED(JSArray, result_array, 3);
4597   RUNTIME_ASSERT(last_match_info->HasFastObjectElements());
4598   RUNTIME_ASSERT(result_array->HasFastObjectElements());
4599
4600   subject = String::Flatten(subject);
4601   RUNTIME_ASSERT(regexp->GetFlags().is_global());
4602
4603   if (regexp->CaptureCount() == 0) {
4604     return SearchRegExpMultiple<false>(
4605         isolate, subject, regexp, last_match_info, result_array);
4606   } else {
4607     return SearchRegExpMultiple<true>(
4608         isolate, subject, regexp, last_match_info, result_array);
4609   }
4610 }
4611
4612
4613 RUNTIME_FUNCTION(Runtime_NumberToRadixString) {
4614   HandleScope scope(isolate);
4615   DCHECK(args.length() == 2);
4616   CONVERT_SMI_ARG_CHECKED(radix, 1);
4617   RUNTIME_ASSERT(2 <= radix && radix <= 36);
4618
4619   // Fast case where the result is a one character string.
4620   if (args[0]->IsSmi()) {
4621     int value = args.smi_at(0);
4622     if (value >= 0 && value < radix) {
4623       // Character array used for conversion.
4624       static const char kCharTable[] = "0123456789abcdefghijklmnopqrstuvwxyz";
4625       return *isolate->factory()->
4626           LookupSingleCharacterStringFromCode(kCharTable[value]);
4627     }
4628   }
4629
4630   // Slow case.
4631   CONVERT_DOUBLE_ARG_CHECKED(value, 0);
4632   if (std::isnan(value)) {
4633     return isolate->heap()->nan_string();
4634   }
4635   if (std::isinf(value)) {
4636     if (value < 0) {
4637       return isolate->heap()->minus_infinity_string();
4638     }
4639     return isolate->heap()->infinity_string();
4640   }
4641   char* str = DoubleToRadixCString(value, radix);
4642   Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(str);
4643   DeleteArray(str);
4644   return *result;
4645 }
4646
4647
4648 RUNTIME_FUNCTION(Runtime_NumberToFixed) {
4649   HandleScope scope(isolate);
4650   DCHECK(args.length() == 2);
4651
4652   CONVERT_DOUBLE_ARG_CHECKED(value, 0);
4653   CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
4654   int f = FastD2IChecked(f_number);
4655   // See DoubleToFixedCString for these constants:
4656   RUNTIME_ASSERT(f >= 0 && f <= 20);
4657   RUNTIME_ASSERT(!Double(value).IsSpecial());
4658   char* str = DoubleToFixedCString(value, f);
4659   Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(str);
4660   DeleteArray(str);
4661   return *result;
4662 }
4663
4664
4665 RUNTIME_FUNCTION(Runtime_NumberToExponential) {
4666   HandleScope scope(isolate);
4667   DCHECK(args.length() == 2);
4668
4669   CONVERT_DOUBLE_ARG_CHECKED(value, 0);
4670   CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
4671   int f = FastD2IChecked(f_number);
4672   RUNTIME_ASSERT(f >= -1 && f <= 20);
4673   RUNTIME_ASSERT(!Double(value).IsSpecial());
4674   char* str = DoubleToExponentialCString(value, f);
4675   Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(str);
4676   DeleteArray(str);
4677   return *result;
4678 }
4679
4680
4681 RUNTIME_FUNCTION(Runtime_NumberToPrecision) {
4682   HandleScope scope(isolate);
4683   DCHECK(args.length() == 2);
4684
4685   CONVERT_DOUBLE_ARG_CHECKED(value, 0);
4686   CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
4687   int f = FastD2IChecked(f_number);
4688   RUNTIME_ASSERT(f >= 1 && f <= 21);
4689   RUNTIME_ASSERT(!Double(value).IsSpecial());
4690   char* str = DoubleToPrecisionCString(value, f);
4691   Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(str);
4692   DeleteArray(str);
4693   return *result;
4694 }
4695
4696
4697 RUNTIME_FUNCTION(Runtime_IsValidSmi) {
4698   SealHandleScope shs(isolate);
4699   DCHECK(args.length() == 1);
4700
4701   CONVERT_NUMBER_CHECKED(int32_t, number, Int32, args[0]);
4702   return isolate->heap()->ToBoolean(Smi::IsValid(number));
4703 }
4704
4705
4706 // Returns a single character string where first character equals
4707 // string->Get(index).
4708 static Handle<Object> GetCharAt(Handle<String> string, uint32_t index) {
4709   if (index < static_cast<uint32_t>(string->length())) {
4710     Factory* factory = string->GetIsolate()->factory();
4711     return factory->LookupSingleCharacterStringFromCode(
4712         String::Flatten(string)->Get(index));
4713   }
4714   return Execution::CharAt(string, index);
4715 }
4716
4717
4718 MaybeHandle<Object> Runtime::GetElementOrCharAt(Isolate* isolate,
4719                                                 Handle<Object> object,
4720                                                 uint32_t index) {
4721   // Handle [] indexing on Strings
4722   if (object->IsString()) {
4723     Handle<Object> result = GetCharAt(Handle<String>::cast(object), index);
4724     if (!result->IsUndefined()) return result;
4725   }
4726
4727   // Handle [] indexing on String objects
4728   if (object->IsStringObjectWithCharacterAt(index)) {
4729     Handle<JSValue> js_value = Handle<JSValue>::cast(object);
4730     Handle<Object> result =
4731         GetCharAt(Handle<String>(String::cast(js_value->value())), index);
4732     if (!result->IsUndefined()) return result;
4733   }
4734
4735   Handle<Object> result;
4736   if (object->IsString() || object->IsNumber() || object->IsBoolean()) {
4737     PrototypeIterator iter(isolate, object);
4738     return Object::GetElement(isolate, PrototypeIterator::GetCurrent(iter),
4739                               index);
4740   } else {
4741     return Object::GetElement(isolate, object, index);
4742   }
4743 }
4744
4745
4746 MUST_USE_RESULT
4747 static MaybeHandle<Name> ToName(Isolate* isolate, Handle<Object> key) {
4748   if (key->IsName()) {
4749     return Handle<Name>::cast(key);
4750   } else {
4751     Handle<Object> converted;
4752     ASSIGN_RETURN_ON_EXCEPTION(
4753         isolate, converted, Execution::ToString(isolate, key), Name);
4754     return Handle<Name>::cast(converted);
4755   }
4756 }
4757
4758
4759 MaybeHandle<Object> Runtime::HasObjectProperty(Isolate* isolate,
4760                                                Handle<JSReceiver> object,
4761                                                Handle<Object> key) {
4762   Maybe<bool> maybe;
4763   // Check if the given key is an array index.
4764   uint32_t index;
4765   if (key->ToArrayIndex(&index)) {
4766     maybe = JSReceiver::HasElement(object, index);
4767   } else {
4768     // Convert the key to a name - possibly by calling back into JavaScript.
4769     Handle<Name> name;
4770     ASSIGN_RETURN_ON_EXCEPTION(isolate, name, ToName(isolate, key), Object);
4771
4772     maybe = JSReceiver::HasProperty(object, name);
4773   }
4774
4775   if (!maybe.has_value) return MaybeHandle<Object>();
4776   return isolate->factory()->ToBoolean(maybe.value);
4777 }
4778
4779
4780 MaybeHandle<Object> Runtime::GetObjectProperty(Isolate* isolate,
4781                                                Handle<Object> object,
4782                                                Handle<Object> key) {
4783   if (object->IsUndefined() || object->IsNull()) {
4784     Handle<Object> args[2] = { key, object };
4785     return isolate->Throw<Object>(
4786         isolate->factory()->NewTypeError("non_object_property_load",
4787                                          HandleVector(args, 2)));
4788   }
4789
4790   // Check if the given key is an array index.
4791   uint32_t index;
4792   if (key->ToArrayIndex(&index)) {
4793     return GetElementOrCharAt(isolate, object, index);
4794   }
4795
4796   // Convert the key to a name - possibly by calling back into JavaScript.
4797   Handle<Name> name;
4798   ASSIGN_RETURN_ON_EXCEPTION(isolate, name, ToName(isolate, key), Object);
4799
4800   // Check if the name is trivially convertible to an index and get
4801   // the element if so.
4802   if (name->AsArrayIndex(&index)) {
4803     return GetElementOrCharAt(isolate, object, index);
4804   } else {
4805     return Object::GetProperty(object, name);
4806   }
4807 }
4808
4809
4810 RUNTIME_FUNCTION(Runtime_GetProperty) {
4811   HandleScope scope(isolate);
4812   DCHECK(args.length() == 2);
4813
4814   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
4815   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
4816   Handle<Object> result;
4817   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
4818       isolate, result,
4819       Runtime::GetObjectProperty(isolate, object, key));
4820   return *result;
4821 }
4822
4823
4824 // KeyedGetProperty is called from KeyedLoadIC::GenerateGeneric.
4825 RUNTIME_FUNCTION(Runtime_KeyedGetProperty) {
4826   HandleScope scope(isolate);
4827   DCHECK(args.length() == 2);
4828
4829   CONVERT_ARG_HANDLE_CHECKED(Object, receiver_obj, 0);
4830   CONVERT_ARG_HANDLE_CHECKED(Object, key_obj, 1);
4831
4832   // Fast cases for getting named properties of the receiver JSObject
4833   // itself.
4834   //
4835   // The global proxy objects has to be excluded since LookupOwn on
4836   // the global proxy object can return a valid result even though the
4837   // global proxy object never has properties.  This is the case
4838   // because the global proxy object forwards everything to its hidden
4839   // prototype including own lookups.
4840   //
4841   // Additionally, we need to make sure that we do not cache results
4842   // for objects that require access checks.
4843   if (receiver_obj->IsJSObject()) {
4844     if (!receiver_obj->IsJSGlobalProxy() &&
4845         !receiver_obj->IsAccessCheckNeeded() &&
4846         key_obj->IsName()) {
4847       DisallowHeapAllocation no_allocation;
4848       Handle<JSObject> receiver = Handle<JSObject>::cast(receiver_obj);
4849       Handle<Name> key = Handle<Name>::cast(key_obj);
4850       if (receiver->HasFastProperties()) {
4851         // Attempt to use lookup cache.
4852         Handle<Map> receiver_map(receiver->map(), isolate);
4853         KeyedLookupCache* keyed_lookup_cache = isolate->keyed_lookup_cache();
4854         int index = keyed_lookup_cache->Lookup(receiver_map, key);
4855         if (index != -1) {
4856           // Doubles are not cached, so raw read the value.
4857           return receiver->RawFastPropertyAt(
4858               FieldIndex::ForKeyedLookupCacheIndex(*receiver_map, index));
4859         }
4860         // Lookup cache miss.  Perform lookup and update the cache if
4861         // appropriate.
4862         LookupResult result(isolate);
4863         receiver->LookupOwn(key, &result);
4864         if (result.IsField()) {
4865           FieldIndex field_index = result.GetFieldIndex();
4866           // Do not track double fields in the keyed lookup cache. Reading
4867           // double values requires boxing.
4868           if (!result.representation().IsDouble()) {
4869             keyed_lookup_cache->Update(receiver_map, key,
4870                 field_index.GetKeyedLookupCacheIndex());
4871           }
4872           AllowHeapAllocation allow_allocation;
4873           return *JSObject::FastPropertyAt(receiver, result.representation(),
4874                                            field_index);
4875         }
4876       } else {
4877         // Attempt dictionary lookup.
4878         NameDictionary* dictionary = receiver->property_dictionary();
4879         int entry = dictionary->FindEntry(key);
4880         if ((entry != NameDictionary::kNotFound) &&
4881             (dictionary->DetailsAt(entry).type() == NORMAL)) {
4882           Object* value = dictionary->ValueAt(entry);
4883           if (!receiver->IsGlobalObject()) return value;
4884           value = PropertyCell::cast(value)->value();
4885           if (!value->IsTheHole()) return value;
4886           // If value is the hole (meaning, absent) do the general lookup.
4887         }
4888       }
4889     } else if (key_obj->IsSmi()) {
4890       // JSObject without a name key. If the key is a Smi, check for a
4891       // definite out-of-bounds access to elements, which is a strong indicator
4892       // that subsequent accesses will also call the runtime. Proactively
4893       // transition elements to FAST_*_ELEMENTS to avoid excessive boxing of
4894       // doubles for those future calls in the case that the elements would
4895       // become FAST_DOUBLE_ELEMENTS.
4896       Handle<JSObject> js_object = Handle<JSObject>::cast(receiver_obj);
4897       ElementsKind elements_kind = js_object->GetElementsKind();
4898       if (IsFastDoubleElementsKind(elements_kind)) {
4899         Handle<Smi> key = Handle<Smi>::cast(key_obj);
4900         if (key->value() >= js_object->elements()->length()) {
4901           if (IsFastHoleyElementsKind(elements_kind)) {
4902             elements_kind = FAST_HOLEY_ELEMENTS;
4903           } else {
4904             elements_kind = FAST_ELEMENTS;
4905           }
4906           RETURN_FAILURE_ON_EXCEPTION(
4907               isolate, TransitionElements(js_object, elements_kind, isolate));
4908         }
4909       } else {
4910         DCHECK(IsFastSmiOrObjectElementsKind(elements_kind) ||
4911                !IsFastElementsKind(elements_kind));
4912       }
4913     }
4914   } else if (receiver_obj->IsString() && key_obj->IsSmi()) {
4915     // Fast case for string indexing using [] with a smi index.
4916     Handle<String> str = Handle<String>::cast(receiver_obj);
4917     int index = args.smi_at(1);
4918     if (index >= 0 && index < str->length()) {
4919       return *GetCharAt(str, index);
4920     }
4921   }
4922
4923   // Fall back to GetObjectProperty.
4924   Handle<Object> result;
4925   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
4926       isolate, result,
4927       Runtime::GetObjectProperty(isolate, receiver_obj, key_obj));
4928   return *result;
4929 }
4930
4931
4932 static bool IsValidAccessor(Handle<Object> obj) {
4933   return obj->IsUndefined() || obj->IsSpecFunction() || obj->IsNull();
4934 }
4935
4936
4937 // Transform getter or setter into something DefineAccessor can handle.
4938 static Handle<Object> InstantiateAccessorComponent(Isolate* isolate,
4939                                                    Handle<Object> component) {
4940   if (component->IsUndefined()) return isolate->factory()->null_value();
4941   Handle<FunctionTemplateInfo> info =
4942       Handle<FunctionTemplateInfo>::cast(component);
4943   return Utils::OpenHandle(*Utils::ToLocal(info)->GetFunction());
4944 }
4945
4946
4947 RUNTIME_FUNCTION(Runtime_DefineApiAccessorProperty) {
4948   HandleScope scope(isolate);
4949   DCHECK(args.length() == 5);
4950   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
4951   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
4952   CONVERT_ARG_HANDLE_CHECKED(Object, getter, 2);
4953   CONVERT_ARG_HANDLE_CHECKED(Object, setter, 3);
4954   CONVERT_SMI_ARG_CHECKED(attribute, 4);
4955   RUNTIME_ASSERT(getter->IsUndefined() || getter->IsFunctionTemplateInfo());
4956   RUNTIME_ASSERT(setter->IsUndefined() || setter->IsFunctionTemplateInfo());
4957   RUNTIME_ASSERT(PropertyDetails::AttributesField::is_valid(
4958       static_cast<PropertyAttributes>(attribute)));
4959   RETURN_FAILURE_ON_EXCEPTION(
4960       isolate, JSObject::DefineAccessor(
4961                    object, name, InstantiateAccessorComponent(isolate, getter),
4962                    InstantiateAccessorComponent(isolate, setter),
4963                    static_cast<PropertyAttributes>(attribute)));
4964   return isolate->heap()->undefined_value();
4965 }
4966
4967
4968 // Implements part of 8.12.9 DefineOwnProperty.
4969 // There are 3 cases that lead here:
4970 // Step 4b - define a new accessor property.
4971 // Steps 9c & 12 - replace an existing data property with an accessor property.
4972 // Step 12 - update an existing accessor property with an accessor or generic
4973 //           descriptor.
4974 RUNTIME_FUNCTION(Runtime_DefineAccessorPropertyUnchecked) {
4975   HandleScope scope(isolate);
4976   DCHECK(args.length() == 5);
4977   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
4978   RUNTIME_ASSERT(!obj->IsNull());
4979   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
4980   CONVERT_ARG_HANDLE_CHECKED(Object, getter, 2);
4981   RUNTIME_ASSERT(IsValidAccessor(getter));
4982   CONVERT_ARG_HANDLE_CHECKED(Object, setter, 3);
4983   RUNTIME_ASSERT(IsValidAccessor(setter));
4984   CONVERT_SMI_ARG_CHECKED(unchecked, 4);
4985   RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
4986   PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked);
4987
4988   bool fast = obj->HasFastProperties();
4989   RETURN_FAILURE_ON_EXCEPTION(
4990       isolate, JSObject::DefineAccessor(obj, name, getter, setter, attr));
4991   if (fast) JSObject::MigrateSlowToFast(obj, 0);
4992   return isolate->heap()->undefined_value();
4993 }
4994
4995
4996 // Implements part of 8.12.9 DefineOwnProperty.
4997 // There are 3 cases that lead here:
4998 // Step 4a - define a new data property.
4999 // Steps 9b & 12 - replace an existing accessor property with a data property.
5000 // Step 12 - update an existing data property with a data or generic
5001 //           descriptor.
5002 RUNTIME_FUNCTION(Runtime_DefineDataPropertyUnchecked) {
5003   HandleScope scope(isolate);
5004   DCHECK(args.length() == 4);
5005   CONVERT_ARG_HANDLE_CHECKED(JSObject, js_object, 0);
5006   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
5007   CONVERT_ARG_HANDLE_CHECKED(Object, obj_value, 2);
5008   CONVERT_SMI_ARG_CHECKED(unchecked, 3);
5009   RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
5010   PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked);
5011
5012   // Check access rights if needed.
5013   if (js_object->IsAccessCheckNeeded() &&
5014       !isolate->MayNamedAccess(js_object, name, v8::ACCESS_SET)) {
5015     return isolate->heap()->undefined_value();
5016   }
5017
5018   LookupResult lookup(isolate);
5019   js_object->LookupOwnRealNamedProperty(name, &lookup);
5020
5021   // Take special care when attributes are different and there is already
5022   // a property. For simplicity we normalize the property which enables us
5023   // to not worry about changing the instance_descriptor and creating a new
5024   // map.
5025   if (lookup.IsFound() &&
5026       (attr != lookup.GetAttributes() || lookup.IsPropertyCallbacks())) {
5027     // Use IgnoreAttributes version since a readonly property may be
5028     // overridden and SetProperty does not allow this.
5029     Handle<Object> result;
5030     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
5031         isolate, result,
5032         JSObject::SetOwnPropertyIgnoreAttributes(
5033             js_object, name, obj_value, attr,
5034             JSReceiver::PERFORM_EXTENSIBILITY_CHECK,
5035             JSReceiver::MAY_BE_STORE_FROM_KEYED,
5036             JSObject::DONT_FORCE_FIELD));
5037     return *result;
5038   }
5039
5040   Handle<Object> result;
5041   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
5042       isolate, result,
5043       Runtime::DefineObjectProperty(
5044           js_object, name, obj_value, attr,
5045           JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED));
5046   return *result;
5047 }
5048
5049
5050 // Return property without being observable by accessors or interceptors.
5051 RUNTIME_FUNCTION(Runtime_GetDataProperty) {
5052   HandleScope scope(isolate);
5053   DCHECK(args.length() == 2);
5054   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
5055   CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
5056   return *JSObject::GetDataProperty(object, key);
5057 }
5058
5059
5060 MaybeHandle<Object> Runtime::SetObjectProperty(Isolate* isolate,
5061                                                Handle<Object> object,
5062                                                Handle<Object> key,
5063                                                Handle<Object> value,
5064                                                StrictMode strict_mode) {
5065   if (object->IsUndefined() || object->IsNull()) {
5066     Handle<Object> args[2] = { key, object };
5067     Handle<Object> error =
5068         isolate->factory()->NewTypeError("non_object_property_store",
5069                                          HandleVector(args, 2));
5070     return isolate->Throw<Object>(error);
5071   }
5072
5073   if (object->IsJSProxy()) {
5074     Handle<Object> name_object;
5075     if (key->IsSymbol()) {
5076       name_object = key;
5077     } else {
5078       ASSIGN_RETURN_ON_EXCEPTION(
5079           isolate, name_object, Execution::ToString(isolate, key), Object);
5080     }
5081     Handle<Name> name = Handle<Name>::cast(name_object);
5082     return Object::SetProperty(Handle<JSProxy>::cast(object), name, value,
5083                                strict_mode);
5084   }
5085
5086   // Check if the given key is an array index.
5087   uint32_t index;
5088   if (key->ToArrayIndex(&index)) {
5089     // TODO(verwaest): Support non-JSObject receivers.
5090     if (!object->IsJSObject()) return value;
5091     Handle<JSObject> js_object = Handle<JSObject>::cast(object);
5092
5093     // In Firefox/SpiderMonkey, Safari and Opera you can access the characters
5094     // of a string using [] notation.  We need to support this too in
5095     // JavaScript.
5096     // In the case of a String object we just need to redirect the assignment to
5097     // the underlying string if the index is in range.  Since the underlying
5098     // string does nothing with the assignment then we can ignore such
5099     // assignments.
5100     if (js_object->IsStringObjectWithCharacterAt(index)) {
5101       return value;
5102     }
5103
5104     JSObject::ValidateElements(js_object);
5105     if (js_object->HasExternalArrayElements() ||
5106         js_object->HasFixedTypedArrayElements()) {
5107       if (!value->IsNumber() &&  !value->IsFloat32x4() &&
5108           !value->IsFloat64x2() && !value->IsInt32x4() &&
5109           !value->IsUndefined()) {
5110         ASSIGN_RETURN_ON_EXCEPTION(
5111             isolate, value, Execution::ToNumber(isolate, value), Object);
5112       }
5113     }
5114
5115     MaybeHandle<Object> result = JSObject::SetElement(
5116         js_object, index, value, NONE, strict_mode, true, SET_PROPERTY);
5117     JSObject::ValidateElements(js_object);
5118
5119     return result.is_null() ? result : value;
5120   }
5121
5122   if (key->IsName()) {
5123     Handle<Name> name = Handle<Name>::cast(key);
5124     if (name->AsArrayIndex(&index)) {
5125       // TODO(verwaest): Support non-JSObject receivers.
5126       if (!object->IsJSObject()) return value;
5127       Handle<JSObject> js_object = Handle<JSObject>::cast(object);
5128       if (js_object->HasExternalArrayElements()) {
5129         if (!value->IsNumber() &&  !value->IsFloat32x4() &&
5130             !value->IsFloat64x2() && !value->IsInt32x4() &&
5131             !value->IsUndefined()) {
5132           ASSIGN_RETURN_ON_EXCEPTION(
5133               isolate, value, Execution::ToNumber(isolate, value), Object);
5134         }
5135       }
5136       return JSObject::SetElement(js_object, index, value, NONE, strict_mode,
5137                                   true, SET_PROPERTY);
5138     } else {
5139       if (name->IsString()) name = String::Flatten(Handle<String>::cast(name));
5140       return Object::SetProperty(object, name, value, strict_mode);
5141     }
5142   }
5143
5144   // Call-back into JavaScript to convert the key to a string.
5145   Handle<Object> converted;
5146   ASSIGN_RETURN_ON_EXCEPTION(
5147       isolate, converted, Execution::ToString(isolate, key), Object);
5148   Handle<String> name = Handle<String>::cast(converted);
5149
5150   if (name->AsArrayIndex(&index)) {
5151     // TODO(verwaest): Support non-JSObject receivers.
5152     if (!object->IsJSObject()) return value;
5153     Handle<JSObject> js_object = Handle<JSObject>::cast(object);
5154     return JSObject::SetElement(js_object, index, value, NONE, strict_mode,
5155                                 true, SET_PROPERTY);
5156   }
5157   return Object::SetProperty(object, name, value, strict_mode);
5158 }
5159
5160
5161 MaybeHandle<Object> Runtime::DefineObjectProperty(
5162     Handle<JSObject> js_object,
5163     Handle<Object> key,
5164     Handle<Object> value,
5165     PropertyAttributes attr,
5166     JSReceiver::StoreFromKeyed store_from_keyed) {
5167   Isolate* isolate = js_object->GetIsolate();
5168   // Check if the given key is an array index.
5169   uint32_t index;
5170   if (key->ToArrayIndex(&index)) {
5171     // In Firefox/SpiderMonkey, Safari and Opera you can access the characters
5172     // of a string using [] notation.  We need to support this too in
5173     // JavaScript.
5174     // In the case of a String object we just need to redirect the assignment to
5175     // the underlying string if the index is in range.  Since the underlying
5176     // string does nothing with the assignment then we can ignore such
5177     // assignments.
5178     if (js_object->IsStringObjectWithCharacterAt(index)) {
5179       return value;
5180     }
5181
5182     return JSObject::SetElement(js_object, index, value, attr,
5183                                 SLOPPY, false, DEFINE_PROPERTY);
5184   }
5185
5186   if (key->IsName()) {
5187     Handle<Name> name = Handle<Name>::cast(key);
5188     if (name->AsArrayIndex(&index)) {
5189       return JSObject::SetElement(js_object, index, value, attr,
5190                                   SLOPPY, false, DEFINE_PROPERTY);
5191     } else {
5192       if (name->IsString()) name = String::Flatten(Handle<String>::cast(name));
5193       return JSObject::SetOwnPropertyIgnoreAttributes(
5194           js_object, name, value, attr, JSReceiver::PERFORM_EXTENSIBILITY_CHECK,
5195           store_from_keyed);
5196     }
5197   }
5198
5199   // Call-back into JavaScript to convert the key to a string.
5200   Handle<Object> converted;
5201   ASSIGN_RETURN_ON_EXCEPTION(
5202       isolate, converted, Execution::ToString(isolate, key), Object);
5203   Handle<String> name = Handle<String>::cast(converted);
5204
5205   if (name->AsArrayIndex(&index)) {
5206     return JSObject::SetElement(js_object, index, value, attr,
5207                                 SLOPPY, false, DEFINE_PROPERTY);
5208   } else {
5209     return JSObject::SetOwnPropertyIgnoreAttributes(
5210         js_object, name, value, attr, JSReceiver::PERFORM_EXTENSIBILITY_CHECK,
5211         store_from_keyed);
5212   }
5213 }
5214
5215
5216 MaybeHandle<Object> Runtime::DeleteObjectProperty(Isolate* isolate,
5217                                                   Handle<JSReceiver> receiver,
5218                                                   Handle<Object> key,
5219                                                   JSReceiver::DeleteMode mode) {
5220   // Check if the given key is an array index.
5221   uint32_t index;
5222   if (key->ToArrayIndex(&index)) {
5223     // In Firefox/SpiderMonkey, Safari and Opera you can access the
5224     // characters of a string using [] notation.  In the case of a
5225     // String object we just need to redirect the deletion to the
5226     // underlying string if the index is in range.  Since the
5227     // underlying string does nothing with the deletion, we can ignore
5228     // such deletions.
5229     if (receiver->IsStringObjectWithCharacterAt(index)) {
5230       return isolate->factory()->true_value();
5231     }
5232
5233     return JSReceiver::DeleteElement(receiver, index, mode);
5234   }
5235
5236   Handle<Name> name;
5237   if (key->IsName()) {
5238     name = Handle<Name>::cast(key);
5239   } else {
5240     // Call-back into JavaScript to convert the key to a string.
5241     Handle<Object> converted;
5242     ASSIGN_RETURN_ON_EXCEPTION(
5243         isolate, converted, Execution::ToString(isolate, key), Object);
5244     name = Handle<String>::cast(converted);
5245   }
5246
5247   if (name->IsString()) name = String::Flatten(Handle<String>::cast(name));
5248   return JSReceiver::DeleteProperty(receiver, name, mode);
5249 }
5250
5251
5252 RUNTIME_FUNCTION(Runtime_SetHiddenProperty) {
5253   HandleScope scope(isolate);
5254   RUNTIME_ASSERT(args.length() == 3);
5255
5256   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
5257   CONVERT_ARG_HANDLE_CHECKED(String, key, 1);
5258   CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
5259   RUNTIME_ASSERT(key->IsUniqueName());
5260   return *JSObject::SetHiddenProperty(object, key, value);
5261 }
5262
5263
5264 RUNTIME_FUNCTION(Runtime_AddNamedProperty) {
5265   HandleScope scope(isolate);
5266   RUNTIME_ASSERT(args.length() == 4);
5267
5268   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
5269   CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
5270   CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
5271   CONVERT_SMI_ARG_CHECKED(unchecked_attributes, 3);
5272   RUNTIME_ASSERT(
5273       (unchecked_attributes & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
5274   // Compute attributes.
5275   PropertyAttributes attributes =
5276       static_cast<PropertyAttributes>(unchecked_attributes);
5277
5278 #ifdef DEBUG
5279   uint32_t index = 0;
5280   DCHECK(!key->ToArrayIndex(&index));
5281   LookupIterator it(object, key, LookupIterator::CHECK_OWN_REAL);
5282   Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
5283   DCHECK(maybe.has_value);
5284   RUNTIME_ASSERT(!it.IsFound());
5285 #endif
5286
5287   Handle<Object> result;
5288   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
5289       isolate, result,
5290       JSObject::SetOwnPropertyIgnoreAttributes(object, key, value, attributes));
5291   return *result;
5292 }
5293
5294
5295 RUNTIME_FUNCTION(Runtime_AddPropertyForTemplate) {
5296   HandleScope scope(isolate);
5297   RUNTIME_ASSERT(args.length() == 4);
5298
5299   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
5300   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
5301   CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
5302   CONVERT_SMI_ARG_CHECKED(unchecked_attributes, 3);
5303   RUNTIME_ASSERT(
5304       (unchecked_attributes & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
5305   // Compute attributes.
5306   PropertyAttributes attributes =
5307       static_cast<PropertyAttributes>(unchecked_attributes);
5308
5309 #ifdef DEBUG
5310   bool duplicate;
5311   if (key->IsName()) {
5312     LookupIterator it(object, Handle<Name>::cast(key),
5313                       LookupIterator::CHECK_OWN_REAL);
5314     Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
5315     DCHECK(maybe.has_value);
5316     duplicate = it.IsFound();
5317   } else {
5318     uint32_t index = 0;
5319     RUNTIME_ASSERT(key->ToArrayIndex(&index));
5320     Maybe<bool> maybe = JSReceiver::HasOwnElement(object, index);
5321     if (!maybe.has_value) return isolate->heap()->exception();
5322     duplicate = maybe.value;
5323   }
5324   if (duplicate) {
5325     Handle<Object> args[1] = { key };
5326     Handle<Object> error = isolate->factory()->NewTypeError(
5327         "duplicate_template_property", HandleVector(args, 1));
5328     return isolate->Throw(*error);
5329   }
5330 #endif
5331
5332   Handle<Object> result;
5333   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
5334       isolate, result,
5335       Runtime::DefineObjectProperty(object, key, value, attributes));
5336   return *result;
5337 }
5338
5339
5340 RUNTIME_FUNCTION(Runtime_SetProperty) {
5341   HandleScope scope(isolate);
5342   RUNTIME_ASSERT(args.length() == 4);
5343
5344   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
5345   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
5346   CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
5347   CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode_arg, 3);
5348   StrictMode strict_mode = strict_mode_arg;
5349
5350   Handle<Object> result;
5351   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
5352       isolate, result,
5353       Runtime::SetObjectProperty(isolate, object, key, value, strict_mode));
5354   return *result;
5355 }
5356
5357
5358 RUNTIME_FUNCTION(Runtime_TransitionElementsKind) {
5359   HandleScope scope(isolate);
5360   RUNTIME_ASSERT(args.length() == 2);
5361   CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
5362   CONVERT_ARG_HANDLE_CHECKED(Map, map, 1);
5363   JSObject::TransitionElementsKind(array, map->elements_kind());
5364   return *array;
5365 }
5366
5367
5368 // Set the native flag on the function.
5369 // This is used to decide if we should transform null and undefined
5370 // into the global object when doing call and apply.
5371 RUNTIME_FUNCTION(Runtime_SetNativeFlag) {
5372   SealHandleScope shs(isolate);
5373   RUNTIME_ASSERT(args.length() == 1);
5374
5375   CONVERT_ARG_CHECKED(Object, object, 0);
5376
5377   if (object->IsJSFunction()) {
5378     JSFunction* func = JSFunction::cast(object);
5379     func->shared()->set_native(true);
5380   }
5381   return isolate->heap()->undefined_value();
5382 }
5383
5384
5385 RUNTIME_FUNCTION(Runtime_SetInlineBuiltinFlag) {
5386   SealHandleScope shs(isolate);
5387   RUNTIME_ASSERT(args.length() == 1);
5388   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
5389
5390   if (object->IsJSFunction()) {
5391     JSFunction* func = JSFunction::cast(*object);
5392     func->shared()->set_inline_builtin(true);
5393   }
5394   return isolate->heap()->undefined_value();
5395 }
5396
5397
5398 RUNTIME_FUNCTION(Runtime_StoreArrayLiteralElement) {
5399   HandleScope scope(isolate);
5400   RUNTIME_ASSERT(args.length() == 5);
5401   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
5402   CONVERT_SMI_ARG_CHECKED(store_index, 1);
5403   CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
5404   CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 3);
5405   CONVERT_SMI_ARG_CHECKED(literal_index, 4);
5406
5407   Object* raw_literal_cell = literals->get(literal_index);
5408   JSArray* boilerplate = NULL;
5409   if (raw_literal_cell->IsAllocationSite()) {
5410     AllocationSite* site = AllocationSite::cast(raw_literal_cell);
5411     boilerplate = JSArray::cast(site->transition_info());
5412   } else {
5413     boilerplate = JSArray::cast(raw_literal_cell);
5414   }
5415   Handle<JSArray> boilerplate_object(boilerplate);
5416   ElementsKind elements_kind = object->GetElementsKind();
5417   DCHECK(IsFastElementsKind(elements_kind));
5418   // Smis should never trigger transitions.
5419   DCHECK(!value->IsSmi());
5420
5421   if (value->IsNumber()) {
5422     DCHECK(IsFastSmiElementsKind(elements_kind));
5423     ElementsKind transitioned_kind = IsFastHoleyElementsKind(elements_kind)
5424         ? FAST_HOLEY_DOUBLE_ELEMENTS
5425         : FAST_DOUBLE_ELEMENTS;
5426     if (IsMoreGeneralElementsKindTransition(
5427             boilerplate_object->GetElementsKind(),
5428             transitioned_kind)) {
5429       JSObject::TransitionElementsKind(boilerplate_object, transitioned_kind);
5430     }
5431     JSObject::TransitionElementsKind(object, transitioned_kind);
5432     DCHECK(IsFastDoubleElementsKind(object->GetElementsKind()));
5433     FixedDoubleArray* double_array = FixedDoubleArray::cast(object->elements());
5434     HeapNumber* number = HeapNumber::cast(*value);
5435     double_array->set(store_index, number->Number());
5436   } else {
5437     if (!IsFastObjectElementsKind(elements_kind)) {
5438       ElementsKind transitioned_kind = IsFastHoleyElementsKind(elements_kind)
5439           ? FAST_HOLEY_ELEMENTS
5440           : FAST_ELEMENTS;
5441       JSObject::TransitionElementsKind(object, transitioned_kind);
5442       ElementsKind boilerplate_elements_kind =
5443           boilerplate_object->GetElementsKind();
5444       if (IsMoreGeneralElementsKindTransition(boilerplate_elements_kind,
5445                                               transitioned_kind)) {
5446         JSObject::TransitionElementsKind(boilerplate_object, transitioned_kind);
5447       }
5448     }
5449     FixedArray* object_array = FixedArray::cast(object->elements());
5450     object_array->set(store_index, *value);
5451   }
5452   return *object;
5453 }
5454
5455
5456 // Check whether debugger and is about to step into the callback that is passed
5457 // to a built-in function such as Array.forEach.
5458 RUNTIME_FUNCTION(Runtime_DebugCallbackSupportsStepping) {
5459   DCHECK(args.length() == 1);
5460   if (!isolate->debug()->is_active() || !isolate->debug()->StepInActive()) {
5461     return isolate->heap()->false_value();
5462   }
5463   CONVERT_ARG_CHECKED(Object, callback, 0);
5464   // We do not step into the callback if it's a builtin or not even a function.
5465   return isolate->heap()->ToBoolean(
5466       callback->IsJSFunction() && !JSFunction::cast(callback)->IsBuiltin());
5467 }
5468
5469
5470 // Set one shot breakpoints for the callback function that is passed to a
5471 // built-in function such as Array.forEach to enable stepping into the callback.
5472 RUNTIME_FUNCTION(Runtime_DebugPrepareStepInIfStepping) {
5473   DCHECK(args.length() == 1);
5474   Debug* debug = isolate->debug();
5475   if (!debug->IsStepping()) return isolate->heap()->undefined_value();
5476   CONVERT_ARG_HANDLE_CHECKED(JSFunction, callback, 0);
5477   HandleScope scope(isolate);
5478   // When leaving the callback, step out has been activated, but not performed
5479   // if we do not leave the builtin.  To be able to step into the callback
5480   // again, we need to clear the step out at this point.
5481   debug->ClearStepOut();
5482   debug->FloodWithOneShot(callback);
5483   return isolate->heap()->undefined_value();
5484 }
5485
5486
5487 RUNTIME_FUNCTION(Runtime_DebugPushPromise) {
5488   DCHECK(args.length() == 1);
5489   HandleScope scope(isolate);
5490   CONVERT_ARG_HANDLE_CHECKED(JSObject, promise, 0);
5491   isolate->debug()->PushPromise(promise);
5492   return isolate->heap()->undefined_value();
5493 }
5494
5495
5496 RUNTIME_FUNCTION(Runtime_DebugPopPromise) {
5497   DCHECK(args.length() == 0);
5498   SealHandleScope shs(isolate);
5499   isolate->debug()->PopPromise();
5500   return isolate->heap()->undefined_value();
5501 }
5502
5503
5504 RUNTIME_FUNCTION(Runtime_DebugPromiseEvent) {
5505   DCHECK(args.length() == 1);
5506   HandleScope scope(isolate);
5507   CONVERT_ARG_HANDLE_CHECKED(JSObject, data, 0);
5508   isolate->debug()->OnPromiseEvent(data);
5509   return isolate->heap()->undefined_value();
5510 }
5511
5512
5513 RUNTIME_FUNCTION(Runtime_DebugPromiseRejectEvent) {
5514   DCHECK(args.length() == 2);
5515   HandleScope scope(isolate);
5516   CONVERT_ARG_HANDLE_CHECKED(JSObject, promise, 0);
5517   CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
5518   isolate->debug()->OnPromiseReject(promise, value);
5519   return isolate->heap()->undefined_value();
5520 }
5521
5522
5523 RUNTIME_FUNCTION(Runtime_DebugAsyncTaskEvent) {
5524   DCHECK(args.length() == 1);
5525   HandleScope scope(isolate);
5526   CONVERT_ARG_HANDLE_CHECKED(JSObject, data, 0);
5527   isolate->debug()->OnAsyncTaskEvent(data);
5528   return isolate->heap()->undefined_value();
5529 }
5530
5531
5532 RUNTIME_FUNCTION(Runtime_DeleteProperty) {
5533   HandleScope scope(isolate);
5534   DCHECK(args.length() == 3);
5535   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
5536   CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
5537   CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 2);
5538   JSReceiver::DeleteMode delete_mode = strict_mode == STRICT
5539       ? JSReceiver::STRICT_DELETION : JSReceiver::NORMAL_DELETION;
5540   Handle<Object> result;
5541   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
5542       isolate, result,
5543       JSReceiver::DeleteProperty(object, key, delete_mode));
5544   return *result;
5545 }
5546
5547
5548 static Object* HasOwnPropertyImplementation(Isolate* isolate,
5549                                             Handle<JSObject> object,
5550                                             Handle<Name> key) {
5551   Maybe<bool> maybe = JSReceiver::HasOwnProperty(object, key);
5552   if (!maybe.has_value) return isolate->heap()->exception();
5553   if (maybe.value) return isolate->heap()->true_value();
5554   // Handle hidden prototypes.  If there's a hidden prototype above this thing
5555   // then we have to check it for properties, because they are supposed to
5556   // look like they are on this object.
5557   PrototypeIterator iter(isolate, object);
5558   if (!iter.IsAtEnd() &&
5559       Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter))
5560           ->map()
5561           ->is_hidden_prototype()) {
5562     // TODO(verwaest): The recursion is not necessary for keys that are array
5563     // indices. Removing this.
5564     return HasOwnPropertyImplementation(
5565         isolate, Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)),
5566         key);
5567   }
5568   RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
5569   return isolate->heap()->false_value();
5570 }
5571
5572
5573 RUNTIME_FUNCTION(Runtime_HasOwnProperty) {
5574   HandleScope scope(isolate);
5575   DCHECK(args.length() == 2);
5576   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0)
5577   CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
5578
5579   uint32_t index;
5580   const bool key_is_array_index = key->AsArrayIndex(&index);
5581
5582   // Only JS objects can have properties.
5583   if (object->IsJSObject()) {
5584     Handle<JSObject> js_obj = Handle<JSObject>::cast(object);
5585     // Fast case: either the key is a real named property or it is not
5586     // an array index and there are no interceptors or hidden
5587     // prototypes.
5588     Maybe<bool> maybe = JSObject::HasRealNamedProperty(js_obj, key);
5589     if (!maybe.has_value) return isolate->heap()->exception();
5590     DCHECK(!isolate->has_pending_exception());
5591     if (maybe.value) {
5592       return isolate->heap()->true_value();
5593     }
5594     Map* map = js_obj->map();
5595     if (!key_is_array_index &&
5596         !map->has_named_interceptor() &&
5597         !HeapObject::cast(map->prototype())->map()->is_hidden_prototype()) {
5598       return isolate->heap()->false_value();
5599     }
5600     // Slow case.
5601     return HasOwnPropertyImplementation(isolate,
5602                                         Handle<JSObject>(js_obj),
5603                                         Handle<Name>(key));
5604   } else if (object->IsString() && key_is_array_index) {
5605     // Well, there is one exception:  Handle [] on strings.
5606     Handle<String> string = Handle<String>::cast(object);
5607     if (index < static_cast<uint32_t>(string->length())) {
5608       return isolate->heap()->true_value();
5609     }
5610   }
5611   return isolate->heap()->false_value();
5612 }
5613
5614
5615 RUNTIME_FUNCTION(Runtime_HasProperty) {
5616   HandleScope scope(isolate);
5617   DCHECK(args.length() == 2);
5618   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
5619   CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
5620
5621   Maybe<bool> maybe = JSReceiver::HasProperty(receiver, key);
5622   if (!maybe.has_value) return isolate->heap()->exception();
5623   return isolate->heap()->ToBoolean(maybe.value);
5624 }
5625
5626
5627 RUNTIME_FUNCTION(Runtime_HasElement) {
5628   HandleScope scope(isolate);
5629   DCHECK(args.length() == 2);
5630   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
5631   CONVERT_SMI_ARG_CHECKED(index, 1);
5632
5633   Maybe<bool> maybe = JSReceiver::HasElement(receiver, index);
5634   if (!maybe.has_value) return isolate->heap()->exception();
5635   return isolate->heap()->ToBoolean(maybe.value);
5636 }
5637
5638
5639 RUNTIME_FUNCTION(Runtime_IsPropertyEnumerable) {
5640   HandleScope scope(isolate);
5641   DCHECK(args.length() == 2);
5642
5643   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
5644   CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
5645
5646   Maybe<PropertyAttributes> maybe =
5647       JSReceiver::GetOwnPropertyAttributes(object, key);
5648   if (!maybe.has_value) return isolate->heap()->exception();
5649   if (maybe.value == ABSENT) maybe.value = DONT_ENUM;
5650   return isolate->heap()->ToBoolean((maybe.value & DONT_ENUM) == 0);
5651 }
5652
5653
5654 RUNTIME_FUNCTION(Runtime_GetPropertyNames) {
5655   HandleScope scope(isolate);
5656   DCHECK(args.length() == 1);
5657   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
5658   Handle<JSArray> result;
5659
5660   isolate->counters()->for_in()->Increment();
5661   Handle<FixedArray> elements;
5662   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
5663       isolate, elements,
5664       JSReceiver::GetKeys(object, JSReceiver::INCLUDE_PROTOS));
5665   return *isolate->factory()->NewJSArrayWithElements(elements);
5666 }
5667
5668
5669 // Returns either a FixedArray as Runtime_GetPropertyNames,
5670 // or, if the given object has an enum cache that contains
5671 // all enumerable properties of the object and its prototypes
5672 // have none, the map of the object. This is used to speed up
5673 // the check for deletions during a for-in.
5674 RUNTIME_FUNCTION(Runtime_GetPropertyNamesFast) {
5675   SealHandleScope shs(isolate);
5676   DCHECK(args.length() == 1);
5677
5678   CONVERT_ARG_CHECKED(JSReceiver, raw_object, 0);
5679
5680   if (raw_object->IsSimpleEnum()) return raw_object->map();
5681
5682   HandleScope scope(isolate);
5683   Handle<JSReceiver> object(raw_object);
5684   Handle<FixedArray> content;
5685   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
5686       isolate, content,
5687       JSReceiver::GetKeys(object, JSReceiver::INCLUDE_PROTOS));
5688
5689   // Test again, since cache may have been built by preceding call.
5690   if (object->IsSimpleEnum()) return object->map();
5691
5692   return *content;
5693 }
5694
5695
5696 // Find the length of the prototype chain that is to be handled as one. If a
5697 // prototype object is hidden it is to be viewed as part of the the object it
5698 // is prototype for.
5699 static int OwnPrototypeChainLength(JSObject* obj) {
5700   int count = 1;
5701   for (PrototypeIterator iter(obj->GetIsolate(), obj);
5702        !iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN); iter.Advance()) {
5703     count++;
5704   }
5705   return count;
5706 }
5707
5708
5709 // Return the names of the own named properties.
5710 // args[0]: object
5711 // args[1]: PropertyAttributes as int
5712 RUNTIME_FUNCTION(Runtime_GetOwnPropertyNames) {
5713   HandleScope scope(isolate);
5714   DCHECK(args.length() == 2);
5715   if (!args[0]->IsJSObject()) {
5716     return isolate->heap()->undefined_value();
5717   }
5718   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
5719   CONVERT_SMI_ARG_CHECKED(filter_value, 1);
5720   PropertyAttributes filter = static_cast<PropertyAttributes>(filter_value);
5721
5722   // Skip the global proxy as it has no properties and always delegates to the
5723   // real global object.
5724   if (obj->IsJSGlobalProxy()) {
5725     // Only collect names if access is permitted.
5726     if (obj->IsAccessCheckNeeded() &&
5727         !isolate->MayNamedAccess(
5728             obj, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) {
5729       isolate->ReportFailedAccessCheck(obj, v8::ACCESS_KEYS);
5730       RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
5731       return *isolate->factory()->NewJSArray(0);
5732     }
5733     PrototypeIterator iter(isolate, obj);
5734     obj = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
5735   }
5736
5737   // Find the number of objects making up this.
5738   int length = OwnPrototypeChainLength(*obj);
5739
5740   // Find the number of own properties for each of the objects.
5741   ScopedVector<int> own_property_count(length);
5742   int total_property_count = 0;
5743   {
5744     PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER);
5745     for (int i = 0; i < length; i++) {
5746       DCHECK(!iter.IsAtEnd());
5747       Handle<JSObject> jsproto =
5748           Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
5749       // Only collect names if access is permitted.
5750       if (jsproto->IsAccessCheckNeeded() &&
5751           !isolate->MayNamedAccess(jsproto,
5752                                    isolate->factory()->undefined_value(),
5753                                    v8::ACCESS_KEYS)) {
5754         isolate->ReportFailedAccessCheck(jsproto, v8::ACCESS_KEYS);
5755         RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
5756         return *isolate->factory()->NewJSArray(0);
5757       }
5758       int n;
5759       n = jsproto->NumberOfOwnProperties(filter);
5760       own_property_count[i] = n;
5761       total_property_count += n;
5762       iter.Advance();
5763     }
5764   }
5765
5766   // Allocate an array with storage for all the property names.
5767   Handle<FixedArray> names =
5768       isolate->factory()->NewFixedArray(total_property_count);
5769
5770   // Get the property names.
5771   int next_copy_index = 0;
5772   int hidden_strings = 0;
5773   {
5774     PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER);
5775     for (int i = 0; i < length; i++) {
5776       DCHECK(!iter.IsAtEnd());
5777       Handle<JSObject> jsproto =
5778           Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
5779       jsproto->GetOwnPropertyNames(*names, next_copy_index, filter);
5780       if (i > 0) {
5781         // Names from hidden prototypes may already have been added
5782         // for inherited function template instances. Count the duplicates
5783         // and stub them out; the final copy pass at the end ignores holes.
5784         for (int j = next_copy_index;
5785              j < next_copy_index + own_property_count[i]; j++) {
5786           Object* name_from_hidden_proto = names->get(j);
5787           for (int k = 0; k < next_copy_index; k++) {
5788             if (names->get(k) != isolate->heap()->hidden_string()) {
5789               Object* name = names->get(k);
5790               if (name_from_hidden_proto == name) {
5791                 names->set(j, isolate->heap()->hidden_string());
5792                 hidden_strings++;
5793                 break;
5794               }
5795             }
5796           }
5797         }
5798       }
5799       next_copy_index += own_property_count[i];
5800
5801       // Hidden properties only show up if the filter does not skip strings.
5802       if ((filter & STRING) == 0 && JSObject::HasHiddenProperties(jsproto)) {
5803         hidden_strings++;
5804       }
5805       iter.Advance();
5806     }
5807   }
5808
5809   // Filter out name of hidden properties object and
5810   // hidden prototype duplicates.
5811   if (hidden_strings > 0) {
5812     Handle<FixedArray> old_names = names;
5813     names = isolate->factory()->NewFixedArray(
5814         names->length() - hidden_strings);
5815     int dest_pos = 0;
5816     for (int i = 0; i < total_property_count; i++) {
5817       Object* name = old_names->get(i);
5818       if (name == isolate->heap()->hidden_string()) {
5819         hidden_strings--;
5820         continue;
5821       }
5822       names->set(dest_pos++, name);
5823     }
5824     DCHECK_EQ(0, hidden_strings);
5825   }
5826
5827   return *isolate->factory()->NewJSArrayWithElements(names);
5828 }
5829
5830
5831 // Return the names of the own indexed properties.
5832 // args[0]: object
5833 RUNTIME_FUNCTION(Runtime_GetOwnElementNames) {
5834   HandleScope scope(isolate);
5835   DCHECK(args.length() == 1);
5836   if (!args[0]->IsJSObject()) {
5837     return isolate->heap()->undefined_value();
5838   }
5839   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
5840
5841   int n = obj->NumberOfOwnElements(static_cast<PropertyAttributes>(NONE));
5842   Handle<FixedArray> names = isolate->factory()->NewFixedArray(n);
5843   obj->GetOwnElementKeys(*names, static_cast<PropertyAttributes>(NONE));
5844   return *isolate->factory()->NewJSArrayWithElements(names);
5845 }
5846
5847
5848 // Return information on whether an object has a named or indexed interceptor.
5849 // args[0]: object
5850 RUNTIME_FUNCTION(Runtime_GetInterceptorInfo) {
5851   HandleScope scope(isolate);
5852   DCHECK(args.length() == 1);
5853   if (!args[0]->IsJSObject()) {
5854     return Smi::FromInt(0);
5855   }
5856   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
5857
5858   int result = 0;
5859   if (obj->HasNamedInterceptor()) result |= 2;
5860   if (obj->HasIndexedInterceptor()) result |= 1;
5861
5862   return Smi::FromInt(result);
5863 }
5864
5865
5866 // Return property names from named interceptor.
5867 // args[0]: object
5868 RUNTIME_FUNCTION(Runtime_GetNamedInterceptorPropertyNames) {
5869   HandleScope scope(isolate);
5870   DCHECK(args.length() == 1);
5871   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
5872
5873   if (obj->HasNamedInterceptor()) {
5874     Handle<JSObject> result;
5875     if (JSObject::GetKeysForNamedInterceptor(obj, obj).ToHandle(&result)) {
5876       return *result;
5877     }
5878   }
5879   return isolate->heap()->undefined_value();
5880 }
5881
5882
5883 // Return element names from indexed interceptor.
5884 // args[0]: object
5885 RUNTIME_FUNCTION(Runtime_GetIndexedInterceptorElementNames) {
5886   HandleScope scope(isolate);
5887   DCHECK(args.length() == 1);
5888   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
5889
5890   if (obj->HasIndexedInterceptor()) {
5891     Handle<JSObject> result;
5892     if (JSObject::GetKeysForIndexedInterceptor(obj, obj).ToHandle(&result)) {
5893       return *result;
5894     }
5895   }
5896   return isolate->heap()->undefined_value();
5897 }
5898
5899
5900 RUNTIME_FUNCTION(Runtime_OwnKeys) {
5901   HandleScope scope(isolate);
5902   DCHECK(args.length() == 1);
5903   CONVERT_ARG_CHECKED(JSObject, raw_object, 0);
5904   Handle<JSObject> object(raw_object);
5905
5906   if (object->IsJSGlobalProxy()) {
5907     // Do access checks before going to the global object.
5908     if (object->IsAccessCheckNeeded() &&
5909         !isolate->MayNamedAccess(
5910             object, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) {
5911       isolate->ReportFailedAccessCheck(object, v8::ACCESS_KEYS);
5912       RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
5913       return *isolate->factory()->NewJSArray(0);
5914     }
5915
5916     PrototypeIterator iter(isolate, object);
5917     // If proxy is detached we simply return an empty array.
5918     if (iter.IsAtEnd()) return *isolate->factory()->NewJSArray(0);
5919     object = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
5920   }
5921
5922   Handle<FixedArray> contents;
5923   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
5924       isolate, contents,
5925       JSReceiver::GetKeys(object, JSReceiver::OWN_ONLY));
5926
5927   // Some fast paths through GetKeysInFixedArrayFor reuse a cached
5928   // property array and since the result is mutable we have to create
5929   // a fresh clone on each invocation.
5930   int length = contents->length();
5931   Handle<FixedArray> copy = isolate->factory()->NewFixedArray(length);
5932   for (int i = 0; i < length; i++) {
5933     Object* entry = contents->get(i);
5934     if (entry->IsString()) {
5935       copy->set(i, entry);
5936     } else {
5937       DCHECK(entry->IsNumber());
5938       HandleScope scope(isolate);
5939       Handle<Object> entry_handle(entry, isolate);
5940       Handle<Object> entry_str =
5941           isolate->factory()->NumberToString(entry_handle);
5942       copy->set(i, *entry_str);
5943     }
5944   }
5945   return *isolate->factory()->NewJSArrayWithElements(copy);
5946 }
5947
5948
5949 RUNTIME_FUNCTION(Runtime_GetArgumentsProperty) {
5950   SealHandleScope shs(isolate);
5951   DCHECK(args.length() == 1);
5952   CONVERT_ARG_HANDLE_CHECKED(Object, raw_key, 0);
5953
5954   // Compute the frame holding the arguments.
5955   JavaScriptFrameIterator it(isolate);
5956   it.AdvanceToArgumentsFrame();
5957   JavaScriptFrame* frame = it.frame();
5958
5959   // Get the actual number of provided arguments.
5960   const uint32_t n = frame->ComputeParametersCount();
5961
5962   // Try to convert the key to an index. If successful and within
5963   // index return the the argument from the frame.
5964   uint32_t index;
5965   if (raw_key->ToArrayIndex(&index) && index < n) {
5966     return frame->GetParameter(index);
5967   }
5968
5969   HandleScope scope(isolate);
5970   if (raw_key->IsSymbol()) {
5971     // Lookup in the initial Object.prototype object.
5972     Handle<Object> result;
5973     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
5974         isolate, result,
5975         Object::GetProperty(isolate->initial_object_prototype(),
5976                             Handle<Symbol>::cast(raw_key)));
5977     return *result;
5978   }
5979
5980   // Convert the key to a string.
5981   Handle<Object> converted;
5982   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
5983       isolate, converted, Execution::ToString(isolate, raw_key));
5984   Handle<String> key = Handle<String>::cast(converted);
5985
5986   // Try to convert the string key into an array index.
5987   if (key->AsArrayIndex(&index)) {
5988     if (index < n) {
5989       return frame->GetParameter(index);
5990     } else {
5991       Handle<Object> initial_prototype(isolate->initial_object_prototype());
5992       Handle<Object> result;
5993       ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
5994           isolate, result,
5995           Object::GetElement(isolate, initial_prototype, index));
5996       return *result;
5997     }
5998   }
5999
6000   // Handle special arguments properties.
6001   if (String::Equals(isolate->factory()->length_string(), key)) {
6002     return Smi::FromInt(n);
6003   }
6004   if (String::Equals(isolate->factory()->callee_string(), key)) {
6005     JSFunction* function = frame->function();
6006     if (function->shared()->strict_mode() == STRICT) {
6007       return isolate->Throw(*isolate->factory()->NewTypeError(
6008           "strict_arguments_callee", HandleVector<Object>(NULL, 0)));
6009     }
6010     return function;
6011   }
6012
6013   // Lookup in the initial Object.prototype object.
6014   Handle<Object> result;
6015   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
6016       isolate, result,
6017       Object::GetProperty(isolate->initial_object_prototype(), key));
6018   return *result;
6019 }
6020
6021
6022 RUNTIME_FUNCTION(Runtime_ToFastProperties) {
6023   HandleScope scope(isolate);
6024   DCHECK(args.length() == 1);
6025   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
6026   if (object->IsJSObject() && !object->IsGlobalObject()) {
6027     JSObject::MigrateSlowToFast(Handle<JSObject>::cast(object), 0);
6028   }
6029   return *object;
6030 }
6031
6032
6033 RUNTIME_FUNCTION(Runtime_ToBool) {
6034   SealHandleScope shs(isolate);
6035   DCHECK(args.length() == 1);
6036   CONVERT_ARG_CHECKED(Object, object, 0);
6037
6038   return isolate->heap()->ToBoolean(object->BooleanValue());
6039 }
6040
6041
6042 // Returns the type string of a value; see ECMA-262, 11.4.3 (p 47).
6043 // Possible optimizations: put the type string into the oddballs.
6044 RUNTIME_FUNCTION(Runtime_Typeof) {
6045   SealHandleScope shs(isolate);
6046   DCHECK(args.length() == 1);
6047   CONVERT_ARG_CHECKED(Object, obj, 0);
6048   if (obj->IsNumber()) return isolate->heap()->number_string();
6049   HeapObject* heap_obj = HeapObject::cast(obj);
6050
6051   // typeof an undetectable object is 'undefined'
6052   if (heap_obj->map()->is_undetectable()) {
6053     return isolate->heap()->undefined_string();
6054   }
6055
6056   InstanceType instance_type = heap_obj->map()->instance_type();
6057   if (instance_type < FIRST_NONSTRING_TYPE) {
6058     return isolate->heap()->string_string();
6059   }
6060
6061   switch (instance_type) {
6062     case ODDBALL_TYPE:
6063       if (heap_obj->IsTrue() || heap_obj->IsFalse()) {
6064         return isolate->heap()->boolean_string();
6065       }
6066       if (heap_obj->IsNull()) {
6067         return isolate->heap()->object_string();
6068       }
6069       DCHECK(heap_obj->IsUndefined());
6070       return isolate->heap()->undefined_string();
6071     case SYMBOL_TYPE:
6072       return isolate->heap()->symbol_string();
6073     case JS_FUNCTION_TYPE:
6074     case JS_FUNCTION_PROXY_TYPE:
6075       return isolate->heap()->function_string();
6076     default:
6077       // For any kind of object not handled above, the spec rule for
6078       // host objects gives that it is okay to return "object"
6079       return isolate->heap()->object_string();
6080   }
6081 }
6082
6083
6084 RUNTIME_FUNCTION(Runtime_Booleanize) {
6085   SealHandleScope shs(isolate);
6086   DCHECK(args.length() == 2);
6087   CONVERT_ARG_CHECKED(Object, value_raw, 0);
6088   CONVERT_SMI_ARG_CHECKED(token_raw, 1);
6089   intptr_t value = reinterpret_cast<intptr_t>(value_raw);
6090   Token::Value token = static_cast<Token::Value>(token_raw);
6091   switch (token) {
6092     case Token::EQ:
6093     case Token::EQ_STRICT:
6094       return isolate->heap()->ToBoolean(value == 0);
6095     case Token::NE:
6096     case Token::NE_STRICT:
6097       return isolate->heap()->ToBoolean(value != 0);
6098     case Token::LT:
6099       return isolate->heap()->ToBoolean(value < 0);
6100     case Token::GT:
6101       return isolate->heap()->ToBoolean(value > 0);
6102     case Token::LTE:
6103       return isolate->heap()->ToBoolean(value <= 0);
6104     case Token::GTE:
6105       return isolate->heap()->ToBoolean(value >= 0);
6106     default:
6107       // This should only happen during natives fuzzing.
6108       return isolate->heap()->undefined_value();
6109   }
6110 }
6111
6112
6113 static bool AreDigits(const uint8_t*s, int from, int to) {
6114   for (int i = from; i < to; i++) {
6115     if (s[i] < '0' || s[i] > '9') return false;
6116   }
6117
6118   return true;
6119 }
6120
6121
6122 static int ParseDecimalInteger(const uint8_t*s, int from, int to) {
6123   DCHECK(to - from < 10);  // Overflow is not possible.
6124   DCHECK(from < to);
6125   int d = s[from] - '0';
6126
6127   for (int i = from + 1; i < to; i++) {
6128     d = 10 * d + (s[i] - '0');
6129   }
6130
6131   return d;
6132 }
6133
6134
6135 RUNTIME_FUNCTION(Runtime_StringToNumber) {
6136   HandleScope handle_scope(isolate);
6137   DCHECK(args.length() == 1);
6138   CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
6139   subject = String::Flatten(subject);
6140
6141   // Fast case: short integer or some sorts of junk values.
6142   if (subject->IsSeqOneByteString()) {
6143     int len = subject->length();
6144     if (len == 0) return Smi::FromInt(0);
6145
6146     DisallowHeapAllocation no_gc;
6147     uint8_t const* data = Handle<SeqOneByteString>::cast(subject)->GetChars();
6148     bool minus = (data[0] == '-');
6149     int start_pos = (minus ? 1 : 0);
6150
6151     if (start_pos == len) {
6152       return isolate->heap()->nan_value();
6153     } else if (data[start_pos] > '9') {
6154       // Fast check for a junk value. A valid string may start from a
6155       // whitespace, a sign ('+' or '-'), the decimal point, a decimal digit
6156       // or the 'I' character ('Infinity'). All of that have codes not greater
6157       // than '9' except 'I' and &nbsp;.
6158       if (data[start_pos] != 'I' && data[start_pos] != 0xa0) {
6159         return isolate->heap()->nan_value();
6160       }
6161     } else if (len - start_pos < 10 && AreDigits(data, start_pos, len)) {
6162       // The maximal/minimal smi has 10 digits. If the string has less digits
6163       // we know it will fit into the smi-data type.
6164       int d = ParseDecimalInteger(data, start_pos, len);
6165       if (minus) {
6166         if (d == 0) return isolate->heap()->minus_zero_value();
6167         d = -d;
6168       } else if (!subject->HasHashCode() &&
6169                  len <= String::kMaxArrayIndexSize &&
6170                  (len == 1 || data[0] != '0')) {
6171         // String hash is not calculated yet but all the data are present.
6172         // Update the hash field to speed up sequential convertions.
6173         uint32_t hash = StringHasher::MakeArrayIndexHash(d, len);
6174 #ifdef DEBUG
6175         subject->Hash();  // Force hash calculation.
6176         DCHECK_EQ(static_cast<int>(subject->hash_field()),
6177                   static_cast<int>(hash));
6178 #endif
6179         subject->set_hash_field(hash);
6180       }
6181       return Smi::FromInt(d);
6182     }
6183   }
6184
6185   // Slower case.
6186   int flags = ALLOW_HEX;
6187   if (FLAG_harmony_numeric_literals) {
6188     // The current spec draft has not updated "ToNumber Applied to the String
6189     // Type", https://bugs.ecmascript.org/show_bug.cgi?id=1584
6190     flags |= ALLOW_OCTAL | ALLOW_BINARY;
6191   }
6192
6193   return *isolate->factory()->NewNumber(StringToDouble(
6194       isolate->unicode_cache(), *subject, flags));
6195 }
6196
6197
6198 RUNTIME_FUNCTION(Runtime_NewString) {
6199   HandleScope scope(isolate);
6200   DCHECK(args.length() == 2);
6201   CONVERT_SMI_ARG_CHECKED(length, 0);
6202   CONVERT_BOOLEAN_ARG_CHECKED(is_one_byte, 1);
6203   if (length == 0) return isolate->heap()->empty_string();
6204   Handle<String> result;
6205   if (is_one_byte) {
6206     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
6207         isolate, result, isolate->factory()->NewRawOneByteString(length));
6208   } else {
6209     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
6210         isolate, result, isolate->factory()->NewRawTwoByteString(length));
6211   }
6212   return *result;
6213 }
6214
6215
6216 RUNTIME_FUNCTION(Runtime_TruncateString) {
6217   HandleScope scope(isolate);
6218   DCHECK(args.length() == 2);
6219   CONVERT_ARG_HANDLE_CHECKED(SeqString, string, 0);
6220   CONVERT_SMI_ARG_CHECKED(new_length, 1);
6221   RUNTIME_ASSERT(new_length >= 0);
6222   return *SeqString::Truncate(string, new_length);
6223 }
6224
6225
6226 RUNTIME_FUNCTION(Runtime_URIEscape) {
6227   HandleScope scope(isolate);
6228   DCHECK(args.length() == 1);
6229   CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
6230   Handle<String> string = String::Flatten(source);
6231   DCHECK(string->IsFlat());
6232   Handle<String> result;
6233   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
6234       isolate, result,
6235       string->IsOneByteRepresentationUnderneath()
6236             ? URIEscape::Escape<uint8_t>(isolate, source)
6237             : URIEscape::Escape<uc16>(isolate, source));
6238   return *result;
6239 }
6240
6241
6242 RUNTIME_FUNCTION(Runtime_URIUnescape) {
6243   HandleScope scope(isolate);
6244   DCHECK(args.length() == 1);
6245   CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
6246   Handle<String> string = String::Flatten(source);
6247   DCHECK(string->IsFlat());
6248   Handle<String> result;
6249   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
6250       isolate, result,
6251       string->IsOneByteRepresentationUnderneath()
6252             ? URIUnescape::Unescape<uint8_t>(isolate, source)
6253             : URIUnescape::Unescape<uc16>(isolate, source));
6254   return *result;
6255 }
6256
6257
6258 RUNTIME_FUNCTION(Runtime_QuoteJSONString) {
6259   HandleScope scope(isolate);
6260   CONVERT_ARG_HANDLE_CHECKED(String, string, 0);
6261   DCHECK(args.length() == 1);
6262   Handle<Object> result;
6263   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
6264       isolate, result, BasicJsonStringifier::StringifyString(isolate, string));
6265   return *result;
6266 }
6267
6268
6269 RUNTIME_FUNCTION(Runtime_BasicJSONStringify) {
6270   HandleScope scope(isolate);
6271   DCHECK(args.length() == 1);
6272   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
6273   BasicJsonStringifier stringifier(isolate);
6274   Handle<Object> result;
6275   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
6276       isolate, result, stringifier.Stringify(object));
6277   return *result;
6278 }
6279
6280
6281 RUNTIME_FUNCTION(Runtime_StringParseInt) {
6282   HandleScope handle_scope(isolate);
6283   DCHECK(args.length() == 2);
6284   CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
6285   CONVERT_NUMBER_CHECKED(int, radix, Int32, args[1]);
6286   RUNTIME_ASSERT(radix == 0 || (2 <= radix && radix <= 36));
6287
6288   subject = String::Flatten(subject);
6289   double value;
6290
6291   { DisallowHeapAllocation no_gc;
6292     String::FlatContent flat = subject->GetFlatContent();
6293
6294     // ECMA-262 section 15.1.2.3, empty string is NaN
6295     if (flat.IsAscii()) {
6296       value = StringToInt(
6297           isolate->unicode_cache(), flat.ToOneByteVector(), radix);
6298     } else {
6299       value = StringToInt(
6300           isolate->unicode_cache(), flat.ToUC16Vector(), radix);
6301     }
6302   }
6303
6304   return *isolate->factory()->NewNumber(value);
6305 }
6306
6307
6308 RUNTIME_FUNCTION(Runtime_StringParseFloat) {
6309   HandleScope shs(isolate);
6310   DCHECK(args.length() == 1);
6311   CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
6312
6313   subject = String::Flatten(subject);
6314   double value = StringToDouble(isolate->unicode_cache(), *subject,
6315                                 ALLOW_TRAILING_JUNK, base::OS::nan_value());
6316
6317   return *isolate->factory()->NewNumber(value);
6318 }
6319
6320
6321 static inline bool ToUpperOverflows(uc32 character) {
6322   // y with umlauts and the micro sign are the only characters that stop
6323   // fitting into one-byte when converting to uppercase.
6324   static const uc32 yuml_code = 0xff;
6325   static const uc32 micro_code = 0xb5;
6326   return (character == yuml_code || character == micro_code);
6327 }
6328
6329
6330 template <class Converter>
6331 MUST_USE_RESULT static Object* ConvertCaseHelper(
6332     Isolate* isolate,
6333     String* string,
6334     SeqString* result,
6335     int result_length,
6336     unibrow::Mapping<Converter, 128>* mapping) {
6337   DisallowHeapAllocation no_gc;
6338   // We try this twice, once with the assumption that the result is no longer
6339   // than the input and, if that assumption breaks, again with the exact
6340   // length.  This may not be pretty, but it is nicer than what was here before
6341   // and I hereby claim my vaffel-is.
6342   //
6343   // NOTE: This assumes that the upper/lower case of an ASCII
6344   // character is also ASCII.  This is currently the case, but it
6345   // might break in the future if we implement more context and locale
6346   // dependent upper/lower conversions.
6347   bool has_changed_character = false;
6348
6349   // Convert all characters to upper case, assuming that they will fit
6350   // in the buffer
6351   Access<ConsStringIteratorOp> op(
6352       isolate->runtime_state()->string_iterator());
6353   StringCharacterStream stream(string, op.value());
6354   unibrow::uchar chars[Converter::kMaxWidth];
6355   // We can assume that the string is not empty
6356   uc32 current = stream.GetNext();
6357   bool ignore_overflow = Converter::kIsToLower || result->IsSeqTwoByteString();
6358   for (int i = 0; i < result_length;) {
6359     bool has_next = stream.HasMore();
6360     uc32 next = has_next ? stream.GetNext() : 0;
6361     int char_length = mapping->get(current, next, chars);
6362     if (char_length == 0) {
6363       // The case conversion of this character is the character itself.
6364       result->Set(i, current);
6365       i++;
6366     } else if (char_length == 1 &&
6367                (ignore_overflow || !ToUpperOverflows(current))) {
6368       // Common case: converting the letter resulted in one character.
6369       DCHECK(static_cast<uc32>(chars[0]) != current);
6370       result->Set(i, chars[0]);
6371       has_changed_character = true;
6372       i++;
6373     } else if (result_length == string->length()) {
6374       bool overflows = ToUpperOverflows(current);
6375       // We've assumed that the result would be as long as the
6376       // input but here is a character that converts to several
6377       // characters.  No matter, we calculate the exact length
6378       // of the result and try the whole thing again.
6379       //
6380       // Note that this leaves room for optimization.  We could just
6381       // memcpy what we already have to the result string.  Also,
6382       // the result string is the last object allocated we could
6383       // "realloc" it and probably, in the vast majority of cases,
6384       // extend the existing string to be able to hold the full
6385       // result.
6386       int next_length = 0;
6387       if (has_next) {
6388         next_length = mapping->get(next, 0, chars);
6389         if (next_length == 0) next_length = 1;
6390       }
6391       int current_length = i + char_length + next_length;
6392       while (stream.HasMore()) {
6393         current = stream.GetNext();
6394         overflows |= ToUpperOverflows(current);
6395         // NOTE: we use 0 as the next character here because, while
6396         // the next character may affect what a character converts to,
6397         // it does not in any case affect the length of what it convert
6398         // to.
6399         int char_length = mapping->get(current, 0, chars);
6400         if (char_length == 0) char_length = 1;
6401         current_length += char_length;
6402         if (current_length > String::kMaxLength) {
6403           AllowHeapAllocation allocate_error_and_return;
6404           return isolate->ThrowInvalidStringLength();
6405         }
6406       }
6407       // Try again with the real length.  Return signed if we need
6408       // to allocate a two-byte string for to uppercase.
6409       return (overflows && !ignore_overflow) ? Smi::FromInt(-current_length)
6410                                              : Smi::FromInt(current_length);
6411     } else {
6412       for (int j = 0; j < char_length; j++) {
6413         result->Set(i, chars[j]);
6414         i++;
6415       }
6416       has_changed_character = true;
6417     }
6418     current = next;
6419   }
6420   if (has_changed_character) {
6421     return result;
6422   } else {
6423     // If we didn't actually change anything in doing the conversion
6424     // we simple return the result and let the converted string
6425     // become garbage; there is no reason to keep two identical strings
6426     // alive.
6427     return string;
6428   }
6429 }
6430
6431
6432 namespace {
6433
6434 static const uintptr_t kOneInEveryByte = kUintptrAllBitsSet / 0xFF;
6435 static const uintptr_t kAsciiMask = kOneInEveryByte << 7;
6436
6437 // Given a word and two range boundaries returns a word with high bit
6438 // set in every byte iff the corresponding input byte was strictly in
6439 // the range (m, n). All the other bits in the result are cleared.
6440 // This function is only useful when it can be inlined and the
6441 // boundaries are statically known.
6442 // Requires: all bytes in the input word and the boundaries must be
6443 // ASCII (less than 0x7F).
6444 static inline uintptr_t AsciiRangeMask(uintptr_t w, char m, char n) {
6445   // Use strict inequalities since in edge cases the function could be
6446   // further simplified.
6447   DCHECK(0 < m && m < n);
6448   // Has high bit set in every w byte less than n.
6449   uintptr_t tmp1 = kOneInEveryByte * (0x7F + n) - w;
6450   // Has high bit set in every w byte greater than m.
6451   uintptr_t tmp2 = w + kOneInEveryByte * (0x7F - m);
6452   return (tmp1 & tmp2 & (kOneInEveryByte * 0x80));
6453 }
6454
6455
6456 #ifdef DEBUG
6457 static bool CheckFastAsciiConvert(char* dst,
6458                                   const char* src,
6459                                   int length,
6460                                   bool changed,
6461                                   bool is_to_lower) {
6462   bool expected_changed = false;
6463   for (int i = 0; i < length; i++) {
6464     if (dst[i] == src[i]) continue;
6465     expected_changed = true;
6466     if (is_to_lower) {
6467       DCHECK('A' <= src[i] && src[i] <= 'Z');
6468       DCHECK(dst[i] == src[i] + ('a' - 'A'));
6469     } else {
6470       DCHECK('a' <= src[i] && src[i] <= 'z');
6471       DCHECK(dst[i] == src[i] - ('a' - 'A'));
6472     }
6473   }
6474   return (expected_changed == changed);
6475 }
6476 #endif
6477
6478
6479 template<class Converter>
6480 static bool FastAsciiConvert(char* dst,
6481                              const char* src,
6482                              int length,
6483                              bool* changed_out) {
6484 #ifdef DEBUG
6485     char* saved_dst = dst;
6486     const char* saved_src = src;
6487 #endif
6488   DisallowHeapAllocation no_gc;
6489   // We rely on the distance between upper and lower case letters
6490   // being a known power of 2.
6491   DCHECK('a' - 'A' == (1 << 5));
6492   // Boundaries for the range of input characters than require conversion.
6493   static const char lo = Converter::kIsToLower ? 'A' - 1 : 'a' - 1;
6494   static const char hi = Converter::kIsToLower ? 'Z' + 1 : 'z' + 1;
6495   bool changed = false;
6496   uintptr_t or_acc = 0;
6497   const char* const limit = src + length;
6498 #ifdef V8_HOST_CAN_READ_UNALIGNED
6499   // Process the prefix of the input that requires no conversion one
6500   // (machine) word at a time.
6501   while (src <= limit - sizeof(uintptr_t)) {
6502     const uintptr_t w = *reinterpret_cast<const uintptr_t*>(src);
6503     or_acc |= w;
6504     if (AsciiRangeMask(w, lo, hi) != 0) {
6505       changed = true;
6506       break;
6507     }
6508     *reinterpret_cast<uintptr_t*>(dst) = w;
6509     src += sizeof(uintptr_t);
6510     dst += sizeof(uintptr_t);
6511   }
6512   // Process the remainder of the input performing conversion when
6513   // required one word at a time.
6514   while (src <= limit - sizeof(uintptr_t)) {
6515     const uintptr_t w = *reinterpret_cast<const uintptr_t*>(src);
6516     or_acc |= w;
6517     uintptr_t m = AsciiRangeMask(w, lo, hi);
6518     // The mask has high (7th) bit set in every byte that needs
6519     // conversion and we know that the distance between cases is
6520     // 1 << 5.
6521     *reinterpret_cast<uintptr_t*>(dst) = w ^ (m >> 2);
6522     src += sizeof(uintptr_t);
6523     dst += sizeof(uintptr_t);
6524   }
6525 #endif
6526   // Process the last few bytes of the input (or the whole input if
6527   // unaligned access is not supported).
6528   while (src < limit) {
6529     char c = *src;
6530     or_acc |= c;
6531     if (lo < c && c < hi) {
6532       c ^= (1 << 5);
6533       changed = true;
6534     }
6535     *dst = c;
6536     ++src;
6537     ++dst;
6538   }
6539   if ((or_acc & kAsciiMask) != 0) {
6540     return false;
6541   }
6542
6543   DCHECK(CheckFastAsciiConvert(
6544              saved_dst, saved_src, length, changed, Converter::kIsToLower));
6545
6546   *changed_out = changed;
6547   return true;
6548 }
6549
6550 }  // namespace
6551
6552
6553 template <class Converter>
6554 MUST_USE_RESULT static Object* ConvertCase(
6555     Handle<String> s,
6556     Isolate* isolate,
6557     unibrow::Mapping<Converter, 128>* mapping) {
6558   s = String::Flatten(s);
6559   int length = s->length();
6560   // Assume that the string is not empty; we need this assumption later
6561   if (length == 0) return *s;
6562
6563   // Simpler handling of ASCII strings.
6564   //
6565   // NOTE: This assumes that the upper/lower case of an ASCII
6566   // character is also ASCII.  This is currently the case, but it
6567   // might break in the future if we implement more context and locale
6568   // dependent upper/lower conversions.
6569   if (s->IsOneByteRepresentationUnderneath()) {
6570     // Same length as input.
6571     Handle<SeqOneByteString> result =
6572         isolate->factory()->NewRawOneByteString(length).ToHandleChecked();
6573     DisallowHeapAllocation no_gc;
6574     String::FlatContent flat_content = s->GetFlatContent();
6575     DCHECK(flat_content.IsFlat());
6576     bool has_changed_character = false;
6577     bool is_ascii = FastAsciiConvert<Converter>(
6578         reinterpret_cast<char*>(result->GetChars()),
6579         reinterpret_cast<const char*>(flat_content.ToOneByteVector().start()),
6580         length,
6581         &has_changed_character);
6582     // If not ASCII, we discard the result and take the 2 byte path.
6583     if (is_ascii) return has_changed_character ? *result : *s;
6584   }
6585
6586   Handle<SeqString> result;  // Same length as input.
6587   if (s->IsOneByteRepresentation()) {
6588     result = isolate->factory()->NewRawOneByteString(length).ToHandleChecked();
6589   } else {
6590     result = isolate->factory()->NewRawTwoByteString(length).ToHandleChecked();
6591   }
6592
6593   Object* answer = ConvertCaseHelper(isolate, *s, *result, length, mapping);
6594   if (answer->IsException() || answer->IsString()) return answer;
6595
6596   DCHECK(answer->IsSmi());
6597   length = Smi::cast(answer)->value();
6598   if (s->IsOneByteRepresentation() && length > 0) {
6599     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
6600         isolate, result, isolate->factory()->NewRawOneByteString(length));
6601   } else {
6602     if (length < 0) length = -length;
6603     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
6604         isolate, result, isolate->factory()->NewRawTwoByteString(length));
6605   }
6606   return ConvertCaseHelper(isolate, *s, *result, length, mapping);
6607 }
6608
6609
6610 RUNTIME_FUNCTION(Runtime_StringToLowerCase) {
6611   HandleScope scope(isolate);
6612   DCHECK(args.length() == 1);
6613   CONVERT_ARG_HANDLE_CHECKED(String, s, 0);
6614   return ConvertCase(
6615       s, isolate, isolate->runtime_state()->to_lower_mapping());
6616 }
6617
6618
6619 RUNTIME_FUNCTION(Runtime_StringToUpperCase) {
6620   HandleScope scope(isolate);
6621   DCHECK(args.length() == 1);
6622   CONVERT_ARG_HANDLE_CHECKED(String, s, 0);
6623   return ConvertCase(
6624       s, isolate, isolate->runtime_state()->to_upper_mapping());
6625 }
6626
6627
6628 RUNTIME_FUNCTION(Runtime_StringTrim) {
6629   HandleScope scope(isolate);
6630   DCHECK(args.length() == 3);
6631
6632   CONVERT_ARG_HANDLE_CHECKED(String, string, 0);
6633   CONVERT_BOOLEAN_ARG_CHECKED(trimLeft, 1);
6634   CONVERT_BOOLEAN_ARG_CHECKED(trimRight, 2);
6635
6636   string = String::Flatten(string);
6637   int length = string->length();
6638
6639   int left = 0;
6640   UnicodeCache* unicode_cache = isolate->unicode_cache();
6641   if (trimLeft) {
6642     while (left < length &&
6643            unicode_cache->IsWhiteSpaceOrLineTerminator(string->Get(left))) {
6644       left++;
6645     }
6646   }
6647
6648   int right = length;
6649   if (trimRight) {
6650     while (right > left &&
6651            unicode_cache->IsWhiteSpaceOrLineTerminator(
6652                string->Get(right - 1))) {
6653       right--;
6654     }
6655   }
6656
6657   return *isolate->factory()->NewSubString(string, left, right);
6658 }
6659
6660
6661 RUNTIME_FUNCTION(Runtime_StringSplit) {
6662   HandleScope handle_scope(isolate);
6663   DCHECK(args.length() == 3);
6664   CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
6665   CONVERT_ARG_HANDLE_CHECKED(String, pattern, 1);
6666   CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[2]);
6667   RUNTIME_ASSERT(limit > 0);
6668
6669   int subject_length = subject->length();
6670   int pattern_length = pattern->length();
6671   RUNTIME_ASSERT(pattern_length > 0);
6672
6673   if (limit == 0xffffffffu) {
6674     Handle<Object> cached_answer(
6675         RegExpResultsCache::Lookup(isolate->heap(),
6676                                    *subject,
6677                                    *pattern,
6678                                    RegExpResultsCache::STRING_SPLIT_SUBSTRINGS),
6679         isolate);
6680     if (*cached_answer != Smi::FromInt(0)) {
6681       // The cache FixedArray is a COW-array and can therefore be reused.
6682       Handle<JSArray> result =
6683           isolate->factory()->NewJSArrayWithElements(
6684               Handle<FixedArray>::cast(cached_answer));
6685       return *result;
6686     }
6687   }
6688
6689   // The limit can be very large (0xffffffffu), but since the pattern
6690   // isn't empty, we can never create more parts than ~half the length
6691   // of the subject.
6692
6693   subject = String::Flatten(subject);
6694   pattern = String::Flatten(pattern);
6695
6696   static const int kMaxInitialListCapacity = 16;
6697
6698   ZoneScope zone_scope(isolate->runtime_zone());
6699
6700   // Find (up to limit) indices of separator and end-of-string in subject
6701   int initial_capacity = Min<uint32_t>(kMaxInitialListCapacity, limit);
6702   ZoneList<int> indices(initial_capacity, zone_scope.zone());
6703
6704   FindStringIndicesDispatch(isolate, *subject, *pattern,
6705                             &indices, limit, zone_scope.zone());
6706
6707   if (static_cast<uint32_t>(indices.length()) < limit) {
6708     indices.Add(subject_length, zone_scope.zone());
6709   }
6710
6711   // The list indices now contains the end of each part to create.
6712
6713   // Create JSArray of substrings separated by separator.
6714   int part_count = indices.length();
6715
6716   Handle<JSArray> result = isolate->factory()->NewJSArray(part_count);
6717   JSObject::EnsureCanContainHeapObjectElements(result);
6718   result->set_length(Smi::FromInt(part_count));
6719
6720   DCHECK(result->HasFastObjectElements());
6721
6722   if (part_count == 1 && indices.at(0) == subject_length) {
6723     FixedArray::cast(result->elements())->set(0, *subject);
6724     return *result;
6725   }
6726
6727   Handle<FixedArray> elements(FixedArray::cast(result->elements()));
6728   int part_start = 0;
6729   for (int i = 0; i < part_count; i++) {
6730     HandleScope local_loop_handle(isolate);
6731     int part_end = indices.at(i);
6732     Handle<String> substring =
6733         isolate->factory()->NewProperSubString(subject, part_start, part_end);
6734     elements->set(i, *substring);
6735     part_start = part_end + pattern_length;
6736   }
6737
6738   if (limit == 0xffffffffu) {
6739     if (result->HasFastObjectElements()) {
6740       RegExpResultsCache::Enter(isolate,
6741                                 subject,
6742                                 pattern,
6743                                 elements,
6744                                 RegExpResultsCache::STRING_SPLIT_SUBSTRINGS);
6745     }
6746   }
6747
6748   return *result;
6749 }
6750
6751
6752 // Copies ASCII characters to the given fixed array looking up
6753 // one-char strings in the cache. Gives up on the first char that is
6754 // not in the cache and fills the remainder with smi zeros. Returns
6755 // the length of the successfully copied prefix.
6756 static int CopyCachedAsciiCharsToArray(Heap* heap,
6757                                        const uint8_t* chars,
6758                                        FixedArray* elements,
6759                                        int length) {
6760   DisallowHeapAllocation no_gc;
6761   FixedArray* ascii_cache = heap->single_character_string_cache();
6762   Object* undefined = heap->undefined_value();
6763   int i;
6764   WriteBarrierMode mode = elements->GetWriteBarrierMode(no_gc);
6765   for (i = 0; i < length; ++i) {
6766     Object* value = ascii_cache->get(chars[i]);
6767     if (value == undefined) break;
6768     elements->set(i, value, mode);
6769   }
6770   if (i < length) {
6771     DCHECK(Smi::FromInt(0) == 0);
6772     memset(elements->data_start() + i, 0, kPointerSize * (length - i));
6773   }
6774 #ifdef DEBUG
6775   for (int j = 0; j < length; ++j) {
6776     Object* element = elements->get(j);
6777     DCHECK(element == Smi::FromInt(0) ||
6778            (element->IsString() && String::cast(element)->LooksValid()));
6779   }
6780 #endif
6781   return i;
6782 }
6783
6784
6785 // Converts a String to JSArray.
6786 // For example, "foo" => ["f", "o", "o"].
6787 RUNTIME_FUNCTION(Runtime_StringToArray) {
6788   HandleScope scope(isolate);
6789   DCHECK(args.length() == 2);
6790   CONVERT_ARG_HANDLE_CHECKED(String, s, 0);
6791   CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]);
6792
6793   s = String::Flatten(s);
6794   const int length = static_cast<int>(Min<uint32_t>(s->length(), limit));
6795
6796   Handle<FixedArray> elements;
6797   int position = 0;
6798   if (s->IsFlat() && s->IsOneByteRepresentation()) {
6799     // Try using cached chars where possible.
6800     elements = isolate->factory()->NewUninitializedFixedArray(length);
6801
6802     DisallowHeapAllocation no_gc;
6803     String::FlatContent content = s->GetFlatContent();
6804     if (content.IsAscii()) {
6805       Vector<const uint8_t> chars = content.ToOneByteVector();
6806       // Note, this will initialize all elements (not only the prefix)
6807       // to prevent GC from seeing partially initialized array.
6808       position = CopyCachedAsciiCharsToArray(isolate->heap(),
6809                                              chars.start(),
6810                                              *elements,
6811                                              length);
6812     } else {
6813       MemsetPointer(elements->data_start(),
6814                     isolate->heap()->undefined_value(),
6815                     length);
6816     }
6817   } else {
6818     elements = isolate->factory()->NewFixedArray(length);
6819   }
6820   for (int i = position; i < length; ++i) {
6821     Handle<Object> str =
6822         isolate->factory()->LookupSingleCharacterStringFromCode(s->Get(i));
6823     elements->set(i, *str);
6824   }
6825
6826 #ifdef DEBUG
6827   for (int i = 0; i < length; ++i) {
6828     DCHECK(String::cast(elements->get(i))->length() == 1);
6829   }
6830 #endif
6831
6832   return *isolate->factory()->NewJSArrayWithElements(elements);
6833 }
6834
6835
6836 RUNTIME_FUNCTION(Runtime_NewStringWrapper) {
6837   HandleScope scope(isolate);
6838   DCHECK(args.length() == 1);
6839   CONVERT_ARG_HANDLE_CHECKED(String, value, 0);
6840   return *Object::ToObject(isolate, value).ToHandleChecked();
6841 }
6842
6843
6844 bool Runtime::IsUpperCaseChar(RuntimeState* runtime_state, uint16_t ch) {
6845   unibrow::uchar chars[unibrow::ToUppercase::kMaxWidth];
6846   int char_length = runtime_state->to_upper_mapping()->get(ch, 0, chars);
6847   return char_length == 0;
6848 }
6849
6850
6851 RUNTIME_FUNCTION(Runtime_NumberToStringRT) {
6852   HandleScope scope(isolate);
6853   DCHECK(args.length() == 1);
6854   CONVERT_NUMBER_ARG_HANDLE_CHECKED(number, 0);
6855
6856   return *isolate->factory()->NumberToString(number);
6857 }
6858
6859
6860 RUNTIME_FUNCTION(Runtime_NumberToStringSkipCache) {
6861   HandleScope scope(isolate);
6862   DCHECK(args.length() == 1);
6863   CONVERT_NUMBER_ARG_HANDLE_CHECKED(number, 0);
6864
6865   return *isolate->factory()->NumberToString(number, false);
6866 }
6867
6868
6869 RUNTIME_FUNCTION(Runtime_NumberToInteger) {
6870   HandleScope scope(isolate);
6871   DCHECK(args.length() == 1);
6872
6873   CONVERT_DOUBLE_ARG_CHECKED(number, 0);
6874   return *isolate->factory()->NewNumber(DoubleToInteger(number));
6875 }
6876
6877
6878 RUNTIME_FUNCTION(Runtime_NumberToIntegerMapMinusZero) {
6879   HandleScope scope(isolate);
6880   DCHECK(args.length() == 1);
6881
6882   CONVERT_DOUBLE_ARG_CHECKED(number, 0);
6883   double double_value = DoubleToInteger(number);
6884   // Map both -0 and +0 to +0.
6885   if (double_value == 0) double_value = 0;
6886
6887   return *isolate->factory()->NewNumber(double_value);
6888 }
6889
6890
6891 RUNTIME_FUNCTION(Runtime_NumberToJSUint32) {
6892   HandleScope scope(isolate);
6893   DCHECK(args.length() == 1);
6894
6895   CONVERT_NUMBER_CHECKED(int32_t, number, Uint32, args[0]);
6896   return *isolate->factory()->NewNumberFromUint(number);
6897 }
6898
6899
6900 RUNTIME_FUNCTION(Runtime_NumberToJSInt32) {
6901   HandleScope scope(isolate);
6902   DCHECK(args.length() == 1);
6903
6904   CONVERT_DOUBLE_ARG_CHECKED(number, 0);
6905   return *isolate->factory()->NewNumberFromInt(DoubleToInt32(number));
6906 }
6907
6908
6909 // Converts a Number to a Smi, if possible. Returns NaN if the number is not
6910 // a small integer.
6911 RUNTIME_FUNCTION(Runtime_NumberToSmi) {
6912   SealHandleScope shs(isolate);
6913   DCHECK(args.length() == 1);
6914   CONVERT_ARG_CHECKED(Object, obj, 0);
6915   if (obj->IsSmi()) {
6916     return obj;
6917   }
6918   if (obj->IsHeapNumber()) {
6919     double value = HeapNumber::cast(obj)->value();
6920     int int_value = FastD2I(value);
6921     if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
6922       return Smi::FromInt(int_value);
6923     }
6924   }
6925   return isolate->heap()->nan_value();
6926 }
6927
6928
6929 RUNTIME_FUNCTION(Runtime_AllocateHeapNumber) {
6930   HandleScope scope(isolate);
6931   DCHECK(args.length() == 0);
6932   return *isolate->factory()->NewHeapNumber(0);
6933 }
6934
6935
6936 RUNTIME_FUNCTION(Runtime_AllocateFloat32x4) {
6937   HandleScope scope(isolate);
6938   DCHECK(args.length() == 0);
6939
6940   float32x4_value_t zero = {{0, 0, 0, 0}};
6941   return *isolate->factory()->NewFloat32x4(zero);
6942 }
6943
6944
6945 RUNTIME_FUNCTION(Runtime_AllocateFloat64x2) {
6946   HandleScope scope(isolate);
6947   DCHECK(args.length() == 0);
6948
6949   float64x2_value_t zero = {{0, 0}};
6950   return *isolate->factory()->NewFloat64x2(zero);
6951 }
6952
6953
6954 RUNTIME_FUNCTION(Runtime_AllocateInt32x4) {
6955   HandleScope scope(isolate);
6956   DCHECK(args.length() == 0);
6957
6958   int32x4_value_t zero = {{0, 0, 0, 0}};
6959   return *isolate->factory()->NewInt32x4(zero);
6960 }
6961
6962
6963 RUNTIME_FUNCTION(Runtime_NumberAdd) {
6964   HandleScope scope(isolate);
6965   DCHECK(args.length() == 2);
6966
6967   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
6968   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
6969   return *isolate->factory()->NewNumber(x + y);
6970 }
6971
6972
6973 RUNTIME_FUNCTION(Runtime_NumberSub) {
6974   HandleScope scope(isolate);
6975   DCHECK(args.length() == 2);
6976
6977   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
6978   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
6979   return *isolate->factory()->NewNumber(x - y);
6980 }
6981
6982
6983 RUNTIME_FUNCTION(Runtime_NumberMul) {
6984   HandleScope scope(isolate);
6985   DCHECK(args.length() == 2);
6986
6987   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
6988   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
6989   return *isolate->factory()->NewNumber(x * y);
6990 }
6991
6992
6993 RUNTIME_FUNCTION(Runtime_NumberUnaryMinus) {
6994   HandleScope scope(isolate);
6995   DCHECK(args.length() == 1);
6996
6997   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
6998   return *isolate->factory()->NewNumber(-x);
6999 }
7000
7001
7002 RUNTIME_FUNCTION(Runtime_NumberDiv) {
7003   HandleScope scope(isolate);
7004   DCHECK(args.length() == 2);
7005
7006   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7007   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
7008   return *isolate->factory()->NewNumber(x / y);
7009 }
7010
7011
7012 RUNTIME_FUNCTION(Runtime_NumberMod) {
7013   HandleScope scope(isolate);
7014   DCHECK(args.length() == 2);
7015
7016   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7017   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
7018   return *isolate->factory()->NewNumber(modulo(x, y));
7019 }
7020
7021
7022 RUNTIME_FUNCTION(Runtime_NumberImul) {
7023   HandleScope scope(isolate);
7024   DCHECK(args.length() == 2);
7025
7026   // We rely on implementation-defined behavior below, but at least not on
7027   // undefined behavior.
7028   CONVERT_NUMBER_CHECKED(uint32_t, x, Int32, args[0]);
7029   CONVERT_NUMBER_CHECKED(uint32_t, y, Int32, args[1]);
7030   int32_t product = static_cast<int32_t>(x * y);
7031   return *isolate->factory()->NewNumberFromInt(product);
7032 }
7033
7034
7035 RUNTIME_FUNCTION(Runtime_StringAdd) {
7036   HandleScope scope(isolate);
7037   DCHECK(args.length() == 2);
7038   CONVERT_ARG_HANDLE_CHECKED(String, str1, 0);
7039   CONVERT_ARG_HANDLE_CHECKED(String, str2, 1);
7040   isolate->counters()->string_add_runtime()->Increment();
7041   Handle<String> result;
7042   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
7043       isolate, result, isolate->factory()->NewConsString(str1, str2));
7044   return *result;
7045 }
7046
7047
7048 template <typename sinkchar>
7049 static inline void StringBuilderConcatHelper(String* special,
7050                                              sinkchar* sink,
7051                                              FixedArray* fixed_array,
7052                                              int array_length) {
7053   DisallowHeapAllocation no_gc;
7054   int position = 0;
7055   for (int i = 0; i < array_length; i++) {
7056     Object* element = fixed_array->get(i);
7057     if (element->IsSmi()) {
7058       // Smi encoding of position and length.
7059       int encoded_slice = Smi::cast(element)->value();
7060       int pos;
7061       int len;
7062       if (encoded_slice > 0) {
7063         // Position and length encoded in one smi.
7064         pos = StringBuilderSubstringPosition::decode(encoded_slice);
7065         len = StringBuilderSubstringLength::decode(encoded_slice);
7066       } else {
7067         // Position and length encoded in two smis.
7068         Object* obj = fixed_array->get(++i);
7069         DCHECK(obj->IsSmi());
7070         pos = Smi::cast(obj)->value();
7071         len = -encoded_slice;
7072       }
7073       String::WriteToFlat(special,
7074                           sink + position,
7075                           pos,
7076                           pos + len);
7077       position += len;
7078     } else {
7079       String* string = String::cast(element);
7080       int element_length = string->length();
7081       String::WriteToFlat(string, sink + position, 0, element_length);
7082       position += element_length;
7083     }
7084   }
7085 }
7086
7087
7088 // Returns the result length of the concatenation.
7089 // On illegal argument, -1 is returned.
7090 static inline int StringBuilderConcatLength(int special_length,
7091                                             FixedArray* fixed_array,
7092                                             int array_length,
7093                                             bool* one_byte) {
7094   DisallowHeapAllocation no_gc;
7095   int position = 0;
7096   for (int i = 0; i < array_length; i++) {
7097     int increment = 0;
7098     Object* elt = fixed_array->get(i);
7099     if (elt->IsSmi()) {
7100       // Smi encoding of position and length.
7101       int smi_value = Smi::cast(elt)->value();
7102       int pos;
7103       int len;
7104       if (smi_value > 0) {
7105         // Position and length encoded in one smi.
7106         pos = StringBuilderSubstringPosition::decode(smi_value);
7107         len = StringBuilderSubstringLength::decode(smi_value);
7108       } else {
7109         // Position and length encoded in two smis.
7110         len = -smi_value;
7111         // Get the position and check that it is a positive smi.
7112         i++;
7113         if (i >= array_length) return -1;
7114         Object* next_smi = fixed_array->get(i);
7115         if (!next_smi->IsSmi()) return -1;
7116         pos = Smi::cast(next_smi)->value();
7117         if (pos < 0) return -1;
7118       }
7119       DCHECK(pos >= 0);
7120       DCHECK(len >= 0);
7121       if (pos > special_length || len > special_length - pos) return -1;
7122       increment = len;
7123     } else if (elt->IsString()) {
7124       String* element = String::cast(elt);
7125       int element_length = element->length();
7126       increment = element_length;
7127       if (*one_byte && !element->HasOnlyOneByteChars()) {
7128         *one_byte = false;
7129       }
7130     } else {
7131       return -1;
7132     }
7133     if (increment > String::kMaxLength - position) {
7134       return kMaxInt;  // Provoke throw on allocation.
7135     }
7136     position += increment;
7137   }
7138   return position;
7139 }
7140
7141
7142 RUNTIME_FUNCTION(Runtime_StringBuilderConcat) {
7143   HandleScope scope(isolate);
7144   DCHECK(args.length() == 3);
7145   CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
7146   if (!args[1]->IsSmi()) return isolate->ThrowInvalidStringLength();
7147   CONVERT_SMI_ARG_CHECKED(array_length, 1);
7148   CONVERT_ARG_HANDLE_CHECKED(String, special, 2);
7149
7150   size_t actual_array_length = 0;
7151   RUNTIME_ASSERT(
7152       TryNumberToSize(isolate, array->length(), &actual_array_length));
7153   RUNTIME_ASSERT(array_length >= 0);
7154   RUNTIME_ASSERT(static_cast<size_t>(array_length) <= actual_array_length);
7155
7156   // This assumption is used by the slice encoding in one or two smis.
7157   DCHECK(Smi::kMaxValue >= String::kMaxLength);
7158
7159   RUNTIME_ASSERT(array->HasFastElements());
7160   JSObject::EnsureCanContainHeapObjectElements(array);
7161
7162   int special_length = special->length();
7163   if (!array->HasFastObjectElements()) {
7164     return isolate->Throw(isolate->heap()->illegal_argument_string());
7165   }
7166
7167   int length;
7168   bool one_byte = special->HasOnlyOneByteChars();
7169
7170   { DisallowHeapAllocation no_gc;
7171     FixedArray* fixed_array = FixedArray::cast(array->elements());
7172     if (fixed_array->length() < array_length) {
7173       array_length = fixed_array->length();
7174     }
7175
7176     if (array_length == 0) {
7177       return isolate->heap()->empty_string();
7178     } else if (array_length == 1) {
7179       Object* first = fixed_array->get(0);
7180       if (first->IsString()) return first;
7181     }
7182     length = StringBuilderConcatLength(
7183         special_length, fixed_array, array_length, &one_byte);
7184   }
7185
7186   if (length == -1) {
7187     return isolate->Throw(isolate->heap()->illegal_argument_string());
7188   }
7189
7190   if (one_byte) {
7191     Handle<SeqOneByteString> answer;
7192     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
7193         isolate, answer,
7194         isolate->factory()->NewRawOneByteString(length));
7195     StringBuilderConcatHelper(*special,
7196                               answer->GetChars(),
7197                               FixedArray::cast(array->elements()),
7198                               array_length);
7199     return *answer;
7200   } else {
7201     Handle<SeqTwoByteString> answer;
7202     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
7203         isolate, answer,
7204         isolate->factory()->NewRawTwoByteString(length));
7205     StringBuilderConcatHelper(*special,
7206                               answer->GetChars(),
7207                               FixedArray::cast(array->elements()),
7208                               array_length);
7209     return *answer;
7210   }
7211 }
7212
7213
7214 RUNTIME_FUNCTION(Runtime_StringBuilderJoin) {
7215   HandleScope scope(isolate);
7216   DCHECK(args.length() == 3);
7217   CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
7218   if (!args[1]->IsSmi()) return isolate->ThrowInvalidStringLength();
7219   CONVERT_SMI_ARG_CHECKED(array_length, 1);
7220   CONVERT_ARG_HANDLE_CHECKED(String, separator, 2);
7221   RUNTIME_ASSERT(array->HasFastObjectElements());
7222   RUNTIME_ASSERT(array_length >= 0);
7223
7224   Handle<FixedArray> fixed_array(FixedArray::cast(array->elements()));
7225   if (fixed_array->length() < array_length) {
7226     array_length = fixed_array->length();
7227   }
7228
7229   if (array_length == 0) {
7230     return isolate->heap()->empty_string();
7231   } else if (array_length == 1) {
7232     Object* first = fixed_array->get(0);
7233     RUNTIME_ASSERT(first->IsString());
7234     return first;
7235   }
7236
7237   int separator_length = separator->length();
7238   RUNTIME_ASSERT(separator_length > 0);
7239   int max_nof_separators =
7240       (String::kMaxLength + separator_length - 1) / separator_length;
7241   if (max_nof_separators < (array_length - 1)) {
7242     return isolate->ThrowInvalidStringLength();
7243   }
7244   int length = (array_length - 1) * separator_length;
7245   for (int i = 0; i < array_length; i++) {
7246     Object* element_obj = fixed_array->get(i);
7247     RUNTIME_ASSERT(element_obj->IsString());
7248     String* element = String::cast(element_obj);
7249     int increment = element->length();
7250     if (increment > String::kMaxLength - length) {
7251       STATIC_ASSERT(String::kMaxLength < kMaxInt);
7252       length = kMaxInt;  // Provoke exception;
7253       break;
7254     }
7255     length += increment;
7256   }
7257
7258   Handle<SeqTwoByteString> answer;
7259   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
7260       isolate, answer,
7261       isolate->factory()->NewRawTwoByteString(length));
7262
7263   DisallowHeapAllocation no_gc;
7264
7265   uc16* sink = answer->GetChars();
7266 #ifdef DEBUG
7267   uc16* end = sink + length;
7268 #endif
7269
7270   RUNTIME_ASSERT(fixed_array->get(0)->IsString());
7271   String* first = String::cast(fixed_array->get(0));
7272   String* separator_raw = *separator;
7273   int first_length = first->length();
7274   String::WriteToFlat(first, sink, 0, first_length);
7275   sink += first_length;
7276
7277   for (int i = 1; i < array_length; i++) {
7278     DCHECK(sink + separator_length <= end);
7279     String::WriteToFlat(separator_raw, sink, 0, separator_length);
7280     sink += separator_length;
7281
7282     RUNTIME_ASSERT(fixed_array->get(i)->IsString());
7283     String* element = String::cast(fixed_array->get(i));
7284     int element_length = element->length();
7285     DCHECK(sink + element_length <= end);
7286     String::WriteToFlat(element, sink, 0, element_length);
7287     sink += element_length;
7288   }
7289   DCHECK(sink == end);
7290
7291   // Use %_FastAsciiArrayJoin instead.
7292   DCHECK(!answer->IsOneByteRepresentation());
7293   return *answer;
7294 }
7295
7296 template <typename Char>
7297 static void JoinSparseArrayWithSeparator(FixedArray* elements,
7298                                          int elements_length,
7299                                          uint32_t array_length,
7300                                          String* separator,
7301                                          Vector<Char> buffer) {
7302   DisallowHeapAllocation no_gc;
7303   int previous_separator_position = 0;
7304   int separator_length = separator->length();
7305   int cursor = 0;
7306   for (int i = 0; i < elements_length; i += 2) {
7307     int position = NumberToInt32(elements->get(i));
7308     String* string = String::cast(elements->get(i + 1));
7309     int string_length = string->length();
7310     if (string->length() > 0) {
7311       while (previous_separator_position < position) {
7312         String::WriteToFlat<Char>(separator, &buffer[cursor],
7313                                   0, separator_length);
7314         cursor += separator_length;
7315         previous_separator_position++;
7316       }
7317       String::WriteToFlat<Char>(string, &buffer[cursor],
7318                                 0, string_length);
7319       cursor += string->length();
7320     }
7321   }
7322   if (separator_length > 0) {
7323     // Array length must be representable as a signed 32-bit number,
7324     // otherwise the total string length would have been too large.
7325     DCHECK(array_length <= 0x7fffffff);  // Is int32_t.
7326     int last_array_index = static_cast<int>(array_length - 1);
7327     while (previous_separator_position < last_array_index) {
7328       String::WriteToFlat<Char>(separator, &buffer[cursor],
7329                                 0, separator_length);
7330       cursor += separator_length;
7331       previous_separator_position++;
7332     }
7333   }
7334   DCHECK(cursor <= buffer.length());
7335 }
7336
7337
7338 RUNTIME_FUNCTION(Runtime_SparseJoinWithSeparator) {
7339   HandleScope scope(isolate);
7340   DCHECK(args.length() == 3);
7341   CONVERT_ARG_HANDLE_CHECKED(JSArray, elements_array, 0);
7342   CONVERT_NUMBER_CHECKED(uint32_t, array_length, Uint32, args[1]);
7343   CONVERT_ARG_HANDLE_CHECKED(String, separator, 2);
7344   // elements_array is fast-mode JSarray of alternating positions
7345   // (increasing order) and strings.
7346   RUNTIME_ASSERT(elements_array->HasFastSmiOrObjectElements());
7347   // array_length is length of original array (used to add separators);
7348   // separator is string to put between elements. Assumed to be non-empty.
7349   RUNTIME_ASSERT(array_length > 0);
7350
7351   // Find total length of join result.
7352   int string_length = 0;
7353   bool is_ascii = separator->IsOneByteRepresentation();
7354   bool overflow = false;
7355   CONVERT_NUMBER_CHECKED(int, elements_length, Int32, elements_array->length());
7356   RUNTIME_ASSERT(elements_length <= elements_array->elements()->length());
7357   RUNTIME_ASSERT((elements_length & 1) == 0);  // Even length.
7358   FixedArray* elements = FixedArray::cast(elements_array->elements());
7359   for (int i = 0; i < elements_length; i += 2) {
7360     RUNTIME_ASSERT(elements->get(i)->IsNumber());
7361     CONVERT_NUMBER_CHECKED(uint32_t, position, Uint32, elements->get(i));
7362     RUNTIME_ASSERT(position < array_length);
7363     RUNTIME_ASSERT(elements->get(i + 1)->IsString());
7364   }
7365
7366   { DisallowHeapAllocation no_gc;
7367     for (int i = 0; i < elements_length; i += 2) {
7368       String* string = String::cast(elements->get(i + 1));
7369       int length = string->length();
7370       if (is_ascii && !string->IsOneByteRepresentation()) {
7371         is_ascii = false;
7372       }
7373       if (length > String::kMaxLength ||
7374           String::kMaxLength - length < string_length) {
7375         overflow = true;
7376         break;
7377       }
7378       string_length += length;
7379     }
7380   }
7381
7382   int separator_length = separator->length();
7383   if (!overflow && separator_length > 0) {
7384     if (array_length <= 0x7fffffffu) {
7385       int separator_count = static_cast<int>(array_length) - 1;
7386       int remaining_length = String::kMaxLength - string_length;
7387       if ((remaining_length / separator_length) >= separator_count) {
7388         string_length += separator_length * (array_length - 1);
7389       } else {
7390         // Not room for the separators within the maximal string length.
7391         overflow = true;
7392       }
7393     } else {
7394       // Nonempty separator and at least 2^31-1 separators necessary
7395       // means that the string is too large to create.
7396       STATIC_ASSERT(String::kMaxLength < 0x7fffffff);
7397       overflow = true;
7398     }
7399   }
7400   if (overflow) {
7401     // Throw an exception if the resulting string is too large. See
7402     // https://code.google.com/p/chromium/issues/detail?id=336820
7403     // for details.
7404     return isolate->ThrowInvalidStringLength();
7405   }
7406
7407   if (is_ascii) {
7408     Handle<SeqOneByteString> result = isolate->factory()->NewRawOneByteString(
7409         string_length).ToHandleChecked();
7410     JoinSparseArrayWithSeparator<uint8_t>(
7411         FixedArray::cast(elements_array->elements()),
7412         elements_length,
7413         array_length,
7414         *separator,
7415         Vector<uint8_t>(result->GetChars(), string_length));
7416     return *result;
7417   } else {
7418     Handle<SeqTwoByteString> result = isolate->factory()->NewRawTwoByteString(
7419         string_length).ToHandleChecked();
7420     JoinSparseArrayWithSeparator<uc16>(
7421         FixedArray::cast(elements_array->elements()),
7422         elements_length,
7423         array_length,
7424         *separator,
7425         Vector<uc16>(result->GetChars(), string_length));
7426     return *result;
7427   }
7428 }
7429
7430
7431 RUNTIME_FUNCTION(Runtime_NumberOr) {
7432   HandleScope scope(isolate);
7433   DCHECK(args.length() == 2);
7434
7435   CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
7436   CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
7437   return *isolate->factory()->NewNumberFromInt(x | y);
7438 }
7439
7440
7441 RUNTIME_FUNCTION(Runtime_NumberAnd) {
7442   HandleScope scope(isolate);
7443   DCHECK(args.length() == 2);
7444
7445   CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
7446   CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
7447   return *isolate->factory()->NewNumberFromInt(x & y);
7448 }
7449
7450
7451 RUNTIME_FUNCTION(Runtime_NumberXor) {
7452   HandleScope scope(isolate);
7453   DCHECK(args.length() == 2);
7454
7455   CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
7456   CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
7457   return *isolate->factory()->NewNumberFromInt(x ^ y);
7458 }
7459
7460
7461 RUNTIME_FUNCTION(Runtime_NumberShl) {
7462   HandleScope scope(isolate);
7463   DCHECK(args.length() == 2);
7464
7465   CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
7466   CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
7467   return *isolate->factory()->NewNumberFromInt(x << (y & 0x1f));
7468 }
7469
7470
7471 RUNTIME_FUNCTION(Runtime_NumberShr) {
7472   HandleScope scope(isolate);
7473   DCHECK(args.length() == 2);
7474
7475   CONVERT_NUMBER_CHECKED(uint32_t, x, Uint32, args[0]);
7476   CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
7477   return *isolate->factory()->NewNumberFromUint(x >> (y & 0x1f));
7478 }
7479
7480
7481 RUNTIME_FUNCTION(Runtime_NumberSar) {
7482   HandleScope scope(isolate);
7483   DCHECK(args.length() == 2);
7484
7485   CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
7486   CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
7487   return *isolate->factory()->NewNumberFromInt(
7488       ArithmeticShiftRight(x, y & 0x1f));
7489 }
7490
7491
7492 RUNTIME_FUNCTION(Runtime_NumberEquals) {
7493   SealHandleScope shs(isolate);
7494   DCHECK(args.length() == 2);
7495
7496   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7497   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
7498   if (std::isnan(x)) return Smi::FromInt(NOT_EQUAL);
7499   if (std::isnan(y)) return Smi::FromInt(NOT_EQUAL);
7500   if (x == y) return Smi::FromInt(EQUAL);
7501   Object* result;
7502   if ((fpclassify(x) == FP_ZERO) && (fpclassify(y) == FP_ZERO)) {
7503     result = Smi::FromInt(EQUAL);
7504   } else {
7505     result = Smi::FromInt(NOT_EQUAL);
7506   }
7507   return result;
7508 }
7509
7510
7511 RUNTIME_FUNCTION(Runtime_StringEquals) {
7512   HandleScope handle_scope(isolate);
7513   DCHECK(args.length() == 2);
7514
7515   CONVERT_ARG_HANDLE_CHECKED(String, x, 0);
7516   CONVERT_ARG_HANDLE_CHECKED(String, y, 1);
7517
7518   bool not_equal = !String::Equals(x, y);
7519   // This is slightly convoluted because the value that signifies
7520   // equality is 0 and inequality is 1 so we have to negate the result
7521   // from String::Equals.
7522   DCHECK(not_equal == 0 || not_equal == 1);
7523   STATIC_ASSERT(EQUAL == 0);
7524   STATIC_ASSERT(NOT_EQUAL == 1);
7525   return Smi::FromInt(not_equal);
7526 }
7527
7528
7529 RUNTIME_FUNCTION(Runtime_NumberCompare) {
7530   SealHandleScope shs(isolate);
7531   DCHECK(args.length() == 3);
7532
7533   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7534   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
7535   CONVERT_ARG_HANDLE_CHECKED(Object, uncomparable_result, 2)
7536   if (std::isnan(x) || std::isnan(y)) return *uncomparable_result;
7537   if (x == y) return Smi::FromInt(EQUAL);
7538   if (isless(x, y)) return Smi::FromInt(LESS);
7539   return Smi::FromInt(GREATER);
7540 }
7541
7542
7543 // Compare two Smis as if they were converted to strings and then
7544 // compared lexicographically.
7545 RUNTIME_FUNCTION(Runtime_SmiLexicographicCompare) {
7546   SealHandleScope shs(isolate);
7547   DCHECK(args.length() == 2);
7548   CONVERT_SMI_ARG_CHECKED(x_value, 0);
7549   CONVERT_SMI_ARG_CHECKED(y_value, 1);
7550
7551   // If the integers are equal so are the string representations.
7552   if (x_value == y_value) return Smi::FromInt(EQUAL);
7553
7554   // If one of the integers is zero the normal integer order is the
7555   // same as the lexicographic order of the string representations.
7556   if (x_value == 0 || y_value == 0)
7557     return Smi::FromInt(x_value < y_value ? LESS : GREATER);
7558
7559   // If only one of the integers is negative the negative number is
7560   // smallest because the char code of '-' is less than the char code
7561   // of any digit.  Otherwise, we make both values positive.
7562
7563   // Use unsigned values otherwise the logic is incorrect for -MIN_INT on
7564   // architectures using 32-bit Smis.
7565   uint32_t x_scaled = x_value;
7566   uint32_t y_scaled = y_value;
7567   if (x_value < 0 || y_value < 0) {
7568     if (y_value >= 0) return Smi::FromInt(LESS);
7569     if (x_value >= 0) return Smi::FromInt(GREATER);
7570     x_scaled = -x_value;
7571     y_scaled = -y_value;
7572   }
7573
7574   static const uint32_t kPowersOf10[] = {
7575     1, 10, 100, 1000, 10*1000, 100*1000,
7576     1000*1000, 10*1000*1000, 100*1000*1000,
7577     1000*1000*1000
7578   };
7579
7580   // If the integers have the same number of decimal digits they can be
7581   // compared directly as the numeric order is the same as the
7582   // lexicographic order.  If one integer has fewer digits, it is scaled
7583   // by some power of 10 to have the same number of digits as the longer
7584   // integer.  If the scaled integers are equal it means the shorter
7585   // integer comes first in the lexicographic order.
7586
7587   // From http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
7588   int x_log2 = IntegerLog2(x_scaled);
7589   int x_log10 = ((x_log2 + 1) * 1233) >> 12;
7590   x_log10 -= x_scaled < kPowersOf10[x_log10];
7591
7592   int y_log2 = IntegerLog2(y_scaled);
7593   int y_log10 = ((y_log2 + 1) * 1233) >> 12;
7594   y_log10 -= y_scaled < kPowersOf10[y_log10];
7595
7596   int tie = EQUAL;
7597
7598   if (x_log10 < y_log10) {
7599     // X has fewer digits.  We would like to simply scale up X but that
7600     // might overflow, e.g when comparing 9 with 1_000_000_000, 9 would
7601     // be scaled up to 9_000_000_000. So we scale up by the next
7602     // smallest power and scale down Y to drop one digit. It is OK to
7603     // drop one digit from the longer integer since the final digit is
7604     // past the length of the shorter integer.
7605     x_scaled *= kPowersOf10[y_log10 - x_log10 - 1];
7606     y_scaled /= 10;
7607     tie = LESS;
7608   } else if (y_log10 < x_log10) {
7609     y_scaled *= kPowersOf10[x_log10 - y_log10 - 1];
7610     x_scaled /= 10;
7611     tie = GREATER;
7612   }
7613
7614   if (x_scaled < y_scaled) return Smi::FromInt(LESS);
7615   if (x_scaled > y_scaled) return Smi::FromInt(GREATER);
7616   return Smi::FromInt(tie);
7617 }
7618
7619
7620 RUNTIME_FUNCTION(Runtime_StringCompare) {
7621   HandleScope handle_scope(isolate);
7622   DCHECK(args.length() == 2);
7623
7624   CONVERT_ARG_HANDLE_CHECKED(String, x, 0);
7625   CONVERT_ARG_HANDLE_CHECKED(String, y, 1);
7626
7627   isolate->counters()->string_compare_runtime()->Increment();
7628
7629   // A few fast case tests before we flatten.
7630   if (x.is_identical_to(y)) return Smi::FromInt(EQUAL);
7631   if (y->length() == 0) {
7632     if (x->length() == 0) return Smi::FromInt(EQUAL);
7633     return Smi::FromInt(GREATER);
7634   } else if (x->length() == 0) {
7635     return Smi::FromInt(LESS);
7636   }
7637
7638   int d = x->Get(0) - y->Get(0);
7639   if (d < 0) return Smi::FromInt(LESS);
7640   else if (d > 0) return Smi::FromInt(GREATER);
7641
7642   // Slow case.
7643   x = String::Flatten(x);
7644   y = String::Flatten(y);
7645
7646   DisallowHeapAllocation no_gc;
7647   Object* equal_prefix_result = Smi::FromInt(EQUAL);
7648   int prefix_length = x->length();
7649   if (y->length() < prefix_length) {
7650     prefix_length = y->length();
7651     equal_prefix_result = Smi::FromInt(GREATER);
7652   } else if (y->length() > prefix_length) {
7653     equal_prefix_result = Smi::FromInt(LESS);
7654   }
7655   int r;
7656   String::FlatContent x_content = x->GetFlatContent();
7657   String::FlatContent y_content = y->GetFlatContent();
7658   if (x_content.IsAscii()) {
7659     Vector<const uint8_t> x_chars = x_content.ToOneByteVector();
7660     if (y_content.IsAscii()) {
7661       Vector<const uint8_t> y_chars = y_content.ToOneByteVector();
7662       r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
7663     } else {
7664       Vector<const uc16> y_chars = y_content.ToUC16Vector();
7665       r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
7666     }
7667   } else {
7668     Vector<const uc16> x_chars = x_content.ToUC16Vector();
7669     if (y_content.IsAscii()) {
7670       Vector<const uint8_t> y_chars = y_content.ToOneByteVector();
7671       r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
7672     } else {
7673       Vector<const uc16> y_chars = y_content.ToUC16Vector();
7674       r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
7675     }
7676   }
7677   Object* result;
7678   if (r == 0) {
7679     result = equal_prefix_result;
7680   } else {
7681     result = (r < 0) ? Smi::FromInt(LESS) : Smi::FromInt(GREATER);
7682   }
7683   return result;
7684 }
7685
7686
7687 #define RUNTIME_UNARY_MATH(Name, name)                                         \
7688 RUNTIME_FUNCTION(Runtime_Math##Name) {                           \
7689   HandleScope scope(isolate);                                                  \
7690   DCHECK(args.length() == 1);                                                  \
7691   isolate->counters()->math_##name()->Increment();                             \
7692   CONVERT_DOUBLE_ARG_CHECKED(x, 0);                                            \
7693   return *isolate->factory()->NewHeapNumber(std::name(x));                     \
7694 }
7695
7696 RUNTIME_UNARY_MATH(Acos, acos)
7697 RUNTIME_UNARY_MATH(Asin, asin)
7698 RUNTIME_UNARY_MATH(Atan, atan)
7699 RUNTIME_UNARY_MATH(LogRT, log)
7700 #undef RUNTIME_UNARY_MATH
7701
7702
7703 RUNTIME_FUNCTION(Runtime_DoubleHi) {
7704   HandleScope scope(isolate);
7705   DCHECK(args.length() == 1);
7706   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7707   uint64_t integer = double_to_uint64(x);
7708   integer = (integer >> 32) & 0xFFFFFFFFu;
7709   return *isolate->factory()->NewNumber(static_cast<int32_t>(integer));
7710 }
7711
7712
7713 RUNTIME_FUNCTION(Runtime_DoubleLo) {
7714   HandleScope scope(isolate);
7715   DCHECK(args.length() == 1);
7716   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7717   return *isolate->factory()->NewNumber(
7718       static_cast<int32_t>(double_to_uint64(x) & 0xFFFFFFFFu));
7719 }
7720
7721
7722 RUNTIME_FUNCTION(Runtime_ConstructDouble) {
7723   HandleScope scope(isolate);
7724   DCHECK(args.length() == 2);
7725   CONVERT_NUMBER_CHECKED(uint32_t, hi, Uint32, args[0]);
7726   CONVERT_NUMBER_CHECKED(uint32_t, lo, Uint32, args[1]);
7727   uint64_t result = (static_cast<uint64_t>(hi) << 32) | lo;
7728   return *isolate->factory()->NewNumber(uint64_to_double(result));
7729 }
7730
7731
7732 RUNTIME_FUNCTION(Runtime_RemPiO2) {
7733   HandleScope handle_scope(isolate);
7734   DCHECK(args.length() == 1);
7735   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7736   Factory* factory = isolate->factory();
7737   double y[2];
7738   int n = fdlibm::rempio2(x, y);
7739   Handle<FixedArray> array = factory->NewFixedArray(3);
7740   Handle<HeapNumber> y0 = factory->NewHeapNumber(y[0]);
7741   Handle<HeapNumber> y1 = factory->NewHeapNumber(y[1]);
7742   array->set(0, Smi::FromInt(n));
7743   array->set(1, *y0);
7744   array->set(2, *y1);
7745   return *factory->NewJSArrayWithElements(array);
7746 }
7747
7748
7749 static const double kPiDividedBy4 = 0.78539816339744830962;
7750
7751
7752 RUNTIME_FUNCTION(Runtime_MathAtan2) {
7753   HandleScope scope(isolate);
7754   DCHECK(args.length() == 2);
7755   isolate->counters()->math_atan2()->Increment();
7756
7757   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7758   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
7759   double result;
7760   if (std::isinf(x) && std::isinf(y)) {
7761     // Make sure that the result in case of two infinite arguments
7762     // is a multiple of Pi / 4. The sign of the result is determined
7763     // by the first argument (x) and the sign of the second argument
7764     // determines the multiplier: one or three.
7765     int multiplier = (x < 0) ? -1 : 1;
7766     if (y < 0) multiplier *= 3;
7767     result = multiplier * kPiDividedBy4;
7768   } else {
7769     result = std::atan2(x, y);
7770   }
7771   return *isolate->factory()->NewNumber(result);
7772 }
7773
7774
7775 RUNTIME_FUNCTION(Runtime_MathExpRT) {
7776   HandleScope scope(isolate);
7777   DCHECK(args.length() == 1);
7778   isolate->counters()->math_exp()->Increment();
7779
7780   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7781   lazily_initialize_fast_exp();
7782   return *isolate->factory()->NewNumber(fast_exp(x));
7783 }
7784
7785
7786 RUNTIME_FUNCTION(Runtime_MathFloorRT) {
7787   HandleScope scope(isolate);
7788   DCHECK(args.length() == 1);
7789   isolate->counters()->math_floor()->Increment();
7790
7791   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7792   return *isolate->factory()->NewNumber(Floor(x));
7793 }
7794
7795
7796 // Slow version of Math.pow.  We check for fast paths for special cases.
7797 // Used if VFP3 is not available.
7798 RUNTIME_FUNCTION(Runtime_MathPowSlow) {
7799   HandleScope scope(isolate);
7800   DCHECK(args.length() == 2);
7801   isolate->counters()->math_pow()->Increment();
7802
7803   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7804
7805   // If the second argument is a smi, it is much faster to call the
7806   // custom powi() function than the generic pow().
7807   if (args[1]->IsSmi()) {
7808     int y = args.smi_at(1);
7809     return *isolate->factory()->NewNumber(power_double_int(x, y));
7810   }
7811
7812   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
7813   double result = power_helper(x, y);
7814   if (std::isnan(result)) return isolate->heap()->nan_value();
7815   return *isolate->factory()->NewNumber(result);
7816 }
7817
7818
7819 // Fast version of Math.pow if we know that y is not an integer and y is not
7820 // -0.5 or 0.5.  Used as slow case from full codegen.
7821 RUNTIME_FUNCTION(Runtime_MathPowRT) {
7822   HandleScope scope(isolate);
7823   DCHECK(args.length() == 2);
7824   isolate->counters()->math_pow()->Increment();
7825
7826   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7827   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
7828   if (y == 0) {
7829     return Smi::FromInt(1);
7830   } else {
7831     double result = power_double_double(x, y);
7832     if (std::isnan(result)) return isolate->heap()->nan_value();
7833     return *isolate->factory()->NewNumber(result);
7834   }
7835 }
7836
7837
7838 RUNTIME_FUNCTION(Runtime_RoundNumber) {
7839   HandleScope scope(isolate);
7840   DCHECK(args.length() == 1);
7841   CONVERT_NUMBER_ARG_HANDLE_CHECKED(input, 0);
7842   isolate->counters()->math_round()->Increment();
7843
7844   if (!input->IsHeapNumber()) {
7845     DCHECK(input->IsSmi());
7846     return *input;
7847   }
7848
7849   Handle<HeapNumber> number = Handle<HeapNumber>::cast(input);
7850
7851   double value = number->value();
7852   int exponent = number->get_exponent();
7853   int sign = number->get_sign();
7854
7855   if (exponent < -1) {
7856     // Number in range ]-0.5..0.5[. These always round to +/-zero.
7857     if (sign) return isolate->heap()->minus_zero_value();
7858     return Smi::FromInt(0);
7859   }
7860
7861   // We compare with kSmiValueSize - 2 because (2^30 - 0.1) has exponent 29 and
7862   // should be rounded to 2^30, which is not smi (for 31-bit smis, similar
7863   // argument holds for 32-bit smis).
7864   if (!sign && exponent < kSmiValueSize - 2) {
7865     return Smi::FromInt(static_cast<int>(value + 0.5));
7866   }
7867
7868   // If the magnitude is big enough, there's no place for fraction part. If we
7869   // try to add 0.5 to this number, 1.0 will be added instead.
7870   if (exponent >= 52) {
7871     return *number;
7872   }
7873
7874   if (sign && value >= -0.5) return isolate->heap()->minus_zero_value();
7875
7876   // Do not call NumberFromDouble() to avoid extra checks.
7877   return *isolate->factory()->NewNumber(Floor(value + 0.5));
7878 }
7879
7880
7881 RUNTIME_FUNCTION(Runtime_MathSqrtRT) {
7882   HandleScope scope(isolate);
7883   DCHECK(args.length() == 1);
7884   isolate->counters()->math_sqrt()->Increment();
7885
7886   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7887   return *isolate->factory()->NewNumber(fast_sqrt(x));
7888 }
7889
7890
7891 RUNTIME_FUNCTION(Runtime_MathFround) {
7892   HandleScope scope(isolate);
7893   DCHECK(args.length() == 1);
7894
7895   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7896   float xf = static_cast<float>(x);
7897   return *isolate->factory()->NewNumber(xf);
7898 }
7899
7900
7901 RUNTIME_FUNCTION(Runtime_DateMakeDay) {
7902   SealHandleScope shs(isolate);
7903   DCHECK(args.length() == 2);
7904
7905   CONVERT_SMI_ARG_CHECKED(year, 0);
7906   CONVERT_SMI_ARG_CHECKED(month, 1);
7907
7908   int days = isolate->date_cache()->DaysFromYearMonth(year, month);
7909   RUNTIME_ASSERT(Smi::IsValid(days));
7910   return Smi::FromInt(days);
7911 }
7912
7913
7914 RUNTIME_FUNCTION(Runtime_DateSetValue) {
7915   HandleScope scope(isolate);
7916   DCHECK(args.length() == 3);
7917
7918   CONVERT_ARG_HANDLE_CHECKED(JSDate, date, 0);
7919   CONVERT_DOUBLE_ARG_CHECKED(time, 1);
7920   CONVERT_SMI_ARG_CHECKED(is_utc, 2);
7921
7922   DateCache* date_cache = isolate->date_cache();
7923
7924   Handle<Object> value;;
7925   bool is_value_nan = false;
7926   if (std::isnan(time)) {
7927     value = isolate->factory()->nan_value();
7928     is_value_nan = true;
7929   } else if (!is_utc &&
7930              (time < -DateCache::kMaxTimeBeforeUTCInMs ||
7931               time > DateCache::kMaxTimeBeforeUTCInMs)) {
7932     value = isolate->factory()->nan_value();
7933     is_value_nan = true;
7934   } else {
7935     time = is_utc ? time : date_cache->ToUTC(static_cast<int64_t>(time));
7936     if (time < -DateCache::kMaxTimeInMs ||
7937         time > DateCache::kMaxTimeInMs) {
7938       value = isolate->factory()->nan_value();
7939       is_value_nan = true;
7940     } else  {
7941       value = isolate->factory()->NewNumber(DoubleToInteger(time));
7942     }
7943   }
7944   date->SetValue(*value, is_value_nan);
7945   return *value;
7946 }
7947
7948
7949 static Handle<JSObject> NewSloppyArguments(Isolate* isolate,
7950                                            Handle<JSFunction> callee,
7951                                            Object** parameters,
7952                                            int argument_count) {
7953   Handle<JSObject> result =
7954       isolate->factory()->NewArgumentsObject(callee, argument_count);
7955
7956   // Allocate the elements if needed.
7957   int parameter_count = callee->shared()->formal_parameter_count();
7958   if (argument_count > 0) {
7959     if (parameter_count > 0) {
7960       int mapped_count = Min(argument_count, parameter_count);
7961       Handle<FixedArray> parameter_map =
7962           isolate->factory()->NewFixedArray(mapped_count + 2, NOT_TENURED);
7963       parameter_map->set_map(
7964           isolate->heap()->sloppy_arguments_elements_map());
7965
7966       Handle<Map> map = Map::Copy(handle(result->map()));
7967       map->set_elements_kind(SLOPPY_ARGUMENTS_ELEMENTS);
7968
7969       result->set_map(*map);
7970       result->set_elements(*parameter_map);
7971
7972       // Store the context and the arguments array at the beginning of the
7973       // parameter map.
7974       Handle<Context> context(isolate->context());
7975       Handle<FixedArray> arguments =
7976           isolate->factory()->NewFixedArray(argument_count, NOT_TENURED);
7977       parameter_map->set(0, *context);
7978       parameter_map->set(1, *arguments);
7979
7980       // Loop over the actual parameters backwards.
7981       int index = argument_count - 1;
7982       while (index >= mapped_count) {
7983         // These go directly in the arguments array and have no
7984         // corresponding slot in the parameter map.
7985         arguments->set(index, *(parameters - index - 1));
7986         --index;
7987       }
7988
7989       Handle<ScopeInfo> scope_info(callee->shared()->scope_info());
7990       while (index >= 0) {
7991         // Detect duplicate names to the right in the parameter list.
7992         Handle<String> name(scope_info->ParameterName(index));
7993         int context_local_count = scope_info->ContextLocalCount();
7994         bool duplicate = false;
7995         for (int j = index + 1; j < parameter_count; ++j) {
7996           if (scope_info->ParameterName(j) == *name) {
7997             duplicate = true;
7998             break;
7999           }
8000         }
8001
8002         if (duplicate) {
8003           // This goes directly in the arguments array with a hole in the
8004           // parameter map.
8005           arguments->set(index, *(parameters - index - 1));
8006           parameter_map->set_the_hole(index + 2);
8007         } else {
8008           // The context index goes in the parameter map with a hole in the
8009           // arguments array.
8010           int context_index = -1;
8011           for (int j = 0; j < context_local_count; ++j) {
8012             if (scope_info->ContextLocalName(j) == *name) {
8013               context_index = j;
8014               break;
8015             }
8016           }
8017           DCHECK(context_index >= 0);
8018           arguments->set_the_hole(index);
8019           parameter_map->set(index + 2, Smi::FromInt(
8020               Context::MIN_CONTEXT_SLOTS + context_index));
8021         }
8022
8023         --index;
8024       }
8025     } else {
8026       // If there is no aliasing, the arguments object elements are not
8027       // special in any way.
8028       Handle<FixedArray> elements =
8029           isolate->factory()->NewFixedArray(argument_count, NOT_TENURED);
8030       result->set_elements(*elements);
8031       for (int i = 0; i < argument_count; ++i) {
8032         elements->set(i, *(parameters - i - 1));
8033       }
8034     }
8035   }
8036   return result;
8037 }
8038
8039
8040 static Handle<JSObject> NewStrictArguments(Isolate* isolate,
8041                                            Handle<JSFunction> callee,
8042                                            Object** parameters,
8043                                            int argument_count) {
8044   Handle<JSObject> result =
8045       isolate->factory()->NewArgumentsObject(callee, argument_count);
8046
8047   if (argument_count > 0) {
8048     Handle<FixedArray> array =
8049         isolate->factory()->NewUninitializedFixedArray(argument_count);
8050     DisallowHeapAllocation no_gc;
8051     WriteBarrierMode mode = array->GetWriteBarrierMode(no_gc);
8052     for (int i = 0; i < argument_count; i++) {
8053       array->set(i, *--parameters, mode);
8054     }
8055     result->set_elements(*array);
8056   }
8057   return result;
8058 }
8059
8060
8061 RUNTIME_FUNCTION(Runtime_NewArguments) {
8062   HandleScope scope(isolate);
8063   DCHECK(args.length() == 1);
8064   CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0);
8065   JavaScriptFrameIterator it(isolate);
8066
8067   // Find the frame that holds the actual arguments passed to the function.
8068   it.AdvanceToArgumentsFrame();
8069   JavaScriptFrame* frame = it.frame();
8070
8071   // Determine parameter location on the stack and dispatch on language mode.
8072   int argument_count = frame->GetArgumentsLength();
8073   Object** parameters = reinterpret_cast<Object**>(frame->GetParameterSlot(-1));
8074   return callee->shared()->strict_mode() == STRICT
8075              ? *NewStrictArguments(isolate, callee, parameters, argument_count)
8076              : *NewSloppyArguments(isolate, callee, parameters, argument_count);
8077 }
8078
8079
8080 RUNTIME_FUNCTION(Runtime_NewSloppyArguments) {
8081   HandleScope scope(isolate);
8082   DCHECK(args.length() == 3);
8083   CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0);
8084   Object** parameters = reinterpret_cast<Object**>(args[1]);
8085   CONVERT_SMI_ARG_CHECKED(argument_count, 2);
8086   return *NewSloppyArguments(isolate, callee, parameters, argument_count);
8087 }
8088
8089
8090 RUNTIME_FUNCTION(Runtime_NewStrictArguments) {
8091   HandleScope scope(isolate);
8092   DCHECK(args.length() == 3);
8093   CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0)
8094   Object** parameters = reinterpret_cast<Object**>(args[1]);
8095   CONVERT_SMI_ARG_CHECKED(argument_count, 2);
8096   return *NewStrictArguments(isolate, callee, parameters, argument_count);
8097 }
8098
8099
8100 RUNTIME_FUNCTION(Runtime_NewClosureFromStubFailure) {
8101   HandleScope scope(isolate);
8102   DCHECK(args.length() == 1);
8103   CONVERT_ARG_HANDLE_CHECKED(SharedFunctionInfo, shared, 0);
8104   Handle<Context> context(isolate->context());
8105   PretenureFlag pretenure_flag = NOT_TENURED;
8106   return *isolate->factory()->NewFunctionFromSharedFunctionInfo(
8107       shared,  context, pretenure_flag);
8108 }
8109
8110
8111 RUNTIME_FUNCTION(Runtime_NewClosure) {
8112   HandleScope scope(isolate);
8113   DCHECK(args.length() == 3);
8114   CONVERT_ARG_HANDLE_CHECKED(Context, context, 0);
8115   CONVERT_ARG_HANDLE_CHECKED(SharedFunctionInfo, shared, 1);
8116   CONVERT_BOOLEAN_ARG_CHECKED(pretenure, 2);
8117
8118   // The caller ensures that we pretenure closures that are assigned
8119   // directly to properties.
8120   PretenureFlag pretenure_flag = pretenure ? TENURED : NOT_TENURED;
8121   return *isolate->factory()->NewFunctionFromSharedFunctionInfo(
8122       shared, context, pretenure_flag);
8123 }
8124
8125
8126 // Find the arguments of the JavaScript function invocation that called
8127 // into C++ code. Collect these in a newly allocated array of handles (possibly
8128 // prefixed by a number of empty handles).
8129 static SmartArrayPointer<Handle<Object> > GetCallerArguments(
8130     Isolate* isolate,
8131     int prefix_argc,
8132     int* total_argc) {
8133   // Find frame containing arguments passed to the caller.
8134   JavaScriptFrameIterator it(isolate);
8135   JavaScriptFrame* frame = it.frame();
8136   List<JSFunction*> functions(2);
8137   frame->GetFunctions(&functions);
8138   if (functions.length() > 1) {
8139     int inlined_jsframe_index = functions.length() - 1;
8140     JSFunction* inlined_function = functions[inlined_jsframe_index];
8141     SlotRefValueBuilder slot_refs(
8142         frame,
8143         inlined_jsframe_index,
8144         inlined_function->shared()->formal_parameter_count());
8145
8146     int args_count = slot_refs.args_length();
8147
8148     *total_argc = prefix_argc + args_count;
8149     SmartArrayPointer<Handle<Object> > param_data(
8150         NewArray<Handle<Object> >(*total_argc));
8151     slot_refs.Prepare(isolate);
8152     for (int i = 0; i < args_count; i++) {
8153       Handle<Object> val = slot_refs.GetNext(isolate, 0);
8154       param_data[prefix_argc + i] = val;
8155     }
8156     slot_refs.Finish(isolate);
8157
8158     return param_data;
8159   } else {
8160     it.AdvanceToArgumentsFrame();
8161     frame = it.frame();
8162     int args_count = frame->ComputeParametersCount();
8163
8164     *total_argc = prefix_argc + args_count;
8165     SmartArrayPointer<Handle<Object> > param_data(
8166         NewArray<Handle<Object> >(*total_argc));
8167     for (int i = 0; i < args_count; i++) {
8168       Handle<Object> val = Handle<Object>(frame->GetParameter(i), isolate);
8169       param_data[prefix_argc + i] = val;
8170     }
8171     return param_data;
8172   }
8173 }
8174
8175
8176 RUNTIME_FUNCTION(Runtime_FunctionBindArguments) {
8177   HandleScope scope(isolate);
8178   DCHECK(args.length() == 4);
8179   CONVERT_ARG_HANDLE_CHECKED(JSFunction, bound_function, 0);
8180   CONVERT_ARG_HANDLE_CHECKED(Object, bindee, 1);
8181   CONVERT_ARG_HANDLE_CHECKED(Object, this_object, 2);
8182   CONVERT_NUMBER_ARG_HANDLE_CHECKED(new_length, 3);
8183
8184   // TODO(lrn): Create bound function in C++ code from premade shared info.
8185   bound_function->shared()->set_bound(true);
8186   // Get all arguments of calling function (Function.prototype.bind).
8187   int argc = 0;
8188   SmartArrayPointer<Handle<Object> > arguments =
8189       GetCallerArguments(isolate, 0, &argc);
8190   // Don't count the this-arg.
8191   if (argc > 0) {
8192     RUNTIME_ASSERT(arguments[0].is_identical_to(this_object));
8193     argc--;
8194   } else {
8195     RUNTIME_ASSERT(this_object->IsUndefined());
8196   }
8197   // Initialize array of bindings (function, this, and any existing arguments
8198   // if the function was already bound).
8199   Handle<FixedArray> new_bindings;
8200   int i;
8201   if (bindee->IsJSFunction() && JSFunction::cast(*bindee)->shared()->bound()) {
8202     Handle<FixedArray> old_bindings(
8203         JSFunction::cast(*bindee)->function_bindings());
8204     RUNTIME_ASSERT(old_bindings->length() > JSFunction::kBoundFunctionIndex);
8205     new_bindings =
8206         isolate->factory()->NewFixedArray(old_bindings->length() + argc);
8207     bindee = Handle<Object>(old_bindings->get(JSFunction::kBoundFunctionIndex),
8208                             isolate);
8209     i = 0;
8210     for (int n = old_bindings->length(); i < n; i++) {
8211       new_bindings->set(i, old_bindings->get(i));
8212     }
8213   } else {
8214     int array_size = JSFunction::kBoundArgumentsStartIndex + argc;
8215     new_bindings = isolate->factory()->NewFixedArray(array_size);
8216     new_bindings->set(JSFunction::kBoundFunctionIndex, *bindee);
8217     new_bindings->set(JSFunction::kBoundThisIndex, *this_object);
8218     i = 2;
8219   }
8220   // Copy arguments, skipping the first which is "this_arg".
8221   for (int j = 0; j < argc; j++, i++) {
8222     new_bindings->set(i, *arguments[j + 1]);
8223   }
8224   new_bindings->set_map_no_write_barrier(
8225       isolate->heap()->fixed_cow_array_map());
8226   bound_function->set_function_bindings(*new_bindings);
8227
8228   // Update length. Have to remove the prototype first so that map migration
8229   // is happy about the number of fields.
8230   RUNTIME_ASSERT(bound_function->RemovePrototype());
8231   Handle<Map> bound_function_map(
8232       isolate->native_context()->bound_function_map());
8233   JSObject::MigrateToMap(bound_function, bound_function_map);
8234   Handle<String> length_string = isolate->factory()->length_string();
8235   PropertyAttributes attr =
8236       static_cast<PropertyAttributes>(DONT_DELETE | DONT_ENUM | READ_ONLY);
8237   RETURN_FAILURE_ON_EXCEPTION(
8238       isolate,
8239       JSObject::SetOwnPropertyIgnoreAttributes(
8240           bound_function, length_string, new_length, attr));
8241   return *bound_function;
8242 }
8243
8244
8245 RUNTIME_FUNCTION(Runtime_BoundFunctionGetBindings) {
8246   HandleScope handles(isolate);
8247   DCHECK(args.length() == 1);
8248   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, callable, 0);
8249   if (callable->IsJSFunction()) {
8250     Handle<JSFunction> function = Handle<JSFunction>::cast(callable);
8251     if (function->shared()->bound()) {
8252       Handle<FixedArray> bindings(function->function_bindings());
8253       RUNTIME_ASSERT(bindings->map() == isolate->heap()->fixed_cow_array_map());
8254       return *isolate->factory()->NewJSArrayWithElements(bindings);
8255     }
8256   }
8257   return isolate->heap()->undefined_value();
8258 }
8259
8260
8261 RUNTIME_FUNCTION(Runtime_NewObjectFromBound) {
8262   HandleScope scope(isolate);
8263   DCHECK(args.length() == 1);
8264   // First argument is a function to use as a constructor.
8265   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
8266   RUNTIME_ASSERT(function->shared()->bound());
8267
8268   // The argument is a bound function. Extract its bound arguments
8269   // and callable.
8270   Handle<FixedArray> bound_args =
8271       Handle<FixedArray>(FixedArray::cast(function->function_bindings()));
8272   int bound_argc = bound_args->length() - JSFunction::kBoundArgumentsStartIndex;
8273   Handle<Object> bound_function(
8274       JSReceiver::cast(bound_args->get(JSFunction::kBoundFunctionIndex)),
8275       isolate);
8276   DCHECK(!bound_function->IsJSFunction() ||
8277          !Handle<JSFunction>::cast(bound_function)->shared()->bound());
8278
8279   int total_argc = 0;
8280   SmartArrayPointer<Handle<Object> > param_data =
8281       GetCallerArguments(isolate, bound_argc, &total_argc);
8282   for (int i = 0; i < bound_argc; i++) {
8283     param_data[i] = Handle<Object>(bound_args->get(
8284         JSFunction::kBoundArgumentsStartIndex + i), isolate);
8285   }
8286
8287   if (!bound_function->IsJSFunction()) {
8288     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
8289         isolate, bound_function,
8290         Execution::TryGetConstructorDelegate(isolate, bound_function));
8291   }
8292   DCHECK(bound_function->IsJSFunction());
8293
8294   Handle<Object> result;
8295   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
8296       isolate, result,
8297       Execution::New(Handle<JSFunction>::cast(bound_function),
8298                      total_argc, param_data.get()));
8299   return *result;
8300 }
8301
8302
8303 static Object* Runtime_NewObjectHelper(Isolate* isolate,
8304                                             Handle<Object> constructor,
8305                                             Handle<AllocationSite> site) {
8306   // If the constructor isn't a proper function we throw a type error.
8307   if (!constructor->IsJSFunction()) {
8308     Vector< Handle<Object> > arguments = HandleVector(&constructor, 1);
8309     Handle<Object> type_error =
8310         isolate->factory()->NewTypeError("not_constructor", arguments);
8311     return isolate->Throw(*type_error);
8312   }
8313
8314   Handle<JSFunction> function = Handle<JSFunction>::cast(constructor);
8315
8316   // If function should not have prototype, construction is not allowed. In this
8317   // case generated code bailouts here, since function has no initial_map.
8318   if (!function->should_have_prototype() && !function->shared()->bound()) {
8319     Vector< Handle<Object> > arguments = HandleVector(&constructor, 1);
8320     Handle<Object> type_error =
8321         isolate->factory()->NewTypeError("not_constructor", arguments);
8322     return isolate->Throw(*type_error);
8323   }
8324
8325   Debug* debug = isolate->debug();
8326   // Handle stepping into constructors if step into is active.
8327   if (debug->StepInActive()) {
8328     debug->HandleStepIn(function, Handle<Object>::null(), 0, true);
8329   }
8330
8331   if (function->has_initial_map()) {
8332     if (function->initial_map()->instance_type() == JS_FUNCTION_TYPE) {
8333       // The 'Function' function ignores the receiver object when
8334       // called using 'new' and creates a new JSFunction object that
8335       // is returned.  The receiver object is only used for error
8336       // reporting if an error occurs when constructing the new
8337       // JSFunction. Factory::NewJSObject() should not be used to
8338       // allocate JSFunctions since it does not properly initialize
8339       // the shared part of the function. Since the receiver is
8340       // ignored anyway, we use the global object as the receiver
8341       // instead of a new JSFunction object. This way, errors are
8342       // reported the same way whether or not 'Function' is called
8343       // using 'new'.
8344       return isolate->global_proxy();
8345     }
8346   }
8347
8348   // The function should be compiled for the optimization hints to be
8349   // available.
8350   Compiler::EnsureCompiled(function, CLEAR_EXCEPTION);
8351
8352   Handle<JSObject> result;
8353   if (site.is_null()) {
8354     result = isolate->factory()->NewJSObject(function);
8355   } else {
8356     result = isolate->factory()->NewJSObjectWithMemento(function, site);
8357   }
8358
8359   isolate->counters()->constructed_objects()->Increment();
8360   isolate->counters()->constructed_objects_runtime()->Increment();
8361
8362   return *result;
8363 }
8364
8365
8366 RUNTIME_FUNCTION(Runtime_NewObject) {
8367   HandleScope scope(isolate);
8368   DCHECK(args.length() == 1);
8369   CONVERT_ARG_HANDLE_CHECKED(Object, constructor, 0);
8370   return Runtime_NewObjectHelper(isolate,
8371                                  constructor,
8372                                  Handle<AllocationSite>::null());
8373 }
8374
8375
8376 RUNTIME_FUNCTION(Runtime_NewObjectWithAllocationSite) {
8377   HandleScope scope(isolate);
8378   DCHECK(args.length() == 2);
8379   CONVERT_ARG_HANDLE_CHECKED(Object, constructor, 1);
8380   CONVERT_ARG_HANDLE_CHECKED(Object, feedback, 0);
8381   Handle<AllocationSite> site;
8382   if (feedback->IsAllocationSite()) {
8383     // The feedback can be an AllocationSite or undefined.
8384     site = Handle<AllocationSite>::cast(feedback);
8385   }
8386   return Runtime_NewObjectHelper(isolate, constructor, site);
8387 }
8388
8389
8390 RUNTIME_FUNCTION(Runtime_FinalizeInstanceSize) {
8391   HandleScope scope(isolate);
8392   DCHECK(args.length() == 1);
8393
8394   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
8395   function->CompleteInobjectSlackTracking();
8396
8397   return isolate->heap()->undefined_value();
8398 }
8399
8400
8401 RUNTIME_FUNCTION(Runtime_CompileUnoptimized) {
8402   HandleScope scope(isolate);
8403   DCHECK(args.length() == 1);
8404   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
8405 #ifdef DEBUG
8406   if (FLAG_trace_lazy && !function->shared()->is_compiled()) {
8407     PrintF("[unoptimized: ");
8408     function->PrintName();
8409     PrintF("]\n");
8410   }
8411 #endif
8412
8413   // Compile the target function.
8414   DCHECK(function->shared()->allows_lazy_compilation());
8415
8416   Handle<Code> code;
8417   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, code,
8418                                      Compiler::GetUnoptimizedCode(function));
8419   function->ReplaceCode(*code);
8420
8421   // All done. Return the compiled code.
8422   DCHECK(function->is_compiled());
8423   DCHECK(function->code()->kind() == Code::FUNCTION ||
8424          (FLAG_always_opt &&
8425           function->code()->kind() == Code::OPTIMIZED_FUNCTION));
8426   return *code;
8427 }
8428
8429
8430 RUNTIME_FUNCTION(Runtime_CompileOptimized) {
8431   HandleScope scope(isolate);
8432   DCHECK(args.length() == 2);
8433   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
8434   CONVERT_BOOLEAN_ARG_CHECKED(concurrent, 1);
8435
8436   Handle<Code> unoptimized(function->shared()->code());
8437   if (!function->shared()->is_compiled()) {
8438     // If the function is not compiled, do not optimize.
8439     // This can happen if the debugger is activated and
8440     // the function is returned to the not compiled state.
8441     // TODO(yangguo): reconsider this.
8442     function->ReplaceCode(function->shared()->code());
8443   } else if (!isolate->use_crankshaft() ||
8444              function->shared()->optimization_disabled() ||
8445              isolate->DebuggerHasBreakPoints()) {
8446     // If the function is not optimizable or debugger is active continue
8447     // using the code from the full compiler.
8448     if (FLAG_trace_opt) {
8449       PrintF("[failed to optimize ");
8450       function->PrintName();
8451       PrintF(": is code optimizable: %s, is debugger enabled: %s]\n",
8452           function->shared()->optimization_disabled() ? "F" : "T",
8453           isolate->DebuggerHasBreakPoints() ? "T" : "F");
8454     }
8455     function->ReplaceCode(*unoptimized);
8456   } else {
8457     Compiler::ConcurrencyMode mode = concurrent ? Compiler::CONCURRENT
8458                                                 : Compiler::NOT_CONCURRENT;
8459     Handle<Code> code;
8460     if (Compiler::GetOptimizedCode(
8461             function, unoptimized, mode).ToHandle(&code)) {
8462       function->ReplaceCode(*code);
8463     } else {
8464       function->ReplaceCode(*unoptimized);
8465     }
8466   }
8467
8468   DCHECK(function->code()->kind() == Code::FUNCTION ||
8469          function->code()->kind() == Code::OPTIMIZED_FUNCTION ||
8470          function->IsInOptimizationQueue());
8471   return function->code();
8472 }
8473
8474
8475 class ActivationsFinder : public ThreadVisitor {
8476  public:
8477   Code* code_;
8478   bool has_code_activations_;
8479
8480   explicit ActivationsFinder(Code* code)
8481     : code_(code),
8482       has_code_activations_(false) { }
8483
8484   void VisitThread(Isolate* isolate, ThreadLocalTop* top) {
8485     JavaScriptFrameIterator it(isolate, top);
8486     VisitFrames(&it);
8487   }
8488
8489   void VisitFrames(JavaScriptFrameIterator* it) {
8490     for (; !it->done(); it->Advance()) {
8491       JavaScriptFrame* frame = it->frame();
8492       if (code_->contains(frame->pc())) has_code_activations_ = true;
8493     }
8494   }
8495 };
8496
8497
8498 RUNTIME_FUNCTION(Runtime_NotifyStubFailure) {
8499   HandleScope scope(isolate);
8500   DCHECK(args.length() == 0);
8501   Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate);
8502   DCHECK(AllowHeapAllocation::IsAllowed());
8503   delete deoptimizer;
8504   return isolate->heap()->undefined_value();
8505 }
8506
8507
8508 RUNTIME_FUNCTION(Runtime_NotifyDeoptimized) {
8509   HandleScope scope(isolate);
8510   DCHECK(args.length() == 1);
8511   CONVERT_SMI_ARG_CHECKED(type_arg, 0);
8512   Deoptimizer::BailoutType type =
8513       static_cast<Deoptimizer::BailoutType>(type_arg);
8514   Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate);
8515   DCHECK(AllowHeapAllocation::IsAllowed());
8516
8517   Handle<JSFunction> function = deoptimizer->function();
8518   Handle<Code> optimized_code = deoptimizer->compiled_code();
8519
8520   DCHECK(optimized_code->kind() == Code::OPTIMIZED_FUNCTION);
8521   DCHECK(type == deoptimizer->bailout_type());
8522
8523   // Make sure to materialize objects before causing any allocation.
8524   JavaScriptFrameIterator it(isolate);
8525   deoptimizer->MaterializeHeapObjects(&it);
8526   delete deoptimizer;
8527
8528   JavaScriptFrame* frame = it.frame();
8529   RUNTIME_ASSERT(frame->function()->IsJSFunction());
8530   DCHECK(frame->function() == *function);
8531
8532   // Avoid doing too much work when running with --always-opt and keep
8533   // the optimized code around.
8534   if (FLAG_always_opt || type == Deoptimizer::LAZY) {
8535     return isolate->heap()->undefined_value();
8536   }
8537
8538   // Search for other activations of the same function and code.
8539   ActivationsFinder activations_finder(*optimized_code);
8540   activations_finder.VisitFrames(&it);
8541   isolate->thread_manager()->IterateArchivedThreads(&activations_finder);
8542
8543   if (!activations_finder.has_code_activations_) {
8544     if (function->code() == *optimized_code) {
8545       if (FLAG_trace_deopt) {
8546         PrintF("[removing optimized code for: ");
8547         function->PrintName();
8548         PrintF("]\n");
8549       }
8550       function->ReplaceCode(function->shared()->code());
8551       // Evict optimized code for this function from the cache so that it
8552       // doesn't get used for new closures.
8553       function->shared()->EvictFromOptimizedCodeMap(*optimized_code,
8554                                                     "notify deoptimized");
8555     }
8556   } else {
8557     // TODO(titzer): we should probably do DeoptimizeCodeList(code)
8558     // unconditionally if the code is not already marked for deoptimization.
8559     // If there is an index by shared function info, all the better.
8560     Deoptimizer::DeoptimizeFunction(*function);
8561   }
8562
8563   return isolate->heap()->undefined_value();
8564 }
8565
8566
8567 RUNTIME_FUNCTION(Runtime_DeoptimizeFunction) {
8568   HandleScope scope(isolate);
8569   DCHECK(args.length() == 1);
8570   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
8571   if (!function->IsOptimized()) return isolate->heap()->undefined_value();
8572
8573   // TODO(turbofan): Deoptimization is not supported yet.
8574   if (function->code()->is_turbofanned() && !FLAG_turbo_deoptimization) {
8575     return isolate->heap()->undefined_value();
8576   }
8577
8578   Deoptimizer::DeoptimizeFunction(*function);
8579
8580   return isolate->heap()->undefined_value();
8581 }
8582
8583
8584 RUNTIME_FUNCTION(Runtime_ClearFunctionTypeFeedback) {
8585   HandleScope scope(isolate);
8586   DCHECK(args.length() == 1);
8587   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
8588   function->shared()->ClearTypeFeedbackInfo();
8589   Code* unoptimized = function->shared()->code();
8590   if (unoptimized->kind() == Code::FUNCTION) {
8591     unoptimized->ClearInlineCaches();
8592   }
8593   return isolate->heap()->undefined_value();
8594 }
8595
8596
8597 RUNTIME_FUNCTION(Runtime_RunningInSimulator) {
8598   SealHandleScope shs(isolate);
8599   DCHECK(args.length() == 0);
8600 #if defined(USE_SIMULATOR)
8601   return isolate->heap()->true_value();
8602 #else
8603   return isolate->heap()->false_value();
8604 #endif
8605 }
8606
8607
8608 RUNTIME_FUNCTION(Runtime_IsConcurrentRecompilationSupported) {
8609   SealHandleScope shs(isolate);
8610   DCHECK(args.length() == 0);
8611   return isolate->heap()->ToBoolean(
8612       isolate->concurrent_recompilation_enabled());
8613 }
8614
8615
8616 RUNTIME_FUNCTION(Runtime_OptimizeFunctionOnNextCall) {
8617   HandleScope scope(isolate);
8618   RUNTIME_ASSERT(args.length() == 1 || args.length() == 2);
8619   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
8620
8621   if (!function->IsOptimizable() &&
8622       !function->IsMarkedForConcurrentOptimization() &&
8623       !function->IsInOptimizationQueue()) {
8624     return isolate->heap()->undefined_value();
8625   }
8626
8627   function->MarkForOptimization();
8628
8629   Code* unoptimized = function->shared()->code();
8630   if (args.length() == 2 &&
8631       unoptimized->kind() == Code::FUNCTION) {
8632     CONVERT_ARG_HANDLE_CHECKED(String, type, 1);
8633     if (type->IsOneByteEqualTo(STATIC_ASCII_VECTOR("osr")) && FLAG_use_osr) {
8634       // Start patching from the currently patched loop nesting level.
8635       DCHECK(BackEdgeTable::Verify(isolate, unoptimized));
8636       isolate->runtime_profiler()->AttemptOnStackReplacement(
8637           *function, Code::kMaxLoopNestingMarker);
8638     } else if (type->IsOneByteEqualTo(STATIC_ASCII_VECTOR("concurrent")) &&
8639                isolate->concurrent_recompilation_enabled()) {
8640       function->MarkForConcurrentOptimization();
8641     }
8642   }
8643
8644   return isolate->heap()->undefined_value();
8645 }
8646
8647
8648 RUNTIME_FUNCTION(Runtime_NeverOptimizeFunction) {
8649   HandleScope scope(isolate);
8650   DCHECK(args.length() == 1);
8651   CONVERT_ARG_CHECKED(JSFunction, function, 0);
8652   function->shared()->set_optimization_disabled(true);
8653   return isolate->heap()->undefined_value();
8654 }
8655
8656
8657 RUNTIME_FUNCTION(Runtime_GetOptimizationStatus) {
8658   HandleScope scope(isolate);
8659   RUNTIME_ASSERT(args.length() == 1 || args.length() == 2);
8660   if (!isolate->use_crankshaft()) {
8661     return Smi::FromInt(4);  // 4 == "never".
8662   }
8663   bool sync_with_compiler_thread = true;
8664   if (args.length() == 2) {
8665     CONVERT_ARG_HANDLE_CHECKED(String, sync, 1);
8666     if (sync->IsOneByteEqualTo(STATIC_ASCII_VECTOR("no sync"))) {
8667       sync_with_compiler_thread = false;
8668     }
8669   }
8670   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
8671   if (isolate->concurrent_recompilation_enabled() &&
8672       sync_with_compiler_thread) {
8673     while (function->IsInOptimizationQueue()) {
8674       isolate->optimizing_compiler_thread()->InstallOptimizedFunctions();
8675       base::OS::Sleep(50);
8676     }
8677   }
8678   if (FLAG_always_opt) {
8679     // We may have always opt, but that is more best-effort than a real
8680     // promise, so we still say "no" if it is not optimized.
8681     return function->IsOptimized() ? Smi::FromInt(3)   // 3 == "always".
8682                                    : Smi::FromInt(2);  // 2 == "no".
8683   }
8684   if (FLAG_deopt_every_n_times) {
8685     return Smi::FromInt(6);  // 6 == "maybe deopted".
8686   }
8687   if (function->IsOptimized() && function->code()->is_turbofanned()) {
8688     return Smi::FromInt(7);  // 7 == "TurboFan compiler".
8689   }
8690   return function->IsOptimized() ? Smi::FromInt(1)   // 1 == "yes".
8691                                  : Smi::FromInt(2);  // 2 == "no".
8692 }
8693
8694
8695 RUNTIME_FUNCTION(Runtime_UnblockConcurrentRecompilation) {
8696   DCHECK(args.length() == 0);
8697   RUNTIME_ASSERT(FLAG_block_concurrent_recompilation);
8698   RUNTIME_ASSERT(isolate->concurrent_recompilation_enabled());
8699   isolate->optimizing_compiler_thread()->Unblock();
8700   return isolate->heap()->undefined_value();
8701 }
8702
8703
8704 RUNTIME_FUNCTION(Runtime_GetOptimizationCount) {
8705   HandleScope scope(isolate);
8706   DCHECK(args.length() == 1);
8707   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
8708   return Smi::FromInt(function->shared()->opt_count());
8709 }
8710
8711
8712 static bool IsSuitableForOnStackReplacement(Isolate* isolate,
8713                                             Handle<JSFunction> function,
8714                                             Handle<Code> current_code) {
8715   // Keep track of whether we've succeeded in optimizing.
8716   if (!isolate->use_crankshaft() || !current_code->optimizable()) return false;
8717   // If we are trying to do OSR when there are already optimized
8718   // activations of the function, it means (a) the function is directly or
8719   // indirectly recursive and (b) an optimized invocation has been
8720   // deoptimized so that we are currently in an unoptimized activation.
8721   // Check for optimized activations of this function.
8722   for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) {
8723     JavaScriptFrame* frame = it.frame();
8724     if (frame->is_optimized() && frame->function() == *function) return false;
8725   }
8726
8727   return true;
8728 }
8729
8730
8731 RUNTIME_FUNCTION(Runtime_CompileForOnStackReplacement) {
8732   HandleScope scope(isolate);
8733   DCHECK(args.length() == 1);
8734   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
8735   Handle<Code> caller_code(function->shared()->code());
8736
8737   // We're not prepared to handle a function with arguments object.
8738   DCHECK(!function->shared()->uses_arguments());
8739
8740   RUNTIME_ASSERT(FLAG_use_osr);
8741
8742   // Passing the PC in the javascript frame from the caller directly is
8743   // not GC safe, so we walk the stack to get it.
8744   JavaScriptFrameIterator it(isolate);
8745   JavaScriptFrame* frame = it.frame();
8746   if (!caller_code->contains(frame->pc())) {
8747     // Code on the stack may not be the code object referenced by the shared
8748     // function info.  It may have been replaced to include deoptimization data.
8749     caller_code = Handle<Code>(frame->LookupCode());
8750   }
8751
8752   uint32_t pc_offset = static_cast<uint32_t>(
8753       frame->pc() - caller_code->instruction_start());
8754
8755 #ifdef DEBUG
8756   DCHECK_EQ(frame->function(), *function);
8757   DCHECK_EQ(frame->LookupCode(), *caller_code);
8758   DCHECK(caller_code->contains(frame->pc()));
8759 #endif  // DEBUG
8760
8761
8762   BailoutId ast_id = caller_code->TranslatePcOffsetToAstId(pc_offset);
8763   DCHECK(!ast_id.IsNone());
8764
8765   Compiler::ConcurrencyMode mode =
8766       isolate->concurrent_osr_enabled() &&
8767       (function->shared()->ast_node_count() > 512) ? Compiler::CONCURRENT
8768                                                    : Compiler::NOT_CONCURRENT;
8769   Handle<Code> result = Handle<Code>::null();
8770
8771   OptimizedCompileJob* job = NULL;
8772   if (mode == Compiler::CONCURRENT) {
8773     // Gate the OSR entry with a stack check.
8774     BackEdgeTable::AddStackCheck(caller_code, pc_offset);
8775     // Poll already queued compilation jobs.
8776     OptimizingCompilerThread* thread = isolate->optimizing_compiler_thread();
8777     if (thread->IsQueuedForOSR(function, ast_id)) {
8778       if (FLAG_trace_osr) {
8779         PrintF("[OSR - Still waiting for queued: ");
8780         function->PrintName();
8781         PrintF(" at AST id %d]\n", ast_id.ToInt());
8782       }
8783       return NULL;
8784     }
8785
8786     job = thread->FindReadyOSRCandidate(function, ast_id);
8787   }
8788
8789   if (job != NULL) {
8790     if (FLAG_trace_osr) {
8791       PrintF("[OSR - Found ready: ");
8792       function->PrintName();
8793       PrintF(" at AST id %d]\n", ast_id.ToInt());
8794     }
8795     result = Compiler::GetConcurrentlyOptimizedCode(job);
8796   } else if (IsSuitableForOnStackReplacement(isolate, function, caller_code)) {
8797     if (FLAG_trace_osr) {
8798       PrintF("[OSR - Compiling: ");
8799       function->PrintName();
8800       PrintF(" at AST id %d]\n", ast_id.ToInt());
8801     }
8802     MaybeHandle<Code> maybe_result = Compiler::GetOptimizedCode(
8803         function, caller_code, mode, ast_id);
8804     if (maybe_result.ToHandle(&result) &&
8805         result.is_identical_to(isolate->builtins()->InOptimizationQueue())) {
8806       // Optimization is queued.  Return to check later.
8807       return NULL;
8808     }
8809   }
8810
8811   // Revert the patched back edge table, regardless of whether OSR succeeds.
8812   BackEdgeTable::Revert(isolate, *caller_code);
8813
8814   // Check whether we ended up with usable optimized code.
8815   if (!result.is_null() && result->kind() == Code::OPTIMIZED_FUNCTION) {
8816     DeoptimizationInputData* data =
8817         DeoptimizationInputData::cast(result->deoptimization_data());
8818
8819     if (data->OsrPcOffset()->value() >= 0) {
8820       DCHECK(BailoutId(data->OsrAstId()->value()) == ast_id);
8821       if (FLAG_trace_osr) {
8822         PrintF("[OSR - Entry at AST id %d, offset %d in optimized code]\n",
8823                ast_id.ToInt(), data->OsrPcOffset()->value());
8824       }
8825       // TODO(titzer): this is a massive hack to make the deopt counts
8826       // match. Fix heuristics for reenabling optimizations!
8827       function->shared()->increment_deopt_count();
8828
8829       // TODO(titzer): Do not install code into the function.
8830       function->ReplaceCode(*result);
8831       return *result;
8832     }
8833   }
8834
8835   // Failed.
8836   if (FLAG_trace_osr) {
8837     PrintF("[OSR - Failed: ");
8838     function->PrintName();
8839     PrintF(" at AST id %d]\n", ast_id.ToInt());
8840   }
8841
8842   if (!function->IsOptimized()) {
8843     function->ReplaceCode(function->shared()->code());
8844   }
8845   return NULL;
8846 }
8847
8848
8849 RUNTIME_FUNCTION(Runtime_SetAllocationTimeout) {
8850   SealHandleScope shs(isolate);
8851   DCHECK(args.length() == 2 || args.length() == 3);
8852 #ifdef DEBUG
8853   CONVERT_SMI_ARG_CHECKED(interval, 0);
8854   CONVERT_SMI_ARG_CHECKED(timeout, 1);
8855   isolate->heap()->set_allocation_timeout(timeout);
8856   FLAG_gc_interval = interval;
8857   if (args.length() == 3) {
8858     // Enable/disable inline allocation if requested.
8859     CONVERT_BOOLEAN_ARG_CHECKED(inline_allocation, 2);
8860     if (inline_allocation) {
8861       isolate->heap()->EnableInlineAllocation();
8862     } else {
8863       isolate->heap()->DisableInlineAllocation();
8864     }
8865   }
8866 #endif
8867   return isolate->heap()->undefined_value();
8868 }
8869
8870
8871 RUNTIME_FUNCTION(Runtime_CheckIsBootstrapping) {
8872   SealHandleScope shs(isolate);
8873   DCHECK(args.length() == 0);
8874   RUNTIME_ASSERT(isolate->bootstrapper()->IsActive());
8875   return isolate->heap()->undefined_value();
8876 }
8877
8878
8879 RUNTIME_FUNCTION(Runtime_GetRootNaN) {
8880   SealHandleScope shs(isolate);
8881   DCHECK(args.length() == 0);
8882   RUNTIME_ASSERT(isolate->bootstrapper()->IsActive());
8883   return isolate->heap()->nan_value();
8884 }
8885
8886
8887 RUNTIME_FUNCTION(Runtime_Call) {
8888   HandleScope scope(isolate);
8889   DCHECK(args.length() >= 2);
8890   int argc = args.length() - 2;
8891   CONVERT_ARG_CHECKED(JSReceiver, fun, argc + 1);
8892   Object* receiver = args[0];
8893
8894   // If there are too many arguments, allocate argv via malloc.
8895   const int argv_small_size = 10;
8896   Handle<Object> argv_small_buffer[argv_small_size];
8897   SmartArrayPointer<Handle<Object> > argv_large_buffer;
8898   Handle<Object>* argv = argv_small_buffer;
8899   if (argc > argv_small_size) {
8900     argv = new Handle<Object>[argc];
8901     if (argv == NULL) return isolate->StackOverflow();
8902     argv_large_buffer = SmartArrayPointer<Handle<Object> >(argv);
8903   }
8904
8905   for (int i = 0; i < argc; ++i) {
8906      argv[i] = Handle<Object>(args[1 + i], isolate);
8907   }
8908
8909   Handle<JSReceiver> hfun(fun);
8910   Handle<Object> hreceiver(receiver, isolate);
8911   Handle<Object> result;
8912   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
8913       isolate, result,
8914       Execution::Call(isolate, hfun, hreceiver, argc, argv, true));
8915   return *result;
8916 }
8917
8918
8919 RUNTIME_FUNCTION(Runtime_Apply) {
8920   HandleScope scope(isolate);
8921   DCHECK(args.length() == 5);
8922   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, fun, 0);
8923   CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 1);
8924   CONVERT_ARG_HANDLE_CHECKED(JSObject, arguments, 2);
8925   CONVERT_SMI_ARG_CHECKED(offset, 3);
8926   CONVERT_SMI_ARG_CHECKED(argc, 4);
8927   RUNTIME_ASSERT(offset >= 0);
8928   // Loose upper bound to allow fuzzing. We'll most likely run out of
8929   // stack space before hitting this limit.
8930   static int kMaxArgc = 1000000;
8931   RUNTIME_ASSERT(argc >= 0 && argc <= kMaxArgc);
8932
8933   // If there are too many arguments, allocate argv via malloc.
8934   const int argv_small_size = 10;
8935   Handle<Object> argv_small_buffer[argv_small_size];
8936   SmartArrayPointer<Handle<Object> > argv_large_buffer;
8937   Handle<Object>* argv = argv_small_buffer;
8938   if (argc > argv_small_size) {
8939     argv = new Handle<Object>[argc];
8940     if (argv == NULL) return isolate->StackOverflow();
8941     argv_large_buffer = SmartArrayPointer<Handle<Object> >(argv);
8942   }
8943
8944   for (int i = 0; i < argc; ++i) {
8945     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
8946         isolate, argv[i],
8947         Object::GetElement(isolate, arguments, offset + i));
8948   }
8949
8950   Handle<Object> result;
8951   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
8952       isolate, result,
8953       Execution::Call(isolate, fun, receiver, argc, argv, true));
8954   return *result;
8955 }
8956
8957
8958 RUNTIME_FUNCTION(Runtime_GetFunctionDelegate) {
8959   HandleScope scope(isolate);
8960   DCHECK(args.length() == 1);
8961   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
8962   RUNTIME_ASSERT(!object->IsJSFunction());
8963   return *Execution::GetFunctionDelegate(isolate, object);
8964 }
8965
8966
8967 RUNTIME_FUNCTION(Runtime_GetConstructorDelegate) {
8968   HandleScope scope(isolate);
8969   DCHECK(args.length() == 1);
8970   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
8971   RUNTIME_ASSERT(!object->IsJSFunction());
8972   return *Execution::GetConstructorDelegate(isolate, object);
8973 }
8974
8975
8976 RUNTIME_FUNCTION(Runtime_NewGlobalContext) {
8977   HandleScope scope(isolate);
8978   DCHECK(args.length() == 2);
8979
8980   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
8981   CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 1);
8982   Handle<Context> result =
8983       isolate->factory()->NewGlobalContext(function, scope_info);
8984
8985   DCHECK(function->context() == isolate->context());
8986   DCHECK(function->context()->global_object() == result->global_object());
8987   result->global_object()->set_global_context(*result);
8988   return *result;
8989 }
8990
8991
8992 RUNTIME_FUNCTION(Runtime_NewFunctionContext) {
8993   HandleScope scope(isolate);
8994   DCHECK(args.length() == 1);
8995
8996   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
8997
8998   DCHECK(function->context() == isolate->context());
8999   int length = function->shared()->scope_info()->ContextLength();
9000   return *isolate->factory()->NewFunctionContext(length, function);
9001 }
9002
9003
9004 RUNTIME_FUNCTION(Runtime_PushWithContext) {
9005   HandleScope scope(isolate);
9006   DCHECK(args.length() == 2);
9007   Handle<JSReceiver> extension_object;
9008   if (args[0]->IsJSReceiver()) {
9009     extension_object = args.at<JSReceiver>(0);
9010   } else {
9011     // Try to convert the object to a proper JavaScript object.
9012     MaybeHandle<JSReceiver> maybe_object =
9013         Object::ToObject(isolate, args.at<Object>(0));
9014     if (!maybe_object.ToHandle(&extension_object)) {
9015       Handle<Object> handle = args.at<Object>(0);
9016       Handle<Object> result =
9017           isolate->factory()->NewTypeError("with_expression",
9018                                            HandleVector(&handle, 1));
9019       return isolate->Throw(*result);
9020     }
9021   }
9022
9023   Handle<JSFunction> function;
9024   if (args[1]->IsSmi()) {
9025     // A smi sentinel indicates a context nested inside global code rather
9026     // than some function.  There is a canonical empty function that can be
9027     // gotten from the native context.
9028     function = handle(isolate->native_context()->closure());
9029   } else {
9030     function = args.at<JSFunction>(1);
9031   }
9032
9033   Handle<Context> current(isolate->context());
9034   Handle<Context> context = isolate->factory()->NewWithContext(
9035       function, current, extension_object);
9036   isolate->set_context(*context);
9037   return *context;
9038 }
9039
9040
9041 RUNTIME_FUNCTION(Runtime_PushCatchContext) {
9042   HandleScope scope(isolate);
9043   DCHECK(args.length() == 3);
9044   CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
9045   CONVERT_ARG_HANDLE_CHECKED(Object, thrown_object, 1);
9046   Handle<JSFunction> function;
9047   if (args[2]->IsSmi()) {
9048     // A smi sentinel indicates a context nested inside global code rather
9049     // than some function.  There is a canonical empty function that can be
9050     // gotten from the native context.
9051     function = handle(isolate->native_context()->closure());
9052   } else {
9053     function = args.at<JSFunction>(2);
9054   }
9055   Handle<Context> current(isolate->context());
9056   Handle<Context> context = isolate->factory()->NewCatchContext(
9057       function, current, name, thrown_object);
9058   isolate->set_context(*context);
9059   return *context;
9060 }
9061
9062
9063 RUNTIME_FUNCTION(Runtime_PushBlockContext) {
9064   HandleScope scope(isolate);
9065   DCHECK(args.length() == 2);
9066   CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 0);
9067   Handle<JSFunction> function;
9068   if (args[1]->IsSmi()) {
9069     // A smi sentinel indicates a context nested inside global code rather
9070     // than some function.  There is a canonical empty function that can be
9071     // gotten from the native context.
9072     function = handle(isolate->native_context()->closure());
9073   } else {
9074     function = args.at<JSFunction>(1);
9075   }
9076   Handle<Context> current(isolate->context());
9077   Handle<Context> context = isolate->factory()->NewBlockContext(
9078       function, current, scope_info);
9079   isolate->set_context(*context);
9080   return *context;
9081 }
9082
9083
9084 RUNTIME_FUNCTION(Runtime_IsJSModule) {
9085   SealHandleScope shs(isolate);
9086   DCHECK(args.length() == 1);
9087   CONVERT_ARG_CHECKED(Object, obj, 0);
9088   return isolate->heap()->ToBoolean(obj->IsJSModule());
9089 }
9090
9091
9092 RUNTIME_FUNCTION(Runtime_PushModuleContext) {
9093   SealHandleScope shs(isolate);
9094   DCHECK(args.length() == 2);
9095   CONVERT_SMI_ARG_CHECKED(index, 0);
9096
9097   if (!args[1]->IsScopeInfo()) {
9098     // Module already initialized. Find hosting context and retrieve context.
9099     Context* host = Context::cast(isolate->context())->global_context();
9100     Context* context = Context::cast(host->get(index));
9101     DCHECK(context->previous() == isolate->context());
9102     isolate->set_context(context);
9103     return context;
9104   }
9105
9106   CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 1);
9107
9108   // Allocate module context.
9109   HandleScope scope(isolate);
9110   Factory* factory = isolate->factory();
9111   Handle<Context> context = factory->NewModuleContext(scope_info);
9112   Handle<JSModule> module = factory->NewJSModule(context, scope_info);
9113   context->set_module(*module);
9114   Context* previous = isolate->context();
9115   context->set_previous(previous);
9116   context->set_closure(previous->closure());
9117   context->set_global_object(previous->global_object());
9118   isolate->set_context(*context);
9119
9120   // Find hosting scope and initialize internal variable holding module there.
9121   previous->global_context()->set(index, *context);
9122
9123   return *context;
9124 }
9125
9126
9127 RUNTIME_FUNCTION(Runtime_DeclareModules) {
9128   HandleScope scope(isolate);
9129   DCHECK(args.length() == 1);
9130   CONVERT_ARG_HANDLE_CHECKED(FixedArray, descriptions, 0);
9131   Context* host_context = isolate->context();
9132
9133   for (int i = 0; i < descriptions->length(); ++i) {
9134     Handle<ModuleInfo> description(ModuleInfo::cast(descriptions->get(i)));
9135     int host_index = description->host_index();
9136     Handle<Context> context(Context::cast(host_context->get(host_index)));
9137     Handle<JSModule> module(context->module());
9138
9139     for (int j = 0; j < description->length(); ++j) {
9140       Handle<String> name(description->name(j));
9141       VariableMode mode = description->mode(j);
9142       int index = description->index(j);
9143       switch (mode) {
9144         case VAR:
9145         case LET:
9146         case CONST:
9147         case CONST_LEGACY: {
9148           PropertyAttributes attr =
9149               IsImmutableVariableMode(mode) ? FROZEN : SEALED;
9150           Handle<AccessorInfo> info =
9151               Accessors::MakeModuleExport(name, index, attr);
9152           Handle<Object> result =
9153               JSObject::SetAccessor(module, info).ToHandleChecked();
9154           DCHECK(!result->IsUndefined());
9155           USE(result);
9156           break;
9157         }
9158         case MODULE: {
9159           Object* referenced_context = Context::cast(host_context)->get(index);
9160           Handle<JSModule> value(Context::cast(referenced_context)->module());
9161           JSObject::SetOwnPropertyIgnoreAttributes(module, name, value, FROZEN)
9162               .Assert();
9163           break;
9164         }
9165         case INTERNAL:
9166         case TEMPORARY:
9167         case DYNAMIC:
9168         case DYNAMIC_GLOBAL:
9169         case DYNAMIC_LOCAL:
9170           UNREACHABLE();
9171       }
9172     }
9173
9174     JSObject::PreventExtensions(module).Assert();
9175   }
9176
9177   DCHECK(!isolate->has_pending_exception());
9178   return isolate->heap()->undefined_value();
9179 }
9180
9181
9182 RUNTIME_FUNCTION(Runtime_DeleteLookupSlot) {
9183   HandleScope scope(isolate);
9184   DCHECK(args.length() == 2);
9185
9186   CONVERT_ARG_HANDLE_CHECKED(Context, context, 0);
9187   CONVERT_ARG_HANDLE_CHECKED(String, name, 1);
9188
9189   int index;
9190   PropertyAttributes attributes;
9191   ContextLookupFlags flags = FOLLOW_CHAINS;
9192   BindingFlags binding_flags;
9193   Handle<Object> holder = context->Lookup(name,
9194                                           flags,
9195                                           &index,
9196                                           &attributes,
9197                                           &binding_flags);
9198
9199   // If the slot was not found the result is true.
9200   if (holder.is_null()) {
9201     return isolate->heap()->true_value();
9202   }
9203
9204   // If the slot was found in a context, it should be DONT_DELETE.
9205   if (holder->IsContext()) {
9206     return isolate->heap()->false_value();
9207   }
9208
9209   // The slot was found in a JSObject, either a context extension object,
9210   // the global object, or the subject of a with.  Try to delete it
9211   // (respecting DONT_DELETE).
9212   Handle<JSObject> object = Handle<JSObject>::cast(holder);
9213   Handle<Object> result;
9214   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
9215       isolate, result,
9216       JSReceiver::DeleteProperty(object, name));
9217   return *result;
9218 }
9219
9220
9221 // A mechanism to return a pair of Object pointers in registers (if possible).
9222 // How this is achieved is calling convention-dependent.
9223 // All currently supported x86 compiles uses calling conventions that are cdecl
9224 // variants where a 64-bit value is returned in two 32-bit registers
9225 // (edx:eax on ia32, r1:r0 on ARM).
9226 // In AMD-64 calling convention a struct of two pointers is returned in rdx:rax.
9227 // In Win64 calling convention, a struct of two pointers is returned in memory,
9228 // allocated by the caller, and passed as a pointer in a hidden first parameter.
9229 #ifdef V8_HOST_ARCH_64_BIT
9230 struct ObjectPair {
9231   Object* x;
9232   Object* y;
9233 };
9234
9235
9236 static inline ObjectPair MakePair(Object* x, Object* y) {
9237   ObjectPair result = {x, y};
9238   // Pointers x and y returned in rax and rdx, in AMD-x64-abi.
9239   // In Win64 they are assigned to a hidden first argument.
9240   return result;
9241 }
9242 #elif V8_TARGET_ARCH_X64 && V8_TARGET_ARCH_32_BIT
9243 // For x32 a 128-bit struct return is done as rax and rdx from the ObjectPair
9244 // are used in the full codegen and Crankshaft compiler. An alternative is
9245 // using uint64_t and modifying full codegen and Crankshaft compiler.
9246 struct ObjectPair {
9247   Object* x;
9248   uint32_t x_upper;
9249   Object* y;
9250   uint32_t y_upper;
9251 };
9252
9253
9254 static inline ObjectPair MakePair(Object* x, Object* y) {
9255   ObjectPair result = {x, 0, y, 0};
9256   // Pointers x and y returned in rax and rdx, in x32-abi.
9257   return result;
9258 }
9259 #else
9260 typedef uint64_t ObjectPair;
9261 static inline ObjectPair MakePair(Object* x, Object* y) {
9262 #if defined(V8_TARGET_LITTLE_ENDIAN)
9263   return reinterpret_cast<uint32_t>(x) |
9264       (reinterpret_cast<ObjectPair>(y) << 32);
9265 #elif defined(V8_TARGET_BIG_ENDIAN)
9266     return reinterpret_cast<uint32_t>(y) |
9267         (reinterpret_cast<ObjectPair>(x) << 32);
9268 #else
9269 #error Unknown endianness
9270 #endif
9271 }
9272 #endif
9273
9274
9275 static Object* ComputeReceiverForNonGlobal(Isolate* isolate,
9276                                            JSObject* holder) {
9277   DCHECK(!holder->IsGlobalObject());
9278   Context* top = isolate->context();
9279   // Get the context extension function.
9280   JSFunction* context_extension_function =
9281       top->native_context()->context_extension_function();
9282   // If the holder isn't a context extension object, we just return it
9283   // as the receiver. This allows arguments objects to be used as
9284   // receivers, but only if they are put in the context scope chain
9285   // explicitly via a with-statement.
9286   Object* constructor = holder->map()->constructor();
9287   if (constructor != context_extension_function) return holder;
9288   // Fall back to using the global object as the implicit receiver if
9289   // the property turns out to be a local variable allocated in a
9290   // context extension object - introduced via eval.
9291   return isolate->heap()->undefined_value();
9292 }
9293
9294
9295 static ObjectPair LoadLookupSlotHelper(Arguments args, Isolate* isolate,
9296                                        bool throw_error) {
9297   HandleScope scope(isolate);
9298   DCHECK_EQ(2, args.length());
9299
9300   if (!args[0]->IsContext() || !args[1]->IsString()) {
9301     return MakePair(isolate->ThrowIllegalOperation(), NULL);
9302   }
9303   Handle<Context> context = args.at<Context>(0);
9304   Handle<String> name = args.at<String>(1);
9305
9306   int index;
9307   PropertyAttributes attributes;
9308   ContextLookupFlags flags = FOLLOW_CHAINS;
9309   BindingFlags binding_flags;
9310   Handle<Object> holder = context->Lookup(name,
9311                                           flags,
9312                                           &index,
9313                                           &attributes,
9314                                           &binding_flags);
9315   if (isolate->has_pending_exception()) {
9316     return MakePair(isolate->heap()->exception(), NULL);
9317   }
9318
9319   // If the index is non-negative, the slot has been found in a context.
9320   if (index >= 0) {
9321     DCHECK(holder->IsContext());
9322     // If the "property" we were looking for is a local variable, the
9323     // receiver is the global object; see ECMA-262, 3rd., 10.1.6 and 10.2.3.
9324     Handle<Object> receiver = isolate->factory()->undefined_value();
9325     Object* value = Context::cast(*holder)->get(index);
9326     // Check for uninitialized bindings.
9327     switch (binding_flags) {
9328       case MUTABLE_CHECK_INITIALIZED:
9329       case IMMUTABLE_CHECK_INITIALIZED_HARMONY:
9330         if (value->IsTheHole()) {
9331           Handle<Object> reference_error =
9332               isolate->factory()->NewReferenceError("not_defined",
9333                                                     HandleVector(&name, 1));
9334           return MakePair(isolate->Throw(*reference_error), NULL);
9335         }
9336         // FALLTHROUGH
9337       case MUTABLE_IS_INITIALIZED:
9338       case IMMUTABLE_IS_INITIALIZED:
9339       case IMMUTABLE_IS_INITIALIZED_HARMONY:
9340         DCHECK(!value->IsTheHole());
9341         return MakePair(value, *receiver);
9342       case IMMUTABLE_CHECK_INITIALIZED:
9343         if (value->IsTheHole()) {
9344           DCHECK((attributes & READ_ONLY) != 0);
9345           value = isolate->heap()->undefined_value();
9346         }
9347         return MakePair(value, *receiver);
9348       case MISSING_BINDING:
9349         UNREACHABLE();
9350         return MakePair(NULL, NULL);
9351     }
9352   }
9353
9354   // Otherwise, if the slot was found the holder is a context extension
9355   // object, subject of a with, or a global object.  We read the named
9356   // property from it.
9357   if (!holder.is_null()) {
9358     Handle<JSReceiver> object = Handle<JSReceiver>::cast(holder);
9359 #ifdef DEBUG
9360     if (!object->IsJSProxy()) {
9361       Maybe<bool> maybe = JSReceiver::HasProperty(object, name);
9362       DCHECK(maybe.has_value);
9363       DCHECK(maybe.value);
9364     }
9365 #endif
9366     // GetProperty below can cause GC.
9367     Handle<Object> receiver_handle(
9368         object->IsGlobalObject()
9369             ? Object::cast(isolate->heap()->undefined_value())
9370             : object->IsJSProxy() ? static_cast<Object*>(*object)
9371                 : ComputeReceiverForNonGlobal(isolate, JSObject::cast(*object)),
9372         isolate);
9373
9374     // No need to unhole the value here.  This is taken care of by the
9375     // GetProperty function.
9376     Handle<Object> value;
9377     ASSIGN_RETURN_ON_EXCEPTION_VALUE(
9378         isolate, value,
9379         Object::GetProperty(object, name),
9380         MakePair(isolate->heap()->exception(), NULL));
9381     return MakePair(*value, *receiver_handle);
9382   }
9383
9384   if (throw_error) {
9385     // The property doesn't exist - throw exception.
9386     Handle<Object> reference_error =
9387         isolate->factory()->NewReferenceError("not_defined",
9388                                               HandleVector(&name, 1));
9389     return MakePair(isolate->Throw(*reference_error), NULL);
9390   } else {
9391     // The property doesn't exist - return undefined.
9392     return MakePair(isolate->heap()->undefined_value(),
9393                     isolate->heap()->undefined_value());
9394   }
9395 }
9396
9397
9398 RUNTIME_FUNCTION_RETURN_PAIR(Runtime_LoadLookupSlot) {
9399   return LoadLookupSlotHelper(args, isolate, true);
9400 }
9401
9402
9403 RUNTIME_FUNCTION_RETURN_PAIR(Runtime_LoadLookupSlotNoReferenceError) {
9404   return LoadLookupSlotHelper(args, isolate, false);
9405 }
9406
9407
9408 RUNTIME_FUNCTION(Runtime_StoreLookupSlot) {
9409   HandleScope scope(isolate);
9410   DCHECK(args.length() == 4);
9411
9412   CONVERT_ARG_HANDLE_CHECKED(Object, value, 0);
9413   CONVERT_ARG_HANDLE_CHECKED(Context, context, 1);
9414   CONVERT_ARG_HANDLE_CHECKED(String, name, 2);
9415   CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 3);
9416
9417   int index;
9418   PropertyAttributes attributes;
9419   ContextLookupFlags flags = FOLLOW_CHAINS;
9420   BindingFlags binding_flags;
9421   Handle<Object> holder = context->Lookup(name,
9422                                           flags,
9423                                           &index,
9424                                           &attributes,
9425                                           &binding_flags);
9426   // In case of JSProxy, an exception might have been thrown.
9427   if (isolate->has_pending_exception()) return isolate->heap()->exception();
9428
9429   // The property was found in a context slot.
9430   if (index >= 0) {
9431     if ((attributes & READ_ONLY) == 0) {
9432       Handle<Context>::cast(holder)->set(index, *value);
9433     } else if (strict_mode == STRICT) {
9434       // Setting read only property in strict mode.
9435       Handle<Object> error =
9436           isolate->factory()->NewTypeError("strict_cannot_assign",
9437                                            HandleVector(&name, 1));
9438       return isolate->Throw(*error);
9439     }
9440     return *value;
9441   }
9442
9443   // Slow case: The property is not in a context slot.  It is either in a
9444   // context extension object, a property of the subject of a with, or a
9445   // property of the global object.
9446   Handle<JSReceiver> object;
9447   if (attributes != ABSENT) {
9448     // The property exists on the holder.
9449     object = Handle<JSReceiver>::cast(holder);
9450   } else if (strict_mode == STRICT) {
9451     // If absent in strict mode: throw.
9452     Handle<Object> error = isolate->factory()->NewReferenceError(
9453         "not_defined", HandleVector(&name, 1));
9454     return isolate->Throw(*error);
9455   } else {
9456     // If absent in sloppy mode: add the property to the global object.
9457     object = Handle<JSReceiver>(context->global_object());
9458   }
9459
9460   RETURN_FAILURE_ON_EXCEPTION(
9461       isolate, Object::SetProperty(object, name, value, strict_mode));
9462
9463   return *value;
9464 }
9465
9466
9467 RUNTIME_FUNCTION(Runtime_Throw) {
9468   HandleScope scope(isolate);
9469   DCHECK(args.length() == 1);
9470
9471   return isolate->Throw(args[0]);
9472 }
9473
9474
9475 RUNTIME_FUNCTION(Runtime_ReThrow) {
9476   HandleScope scope(isolate);
9477   DCHECK(args.length() == 1);
9478
9479   return isolate->ReThrow(args[0]);
9480 }
9481
9482
9483 RUNTIME_FUNCTION(Runtime_PromoteScheduledException) {
9484   SealHandleScope shs(isolate);
9485   DCHECK(args.length() == 0);
9486   return isolate->PromoteScheduledException();
9487 }
9488
9489
9490 RUNTIME_FUNCTION(Runtime_ThrowReferenceError) {
9491   HandleScope scope(isolate);
9492   DCHECK(args.length() == 1);
9493   CONVERT_ARG_HANDLE_CHECKED(Object, name, 0);
9494   Handle<Object> reference_error =
9495     isolate->factory()->NewReferenceError("not_defined",
9496                                           HandleVector(&name, 1));
9497   return isolate->Throw(*reference_error);
9498 }
9499
9500
9501 RUNTIME_FUNCTION(Runtime_ThrowNotDateError) {
9502   HandleScope scope(isolate);
9503   DCHECK(args.length() == 0);
9504   return isolate->Throw(*isolate->factory()->NewTypeError(
9505       "not_date_object", HandleVector<Object>(NULL, 0)));
9506 }
9507
9508
9509 RUNTIME_FUNCTION(Runtime_StackGuard) {
9510   SealHandleScope shs(isolate);
9511   DCHECK(args.length() == 0);
9512
9513   // First check if this is a real stack overflow.
9514   StackLimitCheck check(isolate);
9515   if (check.JsHasOverflowed()) {
9516     return isolate->StackOverflow();
9517   }
9518
9519   return isolate->stack_guard()->HandleInterrupts();
9520 }
9521
9522
9523 RUNTIME_FUNCTION(Runtime_TryInstallOptimizedCode) {
9524   HandleScope scope(isolate);
9525   DCHECK(args.length() == 1);
9526   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
9527
9528   // First check if this is a real stack overflow.
9529   StackLimitCheck check(isolate);
9530   if (check.JsHasOverflowed()) {
9531     SealHandleScope shs(isolate);
9532     return isolate->StackOverflow();
9533   }
9534
9535   isolate->optimizing_compiler_thread()->InstallOptimizedFunctions();
9536   return (function->IsOptimized()) ? function->code()
9537                                    : function->shared()->code();
9538 }
9539
9540
9541 RUNTIME_FUNCTION(Runtime_Interrupt) {
9542   SealHandleScope shs(isolate);
9543   DCHECK(args.length() == 0);
9544   return isolate->stack_guard()->HandleInterrupts();
9545 }
9546
9547
9548 static int StackSize(Isolate* isolate) {
9549   int n = 0;
9550   for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) n++;
9551   return n;
9552 }
9553
9554
9555 static void PrintTransition(Isolate* isolate, Object* result) {
9556   // indentation
9557   { const int nmax = 80;
9558     int n = StackSize(isolate);
9559     if (n <= nmax)
9560       PrintF("%4d:%*s", n, n, "");
9561     else
9562       PrintF("%4d:%*s", n, nmax, "...");
9563   }
9564
9565   if (result == NULL) {
9566     JavaScriptFrame::PrintTop(isolate, stdout, true, false);
9567     PrintF(" {\n");
9568   } else {
9569     // function result
9570     PrintF("} -> ");
9571     result->ShortPrint();
9572     PrintF("\n");
9573   }
9574 }
9575
9576
9577 RUNTIME_FUNCTION(Runtime_TraceEnter) {
9578   SealHandleScope shs(isolate);
9579   DCHECK(args.length() == 0);
9580   PrintTransition(isolate, NULL);
9581   return isolate->heap()->undefined_value();
9582 }
9583
9584
9585 RUNTIME_FUNCTION(Runtime_TraceExit) {
9586   SealHandleScope shs(isolate);
9587   DCHECK(args.length() == 1);
9588   CONVERT_ARG_CHECKED(Object, obj, 0);
9589   PrintTransition(isolate, obj);
9590   return obj;  // return TOS
9591 }
9592
9593
9594 RUNTIME_FUNCTION(Runtime_DebugPrint) {
9595   SealHandleScope shs(isolate);
9596   DCHECK(args.length() == 1);
9597
9598   OFStream os(stdout);
9599 #ifdef DEBUG
9600   if (args[0]->IsString()) {
9601     // If we have a string, assume it's a code "marker"
9602     // and print some interesting cpu debugging info.
9603     JavaScriptFrameIterator it(isolate);
9604     JavaScriptFrame* frame = it.frame();
9605     os << "fp = " << frame->fp() << ", sp = " << frame->sp()
9606        << ", caller_sp = " << frame->caller_sp() << ": ";
9607   } else {
9608     os << "DebugPrint: ";
9609   }
9610   args[0]->Print(os);
9611   if (args[0]->IsHeapObject()) {
9612     os << "\n";
9613     HeapObject::cast(args[0])->map()->Print(os);
9614   }
9615 #else
9616   // ShortPrint is available in release mode. Print is not.
9617   os << Brief(args[0]);
9618 #endif
9619   os << endl;
9620
9621   return args[0];  // return TOS
9622 }
9623
9624
9625 RUNTIME_FUNCTION(Runtime_DebugTrace) {
9626   SealHandleScope shs(isolate);
9627   DCHECK(args.length() == 0);
9628   isolate->PrintStack(stdout);
9629   return isolate->heap()->undefined_value();
9630 }
9631
9632
9633 RUNTIME_FUNCTION(Runtime_DateCurrentTime) {
9634   HandleScope scope(isolate);
9635   DCHECK(args.length() == 0);
9636   if (FLAG_log_timer_events) LOG(isolate, CurrentTimeEvent());
9637
9638   // According to ECMA-262, section 15.9.1, page 117, the precision of
9639   // the number in a Date object representing a particular instant in
9640   // time is milliseconds. Therefore, we floor the result of getting
9641   // the OS time.
9642   double millis;
9643   if (FLAG_verify_predictable) {
9644     millis = 1388534400000.0;  // Jan 1 2014 00:00:00 GMT+0000
9645     millis += Floor(isolate->heap()->synthetic_time());
9646   } else {
9647     millis = Floor(base::OS::TimeCurrentMillis());
9648   }
9649   return *isolate->factory()->NewNumber(millis);
9650 }
9651
9652
9653 RUNTIME_FUNCTION(Runtime_DateParseString) {
9654   HandleScope scope(isolate);
9655   DCHECK(args.length() == 2);
9656   CONVERT_ARG_HANDLE_CHECKED(String, str, 0);
9657   CONVERT_ARG_HANDLE_CHECKED(JSArray, output, 1);
9658
9659   RUNTIME_ASSERT(output->HasFastElements());
9660   JSObject::EnsureCanContainHeapObjectElements(output);
9661   RUNTIME_ASSERT(output->HasFastObjectElements());
9662   Handle<FixedArray> output_array(FixedArray::cast(output->elements()));
9663   RUNTIME_ASSERT(output_array->length() >= DateParser::OUTPUT_SIZE);
9664
9665   str = String::Flatten(str);
9666   DisallowHeapAllocation no_gc;
9667
9668   bool result;
9669   String::FlatContent str_content = str->GetFlatContent();
9670   if (str_content.IsAscii()) {
9671     result = DateParser::Parse(str_content.ToOneByteVector(),
9672                                *output_array,
9673                                isolate->unicode_cache());
9674   } else {
9675     DCHECK(str_content.IsTwoByte());
9676     result = DateParser::Parse(str_content.ToUC16Vector(),
9677                                *output_array,
9678                                isolate->unicode_cache());
9679   }
9680
9681   if (result) {
9682     return *output;
9683   } else {
9684     return isolate->heap()->null_value();
9685   }
9686 }
9687
9688
9689 RUNTIME_FUNCTION(Runtime_DateLocalTimezone) {
9690   HandleScope scope(isolate);
9691   DCHECK(args.length() == 1);
9692
9693   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
9694   RUNTIME_ASSERT(x >= -DateCache::kMaxTimeBeforeUTCInMs &&
9695                  x <= DateCache::kMaxTimeBeforeUTCInMs);
9696   const char* zone =
9697       isolate->date_cache()->LocalTimezone(static_cast<int64_t>(x));
9698   Handle<String> result = isolate->factory()->NewStringFromUtf8(
9699       CStrVector(zone)).ToHandleChecked();
9700   return *result;
9701 }
9702
9703
9704 RUNTIME_FUNCTION(Runtime_DateToUTC) {
9705   HandleScope scope(isolate);
9706   DCHECK(args.length() == 1);
9707
9708   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
9709   RUNTIME_ASSERT(x >= -DateCache::kMaxTimeBeforeUTCInMs &&
9710                  x <= DateCache::kMaxTimeBeforeUTCInMs);
9711   int64_t time = isolate->date_cache()->ToUTC(static_cast<int64_t>(x));
9712
9713   return *isolate->factory()->NewNumber(static_cast<double>(time));
9714 }
9715
9716
9717 RUNTIME_FUNCTION(Runtime_DateCacheVersion) {
9718   HandleScope hs(isolate);
9719   DCHECK(args.length() == 0);
9720   if (!isolate->eternal_handles()->Exists(EternalHandles::DATE_CACHE_VERSION)) {
9721     Handle<FixedArray> date_cache_version =
9722         isolate->factory()->NewFixedArray(1, TENURED);
9723     date_cache_version->set(0, Smi::FromInt(0));
9724     isolate->eternal_handles()->CreateSingleton(
9725         isolate, *date_cache_version, EternalHandles::DATE_CACHE_VERSION);
9726   }
9727   Handle<FixedArray> date_cache_version =
9728       Handle<FixedArray>::cast(isolate->eternal_handles()->GetSingleton(
9729           EternalHandles::DATE_CACHE_VERSION));
9730   // Return result as a JS array.
9731   Handle<JSObject> result =
9732       isolate->factory()->NewJSObject(isolate->array_function());
9733   JSArray::SetContent(Handle<JSArray>::cast(result), date_cache_version);
9734   return *result;
9735 }
9736
9737
9738 RUNTIME_FUNCTION(Runtime_GlobalProxy) {
9739   SealHandleScope shs(isolate);
9740   DCHECK(args.length() == 1);
9741   CONVERT_ARG_CHECKED(Object, global, 0);
9742   if (!global->IsJSGlobalObject()) return isolate->heap()->null_value();
9743   return JSGlobalObject::cast(global)->global_proxy();
9744 }
9745
9746
9747 RUNTIME_FUNCTION(Runtime_IsAttachedGlobal) {
9748   SealHandleScope shs(isolate);
9749   DCHECK(args.length() == 1);
9750   CONVERT_ARG_CHECKED(Object, global, 0);
9751   if (!global->IsJSGlobalObject()) return isolate->heap()->false_value();
9752   return isolate->heap()->ToBoolean(
9753       !JSGlobalObject::cast(global)->IsDetached());
9754 }
9755
9756
9757 RUNTIME_FUNCTION(Runtime_ParseJson) {
9758   HandleScope scope(isolate);
9759   DCHECK(args.length() == 1);
9760   CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
9761
9762   source = String::Flatten(source);
9763   // Optimized fast case where we only have ASCII characters.
9764   Handle<Object> result;
9765   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
9766       isolate, result,
9767       source->IsSeqOneByteString() ? JsonParser<true>::Parse(source)
9768                                    : JsonParser<false>::Parse(source));
9769   return *result;
9770 }
9771
9772
9773 bool CodeGenerationFromStringsAllowed(Isolate* isolate,
9774                                       Handle<Context> context) {
9775   DCHECK(context->allow_code_gen_from_strings()->IsFalse());
9776   // Check with callback if set.
9777   AllowCodeGenerationFromStringsCallback callback =
9778       isolate->allow_code_gen_callback();
9779   if (callback == NULL) {
9780     // No callback set and code generation disallowed.
9781     return false;
9782   } else {
9783     // Callback set. Let it decide if code generation is allowed.
9784     VMState<EXTERNAL> state(isolate);
9785     return callback(v8::Utils::ToLocal(context));
9786   }
9787 }
9788
9789
9790 // Walk up the stack expecting:
9791 //  - Runtime_CompileString
9792 //  - JSFunction callee (eval, Function constructor, etc)
9793 //  - call() (maybe)
9794 //  - apply() (maybe)
9795 //  - bind() (maybe)
9796 // - JSFunction caller (maybe)
9797 //
9798 // return true if the caller has the same security token as the callee
9799 // or if an exit frame was hit, in which case allow it through, as it could
9800 // have come through the api.
9801 static bool TokensMatchForCompileString(Isolate* isolate) {
9802   MaybeHandle<JSFunction> callee;
9803   bool exit_handled = true;
9804   bool tokens_match = true;
9805   bool done = false;
9806   for (StackFrameIterator it(isolate); !it.done() && !done; it.Advance()) {
9807     StackFrame* raw_frame = it.frame();
9808     if (!raw_frame->is_java_script()) {
9809       if (raw_frame->is_exit()) exit_handled = false;
9810       continue;
9811     }
9812     JavaScriptFrame* outer_frame = JavaScriptFrame::cast(raw_frame);
9813     List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
9814     outer_frame->Summarize(&frames);
9815     for (int i = frames.length() - 1; i >= 0 && !done; --i) {
9816       FrameSummary& frame = frames[i];
9817       Handle<JSFunction> fun = frame.function();
9818       // Capture the callee function.
9819       if (callee.is_null()) {
9820         callee = fun;
9821         exit_handled = true;
9822         continue;
9823       }
9824       // Exit condition.
9825       Handle<Context> context(callee.ToHandleChecked()->context());
9826       if (!fun->context()->HasSameSecurityTokenAs(*context)) {
9827         tokens_match = false;
9828         done = true;
9829         continue;
9830       }
9831       // Skip bound functions in correct origin.
9832       if (fun->shared()->bound()) {
9833         exit_handled = true;
9834         continue;
9835       }
9836       done = true;
9837     }
9838   }
9839   return !exit_handled || tokens_match;
9840 }
9841
9842
9843 RUNTIME_FUNCTION(Runtime_CompileString) {
9844   HandleScope scope(isolate);
9845   DCHECK(args.length() == 2);
9846   CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
9847   CONVERT_BOOLEAN_ARG_CHECKED(function_literal_only, 1);
9848
9849   // Extract native context.
9850   Handle<Context> context(isolate->native_context());
9851
9852   // Filter cross security context calls.
9853   if (!TokensMatchForCompileString(isolate)) {
9854     return isolate->heap()->undefined_value();
9855   }
9856
9857   // Check if native context allows code generation from
9858   // strings. Throw an exception if it doesn't.
9859   if (context->allow_code_gen_from_strings()->IsFalse() &&
9860       !CodeGenerationFromStringsAllowed(isolate, context)) {
9861     Handle<Object> error_message =
9862         context->ErrorMessageForCodeGenerationFromStrings();
9863     return isolate->Throw(*isolate->factory()->NewEvalError(
9864         "code_gen_from_strings", HandleVector<Object>(&error_message, 1)));
9865   }
9866
9867   // Compile source string in the native context.
9868   ParseRestriction restriction = function_literal_only
9869       ? ONLY_SINGLE_FUNCTION_LITERAL : NO_PARSE_RESTRICTION;
9870   Handle<JSFunction> fun;
9871   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
9872       isolate, fun,
9873       Compiler::GetFunctionFromEval(
9874           source, context, SLOPPY, restriction, RelocInfo::kNoPosition));
9875   return *fun;
9876 }
9877
9878
9879 static ObjectPair CompileGlobalEval(Isolate* isolate,
9880                                     Handle<String> source,
9881                                     Handle<Object> receiver,
9882                                     StrictMode strict_mode,
9883                                     int scope_position) {
9884   Handle<Context> context = Handle<Context>(isolate->context());
9885   Handle<Context> native_context = Handle<Context>(context->native_context());
9886
9887   // Check if native context allows code generation from
9888   // strings. Throw an exception if it doesn't.
9889   if (native_context->allow_code_gen_from_strings()->IsFalse() &&
9890       !CodeGenerationFromStringsAllowed(isolate, native_context)) {
9891     Handle<Object> error_message =
9892         native_context->ErrorMessageForCodeGenerationFromStrings();
9893     isolate->Throw(*isolate->factory()->NewEvalError(
9894         "code_gen_from_strings", HandleVector<Object>(&error_message, 1)));
9895     return MakePair(isolate->heap()->exception(), NULL);
9896   }
9897
9898   // Deal with a normal eval call with a string argument. Compile it
9899   // and return the compiled function bound in the local context.
9900   static const ParseRestriction restriction = NO_PARSE_RESTRICTION;
9901   Handle<JSFunction> compiled;
9902   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
9903       isolate, compiled,
9904       Compiler::GetFunctionFromEval(
9905           source, context, strict_mode, restriction, scope_position),
9906       MakePair(isolate->heap()->exception(), NULL));
9907   return MakePair(*compiled, *receiver);
9908 }
9909
9910
9911 RUNTIME_FUNCTION_RETURN_PAIR(Runtime_ResolvePossiblyDirectEval) {
9912   HandleScope scope(isolate);
9913   DCHECK(args.length() == 5);
9914
9915   Handle<Object> callee = args.at<Object>(0);
9916
9917   // If "eval" didn't refer to the original GlobalEval, it's not a
9918   // direct call to eval.
9919   // (And even if it is, but the first argument isn't a string, just let
9920   // execution default to an indirect call to eval, which will also return
9921   // the first argument without doing anything).
9922   if (*callee != isolate->native_context()->global_eval_fun() ||
9923       !args[1]->IsString()) {
9924     return MakePair(*callee, isolate->heap()->undefined_value());
9925   }
9926
9927   DCHECK(args[3]->IsSmi());
9928   DCHECK(args.smi_at(3) == SLOPPY || args.smi_at(3) == STRICT);
9929   StrictMode strict_mode = static_cast<StrictMode>(args.smi_at(3));
9930   DCHECK(args[4]->IsSmi());
9931   return CompileGlobalEval(isolate,
9932                            args.at<String>(1),
9933                            args.at<Object>(2),
9934                            strict_mode,
9935                            args.smi_at(4));
9936 }
9937
9938
9939 RUNTIME_FUNCTION(Runtime_AllocateInNewSpace) {
9940   HandleScope scope(isolate);
9941   DCHECK(args.length() == 1);
9942   CONVERT_SMI_ARG_CHECKED(size, 0);
9943   RUNTIME_ASSERT(IsAligned(size, kPointerSize));
9944   RUNTIME_ASSERT(size > 0);
9945   RUNTIME_ASSERT(size <= Page::kMaxRegularHeapObjectSize);
9946   return *isolate->factory()->NewFillerObject(size, false, NEW_SPACE);
9947 }
9948
9949
9950 RUNTIME_FUNCTION(Runtime_AllocateInTargetSpace) {
9951   HandleScope scope(isolate);
9952   DCHECK(args.length() == 2);
9953   CONVERT_SMI_ARG_CHECKED(size, 0);
9954   CONVERT_SMI_ARG_CHECKED(flags, 1);
9955   RUNTIME_ASSERT(IsAligned(size, kPointerSize));
9956   RUNTIME_ASSERT(size > 0);
9957   RUNTIME_ASSERT(size <= Page::kMaxRegularHeapObjectSize);
9958   bool double_align = AllocateDoubleAlignFlag::decode(flags);
9959   AllocationSpace space = AllocateTargetSpace::decode(flags);
9960   return *isolate->factory()->NewFillerObject(size, double_align, space);
9961 }
9962
9963
9964 // Push an object unto an array of objects if it is not already in the
9965 // array.  Returns true if the element was pushed on the stack and
9966 // false otherwise.
9967 RUNTIME_FUNCTION(Runtime_PushIfAbsent) {
9968   HandleScope scope(isolate);
9969   DCHECK(args.length() == 2);
9970   CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
9971   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, element, 1);
9972   RUNTIME_ASSERT(array->HasFastSmiOrObjectElements());
9973   int length = Smi::cast(array->length())->value();
9974   FixedArray* elements = FixedArray::cast(array->elements());
9975   for (int i = 0; i < length; i++) {
9976     if (elements->get(i) == *element) return isolate->heap()->false_value();
9977   }
9978
9979   // Strict not needed. Used for cycle detection in Array join implementation.
9980   RETURN_FAILURE_ON_EXCEPTION(
9981       isolate,
9982       JSObject::SetFastElement(array, length, element, SLOPPY, true));
9983   return isolate->heap()->true_value();
9984 }
9985
9986
9987 /**
9988  * A simple visitor visits every element of Array's.
9989  * The backend storage can be a fixed array for fast elements case,
9990  * or a dictionary for sparse array. Since Dictionary is a subtype
9991  * of FixedArray, the class can be used by both fast and slow cases.
9992  * The second parameter of the constructor, fast_elements, specifies
9993  * whether the storage is a FixedArray or Dictionary.
9994  *
9995  * An index limit is used to deal with the situation that a result array
9996  * length overflows 32-bit non-negative integer.
9997  */
9998 class ArrayConcatVisitor {
9999  public:
10000   ArrayConcatVisitor(Isolate* isolate,
10001                      Handle<FixedArray> storage,
10002                      bool fast_elements) :
10003       isolate_(isolate),
10004       storage_(Handle<FixedArray>::cast(
10005           isolate->global_handles()->Create(*storage))),
10006       index_offset_(0u),
10007       fast_elements_(fast_elements),
10008       exceeds_array_limit_(false) { }
10009
10010   ~ArrayConcatVisitor() {
10011     clear_storage();
10012   }
10013
10014   void visit(uint32_t i, Handle<Object> elm) {
10015     if (i > JSObject::kMaxElementCount - index_offset_) {
10016       exceeds_array_limit_ = true;
10017       return;
10018     }
10019     uint32_t index = index_offset_ + i;
10020
10021     if (fast_elements_) {
10022       if (index < static_cast<uint32_t>(storage_->length())) {
10023         storage_->set(index, *elm);
10024         return;
10025       }
10026       // Our initial estimate of length was foiled, possibly by
10027       // getters on the arrays increasing the length of later arrays
10028       // during iteration.
10029       // This shouldn't happen in anything but pathological cases.
10030       SetDictionaryMode();
10031       // Fall-through to dictionary mode.
10032     }
10033     DCHECK(!fast_elements_);
10034     Handle<SeededNumberDictionary> dict(
10035         SeededNumberDictionary::cast(*storage_));
10036     Handle<SeededNumberDictionary> result =
10037         SeededNumberDictionary::AtNumberPut(dict, index, elm);
10038     if (!result.is_identical_to(dict)) {
10039       // Dictionary needed to grow.
10040       clear_storage();
10041       set_storage(*result);
10042     }
10043   }
10044
10045   void increase_index_offset(uint32_t delta) {
10046     if (JSObject::kMaxElementCount - index_offset_ < delta) {
10047       index_offset_ = JSObject::kMaxElementCount;
10048     } else {
10049       index_offset_ += delta;
10050     }
10051     // If the initial length estimate was off (see special case in visit()),
10052     // but the array blowing the limit didn't contain elements beyond the
10053     // provided-for index range, go to dictionary mode now.
10054     if (fast_elements_ &&
10055         index_offset_ >
10056             static_cast<uint32_t>(FixedArrayBase::cast(*storage_)->length())) {
10057       SetDictionaryMode();
10058     }
10059   }
10060
10061   bool exceeds_array_limit() {
10062     return exceeds_array_limit_;
10063   }
10064
10065   Handle<JSArray> ToArray() {
10066     Handle<JSArray> array = isolate_->factory()->NewJSArray(0);
10067     Handle<Object> length =
10068         isolate_->factory()->NewNumber(static_cast<double>(index_offset_));
10069     Handle<Map> map = JSObject::GetElementsTransitionMap(
10070         array,
10071         fast_elements_ ? FAST_HOLEY_ELEMENTS : DICTIONARY_ELEMENTS);
10072     array->set_map(*map);
10073     array->set_length(*length);
10074     array->set_elements(*storage_);
10075     return array;
10076   }
10077
10078  private:
10079   // Convert storage to dictionary mode.
10080   void SetDictionaryMode() {
10081     DCHECK(fast_elements_);
10082     Handle<FixedArray> current_storage(*storage_);
10083     Handle<SeededNumberDictionary> slow_storage(
10084         SeededNumberDictionary::New(isolate_, current_storage->length()));
10085     uint32_t current_length = static_cast<uint32_t>(current_storage->length());
10086     for (uint32_t i = 0; i < current_length; i++) {
10087       HandleScope loop_scope(isolate_);
10088       Handle<Object> element(current_storage->get(i), isolate_);
10089       if (!element->IsTheHole()) {
10090         Handle<SeededNumberDictionary> new_storage =
10091             SeededNumberDictionary::AtNumberPut(slow_storage, i, element);
10092         if (!new_storage.is_identical_to(slow_storage)) {
10093           slow_storage = loop_scope.CloseAndEscape(new_storage);
10094         }
10095       }
10096     }
10097     clear_storage();
10098     set_storage(*slow_storage);
10099     fast_elements_ = false;
10100   }
10101
10102   inline void clear_storage() {
10103     GlobalHandles::Destroy(Handle<Object>::cast(storage_).location());
10104   }
10105
10106   inline void set_storage(FixedArray* storage) {
10107     storage_ = Handle<FixedArray>::cast(
10108         isolate_->global_handles()->Create(storage));
10109   }
10110
10111   Isolate* isolate_;
10112   Handle<FixedArray> storage_;  // Always a global handle.
10113   // Index after last seen index. Always less than or equal to
10114   // JSObject::kMaxElementCount.
10115   uint32_t index_offset_;
10116   bool fast_elements_ : 1;
10117   bool exceeds_array_limit_ : 1;
10118 };
10119
10120
10121 static uint32_t EstimateElementCount(Handle<JSArray> array) {
10122   uint32_t length = static_cast<uint32_t>(array->length()->Number());
10123   int element_count = 0;
10124   switch (array->GetElementsKind()) {
10125     case FAST_SMI_ELEMENTS:
10126     case FAST_HOLEY_SMI_ELEMENTS:
10127     case FAST_ELEMENTS:
10128     case FAST_HOLEY_ELEMENTS: {
10129       // Fast elements can't have lengths that are not representable by
10130       // a 32-bit signed integer.
10131       DCHECK(static_cast<int32_t>(FixedArray::kMaxLength) >= 0);
10132       int fast_length = static_cast<int>(length);
10133       Handle<FixedArray> elements(FixedArray::cast(array->elements()));
10134       for (int i = 0; i < fast_length; i++) {
10135         if (!elements->get(i)->IsTheHole()) element_count++;
10136       }
10137       break;
10138     }
10139     case FAST_DOUBLE_ELEMENTS:
10140     case FAST_HOLEY_DOUBLE_ELEMENTS: {
10141       // Fast elements can't have lengths that are not representable by
10142       // a 32-bit signed integer.
10143       DCHECK(static_cast<int32_t>(FixedDoubleArray::kMaxLength) >= 0);
10144       int fast_length = static_cast<int>(length);
10145       if (array->elements()->IsFixedArray()) {
10146         DCHECK(FixedArray::cast(array->elements())->length() == 0);
10147         break;
10148       }
10149       Handle<FixedDoubleArray> elements(
10150           FixedDoubleArray::cast(array->elements()));
10151       for (int i = 0; i < fast_length; i++) {
10152         if (!elements->is_the_hole(i)) element_count++;
10153       }
10154       break;
10155     }
10156     case DICTIONARY_ELEMENTS: {
10157       Handle<SeededNumberDictionary> dictionary(
10158           SeededNumberDictionary::cast(array->elements()));
10159       int capacity = dictionary->Capacity();
10160       for (int i = 0; i < capacity; i++) {
10161         Handle<Object> key(dictionary->KeyAt(i), array->GetIsolate());
10162         if (dictionary->IsKey(*key)) {
10163           element_count++;
10164         }
10165       }
10166       break;
10167     }
10168     case SLOPPY_ARGUMENTS_ELEMENTS:
10169 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size)                      \
10170     case EXTERNAL_##TYPE##_ELEMENTS:                                         \
10171     case TYPE##_ELEMENTS:                                                    \
10172
10173     TYPED_ARRAYS(TYPED_ARRAY_CASE)
10174 #undef TYPED_ARRAY_CASE
10175       // External arrays are always dense.
10176       return length;
10177   }
10178   // As an estimate, we assume that the prototype doesn't contain any
10179   // inherited elements.
10180   return element_count;
10181 }
10182
10183
10184
10185 template<class ExternalArrayClass, class ElementType>
10186 static void IterateExternalArrayElements(Isolate* isolate,
10187                                          Handle<JSObject> receiver,
10188                                          bool elements_are_ints,
10189                                          bool elements_are_guaranteed_smis,
10190                                          ArrayConcatVisitor* visitor) {
10191   Handle<ExternalArrayClass> array(
10192       ExternalArrayClass::cast(receiver->elements()));
10193   uint32_t len = static_cast<uint32_t>(array->length());
10194
10195   DCHECK(visitor != NULL);
10196   if (elements_are_ints) {
10197     if (elements_are_guaranteed_smis) {
10198       for (uint32_t j = 0; j < len; j++) {
10199         HandleScope loop_scope(isolate);
10200         Handle<Smi> e(Smi::FromInt(static_cast<int>(array->get_scalar(j))),
10201                       isolate);
10202         visitor->visit(j, e);
10203       }
10204     } else {
10205       for (uint32_t j = 0; j < len; j++) {
10206         HandleScope loop_scope(isolate);
10207         int64_t val = static_cast<int64_t>(array->get_scalar(j));
10208         if (Smi::IsValid(static_cast<intptr_t>(val))) {
10209           Handle<Smi> e(Smi::FromInt(static_cast<int>(val)), isolate);
10210           visitor->visit(j, e);
10211         } else {
10212           Handle<Object> e =
10213               isolate->factory()->NewNumber(static_cast<ElementType>(val));
10214           visitor->visit(j, e);
10215         }
10216       }
10217     }
10218   } else {
10219     for (uint32_t j = 0; j < len; j++) {
10220       HandleScope loop_scope(isolate);
10221       Handle<Object> e = isolate->factory()->NewNumber(array->get_scalar(j));
10222       visitor->visit(j, e);
10223     }
10224   }
10225 }
10226
10227
10228 static void IterateExternalFloat32x4ArrayElements(Isolate* isolate,
10229                                                   Handle<JSObject> receiver,
10230                                                   ArrayConcatVisitor* visitor) {
10231   Handle<ExternalFloat32x4Array> array(
10232       ExternalFloat32x4Array::cast(receiver->elements()));
10233   uint32_t len = static_cast<uint32_t>(array->length());
10234
10235   DCHECK(visitor != NULL);
10236   for (uint32_t j = 0; j < len; j++) {
10237     HandleScope loop_scope(isolate);
10238     Handle<Object> e = isolate->factory()->NewFloat32x4(array->get_scalar(j));
10239     visitor->visit(j, e);
10240   }
10241 }
10242
10243
10244 static void IterateExternalFloat64x2ArrayElements(Isolate* isolate,
10245                                                   Handle<JSObject> receiver,
10246                                                   ArrayConcatVisitor* visitor) {
10247   Handle<ExternalFloat64x2Array> array(
10248       ExternalFloat64x2Array::cast(receiver->elements()));
10249   uint32_t len = static_cast<uint32_t>(array->length());
10250
10251   DCHECK(visitor != NULL);
10252   for (uint32_t j = 0; j < len; j++) {
10253     HandleScope loop_scope(isolate);
10254     Handle<Object> e = isolate->factory()->NewFloat64x2(array->get_scalar(j));
10255     visitor->visit(j, e);
10256   }
10257 }
10258
10259
10260 static void IterateExternalInt32x4ArrayElements(Isolate* isolate,
10261                                                  Handle<JSObject> receiver,
10262                                                  ArrayConcatVisitor* visitor) {
10263   Handle<ExternalInt32x4Array> array(
10264       ExternalInt32x4Array::cast(receiver->elements()));
10265   uint32_t len = static_cast<uint32_t>(array->length());
10266
10267   DCHECK(visitor != NULL);
10268   for (uint32_t j = 0; j < len; j++) {
10269     HandleScope loop_scope(isolate);
10270     Handle<Object> e = isolate->factory()->NewInt32x4(array->get_scalar(j));
10271     visitor->visit(j, e);
10272   }
10273 }
10274
10275
10276 // Used for sorting indices in a List<uint32_t>.
10277 static int compareUInt32(const uint32_t* ap, const uint32_t* bp) {
10278   uint32_t a = *ap;
10279   uint32_t b = *bp;
10280   return (a == b) ? 0 : (a < b) ? -1 : 1;
10281 }
10282
10283
10284 static void CollectElementIndices(Handle<JSObject> object,
10285                                   uint32_t range,
10286                                   List<uint32_t>* indices) {
10287   Isolate* isolate = object->GetIsolate();
10288   ElementsKind kind = object->GetElementsKind();
10289   switch (kind) {
10290     case FAST_SMI_ELEMENTS:
10291     case FAST_ELEMENTS:
10292     case FAST_HOLEY_SMI_ELEMENTS:
10293     case FAST_HOLEY_ELEMENTS: {
10294       Handle<FixedArray> elements(FixedArray::cast(object->elements()));
10295       uint32_t length = static_cast<uint32_t>(elements->length());
10296       if (range < length) length = range;
10297       for (uint32_t i = 0; i < length; i++) {
10298         if (!elements->get(i)->IsTheHole()) {
10299           indices->Add(i);
10300         }
10301       }
10302       break;
10303     }
10304     case FAST_HOLEY_DOUBLE_ELEMENTS:
10305     case FAST_DOUBLE_ELEMENTS: {
10306       // TODO(1810): Decide if it's worthwhile to implement this.
10307       UNREACHABLE();
10308       break;
10309     }
10310     case DICTIONARY_ELEMENTS: {
10311       Handle<SeededNumberDictionary> dict(
10312           SeededNumberDictionary::cast(object->elements()));
10313       uint32_t capacity = dict->Capacity();
10314       for (uint32_t j = 0; j < capacity; j++) {
10315         HandleScope loop_scope(isolate);
10316         Handle<Object> k(dict->KeyAt(j), isolate);
10317         if (dict->IsKey(*k)) {
10318           DCHECK(k->IsNumber());
10319           uint32_t index = static_cast<uint32_t>(k->Number());
10320           if (index < range) {
10321             indices->Add(index);
10322           }
10323         }
10324       }
10325       break;
10326     }
10327     default: {
10328       int dense_elements_length;
10329       switch (kind) {
10330 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size)                        \
10331         case EXTERNAL_##TYPE##_ELEMENTS: {                                     \
10332           dense_elements_length =                                              \
10333               External##Type##Array::cast(object->elements())->length();       \
10334           break;                                                               \
10335         }
10336
10337         TYPED_ARRAYS(TYPED_ARRAY_CASE)
10338 #undef TYPED_ARRAY_CASE
10339
10340         default:
10341           UNREACHABLE();
10342           dense_elements_length = 0;
10343           break;
10344       }
10345       uint32_t length = static_cast<uint32_t>(dense_elements_length);
10346       if (range <= length) {
10347         length = range;
10348         // We will add all indices, so we might as well clear it first
10349         // and avoid duplicates.
10350         indices->Clear();
10351       }
10352       for (uint32_t i = 0; i < length; i++) {
10353         indices->Add(i);
10354       }
10355       if (length == range) return;  // All indices accounted for already.
10356       break;
10357     }
10358   }
10359
10360   PrototypeIterator iter(isolate, object);
10361   if (!iter.IsAtEnd()) {
10362     // The prototype will usually have no inherited element indices,
10363     // but we have to check.
10364     CollectElementIndices(
10365         Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), range,
10366         indices);
10367   }
10368 }
10369
10370
10371 /**
10372  * A helper function that visits elements of a JSArray in numerical
10373  * order.
10374  *
10375  * The visitor argument called for each existing element in the array
10376  * with the element index and the element's value.
10377  * Afterwards it increments the base-index of the visitor by the array
10378  * length.
10379  * Returns false if any access threw an exception, otherwise true.
10380  */
10381 static bool IterateElements(Isolate* isolate,
10382                             Handle<JSArray> receiver,
10383                             ArrayConcatVisitor* visitor) {
10384   uint32_t length = static_cast<uint32_t>(receiver->length()->Number());
10385   switch (receiver->GetElementsKind()) {
10386     case FAST_SMI_ELEMENTS:
10387     case FAST_ELEMENTS:
10388     case FAST_HOLEY_SMI_ELEMENTS:
10389     case FAST_HOLEY_ELEMENTS: {
10390       // Run through the elements FixedArray and use HasElement and GetElement
10391       // to check the prototype for missing elements.
10392       Handle<FixedArray> elements(FixedArray::cast(receiver->elements()));
10393       int fast_length = static_cast<int>(length);
10394       DCHECK(fast_length <= elements->length());
10395       for (int j = 0; j < fast_length; j++) {
10396         HandleScope loop_scope(isolate);
10397         Handle<Object> element_value(elements->get(j), isolate);
10398         if (!element_value->IsTheHole()) {
10399           visitor->visit(j, element_value);
10400         } else {
10401           Maybe<bool> maybe = JSReceiver::HasElement(receiver, j);
10402           if (!maybe.has_value) return false;
10403           if (maybe.value) {
10404             // Call GetElement on receiver, not its prototype, or getters won't
10405             // have the correct receiver.
10406             ASSIGN_RETURN_ON_EXCEPTION_VALUE(
10407                 isolate, element_value,
10408                 Object::GetElement(isolate, receiver, j), false);
10409             visitor->visit(j, element_value);
10410           }
10411         }
10412       }
10413       break;
10414     }
10415     case FAST_HOLEY_DOUBLE_ELEMENTS:
10416     case FAST_DOUBLE_ELEMENTS: {
10417       // Empty array is FixedArray but not FixedDoubleArray.
10418       if (length == 0) break;
10419       // Run through the elements FixedArray and use HasElement and GetElement
10420       // to check the prototype for missing elements.
10421       if (receiver->elements()->IsFixedArray()) {
10422         DCHECK(receiver->elements()->length() == 0);
10423         break;
10424       }
10425       Handle<FixedDoubleArray> elements(
10426           FixedDoubleArray::cast(receiver->elements()));
10427       int fast_length = static_cast<int>(length);
10428       DCHECK(fast_length <= elements->length());
10429       for (int j = 0; j < fast_length; j++) {
10430         HandleScope loop_scope(isolate);
10431         if (!elements->is_the_hole(j)) {
10432           double double_value = elements->get_scalar(j);
10433           Handle<Object> element_value =
10434               isolate->factory()->NewNumber(double_value);
10435           visitor->visit(j, element_value);
10436         } else {
10437           Maybe<bool> maybe = JSReceiver::HasElement(receiver, j);
10438           if (!maybe.has_value) return false;
10439           if (maybe.value) {
10440             // Call GetElement on receiver, not its prototype, or getters won't
10441             // have the correct receiver.
10442             Handle<Object> element_value;
10443             ASSIGN_RETURN_ON_EXCEPTION_VALUE(
10444                 isolate, element_value,
10445                 Object::GetElement(isolate, receiver, j), false);
10446             visitor->visit(j, element_value);
10447           }
10448         }
10449       }
10450       break;
10451     }
10452     case DICTIONARY_ELEMENTS: {
10453       Handle<SeededNumberDictionary> dict(receiver->element_dictionary());
10454       List<uint32_t> indices(dict->Capacity() / 2);
10455       // Collect all indices in the object and the prototypes less
10456       // than length. This might introduce duplicates in the indices list.
10457       CollectElementIndices(receiver, length, &indices);
10458       indices.Sort(&compareUInt32);
10459       int j = 0;
10460       int n = indices.length();
10461       while (j < n) {
10462         HandleScope loop_scope(isolate);
10463         uint32_t index = indices[j];
10464         Handle<Object> element;
10465         ASSIGN_RETURN_ON_EXCEPTION_VALUE(
10466             isolate, element,
10467             Object::GetElement(isolate, receiver, index),
10468             false);
10469         visitor->visit(index, element);
10470         // Skip to next different index (i.e., omit duplicates).
10471         do {
10472           j++;
10473         } while (j < n && indices[j] == index);
10474       }
10475       break;
10476     }
10477     case EXTERNAL_UINT8_CLAMPED_ELEMENTS: {
10478       Handle<ExternalUint8ClampedArray> pixels(ExternalUint8ClampedArray::cast(
10479           receiver->elements()));
10480       for (uint32_t j = 0; j < length; j++) {
10481         Handle<Smi> e(Smi::FromInt(pixels->get_scalar(j)), isolate);
10482         visitor->visit(j, e);
10483       }
10484       break;
10485     }
10486     case EXTERNAL_INT8_ELEMENTS: {
10487       IterateExternalArrayElements<ExternalInt8Array, int8_t>(
10488           isolate, receiver, true, true, visitor);
10489       break;
10490     }
10491     case EXTERNAL_UINT8_ELEMENTS: {
10492       IterateExternalArrayElements<ExternalUint8Array, uint8_t>(
10493           isolate, receiver, true, true, visitor);
10494       break;
10495     }
10496     case EXTERNAL_INT16_ELEMENTS: {
10497       IterateExternalArrayElements<ExternalInt16Array, int16_t>(
10498           isolate, receiver, true, true, visitor);
10499       break;
10500     }
10501     case EXTERNAL_UINT16_ELEMENTS: {
10502       IterateExternalArrayElements<ExternalUint16Array, uint16_t>(
10503           isolate, receiver, true, true, visitor);
10504       break;
10505     }
10506     case EXTERNAL_INT32_ELEMENTS: {
10507       IterateExternalArrayElements<ExternalInt32Array, int32_t>(
10508           isolate, receiver, true, false, visitor);
10509       break;
10510     }
10511     case EXTERNAL_UINT32_ELEMENTS: {
10512       IterateExternalArrayElements<ExternalUint32Array, uint32_t>(
10513           isolate, receiver, true, false, visitor);
10514       break;
10515     }
10516     case EXTERNAL_FLOAT32_ELEMENTS: {
10517       IterateExternalArrayElements<ExternalFloat32Array, float>(
10518           isolate, receiver, false, false, visitor);
10519       break;
10520     }
10521     case EXTERNAL_FLOAT32x4_ELEMENTS: {
10522       IterateExternalFloat32x4ArrayElements(isolate, receiver, visitor);
10523       break;
10524     }
10525     case EXTERNAL_FLOAT64x2_ELEMENTS: {
10526       IterateExternalFloat64x2ArrayElements(isolate, receiver, visitor);
10527       break;
10528     }
10529     case EXTERNAL_INT32x4_ELEMENTS: {
10530       IterateExternalInt32x4ArrayElements(isolate, receiver, visitor);
10531       break;
10532     }
10533     case EXTERNAL_FLOAT64_ELEMENTS: {
10534       IterateExternalArrayElements<ExternalFloat64Array, double>(
10535           isolate, receiver, false, false, visitor);
10536       break;
10537     }
10538     default:
10539       UNREACHABLE();
10540       break;
10541   }
10542   visitor->increase_index_offset(length);
10543   return true;
10544 }
10545
10546
10547 /**
10548  * Array::concat implementation.
10549  * See ECMAScript 262, 15.4.4.4.
10550  * TODO(581): Fix non-compliance for very large concatenations and update to
10551  * following the ECMAScript 5 specification.
10552  */
10553 RUNTIME_FUNCTION(Runtime_ArrayConcat) {
10554   HandleScope handle_scope(isolate);
10555   DCHECK(args.length() == 1);
10556
10557   CONVERT_ARG_HANDLE_CHECKED(JSArray, arguments, 0);
10558   int argument_count = static_cast<int>(arguments->length()->Number());
10559   RUNTIME_ASSERT(arguments->HasFastObjectElements());
10560   Handle<FixedArray> elements(FixedArray::cast(arguments->elements()));
10561
10562   // Pass 1: estimate the length and number of elements of the result.
10563   // The actual length can be larger if any of the arguments have getters
10564   // that mutate other arguments (but will otherwise be precise).
10565   // The number of elements is precise if there are no inherited elements.
10566
10567   ElementsKind kind = FAST_SMI_ELEMENTS;
10568
10569   uint32_t estimate_result_length = 0;
10570   uint32_t estimate_nof_elements = 0;
10571   for (int i = 0; i < argument_count; i++) {
10572     HandleScope loop_scope(isolate);
10573     Handle<Object> obj(elements->get(i), isolate);
10574     uint32_t length_estimate;
10575     uint32_t element_estimate;
10576     if (obj->IsJSArray()) {
10577       Handle<JSArray> array(Handle<JSArray>::cast(obj));
10578       length_estimate = static_cast<uint32_t>(array->length()->Number());
10579       if (length_estimate != 0) {
10580         ElementsKind array_kind =
10581             GetPackedElementsKind(array->map()->elements_kind());
10582         if (IsMoreGeneralElementsKindTransition(kind, array_kind)) {
10583           kind = array_kind;
10584         }
10585       }
10586       element_estimate = EstimateElementCount(array);
10587     } else {
10588       if (obj->IsHeapObject()) {
10589         if (obj->IsNumber()) {
10590           if (IsMoreGeneralElementsKindTransition(kind, FAST_DOUBLE_ELEMENTS)) {
10591             kind = FAST_DOUBLE_ELEMENTS;
10592           }
10593         } else if (IsMoreGeneralElementsKindTransition(kind, FAST_ELEMENTS)) {
10594           kind = FAST_ELEMENTS;
10595         }
10596       }
10597       length_estimate = 1;
10598       element_estimate = 1;
10599     }
10600     // Avoid overflows by capping at kMaxElementCount.
10601     if (JSObject::kMaxElementCount - estimate_result_length <
10602         length_estimate) {
10603       estimate_result_length = JSObject::kMaxElementCount;
10604     } else {
10605       estimate_result_length += length_estimate;
10606     }
10607     if (JSObject::kMaxElementCount - estimate_nof_elements <
10608         element_estimate) {
10609       estimate_nof_elements = JSObject::kMaxElementCount;
10610     } else {
10611       estimate_nof_elements += element_estimate;
10612     }
10613   }
10614
10615   // If estimated number of elements is more than half of length, a
10616   // fixed array (fast case) is more time and space-efficient than a
10617   // dictionary.
10618   bool fast_case = (estimate_nof_elements * 2) >= estimate_result_length;
10619
10620   if (fast_case && kind == FAST_DOUBLE_ELEMENTS) {
10621     Handle<FixedArrayBase> storage =
10622         isolate->factory()->NewFixedDoubleArray(estimate_result_length);
10623     int j = 0;
10624     if (estimate_result_length > 0) {
10625       Handle<FixedDoubleArray> double_storage =
10626           Handle<FixedDoubleArray>::cast(storage);
10627       bool failure = false;
10628       for (int i = 0; i < argument_count; i++) {
10629         Handle<Object> obj(elements->get(i), isolate);
10630         if (obj->IsSmi()) {
10631           double_storage->set(j, Smi::cast(*obj)->value());
10632           j++;
10633         } else if (obj->IsNumber()) {
10634           double_storage->set(j, obj->Number());
10635           j++;
10636         } else {
10637           JSArray* array = JSArray::cast(*obj);
10638           uint32_t length = static_cast<uint32_t>(array->length()->Number());
10639           switch (array->map()->elements_kind()) {
10640             case FAST_HOLEY_DOUBLE_ELEMENTS:
10641             case FAST_DOUBLE_ELEMENTS: {
10642               // Empty array is FixedArray but not FixedDoubleArray.
10643               if (length == 0) break;
10644               FixedDoubleArray* elements =
10645                   FixedDoubleArray::cast(array->elements());
10646               for (uint32_t i = 0; i < length; i++) {
10647                 if (elements->is_the_hole(i)) {
10648                   failure = true;
10649                   break;
10650                 }
10651                 double double_value = elements->get_scalar(i);
10652                 double_storage->set(j, double_value);
10653                 j++;
10654               }
10655               break;
10656             }
10657             case FAST_HOLEY_SMI_ELEMENTS:
10658             case FAST_SMI_ELEMENTS: {
10659               FixedArray* elements(
10660                   FixedArray::cast(array->elements()));
10661               for (uint32_t i = 0; i < length; i++) {
10662                 Object* element = elements->get(i);
10663                 if (element->IsTheHole()) {
10664                   failure = true;
10665                   break;
10666                 }
10667                 int32_t int_value = Smi::cast(element)->value();
10668                 double_storage->set(j, int_value);
10669                 j++;
10670               }
10671               break;
10672             }
10673             case FAST_HOLEY_ELEMENTS:
10674               DCHECK_EQ(0, length);
10675               break;
10676             default:
10677               UNREACHABLE();
10678           }
10679         }
10680         if (failure) break;
10681       }
10682     }
10683     Handle<JSArray> array = isolate->factory()->NewJSArray(0);
10684     Smi* length = Smi::FromInt(j);
10685     Handle<Map> map;
10686     map = JSObject::GetElementsTransitionMap(array, kind);
10687     array->set_map(*map);
10688     array->set_length(length);
10689     array->set_elements(*storage);
10690     return *array;
10691   }
10692
10693   Handle<FixedArray> storage;
10694   if (fast_case) {
10695     // The backing storage array must have non-existing elements to preserve
10696     // holes across concat operations.
10697     storage = isolate->factory()->NewFixedArrayWithHoles(
10698         estimate_result_length);
10699   } else {
10700     // TODO(126): move 25% pre-allocation logic into Dictionary::Allocate
10701     uint32_t at_least_space_for = estimate_nof_elements +
10702                                   (estimate_nof_elements >> 2);
10703     storage = Handle<FixedArray>::cast(
10704         SeededNumberDictionary::New(isolate, at_least_space_for));
10705   }
10706
10707   ArrayConcatVisitor visitor(isolate, storage, fast_case);
10708
10709   for (int i = 0; i < argument_count; i++) {
10710     Handle<Object> obj(elements->get(i), isolate);
10711     if (obj->IsJSArray()) {
10712       Handle<JSArray> array = Handle<JSArray>::cast(obj);
10713       if (!IterateElements(isolate, array, &visitor)) {
10714         return isolate->heap()->exception();
10715       }
10716     } else {
10717       visitor.visit(0, obj);
10718       visitor.increase_index_offset(1);
10719     }
10720   }
10721
10722   if (visitor.exceeds_array_limit()) {
10723     return isolate->Throw(
10724         *isolate->factory()->NewRangeError("invalid_array_length",
10725                                            HandleVector<Object>(NULL, 0)));
10726   }
10727   return *visitor.ToArray();
10728 }
10729
10730
10731 // This will not allocate (flatten the string), but it may run
10732 // very slowly for very deeply nested ConsStrings.  For debugging use only.
10733 RUNTIME_FUNCTION(Runtime_GlobalPrint) {
10734   SealHandleScope shs(isolate);
10735   DCHECK(args.length() == 1);
10736
10737   CONVERT_ARG_CHECKED(String, string, 0);
10738   ConsStringIteratorOp op;
10739   StringCharacterStream stream(string, &op);
10740   while (stream.HasMore()) {
10741     uint16_t character = stream.GetNext();
10742     PrintF("%c", character);
10743   }
10744   return string;
10745 }
10746
10747
10748 // Moves all own elements of an object, that are below a limit, to positions
10749 // starting at zero. All undefined values are placed after non-undefined values,
10750 // and are followed by non-existing element. Does not change the length
10751 // property.
10752 // Returns the number of non-undefined elements collected.
10753 // Returns -1 if hole removal is not supported by this method.
10754 RUNTIME_FUNCTION(Runtime_RemoveArrayHoles) {
10755   HandleScope scope(isolate);
10756   DCHECK(args.length() == 2);
10757   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
10758   CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]);
10759   return *JSObject::PrepareElementsForSort(object, limit);
10760 }
10761
10762
10763 // Move contents of argument 0 (an array) to argument 1 (an array)
10764 RUNTIME_FUNCTION(Runtime_MoveArrayContents) {
10765   HandleScope scope(isolate);
10766   DCHECK(args.length() == 2);
10767   CONVERT_ARG_HANDLE_CHECKED(JSArray, from, 0);
10768   CONVERT_ARG_HANDLE_CHECKED(JSArray, to, 1);
10769   JSObject::ValidateElements(from);
10770   JSObject::ValidateElements(to);
10771
10772   Handle<FixedArrayBase> new_elements(from->elements());
10773   ElementsKind from_kind = from->GetElementsKind();
10774   Handle<Map> new_map = JSObject::GetElementsTransitionMap(to, from_kind);
10775   JSObject::SetMapAndElements(to, new_map, new_elements);
10776   to->set_length(from->length());
10777
10778   JSObject::ResetElements(from);
10779   from->set_length(Smi::FromInt(0));
10780
10781   JSObject::ValidateElements(to);
10782   return *to;
10783 }
10784
10785
10786 // How many elements does this object/array have?
10787 RUNTIME_FUNCTION(Runtime_EstimateNumberOfElements) {
10788   HandleScope scope(isolate);
10789   DCHECK(args.length() == 1);
10790   CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
10791   Handle<FixedArrayBase> elements(array->elements(), isolate);
10792   SealHandleScope shs(isolate);
10793   if (elements->IsDictionary()) {
10794     int result =
10795         Handle<SeededNumberDictionary>::cast(elements)->NumberOfElements();
10796     return Smi::FromInt(result);
10797   } else {
10798     DCHECK(array->length()->IsSmi());
10799     // For packed elements, we know the exact number of elements
10800     int length = elements->length();
10801     ElementsKind kind = array->GetElementsKind();
10802     if (IsFastPackedElementsKind(kind)) {
10803       return Smi::FromInt(length);
10804     }
10805     // For holey elements, take samples from the buffer checking for holes
10806     // to generate the estimate.
10807     const int kNumberOfHoleCheckSamples = 97;
10808     int increment = (length < kNumberOfHoleCheckSamples)
10809                         ? 1
10810                         : static_cast<int>(length / kNumberOfHoleCheckSamples);
10811     ElementsAccessor* accessor = array->GetElementsAccessor();
10812     int holes = 0;
10813     for (int i = 0; i < length; i += increment) {
10814       if (!accessor->HasElement(array, array, i, elements)) {
10815         ++holes;
10816       }
10817     }
10818     int estimate = static_cast<int>((kNumberOfHoleCheckSamples - holes) /
10819                                     kNumberOfHoleCheckSamples * length);
10820     return Smi::FromInt(estimate);
10821   }
10822 }
10823
10824
10825 // Returns an array that tells you where in the [0, length) interval an array
10826 // might have elements.  Can either return an array of keys (positive integers
10827 // or undefined) or a number representing the positive length of an interval
10828 // starting at index 0.
10829 // Intervals can span over some keys that are not in the object.
10830 RUNTIME_FUNCTION(Runtime_GetArrayKeys) {
10831   HandleScope scope(isolate);
10832   DCHECK(args.length() == 2);
10833   CONVERT_ARG_HANDLE_CHECKED(JSObject, array, 0);
10834   CONVERT_NUMBER_CHECKED(uint32_t, length, Uint32, args[1]);
10835   if (array->elements()->IsDictionary()) {
10836     Handle<FixedArray> keys = isolate->factory()->empty_fixed_array();
10837     for (PrototypeIterator iter(isolate, array,
10838                                 PrototypeIterator::START_AT_RECEIVER);
10839          !iter.IsAtEnd(); iter.Advance()) {
10840       if (PrototypeIterator::GetCurrent(iter)->IsJSProxy() ||
10841           JSObject::cast(*PrototypeIterator::GetCurrent(iter))
10842               ->HasIndexedInterceptor()) {
10843         // Bail out if we find a proxy or interceptor, likely not worth
10844         // collecting keys in that case.
10845         return *isolate->factory()->NewNumberFromUint(length);
10846       }
10847       Handle<JSObject> current =
10848           Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
10849       Handle<FixedArray> current_keys =
10850           isolate->factory()->NewFixedArray(current->NumberOfOwnElements(NONE));
10851       current->GetOwnElementKeys(*current_keys, NONE);
10852       ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
10853           isolate, keys, FixedArray::UnionOfKeys(keys, current_keys));
10854     }
10855     // Erase any keys >= length.
10856     // TODO(adamk): Remove this step when the contract of %GetArrayKeys
10857     // is changed to let this happen on the JS side.
10858     for (int i = 0; i < keys->length(); i++) {
10859       if (NumberToUint32(keys->get(i)) >= length) keys->set_undefined(i);
10860     }
10861     return *isolate->factory()->NewJSArrayWithElements(keys);
10862   } else {
10863     RUNTIME_ASSERT(array->HasFastSmiOrObjectElements() ||
10864                    array->HasFastDoubleElements());
10865     uint32_t actual_length = static_cast<uint32_t>(array->elements()->length());
10866     return *isolate->factory()->NewNumberFromUint(Min(actual_length, length));
10867   }
10868 }
10869
10870
10871 RUNTIME_FUNCTION(Runtime_LookupAccessor) {
10872   HandleScope scope(isolate);
10873   DCHECK(args.length() == 3);
10874   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
10875   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
10876   CONVERT_SMI_ARG_CHECKED(flag, 2);
10877   AccessorComponent component = flag == 0 ? ACCESSOR_GETTER : ACCESSOR_SETTER;
10878   if (!receiver->IsJSObject()) return isolate->heap()->undefined_value();
10879   Handle<Object> result;
10880   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
10881       isolate, result,
10882       JSObject::GetAccessor(Handle<JSObject>::cast(receiver), name, component));
10883   return *result;
10884 }
10885
10886
10887 RUNTIME_FUNCTION(Runtime_DebugBreak) {
10888   SealHandleScope shs(isolate);
10889   DCHECK(args.length() == 0);
10890   isolate->debug()->HandleDebugBreak();
10891   return isolate->heap()->undefined_value();
10892 }
10893
10894
10895 // Helper functions for wrapping and unwrapping stack frame ids.
10896 static Smi* WrapFrameId(StackFrame::Id id) {
10897   DCHECK(IsAligned(OffsetFrom(id), static_cast<intptr_t>(4)));
10898   return Smi::FromInt(id >> 2);
10899 }
10900
10901
10902 static StackFrame::Id UnwrapFrameId(int wrapped) {
10903   return static_cast<StackFrame::Id>(wrapped << 2);
10904 }
10905
10906
10907 // Adds a JavaScript function as a debug event listener.
10908 // args[0]: debug event listener function to set or null or undefined for
10909 //          clearing the event listener function
10910 // args[1]: object supplied during callback
10911 RUNTIME_FUNCTION(Runtime_SetDebugEventListener) {
10912   SealHandleScope shs(isolate);
10913   DCHECK(args.length() == 2);
10914   RUNTIME_ASSERT(args[0]->IsJSFunction() ||
10915                  args[0]->IsUndefined() ||
10916                  args[0]->IsNull());
10917   CONVERT_ARG_HANDLE_CHECKED(Object, callback, 0);
10918   CONVERT_ARG_HANDLE_CHECKED(Object, data, 1);
10919   isolate->debug()->SetEventListener(callback, data);
10920
10921   return isolate->heap()->undefined_value();
10922 }
10923
10924
10925 RUNTIME_FUNCTION(Runtime_Break) {
10926   SealHandleScope shs(isolate);
10927   DCHECK(args.length() == 0);
10928   isolate->stack_guard()->RequestDebugBreak();
10929   return isolate->heap()->undefined_value();
10930 }
10931
10932
10933 static Handle<Object> DebugLookupResultValue(Isolate* isolate,
10934                                              Handle<Object> receiver,
10935                                              Handle<Name> name,
10936                                              LookupResult* result,
10937                                              bool* has_caught = NULL) {
10938   Handle<Object> value = isolate->factory()->undefined_value();
10939   if  (!result->IsFound()) return value;
10940   switch (result->type()) {
10941     case NORMAL:
10942       return JSObject::GetNormalizedProperty(handle(result->holder(), isolate),
10943                                              result);
10944     case FIELD:
10945       return JSObject::FastPropertyAt(handle(result->holder(), isolate),
10946                                       result->representation(),
10947                                       result->GetFieldIndex());
10948     case CONSTANT:
10949       return handle(result->GetConstant(), isolate);
10950     case CALLBACKS: {
10951       Handle<Object> structure(result->GetCallbackObject(), isolate);
10952       DCHECK(!structure->IsForeign());
10953       if (structure->IsAccessorInfo()) {
10954         MaybeHandle<Object> obj = JSObject::GetPropertyWithAccessor(
10955             receiver, name, handle(result->holder(), isolate), structure);
10956         if (!obj.ToHandle(&value)) {
10957           value = handle(isolate->pending_exception(), isolate);
10958           isolate->clear_pending_exception();
10959           if (has_caught != NULL) *has_caught = true;
10960           return value;
10961         }
10962       }
10963       break;
10964     }
10965     case INTERCEPTOR:
10966     case HANDLER:
10967       break;
10968     case NONEXISTENT:
10969       UNREACHABLE();
10970       break;
10971   }
10972   return value;
10973 }
10974
10975
10976 // Get debugger related details for an object property.
10977 // args[0]: object holding property
10978 // args[1]: name of the property
10979 //
10980 // The array returned contains the following information:
10981 // 0: Property value
10982 // 1: Property details
10983 // 2: Property value is exception
10984 // 3: Getter function if defined
10985 // 4: Setter function if defined
10986 // Items 2-4 are only filled if the property has either a getter or a setter
10987 // defined through __defineGetter__ and/or __defineSetter__.
10988 RUNTIME_FUNCTION(Runtime_DebugGetPropertyDetails) {
10989   HandleScope scope(isolate);
10990
10991   DCHECK(args.length() == 2);
10992
10993   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
10994   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
10995
10996   // Make sure to set the current context to the context before the debugger was
10997   // entered (if the debugger is entered). The reason for switching context here
10998   // is that for some property lookups (accessors and interceptors) callbacks
10999   // into the embedding application can occour, and the embedding application
11000   // could have the assumption that its own native context is the current
11001   // context and not some internal debugger context.
11002   SaveContext save(isolate);
11003   if (isolate->debug()->in_debug_scope()) {
11004     isolate->set_context(*isolate->debug()->debugger_entry()->GetContext());
11005   }
11006
11007   // Check if the name is trivially convertible to an index and get the element
11008   // if so.
11009   uint32_t index;
11010   if (name->AsArrayIndex(&index)) {
11011     Handle<FixedArray> details = isolate->factory()->NewFixedArray(2);
11012     Handle<Object> element_or_char;
11013     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
11014         isolate, element_or_char,
11015         Runtime::GetElementOrCharAt(isolate, obj, index));
11016     details->set(0, *element_or_char);
11017     details->set(
11018         1, PropertyDetails(NONE, NORMAL, Representation::None()).AsSmi());
11019     return *isolate->factory()->NewJSArrayWithElements(details);
11020   }
11021
11022   // Find the number of objects making up this.
11023   int length = OwnPrototypeChainLength(*obj);
11024
11025   // Try own lookup on each of the objects.
11026   PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER);
11027   for (int i = 0; i < length; i++) {
11028     DCHECK(!iter.IsAtEnd());
11029     Handle<JSObject> jsproto =
11030         Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
11031     LookupResult result(isolate);
11032     jsproto->LookupOwn(name, &result);
11033     if (result.IsFound()) {
11034       // LookupResult is not GC safe as it holds raw object pointers.
11035       // GC can happen later in this code so put the required fields into
11036       // local variables using handles when required for later use.
11037       Handle<Object> result_callback_obj;
11038       if (result.IsPropertyCallbacks()) {
11039         result_callback_obj = Handle<Object>(result.GetCallbackObject(),
11040                                              isolate);
11041       }
11042
11043
11044       bool has_caught = false;
11045       Handle<Object> value = DebugLookupResultValue(
11046           isolate, obj, name, &result, &has_caught);
11047
11048       // If the callback object is a fixed array then it contains JavaScript
11049       // getter and/or setter.
11050       bool has_js_accessors = result.IsPropertyCallbacks() &&
11051                               result_callback_obj->IsAccessorPair();
11052       Handle<FixedArray> details =
11053           isolate->factory()->NewFixedArray(has_js_accessors ? 5 : 2);
11054       details->set(0, *value);
11055       details->set(1, result.GetPropertyDetails().AsSmi());
11056       if (has_js_accessors) {
11057         AccessorPair* accessors = AccessorPair::cast(*result_callback_obj);
11058         details->set(2, isolate->heap()->ToBoolean(has_caught));
11059         details->set(3, accessors->GetComponent(ACCESSOR_GETTER));
11060         details->set(4, accessors->GetComponent(ACCESSOR_SETTER));
11061       }
11062
11063       return *isolate->factory()->NewJSArrayWithElements(details);
11064     }
11065     iter.Advance();
11066   }
11067
11068   return isolate->heap()->undefined_value();
11069 }
11070
11071
11072 RUNTIME_FUNCTION(Runtime_DebugGetProperty) {
11073   HandleScope scope(isolate);
11074
11075   DCHECK(args.length() == 2);
11076
11077   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
11078   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
11079
11080   LookupResult result(isolate);
11081   obj->Lookup(name, &result);
11082   return *DebugLookupResultValue(isolate, obj, name, &result);
11083 }
11084
11085
11086 // Return the property type calculated from the property details.
11087 // args[0]: smi with property details.
11088 RUNTIME_FUNCTION(Runtime_DebugPropertyTypeFromDetails) {
11089   SealHandleScope shs(isolate);
11090   DCHECK(args.length() == 1);
11091   CONVERT_PROPERTY_DETAILS_CHECKED(details, 0);
11092   return Smi::FromInt(static_cast<int>(details.type()));
11093 }
11094
11095
11096 // Return the property attribute calculated from the property details.
11097 // args[0]: smi with property details.
11098 RUNTIME_FUNCTION(Runtime_DebugPropertyAttributesFromDetails) {
11099   SealHandleScope shs(isolate);
11100   DCHECK(args.length() == 1);
11101   CONVERT_PROPERTY_DETAILS_CHECKED(details, 0);
11102   return Smi::FromInt(static_cast<int>(details.attributes()));
11103 }
11104
11105
11106 // Return the property insertion index calculated from the property details.
11107 // args[0]: smi with property details.
11108 RUNTIME_FUNCTION(Runtime_DebugPropertyIndexFromDetails) {
11109   SealHandleScope shs(isolate);
11110   DCHECK(args.length() == 1);
11111   CONVERT_PROPERTY_DETAILS_CHECKED(details, 0);
11112   // TODO(verwaest): Depends on the type of details.
11113   return Smi::FromInt(details.dictionary_index());
11114 }
11115
11116
11117 // Return property value from named interceptor.
11118 // args[0]: object
11119 // args[1]: property name
11120 RUNTIME_FUNCTION(Runtime_DebugNamedInterceptorPropertyValue) {
11121   HandleScope scope(isolate);
11122   DCHECK(args.length() == 2);
11123   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
11124   RUNTIME_ASSERT(obj->HasNamedInterceptor());
11125   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
11126
11127   Handle<Object> result;
11128   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
11129       isolate, result, JSObject::GetProperty(obj, name));
11130   return *result;
11131 }
11132
11133
11134 // Return element value from indexed interceptor.
11135 // args[0]: object
11136 // args[1]: index
11137 RUNTIME_FUNCTION(Runtime_DebugIndexedInterceptorElementValue) {
11138   HandleScope scope(isolate);
11139   DCHECK(args.length() == 2);
11140   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
11141   RUNTIME_ASSERT(obj->HasIndexedInterceptor());
11142   CONVERT_NUMBER_CHECKED(uint32_t, index, Uint32, args[1]);
11143   Handle<Object> result;
11144   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
11145       isolate, result, JSObject::GetElementWithInterceptor(obj, obj, index));
11146   return *result;
11147 }
11148
11149
11150 static bool CheckExecutionState(Isolate* isolate, int break_id) {
11151   return !isolate->debug()->debug_context().is_null() &&
11152          isolate->debug()->break_id() != 0 &&
11153          isolate->debug()->break_id() == break_id;
11154 }
11155
11156
11157 RUNTIME_FUNCTION(Runtime_CheckExecutionState) {
11158   SealHandleScope shs(isolate);
11159   DCHECK(args.length() == 1);
11160   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
11161   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
11162   return isolate->heap()->true_value();
11163 }
11164
11165
11166 RUNTIME_FUNCTION(Runtime_GetFrameCount) {
11167   HandleScope scope(isolate);
11168   DCHECK(args.length() == 1);
11169   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
11170   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
11171
11172   // Count all frames which are relevant to debugging stack trace.
11173   int n = 0;
11174   StackFrame::Id id = isolate->debug()->break_frame_id();
11175   if (id == StackFrame::NO_ID) {
11176     // If there is no JavaScript stack frame count is 0.
11177     return Smi::FromInt(0);
11178   }
11179
11180   for (JavaScriptFrameIterator it(isolate, id); !it.done(); it.Advance()) {
11181     List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
11182     it.frame()->Summarize(&frames);
11183     for (int i = frames.length() - 1; i >= 0; i--) {
11184       // Omit functions from native scripts.
11185       if (!frames[i].function()->IsFromNativeScript()) n++;
11186     }
11187   }
11188   return Smi::FromInt(n);
11189 }
11190
11191
11192 class FrameInspector {
11193  public:
11194   FrameInspector(JavaScriptFrame* frame,
11195                  int inlined_jsframe_index,
11196                  Isolate* isolate)
11197       : frame_(frame), deoptimized_frame_(NULL), isolate_(isolate) {
11198     // Calculate the deoptimized frame.
11199     if (frame->is_optimized()) {
11200       deoptimized_frame_ = Deoptimizer::DebuggerInspectableFrame(
11201           frame, inlined_jsframe_index, isolate);
11202     }
11203     has_adapted_arguments_ = frame_->has_adapted_arguments();
11204     is_bottommost_ = inlined_jsframe_index == 0;
11205     is_optimized_ = frame_->is_optimized();
11206   }
11207
11208   ~FrameInspector() {
11209     // Get rid of the calculated deoptimized frame if any.
11210     if (deoptimized_frame_ != NULL) {
11211       Deoptimizer::DeleteDebuggerInspectableFrame(deoptimized_frame_,
11212                                                   isolate_);
11213     }
11214   }
11215
11216   int GetParametersCount() {
11217     return is_optimized_
11218         ? deoptimized_frame_->parameters_count()
11219         : frame_->ComputeParametersCount();
11220   }
11221   int expression_count() { return deoptimized_frame_->expression_count(); }
11222   Object* GetFunction() {
11223     return is_optimized_
11224         ? deoptimized_frame_->GetFunction()
11225         : frame_->function();
11226   }
11227   Object* GetParameter(int index) {
11228     return is_optimized_
11229         ? deoptimized_frame_->GetParameter(index)
11230         : frame_->GetParameter(index);
11231   }
11232   Object* GetExpression(int index) {
11233     return is_optimized_
11234         ? deoptimized_frame_->GetExpression(index)
11235         : frame_->GetExpression(index);
11236   }
11237   int GetSourcePosition() {
11238     return is_optimized_
11239         ? deoptimized_frame_->GetSourcePosition()
11240         : frame_->LookupCode()->SourcePosition(frame_->pc());
11241   }
11242   bool IsConstructor() {
11243     return is_optimized_ && !is_bottommost_
11244         ? deoptimized_frame_->HasConstructStub()
11245         : frame_->IsConstructor();
11246   }
11247
11248   // To inspect all the provided arguments the frame might need to be
11249   // replaced with the arguments frame.
11250   void SetArgumentsFrame(JavaScriptFrame* frame) {
11251     DCHECK(has_adapted_arguments_);
11252     frame_ = frame;
11253     is_optimized_ = frame_->is_optimized();
11254     DCHECK(!is_optimized_);
11255   }
11256
11257  private:
11258   JavaScriptFrame* frame_;
11259   DeoptimizedFrameInfo* deoptimized_frame_;
11260   Isolate* isolate_;
11261   bool is_optimized_;
11262   bool is_bottommost_;
11263   bool has_adapted_arguments_;
11264
11265   DISALLOW_COPY_AND_ASSIGN(FrameInspector);
11266 };
11267
11268
11269 static const int kFrameDetailsFrameIdIndex = 0;
11270 static const int kFrameDetailsReceiverIndex = 1;
11271 static const int kFrameDetailsFunctionIndex = 2;
11272 static const int kFrameDetailsArgumentCountIndex = 3;
11273 static const int kFrameDetailsLocalCountIndex = 4;
11274 static const int kFrameDetailsSourcePositionIndex = 5;
11275 static const int kFrameDetailsConstructCallIndex = 6;
11276 static const int kFrameDetailsAtReturnIndex = 7;
11277 static const int kFrameDetailsFlagsIndex = 8;
11278 static const int kFrameDetailsFirstDynamicIndex = 9;
11279
11280
11281 static SaveContext* FindSavedContextForFrame(Isolate* isolate,
11282                                              JavaScriptFrame* frame) {
11283   SaveContext* save = isolate->save_context();
11284   while (save != NULL && !save->IsBelowFrame(frame)) {
11285     save = save->prev();
11286   }
11287   DCHECK(save != NULL);
11288   return save;
11289 }
11290
11291
11292 RUNTIME_FUNCTION(Runtime_IsOptimized) {
11293   SealHandleScope shs(isolate);
11294   DCHECK(args.length() == 0);
11295   JavaScriptFrameIterator it(isolate);
11296   JavaScriptFrame* frame = it.frame();
11297   return isolate->heap()->ToBoolean(frame->is_optimized());
11298 }
11299
11300
11301 // Advances the iterator to the frame that matches the index and returns the
11302 // inlined frame index, or -1 if not found.  Skips native JS functions.
11303 static int FindIndexedNonNativeFrame(JavaScriptFrameIterator* it, int index) {
11304   int count = -1;
11305   for (; !it->done(); it->Advance()) {
11306     List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
11307     it->frame()->Summarize(&frames);
11308     for (int i = frames.length() - 1; i >= 0; i--) {
11309       // Omit functions from native scripts.
11310       if (frames[i].function()->IsFromNativeScript()) continue;
11311       if (++count == index) return i;
11312     }
11313   }
11314   return -1;
11315 }
11316
11317
11318 // Return an array with frame details
11319 // args[0]: number: break id
11320 // args[1]: number: frame index
11321 //
11322 // The array returned contains the following information:
11323 // 0: Frame id
11324 // 1: Receiver
11325 // 2: Function
11326 // 3: Argument count
11327 // 4: Local count
11328 // 5: Source position
11329 // 6: Constructor call
11330 // 7: Is at return
11331 // 8: Flags
11332 // Arguments name, value
11333 // Locals name, value
11334 // Return value if any
11335 RUNTIME_FUNCTION(Runtime_GetFrameDetails) {
11336   HandleScope scope(isolate);
11337   DCHECK(args.length() == 2);
11338   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
11339   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
11340
11341   CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
11342   Heap* heap = isolate->heap();
11343
11344   // Find the relevant frame with the requested index.
11345   StackFrame::Id id = isolate->debug()->break_frame_id();
11346   if (id == StackFrame::NO_ID) {
11347     // If there are no JavaScript stack frames return undefined.
11348     return heap->undefined_value();
11349   }
11350
11351   JavaScriptFrameIterator it(isolate, id);
11352   // Inlined frame index in optimized frame, starting from outer function.
11353   int inlined_jsframe_index = FindIndexedNonNativeFrame(&it, index);
11354   if (inlined_jsframe_index == -1) return heap->undefined_value();
11355
11356   FrameInspector frame_inspector(it.frame(), inlined_jsframe_index, isolate);
11357   bool is_optimized = it.frame()->is_optimized();
11358
11359   // Traverse the saved contexts chain to find the active context for the
11360   // selected frame.
11361   SaveContext* save = FindSavedContextForFrame(isolate, it.frame());
11362
11363   // Get the frame id.
11364   Handle<Object> frame_id(WrapFrameId(it.frame()->id()), isolate);
11365
11366   // Find source position in unoptimized code.
11367   int position = frame_inspector.GetSourcePosition();
11368
11369   // Check for constructor frame.
11370   bool constructor = frame_inspector.IsConstructor();
11371
11372   // Get scope info and read from it for local variable information.
11373   Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction()));
11374   Handle<SharedFunctionInfo> shared(function->shared());
11375   Handle<ScopeInfo> scope_info(shared->scope_info());
11376   DCHECK(*scope_info != ScopeInfo::Empty(isolate));
11377
11378   // Get the locals names and values into a temporary array.
11379   int local_count = scope_info->LocalCount();
11380   for (int slot = 0; slot < scope_info->LocalCount(); ++slot) {
11381     // Hide compiler-introduced temporary variables, whether on the stack or on
11382     // the context.
11383     if (scope_info->LocalIsSynthetic(slot))
11384       local_count--;
11385   }
11386
11387   Handle<FixedArray> locals =
11388       isolate->factory()->NewFixedArray(local_count * 2);
11389
11390   // Fill in the values of the locals.
11391   int local = 0;
11392   int i = 0;
11393   for (; i < scope_info->StackLocalCount(); ++i) {
11394     // Use the value from the stack.
11395     if (scope_info->LocalIsSynthetic(i))
11396       continue;
11397     locals->set(local * 2, scope_info->LocalName(i));
11398     locals->set(local * 2 + 1, frame_inspector.GetExpression(i));
11399     local++;
11400   }
11401   if (local < local_count) {
11402     // Get the context containing declarations.
11403     Handle<Context> context(
11404         Context::cast(it.frame()->context())->declaration_context());
11405     for (; i < scope_info->LocalCount(); ++i) {
11406       if (scope_info->LocalIsSynthetic(i))
11407         continue;
11408       Handle<String> name(scope_info->LocalName(i));
11409       VariableMode mode;
11410       InitializationFlag init_flag;
11411       MaybeAssignedFlag maybe_assigned_flag;
11412       locals->set(local * 2, *name);
11413       int context_slot_index = ScopeInfo::ContextSlotIndex(
11414           scope_info, name, &mode, &init_flag, &maybe_assigned_flag);
11415       Object* value = context->get(context_slot_index);
11416       locals->set(local * 2 + 1, value);
11417       local++;
11418     }
11419   }
11420
11421   // Check whether this frame is positioned at return. If not top
11422   // frame or if the frame is optimized it cannot be at a return.
11423   bool at_return = false;
11424   if (!is_optimized && index == 0) {
11425     at_return = isolate->debug()->IsBreakAtReturn(it.frame());
11426   }
11427
11428   // If positioned just before return find the value to be returned and add it
11429   // to the frame information.
11430   Handle<Object> return_value = isolate->factory()->undefined_value();
11431   if (at_return) {
11432     StackFrameIterator it2(isolate);
11433     Address internal_frame_sp = NULL;
11434     while (!it2.done()) {
11435       if (it2.frame()->is_internal()) {
11436         internal_frame_sp = it2.frame()->sp();
11437       } else {
11438         if (it2.frame()->is_java_script()) {
11439           if (it2.frame()->id() == it.frame()->id()) {
11440             // The internal frame just before the JavaScript frame contains the
11441             // value to return on top. A debug break at return will create an
11442             // internal frame to store the return value (eax/rax/r0) before
11443             // entering the debug break exit frame.
11444             if (internal_frame_sp != NULL) {
11445               return_value =
11446                   Handle<Object>(Memory::Object_at(internal_frame_sp),
11447                                  isolate);
11448               break;
11449             }
11450           }
11451         }
11452
11453         // Indicate that the previous frame was not an internal frame.
11454         internal_frame_sp = NULL;
11455       }
11456       it2.Advance();
11457     }
11458   }
11459
11460   // Now advance to the arguments adapter frame (if any). It contains all
11461   // the provided parameters whereas the function frame always have the number
11462   // of arguments matching the functions parameters. The rest of the
11463   // information (except for what is collected above) is the same.
11464   if ((inlined_jsframe_index == 0) && it.frame()->has_adapted_arguments()) {
11465     it.AdvanceToArgumentsFrame();
11466     frame_inspector.SetArgumentsFrame(it.frame());
11467   }
11468
11469   // Find the number of arguments to fill. At least fill the number of
11470   // parameters for the function and fill more if more parameters are provided.
11471   int argument_count = scope_info->ParameterCount();
11472   if (argument_count < frame_inspector.GetParametersCount()) {
11473     argument_count = frame_inspector.GetParametersCount();
11474   }
11475
11476   // Calculate the size of the result.
11477   int details_size = kFrameDetailsFirstDynamicIndex +
11478                      2 * (argument_count + local_count) +
11479                      (at_return ? 1 : 0);
11480   Handle<FixedArray> details = isolate->factory()->NewFixedArray(details_size);
11481
11482   // Add the frame id.
11483   details->set(kFrameDetailsFrameIdIndex, *frame_id);
11484
11485   // Add the function (same as in function frame).
11486   details->set(kFrameDetailsFunctionIndex, frame_inspector.GetFunction());
11487
11488   // Add the arguments count.
11489   details->set(kFrameDetailsArgumentCountIndex, Smi::FromInt(argument_count));
11490
11491   // Add the locals count
11492   details->set(kFrameDetailsLocalCountIndex,
11493                Smi::FromInt(local_count));
11494
11495   // Add the source position.
11496   if (position != RelocInfo::kNoPosition) {
11497     details->set(kFrameDetailsSourcePositionIndex, Smi::FromInt(position));
11498   } else {
11499     details->set(kFrameDetailsSourcePositionIndex, heap->undefined_value());
11500   }
11501
11502   // Add the constructor information.
11503   details->set(kFrameDetailsConstructCallIndex, heap->ToBoolean(constructor));
11504
11505   // Add the at return information.
11506   details->set(kFrameDetailsAtReturnIndex, heap->ToBoolean(at_return));
11507
11508   // Add flags to indicate information on whether this frame is
11509   //   bit 0: invoked in the debugger context.
11510   //   bit 1: optimized frame.
11511   //   bit 2: inlined in optimized frame
11512   int flags = 0;
11513   if (*save->context() == *isolate->debug()->debug_context()) {
11514     flags |= 1 << 0;
11515   }
11516   if (is_optimized) {
11517     flags |= 1 << 1;
11518     flags |= inlined_jsframe_index << 2;
11519   }
11520   details->set(kFrameDetailsFlagsIndex, Smi::FromInt(flags));
11521
11522   // Fill the dynamic part.
11523   int details_index = kFrameDetailsFirstDynamicIndex;
11524
11525   // Add arguments name and value.
11526   for (int i = 0; i < argument_count; i++) {
11527     // Name of the argument.
11528     if (i < scope_info->ParameterCount()) {
11529       details->set(details_index++, scope_info->ParameterName(i));
11530     } else {
11531       details->set(details_index++, heap->undefined_value());
11532     }
11533
11534     // Parameter value.
11535     if (i < frame_inspector.GetParametersCount()) {
11536       // Get the value from the stack.
11537       details->set(details_index++, frame_inspector.GetParameter(i));
11538     } else {
11539       details->set(details_index++, heap->undefined_value());
11540     }
11541   }
11542
11543   // Add locals name and value from the temporary copy from the function frame.
11544   for (int i = 0; i < local_count * 2; i++) {
11545     details->set(details_index++, locals->get(i));
11546   }
11547
11548   // Add the value being returned.
11549   if (at_return) {
11550     details->set(details_index++, *return_value);
11551   }
11552
11553   // Add the receiver (same as in function frame).
11554   // THIS MUST BE DONE LAST SINCE WE MIGHT ADVANCE
11555   // THE FRAME ITERATOR TO WRAP THE RECEIVER.
11556   Handle<Object> receiver(it.frame()->receiver(), isolate);
11557   if (!receiver->IsJSObject() &&
11558       shared->strict_mode() == SLOPPY &&
11559       !function->IsBuiltin()) {
11560     // If the receiver is not a JSObject and the function is not a
11561     // builtin or strict-mode we have hit an optimization where a
11562     // value object is not converted into a wrapped JS objects. To
11563     // hide this optimization from the debugger, we wrap the receiver
11564     // by creating correct wrapper object based on the calling frame's
11565     // native context.
11566     it.Advance();
11567     if (receiver->IsUndefined()) {
11568       receiver = handle(function->global_proxy());
11569     } else {
11570       DCHECK(!receiver->IsNull());
11571       Context* context = Context::cast(it.frame()->context());
11572       Handle<Context> native_context(Context::cast(context->native_context()));
11573       receiver = Object::ToObject(
11574           isolate, receiver, native_context).ToHandleChecked();
11575     }
11576   }
11577   details->set(kFrameDetailsReceiverIndex, *receiver);
11578
11579   DCHECK_EQ(details_size, details_index);
11580   return *isolate->factory()->NewJSArrayWithElements(details);
11581 }
11582
11583
11584 static bool ParameterIsShadowedByContextLocal(Handle<ScopeInfo> info,
11585                                               Handle<String> parameter_name) {
11586   VariableMode mode;
11587   InitializationFlag init_flag;
11588   MaybeAssignedFlag maybe_assigned_flag;
11589   return ScopeInfo::ContextSlotIndex(info, parameter_name, &mode, &init_flag,
11590                                      &maybe_assigned_flag) != -1;
11591 }
11592
11593
11594 // Create a plain JSObject which materializes the local scope for the specified
11595 // frame.
11596 MUST_USE_RESULT
11597 static MaybeHandle<JSObject> MaterializeStackLocalsWithFrameInspector(
11598     Isolate* isolate,
11599     Handle<JSObject> target,
11600     Handle<JSFunction> function,
11601     FrameInspector* frame_inspector) {
11602   Handle<SharedFunctionInfo> shared(function->shared());
11603   Handle<ScopeInfo> scope_info(shared->scope_info());
11604
11605   // First fill all parameters.
11606   for (int i = 0; i < scope_info->ParameterCount(); ++i) {
11607     // Do not materialize the parameter if it is shadowed by a context local.
11608     Handle<String> name(scope_info->ParameterName(i));
11609     if (ParameterIsShadowedByContextLocal(scope_info, name)) continue;
11610
11611     HandleScope scope(isolate);
11612     Handle<Object> value(i < frame_inspector->GetParametersCount()
11613                              ? frame_inspector->GetParameter(i)
11614                              : isolate->heap()->undefined_value(),
11615                          isolate);
11616     DCHECK(!value->IsTheHole());
11617
11618     RETURN_ON_EXCEPTION(
11619         isolate,
11620         Runtime::SetObjectProperty(isolate, target, name, value, SLOPPY),
11621         JSObject);
11622   }
11623
11624   // Second fill all stack locals.
11625   for (int i = 0; i < scope_info->StackLocalCount(); ++i) {
11626     if (scope_info->LocalIsSynthetic(i)) continue;
11627     Handle<String> name(scope_info->StackLocalName(i));
11628     Handle<Object> value(frame_inspector->GetExpression(i), isolate);
11629     if (value->IsTheHole()) continue;
11630
11631     RETURN_ON_EXCEPTION(
11632         isolate,
11633         Runtime::SetObjectProperty(isolate, target, name, value, SLOPPY),
11634         JSObject);
11635   }
11636
11637   return target;
11638 }
11639
11640
11641 static void UpdateStackLocalsFromMaterializedObject(Isolate* isolate,
11642                                                     Handle<JSObject> target,
11643                                                     Handle<JSFunction> function,
11644                                                     JavaScriptFrame* frame,
11645                                                     int inlined_jsframe_index) {
11646   if (inlined_jsframe_index != 0 || frame->is_optimized()) {
11647     // Optimized frames are not supported.
11648     // TODO(yangguo): make sure all code deoptimized when debugger is active
11649     //                and assert that this cannot happen.
11650     return;
11651   }
11652
11653   Handle<SharedFunctionInfo> shared(function->shared());
11654   Handle<ScopeInfo> scope_info(shared->scope_info());
11655
11656   // Parameters.
11657   for (int i = 0; i < scope_info->ParameterCount(); ++i) {
11658     // Shadowed parameters were not materialized.
11659     Handle<String> name(scope_info->ParameterName(i));
11660     if (ParameterIsShadowedByContextLocal(scope_info, name)) continue;
11661
11662     DCHECK(!frame->GetParameter(i)->IsTheHole());
11663     HandleScope scope(isolate);
11664     Handle<Object> value =
11665         Object::GetPropertyOrElement(target, name).ToHandleChecked();
11666     frame->SetParameterValue(i, *value);
11667   }
11668
11669   // Stack locals.
11670   for (int i = 0; i < scope_info->StackLocalCount(); ++i) {
11671     if (scope_info->LocalIsSynthetic(i)) continue;
11672     if (frame->GetExpression(i)->IsTheHole()) continue;
11673     HandleScope scope(isolate);
11674     Handle<Object> value = Object::GetPropertyOrElement(
11675         target,
11676         handle(scope_info->StackLocalName(i), isolate)).ToHandleChecked();
11677     frame->SetExpression(i, *value);
11678   }
11679 }
11680
11681
11682 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeLocalContext(
11683     Isolate* isolate,
11684     Handle<JSObject> target,
11685     Handle<JSFunction> function,
11686     JavaScriptFrame* frame) {
11687   HandleScope scope(isolate);
11688   Handle<SharedFunctionInfo> shared(function->shared());
11689   Handle<ScopeInfo> scope_info(shared->scope_info());
11690
11691   if (!scope_info->HasContext()) return target;
11692
11693   // Third fill all context locals.
11694   Handle<Context> frame_context(Context::cast(frame->context()));
11695   Handle<Context> function_context(frame_context->declaration_context());
11696   if (!ScopeInfo::CopyContextLocalsToScopeObject(
11697           scope_info, function_context, target)) {
11698     return MaybeHandle<JSObject>();
11699   }
11700
11701   // Finally copy any properties from the function context extension.
11702   // These will be variables introduced by eval.
11703   if (function_context->closure() == *function) {
11704     if (function_context->has_extension() &&
11705         !function_context->IsNativeContext()) {
11706       Handle<JSObject> ext(JSObject::cast(function_context->extension()));
11707       Handle<FixedArray> keys;
11708       ASSIGN_RETURN_ON_EXCEPTION(
11709           isolate, keys,
11710           JSReceiver::GetKeys(ext, JSReceiver::INCLUDE_PROTOS),
11711           JSObject);
11712
11713       for (int i = 0; i < keys->length(); i++) {
11714         // Names of variables introduced by eval are strings.
11715         DCHECK(keys->get(i)->IsString());
11716         Handle<String> key(String::cast(keys->get(i)));
11717         Handle<Object> value;
11718         ASSIGN_RETURN_ON_EXCEPTION(
11719             isolate, value, Object::GetPropertyOrElement(ext, key), JSObject);
11720         RETURN_ON_EXCEPTION(
11721             isolate,
11722             Runtime::SetObjectProperty(isolate, target, key, value, SLOPPY),
11723             JSObject);
11724       }
11725     }
11726   }
11727
11728   return target;
11729 }
11730
11731
11732 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeLocalScope(
11733     Isolate* isolate,
11734     JavaScriptFrame* frame,
11735     int inlined_jsframe_index) {
11736   FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate);
11737   Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction()));
11738
11739   Handle<JSObject> local_scope =
11740       isolate->factory()->NewJSObject(isolate->object_function());
11741   ASSIGN_RETURN_ON_EXCEPTION(
11742       isolate, local_scope,
11743       MaterializeStackLocalsWithFrameInspector(
11744           isolate, local_scope, function, &frame_inspector),
11745       JSObject);
11746
11747   return MaterializeLocalContext(isolate, local_scope, function, frame);
11748 }
11749
11750
11751 // Set the context local variable value.
11752 static bool SetContextLocalValue(Isolate* isolate,
11753                                  Handle<ScopeInfo> scope_info,
11754                                  Handle<Context> context,
11755                                  Handle<String> variable_name,
11756                                  Handle<Object> new_value) {
11757   for (int i = 0; i < scope_info->ContextLocalCount(); i++) {
11758     Handle<String> next_name(scope_info->ContextLocalName(i));
11759     if (String::Equals(variable_name, next_name)) {
11760       VariableMode mode;
11761       InitializationFlag init_flag;
11762       MaybeAssignedFlag maybe_assigned_flag;
11763       int context_index = ScopeInfo::ContextSlotIndex(
11764           scope_info, next_name, &mode, &init_flag, &maybe_assigned_flag);
11765       context->set(context_index, *new_value);
11766       return true;
11767     }
11768   }
11769
11770   return false;
11771 }
11772
11773
11774 static bool SetLocalVariableValue(Isolate* isolate,
11775                                   JavaScriptFrame* frame,
11776                                   int inlined_jsframe_index,
11777                                   Handle<String> variable_name,
11778                                   Handle<Object> new_value) {
11779   if (inlined_jsframe_index != 0 || frame->is_optimized()) {
11780     // Optimized frames are not supported.
11781     return false;
11782   }
11783
11784   Handle<JSFunction> function(frame->function());
11785   Handle<SharedFunctionInfo> shared(function->shared());
11786   Handle<ScopeInfo> scope_info(shared->scope_info());
11787
11788   bool default_result = false;
11789
11790   // Parameters.
11791   for (int i = 0; i < scope_info->ParameterCount(); ++i) {
11792     HandleScope scope(isolate);
11793     if (String::Equals(handle(scope_info->ParameterName(i)), variable_name)) {
11794       frame->SetParameterValue(i, *new_value);
11795       // Argument might be shadowed in heap context, don't stop here.
11796       default_result = true;
11797     }
11798   }
11799
11800   // Stack locals.
11801   for (int i = 0; i < scope_info->StackLocalCount(); ++i) {
11802     HandleScope scope(isolate);
11803     if (String::Equals(handle(scope_info->StackLocalName(i)), variable_name)) {
11804       frame->SetExpression(i, *new_value);
11805       return true;
11806     }
11807   }
11808
11809   if (scope_info->HasContext()) {
11810     // Context locals.
11811     Handle<Context> frame_context(Context::cast(frame->context()));
11812     Handle<Context> function_context(frame_context->declaration_context());
11813     if (SetContextLocalValue(
11814         isolate, scope_info, function_context, variable_name, new_value)) {
11815       return true;
11816     }
11817
11818     // Function context extension. These are variables introduced by eval.
11819     if (function_context->closure() == *function) {
11820       if (function_context->has_extension() &&
11821           !function_context->IsNativeContext()) {
11822         Handle<JSObject> ext(JSObject::cast(function_context->extension()));
11823
11824         Maybe<bool> maybe = JSReceiver::HasProperty(ext, variable_name);
11825         DCHECK(maybe.has_value);
11826         if (maybe.value) {
11827           // We don't expect this to do anything except replacing
11828           // property value.
11829           Runtime::SetObjectProperty(isolate, ext, variable_name, new_value,
11830                                      SLOPPY).Assert();
11831           return true;
11832         }
11833       }
11834     }
11835   }
11836
11837   return default_result;
11838 }
11839
11840
11841 // Create a plain JSObject which materializes the closure content for the
11842 // context.
11843 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeClosure(
11844     Isolate* isolate,
11845     Handle<Context> context) {
11846   DCHECK(context->IsFunctionContext());
11847
11848   Handle<SharedFunctionInfo> shared(context->closure()->shared());
11849   Handle<ScopeInfo> scope_info(shared->scope_info());
11850
11851   // Allocate and initialize a JSObject with all the content of this function
11852   // closure.
11853   Handle<JSObject> closure_scope =
11854       isolate->factory()->NewJSObject(isolate->object_function());
11855
11856   // Fill all context locals to the context extension.
11857   if (!ScopeInfo::CopyContextLocalsToScopeObject(
11858           scope_info, context, closure_scope)) {
11859     return MaybeHandle<JSObject>();
11860   }
11861
11862   // Finally copy any properties from the function context extension. This will
11863   // be variables introduced by eval.
11864   if (context->has_extension()) {
11865     Handle<JSObject> ext(JSObject::cast(context->extension()));
11866     Handle<FixedArray> keys;
11867     ASSIGN_RETURN_ON_EXCEPTION(
11868         isolate, keys,
11869         JSReceiver::GetKeys(ext, JSReceiver::INCLUDE_PROTOS), JSObject);
11870
11871     for (int i = 0; i < keys->length(); i++) {
11872       HandleScope scope(isolate);
11873       // Names of variables introduced by eval are strings.
11874       DCHECK(keys->get(i)->IsString());
11875       Handle<String> key(String::cast(keys->get(i)));
11876       Handle<Object> value;
11877       ASSIGN_RETURN_ON_EXCEPTION(
11878           isolate, value, Object::GetPropertyOrElement(ext, key), JSObject);
11879       RETURN_ON_EXCEPTION(
11880           isolate,
11881           Runtime::DefineObjectProperty(closure_scope, key, value, NONE),
11882           JSObject);
11883     }
11884   }
11885
11886   return closure_scope;
11887 }
11888
11889
11890 // This method copies structure of MaterializeClosure method above.
11891 static bool SetClosureVariableValue(Isolate* isolate,
11892                                     Handle<Context> context,
11893                                     Handle<String> variable_name,
11894                                     Handle<Object> new_value) {
11895   DCHECK(context->IsFunctionContext());
11896
11897   Handle<SharedFunctionInfo> shared(context->closure()->shared());
11898   Handle<ScopeInfo> scope_info(shared->scope_info());
11899
11900   // Context locals to the context extension.
11901   if (SetContextLocalValue(
11902           isolate, scope_info, context, variable_name, new_value)) {
11903     return true;
11904   }
11905
11906   // Properties from the function context extension. This will
11907   // be variables introduced by eval.
11908   if (context->has_extension()) {
11909     Handle<JSObject> ext(JSObject::cast(context->extension()));
11910     Maybe<bool> maybe = JSReceiver::HasProperty(ext, variable_name);
11911     DCHECK(maybe.has_value);
11912     if (maybe.value) {
11913       // We don't expect this to do anything except replacing property value.
11914       Runtime::DefineObjectProperty(
11915           ext, variable_name, new_value, NONE).Assert();
11916       return true;
11917     }
11918   }
11919
11920   return false;
11921 }
11922
11923
11924 // Create a plain JSObject which materializes the scope for the specified
11925 // catch context.
11926 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeCatchScope(
11927     Isolate* isolate,
11928     Handle<Context> context) {
11929   DCHECK(context->IsCatchContext());
11930   Handle<String> name(String::cast(context->extension()));
11931   Handle<Object> thrown_object(context->get(Context::THROWN_OBJECT_INDEX),
11932                                isolate);
11933   Handle<JSObject> catch_scope =
11934       isolate->factory()->NewJSObject(isolate->object_function());
11935   RETURN_ON_EXCEPTION(
11936       isolate,
11937       Runtime::DefineObjectProperty(catch_scope, name, thrown_object, NONE),
11938       JSObject);
11939   return catch_scope;
11940 }
11941
11942
11943 static bool SetCatchVariableValue(Isolate* isolate,
11944                                   Handle<Context> context,
11945                                   Handle<String> variable_name,
11946                                   Handle<Object> new_value) {
11947   DCHECK(context->IsCatchContext());
11948   Handle<String> name(String::cast(context->extension()));
11949   if (!String::Equals(name, variable_name)) {
11950     return false;
11951   }
11952   context->set(Context::THROWN_OBJECT_INDEX, *new_value);
11953   return true;
11954 }
11955
11956
11957 // Create a plain JSObject which materializes the block scope for the specified
11958 // block context.
11959 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeBlockScope(
11960     Isolate* isolate,
11961     Handle<Context> context) {
11962   DCHECK(context->IsBlockContext());
11963   Handle<ScopeInfo> scope_info(ScopeInfo::cast(context->extension()));
11964
11965   // Allocate and initialize a JSObject with all the arguments, stack locals
11966   // heap locals and extension properties of the debugged function.
11967   Handle<JSObject> block_scope =
11968       isolate->factory()->NewJSObject(isolate->object_function());
11969
11970   // Fill all context locals.
11971   if (!ScopeInfo::CopyContextLocalsToScopeObject(
11972           scope_info, context, block_scope)) {
11973     return MaybeHandle<JSObject>();
11974   }
11975
11976   return block_scope;
11977 }
11978
11979
11980 // Create a plain JSObject which materializes the module scope for the specified
11981 // module context.
11982 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeModuleScope(
11983     Isolate* isolate,
11984     Handle<Context> context) {
11985   DCHECK(context->IsModuleContext());
11986   Handle<ScopeInfo> scope_info(ScopeInfo::cast(context->extension()));
11987
11988   // Allocate and initialize a JSObject with all the members of the debugged
11989   // module.
11990   Handle<JSObject> module_scope =
11991       isolate->factory()->NewJSObject(isolate->object_function());
11992
11993   // Fill all context locals.
11994   if (!ScopeInfo::CopyContextLocalsToScopeObject(
11995           scope_info, context, module_scope)) {
11996     return MaybeHandle<JSObject>();
11997   }
11998
11999   return module_scope;
12000 }
12001
12002
12003 // Iterate over the actual scopes visible from a stack frame or from a closure.
12004 // The iteration proceeds from the innermost visible nested scope outwards.
12005 // All scopes are backed by an actual context except the local scope,
12006 // which is inserted "artificially" in the context chain.
12007 class ScopeIterator {
12008  public:
12009   enum ScopeType {
12010     ScopeTypeGlobal = 0,
12011     ScopeTypeLocal,
12012     ScopeTypeWith,
12013     ScopeTypeClosure,
12014     ScopeTypeCatch,
12015     ScopeTypeBlock,
12016     ScopeTypeModule
12017   };
12018
12019   ScopeIterator(Isolate* isolate,
12020                 JavaScriptFrame* frame,
12021                 int inlined_jsframe_index,
12022                 bool ignore_nested_scopes = false)
12023     : isolate_(isolate),
12024       frame_(frame),
12025       inlined_jsframe_index_(inlined_jsframe_index),
12026       function_(frame->function()),
12027       context_(Context::cast(frame->context())),
12028       nested_scope_chain_(4),
12029       failed_(false) {
12030
12031     // Catch the case when the debugger stops in an internal function.
12032     Handle<SharedFunctionInfo> shared_info(function_->shared());
12033     Handle<ScopeInfo> scope_info(shared_info->scope_info());
12034     if (shared_info->script() == isolate->heap()->undefined_value()) {
12035       while (context_->closure() == *function_) {
12036         context_ = Handle<Context>(context_->previous(), isolate_);
12037       }
12038       return;
12039     }
12040
12041     // Get the debug info (create it if it does not exist).
12042     if (!isolate->debug()->EnsureDebugInfo(shared_info, function_)) {
12043       // Return if ensuring debug info failed.
12044       return;
12045     }
12046
12047     // Currently it takes too much time to find nested scopes due to script
12048     // parsing. Sometimes we want to run the ScopeIterator as fast as possible
12049     // (for example, while collecting async call stacks on every
12050     // addEventListener call), even if we drop some nested scopes.
12051     // Later we may optimize getting the nested scopes (cache the result?)
12052     // and include nested scopes into the "fast" iteration case as well.
12053     if (!ignore_nested_scopes) {
12054       Handle<DebugInfo> debug_info = Debug::GetDebugInfo(shared_info);
12055
12056       // Find the break point where execution has stopped.
12057       BreakLocationIterator break_location_iterator(debug_info,
12058                                                     ALL_BREAK_LOCATIONS);
12059       // pc points to the instruction after the current one, possibly a break
12060       // location as well. So the "- 1" to exclude it from the search.
12061       break_location_iterator.FindBreakLocationFromAddress(frame->pc() - 1);
12062
12063       // Within the return sequence at the moment it is not possible to
12064       // get a source position which is consistent with the current scope chain.
12065       // Thus all nested with, catch and block contexts are skipped and we only
12066       // provide the function scope.
12067       ignore_nested_scopes = break_location_iterator.IsExit();
12068     }
12069
12070     if (ignore_nested_scopes) {
12071       if (scope_info->HasContext()) {
12072         context_ = Handle<Context>(context_->declaration_context(), isolate_);
12073       } else {
12074         while (context_->closure() == *function_) {
12075           context_ = Handle<Context>(context_->previous(), isolate_);
12076         }
12077       }
12078       if (scope_info->scope_type() == FUNCTION_SCOPE) {
12079         nested_scope_chain_.Add(scope_info);
12080       }
12081     } else {
12082       // Reparse the code and analyze the scopes.
12083       Handle<Script> script(Script::cast(shared_info->script()));
12084       Scope* scope = NULL;
12085
12086       // Check whether we are in global, eval or function code.
12087       Handle<ScopeInfo> scope_info(shared_info->scope_info());
12088       if (scope_info->scope_type() != FUNCTION_SCOPE) {
12089         // Global or eval code.
12090         CompilationInfoWithZone info(script);
12091         if (scope_info->scope_type() == GLOBAL_SCOPE) {
12092           info.MarkAsGlobal();
12093         } else {
12094           DCHECK(scope_info->scope_type() == EVAL_SCOPE);
12095           info.MarkAsEval();
12096           info.SetContext(Handle<Context>(function_->context()));
12097         }
12098         if (Parser::Parse(&info) && Scope::Analyze(&info)) {
12099           scope = info.function()->scope();
12100         }
12101         RetrieveScopeChain(scope, shared_info);
12102       } else {
12103         // Function code
12104         CompilationInfoWithZone info(shared_info);
12105         if (Parser::Parse(&info) && Scope::Analyze(&info)) {
12106           scope = info.function()->scope();
12107         }
12108         RetrieveScopeChain(scope, shared_info);
12109       }
12110     }
12111   }
12112
12113   ScopeIterator(Isolate* isolate,
12114                 Handle<JSFunction> function)
12115     : isolate_(isolate),
12116       frame_(NULL),
12117       inlined_jsframe_index_(0),
12118       function_(function),
12119       context_(function->context()),
12120       failed_(false) {
12121     if (function->IsBuiltin()) {
12122       context_ = Handle<Context>();
12123     }
12124   }
12125
12126   // More scopes?
12127   bool Done() {
12128     DCHECK(!failed_);
12129     return context_.is_null();
12130   }
12131
12132   bool Failed() { return failed_; }
12133
12134   // Move to the next scope.
12135   void Next() {
12136     DCHECK(!failed_);
12137     ScopeType scope_type = Type();
12138     if (scope_type == ScopeTypeGlobal) {
12139       // The global scope is always the last in the chain.
12140       DCHECK(context_->IsNativeContext());
12141       context_ = Handle<Context>();
12142       return;
12143     }
12144     if (nested_scope_chain_.is_empty()) {
12145       context_ = Handle<Context>(context_->previous(), isolate_);
12146     } else {
12147       if (nested_scope_chain_.last()->HasContext()) {
12148         DCHECK(context_->previous() != NULL);
12149         context_ = Handle<Context>(context_->previous(), isolate_);
12150       }
12151       nested_scope_chain_.RemoveLast();
12152     }
12153   }
12154
12155   // Return the type of the current scope.
12156   ScopeType Type() {
12157     DCHECK(!failed_);
12158     if (!nested_scope_chain_.is_empty()) {
12159       Handle<ScopeInfo> scope_info = nested_scope_chain_.last();
12160       switch (scope_info->scope_type()) {
12161         case FUNCTION_SCOPE:
12162           DCHECK(context_->IsFunctionContext() ||
12163                  !scope_info->HasContext());
12164           return ScopeTypeLocal;
12165         case MODULE_SCOPE:
12166           DCHECK(context_->IsModuleContext());
12167           return ScopeTypeModule;
12168         case GLOBAL_SCOPE:
12169           DCHECK(context_->IsNativeContext());
12170           return ScopeTypeGlobal;
12171         case WITH_SCOPE:
12172           DCHECK(context_->IsWithContext());
12173           return ScopeTypeWith;
12174         case CATCH_SCOPE:
12175           DCHECK(context_->IsCatchContext());
12176           return ScopeTypeCatch;
12177         case BLOCK_SCOPE:
12178           DCHECK(!scope_info->HasContext() ||
12179                  context_->IsBlockContext());
12180           return ScopeTypeBlock;
12181         case EVAL_SCOPE:
12182           UNREACHABLE();
12183       }
12184     }
12185     if (context_->IsNativeContext()) {
12186       DCHECK(context_->global_object()->IsGlobalObject());
12187       return ScopeTypeGlobal;
12188     }
12189     if (context_->IsFunctionContext()) {
12190       return ScopeTypeClosure;
12191     }
12192     if (context_->IsCatchContext()) {
12193       return ScopeTypeCatch;
12194     }
12195     if (context_->IsBlockContext()) {
12196       return ScopeTypeBlock;
12197     }
12198     if (context_->IsModuleContext()) {
12199       return ScopeTypeModule;
12200     }
12201     DCHECK(context_->IsWithContext());
12202     return ScopeTypeWith;
12203   }
12204
12205   // Return the JavaScript object with the content of the current scope.
12206   MaybeHandle<JSObject> ScopeObject() {
12207     DCHECK(!failed_);
12208     switch (Type()) {
12209       case ScopeIterator::ScopeTypeGlobal:
12210         return Handle<JSObject>(CurrentContext()->global_object());
12211       case ScopeIterator::ScopeTypeLocal:
12212         // Materialize the content of the local scope into a JSObject.
12213         DCHECK(nested_scope_chain_.length() == 1);
12214         return MaterializeLocalScope(isolate_, frame_, inlined_jsframe_index_);
12215       case ScopeIterator::ScopeTypeWith:
12216         // Return the with object.
12217         return Handle<JSObject>(JSObject::cast(CurrentContext()->extension()));
12218       case ScopeIterator::ScopeTypeCatch:
12219         return MaterializeCatchScope(isolate_, CurrentContext());
12220       case ScopeIterator::ScopeTypeClosure:
12221         // Materialize the content of the closure scope into a JSObject.
12222         return MaterializeClosure(isolate_, CurrentContext());
12223       case ScopeIterator::ScopeTypeBlock:
12224         return MaterializeBlockScope(isolate_, CurrentContext());
12225       case ScopeIterator::ScopeTypeModule:
12226         return MaterializeModuleScope(isolate_, CurrentContext());
12227     }
12228     UNREACHABLE();
12229     return Handle<JSObject>();
12230   }
12231
12232   bool SetVariableValue(Handle<String> variable_name,
12233                         Handle<Object> new_value) {
12234     DCHECK(!failed_);
12235     switch (Type()) {
12236       case ScopeIterator::ScopeTypeGlobal:
12237         break;
12238       case ScopeIterator::ScopeTypeLocal:
12239         return SetLocalVariableValue(isolate_, frame_, inlined_jsframe_index_,
12240             variable_name, new_value);
12241       case ScopeIterator::ScopeTypeWith:
12242         break;
12243       case ScopeIterator::ScopeTypeCatch:
12244         return SetCatchVariableValue(isolate_, CurrentContext(),
12245             variable_name, new_value);
12246       case ScopeIterator::ScopeTypeClosure:
12247         return SetClosureVariableValue(isolate_, CurrentContext(),
12248             variable_name, new_value);
12249       case ScopeIterator::ScopeTypeBlock:
12250         // TODO(2399): should we implement it?
12251         break;
12252       case ScopeIterator::ScopeTypeModule:
12253         // TODO(2399): should we implement it?
12254         break;
12255     }
12256     return false;
12257   }
12258
12259   Handle<ScopeInfo> CurrentScopeInfo() {
12260     DCHECK(!failed_);
12261     if (!nested_scope_chain_.is_empty()) {
12262       return nested_scope_chain_.last();
12263     } else if (context_->IsBlockContext()) {
12264       return Handle<ScopeInfo>(ScopeInfo::cast(context_->extension()));
12265     } else if (context_->IsFunctionContext()) {
12266       return Handle<ScopeInfo>(context_->closure()->shared()->scope_info());
12267     }
12268     return Handle<ScopeInfo>::null();
12269   }
12270
12271   // Return the context for this scope. For the local context there might not
12272   // be an actual context.
12273   Handle<Context> CurrentContext() {
12274     DCHECK(!failed_);
12275     if (Type() == ScopeTypeGlobal ||
12276         nested_scope_chain_.is_empty()) {
12277       return context_;
12278     } else if (nested_scope_chain_.last()->HasContext()) {
12279       return context_;
12280     } else {
12281       return Handle<Context>();
12282     }
12283   }
12284
12285 #ifdef DEBUG
12286   // Debug print of the content of the current scope.
12287   void DebugPrint() {
12288     OFStream os(stdout);
12289     DCHECK(!failed_);
12290     switch (Type()) {
12291       case ScopeIterator::ScopeTypeGlobal:
12292         os << "Global:\n";
12293         CurrentContext()->Print(os);
12294         break;
12295
12296       case ScopeIterator::ScopeTypeLocal: {
12297         os << "Local:\n";
12298         function_->shared()->scope_info()->Print();
12299         if (!CurrentContext().is_null()) {
12300           CurrentContext()->Print(os);
12301           if (CurrentContext()->has_extension()) {
12302             Handle<Object> extension(CurrentContext()->extension(), isolate_);
12303             if (extension->IsJSContextExtensionObject()) {
12304               extension->Print(os);
12305             }
12306           }
12307         }
12308         break;
12309       }
12310
12311       case ScopeIterator::ScopeTypeWith:
12312         os << "With:\n";
12313         CurrentContext()->extension()->Print(os);
12314         break;
12315
12316       case ScopeIterator::ScopeTypeCatch:
12317         os << "Catch:\n";
12318         CurrentContext()->extension()->Print(os);
12319         CurrentContext()->get(Context::THROWN_OBJECT_INDEX)->Print(os);
12320         break;
12321
12322       case ScopeIterator::ScopeTypeClosure:
12323         os << "Closure:\n";
12324         CurrentContext()->Print(os);
12325         if (CurrentContext()->has_extension()) {
12326           Handle<Object> extension(CurrentContext()->extension(), isolate_);
12327           if (extension->IsJSContextExtensionObject()) {
12328             extension->Print(os);
12329           }
12330         }
12331         break;
12332
12333       default:
12334         UNREACHABLE();
12335     }
12336     PrintF("\n");
12337   }
12338 #endif
12339
12340  private:
12341   Isolate* isolate_;
12342   JavaScriptFrame* frame_;
12343   int inlined_jsframe_index_;
12344   Handle<JSFunction> function_;
12345   Handle<Context> context_;
12346   List<Handle<ScopeInfo> > nested_scope_chain_;
12347   bool failed_;
12348
12349   void RetrieveScopeChain(Scope* scope,
12350                           Handle<SharedFunctionInfo> shared_info) {
12351     if (scope != NULL) {
12352       int source_position = shared_info->code()->SourcePosition(frame_->pc());
12353       scope->GetNestedScopeChain(&nested_scope_chain_, source_position);
12354     } else {
12355       // A failed reparse indicates that the preparser has diverged from the
12356       // parser or that the preparse data given to the initial parse has been
12357       // faulty. We fail in debug mode but in release mode we only provide the
12358       // information we get from the context chain but nothing about
12359       // completely stack allocated scopes or stack allocated locals.
12360       // Or it could be due to stack overflow.
12361       DCHECK(isolate_->has_pending_exception());
12362       failed_ = true;
12363     }
12364   }
12365
12366   DISALLOW_IMPLICIT_CONSTRUCTORS(ScopeIterator);
12367 };
12368
12369
12370 RUNTIME_FUNCTION(Runtime_GetScopeCount) {
12371   HandleScope scope(isolate);
12372   DCHECK(args.length() == 2);
12373   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
12374   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
12375
12376   CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
12377
12378   // Get the frame where the debugging is performed.
12379   StackFrame::Id id = UnwrapFrameId(wrapped_id);
12380   JavaScriptFrameIterator it(isolate, id);
12381   JavaScriptFrame* frame = it.frame();
12382
12383   // Count the visible scopes.
12384   int n = 0;
12385   for (ScopeIterator it(isolate, frame, 0);
12386        !it.Done();
12387        it.Next()) {
12388     n++;
12389   }
12390
12391   return Smi::FromInt(n);
12392 }
12393
12394
12395 // Returns the list of step-in positions (text offset) in a function of the
12396 // stack frame in a range from the current debug break position to the end
12397 // of the corresponding statement.
12398 RUNTIME_FUNCTION(Runtime_GetStepInPositions) {
12399   HandleScope scope(isolate);
12400   DCHECK(args.length() == 2);
12401   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
12402   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
12403
12404   CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
12405
12406   // Get the frame where the debugging is performed.
12407   StackFrame::Id id = UnwrapFrameId(wrapped_id);
12408   JavaScriptFrameIterator frame_it(isolate, id);
12409   RUNTIME_ASSERT(!frame_it.done());
12410
12411   JavaScriptFrame* frame = frame_it.frame();
12412
12413   Handle<JSFunction> fun =
12414       Handle<JSFunction>(frame->function());
12415   Handle<SharedFunctionInfo> shared =
12416       Handle<SharedFunctionInfo>(fun->shared());
12417
12418   if (!isolate->debug()->EnsureDebugInfo(shared, fun)) {
12419     return isolate->heap()->undefined_value();
12420   }
12421
12422   Handle<DebugInfo> debug_info = Debug::GetDebugInfo(shared);
12423
12424   int len = 0;
12425   Handle<JSArray> array(isolate->factory()->NewJSArray(10));
12426   // Find the break point where execution has stopped.
12427   BreakLocationIterator break_location_iterator(debug_info,
12428                                                 ALL_BREAK_LOCATIONS);
12429
12430   break_location_iterator.FindBreakLocationFromAddress(frame->pc() - 1);
12431   int current_statement_pos = break_location_iterator.statement_position();
12432
12433   while (!break_location_iterator.Done()) {
12434     bool accept;
12435     if (break_location_iterator.pc() > frame->pc()) {
12436       accept = true;
12437     } else {
12438       StackFrame::Id break_frame_id = isolate->debug()->break_frame_id();
12439       // The break point is near our pc. Could be a step-in possibility,
12440       // that is currently taken by active debugger call.
12441       if (break_frame_id == StackFrame::NO_ID) {
12442         // We are not stepping.
12443         accept = false;
12444       } else {
12445         JavaScriptFrameIterator additional_frame_it(isolate, break_frame_id);
12446         // If our frame is a top frame and we are stepping, we can do step-in
12447         // at this place.
12448         accept = additional_frame_it.frame()->id() == id;
12449       }
12450     }
12451     if (accept) {
12452       if (break_location_iterator.IsStepInLocation(isolate)) {
12453         Smi* position_value = Smi::FromInt(break_location_iterator.position());
12454         RETURN_FAILURE_ON_EXCEPTION(
12455             isolate,
12456             JSObject::SetElement(array, len,
12457                                  Handle<Object>(position_value, isolate),
12458                                  NONE, SLOPPY));
12459         len++;
12460       }
12461     }
12462     // Advance iterator.
12463     break_location_iterator.Next();
12464     if (current_statement_pos !=
12465         break_location_iterator.statement_position()) {
12466       break;
12467     }
12468   }
12469   return *array;
12470 }
12471
12472
12473 static const int kScopeDetailsTypeIndex = 0;
12474 static const int kScopeDetailsObjectIndex = 1;
12475 static const int kScopeDetailsSize = 2;
12476
12477
12478 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeScopeDetails(
12479     Isolate* isolate,
12480     ScopeIterator* it) {
12481   // Calculate the size of the result.
12482   int details_size = kScopeDetailsSize;
12483   Handle<FixedArray> details = isolate->factory()->NewFixedArray(details_size);
12484
12485   // Fill in scope details.
12486   details->set(kScopeDetailsTypeIndex, Smi::FromInt(it->Type()));
12487   Handle<JSObject> scope_object;
12488   ASSIGN_RETURN_ON_EXCEPTION(
12489       isolate, scope_object, it->ScopeObject(), JSObject);
12490   details->set(kScopeDetailsObjectIndex, *scope_object);
12491
12492   return isolate->factory()->NewJSArrayWithElements(details);
12493 }
12494
12495
12496 // Return an array with scope details
12497 // args[0]: number: break id
12498 // args[1]: number: frame index
12499 // args[2]: number: inlined frame index
12500 // args[3]: number: scope index
12501 //
12502 // The array returned contains the following information:
12503 // 0: Scope type
12504 // 1: Scope object
12505 RUNTIME_FUNCTION(Runtime_GetScopeDetails) {
12506   HandleScope scope(isolate);
12507   DCHECK(args.length() == 4);
12508   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
12509   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
12510
12511   CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
12512   CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
12513   CONVERT_NUMBER_CHECKED(int, index, Int32, args[3]);
12514
12515   // Get the frame where the debugging is performed.
12516   StackFrame::Id id = UnwrapFrameId(wrapped_id);
12517   JavaScriptFrameIterator frame_it(isolate, id);
12518   JavaScriptFrame* frame = frame_it.frame();
12519
12520   // Find the requested scope.
12521   int n = 0;
12522   ScopeIterator it(isolate, frame, inlined_jsframe_index);
12523   for (; !it.Done() && n < index; it.Next()) {
12524     n++;
12525   }
12526   if (it.Done()) {
12527     return isolate->heap()->undefined_value();
12528   }
12529   Handle<JSObject> details;
12530   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
12531       isolate, details, MaterializeScopeDetails(isolate, &it));
12532   return *details;
12533 }
12534
12535
12536 // Return an array of scope details
12537 // args[0]: number: break id
12538 // args[1]: number: frame index
12539 // args[2]: number: inlined frame index
12540 // args[3]: boolean: ignore nested scopes
12541 //
12542 // The array returned contains arrays with the following information:
12543 // 0: Scope type
12544 // 1: Scope object
12545 RUNTIME_FUNCTION(Runtime_GetAllScopesDetails) {
12546   HandleScope scope(isolate);
12547   DCHECK(args.length() == 3 || args.length() == 4);
12548   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
12549   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
12550
12551   CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
12552   CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
12553
12554   bool ignore_nested_scopes = false;
12555   if (args.length() == 4) {
12556     CONVERT_BOOLEAN_ARG_CHECKED(flag, 3);
12557     ignore_nested_scopes = flag;
12558   }
12559
12560   // Get the frame where the debugging is performed.
12561   StackFrame::Id id = UnwrapFrameId(wrapped_id);
12562   JavaScriptFrameIterator frame_it(isolate, id);
12563   JavaScriptFrame* frame = frame_it.frame();
12564
12565   List<Handle<JSObject> > result(4);
12566   ScopeIterator it(isolate, frame, inlined_jsframe_index, ignore_nested_scopes);
12567   for (; !it.Done(); it.Next()) {
12568     Handle<JSObject> details;
12569     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
12570         isolate, details, MaterializeScopeDetails(isolate, &it));
12571     result.Add(details);
12572   }
12573
12574   Handle<FixedArray> array = isolate->factory()->NewFixedArray(result.length());
12575   for (int i = 0; i < result.length(); ++i) {
12576     array->set(i, *result[i]);
12577   }
12578   return *isolate->factory()->NewJSArrayWithElements(array);
12579 }
12580
12581
12582 RUNTIME_FUNCTION(Runtime_GetFunctionScopeCount) {
12583   HandleScope scope(isolate);
12584   DCHECK(args.length() == 1);
12585
12586   // Check arguments.
12587   CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
12588
12589   // Count the visible scopes.
12590   int n = 0;
12591   for (ScopeIterator it(isolate, fun); !it.Done(); it.Next()) {
12592     n++;
12593   }
12594
12595   return Smi::FromInt(n);
12596 }
12597
12598
12599 RUNTIME_FUNCTION(Runtime_GetFunctionScopeDetails) {
12600   HandleScope scope(isolate);
12601   DCHECK(args.length() == 2);
12602
12603   // Check arguments.
12604   CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
12605   CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
12606
12607   // Find the requested scope.
12608   int n = 0;
12609   ScopeIterator it(isolate, fun);
12610   for (; !it.Done() && n < index; it.Next()) {
12611     n++;
12612   }
12613   if (it.Done()) {
12614     return isolate->heap()->undefined_value();
12615   }
12616
12617   Handle<JSObject> details;
12618   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
12619       isolate, details, MaterializeScopeDetails(isolate, &it));
12620   return *details;
12621 }
12622
12623
12624 static bool SetScopeVariableValue(ScopeIterator* it, int index,
12625                                   Handle<String> variable_name,
12626                                   Handle<Object> new_value) {
12627   for (int n = 0; !it->Done() && n < index; it->Next()) {
12628     n++;
12629   }
12630   if (it->Done()) {
12631     return false;
12632   }
12633   return it->SetVariableValue(variable_name, new_value);
12634 }
12635
12636
12637 // Change variable value in closure or local scope
12638 // args[0]: number or JsFunction: break id or function
12639 // args[1]: number: frame index (when arg[0] is break id)
12640 // args[2]: number: inlined frame index (when arg[0] is break id)
12641 // args[3]: number: scope index
12642 // args[4]: string: variable name
12643 // args[5]: object: new value
12644 //
12645 // Return true if success and false otherwise
12646 RUNTIME_FUNCTION(Runtime_SetScopeVariableValue) {
12647   HandleScope scope(isolate);
12648   DCHECK(args.length() == 6);
12649
12650   // Check arguments.
12651   CONVERT_NUMBER_CHECKED(int, index, Int32, args[3]);
12652   CONVERT_ARG_HANDLE_CHECKED(String, variable_name, 4);
12653   CONVERT_ARG_HANDLE_CHECKED(Object, new_value, 5);
12654
12655   bool res;
12656   if (args[0]->IsNumber()) {
12657     CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
12658     RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
12659
12660     CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
12661     CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
12662
12663     // Get the frame where the debugging is performed.
12664     StackFrame::Id id = UnwrapFrameId(wrapped_id);
12665     JavaScriptFrameIterator frame_it(isolate, id);
12666     JavaScriptFrame* frame = frame_it.frame();
12667
12668     ScopeIterator it(isolate, frame, inlined_jsframe_index);
12669     res = SetScopeVariableValue(&it, index, variable_name, new_value);
12670   } else {
12671     CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
12672     ScopeIterator it(isolate, fun);
12673     res = SetScopeVariableValue(&it, index, variable_name, new_value);
12674   }
12675
12676   return isolate->heap()->ToBoolean(res);
12677 }
12678
12679
12680 RUNTIME_FUNCTION(Runtime_DebugPrintScopes) {
12681   HandleScope scope(isolate);
12682   DCHECK(args.length() == 0);
12683
12684 #ifdef DEBUG
12685   // Print the scopes for the top frame.
12686   StackFrameLocator locator(isolate);
12687   JavaScriptFrame* frame = locator.FindJavaScriptFrame(0);
12688   for (ScopeIterator it(isolate, frame, 0);
12689        !it.Done();
12690        it.Next()) {
12691     it.DebugPrint();
12692   }
12693 #endif
12694   return isolate->heap()->undefined_value();
12695 }
12696
12697
12698 RUNTIME_FUNCTION(Runtime_GetThreadCount) {
12699   HandleScope scope(isolate);
12700   DCHECK(args.length() == 1);
12701   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
12702   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
12703
12704   // Count all archived V8 threads.
12705   int n = 0;
12706   for (ThreadState* thread =
12707           isolate->thread_manager()->FirstThreadStateInUse();
12708        thread != NULL;
12709        thread = thread->Next()) {
12710     n++;
12711   }
12712
12713   // Total number of threads is current thread and archived threads.
12714   return Smi::FromInt(n + 1);
12715 }
12716
12717
12718 static const int kThreadDetailsCurrentThreadIndex = 0;
12719 static const int kThreadDetailsThreadIdIndex = 1;
12720 static const int kThreadDetailsSize = 2;
12721
12722 // Return an array with thread details
12723 // args[0]: number: break id
12724 // args[1]: number: thread index
12725 //
12726 // The array returned contains the following information:
12727 // 0: Is current thread?
12728 // 1: Thread id
12729 RUNTIME_FUNCTION(Runtime_GetThreadDetails) {
12730   HandleScope scope(isolate);
12731   DCHECK(args.length() == 2);
12732   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
12733   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
12734
12735   CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
12736
12737   // Allocate array for result.
12738   Handle<FixedArray> details =
12739       isolate->factory()->NewFixedArray(kThreadDetailsSize);
12740
12741   // Thread index 0 is current thread.
12742   if (index == 0) {
12743     // Fill the details.
12744     details->set(kThreadDetailsCurrentThreadIndex,
12745                  isolate->heap()->true_value());
12746     details->set(kThreadDetailsThreadIdIndex,
12747                  Smi::FromInt(ThreadId::Current().ToInteger()));
12748   } else {
12749     // Find the thread with the requested index.
12750     int n = 1;
12751     ThreadState* thread =
12752         isolate->thread_manager()->FirstThreadStateInUse();
12753     while (index != n && thread != NULL) {
12754       thread = thread->Next();
12755       n++;
12756     }
12757     if (thread == NULL) {
12758       return isolate->heap()->undefined_value();
12759     }
12760
12761     // Fill the details.
12762     details->set(kThreadDetailsCurrentThreadIndex,
12763                  isolate->heap()->false_value());
12764     details->set(kThreadDetailsThreadIdIndex,
12765                  Smi::FromInt(thread->id().ToInteger()));
12766   }
12767
12768   // Convert to JS array and return.
12769   return *isolate->factory()->NewJSArrayWithElements(details);
12770 }
12771
12772
12773 // Sets the disable break state
12774 // args[0]: disable break state
12775 RUNTIME_FUNCTION(Runtime_SetDisableBreak) {
12776   HandleScope scope(isolate);
12777   DCHECK(args.length() == 1);
12778   CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 0);
12779   isolate->debug()->set_disable_break(disable_break);
12780   return  isolate->heap()->undefined_value();
12781 }
12782
12783
12784 static bool IsPositionAlignmentCodeCorrect(int alignment) {
12785   return alignment == STATEMENT_ALIGNED || alignment == BREAK_POSITION_ALIGNED;
12786 }
12787
12788
12789 RUNTIME_FUNCTION(Runtime_GetBreakLocations) {
12790   HandleScope scope(isolate);
12791   DCHECK(args.length() == 2);
12792
12793   CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
12794   CONVERT_NUMBER_CHECKED(int32_t, statement_aligned_code, Int32, args[1]);
12795
12796   if (!IsPositionAlignmentCodeCorrect(statement_aligned_code)) {
12797     return isolate->ThrowIllegalOperation();
12798   }
12799   BreakPositionAlignment alignment =
12800       static_cast<BreakPositionAlignment>(statement_aligned_code);
12801
12802   Handle<SharedFunctionInfo> shared(fun->shared());
12803   // Find the number of break points
12804   Handle<Object> break_locations =
12805       Debug::GetSourceBreakLocations(shared, alignment);
12806   if (break_locations->IsUndefined()) return isolate->heap()->undefined_value();
12807   // Return array as JS array
12808   return *isolate->factory()->NewJSArrayWithElements(
12809       Handle<FixedArray>::cast(break_locations));
12810 }
12811
12812
12813 // Set a break point in a function.
12814 // args[0]: function
12815 // args[1]: number: break source position (within the function source)
12816 // args[2]: number: break point object
12817 RUNTIME_FUNCTION(Runtime_SetFunctionBreakPoint) {
12818   HandleScope scope(isolate);
12819   DCHECK(args.length() == 3);
12820   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
12821   CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
12822   RUNTIME_ASSERT(source_position >= function->shared()->start_position() &&
12823                  source_position <= function->shared()->end_position());
12824   CONVERT_ARG_HANDLE_CHECKED(Object, break_point_object_arg, 2);
12825
12826   // Set break point.
12827   RUNTIME_ASSERT(isolate->debug()->SetBreakPoint(
12828       function, break_point_object_arg, &source_position));
12829
12830   return Smi::FromInt(source_position);
12831 }
12832
12833
12834 // Changes the state of a break point in a script and returns source position
12835 // where break point was set. NOTE: Regarding performance see the NOTE for
12836 // GetScriptFromScriptData.
12837 // args[0]: script to set break point in
12838 // args[1]: number: break source position (within the script source)
12839 // args[2]: number, breakpoint position alignment
12840 // args[3]: number: break point object
12841 RUNTIME_FUNCTION(Runtime_SetScriptBreakPoint) {
12842   HandleScope scope(isolate);
12843   DCHECK(args.length() == 4);
12844   CONVERT_ARG_HANDLE_CHECKED(JSValue, wrapper, 0);
12845   CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
12846   RUNTIME_ASSERT(source_position >= 0);
12847   CONVERT_NUMBER_CHECKED(int32_t, statement_aligned_code, Int32, args[2]);
12848   CONVERT_ARG_HANDLE_CHECKED(Object, break_point_object_arg, 3);
12849
12850   if (!IsPositionAlignmentCodeCorrect(statement_aligned_code)) {
12851     return isolate->ThrowIllegalOperation();
12852   }
12853   BreakPositionAlignment alignment =
12854       static_cast<BreakPositionAlignment>(statement_aligned_code);
12855
12856   // Get the script from the script wrapper.
12857   RUNTIME_ASSERT(wrapper->value()->IsScript());
12858   Handle<Script> script(Script::cast(wrapper->value()));
12859
12860   // Set break point.
12861   if (!isolate->debug()->SetBreakPointForScript(script, break_point_object_arg,
12862                                                 &source_position,
12863                                                 alignment)) {
12864     return isolate->heap()->undefined_value();
12865   }
12866
12867   return Smi::FromInt(source_position);
12868 }
12869
12870
12871 // Clear a break point
12872 // args[0]: number: break point object
12873 RUNTIME_FUNCTION(Runtime_ClearBreakPoint) {
12874   HandleScope scope(isolate);
12875   DCHECK(args.length() == 1);
12876   CONVERT_ARG_HANDLE_CHECKED(Object, break_point_object_arg, 0);
12877
12878   // Clear break point.
12879   isolate->debug()->ClearBreakPoint(break_point_object_arg);
12880
12881   return isolate->heap()->undefined_value();
12882 }
12883
12884
12885 // Change the state of break on exceptions.
12886 // args[0]: Enum value indicating whether to affect caught/uncaught exceptions.
12887 // args[1]: Boolean indicating on/off.
12888 RUNTIME_FUNCTION(Runtime_ChangeBreakOnException) {
12889   HandleScope scope(isolate);
12890   DCHECK(args.length() == 2);
12891   CONVERT_NUMBER_CHECKED(uint32_t, type_arg, Uint32, args[0]);
12892   CONVERT_BOOLEAN_ARG_CHECKED(enable, 1);
12893
12894   // If the number doesn't match an enum value, the ChangeBreakOnException
12895   // function will default to affecting caught exceptions.
12896   ExceptionBreakType type = static_cast<ExceptionBreakType>(type_arg);
12897   // Update break point state.
12898   isolate->debug()->ChangeBreakOnException(type, enable);
12899   return isolate->heap()->undefined_value();
12900 }
12901
12902
12903 // Returns the state of break on exceptions
12904 // args[0]: boolean indicating uncaught exceptions
12905 RUNTIME_FUNCTION(Runtime_IsBreakOnException) {
12906   HandleScope scope(isolate);
12907   DCHECK(args.length() == 1);
12908   CONVERT_NUMBER_CHECKED(uint32_t, type_arg, Uint32, args[0]);
12909
12910   ExceptionBreakType type = static_cast<ExceptionBreakType>(type_arg);
12911   bool result = isolate->debug()->IsBreakOnException(type);
12912   return Smi::FromInt(result);
12913 }
12914
12915
12916 // Prepare for stepping
12917 // args[0]: break id for checking execution state
12918 // args[1]: step action from the enumeration StepAction
12919 // args[2]: number of times to perform the step, for step out it is the number
12920 //          of frames to step down.
12921 RUNTIME_FUNCTION(Runtime_PrepareStep) {
12922   HandleScope scope(isolate);
12923   DCHECK(args.length() == 4);
12924   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
12925   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
12926
12927   if (!args[1]->IsNumber() || !args[2]->IsNumber()) {
12928     return isolate->Throw(isolate->heap()->illegal_argument_string());
12929   }
12930
12931   CONVERT_NUMBER_CHECKED(int, wrapped_frame_id, Int32, args[3]);
12932
12933   StackFrame::Id frame_id;
12934   if (wrapped_frame_id == 0) {
12935     frame_id = StackFrame::NO_ID;
12936   } else {
12937     frame_id = UnwrapFrameId(wrapped_frame_id);
12938   }
12939
12940   // Get the step action and check validity.
12941   StepAction step_action = static_cast<StepAction>(NumberToInt32(args[1]));
12942   if (step_action != StepIn &&
12943       step_action != StepNext &&
12944       step_action != StepOut &&
12945       step_action != StepInMin &&
12946       step_action != StepMin) {
12947     return isolate->Throw(isolate->heap()->illegal_argument_string());
12948   }
12949
12950   if (frame_id != StackFrame::NO_ID && step_action != StepNext &&
12951       step_action != StepMin && step_action != StepOut) {
12952     return isolate->ThrowIllegalOperation();
12953   }
12954
12955   // Get the number of steps.
12956   int step_count = NumberToInt32(args[2]);
12957   if (step_count < 1) {
12958     return isolate->Throw(isolate->heap()->illegal_argument_string());
12959   }
12960
12961   // Clear all current stepping setup.
12962   isolate->debug()->ClearStepping();
12963
12964   // Prepare step.
12965   isolate->debug()->PrepareStep(static_cast<StepAction>(step_action),
12966                                 step_count,
12967                                 frame_id);
12968   return isolate->heap()->undefined_value();
12969 }
12970
12971
12972 // Clear all stepping set by PrepareStep.
12973 RUNTIME_FUNCTION(Runtime_ClearStepping) {
12974   HandleScope scope(isolate);
12975   DCHECK(args.length() == 0);
12976   isolate->debug()->ClearStepping();
12977   return isolate->heap()->undefined_value();
12978 }
12979
12980
12981 // Helper function to find or create the arguments object for
12982 // Runtime_DebugEvaluate.
12983 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeArgumentsObject(
12984     Isolate* isolate,
12985     Handle<JSObject> target,
12986     Handle<JSFunction> function) {
12987   // Do not materialize the arguments object for eval or top-level code.
12988   // Skip if "arguments" is already taken.
12989   if (!function->shared()->is_function()) return target;
12990   Maybe<bool> maybe = JSReceiver::HasOwnProperty(
12991       target, isolate->factory()->arguments_string());
12992   if (!maybe.has_value) return MaybeHandle<JSObject>();
12993   if (maybe.value) return target;
12994
12995   // FunctionGetArguments can't throw an exception.
12996   Handle<JSObject> arguments = Handle<JSObject>::cast(
12997       Accessors::FunctionGetArguments(function));
12998   Handle<String> arguments_str = isolate->factory()->arguments_string();
12999   RETURN_ON_EXCEPTION(
13000       isolate,
13001       Runtime::DefineObjectProperty(target, arguments_str, arguments, NONE),
13002       JSObject);
13003   return target;
13004 }
13005
13006
13007 // Compile and evaluate source for the given context.
13008 static MaybeHandle<Object> DebugEvaluate(Isolate* isolate,
13009                                          Handle<Context> context,
13010                                          Handle<Object> context_extension,
13011                                          Handle<Object> receiver,
13012                                          Handle<String> source) {
13013   if (context_extension->IsJSObject()) {
13014     Handle<JSObject> extension = Handle<JSObject>::cast(context_extension);
13015     Handle<JSFunction> closure(context->closure(), isolate);
13016     context = isolate->factory()->NewWithContext(closure, context, extension);
13017   }
13018
13019   Handle<JSFunction> eval_fun;
13020   ASSIGN_RETURN_ON_EXCEPTION(
13021       isolate, eval_fun,
13022       Compiler::GetFunctionFromEval(source,
13023                                     context,
13024                                     SLOPPY,
13025                                     NO_PARSE_RESTRICTION,
13026                                     RelocInfo::kNoPosition),
13027       Object);
13028
13029   Handle<Object> result;
13030   ASSIGN_RETURN_ON_EXCEPTION(
13031       isolate, result,
13032       Execution::Call(isolate, eval_fun, receiver, 0, NULL),
13033       Object);
13034
13035   // Skip the global proxy as it has no properties and always delegates to the
13036   // real global object.
13037   if (result->IsJSGlobalProxy()) {
13038     PrototypeIterator iter(isolate, result);
13039     // TODO(verwaest): This will crash when the global proxy is detached.
13040     result = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
13041   }
13042
13043   // Clear the oneshot breakpoints so that the debugger does not step further.
13044   isolate->debug()->ClearStepping();
13045   return result;
13046 }
13047
13048
13049 // Evaluate a piece of JavaScript in the context of a stack frame for
13050 // debugging.  Things that need special attention are:
13051 // - Parameters and stack-allocated locals need to be materialized.  Altered
13052 //   values need to be written back to the stack afterwards.
13053 // - The arguments object needs to materialized.
13054 RUNTIME_FUNCTION(Runtime_DebugEvaluate) {
13055   HandleScope scope(isolate);
13056
13057   // Check the execution state and decode arguments frame and source to be
13058   // evaluated.
13059   DCHECK(args.length() == 6);
13060   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
13061   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
13062
13063   CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
13064   CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
13065   CONVERT_ARG_HANDLE_CHECKED(String, source, 3);
13066   CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 4);
13067   CONVERT_ARG_HANDLE_CHECKED(Object, context_extension, 5);
13068
13069   // Handle the processing of break.
13070   DisableBreak disable_break_scope(isolate->debug(), disable_break);
13071
13072   // Get the frame where the debugging is performed.
13073   StackFrame::Id id = UnwrapFrameId(wrapped_id);
13074   JavaScriptFrameIterator it(isolate, id);
13075   JavaScriptFrame* frame = it.frame();
13076   FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate);
13077   Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction()));
13078
13079   // Traverse the saved contexts chain to find the active context for the
13080   // selected frame.
13081   SaveContext* save = FindSavedContextForFrame(isolate, frame);
13082
13083   SaveContext savex(isolate);
13084   isolate->set_context(*(save->context()));
13085
13086   // Evaluate on the context of the frame.
13087   Handle<Context> context(Context::cast(frame->context()));
13088   DCHECK(!context.is_null());
13089
13090   // Materialize stack locals and the arguments object.
13091   Handle<JSObject> materialized =
13092       isolate->factory()->NewJSObject(isolate->object_function());
13093
13094   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
13095       isolate, materialized,
13096       MaterializeStackLocalsWithFrameInspector(
13097           isolate, materialized, function, &frame_inspector));
13098
13099   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
13100       isolate, materialized,
13101       MaterializeArgumentsObject(isolate, materialized, function));
13102
13103   // Add the materialized object in a with-scope to shadow the stack locals.
13104   context = isolate->factory()->NewWithContext(function, context, materialized);
13105
13106   Handle<Object> receiver(frame->receiver(), isolate);
13107   Handle<Object> result;
13108   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
13109       isolate, result,
13110       DebugEvaluate(isolate, context, context_extension, receiver, source));
13111
13112   // Write back potential changes to materialized stack locals to the stack.
13113   UpdateStackLocalsFromMaterializedObject(
13114       isolate, materialized, function, frame, inlined_jsframe_index);
13115
13116   return *result;
13117 }
13118
13119
13120 RUNTIME_FUNCTION(Runtime_DebugEvaluateGlobal) {
13121   HandleScope scope(isolate);
13122
13123   // Check the execution state and decode arguments frame and source to be
13124   // evaluated.
13125   DCHECK(args.length() == 4);
13126   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
13127   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
13128
13129   CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
13130   CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 2);
13131   CONVERT_ARG_HANDLE_CHECKED(Object, context_extension, 3);
13132
13133   // Handle the processing of break.
13134   DisableBreak disable_break_scope(isolate->debug(), disable_break);
13135
13136   // Enter the top context from before the debugger was invoked.
13137   SaveContext save(isolate);
13138   SaveContext* top = &save;
13139   while (top != NULL && *top->context() == *isolate->debug()->debug_context()) {
13140     top = top->prev();
13141   }
13142   if (top != NULL) {
13143     isolate->set_context(*top->context());
13144   }
13145
13146   // Get the native context now set to the top context from before the
13147   // debugger was invoked.
13148   Handle<Context> context = isolate->native_context();
13149   Handle<JSObject> receiver(context->global_proxy());
13150   Handle<Object> result;
13151   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
13152       isolate, result,
13153       DebugEvaluate(isolate, context, context_extension, receiver, source));
13154   return *result;
13155 }
13156
13157
13158 RUNTIME_FUNCTION(Runtime_DebugGetLoadedScripts) {
13159   HandleScope scope(isolate);
13160   DCHECK(args.length() == 0);
13161
13162   // Fill the script objects.
13163   Handle<FixedArray> instances = isolate->debug()->GetLoadedScripts();
13164
13165   // Convert the script objects to proper JS objects.
13166   for (int i = 0; i < instances->length(); i++) {
13167     Handle<Script> script = Handle<Script>(Script::cast(instances->get(i)));
13168     // Get the script wrapper in a local handle before calling GetScriptWrapper,
13169     // because using
13170     //   instances->set(i, *GetScriptWrapper(script))
13171     // is unsafe as GetScriptWrapper might call GC and the C++ compiler might
13172     // already have dereferenced the instances handle.
13173     Handle<JSObject> wrapper = Script::GetWrapper(script);
13174     instances->set(i, *wrapper);
13175   }
13176
13177   // Return result as a JS array.
13178   Handle<JSObject> result =
13179       isolate->factory()->NewJSObject(isolate->array_function());
13180   JSArray::SetContent(Handle<JSArray>::cast(result), instances);
13181   return *result;
13182 }
13183
13184
13185 // Helper function used by Runtime_DebugReferencedBy below.
13186 static int DebugReferencedBy(HeapIterator* iterator,
13187                              JSObject* target,
13188                              Object* instance_filter, int max_references,
13189                              FixedArray* instances, int instances_size,
13190                              JSFunction* arguments_function) {
13191   Isolate* isolate = target->GetIsolate();
13192   SealHandleScope shs(isolate);
13193   DisallowHeapAllocation no_allocation;
13194
13195   // Iterate the heap.
13196   int count = 0;
13197   JSObject* last = NULL;
13198   HeapObject* heap_obj = NULL;
13199   while (((heap_obj = iterator->next()) != NULL) &&
13200          (max_references == 0 || count < max_references)) {
13201     // Only look at all JSObjects.
13202     if (heap_obj->IsJSObject()) {
13203       // Skip context extension objects and argument arrays as these are
13204       // checked in the context of functions using them.
13205       JSObject* obj = JSObject::cast(heap_obj);
13206       if (obj->IsJSContextExtensionObject() ||
13207           obj->map()->constructor() == arguments_function) {
13208         continue;
13209       }
13210
13211       // Check if the JS object has a reference to the object looked for.
13212       if (obj->ReferencesObject(target)) {
13213         // Check instance filter if supplied. This is normally used to avoid
13214         // references from mirror objects (see Runtime_IsInPrototypeChain).
13215         if (!instance_filter->IsUndefined()) {
13216           for (PrototypeIterator iter(isolate, obj); !iter.IsAtEnd();
13217                iter.Advance()) {
13218             if (iter.GetCurrent() == instance_filter) {
13219               obj = NULL;  // Don't add this object.
13220               break;
13221             }
13222           }
13223         }
13224
13225         if (obj != NULL) {
13226           // Valid reference found add to instance array if supplied an update
13227           // count.
13228           if (instances != NULL && count < instances_size) {
13229             instances->set(count, obj);
13230           }
13231           last = obj;
13232           count++;
13233         }
13234       }
13235     }
13236   }
13237
13238   // Check for circular reference only. This can happen when the object is only
13239   // referenced from mirrors and has a circular reference in which case the
13240   // object is not really alive and would have been garbage collected if not
13241   // referenced from the mirror.
13242   if (count == 1 && last == target) {
13243     count = 0;
13244   }
13245
13246   // Return the number of referencing objects found.
13247   return count;
13248 }
13249
13250
13251 // Scan the heap for objects with direct references to an object
13252 // args[0]: the object to find references to
13253 // args[1]: constructor function for instances to exclude (Mirror)
13254 // args[2]: the the maximum number of objects to return
13255 RUNTIME_FUNCTION(Runtime_DebugReferencedBy) {
13256   HandleScope scope(isolate);
13257   DCHECK(args.length() == 3);
13258
13259   // Check parameters.
13260   CONVERT_ARG_HANDLE_CHECKED(JSObject, target, 0);
13261   CONVERT_ARG_HANDLE_CHECKED(Object, instance_filter, 1);
13262   RUNTIME_ASSERT(instance_filter->IsUndefined() ||
13263                  instance_filter->IsJSObject());
13264   CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[2]);
13265   RUNTIME_ASSERT(max_references >= 0);
13266
13267
13268   // Get the constructor function for context extension and arguments array.
13269   Handle<JSFunction> arguments_function(
13270       JSFunction::cast(isolate->sloppy_arguments_map()->constructor()));
13271
13272   // Get the number of referencing objects.
13273   int count;
13274   // First perform a full GC in order to avoid dead objects and to make the heap
13275   // iterable.
13276   Heap* heap = isolate->heap();
13277   heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "%DebugConstructedBy");
13278   {
13279     HeapIterator heap_iterator(heap);
13280     count = DebugReferencedBy(&heap_iterator,
13281                               *target, *instance_filter, max_references,
13282                               NULL, 0, *arguments_function);
13283   }
13284
13285   // Allocate an array to hold the result.
13286   Handle<FixedArray> instances = isolate->factory()->NewFixedArray(count);
13287
13288   // Fill the referencing objects.
13289   {
13290     HeapIterator heap_iterator(heap);
13291     count = DebugReferencedBy(&heap_iterator,
13292                               *target, *instance_filter, max_references,
13293                               *instances, count, *arguments_function);
13294   }
13295
13296   // Return result as JS array.
13297   Handle<JSFunction> constructor = isolate->array_function();
13298
13299   Handle<JSObject> result = isolate->factory()->NewJSObject(constructor);
13300   JSArray::SetContent(Handle<JSArray>::cast(result), instances);
13301   return *result;
13302 }
13303
13304
13305 // Helper function used by Runtime_DebugConstructedBy below.
13306 static int DebugConstructedBy(HeapIterator* iterator,
13307                               JSFunction* constructor,
13308                               int max_references,
13309                               FixedArray* instances,
13310                               int instances_size) {
13311   DisallowHeapAllocation no_allocation;
13312
13313   // Iterate the heap.
13314   int count = 0;
13315   HeapObject* heap_obj = NULL;
13316   while (((heap_obj = iterator->next()) != NULL) &&
13317          (max_references == 0 || count < max_references)) {
13318     // Only look at all JSObjects.
13319     if (heap_obj->IsJSObject()) {
13320       JSObject* obj = JSObject::cast(heap_obj);
13321       if (obj->map()->constructor() == constructor) {
13322         // Valid reference found add to instance array if supplied an update
13323         // count.
13324         if (instances != NULL && count < instances_size) {
13325           instances->set(count, obj);
13326         }
13327         count++;
13328       }
13329     }
13330   }
13331
13332   // Return the number of referencing objects found.
13333   return count;
13334 }
13335
13336
13337 // Scan the heap for objects constructed by a specific function.
13338 // args[0]: the constructor to find instances of
13339 // args[1]: the the maximum number of objects to return
13340 RUNTIME_FUNCTION(Runtime_DebugConstructedBy) {
13341   HandleScope scope(isolate);
13342   DCHECK(args.length() == 2);
13343
13344
13345   // Check parameters.
13346   CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, 0);
13347   CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[1]);
13348   RUNTIME_ASSERT(max_references >= 0);
13349
13350   // Get the number of referencing objects.
13351   int count;
13352   // First perform a full GC in order to avoid dead objects and to make the heap
13353   // iterable.
13354   Heap* heap = isolate->heap();
13355   heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "%DebugConstructedBy");
13356   {
13357     HeapIterator heap_iterator(heap);
13358     count = DebugConstructedBy(&heap_iterator,
13359                                *constructor,
13360                                max_references,
13361                                NULL,
13362                                0);
13363   }
13364
13365   // Allocate an array to hold the result.
13366   Handle<FixedArray> instances = isolate->factory()->NewFixedArray(count);
13367
13368   // Fill the referencing objects.
13369   {
13370     HeapIterator heap_iterator2(heap);
13371     count = DebugConstructedBy(&heap_iterator2,
13372                                *constructor,
13373                                max_references,
13374                                *instances,
13375                                count);
13376   }
13377
13378   // Return result as JS array.
13379   Handle<JSFunction> array_function = isolate->array_function();
13380   Handle<JSObject> result = isolate->factory()->NewJSObject(array_function);
13381   JSArray::SetContent(Handle<JSArray>::cast(result), instances);
13382   return *result;
13383 }
13384
13385
13386 // Find the effective prototype object as returned by __proto__.
13387 // args[0]: the object to find the prototype for.
13388 RUNTIME_FUNCTION(Runtime_DebugGetPrototype) {
13389   HandleScope shs(isolate);
13390   DCHECK(args.length() == 1);
13391   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
13392   return *GetPrototypeSkipHiddenPrototypes(isolate, obj);
13393 }
13394
13395
13396 // Patches script source (should be called upon BeforeCompile event).
13397 RUNTIME_FUNCTION(Runtime_DebugSetScriptSource) {
13398   HandleScope scope(isolate);
13399   DCHECK(args.length() == 2);
13400
13401   CONVERT_ARG_HANDLE_CHECKED(JSValue, script_wrapper, 0);
13402   CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
13403
13404   RUNTIME_ASSERT(script_wrapper->value()->IsScript());
13405   Handle<Script> script(Script::cast(script_wrapper->value()));
13406
13407   int compilation_state = script->compilation_state();
13408   RUNTIME_ASSERT(compilation_state == Script::COMPILATION_STATE_INITIAL);
13409   script->set_source(*source);
13410
13411   return isolate->heap()->undefined_value();
13412 }
13413
13414
13415 RUNTIME_FUNCTION(Runtime_SystemBreak) {
13416   SealHandleScope shs(isolate);
13417   DCHECK(args.length() == 0);
13418   base::OS::DebugBreak();
13419   return isolate->heap()->undefined_value();
13420 }
13421
13422
13423 RUNTIME_FUNCTION(Runtime_DebugDisassembleFunction) {
13424   HandleScope scope(isolate);
13425 #ifdef DEBUG
13426   DCHECK(args.length() == 1);
13427   // Get the function and make sure it is compiled.
13428   CONVERT_ARG_HANDLE_CHECKED(JSFunction, func, 0);
13429   if (!Compiler::EnsureCompiled(func, KEEP_EXCEPTION)) {
13430     return isolate->heap()->exception();
13431   }
13432   OFStream os(stdout);
13433   func->code()->Print(os);
13434   os << endl;
13435 #endif  // DEBUG
13436   return isolate->heap()->undefined_value();
13437 }
13438
13439
13440 RUNTIME_FUNCTION(Runtime_DebugDisassembleConstructor) {
13441   HandleScope scope(isolate);
13442 #ifdef DEBUG
13443   DCHECK(args.length() == 1);
13444   // Get the function and make sure it is compiled.
13445   CONVERT_ARG_HANDLE_CHECKED(JSFunction, func, 0);
13446   if (!Compiler::EnsureCompiled(func, KEEP_EXCEPTION)) {
13447     return isolate->heap()->exception();
13448   }
13449   OFStream os(stdout);
13450   func->shared()->construct_stub()->Print(os);
13451   os << endl;
13452 #endif  // DEBUG
13453   return isolate->heap()->undefined_value();
13454 }
13455
13456
13457 RUNTIME_FUNCTION(Runtime_FunctionGetInferredName) {
13458   SealHandleScope shs(isolate);
13459   DCHECK(args.length() == 1);
13460
13461   CONVERT_ARG_CHECKED(JSFunction, f, 0);
13462   return f->shared()->inferred_name();
13463 }
13464
13465
13466 static int FindSharedFunctionInfosForScript(HeapIterator* iterator,
13467                                             Script* script,
13468                                             FixedArray* buffer) {
13469   DisallowHeapAllocation no_allocation;
13470   int counter = 0;
13471   int buffer_size = buffer->length();
13472   for (HeapObject* obj = iterator->next();
13473        obj != NULL;
13474        obj = iterator->next()) {
13475     DCHECK(obj != NULL);
13476     if (!obj->IsSharedFunctionInfo()) {
13477       continue;
13478     }
13479     SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj);
13480     if (shared->script() != script) {
13481       continue;
13482     }
13483     if (counter < buffer_size) {
13484       buffer->set(counter, shared);
13485     }
13486     counter++;
13487   }
13488   return counter;
13489 }
13490
13491
13492 // For a script finds all SharedFunctionInfo's in the heap that points
13493 // to this script. Returns JSArray of SharedFunctionInfo wrapped
13494 // in OpaqueReferences.
13495 RUNTIME_FUNCTION(Runtime_LiveEditFindSharedFunctionInfosForScript) {
13496   HandleScope scope(isolate);
13497   CHECK(isolate->debug()->live_edit_enabled());
13498   DCHECK(args.length() == 1);
13499   CONVERT_ARG_CHECKED(JSValue, script_value, 0);
13500
13501   RUNTIME_ASSERT(script_value->value()->IsScript());
13502   Handle<Script> script = Handle<Script>(Script::cast(script_value->value()));
13503
13504   const int kBufferSize = 32;
13505
13506   Handle<FixedArray> array;
13507   array = isolate->factory()->NewFixedArray(kBufferSize);
13508   int number;
13509   Heap* heap = isolate->heap();
13510   {
13511     HeapIterator heap_iterator(heap);
13512     Script* scr = *script;
13513     FixedArray* arr = *array;
13514     number = FindSharedFunctionInfosForScript(&heap_iterator, scr, arr);
13515   }
13516   if (number > kBufferSize) {
13517     array = isolate->factory()->NewFixedArray(number);
13518     HeapIterator heap_iterator(heap);
13519     Script* scr = *script;
13520     FixedArray* arr = *array;
13521     FindSharedFunctionInfosForScript(&heap_iterator, scr, arr);
13522   }
13523
13524   Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements(array);
13525   result->set_length(Smi::FromInt(number));
13526
13527   LiveEdit::WrapSharedFunctionInfos(result);
13528
13529   return *result;
13530 }
13531
13532
13533 // For a script calculates compilation information about all its functions.
13534 // The script source is explicitly specified by the second argument.
13535 // The source of the actual script is not used, however it is important that
13536 // all generated code keeps references to this particular instance of script.
13537 // Returns a JSArray of compilation infos. The array is ordered so that
13538 // each function with all its descendant is always stored in a continues range
13539 // with the function itself going first. The root function is a script function.
13540 RUNTIME_FUNCTION(Runtime_LiveEditGatherCompileInfo) {
13541   HandleScope scope(isolate);
13542   CHECK(isolate->debug()->live_edit_enabled());
13543   DCHECK(args.length() == 2);
13544   CONVERT_ARG_CHECKED(JSValue, script, 0);
13545   CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
13546
13547   RUNTIME_ASSERT(script->value()->IsScript());
13548   Handle<Script> script_handle = Handle<Script>(Script::cast(script->value()));
13549
13550   Handle<JSArray> result;
13551   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
13552       isolate, result, LiveEdit::GatherCompileInfo(script_handle, source));
13553   return *result;
13554 }
13555
13556
13557 // Changes the source of the script to a new_source.
13558 // If old_script_name is provided (i.e. is a String), also creates a copy of
13559 // the script with its original source and sends notification to debugger.
13560 RUNTIME_FUNCTION(Runtime_LiveEditReplaceScript) {
13561   HandleScope scope(isolate);
13562   CHECK(isolate->debug()->live_edit_enabled());
13563   DCHECK(args.length() == 3);
13564   CONVERT_ARG_CHECKED(JSValue, original_script_value, 0);
13565   CONVERT_ARG_HANDLE_CHECKED(String, new_source, 1);
13566   CONVERT_ARG_HANDLE_CHECKED(Object, old_script_name, 2);
13567
13568   RUNTIME_ASSERT(original_script_value->value()->IsScript());
13569   Handle<Script> original_script(Script::cast(original_script_value->value()));
13570
13571   Handle<Object> old_script = LiveEdit::ChangeScriptSource(
13572       original_script,  new_source,  old_script_name);
13573
13574   if (old_script->IsScript()) {
13575     Handle<Script> script_handle = Handle<Script>::cast(old_script);
13576     return *Script::GetWrapper(script_handle);
13577   } else {
13578     return isolate->heap()->null_value();
13579   }
13580 }
13581
13582
13583 RUNTIME_FUNCTION(Runtime_LiveEditFunctionSourceUpdated) {
13584   HandleScope scope(isolate);
13585   CHECK(isolate->debug()->live_edit_enabled());
13586   DCHECK(args.length() == 1);
13587   CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_info, 0);
13588   RUNTIME_ASSERT(SharedInfoWrapper::IsInstance(shared_info));
13589
13590   LiveEdit::FunctionSourceUpdated(shared_info);
13591   return isolate->heap()->undefined_value();
13592 }
13593
13594
13595 // Replaces code of SharedFunctionInfo with a new one.
13596 RUNTIME_FUNCTION(Runtime_LiveEditReplaceFunctionCode) {
13597   HandleScope scope(isolate);
13598   CHECK(isolate->debug()->live_edit_enabled());
13599   DCHECK(args.length() == 2);
13600   CONVERT_ARG_HANDLE_CHECKED(JSArray, new_compile_info, 0);
13601   CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_info, 1);
13602   RUNTIME_ASSERT(SharedInfoWrapper::IsInstance(shared_info));
13603
13604   LiveEdit::ReplaceFunctionCode(new_compile_info, shared_info);
13605   return isolate->heap()->undefined_value();
13606 }
13607
13608
13609 // Connects SharedFunctionInfo to another script.
13610 RUNTIME_FUNCTION(Runtime_LiveEditFunctionSetScript) {
13611   HandleScope scope(isolate);
13612   CHECK(isolate->debug()->live_edit_enabled());
13613   DCHECK(args.length() == 2);
13614   CONVERT_ARG_HANDLE_CHECKED(Object, function_object, 0);
13615   CONVERT_ARG_HANDLE_CHECKED(Object, script_object, 1);
13616
13617   if (function_object->IsJSValue()) {
13618     Handle<JSValue> function_wrapper = Handle<JSValue>::cast(function_object);
13619     if (script_object->IsJSValue()) {
13620       RUNTIME_ASSERT(JSValue::cast(*script_object)->value()->IsScript());
13621       Script* script = Script::cast(JSValue::cast(*script_object)->value());
13622       script_object = Handle<Object>(script, isolate);
13623     }
13624     RUNTIME_ASSERT(function_wrapper->value()->IsSharedFunctionInfo());
13625     LiveEdit::SetFunctionScript(function_wrapper, script_object);
13626   } else {
13627     // Just ignore this. We may not have a SharedFunctionInfo for some functions
13628     // and we check it in this function.
13629   }
13630
13631   return isolate->heap()->undefined_value();
13632 }
13633
13634
13635 // In a code of a parent function replaces original function as embedded object
13636 // with a substitution one.
13637 RUNTIME_FUNCTION(Runtime_LiveEditReplaceRefToNestedFunction) {
13638   HandleScope scope(isolate);
13639   CHECK(isolate->debug()->live_edit_enabled());
13640   DCHECK(args.length() == 3);
13641
13642   CONVERT_ARG_HANDLE_CHECKED(JSValue, parent_wrapper, 0);
13643   CONVERT_ARG_HANDLE_CHECKED(JSValue, orig_wrapper, 1);
13644   CONVERT_ARG_HANDLE_CHECKED(JSValue, subst_wrapper, 2);
13645   RUNTIME_ASSERT(parent_wrapper->value()->IsSharedFunctionInfo());
13646   RUNTIME_ASSERT(orig_wrapper->value()->IsSharedFunctionInfo());
13647   RUNTIME_ASSERT(subst_wrapper->value()->IsSharedFunctionInfo());
13648
13649   LiveEdit::ReplaceRefToNestedFunction(
13650       parent_wrapper, orig_wrapper, subst_wrapper);
13651   return isolate->heap()->undefined_value();
13652 }
13653
13654
13655 // Updates positions of a shared function info (first parameter) according
13656 // to script source change. Text change is described in second parameter as
13657 // array of groups of 3 numbers:
13658 // (change_begin, change_end, change_end_new_position).
13659 // Each group describes a change in text; groups are sorted by change_begin.
13660 RUNTIME_FUNCTION(Runtime_LiveEditPatchFunctionPositions) {
13661   HandleScope scope(isolate);
13662   CHECK(isolate->debug()->live_edit_enabled());
13663   DCHECK(args.length() == 2);
13664   CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_array, 0);
13665   CONVERT_ARG_HANDLE_CHECKED(JSArray, position_change_array, 1);
13666   RUNTIME_ASSERT(SharedInfoWrapper::IsInstance(shared_array))
13667
13668   LiveEdit::PatchFunctionPositions(shared_array, position_change_array);
13669   return isolate->heap()->undefined_value();
13670 }
13671
13672
13673 // For array of SharedFunctionInfo's (each wrapped in JSValue)
13674 // checks that none of them have activations on stacks (of any thread).
13675 // Returns array of the same length with corresponding results of
13676 // LiveEdit::FunctionPatchabilityStatus type.
13677 RUNTIME_FUNCTION(Runtime_LiveEditCheckAndDropActivations) {
13678   HandleScope scope(isolate);
13679   CHECK(isolate->debug()->live_edit_enabled());
13680   DCHECK(args.length() == 2);
13681   CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_array, 0);
13682   CONVERT_BOOLEAN_ARG_CHECKED(do_drop, 1);
13683   RUNTIME_ASSERT(shared_array->length()->IsSmi());
13684   RUNTIME_ASSERT(shared_array->HasFastElements())
13685   int array_length = Smi::cast(shared_array->length())->value();
13686   for (int i = 0; i < array_length; i++) {
13687     Handle<Object> element =
13688         Object::GetElement(isolate, shared_array, i).ToHandleChecked();
13689     RUNTIME_ASSERT(
13690         element->IsJSValue() &&
13691         Handle<JSValue>::cast(element)->value()->IsSharedFunctionInfo());
13692   }
13693
13694   return *LiveEdit::CheckAndDropActivations(shared_array, do_drop);
13695 }
13696
13697
13698 // Compares 2 strings line-by-line, then token-wise and returns diff in form
13699 // of JSArray of triplets (pos1, pos1_end, pos2_end) describing list
13700 // of diff chunks.
13701 RUNTIME_FUNCTION(Runtime_LiveEditCompareStrings) {
13702   HandleScope scope(isolate);
13703   CHECK(isolate->debug()->live_edit_enabled());
13704   DCHECK(args.length() == 2);
13705   CONVERT_ARG_HANDLE_CHECKED(String, s1, 0);
13706   CONVERT_ARG_HANDLE_CHECKED(String, s2, 1);
13707
13708   return *LiveEdit::CompareStrings(s1, s2);
13709 }
13710
13711
13712 // Restarts a call frame and completely drops all frames above.
13713 // Returns true if successful. Otherwise returns undefined or an error message.
13714 RUNTIME_FUNCTION(Runtime_LiveEditRestartFrame) {
13715   HandleScope scope(isolate);
13716   CHECK(isolate->debug()->live_edit_enabled());
13717   DCHECK(args.length() == 2);
13718   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
13719   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
13720
13721   CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
13722   Heap* heap = isolate->heap();
13723
13724   // Find the relevant frame with the requested index.
13725   StackFrame::Id id = isolate->debug()->break_frame_id();
13726   if (id == StackFrame::NO_ID) {
13727     // If there are no JavaScript stack frames return undefined.
13728     return heap->undefined_value();
13729   }
13730
13731   JavaScriptFrameIterator it(isolate, id);
13732   int inlined_jsframe_index = FindIndexedNonNativeFrame(&it, index);
13733   if (inlined_jsframe_index == -1) return heap->undefined_value();
13734   // We don't really care what the inlined frame index is, since we are
13735   // throwing away the entire frame anyways.
13736   const char* error_message = LiveEdit::RestartFrame(it.frame());
13737   if (error_message) {
13738     return *(isolate->factory()->InternalizeUtf8String(error_message));
13739   }
13740   return heap->true_value();
13741 }
13742
13743
13744 // A testing entry. Returns statement position which is the closest to
13745 // source_position.
13746 RUNTIME_FUNCTION(Runtime_GetFunctionCodePositionFromSource) {
13747   HandleScope scope(isolate);
13748   CHECK(isolate->debug()->live_edit_enabled());
13749   DCHECK(args.length() == 2);
13750   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
13751   CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
13752
13753   Handle<Code> code(function->code(), isolate);
13754
13755   if (code->kind() != Code::FUNCTION &&
13756       code->kind() != Code::OPTIMIZED_FUNCTION) {
13757     return isolate->heap()->undefined_value();
13758   }
13759
13760   RelocIterator it(*code, RelocInfo::ModeMask(RelocInfo::STATEMENT_POSITION));
13761   int closest_pc = 0;
13762   int distance = kMaxInt;
13763   while (!it.done()) {
13764     int statement_position = static_cast<int>(it.rinfo()->data());
13765     // Check if this break point is closer that what was previously found.
13766     if (source_position <= statement_position &&
13767         statement_position - source_position < distance) {
13768       closest_pc =
13769           static_cast<int>(it.rinfo()->pc() - code->instruction_start());
13770       distance = statement_position - source_position;
13771       // Check whether we can't get any closer.
13772       if (distance == 0) break;
13773     }
13774     it.next();
13775   }
13776
13777   return Smi::FromInt(closest_pc);
13778 }
13779
13780
13781 // Calls specified function with or without entering the debugger.
13782 // This is used in unit tests to run code as if debugger is entered or simply
13783 // to have a stack with C++ frame in the middle.
13784 RUNTIME_FUNCTION(Runtime_ExecuteInDebugContext) {
13785   HandleScope scope(isolate);
13786   DCHECK(args.length() == 2);
13787   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
13788   CONVERT_BOOLEAN_ARG_CHECKED(without_debugger, 1);
13789
13790   MaybeHandle<Object> maybe_result;
13791   if (without_debugger) {
13792     maybe_result = Execution::Call(isolate,
13793                                    function,
13794                                    handle(function->global_proxy()),
13795                                    0,
13796                                    NULL);
13797   } else {
13798     DebugScope debug_scope(isolate->debug());
13799     maybe_result = Execution::Call(isolate,
13800                                    function,
13801                                    handle(function->global_proxy()),
13802                                    0,
13803                                    NULL);
13804   }
13805   Handle<Object> result;
13806   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, maybe_result);
13807   return *result;
13808 }
13809
13810
13811 // Sets a v8 flag.
13812 RUNTIME_FUNCTION(Runtime_SetFlags) {
13813   SealHandleScope shs(isolate);
13814   DCHECK(args.length() == 1);
13815   CONVERT_ARG_CHECKED(String, arg, 0);
13816   SmartArrayPointer<char> flags =
13817       arg->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
13818   FlagList::SetFlagsFromString(flags.get(), StrLength(flags.get()));
13819   return isolate->heap()->undefined_value();
13820 }
13821
13822
13823 // Performs a GC.
13824 // Presently, it only does a full GC.
13825 RUNTIME_FUNCTION(Runtime_CollectGarbage) {
13826   SealHandleScope shs(isolate);
13827   DCHECK(args.length() == 1);
13828   isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, "%CollectGarbage");
13829   return isolate->heap()->undefined_value();
13830 }
13831
13832
13833 // Gets the current heap usage.
13834 RUNTIME_FUNCTION(Runtime_GetHeapUsage) {
13835   SealHandleScope shs(isolate);
13836   DCHECK(args.length() == 0);
13837   int usage = static_cast<int>(isolate->heap()->SizeOfObjects());
13838   if (!Smi::IsValid(usage)) {
13839     return *isolate->factory()->NewNumberFromInt(usage);
13840   }
13841   return Smi::FromInt(usage);
13842 }
13843
13844
13845 #ifdef V8_I18N_SUPPORT
13846 RUNTIME_FUNCTION(Runtime_CanonicalizeLanguageTag) {
13847   HandleScope scope(isolate);
13848   Factory* factory = isolate->factory();
13849
13850   DCHECK(args.length() == 1);
13851   CONVERT_ARG_HANDLE_CHECKED(String, locale_id_str, 0);
13852
13853   v8::String::Utf8Value locale_id(v8::Utils::ToLocal(locale_id_str));
13854
13855   // Return value which denotes invalid language tag.
13856   const char* const kInvalidTag = "invalid-tag";
13857
13858   UErrorCode error = U_ZERO_ERROR;
13859   char icu_result[ULOC_FULLNAME_CAPACITY];
13860   int icu_length = 0;
13861
13862   uloc_forLanguageTag(*locale_id, icu_result, ULOC_FULLNAME_CAPACITY,
13863                       &icu_length, &error);
13864   if (U_FAILURE(error) || icu_length == 0) {
13865     return *factory->NewStringFromAsciiChecked(kInvalidTag);
13866   }
13867
13868   char result[ULOC_FULLNAME_CAPACITY];
13869
13870   // Force strict BCP47 rules.
13871   uloc_toLanguageTag(icu_result, result, ULOC_FULLNAME_CAPACITY, TRUE, &error);
13872
13873   if (U_FAILURE(error)) {
13874     return *factory->NewStringFromAsciiChecked(kInvalidTag);
13875   }
13876
13877   return *factory->NewStringFromAsciiChecked(result);
13878 }
13879
13880
13881 RUNTIME_FUNCTION(Runtime_AvailableLocalesOf) {
13882   HandleScope scope(isolate);
13883   Factory* factory = isolate->factory();
13884
13885   DCHECK(args.length() == 1);
13886   CONVERT_ARG_HANDLE_CHECKED(String, service, 0);
13887
13888   const icu::Locale* available_locales = NULL;
13889   int32_t count = 0;
13890
13891   if (service->IsUtf8EqualTo(CStrVector("collator"))) {
13892     available_locales = icu::Collator::getAvailableLocales(count);
13893   } else if (service->IsUtf8EqualTo(CStrVector("numberformat"))) {
13894     available_locales = icu::NumberFormat::getAvailableLocales(count);
13895   } else if (service->IsUtf8EqualTo(CStrVector("dateformat"))) {
13896     available_locales = icu::DateFormat::getAvailableLocales(count);
13897   } else if (service->IsUtf8EqualTo(CStrVector("breakiterator"))) {
13898     available_locales = icu::BreakIterator::getAvailableLocales(count);
13899   }
13900
13901   UErrorCode error = U_ZERO_ERROR;
13902   char result[ULOC_FULLNAME_CAPACITY];
13903   Handle<JSObject> locales =
13904       factory->NewJSObject(isolate->object_function());
13905
13906   for (int32_t i = 0; i < count; ++i) {
13907     const char* icu_name = available_locales[i].getName();
13908
13909     error = U_ZERO_ERROR;
13910     // No need to force strict BCP47 rules.
13911     uloc_toLanguageTag(icu_name, result, ULOC_FULLNAME_CAPACITY, FALSE, &error);
13912     if (U_FAILURE(error)) {
13913       // This shouldn't happen, but lets not break the user.
13914       continue;
13915     }
13916
13917     RETURN_FAILURE_ON_EXCEPTION(isolate,
13918         JSObject::SetOwnPropertyIgnoreAttributes(
13919             locales,
13920             factory->NewStringFromAsciiChecked(result),
13921             factory->NewNumber(i),
13922             NONE));
13923   }
13924
13925   return *locales;
13926 }
13927
13928
13929 RUNTIME_FUNCTION(Runtime_GetDefaultICULocale) {
13930   HandleScope scope(isolate);
13931   Factory* factory = isolate->factory();
13932
13933   DCHECK(args.length() == 0);
13934
13935   icu::Locale default_locale;
13936
13937   // Set the locale
13938   char result[ULOC_FULLNAME_CAPACITY];
13939   UErrorCode status = U_ZERO_ERROR;
13940   uloc_toLanguageTag(
13941       default_locale.getName(), result, ULOC_FULLNAME_CAPACITY, FALSE, &status);
13942   if (U_SUCCESS(status)) {
13943     return *factory->NewStringFromAsciiChecked(result);
13944   }
13945
13946   return *factory->NewStringFromStaticAscii("und");
13947 }
13948
13949
13950 RUNTIME_FUNCTION(Runtime_GetLanguageTagVariants) {
13951   HandleScope scope(isolate);
13952   Factory* factory = isolate->factory();
13953
13954   DCHECK(args.length() == 1);
13955
13956   CONVERT_ARG_HANDLE_CHECKED(JSArray, input, 0);
13957
13958   uint32_t length = static_cast<uint32_t>(input->length()->Number());
13959   // Set some limit to prevent fuzz tests from going OOM.
13960   // Can be bumped when callers' requirements change.
13961   RUNTIME_ASSERT(length < 100);
13962   Handle<FixedArray> output = factory->NewFixedArray(length);
13963   Handle<Name> maximized = factory->NewStringFromStaticAscii("maximized");
13964   Handle<Name> base = factory->NewStringFromStaticAscii("base");
13965   for (unsigned int i = 0; i < length; ++i) {
13966     Handle<Object> locale_id;
13967     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
13968         isolate, locale_id, Object::GetElement(isolate, input, i));
13969     if (!locale_id->IsString()) {
13970       return isolate->Throw(*factory->illegal_argument_string());
13971     }
13972
13973     v8::String::Utf8Value utf8_locale_id(
13974         v8::Utils::ToLocal(Handle<String>::cast(locale_id)));
13975
13976     UErrorCode error = U_ZERO_ERROR;
13977
13978     // Convert from BCP47 to ICU format.
13979     // de-DE-u-co-phonebk -> de_DE@collation=phonebook
13980     char icu_locale[ULOC_FULLNAME_CAPACITY];
13981     int icu_locale_length = 0;
13982     uloc_forLanguageTag(*utf8_locale_id, icu_locale, ULOC_FULLNAME_CAPACITY,
13983                         &icu_locale_length, &error);
13984     if (U_FAILURE(error) || icu_locale_length == 0) {
13985       return isolate->Throw(*factory->illegal_argument_string());
13986     }
13987
13988     // Maximize the locale.
13989     // de_DE@collation=phonebook -> de_Latn_DE@collation=phonebook
13990     char icu_max_locale[ULOC_FULLNAME_CAPACITY];
13991     uloc_addLikelySubtags(
13992         icu_locale, icu_max_locale, ULOC_FULLNAME_CAPACITY, &error);
13993
13994     // Remove extensions from maximized locale.
13995     // de_Latn_DE@collation=phonebook -> de_Latn_DE
13996     char icu_base_max_locale[ULOC_FULLNAME_CAPACITY];
13997     uloc_getBaseName(
13998         icu_max_locale, icu_base_max_locale, ULOC_FULLNAME_CAPACITY, &error);
13999
14000     // Get original name without extensions.
14001     // de_DE@collation=phonebook -> de_DE
14002     char icu_base_locale[ULOC_FULLNAME_CAPACITY];
14003     uloc_getBaseName(
14004         icu_locale, icu_base_locale, ULOC_FULLNAME_CAPACITY, &error);
14005
14006     // Convert from ICU locale format to BCP47 format.
14007     // de_Latn_DE -> de-Latn-DE
14008     char base_max_locale[ULOC_FULLNAME_CAPACITY];
14009     uloc_toLanguageTag(icu_base_max_locale, base_max_locale,
14010                        ULOC_FULLNAME_CAPACITY, FALSE, &error);
14011
14012     // de_DE -> de-DE
14013     char base_locale[ULOC_FULLNAME_CAPACITY];
14014     uloc_toLanguageTag(
14015         icu_base_locale, base_locale, ULOC_FULLNAME_CAPACITY, FALSE, &error);
14016
14017     if (U_FAILURE(error)) {
14018       return isolate->Throw(*factory->illegal_argument_string());
14019     }
14020
14021     Handle<JSObject> result = factory->NewJSObject(isolate->object_function());
14022     Handle<String> value = factory->NewStringFromAsciiChecked(base_max_locale);
14023     JSObject::AddProperty(result, maximized, value, NONE);
14024     value = factory->NewStringFromAsciiChecked(base_locale);
14025     JSObject::AddProperty(result, base, value, NONE);
14026     output->set(i, *result);
14027   }
14028
14029   Handle<JSArray> result = factory->NewJSArrayWithElements(output);
14030   result->set_length(Smi::FromInt(length));
14031   return *result;
14032 }
14033
14034
14035 RUNTIME_FUNCTION(Runtime_IsInitializedIntlObject) {
14036   HandleScope scope(isolate);
14037
14038   DCHECK(args.length() == 1);
14039
14040   CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
14041
14042   if (!input->IsJSObject()) return isolate->heap()->false_value();
14043   Handle<JSObject> obj = Handle<JSObject>::cast(input);
14044
14045   Handle<String> marker = isolate->factory()->intl_initialized_marker_string();
14046   Handle<Object> tag(obj->GetHiddenProperty(marker), isolate);
14047   return isolate->heap()->ToBoolean(!tag->IsTheHole());
14048 }
14049
14050
14051 RUNTIME_FUNCTION(Runtime_IsInitializedIntlObjectOfType) {
14052   HandleScope scope(isolate);
14053
14054   DCHECK(args.length() == 2);
14055
14056   CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
14057   CONVERT_ARG_HANDLE_CHECKED(String, expected_type, 1);
14058
14059   if (!input->IsJSObject()) return isolate->heap()->false_value();
14060   Handle<JSObject> obj = Handle<JSObject>::cast(input);
14061
14062   Handle<String> marker = isolate->factory()->intl_initialized_marker_string();
14063   Handle<Object> tag(obj->GetHiddenProperty(marker), isolate);
14064   return isolate->heap()->ToBoolean(
14065       tag->IsString() && String::cast(*tag)->Equals(*expected_type));
14066 }
14067
14068
14069 RUNTIME_FUNCTION(Runtime_MarkAsInitializedIntlObjectOfType) {
14070   HandleScope scope(isolate);
14071
14072   DCHECK(args.length() == 3);
14073
14074   CONVERT_ARG_HANDLE_CHECKED(JSObject, input, 0);
14075   CONVERT_ARG_HANDLE_CHECKED(String, type, 1);
14076   CONVERT_ARG_HANDLE_CHECKED(JSObject, impl, 2);
14077
14078   Handle<String> marker = isolate->factory()->intl_initialized_marker_string();
14079   JSObject::SetHiddenProperty(input, marker, type);
14080
14081   marker = isolate->factory()->intl_impl_object_string();
14082   JSObject::SetHiddenProperty(input, marker, impl);
14083
14084   return isolate->heap()->undefined_value();
14085 }
14086
14087
14088 RUNTIME_FUNCTION(Runtime_GetImplFromInitializedIntlObject) {
14089   HandleScope scope(isolate);
14090
14091   DCHECK(args.length() == 1);
14092
14093   CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
14094
14095   if (!input->IsJSObject()) {
14096     Vector< Handle<Object> > arguments = HandleVector(&input, 1);
14097     Handle<Object> type_error =
14098         isolate->factory()->NewTypeError("not_intl_object", arguments);
14099     return isolate->Throw(*type_error);
14100   }
14101
14102   Handle<JSObject> obj = Handle<JSObject>::cast(input);
14103
14104   Handle<String> marker = isolate->factory()->intl_impl_object_string();
14105   Handle<Object> impl(obj->GetHiddenProperty(marker), isolate);
14106   if (impl->IsTheHole()) {
14107     Vector< Handle<Object> > arguments = HandleVector(&obj, 1);
14108     Handle<Object> type_error =
14109         isolate->factory()->NewTypeError("not_intl_object", arguments);
14110     return isolate->Throw(*type_error);
14111   }
14112   return *impl;
14113 }
14114
14115
14116 RUNTIME_FUNCTION(Runtime_CreateDateTimeFormat) {
14117   HandleScope scope(isolate);
14118
14119   DCHECK(args.length() == 3);
14120
14121   CONVERT_ARG_HANDLE_CHECKED(String, locale, 0);
14122   CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1);
14123   CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2);
14124
14125   Handle<ObjectTemplateInfo> date_format_template =
14126       I18N::GetTemplate(isolate);
14127
14128   // Create an empty object wrapper.
14129   Handle<JSObject> local_object;
14130   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
14131       isolate, local_object,
14132       Execution::InstantiateObject(date_format_template));
14133
14134   // Set date time formatter as internal field of the resulting JS object.
14135   icu::SimpleDateFormat* date_format = DateFormat::InitializeDateTimeFormat(
14136       isolate, locale, options, resolved);
14137
14138   if (!date_format) return isolate->ThrowIllegalOperation();
14139
14140   local_object->SetInternalField(0, reinterpret_cast<Smi*>(date_format));
14141
14142   Factory* factory = isolate->factory();
14143   Handle<String> key = factory->NewStringFromStaticAscii("dateFormat");
14144   Handle<String> value = factory->NewStringFromStaticAscii("valid");
14145   JSObject::AddProperty(local_object, key, value, NONE);
14146
14147   // Make object handle weak so we can delete the data format once GC kicks in.
14148   Handle<Object> wrapper = isolate->global_handles()->Create(*local_object);
14149   GlobalHandles::MakeWeak(wrapper.location(),
14150                           reinterpret_cast<void*>(wrapper.location()),
14151                           DateFormat::DeleteDateFormat);
14152   return *local_object;
14153 }
14154
14155
14156 RUNTIME_FUNCTION(Runtime_InternalDateFormat) {
14157   HandleScope scope(isolate);
14158
14159   DCHECK(args.length() == 2);
14160
14161   CONVERT_ARG_HANDLE_CHECKED(JSObject, date_format_holder, 0);
14162   CONVERT_ARG_HANDLE_CHECKED(JSDate, date, 1);
14163
14164   Handle<Object> value;
14165   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
14166       isolate, value, Execution::ToNumber(isolate, date));
14167
14168   icu::SimpleDateFormat* date_format =
14169       DateFormat::UnpackDateFormat(isolate, date_format_holder);
14170   if (!date_format) return isolate->ThrowIllegalOperation();
14171
14172   icu::UnicodeString result;
14173   date_format->format(value->Number(), result);
14174
14175   Handle<String> result_str;
14176   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
14177       isolate, result_str,
14178       isolate->factory()->NewStringFromTwoByte(
14179           Vector<const uint16_t>(
14180               reinterpret_cast<const uint16_t*>(result.getBuffer()),
14181               result.length())));
14182   return *result_str;
14183 }
14184
14185
14186 RUNTIME_FUNCTION(Runtime_InternalDateParse) {
14187   HandleScope scope(isolate);
14188
14189   DCHECK(args.length() == 2);
14190
14191   CONVERT_ARG_HANDLE_CHECKED(JSObject, date_format_holder, 0);
14192   CONVERT_ARG_HANDLE_CHECKED(String, date_string, 1);
14193
14194   v8::String::Utf8Value utf8_date(v8::Utils::ToLocal(date_string));
14195   icu::UnicodeString u_date(icu::UnicodeString::fromUTF8(*utf8_date));
14196   icu::SimpleDateFormat* date_format =
14197       DateFormat::UnpackDateFormat(isolate, date_format_holder);
14198   if (!date_format) return isolate->ThrowIllegalOperation();
14199
14200   UErrorCode status = U_ZERO_ERROR;
14201   UDate date = date_format->parse(u_date, status);
14202   if (U_FAILURE(status)) return isolate->heap()->undefined_value();
14203
14204   Handle<Object> result;
14205   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
14206       isolate, result,
14207       Execution::NewDate(isolate, static_cast<double>(date)));
14208   DCHECK(result->IsJSDate());
14209   return *result;
14210 }
14211
14212
14213 RUNTIME_FUNCTION(Runtime_CreateNumberFormat) {
14214   HandleScope scope(isolate);
14215
14216   DCHECK(args.length() == 3);
14217
14218   CONVERT_ARG_HANDLE_CHECKED(String, locale, 0);
14219   CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1);
14220   CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2);
14221
14222   Handle<ObjectTemplateInfo> number_format_template =
14223       I18N::GetTemplate(isolate);
14224
14225   // Create an empty object wrapper.
14226   Handle<JSObject> local_object;
14227   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
14228       isolate, local_object,
14229       Execution::InstantiateObject(number_format_template));
14230
14231   // Set number formatter as internal field of the resulting JS object.
14232   icu::DecimalFormat* number_format = NumberFormat::InitializeNumberFormat(
14233       isolate, locale, options, resolved);
14234
14235   if (!number_format) return isolate->ThrowIllegalOperation();
14236
14237   local_object->SetInternalField(0, reinterpret_cast<Smi*>(number_format));
14238
14239   Factory* factory = isolate->factory();
14240   Handle<String> key = factory->NewStringFromStaticAscii("numberFormat");
14241   Handle<String> value = factory->NewStringFromStaticAscii("valid");
14242   JSObject::AddProperty(local_object, key, value, NONE);
14243
14244   Handle<Object> wrapper = isolate->global_handles()->Create(*local_object);
14245   GlobalHandles::MakeWeak(wrapper.location(),
14246                           reinterpret_cast<void*>(wrapper.location()),
14247                           NumberFormat::DeleteNumberFormat);
14248   return *local_object;
14249 }
14250
14251
14252 RUNTIME_FUNCTION(Runtime_InternalNumberFormat) {
14253   HandleScope scope(isolate);
14254
14255   DCHECK(args.length() == 2);
14256
14257   CONVERT_ARG_HANDLE_CHECKED(JSObject, number_format_holder, 0);
14258   CONVERT_ARG_HANDLE_CHECKED(Object, number, 1);
14259
14260   Handle<Object> value;
14261   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
14262       isolate, value, Execution::ToNumber(isolate, number));
14263
14264   icu::DecimalFormat* number_format =
14265       NumberFormat::UnpackNumberFormat(isolate, number_format_holder);
14266   if (!number_format) return isolate->ThrowIllegalOperation();
14267
14268   icu::UnicodeString result;
14269   number_format->format(value->Number(), result);
14270
14271   Handle<String> result_str;
14272   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
14273       isolate, result_str,
14274       isolate->factory()->NewStringFromTwoByte(
14275           Vector<const uint16_t>(
14276               reinterpret_cast<const uint16_t*>(result.getBuffer()),
14277               result.length())));
14278   return *result_str;
14279 }
14280
14281
14282 RUNTIME_FUNCTION(Runtime_InternalNumberParse) {
14283   HandleScope scope(isolate);
14284
14285   DCHECK(args.length() == 2);
14286
14287   CONVERT_ARG_HANDLE_CHECKED(JSObject, number_format_holder, 0);
14288   CONVERT_ARG_HANDLE_CHECKED(String, number_string, 1);
14289
14290   v8::String::Utf8Value utf8_number(v8::Utils::ToLocal(number_string));
14291   icu::UnicodeString u_number(icu::UnicodeString::fromUTF8(*utf8_number));
14292   icu::DecimalFormat* number_format =
14293       NumberFormat::UnpackNumberFormat(isolate, number_format_holder);
14294   if (!number_format) return isolate->ThrowIllegalOperation();
14295
14296   UErrorCode status = U_ZERO_ERROR;
14297   icu::Formattable result;
14298   // ICU 4.6 doesn't support parseCurrency call. We need to wait for ICU49
14299   // to be part of Chrome.
14300   // TODO(cira): Include currency parsing code using parseCurrency call.
14301   // We need to check if the formatter parses all currencies or only the
14302   // one it was constructed with (it will impact the API - how to return ISO
14303   // code and the value).
14304   number_format->parse(u_number, result, status);
14305   if (U_FAILURE(status)) return isolate->heap()->undefined_value();
14306
14307   switch (result.getType()) {
14308   case icu::Formattable::kDouble:
14309     return *isolate->factory()->NewNumber(result.getDouble());
14310   case icu::Formattable::kLong:
14311     return *isolate->factory()->NewNumberFromInt(result.getLong());
14312   case icu::Formattable::kInt64:
14313     return *isolate->factory()->NewNumber(
14314         static_cast<double>(result.getInt64()));
14315   default:
14316     return isolate->heap()->undefined_value();
14317   }
14318 }
14319
14320
14321 RUNTIME_FUNCTION(Runtime_CreateCollator) {
14322   HandleScope scope(isolate);
14323
14324   DCHECK(args.length() == 3);
14325
14326   CONVERT_ARG_HANDLE_CHECKED(String, locale, 0);
14327   CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1);
14328   CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2);
14329
14330   Handle<ObjectTemplateInfo> collator_template = I18N::GetTemplate(isolate);
14331
14332   // Create an empty object wrapper.
14333   Handle<JSObject> local_object;
14334   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
14335       isolate, local_object, Execution::InstantiateObject(collator_template));
14336
14337   // Set collator as internal field of the resulting JS object.
14338   icu::Collator* collator = Collator::InitializeCollator(
14339       isolate, locale, options, resolved);
14340
14341   if (!collator) return isolate->ThrowIllegalOperation();
14342
14343   local_object->SetInternalField(0, reinterpret_cast<Smi*>(collator));
14344
14345   Factory* factory = isolate->factory();
14346   Handle<String> key = factory->NewStringFromStaticAscii("collator");
14347   Handle<String> value = factory->NewStringFromStaticAscii("valid");
14348   JSObject::AddProperty(local_object, key, value, NONE);
14349
14350   Handle<Object> wrapper = isolate->global_handles()->Create(*local_object);
14351   GlobalHandles::MakeWeak(wrapper.location(),
14352                           reinterpret_cast<void*>(wrapper.location()),
14353                           Collator::DeleteCollator);
14354   return *local_object;
14355 }
14356
14357
14358 RUNTIME_FUNCTION(Runtime_InternalCompare) {
14359   HandleScope scope(isolate);
14360
14361   DCHECK(args.length() == 3);
14362
14363   CONVERT_ARG_HANDLE_CHECKED(JSObject, collator_holder, 0);
14364   CONVERT_ARG_HANDLE_CHECKED(String, string1, 1);
14365   CONVERT_ARG_HANDLE_CHECKED(String, string2, 2);
14366
14367   icu::Collator* collator = Collator::UnpackCollator(isolate, collator_holder);
14368   if (!collator) return isolate->ThrowIllegalOperation();
14369
14370   v8::String::Value string_value1(v8::Utils::ToLocal(string1));
14371   v8::String::Value string_value2(v8::Utils::ToLocal(string2));
14372   const UChar* u_string1 = reinterpret_cast<const UChar*>(*string_value1);
14373   const UChar* u_string2 = reinterpret_cast<const UChar*>(*string_value2);
14374   UErrorCode status = U_ZERO_ERROR;
14375   UCollationResult result = collator->compare(u_string1,
14376                                               string_value1.length(),
14377                                               u_string2,
14378                                               string_value2.length(),
14379                                               status);
14380   if (U_FAILURE(status)) return isolate->ThrowIllegalOperation();
14381
14382   return *isolate->factory()->NewNumberFromInt(result);
14383 }
14384
14385
14386 RUNTIME_FUNCTION(Runtime_StringNormalize) {
14387   HandleScope scope(isolate);
14388   static const UNormalizationMode normalizationForms[] =
14389       { UNORM_NFC, UNORM_NFD, UNORM_NFKC, UNORM_NFKD };
14390
14391   DCHECK(args.length() == 2);
14392
14393   CONVERT_ARG_HANDLE_CHECKED(String, stringValue, 0);
14394   CONVERT_NUMBER_CHECKED(int, form_id, Int32, args[1]);
14395   RUNTIME_ASSERT(form_id >= 0 &&
14396                  static_cast<size_t>(form_id) < ARRAY_SIZE(normalizationForms));
14397
14398   v8::String::Value string_value(v8::Utils::ToLocal(stringValue));
14399   const UChar* u_value = reinterpret_cast<const UChar*>(*string_value);
14400
14401   // TODO(mnita): check Normalizer2 (not available in ICU 46)
14402   UErrorCode status = U_ZERO_ERROR;
14403   icu::UnicodeString result;
14404   icu::Normalizer::normalize(u_value, normalizationForms[form_id], 0,
14405       result, status);
14406   if (U_FAILURE(status)) {
14407     return isolate->heap()->undefined_value();
14408   }
14409
14410   Handle<String> result_str;
14411   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
14412       isolate, result_str,
14413       isolate->factory()->NewStringFromTwoByte(
14414           Vector<const uint16_t>(
14415               reinterpret_cast<const uint16_t*>(result.getBuffer()),
14416               result.length())));
14417   return *result_str;
14418 }
14419
14420
14421 RUNTIME_FUNCTION(Runtime_CreateBreakIterator) {
14422   HandleScope scope(isolate);
14423
14424   DCHECK(args.length() == 3);
14425
14426   CONVERT_ARG_HANDLE_CHECKED(String, locale, 0);
14427   CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1);
14428   CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2);
14429
14430   Handle<ObjectTemplateInfo> break_iterator_template =
14431       I18N::GetTemplate2(isolate);
14432
14433   // Create an empty object wrapper.
14434   Handle<JSObject> local_object;
14435   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
14436       isolate, local_object,
14437       Execution::InstantiateObject(break_iterator_template));
14438
14439   // Set break iterator as internal field of the resulting JS object.
14440   icu::BreakIterator* break_iterator = BreakIterator::InitializeBreakIterator(
14441       isolate, locale, options, resolved);
14442
14443   if (!break_iterator) return isolate->ThrowIllegalOperation();
14444
14445   local_object->SetInternalField(0, reinterpret_cast<Smi*>(break_iterator));
14446   // Make sure that the pointer to adopted text is NULL.
14447   local_object->SetInternalField(1, reinterpret_cast<Smi*>(NULL));
14448
14449   Factory* factory = isolate->factory();
14450   Handle<String> key = factory->NewStringFromStaticAscii("breakIterator");
14451   Handle<String> value = factory->NewStringFromStaticAscii("valid");
14452   JSObject::AddProperty(local_object, key, value, NONE);
14453
14454   // Make object handle weak so we can delete the break iterator once GC kicks
14455   // in.
14456   Handle<Object> wrapper = isolate->global_handles()->Create(*local_object);
14457   GlobalHandles::MakeWeak(wrapper.location(),
14458                           reinterpret_cast<void*>(wrapper.location()),
14459                           BreakIterator::DeleteBreakIterator);
14460   return *local_object;
14461 }
14462
14463
14464 RUNTIME_FUNCTION(Runtime_BreakIteratorAdoptText) {
14465   HandleScope scope(isolate);
14466
14467   DCHECK(args.length() == 2);
14468
14469   CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
14470   CONVERT_ARG_HANDLE_CHECKED(String, text, 1);
14471
14472   icu::BreakIterator* break_iterator =
14473       BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder);
14474   if (!break_iterator) return isolate->ThrowIllegalOperation();
14475
14476   icu::UnicodeString* u_text = reinterpret_cast<icu::UnicodeString*>(
14477       break_iterator_holder->GetInternalField(1));
14478   delete u_text;
14479
14480   v8::String::Value text_value(v8::Utils::ToLocal(text));
14481   u_text = new icu::UnicodeString(
14482       reinterpret_cast<const UChar*>(*text_value), text_value.length());
14483   break_iterator_holder->SetInternalField(1, reinterpret_cast<Smi*>(u_text));
14484
14485   break_iterator->setText(*u_text);
14486
14487   return isolate->heap()->undefined_value();
14488 }
14489
14490
14491 RUNTIME_FUNCTION(Runtime_BreakIteratorFirst) {
14492   HandleScope scope(isolate);
14493
14494   DCHECK(args.length() == 1);
14495
14496   CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
14497
14498   icu::BreakIterator* break_iterator =
14499       BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder);
14500   if (!break_iterator) return isolate->ThrowIllegalOperation();
14501
14502   return *isolate->factory()->NewNumberFromInt(break_iterator->first());
14503 }
14504
14505
14506 RUNTIME_FUNCTION(Runtime_BreakIteratorNext) {
14507   HandleScope scope(isolate);
14508
14509   DCHECK(args.length() == 1);
14510
14511   CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
14512
14513   icu::BreakIterator* break_iterator =
14514       BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder);
14515   if (!break_iterator) return isolate->ThrowIllegalOperation();
14516
14517   return *isolate->factory()->NewNumberFromInt(break_iterator->next());
14518 }
14519
14520
14521 RUNTIME_FUNCTION(Runtime_BreakIteratorCurrent) {
14522   HandleScope scope(isolate);
14523
14524   DCHECK(args.length() == 1);
14525
14526   CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
14527
14528   icu::BreakIterator* break_iterator =
14529       BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder);
14530   if (!break_iterator) return isolate->ThrowIllegalOperation();
14531
14532   return *isolate->factory()->NewNumberFromInt(break_iterator->current());
14533 }
14534
14535
14536 RUNTIME_FUNCTION(Runtime_BreakIteratorBreakType) {
14537   HandleScope scope(isolate);
14538
14539   DCHECK(args.length() == 1);
14540
14541   CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
14542
14543   icu::BreakIterator* break_iterator =
14544       BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder);
14545   if (!break_iterator) return isolate->ThrowIllegalOperation();
14546
14547   // TODO(cira): Remove cast once ICU fixes base BreakIterator class.
14548   icu::RuleBasedBreakIterator* rule_based_iterator =
14549       static_cast<icu::RuleBasedBreakIterator*>(break_iterator);
14550   int32_t status = rule_based_iterator->getRuleStatus();
14551   // Keep return values in sync with JavaScript BreakType enum.
14552   if (status >= UBRK_WORD_NONE && status < UBRK_WORD_NONE_LIMIT) {
14553     return *isolate->factory()->NewStringFromStaticAscii("none");
14554   } else if (status >= UBRK_WORD_NUMBER && status < UBRK_WORD_NUMBER_LIMIT) {
14555     return *isolate->factory()->NewStringFromStaticAscii("number");
14556   } else if (status >= UBRK_WORD_LETTER && status < UBRK_WORD_LETTER_LIMIT) {
14557     return *isolate->factory()->NewStringFromStaticAscii("letter");
14558   } else if (status >= UBRK_WORD_KANA && status < UBRK_WORD_KANA_LIMIT) {
14559     return *isolate->factory()->NewStringFromStaticAscii("kana");
14560   } else if (status >= UBRK_WORD_IDEO && status < UBRK_WORD_IDEO_LIMIT) {
14561     return *isolate->factory()->NewStringFromStaticAscii("ideo");
14562   } else {
14563     return *isolate->factory()->NewStringFromStaticAscii("unknown");
14564   }
14565 }
14566 #endif  // V8_I18N_SUPPORT
14567
14568
14569 // Finds the script object from the script data. NOTE: This operation uses
14570 // heap traversal to find the function generated for the source position
14571 // for the requested break point. For lazily compiled functions several heap
14572 // traversals might be required rendering this operation as a rather slow
14573 // operation. However for setting break points which is normally done through
14574 // some kind of user interaction the performance is not crucial.
14575 static Handle<Object> Runtime_GetScriptFromScriptName(
14576     Handle<String> script_name) {
14577   // Scan the heap for Script objects to find the script with the requested
14578   // script data.
14579   Handle<Script> script;
14580   Factory* factory = script_name->GetIsolate()->factory();
14581   Heap* heap = script_name->GetHeap();
14582   HeapIterator iterator(heap);
14583   HeapObject* obj = NULL;
14584   while (script.is_null() && ((obj = iterator.next()) != NULL)) {
14585     // If a script is found check if it has the script data requested.
14586     if (obj->IsScript()) {
14587       if (Script::cast(obj)->name()->IsString()) {
14588         if (String::cast(Script::cast(obj)->name())->Equals(*script_name)) {
14589           script = Handle<Script>(Script::cast(obj));
14590         }
14591       }
14592     }
14593   }
14594
14595   // If no script with the requested script data is found return undefined.
14596   if (script.is_null()) return factory->undefined_value();
14597
14598   // Return the script found.
14599   return Script::GetWrapper(script);
14600 }
14601
14602
14603 // Get the script object from script data. NOTE: Regarding performance
14604 // see the NOTE for GetScriptFromScriptData.
14605 // args[0]: script data for the script to find the source for
14606 RUNTIME_FUNCTION(Runtime_GetScript) {
14607   HandleScope scope(isolate);
14608
14609   DCHECK(args.length() == 1);
14610
14611   CONVERT_ARG_CHECKED(String, script_name, 0);
14612
14613   // Find the requested script.
14614   Handle<Object> result =
14615       Runtime_GetScriptFromScriptName(Handle<String>(script_name));
14616   return *result;
14617 }
14618
14619
14620 // Collect the raw data for a stack trace.  Returns an array of 4
14621 // element segments each containing a receiver, function, code and
14622 // native code offset.
14623 RUNTIME_FUNCTION(Runtime_CollectStackTrace) {
14624   HandleScope scope(isolate);
14625   DCHECK(args.length() == 2);
14626   CONVERT_ARG_HANDLE_CHECKED(JSObject, error_object, 0);
14627   CONVERT_ARG_HANDLE_CHECKED(Object, caller, 1);
14628
14629   if (!isolate->bootstrapper()->IsActive()) {
14630     // Optionally capture a more detailed stack trace for the message.
14631     isolate->CaptureAndSetDetailedStackTrace(error_object);
14632     // Capture a simple stack trace for the stack property.
14633     isolate->CaptureAndSetSimpleStackTrace(error_object, caller);
14634   }
14635   return isolate->heap()->undefined_value();
14636 }
14637
14638
14639 // Returns V8 version as a string.
14640 RUNTIME_FUNCTION(Runtime_GetV8Version) {
14641   HandleScope scope(isolate);
14642   DCHECK(args.length() == 0);
14643
14644   const char* version_string = v8::V8::GetVersion();
14645
14646   return *isolate->factory()->NewStringFromAsciiChecked(version_string);
14647 }
14648
14649
14650 RUNTIME_FUNCTION(Runtime_Abort) {
14651   SealHandleScope shs(isolate);
14652   DCHECK(args.length() == 1);
14653   CONVERT_SMI_ARG_CHECKED(message_id, 0);
14654   const char* message = GetBailoutReason(
14655       static_cast<BailoutReason>(message_id));
14656   base::OS::PrintError("abort: %s\n", message);
14657   isolate->PrintStack(stderr);
14658   base::OS::Abort();
14659   UNREACHABLE();
14660   return NULL;
14661 }
14662
14663
14664 RUNTIME_FUNCTION(Runtime_AbortJS) {
14665   HandleScope scope(isolate);
14666   DCHECK(args.length() == 1);
14667   CONVERT_ARG_HANDLE_CHECKED(String, message, 0);
14668   base::OS::PrintError("abort: %s\n", message->ToCString().get());
14669   isolate->PrintStack(stderr);
14670   base::OS::Abort();
14671   UNREACHABLE();
14672   return NULL;
14673 }
14674
14675
14676 RUNTIME_FUNCTION(Runtime_FlattenString) {
14677   HandleScope scope(isolate);
14678   DCHECK(args.length() == 1);
14679   CONVERT_ARG_HANDLE_CHECKED(String, str, 0);
14680   return *String::Flatten(str);
14681 }
14682
14683
14684 RUNTIME_FUNCTION(Runtime_NotifyContextDisposed) {
14685   HandleScope scope(isolate);
14686   DCHECK(args.length() == 0);
14687   isolate->heap()->NotifyContextDisposed();
14688   return isolate->heap()->undefined_value();
14689 }
14690
14691
14692 RUNTIME_FUNCTION(Runtime_LoadMutableDouble) {
14693   HandleScope scope(isolate);
14694   DCHECK(args.length() == 2);
14695   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
14696   CONVERT_ARG_HANDLE_CHECKED(Smi, index, 1);
14697   RUNTIME_ASSERT((index->value() & 1) == 1);
14698   FieldIndex field_index =
14699       FieldIndex::ForLoadByFieldIndex(object->map(), index->value());
14700   if (field_index.is_inobject()) {
14701     RUNTIME_ASSERT(field_index.property_index() <
14702                    object->map()->inobject_properties());
14703   } else {
14704     RUNTIME_ASSERT(field_index.outobject_array_index() <
14705                    object->properties()->length());
14706   }
14707   Handle<Object> raw_value(object->RawFastPropertyAt(field_index), isolate);
14708   RUNTIME_ASSERT(raw_value->IsMutableHeapNumber());
14709   return *Object::WrapForRead(isolate, raw_value, Representation::Double());
14710 }
14711
14712
14713 RUNTIME_FUNCTION(Runtime_TryMigrateInstance) {
14714   HandleScope scope(isolate);
14715   DCHECK(args.length() == 1);
14716   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
14717   if (!object->IsJSObject()) return Smi::FromInt(0);
14718   Handle<JSObject> js_object = Handle<JSObject>::cast(object);
14719   if (!js_object->map()->is_deprecated()) return Smi::FromInt(0);
14720   // This call must not cause lazy deopts, because it's called from deferred
14721   // code where we can't handle lazy deopts for lack of a suitable bailout
14722   // ID. So we just try migration and signal failure if necessary,
14723   // which will also trigger a deopt.
14724   if (!JSObject::TryMigrateInstance(js_object)) return Smi::FromInt(0);
14725   return *object;
14726 }
14727
14728
14729 RUNTIME_FUNCTION(Runtime_GetFromCache) {
14730   SealHandleScope shs(isolate);
14731   // This is only called from codegen, so checks might be more lax.
14732   CONVERT_ARG_CHECKED(JSFunctionResultCache, cache, 0);
14733   CONVERT_ARG_CHECKED(Object, key, 1);
14734
14735   {
14736     DisallowHeapAllocation no_alloc;
14737
14738     int finger_index = cache->finger_index();
14739     Object* o = cache->get(finger_index);
14740     if (o == key) {
14741       // The fastest case: hit the same place again.
14742       return cache->get(finger_index + 1);
14743     }
14744
14745     for (int i = finger_index - 2;
14746          i >= JSFunctionResultCache::kEntriesIndex;
14747          i -= 2) {
14748       o = cache->get(i);
14749       if (o == key) {
14750         cache->set_finger_index(i);
14751         return cache->get(i + 1);
14752       }
14753     }
14754
14755     int size = cache->size();
14756     DCHECK(size <= cache->length());
14757
14758     for (int i = size - 2; i > finger_index; i -= 2) {
14759       o = cache->get(i);
14760       if (o == key) {
14761         cache->set_finger_index(i);
14762         return cache->get(i + 1);
14763       }
14764     }
14765   }
14766
14767   // There is no value in the cache.  Invoke the function and cache result.
14768   HandleScope scope(isolate);
14769
14770   Handle<JSFunctionResultCache> cache_handle(cache);
14771   Handle<Object> key_handle(key, isolate);
14772   Handle<Object> value;
14773   {
14774     Handle<JSFunction> factory(JSFunction::cast(
14775           cache_handle->get(JSFunctionResultCache::kFactoryIndex)));
14776     // TODO(antonm): consider passing a receiver when constructing a cache.
14777     Handle<JSObject> receiver(isolate->global_proxy());
14778     // This handle is nor shared, nor used later, so it's safe.
14779     Handle<Object> argv[] = { key_handle };
14780     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
14781         isolate, value,
14782         Execution::Call(isolate, factory, receiver, ARRAY_SIZE(argv), argv));
14783   }
14784
14785 #ifdef VERIFY_HEAP
14786   if (FLAG_verify_heap) {
14787     cache_handle->JSFunctionResultCacheVerify();
14788   }
14789 #endif
14790
14791   // Function invocation may have cleared the cache.  Reread all the data.
14792   int finger_index = cache_handle->finger_index();
14793   int size = cache_handle->size();
14794
14795   // If we have spare room, put new data into it, otherwise evict post finger
14796   // entry which is likely to be the least recently used.
14797   int index = -1;
14798   if (size < cache_handle->length()) {
14799     cache_handle->set_size(size + JSFunctionResultCache::kEntrySize);
14800     index = size;
14801   } else {
14802     index = finger_index + JSFunctionResultCache::kEntrySize;
14803     if (index == cache_handle->length()) {
14804       index = JSFunctionResultCache::kEntriesIndex;
14805     }
14806   }
14807
14808   DCHECK(index % 2 == 0);
14809   DCHECK(index >= JSFunctionResultCache::kEntriesIndex);
14810   DCHECK(index < cache_handle->length());
14811
14812   cache_handle->set(index, *key_handle);
14813   cache_handle->set(index + 1, *value);
14814   cache_handle->set_finger_index(index);
14815
14816 #ifdef VERIFY_HEAP
14817   if (FLAG_verify_heap) {
14818     cache_handle->JSFunctionResultCacheVerify();
14819   }
14820 #endif
14821
14822   return *value;
14823 }
14824
14825
14826 RUNTIME_FUNCTION(Runtime_MessageGetStartPosition) {
14827   SealHandleScope shs(isolate);
14828   DCHECK(args.length() == 1);
14829   CONVERT_ARG_CHECKED(JSMessageObject, message, 0);
14830   return Smi::FromInt(message->start_position());
14831 }
14832
14833
14834 RUNTIME_FUNCTION(Runtime_MessageGetScript) {
14835   SealHandleScope shs(isolate);
14836   DCHECK(args.length() == 1);
14837   CONVERT_ARG_CHECKED(JSMessageObject, message, 0);
14838   return message->script();
14839 }
14840
14841
14842 #ifdef DEBUG
14843 // ListNatives is ONLY used by the fuzz-natives.js in debug mode
14844 // Exclude the code in release mode.
14845 RUNTIME_FUNCTION(Runtime_ListNatives) {
14846   HandleScope scope(isolate);
14847   DCHECK(args.length() == 0);
14848 #define COUNT_ENTRY(Name, argc, ressize) + 1
14849   int entry_count = 0
14850       RUNTIME_FUNCTION_LIST(COUNT_ENTRY)
14851       INLINE_FUNCTION_LIST(COUNT_ENTRY)
14852       INLINE_OPTIMIZED_FUNCTION_LIST(COUNT_ENTRY);
14853 #undef COUNT_ENTRY
14854   Factory* factory = isolate->factory();
14855   Handle<FixedArray> elements = factory->NewFixedArray(entry_count);
14856   int index = 0;
14857   bool inline_runtime_functions = false;
14858 #define ADD_ENTRY(Name, argc, ressize)                                       \
14859   {                                                                          \
14860     HandleScope inner(isolate);                                              \
14861     Handle<String> name;                                                     \
14862     /* Inline runtime functions have an underscore in front of the name. */  \
14863     if (inline_runtime_functions) {                                          \
14864       name = factory->NewStringFromStaticAscii("_" #Name);                   \
14865     } else {                                                                 \
14866       name = factory->NewStringFromStaticAscii(#Name);                       \
14867     }                                                                        \
14868     Handle<FixedArray> pair_elements = factory->NewFixedArray(2);            \
14869     pair_elements->set(0, *name);                                            \
14870     pair_elements->set(1, Smi::FromInt(argc));                               \
14871     Handle<JSArray> pair = factory->NewJSArrayWithElements(pair_elements);   \
14872     elements->set(index++, *pair);                                           \
14873   }
14874   inline_runtime_functions = false;
14875   RUNTIME_FUNCTION_LIST(ADD_ENTRY)
14876   INLINE_OPTIMIZED_FUNCTION_LIST(ADD_ENTRY)
14877   inline_runtime_functions = true;
14878   INLINE_FUNCTION_LIST(ADD_ENTRY)
14879 #undef ADD_ENTRY
14880   DCHECK_EQ(index, entry_count);
14881   Handle<JSArray> result = factory->NewJSArrayWithElements(elements);
14882   return *result;
14883 }
14884 #endif
14885
14886
14887 RUNTIME_FUNCTION(Runtime_IS_VAR) {
14888   UNREACHABLE();  // implemented as macro in the parser
14889   return NULL;
14890 }
14891
14892
14893 #define ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(Name)        \
14894   RUNTIME_FUNCTION(Runtime_Has##Name) {          \
14895     CONVERT_ARG_CHECKED(JSObject, obj, 0);                \
14896     return isolate->heap()->ToBoolean(obj->Has##Name());  \
14897   }
14898
14899 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastSmiElements)
14900 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastObjectElements)
14901 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastSmiOrObjectElements)
14902 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastDoubleElements)
14903 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastHoleyElements)
14904 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(DictionaryElements)
14905 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(SloppyArgumentsElements)
14906 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalArrayElements)
14907 // Properties test sitting with elements tests - not fooling anyone.
14908 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastProperties)
14909
14910 #undef ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION
14911
14912
14913 #define TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION(Type, type, TYPE, ctype, size)     \
14914   RUNTIME_FUNCTION(Runtime_HasExternal##Type##Elements) {             \
14915     CONVERT_ARG_CHECKED(JSObject, obj, 0);                                     \
14916     return isolate->heap()->ToBoolean(obj->HasExternal##Type##Elements());     \
14917   }
14918
14919 TYPED_ARRAYS(TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION)
14920
14921 #undef TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION
14922
14923
14924 #define FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION(Type, type, TYPE, ctype, s)  \
14925   RUNTIME_FUNCTION(Runtime_HasFixed##Type##Elements) {                \
14926     CONVERT_ARG_CHECKED(JSObject, obj, 0);                                     \
14927     return isolate->heap()->ToBoolean(obj->HasFixed##Type##Elements());        \
14928   }
14929
14930 TYPED_ARRAYS(FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION)
14931
14932 #undef FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION
14933
14934
14935 RUNTIME_FUNCTION(Runtime_HaveSameMap) {
14936   SealHandleScope shs(isolate);
14937   DCHECK(args.length() == 2);
14938   CONVERT_ARG_CHECKED(JSObject, obj1, 0);
14939   CONVERT_ARG_CHECKED(JSObject, obj2, 1);
14940   return isolate->heap()->ToBoolean(obj1->map() == obj2->map());
14941 }
14942
14943
14944 RUNTIME_FUNCTION(Runtime_IsJSGlobalProxy) {
14945   SealHandleScope shs(isolate);
14946   DCHECK(args.length() == 1);
14947   CONVERT_ARG_CHECKED(Object, obj, 0);
14948   return isolate->heap()->ToBoolean(obj->IsJSGlobalProxy());
14949 }
14950
14951
14952 RUNTIME_FUNCTION(Runtime_IsObserved) {
14953   SealHandleScope shs(isolate);
14954   DCHECK(args.length() == 1);
14955
14956   if (!args[0]->IsJSReceiver()) return isolate->heap()->false_value();
14957   CONVERT_ARG_CHECKED(JSReceiver, obj, 0);
14958   DCHECK(!obj->IsJSGlobalProxy() || !obj->map()->is_observed());
14959   return isolate->heap()->ToBoolean(obj->map()->is_observed());
14960 }
14961
14962
14963 RUNTIME_FUNCTION(Runtime_SetIsObserved) {
14964   HandleScope scope(isolate);
14965   DCHECK(args.length() == 1);
14966   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, obj, 0);
14967   RUNTIME_ASSERT(!obj->IsJSGlobalProxy());
14968   if (obj->IsJSProxy()) return isolate->heap()->undefined_value();
14969   RUNTIME_ASSERT(!obj->map()->is_observed());
14970
14971   DCHECK(obj->IsJSObject());
14972   JSObject::SetObserved(Handle<JSObject>::cast(obj));
14973   return isolate->heap()->undefined_value();
14974 }
14975
14976
14977 RUNTIME_FUNCTION(Runtime_EnqueueMicrotask) {
14978   HandleScope scope(isolate);
14979   DCHECK(args.length() == 1);
14980   CONVERT_ARG_HANDLE_CHECKED(JSFunction, microtask, 0);
14981   isolate->EnqueueMicrotask(microtask);
14982   return isolate->heap()->undefined_value();
14983 }
14984
14985
14986 RUNTIME_FUNCTION(Runtime_RunMicrotasks) {
14987   HandleScope scope(isolate);
14988   DCHECK(args.length() == 0);
14989   isolate->RunMicrotasks();
14990   return isolate->heap()->undefined_value();
14991 }
14992
14993
14994 RUNTIME_FUNCTION(Runtime_GetObservationState) {
14995   SealHandleScope shs(isolate);
14996   DCHECK(args.length() == 0);
14997   return isolate->heap()->observation_state();
14998 }
14999
15000
15001 RUNTIME_FUNCTION(Runtime_ObservationWeakMapCreate) {
15002   HandleScope scope(isolate);
15003   DCHECK(args.length() == 0);
15004   // TODO(adamk): Currently this runtime function is only called three times per
15005   // isolate. If it's called more often, the map should be moved into the
15006   // strong root list.
15007   Handle<Map> map =
15008       isolate->factory()->NewMap(JS_WEAK_MAP_TYPE, JSWeakMap::kSize);
15009   Handle<JSWeakMap> weakmap =
15010       Handle<JSWeakMap>::cast(isolate->factory()->NewJSObjectFromMap(map));
15011   return *WeakCollectionInitialize(isolate, weakmap);
15012 }
15013
15014
15015 static bool ContextsHaveSameOrigin(Handle<Context> context1,
15016                                    Handle<Context> context2) {
15017   return context1->security_token() == context2->security_token();
15018 }
15019
15020
15021 RUNTIME_FUNCTION(Runtime_ObserverObjectAndRecordHaveSameOrigin) {
15022   HandleScope scope(isolate);
15023   DCHECK(args.length() == 3);
15024   CONVERT_ARG_HANDLE_CHECKED(JSFunction, observer, 0);
15025   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 1);
15026   CONVERT_ARG_HANDLE_CHECKED(JSObject, record, 2);
15027
15028   Handle<Context> observer_context(observer->context()->native_context());
15029   Handle<Context> object_context(object->GetCreationContext());
15030   Handle<Context> record_context(record->GetCreationContext());
15031
15032   return isolate->heap()->ToBoolean(
15033       ContextsHaveSameOrigin(object_context, observer_context) &&
15034       ContextsHaveSameOrigin(object_context, record_context));
15035 }
15036
15037
15038 RUNTIME_FUNCTION(Runtime_ObjectWasCreatedInCurrentOrigin) {
15039   HandleScope scope(isolate);
15040   DCHECK(args.length() == 1);
15041   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
15042
15043   Handle<Context> creation_context(object->GetCreationContext(), isolate);
15044   return isolate->heap()->ToBoolean(
15045       ContextsHaveSameOrigin(creation_context, isolate->native_context()));
15046 }
15047
15048
15049 RUNTIME_FUNCTION(Runtime_GetObjectContextObjectObserve) {
15050   HandleScope scope(isolate);
15051   DCHECK(args.length() == 1);
15052   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
15053
15054   Handle<Context> context(object->GetCreationContext(), isolate);
15055   return context->native_object_observe();
15056 }
15057
15058
15059 RUNTIME_FUNCTION(Runtime_GetObjectContextObjectGetNotifier) {
15060   HandleScope scope(isolate);
15061   DCHECK(args.length() == 1);
15062   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
15063
15064   Handle<Context> context(object->GetCreationContext(), isolate);
15065   return context->native_object_get_notifier();
15066 }
15067
15068
15069 RUNTIME_FUNCTION(Runtime_GetObjectContextNotifierPerformChange) {
15070   HandleScope scope(isolate);
15071   DCHECK(args.length() == 1);
15072   CONVERT_ARG_HANDLE_CHECKED(JSObject, object_info, 0);
15073
15074   Handle<Context> context(object_info->GetCreationContext(), isolate);
15075   return context->native_object_notifier_perform_change();
15076 }
15077
15078
15079 static Object* ArrayConstructorCommon(Isolate* isolate,
15080                                            Handle<JSFunction> constructor,
15081                                            Handle<AllocationSite> site,
15082                                            Arguments* caller_args) {
15083   Factory* factory = isolate->factory();
15084
15085   bool holey = false;
15086   bool can_use_type_feedback = true;
15087   if (caller_args->length() == 1) {
15088     Handle<Object> argument_one = caller_args->at<Object>(0);
15089     if (argument_one->IsSmi()) {
15090       int value = Handle<Smi>::cast(argument_one)->value();
15091       if (value < 0 || value >= JSObject::kInitialMaxFastElementArray) {
15092         // the array is a dictionary in this case.
15093         can_use_type_feedback = false;
15094       } else if (value != 0) {
15095         holey = true;
15096       }
15097     } else {
15098       // Non-smi length argument produces a dictionary
15099       can_use_type_feedback = false;
15100     }
15101   }
15102
15103   Handle<JSArray> array;
15104   if (!site.is_null() && can_use_type_feedback) {
15105     ElementsKind to_kind = site->GetElementsKind();
15106     if (holey && !IsFastHoleyElementsKind(to_kind)) {
15107       to_kind = GetHoleyElementsKind(to_kind);
15108       // Update the allocation site info to reflect the advice alteration.
15109       site->SetElementsKind(to_kind);
15110     }
15111
15112     // We should allocate with an initial map that reflects the allocation site
15113     // advice. Therefore we use AllocateJSObjectFromMap instead of passing
15114     // the constructor.
15115     Handle<Map> initial_map(constructor->initial_map(), isolate);
15116     if (to_kind != initial_map->elements_kind()) {
15117       initial_map = Map::AsElementsKind(initial_map, to_kind);
15118     }
15119
15120     // If we don't care to track arrays of to_kind ElementsKind, then
15121     // don't emit a memento for them.
15122     Handle<AllocationSite> allocation_site;
15123     if (AllocationSite::GetMode(to_kind) == TRACK_ALLOCATION_SITE) {
15124       allocation_site = site;
15125     }
15126
15127     array = Handle<JSArray>::cast(factory->NewJSObjectFromMap(
15128         initial_map, NOT_TENURED, true, allocation_site));
15129   } else {
15130     array = Handle<JSArray>::cast(factory->NewJSObject(constructor));
15131
15132     // We might need to transition to holey
15133     ElementsKind kind = constructor->initial_map()->elements_kind();
15134     if (holey && !IsFastHoleyElementsKind(kind)) {
15135       kind = GetHoleyElementsKind(kind);
15136       JSObject::TransitionElementsKind(array, kind);
15137     }
15138   }
15139
15140   factory->NewJSArrayStorage(array, 0, 0, DONT_INITIALIZE_ARRAY_ELEMENTS);
15141
15142   ElementsKind old_kind = array->GetElementsKind();
15143   RETURN_FAILURE_ON_EXCEPTION(
15144       isolate, ArrayConstructInitializeElements(array, caller_args));
15145   if (!site.is_null() &&
15146       (old_kind != array->GetElementsKind() ||
15147        !can_use_type_feedback)) {
15148     // The arguments passed in caused a transition. This kind of complexity
15149     // can't be dealt with in the inlined hydrogen array constructor case.
15150     // We must mark the allocationsite as un-inlinable.
15151     site->SetDoNotInlineCall();
15152   }
15153   return *array;
15154 }
15155
15156
15157 RUNTIME_FUNCTION(Runtime_ArrayConstructor) {
15158   HandleScope scope(isolate);
15159   // If we get 2 arguments then they are the stub parameters (constructor, type
15160   // info).  If we get 4, then the first one is a pointer to the arguments
15161   // passed by the caller, and the last one is the length of the arguments
15162   // passed to the caller (redundant, but useful to check on the deoptimizer
15163   // with an assert).
15164   Arguments empty_args(0, NULL);
15165   bool no_caller_args = args.length() == 2;
15166   DCHECK(no_caller_args || args.length() == 4);
15167   int parameters_start = no_caller_args ? 0 : 1;
15168   Arguments* caller_args = no_caller_args
15169       ? &empty_args
15170       : reinterpret_cast<Arguments*>(args[0]);
15171   CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, parameters_start);
15172   CONVERT_ARG_HANDLE_CHECKED(Object, type_info, parameters_start + 1);
15173 #ifdef DEBUG
15174   if (!no_caller_args) {
15175     CONVERT_SMI_ARG_CHECKED(arg_count, parameters_start + 2);
15176     DCHECK(arg_count == caller_args->length());
15177   }
15178 #endif
15179
15180   Handle<AllocationSite> site;
15181   if (!type_info.is_null() &&
15182       *type_info != isolate->heap()->undefined_value()) {
15183     site = Handle<AllocationSite>::cast(type_info);
15184     DCHECK(!site->SitePointsToLiteral());
15185   }
15186
15187   return ArrayConstructorCommon(isolate,
15188                                 constructor,
15189                                 site,
15190                                 caller_args);
15191 }
15192
15193
15194 RUNTIME_FUNCTION(Runtime_InternalArrayConstructor) {
15195   HandleScope scope(isolate);
15196   Arguments empty_args(0, NULL);
15197   bool no_caller_args = args.length() == 1;
15198   DCHECK(no_caller_args || args.length() == 3);
15199   int parameters_start = no_caller_args ? 0 : 1;
15200   Arguments* caller_args = no_caller_args
15201       ? &empty_args
15202       : reinterpret_cast<Arguments*>(args[0]);
15203   CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, parameters_start);
15204 #ifdef DEBUG
15205   if (!no_caller_args) {
15206     CONVERT_SMI_ARG_CHECKED(arg_count, parameters_start + 1);
15207     DCHECK(arg_count == caller_args->length());
15208   }
15209 #endif
15210   return ArrayConstructorCommon(isolate,
15211                                 constructor,
15212                                 Handle<AllocationSite>::null(),
15213                                 caller_args);
15214 }
15215
15216
15217 RUNTIME_FUNCTION(Runtime_NormalizeElements) {
15218   HandleScope scope(isolate);
15219   DCHECK(args.length() == 1);
15220   CONVERT_ARG_HANDLE_CHECKED(JSObject, array, 0);
15221   RUNTIME_ASSERT(!array->HasExternalArrayElements() &&
15222                  !array->HasFixedTypedArrayElements());
15223   JSObject::NormalizeElements(array);
15224   return *array;
15225 }
15226
15227
15228 RUNTIME_FUNCTION(Runtime_MaxSmi) {
15229   SealHandleScope shs(isolate);
15230   DCHECK(args.length() == 0);
15231   return Smi::FromInt(Smi::kMaxValue);
15232 }
15233
15234
15235 // TODO(dcarney): remove this function when TurboFan supports it.
15236 // Takes the object to be iterated over and the result of GetPropertyNamesFast
15237 // Returns pair (cache_array, cache_type).
15238 RUNTIME_FUNCTION_RETURN_PAIR(Runtime_ForInInit) {
15239   SealHandleScope scope(isolate);
15240   DCHECK(args.length() == 2);
15241   // This simulates CONVERT_ARG_HANDLE_CHECKED for calls returning pairs.
15242   // Not worth creating a macro atm as this function should be removed.
15243   if (!args[0]->IsJSReceiver() || !args[1]->IsObject()) {
15244     Object* error = isolate->ThrowIllegalOperation();
15245     return MakePair(error, isolate->heap()->undefined_value());
15246   }
15247   Handle<JSReceiver> object = args.at<JSReceiver>(0);
15248   Handle<Object> cache_type = args.at<Object>(1);
15249   if (cache_type->IsMap()) {
15250     // Enum cache case.
15251     if (Map::EnumLengthBits::decode(Map::cast(*cache_type)->bit_field3()) ==
15252         0) {
15253       // 0 length enum.
15254       // Can't handle this case in the graph builder,
15255       // so transform it into the empty fixed array case.
15256       return MakePair(isolate->heap()->empty_fixed_array(), Smi::FromInt(1));
15257     }
15258     return MakePair(object->map()->instance_descriptors()->GetEnumCache(),
15259                     *cache_type);
15260   } else {
15261     // FixedArray case.
15262     Smi* new_cache_type = Smi::FromInt(object->IsJSProxy() ? 0 : 1);
15263     return MakePair(*Handle<FixedArray>::cast(cache_type), new_cache_type);
15264   }
15265 }
15266
15267
15268 // TODO(dcarney): remove this function when TurboFan supports it.
15269 RUNTIME_FUNCTION(Runtime_ForInCacheArrayLength) {
15270   SealHandleScope shs(isolate);
15271   DCHECK(args.length() == 2);
15272   CONVERT_ARG_HANDLE_CHECKED(Object, cache_type, 0);
15273   CONVERT_ARG_HANDLE_CHECKED(FixedArray, array, 1);
15274   int length = 0;
15275   if (cache_type->IsMap()) {
15276     length = Map::cast(*cache_type)->EnumLength();
15277   } else {
15278     DCHECK(cache_type->IsSmi());
15279     length = array->length();
15280   }
15281   return Smi::FromInt(length);
15282 }
15283
15284
15285 // TODO(dcarney): remove this function when TurboFan supports it.
15286 // Takes (the object to be iterated over,
15287 //        cache_array from ForInInit,
15288 //        cache_type from ForInInit,
15289 //        the current index)
15290 // Returns pair (array[index], needs_filtering).
15291 RUNTIME_FUNCTION_RETURN_PAIR(Runtime_ForInNext) {
15292   SealHandleScope scope(isolate);
15293   DCHECK(args.length() == 4);
15294   // This simulates CONVERT_ARG_HANDLE_CHECKED for calls returning pairs.
15295   // Not worth creating a macro atm as this function should be removed.
15296   if (!args[0]->IsJSReceiver() || !args[1]->IsFixedArray() ||
15297       !args[2]->IsObject() || !args[3]->IsSmi()) {
15298     Object* error = isolate->ThrowIllegalOperation();
15299     return MakePair(error, isolate->heap()->undefined_value());
15300   }
15301   Handle<JSReceiver> object = args.at<JSReceiver>(0);
15302   Handle<FixedArray> array = args.at<FixedArray>(1);
15303   Handle<Object> cache_type = args.at<Object>(2);
15304   int index = args.smi_at(3);
15305   // Figure out first if a slow check is needed for this object.
15306   bool slow_check_needed = false;
15307   if (cache_type->IsMap()) {
15308     if (object->map() != Map::cast(*cache_type)) {
15309       // Object transitioned.  Need slow check.
15310       slow_check_needed = true;
15311     }
15312   } else {
15313     // No slow check needed for proxies.
15314     slow_check_needed = Smi::cast(*cache_type)->value() == 1;
15315   }
15316   return MakePair(array->get(index),
15317                   isolate->heap()->ToBoolean(slow_check_needed));
15318 }
15319
15320
15321 #define RETURN_Float32x4_RESULT(value)                                         \
15322   return *isolate->factory()->NewFloat32x4(value);
15323
15324
15325 #define RETURN_Float64x2_RESULT(value)                                         \
15326   return *isolate->factory()->NewFloat64x2(value);
15327
15328
15329 #define RETURN_Int32x4_RESULT(value)                                           \
15330   return *isolate->factory()->NewInt32x4(value);
15331
15332
15333 RUNTIME_FUNCTION(Runtime_CreateFloat32x4) {
15334   HandleScope scope(isolate);
15335   DCHECK(args.length() == 4);
15336   RUNTIME_ASSERT(args[0]->IsNumber());
15337   RUNTIME_ASSERT(args[1]->IsNumber());
15338   RUNTIME_ASSERT(args[2]->IsNumber());
15339   RUNTIME_ASSERT(args[3]->IsNumber());
15340
15341   float32x4_value_t value;
15342   value.storage[0] = static_cast<float>(args.number_at(0));
15343   value.storage[1] = static_cast<float>(args.number_at(1));
15344   value.storage[2] = static_cast<float>(args.number_at(2));
15345   value.storage[3] = static_cast<float>(args.number_at(3));
15346
15347   RETURN_Float32x4_RESULT(value);
15348 }
15349
15350
15351 RUNTIME_FUNCTION(Runtime_CreateFloat64x2) {
15352   HandleScope scope(isolate);
15353   DCHECK(args.length() == 2);
15354   RUNTIME_ASSERT(args[0]->IsNumber());
15355   RUNTIME_ASSERT(args[1]->IsNumber());
15356
15357   float64x2_value_t value;
15358   value.storage[0] = args.number_at(0);
15359   value.storage[1] = args.number_at(1);
15360
15361   RETURN_Float64x2_RESULT(value);
15362 }
15363
15364
15365 RUNTIME_FUNCTION(Runtime_CreateInt32x4) {
15366   HandleScope scope(isolate);
15367   DCHECK(args.length() == 4);
15368   RUNTIME_ASSERT(args[0]->IsNumber());
15369   RUNTIME_ASSERT(args[1]->IsNumber());
15370   RUNTIME_ASSERT(args[2]->IsNumber());
15371   RUNTIME_ASSERT(args[3]->IsNumber());
15372
15373   int32x4_value_t value;
15374   value.storage[0] = NumberToInt32(args[0]);
15375   value.storage[1] = NumberToInt32(args[1]);
15376   value.storage[2] = NumberToInt32(args[2]);
15377   value.storage[3] = NumberToInt32(args[3]);
15378
15379   RETURN_Int32x4_RESULT(value);
15380 }
15381
15382
15383 // Used to convert between uint32_t and float32 without breaking strict
15384 // aliasing rules.
15385 union float32_uint32 {
15386   float f;
15387   uint32_t u;
15388   float32_uint32(float v) {
15389     f = v;
15390   }
15391   float32_uint32(uint32_t v) {
15392     u = v;
15393   }
15394 };
15395
15396
15397 union float64_uint64 {
15398   double f;
15399   uint64_t u;
15400   float64_uint64(double v) {
15401     f = v;
15402   }
15403   float64_uint64(uint64_t v) {
15404     u = v;
15405   }
15406 };
15407
15408
15409 RUNTIME_FUNCTION(Runtime_Float32x4GetSignMask) {
15410   HandleScope scope(isolate);
15411   DCHECK(args.length() == 1);
15412   CONVERT_ARG_CHECKED(Float32x4, self, 0);
15413   float32_uint32 x(self->x());
15414   float32_uint32 y(self->y());
15415   float32_uint32 z(self->z());
15416   float32_uint32 w(self->w());
15417   uint32_t mx = (x.u & 0x80000000) >> 31;
15418   uint32_t my = (y.u & 0x80000000) >> 31;
15419   uint32_t mz = (z.u & 0x80000000) >> 31;
15420   uint32_t mw = (w.u & 0x80000000) >> 31;
15421   uint32_t value = mx | (my << 1) | (mz << 2) | (mw << 3);
15422   return *isolate->factory()->NewNumberFromUint(value);
15423 }
15424
15425
15426 RUNTIME_FUNCTION(Runtime_Float64x2GetSignMask) {
15427   HandleScope scope(isolate);
15428   DCHECK(args.length() == 1);
15429   CONVERT_ARG_CHECKED(Float64x2, self, 0);
15430   float64_uint64 x(self->x());
15431   float64_uint64 y(self->y());
15432   uint64_t mx = x.u >> 63;
15433   uint64_t my = y.u >> 63;
15434   uint32_t value = static_cast<uint32_t>(mx | (my << 1));
15435   return *isolate->factory()->NewNumberFromUint(value);
15436 }
15437
15438
15439 RUNTIME_FUNCTION(Runtime_Int32x4GetSignMask) {
15440   HandleScope scope(isolate);
15441   DCHECK(args.length() == 1);
15442   CONVERT_ARG_CHECKED(Int32x4, self, 0);
15443   uint32_t mx = (self->x() & 0x80000000) >> 31;
15444   uint32_t my = (self->y() & 0x80000000) >> 31;
15445   uint32_t mz = (self->z() & 0x80000000) >> 31;
15446   uint32_t mw = (self->w() & 0x80000000) >> 31;
15447   uint32_t value = mx | (my << 1) | (mz << 2) | (mw << 3);
15448   return *isolate->factory()->NewNumberFromUint(value);
15449 }
15450
15451
15452 #define LANE_VALUE(VALUE, LANE) \
15453   VALUE->LANE()
15454
15455
15456 #define LANE_FLAG(VALUE, LANE)  \
15457   VALUE->LANE() != 0
15458
15459
15460 #define SIMD128_LANE_ACCESS_FUNCTIONS(V)                      \
15461   V(Float32x4, GetX, NewNumber, x, LANE_VALUE)       \
15462   V(Float32x4, GetY, NewNumber, y, LANE_VALUE)       \
15463   V(Float32x4, GetZ, NewNumber, z, LANE_VALUE)       \
15464   V(Float32x4, GetW, NewNumber, w, LANE_VALUE)       \
15465   V(Float64x2, GetX, NewNumber, x, LANE_VALUE)       \
15466   V(Float64x2, GetY, NewNumber, y, LANE_VALUE)       \
15467   V(Int32x4, GetX, NewNumberFromInt, x, LANE_VALUE)            \
15468   V(Int32x4, GetY, NewNumberFromInt, y, LANE_VALUE)            \
15469   V(Int32x4, GetZ, NewNumberFromInt, z, LANE_VALUE)            \
15470   V(Int32x4, GetW, NewNumberFromInt, w, LANE_VALUE)            \
15471   V(Int32x4, GetFlagX, ToBoolean, x, LANE_FLAG)               \
15472   V(Int32x4, GetFlagY, ToBoolean, y, LANE_FLAG)               \
15473   V(Int32x4, GetFlagZ, ToBoolean, z, LANE_FLAG)               \
15474   V(Int32x4, GetFlagW, ToBoolean, w, LANE_FLAG)
15475
15476
15477 #define DECLARE_SIMD_LANE_ACCESS_FUNCTION(                    \
15478     TYPE, NAME, HEAP_FUNCTION, LANE, ACCESS_FUNCTION)         \
15479 RUNTIME_FUNCTION(Runtime_##TYPE##NAME) {        \
15480   HandleScope scope(isolate);                                 \
15481   DCHECK(args.length() == 1);                                 \
15482                                                               \
15483   CONVERT_ARG_CHECKED(TYPE, a, 0);                            \
15484                                                               \
15485   return *isolate->factory()->HEAP_FUNCTION(                  \
15486       ACCESS_FUNCTION(a, LANE));                              \
15487 }
15488
15489
15490 SIMD128_LANE_ACCESS_FUNCTIONS(DECLARE_SIMD_LANE_ACCESS_FUNCTION)
15491
15492
15493 template<typename T>
15494 static inline T Neg(T a) {
15495   return -a;
15496 }
15497
15498
15499 template<typename T>
15500 static inline T Not(T a) {
15501   return ~a;
15502 }
15503
15504
15505 template<typename T>
15506 static inline T Reciprocal(T a) {
15507   UNIMPLEMENTED();
15508 }
15509
15510
15511 template<>
15512 inline float Reciprocal<float>(float a) {
15513   return 1.0f / a;
15514 }
15515
15516
15517 template<typename T>
15518 static inline T ReciprocalSqrt(T a) {
15519   UNIMPLEMENTED();
15520 }
15521
15522
15523 template<>
15524 inline float ReciprocalSqrt<float>(float a) {
15525   return sqrtf(1.0f / a);
15526 }
15527
15528
15529 template<typename T>
15530 static inline T Sqrt(T a) {
15531   UNIMPLEMENTED();
15532 }
15533
15534
15535 template<>
15536 inline float Sqrt<float>(float a) {
15537   return sqrtf(a);
15538 }
15539
15540
15541 template<>
15542 inline double Sqrt<double>(double a) {
15543   return sqrt(a);
15544 }
15545
15546
15547 #define SIMD128_UNARY_FUNCTIONS(V)                            \
15548   V(Float32x4, Abs)                                           \
15549   V(Float32x4, Neg)                                           \
15550   V(Float32x4, Reciprocal)                                    \
15551   V(Float32x4, ReciprocalSqrt)                                \
15552   V(Float32x4, Sqrt)                                          \
15553   V(Float64x2, Abs)                                           \
15554   V(Float64x2, Neg)                                           \
15555   V(Float64x2, Sqrt)                                          \
15556   V(Int32x4, Neg)                                             \
15557   V(Int32x4, Not)
15558
15559
15560 #define DECLARE_SIMD_UNARY_FUNCTION(TYPE, FUNCTION)           \
15561 RUNTIME_FUNCTION(Runtime_##TYPE##FUNCTION) {    \
15562   HandleScope scope(isolate);                                 \
15563   DCHECK(args.length() == 1);                                 \
15564                                                               \
15565   CONVERT_ARG_CHECKED(TYPE, a, 0);                            \
15566                                                               \
15567   TYPE::value_t result;                                       \
15568   for (int i = 0; i < TYPE::kLanes; i++) {                    \
15569     result.storage[i] = FUNCTION(a->getAt(i));                \
15570   }                                                           \
15571                                                               \
15572   RETURN_##TYPE##_RESULT(result);                             \
15573 }
15574
15575
15576 SIMD128_UNARY_FUNCTIONS(DECLARE_SIMD_UNARY_FUNCTION)
15577
15578
15579 template<typename T1, typename T2>
15580 inline void BitsTo(T1 s, T2* t) {
15581   memcpy(t, &s, sizeof(T2));
15582 }
15583
15584
15585 template<typename T1, typename T2>
15586 inline void To(T1 s, T2* t) {
15587 }
15588
15589
15590 template<>
15591 inline void To<int32_t, float>(int32_t s, float* t) {
15592   *t = static_cast<float>(s);
15593 }
15594
15595
15596 template<>
15597 inline void To<float, int32_t>(float s, int32_t* t) {
15598   *t = DoubleToInt32(static_cast<double>(s));
15599 }
15600
15601
15602 #define SIMD128_CONVERSION_FUNCTIONS(V)                       \
15603   V(Float32x4, BitsTo, Int32x4)                               \
15604   V(Float32x4, To, Int32x4)                                   \
15605   V(Int32x4, BitsTo, Float32x4)                               \
15606   V(Int32x4, To, Float32x4)
15607
15608
15609 #define DECLARE_SIMD_CONVERSION_FUNCTION(                     \
15610     SOURCE_TYPE, FUNCTION, TARGET_TYPE)                       \
15611 RUNTIME_FUNCTION(                               \
15612     Runtime_##SOURCE_TYPE##FUNCTION##TARGET_TYPE) {           \
15613   HandleScope scope(isolate);                                 \
15614   DCHECK(args.length() == 1);                                 \
15615                                                               \
15616   CONVERT_ARG_CHECKED(SOURCE_TYPE, a, 0);                     \
15617                                                               \
15618   TARGET_TYPE::value_t result;                                \
15619   for (int i = 0; i < SOURCE_TYPE::kLanes; i++) {             \
15620     FUNCTION(a->getAt(i), &result.storage[i]);                \
15621   }                                                           \
15622                                                               \
15623   RETURN_##TARGET_TYPE##_RESULT(result);                      \
15624 }
15625
15626
15627 SIMD128_CONVERSION_FUNCTIONS(DECLARE_SIMD_CONVERSION_FUNCTION)
15628
15629
15630 template<typename T>
15631 static inline T Add(T a, T b) {
15632   return a + b;
15633 }
15634
15635
15636 template<typename T>
15637 static inline T Div(T a, T b) {
15638   return a / b;
15639 }
15640
15641
15642 template<typename T>
15643 static inline T Mul(T a, T b) {
15644   return a * b;
15645 }
15646
15647
15648 template<typename T>
15649 static inline T Sub(T a, T b) {
15650   return a - b;
15651 }
15652
15653
15654 template<typename T>
15655 static inline int32_t Equal(T a, T b) {
15656   return a == b ? -1 : 0;
15657 }
15658
15659
15660 template<typename T>
15661 static inline int32_t NotEqual(T a, T b) {
15662   return a != b ? -1 : 0;
15663 }
15664
15665
15666 template<typename T>
15667 static inline int32_t GreaterThanOrEqual(T a, T b) {
15668   return a >= b ? -1 : 0;
15669 }
15670
15671
15672 template<typename T>
15673 static inline int32_t GreaterThan(T a, T b) {
15674   return a > b ? -1 : 0;
15675 }
15676
15677
15678 template<typename T>
15679 static inline int32_t LessThan(T a, T b) {
15680   return a < b ? -1 : 0;
15681 }
15682
15683
15684 template<typename T>
15685 static inline int32_t LessThanOrEqual(T a, T b) {
15686   return a <= b ? -1 : 0;
15687 }
15688
15689
15690 template<typename T>
15691 static inline T And(T a, T b) {
15692   return a & b;
15693 }
15694
15695
15696 template<typename T>
15697 static inline T Or(T a, T b) {
15698   return a | b;
15699 }
15700
15701
15702 template<typename T>
15703 static inline T Xor(T a, T b) {
15704   return a ^ b;
15705 }
15706
15707
15708 #define SIMD128_BINARY_FUNCTIONS(V)                           \
15709   V(Float32x4, Add, Float32x4)                                \
15710   V(Float32x4, Div, Float32x4)                                \
15711   V(Float32x4, Max, Float32x4)                                \
15712   V(Float32x4, Min, Float32x4)                                \
15713   V(Float32x4, Mul, Float32x4)                                \
15714   V(Float32x4, Sub, Float32x4)                                \
15715   V(Float32x4, Equal, Int32x4)                                \
15716   V(Float32x4, NotEqual, Int32x4)                             \
15717   V(Float32x4, GreaterThanOrEqual, Int32x4)                   \
15718   V(Float32x4, GreaterThan, Int32x4)                          \
15719   V(Float32x4, LessThan, Int32x4)                             \
15720   V(Float32x4, LessThanOrEqual, Int32x4)                      \
15721   V(Float64x2, Add, Float64x2)                                \
15722   V(Float64x2, Div, Float64x2)                                \
15723   V(Float64x2, Max, Float64x2)                                \
15724   V(Float64x2, Min, Float64x2)                                \
15725   V(Float64x2, Mul, Float64x2)                                \
15726   V(Float64x2, Sub, Float64x2)                                \
15727   V(Int32x4, Add, Int32x4)                                    \
15728   V(Int32x4, And, Int32x4)                                    \
15729   V(Int32x4, Mul, Int32x4)                                    \
15730   V(Int32x4, Or, Int32x4)                                     \
15731   V(Int32x4, Sub, Int32x4)                                    \
15732   V(Int32x4, Xor, Int32x4)                                    \
15733   V(Int32x4, Equal, Int32x4)                                  \
15734   V(Int32x4, GreaterThan, Int32x4)                            \
15735   V(Int32x4, LessThan, Int32x4)
15736
15737
15738 #define DECLARE_SIMD_BINARY_FUNCTION(                         \
15739     TYPE, FUNCTION, RETURN_TYPE)                              \
15740 RUNTIME_FUNCTION(Runtime_##TYPE##FUNCTION) {    \
15741   HandleScope scope(isolate);                                 \
15742   DCHECK(args.length() == 2);                                 \
15743                                                               \
15744   CONVERT_ARG_CHECKED(TYPE, a, 0);                            \
15745   CONVERT_ARG_CHECKED(TYPE, b, 1);                            \
15746                                                               \
15747   RETURN_TYPE::value_t result;                                \
15748   for (int i = 0; i < TYPE::kLanes; i++) {                    \
15749     result.storage[i] = FUNCTION(a->getAt(i), b->getAt(i));   \
15750   }                                                           \
15751                                                               \
15752   RETURN_##RETURN_TYPE##_RESULT(result);                      \
15753 }
15754
15755
15756 SIMD128_BINARY_FUNCTIONS(DECLARE_SIMD_BINARY_FUNCTION)
15757
15758
15759 #define SIMD128_SHUFFLE_FUNCTIONS(V)                          \
15760   V(Float32x4)                                                \
15761   V(Int32x4)
15762
15763
15764 #define DECLARE_SIMD_SHUFFLE_FUNCTION(TYPE)                   \
15765 RUNTIME_FUNCTION(Runtime_##TYPE##Shuffle) {     \
15766   HandleScope scope(isolate);                                 \
15767   DCHECK(args.length() == 2);                                 \
15768                                                               \
15769   CONVERT_ARG_CHECKED(TYPE, a, 0);                            \
15770   RUNTIME_ASSERT(args[1]->IsNumber());                        \
15771   uint32_t m = NumberToUint32(args[1]);                       \
15772                                                               \
15773   TYPE::value_t result;                                       \
15774   for (int i = 0; i < TYPE::kLanes; i++) {                    \
15775     result.storage[i] = a->getAt((m >> (i * 2)) & 0x3);       \
15776   }                                                           \
15777                                                               \
15778   RETURN_##TYPE##_RESULT(result);                             \
15779 }
15780
15781
15782 SIMD128_SHUFFLE_FUNCTIONS(DECLARE_SIMD_SHUFFLE_FUNCTION)
15783
15784
15785 RUNTIME_FUNCTION(Runtime_Float32x4Scale) {
15786   HandleScope scope(isolate);
15787   DCHECK(args.length() == 2);
15788
15789   CONVERT_ARG_CHECKED(Float32x4, self, 0);
15790   RUNTIME_ASSERT(args[1]->IsNumber());
15791
15792   float _s = static_cast<float>(args.number_at(1));
15793   float32x4_value_t result;
15794   result.storage[0] = self->x() * _s;
15795   result.storage[1] = self->y() * _s;
15796   result.storage[2] = self->z() * _s;
15797   result.storage[3] = self->w() * _s;
15798
15799   RETURN_Float32x4_RESULT(result);
15800 }
15801
15802
15803 RUNTIME_FUNCTION(Runtime_Float64x2Scale) {
15804   HandleScope scope(isolate);
15805   DCHECK(args.length() == 2);
15806
15807   CONVERT_ARG_CHECKED(Float64x2, self, 0);
15808   RUNTIME_ASSERT(args[1]->IsNumber());
15809
15810   double _s = args.number_at(1);
15811   float64x2_value_t result;
15812   result.storage[0] = self->x() * _s;
15813   result.storage[1] = self->y() * _s;
15814
15815   RETURN_Float64x2_RESULT(result);
15816 }
15817
15818
15819 #define ARG_TO_FLOAT32(x) \
15820   CONVERT_DOUBLE_ARG_CHECKED(t, 1); \
15821   float x = static_cast<float>(t);
15822
15823
15824 #define ARG_TO_FLOAT64(x) \
15825   CONVERT_DOUBLE_ARG_CHECKED(x, 1); \
15826
15827
15828 #define ARG_TO_INT32(x) \
15829   RUNTIME_ASSERT(args[1]->IsNumber()); \
15830   int32_t x = NumberToInt32(args[1]);
15831
15832
15833 #define ARG_TO_BOOLEAN(x) \
15834   CONVERT_BOOLEAN_ARG_CHECKED(flag, 1); \
15835   int32_t x = flag ? -1 : 0;
15836
15837 #define SIMD128_SET_LANE_FUNCTIONS(V)                         \
15838   V(Float32x4, WithX, ARG_TO_FLOAT32, 0)                      \
15839   V(Float32x4, WithY, ARG_TO_FLOAT32, 1)                      \
15840   V(Float32x4, WithZ, ARG_TO_FLOAT32, 2)                      \
15841   V(Float32x4, WithW, ARG_TO_FLOAT32, 3)                      \
15842   V(Float64x2, WithX, ARG_TO_FLOAT64, 0)                      \
15843   V(Float64x2, WithY, ARG_TO_FLOAT64, 1)                      \
15844   V(Int32x4, WithX, ARG_TO_INT32, 0)                          \
15845   V(Int32x4, WithY, ARG_TO_INT32, 1)                          \
15846   V(Int32x4, WithZ, ARG_TO_INT32, 2)                          \
15847   V(Int32x4, WithW, ARG_TO_INT32, 3)                          \
15848   V(Int32x4, WithFlagX, ARG_TO_BOOLEAN, 0)                    \
15849   V(Int32x4, WithFlagY, ARG_TO_BOOLEAN, 1)                    \
15850   V(Int32x4, WithFlagZ, ARG_TO_BOOLEAN, 2)                    \
15851   V(Int32x4, WithFlagW, ARG_TO_BOOLEAN, 3)
15852
15853
15854 #define DECLARE_SIMD_SET_LANE_FUNCTION(                       \
15855     TYPE, NAME, ARG_FUNCTION, LANE)                           \
15856 RUNTIME_FUNCTION(Runtime_##TYPE##NAME) {        \
15857   HandleScope scope(isolate);                                 \
15858   DCHECK(args.length() == 2);                                 \
15859                                                               \
15860   CONVERT_ARG_CHECKED(TYPE, a, 0);                            \
15861   ARG_FUNCTION(value);                                        \
15862                                                               \
15863   TYPE::value_t result;                                       \
15864   for (int i = 0; i < TYPE::kLanes; i++) {                    \
15865     if (i != LANE)                                            \
15866       result.storage[i] = a->getAt(i);                        \
15867     else                                                      \
15868       result.storage[i] = value;                              \
15869   }                                                           \
15870                                                               \
15871   RETURN_##TYPE##_RESULT(result);                             \
15872 }
15873
15874
15875 SIMD128_SET_LANE_FUNCTIONS(DECLARE_SIMD_SET_LANE_FUNCTION)
15876
15877
15878 RUNTIME_FUNCTION(Runtime_Float32x4Clamp) {
15879   HandleScope scope(isolate);
15880   DCHECK(args.length() == 3);
15881
15882   CONVERT_ARG_CHECKED(Float32x4, self, 0);
15883   CONVERT_ARG_CHECKED(Float32x4, lo, 1);
15884   CONVERT_ARG_CHECKED(Float32x4, hi, 2);
15885
15886   float32x4_value_t result;
15887   float _x = self->x() > lo->x() ? self->x() : lo->x();
15888   float _y = self->y() > lo->y() ? self->y() : lo->y();
15889   float _z = self->z() > lo->z() ? self->z() : lo->z();
15890   float _w = self->w() > lo->w() ? self->w() : lo->w();
15891   result.storage[0] = _x > hi->x() ? hi->x() : _x;
15892   result.storage[1] = _y > hi->y() ? hi->y() : _y;
15893   result.storage[2] = _z > hi->z() ? hi->z() : _z;
15894   result.storage[3] = _w > hi->w() ? hi->w() : _w;
15895
15896   RETURN_Float32x4_RESULT(result);
15897 }
15898
15899
15900 RUNTIME_FUNCTION(Runtime_Float64x2Clamp) {
15901   HandleScope scope(isolate);
15902   DCHECK(args.length() == 3);
15903
15904   CONVERT_ARG_CHECKED(Float64x2, self, 0);
15905   CONVERT_ARG_CHECKED(Float64x2, lo, 1);
15906   CONVERT_ARG_CHECKED(Float64x2, hi, 2);
15907
15908   float64x2_value_t result;
15909   double _x = self->x() > lo->x() ? self->x() : lo->x();
15910   double _y = self->y() > lo->y() ? self->y() : lo->y();
15911   result.storage[0] = _x > hi->x() ? hi->x() : _x;
15912   result.storage[1] = _y > hi->y() ? hi->y() : _y;
15913
15914   RETURN_Float64x2_RESULT(result);
15915 }
15916
15917
15918 RUNTIME_FUNCTION(Runtime_Float32x4ShuffleMix) {
15919   HandleScope scope(isolate);
15920   DCHECK(args.length() == 3);
15921
15922   CONVERT_ARG_CHECKED(Float32x4, first, 0);
15923   CONVERT_ARG_CHECKED(Float32x4, second, 1);
15924   RUNTIME_ASSERT(args[2]->IsNumber());
15925
15926   uint32_t m = NumberToUint32(args[2]);
15927   float32x4_value_t result;
15928   float data1[4] = { first->x(), first->y(), first->z(), first->w() };
15929   float data2[4] = { second->x(), second->y(), second->z(), second->w() };
15930   result.storage[0] = data1[m & 0x3];
15931   result.storage[1] = data1[(m >> 2) & 0x3];
15932   result.storage[2] = data2[(m >> 4) & 0x3];
15933   result.storage[3] = data2[(m >> 6) & 0x3];
15934
15935   RETURN_Float32x4_RESULT(result);
15936 }
15937
15938
15939 RUNTIME_FUNCTION(Runtime_Float32x4Select) {
15940   HandleScope scope(isolate);
15941   DCHECK(args.length() == 3);
15942
15943   CONVERT_ARG_CHECKED(Int32x4, self, 0);
15944   CONVERT_ARG_CHECKED(Float32x4, tv, 1);
15945   CONVERT_ARG_CHECKED(Float32x4, fv, 2);
15946
15947   uint32_t _maskX = self->x();
15948   uint32_t _maskY = self->y();
15949   uint32_t _maskZ = self->z();
15950   uint32_t _maskW = self->w();
15951   // Extract floats and interpret them as masks.
15952   float32_uint32 tvx(tv->x());
15953   float32_uint32 tvy(tv->y());
15954   float32_uint32 tvz(tv->z());
15955   float32_uint32 tvw(tv->w());
15956   float32_uint32 fvx(fv->x());
15957   float32_uint32 fvy(fv->y());
15958   float32_uint32 fvz(fv->z());
15959   float32_uint32 fvw(fv->w());
15960   // Perform select.
15961   float32_uint32 tempX((_maskX & tvx.u) | (~_maskX & fvx.u));
15962   float32_uint32 tempY((_maskY & tvy.u) | (~_maskY & fvy.u));
15963   float32_uint32 tempZ((_maskZ & tvz.u) | (~_maskZ & fvz.u));
15964   float32_uint32 tempW((_maskW & tvw.u) | (~_maskW & fvw.u));
15965
15966   float32x4_value_t result;
15967   result.storage[0] = tempX.f;
15968   result.storage[1] = tempY.f;
15969   result.storage[2] = tempZ.f;
15970   result.storage[3] = tempW.f;
15971
15972   RETURN_Float32x4_RESULT(result);
15973 }
15974
15975
15976 RUNTIME_FUNCTION(Runtime_Int32x4Select) {
15977   HandleScope scope(isolate);
15978   DCHECK(args.length() == 3);
15979
15980   CONVERT_ARG_CHECKED(Int32x4, self, 0);
15981   CONVERT_ARG_CHECKED(Int32x4, tv, 1);
15982   CONVERT_ARG_CHECKED(Int32x4, fv, 2);
15983
15984   uint32_t _maskX = self->x();
15985   uint32_t _maskY = self->y();
15986   uint32_t _maskZ = self->z();
15987   uint32_t _maskW = self->w();
15988
15989   int32x4_value_t result;
15990   result.storage[0] = (_maskX & tv->x()) | (~_maskX & fv->x());
15991   result.storage[1] = (_maskY & tv->y()) | (~_maskY & fv->y());
15992   result.storage[2] = (_maskZ & tv->z()) | (~_maskZ & fv->z());
15993   result.storage[3] = (_maskW & tv->w()) | (~_maskW & fv->w());
15994
15995   RETURN_Int32x4_RESULT(result);
15996 }
15997
15998
15999 // ----------------------------------------------------------------------------
16000 // Reference implementation for inlined runtime functions.  Only used when the
16001 // compiler does not support a certain intrinsic.  Don't optimize these, but
16002 // implement the intrinsic in the respective compiler instead.
16003
16004 // TODO(mstarzinger): These are place-holder stubs for TurboFan and will
16005 // eventually all have a C++ implementation and this macro will be gone.
16006 #define U(name)                               \
16007   RUNTIME_FUNCTION(RuntimeReference_##name) { \
16008     UNIMPLEMENTED();                          \
16009     return NULL;                              \
16010   }
16011
16012 U(IsStringWrapperSafeForDefaultValueOf)
16013 U(GeneratorNext)
16014 U(GeneratorThrow)
16015 U(DebugBreakInOptimizedCode)
16016
16017 #undef U
16018
16019
16020 RUNTIME_FUNCTION(RuntimeReference_IsSmi) {
16021   SealHandleScope shs(isolate);
16022   DCHECK(args.length() == 1);
16023   CONVERT_ARG_CHECKED(Object, obj, 0);
16024   return isolate->heap()->ToBoolean(obj->IsSmi());
16025 }
16026
16027
16028 RUNTIME_FUNCTION(RuntimeReference_IsNonNegativeSmi) {
16029   SealHandleScope shs(isolate);
16030   DCHECK(args.length() == 1);
16031   CONVERT_ARG_CHECKED(Object, obj, 0);
16032   return isolate->heap()->ToBoolean(obj->IsSmi() &&
16033                                     Smi::cast(obj)->value() >= 0);
16034 }
16035
16036
16037 RUNTIME_FUNCTION(RuntimeReference_IsArray) {
16038   SealHandleScope shs(isolate);
16039   DCHECK(args.length() == 1);
16040   CONVERT_ARG_CHECKED(Object, obj, 0);
16041   return isolate->heap()->ToBoolean(obj->IsJSArray());
16042 }
16043
16044
16045 RUNTIME_FUNCTION(RuntimeReference_IsRegExp) {
16046   SealHandleScope shs(isolate);
16047   DCHECK(args.length() == 1);
16048   CONVERT_ARG_CHECKED(Object, obj, 0);
16049   return isolate->heap()->ToBoolean(obj->IsJSRegExp());
16050 }
16051
16052
16053 RUNTIME_FUNCTION(RuntimeReference_IsConstructCall) {
16054   SealHandleScope shs(isolate);
16055   DCHECK(args.length() == 0);
16056   JavaScriptFrameIterator it(isolate);
16057   JavaScriptFrame* frame = it.frame();
16058   return isolate->heap()->ToBoolean(frame->IsConstructor());
16059 }
16060
16061
16062 RUNTIME_FUNCTION(RuntimeReference_CallFunction) {
16063   SealHandleScope shs(isolate);
16064   return __RT_impl_Runtime_Call(args, isolate);
16065 }
16066
16067
16068 RUNTIME_FUNCTION(RuntimeReference_ArgumentsLength) {
16069   SealHandleScope shs(isolate);
16070   DCHECK(args.length() == 0);
16071   JavaScriptFrameIterator it(isolate);
16072   JavaScriptFrame* frame = it.frame();
16073   return Smi::FromInt(frame->GetArgumentsLength());
16074 }
16075
16076
16077 RUNTIME_FUNCTION(RuntimeReference_Arguments) {
16078   SealHandleScope shs(isolate);
16079   return __RT_impl_Runtime_GetArgumentsProperty(args, isolate);
16080 }
16081
16082
16083 RUNTIME_FUNCTION(RuntimeReference_ValueOf) {
16084   SealHandleScope shs(isolate);
16085   DCHECK(args.length() == 1);
16086   CONVERT_ARG_CHECKED(Object, obj, 0);
16087   if (!obj->IsJSValue()) return obj;
16088   return JSValue::cast(obj)->value();
16089 }
16090
16091
16092 RUNTIME_FUNCTION(RuntimeReference_SetValueOf) {
16093   SealHandleScope shs(isolate);
16094   DCHECK(args.length() == 2);
16095   CONVERT_ARG_CHECKED(Object, obj, 0);
16096   CONVERT_ARG_CHECKED(Object, value, 1);
16097   if (!obj->IsJSValue()) return value;
16098   JSValue::cast(obj)->set_value(value);
16099   return value;
16100 }
16101
16102
16103 RUNTIME_FUNCTION(RuntimeReference_DateField) {
16104   SealHandleScope shs(isolate);
16105   DCHECK(args.length() == 2);
16106   CONVERT_ARG_CHECKED(Object, obj, 0);
16107   CONVERT_SMI_ARG_CHECKED(index, 1);
16108   if (!obj->IsJSDate()) {
16109     HandleScope scope(isolate);
16110     return isolate->Throw(*isolate->factory()->NewTypeError(
16111         "not_date_object", HandleVector<Object>(NULL, 0)));
16112   }
16113   JSDate* date = JSDate::cast(obj);
16114   if (index == 0) return date->value();
16115   return JSDate::GetField(date, Smi::FromInt(index));
16116 }
16117
16118
16119 RUNTIME_FUNCTION(RuntimeReference_StringCharFromCode) {
16120   SealHandleScope shs(isolate);
16121   return __RT_impl_Runtime_CharFromCode(args, isolate);
16122 }
16123
16124
16125 RUNTIME_FUNCTION(RuntimeReference_StringCharAt) {
16126   SealHandleScope shs(isolate);
16127   DCHECK(args.length() == 2);
16128   if (!args[0]->IsString()) return Smi::FromInt(0);
16129   if (!args[1]->IsNumber()) return Smi::FromInt(0);
16130   if (std::isinf(args.number_at(1))) return isolate->heap()->empty_string();
16131   Object* code = __RT_impl_Runtime_StringCharCodeAtRT(args, isolate);
16132   if (code->IsNaN()) return isolate->heap()->empty_string();
16133   return __RT_impl_Runtime_CharFromCode(Arguments(1, &code), isolate);
16134 }
16135
16136
16137 RUNTIME_FUNCTION(RuntimeReference_OneByteSeqStringSetChar) {
16138   SealHandleScope shs(isolate);
16139   DCHECK(args.length() == 3);
16140   CONVERT_ARG_CHECKED(SeqOneByteString, string, 0);
16141   CONVERT_SMI_ARG_CHECKED(index, 1);
16142   CONVERT_SMI_ARG_CHECKED(value, 2);
16143   string->SeqOneByteStringSet(index, value);
16144   return string;
16145 }
16146
16147
16148 RUNTIME_FUNCTION(RuntimeReference_TwoByteSeqStringSetChar) {
16149   SealHandleScope shs(isolate);
16150   DCHECK(args.length() == 3);
16151   CONVERT_ARG_CHECKED(SeqTwoByteString, string, 0);
16152   CONVERT_SMI_ARG_CHECKED(index, 1);
16153   CONVERT_SMI_ARG_CHECKED(value, 2);
16154   string->SeqTwoByteStringSet(index, value);
16155   return string;
16156 }
16157
16158
16159 RUNTIME_FUNCTION(RuntimeReference_ObjectEquals) {
16160   SealHandleScope shs(isolate);
16161   DCHECK(args.length() == 2);
16162   CONVERT_ARG_CHECKED(Object, obj1, 0);
16163   CONVERT_ARG_CHECKED(Object, obj2, 1);
16164   return isolate->heap()->ToBoolean(obj1 == obj2);
16165 }
16166
16167
16168 RUNTIME_FUNCTION(RuntimeReference_IsObject) {
16169   SealHandleScope shs(isolate);
16170   DCHECK(args.length() == 1);
16171   CONVERT_ARG_CHECKED(Object, obj, 0);
16172   if (!obj->IsHeapObject()) return isolate->heap()->false_value();
16173   if (obj->IsNull()) return isolate->heap()->true_value();
16174   if (obj->IsUndetectableObject()) return isolate->heap()->false_value();
16175   Map* map = HeapObject::cast(obj)->map();
16176   bool is_non_callable_spec_object =
16177       map->instance_type() >= FIRST_NONCALLABLE_SPEC_OBJECT_TYPE &&
16178       map->instance_type() <= LAST_NONCALLABLE_SPEC_OBJECT_TYPE;
16179   return isolate->heap()->ToBoolean(is_non_callable_spec_object);
16180 }
16181
16182
16183 RUNTIME_FUNCTION(RuntimeReference_IsFunction) {
16184   SealHandleScope shs(isolate);
16185   DCHECK(args.length() == 1);
16186   CONVERT_ARG_CHECKED(Object, obj, 0);
16187   return isolate->heap()->ToBoolean(obj->IsJSFunction());
16188 }
16189
16190
16191 RUNTIME_FUNCTION(RuntimeReference_IsUndetectableObject) {
16192   SealHandleScope shs(isolate);
16193   DCHECK(args.length() == 1);
16194   CONVERT_ARG_CHECKED(Object, obj, 0);
16195   return isolate->heap()->ToBoolean(obj->IsUndetectableObject());
16196 }
16197
16198
16199 RUNTIME_FUNCTION(RuntimeReference_IsSpecObject) {
16200   SealHandleScope shs(isolate);
16201   DCHECK(args.length() == 1);
16202   CONVERT_ARG_CHECKED(Object, obj, 0);
16203   return isolate->heap()->ToBoolean(obj->IsSpecObject());
16204 }
16205
16206
16207 RUNTIME_FUNCTION(RuntimeReference_MathPow) {
16208   SealHandleScope shs(isolate);
16209   return __RT_impl_Runtime_MathPowSlow(args, isolate);
16210 }
16211
16212
16213 RUNTIME_FUNCTION(RuntimeReference_IsMinusZero) {
16214   SealHandleScope shs(isolate);
16215   DCHECK(args.length() == 1);
16216   CONVERT_ARG_CHECKED(Object, obj, 0);
16217   if (!obj->IsHeapNumber()) return isolate->heap()->false_value();
16218   HeapNumber* number = HeapNumber::cast(obj);
16219   return isolate->heap()->ToBoolean(IsMinusZero(number->value()));
16220 }
16221
16222
16223 RUNTIME_FUNCTION(RuntimeReference_HasCachedArrayIndex) {
16224   SealHandleScope shs(isolate);
16225   DCHECK(args.length() == 1);
16226   return isolate->heap()->false_value();
16227 }
16228
16229
16230 RUNTIME_FUNCTION(RuntimeReference_GetCachedArrayIndex) {
16231   SealHandleScope shs(isolate);
16232   DCHECK(args.length() == 1);
16233   return isolate->heap()->undefined_value();
16234 }
16235
16236
16237 RUNTIME_FUNCTION(RuntimeReference_FastAsciiArrayJoin) {
16238   SealHandleScope shs(isolate);
16239   DCHECK(args.length() == 2);
16240   return isolate->heap()->undefined_value();
16241 }
16242
16243
16244 RUNTIME_FUNCTION(RuntimeReference_ClassOf) {
16245   SealHandleScope shs(isolate);
16246   DCHECK(args.length() == 1);
16247   CONVERT_ARG_CHECKED(Object, obj, 0);
16248   if (!obj->IsJSReceiver()) return isolate->heap()->null_value();
16249   return JSReceiver::cast(obj)->class_name();
16250 }
16251
16252
16253 RUNTIME_FUNCTION(RuntimeReference_StringCharCodeAt) {
16254   SealHandleScope shs(isolate);
16255   DCHECK(args.length() == 2);
16256   if (!args[0]->IsString()) return isolate->heap()->undefined_value();
16257   if (!args[1]->IsNumber()) return isolate->heap()->undefined_value();
16258   if (std::isinf(args.number_at(1))) return isolate->heap()->nan_value();
16259   return __RT_impl_Runtime_StringCharCodeAtRT(args, isolate);
16260 }
16261
16262
16263 RUNTIME_FUNCTION(RuntimeReference_StringAdd) {
16264   SealHandleScope shs(isolate);
16265   return __RT_impl_Runtime_StringAdd(args, isolate);
16266 }
16267
16268
16269 RUNTIME_FUNCTION(RuntimeReference_SubString) {
16270   SealHandleScope shs(isolate);
16271   return __RT_impl_Runtime_SubString(args, isolate);
16272 }
16273
16274
16275 RUNTIME_FUNCTION(RuntimeReference_StringCompare) {
16276   SealHandleScope shs(isolate);
16277   return __RT_impl_Runtime_StringCompare(args, isolate);
16278 }
16279
16280
16281 RUNTIME_FUNCTION(RuntimeReference_RegExpExec) {
16282   SealHandleScope shs(isolate);
16283   return __RT_impl_Runtime_RegExpExecRT(args, isolate);
16284 }
16285
16286
16287 RUNTIME_FUNCTION(RuntimeReference_RegExpConstructResult) {
16288   SealHandleScope shs(isolate);
16289   return __RT_impl_Runtime_RegExpConstructResult(args, isolate);
16290 }
16291
16292
16293 RUNTIME_FUNCTION(RuntimeReference_GetFromCache) {
16294   HandleScope scope(isolate);
16295   DCHECK(args.length() == 2);
16296   CONVERT_SMI_ARG_CHECKED(id, 0);
16297   args[0] = isolate->native_context()->jsfunction_result_caches()->get(id);
16298   return __RT_impl_Runtime_GetFromCache(args, isolate);
16299 }
16300
16301
16302 RUNTIME_FUNCTION(RuntimeReference_NumberToString) {
16303   SealHandleScope shs(isolate);
16304   return __RT_impl_Runtime_NumberToStringRT(args, isolate);
16305 }
16306
16307
16308 RUNTIME_FUNCTION(RuntimeReference_DebugIsActive) {
16309   SealHandleScope shs(isolate);
16310   return Smi::FromInt(isolate->debug()->is_active());
16311 }
16312
16313
16314 // ----------------------------------------------------------------------------
16315 // Implementation of Runtime
16316
16317 #define F(name, number_of_args, result_size)                                  \
16318   {                                                                           \
16319     Runtime::k##name, Runtime::RUNTIME, #name, FUNCTION_ADDR(Runtime_##name), \
16320         number_of_args, result_size                                           \
16321   }                                                                           \
16322   ,
16323
16324
16325 #define I(name, number_of_args, result_size)                                \
16326   {                                                                         \
16327     Runtime::kInline##name, Runtime::INLINE, "_" #name,                     \
16328         FUNCTION_ADDR(RuntimeReference_##name), number_of_args, result_size \
16329   }                                                                         \
16330   ,
16331
16332
16333 #define IO(name, number_of_args, result_size)                              \
16334   {                                                                        \
16335     Runtime::kInlineOptimized##name, Runtime::INLINE_OPTIMIZED, "_" #name, \
16336         FUNCTION_ADDR(Runtime_##name), number_of_args, result_size         \
16337   }                                                                        \
16338   ,
16339
16340
16341 static const Runtime::Function kIntrinsicFunctions[] = {
16342   RUNTIME_FUNCTION_LIST(F)
16343   INLINE_OPTIMIZED_FUNCTION_LIST(F)
16344   INLINE_FUNCTION_LIST(I)
16345   INLINE_OPTIMIZED_FUNCTION_LIST(IO)
16346 };
16347
16348 #undef IO
16349 #undef I
16350 #undef F
16351
16352
16353 void Runtime::InitializeIntrinsicFunctionNames(Isolate* isolate,
16354                                                Handle<NameDictionary> dict) {
16355   DCHECK(dict->NumberOfElements() == 0);
16356   HandleScope scope(isolate);
16357   for (int i = 0; i < kNumFunctions; ++i) {
16358     const char* name = kIntrinsicFunctions[i].name;
16359     if (name == NULL) continue;
16360     Handle<NameDictionary> new_dict = NameDictionary::Add(
16361         dict,
16362         isolate->factory()->InternalizeUtf8String(name),
16363         Handle<Smi>(Smi::FromInt(i), isolate),
16364         PropertyDetails(NONE, NORMAL, Representation::None()));
16365     // The dictionary does not need to grow.
16366     CHECK(new_dict.is_identical_to(dict));
16367   }
16368 }
16369
16370
16371 const Runtime::Function* Runtime::FunctionForName(Handle<String> name) {
16372   Heap* heap = name->GetHeap();
16373   int entry = heap->intrinsic_function_names()->FindEntry(name);
16374   if (entry != kNotFound) {
16375     Object* smi_index = heap->intrinsic_function_names()->ValueAt(entry);
16376     int function_index = Smi::cast(smi_index)->value();
16377     return &(kIntrinsicFunctions[function_index]);
16378   }
16379   return NULL;
16380 }
16381
16382
16383 const Runtime::Function* Runtime::FunctionForEntry(Address entry) {
16384   for (size_t i = 0; i < ARRAY_SIZE(kIntrinsicFunctions); ++i) {
16385     if (entry == kIntrinsicFunctions[i].entry) {
16386       return &(kIntrinsicFunctions[i]);
16387     }
16388   }
16389   return NULL;
16390 }
16391
16392
16393 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) {
16394   return &(kIntrinsicFunctions[static_cast<int>(id)]);
16395 }
16396
16397 } }  // namespace v8::internal