• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
4 // met:
5 //
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.
15 //
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.
27 
28 #include "v8.h"
29 
30 #include "accessors.h"
31 #include "api.h"
32 #include "bootstrapper.h"
33 #include "compiler.h"
34 #include "debug.h"
35 #include "execution.h"
36 #include "global-handles.h"
37 #include "isolate-inl.h"
38 #include "macro-assembler.h"
39 #include "natives.h"
40 #include "objects-visiting.h"
41 #include "platform.h"
42 #include "snapshot.h"
43 #include "extensions/externalize-string-extension.h"
44 #include "extensions/gc-extension.h"
45 
46 namespace v8 {
47 namespace internal {
48 
49 
NativesExternalStringResource(Bootstrapper * bootstrapper,const char * source,size_t length)50 NativesExternalStringResource::NativesExternalStringResource(
51     Bootstrapper* bootstrapper,
52     const char* source,
53     size_t length)
54     : data_(source), length_(length) {
55   if (bootstrapper->delete_these_non_arrays_on_tear_down_ == NULL) {
56     bootstrapper->delete_these_non_arrays_on_tear_down_ = new List<char*>(2);
57   }
58   // The resources are small objects and we only make a fixed number of
59   // them, but let's clean them up on exit for neatness.
60   bootstrapper->delete_these_non_arrays_on_tear_down_->
61       Add(reinterpret_cast<char*>(this));
62 }
63 
64 
Bootstrapper()65 Bootstrapper::Bootstrapper()
66     : nesting_(0),
67       extensions_cache_(Script::TYPE_EXTENSION),
68       delete_these_non_arrays_on_tear_down_(NULL),
69       delete_these_arrays_on_tear_down_(NULL) {
70 }
71 
72 
NativesSourceLookup(int index)73 Handle<String> Bootstrapper::NativesSourceLookup(int index) {
74   ASSERT(0 <= index && index < Natives::GetBuiltinsCount());
75   Isolate* isolate = Isolate::Current();
76   Factory* factory = isolate->factory();
77   Heap* heap = isolate->heap();
78   if (heap->natives_source_cache()->get(index)->IsUndefined()) {
79     // We can use external strings for the natives.
80     Vector<const char> source = Natives::GetRawScriptSource(index);
81     NativesExternalStringResource* resource =
82         new NativesExternalStringResource(this,
83                                           source.start(),
84                                           source.length());
85     Handle<String> source_code =
86         factory->NewExternalStringFromAscii(resource);
87     heap->natives_source_cache()->set(index, *source_code);
88   }
89   Handle<Object> cached_source(heap->natives_source_cache()->get(index));
90   return Handle<String>::cast(cached_source);
91 }
92 
93 
Initialize(bool create_heap_objects)94 void Bootstrapper::Initialize(bool create_heap_objects) {
95   extensions_cache_.Initialize(create_heap_objects);
96   GCExtension::Register();
97   ExternalizeStringExtension::Register();
98 }
99 
100 
AllocateAutoDeletedArray(int bytes)101 char* Bootstrapper::AllocateAutoDeletedArray(int bytes) {
102   char* memory = new char[bytes];
103   if (memory != NULL) {
104     if (delete_these_arrays_on_tear_down_ == NULL) {
105       delete_these_arrays_on_tear_down_ = new List<char*>(2);
106     }
107     delete_these_arrays_on_tear_down_->Add(memory);
108   }
109   return memory;
110 }
111 
112 
TearDown()113 void Bootstrapper::TearDown() {
114   if (delete_these_non_arrays_on_tear_down_ != NULL) {
115     int len = delete_these_non_arrays_on_tear_down_->length();
116     ASSERT(len < 20);  // Don't use this mechanism for unbounded allocations.
117     for (int i = 0; i < len; i++) {
118       delete delete_these_non_arrays_on_tear_down_->at(i);
119       delete_these_non_arrays_on_tear_down_->at(i) = NULL;
120     }
121     delete delete_these_non_arrays_on_tear_down_;
122     delete_these_non_arrays_on_tear_down_ = NULL;
123   }
124 
125   if (delete_these_arrays_on_tear_down_ != NULL) {
126     int len = delete_these_arrays_on_tear_down_->length();
127     ASSERT(len < 1000);  // Don't use this mechanism for unbounded allocations.
128     for (int i = 0; i < len; i++) {
129       delete[] delete_these_arrays_on_tear_down_->at(i);
130       delete_these_arrays_on_tear_down_->at(i) = NULL;
131     }
132     delete delete_these_arrays_on_tear_down_;
133     delete_these_arrays_on_tear_down_ = NULL;
134   }
135 
136   extensions_cache_.Initialize(false);  // Yes, symmetrical
137 }
138 
139 
140 class Genesis BASE_EMBEDDED {
141  public:
142   Genesis(Isolate* isolate,
143           Handle<Object> global_object,
144           v8::Handle<v8::ObjectTemplate> global_template,
145           v8::ExtensionConfiguration* extensions);
~Genesis()146   ~Genesis() { }
147 
result()148   Handle<Context> result() { return result_; }
149 
previous()150   Genesis* previous() { return previous_; }
151 
isolate() const152   Isolate* isolate() const { return isolate_; }
factory() const153   Factory* factory() const { return isolate_->factory(); }
heap() const154   Heap* heap() const { return isolate_->heap(); }
155 
156  private:
157   Handle<Context> global_context_;
158   Isolate* isolate_;
159 
160   // There may be more than one active genesis object: When GC is
161   // triggered during environment creation there may be weak handle
162   // processing callbacks which may create new environments.
163   Genesis* previous_;
164 
global_context()165   Handle<Context> global_context() { return global_context_; }
166 
167   // Creates some basic objects. Used for creating a context from scratch.
168   void CreateRoots();
169   // Creates the empty function.  Used for creating a context from scratch.
170   Handle<JSFunction> CreateEmptyFunction(Isolate* isolate);
171   // Creates the ThrowTypeError function. ECMA 5th Ed. 13.2.3
172   Handle<JSFunction> GetThrowTypeErrorFunction();
173 
174   void CreateStrictModeFunctionMaps(Handle<JSFunction> empty);
175 
176   // Make the "arguments" and "caller" properties throw a TypeError on access.
177   void PoisonArgumentsAndCaller(Handle<Map> map);
178 
179   // Creates the global objects using the global and the template passed in
180   // through the API.  We call this regardless of whether we are building a
181   // context from scratch or using a deserialized one from the partial snapshot
182   // but in the latter case we don't use the objects it produces directly, as
183   // we have to used the deserialized ones that are linked together with the
184   // rest of the context snapshot.
185   Handle<JSGlobalProxy> CreateNewGlobals(
186       v8::Handle<v8::ObjectTemplate> global_template,
187       Handle<Object> global_object,
188       Handle<GlobalObject>* global_proxy_out);
189   // Hooks the given global proxy into the context.  If the context was created
190   // by deserialization then this will unhook the global proxy that was
191   // deserialized, leaving the GC to pick it up.
192   void HookUpGlobalProxy(Handle<GlobalObject> inner_global,
193                          Handle<JSGlobalProxy> global_proxy);
194   // Similarly, we want to use the inner global that has been created by the
195   // templates passed through the API.  The inner global from the snapshot is
196   // detached from the other objects in the snapshot.
197   void HookUpInnerGlobal(Handle<GlobalObject> inner_global);
198   // New context initialization.  Used for creating a context from scratch.
199   bool InitializeGlobal(Handle<GlobalObject> inner_global,
200                         Handle<JSFunction> empty_function);
201   void InitializeExperimentalGlobal();
202   // Installs the contents of the native .js files on the global objects.
203   // Used for creating a context from scratch.
204   void InstallNativeFunctions();
205   void InstallExperimentalNativeFunctions();
206   bool InstallNatives();
207   bool InstallExperimentalNatives();
208   void InstallBuiltinFunctionIds();
209   void InstallJSFunctionResultCaches();
210   void InitializeNormalizedMapCaches();
211 
212   enum ExtensionTraversalState {
213     UNVISITED, VISITED, INSTALLED
214   };
215 
216   class ExtensionStates {
217    public:
218     ExtensionStates();
219     ExtensionTraversalState get_state(RegisteredExtension* extension);
220     void set_state(RegisteredExtension* extension,
221                    ExtensionTraversalState state);
222    private:
223     HashMap map_;
224     DISALLOW_COPY_AND_ASSIGN(ExtensionStates);
225   };
226 
227   // Used both for deserialized and from-scratch contexts to add the extensions
228   // provided.
229   static bool InstallExtensions(Handle<Context> global_context,
230                                 v8::ExtensionConfiguration* extensions);
231   static bool InstallExtension(const char* name,
232                                ExtensionStates* extension_states);
233   static bool InstallExtension(v8::RegisteredExtension* current,
234                                ExtensionStates* extension_states);
235   static void InstallSpecialObjects(Handle<Context> global_context);
236   bool InstallJSBuiltins(Handle<JSBuiltinsObject> builtins);
237   bool ConfigureApiObject(Handle<JSObject> object,
238                           Handle<ObjectTemplateInfo> object_template);
239   bool ConfigureGlobalObjects(v8::Handle<v8::ObjectTemplate> global_template);
240 
241   // Migrates all properties from the 'from' object to the 'to'
242   // object and overrides the prototype in 'to' with the one from
243   // 'from'.
244   void TransferObject(Handle<JSObject> from, Handle<JSObject> to);
245   void TransferNamedProperties(Handle<JSObject> from, Handle<JSObject> to);
246   void TransferIndexedProperties(Handle<JSObject> from, Handle<JSObject> to);
247 
248   enum PrototypePropertyMode {
249     DONT_ADD_PROTOTYPE,
250     ADD_READONLY_PROTOTYPE,
251     ADD_WRITEABLE_PROTOTYPE
252   };
253 
254   Handle<Map> CreateFunctionMap(PrototypePropertyMode prototype_mode);
255 
256   Handle<DescriptorArray> ComputeFunctionInstanceDescriptor(
257       PrototypePropertyMode prototypeMode);
258   void MakeFunctionInstancePrototypeWritable();
259 
260   Handle<Map> CreateStrictModeFunctionMap(
261       PrototypePropertyMode prototype_mode,
262       Handle<JSFunction> empty_function);
263 
264   Handle<DescriptorArray> ComputeStrictFunctionInstanceDescriptor(
265       PrototypePropertyMode propertyMode);
266 
267   static bool CompileBuiltin(Isolate* isolate, int index);
268   static bool CompileExperimentalBuiltin(Isolate* isolate, int index);
269   static bool CompileNative(Vector<const char> name, Handle<String> source);
270   static bool CompileScriptCached(Vector<const char> name,
271                                   Handle<String> source,
272                                   SourceCodeCache* cache,
273                                   v8::Extension* extension,
274                                   Handle<Context> top_context,
275                                   bool use_runtime_context);
276 
277   Handle<Context> result_;
278 
279   // Function instance maps. Function literal maps are created initially with
280   // a read only prototype for the processing of JS builtins. Later the function
281   // instance maps are replaced in order to make prototype writable.
282   // These are the final, writable prototype, maps.
283   Handle<Map> function_instance_map_writable_prototype_;
284   Handle<Map> strict_mode_function_instance_map_writable_prototype_;
285   Handle<JSFunction> throw_type_error_function;
286 
287   BootstrapperActive active_;
288   friend class Bootstrapper;
289 };
290 
291 
Iterate(ObjectVisitor * v)292 void Bootstrapper::Iterate(ObjectVisitor* v) {
293   extensions_cache_.Iterate(v);
294   v->Synchronize(VisitorSynchronization::kExtensions);
295 }
296 
297 
CreateEnvironment(Isolate * isolate,Handle<Object> global_object,v8::Handle<v8::ObjectTemplate> global_template,v8::ExtensionConfiguration * extensions)298 Handle<Context> Bootstrapper::CreateEnvironment(
299     Isolate* isolate,
300     Handle<Object> global_object,
301     v8::Handle<v8::ObjectTemplate> global_template,
302     v8::ExtensionConfiguration* extensions) {
303   HandleScope scope;
304   Handle<Context> env;
305   Genesis genesis(isolate, global_object, global_template, extensions);
306   env = genesis.result();
307   if (!env.is_null()) {
308     if (InstallExtensions(env, extensions)) {
309       return env;
310     }
311   }
312   return Handle<Context>();
313 }
314 
315 
SetObjectPrototype(Handle<JSObject> object,Handle<Object> proto)316 static void SetObjectPrototype(Handle<JSObject> object, Handle<Object> proto) {
317   // object.__proto__ = proto;
318   Factory* factory = object->GetIsolate()->factory();
319   Handle<Map> old_to_map = Handle<Map>(object->map());
320   Handle<Map> new_to_map = factory->CopyMapDropTransitions(old_to_map);
321   new_to_map->set_prototype(*proto);
322   object->set_map(*new_to_map);
323 }
324 
325 
DetachGlobal(Handle<Context> env)326 void Bootstrapper::DetachGlobal(Handle<Context> env) {
327   Factory* factory = env->GetIsolate()->factory();
328   JSGlobalProxy::cast(env->global_proxy())->set_context(*factory->null_value());
329   SetObjectPrototype(Handle<JSObject>(env->global_proxy()),
330                      factory->null_value());
331   env->set_global_proxy(env->global());
332   env->global()->set_global_receiver(env->global());
333 }
334 
335 
ReattachGlobal(Handle<Context> env,Handle<Object> global_object)336 void Bootstrapper::ReattachGlobal(Handle<Context> env,
337                                   Handle<Object> global_object) {
338   ASSERT(global_object->IsJSGlobalProxy());
339   Handle<JSGlobalProxy> global = Handle<JSGlobalProxy>::cast(global_object);
340   env->global()->set_global_receiver(*global);
341   env->set_global_proxy(*global);
342   SetObjectPrototype(global, Handle<JSObject>(env->global()));
343   global->set_context(*env);
344 }
345 
346 
InstallFunction(Handle<JSObject> target,const char * name,InstanceType type,int instance_size,Handle<JSObject> prototype,Builtins::Name call,bool is_ecma_native)347 static Handle<JSFunction> InstallFunction(Handle<JSObject> target,
348                                           const char* name,
349                                           InstanceType type,
350                                           int instance_size,
351                                           Handle<JSObject> prototype,
352                                           Builtins::Name call,
353                                           bool is_ecma_native) {
354   Isolate* isolate = target->GetIsolate();
355   Factory* factory = isolate->factory();
356   Handle<String> symbol = factory->LookupAsciiSymbol(name);
357   Handle<Code> call_code = Handle<Code>(isolate->builtins()->builtin(call));
358   Handle<JSFunction> function = prototype.is_null() ?
359     factory->NewFunctionWithoutPrototype(symbol, call_code) :
360     factory->NewFunctionWithPrototype(symbol,
361                                       type,
362                                       instance_size,
363                                       prototype,
364                                       call_code,
365                                       is_ecma_native);
366   PropertyAttributes attributes;
367   if (target->IsJSBuiltinsObject()) {
368     attributes =
369         static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
370   } else {
371     attributes = DONT_ENUM;
372   }
373   CHECK_NOT_EMPTY_HANDLE(isolate,
374                          JSObject::SetLocalPropertyIgnoreAttributes(
375                              target, symbol, function, attributes));
376   if (is_ecma_native) {
377     function->shared()->set_instance_class_name(*symbol);
378   }
379   function->shared()->set_native(true);
380   return function;
381 }
382 
383 
ComputeFunctionInstanceDescriptor(PrototypePropertyMode prototypeMode)384 Handle<DescriptorArray> Genesis::ComputeFunctionInstanceDescriptor(
385     PrototypePropertyMode prototypeMode) {
386   int size = (prototypeMode == DONT_ADD_PROTOTYPE) ? 4 : 5;
387   Handle<DescriptorArray> descriptors(factory()->NewDescriptorArray(size));
388   PropertyAttributes attribs = static_cast<PropertyAttributes>(
389       DONT_ENUM | DONT_DELETE | READ_ONLY);
390 
391   DescriptorArray::WhitenessWitness witness(*descriptors);
392 
393   {  // Add length.
394     Handle<Foreign> f(factory()->NewForeign(&Accessors::FunctionLength));
395     CallbacksDescriptor d(*factory()->length_symbol(), *f, attribs);
396     descriptors->Set(0, &d, witness);
397   }
398   {  // Add name.
399     Handle<Foreign> f(factory()->NewForeign(&Accessors::FunctionName));
400     CallbacksDescriptor d(*factory()->name_symbol(), *f, attribs);
401     descriptors->Set(1, &d, witness);
402   }
403   {  // Add arguments.
404     Handle<Foreign> f(factory()->NewForeign(&Accessors::FunctionArguments));
405     CallbacksDescriptor d(*factory()->arguments_symbol(), *f, attribs);
406     descriptors->Set(2, &d, witness);
407   }
408   {  // Add caller.
409     Handle<Foreign> f(factory()->NewForeign(&Accessors::FunctionCaller));
410     CallbacksDescriptor d(*factory()->caller_symbol(), *f, attribs);
411     descriptors->Set(3, &d, witness);
412   }
413   if (prototypeMode != DONT_ADD_PROTOTYPE) {
414     // Add prototype.
415     if (prototypeMode == ADD_WRITEABLE_PROTOTYPE) {
416       attribs = static_cast<PropertyAttributes>(attribs & ~READ_ONLY);
417     }
418     Handle<Foreign> f(factory()->NewForeign(&Accessors::FunctionPrototype));
419     CallbacksDescriptor d(*factory()->prototype_symbol(), *f, attribs);
420     descriptors->Set(4, &d, witness);
421   }
422   descriptors->Sort(witness);
423   return descriptors;
424 }
425 
426 
CreateFunctionMap(PrototypePropertyMode prototype_mode)427 Handle<Map> Genesis::CreateFunctionMap(PrototypePropertyMode prototype_mode) {
428   Handle<Map> map = factory()->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
429   Handle<DescriptorArray> descriptors =
430       ComputeFunctionInstanceDescriptor(prototype_mode);
431   map->set_instance_descriptors(*descriptors);
432   map->set_function_with_prototype(prototype_mode != DONT_ADD_PROTOTYPE);
433   return map;
434 }
435 
436 
CreateEmptyFunction(Isolate * isolate)437 Handle<JSFunction> Genesis::CreateEmptyFunction(Isolate* isolate) {
438   // Allocate the map for function instances. Maps are allocated first and their
439   // prototypes patched later, once empty function is created.
440 
441   // Please note that the prototype property for function instances must be
442   // writable.
443   Handle<Map> function_instance_map =
444       CreateFunctionMap(ADD_WRITEABLE_PROTOTYPE);
445   global_context()->set_function_instance_map(*function_instance_map);
446 
447   // Functions with this map will not have a 'prototype' property, and
448   // can not be used as constructors.
449   Handle<Map> function_without_prototype_map =
450       CreateFunctionMap(DONT_ADD_PROTOTYPE);
451   global_context()->set_function_without_prototype_map(
452       *function_without_prototype_map);
453 
454   // Allocate the function map. This map is temporary, used only for processing
455   // of builtins.
456   // Later the map is replaced with writable prototype map, allocated below.
457   Handle<Map> function_map = CreateFunctionMap(ADD_READONLY_PROTOTYPE);
458   global_context()->set_function_map(*function_map);
459 
460   // The final map for functions. Writeable prototype.
461   // This map is installed in MakeFunctionInstancePrototypeWritable.
462   function_instance_map_writable_prototype_ =
463       CreateFunctionMap(ADD_WRITEABLE_PROTOTYPE);
464 
465   Factory* factory = isolate->factory();
466   Heap* heap = isolate->heap();
467 
468   Handle<String> object_name = Handle<String>(heap->Object_symbol());
469 
470   {  // --- O b j e c t ---
471     Handle<JSFunction> object_fun =
472         factory->NewFunction(object_name, factory->null_value());
473     Handle<Map> object_function_map =
474         factory->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
475     object_fun->set_initial_map(*object_function_map);
476     object_function_map->set_constructor(*object_fun);
477 
478     global_context()->set_object_function(*object_fun);
479 
480     // Allocate a new prototype for the object function.
481     Handle<JSObject> prototype = factory->NewJSObject(
482         isolate->object_function(),
483         TENURED);
484 
485     global_context()->set_initial_object_prototype(*prototype);
486     SetPrototype(object_fun, prototype);
487     object_function_map->
488       set_instance_descriptors(heap->empty_descriptor_array());
489   }
490 
491   // Allocate the empty function as the prototype for function ECMAScript
492   // 262 15.3.4.
493   Handle<String> symbol = factory->LookupAsciiSymbol("Empty");
494   Handle<JSFunction> empty_function =
495       factory->NewFunctionWithoutPrototype(symbol, CLASSIC_MODE);
496 
497   // --- E m p t y ---
498   Handle<Code> code =
499       Handle<Code>(isolate->builtins()->builtin(
500           Builtins::kEmptyFunction));
501   empty_function->set_code(*code);
502   empty_function->shared()->set_code(*code);
503   Handle<String> source = factory->NewStringFromAscii(CStrVector("() {}"));
504   Handle<Script> script = factory->NewScript(source);
505   script->set_type(Smi::FromInt(Script::TYPE_NATIVE));
506   empty_function->shared()->set_script(*script);
507   empty_function->shared()->set_start_position(0);
508   empty_function->shared()->set_end_position(source->length());
509   empty_function->shared()->DontAdaptArguments();
510 
511   // Set prototypes for the function maps.
512   global_context()->function_map()->set_prototype(*empty_function);
513   global_context()->function_instance_map()->set_prototype(*empty_function);
514   global_context()->function_without_prototype_map()->
515       set_prototype(*empty_function);
516   function_instance_map_writable_prototype_->set_prototype(*empty_function);
517 
518   // Allocate the function map first and then patch the prototype later
519   Handle<Map> empty_fm = factory->CopyMapDropDescriptors(
520       function_without_prototype_map);
521   empty_fm->set_instance_descriptors(
522       function_without_prototype_map->instance_descriptors());
523   empty_fm->set_prototype(global_context()->object_function()->prototype());
524   empty_function->set_map(*empty_fm);
525   return empty_function;
526 }
527 
528 
ComputeStrictFunctionInstanceDescriptor(PrototypePropertyMode prototypeMode)529 Handle<DescriptorArray> Genesis::ComputeStrictFunctionInstanceDescriptor(
530     PrototypePropertyMode prototypeMode) {
531   int size = (prototypeMode == DONT_ADD_PROTOTYPE) ? 4 : 5;
532   Handle<DescriptorArray> descriptors(factory()->NewDescriptorArray(size));
533   PropertyAttributes attribs = static_cast<PropertyAttributes>(
534       DONT_ENUM | DONT_DELETE);
535 
536   DescriptorArray::WhitenessWitness witness(*descriptors);
537 
538   {  // Add length.
539     Handle<Foreign> f(factory()->NewForeign(&Accessors::FunctionLength));
540     CallbacksDescriptor d(*factory()->length_symbol(), *f, attribs);
541     descriptors->Set(0, &d, witness);
542   }
543   {  // Add name.
544     Handle<Foreign> f(factory()->NewForeign(&Accessors::FunctionName));
545     CallbacksDescriptor d(*factory()->name_symbol(), *f, attribs);
546     descriptors->Set(1, &d, witness);
547   }
548   {  // Add arguments.
549     Handle<AccessorPair> arguments(factory()->NewAccessorPair());
550     CallbacksDescriptor d(*factory()->arguments_symbol(), *arguments, attribs);
551     descriptors->Set(2, &d, witness);
552   }
553   {  // Add caller.
554     Handle<AccessorPair> caller(factory()->NewAccessorPair());
555     CallbacksDescriptor d(*factory()->caller_symbol(), *caller, attribs);
556     descriptors->Set(3, &d, witness);
557   }
558 
559   if (prototypeMode != DONT_ADD_PROTOTYPE) {
560     // Add prototype.
561     if (prototypeMode != ADD_WRITEABLE_PROTOTYPE) {
562       attribs = static_cast<PropertyAttributes>(attribs | READ_ONLY);
563     }
564     Handle<Foreign> f(factory()->NewForeign(&Accessors::FunctionPrototype));
565     CallbacksDescriptor d(*factory()->prototype_symbol(), *f, attribs);
566     descriptors->Set(4, &d, witness);
567   }
568 
569   descriptors->Sort(witness);
570   return descriptors;
571 }
572 
573 
574 // ECMAScript 5th Edition, 13.2.3
GetThrowTypeErrorFunction()575 Handle<JSFunction> Genesis::GetThrowTypeErrorFunction() {
576   if (throw_type_error_function.is_null()) {
577     Handle<String> name = factory()->LookupAsciiSymbol("ThrowTypeError");
578     throw_type_error_function =
579       factory()->NewFunctionWithoutPrototype(name, CLASSIC_MODE);
580     Handle<Code> code(isolate()->builtins()->builtin(
581         Builtins::kStrictModePoisonPill));
582     throw_type_error_function->set_map(
583         global_context()->function_map());
584     throw_type_error_function->set_code(*code);
585     throw_type_error_function->shared()->set_code(*code);
586     throw_type_error_function->shared()->DontAdaptArguments();
587 
588     JSObject::PreventExtensions(throw_type_error_function);
589   }
590   return throw_type_error_function;
591 }
592 
593 
CreateStrictModeFunctionMap(PrototypePropertyMode prototype_mode,Handle<JSFunction> empty_function)594 Handle<Map> Genesis::CreateStrictModeFunctionMap(
595     PrototypePropertyMode prototype_mode,
596     Handle<JSFunction> empty_function) {
597   Handle<Map> map = factory()->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
598   Handle<DescriptorArray> descriptors =
599       ComputeStrictFunctionInstanceDescriptor(prototype_mode);
600   map->set_instance_descriptors(*descriptors);
601   map->set_function_with_prototype(prototype_mode != DONT_ADD_PROTOTYPE);
602   map->set_prototype(*empty_function);
603   return map;
604 }
605 
606 
CreateStrictModeFunctionMaps(Handle<JSFunction> empty)607 void Genesis::CreateStrictModeFunctionMaps(Handle<JSFunction> empty) {
608   // Allocate map for the strict mode function instances.
609   Handle<Map> strict_mode_function_instance_map =
610       CreateStrictModeFunctionMap(ADD_WRITEABLE_PROTOTYPE, empty);
611   global_context()->set_strict_mode_function_instance_map(
612       *strict_mode_function_instance_map);
613 
614   // Allocate map for the prototype-less strict mode instances.
615   Handle<Map> strict_mode_function_without_prototype_map =
616       CreateStrictModeFunctionMap(DONT_ADD_PROTOTYPE, empty);
617   global_context()->set_strict_mode_function_without_prototype_map(
618       *strict_mode_function_without_prototype_map);
619 
620   // Allocate map for the strict mode functions. This map is temporary, used
621   // only for processing of builtins.
622   // Later the map is replaced with writable prototype map, allocated below.
623   Handle<Map> strict_mode_function_map =
624       CreateStrictModeFunctionMap(ADD_READONLY_PROTOTYPE, empty);
625   global_context()->set_strict_mode_function_map(
626       *strict_mode_function_map);
627 
628   // The final map for the strict mode functions. Writeable prototype.
629   // This map is installed in MakeFunctionInstancePrototypeWritable.
630   strict_mode_function_instance_map_writable_prototype_ =
631       CreateStrictModeFunctionMap(ADD_WRITEABLE_PROTOTYPE, empty);
632 
633   // Complete the callbacks.
634   PoisonArgumentsAndCaller(strict_mode_function_instance_map);
635   PoisonArgumentsAndCaller(strict_mode_function_without_prototype_map);
636   PoisonArgumentsAndCaller(strict_mode_function_map);
637   PoisonArgumentsAndCaller(
638       strict_mode_function_instance_map_writable_prototype_);
639 }
640 
641 
SetAccessors(Handle<Map> map,Handle<String> name,Handle<JSFunction> func)642 static void SetAccessors(Handle<Map> map,
643                          Handle<String> name,
644                          Handle<JSFunction> func) {
645   DescriptorArray* descs = map->instance_descriptors();
646   int number = descs->Search(*name);
647   AccessorPair* accessors = AccessorPair::cast(descs->GetValue(number));
648   accessors->set_getter(*func);
649   accessors->set_setter(*func);
650 }
651 
652 
PoisonArgumentsAndCaller(Handle<Map> map)653 void Genesis::PoisonArgumentsAndCaller(Handle<Map> map) {
654   SetAccessors(map, factory()->arguments_symbol(), GetThrowTypeErrorFunction());
655   SetAccessors(map, factory()->caller_symbol(), GetThrowTypeErrorFunction());
656 }
657 
658 
AddToWeakGlobalContextList(Context * context)659 static void AddToWeakGlobalContextList(Context* context) {
660   ASSERT(context->IsGlobalContext());
661   Heap* heap = context->GetIsolate()->heap();
662 #ifdef DEBUG
663   { // NOLINT
664     ASSERT(context->get(Context::NEXT_CONTEXT_LINK)->IsUndefined());
665     // Check that context is not in the list yet.
666     for (Object* current = heap->global_contexts_list();
667          !current->IsUndefined();
668          current = Context::cast(current)->get(Context::NEXT_CONTEXT_LINK)) {
669       ASSERT(current != context);
670     }
671   }
672 #endif
673   context->set(Context::NEXT_CONTEXT_LINK, heap->global_contexts_list());
674   heap->set_global_contexts_list(context);
675 }
676 
677 
CreateRoots()678 void Genesis::CreateRoots() {
679   // Allocate the global context FixedArray first and then patch the
680   // closure and extension object later (we need the empty function
681   // and the global object, but in order to create those, we need the
682   // global context).
683   global_context_ = Handle<Context>::cast(isolate()->global_handles()->Create(
684               *factory()->NewGlobalContext()));
685   AddToWeakGlobalContextList(*global_context_);
686   isolate()->set_context(*global_context());
687 
688   // Allocate the message listeners object.
689   {
690     v8::NeanderArray listeners;
691     global_context()->set_message_listeners(*listeners.value());
692   }
693 }
694 
695 
CreateNewGlobals(v8::Handle<v8::ObjectTemplate> global_template,Handle<Object> global_object,Handle<GlobalObject> * inner_global_out)696 Handle<JSGlobalProxy> Genesis::CreateNewGlobals(
697     v8::Handle<v8::ObjectTemplate> global_template,
698     Handle<Object> global_object,
699     Handle<GlobalObject>* inner_global_out) {
700   // The argument global_template aka data is an ObjectTemplateInfo.
701   // It has a constructor pointer that points at global_constructor which is a
702   // FunctionTemplateInfo.
703   // The global_constructor is used to create or reinitialize the global_proxy.
704   // The global_constructor also has a prototype_template pointer that points at
705   // js_global_template which is an ObjectTemplateInfo.
706   // That in turn has a constructor pointer that points at
707   // js_global_constructor which is a FunctionTemplateInfo.
708   // js_global_constructor is used to make js_global_function
709   // js_global_function is used to make the new inner_global.
710   //
711   // --- G l o b a l ---
712   // Step 1: Create a fresh inner JSGlobalObject.
713   Handle<JSFunction> js_global_function;
714   Handle<ObjectTemplateInfo> js_global_template;
715   if (!global_template.IsEmpty()) {
716     // Get prototype template of the global_template.
717     Handle<ObjectTemplateInfo> data =
718         v8::Utils::OpenHandle(*global_template);
719     Handle<FunctionTemplateInfo> global_constructor =
720         Handle<FunctionTemplateInfo>(
721             FunctionTemplateInfo::cast(data->constructor()));
722     Handle<Object> proto_template(global_constructor->prototype_template());
723     if (!proto_template->IsUndefined()) {
724       js_global_template =
725           Handle<ObjectTemplateInfo>::cast(proto_template);
726     }
727   }
728 
729   if (js_global_template.is_null()) {
730     Handle<String> name = Handle<String>(heap()->empty_symbol());
731     Handle<Code> code = Handle<Code>(isolate()->builtins()->builtin(
732         Builtins::kIllegal));
733     js_global_function =
734         factory()->NewFunction(name, JS_GLOBAL_OBJECT_TYPE,
735                                JSGlobalObject::kSize, code, true);
736     // Change the constructor property of the prototype of the
737     // hidden global function to refer to the Object function.
738     Handle<JSObject> prototype =
739         Handle<JSObject>(
740             JSObject::cast(js_global_function->instance_prototype()));
741     CHECK_NOT_EMPTY_HANDLE(isolate(),
742                            JSObject::SetLocalPropertyIgnoreAttributes(
743                                prototype, factory()->constructor_symbol(),
744                                isolate()->object_function(), NONE));
745   } else {
746     Handle<FunctionTemplateInfo> js_global_constructor(
747         FunctionTemplateInfo::cast(js_global_template->constructor()));
748     js_global_function =
749         factory()->CreateApiFunction(js_global_constructor,
750                                      factory()->InnerGlobalObject);
751   }
752 
753   js_global_function->initial_map()->set_is_hidden_prototype();
754   Handle<GlobalObject> inner_global =
755       factory()->NewGlobalObject(js_global_function);
756   if (inner_global_out != NULL) {
757     *inner_global_out = inner_global;
758   }
759 
760   // Step 2: create or re-initialize the global proxy object.
761   Handle<JSFunction> global_proxy_function;
762   if (global_template.IsEmpty()) {
763     Handle<String> name = Handle<String>(heap()->empty_symbol());
764     Handle<Code> code = Handle<Code>(isolate()->builtins()->builtin(
765         Builtins::kIllegal));
766     global_proxy_function =
767         factory()->NewFunction(name, JS_GLOBAL_PROXY_TYPE,
768                                JSGlobalProxy::kSize, code, true);
769   } else {
770     Handle<ObjectTemplateInfo> data =
771         v8::Utils::OpenHandle(*global_template);
772     Handle<FunctionTemplateInfo> global_constructor(
773             FunctionTemplateInfo::cast(data->constructor()));
774     global_proxy_function =
775         factory()->CreateApiFunction(global_constructor,
776                                      factory()->OuterGlobalObject);
777   }
778 
779   Handle<String> global_name = factory()->LookupAsciiSymbol("global");
780   global_proxy_function->shared()->set_instance_class_name(*global_name);
781   global_proxy_function->initial_map()->set_is_access_check_needed(true);
782 
783   // Set global_proxy.__proto__ to js_global after ConfigureGlobalObjects
784   // Return the global proxy.
785 
786   if (global_object.location() != NULL) {
787     ASSERT(global_object->IsJSGlobalProxy());
788     return ReinitializeJSGlobalProxy(
789         global_proxy_function,
790         Handle<JSGlobalProxy>::cast(global_object));
791   } else {
792     return Handle<JSGlobalProxy>::cast(
793         factory()->NewJSObject(global_proxy_function, TENURED));
794   }
795 }
796 
797 
HookUpGlobalProxy(Handle<GlobalObject> inner_global,Handle<JSGlobalProxy> global_proxy)798 void Genesis::HookUpGlobalProxy(Handle<GlobalObject> inner_global,
799                                 Handle<JSGlobalProxy> global_proxy) {
800   // Set the global context for the global object.
801   inner_global->set_global_context(*global_context());
802   inner_global->set_global_receiver(*global_proxy);
803   global_proxy->set_context(*global_context());
804   global_context()->set_global_proxy(*global_proxy);
805 }
806 
807 
HookUpInnerGlobal(Handle<GlobalObject> inner_global)808 void Genesis::HookUpInnerGlobal(Handle<GlobalObject> inner_global) {
809   Handle<GlobalObject> inner_global_from_snapshot(
810       GlobalObject::cast(global_context_->extension()));
811   Handle<JSBuiltinsObject> builtins_global(global_context_->builtins());
812   global_context_->set_extension(*inner_global);
813   global_context_->set_global(*inner_global);
814   global_context_->set_security_token(*inner_global);
815   static const PropertyAttributes attributes =
816       static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE);
817   ForceSetProperty(builtins_global,
818                    factory()->LookupAsciiSymbol("global"),
819                    inner_global,
820                    attributes);
821   // Set up the reference from the global object to the builtins object.
822   JSGlobalObject::cast(*inner_global)->set_builtins(*builtins_global);
823   TransferNamedProperties(inner_global_from_snapshot, inner_global);
824   TransferIndexedProperties(inner_global_from_snapshot, inner_global);
825 }
826 
827 
828 // This is only called if we are not using snapshots.  The equivalent
829 // work in the snapshot case is done in HookUpInnerGlobal.
InitializeGlobal(Handle<GlobalObject> inner_global,Handle<JSFunction> empty_function)830 bool Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
831                                Handle<JSFunction> empty_function) {
832   // --- G l o b a l   C o n t e x t ---
833   // Use the empty function as closure (no scope info).
834   global_context()->set_closure(*empty_function);
835   global_context()->set_previous(NULL);
836   // Set extension and global object.
837   global_context()->set_extension(*inner_global);
838   global_context()->set_global(*inner_global);
839   // Security setup: Set the security token of the global object to
840   // its the inner global. This makes the security check between two
841   // different contexts fail by default even in case of global
842   // object reinitialization.
843   global_context()->set_security_token(*inner_global);
844 
845   Isolate* isolate = inner_global->GetIsolate();
846   Factory* factory = isolate->factory();
847   Heap* heap = isolate->heap();
848 
849   Handle<String> object_name = Handle<String>(heap->Object_symbol());
850   CHECK_NOT_EMPTY_HANDLE(isolate,
851                          JSObject::SetLocalPropertyIgnoreAttributes(
852                              inner_global, object_name,
853                              isolate->object_function(), DONT_ENUM));
854 
855   Handle<JSObject> global = Handle<JSObject>(global_context()->global());
856 
857   // Install global Function object
858   InstallFunction(global, "Function", JS_FUNCTION_TYPE, JSFunction::kSize,
859                   empty_function, Builtins::kIllegal, true);  // ECMA native.
860 
861   {  // --- A r r a y ---
862     Handle<JSFunction> array_function =
863         InstallFunction(global, "Array", JS_ARRAY_TYPE, JSArray::kSize,
864                         isolate->initial_object_prototype(),
865                         Builtins::kArrayCode, true);
866     array_function->shared()->set_construct_stub(
867         isolate->builtins()->builtin(Builtins::kArrayConstructCode));
868     array_function->shared()->DontAdaptArguments();
869 
870     // This seems a bit hackish, but we need to make sure Array.length
871     // is 1.
872     array_function->shared()->set_length(1);
873     Handle<DescriptorArray> array_descriptors =
874         factory->CopyAppendForeignDescriptor(
875             factory->empty_descriptor_array(),
876             factory->length_symbol(),
877             factory->NewForeign(&Accessors::ArrayLength),
878             static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE));
879 
880     // array_function is used internally. JS code creating array object should
881     // search for the 'Array' property on the global object and use that one
882     // as the constructor. 'Array' property on a global object can be
883     // overwritten by JS code.
884     global_context()->set_array_function(*array_function);
885     array_function->initial_map()->set_instance_descriptors(*array_descriptors);
886   }
887 
888   {  // --- N u m b e r ---
889     Handle<JSFunction> number_fun =
890         InstallFunction(global, "Number", JS_VALUE_TYPE, JSValue::kSize,
891                         isolate->initial_object_prototype(),
892                         Builtins::kIllegal, true);
893     global_context()->set_number_function(*number_fun);
894   }
895 
896   {  // --- B o o l e a n ---
897     Handle<JSFunction> boolean_fun =
898         InstallFunction(global, "Boolean", JS_VALUE_TYPE, JSValue::kSize,
899                         isolate->initial_object_prototype(),
900                         Builtins::kIllegal, true);
901     global_context()->set_boolean_function(*boolean_fun);
902   }
903 
904   {  // --- S t r i n g ---
905     Handle<JSFunction> string_fun =
906         InstallFunction(global, "String", JS_VALUE_TYPE, JSValue::kSize,
907                         isolate->initial_object_prototype(),
908                         Builtins::kIllegal, true);
909     string_fun->shared()->set_construct_stub(
910         isolate->builtins()->builtin(Builtins::kStringConstructCode));
911     global_context()->set_string_function(*string_fun);
912     // Add 'length' property to strings.
913     Handle<DescriptorArray> string_descriptors =
914         factory->CopyAppendForeignDescriptor(
915             factory->empty_descriptor_array(),
916             factory->length_symbol(),
917             factory->NewForeign(&Accessors::StringLength),
918             static_cast<PropertyAttributes>(DONT_ENUM |
919                                             DONT_DELETE |
920                                             READ_ONLY));
921 
922     Handle<Map> string_map =
923         Handle<Map>(global_context()->string_function()->initial_map());
924     string_map->set_instance_descriptors(*string_descriptors);
925   }
926 
927   {  // --- D a t e ---
928     // Builtin functions for Date.prototype.
929     Handle<JSFunction> date_fun =
930         InstallFunction(global, "Date", JS_DATE_TYPE, JSDate::kSize,
931                         isolate->initial_object_prototype(),
932                         Builtins::kIllegal, true);
933 
934     global_context()->set_date_function(*date_fun);
935   }
936 
937 
938   {  // -- R e g E x p
939     // Builtin functions for RegExp.prototype.
940     Handle<JSFunction> regexp_fun =
941         InstallFunction(global, "RegExp", JS_REGEXP_TYPE, JSRegExp::kSize,
942                         isolate->initial_object_prototype(),
943                         Builtins::kIllegal, true);
944     global_context()->set_regexp_function(*regexp_fun);
945 
946     ASSERT(regexp_fun->has_initial_map());
947     Handle<Map> initial_map(regexp_fun->initial_map());
948 
949     ASSERT_EQ(0, initial_map->inobject_properties());
950 
951     Handle<DescriptorArray> descriptors = factory->NewDescriptorArray(5);
952     DescriptorArray::WhitenessWitness witness(*descriptors);
953     PropertyAttributes final =
954         static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
955     int enum_index = 0;
956     {
957       // ECMA-262, section 15.10.7.1.
958       FieldDescriptor field(heap->source_symbol(),
959                             JSRegExp::kSourceFieldIndex,
960                             final,
961                             enum_index++);
962       descriptors->Set(0, &field, witness);
963     }
964     {
965       // ECMA-262, section 15.10.7.2.
966       FieldDescriptor field(heap->global_symbol(),
967                             JSRegExp::kGlobalFieldIndex,
968                             final,
969                             enum_index++);
970       descriptors->Set(1, &field, witness);
971     }
972     {
973       // ECMA-262, section 15.10.7.3.
974       FieldDescriptor field(heap->ignore_case_symbol(),
975                             JSRegExp::kIgnoreCaseFieldIndex,
976                             final,
977                             enum_index++);
978       descriptors->Set(2, &field, witness);
979     }
980     {
981       // ECMA-262, section 15.10.7.4.
982       FieldDescriptor field(heap->multiline_symbol(),
983                             JSRegExp::kMultilineFieldIndex,
984                             final,
985                             enum_index++);
986       descriptors->Set(3, &field, witness);
987     }
988     {
989       // ECMA-262, section 15.10.7.5.
990       PropertyAttributes writable =
991           static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
992       FieldDescriptor field(heap->last_index_symbol(),
993                             JSRegExp::kLastIndexFieldIndex,
994                             writable,
995                             enum_index++);
996       descriptors->Set(4, &field, witness);
997     }
998     descriptors->SetNextEnumerationIndex(enum_index);
999     descriptors->Sort(witness);
1000 
1001     initial_map->set_inobject_properties(5);
1002     initial_map->set_pre_allocated_property_fields(5);
1003     initial_map->set_unused_property_fields(0);
1004     initial_map->set_instance_size(
1005         initial_map->instance_size() + 5 * kPointerSize);
1006     initial_map->set_instance_descriptors(*descriptors);
1007     initial_map->set_visitor_id(StaticVisitorBase::GetVisitorId(*initial_map));
1008 
1009     // RegExp prototype object is itself a RegExp.
1010     Handle<Map> proto_map = factory->CopyMapDropTransitions(initial_map);
1011     proto_map->set_prototype(global_context()->initial_object_prototype());
1012     Handle<JSObject> proto = factory->NewJSObjectFromMap(proto_map);
1013     proto->InObjectPropertyAtPut(JSRegExp::kSourceFieldIndex,
1014                                  heap->empty_string());
1015     proto->InObjectPropertyAtPut(JSRegExp::kGlobalFieldIndex,
1016                                  heap->false_value());
1017     proto->InObjectPropertyAtPut(JSRegExp::kIgnoreCaseFieldIndex,
1018                                  heap->false_value());
1019     proto->InObjectPropertyAtPut(JSRegExp::kMultilineFieldIndex,
1020                                  heap->false_value());
1021     proto->InObjectPropertyAtPut(JSRegExp::kLastIndexFieldIndex,
1022                                  Smi::FromInt(0),
1023                                  SKIP_WRITE_BARRIER);  // It's a Smi.
1024     initial_map->set_prototype(*proto);
1025     factory->SetRegExpIrregexpData(Handle<JSRegExp>::cast(proto),
1026                                    JSRegExp::IRREGEXP, factory->empty_string(),
1027                                    JSRegExp::Flags(0), 0);
1028   }
1029 
1030   {  // -- J S O N
1031     Handle<String> name = factory->NewStringFromAscii(CStrVector("JSON"));
1032     Handle<JSFunction> cons = factory->NewFunction(name,
1033                                                    factory->the_hole_value());
1034     { MaybeObject* result = cons->SetInstancePrototype(
1035         global_context()->initial_object_prototype());
1036       if (result->IsFailure()) return false;
1037     }
1038     cons->SetInstanceClassName(*name);
1039     Handle<JSObject> json_object = factory->NewJSObject(cons, TENURED);
1040     ASSERT(json_object->IsJSObject());
1041     CHECK_NOT_EMPTY_HANDLE(isolate,
1042                            JSObject::SetLocalPropertyIgnoreAttributes(
1043                                  global, name, json_object, DONT_ENUM));
1044     global_context()->set_json_object(*json_object);
1045   }
1046 
1047   {  // --- arguments_boilerplate_
1048     // Make sure we can recognize argument objects at runtime.
1049     // This is done by introducing an anonymous function with
1050     // class_name equals 'Arguments'.
1051     Handle<String> symbol = factory->LookupAsciiSymbol("Arguments");
1052     Handle<Code> code = Handle<Code>(
1053         isolate->builtins()->builtin(Builtins::kIllegal));
1054     Handle<JSObject> prototype =
1055         Handle<JSObject>(
1056             JSObject::cast(global_context()->object_function()->prototype()));
1057 
1058     Handle<JSFunction> function =
1059         factory->NewFunctionWithPrototype(symbol,
1060                                           JS_OBJECT_TYPE,
1061                                           JSObject::kHeaderSize,
1062                                           prototype,
1063                                           code,
1064                                           false);
1065     ASSERT(!function->has_initial_map());
1066     function->shared()->set_instance_class_name(*symbol);
1067     function->shared()->set_expected_nof_properties(2);
1068     Handle<JSObject> result = factory->NewJSObject(function);
1069 
1070     global_context()->set_arguments_boilerplate(*result);
1071     // Note: length must be added as the first property and
1072     //       callee must be added as the second property.
1073     CHECK_NOT_EMPTY_HANDLE(isolate,
1074                            JSObject::SetLocalPropertyIgnoreAttributes(
1075                                result, factory->length_symbol(),
1076                                factory->undefined_value(), DONT_ENUM));
1077     CHECK_NOT_EMPTY_HANDLE(isolate,
1078                            JSObject::SetLocalPropertyIgnoreAttributes(
1079                                result, factory->callee_symbol(),
1080                                factory->undefined_value(), DONT_ENUM));
1081 
1082 #ifdef DEBUG
1083     LookupResult lookup(isolate);
1084     result->LocalLookup(heap->callee_symbol(), &lookup);
1085     ASSERT(lookup.IsFound() && (lookup.type() == FIELD));
1086     ASSERT(lookup.GetFieldIndex() == Heap::kArgumentsCalleeIndex);
1087 
1088     result->LocalLookup(heap->length_symbol(), &lookup);
1089     ASSERT(lookup.IsFound() && (lookup.type() == FIELD));
1090     ASSERT(lookup.GetFieldIndex() == Heap::kArgumentsLengthIndex);
1091 
1092     ASSERT(result->map()->inobject_properties() > Heap::kArgumentsCalleeIndex);
1093     ASSERT(result->map()->inobject_properties() > Heap::kArgumentsLengthIndex);
1094 
1095     // Check the state of the object.
1096     ASSERT(result->HasFastProperties());
1097     ASSERT(result->HasFastElements());
1098 #endif
1099   }
1100 
1101   {  // --- aliased_arguments_boilerplate_
1102     // Set up a well-formed parameter map to make assertions happy.
1103     Handle<FixedArray> elements = factory->NewFixedArray(2);
1104     elements->set_map(heap->non_strict_arguments_elements_map());
1105     Handle<FixedArray> array;
1106     array = factory->NewFixedArray(0);
1107     elements->set(0, *array);
1108     array = factory->NewFixedArray(0);
1109     elements->set(1, *array);
1110 
1111     Handle<Map> old_map(global_context()->arguments_boilerplate()->map());
1112     Handle<Map> new_map = factory->CopyMapDropTransitions(old_map);
1113     new_map->set_pre_allocated_property_fields(2);
1114     Handle<JSObject> result = factory->NewJSObjectFromMap(new_map);
1115     // Set elements kind after allocating the object because
1116     // NewJSObjectFromMap assumes a fast elements map.
1117     new_map->set_elements_kind(NON_STRICT_ARGUMENTS_ELEMENTS);
1118     result->set_elements(*elements);
1119     ASSERT(result->HasNonStrictArgumentsElements());
1120     global_context()->set_aliased_arguments_boilerplate(*result);
1121   }
1122 
1123   {  // --- strict mode arguments boilerplate
1124     const PropertyAttributes attributes =
1125       static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
1126 
1127     // Create the ThrowTypeError functions.
1128     Handle<AccessorPair> callee = factory->NewAccessorPair();
1129     Handle<AccessorPair> caller = factory->NewAccessorPair();
1130 
1131     Handle<JSFunction> throw_function =
1132         GetThrowTypeErrorFunction();
1133 
1134     // Install the ThrowTypeError functions.
1135     callee->set_getter(*throw_function);
1136     callee->set_setter(*throw_function);
1137     caller->set_getter(*throw_function);
1138     caller->set_setter(*throw_function);
1139 
1140     // Create the descriptor array for the arguments object.
1141     Handle<DescriptorArray> descriptors = factory->NewDescriptorArray(3);
1142     DescriptorArray::WhitenessWitness witness(*descriptors);
1143     {  // length
1144       FieldDescriptor d(*factory->length_symbol(), 0, DONT_ENUM);
1145       descriptors->Set(0, &d, witness);
1146     }
1147     {  // callee
1148       CallbacksDescriptor d(*factory->callee_symbol(), *callee, attributes);
1149       descriptors->Set(1, &d, witness);
1150     }
1151     {  // caller
1152       CallbacksDescriptor d(*factory->caller_symbol(), *caller, attributes);
1153       descriptors->Set(2, &d, witness);
1154     }
1155     descriptors->Sort(witness);
1156 
1157     // Create the map. Allocate one in-object field for length.
1158     Handle<Map> map = factory->NewMap(JS_OBJECT_TYPE,
1159                                       Heap::kArgumentsObjectSizeStrict);
1160     map->set_instance_descriptors(*descriptors);
1161     map->set_function_with_prototype(true);
1162     map->set_prototype(global_context()->object_function()->prototype());
1163     map->set_pre_allocated_property_fields(1);
1164     map->set_inobject_properties(1);
1165 
1166     // Copy constructor from the non-strict arguments boilerplate.
1167     map->set_constructor(
1168       global_context()->arguments_boilerplate()->map()->constructor());
1169 
1170     // Allocate the arguments boilerplate object.
1171     Handle<JSObject> result = factory->NewJSObjectFromMap(map);
1172     global_context()->set_strict_mode_arguments_boilerplate(*result);
1173 
1174     // Add length property only for strict mode boilerplate.
1175     CHECK_NOT_EMPTY_HANDLE(isolate,
1176                            JSObject::SetLocalPropertyIgnoreAttributes(
1177                                result, factory->length_symbol(),
1178                                factory->undefined_value(), DONT_ENUM));
1179 
1180 #ifdef DEBUG
1181     LookupResult lookup(isolate);
1182     result->LocalLookup(heap->length_symbol(), &lookup);
1183     ASSERT(lookup.IsFound() && (lookup.type() == FIELD));
1184     ASSERT(lookup.GetFieldIndex() == Heap::kArgumentsLengthIndex);
1185 
1186     ASSERT(result->map()->inobject_properties() > Heap::kArgumentsLengthIndex);
1187 
1188     // Check the state of the object.
1189     ASSERT(result->HasFastProperties());
1190     ASSERT(result->HasFastElements());
1191 #endif
1192   }
1193 
1194   {  // --- context extension
1195     // Create a function for the context extension objects.
1196     Handle<Code> code = Handle<Code>(
1197         isolate->builtins()->builtin(Builtins::kIllegal));
1198     Handle<JSFunction> context_extension_fun =
1199         factory->NewFunction(factory->empty_symbol(),
1200                              JS_CONTEXT_EXTENSION_OBJECT_TYPE,
1201                              JSObject::kHeaderSize,
1202                              code,
1203                              true);
1204 
1205     Handle<String> name = factory->LookupAsciiSymbol("context_extension");
1206     context_extension_fun->shared()->set_instance_class_name(*name);
1207     global_context()->set_context_extension_function(*context_extension_fun);
1208   }
1209 
1210 
1211   {
1212     // Set up the call-as-function delegate.
1213     Handle<Code> code =
1214         Handle<Code>(isolate->builtins()->builtin(
1215             Builtins::kHandleApiCallAsFunction));
1216     Handle<JSFunction> delegate =
1217         factory->NewFunction(factory->empty_symbol(), JS_OBJECT_TYPE,
1218                              JSObject::kHeaderSize, code, true);
1219     global_context()->set_call_as_function_delegate(*delegate);
1220     delegate->shared()->DontAdaptArguments();
1221   }
1222 
1223   {
1224     // Set up the call-as-constructor delegate.
1225     Handle<Code> code =
1226         Handle<Code>(isolate->builtins()->builtin(
1227             Builtins::kHandleApiCallAsConstructor));
1228     Handle<JSFunction> delegate =
1229         factory->NewFunction(factory->empty_symbol(), JS_OBJECT_TYPE,
1230                              JSObject::kHeaderSize, code, true);
1231     global_context()->set_call_as_constructor_delegate(*delegate);
1232     delegate->shared()->DontAdaptArguments();
1233   }
1234 
1235   // Initialize the out of memory slot.
1236   global_context()->set_out_of_memory(heap->false_value());
1237 
1238   // Initialize the data slot.
1239   global_context()->set_data(heap->undefined_value());
1240 
1241   {
1242     // Initialize the random seed slot.
1243     Handle<ByteArray> zeroed_byte_array(
1244         factory->NewByteArray(kRandomStateSize));
1245     global_context()->set_random_seed(*zeroed_byte_array);
1246     memset(zeroed_byte_array->GetDataStartAddress(), 0, kRandomStateSize);
1247   }
1248   return true;
1249 }
1250 
1251 
InitializeExperimentalGlobal()1252 void Genesis::InitializeExperimentalGlobal() {
1253   Handle<JSObject> global = Handle<JSObject>(global_context()->global());
1254 
1255   // TODO(mstarzinger): Move this into Genesis::InitializeGlobal once we no
1256   // longer need to live behind a flag, so functions get added to the snapshot.
1257   if (FLAG_harmony_collections) {
1258     {  // -- S e t
1259       Handle<JSObject> prototype =
1260           factory()->NewJSObject(isolate()->object_function(), TENURED);
1261       InstallFunction(global, "Set", JS_SET_TYPE, JSSet::kSize,
1262                       prototype, Builtins::kIllegal, true);
1263     }
1264     {  // -- M a p
1265       Handle<JSObject> prototype =
1266           factory()->NewJSObject(isolate()->object_function(), TENURED);
1267       InstallFunction(global, "Map", JS_MAP_TYPE, JSMap::kSize,
1268                       prototype, Builtins::kIllegal, true);
1269     }
1270     {  // -- W e a k M a p
1271       Handle<JSObject> prototype =
1272           factory()->NewJSObject(isolate()->object_function(), TENURED);
1273       InstallFunction(global, "WeakMap", JS_WEAK_MAP_TYPE, JSWeakMap::kSize,
1274                       prototype, Builtins::kIllegal, true);
1275     }
1276   }
1277 }
1278 
1279 
CompileBuiltin(Isolate * isolate,int index)1280 bool Genesis::CompileBuiltin(Isolate* isolate, int index) {
1281   Vector<const char> name = Natives::GetScriptName(index);
1282   Handle<String> source_code =
1283       isolate->bootstrapper()->NativesSourceLookup(index);
1284   return CompileNative(name, source_code);
1285 }
1286 
1287 
CompileExperimentalBuiltin(Isolate * isolate,int index)1288 bool Genesis::CompileExperimentalBuiltin(Isolate* isolate, int index) {
1289   Vector<const char> name = ExperimentalNatives::GetScriptName(index);
1290   Factory* factory = isolate->factory();
1291   Handle<String> source_code =
1292       factory->NewStringFromAscii(
1293           ExperimentalNatives::GetRawScriptSource(index));
1294   return CompileNative(name, source_code);
1295 }
1296 
1297 
CompileNative(Vector<const char> name,Handle<String> source)1298 bool Genesis::CompileNative(Vector<const char> name, Handle<String> source) {
1299   HandleScope scope;
1300   Isolate* isolate = source->GetIsolate();
1301 #ifdef ENABLE_DEBUGGER_SUPPORT
1302   isolate->debugger()->set_compiling_natives(true);
1303 #endif
1304   // During genesis, the boilerplate for stack overflow won't work until the
1305   // environment has been at least partially initialized. Add a stack check
1306   // before entering JS code to catch overflow early.
1307   StackLimitCheck check(Isolate::Current());
1308   if (check.HasOverflowed()) return false;
1309 
1310   bool result = CompileScriptCached(name,
1311                                     source,
1312                                     NULL,
1313                                     NULL,
1314                                     Handle<Context>(isolate->context()),
1315                                     true);
1316   ASSERT(isolate->has_pending_exception() != result);
1317   if (!result) isolate->clear_pending_exception();
1318 #ifdef ENABLE_DEBUGGER_SUPPORT
1319   isolate->debugger()->set_compiling_natives(false);
1320 #endif
1321   return result;
1322 }
1323 
1324 
CompileScriptCached(Vector<const char> name,Handle<String> source,SourceCodeCache * cache,v8::Extension * extension,Handle<Context> top_context,bool use_runtime_context)1325 bool Genesis::CompileScriptCached(Vector<const char> name,
1326                                   Handle<String> source,
1327                                   SourceCodeCache* cache,
1328                                   v8::Extension* extension,
1329                                   Handle<Context> top_context,
1330                                   bool use_runtime_context) {
1331   Factory* factory = source->GetIsolate()->factory();
1332   HandleScope scope;
1333   Handle<SharedFunctionInfo> function_info;
1334 
1335   // If we can't find the function in the cache, we compile a new
1336   // function and insert it into the cache.
1337   if (cache == NULL || !cache->Lookup(name, &function_info)) {
1338     ASSERT(source->IsAsciiRepresentation());
1339     Handle<String> script_name = factory->NewStringFromUtf8(name);
1340     function_info = Compiler::Compile(
1341         source,
1342         script_name,
1343         0,
1344         0,
1345         extension,
1346         NULL,
1347         Handle<String>::null(),
1348         use_runtime_context ? NATIVES_CODE : NOT_NATIVES_CODE);
1349     if (function_info.is_null()) return false;
1350     if (cache != NULL) cache->Add(name, function_info);
1351   }
1352 
1353   // Set up the function context. Conceptually, we should clone the
1354   // function before overwriting the context but since we're in a
1355   // single-threaded environment it is not strictly necessary.
1356   ASSERT(top_context->IsGlobalContext());
1357   Handle<Context> context =
1358       Handle<Context>(use_runtime_context
1359                       ? Handle<Context>(top_context->runtime_context())
1360                       : top_context);
1361   Handle<JSFunction> fun =
1362       factory->NewFunctionFromSharedFunctionInfo(function_info, context);
1363 
1364   // Call function using either the runtime object or the global
1365   // object as the receiver. Provide no parameters.
1366   Handle<Object> receiver =
1367       Handle<Object>(use_runtime_context
1368                      ? top_context->builtins()
1369                      : top_context->global());
1370   bool has_pending_exception;
1371   Execution::Call(fun, receiver, 0, NULL, &has_pending_exception);
1372   if (has_pending_exception) return false;
1373   return true;
1374 }
1375 
1376 
1377 #define INSTALL_NATIVE(Type, name, var)                                       \
1378   Handle<String> var##_name = factory()->LookupAsciiSymbol(name);             \
1379   Object* var##_native =                                                      \
1380       global_context()->builtins()->GetPropertyNoExceptionThrown(             \
1381            *var##_name);                                                      \
1382   global_context()->set_##var(Type::cast(var##_native));
1383 
1384 
InstallNativeFunctions()1385 void Genesis::InstallNativeFunctions() {
1386   HandleScope scope;
1387   INSTALL_NATIVE(JSFunction, "CreateDate", create_date_fun);
1388   INSTALL_NATIVE(JSFunction, "ToNumber", to_number_fun);
1389   INSTALL_NATIVE(JSFunction, "ToString", to_string_fun);
1390   INSTALL_NATIVE(JSFunction, "ToDetailString", to_detail_string_fun);
1391   INSTALL_NATIVE(JSFunction, "ToObject", to_object_fun);
1392   INSTALL_NATIVE(JSFunction, "ToInteger", to_integer_fun);
1393   INSTALL_NATIVE(JSFunction, "ToUint32", to_uint32_fun);
1394   INSTALL_NATIVE(JSFunction, "ToInt32", to_int32_fun);
1395   INSTALL_NATIVE(JSFunction, "GlobalEval", global_eval_fun);
1396   INSTALL_NATIVE(JSFunction, "Instantiate", instantiate_fun);
1397   INSTALL_NATIVE(JSFunction, "ConfigureTemplateInstance",
1398                  configure_instance_fun);
1399   INSTALL_NATIVE(JSFunction, "GetStackTraceLine", get_stack_trace_line_fun);
1400   INSTALL_NATIVE(JSObject, "functionCache", function_cache);
1401   INSTALL_NATIVE(JSFunction, "ToCompletePropertyDescriptor",
1402                  to_complete_property_descriptor);
1403 }
1404 
InstallExperimentalNativeFunctions()1405 void Genesis::InstallExperimentalNativeFunctions() {
1406   if (FLAG_harmony_proxies) {
1407     INSTALL_NATIVE(JSFunction, "DerivedHasTrap", derived_has_trap);
1408     INSTALL_NATIVE(JSFunction, "DerivedGetTrap", derived_get_trap);
1409     INSTALL_NATIVE(JSFunction, "DerivedSetTrap", derived_set_trap);
1410     INSTALL_NATIVE(JSFunction, "ProxyEnumerate", proxy_enumerate);
1411   }
1412 }
1413 
1414 #undef INSTALL_NATIVE
1415 
1416 
InstallNatives()1417 bool Genesis::InstallNatives() {
1418   HandleScope scope;
1419 
1420   // Create a function for the builtins object. Allocate space for the
1421   // JavaScript builtins, a reference to the builtins object
1422   // (itself) and a reference to the global_context directly in the object.
1423   Handle<Code> code = Handle<Code>(
1424       isolate()->builtins()->builtin(Builtins::kIllegal));
1425   Handle<JSFunction> builtins_fun =
1426       factory()->NewFunction(factory()->empty_symbol(),
1427                              JS_BUILTINS_OBJECT_TYPE,
1428                              JSBuiltinsObject::kSize, code, true);
1429 
1430   Handle<String> name = factory()->LookupAsciiSymbol("builtins");
1431   builtins_fun->shared()->set_instance_class_name(*name);
1432 
1433   // Allocate the builtins object.
1434   Handle<JSBuiltinsObject> builtins =
1435       Handle<JSBuiltinsObject>::cast(factory()->NewGlobalObject(builtins_fun));
1436   builtins->set_builtins(*builtins);
1437   builtins->set_global_context(*global_context());
1438   builtins->set_global_receiver(*builtins);
1439 
1440   // Set up the 'global' properties of the builtins object. The
1441   // 'global' property that refers to the global object is the only
1442   // way to get from code running in the builtins context to the
1443   // global object.
1444   static const PropertyAttributes attributes =
1445       static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE);
1446   Handle<String> global_symbol = factory()->LookupAsciiSymbol("global");
1447   Handle<Object> global_obj(global_context()->global());
1448   CHECK_NOT_EMPTY_HANDLE(isolate(),
1449                          JSObject::SetLocalPropertyIgnoreAttributes(
1450                              builtins, global_symbol, global_obj, attributes));
1451 
1452   // Set up the reference from the global object to the builtins object.
1453   JSGlobalObject::cast(global_context()->global())->set_builtins(*builtins);
1454 
1455   // Create a bridge function that has context in the global context.
1456   Handle<JSFunction> bridge =
1457       factory()->NewFunction(factory()->empty_symbol(),
1458                              factory()->undefined_value());
1459   ASSERT(bridge->context() == *isolate()->global_context());
1460 
1461   // Allocate the builtins context.
1462   Handle<Context> context =
1463     factory()->NewFunctionContext(Context::MIN_CONTEXT_SLOTS, bridge);
1464   context->set_global(*builtins);  // override builtins global object
1465 
1466   global_context()->set_runtime_context(*context);
1467 
1468   {  // -- S c r i p t
1469     // Builtin functions for Script.
1470     Handle<JSFunction> script_fun =
1471         InstallFunction(builtins, "Script", JS_VALUE_TYPE, JSValue::kSize,
1472                         isolate()->initial_object_prototype(),
1473                         Builtins::kIllegal, false);
1474     Handle<JSObject> prototype =
1475         factory()->NewJSObject(isolate()->object_function(), TENURED);
1476     SetPrototype(script_fun, prototype);
1477     global_context()->set_script_function(*script_fun);
1478 
1479     // Add 'source' and 'data' property to scripts.
1480     PropertyAttributes common_attributes =
1481         static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
1482     Handle<Foreign> foreign_source =
1483         factory()->NewForeign(&Accessors::ScriptSource);
1484     Handle<DescriptorArray> script_descriptors =
1485         factory()->CopyAppendForeignDescriptor(
1486             factory()->empty_descriptor_array(),
1487             factory()->LookupAsciiSymbol("source"),
1488             foreign_source,
1489             common_attributes);
1490     Handle<Foreign> foreign_name =
1491         factory()->NewForeign(&Accessors::ScriptName);
1492     script_descriptors =
1493         factory()->CopyAppendForeignDescriptor(
1494             script_descriptors,
1495             factory()->LookupAsciiSymbol("name"),
1496             foreign_name,
1497             common_attributes);
1498     Handle<Foreign> foreign_id = factory()->NewForeign(&Accessors::ScriptId);
1499     script_descriptors =
1500         factory()->CopyAppendForeignDescriptor(
1501             script_descriptors,
1502             factory()->LookupAsciiSymbol("id"),
1503             foreign_id,
1504             common_attributes);
1505     Handle<Foreign> foreign_line_offset =
1506         factory()->NewForeign(&Accessors::ScriptLineOffset);
1507     script_descriptors =
1508         factory()->CopyAppendForeignDescriptor(
1509             script_descriptors,
1510             factory()->LookupAsciiSymbol("line_offset"),
1511             foreign_line_offset,
1512             common_attributes);
1513     Handle<Foreign> foreign_column_offset =
1514         factory()->NewForeign(&Accessors::ScriptColumnOffset);
1515     script_descriptors =
1516         factory()->CopyAppendForeignDescriptor(
1517             script_descriptors,
1518             factory()->LookupAsciiSymbol("column_offset"),
1519             foreign_column_offset,
1520             common_attributes);
1521     Handle<Foreign> foreign_data =
1522         factory()->NewForeign(&Accessors::ScriptData);
1523     script_descriptors =
1524         factory()->CopyAppendForeignDescriptor(
1525             script_descriptors,
1526             factory()->LookupAsciiSymbol("data"),
1527             foreign_data,
1528             common_attributes);
1529     Handle<Foreign> foreign_type =
1530         factory()->NewForeign(&Accessors::ScriptType);
1531     script_descriptors =
1532         factory()->CopyAppendForeignDescriptor(
1533             script_descriptors,
1534             factory()->LookupAsciiSymbol("type"),
1535             foreign_type,
1536             common_attributes);
1537     Handle<Foreign> foreign_compilation_type =
1538         factory()->NewForeign(&Accessors::ScriptCompilationType);
1539     script_descriptors =
1540         factory()->CopyAppendForeignDescriptor(
1541             script_descriptors,
1542             factory()->LookupAsciiSymbol("compilation_type"),
1543             foreign_compilation_type,
1544             common_attributes);
1545     Handle<Foreign> foreign_line_ends =
1546         factory()->NewForeign(&Accessors::ScriptLineEnds);
1547     script_descriptors =
1548         factory()->CopyAppendForeignDescriptor(
1549             script_descriptors,
1550             factory()->LookupAsciiSymbol("line_ends"),
1551             foreign_line_ends,
1552             common_attributes);
1553     Handle<Foreign> foreign_context_data =
1554         factory()->NewForeign(&Accessors::ScriptContextData);
1555     script_descriptors =
1556         factory()->CopyAppendForeignDescriptor(
1557             script_descriptors,
1558             factory()->LookupAsciiSymbol("context_data"),
1559             foreign_context_data,
1560             common_attributes);
1561     Handle<Foreign> foreign_eval_from_script =
1562         factory()->NewForeign(&Accessors::ScriptEvalFromScript);
1563     script_descriptors =
1564         factory()->CopyAppendForeignDescriptor(
1565             script_descriptors,
1566             factory()->LookupAsciiSymbol("eval_from_script"),
1567             foreign_eval_from_script,
1568             common_attributes);
1569     Handle<Foreign> foreign_eval_from_script_position =
1570         factory()->NewForeign(&Accessors::ScriptEvalFromScriptPosition);
1571     script_descriptors =
1572         factory()->CopyAppendForeignDescriptor(
1573             script_descriptors,
1574             factory()->LookupAsciiSymbol("eval_from_script_position"),
1575             foreign_eval_from_script_position,
1576             common_attributes);
1577     Handle<Foreign> foreign_eval_from_function_name =
1578         factory()->NewForeign(&Accessors::ScriptEvalFromFunctionName);
1579     script_descriptors =
1580         factory()->CopyAppendForeignDescriptor(
1581             script_descriptors,
1582             factory()->LookupAsciiSymbol("eval_from_function_name"),
1583             foreign_eval_from_function_name,
1584             common_attributes);
1585 
1586     Handle<Map> script_map = Handle<Map>(script_fun->initial_map());
1587     script_map->set_instance_descriptors(*script_descriptors);
1588 
1589     // Allocate the empty script.
1590     Handle<Script> script = factory()->NewScript(factory()->empty_string());
1591     script->set_type(Smi::FromInt(Script::TYPE_NATIVE));
1592     heap()->public_set_empty_script(*script);
1593   }
1594   {
1595     // Builtin function for OpaqueReference -- a JSValue-based object,
1596     // that keeps its field isolated from JavaScript code. It may store
1597     // objects, that JavaScript code may not access.
1598     Handle<JSFunction> opaque_reference_fun =
1599         InstallFunction(builtins, "OpaqueReference", JS_VALUE_TYPE,
1600                         JSValue::kSize,
1601                         isolate()->initial_object_prototype(),
1602                         Builtins::kIllegal, false);
1603     Handle<JSObject> prototype =
1604         factory()->NewJSObject(isolate()->object_function(), TENURED);
1605     SetPrototype(opaque_reference_fun, prototype);
1606     global_context()->set_opaque_reference_function(*opaque_reference_fun);
1607   }
1608 
1609   {  // --- I n t e r n a l   A r r a y ---
1610     // An array constructor on the builtins object that works like
1611     // the public Array constructor, except that its prototype
1612     // doesn't inherit from Object.prototype.
1613     // To be used only for internal work by builtins. Instances
1614     // must not be leaked to user code.
1615     Handle<JSFunction> array_function =
1616         InstallFunction(builtins,
1617                         "InternalArray",
1618                         JS_ARRAY_TYPE,
1619                         JSArray::kSize,
1620                         isolate()->initial_object_prototype(),
1621                         Builtins::kInternalArrayCode,
1622                         true);
1623     Handle<JSObject> prototype =
1624         factory()->NewJSObject(isolate()->object_function(), TENURED);
1625     SetPrototype(array_function, prototype);
1626 
1627     array_function->shared()->set_construct_stub(
1628         isolate()->builtins()->builtin(Builtins::kArrayConstructCode));
1629     array_function->shared()->DontAdaptArguments();
1630 
1631     // InternalArrays should not use Smi-Only array optimizations. There are too
1632     // many places in the C++ runtime code (e.g. RegEx) that assume that
1633     // elements in InternalArrays can be set to non-Smi values without going
1634     // through a common bottleneck that would make the SMI_ONLY -> FAST_ELEMENT
1635     // transition easy to trap. Moreover, they rarely are smi-only.
1636     MaybeObject* maybe_map =
1637         array_function->initial_map()->CopyDropTransitions();
1638     Map* new_map;
1639     if (!maybe_map->To<Map>(&new_map)) return false;
1640     new_map->set_elements_kind(FAST_ELEMENTS);
1641     array_function->set_initial_map(new_map);
1642 
1643     // Make "length" magic on instances.
1644     Handle<DescriptorArray> array_descriptors =
1645         factory()->CopyAppendForeignDescriptor(
1646             factory()->empty_descriptor_array(),
1647             factory()->length_symbol(),
1648             factory()->NewForeign(&Accessors::ArrayLength),
1649             static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE));
1650 
1651     array_function->initial_map()->set_instance_descriptors(
1652         *array_descriptors);
1653 
1654     global_context()->set_internal_array_function(*array_function);
1655   }
1656 
1657   if (FLAG_disable_native_files) {
1658     PrintF("Warning: Running without installed natives!\n");
1659     return true;
1660   }
1661 
1662   // Install natives.
1663   for (int i = Natives::GetDebuggerCount();
1664        i < Natives::GetBuiltinsCount();
1665        i++) {
1666     if (!CompileBuiltin(isolate(), i)) return false;
1667     // TODO(ager): We really only need to install the JS builtin
1668     // functions on the builtins object after compiling and running
1669     // runtime.js.
1670     if (!InstallJSBuiltins(builtins)) return false;
1671   }
1672 
1673   InstallNativeFunctions();
1674 
1675   // Store the map for the string prototype after the natives has been compiled
1676   // and the String function has been set up.
1677   Handle<JSFunction> string_function(global_context()->string_function());
1678   ASSERT(JSObject::cast(
1679       string_function->initial_map()->prototype())->HasFastProperties());
1680   global_context()->set_string_function_prototype_map(
1681       HeapObject::cast(string_function->initial_map()->prototype())->map());
1682 
1683   // Install Function.prototype.call and apply.
1684   { Handle<String> key = factory()->function_class_symbol();
1685     Handle<JSFunction> function =
1686         Handle<JSFunction>::cast(GetProperty(isolate()->global(), key));
1687     Handle<JSObject> proto =
1688         Handle<JSObject>(JSObject::cast(function->instance_prototype()));
1689 
1690     // Install the call and the apply functions.
1691     Handle<JSFunction> call =
1692         InstallFunction(proto, "call", JS_OBJECT_TYPE, JSObject::kHeaderSize,
1693                         Handle<JSObject>::null(),
1694                         Builtins::kFunctionCall,
1695                         false);
1696     Handle<JSFunction> apply =
1697         InstallFunction(proto, "apply", JS_OBJECT_TYPE, JSObject::kHeaderSize,
1698                         Handle<JSObject>::null(),
1699                         Builtins::kFunctionApply,
1700                         false);
1701 
1702     // Make sure that Function.prototype.call appears to be compiled.
1703     // The code will never be called, but inline caching for call will
1704     // only work if it appears to be compiled.
1705     call->shared()->DontAdaptArguments();
1706     ASSERT(call->is_compiled());
1707 
1708     // Set the expected parameters for apply to 2; required by builtin.
1709     apply->shared()->set_formal_parameter_count(2);
1710 
1711     // Set the lengths for the functions to satisfy ECMA-262.
1712     call->shared()->set_length(1);
1713     apply->shared()->set_length(2);
1714   }
1715 
1716   InstallBuiltinFunctionIds();
1717 
1718   // Create a constructor for RegExp results (a variant of Array that
1719   // predefines the two properties index and match).
1720   {
1721     // RegExpResult initial map.
1722 
1723     // Find global.Array.prototype to inherit from.
1724     Handle<JSFunction> array_constructor(global_context()->array_function());
1725     Handle<JSObject> array_prototype(
1726         JSObject::cast(array_constructor->instance_prototype()));
1727 
1728     // Add initial map.
1729     Handle<Map> initial_map =
1730         factory()->NewMap(JS_ARRAY_TYPE, JSRegExpResult::kSize);
1731     initial_map->set_constructor(*array_constructor);
1732 
1733     // Set prototype on map.
1734     initial_map->set_non_instance_prototype(false);
1735     initial_map->set_prototype(*array_prototype);
1736 
1737     // Update map with length accessor from Array and add "index" and "input".
1738     Handle<DescriptorArray> reresult_descriptors =
1739         factory()->NewDescriptorArray(3);
1740     DescriptorArray::WhitenessWitness witness(*reresult_descriptors);
1741 
1742     JSFunction* array_function = global_context()->array_function();
1743     Handle<DescriptorArray> array_descriptors(
1744         array_function->initial_map()->instance_descriptors());
1745     int index = array_descriptors->SearchWithCache(heap()->length_symbol());
1746     MaybeObject* copy_result =
1747         reresult_descriptors->CopyFrom(0, *array_descriptors, index, witness);
1748     if (copy_result->IsFailure()) return false;
1749 
1750     int enum_index = 0;
1751     {
1752       FieldDescriptor index_field(heap()->index_symbol(),
1753                                   JSRegExpResult::kIndexIndex,
1754                                   NONE,
1755                                   enum_index++);
1756       reresult_descriptors->Set(1, &index_field, witness);
1757     }
1758 
1759     {
1760       FieldDescriptor input_field(heap()->input_symbol(),
1761                                   JSRegExpResult::kInputIndex,
1762                                   NONE,
1763                                   enum_index++);
1764       reresult_descriptors->Set(2, &input_field, witness);
1765     }
1766     reresult_descriptors->Sort(witness);
1767 
1768     initial_map->set_inobject_properties(2);
1769     initial_map->set_pre_allocated_property_fields(2);
1770     initial_map->set_unused_property_fields(0);
1771     initial_map->set_instance_descriptors(*reresult_descriptors);
1772 
1773     global_context()->set_regexp_result_map(*initial_map);
1774   }
1775 
1776 #ifdef DEBUG
1777   builtins->Verify();
1778 #endif
1779 
1780   return true;
1781 }
1782 
1783 
InstallExperimentalNatives()1784 bool Genesis::InstallExperimentalNatives() {
1785   for (int i = ExperimentalNatives::GetDebuggerCount();
1786        i < ExperimentalNatives::GetBuiltinsCount();
1787        i++) {
1788     if (FLAG_harmony_proxies &&
1789         strcmp(ExperimentalNatives::GetScriptName(i).start(),
1790                "native proxy.js") == 0) {
1791       if (!CompileExperimentalBuiltin(isolate(), i)) return false;
1792     }
1793     if (FLAG_harmony_collections &&
1794         strcmp(ExperimentalNatives::GetScriptName(i).start(),
1795                "native collection.js") == 0) {
1796       if (!CompileExperimentalBuiltin(isolate(), i)) return false;
1797     }
1798   }
1799 
1800   InstallExperimentalNativeFunctions();
1801 
1802   return true;
1803 }
1804 
1805 
ResolveBuiltinIdHolder(Handle<Context> global_context,const char * holder_expr)1806 static Handle<JSObject> ResolveBuiltinIdHolder(
1807     Handle<Context> global_context,
1808     const char* holder_expr) {
1809   Factory* factory = global_context->GetIsolate()->factory();
1810   Handle<GlobalObject> global(global_context->global());
1811   const char* period_pos = strchr(holder_expr, '.');
1812   if (period_pos == NULL) {
1813     return Handle<JSObject>::cast(
1814         GetProperty(global, factory->LookupAsciiSymbol(holder_expr)));
1815   }
1816   ASSERT_EQ(".prototype", period_pos);
1817   Vector<const char> property(holder_expr,
1818                               static_cast<int>(period_pos - holder_expr));
1819   Handle<JSFunction> function = Handle<JSFunction>::cast(
1820       GetProperty(global, factory->LookupSymbol(property)));
1821   return Handle<JSObject>(JSObject::cast(function->prototype()));
1822 }
1823 
1824 
InstallBuiltinFunctionId(Handle<JSObject> holder,const char * function_name,BuiltinFunctionId id)1825 static void InstallBuiltinFunctionId(Handle<JSObject> holder,
1826                                      const char* function_name,
1827                                      BuiltinFunctionId id) {
1828   Factory* factory = holder->GetIsolate()->factory();
1829   Handle<String> name = factory->LookupAsciiSymbol(function_name);
1830   Object* function_object = holder->GetProperty(*name)->ToObjectUnchecked();
1831   Handle<JSFunction> function(JSFunction::cast(function_object));
1832   function->shared()->set_function_data(Smi::FromInt(id));
1833 }
1834 
1835 
InstallBuiltinFunctionIds()1836 void Genesis::InstallBuiltinFunctionIds() {
1837   HandleScope scope;
1838 #define INSTALL_BUILTIN_ID(holder_expr, fun_name, name) \
1839   {                                                     \
1840     Handle<JSObject> holder = ResolveBuiltinIdHolder(   \
1841         global_context(), #holder_expr);                \
1842     BuiltinFunctionId id = k##name;                     \
1843     InstallBuiltinFunctionId(holder, #fun_name, id);    \
1844   }
1845   FUNCTIONS_WITH_ID_LIST(INSTALL_BUILTIN_ID)
1846 #undef INSTALL_BUILTIN_ID
1847 }
1848 
1849 
1850 // Do not forget to update macros.py with named constant
1851 // of cache id.
1852 #define JSFUNCTION_RESULT_CACHE_LIST(F) \
1853   F(16, global_context()->regexp_function())
1854 
1855 
CreateCache(int size,Handle<JSFunction> factory_function)1856 static FixedArray* CreateCache(int size, Handle<JSFunction> factory_function) {
1857   Factory* factory = factory_function->GetIsolate()->factory();
1858   // Caches are supposed to live for a long time, allocate in old space.
1859   int array_size = JSFunctionResultCache::kEntriesIndex + 2 * size;
1860   // Cannot use cast as object is not fully initialized yet.
1861   JSFunctionResultCache* cache = reinterpret_cast<JSFunctionResultCache*>(
1862       *factory->NewFixedArrayWithHoles(array_size, TENURED));
1863   cache->set(JSFunctionResultCache::kFactoryIndex, *factory_function);
1864   cache->MakeZeroSize();
1865   return cache;
1866 }
1867 
1868 
InstallJSFunctionResultCaches()1869 void Genesis::InstallJSFunctionResultCaches() {
1870   const int kNumberOfCaches = 0 +
1871 #define F(size, func) + 1
1872     JSFUNCTION_RESULT_CACHE_LIST(F)
1873 #undef F
1874   ;
1875 
1876   Handle<FixedArray> caches = FACTORY->NewFixedArray(kNumberOfCaches, TENURED);
1877 
1878   int index = 0;
1879 
1880 #define F(size, func) do {                                              \
1881     FixedArray* cache = CreateCache((size), Handle<JSFunction>(func));  \
1882     caches->set(index++, cache);                                        \
1883   } while (false)
1884 
1885   JSFUNCTION_RESULT_CACHE_LIST(F);
1886 
1887 #undef F
1888 
1889   global_context()->set_jsfunction_result_caches(*caches);
1890 }
1891 
1892 
InitializeNormalizedMapCaches()1893 void Genesis::InitializeNormalizedMapCaches() {
1894   Handle<FixedArray> array(
1895       FACTORY->NewFixedArray(NormalizedMapCache::kEntries, TENURED));
1896   global_context()->set_normalized_map_cache(NormalizedMapCache::cast(*array));
1897 }
1898 
1899 
InstallExtensions(Handle<Context> global_context,v8::ExtensionConfiguration * extensions)1900 bool Bootstrapper::InstallExtensions(Handle<Context> global_context,
1901                                      v8::ExtensionConfiguration* extensions) {
1902   Isolate* isolate = global_context->GetIsolate();
1903   BootstrapperActive active;
1904   SaveContext saved_context(isolate);
1905   isolate->set_context(*global_context);
1906   if (!Genesis::InstallExtensions(global_context, extensions)) return false;
1907   Genesis::InstallSpecialObjects(global_context);
1908   return true;
1909 }
1910 
1911 
InstallSpecialObjects(Handle<Context> global_context)1912 void Genesis::InstallSpecialObjects(Handle<Context> global_context) {
1913   Isolate* isolate = global_context->GetIsolate();
1914   Factory* factory = isolate->factory();
1915   HandleScope scope;
1916   Handle<JSGlobalObject> global(JSGlobalObject::cast(global_context->global()));
1917   // Expose the natives in global if a name for it is specified.
1918   if (FLAG_expose_natives_as != NULL && strlen(FLAG_expose_natives_as) != 0) {
1919     Handle<String> natives = factory->LookupAsciiSymbol(FLAG_expose_natives_as);
1920     CHECK_NOT_EMPTY_HANDLE(isolate,
1921                            JSObject::SetLocalPropertyIgnoreAttributes(
1922                                global, natives,
1923                                Handle<JSObject>(global->builtins()),
1924                                DONT_ENUM));
1925   }
1926 
1927   Handle<Object> Error = GetProperty(global, "Error");
1928   if (Error->IsJSObject()) {
1929     Handle<String> name = factory->LookupAsciiSymbol("stackTraceLimit");
1930     Handle<Smi> stack_trace_limit(Smi::FromInt(FLAG_stack_trace_limit));
1931     CHECK_NOT_EMPTY_HANDLE(isolate,
1932                            JSObject::SetLocalPropertyIgnoreAttributes(
1933                                Handle<JSObject>::cast(Error), name,
1934                                stack_trace_limit, NONE));
1935   }
1936 
1937 #ifdef ENABLE_DEBUGGER_SUPPORT
1938   // Expose the debug global object in global if a name for it is specified.
1939   if (FLAG_expose_debug_as != NULL && strlen(FLAG_expose_debug_as) != 0) {
1940     Debug* debug = Isolate::Current()->debug();
1941     // If loading fails we just bail out without installing the
1942     // debugger but without tanking the whole context.
1943     if (!debug->Load()) return;
1944     // Set the security token for the debugger context to the same as
1945     // the shell global context to allow calling between these (otherwise
1946     // exposing debug global object doesn't make much sense).
1947     debug->debug_context()->set_security_token(
1948         global_context->security_token());
1949 
1950     Handle<String> debug_string =
1951         factory->LookupAsciiSymbol(FLAG_expose_debug_as);
1952     Handle<Object> global_proxy(debug->debug_context()->global_proxy());
1953     CHECK_NOT_EMPTY_HANDLE(isolate,
1954                            JSObject::SetLocalPropertyIgnoreAttributes(
1955                                global, debug_string, global_proxy, DONT_ENUM));
1956   }
1957 #endif
1958 }
1959 
Hash(RegisteredExtension * extension)1960 static uint32_t Hash(RegisteredExtension* extension) {
1961   return v8::internal::ComputePointerHash(extension);
1962 }
1963 
MatchRegisteredExtensions(void * key1,void * key2)1964 static bool MatchRegisteredExtensions(void* key1, void* key2) {
1965   return key1 == key2;
1966 }
1967 
ExtensionStates()1968 Genesis::ExtensionStates::ExtensionStates()
1969   : map_(MatchRegisteredExtensions, 8) { }
1970 
get_state(RegisteredExtension * extension)1971 Genesis::ExtensionTraversalState Genesis::ExtensionStates::get_state(
1972     RegisteredExtension* extension) {
1973   i::HashMap::Entry* entry = map_.Lookup(extension, Hash(extension), false);
1974   if (entry == NULL) {
1975     return UNVISITED;
1976   }
1977   return static_cast<ExtensionTraversalState>(
1978       reinterpret_cast<intptr_t>(entry->value));
1979 }
1980 
set_state(RegisteredExtension * extension,ExtensionTraversalState state)1981 void Genesis::ExtensionStates::set_state(RegisteredExtension* extension,
1982                                          ExtensionTraversalState state) {
1983   map_.Lookup(extension, Hash(extension), true)->value =
1984       reinterpret_cast<void*>(static_cast<intptr_t>(state));
1985 }
1986 
InstallExtensions(Handle<Context> global_context,v8::ExtensionConfiguration * extensions)1987 bool Genesis::InstallExtensions(Handle<Context> global_context,
1988                                 v8::ExtensionConfiguration* extensions) {
1989   // TODO(isolates): Extensions on multiple isolates may take a little more
1990   //                 effort. (The external API reads 'ignore'-- does that mean
1991   //                 we can break the interface?)
1992 
1993 
1994   ExtensionStates extension_states;  // All extensions have state UNVISITED.
1995   // Install auto extensions.
1996   v8::RegisteredExtension* current = v8::RegisteredExtension::first_extension();
1997   while (current != NULL) {
1998     if (current->extension()->auto_enable())
1999       InstallExtension(current, &extension_states);
2000     current = current->next();
2001   }
2002 
2003   if (FLAG_expose_gc) InstallExtension("v8/gc", &extension_states);
2004   if (FLAG_expose_externalize_string) {
2005     InstallExtension("v8/externalize", &extension_states);
2006   }
2007 
2008   if (extensions == NULL) return true;
2009   // Install required extensions
2010   int count = v8::ImplementationUtilities::GetNameCount(extensions);
2011   const char** names = v8::ImplementationUtilities::GetNames(extensions);
2012   for (int i = 0; i < count; i++) {
2013     if (!InstallExtension(names[i], &extension_states))
2014       return false;
2015   }
2016 
2017   return true;
2018 }
2019 
2020 
2021 // Installs a named extension.  This methods is unoptimized and does
2022 // not scale well if we want to support a large number of extensions.
InstallExtension(const char * name,ExtensionStates * extension_states)2023 bool Genesis::InstallExtension(const char* name,
2024                                ExtensionStates* extension_states) {
2025   v8::RegisteredExtension* current = v8::RegisteredExtension::first_extension();
2026   // Loop until we find the relevant extension
2027   while (current != NULL) {
2028     if (strcmp(name, current->extension()->name()) == 0) break;
2029     current = current->next();
2030   }
2031   // Didn't find the extension; fail.
2032   if (current == NULL) {
2033     v8::Utils::ReportApiFailure(
2034         "v8::Context::New()", "Cannot find required extension");
2035     return false;
2036   }
2037   return InstallExtension(current, extension_states);
2038 }
2039 
2040 
InstallExtension(v8::RegisteredExtension * current,ExtensionStates * extension_states)2041 bool Genesis::InstallExtension(v8::RegisteredExtension* current,
2042                                ExtensionStates* extension_states) {
2043   HandleScope scope;
2044 
2045   if (extension_states->get_state(current) == INSTALLED) return true;
2046   // The current node has already been visited so there must be a
2047   // cycle in the dependency graph; fail.
2048   if (extension_states->get_state(current) == VISITED) {
2049     v8::Utils::ReportApiFailure(
2050         "v8::Context::New()", "Circular extension dependency");
2051     return false;
2052   }
2053   ASSERT(extension_states->get_state(current) == UNVISITED);
2054   extension_states->set_state(current, VISITED);
2055   v8::Extension* extension = current->extension();
2056   // Install the extension's dependencies
2057   for (int i = 0; i < extension->dependency_count(); i++) {
2058     if (!InstallExtension(extension->dependencies()[i], extension_states))
2059       return false;
2060   }
2061   Isolate* isolate = Isolate::Current();
2062   Handle<String> source_code =
2063       isolate->factory()->NewExternalStringFromAscii(extension->source());
2064   bool result = CompileScriptCached(
2065       CStrVector(extension->name()),
2066       source_code,
2067       isolate->bootstrapper()->extensions_cache(),
2068       extension,
2069       Handle<Context>(isolate->context()),
2070       false);
2071   ASSERT(isolate->has_pending_exception() != result);
2072   if (!result) {
2073     // We print out the name of the extension that fail to install.
2074     // When an error is thrown during bootstrapping we automatically print
2075     // the line number at which this happened to the console in the isolate
2076     // error throwing functionality.
2077     OS::PrintError("Error installing extension '%s'.\n",
2078                    current->extension()->name());
2079     isolate->clear_pending_exception();
2080   }
2081   extension_states->set_state(current, INSTALLED);
2082   isolate->NotifyExtensionInstalled();
2083   return result;
2084 }
2085 
2086 
InstallJSBuiltins(Handle<JSBuiltinsObject> builtins)2087 bool Genesis::InstallJSBuiltins(Handle<JSBuiltinsObject> builtins) {
2088   HandleScope scope;
2089   Factory* factory = builtins->GetIsolate()->factory();
2090   for (int i = 0; i < Builtins::NumberOfJavaScriptBuiltins(); i++) {
2091     Builtins::JavaScript id = static_cast<Builtins::JavaScript>(i);
2092     Handle<String> name = factory->LookupAsciiSymbol(Builtins::GetName(id));
2093     Object* function_object = builtins->GetPropertyNoExceptionThrown(*name);
2094     Handle<JSFunction> function
2095         = Handle<JSFunction>(JSFunction::cast(function_object));
2096     builtins->set_javascript_builtin(id, *function);
2097     Handle<SharedFunctionInfo> shared
2098         = Handle<SharedFunctionInfo>(function->shared());
2099     if (!SharedFunctionInfo::EnsureCompiled(shared, CLEAR_EXCEPTION)) {
2100       return false;
2101     }
2102     // Set the code object on the function object.
2103     function->ReplaceCode(function->shared()->code());
2104     builtins->set_javascript_builtin_code(id, shared->code());
2105   }
2106   return true;
2107 }
2108 
2109 
ConfigureGlobalObjects(v8::Handle<v8::ObjectTemplate> global_proxy_template)2110 bool Genesis::ConfigureGlobalObjects(
2111     v8::Handle<v8::ObjectTemplate> global_proxy_template) {
2112   Handle<JSObject> global_proxy(
2113       JSObject::cast(global_context()->global_proxy()));
2114   Handle<JSObject> inner_global(JSObject::cast(global_context()->global()));
2115 
2116   if (!global_proxy_template.IsEmpty()) {
2117     // Configure the global proxy object.
2118     Handle<ObjectTemplateInfo> proxy_data =
2119         v8::Utils::OpenHandle(*global_proxy_template);
2120     if (!ConfigureApiObject(global_proxy, proxy_data)) return false;
2121 
2122     // Configure the inner global object.
2123     Handle<FunctionTemplateInfo> proxy_constructor(
2124         FunctionTemplateInfo::cast(proxy_data->constructor()));
2125     if (!proxy_constructor->prototype_template()->IsUndefined()) {
2126       Handle<ObjectTemplateInfo> inner_data(
2127           ObjectTemplateInfo::cast(proxy_constructor->prototype_template()));
2128       if (!ConfigureApiObject(inner_global, inner_data)) return false;
2129     }
2130   }
2131 
2132   SetObjectPrototype(global_proxy, inner_global);
2133   return true;
2134 }
2135 
2136 
ConfigureApiObject(Handle<JSObject> object,Handle<ObjectTemplateInfo> object_template)2137 bool Genesis::ConfigureApiObject(Handle<JSObject> object,
2138     Handle<ObjectTemplateInfo> object_template) {
2139   ASSERT(!object_template.is_null());
2140   ASSERT(object->IsInstanceOf(
2141       FunctionTemplateInfo::cast(object_template->constructor())));
2142 
2143   bool pending_exception = false;
2144   Handle<JSObject> obj =
2145       Execution::InstantiateObject(object_template, &pending_exception);
2146   if (pending_exception) {
2147     ASSERT(isolate()->has_pending_exception());
2148     isolate()->clear_pending_exception();
2149     return false;
2150   }
2151   TransferObject(obj, object);
2152   return true;
2153 }
2154 
2155 
TransferNamedProperties(Handle<JSObject> from,Handle<JSObject> to)2156 void Genesis::TransferNamedProperties(Handle<JSObject> from,
2157                                       Handle<JSObject> to) {
2158   if (from->HasFastProperties()) {
2159     Handle<DescriptorArray> descs =
2160         Handle<DescriptorArray>(from->map()->instance_descriptors());
2161     for (int i = 0; i < descs->number_of_descriptors(); i++) {
2162       PropertyDetails details = PropertyDetails(descs->GetDetails(i));
2163       switch (details.type()) {
2164         case FIELD: {
2165           HandleScope inner;
2166           Handle<String> key = Handle<String>(descs->GetKey(i));
2167           int index = descs->GetFieldIndex(i);
2168           Handle<Object> value = Handle<Object>(from->FastPropertyAt(index));
2169           CHECK_NOT_EMPTY_HANDLE(to->GetIsolate(),
2170                                  JSObject::SetLocalPropertyIgnoreAttributes(
2171                                      to, key, value, details.attributes()));
2172           break;
2173         }
2174         case CONSTANT_FUNCTION: {
2175           HandleScope inner;
2176           Handle<String> key = Handle<String>(descs->GetKey(i));
2177           Handle<JSFunction> fun =
2178               Handle<JSFunction>(descs->GetConstantFunction(i));
2179           CHECK_NOT_EMPTY_HANDLE(to->GetIsolate(),
2180                                  JSObject::SetLocalPropertyIgnoreAttributes(
2181                                      to, key, fun, details.attributes()));
2182           break;
2183         }
2184         case CALLBACKS: {
2185           LookupResult result(isolate());
2186           to->LocalLookup(descs->GetKey(i), &result);
2187           // If the property is already there we skip it
2188           if (result.IsProperty()) continue;
2189           HandleScope inner;
2190           ASSERT(!to->HasFastProperties());
2191           // Add to dictionary.
2192           Handle<String> key = Handle<String>(descs->GetKey(i));
2193           Handle<Object> callbacks(descs->GetCallbacksObject(i));
2194           PropertyDetails d =
2195               PropertyDetails(details.attributes(), CALLBACKS, details.index());
2196           JSObject::SetNormalizedProperty(to, key, callbacks, d);
2197           break;
2198         }
2199         case MAP_TRANSITION:
2200         case ELEMENTS_TRANSITION:
2201         case CONSTANT_TRANSITION:
2202         case NULL_DESCRIPTOR:
2203           // Ignore non-properties.
2204           break;
2205         case NORMAL:
2206           // Do not occur since the from object has fast properties.
2207         case HANDLER:
2208         case INTERCEPTOR:
2209           // No element in instance descriptors have proxy or interceptor type.
2210           UNREACHABLE();
2211           break;
2212       }
2213     }
2214   } else {
2215     Handle<StringDictionary> properties =
2216         Handle<StringDictionary>(from->property_dictionary());
2217     int capacity = properties->Capacity();
2218     for (int i = 0; i < capacity; i++) {
2219       Object* raw_key(properties->KeyAt(i));
2220       if (properties->IsKey(raw_key)) {
2221         ASSERT(raw_key->IsString());
2222         // If the property is already there we skip it.
2223         LookupResult result(isolate());
2224         to->LocalLookup(String::cast(raw_key), &result);
2225         if (result.IsProperty()) continue;
2226         // Set the property.
2227         Handle<String> key = Handle<String>(String::cast(raw_key));
2228         Handle<Object> value = Handle<Object>(properties->ValueAt(i));
2229         if (value->IsJSGlobalPropertyCell()) {
2230           value = Handle<Object>(JSGlobalPropertyCell::cast(*value)->value());
2231         }
2232         PropertyDetails details = properties->DetailsAt(i);
2233         CHECK_NOT_EMPTY_HANDLE(to->GetIsolate(),
2234                                JSObject::SetLocalPropertyIgnoreAttributes(
2235                                    to, key, value, details.attributes()));
2236       }
2237     }
2238   }
2239 }
2240 
2241 
TransferIndexedProperties(Handle<JSObject> from,Handle<JSObject> to)2242 void Genesis::TransferIndexedProperties(Handle<JSObject> from,
2243                                         Handle<JSObject> to) {
2244   // Cloning the elements array is sufficient.
2245   Handle<FixedArray> from_elements =
2246       Handle<FixedArray>(FixedArray::cast(from->elements()));
2247   Handle<FixedArray> to_elements = FACTORY->CopyFixedArray(from_elements);
2248   to->set_elements(*to_elements);
2249 }
2250 
2251 
TransferObject(Handle<JSObject> from,Handle<JSObject> to)2252 void Genesis::TransferObject(Handle<JSObject> from, Handle<JSObject> to) {
2253   HandleScope outer;
2254   Factory* factory = from->GetIsolate()->factory();
2255 
2256   ASSERT(!from->IsJSArray());
2257   ASSERT(!to->IsJSArray());
2258 
2259   TransferNamedProperties(from, to);
2260   TransferIndexedProperties(from, to);
2261 
2262   // Transfer the prototype (new map is needed).
2263   Handle<Map> old_to_map = Handle<Map>(to->map());
2264   Handle<Map> new_to_map = factory->CopyMapDropTransitions(old_to_map);
2265   new_to_map->set_prototype(from->map()->prototype());
2266   to->set_map(*new_to_map);
2267 }
2268 
2269 
MakeFunctionInstancePrototypeWritable()2270 void Genesis::MakeFunctionInstancePrototypeWritable() {
2271   // The maps with writable prototype are created in CreateEmptyFunction
2272   // and CreateStrictModeFunctionMaps respectively. Initially the maps are
2273   // created with read-only prototype for JS builtins processing.
2274   ASSERT(!function_instance_map_writable_prototype_.is_null());
2275   ASSERT(!strict_mode_function_instance_map_writable_prototype_.is_null());
2276 
2277   // Replace function instance maps to make prototype writable.
2278   global_context()->set_function_map(
2279     *function_instance_map_writable_prototype_);
2280   global_context()->set_strict_mode_function_map(
2281     *strict_mode_function_instance_map_writable_prototype_);
2282 }
2283 
2284 
Genesis(Isolate * isolate,Handle<Object> global_object,v8::Handle<v8::ObjectTemplate> global_template,v8::ExtensionConfiguration * extensions)2285 Genesis::Genesis(Isolate* isolate,
2286                  Handle<Object> global_object,
2287                  v8::Handle<v8::ObjectTemplate> global_template,
2288                  v8::ExtensionConfiguration* extensions) : isolate_(isolate) {
2289   result_ = Handle<Context>::null();
2290   // If V8 isn't running and cannot be initialized, just return.
2291   if (!V8::IsRunning() && !V8::Initialize(NULL)) return;
2292 
2293   // Before creating the roots we must save the context and restore it
2294   // on all function exits.
2295   HandleScope scope;
2296   SaveContext saved_context(isolate);
2297 
2298   // During genesis, the boilerplate for stack overflow won't work until the
2299   // environment has been at least partially initialized. Add a stack check
2300   // before entering JS code to catch overflow early.
2301   StackLimitCheck check(Isolate::Current());
2302   if (check.HasOverflowed()) return;
2303 
2304   Handle<Context> new_context = Snapshot::NewContextFromSnapshot();
2305   if (!new_context.is_null()) {
2306     global_context_ =
2307         Handle<Context>::cast(isolate->global_handles()->Create(*new_context));
2308     AddToWeakGlobalContextList(*global_context_);
2309     isolate->set_context(*global_context_);
2310     isolate->counters()->contexts_created_by_snapshot()->Increment();
2311     Handle<GlobalObject> inner_global;
2312     Handle<JSGlobalProxy> global_proxy =
2313         CreateNewGlobals(global_template,
2314                          global_object,
2315                          &inner_global);
2316 
2317     HookUpGlobalProxy(inner_global, global_proxy);
2318     HookUpInnerGlobal(inner_global);
2319 
2320     if (!ConfigureGlobalObjects(global_template)) return;
2321   } else {
2322     // We get here if there was no context snapshot.
2323     CreateRoots();
2324     Handle<JSFunction> empty_function = CreateEmptyFunction(isolate);
2325     CreateStrictModeFunctionMaps(empty_function);
2326     Handle<GlobalObject> inner_global;
2327     Handle<JSGlobalProxy> global_proxy =
2328         CreateNewGlobals(global_template, global_object, &inner_global);
2329     HookUpGlobalProxy(inner_global, global_proxy);
2330     if (!InitializeGlobal(inner_global, empty_function)) return;
2331     InstallJSFunctionResultCaches();
2332     InitializeNormalizedMapCaches();
2333     if (!InstallNatives()) return;
2334 
2335     MakeFunctionInstancePrototypeWritable();
2336 
2337     if (!ConfigureGlobalObjects(global_template)) return;
2338     isolate->counters()->contexts_created_from_scratch()->Increment();
2339   }
2340 
2341   // Initialize experimental globals and install experimental natives.
2342   InitializeExperimentalGlobal();
2343   if (!InstallExperimentalNatives()) return;
2344 
2345   result_ = global_context_;
2346 }
2347 
2348 
2349 // Support for thread preemption.
2350 
2351 // Reserve space for statics needing saving and restoring.
ArchiveSpacePerThread()2352 int Bootstrapper::ArchiveSpacePerThread() {
2353   return sizeof(NestingCounterType);
2354 }
2355 
2356 
2357 // Archive statics that are thread local.
ArchiveState(char * to)2358 char* Bootstrapper::ArchiveState(char* to) {
2359   *reinterpret_cast<NestingCounterType*>(to) = nesting_;
2360   nesting_ = 0;
2361   return to + sizeof(NestingCounterType);
2362 }
2363 
2364 
2365 // Restore statics that are thread local.
RestoreState(char * from)2366 char* Bootstrapper::RestoreState(char* from) {
2367   nesting_ = *reinterpret_cast<NestingCounterType*>(from);
2368   return from + sizeof(NestingCounterType);
2369 }
2370 
2371 
2372 // Called when the top-level V8 mutex is destroyed.
FreeThreadResources()2373 void Bootstrapper::FreeThreadResources() {
2374   ASSERT(!IsActive());
2375 }
2376 
2377 } }  // namespace v8::internal
2378