Hide RegExp and String initialization in a closure.
authoryangguo <yangguo@chromium.org>
Thu, 12 Mar 2015 14:47:35 +0000 (07:47 -0700)
committerCommit bot <commit-bot@chromium.org>
Thu, 12 Mar 2015 14:47:49 +0000 (14:47 +0000)
R=jkummerow@chromium.org

Review URL: https://codereview.chromium.org/1000063002

Cr-Commit-Position: refs/heads/master@{#27161}

src/api.cc
src/i18n.js
src/math.js
src/messages.js
src/regexp.js
src/snapshot-common.cc
src/string-iterator.js
src/string.js
src/third_party/fdlibm/fdlibm.js
src/v8natives.js

index e26f833..d55050a 100644 (file)
@@ -328,6 +328,8 @@ void V8::SetSnapshotDataBlob(StartupData* snapshot_blob) {
 
 bool RunExtraCode(Isolate* isolate, const char* utf8_source) {
   // Run custom script if provided.
+  base::ElapsedTimer timer;
+  timer.Start();
   TryCatch try_catch;
   Local<String> source_string = String::NewFromUtf8(isolate, utf8_source);
   if (try_catch.HasCaught()) return false;
@@ -336,6 +338,11 @@ bool RunExtraCode(Isolate* isolate, const char* utf8_source) {
   Local<Script> script = ScriptCompiler::Compile(isolate, &source);
   if (try_catch.HasCaught()) return false;
   script->Run();
+  if (i::FLAG_profile_deserialization) {
+    i::PrintF("Executing custom snapshot script took %0.3f ms\n",
+              timer.Elapsed().InMillisecondsF());
+  }
+  timer.Stop();
   return !try_catch.HasCaught();
 }
 
@@ -345,6 +352,8 @@ StartupData V8::CreateSnapshotDataBlob(const char* custom_source) {
   Isolate* isolate = reinterpret_cast<Isolate*>(internal_isolate);
   StartupData result = {NULL, 0};
   {
+    base::ElapsedTimer timer;
+    timer.Start();
     Isolate::Scope isolate_scope(isolate);
     internal_isolate->Init(NULL);
     Persistent<Context> context;
@@ -384,6 +393,11 @@ StartupData V8::CreateSnapshotDataBlob(const char* custom_source) {
 
       result = i::Snapshot::CreateSnapshotBlob(ser, context_ser, metadata);
     }
+    if (i::FLAG_profile_deserialization) {
+      i::PrintF("Creating snapshot took %0.3f ms\n",
+                timer.Elapsed().InMillisecondsF());
+    }
+    timer.Stop();
   }
   isolate->Dispose();
   return result;
index 47f83ef..c743cad 100644 (file)
@@ -15,6 +15,8 @@
 %CheckIsBootstrapping();
 
 var GlobalDate = global.Date;
+var GlobalRegExp = global.RegExp;
+var GlobalString = global.String;
 
 var undefined = global.undefined;
 
@@ -54,7 +56,7 @@ var UNICODE_EXTENSION_RE = undefined;
 
 function GetUnicodeExtensionRE() {
   if (UNICODE_EXTENSION_RE === undefined) {
-    UNICODE_EXTENSION_RE = new $RegExp('-u(-[a-z0-9]{2,8})+', 'g');
+    UNICODE_EXTENSION_RE = new GlobalRegExp('-u(-[a-z0-9]{2,8})+', 'g');
   }
   return UNICODE_EXTENSION_RE;
 }
@@ -66,7 +68,7 @@ var ANY_EXTENSION_RE = undefined;
 
 function GetAnyExtensionRE() {
   if (ANY_EXTENSION_RE === undefined) {
-    ANY_EXTENSION_RE = new $RegExp('-[a-z0-9]{1}-.*', 'g');
+    ANY_EXTENSION_RE = new GlobalRegExp('-[a-z0-9]{1}-.*', 'g');
   }
   return ANY_EXTENSION_RE;
 }
@@ -78,7 +80,7 @@ var QUOTED_STRING_RE = undefined;
 
 function GetQuotedStringRE() {
   if (QUOTED_STRING_RE === undefined) {
-    QUOTED_STRING_RE = new $RegExp("'[^']+'", 'g');
+    QUOTED_STRING_RE = new GlobalRegExp("'[^']+'", 'g');
   }
   return QUOTED_STRING_RE;
 }
@@ -91,7 +93,7 @@ var SERVICE_RE = undefined;
 function GetServiceRE() {
   if (SERVICE_RE === undefined) {
     SERVICE_RE =
-        new $RegExp('^(collator|numberformat|dateformat|breakiterator)$');
+        new GlobalRegExp('^(collator|numberformat|dateformat|breakiterator)$');
   }
   return SERVICE_RE;
 }
@@ -141,7 +143,7 @@ var TIMEZONE_NAME_CHECK_RE = undefined;
 function GetTimezoneNameCheckRE() {
   if (TIMEZONE_NAME_CHECK_RE === undefined) {
     TIMEZONE_NAME_CHECK_RE =
-        new $RegExp('^([A-Za-z]+)/([A-Za-z]+)(?:_([A-Za-z]+))*$');
+        new GlobalRegExp('^([A-Za-z]+)/([A-Za-z]+)(?:_([A-Za-z]+))*$');
   }
   return TIMEZONE_NAME_CHECK_RE;
 }
@@ -289,7 +291,7 @@ function supportedLocalesOf(service, locales, options) {
 
   var matcher = options.localeMatcher;
   if (matcher !== undefined) {
-    matcher = $String(matcher);
+    matcher = GlobalString(matcher);
     if (matcher !== 'lookup' && matcher !== 'best fit') {
       throw new $RangeError('Illegal value for localeMatcher:' + matcher);
     }
@@ -375,7 +377,7 @@ function getGetOption(options, caller) {
           value = $Boolean(value);
           break;
         case 'string':
-          value = $String(value);
+          value = GlobalString(value);
           break;
         case 'number':
           value = $Number(value);
@@ -531,7 +533,7 @@ function setOptions(inOptions, extensionMap, keyValues, getOption, outOptions) {
   var extension = '';
 
   var updateExtension = function updateExtension(key, value) {
-    return '-' + key + '-' + $String(value);
+    return '-' + key + '-' + GlobalString(value);
   }
 
   var updateProperty = function updateProperty(property, type, value) {
@@ -620,7 +622,7 @@ function getOptimalLanguageTag(original, resolved) {
   }
 
   // Preserve extensions of resolved locale, but swap base tags with original.
-  var resolvedBase = new $RegExp('^' + locales[1].base);
+  var resolvedBase = new GlobalRegExp('^' + locales[1].base);
   return resolved.replace(resolvedBase, locales[0].base);
 }
 
@@ -710,7 +712,7 @@ function canonicalizeLanguageTag(localeID) {
     throw new $TypeError('Language ID should be string or object.');
   }
 
-  var localeString = $String(localeID);
+  var localeString = GlobalString(localeID);
 
   if (isValidLanguageTag(localeString) === false) {
     throw new $RangeError('Invalid language tag: ' + localeString);
@@ -839,12 +841,12 @@ function BuildLanguageTagREs() {
   var privateUse = '(x(-' + alphanum + '{1,8})+)';
 
   var singleton = '(' + digit + '|[A-WY-Za-wy-z])';
-  LANGUAGE_SINGLETON_RE = new $RegExp('^' + singleton + '$', 'i');
+  LANGUAGE_SINGLETON_RE = new GlobalRegExp('^' + singleton + '$', 'i');
 
   var extension = '(' + singleton + '(-' + alphanum + '{2,8})+)';
 
   var variant = '(' + alphanum + '{5,8}|(' + digit + alphanum + '{3}))';
-  LANGUAGE_VARIANT_RE = new $RegExp('^' + variant + '$', 'i');
+  LANGUAGE_VARIANT_RE = new GlobalRegExp('^' + variant + '$', 'i');
 
   var region = '(' + alpha + '{2}|' + digit + '{3})';
   var script = '(' + alpha + '{4})';
@@ -856,7 +858,7 @@ function BuildLanguageTagREs() {
 
   var languageTag =
       '^(' + langTag + '|' + privateUse + '|' + grandfathered + ')$';
-  LANGUAGE_TAG_RE = new $RegExp(languageTag, 'i');
+  LANGUAGE_TAG_RE = new GlobalRegExp(languageTag, 'i');
 }
 
 /**
@@ -1029,7 +1031,7 @@ function initializeCollator(collator, locales, options) {
  */
 function compare(collator, x, y) {
   return %InternalCompare(%GetImplFromInitializedIntlObject(collator),
-                          $String(x), $String(y));
+                          GlobalString(x), GlobalString(y));
 };
 
 
@@ -1282,7 +1284,7 @@ function formatNumber(formatter, value) {
  */
 function parseNumber(formatter, value) {
   return %InternalNumberParse(%GetImplFromInitializedIntlObject(formatter),
-                              $String(value));
+                              GlobalString(value));
 }
 
 
@@ -1686,7 +1688,7 @@ function formatDate(formatter, dateValue) {
  */
 function parseDate(formatter, value) {
   return %InternalDateParse(%GetImplFromInitializedIntlObject(formatter),
-                            $String(value));
+                            GlobalString(value));
 }
 
 
@@ -1847,7 +1849,7 @@ function initializeBreakIterator(iterator, locales, options) {
  */
 function adoptText(iterator, text) {
   %BreakIteratorAdoptText(%GetImplFromInitializedIntlObject(iterator),
-                          $String(text));
+                          GlobalString(text));
 }
 
 
@@ -1930,7 +1932,7 @@ function cachedOrNewService(service, locales, options, defaults) {
  * Compares this and that, and returns less than 0, 0 or greater than 0 value.
  * Overrides the built-in method.
  */
-OverrideFunction($String.prototype, 'localeCompare', function(that) {
+OverrideFunction(GlobalString.prototype, 'localeCompare', function(that) {
     if (%_IsConstructCall()) {
       throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR);
     }
@@ -1954,14 +1956,14 @@ OverrideFunction($String.prototype, 'localeCompare', function(that) {
  * If the form is not one of "NFC", "NFD", "NFKC", or "NFKD", then throw
  * a RangeError Exception.
  */
-OverrideFunction($String.prototype, 'normalize', function(that) {
+OverrideFunction(GlobalString.prototype, 'normalize', function(that) {
     if (%_IsConstructCall()) {
       throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR);
     }
 
     CHECK_OBJECT_COERCIBLE(this, "String.prototype.normalize");
 
-    var form = $String(%_Arguments(0) || 'NFC');
+    var form = GlobalString(%_Arguments(0) || 'NFC');
 
     var normalizationForm = NORMALIZATION_FORMS.indexOf(form);
     if (normalizationForm === -1) {
index 6b51593..d7e5f94 100644 (file)
@@ -2,13 +2,6 @@
 // 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 $Object = global.Object;
-
-// Instance class name can only be set on functions. That is the only
-// purpose for MathConstructor.
-
 var rngstate;  // Initialized to a Uint32Array during genesis.
 
 var $abs;
@@ -17,12 +10,17 @@ var $floor;
 var $max;
 var $min;
 
-// -------------------------------------------------------------------
-
 (function() {
 
 "use strict";
 
+%CheckIsBootstrapping();
+
+var GlobalObject = global.Object;
+var GlobalArray = global.Array;
+
+//-------------------------------------------------------------------
+
 // ECMA 262 - 15.8.2.1
 function MathAbs(x) {
   if (%_IsSmi(x)) return x >= 0 ? x : -x;
@@ -293,20 +291,20 @@ function CubeRoot(x) {
 
 // -------------------------------------------------------------------
 
-%CheckIsBootstrapping();
-
+// Instance class name can only be set on functions. That is the only
+// purpose for MathConstructor.
 function MathConstructor() {}
 
 var Math = new MathConstructor();
 
-%InternalSetPrototype(Math, $Object.prototype);
+%InternalSetPrototype(Math, GlobalObject.prototype);
 %AddNamedProperty(global, "Math", Math, DONT_ENUM);
 %FunctionSetInstanceClassName(MathConstructor, 'Math');
 
 %AddNamedProperty(Math, symbolToStringTag, "Math", READ_ONLY | DONT_ENUM);
 
 // Set up math constants.
-InstallConstants(Math, $Array(
+InstallConstants(Math, GlobalArray(
   // ECMA-262, section 15.8.1.1.
   "E", 2.7182818284590452354,
   // ECMA-262, section 15.8.1.2.
@@ -323,7 +321,7 @@ InstallConstants(Math, $Array(
 
 // Set up non-enumerable functions of the Math object and
 // set their names.
-InstallFunctions(Math, DONT_ENUM, $Array(
+InstallFunctions(Math, DONT_ENUM, GlobalArray(
   "random", MathRandom,
   "abs", MathAbs,
   "acos", MathAcosJS,
index f0e71d9..07d6719 100644 (file)
@@ -442,7 +442,7 @@ function ScriptLocationFromPosition(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 && %_CallFunction(this.source, end - 1, StringCharAt) == '\r') {
+  if (end > 0 && %_CallFunction(this.source, end - 1, $stringCharAt) == '\r') {
     end--;
   }
   var column = position - start;
@@ -565,7 +565,7 @@ function ScriptSourceLine(opt_line) {
   var line_ends = this.line_ends;
   var start = line == 0 ? 0 : line_ends[line - 1] + 1;
   var end = line_ends[line];
-  return %_CallFunction(this.source, start, end, StringSubstring);
+  return %_CallFunction(this.source, start, end, $stringSubstring);
 }
 
 
@@ -707,7 +707,7 @@ function SourceLocationSourceText() {
   return %_CallFunction(this.script.source,
                         this.start,
                         this.end,
-                        StringSubstring);
+                        $stringSubstring);
 }
 
 
@@ -755,7 +755,7 @@ function SourceSliceSourceText() {
   return %_CallFunction(this.script.source,
                         this.from_position,
                         this.to_position,
-                        StringSubstring);
+                        $stringSubstring);
 }
 
 SetUpLockedPrototype(SourceSlice,
@@ -969,12 +969,12 @@ function CallSiteToString() {
     var methodName = this.getMethodName();
     if (functionName) {
       if (typeName &&
-          %_CallFunction(functionName, typeName, StringIndexOfJS) != 0) {
+          %_CallFunction(functionName, typeName, $stringIndexOf) != 0) {
         line += typeName + ".";
       }
       line += functionName;
       if (methodName &&
-          (%_CallFunction(functionName, "." + methodName, StringIndexOfJS) !=
+          (%_CallFunction(functionName, "." + methodName, $stringIndexOf) !=
            functionName.length - methodName.length - 1)) {
         line += " [as " + methodName + "]";
       }
index 416f586..140f779 100644 (file)
@@ -2,12 +2,37 @@
 // 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 declaration has been made
-// in runtime.js:
-// var $Object = global.Object;
-// var $Array = global.Array;
+var $regexpExec;
+var $regexpExecNoTests;
+var $regexpLastMatchInfo;
+var $regexpLastMatchInfoOverride;
 
-var $RegExp = global.RegExp;
+(function() {
+
+%CheckIsBootstrapping();
+
+var GlobalRegExp = global.RegExp;
+var GlobalArray = global.Array;
+
+// Property of the builtins object for recording the result of the last
+// regexp match.  The property $regexpLastMatchInfo includes the matchIndices
+// array of the last successful regexp match (an array of start/end index
+// pairs for the match and all the captured substrings), the invariant is
+// that there are at least two capture indeces.  The array also contains
+// the subject string for the last successful match.
+$regexpLastMatchInfo = new InternalPackedArray(
+ 2,                 // REGEXP_NUMBER_OF_CAPTURES
+ "",                // Last subject.
+ UNDEFINED,         // Last input - settable with RegExpSetInput.
+ 0,                 // REGEXP_FIRST_CAPTURE + 0
+ 0                  // REGEXP_FIRST_CAPTURE + 1
+);
+
+// Override last match info with an array of actual substrings.
+// Used internally by replace regexp with function.
+// The array has the format of an "apply" argument for a replacement
+// function.
+$regexpLastMatchInfoOverride = null;
 
 // -------------------------------------------------------------------
 
@@ -44,7 +69,7 @@ function RegExpConstructor(pattern, flags) {
     if (IS_REGEXP(pattern) && IS_UNDEFINED(flags)) {
       return pattern;
     }
-    return new $RegExp(pattern, flags);
+    return new GlobalRegExp(pattern, flags);
   }
 }
 
@@ -60,7 +85,7 @@ function RegExpCompileJS(pattern, flags) {
   // RegExp.prototype.compile and in the constructor, where they are
   // the empty string.  For compatibility with JSC, we match their
   // behavior.
-  if (this == $RegExp.prototype) {
+  if (this == GlobalRegExp.prototype) {
     // We don't allow recompiling RegExp.prototype.
     throw MakeTypeError('incompatible_method_receiver',
                         ['RegExp.prototype.compile', this]);
@@ -74,8 +99,8 @@ function RegExpCompileJS(pattern, flags) {
 
 
 function DoRegExpExec(regexp, string, index) {
-  var result = %_RegExpExec(regexp, string, index, lastMatchInfo);
-  if (result !== null) lastMatchInfoOverride = null;
+  var result = %_RegExpExec(regexp, string, index, $regexpLastMatchInfo);
+  if (result !== null) $regexpLastMatchInfoOverride = null;
   return result;
 }
 
@@ -108,9 +133,9 @@ endmacro
 
 function RegExpExecNoTests(regexp, string, start) {
   // Must be called with RegExp, string and positive integer as arguments.
-  var matchInfo = %_RegExpExec(regexp, string, start, lastMatchInfo);
+  var matchInfo = %_RegExpExec(regexp, string, start, $regexpLastMatchInfo);
   if (matchInfo !== null) {
-    lastMatchInfoOverride = null;
+    $regexpLastMatchInfoOverride = null;
     RETURN_NEW_RESULT_FROM_MATCH_INFO(matchInfo, string);
   }
   regexp.lastIndex = 0;
@@ -141,8 +166,8 @@ function RegExpExec(string) {
     i = 0;
   }
 
-  // matchIndices is either null or the lastMatchInfo array.
-  var matchIndices = %_RegExpExec(this, string, i, lastMatchInfo);
+  // matchIndices is either null or the $regexpLastMatchInfo array.
+  var matchIndices = %_RegExpExec(this, string, i, $regexpLastMatchInfo);
 
   if (IS_NULL(matchIndices)) {
     this.lastIndex = 0;
@@ -150,9 +175,9 @@ function RegExpExec(string) {
   }
 
   // Successful match.
-  lastMatchInfoOverride = null;
+  $regexpLastMatchInfoOverride = null;
   if (updateLastIndex) {
-    this.lastIndex = lastMatchInfo[CAPTURE1];
+    this.lastIndex = $regexpLastMatchInfo[CAPTURE1];
   }
   RETURN_NEW_RESULT_FROM_MATCH_INFO(matchIndices, string);
 }
@@ -184,14 +209,14 @@ function RegExpTest(string) {
       this.lastIndex = 0;
       return false;
     }
-    // matchIndices is either null or the lastMatchInfo array.
-    var matchIndices = %_RegExpExec(this, string, i, lastMatchInfo);
+    // matchIndices is either null or the $regexpLastMatchInfo array.
+    var matchIndices = %_RegExpExec(this, string, i, $regexpLastMatchInfo);
     if (IS_NULL(matchIndices)) {
       this.lastIndex = 0;
       return false;
     }
-    lastMatchInfoOverride = null;
-    this.lastIndex = lastMatchInfo[CAPTURE1];
+    $regexpLastMatchInfoOverride = null;
+    this.lastIndex = $regexpLastMatchInfo[CAPTURE1];
     return true;
   } else {
     // Non-global, non-sticky regexp.
@@ -205,13 +230,13 @@ function RegExpTest(string) {
         %_StringCharCodeAt(regexp.source, 2) != 63) {  // '?'
       regexp = TrimRegExp(regexp);
     }
-    // matchIndices is either null or the lastMatchInfo array.
-    var matchIndices = %_RegExpExec(regexp, string, 0, lastMatchInfo);
+    // matchIndices is either null or the $regexpLastMatchInfo array.
+    var matchIndices = %_RegExpExec(regexp, string, 0, $regexpLastMatchInfo);
     if (IS_NULL(matchIndices)) {
       this.lastIndex = 0;
       return false;
     }
-    lastMatchInfoOverride = null;
+    $regexpLastMatchInfoOverride = null;
     return true;
   }
 }
@@ -220,9 +245,9 @@ function TrimRegExp(regexp) {
   if (!%_ObjectEquals(regexp_key, regexp)) {
     regexp_key = regexp;
     regexp_val =
-      new $RegExp(%_SubString(regexp.source, 2, regexp.source.length),
-                  (regexp.ignoreCase ? regexp.multiline ? "im" : "i"
-                                     : regexp.multiline ? "m" : ""));
+      new GlobalRegExp(%_SubString(regexp.source, 2, regexp.source.length),
+                       (regexp.ignoreCase ? regexp.multiline ? "im" : "i"
+                                          : regexp.multiline ? "m" : ""));
   }
   return regexp_val;
 }
@@ -248,30 +273,30 @@ function RegExpToString() {
 // on the captures array of the last successful match and the subject string
 // of the last successful match.
 function RegExpGetLastMatch() {
-  if (lastMatchInfoOverride !== null) {
-    return OVERRIDE_MATCH(lastMatchInfoOverride);
+  if ($regexpLastMatchInfoOverride !== null) {
+    return OVERRIDE_MATCH($regexpLastMatchInfoOverride);
   }
-  var regExpSubject = LAST_SUBJECT(lastMatchInfo);
+  var regExpSubject = LAST_SUBJECT($regexpLastMatchInfo);
   return %_SubString(regExpSubject,
-                     lastMatchInfo[CAPTURE0],
-                     lastMatchInfo[CAPTURE1]);
+                     $regexpLastMatchInfo[CAPTURE0],
+                     $regexpLastMatchInfo[CAPTURE1]);
 }
 
 
 function RegExpGetLastParen() {
-  if (lastMatchInfoOverride) {
-    var override = lastMatchInfoOverride;
+  if ($regexpLastMatchInfoOverride) {
+    var override = $regexpLastMatchInfoOverride;
     if (override.length <= 3) return '';
     return override[override.length - 3];
   }
-  var length = NUMBER_OF_CAPTURES(lastMatchInfo);
+  var length = NUMBER_OF_CAPTURES($regexpLastMatchInfo);
   if (length <= 2) return '';  // There were no captures.
   // We match the SpiderMonkey behavior: return the substring defined by the
   // last pair (after the first pair) of elements of the capture array even if
   // it is empty.
-  var regExpSubject = LAST_SUBJECT(lastMatchInfo);
-  var start = lastMatchInfo[CAPTURE(length - 2)];
-  var end = lastMatchInfo[CAPTURE(length - 1)];
+  var regExpSubject = LAST_SUBJECT($regexpLastMatchInfo);
+  var start = $regexpLastMatchInfo[CAPTURE(length - 2)];
+  var end = $regexpLastMatchInfo[CAPTURE(length - 1)];
   if (start != -1 && end != -1) {
     return %_SubString(regExpSubject, start, end);
   }
@@ -282,11 +307,11 @@ function RegExpGetLastParen() {
 function RegExpGetLeftContext() {
   var start_index;
   var subject;
-  if (!lastMatchInfoOverride) {
-    start_index = lastMatchInfo[CAPTURE0];
-    subject = LAST_SUBJECT(lastMatchInfo);
+  if (!$regexpLastMatchInfoOverride) {
+    start_index = $regexpLastMatchInfo[CAPTURE0];
+    subject = LAST_SUBJECT($regexpLastMatchInfo);
   } else {
-    var override = lastMatchInfoOverride;
+    var override = $regexpLastMatchInfoOverride;
     start_index = OVERRIDE_POS(override);
     subject = OVERRIDE_SUBJECT(override);
   }
@@ -297,11 +322,11 @@ function RegExpGetLeftContext() {
 function RegExpGetRightContext() {
   var start_index;
   var subject;
-  if (!lastMatchInfoOverride) {
-    start_index = lastMatchInfo[CAPTURE1];
-    subject = LAST_SUBJECT(lastMatchInfo);
+  if (!$regexpLastMatchInfoOverride) {
+    start_index = $regexpLastMatchInfo[CAPTURE1];
+    subject = LAST_SUBJECT($regexpLastMatchInfo);
   } else {
-    var override = lastMatchInfoOverride;
+    var override = $regexpLastMatchInfoOverride;
     subject = OVERRIDE_SUBJECT(override);
     var match = OVERRIDE_MATCH(override);
     start_index = OVERRIDE_POS(override) + match.length;
@@ -314,126 +339,106 @@ function RegExpGetRightContext() {
 // successful match, or ''.  The function RegExpMakeCaptureGetter will be
 // called with indices from 1 to 9.
 function RegExpMakeCaptureGetter(n) {
-  return function() {
-    if (lastMatchInfoOverride) {
-      if (n < lastMatchInfoOverride.length - 2) {
-        return OVERRIDE_CAPTURE(lastMatchInfoOverride, n);
+  return function foo() {
+    if ($regexpLastMatchInfoOverride) {
+      if (n < $regexpLastMatchInfoOverride.length - 2) {
+        return OVERRIDE_CAPTURE($regexpLastMatchInfoOverride, n);
       }
       return '';
     }
     var index = n * 2;
-    if (index >= NUMBER_OF_CAPTURES(lastMatchInfo)) return '';
-    var matchStart = lastMatchInfo[CAPTURE(index)];
-    var matchEnd = lastMatchInfo[CAPTURE(index + 1)];
+    if (index >= NUMBER_OF_CAPTURES($regexpLastMatchInfo)) return '';
+    var matchStart = $regexpLastMatchInfo[CAPTURE(index)];
+    var matchEnd = $regexpLastMatchInfo[CAPTURE(index + 1)];
     if (matchStart == -1 || matchEnd == -1) return '';
-    return %_SubString(LAST_SUBJECT(lastMatchInfo), matchStart, matchEnd);
+    return %_SubString(LAST_SUBJECT($regexpLastMatchInfo), matchStart, matchEnd);
   };
 }
 
-
-// Property of the builtins object for recording the result of the last
-// regexp match.  The property lastMatchInfo includes the matchIndices
-// array of the last successful regexp match (an array of start/end index
-// pairs for the match and all the captured substrings), the invariant is
-// that there are at least two capture indeces.  The array also contains
-// the subject string for the last successful match.
-var lastMatchInfo = new InternalPackedArray(
-    2,                 // REGEXP_NUMBER_OF_CAPTURES
-    "",                // Last subject.
-    UNDEFINED,         // Last input - settable with RegExpSetInput.
-    0,                 // REGEXP_FIRST_CAPTURE + 0
-    0                  // REGEXP_FIRST_CAPTURE + 1
-);
-
-// Override last match info with an array of actual substrings.
-// Used internally by replace regexp with function.
-// The array has the format of an "apply" argument for a replacement
-// function.
-var lastMatchInfoOverride = null;
-
 // -------------------------------------------------------------------
 
-function SetUpRegExp() {
-  %CheckIsBootstrapping();
-  %FunctionSetInstanceClassName($RegExp, 'RegExp');
-  %AddNamedProperty($RegExp.prototype, 'constructor', $RegExp, DONT_ENUM);
-  %SetCode($RegExp, RegExpConstructor);
-
-  InstallFunctions($RegExp.prototype, DONT_ENUM, $Array(
-    "exec", RegExpExec,
-    "test", RegExpTest,
-    "toString", RegExpToString,
-    "compile", RegExpCompileJS
-  ));
-
-  // The length of compile is 1 in SpiderMonkey.
-  %FunctionSetLength($RegExp.prototype.compile, 1);
-
-  // The properties `input` and `$_` are aliases for each other.  When this
-  // value is set the value it is set to is coerced to a string.
-  // Getter and setter for the input.
-  var RegExpGetInput = function() {
-    var regExpInput = LAST_INPUT(lastMatchInfo);
-    return IS_UNDEFINED(regExpInput) ? "" : regExpInput;
-  };
-  var RegExpSetInput = function(string) {
-    LAST_INPUT(lastMatchInfo) = ToString(string);
-  };
-
-  %OptimizeObjectForAddingMultipleProperties($RegExp, 22);
-  %DefineAccessorPropertyUnchecked($RegExp, 'input', RegExpGetInput,
-                                   RegExpSetInput, DONT_DELETE);
-  %DefineAccessorPropertyUnchecked($RegExp, '$_', RegExpGetInput,
-                                   RegExpSetInput, DONT_ENUM | DONT_DELETE);
-
-  // The properties multiline and $* are aliases for each other.  When this
-  // value is set in SpiderMonkey, the value it is set to is coerced to a
-  // boolean.  We mimic that behavior with a slight difference: in SpiderMonkey
-  // the value of the expression 'RegExp.multiline = null' (for instance) is the
-  // boolean false (i.e., the value after coercion), while in V8 it is the value
-  // null (i.e., the value before coercion).
-
-  // Getter and setter for multiline.
-  var multiline = false;
-  var RegExpGetMultiline = function() { return multiline; };
-  var RegExpSetMultiline = function(flag) { multiline = flag ? true : false; };
-
-  %DefineAccessorPropertyUnchecked($RegExp, 'multiline', RegExpGetMultiline,
-                                   RegExpSetMultiline, DONT_DELETE);
-  %DefineAccessorPropertyUnchecked($RegExp, '$*', RegExpGetMultiline,
-                                   RegExpSetMultiline,
-                                   DONT_ENUM | DONT_DELETE);
-
-
-  var NoOpSetter = function(ignored) {};
-
-
-  // Static properties set by a successful match.
-  %DefineAccessorPropertyUnchecked($RegExp, 'lastMatch', RegExpGetLastMatch,
-                                   NoOpSetter, DONT_DELETE);
-  %DefineAccessorPropertyUnchecked($RegExp, '$&', RegExpGetLastMatch,
-                                   NoOpSetter, DONT_ENUM | DONT_DELETE);
-  %DefineAccessorPropertyUnchecked($RegExp, 'lastParen', RegExpGetLastParen,
-                                   NoOpSetter, DONT_DELETE);
-  %DefineAccessorPropertyUnchecked($RegExp, '$+', RegExpGetLastParen,
-                                   NoOpSetter, DONT_ENUM | DONT_DELETE);
-  %DefineAccessorPropertyUnchecked($RegExp, 'leftContext',
-                                   RegExpGetLeftContext, NoOpSetter,
+%FunctionSetInstanceClassName(GlobalRegExp, 'RegExp');
+%AddNamedProperty(
+    GlobalRegExp.prototype, 'constructor', GlobalRegExp, DONT_ENUM);
+%SetCode(GlobalRegExp, RegExpConstructor);
+
+InstallFunctions(GlobalRegExp.prototype, DONT_ENUM, GlobalArray(
+  "exec", RegExpExec,
+  "test", RegExpTest,
+  "toString", RegExpToString,
+  "compile", RegExpCompileJS
+));
+
+// The length of compile is 1 in SpiderMonkey.
+%FunctionSetLength(GlobalRegExp.prototype.compile, 1);
+
+// The properties `input` and `$_` are aliases for each other.  When this
+// value is set the value it is set to is coerced to a string.
+// Getter and setter for the input.
+var RegExpGetInput = function() {
+  var regExpInput = LAST_INPUT($regexpLastMatchInfo);
+  return IS_UNDEFINED(regExpInput) ? "" : regExpInput;
+};
+var RegExpSetInput = function(string) {
+  LAST_INPUT($regexpLastMatchInfo) = ToString(string);
+};
+
+%OptimizeObjectForAddingMultipleProperties(GlobalRegExp, 22);
+%DefineAccessorPropertyUnchecked(GlobalRegExp, 'input', RegExpGetInput,
+                                 RegExpSetInput, DONT_DELETE);
+%DefineAccessorPropertyUnchecked(GlobalRegExp, '$_', RegExpGetInput,
+                                 RegExpSetInput, DONT_ENUM | DONT_DELETE);
+
+// The properties multiline and $* are aliases for each other.  When this
+// value is set in SpiderMonkey, the value it is set to is coerced to a
+// boolean.  We mimic that behavior with a slight difference: in SpiderMonkey
+// the value of the expression 'RegExp.multiline = null' (for instance) is the
+// boolean false (i.e., the value after coercion), while in V8 it is the value
+// null (i.e., the value before coercion).
+
+// Getter and setter for multiline.
+var multiline = false;
+var RegExpGetMultiline = function() { return multiline; };
+var RegExpSetMultiline = function(flag) { multiline = flag ? true : false; };
+
+%DefineAccessorPropertyUnchecked(GlobalRegExp, 'multiline', RegExpGetMultiline,
+                                 RegExpSetMultiline, DONT_DELETE);
+%DefineAccessorPropertyUnchecked(GlobalRegExp, '$*', RegExpGetMultiline,
+                                 RegExpSetMultiline,
+                                 DONT_ENUM | DONT_DELETE);
+
+
+var NoOpSetter = function(ignored) {};
+
+
+// Static properties set by a successful match.
+%DefineAccessorPropertyUnchecked(GlobalRegExp, 'lastMatch', RegExpGetLastMatch,
+                                 NoOpSetter, DONT_DELETE);
+%DefineAccessorPropertyUnchecked(GlobalRegExp, '$&', RegExpGetLastMatch,
+                                 NoOpSetter, DONT_ENUM | DONT_DELETE);
+%DefineAccessorPropertyUnchecked(GlobalRegExp, 'lastParen', RegExpGetLastParen,
+                                 NoOpSetter, DONT_DELETE);
+%DefineAccessorPropertyUnchecked(GlobalRegExp, '$+', RegExpGetLastParen,
+                                 NoOpSetter, DONT_ENUM | DONT_DELETE);
+%DefineAccessorPropertyUnchecked(GlobalRegExp, 'leftContext',
+                                 RegExpGetLeftContext, NoOpSetter,
+                                 DONT_DELETE);
+%DefineAccessorPropertyUnchecked(GlobalRegExp, '$`', RegExpGetLeftContext,
+                                 NoOpSetter, DONT_ENUM | DONT_DELETE);
+%DefineAccessorPropertyUnchecked(GlobalRegExp, 'rightContext',
+                                 RegExpGetRightContext, NoOpSetter,
+                                 DONT_DELETE);
+%DefineAccessorPropertyUnchecked(GlobalRegExp, "$'", RegExpGetRightContext,
+                                 NoOpSetter, DONT_ENUM | DONT_DELETE);
+
+for (var i = 1; i < 10; ++i) {
+  %DefineAccessorPropertyUnchecked(GlobalRegExp, '$' + i,
+                                   RegExpMakeCaptureGetter(i), NoOpSetter,
                                    DONT_DELETE);
-  %DefineAccessorPropertyUnchecked($RegExp, '$`', RegExpGetLeftContext,
-                                   NoOpSetter, DONT_ENUM | DONT_DELETE);
-  %DefineAccessorPropertyUnchecked($RegExp, 'rightContext',
-                                   RegExpGetRightContext, NoOpSetter,
-                                   DONT_DELETE);
-  %DefineAccessorPropertyUnchecked($RegExp, "$'", RegExpGetRightContext,
-                                   NoOpSetter, DONT_ENUM | DONT_DELETE);
-
-  for (var i = 1; i < 10; ++i) {
-    %DefineAccessorPropertyUnchecked($RegExp, '$' + i,
-                                     RegExpMakeCaptureGetter(i), NoOpSetter,
-                                     DONT_DELETE);
-  }
-  %ToFastProperties($RegExp);
 }
+%ToFastProperties(GlobalRegExp);
+
+$regexpExecNoTests = RegExpExecNoTests;
+$regexpExec = DoRegExpExec;
 
-SetUpRegExp();
+})();
index a3e5e02..6bcabff 100644 (file)
@@ -110,9 +110,9 @@ void CalculateFirstPageSizes(bool is_default_snapshot,
     }
     PrintF(
         "Deserialization will reserve:\n"
-        "%*d bytes for startup\n"
-        "%*d bytes per context\n",
-        10, startup_total, 10, context_total);
+        "%10d bytes for startup\n"
+        "%10d bytes per context\n",
+        startup_total, context_total);
   }
 
   for (int space = 0; space < i::Serializer::kNumberOfSpaces; space++) {
@@ -187,9 +187,9 @@ v8::StartupData Snapshot::CreateSnapshotBlob(
   if (FLAG_profile_deserialization) {
     PrintF(
         "Snapshot blob consists of:\n"
-        "%*d bytes for startup\n"
-        "%*d bytes for context\n",
-        10, startup_length, 10, context_length);
+        "%10d bytes for startup\n"
+        "%10d bytes for context\n",
+        startup_length, context_length);
   }
   return result;
 }
index f5eef37..df31c13 100644 (file)
@@ -2,13 +2,17 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+(function() {
+
 "use strict";
 
+%CheckIsBootstrapping();
 
-// This file relies on the fact that the following declaration has been made
-// in runtime.js:
-// var $String = global.String;
+var GlobalArray = global.Array;
+var GlobalObject = global.Object;
+var GlobalString = global.String;
 
+//-------------------------------------------------------------------
 
 var stringIteratorIteratedStringSymbol =
     GLOBAL_PRIVATE("StringIterator#iteratedString");
@@ -75,35 +79,27 @@ function StringIteratorNext() {
 }
 
 
-function SetUpStringIterator() {
-  %CheckIsBootstrapping();
-
-  %FunctionSetPrototype(StringIterator, new $Object());
-  %FunctionSetInstanceClassName(StringIterator, 'String Iterator');
-
-  InstallFunctions(StringIterator.prototype, DONT_ENUM, $Array(
-    'next', StringIteratorNext
-  ));
-  %FunctionSetName(StringIteratorIterator, '[Symbol.iterator]');
-  %AddNamedProperty(StringIterator.prototype, symbolIterator,
-                    StringIteratorIterator, DONT_ENUM);
-  %AddNamedProperty(StringIterator.prototype, symbolToStringTag,
-                    "String Iterator", READ_ONLY | DONT_ENUM);
-}
-SetUpStringIterator();
-
-
 // 21.1.3.27 String.prototype [ @@iterator ]( )
 function StringPrototypeIterator() {
   return CreateStringIterator(this);
 }
 
+//-------------------------------------------------------------------
 
-function ExtendStringPrototypeWithIterator() {
-  %CheckIsBootstrapping();
+%FunctionSetPrototype(StringIterator, new GlobalObject());
+%FunctionSetInstanceClassName(StringIterator, 'String Iterator');
 
-  %FunctionSetName(StringPrototypeIterator, '[Symbol.iterator]');
-  %AddNamedProperty($String.prototype, symbolIterator,
-                    StringPrototypeIterator, DONT_ENUM);
-}
-ExtendStringPrototypeWithIterator();
+InstallFunctions(StringIterator.prototype, DONT_ENUM, GlobalArray(
+  'next', StringIteratorNext
+));
+%FunctionSetName(StringIteratorIterator, '[Symbol.iterator]');
+%AddNamedProperty(StringIterator.prototype, symbolIterator,
+                  StringIteratorIterator, DONT_ENUM);
+%AddNamedProperty(StringIterator.prototype, symbolToStringTag,
+                  "String Iterator", READ_ONLY | DONT_ENUM);
+
+%FunctionSetName(StringPrototypeIterator, '[Symbol.iterator]');
+%AddNamedProperty(GlobalString.prototype, symbolIterator,
+                  StringPrototypeIterator, DONT_ENUM);
+
+})();
index ac5cb7f..5b73961 100644 (file)
@@ -2,11 +2,19 @@
 // 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 declaration has been made
-// in runtime.js:
-// var $String = global.String;
+var $stringCharAt;
+var $stringIndexOf;
+var $stringSubstring;
 
-// -------------------------------------------------------------------
+(function() {
+
+%CheckIsBootstrapping();
+
+var GlobalArray = global.Array;
+var GlobalRegExp = global.RegExp;
+var GlobalString = global.String;
+
+//-------------------------------------------------------------------
 
 function StringConstructor(x) {
   if (%_ArgumentsLength() == 0) x = '';
@@ -147,16 +155,15 @@ function StringMatchJS(regexp) {
     // value is discarded.
     var lastIndex = regexp.lastIndex;
     TO_INTEGER_FOR_SIDE_EFFECT(lastIndex);
-    if (!regexp.global) return RegExpExecNoTests(regexp, subject, 0);
-    // lastMatchInfo is defined in regexp.js.
-    var result = %StringMatch(subject, regexp, lastMatchInfo);
-    if (result !== null) lastMatchInfoOverride = null;
+    if (!regexp.global) return $regexpExecNoTests(regexp, subject, 0);
+    var result = %StringMatch(subject, regexp, $regexpLastMatchInfo);
+    if (result !== null) $regexpLastMatchInfoOverride = null;
     regexp.lastIndex = 0;
     return result;
   }
   // Non-regexp argument.
-  regexp = new $RegExp(regexp);
-  return RegExpExecNoTests(regexp, subject, 0);
+  regexp = new GlobalRegExp(regexp);
+  return $regexpExecNoTests(regexp, subject, 0);
 }
 
 
@@ -182,9 +189,9 @@ function StringNormalizeJS(form) {
 }
 
 
-// This has the same size as the lastMatchInfo array, and can be used for
-// functions that expect that structure to be returned.  It is used when the
-// needle is a string rather than a regexp.  In this case we can't update
+// This has the same size as the $regexpLastMatchInfo array, and can be used
+// for functions that expect that structure to be returned.  It is used when
+// the needle is a string rather than a regexp.  In this case we can't update
 // lastMatchArray without erroneously affecting the properties on the global
 // RegExp object.
 var reusableMatchInfo = [2, "", "", -1, -1];
@@ -224,7 +231,7 @@ function StringReplace(search, replace) {
 
       if (!search.global) {
         // Non-global regexp search, string replace.
-        var match = DoRegExpExec(search, subject, 0);
+        var match = $regexpExec(search, subject, 0);
         if (match == null) {
           search.lastIndex = 0
           return subject;
@@ -233,28 +240,28 @@ function StringReplace(search, replace) {
           return %_SubString(subject, 0, match[CAPTURE0]) +
                  %_SubString(subject, match[CAPTURE1], subject.length)
         }
-        return ExpandReplacement(replace, subject, lastMatchInfo,
+        return ExpandReplacement(replace, subject, $regexpLastMatchInfo,
                                  %_SubString(subject, 0, match[CAPTURE0])) +
                %_SubString(subject, match[CAPTURE1], subject.length);
       }
 
       // Global regexp search, string replace.
       search.lastIndex = 0;
-      if (lastMatchInfoOverride == null) {
+      if ($regexpLastMatchInfoOverride == null) {
         return %StringReplaceGlobalRegExpWithString(
-            subject, search, replace, lastMatchInfo);
+            subject, search, replace, $regexpLastMatchInfo);
       } else {
         // We use this hack to detect whether StringReplaceRegExpWithString
         // found at least one hit. In that case we need to remove any
         // override.
-        var saved_subject = lastMatchInfo[LAST_SUBJECT_INDEX];
-        lastMatchInfo[LAST_SUBJECT_INDEX] = 0;
+        var saved_subject = $regexpLastMatchInfo[LAST_SUBJECT_INDEX];
+        $regexpLastMatchInfo[LAST_SUBJECT_INDEX] = 0;
         var answer = %StringReplaceGlobalRegExpWithString(
-            subject, search, replace, lastMatchInfo);
-        if (%_IsSmi(lastMatchInfo[LAST_SUBJECT_INDEX])) {
-          lastMatchInfo[LAST_SUBJECT_INDEX] = saved_subject;
+            subject, search, replace, $regexpLastMatchInfo);
+        if (%_IsSmi($regexpLastMatchInfo[LAST_SUBJECT_INDEX])) {
+          $regexpLastMatchInfo[LAST_SUBJECT_INDEX] = saved_subject;
         } else {
-          lastMatchInfoOverride = null;
+          $regexpLastMatchInfoOverride = null;
         }
         return answer;
       }
@@ -418,7 +425,7 @@ function StringReplaceGlobalRegExpWithFunction(subject, regexp, replace) {
   }
   var res = %RegExpExecMultiple(regexp,
                                 subject,
-                                lastMatchInfo,
+                                $regexpLastMatchInfo,
                                 resultArray);
   regexp.lastIndex = 0;
   if (IS_NULL(res)) {
@@ -427,7 +434,7 @@ function StringReplaceGlobalRegExpWithFunction(subject, regexp, replace) {
     return subject;
   }
   var len = res.length;
-  if (NUMBER_OF_CAPTURES(lastMatchInfo) == 2) {
+  if (NUMBER_OF_CAPTURES($regexpLastMatchInfo) == 2) {
     // If the number of captures is two then there are no explicit captures in
     // the regexp, just the implicit capture that captures the whole match.  In
     // this case we can simplify quite a bit and end up with something faster.
@@ -451,7 +458,7 @@ function StringReplaceGlobalRegExpWithFunction(subject, regexp, replace) {
       } else {
         override[0] = elem;
         override[1] = match_start;
-        lastMatchInfoOverride = override;
+        $regexpLastMatchInfoOverride = override;
         var func_result =
             %_CallFunction(receiver, elem, match_start, subject, replace);
         // Overwrite the i'th element in the results with the string we got
@@ -467,7 +474,7 @@ function StringReplaceGlobalRegExpWithFunction(subject, regexp, replace) {
       if (!%_IsSmi(elem)) {
         // elem must be an Array.
         // Use the apply argument as backing for global RegExp properties.
-        lastMatchInfoOverride = elem;
+        $regexpLastMatchInfoOverride = elem;
         var func_result = %Apply(replace, receiver, elem, 0, elem.length);
         // Overwrite the i'th element in the results with the string we got
         // back from the callback function.
@@ -483,7 +490,7 @@ function StringReplaceGlobalRegExpWithFunction(subject, regexp, replace) {
 
 
 function StringReplaceNonGlobalRegExpWithFunction(subject, regexp, replace) {
-  var matchInfo = DoRegExpExec(regexp, subject, 0);
+  var matchInfo = $regexpExec(regexp, subject, 0);
   if (IS_NULL(matchInfo)) {
     regexp.lastIndex = 0;
     return subject;
@@ -530,9 +537,9 @@ function StringSearch(re) {
   } else if (IS_REGEXP(re)) {
     regexp = re;
   } else {
-    regexp = new $RegExp(re);
+    regexp = new GlobalRegExp(re);
   }
-  var match = DoRegExpExec(regexp, TO_STRING_INLINE(this), 0);
+  var match = $regexpExec(regexp, TO_STRING_INLINE(this), 0);
   if (match) {
     return match[CAPTURE0];
   }
@@ -618,7 +625,7 @@ function StringSplitJS(separator, limit) {
 
 function StringSplitOnRegExp(subject, separator, limit, length) {
   if (length === 0) {
-    if (DoRegExpExec(separator, subject, 0, 0) != null) {
+    if ($regexpExec(separator, subject, 0, 0) != null) {
       return [];
     }
     return [subject];
@@ -637,7 +644,7 @@ function StringSplitOnRegExp(subject, separator, limit, length) {
       break;
     }
 
-    var matchInfo = DoRegExpExec(separator, subject, startIndex);
+    var matchInfo = $regexpExec(separator, subject, startIndex);
     if (matchInfo == null || length === (startMatch = matchInfo[CAPTURE0])) {
       result[result.length] = %_SubString(subject, currentIndex, length);
       break;
@@ -926,60 +933,61 @@ function StringSup() {
 
 // -------------------------------------------------------------------
 
-function SetUpString() {
-  %CheckIsBootstrapping();
-
-  // Set the String function and constructor.
-  %SetCode($String, StringConstructor);
-  %FunctionSetPrototype($String, new $String());
-
-  // Set up the constructor property on the String prototype object.
-  %AddNamedProperty($String.prototype, "constructor", $String, DONT_ENUM);
-
-  // Set up the non-enumerable functions on the String object.
-  InstallFunctions($String, DONT_ENUM, $Array(
-    "fromCharCode", StringFromCharCode
-  ));
-
-  // Set up the non-enumerable functions on the String prototype object.
-  InstallFunctions($String.prototype, DONT_ENUM, $Array(
-    "valueOf", StringValueOf,
-    "toString", StringToString,
-    "charAt", StringCharAt,
-    "charCodeAt", StringCharCodeAt,
-    "concat", StringConcat,
-    "indexOf", StringIndexOfJS,
-    "lastIndexOf", StringLastIndexOfJS,
-    "localeCompare", StringLocaleCompareJS,
-    "match", StringMatchJS,
-    "normalize", StringNormalizeJS,
-    "replace", StringReplace,
-    "search", StringSearch,
-    "slice", StringSlice,
-    "split", StringSplitJS,
-    "substring", StringSubstring,
-    "substr", StringSubstr,
-    "toLowerCase", StringToLowerCaseJS,
-    "toLocaleLowerCase", StringToLocaleLowerCase,
-    "toUpperCase", StringToUpperCaseJS,
-    "toLocaleUpperCase", StringToLocaleUpperCase,
-    "trim", StringTrimJS,
-    "trimLeft", StringTrimLeft,
-    "trimRight", StringTrimRight,
-    "link", StringLink,
-    "anchor", StringAnchor,
-    "fontcolor", StringFontcolor,
-    "fontsize", StringFontsize,
-    "big", StringBig,
-    "blink", StringBlink,
-    "bold", StringBold,
-    "fixed", StringFixed,
-    "italics", StringItalics,
-    "small", StringSmall,
-    "strike", StringStrike,
-    "sub", StringSub,
-    "sup", StringSup
-  ));
-}
-
-SetUpString();
+// Set the String function and constructor.
+%SetCode(GlobalString, StringConstructor);
+%FunctionSetPrototype(GlobalString, new GlobalString());
+
+// Set up the constructor property on the String prototype object.
+%AddNamedProperty(
+    GlobalString.prototype, "constructor", GlobalString, DONT_ENUM);
+
+// Set up the non-enumerable functions on the String object.
+InstallFunctions(GlobalString, DONT_ENUM, GlobalArray(
+  "fromCharCode", StringFromCharCode
+));
+
+// Set up the non-enumerable functions on the String prototype object.
+InstallFunctions(GlobalString.prototype, DONT_ENUM, GlobalArray(
+  "valueOf", StringValueOf,
+  "toString", StringToString,
+  "charAt", StringCharAt,
+  "charCodeAt", StringCharCodeAt,
+  "concat", StringConcat,
+  "indexOf", StringIndexOfJS,
+  "lastIndexOf", StringLastIndexOfJS,
+  "localeCompare", StringLocaleCompareJS,
+  "match", StringMatchJS,
+  "normalize", StringNormalizeJS,
+  "replace", StringReplace,
+  "search", StringSearch,
+  "slice", StringSlice,
+  "split", StringSplitJS,
+  "substring", StringSubstring,
+  "substr", StringSubstr,
+  "toLowerCase", StringToLowerCaseJS,
+  "toLocaleLowerCase", StringToLocaleLowerCase,
+  "toUpperCase", StringToUpperCaseJS,
+  "toLocaleUpperCase", StringToLocaleUpperCase,
+  "trim", StringTrimJS,
+  "trimLeft", StringTrimLeft,
+  "trimRight", StringTrimRight,
+  "link", StringLink,
+  "anchor", StringAnchor,
+  "fontcolor", StringFontcolor,
+  "fontsize", StringFontsize,
+  "big", StringBig,
+  "blink", StringBlink,
+  "bold", StringBold,
+  "fixed", StringFixed,
+  "italics", StringItalics,
+  "small", StringSmall,
+  "strike", StringStrike,
+  "sub", StringSub,
+  "sup", StringSup
+));
+
+$stringCharAt = StringCharAt;
+$stringIndexOf = StringIndexOfJS;
+$stringSubstring = StringSubstring;
+
+})();
index 360712a..e037392 100644 (file)
@@ -30,6 +30,13 @@ var rempio2result;
   
 "use strict";
 
+%CheckIsBootstrapping();
+
+var GlobalMath = global.Math;
+var GlobalArray = global.Array;
+
+//-------------------------------------------------------------------
+
 const INVPIO2 = kMath[0];
 const PIO2_1  = kMath[1];
 const PIO2_1T = kMath[2];
@@ -1006,9 +1013,7 @@ function MathLog2(x) {
 
 //-------------------------------------------------------------------
 
-%CheckIsBootstrapping();
-
-InstallFunctions(global.Math, DONT_ENUM, $Array(
+InstallFunctions(GlobalMath, DONT_ENUM, GlobalArray(
   "cos", MathCos,
   "sin", MathSin,
   "tan", MathTan,
@@ -1023,4 +1028,4 @@ InstallFunctions(global.Math, DONT_ENUM, $Array(
 %SetInlineBuiltinFlag(MathSin);
 %SetInlineBuiltinFlag(MathCos);
 
-})();
\ No newline at end of file
+})();
index 490f39f..1acc922 100644 (file)
@@ -1843,7 +1843,7 @@ function NewFunctionFromString(arguments, function_token) {
     // 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, ')', StringIndexOfJS) != -1) {
+    if (%_CallFunction(p, ')', $stringIndexOf) != -1) {
       throw MakeSyntaxError('paren_in_arg_string', []);
     }
     // If the formal parameters include an unbalanced block comment, the