This CL simplifies var / const by ensuring the behavior is consistent in itself,...
authorverwaest@chromium.org <verwaest@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 14 Jul 2014 14:01:04 +0000 (14:01 +0000)
committerverwaest@chromium.org <verwaest@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 14 Jul 2014 14:01:04 +0000 (14:01 +0000)
Legacy const is changed so that a declaration declares a configurable, but non-writable, slot, and the initializer reconfigures it (when possible) to non-configurable non-writable. This avoids the need for "the hole" as marker value in JSContextExtensionObjects and GlobalObjects. Undefined is used instead.

BUG=
R=rossberg@chromium.org

Review URL: https://codereview.chromium.org/379893002

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@22379 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

17 files changed:
src/arm/full-codegen-arm.cc
src/arm64/full-codegen-arm64.cc
src/full-codegen.h
src/ia32/full-codegen-ia32.cc
src/parser.cc
src/runtime.cc
src/runtime.h
src/x64/full-codegen-x64.cc
test/cctest/test-decls.cc
test/mjsunit/const-eval-init.js
test/mjsunit/const-redecl.js
test/mjsunit/global-const-var-conflicts.js
test/mjsunit/regress/regress-1170.js
test/mjsunit/regress/regress-1213575.js
test/mjsunit/regress/regress-freeze-setter.js [moved from test/mjsunit/regress/regress-global-freeze-const.js with 68% similarity]
test/mozilla/mozilla.status
tools/generate-runtime-tests.py

index bb9fe95..e64b40f 100644 (file)
@@ -855,7 +855,7 @@ void FullCodeGenerator::VisitVariableDeclaration(
         __ mov(r0, Operand(Smi::FromInt(0)));  // Indicates no initial value.
         __ Push(cp, r2, r1, r0);
       }
-      __ CallRuntime(Runtime::kDeclareContextSlot, 4);
+      __ CallRuntime(Runtime::kDeclareLookupSlot, 4);
       break;
     }
   }
@@ -911,7 +911,7 @@ void FullCodeGenerator::VisitFunctionDeclaration(
       __ Push(cp, r2, r1);
       // Push initial value for function declaration.
       VisitForStackValue(declaration->fun());
-      __ CallRuntime(Runtime::kDeclareContextSlot, 4);
+      __ CallRuntime(Runtime::kDeclareLookupSlot, 4);
       break;
     }
   }
@@ -2458,16 +2458,6 @@ void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot(
 }
 
 
-void FullCodeGenerator::EmitCallStoreContextSlot(
-    Handle<String> name, StrictMode strict_mode) {
-  __ push(r0);  // Value.
-  __ mov(r1, Operand(name));
-  __ mov(r0, Operand(Smi::FromInt(strict_mode)));
-  __ Push(cp, r1, r0);  // Context, name, strict mode.
-  __ CallRuntime(Runtime::kStoreContextSlot, 4);
-}
-
-
 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op) {
   if (var->IsUnallocated()) {
     // Global var, const, or let.
@@ -2482,7 +2472,7 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op) {
       __ push(r0);
       __ mov(r0, Operand(var->name()));
       __ Push(cp, r0);  // Context and name.
-      __ CallRuntime(Runtime::kInitializeConstContextSlot, 3);
+      __ CallRuntime(Runtime::kInitializeLegacyConstLookupSlot, 3);
     } else {
       ASSERT(var->IsStackAllocated() || var->IsContextSlot());
       Label skip;
@@ -2496,29 +2486,33 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op) {
 
   } else if (var->mode() == LET && op != Token::INIT_LET) {
     // Non-initializing assignment to let variable needs a write barrier.
-    if (var->IsLookupSlot()) {
-      EmitCallStoreContextSlot(var->name(), strict_mode());
-    } else {
-      ASSERT(var->IsStackAllocated() || var->IsContextSlot());
-      Label assign;
-      MemOperand location = VarOperand(var, r1);
-      __ ldr(r3, location);
-      __ CompareRoot(r3, Heap::kTheHoleValueRootIndex);
-      __ b(ne, &assign);
-      __ mov(r3, Operand(var->name()));
-      __ push(r3);
-      __ CallRuntime(Runtime::kThrowReferenceError, 1);
-      // Perform the assignment.
-      __ bind(&assign);
-      EmitStoreToStackLocalOrContextSlot(var, location);
-    }
+    ASSERT(!var->IsLookupSlot());
+    ASSERT(var->IsStackAllocated() || var->IsContextSlot());
+    Label assign;
+    MemOperand location = VarOperand(var, r1);
+    __ ldr(r3, location);
+    __ CompareRoot(r3, Heap::kTheHoleValueRootIndex);
+    __ b(ne, &assign);
+    __ mov(r3, Operand(var->name()));
+    __ push(r3);
+    __ CallRuntime(Runtime::kThrowReferenceError, 1);
+    // Perform the assignment.
+    __ bind(&assign);
+    EmitStoreToStackLocalOrContextSlot(var, location);
 
   } else if (!var->is_const_mode() || op == Token::INIT_CONST) {
-    // Assignment to var or initializing assignment to let/const
-    // in harmony mode.
     if (var->IsLookupSlot()) {
-      EmitCallStoreContextSlot(var->name(), strict_mode());
+      ASSERT(op == Token::ASSIGN || op == Token::INIT_VAR ||
+             op == Token::ASSIGN_ADD);
+      // Assignment to var.
+      __ push(r0);  // Value.
+      __ mov(r1, Operand(var->name()));
+      __ mov(r0, Operand(Smi::FromInt(strict_mode())));
+      __ Push(cp, r1, r0);  // Context, name, strict mode.
+      __ CallRuntime(Runtime::kStoreLookupSlot, 4);
     } else {
+      // Assignment to var or initializing assignment to let/const in harmony
+      // mode.
       ASSERT((var->IsStackAllocated() || var->IsContextSlot()));
       MemOperand location = VarOperand(var, r1);
       if (generate_debug_code_ && op == Token::INIT_LET) {
index f7103f2..b3539e6 100644 (file)
@@ -859,7 +859,7 @@ void FullCodeGenerator::VisitVariableDeclaration(
         // Pushing 0 (xzr) indicates no initial value.
         __ Push(cp, x2, x1, xzr);
       }
-      __ CallRuntime(Runtime::kDeclareContextSlot, 4);
+      __ CallRuntime(Runtime::kDeclareLookupSlot, 4);
       break;
     }
   }
@@ -915,7 +915,7 @@ void FullCodeGenerator::VisitFunctionDeclaration(
       __ Push(cp, x2, x1);
       // Push initial value for function declaration.
       VisitForStackValue(declaration->fun());
-      __ CallRuntime(Runtime::kDeclareContextSlot, 4);
+      __ CallRuntime(Runtime::kDeclareLookupSlot, 4);
       break;
     }
   }
@@ -2142,19 +2142,6 @@ void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot(
 }
 
 
-void FullCodeGenerator::EmitCallStoreContextSlot(
-    Handle<String> name, StrictMode strict_mode) {
-  __ Mov(x11, Operand(name));
-  __ Mov(x10, Smi::FromInt(strict_mode));
-  // jssp[0]  : mode.
-  // jssp[8]  : name.
-  // jssp[16] : context.
-  // jssp[24] : value.
-  __ Push(x0, cp, x11, x10);
-  __ CallRuntime(Runtime::kStoreContextSlot, 4);
-}
-
-
 void FullCodeGenerator::EmitVariableAssignment(Variable* var,
                                                Token::Value op) {
   ASM_LOCATION("FullCodeGenerator::EmitVariableAssignment");
@@ -2170,7 +2157,7 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var,
     if (var->IsLookupSlot()) {
       __ Mov(x1, Operand(var->name()));
       __ Push(x0, cp, x1);
-      __ CallRuntime(Runtime::kInitializeConstContextSlot, 3);
+      __ CallRuntime(Runtime::kInitializeLegacyConstLookupSlot, 3);
     } else {
       ASSERT(var->IsStackLocal() || var->IsContextSlot());
       Label skip;
@@ -2183,28 +2170,35 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var,
 
   } else if (var->mode() == LET && op != Token::INIT_LET) {
     // Non-initializing assignment to let variable needs a write barrier.
-    if (var->IsLookupSlot()) {
-      EmitCallStoreContextSlot(var->name(), strict_mode());
-    } else {
-      ASSERT(var->IsStackAllocated() || var->IsContextSlot());
-      Label assign;
-      MemOperand location = VarOperand(var, x1);
-      __ Ldr(x10, location);
-      __ JumpIfNotRoot(x10, Heap::kTheHoleValueRootIndex, &assign);
-      __ Mov(x10, Operand(var->name()));
-      __ Push(x10);
-      __ CallRuntime(Runtime::kThrowReferenceError, 1);
-      // Perform the assignment.
-      __ Bind(&assign);
-      EmitStoreToStackLocalOrContextSlot(var, location);
-    }
+    ASSERT(!var->IsLookupSlot());
+    ASSERT(var->IsStackAllocated() || var->IsContextSlot());
+    Label assign;
+    MemOperand location = VarOperand(var, x1);
+    __ Ldr(x10, location);
+    __ JumpIfNotRoot(x10, Heap::kTheHoleValueRootIndex, &assign);
+    __ Mov(x10, Operand(var->name()));
+    __ Push(x10);
+    __ CallRuntime(Runtime::kThrowReferenceError, 1);
+    // Perform the assignment.
+    __ Bind(&assign);
+    EmitStoreToStackLocalOrContextSlot(var, location);
 
   } else if (!var->is_const_mode() || op == Token::INIT_CONST) {
-    // Assignment to var or initializing assignment to let/const
-    // in harmony mode.
     if (var->IsLookupSlot()) {
-      EmitCallStoreContextSlot(var->name(), strict_mode());
+      ASSERT(op == Token::ASSIGN || op == Token::INIT_VAR ||
+             op == Token::ASSIGN_ADD);
+      // Assignment to var.
+      __ Mov(x11, Operand(var->name()));
+      __ Mov(x10, Smi::FromInt(strict_mode()));
+      // jssp[0]  : mode.
+      // jssp[8]  : name.
+      // jssp[16] : context.
+      // jssp[24] : value.
+      __ Push(x0, cp, x11, x10);
+      __ CallRuntime(Runtime::kStoreLookupSlot, 4);
     } else {
+      // Assignment to var or initializing assignment to let/const in harmony
+      // mode.
       ASSERT(var->IsStackAllocated() || var->IsContextSlot());
       MemOperand location = VarOperand(var, x1);
       if (FLAG_debug_code && op == Token::INIT_LET) {
index 555bc60..ab1d47b 100644 (file)
@@ -550,7 +550,6 @@ class FullCodeGenerator: public AstVisitor {
   // Helper functions to EmitVariableAssignment
   void EmitStoreToStackLocalOrContextSlot(Variable* var,
                                           MemOperand location);
-  void EmitCallStoreContextSlot(Handle<String> name, StrictMode strict_mode);
 
   // Complete a named property assignment.  The receiver is expected on top
   // of the stack and the right-hand-side value in the accumulator.
index e3669cf..8ab2d30 100644 (file)
@@ -802,7 +802,7 @@ void FullCodeGenerator::VisitVariableDeclaration(
       } else {
         __ push(Immediate(Smi::FromInt(0)));  // Indicates no initial value.
       }
-      __ CallRuntime(Runtime::kDeclareContextSlot, 4);
+      __ CallRuntime(Runtime::kDeclareLookupSlot, 4);
       break;
     }
   }
@@ -855,7 +855,7 @@ void FullCodeGenerator::VisitFunctionDeclaration(
       __ push(Immediate(variable->name()));
       __ push(Immediate(Smi::FromInt(NONE)));
       VisitForStackValue(declaration->fun());
-      __ CallRuntime(Runtime::kDeclareContextSlot, 4);
+      __ CallRuntime(Runtime::kDeclareLookupSlot, 4);
       break;
     }
   }
@@ -2385,16 +2385,6 @@ void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot(
 }
 
 
-void FullCodeGenerator::EmitCallStoreContextSlot(
-    Handle<String> name, StrictMode strict_mode) {
-  __ push(eax);  // Value.
-  __ push(esi);  // Context.
-  __ push(Immediate(name));
-  __ push(Immediate(Smi::FromInt(strict_mode)));
-  __ CallRuntime(Runtime::kStoreContextSlot, 4);
-}
-
-
 void FullCodeGenerator::EmitVariableAssignment(Variable* var,
                                                Token::Value op) {
   if (var->IsUnallocated()) {
@@ -2410,7 +2400,7 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var,
       __ push(eax);
       __ push(esi);
       __ push(Immediate(var->name()));
-      __ CallRuntime(Runtime::kInitializeConstContextSlot, 3);
+      __ CallRuntime(Runtime::kInitializeLegacyConstLookupSlot, 3);
     } else {
       ASSERT(var->IsStackLocal() || var->IsContextSlot());
       Label skip;
@@ -2424,27 +2414,31 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var,
 
   } else if (var->mode() == LET && op != Token::INIT_LET) {
     // Non-initializing assignment to let variable needs a write barrier.
-    if (var->IsLookupSlot()) {
-      EmitCallStoreContextSlot(var->name(), strict_mode());
-    } else {
-      ASSERT(var->IsStackAllocated() || var->IsContextSlot());
-      Label assign;
-      MemOperand location = VarOperand(var, ecx);
-      __ mov(edx, location);
-      __ cmp(edx, isolate()->factory()->the_hole_value());
-      __ j(not_equal, &assign, Label::kNear);
-      __ push(Immediate(var->name()));
-      __ CallRuntime(Runtime::kThrowReferenceError, 1);
-      __ bind(&assign);
-      EmitStoreToStackLocalOrContextSlot(var, location);
-    }
+    ASSERT(!var->IsLookupSlot());
+    ASSERT(var->IsStackAllocated() || var->IsContextSlot());
+    Label assign;
+    MemOperand location = VarOperand(var, ecx);
+    __ mov(edx, location);
+    __ cmp(edx, isolate()->factory()->the_hole_value());
+    __ j(not_equal, &assign, Label::kNear);
+    __ push(Immediate(var->name()));
+    __ CallRuntime(Runtime::kThrowReferenceError, 1);
+    __ bind(&assign);
+    EmitStoreToStackLocalOrContextSlot(var, location);
 
   } else if (!var->is_const_mode() || op == Token::INIT_CONST) {
-    // Assignment to var or initializing assignment to let/const
-    // in harmony mode.
     if (var->IsLookupSlot()) {
-      EmitCallStoreContextSlot(var->name(), strict_mode());
+      ASSERT(op == Token::ASSIGN || op == Token::INIT_VAR ||
+             op == Token::ASSIGN_ADD);
+      // Assignment to var.
+      __ push(eax);  // Value.
+      __ push(esi);  // Context.
+      __ push(Immediate(var->name()));
+      __ push(Immediate(Smi::FromInt(strict_mode())));
+      __ CallRuntime(Runtime::kStoreLookupSlot, 4);
     } else {
+      // Assignment to var or initializing assignment to let/const in harmony
+      // mode.
       ASSERT(var->IsStackAllocated() || var->IsContextSlot());
       MemOperand location = VarOperand(var, ecx);
       if (generate_debug_code_ && op == Token::INIT_LET) {
index 2098f35..2489b81 100644 (file)
@@ -1704,7 +1704,7 @@ void Parser::Declare(Declaration* declaration, bool resolve, bool* ok) {
   // same variable if it is declared several times. This is not a
   // semantic issue as long as we keep the source order, but it may be
   // a performance issue since it may lead to repeated
-  // RuntimeHidden_DeclareContextSlot calls.
+  // RuntimeHidden_DeclareLookupSlot calls.
   declaration_scope->AddDeclaration(declaration);
 
   if (mode == CONST_LEGACY && declaration_scope->is_global_scope()) {
@@ -1718,7 +1718,7 @@ void Parser::Declare(Declaration* declaration, bool resolve, bool* ok) {
              declaration_scope->strict_mode() == SLOPPY) {
     // For variable declarations in a sloppy eval scope the proxy is bound
     // to a lookup variable to force a dynamic declaration using the
-    // DeclareContextSlot runtime function.
+    // DeclareLookupSlot runtime function.
     Variable::Kind kind = Variable::NORMAL;
     var = new(zone()) Variable(
         declaration_scope, name, mode, true, kind,
@@ -2189,21 +2189,22 @@ Block* Parser::ParseVariableDeclarations(
         if (value != NULL && !inside_with()) {
           arguments->Add(value, zone());
           value = NULL;  // zap the value to avoid the unnecessary assignment
+          // Construct the call to Runtime_InitializeVarGlobal
+          // and add it to the initialization statement block.
+          initialize = factory()->NewCallRuntime(
+              ast_value_factory_->initialize_var_global_string(),
+              Runtime::FunctionForId(Runtime::kInitializeVarGlobal), arguments,
+              pos);
+        } else {
+          initialize = NULL;
         }
-
-        // Construct the call to Runtime_InitializeVarGlobal
-        // and add it to the initialization statement block.
-        // Note that the function does different things depending on
-        // the number of arguments (2 or 3).
-        initialize = factory()->NewCallRuntime(
-            ast_value_factory_->initialize_var_global_string(),
-            Runtime::FunctionForId(Runtime::kInitializeVarGlobal),
-            arguments, pos);
       }
 
-      block->AddStatement(
-          factory()->NewExpressionStatement(initialize, RelocInfo::kNoPosition),
-          zone());
+      if (initialize != NULL) {
+        block->AddStatement(factory()->NewExpressionStatement(
+                                initialize, RelocInfo::kNoPosition),
+                            zone());
+      }
     } else if (needs_init) {
       // Constant initializations always assign to the declared constant which
       // is always at the function scope level. This is only relevant for
index 17358e4..432f20a 100644 (file)
@@ -641,8 +641,8 @@ RUNTIME_FUNCTION(Runtime_CreateGlobalPrivateSymbol) {
     ASSERT(symbol->IsUndefined());
     symbol = isolate->factory()->NewPrivateSymbol();
     Handle<Symbol>::cast(symbol)->set_name(*name);
-    JSObject::SetProperty(Handle<JSObject>::cast(privates),
-                          name, symbol, NONE, STRICT).Assert();
+    JSObject::SetProperty(Handle<JSObject>::cast(privates), name, symbol, NONE,
+                          STRICT).Assert();
   }
   return *symbol;
 }
@@ -2110,6 +2110,50 @@ static Object* ThrowRedeclarationError(Isolate* isolate, Handle<String> name) {
 }
 
 
+// May throw a RedeclarationError.
+static Object* DeclareGlobals(Isolate* isolate, Handle<GlobalObject> global,
+                              Handle<String> name, Handle<Object> value,
+                              PropertyAttributes attr, bool is_var,
+                              bool is_const, bool is_function) {
+  // Do the lookup own properties only, see ES5 erratum.
+  LookupIterator it(global, name, LookupIterator::CHECK_HIDDEN);
+  PropertyAttributes old_attributes = JSReceiver::GetPropertyAttributes(&it);
+
+  if (old_attributes != ABSENT) {
+    // The name was declared before; check for conflicting re-declarations.
+    if (is_const) return ThrowRedeclarationError(isolate, name);
+
+    // Skip var re-declarations.
+    if (is_var) return isolate->heap()->undefined_value();
+
+    ASSERT(is_function);
+    if ((old_attributes & DONT_DELETE) != 0) {
+      // Only allow reconfiguring globals to functions in user code (no
+      // natives, which are marked as read-only).
+      ASSERT((attr & READ_ONLY) == 0);
+
+      // Check whether we can reconfigure the existing property into a
+      // function.
+      PropertyDetails old_details = it.property_details();
+      // TODO(verwaest): CALLBACKS invalidly includes ExecutableAccessInfo,
+      // which are actually data properties, not accessor properties.
+      if (old_details.IsReadOnly() || old_details.IsDontEnum() ||
+          old_details.type() == CALLBACKS) {
+        return ThrowRedeclarationError(isolate, name);
+      }
+      // If the existing property is not configurable, keep its attributes. Do
+      attr = old_attributes;
+    }
+  }
+
+  // Define or redefine own property.
+  RETURN_FAILURE_ON_EXCEPTION(isolate, JSObject::SetOwnPropertyIgnoreAttributes(
+                                           global, name, value, attr));
+
+  return isolate->heap()->undefined_value();
+}
+
+
 RUNTIME_FUNCTION(Runtime_DeclareGlobals) {
   HandleScope scope(isolate);
   ASSERT(args.length() == 3);
@@ -2124,181 +2168,42 @@ RUNTIME_FUNCTION(Runtime_DeclareGlobals) {
   for (int i = 0; i < length; i += 2) {
     HandleScope scope(isolate);
     Handle<String> name(String::cast(pairs->get(i)));
-    Handle<Object> value(pairs->get(i + 1), isolate);
+    Handle<Object> initial_value(pairs->get(i + 1), isolate);
 
     // We have to declare a global const property. To capture we only
     // assign to it when evaluating the assignment for "const x =
     // <expr>" the initial value is the hole.
-    bool is_var = value->IsUndefined();
-    bool is_const = value->IsTheHole();
-    bool is_function = value->IsSharedFunctionInfo();
+    bool is_var = initial_value->IsUndefined();
+    bool is_const = initial_value->IsTheHole();
+    bool is_function = initial_value->IsSharedFunctionInfo();
     ASSERT(is_var + is_const + is_function == 1);
 
-    if (is_var || is_const) {
-      // Lookup the property in the global object, and don't set the
-      // value of the variable if the property is already there.
-      // Do the lookup own properties only, see ES5 erratum.
-      LookupResult lookup(isolate);
-      global->LookupOwn(name, &lookup, true);
-      if (lookup.IsFound()) {
-        // We found an existing property. Unless it was an interceptor
-        // that claims the property is absent, skip this declaration.
-        if (!lookup.IsInterceptor()) continue;
-        if (JSReceiver::GetPropertyAttributes(global, name) != ABSENT) continue;
-        // Fall-through and introduce the absent property by using
-        // SetProperty.
-      }
-    } else if (is_function) {
+    Handle<Object> value;
+    if (is_function) {
       // Copy the function and update its context. Use it as value.
       Handle<SharedFunctionInfo> shared =
-          Handle<SharedFunctionInfo>::cast(value);
+          Handle<SharedFunctionInfo>::cast(initial_value);
       Handle<JSFunction> function =
-          isolate->factory()->NewFunctionFromSharedFunctionInfo(
-              shared, context, TENURED);
+          isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, context,
+                                                                TENURED);
       value = function;
+    } else {
+      value = isolate->factory()->undefined_value();
     }
 
-    LookupResult lookup(isolate);
-    global->LookupOwn(name, &lookup, true);
-
     // Compute the property attributes. According to ECMA-262,
     // the property must be non-configurable except in eval.
-    int attr = NONE;
-    bool is_eval = DeclareGlobalsEvalFlag::decode(flags);
-    if (!is_eval) {
-      attr |= DONT_DELETE;
-    }
     bool is_native = DeclareGlobalsNativeFlag::decode(flags);
-    if (is_const || (is_native && is_function)) {
-      attr |= READ_ONLY;
-    }
-
-    StrictMode strict_mode = DeclareGlobalsStrictMode::decode(flags);
-
-    if (!lookup.IsFound() || is_function) {
-      // If the own property exists, check that we can reconfigure it
-      // as required for function declarations.
-      if (lookup.IsFound() && lookup.IsDontDelete()) {
-        if (lookup.IsReadOnly() || lookup.IsDontEnum() ||
-            lookup.IsPropertyCallbacks()) {
-          return ThrowRedeclarationError(isolate, name);
-        }
-        // If the existing property is not configurable, keep its attributes.
-        attr = lookup.GetAttributes();
-      }
-      // Define or redefine own property.
-      RETURN_FAILURE_ON_EXCEPTION(isolate,
-          JSObject::SetOwnPropertyIgnoreAttributes(
-              global, name, value, static_cast<PropertyAttributes>(attr)));
-    } else {
-      // Do a [[Put]] on the existing (own) property.
-      RETURN_FAILURE_ON_EXCEPTION(
-          isolate,
-          JSObject::SetProperty(
-              global, name, value, static_cast<PropertyAttributes>(attr),
-              strict_mode));
-    }
-  }
-
-  ASSERT(!isolate->has_pending_exception());
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_DeclareContextSlot) {
-  HandleScope scope(isolate);
-  ASSERT(args.length() == 4);
-
-  // Declarations are always made in a function or native context.  In the
-  // case of eval code, the context passed is the context of the caller,
-  // which may be some nested context and not the declaration context.
-  CONVERT_ARG_HANDLE_CHECKED(Context, context_arg, 0);
-  Handle<Context> context(context_arg->declaration_context());
-  CONVERT_ARG_HANDLE_CHECKED(String, name, 1);
-  CONVERT_SMI_ARG_CHECKED(mode_arg, 2);
-  PropertyAttributes mode = static_cast<PropertyAttributes>(mode_arg);
-  RUNTIME_ASSERT(mode == READ_ONLY || mode == NONE);
-  CONVERT_ARG_HANDLE_CHECKED(Object, initial_value, 3);
-
-  int index;
-  PropertyAttributes attributes;
-  ContextLookupFlags flags = DONT_FOLLOW_CHAINS;
-  BindingFlags binding_flags;
-  Handle<Object> holder =
-      context->Lookup(name, flags, &index, &attributes, &binding_flags);
-
-  if (attributes != ABSENT) {
-    // The name was declared before; check for conflicting re-declarations.
-    // Note: this is actually inconsistent with what happens for globals (where
-    // we silently ignore such declarations).
-    if (((attributes & READ_ONLY) != 0) || (mode == READ_ONLY)) {
-      // Functions are not read-only.
-      ASSERT(mode != READ_ONLY || initial_value->IsTheHole());
-      return ThrowRedeclarationError(isolate, name);
-    }
-
-    // Initialize it if necessary.
-    if (*initial_value != NULL) {
-      if (index >= 0) {
-        ASSERT(holder.is_identical_to(context));
-        if (((attributes & READ_ONLY) == 0) ||
-            context->get(index)->IsTheHole()) {
-          context->set(index, *initial_value);
-        }
-      } else {
-        // Slow case: The property is in the context extension object of a
-        // function context or the global object of a native context.
-        Handle<JSObject> object = Handle<JSObject>::cast(holder);
-        RETURN_FAILURE_ON_EXCEPTION(
-            isolate,
-            JSReceiver::SetProperty(object, name, initial_value, mode, SLOPPY));
-      }
-    }
+    bool is_eval = DeclareGlobalsEvalFlag::decode(flags);
+    int attr = NONE;
+    if (is_const) attr |= READ_ONLY;
+    if (is_function && is_native) attr |= READ_ONLY;
+    if (!is_const && !is_eval) attr |= DONT_DELETE;
 
-  } else {
-    // The property is not in the function context. It needs to be
-    // "declared" in the function context's extension context or as a
-    // property of the the global object.
-    Handle<JSObject> object;
-    if (context->has_extension()) {
-      object = Handle<JSObject>(JSObject::cast(context->extension()));
-    } else {
-      // Context extension objects are allocated lazily.
-      ASSERT(context->IsFunctionContext());
-      object = isolate->factory()->NewJSObject(
-          isolate->context_extension_function());
-      context->set_extension(*object);
-    }
-    ASSERT(*object != NULL);
-
-    // Declare the property by setting it to the initial value if provided,
-    // or undefined, and use the correct mode (e.g. READ_ONLY attribute for
-    // constant declarations).
-    ASSERT(!JSReceiver::HasOwnProperty(object, name));
-    Handle<Object> value(isolate->heap()->undefined_value(), isolate);
-    if (*initial_value != NULL) value = initial_value;
-    // Declaring a const context slot is a conflicting declaration if
-    // there is a callback with that name in a prototype. It is
-    // allowed to introduce const variables in
-    // JSContextExtensionObjects. They are treated specially in
-    // SetProperty and no setters are invoked for those since they are
-    // not real JSObjects.
-    if (initial_value->IsTheHole() &&
-        !object->IsJSContextExtensionObject()) {
-      LookupResult lookup(isolate);
-      object->Lookup(name, &lookup);
-      if (lookup.IsPropertyCallbacks()) {
-        return ThrowRedeclarationError(isolate, name);
-      }
-    }
-    if (object->IsJSGlobalObject()) {
-      // Define own property on the global object.
-      RETURN_FAILURE_ON_EXCEPTION(isolate,
-         JSObject::SetOwnPropertyIgnoreAttributes(object, name, value, mode));
-    } else {
-      RETURN_FAILURE_ON_EXCEPTION(isolate,
-         JSReceiver::SetProperty(object, name, value, mode, SLOPPY));
-    }
+    Object* result = DeclareGlobals(isolate, global, name, value,
+                                    static_cast<PropertyAttributes>(attr),
+                                    is_var, is_const, is_function);
+    if (isolate->has_pending_exception()) return result;
   }
 
   return isolate->heap()->undefined_value();
@@ -2313,60 +2218,23 @@ RUNTIME_FUNCTION(Runtime_InitializeVarGlobal) {
 
   // Determine if we need to assign to the variable if it already
   // exists (based on the number of arguments).
-  RUNTIME_ASSERT(args.length() == 2 || args.length() == 3);
-  bool assign = args.length() == 3;
+  RUNTIME_ASSERT(args.length() == 3);
 
   CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
   CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
 
-  // According to ECMA-262, section 12.2, page 62, the property must
-  // not be deletable.
-  PropertyAttributes attributes = DONT_DELETE;
-
-  // Lookup the property as own on the global object. If it isn't
-  // there, there is a property with this name in the prototype chain.
-  // We follow Safari and Firefox behavior and only set the property
-  // if there is an explicit initialization value that we have
-  // to assign to the property.
-  // Note that objects can have hidden prototypes, so we need to traverse
-  // the whole chain of hidden prototypes to do an 'own' lookup.
-  LookupResult lookup(isolate);
-  isolate->context()->global_object()->LookupOwn(name, &lookup, true);
-  if (lookup.IsInterceptor()) {
-    Handle<JSObject> holder(lookup.holder());
-    PropertyAttributes intercepted =
-        JSReceiver::GetPropertyAttributes(holder, name);
-    if (intercepted != ABSENT && (intercepted & READ_ONLY) == 0) {
-      // Found an interceptor that's not read only.
-      if (assign) {
-        CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
-        Handle<Object> result;
-        ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-            isolate, result,
-            JSObject::SetPropertyForResult(
-                holder, &lookup, name, value, attributes, strict_mode));
-        return *result;
-      } else {
-        return isolate->heap()->undefined_value();
-      }
-    }
-  }
-
-  if (assign) {
-    CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
-    Handle<GlobalObject> global(isolate->context()->global_object());
-    Handle<Object> result;
-    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-        isolate, result,
-        JSReceiver::SetProperty(global, name, value, attributes, strict_mode));
-    return *result;
-  }
-  return isolate->heap()->undefined_value();
+  Handle<GlobalObject> global(isolate->context()->global_object());
+  Handle<Object> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, result,
+      JSReceiver::SetProperty(global, name, value, NONE, strict_mode));
+  return *result;
 }
 
 
 RUNTIME_FUNCTION(Runtime_InitializeConstGlobal) {
-  SealHandleScope shs(isolate);
+  HandleScope handle_scope(isolate);
   // All constants are declared with an initial value. The name
   // of the constant is the first argument and the initial value
   // is the second.
@@ -2374,71 +2242,112 @@ RUNTIME_FUNCTION(Runtime_InitializeConstGlobal) {
   CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
   CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
 
-  // Get the current global object from top.
-  GlobalObject* global = isolate->context()->global_object();
+  Handle<GlobalObject> global = isolate->global_object();
 
-  // According to ECMA-262, section 12.2, page 62, the property must
-  // not be deletable. Since it's a const, it must be READ_ONLY too.
-  PropertyAttributes attributes =
-      static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY);
+  // Lookup the property as own on the global object.
+  LookupIterator it(global, name, LookupIterator::CHECK_HIDDEN);
+  PropertyAttributes old_attributes = JSReceiver::GetPropertyAttributes(&it);
 
-  // Lookup the property as own on the global object. If it isn't
-  // there, we add the property and take special precautions to always
-  // add it even in case of callbacks in the prototype chain (this rules
-  // out using SetProperty). We use SetOwnPropertyIgnoreAttributes instead
-  LookupResult lookup(isolate);
-  global->LookupOwn(name, &lookup);
-  if (!lookup.IsFound()) {
-    HandleScope handle_scope(isolate);
-    Handle<GlobalObject> global(isolate->context()->global_object());
-    JSObject::AddProperty(global, name, value, attributes);
-    return *value;
+  PropertyAttributes attr =
+      static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY);
+  // Set the value if the property is either missing, or the property attributes
+  // allow setting the value without invoking an accessor.
+  if (it.IsFound()) {
+    // Ignore if we can't reconfigure the value.
+    if ((old_attributes & DONT_DELETE) != 0) {
+      if ((old_attributes & READ_ONLY) != 0 ||
+          it.property_kind() == LookupIterator::ACCESSOR) {
+        return *value;
+      }
+      attr = static_cast<PropertyAttributes>(old_attributes | READ_ONLY);
+    }
   }
 
-  if (!lookup.IsReadOnly()) {
-    // Restore global object from context (in case of GC) and continue
-    // with setting the value.
-    HandleScope handle_scope(isolate);
-    Handle<GlobalObject> global(isolate->context()->global_object());
+  RETURN_FAILURE_ON_EXCEPTION(isolate, JSObject::SetOwnPropertyIgnoreAttributes(
+                                           global, name, value, attr));
 
-    // BUG 1213575: Handle the case where we have to set a read-only
-    // property through an interceptor and only do it if it's
-    // uninitialized, e.g. the hole. Nirk...
-    // Passing sloppy mode because the property is writable.
-    RETURN_FAILURE_ON_EXCEPTION(
-        isolate,
-        JSReceiver::SetProperty(global, name, value, attributes, SLOPPY));
-    return *value;
+  return *value;
+}
+
+
+RUNTIME_FUNCTION(Runtime_DeclareLookupSlot) {
+  HandleScope scope(isolate);
+  ASSERT(args.length() == 4);
+
+  // Declarations are always made in a function, native, or global context. In
+  // the case of eval code, the context passed is the context of the caller,
+  // which may be some nested context and not the declaration context.
+  CONVERT_ARG_HANDLE_CHECKED(Context, context_arg, 0);
+  Handle<Context> context(context_arg->declaration_context());
+  CONVERT_ARG_HANDLE_CHECKED(String, name, 1);
+  CONVERT_SMI_ARG_CHECKED(attr_arg, 2);
+  PropertyAttributes attr = static_cast<PropertyAttributes>(attr_arg);
+  RUNTIME_ASSERT(attr == READ_ONLY || attr == NONE);
+  CONVERT_ARG_HANDLE_CHECKED(Object, initial_value, 3);
+
+  // TODO(verwaest): Unify the encoding indicating "var" with DeclareGlobals.
+  bool is_var = *initial_value == NULL;
+  bool is_const = initial_value->IsTheHole();
+  bool is_function = initial_value->IsJSFunction();
+  ASSERT(is_var + is_const + is_function == 1);
+
+  int index;
+  PropertyAttributes attributes;
+  ContextLookupFlags flags = DONT_FOLLOW_CHAINS;
+  BindingFlags binding_flags;
+  Handle<Object> holder =
+      context->Lookup(name, flags, &index, &attributes, &binding_flags);
+
+  Handle<JSObject> object;
+  Handle<Object> value =
+      is_function ? initial_value
+                  : Handle<Object>::cast(isolate->factory()->undefined_value());
+
+  // TODO(verwaest): This case should probably not be covered by this function,
+  // but by DeclareGlobals instead.
+  if ((attributes != ABSENT && holder->IsJSGlobalObject()) ||
+      (context_arg->has_extension() &&
+       context_arg->extension()->IsJSGlobalObject())) {
+    return DeclareGlobals(isolate, Handle<JSGlobalObject>::cast(holder), name,
+                          value, attr, is_var, is_const, is_function);
   }
 
-  // Set the value, but only if we're assigning the initial value to a
-  // constant. For now, we determine this by checking if the
-  // current value is the hole.
-  // Strict mode handling not needed (const is disallowed in strict mode).
-  if (lookup.IsField()) {
-    FixedArray* properties = global->properties();
-    int index = lookup.GetFieldIndex().outobject_array_index();
-    if (properties->get(index)->IsTheHole() || !lookup.IsReadOnly()) {
-      properties->set(index, *value);
+  if (attributes != ABSENT) {
+    // The name was declared before; check for conflicting re-declarations.
+    if (is_const || (attributes & READ_ONLY) != 0) {
+      return ThrowRedeclarationError(isolate, name);
     }
-  } else if (lookup.IsNormal()) {
-    if (global->GetNormalizedProperty(&lookup)->IsTheHole() ||
-        !lookup.IsReadOnly()) {
-      HandleScope scope(isolate);
-      JSObject::SetNormalizedProperty(Handle<JSObject>(global), &lookup, value);
+
+    // Skip var re-declarations.
+    if (is_var) return isolate->heap()->undefined_value();
+
+    ASSERT(is_function);
+    if (index >= 0) {
+      ASSERT(holder.is_identical_to(context));
+      context->set(index, *initial_value);
+      return isolate->heap()->undefined_value();
     }
+
+    object = Handle<JSObject>::cast(holder);
+
+  } else if (context->has_extension()) {
+    object = handle(JSObject::cast(context->extension()));
+    ASSERT(object->IsJSContextExtensionObject() || object->IsJSGlobalObject());
   } else {
-    // Ignore re-initialization of constants that have already been
-    // assigned a constant value.
-    ASSERT(lookup.IsReadOnly() && lookup.IsConstant());
+    ASSERT(context->IsFunctionContext());
+    object =
+        isolate->factory()->NewJSObject(isolate->context_extension_function());
+    context->set_extension(*object);
   }
 
-  // Use the set value as the result of the operation.
-  return *value;
+  RETURN_FAILURE_ON_EXCEPTION(isolate, JSObject::SetOwnPropertyIgnoreAttributes(
+                                           object, name, value, attr));
+
+  return isolate->heap()->undefined_value();
 }
 
 
-RUNTIME_FUNCTION(Runtime_InitializeConstContextSlot) {
+RUNTIME_FUNCTION(Runtime_InitializeLegacyConstLookupSlot) {
   HandleScope scope(isolate);
   ASSERT(args.length() == 3);
 
@@ -2451,86 +2360,56 @@ RUNTIME_FUNCTION(Runtime_InitializeConstContextSlot) {
 
   int index;
   PropertyAttributes attributes;
-  ContextLookupFlags flags = FOLLOW_CHAINS;
+  ContextLookupFlags flags = DONT_FOLLOW_CHAINS;
   BindingFlags binding_flags;
   Handle<Object> holder =
       context->Lookup(name, flags, &index, &attributes, &binding_flags);
 
   if (index >= 0) {
     ASSERT(holder->IsContext());
-    // Property was found in a context.  Perform the assignment if we
-    // found some non-constant or an uninitialized constant.
+    // Property was found in a context.  Perform the assignment if the constant
+    // was uninitialized.
     Handle<Context> context = Handle<Context>::cast(holder);
-    if ((attributes & READ_ONLY) == 0 || context->get(index)->IsTheHole()) {
-      context->set(index, *value);
-    }
+    ASSERT((attributes & READ_ONLY) != 0);
+    if (context->get(index)->IsTheHole()) context->set(index, *value);
     return *value;
   }
 
-  // The property could not be found, we introduce it as a property of the
-  // global object.
-  if (attributes == ABSENT) {
-    Handle<JSObject> global = Handle<JSObject>(
-        isolate->context()->global_object());
-    // Strict mode not needed (const disallowed in strict mode).
-    RETURN_FAILURE_ON_EXCEPTION(
-        isolate,
-        JSReceiver::SetProperty(global, name, value, NONE, SLOPPY));
-    return *value;
-  }
+  PropertyAttributes attr =
+      static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY);
 
-  // The property was present in some function's context extension object,
-  // as a property on the subject of a with, or as a property of the global
-  // object.
-  //
-  // In most situations, eval-introduced consts should still be present in
-  // the context extension object.  However, because declaration and
-  // initialization are separate, the property might have been deleted
-  // before we reach the initialization point.
-  //
-  // Example:
-  //
-  //    function f() { eval("delete x; const x;"); }
-  //
-  // In that case, the initialization behaves like a normal assignment.
-  Handle<JSObject> object = Handle<JSObject>::cast(holder);
+  // Strict mode handling not needed (legacy const is disallowed in strict
+  // mode).
 
-  if (*object == context->extension()) {
-    // This is the property that was introduced by the const declaration.
-    // Set it if it hasn't been set before.  NOTE: We cannot use
-    // GetProperty() to get the current value as it 'unholes' the value.
-    LookupResult lookup(isolate);
-    object->LookupOwnRealNamedProperty(name, &lookup);
-    ASSERT(lookup.IsFound());  // the property was declared
-    ASSERT(lookup.IsReadOnly());  // and it was declared as read-only
-
-    if (lookup.IsField()) {
-      FixedArray* properties = object->properties();
-      FieldIndex index = lookup.GetFieldIndex();
-      ASSERT(!index.is_inobject());
-      if (properties->get(index.outobject_array_index())->IsTheHole()) {
-        properties->set(index.outobject_array_index(), *value);
-      }
-    } else if (lookup.IsNormal()) {
-      if (object->GetNormalizedProperty(&lookup)->IsTheHole()) {
-        JSObject::SetNormalizedProperty(object, &lookup, value);
-      }
-    } else {
-      // We should not reach here. Any real, named property should be
-      // either a field or a dictionary slot.
-      UNREACHABLE();
-    }
+  // The declared const was configurable, and may have been deleted in the
+  // meanwhile. If so, re-introduce the variable in the context extension.
+  ASSERT(context_arg->has_extension());
+  if (attributes == ABSENT) {
+    holder = handle(context_arg->extension(), isolate);
   } else {
-    // The property was found on some other object.  Set it if it is not a
-    // read-only property.
-    if ((attributes & READ_ONLY) == 0) {
-      // Strict mode not needed (const disallowed in strict mode).
-      RETURN_FAILURE_ON_EXCEPTION(
-          isolate,
-          JSReceiver::SetProperty(object, name, value, attributes, SLOPPY));
+    // For JSContextExtensionObjects, the initializer can be run multiple times
+    // if in a for loop: for (var i = 0; i < 2; i++) { const x = i; }. Only the
+    // first assignment should go through. For JSGlobalObjects, additionally any
+    // code can run in between that modifies the declared property.
+    ASSERT(holder->IsJSGlobalObject() || holder->IsJSContextExtensionObject());
+
+    LookupIterator it(holder, name, LookupIterator::CHECK_HIDDEN);
+    PropertyAttributes old_attributes = JSReceiver::GetPropertyAttributes(&it);
+
+    // Ignore if we can't reconfigure the value.
+    if ((old_attributes & DONT_DELETE) != 0) {
+      if ((old_attributes & READ_ONLY) != 0 ||
+          it.property_kind() == LookupIterator::ACCESSOR) {
+        return *value;
+      }
+      attr = static_cast<PropertyAttributes>(old_attributes | READ_ONLY);
     }
   }
 
+  RETURN_FAILURE_ON_EXCEPTION(
+      isolate, JSObject::SetOwnPropertyIgnoreAttributes(
+                   Handle<JSObject>::cast(holder), name, value, attr));
+
   return *value;
 }
 
@@ -9333,7 +9212,7 @@ RUNTIME_FUNCTION_RETURN_PAIR(Runtime_LoadContextSlotNoReferenceError) {
 }
 
 
-RUNTIME_FUNCTION(Runtime_StoreContextSlot) {
+RUNTIME_FUNCTION(Runtime_StoreLookupSlot) {
   HandleScope scope(isolate);
   ASSERT(args.length() == 4);
 
@@ -9351,22 +9230,13 @@ RUNTIME_FUNCTION(Runtime_StoreContextSlot) {
                                           &index,
                                           &attributes,
                                           &binding_flags);
+  // In case of JSProxy, an exception might have been thrown.
   if (isolate->has_pending_exception()) return isolate->heap()->exception();
 
+  // The property was found in a context slot.
   if (index >= 0) {
-    // The property was found in a context slot.
-    Handle<Context> context = Handle<Context>::cast(holder);
-    if (binding_flags == MUTABLE_CHECK_INITIALIZED &&
-        context->get(index)->IsTheHole()) {
-      Handle<Object> error =
-          isolate->factory()->NewReferenceError("not_defined",
-                                                HandleVector(&name, 1));
-      return isolate->Throw(*error);
-    }
-    // Ignore if read_only variable.
     if ((attributes & READ_ONLY) == 0) {
-      // Context is a fixed array and set cannot fail.
-      context->set(index, *value);
+      Handle<Context>::cast(holder)->set(index, *value);
     } else if (strict_mode == STRICT) {
       // Setting read only property in strict mode.
       Handle<Object> error =
@@ -9381,39 +9251,22 @@ RUNTIME_FUNCTION(Runtime_StoreContextSlot) {
   // context extension object, a property of the subject of a with, or a
   // property of the global object.
   Handle<JSReceiver> object;
-
-  if (!holder.is_null()) {
+  if (attributes != ABSENT) {
     // The property exists on the holder.
     object = Handle<JSReceiver>::cast(holder);
+  } else if (strict_mode == STRICT) {
+    // If absent in strict mode: throw.
+    Handle<Object> error = isolate->factory()->NewReferenceError(
+        "not_defined", HandleVector(&name, 1));
+    return isolate->Throw(*error);
   } else {
-    // The property was not found.
-    ASSERT(attributes == ABSENT);
-
-    if (strict_mode == STRICT) {
-      // Throw in strict mode (assignment to undefined variable).
-      Handle<Object> error =
-          isolate->factory()->NewReferenceError(
-              "not_defined", HandleVector(&name, 1));
-      return isolate->Throw(*error);
-    }
-    // In sloppy mode, the property is added to the global object.
-    attributes = NONE;
-    object = Handle<JSReceiver>(isolate->context()->global_object());
+    // If absent in sloppy mode: add the property to the global object.
+    object = Handle<JSReceiver>(context->global_object());
   }
 
-  // Set the property if it's not read only or doesn't yet exist.
-  if ((attributes & READ_ONLY) == 0 ||
-      (JSReceiver::GetOwnPropertyAttributes(object, name) == ABSENT)) {
-    RETURN_FAILURE_ON_EXCEPTION(
-        isolate,
-        JSReceiver::SetProperty(object, name, value, NONE, strict_mode));
-  } else if (strict_mode == STRICT && (attributes & READ_ONLY) != 0) {
-    // Setting read only property in strict mode.
-    Handle<Object> error =
-      isolate->factory()->NewTypeError(
-          "strict_cannot_assign", HandleVector(&name, 1));
-    return isolate->Throw(*error);
-  }
+  RETURN_FAILURE_ON_EXCEPTION(
+      isolate, JSReceiver::SetProperty(object, name, value, NONE, strict_mode));
+
   return *value;
 }
 
index 4c68b3b..475721b 100644 (file)
@@ -177,310 +177,310 @@ namespace internal {
   F(IsValidSmi, 1, 1)
 
 
-#define RUNTIME_FUNCTION_LIST_ALWAYS_2(F) \
-  /* Reflection */ \
-  F(FunctionSetInstanceClassName, 2, 1) \
-  F(FunctionSetLength, 2, 1) \
-  F(FunctionSetPrototype, 2, 1) \
-  F(FunctionGetName, 1, 1) \
-  F(FunctionSetName, 2, 1) \
-  F(FunctionNameShouldPrintAsAnonymous, 1, 1) \
-  F(FunctionMarkNameShouldPrintAsAnonymous, 1, 1) \
-  F(FunctionIsGenerator, 1, 1) \
-  F(FunctionBindArguments, 4, 1) \
-  F(BoundFunctionGetBindings, 1, 1) \
-  F(FunctionRemovePrototype, 1, 1) \
-  F(FunctionGetSourceCode, 1, 1) \
-  F(FunctionGetScript, 1, 1) \
-  F(FunctionGetScriptSourcePosition, 1, 1) \
-  F(FunctionGetPositionForOffset, 2, 1) \
-  F(FunctionIsAPIFunction, 1, 1) \
-  F(FunctionIsBuiltin, 1, 1) \
-  F(GetScript, 1, 1) \
-  F(CollectStackTrace, 2, 1) \
-  F(GetV8Version, 0, 1) \
-  \
-  F(SetCode, 2, 1) \
-  \
-  F(CreateApiFunction, 2, 1) \
-  F(IsTemplate, 1, 1) \
-  F(GetTemplateField, 2, 1) \
-  F(DisableAccessChecks, 1, 1) \
-  F(EnableAccessChecks, 1, 1) \
-  \
-  /* Dates */ \
-  F(DateCurrentTime, 0, 1) \
-  F(DateParseString, 2, 1) \
-  F(DateLocalTimezone, 1, 1) \
-  F(DateToUTC, 1, 1) \
-  F(DateMakeDay, 2, 1) \
-  F(DateSetValue, 3, 1) \
-  F(DateCacheVersion, 0, 1) \
-  \
-  /* Globals */ \
-  F(CompileString, 2, 1) \
-  \
-  /* Eval */ \
-  F(GlobalProxy, 1, 1) \
-  F(IsAttachedGlobal, 1, 1) \
-  \
-  F(AddProperty, 4, 1) \
-  F(AddPropertyForTemplate, 4, 1) \
-  F(SetProperty, 4, 1) \
-  F(DefineDataPropertyUnchecked, 4, 1) \
-  F(DefineAccessorPropertyUnchecked, 5, 1) \
-  F(GetDataProperty, 2, 1) \
-  F(SetHiddenProperty, 3, 1) \
-  \
-  /* Arrays */ \
-  F(RemoveArrayHoles, 2, 1) \
-  F(GetArrayKeys, 2, 1) \
-  F(MoveArrayContents, 2, 1) \
-  F(EstimateNumberOfElements, 1, 1) \
-  \
-  /* Getters and Setters */ \
-  F(LookupAccessor, 3, 1) \
-  \
-  /* ES5 */ \
-  F(ObjectFreeze, 1, 1) \
-  \
-  /* Harmony modules */ \
-  F(IsJSModule, 1, 1) \
-  \
-  /* Harmony symbols */ \
-  F(CreateSymbol, 1, 1) \
-  F(CreatePrivateSymbol, 1, 1) \
-  F(CreateGlobalPrivateSymbol, 1, 1) \
-  F(NewSymbolWrapper, 1, 1) \
-  F(SymbolDescription, 1, 1) \
-  F(SymbolRegistry, 0, 1) \
-  F(SymbolIsPrivate, 1, 1) \
-  \
-  /* Harmony proxies */ \
-  F(CreateJSProxy, 2, 1) \
-  F(CreateJSFunctionProxy, 4, 1) \
-  F(IsJSProxy, 1, 1) \
-  F(IsJSFunctionProxy, 1, 1) \
-  F(GetHandler, 1, 1) \
-  F(GetCallTrap, 1, 1) \
-  F(GetConstructTrap, 1, 1) \
-  F(Fix, 1, 1) \
-  \
-  /* Harmony sets */ \
-  F(SetInitialize, 1, 1) \
-  F(SetAdd, 2, 1) \
-  F(SetHas, 2, 1) \
-  F(SetDelete, 2, 1) \
-  F(SetClear, 1, 1) \
-  F(SetGetSize, 1, 1) \
-  \
-  F(SetIteratorInitialize, 3, 1) \
-  F(SetIteratorNext, 2, 1) \
-  \
-  /* Harmony maps */ \
-  F(MapInitialize, 1, 1) \
-  F(MapGet, 2, 1) \
-  F(MapHas, 2, 1) \
-  F(MapDelete, 2, 1) \
-  F(MapClear, 1, 1) \
-  F(MapSet, 3, 1) \
-  F(MapGetSize, 1, 1) \
-  \
-  F(MapIteratorInitialize, 3, 1) \
-  F(MapIteratorNext, 2, 1) \
-  \
-  /* Harmony weak maps and sets */ \
-  F(WeakCollectionInitialize, 1, 1) \
-  F(WeakCollectionGet, 2, 1) \
-  F(WeakCollectionHas, 2, 1) \
-  F(WeakCollectionDelete, 2, 1) \
-  F(WeakCollectionSet, 3, 1) \
-  \
-  /* Harmony events */ \
-  F(EnqueueMicrotask, 1, 1) \
-  F(RunMicrotasks, 0, 1) \
-  \
-  /* Harmony observe */ \
-  F(IsObserved, 1, 1) \
-  F(SetIsObserved, 1, 1) \
-  F(GetObservationState, 0, 1) \
-  F(ObservationWeakMapCreate, 0, 1) \
-  F(ObserverObjectAndRecordHaveSameOrigin, 3, 1) \
-  F(ObjectWasCreatedInCurrentOrigin, 1, 1) \
-  F(GetObjectContextObjectObserve, 1, 1) \
-  F(GetObjectContextObjectGetNotifier, 1, 1) \
-  F(GetObjectContextNotifierPerformChange, 1, 1) \
-  \
-  /* Harmony typed arrays */ \
-  F(ArrayBufferInitialize, 2, 1)\
-  F(ArrayBufferSliceImpl, 3, 1) \
-  F(ArrayBufferIsView, 1, 1) \
-  F(ArrayBufferNeuter, 1, 1) \
-  \
-  F(TypedArrayInitializeFromArrayLike, 4, 1) \
-  F(TypedArrayGetBuffer, 1, 1) \
-  F(TypedArraySetFastCases, 3, 1) \
-  \
-  F(DataViewGetBuffer, 1, 1) \
-  F(DataViewGetInt8, 3, 1) \
-  F(DataViewGetUint8, 3, 1) \
-  F(DataViewGetInt16, 3, 1) \
-  F(DataViewGetUint16, 3, 1) \
-  F(DataViewGetInt32, 3, 1) \
-  F(DataViewGetUint32, 3, 1) \
-  F(DataViewGetFloat32, 3, 1) \
-  F(DataViewGetFloat64, 3, 1) \
-  \
-  F(DataViewSetInt8, 4, 1) \
-  F(DataViewSetUint8, 4, 1) \
-  F(DataViewSetInt16, 4, 1) \
-  F(DataViewSetUint16, 4, 1) \
-  F(DataViewSetInt32, 4, 1) \
-  F(DataViewSetUint32, 4, 1) \
-  F(DataViewSetFloat32, 4, 1) \
-  F(DataViewSetFloat64, 4, 1) \
-  \
-  /* Statements */ \
-  F(NewObjectFromBound, 1, 1) \
-  \
-  /* Declarations and initialization */ \
-  F(InitializeVarGlobal, -1 /* 2 or 3 */, 1) \
-  F(OptimizeObjectForAddingMultipleProperties, 2, 1) \
-  \
-  /* Debugging */ \
-  F(DebugPrint, 1, 1) \
-  F(GlobalPrint, 1, 1) \
-  F(DebugTrace, 0, 1) \
-  F(TraceEnter, 0, 1) \
-  F(TraceExit, 1, 1) \
-  F(Abort, 1, 1) \
-  F(AbortJS, 1, 1) \
-  /* ES5 */ \
-  F(OwnKeys, 1, 1) \
-  \
-  /* Message objects */ \
-  F(MessageGetStartPosition, 1, 1) \
-  F(MessageGetScript, 1, 1) \
-  \
+#define RUNTIME_FUNCTION_LIST_ALWAYS_2(F)              \
+  /* Reflection */                                     \
+  F(FunctionSetInstanceClassName, 2, 1)                \
+  F(FunctionSetLength, 2, 1)                           \
+  F(FunctionSetPrototype, 2, 1)                        \
+  F(FunctionGetName, 1, 1)                             \
+  F(FunctionSetName, 2, 1)                             \
+  F(FunctionNameShouldPrintAsAnonymous, 1, 1)          \
+  F(FunctionMarkNameShouldPrintAsAnonymous, 1, 1)      \
+  F(FunctionIsGenerator, 1, 1)                         \
+  F(FunctionBindArguments, 4, 1)                       \
+  F(BoundFunctionGetBindings, 1, 1)                    \
+  F(FunctionRemovePrototype, 1, 1)                     \
+  F(FunctionGetSourceCode, 1, 1)                       \
+  F(FunctionGetScript, 1, 1)                           \
+  F(FunctionGetScriptSourcePosition, 1, 1)             \
+  F(FunctionGetPositionForOffset, 2, 1)                \
+  F(FunctionIsAPIFunction, 1, 1)                       \
+  F(FunctionIsBuiltin, 1, 1)                           \
+  F(GetScript, 1, 1)                                   \
+  F(CollectStackTrace, 2, 1)                           \
+  F(GetV8Version, 0, 1)                                \
+                                                       \
+  F(SetCode, 2, 1)                                     \
+                                                       \
+  F(CreateApiFunction, 2, 1)                           \
+  F(IsTemplate, 1, 1)                                  \
+  F(GetTemplateField, 2, 1)                            \
+  F(DisableAccessChecks, 1, 1)                         \
+  F(EnableAccessChecks, 1, 1)                          \
+                                                       \
+  /* Dates */                                          \
+  F(DateCurrentTime, 0, 1)                             \
+  F(DateParseString, 2, 1)                             \
+  F(DateLocalTimezone, 1, 1)                           \
+  F(DateToUTC, 1, 1)                                   \
+  F(DateMakeDay, 2, 1)                                 \
+  F(DateSetValue, 3, 1)                                \
+  F(DateCacheVersion, 0, 1)                            \
+                                                       \
+  /* Globals */                                        \
+  F(CompileString, 2, 1)                               \
+                                                       \
+  /* Eval */                                           \
+  F(GlobalProxy, 1, 1)                                 \
+  F(IsAttachedGlobal, 1, 1)                            \
+                                                       \
+  F(AddProperty, 4, 1)                                 \
+  F(AddPropertyForTemplate, 4, 1)                      \
+  F(SetProperty, 4, 1)                                 \
+  F(DefineDataPropertyUnchecked, 4, 1)                 \
+  F(DefineAccessorPropertyUnchecked, 5, 1)             \
+  F(GetDataProperty, 2, 1)                             \
+  F(SetHiddenProperty, 3, 1)                           \
+                                                       \
+  /* Arrays */                                         \
+  F(RemoveArrayHoles, 2, 1)                            \
+  F(GetArrayKeys, 2, 1)                                \
+  F(MoveArrayContents, 2, 1)                           \
+  F(EstimateNumberOfElements, 1, 1)                    \
+                                                       \
+  /* Getters and Setters */                            \
+  F(LookupAccessor, 3, 1)                              \
+                                                       \
+  /* ES5 */                                            \
+  F(ObjectFreeze, 1, 1)                                \
+                                                       \
+  /* Harmony modules */                                \
+  F(IsJSModule, 1, 1)                                  \
+                                                       \
+  /* Harmony symbols */                                \
+  F(CreateSymbol, 1, 1)                                \
+  F(CreatePrivateSymbol, 1, 1)                         \
+  F(CreateGlobalPrivateSymbol, 1, 1)                   \
+  F(NewSymbolWrapper, 1, 1)                            \
+  F(SymbolDescription, 1, 1)                           \
+  F(SymbolRegistry, 0, 1)                              \
+  F(SymbolIsPrivate, 1, 1)                             \
+                                                       \
+  /* Harmony proxies */                                \
+  F(CreateJSProxy, 2, 1)                               \
+  F(CreateJSFunctionProxy, 4, 1)                       \
+  F(IsJSProxy, 1, 1)                                   \
+  F(IsJSFunctionProxy, 1, 1)                           \
+  F(GetHandler, 1, 1)                                  \
+  F(GetCallTrap, 1, 1)                                 \
+  F(GetConstructTrap, 1, 1)                            \
+  F(Fix, 1, 1)                                         \
+                                                       \
+  /* Harmony sets */                                   \
+  F(SetInitialize, 1, 1)                               \
+  F(SetAdd, 2, 1)                                      \
+  F(SetHas, 2, 1)                                      \
+  F(SetDelete, 2, 1)                                   \
+  F(SetClear, 1, 1)                                    \
+  F(SetGetSize, 1, 1)                                  \
+                                                       \
+  F(SetIteratorInitialize, 3, 1)                       \
+  F(SetIteratorNext, 2, 1)                             \
+                                                       \
+  /* Harmony maps */                                   \
+  F(MapInitialize, 1, 1)                               \
+  F(MapGet, 2, 1)                                      \
+  F(MapHas, 2, 1)                                      \
+  F(MapDelete, 2, 1)                                   \
+  F(MapClear, 1, 1)                                    \
+  F(MapSet, 3, 1)                                      \
+  F(MapGetSize, 1, 1)                                  \
+                                                       \
+  F(MapIteratorInitialize, 3, 1)                       \
+  F(MapIteratorNext, 2, 1)                             \
+                                                       \
+  /* Harmony weak maps and sets */                     \
+  F(WeakCollectionInitialize, 1, 1)                    \
+  F(WeakCollectionGet, 2, 1)                           \
+  F(WeakCollectionHas, 2, 1)                           \
+  F(WeakCollectionDelete, 2, 1)                        \
+  F(WeakCollectionSet, 3, 1)                           \
+                                                       \
+  /* Harmony events */                                 \
+  F(EnqueueMicrotask, 1, 1)                            \
+  F(RunMicrotasks, 0, 1)                               \
+                                                       \
+  /* Harmony observe */                                \
+  F(IsObserved, 1, 1)                                  \
+  F(SetIsObserved, 1, 1)                               \
+  F(GetObservationState, 0, 1)                         \
+  F(ObservationWeakMapCreate, 0, 1)                    \
+  F(ObserverObjectAndRecordHaveSameOrigin, 3, 1)       \
+  F(ObjectWasCreatedInCurrentOrigin, 1, 1)             \
+  F(GetObjectContextObjectObserve, 1, 1)               \
+  F(GetObjectContextObjectGetNotifier, 1, 1)           \
+  F(GetObjectContextNotifierPerformChange, 1, 1)       \
+                                                       \
+  /* Harmony typed arrays */                           \
+  F(ArrayBufferInitialize, 2, 1)                       \
+  F(ArrayBufferSliceImpl, 3, 1)                        \
+  F(ArrayBufferIsView, 1, 1)                           \
+  F(ArrayBufferNeuter, 1, 1)                           \
+                                                       \
+  F(TypedArrayInitializeFromArrayLike, 4, 1)           \
+  F(TypedArrayGetBuffer, 1, 1)                         \
+  F(TypedArraySetFastCases, 3, 1)                      \
+                                                       \
+  F(DataViewGetBuffer, 1, 1)                           \
+  F(DataViewGetInt8, 3, 1)                             \
+  F(DataViewGetUint8, 3, 1)                            \
+  F(DataViewGetInt16, 3, 1)                            \
+  F(DataViewGetUint16, 3, 1)                           \
+  F(DataViewGetInt32, 3, 1)                            \
+  F(DataViewGetUint32, 3, 1)                           \
+  F(DataViewGetFloat32, 3, 1)                          \
+  F(DataViewGetFloat64, 3, 1)                          \
+                                                       \
+  F(DataViewSetInt8, 4, 1)                             \
+  F(DataViewSetUint8, 4, 1)                            \
+  F(DataViewSetInt16, 4, 1)                            \
+  F(DataViewSetUint16, 4, 1)                           \
+  F(DataViewSetInt32, 4, 1)                            \
+  F(DataViewSetUint32, 4, 1)                           \
+  F(DataViewSetFloat32, 4, 1)                          \
+  F(DataViewSetFloat64, 4, 1)                          \
+                                                       \
+  /* Statements */                                     \
+  F(NewObjectFromBound, 1, 1)                          \
+                                                       \
+  /* Declarations and initialization */                \
+  F(InitializeVarGlobal, 3, 1)                         \
+  F(OptimizeObjectForAddingMultipleProperties, 2, 1)   \
+                                                       \
+  /* Debugging */                                      \
+  F(DebugPrint, 1, 1)                                  \
+  F(GlobalPrint, 1, 1)                                 \
+  F(DebugTrace, 0, 1)                                  \
+  F(TraceEnter, 0, 1)                                  \
+  F(TraceExit, 1, 1)                                   \
+  F(Abort, 1, 1)                                       \
+  F(AbortJS, 1, 1)                                     \
+  /* ES5 */                                            \
+  F(OwnKeys, 1, 1)                                     \
+                                                       \
+  /* Message objects */                                \
+  F(MessageGetStartPosition, 1, 1)                     \
+  F(MessageGetScript, 1, 1)                            \
+                                                       \
   /* Pseudo functions - handled as macros by parser */ \
-  F(IS_VAR, 1, 1) \
-  \
-  /* expose boolean functions from objects-inl.h */ \
-  F(HasFastSmiElements, 1, 1) \
-  F(HasFastSmiOrObjectElements, 1, 1) \
-  F(HasFastObjectElements, 1, 1) \
-  F(HasFastDoubleElements, 1, 1) \
-  F(HasFastHoleyElements, 1, 1) \
-  F(HasDictionaryElements, 1, 1) \
-  F(HasSloppyArgumentsElements, 1, 1) \
-  F(HasExternalUint8ClampedElements, 1, 1) \
-  F(HasExternalArrayElements, 1, 1) \
-  F(HasExternalInt8Elements, 1, 1) \
-  F(HasExternalUint8Elements, 1, 1) \
-  F(HasExternalInt16Elements, 1, 1) \
-  F(HasExternalUint16Elements, 1, 1) \
-  F(HasExternalInt32Elements, 1, 1) \
-  F(HasExternalUint32Elements, 1, 1) \
-  F(HasExternalFloat32Elements, 1, 1) \
-  F(HasExternalFloat64Elements, 1, 1) \
-  F(HasFixedUint8ClampedElements, 1, 1) \
-  F(HasFixedInt8Elements, 1, 1) \
-  F(HasFixedUint8Elements, 1, 1) \
-  F(HasFixedInt16Elements, 1, 1) \
-  F(HasFixedUint16Elements, 1, 1) \
-  F(HasFixedInt32Elements, 1, 1) \
-  F(HasFixedUint32Elements, 1, 1) \
-  F(HasFixedFloat32Elements, 1, 1) \
-  F(HasFixedFloat64Elements, 1, 1) \
-  F(HasFastProperties, 1, 1) \
-  F(TransitionElementsKind, 2, 1) \
-  F(HaveSameMap, 2, 1) \
+  F(IS_VAR, 1, 1)                                      \
+                                                       \
+  /* expose boolean functions from objects-inl.h */    \
+  F(HasFastSmiElements, 1, 1)                          \
+  F(HasFastSmiOrObjectElements, 1, 1)                  \
+  F(HasFastObjectElements, 1, 1)                       \
+  F(HasFastDoubleElements, 1, 1)                       \
+  F(HasFastHoleyElements, 1, 1)                        \
+  F(HasDictionaryElements, 1, 1)                       \
+  F(HasSloppyArgumentsElements, 1, 1)                  \
+  F(HasExternalUint8ClampedElements, 1, 1)             \
+  F(HasExternalArrayElements, 1, 1)                    \
+  F(HasExternalInt8Elements, 1, 1)                     \
+  F(HasExternalUint8Elements, 1, 1)                    \
+  F(HasExternalInt16Elements, 1, 1)                    \
+  F(HasExternalUint16Elements, 1, 1)                   \
+  F(HasExternalInt32Elements, 1, 1)                    \
+  F(HasExternalUint32Elements, 1, 1)                   \
+  F(HasExternalFloat32Elements, 1, 1)                  \
+  F(HasExternalFloat64Elements, 1, 1)                  \
+  F(HasFixedUint8ClampedElements, 1, 1)                \
+  F(HasFixedInt8Elements, 1, 1)                        \
+  F(HasFixedUint8Elements, 1, 1)                       \
+  F(HasFixedInt16Elements, 1, 1)                       \
+  F(HasFixedUint16Elements, 1, 1)                      \
+  F(HasFixedInt32Elements, 1, 1)                       \
+  F(HasFixedUint32Elements, 1, 1)                      \
+  F(HasFixedFloat32Elements, 1, 1)                     \
+  F(HasFixedFloat64Elements, 1, 1)                     \
+  F(HasFastProperties, 1, 1)                           \
+  F(TransitionElementsKind, 2, 1)                      \
+  F(HaveSameMap, 2, 1)                                 \
   F(IsJSGlobalProxy, 1, 1)
 
 
-#define RUNTIME_FUNCTION_LIST_ALWAYS_3(F) \
-  /* String and Regexp */ \
-  F(NumberToStringRT, 1, 1) \
-  F(RegExpConstructResult, 3, 1) \
-  F(RegExpExecRT, 4, 1) \
-  F(StringAdd, 2, 1)  \
-  F(SubString, 3, 1) \
-  F(InternalizeString, 1, 1) \
-  F(StringCompare, 2, 1) \
-  F(StringCharCodeAtRT, 2, 1) \
-  F(GetFromCache, 2, 1) \
-  \
-  /* Compilation */ \
-  F(CompileUnoptimized, 1, 1) \
-  F(CompileOptimized, 2, 1) \
-  F(TryInstallOptimizedCode, 1, 1) \
-  F(NotifyDeoptimized, 1, 1) \
-  F(NotifyStubFailure, 0, 1) \
-  \
-  /* Utilities */ \
-  F(AllocateInNewSpace, 1, 1) \
-  F(AllocateInTargetSpace, 2, 1) \
-  F(AllocateHeapNumber, 0, 1) \
-  F(NumberToSmi, 1, 1) \
-  F(NumberToStringSkipCache, 1, 1) \
-  \
-  F(NewSloppyArguments, 3, 1) \
-  F(NewStrictArguments, 3, 1) \
-  \
-  /* Harmony generators */ \
-  F(CreateJSGeneratorObject, 0, 1) \
-  F(SuspendJSGeneratorObject, 1, 1) \
-  F(ResumeJSGeneratorObject, 3, 1) \
-  F(ThrowGeneratorStateError, 1, 1) \
-  \
-  /* Arrays */ \
-  F(ArrayConstructor, -1, 1) \
-  F(InternalArrayConstructor, -1, 1) \
-  \
-  /* Literals */ \
-  F(MaterializeRegExpLiteral, 4, 1)\
-  F(CreateObjectLiteral, 4, 1) \
-  F(CreateArrayLiteral, 4, 1) \
-  F(CreateArrayLiteralStubBailout, 3, 1) \
-  \
-  /* Statements */ \
-  F(NewClosure, 3, 1) \
-  F(NewClosureFromStubFailure, 1, 1) \
-  F(NewObject, 1, 1) \
-  F(NewObjectWithAllocationSite, 2, 1) \
-  F(FinalizeInstanceSize, 1, 1) \
-  F(Throw, 1, 1) \
-  F(ReThrow, 1, 1) \
-  F(ThrowReferenceError, 1, 1) \
-  F(ThrowNotDateError, 0, 1) \
-  F(StackGuard, 0, 1) \
-  F(Interrupt, 0, 1) \
-  F(PromoteScheduledException, 0, 1) \
-  \
-  /* Contexts */ \
-  F(NewGlobalContext, 2, 1) \
-  F(NewFunctionContext, 1, 1) \
-  F(PushWithContext, 2, 1) \
-  F(PushCatchContext, 3, 1) \
-  F(PushBlockContext, 2, 1) \
-  F(PushModuleContext, 2, 1) \
-  F(DeleteContextSlot, 2, 1) \
-  F(LoadContextSlot, 2, 2) \
+#define RUNTIME_FUNCTION_LIST_ALWAYS_3(F)  \
+  /* String and Regexp */                  \
+  F(NumberToStringRT, 1, 1)                \
+  F(RegExpConstructResult, 3, 1)           \
+  F(RegExpExecRT, 4, 1)                    \
+  F(StringAdd, 2, 1)                       \
+  F(SubString, 3, 1)                       \
+  F(InternalizeString, 1, 1)               \
+  F(StringCompare, 2, 1)                   \
+  F(StringCharCodeAtRT, 2, 1)              \
+  F(GetFromCache, 2, 1)                    \
+                                           \
+  /* Compilation */                        \
+  F(CompileUnoptimized, 1, 1)              \
+  F(CompileOptimized, 2, 1)                \
+  F(TryInstallOptimizedCode, 1, 1)         \
+  F(NotifyDeoptimized, 1, 1)               \
+  F(NotifyStubFailure, 0, 1)               \
+                                           \
+  /* Utilities */                          \
+  F(AllocateInNewSpace, 1, 1)              \
+  F(AllocateInTargetSpace, 2, 1)           \
+  F(AllocateHeapNumber, 0, 1)              \
+  F(NumberToSmi, 1, 1)                     \
+  F(NumberToStringSkipCache, 1, 1)         \
+                                           \
+  F(NewSloppyArguments, 3, 1)              \
+  F(NewStrictArguments, 3, 1)              \
+                                           \
+  /* Harmony generators */                 \
+  F(CreateJSGeneratorObject, 0, 1)         \
+  F(SuspendJSGeneratorObject, 1, 1)        \
+  F(ResumeJSGeneratorObject, 3, 1)         \
+  F(ThrowGeneratorStateError, 1, 1)        \
+                                           \
+  /* Arrays */                             \
+  F(ArrayConstructor, -1, 1)               \
+  F(InternalArrayConstructor, -1, 1)       \
+                                           \
+  /* Literals */                           \
+  F(MaterializeRegExpLiteral, 4, 1)        \
+  F(CreateObjectLiteral, 4, 1)             \
+  F(CreateArrayLiteral, 4, 1)              \
+  F(CreateArrayLiteralStubBailout, 3, 1)   \
+                                           \
+  /* Statements */                         \
+  F(NewClosure, 3, 1)                      \
+  F(NewClosureFromStubFailure, 1, 1)       \
+  F(NewObject, 1, 1)                       \
+  F(NewObjectWithAllocationSite, 2, 1)     \
+  F(FinalizeInstanceSize, 1, 1)            \
+  F(Throw, 1, 1)                           \
+  F(ReThrow, 1, 1)                         \
+  F(ThrowReferenceError, 1, 1)             \
+  F(ThrowNotDateError, 0, 1)               \
+  F(StackGuard, 0, 1)                      \
+  F(Interrupt, 0, 1)                       \
+  F(PromoteScheduledException, 0, 1)       \
+                                           \
+  /* Contexts */                           \
+  F(NewGlobalContext, 2, 1)                \
+  F(NewFunctionContext, 1, 1)              \
+  F(PushWithContext, 2, 1)                 \
+  F(PushCatchContext, 3, 1)                \
+  F(PushBlockContext, 2, 1)                \
+  F(PushModuleContext, 2, 1)               \
+  F(DeleteContextSlot, 2, 1)               \
+  F(LoadContextSlot, 2, 2)                 \
   F(LoadContextSlotNoReferenceError, 2, 2) \
-  F(StoreContextSlot, 4, 1) \
-  \
-  /* Declarations and initialization */ \
-  F(DeclareGlobals, 3, 1) \
-  F(DeclareModules, 1, 1) \
-  F(DeclareContextSlot, 4, 1) \
-  F(InitializeConstGlobal, 2, 1) \
-  F(InitializeConstContextSlot, 3, 1) \
-  \
-  /* Eval */ \
-  F(ResolvePossiblyDirectEval, 5, 2) \
-  \
-  /* Maths */ \
-  F(MathPowSlow, 2, 1) \
+  F(StoreLookupSlot, 4, 1)                 \
+                                           \
+  /* Declarations and initialization */    \
+  F(DeclareGlobals, 3, 1)                  \
+  F(DeclareModules, 1, 1)                  \
+  F(DeclareLookupSlot, 4, 1)               \
+  F(InitializeConstGlobal, 2, 1)           \
+  F(InitializeLegacyConstLookupSlot, 3, 1) \
+                                           \
+  /* Eval */                               \
+  F(ResolvePossiblyDirectEval, 5, 2)       \
+                                           \
+  /* Maths */                              \
+  F(MathPowSlow, 2, 1)                     \
   F(MathPowRT, 2, 1)
 
 
index 7fc7c76..625ce1a 100644 (file)
@@ -824,7 +824,7 @@ void FullCodeGenerator::VisitVariableDeclaration(
       } else {
         __ Push(Smi::FromInt(0));  // Indicates no initial value.
       }
-      __ CallRuntime(Runtime::kDeclareContextSlot, 4);
+      __ CallRuntime(Runtime::kDeclareLookupSlot, 4);
       break;
     }
   }
@@ -878,7 +878,7 @@ void FullCodeGenerator::VisitFunctionDeclaration(
       __ Push(variable->name());
       __ Push(Smi::FromInt(NONE));
       VisitForStackValue(declaration->fun());
-      __ CallRuntime(Runtime::kDeclareContextSlot, 4);
+      __ CallRuntime(Runtime::kDeclareLookupSlot, 4);
       break;
     }
   }
@@ -2383,16 +2383,6 @@ void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot(
 }
 
 
-void FullCodeGenerator::EmitCallStoreContextSlot(
-    Handle<String> name, StrictMode strict_mode) {
-  __ Push(rax);  // Value.
-  __ Push(rsi);  // Context.
-  __ Push(name);
-  __ Push(Smi::FromInt(strict_mode));
-  __ CallRuntime(Runtime::kStoreContextSlot, 4);
-}
-
-
 void FullCodeGenerator::EmitVariableAssignment(Variable* var,
                                                Token::Value op) {
   if (var->IsUnallocated()) {
@@ -2408,7 +2398,7 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var,
       __ Push(rax);
       __ Push(rsi);
       __ Push(var->name());
-      __ CallRuntime(Runtime::kInitializeConstContextSlot, 3);
+      __ CallRuntime(Runtime::kInitializeLegacyConstLookupSlot, 3);
     } else {
       ASSERT(var->IsStackLocal() || var->IsContextSlot());
       Label skip;
@@ -2422,27 +2412,31 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var,
 
   } else if (var->mode() == LET && op != Token::INIT_LET) {
     // Non-initializing assignment to let variable needs a write barrier.
-    if (var->IsLookupSlot()) {
-      EmitCallStoreContextSlot(var->name(), strict_mode());
-    } else {
-      ASSERT(var->IsStackAllocated() || var->IsContextSlot());
-      Label assign;
-      MemOperand location = VarOperand(var, rcx);
-      __ movp(rdx, location);
-      __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex);
-      __ j(not_equal, &assign, Label::kNear);
-      __ Push(var->name());
-      __ CallRuntime(Runtime::kThrowReferenceError, 1);
-      __ bind(&assign);
-      EmitStoreToStackLocalOrContextSlot(var, location);
-    }
+    ASSERT(!var->IsLookupSlot());
+    ASSERT(var->IsStackAllocated() || var->IsContextSlot());
+    Label assign;
+    MemOperand location = VarOperand(var, rcx);
+    __ movp(rdx, location);
+    __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex);
+    __ j(not_equal, &assign, Label::kNear);
+    __ Push(var->name());
+    __ CallRuntime(Runtime::kThrowReferenceError, 1);
+    __ bind(&assign);
+    EmitStoreToStackLocalOrContextSlot(var, location);
 
   } else if (!var->is_const_mode() || op == Token::INIT_CONST) {
-    // Assignment to var or initializing assignment to let/const
-    // in harmony mode.
     if (var->IsLookupSlot()) {
-      EmitCallStoreContextSlot(var->name(), strict_mode());
+      ASSERT(op == Token::ASSIGN || op == Token::INIT_VAR ||
+             op == Token::ASSIGN_ADD);
+      // Assignment to var.
+      __ Push(rax);  // Value.
+      __ Push(rsi);  // Context.
+      __ Push(var->name());
+      __ Push(Smi::FromInt(strict_mode()));
+      __ CallRuntime(Runtime::kStoreLookupSlot, 4);
     } else {
+      // Assignment to var or initializing assignment to let/const in harmony
+      // mode.
       ASSERT(var->IsStackAllocated() || var->IsContextSlot());
       MemOperand location = VarOperand(var, rcx);
       if (generate_debug_code_ && op == Token::INIT_LET) {
index cd33811..19767a2 100644 (file)
@@ -236,17 +236,14 @@ TEST(Unknown) {
   { DeclarationContext context;
     context.Check("var x; x",
                   1,  // access
-                  1,  // declaration
-                  2,  // declaration + initialization
-                  EXPECT_RESULT, Undefined(CcTest::isolate()));
+                  0, 0, EXPECT_RESULT, Undefined(CcTest::isolate()));
   }
 
   { DeclarationContext context;
     context.Check("var x = 0; x",
                   1,  // access
-                  2,  // declaration + initialization
-                  2,  // declaration + initialization
-                  EXPECT_RESULT, Number::New(CcTest::isolate(), 0));
+                  1,  // initialization
+                  0, EXPECT_RESULT, Number::New(CcTest::isolate(), 0));
   }
 
   { DeclarationContext context;
@@ -260,78 +257,19 @@ TEST(Unknown) {
   { DeclarationContext context;
     context.Check("const x; x",
                   1,  // access
-                  2,  // declaration + initialization
-                  1,  // declaration
-                  EXPECT_RESULT, Undefined(CcTest::isolate()));
+                  0, 0, EXPECT_RESULT, Undefined(CcTest::isolate()));
   }
 
   { DeclarationContext context;
-    // SB 0 - BUG 1213579
     context.Check("const x = 0; x",
                   1,  // access
-                  2,  // declaration + initialization
-                  1,  // declaration
-                  EXPECT_RESULT, Undefined(CcTest::isolate()));
-  }
-}
-
-
-
-class PresentPropertyContext: public DeclarationContext {
- protected:
-  virtual v8::Handle<Integer> Query(Local<String> key) {
-    return Integer::New(isolate(), v8::None);
-  }
-};
-
-
-
-TEST(Present) {
-  HandleScope scope(CcTest::isolate());
-
-  { PresentPropertyContext context;
-    context.Check("var x; x",
-                  1,  // access
-                  0,
-                  2,  // declaration + initialization
-                  EXPECT_EXCEPTION);  // x is not defined!
-  }
-
-  { PresentPropertyContext context;
-    context.Check("var x = 0; x",
-                  1,  // access
-                  1,  // initialization
-                  2,  // declaration + initialization
-                  EXPECT_RESULT, Number::New(CcTest::isolate(), 0));
-  }
-
-  { PresentPropertyContext context;
-    context.Check("function x() { }; x",
-                  1,  // access
                   0,
                   0,
-                  EXPECT_RESULT);
-  }
-
-  { PresentPropertyContext context;
-    context.Check("const x; x",
-                  1,  // access
-                  1,  // initialization
-                  1,  // (re-)declaration
-                  EXPECT_RESULT, Undefined(CcTest::isolate()));
-  }
-
-  { PresentPropertyContext context;
-    context.Check("const x = 0; x",
-                  1,  // access
-                  1,  // initialization
-                  1,  // (re-)declaration
                   EXPECT_RESULT, Number::New(CcTest::isolate(), 0));
   }
 }
 
 
-
 class AbsentPropertyContext: public DeclarationContext {
  protected:
   virtual v8::Handle<Integer> Query(Local<String> key) {
@@ -348,17 +286,14 @@ TEST(Absent) {
   { AbsentPropertyContext context;
     context.Check("var x; x",
                   1,  // access
-                  1,  // declaration
-                  2,  // declaration + initialization
-                  EXPECT_RESULT, Undefined(isolate));
+                  0, 0, EXPECT_RESULT, Undefined(isolate));
   }
 
   { AbsentPropertyContext context;
     context.Check("var x = 0; x",
                   1,  // access
-                  2,  // declaration + initialization
-                  2,  // declaration + initialization
-                  EXPECT_RESULT, Number::New(isolate, 0));
+                  1,  // initialization
+                  0, EXPECT_RESULT, Number::New(isolate, 0));
   }
 
   { AbsentPropertyContext context;
@@ -372,25 +307,19 @@ TEST(Absent) {
   { AbsentPropertyContext context;
     context.Check("const x; x",
                   1,  // access
-                  2,  // declaration + initialization
-                  1,  // declaration
-                  EXPECT_RESULT, Undefined(isolate));
+                  0, 0, EXPECT_RESULT, Undefined(isolate));
   }
 
   { AbsentPropertyContext context;
     context.Check("const x = 0; x",
                   1,  // access
-                  2,  // declaration + initialization
-                  1,  // declaration
-                  EXPECT_RESULT, Undefined(isolate));  // SB 0 - BUG 1213579
+                  0, 0, EXPECT_RESULT, Number::New(isolate, 0));
   }
 
   { AbsentPropertyContext context;
     context.Check("if (false) { var x = 0 }; x",
                   1,  // access
-                  1,  // declaration
-                  1,  // declaration + initialization
-                  EXPECT_RESULT, Undefined(isolate));
+                  0, 0, EXPECT_RESULT, Undefined(isolate));
   }
 }
 
@@ -439,17 +368,14 @@ TEST(Appearing) {
   { AppearingPropertyContext context;
     context.Check("var x; x",
                   1,  // access
-                  1,  // declaration
-                  2,  // declaration + initialization
-                  EXPECT_RESULT, Undefined(CcTest::isolate()));
+                  0, 0, EXPECT_RESULT, Undefined(CcTest::isolate()));
   }
 
   { AppearingPropertyContext context;
     context.Check("var x = 0; x",
                   1,  // access
-                  2,  // declaration + initialization
-                  2,  // declaration + initialization
-                  EXPECT_RESULT, Number::New(CcTest::isolate(), 0));
+                  1,  // initialization
+                  0, EXPECT_RESULT, Number::New(CcTest::isolate(), 0));
   }
 
   { AppearingPropertyContext context;
@@ -463,78 +389,13 @@ TEST(Appearing) {
   { AppearingPropertyContext context;
     context.Check("const x; x",
                   1,  // access
-                  2,  // declaration + initialization
-                  1,  // declaration
-                  EXPECT_RESULT, Undefined(CcTest::isolate()));
+                  0, 0, EXPECT_RESULT, Undefined(CcTest::isolate()));
   }
 
   { AppearingPropertyContext context;
     context.Check("const x = 0; x",
                   1,  // access
-                  2,  // declaration + initialization
-                  1,  // declaration
-                  EXPECT_RESULT, Undefined(CcTest::isolate()));
-                  // Result is undefined because declaration succeeded but
-                  // initialization to 0 failed (due to context behavior).
-  }
-}
-
-
-
-class ReappearingPropertyContext: public DeclarationContext {
- public:
-  enum State {
-    DECLARE,
-    DONT_DECLARE,
-    INITIALIZE,
-    UNKNOWN
-  };
-
-  ReappearingPropertyContext() : state_(DECLARE) { }
-
- protected:
-  virtual v8::Handle<Integer> Query(Local<String> key) {
-    switch (state_) {
-      case DECLARE:
-        // Force the first declaration by returning that
-        // the property is absent.
-        state_ = DONT_DECLARE;
-        return Handle<Integer>();
-      case DONT_DECLARE:
-        // Ignore the second declaration by returning
-        // that the property is already there.
-        state_ = INITIALIZE;
-        return Integer::New(isolate(), v8::None);
-      case INITIALIZE:
-        // Force an initialization by returning that
-        // the property is absent. This will make sure
-        // that the setter is called and it will not
-        // lead to redeclaration conflicts (yet).
-        state_ = UNKNOWN;
-        return Handle<Integer>();
-      default:
-        CHECK(state_ == UNKNOWN);
-        break;
-    }
-    // Do the lookup in the object.
-    return Handle<Integer>();
-  }
-
- private:
-  State state_;
-};
-
-
-TEST(Reappearing) {
-  v8::V8::Initialize();
-  HandleScope scope(CcTest::isolate());
-
-  { ReappearingPropertyContext context;
-    context.Check("const x; var x = 0",
-                  0,
-                  3,  // const declaration+initialization, var initialization
-                  3,  // 2 x declaration + var initialization
-                  EXPECT_RESULT, Undefined(CcTest::isolate()));
+                  0, 0, EXPECT_RESULT, Number::New(CcTest::isolate(), 0));
   }
 }
 
@@ -669,19 +530,13 @@ TEST(ExistsInHiddenPrototype) {
   HandleScope scope(CcTest::isolate());
 
   { ExistsInHiddenPrototypeContext context;
-    context.Check("var x; x",
-                  1,  // access
-                  0,
-                  2,  // declaration + initialization
-                  EXPECT_EXCEPTION);  // x is not defined!
+    context.Check("var x; x", 0, 0, 0, EXPECT_RESULT,
+                  Undefined(CcTest::isolate()));
   }
 
   { ExistsInHiddenPrototypeContext context;
-    context.Check("var x = 0; x",
-                  1,  // access
-                  1,  // initialization
-                  2,  // declaration + initialization
-                  EXPECT_RESULT, Number::New(CcTest::isolate(), 0));
+    context.Check("var x = 0; x", 0, 0, 0, EXPECT_RESULT,
+                  Number::New(CcTest::isolate(), 0));
   }
 
   { ExistsInHiddenPrototypeContext context;
@@ -694,20 +549,14 @@ TEST(ExistsInHiddenPrototype) {
 
   // TODO(mstarzinger): The semantics of global const is vague.
   { ExistsInHiddenPrototypeContext context;
-    context.Check("const x; x",
-                  0,
-                  0,
-                  1,  // (re-)declaration
-                  EXPECT_RESULT, Undefined(CcTest::isolate()));
+    context.Check("const x; x", 0, 0, 0, EXPECT_RESULT,
+                  Undefined(CcTest::isolate()));
   }
 
   // TODO(mstarzinger): The semantics of global const is vague.
   { ExistsInHiddenPrototypeContext context;
-    context.Check("const x = 0; x",
-                  0,
-                  0,
-                  1,  // (re-)declaration
-                  EXPECT_RESULT, Number::New(CcTest::isolate(), 0));
+    context.Check("const x = 0; x", 0, 0, 0, EXPECT_RESULT,
+                  Number::New(CcTest::isolate(), 0));
   }
 }
 
@@ -768,10 +617,8 @@ TEST(CrossScriptReferences) {
                   EXPECT_RESULT, Number::New(isolate, 1));
     context.Check("var x = 2; x",
                   EXPECT_RESULT, Number::New(isolate, 2));
-    context.Check("const x = 3; x",
-                  EXPECT_RESULT, Number::New(isolate, 3));
-    context.Check("const x = 4; x",
-                  EXPECT_RESULT, Number::New(isolate, 4));
+    context.Check("const x = 3; x", EXPECT_EXCEPTION);
+    context.Check("const x = 4; x", EXPECT_EXCEPTION);
     context.Check("x = 5; x",
                   EXPECT_RESULT, Number::New(isolate, 5));
     context.Check("var x = 6; x",
@@ -787,8 +634,7 @@ TEST(CrossScriptReferences) {
                   EXPECT_RESULT, Number::New(isolate, 1));
     context.Check("var x = 2; x",  // assignment ignored
                   EXPECT_RESULT, Number::New(isolate, 1));
-    context.Check("const x = 3; x",
-                  EXPECT_RESULT, Number::New(isolate, 1));
+    context.Check("const x = 3; x", EXPECT_EXCEPTION);
     context.Check("x = 4; x",  // assignment ignored
                   EXPECT_RESULT, Number::New(isolate, 1));
     context.Check("var x = 5; x",  // assignment ignored
index d350384..50e3a8d 100644 (file)
@@ -36,29 +36,29 @@ function testIntroduceGlobal() {
   var source =
       // Deleting 'x' removes the local const property.
       "delete x;" +
-      // Initialization turns into assignment to global 'x'.
+      // Initialization redefines global 'x'.
       "const x = 3; assertEquals(3, x);" +
-      // No constness of the global 'x'.
-      "x = 4; assertEquals(4, x);";
+      // Test constness of the global 'x'.
+      "x = 4; assertEquals(3, x);";
   eval(source);
 }
 
 testIntroduceGlobal();
-assertEquals(4, x);
+assertEquals("undefined", typeof x);
 
 function testAssignExistingGlobal() {
   var source =
       // Delete 'x' to remove the local const property.
       "delete x;" +
-      // Initialization turns into assignment to global 'x'.
+      // Initialization redefines global 'x'.
       "const x = 5; assertEquals(5, x);" +
-      // No constness of the global 'x'.
-      "x = 6; assertEquals(6, x);";
+      // Test constness of the global 'x'.
+      "x = 6; assertEquals(5, x);";
   eval(source);
 }
 
 testAssignExistingGlobal();
-assertEquals(6, x);
+assertEquals("undefined", typeof x);
 
 function testAssignmentArgument(x) {
   function local() {
@@ -66,7 +66,7 @@ function testAssignmentArgument(x) {
     eval(source);
   }
   local();
-  assertEquals(7, x);
+  assertEquals("undefined", typeof x);
 }
 
 for (var i = 0; i < 5; i++) {
@@ -74,17 +74,18 @@ for (var i = 0; i < 5; i++) {
 }
 %OptimizeFunctionOnNextCall(testAssignmentArgument);
 testAssignmentArgument();
-assertEquals(6, x);
+assertEquals("undefined", typeof x);
 
 __defineSetter__('x', function() { throw 42; });
-function testAssignGlobalThrows() {
-  // Initialization turns into assignment to global 'x' which
-  // throws an exception.
-  var source = "delete x; const x = 8";
+var finished = false;
+function testRedefineGlobal() {
+  // Initialization redefines global 'x'.
+  var source = "delete x; const x = 8; finished = true;";
   eval(source);
 }
 
-assertThrows("testAssignGlobalThrows()");
+testRedefineGlobal();
+assertTrue(finished);
 
 function testInitFastCaseExtension() {
   var source = "const x = 9; assertEquals(9, x); x = 10; assertEquals(9, x)";
@@ -111,7 +112,7 @@ function testAssignSurroundingContextSlot() {
     eval(source);
   }
   local();
-  assertEquals(13, x);
+  assertEquals(12, x);
 }
 
 testAssignSurroundingContextSlot();
index c0b97e6..f311f0d 100644 (file)
@@ -49,37 +49,6 @@ function TestLocal(s,e) {
 }
 
 
-// NOTE: TestGlobal usually only tests the given string in the context
-// of a global object in dictionary mode. This is because we use
-// delete to get rid of any added properties.
-function TestGlobal(s,e) {
-  // Collect the global properties before the call.
-  var properties = [];
-  for (var key in this) properties.push(key);
-  // Compute the result.
-  var result;
-  try {
-    var code = s + (e ? "; $$$result=" + e : "");
-    if (this.execScript) {
-      execScript(code);
-    } else {
-      this.eval(code);
-    }
-    // Avoid issues if $$$result is not defined by
-    // reading it through this.
-    result = this.$$$result;
-  } catch (x) {
-    result = CheckException(x);
-  }
-  // Get rid of any introduced global properties before
-  // returning the result.
-  for (var key in this) {
-    if (properties.indexOf(key) == -1) delete this[key];
-  }
-  return result;
-}
-
-
 function TestContext(s,e) {
   try {
     // Use a with-statement to force the system to do dynamic
@@ -98,8 +67,6 @@ function TestAll(expected,s,opt_e) {
   var msg = s;
   if (opt_e) { e = opt_e; msg += "; " + opt_e; }
   assertEquals(expected, TestLocal(s,e), "local:'" + msg + "'");
-  // Redeclarations of global consts do not throw, they are silently ignored.
-  assertEquals(42, TestGlobal(s, 42), "global:'" + msg + "'");
   assertEquals(expected, TestContext(s,e), "context:'" + msg + "'");
 }
 
@@ -112,7 +79,7 @@ function TestConflict(def0, def1) {
   // Eval first definition.
   TestAll("TypeError", 'eval("' + def0 +'"); ' + def1);
   // Eval second definition.
-  TestAll("TypeError", def0 + '; eval("' + def1 + '")');
+  TestAll("TypeError", def0 + '; eval("' + def1 +'")');
   // Eval both definitions separately.
   TestAll("TypeError", 'eval("' + def0 +'"); eval("' + def1 + '")');
 }
@@ -234,47 +201,26 @@ var undefined = 1;  // Should be silently ignored.
 assertEquals(original_undef, undefined, "undefined got overwritten");
 undefined = original_undef;
 
-var a; const a; const a = 1;
-assertEquals(1, a, "a has wrong value");
-a = 2;
-assertEquals(2, a, "a should be writable");
-
-var b = 1; const b = 2;
-assertEquals(2, b, "b has wrong value");
-
-var c = 1; const c = 2; const c = 3;
-assertEquals(3, c, "c has wrong value");
-
-const d = 1; const d = 2;
-assertEquals(1, d, "d has wrong value");
-
-const e = 1; var e = 2;
+const e = 1; eval('var e = 2');
 assertEquals(1, e, "e has wrong value");
 
-const f = 1; const f;
-assertEquals(1, f, "f has wrong value");
-
-var g; const g = 1;
-assertEquals(1, g, "g has wrong value");
-g = 2;
-assertEquals(2, g, "g should be writable");
-
-const h; var h = 1;
-assertEquals(undefined,h,  "h has wrong value");
+const h; eval('var h = 1');
+assertEquals(undefined, h, "h has wrong value");
 
 eval("Object.defineProperty(this, 'i', { writable: true });"
    + "const i = 7;"
    + "assertEquals(7, i, \"i has wrong value\");");
 
 var global = this;
-assertThrows(function() {
-  Object.defineProperty(global, 'j', { writable: true })
-}, TypeError);
-const j = 2;  // This is what makes the function above throw, because the
-// const declaration gets hoisted and makes the property non-configurable.
+Object.defineProperty(global, 'j', { value: 100, writable: true });
+assertEquals(100, j);
+// The const declaration stays configurable, so the declaration above goes
+// through even though the const declaration is hoisted above.
+const j = 2;
 assertEquals(2, j, "j has wrong value");
 
-var k = 1; const k;
-// You could argue about the expected result here. For now, the winning
-// argument is that "const k;" is equivalent to "const k = undefined;".
-assertEquals(undefined, k, "k has wrong value");
+var k = 1;
+try { eval('const k'); } catch(e) { }
+assertEquals(1, k, "k has wrong value");
+try { eval('const k = 10'); } catch(e) { }
+assertEquals(1, k, "k has wrong value");
index 2fca96f..3b87e3d 100644 (file)
@@ -41,17 +41,20 @@ try { eval("var b"); } catch (e) { caught++; assertTrue(e instanceof TypeError);
 assertEquals(0, b);
 try { eval("var b = 1"); } catch (e) { caught++; assertTrue(e instanceof TypeError); }
 assertEquals(0, b);
+assertEquals(0, caught);
 
 eval("var c");
 try { eval("const c"); } catch (e) { caught++; assertTrue(e instanceof TypeError); }
 assertTrue(typeof c == 'undefined');
+assertEquals(1, caught);
 try { eval("const c = 1"); } catch (e) { caught++; assertTrue(e instanceof TypeError); }
-assertEquals(1, c);
+assertEquals(undefined, c);
+assertEquals(2, caught);
 
 eval("var d = 0");
 try { eval("const d"); } catch (e) { caught++; assertTrue(e instanceof TypeError); }
-assertEquals(undefined, d);
+assertEquals(0, d);
+assertEquals(3, caught);
 try { eval("const d = 1"); } catch (e) { caught++; assertTrue(e instanceof TypeError); }
-assertEquals(1, d);
-
-assertEquals(0, caught);
+assertEquals(0, d);
+assertEquals(4, caught);
index 8c5f6f8..5d5800e 100644 (file)
@@ -25,8 +25,6 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// Flags: --es52_globals
-
 var setter_value = 0;
 
 this.__defineSetter__("a", function(v) { setter_value = v; });
@@ -35,8 +33,9 @@ assertEquals(1, setter_value);
 assertFalse("value" in Object.getOwnPropertyDescriptor(this, "a"));
 
 eval("with({}) { eval('var a = 2') }");
-assertEquals(2, setter_value);
+assertTrue("get" in Object.getOwnPropertyDescriptor(this, "a"));
 assertFalse("value" in Object.getOwnPropertyDescriptor(this, "a"));
+assertEquals(2, setter_value);
 
 // Function declarations are treated specially to match Safari. We do
 // not call setters for them.
@@ -47,10 +46,8 @@ assertTrue("value" in Object.getOwnPropertyDescriptor(this, "a"));
 this.__defineSetter__("b", function(v) { setter_value = v; });
 try {
   eval("const b = 3");
-} catch(e) {
-  assertUnreachable();
-}
-assertEquals(3, setter_value);
+} catch(e) { }
+assertEquals(2, setter_value);
 
 try {
   eval("with({}) { eval('const b = 23') }");
index f3a11db..8c197bc 100644 (file)
@@ -37,4 +37,4 @@ try {
   assertTrue(e instanceof TypeError);
   caught = true;
 }
-assertFalse(caught);
+assertTrue(caught);
@@ -2,6 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-__defineSetter__('x', function() { });
+Object.defineProperty(this, 'x', {set: function() { }});
 Object.freeze(this);
-eval('const x = 1');
+eval('"use strict"; x = 20;');
index f6689a3..2096a0d 100644 (file)
   # We do not correctly handle assignments within "with"
   'ecma_3/Statements/12.10-01': [FAIL],
 
-  # We do not throw an exception when a const is redeclared.
-  # (We only fail section 1 of the test.)
-  'js1_5/Regress/regress-103602': [FAIL],
-
   ##################### MOZILLA EXTENSION TESTS #####################
 
   'ecma/extensions/15.1.2.1-1': [FAIL_OK],
index 981d053..c81d900 100755 (executable)
@@ -49,7 +49,7 @@ EXPAND_MACROS = [
 # to parse them!
 EXPECTED_FUNCTION_COUNT = 417
 EXPECTED_FUZZABLE_COUNT = 332
-EXPECTED_CCTEST_COUNT = 6
+EXPECTED_CCTEST_COUNT = 9
 EXPECTED_UNKNOWN_COUNT = 4
 EXPECTED_BUILTINS_COUNT = 810