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 40c0f755 Ryan
// 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