diff options
author | Ali Ijaz Sheikh <ofrobots@google.com> | 2015-08-23 06:09:40 -0700 |
---|---|---|
committer | Rod Vagg <rod@vagg.org> | 2015-09-06 21:38:01 +1000 |
commit | 9fddd83cf9adf505bce2e2373881df0c4d41b261 (patch) | |
tree | 4272ce14c10fea496af2e78fc6debb187d613451 /deps/v8/src/bootstrapper.cc | |
parent | 46b7d151674d138e7ea4342d5f3ada1208b87ff2 (diff) | |
download | node-new-9fddd83cf9adf505bce2e2373881df0c4d41b261.tar.gz |
deps: upgrade V8 to 4.5.103.24
Upgrade to the latest branch-head for V8 4.5. For the full commit log see
https://github.com/v8/v8-git-mirror/commits/4.5.103.24
PR-URL: https://github.com/nodejs/node/pull/2509
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Diffstat (limited to 'deps/v8/src/bootstrapper.cc')
-rw-r--r-- | deps/v8/src/bootstrapper.cc | 498 |
1 files changed, 348 insertions, 150 deletions
diff --git a/deps/v8/src/bootstrapper.cc b/deps/v8/src/bootstrapper.cc index c56c429937..43fc0eb835 100644 --- a/deps/v8/src/bootstrapper.cc +++ b/deps/v8/src/bootstrapper.cc @@ -148,9 +148,8 @@ void Bootstrapper::TearDown() { class Genesis BASE_EMBEDDED { public: - Genesis(Isolate* isolate, - MaybeHandle<JSGlobalProxy> maybe_global_proxy, - v8::Handle<v8::ObjectTemplate> global_proxy_template, + Genesis(Isolate* isolate, MaybeHandle<JSGlobalProxy> maybe_global_proxy, + v8::Local<v8::ObjectTemplate> global_proxy_template, v8::ExtensionConfiguration* extensions); ~Genesis() { } @@ -185,7 +184,7 @@ class Genesis BASE_EMBEDDED { // we have to used the deserialized ones that are linked together with the // rest of the context snapshot. Handle<GlobalObject> CreateNewGlobals( - v8::Handle<v8::ObjectTemplate> global_proxy_template, + v8::Local<v8::ObjectTemplate> global_proxy_template, Handle<JSGlobalProxy> global_proxy); // Hooks the given global proxy into the context. If the context was created // by deserialization then this will unhook the global proxy that was @@ -197,6 +196,11 @@ class Genesis BASE_EMBEDDED { // other objects in the snapshot. void HookUpGlobalObject(Handle<GlobalObject> global_object, Handle<FixedArray> outdated_contexts); + // The native context has a ScriptContextTable that store declarative bindings + // made in script scopes. Add a "this" binding to that table pointing to the + // global proxy. + void InstallGlobalThisBinding(); + void HookUpGlobalThisBinding(Handle<FixedArray> outdated_contexts); // New context initialization. Used for creating a context from scratch. void InitializeGlobal(Handle<GlobalObject> global_object, Handle<JSFunction> empty_function); @@ -217,7 +221,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(); @@ -230,6 +234,7 @@ class Genesis BASE_EMBEDDED { bool InstallExperimentalNatives(); bool InstallExtraNatives(); void InstallBuiltinFunctionIds(); + void InstallExperimentalBuiltinFunctionIds(); void InstallJSFunctionResultCaches(); void InitializeNormalizedMapCaches(); @@ -268,7 +273,7 @@ class Genesis BASE_EMBEDDED { bool ConfigureApiObject(Handle<JSObject> object, Handle<ObjectTemplateInfo> object_template); bool ConfigureGlobalObjects( - v8::Handle<v8::ObjectTemplate> global_proxy_template); + v8::Local<v8::ObjectTemplate> global_proxy_template); // Migrates all properties from the 'from' object to the 'to' // object and overrides the prototype in 'to' with the one from @@ -310,16 +315,13 @@ class Genesis BASE_EMBEDDED { 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); - 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 CallUtilsFunction(Isolate* isolate, const char* name); + + static bool CompileExtension(Isolate* isolate, v8::Extension* extension); Isolate* isolate_; Handle<Context> result_; @@ -347,7 +349,7 @@ void Bootstrapper::Iterate(ObjectVisitor* v) { Handle<Context> Bootstrapper::CreateEnvironment( MaybeHandle<JSGlobalProxy> maybe_global_proxy, - v8::Handle<v8::ObjectTemplate> global_proxy_template, + v8::Local<v8::ObjectTemplate> global_proxy_template, v8::ExtensionConfiguration* extensions) { HandleScope scope(isolate_); Genesis genesis( @@ -534,6 +536,12 @@ Handle<JSFunction> Genesis::CreateEmptyFunction(Isolate* isolate) { native_context()->set_initial_array_prototype(*object_function_prototype); Accessors::FunctionSetPrototype(object_fun, object_function_prototype) .Assert(); + + // Allocate initial strong object map. + Handle<Map> strong_object_map = + Map::Copy(Handle<Map>(object_fun->initial_map()), "EmptyStrongObject"); + strong_object_map->set_is_strong(); + native_context()->set_js_object_strong_map(*strong_object_map); } // Allocate the empty function as the prototype for function - ES6 19.2.3 @@ -554,10 +562,10 @@ Handle<JSFunction> Genesis::CreateEmptyFunction(Isolate* isolate) { Handle<String> source = factory->NewStringFromStaticChars("() {}"); Handle<Script> script = factory->NewScript(source); script->set_type(Smi::FromInt(Script::TYPE_NATIVE)); - empty_function->shared()->set_script(*script); empty_function->shared()->set_start_position(0); empty_function->shared()->set_end_position(source->length()); empty_function->shared()->DontAdaptArguments(); + SharedFunctionInfo::SetScript(handle(empty_function->shared()), script); // Set prototypes for the function maps. Handle<Map> sloppy_function_map(native_context()->sloppy_function_map(), @@ -590,7 +598,7 @@ void Genesis::SetStrictFunctionInstanceDescriptor(Handle<Map> map, // Add length. if (function_mode == BOUND_FUNCTION) { Handle<String> length_string = isolate()->factory()->length_string(); - DataDescriptor d(length_string, 0, ro_attribs, Representation::Tagged()); + DataDescriptor d(length_string, 0, roc_attribs, Representation::Tagged()); map->AppendDescriptor(&d); } else { DCHECK(function_mode == FUNCTION_WITH_WRITEABLE_PROTOTYPE || @@ -709,7 +717,7 @@ Handle<Map> Genesis::CreateStrongFunctionMap( map->set_function_with_prototype(is_constructor); Map::SetPrototype(map, empty_function); map->set_is_extensible(is_constructor); - // TODO(rossberg): mark strong + map->set_is_strong(); return map; } @@ -787,7 +795,8 @@ static void AddToWeakNativeContextList(Context* context) { } } #endif - context->set(Context::NEXT_CONTEXT_LINK, heap->native_contexts_list()); + context->set(Context::NEXT_CONTEXT_LINK, heap->native_contexts_list(), + UPDATE_WEAK_WRITE_BARRIER); heap->set_native_contexts_list(context); } @@ -809,8 +818,43 @@ void Genesis::CreateRoots() { } +void Genesis::InstallGlobalThisBinding() { + Handle<ScriptContextTable> script_contexts( + native_context()->script_context_table()); + Handle<ScopeInfo> scope_info = ScopeInfo::CreateGlobalThisBinding(isolate()); + Handle<JSFunction> closure(native_context()->closure()); + Handle<Context> context = factory()->NewScriptContext(closure, scope_info); + + // Go ahead and hook it up while we're at it. + int slot = scope_info->ReceiverContextSlotIndex(); + DCHECK_EQ(slot, Context::MIN_CONTEXT_SLOTS); + context->set(slot, native_context()->global_proxy()); + + Handle<ScriptContextTable> new_script_contexts = + ScriptContextTable::Extend(script_contexts, context); + native_context()->set_script_context_table(*new_script_contexts); +} + + +void Genesis::HookUpGlobalThisBinding(Handle<FixedArray> outdated_contexts) { + // One of these contexts should be the one that declares the global "this" + // binding. + for (int i = 0; i < outdated_contexts->length(); ++i) { + Context* context = Context::cast(outdated_contexts->get(i)); + if (context->IsScriptContext()) { + ScopeInfo* scope_info = ScopeInfo::cast(context->extension()); + int slot = scope_info->ReceiverContextSlotIndex(); + if (slot >= 0) { + DCHECK_EQ(slot, Context::MIN_CONTEXT_SLOTS); + context->set(slot, native_context()->global_proxy()); + } + } + } +} + + Handle<GlobalObject> Genesis::CreateNewGlobals( - v8::Handle<v8::ObjectTemplate> global_proxy_template, + v8::Local<v8::ObjectTemplate> global_proxy_template, Handle<JSGlobalProxy> global_proxy) { // The argument global_proxy_template aka data is an ObjectTemplateInfo. // It has a constructor pointer that points at global_constructor which is a @@ -935,8 +979,9 @@ void Genesis::HookUpGlobalObject(Handle<GlobalObject> global_object, static const PropertyAttributes attributes = static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE); - Runtime::DefineObjectProperty(builtins_global, factory()->global_string(), - global_object, attributes).Assert(); + JSObject::SetOwnPropertyIgnoreAttributes(builtins_global, + factory()->global_string(), + global_object, attributes).Assert(); // Set up the reference from the global object to the builtins object. JSGlobalObject::cast(*global_object)->set_builtins(*builtins_global); TransferNamedProperties(global_object_from_snapshot, global_object); @@ -967,6 +1012,7 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> global_object, Handle<ScriptContextTable> script_context_table = factory->NewScriptContextTable(); native_context()->set_script_context_table(*script_context_table); + InstallGlobalThisBinding(); Handle<String> object_name = factory->Object_string(); JSObject::AddProperty( @@ -1020,6 +1066,11 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> global_object, ArrayConstructorStub array_constructor_stub(isolate); Handle<Code> code = array_constructor_stub.GetCode(); array_function->shared()->set_construct_stub(*code); + + Handle<Map> initial_strong_map = + Map::Copy(initial_map, "SetInstancePrototype"); + initial_strong_map->set_is_strong(); + CacheInitialJSArrayMaps(native_context(), initial_strong_map); } { // --- N u m b e r --- @@ -1186,7 +1237,6 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> global_object, isolate->initial_object_prototype(), Builtins::kIllegal); native_context()->set_array_buffer_fun(*array_buffer_fun); - native_context()->set_array_buffer_map(array_buffer_fun->initial_map()); } { // -- T y p e d A r r a y s @@ -1213,13 +1263,19 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> global_object, native_context()->set_data_view_fun(*data_view_fun); } - // -- M a p - InstallFunction(global, "Map", JS_MAP_TYPE, JSMap::kSize, - isolate->initial_object_prototype(), Builtins::kIllegal); + { // -- M a p + Handle<JSFunction> js_map_fun = InstallFunction( + global, "Map", JS_MAP_TYPE, JSMap::kSize, + isolate->initial_object_prototype(), Builtins::kIllegal); + native_context()->set_js_map_fun(*js_map_fun); + } - // -- S e t - InstallFunction(global, "Set", JS_SET_TYPE, JSSet::kSize, - isolate->initial_object_prototype(), Builtins::kIllegal); + { // -- S e t + Handle<JSFunction> js_set_fun = InstallFunction( + global, "Set", JS_SET_TYPE, JSSet::kSize, + isolate->initial_object_prototype(), Builtins::kIllegal); + native_context()->set_js_set_fun(*js_set_fun); + } { // Set up the iterator result object STATIC_ASSERT(JSGeneratorObject::kResultPropertyCount == 2); @@ -1300,12 +1356,17 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> global_object, DCHECK(IsFastObjectElementsKind(map->elements_kind())); } - { // --- aliased arguments map - Handle<Map> map = - Map::Copy(isolate->sloppy_arguments_map(), "AliasedArguments"); - map->set_elements_kind(SLOPPY_ARGUMENTS_ELEMENTS); + { // --- fast and slow aliased arguments map + Handle<Map> map = isolate->sloppy_arguments_map(); + map = Map::Copy(map, "FastAliasedArguments"); + map->set_elements_kind(FAST_SLOPPY_ARGUMENTS_ELEMENTS); DCHECK_EQ(2, map->pre_allocated_property_fields()); - native_context()->set_aliased_arguments_map(*map); + native_context()->set_fast_aliased_arguments_map(*map); + + map = Map::Copy(map, "SlowAliasedArguments"); + map->set_elements_kind(SLOW_SLOPPY_ARGUMENTS_ELEMENTS); + DCHECK_EQ(2, map->pre_allocated_property_fields()); + native_context()->set_slow_aliased_arguments_map(*map); } { // --- strict mode arguments map @@ -1445,109 +1506,130 @@ bool Genesis::CompileBuiltin(Isolate* isolate, int index) { 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> utils = isolate->natives_utils_object(); + Handle<Object> args[] = {global, utils}; + 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> utils = isolate->natives_utils_object(); + Handle<Object> args[] = {global, utils}; + 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->extras_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 // before entering JS code to catch overflow early. 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; + if (check.JsHasOverflowed(1 * KB)) { + isolate->StackOverflow(); + 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, ScriptOriginOptions(), Handle<Object>(), + context, NULL, NULL, ScriptCompiler::kNoCompileOptions, NATIVES_CODE, + false); + if (function_info.is_null()) return 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::CallUtilsFunction(Isolate* isolate, const char* name) { + Handle<JSObject> utils = + Handle<JSObject>::cast(isolate->natives_utils_object()); + Handle<String> name_string = + isolate->factory()->NewStringFromAsciiChecked(name); + Handle<Object> fun = JSObject::GetDataProperty(utils, name_string); + Handle<Object> receiver = isolate->factory()->undefined_value(); + Handle<Object> args[] = {utils}; + return !Execution::Call(isolate, fun, receiver, 1, args).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, ScriptOriginOptions(), 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(); } @@ -1611,6 +1693,7 @@ void Genesis::InstallNativeFunctions() { to_complete_property_descriptor); INSTALL_NATIVE(Symbol, "$promiseStatus", promise_status); + INSTALL_NATIVE(Symbol, "$promiseValue", promise_value); INSTALL_NATIVE(JSFunction, "$promiseCreate", promise_create); INSTALL_NATIVE(JSFunction, "$promiseResolve", promise_resolve); INSTALL_NATIVE(JSFunction, "$promiseReject", promise_reject); @@ -1632,6 +1715,15 @@ void Genesis::InstallNativeFunctions() { INSTALL_NATIVE(JSFunction, "$observeNativeObjectNotifierPerformChange", native_object_notifier_perform_change); INSTALL_NATIVE(JSFunction, "$arrayValues", array_values_iterator); + INSTALL_NATIVE(JSFunction, "$mapGet", map_get); + INSTALL_NATIVE(JSFunction, "$mapSet", map_set); + INSTALL_NATIVE(JSFunction, "$mapHas", map_has); + INSTALL_NATIVE(JSFunction, "$mapDelete", map_delete); + INSTALL_NATIVE(JSFunction, "$setAdd", set_add); + INSTALL_NATIVE(JSFunction, "$setHas", set_has); + INSTALL_NATIVE(JSFunction, "$setDelete", set_delete); + INSTALL_NATIVE(JSFunction, "$mapFromArray", map_from_array); + INSTALL_NATIVE(JSFunction, "$setFromArray", set_from_array); } @@ -1710,10 +1802,7 @@ void Genesis::InitializeBuiltinTypedArrays() { void Genesis::InstallNativeFunctions_##id() {} EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_modules) -EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_arrays) EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_array_includes) -EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_classes) -EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_object_literals) EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_regexps) EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_arrow_functions) EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_tostring) @@ -1726,6 +1815,11 @@ EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_reflect) EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_spreadcalls) EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_destructuring) EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_object) +EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_spread_arrays) +EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_sharedarraybuffer) +EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_atomics) +EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_new_target) +EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_concat_spreadable) void Genesis::InstallNativeFunctions_harmony_proxies() { @@ -1737,16 +1831,14 @@ void Genesis::InstallNativeFunctions_harmony_proxies() { } } + #undef INSTALL_NATIVE #define EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(id) \ void Genesis::InitializeGlobal_##id() {} EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_modules) -EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_arrays) EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_array_includes) -EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_classes) -EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_object_literals) EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_arrow_functions) EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_proxies) EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_sloppy) @@ -1756,6 +1848,10 @@ EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_rest_parameters) EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_spreadcalls) EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_destructuring) EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_object) +EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_spread_arrays) +EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_atomics) +EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_new_target) +EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_concat_spreadable) void Genesis::InitializeGlobal_harmony_regexps() { Handle<JSObject> builtins(native_context()->builtins()); @@ -1818,10 +1914,23 @@ void Genesis::InitializeGlobal_harmony_tostring() { } -Handle<JSFunction> Genesis::InstallInternalArray( - Handle<JSBuiltinsObject> builtins, - const char* name, - ElementsKind elements_kind) { +void Genesis::InitializeGlobal_harmony_sharedarraybuffer() { + if (!FLAG_harmony_sharedarraybuffer) return; + + Handle<JSGlobalObject> global( + JSGlobalObject::cast(native_context()->global_object())); + + Handle<JSFunction> shared_array_buffer_fun = InstallFunction( + global, "SharedArrayBuffer", JS_ARRAY_BUFFER_TYPE, + JSArrayBuffer::kSizeWithInternalFields, + isolate()->initial_object_prototype(), Builtins::kIllegal); + native_context()->set_shared_array_buffer_fun(*shared_array_buffer_fun); +} + + +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 +1939,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 +2019,23 @@ bool Genesis::InstallNatives() { native_context()->set_runtime_context(*context); + // Set up the utils object as shared container between native scripts. + Handle<JSObject> utils = factory()->NewJSObject(isolate()->object_function()); + JSObject::NormalizeProperties(utils, CLEAR_INOBJECT_PROPERTIES, 16, + "utils container for native scripts"); + native_context()->set_natives_utils_object(*utils); + + Handle<JSObject> extras_exports = + factory()->NewJSObject(isolate()->object_function()); + JSObject::NormalizeProperties(extras_exports, CLEAR_INOBJECT_PROPERTIES, 2, + "container to export to extra natives"); + native_context()->set_extras_exports_object(*extras_exports); + + if (FLAG_expose_natives_as != NULL) { + Handle<String> utils_key = factory()->NewStringFromAsciiChecked("utils"); + JSObject::AddProperty(builtins, utils_key, utils, NONE); + } + { // -- S c r i p t // Builtin functions for Script. Handle<JSFunction> script_fun = InstallFunction( @@ -2082,13 +2208,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. { + HandleScope scope(isolate()); + Handle<JSObject> utils = + Handle<JSObject>::cast(isolate()->natives_utils_object()); Handle<JSFunction> array_function = - InstallInternalArray(builtins, "InternalArray", FAST_HOLEY_ELEMENTS); + InstallInternalArray(utils, "InternalArray", FAST_HOLEY_ELEMENTS); native_context()->set_internal_array_function(*array_function); - } - - { - InstallInternalArray(builtins, "InternalPackedArray", FAST_ELEMENTS); + InstallInternalArray(utils, "InternalPackedArray", FAST_ELEMENTS); } { // -- S e t I t e r a t o r @@ -2110,10 +2236,17 @@ bool Genesis::InstallNatives() { { // Create generator meta-objects and install them on the builtins object. Handle<JSObject> builtins(native_context()->builtins()); + Handle<JSObject> iterator_prototype = + factory()->NewJSObject(isolate()->object_function(), TENURED); Handle<JSObject> generator_object_prototype = factory()->NewJSObject(isolate()->object_function(), TENURED); Handle<JSObject> generator_function_prototype = factory()->NewJSObject(isolate()->object_function(), TENURED); + SetObjectPrototype(generator_object_prototype, iterator_prototype); + JSObject::AddProperty( + builtins, factory()->InternalizeUtf8String("$iteratorPrototype"), + iterator_prototype, + static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY)); JSObject::AddProperty( builtins, factory()->InternalizeUtf8String("GeneratorFunctionPrototype"), @@ -2132,9 +2265,11 @@ bool Genesis::InstallNatives() { Builtins::kIllegal, kUseStrictFunctionMap); // Create maps for generator functions and their prototypes. Store those - // maps in the native context. Generator functions do not have writable - // prototypes, nor do they have "caller" or "arguments" accessors. - Handle<Map> strict_function_map(native_context()->strict_function_map()); + // maps in the native context. The "prototype" property descriptor is + // writable, non-enumerable, and non-configurable (as per ES6 draft + // 04-14-15, section 25.2.4.3). + Handle<Map> strict_function_map(strict_function_map_writable_prototype_); + // Generator functions do not have "caller" or "arguments" accessors. Handle<Map> sloppy_generator_function_map = Map::Copy(strict_function_map, "SloppyGeneratorFunction"); Map::SetPrototype(sloppy_generator_function_map, @@ -2181,7 +2316,6 @@ bool Genesis::InstallNatives() { #undef INSTALL_PUBLIC_SYMBOL } - // Install natives. int i = Natives::GetDebuggerCount(); if (!CompileBuiltin(isolate(), i)) return false; if (!InstallJSBuiltins(builtins)) return false; @@ -2190,6 +2324,8 @@ bool Genesis::InstallNatives() { if (!CompileBuiltin(isolate(), i)) return false; } + if (!CallUtilsFunction(isolate(), "PostNatives")) return false; + InstallNativeFunctions(); auto function_cache = @@ -2308,7 +2444,14 @@ bool Genesis::InstallNatives() { { AccessorConstantDescriptor d(factory()->iterator_symbol(), arguments_iterator, attribs); - Handle<Map> map(native_context()->aliased_arguments_map()); + Handle<Map> map(native_context()->fast_aliased_arguments_map()); + Map::EnsureDescriptorSlack(map, 1); + map->AppendDescriptor(&d); + } + { + AccessorConstantDescriptor d(factory()->iterator_symbol(), + arguments_iterator, attribs); + Handle<Map> map(native_context()->slow_aliased_arguments_map()); Map::EnsureDescriptorSlack(map, 1); map->AppendDescriptor(&d); } @@ -2332,14 +2475,10 @@ bool Genesis::InstallNatives() { bool Genesis::InstallExperimentalNatives() { - static const char* harmony_arrays_natives[] = { - "native harmony-array.js", "native harmony-typedarray.js", nullptr}; static const char* harmony_array_includes_natives[] = { "native harmony-array-includes.js", nullptr}; static const char* harmony_proxies_natives[] = {"native proxy.js", nullptr}; - static const char* harmony_classes_natives[] = {nullptr}; static const char* harmony_modules_natives[] = {nullptr}; - static const char* harmony_object_literals_natives[] = {nullptr}; static const char* harmony_regexps_natives[] = {"native harmony-regexp.js", nullptr}; static const char* harmony_arrow_functions_natives[] = {nullptr}; @@ -2357,6 +2496,14 @@ bool Genesis::InstallExperimentalNatives() { static const char* harmony_destructuring_natives[] = {nullptr}; static const char* harmony_object_natives[] = {"native harmony-object.js", NULL}; + static const char* harmony_spread_arrays_natives[] = {nullptr}; + static const char* harmony_sharedarraybuffer_natives[] = { + "native harmony-sharedarraybuffer.js", NULL}; + static const char* harmony_atomics_natives[] = {"native harmony-atomics.js", + nullptr}; + static const char* harmony_new_target_natives[] = {nullptr}; + static const char* harmony_concat_spreadable_natives[] = { + "native harmony-concat-spreadable.js", nullptr}; for (int i = ExperimentalNatives::GetDebuggerCount(); i < ExperimentalNatives::GetBuiltinsCount(); i++) { @@ -2376,7 +2523,10 @@ bool Genesis::InstallExperimentalNatives() { #undef INSTALL_EXPERIMENTAL_NATIVES } + if (!CallUtilsFunction(isolate(), "PostExperimentals")) return false; + InstallExperimentalNativeFunctions(); + InstallExperimentalBuiltinFunctionIds(); return true; } @@ -2402,6 +2552,11 @@ static void InstallBuiltinFunctionId(Handle<JSObject> holder, } +#define INSTALL_BUILTIN_ID(holder_expr, fun_name, name) \ + { #holder_expr, #fun_name, k##name } \ + , + + void Genesis::InstallBuiltinFunctionIds() { HandleScope scope(isolate()); struct BuiltinFunctionIds { @@ -2410,12 +2565,8 @@ void Genesis::InstallBuiltinFunctionIds() { BuiltinFunctionId id; }; -#define INSTALL_BUILTIN_ID(holder_expr, fun_name, name) \ - { #holder_expr, #fun_name, k##name } \ - , const BuiltinFunctionIds builtins[] = { FUNCTIONS_WITH_ID_LIST(INSTALL_BUILTIN_ID)}; -#undef INSTALL_BUILTIN_ID for (const BuiltinFunctionIds& builtin : builtins) { Handle<JSObject> holder = @@ -2425,6 +2576,29 @@ void Genesis::InstallBuiltinFunctionIds() { } +void Genesis::InstallExperimentalBuiltinFunctionIds() { + if (FLAG_harmony_atomics) { + struct BuiltinFunctionIds { + const char* holder_expr; + const char* fun_name; + BuiltinFunctionId id; + }; + + const BuiltinFunctionIds atomic_builtins[] = { + ATOMIC_FUNCTIONS_WITH_ID_LIST(INSTALL_BUILTIN_ID)}; + + for (const BuiltinFunctionIds& builtin : atomic_builtins) { + Handle<JSObject> holder = + ResolveBuiltinIdHolder(native_context(), builtin.holder_expr); + InstallBuiltinFunctionId(holder, builtin.fun_name, builtin.id); + } + } +} + + +#undef INSTALL_BUILTIN_ID + + // Do not forget to update macros.py with named constant // of cache id. #define JSFUNCTION_RESULT_CACHE_LIST(F) \ @@ -2502,14 +2676,17 @@ bool Genesis::InstallSpecialObjects(Handle<Context> native_context) { Handle<Smi> stack_trace_limit(Smi::FromInt(FLAG_stack_trace_limit), isolate); JSObject::AddProperty(Error, name, stack_trace_limit, NONE); + // By now the utils object is useless and can be removed. + native_context->set_natives_utils_object(*factory->undefined_value()); + // Expose the natives in global if a name for it is specified. if (FLAG_expose_natives_as != NULL && strlen(FLAG_expose_natives_as) != 0) { - Handle<String> natives = + Handle<String> natives_key = factory->InternalizeUtf8String(FLAG_expose_natives_as); uint32_t dummy_index; - if (natives->AsArrayIndex(&dummy_index)) return true; - JSObject::AddProperty(global, natives, handle(global->builtins()), - DONT_ENUM); + if (natives_key->AsArrayIndex(&dummy_index)) return true; + Handle<JSBuiltinsObject> natives(global->builtins()); + JSObject::AddProperty(global, natives_key, natives, DONT_ENUM); } // Expose the stack trace symbol to native JS. @@ -2653,17 +2830,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. @@ -2694,7 +2861,7 @@ bool Genesis::InstallJSBuiltins(Handle<JSBuiltinsObject> builtins) { bool Genesis::ConfigureGlobalObjects( - v8::Handle<v8::ObjectTemplate> global_proxy_template) { + v8::Local<v8::ObjectTemplate> global_proxy_template) { Handle<JSObject> global_proxy( JSObject::cast(native_context()->global_proxy())); Handle<JSObject> global_object( @@ -2720,6 +2887,12 @@ bool Genesis::ConfigureGlobalObjects( native_context()->set_initial_array_prototype( JSArray::cast(native_context()->array_function()->prototype())); + native_context()->set_array_buffer_map( + native_context()->array_buffer_fun()->initial_map()); + native_context()->set_js_map_map( + native_context()->js_map_fun()->initial_map()); + native_context()->set_js_set_map( + native_context()->js_set_fun()->initial_map()); return true; } @@ -2793,6 +2966,29 @@ void Genesis::TransferNamedProperties(Handle<JSObject> from, } } } + } else if (from->IsGlobalObject()) { + Handle<GlobalDictionary> properties = + Handle<GlobalDictionary>(from->global_dictionary()); + int capacity = properties->Capacity(); + for (int i = 0; i < capacity; i++) { + Object* raw_key(properties->KeyAt(i)); + if (properties->IsKey(raw_key)) { + DCHECK(raw_key->IsName()); + // If the property is already there we skip it. + Handle<Name> key(Name::cast(raw_key)); + LookupIterator it(to, key, LookupIterator::OWN_SKIP_INTERCEPTOR); + CHECK_NE(LookupIterator::ACCESS_CHECK, it.state()); + if (it.IsFound()) continue; + // Set the property. + DCHECK(properties->ValueAt(i)->IsPropertyCell()); + Handle<PropertyCell> cell(PropertyCell::cast(properties->ValueAt(i))); + Handle<Object> value(cell->value(), isolate()); + if (value->IsTheHole()) continue; + PropertyDetails details = cell->property_details(); + DCHECK_EQ(kData, details.kind()); + JSObject::AddProperty(to, key, value, details.attributes()); + } + } } else { Handle<NameDictionary> properties = Handle<NameDictionary>(from->property_dictionary()); @@ -2810,10 +3006,7 @@ void Genesis::TransferNamedProperties(Handle<JSObject> from, Handle<Object> value = Handle<Object>(properties->ValueAt(i), isolate()); DCHECK(!value->IsCell()); - if (value->IsPropertyCell()) { - value = handle(PropertyCell::cast(*value)->value(), isolate()); - } - if (value->IsTheHole()) continue; + DCHECK(!value->IsTheHole()); PropertyDetails details = properties->DetailsAt(i); DCHECK_EQ(kData, details.kind()); JSObject::AddProperty(to, key, value, details.attributes()); @@ -2889,10 +3082,9 @@ class NoTrackDoubleFieldsForSerializerScope { Genesis::Genesis(Isolate* isolate, MaybeHandle<JSGlobalProxy> maybe_global_proxy, - v8::Handle<v8::ObjectTemplate> global_proxy_template, + v8::Local<v8::ObjectTemplate> global_proxy_template, v8::ExtensionConfiguration* extensions) - : isolate_(isolate), - active_(isolate->bootstrapper()) { + : isolate_(isolate), active_(isolate->bootstrapper()) { NoTrackDoubleFieldsForSerializerScope disable_scope(isolate); result_ = Handle<Context>::null(); // Before creating the roots we must save the context and restore it @@ -2903,7 +3095,10 @@ Genesis::Genesis(Isolate* isolate, // environment has been at least partially initialized. Add a stack check // before entering JS code to catch overflow early. StackLimitCheck check(isolate); - if (check.HasOverflowed()) return; + if (check.HasOverflowed()) { + isolate->StackOverflow(); + return; + } // The deserializer needs to hook up references to the global proxy. // Create an uninitialized global proxy now if we don't have one @@ -2915,6 +3110,7 @@ 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() || !Snapshot::NewContextFromSnapshot(isolate, global_proxy, @@ -2943,6 +3139,7 @@ Genesis::Genesis(Isolate* isolate, HookUpGlobalObject(global_object, outdated_contexts); native_context()->builtins()->set_global_proxy( native_context()->global_proxy()); + HookUpGlobalThisBinding(outdated_contexts); if (!ConfigureGlobalObjects(global_proxy_template)) return; } else { @@ -3010,4 +3207,5 @@ void Bootstrapper::FreeThreadResources() { DCHECK(!IsActive()); } -} } // namespace v8::internal +} // namespace internal +} // namespace v8 |