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