native_context()->set_object_function(*object_fun);
// Allocate a new prototype for the object function.
- Handle<JSObject> prototype = factory->NewJSObject(
- isolate->object_function(),
- TENURED);
+ Handle<Map> object_prototype_map =
+ factory->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
+ Handle<DescriptorArray> prototype_descriptors(
+ factory->NewDescriptorArray(0, 1));
+ DescriptorArray::WhitenessWitness witness(*prototype_descriptors);
+ Handle<Foreign> object_prototype(
+ factory->NewForeign(&Accessors::ObjectPrototype));
+ PropertyAttributes attribs = static_cast<PropertyAttributes>(
+ DONT_ENUM | DONT_DELETE);
+ object_prototype_map->set_instance_descriptors(*prototype_descriptors);
+
+ { // Add __proto__.
+ CallbacksDescriptor d(heap->Proto_symbol(), *object_prototype, attribs);
+ object_prototype_map->AppendDescriptor(&d, witness);
+ }
+
+ Handle<JSObject> prototype = factory->NewJSObjectFromMap(
+ object_prototype_map,
+ TENURED);
native_context()->set_initial_object_prototype(*prototype);
SetPrototype(object_fun, prototype);
}
-Handle<JSObject> Factory::NewJSObjectFromMap(Handle<Map> map) {
+Handle<JSObject> Factory::NewJSObjectFromMap(Handle<Map> map,
+ PretenureFlag pretenure) {
CALL_HEAP_FUNCTION(
isolate(),
- isolate()->heap()->AllocateJSObjectFromMap(*map, NOT_TENURED),
+ isolate()->heap()->AllocateJSObjectFromMap(*map, pretenure),
JSObject);
}
// JS objects are pretenured when allocated by the bootstrapper and
// runtime.
- Handle<JSObject> NewJSObjectFromMap(Handle<Map> map);
+ Handle<JSObject> NewJSObjectFromMap(Handle<Map> map,
+ PretenureFlag pretenure = NOT_TENURED);
// JS modules are pretenured.
Handle<JSModule> NewJSModule(Handle<Context> context,
// Parse a JSON object. Position must be right at '{'.
template <bool seq_ascii>
Handle<Object> JsonParser<seq_ascii>::ParseJsonObject() {
- Handle<Object> prototype;
Handle<JSObject> json_object =
factory()->NewJSObject(object_constructor(), pretenure_);
ASSERT_EQ(c0_, '{');
Handle<Object> value = ParseJsonValue();
if (value.is_null()) return ReportUnexpectedCharacter();
- if (key->Equals(isolate()->heap()->Proto_symbol())) {
- prototype = value;
+ if (JSObject::TryTransitionToField(json_object, key)) {
+ int index = json_object->LastAddedFieldIndex();
+ json_object->FastPropertyAtPut(index, *value);
} else {
- if (JSObject::TryTransitionToField(json_object, key)) {
- int index = json_object->LastAddedFieldIndex();
- json_object->FastPropertyAtPut(index, *value);
- } else {
- JSObject::SetLocalPropertyIgnoreAttributes(
- json_object, key, value, NONE);
- }
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ json_object, key, value, NONE);
}
} while (MatchSkipWhiteSpace(','));
if (c0_ != '}') {
return ReportUnexpectedCharacter();
}
- if (!prototype.is_null()) SetPrototype(json_object, prototype);
}
AdvanceSkipWhitespace();
return json_object;
JSObject* js_object = JSObject::cast(this);
- // Check __proto__ before interceptor.
- if (name->Equals(heap->Proto_symbol()) && !IsJSContextExtensionObject()) {
- result->ConstantResult(js_object);
- return;
- }
-
// Check for lookup interceptor except when bootstrapping.
if (js_object->HasNamedInterceptor() &&
!heap->isolate()->bootstrapper()->IsActive()) {
number_ = number;
}
- void ConstantResult(JSObject* holder) {
- lookup_type_ = CONSTANT_TYPE;
- holder_ = holder;
- details_ =
- PropertyDetails(static_cast<PropertyAttributes>(DONT_ENUM |
- DONT_DELETE),
- CALLBACKS);
- number_ = -1;
- }
-
void DictionaryResult(JSObject* holder, int entry) {
lookup_type_ = DICTIONARY_TYPE;
holder_ = holder;
}
Object* GetCallbackObject() {
- if (lookup_type_ == CONSTANT_TYPE) {
- return HEAP->prototype_accessors();
- }
- ASSERT(!IsTransition());
+ ASSERT(type() == CALLBACKS && !IsTransition());
return GetValue();
}
TRANSITION_TYPE,
DICTIONARY_TYPE,
HANDLER_TYPE,
- INTERCEPTOR_TYPE,
- CONSTANT_TYPE
+ INTERCEPTOR_TYPE
} lookup_type_;
JSReceiver* holder_;
Local<v8::Object> top = templ->GetFunction()->NewInstance();
Local<v8::Object> middle = templ->GetFunction()->NewInstance();
- bottom->Set(v8_str("__proto__"), middle);
- middle->Set(v8_str("__proto__"), top);
+ bottom->SetPrototype(middle);
+ middle->SetPrototype(top);
env->Global()->Set(v8_str("obj"), bottom);
// Indexed and named get.
call_ic_function4 =
v8_compile("function f(x) { return x - 1; }; f")->Run();
v8::Handle<Value> value = CompileRun(
- "o.__proto__.x = function(x) { return x + 1; };"
+ "Object.getPrototypeOf(o).x = function(x) { return x + 1; };"
"var result = 0;"
"for (var i = 0; i < 1000; i++) {"
" result = o.x(42);"
assertFalse(proto_desc.writable, name);
assertFalse(proto_desc.configurable, name);
var prototype = proto_desc.value;
- assertEquals(null, prototype.__proto__, name);
+ assertEquals(null, Object.getPrototypeOf(prototype), name);
for (var i = 0; i < propNames.length; i++) {
var propName = propNames[i];
if (propName == "constructor") continue;
obj.__proto__ = p;
obj.__proto__ = p; // ignored
obj.__proto__ = null;
-obj.__proto__ = q;
+obj.__proto__ = q; // the __proto__ accessor is gone
// TODO(adamk): Add tests for objects with hidden prototypes
// once we support observing the global object.
Object.deliverChangeRecords(observer.callback);
{ object: obj, name: '__proto__', type: 'prototype',
oldValue: Object.prototype },
{ object: obj, name: '__proto__', type: 'prototype', oldValue: p },
- { object: obj, name: '__proto__', type: 'prototype', oldValue: null },
+ { object: obj, name: '__proto__', type: 'new' },
]);
C.prototype = create(handler);
var o = new C;
- assertSame(C.prototype, o.__proto__);
assertSame(C.prototype, Object.getPrototypeOf(o));
}
falseNum.toString = function() { return 42; };
assertEquals('"42"', JSON.stringify(falseNum));
-// We don't currently allow plain properties called __proto__ in JSON
-// objects in JSON.parse. Instead we read them as we would JS object
-// literals. If we change that, this test should change with it.
-//
-// Parse a non-object value as __proto__. This must not create a
-// __proto__ property different from the original, and should not
-// change the original.
-var o = JSON.parse('{"__proto__":5}');
-assertEquals(Object.prototype, o.__proto__); // __proto__ isn't changed.
-assertEquals(0, Object.keys(o).length); // __proto__ isn't added as enumerable.
+// Parse an object value as __proto__.
+var o1 = JSON.parse('{"__proto__":[]}');
+assertEquals([], o1.__proto__);
+assertEquals(["__proto__"], Object.keys(o1));
+assertEquals([], Object.getOwnPropertyDescriptor(o1, "__proto__").value);
+assertEquals(["__proto__"], Object.getOwnPropertyNames(o1));
+assertTrue(o1.hasOwnProperty("__proto__"));
+assertTrue(Object.prototype.isPrototypeOf(o1));
+
+// Parse a non-object value as __proto__.
+var o2 = JSON.parse('{"__proto__":5}');
+assertEquals(5, o2.__proto__);
+assertEquals(["__proto__"], Object.keys(o2));
+assertEquals(5, Object.getOwnPropertyDescriptor(o2, "__proto__").value);
+assertEquals(["__proto__"], Object.getOwnPropertyNames(o2));
+assertTrue(o2.hasOwnProperty("__proto__"));
+assertTrue(Object.prototype.isPrototypeOf(o2));
var json = '{"stuff before slash\\\\stuff after slash":"whatever"}';
assertEquals(json, JSON.stringify(JSON.parse(json)));
--- /dev/null
+// Copyright 2013 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.
+
+var o = {};
+Object.preventExtensions(o);
+assertThrows("Object.defineProperty(o, 'foobarloo', {value:{}});", TypeError);
+assertThrows("Object.defineProperty(o, '__proto__', {value:{}});", TypeError);
############################### BUGS ###################################
-# '__proto__' should be treated as a normal property in JSON.
-S15.12.2_A1: FAIL
-
# Sequencing of getter side effects on receiver and argument properties
# is wrong. The receiver callback should be called before any arguments
# are evaluated.