Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(699)

Unified Diff: src/runtime.cc

Issue 48006: Reapply revisions 1432, 1433, 1469 and 1472 while fixing issue 279. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/runtime.cc
===================================================================
--- src/runtime.cc (revision 1544)
+++ src/runtime.cc (working copy)
@@ -44,6 +44,7 @@
#include "scopeinfo.h"
#include "v8threads.h"
#include "smart-pointer.h"
+#include "parser.h"
namespace v8 { namespace internal {
@@ -70,6 +71,13 @@
RUNTIME_ASSERT(obj->IsBoolean()); \
bool name = (obj)->IsTrue();
+// Cast the given object to a Smi and store its value in an int variable
+// with the given name. If the object is not a Smi call IllegalOperation
+// and return.
+#define CONVERT_SMI_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.
@@ -93,8 +101,103 @@
}
-static Object* Runtime_CloneObjectLiteralBoilerplate(Arguments args) {
+static Object* DeepCopyBoilerplate(JSObject* boilerplate) {
+ StackLimitCheck check;
+ if (check.HasOverflowed()) return Top::StackOverflow();
+
+ Object* result = Heap::CopyJSObject(boilerplate);
+ if (result->IsFailure()) return result;
+ JSObject* copy = JSObject::cast(result);
+
+ // Deep copy local properties.
+ if (copy->HasFastProperties()) {
+ FixedArray* properties = copy->properties();
+ WriteBarrierMode mode = properties->GetWriteBarrierMode();
+ for (int i = 0; i < properties->length(); i++) {
+ Object* value = properties->get(i);
+ if (value->IsJSObject()) {
+ JSObject* jsObject = JSObject::cast(value);
+ result = DeepCopyBoilerplate(jsObject);
+ if (result->IsFailure()) return result;
+ properties->set(i, result, mode);
+ }
+ }
+ mode = copy->GetWriteBarrierMode();
+ for (int i = 0; i < copy->map()->inobject_properties(); i++) {
+ Object* value = copy->InObjectPropertyAt(i);
+ if (value->IsJSObject()) {
+ JSObject* jsObject = JSObject::cast(value);
+ result = DeepCopyBoilerplate(jsObject);
+ if (result->IsFailure()) return result;
+ copy->InObjectPropertyAtPut(i, result, mode);
+ }
+ }
+ } else {
+ result = Heap::AllocateFixedArray(copy->NumberOfLocalProperties(NONE));
+ if (result->IsFailure()) return result;
+ FixedArray* names = FixedArray::cast(result);
+ copy->GetLocalPropertyNames(names, 0);
+ for (int i = 0; i < names->length(); i++) {
+ ASSERT(names->get(i)->IsString());
+ String* keyString = String::cast(names->get(i));
+ PropertyAttributes attributes = copy->GetLocalPropertyAttribute(keyString);
+ // Only deep copy fields from the object literal expression.
+ // In particular, don't try to copy the length attribute of
+ // an array.
+ if (attributes != NONE) continue;
+ Object* value = copy->GetProperty(keyString, &attributes);
+ ASSERT(!value->IsFailure());
+ if (value->IsJSObject()) {
+ JSObject* jsObject = JSObject::cast(value);
+ result = DeepCopyBoilerplate(jsObject);
+ if (result->IsFailure()) return result;
+ result = copy->SetProperty(keyString, result, NONE);
+ if (result->IsFailure()) return result;
+ }
+ }
+ }
+
+ // Deep copy local elements.
+ if (copy->HasFastElements()) {
+ FixedArray* elements = copy->elements();
+ WriteBarrierMode mode = elements->GetWriteBarrierMode();
+ for (int i = 0; i < elements->length(); i++) {
+ Object* value = elements->get(i);
+ if (value->IsJSObject()) {
+ JSObject* jsObject = JSObject::cast(value);
+ result = DeepCopyBoilerplate(jsObject);
+ if (result->IsFailure()) return result;
+ elements->set(i, result, mode);
+ }
+ }
+ } else {
+ Dictionary* element_dictionary = copy->element_dictionary();
+ int capacity = element_dictionary->Capacity();
+ for (int i = 0; i < capacity; i++) {
+ Object* k = element_dictionary->KeyAt(i);
+ if (element_dictionary->IsKey(k)) {
+ Object* value = element_dictionary->ValueAt(i);
+ if (value->IsJSObject()) {
+ JSObject* jsObject = JSObject::cast(value);
+ result = DeepCopyBoilerplate(jsObject);
+ if (result->IsFailure()) return result;
+ element_dictionary->ValueAtPut(i, result);
+ }
+ }
+ }
+ }
+ return copy;
+}
+
+
+static Object* Runtime_CloneLiteralBoilerplate(Arguments args) {
CONVERT_CHECKED(JSObject, boilerplate, args[0]);
+ return DeepCopyBoilerplate(boilerplate);
+}
+
+
+static Object* Runtime_CloneShallowLiteralBoilerplate(Arguments args) {
+ CONVERT_CHECKED(JSObject, boilerplate, args[0]);
return Heap::CopyJSObject(boilerplate);
}
@@ -132,14 +235,14 @@
}
-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> CreateLiteralBoilerplate(
+ Handle<FixedArray> literals,
+ Handle<FixedArray> constant_properties);
+
+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
@@ -162,6 +265,13 @@
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()) {
@@ -186,39 +296,97 @@
// 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 Failure::Exception();
+ if (result.is_null()) return result;
}
}
+ 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_SMI_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, *boilerplate);
+ literals->set(literals_index, *result);
- return *boilerplate;
+ return *result;
}
-static Object* Runtime_CreateArrayLiteral(Arguments args) {
+static Object* Runtime_CreateArrayLiteralBoilerplate(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.
- 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;
+ HandleScope scope;
+ ASSERT(args.length() == 3);
+ CONVERT_ARG_CHECKED(FixedArray, literals, 0);
+ CONVERT_SMI_CHECKED(literals_index, args[1]);
+ CONVERT_ARG_CHECKED(FixedArray, elements, 2);
- // Copy the elements.
- Object* content = elements->Copy();
- if (content->IsFailure()) return content;
+ Handle<Object> object = CreateArrayLiteralBoilerplate(literals, elements);
+ if (object.is_null()) return Failure::Exception();
- // Set the elements.
- JSArray::cast(object)->SetContent(FixedArray::cast(content));
- return object;
+ // Update the functions literal and return the boilerplate.
+ literals->set(literals_index, *object);
+ return *object;
}
« src/objects.h ('K') | « src/runtime.h ('k') | test/mjsunit/fuzz-natives.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698