| Index: src/parser.cc
 | 
| ===================================================================
 | 
| --- src/parser.cc	(revision 1544)
 | 
| +++ src/parser.cc	(working copy)
 | 
| @@ -158,10 +158,12 @@
 | 
|  
 | 
|    // Decide if a property should be the object boilerplate.
 | 
|    bool IsBoilerplateProperty(ObjectLiteral::Property* property);
 | 
| -  // If the property is CONSTANT type, it returns the literal value,
 | 
| -  // otherwise, it return undefined literal as the placeholder
 | 
| +  // 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
 | 
|    // in the object literal boilerplate.
 | 
| -  Literal* GetBoilerplateValue(ObjectLiteral::Property* property);
 | 
| +  Handle<Object> GetBoilerplateValue(Expression* expression);
 | 
|  
 | 
|    enum FunctionLiteralType {
 | 
|      EXPRESSION,
 | 
| @@ -3054,6 +3056,7 @@
 | 
|  
 | 
|    // 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;
 | 
|  
 | 
| @@ -3062,16 +3065,24 @@
 | 
|        Factory::NewFixedArray(values.length(), TENURED);
 | 
|  
 | 
|    // Fill in the literals.
 | 
| +  bool is_simple = true;
 | 
| +  int depth = 1;
 | 
|    for (int i = 0; i < values.length(); i++) {
 | 
| -    Literal* literal = values.at(i)->AsLiteral();
 | 
| -    if (literal == NULL) {
 | 
| +    MaterializedLiteral* m_literal = values.at(i)->AsMaterializedLiteral();
 | 
| +    if (m_literal != NULL && m_literal->depth() + 1 > depth) {
 | 
| +      depth = m_literal->depth() + 1;
 | 
| +    }
 | 
| +    Handle<Object> boilerplate_value = GetBoilerplateValue(values.at(i));
 | 
| +    if (boilerplate_value->IsUndefined()) {
 | 
|        literals->set_the_hole(i);
 | 
| +      is_simple = false;
 | 
|      } else {
 | 
| -      literals->set(i, *literal->handle());
 | 
| +      literals->set(i, *boilerplate_value);
 | 
|      }
 | 
|    }
 | 
|  
 | 
| -  return NEW(ArrayLiteral(literals, values.elements()));
 | 
| +  return NEW(ArrayLiteral(literals, values.elements(),
 | 
| +                          literal_index, is_simple, depth));
 | 
|  }
 | 
|  
 | 
|  
 | 
| @@ -3081,13 +3092,51 @@
 | 
|  }
 | 
|  
 | 
|  
 | 
| -Literal* Parser::GetBoilerplateValue(ObjectLiteral::Property* property) {
 | 
| -  if (property->kind() == ObjectLiteral::Property::CONSTANT)
 | 
| -    return property->value()->AsLiteral();
 | 
| -  return GetLiteralUndefined();
 | 
| +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();
 | 
| +}
 | 
| +
 | 
| +
 | 
|  Expression* Parser::ParseObjectLiteral(bool* ok) {
 | 
|    // ObjectLiteral ::
 | 
|    //   '{' (
 | 
| @@ -3179,24 +3228,36 @@
 | 
|    Handle<FixedArray> constant_properties =
 | 
|        Factory::NewFixedArray(number_of_boilerplate_properties * 2, TENURED);
 | 
|    int position = 0;
 | 
| +  bool is_simple = true;
 | 
| +  int depth = 1;
 | 
|    for (int i = 0; i < properties.length(); i++) {
 | 
|      ObjectLiteral::Property* property = properties.at(i);
 | 
| -    if (!IsBoilerplateProperty(property)) continue;
 | 
| +    if (!IsBoilerplateProperty(property)) {
 | 
| +      is_simple = false;
 | 
| +      continue;
 | 
| +    }
 | 
| +    MaterializedLiteral* m_literal = property->value()->AsMaterializedLiteral();
 | 
| +    if (m_literal != NULL && m_literal->depth() + 1 > depth) {
 | 
| +      depth = m_literal->depth() + 1;
 | 
| +    }
 | 
|  
 | 
|      // 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();
 | 
| -    Literal* literal = GetBoilerplateValue(property);
 | 
| +    Handle<Object> value = GetBoilerplateValue(property->value());
 | 
| +    is_simple = is_simple && !value->IsUndefined();
 | 
|  
 | 
|      // Add name, value pair to the fixed array.
 | 
|      constant_properties->set(position++, *key);
 | 
| -    constant_properties->set(position++, *literal->handle());
 | 
| +    constant_properties->set(position++, *value);
 | 
|    }
 | 
|  
 | 
|    return new ObjectLiteral(constant_properties,
 | 
|                             properties.elements(),
 | 
| -                           literal_index);
 | 
| +                           literal_index,
 | 
| +                           is_simple,
 | 
| +                           depth);
 | 
|  }
 | 
|  
 | 
|  
 | 
| 
 |