Commit 1979ab55 authored by Camillo Bruni's avatar Camillo Bruni Committed by Commit Bot

[heap-verification] Increase verification for arguments objects

BUG: v8/6251
Change-Id: I64e6ad220f05384e4cd549c1356fd713423c3044
Reviewed-on: https://chromium-review.googlesource.com/480072Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Commit-Queue: Camillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#44695}
parent 38be4a17
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "src/bootstrapper.h" #include "src/bootstrapper.h"
#include "src/disasm.h" #include "src/disasm.h"
#include "src/disassembler.h" #include "src/disassembler.h"
#include "src/elements.h"
#include "src/field-type.h" #include "src/field-type.h"
#include "src/layout-descriptor.h" #include "src/layout-descriptor.h"
#include "src/macro-assembler.h" #include "src/macro-assembler.h"
...@@ -105,12 +106,14 @@ void HeapObject::HeapObjectVerify() { ...@@ -105,12 +106,14 @@ void HeapObject::HeapObjectVerify() {
break; break;
case JS_OBJECT_TYPE: case JS_OBJECT_TYPE:
case JS_ERROR_TYPE: case JS_ERROR_TYPE:
case JS_ARGUMENTS_TYPE:
case JS_API_OBJECT_TYPE: case JS_API_OBJECT_TYPE:
case JS_SPECIAL_API_OBJECT_TYPE: case JS_SPECIAL_API_OBJECT_TYPE:
case JS_CONTEXT_EXTENSION_OBJECT_TYPE: case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
JSObject::cast(this)->JSObjectVerify(); JSObject::cast(this)->JSObjectVerify();
break; break;
case JS_ARGUMENTS_TYPE:
JSArgumentsObject::cast(this)->JSArgumentsObjectVerify();
break;
case JS_GENERATOR_OBJECT_TYPE: case JS_GENERATOR_OBJECT_TYPE:
JSGeneratorObject::cast(this)->JSGeneratorObjectVerify(); JSGeneratorObject::cast(this)->JSGeneratorObjectVerify();
break; break;
...@@ -162,6 +165,7 @@ void HeapObject::HeapObjectVerify() { ...@@ -162,6 +165,7 @@ void HeapObject::HeapObjectVerify() {
case JS_MAP_ITERATOR_TYPE: case JS_MAP_ITERATOR_TYPE:
JSMapIterator::cast(this)->JSMapIteratorVerify(); JSMapIterator::cast(this)->JSMapIteratorVerify();
break; break;
case JS_TYPED_ARRAY_KEY_ITERATOR_TYPE: case JS_TYPED_ARRAY_KEY_ITERATOR_TYPE:
case JS_FAST_ARRAY_KEY_ITERATOR_TYPE: case JS_FAST_ARRAY_KEY_ITERATOR_TYPE:
case JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE: case JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE:
...@@ -326,11 +330,7 @@ void JSObject::JSObjectVerify() { ...@@ -326,11 +330,7 @@ void JSObject::JSObjectVerify() {
VerifyHeapPointer(properties()); VerifyHeapPointer(properties());
VerifyHeapPointer(elements()); VerifyHeapPointer(elements());
if (HasSloppyArgumentsElements()) { CHECK_IMPLIES(HasSloppyArgumentsElements(), IsJSArgumentsObject());
CHECK(this->elements()->IsFixedArray());
CHECK_GE(this->elements()->length(), 2);
}
if (HasFastProperties()) { if (HasFastProperties()) {
int actual_unused_property_fields = map()->GetInObjectProperties() + int actual_unused_property_fields = map()->GetInObjectProperties() +
properties()->length() - properties()->length() -
...@@ -467,6 +467,70 @@ void TransitionArray::TransitionArrayVerify() { ...@@ -467,6 +467,70 @@ void TransitionArray::TransitionArrayVerify() {
next_link()->IsTransitionArray()); next_link()->IsTransitionArray());
} }
void JSArgumentsObject::JSArgumentsObjectVerify() {
if (IsSloppyArgumentsElementsKind(GetElementsKind())) {
JSSloppyArgumentsObject::cast(this)->JSSloppyArgumentsObjectVerify();
}
JSObjectVerify();
}
void JSSloppyArgumentsObject::JSSloppyArgumentsObjectVerify() {
Isolate* isolate = GetIsolate();
if (isolate->IsInAnyContext(map(), Context::SLOPPY_ARGUMENTS_MAP_INDEX) ||
isolate->IsInAnyContext(map(),
Context::SLOW_ALIASED_ARGUMENTS_MAP_INDEX) ||
isolate->IsInAnyContext(map(),
Context::FAST_ALIASED_ARGUMENTS_MAP_INDEX)) {
// We can only verify the in-object fields for the original maps.
VerifyObjectField(kLengthOffset);
VerifyObjectField(kCalleeOffset);
}
ElementsKind kind = GetElementsKind();
CHECK(IsSloppyArgumentsElementsKind(kind));
SloppyArgumentsElements::cast(elements())
->SloppyArgumentsElementsVerify(this);
}
void SloppyArgumentsElements::SloppyArgumentsElementsVerify(
JSSloppyArgumentsObject* holder) {
Isolate* isolate = GetIsolate();
FixedArrayVerify();
// Abort verification if only partially initialized.
if (arguments()->IsUndefined(isolate)) return;
ElementsKind kind = holder->GetElementsKind();
CHECK(IsFixedArray());
CHECK_GE(length(), 2);
CHECK_EQ(map(), isolate->heap()->sloppy_arguments_elements_map());
Context* context_object = Context::cast(context());
FixedArray* arg_elements = FixedArray::cast(arguments());
if (arg_elements->length() == 0) {
CHECK(arg_elements == isolate->heap()->empty_fixed_array());
return;
}
int nofMappedParameters =
length() - SloppyArgumentsElements::kParameterMapStart;
CHECK_LE(nofMappedParameters, context_object->length());
CHECK_LE(nofMappedParameters, arg_elements->length());
ElementsAccessor* accessor;
if (kind == FAST_SLOPPY_ARGUMENTS_ELEMENTS) {
accessor = ElementsAccessor::ForKind(FAST_HOLEY_ELEMENTS);
} else {
accessor = ElementsAccessor::ForKind(DICTIONARY_ELEMENTS);
}
for (int i = 0; i < nofMappedParameters; i++) {
// Verify that each context-mapped argument is either the hole or a valid
// Smi within context length range.
Object* mapped = get_mapped_entry(i);
if (mapped->IsTheHole(isolate)) continue;
Object* value = context_object->get(Smi::cast(mapped)->value());
CHECK(value->IsObject());
// None of the context-mapped entries should exist in the arguments
// elements unless they have been deleted and readded, which would leave
// the_hole in the parameter map.
CHECK(!accessor->HasElement(holder, i, arg_elements));
}
}
void JSGeneratorObject::JSGeneratorObjectVerify() { void JSGeneratorObject::JSGeneratorObjectVerify() {
// In an expression like "new g()", there can be a point where a generator // In an expression like "new g()", there can be a point where a generator
......
...@@ -207,6 +207,10 @@ bool HeapObject::IsFixedArray() const { ...@@ -207,6 +207,10 @@ bool HeapObject::IsFixedArray() const {
bool HeapObject::IsSloppyArgumentsElements() const { return IsFixedArray(); } bool HeapObject::IsSloppyArgumentsElements() const { return IsFixedArray(); }
bool HeapObject::IsJSSloppyArgumentsObject() const {
return IsJSArgumentsObject();
}
bool HeapObject::IsJSGeneratorObject() const { bool HeapObject::IsJSGeneratorObject() const {
return map()->instance_type() == JS_GENERATOR_OBJECT_TYPE || return map()->instance_type() == JS_GENERATOR_OBJECT_TYPE ||
IsJSAsyncGeneratorObject(); IsJSAsyncGeneratorObject();
...@@ -640,6 +644,7 @@ CAST_ACCESSOR(Foreign) ...@@ -640,6 +644,7 @@ CAST_ACCESSOR(Foreign)
CAST_ACCESSOR(GlobalDictionary) CAST_ACCESSOR(GlobalDictionary)
CAST_ACCESSOR(HandlerTable) CAST_ACCESSOR(HandlerTable)
CAST_ACCESSOR(HeapObject) CAST_ACCESSOR(HeapObject)
CAST_ACCESSOR(JSArgumentsObject);
CAST_ACCESSOR(JSArray) CAST_ACCESSOR(JSArray)
CAST_ACCESSOR(JSArrayBuffer) CAST_ACCESSOR(JSArrayBuffer)
CAST_ACCESSOR(JSArrayBufferView) CAST_ACCESSOR(JSArrayBufferView)
...@@ -663,6 +668,7 @@ CAST_ACCESSOR(JSPromiseCapability) ...@@ -663,6 +668,7 @@ CAST_ACCESSOR(JSPromiseCapability)
CAST_ACCESSOR(JSPromise) CAST_ACCESSOR(JSPromise)
CAST_ACCESSOR(JSSet) CAST_ACCESSOR(JSSet)
CAST_ACCESSOR(JSSetIterator) CAST_ACCESSOR(JSSetIterator)
CAST_ACCESSOR(JSSloppyArgumentsObject)
CAST_ACCESSOR(JSAsyncFromSyncIterator) CAST_ACCESSOR(JSAsyncFromSyncIterator)
CAST_ACCESSOR(JSStringIterator) CAST_ACCESSOR(JSStringIterator)
CAST_ACCESSOR(JSArrayIterator) CAST_ACCESSOR(JSArrayIterator)
...@@ -5510,6 +5516,9 @@ void Map::SetBackPointer(Object* value, WriteBarrierMode mode) { ...@@ -5510,6 +5516,9 @@ void Map::SetBackPointer(Object* value, WriteBarrierMode mode) {
set_constructor_or_backpointer(value, mode); set_constructor_or_backpointer(value, mode);
} }
ACCESSORS(JSArgumentsObject, length, Object, kLengthOffset);
ACCESSORS(JSSloppyArgumentsObject, callee, Object, kCalleeOffset);
ACCESSORS(Map, code_cache, FixedArray, kCodeCacheOffset) ACCESSORS(Map, code_cache, FixedArray, kCodeCacheOffset)
ACCESSORS(Map, dependent_code, DependentCode, kDependentCodeOffset) ACCESSORS(Map, dependent_code, DependentCode, kDependentCodeOffset)
ACCESSORS(Map, weak_cell_cache, Object, kWeakCellCacheOffset) ACCESSORS(Map, weak_cell_cache, Object, kWeakCellCacheOffset)
......
...@@ -145,7 +145,6 @@ ...@@ -145,7 +145,6 @@
// - DebugInfo // - DebugInfo
// - BreakPointInfo // - BreakPointInfo
// - StackFrameInfo // - StackFrameInfo
// - SourcePositionTableWithFrameCache
// - CodeCache // - CodeCache
// - PrototypeInfo // - PrototypeInfo
// - Module // - Module
...@@ -713,8 +712,8 @@ enum InstanceType { ...@@ -713,8 +712,8 @@ enum InstanceType {
WEAK_CELL_TYPE, WEAK_CELL_TYPE,
PROPERTY_CELL_TYPE, PROPERTY_CELL_TYPE,
// TODO(yangguo): these padding types are for ABI stability. Remove after // All the following types are subtypes of JSReceiver, which corresponds to
// version 6.0 branch, or replace them when there is demand for new types. // objects in the JS sense. The first and the last type in this range are
PADDING_TYPE_1, PADDING_TYPE_1,
PADDING_TYPE_2, PADDING_TYPE_2,
PADDING_TYPE_3, PADDING_TYPE_3,
...@@ -1060,6 +1059,7 @@ template <class C> inline bool Is(Object* obj); ...@@ -1060,6 +1059,7 @@ template <class C> inline bool Is(Object* obj);
V(JSRegExp) \ V(JSRegExp) \
V(JSSet) \ V(JSSet) \
V(JSSetIterator) \ V(JSSetIterator) \
V(JSSloppyArgumentsObject) \
V(JSStringIterator) \ V(JSStringIterator) \
V(JSTypedArray) \ V(JSTypedArray) \
V(JSValue) \ V(JSValue) \
...@@ -2688,6 +2688,11 @@ class JSArgumentsObject: public JSObject { ...@@ -2688,6 +2688,11 @@ class JSArgumentsObject: public JSObject {
// Indices of in-object properties. // Indices of in-object properties.
static const int kLengthIndex = 0; static const int kLengthIndex = 0;
DECL_ACCESSORS(length, Object)
DECLARE_VERIFIER(JSArgumentsObject)
DECLARE_CAST(JSArgumentsObject)
private: private:
DISALLOW_IMPLICIT_CONSTRUCTORS(JSArgumentsObject); DISALLOW_IMPLICIT_CONSTRUCTORS(JSArgumentsObject);
}; };
...@@ -2703,6 +2708,11 @@ class JSSloppyArgumentsObject: public JSArgumentsObject { ...@@ -2703,6 +2708,11 @@ class JSSloppyArgumentsObject: public JSArgumentsObject {
// Indices of in-object properties. // Indices of in-object properties.
static const int kCalleeIndex = 1; static const int kCalleeIndex = 1;
DECL_ACCESSORS(callee, Object)
DECLARE_VERIFIER(JSSloppyArgumentsObject)
DECLARE_CAST(JSSloppyArgumentsObject)
private: private:
DISALLOW_IMPLICIT_CONSTRUCTORS(JSSloppyArgumentsObject); DISALLOW_IMPLICIT_CONSTRUCTORS(JSSloppyArgumentsObject);
}; };
...@@ -2715,6 +2725,8 @@ class JSStrictArgumentsObject: public JSArgumentsObject { ...@@ -2715,6 +2725,8 @@ class JSStrictArgumentsObject: public JSArgumentsObject {
// Offsets of object fields. // Offsets of object fields.
static const int kSize = JSArgumentsObject::kHeaderSize; static const int kSize = JSArgumentsObject::kHeaderSize;
DECLARE_CAST(JSStrictArgumentsObject)
private: private:
DISALLOW_IMPLICIT_CONSTRUCTORS(JSStrictArgumentsObject); DISALLOW_IMPLICIT_CONSTRUCTORS(JSStrictArgumentsObject);
}; };
...@@ -2906,6 +2918,7 @@ class FixedDoubleArray: public FixedArrayBase { ...@@ -2906,6 +2918,7 @@ class FixedDoubleArray: public FixedArrayBase {
// JSArgumentsObject: // JSArgumentsObject:
// - FAST_SLOPPY_ARGUMENTS_ELEMENTS: FAST_HOLEY_ELEMENTS // - FAST_SLOPPY_ARGUMENTS_ELEMENTS: FAST_HOLEY_ELEMENTS
// - SLOW_SLOPPY_ARGUMENTS_ELEMENTS: DICTIONARY_ELEMENTS // - SLOW_SLOPPY_ARGUMENTS_ELEMENTS: DICTIONARY_ELEMENTS
// - SLOW_SLOPPY_ARGUMENTS_ELEMENTS: DICTIONARY_ELEMENTS
class SloppyArgumentsElements : public FixedArray { class SloppyArgumentsElements : public FixedArray {
public: public:
static const int kContextIndex = 0; static const int kContextIndex = 0;
...@@ -2920,6 +2933,9 @@ class SloppyArgumentsElements : public FixedArray { ...@@ -2920,6 +2933,9 @@ class SloppyArgumentsElements : public FixedArray {
inline void set_mapped_entry(uint32_t entry, Object* object); inline void set_mapped_entry(uint32_t entry, Object* object);
DECLARE_CAST(SloppyArgumentsElements) DECLARE_CAST(SloppyArgumentsElements)
#ifdef VERIFY_HEAP
void SloppyArgumentsElementsVerify(JSSloppyArgumentsObject* holder);
#endif
private: private:
DISALLOW_IMPLICIT_CONSTRUCTORS(SloppyArgumentsElements); DISALLOW_IMPLICIT_CONSTRUCTORS(SloppyArgumentsElements);
...@@ -3300,7 +3316,7 @@ class BytecodeArray : public FixedArrayBase { ...@@ -3300,7 +3316,7 @@ class BytecodeArray : public FixedArrayBase {
DECL_ACCESSORS(handler_table, FixedArray) DECL_ACCESSORS(handler_table, FixedArray)
// Accessors for source position table containing mappings between byte code // Accessors for source position table containing mappings between byte code
// offset and source position or SourcePositionTableWithFrameCache. // offset and source position.
DECL_ACCESSORS(source_position_table, Object) DECL_ACCESSORS(source_position_table, Object)
inline ByteArray* SourcePositionTable(); inline ByteArray* SourcePositionTable();
...@@ -3715,7 +3731,7 @@ class Code: public HeapObject { ...@@ -3715,7 +3731,7 @@ class Code: public HeapObject {
// [deoptimization_data]: Array containing data for deopt. // [deoptimization_data]: Array containing data for deopt.
DECL_ACCESSORS(deoptimization_data, FixedArray) DECL_ACCESSORS(deoptimization_data, FixedArray)
// [source_position_table]: ByteArray for the source positions table or // [source_position_table]: ByteArray for the source positions table.
// SourcePositionTableWithFrameCache. // SourcePositionTableWithFrameCache.
DECL_ACCESSORS(source_position_table, Object) DECL_ACCESSORS(source_position_table, Object)
...@@ -3879,8 +3895,8 @@ class Code: public HeapObject { ...@@ -3879,8 +3895,8 @@ class Code: public HeapObject {
inline bool marked_for_deoptimization(); inline bool marked_for_deoptimization();
inline void set_marked_for_deoptimization(bool flag); inline void set_marked_for_deoptimization(bool flag);
// [deopt_already_counted]: For kind OPTIMIZED_FUNCTION tells whether // [is_promise_rejection]: For kind BUILTIN tells whether the exception
// the code was already deoptimized. // thrown by the code will lead to promise rejection.
inline bool deopt_already_counted(); inline bool deopt_already_counted();
inline void set_deopt_already_counted(bool flag); inline void set_deopt_already_counted(bool flag);
...@@ -5887,7 +5903,7 @@ class SharedFunctionInfo: public HeapObject { ...@@ -5887,7 +5903,7 @@ class SharedFunctionInfo: public HeapObject {
inline bool is_compiled() const; inline bool is_compiled() const;
// [length]: The function length - usually the number of declared parameters. // [length]: The function length - usually the number of declared parameters.
// Use up to 2^30 parameters. The value is only reliable when the function has // Use up to 2^30 parameters.
// been compiled. // been compiled.
inline int GetLength() const; inline int GetLength() const;
inline bool HasLength() const; inline bool HasLength() const;
......
...@@ -2,17 +2,23 @@ ...@@ -2,17 +2,23 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// Flags: --allow-natives-syntax
function f(a, b, c, d) { return arguments; } function f(a, b, c, d) { return arguments; }
// Ensure non-configurable argument elements stay non-configurable. // Ensure non-configurable argument elements stay non-configurable.
(function () { (function () {
var args = f(1); var args = f(1);
Object.defineProperty(args, "0", {value: 10, configurable: false}); Object.defineProperty(args, "0", {value: 10, configurable: false});
%HeapObjectVerify(args);
assertFalse(Object.getOwnPropertyDescriptor(args, "0").configurable); assertFalse(Object.getOwnPropertyDescriptor(args, "0").configurable);
%HeapObjectVerify(args);
for (var i = 0; i < 10; i++) { for (var i = 0; i < 10; i++) {
args[i] = 1; args[i] = 1;
} }
%HeapObjectVerify(args);
assertFalse(Object.getOwnPropertyDescriptor(args, "0").configurable); assertFalse(Object.getOwnPropertyDescriptor(args, "0").configurable);
%HeapObjectVerify(args);
})(); })();
// Ensure read-only properties on the prototype chain cause TypeError. // Ensure read-only properties on the prototype chain cause TypeError.
...@@ -27,7 +33,11 @@ function f(a, b, c, d) { return arguments; } ...@@ -27,7 +33,11 @@ function f(a, b, c, d) { return arguments; }
for (var i = 0; i < index; i++) { for (var i = 0; i < index; i++) {
store(o, i, 0); store(o, i, 0);
} }
%HeapObjectVerify(proto);
%HeapObjectVerify(o);
Object.defineProperty(proto, index, {value: 100, writable: false}); Object.defineProperty(proto, index, {value: 100, writable: false});
%HeapObjectVerify(proto);
%HeapObjectVerify(o);
assertThrows(function() { store(o, index, 0); }); assertThrows(function() { store(o, index, 0); });
assertEquals(100, o[index]); assertEquals(100, o[index]);
})(); })();
...@@ -42,7 +52,11 @@ function f(a, b, c, d) { return arguments; } ...@@ -42,7 +52,11 @@ function f(a, b, c, d) { return arguments; }
for (var i = 0; i < index; i++) { for (var i = 0; i < index; i++) {
store(o, i, 0); store(o, i, 0);
} }
%HeapObjectVerify(proto);
%HeapObjectVerify(o);
Object.defineProperty(proto, index, {value: 100, writable: false}); Object.defineProperty(proto, index, {value: 100, writable: false});
%HeapObjectVerify(proto);
%HeapObjectVerify(o);
assertThrows(function() { store(o, index, 0); }); assertThrows(function() { store(o, index, 0); });
assertEquals(100, o[index]); assertEquals(100, o[index]);
})(); })();
...@@ -57,7 +71,11 @@ function f(a, b, c, d) { return arguments; } ...@@ -57,7 +71,11 @@ function f(a, b, c, d) { return arguments; }
for (var i = 0; i < index; i++) { for (var i = 0; i < index; i++) {
store(o, i, 0); store(o, i, 0);
} }
%HeapObjectVerify(proto);
%HeapObjectVerify(o);
Object.defineProperty(proto, index, {value: 100, writable: false}); Object.defineProperty(proto, index, {value: 100, writable: false});
%HeapObjectVerify(proto);
%HeapObjectVerify(o);
assertThrows(function() { store(o, index, 0); }); assertThrows(function() { store(o, index, 0); });
assertEquals(100, o[index]); assertEquals(100, o[index]);
})(); })();
...@@ -72,7 +90,11 @@ function f(a, b, c, d) { return arguments; } ...@@ -72,7 +90,11 @@ function f(a, b, c, d) { return arguments; }
for (var i = 0; i < index; i++) { for (var i = 0; i < index; i++) {
store(o, i, 0); store(o, i, 0);
} }
%HeapObjectVerify(proto);
%HeapObjectVerify(o);
Object.defineProperty(proto, index, {value: 100, writable: false}); Object.defineProperty(proto, index, {value: 100, writable: false});
%HeapObjectVerify(proto);
%HeapObjectVerify(o);
assertThrows(function() { store(o, index, 0); }); assertThrows(function() { store(o, index, 0); });
assertEquals(100, o[index]); assertEquals(100, o[index]);
})(); })();
...@@ -87,12 +109,17 @@ function f(a, b, c, d) { return arguments; } ...@@ -87,12 +109,17 @@ function f(a, b, c, d) { return arguments; }
for (var i = 0; i < index; i++) { for (var i = 0; i < index; i++) {
store(o, i, 0); store(o, i, 0);
} }
%HeapObjectVerify(proto);
%HeapObjectVerify(o);
Object.preventExtensions(proto); Object.preventExtensions(proto);
%HeapObjectVerify(proto);
%HeapObjectVerify(o);
Object.defineProperty(proto, index, {value: 100, writable: false}); Object.defineProperty(proto, index, {value: 100, writable: false});
%HeapObjectVerify(proto);
%HeapObjectVerify(o);
assertThrows(function() { store(o, index, 0); }); assertThrows(function() { store(o, index, 0); });
assertEquals(100, o[index]); assertEquals(100, o[index]);
})(); })();
// Extensions prevented arguments object. // Extensions prevented arguments object.
(function () { (function () {
var o = []; var o = [];
...@@ -103,8 +130,14 @@ function f(a, b, c, d) { return arguments; } ...@@ -103,8 +130,14 @@ function f(a, b, c, d) { return arguments; }
for (var i = 0; i < index; i++) { for (var i = 0; i < index; i++) {
store(o, i, 0); store(o, i, 0);
} }
%HeapObjectVerify(proto);
%HeapObjectVerify(o);
Object.preventExtensions(proto); Object.preventExtensions(proto);
%HeapObjectVerify(proto);
%HeapObjectVerify(o);
Object.defineProperty(proto, index, {value: 100, writable: false}); Object.defineProperty(proto, index, {value: 100, writable: false});
%HeapObjectVerify(proto);
%HeapObjectVerify(o);
assertThrows(function() { store(o, index, 0); }); assertThrows(function() { store(o, index, 0); });
assertEquals(100, o[index]); assertEquals(100, o[index]);
})(); })();
...@@ -120,7 +153,11 @@ function f(a, b, c, d) { return arguments; } ...@@ -120,7 +153,11 @@ function f(a, b, c, d) { return arguments; }
store(o, i, 0); store(o, i, 0);
} }
proto[1 << 30] = 1; proto[1 << 30] = 1;
%HeapObjectVerify(proto);
%HeapObjectVerify(o);
Object.defineProperty(proto, index, {value: 100, writable: false}); Object.defineProperty(proto, index, {value: 100, writable: false});
%HeapObjectVerify(proto);
%HeapObjectVerify(o);
assertThrows(function() { store(o, index, 0); }); assertThrows(function() { store(o, index, 0); });
assertEquals(100, o[index]); assertEquals(100, o[index]);
})(); })();
...@@ -134,7 +171,11 @@ function f(a, b, c, d) { return arguments; } ...@@ -134,7 +171,11 @@ function f(a, b, c, d) { return arguments; }
for (var i = 0; i < 3; i++) { for (var i = 0; i < 3; i++) {
store(o, i, 0); store(o, i, 0);
} }
%HeapObjectVerify(proto);
%HeapObjectVerify(o);
Object.freeze(proto); Object.freeze(proto);
%HeapObjectVerify(proto);
%HeapObjectVerify(o);
assertThrows(function() { store(o, 3, 0); }); assertThrows(function() { store(o, 3, 0); });
assertEquals(3, o[3]); assertEquals(3, o[3]);
})(); })();
...@@ -148,7 +189,11 @@ function f(a, b, c, d) { return arguments; } ...@@ -148,7 +189,11 @@ function f(a, b, c, d) { return arguments; }
for (var i = 0; i < 3; i++) { for (var i = 0; i < 3; i++) {
store(o, i, 0); store(o, i, 0);
} }
%HeapObjectVerify(proto);
%HeapObjectVerify(o);
Object.freeze(proto); Object.freeze(proto);
%HeapObjectVerify(proto);
%HeapObjectVerify(o);
assertThrows(function() { store(o, 3, 0); }); assertThrows(function() { store(o, 3, 0); });
assertEquals(3, o[3]); assertEquals(3, o[3]);
})(); })();
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment