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