1958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Copyright 2014 the V8 project authors. All rights reserved. 2958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Use of this source code is governed by a BSD-style license that can be 3958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// found in the LICENSE file. 4958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 5014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/runtime/runtime-utils.h" 6958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 7f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include <memory> 8f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 9958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/accessors.h" 10958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/arguments.h" 11014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/ast/scopes.h" 12014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/deoptimizer.h" 13958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/frames-inl.h" 14014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/isolate-inl.h" 15014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/messages.h" 16958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 17958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniernamespace v8 { 18958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniernamespace internal { 19958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 20f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochRUNTIME_FUNCTION(Runtime_ThrowConstAssignError) { 21f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch HandleScope scope(isolate); 22f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch THROW_NEW_ERROR_RETURN_FAILURE(isolate, 23f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch NewTypeError(MessageTemplate::kConstAssign)); 24f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 25f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 26f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochnamespace { 27f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 2813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochenum class RedeclarationType { kSyntaxError = 0, kTypeError = 1 }; 2913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 30f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochObject* ThrowRedeclarationError(Isolate* isolate, Handle<String> name, 31f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch RedeclarationType redeclaration_type) { 32958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HandleScope scope(isolate); 3313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (redeclaration_type == RedeclarationType::kSyntaxError) { 3413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch THROW_NEW_ERROR_RETURN_FAILURE( 3513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch isolate, NewSyntaxError(MessageTemplate::kVarRedeclaration, name)); 3613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } else { 3713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch THROW_NEW_ERROR_RETURN_FAILURE( 3813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch isolate, NewTypeError(MessageTemplate::kVarRedeclaration, name)); 3913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 40958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 41958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 42958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 43958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// May throw a RedeclarationError. 44f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochObject* DeclareGlobal( 45f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Isolate* isolate, Handle<JSGlobalObject> global, Handle<String> name, 46f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<Object> value, PropertyAttributes attr, bool is_var, 47f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch bool is_function_declaration, RedeclarationType redeclaration_type, 48f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<TypeFeedbackVector> feedback_vector = Handle<TypeFeedbackVector>(), 49f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch FeedbackVectorSlot slot = FeedbackVectorSlot::Invalid()) { 50958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<ScriptContextTable> script_contexts( 51958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier global->native_context()->script_context_table()); 52958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ScriptContextTable::LookupResult lookup; 53958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (ScriptContextTable::Lookup(script_contexts, name, &lookup) && 54958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier IsLexicalVariableMode(lookup.mode)) { 5513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // ES#sec-globaldeclarationinstantiation 6.a: 5613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // If envRec.HasLexicalDeclaration(name) is true, throw a SyntaxError 5713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // exception. 5813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return ThrowRedeclarationError(isolate, name, 5913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch RedeclarationType::kSyntaxError); 60958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 61958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 62958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Do the lookup own properties only, see ES5 erratum. 63f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch LookupIterator::Configuration lookup_config( 64f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch LookupIterator::Configuration::OWN_SKIP_INTERCEPTOR); 65f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (is_function_declaration) { 66f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // For function declarations, use the interceptor on the declaration. For 67f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // non-functions, use it only on initialization. 68f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch lookup_config = LookupIterator::Configuration::OWN; 69f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 70f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch LookupIterator it(global, name, global, lookup_config); 71958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it); 72014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!maybe.IsJust()) return isolate->heap()->exception(); 73958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 74958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (it.IsFound()) { 75014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PropertyAttributes old_attributes = maybe.FromJust(); 76958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // The name was declared before; check for conflicting re-declarations. 77958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 78958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Skip var re-declarations. 79958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (is_var) return isolate->heap()->undefined_value(); 80958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 81f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch DCHECK(is_function_declaration); 82958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if ((old_attributes & DONT_DELETE) != 0) { 83958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Only allow reconfiguring globals to functions in user code (no 84958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // natives, which are marked as read-only). 85958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK((attr & READ_ONLY) == 0); 86958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 87958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Check whether we can reconfigure the existing property into a 88958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // function. 89958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PropertyDetails old_details = it.property_details(); 90958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (old_details.IsReadOnly() || old_details.IsDontEnum() || 91109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch (it.state() == LookupIterator::ACCESSOR && 92109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch it.GetAccessors()->IsAccessorPair())) { 93f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // ECMA-262 section 15.1.11 GlobalDeclarationInstantiation 5.d: 9413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // If hasRestrictedGlobal is true, throw a SyntaxError exception. 95f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // ECMA-262 section 18.2.1.3 EvalDeclarationInstantiation 8.a.iv.1.b: 9613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // If fnDefinable is false, throw a TypeError exception. 9713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return ThrowRedeclarationError(isolate, name, redeclaration_type); 98958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 99958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // If the existing property is not configurable, keep its attributes. Do 100958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier attr = old_attributes; 101958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 102109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 103109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // If the current state is ACCESSOR, this could mean it's an AccessorInfo 104109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // type property. We are not allowed to call into such setters during global 105109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // function declaration since this would break e.g., onload. Meaning 106109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // 'function onload() {}' would invalidly register that function as the 107109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // onload callback. To avoid this situation, we first delete the property 108109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // before readding it as a regular data property below. 109109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (it.state() == LookupIterator::ACCESSOR) it.Delete(); 110958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 111958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 112f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (is_function_declaration) { 113f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch it.Restart(); 114f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 115f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 116958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Define or redefine own property. 117109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch RETURN_FAILURE_ON_EXCEPTION( 118109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch isolate, JSObject::DefineOwnPropertyIgnoreAttributes(&it, value, attr)); 119958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 120f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (!feedback_vector.is_null()) { 121f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK_EQ(*global, *it.GetHolder<Object>()); 122f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Preinitialize the feedback slot if the global object does not have 123f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // named interceptor or the interceptor is not masking. 124f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (!global->HasNamedInterceptor() || 125f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch global->GetNamedInterceptor()->non_masking()) { 126f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch LoadGlobalICNexus nexus(feedback_vector, slot); 127f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch nexus.ConfigurePropertyCellMode(it.GetPropertyCell()); 128f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 129f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 130958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return isolate->heap()->undefined_value(); 131958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 132958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 133f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochObject* DeclareGlobals(Isolate* isolate, Handle<FixedArray> pairs, int flags, 134f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<TypeFeedbackVector> feedback_vector) { 135958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HandleScope scope(isolate); 136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<JSGlobalObject> global(isolate->global_object()); 137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Context> context(isolate->context()); 138958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 139958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Traverse the name/value pairs and set the properties. 140958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int length = pairs->length(); 1413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch FOR_WITH_HANDLE_SCOPE(isolate, int, i = 0, i, i < length, i += 2, { 142f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch FeedbackVectorSlot slot(Smi::cast(pairs->get(i))->value()); 143f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<String> name(feedback_vector->GetName(slot), isolate); 144958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<Object> initial_value(pairs->get(i + 1), isolate); 145958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 14613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch bool is_var = initial_value->IsUndefined(isolate); 147958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool is_function = initial_value->IsSharedFunctionInfo(); 14813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK_EQ(1, BoolToInt(is_var) + BoolToInt(is_function)); 149958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 150958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<Object> value; 151958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (is_function) { 152958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Copy the function and update its context. Use it as value. 153958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<SharedFunctionInfo> shared = 154958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<SharedFunctionInfo>::cast(initial_value); 155958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<JSFunction> function = 156958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, context, 157958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier TENURED); 158958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier value = function; 159958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 160958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier value = isolate->factory()->undefined_value(); 161958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 162958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 163958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Compute the property attributes. According to ECMA-262, 164958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // the property must be non-configurable except in eval. 165958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool is_native = DeclareGlobalsNativeFlag::decode(flags); 166958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool is_eval = DeclareGlobalsEvalFlag::decode(flags); 167958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int attr = NONE; 168958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (is_function && is_native) attr |= READ_ONLY; 16913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (!is_eval) attr |= DONT_DELETE; 170958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 17113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // ES#sec-globaldeclarationinstantiation 5.d: 17213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // If hasRestrictedGlobal is true, throw a SyntaxError exception. 173f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Object* result = DeclareGlobal( 17413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch isolate, global, name, value, static_cast<PropertyAttributes>(attr), 175f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch is_var, is_function, RedeclarationType::kSyntaxError, feedback_vector, 176f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch slot); 177958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (isolate->has_pending_exception()) return result; 1783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch }); 179958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 180958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return isolate->heap()->undefined_value(); 181958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 182958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 183f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} // namespace 184958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 185f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochRUNTIME_FUNCTION(Runtime_DeclareGlobals) { 186958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HandleScope scope(isolate); 18713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK_EQ(3, args.length()); 188958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 189f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CONVERT_ARG_HANDLE_CHECKED(FixedArray, pairs, 0); 190f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CONVERT_SMI_ARG_CHECKED(flags, 1); 191f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CONVERT_ARG_HANDLE_CHECKED(TypeFeedbackVector, feedback_vector, 2); 192958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 193f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return DeclareGlobals(isolate, pairs, flags, feedback_vector); 194f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 195958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 196f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// TODO(ishell): merge this with Runtime::kDeclareGlobals once interpreter 197f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// is able to pass feedback vector. 198f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochRUNTIME_FUNCTION(Runtime_DeclareGlobalsForInterpreter) { 199f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch HandleScope scope(isolate); 200f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK_EQ(3, args.length()); 201958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 202f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CONVERT_ARG_HANDLE_CHECKED(FixedArray, pairs, 0); 203f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CONVERT_SMI_ARG_CHECKED(flags, 1); 204f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CONVERT_ARG_HANDLE_CHECKED(JSFunction, closure, 2); 205958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 206f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<TypeFeedbackVector> feedback_vector(closure->feedback_vector(), 207f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch isolate); 208f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return DeclareGlobals(isolate, pairs, flags, feedback_vector); 209f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 210958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 211f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochRUNTIME_FUNCTION(Runtime_InitializeVarGlobal) { 212f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch HandleScope scope(isolate); 213f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK_EQ(3, args.length()); 214f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CONVERT_ARG_HANDLE_CHECKED(String, name, 0); 215f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CONVERT_LANGUAGE_MODE_ARG_CHECKED(language_mode, 1); 216f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CONVERT_ARG_HANDLE_CHECKED(Object, value, 2); 217958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 218f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<JSGlobalObject> global(isolate->global_object()); 219f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch RETURN_RESULT_OR_FAILURE( 220f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch isolate, Object::SetProperty(global, name, value, language_mode)); 221958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 222958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace { 224958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 22513e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochObject* DeclareEvalHelper(Isolate* isolate, Handle<String> name, 22613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Handle<Object> value) { 22713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // Declarations are always made in a function, native, or script context, or 22813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // a declaration block scope. Since this is called from eval, the context 22913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // passed is the context of the caller, which may be some nested context and 23013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // not the declaration context. 231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Context> context_arg(isolate->context(), isolate); 232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Context> context(context_arg->declaration_context(), isolate); 233958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 23413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK(context->IsFunctionContext() || context->IsNativeContext() || 23513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch context->IsScriptContext() || 23613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch (context->IsBlockContext() && context->has_extension())); 23713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 23813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch bool is_function = value->IsJSFunction(); 23913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch bool is_var = !is_function; 24013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK(!is_var || value->IsUndefined(isolate)); 241958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 242958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int index; 243958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PropertyAttributes attributes; 244f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch InitializationFlag init_flag; 245f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch VariableMode mode; 246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 24713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // Check for a conflict with a lexically scoped variable 248f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch context_arg->Lookup(name, LEXICAL_TEST, &index, &attributes, &init_flag, 249f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch &mode); 250f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (attributes != ABSENT && IsLexicalVariableMode(mode)) { 25113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // ES#sec-evaldeclarationinstantiation 5.a.i.1: 25213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // If varEnvRec.HasLexicalDeclaration(name) is true, throw a SyntaxError 25313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // exception. 25413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // ES#sec-evaldeclarationinstantiation 5.d.ii.2.a.i: 25513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // Throw a SyntaxError exception. 25613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return ThrowRedeclarationError(isolate, name, 25713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch RedeclarationType::kSyntaxError); 258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Object> holder = context->Lookup(name, DONT_FOLLOW_CHAINS, &index, 261f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch &attributes, &init_flag, &mode); 26213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK(!isolate->has_pending_exception()); 263958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 264958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<JSObject> object; 265958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (attributes != ABSENT && holder->IsJSGlobalObject()) { 26713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // ES#sec-evaldeclarationinstantiation 8.a.iv.1.b: 26813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // If fnDefinable is false, throw a TypeError exception. 269f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return DeclareGlobal(isolate, Handle<JSGlobalObject>::cast(holder), name, 270f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch value, NONE, is_var, is_function, 271f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch RedeclarationType::kTypeError); 272958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (context_arg->extension()->IsJSGlobalObject()) { 274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<JSGlobalObject> global( 275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JSGlobalObject::cast(context_arg->extension()), isolate); 276f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return DeclareGlobal(isolate, global, name, value, NONE, is_var, 277f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch is_function, RedeclarationType::kTypeError); 278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (context->IsScriptContext()) { 279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(context->global_object()->IsJSGlobalObject()); 280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<JSGlobalObject> global( 281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JSGlobalObject::cast(context->global_object()), isolate); 282f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return DeclareGlobal(isolate, global, name, value, NONE, is_var, 283f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch is_function, RedeclarationType::kTypeError); 284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 285958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 286958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (attributes != ABSENT) { 28713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK_EQ(NONE, attributes); 288958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 289958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Skip var re-declarations. 290958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (is_var) return isolate->heap()->undefined_value(); 291958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 292958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(is_function); 293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (index != Context::kNotFound) { 294958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(holder.is_identical_to(context)); 29513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch context->set(index, *value); 296958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return isolate->heap()->undefined_value(); 297958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 298958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 299958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier object = Handle<JSObject>::cast(holder); 300958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 301958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (context->has_extension()) { 302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Sloppy varblock contexts might not have an extension object yet, 303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // in which case their extension is a ScopeInfo. 304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (context->extension()->IsScopeInfo()) { 305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(context->IsBlockContext()); 306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch object = isolate->factory()->NewJSObject( 307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isolate->context_extension_function()); 308f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Handle<HeapObject> extension = isolate->factory()->NewContextExtension( 309f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch handle(context->scope_info()), object); 310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch context->set_extension(*extension); 311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch object = handle(context->extension_object(), isolate); 313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 314958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(object->IsJSContextExtensionObject() || object->IsJSGlobalObject()); 315958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 316958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(context->IsFunctionContext()); 317958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier object = 318958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier isolate->factory()->NewJSObject(isolate->context_extension_function()); 319958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier context->set_extension(*object); 320958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 321958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 322958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier RETURN_FAILURE_ON_EXCEPTION(isolate, JSObject::SetOwnPropertyIgnoreAttributes( 32313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch object, name, value, NONE)); 324958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 325958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return isolate->heap()->undefined_value(); 326958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 327958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace 329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 33013e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochRUNTIME_FUNCTION(Runtime_DeclareEvalFunction) { 331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HandleScope scope(isolate); 33213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK_EQ(2, args.length()); 333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CONVERT_ARG_HANDLE_CHECKED(String, name, 0); 33413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch CONVERT_ARG_HANDLE_CHECKED(Object, value, 1); 33513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return DeclareEvalHelper(isolate, name, value); 336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 33813e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochRUNTIME_FUNCTION(Runtime_DeclareEvalVar) { 33913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch HandleScope scope(isolate); 34013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK_EQ(1, args.length()); 34113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch CONVERT_ARG_HANDLE_CHECKED(String, name, 0); 34213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return DeclareEvalHelper(isolate, name, 34313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch isolate->factory()->undefined_value()); 34413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch} 345958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace { 347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Find the arguments of the JavaScript function invocation that called 349109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch// into C++ code. Collect these in a newly allocated array of handles. 350f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochstd::unique_ptr<Handle<Object>[]> GetCallerArguments(Isolate* isolate, 351f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch int* total_argc) { 352014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Find frame containing arguments passed to the caller. 353014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JavaScriptFrameIterator it(isolate); 354014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JavaScriptFrame* frame = it.frame(); 355014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch List<JSFunction*> functions(2); 356014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frame->GetFunctions(&functions); 357014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (functions.length() > 1) { 358014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int inlined_jsframe_index = functions.length() - 1; 359014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch TranslatedState translated_values(frame); 360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch translated_values.Prepare(false, frame->fp()); 361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int argument_count = 0; 363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch TranslatedFrame* translated_frame = 364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch translated_values.GetArgumentsInfoFromJSFrameIndex( 365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inlined_jsframe_index, &argument_count); 366014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch TranslatedFrame::iterator iter = translated_frame->begin(); 367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 368014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Skip the function. 369014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch iter++; 370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Skip the receiver. 372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch iter++; 373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch argument_count--; 374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 375109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch *total_argc = argument_count; 376f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch std::unique_ptr<Handle<Object>[]> param_data( 377014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NewArray<Handle<Object>>(*total_argc)); 378014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool should_deoptimize = false; 379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 0; i < argument_count; i++) { 380014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch should_deoptimize = should_deoptimize || iter->IsMaterializedObject(); 381014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Object> value = iter->GetValue(); 382109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch param_data[i] = value; 383014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch iter++; 384014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 385014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (should_deoptimize) { 387014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch translated_values.StoreMaterializedValuesAndDeopt(); 388014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 389014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return param_data; 391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch it.AdvanceToArgumentsFrame(); 393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frame = it.frame(); 394014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int args_count = frame->ComputeParametersCount(); 395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 396109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch *total_argc = args_count; 397f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch std::unique_ptr<Handle<Object>[]> param_data( 398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NewArray<Handle<Object>>(*total_argc)); 399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 0; i < args_count; i++) { 400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Object> val = Handle<Object>(frame->GetParameter(i), isolate); 401109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch param_data[i] = val; 402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return param_data; 404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochtemplate <typename T> 408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochHandle<JSObject> NewSloppyArguments(Isolate* isolate, Handle<JSFunction> callee, 409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch T parameters, int argument_count) { 410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CHECK(!IsSubclassConstructor(callee->shared()->kind())); 411014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(callee->shared()->has_simple_parameters()); 412958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<JSObject> result = 413958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier isolate->factory()->NewArgumentsObject(callee, argument_count); 414958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 415958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Allocate the elements if needed. 416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int parameter_count = callee->shared()->internal_formal_parameter_count(); 417958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (argument_count > 0) { 418958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (parameter_count > 0) { 419958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int mapped_count = Min(argument_count, parameter_count); 420958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<FixedArray> parameter_map = 421958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier isolate->factory()->NewFixedArray(mapped_count + 2, NOT_TENURED); 422958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier parameter_map->set_map(isolate->heap()->sloppy_arguments_elements_map()); 423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch result->set_map(isolate->native_context()->fast_aliased_arguments_map()); 424958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier result->set_elements(*parameter_map); 425958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 426958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Store the context and the arguments array at the beginning of the 427958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // parameter map. 428958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<Context> context(isolate->context()); 429958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<FixedArray> arguments = 430958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier isolate->factory()->NewFixedArray(argument_count, NOT_TENURED); 431958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier parameter_map->set(0, *context); 432958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier parameter_map->set(1, *arguments); 433958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 434958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Loop over the actual parameters backwards. 435958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int index = argument_count - 1; 436958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier while (index >= mapped_count) { 437958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // These go directly in the arguments array and have no 438958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // corresponding slot in the parameter map. 439014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch arguments->set(index, parameters[index]); 440958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier --index; 441958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 442958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 443958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<ScopeInfo> scope_info(callee->shared()->scope_info()); 444958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier while (index >= 0) { 445958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Detect duplicate names to the right in the parameter list. 446958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<String> name(scope_info->ParameterName(index)); 447958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int context_local_count = scope_info->ContextLocalCount(); 448958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool duplicate = false; 449958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (int j = index + 1; j < parameter_count; ++j) { 450958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (scope_info->ParameterName(j) == *name) { 451958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier duplicate = true; 452958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 453958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 454958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 455958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 456958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (duplicate) { 457958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // This goes directly in the arguments array with a hole in the 458958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // parameter map. 459014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch arguments->set(index, parameters[index]); 460958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier parameter_map->set_the_hole(index + 2); 461958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 462958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // The context index goes in the parameter map with a hole in the 463958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // arguments array. 464958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int context_index = -1; 465958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (int j = 0; j < context_local_count; ++j) { 466958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (scope_info->ContextLocalName(j) == *name) { 467958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier context_index = j; 468958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 469958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 470958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 472958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(context_index >= 0); 473958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier arguments->set_the_hole(index); 474958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier parameter_map->set( 475958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier index + 2, 476958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Smi::FromInt(Context::MIN_CONTEXT_SLOTS + context_index)); 477958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 478958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 479958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier --index; 480958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 481958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 482958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // If there is no aliasing, the arguments object elements are not 483958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // special in any way. 484958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<FixedArray> elements = 485958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier isolate->factory()->NewFixedArray(argument_count, NOT_TENURED); 486958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier result->set_elements(*elements); 487958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (int i = 0; i < argument_count; ++i) { 488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch elements->set(i, parameters[i]); 489958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 490958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 491958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 492958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return result; 493958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 494958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 495958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass HandleArguments BASE_EMBEDDED { 497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public: 498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch explicit HandleArguments(Handle<Object>* array) : array_(array) {} 499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Object* operator[](int index) { return *array_[index]; } 500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private: 502014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Object>* array_; 503014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}; 504014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 505014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass ParameterArguments BASE_EMBEDDED { 507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public: 508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch explicit ParameterArguments(Object** parameters) : parameters_(parameters) {} 509014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Object*& operator[](int index) { return *(parameters_ - index - 1); } 510014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private: 512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Object** parameters_; 513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}; 514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 515014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace 516014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 517014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 518014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochRUNTIME_FUNCTION(Runtime_NewSloppyArguments_Generic) { 519958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HandleScope scope(isolate); 520958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(args.length() == 1); 521958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0); 522014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // This generic runtime function can also be used when the caller has been 523014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // inlined, we use the slow but accurate {GetCallerArguments}. 524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int argument_count = 0; 525f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch std::unique_ptr<Handle<Object>[]> arguments = 526109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch GetCallerArguments(isolate, &argument_count); 527014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HandleArguments argument_getter(arguments.get()); 528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return *NewSloppyArguments(isolate, callee, argument_getter, argument_count); 529014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 530958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 531958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 532109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochRUNTIME_FUNCTION(Runtime_NewStrictArguments) { 533014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HandleScope scope(isolate); 534109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK_EQ(1, args.length()); 535014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0); 536014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // This generic runtime function can also be used when the caller has been 537014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // inlined, we use the slow but accurate {GetCallerArguments}. 538014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int argument_count = 0; 539f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch std::unique_ptr<Handle<Object>[]> arguments = 540109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch GetCallerArguments(isolate, &argument_count); 541109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<JSObject> result = 542109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch isolate->factory()->NewArgumentsObject(callee, argument_count); 543109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (argument_count) { 544109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<FixedArray> array = 545109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch isolate->factory()->NewUninitializedFixedArray(argument_count); 546109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DisallowHeapAllocation no_gc; 547109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch WriteBarrierMode mode = array->GetWriteBarrierMode(no_gc); 548109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch for (int i = 0; i < argument_count; i++) { 549109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch array->set(i, *arguments[i], mode); 550109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 551109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch result->set_elements(*array); 552109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 553109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return *result; 554014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 555014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 557109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochRUNTIME_FUNCTION(Runtime_NewRestParameter) { 558014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HandleScope scope(isolate); 559109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK_EQ(1, args.length()); 560014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0) 561109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch int start_index = callee->shared()->internal_formal_parameter_count(); 562014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // This generic runtime function can also be used when the caller has been 563014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // inlined, we use the slow but accurate {GetCallerArguments}. 564014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int argument_count = 0; 565f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch std::unique_ptr<Handle<Object>[]> arguments = 566109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch GetCallerArguments(isolate, &argument_count); 567109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch int num_elements = std::max(0, argument_count - start_index); 5683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<JSObject> result = 5693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch isolate->factory()->NewJSArray(FAST_ELEMENTS, num_elements, num_elements, 5703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DONT_INITIALIZE_ARRAY_ELEMENTS); 571109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch { 572109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DisallowHeapAllocation no_gc; 573109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch FixedArray* elements = FixedArray::cast(result->elements()); 574f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch WriteBarrierMode mode = elements->GetWriteBarrierMode(no_gc); 575109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch for (int i = 0; i < num_elements; i++) { 576109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch elements->set(i, *arguments[i + start_index], mode); 577109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 578109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 579109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return *result; 580958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 581958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 582958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 583958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierRUNTIME_FUNCTION(Runtime_NewSloppyArguments) { 584958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HandleScope scope(isolate); 585958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(args.length() == 3); 586958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0); 587958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Object** parameters = reinterpret_cast<Object**>(args[1]); 588958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CONVERT_SMI_ARG_CHECKED(argument_count, 2); 589014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ParameterArguments argument_getter(parameters); 590014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return *NewSloppyArguments(isolate, callee, argument_getter, argument_count); 591958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 592958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 593958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 594958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierRUNTIME_FUNCTION(Runtime_NewClosure) { 595958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HandleScope scope(isolate); 596014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(1, args.length()); 597014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CONVERT_ARG_HANDLE_CHECKED(SharedFunctionInfo, shared, 0); 598014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Context> context(isolate->context(), isolate); 599014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return *isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, context, 600014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NOT_TENURED); 601014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 602014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 603958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 604014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochRUNTIME_FUNCTION(Runtime_NewClosure_Tenured) { 605014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HandleScope scope(isolate); 606014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(1, args.length()); 607014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CONVERT_ARG_HANDLE_CHECKED(SharedFunctionInfo, shared, 0); 608014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Context> context(isolate->context(), isolate); 609958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // The caller ensures that we pretenure closures that are assigned 610958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // directly to properties. 611958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return *isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, context, 612014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch TENURED); 613958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 614958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 615958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstatic Object* FindNameClash(Handle<ScopeInfo> scope_info, 616014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<JSGlobalObject> global_object, 617958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<ScriptContextTable> script_context) { 618958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Isolate* isolate = scope_info->GetIsolate(); 619958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (int var = 0; var < scope_info->ContextLocalCount(); var++) { 620958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<String> name(scope_info->ContextLocalName(var)); 621958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier VariableMode mode = scope_info->ContextLocalMode(var); 622958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ScriptContextTable::LookupResult lookup; 623958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (ScriptContextTable::Lookup(script_context, name, &lookup)) { 624958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (IsLexicalVariableMode(mode) || IsLexicalVariableMode(lookup.mode)) { 62513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // ES#sec-globaldeclarationinstantiation 5.b: 62613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // If envRec.HasLexicalDeclaration(name) is true, throw a SyntaxError 62713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // exception. 62813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return ThrowRedeclarationError(isolate, name, 62913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch RedeclarationType::kSyntaxError); 630958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 631958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 632958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 633958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (IsLexicalVariableMode(mode)) { 6343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch LookupIterator it(global_object, name, global_object, 635bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch LookupIterator::OWN_SKIP_INTERCEPTOR); 636958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it); 637014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!maybe.IsJust()) return isolate->heap()->exception(); 638014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if ((maybe.FromJust() & DONT_DELETE) != 0) { 63913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // ES#sec-globaldeclarationinstantiation 5.a: 64013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // If envRec.HasVarDeclaration(name) is true, throw a SyntaxError 64113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // exception. 64213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // ES#sec-globaldeclarationinstantiation 5.d: 64313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // If hasRestrictedGlobal is true, throw a SyntaxError exception. 64413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return ThrowRedeclarationError(isolate, name, 64513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch RedeclarationType::kSyntaxError); 646958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 647958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 648014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JSGlobalObject::InvalidatePropertyCell(global_object, name); 649958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 650958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 651958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return isolate->heap()->undefined_value(); 652958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 653958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 654958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 655958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierRUNTIME_FUNCTION(Runtime_NewScriptContext) { 656958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HandleScope scope(isolate); 657958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(args.length() == 2); 658958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 659958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); 660958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 1); 661014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<JSGlobalObject> global_object(function->context()->global_object()); 662958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<Context> native_context(global_object->native_context()); 663958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<ScriptContextTable> script_context_table( 664958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier native_context->script_context_table()); 665958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 666958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Object* name_clash_result = 667958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier FindNameClash(scope_info, global_object, script_context_table); 668958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (isolate->has_pending_exception()) return name_clash_result; 669958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 670014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Script contexts have a canonical empty function as their closure, not the 671014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // anonymous closure containing the global code. See 672014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // FullCodeGenerator::PushFunctionArgumentForContextAllocation. 673014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<JSFunction> closure( 674014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch function->shared()->IsBuiltin() ? *function : native_context->closure()); 675958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<Context> result = 676014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isolate->factory()->NewScriptContext(closure, scope_info); 677014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 678958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(function->context() == isolate->context()); 679014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(*global_object == result->global_object()); 680958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 681958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<ScriptContextTable> new_script_context_table = 682958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ScriptContextTable::Extend(script_context_table, result); 683958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier native_context->set_script_context_table(*new_script_context_table); 684958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return *result; 685958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 686958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 687958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 688958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierRUNTIME_FUNCTION(Runtime_NewFunctionContext) { 689958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HandleScope scope(isolate); 690958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(args.length() == 1); 691958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 692958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); 693958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 694958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(function->context() == isolate->context()); 695958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int length = function->shared()->scope_info()->ContextLength(); 696958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return *isolate->factory()->NewFunctionContext(length, function); 697958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 698958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 699958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 700958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierRUNTIME_FUNCTION(Runtime_PushWithContext) { 701958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HandleScope scope(isolate); 702f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch DCHECK_EQ(3, args.length()); 703014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CONVERT_ARG_HANDLE_CHECKED(JSReceiver, extension_object, 0); 704f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 1); 705f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 2); 706958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<Context> current(isolate->context()); 707f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Handle<Context> context = isolate->factory()->NewWithContext( 708f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch function, current, scope_info, extension_object); 709958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier isolate->set_context(*context); 710958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return *context; 711958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 712958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 713f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochRUNTIME_FUNCTION(Runtime_PushModuleContext) { 714f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch HandleScope scope(isolate); 715f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch DCHECK_EQ(3, args.length()); 716f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch CONVERT_ARG_HANDLE_CHECKED(Module, module, 0); 717f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 1); 718f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 2); 719f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch DCHECK(function->context() == isolate->context()); 720f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 721f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Handle<Context> context = 722f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch isolate->factory()->NewModuleContext(module, function, scope_info); 723f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch isolate->set_context(*context); 724f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return *context; 725f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 726958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 727958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierRUNTIME_FUNCTION(Runtime_PushCatchContext) { 728958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HandleScope scope(isolate); 729f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch DCHECK_EQ(4, args.length()); 730958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CONVERT_ARG_HANDLE_CHECKED(String, name, 0); 731958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CONVERT_ARG_HANDLE_CHECKED(Object, thrown_object, 1); 732f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 2); 733f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 3); 734958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<Context> current(isolate->context()); 735958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<Context> context = isolate->factory()->NewCatchContext( 736f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch function, current, scope_info, name, thrown_object); 737958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier isolate->set_context(*context); 738958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return *context; 739958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 740958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 741958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 742958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierRUNTIME_FUNCTION(Runtime_PushBlockContext) { 743958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HandleScope scope(isolate); 744014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(2, args.length()); 745958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 0); 746014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 1); 747958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<Context> current(isolate->context()); 748958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<Context> context = 749958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier isolate->factory()->NewBlockContext(function, current, scope_info); 750958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier isolate->set_context(*context); 751958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return *context; 752958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 753958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 754958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 755958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierRUNTIME_FUNCTION(Runtime_DeleteLookupSlot) { 756958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HandleScope scope(isolate); 757109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK_EQ(1, args.length()); 758109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch CONVERT_ARG_HANDLE_CHECKED(String, name, 0); 759958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 760958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int index; 761958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PropertyAttributes attributes; 762f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch InitializationFlag flag; 763f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch VariableMode mode; 764109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<Object> holder = isolate->context()->Lookup( 765f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch name, FOLLOW_CHAINS, &index, &attributes, &flag, &mode); 766958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 767958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // If the slot was not found the result is true. 768958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (holder.is_null()) { 769014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // In case of JSProxy, an exception might have been thrown. 770014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (isolate->has_pending_exception()) return isolate->heap()->exception(); 771958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return isolate->heap()->true_value(); 772958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 773958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 774958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // If the slot was found in a context, it should be DONT_DELETE. 775958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (holder->IsContext()) { 776958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return isolate->heap()->false_value(); 777958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 778958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 779014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // The slot was found in a JSReceiver, either a context extension object, 780958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // the global object, or the subject of a with. Try to delete it 781958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // (respecting DONT_DELETE). 782014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<JSReceiver> object = Handle<JSReceiver>::cast(holder); 783014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Maybe<bool> result = JSReceiver::DeleteProperty(object, name); 784014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MAYBE_RETURN(result, isolate->heap()->exception()); 785014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return isolate->heap()->ToBoolean(result.FromJust()); 786958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 787958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 788958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 789109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochnamespace { 790958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 791109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochMaybeHandle<Object> LoadLookupSlot(Handle<String> name, 792109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Object::ShouldThrow should_throw, 793109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<Object>* receiver_return = nullptr) { 794109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Isolate* const isolate = name->GetIsolate(); 795958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 796958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int index; 797958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PropertyAttributes attributes; 798f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch InitializationFlag flag; 799f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch VariableMode mode; 800109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<Object> holder = isolate->context()->Lookup( 801f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch name, FOLLOW_CHAINS, &index, &attributes, &flag, &mode); 802109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (isolate->has_pending_exception()) return MaybeHandle<Object>(); 803958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 804014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (index != Context::kNotFound) { 805958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(holder->IsContext()); 806958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // If the "property" we were looking for is a local variable, the 807958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // receiver is the global object; see ECMA-262, 3rd., 10.1.6 and 10.2.3. 808958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<Object> receiver = isolate->factory()->undefined_value(); 809109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<Object> value = handle(Context::cast(*holder)->get(index), isolate); 810958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Check for uninitialized bindings. 811f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (flag == kNeedsInitialization && value->IsTheHole(isolate)) { 812f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch THROW_NEW_ERROR(isolate, 813f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch NewReferenceError(MessageTemplate::kNotDefined, name), 814f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Object); 815958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 816f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK(!value->IsTheHole(isolate)); 817f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (receiver_return) *receiver_return = receiver; 818f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return value; 819958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 820958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 821958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Otherwise, if the slot was found the holder is a context extension 822958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // object, subject of a with, or a global object. We read the named 823958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // property from it. 824958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!holder.is_null()) { 825958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // No need to unhole the value here. This is taken care of by the 826958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // GetProperty function. 827958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<Object> value; 828109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch ASSIGN_RETURN_ON_EXCEPTION( 829109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch isolate, value, Object::GetProperty(holder, name), 830109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Object); 831109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (receiver_return) { 832109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch *receiver_return = 833109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch (holder->IsJSGlobalObject() || holder->IsJSContextExtensionObject()) 834109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch ? Handle<Object>::cast(isolate->factory()->undefined_value()) 835109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch : holder; 836109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 837109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return value; 838958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 839958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 840109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (should_throw == Object::THROW_ON_ERROR) { 841958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // The property doesn't exist - throw exception. 842109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch THROW_NEW_ERROR( 843109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch isolate, NewReferenceError(MessageTemplate::kNotDefined, name), Object); 844958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 845109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 846109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // The property doesn't exist - return undefined. 847109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (receiver_return) *receiver_return = isolate->factory()->undefined_value(); 848109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return isolate->factory()->undefined_value(); 849958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 850958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 851109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} // namespace 852958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 853109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 854109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochRUNTIME_FUNCTION(Runtime_LoadLookupSlot) { 855109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch HandleScope scope(isolate); 856109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK_EQ(1, args.length()); 857109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch CONVERT_ARG_HANDLE_CHECKED(String, name, 0); 85813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch RETURN_RESULT_OR_FAILURE(isolate, 85913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch LoadLookupSlot(name, Object::THROW_ON_ERROR)); 860958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 861958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 862958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 863109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochRUNTIME_FUNCTION(Runtime_LoadLookupSlotInsideTypeof) { 864109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch HandleScope scope(isolate); 865109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK_EQ(1, args.length()); 866109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch CONVERT_ARG_HANDLE_CHECKED(String, name, 0); 86713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch RETURN_RESULT_OR_FAILURE(isolate, LoadLookupSlot(name, Object::DONT_THROW)); 868958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 869958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 870958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 871109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochRUNTIME_FUNCTION_RETURN_PAIR(Runtime_LoadLookupSlotForCall) { 872958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier HandleScope scope(isolate); 873109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK_EQ(1, args.length()); 874109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK(args[0]->IsString()); 875109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<String> name = args.at<String>(0); 876109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<Object> value; 877109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<Object> receiver; 878109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch ASSIGN_RETURN_ON_EXCEPTION_VALUE( 879109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch isolate, value, LoadLookupSlot(name, Object::THROW_ON_ERROR, &receiver), 880109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch MakePair(isolate->heap()->exception(), nullptr)); 881109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return MakePair(*value, *receiver); 882109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 8838389745919cae02139ddc085a63c00d024269cf2Ben Murdoch 884109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 885109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochnamespace { 886109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 887109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochMaybeHandle<Object> StoreLookupSlot(Handle<String> name, Handle<Object> value, 888109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch LanguageMode language_mode) { 889109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Isolate* const isolate = name->GetIsolate(); 890109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<Context> context(isolate->context(), isolate); 891958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 892958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int index; 893958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PropertyAttributes attributes; 894f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch InitializationFlag flag; 895f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch VariableMode mode; 896958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<Object> holder = 897f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch context->Lookup(name, FOLLOW_CHAINS, &index, &attributes, &flag, &mode); 898014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (holder.is_null()) { 899014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // In case of JSProxy, an exception might have been thrown. 900109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (isolate->has_pending_exception()) return MaybeHandle<Object>(); 901014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 902958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 903958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // The property was found in a context slot. 904014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (index != Context::kNotFound) { 905f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (flag == kNeedsInitialization && 906c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Handle<Context>::cast(holder)->is_the_hole(isolate, index)) { 907109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch THROW_NEW_ERROR(isolate, 908109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch NewReferenceError(MessageTemplate::kNotDefined, name), 909109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Object); 910014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 911958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if ((attributes & READ_ONLY) == 0) { 912958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<Context>::cast(holder)->set(index, *value); 913014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (is_strict(language_mode)) { 914958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Setting read only property in strict mode. 915109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch THROW_NEW_ERROR(isolate, 916109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch NewTypeError(MessageTemplate::kStrictCannotAssign, name), 917109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Object); 918958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 919109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return value; 920958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 921958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 922958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Slow case: The property is not in a context slot. It is either in a 923958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // context extension object, a property of the subject of a with, or a 924958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // property of the global object. 925958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<JSReceiver> object; 926958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (attributes != ABSENT) { 927958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // The property exists on the holder. 928958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier object = Handle<JSReceiver>::cast(holder); 929014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (is_strict(language_mode)) { 930958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // If absent in strict mode: throw. 931109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch THROW_NEW_ERROR( 932109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch isolate, NewReferenceError(MessageTemplate::kNotDefined, name), Object); 933958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 934958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // If absent in sloppy mode: add the property to the global object. 935958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier object = Handle<JSReceiver>(context->global_object()); 936958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 937958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 938109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch ASSIGN_RETURN_ON_EXCEPTION( 939109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch isolate, value, Object::SetProperty(object, name, value, language_mode), 940109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Object); 941109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return value; 942f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch} 9438389745919cae02139ddc085a63c00d024269cf2Ben Murdoch 944109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} // namespace 945109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 946958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 947109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochRUNTIME_FUNCTION(Runtime_StoreLookupSlot_Sloppy) { 948014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HandleScope scope(isolate); 949109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK_EQ(2, args.length()); 950109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch CONVERT_ARG_HANDLE_CHECKED(String, name, 0); 951109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch CONVERT_ARG_HANDLE_CHECKED(Object, value, 1); 95213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch RETURN_RESULT_OR_FAILURE(isolate, StoreLookupSlot(name, value, SLOPPY)); 953014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 954014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 955014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 956109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochRUNTIME_FUNCTION(Runtime_StoreLookupSlot_Strict) { 957014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch HandleScope scope(isolate); 958109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK_EQ(2, args.length()); 959109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch CONVERT_ARG_HANDLE_CHECKED(String, name, 0); 960109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch CONVERT_ARG_HANDLE_CHECKED(Object, value, 1); 96113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch RETURN_RESULT_OR_FAILURE(isolate, StoreLookupSlot(name, value, STRICT)); 962f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch} 963109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 964014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 965014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 966