Author: [email protected]
Date: Sun Mar 15 09:18:20 2009
New Revision: 1511

Added:
    branches/bleeding_edge/test/mjsunit/regress/regress-279.js
Modified:
    branches/bleeding_edge/src/ast.cc
    branches/bleeding_edge/src/ast.h
    branches/bleeding_edge/src/codegen-arm.cc
    branches/bleeding_edge/src/codegen-ia32.cc
    branches/bleeding_edge/src/heap.h
    branches/bleeding_edge/src/parser.cc
    branches/bleeding_edge/src/parser.h
    branches/bleeding_edge/src/runtime.cc
    branches/bleeding_edge/src/runtime.h
    branches/bleeding_edge/test/mjsunit/fuzz-natives.js

Log:
Revert 1432, 1433, 1469 and 1472 due to a bug with literal objects.
Review URL: http://codereview.chromium.org/46088

Modified: branches/bleeding_edge/src/ast.cc
==============================================================================
--- branches/bleeding_edge/src/ast.cc   (original)
+++ branches/bleeding_edge/src/ast.cc   Sun Mar 15 09:18:20 2009
@@ -135,12 +135,8 @@
    Object* k = *key->handle();
    if (k->IsSymbol() && Heap::Proto_symbol()->Equals(String::cast(k))) {
      kind_ = PROTOTYPE;
-  } else if (value_->AsMaterializedLiteral() != NULL) {
-    kind_ = MATERIALIZED_LITERAL;
-  } else if (value_->AsLiteral() != NULL) {
-    kind_ = CONSTANT;
    } else {
-    kind_ = COMPUTED;
+    kind_ = value_->AsLiteral() == NULL ? COMPUTED : CONSTANT;
    }
  }


Modified: branches/bleeding_edge/src/ast.h
==============================================================================
--- branches/bleeding_edge/src/ast.h    (original)
+++ branches/bleeding_edge/src/ast.h    Sun Mar 15 09:18:20 2009
@@ -95,7 +95,6 @@

  // Forward declarations
  class TargetCollector;
-class MaterializedLiteral;

  #define DEF_FORWARD_DECLARATION(type) class type;
  NODE_LIST(DEF_FORWARD_DECLARATION)
@@ -130,9 +129,6 @@
    virtual BinaryOperation* AsBinaryOperation() { return NULL; }
    virtual Assignment* AsAssignment() { return NULL; }
    virtual FunctionLiteral* AsFunctionLiteral() { return NULL; }
-  virtual MaterializedLiteral* AsMaterializedLiteral() { return NULL; }
-  virtual ObjectLiteral* AsObjectLiteral() { return NULL; }
-  virtual ArrayLiteral* AsArrayLiteral() { return NULL; }

    void set_statement_pos(int statement_pos) { statement_pos_ =  
statement_pos; }
    int statement_pos() const { return statement_pos_; }
@@ -640,20 +636,11 @@
  // Base class for literals that needs space in the corresponding  
JSFunction.
  class MaterializedLiteral: public Expression {
   public:
-  explicit MaterializedLiteral(int literal_index, bool is_simple)
-      : literal_index_(literal_index), is_simple_(is_simple) {}
-
-  virtual MaterializedLiteral* AsMaterializedLiteral() { return this; }
-
+  explicit MaterializedLiteral(int literal_index)
+      : literal_index_(literal_index) {}
    int literal_index() { return literal_index_; }
-
-  // A materialized literal is simple if the values consist of only
-  // constants and simple object and array literals.
-  bool is_simple() const { return is_simple_; }
-
   private:
    int literal_index_;
-  bool is_simple_;
  };


@@ -668,11 +655,10 @@
     public:

      enum Kind {
-      CONSTANT,              // Property with constant value (compile  
time).
-      COMPUTED,              // Property with computed value (execution  
time).
-      MATERIALIZED_LITERAL,  // Property value is a materialized literal.
-      GETTER, SETTER,        // Property is an accessor function.
-      PROTOTYPE              // Property is __proto__.
+      CONSTANT,       // Property with constant value (at compile time).
+      COMPUTED,       // Property with computed value (at execution time).
+      GETTER, SETTER,  // Property is an accessor function.
+      PROTOTYPE       // Property is __proto__.
      };

      Property(Literal* key, Expression* value);
@@ -690,13 +676,12 @@

    ObjectLiteral(Handle<FixedArray> constant_properties,
                  ZoneList<Property*>* properties,
-                int literal_index,
-                bool is_simple)
-      : MaterializedLiteral(literal_index, is_simple),
+                int literal_index)
+      : MaterializedLiteral(literal_index),
          constant_properties_(constant_properties),
-        properties_(properties) {}
+        properties_(properties) {
+  }

-  virtual ObjectLiteral* AsObjectLiteral() { return this; }
    virtual void Accept(AstVisitor* v);

    Handle<FixedArray> constant_properties() const {
@@ -716,7 +701,7 @@
    RegExpLiteral(Handle<String> pattern,
                  Handle<String> flags,
                  int literal_index)
-      : MaterializedLiteral(literal_index, false),
+      : MaterializedLiteral(literal_index),
          pattern_(pattern),
          flags_(flags) {}

@@ -732,18 +717,14 @@

  // An array literal has a literals object that is used
  // for minimizing the work when constructing it at runtime.
-class ArrayLiteral: public MaterializedLiteral {
+class ArrayLiteral: public Expression {
   public:
    ArrayLiteral(Handle<FixedArray> literals,
-               ZoneList<Expression*>* values,
-               int literal_index,
-               bool is_simple)
-      : MaterializedLiteral(literal_index, is_simple),
-        literals_(literals),
-        values_(values) {}
+               ZoneList<Expression*>* values)
+      : literals_(literals), values_(values) {
+  }

    virtual void Accept(AstVisitor* v);
-  virtual ArrayLiteral* AsArrayLiteral() { return this; }

    Handle<FixedArray> literals() const { return literals_; }
    ZoneList<Expression*>* values() const { return values_; }

Modified: branches/bleeding_edge/src/codegen-arm.cc
==============================================================================
--- branches/bleeding_edge/src/codegen-arm.cc   (original)
+++ branches/bleeding_edge/src/codegen-arm.cc   Sun Mar 15 09:18:20 2009
@@ -2612,7 +2612,7 @@


  // This deferred code stub will be used for creating the boilerplate
-// by calling Runtime_CreateObjectLiteralBoilerplate.
+// by calling Runtime_CreateObjectLiteral.
  // Each created boilerplate is stored in the JSFunction and they are
  // therefore context dependent.
  class DeferredObjectLiteral: public DeferredCode {
@@ -2686,7 +2686,7 @@
    frame_->EmitPush(r2);

    // Clone the boilerplate object.
-  frame_->CallRuntime(Runtime::kCloneLiteralBoilerplate, 1);
+  frame_->CallRuntime(Runtime::kCloneObjectLiteralBoilerplate, 1);
    frame_->EmitPush(r0);  // save the result
    // r0: cloned object literal

@@ -2695,11 +2695,7 @@
      Literal* key = property->key();
      Expression* value = property->value();
      switch (property->kind()) {
-      case ObjectLiteral::Property::CONSTANT:
-        break;
-      case ObjectLiteral::Property::MATERIALIZED_LITERAL:
-        if (property->value()->AsMaterializedLiteral()->is_simple()) break;
-        // else fall through
+      case ObjectLiteral::Property::CONSTANT: break;
        case ObjectLiteral::Property::COMPUTED:  // fall through
        case ObjectLiteral::Property::PROTOTYPE: {
          frame_->EmitPush(r0);  // dup the result
@@ -2736,49 +2732,6 @@
  }


-// This deferred code stub will be used for creating the boilerplate
-// by calling Runtime_CreateArrayLiteralBoilerplate.
-// Each created boilerplate is stored in the JSFunction and they are
-// therefore context dependent.
-class DeferredArrayLiteral: public DeferredCode {
- public:
-  DeferredArrayLiteral(CodeGenerator* generator, ArrayLiteral* node)
-      : DeferredCode(generator), node_(node) {
-    set_comment("[ DeferredArrayLiteral");
-  }
-
-  virtual void Generate();
-
- private:
-  ArrayLiteral* node_;
-};
-
-
-void DeferredArrayLiteral::Generate() {
-  // Argument is passed in r1.
-  enter()->Bind();
-  VirtualFrame::SpilledScope spilled_scope(generator());
-
-  // If the entry is undefined we call the runtime system to computed
-  // the literal.
-
-  VirtualFrame* frame = generator()->frame();
-  // Literal array (0).
-  frame->EmitPush(r1);
-  // Literal index (1).
-  __ mov(r0, Operand(Smi::FromInt(node_->literal_index())));
-  frame->EmitPush(r0);
-  // Constant properties (2).
-  __ mov(r0, Operand(node_->literals()));
-  frame->EmitPush(r0);
-  Result boilerplate =
-      frame->CallRuntime(Runtime::kCreateArrayLiteralBoilerplate, 3);
-  __ mov(r2, Operand(boilerplate.reg()));
-  // Result is returned in r2.
-  exit_.Jump();
-}
-
-
  void CodeGenerator::VisitArrayLiteral(ArrayLiteral* node) {
  #ifdef DEBUG
    int original_height = frame_->height();
@@ -2786,34 +2739,17 @@
    VirtualFrame::SpilledScope spilled_scope(this);
    Comment cmnt(masm_, "[ ArrayLiteral");

-  DeferredArrayLiteral* deferred = new DeferredArrayLiteral(this, node);
-
-  // Retrieve the literal array and check the allocated entry.
-
-  // Load the function of this activation.
-  __ ldr(r1, frame_->Function());
-
-  // Load the literals array of the function.
-  __ ldr(r1, FieldMemOperand(r1, JSFunction::kLiteralsOffset));
-
-  // Load the literal at the ast saved index.
-  int literal_offset =
-      FixedArray::kHeaderSize + node->literal_index() * kPointerSize;
-  __ ldr(r2, FieldMemOperand(r1, literal_offset));
-
-  // Check whether we need to materialize the object literal boilerplate.
-  // If so, jump to the deferred code.
-  __ cmp(r2, Operand(Factory::undefined_value()));
-  deferred->enter()->Branch(eq);
-  deferred->BindExit();
-
-  // Push the object literal boilerplate.
-  frame_->EmitPush(r2);
+  // Call runtime to create the array literal.
+  __ mov(r0, Operand(node->literals()));
+  frame_->EmitPush(r0);
+  // Load the function of this frame.
+  __ ldr(r0, frame_->Function());
+  __ ldr(r0, FieldMemOperand(r0, JSFunction::kLiteralsOffset));
+  frame_->EmitPush(r0);
+  frame_->CallRuntime(Runtime::kCreateArrayLiteral, 2);

-  // Clone the boilerplate object.
-  frame_->CallRuntime(Runtime::kCloneLiteralBoilerplate, 1);
-  frame_->EmitPush(r0);  // save the result
-  // r0: cloned object literal
+  // Push the resulting array literal on the stack.
+  frame_->EmitPush(r0);

    // Generate code to set the elements in the array that are not
    // literals.

Modified: branches/bleeding_edge/src/codegen-ia32.cc
==============================================================================
--- branches/bleeding_edge/src/codegen-ia32.cc  (original)
+++ branches/bleeding_edge/src/codegen-ia32.cc  Sun Mar 15 09:18:20 2009
@@ -32,7 +32,6 @@
  #include "debug.h"
  #include "scopes.h"
  #include "runtime.h"
-#include "parser.h"

  namespace v8 { namespace internal {

@@ -3501,18 +3500,14 @@
    frame_->Push(&boilerplate);
    // Clone the boilerplate object.
    Result clone =
-      frame_->CallRuntime(Runtime::kCloneLiteralBoilerplate, 1);
+      frame_->CallRuntime(Runtime::kCloneObjectLiteralBoilerplate, 1);
    // Push the newly cloned literal object as the result.
    frame_->Push(&clone);

    for (int i = 0; i < node->properties()->length(); i++) {
      ObjectLiteral::Property* property = node->properties()->at(i);
      switch (property->kind()) {
-      case ObjectLiteral::Property::CONSTANT:
-        break;
-      case ObjectLiteral::Property::MATERIALIZED_LITERAL:
-        if (CompileTimeValue::IsCompileTimeValue(property->value())) break;
-        // else fall through.
+      case ObjectLiteral::Property::CONSTANT: break;
        case ObjectLiteral::Property::COMPUTED: {
          Handle<Object> key(property->key()->handle());
          Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
@@ -3570,123 +3565,59 @@
  }


-// This deferred code stub will be used for creating the boilerplate
-// by calling Runtime_CreateArrayLiteralBoilerplate.
-// Each created boilerplate is stored in the JSFunction and they are
-// therefore context dependent.
-class DeferredArrayLiteral: public DeferredCode {
- public:
-  DeferredArrayLiteral(CodeGenerator* generator,
-                       ArrayLiteral* node)
-      : DeferredCode(generator), node_(node) {
-    set_comment("[ DeferredArrayLiteral");
-  }
-
-  virtual void Generate();
-
- private:
-  ArrayLiteral* node_;
-};
-
-
-void DeferredArrayLiteral::Generate() {
-  Result literals(generator());
-  enter()->Bind(&literals);
-  // Since the entry is undefined we call the runtime system to
-  // compute the literal.
-
-  VirtualFrame* frame = generator()->frame();
-  // Literal array (0).
-  frame->Push(&literals);
-  // Literal index (1).
-  frame->Push(Smi::FromInt(node_->literal_index()));
-  // Constant properties (2).
-  frame->Push(node_->literals());
-  Result boilerplate =
-      frame->CallRuntime(Runtime::kCreateArrayLiteralBoilerplate, 3);
-  exit_.Jump(&boilerplate);
-}
-
-
  void CodeGenerator::VisitArrayLiteral(ArrayLiteral* node) {
    Comment cmnt(masm_, "[ ArrayLiteral");
-  DeferredArrayLiteral* deferred = new DeferredArrayLiteral(this, node);

-  // Retrieve the literals array and check the allocated entry.  Begin
-  // with a writable copy of the function of this activation in a
-  // register.
+  // Call the runtime to create the array literal.
+  frame_->Push(node->literals());
+  // Load the literals array of the current function.
    frame_->PushFunction();
    Result literals = frame_->Pop();
    literals.ToRegister();
-  frame_->Spill(literals.reg());
-
-  // Load the literals array of the function.
+  frame_->Spill(literals.reg());  // Make it writable.
    __ mov(literals.reg(),
           FieldOperand(literals.reg(), JSFunction::kLiteralsOffset));
-
-  // Load the literal at the ast saved index.
-  int literal_offset =
-      FixedArray::kHeaderSize + node->literal_index() * kPointerSize;
-  Result boilerplate = allocator_->Allocate();
-  ASSERT(boilerplate.is_valid());
-  __ mov(boilerplate.reg(), FieldOperand(literals.reg(), literal_offset));
-
-  // Check whether we need to materialize the object literal boilerplate.
-  // If so, jump to the deferred code passing the literals array.
-  __ cmp(boilerplate.reg(), Factory::undefined_value());
-  deferred->enter()->Branch(equal, &literals, not_taken);
-
-  literals.Unuse();
-  // The deferred code returns the boilerplate object.
-  deferred->BindExit(&boilerplate);
+  frame_->Push(&literals);
+  Result array = frame_->CallRuntime(Runtime::kCreateArrayLiteral, 2);

    // Push the resulting array literal on the stack.
-  frame_->Push(&boilerplate);
-
-  // Clone the boilerplate object.
-  Result clone =
-      frame_->CallRuntime(Runtime::kCloneLiteralBoilerplate, 1);
-  // Push the newly cloned literal object as the result.
-  frame_->Push(&clone);
+  frame_->Push(&array);

    // Generate code to set the elements in the array that are not
    // literals.
    for (int i = 0; i < node->values()->length(); i++) {
      Expression* value = node->values()->at(i);

-    // If value is a literal the property value is already set in the
+    // If value is literal the property value is already set in the
      // boilerplate object.
-    if (value->AsLiteral() != NULL) continue;
-    // If value is a materialized literal the property value is already set
-    // in the boilerplate object if it is simple.
-    if (CompileTimeValue::IsCompileTimeValue(value)) continue;
-
-    // The property must be set by generated code.
-    Load(value);
-
-    // Get the property value off the stack.
-    Result prop_value = frame_->Pop();
-    prop_value.ToRegister();
+    if (value->AsLiteral() == NULL) {
+      // The property must be set by generated code.
+      Load(value);
+
+      // Get the property value off the stack.
+      Result prop_value = frame_->Pop();
+      prop_value.ToRegister();

-    // Fetch the array literal while leaving a copy on the stack and
-    // use it to get the elements array.
-    frame_->Dup();
-    Result elements = frame_->Pop();
-    elements.ToRegister();
-    frame_->Spill(elements.reg());
-    // Get the elements array.
-    __ mov(elements.reg(),
-           FieldOperand(elements.reg(), JSObject::kElementsOffset));
-
-    // Write to the indexed properties array.
-    int offset = i * kPointerSize + Array::kHeaderSize;
-    __ mov(FieldOperand(elements.reg(), offset), prop_value.reg());
-
-    // Update the write barrier for the array address.
-    frame_->Spill(prop_value.reg());  // Overwritten by the write barrier.
-    Result scratch = allocator_->Allocate();
-    ASSERT(scratch.is_valid());
-    __ RecordWrite(elements.reg(), offset, prop_value.reg(),  
scratch.reg());
+      // Fetch the array literal while leaving a copy on the stack and
+      // use it to get the elements array.
+      frame_->Dup();
+      Result elements = frame_->Pop();
+      elements.ToRegister();
+      frame_->Spill(elements.reg());
+      // Get the elements array.
+      __ mov(elements.reg(),
+             FieldOperand(elements.reg(), JSObject::kElementsOffset));
+
+      // Write to the indexed properties array.
+      int offset = i * kPointerSize + Array::kHeaderSize;
+      __ mov(FieldOperand(elements.reg(), offset), prop_value.reg());
+
+      // Update the write barrier for the array address.
+      frame_->Spill(prop_value.reg());  // Overwritten by the write  
barrier.
+      Result scratch = allocator_->Allocate();
+      ASSERT(scratch.is_valid());
+      __ RecordWrite(elements.reg(), offset, prop_value.reg(),  
scratch.reg());
+    }
    }
  }


Modified: branches/bleeding_edge/src/heap.h
==============================================================================
--- branches/bleeding_edge/src/heap.h   (original)
+++ branches/bleeding_edge/src/heap.h   Sun Mar 15 09:18:20 2009
@@ -167,6 +167,8 @@
    V(char_at_symbol, "CharAt")                                            \
    V(undefined_symbol, "undefined")                                       \
    V(value_of_symbol, "valueOf")                                          \
+   
V(CreateObjectLiteralBoilerplate_symbol, "CreateObjectLiteralBoilerplate") \
+  V(CreateArrayLiteral_symbol, "CreateArrayLiteral")                     \
    V(InitializeVarGlobal_symbol, "InitializeVarGlobal")                   \
    V(InitializeConstGlobal_symbol, "InitializeConstGlobal")               \
    V(stack_overflow_symbol, "kStackOverflowBoilerplate")                  \

Modified: branches/bleeding_edge/src/parser.cc
==============================================================================
--- branches/bleeding_edge/src/parser.cc        (original)
+++ branches/bleeding_edge/src/parser.cc        Sun Mar 15 09:18:20 2009
@@ -158,12 +158,10 @@

    // Decide if a property should be the object boilerplate.
    bool IsBoilerplateProperty(ObjectLiteral::Property* property);
-  // If the expression is a literal, return the literal value;
-  // if the expression is a materialized literal and is simple return a
-  // compile time value as encoded by CompileTimeValue::GetValue().
-  // Otherwise, return undefined literal as the placeholder
+  // If the property is CONSTANT type, it returns the literal value,
+  // otherwise, it return undefined literal as the placeholder
    // in the object literal boilerplate.
-  Handle<Object> GetBoilerplateValue(Expression* expression);
+  Literal* GetBoilerplateValue(ObjectLiteral::Property* property);

    enum FunctionLiteralType {
      EXPRESSION,
@@ -3058,7 +3056,6 @@

    // Update the scope information before the pre-parsing bailout.
    temp_scope_->set_contains_array_literal();
-  int literal_index = temp_scope_->NextMaterializedLiteralIndex();

    if (is_pre_parsing_) return NULL;

@@ -3067,19 +3064,16 @@
        Factory::NewFixedArray(values.length(), TENURED);

    // Fill in the literals.
-  bool is_simple = true;
    for (int i = 0; i < values.length(); i++) {
-    Handle<Object> boilerplate_value = GetBoilerplateValue(values.at(i));
-    if (boilerplate_value->IsUndefined()) {
+    Literal* literal = values.at(i)->AsLiteral();
+    if (literal == NULL) {
        literals->set_the_hole(i);
-      is_simple = false;
      } else {
-      literals->set(i, *boilerplate_value);
+      literals->set(i, *literal->handle());
      }
    }

-  return NEW(ArrayLiteral(literals, values.elements(),
-                          literal_index, is_simple));
+  return NEW(ArrayLiteral(literals, values.elements()));
  }


@@ -3089,48 +3083,10 @@
  }


-bool CompileTimeValue::IsCompileTimeValue(Expression* expression) {
-  MaterializedLiteral* lit = expression->AsMaterializedLiteral();
-  return lit != NULL && lit->is_simple();
-}
-
-Handle<FixedArray> CompileTimeValue::GetValue(Expression* expression) {
-  ASSERT(IsCompileTimeValue(expression));
-  Handle<FixedArray> result = Factory::NewFixedArray(2, TENURED);
-  ObjectLiteral* object_literal = expression->AsObjectLiteral();
-  if (object_literal != NULL) {
-    ASSERT(object_literal->is_simple());
-    result->set(kTypeSlot, Smi::FromInt(OBJECT_LITERAL));
-    result->set(kElementsSlot, *object_literal->constant_properties());
-  } else {
-    ArrayLiteral* array_literal = expression->AsArrayLiteral();
-    ASSERT(array_literal != NULL && array_literal->is_simple());
-    result->set(kTypeSlot, Smi::FromInt(ARRAY_LITERAL));
-    result->set(kElementsSlot, *array_literal->literals());
-  }
-  return result;
-}
-
-
-CompileTimeValue::Type CompileTimeValue::GetType(Handle<FixedArray> value)  
{
-  Smi* type_value = Smi::cast(value->get(kTypeSlot));
-  return static_cast<Type>(type_value->value());
-}
-
-
-Handle<FixedArray> CompileTimeValue::GetElements(Handle<FixedArray> value)  
{
-  return Handle<FixedArray>(FixedArray::cast(value->get(kElementsSlot)));
-}
-
-
-Handle<Object> Parser::GetBoilerplateValue(Expression* expression) {
-  if (expression->AsLiteral() != NULL) {
-    return expression->AsLiteral()->handle();
-  }
-  if (CompileTimeValue::IsCompileTimeValue(expression)) {
-    return CompileTimeValue::GetValue(expression);
-  }
-  return Factory::undefined_value();
+Literal* Parser::GetBoilerplateValue(ObjectLiteral::Property* property) {
+  if (property->kind() == ObjectLiteral::Property::CONSTANT)
+    return property->value()->AsLiteral();
+  return GetLiteralUndefined();
  }


@@ -3225,30 +3181,24 @@
    Handle<FixedArray> constant_properties =
        Factory::NewFixedArray(number_of_boilerplate_properties * 2,  
TENURED);
    int position = 0;
-  bool is_simple = true;
    for (int i = 0; i < properties.length(); i++) {
      ObjectLiteral::Property* property = properties.at(i);
-    if (!IsBoilerplateProperty(property)) {
-      is_simple = false;
-      continue;
-    }
+    if (!IsBoilerplateProperty(property)) continue;

      // Add CONSTANT and COMPUTED properties to boilerplate. Use undefined
      // value for COMPUTED properties, the real value is filled in at
      // runtime. The enumeration order is maintained.
      Handle<Object> key = property->key()->handle();
-    Handle<Object> value = GetBoilerplateValue(property->value());
-    is_simple = is_simple && !value->IsUndefined();
+    Literal* literal = GetBoilerplateValue(property);

      // Add name, value pair to the fixed array.
      constant_properties->set(position++, *key);
-    constant_properties->set(position++, *value);
+    constant_properties->set(position++, *literal->handle());
    }

    return new ObjectLiteral(constant_properties,
                             properties.elements(),
-                           literal_index,
-                           is_simple);
+                           literal_index);
  }



Modified: branches/bleeding_edge/src/parser.h
==============================================================================
--- branches/bleeding_edge/src/parser.h (original)
+++ branches/bleeding_edge/src/parser.h Sun Mar 15 09:18:20 2009
@@ -29,7 +29,6 @@
  #define V8_PARSER_H_

  #include "scanner.h"
-#include "allocation.h"

  namespace v8 { namespace internal {

@@ -165,35 +164,6 @@
                               int start_position,
                               int end_position,
                               bool is_expression);
-
-
-// Support for handling complex values (array and object literals) that
-// can be fully handled at compile time.
-class CompileTimeValue: public AllStatic {
- public:
-  enum Type {
-    OBJECT_LITERAL,
-    ARRAY_LITERAL
-  };
-
-  static bool IsCompileTimeValue(Expression* expression);
-
-  // Get the value as a compile time value.
-  static Handle<FixedArray> GetValue(Expression* expression);
-
-  // Get the type of a compile time value returned by GetValue().
-  static Type GetType(Handle<FixedArray> value);
-
-  // Get the elements array of a compile time value returned by GetValue().
-  static Handle<FixedArray> GetElements(Handle<FixedArray> value);
-
- private:
-  static const int kTypeSlot = 0;
-  static const int kElementsSlot = 1;
-
-  DISALLOW_IMPLICIT_CONSTRUCTORS(CompileTimeValue);
-};
-

  } }  // namespace v8::internal


Modified: branches/bleeding_edge/src/runtime.cc
==============================================================================
--- branches/bleeding_edge/src/runtime.cc       (original)
+++ branches/bleeding_edge/src/runtime.cc       Sun Mar 15 09:18:20 2009
@@ -43,7 +43,6 @@
  #include "scopeinfo.h"
  #include "v8threads.h"
  #include "smart-pointer.h"
-#include "parser.h"

  namespace v8 { namespace internal {

@@ -70,13 +69,6 @@
    RUNTIME_ASSERT(obj->IsBoolean());                                   \
    bool name = (obj)->IsTrue();

-// Cast the given object to an int and store it in a variable with
-// the given name.  If the object is not a Smi call IllegalOperation
-// and return.
-#define CONVERT_INT_CHECKED(name, obj)                            \
-  RUNTIME_ASSERT(obj->IsSmi());                                   \
-  int name = Smi::cast(obj)->value();
-
  // Cast the given object to a double and store it in a variable with
  // the given name.  If the object is not a number (as opposed to
  // the number not-a-number) call IllegalOperation and return.
@@ -100,7 +92,7 @@
  }


-static Object* Runtime_CloneLiteralBoilerplate(Arguments args) {
+static Object* Runtime_CloneObjectLiteralBoilerplate(Arguments args) {
    CONVERT_CHECKED(JSObject, boilerplate, args[0]);
    return Heap::CopyJSObject(boilerplate);
  }
@@ -139,14 +131,14 @@
  }


-static Handle<Object> CreateLiteralBoilerplate(
-    Handle<FixedArray> literals,
-    Handle<FixedArray> constant_properties);
-
+static Object* Runtime_CreateObjectLiteralBoilerplate(Arguments args) {
+  HandleScope scope;
+  ASSERT(args.length() == 3);
+  // Copy the arguments.
+  Handle<FixedArray> literals = args.at<FixedArray>(0);
+  int literals_index = Smi::cast(args[1])->value();
+  Handle<FixedArray> constant_properties = args.at<FixedArray>(2);

-static Handle<Object> CreateObjectLiteralBoilerplate(
-    Handle<FixedArray> literals,
-    Handle<FixedArray> constant_properties) {
    // Get the global context from the literals array.  This is the
    // context in which the function was created and we use the object
    // function from this context to create the object literal.  We do
@@ -169,13 +161,6 @@
      for (int index = 0; index < length; index +=2) {
        Handle<Object> key(constant_properties->get(index+0));
        Handle<Object> value(constant_properties->get(index+1));
-      if (value->IsFixedArray()) {
-        // The value contains the constant_properties of a
-        // simple object literal.
-        Handle<FixedArray> array = Handle<FixedArray>::cast(value);
-        value = CreateLiteralBoilerplate(literals, array);
-        if (value.is_null()) return value;
-      }
        Handle<Object> result;
        uint32_t element_index = 0;
        if (key->IsSymbol()) {
@@ -200,96 +185,39 @@
        // exception, the exception is converted to an empty handle in
        // the handle based operations.  In that case, we need to
        // convert back to an exception.
-      if (result.is_null()) return result;
+      if (result.is_null()) return Failure::Exception();
      }
    }

-  return boilerplate;
-}
-
-
-static Handle<Object> CreateArrayLiteralBoilerplate(
-    Handle<FixedArray> literals,
-    Handle<FixedArray> elements) {
-  // Create the JSArray.
-  Handle<JSFunction> constructor(
-      JSFunction::GlobalContextFromLiterals(*literals)->array_function());
-  Handle<Object> object = Factory::NewJSObject(constructor);
-
-  Handle<Object> copied_elements = Factory::CopyFixedArray(elements);
-
-  Handle<FixedArray> content = Handle<FixedArray>::cast(copied_elements);
-  for (int i = 0; i < content->length(); i++) {
-    if (content->get(i)->IsFixedArray()) {
-      // The value contains the constant_properties of a
-      // simple object literal.
-      Handle<FixedArray> fa(FixedArray::cast(content->get(i)));
-      Handle<Object> result = CreateLiteralBoilerplate(literals, fa);
-      if (result.is_null()) return result;
-      content->set(i, *result);
-    }
-  }
-
-  // Set the elements.
-  Handle<JSArray>::cast(object)->SetContent(*content);
-  return object;
-}
-
-
-static Handle<Object> CreateLiteralBoilerplate(
-    Handle<FixedArray> literals,
-    Handle<FixedArray> array) {
-  Handle<FixedArray> elements = CompileTimeValue::GetElements(array);
-  switch (CompileTimeValue::GetType(array)) {
-    case CompileTimeValue::OBJECT_LITERAL:
-      return CreateObjectLiteralBoilerplate(literals, elements);
-    case CompileTimeValue::ARRAY_LITERAL:
-      return CreateArrayLiteralBoilerplate(literals, elements);
-    default:
-      UNREACHABLE();
-      return Handle<Object>::null();
-  }
-}
-
-
-static Object* Runtime_CreateObjectLiteralBoilerplate(Arguments args) {
-  HandleScope scope;
-  ASSERT(args.length() == 3);
-  // Copy the arguments.
-  CONVERT_ARG_CHECKED(FixedArray, literals, 0);
-  CONVERT_INT_CHECKED(literals_index, args[1]);
-  CONVERT_ARG_CHECKED(FixedArray, constant_properties, 2);
-
-  Handle<Object> result =
-    CreateObjectLiteralBoilerplate(literals, constant_properties);
-
-  if (result.is_null()) return Failure::Exception();
-
    // Update the functions literal and return the boilerplate.
-  literals->set(literals_index, *result);
+  literals->set(literals_index, *boilerplate);

-  return *result;
+  return *boilerplate;
  }


-static Object* Runtime_CreateArrayLiteralBoilerplate(Arguments args) {
+static Object* Runtime_CreateArrayLiteral(Arguments args) {
    // Takes a FixedArray of elements containing the literal elements of
    // the array literal and produces JSArray with those elements.
    // Additionally takes the literals array of the surrounding function
    // which contains the context from which to get the Array function
    // to use for creating the array literal.
-  HandleScope scope;
-  ASSERT(args.length() == 3);
-  CONVERT_ARG_CHECKED(FixedArray, literals, 0);
-  CONVERT_INT_CHECKED(literals_index, args[1]);
-  CONVERT_ARG_CHECKED(FixedArray, elements, 2);
+  ASSERT(args.length() == 2);
+  CONVERT_CHECKED(FixedArray, elements, args[0]);
+  CONVERT_CHECKED(FixedArray, literals, args[1]);
+  JSFunction* constructor =
+      JSFunction::GlobalContextFromLiterals(literals)->array_function();
+  // Create the JSArray.
+  Object* object = Heap::AllocateJSObject(constructor);
+  if (object->IsFailure()) return object;

-  Handle<Object> object = CreateArrayLiteralBoilerplate(literals,  
elements);
-  if (object.is_null()) return Failure::Exception();
+  // Copy the elements.
+  Object* content = elements->Copy();
+  if (content->IsFailure()) return content;

-  // Update the functions literal and return the boilerplate.
-  literals->set(literals_index, *object);
-  return *object;
+  // Set the elements.
+  JSArray::cast(object)->SetContent(FixedArray::cast(content));
+  return object;
  }



Modified: branches/bleeding_edge/src/runtime.h
==============================================================================
--- branches/bleeding_edge/src/runtime.h        (original)
+++ branches/bleeding_edge/src/runtime.h        Sun Mar 15 09:18:20 2009
@@ -251,9 +251,9 @@
    \
    /* Literals */ \
    F(MaterializeRegExpLiteral, 4)\
-  F(CreateArrayLiteralBoilerplate, 3) \
+  F(CreateArrayLiteral, 2) \
    F(CreateObjectLiteralBoilerplate, 3) \
-  F(CloneLiteralBoilerplate, 1) \
+  F(CloneObjectLiteralBoilerplate, 1) \
    \
    /* Catch context extension objects */ \
    F(CreateCatchExtensionObject, 2) \
@@ -326,6 +326,7 @@
      kNofFunctions
  #undef F
    };
+  static Object* CreateArrayLiteral(Arguments args);

    // Runtime function descriptor.
    struct Function {

Modified: branches/bleeding_edge/test/mjsunit/fuzz-natives.js
==============================================================================
--- branches/bleeding_edge/test/mjsunit/fuzz-natives.js (original)
+++ branches/bleeding_edge/test/mjsunit/fuzz-natives.js Sun Mar 15 09:18:20  
2009
@@ -121,8 +121,7 @@
    "PushContext": true,
    "LazyCompile": true,
    "CreateObjectLiteralBoilerplate": true,
-  "CloneLiteralBoilerplate": true,
-  "CreateArrayLiteralBoilerplate": true,
+  "CloneObjectLiteralBoilerplate": true,
    "IS_VAR": true,
    "ResolvePossiblyDirectEval": true,
    "Log": true

Added: branches/bleeding_edge/test/mjsunit/regress/regress-279.js
==============================================================================
--- (empty file)
+++ branches/bleeding_edge/test/mjsunit/regress/regress-279.js  Sun Mar 15  
09:18:20 2009
@@ -0,0 +1,53 @@
+// Copyright 2009 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+function makeArrayInObject() {
+  return { foo: [] };
+}
+
+var a = makeArrayInObject();
+a.foo.push(5);
+var b = makeArrayInObject();
+assertEquals(0, b.foo.length, "Array in object");
+
+function makeObjectInObject() {
+  return { foo: {} };
+}
+
+a = makeObjectInObject();
+a.foo.bar = 1;
+b = makeObjectInObject();
+assertEquals('undefined', typeof(b.foo.bar), "Object in object");
+
+function makeObjectInArray() {
+  return [ {} ];
+}
+
+a = makeObjectInArray();
+a[0].bar = 1;
+b = makeObjectInArray();
+assertEquals('undefined', typeof(b[0].bar), "Object in object");

--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---

Reply via email to