1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 #include "accessors.h"
32 #include "bootstrapper.h"
35 #include "execution.h"
36 #include "global-handles.h"
37 #include "isolate-inl.h"
38 #include "macro-assembler.h"
40 #include "objects-visiting.h"
43 #include "trig-table.h"
44 #include "extensions/externalize-string-extension.h"
45 #include "extensions/free-buffer-extension.h"
46 #include "extensions/gc-extension.h"
47 #include "extensions/statistics-extension.h"
48 #include "extensions/trigger-failure-extension.h"
49 #include "code-stubs.h"
55 NativesExternalStringResource::NativesExternalStringResource(
56 Bootstrapper* bootstrapper,
59 : data_(source), length_(length) {
60 if (bootstrapper->delete_these_non_arrays_on_tear_down_ == NULL) {
61 bootstrapper->delete_these_non_arrays_on_tear_down_ = new List<char*>(2);
63 // The resources are small objects and we only make a fixed number of
64 // them, but let's clean them up on exit for neatness.
65 bootstrapper->delete_these_non_arrays_on_tear_down_->
66 Add(reinterpret_cast<char*>(this));
70 Bootstrapper::Bootstrapper(Isolate* isolate)
73 extensions_cache_(Script::TYPE_EXTENSION),
74 delete_these_non_arrays_on_tear_down_(NULL),
75 delete_these_arrays_on_tear_down_(NULL) {
79 Handle<String> Bootstrapper::NativesSourceLookup(int index) {
80 ASSERT(0 <= index && index < Natives::GetBuiltinsCount());
81 Heap* heap = isolate_->heap();
82 if (heap->natives_source_cache()->get(index)->IsUndefined()) {
83 // We can use external strings for the natives.
84 Vector<const char> source = Natives::GetRawScriptSource(index);
85 NativesExternalStringResource* resource =
86 new NativesExternalStringResource(this,
89 Handle<String> source_code =
90 isolate_->factory()->NewExternalStringFromAscii(resource);
91 heap->natives_source_cache()->set(index, *source_code);
93 Handle<Object> cached_source(heap->natives_source_cache()->get(index),
95 return Handle<String>::cast(cached_source);
99 void Bootstrapper::Initialize(bool create_heap_objects) {
100 extensions_cache_.Initialize(isolate_, create_heap_objects);
104 static const char* GCFunctionName() {
105 bool flag_given = FLAG_expose_gc_as != NULL && strlen(FLAG_expose_gc_as) != 0;
106 return flag_given ? FLAG_expose_gc_as : "gc";
110 v8::Extension* Bootstrapper::free_buffer_extension_ = NULL;
111 v8::Extension* Bootstrapper::gc_extension_ = NULL;
112 v8::Extension* Bootstrapper::externalize_string_extension_ = NULL;
113 v8::Extension* Bootstrapper::statistics_extension_ = NULL;
114 v8::Extension* Bootstrapper::trigger_failure_extension_ = NULL;
117 void Bootstrapper::InitializeOncePerProcess() {
118 free_buffer_extension_ = new FreeBufferExtension;
119 v8::RegisterExtension(free_buffer_extension_);
120 gc_extension_ = new GCExtension(GCFunctionName());
121 v8::RegisterExtension(gc_extension_);
122 externalize_string_extension_ = new ExternalizeStringExtension;
123 v8::RegisterExtension(externalize_string_extension_);
124 statistics_extension_ = new StatisticsExtension;
125 v8::RegisterExtension(statistics_extension_);
126 trigger_failure_extension_ = new TriggerFailureExtension;
127 v8::RegisterExtension(trigger_failure_extension_);
131 void Bootstrapper::TearDownExtensions() {
132 delete free_buffer_extension_;
133 delete gc_extension_;
134 delete externalize_string_extension_;
135 delete statistics_extension_;
136 delete trigger_failure_extension_;
140 char* Bootstrapper::AllocateAutoDeletedArray(int bytes) {
141 char* memory = new char[bytes];
142 if (memory != NULL) {
143 if (delete_these_arrays_on_tear_down_ == NULL) {
144 delete_these_arrays_on_tear_down_ = new List<char*>(2);
146 delete_these_arrays_on_tear_down_->Add(memory);
152 void Bootstrapper::TearDown() {
153 if (delete_these_non_arrays_on_tear_down_ != NULL) {
154 int len = delete_these_non_arrays_on_tear_down_->length();
155 ASSERT(len < 20); // Don't use this mechanism for unbounded allocations.
156 for (int i = 0; i < len; i++) {
157 delete delete_these_non_arrays_on_tear_down_->at(i);
158 delete_these_non_arrays_on_tear_down_->at(i) = NULL;
160 delete delete_these_non_arrays_on_tear_down_;
161 delete_these_non_arrays_on_tear_down_ = NULL;
164 if (delete_these_arrays_on_tear_down_ != NULL) {
165 int len = delete_these_arrays_on_tear_down_->length();
166 ASSERT(len < 1000); // Don't use this mechanism for unbounded allocations.
167 for (int i = 0; i < len; i++) {
168 delete[] delete_these_arrays_on_tear_down_->at(i);
169 delete_these_arrays_on_tear_down_->at(i) = NULL;
171 delete delete_these_arrays_on_tear_down_;
172 delete_these_arrays_on_tear_down_ = NULL;
175 extensions_cache_.Initialize(isolate_, false); // Yes, symmetrical
179 class Genesis BASE_EMBEDDED {
181 Genesis(Isolate* isolate,
182 Handle<Object> global_object,
183 v8::Handle<v8::ObjectTemplate> global_template,
184 v8::ExtensionConfiguration* extensions);
187 Isolate* isolate() const { return isolate_; }
188 Factory* factory() const { return isolate_->factory(); }
189 Heap* heap() const { return isolate_->heap(); }
191 Handle<Context> result() { return result_; }
194 Handle<Context> native_context() { return native_context_; }
196 // Creates some basic objects. Used for creating a context from scratch.
198 // Creates the empty function. Used for creating a context from scratch.
199 Handle<JSFunction> CreateEmptyFunction(Isolate* isolate);
200 // Creates the ThrowTypeError function. ECMA 5th Ed. 13.2.3
201 Handle<JSFunction> GetThrowTypeErrorFunction();
203 void CreateStrictModeFunctionMaps(Handle<JSFunction> empty);
205 // Make the "arguments" and "caller" properties throw a TypeError on access.
206 void PoisonArgumentsAndCaller(Handle<Map> map);
208 // Creates the global objects using the global and the template passed in
209 // through the API. We call this regardless of whether we are building a
210 // context from scratch or using a deserialized one from the partial snapshot
211 // but in the latter case we don't use the objects it produces directly, as
212 // we have to used the deserialized ones that are linked together with the
213 // rest of the context snapshot.
214 Handle<JSGlobalProxy> CreateNewGlobals(
215 v8::Handle<v8::ObjectTemplate> global_template,
216 Handle<Object> global_object,
217 Handle<GlobalObject>* global_proxy_out);
218 // Hooks the given global proxy into the context. If the context was created
219 // by deserialization then this will unhook the global proxy that was
220 // deserialized, leaving the GC to pick it up.
221 void HookUpGlobalProxy(Handle<GlobalObject> inner_global,
222 Handle<JSGlobalProxy> global_proxy);
223 // Similarly, we want to use the inner global that has been created by the
224 // templates passed through the API. The inner global from the snapshot is
225 // detached from the other objects in the snapshot.
226 void HookUpInnerGlobal(Handle<GlobalObject> inner_global);
227 // New context initialization. Used for creating a context from scratch.
228 void InitializeGlobal(Handle<GlobalObject> inner_global,
229 Handle<JSFunction> empty_function);
230 void InitializeExperimentalGlobal();
231 // Installs the contents of the native .js files on the global objects.
232 // Used for creating a context from scratch.
233 void InstallNativeFunctions();
234 void InstallExperimentalNativeFunctions();
235 Handle<JSFunction> InstallInternalArray(Handle<JSBuiltinsObject> builtins,
237 ElementsKind elements_kind);
238 bool InstallNatives();
240 Handle<JSFunction> InstallTypedArray(const char* name,
241 ElementsKind elementsKind);
242 bool InstallExperimentalNatives();
243 void InstallBuiltinFunctionIds();
244 void InstallExperimentalSIMDBuiltinFunctionIds();
245 void InstallJSFunctionResultCaches();
246 void InitializeNormalizedMapCaches();
248 enum ExtensionTraversalState {
249 UNVISITED, VISITED, INSTALLED
252 class ExtensionStates {
255 ExtensionTraversalState get_state(RegisteredExtension* extension);
256 void set_state(RegisteredExtension* extension,
257 ExtensionTraversalState state);
260 DISALLOW_COPY_AND_ASSIGN(ExtensionStates);
263 // Used both for deserialized and from-scratch contexts to add the extensions
265 static bool InstallExtensions(Handle<Context> native_context,
266 v8::ExtensionConfiguration* extensions);
267 static bool InstallAutoExtensions(Isolate* isolate,
268 ExtensionStates* extension_states);
269 static bool InstallRequestedExtensions(Isolate* isolate,
270 v8::ExtensionConfiguration* extensions,
271 ExtensionStates* extension_states);
272 static bool InstallExtension(Isolate* isolate,
274 ExtensionStates* extension_states);
275 static bool InstallExtension(Isolate* isolate,
276 v8::RegisteredExtension* current,
277 ExtensionStates* extension_states);
278 static bool InstallSpecialObjects(Handle<Context> native_context);
279 bool InstallJSBuiltins(Handle<JSBuiltinsObject> builtins);
280 bool ConfigureApiObject(Handle<JSObject> object,
281 Handle<ObjectTemplateInfo> object_template);
282 bool ConfigureGlobalObjects(v8::Handle<v8::ObjectTemplate> global_template);
284 // Migrates all properties from the 'from' object to the 'to'
285 // object and overrides the prototype in 'to' with the one from
287 void TransferObject(Handle<JSObject> from, Handle<JSObject> to);
288 void TransferNamedProperties(Handle<JSObject> from, Handle<JSObject> to);
289 void TransferIndexedProperties(Handle<JSObject> from, Handle<JSObject> to);
291 enum PrototypePropertyMode {
293 ADD_READONLY_PROTOTYPE,
294 ADD_WRITEABLE_PROTOTYPE
297 Handle<Map> CreateFunctionMap(PrototypePropertyMode prototype_mode);
299 void SetFunctionInstanceDescriptor(Handle<Map> map,
300 PrototypePropertyMode prototypeMode);
301 void MakeFunctionInstancePrototypeWritable();
303 Handle<Map> CreateStrictModeFunctionMap(
304 PrototypePropertyMode prototype_mode,
305 Handle<JSFunction> empty_function);
307 void SetStrictFunctionInstanceDescriptor(Handle<Map> map,
308 PrototypePropertyMode propertyMode);
310 static bool CompileBuiltin(Isolate* isolate, int index);
311 static bool CompileExperimentalBuiltin(Isolate* isolate, int index);
312 static bool CompileNative(Isolate* isolate,
313 Vector<const char> name,
314 Handle<String> source);
315 static bool CompileScriptCached(Isolate* isolate,
316 Vector<const char> name,
317 Handle<String> source,
318 SourceCodeCache* cache,
319 v8::Extension* extension,
320 Handle<Context> top_context,
321 bool use_runtime_context);
324 Handle<Context> result_;
325 Handle<Context> native_context_;
327 // Function maps. Function maps are created initially with a read only
328 // prototype for the processing of JS builtins. Later the function maps are
329 // replaced in order to make prototype writable. These are the final, writable
331 Handle<Map> function_map_writable_prototype_;
332 Handle<Map> strict_mode_function_map_writable_prototype_;
333 Handle<JSFunction> throw_type_error_function;
335 BootstrapperActive active_;
336 friend class Bootstrapper;
340 void Bootstrapper::Iterate(ObjectVisitor* v) {
341 extensions_cache_.Iterate(v);
342 v->Synchronize(VisitorSynchronization::kExtensions);
346 Handle<Context> Bootstrapper::CreateEnvironment(
347 Handle<Object> global_object,
348 v8::Handle<v8::ObjectTemplate> global_template,
349 v8::ExtensionConfiguration* extensions) {
350 HandleScope scope(isolate_);
351 Genesis genesis(isolate_, global_object, global_template, extensions);
352 Handle<Context> env = genesis.result();
353 if (env.is_null() || !InstallExtensions(env, extensions)) {
354 return Handle<Context>();
356 return scope.CloseAndEscape(env);
360 static void SetObjectPrototype(Handle<JSObject> object, Handle<Object> proto) {
361 // object.__proto__ = proto;
362 Factory* factory = object->GetIsolate()->factory();
363 Handle<Map> old_to_map = Handle<Map>(object->map());
364 Handle<Map> new_to_map = factory->CopyMap(old_to_map);
365 new_to_map->set_prototype(*proto);
366 object->set_map(*new_to_map);
370 void Bootstrapper::DetachGlobal(Handle<Context> env) {
371 Factory* factory = env->GetIsolate()->factory();
372 Handle<JSGlobalProxy> global_proxy(JSGlobalProxy::cast(env->global_proxy()));
373 global_proxy->set_native_context(*factory->null_value());
374 SetObjectPrototype(global_proxy, factory->null_value());
378 static Handle<JSFunction> InstallFunction(Handle<JSObject> target,
382 Handle<JSObject> prototype,
384 bool install_initial_map,
385 bool set_instance_class_name) {
386 Isolate* isolate = target->GetIsolate();
387 Factory* factory = isolate->factory();
388 Handle<String> internalized_name = factory->InternalizeUtf8String(name);
389 Handle<Code> call_code = Handle<Code>(isolate->builtins()->builtin(call));
390 Handle<JSFunction> function = prototype.is_null() ?
391 factory->NewFunctionWithoutPrototype(internalized_name, call_code) :
392 factory->NewFunctionWithPrototype(internalized_name,
397 install_initial_map);
398 PropertyAttributes attributes;
399 if (target->IsJSBuiltinsObject()) {
401 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
403 attributes = DONT_ENUM;
405 CHECK_NOT_EMPTY_HANDLE(isolate,
406 JSObject::SetLocalPropertyIgnoreAttributes(
407 target, internalized_name, function, attributes));
408 if (set_instance_class_name) {
409 function->shared()->set_instance_class_name(*internalized_name);
411 function->shared()->set_native(true);
416 void Genesis::SetFunctionInstanceDescriptor(
417 Handle<Map> map, PrototypePropertyMode prototypeMode) {
418 int size = (prototypeMode == DONT_ADD_PROTOTYPE) ? 4 : 5;
419 Handle<DescriptorArray> descriptors(factory()->NewDescriptorArray(0, size));
420 DescriptorArray::WhitenessWitness witness(*descriptors);
422 Handle<Foreign> length(factory()->NewForeign(&Accessors::FunctionLength));
423 Handle<Foreign> name(factory()->NewForeign(&Accessors::FunctionName));
424 Handle<Foreign> args(factory()->NewForeign(&Accessors::FunctionArguments));
425 Handle<Foreign> caller(factory()->NewForeign(&Accessors::FunctionCaller));
426 Handle<Foreign> prototype;
427 if (prototypeMode != DONT_ADD_PROTOTYPE) {
428 prototype = factory()->NewForeign(&Accessors::FunctionPrototype);
430 PropertyAttributes attribs = static_cast<PropertyAttributes>(
431 DONT_ENUM | DONT_DELETE | READ_ONLY);
432 map->set_instance_descriptors(*descriptors);
435 CallbacksDescriptor d(*factory()->length_string(), *length, attribs);
436 map->AppendDescriptor(&d, witness);
439 CallbacksDescriptor d(*factory()->name_string(), *name, attribs);
440 map->AppendDescriptor(&d, witness);
443 CallbacksDescriptor d(*factory()->arguments_string(), *args, attribs);
444 map->AppendDescriptor(&d, witness);
447 CallbacksDescriptor d(*factory()->caller_string(), *caller, attribs);
448 map->AppendDescriptor(&d, witness);
450 if (prototypeMode != DONT_ADD_PROTOTYPE) {
452 if (prototypeMode == ADD_WRITEABLE_PROTOTYPE) {
453 attribs = static_cast<PropertyAttributes>(attribs & ~READ_ONLY);
455 CallbacksDescriptor d(*factory()->prototype_string(), *prototype, attribs);
456 map->AppendDescriptor(&d, witness);
461 Handle<Map> Genesis::CreateFunctionMap(PrototypePropertyMode prototype_mode) {
462 Handle<Map> map = factory()->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
463 SetFunctionInstanceDescriptor(map, prototype_mode);
464 map->set_function_with_prototype(prototype_mode != DONT_ADD_PROTOTYPE);
469 Handle<JSFunction> Genesis::CreateEmptyFunction(Isolate* isolate) {
470 // Allocate the map for function instances. Maps are allocated first and their
471 // prototypes patched later, once empty function is created.
473 // Functions with this map will not have a 'prototype' property, and
474 // can not be used as constructors.
475 Handle<Map> function_without_prototype_map =
476 CreateFunctionMap(DONT_ADD_PROTOTYPE);
477 native_context()->set_function_without_prototype_map(
478 *function_without_prototype_map);
480 // Allocate the function map. This map is temporary, used only for processing
482 // Later the map is replaced with writable prototype map, allocated below.
483 Handle<Map> function_map = CreateFunctionMap(ADD_READONLY_PROTOTYPE);
484 native_context()->set_function_map(*function_map);
486 // The final map for functions. Writeable prototype.
487 // This map is installed in MakeFunctionInstancePrototypeWritable.
488 function_map_writable_prototype_ = CreateFunctionMap(ADD_WRITEABLE_PROTOTYPE);
490 Factory* factory = isolate->factory();
492 Handle<String> object_name = factory->Object_string();
494 { // --- O b j e c t ---
495 Handle<JSFunction> object_fun =
496 factory->NewFunction(object_name, factory->null_value());
497 Handle<Map> object_function_map =
498 factory->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
499 object_fun->set_initial_map(*object_function_map);
500 object_function_map->set_constructor(*object_fun);
502 native_context()->set_object_function(*object_fun);
504 // Allocate a new prototype for the object function.
505 Handle<JSObject> prototype = factory->NewJSObject(
506 isolate->object_function(),
509 native_context()->set_initial_object_prototype(*prototype);
510 // For bootstrapping set the array prototype to be the same as the object
511 // prototype, otherwise the missing initial_array_prototype will cause
512 // assertions during startup.
513 native_context()->set_initial_array_prototype(*prototype);
514 Accessors::FunctionSetPrototype(object_fun, prototype);
517 // Allocate the empty function as the prototype for function ECMAScript
519 Handle<String> empty_string =
520 factory->InternalizeOneByteString(STATIC_ASCII_VECTOR("Empty"));
521 Handle<JSFunction> empty_function =
522 factory->NewFunctionWithoutPrototype(empty_string, CLASSIC_MODE);
526 Handle<Code>(isolate->builtins()->builtin(
527 Builtins::kEmptyFunction));
528 empty_function->set_code(*code);
529 empty_function->shared()->set_code(*code);
530 Handle<String> source =
531 factory->NewStringFromOneByte(STATIC_ASCII_VECTOR("() {}"));
532 Handle<Script> script = factory->NewScript(source);
533 script->set_type(Smi::FromInt(Script::TYPE_NATIVE));
534 empty_function->shared()->set_script(*script);
535 empty_function->shared()->set_start_position(0);
536 empty_function->shared()->set_end_position(source->length());
537 empty_function->shared()->DontAdaptArguments();
539 // Set prototypes for the function maps.
540 native_context()->function_map()->set_prototype(*empty_function);
541 native_context()->function_without_prototype_map()->
542 set_prototype(*empty_function);
543 function_map_writable_prototype_->set_prototype(*empty_function);
545 // Allocate the function map first and then patch the prototype later
546 Handle<Map> empty_function_map = CreateFunctionMap(DONT_ADD_PROTOTYPE);
547 empty_function_map->set_prototype(
548 native_context()->object_function()->prototype());
549 empty_function->set_map(*empty_function_map);
550 return empty_function;
554 void Genesis::SetStrictFunctionInstanceDescriptor(
555 Handle<Map> map, PrototypePropertyMode prototypeMode) {
556 int size = (prototypeMode == DONT_ADD_PROTOTYPE) ? 4 : 5;
557 Handle<DescriptorArray> descriptors(factory()->NewDescriptorArray(0, size));
558 DescriptorArray::WhitenessWitness witness(*descriptors);
560 Handle<Foreign> length(factory()->NewForeign(&Accessors::FunctionLength));
561 Handle<Foreign> name(factory()->NewForeign(&Accessors::FunctionName));
562 Handle<AccessorPair> arguments(factory()->NewAccessorPair());
563 Handle<AccessorPair> caller(factory()->NewAccessorPair());
564 Handle<Foreign> prototype;
565 if (prototypeMode != DONT_ADD_PROTOTYPE) {
566 prototype = factory()->NewForeign(&Accessors::FunctionPrototype);
568 PropertyAttributes rw_attribs =
569 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
570 PropertyAttributes ro_attribs =
571 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
572 map->set_instance_descriptors(*descriptors);
575 CallbacksDescriptor d(*factory()->length_string(), *length, ro_attribs);
576 map->AppendDescriptor(&d, witness);
579 CallbacksDescriptor d(*factory()->name_string(), *name, ro_attribs);
580 map->AppendDescriptor(&d, witness);
583 CallbacksDescriptor d(*factory()->arguments_string(), *arguments,
585 map->AppendDescriptor(&d, witness);
588 CallbacksDescriptor d(*factory()->caller_string(), *caller, rw_attribs);
589 map->AppendDescriptor(&d, witness);
591 if (prototypeMode != DONT_ADD_PROTOTYPE) {
593 PropertyAttributes attribs =
594 prototypeMode == ADD_WRITEABLE_PROTOTYPE ? rw_attribs : ro_attribs;
595 CallbacksDescriptor d(*factory()->prototype_string(), *prototype, attribs);
596 map->AppendDescriptor(&d, witness);
601 // ECMAScript 5th Edition, 13.2.3
602 Handle<JSFunction> Genesis::GetThrowTypeErrorFunction() {
603 if (throw_type_error_function.is_null()) {
604 Handle<String> name = factory()->InternalizeOneByteString(
605 STATIC_ASCII_VECTOR("ThrowTypeError"));
606 throw_type_error_function =
607 factory()->NewFunctionWithoutPrototype(name, CLASSIC_MODE);
608 Handle<Code> code(isolate()->builtins()->builtin(
609 Builtins::kStrictModePoisonPill));
610 throw_type_error_function->set_map(
611 native_context()->function_map());
612 throw_type_error_function->set_code(*code);
613 throw_type_error_function->shared()->set_code(*code);
614 throw_type_error_function->shared()->DontAdaptArguments();
616 JSObject::PreventExtensions(throw_type_error_function);
618 return throw_type_error_function;
622 Handle<Map> Genesis::CreateStrictModeFunctionMap(
623 PrototypePropertyMode prototype_mode,
624 Handle<JSFunction> empty_function) {
625 Handle<Map> map = factory()->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
626 SetStrictFunctionInstanceDescriptor(map, prototype_mode);
627 map->set_function_with_prototype(prototype_mode != DONT_ADD_PROTOTYPE);
628 map->set_prototype(*empty_function);
633 void Genesis::CreateStrictModeFunctionMaps(Handle<JSFunction> empty) {
634 // Allocate map for the prototype-less strict mode instances.
635 Handle<Map> strict_mode_function_without_prototype_map =
636 CreateStrictModeFunctionMap(DONT_ADD_PROTOTYPE, empty);
637 native_context()->set_strict_mode_function_without_prototype_map(
638 *strict_mode_function_without_prototype_map);
640 // Allocate map for the strict mode functions. This map is temporary, used
641 // only for processing of builtins.
642 // Later the map is replaced with writable prototype map, allocated below.
643 Handle<Map> strict_mode_function_map =
644 CreateStrictModeFunctionMap(ADD_READONLY_PROTOTYPE, empty);
645 native_context()->set_strict_mode_function_map(
646 *strict_mode_function_map);
648 // The final map for the strict mode functions. Writeable prototype.
649 // This map is installed in MakeFunctionInstancePrototypeWritable.
650 strict_mode_function_map_writable_prototype_ =
651 CreateStrictModeFunctionMap(ADD_WRITEABLE_PROTOTYPE, empty);
653 // Complete the callbacks.
654 PoisonArgumentsAndCaller(strict_mode_function_without_prototype_map);
655 PoisonArgumentsAndCaller(strict_mode_function_map);
656 PoisonArgumentsAndCaller(strict_mode_function_map_writable_prototype_);
660 static void SetAccessors(Handle<Map> map,
662 Handle<JSFunction> func) {
663 DescriptorArray* descs = map->instance_descriptors();
664 int number = descs->SearchWithCache(*name, *map);
665 AccessorPair* accessors = AccessorPair::cast(descs->GetValue(number));
666 accessors->set_getter(*func);
667 accessors->set_setter(*func);
671 void Genesis::PoisonArgumentsAndCaller(Handle<Map> map) {
672 SetAccessors(map, factory()->arguments_string(), GetThrowTypeErrorFunction());
673 SetAccessors(map, factory()->caller_string(), GetThrowTypeErrorFunction());
677 static void AddToWeakNativeContextList(Context* context) {
678 ASSERT(context->IsNativeContext());
679 Heap* heap = context->GetIsolate()->heap();
682 ASSERT(context->get(Context::NEXT_CONTEXT_LINK)->IsUndefined());
683 // Check that context is not in the list yet.
684 for (Object* current = heap->native_contexts_list();
685 !current->IsUndefined();
686 current = Context::cast(current)->get(Context::NEXT_CONTEXT_LINK)) {
687 ASSERT(current != context);
691 context->set(Context::NEXT_CONTEXT_LINK, heap->native_contexts_list());
692 heap->set_native_contexts_list(context);
696 void Genesis::CreateRoots() {
697 // Allocate the native context FixedArray first and then patch the
698 // closure and extension object later (we need the empty function
699 // and the global object, but in order to create those, we need the
701 native_context_ = factory()->NewNativeContext();
702 AddToWeakNativeContextList(*native_context());
703 isolate()->set_context(*native_context());
705 // Allocate the message listeners object.
707 v8::NeanderArray listeners(isolate());
708 native_context()->set_message_listeners(*listeners.value());
713 Handle<JSGlobalProxy> Genesis::CreateNewGlobals(
714 v8::Handle<v8::ObjectTemplate> global_template,
715 Handle<Object> global_object,
716 Handle<GlobalObject>* inner_global_out) {
717 // The argument global_template aka data is an ObjectTemplateInfo.
718 // It has a constructor pointer that points at global_constructor which is a
719 // FunctionTemplateInfo.
720 // The global_constructor is used to create or reinitialize the global_proxy.
721 // The global_constructor also has a prototype_template pointer that points at
722 // js_global_template which is an ObjectTemplateInfo.
723 // That in turn has a constructor pointer that points at
724 // js_global_constructor which is a FunctionTemplateInfo.
725 // js_global_constructor is used to make js_global_function
726 // js_global_function is used to make the new inner_global.
728 // --- G l o b a l ---
729 // Step 1: Create a fresh inner JSGlobalObject.
730 Handle<JSFunction> js_global_function;
731 Handle<ObjectTemplateInfo> js_global_template;
732 if (!global_template.IsEmpty()) {
733 // Get prototype template of the global_template.
734 Handle<ObjectTemplateInfo> data =
735 v8::Utils::OpenHandle(*global_template);
736 Handle<FunctionTemplateInfo> global_constructor =
737 Handle<FunctionTemplateInfo>(
738 FunctionTemplateInfo::cast(data->constructor()));
739 Handle<Object> proto_template(global_constructor->prototype_template(),
741 if (!proto_template->IsUndefined()) {
743 Handle<ObjectTemplateInfo>::cast(proto_template);
747 if (js_global_template.is_null()) {
748 Handle<String> name = Handle<String>(heap()->empty_string());
749 Handle<Code> code = Handle<Code>(isolate()->builtins()->builtin(
750 Builtins::kIllegal));
752 factory()->NewFunction(name, JS_GLOBAL_OBJECT_TYPE,
753 JSGlobalObject::kSize, code, true);
754 // Change the constructor property of the prototype of the
755 // hidden global function to refer to the Object function.
756 Handle<JSObject> prototype =
758 JSObject::cast(js_global_function->instance_prototype()));
759 CHECK_NOT_EMPTY_HANDLE(isolate(),
760 JSObject::SetLocalPropertyIgnoreAttributes(
761 prototype, factory()->constructor_string(),
762 isolate()->object_function(), NONE));
764 Handle<FunctionTemplateInfo> js_global_constructor(
765 FunctionTemplateInfo::cast(js_global_template->constructor()));
767 factory()->CreateApiFunction(js_global_constructor,
768 factory()->InnerGlobalObject);
771 js_global_function->initial_map()->set_is_hidden_prototype();
772 js_global_function->initial_map()->set_dictionary_map(true);
773 Handle<GlobalObject> inner_global =
774 factory()->NewGlobalObject(js_global_function);
775 if (inner_global_out != NULL) {
776 *inner_global_out = inner_global;
779 // Step 2: create or re-initialize the global proxy object.
780 Handle<JSFunction> global_proxy_function;
781 if (global_template.IsEmpty()) {
782 Handle<String> name = Handle<String>(heap()->empty_string());
783 Handle<Code> code = Handle<Code>(isolate()->builtins()->builtin(
784 Builtins::kIllegal));
785 global_proxy_function =
786 factory()->NewFunction(name, JS_GLOBAL_PROXY_TYPE,
787 JSGlobalProxy::kSize, code, true);
789 Handle<ObjectTemplateInfo> data =
790 v8::Utils::OpenHandle(*global_template);
791 Handle<FunctionTemplateInfo> global_constructor(
792 FunctionTemplateInfo::cast(data->constructor()));
793 global_proxy_function =
794 factory()->CreateApiFunction(global_constructor,
795 factory()->OuterGlobalObject);
798 Handle<String> global_name = factory()->InternalizeOneByteString(
799 STATIC_ASCII_VECTOR("global"));
800 global_proxy_function->shared()->set_instance_class_name(*global_name);
801 global_proxy_function->initial_map()->set_is_access_check_needed(true);
803 // Set global_proxy.__proto__ to js_global after ConfigureGlobalObjects
804 // Return the global proxy.
806 if (global_object.location() != NULL) {
807 ASSERT(global_object->IsJSGlobalProxy());
808 return ReinitializeJSGlobalProxy(
809 global_proxy_function,
810 Handle<JSGlobalProxy>::cast(global_object));
812 return Handle<JSGlobalProxy>::cast(
813 factory()->NewJSObject(global_proxy_function, TENURED));
818 void Genesis::HookUpGlobalProxy(Handle<GlobalObject> inner_global,
819 Handle<JSGlobalProxy> global_proxy) {
820 // Set the native context for the global object.
821 inner_global->set_native_context(*native_context());
822 inner_global->set_global_context(*native_context());
823 inner_global->set_global_receiver(*global_proxy);
824 global_proxy->set_native_context(*native_context());
825 native_context()->set_global_proxy(*global_proxy);
829 void Genesis::HookUpInnerGlobal(Handle<GlobalObject> inner_global) {
830 Handle<GlobalObject> inner_global_from_snapshot(
831 GlobalObject::cast(native_context()->extension()));
832 Handle<JSBuiltinsObject> builtins_global(native_context()->builtins());
833 native_context()->set_extension(*inner_global);
834 native_context()->set_global_object(*inner_global);
835 native_context()->set_security_token(*inner_global);
836 static const PropertyAttributes attributes =
837 static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE);
838 ForceSetProperty(builtins_global,
839 factory()->InternalizeOneByteString(
840 STATIC_ASCII_VECTOR("global")),
843 // Set up the reference from the global object to the builtins object.
844 JSGlobalObject::cast(*inner_global)->set_builtins(*builtins_global);
845 TransferNamedProperties(inner_global_from_snapshot, inner_global);
846 TransferIndexedProperties(inner_global_from_snapshot, inner_global);
850 // This is only called if we are not using snapshots. The equivalent
851 // work in the snapshot case is done in HookUpInnerGlobal.
852 void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
853 Handle<JSFunction> empty_function) {
854 // --- N a t i v e C o n t e x t ---
855 // Use the empty function as closure (no scope info).
856 native_context()->set_closure(*empty_function);
857 native_context()->set_previous(NULL);
858 // Set extension and global object.
859 native_context()->set_extension(*inner_global);
860 native_context()->set_global_object(*inner_global);
861 // Security setup: Set the security token of the global object to
862 // its the inner global. This makes the security check between two
863 // different contexts fail by default even in case of global
864 // object reinitialization.
865 native_context()->set_security_token(*inner_global);
867 Isolate* isolate = inner_global->GetIsolate();
868 Factory* factory = isolate->factory();
869 Heap* heap = isolate->heap();
871 Handle<String> object_name = factory->Object_string();
872 CHECK_NOT_EMPTY_HANDLE(isolate,
873 JSObject::SetLocalPropertyIgnoreAttributes(
874 inner_global, object_name,
875 isolate->object_function(), DONT_ENUM));
877 Handle<JSObject> global = Handle<JSObject>(native_context()->global_object());
879 // Install global Function object
880 InstallFunction(global, "Function", JS_FUNCTION_TYPE, JSFunction::kSize,
881 empty_function, Builtins::kIllegal, true, true);
883 { // --- A r r a y ---
884 Handle<JSFunction> array_function =
885 InstallFunction(global, "Array", JS_ARRAY_TYPE, JSArray::kSize,
886 isolate->initial_object_prototype(),
887 Builtins::kArrayCode, true, true);
888 array_function->shared()->DontAdaptArguments();
889 array_function->shared()->set_function_data(Smi::FromInt(kArrayCode));
891 // This seems a bit hackish, but we need to make sure Array.length
893 array_function->shared()->set_length(1);
895 Handle<Map> initial_map(array_function->initial_map());
897 // This assert protects an optimization in
898 // HGraphBuilder::JSArrayBuilder::EmitMapCode()
899 ASSERT(initial_map->elements_kind() == GetInitialFastElementsKind());
901 Handle<DescriptorArray> array_descriptors(
902 factory->NewDescriptorArray(0, 1));
903 DescriptorArray::WhitenessWitness witness(*array_descriptors);
905 Handle<Foreign> array_length(factory->NewForeign(&Accessors::ArrayLength));
906 PropertyAttributes attribs = static_cast<PropertyAttributes>(
907 DONT_ENUM | DONT_DELETE);
908 initial_map->set_instance_descriptors(*array_descriptors);
911 CallbacksDescriptor d(*factory->length_string(), *array_length, attribs);
912 array_function->initial_map()->AppendDescriptor(&d, witness);
915 // array_function is used internally. JS code creating array object should
916 // search for the 'Array' property on the global object and use that one
917 // as the constructor. 'Array' property on a global object can be
918 // overwritten by JS code.
919 native_context()->set_array_function(*array_function);
921 // Cache the array maps, needed by ArrayConstructorStub
922 CacheInitialJSArrayMaps(native_context(), initial_map);
923 ArrayConstructorStub array_constructor_stub(isolate);
924 Handle<Code> code = array_constructor_stub.GetCode(isolate);
925 array_function->shared()->set_construct_stub(*code);
928 { // --- N u m b e r ---
929 Handle<JSFunction> number_fun =
930 InstallFunction(global, "Number", JS_VALUE_TYPE, JSValue::kSize,
931 isolate->initial_object_prototype(),
932 Builtins::kIllegal, true, true);
933 native_context()->set_number_function(*number_fun);
936 { // --- B o o l e a n ---
937 Handle<JSFunction> boolean_fun =
938 InstallFunction(global, "Boolean", JS_VALUE_TYPE, JSValue::kSize,
939 isolate->initial_object_prototype(),
940 Builtins::kIllegal, true, true);
941 native_context()->set_boolean_function(*boolean_fun);
944 { // --- S t r i n g ---
945 Handle<JSFunction> string_fun =
946 InstallFunction(global, "String", JS_VALUE_TYPE, JSValue::kSize,
947 isolate->initial_object_prototype(),
948 Builtins::kIllegal, true, true);
949 string_fun->shared()->set_construct_stub(
950 isolate->builtins()->builtin(Builtins::kStringConstructCode));
951 native_context()->set_string_function(*string_fun);
953 Handle<Map> string_map =
954 Handle<Map>(native_context()->string_function()->initial_map());
955 Handle<DescriptorArray> string_descriptors(
956 factory->NewDescriptorArray(0, 1));
957 DescriptorArray::WhitenessWitness witness(*string_descriptors);
959 Handle<Foreign> string_length(
960 factory->NewForeign(&Accessors::StringLength));
961 PropertyAttributes attribs = static_cast<PropertyAttributes>(
962 DONT_ENUM | DONT_DELETE | READ_ONLY);
963 string_map->set_instance_descriptors(*string_descriptors);
966 CallbacksDescriptor d(*factory->length_string(), *string_length, attribs);
967 string_map->AppendDescriptor(&d, witness);
972 // Builtin functions for Date.prototype.
973 Handle<JSFunction> date_fun =
974 InstallFunction(global, "Date", JS_DATE_TYPE, JSDate::kSize,
975 isolate->initial_object_prototype(),
976 Builtins::kIllegal, true, true);
978 native_context()->set_date_function(*date_fun);
983 // Builtin functions for RegExp.prototype.
984 Handle<JSFunction> regexp_fun =
985 InstallFunction(global, "RegExp", JS_REGEXP_TYPE, JSRegExp::kSize,
986 isolate->initial_object_prototype(),
987 Builtins::kIllegal, true, true);
988 native_context()->set_regexp_function(*regexp_fun);
990 ASSERT(regexp_fun->has_initial_map());
991 Handle<Map> initial_map(regexp_fun->initial_map());
993 ASSERT_EQ(0, initial_map->inobject_properties());
995 PropertyAttributes final =
996 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
997 Handle<DescriptorArray> descriptors = factory->NewDescriptorArray(0, 5);
998 DescriptorArray::WhitenessWitness witness(*descriptors);
999 initial_map->set_instance_descriptors(*descriptors);
1002 // ECMA-262, section 15.10.7.1.
1003 FieldDescriptor field(heap->source_string(),
1004 JSRegExp::kSourceFieldIndex,
1006 Representation::Tagged());
1007 initial_map->AppendDescriptor(&field, witness);
1010 // ECMA-262, section 15.10.7.2.
1011 FieldDescriptor field(heap->global_string(),
1012 JSRegExp::kGlobalFieldIndex,
1014 Representation::Tagged());
1015 initial_map->AppendDescriptor(&field, witness);
1018 // ECMA-262, section 15.10.7.3.
1019 FieldDescriptor field(heap->ignore_case_string(),
1020 JSRegExp::kIgnoreCaseFieldIndex,
1022 Representation::Tagged());
1023 initial_map->AppendDescriptor(&field, witness);
1026 // ECMA-262, section 15.10.7.4.
1027 FieldDescriptor field(heap->multiline_string(),
1028 JSRegExp::kMultilineFieldIndex,
1030 Representation::Tagged());
1031 initial_map->AppendDescriptor(&field, witness);
1034 // ECMA-262, section 15.10.7.5.
1035 PropertyAttributes writable =
1036 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
1037 FieldDescriptor field(heap->last_index_string(),
1038 JSRegExp::kLastIndexFieldIndex,
1040 Representation::Tagged());
1041 initial_map->AppendDescriptor(&field, witness);
1044 initial_map->set_inobject_properties(5);
1045 initial_map->set_pre_allocated_property_fields(5);
1046 initial_map->set_unused_property_fields(0);
1047 initial_map->set_instance_size(
1048 initial_map->instance_size() + 5 * kPointerSize);
1049 initial_map->set_visitor_id(StaticVisitorBase::GetVisitorId(*initial_map));
1051 // RegExp prototype object is itself a RegExp.
1052 Handle<Map> proto_map = factory->CopyMap(initial_map);
1053 proto_map->set_prototype(native_context()->initial_object_prototype());
1054 Handle<JSObject> proto = factory->NewJSObjectFromMap(proto_map);
1055 proto->InObjectPropertyAtPut(JSRegExp::kSourceFieldIndex,
1056 heap->query_colon_string());
1057 proto->InObjectPropertyAtPut(JSRegExp::kGlobalFieldIndex,
1058 heap->false_value());
1059 proto->InObjectPropertyAtPut(JSRegExp::kIgnoreCaseFieldIndex,
1060 heap->false_value());
1061 proto->InObjectPropertyAtPut(JSRegExp::kMultilineFieldIndex,
1062 heap->false_value());
1063 proto->InObjectPropertyAtPut(JSRegExp::kLastIndexFieldIndex,
1065 SKIP_WRITE_BARRIER); // It's a Smi.
1066 initial_map->set_prototype(*proto);
1067 factory->SetRegExpIrregexpData(Handle<JSRegExp>::cast(proto),
1068 JSRegExp::IRREGEXP, factory->empty_string(),
1069 JSRegExp::Flags(0), 0);
1073 Handle<String> name = factory->InternalizeUtf8String("JSON");
1074 Handle<JSFunction> cons = factory->NewFunction(name,
1075 factory->the_hole_value());
1076 JSFunction::SetInstancePrototype(cons,
1077 Handle<Object>(native_context()->initial_object_prototype(), isolate));
1078 cons->SetInstanceClassName(*name);
1079 Handle<JSObject> json_object = factory->NewJSObject(cons, TENURED);
1080 ASSERT(json_object->IsJSObject());
1081 CHECK_NOT_EMPTY_HANDLE(isolate,
1082 JSObject::SetLocalPropertyIgnoreAttributes(
1083 global, name, json_object, DONT_ENUM));
1084 native_context()->set_json_object(*json_object);
1087 { // -- A r r a y B u f f e r
1088 Handle<JSFunction> array_buffer_fun =
1090 global, "ArrayBuffer", JS_ARRAY_BUFFER_TYPE,
1091 JSArrayBuffer::kSizeWithInternalFields,
1092 isolate->initial_object_prototype(),
1093 Builtins::kIllegal, true, true);
1094 native_context()->set_array_buffer_fun(*array_buffer_fun);
1097 { // -- T y p e d A r r a y s
1098 #define INSTALL_TYPED_ARRAY(Type, type, TYPE, ctype, size) \
1100 Handle<JSFunction> fun = InstallTypedArray(#Type "Array", \
1101 EXTERNAL_##TYPE##_ELEMENTS); \
1102 native_context()->set_##type##_array_fun(*fun); \
1104 BUILTIN_TYPED_ARRAY(INSTALL_TYPED_ARRAY)
1105 #undef INSTALL_TYPED_ARRAY
1107 Handle<JSFunction> data_view_fun =
1109 global, "DataView", JS_DATA_VIEW_TYPE,
1110 JSDataView::kSizeWithInternalFields,
1111 isolate->initial_object_prototype(),
1112 Builtins::kIllegal, true, true);
1113 native_context()->set_data_view_fun(*data_view_fun);
1116 { // --- arguments_boilerplate_
1117 // Make sure we can recognize argument objects at runtime.
1118 // This is done by introducing an anonymous function with
1119 // class_name equals 'Arguments'.
1120 Handle<String> arguments_string = factory->InternalizeOneByteString(
1121 STATIC_ASCII_VECTOR("Arguments"));
1122 Handle<Code> code = Handle<Code>(
1123 isolate->builtins()->builtin(Builtins::kIllegal));
1124 Handle<JSObject> prototype =
1126 JSObject::cast(native_context()->object_function()->prototype()));
1128 Handle<JSFunction> function =
1129 factory->NewFunctionWithPrototype(arguments_string,
1131 JSObject::kHeaderSize,
1135 ASSERT(!function->has_initial_map());
1136 function->shared()->set_instance_class_name(*arguments_string);
1137 function->shared()->set_expected_nof_properties(2);
1138 Handle<JSObject> result = factory->NewJSObject(function);
1140 native_context()->set_arguments_boilerplate(*result);
1141 // Note: length must be added as the first property and
1142 // callee must be added as the second property.
1143 CHECK_NOT_EMPTY_HANDLE(isolate,
1144 JSObject::SetLocalPropertyIgnoreAttributes(
1145 result, factory->length_string(),
1146 factory->undefined_value(), DONT_ENUM,
1147 Object::FORCE_TAGGED, FORCE_FIELD));
1148 CHECK_NOT_EMPTY_HANDLE(isolate,
1149 JSObject::SetLocalPropertyIgnoreAttributes(
1150 result, factory->callee_string(),
1151 factory->undefined_value(), DONT_ENUM,
1152 Object::FORCE_TAGGED, FORCE_FIELD));
1155 LookupResult lookup(isolate);
1156 result->LocalLookup(heap->callee_string(), &lookup);
1157 ASSERT(lookup.IsField());
1158 ASSERT(lookup.GetFieldIndex().field_index() == Heap::kArgumentsCalleeIndex);
1160 result->LocalLookup(heap->length_string(), &lookup);
1161 ASSERT(lookup.IsField());
1162 ASSERT(lookup.GetFieldIndex().field_index() == Heap::kArgumentsLengthIndex);
1164 ASSERT(result->map()->inobject_properties() > Heap::kArgumentsCalleeIndex);
1165 ASSERT(result->map()->inobject_properties() > Heap::kArgumentsLengthIndex);
1167 // Check the state of the object.
1168 ASSERT(result->HasFastProperties());
1169 ASSERT(result->HasFastObjectElements());
1173 { // --- aliased_arguments_boilerplate_
1174 // Set up a well-formed parameter map to make assertions happy.
1175 Handle<FixedArray> elements = factory->NewFixedArray(2);
1176 elements->set_map(heap->non_strict_arguments_elements_map());
1177 Handle<FixedArray> array;
1178 array = factory->NewFixedArray(0);
1179 elements->set(0, *array);
1180 array = factory->NewFixedArray(0);
1181 elements->set(1, *array);
1183 Handle<Map> old_map(native_context()->arguments_boilerplate()->map());
1184 Handle<Map> new_map = factory->CopyMap(old_map);
1185 new_map->set_pre_allocated_property_fields(2);
1186 Handle<JSObject> result = factory->NewJSObjectFromMap(new_map);
1187 // Set elements kind after allocating the object because
1188 // NewJSObjectFromMap assumes a fast elements map.
1189 new_map->set_elements_kind(NON_STRICT_ARGUMENTS_ELEMENTS);
1190 result->set_elements(*elements);
1191 ASSERT(result->HasNonStrictArgumentsElements());
1192 native_context()->set_aliased_arguments_boilerplate(*result);
1195 { // --- strict mode arguments boilerplate
1196 const PropertyAttributes attributes =
1197 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
1199 // Create the ThrowTypeError functions.
1200 Handle<AccessorPair> callee = factory->NewAccessorPair();
1201 Handle<AccessorPair> caller = factory->NewAccessorPair();
1203 Handle<JSFunction> throw_function =
1204 GetThrowTypeErrorFunction();
1206 // Install the ThrowTypeError functions.
1207 callee->set_getter(*throw_function);
1208 callee->set_setter(*throw_function);
1209 caller->set_getter(*throw_function);
1210 caller->set_setter(*throw_function);
1212 // Create the map. Allocate one in-object field for length.
1213 Handle<Map> map = factory->NewMap(JS_OBJECT_TYPE,
1214 Heap::kArgumentsObjectSizeStrict);
1215 // Create the descriptor array for the arguments object.
1216 Handle<DescriptorArray> descriptors = factory->NewDescriptorArray(0, 3);
1217 DescriptorArray::WhitenessWitness witness(*descriptors);
1218 map->set_instance_descriptors(*descriptors);
1222 *factory->length_string(), 0, DONT_ENUM, Representation::Tagged());
1223 map->AppendDescriptor(&d, witness);
1226 CallbacksDescriptor d(*factory->callee_string(),
1229 map->AppendDescriptor(&d, witness);
1232 CallbacksDescriptor d(*factory->caller_string(),
1235 map->AppendDescriptor(&d, witness);
1238 map->set_function_with_prototype(true);
1239 map->set_prototype(native_context()->object_function()->prototype());
1240 map->set_pre_allocated_property_fields(1);
1241 map->set_inobject_properties(1);
1243 // Copy constructor from the non-strict arguments boilerplate.
1244 map->set_constructor(
1245 native_context()->arguments_boilerplate()->map()->constructor());
1247 // Allocate the arguments boilerplate object.
1248 Handle<JSObject> result = factory->NewJSObjectFromMap(map);
1249 native_context()->set_strict_mode_arguments_boilerplate(*result);
1251 // Add length property only for strict mode boilerplate.
1252 CHECK_NOT_EMPTY_HANDLE(isolate,
1253 JSObject::SetLocalPropertyIgnoreAttributes(
1254 result, factory->length_string(),
1255 factory->undefined_value(), DONT_ENUM));
1258 LookupResult lookup(isolate);
1259 result->LocalLookup(heap->length_string(), &lookup);
1260 ASSERT(lookup.IsField());
1261 ASSERT(lookup.GetFieldIndex().field_index() == Heap::kArgumentsLengthIndex);
1263 ASSERT(result->map()->inobject_properties() > Heap::kArgumentsLengthIndex);
1265 // Check the state of the object.
1266 ASSERT(result->HasFastProperties());
1267 ASSERT(result->HasFastObjectElements());
1271 { // --- context extension
1272 // Create a function for the context extension objects.
1273 Handle<Code> code = Handle<Code>(
1274 isolate->builtins()->builtin(Builtins::kIllegal));
1275 Handle<JSFunction> context_extension_fun =
1276 factory->NewFunction(factory->empty_string(),
1277 JS_CONTEXT_EXTENSION_OBJECT_TYPE,
1278 JSObject::kHeaderSize,
1282 Handle<String> name = factory->InternalizeOneByteString(
1283 STATIC_ASCII_VECTOR("context_extension"));
1284 context_extension_fun->shared()->set_instance_class_name(*name);
1285 native_context()->set_context_extension_function(*context_extension_fun);
1290 // Set up the call-as-function delegate.
1292 Handle<Code>(isolate->builtins()->builtin(
1293 Builtins::kHandleApiCallAsFunction));
1294 Handle<JSFunction> delegate =
1295 factory->NewFunction(factory->empty_string(), JS_OBJECT_TYPE,
1296 JSObject::kHeaderSize, code, true);
1297 native_context()->set_call_as_function_delegate(*delegate);
1298 delegate->shared()->DontAdaptArguments();
1302 // Set up the call-as-constructor delegate.
1304 Handle<Code>(isolate->builtins()->builtin(
1305 Builtins::kHandleApiCallAsConstructor));
1306 Handle<JSFunction> delegate =
1307 factory->NewFunction(factory->empty_string(), JS_OBJECT_TYPE,
1308 JSObject::kHeaderSize, code, true);
1309 native_context()->set_call_as_constructor_delegate(*delegate);
1310 delegate->shared()->DontAdaptArguments();
1313 // Initialize the out of memory slot.
1314 native_context()->set_out_of_memory(heap->false_value());
1316 // Initialize the embedder data slot.
1317 Handle<FixedArray> embedder_data = factory->NewFixedArray(3);
1318 native_context()->set_embedder_data(*embedder_data);
1322 Handle<JSFunction> Genesis::InstallTypedArray(
1323 const char* name, ElementsKind elementsKind) {
1324 Handle<JSObject> global = Handle<JSObject>(native_context()->global_object());
1325 Handle<JSFunction> result = InstallFunction(global, name, JS_TYPED_ARRAY_TYPE,
1326 JSTypedArray::kSize, isolate()->initial_object_prototype(),
1327 Builtins::kIllegal, false, true);
1329 Handle<Map> initial_map = isolate()->factory()->NewMap(
1330 JS_TYPED_ARRAY_TYPE, JSTypedArray::kSizeWithInternalFields, elementsKind);
1331 result->set_initial_map(*initial_map);
1332 initial_map->set_constructor(*result);
1337 void Genesis::InitializeExperimentalGlobal() {
1338 Handle<JSObject> global = Handle<JSObject>(native_context()->global_object());
1340 // TODO(mstarzinger): Move this into Genesis::InitializeGlobal once we no
1341 // longer need to live behind flags, so functions get added to the snapshot.
1343 if (FLAG_harmony_symbols) {
1344 // --- S y m b o l ---
1345 Handle<JSFunction> symbol_fun =
1346 InstallFunction(global, "Symbol", JS_VALUE_TYPE, JSValue::kSize,
1347 isolate()->initial_object_prototype(),
1348 Builtins::kIllegal, true, true);
1349 native_context()->set_symbol_function(*symbol_fun);
1352 if (FLAG_harmony_collections) {
1354 InstallFunction(global, "Set", JS_SET_TYPE, JSSet::kSize,
1355 isolate()->initial_object_prototype(),
1356 Builtins::kIllegal, true, true);
1359 InstallFunction(global, "Map", JS_MAP_TYPE, JSMap::kSize,
1360 isolate()->initial_object_prototype(),
1361 Builtins::kIllegal, true, true);
1363 { // -- W e a k M a p
1364 InstallFunction(global, "WeakMap", JS_WEAK_MAP_TYPE, JSWeakMap::kSize,
1365 isolate()->initial_object_prototype(),
1366 Builtins::kIllegal, true, true);
1368 { // -- W e a k S e t
1369 InstallFunction(global, "WeakSet", JS_WEAK_SET_TYPE, JSWeakSet::kSize,
1370 isolate()->initial_object_prototype(),
1371 Builtins::kIllegal, true, true);
1375 if (FLAG_harmony_generators) {
1376 // Create generator meta-objects and install them on the builtins object.
1377 Handle<JSObject> builtins(native_context()->builtins());
1378 Handle<JSObject> generator_object_prototype =
1379 factory()->NewJSObject(isolate()->object_function(), TENURED);
1380 Handle<JSFunction> generator_function_prototype =
1381 InstallFunction(builtins, "GeneratorFunctionPrototype",
1382 JS_FUNCTION_TYPE, JSFunction::kHeaderSize,
1383 generator_object_prototype, Builtins::kIllegal,
1385 InstallFunction(builtins, "GeneratorFunction",
1386 JS_FUNCTION_TYPE, JSFunction::kSize,
1387 generator_function_prototype, Builtins::kIllegal,
1390 // Create maps for generator functions and their prototypes. Store those
1391 // maps in the native context.
1392 Handle<Map> function_map(native_context()->function_map());
1393 Handle<Map> generator_function_map = factory()->CopyMap(function_map);
1394 generator_function_map->set_prototype(*generator_function_prototype);
1395 native_context()->set_generator_function_map(*generator_function_map);
1397 Handle<Map> strict_mode_function_map(
1398 native_context()->strict_mode_function_map());
1399 Handle<Map> strict_mode_generator_function_map = factory()->CopyMap(
1400 strict_mode_function_map);
1401 strict_mode_generator_function_map->set_prototype(
1402 *generator_function_prototype);
1403 native_context()->set_strict_mode_generator_function_map(
1404 *strict_mode_generator_function_map);
1406 Handle<Map> object_map(native_context()->object_function()->initial_map());
1407 Handle<Map> generator_object_prototype_map = factory()->CopyMap(
1409 generator_object_prototype_map->set_prototype(
1410 *generator_object_prototype);
1411 native_context()->set_generator_object_prototype_map(
1412 *generator_object_prototype_map);
1414 // Create a map for generator result objects.
1415 ASSERT(object_map->inobject_properties() == 0);
1416 STATIC_ASSERT(JSGeneratorObject::kResultPropertyCount == 2);
1417 Handle<Map> generator_result_map = factory()->CopyMap(object_map,
1418 JSGeneratorObject::kResultPropertyCount);
1419 ASSERT(generator_result_map->inobject_properties() ==
1420 JSGeneratorObject::kResultPropertyCount);
1422 Handle<DescriptorArray> descriptors = factory()->NewDescriptorArray(0,
1423 JSGeneratorObject::kResultPropertyCount);
1424 DescriptorArray::WhitenessWitness witness(*descriptors);
1425 generator_result_map->set_instance_descriptors(*descriptors);
1427 Handle<String> value_string = factory()->InternalizeOneByteString(
1428 STATIC_ASCII_VECTOR("value"));
1429 FieldDescriptor value_descr(*value_string,
1430 JSGeneratorObject::kResultValuePropertyIndex,
1432 Representation::Tagged());
1433 generator_result_map->AppendDescriptor(&value_descr, witness);
1435 Handle<String> done_string = factory()->InternalizeOneByteString(
1436 STATIC_ASCII_VECTOR("done"));
1437 FieldDescriptor done_descr(*done_string,
1438 JSGeneratorObject::kResultDonePropertyIndex,
1440 Representation::Tagged());
1441 generator_result_map->AppendDescriptor(&done_descr, witness);
1443 generator_result_map->set_unused_property_fields(0);
1444 ASSERT_EQ(JSGeneratorObject::kResultSize,
1445 generator_result_map->instance_size());
1446 native_context()->set_generator_result_map(*generator_result_map);
1449 if (FLAG_simd_object) {
1451 Handle<String> name = factory()->InternalizeUtf8String("SIMD");
1452 Handle<JSFunction> cons =
1453 factory()->NewFunction(name, factory()->the_hole_value());
1454 JSFunction::SetInstancePrototype(cons,
1455 Handle<Object>(native_context()->initial_object_prototype(),
1457 cons->SetInstanceClassName(*name);
1458 Handle<JSObject> simd_object = factory()->NewJSObject(cons, TENURED);
1459 ASSERT(simd_object->IsJSObject());
1460 CHECK_NOT_EMPTY_HANDLE(isolate(),
1461 JSObject::SetLocalPropertyIgnoreAttributes(
1462 global, name, simd_object, DONT_ENUM));
1463 native_context()->set_simd_object(*simd_object);
1464 // --- f l o a t 3 2 x 4 ---
1465 Handle<JSFunction> float32x4_fun =
1466 InstallFunction(simd_object, "float32x4", JS_VALUE_TYPE, JSValue::kSize,
1467 isolate()->initial_object_prototype(),
1468 Builtins::kIllegal, true, true);
1469 native_context()->set_float32x4_function(*float32x4_fun);
1471 // --- i n t 3 2 x 4 ---
1472 Handle<JSFunction> int32x4_fun =
1473 InstallFunction(simd_object, "int32x4", JS_VALUE_TYPE, JSValue::kSize,
1474 isolate()->initial_object_prototype(),
1475 Builtins::kIllegal, true, true);
1476 native_context()->set_int32x4_function(*int32x4_fun);
1478 // --- F l o a t 3 2 x 4 A r r a y---
1479 Handle<JSFunction> float32x4_array_fun = InstallTypedArray("Float32x4Array",
1480 EXTERNAL_FLOAT32x4_ELEMENTS);
1481 native_context()->set_float32x4_array_fun(*float32x4_array_fun);
1483 // --- I n t 3 2 x 4 A r r a y---
1484 Handle<JSFunction> int32x4_array_fun = InstallTypedArray("Int32x4Array",
1485 EXTERNAL_INT32x4_ELEMENTS);
1486 native_context()->set_int32x4_array_fun(*int32x4_array_fun);
1491 bool Genesis::CompileBuiltin(Isolate* isolate, int index) {
1492 Vector<const char> name = Natives::GetScriptName(index);
1493 Handle<String> source_code =
1494 isolate->bootstrapper()->NativesSourceLookup(index);
1495 return CompileNative(isolate, name, source_code);
1499 bool Genesis::CompileExperimentalBuiltin(Isolate* isolate, int index) {
1500 Vector<const char> name = ExperimentalNatives::GetScriptName(index);
1501 Factory* factory = isolate->factory();
1502 Handle<String> source_code =
1503 factory->NewStringFromAscii(
1504 ExperimentalNatives::GetRawScriptSource(index));
1505 return CompileNative(isolate, name, source_code);
1509 bool Genesis::CompileNative(Isolate* isolate,
1510 Vector<const char> name,
1511 Handle<String> source) {
1512 HandleScope scope(isolate);
1513 #ifdef ENABLE_DEBUGGER_SUPPORT
1514 isolate->debugger()->set_compiling_natives(true);
1516 // During genesis, the boilerplate for stack overflow won't work until the
1517 // environment has been at least partially initialized. Add a stack check
1518 // before entering JS code to catch overflow early.
1519 StackLimitCheck check(isolate);
1520 if (check.HasOverflowed()) return false;
1522 bool result = CompileScriptCached(isolate,
1527 Handle<Context>(isolate->context()),
1529 ASSERT(isolate->has_pending_exception() != result);
1530 if (!result) isolate->clear_pending_exception();
1531 #ifdef ENABLE_DEBUGGER_SUPPORT
1532 isolate->debugger()->set_compiling_natives(false);
1538 bool Genesis::CompileScriptCached(Isolate* isolate,
1539 Vector<const char> name,
1540 Handle<String> source,
1541 SourceCodeCache* cache,
1542 v8::Extension* extension,
1543 Handle<Context> top_context,
1544 bool use_runtime_context) {
1545 Factory* factory = isolate->factory();
1546 HandleScope scope(isolate);
1547 Handle<SharedFunctionInfo> function_info;
1549 // If we can't find the function in the cache, we compile a new
1550 // function and insert it into the cache.
1551 if (cache == NULL || !cache->Lookup(name, &function_info)) {
1552 ASSERT(source->IsOneByteRepresentation());
1553 Handle<String> script_name = factory->NewStringFromUtf8(name);
1554 function_info = Compiler::CompileScript(
1563 Handle<String>::null(),
1564 use_runtime_context ? NATIVES_CODE : NOT_NATIVES_CODE);
1565 if (function_info.is_null()) return false;
1566 if (cache != NULL) cache->Add(name, function_info);
1569 // Set up the function context. Conceptually, we should clone the
1570 // function before overwriting the context but since we're in a
1571 // single-threaded environment it is not strictly necessary.
1572 ASSERT(top_context->IsNativeContext());
1573 Handle<Context> context =
1574 Handle<Context>(use_runtime_context
1575 ? Handle<Context>(top_context->runtime_context())
1577 Handle<JSFunction> fun =
1578 factory->NewFunctionFromSharedFunctionInfo(function_info, context);
1580 // Call function using either the runtime object or the global
1581 // object as the receiver. Provide no parameters.
1582 Handle<Object> receiver =
1583 Handle<Object>(use_runtime_context
1584 ? top_context->builtins()
1585 : top_context->global_object(),
1587 bool has_pending_exception;
1588 Execution::Call(isolate, fun, receiver, 0, NULL, &has_pending_exception);
1589 if (has_pending_exception) return false;
1594 #define INSTALL_NATIVE(Type, name, var) \
1595 Handle<String> var##_name = \
1596 factory()->InternalizeOneByteString(STATIC_ASCII_VECTOR(name)); \
1597 Object* var##_native = \
1598 native_context()->builtins()->GetPropertyNoExceptionThrown( \
1600 native_context()->set_##var(Type::cast(var##_native));
1603 void Genesis::InstallNativeFunctions() {
1604 HandleScope scope(isolate());
1605 INSTALL_NATIVE(JSFunction, "CreateDate", create_date_fun);
1606 INSTALL_NATIVE(JSFunction, "ToNumber", to_number_fun);
1607 INSTALL_NATIVE(JSFunction, "ToString", to_string_fun);
1608 INSTALL_NATIVE(JSFunction, "ToDetailString", to_detail_string_fun);
1609 INSTALL_NATIVE(JSFunction, "ToObject", to_object_fun);
1610 INSTALL_NATIVE(JSFunction, "ToInteger", to_integer_fun);
1611 INSTALL_NATIVE(JSFunction, "ToUint32", to_uint32_fun);
1612 INSTALL_NATIVE(JSFunction, "ToInt32", to_int32_fun);
1613 INSTALL_NATIVE(JSFunction, "GlobalEval", global_eval_fun);
1614 INSTALL_NATIVE(JSFunction, "Instantiate", instantiate_fun);
1615 INSTALL_NATIVE(JSFunction, "ConfigureTemplateInstance",
1616 configure_instance_fun);
1617 INSTALL_NATIVE(JSFunction, "GetStackTraceLine", get_stack_trace_line_fun);
1618 INSTALL_NATIVE(JSObject, "functionCache", function_cache);
1619 INSTALL_NATIVE(JSFunction, "ToCompletePropertyDescriptor",
1620 to_complete_property_descriptor);
1624 void Genesis::InstallExperimentalNativeFunctions() {
1625 INSTALL_NATIVE(JSFunction, "RunMicrotasks", run_microtasks);
1626 if (FLAG_harmony_proxies) {
1627 INSTALL_NATIVE(JSFunction, "DerivedHasTrap", derived_has_trap);
1628 INSTALL_NATIVE(JSFunction, "DerivedGetTrap", derived_get_trap);
1629 INSTALL_NATIVE(JSFunction, "DerivedSetTrap", derived_set_trap);
1630 INSTALL_NATIVE(JSFunction, "ProxyEnumerate", proxy_enumerate);
1632 if (FLAG_harmony_observation) {
1633 INSTALL_NATIVE(JSFunction, "NotifyChange", observers_notify_change);
1634 INSTALL_NATIVE(JSFunction, "EnqueueSpliceRecord", observers_enqueue_splice);
1635 INSTALL_NATIVE(JSFunction, "BeginPerformSplice",
1636 observers_begin_perform_splice);
1637 INSTALL_NATIVE(JSFunction, "EndPerformSplice",
1638 observers_end_perform_splice);
1642 #undef INSTALL_NATIVE
1645 Handle<JSFunction> Genesis::InstallInternalArray(
1646 Handle<JSBuiltinsObject> builtins,
1648 ElementsKind elements_kind) {
1649 // --- I n t e r n a l A r r a y ---
1650 // An array constructor on the builtins object that works like
1651 // the public Array constructor, except that its prototype
1652 // doesn't inherit from Object.prototype.
1653 // To be used only for internal work by builtins. Instances
1654 // must not be leaked to user code.
1655 Handle<JSFunction> array_function =
1656 InstallFunction(builtins,
1660 isolate()->initial_object_prototype(),
1661 Builtins::kInternalArrayCode,
1663 Handle<JSObject> prototype =
1664 factory()->NewJSObject(isolate()->object_function(), TENURED);
1665 Accessors::FunctionSetPrototype(array_function, prototype);
1667 InternalArrayConstructorStub internal_array_constructor_stub(isolate());
1668 Handle<Code> code = internal_array_constructor_stub.GetCode(isolate());
1669 array_function->shared()->set_construct_stub(*code);
1670 array_function->shared()->DontAdaptArguments();
1672 Handle<Map> original_map(array_function->initial_map());
1673 Handle<Map> initial_map = factory()->CopyMap(original_map);
1674 initial_map->set_elements_kind(elements_kind);
1675 array_function->set_initial_map(*initial_map);
1677 // Make "length" magic on instances.
1678 Handle<DescriptorArray> array_descriptors(
1679 factory()->NewDescriptorArray(0, 1));
1680 DescriptorArray::WhitenessWitness witness(*array_descriptors);
1682 Handle<Foreign> array_length(factory()->NewForeign(
1683 &Accessors::ArrayLength));
1684 PropertyAttributes attribs = static_cast<PropertyAttributes>(
1685 DONT_ENUM | DONT_DELETE);
1686 initial_map->set_instance_descriptors(*array_descriptors);
1689 CallbacksDescriptor d(
1690 *factory()->length_string(), *array_length, attribs);
1691 array_function->initial_map()->AppendDescriptor(&d, witness);
1694 return array_function;
1698 bool Genesis::InstallNatives() {
1699 HandleScope scope(isolate());
1701 // Create a function for the builtins object. Allocate space for the
1702 // JavaScript builtins, a reference to the builtins object
1703 // (itself) and a reference to the native_context directly in the object.
1704 Handle<Code> code = Handle<Code>(
1705 isolate()->builtins()->builtin(Builtins::kIllegal));
1706 Handle<JSFunction> builtins_fun =
1707 factory()->NewFunction(factory()->empty_string(),
1708 JS_BUILTINS_OBJECT_TYPE,
1709 JSBuiltinsObject::kSize, code, true);
1711 Handle<String> name =
1712 factory()->InternalizeOneByteString(STATIC_ASCII_VECTOR("builtins"));
1713 builtins_fun->shared()->set_instance_class_name(*name);
1714 builtins_fun->initial_map()->set_dictionary_map(true);
1715 builtins_fun->initial_map()->set_prototype(heap()->null_value());
1717 // Allocate the builtins object.
1718 Handle<JSBuiltinsObject> builtins =
1719 Handle<JSBuiltinsObject>::cast(factory()->NewGlobalObject(builtins_fun));
1720 builtins->set_builtins(*builtins);
1721 builtins->set_native_context(*native_context());
1722 builtins->set_global_context(*native_context());
1723 builtins->set_global_receiver(*builtins);
1724 builtins->set_global_receiver(native_context()->global_proxy());
1727 // Set up the 'global' properties of the builtins object. The
1728 // 'global' property that refers to the global object is the only
1729 // way to get from code running in the builtins context to the
1731 static const PropertyAttributes attributes =
1732 static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE);
1733 Handle<String> global_string =
1734 factory()->InternalizeOneByteString(STATIC_ASCII_VECTOR("global"));
1735 Handle<Object> global_obj(native_context()->global_object(), isolate());
1736 CHECK_NOT_EMPTY_HANDLE(isolate(),
1737 JSObject::SetLocalPropertyIgnoreAttributes(
1738 builtins, global_string, global_obj, attributes));
1739 Handle<String> builtins_string =
1740 factory()->InternalizeOneByteString(STATIC_ASCII_VECTOR("builtins"));
1741 CHECK_NOT_EMPTY_HANDLE(isolate(),
1742 JSObject::SetLocalPropertyIgnoreAttributes(
1743 builtins, builtins_string, builtins, attributes));
1745 // Set up the reference from the global object to the builtins object.
1746 JSGlobalObject::cast(native_context()->global_object())->
1747 set_builtins(*builtins);
1749 // Create a bridge function that has context in the native context.
1750 Handle<JSFunction> bridge =
1751 factory()->NewFunction(factory()->empty_string(),
1752 factory()->undefined_value());
1753 ASSERT(bridge->context() == *isolate()->native_context());
1755 // Allocate the builtins context.
1756 Handle<Context> context =
1757 factory()->NewFunctionContext(Context::MIN_CONTEXT_SLOTS, bridge);
1758 context->set_global_object(*builtins); // override builtins global object
1760 native_context()->set_runtime_context(*context);
1763 // Builtin functions for Script.
1764 Handle<JSFunction> script_fun =
1765 InstallFunction(builtins, "Script", JS_VALUE_TYPE, JSValue::kSize,
1766 isolate()->initial_object_prototype(),
1767 Builtins::kIllegal, false, false);
1768 Handle<JSObject> prototype =
1769 factory()->NewJSObject(isolate()->object_function(), TENURED);
1770 Accessors::FunctionSetPrototype(script_fun, prototype);
1771 native_context()->set_script_function(*script_fun);
1773 Handle<Map> script_map = Handle<Map>(script_fun->initial_map());
1775 Handle<DescriptorArray> script_descriptors(
1776 factory()->NewDescriptorArray(0, 13));
1777 DescriptorArray::WhitenessWitness witness(*script_descriptors);
1779 Handle<Foreign> script_source(
1780 factory()->NewForeign(&Accessors::ScriptSource));
1781 Handle<Foreign> script_name(factory()->NewForeign(&Accessors::ScriptName));
1782 Handle<String> id_string(factory()->InternalizeOneByteString(
1783 STATIC_ASCII_VECTOR("id")));
1784 Handle<Foreign> script_id(factory()->NewForeign(&Accessors::ScriptId));
1785 Handle<String> line_offset_string(
1786 factory()->InternalizeOneByteString(
1787 STATIC_ASCII_VECTOR("line_offset")));
1788 Handle<Foreign> script_line_offset(
1789 factory()->NewForeign(&Accessors::ScriptLineOffset));
1790 Handle<String> column_offset_string(
1791 factory()->InternalizeOneByteString(
1792 STATIC_ASCII_VECTOR("column_offset")));
1793 Handle<Foreign> script_column_offset(
1794 factory()->NewForeign(&Accessors::ScriptColumnOffset));
1795 Handle<String> data_string(factory()->InternalizeOneByteString(
1796 STATIC_ASCII_VECTOR("data")));
1797 Handle<Foreign> script_data(factory()->NewForeign(&Accessors::ScriptData));
1798 Handle<String> type_string(factory()->InternalizeOneByteString(
1799 STATIC_ASCII_VECTOR("type")));
1800 Handle<Foreign> script_type(factory()->NewForeign(&Accessors::ScriptType));
1801 Handle<String> compilation_type_string(
1802 factory()->InternalizeOneByteString(
1803 STATIC_ASCII_VECTOR("compilation_type")));
1804 Handle<Foreign> script_compilation_type(
1805 factory()->NewForeign(&Accessors::ScriptCompilationType));
1806 Handle<String> line_ends_string(factory()->InternalizeOneByteString(
1807 STATIC_ASCII_VECTOR("line_ends")));
1808 Handle<Foreign> script_line_ends(
1809 factory()->NewForeign(&Accessors::ScriptLineEnds));
1810 Handle<String> context_data_string(
1811 factory()->InternalizeOneByteString(
1812 STATIC_ASCII_VECTOR("context_data")));
1813 Handle<Foreign> script_context_data(
1814 factory()->NewForeign(&Accessors::ScriptContextData));
1815 Handle<String> eval_from_script_string(
1816 factory()->InternalizeOneByteString(
1817 STATIC_ASCII_VECTOR("eval_from_script")));
1818 Handle<Foreign> script_eval_from_script(
1819 factory()->NewForeign(&Accessors::ScriptEvalFromScript));
1820 Handle<String> eval_from_script_position_string(
1821 factory()->InternalizeOneByteString(
1822 STATIC_ASCII_VECTOR("eval_from_script_position")));
1823 Handle<Foreign> script_eval_from_script_position(
1824 factory()->NewForeign(&Accessors::ScriptEvalFromScriptPosition));
1825 Handle<String> eval_from_function_name_string(
1826 factory()->InternalizeOneByteString(
1827 STATIC_ASCII_VECTOR("eval_from_function_name")));
1828 Handle<Foreign> script_eval_from_function_name(
1829 factory()->NewForeign(&Accessors::ScriptEvalFromFunctionName));
1830 PropertyAttributes attribs =
1831 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
1832 script_map->set_instance_descriptors(*script_descriptors);
1835 CallbacksDescriptor d(
1836 *factory()->source_string(), *script_source, attribs);
1837 script_map->AppendDescriptor(&d, witness);
1841 CallbacksDescriptor d(*factory()->name_string(), *script_name, attribs);
1842 script_map->AppendDescriptor(&d, witness);
1846 CallbacksDescriptor d(*id_string, *script_id, attribs);
1847 script_map->AppendDescriptor(&d, witness);
1851 CallbacksDescriptor d(*line_offset_string, *script_line_offset, attribs);
1852 script_map->AppendDescriptor(&d, witness);
1856 CallbacksDescriptor d(
1857 *column_offset_string, *script_column_offset, attribs);
1858 script_map->AppendDescriptor(&d, witness);
1862 CallbacksDescriptor d(*data_string, *script_data, attribs);
1863 script_map->AppendDescriptor(&d, witness);
1867 CallbacksDescriptor d(*type_string, *script_type, attribs);
1868 script_map->AppendDescriptor(&d, witness);
1872 CallbacksDescriptor d(
1873 *compilation_type_string, *script_compilation_type, attribs);
1874 script_map->AppendDescriptor(&d, witness);
1878 CallbacksDescriptor d(*line_ends_string, *script_line_ends, attribs);
1879 script_map->AppendDescriptor(&d, witness);
1883 CallbacksDescriptor d(
1884 *context_data_string, *script_context_data, attribs);
1885 script_map->AppendDescriptor(&d, witness);
1889 CallbacksDescriptor d(
1890 *eval_from_script_string, *script_eval_from_script, attribs);
1891 script_map->AppendDescriptor(&d, witness);
1895 CallbacksDescriptor d(
1896 *eval_from_script_position_string,
1897 *script_eval_from_script_position,
1899 script_map->AppendDescriptor(&d, witness);
1903 CallbacksDescriptor d(
1904 *eval_from_function_name_string,
1905 *script_eval_from_function_name,
1907 script_map->AppendDescriptor(&d, witness);
1910 // Allocate the empty script.
1911 Handle<Script> script = factory()->NewScript(factory()->empty_string());
1912 script->set_type(Smi::FromInt(Script::TYPE_NATIVE));
1913 heap()->public_set_empty_script(*script);
1916 // Builtin function for OpaqueReference -- a JSValue-based object,
1917 // that keeps its field isolated from JavaScript code. It may store
1918 // objects, that JavaScript code may not access.
1919 Handle<JSFunction> opaque_reference_fun =
1920 InstallFunction(builtins, "OpaqueReference", JS_VALUE_TYPE,
1922 isolate()->initial_object_prototype(),
1923 Builtins::kIllegal, false, false);
1924 Handle<JSObject> prototype =
1925 factory()->NewJSObject(isolate()->object_function(), TENURED);
1926 Accessors::FunctionSetPrototype(opaque_reference_fun, prototype);
1927 native_context()->set_opaque_reference_function(*opaque_reference_fun);
1930 // InternalArrays should not use Smi-Only array optimizations. There are too
1931 // many places in the C++ runtime code (e.g. RegEx) that assume that
1932 // elements in InternalArrays can be set to non-Smi values without going
1933 // through a common bottleneck that would make the SMI_ONLY -> FAST_ELEMENT
1934 // transition easy to trap. Moreover, they rarely are smi-only.
1936 Handle<JSFunction> array_function =
1937 InstallInternalArray(builtins, "InternalArray", FAST_HOLEY_ELEMENTS);
1938 native_context()->set_internal_array_function(*array_function);
1942 InstallInternalArray(builtins, "InternalPackedArray", FAST_ELEMENTS);
1945 if (FLAG_disable_native_files) {
1946 PrintF("Warning: Running without installed natives!\n");
1951 for (int i = Natives::GetDebuggerCount();
1952 i < Natives::GetBuiltinsCount();
1954 if (!CompileBuiltin(isolate(), i)) return false;
1955 // TODO(ager): We really only need to install the JS builtin
1956 // functions on the builtins object after compiling and running
1958 if (!InstallJSBuiltins(builtins)) return false;
1961 InstallNativeFunctions();
1963 // Store the map for the string prototype after the natives has been compiled
1964 // and the String function has been set up.
1965 Handle<JSFunction> string_function(native_context()->string_function());
1966 ASSERT(JSObject::cast(
1967 string_function->initial_map()->prototype())->HasFastProperties());
1968 native_context()->set_string_function_prototype_map(
1969 HeapObject::cast(string_function->initial_map()->prototype())->map());
1971 // Install Function.prototype.call and apply.
1972 { Handle<String> key = factory()->function_class_string();
1973 Handle<JSFunction> function =
1974 Handle<JSFunction>::cast(
1975 GetProperty(isolate(), isolate()->global_object(), key));
1976 Handle<JSObject> proto =
1977 Handle<JSObject>(JSObject::cast(function->instance_prototype()));
1979 // Install the call and the apply functions.
1980 Handle<JSFunction> call =
1981 InstallFunction(proto, "call", JS_OBJECT_TYPE, JSObject::kHeaderSize,
1982 Handle<JSObject>::null(),
1983 Builtins::kFunctionCall,
1985 Handle<JSFunction> apply =
1986 InstallFunction(proto, "apply", JS_OBJECT_TYPE, JSObject::kHeaderSize,
1987 Handle<JSObject>::null(),
1988 Builtins::kFunctionApply,
1991 // Make sure that Function.prototype.call appears to be compiled.
1992 // The code will never be called, but inline caching for call will
1993 // only work if it appears to be compiled.
1994 call->shared()->DontAdaptArguments();
1995 ASSERT(call->is_compiled());
1997 // Set the expected parameters for apply to 2; required by builtin.
1998 apply->shared()->set_formal_parameter_count(2);
2000 // Set the lengths for the functions to satisfy ECMA-262.
2001 call->shared()->set_length(1);
2002 apply->shared()->set_length(2);
2005 InstallBuiltinFunctionIds();
2007 // Create a constructor for RegExp results (a variant of Array that
2008 // predefines the two properties index and match).
2010 // RegExpResult initial map.
2012 // Find global.Array.prototype to inherit from.
2013 Handle<JSFunction> array_constructor(native_context()->array_function());
2014 Handle<JSObject> array_prototype(
2015 JSObject::cast(array_constructor->instance_prototype()));
2018 Handle<Map> initial_map =
2019 factory()->NewMap(JS_ARRAY_TYPE, JSRegExpResult::kSize);
2020 initial_map->set_constructor(*array_constructor);
2022 // Set prototype on map.
2023 initial_map->set_non_instance_prototype(false);
2024 initial_map->set_prototype(*array_prototype);
2026 // Update map with length accessor from Array and add "index" and "input".
2027 Handle<DescriptorArray> reresult_descriptors =
2028 factory()->NewDescriptorArray(0, 3);
2029 DescriptorArray::WhitenessWitness witness(*reresult_descriptors);
2030 initial_map->set_instance_descriptors(*reresult_descriptors);
2033 JSFunction* array_function = native_context()->array_function();
2034 Handle<DescriptorArray> array_descriptors(
2035 array_function->initial_map()->instance_descriptors());
2036 String* length = heap()->length_string();
2037 int old = array_descriptors->SearchWithCache(
2038 length, array_function->initial_map());
2039 ASSERT(old != DescriptorArray::kNotFound);
2040 CallbacksDescriptor desc(length,
2041 array_descriptors->GetValue(old),
2042 array_descriptors->GetDetails(old).attributes());
2043 initial_map->AppendDescriptor(&desc, witness);
2046 FieldDescriptor index_field(heap()->index_string(),
2047 JSRegExpResult::kIndexIndex,
2049 Representation::Tagged());
2050 initial_map->AppendDescriptor(&index_field, witness);
2054 FieldDescriptor input_field(heap()->input_string(),
2055 JSRegExpResult::kInputIndex,
2057 Representation::Tagged());
2058 initial_map->AppendDescriptor(&input_field, witness);
2061 initial_map->set_inobject_properties(2);
2062 initial_map->set_pre_allocated_property_fields(2);
2063 initial_map->set_unused_property_fields(0);
2065 native_context()->set_regexp_result_map(*initial_map);
2076 #define INSTALL_EXPERIMENTAL_NATIVE(i, flag, file) \
2077 if (FLAG_harmony_##flag && \
2078 strcmp(ExperimentalNatives::GetScriptName(i).start(), \
2079 "native " file) == 0) { \
2080 if (!CompileExperimentalBuiltin(isolate(), i)) return false; \
2084 bool Genesis::InstallExperimentalNatives() {
2085 for (int i = ExperimentalNatives::GetDebuggerCount();
2086 i < ExperimentalNatives::GetBuiltinsCount();
2088 INSTALL_EXPERIMENTAL_NATIVE(i, symbols, "symbol.js")
2089 INSTALL_EXPERIMENTAL_NATIVE(i, proxies, "proxy.js")
2090 INSTALL_EXPERIMENTAL_NATIVE(i, collections, "collection.js")
2091 INSTALL_EXPERIMENTAL_NATIVE(i, observation, "object-observe.js")
2092 INSTALL_EXPERIMENTAL_NATIVE(i, promises, "promise.js")
2093 INSTALL_EXPERIMENTAL_NATIVE(i, generators, "generator.js")
2094 INSTALL_EXPERIMENTAL_NATIVE(i, iteration, "array-iterator.js")
2095 INSTALL_EXPERIMENTAL_NATIVE(i, strings, "harmony-string.js")
2096 INSTALL_EXPERIMENTAL_NATIVE(i, arrays, "harmony-array.js")
2097 INSTALL_EXPERIMENTAL_NATIVE(i, maths, "harmony-math.js")
2098 if (FLAG_simd_object &&
2099 strcmp(ExperimentalNatives::GetScriptName(i).start(),
2100 "native simd128.js") == 0) {
2101 if (!CompileExperimentalBuiltin(isolate(), i)) return false;
2102 InstallExperimentalSIMDBuiltinFunctionIds();
2103 // Store the map for the float32x4 and int32x4 function prototype after
2104 // the float32x4 and int32x4 function has been set up.
2105 JSObject* float32x4_function_prototype = JSObject::cast(
2106 native_context()->float32x4_function()->instance_prototype());
2107 native_context()->set_float32x4_function_prototype_map(
2108 float32x4_function_prototype->map());
2109 JSObject* int32x4_function_prototype = JSObject::cast(
2110 native_context()->int32x4_function()->instance_prototype());
2111 native_context()->set_int32x4_function_prototype_map(
2112 int32x4_function_prototype->map());
2116 InstallExperimentalNativeFunctions();
2122 static Handle<JSObject> ResolveBuiltinIdHolder(
2123 Handle<Context> native_context,
2124 const char* holder_expr) {
2125 Isolate* isolate = native_context->GetIsolate();
2126 Factory* factory = isolate->factory();
2127 Handle<GlobalObject> global(native_context->global_object());
2128 const char* period_pos = strchr(holder_expr, '.');
2129 if (period_pos == NULL) {
2130 return Handle<JSObject>::cast(GetProperty(
2131 isolate, global, factory->InternalizeUtf8String(holder_expr)));
2133 ASSERT_EQ(".prototype", period_pos);
2134 Vector<const char> property(holder_expr,
2135 static_cast<int>(period_pos - holder_expr));
2136 Handle<JSFunction> function = Handle<JSFunction>::cast(
2137 GetProperty(isolate, global, factory->InternalizeUtf8String(property)));
2138 return Handle<JSObject>(JSObject::cast(function->prototype()));
2142 static Handle<JSObject> ResolveBuiltinSIMDIdHolder(
2143 Handle<Context> native_context,
2144 const char* holder_expr) {
2145 Isolate* isolate = native_context->GetIsolate();
2146 Factory* factory = isolate->factory();
2147 Handle<GlobalObject> global(native_context->global_object());
2148 Handle<Object> holder = global;
2149 char* name = const_cast<char*>(holder_expr);
2150 char* period_pos = strchr(name, '.');
2151 while (period_pos != NULL) {
2152 Vector<const char> property(name, static_cast<int>(period_pos - name));
2153 holder = GetProperty(isolate, holder,
2154 factory->InternalizeUtf8String(property));
2155 if (strcmp(".prototype", period_pos) == 0) {
2156 Handle<JSFunction> function = Handle<JSFunction>::cast(holder);
2157 return Handle<JSObject>(JSObject::cast(function->prototype()));
2159 name = period_pos + 1;
2160 period_pos = strchr(name, '.');
2164 return Handle<JSObject>::cast(GetProperty(
2165 isolate, holder, factory->InternalizeUtf8String(name)));
2169 static void InstallBuiltinFunctionId(Handle<JSObject> holder,
2170 const char* function_name,
2171 BuiltinFunctionId id) {
2172 Factory* factory = holder->GetIsolate()->factory();
2173 Handle<String> name = factory->InternalizeUtf8String(function_name);
2174 Object* function_object = holder->GetProperty(*name)->ToObjectUnchecked();
2175 Handle<JSFunction> function(JSFunction::cast(function_object));
2176 function->shared()->set_function_data(Smi::FromInt(id));
2180 void Genesis::InstallBuiltinFunctionIds() {
2181 HandleScope scope(isolate());
2182 #define INSTALL_BUILTIN_ID(holder_expr, fun_name, name) \
2184 Handle<JSObject> holder = ResolveBuiltinIdHolder( \
2185 native_context(), #holder_expr); \
2186 BuiltinFunctionId id = k##name; \
2187 InstallBuiltinFunctionId(holder, #fun_name, id); \
2189 FUNCTIONS_WITH_ID_LIST(INSTALL_BUILTIN_ID)
2190 #undef INSTALL_BUILTIN_ID
2194 void Genesis::InstallExperimentalSIMDBuiltinFunctionIds() {
2195 HandleScope scope(isolate());
2196 #define INSTALL_BUILTIN_ID(holder_expr, fun_name, name) \
2198 Handle<JSObject> holder = ResolveBuiltinSIMDIdHolder( \
2199 native_context(), #holder_expr); \
2200 BuiltinFunctionId id = k##name; \
2201 InstallBuiltinFunctionId(holder, #fun_name, id); \
2203 SIMD_ARRAY_OPERATIONS(INSTALL_BUILTIN_ID)
2204 #define INSTALL_SIMD_NULLARY_FUNCTION_ID(p1, p2, p3, p4) \
2205 INSTALL_BUILTIN_ID(p1, p2, p3)
2206 SIMD_NULLARY_OPERATIONS(INSTALL_SIMD_NULLARY_FUNCTION_ID)
2207 #undef INSTALL_SIMD_NULLARY_FUNCTION_ID
2208 #define INSTALL_SIMD_UNARY_FUNCTION_ID(p1, p2, p3, p4, p5) \
2209 INSTALL_BUILTIN_ID(p1, p2, p3)
2210 SIMD_UNARY_OPERATIONS(INSTALL_SIMD_UNARY_FUNCTION_ID)
2211 #undef INSTALL_SIMD_UNARY_FUNCTION_ID
2212 #define INSTALL_SIMD_BINARY_FUNCTION_ID(p1, p2, p3, p4, p5, p6) \
2213 INSTALL_BUILTIN_ID(p1, p2, p3)
2214 SIMD_BINARY_OPERATIONS(INSTALL_SIMD_BINARY_FUNCTION_ID)
2215 #undef INSTALL_SIMD_BINARY_FUNCTION_ID
2216 #define INSTALL_SIMD_TERNARY_FUNCTION_ID(p1, p2, p3, p4, p5, p6, p7) \
2217 INSTALL_BUILTIN_ID(p1, p2, p3)
2218 SIMD_TERNARY_OPERATIONS(INSTALL_SIMD_TERNARY_FUNCTION_ID)
2219 #undef INSTALL_SIMD_TERNARY_FUNCTION_ID
2220 #define INSTALL_SIMD_QUARTERNARY_FUNCTION_ID(p1, p2, p3, p4, p5, p6, p7, p8) \
2221 INSTALL_BUILTIN_ID(p1, p2, p3)
2222 SIMD_QUARTERNARY_OPERATIONS(INSTALL_SIMD_QUARTERNARY_FUNCTION_ID)
2223 #undef INSTALL_SIMD_QUARTERNARY_FUNCTION_ID
2224 #undef INSTALL_BUILTIN_ID
2228 // Do not forget to update macros.py with named constant
2230 #define JSFUNCTION_RESULT_CACHE_LIST(F) \
2231 F(16, native_context()->regexp_function())
2234 static FixedArray* CreateCache(int size, Handle<JSFunction> factory_function) {
2235 Factory* factory = factory_function->GetIsolate()->factory();
2236 // Caches are supposed to live for a long time, allocate in old space.
2237 int array_size = JSFunctionResultCache::kEntriesIndex + 2 * size;
2238 // Cannot use cast as object is not fully initialized yet.
2239 JSFunctionResultCache* cache = reinterpret_cast<JSFunctionResultCache*>(
2240 *factory->NewFixedArrayWithHoles(array_size, TENURED));
2241 cache->set(JSFunctionResultCache::kFactoryIndex, *factory_function);
2242 cache->MakeZeroSize();
2247 void Genesis::InstallJSFunctionResultCaches() {
2248 const int kNumberOfCaches = 0 +
2249 #define F(size, func) + 1
2250 JSFUNCTION_RESULT_CACHE_LIST(F)
2254 Handle<FixedArray> caches =
2255 factory()->NewFixedArray(kNumberOfCaches, TENURED);
2259 #define F(size, func) do { \
2260 FixedArray* cache = CreateCache((size), Handle<JSFunction>(func)); \
2261 caches->set(index++, cache); \
2264 JSFUNCTION_RESULT_CACHE_LIST(F);
2268 native_context()->set_jsfunction_result_caches(*caches);
2272 void Genesis::InitializeNormalizedMapCaches() {
2273 Handle<FixedArray> array(
2274 factory()->NewFixedArray(NormalizedMapCache::kEntries, TENURED));
2275 native_context()->set_normalized_map_cache(NormalizedMapCache::cast(*array));
2279 bool Bootstrapper::InstallExtensions(Handle<Context> native_context,
2280 v8::ExtensionConfiguration* extensions) {
2281 BootstrapperActive active(this);
2282 SaveContext saved_context(isolate_);
2283 isolate_->set_context(*native_context);
2284 return Genesis::InstallExtensions(native_context, extensions) &&
2285 Genesis::InstallSpecialObjects(native_context);
2289 bool Genesis::InstallSpecialObjects(Handle<Context> native_context) {
2290 Isolate* isolate = native_context->GetIsolate();
2291 Factory* factory = isolate->factory();
2292 HandleScope scope(isolate);
2293 Handle<JSGlobalObject> global(JSGlobalObject::cast(
2294 native_context->global_object()));
2295 // Expose the natives in global if a name for it is specified.
2296 if (FLAG_expose_natives_as != NULL && strlen(FLAG_expose_natives_as) != 0) {
2297 Handle<String> natives =
2298 factory->InternalizeUtf8String(FLAG_expose_natives_as);
2299 JSObject::SetLocalPropertyIgnoreAttributes(
2300 global, natives, Handle<JSObject>(global->builtins()), DONT_ENUM);
2301 if (isolate->has_pending_exception()) return false;
2304 Handle<Object> Error = GetProperty(global, "Error");
2305 if (Error->IsJSObject()) {
2306 Handle<String> name = factory->InternalizeOneByteString(
2307 STATIC_ASCII_VECTOR("stackTraceLimit"));
2308 Handle<Smi> stack_trace_limit(
2309 Smi::FromInt(FLAG_stack_trace_limit), isolate);
2310 JSObject::SetLocalPropertyIgnoreAttributes(
2311 Handle<JSObject>::cast(Error), name, stack_trace_limit, NONE);
2312 if (isolate->has_pending_exception()) return false;
2315 #ifdef ENABLE_DEBUGGER_SUPPORT
2316 // Expose the debug global object in global if a name for it is specified.
2317 if (FLAG_expose_debug_as != NULL && strlen(FLAG_expose_debug_as) != 0) {
2318 Debug* debug = isolate->debug();
2319 // If loading fails we just bail out without installing the
2320 // debugger but without tanking the whole context.
2321 if (!debug->Load()) return true;
2322 // Set the security token for the debugger context to the same as
2323 // the shell native context to allow calling between these (otherwise
2324 // exposing debug global object doesn't make much sense).
2325 debug->debug_context()->set_security_token(
2326 native_context->security_token());
2328 Handle<String> debug_string =
2329 factory->InternalizeUtf8String(FLAG_expose_debug_as);
2330 Handle<Object> global_proxy(
2331 debug->debug_context()->global_proxy(), isolate);
2332 JSObject::SetLocalPropertyIgnoreAttributes(
2333 global, debug_string, global_proxy, DONT_ENUM);
2334 if (isolate->has_pending_exception()) return false;
2341 static uint32_t Hash(RegisteredExtension* extension) {
2342 return v8::internal::ComputePointerHash(extension);
2346 static bool MatchRegisteredExtensions(void* key1, void* key2) {
2347 return key1 == key2;
2350 Genesis::ExtensionStates::ExtensionStates()
2351 : map_(MatchRegisteredExtensions, 8) { }
2353 Genesis::ExtensionTraversalState Genesis::ExtensionStates::get_state(
2354 RegisteredExtension* extension) {
2355 i::HashMap::Entry* entry = map_.Lookup(extension, Hash(extension), false);
2356 if (entry == NULL) {
2359 return static_cast<ExtensionTraversalState>(
2360 reinterpret_cast<intptr_t>(entry->value));
2363 void Genesis::ExtensionStates::set_state(RegisteredExtension* extension,
2364 ExtensionTraversalState state) {
2365 map_.Lookup(extension, Hash(extension), true)->value =
2366 reinterpret_cast<void*>(static_cast<intptr_t>(state));
2370 bool Genesis::InstallExtensions(Handle<Context> native_context,
2371 v8::ExtensionConfiguration* extensions) {
2372 Isolate* isolate = native_context->GetIsolate();
2373 ExtensionStates extension_states; // All extensions have state UNVISITED.
2374 return InstallAutoExtensions(isolate, &extension_states) &&
2375 (!FLAG_expose_free_buffer ||
2376 InstallExtension(isolate, "v8/free-buffer", &extension_states)) &&
2378 InstallExtension(isolate, "v8/gc", &extension_states)) &&
2379 (!FLAG_expose_externalize_string ||
2380 InstallExtension(isolate, "v8/externalize", &extension_states)) &&
2381 (!FLAG_track_gc_object_stats ||
2382 InstallExtension(isolate, "v8/statistics", &extension_states)) &&
2383 (!FLAG_expose_trigger_failure ||
2384 InstallExtension(isolate, "v8/trigger-failure", &extension_states)) &&
2385 InstallRequestedExtensions(isolate, extensions, &extension_states);
2389 bool Genesis::InstallAutoExtensions(Isolate* isolate,
2390 ExtensionStates* extension_states) {
2391 for (v8::RegisteredExtension* it = v8::RegisteredExtension::first_extension();
2394 if (it->extension()->auto_enable() &&
2395 !InstallExtension(isolate, it, extension_states)) {
2403 bool Genesis::InstallRequestedExtensions(Isolate* isolate,
2404 v8::ExtensionConfiguration* extensions,
2405 ExtensionStates* extension_states) {
2406 for (const char** it = extensions->begin(); it != extensions->end(); ++it) {
2407 if (!InstallExtension(isolate, *it, extension_states)) return false;
2413 // Installs a named extension. This methods is unoptimized and does
2414 // not scale well if we want to support a large number of extensions.
2415 bool Genesis::InstallExtension(Isolate* isolate,
2417 ExtensionStates* extension_states) {
2418 for (v8::RegisteredExtension* it = v8::RegisteredExtension::first_extension();
2421 if (strcmp(name, it->extension()->name()) == 0) {
2422 return InstallExtension(isolate, it, extension_states);
2425 return Utils::ApiCheck(false,
2426 "v8::Context::New()",
2427 "Cannot find required extension");
2431 bool Genesis::InstallExtension(Isolate* isolate,
2432 v8::RegisteredExtension* current,
2433 ExtensionStates* extension_states) {
2434 HandleScope scope(isolate);
2436 if (extension_states->get_state(current) == INSTALLED) return true;
2437 // The current node has already been visited so there must be a
2438 // cycle in the dependency graph; fail.
2439 if (!Utils::ApiCheck(extension_states->get_state(current) != VISITED,
2440 "v8::Context::New()",
2441 "Circular extension dependency")) {
2444 ASSERT(extension_states->get_state(current) == UNVISITED);
2445 extension_states->set_state(current, VISITED);
2446 v8::Extension* extension = current->extension();
2447 // Install the extension's dependencies
2448 for (int i = 0; i < extension->dependency_count(); i++) {
2449 if (!InstallExtension(isolate,
2450 extension->dependencies()[i],
2451 extension_states)) {
2455 Handle<String> source_code =
2456 isolate->factory()->NewExternalStringFromAscii(extension->source());
2457 bool result = CompileScriptCached(isolate,
2458 CStrVector(extension->name()),
2460 isolate->bootstrapper()->extensions_cache(),
2462 Handle<Context>(isolate->context()),
2464 ASSERT(isolate->has_pending_exception() != result);
2466 // We print out the name of the extension that fail to install.
2467 // When an error is thrown during bootstrapping we automatically print
2468 // the line number at which this happened to the console in the isolate
2469 // error throwing functionality.
2470 OS::PrintError("Error installing extension '%s'.\n",
2471 current->extension()->name());
2472 isolate->clear_pending_exception();
2474 extension_states->set_state(current, INSTALLED);
2475 isolate->NotifyExtensionInstalled();
2480 bool Genesis::InstallJSBuiltins(Handle<JSBuiltinsObject> builtins) {
2481 HandleScope scope(isolate());
2482 for (int i = 0; i < Builtins::NumberOfJavaScriptBuiltins(); i++) {
2483 Builtins::JavaScript id = static_cast<Builtins::JavaScript>(i);
2484 Handle<String> name =
2485 factory()->InternalizeUtf8String(Builtins::GetName(id));
2486 Object* function_object = builtins->GetPropertyNoExceptionThrown(*name);
2487 Handle<JSFunction> function
2488 = Handle<JSFunction>(JSFunction::cast(function_object));
2489 builtins->set_javascript_builtin(id, *function);
2490 if (!Compiler::EnsureCompiled(function, CLEAR_EXCEPTION)) {
2493 builtins->set_javascript_builtin_code(id, function->shared()->code());
2499 bool Genesis::ConfigureGlobalObjects(
2500 v8::Handle<v8::ObjectTemplate> global_proxy_template) {
2501 Handle<JSObject> global_proxy(
2502 JSObject::cast(native_context()->global_proxy()));
2503 Handle<JSObject> inner_global(
2504 JSObject::cast(native_context()->global_object()));
2506 if (!global_proxy_template.IsEmpty()) {
2507 // Configure the global proxy object.
2508 Handle<ObjectTemplateInfo> proxy_data =
2509 v8::Utils::OpenHandle(*global_proxy_template);
2510 if (!ConfigureApiObject(global_proxy, proxy_data)) return false;
2512 // Configure the inner global object.
2513 Handle<FunctionTemplateInfo> proxy_constructor(
2514 FunctionTemplateInfo::cast(proxy_data->constructor()));
2515 if (!proxy_constructor->prototype_template()->IsUndefined()) {
2516 Handle<ObjectTemplateInfo> inner_data(
2517 ObjectTemplateInfo::cast(proxy_constructor->prototype_template()));
2518 if (!ConfigureApiObject(inner_global, inner_data)) return false;
2522 SetObjectPrototype(global_proxy, inner_global);
2524 native_context()->set_initial_array_prototype(
2525 JSArray::cast(native_context()->array_function()->prototype()));
2531 bool Genesis::ConfigureApiObject(Handle<JSObject> object,
2532 Handle<ObjectTemplateInfo> object_template) {
2533 ASSERT(!object_template.is_null());
2534 ASSERT(FunctionTemplateInfo::cast(object_template->constructor())
2535 ->IsTemplateFor(object->map()));;
2537 bool pending_exception = false;
2538 Handle<JSObject> obj =
2539 Execution::InstantiateObject(object_template, &pending_exception);
2540 if (pending_exception) {
2541 ASSERT(isolate()->has_pending_exception());
2542 isolate()->clear_pending_exception();
2545 TransferObject(obj, object);
2550 void Genesis::TransferNamedProperties(Handle<JSObject> from,
2551 Handle<JSObject> to) {
2552 if (from->HasFastProperties()) {
2553 Handle<DescriptorArray> descs =
2554 Handle<DescriptorArray>(from->map()->instance_descriptors());
2555 for (int i = 0; i < from->map()->NumberOfOwnDescriptors(); i++) {
2556 PropertyDetails details = descs->GetDetails(i);
2557 switch (details.type()) {
2559 HandleScope inner(isolate());
2560 Handle<Name> key = Handle<Name>(descs->GetKey(i));
2561 int index = descs->GetFieldIndex(i);
2562 ASSERT(!descs->GetDetails(i).representation().IsDouble());
2563 Handle<Object> value = Handle<Object>(from->RawFastPropertyAt(index),
2565 CHECK_NOT_EMPTY_HANDLE(isolate(),
2566 JSObject::SetLocalPropertyIgnoreAttributes(
2567 to, key, value, details.attributes()));
2571 HandleScope inner(isolate());
2572 Handle<Name> key = Handle<Name>(descs->GetKey(i));
2573 Handle<Object> constant(descs->GetConstant(i), isolate());
2574 CHECK_NOT_EMPTY_HANDLE(isolate(),
2575 JSObject::SetLocalPropertyIgnoreAttributes(
2576 to, key, constant, details.attributes()));
2580 LookupResult result(isolate());
2581 to->LocalLookup(descs->GetKey(i), &result);
2582 // If the property is already there we skip it
2583 if (result.IsFound()) continue;
2584 HandleScope inner(isolate());
2585 ASSERT(!to->HasFastProperties());
2586 // Add to dictionary.
2587 Handle<Name> key = Handle<Name>(descs->GetKey(i));
2588 Handle<Object> callbacks(descs->GetCallbacksObject(i), isolate());
2589 PropertyDetails d = PropertyDetails(
2590 details.attributes(), CALLBACKS, i + 1);
2591 JSObject::SetNormalizedProperty(to, key, callbacks, d);
2595 // Do not occur since the from object has fast properties.
2600 // No element in instance descriptors have proxy or interceptor type.
2606 Handle<NameDictionary> properties =
2607 Handle<NameDictionary>(from->property_dictionary());
2608 int capacity = properties->Capacity();
2609 for (int i = 0; i < capacity; i++) {
2610 Object* raw_key(properties->KeyAt(i));
2611 if (properties->IsKey(raw_key)) {
2612 ASSERT(raw_key->IsName());
2613 // If the property is already there we skip it.
2614 LookupResult result(isolate());
2615 to->LocalLookup(Name::cast(raw_key), &result);
2616 if (result.IsFound()) continue;
2617 // Set the property.
2618 Handle<Name> key = Handle<Name>(Name::cast(raw_key));
2619 Handle<Object> value = Handle<Object>(properties->ValueAt(i),
2621 ASSERT(!value->IsCell());
2622 if (value->IsPropertyCell()) {
2623 value = Handle<Object>(PropertyCell::cast(*value)->value(),
2626 PropertyDetails details = properties->DetailsAt(i);
2627 CHECK_NOT_EMPTY_HANDLE(isolate(),
2628 JSObject::SetLocalPropertyIgnoreAttributes(
2629 to, key, value, details.attributes()));
2636 void Genesis::TransferIndexedProperties(Handle<JSObject> from,
2637 Handle<JSObject> to) {
2638 // Cloning the elements array is sufficient.
2639 Handle<FixedArray> from_elements =
2640 Handle<FixedArray>(FixedArray::cast(from->elements()));
2641 Handle<FixedArray> to_elements = factory()->CopyFixedArray(from_elements);
2642 to->set_elements(*to_elements);
2646 void Genesis::TransferObject(Handle<JSObject> from, Handle<JSObject> to) {
2647 HandleScope outer(isolate());
2649 ASSERT(!from->IsJSArray());
2650 ASSERT(!to->IsJSArray());
2652 TransferNamedProperties(from, to);
2653 TransferIndexedProperties(from, to);
2655 // Transfer the prototype (new map is needed).
2656 Handle<Map> old_to_map = Handle<Map>(to->map());
2657 Handle<Map> new_to_map = factory()->CopyMap(old_to_map);
2658 new_to_map->set_prototype(from->map()->prototype());
2659 to->set_map(*new_to_map);
2663 void Genesis::MakeFunctionInstancePrototypeWritable() {
2664 // The maps with writable prototype are created in CreateEmptyFunction
2665 // and CreateStrictModeFunctionMaps respectively. Initially the maps are
2666 // created with read-only prototype for JS builtins processing.
2667 ASSERT(!function_map_writable_prototype_.is_null());
2668 ASSERT(!strict_mode_function_map_writable_prototype_.is_null());
2670 // Replace function instance maps to make prototype writable.
2671 native_context()->set_function_map(*function_map_writable_prototype_);
2672 native_context()->set_strict_mode_function_map(
2673 *strict_mode_function_map_writable_prototype_);
2677 class NoTrackDoubleFieldsForSerializerScope {
2679 NoTrackDoubleFieldsForSerializerScope() : flag_(FLAG_track_double_fields) {
2680 if (Serializer::enabled()) {
2681 // Disable tracking double fields because heap numbers treated as
2682 // immutable by the serializer.
2683 FLAG_track_double_fields = false;
2686 ~NoTrackDoubleFieldsForSerializerScope() {
2687 FLAG_track_double_fields = flag_;
2695 Genesis::Genesis(Isolate* isolate,
2696 Handle<Object> global_object,
2697 v8::Handle<v8::ObjectTemplate> global_template,
2698 v8::ExtensionConfiguration* extensions)
2699 : isolate_(isolate),
2700 active_(isolate->bootstrapper()) {
2701 NoTrackDoubleFieldsForSerializerScope disable_double_tracking_for_serializer;
2702 result_ = Handle<Context>::null();
2703 // If V8 cannot be initialized, just return.
2704 if (!V8::Initialize(NULL)) return;
2706 // Before creating the roots we must save the context and restore it
2707 // on all function exits.
2708 SaveContext saved_context(isolate);
2710 // During genesis, the boilerplate for stack overflow won't work until the
2711 // environment has been at least partially initialized. Add a stack check
2712 // before entering JS code to catch overflow early.
2713 StackLimitCheck check(isolate);
2714 if (check.HasOverflowed()) return;
2716 // We can only de-serialize a context if the isolate was initialized from
2717 // a snapshot. Otherwise we have to build the context from scratch.
2718 if (isolate->initialized_from_snapshot()) {
2719 native_context_ = Snapshot::NewContextFromSnapshot(isolate);
2721 native_context_ = Handle<Context>();
2724 if (!native_context().is_null()) {
2725 AddToWeakNativeContextList(*native_context());
2726 isolate->set_context(*native_context());
2727 isolate->counters()->contexts_created_by_snapshot()->Increment();
2728 Handle<GlobalObject> inner_global;
2729 Handle<JSGlobalProxy> global_proxy =
2730 CreateNewGlobals(global_template,
2734 HookUpGlobalProxy(inner_global, global_proxy);
2735 HookUpInnerGlobal(inner_global);
2736 native_context()->builtins()->set_global_receiver(
2737 native_context()->global_proxy());
2739 if (!ConfigureGlobalObjects(global_template)) return;
2741 // We get here if there was no context snapshot.
2743 Handle<JSFunction> empty_function = CreateEmptyFunction(isolate);
2744 CreateStrictModeFunctionMaps(empty_function);
2745 Handle<GlobalObject> inner_global;
2746 Handle<JSGlobalProxy> global_proxy =
2747 CreateNewGlobals(global_template, global_object, &inner_global);
2748 HookUpGlobalProxy(inner_global, global_proxy);
2749 InitializeGlobal(inner_global, empty_function);
2750 InstallJSFunctionResultCaches();
2751 InitializeNormalizedMapCaches();
2752 if (!InstallNatives()) return;
2754 MakeFunctionInstancePrototypeWritable();
2756 if (!ConfigureGlobalObjects(global_template)) return;
2757 isolate->counters()->contexts_created_from_scratch()->Increment();
2760 // Initialize experimental globals and install experimental natives.
2761 InitializeExperimentalGlobal();
2762 if (!InstallExperimentalNatives()) return;
2764 // We can't (de-)serialize typed arrays currently, but we are lucky: The state
2765 // of the random number generator needs no initialization during snapshot
2766 // creation time and we don't need trigonometric functions then.
2767 if (!Serializer::enabled()) {
2768 // Initially seed the per-context random number generator using the
2769 // per-isolate random number generator.
2770 const int num_elems = 2;
2771 const int num_bytes = num_elems * sizeof(uint32_t);
2772 uint32_t* state = reinterpret_cast<uint32_t*>(malloc(num_bytes));
2775 isolate->random_number_generator()->NextBytes(state, num_bytes);
2776 } while (state[0] == 0 || state[1] == 0);
2778 v8::Local<v8::ArrayBuffer> buffer = v8::ArrayBuffer::New(
2779 reinterpret_cast<v8::Isolate*>(isolate), state, num_bytes);
2780 Utils::OpenHandle(*buffer)->set_should_be_freed(true);
2781 v8::Local<v8::Uint32Array> ta = v8::Uint32Array::New(buffer, 0, num_elems);
2782 Handle<JSBuiltinsObject> builtins(native_context()->builtins());
2783 ForceSetProperty(builtins,
2784 factory()->InternalizeOneByteString(
2785 STATIC_ASCII_VECTOR("rngstate")),
2786 Utils::OpenHandle(*ta),
2789 // Initialize trigonometric lookup tables and constants.
2790 const int table_num_bytes = TrigonometricLookupTable::table_num_bytes();
2791 v8::Local<v8::ArrayBuffer> sin_buffer = v8::ArrayBuffer::New(
2792 reinterpret_cast<v8::Isolate*>(isolate),
2793 TrigonometricLookupTable::sin_table(), table_num_bytes);
2794 v8::Local<v8::ArrayBuffer> cos_buffer = v8::ArrayBuffer::New(
2795 reinterpret_cast<v8::Isolate*>(isolate),
2796 TrigonometricLookupTable::cos_x_interval_table(), table_num_bytes);
2797 v8::Local<v8::Float64Array> sin_table = v8::Float64Array::New(
2798 sin_buffer, 0, TrigonometricLookupTable::table_size());
2799 v8::Local<v8::Float64Array> cos_table = v8::Float64Array::New(
2800 cos_buffer, 0, TrigonometricLookupTable::table_size());
2802 ForceSetProperty(builtins,
2803 factory()->InternalizeOneByteString(
2804 STATIC_ASCII_VECTOR("kSinTable")),
2805 Utils::OpenHandle(*sin_table),
2807 ForceSetProperty(builtins,
2808 factory()->InternalizeOneByteString(
2809 STATIC_ASCII_VECTOR("kCosXIntervalTable")),
2810 Utils::OpenHandle(*cos_table),
2812 ForceSetProperty(builtins,
2813 factory()->InternalizeOneByteString(
2814 STATIC_ASCII_VECTOR("kSamples")),
2815 factory()->NewHeapNumber(
2816 TrigonometricLookupTable::samples()),
2818 ForceSetProperty(builtins,
2819 factory()->InternalizeOneByteString(
2820 STATIC_ASCII_VECTOR("kIndexConvert")),
2821 factory()->NewHeapNumber(
2822 TrigonometricLookupTable::samples_over_pi_half()),
2826 result_ = native_context();
2830 // Support for thread preemption.
2832 // Reserve space for statics needing saving and restoring.
2833 int Bootstrapper::ArchiveSpacePerThread() {
2834 return sizeof(NestingCounterType);
2838 // Archive statics that are thread local.
2839 char* Bootstrapper::ArchiveState(char* to) {
2840 *reinterpret_cast<NestingCounterType*>(to) = nesting_;
2842 return to + sizeof(NestingCounterType);
2846 // Restore statics that are thread local.
2847 char* Bootstrapper::RestoreState(char* from) {
2848 nesting_ = *reinterpret_cast<NestingCounterType*>(from);
2849 return from + sizeof(NestingCounterType);
2853 // Called when the top-level V8 mutex is destroyed.
2854 void Bootstrapper::FreeThreadResources() {
2855 ASSERT(!IsActive());
2858 } } // namespace v8::internal