Avoid using Function.prototype.call in a number of places in our
authorager@chromium.org <ager@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 28 Jan 2011 10:33:10 +0000 (10:33 +0000)
committerager@chromium.org <ager@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 28 Jan 2011 10:33:10 +0000 (10:33 +0000)
builtins files. We should always use %_CallFunction for a couple of
reasons: it cannot be overwritten and it does not wrap basic types in
wrapper objects.

Review URL: http://codereview.chromium.org/6349018

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@6524 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/date.js
src/json.js
src/messages.js
src/mirror-debugger.js
src/regexp.js
test/cctest/test-api.cc
test/mjsunit/debug-backtrace-text.js

index 9eb607c7e5e160798354f77dc9a02b75098cc4c1..1fb4897921a91fb1d434909136e9d0034f584c29 100644 (file)
@@ -605,7 +605,7 @@ function DateToTimeString() {
 
 // ECMA 262 - 15.9.5.5
 function DateToLocaleString() {
-  return DateToString.call(this);
+  return %_CallFunction(this, DateToString);
 }
 
 
@@ -973,7 +973,7 @@ function DateSetYear(year) {
 // do that either.  Instead, we create a new function whose name
 // property will return toGMTString.
 function DateToGMTString() {
-  return DateToUTCString.call(this);
+  return %_CallFunction(this, DateToUTCString);
 }
 
 
index e90d5d1d0a47415541a461661b84f5f9d3d71ca4..e6ada51b48711c07a59f6dcf131aa6a168071718 100644 (file)
@@ -38,7 +38,7 @@ function Revive(holder, name, reviver) {
       }
     } else {
       for (var p in val) {
-        if (ObjectHasOwnProperty.call(val, p)) {
+        if (%_CallFunction(val, p, ObjectHasOwnProperty)) {
           var newElement = Revive(val, p, reviver);
           if (IS_UNDEFINED(newElement)) {
             delete val[p];
@@ -101,7 +101,7 @@ function SerializeObject(value, replacer, stack, indent, gap) {
   if (IS_ARRAY(replacer)) {
     var length = replacer.length;
     for (var i = 0; i < length; i++) {
-      if (ObjectHasOwnProperty.call(replacer, i)) {
+      if (%_CallFunction(replacer, i, ObjectHasOwnProperty)) {
         var p = replacer[i];
         var strP = JSONSerialize(p, value, replacer, stack, indent, gap);
         if (!IS_UNDEFINED(strP)) {
@@ -114,7 +114,7 @@ function SerializeObject(value, replacer, stack, indent, gap) {
     }
   } else {
     for (var p in value) {
-      if (ObjectHasOwnProperty.call(value, p)) {
+      if (%_CallFunction(value, p, ObjectHasOwnProperty)) {
         var strP = JSONSerialize(p, value, replacer, stack, indent, gap);
         if (!IS_UNDEFINED(strP)) {
           var member = %QuoteJSONString(p) + ":";
index a072d3b4738a867698d30949ab5e44b0ec5b4e7c..fcd7285ecfb769dd2590b7f468d4b0e0663c92f4 100644 (file)
@@ -50,33 +50,10 @@ var kNoLineNumberInfo = 0;
 // message on access.
 var kAddMessageAccessorsMarker = { };
 
-
-function GetInstanceName(cons) {
-  if (cons.length == 0) {
-    return "";
-  }
-  var first = %StringToLowerCase(StringCharAt.call(cons, 0));
-  if (kVowelSounds === 0) {
-    kVowelSounds = {a: true, e: true, i: true, o: true, u: true, y: true};
-    kCapitalVowelSounds = {a: true, e: true, i: true, o: true, u: true, h: true,
-        f: true, l: true, m: true, n: true, r: true, s: true, x: true, y: true};
-  }
-  var vowel_mapping = kVowelSounds;
-  if (cons.length > 1 && (StringCharAt.call(cons, 0) != first)) {
-    // First char is upper case
-    var second = %StringToLowerCase(StringCharAt.call(cons, 1));
-    // Second char is upper case
-    if (StringCharAt.call(cons, 1) != second) {
-      vowel_mapping = kCapitalVowelSounds;
-    }
-  }
-  var s = vowel_mapping[first] ? "an " : "a ";
-  return s + cons;
-}
-
-
 var kMessages = 0;
 
+var kReplacementMarkers =
+    [ "%0", "%1", "%2", "%3", "%4", "%5", "%6", "%7", "%8", "%9", "%10" ];
 
 function FormatString(format, args) {
   var result = format;
@@ -87,7 +64,9 @@ function FormatString(format, args) {
     } catch (e) {
       str = "#<error>";
     }
-    result = ArrayJoin.call(StringSplit.call(result, "%" + i), str);
+    var replacement_marker = kReplacementMarkers[i];
+    var split = %_CallFunction(result, replacement_marker, StringSplit);
+    result = %_CallFunction(split, str, ArrayJoin);
   }
   return result;
 }
@@ -130,7 +109,7 @@ function ToDetailString(obj) {
     if (!constructorName || !IS_STRING(constructorName)) {
       return ToStringCheckErrorObject(obj);
     }
-    return "#<" + GetInstanceName(constructorName) + ">";
+    return "#<" + constructorName + ">";
   } else {
     return ToStringCheckErrorObject(obj);
   }
@@ -352,7 +331,7 @@ Script.prototype.locationFromPosition = function (position,
   var line_ends = this.line_ends;
   var start = line == 0 ? 0 : line_ends[line - 1] + 1;
   var end = line_ends[line];
-  if (end > 0 && StringCharAt.call(this.source, end - 1) == '\r') end--;
+  if (end > 0 && %_CallFunction(this.source, end - 1, StringCharAt) == '\r') end--;
   var column = position - start;
 
   // Adjust according to the offset within the resource.
@@ -467,7 +446,7 @@ Script.prototype.sourceLine = function (opt_line) {
   var line_ends = this.line_ends;
   var start = line == 0 ? 0 : line_ends[line - 1] + 1;
   var end = line_ends[line];
-  return StringSubstring.call(this.source, start, end);
+  return %_CallFunction(this.source, start, end, StringSubstring);
 }
 
 
@@ -595,7 +574,7 @@ SourceLocation.prototype.restrict = function (opt_limit, opt_before) {
  *     Source text for this location.
  */
 SourceLocation.prototype.sourceText = function () {
-  return StringSubstring.call(this.script.source, this.start, this.end);
+  return %_CallFunction(this.script.source, this.start, this.end, StringSubstring);
 };
 
 
@@ -632,7 +611,10 @@ function SourceSlice(script, from_line, to_line, from_position, to_position) {
  *     the line terminating characters (if any)
  */
 SourceSlice.prototype.sourceText = function () {
-  return StringSubstring.call(this.script.source, this.from_position, this.to_position);
+  return %_CallFunction(this.script.source,
+                        this.from_position,
+                        this.to_position,
+                        StringSubstring);
 };
 
 
@@ -707,10 +689,10 @@ CallSite.prototype.getThis = function () {
 CallSite.prototype.getTypeName = function () {
   var constructor = this.receiver.constructor;
   if (!constructor)
-    return $Object.prototype.toString.call(this.receiver);
+    return %_CallFunction(this.receiver, ObjectToString);
   var constructorName = constructor.name;
   if (!constructorName)
-    return $Object.prototype.toString.call(this.receiver);
+    return %_CallFunction(this.receiver, ObjectToString);
   return constructorName;
 };
 
@@ -759,8 +741,8 @@ CallSite.prototype.getMethodName = function () {
   // this function.
   var ownName = this.fun.name;
   if (ownName && this.receiver &&
-      (ObjectLookupGetter.call(this.receiver, ownName) === this.fun ||
-       ObjectLookupSetter.call(this.receiver, ownName) === this.fun ||
+      (%_CallFunction(this.receiver, ownName, ObjectLookupGetter) === this.fun ||
+       %_CallFunction(this.receiver, ownName, ObjectLookupSetter) === this.fun ||
        this.receiver[ownName] === this.fun)) {
     // To handle DontEnum properties we guess that the method has
     // the same name as the function.
index 9177a6bc26e259a962ee17ca77eed47383a63659..80d385952b425c4033a50763279cf6d77f3491b1 100644 (file)
@@ -411,7 +411,7 @@ Mirror.prototype.allocateTransientHandle_ = function() {
 
 Mirror.prototype.toText = function() {
   // Simpel to text which is used when on specialization in subclass.
-  return "#<" + builtins.GetInstanceName(this.constructor.name) + ">";
+  return "#<" + this.constructor.name + ">";
 }
 
 
@@ -425,7 +425,7 @@ Mirror.prototype.toText = function() {
  * @extends Mirror
  */
 function ValueMirror(type, value, transient) {
-  Mirror.call(this, type);
+  %_CallFunction(this, type, Mirror);
   this.value_ = value;
   if (!transient) {
     this.allocateHandle_();
@@ -470,7 +470,7 @@ ValueMirror.prototype.value = function() {
  * @extends ValueMirror
  */
 function UndefinedMirror() {
-  ValueMirror.call(this, UNDEFINED_TYPE, void 0);
+  %_CallFunction(this, UNDEFINED_TYPE, void 0, ValueMirror);
 }
 inherits(UndefinedMirror, ValueMirror);
 
@@ -486,7 +486,7 @@ UndefinedMirror.prototype.toText = function() {
  * @extends ValueMirror
  */
 function NullMirror() {
-  ValueMirror.call(this, NULL_TYPE, null);
+  %_CallFunction(this, NULL_TYPE, null, ValueMirror);
 }
 inherits(NullMirror, ValueMirror);
 
@@ -503,7 +503,7 @@ NullMirror.prototype.toText = function() {
  * @extends ValueMirror
  */
 function BooleanMirror(value) {
-  ValueMirror.call(this, BOOLEAN_TYPE, value);
+  %_CallFunction(this, BOOLEAN_TYPE, value, ValueMirror);
 }
 inherits(BooleanMirror, ValueMirror);
 
@@ -520,7 +520,7 @@ BooleanMirror.prototype.toText = function() {
  * @extends ValueMirror
  */
 function NumberMirror(value) {
-  ValueMirror.call(this, NUMBER_TYPE, value);
+  %_CallFunction(this, NUMBER_TYPE, value, ValueMirror);
 }
 inherits(NumberMirror, ValueMirror);
 
@@ -537,7 +537,7 @@ NumberMirror.prototype.toText = function() {
  * @extends ValueMirror
  */
 function StringMirror(value) {
-  ValueMirror.call(this, STRING_TYPE, value);
+  %_CallFunction(this, STRING_TYPE, value, ValueMirror);
 }
 inherits(StringMirror, ValueMirror);
 
@@ -568,7 +568,7 @@ StringMirror.prototype.toText = function() {
  * @extends ValueMirror
  */
 function ObjectMirror(value, type, transient) {
-  ValueMirror.call(this, type || OBJECT_TYPE, value, transient);
+  %_CallFunction(this, type || OBJECT_TYPE, value, transient, ValueMirror);
 }
 inherits(ObjectMirror, ValueMirror);
 
@@ -767,7 +767,7 @@ ObjectMirror.prototype.toText = function() {
       name = this.className();
     }
   }
-  return '#<' + builtins.GetInstanceName(name) + '>';
+  return '#<' + name + '>';
 };
 
 
@@ -778,7 +778,7 @@ ObjectMirror.prototype.toText = function() {
  * @extends ObjectMirror
  */
 function FunctionMirror(value) {
-  ObjectMirror.call(this, value, FUNCTION_TYPE);
+  %_CallFunction(this, value, FUNCTION_TYPE, ObjectMirror);
   this.resolved_ = true;
 }
 inherits(FunctionMirror, ObjectMirror);
@@ -908,7 +908,7 @@ FunctionMirror.prototype.toText = function() {
 function UnresolvedFunctionMirror(value) {
   // Construct this using the ValueMirror as an unresolved function is not a
   // real object but just a string.
-  ValueMirror.call(this, FUNCTION_TYPE, value);
+  %_CallFunction(this, FUNCTION_TYPE, value, ValueMirror);
   this.propertyCount_ = 0;
   this.elementCount_ = 0;
   this.resolved_ = false;
@@ -958,7 +958,7 @@ UnresolvedFunctionMirror.prototype.propertyNames = function(kind, limit) {
  * @extends ObjectMirror
  */
 function ArrayMirror(value) {
-  ObjectMirror.call(this, value);
+  %_CallFunction(this, value, ObjectMirror);
 }
 inherits(ArrayMirror, ObjectMirror);
 
@@ -994,7 +994,7 @@ ArrayMirror.prototype.indexedPropertiesFromRange = function(opt_from_index, opt_
  * @extends ObjectMirror
  */
 function DateMirror(value) {
-  ObjectMirror.call(this, value);
+  %_CallFunction(this, value, ObjectMirror);
 }
 inherits(DateMirror, ObjectMirror);
 
@@ -1012,7 +1012,7 @@ DateMirror.prototype.toText = function() {
  * @extends ObjectMirror
  */
 function RegExpMirror(value) {
-  ObjectMirror.call(this, value, REGEXP_TYPE);
+  %_CallFunction(this, value, REGEXP_TYPE, ObjectMirror);
 }
 inherits(RegExpMirror, ObjectMirror);
 
@@ -1066,7 +1066,7 @@ RegExpMirror.prototype.toText = function() {
  * @extends ObjectMirror
  */
 function ErrorMirror(value) {
-  ObjectMirror.call(this, value, ERROR_TYPE);
+  %_CallFunction(this, value, ERROR_TYPE, ObjectMirror);
 }
 inherits(ErrorMirror, ObjectMirror);
 
@@ -1101,7 +1101,7 @@ ErrorMirror.prototype.toText = function() {
  * @extends Mirror
  */
 function PropertyMirror(mirror, name, details) {
-  Mirror.call(this, PROPERTY_TYPE);
+  %_CallFunction(this, PROPERTY_TYPE, Mirror);
   this.mirror_ = mirror;
   this.name_ = name;
   this.value_ = details[0];
@@ -1397,7 +1397,7 @@ FrameDetails.prototype.scopeCount = function() {
  * @extends Mirror
  */
 function FrameMirror(break_id, index) {
-  Mirror.call(this, FRAME_TYPE);
+  %_CallFunction(this, FRAME_TYPE, Mirror);
   this.break_id_ = break_id;
   this.index_ = index;
   this.details_ = new FrameDetails(break_id, index);
@@ -1712,7 +1712,7 @@ ScopeDetails.prototype.object = function() {
  * @extends Mirror
  */
 function ScopeMirror(frame, index) {
-  Mirror.call(this, SCOPE_TYPE);
+  %_CallFunction(this, SCOPE_TYPE, Mirror);
   this.frame_index_ = frame.index_;
   this.scope_index_ = index;
   this.details_ = new ScopeDetails(frame, index);
@@ -1752,7 +1752,7 @@ ScopeMirror.prototype.scopeObject = function() {
  * @extends Mirror
  */
 function ScriptMirror(script) {
-  Mirror.call(this, SCRIPT_TYPE);
+  %_CallFunction(this, SCRIPT_TYPE, Mirror);
   this.script_ = script;
   this.context_ = new ContextMirror(script.context_data);
   this.allocateHandle_();
@@ -1868,7 +1868,7 @@ ScriptMirror.prototype.toText = function() {
  * @extends Mirror
  */
 function ContextMirror(data) {
-  Mirror.call(this, CONTEXT_TYPE);
+  %_CallFunction(this, CONTEXT_TYPE, Mirror);
   this.data_ = data;
   this.allocateHandle_();
 }
index 0de66c644ed4fcfcd94d4826d700e24b7a6f7976..5b7e3a9d2f80563889c95d9b04b8306c4bb7936d 100644 (file)
@@ -52,7 +52,7 @@ function DoConstructRegExp(object, pattern, flags) {
   var multiline = false;
 
   for (var i = 0; i < flags.length; i++) {
-    var c = StringCharAt.call(flags, i);
+    var c = %_CallFunction(flags, i, StringCharAt);
     switch (c) {
       case 'g':
         // Allow duplicate flags to be consistent with JSC and others.
index 48dc72e7b3d8fc1159ccbb294cffed54996081ef..e06062b2ed4c46d4a6f8e23b64a09be49f6eccd2 100644 (file)
@@ -2376,6 +2376,8 @@ TEST(APIThrowMessageOverwrittenToString) {
   v8::HandleScope scope;
   v8::V8::AddMessageListener(check_reference_error_message);
   LocalContext context;
+  CompileRun("Number.prototype.toString = function f() { return 'Yikes'; }");
+  CompileRun("String.prototype.toString = function f() { return 'Yikes'; }");
   CompileRun("ReferenceError.prototype.toString ="
              "  function() { return 'Whoops' }");
   CompileRun("asdf;");
@@ -6246,7 +6248,7 @@ THREADED_TEST(FunctionDescriptorException) {
     "    var str = String(e);"
     "    if (str.indexOf('TypeError') == -1) return 1;"
     "    if (str.indexOf('[object Fun]') != -1) return 2;"
-    "    if (str.indexOf('#<Fun>') == -1) return 3;"
+    "    if (str.indexOf('#<Fun>') == -1) return 3;"
     "    return 0;"
     "  }"
     "  return 4;"
index 67c674667b7e43cbdd8b9205e581eb3c2fd4d039..61648fa4e2e6ee4e8554556db02e18acd93fe0b1 100644 (file)
@@ -80,9 +80,9 @@ function listener(event, exec_state, event_data, data) {
       // 1: Call distance on Point where distance is a direct property
       // 2: Call on function an array element 2
       // 3: [anonymous]
-      assertEquals("#<a Point>.distanceTo(p=#<a Point>)", exec_state.frame(0).invocationText());
-      assertEquals("#<a Point>.distanceTo(p=#<a Point>)", exec_state.frame(1).invocationText());
-      assertEquals("#<an Array>[2](aka distance)(p=#<a Point>, q=#<a Point>)", exec_state.frame(2).invocationText());
+      assertEquals("#<Point>.distanceTo(p=#<Point>)", exec_state.frame(0).invocationText());
+      assertEquals("#<Point>.distanceTo(p=#<Point>)", exec_state.frame(1).invocationText());
+      assertEquals("#<Array>[2](aka distance)(p=#<Point>, q=#<Point>)", exec_state.frame(2).invocationText());
       assertEquals("[anonymous]()", exec_state.frame(3).invocationText());
       listenerCalled = true;
     } else {