The data contained in this repository can be downloaded to your computer using one of several clients.
Please see the documentation of your version control software client for more information.

Please select the desired protocol below to get the URL.

This URL has Read-Only access.

Statistics
| Branch: | Revision:

main_repo / deps / v8 / src / bootstrapper.cc @ 40c0f755

History | View | Annotate | Download (56.2 KB)

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

    
40
namespace v8 { namespace internal {
41

    
42
// A SourceCodeCache uses a FixedArray to store pairs of
43
// (AsciiString*, JSFunction*), mapping names of native code files
44
// (runtime.js, etc.) to precompiled functions. Instead of mapping
45
// names to functions it might make sense to let the JS2C tool
46
// generate an index for each native JS file.
47
class SourceCodeCache BASE_EMBEDDED {
48
 public:
49
  explicit SourceCodeCache(ScriptType type): type_(type) { }
50

    
51
  void Initialize(bool create_heap_objects) {
52
    if (create_heap_objects) {
53
      cache_ = Heap::empty_fixed_array();
54
    } else {
55
      cache_ = NULL;
56
    }
57
  }
58

    
59
  void Iterate(ObjectVisitor* v) {
60
    v->VisitPointer(bit_cast<Object**, FixedArray**>(&cache_));
61
  }
62

    
63

    
64
  bool Lookup(Vector<const char> name, Handle<JSFunction>* handle) {
65
    for (int i = 0; i < cache_->length(); i+=2) {
66
      SeqAsciiString* str = SeqAsciiString::cast(cache_->get(i));
67
      if (str->IsEqualTo(name)) {
68
        *handle = Handle<JSFunction>(JSFunction::cast(cache_->get(i + 1)));
69
        return true;
70
      }
71
    }
72
    return false;
73
  }
74

    
75

    
76
  void Add(Vector<const char> name, Handle<JSFunction> fun) {
77
    ASSERT(fun->IsBoilerplate());
78
    HandleScope scope;
79
    int length = cache_->length();
80
    Handle<FixedArray> new_array =
81
        Factory::NewFixedArray(length + 2, TENURED);
82
    cache_->CopyTo(0, *new_array, 0, cache_->length());
83
    cache_ = *new_array;
84
    Handle<String> str = Factory::NewStringFromAscii(name, TENURED);
85
    cache_->set(length, *str);
86
    cache_->set(length + 1, *fun);
87
    Script::cast(fun->shared()->script())->set_type(Smi::FromInt(type_));
88
  }
89

    
90
 private:
91
  ScriptType type_;
92
  FixedArray* cache_;
93
  DISALLOW_COPY_AND_ASSIGN(SourceCodeCache);
94
};
95

    
96
static SourceCodeCache natives_cache(SCRIPT_TYPE_NATIVE);
97
static SourceCodeCache extensions_cache(SCRIPT_TYPE_EXTENSION);
98

    
99

    
100
Handle<String> Bootstrapper::NativesSourceLookup(int index) {
101
  ASSERT(0 <= index && index < Natives::GetBuiltinsCount());
102
  if (Heap::natives_source_cache()->get(index)->IsUndefined()) {
103
    Handle<String> source_code =
104
      Factory::NewStringFromAscii(Natives::GetScriptSource(index));
105
    Heap::natives_source_cache()->set(index, *source_code);
106
  }
107
  Handle<Object> cached_source(Heap::natives_source_cache()->get(index));
108
  return Handle<String>::cast(cached_source);
109
}
110

    
111

    
112
bool Bootstrapper::NativesCacheLookup(Vector<const char> name,
113
                                      Handle<JSFunction>* handle) {
114
  return natives_cache.Lookup(name, handle);
115
}
116

    
117

    
118
void Bootstrapper::NativesCacheAdd(Vector<const char> name,
119
                                   Handle<JSFunction> fun) {
120
  natives_cache.Add(name, fun);
121
}
122

    
123

    
124
void Bootstrapper::Initialize(bool create_heap_objects) {
125
  natives_cache.Initialize(create_heap_objects);
126
  extensions_cache.Initialize(create_heap_objects);
127
}
128

    
129

    
130
void Bootstrapper::TearDown() {
131
  natives_cache.Initialize(false);  // Yes, symmetrical
132
  extensions_cache.Initialize(false);
133
}
134

    
135

    
136
// Pending fixups are code positions that have refer to builtin code
137
// objects that were not available at the time the code was generated.
138
// The pending list is processed whenever an environment has been
139
// created.
140
class PendingFixups : public AllStatic {
141
 public:
142
  static void Add(Code* code, MacroAssembler* masm);
143
  static bool Process(Handle<JSBuiltinsObject> builtins);
144

    
145
  static void Iterate(ObjectVisitor* v);
146

    
147
 private:
148
  static List<Object*> code_;
149
  static List<const char*> name_;
150
  static List<int> pc_;
151
  static List<uint32_t> flags_;
152

    
153
  static void Clear();
154
};
155

    
156

    
157
List<Object*> PendingFixups::code_(0);
158
List<const char*> PendingFixups::name_(0);
159
List<int> PendingFixups::pc_(0);
160
List<uint32_t> PendingFixups::flags_(0);
161

    
162

    
163
void PendingFixups::Add(Code* code, MacroAssembler* masm) {
164
  // Note this code is not only called during bootstrapping.
165
  List<MacroAssembler::Unresolved>* unresolved = masm->unresolved();
166
  int n = unresolved->length();
167
  for (int i = 0; i < n; i++) {
168
    const char* name = unresolved->at(i).name;
169
    code_.Add(code);
170
    name_.Add(name);
171
    pc_.Add(unresolved->at(i).pc);
172
    flags_.Add(unresolved->at(i).flags);
173
    LOG(StringEvent("unresolved", name));
174
  }
175
}
176

    
177

    
178
bool PendingFixups::Process(Handle<JSBuiltinsObject> builtins) {
179
  HandleScope scope;
180
  // NOTE: Extra fixups may be added to the list during the iteration
181
  // due to lazy compilation of functions during the processing. Do not
182
  // cache the result of getting the length of the code list.
183
  for (int i = 0; i < code_.length(); i++) {
184
    const char* name = name_[i];
185
    uint32_t flags = flags_[i];
186
    Handle<String> symbol = Factory::LookupAsciiSymbol(name);
187
    Object* o = builtins->GetProperty(*symbol);
188
#ifdef DEBUG
189
    if (!o->IsJSFunction()) {
190
      V8_Fatal(__FILE__, __LINE__, "Cannot resolve call to builtin %s", name);
191
    }
192
#endif
193
    Handle<JSFunction> f = Handle<JSFunction>(JSFunction::cast(o));
194
    // Make sure the number of parameters match the formal parameter count.
195
    int argc = Bootstrapper::FixupFlagsArgumentsCount::decode(flags);
196
    USE(argc);
197
    ASSERT(f->shared()->formal_parameter_count() == argc);
198
    if (!f->is_compiled()) {
199
      // Do lazy compilation and check for stack overflows.
200
      if (!CompileLazy(f, CLEAR_EXCEPTION)) {
201
        Clear();
202
        return false;
203
      }
204
    }
205
    Code* code = Code::cast(code_[i]);
206
    Address pc = code->instruction_start() + pc_[i];
207
    bool is_pc_relative = Bootstrapper::FixupFlagsIsPCRelative::decode(flags);
208
    bool use_code_object = Bootstrapper::FixupFlagsUseCodeObject::decode(flags);
209

    
210
    if (use_code_object) {
211
      if (is_pc_relative) {
212
        Assembler::set_target_address_at(
213
            pc, reinterpret_cast<Address>(f->code()));
214
      } else {
215
        *reinterpret_cast<Object**>(pc) = f->code();
216
      }
217
    } else {
218
      ASSERT(is_pc_relative);
219
      Assembler::set_target_address_at(pc, f->code()->instruction_start());
220
    }
221

    
222
    LOG(StringEvent("resolved", name));
223
  }
224
  Clear();
225

    
226
  // TODO(1240818): We should probably try to avoid doing this for all
227
  // the V8 builtin JS files. It should only happen after running
228
  // runtime.js - just like there shouldn't be any fixups left after
229
  // that.
230
  for (int i = 0; i < Builtins::NumberOfJavaScriptBuiltins(); i++) {
231
    Builtins::JavaScript id = static_cast<Builtins::JavaScript>(i);
232
    Handle<String> name = Factory::LookupAsciiSymbol(Builtins::GetName(id));
233
    JSFunction* function = JSFunction::cast(builtins->GetProperty(*name));
234
    builtins->set_javascript_builtin(id, function);
235
  }
236

    
237
  return true;
238
}
239

    
240

    
241
void PendingFixups::Clear() {
242
  code_.Clear();
243
  name_.Clear();
244
  pc_.Clear();
245
  flags_.Clear();
246
}
247

    
248

    
249
void PendingFixups::Iterate(ObjectVisitor* v) {
250
  if (!code_.is_empty()) {
251
    v->VisitPointers(&code_[0], &code_[0] + code_.length());
252
  }
253
}
254

    
255

    
256
class Genesis BASE_EMBEDDED {
257
 public:
258
  Genesis(Handle<Object> global_object,
259
          v8::Handle<v8::ObjectTemplate> global_template,
260
          v8::ExtensionConfiguration* extensions);
261
  ~Genesis();
262

    
263
  Handle<Context> result() { return result_; }
264

    
265
  Genesis* previous() { return previous_; }
266
  static Genesis* current() { return current_; }
267

    
268
  // Support for thread preemption.
269
  static int ArchiveSpacePerThread();
270
  static char* ArchiveState(char* to);
271
  static char* RestoreState(char* from);
272

    
273
 private:
274
  Handle<Context> global_context_;
275

    
276
  // There may be more than one active genesis object: When GC is
277
  // triggered during environment creation there may be weak handle
278
  // processing callbacks which may create new environments.
279
  Genesis* previous_;
280
  static Genesis* current_;
281

    
282
  Handle<Context> global_context() { return global_context_; }
283

    
284
  void CreateRoots(v8::Handle<v8::ObjectTemplate> global_template,
285
                   Handle<Object> global_object);
286
  void InstallNativeFunctions();
287
  bool InstallNatives();
288
  bool InstallExtensions(v8::ExtensionConfiguration* extensions);
289
  bool InstallExtension(const char* name);
290
  bool InstallExtension(v8::RegisteredExtension* current);
291
  bool InstallSpecialObjects();
292
  bool ConfigureApiObject(Handle<JSObject> object,
293
                          Handle<ObjectTemplateInfo> object_template);
294
  bool ConfigureGlobalObjects(v8::Handle<v8::ObjectTemplate> global_template);
295

    
296
  // Migrates all properties from the 'from' object to the 'to'
297
  // object and overrides the prototype in 'to' with the one from
298
  // 'from'.
299
  void TransferObject(Handle<JSObject> from, Handle<JSObject> to);
300
  void TransferNamedProperties(Handle<JSObject> from, Handle<JSObject> to);
301
  void TransferIndexedProperties(Handle<JSObject> from, Handle<JSObject> to);
302

    
303
  Handle<DescriptorArray> ComputeFunctionInstanceDescriptor(
304
      bool make_prototype_read_only,
305
      bool make_prototype_enumerable = false);
306
  void MakeFunctionInstancePrototypeWritable();
307

    
308
  void AddSpecialFunction(Handle<JSObject> prototype,
309
                          const char* name,
310
                          Handle<Code> code);
311

    
312
  void BuildSpecialFunctionTable();
313

    
314
  static bool CompileBuiltin(int index);
315
  static bool CompileNative(Vector<const char> name, Handle<String> source);
316
  static bool CompileScriptCached(Vector<const char> name,
317
                                  Handle<String> source,
318
                                  SourceCodeCache* cache,
319
                                  v8::Extension* extension,
320
                                  bool use_runtime_context);
321

    
322
  Handle<Context> result_;
323
};
324

    
325
Genesis* Genesis::current_ = NULL;
326

    
327

    
328
void Bootstrapper::Iterate(ObjectVisitor* v) {
329
  natives_cache.Iterate(v);
330
  extensions_cache.Iterate(v);
331
  PendingFixups::Iterate(v);
332
}
333

    
334

    
335
// While setting up the environment, we collect code positions that
336
// need to be patched before we can run any code in the environment.
337
void Bootstrapper::AddFixup(Code* code, MacroAssembler* masm) {
338
  PendingFixups::Add(code, masm);
339
}
340

    
341

    
342
bool Bootstrapper::IsActive() {
343
  return Genesis::current() != NULL;
344
}
345

    
346

    
347
Handle<Context> Bootstrapper::CreateEnvironment(
348
    Handle<Object> global_object,
349
    v8::Handle<v8::ObjectTemplate> global_template,
350
    v8::ExtensionConfiguration* extensions) {
351
  Genesis genesis(global_object, global_template, extensions);
352
  return genesis.result();
353
}
354

    
355

    
356
static void SetObjectPrototype(Handle<JSObject> object, Handle<Object> proto) {
357
  // object.__proto__ = proto;
358
  Handle<Map> old_to_map = Handle<Map>(object->map());
359
  Handle<Map> new_to_map = Factory::CopyMapDropTransitions(old_to_map);
360
  new_to_map->set_prototype(*proto);
361
  object->set_map(*new_to_map);
362
}
363

    
364

    
365
void Bootstrapper::DetachGlobal(Handle<Context> env) {
366
  JSGlobalProxy::cast(env->global_proxy())->set_context(*Factory::null_value());
367
  SetObjectPrototype(Handle<JSObject>(env->global_proxy()),
368
                     Factory::null_value());
369
  env->set_global_proxy(env->global());
370
  env->global()->set_global_receiver(env->global());
371
}
372

    
373

    
374
Genesis::~Genesis() {
375
  ASSERT(current_ == this);
376
  current_ = previous_;
377
}
378

    
379

    
380
static Handle<JSFunction> InstallFunction(Handle<JSObject> target,
381
                                          const char* name,
382
                                          InstanceType type,
383
                                          int instance_size,
384
                                          Handle<JSObject> prototype,
385
                                          Builtins::Name call,
386
                                          bool is_ecma_native) {
387
  Handle<String> symbol = Factory::LookupAsciiSymbol(name);
388
  Handle<Code> call_code = Handle<Code>(Builtins::builtin(call));
389
  Handle<JSFunction> function =
390
    Factory::NewFunctionWithPrototype(symbol,
391
                                      type,
392
                                      instance_size,
393
                                      prototype,
394
                                      call_code,
395
                                      is_ecma_native);
396
  SetProperty(target, symbol, function, DONT_ENUM);
397
  if (is_ecma_native) {
398
    function->shared()->set_instance_class_name(*symbol);
399
  }
400
  return function;
401
}
402

    
403

    
404
Handle<DescriptorArray> Genesis::ComputeFunctionInstanceDescriptor(
405
    bool make_prototype_read_only,
406
    bool make_prototype_enumerable) {
407
  Handle<DescriptorArray> result = Factory::empty_descriptor_array();
408

    
409
  // Add prototype.
410
  PropertyAttributes attributes = static_cast<PropertyAttributes>(
411
      (make_prototype_enumerable ? 0 : DONT_ENUM)
412
      | DONT_DELETE
413
      | (make_prototype_read_only ? READ_ONLY : 0));
414
  result =
415
      Factory::CopyAppendProxyDescriptor(
416
          result,
417
          Factory::prototype_symbol(),
418
          Factory::NewProxy(&Accessors::FunctionPrototype),
419
          attributes);
420

    
421
  attributes =
422
      static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
423
  // Add length.
424
  result =
425
      Factory::CopyAppendProxyDescriptor(
426
          result,
427
          Factory::length_symbol(),
428
          Factory::NewProxy(&Accessors::FunctionLength),
429
          attributes);
430

    
431
  // Add name.
432
  result =
433
      Factory::CopyAppendProxyDescriptor(
434
          result,
435
          Factory::name_symbol(),
436
          Factory::NewProxy(&Accessors::FunctionName),
437
          attributes);
438

    
439
  // Add arguments.
440
  result =
441
      Factory::CopyAppendProxyDescriptor(
442
          result,
443
          Factory::arguments_symbol(),
444
          Factory::NewProxy(&Accessors::FunctionArguments),
445
          attributes);
446

    
447
  // Add caller.
448
  result =
449
      Factory::CopyAppendProxyDescriptor(
450
          result,
451
          Factory::caller_symbol(),
452
          Factory::NewProxy(&Accessors::FunctionCaller),
453
          attributes);
454

    
455
  return result;
456
}
457

    
458

    
459
void Genesis::CreateRoots(v8::Handle<v8::ObjectTemplate> global_template,
460
                          Handle<Object> global_object) {
461
  HandleScope scope;
462
  // Allocate the global context FixedArray first and then patch the
463
  // closure and extension object later (we need the empty function
464
  // and the global object, but in order to create those, we need the
465
  // global context).
466
  global_context_ =
467
      Handle<Context>::cast(
468
          GlobalHandles::Create(*Factory::NewGlobalContext()));
469
  Top::set_context(*global_context());
470

    
471
  // Allocate the message listeners object.
472
  v8::NeanderArray listeners;
473
  global_context()->set_message_listeners(*listeners.value());
474

    
475
  // Allocate the map for function instances.
476
  Handle<Map> fm = Factory::NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
477
  global_context()->set_function_instance_map(*fm);
478
  // Please note that the prototype property for function instances must be
479
  // writable.
480
  Handle<DescriptorArray> function_map_descriptors =
481
      ComputeFunctionInstanceDescriptor(false, true);
482
  fm->set_instance_descriptors(*function_map_descriptors);
483

    
484
  // Allocate the function map first and then patch the prototype later
485
  fm = Factory::NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
486
  global_context()->set_function_map(*fm);
487
  function_map_descriptors = ComputeFunctionInstanceDescriptor(true);
488
  fm->set_instance_descriptors(*function_map_descriptors);
489

    
490
  Handle<String> object_name = Handle<String>(Heap::Object_symbol());
491

    
492
  {  // --- O b j e c t ---
493
    Handle<JSFunction> object_fun =
494
        Factory::NewFunction(object_name, Factory::null_value());
495
    Handle<Map> object_function_map =
496
        Factory::NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
497
    object_fun->set_initial_map(*object_function_map);
498
    object_function_map->set_constructor(*object_fun);
499

    
500
    global_context()->set_object_function(*object_fun);
501

    
502
    // Allocate a new prototype for the object function.
503
    Handle<JSObject> prototype = Factory::NewJSObject(Top::object_function(),
504
                                                      TENURED);
505

    
506
    global_context()->set_initial_object_prototype(*prototype);
507
    SetPrototype(object_fun, prototype);
508
    object_function_map->
509
      set_instance_descriptors(Heap::empty_descriptor_array());
510
  }
511

    
512
  // Allocate the empty function as the prototype for function ECMAScript
513
  // 262 15.3.4.
514
  Handle<String> symbol = Factory::LookupAsciiSymbol("Empty");
515
  Handle<JSFunction> empty_function =
516
      Factory::NewFunction(symbol, Factory::null_value());
517

    
518
  {  // --- E m p t y ---
519
    Handle<Code> code =
520
        Handle<Code>(Builtins::builtin(Builtins::EmptyFunction));
521
    empty_function->set_code(*code);
522
    Handle<String> source = Factory::NewStringFromAscii(CStrVector("() {}"));
523
    Handle<Script> script = Factory::NewScript(source);
524
    script->set_type(Smi::FromInt(SCRIPT_TYPE_NATIVE));
525
    empty_function->shared()->set_script(*script);
526
    empty_function->shared()->set_start_position(0);
527
    empty_function->shared()->set_end_position(source->length());
528
    empty_function->shared()->DontAdaptArguments();
529
    global_context()->function_map()->set_prototype(*empty_function);
530
    global_context()->function_instance_map()->set_prototype(*empty_function);
531

    
532
    // Allocate the function map first and then patch the prototype later
533
    Handle<Map> empty_fm = Factory::CopyMap(fm);
534
    empty_fm->set_instance_descriptors(*function_map_descriptors);
535
    empty_fm->set_prototype(global_context()->object_function()->prototype());
536
    empty_function->set_map(*empty_fm);
537
  }
538

    
539
  {  // --- G l o b a l ---
540
    // Step 1: create a fresh inner JSGlobalObject
541
    Handle<JSGlobalObject> object;
542
    {
543
      Handle<JSFunction> js_global_function;
544
      Handle<ObjectTemplateInfo> js_global_template;
545
      if (!global_template.IsEmpty()) {
546
        // Get prototype template of the global_template
547
        Handle<ObjectTemplateInfo> data =
548
            v8::Utils::OpenHandle(*global_template);
549
        Handle<FunctionTemplateInfo> global_constructor =
550
            Handle<FunctionTemplateInfo>(
551
                FunctionTemplateInfo::cast(data->constructor()));
552
        Handle<Object> proto_template(global_constructor->prototype_template());
553
        if (!proto_template->IsUndefined()) {
554
          js_global_template =
555
              Handle<ObjectTemplateInfo>::cast(proto_template);
556
        }
557
      }
558

    
559
      if (js_global_template.is_null()) {
560
        Handle<String> name = Handle<String>(Heap::empty_symbol());
561
        Handle<Code> code = Handle<Code>(Builtins::builtin(Builtins::Illegal));
562
        js_global_function =
563
            Factory::NewFunction(name, JS_GLOBAL_OBJECT_TYPE,
564
                                 JSGlobalObject::kSize, code, true);
565
        // Change the constructor property of the prototype of the
566
        // hidden global function to refer to the Object function.
567
        Handle<JSObject> prototype =
568
            Handle<JSObject>(
569
                JSObject::cast(js_global_function->instance_prototype()));
570
        SetProperty(prototype, Factory::constructor_symbol(),
571
                    Top::object_function(), NONE);
572
      } else {
573
        Handle<FunctionTemplateInfo> js_global_constructor(
574
            FunctionTemplateInfo::cast(js_global_template->constructor()));
575
        js_global_function =
576
            Factory::CreateApiFunction(js_global_constructor,
577
                                       Factory::InnerGlobalObject);
578
      }
579

    
580
      js_global_function->initial_map()->set_is_hidden_prototype();
581
      SetExpectedNofProperties(js_global_function, 100);
582
      object = Handle<JSGlobalObject>::cast(
583
          Factory::NewJSObject(js_global_function, TENURED));
584
    }
585

    
586
    // Set the global context for the global object.
587
    object->set_global_context(*global_context());
588

    
589
    // Step 2: create or re-initialize the global proxy object.
590
    Handle<JSGlobalProxy> global_proxy;
591
    {
592
      Handle<JSFunction> global_proxy_function;
593
      if (global_template.IsEmpty()) {
594
        Handle<String> name = Handle<String>(Heap::empty_symbol());
595
        Handle<Code> code = Handle<Code>(Builtins::builtin(Builtins::Illegal));
596
        global_proxy_function =
597
            Factory::NewFunction(name, JS_GLOBAL_PROXY_TYPE,
598
                                 JSGlobalProxy::kSize, code, true);
599
      } else {
600
        Handle<ObjectTemplateInfo> data =
601
            v8::Utils::OpenHandle(*global_template);
602
        Handle<FunctionTemplateInfo> global_constructor(
603
                FunctionTemplateInfo::cast(data->constructor()));
604
        global_proxy_function =
605
            Factory::CreateApiFunction(global_constructor,
606
                                       Factory::OuterGlobalObject);
607
      }
608

    
609
      Handle<String> global_name = Factory::LookupAsciiSymbol("global");
610
      global_proxy_function->shared()->set_instance_class_name(*global_name);
611
      global_proxy_function->initial_map()->set_is_access_check_needed(true);
612

    
613
      // Set global_proxy.__proto__ to js_global after ConfigureGlobalObjects
614

    
615
      if (global_object.location() != NULL) {
616
        ASSERT(global_object->IsJSGlobalProxy());
617
        global_proxy =
618
            ReinitializeJSGlobalProxy(
619
                global_proxy_function,
620
                Handle<JSGlobalProxy>::cast(global_object));
621
      } else {
622
        global_proxy = Handle<JSGlobalProxy>::cast(
623
            Factory::NewJSObject(global_proxy_function, TENURED));
624
      }
625

    
626
      // Security setup: Set the security token of the global object to
627
      // its the inner global. This makes the security check between two
628
      // different contexts fail by default even in case of global
629
      // object reinitialization.
630
      object->set_global_receiver(*global_proxy);
631
      global_proxy->set_context(*global_context());
632
    }
633

    
634
    {  // --- G l o b a l   C o n t e x t ---
635
      // use the empty function as closure (no scope info)
636
      global_context()->set_closure(*empty_function);
637
      global_context()->set_fcontext(*global_context());
638
      global_context()->set_previous(NULL);
639

    
640
      // set extension and global object
641
      global_context()->set_extension(*object);
642
      global_context()->set_global(*object);
643
      global_context()->set_global_proxy(*global_proxy);
644
      // use inner global object as security token by default
645
      global_context()->set_security_token(*object);
646
    }
647

    
648
    Handle<JSObject> global = Handle<JSObject>(global_context()->global());
649
    SetProperty(global, object_name, Top::object_function(), DONT_ENUM);
650
  }
651

    
652
  Handle<JSObject> global = Handle<JSObject>(global_context()->global());
653

    
654
  // Install global Function object
655
  InstallFunction(global, "Function", JS_FUNCTION_TYPE, JSFunction::kSize,
656
                  empty_function, Builtins::Illegal, true);  // ECMA native.
657

    
658
  {  // --- A r r a y ---
659
    Handle<JSFunction> array_function =
660
        InstallFunction(global, "Array", JS_ARRAY_TYPE, JSArray::kSize,
661
                        Top::initial_object_prototype(), Builtins::ArrayCode,
662
                        true);
663
    array_function->shared()->DontAdaptArguments();
664

    
665
    // This seems a bit hackish, but we need to make sure Array.length
666
    // is 1.
667
    array_function->shared()->set_length(1);
668
    Handle<DescriptorArray> array_descriptors =
669
        Factory::CopyAppendProxyDescriptor(
670
            Factory::empty_descriptor_array(),
671
            Factory::length_symbol(),
672
            Factory::NewProxy(&Accessors::ArrayLength),
673
            static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE));
674

    
675
    // Cache the fast JavaScript array map
676
    global_context()->set_js_array_map(array_function->initial_map());
677
    global_context()->js_array_map()->set_instance_descriptors(
678
        *array_descriptors);
679
    // array_function is used internally. JS code creating array object should
680
    // search for the 'Array' property on the global object and use that one
681
    // as the constructor. 'Array' property on a global object can be
682
    // overwritten by JS code.
683
    global_context()->set_array_function(*array_function);
684
  }
685

    
686
  {  // --- N u m b e r ---
687
    Handle<JSFunction> number_fun =
688
        InstallFunction(global, "Number", JS_VALUE_TYPE, JSValue::kSize,
689
                        Top::initial_object_prototype(), Builtins::Illegal,
690
                        true);
691
    global_context()->set_number_function(*number_fun);
692
  }
693

    
694
  {  // --- B o o l e a n ---
695
    Handle<JSFunction> boolean_fun =
696
        InstallFunction(global, "Boolean", JS_VALUE_TYPE, JSValue::kSize,
697
                        Top::initial_object_prototype(), Builtins::Illegal,
698
                        true);
699
    global_context()->set_boolean_function(*boolean_fun);
700
  }
701

    
702
  {  // --- S t r i n g ---
703
    Handle<JSFunction> string_fun =
704
        InstallFunction(global, "String", JS_VALUE_TYPE, JSValue::kSize,
705
                        Top::initial_object_prototype(), Builtins::Illegal,
706
                        true);
707
    global_context()->set_string_function(*string_fun);
708
    // Add 'length' property to strings.
709
    Handle<DescriptorArray> string_descriptors =
710
        Factory::CopyAppendProxyDescriptor(
711
            Factory::empty_descriptor_array(),
712
            Factory::length_symbol(),
713
            Factory::NewProxy(&Accessors::StringLength),
714
            static_cast<PropertyAttributes>(DONT_ENUM |
715
                                            DONT_DELETE |
716
                                            READ_ONLY));
717

    
718
    Handle<Map> string_map =
719
        Handle<Map>(global_context()->string_function()->initial_map());
720
    string_map->set_instance_descriptors(*string_descriptors);
721
  }
722

    
723
  {  // --- D a t e ---
724
    // Builtin functions for Date.prototype.
725
    Handle<JSFunction> date_fun =
726
        InstallFunction(global, "Date", JS_VALUE_TYPE, JSValue::kSize,
727
                        Top::initial_object_prototype(), Builtins::Illegal,
728
                        true);
729

    
730
    global_context()->set_date_function(*date_fun);
731
  }
732

    
733

    
734
  {  // -- R e g E x p
735
    // Builtin functions for RegExp.prototype.
736
    Handle<JSFunction> regexp_fun =
737
        InstallFunction(global, "RegExp", JS_REGEXP_TYPE, JSRegExp::kSize,
738
                        Top::initial_object_prototype(), Builtins::Illegal,
739
                        true);
740

    
741
    global_context()->set_regexp_function(*regexp_fun);
742
  }
743

    
744
  {  // --- arguments_boilerplate_
745
    // Make sure we can recognize argument objects at runtime.
746
    // This is done by introducing an anonymous function with
747
    // class_name equals 'Arguments'.
748
    Handle<String> symbol = Factory::LookupAsciiSymbol("Arguments");
749
    Handle<Code> code = Handle<Code>(Builtins::builtin(Builtins::Illegal));
750
    Handle<JSObject> prototype =
751
        Handle<JSObject>(
752
            JSObject::cast(global_context()->object_function()->prototype()));
753

    
754
    Handle<JSFunction> function =
755
        Factory::NewFunctionWithPrototype(symbol,
756
                                          JS_OBJECT_TYPE,
757
                                          JSObject::kHeaderSize,
758
                                          prototype,
759
                                          code,
760
                                          false);
761
    ASSERT(!function->has_initial_map());
762
    function->shared()->set_instance_class_name(*symbol);
763
    function->shared()->set_expected_nof_properties(2);
764
    Handle<JSObject> result = Factory::NewJSObject(function);
765

    
766
    global_context()->set_arguments_boilerplate(*result);
767
    // Note: callee must be added as the first property and
768
    //       length must be added as the second property.
769
    SetProperty(result, Factory::callee_symbol(),
770
                Factory::undefined_value(),
771
                DONT_ENUM);
772
    SetProperty(result, Factory::length_symbol(),
773
                Factory::undefined_value(),
774
                DONT_ENUM);
775

    
776
#ifdef DEBUG
777
    LookupResult lookup;
778
    result->LocalLookup(Heap::callee_symbol(), &lookup);
779
    ASSERT(lookup.IsValid() && (lookup.type() == FIELD));
780
    ASSERT(lookup.GetFieldIndex() == Heap::arguments_callee_index);
781

    
782
    result->LocalLookup(Heap::length_symbol(), &lookup);
783
    ASSERT(lookup.IsValid() && (lookup.type() == FIELD));
784
    ASSERT(lookup.GetFieldIndex() == Heap::arguments_length_index);
785

    
786
    ASSERT(result->map()->inobject_properties() > Heap::arguments_callee_index);
787
    ASSERT(result->map()->inobject_properties() > Heap::arguments_length_index);
788

    
789
    // Check the state of the object.
790
    ASSERT(result->HasFastProperties());
791
    ASSERT(result->HasFastElements());
792
#endif
793
  }
794

    
795
  {  // --- context extension
796
    // Create a function for the context extension objects.
797
    Handle<Code> code = Handle<Code>(Builtins::builtin(Builtins::Illegal));
798
    Handle<JSFunction> context_extension_fun =
799
        Factory::NewFunction(Factory::empty_symbol(),
800
                             JS_CONTEXT_EXTENSION_OBJECT_TYPE,
801
                             JSObject::kHeaderSize,
802
                             code,
803
                             true);
804

    
805
    Handle<String> name = Factory::LookupAsciiSymbol("context_extension");
806
    context_extension_fun->shared()->set_instance_class_name(*name);
807
    global_context()->set_context_extension_function(*context_extension_fun);
808
  }
809

    
810
  // Setup the call-as-function delegate.
811
  Handle<Code> code =
812
      Handle<Code>(Builtins::builtin(Builtins::HandleApiCallAsFunction));
813
  Handle<JSFunction> delegate =
814
      Factory::NewFunction(Factory::empty_symbol(), JS_OBJECT_TYPE,
815
                           JSObject::kHeaderSize, code, true);
816
  global_context()->set_call_as_function_delegate(*delegate);
817
  delegate->shared()->DontAdaptArguments();
818

    
819
  global_context()->set_special_function_table(Heap::empty_fixed_array());
820

    
821
  // Initialize the out of memory slot.
822
  global_context()->set_out_of_memory(Heap::false_value());
823
}
824

    
825

    
826
bool Genesis::CompileBuiltin(int index) {
827
  Vector<const char> name = Natives::GetScriptName(index);
828
  Handle<String> source_code = Bootstrapper::NativesSourceLookup(index);
829
  return CompileNative(name, source_code);
830
}
831

    
832

    
833
bool Genesis::CompileNative(Vector<const char> name, Handle<String> source) {
834
  HandleScope scope;
835
  Debugger::set_compiling_natives(true);
836
  bool result =
837
      CompileScriptCached(name, source, &natives_cache, NULL, true);
838
  ASSERT(Top::has_pending_exception() != result);
839
  if (!result) Top::clear_pending_exception();
840
  Debugger::set_compiling_natives(false);
841
  return result;
842
}
843

    
844

    
845
bool Genesis::CompileScriptCached(Vector<const char> name,
846
                                  Handle<String> source,
847
                                  SourceCodeCache* cache,
848
                                  v8::Extension* extension,
849
                                  bool use_runtime_context) {
850
  HandleScope scope;
851
  Handle<JSFunction> boilerplate;
852

    
853
  // If we can't find the function in the cache, we compile a new
854
  // function and insert it into the cache.
855
  if (!cache->Lookup(name, &boilerplate)) {
856
#ifdef DEBUG
857
    ASSERT(StringShape(*source).IsAsciiRepresentation());
858
#endif
859
    Handle<String> script_name = Factory::NewStringFromUtf8(name);
860
    boilerplate =
861
        Compiler::Compile(source, script_name, 0, 0, extension, NULL);
862
    if (boilerplate.is_null()) return false;
863
    cache->Add(name, boilerplate);
864
  }
865

    
866
  // Setup the function context. Conceptually, we should clone the
867
  // function before overwriting the context but since we're in a
868
  // single-threaded environment it is not strictly necessary.
869
  ASSERT(Top::context()->IsGlobalContext());
870
  Handle<Context> context =
871
      Handle<Context>(use_runtime_context
872
                      ? Top::context()->runtime_context()
873
                      : Top::context());
874
  Handle<JSFunction> fun =
875
      Factory::NewFunctionFromBoilerplate(boilerplate, context);
876

    
877
  // Call function using the either the runtime object or the global
878
  // object as the receiver. Provide no parameters.
879
  Handle<Object> receiver =
880
      Handle<Object>(use_runtime_context
881
                     ? Top::context()->builtins()
882
                     : Top::context()->global());
883
  bool has_pending_exception;
884
  Handle<Object> result =
885
      Execution::Call(fun, receiver, 0, NULL, &has_pending_exception);
886
  if (has_pending_exception) return false;
887
  return PendingFixups::Process(
888
      Handle<JSBuiltinsObject>(Top::context()->builtins()));
889
}
890

    
891

    
892
#define INSTALL_NATIVE(Type, name, var)                                  \
893
  Handle<String> var##_name = Factory::LookupAsciiSymbol(name);          \
894
  global_context()->set_##var(Type::cast(global_context()->              \
895
                                           builtins()->                  \
896
                                             GetProperty(*var##_name)));
897

    
898
void Genesis::InstallNativeFunctions() {
899
  HandleScope scope;
900
  INSTALL_NATIVE(JSFunction, "CreateDate", create_date_fun);
901
  INSTALL_NATIVE(JSFunction, "ToNumber", to_number_fun);
902
  INSTALL_NATIVE(JSFunction, "ToString", to_string_fun);
903
  INSTALL_NATIVE(JSFunction, "ToDetailString", to_detail_string_fun);
904
  INSTALL_NATIVE(JSFunction, "ToObject", to_object_fun);
905
  INSTALL_NATIVE(JSFunction, "ToInteger", to_integer_fun);
906
  INSTALL_NATIVE(JSFunction, "ToUint32", to_uint32_fun);
907
  INSTALL_NATIVE(JSFunction, "ToInt32", to_int32_fun);
908
  INSTALL_NATIVE(JSFunction, "ToBoolean", to_boolean_fun);
909
  INSTALL_NATIVE(JSFunction, "Instantiate", instantiate_fun);
910
  INSTALL_NATIVE(JSFunction, "ConfigureTemplateInstance",
911
                 configure_instance_fun);
912
  INSTALL_NATIVE(JSFunction, "MakeMessage", make_message_fun);
913
  INSTALL_NATIVE(JSFunction, "GetStackTraceLine", get_stack_trace_line_fun);
914
  INSTALL_NATIVE(JSObject, "functionCache", function_cache);
915
}
916

    
917
#undef INSTALL_NATIVE
918

    
919

    
920
bool Genesis::InstallNatives() {
921
  HandleScope scope;
922

    
923
  // Create a function for the builtins object. Allocate space for the
924
  // JavaScript builtins, a reference to the builtins object
925
  // (itself) and a reference to the global_context directly in the object.
926
  Handle<Code> code = Handle<Code>(Builtins::builtin(Builtins::Illegal));
927
  Handle<JSFunction> builtins_fun =
928
      Factory::NewFunction(Factory::empty_symbol(), JS_BUILTINS_OBJECT_TYPE,
929
                           JSBuiltinsObject::kSize, code, true);
930

    
931
  Handle<String> name = Factory::LookupAsciiSymbol("builtins");
932
  builtins_fun->shared()->set_instance_class_name(*name);
933
  SetExpectedNofProperties(builtins_fun, 100);
934

    
935
  // Allocate the builtins object.
936
  Handle<JSBuiltinsObject> builtins =
937
      Handle<JSBuiltinsObject>::cast(Factory::NewJSObject(builtins_fun,
938
                                                          TENURED));
939
  builtins->set_builtins(*builtins);
940
  builtins->set_global_context(*global_context());
941
  builtins->set_global_receiver(*builtins);
942

    
943
  // Setup the 'global' properties of the builtins object. The
944
  // 'global' property that refers to the global object is the only
945
  // way to get from code running in the builtins context to the
946
  // global object.
947
  static const PropertyAttributes attributes =
948
      static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE);
949
  SetProperty(builtins, Factory::LookupAsciiSymbol("global"),
950
              Handle<Object>(global_context()->global()), attributes);
951

    
952
  // Setup the reference from the global object to the builtins object.
953
  JSGlobalObject::cast(global_context()->global())->set_builtins(*builtins);
954

    
955
  // Create a bridge function that has context in the global context.
956
  Handle<JSFunction> bridge =
957
      Factory::NewFunction(Factory::empty_symbol(), Factory::undefined_value());
958
  ASSERT(bridge->context() == *Top::global_context());
959

    
960
  // Allocate the builtins context.
961
  Handle<Context> context =
962
    Factory::NewFunctionContext(Context::MIN_CONTEXT_SLOTS, bridge);
963
  context->set_global(*builtins);  // override builtins global object
964

    
965
  global_context()->set_runtime_context(*context);
966

    
967
  {  // -- S c r i p t
968
    // Builtin functions for Script.
969
    Handle<JSFunction> script_fun =
970
        InstallFunction(builtins, "Script", JS_VALUE_TYPE, JSValue::kSize,
971
                        Top::initial_object_prototype(), Builtins::Illegal,
972
                        false);
973
    Handle<JSObject> prototype =
974
        Factory::NewJSObject(Top::object_function(), TENURED);
975
    SetPrototype(script_fun, prototype);
976
    global_context()->set_script_function(*script_fun);
977

    
978
    // Add 'source' and 'data' property to scripts.
979
    PropertyAttributes common_attributes =
980
        static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
981
    Handle<Proxy> proxy_source = Factory::NewProxy(&Accessors::ScriptSource);
982
    Handle<DescriptorArray> script_descriptors =
983
        Factory::CopyAppendProxyDescriptor(
984
            Factory::empty_descriptor_array(),
985
            Factory::LookupAsciiSymbol("source"),
986
            proxy_source,
987
            common_attributes);
988
    Handle<Proxy> proxy_name = Factory::NewProxy(&Accessors::ScriptName);
989
    script_descriptors =
990
        Factory::CopyAppendProxyDescriptor(
991
            script_descriptors,
992
            Factory::LookupAsciiSymbol("name"),
993
            proxy_name,
994
            common_attributes);
995
    Handle<Proxy> proxy_id = Factory::NewProxy(&Accessors::ScriptId);
996
    script_descriptors =
997
        Factory::CopyAppendProxyDescriptor(
998
            script_descriptors,
999
            Factory::LookupAsciiSymbol("id"),
1000
            proxy_id,
1001
            common_attributes);
1002
    Handle<Proxy> proxy_line_offset =
1003
        Factory::NewProxy(&Accessors::ScriptLineOffset);
1004
    script_descriptors =
1005
        Factory::CopyAppendProxyDescriptor(
1006
            script_descriptors,
1007
            Factory::LookupAsciiSymbol("line_offset"),
1008
            proxy_line_offset,
1009
            common_attributes);
1010
    Handle<Proxy> proxy_column_offset =
1011
        Factory::NewProxy(&Accessors::ScriptColumnOffset);
1012
    script_descriptors =
1013
        Factory::CopyAppendProxyDescriptor(
1014
            script_descriptors,
1015
            Factory::LookupAsciiSymbol("column_offset"),
1016
            proxy_column_offset,
1017
            common_attributes);
1018
    Handle<Proxy> proxy_type = Factory::NewProxy(&Accessors::ScriptType);
1019
    script_descriptors =
1020
        Factory::CopyAppendProxyDescriptor(
1021
            script_descriptors,
1022
            Factory::LookupAsciiSymbol("type"),
1023
            proxy_type,
1024
            common_attributes);
1025
    Handle<Proxy> proxy_line_ends =
1026
        Factory::NewProxy(&Accessors::ScriptLineEnds);
1027
    script_descriptors =
1028
        Factory::CopyAppendProxyDescriptor(
1029
            script_descriptors,
1030
            Factory::LookupAsciiSymbol("line_ends"),
1031
            proxy_line_ends,
1032
            common_attributes);
1033

    
1034
    Handle<Map> script_map = Handle<Map>(script_fun->initial_map());
1035
    script_map->set_instance_descriptors(*script_descriptors);
1036

    
1037
    // Allocate the empty script.
1038
    Handle<Script> script = Factory::NewScript(Factory::empty_string());
1039
    script->set_type(Smi::FromInt(SCRIPT_TYPE_NATIVE));
1040
    global_context()->set_empty_script(*script);
1041
  }
1042

    
1043
  if (FLAG_natives_file == NULL) {
1044
    // Without natives file, install default natives.
1045
    for (int i = Natives::GetDelayCount();
1046
         i < Natives::GetBuiltinsCount();
1047
         i++) {
1048
      if (!CompileBuiltin(i)) return false;
1049
    }
1050

    
1051
    // Setup natives with lazy loading.
1052
    SetupLazy(Handle<JSFunction>(global_context()->date_function()),
1053
              Natives::GetIndex("date"),
1054
              Top::global_context(),
1055
              Handle<Context>(Top::context()->runtime_context()));
1056
    SetupLazy(Handle<JSFunction>(global_context()->regexp_function()),
1057
              Natives::GetIndex("regexp"),
1058
              Top::global_context(),
1059
              Handle<Context>(Top::context()->runtime_context()));
1060

    
1061
  } else if (strlen(FLAG_natives_file) != 0) {
1062
    // Otherwise install natives from natives file if file exists and
1063
    // compiles.
1064
    bool exists;
1065
    Vector<const char> source = ReadFile(FLAG_natives_file, &exists);
1066
    Handle<String> source_string = Factory::NewStringFromAscii(source);
1067
    if (source.is_empty()) return false;
1068
    bool result = CompileNative(CStrVector(FLAG_natives_file), source_string);
1069
    if (!result) return false;
1070

    
1071
  } else {
1072
    // Empty natives file name - do not install any natives.
1073
    PrintF("Warning: Running without installed natives!\n");
1074
    return true;
1075
  }
1076

    
1077
  InstallNativeFunctions();
1078

    
1079
  // Install Function.prototype.call and apply.
1080
  { Handle<String> key = Factory::function_class_symbol();
1081
    Handle<JSFunction> function =
1082
        Handle<JSFunction>::cast(GetProperty(Top::global(), key));
1083
    Handle<JSObject> proto =
1084
        Handle<JSObject>(JSObject::cast(function->instance_prototype()));
1085

    
1086
    // Install the call and the apply functions.
1087
    Handle<JSFunction> call =
1088
        InstallFunction(proto, "call", JS_OBJECT_TYPE, JSObject::kHeaderSize,
1089
                        Factory::NewJSObject(Top::object_function(), TENURED),
1090
                        Builtins::FunctionCall,
1091
                        false);
1092
    Handle<JSFunction> apply =
1093
        InstallFunction(proto, "apply", JS_OBJECT_TYPE, JSObject::kHeaderSize,
1094
                        Factory::NewJSObject(Top::object_function(), TENURED),
1095
                        Builtins::FunctionApply,
1096
                        false);
1097

    
1098
    // Make sure that Function.prototype.call appears to be compiled.
1099
    // The code will never be called, but inline caching for call will
1100
    // only work if it appears to be compiled.
1101
    call->shared()->DontAdaptArguments();
1102
    ASSERT(call->is_compiled());
1103

    
1104
    // Set the expected parameters for apply to 2; required by builtin.
1105
    apply->shared()->set_formal_parameter_count(2);
1106

    
1107
    // Set the lengths for the functions to satisfy ECMA-262.
1108
    call->shared()->set_length(1);
1109
    apply->shared()->set_length(2);
1110
  }
1111

    
1112
  // Make sure that the builtins object has fast properties.
1113
  // If the ASSERT below fails, please increase the expected number of
1114
  // properties for the builtins object.
1115
  ASSERT(builtins->HasFastProperties());
1116
#ifdef DEBUG
1117
  builtins->Verify();
1118
#endif
1119
  return true;
1120
}
1121

    
1122

    
1123
bool Genesis::InstallSpecialObjects() {
1124
  HandleScope scope;
1125
  Handle<JSGlobalObject> js_global(
1126
      JSGlobalObject::cast(global_context()->global()));
1127
  // Expose the natives in global if a name for it is specified.
1128
  if (FLAG_expose_natives_as != NULL && strlen(FLAG_expose_natives_as) != 0) {
1129
    Handle<String> natives_string =
1130
        Factory::LookupAsciiSymbol(FLAG_expose_natives_as);
1131
    SetProperty(js_global, natives_string,
1132
                Handle<JSObject>(js_global->builtins()), DONT_ENUM);
1133
  }
1134

    
1135
  // Expose the debug global object in global if a name for it is specified.
1136
  if (FLAG_expose_debug_as != NULL && strlen(FLAG_expose_debug_as) != 0) {
1137
    // If loading fails we just bail out without installing the
1138
    // debugger but without tanking the whole context.
1139
    if (!Debug::Load())
1140
      return true;
1141
    // Set the security token for the debugger context to the same as
1142
    // the shell global context to allow calling between these (otherwise
1143
    // exposing debug global object doesn't make much sense).
1144
    Debug::debug_context()->set_security_token(
1145
        global_context()->security_token());
1146

    
1147
    Handle<String> debug_string =
1148
        Factory::LookupAsciiSymbol(FLAG_expose_debug_as);
1149
    SetProperty(js_global, debug_string,
1150
        Handle<Object>(Debug::debug_context()->global_proxy()), DONT_ENUM);
1151
  }
1152

    
1153
  return true;
1154
}
1155

    
1156

    
1157
bool Genesis::InstallExtensions(v8::ExtensionConfiguration* extensions) {
1158
  // Clear coloring of extension list
1159
  v8::RegisteredExtension* current = v8::RegisteredExtension::first_extension();
1160
  while (current != NULL) {
1161
    current->set_state(v8::UNVISITED);
1162
    current = current->next();
1163
  }
1164
  // Install auto extensions
1165
  current = v8::RegisteredExtension::first_extension();
1166
  while (current != NULL) {
1167
    if (current->extension()->auto_enable())
1168
      InstallExtension(current);
1169
    current = current->next();
1170
  }
1171

    
1172
  if (FLAG_expose_gc) InstallExtension("v8/gc");
1173

    
1174
  if (extensions == NULL) return true;
1175
  // Install required extensions
1176
  int count = v8::ImplementationUtilities::GetNameCount(extensions);
1177
  const char** names = v8::ImplementationUtilities::GetNames(extensions);
1178
  for (int i = 0; i < count; i++) {
1179
    if (!InstallExtension(names[i]))
1180
      return false;
1181
  }
1182

    
1183
  return true;
1184
}
1185

    
1186

    
1187
// Installs a named extension.  This methods is unoptimized and does
1188
// not scale well if we want to support a large number of extensions.
1189
bool Genesis::InstallExtension(const char* name) {
1190
  v8::RegisteredExtension* current = v8::RegisteredExtension::first_extension();
1191
  // Loop until we find the relevant extension
1192
  while (current != NULL) {
1193
    if (strcmp(name, current->extension()->name()) == 0) break;
1194
    current = current->next();
1195
  }
1196
  // Didn't find the extension; fail.
1197
  if (current == NULL) {
1198
    v8::Utils::ReportApiFailure(
1199
        "v8::Context::New()", "Cannot find required extension");
1200
    return false;
1201
  }
1202
  return InstallExtension(current);
1203
}
1204

    
1205

    
1206
bool Genesis::InstallExtension(v8::RegisteredExtension* current) {
1207
  HandleScope scope;
1208

    
1209
  if (current->state() == v8::INSTALLED) return true;
1210
  // The current node has already been visited so there must be a
1211
  // cycle in the dependency graph; fail.
1212
  if (current->state() == v8::VISITED) {
1213
    v8::Utils::ReportApiFailure(
1214
        "v8::Context::New()", "Circular extension dependency");
1215
    return false;
1216
  }
1217
  ASSERT(current->state() == v8::UNVISITED);
1218
  current->set_state(v8::VISITED);
1219
  v8::Extension* extension = current->extension();
1220
  // Install the extension's dependencies
1221
  for (int i = 0; i < extension->dependency_count(); i++) {
1222
    if (!InstallExtension(extension->dependencies()[i])) return false;
1223
  }
1224
  Vector<const char> source = CStrVector(extension->source());
1225
  Handle<String> source_code = Factory::NewStringFromAscii(source);
1226
  bool result = CompileScriptCached(CStrVector(extension->name()),
1227
                                    source_code,
1228
                                    &extensions_cache, extension,
1229
                                    false);
1230
  ASSERT(Top::has_pending_exception() != result);
1231
  if (!result) {
1232
    Top::clear_pending_exception();
1233
    v8::Utils::ReportApiFailure(
1234
        "v8::Context::New()", "Error installing extension");
1235
  }
1236
  current->set_state(v8::INSTALLED);
1237
  return result;
1238
}
1239

    
1240

    
1241
bool Genesis::ConfigureGlobalObjects(
1242
    v8::Handle<v8::ObjectTemplate> global_proxy_template) {
1243
  Handle<JSObject> global_proxy(
1244
      JSObject::cast(global_context()->global_proxy()));
1245
  Handle<JSObject> js_global(JSObject::cast(global_context()->global()));
1246

    
1247
  if (!global_proxy_template.IsEmpty()) {
1248
    // Configure the global proxy object.
1249
    Handle<ObjectTemplateInfo> proxy_data =
1250
        v8::Utils::OpenHandle(*global_proxy_template);
1251
    if (!ConfigureApiObject(global_proxy, proxy_data)) return false;
1252

    
1253
    // Configure the inner global object.
1254
    Handle<FunctionTemplateInfo> proxy_constructor(
1255
        FunctionTemplateInfo::cast(proxy_data->constructor()));
1256
    if (!proxy_constructor->prototype_template()->IsUndefined()) {
1257
      Handle<ObjectTemplateInfo> inner_data(
1258
          ObjectTemplateInfo::cast(proxy_constructor->prototype_template()));
1259
      if (!ConfigureApiObject(js_global, inner_data)) return false;
1260
    }
1261
  }
1262

    
1263
  SetObjectPrototype(global_proxy, js_global);
1264
  return true;
1265
}
1266

    
1267

    
1268
bool Genesis::ConfigureApiObject(Handle<JSObject> object,
1269
    Handle<ObjectTemplateInfo> object_template) {
1270
  ASSERT(!object_template.is_null());
1271
  ASSERT(object->IsInstanceOf(
1272
      FunctionTemplateInfo::cast(object_template->constructor())));
1273

    
1274
  bool pending_exception = false;
1275
  Handle<JSObject> obj =
1276
      Execution::InstantiateObject(object_template, &pending_exception);
1277
  if (pending_exception) {
1278
    ASSERT(Top::has_pending_exception());
1279
    Top::clear_pending_exception();
1280
    return false;
1281
  }
1282
  TransferObject(obj, object);
1283
  return true;
1284
}
1285

    
1286

    
1287
void Genesis::TransferNamedProperties(Handle<JSObject> from,
1288
                                      Handle<JSObject> to) {
1289
  if (from->HasFastProperties()) {
1290
    Handle<DescriptorArray> descs =
1291
        Handle<DescriptorArray>(from->map()->instance_descriptors());
1292
    int offset = 0;
1293
    while (true) {
1294
      // Iterating through the descriptors is not gc safe so we have to
1295
      // store the value in a handle and create a new stream for each entry.
1296
      DescriptorReader stream(*descs, offset);
1297
      if (stream.eos()) break;
1298
      // We have to read out the next offset before we do anything that may
1299
      // cause a gc, since the DescriptorReader is not gc safe.
1300
      offset = stream.next_position();
1301
      PropertyDetails details = stream.GetDetails();
1302
      switch (details.type()) {
1303
        case FIELD: {
1304
          HandleScope inner;
1305
          Handle<String> key = Handle<String>(stream.GetKey());
1306
          int index = stream.GetFieldIndex();
1307
          Handle<Object> value = Handle<Object>(from->FastPropertyAt(index));
1308
          SetProperty(to, key, value, details.attributes());
1309
          break;
1310
        }
1311
        case CONSTANT_FUNCTION: {
1312
          HandleScope inner;
1313
          Handle<String> key = Handle<String>(stream.GetKey());
1314
          Handle<JSFunction> fun =
1315
              Handle<JSFunction>(stream.GetConstantFunction());
1316
          SetProperty(to, key, fun, details.attributes());
1317
          break;
1318
        }
1319
        case CALLBACKS: {
1320
          LookupResult result;
1321
          to->LocalLookup(stream.GetKey(), &result);
1322
          // If the property is already there we skip it
1323
          if (result.IsValid()) continue;
1324
          HandleScope inner;
1325
          Handle<DescriptorArray> inst_descs =
1326
              Handle<DescriptorArray>(to->map()->instance_descriptors());
1327
          Handle<String> key = Handle<String>(stream.GetKey());
1328
          Handle<Object> entry = Handle<Object>(stream.GetCallbacksObject());
1329
          inst_descs = Factory::CopyAppendProxyDescriptor(inst_descs,
1330
                                                          key,
1331
                                                          entry,
1332
                                                          details.attributes());
1333
          to->map()->set_instance_descriptors(*inst_descs);
1334
          break;
1335
        }
1336
        case MAP_TRANSITION:
1337
        case CONSTANT_TRANSITION:
1338
        case NULL_DESCRIPTOR:
1339
          // Ignore non-properties.
1340
          break;
1341
        case NORMAL:
1342
          // Do not occur since the from object has fast properties.
1343
        case INTERCEPTOR:
1344
          // No element in instance descriptors have interceptor type.
1345
          UNREACHABLE();
1346
          break;
1347
      }
1348
    }
1349
  } else {
1350
    Handle<Dictionary> properties =
1351
        Handle<Dictionary>(from->property_dictionary());
1352
    int capacity = properties->Capacity();
1353
    for (int i = 0; i < capacity; i++) {
1354
      Object* raw_key(properties->KeyAt(i));
1355
      if (properties->IsKey(raw_key)) {
1356
        ASSERT(raw_key->IsString());
1357
        // If the property is already there we skip it.
1358
        LookupResult result;
1359
        to->LocalLookup(String::cast(raw_key), &result);
1360
        if (result.IsValid()) continue;
1361
        // Set the property.
1362
        Handle<String> key = Handle<String>(String::cast(raw_key));
1363
        Handle<Object> value = Handle<Object>(properties->ValueAt(i));
1364
        PropertyDetails details = properties->DetailsAt(i);
1365
        SetProperty(to, key, value, details.attributes());
1366
      }
1367
    }
1368
  }
1369
}
1370

    
1371

    
1372
void Genesis::TransferIndexedProperties(Handle<JSObject> from,
1373
                                        Handle<JSObject> to) {
1374
  // Cloning the elements array is sufficient.
1375
  Handle<FixedArray> from_elements =
1376
      Handle<FixedArray>(FixedArray::cast(from->elements()));
1377
  Handle<FixedArray> to_elements = Factory::CopyFixedArray(from_elements);
1378
  to->set_elements(*to_elements);
1379
}
1380

    
1381

    
1382
void Genesis::TransferObject(Handle<JSObject> from, Handle<JSObject> to) {
1383
  HandleScope outer;
1384

    
1385
  ASSERT(!from->IsJSArray());
1386
  ASSERT(!to->IsJSArray());
1387

    
1388
  TransferNamedProperties(from, to);
1389
  TransferIndexedProperties(from, to);
1390

    
1391
  // Transfer the prototype (new map is needed).
1392
  Handle<Map> old_to_map = Handle<Map>(to->map());
1393
  Handle<Map> new_to_map = Factory::CopyMapDropTransitions(old_to_map);
1394
  new_to_map->set_prototype(from->map()->prototype());
1395
  to->set_map(*new_to_map);
1396
}
1397

    
1398

    
1399
void Genesis::MakeFunctionInstancePrototypeWritable() {
1400
  // Make a new function map so all future functions
1401
  // will have settable and enumerable prototype properties.
1402
  HandleScope scope;
1403

    
1404
  Handle<DescriptorArray> function_map_descriptors =
1405
      ComputeFunctionInstanceDescriptor(false, true);
1406
  Handle<Map> fm = Factory::CopyMap(Top::function_map());
1407
  fm->set_instance_descriptors(*function_map_descriptors);
1408
  Top::context()->global_context()->set_function_map(*fm);
1409
}
1410

    
1411

    
1412
void Genesis::AddSpecialFunction(Handle<JSObject> prototype,
1413
                                 const char* name,
1414
                                 Handle<Code> code) {
1415
  Handle<String> key = Factory::LookupAsciiSymbol(name);
1416
  Handle<Object> value = Handle<Object>(prototype->GetProperty(*key));
1417
  if (value->IsJSFunction()) {
1418
    Handle<JSFunction> optimized = Factory::NewFunction(key,
1419
                                                        JS_OBJECT_TYPE,
1420
                                                        JSObject::kHeaderSize,
1421
                                                        code,
1422
                                                        false);
1423
    optimized->shared()->DontAdaptArguments();
1424
    int len = global_context()->special_function_table()->length();
1425
    Handle<FixedArray> new_array = Factory::NewFixedArray(len + 3);
1426
    for (int index = 0; index < len; index++) {
1427
      new_array->set(index,
1428
                     global_context()->special_function_table()->get(index));
1429
    }
1430
    new_array->set(len+0, *prototype);
1431
    new_array->set(len+1, *value);
1432
    new_array->set(len+2, *optimized);
1433
    global_context()->set_special_function_table(*new_array);
1434
  }
1435
}
1436

    
1437

    
1438
void Genesis::BuildSpecialFunctionTable() {
1439
  HandleScope scope;
1440
  Handle<JSObject> global = Handle<JSObject>(global_context()->global());
1441
  // Add special versions for Array.prototype.pop and push.
1442
  Handle<JSFunction> function =
1443
      Handle<JSFunction>(
1444
          JSFunction::cast(global->GetProperty(Heap::Array_symbol())));
1445
  Handle<JSObject> prototype =
1446
      Handle<JSObject>(JSObject::cast(function->prototype()));
1447
  AddSpecialFunction(prototype, "pop",
1448
                     Handle<Code>(Builtins::builtin(Builtins::ArrayPop)));
1449
  AddSpecialFunction(prototype, "push",
1450
                     Handle<Code>(Builtins::builtin(Builtins::ArrayPush)));
1451
}
1452

    
1453

    
1454
Genesis::Genesis(Handle<Object> global_object,
1455
                 v8::Handle<v8::ObjectTemplate> global_template,
1456
                 v8::ExtensionConfiguration* extensions) {
1457
  // Link this genesis object into the stacked genesis chain. This
1458
  // must be done before any early exits because the destructor
1459
  // will always do unlinking.
1460
  previous_ = current_;
1461
  current_  = this;
1462
  result_ = NULL;
1463

    
1464
  // If V8 hasn't been and cannot be initialized, just return.
1465
  if (!V8::HasBeenSetup() && !V8::Initialize(NULL)) return;
1466

    
1467
  // Before creating the roots we must save the context and restore it
1468
  // on all function exits.
1469
  HandleScope scope;
1470
  SaveContext context;
1471

    
1472
  CreateRoots(global_template, global_object);
1473
  if (!InstallNatives()) return;
1474

    
1475
  MakeFunctionInstancePrototypeWritable();
1476
  BuildSpecialFunctionTable();
1477

    
1478
  if (!ConfigureGlobalObjects(global_template)) return;
1479

    
1480
  if (!InstallExtensions(extensions)) return;
1481

    
1482
  if (!InstallSpecialObjects()) return;
1483

    
1484
  result_ = global_context_;
1485
}
1486

    
1487

    
1488
// Support for thread preemption.
1489

    
1490
// Reserve space for statics needing saving and restoring.
1491
int Bootstrapper::ArchiveSpacePerThread() {
1492
  return Genesis::ArchiveSpacePerThread();
1493
}
1494

    
1495

    
1496
// Archive statics that are thread local.
1497
char* Bootstrapper::ArchiveState(char* to) {
1498
  return Genesis::ArchiveState(to);
1499
}
1500

    
1501

    
1502
// Restore statics that are thread local.
1503
char* Bootstrapper::RestoreState(char* from) {
1504
  return Genesis::RestoreState(from);
1505
}
1506

    
1507

    
1508
// Reserve space for statics needing saving and restoring.
1509
int Genesis::ArchiveSpacePerThread() {
1510
  return sizeof(current_);
1511
}
1512

    
1513

    
1514
// Archive statics that are thread local.
1515
char* Genesis::ArchiveState(char* to) {
1516
  *reinterpret_cast<Genesis**>(to) = current_;
1517
  current_ = NULL;
1518
  return to + sizeof(current_);
1519
}
1520

    
1521

    
1522
// Restore statics that are thread local.
1523
char* Genesis::RestoreState(char* from) {
1524
  current_ = *reinterpret_cast<Genesis**>(from);
1525
  return from + sizeof(current_);
1526
}
1527

    
1528
} }  // namespace v8::internal