// Copyright 2012 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.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
// This file relies on the fact that the following declarations have been made
// in runtime.js:
var f = functions[i + 1];
%FunctionSetName(f, key);
%FunctionRemovePrototype(f);
- %SetProperty(object, key, f, attributes);
+ %AddNamedProperty(object, key, f, attributes);
%SetNativeFlag(f);
}
%ToFastProperties(object);
function InstallGetter(object, name, getter) {
%FunctionSetName(getter, name);
%FunctionRemovePrototype(getter);
- %DefineOrRedefineAccessorProperty(object, name, getter, null, DONT_ENUM);
+ %DefineAccessorPropertyUnchecked(object, name, getter, null, DONT_ENUM);
%SetNativeFlag(getter);
}
%FunctionSetName(setter, name);
%FunctionRemovePrototype(getter);
%FunctionRemovePrototype(setter);
- %DefineOrRedefineAccessorProperty(object, name, getter, setter, DONT_ENUM);
+ %DefineAccessorPropertyUnchecked(object, name, getter, setter, DONT_ENUM);
%SetNativeFlag(getter);
%SetNativeFlag(setter);
}
for (var i = 0; i < constants.length; i += 2) {
var name = constants[i];
var k = constants[i + 1];
- %SetProperty(object, name, k, attributes);
+ %AddNamedProperty(object, name, k, attributes);
}
%ToFastProperties(object);
}
}
if (fields) {
for (var i = 0; i < fields.length; i++) {
- %SetProperty(prototype, fields[i], UNDEFINED, DONT_ENUM | DONT_DELETE);
+ %AddNamedProperty(prototype, fields[i],
+ UNDEFINED, DONT_ENUM | DONT_DELETE);
}
}
for (var i = 0; i < methods.length; i += 2) {
var key = methods[i];
var f = methods[i + 1];
- %SetProperty(prototype, key, f, DONT_ENUM | DONT_DELETE | READ_ONLY);
+ %AddNamedProperty(prototype, key, f, DONT_ENUM | DONT_DELETE | READ_ONLY);
%SetNativeFlag(f);
}
- %SetPrototype(prototype, null);
+ %InternalSetPrototype(prototype, null);
%ToFastProperties(prototype);
}
'be the global object from which eval originated');
}
- var global_receiver = %GlobalReceiver(global);
+ var global_proxy = %GlobalProxy(global);
var f = %CompileString(x, false);
if (!IS_FUNCTION(f)) return f;
- return %_CallFunction(global_receiver, f);
+ return %_CallFunction(global_proxy, f);
}
var attributes = DONT_ENUM | DONT_DELETE | READ_ONLY;
// ECMA 262 - 15.1.1.1.
- %SetProperty(global, "NaN", NAN, attributes);
+ %AddNamedProperty(global, "NaN", NAN, attributes);
// ECMA-262 - 15.1.1.2.
- %SetProperty(global, "Infinity", INFINITY, attributes);
+ %AddNamedProperty(global, "Infinity", INFINITY, attributes);
// ECMA-262 - 15.1.1.3.
- %SetProperty(global, "undefined", UNDEFINED, attributes);
+ %AddNamedProperty(global, "undefined", UNDEFINED, attributes);
// Set up non-enumerable function on the global object.
InstallFunctions(global, DONT_ENUM, $Array(
// ----------------------------------------------------------------------------
// Object
+var DefaultObjectToString = NoSideEffectsObjectToString;
// ECMA-262 - 15.2.4.2
-function ObjectToString() {
+function NoSideEffectsObjectToString() {
if (IS_UNDEFINED(this) && !IS_UNDETECTABLE(this)) return "[object Undefined]";
if (IS_NULL(this)) return "[object Null]";
return "[object " + %_ClassOf(ToObject(this)) + "]";
// ECMA-262 - 15.2.4.5
function ObjectHasOwnProperty(V) {
- if (%IsJSProxy(this)) {
+ if (%_IsJSProxy(this)) {
// TODO(rossberg): adjust once there is a story for symbols vs proxies.
if (IS_SYMBOL(V)) return false;
var handler = %GetHandler(this);
return CallTrap1(handler, "hasOwn", DerivedHasOwnTrap, ToName(V));
}
- return %HasLocalProperty(TO_OBJECT_INLINE(this), ToName(V));
+ return %HasOwnProperty(TO_OBJECT_INLINE(this), ToName(V));
}
// ECMA-262 - 15.2.4.6
function ObjectIsPrototypeOf(V) {
- CHECK_OBJECT_COERCIBLE(this, "Object.prototype.isPrototypeOf");
if (!IS_SPEC_OBJECT(V)) return false;
+ CHECK_OBJECT_COERCIBLE(this, "Object.prototype.isPrototypeOf");
return %IsInPrototypeChain(this, V);
}
// ECMA-262 - 15.2.4.6
function ObjectPropertyIsEnumerable(V) {
var P = ToName(V);
- if (%IsJSProxy(this)) {
+ if (%_IsJSProxy(this)) {
// TODO(rossberg): adjust once there is a story for symbols vs proxies.
if (IS_SYMBOL(V)) return false;
- var desc = GetOwnProperty(this, P);
+ var desc = GetOwnPropertyJS(this, P);
return IS_UNDEFINED(desc) ? false : desc.isEnumerable();
}
return %IsPropertyEnumerable(ToObject(this), P);
function ObjectDefineGetter(name, fun) {
var receiver = this;
if (receiver == null && !IS_UNDETECTABLE(receiver)) {
- receiver = %GlobalReceiver(global);
+ receiver = %GlobalProxy(global);
}
if (!IS_SPEC_FUNCTION(fun)) {
throw new $TypeError(
function ObjectLookupGetter(name) {
var receiver = this;
if (receiver == null && !IS_UNDETECTABLE(receiver)) {
- receiver = %GlobalReceiver(global);
+ receiver = %GlobalProxy(global);
}
return %LookupAccessor(ToObject(receiver), ToName(name), GETTER);
}
function ObjectDefineSetter(name, fun) {
var receiver = this;
if (receiver == null && !IS_UNDETECTABLE(receiver)) {
- receiver = %GlobalReceiver(global);
+ receiver = %GlobalProxy(global);
}
if (!IS_SPEC_FUNCTION(fun)) {
throw new $TypeError(
function ObjectLookupSetter(name) {
var receiver = this;
if (receiver == null && !IS_UNDETECTABLE(receiver)) {
- receiver = %GlobalReceiver(global);
+ receiver = %GlobalProxy(global);
}
return %LookupAccessor(ToObject(receiver), ToName(name), SETTER);
}
function ObjectKeys(obj) {
- if (!IS_SPEC_OBJECT(obj)) {
- throw MakeTypeError("called_on_non_object", ["Object.keys"]);
- }
- if (%IsJSProxy(obj)) {
+ obj = ToObject(obj);
+ if (%_IsJSProxy(obj)) {
var handler = %GetHandler(obj);
var names = CallTrap0(handler, "keys", DerivedKeysTrap);
return ToNameArray(names, "keys", false);
}
- return %LocalKeys(obj);
+ return %OwnKeys(obj);
}
var obj = new $Object();
if (desc.hasValue()) {
- %IgnoreAttributesAndSetProperty(obj, "value", desc.getValue(), NONE);
+ %AddNamedProperty(obj, "value", desc.getValue(), NONE);
}
if (desc.hasWritable()) {
- %IgnoreAttributesAndSetProperty(obj, "writable", desc.isWritable(), NONE);
+ %AddNamedProperty(obj, "writable", desc.isWritable(), NONE);
}
if (desc.hasGetter()) {
- %IgnoreAttributesAndSetProperty(obj, "get", desc.getGet(), NONE);
+ %AddNamedProperty(obj, "get", desc.getGet(), NONE);
}
if (desc.hasSetter()) {
- %IgnoreAttributesAndSetProperty(obj, "set", desc.getSet(), NONE);
+ %AddNamedProperty(obj, "set", desc.getSet(), NONE);
}
if (desc.hasEnumerable()) {
- %IgnoreAttributesAndSetProperty(obj, "enumerable",
- desc.isEnumerable(), NONE);
+ %AddNamedProperty(obj, "enumerable", desc.isEnumerable(), NONE);
}
if (desc.hasConfigurable()) {
- %IgnoreAttributesAndSetProperty(obj, "configurable",
- desc.isConfigurable(), NONE);
+ %AddNamedProperty(obj, "configurable", desc.isConfigurable(), NONE);
}
return obj;
}
"set_",
"hasSetter_"
), $Array(
- "toString", function() {
+ "toString", function PropertyDescriptor_ToString() {
return "[object PropertyDescriptor]";
},
- "setValue", function(value) {
+ "setValue", function PropertyDescriptor_SetValue(value) {
this.value_ = value;
this.hasValue_ = true;
},
- "getValue", function() {
+ "getValue", function PropertyDescriptor_GetValue() {
return this.value_;
},
- "hasValue", function() {
+ "hasValue", function PropertyDescriptor_HasValue() {
return this.hasValue_;
},
- "setEnumerable", function(enumerable) {
+ "setEnumerable", function PropertyDescriptor_SetEnumerable(enumerable) {
this.enumerable_ = enumerable;
this.hasEnumerable_ = true;
},
- "isEnumerable", function () {
+ "isEnumerable", function PropertyDescriptor_IsEnumerable() {
return this.enumerable_;
},
- "hasEnumerable", function() {
+ "hasEnumerable", function PropertyDescriptor_HasEnumerable() {
return this.hasEnumerable_;
},
- "setWritable", function(writable) {
+ "setWritable", function PropertyDescriptor_SetWritable(writable) {
this.writable_ = writable;
this.hasWritable_ = true;
},
- "isWritable", function() {
+ "isWritable", function PropertyDescriptor_IsWritable() {
return this.writable_;
},
- "hasWritable", function() {
+ "hasWritable", function PropertyDescriptor_HasWritable() {
return this.hasWritable_;
},
- "setConfigurable", function(configurable) {
+ "setConfigurable",
+ function PropertyDescriptor_SetConfigurable(configurable) {
this.configurable_ = configurable;
this.hasConfigurable_ = true;
},
- "hasConfigurable", function() {
+ "hasConfigurable", function PropertyDescriptor_HasConfigurable() {
return this.hasConfigurable_;
},
- "isConfigurable", function() {
+ "isConfigurable", function PropertyDescriptor_IsConfigurable() {
return this.configurable_;
},
- "setGet", function(get) {
+ "setGet", function PropertyDescriptor_SetGetter(get) {
this.get_ = get;
- this.hasGetter_ = true;
+ this.hasGetter_ = true;
},
- "getGet", function() {
+ "getGet", function PropertyDescriptor_GetGetter() {
return this.get_;
},
- "hasGetter", function() {
+ "hasGetter", function PropertyDescriptor_HasGetter() {
return this.hasGetter_;
},
- "setSet", function(set) {
+ "setSet", function PropertyDescriptor_SetSetter(set) {
this.set_ = set;
this.hasSetter_ = true;
},
- "getSet", function() {
+ "getSet", function PropertyDescriptor_GetSetter() {
return this.set_;
},
- "hasSetter", function() {
+ "hasSetter", function PropertyDescriptor_HasSetter() {
return this.hasSetter_;
}));
// property descriptor. For a description of the array layout please
// see the runtime.cc file.
function ConvertDescriptorArrayToDescriptor(desc_array) {
- if (desc_array === false) {
- throw 'Internal error: invalid desc_array';
- }
-
if (IS_UNDEFINED(desc_array)) {
return UNDEFINED;
}
// ES5 section 8.12.1.
-function GetOwnProperty(obj, v) {
+function GetOwnPropertyJS(obj, v) {
var p = ToName(v);
- if (%IsJSProxy(obj)) {
+ if (%_IsJSProxy(obj)) {
// TODO(rossberg): adjust once there is a story for symbols vs proxies.
if (IS_SYMBOL(v)) return UNDEFINED;
// If p is not a property on obj undefined is returned.
var props = %GetOwnProperty(ToObject(obj), p);
- // A false value here means that access checks failed.
- if (props === false) return UNDEFINED;
-
return ConvertDescriptorArrayToDescriptor(props);
}
// ES5 section 8.12.7.
function Delete(obj, p, should_throw) {
- var desc = GetOwnProperty(obj, p);
+ var desc = GetOwnPropertyJS(obj, p);
if (IS_UNDEFINED(desc)) return true;
if (desc.isConfigurable()) {
%DeleteProperty(obj, p, 0);
// ES5 8.12.9.
function DefineObjectProperty(obj, p, desc, should_throw) {
- var current_or_access = %GetOwnProperty(ToObject(obj), ToName(p));
- // A false value here means that access checks failed.
- if (current_or_access === false) return UNDEFINED;
-
- var current = ConvertDescriptorArrayToDescriptor(current_or_access);
+ var current_array = %GetOwnProperty(ToObject(obj), ToName(p));
+ var current = ConvertDescriptorArrayToDescriptor(current_array);
var extensible = %IsExtensible(ToObject(obj));
// Error handling according to spec.
value = current.getValue();
}
- %DefineOrRedefineDataProperty(obj, p, value, flag);
+ %DefineDataPropertyUnchecked(obj, p, value, flag);
} else {
// There are 3 cases that lead here:
// Step 4b - defining a new accessor property.
// property.
// Step 12 - updating an existing accessor property with an accessor
// descriptor.
- var getter = desc.hasGetter() ? desc.getGet() : null;
- var setter = desc.hasSetter() ? desc.getSet() : null;
- %DefineOrRedefineAccessorProperty(obj, p, getter, setter, flag);
+ var getter = null;
+ if (desc.hasGetter()) {
+ getter = desc.getGet();
+ } else if (IsAccessorDescriptor(current) && current.hasGetter()) {
+ getter = current.getGet();
+ }
+ var setter = null;
+ if (desc.hasSetter()) {
+ setter = desc.getSet();
+ } else if (IsAccessorDescriptor(current) && current.hasSetter()) {
+ setter = current.getSet();
+ }
+ %DefineAccessorPropertyUnchecked(obj, p, getter, setter, flag);
}
return true;
}
if (new_length != ToNumber(desc.getValue())) {
throw new $RangeError('defineProperty() array length out of range');
}
- var length_desc = GetOwnProperty(obj, "length");
+ var length_desc = GetOwnPropertyJS(obj, "length");
if (new_length != length && !length_desc.isWritable()) {
if (should_throw) {
throw MakeTypeError("redefine_disallowed", [p]);
while (new_length < length--) {
var index = ToString(length);
if (emit_splice) {
- var deletedDesc = GetOwnProperty(obj, index);
+ var deletedDesc = GetOwnPropertyJS(obj, index);
if (deletedDesc && deletedDesc.hasValue())
removed[length - new_length] = deletedDesc.getValue();
}
// Make sure the below call to DefineObjectProperty() doesn't overwrite
// any magic "length" property by removing the value.
// TODO(mstarzinger): This hack should be removed once we have addressed the
- // respective TODO in Runtime_DefineOrRedefineDataProperty.
+ // respective TODO in Runtime_DefineDataPropertyUnchecked.
// For the time being, we need a hack to prevent Object.observe from
// generating two change records.
obj.length = new_length;
}
// Step 4 - Special handling for array index.
- var index = ToUint32(p);
- var emit_splice = false;
- if (ToString(index) == p && index != 4294967295) {
- var length = obj.length;
- if (index >= length && %IsObserved(obj)) {
- emit_splice = true;
- BeginPerformSplice(obj);
- }
+ if (!IS_SYMBOL(p)) {
+ var index = ToUint32(p);
+ var emit_splice = false;
+ if (ToString(index) == p && index != 4294967295) {
+ var length = obj.length;
+ if (index >= length && %IsObserved(obj)) {
+ emit_splice = true;
+ BeginPerformSplice(obj);
+ }
- var length_desc = GetOwnProperty(obj, "length");
- if ((index >= length && !length_desc.isWritable()) ||
- !DefineObjectProperty(obj, p, desc, true)) {
- if (emit_splice)
+ var length_desc = GetOwnPropertyJS(obj, "length");
+ if ((index >= length && !length_desc.isWritable()) ||
+ !DefineObjectProperty(obj, p, desc, true)) {
+ if (emit_splice)
+ EndPerformSplice(obj);
+ if (should_throw) {
+ throw MakeTypeError("define_disallowed", [p]);
+ } else {
+ return false;
+ }
+ }
+ if (index >= length) {
+ obj.length = index + 1;
+ }
+ if (emit_splice) {
EndPerformSplice(obj);
- if (should_throw) {
- throw MakeTypeError("define_disallowed", [p]);
- } else {
- return false;
+ EnqueueSpliceRecord(obj, length, [], index + 1 - length);
}
+ return true;
}
- if (index >= length) {
- obj.length = index + 1;
- }
- if (emit_splice) {
- EndPerformSplice(obj);
- EnqueueSpliceRecord(obj, length, [], index + 1 - length);
- }
- return true;
}
// Step 5 - Fallback to default implementation.
// ES5 section 8.12.9, ES5 section 15.4.5.1 and Harmony proxies.
function DefineOwnProperty(obj, p, desc, should_throw) {
- if (%IsJSProxy(obj)) {
+ if (%_IsJSProxy(obj)) {
// TODO(rossberg): adjust once there is a story for symbols vs proxies.
if (IS_SYMBOL(p)) return false;
throw MakeTypeError("called_on_non_object",
["Object.getOwnPropertyDescriptor"]);
}
- var desc = GetOwnProperty(obj, p);
+ var desc = GetOwnPropertyJS(obj, p);
return FromPropertyDescriptor(desc);
}
var s = ToName(obj[index]);
// TODO(rossberg): adjust once there is a story for symbols vs proxies.
if (IS_SYMBOL(s) && !includeSymbols) continue;
- if (%HasLocalProperty(names, s)) {
+ if (%HasOwnProperty(names, s)) {
throw MakeTypeError("proxy_repeated_prop_name", [obj, trap, s]);
}
array[index] = s;
}
-function ObjectGetOwnPropertyKeys(obj, symbolsOnly) {
+function ObjectGetOwnPropertyKeys(obj, filter) {
var nameArrays = new InternalArray();
- var filter = symbolsOnly ?
- PROPERTY_ATTRIBUTES_STRING | PROPERTY_ATTRIBUTES_PRIVATE_SYMBOL :
- PROPERTY_ATTRIBUTES_SYMBOLIC;
+ filter |= PROPERTY_ATTRIBUTES_PRIVATE_SYMBOL;
// Find all the indexed properties.
- // Only get the local element names if we want to include string keys.
- if (!symbolsOnly) {
- var localElementNames = %GetLocalElementNames(obj);
- for (var i = 0; i < localElementNames.length; ++i) {
- localElementNames[i] = %_NumberToString(localElementNames[i]);
+ // Only get own element names if we want to include string keys.
+ if ((filter & PROPERTY_ATTRIBUTES_STRING) === 0) {
+ var ownElementNames = %GetOwnElementNames(obj);
+ for (var i = 0; i < ownElementNames.length; ++i) {
+ ownElementNames[i] = %_NumberToString(ownElementNames[i]);
}
- nameArrays.push(localElementNames);
+ nameArrays.push(ownElementNames);
// Get names for indexed interceptor properties.
var interceptorInfo = %GetInterceptorInfo(obj);
// Find all the named properties.
- // Get the local property names.
- nameArrays.push(%GetLocalPropertyNames(obj, filter));
+ // Get own property names.
+ nameArrays.push(%GetOwnPropertyNames(obj, filter));
// Get names for named interceptor properties if any.
if ((interceptorInfo & 2) != 0) {
var j = 0;
for (var i = 0; i < propertyNames.length; ++i) {
var name = propertyNames[i];
- if (symbolsOnly) {
- if (!IS_SYMBOL(name) || IS_PRIVATE(name)) continue;
+ if (IS_SYMBOL(name)) {
+ if ((filter & PROPERTY_ATTRIBUTES_SYMBOLIC) || IS_PRIVATE(name)) {
+ continue;
+ }
} else {
- if (IS_SYMBOL(name)) continue;
+ if (filter & PROPERTY_ATTRIBUTES_STRING) continue;
name = ToString(name);
}
if (seenKeys[name]) continue;
// ES5 section 15.2.3.4.
function ObjectGetOwnPropertyNames(obj) {
- if (!IS_SPEC_OBJECT(obj)) {
- throw MakeTypeError("called_on_non_object", ["Object.getOwnPropertyNames"]);
- }
+ obj = ToObject(obj);
// Special handling for proxies.
- if (%IsJSProxy(obj)) {
+ if (%_IsJSProxy(obj)) {
var handler = %GetHandler(obj);
var names = CallTrap0(handler, "getOwnPropertyNames", UNDEFINED);
return ToNameArray(names, "getOwnPropertyNames", false);
}
- return ObjectGetOwnPropertyKeys(obj, false);
+ return ObjectGetOwnPropertyKeys(obj, PROPERTY_ATTRIBUTES_SYMBOLIC);
}
if (!IS_SPEC_OBJECT(proto) && proto !== null) {
throw MakeTypeError("proto_object_or_null", [proto]);
}
- var obj = { __proto__: proto };
+ var obj = {};
+ %InternalSetPrototype(obj, proto);
if (!IS_UNDEFINED(properties)) ObjectDefineProperties(obj, properties);
return obj;
}
throw MakeTypeError("called_on_non_object", ["Object.defineProperty"]);
}
var name = ToName(p);
- if (%IsJSProxy(obj)) {
+ if (%_IsJSProxy(obj)) {
// Clone the attributes object for protection.
// TODO(rossberg): not spec'ed yet, so not sure if this should involve
// non-own properties as it does (or non-enumerable ones, as it doesn't?).
{value: 0, writable: 0, get: 0, set: 0, enumerable: 0, configurable: 0};
for (var i = 0; i < names.length; i++) {
var N = names[i];
- if (!(%HasLocalProperty(standardNames, N))) {
- var attr = GetOwnProperty(attributes, N);
+ if (!(%HasOwnProperty(standardNames, N))) {
+ var attr = GetOwnPropertyJS(attributes, N);
DefineOwnProperty(descObj, N, attr, true);
}
}
}
-function GetOwnEnumerablePropertyNames(properties) {
+function GetOwnEnumerablePropertyNames(object) {
var names = new InternalArray();
- for (var key in properties) {
- if (%HasLocalProperty(properties, key)) {
+ for (var key in object) {
+ if (%HasOwnProperty(object, key)) {
names.push(key);
}
}
+
+ var filter = PROPERTY_ATTRIBUTES_STRING | PROPERTY_ATTRIBUTES_PRIVATE_SYMBOL;
+ var symbols = %GetOwnPropertyNames(object, filter);
+ for (var i = 0; i < symbols.length; ++i) {
+ var symbol = symbols[i];
+ if (IS_SYMBOL(symbol)) {
+ var desc = ObjectGetOwnPropertyDescriptor(object, symbol);
+ if (desc.enumerable) names.push(symbol);
+ }
+ }
+
return names;
}
if (!IS_SPEC_OBJECT(obj)) {
throw MakeTypeError("called_on_non_object", ["Object.seal"]);
}
- if (%IsJSProxy(obj)) {
+ if (%_IsJSProxy(obj)) {
ProxyFix(obj);
}
var names = ObjectGetOwnPropertyNames(obj);
for (var i = 0; i < names.length; i++) {
var name = names[i];
- var desc = GetOwnProperty(obj, name);
+ var desc = GetOwnPropertyJS(obj, name);
if (desc.isConfigurable()) {
desc.setConfigurable(false);
DefineOwnProperty(obj, name, desc, true);
// ES5 section 15.2.3.9.
-function ObjectFreeze(obj) {
+function ObjectFreezeJS(obj) {
if (!IS_SPEC_OBJECT(obj)) {
throw MakeTypeError("called_on_non_object", ["Object.freeze"]);
}
- var isProxy = %IsJSProxy(obj);
- if (isProxy || %HasNonStrictArgumentsElements(obj) || %IsObserved(obj)) {
+ var isProxy = %_IsJSProxy(obj);
+ if (isProxy || %HasSloppyArgumentsElements(obj) || %IsObserved(obj)) {
if (isProxy) {
ProxyFix(obj);
}
var names = ObjectGetOwnPropertyNames(obj);
for (var i = 0; i < names.length; i++) {
var name = names[i];
- var desc = GetOwnProperty(obj, name);
+ var desc = GetOwnPropertyJS(obj, name);
if (desc.isWritable() || desc.isConfigurable()) {
if (IsDataDescriptor(desc)) desc.setWritable(false);
desc.setConfigurable(false);
if (!IS_SPEC_OBJECT(obj)) {
throw MakeTypeError("called_on_non_object", ["Object.preventExtension"]);
}
- if (%IsJSProxy(obj)) {
+ if (%_IsJSProxy(obj)) {
ProxyFix(obj);
}
%PreventExtensions(obj);
if (!IS_SPEC_OBJECT(obj)) {
throw MakeTypeError("called_on_non_object", ["Object.isSealed"]);
}
- if (%IsJSProxy(obj)) {
+ if (%_IsJSProxy(obj)) {
return false;
}
if (%IsExtensible(obj)) {
var names = ObjectGetOwnPropertyNames(obj);
for (var i = 0; i < names.length; i++) {
var name = names[i];
- var desc = GetOwnProperty(obj, name);
- if (desc.isConfigurable()) return false;
+ var desc = GetOwnPropertyJS(obj, name);
+ if (desc.isConfigurable()) {
+ return false;
+ }
}
return true;
}
if (!IS_SPEC_OBJECT(obj)) {
throw MakeTypeError("called_on_non_object", ["Object.isFrozen"]);
}
- if (%IsJSProxy(obj)) {
+ if (%_IsJSProxy(obj)) {
return false;
}
if (%IsExtensible(obj)) {
var names = ObjectGetOwnPropertyNames(obj);
for (var i = 0; i < names.length; i++) {
var name = names[i];
- var desc = GetOwnProperty(obj, name);
+ var desc = GetOwnPropertyJS(obj, name);
if (IsDataDescriptor(desc) && desc.isWritable()) return false;
if (desc.isConfigurable()) return false;
}
if (!IS_SPEC_OBJECT(obj)) {
throw MakeTypeError("called_on_non_object", ["Object.isExtensible"]);
}
- if (%IsJSProxy(obj)) {
+ if (%_IsJSProxy(obj)) {
return true;
}
return %IsExtensible(obj);
}
-// Harmony egal.
+// ECMA-262, Edition 6, section 19.1.2.10
function ObjectIs(obj1, obj2) {
- if (obj1 === obj2) {
- return (obj1 !== 0) || (1 / obj1 === 1 / obj2);
- } else {
- return (obj1 !== obj1) && (obj2 !== obj2);
- }
+ return SameValue(obj1, obj2);
}
-// Harmony __proto__ getter.
+// ECMA-262, Edition 6, section B.2.2.1.1
function ObjectGetProto() {
- return %GetPrototype(this);
+ return %GetPrototype(ToObject(this));
}
-// Harmony __proto__ setter.
-function ObjectSetProto(obj) {
- return %SetPrototype(this, obj);
+// ECMA-262, Edition 6, section B.2.2.1.2
+function ObjectSetProto(proto) {
+ CHECK_OBJECT_COERCIBLE(this, "Object.prototype.__proto__");
+
+ if ((IS_SPEC_OBJECT(proto) || IS_NULL(proto)) && IS_SPEC_OBJECT(this)) {
+ %SetPrototype(this, proto);
+ }
}
%SetNativeFlag($Object);
%SetCode($Object, ObjectConstructor);
- %SetExpectedNumberOfProperties($Object, 4);
- %SetProperty($Object.prototype, "constructor", $Object, DONT_ENUM);
+ %AddNamedProperty($Object.prototype, "constructor", $Object, DONT_ENUM);
// Set up non-enumerable functions on the Object.prototype object.
InstallFunctions($Object.prototype, DONT_ENUM, $Array(
- "toString", ObjectToString,
+ "toString", NoSideEffectsObjectToString,
"toLocaleString", ObjectToLocaleString,
"valueOf", ObjectValueOf,
"hasOwnProperty", ObjectHasOwnProperty,
"create", ObjectCreate,
"defineProperty", ObjectDefineProperty,
"defineProperties", ObjectDefineProperties,
- "freeze", ObjectFreeze,
+ "freeze", ObjectFreezeJS,
"getPrototypeOf", ObjectGetPrototypeOf,
"setPrototypeOf", ObjectSetPrototypeOf,
"getOwnPropertyDescriptor", ObjectGetOwnPropertyDescriptor,
%SetCode($Boolean, BooleanConstructor);
%FunctionSetPrototype($Boolean, new $Boolean(false));
- %SetProperty($Boolean.prototype, "constructor", $Boolean, DONT_ENUM);
+ %AddNamedProperty($Boolean.prototype, "constructor", $Boolean, DONT_ENUM);
InstallFunctions($Boolean.prototype, DONT_ENUM, $Array(
"toString", BooleanToString,
// ECMA-262 section 15.7.4.5
-function NumberToFixed(fractionDigits) {
+function NumberToFixedJS(fractionDigits) {
var x = this;
if (!IS_NUMBER(this)) {
if (!IS_NUMBER_WRAPPER(this)) {
// ECMA-262 section 15.7.4.6
-function NumberToExponential(fractionDigits) {
+function NumberToExponentialJS(fractionDigits) {
var x = this;
if (!IS_NUMBER(this)) {
if (!IS_NUMBER_WRAPPER(this)) {
// ECMA-262 section 15.7.4.7
-function NumberToPrecision(precision) {
+function NumberToPrecisionJS(precision) {
var x = this;
if (!IS_NUMBER(this)) {
if (!IS_NUMBER_WRAPPER(this)) {
%OptimizeObjectForAddingMultipleProperties($Number.prototype, 8);
// Set up the constructor property on the Number prototype object.
- %SetProperty($Number.prototype, "constructor", $Number, DONT_ENUM);
+ %AddNamedProperty($Number.prototype, "constructor", $Number, DONT_ENUM);
InstallConstants($Number, $Array(
// ECMA-262 section 15.7.3.1.
"toString", NumberToString,
"toLocaleString", NumberToLocaleString,
"valueOf", NumberValueOf,
- "toFixed", NumberToFixed,
- "toExponential", NumberToExponential,
- "toPrecision", NumberToPrecision
+ "toFixed", NumberToFixedJS,
+ "toExponential", NumberToExponentialJS,
+ "toPrecision", NumberToPrecisionJS
));
// Harmony Number constructor additions
throw new $TypeError('Function.prototype.toString is not generic');
}
+ var classSource = %ClassGetSourceCode(func);
+ if (IS_STRING(classSource)) {
+ return classSource;
+ }
+
var source = %FunctionGetSourceCode(func);
if (!IS_STRING(source) || %FunctionIsBuiltin(func)) {
var name = %FunctionGetName(func);
}
}
+ if (%FunctionIsArrow(func)) {
+ return source;
+ }
+
var name = %FunctionNameShouldPrintAsAnonymous(func)
? 'anonymous'
: %FunctionGetName(func);
- var head = %FunctionIsGenerator(func) ? 'function* ' : 'function ';
+
+ var isGenerator = %FunctionIsGenerator(func);
+ var head = %FunctionIsConciseMethod(func)
+ ? (isGenerator ? '*' : '')
+ : (isGenerator ? 'function* ' : 'function ');
return head + name + source;
}
return %Apply(bindings[0], bindings[1], argv, 0, bound_argc + argc);
};
- %FunctionRemovePrototype(boundFunction);
var new_length = 0;
- if (%_ClassOf(this) == "Function") {
- // Function or FunctionProxy.
- var old_length = this.length;
- // FunctionProxies might provide a non-UInt32 value. If so, ignore it.
- if ((typeof old_length === "number") &&
- ((old_length >>> 0) === old_length)) {
- var argc = %_ArgumentsLength();
- if (argc > 0) argc--; // Don't count the thisArg as parameter.
- new_length = old_length - argc;
- if (new_length < 0) new_length = 0;
- }
+ var old_length = this.length;
+ // FunctionProxies might provide a non-UInt32 value. If so, ignore it.
+ if ((typeof old_length === "number") &&
+ ((old_length >>> 0) === old_length)) {
+ var argc = %_ArgumentsLength();
+ if (argc > 0) argc--; // Don't count the thisArg as parameter.
+ new_length = old_length - argc;
+ if (new_length < 0) new_length = 0;
}
// This runtime function finds any remaining arguments on the stack,
// so we don't pass the arguments object.
// If the formal parameters string include ) - an illegal
// character - it may make the combined function expression
// compile. We avoid this problem by checking for this early on.
- if (%_CallFunction(p, ')', StringIndexOf) != -1) {
+ if (%_CallFunction(p, ')', StringIndexOfJS) != -1) {
throw MakeSyntaxError('paren_in_arg_string', []);
}
// If the formal parameters include an unbalanced block comment, the
function FunctionConstructor(arg1) { // length == 1
var source = NewFunctionString(arguments, 'function');
- var global_receiver = %GlobalReceiver(global);
+ var global_proxy = %GlobalProxy(global);
// Compile the string in the constructor and not a helper so that errors
// appear to come from here.
- var f = %_CallFunction(global_receiver, %CompileString(source, true));
+ var f = %_CallFunction(global_proxy, %CompileString(source, true));
%FunctionMarkNameShouldPrintAsAnonymous(f);
return f;
}
%CheckIsBootstrapping();
%SetCode($Function, FunctionConstructor);
- %SetProperty($Function.prototype, "constructor", $Function, DONT_ENUM);
+ %AddNamedProperty($Function.prototype, "constructor", $Function, DONT_ENUM);
InstallFunctions($Function.prototype, DONT_ENUM, $Array(
"bind", FunctionBind,
SetUpFunction();
-//----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+// Iterator related spec functions.
-// TODO(rossberg): very simple abstraction for generic microtask queue.
-// Eventually, we should move to a real event queue that allows to maintain
-// relative ordering of different kinds of tasks.
+// ES6 rev 26, 2014-07-18
+// 7.4.1 CheckIterable ( obj )
+function ToIterable(obj) {
+ if (!IS_SPEC_OBJECT(obj)) {
+ return UNDEFINED;
+ }
+ return obj[symbolIterator];
+}
-RunMicrotasks.runners = new InternalArray;
-function RunMicrotasks() {
- while (%SetMicrotaskPending(false)) {
- for (var i in RunMicrotasks.runners) RunMicrotasks.runners[i]();
+// ES6 rev 26, 2014-07-18
+// 7.4.2 GetIterator ( obj, method )
+function GetIterator(obj, method) {
+ if (IS_UNDEFINED(method)) {
+ method = ToIterable(obj);
+ }
+ if (!IS_SPEC_FUNCTION(method)) {
+ throw MakeTypeError('not_iterable', [obj]);
+ }
+ var iterator = %_CallFunction(obj, method);
+ if (!IS_SPEC_OBJECT(iterator)) {
+ throw MakeTypeError('not_an_iterator', [iterator]);
}
+ return iterator;
}