| Index: src/objects.cc
|
| ===================================================================
|
| --- src/objects.cc (revision 7006)
|
| +++ src/objects.cc (working copy)
|
| @@ -1002,6 +1002,9 @@
|
| case SHARED_FUNCTION_INFO_TYPE:
|
| accumulator->Add("<SharedFunctionInfo>");
|
| break;
|
| + case JS_MESSAGE_OBJECT_TYPE:
|
| + accumulator->Add("<JSMessageObject>");
|
| + break;
|
| #define MAKE_STRUCT_CASE(NAME, Name, name) \
|
| case NAME##_TYPE: \
|
| accumulator->Put('<'); \
|
| @@ -1092,6 +1095,7 @@
|
| case JS_GLOBAL_PROXY_TYPE:
|
| case JS_GLOBAL_OBJECT_TYPE:
|
| case JS_BUILTINS_OBJECT_TYPE:
|
| + case JS_MESSAGE_OBJECT_TYPE:
|
| JSObject::BodyDescriptor::IterateBody(this, object_size, v);
|
| break;
|
| case JS_FUNCTION_TYPE:
|
| @@ -1232,6 +1236,8 @@
|
| MaybeObject* JSObject::AddFastProperty(String* name,
|
| Object* value,
|
| PropertyAttributes attributes) {
|
| + ASSERT(!IsJSGlobalProxy());
|
| +
|
| // Normalize the object if the name is an actual string (not the
|
| // hidden symbols) and is not a real identifier.
|
| Isolate* isolate = GetHeap()->isolate();
|
| @@ -1738,8 +1744,9 @@
|
| }
|
|
|
|
|
| -bool JSObject::SetElementWithCallbackSetterInPrototypes(uint32_t index,
|
| - Object* value) {
|
| +MaybeObject* JSObject::SetElementWithCallbackSetterInPrototypes(uint32_t index,
|
| + Object* value,
|
| + bool* found) {
|
| Heap* heap = GetHeap();
|
| for (Object* pt = GetPrototype();
|
| pt != heap->null_value();
|
| @@ -1750,15 +1757,16 @@
|
| NumberDictionary* dictionary = JSObject::cast(pt)->element_dictionary();
|
| int entry = dictionary->FindEntry(index);
|
| if (entry != NumberDictionary::kNotFound) {
|
| - Object* element = dictionary->ValueAt(entry);
|
| PropertyDetails details = dictionary->DetailsAt(entry);
|
| if (details.type() == CALLBACKS) {
|
| - SetElementWithCallback(element, index, value, JSObject::cast(pt));
|
| - return true;
|
| + *found = true;
|
| + return SetElementWithCallback(
|
| + dictionary->ValueAt(entry), index, value, JSObject::cast(pt));
|
| }
|
| }
|
| }
|
| - return false;
|
| + *found = false;
|
| + return heap->the_hole_value();
|
| }
|
|
|
|
|
| @@ -2330,6 +2338,8 @@
|
|
|
| // The global object is always normalized.
|
| ASSERT(!IsGlobalObject());
|
| + // JSGlobalProxy must never be normalized
|
| + ASSERT(!IsJSGlobalProxy());
|
|
|
| Heap* heap = GetHeap();
|
|
|
| @@ -2830,6 +2840,13 @@
|
|
|
|
|
| MaybeObject* JSObject::PreventExtensions() {
|
| + if (IsJSGlobalProxy()) {
|
| + Object* proto = GetPrototype();
|
| + if (proto->IsNull()) return this;
|
| + ASSERT(proto->IsJSGlobalObject());
|
| + return JSObject::cast(proto)->PreventExtensions();
|
| + }
|
| +
|
| // If there are fast elements we normalize.
|
| if (HasFastElements()) {
|
| Object* ok;
|
| @@ -6024,7 +6041,7 @@
|
| Handle<Object> p = it.rinfo()->target_object_handle(origin);
|
| it.rinfo()->set_target_object(*p);
|
| } else if (mode == RelocInfo::GLOBAL_PROPERTY_CELL) {
|
| - Handle<JSGlobalPropertyCell> cell = it.rinfo()->target_cell_handle();
|
| + Handle<JSGlobalPropertyCell> cell = it.rinfo()->target_cell_handle();
|
| it.rinfo()->set_target_cell(*cell);
|
| } else if (RelocInfo::IsCodeTarget(mode)) {
|
| // rewrite code handles in inline cache targets to direct
|
| @@ -6105,7 +6122,7 @@
|
| void Code::SetNoStackCheckTable() {
|
| // Indicate the absence of a stack-check table by a table start after the
|
| // end of the instructions. Table start must be aligned, so round up.
|
| - set_stack_check_table_start(RoundUp(instruction_size(), kIntSize));
|
| + set_stack_check_table_offset(RoundUp(instruction_size(), kIntSize));
|
| }
|
|
|
|
|
| @@ -6382,7 +6399,7 @@
|
| }
|
| PrintF(out, "\n");
|
| } else if (kind() == FUNCTION) {
|
| - unsigned offset = stack_check_table_start();
|
| + unsigned offset = stack_check_table_offset();
|
| // If there is no stack check table, the "table start" will at or after
|
| // (due to alignment) the end of the instruction stream.
|
| if (static_cast<int>(offset) < instruction_size()) {
|
| @@ -6791,6 +6808,13 @@
|
| return UNDEFINED_ELEMENT;
|
| }
|
|
|
| + if (IsJSGlobalProxy()) {
|
| + Object* proto = GetPrototype();
|
| + if (proto->IsNull()) return UNDEFINED_ELEMENT;
|
| + ASSERT(proto->IsJSGlobalObject());
|
| + return JSObject::cast(proto)->HasLocalElement(index);
|
| + }
|
| +
|
| // Check for lookup interceptor
|
| if (HasIndexedInterceptor()) {
|
| return HasElementWithInterceptor(this, index) ? INTERCEPTED_ELEMENT
|
| @@ -7068,9 +7092,11 @@
|
| uint32_t elms_length = static_cast<uint32_t>(elms->length());
|
|
|
| if (check_prototype &&
|
| - (index >= elms_length || elms->get(index)->IsTheHole()) &&
|
| - SetElementWithCallbackSetterInPrototypes(index, value)) {
|
| - return value;
|
| + (index >= elms_length || elms->get(index)->IsTheHole())) {
|
| + bool found;
|
| + MaybeObject* result =
|
| + SetElementWithCallbackSetterInPrototypes(index, value, &found);
|
| + if (found) return result;
|
| }
|
|
|
|
|
| @@ -7204,9 +7230,11 @@
|
| }
|
| } else {
|
| // Index not already used. Look for an accessor in the prototype chain.
|
| - if (check_prototype &&
|
| - SetElementWithCallbackSetterInPrototypes(index, value)) {
|
| - return value;
|
| + if (check_prototype) {
|
| + bool found;
|
| + MaybeObject* result =
|
| + SetElementWithCallbackSetterInPrototypes(index, value, &found);
|
| + if (found) return result;
|
| }
|
| // When we set the is_extensible flag to false we always force
|
| // the element into dictionary mode (and force them to stay there).
|
| @@ -8071,20 +8099,28 @@
|
| // StringSharedKeys are used as keys in the eval cache.
|
| class StringSharedKey : public HashTableKey {
|
| public:
|
| - StringSharedKey(String* source, SharedFunctionInfo* shared)
|
| - : source_(source), shared_(shared) { }
|
| + StringSharedKey(String* source,
|
| + SharedFunctionInfo* shared,
|
| + StrictModeFlag strict_mode)
|
| + : source_(source),
|
| + shared_(shared),
|
| + strict_mode_(strict_mode) { }
|
|
|
| bool IsMatch(Object* other) {
|
| if (!other->IsFixedArray()) return false;
|
| FixedArray* pair = FixedArray::cast(other);
|
| SharedFunctionInfo* shared = SharedFunctionInfo::cast(pair->get(0));
|
| if (shared != shared_) return false;
|
| + StrictModeFlag strict_mode = static_cast<StrictModeFlag>(
|
| + Smi::cast(pair->get(2))->value());
|
| + if (strict_mode != strict_mode_) return false;
|
| String* source = String::cast(pair->get(1));
|
| return source->Equals(source_);
|
| }
|
|
|
| static uint32_t StringSharedHashHelper(String* source,
|
| - SharedFunctionInfo* shared) {
|
| + SharedFunctionInfo* shared,
|
| + StrictModeFlag strict_mode) {
|
| uint32_t hash = source->Hash();
|
| if (shared->HasSourceCode()) {
|
| // Instead of using the SharedFunctionInfo pointer in the hash
|
| @@ -8094,36 +8130,41 @@
|
| // collection.
|
| Script* script = Script::cast(shared->script());
|
| hash ^= String::cast(script->source())->Hash();
|
| + if (strict_mode == kStrictMode) hash ^= 0x8000;
|
| hash += shared->start_position();
|
| }
|
| return hash;
|
| }
|
|
|
| uint32_t Hash() {
|
| - return StringSharedHashHelper(source_, shared_);
|
| + return StringSharedHashHelper(source_, shared_, strict_mode_);
|
| }
|
|
|
| uint32_t HashForObject(Object* obj) {
|
| FixedArray* pair = FixedArray::cast(obj);
|
| SharedFunctionInfo* shared = SharedFunctionInfo::cast(pair->get(0));
|
| String* source = String::cast(pair->get(1));
|
| - return StringSharedHashHelper(source, shared);
|
| + StrictModeFlag strict_mode = static_cast<StrictModeFlag>(
|
| + Smi::cast(pair->get(2))->value());
|
| + return StringSharedHashHelper(source, shared, strict_mode);
|
| }
|
|
|
| MUST_USE_RESULT MaybeObject* AsObject() {
|
| Object* obj;
|
| - { MaybeObject* maybe_obj = source_->GetHeap()->AllocateFixedArray(2);
|
| + { MaybeObject* maybe_obj = source_->GetHeap()->AllocateFixedArray(3);
|
| if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
| }
|
| FixedArray* pair = FixedArray::cast(obj);
|
| pair->set(0, shared_);
|
| pair->set(1, source_);
|
| + pair->set(2, Smi::FromInt(strict_mode_));
|
| return pair;
|
| }
|
|
|
| private:
|
| String* source_;
|
| SharedFunctionInfo* shared_;
|
| + StrictModeFlag strict_mode_;
|
| };
|
|
|
|
|
| @@ -9076,8 +9117,10 @@
|
| }
|
|
|
|
|
| -Object* CompilationCacheTable::LookupEval(String* src, Context* context) {
|
| - StringSharedKey key(src, context->closure()->shared());
|
| +Object* CompilationCacheTable::LookupEval(String* src,
|
| + Context* context,
|
| + StrictModeFlag strict_mode) {
|
| + StringSharedKey key(src, context->closure()->shared(), strict_mode);
|
| int entry = FindEntry(&key);
|
| if (entry == kNotFound) return GetHeap()->undefined_value();
|
| return get(EntryToIndex(entry) + 1);
|
| @@ -9113,8 +9156,10 @@
|
|
|
| MaybeObject* CompilationCacheTable::PutEval(String* src,
|
| Context* context,
|
| - Object* value) {
|
| - StringSharedKey key(src, context->closure()->shared());
|
| + SharedFunctionInfo* value) {
|
| + StringSharedKey key(src,
|
| + context->closure()->shared(),
|
| + value->strict_mode() ? kStrictMode : kNonStrictMode);
|
| Object* obj;
|
| { MaybeObject* maybe_obj = EnsureCapacity(1, &key);
|
| if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
|
|