Upstream version 7.36.149.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 "v8.h"
9
10 #include "accessors.h"
11 #include "allocation-site-scopes.h"
12 #include "api.h"
13 #include "arguments.h"
14 #include "bootstrapper.h"
15 #include "codegen.h"
16 #include "compilation-cache.h"
17 #include "compiler.h"
18 #include "conversions.h"
19 #include "cpu.h"
20 #include "cpu-profiler.h"
21 #include "dateparser-inl.h"
22 #include "debug.h"
23 #include "deoptimizer.h"
24 #include "date.h"
25 #include "execution.h"
26 #include "full-codegen.h"
27 #include "global-handles.h"
28 #include "isolate-inl.h"
29 #include "jsregexp.h"
30 #include "jsregexp-inl.h"
31 #include "json-parser.h"
32 #include "json-stringifier.h"
33 #include "liveedit.h"
34 #include "misc-intrinsics.h"
35 #include "parser.h"
36 #include "platform.h"
37 #include "runtime-profiler.h"
38 #include "runtime.h"
39 #include "scopeinfo.h"
40 #include "smart-pointers.h"
41 #include "string-search.h"
42 #include "stub-cache.h"
43 #include "uri.h"
44 #include "v8threads.h"
45 #include "vm-state-inl.h"
46
47 #ifdef V8_I18N_SUPPORT
48 #include "i18n.h"
49 #include "unicode/brkiter.h"
50 #include "unicode/calendar.h"
51 #include "unicode/coll.h"
52 #include "unicode/curramt.h"
53 #include "unicode/datefmt.h"
54 #include "unicode/dcfmtsym.h"
55 #include "unicode/decimfmt.h"
56 #include "unicode/dtfmtsym.h"
57 #include "unicode/dtptngen.h"
58 #include "unicode/locid.h"
59 #include "unicode/numfmt.h"
60 #include "unicode/numsys.h"
61 #include "unicode/rbbi.h"
62 #include "unicode/smpdtfmt.h"
63 #include "unicode/timezone.h"
64 #include "unicode/uchar.h"
65 #include "unicode/ucol.h"
66 #include "unicode/ucurr.h"
67 #include "unicode/uloc.h"
68 #include "unicode/unum.h"
69 #include "unicode/uversion.h"
70 #endif
71
72 #ifndef _STLP_VENDOR_CSTD
73 // STLPort doesn't import fpclassify and isless into the std namespace.
74 using std::fpclassify;
75 using std::isless;
76 #endif
77
78 namespace v8 {
79 namespace internal {
80
81
82 #define RUNTIME_ASSERT(value) \
83   if (!(value)) return isolate->ThrowIllegalOperation();
84
85 #define RUNTIME_ASSERT_HANDLIFIED(value, T)                          \
86   if (!(value)) {                                                    \
87     isolate->ThrowIllegalOperation();                                \
88     return MaybeHandle<T>();                                         \
89   }
90
91 // Cast the given object to a value of the specified type and store
92 // it in a variable with the given name.  If the object is not of the
93 // expected type call IllegalOperation and return.
94 #define CONVERT_ARG_CHECKED(Type, name, index)                       \
95   RUNTIME_ASSERT(args[index]->Is##Type());                           \
96   Type* name = Type::cast(args[index]);
97
98 #define CONVERT_ARG_HANDLE_CHECKED(Type, name, index)                \
99   RUNTIME_ASSERT(args[index]->Is##Type());                           \
100   Handle<Type> name = args.at<Type>(index);
101
102 #define CONVERT_NUMBER_ARG_HANDLE_CHECKED(name, index)               \
103   RUNTIME_ASSERT(args[index]->IsNumber());                           \
104   Handle<Object> name = args.at<Object>(index);
105
106 // Cast the given object to a boolean and store it in a variable with
107 // the given name.  If the object is not a boolean call IllegalOperation
108 // and return.
109 #define CONVERT_BOOLEAN_ARG_CHECKED(name, index)                     \
110   RUNTIME_ASSERT(args[index]->IsBoolean());                          \
111   bool name = args[index]->IsTrue();
112
113 // Cast the given argument to a Smi and store its value in an int variable
114 // with the given name.  If the argument is not a Smi call IllegalOperation
115 // and return.
116 #define CONVERT_SMI_ARG_CHECKED(name, index)                         \
117   RUNTIME_ASSERT(args[index]->IsSmi());                              \
118   int name = args.smi_at(index);
119
120 // Cast the given argument to a double and store it in a variable with
121 // the given name.  If the argument is not a number (as opposed to
122 // the number not-a-number) call IllegalOperation and return.
123 #define CONVERT_DOUBLE_ARG_CHECKED(name, index)                      \
124   RUNTIME_ASSERT(args[index]->IsNumber());                           \
125   double name = args.number_at(index);
126
127 // Call the specified converter on the object *comand store the result in
128 // a variable of the specified type with the given name.  If the
129 // object is not a Number call IllegalOperation and return.
130 #define CONVERT_NUMBER_CHECKED(type, name, Type, obj)                \
131   RUNTIME_ASSERT(obj->IsNumber());                                   \
132   type name = NumberTo##Type(obj);
133
134
135 // Cast the given argument to PropertyDetails and store its value in a
136 // variable with the given name.  If the argument is not a Smi call
137 // IllegalOperation and return.
138 #define CONVERT_PROPERTY_DETAILS_CHECKED(name, index)                \
139   RUNTIME_ASSERT(args[index]->IsSmi());                              \
140   PropertyDetails name = PropertyDetails(Smi::cast(args[index]));
141
142
143 // Assert that the given argument has a valid value for a StrictMode
144 // and store it in a StrictMode variable with the given name.
145 #define CONVERT_STRICT_MODE_ARG_CHECKED(name, index)                 \
146   RUNTIME_ASSERT(args[index]->IsSmi());                              \
147   RUNTIME_ASSERT(args.smi_at(index) == STRICT ||                     \
148                  args.smi_at(index) == SLOPPY);                      \
149   StrictMode name = static_cast<StrictMode>(args.smi_at(index));
150
151
152 static Handle<Map> ComputeObjectLiteralMap(
153     Handle<Context> context,
154     Handle<FixedArray> constant_properties,
155     bool* is_result_from_cache) {
156   Isolate* isolate = context->GetIsolate();
157   int properties_length = constant_properties->length();
158   int number_of_properties = properties_length / 2;
159   // Check that there are only internal strings and array indices among keys.
160   int number_of_string_keys = 0;
161   for (int p = 0; p != properties_length; p += 2) {
162     Object* key = constant_properties->get(p);
163     uint32_t element_index = 0;
164     if (key->IsInternalizedString()) {
165       number_of_string_keys++;
166     } else if (key->ToArrayIndex(&element_index)) {
167       // An index key does not require space in the property backing store.
168       number_of_properties--;
169     } else {
170       // Bail out as a non-internalized-string non-index key makes caching
171       // impossible.
172       // ASSERT to make sure that the if condition after the loop is false.
173       ASSERT(number_of_string_keys != number_of_properties);
174       break;
175     }
176   }
177   // If we only have internalized strings and array indices among keys then we
178   // can use the map cache in the native context.
179   const int kMaxKeys = 10;
180   if ((number_of_string_keys == number_of_properties) &&
181       (number_of_string_keys < kMaxKeys)) {
182     // Create the fixed array with the key.
183     Handle<FixedArray> keys =
184         isolate->factory()->NewFixedArray(number_of_string_keys);
185     if (number_of_string_keys > 0) {
186       int index = 0;
187       for (int p = 0; p < properties_length; p += 2) {
188         Object* key = constant_properties->get(p);
189         if (key->IsInternalizedString()) {
190           keys->set(index++, key);
191         }
192       }
193       ASSERT(index == number_of_string_keys);
194     }
195     *is_result_from_cache = true;
196     return isolate->factory()->ObjectLiteralMapFromCache(context, keys);
197   }
198   *is_result_from_cache = false;
199   return Map::Create(handle(context->object_function()), number_of_properties);
200 }
201
202
203 MUST_USE_RESULT static MaybeHandle<Object> CreateLiteralBoilerplate(
204     Isolate* isolate,
205     Handle<FixedArray> literals,
206     Handle<FixedArray> constant_properties);
207
208
209 MUST_USE_RESULT static MaybeHandle<Object> CreateObjectLiteralBoilerplate(
210     Isolate* isolate,
211     Handle<FixedArray> literals,
212     Handle<FixedArray> constant_properties,
213     bool should_have_fast_elements,
214     bool has_function_literal) {
215   // Get the native context from the literals array.  This is the
216   // context in which the function was created and we use the object
217   // function from this context to create the object literal.  We do
218   // not use the object function from the current native context
219   // because this might be the object function from another context
220   // which we should not have access to.
221   Handle<Context> context =
222       Handle<Context>(JSFunction::NativeContextFromLiterals(*literals));
223
224   // In case we have function literals, we want the object to be in
225   // slow properties mode for now. We don't go in the map cache because
226   // maps with constant functions can't be shared if the functions are
227   // not the same (which is the common case).
228   bool is_result_from_cache = false;
229   Handle<Map> map = has_function_literal
230       ? Handle<Map>(context->object_function()->initial_map())
231       : ComputeObjectLiteralMap(context,
232                                 constant_properties,
233                                 &is_result_from_cache);
234
235   PretenureFlag pretenure_flag =
236       isolate->heap()->InNewSpace(*literals) ? NOT_TENURED : TENURED;
237
238   Handle<JSObject> boilerplate =
239       isolate->factory()->NewJSObjectFromMap(map, pretenure_flag);
240
241   // Normalize the elements of the boilerplate to save space if needed.
242   if (!should_have_fast_elements) JSObject::NormalizeElements(boilerplate);
243
244   // Add the constant properties to the boilerplate.
245   int length = constant_properties->length();
246   bool should_transform =
247       !is_result_from_cache && boilerplate->HasFastProperties();
248   if (should_transform || has_function_literal) {
249     // Normalize the properties of object to avoid n^2 behavior
250     // when extending the object multiple properties. Indicate the number of
251     // properties to be added.
252     JSObject::NormalizeProperties(
253         boilerplate, KEEP_INOBJECT_PROPERTIES, length / 2);
254   }
255
256   // TODO(verwaest): Support tracking representations in the boilerplate.
257   for (int index = 0; index < length; index +=2) {
258     Handle<Object> key(constant_properties->get(index+0), isolate);
259     Handle<Object> value(constant_properties->get(index+1), isolate);
260     if (value->IsFixedArray()) {
261       // The value contains the constant_properties of a
262       // simple object or array literal.
263       Handle<FixedArray> array = Handle<FixedArray>::cast(value);
264       ASSIGN_RETURN_ON_EXCEPTION(
265           isolate, value,
266           CreateLiteralBoilerplate(isolate, literals, array),
267           Object);
268     }
269     MaybeHandle<Object> maybe_result;
270     uint32_t element_index = 0;
271     StoreMode mode = value->IsJSObject() ? FORCE_FIELD : ALLOW_AS_CONSTANT;
272     if (key->IsInternalizedString()) {
273       if (Handle<String>::cast(key)->AsArrayIndex(&element_index)) {
274         // Array index as string (uint32).
275         maybe_result = JSObject::SetOwnElement(
276             boilerplate, element_index, value, SLOPPY);
277       } else {
278         Handle<String> name(String::cast(*key));
279         ASSERT(!name->AsArrayIndex(&element_index));
280         maybe_result = JSObject::SetLocalPropertyIgnoreAttributes(
281             boilerplate, name, value, NONE,
282             Object::OPTIMAL_REPRESENTATION, mode);
283       }
284     } else if (key->ToArrayIndex(&element_index)) {
285       // Array index (uint32).
286       maybe_result = JSObject::SetOwnElement(
287           boilerplate, element_index, value, SLOPPY);
288     } else {
289       // Non-uint32 number.
290       ASSERT(key->IsNumber());
291       double num = key->Number();
292       char arr[100];
293       Vector<char> buffer(arr, ARRAY_SIZE(arr));
294       const char* str = DoubleToCString(num, buffer);
295       Handle<String> name = isolate->factory()->NewStringFromAsciiChecked(str);
296       maybe_result = JSObject::SetLocalPropertyIgnoreAttributes(
297           boilerplate, name, value, NONE,
298           Object::OPTIMAL_REPRESENTATION, mode);
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::TransformToFastProperties(
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 static const int kSmiLiteralMinimumLength = 1024;
341
342
343 MaybeHandle<Object> Runtime::CreateArrayLiteralBoilerplate(
344     Isolate* isolate,
345     Handle<FixedArray> literals,
346     Handle<FixedArray> elements) {
347   // Create the JSArray.
348   Handle<JSFunction> constructor(
349       JSFunction::NativeContextFromLiterals(*literals)->array_function());
350
351   PretenureFlag pretenure_flag =
352       isolate->heap()->InNewSpace(*literals) ? NOT_TENURED : TENURED;
353
354   Handle<JSArray> object = Handle<JSArray>::cast(
355       isolate->factory()->NewJSObject(constructor, pretenure_flag));
356
357   ElementsKind constant_elements_kind =
358       static_cast<ElementsKind>(Smi::cast(elements->get(0))->value());
359   Handle<FixedArrayBase> constant_elements_values(
360       FixedArrayBase::cast(elements->get(1)));
361
362   { DisallowHeapAllocation no_gc;
363     ASSERT(IsFastElementsKind(constant_elements_kind));
364     Context* native_context = isolate->context()->native_context();
365     Object* maps_array = native_context->js_array_maps();
366     ASSERT(!maps_array->IsUndefined());
367     Object* map = FixedArray::cast(maps_array)->get(constant_elements_kind);
368     object->set_map(Map::cast(map));
369   }
370
371   Handle<FixedArrayBase> copied_elements_values;
372   if (IsFastDoubleElementsKind(constant_elements_kind)) {
373     ASSERT(FLAG_smi_only_arrays);
374     copied_elements_values = isolate->factory()->CopyFixedDoubleArray(
375         Handle<FixedDoubleArray>::cast(constant_elements_values));
376   } else {
377     ASSERT(IsFastSmiOrObjectElementsKind(constant_elements_kind));
378     const bool is_cow =
379         (constant_elements_values->map() ==
380          isolate->heap()->fixed_cow_array_map());
381     if (is_cow) {
382       copied_elements_values = constant_elements_values;
383 #if DEBUG
384       Handle<FixedArray> fixed_array_values =
385           Handle<FixedArray>::cast(copied_elements_values);
386       for (int i = 0; i < fixed_array_values->length(); i++) {
387         ASSERT(!fixed_array_values->get(i)->IsFixedArray());
388       }
389 #endif
390     } else {
391       Handle<FixedArray> fixed_array_values =
392           Handle<FixedArray>::cast(constant_elements_values);
393       Handle<FixedArray> fixed_array_values_copy =
394           isolate->factory()->CopyFixedArray(fixed_array_values);
395       copied_elements_values = fixed_array_values_copy;
396       for (int i = 0; i < fixed_array_values->length(); i++) {
397         if (fixed_array_values->get(i)->IsFixedArray()) {
398           // The value contains the constant_properties of a
399           // simple object or array literal.
400           Handle<FixedArray> fa(FixedArray::cast(fixed_array_values->get(i)));
401           Handle<Object> result;
402           ASSIGN_RETURN_ON_EXCEPTION(
403               isolate, result,
404               CreateLiteralBoilerplate(isolate, literals, fa),
405               Object);
406           fixed_array_values_copy->set(i, *result);
407         }
408       }
409     }
410   }
411   object->set_elements(*copied_elements_values);
412   object->set_length(Smi::FromInt(copied_elements_values->length()));
413
414   //  Ensure that the boilerplate object has FAST_*_ELEMENTS, unless the flag is
415   //  on or the object is larger than the threshold.
416   if (!FLAG_smi_only_arrays &&
417       constant_elements_values->length() < kSmiLiteralMinimumLength) {
418     ElementsKind elements_kind = object->GetElementsKind();
419     if (!IsFastObjectElementsKind(elements_kind)) {
420       if (IsFastHoleyElementsKind(elements_kind)) {
421         TransitionElements(object, FAST_HOLEY_ELEMENTS, isolate).Check();
422       } else {
423         TransitionElements(object, FAST_ELEMENTS, isolate).Check();
424       }
425     }
426   }
427
428   JSObject::ValidateElements(object);
429   return object;
430 }
431
432
433 MUST_USE_RESULT static MaybeHandle<Object> CreateLiteralBoilerplate(
434     Isolate* isolate,
435     Handle<FixedArray> literals,
436     Handle<FixedArray> array) {
437   Handle<FixedArray> elements = CompileTimeValue::GetElements(array);
438   const bool kHasNoFunctionLiteral = false;
439   switch (CompileTimeValue::GetLiteralType(array)) {
440     case CompileTimeValue::OBJECT_LITERAL_FAST_ELEMENTS:
441       return CreateObjectLiteralBoilerplate(isolate,
442                                             literals,
443                                             elements,
444                                             true,
445                                             kHasNoFunctionLiteral);
446     case CompileTimeValue::OBJECT_LITERAL_SLOW_ELEMENTS:
447       return CreateObjectLiteralBoilerplate(isolate,
448                                             literals,
449                                             elements,
450                                             false,
451                                             kHasNoFunctionLiteral);
452     case CompileTimeValue::ARRAY_LITERAL:
453       return Runtime::CreateArrayLiteralBoilerplate(
454           isolate, literals, elements);
455     default:
456       UNREACHABLE();
457       return MaybeHandle<Object>();
458   }
459 }
460
461
462 RUNTIME_FUNCTION(RuntimeHidden_CreateObjectLiteral) {
463   HandleScope scope(isolate);
464   ASSERT(args.length() == 4);
465   CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
466   CONVERT_SMI_ARG_CHECKED(literals_index, 1);
467   CONVERT_ARG_HANDLE_CHECKED(FixedArray, constant_properties, 2);
468   CONVERT_SMI_ARG_CHECKED(flags, 3);
469   bool should_have_fast_elements = (flags & ObjectLiteral::kFastElements) != 0;
470   bool has_function_literal = (flags & ObjectLiteral::kHasFunction) != 0;
471
472   RUNTIME_ASSERT(literals_index >= 0 && literals_index < literals->length());
473
474   // Check if boilerplate exists. If not, create it first.
475   Handle<Object> literal_site(literals->get(literals_index), isolate);
476   Handle<AllocationSite> site;
477   Handle<JSObject> boilerplate;
478   if (*literal_site == isolate->heap()->undefined_value()) {
479     Handle<Object> raw_boilerplate;
480     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
481         isolate, raw_boilerplate,
482         CreateObjectLiteralBoilerplate(
483             isolate,
484             literals,
485             constant_properties,
486             should_have_fast_elements,
487             has_function_literal));
488     boilerplate = Handle<JSObject>::cast(raw_boilerplate);
489
490     AllocationSiteCreationContext creation_context(isolate);
491     site = creation_context.EnterNewScope();
492     RETURN_FAILURE_ON_EXCEPTION(
493         isolate,
494         JSObject::DeepWalk(boilerplate, &creation_context));
495     creation_context.ExitScope(site, boilerplate);
496
497     // Update the functions literal and return the boilerplate.
498     literals->set(literals_index, *site);
499   } else {
500     site = Handle<AllocationSite>::cast(literal_site);
501     boilerplate = Handle<JSObject>(JSObject::cast(site->transition_info()),
502                                    isolate);
503   }
504
505   AllocationSiteUsageContext usage_context(isolate, site, true);
506   usage_context.EnterNewScope();
507   MaybeHandle<Object> maybe_copy = JSObject::DeepCopy(
508       boilerplate, &usage_context);
509   usage_context.ExitScope(site, boilerplate);
510   Handle<Object> copy;
511   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, copy, maybe_copy);
512   return *copy;
513 }
514
515
516 MUST_USE_RESULT static MaybeHandle<AllocationSite> GetLiteralAllocationSite(
517     Isolate* isolate,
518     Handle<FixedArray> literals,
519     int literals_index,
520     Handle<FixedArray> elements) {
521   // Check if boilerplate exists. If not, create it first.
522   Handle<Object> literal_site(literals->get(literals_index), isolate);
523   Handle<AllocationSite> site;
524   if (*literal_site == isolate->heap()->undefined_value()) {
525     ASSERT(*elements != isolate->heap()->empty_fixed_array());
526     Handle<Object> boilerplate;
527     ASSIGN_RETURN_ON_EXCEPTION(
528         isolate, boilerplate,
529         Runtime::CreateArrayLiteralBoilerplate(isolate, literals, elements),
530         AllocationSite);
531
532     AllocationSiteCreationContext creation_context(isolate);
533     site = creation_context.EnterNewScope();
534     if (JSObject::DeepWalk(Handle<JSObject>::cast(boilerplate),
535                            &creation_context).is_null()) {
536       return Handle<AllocationSite>::null();
537     }
538     creation_context.ExitScope(site, Handle<JSObject>::cast(boilerplate));
539
540     literals->set(literals_index, *site);
541   } else {
542     site = Handle<AllocationSite>::cast(literal_site);
543   }
544
545   return site;
546 }
547
548
549 static MaybeHandle<JSObject> CreateArrayLiteralImpl(Isolate* isolate,
550                                            Handle<FixedArray> literals,
551                                            int literals_index,
552                                            Handle<FixedArray> elements,
553                                            int flags) {
554   RUNTIME_ASSERT_HANDLIFIED(literals_index >= 0 &&
555                             literals_index < literals->length(), JSObject);
556   Handle<AllocationSite> site;
557   ASSIGN_RETURN_ON_EXCEPTION(
558       isolate, site,
559       GetLiteralAllocationSite(isolate, literals, literals_index, elements),
560       JSObject);
561
562   bool enable_mementos = (flags & ArrayLiteral::kDisableMementos) == 0;
563   Handle<JSObject> boilerplate(JSObject::cast(site->transition_info()));
564   AllocationSiteUsageContext usage_context(isolate, site, enable_mementos);
565   usage_context.EnterNewScope();
566   JSObject::DeepCopyHints hints = (flags & ArrayLiteral::kShallowElements) == 0
567       ? JSObject::kNoHints
568       : JSObject::kObjectIsShallowArray;
569   MaybeHandle<JSObject> copy = JSObject::DeepCopy(boilerplate, &usage_context,
570                                                   hints);
571   usage_context.ExitScope(site, boilerplate);
572   return copy;
573 }
574
575
576 RUNTIME_FUNCTION(RuntimeHidden_CreateArrayLiteral) {
577   HandleScope scope(isolate);
578   ASSERT(args.length() == 4);
579   CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
580   CONVERT_SMI_ARG_CHECKED(literals_index, 1);
581   CONVERT_ARG_HANDLE_CHECKED(FixedArray, elements, 2);
582   CONVERT_SMI_ARG_CHECKED(flags, 3);
583
584   Handle<JSObject> result;
585   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
586       CreateArrayLiteralImpl(isolate, literals, literals_index, elements,
587                              flags));
588   return *result;
589 }
590
591
592 RUNTIME_FUNCTION(RuntimeHidden_CreateArrayLiteralStubBailout) {
593   HandleScope scope(isolate);
594   ASSERT(args.length() == 3);
595   CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
596   CONVERT_SMI_ARG_CHECKED(literals_index, 1);
597   CONVERT_ARG_HANDLE_CHECKED(FixedArray, elements, 2);
598
599   Handle<JSObject> result;
600   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
601      CreateArrayLiteralImpl(isolate, literals, literals_index, elements,
602                             ArrayLiteral::kShallowElements));
603   return *result;
604 }
605
606
607 RUNTIME_FUNCTION(Runtime_CreateSymbol) {
608   HandleScope scope(isolate);
609   ASSERT(args.length() == 1);
610   CONVERT_ARG_HANDLE_CHECKED(Object, name, 0);
611   RUNTIME_ASSERT(name->IsString() || name->IsUndefined());
612   Handle<Symbol> symbol = isolate->factory()->NewSymbol();
613   if (name->IsString()) symbol->set_name(*name);
614   return *symbol;
615 }
616
617
618 RUNTIME_FUNCTION(Runtime_CreatePrivateSymbol) {
619   HandleScope scope(isolate);
620   ASSERT(args.length() == 1);
621   CONVERT_ARG_HANDLE_CHECKED(Object, name, 0);
622   RUNTIME_ASSERT(name->IsString() || name->IsUndefined());
623   Handle<Symbol> symbol = isolate->factory()->NewPrivateSymbol();
624   if (name->IsString()) symbol->set_name(*name);
625   return *symbol;
626 }
627
628
629 RUNTIME_FUNCTION(Runtime_CreateGlobalPrivateSymbol) {
630   HandleScope scope(isolate);
631   ASSERT(args.length() == 1);
632   CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
633   Handle<JSObject> registry = isolate->GetSymbolRegistry();
634   Handle<String> part = isolate->factory()->private_intern_string();
635   Handle<Object> privates;
636   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
637       isolate, privates, Object::GetPropertyOrElement(registry, part));
638   Handle<Object> symbol;
639   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
640       isolate, symbol, Object::GetPropertyOrElement(privates, name));
641   if (!symbol->IsSymbol()) {
642     ASSERT(symbol->IsUndefined());
643     symbol = isolate->factory()->NewPrivateSymbol();
644     Handle<Symbol>::cast(symbol)->set_name(*name);
645     JSObject::SetProperty(Handle<JSObject>::cast(privates),
646                           name, symbol, NONE, STRICT).Assert();
647   }
648   return *symbol;
649 }
650
651
652 RUNTIME_FUNCTION(Runtime_NewSymbolWrapper) {
653   HandleScope scope(isolate);
654   ASSERT(args.length() == 1);
655   CONVERT_ARG_HANDLE_CHECKED(Symbol, symbol, 0);
656   return *Object::ToObject(isolate, symbol).ToHandleChecked();
657 }
658
659
660 RUNTIME_FUNCTION(Runtime_SymbolDescription) {
661   SealHandleScope shs(isolate);
662   ASSERT(args.length() == 1);
663   CONVERT_ARG_CHECKED(Symbol, symbol, 0);
664   return symbol->name();
665 }
666
667
668 RUNTIME_FUNCTION(Runtime_SymbolRegistry) {
669   HandleScope scope(isolate);
670   ASSERT(args.length() == 0);
671   return *isolate->GetSymbolRegistry();
672 }
673
674
675 RUNTIME_FUNCTION(Runtime_SymbolIsPrivate) {
676   SealHandleScope shs(isolate);
677   ASSERT(args.length() == 1);
678   CONVERT_ARG_CHECKED(Symbol, symbol, 0);
679   return isolate->heap()->ToBoolean(symbol->is_private());
680 }
681
682
683 RUNTIME_FUNCTION(Runtime_CreateJSProxy) {
684   HandleScope scope(isolate);
685   ASSERT(args.length() == 2);
686   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, handler, 0);
687   CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
688   if (!prototype->IsJSReceiver()) prototype = isolate->factory()->null_value();
689   return *isolate->factory()->NewJSProxy(handler, prototype);
690 }
691
692
693 RUNTIME_FUNCTION(Runtime_CreateJSFunctionProxy) {
694   HandleScope scope(isolate);
695   ASSERT(args.length() == 4);
696   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, handler, 0);
697   CONVERT_ARG_HANDLE_CHECKED(Object, call_trap, 1);
698   RUNTIME_ASSERT(call_trap->IsJSFunction() || call_trap->IsJSFunctionProxy());
699   CONVERT_ARG_HANDLE_CHECKED(JSFunction, construct_trap, 2);
700   CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 3);
701   if (!prototype->IsJSReceiver()) prototype = isolate->factory()->null_value();
702   return *isolate->factory()->NewJSFunctionProxy(
703       handler, call_trap, construct_trap, prototype);
704 }
705
706
707 RUNTIME_FUNCTION(Runtime_IsJSProxy) {
708   SealHandleScope shs(isolate);
709   ASSERT(args.length() == 1);
710   CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0);
711   return isolate->heap()->ToBoolean(obj->IsJSProxy());
712 }
713
714
715 RUNTIME_FUNCTION(Runtime_IsJSFunctionProxy) {
716   SealHandleScope shs(isolate);
717   ASSERT(args.length() == 1);
718   CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0);
719   return isolate->heap()->ToBoolean(obj->IsJSFunctionProxy());
720 }
721
722
723 RUNTIME_FUNCTION(Runtime_GetHandler) {
724   SealHandleScope shs(isolate);
725   ASSERT(args.length() == 1);
726   CONVERT_ARG_CHECKED(JSProxy, proxy, 0);
727   return proxy->handler();
728 }
729
730
731 RUNTIME_FUNCTION(Runtime_GetCallTrap) {
732   SealHandleScope shs(isolate);
733   ASSERT(args.length() == 1);
734   CONVERT_ARG_CHECKED(JSFunctionProxy, proxy, 0);
735   return proxy->call_trap();
736 }
737
738
739 RUNTIME_FUNCTION(Runtime_GetConstructTrap) {
740   SealHandleScope shs(isolate);
741   ASSERT(args.length() == 1);
742   CONVERT_ARG_CHECKED(JSFunctionProxy, proxy, 0);
743   return proxy->construct_trap();
744 }
745
746
747 RUNTIME_FUNCTION(Runtime_Fix) {
748   HandleScope scope(isolate);
749   ASSERT(args.length() == 1);
750   CONVERT_ARG_HANDLE_CHECKED(JSProxy, proxy, 0);
751   JSProxy::Fix(proxy);
752   return isolate->heap()->undefined_value();
753 }
754
755
756 void Runtime::FreeArrayBuffer(Isolate* isolate,
757                               JSArrayBuffer* phantom_array_buffer) {
758   if (phantom_array_buffer->should_be_freed()) {
759     ASSERT(phantom_array_buffer->is_external());
760     free(phantom_array_buffer->backing_store());
761   }
762   if (phantom_array_buffer->is_external()) return;
763
764   size_t allocated_length = NumberToSize(
765       isolate, phantom_array_buffer->byte_length());
766
767   isolate->heap()->AdjustAmountOfExternalAllocatedMemory(
768       -static_cast<int64_t>(allocated_length));
769   CHECK(V8::ArrayBufferAllocator() != NULL);
770   V8::ArrayBufferAllocator()->Free(
771       phantom_array_buffer->backing_store(),
772       allocated_length);
773 }
774
775
776 void Runtime::SetupArrayBuffer(Isolate* isolate,
777                                Handle<JSArrayBuffer> array_buffer,
778                                bool is_external,
779                                void* data,
780                                size_t allocated_length) {
781   ASSERT(array_buffer->GetInternalFieldCount() ==
782       v8::ArrayBuffer::kInternalFieldCount);
783   for (int i = 0; i < v8::ArrayBuffer::kInternalFieldCount; i++) {
784     array_buffer->SetInternalField(i, Smi::FromInt(0));
785   }
786   array_buffer->set_backing_store(data);
787   array_buffer->set_flag(Smi::FromInt(0));
788   array_buffer->set_is_external(is_external);
789
790   Handle<Object> byte_length =
791       isolate->factory()->NewNumberFromSize(allocated_length);
792   CHECK(byte_length->IsSmi() || byte_length->IsHeapNumber());
793   array_buffer->set_byte_length(*byte_length);
794
795   array_buffer->set_weak_next(isolate->heap()->array_buffers_list());
796   isolate->heap()->set_array_buffers_list(*array_buffer);
797   array_buffer->set_weak_first_view(isolate->heap()->undefined_value());
798 }
799
800
801 bool Runtime::SetupArrayBufferAllocatingData(
802     Isolate* isolate,
803     Handle<JSArrayBuffer> array_buffer,
804     size_t allocated_length,
805     bool initialize) {
806   void* data;
807   CHECK(V8::ArrayBufferAllocator() != NULL);
808   if (allocated_length != 0) {
809     if (initialize) {
810       data = V8::ArrayBufferAllocator()->Allocate(allocated_length);
811     } else {
812       data =
813           V8::ArrayBufferAllocator()->AllocateUninitialized(allocated_length);
814     }
815     if (data == NULL) return false;
816   } else {
817     data = NULL;
818   }
819
820   SetupArrayBuffer(isolate, array_buffer, false, data, allocated_length);
821
822   isolate->heap()->AdjustAmountOfExternalAllocatedMemory(allocated_length);
823
824   return true;
825 }
826
827
828 void Runtime::NeuterArrayBuffer(Handle<JSArrayBuffer> array_buffer) {
829   Isolate* isolate = array_buffer->GetIsolate();
830   for (Handle<Object> view_obj(array_buffer->weak_first_view(), isolate);
831        !view_obj->IsUndefined();) {
832     Handle<JSArrayBufferView> view(JSArrayBufferView::cast(*view_obj));
833     if (view->IsJSTypedArray()) {
834       JSTypedArray::cast(*view)->Neuter();
835     } else if (view->IsJSDataView()) {
836       JSDataView::cast(*view)->Neuter();
837     } else {
838       UNREACHABLE();
839     }
840     view_obj = handle(view->weak_next(), isolate);
841   }
842   array_buffer->Neuter();
843 }
844
845
846 RUNTIME_FUNCTION(Runtime_ArrayBufferInitialize) {
847   HandleScope scope(isolate);
848   ASSERT(args.length() == 2);
849   CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, holder, 0);
850   CONVERT_NUMBER_ARG_HANDLE_CHECKED(byteLength, 1);
851   if (!holder->byte_length()->IsUndefined()) {
852     // ArrayBuffer is already initialized; probably a fuzz test.
853     return *holder;
854   }
855   size_t allocated_length = 0;
856   if (!TryNumberToSize(isolate, *byteLength, &allocated_length)) {
857     return isolate->Throw(
858         *isolate->factory()->NewRangeError("invalid_array_buffer_length",
859                                            HandleVector<Object>(NULL, 0)));
860   }
861   if (!Runtime::SetupArrayBufferAllocatingData(isolate,
862                                                holder, allocated_length)) {
863     return isolate->Throw(
864         *isolate->factory()->NewRangeError("invalid_array_buffer_length",
865                                            HandleVector<Object>(NULL, 0)));
866   }
867   return *holder;
868 }
869
870
871 RUNTIME_FUNCTION(Runtime_ArrayBufferGetByteLength) {
872   SealHandleScope shs(isolate);
873   ASSERT(args.length() == 1);
874   CONVERT_ARG_CHECKED(JSArrayBuffer, holder, 0);
875   return holder->byte_length();
876 }
877
878
879 RUNTIME_FUNCTION(Runtime_ArrayBufferSliceImpl) {
880   HandleScope scope(isolate);
881   ASSERT(args.length() == 3);
882   CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, source, 0);
883   CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, target, 1);
884   CONVERT_NUMBER_ARG_HANDLE_CHECKED(first, 2);
885   size_t start = 0;
886   RUNTIME_ASSERT(TryNumberToSize(isolate, *first, &start));
887   size_t target_length = NumberToSize(isolate, target->byte_length());
888
889   if (target_length == 0) return isolate->heap()->undefined_value();
890
891   size_t source_byte_length = NumberToSize(isolate, source->byte_length());
892   RUNTIME_ASSERT(start <= source_byte_length);
893   RUNTIME_ASSERT(source_byte_length - start >= target_length);
894   uint8_t* source_data = reinterpret_cast<uint8_t*>(source->backing_store());
895   uint8_t* target_data = reinterpret_cast<uint8_t*>(target->backing_store());
896   CopyBytes(target_data, source_data + start, target_length);
897   return isolate->heap()->undefined_value();
898 }
899
900
901 RUNTIME_FUNCTION(Runtime_ArrayBufferIsView) {
902   HandleScope scope(isolate);
903   ASSERT(args.length() == 1);
904   CONVERT_ARG_CHECKED(Object, object, 0);
905   return isolate->heap()->ToBoolean(object->IsJSArrayBufferView());
906 }
907
908
909 RUNTIME_FUNCTION(Runtime_ArrayBufferNeuter) {
910   HandleScope scope(isolate);
911   ASSERT(args.length() == 1);
912   CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, array_buffer, 0);
913   if (array_buffer->backing_store() == NULL) {
914     CHECK(Smi::FromInt(0) == array_buffer->byte_length());
915     return isolate->heap()->undefined_value();
916   }
917   ASSERT(!array_buffer->is_external());
918   void* backing_store = array_buffer->backing_store();
919   size_t byte_length = NumberToSize(isolate, array_buffer->byte_length());
920   array_buffer->set_is_external(true);
921   Runtime::NeuterArrayBuffer(array_buffer);
922   V8::ArrayBufferAllocator()->Free(backing_store, byte_length);
923   return isolate->heap()->undefined_value();
924 }
925
926
927 void Runtime::ArrayIdToTypeAndSize(
928     int arrayId,
929     ExternalArrayType* array_type,
930     ElementsKind* external_elements_kind,
931     ElementsKind* fixed_elements_kind,
932     size_t* element_size) {
933   switch (arrayId) {
934 #define ARRAY_ID_CASE(Type, type, TYPE, ctype, size)                           \
935     case ARRAY_ID_##TYPE:                                                      \
936       *array_type = kExternal##Type##Array;                                    \
937       *external_elements_kind = EXTERNAL_##TYPE##_ELEMENTS;                    \
938       *fixed_elements_kind = TYPE##_ELEMENTS;                                  \
939       *element_size = size;                                                    \
940       break;
941
942     TYPED_ARRAYS(ARRAY_ID_CASE)
943 #undef ARRAY_ID_CASE
944
945     default:
946       UNREACHABLE();
947   }
948 }
949
950
951 RUNTIME_FUNCTION(Runtime_TypedArrayInitialize) {
952   HandleScope scope(isolate);
953   ASSERT(args.length() == 5);
954   CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0);
955   CONVERT_SMI_ARG_CHECKED(arrayId, 1);
956   CONVERT_ARG_HANDLE_CHECKED(Object, maybe_buffer, 2);
957   CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_offset_object, 3);
958   CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_length_object, 4);
959
960   RUNTIME_ASSERT(arrayId >= Runtime::ARRAY_ID_FIRST &&
961                  arrayId <= Runtime::ARRAY_ID_LAST);
962   RUNTIME_ASSERT(maybe_buffer->IsNull() || maybe_buffer->IsJSArrayBuffer());
963
964   ASSERT(holder->GetInternalFieldCount() ==
965       v8::ArrayBufferView::kInternalFieldCount);
966   for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) {
967     holder->SetInternalField(i, Smi::FromInt(0));
968   }
969
970   ExternalArrayType array_type = kExternalInt8Array;  // Bogus initialization.
971   size_t element_size = 1;  // Bogus initialization.
972   ElementsKind external_elements_kind =
973       EXTERNAL_INT8_ELEMENTS;  // Bogus initialization.
974   ElementsKind fixed_elements_kind = INT8_ELEMENTS;  // Bogus initialization.
975   Runtime::ArrayIdToTypeAndSize(arrayId,
976       &array_type,
977       &external_elements_kind,
978       &fixed_elements_kind,
979       &element_size);
980
981   size_t byte_offset = 0;
982   size_t byte_length = 0;
983   RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_offset_object, &byte_offset));
984   RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_length_object, &byte_length));
985
986   holder->set_byte_offset(*byte_offset_object);
987   holder->set_byte_length(*byte_length_object);
988
989   CHECK_EQ(0, static_cast<int>(byte_length % element_size));
990   size_t length = byte_length / element_size;
991
992   if (length > static_cast<unsigned>(Smi::kMaxValue)) {
993     return isolate->Throw(
994         *isolate->factory()->NewRangeError("invalid_typed_array_length",
995                                            HandleVector<Object>(NULL, 0)));
996   }
997
998   Handle<Object> length_obj = isolate->factory()->NewNumberFromSize(length);
999   holder->set_length(*length_obj);
1000   if (!maybe_buffer->IsNull()) {
1001     Handle<JSArrayBuffer> buffer(JSArrayBuffer::cast(*maybe_buffer));
1002
1003     size_t array_buffer_byte_length =
1004         NumberToSize(isolate, buffer->byte_length());
1005     RUNTIME_ASSERT(byte_offset <= array_buffer_byte_length);
1006     RUNTIME_ASSERT(array_buffer_byte_length - byte_offset >= byte_length);
1007
1008     holder->set_buffer(*buffer);
1009     holder->set_weak_next(buffer->weak_first_view());
1010     buffer->set_weak_first_view(*holder);
1011
1012     Handle<ExternalArray> elements =
1013         isolate->factory()->NewExternalArray(
1014             static_cast<int>(length), array_type,
1015             static_cast<uint8_t*>(buffer->backing_store()) + byte_offset);
1016     Handle<Map> map =
1017         JSObject::GetElementsTransitionMap(holder, external_elements_kind);
1018     JSObject::SetMapAndElements(holder, map, elements);
1019     ASSERT(IsExternalArrayElementsKind(holder->map()->elements_kind()));
1020   } else {
1021     holder->set_buffer(Smi::FromInt(0));
1022     holder->set_weak_next(isolate->heap()->undefined_value());
1023     Handle<FixedTypedArrayBase> elements =
1024         isolate->factory()->NewFixedTypedArray(
1025             static_cast<int>(length), array_type);
1026     holder->set_elements(*elements);
1027   }
1028   return isolate->heap()->undefined_value();
1029 }
1030
1031
1032 // Initializes a typed array from an array-like object.
1033 // If an array-like object happens to be a typed array of the same type,
1034 // initializes backing store using memove.
1035 //
1036 // Returns true if backing store was initialized or false otherwise.
1037 RUNTIME_FUNCTION(Runtime_TypedArrayInitializeFromArrayLike) {
1038   HandleScope scope(isolate);
1039   ASSERT(args.length() == 4);
1040   CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0);
1041   CONVERT_SMI_ARG_CHECKED(arrayId, 1);
1042   CONVERT_ARG_HANDLE_CHECKED(Object, source, 2);
1043   CONVERT_NUMBER_ARG_HANDLE_CHECKED(length_obj, 3);
1044
1045   RUNTIME_ASSERT(arrayId >= Runtime::ARRAY_ID_FIRST &&
1046                  arrayId <= Runtime::ARRAY_ID_LAST);
1047
1048   ASSERT(holder->GetInternalFieldCount() ==
1049       v8::ArrayBufferView::kInternalFieldCount);
1050   for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) {
1051     holder->SetInternalField(i, Smi::FromInt(0));
1052   }
1053
1054   ExternalArrayType array_type = kExternalInt8Array;  // Bogus initialization.
1055   size_t element_size = 1;  // Bogus initialization.
1056   ElementsKind external_elements_kind =
1057       EXTERNAL_INT8_ELEMENTS;  // Bogus intialization.
1058   ElementsKind fixed_elements_kind = INT8_ELEMENTS;  // Bogus initialization.
1059   Runtime::ArrayIdToTypeAndSize(arrayId,
1060       &array_type,
1061       &external_elements_kind,
1062       &fixed_elements_kind,
1063       &element_size);
1064
1065   Handle<JSArrayBuffer> buffer = isolate->factory()->NewJSArrayBuffer();
1066   if (source->IsJSTypedArray() &&
1067       JSTypedArray::cast(*source)->type() == array_type) {
1068     length_obj = Handle<Object>(JSTypedArray::cast(*source)->length(), isolate);
1069   }
1070   size_t length = 0;
1071   RUNTIME_ASSERT(TryNumberToSize(isolate, *length_obj, &length));
1072
1073   if ((length > static_cast<unsigned>(Smi::kMaxValue)) ||
1074       (length > (kMaxInt / element_size))) {
1075     return isolate->Throw(*isolate->factory()->
1076           NewRangeError("invalid_typed_array_length",
1077             HandleVector<Object>(NULL, 0)));
1078   }
1079   size_t byte_length = length * element_size;
1080
1081   // NOTE: not initializing backing store.
1082   // We assume that the caller of this function will initialize holder
1083   // with the loop
1084   //      for(i = 0; i < length; i++) { holder[i] = source[i]; }
1085   // We assume that the caller of this function is always a typed array
1086   // constructor.
1087   // If source is a typed array, this loop will always run to completion,
1088   // so we are sure that the backing store will be initialized.
1089   // Otherwise, the indexing operation might throw, so the loop will not
1090   // run to completion and the typed array might remain partly initialized.
1091   // However we further assume that the caller of this function is a typed array
1092   // constructor, and the exception will propagate out of the constructor,
1093   // therefore uninitialized memory will not be accessible by a user program.
1094   //
1095   // TODO(dslomov): revise this once we support subclassing.
1096
1097   if (!Runtime::SetupArrayBufferAllocatingData(
1098         isolate, buffer, byte_length, false)) {
1099     return isolate->Throw(*isolate->factory()->
1100           NewRangeError("invalid_array_buffer_length",
1101             HandleVector<Object>(NULL, 0)));
1102   }
1103
1104   holder->set_buffer(*buffer);
1105   holder->set_byte_offset(Smi::FromInt(0));
1106   Handle<Object> byte_length_obj(
1107       isolate->factory()->NewNumberFromSize(byte_length));
1108   holder->set_byte_length(*byte_length_obj);
1109   holder->set_length(*length_obj);
1110   holder->set_weak_next(buffer->weak_first_view());
1111   buffer->set_weak_first_view(*holder);
1112
1113   Handle<ExternalArray> elements =
1114       isolate->factory()->NewExternalArray(
1115           static_cast<int>(length), array_type,
1116           static_cast<uint8_t*>(buffer->backing_store()));
1117   Handle<Map> map = JSObject::GetElementsTransitionMap(
1118       holder, external_elements_kind);
1119   JSObject::SetMapAndElements(holder, map, elements);
1120
1121   if (source->IsJSTypedArray()) {
1122     Handle<JSTypedArray> typed_array(JSTypedArray::cast(*source));
1123
1124     if (typed_array->type() == holder->type()) {
1125       uint8_t* backing_store =
1126         static_cast<uint8_t*>(
1127           typed_array->GetBuffer()->backing_store());
1128       size_t source_byte_offset =
1129           NumberToSize(isolate, typed_array->byte_offset());
1130       memcpy(
1131           buffer->backing_store(),
1132           backing_store + source_byte_offset,
1133           byte_length);
1134       return isolate->heap()->true_value();
1135     }
1136   }
1137
1138   return isolate->heap()->false_value();
1139 }
1140
1141
1142 #define BUFFER_VIEW_GETTER(Type, getter, accessor) \
1143   RUNTIME_FUNCTION(Runtime_##Type##Get##getter) {                    \
1144     HandleScope scope(isolate);                                               \
1145     ASSERT(args.length() == 1);                                               \
1146     CONVERT_ARG_HANDLE_CHECKED(JS##Type, holder, 0);                          \
1147     return holder->accessor();                                                \
1148   }
1149
1150 BUFFER_VIEW_GETTER(ArrayBufferView, ByteLength, byte_length)
1151 BUFFER_VIEW_GETTER(ArrayBufferView, ByteOffset, byte_offset)
1152 BUFFER_VIEW_GETTER(TypedArray, Length, length)
1153 BUFFER_VIEW_GETTER(DataView, Buffer, buffer)
1154
1155 #undef BUFFER_VIEW_GETTER
1156
1157 RUNTIME_FUNCTION(Runtime_TypedArrayGetBuffer) {
1158   HandleScope scope(isolate);
1159   ASSERT(args.length() == 1);
1160   CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0);
1161   return *holder->GetBuffer();
1162 }
1163
1164
1165 // Return codes for Runtime_TypedArraySetFastCases.
1166 // Should be synchronized with typedarray.js natives.
1167 enum TypedArraySetResultCodes {
1168   // Set from typed array of the same type.
1169   // This is processed by TypedArraySetFastCases
1170   TYPED_ARRAY_SET_TYPED_ARRAY_SAME_TYPE = 0,
1171   // Set from typed array of the different type, overlapping in memory.
1172   TYPED_ARRAY_SET_TYPED_ARRAY_OVERLAPPING = 1,
1173   // Set from typed array of the different type, non-overlapping.
1174   TYPED_ARRAY_SET_TYPED_ARRAY_NONOVERLAPPING = 2,
1175   // Set from non-typed array.
1176   TYPED_ARRAY_SET_NON_TYPED_ARRAY = 3
1177 };
1178
1179
1180 RUNTIME_FUNCTION(Runtime_TypedArraySetFastCases) {
1181   HandleScope scope(isolate);
1182   ASSERT(args.length() == 3);
1183   if (!args[0]->IsJSTypedArray())
1184     return isolate->Throw(*isolate->factory()->NewTypeError(
1185         "not_typed_array", HandleVector<Object>(NULL, 0)));
1186
1187   if (!args[1]->IsJSTypedArray())
1188     return Smi::FromInt(TYPED_ARRAY_SET_NON_TYPED_ARRAY);
1189
1190   CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, target_obj, 0);
1191   CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, source_obj, 1);
1192   CONVERT_NUMBER_ARG_HANDLE_CHECKED(offset_obj, 2);
1193
1194   Handle<JSTypedArray> target(JSTypedArray::cast(*target_obj));
1195   Handle<JSTypedArray> source(JSTypedArray::cast(*source_obj));
1196   size_t offset = 0;
1197   RUNTIME_ASSERT(TryNumberToSize(isolate, *offset_obj, &offset));
1198   size_t target_length = NumberToSize(isolate, target->length());
1199   size_t source_length = NumberToSize(isolate, source->length());
1200   size_t target_byte_length = NumberToSize(isolate, target->byte_length());
1201   size_t source_byte_length = NumberToSize(isolate, source->byte_length());
1202   if (offset > target_length ||
1203       offset + source_length > target_length ||
1204       offset + source_length < offset)  // overflow
1205     return isolate->Throw(*isolate->factory()->NewRangeError(
1206           "typed_array_set_source_too_large", HandleVector<Object>(NULL, 0)));
1207
1208   size_t target_offset = NumberToSize(isolate, target->byte_offset());
1209   size_t source_offset = NumberToSize(isolate, source->byte_offset());
1210   uint8_t* target_base =
1211       static_cast<uint8_t*>(
1212         target->GetBuffer()->backing_store()) + target_offset;
1213   uint8_t* source_base =
1214       static_cast<uint8_t*>(
1215         source->GetBuffer()->backing_store()) + source_offset;
1216
1217   // Typed arrays of the same type: use memmove.
1218   if (target->type() == source->type()) {
1219     memmove(target_base + offset * target->element_size(),
1220         source_base, source_byte_length);
1221     return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_SAME_TYPE);
1222   }
1223
1224   // Typed arrays of different types over the same backing store
1225   if ((source_base <= target_base &&
1226         source_base + source_byte_length > target_base) ||
1227       (target_base <= source_base &&
1228         target_base + target_byte_length > source_base)) {
1229     // We do not support overlapping ArrayBuffers
1230     ASSERT(
1231       target->GetBuffer()->backing_store() ==
1232       source->GetBuffer()->backing_store());
1233     return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_OVERLAPPING);
1234   } else {  // Non-overlapping typed arrays
1235     return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_NONOVERLAPPING);
1236   }
1237 }
1238
1239
1240 RUNTIME_FUNCTION(Runtime_TypedArrayMaxSizeInHeap) {
1241   ASSERT(args.length() == 0);
1242   ASSERT_OBJECT_SIZE(
1243       FLAG_typed_array_max_size_in_heap + FixedTypedArrayBase::kDataOffset);
1244   return Smi::FromInt(FLAG_typed_array_max_size_in_heap);
1245 }
1246
1247
1248 RUNTIME_FUNCTION(Runtime_DataViewInitialize) {
1249   HandleScope scope(isolate);
1250   ASSERT(args.length() == 4);
1251   CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0);
1252   CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, buffer, 1);
1253   CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_offset, 2);
1254   CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_length, 3);
1255
1256   ASSERT(holder->GetInternalFieldCount() ==
1257       v8::ArrayBufferView::kInternalFieldCount);
1258   for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) {
1259     holder->SetInternalField(i, Smi::FromInt(0));
1260   }
1261   size_t buffer_length = 0;
1262   size_t offset = 0;
1263   size_t length = 0;
1264   RUNTIME_ASSERT(
1265       TryNumberToSize(isolate, buffer->byte_length(), &buffer_length));
1266   RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_offset, &offset));
1267   RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_length, &length));
1268
1269   // TODO(jkummerow): When we have a "safe numerics" helper class, use it here.
1270   // Entire range [offset, offset + length] must be in bounds.
1271   RUNTIME_ASSERT(offset <= buffer_length);
1272   RUNTIME_ASSERT(offset + length <= buffer_length);
1273   // No overflow.
1274   RUNTIME_ASSERT(offset + length >= offset);
1275
1276   holder->set_buffer(*buffer);
1277   holder->set_byte_offset(*byte_offset);
1278   holder->set_byte_length(*byte_length);
1279
1280   holder->set_weak_next(buffer->weak_first_view());
1281   buffer->set_weak_first_view(*holder);
1282
1283   return isolate->heap()->undefined_value();
1284 }
1285
1286
1287 inline static bool NeedToFlipBytes(bool is_little_endian) {
1288 #ifdef V8_TARGET_LITTLE_ENDIAN
1289   return !is_little_endian;
1290 #else
1291   return is_little_endian;
1292 #endif
1293 }
1294
1295
1296 template<int n>
1297 inline void CopyBytes(uint8_t* target, uint8_t* source) {
1298   for (int i = 0; i < n; i++) {
1299     *(target++) = *(source++);
1300   }
1301 }
1302
1303
1304 template<int n>
1305 inline void FlipBytes(uint8_t* target, uint8_t* source) {
1306   source = source + (n-1);
1307   for (int i = 0; i < n; i++) {
1308     *(target++) = *(source--);
1309   }
1310 }
1311
1312
1313 template<typename T>
1314 inline static bool DataViewGetValue(
1315     Isolate* isolate,
1316     Handle<JSDataView> data_view,
1317     Handle<Object> byte_offset_obj,
1318     bool is_little_endian,
1319     T* result) {
1320   size_t byte_offset = 0;
1321   if (!TryNumberToSize(isolate, *byte_offset_obj, &byte_offset)) {
1322     return false;
1323   }
1324   Handle<JSArrayBuffer> buffer(JSArrayBuffer::cast(data_view->buffer()));
1325
1326   size_t data_view_byte_offset =
1327       NumberToSize(isolate, data_view->byte_offset());
1328   size_t data_view_byte_length =
1329       NumberToSize(isolate, data_view->byte_length());
1330   if (byte_offset + sizeof(T) > data_view_byte_length ||
1331       byte_offset + sizeof(T) < byte_offset)  {  // overflow
1332     return false;
1333   }
1334
1335   union Value {
1336     T data;
1337     uint8_t bytes[sizeof(T)];
1338   };
1339
1340   Value value;
1341   size_t buffer_offset = data_view_byte_offset + byte_offset;
1342   ASSERT(
1343       NumberToSize(isolate, buffer->byte_length())
1344       >= buffer_offset + sizeof(T));
1345   uint8_t* source =
1346         static_cast<uint8_t*>(buffer->backing_store()) + buffer_offset;
1347   if (NeedToFlipBytes(is_little_endian)) {
1348     FlipBytes<sizeof(T)>(value.bytes, source);
1349   } else {
1350     CopyBytes<sizeof(T)>(value.bytes, source);
1351   }
1352   *result = value.data;
1353   return true;
1354 }
1355
1356
1357 template<typename T>
1358 static bool DataViewSetValue(
1359     Isolate* isolate,
1360     Handle<JSDataView> data_view,
1361     Handle<Object> byte_offset_obj,
1362     bool is_little_endian,
1363     T data) {
1364   size_t byte_offset = 0;
1365   if (!TryNumberToSize(isolate, *byte_offset_obj, &byte_offset)) {
1366     return false;
1367   }
1368   Handle<JSArrayBuffer> buffer(JSArrayBuffer::cast(data_view->buffer()));
1369
1370   size_t data_view_byte_offset =
1371       NumberToSize(isolate, data_view->byte_offset());
1372   size_t data_view_byte_length =
1373       NumberToSize(isolate, data_view->byte_length());
1374   if (byte_offset + sizeof(T) > data_view_byte_length ||
1375       byte_offset + sizeof(T) < byte_offset)  {  // overflow
1376     return false;
1377   }
1378
1379   union Value {
1380     T data;
1381     uint8_t bytes[sizeof(T)];
1382   };
1383
1384   Value value;
1385   value.data = data;
1386   size_t buffer_offset = data_view_byte_offset + byte_offset;
1387   ASSERT(
1388       NumberToSize(isolate, buffer->byte_length())
1389       >= buffer_offset + sizeof(T));
1390   uint8_t* target =
1391         static_cast<uint8_t*>(buffer->backing_store()) + buffer_offset;
1392   if (NeedToFlipBytes(is_little_endian)) {
1393     FlipBytes<sizeof(T)>(target, value.bytes);
1394   } else {
1395     CopyBytes<sizeof(T)>(target, value.bytes);
1396   }
1397   return true;
1398 }
1399
1400
1401 #define DATA_VIEW_GETTER(TypeName, Type, Converter)                           \
1402   RUNTIME_FUNCTION(Runtime_DataViewGet##TypeName) {                  \
1403     HandleScope scope(isolate);                                               \
1404     ASSERT(args.length() == 3);                                               \
1405     CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0);                        \
1406     CONVERT_ARG_HANDLE_CHECKED(Object, offset, 1);                            \
1407     CONVERT_BOOLEAN_ARG_CHECKED(is_little_endian, 2);                         \
1408     Type result;                                                              \
1409     if (DataViewGetValue(                                                     \
1410           isolate, holder, offset, is_little_endian, &result)) {              \
1411       return *isolate->factory()->Converter(result);                          \
1412     } else {                                                                  \
1413       return isolate->Throw(*isolate->factory()->NewRangeError(               \
1414           "invalid_data_view_accessor_offset",                                \
1415           HandleVector<Object>(NULL, 0)));                                    \
1416     }                                                                         \
1417   }
1418
1419 DATA_VIEW_GETTER(Uint8, uint8_t, NewNumberFromUint)
1420 DATA_VIEW_GETTER(Int8, int8_t, NewNumberFromInt)
1421 DATA_VIEW_GETTER(Uint16, uint16_t, NewNumberFromUint)
1422 DATA_VIEW_GETTER(Int16, int16_t, NewNumberFromInt)
1423 DATA_VIEW_GETTER(Uint32, uint32_t, NewNumberFromUint)
1424 DATA_VIEW_GETTER(Int32, int32_t, NewNumberFromInt)
1425 DATA_VIEW_GETTER(Float32, float, NewNumber)
1426 DATA_VIEW_GETTER(Float64, double, NewNumber)
1427
1428 #undef DATA_VIEW_GETTER
1429
1430
1431 template <typename T>
1432 static T DataViewConvertValue(double value);
1433
1434
1435 template <>
1436 int8_t DataViewConvertValue<int8_t>(double value) {
1437   return static_cast<int8_t>(DoubleToInt32(value));
1438 }
1439
1440
1441 template <>
1442 int16_t DataViewConvertValue<int16_t>(double value) {
1443   return static_cast<int16_t>(DoubleToInt32(value));
1444 }
1445
1446
1447 template <>
1448 int32_t DataViewConvertValue<int32_t>(double value) {
1449   return DoubleToInt32(value);
1450 }
1451
1452
1453 template <>
1454 uint8_t DataViewConvertValue<uint8_t>(double value) {
1455   return static_cast<uint8_t>(DoubleToUint32(value));
1456 }
1457
1458
1459 template <>
1460 uint16_t DataViewConvertValue<uint16_t>(double value) {
1461   return static_cast<uint16_t>(DoubleToUint32(value));
1462 }
1463
1464
1465 template <>
1466 uint32_t DataViewConvertValue<uint32_t>(double value) {
1467   return DoubleToUint32(value);
1468 }
1469
1470
1471 template <>
1472 float DataViewConvertValue<float>(double value) {
1473   return static_cast<float>(value);
1474 }
1475
1476
1477 template <>
1478 double DataViewConvertValue<double>(double value) {
1479   return value;
1480 }
1481
1482
1483 #define DATA_VIEW_SETTER(TypeName, Type)                                      \
1484   RUNTIME_FUNCTION(Runtime_DataViewSet##TypeName) {                  \
1485     HandleScope scope(isolate);                                               \
1486     ASSERT(args.length() == 4);                                               \
1487     CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0);                        \
1488     CONVERT_ARG_HANDLE_CHECKED(Object, offset, 1);                            \
1489     CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);                             \
1490     CONVERT_BOOLEAN_ARG_CHECKED(is_little_endian, 3);                         \
1491     Type v = DataViewConvertValue<Type>(value->Number());                     \
1492     if (DataViewSetValue(                                                     \
1493           isolate, holder, offset, is_little_endian, v)) {                    \
1494       return isolate->heap()->undefined_value();                              \
1495     } else {                                                                  \
1496       return isolate->Throw(*isolate->factory()->NewRangeError(               \
1497           "invalid_data_view_accessor_offset",                                \
1498           HandleVector<Object>(NULL, 0)));                                    \
1499     }                                                                         \
1500   }
1501
1502 DATA_VIEW_SETTER(Uint8, uint8_t)
1503 DATA_VIEW_SETTER(Int8, int8_t)
1504 DATA_VIEW_SETTER(Uint16, uint16_t)
1505 DATA_VIEW_SETTER(Int16, int16_t)
1506 DATA_VIEW_SETTER(Uint32, uint32_t)
1507 DATA_VIEW_SETTER(Int32, int32_t)
1508 DATA_VIEW_SETTER(Float32, float)
1509 DATA_VIEW_SETTER(Float64, double)
1510
1511 #undef DATA_VIEW_SETTER
1512
1513
1514 RUNTIME_FUNCTION(Runtime_SetInitialize) {
1515   HandleScope scope(isolate);
1516   ASSERT(args.length() == 1);
1517   CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
1518   Handle<OrderedHashSet> table = isolate->factory()->NewOrderedHashSet();
1519   holder->set_table(*table);
1520   return *holder;
1521 }
1522
1523
1524 RUNTIME_FUNCTION(Runtime_SetAdd) {
1525   HandleScope scope(isolate);
1526   ASSERT(args.length() == 2);
1527   CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
1528   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
1529   Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
1530   table = OrderedHashSet::Add(table, key);
1531   holder->set_table(*table);
1532   return isolate->heap()->undefined_value();
1533 }
1534
1535
1536 RUNTIME_FUNCTION(Runtime_SetHas) {
1537   HandleScope scope(isolate);
1538   ASSERT(args.length() == 2);
1539   CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
1540   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
1541   Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
1542   return isolate->heap()->ToBoolean(table->Contains(key));
1543 }
1544
1545
1546 RUNTIME_FUNCTION(Runtime_SetDelete) {
1547   HandleScope scope(isolate);
1548   ASSERT(args.length() == 2);
1549   CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
1550   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
1551   Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
1552   table = OrderedHashSet::Remove(table, key);
1553   holder->set_table(*table);
1554   return isolate->heap()->undefined_value();
1555 }
1556
1557
1558 RUNTIME_FUNCTION(Runtime_SetClear) {
1559   HandleScope scope(isolate);
1560   ASSERT(args.length() == 1);
1561   CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
1562   Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
1563   table = OrderedHashSet::Clear(table);
1564   holder->set_table(*table);
1565   return isolate->heap()->undefined_value();
1566 }
1567
1568
1569 RUNTIME_FUNCTION(Runtime_SetGetSize) {
1570   HandleScope scope(isolate);
1571   ASSERT(args.length() == 1);
1572   CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
1573   Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
1574   return Smi::FromInt(table->NumberOfElements());
1575 }
1576
1577
1578 RUNTIME_FUNCTION(Runtime_SetCreateIterator) {
1579   HandleScope scope(isolate);
1580   ASSERT(args.length() == 2);
1581   CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
1582   CONVERT_SMI_ARG_CHECKED(kind, 1)
1583   RUNTIME_ASSERT(kind == JSSetIterator::kKindValues ||
1584                  kind == JSSetIterator::kKindEntries);
1585   Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
1586   return *JSSetIterator::Create(table, kind);
1587 }
1588
1589
1590 RUNTIME_FUNCTION(Runtime_SetIteratorNext) {
1591   HandleScope scope(isolate);
1592   ASSERT(args.length() == 1);
1593   CONVERT_ARG_HANDLE_CHECKED(JSSetIterator, holder, 0);
1594   return *JSSetIterator::Next(holder);
1595 }
1596
1597
1598 RUNTIME_FUNCTION(Runtime_SetIteratorClose) {
1599   HandleScope scope(isolate);
1600   ASSERT(args.length() == 1);
1601   CONVERT_ARG_HANDLE_CHECKED(JSSetIterator, holder, 0);
1602   holder->Close();
1603   return isolate->heap()->undefined_value();
1604 }
1605
1606
1607 RUNTIME_FUNCTION(Runtime_MapInitialize) {
1608   HandleScope scope(isolate);
1609   ASSERT(args.length() == 1);
1610   CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
1611   Handle<OrderedHashMap> table = isolate->factory()->NewOrderedHashMap();
1612   holder->set_table(*table);
1613   return *holder;
1614 }
1615
1616
1617 RUNTIME_FUNCTION(Runtime_MapGet) {
1618   HandleScope scope(isolate);
1619   ASSERT(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 lookup->IsTheHole() ? isolate->heap()->undefined_value() : *lookup;
1625 }
1626
1627
1628 RUNTIME_FUNCTION(Runtime_MapHas) {
1629   HandleScope scope(isolate);
1630   ASSERT(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   Handle<Object> lookup(table->Lookup(key), isolate);
1635   return isolate->heap()->ToBoolean(!lookup->IsTheHole());
1636 }
1637
1638
1639 RUNTIME_FUNCTION(Runtime_MapDelete) {
1640   HandleScope scope(isolate);
1641   ASSERT(args.length() == 2);
1642   CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
1643   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
1644   Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
1645   Handle<Object> lookup(table->Lookup(key), isolate);
1646   Handle<OrderedHashMap> new_table =
1647       OrderedHashMap::Put(table, key, isolate->factory()->the_hole_value());
1648   holder->set_table(*new_table);
1649   return isolate->heap()->ToBoolean(!lookup->IsTheHole());
1650 }
1651
1652
1653 RUNTIME_FUNCTION(Runtime_MapClear) {
1654   HandleScope scope(isolate);
1655   ASSERT(args.length() == 1);
1656   CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
1657   Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
1658   table = OrderedHashMap::Clear(table);
1659   holder->set_table(*table);
1660   return isolate->heap()->undefined_value();
1661 }
1662
1663
1664 RUNTIME_FUNCTION(Runtime_MapSet) {
1665   HandleScope scope(isolate);
1666   ASSERT(args.length() == 3);
1667   CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
1668   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
1669   CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
1670   Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
1671   Handle<OrderedHashMap> new_table = OrderedHashMap::Put(table, key, value);
1672   holder->set_table(*new_table);
1673   return isolate->heap()->undefined_value();
1674 }
1675
1676
1677 RUNTIME_FUNCTION(Runtime_MapGetSize) {
1678   HandleScope scope(isolate);
1679   ASSERT(args.length() == 1);
1680   CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
1681   Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
1682   return Smi::FromInt(table->NumberOfElements());
1683 }
1684
1685
1686 RUNTIME_FUNCTION(Runtime_MapCreateIterator) {
1687   HandleScope scope(isolate);
1688   ASSERT(args.length() == 2);
1689   CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
1690   CONVERT_SMI_ARG_CHECKED(kind, 1)
1691   RUNTIME_ASSERT(kind == JSMapIterator::kKindKeys
1692       || kind == JSMapIterator::kKindValues
1693       || kind == JSMapIterator::kKindEntries);
1694   Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
1695   return *JSMapIterator::Create(table, kind);
1696 }
1697
1698
1699 RUNTIME_FUNCTION(Runtime_MapIteratorNext) {
1700   HandleScope scope(isolate);
1701   ASSERT(args.length() == 1);
1702   CONVERT_ARG_HANDLE_CHECKED(JSMapIterator, holder, 0);
1703   return *JSMapIterator::Next(holder);
1704 }
1705
1706
1707 RUNTIME_FUNCTION(Runtime_MapIteratorClose) {
1708   HandleScope scope(isolate);
1709   ASSERT(args.length() == 1);
1710   CONVERT_ARG_HANDLE_CHECKED(JSMapIterator, holder, 0);
1711   holder->Close();
1712   return isolate->heap()->undefined_value();
1713 }
1714
1715
1716 static Handle<JSWeakCollection> WeakCollectionInitialize(
1717     Isolate* isolate,
1718     Handle<JSWeakCollection> weak_collection) {
1719   ASSERT(weak_collection->map()->inobject_properties() == 0);
1720   Handle<ObjectHashTable> table = ObjectHashTable::New(isolate, 0);
1721   weak_collection->set_table(*table);
1722   weak_collection->set_next(Smi::FromInt(0));
1723   return weak_collection;
1724 }
1725
1726
1727 RUNTIME_FUNCTION(Runtime_WeakCollectionInitialize) {
1728   HandleScope scope(isolate);
1729   ASSERT(args.length() == 1);
1730   CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
1731   return *WeakCollectionInitialize(isolate, weak_collection);
1732 }
1733
1734
1735 RUNTIME_FUNCTION(Runtime_WeakCollectionGet) {
1736   HandleScope scope(isolate);
1737   ASSERT(args.length() == 2);
1738   CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
1739   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
1740   Handle<ObjectHashTable> table(
1741       ObjectHashTable::cast(weak_collection->table()));
1742   Handle<Object> lookup(table->Lookup(key), isolate);
1743   return lookup->IsTheHole() ? isolate->heap()->undefined_value() : *lookup;
1744 }
1745
1746
1747 RUNTIME_FUNCTION(Runtime_WeakCollectionHas) {
1748   HandleScope scope(isolate);
1749   ASSERT(args.length() == 2);
1750   CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
1751   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
1752   Handle<ObjectHashTable> table(
1753       ObjectHashTable::cast(weak_collection->table()));
1754   Handle<Object> lookup(table->Lookup(key), isolate);
1755   return isolate->heap()->ToBoolean(!lookup->IsTheHole());
1756 }
1757
1758
1759 RUNTIME_FUNCTION(Runtime_WeakCollectionDelete) {
1760   HandleScope scope(isolate);
1761   ASSERT(args.length() == 2);
1762   CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
1763   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
1764   Handle<ObjectHashTable> table(ObjectHashTable::cast(
1765       weak_collection->table()));
1766   Handle<Object> lookup(table->Lookup(key), isolate);
1767   Handle<ObjectHashTable> new_table =
1768       ObjectHashTable::Put(table, key, isolate->factory()->the_hole_value());
1769   weak_collection->set_table(*new_table);
1770   return isolate->heap()->ToBoolean(!lookup->IsTheHole());
1771 }
1772
1773
1774 RUNTIME_FUNCTION(Runtime_WeakCollectionSet) {
1775   HandleScope scope(isolate);
1776   ASSERT(args.length() == 3);
1777   CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
1778   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
1779   CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
1780   Handle<ObjectHashTable> table(
1781       ObjectHashTable::cast(weak_collection->table()));
1782   Handle<ObjectHashTable> new_table = ObjectHashTable::Put(table, key, value);
1783   weak_collection->set_table(*new_table);
1784   return isolate->heap()->undefined_value();
1785 }
1786
1787
1788 RUNTIME_FUNCTION(Runtime_ClassOf) {
1789   SealHandleScope shs(isolate);
1790   ASSERT(args.length() == 1);
1791   CONVERT_ARG_CHECKED(Object, obj, 0);
1792   if (!obj->IsJSObject()) return isolate->heap()->null_value();
1793   return JSObject::cast(obj)->class_name();
1794 }
1795
1796
1797 RUNTIME_FUNCTION(Runtime_GetPrototype) {
1798   HandleScope scope(isolate);
1799   ASSERT(args.length() == 1);
1800   CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0);
1801   // We don't expect access checks to be needed on JSProxy objects.
1802   ASSERT(!obj->IsAccessCheckNeeded() || obj->IsJSObject());
1803   do {
1804     if (obj->IsAccessCheckNeeded() &&
1805         !isolate->MayNamedAccess(Handle<JSObject>::cast(obj),
1806                                  isolate->factory()->proto_string(),
1807                                  v8::ACCESS_GET)) {
1808       isolate->ReportFailedAccessCheck(Handle<JSObject>::cast(obj),
1809                                        v8::ACCESS_GET);
1810       RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
1811       return isolate->heap()->undefined_value();
1812     }
1813     obj = Object::GetPrototype(isolate, obj);
1814   } while (obj->IsJSObject() &&
1815            JSObject::cast(*obj)->map()->is_hidden_prototype());
1816   return *obj;
1817 }
1818
1819
1820 static inline Handle<Object> GetPrototypeSkipHiddenPrototypes(
1821     Isolate* isolate, Handle<Object> receiver) {
1822   Handle<Object> current = Object::GetPrototype(isolate, receiver);
1823   while (current->IsJSObject() &&
1824          JSObject::cast(*current)->map()->is_hidden_prototype()) {
1825     current = Object::GetPrototype(isolate, current);
1826   }
1827   return current;
1828 }
1829
1830
1831 RUNTIME_FUNCTION(Runtime_SetPrototype) {
1832   HandleScope scope(isolate);
1833   ASSERT(args.length() == 2);
1834   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
1835   CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
1836   if (obj->IsAccessCheckNeeded() &&
1837       !isolate->MayNamedAccess(
1838           obj, isolate->factory()->proto_string(), v8::ACCESS_SET)) {
1839     isolate->ReportFailedAccessCheck(obj, v8::ACCESS_SET);
1840     RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
1841     return isolate->heap()->undefined_value();
1842   }
1843   if (obj->map()->is_observed()) {
1844     Handle<Object> old_value = GetPrototypeSkipHiddenPrototypes(isolate, obj);
1845     Handle<Object> result;
1846     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
1847         isolate, result,
1848         JSObject::SetPrototype(obj, prototype, true));
1849
1850     Handle<Object> new_value = GetPrototypeSkipHiddenPrototypes(isolate, obj);
1851     if (!new_value->SameValue(*old_value)) {
1852       JSObject::EnqueueChangeRecord(obj, "setPrototype",
1853                                     isolate->factory()->proto_string(),
1854                                     old_value);
1855     }
1856     return *result;
1857   }
1858   Handle<Object> result;
1859   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
1860       isolate, result,
1861       JSObject::SetPrototype(obj, prototype, true));
1862   return *result;
1863 }
1864
1865
1866 RUNTIME_FUNCTION(Runtime_IsInPrototypeChain) {
1867   HandleScope shs(isolate);
1868   ASSERT(args.length() == 2);
1869   // See ECMA-262, section 15.3.5.3, page 88 (steps 5 - 8).
1870   CONVERT_ARG_HANDLE_CHECKED(Object, O, 0);
1871   CONVERT_ARG_HANDLE_CHECKED(Object, V, 1);
1872   while (true) {
1873     Handle<Object> prototype = Object::GetPrototype(isolate, V);
1874     if (prototype->IsNull()) return isolate->heap()->false_value();
1875     if (*O == *prototype) return isolate->heap()->true_value();
1876     V = prototype;
1877   }
1878 }
1879
1880
1881 static bool CheckAccessException(Object* callback,
1882                                  v8::AccessType access_type) {
1883   DisallowHeapAllocation no_gc;
1884   ASSERT(!callback->IsForeign());
1885   if (callback->IsAccessorInfo()) {
1886     AccessorInfo* info = AccessorInfo::cast(callback);
1887     return
1888         (access_type == v8::ACCESS_HAS &&
1889            (info->all_can_read() || info->all_can_write())) ||
1890         (access_type == v8::ACCESS_GET && info->all_can_read()) ||
1891         (access_type == v8::ACCESS_SET && info->all_can_write());
1892   }
1893   if (callback->IsAccessorPair()) {
1894     AccessorPair* info = AccessorPair::cast(callback);
1895     return
1896         (access_type == v8::ACCESS_HAS &&
1897            (info->all_can_read() || info->all_can_write())) ||
1898         (access_type == v8::ACCESS_GET && info->all_can_read()) ||
1899         (access_type == v8::ACCESS_SET && info->all_can_write());
1900   }
1901   return false;
1902 }
1903
1904
1905 template<class Key>
1906 static bool CheckGenericAccess(
1907     Handle<JSObject> receiver,
1908     Handle<JSObject> holder,
1909     Key key,
1910     v8::AccessType access_type,
1911     bool (Isolate::*mayAccess)(Handle<JSObject>, Key, v8::AccessType)) {
1912   Isolate* isolate = receiver->GetIsolate();
1913   for (Handle<JSObject> current = receiver;
1914        true;
1915        current = handle(JSObject::cast(current->GetPrototype()), isolate)) {
1916     if (current->IsAccessCheckNeeded() &&
1917         !(isolate->*mayAccess)(current, key, access_type)) {
1918       return false;
1919     }
1920     if (current.is_identical_to(holder)) break;
1921   }
1922   return true;
1923 }
1924
1925
1926 enum AccessCheckResult {
1927   ACCESS_FORBIDDEN,
1928   ACCESS_ALLOWED,
1929   ACCESS_ABSENT
1930 };
1931
1932
1933 static AccessCheckResult CheckPropertyAccess(Handle<JSObject> obj,
1934                                              Handle<Name> name,
1935                                              v8::AccessType access_type) {
1936   uint32_t index;
1937   if (name->AsArrayIndex(&index)) {
1938     // TODO(1095): we should traverse hidden prototype hierachy as well.
1939     if (CheckGenericAccess(
1940             obj, obj, index, access_type, &Isolate::MayIndexedAccess)) {
1941       return ACCESS_ALLOWED;
1942     }
1943
1944     obj->GetIsolate()->ReportFailedAccessCheck(obj, access_type);
1945     return ACCESS_FORBIDDEN;
1946   }
1947
1948   Isolate* isolate = obj->GetIsolate();
1949   LookupResult lookup(isolate);
1950   obj->LocalLookup(name, &lookup, true);
1951
1952   if (!lookup.IsProperty()) return ACCESS_ABSENT;
1953   Handle<JSObject> holder(lookup.holder(), isolate);
1954   if (CheckGenericAccess<Handle<Object> >(
1955           obj, holder, name, access_type, &Isolate::MayNamedAccess)) {
1956     return ACCESS_ALLOWED;
1957   }
1958
1959   // Access check callback denied the access, but some properties
1960   // can have a special permissions which override callbacks descision
1961   // (currently see v8::AccessControl).
1962   // API callbacks can have per callback access exceptions.
1963   switch (lookup.type()) {
1964     case CALLBACKS:
1965       if (CheckAccessException(lookup.GetCallbackObject(), access_type)) {
1966         return ACCESS_ALLOWED;
1967       }
1968       break;
1969     case INTERCEPTOR:
1970       // If the object has an interceptor, try real named properties.
1971       // Overwrite the result to fetch the correct property later.
1972       holder->LookupRealNamedProperty(name, &lookup);
1973       if (lookup.IsProperty() && lookup.IsPropertyCallbacks()) {
1974         if (CheckAccessException(lookup.GetCallbackObject(), access_type)) {
1975           return ACCESS_ALLOWED;
1976         }
1977       }
1978       break;
1979     default:
1980       break;
1981   }
1982
1983   isolate->ReportFailedAccessCheck(obj, access_type);
1984   return ACCESS_FORBIDDEN;
1985 }
1986
1987
1988 // Enumerator used as indices into the array returned from GetOwnProperty
1989 enum PropertyDescriptorIndices {
1990   IS_ACCESSOR_INDEX,
1991   VALUE_INDEX,
1992   GETTER_INDEX,
1993   SETTER_INDEX,
1994   WRITABLE_INDEX,
1995   ENUMERABLE_INDEX,
1996   CONFIGURABLE_INDEX,
1997   DESCRIPTOR_SIZE
1998 };
1999
2000
2001 MUST_USE_RESULT static MaybeHandle<Object> GetOwnProperty(Isolate* isolate,
2002                                                           Handle<JSObject> obj,
2003                                                           Handle<Name> name) {
2004   Heap* heap = isolate->heap();
2005   Factory* factory = isolate->factory();
2006   // Due to some WebKit tests, we want to make sure that we do not log
2007   // more than one access failure here.
2008   AccessCheckResult access_check_result =
2009       CheckPropertyAccess(obj, name, v8::ACCESS_HAS);
2010   RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
2011   switch (access_check_result) {
2012     case ACCESS_FORBIDDEN: return factory->false_value();
2013     case ACCESS_ALLOWED: break;
2014     case ACCESS_ABSENT: return factory->undefined_value();
2015   }
2016
2017   PropertyAttributes attrs = JSReceiver::GetLocalPropertyAttribute(obj, name);
2018   if (attrs == ABSENT) {
2019     RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
2020     return factory->undefined_value();
2021   }
2022   ASSERT(!isolate->has_scheduled_exception());
2023   Handle<AccessorPair> accessors;
2024   bool has_accessors =
2025       JSObject::GetLocalPropertyAccessorPair(obj, name).ToHandle(&accessors);
2026   Handle<FixedArray> elms = isolate->factory()->NewFixedArray(DESCRIPTOR_SIZE);
2027   elms->set(ENUMERABLE_INDEX, heap->ToBoolean((attrs & DONT_ENUM) == 0));
2028   elms->set(CONFIGURABLE_INDEX, heap->ToBoolean((attrs & DONT_DELETE) == 0));
2029   elms->set(IS_ACCESSOR_INDEX, heap->ToBoolean(has_accessors));
2030
2031   if (!has_accessors) {
2032     elms->set(WRITABLE_INDEX, heap->ToBoolean((attrs & READ_ONLY) == 0));
2033     // Runtime::GetObjectProperty does access check.
2034     Handle<Object> value;
2035     ASSIGN_RETURN_ON_EXCEPTION(
2036         isolate, value, Runtime::GetObjectProperty(isolate, obj, name),
2037         Object);
2038     elms->set(VALUE_INDEX, *value);
2039   } else {
2040     // Access checks are performed for both accessors separately.
2041     // When they fail, the respective field is not set in the descriptor.
2042     Handle<Object> getter(accessors->GetComponent(ACCESSOR_GETTER), isolate);
2043     Handle<Object> setter(accessors->GetComponent(ACCESSOR_SETTER), isolate);
2044
2045     if (!getter->IsMap() && CheckPropertyAccess(obj, name, v8::ACCESS_GET)) {
2046       ASSERT(!isolate->has_scheduled_exception());
2047       elms->set(GETTER_INDEX, *getter);
2048     } else {
2049       RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
2050     }
2051
2052     if (!setter->IsMap() && CheckPropertyAccess(obj, name, v8::ACCESS_SET)) {
2053       ASSERT(!isolate->has_scheduled_exception());
2054       elms->set(SETTER_INDEX, *setter);
2055     } else {
2056       RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
2057     }
2058   }
2059
2060   return isolate->factory()->NewJSArrayWithElements(elms);
2061 }
2062
2063
2064 // Returns an array with the property description:
2065 //  if args[1] is not a property on args[0]
2066 //          returns undefined
2067 //  if args[1] is a data property on args[0]
2068 //         [false, value, Writeable, Enumerable, Configurable]
2069 //  if args[1] is an accessor on args[0]
2070 //         [true, GetFunction, SetFunction, Enumerable, Configurable]
2071 RUNTIME_FUNCTION(Runtime_GetOwnProperty) {
2072   HandleScope scope(isolate);
2073   ASSERT(args.length() == 2);
2074   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
2075   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
2076   Handle<Object> result;
2077   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
2078       isolate, result, GetOwnProperty(isolate, obj, name));
2079   return *result;
2080 }
2081
2082
2083 RUNTIME_FUNCTION(Runtime_PreventExtensions) {
2084   HandleScope scope(isolate);
2085   ASSERT(args.length() == 1);
2086   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
2087   Handle<Object> result;
2088   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
2089       isolate, result, JSObject::PreventExtensions(obj));
2090   return *result;
2091 }
2092
2093
2094 RUNTIME_FUNCTION(Runtime_IsExtensible) {
2095   SealHandleScope shs(isolate);
2096   ASSERT(args.length() == 1);
2097   CONVERT_ARG_CHECKED(JSObject, obj, 0);
2098   if (obj->IsJSGlobalProxy()) {
2099     Object* proto = obj->GetPrototype();
2100     if (proto->IsNull()) return isolate->heap()->false_value();
2101     ASSERT(proto->IsJSGlobalObject());
2102     obj = JSObject::cast(proto);
2103   }
2104   return isolate->heap()->ToBoolean(obj->map()->is_extensible());
2105 }
2106
2107
2108 RUNTIME_FUNCTION(Runtime_RegExpCompile) {
2109   HandleScope scope(isolate);
2110   ASSERT(args.length() == 3);
2111   CONVERT_ARG_HANDLE_CHECKED(JSRegExp, re, 0);
2112   CONVERT_ARG_HANDLE_CHECKED(String, pattern, 1);
2113   CONVERT_ARG_HANDLE_CHECKED(String, flags, 2);
2114   Handle<Object> result;
2115   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
2116       isolate, result, RegExpImpl::Compile(re, pattern, flags));
2117   return *result;
2118 }
2119
2120
2121 RUNTIME_FUNCTION(Runtime_CreateApiFunction) {
2122   HandleScope scope(isolate);
2123   ASSERT(args.length() == 2);
2124   CONVERT_ARG_HANDLE_CHECKED(FunctionTemplateInfo, data, 0);
2125   CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
2126   return *isolate->factory()->CreateApiFunction(data, prototype);
2127 }
2128
2129
2130 RUNTIME_FUNCTION(Runtime_IsTemplate) {
2131   SealHandleScope shs(isolate);
2132   ASSERT(args.length() == 1);
2133   CONVERT_ARG_HANDLE_CHECKED(Object, arg, 0);
2134   bool result = arg->IsObjectTemplateInfo() || arg->IsFunctionTemplateInfo();
2135   return isolate->heap()->ToBoolean(result);
2136 }
2137
2138
2139 RUNTIME_FUNCTION(Runtime_GetTemplateField) {
2140   SealHandleScope shs(isolate);
2141   ASSERT(args.length() == 2);
2142   CONVERT_ARG_CHECKED(HeapObject, templ, 0);
2143   CONVERT_SMI_ARG_CHECKED(index, 1);
2144   int offset = index * kPointerSize + HeapObject::kHeaderSize;
2145   InstanceType type = templ->map()->instance_type();
2146   RUNTIME_ASSERT(type == FUNCTION_TEMPLATE_INFO_TYPE ||
2147                  type == OBJECT_TEMPLATE_INFO_TYPE);
2148   RUNTIME_ASSERT(offset > 0);
2149   if (type == FUNCTION_TEMPLATE_INFO_TYPE) {
2150     RUNTIME_ASSERT(offset < FunctionTemplateInfo::kSize);
2151   } else {
2152     RUNTIME_ASSERT(offset < ObjectTemplateInfo::kSize);
2153   }
2154   return *HeapObject::RawField(templ, offset);
2155 }
2156
2157
2158 RUNTIME_FUNCTION(Runtime_DisableAccessChecks) {
2159   HandleScope scope(isolate);
2160   ASSERT(args.length() == 1);
2161   CONVERT_ARG_HANDLE_CHECKED(HeapObject, object, 0);
2162   Handle<Map> old_map(object->map());
2163   bool needs_access_checks = old_map->is_access_check_needed();
2164   if (needs_access_checks) {
2165     // Copy map so it won't interfere constructor's initial map.
2166     Handle<Map> new_map = Map::Copy(old_map);
2167     new_map->set_is_access_check_needed(false);
2168     if (object->IsJSObject()) {
2169       JSObject::MigrateToMap(Handle<JSObject>::cast(object), new_map);
2170     } else {
2171       object->set_map(*new_map);
2172     }
2173   }
2174   return isolate->heap()->ToBoolean(needs_access_checks);
2175 }
2176
2177
2178 RUNTIME_FUNCTION(Runtime_EnableAccessChecks) {
2179   HandleScope scope(isolate);
2180   ASSERT(args.length() == 1);
2181   CONVERT_ARG_HANDLE_CHECKED(HeapObject, object, 0);
2182   Handle<Map> old_map(object->map());
2183   if (!old_map->is_access_check_needed()) {
2184     // Copy map so it won't interfere constructor's initial map.
2185     Handle<Map> new_map = Map::Copy(old_map);
2186     new_map->set_is_access_check_needed(true);
2187     if (object->IsJSObject()) {
2188       JSObject::MigrateToMap(Handle<JSObject>::cast(object), new_map);
2189     } else {
2190       object->set_map(*new_map);
2191     }
2192   }
2193   return isolate->heap()->undefined_value();
2194 }
2195
2196
2197 // Transform getter or setter into something DefineAccessor can handle.
2198 static Handle<Object> InstantiateAccessorComponent(Isolate* isolate,
2199                                                    Handle<Object> component) {
2200   if (component->IsUndefined()) return isolate->factory()->null_value();
2201   Handle<FunctionTemplateInfo> info =
2202       Handle<FunctionTemplateInfo>::cast(component);
2203   return Utils::OpenHandle(*Utils::ToLocal(info)->GetFunction());
2204 }
2205
2206
2207 RUNTIME_FUNCTION(Runtime_SetAccessorProperty) {
2208   HandleScope scope(isolate);
2209   ASSERT(args.length() == 6);
2210   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
2211   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
2212   CONVERT_ARG_HANDLE_CHECKED(Object, getter, 2);
2213   CONVERT_ARG_HANDLE_CHECKED(Object, setter, 3);
2214   CONVERT_SMI_ARG_CHECKED(attribute, 4);
2215   CONVERT_SMI_ARG_CHECKED(access_control, 5);
2216   RUNTIME_ASSERT(getter->IsUndefined() || getter->IsFunctionTemplateInfo());
2217   RUNTIME_ASSERT(setter->IsUndefined() || setter->IsFunctionTemplateInfo());
2218   RUNTIME_ASSERT(PropertyDetails::AttributesField::is_valid(
2219       static_cast<PropertyAttributes>(attribute)));
2220   JSObject::DefineAccessor(object,
2221                            name,
2222                            InstantiateAccessorComponent(isolate, getter),
2223                            InstantiateAccessorComponent(isolate, setter),
2224                            static_cast<PropertyAttributes>(attribute),
2225                            static_cast<v8::AccessControl>(access_control));
2226   return isolate->heap()->undefined_value();
2227 }
2228
2229
2230 static Object* ThrowRedeclarationError(Isolate* isolate, Handle<String> name) {
2231   HandleScope scope(isolate);
2232   Handle<Object> args[1] = { name };
2233   Handle<Object> error = isolate->factory()->NewTypeError(
2234       "var_redeclaration", HandleVector(args, 1));
2235   return isolate->Throw(*error);
2236 }
2237
2238
2239 RUNTIME_FUNCTION(RuntimeHidden_DeclareGlobals) {
2240   HandleScope scope(isolate);
2241   ASSERT(args.length() == 3);
2242   Handle<GlobalObject> global = Handle<GlobalObject>(
2243       isolate->context()->global_object());
2244
2245   CONVERT_ARG_HANDLE_CHECKED(Context, context, 0);
2246   CONVERT_ARG_HANDLE_CHECKED(FixedArray, pairs, 1);
2247   CONVERT_SMI_ARG_CHECKED(flags, 2);
2248
2249   // Traverse the name/value pairs and set the properties.
2250   int length = pairs->length();
2251   for (int i = 0; i < length; i += 2) {
2252     HandleScope scope(isolate);
2253     Handle<String> name(String::cast(pairs->get(i)));
2254     Handle<Object> value(pairs->get(i + 1), isolate);
2255
2256     // We have to declare a global const property. To capture we only
2257     // assign to it when evaluating the assignment for "const x =
2258     // <expr>" the initial value is the hole.
2259     bool is_var = value->IsUndefined();
2260     bool is_const = value->IsTheHole();
2261     bool is_function = value->IsSharedFunctionInfo();
2262     ASSERT(is_var + is_const + is_function == 1);
2263
2264     if (is_var || is_const) {
2265       // Lookup the property in the global object, and don't set the
2266       // value of the variable if the property is already there.
2267       // Do the lookup locally only, see ES5 erratum.
2268       LookupResult lookup(isolate);
2269       global->LocalLookup(name, &lookup, true);
2270       if (lookup.IsFound()) {
2271         // We found an existing property. Unless it was an interceptor
2272         // that claims the property is absent, skip this declaration.
2273         if (!lookup.IsInterceptor()) continue;
2274         if (JSReceiver::GetPropertyAttribute(global, name) != ABSENT) continue;
2275         // Fall-through and introduce the absent property by using
2276         // SetProperty.
2277       }
2278     } else if (is_function) {
2279       // Copy the function and update its context. Use it as value.
2280       Handle<SharedFunctionInfo> shared =
2281           Handle<SharedFunctionInfo>::cast(value);
2282       Handle<JSFunction> function =
2283           isolate->factory()->NewFunctionFromSharedFunctionInfo(
2284               shared, context, TENURED);
2285       value = function;
2286     }
2287
2288     LookupResult lookup(isolate);
2289     global->LocalLookup(name, &lookup, true);
2290
2291     // Compute the property attributes. According to ECMA-262,
2292     // the property must be non-configurable except in eval.
2293     int attr = NONE;
2294     bool is_eval = DeclareGlobalsEvalFlag::decode(flags);
2295     if (!is_eval) {
2296       attr |= DONT_DELETE;
2297     }
2298     bool is_native = DeclareGlobalsNativeFlag::decode(flags);
2299     if (is_const || (is_native && is_function)) {
2300       attr |= READ_ONLY;
2301     }
2302
2303     StrictMode strict_mode = DeclareGlobalsStrictMode::decode(flags);
2304
2305     if (!lookup.IsFound() || is_function) {
2306       // If the local property exists, check that we can reconfigure it
2307       // as required for function declarations.
2308       if (lookup.IsFound() && lookup.IsDontDelete()) {
2309         if (lookup.IsReadOnly() || lookup.IsDontEnum() ||
2310             lookup.IsPropertyCallbacks()) {
2311           return ThrowRedeclarationError(isolate, name);
2312         }
2313         // If the existing property is not configurable, keep its attributes.
2314         attr = lookup.GetAttributes();
2315       }
2316       // Define or redefine own property.
2317       RETURN_FAILURE_ON_EXCEPTION(isolate,
2318           JSObject::SetLocalPropertyIgnoreAttributes(
2319               global, name, value, static_cast<PropertyAttributes>(attr)));
2320     } else {
2321       // Do a [[Put]] on the existing (own) property.
2322       RETURN_FAILURE_ON_EXCEPTION(
2323           isolate,
2324           JSObject::SetProperty(
2325               global, name, value, static_cast<PropertyAttributes>(attr),
2326               strict_mode));
2327     }
2328   }
2329
2330   ASSERT(!isolate->has_pending_exception());
2331   return isolate->heap()->undefined_value();
2332 }
2333
2334
2335 RUNTIME_FUNCTION(RuntimeHidden_DeclareContextSlot) {
2336   HandleScope scope(isolate);
2337   ASSERT(args.length() == 4);
2338
2339   // Declarations are always made in a function or native context.  In the
2340   // case of eval code, the context passed is the context of the caller,
2341   // which may be some nested context and not the declaration context.
2342   CONVERT_ARG_HANDLE_CHECKED(Context, context_arg, 0);
2343   Handle<Context> context(context_arg->declaration_context());
2344   CONVERT_ARG_HANDLE_CHECKED(String, name, 1);
2345   CONVERT_SMI_ARG_CHECKED(mode_arg, 2);
2346   PropertyAttributes mode = static_cast<PropertyAttributes>(mode_arg);
2347   RUNTIME_ASSERT(mode == READ_ONLY || mode == NONE);
2348   CONVERT_ARG_HANDLE_CHECKED(Object, initial_value, 3);
2349
2350   int index;
2351   PropertyAttributes attributes;
2352   ContextLookupFlags flags = DONT_FOLLOW_CHAINS;
2353   BindingFlags binding_flags;
2354   Handle<Object> holder =
2355       context->Lookup(name, flags, &index, &attributes, &binding_flags);
2356
2357   if (attributes != ABSENT) {
2358     // The name was declared before; check for conflicting re-declarations.
2359     // Note: this is actually inconsistent with what happens for globals (where
2360     // we silently ignore such declarations).
2361     if (((attributes & READ_ONLY) != 0) || (mode == READ_ONLY)) {
2362       // Functions are not read-only.
2363       ASSERT(mode != READ_ONLY || initial_value->IsTheHole());
2364       return ThrowRedeclarationError(isolate, name);
2365     }
2366
2367     // Initialize it if necessary.
2368     if (*initial_value != NULL) {
2369       if (index >= 0) {
2370         ASSERT(holder.is_identical_to(context));
2371         if (((attributes & READ_ONLY) == 0) ||
2372             context->get(index)->IsTheHole()) {
2373           context->set(index, *initial_value);
2374         }
2375       } else {
2376         // Slow case: The property is in the context extension object of a
2377         // function context or the global object of a native context.
2378         Handle<JSObject> object = Handle<JSObject>::cast(holder);
2379         RETURN_FAILURE_ON_EXCEPTION(
2380             isolate,
2381             JSReceiver::SetProperty(object, name, initial_value, mode, SLOPPY));
2382       }
2383     }
2384
2385   } else {
2386     // The property is not in the function context. It needs to be
2387     // "declared" in the function context's extension context or as a
2388     // property of the the global object.
2389     Handle<JSObject> object;
2390     if (context->has_extension()) {
2391       object = Handle<JSObject>(JSObject::cast(context->extension()));
2392     } else {
2393       // Context extension objects are allocated lazily.
2394       ASSERT(context->IsFunctionContext());
2395       object = isolate->factory()->NewJSObject(
2396           isolate->context_extension_function());
2397       context->set_extension(*object);
2398     }
2399     ASSERT(*object != NULL);
2400
2401     // Declare the property by setting it to the initial value if provided,
2402     // or undefined, and use the correct mode (e.g. READ_ONLY attribute for
2403     // constant declarations).
2404     ASSERT(!JSReceiver::HasLocalProperty(object, name));
2405     Handle<Object> value(isolate->heap()->undefined_value(), isolate);
2406     if (*initial_value != NULL) value = initial_value;
2407     // Declaring a const context slot is a conflicting declaration if
2408     // there is a callback with that name in a prototype. It is
2409     // allowed to introduce const variables in
2410     // JSContextExtensionObjects. They are treated specially in
2411     // SetProperty and no setters are invoked for those since they are
2412     // not real JSObjects.
2413     if (initial_value->IsTheHole() &&
2414         !object->IsJSContextExtensionObject()) {
2415       LookupResult lookup(isolate);
2416       object->Lookup(name, &lookup);
2417       if (lookup.IsPropertyCallbacks()) {
2418         return ThrowRedeclarationError(isolate, name);
2419       }
2420     }
2421     if (object->IsJSGlobalObject()) {
2422       // Define own property on the global object.
2423       RETURN_FAILURE_ON_EXCEPTION(isolate,
2424          JSObject::SetLocalPropertyIgnoreAttributes(object, name, value, mode));
2425     } else {
2426       RETURN_FAILURE_ON_EXCEPTION(isolate,
2427          JSReceiver::SetProperty(object, name, value, mode, SLOPPY));
2428     }
2429   }
2430
2431   return isolate->heap()->undefined_value();
2432 }
2433
2434
2435 RUNTIME_FUNCTION(Runtime_InitializeVarGlobal) {
2436   HandleScope scope(isolate);
2437   // args[0] == name
2438   // args[1] == language_mode
2439   // args[2] == value (optional)
2440
2441   // Determine if we need to assign to the variable if it already
2442   // exists (based on the number of arguments).
2443   RUNTIME_ASSERT(args.length() == 2 || args.length() == 3);
2444   bool assign = args.length() == 3;
2445
2446   CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
2447   CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 1);
2448
2449   // According to ECMA-262, section 12.2, page 62, the property must
2450   // not be deletable.
2451   PropertyAttributes attributes = DONT_DELETE;
2452
2453   // Lookup the property locally in the global object. If it isn't
2454   // there, there is a property with this name in the prototype chain.
2455   // We follow Safari and Firefox behavior and only set the property
2456   // locally if there is an explicit initialization value that we have
2457   // to assign to the property.
2458   // Note that objects can have hidden prototypes, so we need to traverse
2459   // the whole chain of hidden prototypes to do a 'local' lookup.
2460   LookupResult lookup(isolate);
2461   isolate->context()->global_object()->LocalLookup(name, &lookup, true);
2462   if (lookup.IsInterceptor()) {
2463     Handle<JSObject> holder(lookup.holder());
2464     PropertyAttributes intercepted =
2465         JSReceiver::GetPropertyAttribute(holder, name);
2466     if (intercepted != ABSENT && (intercepted & READ_ONLY) == 0) {
2467       // Found an interceptor that's not read only.
2468       if (assign) {
2469         CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
2470         Handle<Object> result;
2471         ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
2472             isolate, result,
2473             JSObject::SetPropertyForResult(
2474                 holder, &lookup, name, value, attributes, strict_mode));
2475         return *result;
2476       } else {
2477         return isolate->heap()->undefined_value();
2478       }
2479     }
2480   }
2481
2482   if (assign) {
2483     CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
2484     Handle<GlobalObject> global(isolate->context()->global_object());
2485     Handle<Object> result;
2486     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
2487         isolate, result,
2488         JSReceiver::SetProperty(global, name, value, attributes, strict_mode));
2489     return *result;
2490   }
2491   return isolate->heap()->undefined_value();
2492 }
2493
2494
2495 RUNTIME_FUNCTION(RuntimeHidden_InitializeConstGlobal) {
2496   SealHandleScope shs(isolate);
2497   // All constants are declared with an initial value. The name
2498   // of the constant is the first argument and the initial value
2499   // is the second.
2500   RUNTIME_ASSERT(args.length() == 2);
2501   CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
2502   CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
2503
2504   // Get the current global object from top.
2505   GlobalObject* global = isolate->context()->global_object();
2506
2507   // According to ECMA-262, section 12.2, page 62, the property must
2508   // not be deletable. Since it's a const, it must be READ_ONLY too.
2509   PropertyAttributes attributes =
2510       static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY);
2511
2512   // Lookup the property locally in the global object. If it isn't
2513   // there, we add the property and take special precautions to always
2514   // add it as a local property even in case of callbacks in the
2515   // prototype chain (this rules out using SetProperty).
2516   // We use SetLocalPropertyIgnoreAttributes instead
2517   LookupResult lookup(isolate);
2518   global->LocalLookup(name, &lookup);
2519   if (!lookup.IsFound()) {
2520     HandleScope handle_scope(isolate);
2521     Handle<GlobalObject> global(isolate->context()->global_object());
2522     RETURN_FAILURE_ON_EXCEPTION(
2523         isolate,
2524         JSObject::SetLocalPropertyIgnoreAttributes(global, name, value,
2525                                                    attributes));
2526     return *value;
2527   }
2528
2529   if (!lookup.IsReadOnly()) {
2530     // Restore global object from context (in case of GC) and continue
2531     // with setting the value.
2532     HandleScope handle_scope(isolate);
2533     Handle<GlobalObject> global(isolate->context()->global_object());
2534
2535     // BUG 1213575: Handle the case where we have to set a read-only
2536     // property through an interceptor and only do it if it's
2537     // uninitialized, e.g. the hole. Nirk...
2538     // Passing sloppy mode because the property is writable.
2539     RETURN_FAILURE_ON_EXCEPTION(
2540         isolate,
2541         JSReceiver::SetProperty(global, name, value, attributes, SLOPPY));
2542     return *value;
2543   }
2544
2545   // Set the value, but only if we're assigning the initial value to a
2546   // constant. For now, we determine this by checking if the
2547   // current value is the hole.
2548   // Strict mode handling not needed (const is disallowed in strict mode).
2549   if (lookup.IsField()) {
2550     FixedArray* properties = global->properties();
2551     int index = lookup.GetFieldIndex().field_index();
2552     if (properties->get(index)->IsTheHole() || !lookup.IsReadOnly()) {
2553       properties->set(index, *value);
2554     }
2555   } else if (lookup.IsNormal()) {
2556     if (global->GetNormalizedProperty(&lookup)->IsTheHole() ||
2557         !lookup.IsReadOnly()) {
2558       HandleScope scope(isolate);
2559       JSObject::SetNormalizedProperty(Handle<JSObject>(global), &lookup, value);
2560     }
2561   } else {
2562     // Ignore re-initialization of constants that have already been
2563     // assigned a constant value.
2564     ASSERT(lookup.IsReadOnly() && lookup.IsConstant());
2565   }
2566
2567   // Use the set value as the result of the operation.
2568   return *value;
2569 }
2570
2571
2572 RUNTIME_FUNCTION(RuntimeHidden_InitializeConstContextSlot) {
2573   HandleScope scope(isolate);
2574   ASSERT(args.length() == 3);
2575
2576   CONVERT_ARG_HANDLE_CHECKED(Object, value, 0);
2577   ASSERT(!value->IsTheHole());
2578   // Initializations are always done in a function or native context.
2579   CONVERT_ARG_HANDLE_CHECKED(Context, context_arg, 1);
2580   Handle<Context> context(context_arg->declaration_context());
2581   CONVERT_ARG_HANDLE_CHECKED(String, name, 2);
2582
2583   int index;
2584   PropertyAttributes attributes;
2585   ContextLookupFlags flags = FOLLOW_CHAINS;
2586   BindingFlags binding_flags;
2587   Handle<Object> holder =
2588       context->Lookup(name, flags, &index, &attributes, &binding_flags);
2589
2590   if (index >= 0) {
2591     ASSERT(holder->IsContext());
2592     // Property was found in a context.  Perform the assignment if we
2593     // found some non-constant or an uninitialized constant.
2594     Handle<Context> context = Handle<Context>::cast(holder);
2595     if ((attributes & READ_ONLY) == 0 || context->get(index)->IsTheHole()) {
2596       context->set(index, *value);
2597     }
2598     return *value;
2599   }
2600
2601   // The property could not be found, we introduce it as a property of the
2602   // global object.
2603   if (attributes == ABSENT) {
2604     Handle<JSObject> global = Handle<JSObject>(
2605         isolate->context()->global_object());
2606     // Strict mode not needed (const disallowed in strict mode).
2607     RETURN_FAILURE_ON_EXCEPTION(
2608         isolate,
2609         JSReceiver::SetProperty(global, name, value, NONE, SLOPPY));
2610     return *value;
2611   }
2612
2613   // The property was present in some function's context extension object,
2614   // as a property on the subject of a with, or as a property of the global
2615   // object.
2616   //
2617   // In most situations, eval-introduced consts should still be present in
2618   // the context extension object.  However, because declaration and
2619   // initialization are separate, the property might have been deleted
2620   // before we reach the initialization point.
2621   //
2622   // Example:
2623   //
2624   //    function f() { eval("delete x; const x;"); }
2625   //
2626   // In that case, the initialization behaves like a normal assignment.
2627   Handle<JSObject> object = Handle<JSObject>::cast(holder);
2628
2629   if (*object == context->extension()) {
2630     // This is the property that was introduced by the const declaration.
2631     // Set it if it hasn't been set before.  NOTE: We cannot use
2632     // GetProperty() to get the current value as it 'unholes' the value.
2633     LookupResult lookup(isolate);
2634     object->LocalLookupRealNamedProperty(name, &lookup);
2635     ASSERT(lookup.IsFound());  // the property was declared
2636     ASSERT(lookup.IsReadOnly());  // and it was declared as read-only
2637
2638     if (lookup.IsField()) {
2639       FixedArray* properties = object->properties();
2640       int index = lookup.GetFieldIndex().field_index();
2641       if (properties->get(index)->IsTheHole()) {
2642         properties->set(index, *value);
2643       }
2644     } else if (lookup.IsNormal()) {
2645       if (object->GetNormalizedProperty(&lookup)->IsTheHole()) {
2646         JSObject::SetNormalizedProperty(object, &lookup, value);
2647       }
2648     } else {
2649       // We should not reach here. Any real, named property should be
2650       // either a field or a dictionary slot.
2651       UNREACHABLE();
2652     }
2653   } else {
2654     // The property was found on some other object.  Set it if it is not a
2655     // read-only property.
2656     if ((attributes & READ_ONLY) == 0) {
2657       // Strict mode not needed (const disallowed in strict mode).
2658       RETURN_FAILURE_ON_EXCEPTION(
2659           isolate,
2660           JSReceiver::SetProperty(object, name, value, attributes, SLOPPY));
2661     }
2662   }
2663
2664   return *value;
2665 }
2666
2667
2668 RUNTIME_FUNCTION(Runtime_OptimizeObjectForAddingMultipleProperties) {
2669   HandleScope scope(isolate);
2670   ASSERT(args.length() == 2);
2671   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
2672   CONVERT_SMI_ARG_CHECKED(properties, 1);
2673   // Conservative upper limit to prevent fuzz tests from going OOM.
2674   RUNTIME_ASSERT(properties <= 100000);
2675   if (object->HasFastProperties() && !object->IsJSGlobalProxy()) {
2676     JSObject::NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, properties);
2677   }
2678   return *object;
2679 }
2680
2681
2682 RUNTIME_FUNCTION(RuntimeHidden_RegExpExec) {
2683   HandleScope scope(isolate);
2684   ASSERT(args.length() == 4);
2685   CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0);
2686   CONVERT_ARG_HANDLE_CHECKED(String, subject, 1);
2687   // Due to the way the JS calls are constructed this must be less than the
2688   // length of a string, i.e. it is always a Smi.  We check anyway for security.
2689   CONVERT_SMI_ARG_CHECKED(index, 2);
2690   CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 3);
2691   RUNTIME_ASSERT(index >= 0);
2692   RUNTIME_ASSERT(index <= subject->length());
2693   isolate->counters()->regexp_entry_runtime()->Increment();
2694   Handle<Object> result;
2695   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
2696       isolate, result,
2697       RegExpImpl::Exec(regexp, subject, index, last_match_info));
2698   return *result;
2699 }
2700
2701
2702 RUNTIME_FUNCTION(RuntimeHidden_RegExpConstructResult) {
2703   HandleScope handle_scope(isolate);
2704   ASSERT(args.length() == 3);
2705   CONVERT_SMI_ARG_CHECKED(size, 0);
2706   RUNTIME_ASSERT(size >= 0 && size <= FixedArray::kMaxLength);
2707   CONVERT_ARG_HANDLE_CHECKED(Object, index, 1);
2708   CONVERT_ARG_HANDLE_CHECKED(Object, input, 2);
2709   Handle<FixedArray> elements =  isolate->factory()->NewFixedArray(size);
2710   Handle<Map> regexp_map(isolate->native_context()->regexp_result_map());
2711   Handle<JSObject> object =
2712       isolate->factory()->NewJSObjectFromMap(regexp_map, NOT_TENURED, false);
2713   Handle<JSArray> array = Handle<JSArray>::cast(object);
2714   array->set_elements(*elements);
2715   array->set_length(Smi::FromInt(size));
2716   // Write in-object properties after the length of the array.
2717   array->InObjectPropertyAtPut(JSRegExpResult::kIndexIndex, *index);
2718   array->InObjectPropertyAtPut(JSRegExpResult::kInputIndex, *input);
2719   return *array;
2720 }
2721
2722
2723 RUNTIME_FUNCTION(Runtime_RegExpInitializeObject) {
2724   HandleScope scope(isolate);
2725   ASSERT(args.length() == 5);
2726   CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0);
2727   CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
2728   // If source is the empty string we set it to "(?:)" instead as
2729   // suggested by ECMA-262, 5th, section 15.10.4.1.
2730   if (source->length() == 0) source = isolate->factory()->query_colon_string();
2731
2732   CONVERT_ARG_HANDLE_CHECKED(Object, global, 2);
2733   if (!global->IsTrue()) global = isolate->factory()->false_value();
2734
2735   CONVERT_ARG_HANDLE_CHECKED(Object, ignoreCase, 3);
2736   if (!ignoreCase->IsTrue()) ignoreCase = isolate->factory()->false_value();
2737
2738   CONVERT_ARG_HANDLE_CHECKED(Object, multiline, 4);
2739   if (!multiline->IsTrue()) multiline = isolate->factory()->false_value();
2740
2741   Map* map = regexp->map();
2742   Object* constructor = map->constructor();
2743   if (constructor->IsJSFunction() &&
2744       JSFunction::cast(constructor)->initial_map() == map) {
2745     // If we still have the original map, set in-object properties directly.
2746     regexp->InObjectPropertyAtPut(JSRegExp::kSourceFieldIndex, *source);
2747     // Both true and false are immovable immortal objects so no need for write
2748     // barrier.
2749     regexp->InObjectPropertyAtPut(
2750         JSRegExp::kGlobalFieldIndex, *global, SKIP_WRITE_BARRIER);
2751     regexp->InObjectPropertyAtPut(
2752         JSRegExp::kIgnoreCaseFieldIndex, *ignoreCase, SKIP_WRITE_BARRIER);
2753     regexp->InObjectPropertyAtPut(
2754         JSRegExp::kMultilineFieldIndex, *multiline, SKIP_WRITE_BARRIER);
2755     regexp->InObjectPropertyAtPut(
2756         JSRegExp::kLastIndexFieldIndex, Smi::FromInt(0), SKIP_WRITE_BARRIER);
2757     return *regexp;
2758   }
2759
2760   // Map has changed, so use generic, but slower, method.
2761   PropertyAttributes final =
2762       static_cast<PropertyAttributes>(READ_ONLY | DONT_ENUM | DONT_DELETE);
2763   PropertyAttributes writable =
2764       static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
2765   Handle<Object> zero(Smi::FromInt(0), isolate);
2766   Factory* factory = isolate->factory();
2767   JSObject::SetLocalPropertyIgnoreAttributes(
2768       regexp, factory->source_string(), source, final).Check();
2769   JSObject::SetLocalPropertyIgnoreAttributes(
2770       regexp, factory->global_string(), global, final).Check();
2771   JSObject::SetLocalPropertyIgnoreAttributes(
2772       regexp, factory->ignore_case_string(), ignoreCase, final).Check();
2773   JSObject::SetLocalPropertyIgnoreAttributes(
2774       regexp, factory->multiline_string(), multiline, final).Check();
2775   JSObject::SetLocalPropertyIgnoreAttributes(
2776       regexp, factory->last_index_string(), zero, writable).Check();
2777   return *regexp;
2778 }
2779
2780
2781 RUNTIME_FUNCTION(Runtime_FinishArrayPrototypeSetup) {
2782   HandleScope scope(isolate);
2783   ASSERT(args.length() == 1);
2784   CONVERT_ARG_HANDLE_CHECKED(JSArray, prototype, 0);
2785   Object* length = prototype->length();
2786   RUNTIME_ASSERT(length->IsSmi() && Smi::cast(length)->value() == 0);
2787   RUNTIME_ASSERT(prototype->HasFastSmiOrObjectElements());
2788   // This is necessary to enable fast checks for absence of elements
2789   // on Array.prototype and below.
2790   prototype->set_elements(isolate->heap()->empty_fixed_array());
2791   return Smi::FromInt(0);
2792 }
2793
2794
2795 static Handle<JSFunction> InstallBuiltin(Isolate* isolate,
2796                                          Handle<JSObject> holder,
2797                                          const char* name,
2798                                          Builtins::Name builtin_name) {
2799   Handle<String> key = isolate->factory()->InternalizeUtf8String(name);
2800   Handle<Code> code(isolate->builtins()->builtin(builtin_name));
2801   Handle<JSFunction> optimized =
2802       isolate->factory()->NewFunction(MaybeHandle<Object>(),
2803                                       key,
2804                                       JS_OBJECT_TYPE,
2805                                       JSObject::kHeaderSize,
2806                                       code,
2807                                       false);
2808   optimized->shared()->DontAdaptArguments();
2809   JSReceiver::SetProperty(holder, key, optimized, NONE, STRICT).Assert();
2810   return optimized;
2811 }
2812
2813
2814 RUNTIME_FUNCTION(Runtime_SpecialArrayFunctions) {
2815   HandleScope scope(isolate);
2816   ASSERT(args.length() == 1);
2817   CONVERT_ARG_HANDLE_CHECKED(JSObject, holder, 0);
2818
2819   InstallBuiltin(isolate, holder, "pop", Builtins::kArrayPop);
2820   InstallBuiltin(isolate, holder, "push", Builtins::kArrayPush);
2821   InstallBuiltin(isolate, holder, "shift", Builtins::kArrayShift);
2822   InstallBuiltin(isolate, holder, "unshift", Builtins::kArrayUnshift);
2823   InstallBuiltin(isolate, holder, "slice", Builtins::kArraySlice);
2824   InstallBuiltin(isolate, holder, "splice", Builtins::kArraySplice);
2825   InstallBuiltin(isolate, holder, "concat", Builtins::kArrayConcat);
2826
2827   return *holder;
2828 }
2829
2830
2831 RUNTIME_FUNCTION(Runtime_IsSloppyModeFunction) {
2832   SealHandleScope shs(isolate);
2833   ASSERT(args.length() == 1);
2834   CONVERT_ARG_CHECKED(JSReceiver, callable, 0);
2835   if (!callable->IsJSFunction()) {
2836     HandleScope scope(isolate);
2837     Handle<Object> delegate;
2838     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
2839         isolate, delegate,
2840         Execution::TryGetFunctionDelegate(
2841             isolate, Handle<JSReceiver>(callable)));
2842     callable = JSFunction::cast(*delegate);
2843   }
2844   JSFunction* function = JSFunction::cast(callable);
2845   SharedFunctionInfo* shared = function->shared();
2846   return isolate->heap()->ToBoolean(shared->strict_mode() == SLOPPY);
2847 }
2848
2849
2850 RUNTIME_FUNCTION(Runtime_GetDefaultReceiver) {
2851   SealHandleScope shs(isolate);
2852   ASSERT(args.length() == 1);
2853   CONVERT_ARG_CHECKED(JSReceiver, callable, 0);
2854
2855   if (!callable->IsJSFunction()) {
2856     HandleScope scope(isolate);
2857     Handle<Object> delegate;
2858     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
2859         isolate, delegate,
2860         Execution::TryGetFunctionDelegate(
2861             isolate, Handle<JSReceiver>(callable)));
2862     callable = JSFunction::cast(*delegate);
2863   }
2864   JSFunction* function = JSFunction::cast(callable);
2865
2866   SharedFunctionInfo* shared = function->shared();
2867   if (shared->native() || shared->strict_mode() == STRICT) {
2868     return isolate->heap()->undefined_value();
2869   }
2870   // Returns undefined for strict or native functions, or
2871   // the associated global receiver for "normal" functions.
2872
2873   Context* native_context =
2874       function->context()->global_object()->native_context();
2875   return native_context->global_object()->global_receiver();
2876 }
2877
2878
2879 RUNTIME_FUNCTION(RuntimeHidden_MaterializeRegExpLiteral) {
2880   HandleScope scope(isolate);
2881   ASSERT(args.length() == 4);
2882   CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
2883   CONVERT_SMI_ARG_CHECKED(index, 1);
2884   CONVERT_ARG_HANDLE_CHECKED(String, pattern, 2);
2885   CONVERT_ARG_HANDLE_CHECKED(String, flags, 3);
2886
2887   // Get the RegExp function from the context in the literals array.
2888   // This is the RegExp function from the context in which the
2889   // function was created.  We do not use the RegExp function from the
2890   // current native context because this might be the RegExp function
2891   // from another context which we should not have access to.
2892   Handle<JSFunction> constructor =
2893       Handle<JSFunction>(
2894           JSFunction::NativeContextFromLiterals(*literals)->regexp_function());
2895   // Compute the regular expression literal.
2896   Handle<Object> regexp;
2897   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
2898       isolate, regexp,
2899       RegExpImpl::CreateRegExpLiteral(constructor, pattern, flags));
2900   literals->set(index, *regexp);
2901   return *regexp;
2902 }
2903
2904
2905 RUNTIME_FUNCTION(Runtime_FunctionGetName) {
2906   SealHandleScope shs(isolate);
2907   ASSERT(args.length() == 1);
2908
2909   CONVERT_ARG_CHECKED(JSFunction, f, 0);
2910   return f->shared()->name();
2911 }
2912
2913
2914 RUNTIME_FUNCTION(Runtime_FunctionSetName) {
2915   SealHandleScope shs(isolate);
2916   ASSERT(args.length() == 2);
2917
2918   CONVERT_ARG_CHECKED(JSFunction, f, 0);
2919   CONVERT_ARG_CHECKED(String, name, 1);
2920   f->shared()->set_name(name);
2921   return isolate->heap()->undefined_value();
2922 }
2923
2924
2925 RUNTIME_FUNCTION(Runtime_FunctionNameShouldPrintAsAnonymous) {
2926   SealHandleScope shs(isolate);
2927   ASSERT(args.length() == 1);
2928   CONVERT_ARG_CHECKED(JSFunction, f, 0);
2929   return isolate->heap()->ToBoolean(
2930       f->shared()->name_should_print_as_anonymous());
2931 }
2932
2933
2934 RUNTIME_FUNCTION(Runtime_FunctionMarkNameShouldPrintAsAnonymous) {
2935   SealHandleScope shs(isolate);
2936   ASSERT(args.length() == 1);
2937   CONVERT_ARG_CHECKED(JSFunction, f, 0);
2938   f->shared()->set_name_should_print_as_anonymous(true);
2939   return isolate->heap()->undefined_value();
2940 }
2941
2942
2943 RUNTIME_FUNCTION(Runtime_FunctionIsGenerator) {
2944   SealHandleScope shs(isolate);
2945   ASSERT(args.length() == 1);
2946   CONVERT_ARG_CHECKED(JSFunction, f, 0);
2947   return isolate->heap()->ToBoolean(f->shared()->is_generator());
2948 }
2949
2950
2951 RUNTIME_FUNCTION(Runtime_FunctionRemovePrototype) {
2952   SealHandleScope shs(isolate);
2953   ASSERT(args.length() == 1);
2954
2955   CONVERT_ARG_CHECKED(JSFunction, f, 0);
2956   RUNTIME_ASSERT(f->RemovePrototype());
2957
2958   return isolate->heap()->undefined_value();
2959 }
2960
2961
2962 RUNTIME_FUNCTION(Runtime_FunctionGetScript) {
2963   HandleScope scope(isolate);
2964   ASSERT(args.length() == 1);
2965
2966   CONVERT_ARG_CHECKED(JSFunction, fun, 0);
2967   Handle<Object> script = Handle<Object>(fun->shared()->script(), isolate);
2968   if (!script->IsScript()) return isolate->heap()->undefined_value();
2969
2970   return *Script::GetWrapper(Handle<Script>::cast(script));
2971 }
2972
2973
2974 RUNTIME_FUNCTION(Runtime_FunctionGetSourceCode) {
2975   HandleScope scope(isolate);
2976   ASSERT(args.length() == 1);
2977
2978   CONVERT_ARG_HANDLE_CHECKED(JSFunction, f, 0);
2979   Handle<SharedFunctionInfo> shared(f->shared());
2980   return *shared->GetSourceCode();
2981 }
2982
2983
2984 RUNTIME_FUNCTION(Runtime_FunctionGetScriptSourcePosition) {
2985   SealHandleScope shs(isolate);
2986   ASSERT(args.length() == 1);
2987
2988   CONVERT_ARG_CHECKED(JSFunction, fun, 0);
2989   int pos = fun->shared()->start_position();
2990   return Smi::FromInt(pos);
2991 }
2992
2993
2994 RUNTIME_FUNCTION(Runtime_FunctionGetPositionForOffset) {
2995   SealHandleScope shs(isolate);
2996   ASSERT(args.length() == 2);
2997
2998   CONVERT_ARG_CHECKED(Code, code, 0);
2999   CONVERT_NUMBER_CHECKED(int, offset, Int32, args[1]);
3000
3001   RUNTIME_ASSERT(0 <= offset && offset < code->Size());
3002
3003   Address pc = code->address() + offset;
3004   return Smi::FromInt(code->SourcePosition(pc));
3005 }
3006
3007
3008 RUNTIME_FUNCTION(Runtime_FunctionSetInstanceClassName) {
3009   SealHandleScope shs(isolate);
3010   ASSERT(args.length() == 2);
3011
3012   CONVERT_ARG_CHECKED(JSFunction, fun, 0);
3013   CONVERT_ARG_CHECKED(String, name, 1);
3014   fun->SetInstanceClassName(name);
3015   return isolate->heap()->undefined_value();
3016 }
3017
3018
3019 RUNTIME_FUNCTION(Runtime_FunctionSetLength) {
3020   SealHandleScope shs(isolate);
3021   ASSERT(args.length() == 2);
3022
3023   CONVERT_ARG_CHECKED(JSFunction, fun, 0);
3024   CONVERT_SMI_ARG_CHECKED(length, 1);
3025   fun->shared()->set_length(length);
3026   return isolate->heap()->undefined_value();
3027 }
3028
3029
3030 RUNTIME_FUNCTION(Runtime_FunctionSetPrototype) {
3031   HandleScope scope(isolate);
3032   ASSERT(args.length() == 2);
3033
3034   CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
3035   CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
3036   ASSERT(fun->should_have_prototype());
3037   Accessors::FunctionSetPrototype(fun, value);
3038   return args[0];  // return TOS
3039 }
3040
3041
3042 RUNTIME_FUNCTION(Runtime_FunctionSetReadOnlyPrototype) {
3043   HandleScope shs(isolate);
3044   RUNTIME_ASSERT(args.length() == 1);
3045   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
3046
3047   Handle<String> name = isolate->factory()->prototype_string();
3048
3049   if (function->HasFastProperties()) {
3050     // Construct a new field descriptor with updated attributes.
3051     Handle<DescriptorArray> instance_desc =
3052         handle(function->map()->instance_descriptors());
3053
3054     int index = instance_desc->SearchWithCache(*name, function->map());
3055     ASSERT(index != DescriptorArray::kNotFound);
3056     PropertyDetails details = instance_desc->GetDetails(index);
3057
3058     CallbacksDescriptor new_desc(
3059         name,
3060         handle(instance_desc->GetValue(index), isolate),
3061         static_cast<PropertyAttributes>(details.attributes() | READ_ONLY));
3062
3063     // Create a new map featuring the new field descriptors array.
3064     Handle<Map> map = handle(function->map());
3065     Handle<Map> new_map = Map::CopyReplaceDescriptor(
3066         map, instance_desc, &new_desc, index, OMIT_TRANSITION);
3067
3068     JSObject::MigrateToMap(function, new_map);
3069   } else {  // Dictionary properties.
3070     // Directly manipulate the property details.
3071     DisallowHeapAllocation no_gc;
3072     int entry = function->property_dictionary()->FindEntry(name);
3073     ASSERT(entry != NameDictionary::kNotFound);
3074     PropertyDetails details = function->property_dictionary()->DetailsAt(entry);
3075     PropertyDetails new_details(
3076         static_cast<PropertyAttributes>(details.attributes() | READ_ONLY),
3077         details.type(),
3078         details.dictionary_index());
3079     function->property_dictionary()->DetailsAtPut(entry, new_details);
3080   }
3081   return *function;
3082 }
3083
3084
3085 RUNTIME_FUNCTION(Runtime_FunctionIsAPIFunction) {
3086   SealHandleScope shs(isolate);
3087   ASSERT(args.length() == 1);
3088
3089   CONVERT_ARG_CHECKED(JSFunction, f, 0);
3090   return isolate->heap()->ToBoolean(f->shared()->IsApiFunction());
3091 }
3092
3093
3094 RUNTIME_FUNCTION(Runtime_FunctionIsBuiltin) {
3095   SealHandleScope shs(isolate);
3096   ASSERT(args.length() == 1);
3097
3098   CONVERT_ARG_CHECKED(JSFunction, f, 0);
3099   return isolate->heap()->ToBoolean(f->IsBuiltin());
3100 }
3101
3102
3103 RUNTIME_FUNCTION(Runtime_SetCode) {
3104   HandleScope scope(isolate);
3105   ASSERT(args.length() == 2);
3106
3107   CONVERT_ARG_HANDLE_CHECKED(JSFunction, target, 0);
3108   CONVERT_ARG_HANDLE_CHECKED(JSFunction, source, 1);
3109
3110   Handle<SharedFunctionInfo> target_shared(target->shared());
3111   Handle<SharedFunctionInfo> source_shared(source->shared());
3112   RUNTIME_ASSERT(!source_shared->bound());
3113
3114   if (!Compiler::EnsureCompiled(source, KEEP_EXCEPTION)) {
3115     return isolate->heap()->exception();
3116   }
3117
3118   // Mark both, the source and the target, as un-flushable because the
3119   // shared unoptimized code makes them impossible to enqueue in a list.
3120   ASSERT(target_shared->code()->gc_metadata() == NULL);
3121   ASSERT(source_shared->code()->gc_metadata() == NULL);
3122   target_shared->set_dont_flush(true);
3123   source_shared->set_dont_flush(true);
3124
3125   // Set the code, scope info, formal parameter count, and the length
3126   // of the target shared function info.
3127   target_shared->ReplaceCode(source_shared->code());
3128   target_shared->set_scope_info(source_shared->scope_info());
3129   target_shared->set_length(source_shared->length());
3130   target_shared->set_feedback_vector(source_shared->feedback_vector());
3131   target_shared->set_formal_parameter_count(
3132       source_shared->formal_parameter_count());
3133   target_shared->set_script(source_shared->script());
3134   target_shared->set_start_position_and_type(
3135       source_shared->start_position_and_type());
3136   target_shared->set_end_position(source_shared->end_position());
3137   bool was_native = target_shared->native();
3138   target_shared->set_compiler_hints(source_shared->compiler_hints());
3139   target_shared->set_native(was_native);
3140   target_shared->set_profiler_ticks(source_shared->profiler_ticks());
3141
3142   // Set the code of the target function.
3143   target->ReplaceCode(source_shared->code());
3144   ASSERT(target->next_function_link()->IsUndefined());
3145
3146   // Make sure we get a fresh copy of the literal vector to avoid cross
3147   // context contamination.
3148   Handle<Context> context(source->context());
3149   int number_of_literals = source->NumberOfLiterals();
3150   Handle<FixedArray> literals =
3151       isolate->factory()->NewFixedArray(number_of_literals, TENURED);
3152   if (number_of_literals > 0) {
3153     literals->set(JSFunction::kLiteralNativeContextIndex,
3154                   context->native_context());
3155   }
3156   target->set_context(*context);
3157   target->set_literals(*literals);
3158
3159   if (isolate->logger()->is_logging_code_events() ||
3160       isolate->cpu_profiler()->is_profiling()) {
3161     isolate->logger()->LogExistingFunction(
3162         source_shared, Handle<Code>(source_shared->code()));
3163   }
3164
3165   return *target;
3166 }
3167
3168
3169 RUNTIME_FUNCTION(Runtime_SetExpectedNumberOfProperties) {
3170   HandleScope scope(isolate);
3171   ASSERT(args.length() == 2);
3172   CONVERT_ARG_HANDLE_CHECKED(JSFunction, func, 0);
3173   CONVERT_SMI_ARG_CHECKED(num, 1);
3174   RUNTIME_ASSERT(num >= 0);
3175   // If objects constructed from this function exist then changing
3176   // 'estimated_nof_properties' is dangerous since the previous value might
3177   // have been compiled into the fast construct stub. Moreover, the inobject
3178   // slack tracking logic might have adjusted the previous value, so even
3179   // passing the same value is risky.
3180   if (!func->shared()->live_objects_may_exist()) {
3181     func->shared()->set_expected_nof_properties(num);
3182     if (func->has_initial_map()) {
3183       Handle<Map> new_initial_map = Map::Copy(handle(func->initial_map()));
3184       new_initial_map->set_unused_property_fields(num);
3185       func->set_initial_map(*new_initial_map);
3186     }
3187   }
3188   return isolate->heap()->undefined_value();
3189 }
3190
3191
3192 RUNTIME_FUNCTION(RuntimeHidden_CreateJSGeneratorObject) {
3193   HandleScope scope(isolate);
3194   ASSERT(args.length() == 0);
3195
3196   JavaScriptFrameIterator it(isolate);
3197   JavaScriptFrame* frame = it.frame();
3198   Handle<JSFunction> function(frame->function());
3199   RUNTIME_ASSERT(function->shared()->is_generator());
3200
3201   Handle<JSGeneratorObject> generator;
3202   if (frame->IsConstructor()) {
3203     generator = handle(JSGeneratorObject::cast(frame->receiver()));
3204   } else {
3205     generator = isolate->factory()->NewJSGeneratorObject(function);
3206   }
3207   generator->set_function(*function);
3208   generator->set_context(Context::cast(frame->context()));
3209   generator->set_receiver(frame->receiver());
3210   generator->set_continuation(0);
3211   generator->set_operand_stack(isolate->heap()->empty_fixed_array());
3212   generator->set_stack_handler_index(-1);
3213
3214   return *generator;
3215 }
3216
3217
3218 RUNTIME_FUNCTION(RuntimeHidden_SuspendJSGeneratorObject) {
3219   HandleScope handle_scope(isolate);
3220   ASSERT(args.length() == 1);
3221   CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator_object, 0);
3222
3223   JavaScriptFrameIterator stack_iterator(isolate);
3224   JavaScriptFrame* frame = stack_iterator.frame();
3225   RUNTIME_ASSERT(frame->function()->shared()->is_generator());
3226   ASSERT_EQ(frame->function(), generator_object->function());
3227
3228   // The caller should have saved the context and continuation already.
3229   ASSERT_EQ(generator_object->context(), Context::cast(frame->context()));
3230   ASSERT_LT(0, generator_object->continuation());
3231
3232   // We expect there to be at least two values on the operand stack: the return
3233   // value of the yield expression, and the argument to this runtime call.
3234   // Neither of those should be saved.
3235   int operands_count = frame->ComputeOperandsCount();
3236   ASSERT_GE(operands_count, 2);
3237   operands_count -= 2;
3238
3239   if (operands_count == 0) {
3240     // Although it's semantically harmless to call this function with an
3241     // operands_count of zero, it is also unnecessary.
3242     ASSERT_EQ(generator_object->operand_stack(),
3243               isolate->heap()->empty_fixed_array());
3244     ASSERT_EQ(generator_object->stack_handler_index(), -1);
3245     // If there are no operands on the stack, there shouldn't be a handler
3246     // active either.
3247     ASSERT(!frame->HasHandler());
3248   } else {
3249     int stack_handler_index = -1;
3250     Handle<FixedArray> operand_stack =
3251         isolate->factory()->NewFixedArray(operands_count);
3252     frame->SaveOperandStack(*operand_stack, &stack_handler_index);
3253     generator_object->set_operand_stack(*operand_stack);
3254     generator_object->set_stack_handler_index(stack_handler_index);
3255   }
3256
3257   return isolate->heap()->undefined_value();
3258 }
3259
3260
3261 // Note that this function is the slow path for resuming generators.  It is only
3262 // called if the suspended activation had operands on the stack, stack handlers
3263 // needing rewinding, or if the resume should throw an exception.  The fast path
3264 // is handled directly in FullCodeGenerator::EmitGeneratorResume(), which is
3265 // inlined into GeneratorNext and GeneratorThrow.  EmitGeneratorResumeResume is
3266 // called in any case, as it needs to reconstruct the stack frame and make space
3267 // for arguments and operands.
3268 RUNTIME_FUNCTION(RuntimeHidden_ResumeJSGeneratorObject) {
3269   SealHandleScope shs(isolate);
3270   ASSERT(args.length() == 3);
3271   CONVERT_ARG_CHECKED(JSGeneratorObject, generator_object, 0);
3272   CONVERT_ARG_CHECKED(Object, value, 1);
3273   CONVERT_SMI_ARG_CHECKED(resume_mode_int, 2);
3274   JavaScriptFrameIterator stack_iterator(isolate);
3275   JavaScriptFrame* frame = stack_iterator.frame();
3276
3277   ASSERT_EQ(frame->function(), generator_object->function());
3278   ASSERT(frame->function()->is_compiled());
3279
3280   STATIC_ASSERT(JSGeneratorObject::kGeneratorExecuting < 0);
3281   STATIC_ASSERT(JSGeneratorObject::kGeneratorClosed == 0);
3282
3283   Address pc = generator_object->function()->code()->instruction_start();
3284   int offset = generator_object->continuation();
3285   ASSERT(offset > 0);
3286   frame->set_pc(pc + offset);
3287   if (FLAG_enable_ool_constant_pool) {
3288     frame->set_constant_pool(
3289         generator_object->function()->code()->constant_pool());
3290   }
3291   generator_object->set_continuation(JSGeneratorObject::kGeneratorExecuting);
3292
3293   FixedArray* operand_stack = generator_object->operand_stack();
3294   int operands_count = operand_stack->length();
3295   if (operands_count != 0) {
3296     frame->RestoreOperandStack(operand_stack,
3297                                generator_object->stack_handler_index());
3298     generator_object->set_operand_stack(isolate->heap()->empty_fixed_array());
3299     generator_object->set_stack_handler_index(-1);
3300   }
3301
3302   JSGeneratorObject::ResumeMode resume_mode =
3303       static_cast<JSGeneratorObject::ResumeMode>(resume_mode_int);
3304   switch (resume_mode) {
3305     case JSGeneratorObject::NEXT:
3306       return value;
3307     case JSGeneratorObject::THROW:
3308       return isolate->Throw(value);
3309   }
3310
3311   UNREACHABLE();
3312   return isolate->ThrowIllegalOperation();
3313 }
3314
3315
3316 RUNTIME_FUNCTION(RuntimeHidden_ThrowGeneratorStateError) {
3317   HandleScope scope(isolate);
3318   ASSERT(args.length() == 1);
3319   CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0);
3320   int continuation = generator->continuation();
3321   const char* message = continuation == JSGeneratorObject::kGeneratorClosed ?
3322       "generator_finished" : "generator_running";
3323   Vector< Handle<Object> > argv = HandleVector<Object>(NULL, 0);
3324   Handle<Object> error = isolate->factory()->NewError(message, argv);
3325   return isolate->Throw(*error);
3326 }
3327
3328
3329 RUNTIME_FUNCTION(Runtime_ObjectFreeze) {
3330   HandleScope scope(isolate);
3331   ASSERT(args.length() == 1);
3332   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
3333   Handle<Object> result;
3334   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, JSObject::Freeze(object));
3335   return *result;
3336 }
3337
3338
3339 RUNTIME_FUNCTION(RuntimeHidden_StringCharCodeAt) {
3340   HandleScope handle_scope(isolate);
3341   ASSERT(args.length() == 2);
3342
3343   CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
3344   CONVERT_NUMBER_CHECKED(uint32_t, i, Uint32, args[1]);
3345
3346   // Flatten the string.  If someone wants to get a char at an index
3347   // in a cons string, it is likely that more indices will be
3348   // accessed.
3349   subject = String::Flatten(subject);
3350
3351   if (i >= static_cast<uint32_t>(subject->length())) {
3352     return isolate->heap()->nan_value();
3353   }
3354
3355   return Smi::FromInt(subject->Get(i));
3356 }
3357
3358
3359 RUNTIME_FUNCTION(Runtime_CharFromCode) {
3360   HandleScope handlescope(isolate);
3361   ASSERT(args.length() == 1);
3362   if (args[0]->IsNumber()) {
3363     CONVERT_NUMBER_CHECKED(uint32_t, code, Uint32, args[0]);
3364     code &= 0xffff;
3365     return *isolate->factory()->LookupSingleCharacterStringFromCode(code);
3366   }
3367   return isolate->heap()->empty_string();
3368 }
3369
3370
3371 class FixedArrayBuilder {
3372  public:
3373   explicit FixedArrayBuilder(Isolate* isolate, int initial_capacity)
3374       : array_(isolate->factory()->NewFixedArrayWithHoles(initial_capacity)),
3375         length_(0),
3376         has_non_smi_elements_(false) {
3377     // Require a non-zero initial size. Ensures that doubling the size to
3378     // extend the array will work.
3379     ASSERT(initial_capacity > 0);
3380   }
3381
3382   explicit FixedArrayBuilder(Handle<FixedArray> backing_store)
3383       : array_(backing_store),
3384         length_(0),
3385         has_non_smi_elements_(false) {
3386     // Require a non-zero initial size. Ensures that doubling the size to
3387     // extend the array will work.
3388     ASSERT(backing_store->length() > 0);
3389   }
3390
3391   bool HasCapacity(int elements) {
3392     int length = array_->length();
3393     int required_length = length_ + elements;
3394     return (length >= required_length);
3395   }
3396
3397   void EnsureCapacity(int elements) {
3398     int length = array_->length();
3399     int required_length = length_ + elements;
3400     if (length < required_length) {
3401       int new_length = length;
3402       do {
3403         new_length *= 2;
3404       } while (new_length < required_length);
3405       Handle<FixedArray> extended_array =
3406           array_->GetIsolate()->factory()->NewFixedArrayWithHoles(new_length);
3407       array_->CopyTo(0, *extended_array, 0, length_);
3408       array_ = extended_array;
3409     }
3410   }
3411
3412   void Add(Object* value) {
3413     ASSERT(!value->IsSmi());
3414     ASSERT(length_ < capacity());
3415     array_->set(length_, value);
3416     length_++;
3417     has_non_smi_elements_ = true;
3418   }
3419
3420   void Add(Smi* value) {
3421     ASSERT(value->IsSmi());
3422     ASSERT(length_ < capacity());
3423     array_->set(length_, value);
3424     length_++;
3425   }
3426
3427   Handle<FixedArray> array() {
3428     return array_;
3429   }
3430
3431   int length() {
3432     return length_;
3433   }
3434
3435   int capacity() {
3436     return array_->length();
3437   }
3438
3439   Handle<JSArray> ToJSArray(Handle<JSArray> target_array) {
3440     JSArray::SetContent(target_array, array_);
3441     target_array->set_length(Smi::FromInt(length_));
3442     return target_array;
3443   }
3444
3445
3446  private:
3447   Handle<FixedArray> array_;
3448   int length_;
3449   bool has_non_smi_elements_;
3450 };
3451
3452
3453 // Forward declarations.
3454 const int kStringBuilderConcatHelperLengthBits = 11;
3455 const int kStringBuilderConcatHelperPositionBits = 19;
3456
3457 template <typename schar>
3458 static inline void StringBuilderConcatHelper(String*,
3459                                              schar*,
3460                                              FixedArray*,
3461                                              int);
3462
3463 typedef BitField<int, 0, kStringBuilderConcatHelperLengthBits>
3464     StringBuilderSubstringLength;
3465 typedef BitField<int,
3466                  kStringBuilderConcatHelperLengthBits,
3467                  kStringBuilderConcatHelperPositionBits>
3468     StringBuilderSubstringPosition;
3469
3470
3471 class ReplacementStringBuilder {
3472  public:
3473   ReplacementStringBuilder(Heap* heap,
3474                            Handle<String> subject,
3475                            int estimated_part_count)
3476       : heap_(heap),
3477         array_builder_(heap->isolate(), estimated_part_count),
3478         subject_(subject),
3479         character_count_(0),
3480         is_ascii_(subject->IsOneByteRepresentation()) {
3481     // Require a non-zero initial size. Ensures that doubling the size to
3482     // extend the array will work.
3483     ASSERT(estimated_part_count > 0);
3484   }
3485
3486   static inline void AddSubjectSlice(FixedArrayBuilder* builder,
3487                                      int from,
3488                                      int to) {
3489     ASSERT(from >= 0);
3490     int length = to - from;
3491     ASSERT(length > 0);
3492     if (StringBuilderSubstringLength::is_valid(length) &&
3493         StringBuilderSubstringPosition::is_valid(from)) {
3494       int encoded_slice = StringBuilderSubstringLength::encode(length) |
3495           StringBuilderSubstringPosition::encode(from);
3496       builder->Add(Smi::FromInt(encoded_slice));
3497     } else {
3498       // Otherwise encode as two smis.
3499       builder->Add(Smi::FromInt(-length));
3500       builder->Add(Smi::FromInt(from));
3501     }
3502   }
3503
3504
3505   void EnsureCapacity(int elements) {
3506     array_builder_.EnsureCapacity(elements);
3507   }
3508
3509
3510   void AddSubjectSlice(int from, int to) {
3511     AddSubjectSlice(&array_builder_, from, to);
3512     IncrementCharacterCount(to - from);
3513   }
3514
3515
3516   void AddString(Handle<String> string) {
3517     int length = string->length();
3518     ASSERT(length > 0);
3519     AddElement(*string);
3520     if (!string->IsOneByteRepresentation()) {
3521       is_ascii_ = false;
3522     }
3523     IncrementCharacterCount(length);
3524   }
3525
3526
3527   MaybeHandle<String> ToString() {
3528     Isolate* isolate = heap_->isolate();
3529     if (array_builder_.length() == 0) {
3530       return isolate->factory()->empty_string();
3531     }
3532
3533     Handle<String> joined_string;
3534     if (is_ascii_) {
3535       Handle<SeqOneByteString> seq;
3536       ASSIGN_RETURN_ON_EXCEPTION(
3537           isolate, seq,
3538           isolate->factory()->NewRawOneByteString(character_count_),
3539           String);
3540
3541       DisallowHeapAllocation no_gc;
3542       uint8_t* char_buffer = seq->GetChars();
3543       StringBuilderConcatHelper(*subject_,
3544                                 char_buffer,
3545                                 *array_builder_.array(),
3546                                 array_builder_.length());
3547       joined_string = Handle<String>::cast(seq);
3548     } else {
3549       // Non-ASCII.
3550       Handle<SeqTwoByteString> seq;
3551       ASSIGN_RETURN_ON_EXCEPTION(
3552           isolate, seq,
3553           isolate->factory()->NewRawTwoByteString(character_count_),
3554           String);
3555
3556       DisallowHeapAllocation no_gc;
3557       uc16* char_buffer = seq->GetChars();
3558       StringBuilderConcatHelper(*subject_,
3559                                 char_buffer,
3560                                 *array_builder_.array(),
3561                                 array_builder_.length());
3562       joined_string = Handle<String>::cast(seq);
3563     }
3564     return joined_string;
3565   }
3566
3567
3568   void IncrementCharacterCount(int by) {
3569     if (character_count_ > String::kMaxLength - by) {
3570       STATIC_ASSERT(String::kMaxLength < kMaxInt);
3571       character_count_ = kMaxInt;
3572     } else {
3573       character_count_ += by;
3574     }
3575   }
3576
3577  private:
3578   void AddElement(Object* element) {
3579     ASSERT(element->IsSmi() || element->IsString());
3580     ASSERT(array_builder_.capacity() > array_builder_.length());
3581     array_builder_.Add(element);
3582   }
3583
3584   Heap* heap_;
3585   FixedArrayBuilder array_builder_;
3586   Handle<String> subject_;
3587   int character_count_;
3588   bool is_ascii_;
3589 };
3590
3591
3592 class CompiledReplacement {
3593  public:
3594   explicit CompiledReplacement(Zone* zone)
3595       : parts_(1, zone), replacement_substrings_(0, zone), zone_(zone) {}
3596
3597   // Return whether the replacement is simple.
3598   bool Compile(Handle<String> replacement,
3599                int capture_count,
3600                int subject_length);
3601
3602   // Use Apply only if Compile returned false.
3603   void Apply(ReplacementStringBuilder* builder,
3604              int match_from,
3605              int match_to,
3606              int32_t* match);
3607
3608   // Number of distinct parts of the replacement pattern.
3609   int parts() {
3610     return parts_.length();
3611   }
3612
3613   Zone* zone() const { return zone_; }
3614
3615  private:
3616   enum PartType {
3617     SUBJECT_PREFIX = 1,
3618     SUBJECT_SUFFIX,
3619     SUBJECT_CAPTURE,
3620     REPLACEMENT_SUBSTRING,
3621     REPLACEMENT_STRING,
3622
3623     NUMBER_OF_PART_TYPES
3624   };
3625
3626   struct ReplacementPart {
3627     static inline ReplacementPart SubjectMatch() {
3628       return ReplacementPart(SUBJECT_CAPTURE, 0);
3629     }
3630     static inline ReplacementPart SubjectCapture(int capture_index) {
3631       return ReplacementPart(SUBJECT_CAPTURE, capture_index);
3632     }
3633     static inline ReplacementPart SubjectPrefix() {
3634       return ReplacementPart(SUBJECT_PREFIX, 0);
3635     }
3636     static inline ReplacementPart SubjectSuffix(int subject_length) {
3637       return ReplacementPart(SUBJECT_SUFFIX, subject_length);
3638     }
3639     static inline ReplacementPart ReplacementString() {
3640       return ReplacementPart(REPLACEMENT_STRING, 0);
3641     }
3642     static inline ReplacementPart ReplacementSubString(int from, int to) {
3643       ASSERT(from >= 0);
3644       ASSERT(to > from);
3645       return ReplacementPart(-from, to);
3646     }
3647
3648     // If tag <= 0 then it is the negation of a start index of a substring of
3649     // the replacement pattern, otherwise it's a value from PartType.
3650     ReplacementPart(int tag, int data)
3651         : tag(tag), data(data) {
3652       // Must be non-positive or a PartType value.
3653       ASSERT(tag < NUMBER_OF_PART_TYPES);
3654     }
3655     // Either a value of PartType or a non-positive number that is
3656     // the negation of an index into the replacement string.
3657     int tag;
3658     // The data value's interpretation depends on the value of tag:
3659     // tag == SUBJECT_PREFIX ||
3660     // tag == SUBJECT_SUFFIX:  data is unused.
3661     // tag == SUBJECT_CAPTURE: data is the number of the capture.
3662     // tag == REPLACEMENT_SUBSTRING ||
3663     // tag == REPLACEMENT_STRING:    data is index into array of substrings
3664     //                               of the replacement string.
3665     // tag <= 0: Temporary representation of the substring of the replacement
3666     //           string ranging over -tag .. data.
3667     //           Is replaced by REPLACEMENT_{SUB,}STRING when we create the
3668     //           substring objects.
3669     int data;
3670   };
3671
3672   template<typename Char>
3673   bool ParseReplacementPattern(ZoneList<ReplacementPart>* parts,
3674                                Vector<Char> characters,
3675                                int capture_count,
3676                                int subject_length,
3677                                Zone* zone) {
3678     int length = characters.length();
3679     int last = 0;
3680     for (int i = 0; i < length; i++) {
3681       Char c = characters[i];
3682       if (c == '$') {
3683         int next_index = i + 1;
3684         if (next_index == length) {  // No next character!
3685           break;
3686         }
3687         Char c2 = characters[next_index];
3688         switch (c2) {
3689         case '$':
3690           if (i > last) {
3691             // There is a substring before. Include the first "$".
3692             parts->Add(ReplacementPart::ReplacementSubString(last, next_index),
3693                        zone);
3694             last = next_index + 1;  // Continue after the second "$".
3695           } else {
3696             // Let the next substring start with the second "$".
3697             last = next_index;
3698           }
3699           i = next_index;
3700           break;
3701         case '`':
3702           if (i > last) {
3703             parts->Add(ReplacementPart::ReplacementSubString(last, i), zone);
3704           }
3705           parts->Add(ReplacementPart::SubjectPrefix(), zone);
3706           i = next_index;
3707           last = i + 1;
3708           break;
3709         case '\'':
3710           if (i > last) {
3711             parts->Add(ReplacementPart::ReplacementSubString(last, i), zone);
3712           }
3713           parts->Add(ReplacementPart::SubjectSuffix(subject_length), zone);
3714           i = next_index;
3715           last = i + 1;
3716           break;
3717         case '&':
3718           if (i > last) {
3719             parts->Add(ReplacementPart::ReplacementSubString(last, i), zone);
3720           }
3721           parts->Add(ReplacementPart::SubjectMatch(), zone);
3722           i = next_index;
3723           last = i + 1;
3724           break;
3725         case '0':
3726         case '1':
3727         case '2':
3728         case '3':
3729         case '4':
3730         case '5':
3731         case '6':
3732         case '7':
3733         case '8':
3734         case '9': {
3735           int capture_ref = c2 - '0';
3736           if (capture_ref > capture_count) {
3737             i = next_index;
3738             continue;
3739           }
3740           int second_digit_index = next_index + 1;
3741           if (second_digit_index < length) {
3742             // Peek ahead to see if we have two digits.
3743             Char c3 = characters[second_digit_index];
3744             if ('0' <= c3 && c3 <= '9') {  // Double digits.
3745               int double_digit_ref = capture_ref * 10 + c3 - '0';
3746               if (double_digit_ref <= capture_count) {
3747                 next_index = second_digit_index;
3748                 capture_ref = double_digit_ref;
3749               }
3750             }
3751           }
3752           if (capture_ref > 0) {
3753             if (i > last) {
3754               parts->Add(ReplacementPart::ReplacementSubString(last, i), zone);
3755             }
3756             ASSERT(capture_ref <= capture_count);
3757             parts->Add(ReplacementPart::SubjectCapture(capture_ref), zone);
3758             last = next_index + 1;
3759           }
3760           i = next_index;
3761           break;
3762         }
3763         default:
3764           i = next_index;
3765           break;
3766         }
3767       }
3768     }
3769     if (length > last) {
3770       if (last == 0) {
3771         // Replacement is simple.  Do not use Apply to do the replacement.
3772         return true;
3773       } else {
3774         parts->Add(ReplacementPart::ReplacementSubString(last, length), zone);
3775       }
3776     }
3777     return false;
3778   }
3779
3780   ZoneList<ReplacementPart> parts_;
3781   ZoneList<Handle<String> > replacement_substrings_;
3782   Zone* zone_;
3783 };
3784
3785
3786 bool CompiledReplacement::Compile(Handle<String> replacement,
3787                                   int capture_count,
3788                                   int subject_length) {
3789   {
3790     DisallowHeapAllocation no_gc;
3791     String::FlatContent content = replacement->GetFlatContent();
3792     ASSERT(content.IsFlat());
3793     bool simple = false;
3794     if (content.IsAscii()) {
3795       simple = ParseReplacementPattern(&parts_,
3796                                        content.ToOneByteVector(),
3797                                        capture_count,
3798                                        subject_length,
3799                                        zone());
3800     } else {
3801       ASSERT(content.IsTwoByte());
3802       simple = ParseReplacementPattern(&parts_,
3803                                        content.ToUC16Vector(),
3804                                        capture_count,
3805                                        subject_length,
3806                                        zone());
3807     }
3808     if (simple) return true;
3809   }
3810
3811   Isolate* isolate = replacement->GetIsolate();
3812   // Find substrings of replacement string and create them as String objects.
3813   int substring_index = 0;
3814   for (int i = 0, n = parts_.length(); i < n; i++) {
3815     int tag = parts_[i].tag;
3816     if (tag <= 0) {  // A replacement string slice.
3817       int from = -tag;
3818       int to = parts_[i].data;
3819       replacement_substrings_.Add(
3820           isolate->factory()->NewSubString(replacement, from, to), zone());
3821       parts_[i].tag = REPLACEMENT_SUBSTRING;
3822       parts_[i].data = substring_index;
3823       substring_index++;
3824     } else if (tag == REPLACEMENT_STRING) {
3825       replacement_substrings_.Add(replacement, zone());
3826       parts_[i].data = substring_index;
3827       substring_index++;
3828     }
3829   }
3830   return false;
3831 }
3832
3833
3834 void CompiledReplacement::Apply(ReplacementStringBuilder* builder,
3835                                 int match_from,
3836                                 int match_to,
3837                                 int32_t* match) {
3838   ASSERT_LT(0, parts_.length());
3839   for (int i = 0, n = parts_.length(); i < n; i++) {
3840     ReplacementPart part = parts_[i];
3841     switch (part.tag) {
3842       case SUBJECT_PREFIX:
3843         if (match_from > 0) builder->AddSubjectSlice(0, match_from);
3844         break;
3845       case SUBJECT_SUFFIX: {
3846         int subject_length = part.data;
3847         if (match_to < subject_length) {
3848           builder->AddSubjectSlice(match_to, subject_length);
3849         }
3850         break;
3851       }
3852       case SUBJECT_CAPTURE: {
3853         int capture = part.data;
3854         int from = match[capture * 2];
3855         int to = match[capture * 2 + 1];
3856         if (from >= 0 && to > from) {
3857           builder->AddSubjectSlice(from, to);
3858         }
3859         break;
3860       }
3861       case REPLACEMENT_SUBSTRING:
3862       case REPLACEMENT_STRING:
3863         builder->AddString(replacement_substrings_[part.data]);
3864         break;
3865       default:
3866         UNREACHABLE();
3867     }
3868   }
3869 }
3870
3871
3872 void FindAsciiStringIndices(Vector<const uint8_t> subject,
3873                             char pattern,
3874                             ZoneList<int>* indices,
3875                             unsigned int limit,
3876                             Zone* zone) {
3877   ASSERT(limit > 0);
3878   // Collect indices of pattern in subject using memchr.
3879   // Stop after finding at most limit values.
3880   const uint8_t* subject_start = subject.start();
3881   const uint8_t* subject_end = subject_start + subject.length();
3882   const uint8_t* pos = subject_start;
3883   while (limit > 0) {
3884     pos = reinterpret_cast<const uint8_t*>(
3885         memchr(pos, pattern, subject_end - pos));
3886     if (pos == NULL) return;
3887     indices->Add(static_cast<int>(pos - subject_start), zone);
3888     pos++;
3889     limit--;
3890   }
3891 }
3892
3893
3894 void FindTwoByteStringIndices(const Vector<const uc16> subject,
3895                               uc16 pattern,
3896                               ZoneList<int>* indices,
3897                               unsigned int limit,
3898                               Zone* zone) {
3899   ASSERT(limit > 0);
3900   const uc16* subject_start = subject.start();
3901   const uc16* subject_end = subject_start + subject.length();
3902   for (const uc16* pos = subject_start; pos < subject_end && limit > 0; pos++) {
3903     if (*pos == pattern) {
3904       indices->Add(static_cast<int>(pos - subject_start), zone);
3905       limit--;
3906     }
3907   }
3908 }
3909
3910
3911 template <typename SubjectChar, typename PatternChar>
3912 void FindStringIndices(Isolate* isolate,
3913                        Vector<const SubjectChar> subject,
3914                        Vector<const PatternChar> pattern,
3915                        ZoneList<int>* indices,
3916                        unsigned int limit,
3917                        Zone* zone) {
3918   ASSERT(limit > 0);
3919   // Collect indices of pattern in subject.
3920   // Stop after finding at most limit values.
3921   int pattern_length = pattern.length();
3922   int index = 0;
3923   StringSearch<PatternChar, SubjectChar> search(isolate, pattern);
3924   while (limit > 0) {
3925     index = search.Search(subject, index);
3926     if (index < 0) return;
3927     indices->Add(index, zone);
3928     index += pattern_length;
3929     limit--;
3930   }
3931 }
3932
3933
3934 void FindStringIndicesDispatch(Isolate* isolate,
3935                                String* subject,
3936                                String* pattern,
3937                                ZoneList<int>* indices,
3938                                unsigned int limit,
3939                                Zone* zone) {
3940   {
3941     DisallowHeapAllocation no_gc;
3942     String::FlatContent subject_content = subject->GetFlatContent();
3943     String::FlatContent pattern_content = pattern->GetFlatContent();
3944     ASSERT(subject_content.IsFlat());
3945     ASSERT(pattern_content.IsFlat());
3946     if (subject_content.IsAscii()) {
3947       Vector<const uint8_t> subject_vector = subject_content.ToOneByteVector();
3948       if (pattern_content.IsAscii()) {
3949         Vector<const uint8_t> pattern_vector =
3950             pattern_content.ToOneByteVector();
3951         if (pattern_vector.length() == 1) {
3952           FindAsciiStringIndices(subject_vector,
3953                                  pattern_vector[0],
3954                                  indices,
3955                                  limit,
3956                                  zone);
3957         } else {
3958           FindStringIndices(isolate,
3959                             subject_vector,
3960                             pattern_vector,
3961                             indices,
3962                             limit,
3963                             zone);
3964         }
3965       } else {
3966         FindStringIndices(isolate,
3967                           subject_vector,
3968                           pattern_content.ToUC16Vector(),
3969                           indices,
3970                           limit,
3971                           zone);
3972       }
3973     } else {
3974       Vector<const uc16> subject_vector = subject_content.ToUC16Vector();
3975       if (pattern_content.IsAscii()) {
3976         Vector<const uint8_t> pattern_vector =
3977             pattern_content.ToOneByteVector();
3978         if (pattern_vector.length() == 1) {
3979           FindTwoByteStringIndices(subject_vector,
3980                                    pattern_vector[0],
3981                                    indices,
3982                                    limit,
3983                                    zone);
3984         } else {
3985           FindStringIndices(isolate,
3986                             subject_vector,
3987                             pattern_vector,
3988                             indices,
3989                             limit,
3990                             zone);
3991         }
3992       } else {
3993         Vector<const uc16> pattern_vector = pattern_content.ToUC16Vector();
3994         if (pattern_vector.length() == 1) {
3995           FindTwoByteStringIndices(subject_vector,
3996                                    pattern_vector[0],
3997                                    indices,
3998                                    limit,
3999                                    zone);
4000         } else {
4001           FindStringIndices(isolate,
4002                             subject_vector,
4003                             pattern_vector,
4004                             indices,
4005                             limit,
4006                             zone);
4007         }
4008       }
4009     }
4010   }
4011 }
4012
4013
4014 template<typename ResultSeqString>
4015 MUST_USE_RESULT static Object* StringReplaceGlobalAtomRegExpWithString(
4016     Isolate* isolate,
4017     Handle<String> subject,
4018     Handle<JSRegExp> pattern_regexp,
4019     Handle<String> replacement,
4020     Handle<JSArray> last_match_info) {
4021   ASSERT(subject->IsFlat());
4022   ASSERT(replacement->IsFlat());
4023
4024   ZoneScope zone_scope(isolate->runtime_zone());
4025   ZoneList<int> indices(8, zone_scope.zone());
4026   ASSERT_EQ(JSRegExp::ATOM, pattern_regexp->TypeTag());
4027   String* pattern =
4028       String::cast(pattern_regexp->DataAt(JSRegExp::kAtomPatternIndex));
4029   int subject_len = subject->length();
4030   int pattern_len = pattern->length();
4031   int replacement_len = replacement->length();
4032
4033   FindStringIndicesDispatch(
4034       isolate, *subject, pattern, &indices, 0xffffffff, zone_scope.zone());
4035
4036   int matches = indices.length();
4037   if (matches == 0) return *subject;
4038
4039   // Detect integer overflow.
4040   int64_t result_len_64 =
4041       (static_cast<int64_t>(replacement_len) -
4042        static_cast<int64_t>(pattern_len)) *
4043       static_cast<int64_t>(matches) +
4044       static_cast<int64_t>(subject_len);
4045   int result_len;
4046   if (result_len_64 > static_cast<int64_t>(String::kMaxLength)) {
4047     STATIC_ASSERT(String::kMaxLength < kMaxInt);
4048     result_len = kMaxInt;  // Provoke exception.
4049   } else {
4050     result_len = static_cast<int>(result_len_64);
4051   }
4052
4053   int subject_pos = 0;
4054   int result_pos = 0;
4055
4056   MaybeHandle<SeqString> maybe_res;
4057   if (ResultSeqString::kHasAsciiEncoding) {
4058     maybe_res = isolate->factory()->NewRawOneByteString(result_len);
4059   } else {
4060     maybe_res = isolate->factory()->NewRawTwoByteString(result_len);
4061   }
4062   Handle<SeqString> untyped_res;
4063   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, untyped_res, maybe_res);
4064   Handle<ResultSeqString> result = Handle<ResultSeqString>::cast(untyped_res);
4065
4066   for (int i = 0; i < matches; i++) {
4067     // Copy non-matched subject content.
4068     if (subject_pos < indices.at(i)) {
4069       String::WriteToFlat(*subject,
4070                           result->GetChars() + result_pos,
4071                           subject_pos,
4072                           indices.at(i));
4073       result_pos += indices.at(i) - subject_pos;
4074     }
4075
4076     // Replace match.
4077     if (replacement_len > 0) {
4078       String::WriteToFlat(*replacement,
4079                           result->GetChars() + result_pos,
4080                           0,
4081                           replacement_len);
4082       result_pos += replacement_len;
4083     }
4084
4085     subject_pos = indices.at(i) + pattern_len;
4086   }
4087   // Add remaining subject content at the end.
4088   if (subject_pos < subject_len) {
4089     String::WriteToFlat(*subject,
4090                         result->GetChars() + result_pos,
4091                         subject_pos,
4092                         subject_len);
4093   }
4094
4095   int32_t match_indices[] = { indices.at(matches - 1),
4096                               indices.at(matches - 1) + pattern_len };
4097   RegExpImpl::SetLastMatchInfo(last_match_info, subject, 0, match_indices);
4098
4099   return *result;
4100 }
4101
4102
4103 MUST_USE_RESULT static Object* StringReplaceGlobalRegExpWithString(
4104     Isolate* isolate,
4105     Handle<String> subject,
4106     Handle<JSRegExp> regexp,
4107     Handle<String> replacement,
4108     Handle<JSArray> last_match_info) {
4109   ASSERT(subject->IsFlat());
4110   ASSERT(replacement->IsFlat());
4111
4112   int capture_count = regexp->CaptureCount();
4113   int subject_length = subject->length();
4114
4115   // CompiledReplacement uses zone allocation.
4116   ZoneScope zone_scope(isolate->runtime_zone());
4117   CompiledReplacement compiled_replacement(zone_scope.zone());
4118   bool simple_replace = compiled_replacement.Compile(replacement,
4119                                                      capture_count,
4120                                                      subject_length);
4121
4122   // Shortcut for simple non-regexp global replacements
4123   if (regexp->TypeTag() == JSRegExp::ATOM && simple_replace) {
4124     if (subject->HasOnlyOneByteChars() &&
4125         replacement->HasOnlyOneByteChars()) {
4126       return StringReplaceGlobalAtomRegExpWithString<SeqOneByteString>(
4127           isolate, subject, regexp, replacement, last_match_info);
4128     } else {
4129       return StringReplaceGlobalAtomRegExpWithString<SeqTwoByteString>(
4130           isolate, subject, regexp, replacement, last_match_info);
4131     }
4132   }
4133
4134   RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate);
4135   if (global_cache.HasException()) return isolate->heap()->exception();
4136
4137   int32_t* current_match = global_cache.FetchNext();
4138   if (current_match == NULL) {
4139     if (global_cache.HasException()) return isolate->heap()->exception();
4140     return *subject;
4141   }
4142
4143   // Guessing the number of parts that the final result string is built
4144   // from. Global regexps can match any number of times, so we guess
4145   // conservatively.
4146   int expected_parts = (compiled_replacement.parts() + 1) * 4 + 1;
4147   ReplacementStringBuilder builder(isolate->heap(),
4148                                    subject,
4149                                    expected_parts);
4150
4151   // Number of parts added by compiled replacement plus preceeding
4152   // string and possibly suffix after last match.  It is possible for
4153   // all components to use two elements when encoded as two smis.
4154   const int parts_added_per_loop = 2 * (compiled_replacement.parts() + 2);
4155
4156   int prev = 0;
4157
4158   do {
4159     builder.EnsureCapacity(parts_added_per_loop);
4160
4161     int start = current_match[0];
4162     int end = current_match[1];
4163
4164     if (prev < start) {
4165       builder.AddSubjectSlice(prev, start);
4166     }
4167
4168     if (simple_replace) {
4169       builder.AddString(replacement);
4170     } else {
4171       compiled_replacement.Apply(&builder,
4172                                  start,
4173                                  end,
4174                                  current_match);
4175     }
4176     prev = end;
4177
4178     current_match = global_cache.FetchNext();
4179   } while (current_match != NULL);
4180
4181   if (global_cache.HasException()) return isolate->heap()->exception();
4182
4183   if (prev < subject_length) {
4184     builder.EnsureCapacity(2);
4185     builder.AddSubjectSlice(prev, subject_length);
4186   }
4187
4188   RegExpImpl::SetLastMatchInfo(last_match_info,
4189                                subject,
4190                                capture_count,
4191                                global_cache.LastSuccessfulMatch());
4192
4193   Handle<String> result;
4194   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, builder.ToString());
4195   return *result;
4196 }
4197
4198
4199 template <typename ResultSeqString>
4200 MUST_USE_RESULT static Object* StringReplaceGlobalRegExpWithEmptyString(
4201     Isolate* isolate,
4202     Handle<String> subject,
4203     Handle<JSRegExp> regexp,
4204     Handle<JSArray> last_match_info) {
4205   ASSERT(subject->IsFlat());
4206
4207   // Shortcut for simple non-regexp global replacements
4208   if (regexp->TypeTag() == JSRegExp::ATOM) {
4209     Handle<String> empty_string = isolate->factory()->empty_string();
4210     if (subject->IsOneByteRepresentation()) {
4211       return StringReplaceGlobalAtomRegExpWithString<SeqOneByteString>(
4212           isolate, subject, regexp, empty_string, last_match_info);
4213     } else {
4214       return StringReplaceGlobalAtomRegExpWithString<SeqTwoByteString>(
4215           isolate, subject, regexp, empty_string, last_match_info);
4216     }
4217   }
4218
4219   RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate);
4220   if (global_cache.HasException()) return isolate->heap()->exception();
4221
4222   int32_t* current_match = global_cache.FetchNext();
4223   if (current_match == NULL) {
4224     if (global_cache.HasException()) return isolate->heap()->exception();
4225     return *subject;
4226   }
4227
4228   int start = current_match[0];
4229   int end = current_match[1];
4230   int capture_count = regexp->CaptureCount();
4231   int subject_length = subject->length();
4232
4233   int new_length = subject_length - (end - start);
4234   if (new_length == 0) return isolate->heap()->empty_string();
4235
4236   Handle<ResultSeqString> answer;
4237   if (ResultSeqString::kHasAsciiEncoding) {
4238     answer = Handle<ResultSeqString>::cast(
4239         isolate->factory()->NewRawOneByteString(new_length).ToHandleChecked());
4240   } else {
4241     answer = Handle<ResultSeqString>::cast(
4242         isolate->factory()->NewRawTwoByteString(new_length).ToHandleChecked());
4243   }
4244
4245   int prev = 0;
4246   int position = 0;
4247
4248   do {
4249     start = current_match[0];
4250     end = current_match[1];
4251     if (prev < start) {
4252       // Add substring subject[prev;start] to answer string.
4253       String::WriteToFlat(*subject, answer->GetChars() + position, prev, start);
4254       position += start - prev;
4255     }
4256     prev = end;
4257
4258     current_match = global_cache.FetchNext();
4259   } while (current_match != NULL);
4260
4261   if (global_cache.HasException()) return isolate->heap()->exception();
4262
4263   RegExpImpl::SetLastMatchInfo(last_match_info,
4264                                subject,
4265                                capture_count,
4266                                global_cache.LastSuccessfulMatch());
4267
4268   if (prev < subject_length) {
4269     // Add substring subject[prev;length] to answer string.
4270     String::WriteToFlat(
4271         *subject, answer->GetChars() + position, prev, subject_length);
4272     position += subject_length - prev;
4273   }
4274
4275   if (position == 0) return isolate->heap()->empty_string();
4276
4277   // Shorten string and fill
4278   int string_size = ResultSeqString::SizeFor(position);
4279   int allocated_string_size = ResultSeqString::SizeFor(new_length);
4280   int delta = allocated_string_size - string_size;
4281
4282   answer->set_length(position);
4283   if (delta == 0) return *answer;
4284
4285   Address end_of_string = answer->address() + string_size;
4286   Heap* heap = isolate->heap();
4287
4288   // The trimming is performed on a newly allocated object, which is on a
4289   // fresly allocated page or on an already swept page. Hence, the sweeper
4290   // thread can not get confused with the filler creation. No synchronization
4291   // needed.
4292   heap->CreateFillerObjectAt(end_of_string, delta);
4293   heap->AdjustLiveBytes(answer->address(), -delta, Heap::FROM_MUTATOR);
4294   return *answer;
4295 }
4296
4297
4298 RUNTIME_FUNCTION(Runtime_StringReplaceGlobalRegExpWithString) {
4299   HandleScope scope(isolate);
4300   ASSERT(args.length() == 4);
4301
4302   CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
4303   CONVERT_ARG_HANDLE_CHECKED(String, replacement, 2);
4304   CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 1);
4305   CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 3);
4306
4307   RUNTIME_ASSERT(regexp->GetFlags().is_global());
4308
4309   subject = String::Flatten(subject);
4310
4311   if (replacement->length() == 0) {
4312     if (subject->HasOnlyOneByteChars()) {
4313       return StringReplaceGlobalRegExpWithEmptyString<SeqOneByteString>(
4314           isolate, subject, regexp, last_match_info);
4315     } else {
4316       return StringReplaceGlobalRegExpWithEmptyString<SeqTwoByteString>(
4317           isolate, subject, regexp, last_match_info);
4318     }
4319   }
4320
4321   replacement = String::Flatten(replacement);
4322
4323   return StringReplaceGlobalRegExpWithString(
4324       isolate, subject, regexp, replacement, last_match_info);
4325 }
4326
4327
4328 // This may return an empty MaybeHandle if an exception is thrown or
4329 // we abort due to reaching the recursion limit.
4330 MaybeHandle<String> StringReplaceOneCharWithString(Isolate* isolate,
4331                                                    Handle<String> subject,
4332                                                    Handle<String> search,
4333                                                    Handle<String> replace,
4334                                                    bool* found,
4335                                                    int recursion_limit) {
4336   if (recursion_limit == 0) return MaybeHandle<String>();
4337   recursion_limit--;
4338   if (subject->IsConsString()) {
4339     ConsString* cons = ConsString::cast(*subject);
4340     Handle<String> first = Handle<String>(cons->first());
4341     Handle<String> second = Handle<String>(cons->second());
4342     Handle<String> new_first;
4343     if (!StringReplaceOneCharWithString(
4344             isolate, first, search, replace, found, recursion_limit)
4345             .ToHandle(&new_first)) {
4346       return MaybeHandle<String>();
4347     }
4348     if (*found) return isolate->factory()->NewConsString(new_first, second);
4349
4350     Handle<String> new_second;
4351     if (!StringReplaceOneCharWithString(
4352             isolate, second, search, replace, found, recursion_limit)
4353             .ToHandle(&new_second)) {
4354       return MaybeHandle<String>();
4355     }
4356     if (*found) return isolate->factory()->NewConsString(first, new_second);
4357
4358     return subject;
4359   } else {
4360     int index = Runtime::StringMatch(isolate, subject, search, 0);
4361     if (index == -1) return subject;
4362     *found = true;
4363     Handle<String> first = isolate->factory()->NewSubString(subject, 0, index);
4364     Handle<String> cons1;
4365     ASSIGN_RETURN_ON_EXCEPTION(
4366         isolate, cons1,
4367         isolate->factory()->NewConsString(first, replace),
4368         String);
4369     Handle<String> second =
4370         isolate->factory()->NewSubString(subject, index + 1, subject->length());
4371     return isolate->factory()->NewConsString(cons1, second);
4372   }
4373 }
4374
4375
4376 RUNTIME_FUNCTION(Runtime_StringReplaceOneCharWithString) {
4377   HandleScope scope(isolate);
4378   ASSERT(args.length() == 3);
4379   CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
4380   CONVERT_ARG_HANDLE_CHECKED(String, search, 1);
4381   CONVERT_ARG_HANDLE_CHECKED(String, replace, 2);
4382
4383   // If the cons string tree is too deep, we simply abort the recursion and
4384   // retry with a flattened subject string.
4385   const int kRecursionLimit = 0x1000;
4386   bool found = false;
4387   Handle<String> result;
4388   if (StringReplaceOneCharWithString(
4389           isolate, subject, search, replace, &found, kRecursionLimit)
4390           .ToHandle(&result)) {
4391     return *result;
4392   }
4393   if (isolate->has_pending_exception()) return isolate->heap()->exception();
4394
4395   subject = String::Flatten(subject);
4396   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
4397       isolate, result,
4398       StringReplaceOneCharWithString(
4399           isolate, subject, search, replace, &found, kRecursionLimit));
4400   return *result;
4401 }
4402
4403
4404 // Perform string match of pattern on subject, starting at start index.
4405 // Caller must ensure that 0 <= start_index <= sub->length(),
4406 // and should check that pat->length() + start_index <= sub->length().
4407 int Runtime::StringMatch(Isolate* isolate,
4408                          Handle<String> sub,
4409                          Handle<String> pat,
4410                          int start_index) {
4411   ASSERT(0 <= start_index);
4412   ASSERT(start_index <= sub->length());
4413
4414   int pattern_length = pat->length();
4415   if (pattern_length == 0) return start_index;
4416
4417   int subject_length = sub->length();
4418   if (start_index + pattern_length > subject_length) return -1;
4419
4420   sub = String::Flatten(sub);
4421   pat = String::Flatten(pat);
4422
4423   DisallowHeapAllocation no_gc;  // ensure vectors stay valid
4424   // Extract flattened substrings of cons strings before determining asciiness.
4425   String::FlatContent seq_sub = sub->GetFlatContent();
4426   String::FlatContent seq_pat = pat->GetFlatContent();
4427
4428   // dispatch on type of strings
4429   if (seq_pat.IsAscii()) {
4430     Vector<const uint8_t> pat_vector = seq_pat.ToOneByteVector();
4431     if (seq_sub.IsAscii()) {
4432       return SearchString(isolate,
4433                           seq_sub.ToOneByteVector(),
4434                           pat_vector,
4435                           start_index);
4436     }
4437     return SearchString(isolate,
4438                         seq_sub.ToUC16Vector(),
4439                         pat_vector,
4440                         start_index);
4441   }
4442   Vector<const uc16> pat_vector = seq_pat.ToUC16Vector();
4443   if (seq_sub.IsAscii()) {
4444     return SearchString(isolate,
4445                         seq_sub.ToOneByteVector(),
4446                         pat_vector,
4447                         start_index);
4448   }
4449   return SearchString(isolate,
4450                       seq_sub.ToUC16Vector(),
4451                       pat_vector,
4452                       start_index);
4453 }
4454
4455
4456 RUNTIME_FUNCTION(Runtime_StringIndexOf) {
4457   HandleScope scope(isolate);
4458   ASSERT(args.length() == 3);
4459
4460   CONVERT_ARG_HANDLE_CHECKED(String, sub, 0);
4461   CONVERT_ARG_HANDLE_CHECKED(String, pat, 1);
4462   CONVERT_ARG_HANDLE_CHECKED(Object, index, 2);
4463
4464   uint32_t start_index;
4465   if (!index->ToArrayIndex(&start_index)) return Smi::FromInt(-1);
4466
4467   RUNTIME_ASSERT(start_index <= static_cast<uint32_t>(sub->length()));
4468   int position = Runtime::StringMatch(isolate, sub, pat, start_index);
4469   return Smi::FromInt(position);
4470 }
4471
4472
4473 template <typename schar, typename pchar>
4474 static int StringMatchBackwards(Vector<const schar> subject,
4475                                 Vector<const pchar> pattern,
4476                                 int idx) {
4477   int pattern_length = pattern.length();
4478   ASSERT(pattern_length >= 1);
4479   ASSERT(idx + pattern_length <= subject.length());
4480
4481   if (sizeof(schar) == 1 && sizeof(pchar) > 1) {
4482     for (int i = 0; i < pattern_length; i++) {
4483       uc16 c = pattern[i];
4484       if (c > String::kMaxOneByteCharCode) {
4485         return -1;
4486       }
4487     }
4488   }
4489
4490   pchar pattern_first_char = pattern[0];
4491   for (int i = idx; i >= 0; i--) {
4492     if (subject[i] != pattern_first_char) continue;
4493     int j = 1;
4494     while (j < pattern_length) {
4495       if (pattern[j] != subject[i+j]) {
4496         break;
4497       }
4498       j++;
4499     }
4500     if (j == pattern_length) {
4501       return i;
4502     }
4503   }
4504   return -1;
4505 }
4506
4507
4508 RUNTIME_FUNCTION(Runtime_StringLastIndexOf) {
4509   HandleScope scope(isolate);
4510   ASSERT(args.length() == 3);
4511
4512   CONVERT_ARG_HANDLE_CHECKED(String, sub, 0);
4513   CONVERT_ARG_HANDLE_CHECKED(String, pat, 1);
4514   CONVERT_ARG_HANDLE_CHECKED(Object, index, 2);
4515
4516   uint32_t start_index;
4517   if (!index->ToArrayIndex(&start_index)) return Smi::FromInt(-1);
4518
4519   uint32_t pat_length = pat->length();
4520   uint32_t sub_length = sub->length();
4521
4522   if (start_index + pat_length > sub_length) {
4523     start_index = sub_length - pat_length;
4524   }
4525
4526   if (pat_length == 0) {
4527     return Smi::FromInt(start_index);
4528   }
4529
4530   sub = String::Flatten(sub);
4531   pat = String::Flatten(pat);
4532
4533   int position = -1;
4534   DisallowHeapAllocation no_gc;  // ensure vectors stay valid
4535
4536   String::FlatContent sub_content = sub->GetFlatContent();
4537   String::FlatContent pat_content = pat->GetFlatContent();
4538
4539   if (pat_content.IsAscii()) {
4540     Vector<const uint8_t> pat_vector = pat_content.ToOneByteVector();
4541     if (sub_content.IsAscii()) {
4542       position = StringMatchBackwards(sub_content.ToOneByteVector(),
4543                                       pat_vector,
4544                                       start_index);
4545     } else {
4546       position = StringMatchBackwards(sub_content.ToUC16Vector(),
4547                                       pat_vector,
4548                                       start_index);
4549     }
4550   } else {
4551     Vector<const uc16> pat_vector = pat_content.ToUC16Vector();
4552     if (sub_content.IsAscii()) {
4553       position = StringMatchBackwards(sub_content.ToOneByteVector(),
4554                                       pat_vector,
4555                                       start_index);
4556     } else {
4557       position = StringMatchBackwards(sub_content.ToUC16Vector(),
4558                                       pat_vector,
4559                                       start_index);
4560     }
4561   }
4562
4563   return Smi::FromInt(position);
4564 }
4565
4566
4567 RUNTIME_FUNCTION(Runtime_StringLocaleCompare) {
4568   HandleScope handle_scope(isolate);
4569   ASSERT(args.length() == 2);
4570
4571   CONVERT_ARG_HANDLE_CHECKED(String, str1, 0);
4572   CONVERT_ARG_HANDLE_CHECKED(String, str2, 1);
4573
4574   if (str1.is_identical_to(str2)) return Smi::FromInt(0);  // Equal.
4575   int str1_length = str1->length();
4576   int str2_length = str2->length();
4577
4578   // Decide trivial cases without flattening.
4579   if (str1_length == 0) {
4580     if (str2_length == 0) return Smi::FromInt(0);  // Equal.
4581     return Smi::FromInt(-str2_length);
4582   } else {
4583     if (str2_length == 0) return Smi::FromInt(str1_length);
4584   }
4585
4586   int end = str1_length < str2_length ? str1_length : str2_length;
4587
4588   // No need to flatten if we are going to find the answer on the first
4589   // character.  At this point we know there is at least one character
4590   // in each string, due to the trivial case handling above.
4591   int d = str1->Get(0) - str2->Get(0);
4592   if (d != 0) return Smi::FromInt(d);
4593
4594   str1 = String::Flatten(str1);
4595   str2 = String::Flatten(str2);
4596
4597   DisallowHeapAllocation no_gc;
4598   String::FlatContent flat1 = str1->GetFlatContent();
4599   String::FlatContent flat2 = str2->GetFlatContent();
4600
4601   for (int i = 0; i < end; i++) {
4602     if (flat1.Get(i) != flat2.Get(i)) {
4603       return Smi::FromInt(flat1.Get(i) - flat2.Get(i));
4604     }
4605   }
4606
4607   return Smi::FromInt(str1_length - str2_length);
4608 }
4609
4610
4611 RUNTIME_FUNCTION(RuntimeHidden_SubString) {
4612   HandleScope scope(isolate);
4613   ASSERT(args.length() == 3);
4614
4615   CONVERT_ARG_HANDLE_CHECKED(String, string, 0);
4616   int start, end;
4617   // We have a fast integer-only case here to avoid a conversion to double in
4618   // the common case where from and to are Smis.
4619   if (args[1]->IsSmi() && args[2]->IsSmi()) {
4620     CONVERT_SMI_ARG_CHECKED(from_number, 1);
4621     CONVERT_SMI_ARG_CHECKED(to_number, 2);
4622     start = from_number;
4623     end = to_number;
4624   } else {
4625     CONVERT_DOUBLE_ARG_CHECKED(from_number, 1);
4626     CONVERT_DOUBLE_ARG_CHECKED(to_number, 2);
4627     start = FastD2IChecked(from_number);
4628     end = FastD2IChecked(to_number);
4629   }
4630   RUNTIME_ASSERT(end >= start);
4631   RUNTIME_ASSERT(start >= 0);
4632   RUNTIME_ASSERT(end <= string->length());
4633   isolate->counters()->sub_string_runtime()->Increment();
4634
4635   return *isolate->factory()->NewSubString(string, start, end);
4636 }
4637
4638
4639 RUNTIME_FUNCTION(Runtime_StringMatch) {
4640   HandleScope handles(isolate);
4641   ASSERT(args.length() == 3);
4642
4643   CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
4644   CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 1);
4645   CONVERT_ARG_HANDLE_CHECKED(JSArray, regexp_info, 2);
4646
4647   RUNTIME_ASSERT(regexp_info->HasFastObjectElements());
4648
4649   RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate);
4650   if (global_cache.HasException()) return isolate->heap()->exception();
4651
4652   int capture_count = regexp->CaptureCount();
4653
4654   ZoneScope zone_scope(isolate->runtime_zone());
4655   ZoneList<int> offsets(8, zone_scope.zone());
4656
4657   while (true) {
4658     int32_t* match = global_cache.FetchNext();
4659     if (match == NULL) break;
4660     offsets.Add(match[0], zone_scope.zone());  // start
4661     offsets.Add(match[1], zone_scope.zone());  // end
4662   }
4663
4664   if (global_cache.HasException()) return isolate->heap()->exception();
4665
4666   if (offsets.length() == 0) {
4667     // Not a single match.
4668     return isolate->heap()->null_value();
4669   }
4670
4671   RegExpImpl::SetLastMatchInfo(regexp_info,
4672                                subject,
4673                                capture_count,
4674                                global_cache.LastSuccessfulMatch());
4675
4676   int matches = offsets.length() / 2;
4677   Handle<FixedArray> elements = isolate->factory()->NewFixedArray(matches);
4678   Handle<String> substring =
4679       isolate->factory()->NewSubString(subject, offsets.at(0), offsets.at(1));
4680   elements->set(0, *substring);
4681   for (int i = 1; i < matches; i++) {
4682     HandleScope temp_scope(isolate);
4683     int from = offsets.at(i * 2);
4684     int to = offsets.at(i * 2 + 1);
4685     Handle<String> substring =
4686         isolate->factory()->NewProperSubString(subject, from, to);
4687     elements->set(i, *substring);
4688   }
4689   Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements(elements);
4690   result->set_length(Smi::FromInt(matches));
4691   return *result;
4692 }
4693
4694
4695 // Only called from Runtime_RegExpExecMultiple so it doesn't need to maintain
4696 // separate last match info.  See comment on that function.
4697 template<bool has_capture>
4698 static Object* SearchRegExpMultiple(
4699     Isolate* isolate,
4700     Handle<String> subject,
4701     Handle<JSRegExp> regexp,
4702     Handle<JSArray> last_match_array,
4703     Handle<JSArray> result_array) {
4704   ASSERT(subject->IsFlat());
4705   ASSERT_NE(has_capture, regexp->CaptureCount() == 0);
4706
4707   int capture_count = regexp->CaptureCount();
4708   int subject_length = subject->length();
4709
4710   static const int kMinLengthToCache = 0x1000;
4711
4712   if (subject_length > kMinLengthToCache) {
4713     Handle<Object> cached_answer(RegExpResultsCache::Lookup(
4714         isolate->heap(),
4715         *subject,
4716         regexp->data(),
4717         RegExpResultsCache::REGEXP_MULTIPLE_INDICES), isolate);
4718     if (*cached_answer != Smi::FromInt(0)) {
4719       Handle<FixedArray> cached_fixed_array =
4720           Handle<FixedArray>(FixedArray::cast(*cached_answer));
4721       // The cache FixedArray is a COW-array and can therefore be reused.
4722       JSArray::SetContent(result_array, cached_fixed_array);
4723       // The actual length of the result array is stored in the last element of
4724       // the backing store (the backing FixedArray may have a larger capacity).
4725       Object* cached_fixed_array_last_element =
4726           cached_fixed_array->get(cached_fixed_array->length() - 1);
4727       Smi* js_array_length = Smi::cast(cached_fixed_array_last_element);
4728       result_array->set_length(js_array_length);
4729       RegExpImpl::SetLastMatchInfo(
4730           last_match_array, subject, capture_count, NULL);
4731       return *result_array;
4732     }
4733   }
4734
4735   RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate);
4736   if (global_cache.HasException()) return isolate->heap()->exception();
4737
4738   Handle<FixedArray> result_elements;
4739   if (result_array->HasFastObjectElements()) {
4740     result_elements =
4741         Handle<FixedArray>(FixedArray::cast(result_array->elements()));
4742   }
4743   if (result_elements.is_null() || result_elements->length() < 16) {
4744     result_elements = isolate->factory()->NewFixedArrayWithHoles(16);
4745   }
4746
4747   FixedArrayBuilder builder(result_elements);
4748
4749   // Position to search from.
4750   int match_start = -1;
4751   int match_end = 0;
4752   bool first = true;
4753
4754   // Two smis before and after the match, for very long strings.
4755   static const int kMaxBuilderEntriesPerRegExpMatch = 5;
4756
4757   while (true) {
4758     int32_t* current_match = global_cache.FetchNext();
4759     if (current_match == NULL) break;
4760     match_start = current_match[0];
4761     builder.EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch);
4762     if (match_end < match_start) {
4763       ReplacementStringBuilder::AddSubjectSlice(&builder,
4764                                                 match_end,
4765                                                 match_start);
4766     }
4767     match_end = current_match[1];
4768     {
4769       // Avoid accumulating new handles inside loop.
4770       HandleScope temp_scope(isolate);
4771       Handle<String> match;
4772       if (!first) {
4773         match = isolate->factory()->NewProperSubString(subject,
4774                                                        match_start,
4775                                                        match_end);
4776       } else {
4777         match = isolate->factory()->NewSubString(subject,
4778                                                  match_start,
4779                                                  match_end);
4780         first = false;
4781       }
4782
4783       if (has_capture) {
4784         // Arguments array to replace function is match, captures, index and
4785         // subject, i.e., 3 + capture count in total.
4786         Handle<FixedArray> elements =
4787             isolate->factory()->NewFixedArray(3 + capture_count);
4788
4789         elements->set(0, *match);
4790         for (int i = 1; i <= capture_count; i++) {
4791           int start = current_match[i * 2];
4792           if (start >= 0) {
4793             int end = current_match[i * 2 + 1];
4794             ASSERT(start <= end);
4795             Handle<String> substring =
4796                 isolate->factory()->NewSubString(subject, start, end);
4797             elements->set(i, *substring);
4798           } else {
4799             ASSERT(current_match[i * 2 + 1] < 0);
4800             elements->set(i, isolate->heap()->undefined_value());
4801           }
4802         }
4803         elements->set(capture_count + 1, Smi::FromInt(match_start));
4804         elements->set(capture_count + 2, *subject);
4805         builder.Add(*isolate->factory()->NewJSArrayWithElements(elements));
4806       } else {
4807         builder.Add(*match);
4808       }
4809     }
4810   }
4811
4812   if (global_cache.HasException()) return isolate->heap()->exception();
4813
4814   if (match_start >= 0) {
4815     // Finished matching, with at least one match.
4816     if (match_end < subject_length) {
4817       ReplacementStringBuilder::AddSubjectSlice(&builder,
4818                                                 match_end,
4819                                                 subject_length);
4820     }
4821
4822     RegExpImpl::SetLastMatchInfo(
4823         last_match_array, subject, capture_count, NULL);
4824
4825     if (subject_length > kMinLengthToCache) {
4826       // Store the length of the result array into the last element of the
4827       // backing FixedArray.
4828       builder.EnsureCapacity(1);
4829       Handle<FixedArray> fixed_array = builder.array();
4830       fixed_array->set(fixed_array->length() - 1,
4831                        Smi::FromInt(builder.length()));
4832       // Cache the result and turn the FixedArray into a COW array.
4833       RegExpResultsCache::Enter(isolate,
4834                                 subject,
4835                                 handle(regexp->data(), isolate),
4836                                 fixed_array,
4837                                 RegExpResultsCache::REGEXP_MULTIPLE_INDICES);
4838     }
4839     return *builder.ToJSArray(result_array);
4840   } else {
4841     return isolate->heap()->null_value();  // No matches at all.
4842   }
4843 }
4844
4845
4846 // This is only called for StringReplaceGlobalRegExpWithFunction.  This sets
4847 // lastMatchInfoOverride to maintain the last match info, so we don't need to
4848 // set any other last match array info.
4849 RUNTIME_FUNCTION(Runtime_RegExpExecMultiple) {
4850   HandleScope handles(isolate);
4851   ASSERT(args.length() == 4);
4852
4853   CONVERT_ARG_HANDLE_CHECKED(String, subject, 1);
4854   CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0);
4855   CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 2);
4856   CONVERT_ARG_HANDLE_CHECKED(JSArray, result_array, 3);
4857
4858   subject = String::Flatten(subject);
4859   ASSERT(regexp->GetFlags().is_global());
4860
4861   if (regexp->CaptureCount() == 0) {
4862     return SearchRegExpMultiple<false>(
4863         isolate, subject, regexp, last_match_info, result_array);
4864   } else {
4865     return SearchRegExpMultiple<true>(
4866         isolate, subject, regexp, last_match_info, result_array);
4867   }
4868 }
4869
4870
4871 RUNTIME_FUNCTION(Runtime_NumberToRadixString) {
4872   HandleScope scope(isolate);
4873   ASSERT(args.length() == 2);
4874   CONVERT_SMI_ARG_CHECKED(radix, 1);
4875   RUNTIME_ASSERT(2 <= radix && radix <= 36);
4876
4877   // Fast case where the result is a one character string.
4878   if (args[0]->IsSmi()) {
4879     int value = args.smi_at(0);
4880     if (value >= 0 && value < radix) {
4881       // Character array used for conversion.
4882       static const char kCharTable[] = "0123456789abcdefghijklmnopqrstuvwxyz";
4883       return *isolate->factory()->
4884           LookupSingleCharacterStringFromCode(kCharTable[value]);
4885     }
4886   }
4887
4888   // Slow case.
4889   CONVERT_DOUBLE_ARG_CHECKED(value, 0);
4890   if (std::isnan(value)) {
4891     return isolate->heap()->nan_string();
4892   }
4893   if (std::isinf(value)) {
4894     if (value < 0) {
4895       return isolate->heap()->minus_infinity_string();
4896     }
4897     return isolate->heap()->infinity_string();
4898   }
4899   char* str = DoubleToRadixCString(value, radix);
4900   Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(str);
4901   DeleteArray(str);
4902   return *result;
4903 }
4904
4905
4906 RUNTIME_FUNCTION(Runtime_NumberToFixed) {
4907   HandleScope scope(isolate);
4908   ASSERT(args.length() == 2);
4909
4910   CONVERT_DOUBLE_ARG_CHECKED(value, 0);
4911   CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
4912   int f = FastD2IChecked(f_number);
4913   // See DoubleToFixedCString for these constants:
4914   RUNTIME_ASSERT(f >= 0 && f <= 20);
4915   char* str = DoubleToFixedCString(value, f);
4916   Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(str);
4917   DeleteArray(str);
4918   return *result;
4919 }
4920
4921
4922 RUNTIME_FUNCTION(Runtime_NumberToExponential) {
4923   HandleScope scope(isolate);
4924   ASSERT(args.length() == 2);
4925
4926   CONVERT_DOUBLE_ARG_CHECKED(value, 0);
4927   CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
4928   int f = FastD2IChecked(f_number);
4929   RUNTIME_ASSERT(f >= -1 && f <= 20);
4930   char* str = DoubleToExponentialCString(value, f);
4931   Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(str);
4932   DeleteArray(str);
4933   return *result;
4934 }
4935
4936
4937 RUNTIME_FUNCTION(Runtime_NumberToPrecision) {
4938   HandleScope scope(isolate);
4939   ASSERT(args.length() == 2);
4940
4941   CONVERT_DOUBLE_ARG_CHECKED(value, 0);
4942   CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
4943   int f = FastD2IChecked(f_number);
4944   RUNTIME_ASSERT(f >= 1 && f <= 21);
4945   char* str = DoubleToPrecisionCString(value, f);
4946   Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(str);
4947   DeleteArray(str);
4948   return *result;
4949 }
4950
4951
4952 RUNTIME_FUNCTION(Runtime_IsValidSmi) {
4953   SealHandleScope shs(isolate);
4954   ASSERT(args.length() == 1);
4955
4956   CONVERT_NUMBER_CHECKED(int32_t, number, Int32, args[0]);
4957   return isolate->heap()->ToBoolean(Smi::IsValid(number));
4958 }
4959
4960
4961 // Returns a single character string where first character equals
4962 // string->Get(index).
4963 static Handle<Object> GetCharAt(Handle<String> string, uint32_t index) {
4964   if (index < static_cast<uint32_t>(string->length())) {
4965     Factory* factory = string->GetIsolate()->factory();
4966     return factory->LookupSingleCharacterStringFromCode(
4967         String::Flatten(string)->Get(index));
4968   }
4969   return Execution::CharAt(string, index);
4970 }
4971
4972
4973 MaybeHandle<Object> Runtime::GetElementOrCharAt(Isolate* isolate,
4974                                                 Handle<Object> object,
4975                                                 uint32_t index) {
4976   // Handle [] indexing on Strings
4977   if (object->IsString()) {
4978     Handle<Object> result = GetCharAt(Handle<String>::cast(object), index);
4979     if (!result->IsUndefined()) return result;
4980   }
4981
4982   // Handle [] indexing on String objects
4983   if (object->IsStringObjectWithCharacterAt(index)) {
4984     Handle<JSValue> js_value = Handle<JSValue>::cast(object);
4985     Handle<Object> result =
4986         GetCharAt(Handle<String>(String::cast(js_value->value())), index);
4987     if (!result->IsUndefined()) return result;
4988   }
4989
4990   Handle<Object> result;
4991   if (object->IsString() || object->IsNumber() || object->IsBoolean()) {
4992     Handle<Object> proto(object->GetPrototype(isolate), isolate);
4993     return Object::GetElement(isolate, proto, index);
4994   } else {
4995     return Object::GetElement(isolate, object, index);
4996   }
4997 }
4998
4999
5000 MUST_USE_RESULT
5001 static MaybeHandle<Name> ToName(Isolate* isolate, Handle<Object> key) {
5002   if (key->IsName()) {
5003     return Handle<Name>::cast(key);
5004   } else {
5005     Handle<Object> converted;
5006     ASSIGN_RETURN_ON_EXCEPTION(
5007         isolate, converted, Execution::ToString(isolate, key), Name);
5008     return Handle<Name>::cast(converted);
5009   }
5010 }
5011
5012
5013 MaybeHandle<Object> Runtime::HasObjectProperty(Isolate* isolate,
5014                                                Handle<JSReceiver> object,
5015                                                Handle<Object> key) {
5016   // Check if the given key is an array index.
5017   uint32_t index;
5018   if (key->ToArrayIndex(&index)) {
5019     return isolate->factory()->ToBoolean(JSReceiver::HasElement(object, index));
5020   }
5021
5022   // Convert the key to a name - possibly by calling back into JavaScript.
5023   Handle<Name> name;
5024   ASSIGN_RETURN_ON_EXCEPTION(isolate, name, ToName(isolate, key), Object);
5025
5026   return isolate->factory()->ToBoolean(JSReceiver::HasProperty(object, name));
5027 }
5028
5029
5030 MaybeHandle<Object> Runtime::GetObjectProperty(Isolate* isolate,
5031                                                Handle<Object> object,
5032                                                Handle<Object> key) {
5033   if (object->IsUndefined() || object->IsNull()) {
5034     Handle<Object> args[2] = { key, object };
5035     return isolate->Throw<Object>(
5036         isolate->factory()->NewTypeError("non_object_property_load",
5037                                          HandleVector(args, 2)));
5038   }
5039
5040   // Check if the given key is an array index.
5041   uint32_t index;
5042   if (key->ToArrayIndex(&index)) {
5043     return GetElementOrCharAt(isolate, object, index);
5044   }
5045
5046   // Convert the key to a name - possibly by calling back into JavaScript.
5047   Handle<Name> name;
5048   ASSIGN_RETURN_ON_EXCEPTION(isolate, name, ToName(isolate, key), Object);
5049
5050   // Check if the name is trivially convertible to an index and get
5051   // the element if so.
5052   if (name->AsArrayIndex(&index)) {
5053     return GetElementOrCharAt(isolate, object, index);
5054   } else {
5055     return Object::GetProperty(object, name);
5056   }
5057 }
5058
5059
5060 RUNTIME_FUNCTION(Runtime_GetProperty) {
5061   HandleScope scope(isolate);
5062   ASSERT(args.length() == 2);
5063
5064   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
5065   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
5066   Handle<Object> result;
5067   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
5068       isolate, result,
5069       Runtime::GetObjectProperty(isolate, object, key));
5070   return *result;
5071 }
5072
5073
5074 // KeyedGetProperty is called from KeyedLoadIC::GenerateGeneric.
5075 RUNTIME_FUNCTION(Runtime_KeyedGetProperty) {
5076   HandleScope scope(isolate);
5077   ASSERT(args.length() == 2);
5078
5079   CONVERT_ARG_HANDLE_CHECKED(Object, receiver_obj, 0);
5080   CONVERT_ARG_HANDLE_CHECKED(Object, key_obj, 1);
5081
5082   // Fast cases for getting named properties of the receiver JSObject
5083   // itself.
5084   //
5085   // The global proxy objects has to be excluded since LocalLookup on
5086   // the global proxy object can return a valid result even though the
5087   // global proxy object never has properties.  This is the case
5088   // because the global proxy object forwards everything to its hidden
5089   // prototype including local lookups.
5090   //
5091   // Additionally, we need to make sure that we do not cache results
5092   // for objects that require access checks.
5093   if (receiver_obj->IsJSObject()) {
5094     if (!receiver_obj->IsJSGlobalProxy() &&
5095         !receiver_obj->IsAccessCheckNeeded() &&
5096         key_obj->IsName()) {
5097       DisallowHeapAllocation no_allocation;
5098       Handle<JSObject> receiver = Handle<JSObject>::cast(receiver_obj);
5099       Handle<Name> key = Handle<Name>::cast(key_obj);
5100       if (receiver->HasFastProperties()) {
5101         // Attempt to use lookup cache.
5102         Handle<Map> receiver_map(receiver->map(), isolate);
5103         KeyedLookupCache* keyed_lookup_cache = isolate->keyed_lookup_cache();
5104         int offset = keyed_lookup_cache->Lookup(receiver_map, key);
5105         if (offset != -1) {
5106           // Doubles are not cached, so raw read the value.
5107           Object* value = receiver->RawFastPropertyAt(offset);
5108           return value->IsTheHole()
5109               ? isolate->heap()->undefined_value()
5110               : value;
5111         }
5112         // Lookup cache miss.  Perform lookup and update the cache if
5113         // appropriate.
5114         LookupResult result(isolate);
5115         receiver->LocalLookup(key, &result);
5116         if (result.IsField()) {
5117           int offset = result.GetFieldIndex().field_index();
5118           // Do not track double fields in the keyed lookup cache. Reading
5119           // double values requires boxing.
5120           if (!result.representation().IsDouble()) {
5121             keyed_lookup_cache->Update(receiver_map, key, offset);
5122           }
5123           AllowHeapAllocation allow_allocation;
5124           return *JSObject::FastPropertyAt(
5125               receiver, result.representation(), offset);
5126         }
5127       } else {
5128         // Attempt dictionary lookup.
5129         NameDictionary* dictionary = receiver->property_dictionary();
5130         int entry = dictionary->FindEntry(key);
5131         if ((entry != NameDictionary::kNotFound) &&
5132             (dictionary->DetailsAt(entry).type() == NORMAL)) {
5133           Object* value = dictionary->ValueAt(entry);
5134           if (!receiver->IsGlobalObject()) return value;
5135           value = PropertyCell::cast(value)->value();
5136           if (!value->IsTheHole()) return value;
5137           // If value is the hole do the general lookup.
5138         }
5139       }
5140     } else if (FLAG_smi_only_arrays && key_obj->IsSmi()) {
5141       // JSObject without a name key. If the key is a Smi, check for a
5142       // definite out-of-bounds access to elements, which is a strong indicator
5143       // that subsequent accesses will also call the runtime. Proactively
5144       // transition elements to FAST_*_ELEMENTS to avoid excessive boxing of
5145       // doubles for those future calls in the case that the elements would
5146       // become FAST_DOUBLE_ELEMENTS.
5147       Handle<JSObject> js_object = Handle<JSObject>::cast(receiver_obj);
5148       ElementsKind elements_kind = js_object->GetElementsKind();
5149       if (IsFastDoubleElementsKind(elements_kind)) {
5150         Handle<Smi> key = Handle<Smi>::cast(key_obj);
5151         if (key->value() >= js_object->elements()->length()) {
5152           if (IsFastHoleyElementsKind(elements_kind)) {
5153             elements_kind = FAST_HOLEY_ELEMENTS;
5154           } else {
5155             elements_kind = FAST_ELEMENTS;
5156           }
5157           RETURN_FAILURE_ON_EXCEPTION(
5158               isolate, TransitionElements(js_object, elements_kind, isolate));
5159         }
5160       } else {
5161         ASSERT(IsFastSmiOrObjectElementsKind(elements_kind) ||
5162                !IsFastElementsKind(elements_kind));
5163       }
5164     }
5165   } else if (receiver_obj->IsString() && key_obj->IsSmi()) {
5166     // Fast case for string indexing using [] with a smi index.
5167     Handle<String> str = Handle<String>::cast(receiver_obj);
5168     int index = args.smi_at(1);
5169     if (index >= 0 && index < str->length()) {
5170       return *GetCharAt(str, index);
5171     }
5172   }
5173
5174   // Fall back to GetObjectProperty.
5175   Handle<Object> result;
5176   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
5177       isolate, result,
5178       Runtime::GetObjectProperty(isolate, receiver_obj, key_obj));
5179   return *result;
5180 }
5181
5182
5183 static bool IsValidAccessor(Handle<Object> obj) {
5184   return obj->IsUndefined() || obj->IsSpecFunction() || obj->IsNull();
5185 }
5186
5187
5188 // Implements part of 8.12.9 DefineOwnProperty.
5189 // There are 3 cases that lead here:
5190 // Step 4b - define a new accessor property.
5191 // Steps 9c & 12 - replace an existing data property with an accessor property.
5192 // Step 12 - update an existing accessor property with an accessor or generic
5193 //           descriptor.
5194 RUNTIME_FUNCTION(Runtime_DefineOrRedefineAccessorProperty) {
5195   HandleScope scope(isolate);
5196   ASSERT(args.length() == 5);
5197   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
5198   RUNTIME_ASSERT(!obj->IsNull());
5199   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
5200   CONVERT_ARG_HANDLE_CHECKED(Object, getter, 2);
5201   RUNTIME_ASSERT(IsValidAccessor(getter));
5202   CONVERT_ARG_HANDLE_CHECKED(Object, setter, 3);
5203   RUNTIME_ASSERT(IsValidAccessor(setter));
5204   CONVERT_SMI_ARG_CHECKED(unchecked, 4);
5205   RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
5206   PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked);
5207
5208   bool fast = obj->HasFastProperties();
5209   // DefineAccessor checks access rights.
5210   JSObject::DefineAccessor(obj, name, getter, setter, attr);
5211   RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
5212   if (fast) JSObject::TransformToFastProperties(obj, 0);
5213   return isolate->heap()->undefined_value();
5214 }
5215
5216
5217 // Implements part of 8.12.9 DefineOwnProperty.
5218 // There are 3 cases that lead here:
5219 // Step 4a - define a new data property.
5220 // Steps 9b & 12 - replace an existing accessor property with a data property.
5221 // Step 12 - update an existing data property with a data or generic
5222 //           descriptor.
5223 RUNTIME_FUNCTION(Runtime_DefineOrRedefineDataProperty) {
5224   HandleScope scope(isolate);
5225   ASSERT(args.length() == 4);
5226   CONVERT_ARG_HANDLE_CHECKED(JSObject, js_object, 0);
5227   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
5228   CONVERT_ARG_HANDLE_CHECKED(Object, obj_value, 2);
5229   CONVERT_SMI_ARG_CHECKED(unchecked, 3);
5230   RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
5231   PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked);
5232
5233   // Check access rights if needed.
5234   if (js_object->IsAccessCheckNeeded() &&
5235       !isolate->MayNamedAccess(js_object, name, v8::ACCESS_SET)) {
5236     return isolate->heap()->undefined_value();
5237   }
5238
5239   LookupResult lookup(isolate);
5240   js_object->LocalLookupRealNamedProperty(name, &lookup);
5241
5242   // Special case for callback properties.
5243   if (lookup.IsPropertyCallbacks()) {
5244     Handle<Object> callback(lookup.GetCallbackObject(), isolate);
5245     // Avoid redefining callback as data property, just use the stored
5246     // setter to update the value instead.
5247     // TODO(mstarzinger): So far this only works if property attributes don't
5248     // change, this should be fixed once we cleanup the underlying code.
5249     ASSERT(!callback->IsForeign());
5250     if (callback->IsAccessorInfo() &&
5251         lookup.GetAttributes() == attr) {
5252       Handle<Object> result_object;
5253       ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
5254           isolate, result_object,
5255           JSObject::SetPropertyWithCallback(js_object,
5256                                             callback,
5257                                             name,
5258                                             obj_value,
5259                                             handle(lookup.holder()),
5260                                             STRICT));
5261       return *result_object;
5262     }
5263   }
5264
5265   // Take special care when attributes are different and there is already
5266   // a property. For simplicity we normalize the property which enables us
5267   // to not worry about changing the instance_descriptor and creating a new
5268   // map. The current version of SetObjectProperty does not handle attributes
5269   // correctly in the case where a property is a field and is reset with
5270   // new attributes.
5271   if (lookup.IsFound() &&
5272       (attr != lookup.GetAttributes() || lookup.IsPropertyCallbacks())) {
5273     // New attributes - normalize to avoid writing to instance descriptor
5274     if (js_object->IsJSGlobalProxy()) {
5275       // Since the result is a property, the prototype will exist so
5276       // we don't have to check for null.
5277       js_object = Handle<JSObject>(JSObject::cast(js_object->GetPrototype()));
5278     }
5279     JSObject::NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0);
5280     // Use IgnoreAttributes version since a readonly property may be
5281     // overridden and SetProperty does not allow this.
5282     Handle<Object> result;
5283     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
5284         isolate, result,
5285         JSObject::SetLocalPropertyIgnoreAttributes(
5286             js_object, name, obj_value, attr));
5287     return *result;
5288   }
5289
5290   Handle<Object> result;
5291   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
5292       isolate, result,
5293       Runtime::ForceSetObjectProperty(
5294           js_object, name, obj_value, attr,
5295           JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED));
5296   return *result;
5297 }
5298
5299
5300 // Return property without being observable by accessors or interceptors.
5301 RUNTIME_FUNCTION(Runtime_GetDataProperty) {
5302   HandleScope scope(isolate);
5303   ASSERT(args.length() == 2);
5304   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
5305   CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
5306   return *JSObject::GetDataProperty(object, key);
5307 }
5308
5309
5310 MaybeHandle<Object> Runtime::SetObjectProperty(Isolate* isolate,
5311                                                Handle<Object> object,
5312                                                Handle<Object> key,
5313                                                Handle<Object> value,
5314                                                PropertyAttributes attr,
5315                                                StrictMode strict_mode) {
5316   SetPropertyMode set_mode = attr == NONE ? SET_PROPERTY : DEFINE_PROPERTY;
5317
5318   if (object->IsUndefined() || object->IsNull()) {
5319     Handle<Object> args[2] = { key, object };
5320     Handle<Object> error =
5321         isolate->factory()->NewTypeError("non_object_property_store",
5322                                          HandleVector(args, 2));
5323     return isolate->Throw<Object>(error);
5324   }
5325
5326   if (object->IsJSProxy()) {
5327     Handle<Object> name_object;
5328     if (key->IsSymbol()) {
5329       name_object = key;
5330     } else {
5331       ASSIGN_RETURN_ON_EXCEPTION(
5332           isolate, name_object, Execution::ToString(isolate, key), Object);
5333     }
5334     Handle<Name> name = Handle<Name>::cast(name_object);
5335     return JSReceiver::SetProperty(Handle<JSProxy>::cast(object), name, value,
5336                                    attr,
5337                                    strict_mode);
5338   }
5339
5340   // If the object isn't a JavaScript object, we ignore the store.
5341   if (!object->IsJSObject()) return value;
5342
5343   Handle<JSObject> js_object = Handle<JSObject>::cast(object);
5344
5345   // Check if the given key is an array index.
5346   uint32_t index;
5347   if (key->ToArrayIndex(&index)) {
5348     // In Firefox/SpiderMonkey, Safari and Opera you can access the characters
5349     // of a string using [] notation.  We need to support this too in
5350     // JavaScript.
5351     // In the case of a String object we just need to redirect the assignment to
5352     // the underlying string if the index is in range.  Since the underlying
5353     // string does nothing with the assignment then we can ignore such
5354     // assignments.
5355     if (js_object->IsStringObjectWithCharacterAt(index)) {
5356       return value;
5357     }
5358
5359     JSObject::ValidateElements(js_object);
5360     if (js_object->HasExternalArrayElements() ||
5361         js_object->HasFixedTypedArrayElements()) {
5362       // TODO(ningxin): Throw an error if setting a Float32x4Array element
5363       // while the value is not Float32x4Object.
5364       if (!value->IsNumber() &&  !value->IsFloat32x4() &&
5365           !value->IsFloat64x2() && !value->IsInt32x4() &&
5366           !value->IsUndefined()) {
5367         ASSIGN_RETURN_ON_EXCEPTION(
5368             isolate, value, Execution::ToNumber(isolate, value), Object);
5369       }
5370     }
5371
5372     MaybeHandle<Object> result = JSObject::SetElement(
5373         js_object, index, value, attr, strict_mode, true, set_mode);
5374     JSObject::ValidateElements(js_object);
5375
5376     return result.is_null() ? result : value;
5377   }
5378
5379   if (key->IsName()) {
5380     Handle<Name> name = Handle<Name>::cast(key);
5381     if (name->AsArrayIndex(&index)) {
5382       if (js_object->HasExternalArrayElements()) {
5383         // TODO(ningxin): Throw an error if setting a Float32x4Array element
5384         // while the value is not Float32x4Object.
5385         if (!value->IsNumber() &&  !value->IsFloat32x4() &&
5386             !value->IsFloat64x2() && !value->IsInt32x4() &&
5387             !value->IsUndefined()) {
5388           ASSIGN_RETURN_ON_EXCEPTION(
5389               isolate, value, Execution::ToNumber(isolate, value), Object);
5390         }
5391       }
5392       return JSObject::SetElement(js_object, index, value, attr,
5393                                   strict_mode, true, set_mode);
5394     } else {
5395       if (name->IsString()) name = String::Flatten(Handle<String>::cast(name));
5396       return JSReceiver::SetProperty(js_object, name, value, attr, strict_mode);
5397     }
5398   }
5399
5400   // Call-back into JavaScript to convert the key to a string.
5401   Handle<Object> converted;
5402   ASSIGN_RETURN_ON_EXCEPTION(
5403       isolate, converted, Execution::ToString(isolate, key), Object);
5404   Handle<String> name = Handle<String>::cast(converted);
5405
5406   if (name->AsArrayIndex(&index)) {
5407     return JSObject::SetElement(js_object, index, value, attr,
5408                                 strict_mode, true, set_mode);
5409   } else {
5410     return JSReceiver::SetProperty(js_object, name, value, attr, strict_mode);
5411   }
5412 }
5413
5414
5415 MaybeHandle<Object> Runtime::ForceSetObjectProperty(
5416     Handle<JSObject> js_object,
5417     Handle<Object> key,
5418     Handle<Object> value,
5419     PropertyAttributes attr,
5420     JSReceiver::StoreFromKeyed store_from_keyed) {
5421   Isolate* isolate = js_object->GetIsolate();
5422   // Check if the given key is an array index.
5423   uint32_t index;
5424   if (key->ToArrayIndex(&index)) {
5425     // In Firefox/SpiderMonkey, Safari and Opera you can access the characters
5426     // of a string using [] notation.  We need to support this too in
5427     // JavaScript.
5428     // In the case of a String object we just need to redirect the assignment to
5429     // the underlying string if the index is in range.  Since the underlying
5430     // string does nothing with the assignment then we can ignore such
5431     // assignments.
5432     if (js_object->IsStringObjectWithCharacterAt(index)) {
5433       return value;
5434     }
5435
5436     return JSObject::SetElement(js_object, index, value, attr,
5437                                 SLOPPY, false, DEFINE_PROPERTY);
5438   }
5439
5440   if (key->IsName()) {
5441     Handle<Name> name = Handle<Name>::cast(key);
5442     if (name->AsArrayIndex(&index)) {
5443       return JSObject::SetElement(js_object, index, value, attr,
5444                                   SLOPPY, false, DEFINE_PROPERTY);
5445     } else {
5446       if (name->IsString()) name = String::Flatten(Handle<String>::cast(name));
5447       return JSObject::SetLocalPropertyIgnoreAttributes(
5448           js_object, name, value, attr, Object::OPTIMAL_REPRESENTATION,
5449           ALLOW_AS_CONSTANT, JSReceiver::PERFORM_EXTENSIBILITY_CHECK,
5450           store_from_keyed);
5451     }
5452   }
5453
5454   // Call-back into JavaScript to convert the key to a string.
5455   Handle<Object> converted;
5456   ASSIGN_RETURN_ON_EXCEPTION(
5457       isolate, converted, Execution::ToString(isolate, key), Object);
5458   Handle<String> name = Handle<String>::cast(converted);
5459
5460   if (name->AsArrayIndex(&index)) {
5461     return JSObject::SetElement(js_object, index, value, attr,
5462                                 SLOPPY, false, DEFINE_PROPERTY);
5463   } else {
5464     return JSObject::SetLocalPropertyIgnoreAttributes(
5465         js_object, name, value, attr, Object::OPTIMAL_REPRESENTATION,
5466         ALLOW_AS_CONSTANT, JSReceiver::PERFORM_EXTENSIBILITY_CHECK,
5467         store_from_keyed);
5468   }
5469 }
5470
5471
5472 MaybeHandle<Object> Runtime::DeleteObjectProperty(Isolate* isolate,
5473                                                   Handle<JSReceiver> receiver,
5474                                                   Handle<Object> key,
5475                                                   JSReceiver::DeleteMode mode) {
5476   // Check if the given key is an array index.
5477   uint32_t index;
5478   if (key->ToArrayIndex(&index)) {
5479     // In Firefox/SpiderMonkey, Safari and Opera you can access the
5480     // characters of a string using [] notation.  In the case of a
5481     // String object we just need to redirect the deletion to the
5482     // underlying string if the index is in range.  Since the
5483     // underlying string does nothing with the deletion, we can ignore
5484     // such deletions.
5485     if (receiver->IsStringObjectWithCharacterAt(index)) {
5486       return isolate->factory()->true_value();
5487     }
5488
5489     return JSReceiver::DeleteElement(receiver, index, mode);
5490   }
5491
5492   Handle<Name> name;
5493   if (key->IsName()) {
5494     name = Handle<Name>::cast(key);
5495   } else {
5496     // Call-back into JavaScript to convert the key to a string.
5497     Handle<Object> converted;
5498     ASSIGN_RETURN_ON_EXCEPTION(
5499         isolate, converted, Execution::ToString(isolate, key), Object);
5500     name = Handle<String>::cast(converted);
5501   }
5502
5503   if (name->IsString()) name = String::Flatten(Handle<String>::cast(name));
5504   return JSReceiver::DeleteProperty(receiver, name, mode);
5505 }
5506
5507
5508 RUNTIME_FUNCTION(Runtime_SetHiddenProperty) {
5509   HandleScope scope(isolate);
5510   RUNTIME_ASSERT(args.length() == 3);
5511
5512   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
5513   CONVERT_ARG_HANDLE_CHECKED(String, key, 1);
5514   CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
5515   return *JSObject::SetHiddenProperty(object, key, value);
5516 }
5517
5518
5519 RUNTIME_FUNCTION(Runtime_SetProperty) {
5520   HandleScope scope(isolate);
5521   RUNTIME_ASSERT(args.length() == 4 || args.length() == 5);
5522
5523   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
5524   CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
5525   CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
5526   CONVERT_SMI_ARG_CHECKED(unchecked_attributes, 3);
5527   RUNTIME_ASSERT(
5528       (unchecked_attributes & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
5529   // Compute attributes.
5530   PropertyAttributes attributes =
5531       static_cast<PropertyAttributes>(unchecked_attributes);
5532
5533   StrictMode strict_mode = SLOPPY;
5534   if (args.length() == 5) {
5535     CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode_arg, 4);
5536     strict_mode = strict_mode_arg;
5537   }
5538
5539   Handle<Object> result;
5540   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
5541       isolate, result,
5542       Runtime::SetObjectProperty(
5543           isolate, object, key, value, attributes, strict_mode));
5544   return *result;
5545 }
5546
5547
5548 RUNTIME_FUNCTION(Runtime_TransitionElementsKind) {
5549   HandleScope scope(isolate);
5550   RUNTIME_ASSERT(args.length() == 2);
5551   CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
5552   CONVERT_ARG_HANDLE_CHECKED(Map, map, 1);
5553   JSObject::TransitionElementsKind(array, map->elements_kind());
5554   return *array;
5555 }
5556
5557
5558 // Set the native flag on the function.
5559 // This is used to decide if we should transform null and undefined
5560 // into the global object when doing call and apply.
5561 RUNTIME_FUNCTION(Runtime_SetNativeFlag) {
5562   SealHandleScope shs(isolate);
5563   RUNTIME_ASSERT(args.length() == 1);
5564
5565   CONVERT_ARG_CHECKED(Object, object, 0);
5566
5567   if (object->IsJSFunction()) {
5568     JSFunction* func = JSFunction::cast(object);
5569     func->shared()->set_native(true);
5570   }
5571   return isolate->heap()->undefined_value();
5572 }
5573
5574
5575 RUNTIME_FUNCTION(Runtime_SetInlineBuiltinFlag) {
5576   SealHandleScope shs(isolate);
5577   RUNTIME_ASSERT(args.length() == 1);
5578   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
5579
5580   if (object->IsJSFunction()) {
5581     JSFunction* func = JSFunction::cast(*object);
5582     func->shared()->set_inline_builtin(true);
5583   }
5584   return isolate->heap()->undefined_value();
5585 }
5586
5587
5588 RUNTIME_FUNCTION(Runtime_StoreArrayLiteralElement) {
5589   HandleScope scope(isolate);
5590   RUNTIME_ASSERT(args.length() == 5);
5591   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
5592   CONVERT_SMI_ARG_CHECKED(store_index, 1);
5593   CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
5594   CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 3);
5595   CONVERT_SMI_ARG_CHECKED(literal_index, 4);
5596
5597   Object* raw_literal_cell = literals->get(literal_index);
5598   JSArray* boilerplate = NULL;
5599   if (raw_literal_cell->IsAllocationSite()) {
5600     AllocationSite* site = AllocationSite::cast(raw_literal_cell);
5601     boilerplate = JSArray::cast(site->transition_info());
5602   } else {
5603     boilerplate = JSArray::cast(raw_literal_cell);
5604   }
5605   Handle<JSArray> boilerplate_object(boilerplate);
5606   ElementsKind elements_kind = object->GetElementsKind();
5607   ASSERT(IsFastElementsKind(elements_kind));
5608   // Smis should never trigger transitions.
5609   ASSERT(!value->IsSmi());
5610
5611   if (value->IsNumber()) {
5612     ASSERT(IsFastSmiElementsKind(elements_kind));
5613     ElementsKind transitioned_kind = IsFastHoleyElementsKind(elements_kind)
5614         ? FAST_HOLEY_DOUBLE_ELEMENTS
5615         : FAST_DOUBLE_ELEMENTS;
5616     if (IsMoreGeneralElementsKindTransition(
5617             boilerplate_object->GetElementsKind(),
5618             transitioned_kind)) {
5619       JSObject::TransitionElementsKind(boilerplate_object, transitioned_kind);
5620     }
5621     JSObject::TransitionElementsKind(object, transitioned_kind);
5622     ASSERT(IsFastDoubleElementsKind(object->GetElementsKind()));
5623     FixedDoubleArray* double_array = FixedDoubleArray::cast(object->elements());
5624     HeapNumber* number = HeapNumber::cast(*value);
5625     double_array->set(store_index, number->Number());
5626   } else {
5627     ASSERT(IsFastSmiElementsKind(elements_kind) ||
5628            IsFastDoubleElementsKind(elements_kind));
5629     ElementsKind transitioned_kind = IsFastHoleyElementsKind(elements_kind)
5630         ? FAST_HOLEY_ELEMENTS
5631         : FAST_ELEMENTS;
5632     JSObject::TransitionElementsKind(object, transitioned_kind);
5633     if (IsMoreGeneralElementsKindTransition(
5634             boilerplate_object->GetElementsKind(),
5635             transitioned_kind)) {
5636       JSObject::TransitionElementsKind(boilerplate_object, transitioned_kind);
5637     }
5638     FixedArray* object_array = FixedArray::cast(object->elements());
5639     object_array->set(store_index, *value);
5640   }
5641   return *object;
5642 }
5643
5644
5645 // Check whether debugger and is about to step into the callback that is passed
5646 // to a built-in function such as Array.forEach.
5647 RUNTIME_FUNCTION(Runtime_DebugCallbackSupportsStepping) {
5648   ASSERT(args.length() == 1);
5649   if (!isolate->IsDebuggerActive() || !isolate->debug()->StepInActive()) {
5650     return isolate->heap()->false_value();
5651   }
5652   CONVERT_ARG_CHECKED(Object, callback, 0);
5653   // We do not step into the callback if it's a builtin or not even a function.
5654   return isolate->heap()->ToBoolean(
5655       callback->IsJSFunction() && !JSFunction::cast(callback)->IsBuiltin());
5656 }
5657
5658
5659 // Set one shot breakpoints for the callback function that is passed to a
5660 // built-in function such as Array.forEach to enable stepping into the callback.
5661 RUNTIME_FUNCTION(Runtime_DebugPrepareStepInIfStepping) {
5662   ASSERT(args.length() == 1);
5663   Debug* debug = isolate->debug();
5664   if (!debug->IsStepping()) return isolate->heap()->undefined_value();
5665   CONVERT_ARG_HANDLE_CHECKED(JSFunction, callback, 0);
5666   HandleScope scope(isolate);
5667   // When leaving the callback, step out has been activated, but not performed
5668   // if we do not leave the builtin.  To be able to step into the callback
5669   // again, we need to clear the step out at this point.
5670   debug->ClearStepOut();
5671   debug->FloodWithOneShot(callback);
5672   return isolate->heap()->undefined_value();
5673 }
5674
5675
5676 // The argument is a closure that is kept until the epilogue is called.
5677 // On exception, the closure is called, which returns the promise if the
5678 // exception is considered uncaught, or undefined otherwise.
5679 RUNTIME_FUNCTION(Runtime_DebugPromiseHandlePrologue) {
5680   ASSERT(args.length() == 1);
5681   HandleScope scope(isolate);
5682   CONVERT_ARG_HANDLE_CHECKED(JSFunction, promise_getter, 0);
5683   isolate->debug()->PromiseHandlePrologue(promise_getter);
5684   return isolate->heap()->undefined_value();
5685 }
5686
5687
5688 RUNTIME_FUNCTION(Runtime_DebugPromiseHandleEpilogue) {
5689   ASSERT(args.length() == 0);
5690   SealHandleScope shs(isolate);
5691   isolate->debug()->PromiseHandleEpilogue();
5692   return isolate->heap()->undefined_value();
5693 }
5694
5695
5696 // Set a local property, even if it is READ_ONLY.  If the property does not
5697 // exist, it will be added with attributes NONE.
5698 RUNTIME_FUNCTION(Runtime_IgnoreAttributesAndSetProperty) {
5699   HandleScope scope(isolate);
5700   RUNTIME_ASSERT(args.length() == 3 || args.length() == 4);
5701   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
5702   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
5703   CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
5704   // Compute attributes.
5705   PropertyAttributes attributes = NONE;
5706   if (args.length() == 4) {
5707     CONVERT_SMI_ARG_CHECKED(unchecked_value, 3);
5708     // Only attribute bits should be set.
5709     RUNTIME_ASSERT(
5710         (unchecked_value & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
5711     attributes = static_cast<PropertyAttributes>(unchecked_value);
5712   }
5713   Handle<Object> result;
5714   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
5715       isolate, result,
5716       JSObject::SetLocalPropertyIgnoreAttributes(
5717           object, name, value, attributes));
5718   return *result;
5719 }
5720
5721
5722 RUNTIME_FUNCTION(Runtime_DeleteProperty) {
5723   HandleScope scope(isolate);
5724   ASSERT(args.length() == 3);
5725   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
5726   CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
5727   CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 2);
5728   JSReceiver::DeleteMode delete_mode = strict_mode == STRICT
5729       ? JSReceiver::STRICT_DELETION : JSReceiver::NORMAL_DELETION;
5730   Handle<Object> result;
5731   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
5732       isolate, result,
5733       JSReceiver::DeleteProperty(object, key, delete_mode));
5734   return *result;
5735 }
5736
5737
5738 static Object* HasLocalPropertyImplementation(Isolate* isolate,
5739                                               Handle<JSObject> object,
5740                                               Handle<Name> key) {
5741   if (JSReceiver::HasLocalProperty(object, key)) {
5742     return isolate->heap()->true_value();
5743   }
5744   // Handle hidden prototypes.  If there's a hidden prototype above this thing
5745   // then we have to check it for properties, because they are supposed to
5746   // look like they are on this object.
5747   Handle<Object> proto(object->GetPrototype(), isolate);
5748   if (proto->IsJSObject() &&
5749       Handle<JSObject>::cast(proto)->map()->is_hidden_prototype()) {
5750     return HasLocalPropertyImplementation(isolate,
5751                                           Handle<JSObject>::cast(proto),
5752                                           key);
5753   }
5754   RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
5755   return isolate->heap()->false_value();
5756 }
5757
5758
5759 RUNTIME_FUNCTION(Runtime_HasLocalProperty) {
5760   HandleScope scope(isolate);
5761   ASSERT(args.length() == 2);
5762   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0)
5763   CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
5764
5765   uint32_t index;
5766   const bool key_is_array_index = key->AsArrayIndex(&index);
5767
5768   // Only JS objects can have properties.
5769   if (object->IsJSObject()) {
5770     Handle<JSObject> js_obj = Handle<JSObject>::cast(object);
5771     // Fast case: either the key is a real named property or it is not
5772     // an array index and there are no interceptors or hidden
5773     // prototypes.
5774     if (JSObject::HasRealNamedProperty(js_obj, key)) {
5775       ASSERT(!isolate->has_scheduled_exception());
5776       return isolate->heap()->true_value();
5777     } else {
5778       RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
5779     }
5780     Map* map = js_obj->map();
5781     if (!key_is_array_index &&
5782         !map->has_named_interceptor() &&
5783         !HeapObject::cast(map->prototype())->map()->is_hidden_prototype()) {
5784       return isolate->heap()->false_value();
5785     }
5786     // Slow case.
5787     return HasLocalPropertyImplementation(isolate,
5788                                           Handle<JSObject>(js_obj),
5789                                           Handle<Name>(key));
5790   } else if (object->IsString() && key_is_array_index) {
5791     // Well, there is one exception:  Handle [] on strings.
5792     Handle<String> string = Handle<String>::cast(object);
5793     if (index < static_cast<uint32_t>(string->length())) {
5794       return isolate->heap()->true_value();
5795     }
5796   }
5797   return isolate->heap()->false_value();
5798 }
5799
5800
5801 RUNTIME_FUNCTION(Runtime_HasProperty) {
5802   HandleScope scope(isolate);
5803   ASSERT(args.length() == 2);
5804   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
5805   CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
5806
5807   bool result = JSReceiver::HasProperty(receiver, key);
5808   RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
5809   if (isolate->has_pending_exception()) return isolate->heap()->exception();
5810   return isolate->heap()->ToBoolean(result);
5811 }
5812
5813
5814 RUNTIME_FUNCTION(Runtime_HasElement) {
5815   HandleScope scope(isolate);
5816   ASSERT(args.length() == 2);
5817   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
5818   CONVERT_SMI_ARG_CHECKED(index, 1);
5819
5820   bool result = JSReceiver::HasElement(receiver, index);
5821   RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
5822   return isolate->heap()->ToBoolean(result);
5823 }
5824
5825
5826 RUNTIME_FUNCTION(Runtime_IsPropertyEnumerable) {
5827   HandleScope scope(isolate);
5828   ASSERT(args.length() == 2);
5829
5830   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
5831   CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
5832
5833   PropertyAttributes att = JSReceiver::GetLocalPropertyAttribute(object, key);
5834   if (att == ABSENT || (att & DONT_ENUM) != 0) {
5835     RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
5836     return isolate->heap()->false_value();
5837   }
5838   ASSERT(!isolate->has_scheduled_exception());
5839   return isolate->heap()->true_value();
5840 }
5841
5842
5843 RUNTIME_FUNCTION(Runtime_GetPropertyNames) {
5844   HandleScope scope(isolate);
5845   ASSERT(args.length() == 1);
5846   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
5847   Handle<JSArray> result;
5848
5849   isolate->counters()->for_in()->Increment();
5850   Handle<FixedArray> elements;
5851   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
5852       isolate, elements,
5853       JSReceiver::GetKeys(object, JSReceiver::INCLUDE_PROTOS));
5854   return *isolate->factory()->NewJSArrayWithElements(elements);
5855 }
5856
5857
5858 // Returns either a FixedArray as Runtime_GetPropertyNames,
5859 // or, if the given object has an enum cache that contains
5860 // all enumerable properties of the object and its prototypes
5861 // have none, the map of the object. This is used to speed up
5862 // the check for deletions during a for-in.
5863 RUNTIME_FUNCTION(Runtime_GetPropertyNamesFast) {
5864   SealHandleScope shs(isolate);
5865   ASSERT(args.length() == 1);
5866
5867   CONVERT_ARG_CHECKED(JSReceiver, raw_object, 0);
5868
5869   if (raw_object->IsSimpleEnum()) return raw_object->map();
5870
5871   HandleScope scope(isolate);
5872   Handle<JSReceiver> object(raw_object);
5873   Handle<FixedArray> content;
5874   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
5875       isolate, content,
5876       JSReceiver::GetKeys(object, JSReceiver::INCLUDE_PROTOS));
5877
5878   // Test again, since cache may have been built by preceding call.
5879   if (object->IsSimpleEnum()) return object->map();
5880
5881   return *content;
5882 }
5883
5884
5885 // Find the length of the prototype chain that is to to handled as one. If a
5886 // prototype object is hidden it is to be viewed as part of the the object it
5887 // is prototype for.
5888 static int LocalPrototypeChainLength(JSObject* obj) {
5889   int count = 1;
5890   Object* proto = obj->GetPrototype();
5891   while (proto->IsJSObject() &&
5892          JSObject::cast(proto)->map()->is_hidden_prototype()) {
5893     count++;
5894     proto = JSObject::cast(proto)->GetPrototype();
5895   }
5896   return count;
5897 }
5898
5899
5900 // Return the names of the local named properties.
5901 // args[0]: object
5902 // args[1]: PropertyAttributes as int
5903 RUNTIME_FUNCTION(Runtime_GetLocalPropertyNames) {
5904   HandleScope scope(isolate);
5905   ASSERT(args.length() == 2);
5906   if (!args[0]->IsJSObject()) {
5907     return isolate->heap()->undefined_value();
5908   }
5909   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
5910   CONVERT_SMI_ARG_CHECKED(filter_value, 1);
5911   PropertyAttributes filter = static_cast<PropertyAttributes>(filter_value);
5912
5913   // Skip the global proxy as it has no properties and always delegates to the
5914   // real global object.
5915   if (obj->IsJSGlobalProxy()) {
5916     // Only collect names if access is permitted.
5917     if (obj->IsAccessCheckNeeded() &&
5918         !isolate->MayNamedAccess(
5919             obj, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) {
5920       isolate->ReportFailedAccessCheck(obj, v8::ACCESS_KEYS);
5921       RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
5922       return *isolate->factory()->NewJSArray(0);
5923     }
5924     obj = Handle<JSObject>(JSObject::cast(obj->GetPrototype()));
5925   }
5926
5927   // Find the number of objects making up this.
5928   int length = LocalPrototypeChainLength(*obj);
5929
5930   // Find the number of local properties for each of the objects.
5931   ScopedVector<int> local_property_count(length);
5932   int total_property_count = 0;
5933   Handle<JSObject> jsproto = obj;
5934   for (int i = 0; i < length; i++) {
5935     // Only collect names if access is permitted.
5936     if (jsproto->IsAccessCheckNeeded() &&
5937         !isolate->MayNamedAccess(
5938             jsproto, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) {
5939       isolate->ReportFailedAccessCheck(jsproto, v8::ACCESS_KEYS);
5940       RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
5941       return *isolate->factory()->NewJSArray(0);
5942     }
5943     int n;
5944     n = jsproto->NumberOfLocalProperties(filter);
5945     local_property_count[i] = n;
5946     total_property_count += n;
5947     if (i < length - 1) {
5948       jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype()));
5949     }
5950   }
5951
5952   // Allocate an array with storage for all the property names.
5953   Handle<FixedArray> names =
5954       isolate->factory()->NewFixedArray(total_property_count);
5955
5956   // Get the property names.
5957   jsproto = obj;
5958   int next_copy_index = 0;
5959   int hidden_strings = 0;
5960   for (int i = 0; i < length; i++) {
5961     jsproto->GetLocalPropertyNames(*names, next_copy_index, filter);
5962     if (i > 0) {
5963       // Names from hidden prototypes may already have been added
5964       // for inherited function template instances. Count the duplicates
5965       // and stub them out; the final copy pass at the end ignores holes.
5966       for (int j = next_copy_index;
5967            j < next_copy_index + local_property_count[i];
5968            j++) {
5969         Object* name_from_hidden_proto = names->get(j);
5970         for (int k = 0; k < next_copy_index; k++) {
5971           if (names->get(k) != isolate->heap()->hidden_string()) {
5972             Object* name = names->get(k);
5973             if (name_from_hidden_proto == name) {
5974               names->set(j, isolate->heap()->hidden_string());
5975               hidden_strings++;
5976               break;
5977             }
5978           }
5979         }
5980       }
5981     }
5982     next_copy_index += local_property_count[i];
5983
5984     // Hidden properties only show up if the filter does not skip strings.
5985     if ((filter & STRING) == 0 && JSObject::HasHiddenProperties(jsproto)) {
5986       hidden_strings++;
5987     }
5988     if (i < length - 1) {
5989       jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype()));
5990     }
5991   }
5992
5993   // Filter out name of hidden properties object and
5994   // hidden prototype duplicates.
5995   if (hidden_strings > 0) {
5996     Handle<FixedArray> old_names = names;
5997     names = isolate->factory()->NewFixedArray(
5998         names->length() - hidden_strings);
5999     int dest_pos = 0;
6000     for (int i = 0; i < total_property_count; i++) {
6001       Object* name = old_names->get(i);
6002       if (name == isolate->heap()->hidden_string()) {
6003         hidden_strings--;
6004         continue;
6005       }
6006       names->set(dest_pos++, name);
6007     }
6008     ASSERT_EQ(0, hidden_strings);
6009   }
6010
6011   return *isolate->factory()->NewJSArrayWithElements(names);
6012 }
6013
6014
6015 // Return the names of the local indexed properties.
6016 // args[0]: object
6017 RUNTIME_FUNCTION(Runtime_GetLocalElementNames) {
6018   HandleScope scope(isolate);
6019   ASSERT(args.length() == 1);
6020   if (!args[0]->IsJSObject()) {
6021     return isolate->heap()->undefined_value();
6022   }
6023   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
6024
6025   int n = obj->NumberOfLocalElements(static_cast<PropertyAttributes>(NONE));
6026   Handle<FixedArray> names = isolate->factory()->NewFixedArray(n);
6027   obj->GetLocalElementKeys(*names, static_cast<PropertyAttributes>(NONE));
6028   return *isolate->factory()->NewJSArrayWithElements(names);
6029 }
6030
6031
6032 // Return information on whether an object has a named or indexed interceptor.
6033 // args[0]: object
6034 RUNTIME_FUNCTION(Runtime_GetInterceptorInfo) {
6035   HandleScope scope(isolate);
6036   ASSERT(args.length() == 1);
6037   if (!args[0]->IsJSObject()) {
6038     return Smi::FromInt(0);
6039   }
6040   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
6041
6042   int result = 0;
6043   if (obj->HasNamedInterceptor()) result |= 2;
6044   if (obj->HasIndexedInterceptor()) result |= 1;
6045
6046   return Smi::FromInt(result);
6047 }
6048
6049
6050 // Return property names from named interceptor.
6051 // args[0]: object
6052 RUNTIME_FUNCTION(Runtime_GetNamedInterceptorPropertyNames) {
6053   HandleScope scope(isolate);
6054   ASSERT(args.length() == 1);
6055   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
6056
6057   if (obj->HasNamedInterceptor()) {
6058     Handle<JSObject> result;
6059     if (JSObject::GetKeysForNamedInterceptor(obj, obj).ToHandle(&result)) {
6060       return *result;
6061     }
6062   }
6063   return isolate->heap()->undefined_value();
6064 }
6065
6066
6067 // Return element names from indexed interceptor.
6068 // args[0]: object
6069 RUNTIME_FUNCTION(Runtime_GetIndexedInterceptorElementNames) {
6070   HandleScope scope(isolate);
6071   ASSERT(args.length() == 1);
6072   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
6073
6074   if (obj->HasIndexedInterceptor()) {
6075     Handle<JSObject> result;
6076     if (JSObject::GetKeysForIndexedInterceptor(obj, obj).ToHandle(&result)) {
6077       return *result;
6078     }
6079   }
6080   return isolate->heap()->undefined_value();
6081 }
6082
6083
6084 RUNTIME_FUNCTION(Runtime_LocalKeys) {
6085   HandleScope scope(isolate);
6086   ASSERT(args.length() == 1);
6087   CONVERT_ARG_CHECKED(JSObject, raw_object, 0);
6088   Handle<JSObject> object(raw_object);
6089
6090   if (object->IsJSGlobalProxy()) {
6091     // Do access checks before going to the global object.
6092     if (object->IsAccessCheckNeeded() &&
6093         !isolate->MayNamedAccess(
6094             object, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) {
6095       isolate->ReportFailedAccessCheck(object, v8::ACCESS_KEYS);
6096       RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
6097       return *isolate->factory()->NewJSArray(0);
6098     }
6099
6100     Handle<Object> proto(object->GetPrototype(), isolate);
6101     // If proxy is detached we simply return an empty array.
6102     if (proto->IsNull()) return *isolate->factory()->NewJSArray(0);
6103     object = Handle<JSObject>::cast(proto);
6104   }
6105
6106   Handle<FixedArray> contents;
6107   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
6108       isolate, contents,
6109       JSReceiver::GetKeys(object, JSReceiver::LOCAL_ONLY));
6110
6111   // Some fast paths through GetKeysInFixedArrayFor reuse a cached
6112   // property array and since the result is mutable we have to create
6113   // a fresh clone on each invocation.
6114   int length = contents->length();
6115   Handle<FixedArray> copy = isolate->factory()->NewFixedArray(length);
6116   for (int i = 0; i < length; i++) {
6117     Object* entry = contents->get(i);
6118     if (entry->IsString()) {
6119       copy->set(i, entry);
6120     } else {
6121       ASSERT(entry->IsNumber());
6122       HandleScope scope(isolate);
6123       Handle<Object> entry_handle(entry, isolate);
6124       Handle<Object> entry_str =
6125           isolate->factory()->NumberToString(entry_handle);
6126       copy->set(i, *entry_str);
6127     }
6128   }
6129   return *isolate->factory()->NewJSArrayWithElements(copy);
6130 }
6131
6132
6133 RUNTIME_FUNCTION(Runtime_GetArgumentsProperty) {
6134   SealHandleScope shs(isolate);
6135   ASSERT(args.length() == 1);
6136   CONVERT_ARG_HANDLE_CHECKED(Object, raw_key, 0);
6137
6138   // Compute the frame holding the arguments.
6139   JavaScriptFrameIterator it(isolate);
6140   it.AdvanceToArgumentsFrame();
6141   JavaScriptFrame* frame = it.frame();
6142
6143   // Get the actual number of provided arguments.
6144   const uint32_t n = frame->ComputeParametersCount();
6145
6146   // Try to convert the key to an index. If successful and within
6147   // index return the the argument from the frame.
6148   uint32_t index;
6149   if (raw_key->ToArrayIndex(&index) && index < n) {
6150     return frame->GetParameter(index);
6151   }
6152
6153   HandleScope scope(isolate);
6154   if (raw_key->IsSymbol()) {
6155     // Lookup in the initial Object.prototype object.
6156     Handle<Object> result;
6157     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
6158         isolate, result,
6159         Object::GetProperty(isolate->initial_object_prototype(),
6160                             Handle<Symbol>::cast(raw_key)));
6161     return *result;
6162   }
6163
6164   // Convert the key to a string.
6165   Handle<Object> converted;
6166   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
6167       isolate, converted, Execution::ToString(isolate, raw_key));
6168   Handle<String> key = Handle<String>::cast(converted);
6169
6170   // Try to convert the string key into an array index.
6171   if (key->AsArrayIndex(&index)) {
6172     if (index < n) {
6173       return frame->GetParameter(index);
6174     } else {
6175       Handle<Object> initial_prototype(isolate->initial_object_prototype());
6176       Handle<Object> result;
6177       ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
6178           isolate, result,
6179           Object::GetElement(isolate, initial_prototype, index));
6180       return *result;
6181     }
6182   }
6183
6184   // Handle special arguments properties.
6185   if (String::Equals(isolate->factory()->length_string(), key)) {
6186     return Smi::FromInt(n);
6187   }
6188   if (String::Equals(isolate->factory()->callee_string(), key)) {
6189     JSFunction* function = frame->function();
6190     if (function->shared()->strict_mode() == STRICT) {
6191       return isolate->Throw(*isolate->factory()->NewTypeError(
6192           "strict_arguments_callee", HandleVector<Object>(NULL, 0)));
6193     }
6194     return function;
6195   }
6196
6197   // Lookup in the initial Object.prototype object.
6198   Handle<Object> result;
6199   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
6200       isolate, result,
6201       Object::GetProperty(isolate->initial_object_prototype(), key));
6202   return *result;
6203 }
6204
6205
6206 RUNTIME_FUNCTION(Runtime_ToFastProperties) {
6207   HandleScope scope(isolate);
6208   ASSERT(args.length() == 1);
6209   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
6210   if (object->IsJSObject() && !object->IsGlobalObject()) {
6211     JSObject::TransformToFastProperties(Handle<JSObject>::cast(object), 0);
6212   }
6213   return *object;
6214 }
6215
6216
6217 RUNTIME_FUNCTION(Runtime_ToBool) {
6218   SealHandleScope shs(isolate);
6219   ASSERT(args.length() == 1);
6220   CONVERT_ARG_CHECKED(Object, object, 0);
6221
6222   return isolate->heap()->ToBoolean(object->BooleanValue());
6223 }
6224
6225
6226 // Returns the type string of a value; see ECMA-262, 11.4.3 (p 47).
6227 // Possible optimizations: put the type string into the oddballs.
6228 RUNTIME_FUNCTION(Runtime_Typeof) {
6229   SealHandleScope shs(isolate);
6230   ASSERT(args.length() == 1);
6231   CONVERT_ARG_CHECKED(Object, obj, 0);
6232   if (obj->IsNumber()) return isolate->heap()->number_string();
6233   if (obj->IsFloat32x4()) return isolate->heap()->float32x4_string();
6234   if (obj->IsFloat64x2()) return isolate->heap()->float64x2_string();
6235   if (obj->IsInt32x4()) return isolate->heap()->int32x4_string();
6236   HeapObject* heap_obj = HeapObject::cast(obj);
6237
6238   // typeof an undetectable object is 'undefined'
6239   if (heap_obj->map()->is_undetectable()) {
6240     return isolate->heap()->undefined_string();
6241   }
6242
6243   InstanceType instance_type = heap_obj->map()->instance_type();
6244   if (instance_type < FIRST_NONSTRING_TYPE) {
6245     return isolate->heap()->string_string();
6246   }
6247
6248   switch (instance_type) {
6249     case ODDBALL_TYPE:
6250       if (heap_obj->IsTrue() || heap_obj->IsFalse()) {
6251         return isolate->heap()->boolean_string();
6252       }
6253       if (heap_obj->IsNull()) {
6254         return FLAG_harmony_typeof
6255             ? isolate->heap()->null_string()
6256             : isolate->heap()->object_string();
6257       }
6258       ASSERT(heap_obj->IsUndefined());
6259       return isolate->heap()->undefined_string();
6260     case SYMBOL_TYPE:
6261       return isolate->heap()->symbol_string();
6262     case JS_FUNCTION_TYPE:
6263     case JS_FUNCTION_PROXY_TYPE:
6264       return isolate->heap()->function_string();
6265     default:
6266       // For any kind of object not handled above, the spec rule for
6267       // host objects gives that it is okay to return "object"
6268       return isolate->heap()->object_string();
6269   }
6270 }
6271
6272
6273 static bool AreDigits(const uint8_t*s, int from, int to) {
6274   for (int i = from; i < to; i++) {
6275     if (s[i] < '0' || s[i] > '9') return false;
6276   }
6277
6278   return true;
6279 }
6280
6281
6282 static int ParseDecimalInteger(const uint8_t*s, int from, int to) {
6283   ASSERT(to - from < 10);  // Overflow is not possible.
6284   ASSERT(from < to);
6285   int d = s[from] - '0';
6286
6287   for (int i = from + 1; i < to; i++) {
6288     d = 10 * d + (s[i] - '0');
6289   }
6290
6291   return d;
6292 }
6293
6294
6295 RUNTIME_FUNCTION(Runtime_StringToNumber) {
6296   HandleScope handle_scope(isolate);
6297   ASSERT(args.length() == 1);
6298   CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
6299   subject = String::Flatten(subject);
6300
6301   // Fast case: short integer or some sorts of junk values.
6302   if (subject->IsSeqOneByteString()) {
6303     int len = subject->length();
6304     if (len == 0) return Smi::FromInt(0);
6305
6306     DisallowHeapAllocation no_gc;
6307     uint8_t const* data = Handle<SeqOneByteString>::cast(subject)->GetChars();
6308     bool minus = (data[0] == '-');
6309     int start_pos = (minus ? 1 : 0);
6310
6311     if (start_pos == len) {
6312       return isolate->heap()->nan_value();
6313     } else if (data[start_pos] > '9') {
6314       // Fast check for a junk value. A valid string may start from a
6315       // whitespace, a sign ('+' or '-'), the decimal point, a decimal digit
6316       // or the 'I' character ('Infinity'). All of that have codes not greater
6317       // than '9' except 'I' and &nbsp;.
6318       if (data[start_pos] != 'I' && data[start_pos] != 0xa0) {
6319         return isolate->heap()->nan_value();
6320       }
6321     } else if (len - start_pos < 10 && AreDigits(data, start_pos, len)) {
6322       // The maximal/minimal smi has 10 digits. If the string has less digits
6323       // we know it will fit into the smi-data type.
6324       int d = ParseDecimalInteger(data, start_pos, len);
6325       if (minus) {
6326         if (d == 0) return isolate->heap()->minus_zero_value();
6327         d = -d;
6328       } else if (!subject->HasHashCode() &&
6329                  len <= String::kMaxArrayIndexSize &&
6330                  (len == 1 || data[0] != '0')) {
6331         // String hash is not calculated yet but all the data are present.
6332         // Update the hash field to speed up sequential convertions.
6333         uint32_t hash = StringHasher::MakeArrayIndexHash(d, len);
6334 #ifdef DEBUG
6335         subject->Hash();  // Force hash calculation.
6336         ASSERT_EQ(static_cast<int>(subject->hash_field()),
6337                   static_cast<int>(hash));
6338 #endif
6339         subject->set_hash_field(hash);
6340       }
6341       return Smi::FromInt(d);
6342     }
6343   }
6344
6345   // Slower case.
6346   int flags = ALLOW_HEX;
6347   if (FLAG_harmony_numeric_literals) {
6348     // The current spec draft has not updated "ToNumber Applied to the String
6349     // Type", https://bugs.ecmascript.org/show_bug.cgi?id=1584
6350     flags |= ALLOW_OCTAL | ALLOW_BINARY;
6351   }
6352
6353   return *isolate->factory()->NewNumber(StringToDouble(
6354       isolate->unicode_cache(), *subject, flags));
6355 }
6356
6357
6358 RUNTIME_FUNCTION(Runtime_NewString) {
6359   HandleScope scope(isolate);
6360   ASSERT(args.length() == 2);
6361   CONVERT_SMI_ARG_CHECKED(length, 0);
6362   CONVERT_BOOLEAN_ARG_CHECKED(is_one_byte, 1);
6363   if (length == 0) return isolate->heap()->empty_string();
6364   Handle<String> result;
6365   if (is_one_byte) {
6366     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
6367         isolate, result, isolate->factory()->NewRawOneByteString(length));
6368   } else {
6369     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
6370         isolate, result, isolate->factory()->NewRawTwoByteString(length));
6371   }
6372   return *result;
6373 }
6374
6375
6376 RUNTIME_FUNCTION(Runtime_TruncateString) {
6377   HandleScope scope(isolate);
6378   ASSERT(args.length() == 2);
6379   CONVERT_ARG_HANDLE_CHECKED(SeqString, string, 0);
6380   CONVERT_SMI_ARG_CHECKED(new_length, 1);
6381   RUNTIME_ASSERT(new_length >= 0);
6382   return *SeqString::Truncate(string, new_length);
6383 }
6384
6385
6386 RUNTIME_FUNCTION(Runtime_URIEscape) {
6387   HandleScope scope(isolate);
6388   ASSERT(args.length() == 1);
6389   CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
6390   Handle<String> string = String::Flatten(source);
6391   ASSERT(string->IsFlat());
6392   Handle<String> result;
6393   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
6394       isolate, result,
6395       string->IsOneByteRepresentationUnderneath()
6396             ? URIEscape::Escape<uint8_t>(isolate, source)
6397             : URIEscape::Escape<uc16>(isolate, source));
6398   return *result;
6399 }
6400
6401
6402 RUNTIME_FUNCTION(Runtime_URIUnescape) {
6403   HandleScope scope(isolate);
6404   ASSERT(args.length() == 1);
6405   CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
6406   Handle<String> string = String::Flatten(source);
6407   ASSERT(string->IsFlat());
6408   Handle<String> result;
6409   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
6410       isolate, result,
6411       string->IsOneByteRepresentationUnderneath()
6412             ? URIUnescape::Unescape<uint8_t>(isolate, source)
6413             : URIUnescape::Unescape<uc16>(isolate, source));
6414   return *result;
6415 }
6416
6417
6418 RUNTIME_FUNCTION(Runtime_QuoteJSONString) {
6419   HandleScope scope(isolate);
6420   CONVERT_ARG_HANDLE_CHECKED(String, string, 0);
6421   ASSERT(args.length() == 1);
6422   Handle<Object> result;
6423   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
6424       isolate, result, BasicJsonStringifier::StringifyString(isolate, string));
6425   return *result;
6426 }
6427
6428
6429 RUNTIME_FUNCTION(Runtime_BasicJSONStringify) {
6430   HandleScope scope(isolate);
6431   ASSERT(args.length() == 1);
6432   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
6433   BasicJsonStringifier stringifier(isolate);
6434   Handle<Object> result;
6435   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
6436       isolate, result, stringifier.Stringify(object));
6437   return *result;
6438 }
6439
6440
6441 RUNTIME_FUNCTION(Runtime_StringParseInt) {
6442   HandleScope handle_scope(isolate);
6443   ASSERT(args.length() == 2);
6444   CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
6445   CONVERT_NUMBER_CHECKED(int, radix, Int32, args[1]);
6446   RUNTIME_ASSERT(radix == 0 || (2 <= radix && radix <= 36));
6447
6448   subject = String::Flatten(subject);
6449   double value;
6450
6451   { DisallowHeapAllocation no_gc;
6452     String::FlatContent flat = subject->GetFlatContent();
6453
6454     // ECMA-262 section 15.1.2.3, empty string is NaN
6455     if (flat.IsAscii()) {
6456       value = StringToInt(
6457           isolate->unicode_cache(), flat.ToOneByteVector(), radix);
6458     } else {
6459       value = StringToInt(
6460           isolate->unicode_cache(), flat.ToUC16Vector(), radix);
6461     }
6462   }
6463
6464   return *isolate->factory()->NewNumber(value);
6465 }
6466
6467
6468 RUNTIME_FUNCTION(Runtime_StringParseFloat) {
6469   HandleScope shs(isolate);
6470   ASSERT(args.length() == 1);
6471   CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
6472
6473   subject = String::Flatten(subject);
6474   double value = StringToDouble(
6475       isolate->unicode_cache(), *subject, ALLOW_TRAILING_JUNK, OS::nan_value());
6476
6477   return *isolate->factory()->NewNumber(value);
6478 }
6479
6480
6481 static inline bool ToUpperOverflows(uc32 character) {
6482   // y with umlauts and the micro sign are the only characters that stop
6483   // fitting into one-byte when converting to uppercase.
6484   static const uc32 yuml_code = 0xff;
6485   static const uc32 micro_code = 0xb5;
6486   return (character == yuml_code || character == micro_code);
6487 }
6488
6489
6490 template <class Converter>
6491 MUST_USE_RESULT static Object* ConvertCaseHelper(
6492     Isolate* isolate,
6493     String* string,
6494     SeqString* result,
6495     int result_length,
6496     unibrow::Mapping<Converter, 128>* mapping) {
6497   DisallowHeapAllocation no_gc;
6498   // We try this twice, once with the assumption that the result is no longer
6499   // than the input and, if that assumption breaks, again with the exact
6500   // length.  This may not be pretty, but it is nicer than what was here before
6501   // and I hereby claim my vaffel-is.
6502   //
6503   // NOTE: This assumes that the upper/lower case of an ASCII
6504   // character is also ASCII.  This is currently the case, but it
6505   // might break in the future if we implement more context and locale
6506   // dependent upper/lower conversions.
6507   bool has_changed_character = false;
6508
6509   // Convert all characters to upper case, assuming that they will fit
6510   // in the buffer
6511   Access<ConsStringIteratorOp> op(
6512       isolate->runtime_state()->string_iterator());
6513   StringCharacterStream stream(string, op.value());
6514   unibrow::uchar chars[Converter::kMaxWidth];
6515   // We can assume that the string is not empty
6516   uc32 current = stream.GetNext();
6517   bool ignore_overflow = Converter::kIsToLower || result->IsSeqTwoByteString();
6518   for (int i = 0; i < result_length;) {
6519     bool has_next = stream.HasMore();
6520     uc32 next = has_next ? stream.GetNext() : 0;
6521     int char_length = mapping->get(current, next, chars);
6522     if (char_length == 0) {
6523       // The case conversion of this character is the character itself.
6524       result->Set(i, current);
6525       i++;
6526     } else if (char_length == 1 &&
6527                (ignore_overflow || !ToUpperOverflows(current))) {
6528       // Common case: converting the letter resulted in one character.
6529       ASSERT(static_cast<uc32>(chars[0]) != current);
6530       result->Set(i, chars[0]);
6531       has_changed_character = true;
6532       i++;
6533     } else if (result_length == string->length()) {
6534       bool overflows = ToUpperOverflows(current);
6535       // We've assumed that the result would be as long as the
6536       // input but here is a character that converts to several
6537       // characters.  No matter, we calculate the exact length
6538       // of the result and try the whole thing again.
6539       //
6540       // Note that this leaves room for optimization.  We could just
6541       // memcpy what we already have to the result string.  Also,
6542       // the result string is the last object allocated we could
6543       // "realloc" it and probably, in the vast majority of cases,
6544       // extend the existing string to be able to hold the full
6545       // result.
6546       int next_length = 0;
6547       if (has_next) {
6548         next_length = mapping->get(next, 0, chars);
6549         if (next_length == 0) next_length = 1;
6550       }
6551       int current_length = i + char_length + next_length;
6552       while (stream.HasMore()) {
6553         current = stream.GetNext();
6554         overflows |= ToUpperOverflows(current);
6555         // NOTE: we use 0 as the next character here because, while
6556         // the next character may affect what a character converts to,
6557         // it does not in any case affect the length of what it convert
6558         // to.
6559         int char_length = mapping->get(current, 0, chars);
6560         if (char_length == 0) char_length = 1;
6561         current_length += char_length;
6562         if (current_length > String::kMaxLength) {
6563           AllowHeapAllocation allocate_error_and_return;
6564           return isolate->ThrowInvalidStringLength();
6565         }
6566       }
6567       // Try again with the real length.  Return signed if we need
6568       // to allocate a two-byte string for to uppercase.
6569       return (overflows && !ignore_overflow) ? Smi::FromInt(-current_length)
6570                                              : Smi::FromInt(current_length);
6571     } else {
6572       for (int j = 0; j < char_length; j++) {
6573         result->Set(i, chars[j]);
6574         i++;
6575       }
6576       has_changed_character = true;
6577     }
6578     current = next;
6579   }
6580   if (has_changed_character) {
6581     return result;
6582   } else {
6583     // If we didn't actually change anything in doing the conversion
6584     // we simple return the result and let the converted string
6585     // become garbage; there is no reason to keep two identical strings
6586     // alive.
6587     return string;
6588   }
6589 }
6590
6591
6592 namespace {
6593
6594 static const uintptr_t kOneInEveryByte = kUintptrAllBitsSet / 0xFF;
6595 static const uintptr_t kAsciiMask = kOneInEveryByte << 7;
6596
6597 // Given a word and two range boundaries returns a word with high bit
6598 // set in every byte iff the corresponding input byte was strictly in
6599 // the range (m, n). All the other bits in the result are cleared.
6600 // This function is only useful when it can be inlined and the
6601 // boundaries are statically known.
6602 // Requires: all bytes in the input word and the boundaries must be
6603 // ASCII (less than 0x7F).
6604 static inline uintptr_t AsciiRangeMask(uintptr_t w, char m, char n) {
6605   // Use strict inequalities since in edge cases the function could be
6606   // further simplified.
6607   ASSERT(0 < m && m < n);
6608   // Has high bit set in every w byte less than n.
6609   uintptr_t tmp1 = kOneInEveryByte * (0x7F + n) - w;
6610   // Has high bit set in every w byte greater than m.
6611   uintptr_t tmp2 = w + kOneInEveryByte * (0x7F - m);
6612   return (tmp1 & tmp2 & (kOneInEveryByte * 0x80));
6613 }
6614
6615
6616 #ifdef DEBUG
6617 static bool CheckFastAsciiConvert(char* dst,
6618                                   const char* src,
6619                                   int length,
6620                                   bool changed,
6621                                   bool is_to_lower) {
6622   bool expected_changed = false;
6623   for (int i = 0; i < length; i++) {
6624     if (dst[i] == src[i]) continue;
6625     expected_changed = true;
6626     if (is_to_lower) {
6627       ASSERT('A' <= src[i] && src[i] <= 'Z');
6628       ASSERT(dst[i] == src[i] + ('a' - 'A'));
6629     } else {
6630       ASSERT('a' <= src[i] && src[i] <= 'z');
6631       ASSERT(dst[i] == src[i] - ('a' - 'A'));
6632     }
6633   }
6634   return (expected_changed == changed);
6635 }
6636 #endif
6637
6638
6639 template<class Converter>
6640 static bool FastAsciiConvert(char* dst,
6641                              const char* src,
6642                              int length,
6643                              bool* changed_out) {
6644 #ifdef DEBUG
6645     char* saved_dst = dst;
6646     const char* saved_src = src;
6647 #endif
6648   DisallowHeapAllocation no_gc;
6649   // We rely on the distance between upper and lower case letters
6650   // being a known power of 2.
6651   ASSERT('a' - 'A' == (1 << 5));
6652   // Boundaries for the range of input characters than require conversion.
6653   static const char lo = Converter::kIsToLower ? 'A' - 1 : 'a' - 1;
6654   static const char hi = Converter::kIsToLower ? 'Z' + 1 : 'z' + 1;
6655   bool changed = false;
6656   uintptr_t or_acc = 0;
6657   const char* const limit = src + length;
6658 #ifdef V8_HOST_CAN_READ_UNALIGNED
6659   // Process the prefix of the input that requires no conversion one
6660   // (machine) word at a time.
6661   while (src <= limit - sizeof(uintptr_t)) {
6662     const uintptr_t w = *reinterpret_cast<const uintptr_t*>(src);
6663     or_acc |= w;
6664     if (AsciiRangeMask(w, lo, hi) != 0) {
6665       changed = true;
6666       break;
6667     }
6668     *reinterpret_cast<uintptr_t*>(dst) = w;
6669     src += sizeof(uintptr_t);
6670     dst += sizeof(uintptr_t);
6671   }
6672   // Process the remainder of the input performing conversion when
6673   // required one word at a time.
6674   while (src <= limit - sizeof(uintptr_t)) {
6675     const uintptr_t w = *reinterpret_cast<const uintptr_t*>(src);
6676     or_acc |= w;
6677     uintptr_t m = AsciiRangeMask(w, lo, hi);
6678     // The mask has high (7th) bit set in every byte that needs
6679     // conversion and we know that the distance between cases is
6680     // 1 << 5.
6681     *reinterpret_cast<uintptr_t*>(dst) = w ^ (m >> 2);
6682     src += sizeof(uintptr_t);
6683     dst += sizeof(uintptr_t);
6684   }
6685 #endif
6686   // Process the last few bytes of the input (or the whole input if
6687   // unaligned access is not supported).
6688   while (src < limit) {
6689     char c = *src;
6690     or_acc |= c;
6691     if (lo < c && c < hi) {
6692       c ^= (1 << 5);
6693       changed = true;
6694     }
6695     *dst = c;
6696     ++src;
6697     ++dst;
6698   }
6699   if ((or_acc & kAsciiMask) != 0) {
6700     return false;
6701   }
6702
6703   ASSERT(CheckFastAsciiConvert(
6704              saved_dst, saved_src, length, changed, Converter::kIsToLower));
6705
6706   *changed_out = changed;
6707   return true;
6708 }
6709
6710 }  // namespace
6711
6712
6713 template <class Converter>
6714 MUST_USE_RESULT static Object* ConvertCase(
6715     Handle<String> s,
6716     Isolate* isolate,
6717     unibrow::Mapping<Converter, 128>* mapping) {
6718   s = String::Flatten(s);
6719   int length = s->length();
6720   // Assume that the string is not empty; we need this assumption later
6721   if (length == 0) return *s;
6722
6723   // Simpler handling of ASCII strings.
6724   //
6725   // NOTE: This assumes that the upper/lower case of an ASCII
6726   // character is also ASCII.  This is currently the case, but it
6727   // might break in the future if we implement more context and locale
6728   // dependent upper/lower conversions.
6729   if (s->IsOneByteRepresentationUnderneath()) {
6730     // Same length as input.
6731     Handle<SeqOneByteString> result =
6732         isolate->factory()->NewRawOneByteString(length).ToHandleChecked();
6733     DisallowHeapAllocation no_gc;
6734     String::FlatContent flat_content = s->GetFlatContent();
6735     ASSERT(flat_content.IsFlat());
6736     bool has_changed_character = false;
6737     bool is_ascii = FastAsciiConvert<Converter>(
6738         reinterpret_cast<char*>(result->GetChars()),
6739         reinterpret_cast<const char*>(flat_content.ToOneByteVector().start()),
6740         length,
6741         &has_changed_character);
6742     // If not ASCII, we discard the result and take the 2 byte path.
6743     if (is_ascii) return has_changed_character ? *result : *s;
6744   }
6745
6746   Handle<SeqString> result;  // Same length as input.
6747   if (s->IsOneByteRepresentation()) {
6748     result = isolate->factory()->NewRawOneByteString(length).ToHandleChecked();
6749   } else {
6750     result = isolate->factory()->NewRawTwoByteString(length).ToHandleChecked();
6751   }
6752
6753   Object* answer = ConvertCaseHelper(isolate, *s, *result, length, mapping);
6754   if (answer->IsException() || answer->IsString()) return answer;
6755
6756   ASSERT(answer->IsSmi());
6757   length = Smi::cast(answer)->value();
6758   if (s->IsOneByteRepresentation() && length > 0) {
6759     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
6760         isolate, result, isolate->factory()->NewRawOneByteString(length));
6761   } else {
6762     if (length < 0) length = -length;
6763     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
6764         isolate, result, isolate->factory()->NewRawTwoByteString(length));
6765   }
6766   return ConvertCaseHelper(isolate, *s, *result, length, mapping);
6767 }
6768
6769
6770 RUNTIME_FUNCTION(Runtime_StringToLowerCase) {
6771   HandleScope scope(isolate);
6772   ASSERT(args.length() == 1);
6773   CONVERT_ARG_HANDLE_CHECKED(String, s, 0);
6774   return ConvertCase(
6775       s, isolate, isolate->runtime_state()->to_lower_mapping());
6776 }
6777
6778
6779 RUNTIME_FUNCTION(Runtime_StringToUpperCase) {
6780   HandleScope scope(isolate);
6781   ASSERT(args.length() == 1);
6782   CONVERT_ARG_HANDLE_CHECKED(String, s, 0);
6783   return ConvertCase(
6784       s, isolate, isolate->runtime_state()->to_upper_mapping());
6785 }
6786
6787
6788 RUNTIME_FUNCTION(Runtime_StringTrim) {
6789   HandleScope scope(isolate);
6790   ASSERT(args.length() == 3);
6791
6792   CONVERT_ARG_HANDLE_CHECKED(String, string, 0);
6793   CONVERT_BOOLEAN_ARG_CHECKED(trimLeft, 1);
6794   CONVERT_BOOLEAN_ARG_CHECKED(trimRight, 2);
6795
6796   string = String::Flatten(string);
6797   int length = string->length();
6798
6799   int left = 0;
6800   UnicodeCache* unicode_cache = isolate->unicode_cache();
6801   if (trimLeft) {
6802     while (left < length &&
6803            unicode_cache->IsWhiteSpaceOrLineTerminator(string->Get(left))) {
6804       left++;
6805     }
6806   }
6807
6808   int right = length;
6809   if (trimRight) {
6810     while (right > left &&
6811            unicode_cache->IsWhiteSpaceOrLineTerminator(
6812                string->Get(right - 1))) {
6813       right--;
6814     }
6815   }
6816
6817   return *isolate->factory()->NewSubString(string, left, right);
6818 }
6819
6820
6821 RUNTIME_FUNCTION(Runtime_StringSplit) {
6822   HandleScope handle_scope(isolate);
6823   ASSERT(args.length() == 3);
6824   CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
6825   CONVERT_ARG_HANDLE_CHECKED(String, pattern, 1);
6826   CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[2]);
6827   RUNTIME_ASSERT(limit > 0);
6828
6829   int subject_length = subject->length();
6830   int pattern_length = pattern->length();
6831   RUNTIME_ASSERT(pattern_length > 0);
6832
6833   if (limit == 0xffffffffu) {
6834     Handle<Object> cached_answer(
6835         RegExpResultsCache::Lookup(isolate->heap(),
6836                                    *subject,
6837                                    *pattern,
6838                                    RegExpResultsCache::STRING_SPLIT_SUBSTRINGS),
6839         isolate);
6840     if (*cached_answer != Smi::FromInt(0)) {
6841       // The cache FixedArray is a COW-array and can therefore be reused.
6842       Handle<JSArray> result =
6843           isolate->factory()->NewJSArrayWithElements(
6844               Handle<FixedArray>::cast(cached_answer));
6845       return *result;
6846     }
6847   }
6848
6849   // The limit can be very large (0xffffffffu), but since the pattern
6850   // isn't empty, we can never create more parts than ~half the length
6851   // of the subject.
6852
6853   subject = String::Flatten(subject);
6854   pattern = String::Flatten(pattern);
6855
6856   static const int kMaxInitialListCapacity = 16;
6857
6858   ZoneScope zone_scope(isolate->runtime_zone());
6859
6860   // Find (up to limit) indices of separator and end-of-string in subject
6861   int initial_capacity = Min<uint32_t>(kMaxInitialListCapacity, limit);
6862   ZoneList<int> indices(initial_capacity, zone_scope.zone());
6863
6864   FindStringIndicesDispatch(isolate, *subject, *pattern,
6865                             &indices, limit, zone_scope.zone());
6866
6867   if (static_cast<uint32_t>(indices.length()) < limit) {
6868     indices.Add(subject_length, zone_scope.zone());
6869   }
6870
6871   // The list indices now contains the end of each part to create.
6872
6873   // Create JSArray of substrings separated by separator.
6874   int part_count = indices.length();
6875
6876   Handle<JSArray> result = isolate->factory()->NewJSArray(part_count);
6877   JSObject::EnsureCanContainHeapObjectElements(result);
6878   result->set_length(Smi::FromInt(part_count));
6879
6880   ASSERT(result->HasFastObjectElements());
6881
6882   if (part_count == 1 && indices.at(0) == subject_length) {
6883     FixedArray::cast(result->elements())->set(0, *subject);
6884     return *result;
6885   }
6886
6887   Handle<FixedArray> elements(FixedArray::cast(result->elements()));
6888   int part_start = 0;
6889   for (int i = 0; i < part_count; i++) {
6890     HandleScope local_loop_handle(isolate);
6891     int part_end = indices.at(i);
6892     Handle<String> substring =
6893         isolate->factory()->NewProperSubString(subject, part_start, part_end);
6894     elements->set(i, *substring);
6895     part_start = part_end + pattern_length;
6896   }
6897
6898   if (limit == 0xffffffffu) {
6899     if (result->HasFastObjectElements()) {
6900       RegExpResultsCache::Enter(isolate,
6901                                 subject,
6902                                 pattern,
6903                                 elements,
6904                                 RegExpResultsCache::STRING_SPLIT_SUBSTRINGS);
6905     }
6906   }
6907
6908   return *result;
6909 }
6910
6911
6912 // Copies ASCII characters to the given fixed array looking up
6913 // one-char strings in the cache. Gives up on the first char that is
6914 // not in the cache and fills the remainder with smi zeros. Returns
6915 // the length of the successfully copied prefix.
6916 static int CopyCachedAsciiCharsToArray(Heap* heap,
6917                                        const uint8_t* chars,
6918                                        FixedArray* elements,
6919                                        int length) {
6920   DisallowHeapAllocation no_gc;
6921   FixedArray* ascii_cache = heap->single_character_string_cache();
6922   Object* undefined = heap->undefined_value();
6923   int i;
6924   WriteBarrierMode mode = elements->GetWriteBarrierMode(no_gc);
6925   for (i = 0; i < length; ++i) {
6926     Object* value = ascii_cache->get(chars[i]);
6927     if (value == undefined) break;
6928     elements->set(i, value, mode);
6929   }
6930   if (i < length) {
6931     ASSERT(Smi::FromInt(0) == 0);
6932     memset(elements->data_start() + i, 0, kPointerSize * (length - i));
6933   }
6934 #ifdef DEBUG
6935   for (int j = 0; j < length; ++j) {
6936     Object* element = elements->get(j);
6937     ASSERT(element == Smi::FromInt(0) ||
6938            (element->IsString() && String::cast(element)->LooksValid()));
6939   }
6940 #endif
6941   return i;
6942 }
6943
6944
6945 // Converts a String to JSArray.
6946 // For example, "foo" => ["f", "o", "o"].
6947 RUNTIME_FUNCTION(Runtime_StringToArray) {
6948   HandleScope scope(isolate);
6949   ASSERT(args.length() == 2);
6950   CONVERT_ARG_HANDLE_CHECKED(String, s, 0);
6951   CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]);
6952
6953   s = String::Flatten(s);
6954   const int length = static_cast<int>(Min<uint32_t>(s->length(), limit));
6955
6956   Handle<FixedArray> elements;
6957   int position = 0;
6958   if (s->IsFlat() && s->IsOneByteRepresentation()) {
6959     // Try using cached chars where possible.
6960     elements = isolate->factory()->NewUninitializedFixedArray(length);
6961
6962     DisallowHeapAllocation no_gc;
6963     String::FlatContent content = s->GetFlatContent();
6964     if (content.IsAscii()) {
6965       Vector<const uint8_t> chars = content.ToOneByteVector();
6966       // Note, this will initialize all elements (not only the prefix)
6967       // to prevent GC from seeing partially initialized array.
6968       position = CopyCachedAsciiCharsToArray(isolate->heap(),
6969                                              chars.start(),
6970                                              *elements,
6971                                              length);
6972     } else {
6973       MemsetPointer(elements->data_start(),
6974                     isolate->heap()->undefined_value(),
6975                     length);
6976     }
6977   } else {
6978     elements = isolate->factory()->NewFixedArray(length);
6979   }
6980   for (int i = position; i < length; ++i) {
6981     Handle<Object> str =
6982         isolate->factory()->LookupSingleCharacterStringFromCode(s->Get(i));
6983     elements->set(i, *str);
6984   }
6985
6986 #ifdef DEBUG
6987   for (int i = 0; i < length; ++i) {
6988     ASSERT(String::cast(elements->get(i))->length() == 1);
6989   }
6990 #endif
6991
6992   return *isolate->factory()->NewJSArrayWithElements(elements);
6993 }
6994
6995
6996 RUNTIME_FUNCTION(Runtime_NewStringWrapper) {
6997   HandleScope scope(isolate);
6998   ASSERT(args.length() == 1);
6999   CONVERT_ARG_HANDLE_CHECKED(String, value, 0);
7000   return *Object::ToObject(isolate, value).ToHandleChecked();
7001 }
7002
7003
7004 bool Runtime::IsUpperCaseChar(RuntimeState* runtime_state, uint16_t ch) {
7005   unibrow::uchar chars[unibrow::ToUppercase::kMaxWidth];
7006   int char_length = runtime_state->to_upper_mapping()->get(ch, 0, chars);
7007   return char_length == 0;
7008 }
7009
7010
7011 RUNTIME_FUNCTION(RuntimeHidden_NumberToString) {
7012   HandleScope scope(isolate);
7013   ASSERT(args.length() == 1);
7014   CONVERT_NUMBER_ARG_HANDLE_CHECKED(number, 0);
7015
7016   return *isolate->factory()->NumberToString(number);
7017 }
7018
7019
7020 RUNTIME_FUNCTION(RuntimeHidden_NumberToStringSkipCache) {
7021   HandleScope scope(isolate);
7022   ASSERT(args.length() == 1);
7023   CONVERT_NUMBER_ARG_HANDLE_CHECKED(number, 0);
7024
7025   return *isolate->factory()->NumberToString(number, false);
7026 }
7027
7028
7029 RUNTIME_FUNCTION(Runtime_NumberToInteger) {
7030   HandleScope scope(isolate);
7031   ASSERT(args.length() == 1);
7032
7033   CONVERT_DOUBLE_ARG_CHECKED(number, 0);
7034   return *isolate->factory()->NewNumber(DoubleToInteger(number));
7035 }
7036
7037
7038 RUNTIME_FUNCTION(Runtime_NumberToIntegerMapMinusZero) {
7039   HandleScope scope(isolate);
7040   ASSERT(args.length() == 1);
7041
7042   CONVERT_DOUBLE_ARG_CHECKED(number, 0);
7043   double double_value = DoubleToInteger(number);
7044   // Map both -0 and +0 to +0.
7045   if (double_value == 0) double_value = 0;
7046
7047   return *isolate->factory()->NewNumber(double_value);
7048 }
7049
7050
7051 RUNTIME_FUNCTION(Runtime_NumberToJSUint32) {
7052   HandleScope scope(isolate);
7053   ASSERT(args.length() == 1);
7054
7055   CONVERT_NUMBER_CHECKED(int32_t, number, Uint32, args[0]);
7056   return *isolate->factory()->NewNumberFromUint(number);
7057 }
7058
7059
7060 RUNTIME_FUNCTION(Runtime_NumberToJSInt32) {
7061   HandleScope scope(isolate);
7062   ASSERT(args.length() == 1);
7063
7064   CONVERT_DOUBLE_ARG_CHECKED(number, 0);
7065   return *isolate->factory()->NewNumberFromInt(DoubleToInt32(number));
7066 }
7067
7068
7069 // Converts a Number to a Smi, if possible. Returns NaN if the number is not
7070 // a small integer.
7071 RUNTIME_FUNCTION(RuntimeHidden_NumberToSmi) {
7072   SealHandleScope shs(isolate);
7073   ASSERT(args.length() == 1);
7074   CONVERT_ARG_CHECKED(Object, obj, 0);
7075   if (obj->IsSmi()) {
7076     return obj;
7077   }
7078   if (obj->IsHeapNumber()) {
7079     double value = HeapNumber::cast(obj)->value();
7080     int int_value = FastD2I(value);
7081     if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
7082       return Smi::FromInt(int_value);
7083     }
7084   }
7085   return isolate->heap()->nan_value();
7086 }
7087
7088
7089 RUNTIME_FUNCTION(RuntimeHidden_AllocateHeapNumber) {
7090   HandleScope scope(isolate);
7091   ASSERT(args.length() == 0);
7092   return *isolate->factory()->NewHeapNumber(0);
7093 }
7094
7095
7096 RUNTIME_FUNCTION(Runtime_AllocateFloat32x4) {
7097   HandleScope scope(isolate);
7098   ASSERT(args.length() == 0);
7099
7100   float32x4_value_t zero = {{0, 0, 0, 0}};
7101   return *isolate->factory()->NewFloat32x4(zero);
7102 }
7103
7104
7105 RUNTIME_FUNCTION(Runtime_AllocateFloat64x2) {
7106   HandleScope scope(isolate);
7107   ASSERT(args.length() == 0);
7108
7109   float64x2_value_t zero = {{0, 0}};
7110   return *isolate->factory()->NewFloat64x2(zero);
7111 }
7112
7113
7114 RUNTIME_FUNCTION(Runtime_AllocateInt32x4) {
7115   HandleScope scope(isolate);
7116   ASSERT(args.length() == 0);
7117
7118   int32x4_value_t zero = {{0, 0, 0, 0}};
7119   return *isolate->factory()->NewInt32x4(zero);
7120 }
7121
7122
7123 RUNTIME_FUNCTION(Runtime_NumberAdd) {
7124   HandleScope scope(isolate);
7125   ASSERT(args.length() == 2);
7126
7127   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7128   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
7129   return *isolate->factory()->NewNumber(x + y);
7130 }
7131
7132
7133 RUNTIME_FUNCTION(Runtime_NumberSub) {
7134   HandleScope scope(isolate);
7135   ASSERT(args.length() == 2);
7136
7137   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7138   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
7139   return *isolate->factory()->NewNumber(x - y);
7140 }
7141
7142
7143 RUNTIME_FUNCTION(Runtime_NumberMul) {
7144   HandleScope scope(isolate);
7145   ASSERT(args.length() == 2);
7146
7147   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7148   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
7149   return *isolate->factory()->NewNumber(x * y);
7150 }
7151
7152
7153 RUNTIME_FUNCTION(Runtime_NumberUnaryMinus) {
7154   HandleScope scope(isolate);
7155   ASSERT(args.length() == 1);
7156
7157   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7158   return *isolate->factory()->NewNumber(-x);
7159 }
7160
7161
7162 RUNTIME_FUNCTION(Runtime_NumberDiv) {
7163   HandleScope scope(isolate);
7164   ASSERT(args.length() == 2);
7165
7166   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7167   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
7168   return *isolate->factory()->NewNumber(x / y);
7169 }
7170
7171
7172 RUNTIME_FUNCTION(Runtime_NumberMod) {
7173   HandleScope scope(isolate);
7174   ASSERT(args.length() == 2);
7175
7176   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7177   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
7178   return *isolate->factory()->NewNumber(modulo(x, y));
7179 }
7180
7181
7182 RUNTIME_FUNCTION(Runtime_NumberImul) {
7183   HandleScope scope(isolate);
7184   ASSERT(args.length() == 2);
7185
7186   CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
7187   CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
7188   return *isolate->factory()->NewNumberFromInt(x * y);
7189 }
7190
7191
7192 RUNTIME_FUNCTION(RuntimeHidden_StringAdd) {
7193   HandleScope scope(isolate);
7194   ASSERT(args.length() == 2);
7195   CONVERT_ARG_HANDLE_CHECKED(String, str1, 0);
7196   CONVERT_ARG_HANDLE_CHECKED(String, str2, 1);
7197   isolate->counters()->string_add_runtime()->Increment();
7198   Handle<String> result;
7199   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
7200       isolate, result, isolate->factory()->NewConsString(str1, str2));
7201   return *result;
7202 }
7203
7204
7205 template <typename sinkchar>
7206 static inline void StringBuilderConcatHelper(String* special,
7207                                              sinkchar* sink,
7208                                              FixedArray* fixed_array,
7209                                              int array_length) {
7210   DisallowHeapAllocation no_gc;
7211   int position = 0;
7212   for (int i = 0; i < array_length; i++) {
7213     Object* element = fixed_array->get(i);
7214     if (element->IsSmi()) {
7215       // Smi encoding of position and length.
7216       int encoded_slice = Smi::cast(element)->value();
7217       int pos;
7218       int len;
7219       if (encoded_slice > 0) {
7220         // Position and length encoded in one smi.
7221         pos = StringBuilderSubstringPosition::decode(encoded_slice);
7222         len = StringBuilderSubstringLength::decode(encoded_slice);
7223       } else {
7224         // Position and length encoded in two smis.
7225         Object* obj = fixed_array->get(++i);
7226         ASSERT(obj->IsSmi());
7227         pos = Smi::cast(obj)->value();
7228         len = -encoded_slice;
7229       }
7230       String::WriteToFlat(special,
7231                           sink + position,
7232                           pos,
7233                           pos + len);
7234       position += len;
7235     } else {
7236       String* string = String::cast(element);
7237       int element_length = string->length();
7238       String::WriteToFlat(string, sink + position, 0, element_length);
7239       position += element_length;
7240     }
7241   }
7242 }
7243
7244
7245 // Returns the result length of the concatenation.
7246 // On illegal argument, -1 is returned.
7247 static inline int StringBuilderConcatLength(int special_length,
7248                                             FixedArray* fixed_array,
7249                                             int array_length,
7250                                             bool* one_byte) {
7251   DisallowHeapAllocation no_gc;
7252   int position = 0;
7253   for (int i = 0; i < array_length; i++) {
7254     int increment = 0;
7255     Object* elt = fixed_array->get(i);
7256     if (elt->IsSmi()) {
7257       // Smi encoding of position and length.
7258       int smi_value = Smi::cast(elt)->value();
7259       int pos;
7260       int len;
7261       if (smi_value > 0) {
7262         // Position and length encoded in one smi.
7263         pos = StringBuilderSubstringPosition::decode(smi_value);
7264         len = StringBuilderSubstringLength::decode(smi_value);
7265       } else {
7266         // Position and length encoded in two smis.
7267         len = -smi_value;
7268         // Get the position and check that it is a positive smi.
7269         i++;
7270         if (i >= array_length) return -1;
7271         Object* next_smi = fixed_array->get(i);
7272         if (!next_smi->IsSmi()) return -1;
7273         pos = Smi::cast(next_smi)->value();
7274         if (pos < 0) return -1;
7275       }
7276       ASSERT(pos >= 0);
7277       ASSERT(len >= 0);
7278       if (pos > special_length || len > special_length - pos) return -1;
7279       increment = len;
7280     } else if (elt->IsString()) {
7281       String* element = String::cast(elt);
7282       int element_length = element->length();
7283       increment = element_length;
7284       if (*one_byte && !element->HasOnlyOneByteChars()) {
7285         *one_byte = false;
7286       }
7287     } else {
7288       return -1;
7289     }
7290     if (increment > String::kMaxLength - position) {
7291       return kMaxInt;  // Provoke throw on allocation.
7292     }
7293     position += increment;
7294   }
7295   return position;
7296 }
7297
7298
7299 RUNTIME_FUNCTION(Runtime_StringBuilderConcat) {
7300   HandleScope scope(isolate);
7301   ASSERT(args.length() == 3);
7302   CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
7303   if (!args[1]->IsSmi()) return isolate->ThrowInvalidStringLength();
7304   CONVERT_SMI_ARG_CHECKED(array_length, 1);
7305   CONVERT_ARG_HANDLE_CHECKED(String, special, 2);
7306
7307   size_t actual_array_length = 0;
7308   RUNTIME_ASSERT(
7309       TryNumberToSize(isolate, array->length(), &actual_array_length));
7310   RUNTIME_ASSERT(array_length >= 0);
7311   RUNTIME_ASSERT(static_cast<size_t>(array_length) <= actual_array_length);
7312
7313   // This assumption is used by the slice encoding in one or two smis.
7314   ASSERT(Smi::kMaxValue >= String::kMaxLength);
7315
7316   RUNTIME_ASSERT(array->HasFastElements());
7317   JSObject::EnsureCanContainHeapObjectElements(array);
7318
7319   int special_length = special->length();
7320   if (!array->HasFastObjectElements()) {
7321     return isolate->Throw(isolate->heap()->illegal_argument_string());
7322   }
7323
7324   int length;
7325   bool one_byte = special->HasOnlyOneByteChars();
7326
7327   { DisallowHeapAllocation no_gc;
7328     FixedArray* fixed_array = FixedArray::cast(array->elements());
7329     if (fixed_array->length() < array_length) {
7330       array_length = fixed_array->length();
7331     }
7332
7333     if (array_length == 0) {
7334       return isolate->heap()->empty_string();
7335     } else if (array_length == 1) {
7336       Object* first = fixed_array->get(0);
7337       if (first->IsString()) return first;
7338     }
7339     length = StringBuilderConcatLength(
7340         special_length, fixed_array, array_length, &one_byte);
7341   }
7342
7343   if (length == -1) {
7344     return isolate->Throw(isolate->heap()->illegal_argument_string());
7345   }
7346
7347   if (one_byte) {
7348     Handle<SeqOneByteString> answer;
7349     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
7350         isolate, answer,
7351         isolate->factory()->NewRawOneByteString(length));
7352     StringBuilderConcatHelper(*special,
7353                               answer->GetChars(),
7354                               FixedArray::cast(array->elements()),
7355                               array_length);
7356     return *answer;
7357   } else {
7358     Handle<SeqTwoByteString> answer;
7359     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
7360         isolate, answer,
7361         isolate->factory()->NewRawTwoByteString(length));
7362     StringBuilderConcatHelper(*special,
7363                               answer->GetChars(),
7364                               FixedArray::cast(array->elements()),
7365                               array_length);
7366     return *answer;
7367   }
7368 }
7369
7370
7371 RUNTIME_FUNCTION(Runtime_StringBuilderJoin) {
7372   HandleScope scope(isolate);
7373   ASSERT(args.length() == 3);
7374   CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
7375   if (!args[1]->IsSmi()) return isolate->ThrowInvalidStringLength();
7376   CONVERT_SMI_ARG_CHECKED(array_length, 1);
7377   CONVERT_ARG_HANDLE_CHECKED(String, separator, 2);
7378   RUNTIME_ASSERT(array->HasFastObjectElements());
7379
7380   Handle<FixedArray> fixed_array(FixedArray::cast(array->elements()));
7381   if (fixed_array->length() < array_length) {
7382     array_length = fixed_array->length();
7383   }
7384
7385   if (array_length == 0) {
7386     return isolate->heap()->empty_string();
7387   } else if (array_length == 1) {
7388     Object* first = fixed_array->get(0);
7389     RUNTIME_ASSERT(first->IsString());
7390     return first;
7391   }
7392
7393   int separator_length = separator->length();
7394   RUNTIME_ASSERT(separator_length > 0);
7395   int max_nof_separators =
7396       (String::kMaxLength + separator_length - 1) / separator_length;
7397   if (max_nof_separators < (array_length - 1)) {
7398     return isolate->ThrowInvalidStringLength();
7399   }
7400   int length = (array_length - 1) * separator_length;
7401   for (int i = 0; i < array_length; i++) {
7402     Object* element_obj = fixed_array->get(i);
7403     RUNTIME_ASSERT(element_obj->IsString());
7404     String* element = String::cast(element_obj);
7405     int increment = element->length();
7406     if (increment > String::kMaxLength - length) {
7407       STATIC_ASSERT(String::kMaxLength < kMaxInt);
7408       length = kMaxInt;  // Provoke exception;
7409       break;
7410     }
7411     length += increment;
7412   }
7413
7414   Handle<SeqTwoByteString> answer;
7415   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
7416       isolate, answer,
7417       isolate->factory()->NewRawTwoByteString(length));
7418
7419   DisallowHeapAllocation no_gc;
7420
7421   uc16* sink = answer->GetChars();
7422 #ifdef DEBUG
7423   uc16* end = sink + length;
7424 #endif
7425
7426   String* first = String::cast(fixed_array->get(0));
7427   String* seperator_raw = *separator;
7428   int first_length = first->length();
7429   String::WriteToFlat(first, sink, 0, first_length);
7430   sink += first_length;
7431
7432   for (int i = 1; i < array_length; i++) {
7433     ASSERT(sink + separator_length <= end);
7434     String::WriteToFlat(seperator_raw, sink, 0, separator_length);
7435     sink += separator_length;
7436
7437     String* element = String::cast(fixed_array->get(i));
7438     int element_length = element->length();
7439     ASSERT(sink + element_length <= end);
7440     String::WriteToFlat(element, sink, 0, element_length);
7441     sink += element_length;
7442   }
7443   ASSERT(sink == end);
7444
7445   // Use %_FastAsciiArrayJoin instead.
7446   ASSERT(!answer->IsOneByteRepresentation());
7447   return *answer;
7448 }
7449
7450 template <typename Char>
7451 static void JoinSparseArrayWithSeparator(FixedArray* elements,
7452                                          int elements_length,
7453                                          uint32_t array_length,
7454                                          String* separator,
7455                                          Vector<Char> buffer) {
7456   DisallowHeapAllocation no_gc;
7457   int previous_separator_position = 0;
7458   int separator_length = separator->length();
7459   int cursor = 0;
7460   for (int i = 0; i < elements_length; i += 2) {
7461     int position = NumberToInt32(elements->get(i));
7462     String* string = String::cast(elements->get(i + 1));
7463     int string_length = string->length();
7464     if (string->length() > 0) {
7465       while (previous_separator_position < position) {
7466         String::WriteToFlat<Char>(separator, &buffer[cursor],
7467                                   0, separator_length);
7468         cursor += separator_length;
7469         previous_separator_position++;
7470       }
7471       String::WriteToFlat<Char>(string, &buffer[cursor],
7472                                 0, string_length);
7473       cursor += string->length();
7474     }
7475   }
7476   if (separator_length > 0) {
7477     // Array length must be representable as a signed 32-bit number,
7478     // otherwise the total string length would have been too large.
7479     ASSERT(array_length <= 0x7fffffff);  // Is int32_t.
7480     int last_array_index = static_cast<int>(array_length - 1);
7481     while (previous_separator_position < last_array_index) {
7482       String::WriteToFlat<Char>(separator, &buffer[cursor],
7483                                 0, separator_length);
7484       cursor += separator_length;
7485       previous_separator_position++;
7486     }
7487   }
7488   ASSERT(cursor <= buffer.length());
7489 }
7490
7491
7492 RUNTIME_FUNCTION(Runtime_SparseJoinWithSeparator) {
7493   HandleScope scope(isolate);
7494   ASSERT(args.length() == 3);
7495   CONVERT_ARG_HANDLE_CHECKED(JSArray, elements_array, 0);
7496   CONVERT_NUMBER_CHECKED(uint32_t, array_length, Uint32, args[1]);
7497   CONVERT_ARG_HANDLE_CHECKED(String, separator, 2);
7498   // elements_array is fast-mode JSarray of alternating positions
7499   // (increasing order) and strings.
7500   RUNTIME_ASSERT(elements_array->HasFastSmiOrObjectElements());
7501   // array_length is length of original array (used to add separators);
7502   // separator is string to put between elements. Assumed to be non-empty.
7503   RUNTIME_ASSERT(array_length > 0);
7504
7505   // Find total length of join result.
7506   int string_length = 0;
7507   bool is_ascii = separator->IsOneByteRepresentation();
7508   bool overflow = false;
7509   CONVERT_NUMBER_CHECKED(int, elements_length, Int32, elements_array->length());
7510   RUNTIME_ASSERT(elements_length <= elements_array->elements()->length());
7511   RUNTIME_ASSERT((elements_length & 1) == 0);  // Even length.
7512   FixedArray* elements = FixedArray::cast(elements_array->elements());
7513   for (int i = 0; i < elements_length; i += 2) {
7514     RUNTIME_ASSERT(elements->get(i)->IsNumber());
7515     RUNTIME_ASSERT(elements->get(i + 1)->IsString());
7516   }
7517
7518   { DisallowHeapAllocation no_gc;
7519     for (int i = 0; i < elements_length; i += 2) {
7520       String* string = String::cast(elements->get(i + 1));
7521       int length = string->length();
7522       if (is_ascii && !string->IsOneByteRepresentation()) {
7523         is_ascii = false;
7524       }
7525       if (length > String::kMaxLength ||
7526           String::kMaxLength - length < string_length) {
7527         overflow = true;
7528         break;
7529       }
7530       string_length += length;
7531     }
7532   }
7533
7534   int separator_length = separator->length();
7535   if (!overflow && separator_length > 0) {
7536     if (array_length <= 0x7fffffffu) {
7537       int separator_count = static_cast<int>(array_length) - 1;
7538       int remaining_length = String::kMaxLength - string_length;
7539       if ((remaining_length / separator_length) >= separator_count) {
7540         string_length += separator_length * (array_length - 1);
7541       } else {
7542         // Not room for the separators within the maximal string length.
7543         overflow = true;
7544       }
7545     } else {
7546       // Nonempty separator and at least 2^31-1 separators necessary
7547       // means that the string is too large to create.
7548       STATIC_ASSERT(String::kMaxLength < 0x7fffffff);
7549       overflow = true;
7550     }
7551   }
7552   if (overflow) {
7553     // Throw an exception if the resulting string is too large. See
7554     // https://code.google.com/p/chromium/issues/detail?id=336820
7555     // for details.
7556     return isolate->ThrowInvalidStringLength();
7557   }
7558
7559   if (is_ascii) {
7560     Handle<SeqOneByteString> result = isolate->factory()->NewRawOneByteString(
7561         string_length).ToHandleChecked();
7562     JoinSparseArrayWithSeparator<uint8_t>(
7563         FixedArray::cast(elements_array->elements()),
7564         elements_length,
7565         array_length,
7566         *separator,
7567         Vector<uint8_t>(result->GetChars(), string_length));
7568     return *result;
7569   } else {
7570     Handle<SeqTwoByteString> result = isolate->factory()->NewRawTwoByteString(
7571         string_length).ToHandleChecked();
7572     JoinSparseArrayWithSeparator<uc16>(
7573         FixedArray::cast(elements_array->elements()),
7574         elements_length,
7575         array_length,
7576         *separator,
7577         Vector<uc16>(result->GetChars(), string_length));
7578     return *result;
7579   }
7580 }
7581
7582
7583 RUNTIME_FUNCTION(Runtime_NumberOr) {
7584   HandleScope scope(isolate);
7585   ASSERT(args.length() == 2);
7586
7587   CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
7588   CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
7589   return *isolate->factory()->NewNumberFromInt(x | y);
7590 }
7591
7592
7593 RUNTIME_FUNCTION(Runtime_NumberAnd) {
7594   HandleScope scope(isolate);
7595   ASSERT(args.length() == 2);
7596
7597   CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
7598   CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
7599   return *isolate->factory()->NewNumberFromInt(x & y);
7600 }
7601
7602
7603 RUNTIME_FUNCTION(Runtime_NumberXor) {
7604   HandleScope scope(isolate);
7605   ASSERT(args.length() == 2);
7606
7607   CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
7608   CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
7609   return *isolate->factory()->NewNumberFromInt(x ^ y);
7610 }
7611
7612
7613 RUNTIME_FUNCTION(Runtime_NumberShl) {
7614   HandleScope scope(isolate);
7615   ASSERT(args.length() == 2);
7616
7617   CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
7618   CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
7619   return *isolate->factory()->NewNumberFromInt(x << (y & 0x1f));
7620 }
7621
7622
7623 RUNTIME_FUNCTION(Runtime_NumberShr) {
7624   HandleScope scope(isolate);
7625   ASSERT(args.length() == 2);
7626
7627   CONVERT_NUMBER_CHECKED(uint32_t, x, Uint32, args[0]);
7628   CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
7629   return *isolate->factory()->NewNumberFromUint(x >> (y & 0x1f));
7630 }
7631
7632
7633 RUNTIME_FUNCTION(Runtime_NumberSar) {
7634   HandleScope scope(isolate);
7635   ASSERT(args.length() == 2);
7636
7637   CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
7638   CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
7639   return *isolate->factory()->NewNumberFromInt(
7640       ArithmeticShiftRight(x, y & 0x1f));
7641 }
7642
7643
7644 RUNTIME_FUNCTION(Runtime_NumberEquals) {
7645   SealHandleScope shs(isolate);
7646   ASSERT(args.length() == 2);
7647
7648   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7649   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
7650   if (std::isnan(x)) return Smi::FromInt(NOT_EQUAL);
7651   if (std::isnan(y)) return Smi::FromInt(NOT_EQUAL);
7652   if (x == y) return Smi::FromInt(EQUAL);
7653   Object* result;
7654   if ((fpclassify(x) == FP_ZERO) && (fpclassify(y) == FP_ZERO)) {
7655     result = Smi::FromInt(EQUAL);
7656   } else {
7657     result = Smi::FromInt(NOT_EQUAL);
7658   }
7659   return result;
7660 }
7661
7662
7663 RUNTIME_FUNCTION(Runtime_StringEquals) {
7664   HandleScope handle_scope(isolate);
7665   ASSERT(args.length() == 2);
7666
7667   CONVERT_ARG_HANDLE_CHECKED(String, x, 0);
7668   CONVERT_ARG_HANDLE_CHECKED(String, y, 1);
7669
7670   bool not_equal = !String::Equals(x, y);
7671   // This is slightly convoluted because the value that signifies
7672   // equality is 0 and inequality is 1 so we have to negate the result
7673   // from String::Equals.
7674   ASSERT(not_equal == 0 || not_equal == 1);
7675   STATIC_CHECK(EQUAL == 0);
7676   STATIC_CHECK(NOT_EQUAL == 1);
7677   return Smi::FromInt(not_equal);
7678 }
7679
7680
7681 RUNTIME_FUNCTION(Runtime_NumberCompare) {
7682   SealHandleScope shs(isolate);
7683   ASSERT(args.length() == 3);
7684
7685   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7686   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
7687   CONVERT_ARG_HANDLE_CHECKED(Object, uncomparable_result, 2)
7688   if (std::isnan(x) || std::isnan(y)) return *uncomparable_result;
7689   if (x == y) return Smi::FromInt(EQUAL);
7690   if (isless(x, y)) return Smi::FromInt(LESS);
7691   return Smi::FromInt(GREATER);
7692 }
7693
7694
7695 // Compare two Smis as if they were converted to strings and then
7696 // compared lexicographically.
7697 RUNTIME_FUNCTION(Runtime_SmiLexicographicCompare) {
7698   SealHandleScope shs(isolate);
7699   ASSERT(args.length() == 2);
7700   CONVERT_SMI_ARG_CHECKED(x_value, 0);
7701   CONVERT_SMI_ARG_CHECKED(y_value, 1);
7702
7703   // If the integers are equal so are the string representations.
7704   if (x_value == y_value) return Smi::FromInt(EQUAL);
7705
7706   // If one of the integers is zero the normal integer order is the
7707   // same as the lexicographic order of the string representations.
7708   if (x_value == 0 || y_value == 0)
7709     return Smi::FromInt(x_value < y_value ? LESS : GREATER);
7710
7711   // If only one of the integers is negative the negative number is
7712   // smallest because the char code of '-' is less than the char code
7713   // of any digit.  Otherwise, we make both values positive.
7714
7715   // Use unsigned values otherwise the logic is incorrect for -MIN_INT on
7716   // architectures using 32-bit Smis.
7717   uint32_t x_scaled = x_value;
7718   uint32_t y_scaled = y_value;
7719   if (x_value < 0 || y_value < 0) {
7720     if (y_value >= 0) return Smi::FromInt(LESS);
7721     if (x_value >= 0) return Smi::FromInt(GREATER);
7722     x_scaled = -x_value;
7723     y_scaled = -y_value;
7724   }
7725
7726   static const uint32_t kPowersOf10[] = {
7727     1, 10, 100, 1000, 10*1000, 100*1000,
7728     1000*1000, 10*1000*1000, 100*1000*1000,
7729     1000*1000*1000
7730   };
7731
7732   // If the integers have the same number of decimal digits they can be
7733   // compared directly as the numeric order is the same as the
7734   // lexicographic order.  If one integer has fewer digits, it is scaled
7735   // by some power of 10 to have the same number of digits as the longer
7736   // integer.  If the scaled integers are equal it means the shorter
7737   // integer comes first in the lexicographic order.
7738
7739   // From http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
7740   int x_log2 = IntegerLog2(x_scaled);
7741   int x_log10 = ((x_log2 + 1) * 1233) >> 12;
7742   x_log10 -= x_scaled < kPowersOf10[x_log10];
7743
7744   int y_log2 = IntegerLog2(y_scaled);
7745   int y_log10 = ((y_log2 + 1) * 1233) >> 12;
7746   y_log10 -= y_scaled < kPowersOf10[y_log10];
7747
7748   int tie = EQUAL;
7749
7750   if (x_log10 < y_log10) {
7751     // X has fewer digits.  We would like to simply scale up X but that
7752     // might overflow, e.g when comparing 9 with 1_000_000_000, 9 would
7753     // be scaled up to 9_000_000_000. So we scale up by the next
7754     // smallest power and scale down Y to drop one digit. It is OK to
7755     // drop one digit from the longer integer since the final digit is
7756     // past the length of the shorter integer.
7757     x_scaled *= kPowersOf10[y_log10 - x_log10 - 1];
7758     y_scaled /= 10;
7759     tie = LESS;
7760   } else if (y_log10 < x_log10) {
7761     y_scaled *= kPowersOf10[x_log10 - y_log10 - 1];
7762     x_scaled /= 10;
7763     tie = GREATER;
7764   }
7765
7766   if (x_scaled < y_scaled) return Smi::FromInt(LESS);
7767   if (x_scaled > y_scaled) return Smi::FromInt(GREATER);
7768   return Smi::FromInt(tie);
7769 }
7770
7771
7772 RUNTIME_FUNCTION(RuntimeHidden_StringCompare) {
7773   HandleScope handle_scope(isolate);
7774   ASSERT(args.length() == 2);
7775
7776   CONVERT_ARG_HANDLE_CHECKED(String, x, 0);
7777   CONVERT_ARG_HANDLE_CHECKED(String, y, 1);
7778
7779   isolate->counters()->string_compare_runtime()->Increment();
7780
7781   // A few fast case tests before we flatten.
7782   if (x.is_identical_to(y)) return Smi::FromInt(EQUAL);
7783   if (y->length() == 0) {
7784     if (x->length() == 0) return Smi::FromInt(EQUAL);
7785     return Smi::FromInt(GREATER);
7786   } else if (x->length() == 0) {
7787     return Smi::FromInt(LESS);
7788   }
7789
7790   int d = x->Get(0) - y->Get(0);
7791   if (d < 0) return Smi::FromInt(LESS);
7792   else if (d > 0) return Smi::FromInt(GREATER);
7793
7794   // Slow case.
7795   x = String::Flatten(x);
7796   y = String::Flatten(y);
7797
7798   DisallowHeapAllocation no_gc;
7799   Object* equal_prefix_result = Smi::FromInt(EQUAL);
7800   int prefix_length = x->length();
7801   if (y->length() < prefix_length) {
7802     prefix_length = y->length();
7803     equal_prefix_result = Smi::FromInt(GREATER);
7804   } else if (y->length() > prefix_length) {
7805     equal_prefix_result = Smi::FromInt(LESS);
7806   }
7807   int r;
7808   String::FlatContent x_content = x->GetFlatContent();
7809   String::FlatContent y_content = y->GetFlatContent();
7810   if (x_content.IsAscii()) {
7811     Vector<const uint8_t> x_chars = x_content.ToOneByteVector();
7812     if (y_content.IsAscii()) {
7813       Vector<const uint8_t> y_chars = y_content.ToOneByteVector();
7814       r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
7815     } else {
7816       Vector<const uc16> y_chars = y_content.ToUC16Vector();
7817       r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
7818     }
7819   } else {
7820     Vector<const uc16> x_chars = x_content.ToUC16Vector();
7821     if (y_content.IsAscii()) {
7822       Vector<const uint8_t> y_chars = y_content.ToOneByteVector();
7823       r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
7824     } else {
7825       Vector<const uc16> y_chars = y_content.ToUC16Vector();
7826       r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
7827     }
7828   }
7829   Object* result;
7830   if (r == 0) {
7831     result = equal_prefix_result;
7832   } else {
7833     result = (r < 0) ? Smi::FromInt(LESS) : Smi::FromInt(GREATER);
7834   }
7835   return result;
7836 }
7837
7838
7839 #define RUNTIME_UNARY_MATH(Name, name)                                         \
7840 RUNTIME_FUNCTION(Runtime_Math##Name) {                           \
7841   HandleScope scope(isolate);                                                  \
7842   ASSERT(args.length() == 1);                                                  \
7843   isolate->counters()->math_##name()->Increment();                             \
7844   CONVERT_DOUBLE_ARG_CHECKED(x, 0);                                            \
7845   return *isolate->factory()->NewHeapNumber(std::name(x));                     \
7846 }
7847
7848 RUNTIME_UNARY_MATH(Acos, acos)
7849 RUNTIME_UNARY_MATH(Asin, asin)
7850 RUNTIME_UNARY_MATH(Atan, atan)
7851 RUNTIME_UNARY_MATH(Log, log)
7852 #undef RUNTIME_UNARY_MATH
7853
7854
7855 RUNTIME_FUNCTION(Runtime_DoubleHi) {
7856   HandleScope scope(isolate);
7857   ASSERT(args.length() == 1);
7858   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7859   uint64_t integer = double_to_uint64(x);
7860   integer = (integer >> 32) & 0xFFFFFFFFu;
7861   return *isolate->factory()->NewNumber(static_cast<int32_t>(integer));
7862 }
7863
7864
7865 RUNTIME_FUNCTION(Runtime_DoubleLo) {
7866   HandleScope scope(isolate);
7867   ASSERT(args.length() == 1);
7868   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7869   return *isolate->factory()->NewNumber(
7870       static_cast<int32_t>(double_to_uint64(x) & 0xFFFFFFFFu));
7871 }
7872
7873
7874 RUNTIME_FUNCTION(Runtime_ConstructDouble) {
7875   HandleScope scope(isolate);
7876   ASSERT(args.length() == 2);
7877   CONVERT_NUMBER_CHECKED(uint32_t, hi, Uint32, args[0]);
7878   CONVERT_NUMBER_CHECKED(uint32_t, lo, Uint32, args[1]);
7879   uint64_t result = (static_cast<uint64_t>(hi) << 32) | lo;
7880   return *isolate->factory()->NewNumber(uint64_to_double(result));
7881 }
7882
7883
7884 static const double kPiDividedBy4 = 0.78539816339744830962;
7885
7886
7887 RUNTIME_FUNCTION(Runtime_MathAtan2) {
7888   HandleScope scope(isolate);
7889   ASSERT(args.length() == 2);
7890   isolate->counters()->math_atan2()->Increment();
7891
7892   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7893   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
7894   double result;
7895   if (std::isinf(x) && std::isinf(y)) {
7896     // Make sure that the result in case of two infinite arguments
7897     // is a multiple of Pi / 4. The sign of the result is determined
7898     // by the first argument (x) and the sign of the second argument
7899     // determines the multiplier: one or three.
7900     int multiplier = (x < 0) ? -1 : 1;
7901     if (y < 0) multiplier *= 3;
7902     result = multiplier * kPiDividedBy4;
7903   } else {
7904     result = std::atan2(x, y);
7905   }
7906   return *isolate->factory()->NewNumber(result);
7907 }
7908
7909
7910 RUNTIME_FUNCTION(Runtime_MathExp) {
7911   HandleScope scope(isolate);
7912   ASSERT(args.length() == 1);
7913   isolate->counters()->math_exp()->Increment();
7914
7915   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7916   lazily_initialize_fast_exp();
7917   return *isolate->factory()->NewNumber(fast_exp(x));
7918 }
7919
7920
7921 RUNTIME_FUNCTION(Runtime_MathFloor) {
7922   HandleScope scope(isolate);
7923   ASSERT(args.length() == 1);
7924   isolate->counters()->math_floor()->Increment();
7925
7926   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7927   return *isolate->factory()->NewNumber(std::floor(x));
7928 }
7929
7930
7931 // Slow version of Math.pow.  We check for fast paths for special cases.
7932 // Used if SSE2/VFP3 is not available.
7933 RUNTIME_FUNCTION(RuntimeHidden_MathPowSlow) {
7934   HandleScope scope(isolate);
7935   ASSERT(args.length() == 2);
7936   isolate->counters()->math_pow()->Increment();
7937
7938   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7939
7940   // If the second argument is a smi, it is much faster to call the
7941   // custom powi() function than the generic pow().
7942   if (args[1]->IsSmi()) {
7943     int y = args.smi_at(1);
7944     return *isolate->factory()->NewNumber(power_double_int(x, y));
7945   }
7946
7947   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
7948   double result = power_helper(x, y);
7949   if (std::isnan(result)) return isolate->heap()->nan_value();
7950   return *isolate->factory()->NewNumber(result);
7951 }
7952
7953
7954 // Fast version of Math.pow if we know that y is not an integer and y is not
7955 // -0.5 or 0.5.  Used as slow case from full codegen.
7956 RUNTIME_FUNCTION(RuntimeHidden_MathPow) {
7957   HandleScope scope(isolate);
7958   ASSERT(args.length() == 2);
7959   isolate->counters()->math_pow()->Increment();
7960
7961   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
7962   CONVERT_DOUBLE_ARG_CHECKED(y, 1);
7963   if (y == 0) {
7964     return Smi::FromInt(1);
7965   } else {
7966     double result = power_double_double(x, y);
7967     if (std::isnan(result)) return isolate->heap()->nan_value();
7968     return *isolate->factory()->NewNumber(result);
7969   }
7970 }
7971
7972
7973 RUNTIME_FUNCTION(Runtime_RoundNumber) {
7974   HandleScope scope(isolate);
7975   ASSERT(args.length() == 1);
7976   CONVERT_NUMBER_ARG_HANDLE_CHECKED(input, 0);
7977   isolate->counters()->math_round()->Increment();
7978
7979   if (!input->IsHeapNumber()) {
7980     ASSERT(input->IsSmi());
7981     return *input;
7982   }
7983
7984   Handle<HeapNumber> number = Handle<HeapNumber>::cast(input);
7985
7986   double value = number->value();
7987   int exponent = number->get_exponent();
7988   int sign = number->get_sign();
7989
7990   if (exponent < -1) {
7991     // Number in range ]-0.5..0.5[. These always round to +/-zero.
7992     if (sign) return isolate->heap()->minus_zero_value();
7993     return Smi::FromInt(0);
7994   }
7995
7996   // We compare with kSmiValueSize - 2 because (2^30 - 0.1) has exponent 29 and
7997   // should be rounded to 2^30, which is not smi (for 31-bit smis, similar
7998   // argument holds for 32-bit smis).
7999   if (!sign && exponent < kSmiValueSize - 2) {
8000     return Smi::FromInt(static_cast<int>(value + 0.5));
8001   }
8002
8003   // If the magnitude is big enough, there's no place for fraction part. If we
8004   // try to add 0.5 to this number, 1.0 will be added instead.
8005   if (exponent >= 52) {
8006     return *number;
8007   }
8008
8009   if (sign && value >= -0.5) return isolate->heap()->minus_zero_value();
8010
8011   // Do not call NumberFromDouble() to avoid extra checks.
8012   return *isolate->factory()->NewNumber(std::floor(value + 0.5));
8013 }
8014
8015
8016 RUNTIME_FUNCTION(Runtime_MathSqrt) {
8017   HandleScope scope(isolate);
8018   ASSERT(args.length() == 1);
8019   isolate->counters()->math_sqrt()->Increment();
8020
8021   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
8022   return *isolate->factory()->NewNumber(fast_sqrt(x));
8023 }
8024
8025
8026 RUNTIME_FUNCTION(Runtime_MathFround) {
8027   HandleScope scope(isolate);
8028   ASSERT(args.length() == 1);
8029
8030   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
8031   float xf = static_cast<float>(x);
8032   return *isolate->factory()->NewNumber(xf);
8033 }
8034
8035
8036 RUNTIME_FUNCTION(Runtime_DateMakeDay) {
8037   SealHandleScope shs(isolate);
8038   ASSERT(args.length() == 2);
8039
8040   CONVERT_SMI_ARG_CHECKED(year, 0);
8041   CONVERT_SMI_ARG_CHECKED(month, 1);
8042
8043   int days = isolate->date_cache()->DaysFromYearMonth(year, month);
8044   RUNTIME_ASSERT(Smi::IsValid(days));
8045   return Smi::FromInt(days);
8046 }
8047
8048
8049 RUNTIME_FUNCTION(Runtime_DateSetValue) {
8050   HandleScope scope(isolate);
8051   ASSERT(args.length() == 3);
8052
8053   CONVERT_ARG_HANDLE_CHECKED(JSDate, date, 0);
8054   CONVERT_DOUBLE_ARG_CHECKED(time, 1);
8055   CONVERT_SMI_ARG_CHECKED(is_utc, 2);
8056
8057   DateCache* date_cache = isolate->date_cache();
8058
8059   Handle<Object> value;;
8060   bool is_value_nan = false;
8061   if (std::isnan(time)) {
8062     value = isolate->factory()->nan_value();
8063     is_value_nan = true;
8064   } else if (!is_utc &&
8065              (time < -DateCache::kMaxTimeBeforeUTCInMs ||
8066               time > DateCache::kMaxTimeBeforeUTCInMs)) {
8067     value = isolate->factory()->nan_value();
8068     is_value_nan = true;
8069   } else {
8070     time = is_utc ? time : date_cache->ToUTC(static_cast<int64_t>(time));
8071     if (time < -DateCache::kMaxTimeInMs ||
8072         time > DateCache::kMaxTimeInMs) {
8073       value = isolate->factory()->nan_value();
8074       is_value_nan = true;
8075     } else  {
8076       value = isolate->factory()->NewNumber(DoubleToInteger(time));
8077     }
8078   }
8079   date->SetValue(*value, is_value_nan);
8080   return *value;
8081 }
8082
8083
8084 RUNTIME_FUNCTION(RuntimeHidden_NewArgumentsFast) {
8085   HandleScope scope(isolate);
8086   ASSERT(args.length() == 3);
8087
8088   CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0);
8089   Object** parameters = reinterpret_cast<Object**>(args[1]);
8090   CONVERT_SMI_ARG_CHECKED(argument_count, 2);
8091
8092   Handle<JSObject> result =
8093       isolate->factory()->NewArgumentsObject(callee, argument_count);
8094   // Allocate the elements if needed.
8095   int parameter_count = callee->shared()->formal_parameter_count();
8096   if (argument_count > 0) {
8097     if (parameter_count > 0) {
8098       int mapped_count = Min(argument_count, parameter_count);
8099       Handle<FixedArray> parameter_map =
8100           isolate->factory()->NewFixedArray(mapped_count + 2, NOT_TENURED);
8101       parameter_map->set_map(
8102           isolate->heap()->sloppy_arguments_elements_map());
8103
8104       Handle<Map> map = Map::Copy(handle(result->map()));
8105       map->set_elements_kind(SLOPPY_ARGUMENTS_ELEMENTS);
8106
8107       result->set_map(*map);
8108       result->set_elements(*parameter_map);
8109
8110       // Store the context and the arguments array at the beginning of the
8111       // parameter map.
8112       Handle<Context> context(isolate->context());
8113       Handle<FixedArray> arguments =
8114           isolate->factory()->NewFixedArray(argument_count, NOT_TENURED);
8115       parameter_map->set(0, *context);
8116       parameter_map->set(1, *arguments);
8117
8118       // Loop over the actual parameters backwards.
8119       int index = argument_count - 1;
8120       while (index >= mapped_count) {
8121         // These go directly in the arguments array and have no
8122         // corresponding slot in the parameter map.
8123         arguments->set(index, *(parameters - index - 1));
8124         --index;
8125       }
8126
8127       Handle<ScopeInfo> scope_info(callee->shared()->scope_info());
8128       while (index >= 0) {
8129         // Detect duplicate names to the right in the parameter list.
8130         Handle<String> name(scope_info->ParameterName(index));
8131         int context_local_count = scope_info->ContextLocalCount();
8132         bool duplicate = false;
8133         for (int j = index + 1; j < parameter_count; ++j) {
8134           if (scope_info->ParameterName(j) == *name) {
8135             duplicate = true;
8136             break;
8137           }
8138         }
8139
8140         if (duplicate) {
8141           // This goes directly in the arguments array with a hole in the
8142           // parameter map.
8143           arguments->set(index, *(parameters - index - 1));
8144           parameter_map->set_the_hole(index + 2);
8145         } else {
8146           // The context index goes in the parameter map with a hole in the
8147           // arguments array.
8148           int context_index = -1;
8149           for (int j = 0; j < context_local_count; ++j) {
8150             if (scope_info->ContextLocalName(j) == *name) {
8151               context_index = j;
8152               break;
8153             }
8154           }
8155           ASSERT(context_index >= 0);
8156           arguments->set_the_hole(index);
8157           parameter_map->set(index + 2, Smi::FromInt(
8158               Context::MIN_CONTEXT_SLOTS + context_index));
8159         }
8160
8161         --index;
8162       }
8163     } else {
8164       // If there is no aliasing, the arguments object elements are not
8165       // special in any way.
8166       Handle<FixedArray> elements =
8167           isolate->factory()->NewFixedArray(argument_count, NOT_TENURED);
8168       result->set_elements(*elements);
8169       for (int i = 0; i < argument_count; ++i) {
8170         elements->set(i, *(parameters - i - 1));
8171       }
8172     }
8173   }
8174   return *result;
8175 }
8176
8177
8178 RUNTIME_FUNCTION(RuntimeHidden_NewStrictArgumentsFast) {
8179   HandleScope scope(isolate);
8180   ASSERT(args.length() == 3);
8181   CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0)
8182   Object** parameters = reinterpret_cast<Object**>(args[1]);
8183   CONVERT_SMI_ARG_CHECKED(length, 2);
8184
8185   Handle<JSObject> result =
8186         isolate->factory()->NewArgumentsObject(callee, length);
8187
8188   if (length > 0) {
8189     Handle<FixedArray> array =
8190         isolate->factory()->NewUninitializedFixedArray(length);
8191     DisallowHeapAllocation no_gc;
8192     WriteBarrierMode mode = array->GetWriteBarrierMode(no_gc);
8193     for (int i = 0; i < length; i++) {
8194       array->set(i, *--parameters, mode);
8195     }
8196     result->set_elements(*array);
8197   }
8198   return *result;
8199 }
8200
8201
8202 RUNTIME_FUNCTION(RuntimeHidden_NewClosureFromStubFailure) {
8203   HandleScope scope(isolate);
8204   ASSERT(args.length() == 1);
8205   CONVERT_ARG_HANDLE_CHECKED(SharedFunctionInfo, shared, 0);
8206   Handle<Context> context(isolate->context());
8207   PretenureFlag pretenure_flag = NOT_TENURED;
8208   return *isolate->factory()->NewFunctionFromSharedFunctionInfo(
8209       shared,  context, pretenure_flag);
8210 }
8211
8212
8213 RUNTIME_FUNCTION(RuntimeHidden_NewClosure) {
8214   HandleScope scope(isolate);
8215   ASSERT(args.length() == 3);
8216   CONVERT_ARG_HANDLE_CHECKED(Context, context, 0);
8217   CONVERT_ARG_HANDLE_CHECKED(SharedFunctionInfo, shared, 1);
8218   CONVERT_BOOLEAN_ARG_CHECKED(pretenure, 2);
8219
8220   // The caller ensures that we pretenure closures that are assigned
8221   // directly to properties.
8222   PretenureFlag pretenure_flag = pretenure ? TENURED : NOT_TENURED;
8223   return *isolate->factory()->NewFunctionFromSharedFunctionInfo(
8224       shared, context, pretenure_flag);
8225 }
8226
8227
8228 // Find the arguments of the JavaScript function invocation that called
8229 // into C++ code. Collect these in a newly allocated array of handles (possibly
8230 // prefixed by a number of empty handles).
8231 static SmartArrayPointer<Handle<Object> > GetCallerArguments(
8232     Isolate* isolate,
8233     int prefix_argc,
8234     int* total_argc) {
8235   // Find frame containing arguments passed to the caller.
8236   JavaScriptFrameIterator it(isolate);
8237   JavaScriptFrame* frame = it.frame();
8238   List<JSFunction*> functions(2);
8239   frame->GetFunctions(&functions);
8240   if (functions.length() > 1) {
8241     int inlined_jsframe_index = functions.length() - 1;
8242     JSFunction* inlined_function = functions[inlined_jsframe_index];
8243     SlotRefValueBuilder slot_refs(
8244         frame,
8245         inlined_jsframe_index,
8246         inlined_function->shared()->formal_parameter_count());
8247
8248     int args_count = slot_refs.args_length();
8249
8250     *total_argc = prefix_argc + args_count;
8251     SmartArrayPointer<Handle<Object> > param_data(
8252         NewArray<Handle<Object> >(*total_argc));
8253     slot_refs.Prepare(isolate);
8254     for (int i = 0; i < args_count; i++) {
8255       Handle<Object> val = slot_refs.GetNext(isolate, 0);
8256       param_data[prefix_argc + i] = val;
8257     }
8258     slot_refs.Finish(isolate);
8259
8260     return param_data;
8261   } else {
8262     it.AdvanceToArgumentsFrame();
8263     frame = it.frame();
8264     int args_count = frame->ComputeParametersCount();
8265
8266     *total_argc = prefix_argc + args_count;
8267     SmartArrayPointer<Handle<Object> > param_data(
8268         NewArray<Handle<Object> >(*total_argc));
8269     for (int i = 0; i < args_count; i++) {
8270       Handle<Object> val = Handle<Object>(frame->GetParameter(i), isolate);
8271       param_data[prefix_argc + i] = val;
8272     }
8273     return param_data;
8274   }
8275 }
8276
8277
8278 RUNTIME_FUNCTION(Runtime_FunctionBindArguments) {
8279   HandleScope scope(isolate);
8280   ASSERT(args.length() == 4);
8281   CONVERT_ARG_HANDLE_CHECKED(JSFunction, bound_function, 0);
8282   RUNTIME_ASSERT(args[3]->IsNumber());
8283   Handle<Object> bindee = args.at<Object>(1);
8284
8285   // TODO(lrn): Create bound function in C++ code from premade shared info.
8286   bound_function->shared()->set_bound(true);
8287   // Get all arguments of calling function (Function.prototype.bind).
8288   int argc = 0;
8289   SmartArrayPointer<Handle<Object> > arguments =
8290       GetCallerArguments(isolate, 0, &argc);
8291   // Don't count the this-arg.
8292   if (argc > 0) {
8293     RUNTIME_ASSERT(*arguments[0] == args[2]);
8294     argc--;
8295   } else {
8296     RUNTIME_ASSERT(args[2]->IsUndefined());
8297   }
8298   // Initialize array of bindings (function, this, and any existing arguments
8299   // if the function was already bound).
8300   Handle<FixedArray> new_bindings;
8301   int i;
8302   if (bindee->IsJSFunction() && JSFunction::cast(*bindee)->shared()->bound()) {
8303     Handle<FixedArray> old_bindings(
8304         JSFunction::cast(*bindee)->function_bindings());
8305     RUNTIME_ASSERT(old_bindings->length() > JSFunction::kBoundFunctionIndex);
8306     new_bindings =
8307         isolate->factory()->NewFixedArray(old_bindings->length() + argc);
8308     bindee = Handle<Object>(old_bindings->get(JSFunction::kBoundFunctionIndex),
8309                             isolate);
8310     i = 0;
8311     for (int n = old_bindings->length(); i < n; i++) {
8312       new_bindings->set(i, old_bindings->get(i));
8313     }
8314   } else {
8315     int array_size = JSFunction::kBoundArgumentsStartIndex + argc;
8316     new_bindings = isolate->factory()->NewFixedArray(array_size);
8317     new_bindings->set(JSFunction::kBoundFunctionIndex, *bindee);
8318     new_bindings->set(JSFunction::kBoundThisIndex, args[2]);
8319     i = 2;
8320   }
8321   // Copy arguments, skipping the first which is "this_arg".
8322   for (int j = 0; j < argc; j++, i++) {
8323     new_bindings->set(i, *arguments[j + 1]);
8324   }
8325   new_bindings->set_map_no_write_barrier(
8326       isolate->heap()->fixed_cow_array_map());
8327   bound_function->set_function_bindings(*new_bindings);
8328
8329   // Update length.
8330   Handle<String> length_string = isolate->factory()->length_string();
8331   Handle<Object> new_length(args.at<Object>(3));
8332   PropertyAttributes attr =
8333       static_cast<PropertyAttributes>(DONT_DELETE | DONT_ENUM | READ_ONLY);
8334   Runtime::ForceSetObjectProperty(
8335       bound_function, length_string, new_length, attr).Assert();
8336   return *bound_function;
8337 }
8338
8339
8340 RUNTIME_FUNCTION(Runtime_BoundFunctionGetBindings) {
8341   HandleScope handles(isolate);
8342   ASSERT(args.length() == 1);
8343   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, callable, 0);
8344   if (callable->IsJSFunction()) {
8345     Handle<JSFunction> function = Handle<JSFunction>::cast(callable);
8346     if (function->shared()->bound()) {
8347       Handle<FixedArray> bindings(function->function_bindings());
8348       RUNTIME_ASSERT(bindings->map() == isolate->heap()->fixed_cow_array_map());
8349       return *isolate->factory()->NewJSArrayWithElements(bindings);
8350     }
8351   }
8352   return isolate->heap()->undefined_value();
8353 }
8354
8355
8356 RUNTIME_FUNCTION(Runtime_NewObjectFromBound) {
8357   HandleScope scope(isolate);
8358   ASSERT(args.length() == 1);
8359   // First argument is a function to use as a constructor.
8360   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
8361   RUNTIME_ASSERT(function->shared()->bound());
8362
8363   // The argument is a bound function. Extract its bound arguments
8364   // and callable.
8365   Handle<FixedArray> bound_args =
8366       Handle<FixedArray>(FixedArray::cast(function->function_bindings()));
8367   int bound_argc = bound_args->length() - JSFunction::kBoundArgumentsStartIndex;
8368   Handle<Object> bound_function(
8369       JSReceiver::cast(bound_args->get(JSFunction::kBoundFunctionIndex)),
8370       isolate);
8371   ASSERT(!bound_function->IsJSFunction() ||
8372          !Handle<JSFunction>::cast(bound_function)->shared()->bound());
8373
8374   int total_argc = 0;
8375   SmartArrayPointer<Handle<Object> > param_data =
8376       GetCallerArguments(isolate, bound_argc, &total_argc);
8377   for (int i = 0; i < bound_argc; i++) {
8378     param_data[i] = Handle<Object>(bound_args->get(
8379         JSFunction::kBoundArgumentsStartIndex + i), isolate);
8380   }
8381
8382   if (!bound_function->IsJSFunction()) {
8383     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
8384         isolate, bound_function,
8385         Execution::TryGetConstructorDelegate(isolate, bound_function));
8386   }
8387   ASSERT(bound_function->IsJSFunction());
8388
8389   Handle<Object> result;
8390   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
8391       isolate, result,
8392       Execution::New(Handle<JSFunction>::cast(bound_function),
8393                      total_argc, param_data.get()));
8394   return *result;
8395 }
8396
8397
8398 static Object* Runtime_NewObjectHelper(Isolate* isolate,
8399                                             Handle<Object> constructor,
8400                                             Handle<AllocationSite> site) {
8401   // If the constructor isn't a proper function we throw a type error.
8402   if (!constructor->IsJSFunction()) {
8403     Vector< Handle<Object> > arguments = HandleVector(&constructor, 1);
8404     Handle<Object> type_error =
8405         isolate->factory()->NewTypeError("not_constructor", arguments);
8406     return isolate->Throw(*type_error);
8407   }
8408
8409   Handle<JSFunction> function = Handle<JSFunction>::cast(constructor);
8410
8411   // If function should not have prototype, construction is not allowed. In this
8412   // case generated code bailouts here, since function has no initial_map.
8413   if (!function->should_have_prototype() && !function->shared()->bound()) {
8414     Vector< Handle<Object> > arguments = HandleVector(&constructor, 1);
8415     Handle<Object> type_error =
8416         isolate->factory()->NewTypeError("not_constructor", arguments);
8417     return isolate->Throw(*type_error);
8418   }
8419
8420   Debug* debug = isolate->debug();
8421   // Handle stepping into constructors if step into is active.
8422   if (debug->StepInActive()) {
8423     debug->HandleStepIn(function, Handle<Object>::null(), 0, true);
8424   }
8425
8426   if (function->has_initial_map()) {
8427     if (function->initial_map()->instance_type() == JS_FUNCTION_TYPE) {
8428       // The 'Function' function ignores the receiver object when
8429       // called using 'new' and creates a new JSFunction object that
8430       // is returned.  The receiver object is only used for error
8431       // reporting if an error occurs when constructing the new
8432       // JSFunction. Factory::NewJSObject() should not be used to
8433       // allocate JSFunctions since it does not properly initialize
8434       // the shared part of the function. Since the receiver is
8435       // ignored anyway, we use the global object as the receiver
8436       // instead of a new JSFunction object. This way, errors are
8437       // reported the same way whether or not 'Function' is called
8438       // using 'new'.
8439       return isolate->context()->global_object();
8440     }
8441   }
8442
8443   // The function should be compiled for the optimization hints to be
8444   // available.
8445   Compiler::EnsureCompiled(function, CLEAR_EXCEPTION);
8446
8447   Handle<SharedFunctionInfo> shared(function->shared(), isolate);
8448   if (!function->has_initial_map() &&
8449       shared->IsInobjectSlackTrackingInProgress()) {
8450     // The tracking is already in progress for another function. We can only
8451     // track one initial_map at a time, so we force the completion before the
8452     // function is called as a constructor for the first time.
8453     shared->CompleteInobjectSlackTracking();
8454   }
8455
8456   Handle<JSObject> result;
8457   if (site.is_null()) {
8458     result = isolate->factory()->NewJSObject(function);
8459   } else {
8460     result = isolate->factory()->NewJSObjectWithMemento(function, site);
8461   }
8462
8463   isolate->counters()->constructed_objects()->Increment();
8464   isolate->counters()->constructed_objects_runtime()->Increment();
8465
8466   return *result;
8467 }
8468
8469
8470 RUNTIME_FUNCTION(RuntimeHidden_NewObject) {
8471   HandleScope scope(isolate);
8472   ASSERT(args.length() == 1);
8473   CONVERT_ARG_HANDLE_CHECKED(Object, constructor, 0);
8474   return Runtime_NewObjectHelper(isolate,
8475                                  constructor,
8476                                  Handle<AllocationSite>::null());
8477 }
8478
8479
8480 RUNTIME_FUNCTION(RuntimeHidden_NewObjectWithAllocationSite) {
8481   HandleScope scope(isolate);
8482   ASSERT(args.length() == 2);
8483   CONVERT_ARG_HANDLE_CHECKED(Object, constructor, 1);
8484   CONVERT_ARG_HANDLE_CHECKED(Object, feedback, 0);
8485   Handle<AllocationSite> site;
8486   if (feedback->IsAllocationSite()) {
8487     // The feedback can be an AllocationSite or undefined.
8488     site = Handle<AllocationSite>::cast(feedback);
8489   }
8490   return Runtime_NewObjectHelper(isolate, constructor, site);
8491 }
8492
8493
8494 RUNTIME_FUNCTION(RuntimeHidden_FinalizeInstanceSize) {
8495   HandleScope scope(isolate);
8496   ASSERT(args.length() == 1);
8497
8498   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
8499   function->shared()->CompleteInobjectSlackTracking();
8500
8501   return isolate->heap()->undefined_value();
8502 }
8503
8504
8505 RUNTIME_FUNCTION(RuntimeHidden_CompileUnoptimized) {
8506   HandleScope scope(isolate);
8507   ASSERT(args.length() == 1);
8508   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
8509 #ifdef DEBUG
8510   if (FLAG_trace_lazy && !function->shared()->is_compiled()) {
8511     PrintF("[unoptimized: ");
8512     function->PrintName();
8513     PrintF("]\n");
8514   }
8515 #endif
8516
8517   // Compile the target function.
8518   ASSERT(function->shared()->allows_lazy_compilation());
8519
8520   Handle<Code> code;
8521   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, code,
8522                                      Compiler::GetUnoptimizedCode(function));
8523   function->ReplaceCode(*code);
8524
8525   // All done. Return the compiled code.
8526   ASSERT(function->is_compiled());
8527   ASSERT(function->code()->kind() == Code::FUNCTION ||
8528          (FLAG_always_opt &&
8529           function->code()->kind() == Code::OPTIMIZED_FUNCTION));
8530   return *code;
8531 }
8532
8533
8534 RUNTIME_FUNCTION(RuntimeHidden_CompileOptimized) {
8535   HandleScope scope(isolate);
8536   ASSERT(args.length() == 2);
8537   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
8538   CONVERT_BOOLEAN_ARG_CHECKED(concurrent, 1);
8539
8540   Handle<Code> unoptimized(function->shared()->code());
8541   if (!function->shared()->is_compiled()) {
8542     // If the function is not compiled, do not optimize.
8543     // This can happen if the debugger is activated and
8544     // the function is returned to the not compiled state.
8545     // TODO(yangguo): reconsider this.
8546     function->ReplaceCode(function->shared()->code());
8547   } else if (!isolate->use_crankshaft() ||
8548              function->shared()->optimization_disabled() ||
8549              isolate->DebuggerHasBreakPoints()) {
8550     // If the function is not optimizable or debugger is active continue
8551     // using the code from the full compiler.
8552     if (FLAG_trace_opt) {
8553       PrintF("[failed to optimize ");
8554       function->PrintName();
8555       PrintF(": is code optimizable: %s, is debugger enabled: %s]\n",
8556           function->shared()->optimization_disabled() ? "F" : "T",
8557           isolate->DebuggerHasBreakPoints() ? "T" : "F");
8558     }
8559     function->ReplaceCode(*unoptimized);
8560   } else {
8561     Compiler::ConcurrencyMode mode = concurrent ? Compiler::CONCURRENT
8562                                                 : Compiler::NOT_CONCURRENT;
8563     Handle<Code> code;
8564     if (Compiler::GetOptimizedCode(
8565             function, unoptimized, mode).ToHandle(&code)) {
8566       function->ReplaceCode(*code);
8567     } else {
8568       function->ReplaceCode(*unoptimized);
8569     }
8570   }
8571
8572   ASSERT(function->code()->kind() == Code::FUNCTION ||
8573          function->code()->kind() == Code::OPTIMIZED_FUNCTION ||
8574          function->IsInOptimizationQueue());
8575   return function->code();
8576 }
8577
8578
8579 class ActivationsFinder : public ThreadVisitor {
8580  public:
8581   Code* code_;
8582   bool has_code_activations_;
8583
8584   explicit ActivationsFinder(Code* code)
8585     : code_(code),
8586       has_code_activations_(false) { }
8587
8588   void VisitThread(Isolate* isolate, ThreadLocalTop* top) {
8589     JavaScriptFrameIterator it(isolate, top);
8590     VisitFrames(&it);
8591   }
8592
8593   void VisitFrames(JavaScriptFrameIterator* it) {
8594     for (; !it->done(); it->Advance()) {
8595       JavaScriptFrame* frame = it->frame();
8596       if (code_->contains(frame->pc())) has_code_activations_ = true;
8597     }
8598   }
8599 };
8600
8601
8602 RUNTIME_FUNCTION(RuntimeHidden_NotifyStubFailure) {
8603   HandleScope scope(isolate);
8604   ASSERT(args.length() == 0);
8605   Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate);
8606   ASSERT(AllowHeapAllocation::IsAllowed());
8607   delete deoptimizer;
8608   return isolate->heap()->undefined_value();
8609 }
8610
8611
8612 RUNTIME_FUNCTION(RuntimeHidden_NotifyDeoptimized) {
8613   HandleScope scope(isolate);
8614   ASSERT(args.length() == 1);
8615   CONVERT_SMI_ARG_CHECKED(type_arg, 0);
8616   Deoptimizer::BailoutType type =
8617       static_cast<Deoptimizer::BailoutType>(type_arg);
8618   Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate);
8619   ASSERT(AllowHeapAllocation::IsAllowed());
8620
8621   Handle<JSFunction> function = deoptimizer->function();
8622   Handle<Code> optimized_code = deoptimizer->compiled_code();
8623
8624   ASSERT(optimized_code->kind() == Code::OPTIMIZED_FUNCTION);
8625   ASSERT(type == deoptimizer->bailout_type());
8626
8627   // Make sure to materialize objects before causing any allocation.
8628   JavaScriptFrameIterator it(isolate);
8629   deoptimizer->MaterializeHeapObjects(&it);
8630   delete deoptimizer;
8631
8632   JavaScriptFrame* frame = it.frame();
8633   RUNTIME_ASSERT(frame->function()->IsJSFunction());
8634   ASSERT(frame->function() == *function);
8635
8636   // Avoid doing too much work when running with --always-opt and keep
8637   // the optimized code around.
8638   if (FLAG_always_opt || type == Deoptimizer::LAZY) {
8639     return isolate->heap()->undefined_value();
8640   }
8641
8642   // Search for other activations of the same function and code.
8643   ActivationsFinder activations_finder(*optimized_code);
8644   activations_finder.VisitFrames(&it);
8645   isolate->thread_manager()->IterateArchivedThreads(&activations_finder);
8646
8647   if (!activations_finder.has_code_activations_) {
8648     if (function->code() == *optimized_code) {
8649       if (FLAG_trace_deopt) {
8650         PrintF("[removing optimized code for: ");
8651         function->PrintName();
8652         PrintF("]\n");
8653       }
8654       function->ReplaceCode(function->shared()->code());
8655       // Evict optimized code for this function from the cache so that it
8656       // doesn't get used for new closures.
8657       function->shared()->EvictFromOptimizedCodeMap(*optimized_code,
8658                                                     "notify deoptimized");
8659     }
8660   } else {
8661     // TODO(titzer): we should probably do DeoptimizeCodeList(code)
8662     // unconditionally if the code is not already marked for deoptimization.
8663     // If there is an index by shared function info, all the better.
8664     Deoptimizer::DeoptimizeFunction(*function);
8665   }
8666
8667   return isolate->heap()->undefined_value();
8668 }
8669
8670
8671 RUNTIME_FUNCTION(Runtime_DeoptimizeFunction) {
8672   HandleScope scope(isolate);
8673   ASSERT(args.length() == 1);
8674   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
8675   if (!function->IsOptimized()) return isolate->heap()->undefined_value();
8676
8677   Deoptimizer::DeoptimizeFunction(*function);
8678
8679   return isolate->heap()->undefined_value();
8680 }
8681
8682
8683 RUNTIME_FUNCTION(Runtime_ClearFunctionTypeFeedback) {
8684   HandleScope scope(isolate);
8685   ASSERT(args.length() == 1);
8686   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
8687   function->shared()->ClearTypeFeedbackInfo();
8688   Code* unoptimized = function->shared()->code();
8689   if (unoptimized->kind() == Code::FUNCTION) {
8690     unoptimized->ClearInlineCaches();
8691   }
8692   return isolate->heap()->undefined_value();
8693 }
8694
8695
8696 RUNTIME_FUNCTION(Runtime_RunningInSimulator) {
8697   SealHandleScope shs(isolate);
8698   ASSERT(args.length() == 0);
8699 #if defined(USE_SIMULATOR)
8700   return isolate->heap()->true_value();
8701 #else
8702   return isolate->heap()->false_value();
8703 #endif
8704 }
8705
8706
8707 RUNTIME_FUNCTION(Runtime_IsConcurrentRecompilationSupported) {
8708   SealHandleScope shs(isolate);
8709   ASSERT(args.length() == 0);
8710   return isolate->heap()->ToBoolean(
8711       isolate->concurrent_recompilation_enabled());
8712 }
8713
8714
8715 RUNTIME_FUNCTION(Runtime_OptimizeFunctionOnNextCall) {
8716   HandleScope scope(isolate);
8717   RUNTIME_ASSERT(args.length() == 1 || args.length() == 2);
8718   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
8719
8720   if (!function->IsOptimizable() &&
8721       !function->IsMarkedForConcurrentOptimization() &&
8722       !function->IsInOptimizationQueue()) {
8723     return isolate->heap()->undefined_value();
8724   }
8725
8726   function->MarkForOptimization();
8727
8728   Code* unoptimized = function->shared()->code();
8729   if (args.length() == 2 &&
8730       unoptimized->kind() == Code::FUNCTION) {
8731     CONVERT_ARG_HANDLE_CHECKED(String, type, 1);
8732     if (type->IsOneByteEqualTo(STATIC_ASCII_VECTOR("osr"))) {
8733       // Start patching from the currently patched loop nesting level.
8734       int current_level = unoptimized->allow_osr_at_loop_nesting_level();
8735       ASSERT(BackEdgeTable::Verify(isolate, unoptimized, current_level));
8736       for (int i = current_level + 1; i <= Code::kMaxLoopNestingMarker; i++) {
8737         unoptimized->set_allow_osr_at_loop_nesting_level(i);
8738         isolate->runtime_profiler()->AttemptOnStackReplacement(*function);
8739       }
8740     } else if (type->IsOneByteEqualTo(STATIC_ASCII_VECTOR("concurrent")) &&
8741                isolate->concurrent_recompilation_enabled()) {
8742       function->MarkForConcurrentOptimization();
8743     }
8744   }
8745
8746   return isolate->heap()->undefined_value();
8747 }
8748
8749
8750 RUNTIME_FUNCTION(Runtime_NeverOptimizeFunction) {
8751   HandleScope scope(isolate);
8752   ASSERT(args.length() == 1);
8753   CONVERT_ARG_CHECKED(JSFunction, function, 0);
8754   function->shared()->set_optimization_disabled(true);
8755   return isolate->heap()->undefined_value();
8756 }
8757
8758
8759 RUNTIME_FUNCTION(Runtime_GetOptimizationStatus) {
8760   HandleScope scope(isolate);
8761   RUNTIME_ASSERT(args.length() == 1 || args.length() == 2);
8762   if (!isolate->use_crankshaft()) {
8763     return Smi::FromInt(4);  // 4 == "never".
8764   }
8765   bool sync_with_compiler_thread = true;
8766   if (args.length() == 2) {
8767     CONVERT_ARG_HANDLE_CHECKED(String, sync, 1);
8768     if (sync->IsOneByteEqualTo(STATIC_ASCII_VECTOR("no sync"))) {
8769       sync_with_compiler_thread = false;
8770     }
8771   }
8772   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
8773   if (isolate->concurrent_recompilation_enabled() &&
8774       sync_with_compiler_thread) {
8775     while (function->IsInOptimizationQueue()) {
8776       isolate->optimizing_compiler_thread()->InstallOptimizedFunctions();
8777       OS::Sleep(50);
8778     }
8779   }
8780   if (FLAG_always_opt) {
8781     // We may have always opt, but that is more best-effort than a real
8782     // promise, so we still say "no" if it is not optimized.
8783     return function->IsOptimized() ? Smi::FromInt(3)   // 3 == "always".
8784                                    : Smi::FromInt(2);  // 2 == "no".
8785   }
8786   if (FLAG_deopt_every_n_times) {
8787     return Smi::FromInt(6);  // 6 == "maybe deopted".
8788   }
8789   return function->IsOptimized() ? Smi::FromInt(1)   // 1 == "yes".
8790                                  : Smi::FromInt(2);  // 2 == "no".
8791 }
8792
8793
8794 RUNTIME_FUNCTION(Runtime_UnblockConcurrentRecompilation) {
8795   ASSERT(args.length() == 0);
8796   RUNTIME_ASSERT(FLAG_block_concurrent_recompilation);
8797   RUNTIME_ASSERT(isolate->concurrent_recompilation_enabled());
8798   isolate->optimizing_compiler_thread()->Unblock();
8799   return isolate->heap()->undefined_value();
8800 }
8801
8802
8803 RUNTIME_FUNCTION(Runtime_GetOptimizationCount) {
8804   HandleScope scope(isolate);
8805   ASSERT(args.length() == 1);
8806   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
8807   return Smi::FromInt(function->shared()->opt_count());
8808 }
8809
8810
8811 static bool IsSuitableForOnStackReplacement(Isolate* isolate,
8812                                             Handle<JSFunction> function,
8813                                             Handle<Code> current_code) {
8814   // Keep track of whether we've succeeded in optimizing.
8815   if (!isolate->use_crankshaft() || !current_code->optimizable()) return false;
8816   // If we are trying to do OSR when there are already optimized
8817   // activations of the function, it means (a) the function is directly or
8818   // indirectly recursive and (b) an optimized invocation has been
8819   // deoptimized so that we are currently in an unoptimized activation.
8820   // Check for optimized activations of this function.
8821   for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) {
8822     JavaScriptFrame* frame = it.frame();
8823     if (frame->is_optimized() && frame->function() == *function) return false;
8824   }
8825
8826   return true;
8827 }
8828
8829
8830 RUNTIME_FUNCTION(Runtime_CompileForOnStackReplacement) {
8831   HandleScope scope(isolate);
8832   ASSERT(args.length() == 1);
8833   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
8834   Handle<Code> caller_code(function->shared()->code());
8835
8836   // We're not prepared to handle a function with arguments object.
8837   ASSERT(!function->shared()->uses_arguments());
8838
8839   // Passing the PC in the javascript frame from the caller directly is
8840   // not GC safe, so we walk the stack to get it.
8841   JavaScriptFrameIterator it(isolate);
8842   JavaScriptFrame* frame = it.frame();
8843   if (!caller_code->contains(frame->pc())) {
8844     // Code on the stack may not be the code object referenced by the shared
8845     // function info.  It may have been replaced to include deoptimization data.
8846     caller_code = Handle<Code>(frame->LookupCode());
8847   }
8848
8849   uint32_t pc_offset = static_cast<uint32_t>(
8850       frame->pc() - caller_code->instruction_start());
8851
8852 #ifdef DEBUG
8853   ASSERT_EQ(frame->function(), *function);
8854   ASSERT_EQ(frame->LookupCode(), *caller_code);
8855   ASSERT(caller_code->contains(frame->pc()));
8856 #endif  // DEBUG
8857
8858
8859   BailoutId ast_id = caller_code->TranslatePcOffsetToAstId(pc_offset);
8860   ASSERT(!ast_id.IsNone());
8861
8862   Compiler::ConcurrencyMode mode = isolate->concurrent_osr_enabled()
8863       ? Compiler::CONCURRENT : Compiler::NOT_CONCURRENT;
8864   Handle<Code> result = Handle<Code>::null();
8865
8866   OptimizedCompileJob* job = NULL;
8867   if (mode == Compiler::CONCURRENT) {
8868     // Gate the OSR entry with a stack check.
8869     BackEdgeTable::AddStackCheck(caller_code, pc_offset);
8870     // Poll already queued compilation jobs.
8871     OptimizingCompilerThread* thread = isolate->optimizing_compiler_thread();
8872     if (thread->IsQueuedForOSR(function, ast_id)) {
8873       if (FLAG_trace_osr) {
8874         PrintF("[OSR - Still waiting for queued: ");
8875         function->PrintName();
8876         PrintF(" at AST id %d]\n", ast_id.ToInt());
8877       }
8878       return NULL;
8879     }
8880
8881     job = thread->FindReadyOSRCandidate(function, ast_id);
8882   }
8883
8884   if (job != NULL) {
8885     if (FLAG_trace_osr) {
8886       PrintF("[OSR - Found ready: ");
8887       function->PrintName();
8888       PrintF(" at AST id %d]\n", ast_id.ToInt());
8889     }
8890     result = Compiler::GetConcurrentlyOptimizedCode(job);
8891   } else if (IsSuitableForOnStackReplacement(isolate, function, caller_code)) {
8892     if (FLAG_trace_osr) {
8893       PrintF("[OSR - Compiling: ");
8894       function->PrintName();
8895       PrintF(" at AST id %d]\n", ast_id.ToInt());
8896     }
8897     MaybeHandle<Code> maybe_result = Compiler::GetOptimizedCode(
8898         function, caller_code, mode, ast_id);
8899     if (maybe_result.ToHandle(&result) &&
8900         result.is_identical_to(isolate->builtins()->InOptimizationQueue())) {
8901       // Optimization is queued.  Return to check later.
8902       return NULL;
8903     }
8904   }
8905
8906   // Revert the patched back edge table, regardless of whether OSR succeeds.
8907   BackEdgeTable::Revert(isolate, *caller_code);
8908
8909   // Check whether we ended up with usable optimized code.
8910   if (!result.is_null() && result->kind() == Code::OPTIMIZED_FUNCTION) {
8911     DeoptimizationInputData* data =
8912         DeoptimizationInputData::cast(result->deoptimization_data());
8913
8914     if (data->OsrPcOffset()->value() >= 0) {
8915       ASSERT(BailoutId(data->OsrAstId()->value()) == ast_id);
8916       if (FLAG_trace_osr) {
8917         PrintF("[OSR - Entry at AST id %d, offset %d in optimized code]\n",
8918                ast_id.ToInt(), data->OsrPcOffset()->value());
8919       }
8920       // TODO(titzer): this is a massive hack to make the deopt counts
8921       // match. Fix heuristics for reenabling optimizations!
8922       function->shared()->increment_deopt_count();
8923
8924       // TODO(titzer): Do not install code into the function.
8925       function->ReplaceCode(*result);
8926       return *result;
8927     }
8928   }
8929
8930   // Failed.
8931   if (FLAG_trace_osr) {
8932     PrintF("[OSR - Failed: ");
8933     function->PrintName();
8934     PrintF(" at AST id %d]\n", ast_id.ToInt());
8935   }
8936
8937   if (!function->IsOptimized()) {
8938     function->ReplaceCode(function->shared()->code());
8939   }
8940   return NULL;
8941 }
8942
8943
8944 RUNTIME_FUNCTION(Runtime_SetAllocationTimeout) {
8945   SealHandleScope shs(isolate);
8946   ASSERT(args.length() == 2 || args.length() == 3);
8947 #ifdef DEBUG
8948   CONVERT_SMI_ARG_CHECKED(interval, 0);
8949   CONVERT_SMI_ARG_CHECKED(timeout, 1);
8950   isolate->heap()->set_allocation_timeout(timeout);
8951   FLAG_gc_interval = interval;
8952   if (args.length() == 3) {
8953     // Enable/disable inline allocation if requested.
8954     CONVERT_BOOLEAN_ARG_CHECKED(inline_allocation, 2);
8955     if (inline_allocation) {
8956       isolate->heap()->EnableInlineAllocation();
8957     } else {
8958       isolate->heap()->DisableInlineAllocation();
8959     }
8960   }
8961 #endif
8962   return isolate->heap()->undefined_value();
8963 }
8964
8965
8966 RUNTIME_FUNCTION(Runtime_CheckIsBootstrapping) {
8967   SealHandleScope shs(isolate);
8968   ASSERT(args.length() == 0);
8969   RUNTIME_ASSERT(isolate->bootstrapper()->IsActive());
8970   return isolate->heap()->undefined_value();
8971 }
8972
8973
8974 RUNTIME_FUNCTION(Runtime_GetRootNaN) {
8975   SealHandleScope shs(isolate);
8976   ASSERT(args.length() == 0);
8977   RUNTIME_ASSERT(isolate->bootstrapper()->IsActive());
8978   return isolate->heap()->nan_value();
8979 }
8980
8981
8982 RUNTIME_FUNCTION(Runtime_Call) {
8983   HandleScope scope(isolate);
8984   ASSERT(args.length() >= 2);
8985   int argc = args.length() - 2;
8986   CONVERT_ARG_CHECKED(JSReceiver, fun, argc + 1);
8987   Object* receiver = args[0];
8988
8989   // If there are too many arguments, allocate argv via malloc.
8990   const int argv_small_size = 10;
8991   Handle<Object> argv_small_buffer[argv_small_size];
8992   SmartArrayPointer<Handle<Object> > argv_large_buffer;
8993   Handle<Object>* argv = argv_small_buffer;
8994   if (argc > argv_small_size) {
8995     argv = new Handle<Object>[argc];
8996     if (argv == NULL) return isolate->StackOverflow();
8997     argv_large_buffer = SmartArrayPointer<Handle<Object> >(argv);
8998   }
8999
9000   for (int i = 0; i < argc; ++i) {
9001      argv[i] = Handle<Object>(args[1 + i], isolate);
9002   }
9003
9004   Handle<JSReceiver> hfun(fun);
9005   Handle<Object> hreceiver(receiver, isolate);
9006   Handle<Object> result;
9007   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
9008       isolate, result,
9009       Execution::Call(isolate, hfun, hreceiver, argc, argv, true));
9010   return *result;
9011 }
9012
9013
9014 RUNTIME_FUNCTION(Runtime_Apply) {
9015   HandleScope scope(isolate);
9016   ASSERT(args.length() == 5);
9017   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, fun, 0);
9018   CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 1);
9019   CONVERT_ARG_HANDLE_CHECKED(JSObject, arguments, 2);
9020   CONVERT_SMI_ARG_CHECKED(offset, 3);
9021   CONVERT_SMI_ARG_CHECKED(argc, 4);
9022   RUNTIME_ASSERT(offset >= 0);
9023   // Loose upper bound to allow fuzzing. We'll most likely run out of
9024   // stack space before hitting this limit.
9025   static int kMaxArgc = 1000000;
9026   RUNTIME_ASSERT(argc >= 0 && argc <= kMaxArgc);
9027
9028   // If there are too many arguments, allocate argv via malloc.
9029   const int argv_small_size = 10;
9030   Handle<Object> argv_small_buffer[argv_small_size];
9031   SmartArrayPointer<Handle<Object> > argv_large_buffer;
9032   Handle<Object>* argv = argv_small_buffer;
9033   if (argc > argv_small_size) {
9034     argv = new Handle<Object>[argc];
9035     if (argv == NULL) return isolate->StackOverflow();
9036     argv_large_buffer = SmartArrayPointer<Handle<Object> >(argv);
9037   }
9038
9039   for (int i = 0; i < argc; ++i) {
9040     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
9041         isolate, argv[i],
9042         Object::GetElement(isolate, arguments, offset + i));
9043   }
9044
9045   Handle<Object> result;
9046   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
9047       isolate, result,
9048       Execution::Call(isolate, fun, receiver, argc, argv, true));
9049   return *result;
9050 }
9051
9052
9053 RUNTIME_FUNCTION(Runtime_GetFunctionDelegate) {
9054   HandleScope scope(isolate);
9055   ASSERT(args.length() == 1);
9056   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
9057   RUNTIME_ASSERT(!object->IsJSFunction());
9058   return *Execution::GetFunctionDelegate(isolate, object);
9059 }
9060
9061
9062 RUNTIME_FUNCTION(Runtime_GetConstructorDelegate) {
9063   HandleScope scope(isolate);
9064   ASSERT(args.length() == 1);
9065   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
9066   RUNTIME_ASSERT(!object->IsJSFunction());
9067   return *Execution::GetConstructorDelegate(isolate, object);
9068 }
9069
9070
9071 RUNTIME_FUNCTION(RuntimeHidden_NewGlobalContext) {
9072   HandleScope scope(isolate);
9073   ASSERT(args.length() == 2);
9074
9075   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
9076   CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 1);
9077   Handle<Context> result =
9078       isolate->factory()->NewGlobalContext(function, scope_info);
9079
9080   ASSERT(function->context() == isolate->context());
9081   ASSERT(function->context()->global_object() == result->global_object());
9082   result->global_object()->set_global_context(*result);
9083   return *result;
9084 }
9085
9086
9087 RUNTIME_FUNCTION(RuntimeHidden_NewFunctionContext) {
9088   HandleScope scope(isolate);
9089   ASSERT(args.length() == 1);
9090
9091   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
9092   int length = function->shared()->scope_info()->ContextLength();
9093   return *isolate->factory()->NewFunctionContext(length, function);
9094 }
9095
9096
9097 RUNTIME_FUNCTION(RuntimeHidden_PushWithContext) {
9098   HandleScope scope(isolate);
9099   ASSERT(args.length() == 2);
9100   Handle<JSReceiver> extension_object;
9101   if (args[0]->IsJSReceiver()) {
9102     extension_object = args.at<JSReceiver>(0);
9103   } else {
9104     // Try to convert the object to a proper JavaScript object.
9105     MaybeHandle<JSReceiver> maybe_object =
9106         Object::ToObject(isolate, args.at<Object>(0));
9107     if (!maybe_object.ToHandle(&extension_object)) {
9108       Handle<Object> handle = args.at<Object>(0);
9109       Handle<Object> result =
9110           isolate->factory()->NewTypeError("with_expression",
9111                                            HandleVector(&handle, 1));
9112       return isolate->Throw(*result);
9113     }
9114   }
9115
9116   Handle<JSFunction> function;
9117   if (args[1]->IsSmi()) {
9118     // A smi sentinel indicates a context nested inside global code rather
9119     // than some function.  There is a canonical empty function that can be
9120     // gotten from the native context.
9121     function = handle(isolate->context()->native_context()->closure());
9122   } else {
9123     function = args.at<JSFunction>(1);
9124   }
9125
9126   Handle<Context> current(isolate->context());
9127   Handle<Context> context = isolate->factory()->NewWithContext(
9128       function, current, extension_object);
9129   isolate->set_context(*context);
9130   return *context;
9131 }
9132
9133
9134 RUNTIME_FUNCTION(RuntimeHidden_PushCatchContext) {
9135   HandleScope scope(isolate);
9136   ASSERT(args.length() == 3);
9137   CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
9138   CONVERT_ARG_HANDLE_CHECKED(Object, thrown_object, 1);
9139   Handle<JSFunction> function;
9140   if (args[2]->IsSmi()) {
9141     // A smi sentinel indicates a context nested inside global code rather
9142     // than some function.  There is a canonical empty function that can be
9143     // gotten from the native context.
9144     function = handle(isolate->context()->native_context()->closure());
9145   } else {
9146     function = args.at<JSFunction>(2);
9147   }
9148   Handle<Context> current(isolate->context());
9149   Handle<Context> context = isolate->factory()->NewCatchContext(
9150       function, current, name, thrown_object);
9151   isolate->set_context(*context);
9152   return *context;
9153 }
9154
9155
9156 RUNTIME_FUNCTION(RuntimeHidden_PushBlockContext) {
9157   HandleScope scope(isolate);
9158   ASSERT(args.length() == 2);
9159   CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 0);
9160   Handle<JSFunction> function;
9161   if (args[1]->IsSmi()) {
9162     // A smi sentinel indicates a context nested inside global code rather
9163     // than some function.  There is a canonical empty function that can be
9164     // gotten from the native context.
9165     function = handle(isolate->context()->native_context()->closure());
9166   } else {
9167     function = args.at<JSFunction>(1);
9168   }
9169   Handle<Context> current(isolate->context());
9170   Handle<Context> context = isolate->factory()->NewBlockContext(
9171       function, current, scope_info);
9172   isolate->set_context(*context);
9173   return *context;
9174 }
9175
9176
9177 RUNTIME_FUNCTION(Runtime_IsJSModule) {
9178   SealHandleScope shs(isolate);
9179   ASSERT(args.length() == 1);
9180   CONVERT_ARG_CHECKED(Object, obj, 0);
9181   return isolate->heap()->ToBoolean(obj->IsJSModule());
9182 }
9183
9184
9185 RUNTIME_FUNCTION(RuntimeHidden_PushModuleContext) {
9186   SealHandleScope shs(isolate);
9187   ASSERT(args.length() == 2);
9188   CONVERT_SMI_ARG_CHECKED(index, 0);
9189
9190   if (!args[1]->IsScopeInfo()) {
9191     // Module already initialized. Find hosting context and retrieve context.
9192     Context* host = Context::cast(isolate->context())->global_context();
9193     Context* context = Context::cast(host->get(index));
9194     ASSERT(context->previous() == isolate->context());
9195     isolate->set_context(context);
9196     return context;
9197   }
9198
9199   CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 1);
9200
9201   // Allocate module context.
9202   HandleScope scope(isolate);
9203   Factory* factory = isolate->factory();
9204   Handle<Context> context = factory->NewModuleContext(scope_info);
9205   Handle<JSModule> module = factory->NewJSModule(context, scope_info);
9206   context->set_module(*module);
9207   Context* previous = isolate->context();
9208   context->set_previous(previous);
9209   context->set_closure(previous->closure());
9210   context->set_global_object(previous->global_object());
9211   isolate->set_context(*context);
9212
9213   // Find hosting scope and initialize internal variable holding module there.
9214   previous->global_context()->set(index, *context);
9215
9216   return *context;
9217 }
9218
9219
9220 RUNTIME_FUNCTION(RuntimeHidden_DeclareModules) {
9221   HandleScope scope(isolate);
9222   ASSERT(args.length() == 1);
9223   CONVERT_ARG_HANDLE_CHECKED(FixedArray, descriptions, 0);
9224   Context* host_context = isolate->context();
9225
9226   for (int i = 0; i < descriptions->length(); ++i) {
9227     Handle<ModuleInfo> description(ModuleInfo::cast(descriptions->get(i)));
9228     int host_index = description->host_index();
9229     Handle<Context> context(Context::cast(host_context->get(host_index)));
9230     Handle<JSModule> module(context->module());
9231
9232     for (int j = 0; j < description->length(); ++j) {
9233       Handle<String> name(description->name(j));
9234       VariableMode mode = description->mode(j);
9235       int index = description->index(j);
9236       switch (mode) {
9237         case VAR:
9238         case LET:
9239         case CONST:
9240         case CONST_LEGACY: {
9241           PropertyAttributes attr =
9242               IsImmutableVariableMode(mode) ? FROZEN : SEALED;
9243           Handle<AccessorInfo> info =
9244               Accessors::MakeModuleExport(name, index, attr);
9245           Handle<Object> result =
9246               JSObject::SetAccessor(module, info).ToHandleChecked();
9247           ASSERT(!result->IsUndefined());
9248           USE(result);
9249           break;
9250         }
9251         case MODULE: {
9252           Object* referenced_context = Context::cast(host_context)->get(index);
9253           Handle<JSModule> value(Context::cast(referenced_context)->module());
9254           JSReceiver::SetProperty(module, name, value, FROZEN, STRICT).Assert();
9255           break;
9256         }
9257         case INTERNAL:
9258         case TEMPORARY:
9259         case DYNAMIC:
9260         case DYNAMIC_GLOBAL:
9261         case DYNAMIC_LOCAL:
9262           UNREACHABLE();
9263       }
9264     }
9265
9266     JSObject::PreventExtensions(module).Assert();
9267   }
9268
9269   ASSERT(!isolate->has_pending_exception());
9270   return isolate->heap()->undefined_value();
9271 }
9272
9273
9274 RUNTIME_FUNCTION(RuntimeHidden_DeleteContextSlot) {
9275   HandleScope scope(isolate);
9276   ASSERT(args.length() == 2);
9277
9278   CONVERT_ARG_HANDLE_CHECKED(Context, context, 0);
9279   CONVERT_ARG_HANDLE_CHECKED(String, name, 1);
9280
9281   int index;
9282   PropertyAttributes attributes;
9283   ContextLookupFlags flags = FOLLOW_CHAINS;
9284   BindingFlags binding_flags;
9285   Handle<Object> holder = context->Lookup(name,
9286                                           flags,
9287                                           &index,
9288                                           &attributes,
9289                                           &binding_flags);
9290
9291   // If the slot was not found the result is true.
9292   if (holder.is_null()) {
9293     return isolate->heap()->true_value();
9294   }
9295
9296   // If the slot was found in a context, it should be DONT_DELETE.
9297   if (holder->IsContext()) {
9298     return isolate->heap()->false_value();
9299   }
9300
9301   // The slot was found in a JSObject, either a context extension object,
9302   // the global object, or the subject of a with.  Try to delete it
9303   // (respecting DONT_DELETE).
9304   Handle<JSObject> object = Handle<JSObject>::cast(holder);
9305   Handle<Object> result;
9306   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
9307       isolate, result,
9308       JSReceiver::DeleteProperty(object, name));
9309   return *result;
9310 }
9311
9312
9313 // A mechanism to return a pair of Object pointers in registers (if possible).
9314 // How this is achieved is calling convention-dependent.
9315 // All currently supported x86 compiles uses calling conventions that are cdecl
9316 // variants where a 64-bit value is returned in two 32-bit registers
9317 // (edx:eax on ia32, r1:r0 on ARM).
9318 // In AMD-64 calling convention a struct of two pointers is returned in rdx:rax.
9319 // In Win64 calling convention, a struct of two pointers is returned in memory,
9320 // allocated by the caller, and passed as a pointer in a hidden first parameter.
9321 #ifdef V8_HOST_ARCH_64_BIT
9322 struct ObjectPair {
9323   Object* x;
9324   Object* y;
9325 };
9326
9327
9328 static inline ObjectPair MakePair(Object* x, Object* y) {
9329   ObjectPair result = {x, y};
9330   // Pointers x and y returned in rax and rdx, in AMD-x64-abi.
9331   // In Win64 they are assigned to a hidden first argument.
9332   return result;
9333 }
9334 #else
9335 typedef uint64_t ObjectPair;
9336 static inline ObjectPair MakePair(Object* x, Object* y) {
9337 #if defined(V8_TARGET_LITTLE_ENDIAN)
9338   return reinterpret_cast<uint32_t>(x) |
9339       (reinterpret_cast<ObjectPair>(y) << 32);
9340 #elif defined(V8_TARGET_BIG_ENDIAN)
9341     return reinterpret_cast<uint32_t>(y) |
9342         (reinterpret_cast<ObjectPair>(x) << 32);
9343 #else
9344 #error Unknown endianness
9345 #endif
9346 }
9347 #endif
9348
9349
9350 static Object* ComputeReceiverForNonGlobal(Isolate* isolate,
9351                                            JSObject* holder) {
9352   ASSERT(!holder->IsGlobalObject());
9353   Context* top = isolate->context();
9354   // Get the context extension function.
9355   JSFunction* context_extension_function =
9356       top->native_context()->context_extension_function();
9357   // If the holder isn't a context extension object, we just return it
9358   // as the receiver. This allows arguments objects to be used as
9359   // receivers, but only if they are put in the context scope chain
9360   // explicitly via a with-statement.
9361   Object* constructor = holder->map()->constructor();
9362   if (constructor != context_extension_function) return holder;
9363   // Fall back to using the global object as the implicit receiver if
9364   // the property turns out to be a local variable allocated in a
9365   // context extension object - introduced via eval.
9366   return isolate->heap()->undefined_value();
9367 }
9368
9369
9370 static ObjectPair LoadContextSlotHelper(Arguments args,
9371                                         Isolate* isolate,
9372                                         bool throw_error) {
9373   HandleScope scope(isolate);
9374   ASSERT_EQ(2, args.length());
9375
9376   if (!args[0]->IsContext() || !args[1]->IsString()) {
9377     return MakePair(isolate->ThrowIllegalOperation(), NULL);
9378   }
9379   Handle<Context> context = args.at<Context>(0);
9380   Handle<String> name = args.at<String>(1);
9381
9382   int index;
9383   PropertyAttributes attributes;
9384   ContextLookupFlags flags = FOLLOW_CHAINS;
9385   BindingFlags binding_flags;
9386   Handle<Object> holder = context->Lookup(name,
9387                                           flags,
9388                                           &index,
9389                                           &attributes,
9390                                           &binding_flags);
9391   if (isolate->has_pending_exception()) {
9392     return MakePair(isolate->heap()->exception(), NULL);
9393   }
9394
9395   // If the index is non-negative, the slot has been found in a context.
9396   if (index >= 0) {
9397     ASSERT(holder->IsContext());
9398     // If the "property" we were looking for is a local variable, the
9399     // receiver is the global object; see ECMA-262, 3rd., 10.1.6 and 10.2.3.
9400     Handle<Object> receiver = isolate->factory()->undefined_value();
9401     Object* value = Context::cast(*holder)->get(index);
9402     // Check for uninitialized bindings.
9403     switch (binding_flags) {
9404       case MUTABLE_CHECK_INITIALIZED:
9405       case IMMUTABLE_CHECK_INITIALIZED_HARMONY:
9406         if (value->IsTheHole()) {
9407           Handle<Object> reference_error =
9408               isolate->factory()->NewReferenceError("not_defined",
9409                                                     HandleVector(&name, 1));
9410           return MakePair(isolate->Throw(*reference_error), NULL);
9411         }
9412         // FALLTHROUGH
9413       case MUTABLE_IS_INITIALIZED:
9414       case IMMUTABLE_IS_INITIALIZED:
9415       case IMMUTABLE_IS_INITIALIZED_HARMONY:
9416         ASSERT(!value->IsTheHole());
9417         return MakePair(value, *receiver);
9418       case IMMUTABLE_CHECK_INITIALIZED:
9419         if (value->IsTheHole()) {
9420           ASSERT((attributes & READ_ONLY) != 0);
9421           value = isolate->heap()->undefined_value();
9422         }
9423         return MakePair(value, *receiver);
9424       case MISSING_BINDING:
9425         UNREACHABLE();
9426         return MakePair(NULL, NULL);
9427     }
9428   }
9429
9430   // Otherwise, if the slot was found the holder is a context extension
9431   // object, subject of a with, or a global object.  We read the named
9432   // property from it.
9433   if (!holder.is_null()) {
9434     Handle<JSReceiver> object = Handle<JSReceiver>::cast(holder);
9435     ASSERT(object->IsJSProxy() || JSReceiver::HasProperty(object, name));
9436     // GetProperty below can cause GC.
9437     Handle<Object> receiver_handle(
9438         object->IsGlobalObject()
9439             ? Object::cast(isolate->heap()->undefined_value())
9440             : object->IsJSProxy() ? static_cast<Object*>(*object)
9441                 : ComputeReceiverForNonGlobal(isolate, JSObject::cast(*object)),
9442         isolate);
9443
9444     // No need to unhole the value here.  This is taken care of by the
9445     // GetProperty function.
9446     Handle<Object> value;
9447     ASSIGN_RETURN_ON_EXCEPTION_VALUE(
9448         isolate, value,
9449         Object::GetProperty(object, name),
9450         MakePair(isolate->heap()->exception(), NULL));
9451     return MakePair(*value, *receiver_handle);
9452   }
9453
9454   if (throw_error) {
9455     // The property doesn't exist - throw exception.
9456     Handle<Object> reference_error =
9457         isolate->factory()->NewReferenceError("not_defined",
9458                                               HandleVector(&name, 1));
9459     return MakePair(isolate->Throw(*reference_error), NULL);
9460   } else {
9461     // The property doesn't exist - return undefined.
9462     return MakePair(isolate->heap()->undefined_value(),
9463                     isolate->heap()->undefined_value());
9464   }
9465 }
9466
9467
9468 RUNTIME_FUNCTION_RETURN_PAIR(RuntimeHidden_LoadContextSlot) {
9469   return LoadContextSlotHelper(args, isolate, true);
9470 }
9471
9472
9473 RUNTIME_FUNCTION_RETURN_PAIR(RuntimeHidden_LoadContextSlotNoReferenceError) {
9474   return LoadContextSlotHelper(args, isolate, false);
9475 }
9476
9477
9478 RUNTIME_FUNCTION(RuntimeHidden_StoreContextSlot) {
9479   HandleScope scope(isolate);
9480   ASSERT(args.length() == 4);
9481
9482   CONVERT_ARG_HANDLE_CHECKED(Object, value, 0);
9483   CONVERT_ARG_HANDLE_CHECKED(Context, context, 1);
9484   CONVERT_ARG_HANDLE_CHECKED(String, name, 2);
9485   CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 3);
9486
9487   int index;
9488   PropertyAttributes attributes;
9489   ContextLookupFlags flags = FOLLOW_CHAINS;
9490   BindingFlags binding_flags;
9491   Handle<Object> holder = context->Lookup(name,
9492                                           flags,
9493                                           &index,
9494                                           &attributes,
9495                                           &binding_flags);
9496   if (isolate->has_pending_exception()) return isolate->heap()->exception();
9497
9498   if (index >= 0) {
9499     // The property was found in a context slot.
9500     Handle<Context> context = Handle<Context>::cast(holder);
9501     if (binding_flags == MUTABLE_CHECK_INITIALIZED &&
9502         context->get(index)->IsTheHole()) {
9503       Handle<Object> error =
9504           isolate->factory()->NewReferenceError("not_defined",
9505                                                 HandleVector(&name, 1));
9506       return isolate->Throw(*error);
9507     }
9508     // Ignore if read_only variable.
9509     if ((attributes & READ_ONLY) == 0) {
9510       // Context is a fixed array and set cannot fail.
9511       context->set(index, *value);
9512     } else if (strict_mode == STRICT) {
9513       // Setting read only property in strict mode.
9514       Handle<Object> error =
9515           isolate->factory()->NewTypeError("strict_cannot_assign",
9516                                            HandleVector(&name, 1));
9517       return isolate->Throw(*error);
9518     }
9519     return *value;
9520   }
9521
9522   // Slow case: The property is not in a context slot.  It is either in a
9523   // context extension object, a property of the subject of a with, or a
9524   // property of the global object.
9525   Handle<JSReceiver> object;
9526
9527   if (!holder.is_null()) {
9528     // The property exists on the holder.
9529     object = Handle<JSReceiver>::cast(holder);
9530   } else {
9531     // The property was not found.
9532     ASSERT(attributes == ABSENT);
9533
9534     if (strict_mode == STRICT) {
9535       // Throw in strict mode (assignment to undefined variable).
9536       Handle<Object> error =
9537           isolate->factory()->NewReferenceError(
9538               "not_defined", HandleVector(&name, 1));
9539       return isolate->Throw(*error);
9540     }
9541     // In sloppy mode, the property is added to the global object.
9542     attributes = NONE;
9543     object = Handle<JSReceiver>(isolate->context()->global_object());
9544   }
9545
9546   // Set the property if it's not read only or doesn't yet exist.
9547   if ((attributes & READ_ONLY) == 0 ||
9548       (JSReceiver::GetLocalPropertyAttribute(object, name) == ABSENT)) {
9549     RETURN_FAILURE_ON_EXCEPTION(
9550         isolate,
9551         JSReceiver::SetProperty(object, name, value, NONE, strict_mode));
9552   } else if (strict_mode == STRICT && (attributes & READ_ONLY) != 0) {
9553     // Setting read only property in strict mode.
9554     Handle<Object> error =
9555       isolate->factory()->NewTypeError(
9556           "strict_cannot_assign", HandleVector(&name, 1));
9557     return isolate->Throw(*error);
9558   }
9559   return *value;
9560 }
9561
9562
9563 RUNTIME_FUNCTION(RuntimeHidden_Throw) {
9564   HandleScope scope(isolate);
9565   ASSERT(args.length() == 1);
9566
9567   return isolate->Throw(args[0]);
9568 }
9569
9570
9571 RUNTIME_FUNCTION(RuntimeHidden_ReThrow) {
9572   HandleScope scope(isolate);
9573   ASSERT(args.length() == 1);
9574
9575   return isolate->ReThrow(args[0]);
9576 }
9577
9578
9579 RUNTIME_FUNCTION(RuntimeHidden_PromoteScheduledException) {
9580   SealHandleScope shs(isolate);
9581   ASSERT(args.length() == 0);
9582   return isolate->PromoteScheduledException();
9583 }
9584
9585
9586 RUNTIME_FUNCTION(RuntimeHidden_ThrowReferenceError) {
9587   HandleScope scope(isolate);
9588   ASSERT(args.length() == 1);
9589   CONVERT_ARG_HANDLE_CHECKED(Object, name, 0);
9590   Handle<Object> reference_error =
9591     isolate->factory()->NewReferenceError("not_defined",
9592                                           HandleVector(&name, 1));
9593   return isolate->Throw(*reference_error);
9594 }
9595
9596
9597 RUNTIME_FUNCTION(RuntimeHidden_ThrowNotDateError) {
9598   HandleScope scope(isolate);
9599   ASSERT(args.length() == 0);
9600   return isolate->Throw(*isolate->factory()->NewTypeError(
9601       "not_date_object", HandleVector<Object>(NULL, 0)));
9602 }
9603
9604
9605 RUNTIME_FUNCTION(RuntimeHidden_ThrowMessage) {
9606   HandleScope scope(isolate);
9607   ASSERT(args.length() == 1);
9608   CONVERT_SMI_ARG_CHECKED(message_id, 0);
9609   const char* message = GetBailoutReason(
9610       static_cast<BailoutReason>(message_id));
9611   Handle<String> message_handle =
9612       isolate->factory()->NewStringFromAsciiChecked(message);
9613   return isolate->Throw(*message_handle);
9614 }
9615
9616
9617 RUNTIME_FUNCTION(RuntimeHidden_StackGuard) {
9618   SealHandleScope shs(isolate);
9619   ASSERT(args.length() == 0);
9620
9621   // First check if this is a real stack overflow.
9622   if (isolate->stack_guard()->IsStackOverflow()) {
9623     return isolate->StackOverflow();
9624   }
9625
9626   return Execution::HandleStackGuardInterrupt(isolate);
9627 }
9628
9629
9630 RUNTIME_FUNCTION(RuntimeHidden_TryInstallOptimizedCode) {
9631   HandleScope scope(isolate);
9632   ASSERT(args.length() == 1);
9633   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
9634
9635   // First check if this is a real stack overflow.
9636   if (isolate->stack_guard()->IsStackOverflow()) {
9637     SealHandleScope shs(isolate);
9638     return isolate->StackOverflow();
9639   }
9640
9641   isolate->optimizing_compiler_thread()->InstallOptimizedFunctions();
9642   return (function->IsOptimized()) ? function->code()
9643                                    : function->shared()->code();
9644 }
9645
9646
9647 RUNTIME_FUNCTION(RuntimeHidden_Interrupt) {
9648   SealHandleScope shs(isolate);
9649   ASSERT(args.length() == 0);
9650   return Execution::HandleStackGuardInterrupt(isolate);
9651 }
9652
9653
9654 static int StackSize(Isolate* isolate) {
9655   int n = 0;
9656   for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) n++;
9657   return n;
9658 }
9659
9660
9661 static void PrintTransition(Isolate* isolate, Object* result) {
9662   // indentation
9663   { const int nmax = 80;
9664     int n = StackSize(isolate);
9665     if (n <= nmax)
9666       PrintF("%4d:%*s", n, n, "");
9667     else
9668       PrintF("%4d:%*s", n, nmax, "...");
9669   }
9670
9671   if (result == NULL) {
9672     JavaScriptFrame::PrintTop(isolate, stdout, true, false);
9673     PrintF(" {\n");
9674   } else {
9675     // function result
9676     PrintF("} -> ");
9677     result->ShortPrint();
9678     PrintF("\n");
9679   }
9680 }
9681
9682
9683 RUNTIME_FUNCTION(Runtime_TraceEnter) {
9684   SealHandleScope shs(isolate);
9685   ASSERT(args.length() == 0);
9686   PrintTransition(isolate, NULL);
9687   return isolate->heap()->undefined_value();
9688 }
9689
9690
9691 RUNTIME_FUNCTION(Runtime_TraceExit) {
9692   SealHandleScope shs(isolate);
9693   ASSERT(args.length() == 1);
9694   CONVERT_ARG_CHECKED(Object, obj, 0);
9695   PrintTransition(isolate, obj);
9696   return obj;  // return TOS
9697 }
9698
9699
9700 RUNTIME_FUNCTION(Runtime_DebugPrint) {
9701   SealHandleScope shs(isolate);
9702   ASSERT(args.length() == 1);
9703
9704 #ifdef DEBUG
9705   if (args[0]->IsString()) {
9706     // If we have a string, assume it's a code "marker"
9707     // and print some interesting cpu debugging info.
9708     JavaScriptFrameIterator it(isolate);
9709     JavaScriptFrame* frame = it.frame();
9710     PrintF("fp = %p, sp = %p, caller_sp = %p: ",
9711            frame->fp(), frame->sp(), frame->caller_sp());
9712   } else {
9713     PrintF("DebugPrint: ");
9714   }
9715   args[0]->Print();
9716   if (args[0]->IsHeapObject()) {
9717     PrintF("\n");
9718     HeapObject::cast(args[0])->map()->Print();
9719   }
9720 #else
9721   // ShortPrint is available in release mode. Print is not.
9722   args[0]->ShortPrint();
9723 #endif
9724   PrintF("\n");
9725   Flush();
9726
9727   return args[0];  // return TOS
9728 }
9729
9730
9731 RUNTIME_FUNCTION(Runtime_DebugTrace) {
9732   SealHandleScope shs(isolate);
9733   ASSERT(args.length() == 0);
9734   isolate->PrintStack(stdout);
9735   return isolate->heap()->undefined_value();
9736 }
9737
9738
9739 RUNTIME_FUNCTION(Runtime_DateCurrentTime) {
9740   HandleScope scope(isolate);
9741   ASSERT(args.length() == 0);
9742
9743   // According to ECMA-262, section 15.9.1, page 117, the precision of
9744   // the number in a Date object representing a particular instant in
9745   // time is milliseconds. Therefore, we floor the result of getting
9746   // the OS time.
9747   double millis = std::floor(OS::TimeCurrentMillis());
9748   return *isolate->factory()->NewNumber(millis);
9749 }
9750
9751
9752 RUNTIME_FUNCTION(Runtime_DateParseString) {
9753   HandleScope scope(isolate);
9754   ASSERT(args.length() == 2);
9755   CONVERT_ARG_HANDLE_CHECKED(String, str, 0);
9756   CONVERT_ARG_HANDLE_CHECKED(JSArray, output, 1);
9757
9758   RUNTIME_ASSERT(output->HasFastElements());
9759   JSObject::EnsureCanContainHeapObjectElements(output);
9760   RUNTIME_ASSERT(output->HasFastObjectElements());
9761   Handle<FixedArray> output_array(FixedArray::cast(output->elements()));
9762   RUNTIME_ASSERT(output_array->length() >= DateParser::OUTPUT_SIZE);
9763
9764   str = String::Flatten(str);
9765   DisallowHeapAllocation no_gc;
9766
9767   bool result;
9768   String::FlatContent str_content = str->GetFlatContent();
9769   if (str_content.IsAscii()) {
9770     result = DateParser::Parse(str_content.ToOneByteVector(),
9771                                *output_array,
9772                                isolate->unicode_cache());
9773   } else {
9774     ASSERT(str_content.IsTwoByte());
9775     result = DateParser::Parse(str_content.ToUC16Vector(),
9776                                *output_array,
9777                                isolate->unicode_cache());
9778   }
9779
9780   if (result) {
9781     return *output;
9782   } else {
9783     return isolate->heap()->null_value();
9784   }
9785 }
9786
9787
9788 RUNTIME_FUNCTION(Runtime_DateLocalTimezone) {
9789   HandleScope scope(isolate);
9790   ASSERT(args.length() == 1);
9791
9792   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
9793   const char* zone =
9794       isolate->date_cache()->LocalTimezone(static_cast<int64_t>(x));
9795   Handle<String> result = isolate->factory()->NewStringFromUtf8(
9796       CStrVector(zone)).ToHandleChecked();
9797   return *result;
9798 }
9799
9800
9801 RUNTIME_FUNCTION(Runtime_DateToUTC) {
9802   HandleScope scope(isolate);
9803   ASSERT(args.length() == 1);
9804
9805   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
9806   int64_t time = isolate->date_cache()->ToUTC(static_cast<int64_t>(x));
9807
9808   return *isolate->factory()->NewNumber(static_cast<double>(time));
9809 }
9810
9811
9812 RUNTIME_FUNCTION(Runtime_DateCacheVersion) {
9813   HandleScope hs(isolate);
9814   ASSERT(args.length() == 0);
9815   if (!isolate->eternal_handles()->Exists(EternalHandles::DATE_CACHE_VERSION)) {
9816     Handle<FixedArray> date_cache_version =
9817         isolate->factory()->NewFixedArray(1, TENURED);
9818     date_cache_version->set(0, Smi::FromInt(0));
9819     isolate->eternal_handles()->CreateSingleton(
9820         isolate, *date_cache_version, EternalHandles::DATE_CACHE_VERSION);
9821   }
9822   Handle<FixedArray> date_cache_version =
9823       Handle<FixedArray>::cast(isolate->eternal_handles()->GetSingleton(
9824           EternalHandles::DATE_CACHE_VERSION));
9825   // Return result as a JS array.
9826   Handle<JSObject> result =
9827       isolate->factory()->NewJSObject(isolate->array_function());
9828   JSArray::SetContent(Handle<JSArray>::cast(result), date_cache_version);
9829   return *result;
9830 }
9831
9832
9833 RUNTIME_FUNCTION(Runtime_GlobalReceiver) {
9834   SealHandleScope shs(isolate);
9835   ASSERT(args.length() == 1);
9836   CONVERT_ARG_CHECKED(Object, global, 0);
9837   if (!global->IsJSGlobalObject()) return isolate->heap()->null_value();
9838   return JSGlobalObject::cast(global)->global_receiver();
9839 }
9840
9841
9842 RUNTIME_FUNCTION(Runtime_IsAttachedGlobal) {
9843   SealHandleScope shs(isolate);
9844   ASSERT(args.length() == 1);
9845   CONVERT_ARG_CHECKED(Object, global, 0);
9846   if (!global->IsJSGlobalObject()) return isolate->heap()->false_value();
9847   return isolate->heap()->ToBoolean(
9848       !JSGlobalObject::cast(global)->IsDetached());
9849 }
9850
9851
9852 RUNTIME_FUNCTION(Runtime_ParseJson) {
9853   HandleScope scope(isolate);
9854   ASSERT(args.length() == 1);
9855   CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
9856
9857   source = String::Flatten(source);
9858   // Optimized fast case where we only have ASCII characters.
9859   Handle<Object> result;
9860   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
9861       isolate, result,
9862       source->IsSeqOneByteString() ? JsonParser<true>::Parse(source)
9863                                    : JsonParser<false>::Parse(source));
9864   return *result;
9865 }
9866
9867
9868 bool CodeGenerationFromStringsAllowed(Isolate* isolate,
9869                                       Handle<Context> context) {
9870   ASSERT(context->allow_code_gen_from_strings()->IsFalse());
9871   // Check with callback if set.
9872   AllowCodeGenerationFromStringsCallback callback =
9873       isolate->allow_code_gen_callback();
9874   if (callback == NULL) {
9875     // No callback set and code generation disallowed.
9876     return false;
9877   } else {
9878     // Callback set. Let it decide if code generation is allowed.
9879     VMState<EXTERNAL> state(isolate);
9880     return callback(v8::Utils::ToLocal(context));
9881   }
9882 }
9883
9884
9885 RUNTIME_FUNCTION(Runtime_CompileString) {
9886   HandleScope scope(isolate);
9887   ASSERT(args.length() == 2);
9888   CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
9889   CONVERT_BOOLEAN_ARG_CHECKED(function_literal_only, 1);
9890
9891   // Extract native context.
9892   Handle<Context> context(isolate->context()->native_context());
9893
9894   // Check if native context allows code generation from
9895   // strings. Throw an exception if it doesn't.
9896   if (context->allow_code_gen_from_strings()->IsFalse() &&
9897       !CodeGenerationFromStringsAllowed(isolate, context)) {
9898     Handle<Object> error_message =
9899         context->ErrorMessageForCodeGenerationFromStrings();
9900     return isolate->Throw(*isolate->factory()->NewEvalError(
9901         "code_gen_from_strings", HandleVector<Object>(&error_message, 1)));
9902   }
9903
9904   // Compile source string in the native context.
9905   ParseRestriction restriction = function_literal_only
9906       ? ONLY_SINGLE_FUNCTION_LITERAL : NO_PARSE_RESTRICTION;
9907   Handle<JSFunction> fun;
9908   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
9909       isolate, fun,
9910       Compiler::GetFunctionFromEval(
9911           source, context, SLOPPY, restriction, RelocInfo::kNoPosition));
9912   return *fun;
9913 }
9914
9915
9916 static ObjectPair CompileGlobalEval(Isolate* isolate,
9917                                     Handle<String> source,
9918                                     Handle<Object> receiver,
9919                                     StrictMode strict_mode,
9920                                     int scope_position) {
9921   Handle<Context> context = Handle<Context>(isolate->context());
9922   Handle<Context> native_context = Handle<Context>(context->native_context());
9923
9924   // Check if native context allows code generation from
9925   // strings. Throw an exception if it doesn't.
9926   if (native_context->allow_code_gen_from_strings()->IsFalse() &&
9927       !CodeGenerationFromStringsAllowed(isolate, native_context)) {
9928     Handle<Object> error_message =
9929         native_context->ErrorMessageForCodeGenerationFromStrings();
9930     isolate->Throw(*isolate->factory()->NewEvalError(
9931         "code_gen_from_strings", HandleVector<Object>(&error_message, 1)));
9932     return MakePair(isolate->heap()->exception(), NULL);
9933   }
9934
9935   // Deal with a normal eval call with a string argument. Compile it
9936   // and return the compiled function bound in the local context.
9937   static const ParseRestriction restriction = NO_PARSE_RESTRICTION;
9938   Handle<JSFunction> compiled;
9939   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
9940       isolate, compiled,
9941       Compiler::GetFunctionFromEval(
9942           source, context, strict_mode, restriction, scope_position),
9943       MakePair(isolate->heap()->exception(), NULL));
9944   return MakePair(*compiled, *receiver);
9945 }
9946
9947
9948 RUNTIME_FUNCTION_RETURN_PAIR(RuntimeHidden_ResolvePossiblyDirectEval) {
9949   HandleScope scope(isolate);
9950   ASSERT(args.length() == 5);
9951
9952   Handle<Object> callee = args.at<Object>(0);
9953
9954   // If "eval" didn't refer to the original GlobalEval, it's not a
9955   // direct call to eval.
9956   // (And even if it is, but the first argument isn't a string, just let
9957   // execution default to an indirect call to eval, which will also return
9958   // the first argument without doing anything).
9959   if (*callee != isolate->native_context()->global_eval_fun() ||
9960       !args[1]->IsString()) {
9961     return MakePair(*callee, isolate->heap()->undefined_value());
9962   }
9963
9964   ASSERT(args[3]->IsSmi());
9965   ASSERT(args.smi_at(3) == SLOPPY || args.smi_at(3) == STRICT);
9966   StrictMode strict_mode = static_cast<StrictMode>(args.smi_at(3));
9967   ASSERT(args[4]->IsSmi());
9968   return CompileGlobalEval(isolate,
9969                            args.at<String>(1),
9970                            args.at<Object>(2),
9971                            strict_mode,
9972                            args.smi_at(4));
9973 }
9974
9975
9976 RUNTIME_FUNCTION(RuntimeHidden_AllocateInNewSpace) {
9977   HandleScope scope(isolate);
9978   ASSERT(args.length() == 1);
9979   CONVERT_SMI_ARG_CHECKED(size, 0);
9980   RUNTIME_ASSERT(IsAligned(size, kPointerSize));
9981   RUNTIME_ASSERT(size > 0);
9982   RUNTIME_ASSERT(size <= Page::kMaxRegularHeapObjectSize);
9983   return *isolate->factory()->NewFillerObject(size, false, NEW_SPACE);
9984 }
9985
9986
9987 RUNTIME_FUNCTION(RuntimeHidden_AllocateInTargetSpace) {
9988   HandleScope scope(isolate);
9989   ASSERT(args.length() == 2);
9990   CONVERT_SMI_ARG_CHECKED(size, 0);
9991   CONVERT_SMI_ARG_CHECKED(flags, 1);
9992   RUNTIME_ASSERT(IsAligned(size, kPointerSize));
9993   RUNTIME_ASSERT(size > 0);
9994   RUNTIME_ASSERT(size <= Page::kMaxRegularHeapObjectSize);
9995   bool double_align = AllocateDoubleAlignFlag::decode(flags);
9996   AllocationSpace space = AllocateTargetSpace::decode(flags);
9997   return *isolate->factory()->NewFillerObject(size, double_align, space);
9998 }
9999
10000
10001 // Push an object unto an array of objects if it is not already in the
10002 // array.  Returns true if the element was pushed on the stack and
10003 // false otherwise.
10004 RUNTIME_FUNCTION(Runtime_PushIfAbsent) {
10005   HandleScope scope(isolate);
10006   ASSERT(args.length() == 2);
10007   CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
10008   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, element, 1);
10009   RUNTIME_ASSERT(array->HasFastSmiOrObjectElements());
10010   int length = Smi::cast(array->length())->value();
10011   FixedArray* elements = FixedArray::cast(array->elements());
10012   for (int i = 0; i < length; i++) {
10013     if (elements->get(i) == *element) return isolate->heap()->false_value();
10014   }
10015
10016   // Strict not needed. Used for cycle detection in Array join implementation.
10017   RETURN_FAILURE_ON_EXCEPTION(
10018       isolate,
10019       JSObject::SetFastElement(array, length, element, SLOPPY, true));
10020   return isolate->heap()->true_value();
10021 }
10022
10023
10024 /**
10025  * A simple visitor visits every element of Array's.
10026  * The backend storage can be a fixed array for fast elements case,
10027  * or a dictionary for sparse array. Since Dictionary is a subtype
10028  * of FixedArray, the class can be used by both fast and slow cases.
10029  * The second parameter of the constructor, fast_elements, specifies
10030  * whether the storage is a FixedArray or Dictionary.
10031  *
10032  * An index limit is used to deal with the situation that a result array
10033  * length overflows 32-bit non-negative integer.
10034  */
10035 class ArrayConcatVisitor {
10036  public:
10037   ArrayConcatVisitor(Isolate* isolate,
10038                      Handle<FixedArray> storage,
10039                      bool fast_elements) :
10040       isolate_(isolate),
10041       storage_(Handle<FixedArray>::cast(
10042           isolate->global_handles()->Create(*storage))),
10043       index_offset_(0u),
10044       fast_elements_(fast_elements),
10045       exceeds_array_limit_(false) { }
10046
10047   ~ArrayConcatVisitor() {
10048     clear_storage();
10049   }
10050
10051   void visit(uint32_t i, Handle<Object> elm) {
10052     if (i > JSObject::kMaxElementCount - index_offset_) {
10053       exceeds_array_limit_ = true;
10054       return;
10055     }
10056     uint32_t index = index_offset_ + i;
10057
10058     if (fast_elements_) {
10059       if (index < static_cast<uint32_t>(storage_->length())) {
10060         storage_->set(index, *elm);
10061         return;
10062       }
10063       // Our initial estimate of length was foiled, possibly by
10064       // getters on the arrays increasing the length of later arrays
10065       // during iteration.
10066       // This shouldn't happen in anything but pathological cases.
10067       SetDictionaryMode(index);
10068       // Fall-through to dictionary mode.
10069     }
10070     ASSERT(!fast_elements_);
10071     Handle<SeededNumberDictionary> dict(
10072         SeededNumberDictionary::cast(*storage_));
10073     Handle<SeededNumberDictionary> result =
10074         SeededNumberDictionary::AtNumberPut(dict, index, elm);
10075     if (!result.is_identical_to(dict)) {
10076       // Dictionary needed to grow.
10077       clear_storage();
10078       set_storage(*result);
10079     }
10080   }
10081
10082   void increase_index_offset(uint32_t delta) {
10083     if (JSObject::kMaxElementCount - index_offset_ < delta) {
10084       index_offset_ = JSObject::kMaxElementCount;
10085     } else {
10086       index_offset_ += delta;
10087     }
10088   }
10089
10090   bool exceeds_array_limit() {
10091     return exceeds_array_limit_;
10092   }
10093
10094   Handle<JSArray> ToArray() {
10095     Handle<JSArray> array = isolate_->factory()->NewJSArray(0);
10096     Handle<Object> length =
10097         isolate_->factory()->NewNumber(static_cast<double>(index_offset_));
10098     Handle<Map> map = JSObject::GetElementsTransitionMap(
10099         array,
10100         fast_elements_ ? FAST_HOLEY_ELEMENTS : DICTIONARY_ELEMENTS);
10101     array->set_map(*map);
10102     array->set_length(*length);
10103     array->set_elements(*storage_);
10104     return array;
10105   }
10106
10107  private:
10108   // Convert storage to dictionary mode.
10109   void SetDictionaryMode(uint32_t index) {
10110     ASSERT(fast_elements_);
10111     Handle<FixedArray> current_storage(*storage_);
10112     Handle<SeededNumberDictionary> slow_storage(
10113         SeededNumberDictionary::New(isolate_, current_storage->length()));
10114     uint32_t current_length = static_cast<uint32_t>(current_storage->length());
10115     for (uint32_t i = 0; i < current_length; i++) {
10116       HandleScope loop_scope(isolate_);
10117       Handle<Object> element(current_storage->get(i), isolate_);
10118       if (!element->IsTheHole()) {
10119         Handle<SeededNumberDictionary> new_storage =
10120             SeededNumberDictionary::AtNumberPut(slow_storage, i, element);
10121         if (!new_storage.is_identical_to(slow_storage)) {
10122           slow_storage = loop_scope.CloseAndEscape(new_storage);
10123         }
10124       }
10125     }
10126     clear_storage();
10127     set_storage(*slow_storage);
10128     fast_elements_ = false;
10129   }
10130
10131   inline void clear_storage() {
10132     GlobalHandles::Destroy(Handle<Object>::cast(storage_).location());
10133   }
10134
10135   inline void set_storage(FixedArray* storage) {
10136     storage_ = Handle<FixedArray>::cast(
10137         isolate_->global_handles()->Create(storage));
10138   }
10139
10140   Isolate* isolate_;
10141   Handle<FixedArray> storage_;  // Always a global handle.
10142   // Index after last seen index. Always less than or equal to
10143   // JSObject::kMaxElementCount.
10144   uint32_t index_offset_;
10145   bool fast_elements_ : 1;
10146   bool exceeds_array_limit_ : 1;
10147 };
10148
10149
10150 static uint32_t EstimateElementCount(Handle<JSArray> array) {
10151   uint32_t length = static_cast<uint32_t>(array->length()->Number());
10152   int element_count = 0;
10153   switch (array->GetElementsKind()) {
10154     case FAST_SMI_ELEMENTS:
10155     case FAST_HOLEY_SMI_ELEMENTS:
10156     case FAST_ELEMENTS:
10157     case FAST_HOLEY_ELEMENTS: {
10158       // Fast elements can't have lengths that are not representable by
10159       // a 32-bit signed integer.
10160       ASSERT(static_cast<int32_t>(FixedArray::kMaxLength) >= 0);
10161       int fast_length = static_cast<int>(length);
10162       Handle<FixedArray> elements(FixedArray::cast(array->elements()));
10163       for (int i = 0; i < fast_length; i++) {
10164         if (!elements->get(i)->IsTheHole()) element_count++;
10165       }
10166       break;
10167     }
10168     case FAST_DOUBLE_ELEMENTS:
10169     case FAST_HOLEY_DOUBLE_ELEMENTS: {
10170       // Fast elements can't have lengths that are not representable by
10171       // a 32-bit signed integer.
10172       ASSERT(static_cast<int32_t>(FixedDoubleArray::kMaxLength) >= 0);
10173       int fast_length = static_cast<int>(length);
10174       if (array->elements()->IsFixedArray()) {
10175         ASSERT(FixedArray::cast(array->elements())->length() == 0);
10176         break;
10177       }
10178       Handle<FixedDoubleArray> elements(
10179           FixedDoubleArray::cast(array->elements()));
10180       for (int i = 0; i < fast_length; i++) {
10181         if (!elements->is_the_hole(i)) element_count++;
10182       }
10183       break;
10184     }
10185     case DICTIONARY_ELEMENTS: {
10186       Handle<SeededNumberDictionary> dictionary(
10187           SeededNumberDictionary::cast(array->elements()));
10188       int capacity = dictionary->Capacity();
10189       for (int i = 0; i < capacity; i++) {
10190         Handle<Object> key(dictionary->KeyAt(i), array->GetIsolate());
10191         if (dictionary->IsKey(*key)) {
10192           element_count++;
10193         }
10194       }
10195       break;
10196     }
10197     case SLOPPY_ARGUMENTS_ELEMENTS:
10198 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size)                      \
10199     case EXTERNAL_##TYPE##_ELEMENTS:                                         \
10200     case TYPE##_ELEMENTS:                                                    \
10201
10202     TYPED_ARRAYS(TYPED_ARRAY_CASE)
10203 #undef TYPED_ARRAY_CASE
10204       // External arrays are always dense.
10205       return length;
10206   }
10207   // As an estimate, we assume that the prototype doesn't contain any
10208   // inherited elements.
10209   return element_count;
10210 }
10211
10212
10213
10214 template<class ExternalArrayClass, class ElementType>
10215 static void IterateExternalArrayElements(Isolate* isolate,
10216                                          Handle<JSObject> receiver,
10217                                          bool elements_are_ints,
10218                                          bool elements_are_guaranteed_smis,
10219                                          ArrayConcatVisitor* visitor) {
10220   Handle<ExternalArrayClass> array(
10221       ExternalArrayClass::cast(receiver->elements()));
10222   uint32_t len = static_cast<uint32_t>(array->length());
10223
10224   ASSERT(visitor != NULL);
10225   if (elements_are_ints) {
10226     if (elements_are_guaranteed_smis) {
10227       for (uint32_t j = 0; j < len; j++) {
10228         HandleScope loop_scope(isolate);
10229         Handle<Smi> e(Smi::FromInt(static_cast<int>(array->get_scalar(j))),
10230                       isolate);
10231         visitor->visit(j, e);
10232       }
10233     } else {
10234       for (uint32_t j = 0; j < len; j++) {
10235         HandleScope loop_scope(isolate);
10236         int64_t val = static_cast<int64_t>(array->get_scalar(j));
10237         if (Smi::IsValid(static_cast<intptr_t>(val))) {
10238           Handle<Smi> e(Smi::FromInt(static_cast<int>(val)), isolate);
10239           visitor->visit(j, e);
10240         } else {
10241           Handle<Object> e =
10242               isolate->factory()->NewNumber(static_cast<ElementType>(val));
10243           visitor->visit(j, e);
10244         }
10245       }
10246     }
10247   } else {
10248     for (uint32_t j = 0; j < len; j++) {
10249       HandleScope loop_scope(isolate);
10250       Handle<Object> e = isolate->factory()->NewNumber(array->get_scalar(j));
10251       visitor->visit(j, e);
10252     }
10253   }
10254 }
10255
10256
10257 static void IterateExternalFloat32x4ArrayElements(Isolate* isolate,
10258                                                   Handle<JSObject> receiver,
10259                                                   ArrayConcatVisitor* visitor) {
10260   Handle<ExternalFloat32x4Array> array(
10261       ExternalFloat32x4Array::cast(receiver->elements()));
10262   uint32_t len = static_cast<uint32_t>(array->length());
10263
10264   ASSERT(visitor != NULL);
10265   for (uint32_t j = 0; j < len; j++) {
10266     HandleScope loop_scope(isolate);
10267     Handle<Object> e = isolate->factory()->NewFloat32x4(array->get_scalar(j));
10268     visitor->visit(j, e);
10269   }
10270 }
10271
10272
10273 static void IterateExternalFloat64x2ArrayElements(Isolate* isolate,
10274                                                   Handle<JSObject> receiver,
10275                                                   ArrayConcatVisitor* visitor) {
10276   Handle<ExternalFloat64x2Array> array(
10277       ExternalFloat64x2Array::cast(receiver->elements()));
10278   uint32_t len = static_cast<uint32_t>(array->length());
10279
10280   ASSERT(visitor != NULL);
10281   for (uint32_t j = 0; j < len; j++) {
10282     HandleScope loop_scope(isolate);
10283     Handle<Object> e = isolate->factory()->NewFloat64x2(array->get_scalar(j));
10284     visitor->visit(j, e);
10285   }
10286 }
10287
10288
10289 static void IterateExternalInt32x4ArrayElements(Isolate* isolate,
10290                                                  Handle<JSObject> receiver,
10291                                                  ArrayConcatVisitor* visitor) {
10292   Handle<ExternalInt32x4Array> array(
10293       ExternalInt32x4Array::cast(receiver->elements()));
10294   uint32_t len = static_cast<uint32_t>(array->length());
10295
10296   ASSERT(visitor != NULL);
10297   for (uint32_t j = 0; j < len; j++) {
10298     HandleScope loop_scope(isolate);
10299     Handle<Object> e = isolate->factory()->NewInt32x4(array->get_scalar(j));
10300     visitor->visit(j, e);
10301   }
10302 }
10303
10304
10305 // Used for sorting indices in a List<uint32_t>.
10306 static int compareUInt32(const uint32_t* ap, const uint32_t* bp) {
10307   uint32_t a = *ap;
10308   uint32_t b = *bp;
10309   return (a == b) ? 0 : (a < b) ? -1 : 1;
10310 }
10311
10312
10313 static void CollectElementIndices(Handle<JSObject> object,
10314                                   uint32_t range,
10315                                   List<uint32_t>* indices) {
10316   Isolate* isolate = object->GetIsolate();
10317   ElementsKind kind = object->GetElementsKind();
10318   switch (kind) {
10319     case FAST_SMI_ELEMENTS:
10320     case FAST_ELEMENTS:
10321     case FAST_HOLEY_SMI_ELEMENTS:
10322     case FAST_HOLEY_ELEMENTS: {
10323       Handle<FixedArray> elements(FixedArray::cast(object->elements()));
10324       uint32_t length = static_cast<uint32_t>(elements->length());
10325       if (range < length) length = range;
10326       for (uint32_t i = 0; i < length; i++) {
10327         if (!elements->get(i)->IsTheHole()) {
10328           indices->Add(i);
10329         }
10330       }
10331       break;
10332     }
10333     case FAST_HOLEY_DOUBLE_ELEMENTS:
10334     case FAST_DOUBLE_ELEMENTS: {
10335       // TODO(1810): Decide if it's worthwhile to implement this.
10336       UNREACHABLE();
10337       break;
10338     }
10339     case DICTIONARY_ELEMENTS: {
10340       Handle<SeededNumberDictionary> dict(
10341           SeededNumberDictionary::cast(object->elements()));
10342       uint32_t capacity = dict->Capacity();
10343       for (uint32_t j = 0; j < capacity; j++) {
10344         HandleScope loop_scope(isolate);
10345         Handle<Object> k(dict->KeyAt(j), isolate);
10346         if (dict->IsKey(*k)) {
10347           ASSERT(k->IsNumber());
10348           uint32_t index = static_cast<uint32_t>(k->Number());
10349           if (index < range) {
10350             indices->Add(index);
10351           }
10352         }
10353       }
10354       break;
10355     }
10356     default: {
10357       int dense_elements_length;
10358       switch (kind) {
10359 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size)                        \
10360         case EXTERNAL_##TYPE##_ELEMENTS: {                                     \
10361           dense_elements_length =                                              \
10362               External##Type##Array::cast(object->elements())->length();       \
10363           break;                                                               \
10364         }
10365
10366         TYPED_ARRAYS(TYPED_ARRAY_CASE)
10367 #undef TYPED_ARRAY_CASE
10368
10369         default:
10370           UNREACHABLE();
10371           dense_elements_length = 0;
10372           break;
10373       }
10374       uint32_t length = static_cast<uint32_t>(dense_elements_length);
10375       if (range <= length) {
10376         length = range;
10377         // We will add all indices, so we might as well clear it first
10378         // and avoid duplicates.
10379         indices->Clear();
10380       }
10381       for (uint32_t i = 0; i < length; i++) {
10382         indices->Add(i);
10383       }
10384       if (length == range) return;  // All indices accounted for already.
10385       break;
10386     }
10387   }
10388
10389   Handle<Object> prototype(object->GetPrototype(), isolate);
10390   if (prototype->IsJSObject()) {
10391     // The prototype will usually have no inherited element indices,
10392     // but we have to check.
10393     CollectElementIndices(Handle<JSObject>::cast(prototype), range, indices);
10394   }
10395 }
10396
10397
10398 /**
10399  * A helper function that visits elements of a JSArray in numerical
10400  * order.
10401  *
10402  * The visitor argument called for each existing element in the array
10403  * with the element index and the element's value.
10404  * Afterwards it increments the base-index of the visitor by the array
10405  * length.
10406  * Returns false if any access threw an exception, otherwise true.
10407  */
10408 static bool IterateElements(Isolate* isolate,
10409                             Handle<JSArray> receiver,
10410                             ArrayConcatVisitor* visitor) {
10411   uint32_t length = static_cast<uint32_t>(receiver->length()->Number());
10412   switch (receiver->GetElementsKind()) {
10413     case FAST_SMI_ELEMENTS:
10414     case FAST_ELEMENTS:
10415     case FAST_HOLEY_SMI_ELEMENTS:
10416     case FAST_HOLEY_ELEMENTS: {
10417       // Run through the elements FixedArray and use HasElement and GetElement
10418       // to check the prototype for missing elements.
10419       Handle<FixedArray> elements(FixedArray::cast(receiver->elements()));
10420       int fast_length = static_cast<int>(length);
10421       ASSERT(fast_length <= elements->length());
10422       for (int j = 0; j < fast_length; j++) {
10423         HandleScope loop_scope(isolate);
10424         Handle<Object> element_value(elements->get(j), isolate);
10425         if (!element_value->IsTheHole()) {
10426           visitor->visit(j, element_value);
10427         } else if (JSReceiver::HasElement(receiver, j)) {
10428           // Call GetElement on receiver, not its prototype, or getters won't
10429           // have the correct receiver.
10430           ASSIGN_RETURN_ON_EXCEPTION_VALUE(
10431               isolate, element_value,
10432               Object::GetElement(isolate, receiver, j),
10433               false);
10434           visitor->visit(j, element_value);
10435         }
10436       }
10437       break;
10438     }
10439     case FAST_HOLEY_DOUBLE_ELEMENTS:
10440     case FAST_DOUBLE_ELEMENTS: {
10441       // Empty array is FixedArray but not FixedDoubleArray.
10442       if (length == 0) break;
10443       // Run through the elements FixedArray and use HasElement and GetElement
10444       // to check the prototype for missing elements.
10445       Handle<FixedDoubleArray> elements(
10446           FixedDoubleArray::cast(receiver->elements()));
10447       int fast_length = static_cast<int>(length);
10448       ASSERT(fast_length <= elements->length());
10449       for (int j = 0; j < fast_length; j++) {
10450         HandleScope loop_scope(isolate);
10451         if (!elements->is_the_hole(j)) {
10452           double double_value = elements->get_scalar(j);
10453           Handle<Object> element_value =
10454               isolate->factory()->NewNumber(double_value);
10455           visitor->visit(j, element_value);
10456         } else if (JSReceiver::HasElement(receiver, j)) {
10457           // Call GetElement on receiver, not its prototype, or getters won't
10458           // have the correct receiver.
10459           Handle<Object> element_value;
10460           ASSIGN_RETURN_ON_EXCEPTION_VALUE(
10461               isolate, element_value,
10462               Object::GetElement(isolate, receiver, j),
10463               false);
10464           visitor->visit(j, element_value);
10465         }
10466       }
10467       break;
10468     }
10469     case DICTIONARY_ELEMENTS: {
10470       Handle<SeededNumberDictionary> dict(receiver->element_dictionary());
10471       List<uint32_t> indices(dict->Capacity() / 2);
10472       // Collect all indices in the object and the prototypes less
10473       // than length. This might introduce duplicates in the indices list.
10474       CollectElementIndices(receiver, length, &indices);
10475       indices.Sort(&compareUInt32);
10476       int j = 0;
10477       int n = indices.length();
10478       while (j < n) {
10479         HandleScope loop_scope(isolate);
10480         uint32_t index = indices[j];
10481         Handle<Object> element;
10482         ASSIGN_RETURN_ON_EXCEPTION_VALUE(
10483             isolate, element,
10484             Object::GetElement(isolate, receiver, index),
10485             false);
10486         visitor->visit(index, element);
10487         // Skip to next different index (i.e., omit duplicates).
10488         do {
10489           j++;
10490         } while (j < n && indices[j] == index);
10491       }
10492       break;
10493     }
10494     case EXTERNAL_UINT8_CLAMPED_ELEMENTS: {
10495       Handle<ExternalUint8ClampedArray> pixels(ExternalUint8ClampedArray::cast(
10496           receiver->elements()));
10497       for (uint32_t j = 0; j < length; j++) {
10498         Handle<Smi> e(Smi::FromInt(pixels->get_scalar(j)), isolate);
10499         visitor->visit(j, e);
10500       }
10501       break;
10502     }
10503     case EXTERNAL_INT8_ELEMENTS: {
10504       IterateExternalArrayElements<ExternalInt8Array, int8_t>(
10505           isolate, receiver, true, true, visitor);
10506       break;
10507     }
10508     case EXTERNAL_UINT8_ELEMENTS: {
10509       IterateExternalArrayElements<ExternalUint8Array, uint8_t>(
10510           isolate, receiver, true, true, visitor);
10511       break;
10512     }
10513     case EXTERNAL_INT16_ELEMENTS: {
10514       IterateExternalArrayElements<ExternalInt16Array, int16_t>(
10515           isolate, receiver, true, true, visitor);
10516       break;
10517     }
10518     case EXTERNAL_UINT16_ELEMENTS: {
10519       IterateExternalArrayElements<ExternalUint16Array, uint16_t>(
10520           isolate, receiver, true, true, visitor);
10521       break;
10522     }
10523     case EXTERNAL_INT32_ELEMENTS: {
10524       IterateExternalArrayElements<ExternalInt32Array, int32_t>(
10525           isolate, receiver, true, false, visitor);
10526       break;
10527     }
10528     case EXTERNAL_UINT32_ELEMENTS: {
10529       IterateExternalArrayElements<ExternalUint32Array, uint32_t>(
10530           isolate, receiver, true, false, visitor);
10531       break;
10532     }
10533     case EXTERNAL_FLOAT32_ELEMENTS: {
10534       IterateExternalArrayElements<ExternalFloat32Array, float>(
10535           isolate, receiver, false, false, visitor);
10536       break;
10537     }
10538     case EXTERNAL_FLOAT32x4_ELEMENTS: {
10539       IterateExternalFloat32x4ArrayElements(isolate, receiver, visitor);
10540       break;
10541     }
10542     case EXTERNAL_FLOAT64x2_ELEMENTS: {
10543       IterateExternalFloat64x2ArrayElements(isolate, receiver, visitor);
10544       break;
10545     }
10546     case EXTERNAL_INT32x4_ELEMENTS: {
10547       IterateExternalInt32x4ArrayElements(isolate, receiver, visitor);
10548       break;
10549     }
10550     case EXTERNAL_FLOAT64_ELEMENTS: {
10551       IterateExternalArrayElements<ExternalFloat64Array, double>(
10552           isolate, receiver, false, false, visitor);
10553       break;
10554     }
10555     default:
10556       UNREACHABLE();
10557       break;
10558   }
10559   visitor->increase_index_offset(length);
10560   return true;
10561 }
10562
10563
10564 /**
10565  * Array::concat implementation.
10566  * See ECMAScript 262, 15.4.4.4.
10567  * TODO(581): Fix non-compliance for very large concatenations and update to
10568  * following the ECMAScript 5 specification.
10569  */
10570 RUNTIME_FUNCTION(Runtime_ArrayConcat) {
10571   HandleScope handle_scope(isolate);
10572   ASSERT(args.length() == 1);
10573
10574   CONVERT_ARG_HANDLE_CHECKED(JSArray, arguments, 0);
10575   int argument_count = static_cast<int>(arguments->length()->Number());
10576   RUNTIME_ASSERT(arguments->HasFastObjectElements());
10577   Handle<FixedArray> elements(FixedArray::cast(arguments->elements()));
10578
10579   // Pass 1: estimate the length and number of elements of the result.
10580   // The actual length can be larger if any of the arguments have getters
10581   // that mutate other arguments (but will otherwise be precise).
10582   // The number of elements is precise if there are no inherited elements.
10583
10584   ElementsKind kind = FAST_SMI_ELEMENTS;
10585
10586   uint32_t estimate_result_length = 0;
10587   uint32_t estimate_nof_elements = 0;
10588   for (int i = 0; i < argument_count; i++) {
10589     HandleScope loop_scope(isolate);
10590     Handle<Object> obj(elements->get(i), isolate);
10591     uint32_t length_estimate;
10592     uint32_t element_estimate;
10593     if (obj->IsJSArray()) {
10594       Handle<JSArray> array(Handle<JSArray>::cast(obj));
10595       length_estimate = static_cast<uint32_t>(array->length()->Number());
10596       if (length_estimate != 0) {
10597         ElementsKind array_kind =
10598             GetPackedElementsKind(array->map()->elements_kind());
10599         if (IsMoreGeneralElementsKindTransition(kind, array_kind)) {
10600           kind = array_kind;
10601         }
10602       }
10603       element_estimate = EstimateElementCount(array);
10604     } else {
10605       if (obj->IsHeapObject()) {
10606         if (obj->IsNumber()) {
10607           if (IsMoreGeneralElementsKindTransition(kind, FAST_DOUBLE_ELEMENTS)) {
10608             kind = FAST_DOUBLE_ELEMENTS;
10609           }
10610         } else if (IsMoreGeneralElementsKindTransition(kind, FAST_ELEMENTS)) {
10611           kind = FAST_ELEMENTS;
10612         }
10613       }
10614       length_estimate = 1;
10615       element_estimate = 1;
10616     }
10617     // Avoid overflows by capping at kMaxElementCount.
10618     if (JSObject::kMaxElementCount - estimate_result_length <
10619         length_estimate) {
10620       estimate_result_length = JSObject::kMaxElementCount;
10621     } else {
10622       estimate_result_length += length_estimate;
10623     }
10624     if (JSObject::kMaxElementCount - estimate_nof_elements <
10625         element_estimate) {
10626       estimate_nof_elements = JSObject::kMaxElementCount;
10627     } else {
10628       estimate_nof_elements += element_estimate;
10629     }
10630   }
10631
10632   // If estimated number of elements is more than half of length, a
10633   // fixed array (fast case) is more time and space-efficient than a
10634   // dictionary.
10635   bool fast_case = (estimate_nof_elements * 2) >= estimate_result_length;
10636
10637   if (fast_case && kind == FAST_DOUBLE_ELEMENTS) {
10638     Handle<FixedArrayBase> storage =
10639         isolate->factory()->NewFixedDoubleArray(estimate_result_length);
10640     int j = 0;
10641     if (estimate_result_length > 0) {
10642       Handle<FixedDoubleArray> double_storage =
10643           Handle<FixedDoubleArray>::cast(storage);
10644       bool failure = false;
10645       for (int i = 0; i < argument_count; i++) {
10646         Handle<Object> obj(elements->get(i), isolate);
10647         if (obj->IsSmi()) {
10648           double_storage->set(j, Smi::cast(*obj)->value());
10649           j++;
10650         } else if (obj->IsNumber()) {
10651           double_storage->set(j, obj->Number());
10652           j++;
10653         } else {
10654           JSArray* array = JSArray::cast(*obj);
10655           uint32_t length = static_cast<uint32_t>(array->length()->Number());
10656           switch (array->map()->elements_kind()) {
10657             case FAST_HOLEY_DOUBLE_ELEMENTS:
10658             case FAST_DOUBLE_ELEMENTS: {
10659               // Empty array is FixedArray but not FixedDoubleArray.
10660               if (length == 0) break;
10661               FixedDoubleArray* elements =
10662                   FixedDoubleArray::cast(array->elements());
10663               for (uint32_t i = 0; i < length; i++) {
10664                 if (elements->is_the_hole(i)) {
10665                   failure = true;
10666                   break;
10667                 }
10668                 double double_value = elements->get_scalar(i);
10669                 double_storage->set(j, double_value);
10670                 j++;
10671               }
10672               break;
10673             }
10674             case FAST_HOLEY_SMI_ELEMENTS:
10675             case FAST_SMI_ELEMENTS: {
10676               FixedArray* elements(
10677                   FixedArray::cast(array->elements()));
10678               for (uint32_t i = 0; i < length; i++) {
10679                 Object* element = elements->get(i);
10680                 if (element->IsTheHole()) {
10681                   failure = true;
10682                   break;
10683                 }
10684                 int32_t int_value = Smi::cast(element)->value();
10685                 double_storage->set(j, int_value);
10686                 j++;
10687               }
10688               break;
10689             }
10690             case FAST_HOLEY_ELEMENTS:
10691               ASSERT_EQ(0, length);
10692               break;
10693             default:
10694               UNREACHABLE();
10695           }
10696         }
10697         if (failure) break;
10698       }
10699     }
10700     Handle<JSArray> array = isolate->factory()->NewJSArray(0);
10701     Smi* length = Smi::FromInt(j);
10702     Handle<Map> map;
10703     map = JSObject::GetElementsTransitionMap(array, kind);
10704     array->set_map(*map);
10705     array->set_length(length);
10706     array->set_elements(*storage);
10707     return *array;
10708   }
10709
10710   Handle<FixedArray> storage;
10711   if (fast_case) {
10712     // The backing storage array must have non-existing elements to preserve
10713     // holes across concat operations.
10714     storage = isolate->factory()->NewFixedArrayWithHoles(
10715         estimate_result_length);
10716   } else {
10717     // TODO(126): move 25% pre-allocation logic into Dictionary::Allocate
10718     uint32_t at_least_space_for = estimate_nof_elements +
10719                                   (estimate_nof_elements >> 2);
10720     storage = Handle<FixedArray>::cast(
10721         SeededNumberDictionary::New(isolate, at_least_space_for));
10722   }
10723
10724   ArrayConcatVisitor visitor(isolate, storage, fast_case);
10725
10726   for (int i = 0; i < argument_count; i++) {
10727     Handle<Object> obj(elements->get(i), isolate);
10728     if (obj->IsJSArray()) {
10729       Handle<JSArray> array = Handle<JSArray>::cast(obj);
10730       if (!IterateElements(isolate, array, &visitor)) {
10731         return isolate->heap()->exception();
10732       }
10733     } else {
10734       visitor.visit(0, obj);
10735       visitor.increase_index_offset(1);
10736     }
10737   }
10738
10739   if (visitor.exceeds_array_limit()) {
10740     return isolate->Throw(
10741         *isolate->factory()->NewRangeError("invalid_array_length",
10742                                            HandleVector<Object>(NULL, 0)));
10743   }
10744   return *visitor.ToArray();
10745 }
10746
10747
10748 // This will not allocate (flatten the string), but it may run
10749 // very slowly for very deeply nested ConsStrings.  For debugging use only.
10750 RUNTIME_FUNCTION(Runtime_GlobalPrint) {
10751   SealHandleScope shs(isolate);
10752   ASSERT(args.length() == 1);
10753
10754   CONVERT_ARG_CHECKED(String, string, 0);
10755   ConsStringIteratorOp op;
10756   StringCharacterStream stream(string, &op);
10757   while (stream.HasMore()) {
10758     uint16_t character = stream.GetNext();
10759     PrintF("%c", character);
10760   }
10761   return string;
10762 }
10763
10764
10765 // Moves all own elements of an object, that are below a limit, to positions
10766 // starting at zero. All undefined values are placed after non-undefined values,
10767 // and are followed by non-existing element. Does not change the length
10768 // property.
10769 // Returns the number of non-undefined elements collected.
10770 // Returns -1 if hole removal is not supported by this method.
10771 RUNTIME_FUNCTION(Runtime_RemoveArrayHoles) {
10772   HandleScope scope(isolate);
10773   ASSERT(args.length() == 2);
10774   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
10775   CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]);
10776   return *JSObject::PrepareElementsForSort(object, limit);
10777 }
10778
10779
10780 // Move contents of argument 0 (an array) to argument 1 (an array)
10781 RUNTIME_FUNCTION(Runtime_MoveArrayContents) {
10782   HandleScope scope(isolate);
10783   ASSERT(args.length() == 2);
10784   CONVERT_ARG_HANDLE_CHECKED(JSArray, from, 0);
10785   CONVERT_ARG_HANDLE_CHECKED(JSArray, to, 1);
10786   JSObject::ValidateElements(from);
10787   JSObject::ValidateElements(to);
10788
10789   Handle<FixedArrayBase> new_elements(from->elements());
10790   ElementsKind from_kind = from->GetElementsKind();
10791   Handle<Map> new_map = JSObject::GetElementsTransitionMap(to, from_kind);
10792   JSObject::SetMapAndElements(to, new_map, new_elements);
10793   to->set_length(from->length());
10794
10795   JSObject::ResetElements(from);
10796   from->set_length(Smi::FromInt(0));
10797
10798   JSObject::ValidateElements(to);
10799   return *to;
10800 }
10801
10802
10803 // How many elements does this object/array have?
10804 RUNTIME_FUNCTION(Runtime_EstimateNumberOfElements) {
10805   SealHandleScope shs(isolate);
10806   ASSERT(args.length() == 1);
10807   CONVERT_ARG_CHECKED(JSObject, object, 0);
10808   HeapObject* elements = object->elements();
10809   if (elements->IsDictionary()) {
10810     int result = SeededNumberDictionary::cast(elements)->NumberOfElements();
10811     return Smi::FromInt(result);
10812   } else if (object->IsJSArray()) {
10813     return JSArray::cast(object)->length();
10814   } else {
10815     return Smi::FromInt(FixedArray::cast(elements)->length());
10816   }
10817 }
10818
10819
10820 // Returns an array that tells you where in the [0, length) interval an array
10821 // might have elements.  Can either return an array of keys (positive integers
10822 // or undefined) or a number representing the positive length of an interval
10823 // starting at index 0.
10824 // Intervals can span over some keys that are not in the object.
10825 RUNTIME_FUNCTION(Runtime_GetArrayKeys) {
10826   HandleScope scope(isolate);
10827   ASSERT(args.length() == 2);
10828   CONVERT_ARG_HANDLE_CHECKED(JSObject, array, 0);
10829   CONVERT_NUMBER_CHECKED(uint32_t, length, Uint32, args[1]);
10830   if (array->elements()->IsDictionary()) {
10831     Handle<FixedArray> keys = isolate->factory()->empty_fixed_array();
10832     for (Handle<Object> p = array;
10833          !p->IsNull();
10834          p = Handle<Object>(p->GetPrototype(isolate), isolate)) {
10835       if (p->IsJSProxy() || JSObject::cast(*p)->HasIndexedInterceptor()) {
10836         // Bail out if we find a proxy or interceptor, likely not worth
10837         // collecting keys in that case.
10838         return *isolate->factory()->NewNumberFromUint(length);
10839       }
10840       Handle<JSObject> current = Handle<JSObject>::cast(p);
10841       Handle<FixedArray> current_keys =
10842           isolate->factory()->NewFixedArray(
10843               current->NumberOfLocalElements(NONE));
10844       current->GetLocalElementKeys(*current_keys, NONE);
10845       ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
10846           isolate, keys, FixedArray::UnionOfKeys(keys, current_keys));
10847     }
10848     // Erase any keys >= length.
10849     // TODO(adamk): Remove this step when the contract of %GetArrayKeys
10850     // is changed to let this happen on the JS side.
10851     for (int i = 0; i < keys->length(); i++) {
10852       if (NumberToUint32(keys->get(i)) >= length) keys->set_undefined(i);
10853     }
10854     return *isolate->factory()->NewJSArrayWithElements(keys);
10855   } else {
10856     ASSERT(array->HasFastSmiOrObjectElements() ||
10857            array->HasFastDoubleElements());
10858     uint32_t actual_length = static_cast<uint32_t>(array->elements()->length());
10859     return *isolate->factory()->NewNumberFromUint(Min(actual_length, length));
10860   }
10861 }
10862
10863
10864 RUNTIME_FUNCTION(Runtime_LookupAccessor) {
10865   HandleScope scope(isolate);
10866   ASSERT(args.length() == 3);
10867   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
10868   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
10869   CONVERT_SMI_ARG_CHECKED(flag, 2);
10870   AccessorComponent component = flag == 0 ? ACCESSOR_GETTER : ACCESSOR_SETTER;
10871   if (!receiver->IsJSObject()) return isolate->heap()->undefined_value();
10872   Handle<Object> result;
10873   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
10874       isolate, result,
10875       JSObject::GetAccessor(Handle<JSObject>::cast(receiver), name, component));
10876   return *result;
10877 }
10878
10879
10880 RUNTIME_FUNCTION(Runtime_DebugBreak) {
10881   SealHandleScope shs(isolate);
10882   ASSERT(args.length() == 0);
10883   return Execution::DebugBreakHelper(isolate);
10884 }
10885
10886
10887 // Helper functions for wrapping and unwrapping stack frame ids.
10888 static Smi* WrapFrameId(StackFrame::Id id) {
10889   ASSERT(IsAligned(OffsetFrom(id), static_cast<intptr_t>(4)));
10890   return Smi::FromInt(id >> 2);
10891 }
10892
10893
10894 static StackFrame::Id UnwrapFrameId(int wrapped) {
10895   return static_cast<StackFrame::Id>(wrapped << 2);
10896 }
10897
10898
10899 // Adds a JavaScript function as a debug event listener.
10900 // args[0]: debug event listener function to set or null or undefined for
10901 //          clearing the event listener function
10902 // args[1]: object supplied during callback
10903 RUNTIME_FUNCTION(Runtime_SetDebugEventListener) {
10904   SealHandleScope shs(isolate);
10905   ASSERT(args.length() == 2);
10906   RUNTIME_ASSERT(args[0]->IsJSFunction() ||
10907                  args[0]->IsUndefined() ||
10908                  args[0]->IsNull());
10909   CONVERT_ARG_HANDLE_CHECKED(Object, callback, 0);
10910   CONVERT_ARG_HANDLE_CHECKED(Object, data, 1);
10911   isolate->debugger()->SetEventListener(callback, data);
10912
10913   return isolate->heap()->undefined_value();
10914 }
10915
10916
10917 RUNTIME_FUNCTION(Runtime_Break) {
10918   SealHandleScope shs(isolate);
10919   ASSERT(args.length() == 0);
10920   isolate->stack_guard()->DebugBreak();
10921   return isolate->heap()->undefined_value();
10922 }
10923
10924
10925 static Handle<Object> DebugLookupResultValue(Isolate* isolate,
10926                                              Handle<Object> receiver,
10927                                              Handle<Name> name,
10928                                              LookupResult* result,
10929                                              bool* has_caught = NULL) {
10930   Handle<Object> value = isolate->factory()->undefined_value();
10931   if  (!result->IsFound()) return value;
10932   switch (result->type()) {
10933     case NORMAL:
10934       value = JSObject::GetNormalizedProperty(
10935           handle(result->holder(), isolate), result);
10936       break;
10937     case FIELD:
10938       value = JSObject::FastPropertyAt(handle(result->holder(), isolate),
10939                                        result->representation(),
10940                                        result->GetFieldIndex().field_index());
10941       break;
10942     case CONSTANT:
10943       return handle(result->GetConstant(), isolate);
10944     case CALLBACKS: {
10945       Handle<Object> structure(result->GetCallbackObject(), isolate);
10946       ASSERT(!structure->IsForeign());
10947       if (structure->IsAccessorInfo()) {
10948         MaybeHandle<Object> obj = JSObject::GetPropertyWithCallback(
10949             handle(result->holder(), isolate), receiver, structure, name);
10950         if (!obj.ToHandle(&value)) {
10951           value = handle(isolate->pending_exception(), isolate);
10952           isolate->clear_pending_exception();
10953           if (has_caught != NULL) *has_caught = true;
10954           return value;
10955         }
10956       }
10957       break;
10958     }
10959     case INTERCEPTOR:
10960       break;
10961     case HANDLER:
10962     case NONEXISTENT:
10963       UNREACHABLE();
10964       break;
10965   }
10966   ASSERT(!value->IsTheHole() || result->IsReadOnly());
10967   return value->IsTheHole()
10968       ? Handle<Object>::cast(isolate->factory()->undefined_value()) : value;
10969 }
10970
10971
10972 // Get debugger related details for an object property.
10973 // args[0]: object holding property
10974 // args[1]: name of the property
10975 //
10976 // The array returned contains the following information:
10977 // 0: Property value
10978 // 1: Property details
10979 // 2: Property value is exception
10980 // 3: Getter function if defined
10981 // 4: Setter function if defined
10982 // Items 2-4 are only filled if the property has either a getter or a setter
10983 // defined through __defineGetter__ and/or __defineSetter__.
10984 RUNTIME_FUNCTION(Runtime_DebugGetPropertyDetails) {
10985   HandleScope scope(isolate);
10986
10987   ASSERT(args.length() == 2);
10988
10989   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
10990   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
10991
10992   // Make sure to set the current context to the context before the debugger was
10993   // entered (if the debugger is entered). The reason for switching context here
10994   // is that for some property lookups (accessors and interceptors) callbacks
10995   // into the embedding application can occour, and the embedding application
10996   // could have the assumption that its own native context is the current
10997   // context and not some internal debugger context.
10998   SaveContext save(isolate);
10999   if (isolate->debug()->InDebugger()) {
11000     isolate->set_context(*isolate->debug()->debugger_entry()->GetContext());
11001   }
11002
11003   // Skip the global proxy as it has no properties and always delegates to the
11004   // real global object.
11005   if (obj->IsJSGlobalProxy()) {
11006     obj = Handle<JSObject>(JSObject::cast(obj->GetPrototype()));
11007   }
11008
11009
11010   // Check if the name is trivially convertible to an index and get the element
11011   // if so.
11012   uint32_t index;
11013   if (name->AsArrayIndex(&index)) {
11014     Handle<FixedArray> details = isolate->factory()->NewFixedArray(2);
11015     Handle<Object> element_or_char;
11016     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
11017         isolate, element_or_char,
11018         Runtime::GetElementOrCharAt(isolate, obj, index));
11019     details->set(0, *element_or_char);
11020     details->set(
11021         1, PropertyDetails(NONE, NORMAL, Representation::None()).AsSmi());
11022     return *isolate->factory()->NewJSArrayWithElements(details);
11023   }
11024
11025   // Find the number of objects making up this.
11026   int length = LocalPrototypeChainLength(*obj);
11027
11028   // Try local lookup on each of the objects.
11029   Handle<JSObject> jsproto = obj;
11030   for (int i = 0; i < length; i++) {
11031     LookupResult result(isolate);
11032     jsproto->LocalLookup(name, &result);
11033     if (result.IsFound()) {
11034       // LookupResult is not GC safe as it holds raw object pointers.
11035       // GC can happen later in this code so put the required fields into
11036       // local variables using handles when required for later use.
11037       Handle<Object> result_callback_obj;
11038       if (result.IsPropertyCallbacks()) {
11039         result_callback_obj = Handle<Object>(result.GetCallbackObject(),
11040                                              isolate);
11041       }
11042
11043
11044       bool has_caught = false;
11045       Handle<Object> value = DebugLookupResultValue(
11046           isolate, obj, name, &result, &has_caught);
11047
11048       // If the callback object is a fixed array then it contains JavaScript
11049       // getter and/or setter.
11050       bool has_js_accessors = result.IsPropertyCallbacks() &&
11051                               result_callback_obj->IsAccessorPair();
11052       Handle<FixedArray> details =
11053           isolate->factory()->NewFixedArray(has_js_accessors ? 5 : 2);
11054       details->set(0, *value);
11055       details->set(1, result.GetPropertyDetails().AsSmi());
11056       if (has_js_accessors) {
11057         AccessorPair* accessors = AccessorPair::cast(*result_callback_obj);
11058         details->set(2, isolate->heap()->ToBoolean(has_caught));
11059         details->set(3, accessors->GetComponent(ACCESSOR_GETTER));
11060         details->set(4, accessors->GetComponent(ACCESSOR_SETTER));
11061       }
11062
11063       return *isolate->factory()->NewJSArrayWithElements(details);
11064     }
11065     if (i < length - 1) {
11066       jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype()));
11067     }
11068   }
11069
11070   return isolate->heap()->undefined_value();
11071 }
11072
11073
11074 RUNTIME_FUNCTION(Runtime_DebugGetProperty) {
11075   HandleScope scope(isolate);
11076
11077   ASSERT(args.length() == 2);
11078
11079   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
11080   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
11081
11082   LookupResult result(isolate);
11083   obj->Lookup(name, &result);
11084   return *DebugLookupResultValue(isolate, obj, name, &result);
11085 }
11086
11087
11088 // Return the property type calculated from the property details.
11089 // args[0]: smi with property details.
11090 RUNTIME_FUNCTION(Runtime_DebugPropertyTypeFromDetails) {
11091   SealHandleScope shs(isolate);
11092   ASSERT(args.length() == 1);
11093   CONVERT_PROPERTY_DETAILS_CHECKED(details, 0);
11094   return Smi::FromInt(static_cast<int>(details.type()));
11095 }
11096
11097
11098 // Return the property attribute calculated from the property details.
11099 // args[0]: smi with property details.
11100 RUNTIME_FUNCTION(Runtime_DebugPropertyAttributesFromDetails) {
11101   SealHandleScope shs(isolate);
11102   ASSERT(args.length() == 1);
11103   CONVERT_PROPERTY_DETAILS_CHECKED(details, 0);
11104   return Smi::FromInt(static_cast<int>(details.attributes()));
11105 }
11106
11107
11108 // Return the property insertion index calculated from the property details.
11109 // args[0]: smi with property details.
11110 RUNTIME_FUNCTION(Runtime_DebugPropertyIndexFromDetails) {
11111   SealHandleScope shs(isolate);
11112   ASSERT(args.length() == 1);
11113   CONVERT_PROPERTY_DETAILS_CHECKED(details, 0);
11114   // TODO(verwaest): Depends on the type of details.
11115   return Smi::FromInt(details.dictionary_index());
11116 }
11117
11118
11119 // Return property value from named interceptor.
11120 // args[0]: object
11121 // args[1]: property name
11122 RUNTIME_FUNCTION(Runtime_DebugNamedInterceptorPropertyValue) {
11123   HandleScope scope(isolate);
11124   ASSERT(args.length() == 2);
11125   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
11126   RUNTIME_ASSERT(obj->HasNamedInterceptor());
11127   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
11128
11129   PropertyAttributes attributes;
11130   Handle<Object> result;
11131   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
11132       isolate, result,
11133       JSObject::GetPropertyWithInterceptor(obj, obj, name, &attributes));
11134   return *result;
11135 }
11136
11137
11138 // Return element value from indexed interceptor.
11139 // args[0]: object
11140 // args[1]: index
11141 RUNTIME_FUNCTION(Runtime_DebugIndexedInterceptorElementValue) {
11142   HandleScope scope(isolate);
11143   ASSERT(args.length() == 2);
11144   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
11145   RUNTIME_ASSERT(obj->HasIndexedInterceptor());
11146   CONVERT_NUMBER_CHECKED(uint32_t, index, Uint32, args[1]);
11147   Handle<Object> result;
11148   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
11149       isolate, result, JSObject::GetElementWithInterceptor(obj, obj, index));
11150   return *result;
11151 }
11152
11153
11154 static bool CheckExecutionState(Isolate* isolate, int break_id) {
11155   return (isolate->debug()->break_id() != 0 &&
11156           break_id == isolate->debug()->break_id());
11157 }
11158
11159
11160 RUNTIME_FUNCTION(Runtime_CheckExecutionState) {
11161   SealHandleScope shs(isolate);
11162   ASSERT(args.length() == 1);
11163   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
11164   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
11165   return isolate->heap()->true_value();
11166 }
11167
11168
11169 RUNTIME_FUNCTION(Runtime_GetFrameCount) {
11170   HandleScope scope(isolate);
11171   ASSERT(args.length() == 1);
11172   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
11173   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
11174
11175   // Count all frames which are relevant to debugging stack trace.
11176   int n = 0;
11177   StackFrame::Id id = isolate->debug()->break_frame_id();
11178   if (id == StackFrame::NO_ID) {
11179     // If there is no JavaScript stack frame count is 0.
11180     return Smi::FromInt(0);
11181   }
11182
11183   for (JavaScriptFrameIterator it(isolate, id); !it.done(); it.Advance()) {
11184     n += it.frame()->GetInlineCount();
11185   }
11186   return Smi::FromInt(n);
11187 }
11188
11189
11190 class FrameInspector {
11191  public:
11192   FrameInspector(JavaScriptFrame* frame,
11193                  int inlined_jsframe_index,
11194                  Isolate* isolate)
11195       : frame_(frame), deoptimized_frame_(NULL), isolate_(isolate) {
11196     // Calculate the deoptimized frame.
11197     if (frame->is_optimized()) {
11198       deoptimized_frame_ = Deoptimizer::DebuggerInspectableFrame(
11199           frame, inlined_jsframe_index, isolate);
11200     }
11201     has_adapted_arguments_ = frame_->has_adapted_arguments();
11202     is_bottommost_ = inlined_jsframe_index == 0;
11203     is_optimized_ = frame_->is_optimized();
11204   }
11205
11206   ~FrameInspector() {
11207     // Get rid of the calculated deoptimized frame if any.
11208     if (deoptimized_frame_ != NULL) {
11209       Deoptimizer::DeleteDebuggerInspectableFrame(deoptimized_frame_,
11210                                                   isolate_);
11211     }
11212   }
11213
11214   int GetParametersCount() {
11215     return is_optimized_
11216         ? deoptimized_frame_->parameters_count()
11217         : frame_->ComputeParametersCount();
11218   }
11219   int expression_count() { return deoptimized_frame_->expression_count(); }
11220   Object* GetFunction() {
11221     return is_optimized_
11222         ? deoptimized_frame_->GetFunction()
11223         : frame_->function();
11224   }
11225   Object* GetParameter(int index) {
11226     return is_optimized_
11227         ? deoptimized_frame_->GetParameter(index)
11228         : frame_->GetParameter(index);
11229   }
11230   Object* GetExpression(int index) {
11231     return is_optimized_
11232         ? deoptimized_frame_->GetExpression(index)
11233         : frame_->GetExpression(index);
11234   }
11235   int GetSourcePosition() {
11236     return is_optimized_
11237         ? deoptimized_frame_->GetSourcePosition()
11238         : frame_->LookupCode()->SourcePosition(frame_->pc());
11239   }
11240   bool IsConstructor() {
11241     return is_optimized_ && !is_bottommost_
11242         ? deoptimized_frame_->HasConstructStub()
11243         : frame_->IsConstructor();
11244   }
11245
11246   // To inspect all the provided arguments the frame might need to be
11247   // replaced with the arguments frame.
11248   void SetArgumentsFrame(JavaScriptFrame* frame) {
11249     ASSERT(has_adapted_arguments_);
11250     frame_ = frame;
11251     is_optimized_ = frame_->is_optimized();
11252     ASSERT(!is_optimized_);
11253   }
11254
11255  private:
11256   JavaScriptFrame* frame_;
11257   DeoptimizedFrameInfo* deoptimized_frame_;
11258   Isolate* isolate_;
11259   bool is_optimized_;
11260   bool is_bottommost_;
11261   bool has_adapted_arguments_;
11262
11263   DISALLOW_COPY_AND_ASSIGN(FrameInspector);
11264 };
11265
11266
11267 static const int kFrameDetailsFrameIdIndex = 0;
11268 static const int kFrameDetailsReceiverIndex = 1;
11269 static const int kFrameDetailsFunctionIndex = 2;
11270 static const int kFrameDetailsArgumentCountIndex = 3;
11271 static const int kFrameDetailsLocalCountIndex = 4;
11272 static const int kFrameDetailsSourcePositionIndex = 5;
11273 static const int kFrameDetailsConstructCallIndex = 6;
11274 static const int kFrameDetailsAtReturnIndex = 7;
11275 static const int kFrameDetailsFlagsIndex = 8;
11276 static const int kFrameDetailsFirstDynamicIndex = 9;
11277
11278
11279 static SaveContext* FindSavedContextForFrame(Isolate* isolate,
11280                                              JavaScriptFrame* frame) {
11281   SaveContext* save = isolate->save_context();
11282   while (save != NULL && !save->IsBelowFrame(frame)) {
11283     save = save->prev();
11284   }
11285   ASSERT(save != NULL);
11286   return save;
11287 }
11288
11289
11290 // Return an array with frame details
11291 // args[0]: number: break id
11292 // args[1]: number: frame index
11293 //
11294 // The array returned contains the following information:
11295 // 0: Frame id
11296 // 1: Receiver
11297 // 2: Function
11298 // 3: Argument count
11299 // 4: Local count
11300 // 5: Source position
11301 // 6: Constructor call
11302 // 7: Is at return
11303 // 8: Flags
11304 // Arguments name, value
11305 // Locals name, value
11306 // Return value if any
11307 RUNTIME_FUNCTION(Runtime_GetFrameDetails) {
11308   HandleScope scope(isolate);
11309   ASSERT(args.length() == 2);
11310   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
11311   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
11312
11313   CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
11314   Heap* heap = isolate->heap();
11315
11316   // Find the relevant frame with the requested index.
11317   StackFrame::Id id = isolate->debug()->break_frame_id();
11318   if (id == StackFrame::NO_ID) {
11319     // If there are no JavaScript stack frames return undefined.
11320     return heap->undefined_value();
11321   }
11322
11323   int count = 0;
11324   JavaScriptFrameIterator it(isolate, id);
11325   for (; !it.done(); it.Advance()) {
11326     if (index < count + it.frame()->GetInlineCount()) break;
11327     count += it.frame()->GetInlineCount();
11328   }
11329   if (it.done()) return heap->undefined_value();
11330
11331   bool is_optimized = it.frame()->is_optimized();
11332
11333   int inlined_jsframe_index = 0;  // Inlined frame index in optimized frame.
11334   if (is_optimized) {
11335     inlined_jsframe_index =
11336         it.frame()->GetInlineCount() - (index - count) - 1;
11337   }
11338   FrameInspector frame_inspector(it.frame(), inlined_jsframe_index, isolate);
11339
11340   // Traverse the saved contexts chain to find the active context for the
11341   // selected frame.
11342   SaveContext* save = FindSavedContextForFrame(isolate, it.frame());
11343
11344   // Get the frame id.
11345   Handle<Object> frame_id(WrapFrameId(it.frame()->id()), isolate);
11346
11347   // Find source position in unoptimized code.
11348   int position = frame_inspector.GetSourcePosition();
11349
11350   // Check for constructor frame.
11351   bool constructor = frame_inspector.IsConstructor();
11352
11353   // Get scope info and read from it for local variable information.
11354   Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction()));
11355   Handle<SharedFunctionInfo> shared(function->shared());
11356   Handle<ScopeInfo> scope_info(shared->scope_info());
11357   ASSERT(*scope_info != ScopeInfo::Empty(isolate));
11358
11359   // Get the locals names and values into a temporary array.
11360   int local_count = scope_info->LocalCount();
11361   for (int slot = 0; slot < scope_info->LocalCount(); ++slot) {
11362     // Hide compiler-introduced temporary variables, whether on the stack or on
11363     // the context.
11364     if (scope_info->LocalIsSynthetic(slot))
11365       local_count--;
11366   }
11367
11368   Handle<FixedArray> locals =
11369       isolate->factory()->NewFixedArray(local_count * 2);
11370
11371   // Fill in the values of the locals.
11372   int local = 0;
11373   int i = 0;
11374   for (; i < scope_info->StackLocalCount(); ++i) {
11375     // Use the value from the stack.
11376     if (scope_info->LocalIsSynthetic(i))
11377       continue;
11378     locals->set(local * 2, scope_info->LocalName(i));
11379     locals->set(local * 2 + 1, frame_inspector.GetExpression(i));
11380     local++;
11381   }
11382   if (local < local_count) {
11383     // Get the context containing declarations.
11384     Handle<Context> context(
11385         Context::cast(it.frame()->context())->declaration_context());
11386     for (; i < scope_info->LocalCount(); ++i) {
11387       if (scope_info->LocalIsSynthetic(i))
11388         continue;
11389       Handle<String> name(scope_info->LocalName(i));
11390       VariableMode mode;
11391       InitializationFlag init_flag;
11392       locals->set(local * 2, *name);
11393       int context_slot_index =
11394           ScopeInfo::ContextSlotIndex(scope_info, name, &mode, &init_flag);
11395       Object* value = context->get(context_slot_index);
11396       locals->set(local * 2 + 1, value);
11397       local++;
11398     }
11399   }
11400
11401   // Check whether this frame is positioned at return. If not top
11402   // frame or if the frame is optimized it cannot be at a return.
11403   bool at_return = false;
11404   if (!is_optimized && index == 0) {
11405     at_return = isolate->debug()->IsBreakAtReturn(it.frame());
11406   }
11407
11408   // If positioned just before return find the value to be returned and add it
11409   // to the frame information.
11410   Handle<Object> return_value = isolate->factory()->undefined_value();
11411   if (at_return) {
11412     StackFrameIterator it2(isolate);
11413     Address internal_frame_sp = NULL;
11414     while (!it2.done()) {
11415       if (it2.frame()->is_internal()) {
11416         internal_frame_sp = it2.frame()->sp();
11417       } else {
11418         if (it2.frame()->is_java_script()) {
11419           if (it2.frame()->id() == it.frame()->id()) {
11420             // The internal frame just before the JavaScript frame contains the
11421             // value to return on top. A debug break at return will create an
11422             // internal frame to store the return value (eax/rax/r0) before
11423             // entering the debug break exit frame.
11424             if (internal_frame_sp != NULL) {
11425               return_value =
11426                   Handle<Object>(Memory::Object_at(internal_frame_sp),
11427                                  isolate);
11428               break;
11429             }
11430           }
11431         }
11432
11433         // Indicate that the previous frame was not an internal frame.
11434         internal_frame_sp = NULL;
11435       }
11436       it2.Advance();
11437     }
11438   }
11439
11440   // Now advance to the arguments adapter frame (if any). It contains all
11441   // the provided parameters whereas the function frame always have the number
11442   // of arguments matching the functions parameters. The rest of the
11443   // information (except for what is collected above) is the same.
11444   if ((inlined_jsframe_index == 0) && it.frame()->has_adapted_arguments()) {
11445     it.AdvanceToArgumentsFrame();
11446     frame_inspector.SetArgumentsFrame(it.frame());
11447   }
11448
11449   // Find the number of arguments to fill. At least fill the number of
11450   // parameters for the function and fill more if more parameters are provided.
11451   int argument_count = scope_info->ParameterCount();
11452   if (argument_count < frame_inspector.GetParametersCount()) {
11453     argument_count = frame_inspector.GetParametersCount();
11454   }
11455
11456   // Calculate the size of the result.
11457   int details_size = kFrameDetailsFirstDynamicIndex +
11458                      2 * (argument_count + local_count) +
11459                      (at_return ? 1 : 0);
11460   Handle<FixedArray> details = isolate->factory()->NewFixedArray(details_size);
11461
11462   // Add the frame id.
11463   details->set(kFrameDetailsFrameIdIndex, *frame_id);
11464
11465   // Add the function (same as in function frame).
11466   details->set(kFrameDetailsFunctionIndex, frame_inspector.GetFunction());
11467
11468   // Add the arguments count.
11469   details->set(kFrameDetailsArgumentCountIndex, Smi::FromInt(argument_count));
11470
11471   // Add the locals count
11472   details->set(kFrameDetailsLocalCountIndex,
11473                Smi::FromInt(local_count));
11474
11475   // Add the source position.
11476   if (position != RelocInfo::kNoPosition) {
11477     details->set(kFrameDetailsSourcePositionIndex, Smi::FromInt(position));
11478   } else {
11479     details->set(kFrameDetailsSourcePositionIndex, heap->undefined_value());
11480   }
11481
11482   // Add the constructor information.
11483   details->set(kFrameDetailsConstructCallIndex, heap->ToBoolean(constructor));
11484
11485   // Add the at return information.
11486   details->set(kFrameDetailsAtReturnIndex, heap->ToBoolean(at_return));
11487
11488   // Add flags to indicate information on whether this frame is
11489   //   bit 0: invoked in the debugger context.
11490   //   bit 1: optimized frame.
11491   //   bit 2: inlined in optimized frame
11492   int flags = 0;
11493   if (*save->context() == *isolate->debug()->debug_context()) {
11494     flags |= 1 << 0;
11495   }
11496   if (is_optimized) {
11497     flags |= 1 << 1;
11498     flags |= inlined_jsframe_index << 2;
11499   }
11500   details->set(kFrameDetailsFlagsIndex, Smi::FromInt(flags));
11501
11502   // Fill the dynamic part.
11503   int details_index = kFrameDetailsFirstDynamicIndex;
11504
11505   // Add arguments name and value.
11506   for (int i = 0; i < argument_count; i++) {
11507     // Name of the argument.
11508     if (i < scope_info->ParameterCount()) {
11509       details->set(details_index++, scope_info->ParameterName(i));
11510     } else {
11511       details->set(details_index++, heap->undefined_value());
11512     }
11513
11514     // Parameter value.
11515     if (i < frame_inspector.GetParametersCount()) {
11516       // Get the value from the stack.
11517       details->set(details_index++, frame_inspector.GetParameter(i));
11518     } else {
11519       details->set(details_index++, heap->undefined_value());
11520     }
11521   }
11522
11523   // Add locals name and value from the temporary copy from the function frame.
11524   for (int i = 0; i < local_count * 2; i++) {
11525     details->set(details_index++, locals->get(i));
11526   }
11527
11528   // Add the value being returned.
11529   if (at_return) {
11530     details->set(details_index++, *return_value);
11531   }
11532
11533   // Add the receiver (same as in function frame).
11534   // THIS MUST BE DONE LAST SINCE WE MIGHT ADVANCE
11535   // THE FRAME ITERATOR TO WRAP THE RECEIVER.
11536   Handle<Object> receiver(it.frame()->receiver(), isolate);
11537   if (!receiver->IsJSObject() &&
11538       shared->strict_mode() == SLOPPY &&
11539       !function->IsBuiltin()) {
11540     // If the receiver is not a JSObject and the function is not a
11541     // builtin or strict-mode we have hit an optimization where a
11542     // value object is not converted into a wrapped JS objects. To
11543     // hide this optimization from the debugger, we wrap the receiver
11544     // by creating correct wrapper object based on the calling frame's
11545     // native context.
11546     it.Advance();
11547     if (receiver->IsUndefined()) {
11548       Context* context = function->context();
11549       receiver = handle(context->global_object()->global_receiver());
11550     } else {
11551       ASSERT(!receiver->IsNull());
11552       Context* context = Context::cast(it.frame()->context());
11553       Handle<Context> native_context(Context::cast(context->native_context()));
11554       receiver = Object::ToObject(
11555           isolate, receiver, native_context).ToHandleChecked();
11556     }
11557   }
11558   details->set(kFrameDetailsReceiverIndex, *receiver);
11559
11560   ASSERT_EQ(details_size, details_index);
11561   return *isolate->factory()->NewJSArrayWithElements(details);
11562 }
11563
11564
11565 static bool ParameterIsShadowedByContextLocal(Handle<ScopeInfo> info,
11566                                               Handle<String> parameter_name) {
11567   VariableMode mode;
11568   InitializationFlag flag;
11569   return ScopeInfo::ContextSlotIndex(info, parameter_name, &mode, &flag) != -1;
11570 }
11571
11572
11573 // Create a plain JSObject which materializes the local scope for the specified
11574 // frame.
11575 MUST_USE_RESULT
11576 static MaybeHandle<JSObject> MaterializeStackLocalsWithFrameInspector(
11577     Isolate* isolate,
11578     Handle<JSObject> target,
11579     Handle<JSFunction> function,
11580     FrameInspector* frame_inspector) {
11581   Handle<SharedFunctionInfo> shared(function->shared());
11582   Handle<ScopeInfo> scope_info(shared->scope_info());
11583
11584   // First fill all parameters.
11585   for (int i = 0; i < scope_info->ParameterCount(); ++i) {
11586     // Do not materialize the parameter if it is shadowed by a context local.
11587     Handle<String> name(scope_info->ParameterName(i));
11588     if (ParameterIsShadowedByContextLocal(scope_info, name)) continue;
11589
11590     HandleScope scope(isolate);
11591     Handle<Object> value(i < frame_inspector->GetParametersCount()
11592                              ? frame_inspector->GetParameter(i)
11593                              : isolate->heap()->undefined_value(),
11594                          isolate);
11595     ASSERT(!value->IsTheHole());
11596
11597     RETURN_ON_EXCEPTION(
11598         isolate,
11599         Runtime::SetObjectProperty(isolate, target, name, value, NONE, SLOPPY),
11600         JSObject);
11601   }
11602
11603   // Second fill all stack locals.
11604   for (int i = 0; i < scope_info->StackLocalCount(); ++i) {
11605     if (scope_info->LocalIsSynthetic(i)) continue;
11606     Handle<String> name(scope_info->StackLocalName(i));
11607     Handle<Object> value(frame_inspector->GetExpression(i), isolate);
11608     if (value->IsTheHole()) continue;
11609
11610     RETURN_ON_EXCEPTION(
11611         isolate,
11612         Runtime::SetObjectProperty(isolate, target, name, value, NONE, SLOPPY),
11613         JSObject);
11614   }
11615
11616   return target;
11617 }
11618
11619
11620 static void UpdateStackLocalsFromMaterializedObject(Isolate* isolate,
11621                                                     Handle<JSObject> target,
11622                                                     Handle<JSFunction> function,
11623                                                     JavaScriptFrame* frame,
11624                                                     int inlined_jsframe_index) {
11625   if (inlined_jsframe_index != 0 || frame->is_optimized()) {
11626     // Optimized frames are not supported.
11627     // TODO(yangguo): make sure all code deoptimized when debugger is active
11628     //                and assert that this cannot happen.
11629     return;
11630   }
11631
11632   Handle<SharedFunctionInfo> shared(function->shared());
11633   Handle<ScopeInfo> scope_info(shared->scope_info());
11634
11635   // Parameters.
11636   for (int i = 0; i < scope_info->ParameterCount(); ++i) {
11637     // Shadowed parameters were not materialized.
11638     Handle<String> name(scope_info->ParameterName(i));
11639     if (ParameterIsShadowedByContextLocal(scope_info, name)) continue;
11640
11641     ASSERT(!frame->GetParameter(i)->IsTheHole());
11642     HandleScope scope(isolate);
11643     Handle<Object> value =
11644         Object::GetPropertyOrElement(target, name).ToHandleChecked();
11645     frame->SetParameterValue(i, *value);
11646   }
11647
11648   // Stack locals.
11649   for (int i = 0; i < scope_info->StackLocalCount(); ++i) {
11650     if (scope_info->LocalIsSynthetic(i)) continue;
11651     if (frame->GetExpression(i)->IsTheHole()) continue;
11652     HandleScope scope(isolate);
11653     Handle<Object> value = Object::GetPropertyOrElement(
11654         target,
11655         handle(scope_info->StackLocalName(i), isolate)).ToHandleChecked();
11656     frame->SetExpression(i, *value);
11657   }
11658 }
11659
11660
11661 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeLocalContext(
11662     Isolate* isolate,
11663     Handle<JSObject> target,
11664     Handle<JSFunction> function,
11665     JavaScriptFrame* frame) {
11666   HandleScope scope(isolate);
11667   Handle<SharedFunctionInfo> shared(function->shared());
11668   Handle<ScopeInfo> scope_info(shared->scope_info());
11669
11670   if (!scope_info->HasContext()) return target;
11671
11672   // Third fill all context locals.
11673   Handle<Context> frame_context(Context::cast(frame->context()));
11674   Handle<Context> function_context(frame_context->declaration_context());
11675   if (!ScopeInfo::CopyContextLocalsToScopeObject(
11676           scope_info, function_context, target)) {
11677     return MaybeHandle<JSObject>();
11678   }
11679
11680   // Finally copy any properties from the function context extension.
11681   // These will be variables introduced by eval.
11682   if (function_context->closure() == *function) {
11683     if (function_context->has_extension() &&
11684         !function_context->IsNativeContext()) {
11685       Handle<JSObject> ext(JSObject::cast(function_context->extension()));
11686       Handle<FixedArray> keys;
11687       ASSIGN_RETURN_ON_EXCEPTION(
11688           isolate, keys,
11689           JSReceiver::GetKeys(ext, JSReceiver::INCLUDE_PROTOS),
11690           JSObject);
11691
11692       for (int i = 0; i < keys->length(); i++) {
11693         // Names of variables introduced by eval are strings.
11694         ASSERT(keys->get(i)->IsString());
11695         Handle<String> key(String::cast(keys->get(i)));
11696         Handle<Object> value;
11697         ASSIGN_RETURN_ON_EXCEPTION(
11698             isolate, value, Object::GetPropertyOrElement(ext, key), JSObject);
11699         RETURN_ON_EXCEPTION(
11700             isolate,
11701             Runtime::SetObjectProperty(
11702                 isolate, target, key, value, NONE, SLOPPY),
11703             JSObject);
11704       }
11705     }
11706   }
11707
11708   return target;
11709 }
11710
11711
11712 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeLocalScope(
11713     Isolate* isolate,
11714     JavaScriptFrame* frame,
11715     int inlined_jsframe_index) {
11716   FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate);
11717   Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction()));
11718
11719   Handle<JSObject> local_scope =
11720       isolate->factory()->NewJSObject(isolate->object_function());
11721   ASSIGN_RETURN_ON_EXCEPTION(
11722       isolate, local_scope,
11723       MaterializeStackLocalsWithFrameInspector(
11724           isolate, local_scope, function, &frame_inspector),
11725       JSObject);
11726
11727   return MaterializeLocalContext(isolate, local_scope, function, frame);
11728 }
11729
11730
11731 // Set the context local variable value.
11732 static bool SetContextLocalValue(Isolate* isolate,
11733                                  Handle<ScopeInfo> scope_info,
11734                                  Handle<Context> context,
11735                                  Handle<String> variable_name,
11736                                  Handle<Object> new_value) {
11737   for (int i = 0; i < scope_info->ContextLocalCount(); i++) {
11738     Handle<String> next_name(scope_info->ContextLocalName(i));
11739     if (String::Equals(variable_name, next_name)) {
11740       VariableMode mode;
11741       InitializationFlag init_flag;
11742       int context_index =
11743           ScopeInfo::ContextSlotIndex(scope_info, next_name, &mode, &init_flag);
11744       context->set(context_index, *new_value);
11745       return true;
11746     }
11747   }
11748
11749   return false;
11750 }
11751
11752
11753 static bool SetLocalVariableValue(Isolate* isolate,
11754                                   JavaScriptFrame* frame,
11755                                   int inlined_jsframe_index,
11756                                   Handle<String> variable_name,
11757                                   Handle<Object> new_value) {
11758   if (inlined_jsframe_index != 0 || frame->is_optimized()) {
11759     // Optimized frames are not supported.
11760     return false;
11761   }
11762
11763   Handle<JSFunction> function(frame->function());
11764   Handle<SharedFunctionInfo> shared(function->shared());
11765   Handle<ScopeInfo> scope_info(shared->scope_info());
11766
11767   bool default_result = false;
11768
11769   // Parameters.
11770   for (int i = 0; i < scope_info->ParameterCount(); ++i) {
11771     HandleScope scope(isolate);
11772     if (String::Equals(handle(scope_info->ParameterName(i)), variable_name)) {
11773       frame->SetParameterValue(i, *new_value);
11774       // Argument might be shadowed in heap context, don't stop here.
11775       default_result = true;
11776     }
11777   }
11778
11779   // Stack locals.
11780   for (int i = 0; i < scope_info->StackLocalCount(); ++i) {
11781     HandleScope scope(isolate);
11782     if (String::Equals(handle(scope_info->StackLocalName(i)), variable_name)) {
11783       frame->SetExpression(i, *new_value);
11784       return true;
11785     }
11786   }
11787
11788   if (scope_info->HasContext()) {
11789     // Context locals.
11790     Handle<Context> frame_context(Context::cast(frame->context()));
11791     Handle<Context> function_context(frame_context->declaration_context());
11792     if (SetContextLocalValue(
11793         isolate, scope_info, function_context, variable_name, new_value)) {
11794       return true;
11795     }
11796
11797     // Function context extension. These are variables introduced by eval.
11798     if (function_context->closure() == *function) {
11799       if (function_context->has_extension() &&
11800           !function_context->IsNativeContext()) {
11801         Handle<JSObject> ext(JSObject::cast(function_context->extension()));
11802
11803         if (JSReceiver::HasProperty(ext, variable_name)) {
11804           // We don't expect this to do anything except replacing
11805           // property value.
11806           Runtime::SetObjectProperty(isolate, ext, variable_name, new_value,
11807                                      NONE, SLOPPY).Assert();
11808           return true;
11809         }
11810       }
11811     }
11812   }
11813
11814   return default_result;
11815 }
11816
11817
11818 // Create a plain JSObject which materializes the closure content for the
11819 // context.
11820 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeClosure(
11821     Isolate* isolate,
11822     Handle<Context> context) {
11823   ASSERT(context->IsFunctionContext());
11824
11825   Handle<SharedFunctionInfo> shared(context->closure()->shared());
11826   Handle<ScopeInfo> scope_info(shared->scope_info());
11827
11828   // Allocate and initialize a JSObject with all the content of this function
11829   // closure.
11830   Handle<JSObject> closure_scope =
11831       isolate->factory()->NewJSObject(isolate->object_function());
11832
11833   // Fill all context locals to the context extension.
11834   if (!ScopeInfo::CopyContextLocalsToScopeObject(
11835           scope_info, context, closure_scope)) {
11836     return MaybeHandle<JSObject>();
11837   }
11838
11839   // Finally copy any properties from the function context extension. This will
11840   // be variables introduced by eval.
11841   if (context->has_extension()) {
11842     Handle<JSObject> ext(JSObject::cast(context->extension()));
11843     Handle<FixedArray> keys;
11844     ASSIGN_RETURN_ON_EXCEPTION(
11845         isolate, keys,
11846         JSReceiver::GetKeys(ext, JSReceiver::INCLUDE_PROTOS), JSObject);
11847
11848     for (int i = 0; i < keys->length(); i++) {
11849       HandleScope scope(isolate);
11850       // Names of variables introduced by eval are strings.
11851       ASSERT(keys->get(i)->IsString());
11852       Handle<String> key(String::cast(keys->get(i)));
11853       Handle<Object> value;
11854       ASSIGN_RETURN_ON_EXCEPTION(
11855           isolate, value, Object::GetPropertyOrElement(ext, key), JSObject);
11856       RETURN_ON_EXCEPTION(
11857           isolate,
11858           Runtime::SetObjectProperty(
11859               isolate, closure_scope, key, value, NONE, SLOPPY),
11860           JSObject);
11861     }
11862   }
11863
11864   return closure_scope;
11865 }
11866
11867
11868 // This method copies structure of MaterializeClosure method above.
11869 static bool SetClosureVariableValue(Isolate* isolate,
11870                                     Handle<Context> context,
11871                                     Handle<String> variable_name,
11872                                     Handle<Object> new_value) {
11873   ASSERT(context->IsFunctionContext());
11874
11875   Handle<SharedFunctionInfo> shared(context->closure()->shared());
11876   Handle<ScopeInfo> scope_info(shared->scope_info());
11877
11878   // Context locals to the context extension.
11879   if (SetContextLocalValue(
11880           isolate, scope_info, context, variable_name, new_value)) {
11881     return true;
11882   }
11883
11884   // Properties from the function context extension. This will
11885   // be variables introduced by eval.
11886   if (context->has_extension()) {
11887     Handle<JSObject> ext(JSObject::cast(context->extension()));
11888     if (JSReceiver::HasProperty(ext, variable_name)) {
11889       // We don't expect this to do anything except replacing property value.
11890       Runtime::SetObjectProperty(isolate, ext, variable_name, new_value,
11891                                  NONE, SLOPPY).Assert();
11892       return true;
11893     }
11894   }
11895
11896   return false;
11897 }
11898
11899
11900 // Create a plain JSObject which materializes the scope for the specified
11901 // catch context.
11902 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeCatchScope(
11903     Isolate* isolate,
11904     Handle<Context> context) {
11905   ASSERT(context->IsCatchContext());
11906   Handle<String> name(String::cast(context->extension()));
11907   Handle<Object> thrown_object(context->get(Context::THROWN_OBJECT_INDEX),
11908                                isolate);
11909   Handle<JSObject> catch_scope =
11910       isolate->factory()->NewJSObject(isolate->object_function());
11911   RETURN_ON_EXCEPTION(
11912       isolate,
11913       Runtime::SetObjectProperty(isolate, catch_scope, name, thrown_object,
11914                                  NONE, SLOPPY),
11915       JSObject);
11916   return catch_scope;
11917 }
11918
11919
11920 static bool SetCatchVariableValue(Isolate* isolate,
11921                                   Handle<Context> context,
11922                                   Handle<String> variable_name,
11923                                   Handle<Object> new_value) {
11924   ASSERT(context->IsCatchContext());
11925   Handle<String> name(String::cast(context->extension()));
11926   if (!String::Equals(name, variable_name)) {
11927     return false;
11928   }
11929   context->set(Context::THROWN_OBJECT_INDEX, *new_value);
11930   return true;
11931 }
11932
11933
11934 // Create a plain JSObject which materializes the block scope for the specified
11935 // block context.
11936 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeBlockScope(
11937     Isolate* isolate,
11938     Handle<Context> context) {
11939   ASSERT(context->IsBlockContext());
11940   Handle<ScopeInfo> scope_info(ScopeInfo::cast(context->extension()));
11941
11942   // Allocate and initialize a JSObject with all the arguments, stack locals
11943   // heap locals and extension properties of the debugged function.
11944   Handle<JSObject> block_scope =
11945       isolate->factory()->NewJSObject(isolate->object_function());
11946
11947   // Fill all context locals.
11948   if (!ScopeInfo::CopyContextLocalsToScopeObject(
11949           scope_info, context, block_scope)) {
11950     return MaybeHandle<JSObject>();
11951   }
11952
11953   return block_scope;
11954 }
11955
11956
11957 // Create a plain JSObject which materializes the module scope for the specified
11958 // module context.
11959 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeModuleScope(
11960     Isolate* isolate,
11961     Handle<Context> context) {
11962   ASSERT(context->IsModuleContext());
11963   Handle<ScopeInfo> scope_info(ScopeInfo::cast(context->extension()));
11964
11965   // Allocate and initialize a JSObject with all the members of the debugged
11966   // module.
11967   Handle<JSObject> module_scope =
11968       isolate->factory()->NewJSObject(isolate->object_function());
11969
11970   // Fill all context locals.
11971   if (!ScopeInfo::CopyContextLocalsToScopeObject(
11972           scope_info, context, module_scope)) {
11973     return MaybeHandle<JSObject>();
11974   }
11975
11976   return module_scope;
11977 }
11978
11979
11980 // Iterate over the actual scopes visible from a stack frame or from a closure.
11981 // The iteration proceeds from the innermost visible nested scope outwards.
11982 // All scopes are backed by an actual context except the local scope,
11983 // which is inserted "artificially" in the context chain.
11984 class ScopeIterator {
11985  public:
11986   enum ScopeType {
11987     ScopeTypeGlobal = 0,
11988     ScopeTypeLocal,
11989     ScopeTypeWith,
11990     ScopeTypeClosure,
11991     ScopeTypeCatch,
11992     ScopeTypeBlock,
11993     ScopeTypeModule
11994   };
11995
11996   ScopeIterator(Isolate* isolate,
11997                 JavaScriptFrame* frame,
11998                 int inlined_jsframe_index,
11999                 bool ignore_nested_scopes = false)
12000     : isolate_(isolate),
12001       frame_(frame),
12002       inlined_jsframe_index_(inlined_jsframe_index),
12003       function_(frame->function()),
12004       context_(Context::cast(frame->context())),
12005       nested_scope_chain_(4),
12006       failed_(false) {
12007
12008     // Catch the case when the debugger stops in an internal function.
12009     Handle<SharedFunctionInfo> shared_info(function_->shared());
12010     Handle<ScopeInfo> scope_info(shared_info->scope_info());
12011     if (shared_info->script() == isolate->heap()->undefined_value()) {
12012       while (context_->closure() == *function_) {
12013         context_ = Handle<Context>(context_->previous(), isolate_);
12014       }
12015       return;
12016     }
12017
12018     // Get the debug info (create it if it does not exist).
12019     if (!isolate->debug()->EnsureDebugInfo(shared_info, function_)) {
12020       // Return if ensuring debug info failed.
12021       return;
12022     }
12023
12024     // Currently it takes too much time to find nested scopes due to script
12025     // parsing. Sometimes we want to run the ScopeIterator as fast as possible
12026     // (for example, while collecting async call stacks on every
12027     // addEventListener call), even if we drop some nested scopes.
12028     // Later we may optimize getting the nested scopes (cache the result?)
12029     // and include nested scopes into the "fast" iteration case as well.
12030     if (!ignore_nested_scopes) {
12031       Handle<DebugInfo> debug_info = Debug::GetDebugInfo(shared_info);
12032
12033       // Find the break point where execution has stopped.
12034       BreakLocationIterator break_location_iterator(debug_info,
12035                                                     ALL_BREAK_LOCATIONS);
12036       // pc points to the instruction after the current one, possibly a break
12037       // location as well. So the "- 1" to exclude it from the search.
12038       break_location_iterator.FindBreakLocationFromAddress(frame->pc() - 1);
12039
12040       // Within the return sequence at the moment it is not possible to
12041       // get a source position which is consistent with the current scope chain.
12042       // Thus all nested with, catch and block contexts are skipped and we only
12043       // provide the function scope.
12044       ignore_nested_scopes = break_location_iterator.IsExit();
12045     }
12046
12047     if (ignore_nested_scopes) {
12048       if (scope_info->HasContext()) {
12049         context_ = Handle<Context>(context_->declaration_context(), isolate_);
12050       } else {
12051         while (context_->closure() == *function_) {
12052           context_ = Handle<Context>(context_->previous(), isolate_);
12053         }
12054       }
12055       if (scope_info->scope_type() == FUNCTION_SCOPE) {
12056         nested_scope_chain_.Add(scope_info);
12057       }
12058     } else {
12059       // Reparse the code and analyze the scopes.
12060       Handle<Script> script(Script::cast(shared_info->script()));
12061       Scope* scope = NULL;
12062
12063       // Check whether we are in global, eval or function code.
12064       Handle<ScopeInfo> scope_info(shared_info->scope_info());
12065       if (scope_info->scope_type() != FUNCTION_SCOPE) {
12066         // Global or eval code.
12067         CompilationInfoWithZone info(script);
12068         if (scope_info->scope_type() == GLOBAL_SCOPE) {
12069           info.MarkAsGlobal();
12070         } else {
12071           ASSERT(scope_info->scope_type() == EVAL_SCOPE);
12072           info.MarkAsEval();
12073           info.SetContext(Handle<Context>(function_->context()));
12074         }
12075         if (Parser::Parse(&info) && Scope::Analyze(&info)) {
12076           scope = info.function()->scope();
12077         }
12078         RetrieveScopeChain(scope, shared_info);
12079       } else {
12080         // Function code
12081         CompilationInfoWithZone info(shared_info);
12082         if (Parser::Parse(&info) && Scope::Analyze(&info)) {
12083           scope = info.function()->scope();
12084         }
12085         RetrieveScopeChain(scope, shared_info);
12086       }
12087     }
12088   }
12089
12090   ScopeIterator(Isolate* isolate,
12091                 Handle<JSFunction> function)
12092     : isolate_(isolate),
12093       frame_(NULL),
12094       inlined_jsframe_index_(0),
12095       function_(function),
12096       context_(function->context()),
12097       failed_(false) {
12098     if (function->IsBuiltin()) {
12099       context_ = Handle<Context>();
12100     }
12101   }
12102
12103   // More scopes?
12104   bool Done() {
12105     ASSERT(!failed_);
12106     return context_.is_null();
12107   }
12108
12109   bool Failed() { return failed_; }
12110
12111   // Move to the next scope.
12112   void Next() {
12113     ASSERT(!failed_);
12114     ScopeType scope_type = Type();
12115     if (scope_type == ScopeTypeGlobal) {
12116       // The global scope is always the last in the chain.
12117       ASSERT(context_->IsNativeContext());
12118       context_ = Handle<Context>();
12119       return;
12120     }
12121     if (nested_scope_chain_.is_empty()) {
12122       context_ = Handle<Context>(context_->previous(), isolate_);
12123     } else {
12124       if (nested_scope_chain_.last()->HasContext()) {
12125         ASSERT(context_->previous() != NULL);
12126         context_ = Handle<Context>(context_->previous(), isolate_);
12127       }
12128       nested_scope_chain_.RemoveLast();
12129     }
12130   }
12131
12132   // Return the type of the current scope.
12133   ScopeType Type() {
12134     ASSERT(!failed_);
12135     if (!nested_scope_chain_.is_empty()) {
12136       Handle<ScopeInfo> scope_info = nested_scope_chain_.last();
12137       switch (scope_info->scope_type()) {
12138         case FUNCTION_SCOPE:
12139           ASSERT(context_->IsFunctionContext() ||
12140                  !scope_info->HasContext());
12141           return ScopeTypeLocal;
12142         case MODULE_SCOPE:
12143           ASSERT(context_->IsModuleContext());
12144           return ScopeTypeModule;
12145         case GLOBAL_SCOPE:
12146           ASSERT(context_->IsNativeContext());
12147           return ScopeTypeGlobal;
12148         case WITH_SCOPE:
12149           ASSERT(context_->IsWithContext());
12150           return ScopeTypeWith;
12151         case CATCH_SCOPE:
12152           ASSERT(context_->IsCatchContext());
12153           return ScopeTypeCatch;
12154         case BLOCK_SCOPE:
12155           ASSERT(!scope_info->HasContext() ||
12156                  context_->IsBlockContext());
12157           return ScopeTypeBlock;
12158         case EVAL_SCOPE:
12159           UNREACHABLE();
12160       }
12161     }
12162     if (context_->IsNativeContext()) {
12163       ASSERT(context_->global_object()->IsGlobalObject());
12164       return ScopeTypeGlobal;
12165     }
12166     if (context_->IsFunctionContext()) {
12167       return ScopeTypeClosure;
12168     }
12169     if (context_->IsCatchContext()) {
12170       return ScopeTypeCatch;
12171     }
12172     if (context_->IsBlockContext()) {
12173       return ScopeTypeBlock;
12174     }
12175     if (context_->IsModuleContext()) {
12176       return ScopeTypeModule;
12177     }
12178     ASSERT(context_->IsWithContext());
12179     return ScopeTypeWith;
12180   }
12181
12182   // Return the JavaScript object with the content of the current scope.
12183   MaybeHandle<JSObject> ScopeObject() {
12184     ASSERT(!failed_);
12185     switch (Type()) {
12186       case ScopeIterator::ScopeTypeGlobal:
12187         return Handle<JSObject>(CurrentContext()->global_object());
12188       case ScopeIterator::ScopeTypeLocal:
12189         // Materialize the content of the local scope into a JSObject.
12190         ASSERT(nested_scope_chain_.length() == 1);
12191         return MaterializeLocalScope(isolate_, frame_, inlined_jsframe_index_);
12192       case ScopeIterator::ScopeTypeWith:
12193         // Return the with object.
12194         return Handle<JSObject>(JSObject::cast(CurrentContext()->extension()));
12195       case ScopeIterator::ScopeTypeCatch:
12196         return MaterializeCatchScope(isolate_, CurrentContext());
12197       case ScopeIterator::ScopeTypeClosure:
12198         // Materialize the content of the closure scope into a JSObject.
12199         return MaterializeClosure(isolate_, CurrentContext());
12200       case ScopeIterator::ScopeTypeBlock:
12201         return MaterializeBlockScope(isolate_, CurrentContext());
12202       case ScopeIterator::ScopeTypeModule:
12203         return MaterializeModuleScope(isolate_, CurrentContext());
12204     }
12205     UNREACHABLE();
12206     return Handle<JSObject>();
12207   }
12208
12209   bool SetVariableValue(Handle<String> variable_name,
12210                         Handle<Object> new_value) {
12211     ASSERT(!failed_);
12212     switch (Type()) {
12213       case ScopeIterator::ScopeTypeGlobal:
12214         break;
12215       case ScopeIterator::ScopeTypeLocal:
12216         return SetLocalVariableValue(isolate_, frame_, inlined_jsframe_index_,
12217             variable_name, new_value);
12218       case ScopeIterator::ScopeTypeWith:
12219         break;
12220       case ScopeIterator::ScopeTypeCatch:
12221         return SetCatchVariableValue(isolate_, CurrentContext(),
12222             variable_name, new_value);
12223       case ScopeIterator::ScopeTypeClosure:
12224         return SetClosureVariableValue(isolate_, CurrentContext(),
12225             variable_name, new_value);
12226       case ScopeIterator::ScopeTypeBlock:
12227         // TODO(2399): should we implement it?
12228         break;
12229       case ScopeIterator::ScopeTypeModule:
12230         // TODO(2399): should we implement it?
12231         break;
12232     }
12233     return false;
12234   }
12235
12236   Handle<ScopeInfo> CurrentScopeInfo() {
12237     ASSERT(!failed_);
12238     if (!nested_scope_chain_.is_empty()) {
12239       return nested_scope_chain_.last();
12240     } else if (context_->IsBlockContext()) {
12241       return Handle<ScopeInfo>(ScopeInfo::cast(context_->extension()));
12242     } else if (context_->IsFunctionContext()) {
12243       return Handle<ScopeInfo>(context_->closure()->shared()->scope_info());
12244     }
12245     return Handle<ScopeInfo>::null();
12246   }
12247
12248   // Return the context for this scope. For the local context there might not
12249   // be an actual context.
12250   Handle<Context> CurrentContext() {
12251     ASSERT(!failed_);
12252     if (Type() == ScopeTypeGlobal ||
12253         nested_scope_chain_.is_empty()) {
12254       return context_;
12255     } else if (nested_scope_chain_.last()->HasContext()) {
12256       return context_;
12257     } else {
12258       return Handle<Context>();
12259     }
12260   }
12261
12262 #ifdef DEBUG
12263   // Debug print of the content of the current scope.
12264   void DebugPrint() {
12265     ASSERT(!failed_);
12266     switch (Type()) {
12267       case ScopeIterator::ScopeTypeGlobal:
12268         PrintF("Global:\n");
12269         CurrentContext()->Print();
12270         break;
12271
12272       case ScopeIterator::ScopeTypeLocal: {
12273         PrintF("Local:\n");
12274         function_->shared()->scope_info()->Print();
12275         if (!CurrentContext().is_null()) {
12276           CurrentContext()->Print();
12277           if (CurrentContext()->has_extension()) {
12278             Handle<Object> extension(CurrentContext()->extension(), isolate_);
12279             if (extension->IsJSContextExtensionObject()) {
12280               extension->Print();
12281             }
12282           }
12283         }
12284         break;
12285       }
12286
12287       case ScopeIterator::ScopeTypeWith:
12288         PrintF("With:\n");
12289         CurrentContext()->extension()->Print();
12290         break;
12291
12292       case ScopeIterator::ScopeTypeCatch:
12293         PrintF("Catch:\n");
12294         CurrentContext()->extension()->Print();
12295         CurrentContext()->get(Context::THROWN_OBJECT_INDEX)->Print();
12296         break;
12297
12298       case ScopeIterator::ScopeTypeClosure:
12299         PrintF("Closure:\n");
12300         CurrentContext()->Print();
12301         if (CurrentContext()->has_extension()) {
12302           Handle<Object> extension(CurrentContext()->extension(), isolate_);
12303           if (extension->IsJSContextExtensionObject()) {
12304             extension->Print();
12305           }
12306         }
12307         break;
12308
12309       default:
12310         UNREACHABLE();
12311     }
12312     PrintF("\n");
12313   }
12314 #endif
12315
12316  private:
12317   Isolate* isolate_;
12318   JavaScriptFrame* frame_;
12319   int inlined_jsframe_index_;
12320   Handle<JSFunction> function_;
12321   Handle<Context> context_;
12322   List<Handle<ScopeInfo> > nested_scope_chain_;
12323   bool failed_;
12324
12325   void RetrieveScopeChain(Scope* scope,
12326                           Handle<SharedFunctionInfo> shared_info) {
12327     if (scope != NULL) {
12328       int source_position = shared_info->code()->SourcePosition(frame_->pc());
12329       scope->GetNestedScopeChain(&nested_scope_chain_, source_position);
12330     } else {
12331       // A failed reparse indicates that the preparser has diverged from the
12332       // parser or that the preparse data given to the initial parse has been
12333       // faulty. We fail in debug mode but in release mode we only provide the
12334       // information we get from the context chain but nothing about
12335       // completely stack allocated scopes or stack allocated locals.
12336       // Or it could be due to stack overflow.
12337       ASSERT(isolate_->has_pending_exception());
12338       failed_ = true;
12339     }
12340   }
12341
12342   DISALLOW_IMPLICIT_CONSTRUCTORS(ScopeIterator);
12343 };
12344
12345
12346 RUNTIME_FUNCTION(Runtime_GetScopeCount) {
12347   HandleScope scope(isolate);
12348   ASSERT(args.length() == 2);
12349   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
12350   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
12351
12352   CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
12353
12354   // Get the frame where the debugging is performed.
12355   StackFrame::Id id = UnwrapFrameId(wrapped_id);
12356   JavaScriptFrameIterator it(isolate, id);
12357   JavaScriptFrame* frame = it.frame();
12358
12359   // Count the visible scopes.
12360   int n = 0;
12361   for (ScopeIterator it(isolate, frame, 0);
12362        !it.Done();
12363        it.Next()) {
12364     n++;
12365   }
12366
12367   return Smi::FromInt(n);
12368 }
12369
12370
12371 // Returns the list of step-in positions (text offset) in a function of the
12372 // stack frame in a range from the current debug break position to the end
12373 // of the corresponding statement.
12374 RUNTIME_FUNCTION(Runtime_GetStepInPositions) {
12375   HandleScope scope(isolate);
12376   ASSERT(args.length() == 2);
12377   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
12378   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
12379
12380   CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
12381
12382   // Get the frame where the debugging is performed.
12383   StackFrame::Id id = UnwrapFrameId(wrapped_id);
12384   JavaScriptFrameIterator frame_it(isolate, id);
12385   RUNTIME_ASSERT(!frame_it.done());
12386
12387   JavaScriptFrame* frame = frame_it.frame();
12388
12389   Handle<JSFunction> fun =
12390       Handle<JSFunction>(frame->function());
12391   Handle<SharedFunctionInfo> shared =
12392       Handle<SharedFunctionInfo>(fun->shared());
12393
12394   if (!isolate->debug()->EnsureDebugInfo(shared, fun)) {
12395     return isolate->heap()->undefined_value();
12396   }
12397
12398   Handle<DebugInfo> debug_info = Debug::GetDebugInfo(shared);
12399
12400   int len = 0;
12401   Handle<JSArray> array(isolate->factory()->NewJSArray(10));
12402   // Find the break point where execution has stopped.
12403   BreakLocationIterator break_location_iterator(debug_info,
12404                                                 ALL_BREAK_LOCATIONS);
12405
12406   break_location_iterator.FindBreakLocationFromAddress(frame->pc() - 1);
12407   int current_statement_pos = break_location_iterator.statement_position();
12408
12409   while (!break_location_iterator.Done()) {
12410     bool accept;
12411     if (break_location_iterator.pc() > frame->pc()) {
12412       accept = true;
12413     } else {
12414       StackFrame::Id break_frame_id = isolate->debug()->break_frame_id();
12415       // The break point is near our pc. Could be a step-in possibility,
12416       // that is currently taken by active debugger call.
12417       if (break_frame_id == StackFrame::NO_ID) {
12418         // We are not stepping.
12419         accept = false;
12420       } else {
12421         JavaScriptFrameIterator additional_frame_it(isolate, break_frame_id);
12422         // If our frame is a top frame and we are stepping, we can do step-in
12423         // at this place.
12424         accept = additional_frame_it.frame()->id() == id;
12425       }
12426     }
12427     if (accept) {
12428       if (break_location_iterator.IsStepInLocation(isolate)) {
12429         Smi* position_value = Smi::FromInt(break_location_iterator.position());
12430         RETURN_FAILURE_ON_EXCEPTION(
12431             isolate,
12432             JSObject::SetElement(array, len,
12433                                  Handle<Object>(position_value, isolate),
12434                                  NONE, SLOPPY));
12435         len++;
12436       }
12437     }
12438     // Advance iterator.
12439     break_location_iterator.Next();
12440     if (current_statement_pos !=
12441         break_location_iterator.statement_position()) {
12442       break;
12443     }
12444   }
12445   return *array;
12446 }
12447
12448
12449 static const int kScopeDetailsTypeIndex = 0;
12450 static const int kScopeDetailsObjectIndex = 1;
12451 static const int kScopeDetailsSize = 2;
12452
12453
12454 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeScopeDetails(
12455     Isolate* isolate,
12456     ScopeIterator* it) {
12457   // Calculate the size of the result.
12458   int details_size = kScopeDetailsSize;
12459   Handle<FixedArray> details = isolate->factory()->NewFixedArray(details_size);
12460
12461   // Fill in scope details.
12462   details->set(kScopeDetailsTypeIndex, Smi::FromInt(it->Type()));
12463   Handle<JSObject> scope_object;
12464   ASSIGN_RETURN_ON_EXCEPTION(
12465       isolate, scope_object, it->ScopeObject(), JSObject);
12466   details->set(kScopeDetailsObjectIndex, *scope_object);
12467
12468   return isolate->factory()->NewJSArrayWithElements(details);
12469 }
12470
12471
12472 // Return an array with scope details
12473 // args[0]: number: break id
12474 // args[1]: number: frame index
12475 // args[2]: number: inlined frame index
12476 // args[3]: number: scope index
12477 //
12478 // The array returned contains the following information:
12479 // 0: Scope type
12480 // 1: Scope object
12481 RUNTIME_FUNCTION(Runtime_GetScopeDetails) {
12482   HandleScope scope(isolate);
12483   ASSERT(args.length() == 4);
12484   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
12485   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
12486
12487   CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
12488   CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
12489   CONVERT_NUMBER_CHECKED(int, index, Int32, args[3]);
12490
12491   // Get the frame where the debugging is performed.
12492   StackFrame::Id id = UnwrapFrameId(wrapped_id);
12493   JavaScriptFrameIterator frame_it(isolate, id);
12494   JavaScriptFrame* frame = frame_it.frame();
12495
12496   // Find the requested scope.
12497   int n = 0;
12498   ScopeIterator it(isolate, frame, inlined_jsframe_index);
12499   for (; !it.Done() && n < index; it.Next()) {
12500     n++;
12501   }
12502   if (it.Done()) {
12503     return isolate->heap()->undefined_value();
12504   }
12505   Handle<JSObject> details;
12506   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
12507       isolate, details, MaterializeScopeDetails(isolate, &it));
12508   return *details;
12509 }
12510
12511
12512 // Return an array of scope details
12513 // args[0]: number: break id
12514 // args[1]: number: frame index
12515 // args[2]: number: inlined frame index
12516 // args[3]: boolean: ignore nested scopes
12517 //
12518 // The array returned contains arrays with the following information:
12519 // 0: Scope type
12520 // 1: Scope object
12521 RUNTIME_FUNCTION(Runtime_GetAllScopesDetails) {
12522   HandleScope scope(isolate);
12523   ASSERT(args.length() == 3 || args.length() == 4);
12524   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
12525   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
12526
12527   CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
12528   CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
12529
12530   bool ignore_nested_scopes = false;
12531   if (args.length() == 4) {
12532     CONVERT_BOOLEAN_ARG_CHECKED(flag, 3);
12533     ignore_nested_scopes = flag;
12534   }
12535
12536   // Get the frame where the debugging is performed.
12537   StackFrame::Id id = UnwrapFrameId(wrapped_id);
12538   JavaScriptFrameIterator frame_it(isolate, id);
12539   JavaScriptFrame* frame = frame_it.frame();
12540
12541   List<Handle<JSObject> > result(4);
12542   ScopeIterator it(isolate, frame, inlined_jsframe_index, ignore_nested_scopes);
12543   for (; !it.Done(); it.Next()) {
12544     Handle<JSObject> details;
12545     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
12546         isolate, details, MaterializeScopeDetails(isolate, &it));
12547     result.Add(details);
12548   }
12549
12550   Handle<FixedArray> array = isolate->factory()->NewFixedArray(result.length());
12551   for (int i = 0; i < result.length(); ++i) {
12552     array->set(i, *result[i]);
12553   }
12554   return *isolate->factory()->NewJSArrayWithElements(array);
12555 }
12556
12557
12558 RUNTIME_FUNCTION(Runtime_GetFunctionScopeCount) {
12559   HandleScope scope(isolate);
12560   ASSERT(args.length() == 1);
12561
12562   // Check arguments.
12563   CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
12564
12565   // Count the visible scopes.
12566   int n = 0;
12567   for (ScopeIterator it(isolate, fun); !it.Done(); it.Next()) {
12568     n++;
12569   }
12570
12571   return Smi::FromInt(n);
12572 }
12573
12574
12575 RUNTIME_FUNCTION(Runtime_GetFunctionScopeDetails) {
12576   HandleScope scope(isolate);
12577   ASSERT(args.length() == 2);
12578
12579   // Check arguments.
12580   CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
12581   CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
12582
12583   // Find the requested scope.
12584   int n = 0;
12585   ScopeIterator it(isolate, fun);
12586   for (; !it.Done() && n < index; it.Next()) {
12587     n++;
12588   }
12589   if (it.Done()) {
12590     return isolate->heap()->undefined_value();
12591   }
12592
12593   Handle<JSObject> details;
12594   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
12595       isolate, details, MaterializeScopeDetails(isolate, &it));
12596   return *details;
12597 }
12598
12599
12600 static bool SetScopeVariableValue(ScopeIterator* it, int index,
12601                                   Handle<String> variable_name,
12602                                   Handle<Object> new_value) {
12603   for (int n = 0; !it->Done() && n < index; it->Next()) {
12604     n++;
12605   }
12606   if (it->Done()) {
12607     return false;
12608   }
12609   return it->SetVariableValue(variable_name, new_value);
12610 }
12611
12612
12613 // Change variable value in closure or local scope
12614 // args[0]: number or JsFunction: break id or function
12615 // args[1]: number: frame index (when arg[0] is break id)
12616 // args[2]: number: inlined frame index (when arg[0] is break id)
12617 // args[3]: number: scope index
12618 // args[4]: string: variable name
12619 // args[5]: object: new value
12620 //
12621 // Return true if success and false otherwise
12622 RUNTIME_FUNCTION(Runtime_SetScopeVariableValue) {
12623   HandleScope scope(isolate);
12624   ASSERT(args.length() == 6);
12625
12626   // Check arguments.
12627   CONVERT_NUMBER_CHECKED(int, index, Int32, args[3]);
12628   CONVERT_ARG_HANDLE_CHECKED(String, variable_name, 4);
12629   CONVERT_ARG_HANDLE_CHECKED(Object, new_value, 5);
12630
12631   bool res;
12632   if (args[0]->IsNumber()) {
12633     CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
12634     RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
12635
12636     CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
12637     CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
12638
12639     // Get the frame where the debugging is performed.
12640     StackFrame::Id id = UnwrapFrameId(wrapped_id);
12641     JavaScriptFrameIterator frame_it(isolate, id);
12642     JavaScriptFrame* frame = frame_it.frame();
12643
12644     ScopeIterator it(isolate, frame, inlined_jsframe_index);
12645     res = SetScopeVariableValue(&it, index, variable_name, new_value);
12646   } else {
12647     CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
12648     ScopeIterator it(isolate, fun);
12649     res = SetScopeVariableValue(&it, index, variable_name, new_value);
12650   }
12651
12652   return isolate->heap()->ToBoolean(res);
12653 }
12654
12655
12656 RUNTIME_FUNCTION(Runtime_DebugPrintScopes) {
12657   HandleScope scope(isolate);
12658   ASSERT(args.length() == 0);
12659
12660 #ifdef DEBUG
12661   // Print the scopes for the top frame.
12662   StackFrameLocator locator(isolate);
12663   JavaScriptFrame* frame = locator.FindJavaScriptFrame(0);
12664   for (ScopeIterator it(isolate, frame, 0);
12665        !it.Done();
12666        it.Next()) {
12667     it.DebugPrint();
12668   }
12669 #endif
12670   return isolate->heap()->undefined_value();
12671 }
12672
12673
12674 RUNTIME_FUNCTION(Runtime_GetThreadCount) {
12675   HandleScope scope(isolate);
12676   ASSERT(args.length() == 1);
12677   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
12678   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
12679
12680   // Count all archived V8 threads.
12681   int n = 0;
12682   for (ThreadState* thread =
12683           isolate->thread_manager()->FirstThreadStateInUse();
12684        thread != NULL;
12685        thread = thread->Next()) {
12686     n++;
12687   }
12688
12689   // Total number of threads is current thread and archived threads.
12690   return Smi::FromInt(n + 1);
12691 }
12692
12693
12694 static const int kThreadDetailsCurrentThreadIndex = 0;
12695 static const int kThreadDetailsThreadIdIndex = 1;
12696 static const int kThreadDetailsSize = 2;
12697
12698 // Return an array with thread details
12699 // args[0]: number: break id
12700 // args[1]: number: thread index
12701 //
12702 // The array returned contains the following information:
12703 // 0: Is current thread?
12704 // 1: Thread id
12705 RUNTIME_FUNCTION(Runtime_GetThreadDetails) {
12706   HandleScope scope(isolate);
12707   ASSERT(args.length() == 2);
12708   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
12709   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
12710
12711   CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
12712
12713   // Allocate array for result.
12714   Handle<FixedArray> details =
12715       isolate->factory()->NewFixedArray(kThreadDetailsSize);
12716
12717   // Thread index 0 is current thread.
12718   if (index == 0) {
12719     // Fill the details.
12720     details->set(kThreadDetailsCurrentThreadIndex,
12721                  isolate->heap()->true_value());
12722     details->set(kThreadDetailsThreadIdIndex,
12723                  Smi::FromInt(ThreadId::Current().ToInteger()));
12724   } else {
12725     // Find the thread with the requested index.
12726     int n = 1;
12727     ThreadState* thread =
12728         isolate->thread_manager()->FirstThreadStateInUse();
12729     while (index != n && thread != NULL) {
12730       thread = thread->Next();
12731       n++;
12732     }
12733     if (thread == NULL) {
12734       return isolate->heap()->undefined_value();
12735     }
12736
12737     // Fill the details.
12738     details->set(kThreadDetailsCurrentThreadIndex,
12739                  isolate->heap()->false_value());
12740     details->set(kThreadDetailsThreadIdIndex,
12741                  Smi::FromInt(thread->id().ToInteger()));
12742   }
12743
12744   // Convert to JS array and return.
12745   return *isolate->factory()->NewJSArrayWithElements(details);
12746 }
12747
12748
12749 // Sets the disable break state
12750 // args[0]: disable break state
12751 RUNTIME_FUNCTION(Runtime_SetDisableBreak) {
12752   HandleScope scope(isolate);
12753   ASSERT(args.length() == 1);
12754   CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 0);
12755   isolate->debug()->set_disable_break(disable_break);
12756   return  isolate->heap()->undefined_value();
12757 }
12758
12759
12760 static bool IsPositionAlignmentCodeCorrect(int alignment) {
12761   return alignment == STATEMENT_ALIGNED || alignment == BREAK_POSITION_ALIGNED;
12762 }
12763
12764
12765 RUNTIME_FUNCTION(Runtime_GetBreakLocations) {
12766   HandleScope scope(isolate);
12767   ASSERT(args.length() == 2);
12768
12769   CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
12770   CONVERT_NUMBER_CHECKED(int32_t, statement_aligned_code, Int32, args[1]);
12771
12772   if (!IsPositionAlignmentCodeCorrect(statement_aligned_code)) {
12773     return isolate->ThrowIllegalOperation();
12774   }
12775   BreakPositionAlignment alignment =
12776       static_cast<BreakPositionAlignment>(statement_aligned_code);
12777
12778   Handle<SharedFunctionInfo> shared(fun->shared());
12779   // Find the number of break points
12780   Handle<Object> break_locations =
12781       Debug::GetSourceBreakLocations(shared, alignment);
12782   if (break_locations->IsUndefined()) return isolate->heap()->undefined_value();
12783   // Return array as JS array
12784   return *isolate->factory()->NewJSArrayWithElements(
12785       Handle<FixedArray>::cast(break_locations));
12786 }
12787
12788
12789 // Set a break point in a function.
12790 // args[0]: function
12791 // args[1]: number: break source position (within the function source)
12792 // args[2]: number: break point object
12793 RUNTIME_FUNCTION(Runtime_SetFunctionBreakPoint) {
12794   HandleScope scope(isolate);
12795   ASSERT(args.length() == 3);
12796   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
12797   CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
12798   RUNTIME_ASSERT(source_position >= 0);
12799   CONVERT_ARG_HANDLE_CHECKED(Object, break_point_object_arg, 2);
12800
12801   // Set break point.
12802   isolate->debug()->SetBreakPoint(function, break_point_object_arg,
12803                                   &source_position);
12804
12805   return Smi::FromInt(source_position);
12806 }
12807
12808
12809 // Changes the state of a break point in a script and returns source position
12810 // where break point was set. NOTE: Regarding performance see the NOTE for
12811 // GetScriptFromScriptData.
12812 // args[0]: script to set break point in
12813 // args[1]: number: break source position (within the script source)
12814 // args[2]: number, breakpoint position alignment
12815 // args[3]: number: break point object
12816 RUNTIME_FUNCTION(Runtime_SetScriptBreakPoint) {
12817   HandleScope scope(isolate);
12818   ASSERT(args.length() == 4);
12819   CONVERT_ARG_HANDLE_CHECKED(JSValue, wrapper, 0);
12820   CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
12821   RUNTIME_ASSERT(source_position >= 0);
12822   CONVERT_NUMBER_CHECKED(int32_t, statement_aligned_code, Int32, args[2]);
12823   CONVERT_ARG_HANDLE_CHECKED(Object, break_point_object_arg, 3);
12824
12825   if (!IsPositionAlignmentCodeCorrect(statement_aligned_code)) {
12826     return isolate->ThrowIllegalOperation();
12827   }
12828   BreakPositionAlignment alignment =
12829       static_cast<BreakPositionAlignment>(statement_aligned_code);
12830
12831   // Get the script from the script wrapper.
12832   RUNTIME_ASSERT(wrapper->value()->IsScript());
12833   Handle<Script> script(Script::cast(wrapper->value()));
12834
12835   // Set break point.
12836   if (!isolate->debug()->SetBreakPointForScript(script, break_point_object_arg,
12837                                                 &source_position,
12838                                                 alignment)) {
12839     return isolate->heap()->undefined_value();
12840   }
12841
12842   return Smi::FromInt(source_position);
12843 }
12844
12845
12846 // Clear a break point
12847 // args[0]: number: break point object
12848 RUNTIME_FUNCTION(Runtime_ClearBreakPoint) {
12849   HandleScope scope(isolate);
12850   ASSERT(args.length() == 1);
12851   CONVERT_ARG_HANDLE_CHECKED(Object, break_point_object_arg, 0);
12852
12853   // Clear break point.
12854   isolate->debug()->ClearBreakPoint(break_point_object_arg);
12855
12856   return isolate->heap()->undefined_value();
12857 }
12858
12859
12860 // Change the state of break on exceptions.
12861 // args[0]: Enum value indicating whether to affect caught/uncaught exceptions.
12862 // args[1]: Boolean indicating on/off.
12863 RUNTIME_FUNCTION(Runtime_ChangeBreakOnException) {
12864   HandleScope scope(isolate);
12865   ASSERT(args.length() == 2);
12866   CONVERT_NUMBER_CHECKED(uint32_t, type_arg, Uint32, args[0]);
12867   CONVERT_BOOLEAN_ARG_CHECKED(enable, 1);
12868
12869   // If the number doesn't match an enum value, the ChangeBreakOnException
12870   // function will default to affecting caught exceptions.
12871   ExceptionBreakType type = static_cast<ExceptionBreakType>(type_arg);
12872   // Update break point state.
12873   isolate->debug()->ChangeBreakOnException(type, enable);
12874   return isolate->heap()->undefined_value();
12875 }
12876
12877
12878 // Returns the state of break on exceptions
12879 // args[0]: boolean indicating uncaught exceptions
12880 RUNTIME_FUNCTION(Runtime_IsBreakOnException) {
12881   HandleScope scope(isolate);
12882   ASSERT(args.length() == 1);
12883   CONVERT_NUMBER_CHECKED(uint32_t, type_arg, Uint32, args[0]);
12884
12885   ExceptionBreakType type = static_cast<ExceptionBreakType>(type_arg);
12886   bool result = isolate->debug()->IsBreakOnException(type);
12887   return Smi::FromInt(result);
12888 }
12889
12890
12891 // Prepare for stepping
12892 // args[0]: break id for checking execution state
12893 // args[1]: step action from the enumeration StepAction
12894 // args[2]: number of times to perform the step, for step out it is the number
12895 //          of frames to step down.
12896 RUNTIME_FUNCTION(Runtime_PrepareStep) {
12897   HandleScope scope(isolate);
12898   ASSERT(args.length() == 4);
12899   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
12900   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
12901
12902   if (!args[1]->IsNumber() || !args[2]->IsNumber()) {
12903     return isolate->Throw(isolate->heap()->illegal_argument_string());
12904   }
12905
12906   CONVERT_NUMBER_CHECKED(int, wrapped_frame_id, Int32, args[3]);
12907
12908   StackFrame::Id frame_id;
12909   if (wrapped_frame_id == 0) {
12910     frame_id = StackFrame::NO_ID;
12911   } else {
12912     frame_id = UnwrapFrameId(wrapped_frame_id);
12913   }
12914
12915   // Get the step action and check validity.
12916   StepAction step_action = static_cast<StepAction>(NumberToInt32(args[1]));
12917   if (step_action != StepIn &&
12918       step_action != StepNext &&
12919       step_action != StepOut &&
12920       step_action != StepInMin &&
12921       step_action != StepMin) {
12922     return isolate->Throw(isolate->heap()->illegal_argument_string());
12923   }
12924
12925   if (frame_id != StackFrame::NO_ID && step_action != StepNext &&
12926       step_action != StepMin && step_action != StepOut) {
12927     return isolate->ThrowIllegalOperation();
12928   }
12929
12930   // Get the number of steps.
12931   int step_count = NumberToInt32(args[2]);
12932   if (step_count < 1) {
12933     return isolate->Throw(isolate->heap()->illegal_argument_string());
12934   }
12935
12936   // Clear all current stepping setup.
12937   isolate->debug()->ClearStepping();
12938
12939   // Prepare step.
12940   isolate->debug()->PrepareStep(static_cast<StepAction>(step_action),
12941                                 step_count,
12942                                 frame_id);
12943   return isolate->heap()->undefined_value();
12944 }
12945
12946
12947 // Clear all stepping set by PrepareStep.
12948 RUNTIME_FUNCTION(Runtime_ClearStepping) {
12949   HandleScope scope(isolate);
12950   ASSERT(args.length() == 0);
12951   isolate->debug()->ClearStepping();
12952   return isolate->heap()->undefined_value();
12953 }
12954
12955
12956 // Helper function to find or create the arguments object for
12957 // Runtime_DebugEvaluate.
12958 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeArgumentsObject(
12959     Isolate* isolate,
12960     Handle<JSObject> target,
12961     Handle<JSFunction> function) {
12962   // Do not materialize the arguments object for eval or top-level code.
12963   // Skip if "arguments" is already taken.
12964   if (!function->shared()->is_function() ||
12965       JSReceiver::HasLocalProperty(target,
12966                                    isolate->factory()->arguments_string())) {
12967     return target;
12968   }
12969
12970   // FunctionGetArguments can't throw an exception.
12971   Handle<JSObject> arguments = Handle<JSObject>::cast(
12972       Accessors::FunctionGetArguments(function));
12973   Handle<String> arguments_str = isolate->factory()->arguments_string();
12974   RETURN_ON_EXCEPTION(
12975       isolate,
12976       Runtime::SetObjectProperty(
12977           isolate, target, arguments_str, arguments, ::NONE, SLOPPY),
12978       JSObject);
12979   return target;
12980 }
12981
12982
12983 // Compile and evaluate source for the given context.
12984 static MaybeHandle<Object> DebugEvaluate(Isolate* isolate,
12985                                          Handle<Context> context,
12986                                          Handle<Object> context_extension,
12987                                          Handle<Object> receiver,
12988                                          Handle<String> source) {
12989   if (context_extension->IsJSObject()) {
12990     Handle<JSObject> extension = Handle<JSObject>::cast(context_extension);
12991     Handle<JSFunction> closure(context->closure(), isolate);
12992     context = isolate->factory()->NewWithContext(closure, context, extension);
12993   }
12994
12995   Handle<JSFunction> eval_fun;
12996   ASSIGN_RETURN_ON_EXCEPTION(
12997       isolate, eval_fun,
12998       Compiler::GetFunctionFromEval(source,
12999                                     context,
13000                                     SLOPPY,
13001                                     NO_PARSE_RESTRICTION,
13002                                     RelocInfo::kNoPosition),
13003       Object);
13004
13005   Handle<Object> result;
13006   ASSIGN_RETURN_ON_EXCEPTION(
13007       isolate, result,
13008       Execution::Call(isolate, eval_fun, receiver, 0, NULL),
13009       Object);
13010
13011   // Skip the global proxy as it has no properties and always delegates to the
13012   // real global object.
13013   if (result->IsJSGlobalProxy()) {
13014     result = Handle<JSObject>(JSObject::cast(result->GetPrototype(isolate)));
13015   }
13016
13017   // Clear the oneshot breakpoints so that the debugger does not step further.
13018   isolate->debug()->ClearStepping();
13019   return result;
13020 }
13021
13022
13023 // Evaluate a piece of JavaScript in the context of a stack frame for
13024 // debugging.  Things that need special attention are:
13025 // - Parameters and stack-allocated locals need to be materialized.  Altered
13026 //   values need to be written back to the stack afterwards.
13027 // - The arguments object needs to materialized.
13028 RUNTIME_FUNCTION(Runtime_DebugEvaluate) {
13029   HandleScope scope(isolate);
13030
13031   // Check the execution state and decode arguments frame and source to be
13032   // evaluated.
13033   ASSERT(args.length() == 6);
13034   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
13035   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
13036
13037   CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
13038   CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
13039   CONVERT_ARG_HANDLE_CHECKED(String, source, 3);
13040   CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 4);
13041   CONVERT_ARG_HANDLE_CHECKED(Object, context_extension, 5);
13042
13043   // Handle the processing of break.
13044   DisableBreak disable_break_save(isolate, disable_break);
13045
13046   // Get the frame where the debugging is performed.
13047   StackFrame::Id id = UnwrapFrameId(wrapped_id);
13048   JavaScriptFrameIterator it(isolate, id);
13049   JavaScriptFrame* frame = it.frame();
13050   FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate);
13051   Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction()));
13052
13053   // Traverse the saved contexts chain to find the active context for the
13054   // selected frame.
13055   SaveContext* save = FindSavedContextForFrame(isolate, frame);
13056
13057   SaveContext savex(isolate);
13058   isolate->set_context(*(save->context()));
13059
13060   // Evaluate on the context of the frame.
13061   Handle<Context> context(Context::cast(frame->context()));
13062   ASSERT(!context.is_null());
13063
13064   // Materialize stack locals and the arguments object.
13065   Handle<JSObject> materialized =
13066       isolate->factory()->NewJSObject(isolate->object_function());
13067
13068   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
13069       isolate, materialized,
13070       MaterializeStackLocalsWithFrameInspector(
13071           isolate, materialized, function, &frame_inspector));
13072
13073   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
13074       isolate, materialized,
13075       MaterializeArgumentsObject(isolate, materialized, function));
13076
13077   // Add the materialized object in a with-scope to shadow the stack locals.
13078   context = isolate->factory()->NewWithContext(function, context, materialized);
13079
13080   Handle<Object> receiver(frame->receiver(), isolate);
13081   Handle<Object> result;
13082   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
13083       isolate, result,
13084       DebugEvaluate(isolate, context, context_extension, receiver, source));
13085
13086   // Write back potential changes to materialized stack locals to the stack.
13087   UpdateStackLocalsFromMaterializedObject(
13088       isolate, materialized, function, frame, inlined_jsframe_index);
13089
13090   return *result;
13091 }
13092
13093
13094 RUNTIME_FUNCTION(Runtime_DebugEvaluateGlobal) {
13095   HandleScope scope(isolate);
13096
13097   // Check the execution state and decode arguments frame and source to be
13098   // evaluated.
13099   ASSERT(args.length() == 4);
13100   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
13101   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
13102
13103   CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
13104   CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 2);
13105   CONVERT_ARG_HANDLE_CHECKED(Object, context_extension, 3);
13106
13107   // Handle the processing of break.
13108   DisableBreak disable_break_save(isolate, disable_break);
13109
13110   // Enter the top context from before the debugger was invoked.
13111   SaveContext save(isolate);
13112   SaveContext* top = &save;
13113   while (top != NULL && *top->context() == *isolate->debug()->debug_context()) {
13114     top = top->prev();
13115   }
13116   if (top != NULL) {
13117     isolate->set_context(*top->context());
13118   }
13119
13120   // Get the native context now set to the top context from before the
13121   // debugger was invoked.
13122   Handle<Context> context = isolate->native_context();
13123   Handle<Object> receiver = isolate->global_object();
13124   Handle<Object> result;
13125   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
13126       isolate, result,
13127       DebugEvaluate(isolate, context, context_extension, receiver, source));
13128   return *result;
13129 }
13130
13131
13132 RUNTIME_FUNCTION(Runtime_DebugGetLoadedScripts) {
13133   HandleScope scope(isolate);
13134   ASSERT(args.length() == 0);
13135
13136   // Fill the script objects.
13137   Handle<FixedArray> instances = isolate->debug()->GetLoadedScripts();
13138
13139   // Convert the script objects to proper JS objects.
13140   for (int i = 0; i < instances->length(); i++) {
13141     Handle<Script> script = Handle<Script>(Script::cast(instances->get(i)));
13142     // Get the script wrapper in a local handle before calling GetScriptWrapper,
13143     // because using
13144     //   instances->set(i, *GetScriptWrapper(script))
13145     // is unsafe as GetScriptWrapper might call GC and the C++ compiler might
13146     // already have dereferenced the instances handle.
13147     Handle<JSObject> wrapper = Script::GetWrapper(script);
13148     instances->set(i, *wrapper);
13149   }
13150
13151   // Return result as a JS array.
13152   Handle<JSObject> result =
13153       isolate->factory()->NewJSObject(isolate->array_function());
13154   JSArray::SetContent(Handle<JSArray>::cast(result), instances);
13155   return *result;
13156 }
13157
13158
13159 // Helper function used by Runtime_DebugReferencedBy below.
13160 static int DebugReferencedBy(HeapIterator* iterator,
13161                              JSObject* target,
13162                              Object* instance_filter, int max_references,
13163                              FixedArray* instances, int instances_size,
13164                              JSFunction* arguments_function) {
13165   Isolate* isolate = target->GetIsolate();
13166   SealHandleScope shs(isolate);
13167   DisallowHeapAllocation no_allocation;
13168
13169   // Iterate the heap.
13170   int count = 0;
13171   JSObject* last = NULL;
13172   HeapObject* heap_obj = NULL;
13173   while (((heap_obj = iterator->next()) != NULL) &&
13174          (max_references == 0 || count < max_references)) {
13175     // Only look at all JSObjects.
13176     if (heap_obj->IsJSObject()) {
13177       // Skip context extension objects and argument arrays as these are
13178       // checked in the context of functions using them.
13179       JSObject* obj = JSObject::cast(heap_obj);
13180       if (obj->IsJSContextExtensionObject() ||
13181           obj->map()->constructor() == arguments_function) {
13182         continue;
13183       }
13184
13185       // Check if the JS object has a reference to the object looked for.
13186       if (obj->ReferencesObject(target)) {
13187         // Check instance filter if supplied. This is normally used to avoid
13188         // references from mirror objects (see Runtime_IsInPrototypeChain).
13189         if (!instance_filter->IsUndefined()) {
13190           Object* V = obj;
13191           while (true) {
13192             Object* prototype = V->GetPrototype(isolate);
13193             if (prototype->IsNull()) {
13194               break;
13195             }
13196             if (instance_filter == prototype) {
13197               obj = NULL;  // Don't add this object.
13198               break;
13199             }
13200             V = prototype;
13201           }
13202         }
13203
13204         if (obj != NULL) {
13205           // Valid reference found add to instance array if supplied an update
13206           // count.
13207           if (instances != NULL && count < instances_size) {
13208             instances->set(count, obj);
13209           }
13210           last = obj;
13211           count++;
13212         }
13213       }
13214     }
13215   }
13216
13217   // Check for circular reference only. This can happen when the object is only
13218   // referenced from mirrors and has a circular reference in which case the
13219   // object is not really alive and would have been garbage collected if not
13220   // referenced from the mirror.
13221   if (count == 1 && last == target) {
13222     count = 0;
13223   }
13224
13225   // Return the number of referencing objects found.
13226   return count;
13227 }
13228
13229
13230 // Scan the heap for objects with direct references to an object
13231 // args[0]: the object to find references to
13232 // args[1]: constructor function for instances to exclude (Mirror)
13233 // args[2]: the the maximum number of objects to return
13234 RUNTIME_FUNCTION(Runtime_DebugReferencedBy) {
13235   HandleScope scope(isolate);
13236   ASSERT(args.length() == 3);
13237
13238   // First perform a full GC in order to avoid references from dead objects.
13239   Heap* heap = isolate->heap();
13240   heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "%DebugReferencedBy");
13241   // The heap iterator reserves the right to do a GC to make the heap iterable.
13242   // Due to the GC above we know it won't need to do that, but it seems cleaner
13243   // to get the heap iterator constructed before we start having unprotected
13244   // Object* locals that are not protected by handles.
13245
13246   // Check parameters.
13247   CONVERT_ARG_HANDLE_CHECKED(JSObject, target, 0);
13248   CONVERT_ARG_HANDLE_CHECKED(Object, instance_filter, 1);
13249   RUNTIME_ASSERT(instance_filter->IsUndefined() ||
13250                  instance_filter->IsJSObject());
13251   CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[2]);
13252   RUNTIME_ASSERT(max_references >= 0);
13253
13254
13255   // Get the constructor function for context extension and arguments array.
13256   Handle<JSObject> arguments_boilerplate(
13257       isolate->context()->native_context()->sloppy_arguments_boilerplate());
13258   Handle<JSFunction> arguments_function(
13259       JSFunction::cast(arguments_boilerplate->map()->constructor()));
13260
13261   // Get the number of referencing objects.
13262   int count;
13263   HeapIterator heap_iterator(heap);
13264   count = DebugReferencedBy(&heap_iterator,
13265                             *target, *instance_filter, max_references,
13266                             NULL, 0, *arguments_function);
13267
13268   // Allocate an array to hold the result.
13269   Handle<FixedArray> instances = isolate->factory()->NewFixedArray(count);
13270
13271   // Fill the referencing objects.
13272   // AllocateFixedArray above does not make the heap non-iterable.
13273   ASSERT(heap->IsHeapIterable());
13274   HeapIterator heap_iterator2(heap);
13275   count = DebugReferencedBy(&heap_iterator2,
13276                             *target, *instance_filter, max_references,
13277                             *instances, count, *arguments_function);
13278
13279   // Return result as JS array.
13280   Handle<JSFunction> constructor(
13281       isolate->context()->native_context()->array_function());
13282
13283   Handle<JSObject> result = isolate->factory()->NewJSObject(constructor);
13284   JSArray::SetContent(Handle<JSArray>::cast(result), instances);
13285   return *result;
13286 }
13287
13288
13289 // Helper function used by Runtime_DebugConstructedBy below.
13290 static int DebugConstructedBy(HeapIterator* iterator,
13291                               JSFunction* constructor,
13292                               int max_references,
13293                               FixedArray* instances,
13294                               int instances_size) {
13295   DisallowHeapAllocation no_allocation;
13296
13297   // Iterate the heap.
13298   int count = 0;
13299   HeapObject* heap_obj = NULL;
13300   while (((heap_obj = iterator->next()) != NULL) &&
13301          (max_references == 0 || count < max_references)) {
13302     // Only look at all JSObjects.
13303     if (heap_obj->IsJSObject()) {
13304       JSObject* obj = JSObject::cast(heap_obj);
13305       if (obj->map()->constructor() == constructor) {
13306         // Valid reference found add to instance array if supplied an update
13307         // count.
13308         if (instances != NULL && count < instances_size) {
13309           instances->set(count, obj);
13310         }
13311         count++;
13312       }
13313     }
13314   }
13315
13316   // Return the number of referencing objects found.
13317   return count;
13318 }
13319
13320
13321 // Scan the heap for objects constructed by a specific function.
13322 // args[0]: the constructor to find instances of
13323 // args[1]: the the maximum number of objects to return
13324 RUNTIME_FUNCTION(Runtime_DebugConstructedBy) {
13325   HandleScope scope(isolate);
13326   ASSERT(args.length() == 2);
13327
13328   // First perform a full GC in order to avoid dead objects.
13329   Heap* heap = isolate->heap();
13330   heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "%DebugConstructedBy");
13331
13332   // Check parameters.
13333   CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, 0);
13334   CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[1]);
13335   RUNTIME_ASSERT(max_references >= 0);
13336
13337   // Get the number of referencing objects.
13338   int count;
13339   HeapIterator heap_iterator(heap);
13340   count = DebugConstructedBy(&heap_iterator,
13341                              *constructor,
13342                              max_references,
13343                              NULL,
13344                              0);
13345
13346   // Allocate an array to hold the result.
13347   Handle<FixedArray> instances = isolate->factory()->NewFixedArray(count);
13348
13349   ASSERT(heap->IsHeapIterable());
13350   // Fill the referencing objects.
13351   HeapIterator heap_iterator2(heap);
13352   count = DebugConstructedBy(&heap_iterator2,
13353                              *constructor,
13354                              max_references,
13355                              *instances,
13356                              count);
13357
13358   // Return result as JS array.
13359   Handle<JSFunction> array_function(
13360       isolate->context()->native_context()->array_function());
13361   Handle<JSObject> result = isolate->factory()->NewJSObject(array_function);
13362   JSArray::SetContent(Handle<JSArray>::cast(result), instances);
13363   return *result;
13364 }
13365
13366
13367 // Find the effective prototype object as returned by __proto__.
13368 // args[0]: the object to find the prototype for.
13369 RUNTIME_FUNCTION(Runtime_DebugGetPrototype) {
13370   HandleScope shs(isolate);
13371   ASSERT(args.length() == 1);
13372   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
13373   return *GetPrototypeSkipHiddenPrototypes(isolate, obj);
13374 }
13375
13376
13377 // Patches script source (should be called upon BeforeCompile event).
13378 RUNTIME_FUNCTION(Runtime_DebugSetScriptSource) {
13379   HandleScope scope(isolate);
13380   ASSERT(args.length() == 2);
13381
13382   CONVERT_ARG_HANDLE_CHECKED(JSValue, script_wrapper, 0);
13383   CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
13384
13385   RUNTIME_ASSERT(script_wrapper->value()->IsScript());
13386   Handle<Script> script(Script::cast(script_wrapper->value()));
13387
13388   int compilation_state = script->compilation_state();
13389   RUNTIME_ASSERT(compilation_state == Script::COMPILATION_STATE_INITIAL);
13390   script->set_source(*source);
13391
13392   return isolate->heap()->undefined_value();
13393 }
13394
13395
13396 RUNTIME_FUNCTION(Runtime_SystemBreak) {
13397   SealHandleScope shs(isolate);
13398   ASSERT(args.length() == 0);
13399   OS::DebugBreak();
13400   return isolate->heap()->undefined_value();
13401 }
13402
13403
13404 RUNTIME_FUNCTION(Runtime_DebugDisassembleFunction) {
13405   HandleScope scope(isolate);
13406 #ifdef DEBUG
13407   ASSERT(args.length() == 1);
13408   // Get the function and make sure it is compiled.
13409   CONVERT_ARG_HANDLE_CHECKED(JSFunction, func, 0);
13410   if (!Compiler::EnsureCompiled(func, KEEP_EXCEPTION)) {
13411     return isolate->heap()->exception();
13412   }
13413   func->code()->PrintLn();
13414 #endif  // DEBUG
13415   return isolate->heap()->undefined_value();
13416 }
13417
13418
13419 RUNTIME_FUNCTION(Runtime_DebugDisassembleConstructor) {
13420   HandleScope scope(isolate);
13421 #ifdef DEBUG
13422   ASSERT(args.length() == 1);
13423   // Get the function and make sure it is compiled.
13424   CONVERT_ARG_HANDLE_CHECKED(JSFunction, func, 0);
13425   if (!Compiler::EnsureCompiled(func, KEEP_EXCEPTION)) {
13426     return isolate->heap()->exception();
13427   }
13428   func->shared()->construct_stub()->PrintLn();
13429 #endif  // DEBUG
13430   return isolate->heap()->undefined_value();
13431 }
13432
13433
13434 RUNTIME_FUNCTION(Runtime_FunctionGetInferredName) {
13435   SealHandleScope shs(isolate);
13436   ASSERT(args.length() == 1);
13437
13438   CONVERT_ARG_CHECKED(JSFunction, f, 0);
13439   return f->shared()->inferred_name();
13440 }
13441
13442
13443 static int FindSharedFunctionInfosForScript(HeapIterator* iterator,
13444                                             Script* script,
13445                                             FixedArray* buffer) {
13446   DisallowHeapAllocation no_allocation;
13447   int counter = 0;
13448   int buffer_size = buffer->length();
13449   for (HeapObject* obj = iterator->next();
13450        obj != NULL;
13451        obj = iterator->next()) {
13452     ASSERT(obj != NULL);
13453     if (!obj->IsSharedFunctionInfo()) {
13454       continue;
13455     }
13456     SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj);
13457     if (shared->script() != script) {
13458       continue;
13459     }
13460     if (counter < buffer_size) {
13461       buffer->set(counter, shared);
13462     }
13463     counter++;
13464   }
13465   return counter;
13466 }
13467
13468
13469 // For a script finds all SharedFunctionInfo's in the heap that points
13470 // to this script. Returns JSArray of SharedFunctionInfo wrapped
13471 // in OpaqueReferences.
13472 RUNTIME_FUNCTION(Runtime_LiveEditFindSharedFunctionInfosForScript) {
13473   HandleScope scope(isolate);
13474   CHECK(isolate->debugger()->live_edit_enabled());
13475   ASSERT(args.length() == 1);
13476   CONVERT_ARG_CHECKED(JSValue, script_value, 0);
13477
13478   RUNTIME_ASSERT(script_value->value()->IsScript());
13479   Handle<Script> script = Handle<Script>(Script::cast(script_value->value()));
13480
13481   const int kBufferSize = 32;
13482
13483   Handle<FixedArray> array;
13484   array = isolate->factory()->NewFixedArray(kBufferSize);
13485   int number;
13486   Heap* heap = isolate->heap();
13487   {
13488     heap->EnsureHeapIsIterable();
13489     DisallowHeapAllocation no_allocation;
13490     HeapIterator heap_iterator(heap);
13491     Script* scr = *script;
13492     FixedArray* arr = *array;
13493     number = FindSharedFunctionInfosForScript(&heap_iterator, scr, arr);
13494   }
13495   if (number > kBufferSize) {
13496     array = isolate->factory()->NewFixedArray(number);
13497     heap->EnsureHeapIsIterable();
13498     DisallowHeapAllocation no_allocation;
13499     HeapIterator heap_iterator(heap);
13500     Script* scr = *script;
13501     FixedArray* arr = *array;
13502     FindSharedFunctionInfosForScript(&heap_iterator, scr, arr);
13503   }
13504
13505   Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements(array);
13506   result->set_length(Smi::FromInt(number));
13507
13508   LiveEdit::WrapSharedFunctionInfos(result);
13509
13510   return *result;
13511 }
13512
13513
13514 // For a script calculates compilation information about all its functions.
13515 // The script source is explicitly specified by the second argument.
13516 // The source of the actual script is not used, however it is important that
13517 // all generated code keeps references to this particular instance of script.
13518 // Returns a JSArray of compilation infos. The array is ordered so that
13519 // each function with all its descendant is always stored in a continues range
13520 // with the function itself going first. The root function is a script function.
13521 RUNTIME_FUNCTION(Runtime_LiveEditGatherCompileInfo) {
13522   HandleScope scope(isolate);
13523   CHECK(isolate->debugger()->live_edit_enabled());
13524   ASSERT(args.length() == 2);
13525   CONVERT_ARG_CHECKED(JSValue, script, 0);
13526   CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
13527
13528   RUNTIME_ASSERT(script->value()->IsScript());
13529   Handle<Script> script_handle = Handle<Script>(Script::cast(script->value()));
13530
13531   Handle<JSArray> result;
13532   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
13533       isolate, result, LiveEdit::GatherCompileInfo(script_handle, source));
13534   return *result;
13535 }
13536
13537
13538 // Changes the source of the script to a new_source.
13539 // If old_script_name is provided (i.e. is a String), also creates a copy of
13540 // the script with its original source and sends notification to debugger.
13541 RUNTIME_FUNCTION(Runtime_LiveEditReplaceScript) {
13542   HandleScope scope(isolate);
13543   CHECK(isolate->debugger()->live_edit_enabled());
13544   ASSERT(args.length() == 3);
13545   CONVERT_ARG_CHECKED(JSValue, original_script_value, 0);
13546   CONVERT_ARG_HANDLE_CHECKED(String, new_source, 1);
13547   CONVERT_ARG_HANDLE_CHECKED(Object, old_script_name, 2);
13548
13549   RUNTIME_ASSERT(original_script_value->value()->IsScript());
13550   Handle<Script> original_script(Script::cast(original_script_value->value()));
13551
13552   Handle<Object> old_script = LiveEdit::ChangeScriptSource(
13553       original_script,  new_source,  old_script_name);
13554
13555   if (old_script->IsScript()) {
13556     Handle<Script> script_handle = Handle<Script>::cast(old_script);
13557     return *Script::GetWrapper(script_handle);
13558   } else {
13559     return isolate->heap()->null_value();
13560   }
13561 }
13562
13563
13564 RUNTIME_FUNCTION(Runtime_LiveEditFunctionSourceUpdated) {
13565   HandleScope scope(isolate);
13566   CHECK(isolate->debugger()->live_edit_enabled());
13567   ASSERT(args.length() == 1);
13568   CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_info, 0);
13569   RUNTIME_ASSERT(SharedInfoWrapper::IsInstance(shared_info));
13570
13571   LiveEdit::FunctionSourceUpdated(shared_info);
13572   return isolate->heap()->undefined_value();
13573 }
13574
13575
13576 // Replaces code of SharedFunctionInfo with a new one.
13577 RUNTIME_FUNCTION(Runtime_LiveEditReplaceFunctionCode) {
13578   HandleScope scope(isolate);
13579   CHECK(isolate->debugger()->live_edit_enabled());
13580   ASSERT(args.length() == 2);
13581   CONVERT_ARG_HANDLE_CHECKED(JSArray, new_compile_info, 0);
13582   CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_info, 1);
13583   RUNTIME_ASSERT(SharedInfoWrapper::IsInstance(shared_info));
13584
13585   LiveEdit::ReplaceFunctionCode(new_compile_info, shared_info);
13586   return isolate->heap()->undefined_value();
13587 }
13588
13589
13590 // Connects SharedFunctionInfo to another script.
13591 RUNTIME_FUNCTION(Runtime_LiveEditFunctionSetScript) {
13592   HandleScope scope(isolate);
13593   CHECK(isolate->debugger()->live_edit_enabled());
13594   ASSERT(args.length() == 2);
13595   CONVERT_ARG_HANDLE_CHECKED(Object, function_object, 0);
13596   CONVERT_ARG_HANDLE_CHECKED(Object, script_object, 1);
13597
13598   if (function_object->IsJSValue()) {
13599     Handle<JSValue> function_wrapper = Handle<JSValue>::cast(function_object);
13600     if (script_object->IsJSValue()) {
13601       RUNTIME_ASSERT(JSValue::cast(*script_object)->value()->IsScript());
13602       Script* script = Script::cast(JSValue::cast(*script_object)->value());
13603       script_object = Handle<Object>(script, isolate);
13604     }
13605
13606     LiveEdit::SetFunctionScript(function_wrapper, script_object);
13607   } else {
13608     // Just ignore this. We may not have a SharedFunctionInfo for some functions
13609     // and we check it in this function.
13610   }
13611
13612   return isolate->heap()->undefined_value();
13613 }
13614
13615
13616 // In a code of a parent function replaces original function as embedded object
13617 // with a substitution one.
13618 RUNTIME_FUNCTION(Runtime_LiveEditReplaceRefToNestedFunction) {
13619   HandleScope scope(isolate);
13620   CHECK(isolate->debugger()->live_edit_enabled());
13621   ASSERT(args.length() == 3);
13622
13623   CONVERT_ARG_HANDLE_CHECKED(JSValue, parent_wrapper, 0);
13624   CONVERT_ARG_HANDLE_CHECKED(JSValue, orig_wrapper, 1);
13625   CONVERT_ARG_HANDLE_CHECKED(JSValue, subst_wrapper, 2);
13626   RUNTIME_ASSERT(parent_wrapper->value()->IsSharedFunctionInfo());
13627   RUNTIME_ASSERT(orig_wrapper->value()->IsSharedFunctionInfo());
13628   RUNTIME_ASSERT(subst_wrapper->value()->IsSharedFunctionInfo());
13629
13630   LiveEdit::ReplaceRefToNestedFunction(
13631       parent_wrapper, orig_wrapper, subst_wrapper);
13632   return isolate->heap()->undefined_value();
13633 }
13634
13635
13636 // Updates positions of a shared function info (first parameter) according
13637 // to script source change. Text change is described in second parameter as
13638 // array of groups of 3 numbers:
13639 // (change_begin, change_end, change_end_new_position).
13640 // Each group describes a change in text; groups are sorted by change_begin.
13641 RUNTIME_FUNCTION(Runtime_LiveEditPatchFunctionPositions) {
13642   HandleScope scope(isolate);
13643   CHECK(isolate->debugger()->live_edit_enabled());
13644   ASSERT(args.length() == 2);
13645   CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_array, 0);
13646   CONVERT_ARG_HANDLE_CHECKED(JSArray, position_change_array, 1);
13647   RUNTIME_ASSERT(SharedInfoWrapper::IsInstance(shared_array))
13648
13649   LiveEdit::PatchFunctionPositions(shared_array, position_change_array);
13650   return isolate->heap()->undefined_value();
13651 }
13652
13653
13654 // For array of SharedFunctionInfo's (each wrapped in JSValue)
13655 // checks that none of them have activations on stacks (of any thread).
13656 // Returns array of the same length with corresponding results of
13657 // LiveEdit::FunctionPatchabilityStatus type.
13658 RUNTIME_FUNCTION(Runtime_LiveEditCheckAndDropActivations) {
13659   HandleScope scope(isolate);
13660   CHECK(isolate->debugger()->live_edit_enabled());
13661   ASSERT(args.length() == 2);
13662   CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_array, 0);
13663   CONVERT_BOOLEAN_ARG_CHECKED(do_drop, 1);
13664   RUNTIME_ASSERT(shared_array->length()->IsSmi());
13665   int array_length = Smi::cast(shared_array->length())->value();
13666   for (int i = 0; i < array_length; i++) {
13667     Handle<Object> element =
13668         Object::GetElement(isolate, shared_array, i).ToHandleChecked();
13669     RUNTIME_ASSERT(
13670         element->IsJSValue() &&
13671         Handle<JSValue>::cast(element)->value()->IsSharedFunctionInfo());
13672   }
13673
13674   return *LiveEdit::CheckAndDropActivations(shared_array, do_drop);
13675 }
13676
13677
13678 // Compares 2 strings line-by-line, then token-wise and returns diff in form
13679 // of JSArray of triplets (pos1, pos1_end, pos2_end) describing list
13680 // of diff chunks.
13681 RUNTIME_FUNCTION(Runtime_LiveEditCompareStrings) {
13682   HandleScope scope(isolate);
13683   CHECK(isolate->debugger()->live_edit_enabled());
13684   ASSERT(args.length() == 2);
13685   CONVERT_ARG_HANDLE_CHECKED(String, s1, 0);
13686   CONVERT_ARG_HANDLE_CHECKED(String, s2, 1);
13687
13688   return *LiveEdit::CompareStrings(s1, s2);
13689 }
13690
13691
13692 // Restarts a call frame and completely drops all frames above.
13693 // Returns true if successful. Otherwise returns undefined or an error message.
13694 RUNTIME_FUNCTION(Runtime_LiveEditRestartFrame) {
13695   HandleScope scope(isolate);
13696   CHECK(isolate->debugger()->live_edit_enabled());
13697   ASSERT(args.length() == 2);
13698   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
13699   RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
13700
13701   CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
13702   Heap* heap = isolate->heap();
13703
13704   // Find the relevant frame with the requested index.
13705   StackFrame::Id id = isolate->debug()->break_frame_id();
13706   if (id == StackFrame::NO_ID) {
13707     // If there are no JavaScript stack frames return undefined.
13708     return heap->undefined_value();
13709   }
13710
13711   int count = 0;
13712   JavaScriptFrameIterator it(isolate, id);
13713   for (; !it.done(); it.Advance()) {
13714     if (index < count + it.frame()->GetInlineCount()) break;
13715     count += it.frame()->GetInlineCount();
13716   }
13717   if (it.done()) return heap->undefined_value();
13718
13719   const char* error_message = LiveEdit::RestartFrame(it.frame());
13720   if (error_message) {
13721     return *(isolate->factory()->InternalizeUtf8String(error_message));
13722   }
13723   return heap->true_value();
13724 }
13725
13726
13727 // A testing entry. Returns statement position which is the closest to
13728 // source_position.
13729 RUNTIME_FUNCTION(Runtime_GetFunctionCodePositionFromSource) {
13730   HandleScope scope(isolate);
13731   CHECK(isolate->debugger()->live_edit_enabled());
13732   ASSERT(args.length() == 2);
13733   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
13734   CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
13735
13736   Handle<Code> code(function->code(), isolate);
13737
13738   if (code->kind() != Code::FUNCTION &&
13739       code->kind() != Code::OPTIMIZED_FUNCTION) {
13740     return isolate->heap()->undefined_value();
13741   }
13742
13743   RelocIterator it(*code, RelocInfo::ModeMask(RelocInfo::STATEMENT_POSITION));
13744   int closest_pc = 0;
13745   int distance = kMaxInt;
13746   while (!it.done()) {
13747     int statement_position = static_cast<int>(it.rinfo()->data());
13748     // Check if this break point is closer that what was previously found.
13749     if (source_position <= statement_position &&
13750         statement_position - source_position < distance) {
13751       closest_pc =
13752           static_cast<int>(it.rinfo()->pc() - code->instruction_start());
13753       distance = statement_position - source_position;
13754       // Check whether we can't get any closer.
13755       if (distance == 0) break;
13756     }
13757     it.next();
13758   }
13759
13760   return Smi::FromInt(closest_pc);
13761 }
13762
13763
13764 // Calls specified function with or without entering the debugger.
13765 // This is used in unit tests to run code as if debugger is entered or simply
13766 // to have a stack with C++ frame in the middle.
13767 RUNTIME_FUNCTION(Runtime_ExecuteInDebugContext) {
13768   HandleScope scope(isolate);
13769   ASSERT(args.length() == 2);
13770   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
13771   CONVERT_BOOLEAN_ARG_CHECKED(without_debugger, 1);
13772
13773   MaybeHandle<Object> maybe_result;
13774   if (without_debugger) {
13775     maybe_result = Execution::Call(isolate,
13776                                    function,
13777                                    isolate->global_object(),
13778                                    0,
13779                                    NULL);
13780   } else {
13781     EnterDebugger enter_debugger(isolate);
13782     maybe_result = Execution::Call(isolate,
13783                                    function,
13784                                    isolate->global_object(),
13785                                    0,
13786                                    NULL);
13787   }
13788   Handle<Object> result;
13789   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, maybe_result);
13790   return *result;
13791 }
13792
13793
13794 // Sets a v8 flag.
13795 RUNTIME_FUNCTION(Runtime_SetFlags) {
13796   SealHandleScope shs(isolate);
13797   ASSERT(args.length() == 1);
13798   CONVERT_ARG_CHECKED(String, arg, 0);
13799   SmartArrayPointer<char> flags =
13800       arg->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
13801   FlagList::SetFlagsFromString(flags.get(), StrLength(flags.get()));
13802   return isolate->heap()->undefined_value();
13803 }
13804
13805
13806 // Performs a GC.
13807 // Presently, it only does a full GC.
13808 RUNTIME_FUNCTION(Runtime_CollectGarbage) {
13809   SealHandleScope shs(isolate);
13810   ASSERT(args.length() == 1);
13811   isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, "%CollectGarbage");
13812   return isolate->heap()->undefined_value();
13813 }
13814
13815
13816 // Gets the current heap usage.
13817 RUNTIME_FUNCTION(Runtime_GetHeapUsage) {
13818   SealHandleScope shs(isolate);
13819   ASSERT(args.length() == 0);
13820   int usage = static_cast<int>(isolate->heap()->SizeOfObjects());
13821   if (!Smi::IsValid(usage)) {
13822     return *isolate->factory()->NewNumberFromInt(usage);
13823   }
13824   return Smi::FromInt(usage);
13825 }
13826
13827
13828 #ifdef V8_I18N_SUPPORT
13829 RUNTIME_FUNCTION(Runtime_CanonicalizeLanguageTag) {
13830   HandleScope scope(isolate);
13831   Factory* factory = isolate->factory();
13832
13833   ASSERT(args.length() == 1);
13834   CONVERT_ARG_HANDLE_CHECKED(String, locale_id_str, 0);
13835
13836   v8::String::Utf8Value locale_id(v8::Utils::ToLocal(locale_id_str));
13837
13838   // Return value which denotes invalid language tag.
13839   const char* const kInvalidTag = "invalid-tag";
13840
13841   UErrorCode error = U_ZERO_ERROR;
13842   char icu_result[ULOC_FULLNAME_CAPACITY];
13843   int icu_length = 0;
13844
13845   uloc_forLanguageTag(*locale_id, icu_result, ULOC_FULLNAME_CAPACITY,
13846                       &icu_length, &error);
13847   if (U_FAILURE(error) || icu_length == 0) {
13848     return *factory->NewStringFromAsciiChecked(kInvalidTag);
13849   }
13850
13851   char result[ULOC_FULLNAME_CAPACITY];
13852
13853   // Force strict BCP47 rules.
13854   uloc_toLanguageTag(icu_result, result, ULOC_FULLNAME_CAPACITY, TRUE, &error);
13855
13856   if (U_FAILURE(error)) {
13857     return *factory->NewStringFromAsciiChecked(kInvalidTag);
13858   }
13859
13860   return *factory->NewStringFromAsciiChecked(result);
13861 }
13862
13863
13864 RUNTIME_FUNCTION(Runtime_AvailableLocalesOf) {
13865   HandleScope scope(isolate);
13866   Factory* factory = isolate->factory();
13867
13868   ASSERT(args.length() == 1);
13869   CONVERT_ARG_HANDLE_CHECKED(String, service, 0);
13870
13871   const icu::Locale* available_locales = NULL;
13872   int32_t count = 0;
13873
13874   if (service->IsUtf8EqualTo(CStrVector("collator"))) {
13875     available_locales = icu::Collator::getAvailableLocales(count);
13876   } else if (service->IsUtf8EqualTo(CStrVector("numberformat"))) {
13877     available_locales = icu::NumberFormat::getAvailableLocales(count);
13878   } else if (service->IsUtf8EqualTo(CStrVector("dateformat"))) {
13879     available_locales = icu::DateFormat::getAvailableLocales(count);
13880   } else if (service->IsUtf8EqualTo(CStrVector("breakiterator"))) {
13881     available_locales = icu::BreakIterator::getAvailableLocales(count);
13882   }
13883
13884   UErrorCode error = U_ZERO_ERROR;
13885   char result[ULOC_FULLNAME_CAPACITY];
13886   Handle<JSObject> locales =
13887       factory->NewJSObject(isolate->object_function());
13888
13889   for (int32_t i = 0; i < count; ++i) {
13890     const char* icu_name = available_locales[i].getName();
13891
13892     error = U_ZERO_ERROR;
13893     // No need to force strict BCP47 rules.
13894     uloc_toLanguageTag(icu_name, result, ULOC_FULLNAME_CAPACITY, FALSE, &error);
13895     if (U_FAILURE(error)) {
13896       // This shouldn't happen, but lets not break the user.
13897       continue;
13898     }
13899
13900     RETURN_FAILURE_ON_EXCEPTION(isolate,
13901         JSObject::SetLocalPropertyIgnoreAttributes(
13902             locales,
13903             factory->NewStringFromAsciiChecked(result),
13904             factory->NewNumber(i),
13905             NONE));
13906   }
13907
13908   return *locales;
13909 }
13910
13911
13912 RUNTIME_FUNCTION(Runtime_GetDefaultICULocale) {
13913   HandleScope scope(isolate);
13914   Factory* factory = isolate->factory();
13915
13916   ASSERT(args.length() == 0);
13917
13918   icu::Locale default_locale;
13919
13920   // Set the locale
13921   char result[ULOC_FULLNAME_CAPACITY];
13922   UErrorCode status = U_ZERO_ERROR;
13923   uloc_toLanguageTag(
13924       default_locale.getName(), result, ULOC_FULLNAME_CAPACITY, FALSE, &status);
13925   if (U_SUCCESS(status)) {
13926     return *factory->NewStringFromAsciiChecked(result);
13927   }
13928
13929   return *factory->NewStringFromStaticAscii("und");
13930 }
13931
13932
13933 RUNTIME_FUNCTION(Runtime_GetLanguageTagVariants) {
13934   HandleScope scope(isolate);
13935   Factory* factory = isolate->factory();
13936
13937   ASSERT(args.length() == 1);
13938
13939   CONVERT_ARG_HANDLE_CHECKED(JSArray, input, 0);
13940
13941   uint32_t length = static_cast<uint32_t>(input->length()->Number());
13942   // Set some limit to prevent fuzz tests from going OOM.
13943   // Can be bumped when callers' requirements change.
13944   RUNTIME_ASSERT(length < 100);
13945   Handle<FixedArray> output = factory->NewFixedArray(length);
13946   Handle<Name> maximized = factory->NewStringFromStaticAscii("maximized");
13947   Handle<Name> base = factory->NewStringFromStaticAscii("base");
13948   for (unsigned int i = 0; i < length; ++i) {
13949     Handle<Object> locale_id;
13950     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
13951         isolate, locale_id, Object::GetElement(isolate, input, i));
13952     if (!locale_id->IsString()) {
13953       return isolate->Throw(*factory->illegal_argument_string());
13954     }
13955
13956     v8::String::Utf8Value utf8_locale_id(
13957         v8::Utils::ToLocal(Handle<String>::cast(locale_id)));
13958
13959     UErrorCode error = U_ZERO_ERROR;
13960
13961     // Convert from BCP47 to ICU format.
13962     // de-DE-u-co-phonebk -> de_DE@collation=phonebook
13963     char icu_locale[ULOC_FULLNAME_CAPACITY];
13964     int icu_locale_length = 0;
13965     uloc_forLanguageTag(*utf8_locale_id, icu_locale, ULOC_FULLNAME_CAPACITY,
13966                         &icu_locale_length, &error);
13967     if (U_FAILURE(error) || icu_locale_length == 0) {
13968       return isolate->Throw(*factory->illegal_argument_string());
13969     }
13970
13971     // Maximize the locale.
13972     // de_DE@collation=phonebook -> de_Latn_DE@collation=phonebook
13973     char icu_max_locale[ULOC_FULLNAME_CAPACITY];
13974     uloc_addLikelySubtags(
13975         icu_locale, icu_max_locale, ULOC_FULLNAME_CAPACITY, &error);
13976
13977     // Remove extensions from maximized locale.
13978     // de_Latn_DE@collation=phonebook -> de_Latn_DE
13979     char icu_base_max_locale[ULOC_FULLNAME_CAPACITY];
13980     uloc_getBaseName(
13981         icu_max_locale, icu_base_max_locale, ULOC_FULLNAME_CAPACITY, &error);
13982
13983     // Get original name without extensions.
13984     // de_DE@collation=phonebook -> de_DE
13985     char icu_base_locale[ULOC_FULLNAME_CAPACITY];
13986     uloc_getBaseName(
13987         icu_locale, icu_base_locale, ULOC_FULLNAME_CAPACITY, &error);
13988
13989     // Convert from ICU locale format to BCP47 format.
13990     // de_Latn_DE -> de-Latn-DE
13991     char base_max_locale[ULOC_FULLNAME_CAPACITY];
13992     uloc_toLanguageTag(icu_base_max_locale, base_max_locale,
13993                        ULOC_FULLNAME_CAPACITY, FALSE, &error);
13994
13995     // de_DE -> de-DE
13996     char base_locale[ULOC_FULLNAME_CAPACITY];
13997     uloc_toLanguageTag(
13998         icu_base_locale, base_locale, ULOC_FULLNAME_CAPACITY, FALSE, &error);
13999
14000     if (U_FAILURE(error)) {
14001       return isolate->Throw(*factory->illegal_argument_string());
14002     }
14003
14004     Handle<JSObject> result = factory->NewJSObject(isolate->object_function());
14005     RETURN_FAILURE_ON_EXCEPTION(isolate,
14006         JSObject::SetLocalPropertyIgnoreAttributes(
14007             result,
14008             maximized,
14009             factory->NewStringFromAsciiChecked(base_max_locale),
14010             NONE));
14011     RETURN_FAILURE_ON_EXCEPTION(isolate,
14012         JSObject::SetLocalPropertyIgnoreAttributes(
14013             result,
14014             base,
14015             factory->NewStringFromAsciiChecked(base_locale),
14016             NONE));
14017     output->set(i, *result);
14018   }
14019
14020   Handle<JSArray> result = factory->NewJSArrayWithElements(output);
14021   result->set_length(Smi::FromInt(length));
14022   return *result;
14023 }
14024
14025
14026 RUNTIME_FUNCTION(Runtime_IsInitializedIntlObject) {
14027   HandleScope scope(isolate);
14028
14029   ASSERT(args.length() == 1);
14030
14031   CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
14032
14033   if (!input->IsJSObject()) return isolate->heap()->false_value();
14034   Handle<JSObject> obj = Handle<JSObject>::cast(input);
14035
14036   Handle<String> marker = isolate->factory()->intl_initialized_marker_string();
14037   Handle<Object> tag(obj->GetHiddenProperty(marker), isolate);
14038   return isolate->heap()->ToBoolean(!tag->IsTheHole());
14039 }
14040
14041
14042 RUNTIME_FUNCTION(Runtime_IsInitializedIntlObjectOfType) {
14043   HandleScope scope(isolate);
14044
14045   ASSERT(args.length() == 2);
14046
14047   CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
14048   CONVERT_ARG_HANDLE_CHECKED(String, expected_type, 1);
14049
14050   if (!input->IsJSObject()) return isolate->heap()->false_value();
14051   Handle<JSObject> obj = Handle<JSObject>::cast(input);
14052
14053   Handle<String> marker = isolate->factory()->intl_initialized_marker_string();
14054   Handle<Object> tag(obj->GetHiddenProperty(marker), isolate);
14055   return isolate->heap()->ToBoolean(
14056       tag->IsString() && String::cast(*tag)->Equals(*expected_type));
14057 }
14058
14059
14060 RUNTIME_FUNCTION(Runtime_MarkAsInitializedIntlObjectOfType) {
14061   HandleScope scope(isolate);
14062
14063   ASSERT(args.length() == 3);
14064
14065   CONVERT_ARG_HANDLE_CHECKED(JSObject, input, 0);
14066   CONVERT_ARG_HANDLE_CHECKED(String, type, 1);
14067   CONVERT_ARG_HANDLE_CHECKED(JSObject, impl, 2);
14068
14069   Handle<String> marker = isolate->factory()->intl_initialized_marker_string();
14070   JSObject::SetHiddenProperty(input, marker, type);
14071
14072   marker = isolate->factory()->intl_impl_object_string();
14073   JSObject::SetHiddenProperty(input, marker, impl);
14074
14075   return isolate->heap()->undefined_value();
14076 }
14077
14078
14079 RUNTIME_FUNCTION(Runtime_GetImplFromInitializedIntlObject) {
14080   HandleScope scope(isolate);
14081
14082   ASSERT(args.length() == 1);
14083
14084   CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
14085
14086   if (!input->IsJSObject()) {
14087     Vector< Handle<Object> > arguments = HandleVector(&input, 1);
14088     Handle<Object> type_error =
14089         isolate->factory()->NewTypeError("not_intl_object", arguments);
14090     return isolate->Throw(*type_error);
14091   }
14092
14093   Handle<JSObject> obj = Handle<JSObject>::cast(input);
14094
14095   Handle<String> marker = isolate->factory()->intl_impl_object_string();
14096   Handle<Object> impl(obj->GetHiddenProperty(marker), isolate);
14097   if (impl->IsTheHole()) {
14098     Vector< Handle<Object> > arguments = HandleVector(&obj, 1);
14099     Handle<Object> type_error =
14100         isolate->factory()->NewTypeError("not_intl_object", arguments);
14101     return isolate->Throw(*type_error);
14102   }
14103   return *impl;
14104 }
14105
14106
14107 RUNTIME_FUNCTION(Runtime_CreateDateTimeFormat) {
14108   HandleScope scope(isolate);
14109
14110   ASSERT(args.length() == 3);
14111
14112   CONVERT_ARG_HANDLE_CHECKED(String, locale, 0);
14113   CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1);
14114   CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2);
14115
14116   Handle<ObjectTemplateInfo> date_format_template =
14117       I18N::GetTemplate(isolate);
14118
14119   // Create an empty object wrapper.
14120   Handle<JSObject> local_object;
14121   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
14122       isolate, local_object,
14123       Execution::InstantiateObject(date_format_template));
14124
14125   // Set date time formatter as internal field of the resulting JS object.
14126   icu::SimpleDateFormat* date_format = DateFormat::InitializeDateTimeFormat(
14127       isolate, locale, options, resolved);
14128
14129   if (!date_format) return isolate->ThrowIllegalOperation();
14130
14131   local_object->SetInternalField(0, reinterpret_cast<Smi*>(date_format));
14132
14133   RETURN_FAILURE_ON_EXCEPTION(isolate,
14134       JSObject::SetLocalPropertyIgnoreAttributes(
14135           local_object,
14136           isolate->factory()->NewStringFromStaticAscii("dateFormat"),
14137           isolate->factory()->NewStringFromStaticAscii("valid"),
14138           NONE));
14139
14140   // Make object handle weak so we can delete the data format once GC kicks in.
14141   Handle<Object> wrapper = isolate->global_handles()->Create(*local_object);
14142   GlobalHandles::MakeWeak(wrapper.location(),
14143                           reinterpret_cast<void*>(wrapper.location()),
14144                           DateFormat::DeleteDateFormat);
14145   return *local_object;
14146 }
14147
14148
14149 RUNTIME_FUNCTION(Runtime_InternalDateFormat) {
14150   HandleScope scope(isolate);
14151
14152   ASSERT(args.length() == 2);
14153
14154   CONVERT_ARG_HANDLE_CHECKED(JSObject, date_format_holder, 0);
14155   CONVERT_ARG_HANDLE_CHECKED(JSDate, date, 1);
14156
14157   Handle<Object> value;
14158   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
14159       isolate, value, Execution::ToNumber(isolate, date));
14160
14161   icu::SimpleDateFormat* date_format =
14162       DateFormat::UnpackDateFormat(isolate, date_format_holder);
14163   if (!date_format) return isolate->ThrowIllegalOperation();
14164
14165   icu::UnicodeString result;
14166   date_format->format(value->Number(), result);
14167
14168   Handle<String> result_str;
14169   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
14170       isolate, result_str,
14171       isolate->factory()->NewStringFromTwoByte(
14172           Vector<const uint16_t>(
14173               reinterpret_cast<const uint16_t*>(result.getBuffer()),
14174               result.length())));
14175   return *result_str;
14176 }
14177
14178
14179 RUNTIME_FUNCTION(Runtime_InternalDateParse) {
14180   HandleScope scope(isolate);
14181
14182   ASSERT(args.length() == 2);
14183
14184   CONVERT_ARG_HANDLE_CHECKED(JSObject, date_format_holder, 0);
14185   CONVERT_ARG_HANDLE_CHECKED(String, date_string, 1);
14186
14187   v8::String::Utf8Value utf8_date(v8::Utils::ToLocal(date_string));
14188   icu::UnicodeString u_date(icu::UnicodeString::fromUTF8(*utf8_date));
14189   icu::SimpleDateFormat* date_format =
14190       DateFormat::UnpackDateFormat(isolate, date_format_holder);
14191   if (!date_format) return isolate->ThrowIllegalOperation();
14192
14193   UErrorCode status = U_ZERO_ERROR;
14194   UDate date = date_format->parse(u_date, status);
14195   if (U_FAILURE(status)) return isolate->heap()->undefined_value();
14196
14197   Handle<Object> result;
14198   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
14199       isolate, result,
14200       Execution::NewDate(isolate, static_cast<double>(date)));
14201   ASSERT(result->IsJSDate());
14202   return *result;
14203 }
14204
14205
14206 RUNTIME_FUNCTION(Runtime_CreateNumberFormat) {
14207   HandleScope scope(isolate);
14208
14209   ASSERT(args.length() == 3);
14210
14211   CONVERT_ARG_HANDLE_CHECKED(String, locale, 0);
14212   CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1);
14213   CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2);
14214
14215   Handle<ObjectTemplateInfo> number_format_template =
14216       I18N::GetTemplate(isolate);
14217
14218   // Create an empty object wrapper.
14219   Handle<JSObject> local_object;
14220   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
14221       isolate, local_object,
14222       Execution::InstantiateObject(number_format_template));
14223
14224   // Set number formatter as internal field of the resulting JS object.
14225   icu::DecimalFormat* number_format = NumberFormat::InitializeNumberFormat(
14226       isolate, locale, options, resolved);
14227
14228   if (!number_format) return isolate->ThrowIllegalOperation();
14229
14230   local_object->SetInternalField(0, reinterpret_cast<Smi*>(number_format));
14231
14232   RETURN_FAILURE_ON_EXCEPTION(isolate,
14233       JSObject::SetLocalPropertyIgnoreAttributes(
14234           local_object,
14235           isolate->factory()->NewStringFromStaticAscii("numberFormat"),
14236           isolate->factory()->NewStringFromStaticAscii("valid"),
14237           NONE));
14238
14239   Handle<Object> wrapper = isolate->global_handles()->Create(*local_object);
14240   GlobalHandles::MakeWeak(wrapper.location(),
14241                           reinterpret_cast<void*>(wrapper.location()),
14242                           NumberFormat::DeleteNumberFormat);
14243   return *local_object;
14244 }
14245
14246
14247 RUNTIME_FUNCTION(Runtime_InternalNumberFormat) {
14248   HandleScope scope(isolate);
14249
14250   ASSERT(args.length() == 2);
14251
14252   CONVERT_ARG_HANDLE_CHECKED(JSObject, number_format_holder, 0);
14253   CONVERT_ARG_HANDLE_CHECKED(Object, number, 1);
14254
14255   Handle<Object> value;
14256   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
14257       isolate, value, Execution::ToNumber(isolate, number));
14258
14259   icu::DecimalFormat* number_format =
14260       NumberFormat::UnpackNumberFormat(isolate, number_format_holder);
14261   if (!number_format) return isolate->ThrowIllegalOperation();
14262
14263   icu::UnicodeString result;
14264   number_format->format(value->Number(), result);
14265
14266   Handle<String> result_str;
14267   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
14268       isolate, result_str,
14269       isolate->factory()->NewStringFromTwoByte(
14270           Vector<const uint16_t>(
14271               reinterpret_cast<const uint16_t*>(result.getBuffer()),
14272               result.length())));
14273   return *result_str;
14274 }
14275
14276
14277 RUNTIME_FUNCTION(Runtime_InternalNumberParse) {
14278   HandleScope scope(isolate);
14279
14280   ASSERT(args.length() == 2);
14281
14282   CONVERT_ARG_HANDLE_CHECKED(JSObject, number_format_holder, 0);
14283   CONVERT_ARG_HANDLE_CHECKED(String, number_string, 1);
14284
14285   v8::String::Utf8Value utf8_number(v8::Utils::ToLocal(number_string));
14286   icu::UnicodeString u_number(icu::UnicodeString::fromUTF8(*utf8_number));
14287   icu::DecimalFormat* number_format =
14288       NumberFormat::UnpackNumberFormat(isolate, number_format_holder);
14289   if (!number_format) return isolate->ThrowIllegalOperation();
14290
14291   UErrorCode status = U_ZERO_ERROR;
14292   icu::Formattable result;
14293   // ICU 4.6 doesn't support parseCurrency call. We need to wait for ICU49
14294   // to be part of Chrome.
14295   // TODO(cira): Include currency parsing code using parseCurrency call.
14296   // We need to check if the formatter parses all currencies or only the
14297   // one it was constructed with (it will impact the API - how to return ISO
14298   // code and the value).
14299   number_format->parse(u_number, result, status);
14300   if (U_FAILURE(status)) return isolate->heap()->undefined_value();
14301
14302   switch (result.getType()) {
14303   case icu::Formattable::kDouble:
14304     return *isolate->factory()->NewNumber(result.getDouble());
14305   case icu::Formattable::kLong:
14306     return *isolate->factory()->NewNumberFromInt(result.getLong());
14307   case icu::Formattable::kInt64:
14308     return *isolate->factory()->NewNumber(
14309         static_cast<double>(result.getInt64()));
14310   default:
14311     return isolate->heap()->undefined_value();
14312   }
14313 }
14314
14315
14316 RUNTIME_FUNCTION(Runtime_CreateCollator) {
14317   HandleScope scope(isolate);
14318
14319   ASSERT(args.length() == 3);
14320
14321   CONVERT_ARG_HANDLE_CHECKED(String, locale, 0);
14322   CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1);
14323   CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2);
14324
14325   Handle<ObjectTemplateInfo> collator_template = I18N::GetTemplate(isolate);
14326
14327   // Create an empty object wrapper.
14328   Handle<JSObject> local_object;
14329   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
14330       isolate, local_object, Execution::InstantiateObject(collator_template));
14331
14332   // Set collator as internal field of the resulting JS object.
14333   icu::Collator* collator = Collator::InitializeCollator(
14334       isolate, locale, options, resolved);
14335
14336   if (!collator) return isolate->ThrowIllegalOperation();
14337
14338   local_object->SetInternalField(0, reinterpret_cast<Smi*>(collator));
14339
14340   RETURN_FAILURE_ON_EXCEPTION(isolate,
14341       JSObject::SetLocalPropertyIgnoreAttributes(
14342           local_object,
14343           isolate->factory()->NewStringFromStaticAscii("collator"),
14344           isolate->factory()->NewStringFromStaticAscii("valid"),
14345           NONE));
14346
14347   Handle<Object> wrapper = isolate->global_handles()->Create(*local_object);
14348   GlobalHandles::MakeWeak(wrapper.location(),
14349                           reinterpret_cast<void*>(wrapper.location()),
14350                           Collator::DeleteCollator);
14351   return *local_object;
14352 }
14353
14354
14355 RUNTIME_FUNCTION(Runtime_InternalCompare) {
14356   HandleScope scope(isolate);
14357
14358   ASSERT(args.length() == 3);
14359
14360   CONVERT_ARG_HANDLE_CHECKED(JSObject, collator_holder, 0);
14361   CONVERT_ARG_HANDLE_CHECKED(String, string1, 1);
14362   CONVERT_ARG_HANDLE_CHECKED(String, string2, 2);
14363
14364   icu::Collator* collator = Collator::UnpackCollator(isolate, collator_holder);
14365   if (!collator) return isolate->ThrowIllegalOperation();
14366
14367   v8::String::Value string_value1(v8::Utils::ToLocal(string1));
14368   v8::String::Value string_value2(v8::Utils::ToLocal(string2));
14369   const UChar* u_string1 = reinterpret_cast<const UChar*>(*string_value1);
14370   const UChar* u_string2 = reinterpret_cast<const UChar*>(*string_value2);
14371   UErrorCode status = U_ZERO_ERROR;
14372   UCollationResult result = collator->compare(u_string1,
14373                                               string_value1.length(),
14374                                               u_string2,
14375                                               string_value2.length(),
14376                                               status);
14377   if (U_FAILURE(status)) return isolate->ThrowIllegalOperation();
14378
14379   return *isolate->factory()->NewNumberFromInt(result);
14380 }
14381
14382
14383 RUNTIME_FUNCTION(Runtime_StringNormalize) {
14384   HandleScope scope(isolate);
14385   static const UNormalizationMode normalizationForms[] =
14386       { UNORM_NFC, UNORM_NFD, UNORM_NFKC, UNORM_NFKD };
14387
14388   ASSERT(args.length() == 2);
14389
14390   CONVERT_ARG_HANDLE_CHECKED(String, stringValue, 0);
14391   CONVERT_NUMBER_CHECKED(int, form_id, Int32, args[1]);
14392   RUNTIME_ASSERT(form_id >= 0 &&
14393                  static_cast<size_t>(form_id) < ARRAY_SIZE(normalizationForms));
14394
14395   v8::String::Value string_value(v8::Utils::ToLocal(stringValue));
14396   const UChar* u_value = reinterpret_cast<const UChar*>(*string_value);
14397
14398   // TODO(mnita): check Normalizer2 (not available in ICU 46)
14399   UErrorCode status = U_ZERO_ERROR;
14400   icu::UnicodeString result;
14401   icu::Normalizer::normalize(u_value, normalizationForms[form_id], 0,
14402       result, status);
14403   if (U_FAILURE(status)) {
14404     return isolate->heap()->undefined_value();
14405   }
14406
14407   Handle<String> result_str;
14408   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
14409       isolate, result_str,
14410       isolate->factory()->NewStringFromTwoByte(
14411           Vector<const uint16_t>(
14412               reinterpret_cast<const uint16_t*>(result.getBuffer()),
14413               result.length())));
14414   return *result_str;
14415 }
14416
14417
14418 RUNTIME_FUNCTION(Runtime_CreateBreakIterator) {
14419   HandleScope scope(isolate);
14420
14421   ASSERT(args.length() == 3);
14422
14423   CONVERT_ARG_HANDLE_CHECKED(String, locale, 0);
14424   CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1);
14425   CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2);
14426
14427   Handle<ObjectTemplateInfo> break_iterator_template =
14428       I18N::GetTemplate2(isolate);
14429
14430   // Create an empty object wrapper.
14431   Handle<JSObject> local_object;
14432   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
14433       isolate, local_object,
14434       Execution::InstantiateObject(break_iterator_template));
14435
14436   // Set break iterator as internal field of the resulting JS object.
14437   icu::BreakIterator* break_iterator = BreakIterator::InitializeBreakIterator(
14438       isolate, locale, options, resolved);
14439
14440   if (!break_iterator) return isolate->ThrowIllegalOperation();
14441
14442   local_object->SetInternalField(0, reinterpret_cast<Smi*>(break_iterator));
14443   // Make sure that the pointer to adopted text is NULL.
14444   local_object->SetInternalField(1, reinterpret_cast<Smi*>(NULL));
14445
14446   RETURN_FAILURE_ON_EXCEPTION(isolate,
14447       JSObject::SetLocalPropertyIgnoreAttributes(
14448           local_object,
14449           isolate->factory()->NewStringFromStaticAscii("breakIterator"),
14450           isolate->factory()->NewStringFromStaticAscii("valid"),
14451           NONE));
14452
14453   // Make object handle weak so we can delete the break iterator once GC kicks
14454   // in.
14455   Handle<Object> wrapper = isolate->global_handles()->Create(*local_object);
14456   GlobalHandles::MakeWeak(wrapper.location(),
14457                           reinterpret_cast<void*>(wrapper.location()),
14458                           BreakIterator::DeleteBreakIterator);
14459   return *local_object;
14460 }
14461
14462
14463 RUNTIME_FUNCTION(Runtime_BreakIteratorAdoptText) {
14464   HandleScope scope(isolate);
14465
14466   ASSERT(args.length() == 2);
14467
14468   CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
14469   CONVERT_ARG_HANDLE_CHECKED(String, text, 1);
14470
14471   icu::BreakIterator* break_iterator =
14472       BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder);
14473   if (!break_iterator) return isolate->ThrowIllegalOperation();
14474
14475   icu::UnicodeString* u_text = reinterpret_cast<icu::UnicodeString*>(
14476       break_iterator_holder->GetInternalField(1));
14477   delete u_text;
14478
14479   v8::String::Value text_value(v8::Utils::ToLocal(text));
14480   u_text = new icu::UnicodeString(
14481       reinterpret_cast<const UChar*>(*text_value), text_value.length());
14482   break_iterator_holder->SetInternalField(1, reinterpret_cast<Smi*>(u_text));
14483
14484   break_iterator->setText(*u_text);
14485
14486   return isolate->heap()->undefined_value();
14487 }
14488
14489
14490 RUNTIME_FUNCTION(Runtime_BreakIteratorFirst) {
14491   HandleScope scope(isolate);
14492
14493   ASSERT(args.length() == 1);
14494
14495   CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
14496
14497   icu::BreakIterator* break_iterator =
14498       BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder);
14499   if (!break_iterator) return isolate->ThrowIllegalOperation();
14500
14501   return *isolate->factory()->NewNumberFromInt(break_iterator->first());
14502 }
14503
14504
14505 RUNTIME_FUNCTION(Runtime_BreakIteratorNext) {
14506   HandleScope scope(isolate);
14507
14508   ASSERT(args.length() == 1);
14509
14510   CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
14511
14512   icu::BreakIterator* break_iterator =
14513       BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder);
14514   if (!break_iterator) return isolate->ThrowIllegalOperation();
14515
14516   return *isolate->factory()->NewNumberFromInt(break_iterator->next());
14517 }
14518
14519
14520 RUNTIME_FUNCTION(Runtime_BreakIteratorCurrent) {
14521   HandleScope scope(isolate);
14522
14523   ASSERT(args.length() == 1);
14524
14525   CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
14526
14527   icu::BreakIterator* break_iterator =
14528       BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder);
14529   if (!break_iterator) return isolate->ThrowIllegalOperation();
14530
14531   return *isolate->factory()->NewNumberFromInt(break_iterator->current());
14532 }
14533
14534
14535 RUNTIME_FUNCTION(Runtime_BreakIteratorBreakType) {
14536   HandleScope scope(isolate);
14537
14538   ASSERT(args.length() == 1);
14539
14540   CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
14541
14542   icu::BreakIterator* break_iterator =
14543       BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder);
14544   if (!break_iterator) return isolate->ThrowIllegalOperation();
14545
14546   // TODO(cira): Remove cast once ICU fixes base BreakIterator class.
14547   icu::RuleBasedBreakIterator* rule_based_iterator =
14548       static_cast<icu::RuleBasedBreakIterator*>(break_iterator);
14549   int32_t status = rule_based_iterator->getRuleStatus();
14550   // Keep return values in sync with JavaScript BreakType enum.
14551   if (status >= UBRK_WORD_NONE && status < UBRK_WORD_NONE_LIMIT) {
14552     return *isolate->factory()->NewStringFromStaticAscii("none");
14553   } else if (status >= UBRK_WORD_NUMBER && status < UBRK_WORD_NUMBER_LIMIT) {
14554     return *isolate->factory()->NewStringFromStaticAscii("number");
14555   } else if (status >= UBRK_WORD_LETTER && status < UBRK_WORD_LETTER_LIMIT) {
14556     return *isolate->factory()->NewStringFromStaticAscii("letter");
14557   } else if (status >= UBRK_WORD_KANA && status < UBRK_WORD_KANA_LIMIT) {
14558     return *isolate->factory()->NewStringFromStaticAscii("kana");
14559   } else if (status >= UBRK_WORD_IDEO && status < UBRK_WORD_IDEO_LIMIT) {
14560     return *isolate->factory()->NewStringFromStaticAscii("ideo");
14561   } else {
14562     return *isolate->factory()->NewStringFromStaticAscii("unknown");
14563   }
14564 }
14565 #endif  // V8_I18N_SUPPORT
14566
14567
14568 // Finds the script object from the script data. NOTE: This operation uses
14569 // heap traversal to find the function generated for the source position
14570 // for the requested break point. For lazily compiled functions several heap
14571 // traversals might be required rendering this operation as a rather slow
14572 // operation. However for setting break points which is normally done through
14573 // some kind of user interaction the performance is not crucial.
14574 static Handle<Object> Runtime_GetScriptFromScriptName(
14575     Handle<String> script_name) {
14576   // Scan the heap for Script objects to find the script with the requested
14577   // script data.
14578   Handle<Script> script;
14579   Factory* factory = script_name->GetIsolate()->factory();
14580   Heap* heap = script_name->GetHeap();
14581   heap->EnsureHeapIsIterable();
14582   DisallowHeapAllocation no_allocation_during_heap_iteration;
14583   HeapIterator iterator(heap);
14584   HeapObject* obj = NULL;
14585   while (script.is_null() && ((obj = iterator.next()) != NULL)) {
14586     // If a script is found check if it has the script data requested.
14587     if (obj->IsScript()) {
14588       if (Script::cast(obj)->name()->IsString()) {
14589         if (String::cast(Script::cast(obj)->name())->Equals(*script_name)) {
14590           script = Handle<Script>(Script::cast(obj));
14591         }
14592       }
14593     }
14594   }
14595
14596   // If no script with the requested script data is found return undefined.
14597   if (script.is_null()) return factory->undefined_value();
14598
14599   // Return the script found.
14600   return Script::GetWrapper(script);
14601 }
14602
14603
14604 // Get the script object from script data. NOTE: Regarding performance
14605 // see the NOTE for GetScriptFromScriptData.
14606 // args[0]: script data for the script to find the source for
14607 RUNTIME_FUNCTION(Runtime_GetScript) {
14608   HandleScope scope(isolate);
14609
14610   ASSERT(args.length() == 1);
14611
14612   CONVERT_ARG_CHECKED(String, script_name, 0);
14613
14614   // Find the requested script.
14615   Handle<Object> result =
14616       Runtime_GetScriptFromScriptName(Handle<String>(script_name));
14617   return *result;
14618 }
14619
14620
14621 // Collect the raw data for a stack trace.  Returns an array of 4
14622 // element segments each containing a receiver, function, code and
14623 // native code offset.
14624 RUNTIME_FUNCTION(Runtime_CollectStackTrace) {
14625   HandleScope scope(isolate);
14626   ASSERT(args.length() == 3);
14627   CONVERT_ARG_HANDLE_CHECKED(JSObject, error_object, 0);
14628   CONVERT_ARG_HANDLE_CHECKED(Object, caller, 1);
14629   CONVERT_NUMBER_CHECKED(int32_t, limit, Int32, args[2]);
14630
14631   // Optionally capture a more detailed stack trace for the message.
14632   isolate->CaptureAndSetDetailedStackTrace(error_object);
14633   // Capture a simple stack trace for the stack property.
14634   return *isolate->CaptureSimpleStackTrace(error_object, caller, limit);
14635 }
14636
14637
14638 // Retrieve the stack trace.  This is the raw stack trace that yet has to
14639 // be formatted.  Since we only need this once, clear it afterwards.
14640 RUNTIME_FUNCTION(Runtime_GetAndClearOverflowedStackTrace) {
14641   HandleScope scope(isolate);
14642   ASSERT(args.length() == 1);
14643   CONVERT_ARG_HANDLE_CHECKED(JSObject, error_object, 0);
14644   Handle<String> key = isolate->factory()->hidden_stack_trace_string();
14645   Handle<Object> result(error_object->GetHiddenProperty(key), isolate);
14646   if (result->IsTheHole()) return isolate->heap()->undefined_value();
14647   RUNTIME_ASSERT(result->IsJSArray() || result->IsUndefined());
14648   JSObject::DeleteHiddenProperty(error_object, key);
14649   return *result;
14650 }
14651
14652
14653 // Returns V8 version as a string.
14654 RUNTIME_FUNCTION(Runtime_GetV8Version) {
14655   HandleScope scope(isolate);
14656   ASSERT(args.length() == 0);
14657
14658   const char* version_string = v8::V8::GetVersion();
14659
14660   return *isolate->factory()->NewStringFromAsciiChecked(version_string);
14661 }
14662
14663
14664 RUNTIME_FUNCTION(Runtime_Abort) {
14665   SealHandleScope shs(isolate);
14666   ASSERT(args.length() == 1);
14667   CONVERT_SMI_ARG_CHECKED(message_id, 0);
14668   const char* message = GetBailoutReason(
14669       static_cast<BailoutReason>(message_id));
14670   OS::PrintError("abort: %s\n", message);
14671   isolate->PrintStack(stderr);
14672   OS::Abort();
14673   UNREACHABLE();
14674   return NULL;
14675 }
14676
14677
14678 RUNTIME_FUNCTION(Runtime_AbortJS) {
14679   HandleScope scope(isolate);
14680   ASSERT(args.length() == 1);
14681   CONVERT_ARG_HANDLE_CHECKED(String, message, 0);
14682   OS::PrintError("abort: %s\n", message->ToCString().get());
14683   isolate->PrintStack(stderr);
14684   OS::Abort();
14685   UNREACHABLE();
14686   return NULL;
14687 }
14688
14689
14690 RUNTIME_FUNCTION(Runtime_FlattenString) {
14691   HandleScope scope(isolate);
14692   ASSERT(args.length() == 1);
14693   CONVERT_ARG_HANDLE_CHECKED(String, str, 0);
14694   return *String::Flatten(str);
14695 }
14696
14697
14698 RUNTIME_FUNCTION(Runtime_NotifyContextDisposed) {
14699   HandleScope scope(isolate);
14700   ASSERT(args.length() == 0);
14701   isolate->heap()->NotifyContextDisposed();
14702   return isolate->heap()->undefined_value();
14703 }
14704
14705
14706 RUNTIME_FUNCTION(Runtime_LoadMutableDouble) {
14707   HandleScope scope(isolate);
14708   ASSERT(args.length() == 2);
14709   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
14710   CONVERT_ARG_HANDLE_CHECKED(Smi, index, 1);
14711   int idx = index->value() >> 1;
14712   int inobject_properties = object->map()->inobject_properties();
14713   if (idx < 0) {
14714     idx = -idx + inobject_properties - 1;
14715   }
14716   int max_idx = object->properties()->length() + inobject_properties;
14717   RUNTIME_ASSERT(idx < max_idx);
14718   Handle<Object> raw_value(object->RawFastPropertyAt(idx), isolate);
14719   RUNTIME_ASSERT(raw_value->IsNumber() || raw_value->IsUninitialized());
14720   return *Object::NewStorageFor(isolate, raw_value, Representation::Double());
14721 }
14722
14723
14724 RUNTIME_FUNCTION(Runtime_TryMigrateInstance) {
14725   HandleScope scope(isolate);
14726   ASSERT(args.length() == 1);
14727   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
14728   if (!object->IsJSObject()) return Smi::FromInt(0);
14729   Handle<JSObject> js_object = Handle<JSObject>::cast(object);
14730   if (!js_object->map()->is_deprecated()) return Smi::FromInt(0);
14731   // This call must not cause lazy deopts, because it's called from deferred
14732   // code where we can't handle lazy deopts for lack of a suitable bailout
14733   // ID. So we just try migration and signal failure if necessary,
14734   // which will also trigger a deopt.
14735   if (!JSObject::TryMigrateInstance(js_object)) return Smi::FromInt(0);
14736   return *object;
14737 }
14738
14739
14740 RUNTIME_FUNCTION(RuntimeHidden_GetFromCache) {
14741   SealHandleScope shs(isolate);
14742   // This is only called from codegen, so checks might be more lax.
14743   CONVERT_ARG_CHECKED(JSFunctionResultCache, cache, 0);
14744   CONVERT_ARG_CHECKED(Object, key, 1);
14745
14746   {
14747     DisallowHeapAllocation no_alloc;
14748
14749     int finger_index = cache->finger_index();
14750     Object* o = cache->get(finger_index);
14751     if (o == key) {
14752       // The fastest case: hit the same place again.
14753       return cache->get(finger_index + 1);
14754     }
14755
14756     for (int i = finger_index - 2;
14757          i >= JSFunctionResultCache::kEntriesIndex;
14758          i -= 2) {
14759       o = cache->get(i);
14760       if (o == key) {
14761         cache->set_finger_index(i);
14762         return cache->get(i + 1);
14763       }
14764     }
14765
14766     int size = cache->size();
14767     ASSERT(size <= cache->length());
14768
14769     for (int i = size - 2; i > finger_index; i -= 2) {
14770       o = cache->get(i);
14771       if (o == key) {
14772         cache->set_finger_index(i);
14773         return cache->get(i + 1);
14774       }
14775     }
14776   }
14777
14778   // There is no value in the cache.  Invoke the function and cache result.
14779   HandleScope scope(isolate);
14780
14781   Handle<JSFunctionResultCache> cache_handle(cache);
14782   Handle<Object> key_handle(key, isolate);
14783   Handle<Object> value;
14784   {
14785     Handle<JSFunction> factory(JSFunction::cast(
14786           cache_handle->get(JSFunctionResultCache::kFactoryIndex)));
14787     // TODO(antonm): consider passing a receiver when constructing a cache.
14788     Handle<Object> receiver(isolate->native_context()->global_object(),
14789                             isolate);
14790     // This handle is nor shared, nor used later, so it's safe.
14791     Handle<Object> argv[] = { key_handle };
14792     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
14793         isolate, value,
14794         Execution::Call(isolate, factory, receiver, ARRAY_SIZE(argv), argv));
14795   }
14796
14797 #ifdef VERIFY_HEAP
14798   if (FLAG_verify_heap) {
14799     cache_handle->JSFunctionResultCacheVerify();
14800   }
14801 #endif
14802
14803   // Function invocation may have cleared the cache.  Reread all the data.
14804   int finger_index = cache_handle->finger_index();
14805   int size = cache_handle->size();
14806
14807   // If we have spare room, put new data into it, otherwise evict post finger
14808   // entry which is likely to be the least recently used.
14809   int index = -1;
14810   if (size < cache_handle->length()) {
14811     cache_handle->set_size(size + JSFunctionResultCache::kEntrySize);
14812     index = size;
14813   } else {
14814     index = finger_index + JSFunctionResultCache::kEntrySize;
14815     if (index == cache_handle->length()) {
14816       index = JSFunctionResultCache::kEntriesIndex;
14817     }
14818   }
14819
14820   ASSERT(index % 2 == 0);
14821   ASSERT(index >= JSFunctionResultCache::kEntriesIndex);
14822   ASSERT(index < cache_handle->length());
14823
14824   cache_handle->set(index, *key_handle);
14825   cache_handle->set(index + 1, *value);
14826   cache_handle->set_finger_index(index);
14827
14828 #ifdef VERIFY_HEAP
14829   if (FLAG_verify_heap) {
14830     cache_handle->JSFunctionResultCacheVerify();
14831   }
14832 #endif
14833
14834   return *value;
14835 }
14836
14837
14838 RUNTIME_FUNCTION(Runtime_MessageGetStartPosition) {
14839   SealHandleScope shs(isolate);
14840   ASSERT(args.length() == 1);
14841   CONVERT_ARG_CHECKED(JSMessageObject, message, 0);
14842   return Smi::FromInt(message->start_position());
14843 }
14844
14845
14846 RUNTIME_FUNCTION(Runtime_MessageGetScript) {
14847   SealHandleScope shs(isolate);
14848   ASSERT(args.length() == 1);
14849   CONVERT_ARG_CHECKED(JSMessageObject, message, 0);
14850   return message->script();
14851 }
14852
14853
14854 #ifdef DEBUG
14855 // ListNatives is ONLY used by the fuzz-natives.js in debug mode
14856 // Exclude the code in release mode.
14857 RUNTIME_FUNCTION(Runtime_ListNatives) {
14858   HandleScope scope(isolate);
14859   ASSERT(args.length() == 0);
14860 #define COUNT_ENTRY(Name, argc, ressize) + 1
14861   int entry_count = 0
14862       RUNTIME_FUNCTION_LIST(COUNT_ENTRY)
14863       RUNTIME_HIDDEN_FUNCTION_LIST(COUNT_ENTRY)
14864       INLINE_FUNCTION_LIST(COUNT_ENTRY);
14865 #undef COUNT_ENTRY
14866   Factory* factory = isolate->factory();
14867   Handle<FixedArray> elements = factory->NewFixedArray(entry_count);
14868   int index = 0;
14869   bool inline_runtime_functions = false;
14870 #define ADD_ENTRY(Name, argc, ressize)                                       \
14871   {                                                                          \
14872     HandleScope inner(isolate);                                              \
14873     Handle<String> name;                                                     \
14874     /* Inline runtime functions have an underscore in front of the name. */  \
14875     if (inline_runtime_functions) {                                          \
14876       name = factory->NewStringFromStaticAscii("_" #Name);                   \
14877     } else {                                                                 \
14878       name = factory->NewStringFromStaticAscii(#Name);                       \
14879     }                                                                        \
14880     Handle<FixedArray> pair_elements = factory->NewFixedArray(2);            \
14881     pair_elements->set(0, *name);                                            \
14882     pair_elements->set(1, Smi::FromInt(argc));                               \
14883     Handle<JSArray> pair = factory->NewJSArrayWithElements(pair_elements);   \
14884     elements->set(index++, *pair);                                           \
14885   }
14886   inline_runtime_functions = false;
14887   RUNTIME_FUNCTION_LIST(ADD_ENTRY)
14888   // Calling hidden runtime functions should just throw.
14889   RUNTIME_HIDDEN_FUNCTION_LIST(ADD_ENTRY)
14890   inline_runtime_functions = true;
14891   INLINE_FUNCTION_LIST(ADD_ENTRY)
14892 #undef ADD_ENTRY
14893   ASSERT_EQ(index, entry_count);
14894   Handle<JSArray> result = factory->NewJSArrayWithElements(elements);
14895   return *result;
14896 }
14897 #endif
14898
14899
14900 RUNTIME_FUNCTION(RuntimeHidden_Log) {
14901   HandleScope handle_scope(isolate);
14902   ASSERT(args.length() == 2);
14903   CONVERT_ARG_HANDLE_CHECKED(String, format, 0);
14904   CONVERT_ARG_HANDLE_CHECKED(JSArray, elms, 1);
14905
14906   SmartArrayPointer<char> format_chars = format->ToCString();
14907   isolate->logger()->LogRuntime(
14908       Vector<const char>(format_chars.get(), format->length()), elms);
14909   return isolate->heap()->undefined_value();
14910 }
14911
14912
14913 RUNTIME_FUNCTION(Runtime_IS_VAR) {
14914   UNREACHABLE();  // implemented as macro in the parser
14915   return NULL;
14916 }
14917
14918
14919 #define ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(Name)        \
14920   RUNTIME_FUNCTION(Runtime_Has##Name) {          \
14921     CONVERT_ARG_CHECKED(JSObject, obj, 0);                \
14922     return isolate->heap()->ToBoolean(obj->Has##Name());  \
14923   }
14924
14925 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastSmiElements)
14926 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastObjectElements)
14927 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastSmiOrObjectElements)
14928 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastDoubleElements)
14929 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastHoleyElements)
14930 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(DictionaryElements)
14931 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(SloppyArgumentsElements)
14932 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalArrayElements)
14933 // Properties test sitting with elements tests - not fooling anyone.
14934 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastProperties)
14935
14936 #undef ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION
14937
14938
14939 #define TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION(Type, type, TYPE, ctype, size)     \
14940   RUNTIME_FUNCTION(Runtime_HasExternal##Type##Elements) {             \
14941     CONVERT_ARG_CHECKED(JSObject, obj, 0);                                     \
14942     return isolate->heap()->ToBoolean(obj->HasExternal##Type##Elements());     \
14943   }
14944
14945 TYPED_ARRAYS(TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION)
14946
14947 #undef TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION
14948
14949
14950 #define FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION(Type, type, TYPE, ctype, s)  \
14951   RUNTIME_FUNCTION(Runtime_HasFixed##Type##Elements) {                \
14952     CONVERT_ARG_CHECKED(JSObject, obj, 0);                                     \
14953     return isolate->heap()->ToBoolean(obj->HasFixed##Type##Elements());        \
14954   }
14955
14956 TYPED_ARRAYS(FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION)
14957
14958 #undef FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION
14959
14960
14961 RUNTIME_FUNCTION(Runtime_HaveSameMap) {
14962   SealHandleScope shs(isolate);
14963   ASSERT(args.length() == 2);
14964   CONVERT_ARG_CHECKED(JSObject, obj1, 0);
14965   CONVERT_ARG_CHECKED(JSObject, obj2, 1);
14966   return isolate->heap()->ToBoolean(obj1->map() == obj2->map());
14967 }
14968
14969
14970 RUNTIME_FUNCTION(Runtime_IsJSGlobalProxy) {
14971   SealHandleScope shs(isolate);
14972   ASSERT(args.length() == 1);
14973   CONVERT_ARG_CHECKED(Object, obj, 0);
14974   return isolate->heap()->ToBoolean(obj->IsJSGlobalProxy());
14975 }
14976
14977
14978 RUNTIME_FUNCTION(Runtime_IsObserved) {
14979   SealHandleScope shs(isolate);
14980   ASSERT(args.length() == 1);
14981
14982   if (!args[0]->IsJSReceiver()) return isolate->heap()->false_value();
14983   CONVERT_ARG_CHECKED(JSReceiver, obj, 0);
14984   if (obj->IsJSGlobalProxy()) {
14985     Object* proto = obj->GetPrototype();
14986     if (proto->IsNull()) return isolate->heap()->false_value();
14987     ASSERT(proto->IsJSGlobalObject());
14988     obj = JSReceiver::cast(proto);
14989   }
14990   return isolate->heap()->ToBoolean(obj->map()->is_observed());
14991 }
14992
14993
14994 RUNTIME_FUNCTION(Runtime_SetIsObserved) {
14995   HandleScope scope(isolate);
14996   ASSERT(args.length() == 1);
14997   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, obj, 0);
14998   if (obj->IsJSGlobalProxy()) {
14999     Object* proto = obj->GetPrototype();
15000     if (proto->IsNull()) return isolate->heap()->undefined_value();
15001     ASSERT(proto->IsJSGlobalObject());
15002     obj = handle(JSReceiver::cast(proto));
15003   }
15004   if (obj->IsJSProxy())
15005     return isolate->heap()->undefined_value();
15006
15007   ASSERT(obj->IsJSObject());
15008   JSObject::SetObserved(Handle<JSObject>::cast(obj));
15009   return isolate->heap()->undefined_value();
15010 }
15011
15012
15013 RUNTIME_FUNCTION(Runtime_SetMicrotaskPending) {
15014   SealHandleScope shs(isolate);
15015   ASSERT(args.length() == 1);
15016   CONVERT_BOOLEAN_ARG_CHECKED(new_state, 0);
15017   bool old_state = isolate->microtask_pending();
15018   isolate->set_microtask_pending(new_state);
15019   return isolate->heap()->ToBoolean(old_state);
15020 }
15021
15022
15023 RUNTIME_FUNCTION(Runtime_RunMicrotasks) {
15024   HandleScope scope(isolate);
15025   ASSERT(args.length() == 0);
15026   if (isolate->microtask_pending()) Execution::RunMicrotasks(isolate);
15027   return isolate->heap()->undefined_value();
15028 }
15029
15030
15031 RUNTIME_FUNCTION(Runtime_GetMicrotaskState) {
15032   SealHandleScope shs(isolate);
15033   ASSERT(args.length() == 0);
15034   return isolate->heap()->microtask_state();
15035 }
15036
15037
15038 RUNTIME_FUNCTION(Runtime_GetObservationState) {
15039   SealHandleScope shs(isolate);
15040   ASSERT(args.length() == 0);
15041   return isolate->heap()->observation_state();
15042 }
15043
15044
15045 RUNTIME_FUNCTION(Runtime_ObservationWeakMapCreate) {
15046   HandleScope scope(isolate);
15047   ASSERT(args.length() == 0);
15048   // TODO(adamk): Currently this runtime function is only called three times per
15049   // isolate. If it's called more often, the map should be moved into the
15050   // strong root list.
15051   Handle<Map> map =
15052       isolate->factory()->NewMap(JS_WEAK_MAP_TYPE, JSWeakMap::kSize);
15053   Handle<JSWeakMap> weakmap =
15054       Handle<JSWeakMap>::cast(isolate->factory()->NewJSObjectFromMap(map));
15055   return *WeakCollectionInitialize(isolate, weakmap);
15056 }
15057
15058
15059 static bool ContextsHaveSameOrigin(Handle<Context> context1,
15060                                    Handle<Context> context2) {
15061   return context1->security_token() == context2->security_token();
15062 }
15063
15064
15065 RUNTIME_FUNCTION(Runtime_ObserverObjectAndRecordHaveSameOrigin) {
15066   HandleScope scope(isolate);
15067   ASSERT(args.length() == 3);
15068   CONVERT_ARG_HANDLE_CHECKED(JSFunction, observer, 0);
15069   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 1);
15070   CONVERT_ARG_HANDLE_CHECKED(JSObject, record, 2);
15071
15072   Handle<Context> observer_context(observer->context()->native_context(),
15073       isolate);
15074   Handle<Context> object_context(object->GetCreationContext());
15075   Handle<Context> record_context(record->GetCreationContext());
15076
15077   return isolate->heap()->ToBoolean(
15078       ContextsHaveSameOrigin(object_context, observer_context) &&
15079       ContextsHaveSameOrigin(object_context, record_context));
15080 }
15081
15082
15083 RUNTIME_FUNCTION(Runtime_ObjectWasCreatedInCurrentOrigin) {
15084   HandleScope scope(isolate);
15085   ASSERT(args.length() == 1);
15086   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
15087
15088   Handle<Context> creation_context(object->GetCreationContext(), isolate);
15089   return isolate->heap()->ToBoolean(
15090       ContextsHaveSameOrigin(creation_context, isolate->native_context()));
15091 }
15092
15093
15094 RUNTIME_FUNCTION(Runtime_ObjectObserveInObjectContext) {
15095   HandleScope scope(isolate);
15096   ASSERT(args.length() == 3);
15097   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
15098   CONVERT_ARG_HANDLE_CHECKED(JSFunction, callback, 1);
15099   CONVERT_ARG_HANDLE_CHECKED(Object, accept, 2);
15100   RUNTIME_ASSERT(accept->IsUndefined() || accept->IsJSObject());
15101
15102   Handle<Context> context(object->GetCreationContext(), isolate);
15103   Handle<JSFunction> function(context->native_object_observe(), isolate);
15104   Handle<Object> call_args[] = { object, callback, accept };
15105   Handle<Object> result;
15106
15107   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
15108       isolate, result,
15109       Execution::Call(isolate, function,
15110           handle(context->object_function(), isolate),
15111           ARRAY_SIZE(call_args), call_args, true));
15112   return *result;
15113 }
15114
15115
15116 RUNTIME_FUNCTION(Runtime_ObjectGetNotifierInObjectContext) {
15117   HandleScope scope(isolate);
15118   ASSERT(args.length() == 1);
15119   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
15120
15121   Handle<Context> context(object->GetCreationContext(), isolate);
15122   Handle<JSFunction> function(context->native_object_get_notifier(), isolate);
15123   Handle<Object> call_args[] = { object };
15124   Handle<Object> result;
15125
15126   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
15127       isolate, result,
15128       Execution::Call(isolate, function,
15129           handle(context->object_function(), isolate),
15130           ARRAY_SIZE(call_args), call_args, true));
15131   return *result;
15132 }
15133
15134
15135 RUNTIME_FUNCTION(Runtime_ObjectNotifierPerformChangeInObjectContext) {
15136   HandleScope scope(isolate);
15137   ASSERT(args.length() == 3);
15138   CONVERT_ARG_HANDLE_CHECKED(JSObject, object_info, 0);
15139   CONVERT_ARG_HANDLE_CHECKED(String, change_type, 1);
15140   CONVERT_ARG_HANDLE_CHECKED(JSFunction, change_fn, 2);
15141
15142   Handle<Context> context(object_info->GetCreationContext(), isolate);
15143   Handle<JSFunction> function(context->native_object_notifier_perform_change(),
15144       isolate);
15145   Handle<Object> call_args[] = { object_info, change_type, change_fn };
15146   Handle<Object> result;
15147
15148   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
15149       isolate, result,
15150       Execution::Call(isolate, function, isolate->factory()->undefined_value(),
15151                       ARRAY_SIZE(call_args), call_args, true));
15152   return *result;
15153 }
15154
15155
15156 static Object* ArrayConstructorCommon(Isolate* isolate,
15157                                            Handle<JSFunction> constructor,
15158                                            Handle<AllocationSite> site,
15159                                            Arguments* caller_args) {
15160   Factory* factory = isolate->factory();
15161
15162   bool holey = false;
15163   bool can_use_type_feedback = true;
15164   if (caller_args->length() == 1) {
15165     Handle<Object> argument_one = caller_args->at<Object>(0);
15166     if (argument_one->IsSmi()) {
15167       int value = Handle<Smi>::cast(argument_one)->value();
15168       if (value < 0 || value >= JSObject::kInitialMaxFastElementArray) {
15169         // the array is a dictionary in this case.
15170         can_use_type_feedback = false;
15171       } else if (value != 0) {
15172         holey = true;
15173       }
15174     } else {
15175       // Non-smi length argument produces a dictionary
15176       can_use_type_feedback = false;
15177     }
15178   }
15179
15180   Handle<JSArray> array;
15181   if (!site.is_null() && can_use_type_feedback) {
15182     ElementsKind to_kind = site->GetElementsKind();
15183     if (holey && !IsFastHoleyElementsKind(to_kind)) {
15184       to_kind = GetHoleyElementsKind(to_kind);
15185       // Update the allocation site info to reflect the advice alteration.
15186       site->SetElementsKind(to_kind);
15187     }
15188
15189     // We should allocate with an initial map that reflects the allocation site
15190     // advice. Therefore we use AllocateJSObjectFromMap instead of passing
15191     // the constructor.
15192     Handle<Map> initial_map(constructor->initial_map(), isolate);
15193     if (to_kind != initial_map->elements_kind()) {
15194       initial_map = Map::AsElementsKind(initial_map, to_kind);
15195     }
15196
15197     // If we don't care to track arrays of to_kind ElementsKind, then
15198     // don't emit a memento for them.
15199     Handle<AllocationSite> allocation_site;
15200     if (AllocationSite::GetMode(to_kind) == TRACK_ALLOCATION_SITE) {
15201       allocation_site = site;
15202     }
15203
15204     array = Handle<JSArray>::cast(factory->NewJSObjectFromMap(
15205         initial_map, NOT_TENURED, true, allocation_site));
15206   } else {
15207     array = Handle<JSArray>::cast(factory->NewJSObject(constructor));
15208
15209     // We might need to transition to holey
15210     ElementsKind kind = constructor->initial_map()->elements_kind();
15211     if (holey && !IsFastHoleyElementsKind(kind)) {
15212       kind = GetHoleyElementsKind(kind);
15213       JSObject::TransitionElementsKind(array, kind);
15214     }
15215   }
15216
15217   factory->NewJSArrayStorage(array, 0, 0, DONT_INITIALIZE_ARRAY_ELEMENTS);
15218
15219   ElementsKind old_kind = array->GetElementsKind();
15220   RETURN_FAILURE_ON_EXCEPTION(
15221       isolate, ArrayConstructInitializeElements(array, caller_args));
15222   if (!site.is_null() &&
15223       (old_kind != array->GetElementsKind() ||
15224        !can_use_type_feedback)) {
15225     // The arguments passed in caused a transition. This kind of complexity
15226     // can't be dealt with in the inlined hydrogen array constructor case.
15227     // We must mark the allocationsite as un-inlinable.
15228     site->SetDoNotInlineCall();
15229   }
15230   return *array;
15231 }
15232
15233
15234 RUNTIME_FUNCTION(RuntimeHidden_ArrayConstructor) {
15235   HandleScope scope(isolate);
15236   // If we get 2 arguments then they are the stub parameters (constructor, type
15237   // info).  If we get 4, then the first one is a pointer to the arguments
15238   // passed by the caller, and the last one is the length of the arguments
15239   // passed to the caller (redundant, but useful to check on the deoptimizer
15240   // with an assert).
15241   Arguments empty_args(0, NULL);
15242   bool no_caller_args = args.length() == 2;
15243   ASSERT(no_caller_args || args.length() == 4);
15244   int parameters_start = no_caller_args ? 0 : 1;
15245   Arguments* caller_args = no_caller_args
15246       ? &empty_args
15247       : reinterpret_cast<Arguments*>(args[0]);
15248   CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, parameters_start);
15249   CONVERT_ARG_HANDLE_CHECKED(Object, type_info, parameters_start + 1);
15250 #ifdef DEBUG
15251   if (!no_caller_args) {
15252     CONVERT_SMI_ARG_CHECKED(arg_count, parameters_start + 2);
15253     ASSERT(arg_count == caller_args->length());
15254   }
15255 #endif
15256
15257   Handle<AllocationSite> site;
15258   if (!type_info.is_null() &&
15259       *type_info != isolate->heap()->undefined_value()) {
15260     site = Handle<AllocationSite>::cast(type_info);
15261     ASSERT(!site->SitePointsToLiteral());
15262   }
15263
15264   return ArrayConstructorCommon(isolate,
15265                                 constructor,
15266                                 site,
15267                                 caller_args);
15268 }
15269
15270
15271 RUNTIME_FUNCTION(RuntimeHidden_InternalArrayConstructor) {
15272   HandleScope scope(isolate);
15273   Arguments empty_args(0, NULL);
15274   bool no_caller_args = args.length() == 1;
15275   ASSERT(no_caller_args || args.length() == 3);
15276   int parameters_start = no_caller_args ? 0 : 1;
15277   Arguments* caller_args = no_caller_args
15278       ? &empty_args
15279       : reinterpret_cast<Arguments*>(args[0]);
15280   CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, parameters_start);
15281 #ifdef DEBUG
15282   if (!no_caller_args) {
15283     CONVERT_SMI_ARG_CHECKED(arg_count, parameters_start + 1);
15284     ASSERT(arg_count == caller_args->length());
15285   }
15286 #endif
15287   return ArrayConstructorCommon(isolate,
15288                                 constructor,
15289                                 Handle<AllocationSite>::null(),
15290                                 caller_args);
15291 }
15292
15293
15294 RUNTIME_FUNCTION(Runtime_MaxSmi) {
15295   ASSERT(args.length() == 0);
15296   return Smi::FromInt(Smi::kMaxValue);
15297 }
15298
15299
15300 #define RETURN_Float32x4_RESULT(value)                                         \
15301   return *isolate->factory()->NewFloat32x4(value);
15302
15303
15304 #define RETURN_Float64x2_RESULT(value)                                         \
15305   return *isolate->factory()->NewFloat64x2(value);
15306
15307
15308 #define RETURN_Int32x4_RESULT(value)                                           \
15309   return *isolate->factory()->NewInt32x4(value);
15310
15311
15312 RUNTIME_FUNCTION(Runtime_CreateFloat32x4) {
15313   HandleScope scope(isolate);
15314   ASSERT(args.length() == 4);
15315   RUNTIME_ASSERT(args[0]->IsNumber());
15316   RUNTIME_ASSERT(args[1]->IsNumber());
15317   RUNTIME_ASSERT(args[2]->IsNumber());
15318   RUNTIME_ASSERT(args[3]->IsNumber());
15319
15320   float32x4_value_t value;
15321   value.storage[0] = static_cast<float>(args.number_at(0));
15322   value.storage[1] = static_cast<float>(args.number_at(1));
15323   value.storage[2] = static_cast<float>(args.number_at(2));
15324   value.storage[3] = static_cast<float>(args.number_at(3));
15325
15326   RETURN_Float32x4_RESULT(value);
15327 }
15328
15329
15330 RUNTIME_FUNCTION(Runtime_CreateFloat64x2) {
15331   HandleScope scope(isolate);
15332   ASSERT(args.length() == 2);
15333   RUNTIME_ASSERT(args[0]->IsNumber());
15334   RUNTIME_ASSERT(args[1]->IsNumber());
15335
15336   float64x2_value_t value;
15337   value.storage[0] = args.number_at(0);
15338   value.storage[1] = args.number_at(1);
15339
15340   RETURN_Float64x2_RESULT(value);
15341 }
15342
15343
15344 RUNTIME_FUNCTION(Runtime_CreateInt32x4) {
15345   HandleScope scope(isolate);
15346   ASSERT(args.length() == 4);
15347   RUNTIME_ASSERT(args[0]->IsNumber());
15348   RUNTIME_ASSERT(args[1]->IsNumber());
15349   RUNTIME_ASSERT(args[2]->IsNumber());
15350   RUNTIME_ASSERT(args[3]->IsNumber());
15351
15352   int32x4_value_t value;
15353   value.storage[0] = NumberToInt32(args[0]);
15354   value.storage[1] = NumberToInt32(args[1]);
15355   value.storage[2] = NumberToInt32(args[2]);
15356   value.storage[3] = NumberToInt32(args[3]);
15357
15358   RETURN_Int32x4_RESULT(value);
15359 }
15360
15361
15362 // Used to convert between uint32_t and float32 without breaking strict
15363 // aliasing rules.
15364 union float32_uint32 {
15365   float f;
15366   uint32_t u;
15367   float32_uint32(float v) {
15368     f = v;
15369   }
15370   float32_uint32(uint32_t v) {
15371     u = v;
15372   }
15373 };
15374
15375
15376 union float64_uint64 {
15377   double f;
15378   uint64_t u;
15379   float64_uint64(double v) {
15380     f = v;
15381   }
15382   float64_uint64(uint64_t v) {
15383     u = v;
15384   }
15385 };
15386
15387
15388 RUNTIME_FUNCTION(Runtime_Float32x4GetSignMask) {
15389   HandleScope scope(isolate);
15390   ASSERT(args.length() == 1);
15391   CONVERT_ARG_CHECKED(Float32x4, self, 0);
15392   float32_uint32 x(self->x());
15393   float32_uint32 y(self->y());
15394   float32_uint32 z(self->z());
15395   float32_uint32 w(self->w());
15396   uint32_t mx = (x.u & 0x80000000) >> 31;
15397   uint32_t my = (y.u & 0x80000000) >> 31;
15398   uint32_t mz = (z.u & 0x80000000) >> 31;
15399   uint32_t mw = (w.u & 0x80000000) >> 31;
15400   uint32_t value = mx | (my << 1) | (mz << 2) | (mw << 3);
15401   return *isolate->factory()->NewNumberFromUint(value);
15402 }
15403
15404
15405 RUNTIME_FUNCTION(Runtime_Float64x2GetSignMask) {
15406   HandleScope scope(isolate);
15407   ASSERT(args.length() == 1);
15408   CONVERT_ARG_CHECKED(Float64x2, self, 0);
15409   float64_uint64 x(self->x());
15410   float64_uint64 y(self->y());
15411   uint64_t mx = x.u >> 63;
15412   uint64_t my = y.u >> 63;
15413   uint32_t value = mx | (my << 1) ;
15414   return *isolate->factory()->NewNumberFromUint(value);
15415 }
15416
15417
15418 RUNTIME_FUNCTION(Runtime_Int32x4GetSignMask) {
15419   HandleScope scope(isolate);
15420   ASSERT(args.length() == 1);
15421   CONVERT_ARG_CHECKED(Int32x4, self, 0);
15422   uint32_t mx = (self->x() & 0x80000000) >> 31;
15423   uint32_t my = (self->y() & 0x80000000) >> 31;
15424   uint32_t mz = (self->z() & 0x80000000) >> 31;
15425   uint32_t mw = (self->w() & 0x80000000) >> 31;
15426   uint32_t value = mx | (my << 1) | (mz << 2) | (mw << 3);
15427   return *isolate->factory()->NewNumberFromUint(value);
15428 }
15429
15430
15431 #define LANE_VALUE(VALUE, LANE) \
15432   VALUE->LANE()
15433
15434
15435 #define LANE_FLAG(VALUE, LANE)  \
15436   VALUE->LANE() != 0
15437
15438
15439 #define SIMD128_LANE_ACCESS_FUNCTIONS(V)                      \
15440   V(Float32x4, GetX, NewNumber, x, LANE_VALUE)       \
15441   V(Float32x4, GetY, NewNumber, y, LANE_VALUE)       \
15442   V(Float32x4, GetZ, NewNumber, z, LANE_VALUE)       \
15443   V(Float32x4, GetW, NewNumber, w, LANE_VALUE)       \
15444   V(Float64x2, GetX, NewNumber, x, LANE_VALUE)       \
15445   V(Float64x2, GetY, NewNumber, y, LANE_VALUE)       \
15446   V(Int32x4, GetX, NewNumberFromInt, x, LANE_VALUE)            \
15447   V(Int32x4, GetY, NewNumberFromInt, y, LANE_VALUE)            \
15448   V(Int32x4, GetZ, NewNumberFromInt, z, LANE_VALUE)            \
15449   V(Int32x4, GetW, NewNumberFromInt, w, LANE_VALUE)            \
15450   V(Int32x4, GetFlagX, ToBoolean, x, LANE_FLAG)               \
15451   V(Int32x4, GetFlagY, ToBoolean, y, LANE_FLAG)               \
15452   V(Int32x4, GetFlagZ, ToBoolean, z, LANE_FLAG)               \
15453   V(Int32x4, GetFlagW, ToBoolean, w, LANE_FLAG)
15454
15455
15456 #define DECLARE_SIMD_LANE_ACCESS_FUNCTION(                    \
15457     TYPE, NAME, HEAP_FUNCTION, LANE, ACCESS_FUNCTION)         \
15458 RUNTIME_FUNCTION(Runtime_##TYPE##NAME) {        \
15459   HandleScope scope(isolate);                                 \
15460   ASSERT(args.length() == 1);                                 \
15461                                                               \
15462   CONVERT_ARG_CHECKED(TYPE, a, 0);                            \
15463                                                               \
15464   return *isolate->factory()->HEAP_FUNCTION(                  \
15465       ACCESS_FUNCTION(a, LANE));                              \
15466 }
15467
15468
15469 SIMD128_LANE_ACCESS_FUNCTIONS(DECLARE_SIMD_LANE_ACCESS_FUNCTION)
15470
15471
15472 template<typename T>
15473 static inline T Neg(T a) {
15474   return -a;
15475 }
15476
15477
15478 template<typename T>
15479 static inline T Not(T a) {
15480   return ~a;
15481 }
15482
15483
15484 template<typename T>
15485 static inline T Reciprocal(T a) {
15486   UNIMPLEMENTED();
15487 }
15488
15489
15490 template<>
15491 inline float Reciprocal<float>(float a) {
15492   return 1.0f / a;
15493 }
15494
15495
15496 template<typename T>
15497 static inline T ReciprocalSqrt(T a) {
15498   UNIMPLEMENTED();
15499 }
15500
15501
15502 template<>
15503 inline float ReciprocalSqrt<float>(float a) {
15504   return sqrtf(1.0f / a);
15505 }
15506
15507
15508 template<typename T>
15509 static inline T Sqrt(T a) {
15510   UNIMPLEMENTED();
15511 }
15512
15513
15514 template<>
15515 inline float Sqrt<float>(float a) {
15516   return sqrtf(a);
15517 }
15518
15519
15520 template<>
15521 inline double Sqrt<double>(double a) {
15522   return sqrt(a);
15523 }
15524
15525
15526 #define SIMD128_UNARY_FUNCTIONS(V)                            \
15527   V(Float32x4, Abs)                                           \
15528   V(Float32x4, Neg)                                           \
15529   V(Float32x4, Reciprocal)                                    \
15530   V(Float32x4, ReciprocalSqrt)                                \
15531   V(Float32x4, Sqrt)                                          \
15532   V(Float64x2, Abs)                                           \
15533   V(Float64x2, Neg)                                           \
15534   V(Float64x2, Sqrt)                                          \
15535   V(Int32x4, Neg)                                             \
15536   V(Int32x4, Not)
15537
15538
15539 #define DECLARE_SIMD_UNARY_FUNCTION(TYPE, FUNCTION)           \
15540 RUNTIME_FUNCTION(Runtime_##TYPE##FUNCTION) {    \
15541   HandleScope scope(isolate);                                 \
15542   ASSERT(args.length() == 1);                                 \
15543                                                               \
15544   CONVERT_ARG_CHECKED(TYPE, a, 0);                            \
15545                                                               \
15546   TYPE::value_t result;                                       \
15547   for (int i = 0; i < TYPE::kLanes; i++) {                    \
15548     result.storage[i] = FUNCTION(a->getAt(i));                \
15549   }                                                           \
15550                                                               \
15551   RETURN_##TYPE##_RESULT(result);                             \
15552 }
15553
15554
15555 SIMD128_UNARY_FUNCTIONS(DECLARE_SIMD_UNARY_FUNCTION)
15556
15557
15558 template<typename T1, typename T2>
15559 inline void BitsTo(T1 s, T2* t) {
15560   memcpy(t, &s, sizeof(T2));
15561 }
15562
15563
15564 template<typename T1, typename T2>
15565 inline void To(T1 s, T2* t) {
15566 }
15567
15568
15569 template<>
15570 inline void To<int32_t, float>(int32_t s, float* t) {
15571   *t = static_cast<float>(s);
15572 }
15573
15574
15575 template<>
15576 inline void To<float, int32_t>(float s, int32_t* t) {
15577   *t = DoubleToInt32(static_cast<double>(s));
15578 }
15579
15580
15581 #define SIMD128_CONVERSION_FUNCTIONS(V)                       \
15582   V(Float32x4, BitsTo, Int32x4)                               \
15583   V(Float32x4, To, Int32x4)                                   \
15584   V(Int32x4, BitsTo, Float32x4)                               \
15585   V(Int32x4, To, Float32x4)
15586
15587
15588 #define DECLARE_SIMD_CONVERSION_FUNCTION(                     \
15589     SOURCE_TYPE, FUNCTION, TARGET_TYPE)                       \
15590 RUNTIME_FUNCTION(                               \
15591     Runtime_##SOURCE_TYPE##FUNCTION##TARGET_TYPE) {           \
15592   HandleScope scope(isolate);                                 \
15593   ASSERT(args.length() == 1);                                 \
15594                                                               \
15595   CONVERT_ARG_CHECKED(SOURCE_TYPE, a, 0);                     \
15596                                                               \
15597   TARGET_TYPE::value_t result;                                \
15598   for (int i = 0; i < SOURCE_TYPE::kLanes; i++) {             \
15599     FUNCTION(a->getAt(i), &result.storage[i]);                \
15600   }                                                           \
15601                                                               \
15602   RETURN_##TARGET_TYPE##_RESULT(result);                      \
15603 }
15604
15605
15606 SIMD128_CONVERSION_FUNCTIONS(DECLARE_SIMD_CONVERSION_FUNCTION)
15607
15608
15609 template<typename T>
15610 static inline T Add(T a, T b) {
15611   return a + b;
15612 }
15613
15614
15615 template<typename T>
15616 static inline T Div(T a, T b) {
15617   return a / b;
15618 }
15619
15620
15621 template<typename T>
15622 static inline T Mul(T a, T b) {
15623   return a * b;
15624 }
15625
15626
15627 template<typename T>
15628 static inline T Sub(T a, T b) {
15629   return a - b;
15630 }
15631
15632
15633 template<typename T>
15634 static inline int32_t Equal(T a, T b) {
15635   return a == b ? -1 : 0;
15636 }
15637
15638
15639 template<typename T>
15640 static inline int32_t NotEqual(T a, T b) {
15641   return a != b ? -1 : 0;
15642 }
15643
15644
15645 template<typename T>
15646 static inline int32_t GreaterThanOrEqual(T a, T b) {
15647   return a >= b ? -1 : 0;
15648 }
15649
15650
15651 template<typename T>
15652 static inline int32_t GreaterThan(T a, T b) {
15653   return a > b ? -1 : 0;
15654 }
15655
15656
15657 template<typename T>
15658 static inline int32_t LessThan(T a, T b) {
15659   return a < b ? -1 : 0;
15660 }
15661
15662
15663 template<typename T>
15664 static inline int32_t LessThanOrEqual(T a, T b) {
15665   return a <= b ? -1 : 0;
15666 }
15667
15668
15669 template<typename T>
15670 static inline T And(T a, T b) {
15671   return a & b;
15672 }
15673
15674
15675 template<typename T>
15676 static inline T Or(T a, T b) {
15677   return a | b;
15678 }
15679
15680
15681 template<typename T>
15682 static inline T Xor(T a, T b) {
15683   return a ^ b;
15684 }
15685
15686
15687 #define SIMD128_BINARY_FUNCTIONS(V)                           \
15688   V(Float32x4, Add, Float32x4)                                \
15689   V(Float32x4, Div, Float32x4)                                \
15690   V(Float32x4, Max, Float32x4)                                \
15691   V(Float32x4, Min, Float32x4)                                \
15692   V(Float32x4, Mul, Float32x4)                                \
15693   V(Float32x4, Sub, Float32x4)                                \
15694   V(Float32x4, Equal, Int32x4)                                \
15695   V(Float32x4, NotEqual, Int32x4)                             \
15696   V(Float32x4, GreaterThanOrEqual, Int32x4)                   \
15697   V(Float32x4, GreaterThan, Int32x4)                          \
15698   V(Float32x4, LessThan, Int32x4)                             \
15699   V(Float32x4, LessThanOrEqual, Int32x4)                      \
15700   V(Float64x2, Add, Float64x2)                                \
15701   V(Float64x2, Div, Float64x2)                                \
15702   V(Float64x2, Max, Float64x2)                                \
15703   V(Float64x2, Min, Float64x2)                                \
15704   V(Float64x2, Mul, Float64x2)                                \
15705   V(Float64x2, Sub, Float64x2)                                \
15706   V(Int32x4, Add, Int32x4)                                    \
15707   V(Int32x4, And, Int32x4)                                    \
15708   V(Int32x4, Mul, Int32x4)                                    \
15709   V(Int32x4, Or, Int32x4)                                     \
15710   V(Int32x4, Sub, Int32x4)                                    \
15711   V(Int32x4, Xor, Int32x4)                                    \
15712   V(Int32x4, Equal, Int32x4)                                  \
15713   V(Int32x4, GreaterThan, Int32x4)                            \
15714   V(Int32x4, LessThan, Int32x4)
15715
15716
15717 #define DECLARE_SIMD_BINARY_FUNCTION(                         \
15718     TYPE, FUNCTION, RETURN_TYPE)                              \
15719 RUNTIME_FUNCTION(Runtime_##TYPE##FUNCTION) {    \
15720   HandleScope scope(isolate);                                 \
15721   ASSERT(args.length() == 2);                                 \
15722                                                               \
15723   CONVERT_ARG_CHECKED(TYPE, a, 0);                            \
15724   CONVERT_ARG_CHECKED(TYPE, b, 1);                            \
15725                                                               \
15726   RETURN_TYPE::value_t result;                                \
15727   for (int i = 0; i < TYPE::kLanes; i++) {                    \
15728     result.storage[i] = FUNCTION(a->getAt(i), b->getAt(i));   \
15729   }                                                           \
15730                                                               \
15731   RETURN_##RETURN_TYPE##_RESULT(result);                      \
15732 }
15733
15734
15735 SIMD128_BINARY_FUNCTIONS(DECLARE_SIMD_BINARY_FUNCTION)
15736
15737
15738 #define SIMD128_SHUFFLE_FUNCTIONS(V)                          \
15739   V(Float32x4)                                                \
15740   V(Int32x4)
15741
15742
15743 #define DECLARE_SIMD_SHUFFLE_FUNCTION(TYPE)                   \
15744 RUNTIME_FUNCTION(Runtime_##TYPE##Shuffle) {     \
15745   HandleScope scope(isolate);                                 \
15746   ASSERT(args.length() == 2);                                 \
15747                                                               \
15748   CONVERT_ARG_CHECKED(TYPE, a, 0);                            \
15749   RUNTIME_ASSERT(args[1]->IsNumber());                        \
15750   uint32_t m = NumberToUint32(args[1]);                       \
15751                                                               \
15752   TYPE::value_t result;                                       \
15753   for (int i = 0; i < TYPE::kLanes; i++) {                    \
15754     result.storage[i] = a->getAt((m >> (i * 2)) & 0x3);       \
15755   }                                                           \
15756                                                               \
15757   RETURN_##TYPE##_RESULT(result);                             \
15758 }
15759
15760
15761 SIMD128_SHUFFLE_FUNCTIONS(DECLARE_SIMD_SHUFFLE_FUNCTION)
15762
15763
15764 RUNTIME_FUNCTION(Runtime_Float32x4Scale) {
15765   HandleScope scope(isolate);
15766   ASSERT(args.length() == 2);
15767
15768   CONVERT_ARG_CHECKED(Float32x4, self, 0);
15769   RUNTIME_ASSERT(args[1]->IsNumber());
15770
15771   float _s = static_cast<float>(args.number_at(1));
15772   float32x4_value_t result;
15773   result.storage[0] = self->x() * _s;
15774   result.storage[1] = self->y() * _s;
15775   result.storage[2] = self->z() * _s;
15776   result.storage[3] = self->w() * _s;
15777
15778   RETURN_Float32x4_RESULT(result);
15779 }
15780
15781
15782 RUNTIME_FUNCTION(Runtime_Float64x2Scale) {
15783   HandleScope scope(isolate);
15784   ASSERT(args.length() == 2);
15785
15786   CONVERT_ARG_CHECKED(Float64x2, self, 0);
15787   RUNTIME_ASSERT(args[1]->IsNumber());
15788
15789   double _s = args.number_at(1);
15790   float64x2_value_t result;
15791   result.storage[0] = self->x() * _s;
15792   result.storage[1] = self->y() * _s;
15793
15794   RETURN_Float64x2_RESULT(result);
15795 }
15796
15797
15798 #define ARG_TO_FLOAT32(x) \
15799   CONVERT_DOUBLE_ARG_CHECKED(t, 1); \
15800   float x = static_cast<float>(t);
15801
15802
15803 #define ARG_TO_FLOAT64(x) \
15804   CONVERT_DOUBLE_ARG_CHECKED(x, 1); \
15805
15806
15807 #define ARG_TO_INT32(x) \
15808   RUNTIME_ASSERT(args[1]->IsNumber()); \
15809   int32_t x = NumberToInt32(args[1]);
15810
15811
15812 #define ARG_TO_BOOLEAN(x) \
15813   CONVERT_BOOLEAN_ARG_CHECKED(flag, 1); \
15814   int32_t x = flag ? -1 : 0;
15815
15816 #define SIMD128_SET_LANE_FUNCTIONS(V)                         \
15817   V(Float32x4, WithX, ARG_TO_FLOAT32, 0)                      \
15818   V(Float32x4, WithY, ARG_TO_FLOAT32, 1)                      \
15819   V(Float32x4, WithZ, ARG_TO_FLOAT32, 2)                      \
15820   V(Float32x4, WithW, ARG_TO_FLOAT32, 3)                      \
15821   V(Float64x2, WithX, ARG_TO_FLOAT64, 0)                      \
15822   V(Float64x2, WithY, ARG_TO_FLOAT64, 1)                      \
15823   V(Int32x4, WithX, ARG_TO_INT32, 0)                          \
15824   V(Int32x4, WithY, ARG_TO_INT32, 1)                          \
15825   V(Int32x4, WithZ, ARG_TO_INT32, 2)                          \
15826   V(Int32x4, WithW, ARG_TO_INT32, 3)                          \
15827   V(Int32x4, WithFlagX, ARG_TO_BOOLEAN, 0)                    \
15828   V(Int32x4, WithFlagY, ARG_TO_BOOLEAN, 1)                    \
15829   V(Int32x4, WithFlagZ, ARG_TO_BOOLEAN, 2)                    \
15830   V(Int32x4, WithFlagW, ARG_TO_BOOLEAN, 3)
15831
15832
15833 #define DECLARE_SIMD_SET_LANE_FUNCTION(                       \
15834     TYPE, NAME, ARG_FUNCTION, LANE)                           \
15835 RUNTIME_FUNCTION(Runtime_##TYPE##NAME) {        \
15836   HandleScope scope(isolate);                                 \
15837   ASSERT(args.length() == 2);                                 \
15838                                                               \
15839   CONVERT_ARG_CHECKED(TYPE, a, 0);                            \
15840   ARG_FUNCTION(value);                                        \
15841                                                               \
15842   TYPE::value_t result;                                       \
15843   for (int i = 0; i < TYPE::kLanes; i++) {                    \
15844     if (i != LANE)                                            \
15845       result.storage[i] = a->getAt(i);                        \
15846     else                                                      \
15847       result.storage[i] = value;                              \
15848   }                                                           \
15849                                                               \
15850   RETURN_##TYPE##_RESULT(result);                             \
15851 }
15852
15853
15854 SIMD128_SET_LANE_FUNCTIONS(DECLARE_SIMD_SET_LANE_FUNCTION)
15855
15856
15857 RUNTIME_FUNCTION(Runtime_Float32x4Clamp) {
15858   HandleScope scope(isolate);
15859   ASSERT(args.length() == 3);
15860
15861   CONVERT_ARG_CHECKED(Float32x4, self, 0);
15862   CONVERT_ARG_CHECKED(Float32x4, lo, 1);
15863   CONVERT_ARG_CHECKED(Float32x4, hi, 2);
15864
15865   float32x4_value_t result;
15866   float _x = self->x() > lo->x() ? self->x() : lo->x();
15867   float _y = self->y() > lo->y() ? self->y() : lo->y();
15868   float _z = self->z() > lo->z() ? self->z() : lo->z();
15869   float _w = self->w() > lo->w() ? self->w() : lo->w();
15870   result.storage[0] = _x > hi->x() ? hi->x() : _x;
15871   result.storage[1] = _y > hi->y() ? hi->y() : _y;
15872   result.storage[2] = _z > hi->z() ? hi->z() : _z;
15873   result.storage[3] = _w > hi->w() ? hi->w() : _w;
15874
15875   RETURN_Float32x4_RESULT(result);
15876 }
15877
15878
15879 RUNTIME_FUNCTION(Runtime_Float64x2Clamp) {
15880   HandleScope scope(isolate);
15881   ASSERT(args.length() == 3);
15882
15883   CONVERT_ARG_CHECKED(Float64x2, self, 0);
15884   CONVERT_ARG_CHECKED(Float64x2, lo, 1);
15885   CONVERT_ARG_CHECKED(Float64x2, hi, 2);
15886
15887   float64x2_value_t result;
15888   double _x = self->x() > lo->x() ? self->x() : lo->x();
15889   double _y = self->y() > lo->y() ? self->y() : lo->y();
15890   result.storage[0] = _x > hi->x() ? hi->x() : _x;
15891   result.storage[1] = _y > hi->y() ? hi->y() : _y;
15892
15893   RETURN_Float64x2_RESULT(result);
15894 }
15895
15896
15897 RUNTIME_FUNCTION(Runtime_Float32x4ShuffleMix) {
15898   HandleScope scope(isolate);
15899   ASSERT(args.length() == 3);
15900
15901   CONVERT_ARG_CHECKED(Float32x4, first, 0);
15902   CONVERT_ARG_CHECKED(Float32x4, second, 1);
15903   RUNTIME_ASSERT(args[2]->IsNumber());
15904
15905   uint32_t m = NumberToUint32(args[2]);
15906   float32x4_value_t result;
15907   float data1[4] = { first->x(), first->y(), first->z(), first->w() };
15908   float data2[4] = { second->x(), second->y(), second->z(), second->w() };
15909   result.storage[0] = data1[m & 0x3];
15910   result.storage[1] = data1[(m >> 2) & 0x3];
15911   result.storage[2] = data2[(m >> 4) & 0x3];
15912   result.storage[3] = data2[(m >> 6) & 0x3];
15913
15914   RETURN_Float32x4_RESULT(result);
15915 }
15916
15917
15918 RUNTIME_FUNCTION(Runtime_Int32x4Select) {
15919   HandleScope scope(isolate);
15920   ASSERT(args.length() == 3);
15921
15922   CONVERT_ARG_CHECKED(Int32x4, self, 0);
15923   CONVERT_ARG_CHECKED(Float32x4, tv, 1);
15924   CONVERT_ARG_CHECKED(Float32x4, fv, 2);
15925
15926   uint32_t _maskX = self->x();
15927   uint32_t _maskY = self->y();
15928   uint32_t _maskZ = self->z();
15929   uint32_t _maskW = self->w();
15930   // Extract floats and interpret them as masks.
15931   float32_uint32 tvx(tv->x());
15932   float32_uint32 tvy(tv->y());
15933   float32_uint32 tvz(tv->z());
15934   float32_uint32 tvw(tv->w());
15935   float32_uint32 fvx(fv->x());
15936   float32_uint32 fvy(fv->y());
15937   float32_uint32 fvz(fv->z());
15938   float32_uint32 fvw(fv->w());
15939   // Perform select.
15940   float32_uint32 tempX((_maskX & tvx.u) | (~_maskX & fvx.u));
15941   float32_uint32 tempY((_maskY & tvy.u) | (~_maskY & fvy.u));
15942   float32_uint32 tempZ((_maskZ & tvz.u) | (~_maskZ & fvz.u));
15943   float32_uint32 tempW((_maskW & tvw.u) | (~_maskW & fvw.u));
15944
15945   float32x4_value_t result;
15946   result.storage[0] = tempX.f;
15947   result.storage[1] = tempY.f;
15948   result.storage[2] = tempZ.f;
15949   result.storage[3] = tempW.f;
15950
15951   RETURN_Float32x4_RESULT(result);
15952 }
15953
15954
15955 // ----------------------------------------------------------------------------
15956 // Implementation of Runtime
15957
15958 #define F(name, number_of_args, result_size)                             \
15959   { Runtime::k##name, Runtime::RUNTIME, #name,   \
15960     FUNCTION_ADDR(Runtime_##name), number_of_args, result_size },
15961
15962
15963 #define FH(name, number_of_args, result_size)                             \
15964   { Runtime::kHidden##name, Runtime::RUNTIME_HIDDEN, NULL,   \
15965     FUNCTION_ADDR(RuntimeHidden_##name), number_of_args, result_size },
15966
15967
15968 #define I(name, number_of_args, result_size)                             \
15969   { Runtime::kInline##name, Runtime::INLINE,     \
15970     "_" #name, NULL, number_of_args, result_size },
15971
15972
15973 #define IO(name, number_of_args, result_size) \
15974   { Runtime::kInlineOptimized##name, Runtime::INLINE_OPTIMIZED, \
15975     "_" #name, FUNCTION_ADDR(Runtime_##name), number_of_args, result_size },
15976
15977
15978 static const Runtime::Function kIntrinsicFunctions[] = {
15979   RUNTIME_FUNCTION_LIST(F)
15980   RUNTIME_HIDDEN_FUNCTION_LIST(FH)
15981   INLINE_FUNCTION_LIST(I)
15982   INLINE_OPTIMIZED_FUNCTION_LIST(IO)
15983 };
15984
15985 #undef IO
15986 #undef I
15987 #undef FH
15988 #undef F
15989
15990
15991 void Runtime::InitializeIntrinsicFunctionNames(Isolate* isolate,
15992                                                Handle<NameDictionary> dict) {
15993   ASSERT(dict->NumberOfElements() == 0);
15994   HandleScope scope(isolate);
15995   for (int i = 0; i < kNumFunctions; ++i) {
15996     const char* name = kIntrinsicFunctions[i].name;
15997     if (name == NULL) continue;
15998     Handle<NameDictionary> new_dict = NameDictionary::Add(
15999         dict,
16000         isolate->factory()->InternalizeUtf8String(name),
16001         Handle<Smi>(Smi::FromInt(i), isolate),
16002         PropertyDetails(NONE, NORMAL, Representation::None()));
16003     // The dictionary does not need to grow.
16004     CHECK(new_dict.is_identical_to(dict));
16005   }
16006 }
16007
16008
16009 const Runtime::Function* Runtime::FunctionForName(Handle<String> name) {
16010   Heap* heap = name->GetHeap();
16011   int entry = heap->intrinsic_function_names()->FindEntry(name);
16012   if (entry != kNotFound) {
16013     Object* smi_index = heap->intrinsic_function_names()->ValueAt(entry);
16014     int function_index = Smi::cast(smi_index)->value();
16015     return &(kIntrinsicFunctions[function_index]);
16016   }
16017   return NULL;
16018 }
16019
16020
16021 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) {
16022   return &(kIntrinsicFunctions[static_cast<int>(id)]);
16023 }
16024
16025 } }  // namespace v8::internal