| OLD | NEW | 
|     1 // Copyright 2012 the V8 project authors. All rights reserved. |     1 // Copyright 2012 the V8 project authors. All rights reserved. | 
|     2 // Use of this source code is governed by a BSD-style license that can be |     2 // Use of this source code is governed by a BSD-style license that can be | 
|     3 // found in the LICENSE file. |     3 // found in the LICENSE file. | 
|     4  |     4  | 
|     5 #include <stdlib.h> |     5 #include <stdlib.h> | 
|     6 #include <limits> |     6 #include <limits> | 
|     7  |     7  | 
|     8 #include "src/v8.h" |     8 #include "src/v8.h" | 
|     9  |     9  | 
|    10 #include "src/accessors.h" |    10 #include "src/accessors.h" | 
|    11 #include "src/allocation-site-scopes.h" |  | 
|    12 #include "src/api.h" |    11 #include "src/api.h" | 
|    13 #include "src/arguments.h" |    12 #include "src/arguments.h" | 
|    14 #include "src/bailout-reason.h" |    13 #include "src/bailout-reason.h" | 
|    15 #include "src/base/cpu.h" |    14 #include "src/base/cpu.h" | 
|    16 #include "src/base/platform/platform.h" |    15 #include "src/base/platform/platform.h" | 
|    17 #include "src/bootstrapper.h" |    16 #include "src/bootstrapper.h" | 
|    18 #include "src/codegen.h" |  | 
|    19 #include "src/compilation-cache.h" |  | 
|    20 #include "src/compiler.h" |  | 
|    21 #include "src/conversions.h" |    17 #include "src/conversions.h" | 
|    22 #include "src/deoptimizer.h" |  | 
|    23 #include "src/execution.h" |  | 
|    24 #include "src/full-codegen.h" |  | 
|    25 #include "src/global-handles.h" |    18 #include "src/global-handles.h" | 
|    26 #include "src/isolate-inl.h" |    19 #include "src/isolate-inl.h" | 
|    27 #include "src/parser.h" |  | 
|    28 #include "src/prototype.h" |    20 #include "src/prototype.h" | 
|    29 #include "src/runtime/runtime.h" |    21 #include "src/runtime/runtime.h" | 
|    30 #include "src/runtime/runtime-utils.h" |    22 #include "src/runtime/runtime-utils.h" | 
|    31 #include "src/scopeinfo.h" |  | 
|    32 #include "src/smart-pointers.h" |  | 
|    33 #include "src/utils.h" |    23 #include "src/utils.h" | 
|    34 #include "src/v8threads.h" |  | 
|    35  |    24  | 
|    36  |    25  | 
|    37 namespace v8 { |    26 namespace v8 { | 
|    38 namespace internal { |    27 namespace internal { | 
|    39  |    28  | 
|    40 // Header of runtime functions. |    29 // Header of runtime functions. | 
|    41 #define F(name, number_of_args, result_size)                    \ |    30 #define F(name, number_of_args, result_size)                    \ | 
|    42   Object* Runtime_##name(int args_length, Object** args_object, \ |    31   Object* Runtime_##name(int args_length, Object** args_object, \ | 
|    43                          Isolate* isolate); |    32                          Isolate* isolate); | 
|    44  |    33  | 
|    45 #define P(name, number_of_args, result_size)                       \ |    34 #define P(name, number_of_args, result_size)                       \ | 
|    46   ObjectPair Runtime_##name(int args_length, Object** args_object, \ |    35   ObjectPair Runtime_##name(int args_length, Object** args_object, \ | 
|    47                             Isolate* isolate); |    36                             Isolate* isolate); | 
|    48  |    37  | 
|    49 #define I(name, number_of_args, result_size)                             \ |    38 #define I(name, number_of_args, result_size)                             \ | 
|    50   Object* RuntimeReference_##name(int args_length, Object** args_object, \ |    39   Object* RuntimeReference_##name(int args_length, Object** args_object, \ | 
|    51                                   Isolate* isolate); |    40                                   Isolate* isolate); | 
|    52  |    41  | 
|    53 RUNTIME_FUNCTION_LIST_RETURN_OBJECT(F) |    42 RUNTIME_FUNCTION_LIST_RETURN_OBJECT(F) | 
|    54 RUNTIME_FUNCTION_LIST_RETURN_PAIR(P) |    43 RUNTIME_FUNCTION_LIST_RETURN_PAIR(P) | 
|    55 INLINE_OPTIMIZED_FUNCTION_LIST(F) |    44 INLINE_OPTIMIZED_FUNCTION_LIST(F) | 
|    56 INLINE_FUNCTION_LIST(I) |    45 INLINE_FUNCTION_LIST(I) | 
|    57  |    46  | 
|    58 #undef I |    47 #undef I | 
|    59 #undef F |    48 #undef F | 
|    60 #undef P |    49 #undef P | 
|    61  |    50  | 
|    62  |    51  | 
|    63 static Handle<Map> ComputeObjectLiteralMap( |  | 
|    64     Handle<Context> context, Handle<FixedArray> constant_properties, |  | 
|    65     bool* is_result_from_cache) { |  | 
|    66   Isolate* isolate = context->GetIsolate(); |  | 
|    67   int properties_length = constant_properties->length(); |  | 
|    68   int number_of_properties = properties_length / 2; |  | 
|    69   // Check that there are only internal strings and array indices among keys. |  | 
|    70   int number_of_string_keys = 0; |  | 
|    71   for (int p = 0; p != properties_length; p += 2) { |  | 
|    72     Object* key = constant_properties->get(p); |  | 
|    73     uint32_t element_index = 0; |  | 
|    74     if (key->IsInternalizedString()) { |  | 
|    75       number_of_string_keys++; |  | 
|    76     } else if (key->ToArrayIndex(&element_index)) { |  | 
|    77       // An index key does not require space in the property backing store. |  | 
|    78       number_of_properties--; |  | 
|    79     } else { |  | 
|    80       // Bail out as a non-internalized-string non-index key makes caching |  | 
|    81       // impossible. |  | 
|    82       // DCHECK to make sure that the if condition after the loop is false. |  | 
|    83       DCHECK(number_of_string_keys != number_of_properties); |  | 
|    84       break; |  | 
|    85     } |  | 
|    86   } |  | 
|    87   // If we only have internalized strings and array indices among keys then we |  | 
|    88   // can use the map cache in the native context. |  | 
|    89   const int kMaxKeys = 10; |  | 
|    90   if ((number_of_string_keys == number_of_properties) && |  | 
|    91       (number_of_string_keys < kMaxKeys)) { |  | 
|    92     // Create the fixed array with the key. |  | 
|    93     Handle<FixedArray> keys = |  | 
|    94         isolate->factory()->NewFixedArray(number_of_string_keys); |  | 
|    95     if (number_of_string_keys > 0) { |  | 
|    96       int index = 0; |  | 
|    97       for (int p = 0; p < properties_length; p += 2) { |  | 
|    98         Object* key = constant_properties->get(p); |  | 
|    99         if (key->IsInternalizedString()) { |  | 
|   100           keys->set(index++, key); |  | 
|   101         } |  | 
|   102       } |  | 
|   103       DCHECK(index == number_of_string_keys); |  | 
|   104     } |  | 
|   105     *is_result_from_cache = true; |  | 
|   106     return isolate->factory()->ObjectLiteralMapFromCache(context, keys); |  | 
|   107   } |  | 
|   108   *is_result_from_cache = false; |  | 
|   109   return Map::Create(isolate, number_of_properties); |  | 
|   110 } |  | 
|   111  |  | 
|   112  |  | 
|   113 MUST_USE_RESULT static MaybeHandle<Object> CreateLiteralBoilerplate( |  | 
|   114     Isolate* isolate, Handle<FixedArray> literals, |  | 
|   115     Handle<FixedArray> constant_properties); |  | 
|   116  |  | 
|   117  |  | 
|   118 MUST_USE_RESULT static MaybeHandle<Object> CreateObjectLiteralBoilerplate( |  | 
|   119     Isolate* isolate, Handle<FixedArray> literals, |  | 
|   120     Handle<FixedArray> constant_properties, bool should_have_fast_elements, |  | 
|   121     bool has_function_literal) { |  | 
|   122   // Get the native context from the literals array.  This is the |  | 
|   123   // context in which the function was created and we use the object |  | 
|   124   // function from this context to create the object literal.  We do |  | 
|   125   // not use the object function from the current native context |  | 
|   126   // because this might be the object function from another context |  | 
|   127   // which we should not have access to. |  | 
|   128   Handle<Context> context = |  | 
|   129       Handle<Context>(JSFunction::NativeContextFromLiterals(*literals)); |  | 
|   130  |  | 
|   131   // In case we have function literals, we want the object to be in |  | 
|   132   // slow properties mode for now. We don't go in the map cache because |  | 
|   133   // maps with constant functions can't be shared if the functions are |  | 
|   134   // not the same (which is the common case). |  | 
|   135   bool is_result_from_cache = false; |  | 
|   136   Handle<Map> map = has_function_literal |  | 
|   137                         ? Handle<Map>(context->object_function()->initial_map()) |  | 
|   138                         : ComputeObjectLiteralMap(context, constant_properties, |  | 
|   139                                                   &is_result_from_cache); |  | 
|   140  |  | 
|   141   PretenureFlag pretenure_flag = |  | 
|   142       isolate->heap()->InNewSpace(*literals) ? NOT_TENURED : TENURED; |  | 
|   143  |  | 
|   144   Handle<JSObject> boilerplate = |  | 
|   145       isolate->factory()->NewJSObjectFromMap(map, pretenure_flag); |  | 
|   146  |  | 
|   147   // Normalize the elements of the boilerplate to save space if needed. |  | 
|   148   if (!should_have_fast_elements) JSObject::NormalizeElements(boilerplate); |  | 
|   149  |  | 
|   150   // Add the constant properties to the boilerplate. |  | 
|   151   int length = constant_properties->length(); |  | 
|   152   bool should_transform = |  | 
|   153       !is_result_from_cache && boilerplate->HasFastProperties(); |  | 
|   154   bool should_normalize = should_transform || has_function_literal; |  | 
|   155   if (should_normalize) { |  | 
|   156     // TODO(verwaest): We might not want to ever normalize here. |  | 
|   157     JSObject::NormalizeProperties(boilerplate, KEEP_INOBJECT_PROPERTIES, |  | 
|   158                                   length / 2); |  | 
|   159   } |  | 
|   160   // TODO(verwaest): Support tracking representations in the boilerplate. |  | 
|   161   for (int index = 0; index < length; index += 2) { |  | 
|   162     Handle<Object> key(constant_properties->get(index + 0), isolate); |  | 
|   163     Handle<Object> value(constant_properties->get(index + 1), isolate); |  | 
|   164     if (value->IsFixedArray()) { |  | 
|   165       // The value contains the constant_properties of a |  | 
|   166       // simple object or array literal. |  | 
|   167       Handle<FixedArray> array = Handle<FixedArray>::cast(value); |  | 
|   168       ASSIGN_RETURN_ON_EXCEPTION( |  | 
|   169           isolate, value, CreateLiteralBoilerplate(isolate, literals, array), |  | 
|   170           Object); |  | 
|   171     } |  | 
|   172     MaybeHandle<Object> maybe_result; |  | 
|   173     uint32_t element_index = 0; |  | 
|   174     if (key->IsInternalizedString()) { |  | 
|   175       if (Handle<String>::cast(key)->AsArrayIndex(&element_index)) { |  | 
|   176         // Array index as string (uint32). |  | 
|   177         if (value->IsUninitialized()) value = handle(Smi::FromInt(0), isolate); |  | 
|   178         maybe_result = |  | 
|   179             JSObject::SetOwnElement(boilerplate, element_index, value, SLOPPY); |  | 
|   180       } else { |  | 
|   181         Handle<String> name(String::cast(*key)); |  | 
|   182         DCHECK(!name->AsArrayIndex(&element_index)); |  | 
|   183         maybe_result = JSObject::SetOwnPropertyIgnoreAttributes( |  | 
|   184             boilerplate, name, value, NONE); |  | 
|   185       } |  | 
|   186     } else if (key->ToArrayIndex(&element_index)) { |  | 
|   187       // Array index (uint32). |  | 
|   188       if (value->IsUninitialized()) value = handle(Smi::FromInt(0), isolate); |  | 
|   189       maybe_result = |  | 
|   190           JSObject::SetOwnElement(boilerplate, element_index, value, SLOPPY); |  | 
|   191     } else { |  | 
|   192       // Non-uint32 number. |  | 
|   193       DCHECK(key->IsNumber()); |  | 
|   194       double num = key->Number(); |  | 
|   195       char arr[100]; |  | 
|   196       Vector<char> buffer(arr, arraysize(arr)); |  | 
|   197       const char* str = DoubleToCString(num, buffer); |  | 
|   198       Handle<String> name = isolate->factory()->NewStringFromAsciiChecked(str); |  | 
|   199       maybe_result = JSObject::SetOwnPropertyIgnoreAttributes(boilerplate, name, |  | 
|   200                                                               value, NONE); |  | 
|   201     } |  | 
|   202     // If setting the property on the boilerplate throws an |  | 
|   203     // exception, the exception is converted to an empty handle in |  | 
|   204     // the handle based operations.  In that case, we need to |  | 
|   205     // convert back to an exception. |  | 
|   206     RETURN_ON_EXCEPTION(isolate, maybe_result, Object); |  | 
|   207   } |  | 
|   208  |  | 
|   209   // Transform to fast properties if necessary. For object literals with |  | 
|   210   // containing function literals we defer this operation until after all |  | 
|   211   // computed properties have been assigned so that we can generate |  | 
|   212   // constant function properties. |  | 
|   213   if (should_transform && !has_function_literal) { |  | 
|   214     JSObject::MigrateSlowToFast(boilerplate, |  | 
|   215                                 boilerplate->map()->unused_property_fields()); |  | 
|   216   } |  | 
|   217  |  | 
|   218   return boilerplate; |  | 
|   219 } |  | 
|   220  |  | 
|   221  |  | 
|   222 MUST_USE_RESULT static MaybeHandle<Object> TransitionElements( |    52 MUST_USE_RESULT static MaybeHandle<Object> TransitionElements( | 
|   223     Handle<Object> object, ElementsKind to_kind, Isolate* isolate) { |    53     Handle<Object> object, ElementsKind to_kind, Isolate* isolate) { | 
|   224   HandleScope scope(isolate); |    54   HandleScope scope(isolate); | 
|   225   if (!object->IsJSObject()) { |    55   if (!object->IsJSObject()) { | 
|   226     isolate->ThrowIllegalOperation(); |    56     isolate->ThrowIllegalOperation(); | 
|   227     return MaybeHandle<Object>(); |    57     return MaybeHandle<Object>(); | 
|   228   } |    58   } | 
|   229   ElementsKind from_kind = |    59   ElementsKind from_kind = | 
|   230       Handle<JSObject>::cast(object)->map()->elements_kind(); |    60       Handle<JSObject>::cast(object)->map()->elements_kind(); | 
|   231   if (Map::IsValidElementsTransition(from_kind, to_kind)) { |    61   if (Map::IsValidElementsTransition(from_kind, to_kind)) { | 
|   232     JSObject::TransitionElementsKind(Handle<JSObject>::cast(object), to_kind); |    62     JSObject::TransitionElementsKind(Handle<JSObject>::cast(object), to_kind); | 
|   233     return object; |    63     return object; | 
|   234   } |    64   } | 
|   235   isolate->ThrowIllegalOperation(); |    65   isolate->ThrowIllegalOperation(); | 
|   236   return MaybeHandle<Object>(); |    66   return MaybeHandle<Object>(); | 
|   237 } |    67 } | 
|   238  |    68  | 
|   239  |    69  | 
|   240 MaybeHandle<Object> Runtime::CreateArrayLiteralBoilerplate( |  | 
|   241     Isolate* isolate, Handle<FixedArray> literals, |  | 
|   242     Handle<FixedArray> elements) { |  | 
|   243   // Create the JSArray. |  | 
|   244   Handle<JSFunction> constructor( |  | 
|   245       JSFunction::NativeContextFromLiterals(*literals)->array_function()); |  | 
|   246  |  | 
|   247   PretenureFlag pretenure_flag = |  | 
|   248       isolate->heap()->InNewSpace(*literals) ? NOT_TENURED : TENURED; |  | 
|   249  |  | 
|   250   Handle<JSArray> object = Handle<JSArray>::cast( |  | 
|   251       isolate->factory()->NewJSObject(constructor, pretenure_flag)); |  | 
|   252  |  | 
|   253   ElementsKind constant_elements_kind = |  | 
|   254       static_cast<ElementsKind>(Smi::cast(elements->get(0))->value()); |  | 
|   255   Handle<FixedArrayBase> constant_elements_values( |  | 
|   256       FixedArrayBase::cast(elements->get(1))); |  | 
|   257  |  | 
|   258   { |  | 
|   259     DisallowHeapAllocation no_gc; |  | 
|   260     DCHECK(IsFastElementsKind(constant_elements_kind)); |  | 
|   261     Context* native_context = isolate->context()->native_context(); |  | 
|   262     Object* maps_array = native_context->js_array_maps(); |  | 
|   263     DCHECK(!maps_array->IsUndefined()); |  | 
|   264     Object* map = FixedArray::cast(maps_array)->get(constant_elements_kind); |  | 
|   265     object->set_map(Map::cast(map)); |  | 
|   266   } |  | 
|   267  |  | 
|   268   Handle<FixedArrayBase> copied_elements_values; |  | 
|   269   if (IsFastDoubleElementsKind(constant_elements_kind)) { |  | 
|   270     copied_elements_values = isolate->factory()->CopyFixedDoubleArray( |  | 
|   271         Handle<FixedDoubleArray>::cast(constant_elements_values)); |  | 
|   272   } else { |  | 
|   273     DCHECK(IsFastSmiOrObjectElementsKind(constant_elements_kind)); |  | 
|   274     const bool is_cow = (constant_elements_values->map() == |  | 
|   275                          isolate->heap()->fixed_cow_array_map()); |  | 
|   276     if (is_cow) { |  | 
|   277       copied_elements_values = constant_elements_values; |  | 
|   278 #if DEBUG |  | 
|   279       Handle<FixedArray> fixed_array_values = |  | 
|   280           Handle<FixedArray>::cast(copied_elements_values); |  | 
|   281       for (int i = 0; i < fixed_array_values->length(); i++) { |  | 
|   282         DCHECK(!fixed_array_values->get(i)->IsFixedArray()); |  | 
|   283       } |  | 
|   284 #endif |  | 
|   285     } else { |  | 
|   286       Handle<FixedArray> fixed_array_values = |  | 
|   287           Handle<FixedArray>::cast(constant_elements_values); |  | 
|   288       Handle<FixedArray> fixed_array_values_copy = |  | 
|   289           isolate->factory()->CopyFixedArray(fixed_array_values); |  | 
|   290       copied_elements_values = fixed_array_values_copy; |  | 
|   291       for (int i = 0; i < fixed_array_values->length(); i++) { |  | 
|   292         if (fixed_array_values->get(i)->IsFixedArray()) { |  | 
|   293           // The value contains the constant_properties of a |  | 
|   294           // simple object or array literal. |  | 
|   295           Handle<FixedArray> fa(FixedArray::cast(fixed_array_values->get(i))); |  | 
|   296           Handle<Object> result; |  | 
|   297           ASSIGN_RETURN_ON_EXCEPTION( |  | 
|   298               isolate, result, CreateLiteralBoilerplate(isolate, literals, fa), |  | 
|   299               Object); |  | 
|   300           fixed_array_values_copy->set(i, *result); |  | 
|   301         } |  | 
|   302       } |  | 
|   303     } |  | 
|   304   } |  | 
|   305   object->set_elements(*copied_elements_values); |  | 
|   306   object->set_length(Smi::FromInt(copied_elements_values->length())); |  | 
|   307  |  | 
|   308   JSObject::ValidateElements(object); |  | 
|   309   return object; |  | 
|   310 } |  | 
|   311  |  | 
|   312  |  | 
|   313 MUST_USE_RESULT static MaybeHandle<Object> CreateLiteralBoilerplate( |  | 
|   314     Isolate* isolate, Handle<FixedArray> literals, Handle<FixedArray> array) { |  | 
|   315   Handle<FixedArray> elements = CompileTimeValue::GetElements(array); |  | 
|   316   const bool kHasNoFunctionLiteral = false; |  | 
|   317   switch (CompileTimeValue::GetLiteralType(array)) { |  | 
|   318     case CompileTimeValue::OBJECT_LITERAL_FAST_ELEMENTS: |  | 
|   319       return CreateObjectLiteralBoilerplate(isolate, literals, elements, true, |  | 
|   320                                             kHasNoFunctionLiteral); |  | 
|   321     case CompileTimeValue::OBJECT_LITERAL_SLOW_ELEMENTS: |  | 
|   322       return CreateObjectLiteralBoilerplate(isolate, literals, elements, false, |  | 
|   323                                             kHasNoFunctionLiteral); |  | 
|   324     case CompileTimeValue::ARRAY_LITERAL: |  | 
|   325       return Runtime::CreateArrayLiteralBoilerplate(isolate, literals, |  | 
|   326                                                     elements); |  | 
|   327     default: |  | 
|   328       UNREACHABLE(); |  | 
|   329       return MaybeHandle<Object>(); |  | 
|   330   } |  | 
|   331 } |  | 
|   332  |  | 
|   333  |  | 
|   334 RUNTIME_FUNCTION(Runtime_CreateObjectLiteral) { |  | 
|   335   HandleScope scope(isolate); |  | 
|   336   DCHECK(args.length() == 4); |  | 
|   337   CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0); |  | 
|   338   CONVERT_SMI_ARG_CHECKED(literals_index, 1); |  | 
|   339   CONVERT_ARG_HANDLE_CHECKED(FixedArray, constant_properties, 2); |  | 
|   340   CONVERT_SMI_ARG_CHECKED(flags, 3); |  | 
|   341   bool should_have_fast_elements = (flags & ObjectLiteral::kFastElements) != 0; |  | 
|   342   bool has_function_literal = (flags & ObjectLiteral::kHasFunction) != 0; |  | 
|   343  |  | 
|   344   RUNTIME_ASSERT(literals_index >= 0 && literals_index < literals->length()); |  | 
|   345  |  | 
|   346   // Check if boilerplate exists. If not, create it first. |  | 
|   347   Handle<Object> literal_site(literals->get(literals_index), isolate); |  | 
|   348   Handle<AllocationSite> site; |  | 
|   349   Handle<JSObject> boilerplate; |  | 
|   350   if (*literal_site == isolate->heap()->undefined_value()) { |  | 
|   351     Handle<Object> raw_boilerplate; |  | 
|   352     ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |  | 
|   353         isolate, raw_boilerplate, |  | 
|   354         CreateObjectLiteralBoilerplate(isolate, literals, constant_properties, |  | 
|   355                                        should_have_fast_elements, |  | 
|   356                                        has_function_literal)); |  | 
|   357     boilerplate = Handle<JSObject>::cast(raw_boilerplate); |  | 
|   358  |  | 
|   359     AllocationSiteCreationContext creation_context(isolate); |  | 
|   360     site = creation_context.EnterNewScope(); |  | 
|   361     RETURN_FAILURE_ON_EXCEPTION( |  | 
|   362         isolate, JSObject::DeepWalk(boilerplate, &creation_context)); |  | 
|   363     creation_context.ExitScope(site, boilerplate); |  | 
|   364  |  | 
|   365     // Update the functions literal and return the boilerplate. |  | 
|   366     literals->set(literals_index, *site); |  | 
|   367   } else { |  | 
|   368     site = Handle<AllocationSite>::cast(literal_site); |  | 
|   369     boilerplate = |  | 
|   370         Handle<JSObject>(JSObject::cast(site->transition_info()), isolate); |  | 
|   371   } |  | 
|   372  |  | 
|   373   AllocationSiteUsageContext usage_context(isolate, site, true); |  | 
|   374   usage_context.EnterNewScope(); |  | 
|   375   MaybeHandle<Object> maybe_copy = |  | 
|   376       JSObject::DeepCopy(boilerplate, &usage_context); |  | 
|   377   usage_context.ExitScope(site, boilerplate); |  | 
|   378   Handle<Object> copy; |  | 
|   379   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, copy, maybe_copy); |  | 
|   380   return *copy; |  | 
|   381 } |  | 
|   382  |  | 
|   383  |  | 
|   384 MUST_USE_RESULT static MaybeHandle<AllocationSite> GetLiteralAllocationSite( |  | 
|   385     Isolate* isolate, Handle<FixedArray> literals, int literals_index, |  | 
|   386     Handle<FixedArray> elements) { |  | 
|   387   // Check if boilerplate exists. If not, create it first. |  | 
|   388   Handle<Object> literal_site(literals->get(literals_index), isolate); |  | 
|   389   Handle<AllocationSite> site; |  | 
|   390   if (*literal_site == isolate->heap()->undefined_value()) { |  | 
|   391     DCHECK(*elements != isolate->heap()->empty_fixed_array()); |  | 
|   392     Handle<Object> boilerplate; |  | 
|   393     ASSIGN_RETURN_ON_EXCEPTION( |  | 
|   394         isolate, boilerplate, |  | 
|   395         Runtime::CreateArrayLiteralBoilerplate(isolate, literals, elements), |  | 
|   396         AllocationSite); |  | 
|   397  |  | 
|   398     AllocationSiteCreationContext creation_context(isolate); |  | 
|   399     site = creation_context.EnterNewScope(); |  | 
|   400     if (JSObject::DeepWalk(Handle<JSObject>::cast(boilerplate), |  | 
|   401                            &creation_context).is_null()) { |  | 
|   402       return Handle<AllocationSite>::null(); |  | 
|   403     } |  | 
|   404     creation_context.ExitScope(site, Handle<JSObject>::cast(boilerplate)); |  | 
|   405  |  | 
|   406     literals->set(literals_index, *site); |  | 
|   407   } else { |  | 
|   408     site = Handle<AllocationSite>::cast(literal_site); |  | 
|   409   } |  | 
|   410  |  | 
|   411   return site; |  | 
|   412 } |  | 
|   413  |  | 
|   414  |  | 
|   415 static MaybeHandle<JSObject> CreateArrayLiteralImpl(Isolate* isolate, |  | 
|   416                                                     Handle<FixedArray> literals, |  | 
|   417                                                     int literals_index, |  | 
|   418                                                     Handle<FixedArray> elements, |  | 
|   419                                                     int flags) { |  | 
|   420   RUNTIME_ASSERT_HANDLIFIED( |  | 
|   421       literals_index >= 0 && literals_index < literals->length(), JSObject); |  | 
|   422   Handle<AllocationSite> site; |  | 
|   423   ASSIGN_RETURN_ON_EXCEPTION( |  | 
|   424       isolate, site, |  | 
|   425       GetLiteralAllocationSite(isolate, literals, literals_index, elements), |  | 
|   426       JSObject); |  | 
|   427  |  | 
|   428   bool enable_mementos = (flags & ArrayLiteral::kDisableMementos) == 0; |  | 
|   429   Handle<JSObject> boilerplate(JSObject::cast(site->transition_info())); |  | 
|   430   AllocationSiteUsageContext usage_context(isolate, site, enable_mementos); |  | 
|   431   usage_context.EnterNewScope(); |  | 
|   432   JSObject::DeepCopyHints hints = (flags & ArrayLiteral::kShallowElements) == 0 |  | 
|   433                                       ? JSObject::kNoHints |  | 
|   434                                       : JSObject::kObjectIsShallow; |  | 
|   435   MaybeHandle<JSObject> copy = |  | 
|   436       JSObject::DeepCopy(boilerplate, &usage_context, hints); |  | 
|   437   usage_context.ExitScope(site, boilerplate); |  | 
|   438   return copy; |  | 
|   439 } |  | 
|   440  |  | 
|   441  |  | 
|   442 RUNTIME_FUNCTION(Runtime_CreateArrayLiteral) { |  | 
|   443   HandleScope scope(isolate); |  | 
|   444   DCHECK(args.length() == 4); |  | 
|   445   CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0); |  | 
|   446   CONVERT_SMI_ARG_CHECKED(literals_index, 1); |  | 
|   447   CONVERT_ARG_HANDLE_CHECKED(FixedArray, elements, 2); |  | 
|   448   CONVERT_SMI_ARG_CHECKED(flags, 3); |  | 
|   449  |  | 
|   450   Handle<JSObject> result; |  | 
|   451   ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |  | 
|   452       isolate, result, CreateArrayLiteralImpl(isolate, literals, literals_index, |  | 
|   453                                               elements, flags)); |  | 
|   454   return *result; |  | 
|   455 } |  | 
|   456  |  | 
|   457  |  | 
|   458 RUNTIME_FUNCTION(Runtime_CreateArrayLiteralStubBailout) { |  | 
|   459   HandleScope scope(isolate); |  | 
|   460   DCHECK(args.length() == 3); |  | 
|   461   CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0); |  | 
|   462   CONVERT_SMI_ARG_CHECKED(literals_index, 1); |  | 
|   463   CONVERT_ARG_HANDLE_CHECKED(FixedArray, elements, 2); |  | 
|   464  |  | 
|   465   Handle<JSObject> result; |  | 
|   466   ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |  | 
|   467       isolate, result, |  | 
|   468       CreateArrayLiteralImpl(isolate, literals, literals_index, elements, |  | 
|   469                              ArrayLiteral::kShallowElements)); |  | 
|   470   return *result; |  | 
|   471 } |  | 
|   472  |  | 
|   473  |  | 
|   474 RUNTIME_FUNCTION(Runtime_CreateSymbol) { |  | 
|   475   HandleScope scope(isolate); |  | 
|   476   DCHECK(args.length() == 1); |  | 
|   477   CONVERT_ARG_HANDLE_CHECKED(Object, name, 0); |  | 
|   478   RUNTIME_ASSERT(name->IsString() || name->IsUndefined()); |  | 
|   479   Handle<Symbol> symbol = isolate->factory()->NewSymbol(); |  | 
|   480   if (name->IsString()) symbol->set_name(*name); |  | 
|   481   return *symbol; |  | 
|   482 } |  | 
|   483  |  | 
|   484  |  | 
|   485 RUNTIME_FUNCTION(Runtime_CreatePrivateSymbol) { |  | 
|   486   HandleScope scope(isolate); |  | 
|   487   DCHECK(args.length() == 1); |  | 
|   488   CONVERT_ARG_HANDLE_CHECKED(Object, name, 0); |  | 
|   489   RUNTIME_ASSERT(name->IsString() || name->IsUndefined()); |  | 
|   490   Handle<Symbol> symbol = isolate->factory()->NewPrivateSymbol(); |  | 
|   491   if (name->IsString()) symbol->set_name(*name); |  | 
|   492   return *symbol; |  | 
|   493 } |  | 
|   494  |  | 
|   495  |  | 
|   496 RUNTIME_FUNCTION(Runtime_CreatePrivateOwnSymbol) { |  | 
|   497   HandleScope scope(isolate); |  | 
|   498   DCHECK(args.length() == 1); |  | 
|   499   CONVERT_ARG_HANDLE_CHECKED(Object, name, 0); |  | 
|   500   RUNTIME_ASSERT(name->IsString() || name->IsUndefined()); |  | 
|   501   Handle<Symbol> symbol = isolate->factory()->NewPrivateOwnSymbol(); |  | 
|   502   if (name->IsString()) symbol->set_name(*name); |  | 
|   503   return *symbol; |  | 
|   504 } |  | 
|   505  |  | 
|   506  |  | 
|   507 RUNTIME_FUNCTION(Runtime_CreateGlobalPrivateOwnSymbol) { |  | 
|   508   HandleScope scope(isolate); |  | 
|   509   DCHECK(args.length() == 1); |  | 
|   510   CONVERT_ARG_HANDLE_CHECKED(String, name, 0); |  | 
|   511   Handle<JSObject> registry = isolate->GetSymbolRegistry(); |  | 
|   512   Handle<String> part = isolate->factory()->private_intern_string(); |  | 
|   513   Handle<Object> privates; |  | 
|   514   ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |  | 
|   515       isolate, privates, Object::GetPropertyOrElement(registry, part)); |  | 
|   516   Handle<Object> symbol; |  | 
|   517   ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |  | 
|   518       isolate, symbol, Object::GetPropertyOrElement(privates, name)); |  | 
|   519   if (!symbol->IsSymbol()) { |  | 
|   520     DCHECK(symbol->IsUndefined()); |  | 
|   521     symbol = isolate->factory()->NewPrivateSymbol(); |  | 
|   522     Handle<Symbol>::cast(symbol)->set_name(*name); |  | 
|   523     Handle<Symbol>::cast(symbol)->set_is_own(true); |  | 
|   524     JSObject::SetProperty(Handle<JSObject>::cast(privates), name, symbol, |  | 
|   525                           STRICT).Assert(); |  | 
|   526   } |  | 
|   527   return *symbol; |  | 
|   528 } |  | 
|   529  |  | 
|   530  |  | 
|   531 RUNTIME_FUNCTION(Runtime_NewSymbolWrapper) { |  | 
|   532   HandleScope scope(isolate); |  | 
|   533   DCHECK(args.length() == 1); |  | 
|   534   CONVERT_ARG_HANDLE_CHECKED(Symbol, symbol, 0); |  | 
|   535   return *Object::ToObject(isolate, symbol).ToHandleChecked(); |  | 
|   536 } |  | 
|   537  |  | 
|   538  |  | 
|   539 RUNTIME_FUNCTION(Runtime_SymbolDescription) { |  | 
|   540   SealHandleScope shs(isolate); |  | 
|   541   DCHECK(args.length() == 1); |  | 
|   542   CONVERT_ARG_CHECKED(Symbol, symbol, 0); |  | 
|   543   return symbol->name(); |  | 
|   544 } |  | 
|   545  |  | 
|   546  |  | 
|   547 RUNTIME_FUNCTION(Runtime_SymbolRegistry) { |  | 
|   548   HandleScope scope(isolate); |  | 
|   549   DCHECK(args.length() == 0); |  | 
|   550   return *isolate->GetSymbolRegistry(); |  | 
|   551 } |  | 
|   552  |  | 
|   553  |  | 
|   554 RUNTIME_FUNCTION(Runtime_SymbolIsPrivate) { |  | 
|   555   SealHandleScope shs(isolate); |  | 
|   556   DCHECK(args.length() == 1); |  | 
|   557   CONVERT_ARG_CHECKED(Symbol, symbol, 0); |  | 
|   558   return isolate->heap()->ToBoolean(symbol->is_private()); |  | 
|   559 } |  | 
|   560  |  | 
|   561  |  | 
|   562 RUNTIME_FUNCTION(Runtime_CreateJSProxy) { |  | 
|   563   HandleScope scope(isolate); |  | 
|   564   DCHECK(args.length() == 2); |  | 
|   565   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, handler, 0); |  | 
|   566   CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1); |  | 
|   567   if (!prototype->IsJSReceiver()) prototype = isolate->factory()->null_value(); |  | 
|   568   return *isolate->factory()->NewJSProxy(handler, prototype); |  | 
|   569 } |  | 
|   570  |  | 
|   571  |  | 
|   572 RUNTIME_FUNCTION(Runtime_CreateJSFunctionProxy) { |  | 
|   573   HandleScope scope(isolate); |  | 
|   574   DCHECK(args.length() == 4); |  | 
|   575   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, handler, 0); |  | 
|   576   CONVERT_ARG_HANDLE_CHECKED(Object, call_trap, 1); |  | 
|   577   RUNTIME_ASSERT(call_trap->IsJSFunction() || call_trap->IsJSFunctionProxy()); |  | 
|   578   CONVERT_ARG_HANDLE_CHECKED(JSFunction, construct_trap, 2); |  | 
|   579   CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 3); |  | 
|   580   if (!prototype->IsJSReceiver()) prototype = isolate->factory()->null_value(); |  | 
|   581   return *isolate->factory()->NewJSFunctionProxy(handler, call_trap, |  | 
|   582                                                  construct_trap, prototype); |  | 
|   583 } |  | 
|   584  |  | 
|   585  |  | 
|   586 RUNTIME_FUNCTION(Runtime_IsJSProxy) { |  | 
|   587   SealHandleScope shs(isolate); |  | 
|   588   DCHECK(args.length() == 1); |  | 
|   589   CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0); |  | 
|   590   return isolate->heap()->ToBoolean(obj->IsJSProxy()); |  | 
|   591 } |  | 
|   592  |  | 
|   593  |  | 
|   594 RUNTIME_FUNCTION(Runtime_IsJSFunctionProxy) { |  | 
|   595   SealHandleScope shs(isolate); |  | 
|   596   DCHECK(args.length() == 1); |  | 
|   597   CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0); |  | 
|   598   return isolate->heap()->ToBoolean(obj->IsJSFunctionProxy()); |  | 
|   599 } |  | 
|   600  |  | 
|   601  |  | 
|   602 RUNTIME_FUNCTION(Runtime_GetHandler) { |  | 
|   603   SealHandleScope shs(isolate); |  | 
|   604   DCHECK(args.length() == 1); |  | 
|   605   CONVERT_ARG_CHECKED(JSProxy, proxy, 0); |  | 
|   606   return proxy->handler(); |  | 
|   607 } |  | 
|   608  |  | 
|   609  |  | 
|   610 RUNTIME_FUNCTION(Runtime_GetCallTrap) { |  | 
|   611   SealHandleScope shs(isolate); |  | 
|   612   DCHECK(args.length() == 1); |  | 
|   613   CONVERT_ARG_CHECKED(JSFunctionProxy, proxy, 0); |  | 
|   614   return proxy->call_trap(); |  | 
|   615 } |  | 
|   616  |  | 
|   617  |  | 
|   618 RUNTIME_FUNCTION(Runtime_GetConstructTrap) { |  | 
|   619   SealHandleScope shs(isolate); |  | 
|   620   DCHECK(args.length() == 1); |  | 
|   621   CONVERT_ARG_CHECKED(JSFunctionProxy, proxy, 0); |  | 
|   622   return proxy->construct_trap(); |  | 
|   623 } |  | 
|   624  |  | 
|   625  |  | 
|   626 RUNTIME_FUNCTION(Runtime_Fix) { |  | 
|   627   HandleScope scope(isolate); |  | 
|   628   DCHECK(args.length() == 1); |  | 
|   629   CONVERT_ARG_HANDLE_CHECKED(JSProxy, proxy, 0); |  | 
|   630   JSProxy::Fix(proxy); |  | 
|   631   return isolate->heap()->undefined_value(); |  | 
|   632 } |  | 
|   633  |  | 
|   634  |  | 
|   635 RUNTIME_FUNCTION(Runtime_GetPrototype) { |    70 RUNTIME_FUNCTION(Runtime_GetPrototype) { | 
|   636   HandleScope scope(isolate); |    71   HandleScope scope(isolate); | 
|   637   DCHECK(args.length() == 1); |    72   DCHECK(args.length() == 1); | 
|   638   CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0); |    73   CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0); | 
|   639   // We don't expect access checks to be needed on JSProxy objects. |    74   // We don't expect access checks to be needed on JSProxy objects. | 
|   640   DCHECK(!obj->IsAccessCheckNeeded() || obj->IsJSObject()); |    75   DCHECK(!obj->IsAccessCheckNeeded() || obj->IsJSObject()); | 
|   641   PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER); |    76   PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER); | 
|   642   do { |    77   do { | 
|   643     if (PrototypeIterator::GetCurrent(iter)->IsAccessCheckNeeded() && |    78     if (PrototypeIterator::GetCurrent(iter)->IsAccessCheckNeeded() && | 
|   644         !isolate->MayNamedAccess( |    79         !isolate->MayNamedAccess( | 
| (...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1000   Handle<Map> old_map(object->map()); |   435   Handle<Map> old_map(object->map()); | 
|  1001   RUNTIME_ASSERT(!old_map->is_access_check_needed()); |   436   RUNTIME_ASSERT(!old_map->is_access_check_needed()); | 
|  1002   // Copy map so it won't interfere constructor's initial map. |   437   // Copy map so it won't interfere constructor's initial map. | 
|  1003   Handle<Map> new_map = Map::Copy(old_map); |   438   Handle<Map> new_map = Map::Copy(old_map); | 
|  1004   new_map->set_is_access_check_needed(true); |   439   new_map->set_is_access_check_needed(true); | 
|  1005   JSObject::MigrateToMap(object, new_map); |   440   JSObject::MigrateToMap(object, new_map); | 
|  1006   return isolate->heap()->undefined_value(); |   441   return isolate->heap()->undefined_value(); | 
|  1007 } |   442 } | 
|  1008  |   443  | 
|  1009  |   444  | 
|  1010 static Object* ThrowRedeclarationError(Isolate* isolate, Handle<String> name) { |  | 
|  1011   HandleScope scope(isolate); |  | 
|  1012   Handle<Object> args[1] = {name}; |  | 
|  1013   THROW_NEW_ERROR_RETURN_FAILURE( |  | 
|  1014       isolate, NewTypeError("var_redeclaration", HandleVector(args, 1))); |  | 
|  1015 } |  | 
|  1016  |  | 
|  1017  |  | 
|  1018 // May throw a RedeclarationError. |  | 
|  1019 static Object* DeclareGlobals(Isolate* isolate, Handle<GlobalObject> global, |  | 
|  1020                               Handle<String> name, Handle<Object> value, |  | 
|  1021                               PropertyAttributes attr, bool is_var, |  | 
|  1022                               bool is_const, bool is_function) { |  | 
|  1023   // Do the lookup own properties only, see ES5 erratum. |  | 
|  1024   LookupIterator it(global, name, LookupIterator::HIDDEN_SKIP_INTERCEPTOR); |  | 
|  1025   Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it); |  | 
|  1026   if (!maybe.has_value) return isolate->heap()->exception(); |  | 
|  1027  |  | 
|  1028   if (it.IsFound()) { |  | 
|  1029     PropertyAttributes old_attributes = maybe.value; |  | 
|  1030     // The name was declared before; check for conflicting re-declarations. |  | 
|  1031     if (is_const) return ThrowRedeclarationError(isolate, name); |  | 
|  1032  |  | 
|  1033     // Skip var re-declarations. |  | 
|  1034     if (is_var) return isolate->heap()->undefined_value(); |  | 
|  1035  |  | 
|  1036     DCHECK(is_function); |  | 
|  1037     if ((old_attributes & DONT_DELETE) != 0) { |  | 
|  1038       // Only allow reconfiguring globals to functions in user code (no |  | 
|  1039       // natives, which are marked as read-only). |  | 
|  1040       DCHECK((attr & READ_ONLY) == 0); |  | 
|  1041  |  | 
|  1042       // Check whether we can reconfigure the existing property into a |  | 
|  1043       // function. |  | 
|  1044       PropertyDetails old_details = it.property_details(); |  | 
|  1045       // TODO(verwaest): CALLBACKS invalidly includes ExecutableAccessInfo, |  | 
|  1046       // which are actually data properties, not accessor properties. |  | 
|  1047       if (old_details.IsReadOnly() || old_details.IsDontEnum() || |  | 
|  1048           old_details.type() == CALLBACKS) { |  | 
|  1049         return ThrowRedeclarationError(isolate, name); |  | 
|  1050       } |  | 
|  1051       // If the existing property is not configurable, keep its attributes. Do |  | 
|  1052       attr = old_attributes; |  | 
|  1053     } |  | 
|  1054   } |  | 
|  1055  |  | 
|  1056   // Define or redefine own property. |  | 
|  1057   RETURN_FAILURE_ON_EXCEPTION(isolate, JSObject::SetOwnPropertyIgnoreAttributes( |  | 
|  1058                                            global, name, value, attr)); |  | 
|  1059  |  | 
|  1060   return isolate->heap()->undefined_value(); |  | 
|  1061 } |  | 
|  1062  |  | 
|  1063  |  | 
|  1064 RUNTIME_FUNCTION(Runtime_DeclareGlobals) { |  | 
|  1065   HandleScope scope(isolate); |  | 
|  1066   DCHECK(args.length() == 3); |  | 
|  1067   Handle<GlobalObject> global(isolate->global_object()); |  | 
|  1068  |  | 
|  1069   CONVERT_ARG_HANDLE_CHECKED(Context, context, 0); |  | 
|  1070   CONVERT_ARG_HANDLE_CHECKED(FixedArray, pairs, 1); |  | 
|  1071   CONVERT_SMI_ARG_CHECKED(flags, 2); |  | 
|  1072  |  | 
|  1073   // Traverse the name/value pairs and set the properties. |  | 
|  1074   int length = pairs->length(); |  | 
|  1075   for (int i = 0; i < length; i += 2) { |  | 
|  1076     HandleScope scope(isolate); |  | 
|  1077     Handle<String> name(String::cast(pairs->get(i))); |  | 
|  1078     Handle<Object> initial_value(pairs->get(i + 1), isolate); |  | 
|  1079  |  | 
|  1080     // We have to declare a global const property. To capture we only |  | 
|  1081     // assign to it when evaluating the assignment for "const x = |  | 
|  1082     // <expr>" the initial value is the hole. |  | 
|  1083     bool is_var = initial_value->IsUndefined(); |  | 
|  1084     bool is_const = initial_value->IsTheHole(); |  | 
|  1085     bool is_function = initial_value->IsSharedFunctionInfo(); |  | 
|  1086     DCHECK(is_var + is_const + is_function == 1); |  | 
|  1087  |  | 
|  1088     Handle<Object> value; |  | 
|  1089     if (is_function) { |  | 
|  1090       // Copy the function and update its context. Use it as value. |  | 
|  1091       Handle<SharedFunctionInfo> shared = |  | 
|  1092           Handle<SharedFunctionInfo>::cast(initial_value); |  | 
|  1093       Handle<JSFunction> function = |  | 
|  1094           isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, context, |  | 
|  1095                                                                 TENURED); |  | 
|  1096       value = function; |  | 
|  1097     } else { |  | 
|  1098       value = isolate->factory()->undefined_value(); |  | 
|  1099     } |  | 
|  1100  |  | 
|  1101     // Compute the property attributes. According to ECMA-262, |  | 
|  1102     // the property must be non-configurable except in eval. |  | 
|  1103     bool is_native = DeclareGlobalsNativeFlag::decode(flags); |  | 
|  1104     bool is_eval = DeclareGlobalsEvalFlag::decode(flags); |  | 
|  1105     int attr = NONE; |  | 
|  1106     if (is_const) attr |= READ_ONLY; |  | 
|  1107     if (is_function && is_native) attr |= READ_ONLY; |  | 
|  1108     if (!is_const && !is_eval) attr |= DONT_DELETE; |  | 
|  1109  |  | 
|  1110     Object* result = DeclareGlobals(isolate, global, name, value, |  | 
|  1111                                     static_cast<PropertyAttributes>(attr), |  | 
|  1112                                     is_var, is_const, is_function); |  | 
|  1113     if (isolate->has_pending_exception()) return result; |  | 
|  1114   } |  | 
|  1115  |  | 
|  1116   return isolate->heap()->undefined_value(); |  | 
|  1117 } |  | 
|  1118  |  | 
|  1119  |  | 
|  1120 RUNTIME_FUNCTION(Runtime_InitializeVarGlobal) { |  | 
|  1121   HandleScope scope(isolate); |  | 
|  1122   // args[0] == name |  | 
|  1123   // args[1] == language_mode |  | 
|  1124   // args[2] == value (optional) |  | 
|  1125  |  | 
|  1126   // Determine if we need to assign to the variable if it already |  | 
|  1127   // exists (based on the number of arguments). |  | 
|  1128   RUNTIME_ASSERT(args.length() == 3); |  | 
|  1129  |  | 
|  1130   CONVERT_ARG_HANDLE_CHECKED(String, name, 0); |  | 
|  1131   CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 1); |  | 
|  1132   CONVERT_ARG_HANDLE_CHECKED(Object, value, 2); |  | 
|  1133  |  | 
|  1134   Handle<GlobalObject> global(isolate->context()->global_object()); |  | 
|  1135   Handle<Object> result; |  | 
|  1136   ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |  | 
|  1137       isolate, result, Object::SetProperty(global, name, value, strict_mode)); |  | 
|  1138   return *result; |  | 
|  1139 } |  | 
|  1140  |  | 
|  1141  |  | 
|  1142 RUNTIME_FUNCTION(Runtime_InitializeConstGlobal) { |  | 
|  1143   HandleScope handle_scope(isolate); |  | 
|  1144   // All constants are declared with an initial value. The name |  | 
|  1145   // of the constant is the first argument and the initial value |  | 
|  1146   // is the second. |  | 
|  1147   RUNTIME_ASSERT(args.length() == 2); |  | 
|  1148   CONVERT_ARG_HANDLE_CHECKED(String, name, 0); |  | 
|  1149   CONVERT_ARG_HANDLE_CHECKED(Object, value, 1); |  | 
|  1150  |  | 
|  1151   Handle<GlobalObject> global = isolate->global_object(); |  | 
|  1152  |  | 
|  1153   // Lookup the property as own on the global object. |  | 
|  1154   LookupIterator it(global, name, LookupIterator::HIDDEN_SKIP_INTERCEPTOR); |  | 
|  1155   Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it); |  | 
|  1156   DCHECK(maybe.has_value); |  | 
|  1157   PropertyAttributes old_attributes = maybe.value; |  | 
|  1158  |  | 
|  1159   PropertyAttributes attr = |  | 
|  1160       static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY); |  | 
|  1161   // Set the value if the property is either missing, or the property attributes |  | 
|  1162   // allow setting the value without invoking an accessor. |  | 
|  1163   if (it.IsFound()) { |  | 
|  1164     // Ignore if we can't reconfigure the value. |  | 
|  1165     if ((old_attributes & DONT_DELETE) != 0) { |  | 
|  1166       if ((old_attributes & READ_ONLY) != 0 || |  | 
|  1167           it.state() == LookupIterator::ACCESSOR) { |  | 
|  1168         return *value; |  | 
|  1169       } |  | 
|  1170       attr = static_cast<PropertyAttributes>(old_attributes | READ_ONLY); |  | 
|  1171     } |  | 
|  1172   } |  | 
|  1173  |  | 
|  1174   RETURN_FAILURE_ON_EXCEPTION(isolate, JSObject::SetOwnPropertyIgnoreAttributes( |  | 
|  1175                                            global, name, value, attr)); |  | 
|  1176  |  | 
|  1177   return *value; |  | 
|  1178 } |  | 
|  1179  |  | 
|  1180  |  | 
|  1181 RUNTIME_FUNCTION(Runtime_DeclareLookupSlot) { |  | 
|  1182   HandleScope scope(isolate); |  | 
|  1183   DCHECK(args.length() == 4); |  | 
|  1184  |  | 
|  1185   // Declarations are always made in a function, native, or global context. In |  | 
|  1186   // the case of eval code, the context passed is the context of the caller, |  | 
|  1187   // which may be some nested context and not the declaration context. |  | 
|  1188   CONVERT_ARG_HANDLE_CHECKED(Context, context_arg, 0); |  | 
|  1189   Handle<Context> context(context_arg->declaration_context()); |  | 
|  1190   CONVERT_ARG_HANDLE_CHECKED(String, name, 1); |  | 
|  1191   CONVERT_SMI_ARG_CHECKED(attr_arg, 2); |  | 
|  1192   PropertyAttributes attr = static_cast<PropertyAttributes>(attr_arg); |  | 
|  1193   RUNTIME_ASSERT(attr == READ_ONLY || attr == NONE); |  | 
|  1194   CONVERT_ARG_HANDLE_CHECKED(Object, initial_value, 3); |  | 
|  1195  |  | 
|  1196   // TODO(verwaest): Unify the encoding indicating "var" with DeclareGlobals. |  | 
|  1197   bool is_var = *initial_value == NULL; |  | 
|  1198   bool is_const = initial_value->IsTheHole(); |  | 
|  1199   bool is_function = initial_value->IsJSFunction(); |  | 
|  1200   DCHECK(is_var + is_const + is_function == 1); |  | 
|  1201  |  | 
|  1202   int index; |  | 
|  1203   PropertyAttributes attributes; |  | 
|  1204   ContextLookupFlags flags = DONT_FOLLOW_CHAINS; |  | 
|  1205   BindingFlags binding_flags; |  | 
|  1206   Handle<Object> holder = |  | 
|  1207       context->Lookup(name, flags, &index, &attributes, &binding_flags); |  | 
|  1208  |  | 
|  1209   Handle<JSObject> object; |  | 
|  1210   Handle<Object> value = |  | 
|  1211       is_function ? initial_value |  | 
|  1212                   : Handle<Object>::cast(isolate->factory()->undefined_value()); |  | 
|  1213  |  | 
|  1214   // TODO(verwaest): This case should probably not be covered by this function, |  | 
|  1215   // but by DeclareGlobals instead. |  | 
|  1216   if ((attributes != ABSENT && holder->IsJSGlobalObject()) || |  | 
|  1217       (context_arg->has_extension() && |  | 
|  1218        context_arg->extension()->IsJSGlobalObject())) { |  | 
|  1219     return DeclareGlobals(isolate, Handle<JSGlobalObject>::cast(holder), name, |  | 
|  1220                           value, attr, is_var, is_const, is_function); |  | 
|  1221   } |  | 
|  1222  |  | 
|  1223   if (attributes != ABSENT) { |  | 
|  1224     // The name was declared before; check for conflicting re-declarations. |  | 
|  1225     if (is_const || (attributes & READ_ONLY) != 0) { |  | 
|  1226       return ThrowRedeclarationError(isolate, name); |  | 
|  1227     } |  | 
|  1228  |  | 
|  1229     // Skip var re-declarations. |  | 
|  1230     if (is_var) return isolate->heap()->undefined_value(); |  | 
|  1231  |  | 
|  1232     DCHECK(is_function); |  | 
|  1233     if (index >= 0) { |  | 
|  1234       DCHECK(holder.is_identical_to(context)); |  | 
|  1235       context->set(index, *initial_value); |  | 
|  1236       return isolate->heap()->undefined_value(); |  | 
|  1237     } |  | 
|  1238  |  | 
|  1239     object = Handle<JSObject>::cast(holder); |  | 
|  1240  |  | 
|  1241   } else if (context->has_extension()) { |  | 
|  1242     object = handle(JSObject::cast(context->extension())); |  | 
|  1243     DCHECK(object->IsJSContextExtensionObject() || object->IsJSGlobalObject()); |  | 
|  1244   } else { |  | 
|  1245     DCHECK(context->IsFunctionContext()); |  | 
|  1246     object = |  | 
|  1247         isolate->factory()->NewJSObject(isolate->context_extension_function()); |  | 
|  1248     context->set_extension(*object); |  | 
|  1249   } |  | 
|  1250  |  | 
|  1251   RETURN_FAILURE_ON_EXCEPTION(isolate, JSObject::SetOwnPropertyIgnoreAttributes( |  | 
|  1252                                            object, name, value, attr)); |  | 
|  1253  |  | 
|  1254   return isolate->heap()->undefined_value(); |  | 
|  1255 } |  | 
|  1256  |  | 
|  1257  |  | 
|  1258 RUNTIME_FUNCTION(Runtime_InitializeLegacyConstLookupSlot) { |  | 
|  1259   HandleScope scope(isolate); |  | 
|  1260   DCHECK(args.length() == 3); |  | 
|  1261  |  | 
|  1262   CONVERT_ARG_HANDLE_CHECKED(Object, value, 0); |  | 
|  1263   DCHECK(!value->IsTheHole()); |  | 
|  1264   // Initializations are always done in a function or native context. |  | 
|  1265   CONVERT_ARG_HANDLE_CHECKED(Context, context_arg, 1); |  | 
|  1266   Handle<Context> context(context_arg->declaration_context()); |  | 
|  1267   CONVERT_ARG_HANDLE_CHECKED(String, name, 2); |  | 
|  1268  |  | 
|  1269   int index; |  | 
|  1270   PropertyAttributes attributes; |  | 
|  1271   ContextLookupFlags flags = DONT_FOLLOW_CHAINS; |  | 
|  1272   BindingFlags binding_flags; |  | 
|  1273   Handle<Object> holder = |  | 
|  1274       context->Lookup(name, flags, &index, &attributes, &binding_flags); |  | 
|  1275  |  | 
|  1276   if (index >= 0) { |  | 
|  1277     DCHECK(holder->IsContext()); |  | 
|  1278     // Property was found in a context.  Perform the assignment if the constant |  | 
|  1279     // was uninitialized. |  | 
|  1280     Handle<Context> context = Handle<Context>::cast(holder); |  | 
|  1281     DCHECK((attributes & READ_ONLY) != 0); |  | 
|  1282     if (context->get(index)->IsTheHole()) context->set(index, *value); |  | 
|  1283     return *value; |  | 
|  1284   } |  | 
|  1285  |  | 
|  1286   PropertyAttributes attr = |  | 
|  1287       static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY); |  | 
|  1288  |  | 
|  1289   // Strict mode handling not needed (legacy const is disallowed in strict |  | 
|  1290   // mode). |  | 
|  1291  |  | 
|  1292   // The declared const was configurable, and may have been deleted in the |  | 
|  1293   // meanwhile. If so, re-introduce the variable in the context extension. |  | 
|  1294   DCHECK(context_arg->has_extension()); |  | 
|  1295   if (attributes == ABSENT) { |  | 
|  1296     holder = handle(context_arg->extension(), isolate); |  | 
|  1297   } else { |  | 
|  1298     // For JSContextExtensionObjects, the initializer can be run multiple times |  | 
|  1299     // if in a for loop: for (var i = 0; i < 2; i++) { const x = i; }. Only the |  | 
|  1300     // first assignment should go through. For JSGlobalObjects, additionally any |  | 
|  1301     // code can run in between that modifies the declared property. |  | 
|  1302     DCHECK(holder->IsJSGlobalObject() || holder->IsJSContextExtensionObject()); |  | 
|  1303  |  | 
|  1304     LookupIterator it(holder, name, LookupIterator::HIDDEN_SKIP_INTERCEPTOR); |  | 
|  1305     Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it); |  | 
|  1306     if (!maybe.has_value) return isolate->heap()->exception(); |  | 
|  1307     PropertyAttributes old_attributes = maybe.value; |  | 
|  1308  |  | 
|  1309     // Ignore if we can't reconfigure the value. |  | 
|  1310     if ((old_attributes & DONT_DELETE) != 0) { |  | 
|  1311       if ((old_attributes & READ_ONLY) != 0 || |  | 
|  1312           it.state() == LookupIterator::ACCESSOR) { |  | 
|  1313         return *value; |  | 
|  1314       } |  | 
|  1315       attr = static_cast<PropertyAttributes>(old_attributes | READ_ONLY); |  | 
|  1316     } |  | 
|  1317   } |  | 
|  1318  |  | 
|  1319   RETURN_FAILURE_ON_EXCEPTION( |  | 
|  1320       isolate, JSObject::SetOwnPropertyIgnoreAttributes( |  | 
|  1321                    Handle<JSObject>::cast(holder), name, value, attr)); |  | 
|  1322  |  | 
|  1323   return *value; |  | 
|  1324 } |  | 
|  1325  |  | 
|  1326  |  | 
|  1327 RUNTIME_FUNCTION(Runtime_OptimizeObjectForAddingMultipleProperties) { |   445 RUNTIME_FUNCTION(Runtime_OptimizeObjectForAddingMultipleProperties) { | 
|  1328   HandleScope scope(isolate); |   446   HandleScope scope(isolate); | 
|  1329   DCHECK(args.length() == 2); |   447   DCHECK(args.length() == 2); | 
|  1330   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); |   448   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); | 
|  1331   CONVERT_SMI_ARG_CHECKED(properties, 1); |   449   CONVERT_SMI_ARG_CHECKED(properties, 1); | 
|  1332   // Conservative upper limit to prevent fuzz tests from going OOM. |   450   // Conservative upper limit to prevent fuzz tests from going OOM. | 
|  1333   RUNTIME_ASSERT(properties <= 100000); |   451   RUNTIME_ASSERT(properties <= 100000); | 
|  1334   if (object->HasFastProperties() && !object->IsJSGlobalProxy()) { |   452   if (object->HasFastProperties() && !object->IsJSGlobalProxy()) { | 
|  1335     JSObject::NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, properties); |   453     JSObject::NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, properties); | 
|  1336   } |   454   } | 
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1374   InstallBuiltin(isolate, holder, "shift", Builtins::kArrayShift); |   492   InstallBuiltin(isolate, holder, "shift", Builtins::kArrayShift); | 
|  1375   InstallBuiltin(isolate, holder, "unshift", Builtins::kArrayUnshift); |   493   InstallBuiltin(isolate, holder, "unshift", Builtins::kArrayUnshift); | 
|  1376   InstallBuiltin(isolate, holder, "slice", Builtins::kArraySlice); |   494   InstallBuiltin(isolate, holder, "slice", Builtins::kArraySlice); | 
|  1377   InstallBuiltin(isolate, holder, "splice", Builtins::kArraySplice); |   495   InstallBuiltin(isolate, holder, "splice", Builtins::kArraySplice); | 
|  1378   InstallBuiltin(isolate, holder, "concat", Builtins::kArrayConcat); |   496   InstallBuiltin(isolate, holder, "concat", Builtins::kArrayConcat); | 
|  1379  |   497  | 
|  1380   return *holder; |   498   return *holder; | 
|  1381 } |   499 } | 
|  1382  |   500  | 
|  1383  |   501  | 
|  1384 RUNTIME_FUNCTION(Runtime_IsSloppyModeFunction) { |  | 
|  1385   SealHandleScope shs(isolate); |  | 
|  1386   DCHECK(args.length() == 1); |  | 
|  1387   CONVERT_ARG_CHECKED(JSReceiver, callable, 0); |  | 
|  1388   if (!callable->IsJSFunction()) { |  | 
|  1389     HandleScope scope(isolate); |  | 
|  1390     Handle<Object> delegate; |  | 
|  1391     ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |  | 
|  1392         isolate, delegate, Execution::TryGetFunctionDelegate( |  | 
|  1393                                isolate, Handle<JSReceiver>(callable))); |  | 
|  1394     callable = JSFunction::cast(*delegate); |  | 
|  1395   } |  | 
|  1396   JSFunction* function = JSFunction::cast(callable); |  | 
|  1397   SharedFunctionInfo* shared = function->shared(); |  | 
|  1398   return isolate->heap()->ToBoolean(shared->strict_mode() == SLOPPY); |  | 
|  1399 } |  | 
|  1400  |  | 
|  1401  |  | 
|  1402 RUNTIME_FUNCTION(Runtime_GetDefaultReceiver) { |  | 
|  1403   SealHandleScope shs(isolate); |  | 
|  1404   DCHECK(args.length() == 1); |  | 
|  1405   CONVERT_ARG_CHECKED(JSReceiver, callable, 0); |  | 
|  1406  |  | 
|  1407   if (!callable->IsJSFunction()) { |  | 
|  1408     HandleScope scope(isolate); |  | 
|  1409     Handle<Object> delegate; |  | 
|  1410     ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |  | 
|  1411         isolate, delegate, Execution::TryGetFunctionDelegate( |  | 
|  1412                                isolate, Handle<JSReceiver>(callable))); |  | 
|  1413     callable = JSFunction::cast(*delegate); |  | 
|  1414   } |  | 
|  1415   JSFunction* function = JSFunction::cast(callable); |  | 
|  1416  |  | 
|  1417   SharedFunctionInfo* shared = function->shared(); |  | 
|  1418   if (shared->native() || shared->strict_mode() == STRICT) { |  | 
|  1419     return isolate->heap()->undefined_value(); |  | 
|  1420   } |  | 
|  1421   // Returns undefined for strict or native functions, or |  | 
|  1422   // the associated global receiver for "normal" functions. |  | 
|  1423  |  | 
|  1424   return function->global_proxy(); |  | 
|  1425 } |  | 
|  1426  |  | 
|  1427  |  | 
|  1428 RUNTIME_FUNCTION(Runtime_FunctionGetName) { |  | 
|  1429   SealHandleScope shs(isolate); |  | 
|  1430   DCHECK(args.length() == 1); |  | 
|  1431  |  | 
|  1432   CONVERT_ARG_CHECKED(JSFunction, f, 0); |  | 
|  1433   return f->shared()->name(); |  | 
|  1434 } |  | 
|  1435  |  | 
|  1436  |  | 
|  1437 RUNTIME_FUNCTION(Runtime_FunctionSetName) { |  | 
|  1438   SealHandleScope shs(isolate); |  | 
|  1439   DCHECK(args.length() == 2); |  | 
|  1440  |  | 
|  1441   CONVERT_ARG_CHECKED(JSFunction, f, 0); |  | 
|  1442   CONVERT_ARG_CHECKED(String, name, 1); |  | 
|  1443   f->shared()->set_name(name); |  | 
|  1444   return isolate->heap()->undefined_value(); |  | 
|  1445 } |  | 
|  1446  |  | 
|  1447  |  | 
|  1448 RUNTIME_FUNCTION(Runtime_FunctionNameShouldPrintAsAnonymous) { |  | 
|  1449   SealHandleScope shs(isolate); |  | 
|  1450   DCHECK(args.length() == 1); |  | 
|  1451   CONVERT_ARG_CHECKED(JSFunction, f, 0); |  | 
|  1452   return isolate->heap()->ToBoolean( |  | 
|  1453       f->shared()->name_should_print_as_anonymous()); |  | 
|  1454 } |  | 
|  1455  |  | 
|  1456  |  | 
|  1457 RUNTIME_FUNCTION(Runtime_FunctionMarkNameShouldPrintAsAnonymous) { |  | 
|  1458   SealHandleScope shs(isolate); |  | 
|  1459   DCHECK(args.length() == 1); |  | 
|  1460   CONVERT_ARG_CHECKED(JSFunction, f, 0); |  | 
|  1461   f->shared()->set_name_should_print_as_anonymous(true); |  | 
|  1462   return isolate->heap()->undefined_value(); |  | 
|  1463 } |  | 
|  1464  |  | 
|  1465  |  | 
|  1466 RUNTIME_FUNCTION(Runtime_FunctionIsArrow) { |  | 
|  1467   SealHandleScope shs(isolate); |  | 
|  1468   DCHECK(args.length() == 1); |  | 
|  1469   CONVERT_ARG_CHECKED(JSFunction, f, 0); |  | 
|  1470   return isolate->heap()->ToBoolean(f->shared()->is_arrow()); |  | 
|  1471 } |  | 
|  1472  |  | 
|  1473  |  | 
|  1474 RUNTIME_FUNCTION(Runtime_FunctionIsConciseMethod) { |  | 
|  1475   SealHandleScope shs(isolate); |  | 
|  1476   DCHECK(args.length() == 1); |  | 
|  1477   CONVERT_ARG_CHECKED(JSFunction, f, 0); |  | 
|  1478   return isolate->heap()->ToBoolean(f->shared()->is_concise_method()); |  | 
|  1479 } |  | 
|  1480  |  | 
|  1481  |  | 
|  1482 RUNTIME_FUNCTION(Runtime_FunctionRemovePrototype) { |  | 
|  1483   SealHandleScope shs(isolate); |  | 
|  1484   DCHECK(args.length() == 1); |  | 
|  1485  |  | 
|  1486   CONVERT_ARG_CHECKED(JSFunction, f, 0); |  | 
|  1487   RUNTIME_ASSERT(f->RemovePrototype()); |  | 
|  1488  |  | 
|  1489   return isolate->heap()->undefined_value(); |  | 
|  1490 } |  | 
|  1491  |  | 
|  1492  |  | 
|  1493 RUNTIME_FUNCTION(Runtime_FunctionGetScript) { |  | 
|  1494   HandleScope scope(isolate); |  | 
|  1495   DCHECK(args.length() == 1); |  | 
|  1496  |  | 
|  1497   CONVERT_ARG_CHECKED(JSFunction, fun, 0); |  | 
|  1498   Handle<Object> script = Handle<Object>(fun->shared()->script(), isolate); |  | 
|  1499   if (!script->IsScript()) return isolate->heap()->undefined_value(); |  | 
|  1500  |  | 
|  1501   return *Script::GetWrapper(Handle<Script>::cast(script)); |  | 
|  1502 } |  | 
|  1503  |  | 
|  1504  |  | 
|  1505 RUNTIME_FUNCTION(Runtime_FunctionGetSourceCode) { |  | 
|  1506   HandleScope scope(isolate); |  | 
|  1507   DCHECK(args.length() == 1); |  | 
|  1508  |  | 
|  1509   CONVERT_ARG_HANDLE_CHECKED(JSFunction, f, 0); |  | 
|  1510   Handle<SharedFunctionInfo> shared(f->shared()); |  | 
|  1511   return *shared->GetSourceCode(); |  | 
|  1512 } |  | 
|  1513  |  | 
|  1514  |  | 
|  1515 RUNTIME_FUNCTION(Runtime_FunctionGetScriptSourcePosition) { |  | 
|  1516   SealHandleScope shs(isolate); |  | 
|  1517   DCHECK(args.length() == 1); |  | 
|  1518  |  | 
|  1519   CONVERT_ARG_CHECKED(JSFunction, fun, 0); |  | 
|  1520   int pos = fun->shared()->start_position(); |  | 
|  1521   return Smi::FromInt(pos); |  | 
|  1522 } |  | 
|  1523  |  | 
|  1524  |  | 
|  1525 RUNTIME_FUNCTION(Runtime_FunctionGetPositionForOffset) { |  | 
|  1526   SealHandleScope shs(isolate); |  | 
|  1527   DCHECK(args.length() == 2); |  | 
|  1528  |  | 
|  1529   CONVERT_ARG_CHECKED(Code, code, 0); |  | 
|  1530   CONVERT_NUMBER_CHECKED(int, offset, Int32, args[1]); |  | 
|  1531  |  | 
|  1532   RUNTIME_ASSERT(0 <= offset && offset < code->Size()); |  | 
|  1533  |  | 
|  1534   Address pc = code->address() + offset; |  | 
|  1535   return Smi::FromInt(code->SourcePosition(pc)); |  | 
|  1536 } |  | 
|  1537  |  | 
|  1538  |  | 
|  1539 RUNTIME_FUNCTION(Runtime_FunctionSetInstanceClassName) { |  | 
|  1540   SealHandleScope shs(isolate); |  | 
|  1541   DCHECK(args.length() == 2); |  | 
|  1542  |  | 
|  1543   CONVERT_ARG_CHECKED(JSFunction, fun, 0); |  | 
|  1544   CONVERT_ARG_CHECKED(String, name, 1); |  | 
|  1545   fun->SetInstanceClassName(name); |  | 
|  1546   return isolate->heap()->undefined_value(); |  | 
|  1547 } |  | 
|  1548  |  | 
|  1549  |  | 
|  1550 RUNTIME_FUNCTION(Runtime_FunctionSetLength) { |  | 
|  1551   SealHandleScope shs(isolate); |  | 
|  1552   DCHECK(args.length() == 2); |  | 
|  1553  |  | 
|  1554   CONVERT_ARG_CHECKED(JSFunction, fun, 0); |  | 
|  1555   CONVERT_SMI_ARG_CHECKED(length, 1); |  | 
|  1556   RUNTIME_ASSERT((length & 0xC0000000) == 0xC0000000 || |  | 
|  1557                  (length & 0xC0000000) == 0x0); |  | 
|  1558   fun->shared()->set_length(length); |  | 
|  1559   return isolate->heap()->undefined_value(); |  | 
|  1560 } |  | 
|  1561  |  | 
|  1562  |  | 
|  1563 RUNTIME_FUNCTION(Runtime_FunctionSetPrototype) { |  | 
|  1564   HandleScope scope(isolate); |  | 
|  1565   DCHECK(args.length() == 2); |  | 
|  1566  |  | 
|  1567   CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0); |  | 
|  1568   CONVERT_ARG_HANDLE_CHECKED(Object, value, 1); |  | 
|  1569   RUNTIME_ASSERT(fun->should_have_prototype()); |  | 
|  1570   Accessors::FunctionSetPrototype(fun, value); |  | 
|  1571   return args[0];  // return TOS |  | 
|  1572 } |  | 
|  1573  |  | 
|  1574  |  | 
|  1575 RUNTIME_FUNCTION(Runtime_FunctionIsAPIFunction) { |  | 
|  1576   SealHandleScope shs(isolate); |  | 
|  1577   DCHECK(args.length() == 1); |  | 
|  1578  |  | 
|  1579   CONVERT_ARG_CHECKED(JSFunction, f, 0); |  | 
|  1580   return isolate->heap()->ToBoolean(f->shared()->IsApiFunction()); |  | 
|  1581 } |  | 
|  1582  |  | 
|  1583  |  | 
|  1584 RUNTIME_FUNCTION(Runtime_FunctionIsBuiltin) { |  | 
|  1585   SealHandleScope shs(isolate); |  | 
|  1586   DCHECK(args.length() == 1); |  | 
|  1587  |  | 
|  1588   CONVERT_ARG_CHECKED(JSFunction, f, 0); |  | 
|  1589   return isolate->heap()->ToBoolean(f->IsBuiltin()); |  | 
|  1590 } |  | 
|  1591  |  | 
|  1592  |  | 
|  1593 RUNTIME_FUNCTION(Runtime_SetCode) { |  | 
|  1594   HandleScope scope(isolate); |  | 
|  1595   DCHECK(args.length() == 2); |  | 
|  1596  |  | 
|  1597   CONVERT_ARG_HANDLE_CHECKED(JSFunction, target, 0); |  | 
|  1598   CONVERT_ARG_HANDLE_CHECKED(JSFunction, source, 1); |  | 
|  1599  |  | 
|  1600   Handle<SharedFunctionInfo> target_shared(target->shared()); |  | 
|  1601   Handle<SharedFunctionInfo> source_shared(source->shared()); |  | 
|  1602   RUNTIME_ASSERT(!source_shared->bound()); |  | 
|  1603  |  | 
|  1604   if (!Compiler::EnsureCompiled(source, KEEP_EXCEPTION)) { |  | 
|  1605     return isolate->heap()->exception(); |  | 
|  1606   } |  | 
|  1607  |  | 
|  1608   // Mark both, the source and the target, as un-flushable because the |  | 
|  1609   // shared unoptimized code makes them impossible to enqueue in a list. |  | 
|  1610   DCHECK(target_shared->code()->gc_metadata() == NULL); |  | 
|  1611   DCHECK(source_shared->code()->gc_metadata() == NULL); |  | 
|  1612   target_shared->set_dont_flush(true); |  | 
|  1613   source_shared->set_dont_flush(true); |  | 
|  1614  |  | 
|  1615   // Set the code, scope info, formal parameter count, and the length |  | 
|  1616   // of the target shared function info. |  | 
|  1617   target_shared->ReplaceCode(source_shared->code()); |  | 
|  1618   target_shared->set_scope_info(source_shared->scope_info()); |  | 
|  1619   target_shared->set_length(source_shared->length()); |  | 
|  1620   target_shared->set_feedback_vector(source_shared->feedback_vector()); |  | 
|  1621   target_shared->set_formal_parameter_count( |  | 
|  1622       source_shared->formal_parameter_count()); |  | 
|  1623   target_shared->set_script(source_shared->script()); |  | 
|  1624   target_shared->set_start_position_and_type( |  | 
|  1625       source_shared->start_position_and_type()); |  | 
|  1626   target_shared->set_end_position(source_shared->end_position()); |  | 
|  1627   bool was_native = target_shared->native(); |  | 
|  1628   target_shared->set_compiler_hints(source_shared->compiler_hints()); |  | 
|  1629   target_shared->set_native(was_native); |  | 
|  1630   target_shared->set_profiler_ticks(source_shared->profiler_ticks()); |  | 
|  1631  |  | 
|  1632   // Set the code of the target function. |  | 
|  1633   target->ReplaceCode(source_shared->code()); |  | 
|  1634   DCHECK(target->next_function_link()->IsUndefined()); |  | 
|  1635  |  | 
|  1636   // Make sure we get a fresh copy of the literal vector to avoid cross |  | 
|  1637   // context contamination. |  | 
|  1638   Handle<Context> context(source->context()); |  | 
|  1639   int number_of_literals = source->NumberOfLiterals(); |  | 
|  1640   Handle<FixedArray> literals = |  | 
|  1641       isolate->factory()->NewFixedArray(number_of_literals, TENURED); |  | 
|  1642   if (number_of_literals > 0) { |  | 
|  1643     literals->set(JSFunction::kLiteralNativeContextIndex, |  | 
|  1644                   context->native_context()); |  | 
|  1645   } |  | 
|  1646   target->set_context(*context); |  | 
|  1647   target->set_literals(*literals); |  | 
|  1648  |  | 
|  1649   if (isolate->logger()->is_logging_code_events() || |  | 
|  1650       isolate->cpu_profiler()->is_profiling()) { |  | 
|  1651     isolate->logger()->LogExistingFunction(source_shared, |  | 
|  1652                                            Handle<Code>(source_shared->code())); |  | 
|  1653   } |  | 
|  1654  |  | 
|  1655   return *target; |  | 
|  1656 } |  | 
|  1657  |  | 
|  1658  |  | 
|  1659 RUNTIME_FUNCTION(Runtime_ObjectFreeze) { |   502 RUNTIME_FUNCTION(Runtime_ObjectFreeze) { | 
|  1660   HandleScope scope(isolate); |   503   HandleScope scope(isolate); | 
|  1661   DCHECK(args.length() == 1); |   504   DCHECK(args.length() == 1); | 
|  1662   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); |   505   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); | 
|  1663  |   506  | 
|  1664   // %ObjectFreeze is a fast path and these cases are handled elsewhere. |   507   // %ObjectFreeze is a fast path and these cases are handled elsewhere. | 
|  1665   RUNTIME_ASSERT(!object->HasSloppyArgumentsElements() && |   508   RUNTIME_ASSERT(!object->HasSloppyArgumentsElements() && | 
|  1666                  !object->map()->is_observed() && !object->IsJSProxy()); |   509                  !object->map()->is_observed() && !object->IsJSProxy()); | 
|  1667  |   510  | 
|  1668   Handle<Object> result; |   511   Handle<Object> result; | 
| (...skipping 664 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  2333 RUNTIME_FUNCTION(Runtime_TransitionElementsKind) { |  1176 RUNTIME_FUNCTION(Runtime_TransitionElementsKind) { | 
|  2334   HandleScope scope(isolate); |  1177   HandleScope scope(isolate); | 
|  2335   RUNTIME_ASSERT(args.length() == 2); |  1178   RUNTIME_ASSERT(args.length() == 2); | 
|  2336   CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0); |  1179   CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0); | 
|  2337   CONVERT_ARG_HANDLE_CHECKED(Map, map, 1); |  1180   CONVERT_ARG_HANDLE_CHECKED(Map, map, 1); | 
|  2338   JSObject::TransitionElementsKind(array, map->elements_kind()); |  1181   JSObject::TransitionElementsKind(array, map->elements_kind()); | 
|  2339   return *array; |  1182   return *array; | 
|  2340 } |  1183 } | 
|  2341  |  1184  | 
|  2342  |  1185  | 
|  2343 // Set the native flag on the function. |  | 
|  2344 // This is used to decide if we should transform null and undefined |  | 
|  2345 // into the global object when doing call and apply. |  | 
|  2346 RUNTIME_FUNCTION(Runtime_SetNativeFlag) { |  | 
|  2347   SealHandleScope shs(isolate); |  | 
|  2348   RUNTIME_ASSERT(args.length() == 1); |  | 
|  2349  |  | 
|  2350   CONVERT_ARG_CHECKED(Object, object, 0); |  | 
|  2351  |  | 
|  2352   if (object->IsJSFunction()) { |  | 
|  2353     JSFunction* func = JSFunction::cast(object); |  | 
|  2354     func->shared()->set_native(true); |  | 
|  2355   } |  | 
|  2356   return isolate->heap()->undefined_value(); |  | 
|  2357 } |  | 
|  2358  |  | 
|  2359  |  | 
|  2360 RUNTIME_FUNCTION(Runtime_SetInlineBuiltinFlag) { |  | 
|  2361   SealHandleScope shs(isolate); |  | 
|  2362   RUNTIME_ASSERT(args.length() == 1); |  | 
|  2363   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0); |  | 
|  2364  |  | 
|  2365   if (object->IsJSFunction()) { |  | 
|  2366     JSFunction* func = JSFunction::cast(*object); |  | 
|  2367     func->shared()->set_inline_builtin(true); |  | 
|  2368   } |  | 
|  2369   return isolate->heap()->undefined_value(); |  | 
|  2370 } |  | 
|  2371  |  | 
|  2372  |  | 
|  2373 RUNTIME_FUNCTION(Runtime_StoreArrayLiteralElement) { |  | 
|  2374   HandleScope scope(isolate); |  | 
|  2375   RUNTIME_ASSERT(args.length() == 5); |  | 
|  2376   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); |  | 
|  2377   CONVERT_SMI_ARG_CHECKED(store_index, 1); |  | 
|  2378   CONVERT_ARG_HANDLE_CHECKED(Object, value, 2); |  | 
|  2379   CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 3); |  | 
|  2380   CONVERT_SMI_ARG_CHECKED(literal_index, 4); |  | 
|  2381  |  | 
|  2382   Object* raw_literal_cell = literals->get(literal_index); |  | 
|  2383   JSArray* boilerplate = NULL; |  | 
|  2384   if (raw_literal_cell->IsAllocationSite()) { |  | 
|  2385     AllocationSite* site = AllocationSite::cast(raw_literal_cell); |  | 
|  2386     boilerplate = JSArray::cast(site->transition_info()); |  | 
|  2387   } else { |  | 
|  2388     boilerplate = JSArray::cast(raw_literal_cell); |  | 
|  2389   } |  | 
|  2390   Handle<JSArray> boilerplate_object(boilerplate); |  | 
|  2391   ElementsKind elements_kind = object->GetElementsKind(); |  | 
|  2392   DCHECK(IsFastElementsKind(elements_kind)); |  | 
|  2393   // Smis should never trigger transitions. |  | 
|  2394   DCHECK(!value->IsSmi()); |  | 
|  2395  |  | 
|  2396   if (value->IsNumber()) { |  | 
|  2397     DCHECK(IsFastSmiElementsKind(elements_kind)); |  | 
|  2398     ElementsKind transitioned_kind = IsFastHoleyElementsKind(elements_kind) |  | 
|  2399                                          ? FAST_HOLEY_DOUBLE_ELEMENTS |  | 
|  2400                                          : FAST_DOUBLE_ELEMENTS; |  | 
|  2401     if (IsMoreGeneralElementsKindTransition( |  | 
|  2402             boilerplate_object->GetElementsKind(), transitioned_kind)) { |  | 
|  2403       JSObject::TransitionElementsKind(boilerplate_object, transitioned_kind); |  | 
|  2404     } |  | 
|  2405     JSObject::TransitionElementsKind(object, transitioned_kind); |  | 
|  2406     DCHECK(IsFastDoubleElementsKind(object->GetElementsKind())); |  | 
|  2407     FixedDoubleArray* double_array = FixedDoubleArray::cast(object->elements()); |  | 
|  2408     HeapNumber* number = HeapNumber::cast(*value); |  | 
|  2409     double_array->set(store_index, number->Number()); |  | 
|  2410   } else { |  | 
|  2411     if (!IsFastObjectElementsKind(elements_kind)) { |  | 
|  2412       ElementsKind transitioned_kind = IsFastHoleyElementsKind(elements_kind) |  | 
|  2413                                            ? FAST_HOLEY_ELEMENTS |  | 
|  2414                                            : FAST_ELEMENTS; |  | 
|  2415       JSObject::TransitionElementsKind(object, transitioned_kind); |  | 
|  2416       ElementsKind boilerplate_elements_kind = |  | 
|  2417           boilerplate_object->GetElementsKind(); |  | 
|  2418       if (IsMoreGeneralElementsKindTransition(boilerplate_elements_kind, |  | 
|  2419                                               transitioned_kind)) { |  | 
|  2420         JSObject::TransitionElementsKind(boilerplate_object, transitioned_kind); |  | 
|  2421       } |  | 
|  2422     } |  | 
|  2423     FixedArray* object_array = FixedArray::cast(object->elements()); |  | 
|  2424     object_array->set(store_index, *value); |  | 
|  2425   } |  | 
|  2426   return *object; |  | 
|  2427 } |  | 
|  2428  |  | 
|  2429  |  | 
|  2430 RUNTIME_FUNCTION(Runtime_DebugPromiseRejectEvent) { |  1186 RUNTIME_FUNCTION(Runtime_DebugPromiseRejectEvent) { | 
|  2431   DCHECK(args.length() == 2); |  1187   DCHECK(args.length() == 2); | 
|  2432   HandleScope scope(isolate); |  1188   HandleScope scope(isolate); | 
|  2433   CONVERT_ARG_HANDLE_CHECKED(JSObject, promise, 0); |  1189   CONVERT_ARG_HANDLE_CHECKED(JSObject, promise, 0); | 
|  2434   CONVERT_ARG_HANDLE_CHECKED(Object, value, 1); |  1190   CONVERT_ARG_HANDLE_CHECKED(Object, value, 1); | 
|  2435   isolate->debug()->OnPromiseReject(promise, value); |  1191   isolate->debug()->OnPromiseReject(promise, value); | 
|  2436   return isolate->heap()->undefined_value(); |  1192   return isolate->heap()->undefined_value(); | 
|  2437 } |  1193 } | 
|  2438  |  1194  | 
|  2439  |  1195  | 
| (...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  2843       Handle<Object> entry_handle(entry, isolate); |  1599       Handle<Object> entry_handle(entry, isolate); | 
|  2844       Handle<Object> entry_str = |  1600       Handle<Object> entry_str = | 
|  2845           isolate->factory()->NumberToString(entry_handle); |  1601           isolate->factory()->NumberToString(entry_handle); | 
|  2846       copy->set(i, *entry_str); |  1602       copy->set(i, *entry_str); | 
|  2847     } |  1603     } | 
|  2848   } |  1604   } | 
|  2849   return *isolate->factory()->NewJSArrayWithElements(copy); |  1605   return *isolate->factory()->NewJSArrayWithElements(copy); | 
|  2850 } |  1606 } | 
|  2851  |  1607  | 
|  2852  |  1608  | 
|  2853 RUNTIME_FUNCTION(Runtime_GetArgumentsProperty) { |  | 
|  2854   SealHandleScope shs(isolate); |  | 
|  2855   DCHECK(args.length() == 1); |  | 
|  2856   CONVERT_ARG_HANDLE_CHECKED(Object, raw_key, 0); |  | 
|  2857  |  | 
|  2858   // Compute the frame holding the arguments. |  | 
|  2859   JavaScriptFrameIterator it(isolate); |  | 
|  2860   it.AdvanceToArgumentsFrame(); |  | 
|  2861   JavaScriptFrame* frame = it.frame(); |  | 
|  2862  |  | 
|  2863   // Get the actual number of provided arguments. |  | 
|  2864   const uint32_t n = frame->ComputeParametersCount(); |  | 
|  2865  |  | 
|  2866   // Try to convert the key to an index. If successful and within |  | 
|  2867   // index return the the argument from the frame. |  | 
|  2868   uint32_t index; |  | 
|  2869   if (raw_key->ToArrayIndex(&index) && index < n) { |  | 
|  2870     return frame->GetParameter(index); |  | 
|  2871   } |  | 
|  2872  |  | 
|  2873   HandleScope scope(isolate); |  | 
|  2874   if (raw_key->IsSymbol()) { |  | 
|  2875     Handle<Symbol> symbol = Handle<Symbol>::cast(raw_key); |  | 
|  2876     if (symbol->Equals(isolate->native_context()->iterator_symbol())) { |  | 
|  2877       return isolate->native_context()->array_values_iterator(); |  | 
|  2878     } |  | 
|  2879     // Lookup in the initial Object.prototype object. |  | 
|  2880     Handle<Object> result; |  | 
|  2881     ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |  | 
|  2882         isolate, result, |  | 
|  2883         Object::GetProperty(isolate->initial_object_prototype(), |  | 
|  2884                             Handle<Symbol>::cast(raw_key))); |  | 
|  2885     return *result; |  | 
|  2886   } |  | 
|  2887  |  | 
|  2888   // Convert the key to a string. |  | 
|  2889   Handle<Object> converted; |  | 
|  2890   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, converted, |  | 
|  2891                                      Execution::ToString(isolate, raw_key)); |  | 
|  2892   Handle<String> key = Handle<String>::cast(converted); |  | 
|  2893  |  | 
|  2894   // Try to convert the string key into an array index. |  | 
|  2895   if (key->AsArrayIndex(&index)) { |  | 
|  2896     if (index < n) { |  | 
|  2897       return frame->GetParameter(index); |  | 
|  2898     } else { |  | 
|  2899       Handle<Object> initial_prototype(isolate->initial_object_prototype()); |  | 
|  2900       Handle<Object> result; |  | 
|  2901       ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |  | 
|  2902           isolate, result, |  | 
|  2903           Object::GetElement(isolate, initial_prototype, index)); |  | 
|  2904       return *result; |  | 
|  2905     } |  | 
|  2906   } |  | 
|  2907  |  | 
|  2908   // Handle special arguments properties. |  | 
|  2909   if (String::Equals(isolate->factory()->length_string(), key)) { |  | 
|  2910     return Smi::FromInt(n); |  | 
|  2911   } |  | 
|  2912   if (String::Equals(isolate->factory()->callee_string(), key)) { |  | 
|  2913     JSFunction* function = frame->function(); |  | 
|  2914     if (function->shared()->strict_mode() == STRICT) { |  | 
|  2915       THROW_NEW_ERROR_RETURN_FAILURE( |  | 
|  2916           isolate, NewTypeError("strict_arguments_callee", |  | 
|  2917                                 HandleVector<Object>(NULL, 0))); |  | 
|  2918     } |  | 
|  2919     return function; |  | 
|  2920   } |  | 
|  2921  |  | 
|  2922   // Lookup in the initial Object.prototype object. |  | 
|  2923   Handle<Object> result; |  | 
|  2924   ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |  | 
|  2925       isolate, result, |  | 
|  2926       Object::GetProperty(isolate->initial_object_prototype(), key)); |  | 
|  2927   return *result; |  | 
|  2928 } |  | 
|  2929  |  | 
|  2930  |  | 
|  2931 RUNTIME_FUNCTION(Runtime_ToFastProperties) { |  1609 RUNTIME_FUNCTION(Runtime_ToFastProperties) { | 
|  2932   HandleScope scope(isolate); |  1610   HandleScope scope(isolate); | 
|  2933   DCHECK(args.length() == 1); |  1611   DCHECK(args.length() == 1); | 
|  2934   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0); |  1612   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0); | 
|  2935   if (object->IsJSObject() && !object->IsGlobalObject()) { |  1613   if (object->IsJSObject() && !object->IsGlobalObject()) { | 
|  2936     JSObject::MigrateSlowToFast(Handle<JSObject>::cast(object), 0); |  1614     JSObject::MigrateSlowToFast(Handle<JSObject>::cast(object), 0); | 
|  2937   } |  1615   } | 
|  2938   return *object; |  1616   return *object; | 
|  2939 } |  1617 } | 
|  2940  |  1618  | 
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  3027 } |  1705 } | 
|  3028  |  1706  | 
|  3029  |  1707  | 
|  3030 RUNTIME_FUNCTION(Runtime_AllocateHeapNumber) { |  1708 RUNTIME_FUNCTION(Runtime_AllocateHeapNumber) { | 
|  3031   HandleScope scope(isolate); |  1709   HandleScope scope(isolate); | 
|  3032   DCHECK(args.length() == 0); |  1710   DCHECK(args.length() == 0); | 
|  3033   return *isolate->factory()->NewHeapNumber(0); |  1711   return *isolate->factory()->NewHeapNumber(0); | 
|  3034 } |  1712 } | 
|  3035  |  1713  | 
|  3036  |  1714  | 
|  3037 static Handle<JSObject> NewSloppyArguments(Isolate* isolate, |  | 
|  3038                                            Handle<JSFunction> callee, |  | 
|  3039                                            Object** parameters, |  | 
|  3040                                            int argument_count) { |  | 
|  3041   Handle<JSObject> result = |  | 
|  3042       isolate->factory()->NewArgumentsObject(callee, argument_count); |  | 
|  3043  |  | 
|  3044   // Allocate the elements if needed. |  | 
|  3045   int parameter_count = callee->shared()->formal_parameter_count(); |  | 
|  3046   if (argument_count > 0) { |  | 
|  3047     if (parameter_count > 0) { |  | 
|  3048       int mapped_count = Min(argument_count, parameter_count); |  | 
|  3049       Handle<FixedArray> parameter_map = |  | 
|  3050           isolate->factory()->NewFixedArray(mapped_count + 2, NOT_TENURED); |  | 
|  3051       parameter_map->set_map(isolate->heap()->sloppy_arguments_elements_map()); |  | 
|  3052  |  | 
|  3053       Handle<Map> map = Map::Copy(handle(result->map())); |  | 
|  3054       map->set_elements_kind(SLOPPY_ARGUMENTS_ELEMENTS); |  | 
|  3055  |  | 
|  3056       result->set_map(*map); |  | 
|  3057       result->set_elements(*parameter_map); |  | 
|  3058  |  | 
|  3059       // Store the context and the arguments array at the beginning of the |  | 
|  3060       // parameter map. |  | 
|  3061       Handle<Context> context(isolate->context()); |  | 
|  3062       Handle<FixedArray> arguments = |  | 
|  3063           isolate->factory()->NewFixedArray(argument_count, NOT_TENURED); |  | 
|  3064       parameter_map->set(0, *context); |  | 
|  3065       parameter_map->set(1, *arguments); |  | 
|  3066  |  | 
|  3067       // Loop over the actual parameters backwards. |  | 
|  3068       int index = argument_count - 1; |  | 
|  3069       while (index >= mapped_count) { |  | 
|  3070         // These go directly in the arguments array and have no |  | 
|  3071         // corresponding slot in the parameter map. |  | 
|  3072         arguments->set(index, *(parameters - index - 1)); |  | 
|  3073         --index; |  | 
|  3074       } |  | 
|  3075  |  | 
|  3076       Handle<ScopeInfo> scope_info(callee->shared()->scope_info()); |  | 
|  3077       while (index >= 0) { |  | 
|  3078         // Detect duplicate names to the right in the parameter list. |  | 
|  3079         Handle<String> name(scope_info->ParameterName(index)); |  | 
|  3080         int context_local_count = scope_info->ContextLocalCount(); |  | 
|  3081         bool duplicate = false; |  | 
|  3082         for (int j = index + 1; j < parameter_count; ++j) { |  | 
|  3083           if (scope_info->ParameterName(j) == *name) { |  | 
|  3084             duplicate = true; |  | 
|  3085             break; |  | 
|  3086           } |  | 
|  3087         } |  | 
|  3088  |  | 
|  3089         if (duplicate) { |  | 
|  3090           // This goes directly in the arguments array with a hole in the |  | 
|  3091           // parameter map. |  | 
|  3092           arguments->set(index, *(parameters - index - 1)); |  | 
|  3093           parameter_map->set_the_hole(index + 2); |  | 
|  3094         } else { |  | 
|  3095           // The context index goes in the parameter map with a hole in the |  | 
|  3096           // arguments array. |  | 
|  3097           int context_index = -1; |  | 
|  3098           for (int j = 0; j < context_local_count; ++j) { |  | 
|  3099             if (scope_info->ContextLocalName(j) == *name) { |  | 
|  3100               context_index = j; |  | 
|  3101               break; |  | 
|  3102             } |  | 
|  3103           } |  | 
|  3104           DCHECK(context_index >= 0); |  | 
|  3105           arguments->set_the_hole(index); |  | 
|  3106           parameter_map->set( |  | 
|  3107               index + 2, |  | 
|  3108               Smi::FromInt(Context::MIN_CONTEXT_SLOTS + context_index)); |  | 
|  3109         } |  | 
|  3110  |  | 
|  3111         --index; |  | 
|  3112       } |  | 
|  3113     } else { |  | 
|  3114       // If there is no aliasing, the arguments object elements are not |  | 
|  3115       // special in any way. |  | 
|  3116       Handle<FixedArray> elements = |  | 
|  3117           isolate->factory()->NewFixedArray(argument_count, NOT_TENURED); |  | 
|  3118       result->set_elements(*elements); |  | 
|  3119       for (int i = 0; i < argument_count; ++i) { |  | 
|  3120         elements->set(i, *(parameters - i - 1)); |  | 
|  3121       } |  | 
|  3122     } |  | 
|  3123   } |  | 
|  3124   return result; |  | 
|  3125 } |  | 
|  3126  |  | 
|  3127  |  | 
|  3128 static Handle<JSObject> NewStrictArguments(Isolate* isolate, |  | 
|  3129                                            Handle<JSFunction> callee, |  | 
|  3130                                            Object** parameters, |  | 
|  3131                                            int argument_count) { |  | 
|  3132   Handle<JSObject> result = |  | 
|  3133       isolate->factory()->NewArgumentsObject(callee, argument_count); |  | 
|  3134  |  | 
|  3135   if (argument_count > 0) { |  | 
|  3136     Handle<FixedArray> array = |  | 
|  3137         isolate->factory()->NewUninitializedFixedArray(argument_count); |  | 
|  3138     DisallowHeapAllocation no_gc; |  | 
|  3139     WriteBarrierMode mode = array->GetWriteBarrierMode(no_gc); |  | 
|  3140     for (int i = 0; i < argument_count; i++) { |  | 
|  3141       array->set(i, *--parameters, mode); |  | 
|  3142     } |  | 
|  3143     result->set_elements(*array); |  | 
|  3144   } |  | 
|  3145   return result; |  | 
|  3146 } |  | 
|  3147  |  | 
|  3148  |  | 
|  3149 RUNTIME_FUNCTION(Runtime_NewArguments) { |  | 
|  3150   HandleScope scope(isolate); |  | 
|  3151   DCHECK(args.length() == 1); |  | 
|  3152   CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0); |  | 
|  3153   JavaScriptFrameIterator it(isolate); |  | 
|  3154  |  | 
|  3155   // Find the frame that holds the actual arguments passed to the function. |  | 
|  3156   it.AdvanceToArgumentsFrame(); |  | 
|  3157   JavaScriptFrame* frame = it.frame(); |  | 
|  3158  |  | 
|  3159   // Determine parameter location on the stack and dispatch on language mode. |  | 
|  3160   int argument_count = frame->GetArgumentsLength(); |  | 
|  3161   Object** parameters = reinterpret_cast<Object**>(frame->GetParameterSlot(-1)); |  | 
|  3162   return callee->shared()->strict_mode() == STRICT |  | 
|  3163              ? *NewStrictArguments(isolate, callee, parameters, argument_count) |  | 
|  3164              : *NewSloppyArguments(isolate, callee, parameters, argument_count); |  | 
|  3165 } |  | 
|  3166  |  | 
|  3167  |  | 
|  3168 RUNTIME_FUNCTION(Runtime_NewSloppyArguments) { |  | 
|  3169   HandleScope scope(isolate); |  | 
|  3170   DCHECK(args.length() == 3); |  | 
|  3171   CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0); |  | 
|  3172   Object** parameters = reinterpret_cast<Object**>(args[1]); |  | 
|  3173   CONVERT_SMI_ARG_CHECKED(argument_count, 2); |  | 
|  3174   return *NewSloppyArguments(isolate, callee, parameters, argument_count); |  | 
|  3175 } |  | 
|  3176  |  | 
|  3177  |  | 
|  3178 RUNTIME_FUNCTION(Runtime_NewStrictArguments) { |  | 
|  3179   HandleScope scope(isolate); |  | 
|  3180   DCHECK(args.length() == 3); |  | 
|  3181   CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0) |  | 
|  3182   Object** parameters = reinterpret_cast<Object**>(args[1]); |  | 
|  3183   CONVERT_SMI_ARG_CHECKED(argument_count, 2); |  | 
|  3184   return *NewStrictArguments(isolate, callee, parameters, argument_count); |  | 
|  3185 } |  | 
|  3186  |  | 
|  3187  |  | 
|  3188 RUNTIME_FUNCTION(Runtime_NewClosureFromStubFailure) { |  | 
|  3189   HandleScope scope(isolate); |  | 
|  3190   DCHECK(args.length() == 1); |  | 
|  3191   CONVERT_ARG_HANDLE_CHECKED(SharedFunctionInfo, shared, 0); |  | 
|  3192   Handle<Context> context(isolate->context()); |  | 
|  3193   PretenureFlag pretenure_flag = NOT_TENURED; |  | 
|  3194   return *isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, context, |  | 
|  3195                                                                 pretenure_flag); |  | 
|  3196 } |  | 
|  3197  |  | 
|  3198  |  | 
|  3199 RUNTIME_FUNCTION(Runtime_NewClosure) { |  | 
|  3200   HandleScope scope(isolate); |  | 
|  3201   DCHECK(args.length() == 3); |  | 
|  3202   CONVERT_ARG_HANDLE_CHECKED(Context, context, 0); |  | 
|  3203   CONVERT_ARG_HANDLE_CHECKED(SharedFunctionInfo, shared, 1); |  | 
|  3204   CONVERT_BOOLEAN_ARG_CHECKED(pretenure, 2); |  | 
|  3205  |  | 
|  3206   // The caller ensures that we pretenure closures that are assigned |  | 
|  3207   // directly to properties. |  | 
|  3208   PretenureFlag pretenure_flag = pretenure ? TENURED : NOT_TENURED; |  | 
|  3209   return *isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, context, |  | 
|  3210                                                                 pretenure_flag); |  | 
|  3211 } |  | 
|  3212  |  | 
|  3213  |  | 
|  3214 // Find the arguments of the JavaScript function invocation that called |  | 
|  3215 // into C++ code. Collect these in a newly allocated array of handles (possibly |  | 
|  3216 // prefixed by a number of empty handles). |  | 
|  3217 static SmartArrayPointer<Handle<Object> > GetCallerArguments(Isolate* isolate, |  | 
|  3218                                                              int prefix_argc, |  | 
|  3219                                                              int* total_argc) { |  | 
|  3220   // Find frame containing arguments passed to the caller. |  | 
|  3221   JavaScriptFrameIterator it(isolate); |  | 
|  3222   JavaScriptFrame* frame = it.frame(); |  | 
|  3223   List<JSFunction*> functions(2); |  | 
|  3224   frame->GetFunctions(&functions); |  | 
|  3225   if (functions.length() > 1) { |  | 
|  3226     int inlined_jsframe_index = functions.length() - 1; |  | 
|  3227     JSFunction* inlined_function = functions[inlined_jsframe_index]; |  | 
|  3228     SlotRefValueBuilder slot_refs( |  | 
|  3229         frame, inlined_jsframe_index, |  | 
|  3230         inlined_function->shared()->formal_parameter_count()); |  | 
|  3231  |  | 
|  3232     int args_count = slot_refs.args_length(); |  | 
|  3233  |  | 
|  3234     *total_argc = prefix_argc + args_count; |  | 
|  3235     SmartArrayPointer<Handle<Object> > param_data( |  | 
|  3236         NewArray<Handle<Object> >(*total_argc)); |  | 
|  3237     slot_refs.Prepare(isolate); |  | 
|  3238     for (int i = 0; i < args_count; i++) { |  | 
|  3239       Handle<Object> val = slot_refs.GetNext(isolate, 0); |  | 
|  3240       param_data[prefix_argc + i] = val; |  | 
|  3241     } |  | 
|  3242     slot_refs.Finish(isolate); |  | 
|  3243  |  | 
|  3244     return param_data; |  | 
|  3245   } else { |  | 
|  3246     it.AdvanceToArgumentsFrame(); |  | 
|  3247     frame = it.frame(); |  | 
|  3248     int args_count = frame->ComputeParametersCount(); |  | 
|  3249  |  | 
|  3250     *total_argc = prefix_argc + args_count; |  | 
|  3251     SmartArrayPointer<Handle<Object> > param_data( |  | 
|  3252         NewArray<Handle<Object> >(*total_argc)); |  | 
|  3253     for (int i = 0; i < args_count; i++) { |  | 
|  3254       Handle<Object> val = Handle<Object>(frame->GetParameter(i), isolate); |  | 
|  3255       param_data[prefix_argc + i] = val; |  | 
|  3256     } |  | 
|  3257     return param_data; |  | 
|  3258   } |  | 
|  3259 } |  | 
|  3260  |  | 
|  3261  |  | 
|  3262 RUNTIME_FUNCTION(Runtime_FunctionBindArguments) { |  | 
|  3263   HandleScope scope(isolate); |  | 
|  3264   DCHECK(args.length() == 4); |  | 
|  3265   CONVERT_ARG_HANDLE_CHECKED(JSFunction, bound_function, 0); |  | 
|  3266   CONVERT_ARG_HANDLE_CHECKED(Object, bindee, 1); |  | 
|  3267   CONVERT_ARG_HANDLE_CHECKED(Object, this_object, 2); |  | 
|  3268   CONVERT_NUMBER_ARG_HANDLE_CHECKED(new_length, 3); |  | 
|  3269  |  | 
|  3270   // TODO(lrn): Create bound function in C++ code from premade shared info. |  | 
|  3271   bound_function->shared()->set_bound(true); |  | 
|  3272   // Get all arguments of calling function (Function.prototype.bind). |  | 
|  3273   int argc = 0; |  | 
|  3274   SmartArrayPointer<Handle<Object> > arguments = |  | 
|  3275       GetCallerArguments(isolate, 0, &argc); |  | 
|  3276   // Don't count the this-arg. |  | 
|  3277   if (argc > 0) { |  | 
|  3278     RUNTIME_ASSERT(arguments[0].is_identical_to(this_object)); |  | 
|  3279     argc--; |  | 
|  3280   } else { |  | 
|  3281     RUNTIME_ASSERT(this_object->IsUndefined()); |  | 
|  3282   } |  | 
|  3283   // Initialize array of bindings (function, this, and any existing arguments |  | 
|  3284   // if the function was already bound). |  | 
|  3285   Handle<FixedArray> new_bindings; |  | 
|  3286   int i; |  | 
|  3287   if (bindee->IsJSFunction() && JSFunction::cast(*bindee)->shared()->bound()) { |  | 
|  3288     Handle<FixedArray> old_bindings( |  | 
|  3289         JSFunction::cast(*bindee)->function_bindings()); |  | 
|  3290     RUNTIME_ASSERT(old_bindings->length() > JSFunction::kBoundFunctionIndex); |  | 
|  3291     new_bindings = |  | 
|  3292         isolate->factory()->NewFixedArray(old_bindings->length() + argc); |  | 
|  3293     bindee = Handle<Object>(old_bindings->get(JSFunction::kBoundFunctionIndex), |  | 
|  3294                             isolate); |  | 
|  3295     i = 0; |  | 
|  3296     for (int n = old_bindings->length(); i < n; i++) { |  | 
|  3297       new_bindings->set(i, old_bindings->get(i)); |  | 
|  3298     } |  | 
|  3299   } else { |  | 
|  3300     int array_size = JSFunction::kBoundArgumentsStartIndex + argc; |  | 
|  3301     new_bindings = isolate->factory()->NewFixedArray(array_size); |  | 
|  3302     new_bindings->set(JSFunction::kBoundFunctionIndex, *bindee); |  | 
|  3303     new_bindings->set(JSFunction::kBoundThisIndex, *this_object); |  | 
|  3304     i = 2; |  | 
|  3305   } |  | 
|  3306   // Copy arguments, skipping the first which is "this_arg". |  | 
|  3307   for (int j = 0; j < argc; j++, i++) { |  | 
|  3308     new_bindings->set(i, *arguments[j + 1]); |  | 
|  3309   } |  | 
|  3310   new_bindings->set_map_no_write_barrier( |  | 
|  3311       isolate->heap()->fixed_cow_array_map()); |  | 
|  3312   bound_function->set_function_bindings(*new_bindings); |  | 
|  3313  |  | 
|  3314   // Update length. Have to remove the prototype first so that map migration |  | 
|  3315   // is happy about the number of fields. |  | 
|  3316   RUNTIME_ASSERT(bound_function->RemovePrototype()); |  | 
|  3317   Handle<Map> bound_function_map( |  | 
|  3318       isolate->native_context()->bound_function_map()); |  | 
|  3319   JSObject::MigrateToMap(bound_function, bound_function_map); |  | 
|  3320   Handle<String> length_string = isolate->factory()->length_string(); |  | 
|  3321   PropertyAttributes attr = |  | 
|  3322       static_cast<PropertyAttributes>(DONT_DELETE | DONT_ENUM | READ_ONLY); |  | 
|  3323   RETURN_FAILURE_ON_EXCEPTION( |  | 
|  3324       isolate, JSObject::SetOwnPropertyIgnoreAttributes( |  | 
|  3325                    bound_function, length_string, new_length, attr)); |  | 
|  3326   return *bound_function; |  | 
|  3327 } |  | 
|  3328  |  | 
|  3329  |  | 
|  3330 RUNTIME_FUNCTION(Runtime_BoundFunctionGetBindings) { |  | 
|  3331   HandleScope handles(isolate); |  | 
|  3332   DCHECK(args.length() == 1); |  | 
|  3333   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, callable, 0); |  | 
|  3334   if (callable->IsJSFunction()) { |  | 
|  3335     Handle<JSFunction> function = Handle<JSFunction>::cast(callable); |  | 
|  3336     if (function->shared()->bound()) { |  | 
|  3337       Handle<FixedArray> bindings(function->function_bindings()); |  | 
|  3338       RUNTIME_ASSERT(bindings->map() == isolate->heap()->fixed_cow_array_map()); |  | 
|  3339       return *isolate->factory()->NewJSArrayWithElements(bindings); |  | 
|  3340     } |  | 
|  3341   } |  | 
|  3342   return isolate->heap()->undefined_value(); |  | 
|  3343 } |  | 
|  3344  |  | 
|  3345  |  | 
|  3346 RUNTIME_FUNCTION(Runtime_NewObjectFromBound) { |  | 
|  3347   HandleScope scope(isolate); |  | 
|  3348   DCHECK(args.length() == 1); |  | 
|  3349   // First argument is a function to use as a constructor. |  | 
|  3350   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); |  | 
|  3351   RUNTIME_ASSERT(function->shared()->bound()); |  | 
|  3352  |  | 
|  3353   // The argument is a bound function. Extract its bound arguments |  | 
|  3354   // and callable. |  | 
|  3355   Handle<FixedArray> bound_args = |  | 
|  3356       Handle<FixedArray>(FixedArray::cast(function->function_bindings())); |  | 
|  3357   int bound_argc = bound_args->length() - JSFunction::kBoundArgumentsStartIndex; |  | 
|  3358   Handle<Object> bound_function( |  | 
|  3359       JSReceiver::cast(bound_args->get(JSFunction::kBoundFunctionIndex)), |  | 
|  3360       isolate); |  | 
|  3361   DCHECK(!bound_function->IsJSFunction() || |  | 
|  3362          !Handle<JSFunction>::cast(bound_function)->shared()->bound()); |  | 
|  3363  |  | 
|  3364   int total_argc = 0; |  | 
|  3365   SmartArrayPointer<Handle<Object> > param_data = |  | 
|  3366       GetCallerArguments(isolate, bound_argc, &total_argc); |  | 
|  3367   for (int i = 0; i < bound_argc; i++) { |  | 
|  3368     param_data[i] = Handle<Object>( |  | 
|  3369         bound_args->get(JSFunction::kBoundArgumentsStartIndex + i), isolate); |  | 
|  3370   } |  | 
|  3371  |  | 
|  3372   if (!bound_function->IsJSFunction()) { |  | 
|  3373     ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |  | 
|  3374         isolate, bound_function, |  | 
|  3375         Execution::TryGetConstructorDelegate(isolate, bound_function)); |  | 
|  3376   } |  | 
|  3377   DCHECK(bound_function->IsJSFunction()); |  | 
|  3378  |  | 
|  3379   Handle<Object> result; |  | 
|  3380   ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |  | 
|  3381       isolate, result, Execution::New(Handle<JSFunction>::cast(bound_function), |  | 
|  3382                                       total_argc, param_data.get())); |  | 
|  3383   return *result; |  | 
|  3384 } |  | 
|  3385  |  | 
|  3386  |  | 
|  3387 static Object* Runtime_NewObjectHelper(Isolate* isolate, |  1715 static Object* Runtime_NewObjectHelper(Isolate* isolate, | 
|  3388                                        Handle<Object> constructor, |  1716                                        Handle<Object> constructor, | 
|  3389                                        Handle<AllocationSite> site) { |  1717                                        Handle<AllocationSite> site) { | 
|  3390   // If the constructor isn't a proper function we throw a type error. |  1718   // If the constructor isn't a proper function we throw a type error. | 
|  3391   if (!constructor->IsJSFunction()) { |  1719   if (!constructor->IsJSFunction()) { | 
|  3392     Vector<Handle<Object> > arguments = HandleVector(&constructor, 1); |  1720     Vector<Handle<Object> > arguments = HandleVector(&constructor, 1); | 
|  3393     THROW_NEW_ERROR_RETURN_FAILURE(isolate, |  1721     THROW_NEW_ERROR_RETURN_FAILURE(isolate, | 
|  3394                                    NewTypeError("not_constructor", arguments)); |  1722                                    NewTypeError("not_constructor", arguments)); | 
|  3395   } |  1723   } | 
|  3396  |  1724  | 
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  3488  |  1816  | 
|  3489  |  1817  | 
|  3490 RUNTIME_FUNCTION(Runtime_GetRootNaN) { |  1818 RUNTIME_FUNCTION(Runtime_GetRootNaN) { | 
|  3491   SealHandleScope shs(isolate); |  1819   SealHandleScope shs(isolate); | 
|  3492   DCHECK(args.length() == 0); |  1820   DCHECK(args.length() == 0); | 
|  3493   RUNTIME_ASSERT(isolate->bootstrapper()->IsActive()); |  1821   RUNTIME_ASSERT(isolate->bootstrapper()->IsActive()); | 
|  3494   return isolate->heap()->nan_value(); |  1822   return isolate->heap()->nan_value(); | 
|  3495 } |  1823 } | 
|  3496  |  1824  | 
|  3497  |  1825  | 
|  3498 RUNTIME_FUNCTION(Runtime_Call) { |  | 
|  3499   HandleScope scope(isolate); |  | 
|  3500   DCHECK(args.length() >= 2); |  | 
|  3501   int argc = args.length() - 2; |  | 
|  3502   CONVERT_ARG_CHECKED(JSReceiver, fun, argc + 1); |  | 
|  3503   Object* receiver = args[0]; |  | 
|  3504  |  | 
|  3505   // If there are too many arguments, allocate argv via malloc. |  | 
|  3506   const int argv_small_size = 10; |  | 
|  3507   Handle<Object> argv_small_buffer[argv_small_size]; |  | 
|  3508   SmartArrayPointer<Handle<Object> > argv_large_buffer; |  | 
|  3509   Handle<Object>* argv = argv_small_buffer; |  | 
|  3510   if (argc > argv_small_size) { |  | 
|  3511     argv = new Handle<Object>[argc]; |  | 
|  3512     if (argv == NULL) return isolate->StackOverflow(); |  | 
|  3513     argv_large_buffer = SmartArrayPointer<Handle<Object> >(argv); |  | 
|  3514   } |  | 
|  3515  |  | 
|  3516   for (int i = 0; i < argc; ++i) { |  | 
|  3517     argv[i] = Handle<Object>(args[1 + i], isolate); |  | 
|  3518   } |  | 
|  3519  |  | 
|  3520   Handle<JSReceiver> hfun(fun); |  | 
|  3521   Handle<Object> hreceiver(receiver, isolate); |  | 
|  3522   Handle<Object> result; |  | 
|  3523   ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |  | 
|  3524       isolate, result, |  | 
|  3525       Execution::Call(isolate, hfun, hreceiver, argc, argv, true)); |  | 
|  3526   return *result; |  | 
|  3527 } |  | 
|  3528  |  | 
|  3529  |  | 
|  3530 RUNTIME_FUNCTION(Runtime_Apply) { |  | 
|  3531   HandleScope scope(isolate); |  | 
|  3532   DCHECK(args.length() == 5); |  | 
|  3533   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, fun, 0); |  | 
|  3534   CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 1); |  | 
|  3535   CONVERT_ARG_HANDLE_CHECKED(JSObject, arguments, 2); |  | 
|  3536   CONVERT_INT32_ARG_CHECKED(offset, 3); |  | 
|  3537   CONVERT_INT32_ARG_CHECKED(argc, 4); |  | 
|  3538   RUNTIME_ASSERT(offset >= 0); |  | 
|  3539   // Loose upper bound to allow fuzzing. We'll most likely run out of |  | 
|  3540   // stack space before hitting this limit. |  | 
|  3541   static int kMaxArgc = 1000000; |  | 
|  3542   RUNTIME_ASSERT(argc >= 0 && argc <= kMaxArgc); |  | 
|  3543  |  | 
|  3544   // If there are too many arguments, allocate argv via malloc. |  | 
|  3545   const int argv_small_size = 10; |  | 
|  3546   Handle<Object> argv_small_buffer[argv_small_size]; |  | 
|  3547   SmartArrayPointer<Handle<Object> > argv_large_buffer; |  | 
|  3548   Handle<Object>* argv = argv_small_buffer; |  | 
|  3549   if (argc > argv_small_size) { |  | 
|  3550     argv = new Handle<Object>[argc]; |  | 
|  3551     if (argv == NULL) return isolate->StackOverflow(); |  | 
|  3552     argv_large_buffer = SmartArrayPointer<Handle<Object> >(argv); |  | 
|  3553   } |  | 
|  3554  |  | 
|  3555   for (int i = 0; i < argc; ++i) { |  | 
|  3556     ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |  | 
|  3557         isolate, argv[i], Object::GetElement(isolate, arguments, offset + i)); |  | 
|  3558   } |  | 
|  3559  |  | 
|  3560   Handle<Object> result; |  | 
|  3561   ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |  | 
|  3562       isolate, result, |  | 
|  3563       Execution::Call(isolate, fun, receiver, argc, argv, true)); |  | 
|  3564   return *result; |  | 
|  3565 } |  | 
|  3566  |  | 
|  3567  |  | 
|  3568 RUNTIME_FUNCTION(Runtime_GetFunctionDelegate) { |  | 
|  3569   HandleScope scope(isolate); |  | 
|  3570   DCHECK(args.length() == 1); |  | 
|  3571   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0); |  | 
|  3572   RUNTIME_ASSERT(!object->IsJSFunction()); |  | 
|  3573   return *Execution::GetFunctionDelegate(isolate, object); |  | 
|  3574 } |  | 
|  3575  |  | 
|  3576  |  | 
|  3577 RUNTIME_FUNCTION(Runtime_GetConstructorDelegate) { |  | 
|  3578   HandleScope scope(isolate); |  | 
|  3579   DCHECK(args.length() == 1); |  | 
|  3580   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0); |  | 
|  3581   RUNTIME_ASSERT(!object->IsJSFunction()); |  | 
|  3582   return *Execution::GetConstructorDelegate(isolate, object); |  | 
|  3583 } |  | 
|  3584  |  | 
|  3585  |  | 
|  3586 RUNTIME_FUNCTION(Runtime_NewGlobalContext) { |  | 
|  3587   HandleScope scope(isolate); |  | 
|  3588   DCHECK(args.length() == 2); |  | 
|  3589  |  | 
|  3590   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); |  | 
|  3591   CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 1); |  | 
|  3592   Handle<Context> result = |  | 
|  3593       isolate->factory()->NewGlobalContext(function, scope_info); |  | 
|  3594  |  | 
|  3595   DCHECK(function->context() == isolate->context()); |  | 
|  3596   DCHECK(function->context()->global_object() == result->global_object()); |  | 
|  3597   result->global_object()->set_global_context(*result); |  | 
|  3598   return *result; |  | 
|  3599 } |  | 
|  3600  |  | 
|  3601  |  | 
|  3602 RUNTIME_FUNCTION(Runtime_NewFunctionContext) { |  | 
|  3603   HandleScope scope(isolate); |  | 
|  3604   DCHECK(args.length() == 1); |  | 
|  3605  |  | 
|  3606   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); |  | 
|  3607  |  | 
|  3608   DCHECK(function->context() == isolate->context()); |  | 
|  3609   int length = function->shared()->scope_info()->ContextLength(); |  | 
|  3610   return *isolate->factory()->NewFunctionContext(length, function); |  | 
|  3611 } |  | 
|  3612  |  | 
|  3613  |  | 
|  3614 RUNTIME_FUNCTION(Runtime_PushWithContext) { |  | 
|  3615   HandleScope scope(isolate); |  | 
|  3616   DCHECK(args.length() == 2); |  | 
|  3617   Handle<JSReceiver> extension_object; |  | 
|  3618   if (args[0]->IsJSReceiver()) { |  | 
|  3619     extension_object = args.at<JSReceiver>(0); |  | 
|  3620   } else { |  | 
|  3621     // Try to convert the object to a proper JavaScript object. |  | 
|  3622     MaybeHandle<JSReceiver> maybe_object = |  | 
|  3623         Object::ToObject(isolate, args.at<Object>(0)); |  | 
|  3624     if (!maybe_object.ToHandle(&extension_object)) { |  | 
|  3625       Handle<Object> handle = args.at<Object>(0); |  | 
|  3626       THROW_NEW_ERROR_RETURN_FAILURE( |  | 
|  3627           isolate, NewTypeError("with_expression", HandleVector(&handle, 1))); |  | 
|  3628     } |  | 
|  3629   } |  | 
|  3630  |  | 
|  3631   Handle<JSFunction> function; |  | 
|  3632   if (args[1]->IsSmi()) { |  | 
|  3633     // A smi sentinel indicates a context nested inside global code rather |  | 
|  3634     // than some function.  There is a canonical empty function that can be |  | 
|  3635     // gotten from the native context. |  | 
|  3636     function = handle(isolate->native_context()->closure()); |  | 
|  3637   } else { |  | 
|  3638     function = args.at<JSFunction>(1); |  | 
|  3639   } |  | 
|  3640  |  | 
|  3641   Handle<Context> current(isolate->context()); |  | 
|  3642   Handle<Context> context = |  | 
|  3643       isolate->factory()->NewWithContext(function, current, extension_object); |  | 
|  3644   isolate->set_context(*context); |  | 
|  3645   return *context; |  | 
|  3646 } |  | 
|  3647  |  | 
|  3648  |  | 
|  3649 RUNTIME_FUNCTION(Runtime_PushCatchContext) { |  | 
|  3650   HandleScope scope(isolate); |  | 
|  3651   DCHECK(args.length() == 3); |  | 
|  3652   CONVERT_ARG_HANDLE_CHECKED(String, name, 0); |  | 
|  3653   CONVERT_ARG_HANDLE_CHECKED(Object, thrown_object, 1); |  | 
|  3654   Handle<JSFunction> function; |  | 
|  3655   if (args[2]->IsSmi()) { |  | 
|  3656     // A smi sentinel indicates a context nested inside global code rather |  | 
|  3657     // than some function.  There is a canonical empty function that can be |  | 
|  3658     // gotten from the native context. |  | 
|  3659     function = handle(isolate->native_context()->closure()); |  | 
|  3660   } else { |  | 
|  3661     function = args.at<JSFunction>(2); |  | 
|  3662   } |  | 
|  3663   Handle<Context> current(isolate->context()); |  | 
|  3664   Handle<Context> context = isolate->factory()->NewCatchContext( |  | 
|  3665       function, current, name, thrown_object); |  | 
|  3666   isolate->set_context(*context); |  | 
|  3667   return *context; |  | 
|  3668 } |  | 
|  3669  |  | 
|  3670  |  | 
|  3671 RUNTIME_FUNCTION(Runtime_PushBlockContext) { |  | 
|  3672   HandleScope scope(isolate); |  | 
|  3673   DCHECK(args.length() == 2); |  | 
|  3674   CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 0); |  | 
|  3675   Handle<JSFunction> function; |  | 
|  3676   if (args[1]->IsSmi()) { |  | 
|  3677     // A smi sentinel indicates a context nested inside global code rather |  | 
|  3678     // than some function.  There is a canonical empty function that can be |  | 
|  3679     // gotten from the native context. |  | 
|  3680     function = handle(isolate->native_context()->closure()); |  | 
|  3681   } else { |  | 
|  3682     function = args.at<JSFunction>(1); |  | 
|  3683   } |  | 
|  3684   Handle<Context> current(isolate->context()); |  | 
|  3685   Handle<Context> context = |  | 
|  3686       isolate->factory()->NewBlockContext(function, current, scope_info); |  | 
|  3687   isolate->set_context(*context); |  | 
|  3688   return *context; |  | 
|  3689 } |  | 
|  3690  |  | 
|  3691  |  | 
|  3692 RUNTIME_FUNCTION(Runtime_IsJSModule) { |  | 
|  3693   SealHandleScope shs(isolate); |  | 
|  3694   DCHECK(args.length() == 1); |  | 
|  3695   CONVERT_ARG_CHECKED(Object, obj, 0); |  | 
|  3696   return isolate->heap()->ToBoolean(obj->IsJSModule()); |  | 
|  3697 } |  | 
|  3698  |  | 
|  3699  |  | 
|  3700 RUNTIME_FUNCTION(Runtime_PushModuleContext) { |  | 
|  3701   SealHandleScope shs(isolate); |  | 
|  3702   DCHECK(args.length() == 2); |  | 
|  3703   CONVERT_SMI_ARG_CHECKED(index, 0); |  | 
|  3704  |  | 
|  3705   if (!args[1]->IsScopeInfo()) { |  | 
|  3706     // Module already initialized. Find hosting context and retrieve context. |  | 
|  3707     Context* host = Context::cast(isolate->context())->global_context(); |  | 
|  3708     Context* context = Context::cast(host->get(index)); |  | 
|  3709     DCHECK(context->previous() == isolate->context()); |  | 
|  3710     isolate->set_context(context); |  | 
|  3711     return context; |  | 
|  3712   } |  | 
|  3713  |  | 
|  3714   CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 1); |  | 
|  3715  |  | 
|  3716   // Allocate module context. |  | 
|  3717   HandleScope scope(isolate); |  | 
|  3718   Factory* factory = isolate->factory(); |  | 
|  3719   Handle<Context> context = factory->NewModuleContext(scope_info); |  | 
|  3720   Handle<JSModule> module = factory->NewJSModule(context, scope_info); |  | 
|  3721   context->set_module(*module); |  | 
|  3722   Context* previous = isolate->context(); |  | 
|  3723   context->set_previous(previous); |  | 
|  3724   context->set_closure(previous->closure()); |  | 
|  3725   context->set_global_object(previous->global_object()); |  | 
|  3726   isolate->set_context(*context); |  | 
|  3727  |  | 
|  3728   // Find hosting scope and initialize internal variable holding module there. |  | 
|  3729   previous->global_context()->set(index, *context); |  | 
|  3730  |  | 
|  3731   return *context; |  | 
|  3732 } |  | 
|  3733  |  | 
|  3734  |  | 
|  3735 RUNTIME_FUNCTION(Runtime_DeclareModules) { |  | 
|  3736   HandleScope scope(isolate); |  | 
|  3737   DCHECK(args.length() == 1); |  | 
|  3738   CONVERT_ARG_HANDLE_CHECKED(FixedArray, descriptions, 0); |  | 
|  3739   Context* host_context = isolate->context(); |  | 
|  3740  |  | 
|  3741   for (int i = 0; i < descriptions->length(); ++i) { |  | 
|  3742     Handle<ModuleInfo> description(ModuleInfo::cast(descriptions->get(i))); |  | 
|  3743     int host_index = description->host_index(); |  | 
|  3744     Handle<Context> context(Context::cast(host_context->get(host_index))); |  | 
|  3745     Handle<JSModule> module(context->module()); |  | 
|  3746  |  | 
|  3747     for (int j = 0; j < description->length(); ++j) { |  | 
|  3748       Handle<String> name(description->name(j)); |  | 
|  3749       VariableMode mode = description->mode(j); |  | 
|  3750       int index = description->index(j); |  | 
|  3751       switch (mode) { |  | 
|  3752         case VAR: |  | 
|  3753         case LET: |  | 
|  3754         case CONST: |  | 
|  3755         case CONST_LEGACY: { |  | 
|  3756           PropertyAttributes attr = |  | 
|  3757               IsImmutableVariableMode(mode) ? FROZEN : SEALED; |  | 
|  3758           Handle<AccessorInfo> info = |  | 
|  3759               Accessors::MakeModuleExport(name, index, attr); |  | 
|  3760           Handle<Object> result = |  | 
|  3761               JSObject::SetAccessor(module, info).ToHandleChecked(); |  | 
|  3762           DCHECK(!result->IsUndefined()); |  | 
|  3763           USE(result); |  | 
|  3764           break; |  | 
|  3765         } |  | 
|  3766         case MODULE: { |  | 
|  3767           Object* referenced_context = Context::cast(host_context)->get(index); |  | 
|  3768           Handle<JSModule> value(Context::cast(referenced_context)->module()); |  | 
|  3769           JSObject::SetOwnPropertyIgnoreAttributes(module, name, value, FROZEN) |  | 
|  3770               .Assert(); |  | 
|  3771           break; |  | 
|  3772         } |  | 
|  3773         case INTERNAL: |  | 
|  3774         case TEMPORARY: |  | 
|  3775         case DYNAMIC: |  | 
|  3776         case DYNAMIC_GLOBAL: |  | 
|  3777         case DYNAMIC_LOCAL: |  | 
|  3778           UNREACHABLE(); |  | 
|  3779       } |  | 
|  3780     } |  | 
|  3781  |  | 
|  3782     JSObject::PreventExtensions(module).Assert(); |  | 
|  3783   } |  | 
|  3784  |  | 
|  3785   DCHECK(!isolate->has_pending_exception()); |  | 
|  3786   return isolate->heap()->undefined_value(); |  | 
|  3787 } |  | 
|  3788  |  | 
|  3789  |  | 
|  3790 RUNTIME_FUNCTION(Runtime_DeleteLookupSlot) { |  | 
|  3791   HandleScope scope(isolate); |  | 
|  3792   DCHECK(args.length() == 2); |  | 
|  3793  |  | 
|  3794   CONVERT_ARG_HANDLE_CHECKED(Context, context, 0); |  | 
|  3795   CONVERT_ARG_HANDLE_CHECKED(String, name, 1); |  | 
|  3796  |  | 
|  3797   int index; |  | 
|  3798   PropertyAttributes attributes; |  | 
|  3799   ContextLookupFlags flags = FOLLOW_CHAINS; |  | 
|  3800   BindingFlags binding_flags; |  | 
|  3801   Handle<Object> holder = |  | 
|  3802       context->Lookup(name, flags, &index, &attributes, &binding_flags); |  | 
|  3803  |  | 
|  3804   // If the slot was not found the result is true. |  | 
|  3805   if (holder.is_null()) { |  | 
|  3806     return isolate->heap()->true_value(); |  | 
|  3807   } |  | 
|  3808  |  | 
|  3809   // If the slot was found in a context, it should be DONT_DELETE. |  | 
|  3810   if (holder->IsContext()) { |  | 
|  3811     return isolate->heap()->false_value(); |  | 
|  3812   } |  | 
|  3813  |  | 
|  3814   // The slot was found in a JSObject, either a context extension object, |  | 
|  3815   // the global object, or the subject of a with.  Try to delete it |  | 
|  3816   // (respecting DONT_DELETE). |  | 
|  3817   Handle<JSObject> object = Handle<JSObject>::cast(holder); |  | 
|  3818   Handle<Object> result; |  | 
|  3819   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, |  | 
|  3820                                      JSReceiver::DeleteProperty(object, name)); |  | 
|  3821   return *result; |  | 
|  3822 } |  | 
|  3823  |  | 
|  3824  |  | 
|  3825 static Object* ComputeReceiverForNonGlobal(Isolate* isolate, JSObject* holder) { |  | 
|  3826   DCHECK(!holder->IsGlobalObject()); |  | 
|  3827   Context* top = isolate->context(); |  | 
|  3828   // Get the context extension function. |  | 
|  3829   JSFunction* context_extension_function = |  | 
|  3830       top->native_context()->context_extension_function(); |  | 
|  3831   // If the holder isn't a context extension object, we just return it |  | 
|  3832   // as the receiver. This allows arguments objects to be used as |  | 
|  3833   // receivers, but only if they are put in the context scope chain |  | 
|  3834   // explicitly via a with-statement. |  | 
|  3835   Object* constructor = holder->map()->constructor(); |  | 
|  3836   if (constructor != context_extension_function) return holder; |  | 
|  3837   // Fall back to using the global object as the implicit receiver if |  | 
|  3838   // the property turns out to be a local variable allocated in a |  | 
|  3839   // context extension object - introduced via eval. |  | 
|  3840   return isolate->heap()->undefined_value(); |  | 
|  3841 } |  | 
|  3842  |  | 
|  3843  |  | 
|  3844 static ObjectPair LoadLookupSlotHelper(Arguments args, Isolate* isolate, |  | 
|  3845                                        bool throw_error) { |  | 
|  3846   HandleScope scope(isolate); |  | 
|  3847   DCHECK_EQ(2, args.length()); |  | 
|  3848  |  | 
|  3849   if (!args[0]->IsContext() || !args[1]->IsString()) { |  | 
|  3850     return MakePair(isolate->ThrowIllegalOperation(), NULL); |  | 
|  3851   } |  | 
|  3852   Handle<Context> context = args.at<Context>(0); |  | 
|  3853   Handle<String> name = args.at<String>(1); |  | 
|  3854  |  | 
|  3855   int index; |  | 
|  3856   PropertyAttributes attributes; |  | 
|  3857   ContextLookupFlags flags = FOLLOW_CHAINS; |  | 
|  3858   BindingFlags binding_flags; |  | 
|  3859   Handle<Object> holder = |  | 
|  3860       context->Lookup(name, flags, &index, &attributes, &binding_flags); |  | 
|  3861   if (isolate->has_pending_exception()) { |  | 
|  3862     return MakePair(isolate->heap()->exception(), NULL); |  | 
|  3863   } |  | 
|  3864  |  | 
|  3865   // If the index is non-negative, the slot has been found in a context. |  | 
|  3866   if (index >= 0) { |  | 
|  3867     DCHECK(holder->IsContext()); |  | 
|  3868     // If the "property" we were looking for is a local variable, the |  | 
|  3869     // receiver is the global object; see ECMA-262, 3rd., 10.1.6 and 10.2.3. |  | 
|  3870     Handle<Object> receiver = isolate->factory()->undefined_value(); |  | 
|  3871     Object* value = Context::cast(*holder)->get(index); |  | 
|  3872     // Check for uninitialized bindings. |  | 
|  3873     switch (binding_flags) { |  | 
|  3874       case MUTABLE_CHECK_INITIALIZED: |  | 
|  3875       case IMMUTABLE_CHECK_INITIALIZED_HARMONY: |  | 
|  3876         if (value->IsTheHole()) { |  | 
|  3877           Handle<Object> error; |  | 
|  3878           MaybeHandle<Object> maybe_error = |  | 
|  3879               isolate->factory()->NewReferenceError("not_defined", |  | 
|  3880                                                     HandleVector(&name, 1)); |  | 
|  3881           if (maybe_error.ToHandle(&error)) isolate->Throw(*error); |  | 
|  3882           return MakePair(isolate->heap()->exception(), NULL); |  | 
|  3883         } |  | 
|  3884       // FALLTHROUGH |  | 
|  3885       case MUTABLE_IS_INITIALIZED: |  | 
|  3886       case IMMUTABLE_IS_INITIALIZED: |  | 
|  3887       case IMMUTABLE_IS_INITIALIZED_HARMONY: |  | 
|  3888         DCHECK(!value->IsTheHole()); |  | 
|  3889         return MakePair(value, *receiver); |  | 
|  3890       case IMMUTABLE_CHECK_INITIALIZED: |  | 
|  3891         if (value->IsTheHole()) { |  | 
|  3892           DCHECK((attributes & READ_ONLY) != 0); |  | 
|  3893           value = isolate->heap()->undefined_value(); |  | 
|  3894         } |  | 
|  3895         return MakePair(value, *receiver); |  | 
|  3896       case MISSING_BINDING: |  | 
|  3897         UNREACHABLE(); |  | 
|  3898         return MakePair(NULL, NULL); |  | 
|  3899     } |  | 
|  3900   } |  | 
|  3901  |  | 
|  3902   // Otherwise, if the slot was found the holder is a context extension |  | 
|  3903   // object, subject of a with, or a global object.  We read the named |  | 
|  3904   // property from it. |  | 
|  3905   if (!holder.is_null()) { |  | 
|  3906     Handle<JSReceiver> object = Handle<JSReceiver>::cast(holder); |  | 
|  3907 #ifdef DEBUG |  | 
|  3908     if (!object->IsJSProxy()) { |  | 
|  3909       Maybe<bool> maybe = JSReceiver::HasProperty(object, name); |  | 
|  3910       DCHECK(maybe.has_value); |  | 
|  3911       DCHECK(maybe.value); |  | 
|  3912     } |  | 
|  3913 #endif |  | 
|  3914     // GetProperty below can cause GC. |  | 
|  3915     Handle<Object> receiver_handle( |  | 
|  3916         object->IsGlobalObject() |  | 
|  3917             ? Object::cast(isolate->heap()->undefined_value()) |  | 
|  3918             : object->IsJSProxy() ? static_cast<Object*>(*object) |  | 
|  3919                                   : ComputeReceiverForNonGlobal( |  | 
|  3920                                         isolate, JSObject::cast(*object)), |  | 
|  3921         isolate); |  | 
|  3922  |  | 
|  3923     // No need to unhole the value here.  This is taken care of by the |  | 
|  3924     // GetProperty function. |  | 
|  3925     Handle<Object> value; |  | 
|  3926     ASSIGN_RETURN_ON_EXCEPTION_VALUE( |  | 
|  3927         isolate, value, Object::GetProperty(object, name), |  | 
|  3928         MakePair(isolate->heap()->exception(), NULL)); |  | 
|  3929     return MakePair(*value, *receiver_handle); |  | 
|  3930   } |  | 
|  3931  |  | 
|  3932   if (throw_error) { |  | 
|  3933     // The property doesn't exist - throw exception. |  | 
|  3934     Handle<Object> error; |  | 
|  3935     MaybeHandle<Object> maybe_error = isolate->factory()->NewReferenceError( |  | 
|  3936         "not_defined", HandleVector(&name, 1)); |  | 
|  3937     if (maybe_error.ToHandle(&error)) isolate->Throw(*error); |  | 
|  3938     return MakePair(isolate->heap()->exception(), NULL); |  | 
|  3939   } else { |  | 
|  3940     // The property doesn't exist - return undefined. |  | 
|  3941     return MakePair(isolate->heap()->undefined_value(), |  | 
|  3942                     isolate->heap()->undefined_value()); |  | 
|  3943   } |  | 
|  3944 } |  | 
|  3945  |  | 
|  3946  |  | 
|  3947 RUNTIME_FUNCTION_RETURN_PAIR(Runtime_LoadLookupSlot) { |  | 
|  3948   return LoadLookupSlotHelper(args, isolate, true); |  | 
|  3949 } |  | 
|  3950  |  | 
|  3951  |  | 
|  3952 RUNTIME_FUNCTION_RETURN_PAIR(Runtime_LoadLookupSlotNoReferenceError) { |  | 
|  3953   return LoadLookupSlotHelper(args, isolate, false); |  | 
|  3954 } |  | 
|  3955  |  | 
|  3956  |  | 
|  3957 RUNTIME_FUNCTION(Runtime_StoreLookupSlot) { |  | 
|  3958   HandleScope scope(isolate); |  | 
|  3959   DCHECK(args.length() == 4); |  | 
|  3960  |  | 
|  3961   CONVERT_ARG_HANDLE_CHECKED(Object, value, 0); |  | 
|  3962   CONVERT_ARG_HANDLE_CHECKED(Context, context, 1); |  | 
|  3963   CONVERT_ARG_HANDLE_CHECKED(String, name, 2); |  | 
|  3964   CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 3); |  | 
|  3965  |  | 
|  3966   int index; |  | 
|  3967   PropertyAttributes attributes; |  | 
|  3968   ContextLookupFlags flags = FOLLOW_CHAINS; |  | 
|  3969   BindingFlags binding_flags; |  | 
|  3970   Handle<Object> holder = |  | 
|  3971       context->Lookup(name, flags, &index, &attributes, &binding_flags); |  | 
|  3972   // In case of JSProxy, an exception might have been thrown. |  | 
|  3973   if (isolate->has_pending_exception()) return isolate->heap()->exception(); |  | 
|  3974  |  | 
|  3975   // The property was found in a context slot. |  | 
|  3976   if (index >= 0) { |  | 
|  3977     if ((attributes & READ_ONLY) == 0) { |  | 
|  3978       Handle<Context>::cast(holder)->set(index, *value); |  | 
|  3979     } else if (strict_mode == STRICT) { |  | 
|  3980       // Setting read only property in strict mode. |  | 
|  3981       THROW_NEW_ERROR_RETURN_FAILURE( |  | 
|  3982           isolate, |  | 
|  3983           NewTypeError("strict_cannot_assign", HandleVector(&name, 1))); |  | 
|  3984     } |  | 
|  3985     return *value; |  | 
|  3986   } |  | 
|  3987  |  | 
|  3988   // Slow case: The property is not in a context slot.  It is either in a |  | 
|  3989   // context extension object, a property of the subject of a with, or a |  | 
|  3990   // property of the global object. |  | 
|  3991   Handle<JSReceiver> object; |  | 
|  3992   if (attributes != ABSENT) { |  | 
|  3993     // The property exists on the holder. |  | 
|  3994     object = Handle<JSReceiver>::cast(holder); |  | 
|  3995   } else if (strict_mode == STRICT) { |  | 
|  3996     // If absent in strict mode: throw. |  | 
|  3997     THROW_NEW_ERROR_RETURN_FAILURE( |  | 
|  3998         isolate, NewReferenceError("not_defined", HandleVector(&name, 1))); |  | 
|  3999   } else { |  | 
|  4000     // If absent in sloppy mode: add the property to the global object. |  | 
|  4001     object = Handle<JSReceiver>(context->global_object()); |  | 
|  4002   } |  | 
|  4003  |  | 
|  4004   RETURN_FAILURE_ON_EXCEPTION( |  | 
|  4005       isolate, Object::SetProperty(object, name, value, strict_mode)); |  | 
|  4006  |  | 
|  4007   return *value; |  | 
|  4008 } |  | 
|  4009  |  | 
|  4010  |  | 
|  4011 RUNTIME_FUNCTION(Runtime_Throw) { |  1826 RUNTIME_FUNCTION(Runtime_Throw) { | 
|  4012   HandleScope scope(isolate); |  1827   HandleScope scope(isolate); | 
|  4013   DCHECK(args.length() == 1); |  1828   DCHECK(args.length() == 1); | 
|  4014  |  1829  | 
|  4015   return isolate->Throw(args[0]); |  1830   return isolate->Throw(args[0]); | 
|  4016 } |  1831 } | 
|  4017  |  1832  | 
|  4018  |  1833  | 
|  4019 RUNTIME_FUNCTION(Runtime_ReThrow) { |  1834 RUNTIME_FUNCTION(Runtime_ReThrow) { | 
|  4020   HandleScope scope(isolate); |  1835   HandleScope scope(isolate); | 
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  4071 } |  1886 } | 
|  4072  |  1887  | 
|  4073  |  1888  | 
|  4074 RUNTIME_FUNCTION(Runtime_Interrupt) { |  1889 RUNTIME_FUNCTION(Runtime_Interrupt) { | 
|  4075   SealHandleScope shs(isolate); |  1890   SealHandleScope shs(isolate); | 
|  4076   DCHECK(args.length() == 0); |  1891   DCHECK(args.length() == 0); | 
|  4077   return isolate->stack_guard()->HandleInterrupts(); |  1892   return isolate->stack_guard()->HandleInterrupts(); | 
|  4078 } |  1893 } | 
|  4079  |  1894  | 
|  4080  |  1895  | 
|  4081 static int StackSize(Isolate* isolate) { |  | 
|  4082   int n = 0; |  | 
|  4083   for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) n++; |  | 
|  4084   return n; |  | 
|  4085 } |  | 
|  4086  |  | 
|  4087  |  | 
|  4088 static void PrintTransition(Isolate* isolate, Object* result) { |  | 
|  4089   // indentation |  | 
|  4090   { |  | 
|  4091     const int nmax = 80; |  | 
|  4092     int n = StackSize(isolate); |  | 
|  4093     if (n <= nmax) |  | 
|  4094       PrintF("%4d:%*s", n, n, ""); |  | 
|  4095     else |  | 
|  4096       PrintF("%4d:%*s", n, nmax, "..."); |  | 
|  4097   } |  | 
|  4098  |  | 
|  4099   if (result == NULL) { |  | 
|  4100     JavaScriptFrame::PrintTop(isolate, stdout, true, false); |  | 
|  4101     PrintF(" {\n"); |  | 
|  4102   } else { |  | 
|  4103     // function result |  | 
|  4104     PrintF("} -> "); |  | 
|  4105     result->ShortPrint(); |  | 
|  4106     PrintF("\n"); |  | 
|  4107   } |  | 
|  4108 } |  | 
|  4109  |  | 
|  4110  |  | 
|  4111 RUNTIME_FUNCTION(Runtime_TraceEnter) { |  | 
|  4112   SealHandleScope shs(isolate); |  | 
|  4113   DCHECK(args.length() == 0); |  | 
|  4114   PrintTransition(isolate, NULL); |  | 
|  4115   return isolate->heap()->undefined_value(); |  | 
|  4116 } |  | 
|  4117  |  | 
|  4118  |  | 
|  4119 RUNTIME_FUNCTION(Runtime_TraceExit) { |  | 
|  4120   SealHandleScope shs(isolate); |  | 
|  4121   DCHECK(args.length() == 1); |  | 
|  4122   CONVERT_ARG_CHECKED(Object, obj, 0); |  | 
|  4123   PrintTransition(isolate, obj); |  | 
|  4124   return obj;  // return TOS |  | 
|  4125 } |  | 
|  4126  |  | 
|  4127  |  | 
|  4128 RUNTIME_FUNCTION(Runtime_GlobalProxy) { |  1896 RUNTIME_FUNCTION(Runtime_GlobalProxy) { | 
|  4129   SealHandleScope shs(isolate); |  1897   SealHandleScope shs(isolate); | 
|  4130   DCHECK(args.length() == 1); |  1898   DCHECK(args.length() == 1); | 
|  4131   CONVERT_ARG_CHECKED(Object, global, 0); |  1899   CONVERT_ARG_CHECKED(Object, global, 0); | 
|  4132   if (!global->IsJSGlobalObject()) return isolate->heap()->null_value(); |  1900   if (!global->IsJSGlobalObject()) return isolate->heap()->null_value(); | 
|  4133   return JSGlobalObject::cast(global)->global_proxy(); |  1901   return JSGlobalObject::cast(global)->global_proxy(); | 
|  4134 } |  1902 } | 
|  4135  |  1903  | 
|  4136  |  1904  | 
|  4137 RUNTIME_FUNCTION(Runtime_IsAttachedGlobal) { |  1905 RUNTIME_FUNCTION(Runtime_IsAttachedGlobal) { | 
| (...skipping 1061 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  5199  |  2967  | 
|  5200  |  2968  | 
|  5201 RUNTIME_FUNCTION(Runtime_IsJSGlobalProxy) { |  2969 RUNTIME_FUNCTION(Runtime_IsJSGlobalProxy) { | 
|  5202   SealHandleScope shs(isolate); |  2970   SealHandleScope shs(isolate); | 
|  5203   DCHECK(args.length() == 1); |  2971   DCHECK(args.length() == 1); | 
|  5204   CONVERT_ARG_CHECKED(Object, obj, 0); |  2972   CONVERT_ARG_CHECKED(Object, obj, 0); | 
|  5205   return isolate->heap()->ToBoolean(obj->IsJSGlobalProxy()); |  2973   return isolate->heap()->ToBoolean(obj->IsJSGlobalProxy()); | 
|  5206 } |  2974 } | 
|  5207  |  2975  | 
|  5208  |  2976  | 
|  5209 RUNTIME_FUNCTION(Runtime_IsObserved) { |  | 
|  5210   SealHandleScope shs(isolate); |  | 
|  5211   DCHECK(args.length() == 1); |  | 
|  5212  |  | 
|  5213   if (!args[0]->IsJSReceiver()) return isolate->heap()->false_value(); |  | 
|  5214   CONVERT_ARG_CHECKED(JSReceiver, obj, 0); |  | 
|  5215   DCHECK(!obj->IsJSGlobalProxy() || !obj->map()->is_observed()); |  | 
|  5216   return isolate->heap()->ToBoolean(obj->map()->is_observed()); |  | 
|  5217 } |  | 
|  5218  |  | 
|  5219  |  | 
|  5220 RUNTIME_FUNCTION(Runtime_SetIsObserved) { |  | 
|  5221   HandleScope scope(isolate); |  | 
|  5222   DCHECK(args.length() == 1); |  | 
|  5223   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, obj, 0); |  | 
|  5224   RUNTIME_ASSERT(!obj->IsJSGlobalProxy()); |  | 
|  5225   if (obj->IsJSProxy()) return isolate->heap()->undefined_value(); |  | 
|  5226   RUNTIME_ASSERT(!obj->map()->is_observed()); |  | 
|  5227  |  | 
|  5228   DCHECK(obj->IsJSObject()); |  | 
|  5229   JSObject::SetObserved(Handle<JSObject>::cast(obj)); |  | 
|  5230   return isolate->heap()->undefined_value(); |  | 
|  5231 } |  | 
|  5232  |  | 
|  5233  |  | 
|  5234 RUNTIME_FUNCTION(Runtime_EnqueueMicrotask) { |  | 
|  5235   HandleScope scope(isolate); |  | 
|  5236   DCHECK(args.length() == 1); |  | 
|  5237   CONVERT_ARG_HANDLE_CHECKED(JSFunction, microtask, 0); |  | 
|  5238   isolate->EnqueueMicrotask(microtask); |  | 
|  5239   return isolate->heap()->undefined_value(); |  | 
|  5240 } |  | 
|  5241  |  | 
|  5242  |  | 
|  5243 RUNTIME_FUNCTION(Runtime_RunMicrotasks) { |  | 
|  5244   HandleScope scope(isolate); |  | 
|  5245   DCHECK(args.length() == 0); |  | 
|  5246   isolate->RunMicrotasks(); |  | 
|  5247   return isolate->heap()->undefined_value(); |  | 
|  5248 } |  | 
|  5249  |  | 
|  5250  |  | 
|  5251 RUNTIME_FUNCTION(Runtime_GetObservationState) { |  | 
|  5252   SealHandleScope shs(isolate); |  | 
|  5253   DCHECK(args.length() == 0); |  | 
|  5254   return isolate->heap()->observation_state(); |  | 
|  5255 } |  | 
|  5256  |  | 
|  5257  |  | 
|  5258 static bool ContextsHaveSameOrigin(Handle<Context> context1, |  | 
|  5259                                    Handle<Context> context2) { |  | 
|  5260   return context1->security_token() == context2->security_token(); |  | 
|  5261 } |  | 
|  5262  |  | 
|  5263  |  | 
|  5264 RUNTIME_FUNCTION(Runtime_ObserverObjectAndRecordHaveSameOrigin) { |  | 
|  5265   HandleScope scope(isolate); |  | 
|  5266   DCHECK(args.length() == 3); |  | 
|  5267   CONVERT_ARG_HANDLE_CHECKED(JSFunction, observer, 0); |  | 
|  5268   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 1); |  | 
|  5269   CONVERT_ARG_HANDLE_CHECKED(JSObject, record, 2); |  | 
|  5270  |  | 
|  5271   Handle<Context> observer_context(observer->context()->native_context()); |  | 
|  5272   Handle<Context> object_context(object->GetCreationContext()); |  | 
|  5273   Handle<Context> record_context(record->GetCreationContext()); |  | 
|  5274  |  | 
|  5275   return isolate->heap()->ToBoolean( |  | 
|  5276       ContextsHaveSameOrigin(object_context, observer_context) && |  | 
|  5277       ContextsHaveSameOrigin(object_context, record_context)); |  | 
|  5278 } |  | 
|  5279  |  | 
|  5280  |  | 
|  5281 RUNTIME_FUNCTION(Runtime_ObjectWasCreatedInCurrentOrigin) { |  | 
|  5282   HandleScope scope(isolate); |  | 
|  5283   DCHECK(args.length() == 1); |  | 
|  5284   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); |  | 
|  5285  |  | 
|  5286   Handle<Context> creation_context(object->GetCreationContext(), isolate); |  | 
|  5287   return isolate->heap()->ToBoolean( |  | 
|  5288       ContextsHaveSameOrigin(creation_context, isolate->native_context())); |  | 
|  5289 } |  | 
|  5290  |  | 
|  5291  |  | 
|  5292 RUNTIME_FUNCTION(Runtime_GetObjectContextObjectObserve) { |  | 
|  5293   HandleScope scope(isolate); |  | 
|  5294   DCHECK(args.length() == 1); |  | 
|  5295   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); |  | 
|  5296  |  | 
|  5297   Handle<Context> context(object->GetCreationContext(), isolate); |  | 
|  5298   return context->native_object_observe(); |  | 
|  5299 } |  | 
|  5300  |  | 
|  5301  |  | 
|  5302 RUNTIME_FUNCTION(Runtime_GetObjectContextObjectGetNotifier) { |  | 
|  5303   HandleScope scope(isolate); |  | 
|  5304   DCHECK(args.length() == 1); |  | 
|  5305   CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); |  | 
|  5306  |  | 
|  5307   Handle<Context> context(object->GetCreationContext(), isolate); |  | 
|  5308   return context->native_object_get_notifier(); |  | 
|  5309 } |  | 
|  5310  |  | 
|  5311  |  | 
|  5312 RUNTIME_FUNCTION(Runtime_GetObjectContextNotifierPerformChange) { |  | 
|  5313   HandleScope scope(isolate); |  | 
|  5314   DCHECK(args.length() == 1); |  | 
|  5315   CONVERT_ARG_HANDLE_CHECKED(JSObject, object_info, 0); |  | 
|  5316  |  | 
|  5317   Handle<Context> context(object_info->GetCreationContext(), isolate); |  | 
|  5318   return context->native_object_notifier_perform_change(); |  | 
|  5319 } |  | 
|  5320  |  | 
|  5321  |  | 
|  5322 static Object* ArrayConstructorCommon(Isolate* isolate, |  2977 static Object* ArrayConstructorCommon(Isolate* isolate, | 
|  5323                                       Handle<JSFunction> constructor, |  2978                                       Handle<JSFunction> constructor, | 
|  5324                                       Handle<AllocationSite> site, |  2979                                       Handle<AllocationSite> site, | 
|  5325                                       Arguments* caller_args) { |  2980                                       Arguments* caller_args) { | 
|  5326   Factory* factory = isolate->factory(); |  2981   Factory* factory = isolate->factory(); | 
|  5327  |  2982  | 
|  5328   bool holey = false; |  2983   bool holey = false; | 
|  5329   bool can_use_type_feedback = true; |  2984   bool can_use_type_feedback = true; | 
|  5330   if (caller_args->length() == 1) { |  2985   if (caller_args->length() == 1) { | 
|  5331     Handle<Object> argument_one = caller_args->at<Object>(0); |  2986     Handle<Object> argument_one = caller_args->at<Object>(0); | 
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  5565     UNIMPLEMENTED();                          \ |  3220     UNIMPLEMENTED();                          \ | 
|  5566     return NULL;                              \ |  3221     return NULL;                              \ | 
|  5567   } |  3222   } | 
|  5568  |  3223  | 
|  5569 U(IsStringWrapperSafeForDefaultValueOf) |  3224 U(IsStringWrapperSafeForDefaultValueOf) | 
|  5570 U(DebugBreakInOptimizedCode) |  3225 U(DebugBreakInOptimizedCode) | 
|  5571  |  3226  | 
|  5572 #undef U |  3227 #undef U | 
|  5573  |  3228  | 
|  5574  |  3229  | 
|  5575 RUNTIME_FUNCTION(RuntimeReference_IsSmi) { |  | 
|  5576   SealHandleScope shs(isolate); |  | 
|  5577   DCHECK(args.length() == 1); |  | 
|  5578   CONVERT_ARG_CHECKED(Object, obj, 0); |  | 
|  5579   return isolate->heap()->ToBoolean(obj->IsSmi()); |  | 
|  5580 } |  | 
|  5581  |  | 
|  5582  |  | 
|  5583 RUNTIME_FUNCTION(RuntimeReference_IsNonNegativeSmi) { |  | 
|  5584   SealHandleScope shs(isolate); |  | 
|  5585   DCHECK(args.length() == 1); |  | 
|  5586   CONVERT_ARG_CHECKED(Object, obj, 0); |  | 
|  5587   return isolate->heap()->ToBoolean(obj->IsSmi() && |  | 
|  5588                                     Smi::cast(obj)->value() >= 0); |  | 
|  5589 } |  | 
|  5590  |  | 
|  5591  |  | 
|  5592 RUNTIME_FUNCTION(RuntimeReference_IsArray) { |  3230 RUNTIME_FUNCTION(RuntimeReference_IsArray) { | 
|  5593   SealHandleScope shs(isolate); |  3231   SealHandleScope shs(isolate); | 
|  5594   DCHECK(args.length() == 1); |  3232   DCHECK(args.length() == 1); | 
|  5595   CONVERT_ARG_CHECKED(Object, obj, 0); |  3233   CONVERT_ARG_CHECKED(Object, obj, 0); | 
|  5596   return isolate->heap()->ToBoolean(obj->IsJSArray()); |  3234   return isolate->heap()->ToBoolean(obj->IsJSArray()); | 
|  5597 } |  3235 } | 
|  5598  |  3236  | 
|  5599  |  3237  | 
|  5600 RUNTIME_FUNCTION(RuntimeReference_IsRegExp) { |  | 
|  5601   SealHandleScope shs(isolate); |  | 
|  5602   DCHECK(args.length() == 1); |  | 
|  5603   CONVERT_ARG_CHECKED(Object, obj, 0); |  | 
|  5604   return isolate->heap()->ToBoolean(obj->IsJSRegExp()); |  | 
|  5605 } |  | 
|  5606  |  | 
|  5607  |  | 
|  5608 RUNTIME_FUNCTION(RuntimeReference_IsConstructCall) { |  | 
|  5609   SealHandleScope shs(isolate); |  | 
|  5610   DCHECK(args.length() == 0); |  | 
|  5611   JavaScriptFrameIterator it(isolate); |  | 
|  5612   JavaScriptFrame* frame = it.frame(); |  | 
|  5613   return isolate->heap()->ToBoolean(frame->IsConstructor()); |  | 
|  5614 } |  | 
|  5615  |  | 
|  5616  |  | 
|  5617 RUNTIME_FUNCTION(RuntimeReference_CallFunction) { |  | 
|  5618   SealHandleScope shs(isolate); |  | 
|  5619   return __RT_impl_Runtime_Call(args, isolate); |  | 
|  5620 } |  | 
|  5621  |  | 
|  5622  |  | 
|  5623 RUNTIME_FUNCTION(RuntimeReference_ArgumentsLength) { |  | 
|  5624   SealHandleScope shs(isolate); |  | 
|  5625   DCHECK(args.length() == 0); |  | 
|  5626   JavaScriptFrameIterator it(isolate); |  | 
|  5627   JavaScriptFrame* frame = it.frame(); |  | 
|  5628   return Smi::FromInt(frame->GetArgumentsLength()); |  | 
|  5629 } |  | 
|  5630  |  | 
|  5631  |  | 
|  5632 RUNTIME_FUNCTION(RuntimeReference_Arguments) { |  | 
|  5633   SealHandleScope shs(isolate); |  | 
|  5634   return __RT_impl_Runtime_GetArgumentsProperty(args, isolate); |  | 
|  5635 } |  | 
|  5636  |  | 
|  5637  |  3238  | 
|  5638 RUNTIME_FUNCTION(RuntimeReference_ValueOf) { |  3239 RUNTIME_FUNCTION(RuntimeReference_ValueOf) { | 
|  5639   SealHandleScope shs(isolate); |  3240   SealHandleScope shs(isolate); | 
|  5640   DCHECK(args.length() == 1); |  3241   DCHECK(args.length() == 1); | 
|  5641   CONVERT_ARG_CHECKED(Object, obj, 0); |  3242   CONVERT_ARG_CHECKED(Object, obj, 0); | 
|  5642   if (!obj->IsJSValue()) return obj; |  3243   if (!obj->IsJSValue()) return obj; | 
|  5643   return JSValue::cast(obj)->value(); |  3244   return JSValue::cast(obj)->value(); | 
|  5644 } |  3245 } | 
|  5645  |  3246  | 
|  5646  |  3247  | 
| (...skipping 25 matching lines...) Expand all  Loading... | 
|  5672   if (obj->IsNull()) return isolate->heap()->true_value(); |  3273   if (obj->IsNull()) return isolate->heap()->true_value(); | 
|  5673   if (obj->IsUndetectableObject()) return isolate->heap()->false_value(); |  3274   if (obj->IsUndetectableObject()) return isolate->heap()->false_value(); | 
|  5674   Map* map = HeapObject::cast(obj)->map(); |  3275   Map* map = HeapObject::cast(obj)->map(); | 
|  5675   bool is_non_callable_spec_object = |  3276   bool is_non_callable_spec_object = | 
|  5676       map->instance_type() >= FIRST_NONCALLABLE_SPEC_OBJECT_TYPE && |  3277       map->instance_type() >= FIRST_NONCALLABLE_SPEC_OBJECT_TYPE && | 
|  5677       map->instance_type() <= LAST_NONCALLABLE_SPEC_OBJECT_TYPE; |  3278       map->instance_type() <= LAST_NONCALLABLE_SPEC_OBJECT_TYPE; | 
|  5678   return isolate->heap()->ToBoolean(is_non_callable_spec_object); |  3279   return isolate->heap()->ToBoolean(is_non_callable_spec_object); | 
|  5679 } |  3280 } | 
|  5680  |  3281  | 
|  5681  |  3282  | 
|  5682 RUNTIME_FUNCTION(RuntimeReference_IsFunction) { |  | 
|  5683   SealHandleScope shs(isolate); |  | 
|  5684   DCHECK(args.length() == 1); |  | 
|  5685   CONVERT_ARG_CHECKED(Object, obj, 0); |  | 
|  5686   return isolate->heap()->ToBoolean(obj->IsJSFunction()); |  | 
|  5687 } |  | 
|  5688  |  | 
|  5689  |  | 
|  5690 RUNTIME_FUNCTION(RuntimeReference_IsUndetectableObject) { |  3283 RUNTIME_FUNCTION(RuntimeReference_IsUndetectableObject) { | 
|  5691   SealHandleScope shs(isolate); |  3284   SealHandleScope shs(isolate); | 
|  5692   DCHECK(args.length() == 1); |  3285   DCHECK(args.length() == 1); | 
|  5693   CONVERT_ARG_CHECKED(Object, obj, 0); |  3286   CONVERT_ARG_CHECKED(Object, obj, 0); | 
|  5694   return isolate->heap()->ToBoolean(obj->IsUndetectableObject()); |  3287   return isolate->heap()->ToBoolean(obj->IsUndetectableObject()); | 
|  5695 } |  3288 } | 
|  5696  |  3289  | 
|  5697  |  3290  | 
|  5698 RUNTIME_FUNCTION(RuntimeReference_IsSpecObject) { |  3291 RUNTIME_FUNCTION(RuntimeReference_IsSpecObject) { | 
|  5699   SealHandleScope shs(isolate); |  3292   SealHandleScope shs(isolate); | 
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  5815   } |  3408   } | 
|  5816   return NULL; |  3409   return NULL; | 
|  5817 } |  3410 } | 
|  5818  |  3411  | 
|  5819  |  3412  | 
|  5820 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { |  3413 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { | 
|  5821   return &(kIntrinsicFunctions[static_cast<int>(id)]); |  3414   return &(kIntrinsicFunctions[static_cast<int>(id)]); | 
|  5822 } |  3415 } | 
|  5823 } |  3416 } | 
|  5824 }  // namespace v8::internal |  3417 }  // namespace v8::internal | 
| OLD | NEW |