Revision: 6847
Author: [email protected]
Date: Thu Feb 17 13:56:37 2011
Log: Revert "This is not wrapped for strict mode and builtin functions."
This reverts commit 6845
http://code.google.com/p/v8/source/detail?r=6847
Modified:
/branches/bleeding_edge/src/arm/stub-cache-arm.cc
/branches/bleeding_edge/src/ia32/stub-cache-ia32.cc
/branches/bleeding_edge/src/ic.cc
/branches/bleeding_edge/src/ic.h
/branches/bleeding_edge/src/x64/stub-cache-x64.cc
/branches/bleeding_edge/test/mjsunit/strict-mode.js
=======================================
--- /branches/bleeding_edge/src/arm/stub-cache-arm.cc Thu Feb 17 09:52:03
2011
+++ /branches/bleeding_edge/src/arm/stub-cache-arm.cc Thu Feb 17 13:56:37
2011
@@ -2332,9 +2332,8 @@
break;
case STRING_CHECK:
- if (!function->IsBuiltin() && !function_info->strict_mode()) {
- // Calling non-strict non-builtins with a value as the receiver
- // requires boxing.
+ if (!function->IsBuiltin()) {
+ // Calling non-builtins with a value as receiver requires boxing.
__ jmp(&miss);
} else {
// Check that the object is a two-byte string or a symbol.
@@ -2349,9 +2348,8 @@
break;
case NUMBER_CHECK: {
- if (!function->IsBuiltin() && !function_info->strict_mode()) {
- // Calling non-strict non-builtins with a value as the receiver
- // requires boxing.
+ if (!function->IsBuiltin()) {
+ // Calling non-builtins with a value as receiver requires boxing.
__ jmp(&miss);
} else {
Label fast;
@@ -2371,9 +2369,8 @@
}
case BOOLEAN_CHECK: {
- if (!function->IsBuiltin() && !function_info->strict_mode()) {
- // Calling non-strict non-builtins with a value as the receiver
- // requires boxing.
+ if (!function->IsBuiltin()) {
+ // Calling non-builtins with a value as receiver requires boxing.
__ jmp(&miss);
} else {
Label fast;
=======================================
--- /branches/bleeding_edge/src/ia32/stub-cache-ia32.cc Thu Feb 17 09:52:03
2011
+++ /branches/bleeding_edge/src/ia32/stub-cache-ia32.cc Thu Feb 17 13:56:37
2011
@@ -2204,9 +2204,8 @@
break;
case STRING_CHECK:
- if (!function->IsBuiltin() && !function_info->strict_mode()) {
- // Calling non-strict non-builtins with a value as the receiver
- // requires boxing.
+ if (!function->IsBuiltin()) {
+ // Calling non-builtins with a value as receiver requires boxing.
__ jmp(&miss);
} else {
// Check that the object is a string or a symbol.
@@ -2221,9 +2220,8 @@
break;
case NUMBER_CHECK: {
- if (!function->IsBuiltin() && !function_info->strict_mode()) {
- // Calling non-strict non-builtins with a value as the receiver
- // requires boxing.
+ if (!function->IsBuiltin()) {
+ // Calling non-builtins with a value as receiver requires boxing.
__ jmp(&miss);
} else {
Label fast;
@@ -2243,9 +2241,8 @@
}
case BOOLEAN_CHECK: {
- if (!function->IsBuiltin() && !function_info->strict_mode()) {
- // Calling non-strict non-builtins with a value as the receiver
- // requires boxing.
+ if (!function->IsBuiltin()) {
+ // Calling non-builtins with a value as receiver requires boxing.
__ jmp(&miss);
} else {
Label fast;
=======================================
--- /branches/bleeding_edge/src/ic.cc Thu Feb 17 09:52:03 2011
+++ /branches/bleeding_edge/src/ic.cc Thu Feb 17 13:56:37 2011
@@ -435,28 +435,16 @@
}
-void CallICBase::ReceiverToObjectIfRequired(Object* callee,
- Handle<Object> object) {
- if (callee->IsJSFunction()) {
- JSFunction* function = JSFunction::cast(callee);
- if (function->shared()->strict_mode() || function->IsBuiltin()) {
- // Do not wrap receiver for strict mode functions or for builtins.
- return;
- }
- }
-
- if (object->IsString() || object->IsNumber() || object->IsBoolean()) {
- // And only wrap string, number or boolean.
- HandleScope scope;
- Handle<Object> receiver(object);
-
- // Change the receiver to the result of calling ToObject on it.
- const int argc = this->target()->arguments_count();
- StackFrameLocator locator;
- JavaScriptFrame* frame = locator.FindJavaScriptFrame(0);
- int index = frame->ComputeExpressionsCount() - (argc + 1);
- frame->SetExpression(index, *Factory::ToObject(object));
- }
+void CallICBase::ReceiverToObject(Handle<Object> object) {
+ HandleScope scope;
+ Handle<Object> receiver(object);
+
+ // Change the receiver to the result of calling ToObject on it.
+ const int argc = this->target()->arguments_count();
+ StackFrameLocator locator;
+ JavaScriptFrame* frame = locator.FindJavaScriptFrame(0);
+ int index = frame->ComputeExpressionsCount() - (argc + 1);
+ frame->SetExpression(index, *Factory::ToObject(object));
}
@@ -469,6 +457,10 @@
if (object->IsUndefined() || object->IsNull()) {
return TypeError("non_object_property_call", object, name);
}
+
+ if (object->IsString() || object->IsNumber() || object->IsBoolean()) {
+ ReceiverToObject(object);
+ }
// Check if the name is trivially convertible to an index and get
// the element if so.
@@ -513,12 +505,6 @@
object->GetProperty(*object, &lookup, *name, &attr);
if (!maybe_result->ToObject(&result)) return maybe_result;
}
-
- // Make receiver an object if the callee requires it. Strict mode or
builtin
- // functions do not wrap the receiver, non-strict functions and objects
- // called as functions do.
- ReceiverToObjectIfRequired(result, object);
-
if (lookup.type() == INTERCEPTOR) {
// If the object does not have the requested property, check which
// exception we need to throw.
@@ -579,8 +565,8 @@
case kStringCharAt:
if (object->IsString()) {
String* string = String::cast(*object);
- // Check there's the right string value or wrapper in the receiver
slot.
- ASSERT(string == args[0] || string ==
JSValue::cast(args[0])->value());
+ // Check that there's the right wrapper in the receiver slot.
+ ASSERT(string == JSValue::cast(args[0])->value());
// If we're in the default (fastest) state and the index is
// out of bounds, update the state to record this fact.
if (*extra_ic_state == DEFAULT_STRING_STUB &&
@@ -788,6 +774,10 @@
if (object->IsUndefined() || object->IsNull()) {
return TypeError("non_object_property_call", object, key);
}
+
+ if (object->IsString() || object->IsNumber() || object->IsBoolean()) {
+ ReceiverToObject(object);
+ }
if (FLAG_use_ic && state != MEGAMORPHIC
&& !object->IsAccessCheckNeeded()) {
int argc = target()->arguments_count();
@@ -803,17 +793,10 @@
#endif
}
}
-
Object* result;
{ MaybeObject* maybe_result = Runtime::GetObjectProperty(object, key);
if (!maybe_result->ToObject(&result)) return maybe_result;
}
-
- // Make receiver an object if the callee requires it. Strict mode or
builtin
- // functions do not wrap the receiver, non-strict functions and objects
- // called as functions do.
- ReceiverToObjectIfRequired(result, object);
-
if (result->IsJSFunction()) return result;
result = TryCallAsFunction(result);
MaybeObject* answer = result;
=======================================
--- /branches/bleeding_edge/src/ic.h Thu Feb 17 09:52:03 2011
+++ /branches/bleeding_edge/src/ic.h Thu Feb 17 13:56:37 2011
@@ -224,7 +224,7 @@
// Otherwise, it returns the undefined value.
Object* TryCallAsFunction(Object* object);
- void ReceiverToObjectIfRequired(Object* callee, Handle<Object> object);
+ void ReceiverToObject(Handle<Object> object);
static void Clear(Address address, Code* target);
friend class IC;
=======================================
--- /branches/bleeding_edge/src/x64/stub-cache-x64.cc Thu Feb 17 09:52:03
2011
+++ /branches/bleeding_edge/src/x64/stub-cache-x64.cc Thu Feb 17 13:56:37
2011
@@ -2060,9 +2060,8 @@
break;
case STRING_CHECK:
- if (!function->IsBuiltin() && !function_info->strict_mode()) {
- // Calling non-strict non-builtins with a value as the receiver
- // requires boxing.
+ if (!function->IsBuiltin()) {
+ // Calling non-builtins with a value as receiver requires boxing.
__ jmp(&miss);
} else {
// Check that the object is a two-byte string or a symbol.
@@ -2077,9 +2076,8 @@
break;
case NUMBER_CHECK: {
- if (!function->IsBuiltin() && !function_info->strict_mode()) {
- // Calling non-strict non-builtins with a value as the receiver
- // requires boxing.
+ if (!function->IsBuiltin()) {
+ // Calling non-builtins with a value as receiver requires boxing.
__ jmp(&miss);
} else {
Label fast;
@@ -2098,9 +2096,8 @@
}
case BOOLEAN_CHECK: {
- if (!function->IsBuiltin() && !function_info->strict_mode()) {
- // Calling non-strict non-builtins with a value as the receiver
- // requires boxing.
+ if (!function->IsBuiltin()) {
+ // Calling non-builtins with a value as receiver requires boxing.
__ jmp(&miss);
} else {
Label fast;
=======================================
--- /branches/bleeding_edge/test/mjsunit/strict-mode.js Thu Feb 17 09:52:03
2011
+++ /branches/bleeding_edge/test/mjsunit/strict-mode.js Thu Feb 17 13:56:37
2011
@@ -438,7 +438,7 @@
})();
// Not transforming this in Function.call and Function.apply.
-(function testThisTransformCallApply() {
+(function testThisTransform() {
function non_strict() {
return this;
}
@@ -478,218 +478,3 @@
assertEquals(typeof strict.apply("Hello"), "string");
assertTrue(strict.apply(object) === object);
})();
-
-(function testThisTransform() {
- try {
- function strict() {
- "use strict";
- return typeof(this);
- }
- function nonstrict() {
- return typeof(this);
- }
-
- // Concat to avoid symbol.
- var strict_name = "str" + "ict";
- var nonstrict_name = "non" + "str" + "ict";
- var strict_number = 17;
- var nonstrict_number = 19;
- var strict_name_get = "str" + "ict" + "get";
- var nonstrict_name_get = "non" + "str" + "ict" + "get"
- var strict_number_get = 23;
- var nonstrict_number_get = 29;
-
- function install(t) {
- t.prototype.strict = strict;
- t.prototype.nonstrict = nonstrict;
- t.prototype[strict_number] = strict;
- t.prototype[nonstrict_number] = nonstrict;
- Object.defineProperty(t.prototype, strict_name_get,
- { get: function() { return strict; },
- configurable: true });
- Object.defineProperty(t.prototype, nonstrict_name_get,
- { get: function() { return nonstrict; },
- configurable: true });
- Object.defineProperty(t.prototype, strict_number_get,
- { get: function() { return strict; },
- configurable: true });
- Object.defineProperty(t.prototype, nonstrict_number_get,
- { get: function() { return nonstrict; },
- configurable: true });
- }
-
- function cleanup(t) {
- delete t.prototype.strict;
- delete t.prototype.nonstrict;
- delete t.prototype[strict_number];
- delete t.prototype[nonstrict_number];
- delete t.prototype[strict_name_get];
- delete t.prototype[nonstrict_name_get];
- delete t.prototype[strict_number_get];
- delete t.prototype[nonstrict_number_get];
- }
-
- // Set up fakes
- install(String);
- install(Number);
- install(Boolean)
-
- function callStrict(o) {
- return o.strict();
- }
- function callNonStrict(o) {
- return o.nonstrict();
- }
- function callKeyedStrict(o) {
- return o[strict_name]();
- }
- function callKeyedNonStrict(o) {
- return o[nonstrict_name]();
- }
- function callIndexedStrict(o) {
- return o[strict_number]();
- }
- function callIndexedNonStrict(o) {
- return o[nonstrict_number]();
- }
- function callStrictGet(o) {
- return o.strictget();
- }
- function callNonStrictGet(o) {
- return o.nonstrictget();
- }
- function callKeyedStrictGet(o) {
- return o[strict_name_get]();
- }
- function callKeyedNonStrictGet(o) {
- return o[nonstrict_name_get]();
- }
- function callIndexedStrictGet(o) {
- return o[strict_number_get]();
- }
- function callIndexedNonStrictGet(o) {
- return o[nonstrict_number_get]();
- }
-
- for (var i = 0; i < 10; i ++) {
- assertEquals(("hello").strict(), "string");
- assertEquals(("hello").nonstrict(), "object");
- assertEquals(("hello")[strict_name](), "string");
- assertEquals(("hello")[nonstrict_name](), "object");
- assertEquals(("hello")[strict_number](), "string");
- assertEquals(("hello")[nonstrict_number](), "object");
-
- assertEquals((10 + i).strict(), "number");
- assertEquals((10 + i).nonstrict(), "object");
- assertEquals((10 + i)[strict_name](), "number");
- assertEquals((10 + i)[nonstrict_name](), "object");
- assertEquals((10 + i)[strict_number](), "number");
- assertEquals((10 + i)[nonstrict_number](), "object");
-
- assertEquals((true).strict(), "boolean");
- assertEquals((true).nonstrict(), "object");
- assertEquals((true)[strict_name](), "boolean");
- assertEquals((true)[nonstrict_name](), "object");
- assertEquals((true)[strict_number](), "boolean");
- assertEquals((true)[nonstrict_number](), "object");
-
- assertEquals((false).strict(), "boolean");
- assertEquals((false).nonstrict(), "object");
- assertEquals((false)[strict_name](), "boolean");
- assertEquals((false)[nonstrict_name](), "object");
- assertEquals((false)[strict_number](), "boolean");
- assertEquals((false)[nonstrict_number](), "object");
-
- assertEquals(callStrict("howdy"), "string");
- assertEquals(callNonStrict("howdy"), "object");
- assertEquals(callKeyedStrict("howdy"), "string");
- assertEquals(callKeyedNonStrict("howdy"), "object");
- assertEquals(callIndexedStrict("howdy"), "string");
- assertEquals(callIndexedNonStrict("howdy"), "object");
-
- assertEquals(callStrict(17 + i), "number");
- assertEquals(callNonStrict(17 + i), "object");
- assertEquals(callKeyedStrict(17 + i), "number");
- assertEquals(callKeyedNonStrict(17 + i), "object");
- assertEquals(callIndexedStrict(17 + i), "number");
- assertEquals(callIndexedNonStrict(17 + i), "object");
-
- assertEquals(callStrict(true), "boolean");
- assertEquals(callNonStrict(true), "object");
- assertEquals(callKeyedStrict(true), "boolean");
- assertEquals(callKeyedNonStrict(true), "object");
- assertEquals(callIndexedStrict(true), "boolean");
- assertEquals(callIndexedNonStrict(true), "object");
-
- assertEquals(callStrict(false), "boolean");
- assertEquals(callNonStrict(false), "object");
- assertEquals(callKeyedStrict(false), "boolean");
- assertEquals(callKeyedNonStrict(false), "object");
- assertEquals(callIndexedStrict(false), "boolean");
- assertEquals(callIndexedNonStrict(false), "object");
-
- // All of the above, with getters
- assertEquals(("hello").strictget(), "string");
- assertEquals(("hello").nonstrictget(), "object");
- assertEquals(("hello")[strict_name_get](), "string");
- assertEquals(("hello")[nonstrict_name_get](), "object");
- assertEquals(("hello")[strict_number_get](), "string");
- assertEquals(("hello")[nonstrict_number_get](), "object");
-
- assertEquals((10 + i).strictget(), "number");
- assertEquals((10 + i).nonstrictget(), "object");
- assertEquals((10 + i)[strict_name_get](), "number");
- assertEquals((10 + i)[nonstrict_name_get](), "object");
- assertEquals((10 + i)[strict_number_get](), "number");
- assertEquals((10 + i)[nonstrict_number_get](), "object");
-
- assertEquals((true).strictget(), "boolean");
- assertEquals((true).nonstrictget(), "object");
- assertEquals((true)[strict_name_get](), "boolean");
- assertEquals((true)[nonstrict_name_get](), "object");
- assertEquals((true)[strict_number_get](), "boolean");
- assertEquals((true)[nonstrict_number_get](), "object");
-
- assertEquals((false).strictget(), "boolean");
- assertEquals((false).nonstrictget(), "object");
- assertEquals((false)[strict_name_get](), "boolean");
- assertEquals((false)[nonstrict_name_get](), "object");
- assertEquals((false)[strict_number_get](), "boolean");
- assertEquals((false)[nonstrict_number_get](), "object");
-
- assertEquals(callStrictGet("howdy"), "string");
- assertEquals(callNonStrictGet("howdy"), "object");
- assertEquals(callKeyedStrictGet("howdy"), "string");
- assertEquals(callKeyedNonStrictGet("howdy"), "object");
- assertEquals(callIndexedStrictGet("howdy"), "string");
- assertEquals(callIndexedNonStrictGet("howdy"), "object");
-
- assertEquals(callStrictGet(17 + i), "number");
- assertEquals(callNonStrictGet(17 + i), "object");
- assertEquals(callKeyedStrictGet(17 + i), "number");
- assertEquals(callKeyedNonStrictGet(17 + i), "object");
- assertEquals(callIndexedStrictGet(17 + i), "number");
- assertEquals(callIndexedNonStrictGet(17 + i), "object");
-
- assertEquals(callStrictGet(true), "boolean");
- assertEquals(callNonStrictGet(true), "object");
- assertEquals(callKeyedStrictGet(true), "boolean");
- assertEquals(callKeyedNonStrictGet(true), "object");
- assertEquals(callIndexedStrictGet(true), "boolean");
- assertEquals(callIndexedNonStrictGet(true), "object");
-
- assertEquals(callStrictGet(false), "boolean");
- assertEquals(callNonStrictGet(false), "object");
- assertEquals(callKeyedStrictGet(false), "boolean");
- assertEquals(callKeyedNonStrictGet(false), "object");
- assertEquals(callIndexedStrictGet(false), "boolean");
- assertEquals(callIndexedNonStrictGet(false), "object");
-
- }
- } finally {
- // Cleanup
- cleanup(String);
- cleanup(Number);
- cleanup(Boolean);
- }
-})();
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev