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

Unified Diff: src/v8natives.js

Issue 7348008: Merge up to 8597 to experimental/gc from the bleeding edge. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: '' Created 9 years, 5 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
« no previous file with comments | « src/v8conversions.cc ('k') | src/v8threads.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/v8natives.js
===================================================================
--- src/v8natives.js (revision 8618)
+++ src/v8natives.js (working copy)
@@ -56,7 +56,7 @@
%FunctionSetName(f, key);
%FunctionRemovePrototype(f);
%SetProperty(object, key, f, attributes);
- %SetES5Flag(f);
+ %SetNativeFlag(f);
}
%ToFastProperties(object);
}
@@ -106,7 +106,7 @@
// Truncate number.
return string | 0;
}
- if (IS_UNDEFINED(radix)) radix = 0;
+ radix = radix | 0;
} else {
radix = TO_INT32(radix);
if (!(radix == 0 || (2 <= radix && radix <= 36)))
@@ -132,10 +132,19 @@
function GlobalEval(x) {
if (!IS_STRING(x)) return x;
+ var receiver = this;
var global_receiver = %GlobalReceiver(global);
- var this_is_global_receiver = (this === global_receiver);
+
+ if (receiver == null && !IS_UNDETECTABLE(receiver)) {
+ receiver = global_receiver;
+ }
+
+ var this_is_global_receiver = (receiver === global_receiver);
var global_is_detached = (global === global_receiver);
+ // For consistency with JSC we require the global object passed to
+ // eval to be the global object from which 'eval' originated. This
+ // is not mandated by the spec.
if (!this_is_global_receiver || global_is_detached) {
throw new $EvalError('The "this" object passed to eval must ' +
'be the global object from which eval originated');
@@ -144,7 +153,7 @@
var f = %CompileString(x);
if (!IS_FUNCTION(f)) return f;
- return %_CallFunction(this, f);
+ return %_CallFunction(receiver, f);
}
@@ -246,8 +255,9 @@
// Extensions for providing property getters and setters.
function ObjectDefineGetter(name, fun) {
- if (this == null && !IS_UNDETECTABLE(this)) {
- throw new $TypeError('Object.prototype.__defineGetter__: this is Null');
+ var receiver = this;
+ if (receiver == null && !IS_UNDETECTABLE(receiver)) {
+ receiver = %GlobalReceiver(global);
}
if (!IS_FUNCTION(fun)) {
throw new $TypeError('Object.prototype.__defineGetter__: Expecting function');
@@ -256,21 +266,23 @@
desc.setGet(fun);
desc.setEnumerable(true);
desc.setConfigurable(true);
- DefineOwnProperty(ToObject(this), ToString(name), desc, false);
+ DefineOwnProperty(ToObject(receiver), ToString(name), desc, false);
}
function ObjectLookupGetter(name) {
- if (this == null && !IS_UNDETECTABLE(this)) {
- throw new $TypeError('Object.prototype.__lookupGetter__: this is Null');
+ var receiver = this;
+ if (receiver == null && !IS_UNDETECTABLE(receiver)) {
+ receiver = %GlobalReceiver(global);
}
- return %LookupAccessor(ToObject(this), ToString(name), GETTER);
+ return %LookupAccessor(ToObject(receiver), ToString(name), GETTER);
}
function ObjectDefineSetter(name, fun) {
- if (this == null && !IS_UNDETECTABLE(this)) {
- throw new $TypeError('Object.prototype.__defineSetter__: this is Null');
+ var receiver = this;
+ if (receiver == null && !IS_UNDETECTABLE(receiver)) {
+ receiver = %GlobalReceiver(global);
}
if (!IS_FUNCTION(fun)) {
throw new $TypeError(
@@ -280,15 +292,16 @@
desc.setSet(fun);
desc.setEnumerable(true);
desc.setConfigurable(true);
- DefineOwnProperty(ToObject(this), ToString(name), desc, false);
+ DefineOwnProperty(ToObject(receiver), ToString(name), desc, false);
}
function ObjectLookupSetter(name) {
- if (this == null && !IS_UNDETECTABLE(this)) {
- throw new $TypeError('Object.prototype.__lookupSetter__: this is Null');
+ var receiver = this;
+ if (receiver == null && !IS_UNDETECTABLE(receiver)) {
+ receiver = %GlobalReceiver(global);
}
- return %LookupAccessor(ToObject(this), ToString(name), SETTER);
+ return %LookupAccessor(ToObject(receiver), ToString(name), SETTER);
}
@@ -302,14 +315,14 @@
// ES5 8.10.1.
function IsAccessorDescriptor(desc) {
if (IS_UNDEFINED(desc)) return false;
- return desc.hasGetter_ || desc.hasSetter_;
+ return desc.hasGetter() || desc.hasSetter();
}
// ES5 8.10.2.
function IsDataDescriptor(desc) {
if (IS_UNDEFINED(desc)) return false;
- return desc.hasValue_ || desc.hasWritable_;
+ return desc.hasValue() || desc.hasWritable();
}
@@ -323,6 +336,7 @@
return IsAccessorDescriptor(desc) && IsDataDescriptor(desc);
}
+
// ES5 8.10.4
function FromPropertyDescriptor(desc) {
if (IS_UNDEFINED(desc)) return desc;
@@ -340,6 +354,19 @@
return obj;
}
+// Harmony Proxies
+function FromGenericPropertyDescriptor(desc) {
+ if (IS_UNDEFINED(desc)) return desc;
+ var obj = new $Object();
+ if (desc.hasValue()) obj.value = desc.getValue();
+ if (desc.hasWritable()) obj.writable = desc.isWritable();
+ if (desc.hasGetter()) obj.get = desc.getGet();
+ if (desc.hasSetter()) obj.set = desc.getSet();
+ if (desc.hasEnumerable()) obj.enumerable = desc.isEnumerable();
+ if (desc.hasConfigurable()) obj.configurable = desc.isConfigurable();
+ return obj;
+}
+
// ES5 8.10.5.
function ToPropertyDescriptor(obj) {
if (!IS_SPEC_OBJECT(obj)) {
@@ -386,6 +413,23 @@
}
+// For Harmony proxies.
+function ToCompletePropertyDescriptor(obj) {
+ var desc = ToPropertyDescriptor(obj)
+ if (IsGenericDescriptor(desc) || IsDataDescriptor(desc)) {
+ if (!desc.hasValue()) desc.setValue(void 0);
+ if (!desc.hasWritable()) desc.setWritable(false);
+ } else {
+ // Is accessor descriptor.
+ if (!desc.hasGetter()) desc.setGet(void 0);
+ if (!desc.hasSetter()) desc.setSet(void 0);
+ }
+ if (!desc.hasEnumerable()) desc.setEnumerable(false);
+ if (!desc.hasConfigurable()) desc.setConfigurable(false);
+ return desc;
+}
+
+
function PropertyDescriptor() {
// Initialize here so they are all in-object and have the same map.
// Default values from ES5 8.6.1.
@@ -534,9 +578,25 @@
// ES5 section 8.12.2.
function GetProperty(obj, p) {
+ if (%IsJSProxy(obj)) {
+ var handler = %GetHandler(obj);
+ var getProperty = handler.getPropertyDescriptor;
+ if (IS_UNDEFINED(getProperty)) {
+ throw MakeTypeError("handler_trap_missing",
+ [handler, "getPropertyDescriptor"]);
+ }
+ var descriptor = getProperty.call(handler, p);
+ if (IS_UNDEFINED(descriptor)) return descriptor;
+ var desc = ToCompletePropertyDescriptor(descriptor);
+ if (!desc.configurable) {
+ throw MakeTypeError("proxy_prop_not_configurable",
+ [handler, "getPropertyDescriptor", p, descriptor]);
+ }
+ return desc;
+ }
var prop = GetOwnProperty(obj);
if (!IS_UNDEFINED(prop)) return prop;
- var proto = obj.__proto__;
+ var proto = %GetPrototype(obj);
if (IS_NULL(proto)) return void 0;
return GetProperty(proto, p);
}
@@ -544,6 +604,12 @@
// ES5 section 8.12.6
function HasProperty(obj, p) {
+ if (%IsJSProxy(obj)) {
+ var handler = %GetHandler(obj);
+ var has = handler.has;
+ if (IS_UNDEFINED(has)) has = DerivedHasTrap;
+ return ToBoolean(has.call(handler, obj, p));
+ }
var desc = GetProperty(obj, p);
return IS_UNDEFINED(desc) ? false : true;
}
@@ -563,8 +629,32 @@
}
+// Harmony proxies.
+function DefineProxyProperty(obj, p, attributes, should_throw) {
+ var handler = %GetHandler(obj);
+ var defineProperty = handler.defineProperty;
+ if (IS_UNDEFINED(defineProperty)) {
+ throw MakeTypeError("handler_trap_missing", [handler, "defineProperty"]);
+ }
+ var result = defineProperty.call(handler, p, attributes);
+ if (!ToBoolean(result)) {
+ if (should_throw) {
+ throw MakeTypeError("handler_failed", [handler, "defineProperty"]);
+ } else {
+ return false;
+ }
+ }
+ return true;
+}
+
+
// ES5 8.12.9.
function DefineOwnProperty(obj, p, desc, should_throw) {
+ if (%IsJSProxy(obj)) {
+ var attributes = FromGenericPropertyDescriptor(desc);
+ return DefineProxyProperty(obj, p, attributes, should_throw);
+ }
+
var current_or_access = %GetOwnProperty(ToObject(obj), ToString(p));
// A false value here means that access checks failed.
if (current_or_access === false) return void 0;
@@ -576,7 +666,7 @@
// Step 3
if (IS_UNDEFINED(current) && !extensible) {
if (should_throw) {
- throw MakeTypeError("define_disallowed", ["defineProperty"]);
+ throw MakeTypeError("define_disallowed", [p]);
} else {
return;
}
@@ -606,7 +696,7 @@
(desc.hasEnumerable() &&
desc.isEnumerable() != current.isEnumerable())) {
if (should_throw) {
- throw MakeTypeError("redefine_disallowed", ["defineProperty"]);
+ throw MakeTypeError("redefine_disallowed", [p]);
} else {
return;
}
@@ -616,7 +706,7 @@
// Step 9a
if (IsDataDescriptor(current) != IsDataDescriptor(desc)) {
if (should_throw) {
- throw MakeTypeError("redefine_disallowed", ["defineProperty"]);
+ throw MakeTypeError("redefine_disallowed", [p]);
} else {
return;
}
@@ -625,7 +715,7 @@
if (IsDataDescriptor(current) && IsDataDescriptor(desc)) {
if (!current.isWritable() && desc.isWritable()) {
if (should_throw) {
- throw MakeTypeError("redefine_disallowed", ["defineProperty"]);
+ throw MakeTypeError("redefine_disallowed", [p]);
} else {
return;
}
@@ -633,7 +723,7 @@
if (!current.isWritable() && desc.hasValue() &&
!SameValue(desc.getValue(), current.getValue())) {
if (should_throw) {
- throw MakeTypeError("redefine_disallowed", ["defineProperty"]);
+ throw MakeTypeError("redefine_disallowed", [p]);
} else {
return;
}
@@ -643,14 +733,14 @@
if (IsAccessorDescriptor(desc) && IsAccessorDescriptor(current)) {
if (desc.hasSetter() && !SameValue(desc.getSet(), current.getSet())) {
if (should_throw) {
- throw MakeTypeError("redefine_disallowed", ["defineProperty"]);
+ throw MakeTypeError("redefine_disallowed", [p]);
} else {
return;
}
}
if (desc.hasGetter() && !SameValue(desc.getGet(),current.getGet())) {
if (should_throw) {
- throw MakeTypeError("redefine_disallowed", ["defineProperty"]);
+ throw MakeTypeError("redefine_disallowed", [p]);
} else {
return;
}
@@ -732,7 +822,7 @@
function ObjectGetPrototypeOf(obj) {
if (!IS_SPEC_OBJECT(obj))
throw MakeTypeError("obj_ctor_property_non_object", ["getPrototypeOf"]);
- return obj.__proto__;
+ return %GetPrototype(obj);
}
@@ -745,11 +835,43 @@
}
+// For Harmony proxies
+function ToStringArray(obj, trap) {
+ if (!IS_SPEC_OBJECT(obj)) {
+ throw MakeTypeError("proxy_non_object_prop_names", [obj, trap]);
+ }
+ var n = ToUint32(obj.length);
+ var array = new $Array(n);
+ var names = {}
+ for (var index = 0; index < n; index++) {
+ var s = ToString(obj[index]);
+ if (s in names) {
+ throw MakeTypeError("proxy_repeated_prop_name", [obj, trap, s])
+ }
+ array[index] = s;
+ names.s = 0;
+ }
+ return array;
+}
+
+
// ES5 section 15.2.3.4.
function ObjectGetOwnPropertyNames(obj) {
if (!IS_SPEC_OBJECT(obj))
throw MakeTypeError("obj_ctor_property_non_object", ["getOwnPropertyNames"]);
+ // Special handling for proxies.
+ if (%IsJSProxy(obj)) {
+ var handler = %GetHandler(obj);
+ var getOwnPropertyNames = handler.getOwnPropertyNames;
+ if (IS_UNDEFINED(getOwnPropertyNames)) {
+ throw MakeTypeError("handler_trap_missing",
+ [handler, "getOwnPropertyNames"]);
+ }
+ var names = getOwnPropertyNames.call(handler);
+ return ToStringArray(names, "getOwnPropertyNames");
+ }
+
// Find all the indexed properties.
// Get the local element names.
@@ -815,8 +937,37 @@
throw MakeTypeError("obj_ctor_property_non_object", ["defineProperty"]);
}
var name = ToString(p);
- var desc = ToPropertyDescriptor(attributes);
- DefineOwnProperty(obj, name, desc, true);
+ 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?).
+ var attributesClone = {}
+ for (var a in attributes) {
+ attributesClone[a] = attributes[a];
+ }
+ DefineProxyProperty(obj, name, attributesClone, true);
+ // The following would implement the spec as in the current proposal,
+ // but after recent comments on es-discuss, is most likely obsolete.
+ /*
+ var defineObj = FromGenericPropertyDescriptor(desc);
+ var names = ObjectGetOwnPropertyNames(attributes);
+ var standardNames =
+ {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);
+ DefineOwnProperty(descObj, N, attr, true);
+ }
+ }
+ // This is really confusing the types, but it is what the proxies spec
+ // currently requires:
+ desc = descObj;
+ */
+ } else {
+ var desc = ToPropertyDescriptor(attributes);
+ DefineOwnProperty(obj, name, desc, true);
+ }
return obj;
}
@@ -853,8 +1004,10 @@
for (var i = 0; i < names.length; i++) {
var name = names[i];
var desc = GetOwnProperty(obj, name);
- if (desc.isConfigurable()) desc.setConfigurable(false);
- DefineOwnProperty(obj, name, desc, true);
+ if (desc.isConfigurable()) {
+ desc.setConfigurable(false);
+ DefineOwnProperty(obj, name, desc, true);
+ }
}
return ObjectPreventExtension(obj);
}
@@ -869,9 +1022,11 @@
for (var i = 0; i < names.length; i++) {
var name = names[i];
var desc = GetOwnProperty(obj, name);
- if (IsDataDescriptor(desc)) desc.setWritable(false);
- if (desc.isConfigurable()) desc.setConfigurable(false);
- DefineOwnProperty(obj, name, desc, true);
+ if (desc.isWritable() || desc.isConfigurable()) {
+ if (IsDataDescriptor(desc)) desc.setWritable(false);
+ desc.setConfigurable(false);
+ DefineOwnProperty(obj, name, desc, true);
+ }
}
return ObjectPreventExtension(obj);
}
@@ -927,7 +1082,7 @@
// ES5 section 15.2.3.13
function ObjectIsExtensible(obj) {
if (!IS_SPEC_OBJECT(obj)) {
- throw MakeTypeError("obj_ctor_property_non_object", ["preventExtension"]);
+ throw MakeTypeError("obj_ctor_property_non_object", ["isExtensible"]);
}
return %IsExtensible(obj);
}
@@ -1269,7 +1424,8 @@
// Set the correct length.
var length = (this.length - argc_bound) > 0 ? this.length - argc_bound : 0;
%FunctionSetLength(result, length);
-
+ %FunctionRemovePrototype(result);
+ %FunctionSetBound(result);
return result;
}
« no previous file with comments | « src/v8conversions.cc ('k') | src/v8threads.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698