Upstream version 10.38.220.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 RUNTIME_FUNCTION(Runtime_CompileString) {
9791   HandleScope scope(isolate);
9792   DCHECK(args.length() == 2);
9793   CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
9794   CONVERT_BOOLEAN_ARG_CHECKED(function_literal_only, 1);
9795
9796   // Extract native context.
9797   Handle<Context> context(isolate->native_context());
9798
9799   // Check if native context allows code generation from
9800   // strings. Throw an exception if it doesn't.
9801   if (context->allow_code_gen_from_strings()->IsFalse() &&
9802       !CodeGenerationFromStringsAllowed(isolate, context)) {
9803     Handle<Object> error_message =
9804         context->ErrorMessageForCodeGenerationFromStrings();
9805     return isolate->Throw(*isolate->factory()->NewEvalError(
9806         "code_gen_from_strings", HandleVector<Object>(&error_message, 1)));
9807   }
9808
9809   // Compile source string in the native context.
9810   ParseRestriction restriction = function_literal_only
9811       ? ONLY_SINGLE_FUNCTION_LITERAL : NO_PARSE_RESTRICTION;
9812   Handle<JSFunction> fun;
9813   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
9814       isolate, fun,
9815       Compiler::GetFunctionFromEval(
9816           source, context, SLOPPY, restriction, RelocInfo::kNoPosition));
9817   return *fun;
9818 }
9819
9820
9821 static ObjectPair CompileGlobalEval(Isolate* isolate,
9822                                     Handle<String> source,
9823                                     Handle<Object> receiver,
9824                                     StrictMode strict_mode,
9825                                     int scope_position) {
9826   Handle<Context> context = Handle<Context>(isolate->context());
9827   Handle<Context> native_context = Handle<Context>(context->native_context());
9828
9829   // Check if native context allows code generation from
9830   // strings. Throw an exception if it doesn't.
9831   if (native_context->allow_code_gen_from_strings()->IsFalse() &&
9832       !CodeGenerationFromStringsAllowed(isolate, native_context)) {
9833     Handle<Object> error_message =
9834         native_context->ErrorMessageForCodeGenerationFromStrings();
9835     isolate->Throw(*isolate->factory()->NewEvalError(
9836         "code_gen_from_strings", HandleVector<Object>(&error_message, 1)));
9837     return MakePair(isolate->heap()->exception(), NULL);
9838   }
9839
9840   // Deal with a normal eval call with a string argument. Compile it
9841   // and return the compiled function bound in the local context.
9842   static const ParseRestriction restriction = NO_PARSE_RESTRICTION;
9843   Handle<JSFunction> compiled;
9844   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
9845       isolate, compiled,
9846       Compiler::GetFunctionFromEval(
9847           source, context, strict_mode, restriction, scope_position),
9848       MakePair(isolate->heap()->exception(), NULL));
9849   return MakePair(*compiled, *receiver);
9850 }
9851
9852
9853 RUNTIME_FUNCTION_RETURN_PAIR(Runtime_ResolvePossiblyDirectEval) {
9854   HandleScope scope(isolate);
9855   DCHECK(args.length() == 5);
9856
9857   Handle<Object> callee = args.at<Object>(0);
9858
9859   // If "eval" didn't refer to the original GlobalEval, it's not a
9860   // direct call to eval.
9861   // (And even if it is, but the first argument isn't a string, just let
9862   // execution default to an indirect call to eval, which will also return
9863   // the first argument without doing anything).
9864   if (*callee != isolate->native_context()->global_eval_fun() ||
9865       !args[1]->IsString()) {
9866     return MakePair(*callee, isolate->heap()->undefined_value());
9867   }
9868
9869   DCHECK(args[3]->IsSmi());
9870   DCHECK(args.smi_at(3) == SLOPPY || args.smi_at(3) == STRICT);
9871   StrictMode strict_mode = static_cast<StrictMode>(args.smi_at(3));
9872   DCHECK(args[4]->IsSmi());
9873   return CompileGlobalEval(isolate,
9874                            args.at<String>(1),
9875                            args.at<Object>(2),
9876                            strict_mode,
9877                            args.smi_at(4));
9878 }
9879
9880
9881 RUNTIME_FUNCTION(Runtime_AllocateInNewSpace) {
9882   HandleScope scope(isolate);
9883   DCHECK(args.length() == 1);
9884   CONVERT_SMI_ARG_CHECKED(size, 0);
9885   RUNTIME_ASSERT(IsAligned(size, kPointerSize));
9886   RUNTIME_ASSERT(size > 0);
9887   RUNTIME_ASSERT(size <= Page::kMaxRegularHeapObjectSize);
9888   return *isolate->factory()->NewFillerObject(size, false, NEW_SPACE);
9889 }
9890
9891
9892 RUNTIME_FUNCTION(Runtime_AllocateInTargetSpace) {
9893   HandleScope scope(isolate);
9894   DCHECK(args.length() == 2);
9895   CONVERT_SMI_ARG_CHECKED(size, 0);
9896   CONVERT_SMI_ARG_CHECKED(flags, 1);
9897   RUNTIME_ASSERT(IsAligned(size, kPointerSize));
9898   RUNTIME_ASSERT(size > 0);
9899   RUNTIME_ASSERT(size <= Page::kMaxRegularHeapObjectSize);
9900   bool double_align = AllocateDoubleAlignFlag::decode(flags);
9901   AllocationSpace space = AllocateTargetSpace::decode(flags);
9902   return *isolate->factory()->NewFillerObject(size, double_align, space);
9903 }
9904
9905
9906 // Push an object unto an array of objects if it is not already in the
9907 // array.  Returns true if the element was pushed on the stack and
9908 // false otherwise.
9909 RUNTIME_FUNCTION(Runtime_PushIfAbsent) {
9910   HandleScope scope(isolate);
9911   DCHECK(args.length() == 2);
9912   CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
9913   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, element, 1);
9914   RUNTIME_ASSERT(array->HasFastSmiOrObjectElements());
9915   int length = Smi::cast(array->length())->value();
9916   FixedArray* elements = FixedArray::cast(array->elements());
9917   for (int i = 0; i < length; i++) {
9918     if (elements->get(i) == *element) return isolate->heap()->false_value();
9919   }
9920
9921   // Strict not needed. Used for cycle detection in Array join implementation.
9922   RETURN_FAILURE_ON_EXCEPTION(
9923       isolate,
9924       JSObject::SetFastElement(array, length, element, SLOPPY, true));
9925   return isolate->heap()->true_value();
9926 }
9927
9928
9929 /**
9930  * A simple visitor visits every element of Array's.
9931  * The backend storage can be a fixed array for fast elements case,
9932  * or a dictionary for sparse array. Since Dictionary is a subtype
9933  * of FixedArray, the class can be used by both fast and slow cases.
9934  * The second parameter of the constructor, fast_elements, specifies
9935  * whether the storage is a FixedArray or Dictionary.
9936  *
9937  * An index limit is used to deal with the situation that a result array
9938  * length overflows 32-bit non-negative integer.
9939  */
9940 class ArrayConcatVisitor {
9941  public:
9942   ArrayConcatVisitor(Isolate* isolate,
9943                      Handle<FixedArray> storage,
9944                      bool fast_elements) :
9945       isolate_(isolate),
9946       storage_(Handle<FixedArray>::cast(
9947           isolate->global_handles()->Create(*storage))),
9948       index_offset_(0u),
9949       fast_elements_(fast_elements),
9950       exceeds_array_limit_(false) { }
9951
9952   ~ArrayConcatVisitor() {
9953     clear_storage();
9954   }
9955
9956   void visit(uint32_t i, Handle<Object> elm) {
9957     if (i > JSObject::kMaxElementCount - index_offset_) {
9958       exceeds_array_limit_ = true;
9959       return;
9960     }
9961     uint32_t index = index_offset_ + i;
9962
9963     if (fast_elements_) {
9964       if (index < static_cast<uint32_t>(storage_->length())) {
9965         storage_->set(index, *elm);
9966         return;
9967       }
9968       // Our initial estimate of length was foiled, possibly by
9969       // getters on the arrays increasing the length of later arrays
9970       // during iteration.
9971       // This shouldn't happen in anything but pathological cases.
9972       SetDictionaryMode();
9973       // Fall-through to dictionary mode.
9974     }
9975     DCHECK(!fast_elements_);
9976     Handle<SeededNumberDictionary> dict(
9977         SeededNumberDictionary::cast(*storage_));
9978     Handle<SeededNumberDictionary> result =
9979         SeededNumberDictionary::AtNumberPut(dict, index, elm);
9980     if (!result.is_identical_to(dict)) {
9981       // Dictionary needed to grow.
9982       clear_storage();
9983       set_storage(*result);
9984     }
9985   }
9986
9987   void increase_index_offset(uint32_t delta) {
9988     if (JSObject::kMaxElementCount - index_offset_ < delta) {
9989       index_offset_ = JSObject::kMaxElementCount;
9990     } else {
9991       index_offset_ += delta;
9992     }
9993     // If the initial length estimate was off (see special case in visit()),
9994     // but the array blowing the limit didn't contain elements beyond the
9995     // provided-for index range, go to dictionary mode now.
9996     if (fast_elements_ &&
9997         index_offset_ >
9998             static_cast<uint32_t>(FixedArrayBase::cast(*storage_)->length())) {
9999       SetDictionaryMode();
10000     }
10001   }
10002
10003   bool exceeds_array_limit() {
10004     return exceeds_array_limit_;
10005   }
10006
10007   Handle<JSArray> ToArray() {
10008     Handle<JSArray> array = isolate_->factory()->NewJSArray(0);
10009     Handle<Object> length =
10010         isolate_->factory()->NewNumber(static_cast<double>(index_offset_));
10011     Handle<Map> map = JSObject::GetElementsTransitionMap(
10012         array,
10013         fast_elements_ ? FAST_HOLEY_ELEMENTS : DICTIONARY_ELEMENTS);
10014     array->set_map(*map);
10015     array->set_length(*length);
10016     array->set_elements(*storage_);
10017     return array;
10018   }
10019
10020  private:
10021   // Convert storage to dictionary mode.
10022   void SetDictionaryMode() {
10023     DCHECK(fast_elements_);
10024     Handle<FixedArray> current_storage(*storage_);
10025     Handle<SeededNumberDictionary> slow_storage(
10026         SeededNumberDictionary::New(isolate_, current_storage->length()));
10027     uint32_t current_length = static_cast<uint32_t>(current_storage->length());
10028     for (uint32_t i = 0; i < current_length; i++) {
10029       HandleScope loop_scope(isolate_);
10030       Handle<Object> element(current_storage->get(i), isolate_);
10031       if (!element->IsTheHole()) {
10032         Handle<SeededNumberDictionary> new_storage =
10033             SeededNumberDictionary::AtNumberPut(slow_storage, i, element);
10034         if (!new_storage.is_identical_to(slow_storage)) {
10035           slow_storage = loop_scope.CloseAndEscape(new_storage);
10036         }
10037       }
10038     }
10039     clear_storage();
10040     set_storage(*slow_storage);
10041     fast_elements_ = false;
10042   }
10043
10044   inline void clear_storage() {
10045     GlobalHandles::Destroy(Handle<Object>::cast(storage_).location());
10046   }
10047
10048   inline void set_storage(FixedArray* storage) {
10049     storage_ = Handle<FixedArray>::cast(
10050         isolate_->global_handles()->Create(storage));
10051   }
10052
10053   Isolate* isolate_;
10054   Handle<FixedArray> storage_;  // Always a global handle.
10055   // Index after last seen index. Always less than or equal to
10056   // JSObject::kMaxElementCount.
10057   uint32_t index_offset_;
10058   bool fast_elements_ : 1;
10059   bool exceeds_array_limit_ : 1;
10060 };
10061
10062
10063 static uint32_t EstimateElementCount(Handle<JSArray> array) {
10064   uint32_t length = static_cast<uint32_t>(array->length()->Number());
10065   int element_count = 0;
10066   switch (array->GetElementsKind()) {
10067     case FAST_SMI_ELEMENTS:
10068     case FAST_HOLEY_SMI_ELEMENTS:
10069     case FAST_ELEMENTS:
10070     case FAST_HOLEY_ELEMENTS: {
10071       // Fast elements can't have lengths that are not representable by
10072       // a 32-bit signed integer.
10073       DCHECK(static_cast<int32_t>(FixedArray::kMaxLength) >= 0);
10074       int fast_length = static_cast<int>(length);
10075       Handle<FixedArray> elements(FixedArray::cast(array->elements()));
10076       for (int i = 0; i < fast_length; i++) {
10077         if (!elements->get(i)->IsTheHole()) element_count++;
10078       }
10079       break;
10080     }
10081     case FAST_DOUBLE_ELEMENTS:
10082     case FAST_HOLEY_DOUBLE_ELEMENTS: {
10083       // Fast elements can't have lengths that are not representable by
10084       // a 32-bit signed integer.
10085       DCHECK(static_cast<int32_t>(FixedDoubleArray::kMaxLength) >= 0);
10086       int fast_length = static_cast<int>(length);
10087       if (array->elements()->IsFixedArray()) {
10088         DCHECK(FixedArray::cast(array->elements())->length() == 0);
10089         break;
10090       }
10091       Handle<FixedDoubleArray> elements(
10092           FixedDoubleArray::cast(array->elements()));
10093       for (int i = 0; i < fast_length; i++) {
10094         if (!elements->is_the_hole(i)) element_count++;
10095       }
10096       break;
10097     }
10098     case DICTIONARY_ELEMENTS: {
10099       Handle<SeededNumberDictionary> dictionary(
10100           SeededNumberDictionary::cast(array->elements()));
10101       int capacity = dictionary->Capacity();
10102       for (int i = 0; i < capacity; i++) {
10103         Handle<Object> key(dictionary->KeyAt(i), array->GetIsolate());
10104         if (dictionary->IsKey(*key)) {
10105           element_count++;
10106         }
10107       }
10108       break;
10109     }
10110     case SLOPPY_ARGUMENTS_ELEMENTS:
10111 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size)                      \
10112     case EXTERNAL_##TYPE##_ELEMENTS:                                         \
10113     case TYPE##_ELEMENTS:                                                    \
10114
10115     TYPED_ARRAYS(TYPED_ARRAY_CASE)
10116 #undef TYPED_ARRAY_CASE
10117       // External arrays are always dense.
10118       return length;
10119   }
10120   // As an estimate, we assume that the prototype doesn't contain any
10121   // inherited elements.
10122   return element_count;
10123 }
10124
10125
10126
10127 template<class ExternalArrayClass, class ElementType>
10128 static void IterateExternalArrayElements(Isolate* isolate,
10129                                          Handle<JSObject> receiver,
10130                                          bool elements_are_ints,
10131                                          bool elements_are_guaranteed_smis,
10132                                          ArrayConcatVisitor* visitor) {
10133   Handle<ExternalArrayClass> array(
10134       ExternalArrayClass::cast(receiver->elements()));
10135   uint32_t len = static_cast<uint32_t>(array->length());
10136
10137   DCHECK(visitor != NULL);
10138   if (elements_are_ints) {
10139     if (elements_are_guaranteed_smis) {
10140       for (uint32_t j = 0; j < len; j++) {
10141         HandleScope loop_scope(isolate);
10142         Handle<Smi> e(Smi::FromInt(static_cast<int>(array->get_scalar(j))),
10143                       isolate);
10144         visitor->visit(j, e);
10145       }
10146     } else {
10147       for (uint32_t j = 0; j < len; j++) {
10148         HandleScope loop_scope(isolate);
10149         int64_t val = static_cast<int64_t>(array->get_scalar(j));
10150         if (Smi::IsValid(static_cast<intptr_t>(val))) {
10151           Handle<Smi> e(Smi::FromInt(static_cast<int>(val)), isolate);
10152           visitor->visit(j, e);
10153         } else {
10154           Handle<Object> e =
10155               isolate->factory()->NewNumber(static_cast<ElementType>(val));
10156           visitor->visit(j, e);
10157         }
10158       }
10159     }
10160   } else {
10161     for (uint32_t j = 0; j < len; j++) {
10162       HandleScope loop_scope(isolate);
10163       Handle<Object> e = isolate->factory()->NewNumber(array->get_scalar(j));
10164       visitor->visit(j, e);
10165     }
10166   }
10167 }
10168
10169
10170 static void IterateExternalFloat32x4ArrayElements(Isolate* isolate,
10171                                                   Handle<JSObject> receiver,
10172                                                   ArrayConcatVisitor* visitor) {
10173   Handle<ExternalFloat32x4Array> array(
10174       ExternalFloat32x4Array::cast(receiver->elements()));
10175   uint32_t len = static_cast<uint32_t>(array->length());
10176
10177   DCHECK(visitor != NULL);
10178   for (uint32_t j = 0; j < len; j++) {
10179     HandleScope loop_scope(isolate);
10180     Handle<Object> e = isolate->factory()->NewFloat32x4(array->get_scalar(j));
10181     visitor->visit(j, e);
10182   }
10183 }
10184
10185
10186 static void IterateExternalFloat64x2ArrayElements(Isolate* isolate,
10187                                                   Handle<JSObject> receiver,
10188                                                   ArrayConcatVisitor* visitor) {
10189   Handle<ExternalFloat64x2Array> array(
10190       ExternalFloat64x2Array::cast(receiver->elements()));
10191   uint32_t len = static_cast<uint32_t>(array->length());
10192
10193   DCHECK(visitor != NULL);
10194   for (uint32_t j = 0; j < len; j++) {
10195     HandleScope loop_scope(isolate);
10196     Handle<Object> e = isolate->factory()->NewFloat64x2(array->get_scalar(j));
10197     visitor->visit(j, e);
10198   }
10199 }
10200
10201
10202 static void IterateExternalInt32x4ArrayElements(Isolate* isolate,
10203                                                  Handle<JSObject> receiver,
10204                                                  ArrayConcatVisitor* visitor) {
10205   Handle<ExternalInt32x4Array> array(
10206       ExternalInt32x4Array::cast(receiver->elements()));
10207   uint32_t len = static_cast<uint32_t>(array->length());
10208
10209   DCHECK(visitor != NULL);
10210   for (uint32_t j = 0; j < len; j++) {
10211     HandleScope loop_scope(isolate);
10212     Handle<Object> e = isolate->factory()->NewInt32x4(array->get_scalar(j));
10213     visitor->visit(j, e);
10214   }
10215 }
10216
10217
10218 // Used for sorting indices in a List<uint32_t>.
10219 static int compareUInt32(const uint32_t* ap, const uint32_t* bp) {
10220   uint32_t a = *ap;
10221   uint32_t b = *bp;
10222   return (a == b) ? 0 : (a < b) ? -1 : 1;
10223 }
10224
10225
10226 static void CollectElementIndices(Handle<JSObject> object,
10227                                   uint32_t range,
10228                                   List<uint32_t>* indices) {
10229   Isolate* isolate = object->GetIsolate();
10230   ElementsKind kind = object->GetElementsKind();
10231   switch (kind) {
10232     case FAST_SMI_ELEMENTS:
10233     case FAST_ELEMENTS:
10234     case FAST_HOLEY_SMI_ELEMENTS:
10235     case FAST_HOLEY_ELEMENTS: {
10236       Handle<FixedArray> elements(FixedArray::cast(object->elements()));
10237       uint32_t length = static_cast<uint32_t>(elements->length());
10238       if (range < length) length = range;
10239       for (uint32_t i = 0; i < length; i++) {
10240         if (!elements->get(i)->IsTheHole()) {
10241           indices->Add(i);
10242         }
10243       }
10244       break;
10245     }
10246     case FAST_HOLEY_DOUBLE_ELEMENTS:
10247     case FAST_DOUBLE_ELEMENTS: {
10248       // TODO(1810): Decide if it's worthwhile to implement this.
10249       UNREACHABLE();
10250       break;
10251     }
10252     case DICTIONARY_ELEMENTS: {
10253       Handle<SeededNumberDictionary> dict(
10254           SeededNumberDictionary::cast(object->elements()));
10255       uint32_t capacity = dict->Capacity();
10256       for (uint32_t j = 0; j < capacity; j++) {
10257         HandleScope loop_scope(isolate);
10258         Handle<Object> k(dict->KeyAt(j), isolate);
10259         if (dict->IsKey(*k)) {
10260           DCHECK(k->IsNumber());
10261           uint32_t index = static_cast<uint32_t>(k->Number());
10262           if (index < range) {
10263             indices->Add(index);
10264           }
10265         }
10266       }
10267       break;
10268     }
10269     default: {
10270       int dense_elements_length;
10271       switch (kind) {
10272 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size)                        \
10273         case EXTERNAL_##TYPE##_ELEMENTS: {                                     \
10274           dense_elements_length =                                              \
10275               External##Type##Array::cast(object->elements())->length();       \
10276           break;                                                               \
10277         }
10278
10279         TYPED_ARRAYS(TYPED_ARRAY_CASE)
10280 #undef TYPED_ARRAY_CASE
10281
10282         default:
10283           UNREACHABLE();
10284           dense_elements_length = 0;
10285           break;
10286       }
10287       uint32_t length = static_cast<uint32_t>(dense_elements_length);
10288       if (range <= length) {
10289         length = range;
10290         // We will add all indices, so we might as well clear it first
10291         // and avoid duplicates.
10292         indices->Clear();
10293       }
10294       for (uint32_t i = 0; i < length; i++) {
10295         indices->Add(i);
10296       }
10297       if (length == range) return;  // All indices accounted for already.
10298       break;
10299     }
10300   }
10301
10302   PrototypeIterator iter(isolate, object);
10303   if (!iter.IsAtEnd()) {
10304     // The prototype will usually have no inherited element indices,
10305     // but we have to check.
10306     CollectElementIndices(
10307         Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), range,
10308         indices);
10309   }
10310 }
10311
10312
10313 /**
10314  * A helper function that visits elements of a JSArray in numerical
10315  * order.
10316  *
10317  * The visitor argument called for each existing element in the array
10318  * with the element index and the element's value.
10319  * Afterwards it increments the base-index of the visitor by the array
10320  * length.
10321  * Returns false if any access threw an exception, otherwise true.
10322  */
10323 static bool IterateElements(Isolate* isolate,
10324                             Handle<JSArray> receiver,
10325                             ArrayConcatVisitor* visitor) {
10326   uint32_t length = static_cast<uint32_t>(receiver->length()->Number());
10327   switch (receiver->GetElementsKind()) {
10328     case FAST_SMI_ELEMENTS:
10329     case FAST_ELEMENTS:
10330     case FAST_HOLEY_SMI_ELEMENTS:
10331     case FAST_HOLEY_ELEMENTS: {
10332       // Run through the elements FixedArray and use HasElement and GetElement
10333       // to check the prototype for missing elements.
10334       Handle<FixedArray> elements(FixedArray::cast(receiver->elements()));
10335       int fast_length = static_cast<int>(length);
10336       DCHECK(fast_length <= elements->length());
10337       for (int j = 0; j < fast_length; j++) {
10338         HandleScope loop_scope(isolate);
10339         Handle<Object> element_value(elements->get(j), isolate);
10340         if (!element_value->IsTheHole()) {
10341           visitor->visit(j, element_value);
10342         } else {
10343           Maybe<bool> maybe = JSReceiver::HasElement(receiver, j);
10344           if (!maybe.has_value) return false;
10345           if (maybe.value) {
10346             // Call GetElement on receiver, not its prototype, or getters won't
10347             // have the correct receiver.
10348             ASSIGN_RETURN_ON_EXCEPTION_VALUE(
10349                 isolate, element_value,
10350                 Object::GetElement(isolate, receiver, j), false);
10351             visitor->visit(j, element_value);
10352           }
10353         }
10354       }
10355       break;
10356     }
10357     case FAST_HOLEY_DOUBLE_ELEMENTS:
10358     case FAST_DOUBLE_ELEMENTS: {
10359       // Empty array is FixedArray but not FixedDoubleArray.
10360       if (length == 0) break;
10361       // Run through the elements FixedArray and use HasElement and GetElement
10362       // to check the prototype for missing elements.
10363       if (receiver->elements()->IsFixedArray()) {
10364         DCHECK(receiver->elements()->length() == 0);
10365         break;
10366       }
10367       Handle<FixedDoubleArray> elements(
10368           FixedDoubleArray::cast(receiver->elements()));
10369       int fast_length = static_cast<int>(length);
10370       DCHECK(fast_length <= elements->length());
10371       for (int j = 0; j < fast_length; j++) {
10372         HandleScope loop_scope(isolate);
10373         if (!elements->is_the_hole(j)) {
10374           double double_value = elements->get_scalar(j);
10375           Handle<Object> element_value =
10376               isolate->factory()->NewNumber(double_value);
10377           visitor->visit(j, element_value);
10378         } else {
10379           Maybe<bool> maybe = JSReceiver::HasElement(receiver, j);
10380           if (!maybe.has_value) return false;
10381           if (maybe.value) {
10382             // Call GetElement on receiver, not its prototype, or getters won't
10383             // have the correct receiver.
10384             Handle<Object> element_value;
10385             ASSIGN_RETURN_ON_EXCEPTION_VALUE(
10386                 isolate, element_value,
10387                 Object::GetElement(isolate, receiver, j), false);
10388             visitor->visit(j, element_value);
10389           }
10390         }
10391       }
10392       break;
10393     }
10394     case DICTIONARY_ELEMENTS: {
10395       Handle<SeededNumberDictionary> dict(receiver->element_dictionary());
10396       List<uint32_t> indices(dict->Capacity() / 2);
10397       // Collect all indices in the object and the prototypes less
10398       // than length. This might introduce duplicates in the indices list.
10399       CollectElementIndices(receiver, length, &indices);
10400       indices.Sort(&compareUInt32);
10401       int j = 0;
10402       int n = indices.length();
10403       while (j < n) {
10404         HandleScope loop_scope(isolate);
10405         uint32_t index = indices[j];
10406         Handle<Object> element;
10407         ASSIGN_RETURN_ON_EXCEPTION_VALUE(
10408             isolate, element,
10409             Object::GetElement(isolate, receiver, index),
10410             false);
10411         visitor->visit(index, element);
10412         // Skip to next different index (i.e., omit duplicates).
10413         do {
10414           j++;
10415         } while (j < n && indices[j] == index);
10416       }
10417       break;
10418     }
10419     case EXTERNAL_UINT8_CLAMPED_ELEMENTS: {
10420       Handle<ExternalUint8ClampedArray> pixels(ExternalUint8ClampedArray::cast(
10421           receiver->elements()));
10422       for (uint32_t j = 0; j < length; j++) {
10423         Handle<Smi> e(Smi::FromInt(pixels->get_scalar(j)), isolate);
10424         visitor->visit(j, e);
10425       }
10426       break;
10427     }
10428     case EXTERNAL_INT8_ELEMENTS: {
10429       IterateExternalArrayElements<ExternalInt8Array, int8_t>(
10430           isolate, receiver, true, true, visitor);
10431       break;
10432     }
10433     case EXTERNAL_UINT8_ELEMENTS: {
10434       IterateExternalArrayElements<ExternalUint8Array, uint8_t>(
10435           isolate, receiver, true, true, visitor);
10436       break;
10437     }
10438     case EXTERNAL_INT16_ELEMENTS: {
10439       IterateExternalArrayElements<ExternalInt16Array, int16_t>(
10440           isolate, receiver, true, true, visitor);
10441       break;
10442     }
10443     case EXTERNAL_UINT16_ELEMENTS: {
10444       IterateExternalArrayElements<ExternalUint16Array, uint16_t>(
10445           isolate, receiver, true, true, visitor);
10446       break;
10447     }
10448     case EXTERNAL_INT32_ELEMENTS: {
10449       IterateExternalArrayElements<ExternalInt32Array, int32_t>(
10450           isolate, receiver, true, false, visitor);
10451       break;
10452     }
10453     case EXTERNAL_UINT32_ELEMENTS: {
10454       IterateExternalArrayElements<ExternalUint32Array, uint32_t>(
10455           isolate, receiver, true, false, visitor);
10456       break;
10457     }
10458     case EXTERNAL_FLOAT32_ELEMENTS: {
10459       IterateExternalArrayElements<ExternalFloat32Array, float>(
10460           isolate, receiver, false, false, visitor);
10461       break;
10462     }
10463     case EXTERNAL_FLOAT32x4_ELEMENTS: {
10464       IterateExternalFloat32x4ArrayElements(isolate, receiver, visitor);
10465       break;
10466     }
10467     case EXTERNAL_FLOAT64x2_ELEMENTS: {
10468       IterateExternalFloat64x2ArrayElements(isolate, receiver, visitor);
10469       break;
10470     }
10471     case EXTERNAL_INT32x4_ELEMENTS: {
10472       IterateExternalInt32x4ArrayElements(isolate, receiver, visitor);
10473       break;
10474     }
10475     case EXTERNAL_FLOAT64_ELEMENTS: {
10476       IterateExternalArrayElements<ExternalFloat64Array, double>(
10477           isolate, receiver, false, false, visitor);
10478       break;
10479     }
10480     default:
10481       UNREACHABLE();
10482       break;
10483   }
10484   visitor->increase_index_offset(length);
10485   return true;
10486 }
10487
10488
10489 /**
10490  * Array::concat implementation.
10491  * See ECMAScript 262, 15.4.4.4.
10492  * TODO(581): Fix non-compliance for very large concatenations and update to
10493  * following the ECMAScript 5 specification.
10494  */
10495 RUNTIME_FUNCTION(Runtime_ArrayConcat) {
10496   HandleScope handle_scope(isolate);
10497   DCHECK(args.length() == 1);
10498
10499   CONVERT_ARG_HANDLE_CHECKED(JSArray, arguments, 0);
10500   int argument_count = static_cast<int>(arguments->length()->Number());
10501   RUNTIME_ASSERT(arguments->HasFastObjectElements());
10502   Handle<FixedArray> elements(FixedArray::cast(arguments->elements()));
10503
10504   // Pass 1: estimate the length and number of elements of the result.
10505   // The actual length can be larger if any of the arguments have getters
10506   // that mutate other arguments (but will otherwise be precise).
10507   // The number of elements is precise if there are no inherited elements.
10508
10509   ElementsKind kind = FAST_SMI_ELEMENTS;
10510
10511   uint32_t estimate_result_length = 0;
10512   uint32_t estimate_nof_elements = 0;
10513   for (int i = 0; i < argument_count; i++) {
10514     HandleScope loop_scope(isolate);
10515     Handle<Object> obj(elements->get(i), isolate);
10516     uint32_t length_estimate;
10517     uint32_t element_estimate;
10518     if (obj->IsJSArray()) {
10519       Handle<JSArray> array(Handle<JSArray>::cast(obj));
10520       length_estimate = static_cast<uint32_t>(array->length()->Number());
10521       if (length_estimate != 0) {
10522         ElementsKind array_kind =
10523             GetPackedElementsKind(array->map()->elements_kind());
10524         if (IsMoreGeneralElementsKindTransition(kind, array_kind)) {
10525           kind = array_kind;
10526         }
10527       }
10528       element_estimate = EstimateElementCount(array);
10529     } else {
10530       if (obj->IsHeapObject()) {
10531         if (obj->IsNumber()) {
10532           if (IsMoreGeneralElementsKindTransition(kind, FAST_DOUBLE_ELEMENTS)) {
10533             kind = FAST_DOUBLE_ELEMENTS;
10534           }
10535         } else if (IsMoreGeneralElementsKindTransition(kind, FAST_ELEMENTS)) {
10536           kind = FAST_ELEMENTS;
10537         }
10538       }
10539       length_estimate = 1;
10540       element_estimate = 1;
10541     }
10542     // Avoid overflows by capping at kMaxElementCount.
10543     if (JSObject::kMaxElementCount - estimate_result_length <
10544         length_estimate) {
10545       estimate_result_length = JSObject::kMaxElementCount;
10546     } else {
10547       estimate_result_length += length_estimate;
10548     }
10549     if (JSObject::kMaxElementCount - estimate_nof_elements <
10550         element_estimate) {
10551       estimate_nof_elements = JSObject::kMaxElementCount;
10552     } else {
10553       estimate_nof_elements += element_estimate;
10554     }
10555   }
10556
10557   // If estimated number of elements is more than half of length, a
10558   // fixed array (fast case) is more time and space-efficient than a
10559   // dictionary.
10560   bool fast_case = (estimate_nof_elements * 2) >= estimate_result_length;
10561
10562   if (fast_case && kind == FAST_DOUBLE_ELEMENTS) {
10563     Handle<FixedArrayBase> storage =
10564         isolate->factory()->NewFixedDoubleArray(estimate_result_length);
10565     int j = 0;
10566     bool failure = false;
10567     if (estimate_result_length > 0) {
10568       Handle<FixedDoubleArray> double_storage =
10569           Handle<FixedDoubleArray>::cast(storage);
10570       for (int i = 0; i < argument_count; i++) {
10571         Handle<Object> obj(elements->get(i), isolate);
10572         if (obj->IsSmi()) {
10573           double_storage->set(j, Smi::cast(*obj)->value());
10574           j++;
10575         } else if (obj->IsNumber()) {
10576           double_storage->set(j, obj->Number());
10577           j++;
10578         } else {
10579           JSArray* array = JSArray::cast(*obj);
10580           uint32_t length = static_cast<uint32_t>(array->length()->Number());
10581           switch (array->map()->elements_kind()) {
10582             case FAST_HOLEY_DOUBLE_ELEMENTS:
10583             case FAST_DOUBLE_ELEMENTS: {
10584               // Empty array is FixedArray but not FixedDoubleArray.
10585               if (length == 0) break;
10586               FixedDoubleArray* elements =
10587                   FixedDoubleArray::cast(array->elements());
10588               for (uint32_t i = 0; i < length; i++) {
10589                 if (elements->is_the_hole(i)) {
10590                   // TODO(jkummerow/verwaest): We could be a bit more clever
10591                   // here: Check if there are no elements/getters on the
10592                   // prototype chain, and if so, allow creation of a holey
10593                   // result array.
10594                   // Same thing below (holey smi case).
10595                   failure = true;
10596                   break;
10597                 }
10598                 double double_value = elements->get_scalar(i);
10599                 double_storage->set(j, double_value);
10600                 j++;
10601               }
10602               break;
10603             }
10604             case FAST_HOLEY_SMI_ELEMENTS:
10605             case FAST_SMI_ELEMENTS: {
10606               FixedArray* elements(
10607                   FixedArray::cast(array->elements()));
10608               for (uint32_t i = 0; i < length; i++) {
10609                 Object* element = elements->get(i);
10610                 if (element->IsTheHole()) {
10611                   failure = true;
10612                   break;
10613                 }
10614                 int32_t int_value = Smi::cast(element)->value();
10615                 double_storage->set(j, int_value);
10616                 j++;
10617               }
10618               break;
10619             }
10620             case FAST_HOLEY_ELEMENTS:
10621             case FAST_ELEMENTS:
10622               DCHECK_EQ(0, length);
10623               break;
10624             default:
10625               UNREACHABLE();
10626           }
10627         }
10628         if (failure) break;
10629       }
10630     }
10631     if (!failure) {
10632       Handle<JSArray> array = isolate->factory()->NewJSArray(0);
10633       Smi* length = Smi::FromInt(j);
10634       Handle<Map> map;
10635       map = JSObject::GetElementsTransitionMap(array, kind);
10636       array->set_map(*map);
10637       array->set_length(length);
10638       array->set_elements(*storage);
10639       return *array;
10640     }
10641     // In case of failure, fall through.
10642   }
10643
10644   Handle<FixedArray> storage;
10645   if (fast_case) {
10646     // The backing storage array must have non-existing elements to preserve
10647     // holes across concat operations.
10648     storage = isolate->factory()->NewFixedArrayWithHoles(
10649         estimate_result_length);
10650   } else {
10651     // TODO(126): move 25% pre-allocation logic into Dictionary::Allocate
10652     uint32_t at_least_space_for = estimate_nof_elements +
10653                                   (estimate_nof_elements >> 2);
10654     storage = Handle<FixedArray>::cast(
10655         SeededNumberDictionary::New(isolate, at_least_space_for));
10656   }
10657
10658   ArrayConcatVisitor visitor(isolate, storage, fast_case);
10659
10660   for (int i = 0; i < argument_count; i++) {
10661     Handle<Object> obj(elements->get(i), isolate);
10662     if (obj->IsJSArray()) {
10663       Handle<JSArray> array = Handle<JSArray>::cast(obj);
10664       if (!IterateElements(isolate, array, &visitor)) {
10665         return isolate->heap()->exception();
10666       }
10667     } else {
10668       visitor.visit(0, obj);
10669       visitor.increase_index_offset(1);
10670     }
10671   }
10672
10673   if (visitor.exceeds_array_limit()) {
10674     return isolate->Throw(
10675         *isolate->factory()->NewRangeError("invalid_array_length",
10676                                            HandleVector<Object>(NULL, 0)));
10677   }
10678   return *visitor.ToArray();
10679 }
10680
10681
10682 // This will not allocate (flatten the string), but it may run
10683 // very slowly for very deeply nested ConsStrings.  For debugging use only.
10684 RUNTIME_FUNCTION(Runtime_GlobalPrint) {
10685   SealHandleScope shs(isolate);
10686   DCHECK(args.length() == 1);
10687
10688   CONVERT_ARG_CHECKED(String, string, 0);
10689   ConsStringIteratorOp op;
10690   StringCharacterStream stream(string, &op);
10691   while (stream.HasMore()) {
10692     uint16_t character = stream.GetNext();
10693     PrintF("%c", character);
10694   }
10695   return string;
10696 }
10697
10698
10699 // Moves all own elements of an object, that are below a limit, to positions
10700 // starting at zero. All undefined values are placed after non-undefined values,
10701 // and are followed by non-existing element. Does not change the length
10702 // property.
10703 // Returns the number of non-undefined elements collected.
10704 // Returns -1 if hole removal is not supported by this method.
10705 RUNTIME_FUNCTION(Runtime_RemoveArrayHoles) {
10706   HandleScope scope(isolate);
10707   DCHECK(args.length() == 2);
10708   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
10709   CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]);
10710   return *JSObject::PrepareElementsForSort(object, limit);
10711 }
10712
10713
10714 // Move contents of argument 0 (an array) to argument 1 (an array)
10715 RUNTIME_FUNCTION(Runtime_MoveArrayContents) {
10716   HandleScope scope(isolate);
10717   DCHECK(args.length() == 2);
10718   CONVERT_ARG_HANDLE_CHECKED(JSArray, from, 0);
10719   CONVERT_ARG_HANDLE_CHECKED(JSArray, to, 1);
10720   JSObject::ValidateElements(from);
10721   JSObject::ValidateElements(to);
10722
10723   Handle<FixedArrayBase> new_elements(from->elements());
10724   ElementsKind from_kind = from->GetElementsKind();
10725   Handle<Map> new_map = JSObject::GetElementsTransitionMap(to, from_kind);
10726   JSObject::SetMapAndElements(to, new_map, new_elements);
10727   to->set_length(from->length());
10728
10729   JSObject::ResetElements(from);
10730   from->set_length(Smi::FromInt(0));
10731
10732   JSObject::ValidateElements(to);
10733   return *to;
10734 }
10735
10736
10737 // How many elements does this object/array have?
10738 RUNTIME_FUNCTION(Runtime_EstimateNumberOfElements) {
10739   HandleScope scope(isolate);
10740   DCHECK(args.length() == 1);
10741   CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
10742   Handle<FixedArrayBase> elements(array->elements(), isolate);
10743   SealHandleScope shs(isolate);
10744   if (elements->IsDictionary()) {
10745     int result =
10746         Handle<SeededNumberDictionary>::cast(elements)->NumberOfElements();
10747     return Smi::FromInt(result);
10748   } else {
10749     DCHECK(array->length()->IsSmi());
10750     // For packed elements, we know the exact number of elements
10751     int length = elements->length();
10752     ElementsKind kind = array->GetElementsKind();
10753     if (IsFastPackedElementsKind(kind)) {
10754       return Smi::FromInt(length);
10755     }
10756     // For holey elements, take samples from the buffer checking for holes
10757     // to generate the estimate.
10758     const int kNumberOfHoleCheckSamples = 97;
10759     int increment = (length < kNumberOfHoleCheckSamples)
10760                         ? 1
10761                         : static_cast<int>(length / kNumberOfHoleCheckSamples);
10762     ElementsAccessor* accessor = array->GetElementsAccessor();
10763     int holes = 0;
10764     for (int i = 0; i < length; i += increment) {
10765       if (!accessor->HasElement(array, array, i, elements)) {
10766         ++holes;
10767       }
10768     }
10769     int estimate = static_cast<int>((kNumberOfHoleCheckSamples - holes) /
10770                                     kNumberOfHoleCheckSamples * length);
10771     return Smi::FromInt(estimate);
10772   }
10773 }
10774
10775
10776 // Returns an array that tells you where in the [0, length) interval an array
10777 // might have elements.  Can either return an array of keys (positive integers
10778 // or undefined) or a number representing the positive length of an interval
10779 // starting at index 0.
10780 // Intervals can span over some keys that are not in the object.
10781 RUNTIME_FUNCTION(Runtime_GetArrayKeys) {
10782   HandleScope scope(isolate);
10783   DCHECK(args.length() == 2);
10784   CONVERT_ARG_HANDLE_CHECKED(JSObject, array, 0);
10785   CONVERT_NUMBER_CHECKED(uint32_t, length, Uint32, args[1]);
10786   if (array->elements()->IsDictionary()) {
10787     Handle<FixedArray> keys = isolate->factory()->empty_fixed_array();
10788     for (PrototypeIterator iter(isolate, array,
10789                                 PrototypeIterator::START_AT_RECEIVER);
10790          !iter.IsAtEnd(); iter.Advance()) {
10791       if (PrototypeIterator::GetCurrent(iter)->IsJSProxy() ||
10792           JSObject::cast(*PrototypeIterator::GetCurrent(iter))
10793               ->HasIndexedInterceptor()) {
10794         // Bail out if we find a proxy or interceptor, likely not worth
10795         // collecting keys in that case.
10796         return *isolate->factory()->NewNumberFromUint(length);
10797       }
10798       Handle<JSObject> current =
10799           Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
10800       Handle<FixedArray> current_keys =
10801           isolate->factory()->NewFixedArray(current->NumberOfOwnElements(NONE));
10802       current->GetOwnElementKeys(*current_keys, NONE);
10803       ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
10804           isolate, keys, FixedArray::UnionOfKeys(keys, current_keys));
10805     }
10806     // Erase any keys >= length.
10807     // TODO(adamk): Remove this step when the contract of %GetArrayKeys
10808     // is changed to let this happen on the JS side.
10809     for (int i = 0; i < keys->length(); i++) {
10810       if (NumberToUint32(keys->get(i)) >= length) keys->set_undefined(i);
10811     }
10812     return *isolate->factory()->NewJSArrayWithElements(keys);
10813   } else {
10814     RUNTIME_ASSERT(array->HasFastSmiOrObjectElements() ||
10815                    array->HasFastDoubleElements());
10816     uint32_t actual_length = static_cast<uint32_t>(array->elements()->length());
10817     return *isolate->factory()->NewNumberFromUint(Min(actual_length, length));
10818   }
10819 }
10820
10821
10822 RUNTIME_FUNCTION(Runtime_LookupAccessor) {
10823   HandleScope scope(isolate);
10824   DCHECK(args.length() == 3);
10825   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
10826   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
10827   CONVERT_SMI_ARG_CHECKED(flag, 2);
10828   AccessorComponent component = flag == 0 ? ACCESSOR_GETTER : ACCESSOR_SETTER;
10829   if (!receiver->IsJSObject()) return isolate->heap()->undefined_value();
10830   Handle<Object> result;
10831   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
10832       isolate, result,
10833       JSObject::GetAccessor(Handle<JSObject>::cast(receiver), name, component));
10834   return *result;
10835 }
10836
10837
10838 RUNTIME_FUNCTION(Runtime_DebugBreak) {
10839   SealHandleScope shs(isolate);
10840   DCHECK(args.length() == 0);
10841   isolate->debug()->HandleDebugBreak();
10842   return isolate->heap()->undefined_value();
10843 }
10844
10845
10846 // Helper functions for wrapping and unwrapping stack frame ids.
10847 static Smi* WrapFrameId(StackFrame::Id id) {
10848   DCHECK(IsAligned(OffsetFrom(id), static_cast<intptr_t>(4)));
10849   return Smi::FromInt(id >> 2);
10850 }
10851
10852
10853 static StackFrame::Id UnwrapFrameId(int wrapped) {
10854   return static_cast<StackFrame::Id>(wrapped << 2);
10855 }
10856
10857
10858 // Adds a JavaScript function as a debug event listener.
10859 // args[0]: debug event listener function to set or null or undefined for
10860 //          clearing the event listener function
10861 // args[1]: object supplied during callback
10862 RUNTIME_FUNCTION(Runtime_SetDebugEventListener) {
10863   SealHandleScope shs(isolate);
10864   DCHECK(args.length() == 2);
10865   RUNTIME_ASSERT(args[0]->IsJSFunction() ||
10866                  args[0]->IsUndefined() ||
10867                  args[0]->IsNull());
10868   CONVERT_ARG_HANDLE_CHECKED(Object, callback, 0);
10869   CONVERT_ARG_HANDLE_CHECKED(Object, data, 1);
10870   isolate->debug()->SetEventListener(callback, data);
10871
10872   return isolate->heap()->undefined_value();
10873 }
10874
10875
10876 RUNTIME_FUNCTION(Runtime_Break) {
10877   SealHandleScope shs(isolate);
10878   DCHECK(args.length() == 0);
10879   isolate->stack_guard()->RequestDebugBreak();
10880   return isolate->heap()->undefined_value();
10881 }
10882
10883
10884 static Handle<Object> DebugLookupResultValue(Isolate* isolate,
10885                                              Handle<Object> receiver,
10886                                              Handle<Name> name,
10887                                              LookupResult* result,
10888                                              bool* has_caught = NULL) {
10889   Handle<Object> value = isolate->factory()->undefined_value();
10890   if  (!result->IsFound()) return value;
10891   switch (result->type()) {
10892     case NORMAL:
10893       return JSObject::GetNormalizedProperty(handle(result->holder(), isolate),
10894                                              result);
10895     case FIELD:
10896       return JSObject::FastPropertyAt(handle(result->holder(), isolate),
10897                                       result->representation(),
10898                                       result->GetFieldIndex());
10899     case CONSTANT:
10900       return handle(result->GetConstant(), isolate);
10901     case CALLBACKS: {
10902       Handle<Object> structure(result->GetCallbackObject(), isolate);
10903       DCHECK(!structure->IsForeign());
10904       if (structure->IsAccessorInfo()) {
10905         MaybeHandle<Object> obj = JSObject::GetPropertyWithAccessor(
10906             receiver, name, handle(result->holder(), isolate), structure);
10907         if (!obj.ToHandle(&value)) {
10908           value = handle(isolate->pending_exception(), isolate);
10909           isolate->clear_pending_exception();
10910           if (has_caught != NULL) *has_caught = true;
10911           return value;
10912         }
10913       }
10914       break;
10915     }
10916     case INTERCEPTOR:
10917     case HANDLER:
10918       break;
10919     case NONEXISTENT:
10920       UNREACHABLE();
10921       break;
10922   }
10923   return value;
10924 }
10925
10926
10927 // Get debugger related details for an object property.
10928 // args[0]: object holding property
10929 // args[1]: name of the property
10930 //
10931 // The array returned contains the following information:
10932 // 0: Property value
10933 // 1: Property details
10934 // 2: Property value is exception
10935 // 3: Getter function if defined
10936 // 4: Setter function if defined
10937 // Items 2-4 are only filled if the property has either a getter or a setter
10938 // defined through __defineGetter__ and/or __defineSetter__.
10939 RUNTIME_FUNCTION(Runtime_DebugGetPropertyDetails) {
10940   HandleScope scope(isolate);
10941
10942   DCHECK(args.length() == 2);
10943
10944   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
10945   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
10946
10947   // Make sure to set the current context to the context before the debugger was
10948   // entered (if the debugger is entered). The reason for switching context here
10949   // is that for some property lookups (accessors and interceptors) callbacks
10950   // into the embedding application can occour, and the embedding application
10951   // could have the assumption that its own native context is the current
10952   // context and not some internal debugger context.
10953   SaveContext save(isolate);
10954   if (isolate->debug()->in_debug_scope()) {
10955     isolate->set_context(*isolate->debug()->debugger_entry()->GetContext());
10956   }
10957
10958   // Check if the name is trivially convertible to an index and get the element
10959   // if so.
10960   uint32_t index;
10961   if (name->AsArrayIndex(&index)) {
10962     Handle<FixedArray> details = isolate->factory()->NewFixedArray(2);
10963     Handle<Object> element_or_char;
10964     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
10965         isolate, element_or_char,
10966         Runtime::GetElementOrCharAt(isolate, obj, index));
10967     details->set(0, *element_or_char);
10968     details->set(
10969         1, PropertyDetails(NONE, NORMAL, Representation::None()).AsSmi());
10970     return *isolate->factory()->NewJSArrayWithElements(details);
10971   }
10972
10973   // Find the number of objects making up this.
10974   int length = OwnPrototypeChainLength(*obj);
10975
10976   // Try own lookup on each of the objects.
10977   PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER);
10978   for (int i = 0; i < length; i++) {
10979     DCHECK(!iter.IsAtEnd());
10980     Handle<JSObject> jsproto =
10981         Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
10982     LookupResult result(isolate);
10983     jsproto->LookupOwn(name, &result);
10984     if (result.IsFound()) {
10985       // LookupResult is not GC safe as it holds raw object pointers.
10986       // GC can happen later in this code so put the required fields into
10987       // local variables using handles when required for later use.
10988       Handle<Object> result_callback_obj;
10989       if (result.IsPropertyCallbacks()) {
10990         result_callback_obj = Handle<Object>(result.GetCallbackObject(),
10991                                              isolate);
10992       }
10993
10994
10995       bool has_caught = false;
10996       Handle<Object> value = DebugLookupResultValue(
10997           isolate, obj, name, &result, &has_caught);
10998
10999       // If the callback object is a fixed array then it contains JavaScript
11000       // getter and/or setter.
11001       bool has_js_accessors = result.IsPropertyCallbacks() &&
11002                               result_callback_obj->IsAccessorPair();
11003       Handle<FixedArray> details =
11004           isolate->factory()->NewFixedArray(has_js_accessors ? 5 : 2);
11005       details->set(0, *value);
11006       details->set(1, result.GetPropertyDetails().AsSmi());
11007       if (has_js_accessors) {
11008         AccessorPair* accessors = AccessorPair::cast(*result_callback_obj);
11009         details->set(2, isolate->heap()->ToBoolean(has_caught));
11010         details->set(3, accessors->GetComponent(ACCESSOR_GETTER));
11011         details->set(4, accessors->GetComponent(ACCESSOR_SETTER));
11012       }
11013
11014       return *isolate->factory()->NewJSArrayWithElements(details);
11015     }
11016     iter.Advance();
11017   }
11018
11019   return isolate->heap()->undefined_value();
11020 }
11021
11022
11023 RUNTIME_FUNCTION(Runtime_DebugGetProperty) {
11024   HandleScope scope(isolate);
11025
11026   DCHECK(args.length() == 2);
11027
11028   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
11029   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
11030
11031   LookupResult result(isolate);
11032   obj->Lookup(name, &result);
11033   return *DebugLookupResultValue(isolate, obj, name, &result);
11034 }
11035
11036
11037 // Return the property type calculated from the property details.
11038 // args[0]: smi with property details.
11039 RUNTIME_FUNCTION(Runtime_DebugPropertyTypeFromDetails) {
11040   SealHandleScope shs(isolate);
11041   DCHECK(args.length() == 1);
11042   CONVERT_PROPERTY_DETAILS_CHECKED(details, 0);
11043   return Smi::FromInt(static_cast<int>(details.type()));
11044 }
11045
11046
11047 // Return the property attribute calculated from the property details.
11048 // args[0]: smi with property details.
11049 RUNTIME_FUNCTION(Runtime_DebugPropertyAttributesFromDetails) {
11050   SealHandleScope shs(isolate);
11051   DCHECK(args.length() == 1);
11052   CONVERT_PROPERTY_DETAILS_CHECKED(details, 0);
11053   return Smi::FromInt(static_cast<int>(details.attributes()));
11054 }
11055
11056
11057 // Return the property insertion index calculated from the property details.
11058 // args[0]: smi with property details.
11059 RUNTIME_FUNCTION(Runtime_DebugPropertyIndexFromDetails) {
11060   SealHandleScope shs(isolate);
11061   DCHECK(args.length() == 1);
11062   CONVERT_PROPERTY_DETAILS_CHECKED(details, 0);
11063   // TODO(verwaest): Depends on the type of details.
11064   return Smi::FromInt(details.dictionary_index());
11065 }
11066
11067
11068 // Return property value from named interceptor.
11069 // args[0]: object
11070 // args[1]: property name
11071 RUNTIME_FUNCTION(Runtime_DebugNamedInterceptorPropertyValue) {
11072   HandleScope scope(isolate);
11073   DCHECK(args.length() == 2);
11074   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
11075   RUNTIME_ASSERT(obj->HasNamedInterceptor());
11076   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
11077
11078   Handle<Object> result;
11079   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
11080       isolate, result, JSObject::GetProperty(obj, name));
11081   return *result;
11082 }
11083
11084
11085 // Return element value from indexed interceptor.
11086 // args[0]: object
11087 // args[1]: index
11088 RUNTIME_FUNCTION(Runtime_DebugIndexedInterceptorElementValue) {
11089   HandleScope scope(isolate);
11090   DCHECK(args.length() == 2);
11091   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
11092   RUNTIME_ASSERT(obj->HasIndexedInterceptor());
11093   CONVERT_NUMBER_CHECKED(uint32_t, index, Uint32, args[1]);
11094   Handle<Object> result;
11095   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
11096       isolate, result, JSObject::GetElementWithInterceptor(obj, obj, index));
11097   return *result;
11098 }
11099
11100
11101 static bool CheckExecutionState(Isolate* isolate, int break_id) {
11102   return !isolate->debug()->debug_context().is_null() &&
11103          isolate->debug()->break_id() != 0 &&
11104          isolate->debug()->break_id() == break_id;
11105 }
11106
11107
11108 RUNTIME_FUNCTION(Runtime_CheckExecutionState) {
11109   SealHandleScope shs(isolate);
11110   DCHECK(args.length() == 1);
11111   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
11112   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
11113   return isolate->heap()->true_value();
11114 }
11115
11116
11117 RUNTIME_FUNCTION(Runtime_GetFrameCount) {
11118   HandleScope scope(isolate);
11119   DCHECK(args.length() == 1);
11120   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
11121   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
11122
11123   // Count all frames which are relevant to debugging stack trace.
11124   int n = 0;
11125   StackFrame::Id id = isolate->debug()->break_frame_id();
11126   if (id == StackFrame::NO_ID) {
11127     // If there is no JavaScript stack frame count is 0.
11128     return Smi::FromInt(0);
11129   }
11130
11131   for (JavaScriptFrameIterator it(isolate, id); !it.done(); it.Advance()) {
11132     List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
11133     it.frame()->Summarize(&frames);
11134     for (int i = frames.length() - 1; i >= 0; i--) {
11135       // Omit functions from native scripts.
11136       if (!frames[i].function()->IsFromNativeScript()) n++;
11137     }
11138   }
11139   return Smi::FromInt(n);
11140 }
11141
11142
11143 class FrameInspector {
11144  public:
11145   FrameInspector(JavaScriptFrame* frame,
11146                  int inlined_jsframe_index,
11147                  Isolate* isolate)
11148       : frame_(frame), deoptimized_frame_(NULL), isolate_(isolate) {
11149     // Calculate the deoptimized frame.
11150     if (frame->is_optimized()) {
11151       deoptimized_frame_ = Deoptimizer::DebuggerInspectableFrame(
11152           frame, inlined_jsframe_index, isolate);
11153     }
11154     has_adapted_arguments_ = frame_->has_adapted_arguments();
11155     is_bottommost_ = inlined_jsframe_index == 0;
11156     is_optimized_ = frame_->is_optimized();
11157   }
11158
11159   ~FrameInspector() {
11160     // Get rid of the calculated deoptimized frame if any.
11161     if (deoptimized_frame_ != NULL) {
11162       Deoptimizer::DeleteDebuggerInspectableFrame(deoptimized_frame_,
11163                                                   isolate_);
11164     }
11165   }
11166
11167   int GetParametersCount() {
11168     return is_optimized_
11169         ? deoptimized_frame_->parameters_count()
11170         : frame_->ComputeParametersCount();
11171   }
11172   int expression_count() { return deoptimized_frame_->expression_count(); }
11173   Object* GetFunction() {
11174     return is_optimized_
11175         ? deoptimized_frame_->GetFunction()
11176         : frame_->function();
11177   }
11178   Object* GetParameter(int index) {
11179     return is_optimized_
11180         ? deoptimized_frame_->GetParameter(index)
11181         : frame_->GetParameter(index);
11182   }
11183   Object* GetExpression(int index) {
11184     return is_optimized_
11185         ? deoptimized_frame_->GetExpression(index)
11186         : frame_->GetExpression(index);
11187   }
11188   int GetSourcePosition() {
11189     return is_optimized_
11190         ? deoptimized_frame_->GetSourcePosition()
11191         : frame_->LookupCode()->SourcePosition(frame_->pc());
11192   }
11193   bool IsConstructor() {
11194     return is_optimized_ && !is_bottommost_
11195         ? deoptimized_frame_->HasConstructStub()
11196         : frame_->IsConstructor();
11197   }
11198
11199   // To inspect all the provided arguments the frame might need to be
11200   // replaced with the arguments frame.
11201   void SetArgumentsFrame(JavaScriptFrame* frame) {
11202     DCHECK(has_adapted_arguments_);
11203     frame_ = frame;
11204     is_optimized_ = frame_->is_optimized();
11205     DCHECK(!is_optimized_);
11206   }
11207
11208  private:
11209   JavaScriptFrame* frame_;
11210   DeoptimizedFrameInfo* deoptimized_frame_;
11211   Isolate* isolate_;
11212   bool is_optimized_;
11213   bool is_bottommost_;
11214   bool has_adapted_arguments_;
11215
11216   DISALLOW_COPY_AND_ASSIGN(FrameInspector);
11217 };
11218
11219
11220 static const int kFrameDetailsFrameIdIndex = 0;
11221 static const int kFrameDetailsReceiverIndex = 1;
11222 static const int kFrameDetailsFunctionIndex = 2;
11223 static const int kFrameDetailsArgumentCountIndex = 3;
11224 static const int kFrameDetailsLocalCountIndex = 4;
11225 static const int kFrameDetailsSourcePositionIndex = 5;
11226 static const int kFrameDetailsConstructCallIndex = 6;
11227 static const int kFrameDetailsAtReturnIndex = 7;
11228 static const int kFrameDetailsFlagsIndex = 8;
11229 static const int kFrameDetailsFirstDynamicIndex = 9;
11230
11231
11232 static SaveContext* FindSavedContextForFrame(Isolate* isolate,
11233                                              JavaScriptFrame* frame) {
11234   SaveContext* save = isolate->save_context();
11235   while (save != NULL && !save->IsBelowFrame(frame)) {
11236     save = save->prev();
11237   }
11238   DCHECK(save != NULL);
11239   return save;
11240 }
11241
11242
11243 RUNTIME_FUNCTION(Runtime_IsOptimized) {
11244   SealHandleScope shs(isolate);
11245   DCHECK(args.length() == 0);
11246   JavaScriptFrameIterator it(isolate);
11247   JavaScriptFrame* frame = it.frame();
11248   return isolate->heap()->ToBoolean(frame->is_optimized());
11249 }
11250
11251
11252 // Advances the iterator to the frame that matches the index and returns the
11253 // inlined frame index, or -1 if not found.  Skips native JS functions.
11254 static int FindIndexedNonNativeFrame(JavaScriptFrameIterator* it, int index) {
11255   int count = -1;
11256   for (; !it->done(); it->Advance()) {
11257     List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
11258     it->frame()->Summarize(&frames);
11259     for (int i = frames.length() - 1; i >= 0; i--) {
11260       // Omit functions from native scripts.
11261       if (frames[i].function()->IsFromNativeScript()) continue;
11262       if (++count == index) return i;
11263     }
11264   }
11265   return -1;
11266 }
11267
11268
11269 // Return an array with frame details
11270 // args[0]: number: break id
11271 // args[1]: number: frame index
11272 //
11273 // The array returned contains the following information:
11274 // 0: Frame id
11275 // 1: Receiver
11276 // 2: Function
11277 // 3: Argument count
11278 // 4: Local count
11279 // 5: Source position
11280 // 6: Constructor call
11281 // 7: Is at return
11282 // 8: Flags
11283 // Arguments name, value
11284 // Locals name, value
11285 // Return value if any
11286 RUNTIME_FUNCTION(Runtime_GetFrameDetails) {
11287   HandleScope scope(isolate);
11288   DCHECK(args.length() == 2);
11289   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
11290   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
11291
11292   CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
11293   Heap* heap = isolate->heap();
11294
11295   // Find the relevant frame with the requested index.
11296   StackFrame::Id id = isolate->debug()->break_frame_id();
11297   if (id == StackFrame::NO_ID) {
11298     // If there are no JavaScript stack frames return undefined.
11299     return heap->undefined_value();
11300   }
11301
11302   JavaScriptFrameIterator it(isolate, id);
11303   // Inlined frame index in optimized frame, starting from outer function.
11304   int inlined_jsframe_index = FindIndexedNonNativeFrame(&it, index);
11305   if (inlined_jsframe_index == -1) return heap->undefined_value();
11306
11307   FrameInspector frame_inspector(it.frame(), inlined_jsframe_index, isolate);
11308   bool is_optimized = it.frame()->is_optimized();
11309
11310   // Traverse the saved contexts chain to find the active context for the
11311   // selected frame.
11312   SaveContext* save = FindSavedContextForFrame(isolate, it.frame());
11313
11314   // Get the frame id.
11315   Handle<Object> frame_id(WrapFrameId(it.frame()->id()), isolate);
11316
11317   // Find source position in unoptimized code.
11318   int position = frame_inspector.GetSourcePosition();
11319
11320   // Check for constructor frame.
11321   bool constructor = frame_inspector.IsConstructor();
11322
11323   // Get scope info and read from it for local variable information.
11324   Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction()));
11325   Handle<SharedFunctionInfo> shared(function->shared());
11326   Handle<ScopeInfo> scope_info(shared->scope_info());
11327   DCHECK(*scope_info != ScopeInfo::Empty(isolate));
11328
11329   // Get the locals names and values into a temporary array.
11330   int local_count = scope_info->LocalCount();
11331   for (int slot = 0; slot < scope_info->LocalCount(); ++slot) {
11332     // Hide compiler-introduced temporary variables, whether on the stack or on
11333     // the context.
11334     if (scope_info->LocalIsSynthetic(slot))
11335       local_count--;
11336   }
11337
11338   Handle<FixedArray> locals =
11339       isolate->factory()->NewFixedArray(local_count * 2);
11340
11341   // Fill in the values of the locals.
11342   int local = 0;
11343   int i = 0;
11344   for (; i < scope_info->StackLocalCount(); ++i) {
11345     // Use the value from the stack.
11346     if (scope_info->LocalIsSynthetic(i))
11347       continue;
11348     locals->set(local * 2, scope_info->LocalName(i));
11349     locals->set(local * 2 + 1, frame_inspector.GetExpression(i));
11350     local++;
11351   }
11352   if (local < local_count) {
11353     // Get the context containing declarations.
11354     Handle<Context> context(
11355         Context::cast(it.frame()->context())->declaration_context());
11356     for (; i < scope_info->LocalCount(); ++i) {
11357       if (scope_info->LocalIsSynthetic(i))
11358         continue;
11359       Handle<String> name(scope_info->LocalName(i));
11360       VariableMode mode;
11361       InitializationFlag init_flag;
11362       MaybeAssignedFlag maybe_assigned_flag;
11363       locals->set(local * 2, *name);
11364       int context_slot_index = ScopeInfo::ContextSlotIndex(
11365           scope_info, name, &mode, &init_flag, &maybe_assigned_flag);
11366       Object* value = context->get(context_slot_index);
11367       locals->set(local * 2 + 1, value);
11368       local++;
11369     }
11370   }
11371
11372   // Check whether this frame is positioned at return. If not top
11373   // frame or if the frame is optimized it cannot be at a return.
11374   bool at_return = false;
11375   if (!is_optimized && index == 0) {
11376     at_return = isolate->debug()->IsBreakAtReturn(it.frame());
11377   }
11378
11379   // If positioned just before return find the value to be returned and add it
11380   // to the frame information.
11381   Handle<Object> return_value = isolate->factory()->undefined_value();
11382   if (at_return) {
11383     StackFrameIterator it2(isolate);
11384     Address internal_frame_sp = NULL;
11385     while (!it2.done()) {
11386       if (it2.frame()->is_internal()) {
11387         internal_frame_sp = it2.frame()->sp();
11388       } else {
11389         if (it2.frame()->is_java_script()) {
11390           if (it2.frame()->id() == it.frame()->id()) {
11391             // The internal frame just before the JavaScript frame contains the
11392             // value to return on top. A debug break at return will create an
11393             // internal frame to store the return value (eax/rax/r0) before
11394             // entering the debug break exit frame.
11395             if (internal_frame_sp != NULL) {
11396               return_value =
11397                   Handle<Object>(Memory::Object_at(internal_frame_sp),
11398                                  isolate);
11399               break;
11400             }
11401           }
11402         }
11403
11404         // Indicate that the previous frame was not an internal frame.
11405         internal_frame_sp = NULL;
11406       }
11407       it2.Advance();
11408     }
11409   }
11410
11411   // Now advance to the arguments adapter frame (if any). It contains all
11412   // the provided parameters whereas the function frame always have the number
11413   // of arguments matching the functions parameters. The rest of the
11414   // information (except for what is collected above) is the same.
11415   if ((inlined_jsframe_index == 0) && it.frame()->has_adapted_arguments()) {
11416     it.AdvanceToArgumentsFrame();
11417     frame_inspector.SetArgumentsFrame(it.frame());
11418   }
11419
11420   // Find the number of arguments to fill. At least fill the number of
11421   // parameters for the function and fill more if more parameters are provided.
11422   int argument_count = scope_info->ParameterCount();
11423   if (argument_count < frame_inspector.GetParametersCount()) {
11424     argument_count = frame_inspector.GetParametersCount();
11425   }
11426
11427   // Calculate the size of the result.
11428   int details_size = kFrameDetailsFirstDynamicIndex +
11429                      2 * (argument_count + local_count) +
11430                      (at_return ? 1 : 0);
11431   Handle<FixedArray> details = isolate->factory()->NewFixedArray(details_size);
11432
11433   // Add the frame id.
11434   details->set(kFrameDetailsFrameIdIndex, *frame_id);
11435
11436   // Add the function (same as in function frame).
11437   details->set(kFrameDetailsFunctionIndex, frame_inspector.GetFunction());
11438
11439   // Add the arguments count.
11440   details->set(kFrameDetailsArgumentCountIndex, Smi::FromInt(argument_count));
11441
11442   // Add the locals count
11443   details->set(kFrameDetailsLocalCountIndex,
11444                Smi::FromInt(local_count));
11445
11446   // Add the source position.
11447   if (position != RelocInfo::kNoPosition) {
11448     details->set(kFrameDetailsSourcePositionIndex, Smi::FromInt(position));
11449   } else {
11450     details->set(kFrameDetailsSourcePositionIndex, heap->undefined_value());
11451   }
11452
11453   // Add the constructor information.
11454   details->set(kFrameDetailsConstructCallIndex, heap->ToBoolean(constructor));
11455
11456   // Add the at return information.
11457   details->set(kFrameDetailsAtReturnIndex, heap->ToBoolean(at_return));
11458
11459   // Add flags to indicate information on whether this frame is
11460   //   bit 0: invoked in the debugger context.
11461   //   bit 1: optimized frame.
11462   //   bit 2: inlined in optimized frame
11463   int flags = 0;
11464   if (*save->context() == *isolate->debug()->debug_context()) {
11465     flags |= 1 << 0;
11466   }
11467   if (is_optimized) {
11468     flags |= 1 << 1;
11469     flags |= inlined_jsframe_index << 2;
11470   }
11471   details->set(kFrameDetailsFlagsIndex, Smi::FromInt(flags));
11472
11473   // Fill the dynamic part.
11474   int details_index = kFrameDetailsFirstDynamicIndex;
11475
11476   // Add arguments name and value.
11477   for (int i = 0; i < argument_count; i++) {
11478     // Name of the argument.
11479     if (i < scope_info->ParameterCount()) {
11480       details->set(details_index++, scope_info->ParameterName(i));
11481     } else {
11482       details->set(details_index++, heap->undefined_value());
11483     }
11484
11485     // Parameter value.
11486     if (i < frame_inspector.GetParametersCount()) {
11487       // Get the value from the stack.
11488       details->set(details_index++, frame_inspector.GetParameter(i));
11489     } else {
11490       details->set(details_index++, heap->undefined_value());
11491     }
11492   }
11493
11494   // Add locals name and value from the temporary copy from the function frame.
11495   for (int i = 0; i < local_count * 2; i++) {
11496     details->set(details_index++, locals->get(i));
11497   }
11498
11499   // Add the value being returned.
11500   if (at_return) {
11501     details->set(details_index++, *return_value);
11502   }
11503
11504   // Add the receiver (same as in function frame).
11505   // THIS MUST BE DONE LAST SINCE WE MIGHT ADVANCE
11506   // THE FRAME ITERATOR TO WRAP THE RECEIVER.
11507   Handle<Object> receiver(it.frame()->receiver(), isolate);
11508   if (!receiver->IsJSObject() &&
11509       shared->strict_mode() == SLOPPY &&
11510       !function->IsBuiltin()) {
11511     // If the receiver is not a JSObject and the function is not a
11512     // builtin or strict-mode we have hit an optimization where a
11513     // value object is not converted into a wrapped JS objects. To
11514     // hide this optimization from the debugger, we wrap the receiver
11515     // by creating correct wrapper object based on the calling frame's
11516     // native context.
11517     it.Advance();
11518     if (receiver->IsUndefined()) {
11519       receiver = handle(function->global_proxy());
11520     } else {
11521       DCHECK(!receiver->IsNull());
11522       Context* context = Context::cast(it.frame()->context());
11523       Handle<Context> native_context(Context::cast(context->native_context()));
11524       receiver = Object::ToObject(
11525           isolate, receiver, native_context).ToHandleChecked();
11526     }
11527   }
11528   details->set(kFrameDetailsReceiverIndex, *receiver);
11529
11530   DCHECK_EQ(details_size, details_index);
11531   return *isolate->factory()->NewJSArrayWithElements(details);
11532 }
11533
11534
11535 static bool ParameterIsShadowedByContextLocal(Handle<ScopeInfo> info,
11536                                               Handle<String> parameter_name) {
11537   VariableMode mode;
11538   InitializationFlag init_flag;
11539   MaybeAssignedFlag maybe_assigned_flag;
11540   return ScopeInfo::ContextSlotIndex(info, parameter_name, &mode, &init_flag,
11541                                      &maybe_assigned_flag) != -1;
11542 }
11543
11544
11545 // Create a plain JSObject which materializes the local scope for the specified
11546 // frame.
11547 MUST_USE_RESULT
11548 static MaybeHandle<JSObject> MaterializeStackLocalsWithFrameInspector(
11549     Isolate* isolate,
11550     Handle<JSObject> target,
11551     Handle<JSFunction> function,
11552     FrameInspector* frame_inspector) {
11553   Handle<SharedFunctionInfo> shared(function->shared());
11554   Handle<ScopeInfo> scope_info(shared->scope_info());
11555
11556   // First fill all parameters.
11557   for (int i = 0; i < scope_info->ParameterCount(); ++i) {
11558     // Do not materialize the parameter if it is shadowed by a context local.
11559     Handle<String> name(scope_info->ParameterName(i));
11560     if (ParameterIsShadowedByContextLocal(scope_info, name)) continue;
11561
11562     HandleScope scope(isolate);
11563     Handle<Object> value(i < frame_inspector->GetParametersCount()
11564                              ? frame_inspector->GetParameter(i)
11565                              : isolate->heap()->undefined_value(),
11566                          isolate);
11567     DCHECK(!value->IsTheHole());
11568
11569     RETURN_ON_EXCEPTION(
11570         isolate,
11571         Runtime::SetObjectProperty(isolate, target, name, value, SLOPPY),
11572         JSObject);
11573   }
11574
11575   // Second fill all stack locals.
11576   for (int i = 0; i < scope_info->StackLocalCount(); ++i) {
11577     if (scope_info->LocalIsSynthetic(i)) continue;
11578     Handle<String> name(scope_info->StackLocalName(i));
11579     Handle<Object> value(frame_inspector->GetExpression(i), isolate);
11580     if (value->IsTheHole()) continue;
11581
11582     RETURN_ON_EXCEPTION(
11583         isolate,
11584         Runtime::SetObjectProperty(isolate, target, name, value, SLOPPY),
11585         JSObject);
11586   }
11587
11588   return target;
11589 }
11590
11591
11592 static void UpdateStackLocalsFromMaterializedObject(Isolate* isolate,
11593                                                     Handle<JSObject> target,
11594                                                     Handle<JSFunction> function,
11595                                                     JavaScriptFrame* frame,
11596                                                     int inlined_jsframe_index) {
11597   if (inlined_jsframe_index != 0 || frame->is_optimized()) {
11598     // Optimized frames are not supported.
11599     // TODO(yangguo): make sure all code deoptimized when debugger is active
11600     //                and assert that this cannot happen.
11601     return;
11602   }
11603
11604   Handle<SharedFunctionInfo> shared(function->shared());
11605   Handle<ScopeInfo> scope_info(shared->scope_info());
11606
11607   // Parameters.
11608   for (int i = 0; i < scope_info->ParameterCount(); ++i) {
11609     // Shadowed parameters were not materialized.
11610     Handle<String> name(scope_info->ParameterName(i));
11611     if (ParameterIsShadowedByContextLocal(scope_info, name)) continue;
11612
11613     DCHECK(!frame->GetParameter(i)->IsTheHole());
11614     HandleScope scope(isolate);
11615     Handle<Object> value =
11616         Object::GetPropertyOrElement(target, name).ToHandleChecked();
11617     frame->SetParameterValue(i, *value);
11618   }
11619
11620   // Stack locals.
11621   for (int i = 0; i < scope_info->StackLocalCount(); ++i) {
11622     if (scope_info->LocalIsSynthetic(i)) continue;
11623     if (frame->GetExpression(i)->IsTheHole()) continue;
11624     HandleScope scope(isolate);
11625     Handle<Object> value = Object::GetPropertyOrElement(
11626         target,
11627         handle(scope_info->StackLocalName(i), isolate)).ToHandleChecked();
11628     frame->SetExpression(i, *value);
11629   }
11630 }
11631
11632
11633 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeLocalContext(
11634     Isolate* isolate,
11635     Handle<JSObject> target,
11636     Handle<JSFunction> function,
11637     JavaScriptFrame* frame) {
11638   HandleScope scope(isolate);
11639   Handle<SharedFunctionInfo> shared(function->shared());
11640   Handle<ScopeInfo> scope_info(shared->scope_info());
11641
11642   if (!scope_info->HasContext()) return target;
11643
11644   // Third fill all context locals.
11645   Handle<Context> frame_context(Context::cast(frame->context()));
11646   Handle<Context> function_context(frame_context->declaration_context());
11647   if (!ScopeInfo::CopyContextLocalsToScopeObject(
11648           scope_info, function_context, target)) {
11649     return MaybeHandle<JSObject>();
11650   }
11651
11652   // Finally copy any properties from the function context extension.
11653   // These will be variables introduced by eval.
11654   if (function_context->closure() == *function) {
11655     if (function_context->has_extension() &&
11656         !function_context->IsNativeContext()) {
11657       Handle<JSObject> ext(JSObject::cast(function_context->extension()));
11658       Handle<FixedArray> keys;
11659       ASSIGN_RETURN_ON_EXCEPTION(
11660           isolate, keys,
11661           JSReceiver::GetKeys(ext, JSReceiver::INCLUDE_PROTOS),
11662           JSObject);
11663
11664       for (int i = 0; i < keys->length(); i++) {
11665         // Names of variables introduced by eval are strings.
11666         DCHECK(keys->get(i)->IsString());
11667         Handle<String> key(String::cast(keys->get(i)));
11668         Handle<Object> value;
11669         ASSIGN_RETURN_ON_EXCEPTION(
11670             isolate, value, Object::GetPropertyOrElement(ext, key), JSObject);
11671         RETURN_ON_EXCEPTION(
11672             isolate,
11673             Runtime::SetObjectProperty(isolate, target, key, value, SLOPPY),
11674             JSObject);
11675       }
11676     }
11677   }
11678
11679   return target;
11680 }
11681
11682
11683 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeLocalScope(
11684     Isolate* isolate,
11685     JavaScriptFrame* frame,
11686     int inlined_jsframe_index) {
11687   FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate);
11688   Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction()));
11689
11690   Handle<JSObject> local_scope =
11691       isolate->factory()->NewJSObject(isolate->object_function());
11692   ASSIGN_RETURN_ON_EXCEPTION(
11693       isolate, local_scope,
11694       MaterializeStackLocalsWithFrameInspector(
11695           isolate, local_scope, function, &frame_inspector),
11696       JSObject);
11697
11698   return MaterializeLocalContext(isolate, local_scope, function, frame);
11699 }
11700
11701
11702 // Set the context local variable value.
11703 static bool SetContextLocalValue(Isolate* isolate,
11704                                  Handle<ScopeInfo> scope_info,
11705                                  Handle<Context> context,
11706                                  Handle<String> variable_name,
11707                                  Handle<Object> new_value) {
11708   for (int i = 0; i < scope_info->ContextLocalCount(); i++) {
11709     Handle<String> next_name(scope_info->ContextLocalName(i));
11710     if (String::Equals(variable_name, next_name)) {
11711       VariableMode mode;
11712       InitializationFlag init_flag;
11713       MaybeAssignedFlag maybe_assigned_flag;
11714       int context_index = ScopeInfo::ContextSlotIndex(
11715           scope_info, next_name, &mode, &init_flag, &maybe_assigned_flag);
11716       context->set(context_index, *new_value);
11717       return true;
11718     }
11719   }
11720
11721   return false;
11722 }
11723
11724
11725 static bool SetLocalVariableValue(Isolate* isolate,
11726                                   JavaScriptFrame* frame,
11727                                   int inlined_jsframe_index,
11728                                   Handle<String> variable_name,
11729                                   Handle<Object> new_value) {
11730   if (inlined_jsframe_index != 0 || frame->is_optimized()) {
11731     // Optimized frames are not supported.
11732     return false;
11733   }
11734
11735   Handle<JSFunction> function(frame->function());
11736   Handle<SharedFunctionInfo> shared(function->shared());
11737   Handle<ScopeInfo> scope_info(shared->scope_info());
11738
11739   bool default_result = false;
11740
11741   // Parameters.
11742   for (int i = 0; i < scope_info->ParameterCount(); ++i) {
11743     HandleScope scope(isolate);
11744     if (String::Equals(handle(scope_info->ParameterName(i)), variable_name)) {
11745       frame->SetParameterValue(i, *new_value);
11746       // Argument might be shadowed in heap context, don't stop here.
11747       default_result = true;
11748     }
11749   }
11750
11751   // Stack locals.
11752   for (int i = 0; i < scope_info->StackLocalCount(); ++i) {
11753     HandleScope scope(isolate);
11754     if (String::Equals(handle(scope_info->StackLocalName(i)), variable_name)) {
11755       frame->SetExpression(i, *new_value);
11756       return true;
11757     }
11758   }
11759
11760   if (scope_info->HasContext()) {
11761     // Context locals.
11762     Handle<Context> frame_context(Context::cast(frame->context()));
11763     Handle<Context> function_context(frame_context->declaration_context());
11764     if (SetContextLocalValue(
11765         isolate, scope_info, function_context, variable_name, new_value)) {
11766       return true;
11767     }
11768
11769     // Function context extension. These are variables introduced by eval.
11770     if (function_context->closure() == *function) {
11771       if (function_context->has_extension() &&
11772           !function_context->IsNativeContext()) {
11773         Handle<JSObject> ext(JSObject::cast(function_context->extension()));
11774
11775         Maybe<bool> maybe = JSReceiver::HasProperty(ext, variable_name);
11776         DCHECK(maybe.has_value);
11777         if (maybe.value) {
11778           // We don't expect this to do anything except replacing
11779           // property value.
11780           Runtime::SetObjectProperty(isolate, ext, variable_name, new_value,
11781                                      SLOPPY).Assert();
11782           return true;
11783         }
11784       }
11785     }
11786   }
11787
11788   return default_result;
11789 }
11790
11791
11792 // Create a plain JSObject which materializes the closure content for the
11793 // context.
11794 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeClosure(
11795     Isolate* isolate,
11796     Handle<Context> context) {
11797   DCHECK(context->IsFunctionContext());
11798
11799   Handle<SharedFunctionInfo> shared(context->closure()->shared());
11800   Handle<ScopeInfo> scope_info(shared->scope_info());
11801
11802   // Allocate and initialize a JSObject with all the content of this function
11803   // closure.
11804   Handle<JSObject> closure_scope =
11805       isolate->factory()->NewJSObject(isolate->object_function());
11806
11807   // Fill all context locals to the context extension.
11808   if (!ScopeInfo::CopyContextLocalsToScopeObject(
11809           scope_info, context, closure_scope)) {
11810     return MaybeHandle<JSObject>();
11811   }
11812
11813   // Finally copy any properties from the function context extension. This will
11814   // be variables introduced by eval.
11815   if (context->has_extension()) {
11816     Handle<JSObject> ext(JSObject::cast(context->extension()));
11817     Handle<FixedArray> keys;
11818     ASSIGN_RETURN_ON_EXCEPTION(
11819         isolate, keys,
11820         JSReceiver::GetKeys(ext, JSReceiver::INCLUDE_PROTOS), JSObject);
11821
11822     for (int i = 0; i < keys->length(); i++) {
11823       HandleScope scope(isolate);
11824       // Names of variables introduced by eval are strings.
11825       DCHECK(keys->get(i)->IsString());
11826       Handle<String> key(String::cast(keys->get(i)));
11827       Handle<Object> value;
11828       ASSIGN_RETURN_ON_EXCEPTION(
11829           isolate, value, Object::GetPropertyOrElement(ext, key), JSObject);
11830       RETURN_ON_EXCEPTION(
11831           isolate,
11832           Runtime::DefineObjectProperty(closure_scope, key, value, NONE),
11833           JSObject);
11834     }
11835   }
11836
11837   return closure_scope;
11838 }
11839
11840
11841 // This method copies structure of MaterializeClosure method above.
11842 static bool SetClosureVariableValue(Isolate* isolate,
11843                                     Handle<Context> context,
11844                                     Handle<String> variable_name,
11845                                     Handle<Object> new_value) {
11846   DCHECK(context->IsFunctionContext());
11847
11848   Handle<SharedFunctionInfo> shared(context->closure()->shared());
11849   Handle<ScopeInfo> scope_info(shared->scope_info());
11850
11851   // Context locals to the context extension.
11852   if (SetContextLocalValue(
11853           isolate, scope_info, context, variable_name, new_value)) {
11854     return true;
11855   }
11856
11857   // Properties from the function context extension. This will
11858   // be variables introduced by eval.
11859   if (context->has_extension()) {
11860     Handle<JSObject> ext(JSObject::cast(context->extension()));
11861     Maybe<bool> maybe = JSReceiver::HasProperty(ext, variable_name);
11862     DCHECK(maybe.has_value);
11863     if (maybe.value) {
11864       // We don't expect this to do anything except replacing property value.
11865       Runtime::DefineObjectProperty(
11866           ext, variable_name, new_value, NONE).Assert();
11867       return true;
11868     }
11869   }
11870
11871   return false;
11872 }
11873
11874
11875 // Create a plain JSObject which materializes the scope for the specified
11876 // catch context.
11877 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeCatchScope(
11878     Isolate* isolate,
11879     Handle<Context> context) {
11880   DCHECK(context->IsCatchContext());
11881   Handle<String> name(String::cast(context->extension()));
11882   Handle<Object> thrown_object(context->get(Context::THROWN_OBJECT_INDEX),
11883                                isolate);
11884   Handle<JSObject> catch_scope =
11885       isolate->factory()->NewJSObject(isolate->object_function());
11886   RETURN_ON_EXCEPTION(
11887       isolate,
11888       Runtime::DefineObjectProperty(catch_scope, name, thrown_object, NONE),
11889       JSObject);
11890   return catch_scope;
11891 }
11892
11893
11894 static bool SetCatchVariableValue(Isolate* isolate,
11895                                   Handle<Context> context,
11896                                   Handle<String> variable_name,
11897                                   Handle<Object> new_value) {
11898   DCHECK(context->IsCatchContext());
11899   Handle<String> name(String::cast(context->extension()));
11900   if (!String::Equals(name, variable_name)) {
11901     return false;
11902   }
11903   context->set(Context::THROWN_OBJECT_INDEX, *new_value);
11904   return true;
11905 }
11906
11907
11908 // Create a plain JSObject which materializes the block scope for the specified
11909 // block context.
11910 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeBlockScope(
11911     Isolate* isolate,
11912     Handle<Context> context) {
11913   DCHECK(context->IsBlockContext());
11914   Handle<ScopeInfo> scope_info(ScopeInfo::cast(context->extension()));
11915
11916   // Allocate and initialize a JSObject with all the arguments, stack locals
11917   // heap locals and extension properties of the debugged function.
11918   Handle<JSObject> block_scope =
11919       isolate->factory()->NewJSObject(isolate->object_function());
11920
11921   // Fill all context locals.
11922   if (!ScopeInfo::CopyContextLocalsToScopeObject(
11923           scope_info, context, block_scope)) {
11924     return MaybeHandle<JSObject>();
11925   }
11926
11927   return block_scope;
11928 }
11929
11930
11931 // Create a plain JSObject which materializes the module scope for the specified
11932 // module context.
11933 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeModuleScope(
11934     Isolate* isolate,
11935     Handle<Context> context) {
11936   DCHECK(context->IsModuleContext());
11937   Handle<ScopeInfo> scope_info(ScopeInfo::cast(context->extension()));
11938
11939   // Allocate and initialize a JSObject with all the members of the debugged
11940   // module.
11941   Handle<JSObject> module_scope =
11942       isolate->factory()->NewJSObject(isolate->object_function());
11943
11944   // Fill all context locals.
11945   if (!ScopeInfo::CopyContextLocalsToScopeObject(
11946           scope_info, context, module_scope)) {
11947     return MaybeHandle<JSObject>();
11948   }
11949
11950   return module_scope;
11951 }
11952
11953
11954 // Iterate over the actual scopes visible from a stack frame or from a closure.
11955 // The iteration proceeds from the innermost visible nested scope outwards.
11956 // All scopes are backed by an actual context except the local scope,
11957 // which is inserted "artificially" in the context chain.
11958 class ScopeIterator {
11959  public:
11960   enum ScopeType {
11961     ScopeTypeGlobal = 0,
11962     ScopeTypeLocal,
11963     ScopeTypeWith,
11964     ScopeTypeClosure,
11965     ScopeTypeCatch,
11966     ScopeTypeBlock,
11967     ScopeTypeModule
11968   };
11969
11970   ScopeIterator(Isolate* isolate,
11971                 JavaScriptFrame* frame,
11972                 int inlined_jsframe_index,
11973                 bool ignore_nested_scopes = false)
11974     : isolate_(isolate),
11975       frame_(frame),
11976       inlined_jsframe_index_(inlined_jsframe_index),
11977       function_(frame->function()),
11978       context_(Context::cast(frame->context())),
11979       nested_scope_chain_(4),
11980       failed_(false) {
11981
11982     // Catch the case when the debugger stops in an internal function.
11983     Handle<SharedFunctionInfo> shared_info(function_->shared());
11984     Handle<ScopeInfo> scope_info(shared_info->scope_info());
11985     if (shared_info->script() == isolate->heap()->undefined_value()) {
11986       while (context_->closure() == *function_) {
11987         context_ = Handle<Context>(context_->previous(), isolate_);
11988       }
11989       return;
11990     }
11991
11992     // Get the debug info (create it if it does not exist).
11993     if (!isolate->debug()->EnsureDebugInfo(shared_info, function_)) {
11994       // Return if ensuring debug info failed.
11995       return;
11996     }
11997
11998     // Currently it takes too much time to find nested scopes due to script
11999     // parsing. Sometimes we want to run the ScopeIterator as fast as possible
12000     // (for example, while collecting async call stacks on every
12001     // addEventListener call), even if we drop some nested scopes.
12002     // Later we may optimize getting the nested scopes (cache the result?)
12003     // and include nested scopes into the "fast" iteration case as well.
12004     if (!ignore_nested_scopes) {
12005       Handle<DebugInfo> debug_info = Debug::GetDebugInfo(shared_info);
12006
12007       // Find the break point where execution has stopped.
12008       BreakLocationIterator break_location_iterator(debug_info,
12009                                                     ALL_BREAK_LOCATIONS);
12010       // pc points to the instruction after the current one, possibly a break
12011       // location as well. So the "- 1" to exclude it from the search.
12012       break_location_iterator.FindBreakLocationFromAddress(frame->pc() - 1);
12013
12014       // Within the return sequence at the moment it is not possible to
12015       // get a source position which is consistent with the current scope chain.
12016       // Thus all nested with, catch and block contexts are skipped and we only
12017       // provide the function scope.
12018       ignore_nested_scopes = break_location_iterator.IsExit();
12019     }
12020
12021     if (ignore_nested_scopes) {
12022       if (scope_info->HasContext()) {
12023         context_ = Handle<Context>(context_->declaration_context(), isolate_);
12024       } else {
12025         while (context_->closure() == *function_) {
12026           context_ = Handle<Context>(context_->previous(), isolate_);
12027         }
12028       }
12029       if (scope_info->scope_type() == FUNCTION_SCOPE) {
12030         nested_scope_chain_.Add(scope_info);
12031       }
12032     } else {
12033       // Reparse the code and analyze the scopes.
12034       Handle<Script> script(Script::cast(shared_info->script()));
12035       Scope* scope = NULL;
12036
12037       // Check whether we are in global, eval or function code.
12038       Handle<ScopeInfo> scope_info(shared_info->scope_info());
12039       if (scope_info->scope_type() != FUNCTION_SCOPE) {
12040         // Global or eval code.
12041         CompilationInfoWithZone info(script);
12042         if (scope_info->scope_type() == GLOBAL_SCOPE) {
12043           info.MarkAsGlobal();
12044         } else {
12045           DCHECK(scope_info->scope_type() == EVAL_SCOPE);
12046           info.MarkAsEval();
12047           info.SetContext(Handle<Context>(function_->context()));
12048         }
12049         if (Parser::Parse(&info) && Scope::Analyze(&info)) {
12050           scope = info.function()->scope();
12051         }
12052         RetrieveScopeChain(scope, shared_info);
12053       } else {
12054         // Function code
12055         CompilationInfoWithZone info(shared_info);
12056         if (Parser::Parse(&info) && Scope::Analyze(&info)) {
12057           scope = info.function()->scope();
12058         }
12059         RetrieveScopeChain(scope, shared_info);
12060       }
12061     }
12062   }
12063
12064   ScopeIterator(Isolate* isolate,
12065                 Handle<JSFunction> function)
12066     : isolate_(isolate),
12067       frame_(NULL),
12068       inlined_jsframe_index_(0),
12069       function_(function),
12070       context_(function->context()),
12071       failed_(false) {
12072     if (function->IsBuiltin()) {
12073       context_ = Handle<Context>();
12074     }
12075   }
12076
12077   // More scopes?
12078   bool Done() {
12079     DCHECK(!failed_);
12080     return context_.is_null();
12081   }
12082
12083   bool Failed() { return failed_; }
12084
12085   // Move to the next scope.
12086   void Next() {
12087     DCHECK(!failed_);
12088     ScopeType scope_type = Type();
12089     if (scope_type == ScopeTypeGlobal) {
12090       // The global scope is always the last in the chain.
12091       DCHECK(context_->IsNativeContext());
12092       context_ = Handle<Context>();
12093       return;
12094     }
12095     if (nested_scope_chain_.is_empty()) {
12096       context_ = Handle<Context>(context_->previous(), isolate_);
12097     } else {
12098       if (nested_scope_chain_.last()->HasContext()) {
12099         DCHECK(context_->previous() != NULL);
12100         context_ = Handle<Context>(context_->previous(), isolate_);
12101       }
12102       nested_scope_chain_.RemoveLast();
12103     }
12104   }
12105
12106   // Return the type of the current scope.
12107   ScopeType Type() {
12108     DCHECK(!failed_);
12109     if (!nested_scope_chain_.is_empty()) {
12110       Handle<ScopeInfo> scope_info = nested_scope_chain_.last();
12111       switch (scope_info->scope_type()) {
12112         case FUNCTION_SCOPE:
12113           DCHECK(context_->IsFunctionContext() ||
12114                  !scope_info->HasContext());
12115           return ScopeTypeLocal;
12116         case MODULE_SCOPE:
12117           DCHECK(context_->IsModuleContext());
12118           return ScopeTypeModule;
12119         case GLOBAL_SCOPE:
12120           DCHECK(context_->IsNativeContext());
12121           return ScopeTypeGlobal;
12122         case WITH_SCOPE:
12123           DCHECK(context_->IsWithContext());
12124           return ScopeTypeWith;
12125         case CATCH_SCOPE:
12126           DCHECK(context_->IsCatchContext());
12127           return ScopeTypeCatch;
12128         case BLOCK_SCOPE:
12129           DCHECK(!scope_info->HasContext() ||
12130                  context_->IsBlockContext());
12131           return ScopeTypeBlock;
12132         case EVAL_SCOPE:
12133           UNREACHABLE();
12134       }
12135     }
12136     if (context_->IsNativeContext()) {
12137       DCHECK(context_->global_object()->IsGlobalObject());
12138       return ScopeTypeGlobal;
12139     }
12140     if (context_->IsFunctionContext()) {
12141       return ScopeTypeClosure;
12142     }
12143     if (context_->IsCatchContext()) {
12144       return ScopeTypeCatch;
12145     }
12146     if (context_->IsBlockContext()) {
12147       return ScopeTypeBlock;
12148     }
12149     if (context_->IsModuleContext()) {
12150       return ScopeTypeModule;
12151     }
12152     DCHECK(context_->IsWithContext());
12153     return ScopeTypeWith;
12154   }
12155
12156   // Return the JavaScript object with the content of the current scope.
12157   MaybeHandle<JSObject> ScopeObject() {
12158     DCHECK(!failed_);
12159     switch (Type()) {
12160       case ScopeIterator::ScopeTypeGlobal:
12161         return Handle<JSObject>(CurrentContext()->global_object());
12162       case ScopeIterator::ScopeTypeLocal:
12163         // Materialize the content of the local scope into a JSObject.
12164         DCHECK(nested_scope_chain_.length() == 1);
12165         return MaterializeLocalScope(isolate_, frame_, inlined_jsframe_index_);
12166       case ScopeIterator::ScopeTypeWith:
12167         // Return the with object.
12168         return Handle<JSObject>(JSObject::cast(CurrentContext()->extension()));
12169       case ScopeIterator::ScopeTypeCatch:
12170         return MaterializeCatchScope(isolate_, CurrentContext());
12171       case ScopeIterator::ScopeTypeClosure:
12172         // Materialize the content of the closure scope into a JSObject.
12173         return MaterializeClosure(isolate_, CurrentContext());
12174       case ScopeIterator::ScopeTypeBlock:
12175         return MaterializeBlockScope(isolate_, CurrentContext());
12176       case ScopeIterator::ScopeTypeModule:
12177         return MaterializeModuleScope(isolate_, CurrentContext());
12178     }
12179     UNREACHABLE();
12180     return Handle<JSObject>();
12181   }
12182
12183   bool SetVariableValue(Handle<String> variable_name,
12184                         Handle<Object> new_value) {
12185     DCHECK(!failed_);
12186     switch (Type()) {
12187       case ScopeIterator::ScopeTypeGlobal:
12188         break;
12189       case ScopeIterator::ScopeTypeLocal:
12190         return SetLocalVariableValue(isolate_, frame_, inlined_jsframe_index_,
12191             variable_name, new_value);
12192       case ScopeIterator::ScopeTypeWith:
12193         break;
12194       case ScopeIterator::ScopeTypeCatch:
12195         return SetCatchVariableValue(isolate_, CurrentContext(),
12196             variable_name, new_value);
12197       case ScopeIterator::ScopeTypeClosure:
12198         return SetClosureVariableValue(isolate_, CurrentContext(),
12199             variable_name, new_value);
12200       case ScopeIterator::ScopeTypeBlock:
12201         // TODO(2399): should we implement it?
12202         break;
12203       case ScopeIterator::ScopeTypeModule:
12204         // TODO(2399): should we implement it?
12205         break;
12206     }
12207     return false;
12208   }
12209
12210   Handle<ScopeInfo> CurrentScopeInfo() {
12211     DCHECK(!failed_);
12212     if (!nested_scope_chain_.is_empty()) {
12213       return nested_scope_chain_.last();
12214     } else if (context_->IsBlockContext()) {
12215       return Handle<ScopeInfo>(ScopeInfo::cast(context_->extension()));
12216     } else if (context_->IsFunctionContext()) {
12217       return Handle<ScopeInfo>(context_->closure()->shared()->scope_info());
12218     }
12219     return Handle<ScopeInfo>::null();
12220   }
12221
12222   // Return the context for this scope. For the local context there might not
12223   // be an actual context.
12224   Handle<Context> CurrentContext() {
12225     DCHECK(!failed_);
12226     if (Type() == ScopeTypeGlobal ||
12227         nested_scope_chain_.is_empty()) {
12228       return context_;
12229     } else if (nested_scope_chain_.last()->HasContext()) {
12230       return context_;
12231     } else {
12232       return Handle<Context>();
12233     }
12234   }
12235
12236 #ifdef DEBUG
12237   // Debug print of the content of the current scope.
12238   void DebugPrint() {
12239     OFStream os(stdout);
12240     DCHECK(!failed_);
12241     switch (Type()) {
12242       case ScopeIterator::ScopeTypeGlobal:
12243         os << "Global:\n";
12244         CurrentContext()->Print(os);
12245         break;
12246
12247       case ScopeIterator::ScopeTypeLocal: {
12248         os << "Local:\n";
12249         function_->shared()->scope_info()->Print();
12250         if (!CurrentContext().is_null()) {
12251           CurrentContext()->Print(os);
12252           if (CurrentContext()->has_extension()) {
12253             Handle<Object> extension(CurrentContext()->extension(), isolate_);
12254             if (extension->IsJSContextExtensionObject()) {
12255               extension->Print(os);
12256             }
12257           }
12258         }
12259         break;
12260       }
12261
12262       case ScopeIterator::ScopeTypeWith:
12263         os << "With:\n";
12264         CurrentContext()->extension()->Print(os);
12265         break;
12266
12267       case ScopeIterator::ScopeTypeCatch:
12268         os << "Catch:\n";
12269         CurrentContext()->extension()->Print(os);
12270         CurrentContext()->get(Context::THROWN_OBJECT_INDEX)->Print(os);
12271         break;
12272
12273       case ScopeIterator::ScopeTypeClosure:
12274         os << "Closure:\n";
12275         CurrentContext()->Print(os);
12276         if (CurrentContext()->has_extension()) {
12277           Handle<Object> extension(CurrentContext()->extension(), isolate_);
12278           if (extension->IsJSContextExtensionObject()) {
12279             extension->Print(os);
12280           }
12281         }
12282         break;
12283
12284       default:
12285         UNREACHABLE();
12286     }
12287     PrintF("\n");
12288   }
12289 #endif
12290
12291  private:
12292   Isolate* isolate_;
12293   JavaScriptFrame* frame_;
12294   int inlined_jsframe_index_;
12295   Handle<JSFunction> function_;
12296   Handle<Context> context_;
12297   List<Handle<ScopeInfo> > nested_scope_chain_;
12298   bool failed_;
12299
12300   void RetrieveScopeChain(Scope* scope,
12301                           Handle<SharedFunctionInfo> shared_info) {
12302     if (scope != NULL) {
12303       int source_position = shared_info->code()->SourcePosition(frame_->pc());
12304       scope->GetNestedScopeChain(&nested_scope_chain_, source_position);
12305     } else {
12306       // A failed reparse indicates that the preparser has diverged from the
12307       // parser or that the preparse data given to the initial parse has been
12308       // faulty. We fail in debug mode but in release mode we only provide the
12309       // information we get from the context chain but nothing about
12310       // completely stack allocated scopes or stack allocated locals.
12311       // Or it could be due to stack overflow.
12312       DCHECK(isolate_->has_pending_exception());
12313       failed_ = true;
12314     }
12315   }
12316
12317   DISALLOW_IMPLICIT_CONSTRUCTORS(ScopeIterator);
12318 };
12319
12320
12321 RUNTIME_FUNCTION(Runtime_GetScopeCount) {
12322   HandleScope scope(isolate);
12323   DCHECK(args.length() == 2);
12324   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
12325   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
12326
12327   CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
12328
12329   // Get the frame where the debugging is performed.
12330   StackFrame::Id id = UnwrapFrameId(wrapped_id);
12331   JavaScriptFrameIterator it(isolate, id);
12332   JavaScriptFrame* frame = it.frame();
12333
12334   // Count the visible scopes.
12335   int n = 0;
12336   for (ScopeIterator it(isolate, frame, 0);
12337        !it.Done();
12338        it.Next()) {
12339     n++;
12340   }
12341
12342   return Smi::FromInt(n);
12343 }
12344
12345
12346 // Returns the list of step-in positions (text offset) in a function of the
12347 // stack frame in a range from the current debug break position to the end
12348 // of the corresponding statement.
12349 RUNTIME_FUNCTION(Runtime_GetStepInPositions) {
12350   HandleScope scope(isolate);
12351   DCHECK(args.length() == 2);
12352   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
12353   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
12354
12355   CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
12356
12357   // Get the frame where the debugging is performed.
12358   StackFrame::Id id = UnwrapFrameId(wrapped_id);
12359   JavaScriptFrameIterator frame_it(isolate, id);
12360   RUNTIME_ASSERT(!frame_it.done());
12361
12362   JavaScriptFrame* frame = frame_it.frame();
12363
12364   Handle<JSFunction> fun =
12365       Handle<JSFunction>(frame->function());
12366   Handle<SharedFunctionInfo> shared =
12367       Handle<SharedFunctionInfo>(fun->shared());
12368
12369   if (!isolate->debug()->EnsureDebugInfo(shared, fun)) {
12370     return isolate->heap()->undefined_value();
12371   }
12372
12373   Handle<DebugInfo> debug_info = Debug::GetDebugInfo(shared);
12374
12375   int len = 0;
12376   Handle<JSArray> array(isolate->factory()->NewJSArray(10));
12377   // Find the break point where execution has stopped.
12378   BreakLocationIterator break_location_iterator(debug_info,
12379                                                 ALL_BREAK_LOCATIONS);
12380
12381   break_location_iterator.FindBreakLocationFromAddress(frame->pc() - 1);
12382   int current_statement_pos = break_location_iterator.statement_position();
12383
12384   while (!break_location_iterator.Done()) {
12385     bool accept;
12386     if (break_location_iterator.pc() > frame->pc()) {
12387       accept = true;
12388     } else {
12389       StackFrame::Id break_frame_id = isolate->debug()->break_frame_id();
12390       // The break point is near our pc. Could be a step-in possibility,
12391       // that is currently taken by active debugger call.
12392       if (break_frame_id == StackFrame::NO_ID) {
12393         // We are not stepping.
12394         accept = false;
12395       } else {
12396         JavaScriptFrameIterator additional_frame_it(isolate, break_frame_id);
12397         // If our frame is a top frame and we are stepping, we can do step-in
12398         // at this place.
12399         accept = additional_frame_it.frame()->id() == id;
12400       }
12401     }
12402     if (accept) {
12403       if (break_location_iterator.IsStepInLocation(isolate)) {
12404         Smi* position_value = Smi::FromInt(break_location_iterator.position());
12405         RETURN_FAILURE_ON_EXCEPTION(
12406             isolate,
12407             JSObject::SetElement(array, len,
12408                                  Handle<Object>(position_value, isolate),
12409                                  NONE, SLOPPY));
12410         len++;
12411       }
12412     }
12413     // Advance iterator.
12414     break_location_iterator.Next();
12415     if (current_statement_pos !=
12416         break_location_iterator.statement_position()) {
12417       break;
12418     }
12419   }
12420   return *array;
12421 }
12422
12423
12424 static const int kScopeDetailsTypeIndex = 0;
12425 static const int kScopeDetailsObjectIndex = 1;
12426 static const int kScopeDetailsSize = 2;
12427
12428
12429 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeScopeDetails(
12430     Isolate* isolate,
12431     ScopeIterator* it) {
12432   // Calculate the size of the result.
12433   int details_size = kScopeDetailsSize;
12434   Handle<FixedArray> details = isolate->factory()->NewFixedArray(details_size);
12435
12436   // Fill in scope details.
12437   details->set(kScopeDetailsTypeIndex, Smi::FromInt(it->Type()));
12438   Handle<JSObject> scope_object;
12439   ASSIGN_RETURN_ON_EXCEPTION(
12440       isolate, scope_object, it->ScopeObject(), JSObject);
12441   details->set(kScopeDetailsObjectIndex, *scope_object);
12442
12443   return isolate->factory()->NewJSArrayWithElements(details);
12444 }
12445
12446
12447 // Return an array with scope details
12448 // args[0]: number: break id
12449 // args[1]: number: frame index
12450 // args[2]: number: inlined frame index
12451 // args[3]: number: scope index
12452 //
12453 // The array returned contains the following information:
12454 // 0: Scope type
12455 // 1: Scope object
12456 RUNTIME_FUNCTION(Runtime_GetScopeDetails) {
12457   HandleScope scope(isolate);
12458   DCHECK(args.length() == 4);
12459   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
12460   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
12461
12462   CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
12463   CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
12464   CONVERT_NUMBER_CHECKED(int, index, Int32, args[3]);
12465
12466   // Get the frame where the debugging is performed.
12467   StackFrame::Id id = UnwrapFrameId(wrapped_id);
12468   JavaScriptFrameIterator frame_it(isolate, id);
12469   JavaScriptFrame* frame = frame_it.frame();
12470
12471   // Find the requested scope.
12472   int n = 0;
12473   ScopeIterator it(isolate, frame, inlined_jsframe_index);
12474   for (; !it.Done() && n < index; it.Next()) {
12475     n++;
12476   }
12477   if (it.Done()) {
12478     return isolate->heap()->undefined_value();
12479   }
12480   Handle<JSObject> details;
12481   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
12482       isolate, details, MaterializeScopeDetails(isolate, &it));
12483   return *details;
12484 }
12485
12486
12487 // Return an array of scope details
12488 // args[0]: number: break id
12489 // args[1]: number: frame index
12490 // args[2]: number: inlined frame index
12491 // args[3]: boolean: ignore nested scopes
12492 //
12493 // The array returned contains arrays with the following information:
12494 // 0: Scope type
12495 // 1: Scope object
12496 RUNTIME_FUNCTION(Runtime_GetAllScopesDetails) {
12497   HandleScope scope(isolate);
12498   DCHECK(args.length() == 3 || args.length() == 4);
12499   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
12500   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
12501
12502   CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
12503   CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
12504
12505   bool ignore_nested_scopes = false;
12506   if (args.length() == 4) {
12507     CONVERT_BOOLEAN_ARG_CHECKED(flag, 3);
12508     ignore_nested_scopes = flag;
12509   }
12510
12511   // Get the frame where the debugging is performed.
12512   StackFrame::Id id = UnwrapFrameId(wrapped_id);
12513   JavaScriptFrameIterator frame_it(isolate, id);
12514   JavaScriptFrame* frame = frame_it.frame();
12515
12516   List<Handle<JSObject> > result(4);
12517   ScopeIterator it(isolate, frame, inlined_jsframe_index, ignore_nested_scopes);
12518   for (; !it.Done(); it.Next()) {
12519     Handle<JSObject> details;
12520     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
12521         isolate, details, MaterializeScopeDetails(isolate, &it));
12522     result.Add(details);
12523   }
12524
12525   Handle<FixedArray> array = isolate->factory()->NewFixedArray(result.length());
12526   for (int i = 0; i < result.length(); ++i) {
12527     array->set(i, *result[i]);
12528   }
12529   return *isolate->factory()->NewJSArrayWithElements(array);
12530 }
12531
12532
12533 RUNTIME_FUNCTION(Runtime_GetFunctionScopeCount) {
12534   HandleScope scope(isolate);
12535   DCHECK(args.length() == 1);
12536
12537   // Check arguments.
12538   CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
12539
12540   // Count the visible scopes.
12541   int n = 0;
12542   for (ScopeIterator it(isolate, fun); !it.Done(); it.Next()) {
12543     n++;
12544   }
12545
12546   return Smi::FromInt(n);
12547 }
12548
12549
12550 RUNTIME_FUNCTION(Runtime_GetFunctionScopeDetails) {
12551   HandleScope scope(isolate);
12552   DCHECK(args.length() == 2);
12553
12554   // Check arguments.
12555   CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
12556   CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
12557
12558   // Find the requested scope.
12559   int n = 0;
12560   ScopeIterator it(isolate, fun);
12561   for (; !it.Done() && n < index; it.Next()) {
12562     n++;
12563   }
12564   if (it.Done()) {
12565     return isolate->heap()->undefined_value();
12566   }
12567
12568   Handle<JSObject> details;
12569   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
12570       isolate, details, MaterializeScopeDetails(isolate, &it));
12571   return *details;
12572 }
12573
12574
12575 static bool SetScopeVariableValue(ScopeIterator* it, int index,
12576                                   Handle<String> variable_name,
12577                                   Handle<Object> new_value) {
12578   for (int n = 0; !it->Done() && n < index; it->Next()) {
12579     n++;
12580   }
12581   if (it->Done()) {
12582     return false;
12583   }
12584   return it->SetVariableValue(variable_name, new_value);
12585 }
12586
12587
12588 // Change variable value in closure or local scope
12589 // args[0]: number or JsFunction: break id or function
12590 // args[1]: number: frame index (when arg[0] is break id)
12591 // args[2]: number: inlined frame index (when arg[0] is break id)
12592 // args[3]: number: scope index
12593 // args[4]: string: variable name
12594 // args[5]: object: new value
12595 //
12596 // Return true if success and false otherwise
12597 RUNTIME_FUNCTION(Runtime_SetScopeVariableValue) {
12598   HandleScope scope(isolate);
12599   DCHECK(args.length() == 6);
12600
12601   // Check arguments.
12602   CONVERT_NUMBER_CHECKED(int, index, Int32, args[3]);
12603   CONVERT_ARG_HANDLE_CHECKED(String, variable_name, 4);
12604   CONVERT_ARG_HANDLE_CHECKED(Object, new_value, 5);
12605
12606   bool res;
12607   if (args[0]->IsNumber()) {
12608     CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
12609     RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
12610
12611     CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
12612     CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
12613
12614     // Get the frame where the debugging is performed.
12615     StackFrame::Id id = UnwrapFrameId(wrapped_id);
12616     JavaScriptFrameIterator frame_it(isolate, id);
12617     JavaScriptFrame* frame = frame_it.frame();
12618
12619     ScopeIterator it(isolate, frame, inlined_jsframe_index);
12620     res = SetScopeVariableValue(&it, index, variable_name, new_value);
12621   } else {
12622     CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
12623     ScopeIterator it(isolate, fun);
12624     res = SetScopeVariableValue(&it, index, variable_name, new_value);
12625   }
12626
12627   return isolate->heap()->ToBoolean(res);
12628 }
12629
12630
12631 RUNTIME_FUNCTION(Runtime_DebugPrintScopes) {
12632   HandleScope scope(isolate);
12633   DCHECK(args.length() == 0);
12634
12635 #ifdef DEBUG
12636   // Print the scopes for the top frame.
12637   StackFrameLocator locator(isolate);
12638   JavaScriptFrame* frame = locator.FindJavaScriptFrame(0);
12639   for (ScopeIterator it(isolate, frame, 0);
12640        !it.Done();
12641        it.Next()) {
12642     it.DebugPrint();
12643   }
12644 #endif
12645   return isolate->heap()->undefined_value();
12646 }
12647
12648
12649 RUNTIME_FUNCTION(Runtime_GetThreadCount) {
12650   HandleScope scope(isolate);
12651   DCHECK(args.length() == 1);
12652   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
12653   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
12654
12655   // Count all archived V8 threads.
12656   int n = 0;
12657   for (ThreadState* thread =
12658           isolate->thread_manager()->FirstThreadStateInUse();
12659        thread != NULL;
12660        thread = thread->Next()) {
12661     n++;
12662   }
12663
12664   // Total number of threads is current thread and archived threads.
12665   return Smi::FromInt(n + 1);
12666 }
12667
12668
12669 static const int kThreadDetailsCurrentThreadIndex = 0;
12670 static const int kThreadDetailsThreadIdIndex = 1;
12671 static const int kThreadDetailsSize = 2;
12672
12673 // Return an array with thread details
12674 // args[0]: number: break id
12675 // args[1]: number: thread index
12676 //
12677 // The array returned contains the following information:
12678 // 0: Is current thread?
12679 // 1: Thread id
12680 RUNTIME_FUNCTION(Runtime_GetThreadDetails) {
12681   HandleScope scope(isolate);
12682   DCHECK(args.length() == 2);
12683   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
12684   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
12685
12686   CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
12687
12688   // Allocate array for result.
12689   Handle<FixedArray> details =
12690       isolate->factory()->NewFixedArray(kThreadDetailsSize);
12691
12692   // Thread index 0 is current thread.
12693   if (index == 0) {
12694     // Fill the details.
12695     details->set(kThreadDetailsCurrentThreadIndex,
12696                  isolate->heap()->true_value());
12697     details->set(kThreadDetailsThreadIdIndex,
12698                  Smi::FromInt(ThreadId::Current().ToInteger()));
12699   } else {
12700     // Find the thread with the requested index.
12701     int n = 1;
12702     ThreadState* thread =
12703         isolate->thread_manager()->FirstThreadStateInUse();
12704     while (index != n && thread != NULL) {
12705       thread = thread->Next();
12706       n++;
12707     }
12708     if (thread == NULL) {
12709       return isolate->heap()->undefined_value();
12710     }
12711
12712     // Fill the details.
12713     details->set(kThreadDetailsCurrentThreadIndex,
12714                  isolate->heap()->false_value());
12715     details->set(kThreadDetailsThreadIdIndex,
12716                  Smi::FromInt(thread->id().ToInteger()));
12717   }
12718
12719   // Convert to JS array and return.
12720   return *isolate->factory()->NewJSArrayWithElements(details);
12721 }
12722
12723
12724 // Sets the disable break state
12725 // args[0]: disable break state
12726 RUNTIME_FUNCTION(Runtime_SetDisableBreak) {
12727   HandleScope scope(isolate);
12728   DCHECK(args.length() == 1);
12729   CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 0);
12730   isolate->debug()->set_disable_break(disable_break);
12731   return  isolate->heap()->undefined_value();
12732 }
12733
12734
12735 static bool IsPositionAlignmentCodeCorrect(int alignment) {
12736   return alignment == STATEMENT_ALIGNED || alignment == BREAK_POSITION_ALIGNED;
12737 }
12738
12739
12740 RUNTIME_FUNCTION(Runtime_GetBreakLocations) {
12741   HandleScope scope(isolate);
12742   DCHECK(args.length() == 2);
12743
12744   CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
12745   CONVERT_NUMBER_CHECKED(int32_t, statement_aligned_code, Int32, args[1]);
12746
12747   if (!IsPositionAlignmentCodeCorrect(statement_aligned_code)) {
12748     return isolate->ThrowIllegalOperation();
12749   }
12750   BreakPositionAlignment alignment =
12751       static_cast<BreakPositionAlignment>(statement_aligned_code);
12752
12753   Handle<SharedFunctionInfo> shared(fun->shared());
12754   // Find the number of break points
12755   Handle<Object> break_locations =
12756       Debug::GetSourceBreakLocations(shared, alignment);
12757   if (break_locations->IsUndefined()) return isolate->heap()->undefined_value();
12758   // Return array as JS array
12759   return *isolate->factory()->NewJSArrayWithElements(
12760       Handle<FixedArray>::cast(break_locations));
12761 }
12762
12763
12764 // Set a break point in a function.
12765 // args[0]: function
12766 // args[1]: number: break source position (within the function source)
12767 // args[2]: number: break point object
12768 RUNTIME_FUNCTION(Runtime_SetFunctionBreakPoint) {
12769   HandleScope scope(isolate);
12770   DCHECK(args.length() == 3);
12771   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
12772   CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
12773   RUNTIME_ASSERT(source_position >= function->shared()->start_position() &&
12774                  source_position <= function->shared()->end_position());
12775   CONVERT_ARG_HANDLE_CHECKED(Object, break_point_object_arg, 2);
12776
12777   // Set break point.
12778   RUNTIME_ASSERT(isolate->debug()->SetBreakPoint(
12779       function, break_point_object_arg, &source_position));
12780
12781   return Smi::FromInt(source_position);
12782 }
12783
12784
12785 // Changes the state of a break point in a script and returns source position
12786 // where break point was set. NOTE: Regarding performance see the NOTE for
12787 // GetScriptFromScriptData.
12788 // args[0]: script to set break point in
12789 // args[1]: number: break source position (within the script source)
12790 // args[2]: number, breakpoint position alignment
12791 // args[3]: number: break point object
12792 RUNTIME_FUNCTION(Runtime_SetScriptBreakPoint) {
12793   HandleScope scope(isolate);
12794   DCHECK(args.length() == 4);
12795   CONVERT_ARG_HANDLE_CHECKED(JSValue, wrapper, 0);
12796   CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
12797   RUNTIME_ASSERT(source_position >= 0);
12798   CONVERT_NUMBER_CHECKED(int32_t, statement_aligned_code, Int32, args[2]);
12799   CONVERT_ARG_HANDLE_CHECKED(Object, break_point_object_arg, 3);
12800
12801   if (!IsPositionAlignmentCodeCorrect(statement_aligned_code)) {
12802     return isolate->ThrowIllegalOperation();
12803   }
12804   BreakPositionAlignment alignment =
12805       static_cast<BreakPositionAlignment>(statement_aligned_code);
12806
12807   // Get the script from the script wrapper.
12808   RUNTIME_ASSERT(wrapper->value()->IsScript());
12809   Handle<Script> script(Script::cast(wrapper->value()));
12810
12811   // Set break point.
12812   if (!isolate->debug()->SetBreakPointForScript(script, break_point_object_arg,
12813                                                 &source_position,
12814                                                 alignment)) {
12815     return isolate->heap()->undefined_value();
12816   }
12817
12818   return Smi::FromInt(source_position);
12819 }
12820
12821
12822 // Clear a break point
12823 // args[0]: number: break point object
12824 RUNTIME_FUNCTION(Runtime_ClearBreakPoint) {
12825   HandleScope scope(isolate);
12826   DCHECK(args.length() == 1);
12827   CONVERT_ARG_HANDLE_CHECKED(Object, break_point_object_arg, 0);
12828
12829   // Clear break point.
12830   isolate->debug()->ClearBreakPoint(break_point_object_arg);
12831
12832   return isolate->heap()->undefined_value();
12833 }
12834
12835
12836 // Change the state of break on exceptions.
12837 // args[0]: Enum value indicating whether to affect caught/uncaught exceptions.
12838 // args[1]: Boolean indicating on/off.
12839 RUNTIME_FUNCTION(Runtime_ChangeBreakOnException) {
12840   HandleScope scope(isolate);
12841   DCHECK(args.length() == 2);
12842   CONVERT_NUMBER_CHECKED(uint32_t, type_arg, Uint32, args[0]);
12843   CONVERT_BOOLEAN_ARG_CHECKED(enable, 1);
12844
12845   // If the number doesn't match an enum value, the ChangeBreakOnException
12846   // function will default to affecting caught exceptions.
12847   ExceptionBreakType type = static_cast<ExceptionBreakType>(type_arg);
12848   // Update break point state.
12849   isolate->debug()->ChangeBreakOnException(type, enable);
12850   return isolate->heap()->undefined_value();
12851 }
12852
12853
12854 // Returns the state of break on exceptions
12855 // args[0]: boolean indicating uncaught exceptions
12856 RUNTIME_FUNCTION(Runtime_IsBreakOnException) {
12857   HandleScope scope(isolate);
12858   DCHECK(args.length() == 1);
12859   CONVERT_NUMBER_CHECKED(uint32_t, type_arg, Uint32, args[0]);
12860
12861   ExceptionBreakType type = static_cast<ExceptionBreakType>(type_arg);
12862   bool result = isolate->debug()->IsBreakOnException(type);
12863   return Smi::FromInt(result);
12864 }
12865
12866
12867 // Prepare for stepping
12868 // args[0]: break id for checking execution state
12869 // args[1]: step action from the enumeration StepAction
12870 // args[2]: number of times to perform the step, for step out it is the number
12871 //          of frames to step down.
12872 RUNTIME_FUNCTION(Runtime_PrepareStep) {
12873   HandleScope scope(isolate);
12874   DCHECK(args.length() == 4);
12875   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
12876   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
12877
12878   if (!args[1]->IsNumber() || !args[2]->IsNumber()) {
12879     return isolate->Throw(isolate->heap()->illegal_argument_string());
12880   }
12881
12882   CONVERT_NUMBER_CHECKED(int, wrapped_frame_id, Int32, args[3]);
12883
12884   StackFrame::Id frame_id;
12885   if (wrapped_frame_id == 0) {
12886     frame_id = StackFrame::NO_ID;
12887   } else {
12888     frame_id = UnwrapFrameId(wrapped_frame_id);
12889   }
12890
12891   // Get the step action and check validity.
12892   StepAction step_action = static_cast<StepAction>(NumberToInt32(args[1]));
12893   if (step_action != StepIn &&
12894       step_action != StepNext &&
12895       step_action != StepOut &&
12896       step_action != StepInMin &&
12897       step_action != StepMin) {
12898     return isolate->Throw(isolate->heap()->illegal_argument_string());
12899   }
12900
12901   if (frame_id != StackFrame::NO_ID && step_action != StepNext &&
12902       step_action != StepMin && step_action != StepOut) {
12903     return isolate->ThrowIllegalOperation();
12904   }
12905
12906   // Get the number of steps.
12907   int step_count = NumberToInt32(args[2]);
12908   if (step_count < 1) {
12909     return isolate->Throw(isolate->heap()->illegal_argument_string());
12910   }
12911
12912   // Clear all current stepping setup.
12913   isolate->debug()->ClearStepping();
12914
12915   // Prepare step.
12916   isolate->debug()->PrepareStep(static_cast<StepAction>(step_action),
12917                                 step_count,
12918                                 frame_id);
12919   return isolate->heap()->undefined_value();
12920 }
12921
12922
12923 // Clear all stepping set by PrepareStep.
12924 RUNTIME_FUNCTION(Runtime_ClearStepping) {
12925   HandleScope scope(isolate);
12926   DCHECK(args.length() == 0);
12927   isolate->debug()->ClearStepping();
12928   return isolate->heap()->undefined_value();
12929 }
12930
12931
12932 // Helper function to find or create the arguments object for
12933 // Runtime_DebugEvaluate.
12934 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeArgumentsObject(
12935     Isolate* isolate,
12936     Handle<JSObject> target,
12937     Handle<JSFunction> function) {
12938   // Do not materialize the arguments object for eval or top-level code.
12939   // Skip if "arguments" is already taken.
12940   if (!function->shared()->is_function()) return target;
12941   Maybe<bool> maybe = JSReceiver::HasOwnProperty(
12942       target, isolate->factory()->arguments_string());
12943   if (!maybe.has_value) return MaybeHandle<JSObject>();
12944   if (maybe.value) return target;
12945
12946   // FunctionGetArguments can't throw an exception.
12947   Handle<JSObject> arguments = Handle<JSObject>::cast(
12948       Accessors::FunctionGetArguments(function));
12949   Handle<String> arguments_str = isolate->factory()->arguments_string();
12950   RETURN_ON_EXCEPTION(
12951       isolate,
12952       Runtime::DefineObjectProperty(target, arguments_str, arguments, NONE),
12953       JSObject);
12954   return target;
12955 }
12956
12957
12958 // Compile and evaluate source for the given context.
12959 static MaybeHandle<Object> DebugEvaluate(Isolate* isolate,
12960                                          Handle<Context> context,
12961                                          Handle<Object> context_extension,
12962                                          Handle<Object> receiver,
12963                                          Handle<String> source) {
12964   if (context_extension->IsJSObject()) {
12965     Handle<JSObject> extension = Handle<JSObject>::cast(context_extension);
12966     Handle<JSFunction> closure(context->closure(), isolate);
12967     context = isolate->factory()->NewWithContext(closure, context, extension);
12968   }
12969
12970   Handle<JSFunction> eval_fun;
12971   ASSIGN_RETURN_ON_EXCEPTION(
12972       isolate, eval_fun,
12973       Compiler::GetFunctionFromEval(source,
12974                                     context,
12975                                     SLOPPY,
12976                                     NO_PARSE_RESTRICTION,
12977                                     RelocInfo::kNoPosition),
12978       Object);
12979
12980   Handle<Object> result;
12981   ASSIGN_RETURN_ON_EXCEPTION(
12982       isolate, result,
12983       Execution::Call(isolate, eval_fun, receiver, 0, NULL),
12984       Object);
12985
12986   // Skip the global proxy as it has no properties and always delegates to the
12987   // real global object.
12988   if (result->IsJSGlobalProxy()) {
12989     PrototypeIterator iter(isolate, result);
12990     // TODO(verwaest): This will crash when the global proxy is detached.
12991     result = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
12992   }
12993
12994   // Clear the oneshot breakpoints so that the debugger does not step further.
12995   isolate->debug()->ClearStepping();
12996   return result;
12997 }
12998
12999
13000 // Evaluate a piece of JavaScript in the context of a stack frame for
13001 // debugging.  Things that need special attention are:
13002 // - Parameters and stack-allocated locals need to be materialized.  Altered
13003 //   values need to be written back to the stack afterwards.
13004 // - The arguments object needs to materialized.
13005 RUNTIME_FUNCTION(Runtime_DebugEvaluate) {
13006   HandleScope scope(isolate);
13007
13008   // Check the execution state and decode arguments frame and source to be
13009   // evaluated.
13010   DCHECK(args.length() == 6);
13011   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
13012   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
13013
13014   CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
13015   CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
13016   CONVERT_ARG_HANDLE_CHECKED(String, source, 3);
13017   CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 4);
13018   CONVERT_ARG_HANDLE_CHECKED(Object, context_extension, 5);
13019
13020   // Handle the processing of break.
13021   DisableBreak disable_break_scope(isolate->debug(), disable_break);
13022
13023   // Get the frame where the debugging is performed.
13024   StackFrame::Id id = UnwrapFrameId(wrapped_id);
13025   JavaScriptFrameIterator it(isolate, id);
13026   JavaScriptFrame* frame = it.frame();
13027   FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate);
13028   Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction()));
13029
13030   // Traverse the saved contexts chain to find the active context for the
13031   // selected frame.
13032   SaveContext* save = FindSavedContextForFrame(isolate, frame);
13033
13034   SaveContext savex(isolate);
13035   isolate->set_context(*(save->context()));
13036
13037   // Evaluate on the context of the frame.
13038   Handle<Context> context(Context::cast(frame->context()));
13039   DCHECK(!context.is_null());
13040
13041   // Materialize stack locals and the arguments object.
13042   Handle<JSObject> materialized =
13043       isolate->factory()->NewJSObject(isolate->object_function());
13044
13045   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
13046       isolate, materialized,
13047       MaterializeStackLocalsWithFrameInspector(
13048           isolate, materialized, function, &frame_inspector));
13049
13050   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
13051       isolate, materialized,
13052       MaterializeArgumentsObject(isolate, materialized, function));
13053
13054   // Add the materialized object in a with-scope to shadow the stack locals.
13055   context = isolate->factory()->NewWithContext(function, context, materialized);
13056
13057   Handle<Object> receiver(frame->receiver(), isolate);
13058   Handle<Object> result;
13059   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
13060       isolate, result,
13061       DebugEvaluate(isolate, context, context_extension, receiver, source));
13062
13063   // Write back potential changes to materialized stack locals to the stack.
13064   UpdateStackLocalsFromMaterializedObject(
13065       isolate, materialized, function, frame, inlined_jsframe_index);
13066
13067   return *result;
13068 }
13069
13070
13071 RUNTIME_FUNCTION(Runtime_DebugEvaluateGlobal) {
13072   HandleScope scope(isolate);
13073
13074   // Check the execution state and decode arguments frame and source to be
13075   // evaluated.
13076   DCHECK(args.length() == 4);
13077   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
13078   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
13079
13080   CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
13081   CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 2);
13082   CONVERT_ARG_HANDLE_CHECKED(Object, context_extension, 3);
13083
13084   // Handle the processing of break.
13085   DisableBreak disable_break_scope(isolate->debug(), disable_break);
13086
13087   // Enter the top context from before the debugger was invoked.
13088   SaveContext save(isolate);
13089   SaveContext* top = &save;
13090   while (top != NULL && *top->context() == *isolate->debug()->debug_context()) {
13091     top = top->prev();
13092   }
13093   if (top != NULL) {
13094     isolate->set_context(*top->context());
13095   }
13096
13097   // Get the native context now set to the top context from before the
13098   // debugger was invoked.
13099   Handle<Context> context = isolate->native_context();
13100   Handle<JSObject> receiver(context->global_proxy());
13101   Handle<Object> result;
13102   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
13103       isolate, result,
13104       DebugEvaluate(isolate, context, context_extension, receiver, source));
13105   return *result;
13106 }
13107
13108
13109 RUNTIME_FUNCTION(Runtime_DebugGetLoadedScripts) {
13110   HandleScope scope(isolate);
13111   DCHECK(args.length() == 0);
13112
13113   // Fill the script objects.
13114   Handle<FixedArray> instances = isolate->debug()->GetLoadedScripts();
13115
13116   // Convert the script objects to proper JS objects.
13117   for (int i = 0; i < instances->length(); i++) {
13118     Handle<Script> script = Handle<Script>(Script::cast(instances->get(i)));
13119     // Get the script wrapper in a local handle before calling GetScriptWrapper,
13120     // because using
13121     //   instances->set(i, *GetScriptWrapper(script))
13122     // is unsafe as GetScriptWrapper might call GC and the C++ compiler might
13123     // already have dereferenced the instances handle.
13124     Handle<JSObject> wrapper = Script::GetWrapper(script);
13125     instances->set(i, *wrapper);
13126   }
13127
13128   // Return result as a JS array.
13129   Handle<JSObject> result =
13130       isolate->factory()->NewJSObject(isolate->array_function());
13131   JSArray::SetContent(Handle<JSArray>::cast(result), instances);
13132   return *result;
13133 }
13134
13135
13136 // Helper function used by Runtime_DebugReferencedBy below.
13137 static int DebugReferencedBy(HeapIterator* iterator,
13138                              JSObject* target,
13139                              Object* instance_filter, int max_references,
13140                              FixedArray* instances, int instances_size,
13141                              JSFunction* arguments_function) {
13142   Isolate* isolate = target->GetIsolate();
13143   SealHandleScope shs(isolate);
13144   DisallowHeapAllocation no_allocation;
13145
13146   // Iterate the heap.
13147   int count = 0;
13148   JSObject* last = NULL;
13149   HeapObject* heap_obj = NULL;
13150   while (((heap_obj = iterator->next()) != NULL) &&
13151          (max_references == 0 || count < max_references)) {
13152     // Only look at all JSObjects.
13153     if (heap_obj->IsJSObject()) {
13154       // Skip context extension objects and argument arrays as these are
13155       // checked in the context of functions using them.
13156       JSObject* obj = JSObject::cast(heap_obj);
13157       if (obj->IsJSContextExtensionObject() ||
13158           obj->map()->constructor() == arguments_function) {
13159         continue;
13160       }
13161
13162       // Check if the JS object has a reference to the object looked for.
13163       if (obj->ReferencesObject(target)) {
13164         // Check instance filter if supplied. This is normally used to avoid
13165         // references from mirror objects (see Runtime_IsInPrototypeChain).
13166         if (!instance_filter->IsUndefined()) {
13167           for (PrototypeIterator iter(isolate, obj); !iter.IsAtEnd();
13168                iter.Advance()) {
13169             if (iter.GetCurrent() == instance_filter) {
13170               obj = NULL;  // Don't add this object.
13171               break;
13172             }
13173           }
13174         }
13175
13176         if (obj != NULL) {
13177           // Valid reference found add to instance array if supplied an update
13178           // count.
13179           if (instances != NULL && count < instances_size) {
13180             instances->set(count, obj);
13181           }
13182           last = obj;
13183           count++;
13184         }
13185       }
13186     }
13187   }
13188
13189   // Check for circular reference only. This can happen when the object is only
13190   // referenced from mirrors and has a circular reference in which case the
13191   // object is not really alive and would have been garbage collected if not
13192   // referenced from the mirror.
13193   if (count == 1 && last == target) {
13194     count = 0;
13195   }
13196
13197   // Return the number of referencing objects found.
13198   return count;
13199 }
13200
13201
13202 // Scan the heap for objects with direct references to an object
13203 // args[0]: the object to find references to
13204 // args[1]: constructor function for instances to exclude (Mirror)
13205 // args[2]: the the maximum number of objects to return
13206 RUNTIME_FUNCTION(Runtime_DebugReferencedBy) {
13207   HandleScope scope(isolate);
13208   DCHECK(args.length() == 3);
13209
13210   // Check parameters.
13211   CONVERT_ARG_HANDLE_CHECKED(JSObject, target, 0);
13212   CONVERT_ARG_HANDLE_CHECKED(Object, instance_filter, 1);
13213   RUNTIME_ASSERT(instance_filter->IsUndefined() ||
13214                  instance_filter->IsJSObject());
13215   CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[2]);
13216   RUNTIME_ASSERT(max_references >= 0);
13217
13218
13219   // Get the constructor function for context extension and arguments array.
13220   Handle<JSFunction> arguments_function(
13221       JSFunction::cast(isolate->sloppy_arguments_map()->constructor()));
13222
13223   // Get the number of referencing objects.
13224   int count;
13225   // First perform a full GC in order to avoid dead objects and to make the heap
13226   // iterable.
13227   Heap* heap = isolate->heap();
13228   heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "%DebugConstructedBy");
13229   {
13230     HeapIterator heap_iterator(heap);
13231     count = DebugReferencedBy(&heap_iterator,
13232                               *target, *instance_filter, max_references,
13233                               NULL, 0, *arguments_function);
13234   }
13235
13236   // Allocate an array to hold the result.
13237   Handle<FixedArray> instances = isolate->factory()->NewFixedArray(count);
13238
13239   // Fill the referencing objects.
13240   {
13241     HeapIterator heap_iterator(heap);
13242     count = DebugReferencedBy(&heap_iterator,
13243                               *target, *instance_filter, max_references,
13244                               *instances, count, *arguments_function);
13245   }
13246
13247   // Return result as JS array.
13248   Handle<JSFunction> constructor = isolate->array_function();
13249
13250   Handle<JSObject> result = isolate->factory()->NewJSObject(constructor);
13251   JSArray::SetContent(Handle<JSArray>::cast(result), instances);
13252   return *result;
13253 }
13254
13255
13256 // Helper function used by Runtime_DebugConstructedBy below.
13257 static int DebugConstructedBy(HeapIterator* iterator,
13258                               JSFunction* constructor,
13259                               int max_references,
13260                               FixedArray* instances,
13261                               int instances_size) {
13262   DisallowHeapAllocation no_allocation;
13263
13264   // Iterate the heap.
13265   int count = 0;
13266   HeapObject* heap_obj = NULL;
13267   while (((heap_obj = iterator->next()) != NULL) &&
13268          (max_references == 0 || count < max_references)) {
13269     // Only look at all JSObjects.
13270     if (heap_obj->IsJSObject()) {
13271       JSObject* obj = JSObject::cast(heap_obj);
13272       if (obj->map()->constructor() == constructor) {
13273         // Valid reference found add to instance array if supplied an update
13274         // count.
13275         if (instances != NULL && count < instances_size) {
13276           instances->set(count, obj);
13277         }
13278         count++;
13279       }
13280     }
13281   }
13282
13283   // Return the number of referencing objects found.
13284   return count;
13285 }
13286
13287
13288 // Scan the heap for objects constructed by a specific function.
13289 // args[0]: the constructor to find instances of
13290 // args[1]: the the maximum number of objects to return
13291 RUNTIME_FUNCTION(Runtime_DebugConstructedBy) {
13292   HandleScope scope(isolate);
13293   DCHECK(args.length() == 2);
13294
13295
13296   // Check parameters.
13297   CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, 0);
13298   CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[1]);
13299   RUNTIME_ASSERT(max_references >= 0);
13300
13301   // Get the number of referencing objects.
13302   int count;
13303   // First perform a full GC in order to avoid dead objects and to make the heap
13304   // iterable.
13305   Heap* heap = isolate->heap();
13306   heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "%DebugConstructedBy");
13307   {
13308     HeapIterator heap_iterator(heap);
13309     count = DebugConstructedBy(&heap_iterator,
13310                                *constructor,
13311                                max_references,
13312                                NULL,
13313                                0);
13314   }
13315
13316   // Allocate an array to hold the result.
13317   Handle<FixedArray> instances = isolate->factory()->NewFixedArray(count);
13318
13319   // Fill the referencing objects.
13320   {
13321     HeapIterator heap_iterator2(heap);
13322     count = DebugConstructedBy(&heap_iterator2,
13323                                *constructor,
13324                                max_references,
13325                                *instances,
13326                                count);
13327   }
13328
13329   // Return result as JS array.
13330   Handle<JSFunction> array_function = isolate->array_function();
13331   Handle<JSObject> result = isolate->factory()->NewJSObject(array_function);
13332   JSArray::SetContent(Handle<JSArray>::cast(result), instances);
13333   return *result;
13334 }
13335
13336
13337 // Find the effective prototype object as returned by __proto__.
13338 // args[0]: the object to find the prototype for.
13339 RUNTIME_FUNCTION(Runtime_DebugGetPrototype) {
13340   HandleScope shs(isolate);
13341   DCHECK(args.length() == 1);
13342   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
13343   return *GetPrototypeSkipHiddenPrototypes(isolate, obj);
13344 }
13345
13346
13347 // Patches script source (should be called upon BeforeCompile event).
13348 RUNTIME_FUNCTION(Runtime_DebugSetScriptSource) {
13349   HandleScope scope(isolate);
13350   DCHECK(args.length() == 2);
13351
13352   CONVERT_ARG_HANDLE_CHECKED(JSValue, script_wrapper, 0);
13353   CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
13354
13355   RUNTIME_ASSERT(script_wrapper->value()->IsScript());
13356   Handle<Script> script(Script::cast(script_wrapper->value()));
13357
13358   int compilation_state = script->compilation_state();
13359   RUNTIME_ASSERT(compilation_state == Script::COMPILATION_STATE_INITIAL);
13360   script->set_source(*source);
13361
13362   return isolate->heap()->undefined_value();
13363 }
13364
13365
13366 RUNTIME_FUNCTION(Runtime_SystemBreak) {
13367   SealHandleScope shs(isolate);
13368   DCHECK(args.length() == 0);
13369   base::OS::DebugBreak();
13370   return isolate->heap()->undefined_value();
13371 }
13372
13373
13374 RUNTIME_FUNCTION(Runtime_DebugDisassembleFunction) {
13375   HandleScope scope(isolate);
13376 #ifdef DEBUG
13377   DCHECK(args.length() == 1);
13378   // Get the function and make sure it is compiled.
13379   CONVERT_ARG_HANDLE_CHECKED(JSFunction, func, 0);
13380   if (!Compiler::EnsureCompiled(func, KEEP_EXCEPTION)) {
13381     return isolate->heap()->exception();
13382   }
13383   OFStream os(stdout);
13384   func->code()->Print(os);
13385   os << endl;
13386 #endif  // DEBUG
13387   return isolate->heap()->undefined_value();
13388 }
13389
13390
13391 RUNTIME_FUNCTION(Runtime_DebugDisassembleConstructor) {
13392   HandleScope scope(isolate);
13393 #ifdef DEBUG
13394   DCHECK(args.length() == 1);
13395   // Get the function and make sure it is compiled.
13396   CONVERT_ARG_HANDLE_CHECKED(JSFunction, func, 0);
13397   if (!Compiler::EnsureCompiled(func, KEEP_EXCEPTION)) {
13398     return isolate->heap()->exception();
13399   }
13400   OFStream os(stdout);
13401   func->shared()->construct_stub()->Print(os);
13402   os << endl;
13403 #endif  // DEBUG
13404   return isolate->heap()->undefined_value();
13405 }
13406
13407
13408 RUNTIME_FUNCTION(Runtime_FunctionGetInferredName) {
13409   SealHandleScope shs(isolate);
13410   DCHECK(args.length() == 1);
13411
13412   CONVERT_ARG_CHECKED(JSFunction, f, 0);
13413   return f->shared()->inferred_name();
13414 }
13415
13416
13417 static int FindSharedFunctionInfosForScript(HeapIterator* iterator,
13418                                             Script* script,
13419                                             FixedArray* buffer) {
13420   DisallowHeapAllocation no_allocation;
13421   int counter = 0;
13422   int buffer_size = buffer->length();
13423   for (HeapObject* obj = iterator->next();
13424        obj != NULL;
13425        obj = iterator->next()) {
13426     DCHECK(obj != NULL);
13427     if (!obj->IsSharedFunctionInfo()) {
13428       continue;
13429     }
13430     SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj);
13431     if (shared->script() != script) {
13432       continue;
13433     }
13434     if (counter < buffer_size) {
13435       buffer->set(counter, shared);
13436     }
13437     counter++;
13438   }
13439   return counter;
13440 }
13441
13442
13443 // For a script finds all SharedFunctionInfo's in the heap that points
13444 // to this script. Returns JSArray of SharedFunctionInfo wrapped
13445 // in OpaqueReferences.
13446 RUNTIME_FUNCTION(Runtime_LiveEditFindSharedFunctionInfosForScript) {
13447   HandleScope scope(isolate);
13448   CHECK(isolate->debug()->live_edit_enabled());
13449   DCHECK(args.length() == 1);
13450   CONVERT_ARG_CHECKED(JSValue, script_value, 0);
13451
13452   RUNTIME_ASSERT(script_value->value()->IsScript());
13453   Handle<Script> script = Handle<Script>(Script::cast(script_value->value()));
13454
13455   const int kBufferSize = 32;
13456
13457   Handle<FixedArray> array;
13458   array = isolate->factory()->NewFixedArray(kBufferSize);
13459   int number;
13460   Heap* heap = isolate->heap();
13461   {
13462     HeapIterator heap_iterator(heap);
13463     Script* scr = *script;
13464     FixedArray* arr = *array;
13465     number = FindSharedFunctionInfosForScript(&heap_iterator, scr, arr);
13466   }
13467   if (number > kBufferSize) {
13468     array = isolate->factory()->NewFixedArray(number);
13469     HeapIterator heap_iterator(heap);
13470     Script* scr = *script;
13471     FixedArray* arr = *array;
13472     FindSharedFunctionInfosForScript(&heap_iterator, scr, arr);
13473   }
13474
13475   Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements(array);
13476   result->set_length(Smi::FromInt(number));
13477
13478   LiveEdit::WrapSharedFunctionInfos(result);
13479
13480   return *result;
13481 }
13482
13483
13484 // For a script calculates compilation information about all its functions.
13485 // The script source is explicitly specified by the second argument.
13486 // The source of the actual script is not used, however it is important that
13487 // all generated code keeps references to this particular instance of script.
13488 // Returns a JSArray of compilation infos. The array is ordered so that
13489 // each function with all its descendant is always stored in a continues range
13490 // with the function itself going first. The root function is a script function.
13491 RUNTIME_FUNCTION(Runtime_LiveEditGatherCompileInfo) {
13492   HandleScope scope(isolate);
13493   CHECK(isolate->debug()->live_edit_enabled());
13494   DCHECK(args.length() == 2);
13495   CONVERT_ARG_CHECKED(JSValue, script, 0);
13496   CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
13497
13498   RUNTIME_ASSERT(script->value()->IsScript());
13499   Handle<Script> script_handle = Handle<Script>(Script::cast(script->value()));
13500
13501   Handle<JSArray> result;
13502   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
13503       isolate, result, LiveEdit::GatherCompileInfo(script_handle, source));
13504   return *result;
13505 }
13506
13507
13508 // Changes the source of the script to a new_source.
13509 // If old_script_name is provided (i.e. is a String), also creates a copy of
13510 // the script with its original source and sends notification to debugger.
13511 RUNTIME_FUNCTION(Runtime_LiveEditReplaceScript) {
13512   HandleScope scope(isolate);
13513   CHECK(isolate->debug()->live_edit_enabled());
13514   DCHECK(args.length() == 3);
13515   CONVERT_ARG_CHECKED(JSValue, original_script_value, 0);
13516   CONVERT_ARG_HANDLE_CHECKED(String, new_source, 1);
13517   CONVERT_ARG_HANDLE_CHECKED(Object, old_script_name, 2);
13518
13519   RUNTIME_ASSERT(original_script_value->value()->IsScript());
13520   Handle<Script> original_script(Script::cast(original_script_value->value()));
13521
13522   Handle<Object> old_script = LiveEdit::ChangeScriptSource(
13523       original_script,  new_source,  old_script_name);
13524
13525   if (old_script->IsScript()) {
13526     Handle<Script> script_handle = Handle<Script>::cast(old_script);
13527     return *Script::GetWrapper(script_handle);
13528   } else {
13529     return isolate->heap()->null_value();
13530   }
13531 }
13532
13533
13534 RUNTIME_FUNCTION(Runtime_LiveEditFunctionSourceUpdated) {
13535   HandleScope scope(isolate);
13536   CHECK(isolate->debug()->live_edit_enabled());
13537   DCHECK(args.length() == 1);
13538   CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_info, 0);
13539   RUNTIME_ASSERT(SharedInfoWrapper::IsInstance(shared_info));
13540
13541   LiveEdit::FunctionSourceUpdated(shared_info);
13542   return isolate->heap()->undefined_value();
13543 }
13544
13545
13546 // Replaces code of SharedFunctionInfo with a new one.
13547 RUNTIME_FUNCTION(Runtime_LiveEditReplaceFunctionCode) {
13548   HandleScope scope(isolate);
13549   CHECK(isolate->debug()->live_edit_enabled());
13550   DCHECK(args.length() == 2);
13551   CONVERT_ARG_HANDLE_CHECKED(JSArray, new_compile_info, 0);
13552   CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_info, 1);
13553   RUNTIME_ASSERT(SharedInfoWrapper::IsInstance(shared_info));
13554
13555   LiveEdit::ReplaceFunctionCode(new_compile_info, shared_info);
13556   return isolate->heap()->undefined_value();
13557 }
13558
13559
13560 // Connects SharedFunctionInfo to another script.
13561 RUNTIME_FUNCTION(Runtime_LiveEditFunctionSetScript) {
13562   HandleScope scope(isolate);
13563   CHECK(isolate->debug()->live_edit_enabled());
13564   DCHECK(args.length() == 2);
13565   CONVERT_ARG_HANDLE_CHECKED(Object, function_object, 0);
13566   CONVERT_ARG_HANDLE_CHECKED(Object, script_object, 1);
13567
13568   if (function_object->IsJSValue()) {
13569     Handle<JSValue> function_wrapper = Handle<JSValue>::cast(function_object);
13570     if (script_object->IsJSValue()) {
13571       RUNTIME_ASSERT(JSValue::cast(*script_object)->value()->IsScript());
13572       Script* script = Script::cast(JSValue::cast(*script_object)->value());
13573       script_object = Handle<Object>(script, isolate);
13574     }
13575     RUNTIME_ASSERT(function_wrapper->value()->IsSharedFunctionInfo());
13576     LiveEdit::SetFunctionScript(function_wrapper, script_object);
13577   } else {
13578     // Just ignore this. We may not have a SharedFunctionInfo for some functions
13579     // and we check it in this function.
13580   }
13581
13582   return isolate->heap()->undefined_value();
13583 }
13584
13585
13586 // In a code of a parent function replaces original function as embedded object
13587 // with a substitution one.
13588 RUNTIME_FUNCTION(Runtime_LiveEditReplaceRefToNestedFunction) {
13589   HandleScope scope(isolate);
13590   CHECK(isolate->debug()->live_edit_enabled());
13591   DCHECK(args.length() == 3);
13592
13593   CONVERT_ARG_HANDLE_CHECKED(JSValue, parent_wrapper, 0);
13594   CONVERT_ARG_HANDLE_CHECKED(JSValue, orig_wrapper, 1);
13595   CONVERT_ARG_HANDLE_CHECKED(JSValue, subst_wrapper, 2);
13596   RUNTIME_ASSERT(parent_wrapper->value()->IsSharedFunctionInfo());
13597   RUNTIME_ASSERT(orig_wrapper->value()->IsSharedFunctionInfo());
13598   RUNTIME_ASSERT(subst_wrapper->value()->IsSharedFunctionInfo());
13599
13600   LiveEdit::ReplaceRefToNestedFunction(
13601       parent_wrapper, orig_wrapper, subst_wrapper);
13602   return isolate->heap()->undefined_value();
13603 }
13604
13605
13606 // Updates positions of a shared function info (first parameter) according
13607 // to script source change. Text change is described in second parameter as
13608 // array of groups of 3 numbers:
13609 // (change_begin, change_end, change_end_new_position).
13610 // Each group describes a change in text; groups are sorted by change_begin.
13611 RUNTIME_FUNCTION(Runtime_LiveEditPatchFunctionPositions) {
13612   HandleScope scope(isolate);
13613   CHECK(isolate->debug()->live_edit_enabled());
13614   DCHECK(args.length() == 2);
13615   CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_array, 0);
13616   CONVERT_ARG_HANDLE_CHECKED(JSArray, position_change_array, 1);
13617   RUNTIME_ASSERT(SharedInfoWrapper::IsInstance(shared_array))
13618
13619   LiveEdit::PatchFunctionPositions(shared_array, position_change_array);
13620   return isolate->heap()->undefined_value();
13621 }
13622
13623
13624 // For array of SharedFunctionInfo's (each wrapped in JSValue)
13625 // checks that none of them have activations on stacks (of any thread).
13626 // Returns array of the same length with corresponding results of
13627 // LiveEdit::FunctionPatchabilityStatus type.
13628 RUNTIME_FUNCTION(Runtime_LiveEditCheckAndDropActivations) {
13629   HandleScope scope(isolate);
13630   CHECK(isolate->debug()->live_edit_enabled());
13631   DCHECK(args.length() == 2);
13632   CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_array, 0);
13633   CONVERT_BOOLEAN_ARG_CHECKED(do_drop, 1);
13634   RUNTIME_ASSERT(shared_array->length()->IsSmi());
13635   RUNTIME_ASSERT(shared_array->HasFastElements())
13636   int array_length = Smi::cast(shared_array->length())->value();
13637   for (int i = 0; i < array_length; i++) {
13638     Handle<Object> element =
13639         Object::GetElement(isolate, shared_array, i).ToHandleChecked();
13640     RUNTIME_ASSERT(
13641         element->IsJSValue() &&
13642         Handle<JSValue>::cast(element)->value()->IsSharedFunctionInfo());
13643   }
13644
13645   return *LiveEdit::CheckAndDropActivations(shared_array, do_drop);
13646 }
13647
13648
13649 // Compares 2 strings line-by-line, then token-wise and returns diff in form
13650 // of JSArray of triplets (pos1, pos1_end, pos2_end) describing list
13651 // of diff chunks.
13652 RUNTIME_FUNCTION(Runtime_LiveEditCompareStrings) {
13653   HandleScope scope(isolate);
13654   CHECK(isolate->debug()->live_edit_enabled());
13655   DCHECK(args.length() == 2);
13656   CONVERT_ARG_HANDLE_CHECKED(String, s1, 0);
13657   CONVERT_ARG_HANDLE_CHECKED(String, s2, 1);
13658
13659   return *LiveEdit::CompareStrings(s1, s2);
13660 }
13661
13662
13663 // Restarts a call frame and completely drops all frames above.
13664 // Returns true if successful. Otherwise returns undefined or an error message.
13665 RUNTIME_FUNCTION(Runtime_LiveEditRestartFrame) {
13666   HandleScope scope(isolate);
13667   CHECK(isolate->debug()->live_edit_enabled());
13668   DCHECK(args.length() == 2);
13669   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
13670   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
13671
13672   CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
13673   Heap* heap = isolate->heap();
13674
13675   // Find the relevant frame with the requested index.
13676   StackFrame::Id id = isolate->debug()->break_frame_id();
13677   if (id == StackFrame::NO_ID) {
13678     // If there are no JavaScript stack frames return undefined.
13679     return heap->undefined_value();
13680   }
13681
13682   JavaScriptFrameIterator it(isolate, id);
13683   int inlined_jsframe_index = FindIndexedNonNativeFrame(&it, index);
13684   if (inlined_jsframe_index == -1) return heap->undefined_value();
13685   // We don't really care what the inlined frame index is, since we are
13686   // throwing away the entire frame anyways.
13687   const char* error_message = LiveEdit::RestartFrame(it.frame());
13688   if (error_message) {
13689     return *(isolate->factory()->InternalizeUtf8String(error_message));
13690   }
13691   return heap->true_value();
13692 }
13693
13694
13695 // A testing entry. Returns statement position which is the closest to
13696 // source_position.
13697 RUNTIME_FUNCTION(Runtime_GetFunctionCodePositionFromSource) {
13698   HandleScope scope(isolate);
13699   CHECK(isolate->debug()->live_edit_enabled());
13700   DCHECK(args.length() == 2);
13701   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
13702   CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
13703
13704   Handle<Code> code(function->code(), isolate);
13705
13706   if (code->kind() != Code::FUNCTION &&
13707       code->kind() != Code::OPTIMIZED_FUNCTION) {
13708     return isolate->heap()->undefined_value();
13709   }
13710
13711   RelocIterator it(*code, RelocInfo::ModeMask(RelocInfo::STATEMENT_POSITION));
13712   int closest_pc = 0;
13713   int distance = kMaxInt;
13714   while (!it.done()) {
13715     int statement_position = static_cast<int>(it.rinfo()->data());
13716     // Check if this break point is closer that what was previously found.
13717     if (source_position <= statement_position &&
13718         statement_position - source_position < distance) {
13719       closest_pc =
13720           static_cast<int>(it.rinfo()->pc() - code->instruction_start());
13721       distance = statement_position - source_position;
13722       // Check whether we can't get any closer.
13723       if (distance == 0) break;
13724     }
13725     it.next();
13726   }
13727
13728   return Smi::FromInt(closest_pc);
13729 }
13730
13731
13732 // Calls specified function with or without entering the debugger.
13733 // This is used in unit tests to run code as if debugger is entered or simply
13734 // to have a stack with C++ frame in the middle.
13735 RUNTIME_FUNCTION(Runtime_ExecuteInDebugContext) {
13736   HandleScope scope(isolate);
13737   DCHECK(args.length() == 2);
13738   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
13739   CONVERT_BOOLEAN_ARG_CHECKED(without_debugger, 1);
13740
13741   MaybeHandle<Object> maybe_result;
13742   if (without_debugger) {
13743     maybe_result = Execution::Call(isolate,
13744                                    function,
13745                                    handle(function->global_proxy()),
13746                                    0,
13747                                    NULL);
13748   } else {
13749     DebugScope debug_scope(isolate->debug());
13750     maybe_result = Execution::Call(isolate,
13751                                    function,
13752                                    handle(function->global_proxy()),
13753                                    0,
13754                                    NULL);
13755   }
13756   Handle<Object> result;
13757   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, maybe_result);
13758   return *result;
13759 }
13760
13761
13762 // Sets a v8 flag.
13763 RUNTIME_FUNCTION(Runtime_SetFlags) {
13764   SealHandleScope shs(isolate);
13765   DCHECK(args.length() == 1);
13766   CONVERT_ARG_CHECKED(String, arg, 0);
13767   SmartArrayPointer<char> flags =
13768       arg->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
13769   FlagList::SetFlagsFromString(flags.get(), StrLength(flags.get()));
13770   return isolate->heap()->undefined_value();
13771 }
13772
13773
13774 // Performs a GC.
13775 // Presently, it only does a full GC.
13776 RUNTIME_FUNCTION(Runtime_CollectGarbage) {
13777   SealHandleScope shs(isolate);
13778   DCHECK(args.length() == 1);
13779   isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, "%CollectGarbage");
13780   return isolate->heap()->undefined_value();
13781 }
13782
13783
13784 // Gets the current heap usage.
13785 RUNTIME_FUNCTION(Runtime_GetHeapUsage) {
13786   SealHandleScope shs(isolate);
13787   DCHECK(args.length() == 0);
13788   int usage = static_cast<int>(isolate->heap()->SizeOfObjects());
13789   if (!Smi::IsValid(usage)) {
13790     return *isolate->factory()->NewNumberFromInt(usage);
13791   }
13792   return Smi::FromInt(usage);
13793 }
13794
13795
13796 #ifdef V8_I18N_SUPPORT
13797 RUNTIME_FUNCTION(Runtime_CanonicalizeLanguageTag) {
13798   HandleScope scope(isolate);
13799   Factory* factory = isolate->factory();
13800
13801   DCHECK(args.length() == 1);
13802   CONVERT_ARG_HANDLE_CHECKED(String, locale_id_str, 0);
13803
13804   v8::String::Utf8Value locale_id(v8::Utils::ToLocal(locale_id_str));
13805
13806   // Return value which denotes invalid language tag.
13807   const char* const kInvalidTag = "invalid-tag";
13808
13809   UErrorCode error = U_ZERO_ERROR;
13810   char icu_result[ULOC_FULLNAME_CAPACITY];
13811   int icu_length = 0;
13812
13813   uloc_forLanguageTag(*locale_id, icu_result, ULOC_FULLNAME_CAPACITY,
13814                       &icu_length, &error);
13815   if (U_FAILURE(error) || icu_length == 0) {
13816     return *factory->NewStringFromAsciiChecked(kInvalidTag);
13817   }
13818
13819   char result[ULOC_FULLNAME_CAPACITY];
13820
13821   // Force strict BCP47 rules.
13822   uloc_toLanguageTag(icu_result, result, ULOC_FULLNAME_CAPACITY, TRUE, &error);
13823
13824   if (U_FAILURE(error)) {
13825     return *factory->NewStringFromAsciiChecked(kInvalidTag);
13826   }
13827
13828   return *factory->NewStringFromAsciiChecked(result);
13829 }
13830
13831
13832 RUNTIME_FUNCTION(Runtime_AvailableLocalesOf) {
13833   HandleScope scope(isolate);
13834   Factory* factory = isolate->factory();
13835
13836   DCHECK(args.length() == 1);
13837   CONVERT_ARG_HANDLE_CHECKED(String, service, 0);
13838
13839   const icu::Locale* available_locales = NULL;
13840   int32_t count = 0;
13841
13842   if (service->IsUtf8EqualTo(CStrVector("collator"))) {
13843     available_locales = icu::Collator::getAvailableLocales(count);
13844   } else if (service->IsUtf8EqualTo(CStrVector("numberformat"))) {
13845     available_locales = icu::NumberFormat::getAvailableLocales(count);
13846   } else if (service->IsUtf8EqualTo(CStrVector("dateformat"))) {
13847     available_locales = icu::DateFormat::getAvailableLocales(count);
13848   } else if (service->IsUtf8EqualTo(CStrVector("breakiterator"))) {
13849     available_locales = icu::BreakIterator::getAvailableLocales(count);
13850   }
13851
13852   UErrorCode error = U_ZERO_ERROR;
13853   char result[ULOC_FULLNAME_CAPACITY];
13854   Handle<JSObject> locales =
13855       factory->NewJSObject(isolate->object_function());
13856
13857   for (int32_t i = 0; i < count; ++i) {
13858     const char* icu_name = available_locales[i].getName();
13859
13860     error = U_ZERO_ERROR;
13861     // No need to force strict BCP47 rules.
13862     uloc_toLanguageTag(icu_name, result, ULOC_FULLNAME_CAPACITY, FALSE, &error);
13863     if (U_FAILURE(error)) {
13864       // This shouldn't happen, but lets not break the user.
13865       continue;
13866     }
13867
13868     RETURN_FAILURE_ON_EXCEPTION(isolate,
13869         JSObject::SetOwnPropertyIgnoreAttributes(
13870             locales,
13871             factory->NewStringFromAsciiChecked(result),
13872             factory->NewNumber(i),
13873             NONE));
13874   }
13875
13876   return *locales;
13877 }
13878
13879
13880 RUNTIME_FUNCTION(Runtime_GetDefaultICULocale) {
13881   HandleScope scope(isolate);
13882   Factory* factory = isolate->factory();
13883
13884   DCHECK(args.length() == 0);
13885
13886   icu::Locale default_locale;
13887
13888   // Set the locale
13889   char result[ULOC_FULLNAME_CAPACITY];
13890   UErrorCode status = U_ZERO_ERROR;
13891   uloc_toLanguageTag(
13892       default_locale.getName(), result, ULOC_FULLNAME_CAPACITY, FALSE, &status);
13893   if (U_SUCCESS(status)) {
13894     return *factory->NewStringFromAsciiChecked(result);
13895   }
13896
13897   return *factory->NewStringFromStaticAscii("und");
13898 }
13899
13900
13901 RUNTIME_FUNCTION(Runtime_GetLanguageTagVariants) {
13902   HandleScope scope(isolate);
13903   Factory* factory = isolate->factory();
13904
13905   DCHECK(args.length() == 1);
13906
13907   CONVERT_ARG_HANDLE_CHECKED(JSArray, input, 0);
13908
13909   uint32_t length = static_cast<uint32_t>(input->length()->Number());
13910   // Set some limit to prevent fuzz tests from going OOM.
13911   // Can be bumped when callers' requirements change.
13912   RUNTIME_ASSERT(length < 100);
13913   Handle<FixedArray> output = factory->NewFixedArray(length);
13914   Handle<Name> maximized = factory->NewStringFromStaticAscii("maximized");
13915   Handle<Name> base = factory->NewStringFromStaticAscii("base");
13916   for (unsigned int i = 0; i < length; ++i) {
13917     Handle<Object> locale_id;
13918     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
13919         isolate, locale_id, Object::GetElement(isolate, input, i));
13920     if (!locale_id->IsString()) {
13921       return isolate->Throw(*factory->illegal_argument_string());
13922     }
13923
13924     v8::String::Utf8Value utf8_locale_id(
13925         v8::Utils::ToLocal(Handle<String>::cast(locale_id)));
13926
13927     UErrorCode error = U_ZERO_ERROR;
13928
13929     // Convert from BCP47 to ICU format.
13930     // de-DE-u-co-phonebk -> de_DE@collation=phonebook
13931     char icu_locale[ULOC_FULLNAME_CAPACITY];
13932     int icu_locale_length = 0;
13933     uloc_forLanguageTag(*utf8_locale_id, icu_locale, ULOC_FULLNAME_CAPACITY,
13934                         &icu_locale_length, &error);
13935     if (U_FAILURE(error) || icu_locale_length == 0) {
13936       return isolate->Throw(*factory->illegal_argument_string());
13937     }
13938
13939     // Maximize the locale.
13940     // de_DE@collation=phonebook -> de_Latn_DE@collation=phonebook
13941     char icu_max_locale[ULOC_FULLNAME_CAPACITY];
13942     uloc_addLikelySubtags(
13943         icu_locale, icu_max_locale, ULOC_FULLNAME_CAPACITY, &error);
13944
13945     // Remove extensions from maximized locale.
13946     // de_Latn_DE@collation=phonebook -> de_Latn_DE
13947     char icu_base_max_locale[ULOC_FULLNAME_CAPACITY];
13948     uloc_getBaseName(
13949         icu_max_locale, icu_base_max_locale, ULOC_FULLNAME_CAPACITY, &error);
13950
13951     // Get original name without extensions.
13952     // de_DE@collation=phonebook -> de_DE
13953     char icu_base_locale[ULOC_FULLNAME_CAPACITY];
13954     uloc_getBaseName(
13955         icu_locale, icu_base_locale, ULOC_FULLNAME_CAPACITY, &error);
13956
13957     // Convert from ICU locale format to BCP47 format.
13958     // de_Latn_DE -> de-Latn-DE
13959     char base_max_locale[ULOC_FULLNAME_CAPACITY];
13960     uloc_toLanguageTag(icu_base_max_locale, base_max_locale,
13961                        ULOC_FULLNAME_CAPACITY, FALSE, &error);
13962
13963     // de_DE -> de-DE
13964     char base_locale[ULOC_FULLNAME_CAPACITY];
13965     uloc_toLanguageTag(
13966         icu_base_locale, base_locale, ULOC_FULLNAME_CAPACITY, FALSE, &error);
13967
13968     if (U_FAILURE(error)) {
13969       return isolate->Throw(*factory->illegal_argument_string());
13970     }
13971
13972     Handle<JSObject> result = factory->NewJSObject(isolate->object_function());
13973     Handle<String> value = factory->NewStringFromAsciiChecked(base_max_locale);
13974     JSObject::AddProperty(result, maximized, value, NONE);
13975     value = factory->NewStringFromAsciiChecked(base_locale);
13976     JSObject::AddProperty(result, base, value, NONE);
13977     output->set(i, *result);
13978   }
13979
13980   Handle<JSArray> result = factory->NewJSArrayWithElements(output);
13981   result->set_length(Smi::FromInt(length));
13982   return *result;
13983 }
13984
13985
13986 RUNTIME_FUNCTION(Runtime_IsInitializedIntlObject) {
13987   HandleScope scope(isolate);
13988
13989   DCHECK(args.length() == 1);
13990
13991   CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
13992
13993   if (!input->IsJSObject()) return isolate->heap()->false_value();
13994   Handle<JSObject> obj = Handle<JSObject>::cast(input);
13995
13996   Handle<String> marker = isolate->factory()->intl_initialized_marker_string();
13997   Handle<Object> tag(obj->GetHiddenProperty(marker), isolate);
13998   return isolate->heap()->ToBoolean(!tag->IsTheHole());
13999 }
14000
14001
14002 RUNTIME_FUNCTION(Runtime_IsInitializedIntlObjectOfType) {
14003   HandleScope scope(isolate);
14004
14005   DCHECK(args.length() == 2);
14006
14007   CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
14008   CONVERT_ARG_HANDLE_CHECKED(String, expected_type, 1);
14009
14010   if (!input->IsJSObject()) return isolate->heap()->false_value();
14011   Handle<JSObject> obj = Handle<JSObject>::cast(input);
14012
14013   Handle<String> marker = isolate->factory()->intl_initialized_marker_string();
14014   Handle<Object> tag(obj->GetHiddenProperty(marker), isolate);
14015   return isolate->heap()->ToBoolean(
14016       tag->IsString() && String::cast(*tag)->Equals(*expected_type));
14017 }
14018
14019
14020 RUNTIME_FUNCTION(Runtime_MarkAsInitializedIntlObjectOfType) {
14021   HandleScope scope(isolate);
14022
14023   DCHECK(args.length() == 3);
14024
14025   CONVERT_ARG_HANDLE_CHECKED(JSObject, input, 0);
14026   CONVERT_ARG_HANDLE_CHECKED(String, type, 1);
14027   CONVERT_ARG_HANDLE_CHECKED(JSObject, impl, 2);
14028
14029   Handle<String> marker = isolate->factory()->intl_initialized_marker_string();
14030   JSObject::SetHiddenProperty(input, marker, type);
14031
14032   marker = isolate->factory()->intl_impl_object_string();
14033   JSObject::SetHiddenProperty(input, marker, impl);
14034
14035   return isolate->heap()->undefined_value();
14036 }
14037
14038
14039 RUNTIME_FUNCTION(Runtime_GetImplFromInitializedIntlObject) {
14040   HandleScope scope(isolate);
14041
14042   DCHECK(args.length() == 1);
14043
14044   CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
14045
14046   if (!input->IsJSObject()) {
14047     Vector< Handle<Object> > arguments = HandleVector(&input, 1);
14048     Handle<Object> type_error =
14049         isolate->factory()->NewTypeError("not_intl_object", arguments);
14050     return isolate->Throw(*type_error);
14051   }
14052
14053   Handle<JSObject> obj = Handle<JSObject>::cast(input);
14054
14055   Handle<String> marker = isolate->factory()->intl_impl_object_string();
14056   Handle<Object> impl(obj->GetHiddenProperty(marker), isolate);
14057   if (impl->IsTheHole()) {
14058     Vector< Handle<Object> > arguments = HandleVector(&obj, 1);
14059     Handle<Object> type_error =
14060         isolate->factory()->NewTypeError("not_intl_object", arguments);
14061     return isolate->Throw(*type_error);
14062   }
14063   return *impl;
14064 }
14065
14066
14067 RUNTIME_FUNCTION(Runtime_CreateDateTimeFormat) {
14068   HandleScope scope(isolate);
14069
14070   DCHECK(args.length() == 3);
14071
14072   CONVERT_ARG_HANDLE_CHECKED(String, locale, 0);
14073   CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1);
14074   CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2);
14075
14076   Handle<ObjectTemplateInfo> date_format_template =
14077       I18N::GetTemplate(isolate);
14078
14079   // Create an empty object wrapper.
14080   Handle<JSObject> local_object;
14081   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
14082       isolate, local_object,
14083       Execution::InstantiateObject(date_format_template));
14084
14085   // Set date time formatter as internal field of the resulting JS object.
14086   icu::SimpleDateFormat* date_format = DateFormat::InitializeDateTimeFormat(
14087       isolate, locale, options, resolved);
14088
14089   if (!date_format) return isolate->ThrowIllegalOperation();
14090
14091   local_object->SetInternalField(0, reinterpret_cast<Smi*>(date_format));
14092
14093   Factory* factory = isolate->factory();
14094   Handle<String> key = factory->NewStringFromStaticAscii("dateFormat");
14095   Handle<String> value = factory->NewStringFromStaticAscii("valid");
14096   JSObject::AddProperty(local_object, key, value, NONE);
14097
14098   // Make object handle weak so we can delete the data format once GC kicks in.
14099   Handle<Object> wrapper = isolate->global_handles()->Create(*local_object);
14100   GlobalHandles::MakeWeak(wrapper.location(),
14101                           reinterpret_cast<void*>(wrapper.location()),
14102                           DateFormat::DeleteDateFormat);
14103   return *local_object;
14104 }
14105
14106
14107 RUNTIME_FUNCTION(Runtime_InternalDateFormat) {
14108   HandleScope scope(isolate);
14109
14110   DCHECK(args.length() == 2);
14111
14112   CONVERT_ARG_HANDLE_CHECKED(JSObject, date_format_holder, 0);
14113   CONVERT_ARG_HANDLE_CHECKED(JSDate, date, 1);
14114
14115   Handle<Object> value;
14116   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
14117       isolate, value, Execution::ToNumber(isolate, date));
14118
14119   icu::SimpleDateFormat* date_format =
14120       DateFormat::UnpackDateFormat(isolate, date_format_holder);
14121   if (!date_format) return isolate->ThrowIllegalOperation();
14122
14123   icu::UnicodeString result;
14124   date_format->format(value->Number(), result);
14125
14126   Handle<String> result_str;
14127   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
14128       isolate, result_str,
14129       isolate->factory()->NewStringFromTwoByte(
14130           Vector<const uint16_t>(
14131               reinterpret_cast<const uint16_t*>(result.getBuffer()),
14132               result.length())));
14133   return *result_str;
14134 }
14135
14136
14137 RUNTIME_FUNCTION(Runtime_InternalDateParse) {
14138   HandleScope scope(isolate);
14139
14140   DCHECK(args.length() == 2);
14141
14142   CONVERT_ARG_HANDLE_CHECKED(JSObject, date_format_holder, 0);
14143   CONVERT_ARG_HANDLE_CHECKED(String, date_string, 1);
14144
14145   v8::String::Utf8Value utf8_date(v8::Utils::ToLocal(date_string));
14146   icu::UnicodeString u_date(icu::UnicodeString::fromUTF8(*utf8_date));
14147   icu::SimpleDateFormat* date_format =
14148       DateFormat::UnpackDateFormat(isolate, date_format_holder);
14149   if (!date_format) return isolate->ThrowIllegalOperation();
14150
14151   UErrorCode status = U_ZERO_ERROR;
14152   UDate date = date_format->parse(u_date, status);
14153   if (U_FAILURE(status)) return isolate->heap()->undefined_value();
14154
14155   Handle<Object> result;
14156   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
14157       isolate, result,
14158       Execution::NewDate(isolate, static_cast<double>(date)));
14159   DCHECK(result->IsJSDate());
14160   return *result;
14161 }
14162
14163
14164 RUNTIME_FUNCTION(Runtime_CreateNumberFormat) {
14165   HandleScope scope(isolate);
14166
14167   DCHECK(args.length() == 3);
14168
14169   CONVERT_ARG_HANDLE_CHECKED(String, locale, 0);
14170   CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1);
14171   CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2);
14172
14173   Handle<ObjectTemplateInfo> number_format_template =
14174       I18N::GetTemplate(isolate);
14175
14176   // Create an empty object wrapper.
14177   Handle<JSObject> local_object;
14178   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
14179       isolate, local_object,
14180       Execution::InstantiateObject(number_format_template));
14181
14182   // Set number formatter as internal field of the resulting JS object.
14183   icu::DecimalFormat* number_format = NumberFormat::InitializeNumberFormat(
14184       isolate, locale, options, resolved);
14185
14186   if (!number_format) return isolate->ThrowIllegalOperation();
14187
14188   local_object->SetInternalField(0, reinterpret_cast<Smi*>(number_format));
14189
14190   Factory* factory = isolate->factory();
14191   Handle<String> key = factory->NewStringFromStaticAscii("numberFormat");
14192   Handle<String> value = factory->NewStringFromStaticAscii("valid");
14193   JSObject::AddProperty(local_object, key, value, NONE);
14194
14195   Handle<Object> wrapper = isolate->global_handles()->Create(*local_object);
14196   GlobalHandles::MakeWeak(wrapper.location(),
14197                           reinterpret_cast<void*>(wrapper.location()),
14198                           NumberFormat::DeleteNumberFormat);
14199   return *local_object;
14200 }
14201
14202
14203 RUNTIME_FUNCTION(Runtime_InternalNumberFormat) {
14204   HandleScope scope(isolate);
14205
14206   DCHECK(args.length() == 2);
14207
14208   CONVERT_ARG_HANDLE_CHECKED(JSObject, number_format_holder, 0);
14209   CONVERT_ARG_HANDLE_CHECKED(Object, number, 1);
14210
14211   Handle<Object> value;
14212   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
14213       isolate, value, Execution::ToNumber(isolate, number));
14214
14215   icu::DecimalFormat* number_format =
14216       NumberFormat::UnpackNumberFormat(isolate, number_format_holder);
14217   if (!number_format) return isolate->ThrowIllegalOperation();
14218
14219   icu::UnicodeString result;
14220   number_format->format(value->Number(), result);
14221
14222   Handle<String> result_str;
14223   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
14224       isolate, result_str,
14225       isolate->factory()->NewStringFromTwoByte(
14226           Vector<const uint16_t>(
14227               reinterpret_cast<const uint16_t*>(result.getBuffer()),
14228               result.length())));
14229   return *result_str;
14230 }
14231
14232
14233 RUNTIME_FUNCTION(Runtime_InternalNumberParse) {
14234   HandleScope scope(isolate);
14235
14236   DCHECK(args.length() == 2);
14237
14238   CONVERT_ARG_HANDLE_CHECKED(JSObject, number_format_holder, 0);
14239   CONVERT_ARG_HANDLE_CHECKED(String, number_string, 1);
14240
14241   v8::String::Utf8Value utf8_number(v8::Utils::ToLocal(number_string));
14242   icu::UnicodeString u_number(icu::UnicodeString::fromUTF8(*utf8_number));
14243   icu::DecimalFormat* number_format =
14244       NumberFormat::UnpackNumberFormat(isolate, number_format_holder);
14245   if (!number_format) return isolate->ThrowIllegalOperation();
14246
14247   UErrorCode status = U_ZERO_ERROR;
14248   icu::Formattable result;
14249   // ICU 4.6 doesn't support parseCurrency call. We need to wait for ICU49
14250   // to be part of Chrome.
14251   // TODO(cira): Include currency parsing code using parseCurrency call.
14252   // We need to check if the formatter parses all currencies or only the
14253   // one it was constructed with (it will impact the API - how to return ISO
14254   // code and the value).
14255   number_format->parse(u_number, result, status);
14256   if (U_FAILURE(status)) return isolate->heap()->undefined_value();
14257
14258   switch (result.getType()) {
14259   case icu::Formattable::kDouble:
14260     return *isolate->factory()->NewNumber(result.getDouble());
14261   case icu::Formattable::kLong:
14262     return *isolate->factory()->NewNumberFromInt(result.getLong());
14263   case icu::Formattable::kInt64:
14264     return *isolate->factory()->NewNumber(
14265         static_cast<double>(result.getInt64()));
14266   default:
14267     return isolate->heap()->undefined_value();
14268   }
14269 }
14270
14271
14272 RUNTIME_FUNCTION(Runtime_CreateCollator) {
14273   HandleScope scope(isolate);
14274
14275   DCHECK(args.length() == 3);
14276
14277   CONVERT_ARG_HANDLE_CHECKED(String, locale, 0);
14278   CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1);
14279   CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2);
14280
14281   Handle<ObjectTemplateInfo> collator_template = I18N::GetTemplate(isolate);
14282
14283   // Create an empty object wrapper.
14284   Handle<JSObject> local_object;
14285   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
14286       isolate, local_object, Execution::InstantiateObject(collator_template));
14287
14288   // Set collator as internal field of the resulting JS object.
14289   icu::Collator* collator = Collator::InitializeCollator(
14290       isolate, locale, options, resolved);
14291
14292   if (!collator) return isolate->ThrowIllegalOperation();
14293
14294   local_object->SetInternalField(0, reinterpret_cast<Smi*>(collator));
14295
14296   Factory* factory = isolate->factory();
14297   Handle<String> key = factory->NewStringFromStaticAscii("collator");
14298   Handle<String> value = factory->NewStringFromStaticAscii("valid");
14299   JSObject::AddProperty(local_object, key, value, NONE);
14300
14301   Handle<Object> wrapper = isolate->global_handles()->Create(*local_object);
14302   GlobalHandles::MakeWeak(wrapper.location(),
14303                           reinterpret_cast<void*>(wrapper.location()),
14304                           Collator::DeleteCollator);
14305   return *local_object;
14306 }
14307
14308
14309 RUNTIME_FUNCTION(Runtime_InternalCompare) {
14310   HandleScope scope(isolate);
14311
14312   DCHECK(args.length() == 3);
14313
14314   CONVERT_ARG_HANDLE_CHECKED(JSObject, collator_holder, 0);
14315   CONVERT_ARG_HANDLE_CHECKED(String, string1, 1);
14316   CONVERT_ARG_HANDLE_CHECKED(String, string2, 2);
14317
14318   icu::Collator* collator = Collator::UnpackCollator(isolate, collator_holder);
14319   if (!collator) return isolate->ThrowIllegalOperation();
14320
14321   v8::String::Value string_value1(v8::Utils::ToLocal(string1));
14322   v8::String::Value string_value2(v8::Utils::ToLocal(string2));
14323   const UChar* u_string1 = reinterpret_cast<const UChar*>(*string_value1);
14324   const UChar* u_string2 = reinterpret_cast<const UChar*>(*string_value2);
14325   UErrorCode status = U_ZERO_ERROR;
14326   UCollationResult result = collator->compare(u_string1,
14327                                               string_value1.length(),
14328                                               u_string2,
14329                                               string_value2.length(),
14330                                               status);
14331   if (U_FAILURE(status)) return isolate->ThrowIllegalOperation();
14332
14333   return *isolate->factory()->NewNumberFromInt(result);
14334 }
14335
14336
14337 RUNTIME_FUNCTION(Runtime_StringNormalize) {
14338   HandleScope scope(isolate);
14339   static const UNormalizationMode normalizationForms[] =
14340       { UNORM_NFC, UNORM_NFD, UNORM_NFKC, UNORM_NFKD };
14341
14342   DCHECK(args.length() == 2);
14343
14344   CONVERT_ARG_HANDLE_CHECKED(String, stringValue, 0);
14345   CONVERT_NUMBER_CHECKED(int, form_id, Int32, args[1]);
14346   RUNTIME_ASSERT(form_id >= 0 &&
14347                  static_cast<size_t>(form_id) < ARRAY_SIZE(normalizationForms));
14348
14349   v8::String::Value string_value(v8::Utils::ToLocal(stringValue));
14350   const UChar* u_value = reinterpret_cast<const UChar*>(*string_value);
14351
14352   // TODO(mnita): check Normalizer2 (not available in ICU 46)
14353   UErrorCode status = U_ZERO_ERROR;
14354   icu::UnicodeString result;
14355   icu::Normalizer::normalize(u_value, normalizationForms[form_id], 0,
14356       result, status);
14357   if (U_FAILURE(status)) {
14358     return isolate->heap()->undefined_value();
14359   }
14360
14361   Handle<String> result_str;
14362   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
14363       isolate, result_str,
14364       isolate->factory()->NewStringFromTwoByte(
14365           Vector<const uint16_t>(
14366               reinterpret_cast<const uint16_t*>(result.getBuffer()),
14367               result.length())));
14368   return *result_str;
14369 }
14370
14371
14372 RUNTIME_FUNCTION(Runtime_CreateBreakIterator) {
14373   HandleScope scope(isolate);
14374
14375   DCHECK(args.length() == 3);
14376
14377   CONVERT_ARG_HANDLE_CHECKED(String, locale, 0);
14378   CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1);
14379   CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2);
14380
14381   Handle<ObjectTemplateInfo> break_iterator_template =
14382       I18N::GetTemplate2(isolate);
14383
14384   // Create an empty object wrapper.
14385   Handle<JSObject> local_object;
14386   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
14387       isolate, local_object,
14388       Execution::InstantiateObject(break_iterator_template));
14389
14390   // Set break iterator as internal field of the resulting JS object.
14391   icu::BreakIterator* break_iterator = BreakIterator::InitializeBreakIterator(
14392       isolate, locale, options, resolved);
14393
14394   if (!break_iterator) return isolate->ThrowIllegalOperation();
14395
14396   local_object->SetInternalField(0, reinterpret_cast<Smi*>(break_iterator));
14397   // Make sure that the pointer to adopted text is NULL.
14398   local_object->SetInternalField(1, reinterpret_cast<Smi*>(NULL));
14399
14400   Factory* factory = isolate->factory();
14401   Handle<String> key = factory->NewStringFromStaticAscii("breakIterator");
14402   Handle<String> value = factory->NewStringFromStaticAscii("valid");
14403   JSObject::AddProperty(local_object, key, value, NONE);
14404
14405   // Make object handle weak so we can delete the break iterator once GC kicks
14406   // in.
14407   Handle<Object> wrapper = isolate->global_handles()->Create(*local_object);
14408   GlobalHandles::MakeWeak(wrapper.location(),
14409                           reinterpret_cast<void*>(wrapper.location()),
14410                           BreakIterator::DeleteBreakIterator);
14411   return *local_object;
14412 }
14413
14414
14415 RUNTIME_FUNCTION(Runtime_BreakIteratorAdoptText) {
14416   HandleScope scope(isolate);
14417
14418   DCHECK(args.length() == 2);
14419
14420   CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
14421   CONVERT_ARG_HANDLE_CHECKED(String, text, 1);
14422
14423   icu::BreakIterator* break_iterator =
14424       BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder);
14425   if (!break_iterator) return isolate->ThrowIllegalOperation();
14426
14427   icu::UnicodeString* u_text = reinterpret_cast<icu::UnicodeString*>(
14428       break_iterator_holder->GetInternalField(1));
14429   delete u_text;
14430
14431   v8::String::Value text_value(v8::Utils::ToLocal(text));
14432   u_text = new icu::UnicodeString(
14433       reinterpret_cast<const UChar*>(*text_value), text_value.length());
14434   break_iterator_holder->SetInternalField(1, reinterpret_cast<Smi*>(u_text));
14435
14436   break_iterator->setText(*u_text);
14437
14438   return isolate->heap()->undefined_value();
14439 }
14440
14441
14442 RUNTIME_FUNCTION(Runtime_BreakIteratorFirst) {
14443   HandleScope scope(isolate);
14444
14445   DCHECK(args.length() == 1);
14446
14447   CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
14448
14449   icu::BreakIterator* break_iterator =
14450       BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder);
14451   if (!break_iterator) return isolate->ThrowIllegalOperation();
14452
14453   return *isolate->factory()->NewNumberFromInt(break_iterator->first());
14454 }
14455
14456
14457 RUNTIME_FUNCTION(Runtime_BreakIteratorNext) {
14458   HandleScope scope(isolate);
14459
14460   DCHECK(args.length() == 1);
14461
14462   CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
14463
14464   icu::BreakIterator* break_iterator =
14465       BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder);
14466   if (!break_iterator) return isolate->ThrowIllegalOperation();
14467
14468   return *isolate->factory()->NewNumberFromInt(break_iterator->next());
14469 }
14470
14471
14472 RUNTIME_FUNCTION(Runtime_BreakIteratorCurrent) {
14473   HandleScope scope(isolate);
14474
14475   DCHECK(args.length() == 1);
14476
14477   CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
14478
14479   icu::BreakIterator* break_iterator =
14480       BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder);
14481   if (!break_iterator) return isolate->ThrowIllegalOperation();
14482
14483   return *isolate->factory()->NewNumberFromInt(break_iterator->current());
14484 }
14485
14486
14487 RUNTIME_FUNCTION(Runtime_BreakIteratorBreakType) {
14488   HandleScope scope(isolate);
14489
14490   DCHECK(args.length() == 1);
14491
14492   CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
14493
14494   icu::BreakIterator* break_iterator =
14495       BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder);
14496   if (!break_iterator) return isolate->ThrowIllegalOperation();
14497
14498   // TODO(cira): Remove cast once ICU fixes base BreakIterator class.
14499   icu::RuleBasedBreakIterator* rule_based_iterator =
14500       static_cast<icu::RuleBasedBreakIterator*>(break_iterator);
14501   int32_t status = rule_based_iterator->getRuleStatus();
14502   // Keep return values in sync with JavaScript BreakType enum.
14503   if (status >= UBRK_WORD_NONE && status < UBRK_WORD_NONE_LIMIT) {
14504     return *isolate->factory()->NewStringFromStaticAscii("none");
14505   } else if (status >= UBRK_WORD_NUMBER && status < UBRK_WORD_NUMBER_LIMIT) {
14506     return *isolate->factory()->NewStringFromStaticAscii("number");
14507   } else if (status >= UBRK_WORD_LETTER && status < UBRK_WORD_LETTER_LIMIT) {
14508     return *isolate->factory()->NewStringFromStaticAscii("letter");
14509   } else if (status >= UBRK_WORD_KANA && status < UBRK_WORD_KANA_LIMIT) {
14510     return *isolate->factory()->NewStringFromStaticAscii("kana");
14511   } else if (status >= UBRK_WORD_IDEO && status < UBRK_WORD_IDEO_LIMIT) {
14512     return *isolate->factory()->NewStringFromStaticAscii("ideo");
14513   } else {
14514     return *isolate->factory()->NewStringFromStaticAscii("unknown");
14515   }
14516 }
14517 #endif  // V8_I18N_SUPPORT
14518
14519
14520 // Finds the script object from the script data. NOTE: This operation uses
14521 // heap traversal to find the function generated for the source position
14522 // for the requested break point. For lazily compiled functions several heap
14523 // traversals might be required rendering this operation as a rather slow
14524 // operation. However for setting break points which is normally done through
14525 // some kind of user interaction the performance is not crucial.
14526 static Handle<Object> Runtime_GetScriptFromScriptName(
14527     Handle<String> script_name) {
14528   // Scan the heap for Script objects to find the script with the requested
14529   // script data.
14530   Handle<Script> script;
14531   Factory* factory = script_name->GetIsolate()->factory();
14532   Heap* heap = script_name->GetHeap();
14533   HeapIterator iterator(heap);
14534   HeapObject* obj = NULL;
14535   while (script.is_null() && ((obj = iterator.next()) != NULL)) {
14536     // If a script is found check if it has the script data requested.
14537     if (obj->IsScript()) {
14538       if (Script::cast(obj)->name()->IsString()) {
14539         if (String::cast(Script::cast(obj)->name())->Equals(*script_name)) {
14540           script = Handle<Script>(Script::cast(obj));
14541         }
14542       }
14543     }
14544   }
14545
14546   // If no script with the requested script data is found return undefined.
14547   if (script.is_null()) return factory->undefined_value();
14548
14549   // Return the script found.
14550   return Script::GetWrapper(script);
14551 }
14552
14553
14554 // Get the script object from script data. NOTE: Regarding performance
14555 // see the NOTE for GetScriptFromScriptData.
14556 // args[0]: script data for the script to find the source for
14557 RUNTIME_FUNCTION(Runtime_GetScript) {
14558   HandleScope scope(isolate);
14559
14560   DCHECK(args.length() == 1);
14561
14562   CONVERT_ARG_CHECKED(String, script_name, 0);
14563
14564   // Find the requested script.
14565   Handle<Object> result =
14566       Runtime_GetScriptFromScriptName(Handle<String>(script_name));
14567   return *result;
14568 }
14569
14570
14571 // Collect the raw data for a stack trace.  Returns an array of 4
14572 // element segments each containing a receiver, function, code and
14573 // native code offset.
14574 RUNTIME_FUNCTION(Runtime_CollectStackTrace) {
14575   HandleScope scope(isolate);
14576   DCHECK(args.length() == 2);
14577   CONVERT_ARG_HANDLE_CHECKED(JSObject, error_object, 0);
14578   CONVERT_ARG_HANDLE_CHECKED(Object, caller, 1);
14579
14580   if (!isolate->bootstrapper()->IsActive()) {
14581     // Optionally capture a more detailed stack trace for the message.
14582     isolate->CaptureAndSetDetailedStackTrace(error_object);
14583     // Capture a simple stack trace for the stack property.
14584     isolate->CaptureAndSetSimpleStackTrace(error_object, caller);
14585   }
14586   return isolate->heap()->undefined_value();
14587 }
14588
14589
14590 // Returns V8 version as a string.
14591 RUNTIME_FUNCTION(Runtime_GetV8Version) {
14592   HandleScope scope(isolate);
14593   DCHECK(args.length() == 0);
14594
14595   const char* version_string = v8::V8::GetVersion();
14596
14597   return *isolate->factory()->NewStringFromAsciiChecked(version_string);
14598 }
14599
14600
14601 RUNTIME_FUNCTION(Runtime_Abort) {
14602   SealHandleScope shs(isolate);
14603   DCHECK(args.length() == 1);
14604   CONVERT_SMI_ARG_CHECKED(message_id, 0);
14605   const char* message = GetBailoutReason(
14606       static_cast<BailoutReason>(message_id));
14607   base::OS::PrintError("abort: %s\n", message);
14608   isolate->PrintStack(stderr);
14609   base::OS::Abort();
14610   UNREACHABLE();
14611   return NULL;
14612 }
14613
14614
14615 RUNTIME_FUNCTION(Runtime_AbortJS) {
14616   HandleScope scope(isolate);
14617   DCHECK(args.length() == 1);
14618   CONVERT_ARG_HANDLE_CHECKED(String, message, 0);
14619   base::OS::PrintError("abort: %s\n", message->ToCString().get());
14620   isolate->PrintStack(stderr);
14621   base::OS::Abort();
14622   UNREACHABLE();
14623   return NULL;
14624 }
14625
14626
14627 RUNTIME_FUNCTION(Runtime_FlattenString) {
14628   HandleScope scope(isolate);
14629   DCHECK(args.length() == 1);
14630   CONVERT_ARG_HANDLE_CHECKED(String, str, 0);
14631   return *String::Flatten(str);
14632 }
14633
14634
14635 RUNTIME_FUNCTION(Runtime_NotifyContextDisposed) {
14636   HandleScope scope(isolate);
14637   DCHECK(args.length() == 0);
14638   isolate->heap()->NotifyContextDisposed();
14639   return isolate->heap()->undefined_value();
14640 }
14641
14642
14643 RUNTIME_FUNCTION(Runtime_LoadMutableDouble) {
14644   HandleScope scope(isolate);
14645   DCHECK(args.length() == 2);
14646   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
14647   CONVERT_ARG_HANDLE_CHECKED(Smi, index, 1);
14648   RUNTIME_ASSERT((index->value() & 1) == 1);
14649   FieldIndex field_index =
14650       FieldIndex::ForLoadByFieldIndex(object->map(), index->value());
14651   if (field_index.is_inobject()) {
14652     RUNTIME_ASSERT(field_index.property_index() <
14653                    object->map()->inobject_properties());
14654   } else {
14655     RUNTIME_ASSERT(field_index.outobject_array_index() <
14656                    object->properties()->length());
14657   }
14658   Handle<Object> raw_value(object->RawFastPropertyAt(field_index), isolate);
14659   RUNTIME_ASSERT(raw_value->IsMutableHeapNumber());
14660   return *Object::WrapForRead(isolate, raw_value, Representation::Double());
14661 }
14662
14663
14664 RUNTIME_FUNCTION(Runtime_TryMigrateInstance) {
14665   HandleScope scope(isolate);
14666   DCHECK(args.length() == 1);
14667   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
14668   if (!object->IsJSObject()) return Smi::FromInt(0);
14669   Handle<JSObject> js_object = Handle<JSObject>::cast(object);
14670   if (!js_object->map()->is_deprecated()) return Smi::FromInt(0);
14671   // This call must not cause lazy deopts, because it's called from deferred
14672   // code where we can't handle lazy deopts for lack of a suitable bailout
14673   // ID. So we just try migration and signal failure if necessary,
14674   // which will also trigger a deopt.
14675   if (!JSObject::TryMigrateInstance(js_object)) return Smi::FromInt(0);
14676   return *object;
14677 }
14678
14679
14680 RUNTIME_FUNCTION(Runtime_GetFromCache) {
14681   SealHandleScope shs(isolate);
14682   // This is only called from codegen, so checks might be more lax.
14683   CONVERT_ARG_CHECKED(JSFunctionResultCache, cache, 0);
14684   CONVERT_ARG_CHECKED(Object, key, 1);
14685
14686   {
14687     DisallowHeapAllocation no_alloc;
14688
14689     int finger_index = cache->finger_index();
14690     Object* o = cache->get(finger_index);
14691     if (o == key) {
14692       // The fastest case: hit the same place again.
14693       return cache->get(finger_index + 1);
14694     }
14695
14696     for (int i = finger_index - 2;
14697          i >= JSFunctionResultCache::kEntriesIndex;
14698          i -= 2) {
14699       o = cache->get(i);
14700       if (o == key) {
14701         cache->set_finger_index(i);
14702         return cache->get(i + 1);
14703       }
14704     }
14705
14706     int size = cache->size();
14707     DCHECK(size <= cache->length());
14708
14709     for (int i = size - 2; i > finger_index; i -= 2) {
14710       o = cache->get(i);
14711       if (o == key) {
14712         cache->set_finger_index(i);
14713         return cache->get(i + 1);
14714       }
14715     }
14716   }
14717
14718   // There is no value in the cache.  Invoke the function and cache result.
14719   HandleScope scope(isolate);
14720
14721   Handle<JSFunctionResultCache> cache_handle(cache);
14722   Handle<Object> key_handle(key, isolate);
14723   Handle<Object> value;
14724   {
14725     Handle<JSFunction> factory(JSFunction::cast(
14726           cache_handle->get(JSFunctionResultCache::kFactoryIndex)));
14727     // TODO(antonm): consider passing a receiver when constructing a cache.
14728     Handle<JSObject> receiver(isolate->global_proxy());
14729     // This handle is nor shared, nor used later, so it's safe.
14730     Handle<Object> argv[] = { key_handle };
14731     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
14732         isolate, value,
14733         Execution::Call(isolate, factory, receiver, ARRAY_SIZE(argv), argv));
14734   }
14735
14736 #ifdef VERIFY_HEAP
14737   if (FLAG_verify_heap) {
14738     cache_handle->JSFunctionResultCacheVerify();
14739   }
14740 #endif
14741
14742   // Function invocation may have cleared the cache.  Reread all the data.
14743   int finger_index = cache_handle->finger_index();
14744   int size = cache_handle->size();
14745
14746   // If we have spare room, put new data into it, otherwise evict post finger
14747   // entry which is likely to be the least recently used.
14748   int index = -1;
14749   if (size < cache_handle->length()) {
14750     cache_handle->set_size(size + JSFunctionResultCache::kEntrySize);
14751     index = size;
14752   } else {
14753     index = finger_index + JSFunctionResultCache::kEntrySize;
14754     if (index == cache_handle->length()) {
14755       index = JSFunctionResultCache::kEntriesIndex;
14756     }
14757   }
14758
14759   DCHECK(index % 2 == 0);
14760   DCHECK(index >= JSFunctionResultCache::kEntriesIndex);
14761   DCHECK(index < cache_handle->length());
14762
14763   cache_handle->set(index, *key_handle);
14764   cache_handle->set(index + 1, *value);
14765   cache_handle->set_finger_index(index);
14766
14767 #ifdef VERIFY_HEAP
14768   if (FLAG_verify_heap) {
14769     cache_handle->JSFunctionResultCacheVerify();
14770   }
14771 #endif
14772
14773   return *value;
14774 }
14775
14776
14777 RUNTIME_FUNCTION(Runtime_MessageGetStartPosition) {
14778   SealHandleScope shs(isolate);
14779   DCHECK(args.length() == 1);
14780   CONVERT_ARG_CHECKED(JSMessageObject, message, 0);
14781   return Smi::FromInt(message->start_position());
14782 }
14783
14784
14785 RUNTIME_FUNCTION(Runtime_MessageGetScript) {
14786   SealHandleScope shs(isolate);
14787   DCHECK(args.length() == 1);
14788   CONVERT_ARG_CHECKED(JSMessageObject, message, 0);
14789   return message->script();
14790 }
14791
14792
14793 #ifdef DEBUG
14794 // ListNatives is ONLY used by the fuzz-natives.js in debug mode
14795 // Exclude the code in release mode.
14796 RUNTIME_FUNCTION(Runtime_ListNatives) {
14797   HandleScope scope(isolate);
14798   DCHECK(args.length() == 0);
14799 #define COUNT_ENTRY(Name, argc, ressize) + 1
14800   int entry_count = 0
14801       RUNTIME_FUNCTION_LIST(COUNT_ENTRY)
14802       INLINE_FUNCTION_LIST(COUNT_ENTRY)
14803       INLINE_OPTIMIZED_FUNCTION_LIST(COUNT_ENTRY);
14804 #undef COUNT_ENTRY
14805   Factory* factory = isolate->factory();
14806   Handle<FixedArray> elements = factory->NewFixedArray(entry_count);
14807   int index = 0;
14808   bool inline_runtime_functions = false;
14809 #define ADD_ENTRY(Name, argc, ressize)                                       \
14810   {                                                                          \
14811     HandleScope inner(isolate);                                              \
14812     Handle<String> name;                                                     \
14813     /* Inline runtime functions have an underscore in front of the name. */  \
14814     if (inline_runtime_functions) {                                          \
14815       name = factory->NewStringFromStaticAscii("_" #Name);                   \
14816     } else {                                                                 \
14817       name = factory->NewStringFromStaticAscii(#Name);                       \
14818     }                                                                        \
14819     Handle<FixedArray> pair_elements = factory->NewFixedArray(2);            \
14820     pair_elements->set(0, *name);                                            \
14821     pair_elements->set(1, Smi::FromInt(argc));                               \
14822     Handle<JSArray> pair = factory->NewJSArrayWithElements(pair_elements);   \
14823     elements->set(index++, *pair);                                           \
14824   }
14825   inline_runtime_functions = false;
14826   RUNTIME_FUNCTION_LIST(ADD_ENTRY)
14827   INLINE_OPTIMIZED_FUNCTION_LIST(ADD_ENTRY)
14828   inline_runtime_functions = true;
14829   INLINE_FUNCTION_LIST(ADD_ENTRY)
14830 #undef ADD_ENTRY
14831   DCHECK_EQ(index, entry_count);
14832   Handle<JSArray> result = factory->NewJSArrayWithElements(elements);
14833   return *result;
14834 }
14835 #endif
14836
14837
14838 RUNTIME_FUNCTION(Runtime_IS_VAR) {
14839   UNREACHABLE();  // implemented as macro in the parser
14840   return NULL;
14841 }
14842
14843
14844 #define ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(Name)        \
14845   RUNTIME_FUNCTION(Runtime_Has##Name) {          \
14846     CONVERT_ARG_CHECKED(JSObject, obj, 0);                \
14847     return isolate->heap()->ToBoolean(obj->Has##Name());  \
14848   }
14849
14850 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastSmiElements)
14851 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastObjectElements)
14852 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastSmiOrObjectElements)
14853 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastDoubleElements)
14854 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastHoleyElements)
14855 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(DictionaryElements)
14856 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(SloppyArgumentsElements)
14857 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalArrayElements)
14858 // Properties test sitting with elements tests - not fooling anyone.
14859 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastProperties)
14860
14861 #undef ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION
14862
14863
14864 #define TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION(Type, type, TYPE, ctype, size)     \
14865   RUNTIME_FUNCTION(Runtime_HasExternal##Type##Elements) {             \
14866     CONVERT_ARG_CHECKED(JSObject, obj, 0);                                     \
14867     return isolate->heap()->ToBoolean(obj->HasExternal##Type##Elements());     \
14868   }
14869
14870 TYPED_ARRAYS(TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION)
14871
14872 #undef TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION
14873
14874
14875 #define FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION(Type, type, TYPE, ctype, s)  \
14876   RUNTIME_FUNCTION(Runtime_HasFixed##Type##Elements) {                \
14877     CONVERT_ARG_CHECKED(JSObject, obj, 0);                                     \
14878     return isolate->heap()->ToBoolean(obj->HasFixed##Type##Elements());        \
14879   }
14880
14881 TYPED_ARRAYS(FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION)
14882
14883 #undef FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION
14884
14885
14886 RUNTIME_FUNCTION(Runtime_HaveSameMap) {
14887   SealHandleScope shs(isolate);
14888   DCHECK(args.length() == 2);
14889   CONVERT_ARG_CHECKED(JSObject, obj1, 0);
14890   CONVERT_ARG_CHECKED(JSObject, obj2, 1);
14891   return isolate->heap()->ToBoolean(obj1->map() == obj2->map());
14892 }
14893
14894
14895 RUNTIME_FUNCTION(Runtime_IsJSGlobalProxy) {
14896   SealHandleScope shs(isolate);
14897   DCHECK(args.length() == 1);
14898   CONVERT_ARG_CHECKED(Object, obj, 0);
14899   return isolate->heap()->ToBoolean(obj->IsJSGlobalProxy());
14900 }
14901
14902
14903 RUNTIME_FUNCTION(Runtime_IsObserved) {
14904   SealHandleScope shs(isolate);
14905   DCHECK(args.length() == 1);
14906
14907   if (!args[0]->IsJSReceiver()) return isolate->heap()->false_value();
14908   CONVERT_ARG_CHECKED(JSReceiver, obj, 0);
14909   DCHECK(!obj->IsJSGlobalProxy() || !obj->map()->is_observed());
14910   return isolate->heap()->ToBoolean(obj->map()->is_observed());
14911 }
14912
14913
14914 RUNTIME_FUNCTION(Runtime_SetIsObserved) {
14915   HandleScope scope(isolate);
14916   DCHECK(args.length() == 1);
14917   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, obj, 0);
14918   RUNTIME_ASSERT(!obj->IsJSGlobalProxy());
14919   if (obj->IsJSProxy()) return isolate->heap()->undefined_value();
14920   RUNTIME_ASSERT(!obj->map()->is_observed());
14921
14922   DCHECK(obj->IsJSObject());
14923   JSObject::SetObserved(Handle<JSObject>::cast(obj));
14924   return isolate->heap()->undefined_value();
14925 }
14926
14927
14928 RUNTIME_FUNCTION(Runtime_EnqueueMicrotask) {
14929   HandleScope scope(isolate);
14930   DCHECK(args.length() == 1);
14931   CONVERT_ARG_HANDLE_CHECKED(JSFunction, microtask, 0);
14932   isolate->EnqueueMicrotask(microtask);
14933   return isolate->heap()->undefined_value();
14934 }
14935
14936
14937 RUNTIME_FUNCTION(Runtime_RunMicrotasks) {
14938   HandleScope scope(isolate);
14939   DCHECK(args.length() == 0);
14940   isolate->RunMicrotasks();
14941   return isolate->heap()->undefined_value();
14942 }
14943
14944
14945 RUNTIME_FUNCTION(Runtime_GetObservationState) {
14946   SealHandleScope shs(isolate);
14947   DCHECK(args.length() == 0);
14948   return isolate->heap()->observation_state();
14949 }
14950
14951
14952 RUNTIME_FUNCTION(Runtime_ObservationWeakMapCreate) {
14953   HandleScope scope(isolate);
14954   DCHECK(args.length() == 0);
14955   // TODO(adamk): Currently this runtime function is only called three times per
14956   // isolate. If it's called more often, the map should be moved into the
14957   // strong root list.
14958   Handle<Map> map =
14959       isolate->factory()->NewMap(JS_WEAK_MAP_TYPE, JSWeakMap::kSize);
14960   Handle<JSWeakMap> weakmap =
14961       Handle<JSWeakMap>::cast(isolate->factory()->NewJSObjectFromMap(map));
14962   return *WeakCollectionInitialize(isolate, weakmap);
14963 }
14964
14965
14966 static bool ContextsHaveSameOrigin(Handle<Context> context1,
14967                                    Handle<Context> context2) {
14968   return context1->security_token() == context2->security_token();
14969 }
14970
14971
14972 RUNTIME_FUNCTION(Runtime_ObserverObjectAndRecordHaveSameOrigin) {
14973   HandleScope scope(isolate);
14974   DCHECK(args.length() == 3);
14975   CONVERT_ARG_HANDLE_CHECKED(JSFunction, observer, 0);
14976   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 1);
14977   CONVERT_ARG_HANDLE_CHECKED(JSObject, record, 2);
14978
14979   Handle<Context> observer_context(observer->context()->native_context());
14980   Handle<Context> object_context(object->GetCreationContext());
14981   Handle<Context> record_context(record->GetCreationContext());
14982
14983   return isolate->heap()->ToBoolean(
14984       ContextsHaveSameOrigin(object_context, observer_context) &&
14985       ContextsHaveSameOrigin(object_context, record_context));
14986 }
14987
14988
14989 RUNTIME_FUNCTION(Runtime_ObjectWasCreatedInCurrentOrigin) {
14990   HandleScope scope(isolate);
14991   DCHECK(args.length() == 1);
14992   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
14993
14994   Handle<Context> creation_context(object->GetCreationContext(), isolate);
14995   return isolate->heap()->ToBoolean(
14996       ContextsHaveSameOrigin(creation_context, isolate->native_context()));
14997 }
14998
14999
15000 RUNTIME_FUNCTION(Runtime_GetObjectContextObjectObserve) {
15001   HandleScope scope(isolate);
15002   DCHECK(args.length() == 1);
15003   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
15004
15005   Handle<Context> context(object->GetCreationContext(), isolate);
15006   return context->native_object_observe();
15007 }
15008
15009
15010 RUNTIME_FUNCTION(Runtime_GetObjectContextObjectGetNotifier) {
15011   HandleScope scope(isolate);
15012   DCHECK(args.length() == 1);
15013   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
15014
15015   Handle<Context> context(object->GetCreationContext(), isolate);
15016   return context->native_object_get_notifier();
15017 }
15018
15019
15020 RUNTIME_FUNCTION(Runtime_GetObjectContextNotifierPerformChange) {
15021   HandleScope scope(isolate);
15022   DCHECK(args.length() == 1);
15023   CONVERT_ARG_HANDLE_CHECKED(JSObject, object_info, 0);
15024
15025   Handle<Context> context(object_info->GetCreationContext(), isolate);
15026   return context->native_object_notifier_perform_change();
15027 }
15028
15029
15030 static Object* ArrayConstructorCommon(Isolate* isolate,
15031                                            Handle<JSFunction> constructor,
15032                                            Handle<AllocationSite> site,
15033                                            Arguments* caller_args) {
15034   Factory* factory = isolate->factory();
15035
15036   bool holey = false;
15037   bool can_use_type_feedback = true;
15038   if (caller_args->length() == 1) {
15039     Handle<Object> argument_one = caller_args->at<Object>(0);
15040     if (argument_one->IsSmi()) {
15041       int value = Handle<Smi>::cast(argument_one)->value();
15042       if (value < 0 || value >= JSObject::kInitialMaxFastElementArray) {
15043         // the array is a dictionary in this case.
15044         can_use_type_feedback = false;
15045       } else if (value != 0) {
15046         holey = true;
15047       }
15048     } else {
15049       // Non-smi length argument produces a dictionary
15050       can_use_type_feedback = false;
15051     }
15052   }
15053
15054   Handle<JSArray> array;
15055   if (!site.is_null() && can_use_type_feedback) {
15056     ElementsKind to_kind = site->GetElementsKind();
15057     if (holey && !IsFastHoleyElementsKind(to_kind)) {
15058       to_kind = GetHoleyElementsKind(to_kind);
15059       // Update the allocation site info to reflect the advice alteration.
15060       site->SetElementsKind(to_kind);
15061     }
15062
15063     // We should allocate with an initial map that reflects the allocation site
15064     // advice. Therefore we use AllocateJSObjectFromMap instead of passing
15065     // the constructor.
15066     Handle<Map> initial_map(constructor->initial_map(), isolate);
15067     if (to_kind != initial_map->elements_kind()) {
15068       initial_map = Map::AsElementsKind(initial_map, to_kind);
15069     }
15070
15071     // If we don't care to track arrays of to_kind ElementsKind, then
15072     // don't emit a memento for them.
15073     Handle<AllocationSite> allocation_site;
15074     if (AllocationSite::GetMode(to_kind) == TRACK_ALLOCATION_SITE) {
15075       allocation_site = site;
15076     }
15077
15078     array = Handle<JSArray>::cast(factory->NewJSObjectFromMap(
15079         initial_map, NOT_TENURED, true, allocation_site));
15080   } else {
15081     array = Handle<JSArray>::cast(factory->NewJSObject(constructor));
15082
15083     // We might need to transition to holey
15084     ElementsKind kind = constructor->initial_map()->elements_kind();
15085     if (holey && !IsFastHoleyElementsKind(kind)) {
15086       kind = GetHoleyElementsKind(kind);
15087       JSObject::TransitionElementsKind(array, kind);
15088     }
15089   }
15090
15091   factory->NewJSArrayStorage(array, 0, 0, DONT_INITIALIZE_ARRAY_ELEMENTS);
15092
15093   ElementsKind old_kind = array->GetElementsKind();
15094   RETURN_FAILURE_ON_EXCEPTION(
15095       isolate, ArrayConstructInitializeElements(array, caller_args));
15096   if (!site.is_null() &&
15097       (old_kind != array->GetElementsKind() ||
15098        !can_use_type_feedback)) {
15099     // The arguments passed in caused a transition. This kind of complexity
15100     // can't be dealt with in the inlined hydrogen array constructor case.
15101     // We must mark the allocationsite as un-inlinable.
15102     site->SetDoNotInlineCall();
15103   }
15104   return *array;
15105 }
15106
15107
15108 RUNTIME_FUNCTION(Runtime_ArrayConstructor) {
15109   HandleScope scope(isolate);
15110   // If we get 2 arguments then they are the stub parameters (constructor, type
15111   // info).  If we get 4, then the first one is a pointer to the arguments
15112   // passed by the caller, and the last one is the length of the arguments
15113   // passed to the caller (redundant, but useful to check on the deoptimizer
15114   // with an assert).
15115   Arguments empty_args(0, NULL);
15116   bool no_caller_args = args.length() == 2;
15117   DCHECK(no_caller_args || args.length() == 4);
15118   int parameters_start = no_caller_args ? 0 : 1;
15119   Arguments* caller_args = no_caller_args
15120       ? &empty_args
15121       : reinterpret_cast<Arguments*>(args[0]);
15122   CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, parameters_start);
15123   CONVERT_ARG_HANDLE_CHECKED(Object, type_info, parameters_start + 1);
15124 #ifdef DEBUG
15125   if (!no_caller_args) {
15126     CONVERT_SMI_ARG_CHECKED(arg_count, parameters_start + 2);
15127     DCHECK(arg_count == caller_args->length());
15128   }
15129 #endif
15130
15131   Handle<AllocationSite> site;
15132   if (!type_info.is_null() &&
15133       *type_info != isolate->heap()->undefined_value()) {
15134     site = Handle<AllocationSite>::cast(type_info);
15135     DCHECK(!site->SitePointsToLiteral());
15136   }
15137
15138   return ArrayConstructorCommon(isolate,
15139                                 constructor,
15140                                 site,
15141                                 caller_args);
15142 }
15143
15144
15145 RUNTIME_FUNCTION(Runtime_InternalArrayConstructor) {
15146   HandleScope scope(isolate);
15147   Arguments empty_args(0, NULL);
15148   bool no_caller_args = args.length() == 1;
15149   DCHECK(no_caller_args || args.length() == 3);
15150   int parameters_start = no_caller_args ? 0 : 1;
15151   Arguments* caller_args = no_caller_args
15152       ? &empty_args
15153       : reinterpret_cast<Arguments*>(args[0]);
15154   CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, parameters_start);
15155 #ifdef DEBUG
15156   if (!no_caller_args) {
15157     CONVERT_SMI_ARG_CHECKED(arg_count, parameters_start + 1);
15158     DCHECK(arg_count == caller_args->length());
15159   }
15160 #endif
15161   return ArrayConstructorCommon(isolate,
15162                                 constructor,
15163                                 Handle<AllocationSite>::null(),
15164                                 caller_args);
15165 }
15166
15167
15168 RUNTIME_FUNCTION(Runtime_NormalizeElements) {
15169   HandleScope scope(isolate);
15170   DCHECK(args.length() == 1);
15171   CONVERT_ARG_HANDLE_CHECKED(JSObject, array, 0);
15172   RUNTIME_ASSERT(!array->HasExternalArrayElements() &&
15173                  !array->HasFixedTypedArrayElements());
15174   JSObject::NormalizeElements(array);
15175   return *array;
15176 }
15177
15178
15179 RUNTIME_FUNCTION(Runtime_MaxSmi) {
15180   SealHandleScope shs(isolate);
15181   DCHECK(args.length() == 0);
15182   return Smi::FromInt(Smi::kMaxValue);
15183 }
15184
15185
15186 // TODO(dcarney): remove this function when TurboFan supports it.
15187 // Takes the object to be iterated over and the result of GetPropertyNamesFast
15188 // Returns pair (cache_array, cache_type).
15189 RUNTIME_FUNCTION_RETURN_PAIR(Runtime_ForInInit) {
15190   SealHandleScope scope(isolate);
15191   DCHECK(args.length() == 2);
15192   // This simulates CONVERT_ARG_HANDLE_CHECKED for calls returning pairs.
15193   // Not worth creating a macro atm as this function should be removed.
15194   if (!args[0]->IsJSReceiver() || !args[1]->IsObject()) {
15195     Object* error = isolate->ThrowIllegalOperation();
15196     return MakePair(error, isolate->heap()->undefined_value());
15197   }
15198   Handle<JSReceiver> object = args.at<JSReceiver>(0);
15199   Handle<Object> cache_type = args.at<Object>(1);
15200   if (cache_type->IsMap()) {
15201     // Enum cache case.
15202     if (Map::EnumLengthBits::decode(Map::cast(*cache_type)->bit_field3()) ==
15203         0) {
15204       // 0 length enum.
15205       // Can't handle this case in the graph builder,
15206       // so transform it into the empty fixed array case.
15207       return MakePair(isolate->heap()->empty_fixed_array(), Smi::FromInt(1));
15208     }
15209     return MakePair(object->map()->instance_descriptors()->GetEnumCache(),
15210                     *cache_type);
15211   } else {
15212     // FixedArray case.
15213     Smi* new_cache_type = Smi::FromInt(object->IsJSProxy() ? 0 : 1);
15214     return MakePair(*Handle<FixedArray>::cast(cache_type), new_cache_type);
15215   }
15216 }
15217
15218
15219 // TODO(dcarney): remove this function when TurboFan supports it.
15220 RUNTIME_FUNCTION(Runtime_ForInCacheArrayLength) {
15221   SealHandleScope shs(isolate);
15222   DCHECK(args.length() == 2);
15223   CONVERT_ARG_HANDLE_CHECKED(Object, cache_type, 0);
15224   CONVERT_ARG_HANDLE_CHECKED(FixedArray, array, 1);
15225   int length = 0;
15226   if (cache_type->IsMap()) {
15227     length = Map::cast(*cache_type)->EnumLength();
15228   } else {
15229     DCHECK(cache_type->IsSmi());
15230     length = array->length();
15231   }
15232   return Smi::FromInt(length);
15233 }
15234
15235
15236 // TODO(dcarney): remove this function when TurboFan supports it.
15237 // Takes (the object to be iterated over,
15238 //        cache_array from ForInInit,
15239 //        cache_type from ForInInit,
15240 //        the current index)
15241 // Returns pair (array[index], needs_filtering).
15242 RUNTIME_FUNCTION_RETURN_PAIR(Runtime_ForInNext) {
15243   SealHandleScope scope(isolate);
15244   DCHECK(args.length() == 4);
15245   // This simulates CONVERT_ARG_HANDLE_CHECKED for calls returning pairs.
15246   // Not worth creating a macro atm as this function should be removed.
15247   if (!args[0]->IsJSReceiver() || !args[1]->IsFixedArray() ||
15248       !args[2]->IsObject() || !args[3]->IsSmi()) {
15249     Object* error = isolate->ThrowIllegalOperation();
15250     return MakePair(error, isolate->heap()->undefined_value());
15251   }
15252   Handle<JSReceiver> object = args.at<JSReceiver>(0);
15253   Handle<FixedArray> array = args.at<FixedArray>(1);
15254   Handle<Object> cache_type = args.at<Object>(2);
15255   int index = args.smi_at(3);
15256   // Figure out first if a slow check is needed for this object.
15257   bool slow_check_needed = false;
15258   if (cache_type->IsMap()) {
15259     if (object->map() != Map::cast(*cache_type)) {
15260       // Object transitioned.  Need slow check.
15261       slow_check_needed = true;
15262     }
15263   } else {
15264     // No slow check needed for proxies.
15265     slow_check_needed = Smi::cast(*cache_type)->value() == 1;
15266   }
15267   return MakePair(array->get(index),
15268                   isolate->heap()->ToBoolean(slow_check_needed));
15269 }
15270
15271
15272 #define RETURN_Float32x4_RESULT(value)                                         \
15273   return *isolate->factory()->NewFloat32x4(value);
15274
15275
15276 #define RETURN_Float64x2_RESULT(value)                                         \
15277   return *isolate->factory()->NewFloat64x2(value);
15278
15279
15280 #define RETURN_Int32x4_RESULT(value)                                           \
15281   return *isolate->factory()->NewInt32x4(value);
15282
15283
15284 RUNTIME_FUNCTION(Runtime_CreateFloat32x4) {
15285   HandleScope scope(isolate);
15286   DCHECK(args.length() == 4);
15287   RUNTIME_ASSERT(args[0]->IsNumber());
15288   RUNTIME_ASSERT(args[1]->IsNumber());
15289   RUNTIME_ASSERT(args[2]->IsNumber());
15290   RUNTIME_ASSERT(args[3]->IsNumber());
15291
15292   float32x4_value_t value;
15293   value.storage[0] = static_cast<float>(args.number_at(0));
15294   value.storage[1] = static_cast<float>(args.number_at(1));
15295   value.storage[2] = static_cast<float>(args.number_at(2));
15296   value.storage[3] = static_cast<float>(args.number_at(3));
15297
15298   RETURN_Float32x4_RESULT(value);
15299 }
15300
15301
15302 RUNTIME_FUNCTION(Runtime_CreateFloat64x2) {
15303   HandleScope scope(isolate);
15304   DCHECK(args.length() == 2);
15305   RUNTIME_ASSERT(args[0]->IsNumber());
15306   RUNTIME_ASSERT(args[1]->IsNumber());
15307
15308   float64x2_value_t value;
15309   value.storage[0] = args.number_at(0);
15310   value.storage[1] = args.number_at(1);
15311
15312   RETURN_Float64x2_RESULT(value);
15313 }
15314
15315
15316 RUNTIME_FUNCTION(Runtime_CreateInt32x4) {
15317   HandleScope scope(isolate);
15318   DCHECK(args.length() == 4);
15319   RUNTIME_ASSERT(args[0]->IsNumber());
15320   RUNTIME_ASSERT(args[1]->IsNumber());
15321   RUNTIME_ASSERT(args[2]->IsNumber());
15322   RUNTIME_ASSERT(args[3]->IsNumber());
15323
15324   int32x4_value_t value;
15325   value.storage[0] = NumberToInt32(args[0]);
15326   value.storage[1] = NumberToInt32(args[1]);
15327   value.storage[2] = NumberToInt32(args[2]);
15328   value.storage[3] = NumberToInt32(args[3]);
15329
15330   RETURN_Int32x4_RESULT(value);
15331 }
15332
15333
15334 // Used to convert between uint32_t and float32 without breaking strict
15335 // aliasing rules.
15336 union float32_uint32 {
15337   float f;
15338   uint32_t u;
15339   float32_uint32(float v) {
15340     f = v;
15341   }
15342   float32_uint32(uint32_t v) {
15343     u = v;
15344   }
15345 };
15346
15347
15348 union float64_uint64 {
15349   double f;
15350   uint64_t u;
15351   float64_uint64(double v) {
15352     f = v;
15353   }
15354   float64_uint64(uint64_t v) {
15355     u = v;
15356   }
15357 };
15358
15359
15360 RUNTIME_FUNCTION(Runtime_Float32x4GetSignMask) {
15361   HandleScope scope(isolate);
15362   DCHECK(args.length() == 1);
15363   CONVERT_ARG_CHECKED(Float32x4, self, 0);
15364   float32_uint32 x(self->x());
15365   float32_uint32 y(self->y());
15366   float32_uint32 z(self->z());
15367   float32_uint32 w(self->w());
15368   uint32_t mx = (x.u & 0x80000000) >> 31;
15369   uint32_t my = (y.u & 0x80000000) >> 31;
15370   uint32_t mz = (z.u & 0x80000000) >> 31;
15371   uint32_t mw = (w.u & 0x80000000) >> 31;
15372   uint32_t value = mx | (my << 1) | (mz << 2) | (mw << 3);
15373   return *isolate->factory()->NewNumberFromUint(value);
15374 }
15375
15376
15377 RUNTIME_FUNCTION(Runtime_Float64x2GetSignMask) {
15378   HandleScope scope(isolate);
15379   DCHECK(args.length() == 1);
15380   CONVERT_ARG_CHECKED(Float64x2, self, 0);
15381   float64_uint64 x(self->x());
15382   float64_uint64 y(self->y());
15383   uint64_t mx = x.u >> 63;
15384   uint64_t my = y.u >> 63;
15385   uint32_t value = static_cast<uint32_t>(mx | (my << 1));
15386   return *isolate->factory()->NewNumberFromUint(value);
15387 }
15388
15389
15390 RUNTIME_FUNCTION(Runtime_Int32x4GetSignMask) {
15391   HandleScope scope(isolate);
15392   DCHECK(args.length() == 1);
15393   CONVERT_ARG_CHECKED(Int32x4, self, 0);
15394   uint32_t mx = (self->x() & 0x80000000) >> 31;
15395   uint32_t my = (self->y() & 0x80000000) >> 31;
15396   uint32_t mz = (self->z() & 0x80000000) >> 31;
15397   uint32_t mw = (self->w() & 0x80000000) >> 31;
15398   uint32_t value = mx | (my << 1) | (mz << 2) | (mw << 3);
15399   return *isolate->factory()->NewNumberFromUint(value);
15400 }
15401
15402
15403 #define LANE_VALUE(VALUE, LANE) \
15404   VALUE->LANE()
15405
15406
15407 #define LANE_FLAG(VALUE, LANE)  \
15408   VALUE->LANE() != 0
15409
15410
15411 #define SIMD128_LANE_ACCESS_FUNCTIONS(V)                      \
15412   V(Float32x4, GetX, NewNumber, x, LANE_VALUE)       \
15413   V(Float32x4, GetY, NewNumber, y, LANE_VALUE)       \
15414   V(Float32x4, GetZ, NewNumber, z, LANE_VALUE)       \
15415   V(Float32x4, GetW, NewNumber, w, LANE_VALUE)       \
15416   V(Float64x2, GetX, NewNumber, x, LANE_VALUE)       \
15417   V(Float64x2, GetY, NewNumber, y, LANE_VALUE)       \
15418   V(Int32x4, GetX, NewNumberFromInt, x, LANE_VALUE)            \
15419   V(Int32x4, GetY, NewNumberFromInt, y, LANE_VALUE)            \
15420   V(Int32x4, GetZ, NewNumberFromInt, z, LANE_VALUE)            \
15421   V(Int32x4, GetW, NewNumberFromInt, w, LANE_VALUE)            \
15422   V(Int32x4, GetFlagX, ToBoolean, x, LANE_FLAG)               \
15423   V(Int32x4, GetFlagY, ToBoolean, y, LANE_FLAG)               \
15424   V(Int32x4, GetFlagZ, ToBoolean, z, LANE_FLAG)               \
15425   V(Int32x4, GetFlagW, ToBoolean, w, LANE_FLAG)
15426
15427
15428 #define DECLARE_SIMD_LANE_ACCESS_FUNCTION(                    \
15429     TYPE, NAME, HEAP_FUNCTION, LANE, ACCESS_FUNCTION)         \
15430 RUNTIME_FUNCTION(Runtime_##TYPE##NAME) {        \
15431   HandleScope scope(isolate);                                 \
15432   DCHECK(args.length() == 1);                                 \
15433                                                               \
15434   CONVERT_ARG_CHECKED(TYPE, a, 0);                            \
15435                                                               \
15436   return *isolate->factory()->HEAP_FUNCTION(                  \
15437       ACCESS_FUNCTION(a, LANE));                              \
15438 }
15439
15440
15441 SIMD128_LANE_ACCESS_FUNCTIONS(DECLARE_SIMD_LANE_ACCESS_FUNCTION)
15442
15443
15444 template<typename T>
15445 static inline T Neg(T a) {
15446   return -a;
15447 }
15448
15449
15450 template<typename T>
15451 static inline T Not(T a) {
15452   return ~a;
15453 }
15454
15455
15456 template<typename T>
15457 static inline T Reciprocal(T a) {
15458   UNIMPLEMENTED();
15459 }
15460
15461
15462 template<>
15463 inline float Reciprocal<float>(float a) {
15464   return 1.0f / a;
15465 }
15466
15467
15468 template<typename T>
15469 static inline T ReciprocalSqrt(T a) {
15470   UNIMPLEMENTED();
15471 }
15472
15473
15474 template<>
15475 inline float ReciprocalSqrt<float>(float a) {
15476   return sqrtf(1.0f / a);
15477 }
15478
15479
15480 template<typename T>
15481 static inline T Sqrt(T a) {
15482   UNIMPLEMENTED();
15483 }
15484
15485
15486 template<>
15487 inline float Sqrt<float>(float a) {
15488   return sqrtf(a);
15489 }
15490
15491
15492 template<>
15493 inline double Sqrt<double>(double a) {
15494   return sqrt(a);
15495 }
15496
15497
15498 #define SIMD128_UNARY_FUNCTIONS(V)                            \
15499   V(Float32x4, Abs)                                           \
15500   V(Float32x4, Neg)                                           \
15501   V(Float32x4, Reciprocal)                                    \
15502   V(Float32x4, ReciprocalSqrt)                                \
15503   V(Float32x4, Sqrt)                                          \
15504   V(Float64x2, Abs)                                           \
15505   V(Float64x2, Neg)                                           \
15506   V(Float64x2, Sqrt)                                          \
15507   V(Int32x4, Neg)                                             \
15508   V(Int32x4, Not)
15509
15510
15511 #define DECLARE_SIMD_UNARY_FUNCTION(TYPE, FUNCTION)           \
15512 RUNTIME_FUNCTION(Runtime_##TYPE##FUNCTION) {    \
15513   HandleScope scope(isolate);                                 \
15514   DCHECK(args.length() == 1);                                 \
15515                                                               \
15516   CONVERT_ARG_CHECKED(TYPE, a, 0);                            \
15517                                                               \
15518   TYPE::value_t result;                                       \
15519   for (int i = 0; i < TYPE::kLanes; i++) {                    \
15520     result.storage[i] = FUNCTION(a->getAt(i));                \
15521   }                                                           \
15522                                                               \
15523   RETURN_##TYPE##_RESULT(result);                             \
15524 }
15525
15526
15527 SIMD128_UNARY_FUNCTIONS(DECLARE_SIMD_UNARY_FUNCTION)
15528
15529
15530 template<typename T1, typename T2>
15531 inline void BitsTo(T1 s, T2* t) {
15532   memcpy(t, &s, sizeof(T2));
15533 }
15534
15535
15536 template<typename T1, typename T2>
15537 inline void To(T1 s, T2* t) {
15538 }
15539
15540
15541 template<>
15542 inline void To<int32_t, float>(int32_t s, float* t) {
15543   *t = static_cast<float>(s);
15544 }
15545
15546
15547 template<>
15548 inline void To<float, int32_t>(float s, int32_t* t) {
15549   *t = DoubleToInt32(static_cast<double>(s));
15550 }
15551
15552
15553 #define SIMD128_CONVERSION_FUNCTIONS(V)                       \
15554   V(Float32x4, BitsTo, Int32x4)                               \
15555   V(Float32x4, To, Int32x4)                                   \
15556   V(Int32x4, BitsTo, Float32x4)                               \
15557   V(Int32x4, To, Float32x4)
15558
15559
15560 #define DECLARE_SIMD_CONVERSION_FUNCTION(                     \
15561     SOURCE_TYPE, FUNCTION, TARGET_TYPE)                       \
15562 RUNTIME_FUNCTION(                               \
15563     Runtime_##SOURCE_TYPE##FUNCTION##TARGET_TYPE) {           \
15564   HandleScope scope(isolate);                                 \
15565   DCHECK(args.length() == 1);                                 \
15566                                                               \
15567   CONVERT_ARG_CHECKED(SOURCE_TYPE, a, 0);                     \
15568                                                               \
15569   TARGET_TYPE::value_t result;                                \
15570   for (int i = 0; i < SOURCE_TYPE::kLanes; i++) {             \
15571     FUNCTION(a->getAt(i), &result.storage[i]);                \
15572   }                                                           \
15573                                                               \
15574   RETURN_##TARGET_TYPE##_RESULT(result);                      \
15575 }
15576
15577
15578 SIMD128_CONVERSION_FUNCTIONS(DECLARE_SIMD_CONVERSION_FUNCTION)
15579
15580
15581 template<typename T>
15582 static inline T Add(T a, T b) {
15583   return a + b;
15584 }
15585
15586
15587 template<typename T>
15588 static inline T Div(T a, T b) {
15589   return a / b;
15590 }
15591
15592
15593 template<typename T>
15594 static inline T Mul(T a, T b) {
15595   return a * b;
15596 }
15597
15598
15599 template<typename T>
15600 static inline T Sub(T a, T b) {
15601   return a - b;
15602 }
15603
15604
15605 template<typename T>
15606 static inline int32_t Equal(T a, T b) {
15607   return a == b ? -1 : 0;
15608 }
15609
15610
15611 template<typename T>
15612 static inline int32_t NotEqual(T a, T b) {
15613   return a != b ? -1 : 0;
15614 }
15615
15616
15617 template<typename T>
15618 static inline int32_t GreaterThanOrEqual(T a, T b) {
15619   return a >= b ? -1 : 0;
15620 }
15621
15622
15623 template<typename T>
15624 static inline int32_t GreaterThan(T a, T b) {
15625   return a > b ? -1 : 0;
15626 }
15627
15628
15629 template<typename T>
15630 static inline int32_t LessThan(T a, T b) {
15631   return a < b ? -1 : 0;
15632 }
15633
15634
15635 template<typename T>
15636 static inline int32_t LessThanOrEqual(T a, T b) {
15637   return a <= b ? -1 : 0;
15638 }
15639
15640
15641 template<typename T>
15642 static inline T And(T a, T b) {
15643   return a & b;
15644 }
15645
15646
15647 template<typename T>
15648 static inline T Or(T a, T b) {
15649   return a | b;
15650 }
15651
15652
15653 template<typename T>
15654 static inline T Xor(T a, T b) {
15655   return a ^ b;
15656 }
15657
15658
15659 #define SIMD128_BINARY_FUNCTIONS(V)                           \
15660   V(Float32x4, Add, Float32x4)                                \
15661   V(Float32x4, Div, Float32x4)                                \
15662   V(Float32x4, Max, Float32x4)                                \
15663   V(Float32x4, Min, Float32x4)                                \
15664   V(Float32x4, Mul, Float32x4)                                \
15665   V(Float32x4, Sub, Float32x4)                                \
15666   V(Float32x4, Equal, Int32x4)                                \
15667   V(Float32x4, NotEqual, Int32x4)                             \
15668   V(Float32x4, GreaterThanOrEqual, Int32x4)                   \
15669   V(Float32x4, GreaterThan, Int32x4)                          \
15670   V(Float32x4, LessThan, Int32x4)                             \
15671   V(Float32x4, LessThanOrEqual, Int32x4)                      \
15672   V(Float64x2, Add, Float64x2)                                \
15673   V(Float64x2, Div, Float64x2)                                \
15674   V(Float64x2, Max, Float64x2)                                \
15675   V(Float64x2, Min, Float64x2)                                \
15676   V(Float64x2, Mul, Float64x2)                                \
15677   V(Float64x2, Sub, Float64x2)                                \
15678   V(Int32x4, Add, Int32x4)                                    \
15679   V(Int32x4, And, Int32x4)                                    \
15680   V(Int32x4, Mul, Int32x4)                                    \
15681   V(Int32x4, Or, Int32x4)                                     \
15682   V(Int32x4, Sub, Int32x4)                                    \
15683   V(Int32x4, Xor, Int32x4)                                    \
15684   V(Int32x4, Equal, Int32x4)                                  \
15685   V(Int32x4, GreaterThan, Int32x4)                            \
15686   V(Int32x4, LessThan, Int32x4)
15687
15688
15689 #define DECLARE_SIMD_BINARY_FUNCTION(                         \
15690     TYPE, FUNCTION, RETURN_TYPE)                              \
15691 RUNTIME_FUNCTION(Runtime_##TYPE##FUNCTION) {    \
15692   HandleScope scope(isolate);                                 \
15693   DCHECK(args.length() == 2);                                 \
15694                                                               \
15695   CONVERT_ARG_CHECKED(TYPE, a, 0);                            \
15696   CONVERT_ARG_CHECKED(TYPE, b, 1);                            \
15697                                                               \
15698   RETURN_TYPE::value_t result;                                \
15699   for (int i = 0; i < TYPE::kLanes; i++) {                    \
15700     result.storage[i] = FUNCTION(a->getAt(i), b->getAt(i));   \
15701   }                                                           \
15702                                                               \
15703   RETURN_##RETURN_TYPE##_RESULT(result);                      \
15704 }
15705
15706
15707 SIMD128_BINARY_FUNCTIONS(DECLARE_SIMD_BINARY_FUNCTION)
15708
15709
15710 #define SIMD128_SHUFFLE_FUNCTIONS(V)                          \
15711   V(Float32x4)                                                \
15712   V(Int32x4)
15713
15714
15715 #define DECLARE_SIMD_SHUFFLE_FUNCTION(TYPE)                   \
15716 RUNTIME_FUNCTION(Runtime_##TYPE##Shuffle) {     \
15717   HandleScope scope(isolate);                                 \
15718   DCHECK(args.length() == 2);                                 \
15719                                                               \
15720   CONVERT_ARG_CHECKED(TYPE, a, 0);                            \
15721   RUNTIME_ASSERT(args[1]->IsNumber());                        \
15722   uint32_t m = NumberToUint32(args[1]);                       \
15723                                                               \
15724   TYPE::value_t result;                                       \
15725   for (int i = 0; i < TYPE::kLanes; i++) {                    \
15726     result.storage[i] = a->getAt((m >> (i * 2)) & 0x3);       \
15727   }                                                           \
15728                                                               \
15729   RETURN_##TYPE##_RESULT(result);                             \
15730 }
15731
15732
15733 SIMD128_SHUFFLE_FUNCTIONS(DECLARE_SIMD_SHUFFLE_FUNCTION)
15734
15735
15736 RUNTIME_FUNCTION(Runtime_Float32x4Scale) {
15737   HandleScope scope(isolate);
15738   DCHECK(args.length() == 2);
15739
15740   CONVERT_ARG_CHECKED(Float32x4, self, 0);
15741   RUNTIME_ASSERT(args[1]->IsNumber());
15742
15743   float _s = static_cast<float>(args.number_at(1));
15744   float32x4_value_t result;
15745   result.storage[0] = self->x() * _s;
15746   result.storage[1] = self->y() * _s;
15747   result.storage[2] = self->z() * _s;
15748   result.storage[3] = self->w() * _s;
15749
15750   RETURN_Float32x4_RESULT(result);
15751 }
15752
15753
15754 RUNTIME_FUNCTION(Runtime_Float64x2Scale) {
15755   HandleScope scope(isolate);
15756   DCHECK(args.length() == 2);
15757
15758   CONVERT_ARG_CHECKED(Float64x2, self, 0);
15759   RUNTIME_ASSERT(args[1]->IsNumber());
15760
15761   double _s = args.number_at(1);
15762   float64x2_value_t result;
15763   result.storage[0] = self->x() * _s;
15764   result.storage[1] = self->y() * _s;
15765
15766   RETURN_Float64x2_RESULT(result);
15767 }
15768
15769
15770 #define ARG_TO_FLOAT32(x) \
15771   CONVERT_DOUBLE_ARG_CHECKED(t, 1); \
15772   float x = static_cast<float>(t);
15773
15774
15775 #define ARG_TO_FLOAT64(x) \
15776   CONVERT_DOUBLE_ARG_CHECKED(x, 1); \
15777
15778
15779 #define ARG_TO_INT32(x) \
15780   RUNTIME_ASSERT(args[1]->IsNumber()); \
15781   int32_t x = NumberToInt32(args[1]);
15782
15783
15784 #define ARG_TO_BOOLEAN(x) \
15785   CONVERT_BOOLEAN_ARG_CHECKED(flag, 1); \
15786   int32_t x = flag ? -1 : 0;
15787
15788 #define SIMD128_SET_LANE_FUNCTIONS(V)                         \
15789   V(Float32x4, WithX, ARG_TO_FLOAT32, 0)                      \
15790   V(Float32x4, WithY, ARG_TO_FLOAT32, 1)                      \
15791   V(Float32x4, WithZ, ARG_TO_FLOAT32, 2)                      \
15792   V(Float32x4, WithW, ARG_TO_FLOAT32, 3)                      \
15793   V(Float64x2, WithX, ARG_TO_FLOAT64, 0)                      \
15794   V(Float64x2, WithY, ARG_TO_FLOAT64, 1)                      \
15795   V(Int32x4, WithX, ARG_TO_INT32, 0)                          \
15796   V(Int32x4, WithY, ARG_TO_INT32, 1)                          \
15797   V(Int32x4, WithZ, ARG_TO_INT32, 2)                          \
15798   V(Int32x4, WithW, ARG_TO_INT32, 3)                          \
15799   V(Int32x4, WithFlagX, ARG_TO_BOOLEAN, 0)                    \
15800   V(Int32x4, WithFlagY, ARG_TO_BOOLEAN, 1)                    \
15801   V(Int32x4, WithFlagZ, ARG_TO_BOOLEAN, 2)                    \
15802   V(Int32x4, WithFlagW, ARG_TO_BOOLEAN, 3)
15803
15804
15805 #define DECLARE_SIMD_SET_LANE_FUNCTION(                       \
15806     TYPE, NAME, ARG_FUNCTION, LANE)                           \
15807 RUNTIME_FUNCTION(Runtime_##TYPE##NAME) {        \
15808   HandleScope scope(isolate);                                 \
15809   DCHECK(args.length() == 2);                                 \
15810                                                               \
15811   CONVERT_ARG_CHECKED(TYPE, a, 0);                            \
15812   ARG_FUNCTION(value);                                        \
15813                                                               \
15814   TYPE::value_t result;                                       \
15815   for (int i = 0; i < TYPE::kLanes; i++) {                    \
15816     if (i != LANE)                                            \
15817       result.storage[i] = a->getAt(i);                        \
15818     else                                                      \
15819       result.storage[i] = value;                              \
15820   }                                                           \
15821                                                               \
15822   RETURN_##TYPE##_RESULT(result);                             \
15823 }
15824
15825
15826 SIMD128_SET_LANE_FUNCTIONS(DECLARE_SIMD_SET_LANE_FUNCTION)
15827
15828
15829 RUNTIME_FUNCTION(Runtime_Float32x4Clamp) {
15830   HandleScope scope(isolate);
15831   DCHECK(args.length() == 3);
15832
15833   CONVERT_ARG_CHECKED(Float32x4, self, 0);
15834   CONVERT_ARG_CHECKED(Float32x4, lo, 1);
15835   CONVERT_ARG_CHECKED(Float32x4, hi, 2);
15836
15837   float32x4_value_t result;
15838   float _x = self->x() > lo->x() ? self->x() : lo->x();
15839   float _y = self->y() > lo->y() ? self->y() : lo->y();
15840   float _z = self->z() > lo->z() ? self->z() : lo->z();
15841   float _w = self->w() > lo->w() ? self->w() : lo->w();
15842   result.storage[0] = _x > hi->x() ? hi->x() : _x;
15843   result.storage[1] = _y > hi->y() ? hi->y() : _y;
15844   result.storage[2] = _z > hi->z() ? hi->z() : _z;
15845   result.storage[3] = _w > hi->w() ? hi->w() : _w;
15846
15847   RETURN_Float32x4_RESULT(result);
15848 }
15849
15850
15851 RUNTIME_FUNCTION(Runtime_Float64x2Clamp) {
15852   HandleScope scope(isolate);
15853   DCHECK(args.length() == 3);
15854
15855   CONVERT_ARG_CHECKED(Float64x2, self, 0);
15856   CONVERT_ARG_CHECKED(Float64x2, lo, 1);
15857   CONVERT_ARG_CHECKED(Float64x2, hi, 2);
15858
15859   float64x2_value_t result;
15860   double _x = self->x() > lo->x() ? self->x() : lo->x();
15861   double _y = self->y() > lo->y() ? self->y() : lo->y();
15862   result.storage[0] = _x > hi->x() ? hi->x() : _x;
15863   result.storage[1] = _y > hi->y() ? hi->y() : _y;
15864
15865   RETURN_Float64x2_RESULT(result);
15866 }
15867
15868
15869 RUNTIME_FUNCTION(Runtime_Float32x4ShuffleMix) {
15870   HandleScope scope(isolate);
15871   DCHECK(args.length() == 3);
15872
15873   CONVERT_ARG_CHECKED(Float32x4, first, 0);
15874   CONVERT_ARG_CHECKED(Float32x4, second, 1);
15875   RUNTIME_ASSERT(args[2]->IsNumber());
15876
15877   uint32_t m = NumberToUint32(args[2]);
15878   float32x4_value_t result;
15879   float data1[4] = { first->x(), first->y(), first->z(), first->w() };
15880   float data2[4] = { second->x(), second->y(), second->z(), second->w() };
15881   result.storage[0] = data1[m & 0x3];
15882   result.storage[1] = data1[(m >> 2) & 0x3];
15883   result.storage[2] = data2[(m >> 4) & 0x3];
15884   result.storage[3] = data2[(m >> 6) & 0x3];
15885
15886   RETURN_Float32x4_RESULT(result);
15887 }
15888
15889
15890 RUNTIME_FUNCTION(Runtime_Float32x4Select) {
15891   HandleScope scope(isolate);
15892   DCHECK(args.length() == 3);
15893
15894   CONVERT_ARG_CHECKED(Int32x4, self, 0);
15895   CONVERT_ARG_CHECKED(Float32x4, tv, 1);
15896   CONVERT_ARG_CHECKED(Float32x4, fv, 2);
15897
15898   uint32_t _maskX = self->x();
15899   uint32_t _maskY = self->y();
15900   uint32_t _maskZ = self->z();
15901   uint32_t _maskW = self->w();
15902   // Extract floats and interpret them as masks.
15903   float32_uint32 tvx(tv->x());
15904   float32_uint32 tvy(tv->y());
15905   float32_uint32 tvz(tv->z());
15906   float32_uint32 tvw(tv->w());
15907   float32_uint32 fvx(fv->x());
15908   float32_uint32 fvy(fv->y());
15909   float32_uint32 fvz(fv->z());
15910   float32_uint32 fvw(fv->w());
15911   // Perform select.
15912   float32_uint32 tempX((_maskX & tvx.u) | (~_maskX & fvx.u));
15913   float32_uint32 tempY((_maskY & tvy.u) | (~_maskY & fvy.u));
15914   float32_uint32 tempZ((_maskZ & tvz.u) | (~_maskZ & fvz.u));
15915   float32_uint32 tempW((_maskW & tvw.u) | (~_maskW & fvw.u));
15916
15917   float32x4_value_t result;
15918   result.storage[0] = tempX.f;
15919   result.storage[1] = tempY.f;
15920   result.storage[2] = tempZ.f;
15921   result.storage[3] = tempW.f;
15922
15923   RETURN_Float32x4_RESULT(result);
15924 }
15925
15926
15927 RUNTIME_FUNCTION(Runtime_Int32x4Select) {
15928   HandleScope scope(isolate);
15929   DCHECK(args.length() == 3);
15930
15931   CONVERT_ARG_CHECKED(Int32x4, self, 0);
15932   CONVERT_ARG_CHECKED(Int32x4, tv, 1);
15933   CONVERT_ARG_CHECKED(Int32x4, fv, 2);
15934
15935   uint32_t _maskX = self->x();
15936   uint32_t _maskY = self->y();
15937   uint32_t _maskZ = self->z();
15938   uint32_t _maskW = self->w();
15939
15940   int32x4_value_t result;
15941   result.storage[0] = (_maskX & tv->x()) | (~_maskX & fv->x());
15942   result.storage[1] = (_maskY & tv->y()) | (~_maskY & fv->y());
15943   result.storage[2] = (_maskZ & tv->z()) | (~_maskZ & fv->z());
15944   result.storage[3] = (_maskW & tv->w()) | (~_maskW & fv->w());
15945
15946   RETURN_Int32x4_RESULT(result);
15947 }
15948
15949
15950 // ----------------------------------------------------------------------------
15951 // Reference implementation for inlined runtime functions.  Only used when the
15952 // compiler does not support a certain intrinsic.  Don't optimize these, but
15953 // implement the intrinsic in the respective compiler instead.
15954
15955 // TODO(mstarzinger): These are place-holder stubs for TurboFan and will
15956 // eventually all have a C++ implementation and this macro will be gone.
15957 #define U(name)                               \
15958   RUNTIME_FUNCTION(RuntimeReference_##name) { \
15959     UNIMPLEMENTED();                          \
15960     return NULL;                              \
15961   }
15962
15963 U(IsStringWrapperSafeForDefaultValueOf)
15964 U(GeneratorNext)
15965 U(GeneratorThrow)
15966 U(DebugBreakInOptimizedCode)
15967
15968 #undef U
15969
15970
15971 RUNTIME_FUNCTION(RuntimeReference_IsSmi) {
15972   SealHandleScope shs(isolate);
15973   DCHECK(args.length() == 1);
15974   CONVERT_ARG_CHECKED(Object, obj, 0);
15975   return isolate->heap()->ToBoolean(obj->IsSmi());
15976 }
15977
15978
15979 RUNTIME_FUNCTION(RuntimeReference_IsNonNegativeSmi) {
15980   SealHandleScope shs(isolate);
15981   DCHECK(args.length() == 1);
15982   CONVERT_ARG_CHECKED(Object, obj, 0);
15983   return isolate->heap()->ToBoolean(obj->IsSmi() &&
15984                                     Smi::cast(obj)->value() >= 0);
15985 }
15986
15987
15988 RUNTIME_FUNCTION(RuntimeReference_IsArray) {
15989   SealHandleScope shs(isolate);
15990   DCHECK(args.length() == 1);
15991   CONVERT_ARG_CHECKED(Object, obj, 0);
15992   return isolate->heap()->ToBoolean(obj->IsJSArray());
15993 }
15994
15995
15996 RUNTIME_FUNCTION(RuntimeReference_IsRegExp) {
15997   SealHandleScope shs(isolate);
15998   DCHECK(args.length() == 1);
15999   CONVERT_ARG_CHECKED(Object, obj, 0);
16000   return isolate->heap()->ToBoolean(obj->IsJSRegExp());
16001 }
16002
16003
16004 RUNTIME_FUNCTION(RuntimeReference_IsConstructCall) {
16005   SealHandleScope shs(isolate);
16006   DCHECK(args.length() == 0);
16007   JavaScriptFrameIterator it(isolate);
16008   JavaScriptFrame* frame = it.frame();
16009   return isolate->heap()->ToBoolean(frame->IsConstructor());
16010 }
16011
16012
16013 RUNTIME_FUNCTION(RuntimeReference_CallFunction) {
16014   SealHandleScope shs(isolate);
16015   return __RT_impl_Runtime_Call(args, isolate);
16016 }
16017
16018
16019 RUNTIME_FUNCTION(RuntimeReference_ArgumentsLength) {
16020   SealHandleScope shs(isolate);
16021   DCHECK(args.length() == 0);
16022   JavaScriptFrameIterator it(isolate);
16023   JavaScriptFrame* frame = it.frame();
16024   return Smi::FromInt(frame->GetArgumentsLength());
16025 }
16026
16027
16028 RUNTIME_FUNCTION(RuntimeReference_Arguments) {
16029   SealHandleScope shs(isolate);
16030   return __RT_impl_Runtime_GetArgumentsProperty(args, isolate);
16031 }
16032
16033
16034 RUNTIME_FUNCTION(RuntimeReference_ValueOf) {
16035   SealHandleScope shs(isolate);
16036   DCHECK(args.length() == 1);
16037   CONVERT_ARG_CHECKED(Object, obj, 0);
16038   if (!obj->IsJSValue()) return obj;
16039   return JSValue::cast(obj)->value();
16040 }
16041
16042
16043 RUNTIME_FUNCTION(RuntimeReference_SetValueOf) {
16044   SealHandleScope shs(isolate);
16045   DCHECK(args.length() == 2);
16046   CONVERT_ARG_CHECKED(Object, obj, 0);
16047   CONVERT_ARG_CHECKED(Object, value, 1);
16048   if (!obj->IsJSValue()) return value;
16049   JSValue::cast(obj)->set_value(value);
16050   return value;
16051 }
16052
16053
16054 RUNTIME_FUNCTION(RuntimeReference_DateField) {
16055   SealHandleScope shs(isolate);
16056   DCHECK(args.length() == 2);
16057   CONVERT_ARG_CHECKED(Object, obj, 0);
16058   CONVERT_SMI_ARG_CHECKED(index, 1);
16059   if (!obj->IsJSDate()) {
16060     HandleScope scope(isolate);
16061     return isolate->Throw(*isolate->factory()->NewTypeError(
16062         "not_date_object", HandleVector<Object>(NULL, 0)));
16063   }
16064   JSDate* date = JSDate::cast(obj);
16065   if (index == 0) return date->value();
16066   return JSDate::GetField(date, Smi::FromInt(index));
16067 }
16068
16069
16070 RUNTIME_FUNCTION(RuntimeReference_StringCharFromCode) {
16071   SealHandleScope shs(isolate);
16072   return __RT_impl_Runtime_CharFromCode(args, isolate);
16073 }
16074
16075
16076 RUNTIME_FUNCTION(RuntimeReference_StringCharAt) {
16077   SealHandleScope shs(isolate);
16078   DCHECK(args.length() == 2);
16079   if (!args[0]->IsString()) return Smi::FromInt(0);
16080   if (!args[1]->IsNumber()) return Smi::FromInt(0);
16081   if (std::isinf(args.number_at(1))) return isolate->heap()->empty_string();
16082   Object* code = __RT_impl_Runtime_StringCharCodeAtRT(args, isolate);
16083   if (code->IsNaN()) return isolate->heap()->empty_string();
16084   return __RT_impl_Runtime_CharFromCode(Arguments(1, &code), isolate);
16085 }
16086
16087
16088 RUNTIME_FUNCTION(RuntimeReference_OneByteSeqStringSetChar) {
16089   SealHandleScope shs(isolate);
16090   DCHECK(args.length() == 3);
16091   CONVERT_ARG_CHECKED(SeqOneByteString, string, 0);
16092   CONVERT_SMI_ARG_CHECKED(index, 1);
16093   CONVERT_SMI_ARG_CHECKED(value, 2);
16094   string->SeqOneByteStringSet(index, value);
16095   return string;
16096 }
16097
16098
16099 RUNTIME_FUNCTION(RuntimeReference_TwoByteSeqStringSetChar) {
16100   SealHandleScope shs(isolate);
16101   DCHECK(args.length() == 3);
16102   CONVERT_ARG_CHECKED(SeqTwoByteString, string, 0);
16103   CONVERT_SMI_ARG_CHECKED(index, 1);
16104   CONVERT_SMI_ARG_CHECKED(value, 2);
16105   string->SeqTwoByteStringSet(index, value);
16106   return string;
16107 }
16108
16109
16110 RUNTIME_FUNCTION(RuntimeReference_ObjectEquals) {
16111   SealHandleScope shs(isolate);
16112   DCHECK(args.length() == 2);
16113   CONVERT_ARG_CHECKED(Object, obj1, 0);
16114   CONVERT_ARG_CHECKED(Object, obj2, 1);
16115   return isolate->heap()->ToBoolean(obj1 == obj2);
16116 }
16117
16118
16119 RUNTIME_FUNCTION(RuntimeReference_IsObject) {
16120   SealHandleScope shs(isolate);
16121   DCHECK(args.length() == 1);
16122   CONVERT_ARG_CHECKED(Object, obj, 0);
16123   if (!obj->IsHeapObject()) return isolate->heap()->false_value();
16124   if (obj->IsNull()) return isolate->heap()->true_value();
16125   if (obj->IsUndetectableObject()) return isolate->heap()->false_value();
16126   Map* map = HeapObject::cast(obj)->map();
16127   bool is_non_callable_spec_object =
16128       map->instance_type() >= FIRST_NONCALLABLE_SPEC_OBJECT_TYPE &&
16129       map->instance_type() <= LAST_NONCALLABLE_SPEC_OBJECT_TYPE;
16130   return isolate->heap()->ToBoolean(is_non_callable_spec_object);
16131 }
16132
16133
16134 RUNTIME_FUNCTION(RuntimeReference_IsFunction) {
16135   SealHandleScope shs(isolate);
16136   DCHECK(args.length() == 1);
16137   CONVERT_ARG_CHECKED(Object, obj, 0);
16138   return isolate->heap()->ToBoolean(obj->IsJSFunction());
16139 }
16140
16141
16142 RUNTIME_FUNCTION(RuntimeReference_IsUndetectableObject) {
16143   SealHandleScope shs(isolate);
16144   DCHECK(args.length() == 1);
16145   CONVERT_ARG_CHECKED(Object, obj, 0);
16146   return isolate->heap()->ToBoolean(obj->IsUndetectableObject());
16147 }
16148
16149
16150 RUNTIME_FUNCTION(RuntimeReference_IsSpecObject) {
16151   SealHandleScope shs(isolate);
16152   DCHECK(args.length() == 1);
16153   CONVERT_ARG_CHECKED(Object, obj, 0);
16154   return isolate->heap()->ToBoolean(obj->IsSpecObject());
16155 }
16156
16157
16158 RUNTIME_FUNCTION(RuntimeReference_MathPow) {
16159   SealHandleScope shs(isolate);
16160   return __RT_impl_Runtime_MathPowSlow(args, isolate);
16161 }
16162
16163
16164 RUNTIME_FUNCTION(RuntimeReference_IsMinusZero) {
16165   SealHandleScope shs(isolate);
16166   DCHECK(args.length() == 1);
16167   CONVERT_ARG_CHECKED(Object, obj, 0);
16168   if (!obj->IsHeapNumber()) return isolate->heap()->false_value();
16169   HeapNumber* number = HeapNumber::cast(obj);
16170   return isolate->heap()->ToBoolean(IsMinusZero(number->value()));
16171 }
16172
16173
16174 RUNTIME_FUNCTION(RuntimeReference_HasCachedArrayIndex) {
16175   SealHandleScope shs(isolate);
16176   DCHECK(args.length() == 1);
16177   return isolate->heap()->false_value();
16178 }
16179
16180
16181 RUNTIME_FUNCTION(RuntimeReference_GetCachedArrayIndex) {
16182   SealHandleScope shs(isolate);
16183   DCHECK(args.length() == 1);
16184   return isolate->heap()->undefined_value();
16185 }
16186
16187
16188 RUNTIME_FUNCTION(RuntimeReference_FastAsciiArrayJoin) {
16189   SealHandleScope shs(isolate);
16190   DCHECK(args.length() == 2);
16191   return isolate->heap()->undefined_value();
16192 }
16193
16194
16195 RUNTIME_FUNCTION(RuntimeReference_ClassOf) {
16196   SealHandleScope shs(isolate);
16197   DCHECK(args.length() == 1);
16198   CONVERT_ARG_CHECKED(Object, obj, 0);
16199   if (!obj->IsJSReceiver()) return isolate->heap()->null_value();
16200   return JSReceiver::cast(obj)->class_name();
16201 }
16202
16203
16204 RUNTIME_FUNCTION(RuntimeReference_StringCharCodeAt) {
16205   SealHandleScope shs(isolate);
16206   DCHECK(args.length() == 2);
16207   if (!args[0]->IsString()) return isolate->heap()->undefined_value();
16208   if (!args[1]->IsNumber()) return isolate->heap()->undefined_value();
16209   if (std::isinf(args.number_at(1))) return isolate->heap()->nan_value();
16210   return __RT_impl_Runtime_StringCharCodeAtRT(args, isolate);
16211 }
16212
16213
16214 RUNTIME_FUNCTION(RuntimeReference_StringAdd) {
16215   SealHandleScope shs(isolate);
16216   return __RT_impl_Runtime_StringAdd(args, isolate);
16217 }
16218
16219
16220 RUNTIME_FUNCTION(RuntimeReference_SubString) {
16221   SealHandleScope shs(isolate);
16222   return __RT_impl_Runtime_SubString(args, isolate);
16223 }
16224
16225
16226 RUNTIME_FUNCTION(RuntimeReference_StringCompare) {
16227   SealHandleScope shs(isolate);
16228   return __RT_impl_Runtime_StringCompare(args, isolate);
16229 }
16230
16231
16232 RUNTIME_FUNCTION(RuntimeReference_RegExpExec) {
16233   SealHandleScope shs(isolate);
16234   return __RT_impl_Runtime_RegExpExecRT(args, isolate);
16235 }
16236
16237
16238 RUNTIME_FUNCTION(RuntimeReference_RegExpConstructResult) {
16239   SealHandleScope shs(isolate);
16240   return __RT_impl_Runtime_RegExpConstructResult(args, isolate);
16241 }
16242
16243
16244 RUNTIME_FUNCTION(RuntimeReference_GetFromCache) {
16245   HandleScope scope(isolate);
16246   DCHECK(args.length() == 2);
16247   CONVERT_SMI_ARG_CHECKED(id, 0);
16248   args[0] = isolate->native_context()->jsfunction_result_caches()->get(id);
16249   return __RT_impl_Runtime_GetFromCache(args, isolate);
16250 }
16251
16252
16253 RUNTIME_FUNCTION(RuntimeReference_NumberToString) {
16254   SealHandleScope shs(isolate);
16255   return __RT_impl_Runtime_NumberToStringRT(args, isolate);
16256 }
16257
16258
16259 RUNTIME_FUNCTION(RuntimeReference_DebugIsActive) {
16260   SealHandleScope shs(isolate);
16261   return Smi::FromInt(isolate->debug()->is_active());
16262 }
16263
16264
16265 // ----------------------------------------------------------------------------
16266 // Implementation of Runtime
16267
16268 #define F(name, number_of_args, result_size)                                  \
16269   {                                                                           \
16270     Runtime::k##name, Runtime::RUNTIME, #name, FUNCTION_ADDR(Runtime_##name), \
16271         number_of_args, result_size                                           \
16272   }                                                                           \
16273   ,
16274
16275
16276 #define I(name, number_of_args, result_size)                                \
16277   {                                                                         \
16278     Runtime::kInline##name, Runtime::INLINE, "_" #name,                     \
16279         FUNCTION_ADDR(RuntimeReference_##name), number_of_args, result_size \
16280   }                                                                         \
16281   ,
16282
16283
16284 #define IO(name, number_of_args, result_size)                              \
16285   {                                                                        \
16286     Runtime::kInlineOptimized##name, Runtime::INLINE_OPTIMIZED, "_" #name, \
16287         FUNCTION_ADDR(Runtime_##name), number_of_args, result_size         \
16288   }                                                                        \
16289   ,
16290
16291
16292 static const Runtime::Function kIntrinsicFunctions[] = {
16293   RUNTIME_FUNCTION_LIST(F)
16294   INLINE_OPTIMIZED_FUNCTION_LIST(F)
16295   INLINE_FUNCTION_LIST(I)
16296   INLINE_OPTIMIZED_FUNCTION_LIST(IO)
16297 };
16298
16299 #undef IO
16300 #undef I
16301 #undef F
16302
16303
16304 void Runtime::InitializeIntrinsicFunctionNames(Isolate* isolate,
16305                                                Handle<NameDictionary> dict) {
16306   DCHECK(dict->NumberOfElements() == 0);
16307   HandleScope scope(isolate);
16308   for (int i = 0; i < kNumFunctions; ++i) {
16309     const char* name = kIntrinsicFunctions[i].name;
16310     if (name == NULL) continue;
16311     Handle<NameDictionary> new_dict = NameDictionary::Add(
16312         dict,
16313         isolate->factory()->InternalizeUtf8String(name),
16314         Handle<Smi>(Smi::FromInt(i), isolate),
16315         PropertyDetails(NONE, NORMAL, Representation::None()));
16316     // The dictionary does not need to grow.
16317     CHECK(new_dict.is_identical_to(dict));
16318   }
16319 }
16320
16321
16322 const Runtime::Function* Runtime::FunctionForName(Handle<String> name) {
16323   Heap* heap = name->GetHeap();
16324   int entry = heap->intrinsic_function_names()->FindEntry(name);
16325   if (entry != kNotFound) {
16326     Object* smi_index = heap->intrinsic_function_names()->ValueAt(entry);
16327     int function_index = Smi::cast(smi_index)->value();
16328     return &(kIntrinsicFunctions[function_index]);
16329   }
16330   return NULL;
16331 }
16332
16333
16334 const Runtime::Function* Runtime::FunctionForEntry(Address entry) {
16335   for (size_t i = 0; i < ARRAY_SIZE(kIntrinsicFunctions); ++i) {
16336     if (entry == kIntrinsicFunctions[i].entry) {
16337       return &(kIntrinsicFunctions[i]);
16338     }
16339   }
16340   return NULL;
16341 }
16342
16343
16344 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) {
16345   return &(kIntrinsicFunctions[static_cast<int>(id)]);
16346 }
16347
16348 } }  // namespace v8::internal