Use function wrapper argument to expose internal arrays to native scripts.
authoryangguo <yangguo@chromium.org>
Tue, 12 May 2015 06:14:17 +0000 (23:14 -0700)
committerCommit bot <commit-bot@chromium.org>
Tue, 12 May 2015 06:14:18 +0000 (06:14 +0000)
R=jkummerow@chromium.org

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

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

25 files changed:
src/array.js
src/bootstrapper.cc
src/contexts.h
src/date.js
src/harmony-array-includes.js
src/harmony-array.js
src/harmony-object.js
src/harmony-reflect.js
src/harmony-regexp.js
src/harmony-spread.js
src/harmony-tostring.js
src/harmony-typedarray.js
src/json.js
src/math.js
src/messages.js
src/object-observe.js
src/objects.h
src/promise.js
src/regexp.js
src/string.js
src/templates.js
src/uri.js
src/v8natives.js
test/cctest/test-heap.cc
test/mjsunit/regress/regress-1878.js

index 3f9bd68..93378cf 100644 (file)
@@ -19,7 +19,12 @@ var $innerArrayEvery;
 
 %CheckIsBootstrapping();
 
+// -------------------------------------------------------------------
+// Imports
+
 var GlobalArray = global.Array;
+var InternalArray = exports.InternalArray;
+var InternalPackedArray = exports.InternalPackedArray;
 
 // -------------------------------------------------------------------
 
index f3dd682..7d23fe5 100644 (file)
@@ -217,7 +217,7 @@ class Genesis BASE_EMBEDDED {
   HARMONY_SHIPPING(DECLARE_FEATURE_INITIALIZATION)
 #undef DECLARE_FEATURE_INITIALIZATION
 
-  Handle<JSFunction> InstallInternalArray(Handle<JSBuiltinsObject> builtins,
+  Handle<JSFunction> InstallInternalArray(Handle<JSObject> target,
                                           const char* name,
                                           ElementsKind elements_kind);
   bool InstallNatives();
@@ -233,6 +233,8 @@ class Genesis BASE_EMBEDDED {
   void InstallJSFunctionResultCaches();
   void InitializeNormalizedMapCaches();
 
+  void RemoveExportObjects();
+
   enum ExtensionTraversalState {
     UNVISITED, VISITED, INSTALLED
   };
@@ -307,19 +309,15 @@ class Genesis BASE_EMBEDDED {
                                            FunctionMode function_mode);
   void SetStrongFunctionInstanceDescriptor(Handle<Map> map);
 
-  static bool CompileBuiltin(Isolate* isolate, int index);
+  static bool CompileBuiltin(Isolate* isolate, int index,
+                             Handle<JSObject> shared);
   static bool CompileExperimentalBuiltin(Isolate* isolate, int index);
   static bool CompileExtraBuiltin(Isolate* isolate, int index);
-  static bool CompileNative(Isolate* isolate,
-                            Vector<const char> name,
-                            Handle<String> source);
-  static bool CompileScriptCached(Isolate* isolate,
-                                  Vector<const char> name,
-                                  Handle<String> source,
-                                  SourceCodeCache* cache,
-                                  v8::Extension* extension,
-                                  Handle<Context> top_context,
-                                  bool use_runtime_context);
+  static bool CompileNative(Isolate* isolate, Vector<const char> name,
+                            Handle<String> source, int argc,
+                            Handle<Object> argv[]);
+
+  static bool CompileExtension(Isolate* isolate, v8::Extension* extension);
 
   Isolate* isolate_;
   Handle<Context> result_;
@@ -1441,34 +1439,45 @@ void Genesis::InitializeExperimentalGlobal() {
 }
 
 
-bool Genesis::CompileBuiltin(Isolate* isolate, int index) {
+bool Genesis::CompileBuiltin(Isolate* isolate, int index,
+                             Handle<JSObject> shared) {
   Vector<const char> name = Natives::GetScriptName(index);
   Handle<String> source_code =
       isolate->bootstrapper()->SourceLookup<Natives>(index);
-  return CompileNative(isolate, name, source_code);
+  Handle<Object> global = isolate->global_object();
+  Handle<Object> exports = isolate->builtin_exports_object();
+  Handle<Object> args[] = {global, shared, exports};
+  return CompileNative(isolate, name, source_code, arraysize(args), args);
 }
 
 
 bool Genesis::CompileExperimentalBuiltin(Isolate* isolate, int index) {
+  HandleScope scope(isolate);
   Vector<const char> name = ExperimentalNatives::GetScriptName(index);
   Handle<String> source_code =
       isolate->bootstrapper()->SourceLookup<ExperimentalNatives>(index);
-  return CompileNative(isolate, name, source_code);
+  Handle<Object> global = isolate->global_object();
+  Handle<Object> exports = isolate->builtin_exports_object();
+  Handle<Object> args[] = {global, exports};
+  return CompileNative(isolate, name, source_code, arraysize(args), args);
 }
 
 
 bool Genesis::CompileExtraBuiltin(Isolate* isolate, int index) {
+  HandleScope scope(isolate);
   Vector<const char> name = ExtraNatives::GetScriptName(index);
   Handle<String> source_code =
       isolate->bootstrapper()->SourceLookup<ExtraNatives>(index);
-  return CompileNative(isolate, name, source_code);
+  Handle<Object> global = isolate->global_object();
+  Handle<Object> exports = isolate->builtin_exports_object();
+  Handle<Object> args[] = {global, exports};
+  return CompileNative(isolate, name, source_code, arraysize(args), args);
 }
 
 
-bool Genesis::CompileNative(Isolate* isolate,
-                            Vector<const char> name,
-                            Handle<String> source) {
-  HandleScope scope(isolate);
+bool Genesis::CompileNative(Isolate* isolate, Vector<const char> name,
+                            Handle<String> source, int argc,
+                            Handle<Object> argv[]) {
   SuppressDebug compiling_natives(isolate->debug());
   // During genesis, the boilerplate for stack overflow won't work until the
   // environment has been at least partially initialized. Add a stack check
@@ -1476,78 +1485,72 @@ bool Genesis::CompileNative(Isolate* isolate,
   StackLimitCheck check(isolate);
   if (check.HasOverflowed()) return false;
 
-  bool result = CompileScriptCached(isolate,
-                                    name,
-                                    source,
-                                    NULL,
-                                    NULL,
-                                    Handle<Context>(isolate->context()),
-                                    true);
-  DCHECK(isolate->has_pending_exception() != result);
-  if (!result) isolate->clear_pending_exception();
-  return result;
+  Handle<Context> context(isolate->context());
+
+  Handle<String> script_name =
+      isolate->factory()->NewStringFromUtf8(name).ToHandleChecked();
+  Handle<SharedFunctionInfo> function_info = Compiler::CompileScript(
+      source, script_name, 0, 0, false, false, Handle<Object>(), context, NULL,
+      NULL, ScriptCompiler::kNoCompileOptions, NATIVES_CODE, false);
+
+  DCHECK(context->IsNativeContext());
+
+  Handle<Context> runtime_context(context->runtime_context());
+  Handle<JSBuiltinsObject> receiver(context->builtins());
+  Handle<JSFunction> fun =
+      isolate->factory()->NewFunctionFromSharedFunctionInfo(function_info,
+                                                            runtime_context);
+
+  // For non-extension scripts, run script to get the function wrapper.
+  Handle<Object> wrapper;
+  if (!Execution::Call(isolate, fun, receiver, 0, NULL).ToHandle(&wrapper)) {
+    return false;
+  }
+  // Then run the function wrapper.
+  return !Execution::Call(isolate, Handle<JSFunction>::cast(wrapper), receiver,
+                          argc, argv).is_null();
 }
 
 
-bool Genesis::CompileScriptCached(Isolate* isolate,
-                                  Vector<const char> name,
-                                  Handle<String> source,
-                                  SourceCodeCache* cache,
-                                  v8::Extension* extension,
-                                  Handle<Context> top_context,
-                                  bool use_runtime_context) {
+bool Genesis::CompileExtension(Isolate* isolate, v8::Extension* extension) {
   Factory* factory = isolate->factory();
   HandleScope scope(isolate);
   Handle<SharedFunctionInfo> function_info;
 
+  Handle<String> source =
+      isolate->factory()
+          ->NewExternalStringFromOneByte(extension->source())
+          .ToHandleChecked();
+  DCHECK(source->IsOneByteRepresentation());
+
   // If we can't find the function in the cache, we compile a new
   // function and insert it into the cache.
-  if (cache == NULL || !cache->Lookup(name, &function_info)) {
-    DCHECK(source->IsOneByteRepresentation());
+  Vector<const char> name = CStrVector(extension->name());
+  SourceCodeCache* cache = isolate->bootstrapper()->extensions_cache();
+  Handle<Context> context(isolate->context());
+  DCHECK(context->IsNativeContext());
+
+  if (!cache->Lookup(name, &function_info)) {
     Handle<String> script_name =
         factory->NewStringFromUtf8(name).ToHandleChecked();
     function_info = Compiler::CompileScript(
-        source, script_name, 0, 0, false, false, Handle<Object>(), top_context,
-        extension, NULL, ScriptCompiler::kNoCompileOptions,
-        use_runtime_context ? NATIVES_CODE : NOT_NATIVES_CODE, false);
+        source, script_name, 0, 0, false, false, Handle<Object>(), context,
+        extension, NULL, ScriptCompiler::kNoCompileOptions, NOT_NATIVES_CODE,
+        false);
     if (function_info.is_null()) return false;
-    if (cache != NULL) cache->Add(name, function_info);
+    cache->Add(name, function_info);
   }
 
   // Set up the function context. Conceptually, we should clone the
   // function before overwriting the context but since we're in a
   // single-threaded environment it is not strictly necessary.
-  DCHECK(top_context->IsNativeContext());
-  Handle<Context> context =
-      Handle<Context>(use_runtime_context
-                      ? Handle<Context>(top_context->runtime_context())
-                      : top_context);
   Handle<JSFunction> fun =
       factory->NewFunctionFromSharedFunctionInfo(function_info, context);
 
   // Call function using either the runtime object or the global
   // object as the receiver. Provide no parameters.
-  Handle<Object> receiver =
-      Handle<Object>(use_runtime_context
-                     ? top_context->builtins()
-                     : top_context->global_object(),
-                     isolate);
-  MaybeHandle<Object> result;
-  if (extension == NULL) {
-    // For non-extension scripts, run script to get the function wrapper.
-    Handle<Object> wrapper;
-    if (!Execution::Call(isolate, fun, receiver, 0, NULL).ToHandle(&wrapper)) {
-      return false;
-    }
-    // Then run the function wrapper.
-    Handle<Object> global_obj(top_context->global_object(), isolate);
-    Handle<Object> args[] = {global_obj};
-    result = Execution::Call(isolate, Handle<JSFunction>::cast(wrapper),
-                             receiver, arraysize(args), args);
-  } else {
-    result = Execution::Call(isolate, fun, receiver, 0, NULL);
-  }
-  return !result.is_null();
+  Handle<Object> receiver = isolate->global_object();
+  return !Execution::Call(isolate, fun, receiver, 0, NULL).is_null();
 }
 
 
@@ -1818,10 +1821,9 @@ void Genesis::InitializeGlobal_harmony_tostring() {
 }
 
 
-Handle<JSFunction> Genesis::InstallInternalArray(
-    Handle<JSBuiltinsObject> builtins,
-    const char* name,
-    ElementsKind elements_kind) {
+Handle<JSFunction> Genesis::InstallInternalArray(Handle<JSObject> target,
+                                                 const char* name,
+                                                 ElementsKind elements_kind) {
   // --- I n t e r n a l   A r r a y ---
   // An array constructor on the builtins object that works like
   // the public Array constructor, except that its prototype
@@ -1830,9 +1832,9 @@ Handle<JSFunction> Genesis::InstallInternalArray(
   // must not be leaked to user code.
   Handle<JSObject> prototype =
       factory()->NewJSObject(isolate()->object_function(), TENURED);
-  Handle<JSFunction> array_function = InstallFunction(
-      builtins, name, JS_ARRAY_TYPE, JSArray::kSize,
-      prototype, Builtins::kInternalArrayCode);
+  Handle<JSFunction> array_function =
+      InstallFunction(target, name, JS_ARRAY_TYPE, JSArray::kSize, prototype,
+                      Builtins::kInternalArrayCode);
 
   InternalArrayConstructorStub internal_array_constructor_stub(isolate());
   Handle<Code> code = internal_array_constructor_stub.GetCode();
@@ -1910,6 +1912,27 @@ bool Genesis::InstallNatives() {
 
   native_context()->set_runtime_context(*context);
 
+  // Set up shared object to set up cross references between native scripts.
+  // "shared" is used for cross references between native scripts that are part
+  // of the snapshot. "builtin_exports" is used for experimental natives.
+  Handle<JSObject> shared =
+      factory()->NewJSObject(isolate()->object_function());
+  JSObject::NormalizeProperties(shared, CLEAR_INOBJECT_PROPERTIES, 16,
+                                "container to share between native scripts");
+  Handle<JSObject> builtin_exports =
+      factory()->NewJSObject(isolate()->object_function());
+  JSObject::NormalizeProperties(builtin_exports, CLEAR_INOBJECT_PROPERTIES, 16,
+                                "container to export to experimental natives");
+  native_context()->set_builtin_exports_object(*builtin_exports);
+
+  if (FLAG_expose_natives_as != nullptr) {
+    Handle<String> shared_key = factory()->NewStringFromAsciiChecked("shared");
+    Handle<String> builtin_exports_key =
+        factory()->NewStringFromAsciiChecked("builtin_exports");
+    JSObject::AddProperty(builtins, shared_key, shared, NONE);
+    JSObject::AddProperty(builtins, builtin_exports_key, builtin_exports, NONE);
+  }
+
   {  // -- S c r i p t
     // Builtin functions for Script.
     Handle<JSFunction> script_fun = InstallFunction(
@@ -2082,13 +2105,13 @@ bool Genesis::InstallNatives() {
   // through a common bottleneck that would make the SMI_ONLY -> FAST_ELEMENT
   // transition easy to trap. Moreover, they rarely are smi-only.
   {
-    Handle<JSFunction> array_function =
-        InstallInternalArray(builtins, "InternalArray", FAST_HOLEY_ELEMENTS);
+    HandleScope scope(isolate());
+    Handle<JSObject> builtin_exports =
+        Handle<JSObject>::cast(isolate()->builtin_exports_object());
+    Handle<JSFunction> array_function = InstallInternalArray(
+        builtin_exports, "InternalArray", FAST_HOLEY_ELEMENTS);
     native_context()->set_internal_array_function(*array_function);
-  }
-
-  {
-    InstallInternalArray(builtins, "InternalPackedArray", FAST_ELEMENTS);
+    InstallInternalArray(builtin_exports, "InternalPackedArray", FAST_ELEMENTS);
   }
 
   {  // -- S e t I t e r a t o r
@@ -2181,13 +2204,15 @@ bool Genesis::InstallNatives() {
 #undef INSTALL_PUBLIC_SYMBOL
   }
 
-  // Install natives.
+  // Install natives. Everything exported to experimental natives is also
+  // shared to regular natives.
+  TransferNamedProperties(builtin_exports, shared);
   int i = Natives::GetDebuggerCount();
-  if (!CompileBuiltin(isolate(), i)) return false;
+  if (!CompileBuiltin(isolate(), i, shared)) return false;
   if (!InstallJSBuiltins(builtins)) return false;
 
   for (++i; i < Natives::GetBuiltinsCount(); ++i) {
-    if (!CompileBuiltin(isolate(), i)) return false;
+    if (!CompileBuiltin(isolate(), i, shared)) return false;
   }
 
   InstallNativeFunctions();
@@ -2391,6 +2416,11 @@ bool Genesis::InstallExtraNatives() {
 }
 
 
+void Genesis::RemoveExportObjects() {
+  native_context_->set_builtin_exports_object(Smi::FromInt(0));
+}
+
+
 static void InstallBuiltinFunctionId(Handle<JSObject> holder,
                                      const char* function_name,
                                      BuiltinFunctionId id) {
@@ -2653,17 +2683,7 @@ bool Genesis::InstallExtension(Isolate* isolate,
     }
   }
   // We do not expect this to throw an exception. Change this if it does.
-  Handle<String> source_code =
-      isolate->factory()
-          ->NewExternalStringFromOneByte(extension->source())
-          .ToHandleChecked();
-  bool result = CompileScriptCached(isolate,
-                                    CStrVector(extension->name()),
-                                    source_code,
-                                    isolate->bootstrapper()->extensions_cache(),
-                                    extension,
-                                    Handle<Context>(isolate->context()),
-                                    false);
+  bool result = CompileExtension(isolate, extension);
   DCHECK(isolate->has_pending_exception() != result);
   if (!result) {
     // We print out the name of the extension that fail to install.
@@ -2914,8 +2934,10 @@ Genesis::Genesis(Isolate* isolate,
 
   // We can only de-serialize a context if the isolate was initialized from
   // a snapshot. Otherwise we have to build the context from scratch.
+  // Also create a context from scratch to expose natives, if required by flag.
   Handle<FixedArray> outdated_contexts;
-  if (!isolate->initialized_from_snapshot() ||
+  if (FLAG_expose_natives_as != nullptr ||
+      !isolate->initialized_from_snapshot() ||
       !Snapshot::NewContextFromSnapshot(isolate, global_proxy,
                                         &outdated_contexts)
            .ToHandle(&native_context_)) {
@@ -2971,6 +2993,9 @@ Genesis::Genesis(Isolate* isolate,
     InitializeExperimentalGlobal();
     if (!InstallExperimentalNatives()) return;
     if (!InstallExtraNatives()) return;
+
+    // Exports are no longer needed.
+    RemoveExportObjects();
   }
 
   // The serializer cannot serialize typed arrays. Reset those typed arrays
index 2d04da2..066e8a1 100644 (file)
@@ -185,7 +185,8 @@ enum BindingFlags {
   V(MAP_ITERATOR_MAP_INDEX, Map, map_iterator_map)                             \
   V(SET_ITERATOR_MAP_INDEX, Map, set_iterator_map)                             \
   V(ARRAY_VALUES_ITERATOR_INDEX, JSFunction, array_values_iterator)            \
-  V(SCRIPT_CONTEXT_TABLE_INDEX, ScriptContextTable, script_context_table)
+  V(SCRIPT_CONTEXT_TABLE_INDEX, ScriptContextTable, script_context_table)      \
+  V(BUILTIN_EXPORTS_OBJECT_INDEX, Object, builtin_exports_object)
 
 
 // A table of all script contexts. Every loaded top-level script with top-level
@@ -422,6 +423,7 @@ class Context: public FixedArray {
     SCRIPT_CONTEXT_TABLE_INDEX,
     MAP_CACHE_INDEX,
     TO_LENGTH_FUN_INDEX,
+    BUILTIN_EXPORTS_OBJECT_INDEX,
 
     // Properties from here are treated as weak references by the full GC.
     // Scavenge treats them as strong references.
index 0cd1825..7b6f539 100644 (file)
@@ -16,7 +16,13 @@ var $createDate;
 
 %CheckIsBootstrapping();
 
+// -------------------------------------------------------------------
+// Imports
+
 var GlobalDate = global.Date;
+var InternalArray = shared.InternalArray;
+
+// -------------------------------------------------------------------
 
 // This file contains date support implemented in JavaScript.
 
index 109499e..e4ac07b 100644 (file)
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-(function(global, shared, exports) {
+(function(global, exports) {
 
 'use strict';
 
index f9283b9..8520f35 100644 (file)
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-(function(global, shared, exports) {
+(function(global, exports) {
 
 'use strict';
 
index acf74dd..bbb6437 100644 (file)
@@ -3,7 +3,7 @@
 // found in the LICENSE file.
 //
 
-(function(global, shared, exports) {
+(function(global, exports) {
 
 "use strict";
 
index eee6df4..4f78b2a 100644 (file)
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-(function(global, shared, exports) {
+(function(global, exports) {
 
 'use strict';
 
index 6a32f16..21c2c71 100644 (file)
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-(function(global, shared, exports) {
+(function(global, exports) {
 
 'use strict';
 
index a523d26..8eade4b 100644 (file)
@@ -5,10 +5,16 @@
 var $spreadArguments;
 var $spreadIterable;
 
-(function(global, shared, exports) {
+(function(global, exports) {
 
 'use strict';
 
+// -------------------------------------------------------------------
+// Imports
+var InternalArray = exports.InternalArray;
+
+// -------------------------------------------------------------------
+
 function SpreadArguments() {
   var count = %_ArgumentsLength();
   var args = new InternalArray();
index b3783c4..d29d9c6 100644 (file)
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-(function(global, shared, exports) {
+(function(global, exports) {
 
 "use strict";
 
index 18b4ca0..bbdb91f 100644 (file)
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-(function(global, shared, exports) {
+(function(global, exports) {
 
 "use strict";
 
index f5ac6cb..819811a 100644 (file)
@@ -10,7 +10,11 @@ var $jsonSerializeAdapter;
 
 %CheckIsBootstrapping();
 
+// -------------------------------------------------------------------
+// Imports
+
 var GlobalJSON = global.JSON;
+var InternalArray = shared.InternalArray;
 
 // -------------------------------------------------------------------
 
index af2d0ac..633a5d0 100644 (file)
@@ -16,7 +16,11 @@ var $min;
 
 %CheckIsBootstrapping();
 
+// -------------------------------------------------------------------
+// Imports
+
 var GlobalObject = global.Object;
+var InternalArray = shared.InternalArray;
 
 //-------------------------------------------------------------------
 
index b9503cf..60a9c43 100644 (file)
@@ -35,7 +35,14 @@ var MakeTypeErrorEmbedded;
 
 %CheckIsBootstrapping();
 
+// -------------------------------------------------------------------
+// Imports
+
 var GlobalObject = global.Object;
+var InternalArray = shared.InternalArray;
+
+// -------------------------------------------------------------------
+
 var GlobalError;
 var GlobalTypeError;
 var GlobalRangeError;
@@ -44,8 +51,6 @@ var GlobalSyntaxError;
 var GlobalReferenceError;
 var GlobalEvalError;
 
-// -------------------------------------------------------------------
-
 var kMessages = {
   // Error
   constructor_is_generator:      ["Class constructor may not be a generator"],
index 00bf85d..3dfc35e 100644 (file)
@@ -16,8 +16,12 @@ var $observeNativeObjectNotifierPerformChange;
 
 %CheckIsBootstrapping();
 
+// -------------------------------------------------------------------
+// Imports
+
 var GlobalArray = global.Array;
 var GlobalObject = global.Object;
+var InternalArray = shared.InternalArray;
 
 // -------------------------------------------------------------------
 
index 2172695..b390cc3 100644 (file)
@@ -1694,9 +1694,6 @@ class JSReceiver: public HeapObject {
 // Forward declaration for JSObject::GetOrCreateHiddenPropertiesHashTable.
 class ObjectHashTable;
 
-// Forward declaration for JSObject::Copy.
-class AllocationSite;
-
 
 // The JSObject describes real heap allocated JavaScript objects with
 // properties.
@@ -2157,7 +2154,6 @@ class JSObject: public JSReceiver {
   // Copy object.
   enum DeepCopyHints { kNoHints = 0, kObjectIsShallow = 1 };
 
-  static Handle<JSObject> Copy(Handle<JSObject> object);
   MUST_USE_RESULT static MaybeHandle<JSObject> DeepCopy(
       Handle<JSObject> object,
       AllocationSiteUsageContext* site_context,
index b0d1aa0..97a0b4c 100644 (file)
@@ -19,6 +19,11 @@ var $promiseValue;
 %CheckIsBootstrapping();
 
 // -------------------------------------------------------------------
+// Imports
+
+var InternalArray = shared.InternalArray;
+
+// -------------------------------------------------------------------
 
 // Status values: 0 = pending, +1 = resolved, -1 = rejected
 var promiseStatus = GLOBAL_PRIVATE("Promise#status");
index 3ac5987..b6bf3f9 100644 (file)
@@ -13,7 +13,13 @@ var harmony_unicode_regexps = false;
 
 %CheckIsBootstrapping();
 
+// -------------------------------------------------------------------
+// Imports
+
 var GlobalRegExp = global.RegExp;
+var InternalPackedArray = shared.InternalPackedArray;
+
+// -------------------------------------------------------------------
 
 // Property of the builtins object for recording the result of the last
 // regexp match.  The property $regexpLastMatchInfo includes the matchIndices
index 03979fd..1fc7b02 100644 (file)
@@ -10,8 +10,13 @@ var $stringSubstring;
 
 %CheckIsBootstrapping();
 
+// -------------------------------------------------------------------
+// Imports
+
 var GlobalRegExp = global.RegExp;
 var GlobalString = global.String;
+var InternalArray = shared.InternalArray;
+var InternalPackedArray = shared.InternalPackedArray;
 
 //-------------------------------------------------------------------
 
index ff94683..e49cb3e 100644 (file)
@@ -12,9 +12,17 @@ var $getTemplateCallSite;
 
 %CheckIsBootstrapping();
 
-var callSiteCache = new global.Map;
-var mapGetFn = global.Map.prototype.get;
-var mapSetFn = global.Map.prototype.set;
+// -------------------------------------------------------------------
+// Imports
+
+var GlobalMap = global.Map;
+var InternalArray = shared.InternalArray;
+
+// -------------------------------------------------------------------
+
+var callSiteCache = new GlobalMap;
+var mapGetFn = GlobalMap.prototype.get;
+var mapSetFn = GlobalMap.prototype.set;
 
 
 function SameCallSiteElements(rawStrings, other) {
index 1f4b8b6..d3ecac9 100644 (file)
 
 %CheckIsBootstrapping();
 
+//- ------------------------------------------------------------------
+// Imports
+
 var GlobalObject = global.Object;
 var GlobalArray = global.Array;
+var InternalArray = shared.InternalArray;
 
 // -------------------------------------------------------------------
 // Define internal helper functions.
index ce54c75..94133bf 100644 (file)
@@ -36,11 +36,15 @@ var $toNameArray;
 
 %CheckIsBootstrapping();
 
+// ----------------------------------------------------------------------------
+// Imports
+
 var GlobalArray = global.Array;
 var GlobalBoolean = global.Boolean;
 var GlobalFunction = global.Function;
 var GlobalNumber = global.Number;
 var GlobalObject = global.Object;
+var InternalArray = shared.InternalArray;
 
 // ----------------------------------------------------------------------------
 
index d8c89ae..5730cde 100644 (file)
@@ -5430,3 +5430,56 @@ TEST(PreprocessStackTrace) {
     CHECK(!element->IsCode());
   }
 }
+
+
+static bool shared_has_been_collected = false;
+static bool builtin_exports_has_been_collected = false;
+
+static void SharedHasBeenCollected(
+    const v8::WeakCallbackInfo<v8::Persistent<v8::Object>>& data) {
+  shared_has_been_collected = true;
+  data.GetParameter()->Reset();
+}
+
+
+static void BuiltinExportsHasBeenCollected(
+    const v8::WeakCallbackInfo<v8::Persistent<v8::Object>>& data) {
+  builtin_exports_has_been_collected = true;
+  data.GetParameter()->Reset();
+}
+
+
+TEST(BootstrappingExports) {
+  FLAG_expose_natives_as = "natives";
+  CcTest::InitializeVM();
+  v8::Isolate* isolate = CcTest::isolate();
+
+  if (Snapshot::HaveASnapshotToStartFrom(CcTest::i_isolate())) return;
+
+  shared_has_been_collected = false;
+  builtin_exports_has_been_collected = false;
+
+  v8::Persistent<v8::Object> shared;
+  v8::Persistent<v8::Object> builtin_exports;
+
+  {
+    v8::HandleScope scope(isolate);
+    v8::Handle<v8::Object> natives =
+        CcTest::global()->Get(v8_str("natives"))->ToObject(isolate);
+    shared.Reset(isolate, natives->Get(v8_str("shared"))->ToObject(isolate));
+    natives->Delete(v8_str("shared"));
+    builtin_exports.Reset(
+        isolate, natives->Get(v8_str("builtin_exports"))->ToObject(isolate));
+    natives->Delete(v8_str("builtin_exports"));
+  }
+
+  shared.SetWeak(&shared, SharedHasBeenCollected,
+                 v8::WeakCallbackType::kParameter);
+  builtin_exports.SetWeak(&builtin_exports, BuiltinExportsHasBeenCollected,
+                          v8::WeakCallbackType::kParameter);
+
+  CcTest::heap()->CollectAllAvailableGarbage("fire weak callbacks");
+
+  CHECK(shared_has_been_collected);
+  CHECK(builtin_exports_has_been_collected);
+}
index fbc47bd..2889415 100644 (file)
 var a = Array();
 
 for (var i = 0; i < 1000; i++) {
-  var ai = natives.InternalArray(10000);
+  var ai = natives.shared.InternalArray(10000);
   assertFalse(%HaveSameMap(ai, a));
   assertTrue(%HasFastObjectElements(ai));
 }
 
 for (var i = 0; i < 1000; i++) {
-  var ai = new natives.InternalArray(10000);
+  var ai = new natives.shared.InternalArray(10000);
   assertFalse(%HaveSameMap(ai, a));
   assertTrue(%HasFastObjectElements(ai));
 }