1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "src/bootstrapper.h"
7 #include "src/accessors.h"
8 #include "src/api-natives.h"
9 #include "src/code-stubs.h"
10 #include "src/extensions/externalize-string-extension.h"
11 #include "src/extensions/free-buffer-extension.h"
12 #include "src/extensions/gc-extension.h"
13 #include "src/extensions/statistics-extension.h"
14 #include "src/extensions/trigger-failure-extension.h"
15 #include "src/isolate-inl.h"
16 #include "src/natives.h"
17 #include "src/snapshot.h"
18 #include "third_party/fdlibm/fdlibm.h"
23 Bootstrapper::Bootstrapper(Isolate* isolate)
26 extensions_cache_(Script::TYPE_EXTENSION) {}
29 Handle<String> Bootstrapper::NativesSourceLookup(int index) {
30 DCHECK(0 <= index && index < Natives::GetBuiltinsCount());
31 Heap* heap = isolate_->heap();
32 if (heap->natives_source_cache()->get(index)->IsUndefined()) {
33 // We can use external strings for the natives.
34 Vector<const char> source = Natives::GetScriptSource(index);
35 NativesExternalStringResource* resource =
36 new NativesExternalStringResource(source.start(), source.length());
37 // We do not expect this to throw an exception. Change this if it does.
38 Handle<String> source_code = isolate_->factory()
39 ->NewExternalStringFromOneByte(resource)
41 // Mark this external string with a special map.
42 source_code->set_map(isolate_->heap()->native_source_string_map());
43 heap->natives_source_cache()->set(index, *source_code);
45 Handle<Object> cached_source(heap->natives_source_cache()->get(index),
47 return Handle<String>::cast(cached_source);
51 void Bootstrapper::Initialize(bool create_heap_objects) {
52 extensions_cache_.Initialize(isolate_, create_heap_objects);
56 static const char* GCFunctionName() {
57 bool flag_given = FLAG_expose_gc_as != NULL && strlen(FLAG_expose_gc_as) != 0;
58 return flag_given ? FLAG_expose_gc_as : "gc";
62 v8::Extension* Bootstrapper::free_buffer_extension_ = NULL;
63 v8::Extension* Bootstrapper::gc_extension_ = NULL;
64 v8::Extension* Bootstrapper::externalize_string_extension_ = NULL;
65 v8::Extension* Bootstrapper::statistics_extension_ = NULL;
66 v8::Extension* Bootstrapper::trigger_failure_extension_ = NULL;
69 void Bootstrapper::InitializeOncePerProcess() {
70 free_buffer_extension_ = new FreeBufferExtension;
71 v8::RegisterExtension(free_buffer_extension_);
72 gc_extension_ = new GCExtension(GCFunctionName());
73 v8::RegisterExtension(gc_extension_);
74 externalize_string_extension_ = new ExternalizeStringExtension;
75 v8::RegisterExtension(externalize_string_extension_);
76 statistics_extension_ = new StatisticsExtension;
77 v8::RegisterExtension(statistics_extension_);
78 trigger_failure_extension_ = new TriggerFailureExtension;
79 v8::RegisterExtension(trigger_failure_extension_);
83 void Bootstrapper::TearDownExtensions() {
84 delete free_buffer_extension_;
85 free_buffer_extension_ = NULL;
88 delete externalize_string_extension_;
89 externalize_string_extension_ = NULL;
90 delete statistics_extension_;
91 statistics_extension_ = NULL;
92 delete trigger_failure_extension_;
93 trigger_failure_extension_ = NULL;
97 void Bootstrapper::TearDown() {
98 Object* natives_source_cache = isolate_->heap()->natives_source_cache();
99 if (natives_source_cache->IsFixedArray()) {
100 FixedArray* natives_source_array = FixedArray::cast(natives_source_cache);
101 for (int i = 0; i < Natives::GetBuiltinsCount(); i++) {
102 Object* natives_source = natives_source_array->get(i);
103 if (!natives_source->IsUndefined()) {
104 const NativesExternalStringResource* resource =
105 reinterpret_cast<const NativesExternalStringResource*>(
106 ExternalOneByteString::cast(natives_source)->resource());
112 extensions_cache_.Initialize(isolate_, false); // Yes, symmetrical
116 class Genesis BASE_EMBEDDED {
118 Genesis(Isolate* isolate,
119 MaybeHandle<JSGlobalProxy> maybe_global_proxy,
120 v8::Handle<v8::ObjectTemplate> global_proxy_template,
121 v8::ExtensionConfiguration* extensions);
124 Isolate* isolate() const { return isolate_; }
125 Factory* factory() const { return isolate_->factory(); }
126 Heap* heap() const { return isolate_->heap(); }
128 Handle<Context> result() { return result_; }
131 Handle<Context> native_context() { return native_context_; }
133 // Creates some basic objects. Used for creating a context from scratch.
135 // Creates the empty function. Used for creating a context from scratch.
136 Handle<JSFunction> CreateEmptyFunction(Isolate* isolate);
137 // Creates the ThrowTypeError function. ECMA 5th Ed. 13.2.3
138 Handle<JSFunction> GetStrictPoisonFunction();
139 // Poison for sloppy generator function arguments/callee.
140 Handle<JSFunction> GetGeneratorPoisonFunction();
142 void CreateStrictModeFunctionMaps(Handle<JSFunction> empty);
144 // Make the "arguments" and "caller" properties throw a TypeError on access.
145 void PoisonArgumentsAndCaller(Handle<Map> map);
147 // Creates the global objects using the global proxy and the template passed
148 // in through the API. We call this regardless of whether we are building a
149 // context from scratch or using a deserialized one from the partial snapshot
150 // but in the latter case we don't use the objects it produces directly, as
151 // we have to used the deserialized ones that are linked together with the
152 // rest of the context snapshot.
153 Handle<GlobalObject> CreateNewGlobals(
154 v8::Handle<v8::ObjectTemplate> global_proxy_template,
155 Handle<JSGlobalProxy> global_proxy);
156 // Hooks the given global proxy into the context. If the context was created
157 // by deserialization then this will unhook the global proxy that was
158 // deserialized, leaving the GC to pick it up.
159 void HookUpGlobalProxy(Handle<GlobalObject> global_object,
160 Handle<JSGlobalProxy> global_proxy);
161 // Similarly, we want to use the global that has been created by the templates
162 // passed through the API. The global from the snapshot is detached from the
163 // other objects in the snapshot.
164 void HookUpGlobalObject(Handle<GlobalObject> global_object,
165 Handle<FixedArray> outdated_contexts);
166 // New context initialization. Used for creating a context from scratch.
167 void InitializeGlobal(Handle<GlobalObject> global_object,
168 Handle<JSFunction> empty_function);
169 void InitializeExperimentalGlobal();
170 // Installs the contents of the native .js files on the global objects.
171 // Used for creating a context from scratch.
172 void InstallNativeFunctions();
173 void InstallExperimentalNativeFunctions();
174 // Typed arrays are not serializable and have to initialized afterwards.
175 void InitializeBuiltinTypedArrays();
177 #define DECLARE_FEATURE_INITIALIZATION(id, descr) \
178 void InstallNativeFunctions_##id(); \
179 void InitializeGlobal_##id();
181 HARMONY_INPROGRESS(DECLARE_FEATURE_INITIALIZATION)
182 HARMONY_STAGED(DECLARE_FEATURE_INITIALIZATION)
183 HARMONY_SHIPPING(DECLARE_FEATURE_INITIALIZATION)
184 #undef DECLARE_FEATURE_INITIALIZATION
186 Handle<JSFunction> InstallInternalArray(Handle<JSBuiltinsObject> builtins,
188 ElementsKind elements_kind);
189 bool InstallNatives();
191 void InstallTypedArray(
193 ElementsKind elements_kind,
194 Handle<JSFunction>* fun,
195 Handle<Map>* external_map);
196 bool InstallExperimentalNatives();
197 void InstallBuiltinFunctionIds();
198 void InstallJSFunctionResultCaches();
199 void InitializeNormalizedMapCaches();
201 enum ExtensionTraversalState {
202 UNVISITED, VISITED, INSTALLED
205 class ExtensionStates {
208 ExtensionTraversalState get_state(RegisteredExtension* extension);
209 void set_state(RegisteredExtension* extension,
210 ExtensionTraversalState state);
213 DISALLOW_COPY_AND_ASSIGN(ExtensionStates);
216 // Used both for deserialized and from-scratch contexts to add the extensions
218 static bool InstallExtensions(Handle<Context> native_context,
219 v8::ExtensionConfiguration* extensions);
220 static bool InstallAutoExtensions(Isolate* isolate,
221 ExtensionStates* extension_states);
222 static bool InstallRequestedExtensions(Isolate* isolate,
223 v8::ExtensionConfiguration* extensions,
224 ExtensionStates* extension_states);
225 static bool InstallExtension(Isolate* isolate,
227 ExtensionStates* extension_states);
228 static bool InstallExtension(Isolate* isolate,
229 v8::RegisteredExtension* current,
230 ExtensionStates* extension_states);
231 static bool InstallSpecialObjects(Handle<Context> native_context);
232 bool InstallJSBuiltins(Handle<JSBuiltinsObject> builtins);
233 bool ConfigureApiObject(Handle<JSObject> object,
234 Handle<ObjectTemplateInfo> object_template);
235 bool ConfigureGlobalObjects(
236 v8::Handle<v8::ObjectTemplate> global_proxy_template);
238 // Migrates all properties from the 'from' object to the 'to'
239 // object and overrides the prototype in 'to' with the one from
241 void TransferObject(Handle<JSObject> from, Handle<JSObject> to);
242 void TransferNamedProperties(Handle<JSObject> from, Handle<JSObject> to);
243 void TransferIndexedProperties(Handle<JSObject> from, Handle<JSObject> to);
247 FUNCTION_WITH_WRITEABLE_PROTOTYPE,
248 FUNCTION_WITH_READONLY_PROTOTYPE,
249 // Without prototype.
250 FUNCTION_WITHOUT_PROTOTYPE,
254 static bool IsFunctionModeWithPrototype(FunctionMode function_mode) {
255 return (function_mode == FUNCTION_WITH_WRITEABLE_PROTOTYPE ||
256 function_mode == FUNCTION_WITH_READONLY_PROTOTYPE);
259 Handle<Map> CreateFunctionMap(FunctionMode function_mode);
261 void SetFunctionInstanceDescriptor(Handle<Map> map,
262 FunctionMode function_mode);
263 void MakeFunctionInstancePrototypeWritable();
265 Handle<Map> CreateStrictFunctionMap(
266 FunctionMode function_mode,
267 Handle<JSFunction> empty_function);
269 void SetStrictFunctionInstanceDescriptor(Handle<Map> map,
270 FunctionMode function_mode);
272 static bool CompileBuiltin(Isolate* isolate, int index);
273 static bool CompileExperimentalBuiltin(Isolate* isolate, int index);
274 static bool CompileNative(Isolate* isolate,
275 Vector<const char> name,
276 Handle<String> source);
277 static bool CompileScriptCached(Isolate* isolate,
278 Vector<const char> name,
279 Handle<String> source,
280 SourceCodeCache* cache,
281 v8::Extension* extension,
282 Handle<Context> top_context,
283 bool use_runtime_context);
286 Handle<Context> result_;
287 Handle<Context> native_context_;
289 // Function maps. Function maps are created initially with a read only
290 // prototype for the processing of JS builtins. Later the function maps are
291 // replaced in order to make prototype writable. These are the final, writable
293 Handle<Map> sloppy_function_map_writable_prototype_;
294 Handle<Map> strict_function_map_writable_prototype_;
295 Handle<JSFunction> strict_poison_function;
296 Handle<JSFunction> generator_poison_function;
298 BootstrapperActive active_;
299 friend class Bootstrapper;
303 void Bootstrapper::Iterate(ObjectVisitor* v) {
304 extensions_cache_.Iterate(v);
305 v->Synchronize(VisitorSynchronization::kExtensions);
309 Handle<Context> Bootstrapper::CreateEnvironment(
310 MaybeHandle<JSGlobalProxy> maybe_global_proxy,
311 v8::Handle<v8::ObjectTemplate> global_proxy_template,
312 v8::ExtensionConfiguration* extensions) {
313 HandleScope scope(isolate_);
315 isolate_, maybe_global_proxy, global_proxy_template, extensions);
316 Handle<Context> env = genesis.result();
317 if (env.is_null() || !InstallExtensions(env, extensions)) {
318 return Handle<Context>();
320 return scope.CloseAndEscape(env);
324 static void SetObjectPrototype(Handle<JSObject> object, Handle<Object> proto) {
325 // object.__proto__ = proto;
326 Handle<Map> old_map = Handle<Map>(object->map());
327 Handle<Map> new_map = Map::Copy(old_map, "SetObjectPrototype");
328 new_map->SetPrototype(proto, FAST_PROTOTYPE);
329 JSObject::MigrateToMap(object, new_map);
333 void Bootstrapper::DetachGlobal(Handle<Context> env) {
334 Factory* factory = env->GetIsolate()->factory();
335 Handle<JSGlobalProxy> global_proxy(JSGlobalProxy::cast(env->global_proxy()));
336 global_proxy->set_native_context(*factory->null_value());
337 SetObjectPrototype(global_proxy, factory->null_value());
338 global_proxy->map()->set_constructor(*factory->null_value());
339 if (FLAG_track_detached_contexts) {
340 env->GetIsolate()->AddDetachedContext(env);
345 static Handle<JSFunction> InstallFunction(Handle<JSObject> target,
349 MaybeHandle<JSObject> maybe_prototype,
350 Builtins::Name call) {
351 Isolate* isolate = target->GetIsolate();
352 Factory* factory = isolate->factory();
353 Handle<String> internalized_name = factory->InternalizeUtf8String(name);
354 Handle<Code> call_code = Handle<Code>(isolate->builtins()->builtin(call));
355 Handle<JSObject> prototype;
356 Handle<JSFunction> function = maybe_prototype.ToHandle(&prototype)
357 ? factory->NewFunction(internalized_name, call_code, prototype,
359 : factory->NewFunctionWithoutPrototype(internalized_name, call_code);
360 PropertyAttributes attributes;
361 if (target->IsJSBuiltinsObject()) {
363 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
365 attributes = DONT_ENUM;
367 JSObject::AddProperty(target, internalized_name, function, attributes);
368 if (target->IsJSGlobalObject()) {
369 function->shared()->set_instance_class_name(*internalized_name);
371 function->shared()->set_native(true);
376 void Genesis::SetFunctionInstanceDescriptor(
377 Handle<Map> map, FunctionMode function_mode) {
378 int size = IsFunctionModeWithPrototype(function_mode) ? 5 : 4;
379 Map::EnsureDescriptorSlack(map, size);
381 PropertyAttributes attribs = static_cast<PropertyAttributes>(
382 DONT_ENUM | DONT_DELETE | READ_ONLY);
384 Handle<AccessorInfo> length =
385 Accessors::FunctionLengthInfo(isolate(), attribs);
387 AccessorConstantDescriptor d(Handle<Name>(Name::cast(length->name())),
389 map->AppendDescriptor(&d);
391 Handle<AccessorInfo> name =
392 Accessors::FunctionNameInfo(isolate(), attribs);
394 AccessorConstantDescriptor d(Handle<Name>(Name::cast(name->name())), name,
396 map->AppendDescriptor(&d);
398 Handle<AccessorInfo> args =
399 Accessors::FunctionArgumentsInfo(isolate(), attribs);
401 AccessorConstantDescriptor d(Handle<Name>(Name::cast(args->name())), args,
403 map->AppendDescriptor(&d);
405 Handle<AccessorInfo> caller =
406 Accessors::FunctionCallerInfo(isolate(), attribs);
408 AccessorConstantDescriptor d(Handle<Name>(Name::cast(caller->name())),
410 map->AppendDescriptor(&d);
412 if (IsFunctionModeWithPrototype(function_mode)) {
413 if (function_mode == FUNCTION_WITH_WRITEABLE_PROTOTYPE) {
414 attribs = static_cast<PropertyAttributes>(attribs & ~READ_ONLY);
416 Handle<AccessorInfo> prototype =
417 Accessors::FunctionPrototypeInfo(isolate(), attribs);
418 AccessorConstantDescriptor d(Handle<Name>(Name::cast(prototype->name())),
420 map->AppendDescriptor(&d);
425 Handle<Map> Genesis::CreateFunctionMap(FunctionMode function_mode) {
426 Handle<Map> map = factory()->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
427 SetFunctionInstanceDescriptor(map, function_mode);
428 map->set_function_with_prototype(IsFunctionModeWithPrototype(function_mode));
433 Handle<JSFunction> Genesis::CreateEmptyFunction(Isolate* isolate) {
434 // Allocate the map for function instances. Maps are allocated first and their
435 // prototypes patched later, once empty function is created.
437 // Functions with this map will not have a 'prototype' property, and
438 // can not be used as constructors.
439 Handle<Map> function_without_prototype_map =
440 CreateFunctionMap(FUNCTION_WITHOUT_PROTOTYPE);
441 native_context()->set_sloppy_function_without_prototype_map(
442 *function_without_prototype_map);
444 // Allocate the function map. This map is temporary, used only for processing
446 // Later the map is replaced with writable prototype map, allocated below.
447 Handle<Map> function_map =
448 CreateFunctionMap(FUNCTION_WITH_READONLY_PROTOTYPE);
449 native_context()->set_sloppy_function_map(*function_map);
450 native_context()->set_sloppy_function_with_readonly_prototype_map(
453 // The final map for functions. Writeable prototype.
454 // This map is installed in MakeFunctionInstancePrototypeWritable.
455 sloppy_function_map_writable_prototype_ =
456 CreateFunctionMap(FUNCTION_WITH_WRITEABLE_PROTOTYPE);
458 Factory* factory = isolate->factory();
460 Handle<String> object_name = factory->Object_string();
462 Handle<JSObject> object_function_prototype;
464 { // --- O b j e c t ---
465 Handle<JSFunction> object_fun = factory->NewFunction(object_name);
466 int unused = JSObject::kInitialGlobalObjectUnusedPropertiesCount;
467 int instance_size = JSObject::kHeaderSize + kPointerSize * unused;
468 Handle<Map> object_function_map =
469 factory->NewMap(JS_OBJECT_TYPE, instance_size);
470 object_function_map->set_inobject_properties(unused);
471 JSFunction::SetInitialMap(object_fun, object_function_map,
472 isolate->factory()->null_value());
473 object_function_map->set_unused_property_fields(unused);
475 native_context()->set_object_function(*object_fun);
477 // Allocate a new prototype for the object function.
478 object_function_prototype =
479 factory->NewJSObject(isolate->object_function(), TENURED);
480 Handle<Map> map = Map::Copy(handle(object_function_prototype->map()),
481 "EmptyObjectPrototype");
482 map->set_is_prototype_map(true);
483 object_function_prototype->set_map(*map);
485 native_context()->set_initial_object_prototype(*object_function_prototype);
486 // For bootstrapping set the array prototype to be the same as the object
487 // prototype, otherwise the missing initial_array_prototype will cause
488 // assertions during startup.
489 native_context()->set_initial_array_prototype(*object_function_prototype);
490 Accessors::FunctionSetPrototype(object_fun, object_function_prototype)
494 // Allocate the empty function as the prototype for function ECMAScript
496 Handle<String> empty_string =
497 factory->InternalizeOneByteString(STATIC_CHAR_VECTOR("Empty"));
498 Handle<Code> code(isolate->builtins()->builtin(Builtins::kEmptyFunction));
499 Handle<JSFunction> empty_function = factory->NewFunctionWithoutPrototype(
502 // Allocate the function map first and then patch the prototype later
503 Handle<Map> empty_function_map =
504 CreateFunctionMap(FUNCTION_WITHOUT_PROTOTYPE);
505 DCHECK(!empty_function_map->is_dictionary_map());
506 empty_function_map->SetPrototype(object_function_prototype);
507 empty_function_map->set_is_prototype_map(true);
508 empty_function->set_map(*empty_function_map);
511 Handle<String> source = factory->NewStringFromStaticChars("() {}");
512 Handle<Script> script = factory->NewScript(source);
513 script->set_type(Smi::FromInt(Script::TYPE_NATIVE));
514 empty_function->shared()->set_script(*script);
515 empty_function->shared()->set_start_position(0);
516 empty_function->shared()->set_end_position(source->length());
517 empty_function->shared()->DontAdaptArguments();
519 // Set prototypes for the function maps.
520 native_context()->sloppy_function_map()->SetPrototype(empty_function);
521 native_context()->sloppy_function_without_prototype_map()->SetPrototype(
523 sloppy_function_map_writable_prototype_->SetPrototype(empty_function);
524 return empty_function;
528 void Genesis::SetStrictFunctionInstanceDescriptor(
529 Handle<Map> map, FunctionMode function_mode) {
530 int size = IsFunctionModeWithPrototype(function_mode) ? 5 : 4;
531 Map::EnsureDescriptorSlack(map, size);
533 Handle<AccessorPair> arguments(factory()->NewAccessorPair());
534 Handle<AccessorPair> caller(factory()->NewAccessorPair());
535 PropertyAttributes rw_attribs =
536 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
537 PropertyAttributes ro_attribs =
538 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
541 if (function_mode == BOUND_FUNCTION) {
542 Handle<String> length_string = isolate()->factory()->length_string();
543 DataDescriptor d(length_string, 0, ro_attribs, Representation::Tagged());
544 map->AppendDescriptor(&d);
546 DCHECK(function_mode == FUNCTION_WITH_WRITEABLE_PROTOTYPE ||
547 function_mode == FUNCTION_WITH_READONLY_PROTOTYPE ||
548 function_mode == FUNCTION_WITHOUT_PROTOTYPE);
549 Handle<AccessorInfo> length =
550 Accessors::FunctionLengthInfo(isolate(), ro_attribs);
551 AccessorConstantDescriptor d(Handle<Name>(Name::cast(length->name())),
553 map->AppendDescriptor(&d);
555 Handle<AccessorInfo> name =
556 Accessors::FunctionNameInfo(isolate(), ro_attribs);
558 AccessorConstantDescriptor d(Handle<Name>(Name::cast(name->name())), name,
560 map->AppendDescriptor(&d);
563 AccessorConstantDescriptor d(factory()->arguments_string(), arguments,
565 map->AppendDescriptor(&d);
568 AccessorConstantDescriptor d(factory()->caller_string(), caller,
570 map->AppendDescriptor(&d);
572 if (IsFunctionModeWithPrototype(function_mode)) {
574 PropertyAttributes attribs =
575 function_mode == FUNCTION_WITH_WRITEABLE_PROTOTYPE ? rw_attribs
577 Handle<AccessorInfo> prototype =
578 Accessors::FunctionPrototypeInfo(isolate(), attribs);
579 AccessorConstantDescriptor d(Handle<Name>(Name::cast(prototype->name())),
581 map->AppendDescriptor(&d);
586 // ECMAScript 5th Edition, 13.2.3
587 Handle<JSFunction> Genesis::GetStrictPoisonFunction() {
588 if (strict_poison_function.is_null()) {
589 Handle<String> name = factory()->InternalizeOneByteString(
590 STATIC_CHAR_VECTOR("ThrowTypeError"));
591 Handle<Code> code(isolate()->builtins()->builtin(
592 Builtins::kStrictModePoisonPill));
593 strict_poison_function = factory()->NewFunctionWithoutPrototype(name, code);
594 strict_poison_function->set_map(native_context()->sloppy_function_map());
595 strict_poison_function->shared()->DontAdaptArguments();
597 JSObject::PreventExtensions(strict_poison_function).Assert();
599 return strict_poison_function;
603 Handle<JSFunction> Genesis::GetGeneratorPoisonFunction() {
604 if (generator_poison_function.is_null()) {
605 Handle<String> name = factory()->InternalizeOneByteString(
606 STATIC_CHAR_VECTOR("ThrowTypeError"));
607 Handle<Code> code(isolate()->builtins()->builtin(
608 Builtins::kGeneratorPoisonPill));
609 generator_poison_function = factory()->NewFunctionWithoutPrototype(
611 generator_poison_function->set_map(native_context()->sloppy_function_map());
612 generator_poison_function->shared()->DontAdaptArguments();
614 JSObject::PreventExtensions(generator_poison_function).Assert();
616 return generator_poison_function;
620 Handle<Map> Genesis::CreateStrictFunctionMap(
621 FunctionMode function_mode,
622 Handle<JSFunction> empty_function) {
623 Handle<Map> map = factory()->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
624 SetStrictFunctionInstanceDescriptor(map, function_mode);
625 map->set_function_with_prototype(IsFunctionModeWithPrototype(function_mode));
626 map->SetPrototype(empty_function);
631 void Genesis::CreateStrictModeFunctionMaps(Handle<JSFunction> empty) {
632 // Allocate map for the prototype-less strict mode instances.
633 Handle<Map> strict_function_without_prototype_map =
634 CreateStrictFunctionMap(FUNCTION_WITHOUT_PROTOTYPE, empty);
635 native_context()->set_strict_function_without_prototype_map(
636 *strict_function_without_prototype_map);
638 // Allocate map for the strict mode functions. This map is temporary, used
639 // only for processing of builtins.
640 // Later the map is replaced with writable prototype map, allocated below.
641 Handle<Map> strict_function_map =
642 CreateStrictFunctionMap(FUNCTION_WITH_READONLY_PROTOTYPE, empty);
643 native_context()->set_strict_function_map(*strict_function_map);
645 // The final map for the strict mode functions. Writeable prototype.
646 // This map is installed in MakeFunctionInstancePrototypeWritable.
647 strict_function_map_writable_prototype_ =
648 CreateStrictFunctionMap(FUNCTION_WITH_WRITEABLE_PROTOTYPE, empty);
649 // Special map for bound functions.
650 Handle<Map> bound_function_map =
651 CreateStrictFunctionMap(BOUND_FUNCTION, empty);
652 native_context()->set_bound_function_map(*bound_function_map);
654 // Complete the callbacks.
655 PoisonArgumentsAndCaller(strict_function_without_prototype_map);
656 PoisonArgumentsAndCaller(strict_function_map);
657 PoisonArgumentsAndCaller(strict_function_map_writable_prototype_);
658 PoisonArgumentsAndCaller(bound_function_map);
662 static void SetAccessors(Handle<Map> map,
664 Handle<JSFunction> func) {
665 DescriptorArray* descs = map->instance_descriptors();
666 int number = descs->SearchWithCache(*name, *map);
667 AccessorPair* accessors = AccessorPair::cast(descs->GetValue(number));
668 accessors->set_getter(*func);
669 accessors->set_setter(*func);
673 static void ReplaceAccessors(Handle<Map> map,
675 PropertyAttributes attributes,
676 Handle<AccessorPair> accessor_pair) {
677 DescriptorArray* descriptors = map->instance_descriptors();
678 int idx = descriptors->SearchWithCache(*name, *map);
679 AccessorConstantDescriptor descriptor(name, accessor_pair, attributes);
680 descriptors->Replace(idx, &descriptor);
684 void Genesis::PoisonArgumentsAndCaller(Handle<Map> map) {
685 SetAccessors(map, factory()->arguments_string(), GetStrictPoisonFunction());
686 SetAccessors(map, factory()->caller_string(), GetStrictPoisonFunction());
690 static void AddToWeakNativeContextList(Context* context) {
691 DCHECK(context->IsNativeContext());
692 Heap* heap = context->GetIsolate()->heap();
695 DCHECK(context->get(Context::NEXT_CONTEXT_LINK)->IsUndefined());
696 // Check that context is not in the list yet.
697 for (Object* current = heap->native_contexts_list();
698 !current->IsUndefined();
699 current = Context::cast(current)->get(Context::NEXT_CONTEXT_LINK)) {
700 DCHECK(current != context);
704 context->set(Context::NEXT_CONTEXT_LINK, heap->native_contexts_list());
705 heap->set_native_contexts_list(context);
709 void Genesis::CreateRoots() {
710 // Allocate the native context FixedArray first and then patch the
711 // closure and extension object later (we need the empty function
712 // and the global object, but in order to create those, we need the
714 native_context_ = factory()->NewNativeContext();
715 AddToWeakNativeContextList(*native_context());
716 isolate()->set_context(*native_context());
718 // Allocate the message listeners object.
720 v8::NeanderArray listeners(isolate());
721 native_context()->set_message_listeners(*listeners.value());
726 Handle<GlobalObject> Genesis::CreateNewGlobals(
727 v8::Handle<v8::ObjectTemplate> global_proxy_template,
728 Handle<JSGlobalProxy> global_proxy) {
729 // The argument global_proxy_template aka data is an ObjectTemplateInfo.
730 // It has a constructor pointer that points at global_constructor which is a
731 // FunctionTemplateInfo.
732 // The global_proxy_constructor is used to (re)initialize the
733 // global_proxy. The global_proxy_constructor also has a prototype_template
734 // pointer that points at js_global_object_template which is an
735 // ObjectTemplateInfo.
736 // That in turn has a constructor pointer that points at
737 // js_global_object_constructor which is a FunctionTemplateInfo.
738 // js_global_object_constructor is used to make js_global_object_function
739 // js_global_object_function is used to make the new global_object.
741 // --- G l o b a l ---
742 // Step 1: Create a fresh JSGlobalObject.
743 Handle<JSFunction> js_global_object_function;
744 Handle<ObjectTemplateInfo> js_global_object_template;
745 if (!global_proxy_template.IsEmpty()) {
746 // Get prototype template of the global_proxy_template.
747 Handle<ObjectTemplateInfo> data =
748 v8::Utils::OpenHandle(*global_proxy_template);
749 Handle<FunctionTemplateInfo> global_constructor =
750 Handle<FunctionTemplateInfo>(
751 FunctionTemplateInfo::cast(data->constructor()));
752 Handle<Object> proto_template(global_constructor->prototype_template(),
754 if (!proto_template->IsUndefined()) {
755 js_global_object_template =
756 Handle<ObjectTemplateInfo>::cast(proto_template);
760 if (js_global_object_template.is_null()) {
761 Handle<String> name = Handle<String>(heap()->empty_string());
762 Handle<Code> code = Handle<Code>(isolate()->builtins()->builtin(
763 Builtins::kIllegal));
764 Handle<JSObject> prototype =
765 factory()->NewFunctionPrototype(isolate()->object_function());
766 js_global_object_function = factory()->NewFunction(
767 name, code, prototype, JS_GLOBAL_OBJECT_TYPE, JSGlobalObject::kSize);
769 LookupIterator it(prototype, factory()->constructor_string(),
770 LookupIterator::OWN_SKIP_INTERCEPTOR);
771 Handle<Object> value = JSReceiver::GetProperty(&it).ToHandleChecked();
772 DCHECK(it.IsFound());
773 DCHECK_EQ(*isolate()->object_function(), *value);
776 Handle<FunctionTemplateInfo> js_global_object_constructor(
777 FunctionTemplateInfo::cast(js_global_object_template->constructor()));
778 js_global_object_function = ApiNatives::CreateApiFunction(
779 isolate(), js_global_object_constructor, factory()->the_hole_value(),
780 ApiNatives::GlobalObjectType);
783 js_global_object_function->initial_map()->set_is_hidden_prototype();
784 js_global_object_function->initial_map()->set_dictionary_map(true);
785 Handle<GlobalObject> global_object =
786 factory()->NewGlobalObject(js_global_object_function);
788 // Step 2: (re)initialize the global proxy object.
789 Handle<JSFunction> global_proxy_function;
790 if (global_proxy_template.IsEmpty()) {
791 Handle<String> name = Handle<String>(heap()->empty_string());
792 Handle<Code> code = Handle<Code>(isolate()->builtins()->builtin(
793 Builtins::kIllegal));
794 global_proxy_function = factory()->NewFunction(
795 name, code, JS_GLOBAL_PROXY_TYPE, JSGlobalProxy::kSize);
797 Handle<ObjectTemplateInfo> data =
798 v8::Utils::OpenHandle(*global_proxy_template);
799 Handle<FunctionTemplateInfo> global_constructor(
800 FunctionTemplateInfo::cast(data->constructor()));
801 global_proxy_function = ApiNatives::CreateApiFunction(
802 isolate(), global_constructor, factory()->the_hole_value(),
803 ApiNatives::GlobalProxyType);
806 Handle<String> global_name = factory()->global_string();
807 global_proxy_function->shared()->set_instance_class_name(*global_name);
808 global_proxy_function->initial_map()->set_is_access_check_needed(true);
810 // Set global_proxy.__proto__ to js_global after ConfigureGlobalObjects
811 // Return the global proxy.
813 factory()->ReinitializeJSGlobalProxy(global_proxy, global_proxy_function);
814 return global_object;
818 void Genesis::HookUpGlobalProxy(Handle<GlobalObject> global_object,
819 Handle<JSGlobalProxy> global_proxy) {
820 // Set the native context for the global object.
821 global_object->set_native_context(*native_context());
822 global_object->set_global_proxy(*global_proxy);
823 global_proxy->set_native_context(*native_context());
824 // If we deserialized the context, the global proxy is already
825 // correctly set up. Otherwise it's undefined.
826 DCHECK(native_context()->get(Context::GLOBAL_PROXY_INDEX)->IsUndefined() ||
827 native_context()->global_proxy() == *global_proxy);
828 native_context()->set_global_proxy(*global_proxy);
832 void Genesis::HookUpGlobalObject(Handle<GlobalObject> global_object,
833 Handle<FixedArray> outdated_contexts) {
834 Handle<GlobalObject> global_object_from_snapshot(
835 GlobalObject::cast(native_context()->extension()));
836 Handle<JSBuiltinsObject> builtins_global(native_context()->builtins());
837 native_context()->set_extension(*global_object);
838 native_context()->set_security_token(*global_object);
840 // Replace outdated global objects in deserialized contexts.
841 for (int i = 0; i < outdated_contexts->length(); ++i) {
842 Context* context = Context::cast(outdated_contexts->get(i));
843 DCHECK_EQ(context->global_object(), *global_object_from_snapshot);
844 context->set_global_object(*global_object);
847 static const PropertyAttributes attributes =
848 static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE);
849 Runtime::DefineObjectProperty(builtins_global, factory()->global_string(),
850 global_object, attributes).Assert();
851 // Set up the reference from the global object to the builtins object.
852 JSGlobalObject::cast(*global_object)->set_builtins(*builtins_global);
853 TransferNamedProperties(global_object_from_snapshot, global_object);
854 TransferIndexedProperties(global_object_from_snapshot, global_object);
858 // This is only called if we are not using snapshots. The equivalent
859 // work in the snapshot case is done in HookUpGlobalObject.
860 void Genesis::InitializeGlobal(Handle<GlobalObject> global_object,
861 Handle<JSFunction> empty_function) {
862 // --- N a t i v e C o n t e x t ---
863 // Use the empty function as closure (no scope info).
864 native_context()->set_closure(*empty_function);
865 native_context()->set_previous(NULL);
866 // Set extension and global object.
867 native_context()->set_extension(*global_object);
868 native_context()->set_global_object(*global_object);
869 // Security setup: Set the security token of the native context to the global
870 // object. This makes the security check between two different contexts fail
871 // by default even in case of global object reinitialization.
872 native_context()->set_security_token(*global_object);
874 Isolate* isolate = global_object->GetIsolate();
875 Factory* factory = isolate->factory();
876 Heap* heap = isolate->heap();
878 Handle<ScriptContextTable> script_context_table =
879 factory->NewScriptContextTable();
880 native_context()->set_script_context_table(*script_context_table);
882 Handle<String> object_name = factory->Object_string();
883 JSObject::AddProperty(
884 global_object, object_name, isolate->object_function(), DONT_ENUM);
886 Handle<JSObject> global(native_context()->global_object());
888 // Install global Function object
889 InstallFunction(global, "Function", JS_FUNCTION_TYPE, JSFunction::kSize,
890 empty_function, Builtins::kIllegal);
892 { // --- A r r a y ---
893 Handle<JSFunction> array_function =
894 InstallFunction(global, "Array", JS_ARRAY_TYPE, JSArray::kSize,
895 isolate->initial_object_prototype(),
896 Builtins::kArrayCode);
897 array_function->shared()->DontAdaptArguments();
898 array_function->shared()->set_function_data(Smi::FromInt(kArrayCode));
900 // This seems a bit hackish, but we need to make sure Array.length
902 array_function->shared()->set_length(1);
904 Handle<Map> initial_map(array_function->initial_map());
906 // This assert protects an optimization in
907 // HGraphBuilder::JSArrayBuilder::EmitMapCode()
908 DCHECK(initial_map->elements_kind() == GetInitialFastElementsKind());
909 Map::EnsureDescriptorSlack(initial_map, 1);
911 PropertyAttributes attribs = static_cast<PropertyAttributes>(
912 DONT_ENUM | DONT_DELETE);
914 Handle<AccessorInfo> array_length =
915 Accessors::ArrayLengthInfo(isolate, attribs);
917 AccessorConstantDescriptor d(
918 Handle<Name>(Name::cast(array_length->name())), array_length,
920 initial_map->AppendDescriptor(&d);
923 // array_function is used internally. JS code creating array object should
924 // search for the 'Array' property on the global object and use that one
925 // as the constructor. 'Array' property on a global object can be
926 // overwritten by JS code.
927 native_context()->set_array_function(*array_function);
929 // Cache the array maps, needed by ArrayConstructorStub
930 CacheInitialJSArrayMaps(native_context(), initial_map);
931 ArrayConstructorStub array_constructor_stub(isolate);
932 Handle<Code> code = array_constructor_stub.GetCode();
933 array_function->shared()->set_construct_stub(*code);
936 { // --- N u m b e r ---
937 Handle<JSFunction> number_fun =
938 InstallFunction(global, "Number", JS_VALUE_TYPE, JSValue::kSize,
939 isolate->initial_object_prototype(),
941 native_context()->set_number_function(*number_fun);
944 { // --- B o o l e a n ---
945 Handle<JSFunction> boolean_fun =
946 InstallFunction(global, "Boolean", JS_VALUE_TYPE, JSValue::kSize,
947 isolate->initial_object_prototype(),
949 native_context()->set_boolean_function(*boolean_fun);
952 { // --- S t r i n g ---
953 Handle<JSFunction> string_fun =
954 InstallFunction(global, "String", JS_VALUE_TYPE, JSValue::kSize,
955 isolate->initial_object_prototype(),
957 string_fun->shared()->set_construct_stub(
958 isolate->builtins()->builtin(Builtins::kStringConstructCode));
959 native_context()->set_string_function(*string_fun);
961 Handle<Map> string_map =
962 Handle<Map>(native_context()->string_function()->initial_map());
963 Map::EnsureDescriptorSlack(string_map, 1);
965 PropertyAttributes attribs = static_cast<PropertyAttributes>(
966 DONT_ENUM | DONT_DELETE | READ_ONLY);
967 Handle<AccessorInfo> string_length(
968 Accessors::StringLengthInfo(isolate, attribs));
971 AccessorConstantDescriptor d(factory->length_string(), string_length,
973 string_map->AppendDescriptor(&d);
978 // --- S y m b o l ---
979 Handle<JSFunction> symbol_fun = InstallFunction(
980 global, "Symbol", JS_VALUE_TYPE, JSValue::kSize,
981 isolate->initial_object_prototype(), Builtins::kIllegal);
982 native_context()->set_symbol_function(*symbol_fun);
986 // Builtin functions for Date.prototype.
987 Handle<JSFunction> date_fun =
988 InstallFunction(global, "Date", JS_DATE_TYPE, JSDate::kSize,
989 isolate->initial_object_prototype(),
992 native_context()->set_date_function(*date_fun);
997 // Builtin functions for RegExp.prototype.
998 Handle<JSFunction> regexp_fun =
999 InstallFunction(global, "RegExp", JS_REGEXP_TYPE, JSRegExp::kSize,
1000 isolate->initial_object_prototype(),
1001 Builtins::kIllegal);
1002 native_context()->set_regexp_function(*regexp_fun);
1004 DCHECK(regexp_fun->has_initial_map());
1005 Handle<Map> initial_map(regexp_fun->initial_map());
1007 DCHECK_EQ(0, initial_map->inobject_properties());
1009 PropertyAttributes final =
1010 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
1011 Map::EnsureDescriptorSlack(initial_map, 5);
1014 // ECMA-262, section 15.10.7.1.
1015 Handle<AccessorInfo> regexp_source(
1016 Accessors::RegExpSourceInfo(isolate, final));
1017 AccessorConstantDescriptor d(factory->source_string(), regexp_source,
1019 initial_map->AppendDescriptor(&d);
1022 // ECMA-262, section 15.10.7.2.
1023 DataDescriptor field(factory->global_string(),
1024 JSRegExp::kGlobalFieldIndex, final,
1025 Representation::Tagged());
1026 initial_map->AppendDescriptor(&field);
1029 // ECMA-262, section 15.10.7.3.
1030 DataDescriptor field(factory->ignore_case_string(),
1031 JSRegExp::kIgnoreCaseFieldIndex, final,
1032 Representation::Tagged());
1033 initial_map->AppendDescriptor(&field);
1036 // ECMA-262, section 15.10.7.4.
1037 DataDescriptor field(factory->multiline_string(),
1038 JSRegExp::kMultilineFieldIndex, final,
1039 Representation::Tagged());
1040 initial_map->AppendDescriptor(&field);
1043 // ECMA-262, section 15.10.7.5.
1044 PropertyAttributes writable =
1045 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
1046 DataDescriptor field(factory->last_index_string(),
1047 JSRegExp::kLastIndexFieldIndex, writable,
1048 Representation::Tagged());
1049 initial_map->AppendDescriptor(&field);
1052 static const int num_fields = JSRegExp::kInObjectFieldCount;
1053 initial_map->set_inobject_properties(num_fields);
1054 initial_map->set_pre_allocated_property_fields(num_fields);
1055 initial_map->set_unused_property_fields(0);
1056 initial_map->set_instance_size(initial_map->instance_size() +
1057 num_fields * kPointerSize);
1059 // RegExp prototype object is itself a RegExp.
1060 Handle<Map> proto_map = Map::Copy(initial_map, "RegExpPrototype");
1061 DCHECK(proto_map->prototype() == *isolate->initial_object_prototype());
1062 Handle<JSObject> proto = factory->NewJSObjectFromMap(proto_map);
1063 proto->InObjectPropertyAtPut(JSRegExp::kGlobalFieldIndex,
1064 heap->false_value());
1065 proto->InObjectPropertyAtPut(JSRegExp::kIgnoreCaseFieldIndex,
1066 heap->false_value());
1067 proto->InObjectPropertyAtPut(JSRegExp::kMultilineFieldIndex,
1068 heap->false_value());
1069 proto->InObjectPropertyAtPut(JSRegExp::kLastIndexFieldIndex,
1071 SKIP_WRITE_BARRIER); // It's a Smi.
1072 proto_map->set_is_prototype_map(true);
1073 initial_map->SetPrototype(proto);
1074 factory->SetRegExpIrregexpData(Handle<JSRegExp>::cast(proto),
1075 JSRegExp::IRREGEXP, factory->empty_string(),
1076 JSRegExp::Flags(0), 0);
1080 Handle<String> name = factory->InternalizeUtf8String("JSON");
1081 Handle<JSFunction> cons = factory->NewFunction(name);
1082 JSFunction::SetInstancePrototype(cons,
1083 Handle<Object>(native_context()->initial_object_prototype(), isolate));
1084 cons->SetInstanceClassName(*name);
1085 Handle<JSObject> json_object = factory->NewJSObject(cons, TENURED);
1086 DCHECK(json_object->IsJSObject());
1087 JSObject::AddProperty(global, name, json_object, DONT_ENUM);
1088 native_context()->set_json_object(*json_object);
1091 { // -- A r r a y B u f f e r
1092 Handle<JSFunction> array_buffer_fun =
1094 global, "ArrayBuffer", JS_ARRAY_BUFFER_TYPE,
1095 JSArrayBuffer::kSizeWithInternalFields,
1096 isolate->initial_object_prototype(),
1097 Builtins::kIllegal);
1098 native_context()->set_array_buffer_fun(*array_buffer_fun);
1101 { // -- T y p e d A r r a y s
1102 #define INSTALL_TYPED_ARRAY(Type, type, TYPE, ctype, size) \
1104 Handle<JSFunction> fun; \
1105 Handle<Map> external_map; \
1106 InstallTypedArray(#Type "Array", \
1110 native_context()->set_##type##_array_fun(*fun); \
1111 native_context()->set_##type##_array_external_map(*external_map); \
1113 TYPED_ARRAYS(INSTALL_TYPED_ARRAY)
1114 #undef INSTALL_TYPED_ARRAY
1116 Handle<JSFunction> data_view_fun =
1118 global, "DataView", JS_DATA_VIEW_TYPE,
1119 JSDataView::kSizeWithInternalFields,
1120 isolate->initial_object_prototype(),
1121 Builtins::kIllegal);
1122 native_context()->set_data_view_fun(*data_view_fun);
1126 InstallFunction(global, "Map", JS_MAP_TYPE, JSMap::kSize,
1127 isolate->initial_object_prototype(), Builtins::kIllegal);
1130 InstallFunction(global, "Set", JS_SET_TYPE, JSSet::kSize,
1131 isolate->initial_object_prototype(), Builtins::kIllegal);
1133 { // Set up the iterator result object
1134 STATIC_ASSERT(JSGeneratorObject::kResultPropertyCount == 2);
1135 Handle<JSFunction> object_function(native_context()->object_function());
1136 Handle<Map> iterator_result_map =
1137 Map::Create(isolate, JSGeneratorObject::kResultPropertyCount);
1138 DCHECK_EQ(JSGeneratorObject::kResultSize,
1139 iterator_result_map->instance_size());
1140 DCHECK_EQ(JSGeneratorObject::kResultPropertyCount,
1141 iterator_result_map->inobject_properties());
1142 Map::EnsureDescriptorSlack(iterator_result_map,
1143 JSGeneratorObject::kResultPropertyCount);
1145 DataDescriptor value_descr(factory->value_string(),
1146 JSGeneratorObject::kResultValuePropertyIndex,
1147 NONE, Representation::Tagged());
1148 iterator_result_map->AppendDescriptor(&value_descr);
1150 DataDescriptor done_descr(factory->done_string(),
1151 JSGeneratorObject::kResultDonePropertyIndex, NONE,
1152 Representation::Tagged());
1153 iterator_result_map->AppendDescriptor(&done_descr);
1155 iterator_result_map->set_unused_property_fields(0);
1156 iterator_result_map->set_pre_allocated_property_fields(
1157 JSGeneratorObject::kResultPropertyCount);
1158 DCHECK_EQ(JSGeneratorObject::kResultSize,
1159 iterator_result_map->instance_size());
1160 native_context()->set_iterator_result_map(*iterator_result_map);
1164 InstallFunction(global, "WeakMap", JS_WEAK_MAP_TYPE, JSWeakMap::kSize,
1165 isolate->initial_object_prototype(), Builtins::kIllegal);
1167 InstallFunction(global, "WeakSet", JS_WEAK_SET_TYPE, JSWeakSet::kSize,
1168 isolate->initial_object_prototype(), Builtins::kIllegal);
1170 { // --- sloppy arguments map
1171 // Make sure we can recognize argument objects at runtime.
1172 // This is done by introducing an anonymous function with
1173 // class_name equals 'Arguments'.
1174 Handle<String> arguments_string = factory->Arguments_string();
1175 Handle<Code> code(isolate->builtins()->builtin(Builtins::kIllegal));
1176 Handle<JSFunction> function = factory->NewFunctionWithoutPrototype(
1177 arguments_string, code);
1178 function->shared()->set_instance_class_name(*arguments_string);
1181 factory->NewMap(JS_OBJECT_TYPE, Heap::kSloppyArgumentsObjectSize);
1182 // Create the descriptor array for the arguments object.
1183 Map::EnsureDescriptorSlack(map, 2);
1186 DataDescriptor d(factory->length_string(), Heap::kArgumentsLengthIndex,
1187 DONT_ENUM, Representation::Tagged());
1188 map->AppendDescriptor(&d);
1191 DataDescriptor d(factory->callee_string(), Heap::kArgumentsCalleeIndex,
1192 DONT_ENUM, Representation::Tagged());
1193 map->AppendDescriptor(&d);
1195 // @@iterator method is added later.
1197 map->set_function_with_prototype(true);
1198 map->set_pre_allocated_property_fields(2);
1199 map->set_inobject_properties(2);
1200 native_context()->set_sloppy_arguments_map(*map);
1202 DCHECK(!function->has_initial_map());
1203 JSFunction::SetInitialMap(function, map,
1204 isolate->initial_object_prototype());
1206 DCHECK(map->inobject_properties() > Heap::kArgumentsCalleeIndex);
1207 DCHECK(map->inobject_properties() > Heap::kArgumentsLengthIndex);
1208 DCHECK(!map->is_dictionary_map());
1209 DCHECK(IsFastObjectElementsKind(map->elements_kind()));
1212 { // --- aliased arguments map
1214 Map::Copy(isolate->sloppy_arguments_map(), "AliasedArguments");
1215 map->set_elements_kind(SLOPPY_ARGUMENTS_ELEMENTS);
1216 DCHECK_EQ(2, map->pre_allocated_property_fields());
1217 native_context()->set_aliased_arguments_map(*map);
1220 { // --- strict mode arguments map
1221 const PropertyAttributes attributes =
1222 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
1224 // Create the ThrowTypeError functions.
1225 Handle<AccessorPair> callee = factory->NewAccessorPair();
1226 Handle<AccessorPair> caller = factory->NewAccessorPair();
1228 Handle<JSFunction> poison = GetStrictPoisonFunction();
1230 // Install the ThrowTypeError functions.
1231 callee->set_getter(*poison);
1232 callee->set_setter(*poison);
1233 caller->set_getter(*poison);
1234 caller->set_setter(*poison);
1236 // Create the map. Allocate one in-object field for length.
1237 Handle<Map> map = factory->NewMap(JS_OBJECT_TYPE,
1238 Heap::kStrictArgumentsObjectSize);
1239 // Create the descriptor array for the arguments object.
1240 Map::EnsureDescriptorSlack(map, 3);
1243 DataDescriptor d(factory->length_string(), Heap::kArgumentsLengthIndex,
1244 DONT_ENUM, Representation::Tagged());
1245 map->AppendDescriptor(&d);
1248 AccessorConstantDescriptor d(factory->callee_string(), callee,
1250 map->AppendDescriptor(&d);
1253 AccessorConstantDescriptor d(factory->caller_string(), caller,
1255 map->AppendDescriptor(&d);
1257 // @@iterator method is added later.
1259 map->set_function_with_prototype(true);
1260 DCHECK_EQ(native_context()->object_function()->prototype(),
1261 *isolate->initial_object_prototype());
1262 map->SetPrototype(isolate->initial_object_prototype());
1263 map->set_pre_allocated_property_fields(1);
1264 map->set_inobject_properties(1);
1266 // Copy constructor from the sloppy arguments boilerplate.
1267 map->set_constructor(
1268 native_context()->sloppy_arguments_map()->constructor());
1270 native_context()->set_strict_arguments_map(*map);
1272 DCHECK(map->inobject_properties() > Heap::kArgumentsLengthIndex);
1273 DCHECK(!map->is_dictionary_map());
1274 DCHECK(IsFastObjectElementsKind(map->elements_kind()));
1277 { // --- context extension
1278 // Create a function for the context extension objects.
1279 Handle<Code> code = Handle<Code>(
1280 isolate->builtins()->builtin(Builtins::kIllegal));
1281 Handle<JSFunction> context_extension_fun = factory->NewFunction(
1282 factory->empty_string(), code, JS_CONTEXT_EXTENSION_OBJECT_TYPE,
1283 JSObject::kHeaderSize);
1285 Handle<String> name = factory->InternalizeOneByteString(
1286 STATIC_CHAR_VECTOR("context_extension"));
1287 context_extension_fun->shared()->set_instance_class_name(*name);
1288 native_context()->set_context_extension_function(*context_extension_fun);
1293 // Set up the call-as-function delegate.
1295 Handle<Code>(isolate->builtins()->builtin(
1296 Builtins::kHandleApiCallAsFunction));
1297 Handle<JSFunction> delegate = factory->NewFunction(
1298 factory->empty_string(), code, JS_OBJECT_TYPE, JSObject::kHeaderSize);
1299 native_context()->set_call_as_function_delegate(*delegate);
1300 delegate->shared()->DontAdaptArguments();
1304 // Set up the call-as-constructor delegate.
1306 Handle<Code>(isolate->builtins()->builtin(
1307 Builtins::kHandleApiCallAsConstructor));
1308 Handle<JSFunction> delegate = factory->NewFunction(
1309 factory->empty_string(), code, JS_OBJECT_TYPE, JSObject::kHeaderSize);
1310 native_context()->set_call_as_constructor_delegate(*delegate);
1311 delegate->shared()->DontAdaptArguments();
1314 // Initialize the embedder data slot.
1315 Handle<FixedArray> embedder_data = factory->NewFixedArray(3);
1316 native_context()->set_embedder_data(*embedder_data);
1320 void Genesis::InstallTypedArray(
1322 ElementsKind elements_kind,
1323 Handle<JSFunction>* fun,
1324 Handle<Map>* external_map) {
1325 Handle<JSObject> global = Handle<JSObject>(native_context()->global_object());
1326 Handle<JSFunction> result = InstallFunction(
1327 global, name, JS_TYPED_ARRAY_TYPE, JSTypedArray::kSize,
1328 isolate()->initial_object_prototype(), Builtins::kIllegal);
1330 Handle<Map> initial_map = isolate()->factory()->NewMap(
1331 JS_TYPED_ARRAY_TYPE,
1332 JSTypedArray::kSizeWithInternalFields,
1334 JSFunction::SetInitialMap(result, initial_map,
1335 handle(initial_map->prototype(), isolate()));
1338 ElementsKind external_kind = GetNextTransitionElementsKind(elements_kind);
1339 *external_map = Map::AsElementsKind(initial_map, external_kind);
1343 void Genesis::InitializeExperimentalGlobal() {
1344 #define FEATURE_INITIALIZE_GLOBAL(id, descr) InitializeGlobal_##id();
1346 HARMONY_INPROGRESS(FEATURE_INITIALIZE_GLOBAL)
1347 HARMONY_STAGED(FEATURE_INITIALIZE_GLOBAL)
1348 HARMONY_SHIPPING(FEATURE_INITIALIZE_GLOBAL)
1349 #undef FEATURE_INITIALIZE_GLOBAL
1353 bool Genesis::CompileBuiltin(Isolate* isolate, int index) {
1354 Vector<const char> name = Natives::GetScriptName(index);
1355 Handle<String> source_code =
1356 isolate->bootstrapper()->NativesSourceLookup(index);
1357 return CompileNative(isolate, name, source_code);
1361 bool Genesis::CompileExperimentalBuiltin(Isolate* isolate, int index) {
1362 Vector<const char> name = ExperimentalNatives::GetScriptName(index);
1363 Factory* factory = isolate->factory();
1364 Handle<String> source_code;
1365 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
1366 isolate, source_code,
1367 factory->NewStringFromAscii(ExperimentalNatives::GetScriptSource(index)),
1369 return CompileNative(isolate, name, source_code);
1373 bool Genesis::CompileNative(Isolate* isolate,
1374 Vector<const char> name,
1375 Handle<String> source) {
1376 HandleScope scope(isolate);
1377 SuppressDebug compiling_natives(isolate->debug());
1378 // During genesis, the boilerplate for stack overflow won't work until the
1379 // environment has been at least partially initialized. Add a stack check
1380 // before entering JS code to catch overflow early.
1381 StackLimitCheck check(isolate);
1382 if (check.HasOverflowed()) return false;
1384 bool result = CompileScriptCached(isolate,
1389 Handle<Context>(isolate->context()),
1391 DCHECK(isolate->has_pending_exception() != result);
1392 if (!result) isolate->clear_pending_exception();
1397 bool Genesis::CompileScriptCached(Isolate* isolate,
1398 Vector<const char> name,
1399 Handle<String> source,
1400 SourceCodeCache* cache,
1401 v8::Extension* extension,
1402 Handle<Context> top_context,
1403 bool use_runtime_context) {
1404 Factory* factory = isolate->factory();
1405 HandleScope scope(isolate);
1406 Handle<SharedFunctionInfo> function_info;
1408 // If we can't find the function in the cache, we compile a new
1409 // function and insert it into the cache.
1410 if (cache == NULL || !cache->Lookup(name, &function_info)) {
1411 DCHECK(source->IsOneByteRepresentation());
1412 Handle<String> script_name =
1413 factory->NewStringFromUtf8(name).ToHandleChecked();
1414 function_info = Compiler::CompileScript(
1415 source, script_name, 0, 0, false, false, top_context, extension, NULL,
1416 ScriptCompiler::kNoCompileOptions,
1417 use_runtime_context ? NATIVES_CODE : NOT_NATIVES_CODE, false);
1418 if (function_info.is_null()) return false;
1419 if (cache != NULL) cache->Add(name, function_info);
1422 // Set up the function context. Conceptually, we should clone the
1423 // function before overwriting the context but since we're in a
1424 // single-threaded environment it is not strictly necessary.
1425 DCHECK(top_context->IsNativeContext());
1426 Handle<Context> context =
1427 Handle<Context>(use_runtime_context
1428 ? Handle<Context>(top_context->runtime_context())
1430 Handle<JSFunction> fun =
1431 factory->NewFunctionFromSharedFunctionInfo(function_info, context);
1433 // Call function using either the runtime object or the global
1434 // object as the receiver. Provide no parameters.
1435 Handle<Object> receiver =
1436 Handle<Object>(use_runtime_context
1437 ? top_context->builtins()
1438 : top_context->global_object(),
1440 return !Execution::Call(
1441 isolate, fun, receiver, 0, NULL).is_null();
1445 static Handle<JSObject> ResolveBuiltinIdHolder(Handle<Context> native_context,
1446 const char* holder_expr) {
1447 Isolate* isolate = native_context->GetIsolate();
1448 Factory* factory = isolate->factory();
1449 Handle<GlobalObject> global(native_context->global_object());
1450 const char* period_pos = strchr(holder_expr, '.');
1451 if (period_pos == NULL) {
1452 return Handle<JSObject>::cast(
1453 Object::GetPropertyOrElement(
1454 global, factory->InternalizeUtf8String(holder_expr))
1455 .ToHandleChecked());
1457 const char* inner = period_pos + 1;
1458 DCHECK(!strchr(inner, '.'));
1459 Vector<const char> property(holder_expr,
1460 static_cast<int>(period_pos - holder_expr));
1461 Handle<String> property_string = factory->InternalizeUtf8String(property);
1462 DCHECK(!property_string.is_null());
1463 Handle<JSObject> object = Handle<JSObject>::cast(
1464 Object::GetProperty(global, property_string).ToHandleChecked());
1465 if (strcmp("prototype", inner) == 0) {
1466 Handle<JSFunction> function = Handle<JSFunction>::cast(object);
1467 return Handle<JSObject>(JSObject::cast(function->prototype()));
1469 Handle<String> inner_string = factory->InternalizeUtf8String(inner);
1470 DCHECK(!inner_string.is_null());
1471 Handle<Object> value =
1472 Object::GetProperty(object, inner_string).ToHandleChecked();
1473 return Handle<JSObject>::cast(value);
1477 #define INSTALL_NATIVE(Type, name, var) \
1478 Handle<String> var##_name = \
1479 factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR(name)); \
1480 Handle<Object> var##_native = \
1481 Object::GetProperty(handle(native_context()->builtins()), var##_name) \
1482 .ToHandleChecked(); \
1483 native_context()->set_##var(Type::cast(*var##_native));
1486 void Genesis::InstallNativeFunctions() {
1487 HandleScope scope(isolate());
1488 INSTALL_NATIVE(JSFunction, "CreateDate", create_date_fun);
1490 INSTALL_NATIVE(JSFunction, "ToNumber", to_number_fun);
1491 INSTALL_NATIVE(JSFunction, "ToString", to_string_fun);
1492 INSTALL_NATIVE(JSFunction, "ToDetailString", to_detail_string_fun);
1493 INSTALL_NATIVE(JSFunction, "ToObject", to_object_fun);
1494 INSTALL_NATIVE(JSFunction, "ToInteger", to_integer_fun);
1495 INSTALL_NATIVE(JSFunction, "ToUint32", to_uint32_fun);
1496 INSTALL_NATIVE(JSFunction, "ToInt32", to_int32_fun);
1497 INSTALL_NATIVE(JSFunction, "ToLength", to_length_fun);
1499 INSTALL_NATIVE(JSFunction, "GlobalEval", global_eval_fun);
1500 INSTALL_NATIVE(JSFunction, "GetStackTraceLine", get_stack_trace_line_fun);
1501 INSTALL_NATIVE(JSFunction, "ToCompletePropertyDescriptor",
1502 to_complete_property_descriptor);
1504 INSTALL_NATIVE(JSFunction, "IsPromise", is_promise);
1505 INSTALL_NATIVE(JSFunction, "PromiseCreate", promise_create);
1506 INSTALL_NATIVE(JSFunction, "PromiseResolve", promise_resolve);
1507 INSTALL_NATIVE(JSFunction, "PromiseReject", promise_reject);
1508 INSTALL_NATIVE(JSFunction, "PromiseChain", promise_chain);
1509 INSTALL_NATIVE(JSFunction, "PromiseCatch", promise_catch);
1510 INSTALL_NATIVE(JSFunction, "PromiseThen", promise_then);
1512 INSTALL_NATIVE(JSFunction, "NotifyChange", observers_notify_change);
1513 INSTALL_NATIVE(JSFunction, "EnqueueSpliceRecord", observers_enqueue_splice);
1514 INSTALL_NATIVE(JSFunction, "BeginPerformSplice",
1515 observers_begin_perform_splice);
1516 INSTALL_NATIVE(JSFunction, "EndPerformSplice",
1517 observers_end_perform_splice);
1518 INSTALL_NATIVE(JSFunction, "NativeObjectObserve",
1519 native_object_observe);
1520 INSTALL_NATIVE(JSFunction, "NativeObjectGetNotifier",
1521 native_object_get_notifier);
1522 INSTALL_NATIVE(JSFunction, "NativeObjectNotifierPerformChange",
1523 native_object_notifier_perform_change);
1524 INSTALL_NATIVE(JSFunction, "ArrayValues", array_values_iterator);
1528 void Genesis::InstallExperimentalNativeFunctions() {
1529 if (FLAG_harmony_proxies) {
1530 INSTALL_NATIVE(JSFunction, "DerivedHasTrap", derived_has_trap);
1531 INSTALL_NATIVE(JSFunction, "DerivedGetTrap", derived_get_trap);
1532 INSTALL_NATIVE(JSFunction, "DerivedSetTrap", derived_set_trap);
1533 INSTALL_NATIVE(JSFunction, "ProxyEnumerate", proxy_enumerate);
1536 #define INSTALL_NATIVE_FUNCTIONS_FOR(id, descr) InstallNativeFunctions_##id();
1537 HARMONY_INPROGRESS(INSTALL_NATIVE_FUNCTIONS_FOR)
1538 HARMONY_STAGED(INSTALL_NATIVE_FUNCTIONS_FOR)
1539 HARMONY_SHIPPING(INSTALL_NATIVE_FUNCTIONS_FOR)
1540 #undef INSTALL_NATIVE_FUNCTIONS_FOR
1544 template <typename Data>
1545 Data* SetBuiltinTypedArray(Isolate* isolate, Handle<JSBuiltinsObject> builtins,
1546 ExternalArrayType type, Data* data,
1547 size_t num_elements, const char* name) {
1548 size_t byte_length = num_elements * sizeof(*data);
1549 Handle<JSArrayBuffer> buffer = isolate->factory()->NewJSArrayBuffer();
1550 bool should_be_freed = false;
1552 data = reinterpret_cast<Data*>(malloc(byte_length));
1553 should_be_freed = true;
1555 Runtime::SetupArrayBuffer(isolate, buffer, true, data, byte_length);
1556 buffer->set_should_be_freed(should_be_freed);
1558 Handle<JSTypedArray> typed_array =
1559 isolate->factory()->NewJSTypedArray(type, buffer, 0, num_elements);
1560 Handle<String> name_string = isolate->factory()->InternalizeUtf8String(name);
1561 // Reset property cell type before (re)initializing.
1562 JSBuiltinsObject::InvalidatePropertyCell(builtins, name_string);
1563 JSObject::SetOwnPropertyIgnoreAttributes(builtins, name_string, typed_array,
1564 DONT_DELETE).Assert();
1569 void Genesis::InitializeBuiltinTypedArrays() {
1570 Handle<JSBuiltinsObject> builtins(native_context()->builtins());
1571 { // Initially seed the per-context random number generator using the
1572 // per-isolate random number generator.
1573 const size_t num_elements = 2;
1574 const size_t num_bytes = num_elements * sizeof(uint32_t);
1575 uint32_t* state = SetBuiltinTypedArray<uint32_t>(isolate(), builtins,
1576 kExternalUint32Array, NULL,
1577 num_elements, "rngstate");
1579 isolate()->random_number_generator()->NextBytes(state, num_bytes);
1580 } while (state[0] == 0 || state[1] == 0);
1583 { // Initialize trigonometric lookup tables and constants.
1584 const size_t num_elements = arraysize(fdlibm::MathConstants::constants);
1585 double* data = const_cast<double*>(fdlibm::MathConstants::constants);
1586 SetBuiltinTypedArray<double>(isolate(), builtins, kExternalFloat64Array,
1587 data, num_elements, "kMath");
1590 { // Initialize a result array for rempio2 calculation
1591 const size_t num_elements = 2;
1592 SetBuiltinTypedArray<double>(isolate(), builtins, kExternalFloat64Array,
1593 NULL, num_elements, "rempio2result");
1598 #define EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(id) \
1599 void Genesis::InstallNativeFunctions_##id() {}
1601 EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_scoping)
1602 EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_modules)
1603 EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_strings)
1604 EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_arrays)
1605 EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_array_includes)
1606 EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_classes)
1607 EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_object_literals)
1608 EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_regexps)
1609 EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_arrow_functions)
1610 EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_numeric_literals)
1611 EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_tostring)
1612 EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_templates)
1613 EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_sloppy)
1614 EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_unicode)
1615 EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_unicode_regexps)
1616 EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_computed_property_names)
1617 EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_rest_parameters)
1620 void Genesis::InstallNativeFunctions_harmony_proxies() {
1621 if (FLAG_harmony_proxies) {
1622 INSTALL_NATIVE(JSFunction, "DerivedHasTrap", derived_has_trap);
1623 INSTALL_NATIVE(JSFunction, "DerivedGetTrap", derived_get_trap);
1624 INSTALL_NATIVE(JSFunction, "DerivedSetTrap", derived_set_trap);
1625 INSTALL_NATIVE(JSFunction, "ProxyEnumerate", proxy_enumerate);
1629 #undef INSTALL_NATIVE
1631 #define EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(id) \
1632 void Genesis::InitializeGlobal_##id() {}
1634 EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_scoping)
1635 EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_modules)
1636 EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_strings)
1637 EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_arrays)
1638 EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_array_includes)
1639 EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_classes)
1640 EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_object_literals)
1641 EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_arrow_functions)
1642 EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_numeric_literals)
1643 EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_tostring)
1644 EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_proxies)
1645 EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_templates)
1646 EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_sloppy)
1647 EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_unicode)
1648 EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_computed_property_names)
1649 EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_rest_parameters)
1651 void Genesis::InitializeGlobal_harmony_regexps() {
1652 Handle<JSObject> builtins(native_context()->builtins());
1654 Handle<HeapObject> flag(FLAG_harmony_regexps ? heap()->true_value()
1655 : heap()->false_value());
1656 PropertyAttributes attributes =
1657 static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY);
1658 Runtime::DefineObjectProperty(builtins, factory()->harmony_regexps_string(),
1659 flag, attributes).Assert();
1663 void Genesis::InitializeGlobal_harmony_unicode_regexps() {
1664 Handle<JSObject> builtins(native_context()->builtins());
1666 Handle<HeapObject> flag(FLAG_harmony_unicode_regexps ? heap()->true_value()
1667 : heap()->false_value());
1668 PropertyAttributes attributes =
1669 static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY);
1670 Runtime::DefineObjectProperty(builtins,
1671 factory()->harmony_unicode_regexps_string(),
1672 flag, attributes).Assert();
1676 Handle<JSFunction> Genesis::InstallInternalArray(
1677 Handle<JSBuiltinsObject> builtins,
1679 ElementsKind elements_kind) {
1680 // --- I n t e r n a l A r r a y ---
1681 // An array constructor on the builtins object that works like
1682 // the public Array constructor, except that its prototype
1683 // doesn't inherit from Object.prototype.
1684 // To be used only for internal work by builtins. Instances
1685 // must not be leaked to user code.
1686 Handle<JSObject> prototype =
1687 factory()->NewJSObject(isolate()->object_function(), TENURED);
1688 Handle<JSFunction> array_function = InstallFunction(
1689 builtins, name, JS_ARRAY_TYPE, JSArray::kSize,
1690 prototype, Builtins::kInternalArrayCode);
1692 InternalArrayConstructorStub internal_array_constructor_stub(isolate());
1693 Handle<Code> code = internal_array_constructor_stub.GetCode();
1694 array_function->shared()->set_construct_stub(*code);
1695 array_function->shared()->DontAdaptArguments();
1697 Handle<Map> original_map(array_function->initial_map());
1698 Handle<Map> initial_map = Map::Copy(original_map, "InternalArray");
1699 initial_map->set_elements_kind(elements_kind);
1700 JSFunction::SetInitialMap(array_function, initial_map, prototype);
1702 // Make "length" magic on instances.
1703 Map::EnsureDescriptorSlack(initial_map, 1);
1705 PropertyAttributes attribs = static_cast<PropertyAttributes>(
1706 DONT_ENUM | DONT_DELETE);
1708 Handle<AccessorInfo> array_length =
1709 Accessors::ArrayLengthInfo(isolate(), attribs);
1711 AccessorConstantDescriptor d(Handle<Name>(Name::cast(array_length->name())),
1712 array_length, attribs);
1713 initial_map->AppendDescriptor(&d);
1716 return array_function;
1720 bool Genesis::InstallNatives() {
1721 HandleScope scope(isolate());
1723 // Create a function for the builtins object. Allocate space for the
1724 // JavaScript builtins, a reference to the builtins object
1725 // (itself) and a reference to the native_context directly in the object.
1726 Handle<Code> code = Handle<Code>(
1727 isolate()->builtins()->builtin(Builtins::kIllegal));
1728 Handle<JSFunction> builtins_fun = factory()->NewFunction(
1729 factory()->empty_string(), code, JS_BUILTINS_OBJECT_TYPE,
1730 JSBuiltinsObject::kSize);
1732 Handle<String> name =
1733 factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("builtins"));
1734 builtins_fun->shared()->set_instance_class_name(*name);
1735 builtins_fun->initial_map()->set_dictionary_map(true);
1736 builtins_fun->initial_map()->set_prototype(heap()->null_value());
1738 // Allocate the builtins object.
1739 Handle<JSBuiltinsObject> builtins =
1740 Handle<JSBuiltinsObject>::cast(factory()->NewGlobalObject(builtins_fun));
1741 builtins->set_builtins(*builtins);
1742 builtins->set_native_context(*native_context());
1743 builtins->set_global_proxy(native_context()->global_proxy());
1746 // Set up the 'global' properties of the builtins object. The
1747 // 'global' property that refers to the global object is the only
1748 // way to get from code running in the builtins context to the
1750 static const PropertyAttributes attributes =
1751 static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE);
1752 Handle<String> global_string =
1753 factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("global"));
1754 Handle<Object> global_obj(native_context()->global_object(), isolate());
1755 JSObject::AddProperty(builtins, global_string, global_obj, attributes);
1756 Handle<String> builtins_string =
1757 factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("builtins"));
1758 JSObject::AddProperty(builtins, builtins_string, builtins, attributes);
1760 // Set up the reference from the global object to the builtins object.
1761 JSGlobalObject::cast(native_context()->global_object())->
1762 set_builtins(*builtins);
1764 // Create a bridge function that has context in the native context.
1765 Handle<JSFunction> bridge = factory()->NewFunction(factory()->empty_string());
1766 DCHECK(bridge->context() == *isolate()->native_context());
1768 // Allocate the builtins context.
1769 Handle<Context> context =
1770 factory()->NewFunctionContext(Context::MIN_CONTEXT_SLOTS, bridge);
1771 context->set_global_object(*builtins); // override builtins global object
1773 native_context()->set_runtime_context(*context);
1776 // Builtin functions for Script.
1777 Handle<JSFunction> script_fun = InstallFunction(
1778 builtins, "Script", JS_VALUE_TYPE, JSValue::kSize,
1779 isolate()->initial_object_prototype(), Builtins::kIllegal);
1780 Handle<JSObject> prototype =
1781 factory()->NewJSObject(isolate()->object_function(), TENURED);
1782 Accessors::FunctionSetPrototype(script_fun, prototype).Assert();
1783 native_context()->set_script_function(*script_fun);
1785 Handle<Map> script_map = Handle<Map>(script_fun->initial_map());
1786 Map::EnsureDescriptorSlack(script_map, 15);
1788 PropertyAttributes attribs =
1789 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
1791 Handle<AccessorInfo> script_column =
1792 Accessors::ScriptColumnOffsetInfo(isolate(), attribs);
1794 AccessorConstantDescriptor d(
1795 Handle<Name>(Name::cast(script_column->name())), script_column,
1797 script_map->AppendDescriptor(&d);
1800 Handle<AccessorInfo> script_id =
1801 Accessors::ScriptIdInfo(isolate(), attribs);
1803 AccessorConstantDescriptor d(Handle<Name>(Name::cast(script_id->name())),
1804 script_id, attribs);
1805 script_map->AppendDescriptor(&d);
1809 Handle<AccessorInfo> script_name =
1810 Accessors::ScriptNameInfo(isolate(), attribs);
1812 AccessorConstantDescriptor d(
1813 Handle<Name>(Name::cast(script_name->name())), script_name, attribs);
1814 script_map->AppendDescriptor(&d);
1817 Handle<AccessorInfo> script_line =
1818 Accessors::ScriptLineOffsetInfo(isolate(), attribs);
1820 AccessorConstantDescriptor d(
1821 Handle<Name>(Name::cast(script_line->name())), script_line, attribs);
1822 script_map->AppendDescriptor(&d);
1825 Handle<AccessorInfo> script_source =
1826 Accessors::ScriptSourceInfo(isolate(), attribs);
1828 AccessorConstantDescriptor d(
1829 Handle<Name>(Name::cast(script_source->name())), script_source,
1831 script_map->AppendDescriptor(&d);
1834 Handle<AccessorInfo> script_type =
1835 Accessors::ScriptTypeInfo(isolate(), attribs);
1837 AccessorConstantDescriptor d(
1838 Handle<Name>(Name::cast(script_type->name())), script_type, attribs);
1839 script_map->AppendDescriptor(&d);
1842 Handle<AccessorInfo> script_compilation_type =
1843 Accessors::ScriptCompilationTypeInfo(isolate(), attribs);
1845 AccessorConstantDescriptor d(
1846 Handle<Name>(Name::cast(script_compilation_type->name())),
1847 script_compilation_type, attribs);
1848 script_map->AppendDescriptor(&d);
1851 Handle<AccessorInfo> script_line_ends =
1852 Accessors::ScriptLineEndsInfo(isolate(), attribs);
1854 AccessorConstantDescriptor d(
1855 Handle<Name>(Name::cast(script_line_ends->name())), script_line_ends,
1857 script_map->AppendDescriptor(&d);
1860 Handle<AccessorInfo> script_context_data =
1861 Accessors::ScriptContextDataInfo(isolate(), attribs);
1863 AccessorConstantDescriptor d(
1864 Handle<Name>(Name::cast(script_context_data->name())),
1865 script_context_data, attribs);
1866 script_map->AppendDescriptor(&d);
1869 Handle<AccessorInfo> script_eval_from_script =
1870 Accessors::ScriptEvalFromScriptInfo(isolate(), attribs);
1872 AccessorConstantDescriptor d(
1873 Handle<Name>(Name::cast(script_eval_from_script->name())),
1874 script_eval_from_script, attribs);
1875 script_map->AppendDescriptor(&d);
1878 Handle<AccessorInfo> script_eval_from_script_position =
1879 Accessors::ScriptEvalFromScriptPositionInfo(isolate(), attribs);
1881 AccessorConstantDescriptor d(
1882 Handle<Name>(Name::cast(script_eval_from_script_position->name())),
1883 script_eval_from_script_position, attribs);
1884 script_map->AppendDescriptor(&d);
1887 Handle<AccessorInfo> script_eval_from_function_name =
1888 Accessors::ScriptEvalFromFunctionNameInfo(isolate(), attribs);
1890 AccessorConstantDescriptor d(
1891 Handle<Name>(Name::cast(script_eval_from_function_name->name())),
1892 script_eval_from_function_name, attribs);
1893 script_map->AppendDescriptor(&d);
1896 Handle<AccessorInfo> script_source_url =
1897 Accessors::ScriptSourceUrlInfo(isolate(), attribs);
1899 AccessorConstantDescriptor d(
1900 Handle<Name>(Name::cast(script_source_url->name())),
1901 script_source_url, attribs);
1902 script_map->AppendDescriptor(&d);
1905 Handle<AccessorInfo> script_source_mapping_url =
1906 Accessors::ScriptSourceMappingUrlInfo(isolate(), attribs);
1908 AccessorConstantDescriptor d(
1909 Handle<Name>(Name::cast(script_source_mapping_url->name())),
1910 script_source_mapping_url, attribs);
1911 script_map->AppendDescriptor(&d);
1914 Handle<AccessorInfo> script_is_embedder_debug_script =
1915 Accessors::ScriptIsEmbedderDebugScriptInfo(isolate(), attribs);
1917 AccessorConstantDescriptor d(
1918 Handle<Name>(Name::cast(script_is_embedder_debug_script->name())),
1919 script_is_embedder_debug_script, attribs);
1920 script_map->AppendDescriptor(&d);
1923 // Allocate the empty script.
1924 Handle<Script> script = factory()->NewScript(factory()->empty_string());
1925 script->set_type(Smi::FromInt(Script::TYPE_NATIVE));
1926 heap()->public_set_empty_script(*script);
1929 // Builtin function for OpaqueReference -- a JSValue-based object,
1930 // that keeps its field isolated from JavaScript code. It may store
1931 // objects, that JavaScript code may not access.
1932 Handle<JSFunction> opaque_reference_fun = InstallFunction(
1933 builtins, "OpaqueReference", JS_VALUE_TYPE, JSValue::kSize,
1934 isolate()->initial_object_prototype(), Builtins::kIllegal);
1935 Handle<JSObject> prototype =
1936 factory()->NewJSObject(isolate()->object_function(), TENURED);
1937 Accessors::FunctionSetPrototype(opaque_reference_fun, prototype).Assert();
1938 native_context()->set_opaque_reference_function(*opaque_reference_fun);
1941 // InternalArrays should not use Smi-Only array optimizations. There are too
1942 // many places in the C++ runtime code (e.g. RegEx) that assume that
1943 // elements in InternalArrays can be set to non-Smi values without going
1944 // through a common bottleneck that would make the SMI_ONLY -> FAST_ELEMENT
1945 // transition easy to trap. Moreover, they rarely are smi-only.
1947 Handle<JSFunction> array_function =
1948 InstallInternalArray(builtins, "InternalArray", FAST_HOLEY_ELEMENTS);
1949 native_context()->set_internal_array_function(*array_function);
1953 InstallInternalArray(builtins, "InternalPackedArray", FAST_ELEMENTS);
1956 { // -- S e t I t e r a t o r
1957 Handle<JSFunction> set_iterator_function = InstallFunction(
1958 builtins, "SetIterator", JS_SET_ITERATOR_TYPE, JSSetIterator::kSize,
1959 isolate()->initial_object_prototype(), Builtins::kIllegal);
1960 native_context()->set_set_iterator_map(
1961 set_iterator_function->initial_map());
1964 { // -- M a p I t e r a t o r
1965 Handle<JSFunction> map_iterator_function = InstallFunction(
1966 builtins, "MapIterator", JS_MAP_ITERATOR_TYPE, JSMapIterator::kSize,
1967 isolate()->initial_object_prototype(), Builtins::kIllegal);
1968 native_context()->set_map_iterator_map(
1969 map_iterator_function->initial_map());
1973 // Create generator meta-objects and install them on the builtins object.
1974 Handle<JSObject> builtins(native_context()->builtins());
1975 Handle<JSObject> generator_object_prototype =
1976 factory()->NewJSObject(isolate()->object_function(), TENURED);
1977 Handle<JSFunction> generator_function_prototype =
1978 InstallFunction(builtins, "GeneratorFunctionPrototype",
1979 JS_FUNCTION_TYPE, JSFunction::kHeaderSize,
1980 generator_object_prototype, Builtins::kIllegal);
1981 InstallFunction(builtins, "GeneratorFunction", JS_FUNCTION_TYPE,
1982 JSFunction::kSize, generator_function_prototype,
1983 Builtins::kIllegal);
1985 // Create maps for generator functions and their prototypes. Store those
1986 // maps in the native context.
1987 Handle<Map> generator_function_map =
1988 Map::Copy(sloppy_function_map_writable_prototype_, "GeneratorFunction");
1989 generator_function_map->SetPrototype(generator_function_prototype);
1990 native_context()->set_sloppy_generator_function_map(
1991 *generator_function_map);
1993 // The "arguments" and "caller" instance properties aren't specified, so
1994 // technically we could leave them out. They make even less sense for
1995 // generators than for functions. Still, the same argument that it makes
1996 // sense to keep them around but poisoned in strict mode applies to
1997 // generators as well. With poisoned accessors, naive callers can still
1998 // iterate over the properties without accessing them.
2000 // We can't use PoisonArgumentsAndCaller because that mutates accessor pairs
2001 // in place, and the initial state of the generator function map shares the
2002 // accessor pair with sloppy functions. Also the error message should be
2003 // different. Also unhappily, we can't use the API accessors to implement
2004 // poisoning, because API accessors present themselves as data properties,
2005 // not accessor properties, and so getOwnPropertyDescriptor raises an
2006 // exception as it tries to get the values. Sadness.
2007 Handle<AccessorPair> poison_pair(factory()->NewAccessorPair());
2008 PropertyAttributes rw_attribs =
2009 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
2010 Handle<JSFunction> poison_function = GetGeneratorPoisonFunction();
2011 poison_pair->set_getter(*poison_function);
2012 poison_pair->set_setter(*poison_function);
2013 ReplaceAccessors(generator_function_map, factory()->arguments_string(),
2014 rw_attribs, poison_pair);
2015 ReplaceAccessors(generator_function_map, factory()->caller_string(),
2016 rw_attribs, poison_pair);
2018 Handle<Map> strict_function_map(native_context()->strict_function_map());
2019 Handle<Map> strict_generator_function_map =
2020 Map::Copy(strict_function_map, "StrictGeneratorFunction");
2021 // "arguments" and "caller" already poisoned.
2022 strict_generator_function_map->SetPrototype(generator_function_prototype);
2023 native_context()->set_strict_generator_function_map(
2024 *strict_generator_function_map);
2026 Handle<JSFunction> object_function(native_context()->object_function());
2027 Handle<Map> generator_object_prototype_map = Map::Create(isolate(), 0);
2028 generator_object_prototype_map->SetPrototype(generator_object_prototype);
2029 native_context()->set_generator_object_prototype_map(
2030 *generator_object_prototype_map);
2033 if (FLAG_disable_native_files) {
2034 PrintF("Warning: Running without installed natives!\n");
2038 // Install public symbols.
2040 static const PropertyAttributes attributes =
2041 static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE);
2042 #define INSTALL_PUBLIC_SYMBOL(name, varname, description) \
2043 Handle<String> varname = factory()->NewStringFromStaticChars(#varname); \
2044 JSObject::AddProperty(builtins, varname, factory()->name(), attributes);
2045 PUBLIC_SYMBOL_LIST(INSTALL_PUBLIC_SYMBOL)
2046 #undef INSTALL_PUBLIC_SYMBOL
2050 for (int i = Natives::GetDebuggerCount();
2051 i < Natives::GetBuiltinsCount();
2053 if (!CompileBuiltin(isolate(), i)) return false;
2054 // TODO(ager): We really only need to install the JS builtin
2055 // functions on the builtins object after compiling and running
2057 if (!InstallJSBuiltins(builtins)) return false;
2060 InstallNativeFunctions();
2062 auto function_cache =
2063 ObjectHashTable::New(isolate(), ApiNatives::kInitialFunctionCacheSize);
2064 native_context()->set_function_cache(*function_cache);
2066 // Store the map for the string prototype after the natives has been compiled
2067 // and the String function has been set up.
2068 Handle<JSFunction> string_function(native_context()->string_function());
2069 DCHECK(JSObject::cast(
2070 string_function->initial_map()->prototype())->HasFastProperties());
2071 native_context()->set_string_function_prototype_map(
2072 HeapObject::cast(string_function->initial_map()->prototype())->map());
2074 // Install Function.prototype.call and apply.
2076 Handle<String> key = factory()->Function_string();
2077 Handle<JSFunction> function =
2078 Handle<JSFunction>::cast(Object::GetProperty(
2079 handle(native_context()->global_object()), key).ToHandleChecked());
2080 Handle<JSObject> proto =
2081 Handle<JSObject>(JSObject::cast(function->instance_prototype()));
2083 // Install the call and the apply functions.
2084 Handle<JSFunction> call =
2085 InstallFunction(proto, "call", JS_OBJECT_TYPE, JSObject::kHeaderSize,
2086 MaybeHandle<JSObject>(), Builtins::kFunctionCall);
2087 Handle<JSFunction> apply =
2088 InstallFunction(proto, "apply", JS_OBJECT_TYPE, JSObject::kHeaderSize,
2089 MaybeHandle<JSObject>(), Builtins::kFunctionApply);
2090 if (FLAG_vector_ics) {
2091 // Apply embeds an IC, so we need a type vector of size 1 in the shared
2093 FeedbackVectorSpec spec(0, 1);
2094 spec.SetKind(0, Code::CALL_IC);
2095 Handle<TypeFeedbackVector> feedback_vector =
2096 factory()->NewTypeFeedbackVector(spec);
2097 apply->shared()->set_feedback_vector(*feedback_vector);
2100 // Make sure that Function.prototype.call appears to be compiled.
2101 // The code will never be called, but inline caching for call will
2102 // only work if it appears to be compiled.
2103 call->shared()->DontAdaptArguments();
2104 DCHECK(call->is_compiled());
2106 // Set the expected parameters for apply to 2; required by builtin.
2107 apply->shared()->set_internal_formal_parameter_count(2);
2109 // Set the lengths for the functions to satisfy ECMA-262.
2110 call->shared()->set_length(1);
2111 apply->shared()->set_length(2);
2114 InstallBuiltinFunctionIds();
2116 // Create a constructor for RegExp results (a variant of Array that
2117 // predefines the two properties index and match).
2119 // RegExpResult initial map.
2121 // Find global.Array.prototype to inherit from.
2122 Handle<JSFunction> array_constructor(native_context()->array_function());
2123 Handle<JSObject> array_prototype(
2124 JSObject::cast(array_constructor->instance_prototype()));
2127 Handle<Map> initial_map =
2128 factory()->NewMap(JS_ARRAY_TYPE, JSRegExpResult::kSize);
2129 initial_map->set_constructor(*array_constructor);
2131 // Set prototype on map.
2132 initial_map->set_non_instance_prototype(false);
2133 initial_map->SetPrototype(array_prototype);
2135 // Update map with length accessor from Array and add "index" and "input".
2136 Map::EnsureDescriptorSlack(initial_map, 3);
2139 JSFunction* array_function = native_context()->array_function();
2140 Handle<DescriptorArray> array_descriptors(
2141 array_function->initial_map()->instance_descriptors());
2142 Handle<String> length = factory()->length_string();
2143 int old = array_descriptors->SearchWithCache(
2144 *length, array_function->initial_map());
2145 DCHECK(old != DescriptorArray::kNotFound);
2146 AccessorConstantDescriptor desc(
2147 length, handle(array_descriptors->GetValue(old), isolate()),
2148 array_descriptors->GetDetails(old).attributes());
2149 initial_map->AppendDescriptor(&desc);
2152 DataDescriptor index_field(factory()->index_string(),
2153 JSRegExpResult::kIndexIndex, NONE,
2154 Representation::Tagged());
2155 initial_map->AppendDescriptor(&index_field);
2159 DataDescriptor input_field(factory()->input_string(),
2160 JSRegExpResult::kInputIndex, NONE,
2161 Representation::Tagged());
2162 initial_map->AppendDescriptor(&input_field);
2165 initial_map->set_inobject_properties(2);
2166 initial_map->set_pre_allocated_property_fields(2);
2167 initial_map->set_unused_property_fields(0);
2169 native_context()->set_regexp_result_map(*initial_map);
2172 // Add @@iterator method to the arguments object maps.
2174 PropertyAttributes attribs = DONT_ENUM;
2175 Handle<AccessorInfo> arguments_iterator =
2176 Accessors::ArgumentsIteratorInfo(isolate(), attribs);
2178 AccessorConstantDescriptor d(factory()->iterator_symbol(),
2179 arguments_iterator, attribs);
2180 Handle<Map> map(native_context()->sloppy_arguments_map());
2181 Map::EnsureDescriptorSlack(map, 1);
2182 map->AppendDescriptor(&d);
2185 AccessorConstantDescriptor d(factory()->iterator_symbol(),
2186 arguments_iterator, attribs);
2187 Handle<Map> map(native_context()->aliased_arguments_map());
2188 Map::EnsureDescriptorSlack(map, 1);
2189 map->AppendDescriptor(&d);
2192 AccessorConstantDescriptor d(factory()->iterator_symbol(),
2193 arguments_iterator, attribs);
2194 Handle<Map> map(native_context()->strict_arguments_map());
2195 Map::EnsureDescriptorSlack(map, 1);
2196 map->AppendDescriptor(&d);
2201 if (FLAG_verify_heap) {
2202 builtins->ObjectVerify();
2210 bool Genesis::InstallExperimentalNatives() {
2211 static const char* harmony_arrays_natives[] = {
2212 "native harmony-array.js", "native harmony-typedarray.js", NULL};
2213 static const char* harmony_array_includes_natives[] = {
2214 "native harmony-array-includes.js", NULL};
2215 static const char* harmony_proxies_natives[] = {"native proxy.js", NULL};
2216 static const char* harmony_strings_natives[] = {"native harmony-string.js",
2218 static const char* harmony_classes_natives[] = {NULL};
2219 static const char* harmony_modules_natives[] = {NULL};
2220 static const char* harmony_scoping_natives[] = {NULL};
2221 static const char* harmony_object_literals_natives[] = {NULL};
2222 static const char* harmony_regexps_natives[] = {
2223 "native harmony-regexp.js", NULL};
2224 static const char* harmony_arrow_functions_natives[] = {NULL};
2225 static const char* harmony_numeric_literals_natives[] = {NULL};
2226 static const char* harmony_tostring_natives[] = {"native harmony-tostring.js",
2228 static const char* harmony_templates_natives[] = {
2229 "native harmony-templates.js", NULL};
2230 static const char* harmony_sloppy_natives[] = {NULL};
2231 static const char* harmony_unicode_natives[] = {NULL};
2232 static const char* harmony_unicode_regexps_natives[] = {NULL};
2233 static const char* harmony_computed_property_names_natives[] = {NULL};
2234 static const char* harmony_rest_parameters_natives[] = {NULL};
2236 for (int i = ExperimentalNatives::GetDebuggerCount();
2237 i < ExperimentalNatives::GetBuiltinsCount(); i++) {
2238 #define INSTALL_EXPERIMENTAL_NATIVES(id, desc) \
2240 for (size_t j = 0; id##_natives[j] != NULL; j++) { \
2241 Vector<const char> script_name = ExperimentalNatives::GetScriptName(i); \
2242 if (strncmp(script_name.start(), id##_natives[j], \
2243 script_name.length()) == 0) { \
2244 if (!CompileExperimentalBuiltin(isolate(), i)) return false; \
2248 HARMONY_INPROGRESS(INSTALL_EXPERIMENTAL_NATIVES);
2249 HARMONY_STAGED(INSTALL_EXPERIMENTAL_NATIVES);
2250 HARMONY_SHIPPING(INSTALL_EXPERIMENTAL_NATIVES);
2251 #undef INSTALL_EXPERIMENTAL_NATIVES
2254 InstallExperimentalNativeFunctions();
2259 static void InstallBuiltinFunctionId(Handle<JSObject> holder,
2260 const char* function_name,
2261 BuiltinFunctionId id) {
2262 Isolate* isolate = holder->GetIsolate();
2263 Handle<Object> function_object =
2264 Object::GetProperty(isolate, holder, function_name).ToHandleChecked();
2265 Handle<JSFunction> function = Handle<JSFunction>::cast(function_object);
2266 function->shared()->set_function_data(Smi::FromInt(id));
2270 void Genesis::InstallBuiltinFunctionIds() {
2271 HandleScope scope(isolate());
2272 #define INSTALL_BUILTIN_ID(holder_expr, fun_name, name) \
2274 Handle<JSObject> holder = ResolveBuiltinIdHolder( \
2275 native_context(), #holder_expr); \
2276 BuiltinFunctionId id = k##name; \
2277 InstallBuiltinFunctionId(holder, #fun_name, id); \
2279 FUNCTIONS_WITH_ID_LIST(INSTALL_BUILTIN_ID)
2280 #undef INSTALL_BUILTIN_ID
2284 // Do not forget to update macros.py with named constant
2286 #define JSFUNCTION_RESULT_CACHE_LIST(F) \
2287 F(16, native_context()->regexp_function())
2290 static FixedArray* CreateCache(int size, Handle<JSFunction> factory_function) {
2291 Factory* factory = factory_function->GetIsolate()->factory();
2292 // Caches are supposed to live for a long time, allocate in old space.
2293 int array_size = JSFunctionResultCache::kEntriesIndex + 2 * size;
2294 // Cannot use cast as object is not fully initialized yet.
2295 JSFunctionResultCache* cache = reinterpret_cast<JSFunctionResultCache*>(
2296 *factory->NewFixedArrayWithHoles(array_size, TENURED));
2297 cache->set(JSFunctionResultCache::kFactoryIndex, *factory_function);
2298 cache->MakeZeroSize();
2303 void Genesis::InstallJSFunctionResultCaches() {
2304 const int kNumberOfCaches = 0 +
2305 #define F(size, func) + 1
2306 JSFUNCTION_RESULT_CACHE_LIST(F)
2310 Handle<FixedArray> caches =
2311 factory()->NewFixedArray(kNumberOfCaches, TENURED);
2315 #define F(size, func) do { \
2316 FixedArray* cache = CreateCache((size), Handle<JSFunction>(func)); \
2317 caches->set(index++, cache); \
2320 JSFUNCTION_RESULT_CACHE_LIST(F);
2324 native_context()->set_jsfunction_result_caches(*caches);
2328 void Genesis::InitializeNormalizedMapCaches() {
2329 Handle<NormalizedMapCache> cache = NormalizedMapCache::New(isolate());
2330 native_context()->set_normalized_map_cache(*cache);
2334 bool Bootstrapper::InstallExtensions(Handle<Context> native_context,
2335 v8::ExtensionConfiguration* extensions) {
2336 BootstrapperActive active(this);
2337 SaveContext saved_context(isolate_);
2338 isolate_->set_context(*native_context);
2339 return Genesis::InstallExtensions(native_context, extensions) &&
2340 Genesis::InstallSpecialObjects(native_context);
2344 bool Genesis::InstallSpecialObjects(Handle<Context> native_context) {
2345 Isolate* isolate = native_context->GetIsolate();
2346 // Don't install extensions into the snapshot.
2347 if (isolate->serializer_enabled()) return true;
2349 Factory* factory = isolate->factory();
2350 HandleScope scope(isolate);
2351 Handle<JSGlobalObject> global(JSGlobalObject::cast(
2352 native_context->global_object()));
2354 Handle<JSObject> Error = Handle<JSObject>::cast(
2355 Object::GetProperty(isolate, global, "Error").ToHandleChecked());
2356 Handle<String> name =
2357 factory->InternalizeOneByteString(STATIC_CHAR_VECTOR("stackTraceLimit"));
2358 Handle<Smi> stack_trace_limit(Smi::FromInt(FLAG_stack_trace_limit), isolate);
2359 JSObject::AddProperty(Error, name, stack_trace_limit, NONE);
2361 // Expose the natives in global if a name for it is specified.
2362 if (FLAG_expose_natives_as != NULL && strlen(FLAG_expose_natives_as) != 0) {
2363 Handle<String> natives =
2364 factory->InternalizeUtf8String(FLAG_expose_natives_as);
2365 uint32_t dummy_index;
2366 if (natives->AsArrayIndex(&dummy_index)) return true;
2367 JSObject::AddProperty(global, natives, handle(global->builtins()),
2371 // Expose the stack trace symbol to native JS.
2372 RETURN_ON_EXCEPTION_VALUE(isolate,
2373 JSObject::SetOwnPropertyIgnoreAttributes(
2374 handle(native_context->builtins(), isolate),
2375 factory->InternalizeOneByteString(
2376 STATIC_CHAR_VECTOR("stack_trace_symbol")),
2377 factory->stack_trace_symbol(), NONE),
2380 // Expose the debug global object in global if a name for it is specified.
2381 if (FLAG_expose_debug_as != NULL && strlen(FLAG_expose_debug_as) != 0) {
2382 // If loading fails we just bail out without installing the
2383 // debugger but without tanking the whole context.
2384 Debug* debug = isolate->debug();
2385 if (!debug->Load()) return true;
2386 Handle<Context> debug_context = debug->debug_context();
2387 // Set the security token for the debugger context to the same as
2388 // the shell native context to allow calling between these (otherwise
2389 // exposing debug global object doesn't make much sense).
2390 debug_context->set_security_token(native_context->security_token());
2391 Handle<String> debug_string =
2392 factory->InternalizeUtf8String(FLAG_expose_debug_as);
2394 if (debug_string->AsArrayIndex(&index)) return true;
2395 Handle<Object> global_proxy(debug_context->global_proxy(), isolate);
2396 JSObject::AddProperty(global, debug_string, global_proxy, DONT_ENUM);
2402 static uint32_t Hash(RegisteredExtension* extension) {
2403 return v8::internal::ComputePointerHash(extension);
2407 Genesis::ExtensionStates::ExtensionStates() : map_(HashMap::PointersMatch, 8) {}
2409 Genesis::ExtensionTraversalState Genesis::ExtensionStates::get_state(
2410 RegisteredExtension* extension) {
2411 i::HashMap::Entry* entry = map_.Lookup(extension, Hash(extension), false);
2412 if (entry == NULL) {
2415 return static_cast<ExtensionTraversalState>(
2416 reinterpret_cast<intptr_t>(entry->value));
2419 void Genesis::ExtensionStates::set_state(RegisteredExtension* extension,
2420 ExtensionTraversalState state) {
2421 map_.Lookup(extension, Hash(extension), true)->value =
2422 reinterpret_cast<void*>(static_cast<intptr_t>(state));
2426 bool Genesis::InstallExtensions(Handle<Context> native_context,
2427 v8::ExtensionConfiguration* extensions) {
2428 Isolate* isolate = native_context->GetIsolate();
2429 ExtensionStates extension_states; // All extensions have state UNVISITED.
2430 return InstallAutoExtensions(isolate, &extension_states) &&
2431 (!FLAG_expose_free_buffer ||
2432 InstallExtension(isolate, "v8/free-buffer", &extension_states)) &&
2434 InstallExtension(isolate, "v8/gc", &extension_states)) &&
2435 (!FLAG_expose_externalize_string ||
2436 InstallExtension(isolate, "v8/externalize", &extension_states)) &&
2437 (!FLAG_track_gc_object_stats ||
2438 InstallExtension(isolate, "v8/statistics", &extension_states)) &&
2439 (!FLAG_expose_trigger_failure ||
2440 InstallExtension(isolate, "v8/trigger-failure", &extension_states)) &&
2441 InstallRequestedExtensions(isolate, extensions, &extension_states);
2445 bool Genesis::InstallAutoExtensions(Isolate* isolate,
2446 ExtensionStates* extension_states) {
2447 for (v8::RegisteredExtension* it = v8::RegisteredExtension::first_extension();
2450 if (it->extension()->auto_enable() &&
2451 !InstallExtension(isolate, it, extension_states)) {
2459 bool Genesis::InstallRequestedExtensions(Isolate* isolate,
2460 v8::ExtensionConfiguration* extensions,
2461 ExtensionStates* extension_states) {
2462 for (const char** it = extensions->begin(); it != extensions->end(); ++it) {
2463 if (!InstallExtension(isolate, *it, extension_states)) return false;
2469 // Installs a named extension. This methods is unoptimized and does
2470 // not scale well if we want to support a large number of extensions.
2471 bool Genesis::InstallExtension(Isolate* isolate,
2473 ExtensionStates* extension_states) {
2474 for (v8::RegisteredExtension* it = v8::RegisteredExtension::first_extension();
2477 if (strcmp(name, it->extension()->name()) == 0) {
2478 return InstallExtension(isolate, it, extension_states);
2481 return Utils::ApiCheck(false,
2482 "v8::Context::New()",
2483 "Cannot find required extension");
2487 bool Genesis::InstallExtension(Isolate* isolate,
2488 v8::RegisteredExtension* current,
2489 ExtensionStates* extension_states) {
2490 HandleScope scope(isolate);
2492 if (extension_states->get_state(current) == INSTALLED) return true;
2493 // The current node has already been visited so there must be a
2494 // cycle in the dependency graph; fail.
2495 if (!Utils::ApiCheck(extension_states->get_state(current) != VISITED,
2496 "v8::Context::New()",
2497 "Circular extension dependency")) {
2500 DCHECK(extension_states->get_state(current) == UNVISITED);
2501 extension_states->set_state(current, VISITED);
2502 v8::Extension* extension = current->extension();
2503 // Install the extension's dependencies
2504 for (int i = 0; i < extension->dependency_count(); i++) {
2505 if (!InstallExtension(isolate,
2506 extension->dependencies()[i],
2507 extension_states)) {
2511 // We do not expect this to throw an exception. Change this if it does.
2512 Handle<String> source_code =
2514 ->NewExternalStringFromOneByte(extension->source())
2516 bool result = CompileScriptCached(isolate,
2517 CStrVector(extension->name()),
2519 isolate->bootstrapper()->extensions_cache(),
2521 Handle<Context>(isolate->context()),
2523 DCHECK(isolate->has_pending_exception() != result);
2525 // We print out the name of the extension that fail to install.
2526 // When an error is thrown during bootstrapping we automatically print
2527 // the line number at which this happened to the console in the isolate
2528 // error throwing functionality.
2529 base::OS::PrintError("Error installing extension '%s'.\n",
2530 current->extension()->name());
2531 isolate->clear_pending_exception();
2533 extension_states->set_state(current, INSTALLED);
2534 isolate->NotifyExtensionInstalled();
2539 bool Genesis::InstallJSBuiltins(Handle<JSBuiltinsObject> builtins) {
2540 HandleScope scope(isolate());
2541 for (int i = 0; i < Builtins::NumberOfJavaScriptBuiltins(); i++) {
2542 Builtins::JavaScript id = static_cast<Builtins::JavaScript>(i);
2543 Handle<Object> function_object = Object::GetProperty(
2544 isolate(), builtins, Builtins::GetName(id)).ToHandleChecked();
2545 Handle<JSFunction> function = Handle<JSFunction>::cast(function_object);
2546 // TODO(mstarzinger): This is just a temporary hack to make TurboFan work,
2547 // the correct solution is to restore the context register after invoking
2548 // builtins from full-codegen.
2549 function->shared()->DisableOptimization(kBuiltinFunctionCannotBeOptimized);
2550 builtins->set_javascript_builtin(id, *function);
2551 if (!Compiler::EnsureCompiled(function, CLEAR_EXCEPTION)) {
2554 builtins->set_javascript_builtin_code(id, function->shared()->code());
2560 bool Genesis::ConfigureGlobalObjects(
2561 v8::Handle<v8::ObjectTemplate> global_proxy_template) {
2562 Handle<JSObject> global_proxy(
2563 JSObject::cast(native_context()->global_proxy()));
2564 Handle<JSObject> global_object(
2565 JSObject::cast(native_context()->global_object()));
2567 if (!global_proxy_template.IsEmpty()) {
2568 // Configure the global proxy object.
2569 Handle<ObjectTemplateInfo> global_proxy_data =
2570 v8::Utils::OpenHandle(*global_proxy_template);
2571 if (!ConfigureApiObject(global_proxy, global_proxy_data)) return false;
2573 // Configure the global object.
2574 Handle<FunctionTemplateInfo> proxy_constructor(
2575 FunctionTemplateInfo::cast(global_proxy_data->constructor()));
2576 if (!proxy_constructor->prototype_template()->IsUndefined()) {
2577 Handle<ObjectTemplateInfo> global_object_data(
2578 ObjectTemplateInfo::cast(proxy_constructor->prototype_template()));
2579 if (!ConfigureApiObject(global_object, global_object_data)) return false;
2583 SetObjectPrototype(global_proxy, global_object);
2585 native_context()->set_initial_array_prototype(
2586 JSArray::cast(native_context()->array_function()->prototype()));
2592 bool Genesis::ConfigureApiObject(Handle<JSObject> object,
2593 Handle<ObjectTemplateInfo> object_template) {
2594 DCHECK(!object_template.is_null());
2595 DCHECK(FunctionTemplateInfo::cast(object_template->constructor())
2596 ->IsTemplateFor(object->map()));;
2598 MaybeHandle<JSObject> maybe_obj =
2599 ApiNatives::InstantiateObject(object_template);
2600 Handle<JSObject> obj;
2601 if (!maybe_obj.ToHandle(&obj)) {
2602 DCHECK(isolate()->has_pending_exception());
2603 isolate()->clear_pending_exception();
2606 TransferObject(obj, object);
2611 void Genesis::TransferNamedProperties(Handle<JSObject> from,
2612 Handle<JSObject> to) {
2613 // If JSObject::AddProperty asserts due to already existing property,
2614 // it is likely due to both global objects sharing property name(s).
2615 // Merging those two global objects is impossible.
2616 // The global template must not create properties that already exist
2617 // in the snapshotted global object.
2618 if (from->HasFastProperties()) {
2619 Handle<DescriptorArray> descs =
2620 Handle<DescriptorArray>(from->map()->instance_descriptors());
2621 for (int i = 0; i < from->map()->NumberOfOwnDescriptors(); i++) {
2622 PropertyDetails details = descs->GetDetails(i);
2623 switch (details.type()) {
2625 HandleScope inner(isolate());
2626 Handle<Name> key = Handle<Name>(descs->GetKey(i));
2627 FieldIndex index = FieldIndex::ForDescriptor(from->map(), i);
2628 DCHECK(!descs->GetDetails(i).representation().IsDouble());
2629 Handle<Object> value = Handle<Object>(from->RawFastPropertyAt(index),
2631 JSObject::AddProperty(to, key, value, details.attributes());
2634 case DATA_CONSTANT: {
2635 HandleScope inner(isolate());
2636 Handle<Name> key = Handle<Name>(descs->GetKey(i));
2637 Handle<Object> constant(descs->GetConstant(i), isolate());
2638 JSObject::AddProperty(to, key, constant, details.attributes());
2643 case ACCESSOR_CONSTANT: {
2644 Handle<Name> key(descs->GetKey(i));
2645 LookupIterator it(to, key, LookupIterator::OWN_SKIP_INTERCEPTOR);
2646 CHECK_NE(LookupIterator::ACCESS_CHECK, it.state());
2647 // If the property is already there we skip it
2648 if (it.IsFound()) continue;
2649 HandleScope inner(isolate());
2650 DCHECK(!to->HasFastProperties());
2651 // Add to dictionary.
2652 Handle<Object> callbacks(descs->GetCallbacksObject(i), isolate());
2653 PropertyDetails d(details.attributes(), ACCESSOR_CONSTANT, i + 1);
2654 JSObject::SetNormalizedProperty(to, key, callbacks, d);
2660 Handle<NameDictionary> properties =
2661 Handle<NameDictionary>(from->property_dictionary());
2662 int capacity = properties->Capacity();
2663 for (int i = 0; i < capacity; i++) {
2664 Object* raw_key(properties->KeyAt(i));
2665 if (properties->IsKey(raw_key)) {
2666 DCHECK(raw_key->IsName());
2667 // If the property is already there we skip it.
2668 Handle<Name> key(Name::cast(raw_key));
2669 LookupIterator it(to, key, LookupIterator::OWN_SKIP_INTERCEPTOR);
2670 CHECK_NE(LookupIterator::ACCESS_CHECK, it.state());
2671 if (it.IsFound()) continue;
2672 // Set the property.
2673 Handle<Object> value = Handle<Object>(properties->ValueAt(i),
2675 DCHECK(!value->IsCell());
2676 if (value->IsPropertyCell()) {
2677 value = Handle<Object>(PropertyCell::cast(*value)->value(),
2680 PropertyDetails details = properties->DetailsAt(i);
2681 DCHECK_EQ(kData, details.kind());
2682 JSObject::AddProperty(to, key, value, details.attributes());
2689 void Genesis::TransferIndexedProperties(Handle<JSObject> from,
2690 Handle<JSObject> to) {
2691 // Cloning the elements array is sufficient.
2692 Handle<FixedArray> from_elements =
2693 Handle<FixedArray>(FixedArray::cast(from->elements()));
2694 Handle<FixedArray> to_elements = factory()->CopyFixedArray(from_elements);
2695 to->set_elements(*to_elements);
2699 void Genesis::TransferObject(Handle<JSObject> from, Handle<JSObject> to) {
2700 HandleScope outer(isolate());
2702 DCHECK(!from->IsJSArray());
2703 DCHECK(!to->IsJSArray());
2705 TransferNamedProperties(from, to);
2706 TransferIndexedProperties(from, to);
2708 // Transfer the prototype (new map is needed).
2709 Handle<Object> proto(from->map()->prototype(), isolate());
2710 SetObjectPrototype(to, proto);
2714 void Genesis::MakeFunctionInstancePrototypeWritable() {
2715 // The maps with writable prototype are created in CreateEmptyFunction
2716 // and CreateStrictModeFunctionMaps respectively. Initially the maps are
2717 // created with read-only prototype for JS builtins processing.
2718 DCHECK(!sloppy_function_map_writable_prototype_.is_null());
2719 DCHECK(!strict_function_map_writable_prototype_.is_null());
2721 // Replace function instance maps to make prototype writable.
2722 native_context()->set_sloppy_function_map(
2723 *sloppy_function_map_writable_prototype_);
2724 native_context()->set_strict_function_map(
2725 *strict_function_map_writable_prototype_);
2729 class NoTrackDoubleFieldsForSerializerScope {
2731 explicit NoTrackDoubleFieldsForSerializerScope(Isolate* isolate)
2732 : flag_(FLAG_track_double_fields), enabled_(false) {
2733 if (isolate->serializer_enabled()) {
2734 // Disable tracking double fields because heap numbers treated as
2735 // immutable by the serializer.
2736 FLAG_track_double_fields = false;
2741 ~NoTrackDoubleFieldsForSerializerScope() {
2743 FLAG_track_double_fields = flag_;
2753 Genesis::Genesis(Isolate* isolate,
2754 MaybeHandle<JSGlobalProxy> maybe_global_proxy,
2755 v8::Handle<v8::ObjectTemplate> global_proxy_template,
2756 v8::ExtensionConfiguration* extensions)
2757 : isolate_(isolate),
2758 active_(isolate->bootstrapper()) {
2759 NoTrackDoubleFieldsForSerializerScope disable_scope(isolate);
2760 result_ = Handle<Context>::null();
2761 // Before creating the roots we must save the context and restore it
2762 // on all function exits.
2763 SaveContext saved_context(isolate);
2765 // During genesis, the boilerplate for stack overflow won't work until the
2766 // environment has been at least partially initialized. Add a stack check
2767 // before entering JS code to catch overflow early.
2768 StackLimitCheck check(isolate);
2769 if (check.HasOverflowed()) return;
2771 // The deserializer needs to hook up references to the global proxy.
2772 // Create an uninitialized global proxy now if we don't have one
2773 // and initialize it later in CreateNewGlobals.
2774 Handle<JSGlobalProxy> global_proxy;
2775 if (!maybe_global_proxy.ToHandle(&global_proxy)) {
2776 global_proxy = isolate->factory()->NewUninitializedJSGlobalProxy();
2779 // We can only de-serialize a context if the isolate was initialized from
2780 // a snapshot. Otherwise we have to build the context from scratch.
2781 Handle<FixedArray> outdated_contexts;
2782 if (!isolate->initialized_from_snapshot() ||
2783 !Snapshot::NewContextFromSnapshot(isolate, global_proxy,
2785 .ToHandle(&native_context_)) {
2786 native_context_ = Handle<Context>();
2789 if (!native_context().is_null()) {
2790 AddToWeakNativeContextList(*native_context());
2791 isolate->set_context(*native_context());
2792 isolate->counters()->contexts_created_by_snapshot()->Increment();
2794 if (FLAG_trace_maps) {
2795 Handle<JSFunction> object_fun = isolate->object_function();
2796 PrintF("[TraceMap: InitialMap map= %p SFI= %d_Object ]\n",
2797 reinterpret_cast<void*>(object_fun->initial_map()),
2798 object_fun->shared()->unique_id());
2799 Map::TraceAllTransitions(object_fun->initial_map());
2802 Handle<GlobalObject> global_object =
2803 CreateNewGlobals(global_proxy_template, global_proxy);
2805 HookUpGlobalProxy(global_object, global_proxy);
2806 HookUpGlobalObject(global_object, outdated_contexts);
2807 native_context()->builtins()->set_global_proxy(
2808 native_context()->global_proxy());
2810 if (!ConfigureGlobalObjects(global_proxy_template)) return;
2812 // We get here if there was no context snapshot.
2814 Handle<JSFunction> empty_function = CreateEmptyFunction(isolate);
2815 CreateStrictModeFunctionMaps(empty_function);
2816 Handle<GlobalObject> global_object =
2817 CreateNewGlobals(global_proxy_template, global_proxy);
2818 HookUpGlobalProxy(global_object, global_proxy);
2819 InitializeGlobal(global_object, empty_function);
2820 InstallJSFunctionResultCaches();
2821 InitializeNormalizedMapCaches();
2822 if (!InstallNatives()) return;
2824 MakeFunctionInstancePrototypeWritable();
2826 if (!ConfigureGlobalObjects(global_proxy_template)) return;
2827 isolate->counters()->contexts_created_from_scratch()->Increment();
2830 // Install experimental natives.
2831 if (!InstallExperimentalNatives()) return;
2832 InitializeExperimentalGlobal();
2834 // The serializer cannot serialize typed arrays. Reset those typed arrays
2835 // for each new context.
2836 InitializeBuiltinTypedArrays();
2838 result_ = native_context();
2842 // Support for thread preemption.
2844 // Reserve space for statics needing saving and restoring.
2845 int Bootstrapper::ArchiveSpacePerThread() {
2846 return sizeof(NestingCounterType);
2850 // Archive statics that are thread-local.
2851 char* Bootstrapper::ArchiveState(char* to) {
2852 *reinterpret_cast<NestingCounterType*>(to) = nesting_;
2854 return to + sizeof(NestingCounterType);
2858 // Restore statics that are thread-local.
2859 char* Bootstrapper::RestoreState(char* from) {
2860 nesting_ = *reinterpret_cast<NestingCounterType*>(from);
2861 return from + sizeof(NestingCounterType);
2865 // Called when the top-level V8 mutex is destroyed.
2866 void Bootstrapper::FreeThreadResources() {
2867 DCHECK(!IsActive());
2870 } } // namespace v8::internal