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
-~----------~----~----~----~------~----~------~--~---