HARMONY_SHIPPING(DECLARE_FEATURE_INITIALIZATION)
#undef DECLARE_FEATURE_INITIALIZATION
- Handle<JSFunction> InstallInternalArray(Handle<JSObject> target,
+ Handle<JSFunction> InstallInternalArray(Handle<JSBuiltinsObject> builtins,
const char* name,
ElementsKind elements_kind);
bool InstallNatives();
void InstallJSFunctionResultCaches();
void InitializeNormalizedMapCaches();
- void RemoveExportObjects();
-
enum ExtensionTraversalState {
UNVISITED, VISITED, INSTALLED
};
FunctionMode function_mode);
void SetStrongFunctionInstanceDescriptor(Handle<Map> map);
- static bool CompileBuiltin(Isolate* isolate, int index,
- Handle<JSObject> shared);
+ static bool CompileBuiltin(Isolate* isolate, int index);
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, int argc,
- Handle<Object> argv[]);
-
- static bool CompileExtension(Isolate* isolate, v8::Extension* extension);
+ 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);
Isolate* isolate_;
Handle<Context> result_;
}
-bool Genesis::CompileBuiltin(Isolate* isolate, int index,
- Handle<JSObject> shared) {
+bool Genesis::CompileBuiltin(Isolate* isolate, int index) {
Vector<const char> name = Natives::GetScriptName(index);
Handle<String> source_code =
isolate->bootstrapper()->SourceLookup<Natives>(index);
- 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);
+ return CompileNative(isolate, name, source_code);
}
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);
- 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);
+ return CompileNative(isolate, name, source_code);
}
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);
- 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);
+ return CompileNative(isolate, name, source_code);
}
-bool Genesis::CompileNative(Isolate* isolate, Vector<const char> name,
- Handle<String> source, int argc,
- Handle<Object> argv[]) {
+bool Genesis::CompileNative(Isolate* isolate,
+ Vector<const char> name,
+ Handle<String> source) {
+ HandleScope scope(isolate);
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
StackLimitCheck check(isolate);
if (check.HasOverflowed()) return false;
- 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 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;
}
-bool Genesis::CompileExtension(Isolate* isolate, v8::Extension* extension) {
+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) {
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.
- 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)) {
+ if (cache == NULL || !cache->Lookup(name, &function_info)) {
+ DCHECK(source->IsOneByteRepresentation());
Handle<String> script_name =
factory->NewStringFromUtf8(name).ToHandleChecked();
function_info = Compiler::CompileScript(
- source, script_name, 0, 0, false, false, Handle<Object>(), context,
- extension, NULL, ScriptCompiler::kNoCompileOptions, NOT_NATIVES_CODE,
- false);
+ source, script_name, 0, 0, false, false, Handle<Object>(), top_context,
+ extension, NULL, ScriptCompiler::kNoCompileOptions,
+ use_runtime_context ? NATIVES_CODE : NOT_NATIVES_CODE, false);
if (function_info.is_null()) return false;
- cache->Add(name, function_info);
+ if (cache != NULL) 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 = isolate->global_object();
- return !Execution::Call(isolate, fun, receiver, 0, NULL).is_null();
+ 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<JSFunction> Genesis::InstallInternalArray(Handle<JSObject> target,
- const char* name,
- ElementsKind elements_kind) {
+Handle<JSFunction> Genesis::InstallInternalArray(
+ Handle<JSBuiltinsObject> builtins,
+ 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
// must not be leaked to user code.
Handle<JSObject> prototype =
factory()->NewJSObject(isolate()->object_function(), TENURED);
- Handle<JSFunction> array_function =
- InstallFunction(target, name, JS_ARRAY_TYPE, JSArray::kSize, prototype,
- Builtins::kInternalArrayCode);
+ Handle<JSFunction> array_function = InstallFunction(
+ builtins, name, JS_ARRAY_TYPE, JSArray::kSize,
+ prototype, Builtins::kInternalArrayCode);
InternalArrayConstructorStub internal_array_constructor_stub(isolate());
Handle<Code> code = internal_array_constructor_stub.GetCode();
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(
// through a common bottleneck that would make the SMI_ONLY -> FAST_ELEMENT
// transition easy to trap. Moreover, they rarely are smi-only.
{
- 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);
+ Handle<JSFunction> array_function =
+ InstallInternalArray(builtins, "InternalArray", FAST_HOLEY_ELEMENTS);
native_context()->set_internal_array_function(*array_function);
- InstallInternalArray(builtin_exports, "InternalPackedArray", FAST_ELEMENTS);
+ }
+
+ {
+ InstallInternalArray(builtins, "InternalPackedArray", FAST_ELEMENTS);
}
{ // -- S e t I t e r a t o r
#undef INSTALL_PUBLIC_SYMBOL
}
- // Install natives. Everything exported to experimental natives is also
- // shared to regular natives.
- TransferNamedProperties(builtin_exports, shared);
+ // Install natives.
int i = Natives::GetDebuggerCount();
- if (!CompileBuiltin(isolate(), i, shared)) return false;
+ if (!CompileBuiltin(isolate(), i)) return false;
if (!InstallJSBuiltins(builtins)) return false;
for (++i; i < Natives::GetBuiltinsCount(); ++i) {
- if (!CompileBuiltin(isolate(), i, shared)) return false;
+ if (!CompileBuiltin(isolate(), i)) return false;
}
InstallNativeFunctions();
}
-void Genesis::RemoveExportObjects() {
- native_context_->set_builtin_exports_object(Smi::FromInt(0));
-}
-
-
static void InstallBuiltinFunctionId(Handle<JSObject> holder,
const char* function_name,
BuiltinFunctionId id) {
}
}
// We do not expect this to throw an exception. Change this if it does.
- bool result = CompileExtension(isolate, extension);
+ 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);
DCHECK(isolate->has_pending_exception() != result);
if (!result) {
// We print out the name of the extension that fail to install.
// 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 (FLAG_expose_natives_as != nullptr ||
- !isolate->initialized_from_snapshot() ||
+ if (!isolate->initialized_from_snapshot() ||
!Snapshot::NewContextFromSnapshot(isolate, global_proxy,
&outdated_contexts)
.ToHandle(&native_context_)) {
InitializeExperimentalGlobal();
if (!InstallExperimentalNatives()) return;
if (!InstallExtraNatives()) return;
-
- // Exports are no longer needed.
- RemoveExportObjects();
}
// The serializer cannot serialize typed arrays. Reset those typed arrays