blob: 9f01664da126a448d0dce9687f73eec6450d727e [file] [log] [blame]
Ben Murdoch257744e2011-11-30 15:57:28 +00001// Copyright 2011 the V8 project authors. All rights reserved.
Steve Blocka7e24c12009-10-30 11:49:00 +00002// 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"
Iain Merrick75681382010-08-19 15:07:18 +010039#include "objects-visiting.h"
Steve Blockd0582a62009-12-15 09:54:21 +000040#include "snapshot.h"
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -080041#include "extensions/externalize-string-extension.h"
42#include "extensions/gc-extension.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000043
44namespace v8 {
45namespace internal {
46
Steve Blocka7e24c12009-10-30 11:49:00 +000047
Steve Block44f0eee2011-05-26 01:26:41 +010048NativesExternalStringResource::NativesExternalStringResource(
49 Bootstrapper* bootstrapper,
Ben Murdoch3fb3ca82011-12-02 17:19:32 +000050 const char* source,
51 size_t length)
52 : data_(source), length_(length) {
Steve Block44f0eee2011-05-26 01:26:41 +010053 if (bootstrapper->delete_these_non_arrays_on_tear_down_ == NULL) {
54 bootstrapper->delete_these_non_arrays_on_tear_down_ = new List<char*>(2);
Steve Blockd0582a62009-12-15 09:54:21 +000055 }
56 // The resources are small objects and we only make a fixed number of
57 // them, but let's clean them up on exit for neatness.
Steve Block44f0eee2011-05-26 01:26:41 +010058 bootstrapper->delete_these_non_arrays_on_tear_down_->
Steve Blockd0582a62009-12-15 09:54:21 +000059 Add(reinterpret_cast<char*>(this));
60}
Steve Blocka7e24c12009-10-30 11:49:00 +000061
62
Steve Block44f0eee2011-05-26 01:26:41 +010063Bootstrapper::Bootstrapper()
64 : nesting_(0),
65 extensions_cache_(Script::TYPE_EXTENSION),
66 delete_these_non_arrays_on_tear_down_(NULL),
67 delete_these_arrays_on_tear_down_(NULL) {
68}
69
70
Steve Blocka7e24c12009-10-30 11:49:00 +000071Handle<String> Bootstrapper::NativesSourceLookup(int index) {
72 ASSERT(0 <= index && index < Natives::GetBuiltinsCount());
Steve Block44f0eee2011-05-26 01:26:41 +010073 Isolate* isolate = Isolate::Current();
74 Factory* factory = isolate->factory();
75 Heap* heap = isolate->heap();
76 if (heap->natives_source_cache()->get(index)->IsUndefined()) {
Steve Blockd0582a62009-12-15 09:54:21 +000077 if (!Snapshot::IsEnabled() || FLAG_new_snapshot) {
78 // We can use external strings for the natives.
Ben Murdoch3fb3ca82011-12-02 17:19:32 +000079 Vector<const char> source = Natives::GetRawScriptSource(index);
Steve Blockd0582a62009-12-15 09:54:21 +000080 NativesExternalStringResource* resource =
Steve Block44f0eee2011-05-26 01:26:41 +010081 new NativesExternalStringResource(this,
Ben Murdoch3fb3ca82011-12-02 17:19:32 +000082 source.start(),
83 source.length());
Steve Blockd0582a62009-12-15 09:54:21 +000084 Handle<String> source_code =
Steve Block44f0eee2011-05-26 01:26:41 +010085 factory->NewExternalStringFromAscii(resource);
86 heap->natives_source_cache()->set(index, *source_code);
Steve Blockd0582a62009-12-15 09:54:21 +000087 } else {
88 // Old snapshot code can't cope with external strings at all.
89 Handle<String> source_code =
Ben Murdoch3fb3ca82011-12-02 17:19:32 +000090 factory->NewStringFromAscii(Natives::GetRawScriptSource(index));
Steve Block44f0eee2011-05-26 01:26:41 +010091 heap->natives_source_cache()->set(index, *source_code);
Steve Blockd0582a62009-12-15 09:54:21 +000092 }
Steve Blocka7e24c12009-10-30 11:49:00 +000093 }
Steve Block44f0eee2011-05-26 01:26:41 +010094 Handle<Object> cached_source(heap->natives_source_cache()->get(index));
Steve Blocka7e24c12009-10-30 11:49:00 +000095 return Handle<String>::cast(cached_source);
96}
97
98
Steve Blocka7e24c12009-10-30 11:49:00 +000099void Bootstrapper::Initialize(bool create_heap_objects) {
Steve Block44f0eee2011-05-26 01:26:41 +0100100 extensions_cache_.Initialize(create_heap_objects);
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800101 GCExtension::Register();
102 ExternalizeStringExtension::Register();
Steve Blocka7e24c12009-10-30 11:49:00 +0000103}
104
105
Leon Clarkee46be812010-01-19 14:06:41 +0000106char* Bootstrapper::AllocateAutoDeletedArray(int bytes) {
107 char* memory = new char[bytes];
108 if (memory != NULL) {
Steve Block44f0eee2011-05-26 01:26:41 +0100109 if (delete_these_arrays_on_tear_down_ == NULL) {
110 delete_these_arrays_on_tear_down_ = new List<char*>(2);
Leon Clarkee46be812010-01-19 14:06:41 +0000111 }
Steve Block44f0eee2011-05-26 01:26:41 +0100112 delete_these_arrays_on_tear_down_->Add(memory);
Leon Clarkee46be812010-01-19 14:06:41 +0000113 }
114 return memory;
115}
116
117
Steve Blocka7e24c12009-10-30 11:49:00 +0000118void Bootstrapper::TearDown() {
Steve Block44f0eee2011-05-26 01:26:41 +0100119 if (delete_these_non_arrays_on_tear_down_ != NULL) {
120 int len = delete_these_non_arrays_on_tear_down_->length();
Steve Blockd0582a62009-12-15 09:54:21 +0000121 ASSERT(len < 20); // Don't use this mechanism for unbounded allocations.
122 for (int i = 0; i < len; i++) {
Steve Block44f0eee2011-05-26 01:26:41 +0100123 delete delete_these_non_arrays_on_tear_down_->at(i);
124 delete_these_non_arrays_on_tear_down_->at(i) = NULL;
Steve Blockd0582a62009-12-15 09:54:21 +0000125 }
Steve Block44f0eee2011-05-26 01:26:41 +0100126 delete delete_these_non_arrays_on_tear_down_;
127 delete_these_non_arrays_on_tear_down_ = NULL;
Steve Blockd0582a62009-12-15 09:54:21 +0000128 }
129
Steve Block44f0eee2011-05-26 01:26:41 +0100130 if (delete_these_arrays_on_tear_down_ != NULL) {
131 int len = delete_these_arrays_on_tear_down_->length();
Leon Clarkee46be812010-01-19 14:06:41 +0000132 ASSERT(len < 1000); // Don't use this mechanism for unbounded allocations.
133 for (int i = 0; i < len; i++) {
Steve Block44f0eee2011-05-26 01:26:41 +0100134 delete[] delete_these_arrays_on_tear_down_->at(i);
135 delete_these_arrays_on_tear_down_->at(i) = NULL;
Leon Clarkee46be812010-01-19 14:06:41 +0000136 }
Steve Block44f0eee2011-05-26 01:26:41 +0100137 delete delete_these_arrays_on_tear_down_;
138 delete_these_arrays_on_tear_down_ = NULL;
Leon Clarkee46be812010-01-19 14:06:41 +0000139 }
140
Steve Block44f0eee2011-05-26 01:26:41 +0100141 extensions_cache_.Initialize(false); // Yes, symmetrical
Steve Blocka7e24c12009-10-30 11:49:00 +0000142}
143
144
Steve Blocka7e24c12009-10-30 11:49:00 +0000145class Genesis BASE_EMBEDDED {
146 public:
Ben Murdoch257744e2011-11-30 15:57:28 +0000147 Genesis(Isolate* isolate,
148 Handle<Object> global_object,
Steve Blocka7e24c12009-10-30 11:49:00 +0000149 v8::Handle<v8::ObjectTemplate> global_template,
150 v8::ExtensionConfiguration* extensions);
Andrei Popescu31002712010-02-23 13:46:05 +0000151 ~Genesis() { }
Steve Blocka7e24c12009-10-30 11:49:00 +0000152
153 Handle<Context> result() { return result_; }
154
155 Genesis* previous() { return previous_; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000156
Ben Murdoch257744e2011-11-30 15:57:28 +0000157 Isolate* isolate() const { return isolate_; }
158 Factory* factory() const { return isolate_->factory(); }
159 Heap* heap() const { return isolate_->heap(); }
160
Steve Blocka7e24c12009-10-30 11:49:00 +0000161 private:
162 Handle<Context> global_context_;
Ben Murdoch257744e2011-11-30 15:57:28 +0000163 Isolate* isolate_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000164
165 // There may be more than one active genesis object: When GC is
166 // triggered during environment creation there may be weak handle
167 // processing callbacks which may create new environments.
168 Genesis* previous_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000169
170 Handle<Context> global_context() { return global_context_; }
171
Andrei Popescu31002712010-02-23 13:46:05 +0000172 // Creates some basic objects. Used for creating a context from scratch.
173 void CreateRoots();
174 // Creates the empty function. Used for creating a context from scratch.
Ben Murdoch257744e2011-11-30 15:57:28 +0000175 Handle<JSFunction> CreateEmptyFunction(Isolate* isolate);
Steve Block44f0eee2011-05-26 01:26:41 +0100176 // Creates the ThrowTypeError function. ECMA 5th Ed. 13.2.3
Ben Murdoch257744e2011-11-30 15:57:28 +0000177 Handle<JSFunction> GetThrowTypeErrorFunction();
Steve Block44f0eee2011-05-26 01:26:41 +0100178
179 void CreateStrictModeFunctionMaps(Handle<JSFunction> empty);
Andrei Popescu31002712010-02-23 13:46:05 +0000180 // Creates the global objects using the global and the template passed in
181 // through the API. We call this regardless of whether we are building a
182 // context from scratch or using a deserialized one from the partial snapshot
183 // but in the latter case we don't use the objects it produces directly, as
184 // we have to used the deserialized ones that are linked together with the
185 // rest of the context snapshot.
186 Handle<JSGlobalProxy> CreateNewGlobals(
187 v8::Handle<v8::ObjectTemplate> global_template,
188 Handle<Object> global_object,
189 Handle<GlobalObject>* global_proxy_out);
190 // Hooks the given global proxy into the context. If the context was created
191 // by deserialization then this will unhook the global proxy that was
192 // deserialized, leaving the GC to pick it up.
193 void HookUpGlobalProxy(Handle<GlobalObject> inner_global,
194 Handle<JSGlobalProxy> global_proxy);
Andrei Popescu402d9372010-02-26 13:31:12 +0000195 // Similarly, we want to use the inner global that has been created by the
196 // templates passed through the API. The inner global from the snapshot is
197 // detached from the other objects in the snapshot.
198 void HookUpInnerGlobal(Handle<GlobalObject> inner_global);
Andrei Popescu31002712010-02-23 13:46:05 +0000199 // New context initialization. Used for creating a context from scratch.
200 void InitializeGlobal(Handle<GlobalObject> inner_global,
201 Handle<JSFunction> empty_function);
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000202 void InitializeExperimentalGlobal();
Andrei Popescu31002712010-02-23 13:46:05 +0000203 // Installs the contents of the native .js files on the global objects.
204 // Used for creating a context from scratch.
Steve Blocka7e24c12009-10-30 11:49:00 +0000205 void InstallNativeFunctions();
Ben Murdoch257744e2011-11-30 15:57:28 +0000206 void InstallExperimentalNativeFunctions();
Steve Blocka7e24c12009-10-30 11:49:00 +0000207 bool InstallNatives();
Ben Murdoch257744e2011-11-30 15:57:28 +0000208 bool InstallExperimentalNatives();
Ben Murdochb0fe1622011-05-05 13:52:32 +0100209 void InstallBuiltinFunctionIds();
Steve Block6ded16b2010-05-10 14:33:55 +0100210 void InstallJSFunctionResultCaches();
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100211 void InitializeNormalizedMapCaches();
Andrei Popescu31002712010-02-23 13:46:05 +0000212 // Used both for deserialized and from-scratch contexts to add the extensions
213 // provided.
214 static bool InstallExtensions(Handle<Context> global_context,
215 v8::ExtensionConfiguration* extensions);
216 static bool InstallExtension(const char* name);
217 static bool InstallExtension(v8::RegisteredExtension* current);
218 static void InstallSpecialObjects(Handle<Context> global_context);
Andrei Popescu402d9372010-02-26 13:31:12 +0000219 bool InstallJSBuiltins(Handle<JSBuiltinsObject> builtins);
Steve Blocka7e24c12009-10-30 11:49:00 +0000220 bool ConfigureApiObject(Handle<JSObject> object,
221 Handle<ObjectTemplateInfo> object_template);
222 bool ConfigureGlobalObjects(v8::Handle<v8::ObjectTemplate> global_template);
223
224 // Migrates all properties from the 'from' object to the 'to'
225 // object and overrides the prototype in 'to' with the one from
226 // 'from'.
227 void TransferObject(Handle<JSObject> from, Handle<JSObject> to);
228 void TransferNamedProperties(Handle<JSObject> from, Handle<JSObject> to);
229 void TransferIndexedProperties(Handle<JSObject> from, Handle<JSObject> to);
230
Steve Block6ded16b2010-05-10 14:33:55 +0100231 enum PrototypePropertyMode {
232 DONT_ADD_PROTOTYPE,
233 ADD_READONLY_PROTOTYPE,
234 ADD_WRITEABLE_PROTOTYPE
235 };
Steve Block44f0eee2011-05-26 01:26:41 +0100236
237 Handle<Map> CreateFunctionMap(PrototypePropertyMode prototype_mode);
238
Steve Blocka7e24c12009-10-30 11:49:00 +0000239 Handle<DescriptorArray> ComputeFunctionInstanceDescriptor(
Steve Block6ded16b2010-05-10 14:33:55 +0100240 PrototypePropertyMode prototypeMode);
Steve Blocka7e24c12009-10-30 11:49:00 +0000241 void MakeFunctionInstancePrototypeWritable();
242
Steve Block44f0eee2011-05-26 01:26:41 +0100243 Handle<Map> CreateStrictModeFunctionMap(
244 PrototypePropertyMode prototype_mode,
245 Handle<JSFunction> empty_function,
246 Handle<FixedArray> arguments_callbacks,
247 Handle<FixedArray> caller_callbacks);
248
249 Handle<DescriptorArray> ComputeStrictFunctionInstanceDescriptor(
250 PrototypePropertyMode propertyMode,
251 Handle<FixedArray> arguments,
252 Handle<FixedArray> caller);
253
Ben Murdoch257744e2011-11-30 15:57:28 +0000254 static bool CompileBuiltin(Isolate* isolate, int index);
255 static bool CompileExperimentalBuiltin(Isolate* isolate, int index);
Steve Blocka7e24c12009-10-30 11:49:00 +0000256 static bool CompileNative(Vector<const char> name, Handle<String> source);
257 static bool CompileScriptCached(Vector<const char> name,
258 Handle<String> source,
259 SourceCodeCache* cache,
260 v8::Extension* extension,
Andrei Popescu31002712010-02-23 13:46:05 +0000261 Handle<Context> top_context,
Steve Blocka7e24c12009-10-30 11:49:00 +0000262 bool use_runtime_context);
263
264 Handle<Context> result_;
Steve Block44f0eee2011-05-26 01:26:41 +0100265
266 // Function instance maps. Function literal maps are created initially with
267 // a read only prototype for the processing of JS builtins. Later the function
268 // instance maps are replaced in order to make prototype writable.
269 // These are the final, writable prototype, maps.
270 Handle<Map> function_instance_map_writable_prototype_;
271 Handle<Map> strict_mode_function_instance_map_writable_prototype_;
Ben Murdoch257744e2011-11-30 15:57:28 +0000272 Handle<JSFunction> throw_type_error_function;
Steve Block44f0eee2011-05-26 01:26:41 +0100273
Andrei Popescu31002712010-02-23 13:46:05 +0000274 BootstrapperActive active_;
275 friend class Bootstrapper;
Steve Blocka7e24c12009-10-30 11:49:00 +0000276};
277
Steve Blocka7e24c12009-10-30 11:49:00 +0000278
279void Bootstrapper::Iterate(ObjectVisitor* v) {
Steve Block44f0eee2011-05-26 01:26:41 +0100280 extensions_cache_.Iterate(v);
Steve Blockd0582a62009-12-15 09:54:21 +0000281 v->Synchronize("Extensions");
Steve Blocka7e24c12009-10-30 11:49:00 +0000282}
283
284
Steve Blocka7e24c12009-10-30 11:49:00 +0000285Handle<Context> Bootstrapper::CreateEnvironment(
Ben Murdoch257744e2011-11-30 15:57:28 +0000286 Isolate* isolate,
Steve Blocka7e24c12009-10-30 11:49:00 +0000287 Handle<Object> global_object,
288 v8::Handle<v8::ObjectTemplate> global_template,
289 v8::ExtensionConfiguration* extensions) {
Andrei Popescu31002712010-02-23 13:46:05 +0000290 HandleScope scope;
291 Handle<Context> env;
Ben Murdoch257744e2011-11-30 15:57:28 +0000292 Genesis genesis(isolate, global_object, global_template, extensions);
Andrei Popescu31002712010-02-23 13:46:05 +0000293 env = genesis.result();
294 if (!env.is_null()) {
295 if (InstallExtensions(env, extensions)) {
296 return env;
297 }
298 }
299 return Handle<Context>();
Steve Blocka7e24c12009-10-30 11:49:00 +0000300}
301
302
303static void SetObjectPrototype(Handle<JSObject> object, Handle<Object> proto) {
304 // object.__proto__ = proto;
Ben Murdoch257744e2011-11-30 15:57:28 +0000305 Factory* factory = object->GetIsolate()->factory();
Steve Blocka7e24c12009-10-30 11:49:00 +0000306 Handle<Map> old_to_map = Handle<Map>(object->map());
Ben Murdoch257744e2011-11-30 15:57:28 +0000307 Handle<Map> new_to_map = factory->CopyMapDropTransitions(old_to_map);
Steve Blocka7e24c12009-10-30 11:49:00 +0000308 new_to_map->set_prototype(*proto);
309 object->set_map(*new_to_map);
310}
311
312
313void Bootstrapper::DetachGlobal(Handle<Context> env) {
Ben Murdoch257744e2011-11-30 15:57:28 +0000314 Factory* factory = env->GetIsolate()->factory();
Steve Block44f0eee2011-05-26 01:26:41 +0100315 JSGlobalProxy::cast(env->global_proxy())->set_context(*factory->null_value());
Steve Blocka7e24c12009-10-30 11:49:00 +0000316 SetObjectPrototype(Handle<JSObject>(env->global_proxy()),
Steve Block44f0eee2011-05-26 01:26:41 +0100317 factory->null_value());
Steve Blocka7e24c12009-10-30 11:49:00 +0000318 env->set_global_proxy(env->global());
319 env->global()->set_global_receiver(env->global());
320}
321
322
Andrei Popescu74b3c142010-03-29 12:03:09 +0100323void Bootstrapper::ReattachGlobal(Handle<Context> env,
324 Handle<Object> global_object) {
325 ASSERT(global_object->IsJSGlobalProxy());
326 Handle<JSGlobalProxy> global = Handle<JSGlobalProxy>::cast(global_object);
327 env->global()->set_global_receiver(*global);
328 env->set_global_proxy(*global);
329 SetObjectPrototype(global, Handle<JSObject>(env->global()));
330 global->set_context(*env);
331}
332
333
Steve Blocka7e24c12009-10-30 11:49:00 +0000334static Handle<JSFunction> InstallFunction(Handle<JSObject> target,
335 const char* name,
336 InstanceType type,
337 int instance_size,
338 Handle<JSObject> prototype,
339 Builtins::Name call,
340 bool is_ecma_native) {
Ben Murdoch257744e2011-11-30 15:57:28 +0000341 Isolate* isolate = target->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +0100342 Factory* factory = isolate->factory();
343 Handle<String> symbol = factory->LookupAsciiSymbol(name);
344 Handle<Code> call_code = Handle<Code>(isolate->builtins()->builtin(call));
Steve Block6ded16b2010-05-10 14:33:55 +0100345 Handle<JSFunction> function = prototype.is_null() ?
Steve Block44f0eee2011-05-26 01:26:41 +0100346 factory->NewFunctionWithoutPrototype(symbol, call_code) :
347 factory->NewFunctionWithPrototype(symbol,
Steve Blocka7e24c12009-10-30 11:49:00 +0000348 type,
349 instance_size,
350 prototype,
351 call_code,
352 is_ecma_native);
Steve Block1e0659c2011-05-24 12:43:12 +0100353 SetLocalPropertyNoThrow(target, symbol, function, DONT_ENUM);
Steve Blocka7e24c12009-10-30 11:49:00 +0000354 if (is_ecma_native) {
355 function->shared()->set_instance_class_name(*symbol);
356 }
357 return function;
358}
359
360
361Handle<DescriptorArray> Genesis::ComputeFunctionInstanceDescriptor(
Steve Block6ded16b2010-05-10 14:33:55 +0100362 PrototypePropertyMode prototypeMode) {
Steve Block44f0eee2011-05-26 01:26:41 +0100363 Handle<DescriptorArray> descriptors =
Ben Murdoch257744e2011-11-30 15:57:28 +0000364 factory()->NewDescriptorArray(prototypeMode == DONT_ADD_PROTOTYPE
365 ? 4
366 : 5);
Steve Block6ded16b2010-05-10 14:33:55 +0100367 PropertyAttributes attributes =
Steve Blocka7e24c12009-10-30 11:49:00 +0000368 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
Steve Blocka7e24c12009-10-30 11:49:00 +0000369
Steve Block44f0eee2011-05-26 01:26:41 +0100370 { // Add length.
Ben Murdoch257744e2011-11-30 15:57:28 +0000371 Handle<Foreign> foreign = factory()->NewForeign(&Accessors::FunctionLength);
372 CallbacksDescriptor d(*factory()->length_symbol(), *foreign, attributes);
Steve Block44f0eee2011-05-26 01:26:41 +0100373 descriptors->Set(0, &d);
374 }
375 { // Add name.
Ben Murdoch257744e2011-11-30 15:57:28 +0000376 Handle<Foreign> foreign = factory()->NewForeign(&Accessors::FunctionName);
377 CallbacksDescriptor d(*factory()->name_symbol(), *foreign, attributes);
Steve Block44f0eee2011-05-26 01:26:41 +0100378 descriptors->Set(1, &d);
379 }
380 { // Add arguments.
Ben Murdoch257744e2011-11-30 15:57:28 +0000381 Handle<Foreign> foreign =
382 factory()->NewForeign(&Accessors::FunctionArguments);
383 CallbacksDescriptor d(*factory()->arguments_symbol(), *foreign, attributes);
Steve Block44f0eee2011-05-26 01:26:41 +0100384 descriptors->Set(2, &d);
385 }
386 { // Add caller.
Ben Murdoch257744e2011-11-30 15:57:28 +0000387 Handle<Foreign> foreign = factory()->NewForeign(&Accessors::FunctionCaller);
388 CallbacksDescriptor d(*factory()->caller_symbol(), *foreign, attributes);
Steve Block44f0eee2011-05-26 01:26:41 +0100389 descriptors->Set(3, &d);
390 }
391 if (prototypeMode != DONT_ADD_PROTOTYPE) {
392 // Add prototype.
393 if (prototypeMode == ADD_WRITEABLE_PROTOTYPE) {
394 attributes = static_cast<PropertyAttributes>(attributes & ~READ_ONLY);
395 }
Ben Murdoch257744e2011-11-30 15:57:28 +0000396 Handle<Foreign> foreign =
397 factory()->NewForeign(&Accessors::FunctionPrototype);
398 CallbacksDescriptor d(*factory()->prototype_symbol(), *foreign, attributes);
Steve Block44f0eee2011-05-26 01:26:41 +0100399 descriptors->Set(4, &d);
400 }
401 descriptors->Sort();
402 return descriptors;
403}
Steve Blocka7e24c12009-10-30 11:49:00 +0000404
Steve Blocka7e24c12009-10-30 11:49:00 +0000405
Steve Block44f0eee2011-05-26 01:26:41 +0100406Handle<Map> Genesis::CreateFunctionMap(PrototypePropertyMode prototype_mode) {
Ben Murdoch257744e2011-11-30 15:57:28 +0000407 Handle<Map> map = factory()->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
Steve Block44f0eee2011-05-26 01:26:41 +0100408 Handle<DescriptorArray> descriptors =
409 ComputeFunctionInstanceDescriptor(prototype_mode);
410 map->set_instance_descriptors(*descriptors);
411 map->set_function_with_prototype(prototype_mode != DONT_ADD_PROTOTYPE);
412 return map;
Steve Blocka7e24c12009-10-30 11:49:00 +0000413}
414
415
Ben Murdoch257744e2011-11-30 15:57:28 +0000416Handle<JSFunction> Genesis::CreateEmptyFunction(Isolate* isolate) {
Steve Block44f0eee2011-05-26 01:26:41 +0100417 // Allocate the map for function instances. Maps are allocated first and their
418 // prototypes patched later, once empty function is created.
419
Steve Blocka7e24c12009-10-30 11:49:00 +0000420 // Please note that the prototype property for function instances must be
421 // writable.
Ben Murdoch8b112d22011-06-08 16:22:53 +0100422 Handle<Map> function_instance_map =
423 CreateFunctionMap(ADD_WRITEABLE_PROTOTYPE);
424 global_context()->set_function_instance_map(*function_instance_map);
Steve Block6ded16b2010-05-10 14:33:55 +0100425
426 // Functions with this map will not have a 'prototype' property, and
427 // can not be used as constructors.
Ben Murdoch8b112d22011-06-08 16:22:53 +0100428 Handle<Map> function_without_prototype_map =
429 CreateFunctionMap(DONT_ADD_PROTOTYPE);
Steve Block6ded16b2010-05-10 14:33:55 +0100430 global_context()->set_function_without_prototype_map(
Ben Murdoch8b112d22011-06-08 16:22:53 +0100431 *function_without_prototype_map);
Steve Blocka7e24c12009-10-30 11:49:00 +0000432
Steve Block44f0eee2011-05-26 01:26:41 +0100433 // Allocate the function map. This map is temporary, used only for processing
434 // of builtins.
435 // Later the map is replaced with writable prototype map, allocated below.
Ben Murdoch8b112d22011-06-08 16:22:53 +0100436 Handle<Map> function_map = CreateFunctionMap(ADD_READONLY_PROTOTYPE);
437 global_context()->set_function_map(*function_map);
Steve Blocka7e24c12009-10-30 11:49:00 +0000438
Steve Block44f0eee2011-05-26 01:26:41 +0100439 // The final map for functions. Writeable prototype.
440 // This map is installed in MakeFunctionInstancePrototypeWritable.
441 function_instance_map_writable_prototype_ =
442 CreateFunctionMap(ADD_WRITEABLE_PROTOTYPE);
443
Steve Block44f0eee2011-05-26 01:26:41 +0100444 Factory* factory = isolate->factory();
445 Heap* heap = isolate->heap();
446
447 Handle<String> object_name = Handle<String>(heap->Object_symbol());
Steve Blocka7e24c12009-10-30 11:49:00 +0000448
449 { // --- O b j e c t ---
450 Handle<JSFunction> object_fun =
Steve Block44f0eee2011-05-26 01:26:41 +0100451 factory->NewFunction(object_name, factory->null_value());
Steve Blocka7e24c12009-10-30 11:49:00 +0000452 Handle<Map> object_function_map =
Steve Block44f0eee2011-05-26 01:26:41 +0100453 factory->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
Steve Blocka7e24c12009-10-30 11:49:00 +0000454 object_fun->set_initial_map(*object_function_map);
455 object_function_map->set_constructor(*object_fun);
456
457 global_context()->set_object_function(*object_fun);
458
459 // Allocate a new prototype for the object function.
Steve Block44f0eee2011-05-26 01:26:41 +0100460 Handle<JSObject> prototype = factory->NewJSObject(
461 isolate->object_function(),
462 TENURED);
Steve Blocka7e24c12009-10-30 11:49:00 +0000463
464 global_context()->set_initial_object_prototype(*prototype);
465 SetPrototype(object_fun, prototype);
466 object_function_map->
Steve Block44f0eee2011-05-26 01:26:41 +0100467 set_instance_descriptors(heap->empty_descriptor_array());
Steve Blocka7e24c12009-10-30 11:49:00 +0000468 }
469
470 // Allocate the empty function as the prototype for function ECMAScript
471 // 262 15.3.4.
Steve Block44f0eee2011-05-26 01:26:41 +0100472 Handle<String> symbol = factory->LookupAsciiSymbol("Empty");
Steve Blocka7e24c12009-10-30 11:49:00 +0000473 Handle<JSFunction> empty_function =
Steve Block44f0eee2011-05-26 01:26:41 +0100474 factory->NewFunctionWithoutPrototype(symbol, kNonStrictMode);
Steve Blocka7e24c12009-10-30 11:49:00 +0000475
Andrei Popescu31002712010-02-23 13:46:05 +0000476 // --- E m p t y ---
477 Handle<Code> code =
Steve Block44f0eee2011-05-26 01:26:41 +0100478 Handle<Code>(isolate->builtins()->builtin(
479 Builtins::kEmptyFunction));
Andrei Popescu31002712010-02-23 13:46:05 +0000480 empty_function->set_code(*code);
Iain Merrick75681382010-08-19 15:07:18 +0100481 empty_function->shared()->set_code(*code);
Steve Block44f0eee2011-05-26 01:26:41 +0100482 Handle<String> source = factory->NewStringFromAscii(CStrVector("() {}"));
483 Handle<Script> script = factory->NewScript(source);
Andrei Popescu31002712010-02-23 13:46:05 +0000484 script->set_type(Smi::FromInt(Script::TYPE_NATIVE));
485 empty_function->shared()->set_script(*script);
486 empty_function->shared()->set_start_position(0);
487 empty_function->shared()->set_end_position(source->length());
488 empty_function->shared()->DontAdaptArguments();
Steve Block44f0eee2011-05-26 01:26:41 +0100489
490 // Set prototypes for the function maps.
Andrei Popescu31002712010-02-23 13:46:05 +0000491 global_context()->function_map()->set_prototype(*empty_function);
492 global_context()->function_instance_map()->set_prototype(*empty_function);
Steve Block6ded16b2010-05-10 14:33:55 +0100493 global_context()->function_without_prototype_map()->
494 set_prototype(*empty_function);
Steve Block44f0eee2011-05-26 01:26:41 +0100495 function_instance_map_writable_prototype_->set_prototype(*empty_function);
Steve Blocka7e24c12009-10-30 11:49:00 +0000496
Andrei Popescu31002712010-02-23 13:46:05 +0000497 // Allocate the function map first and then patch the prototype later
Steve Block44f0eee2011-05-26 01:26:41 +0100498 Handle<Map> empty_fm = factory->CopyMapDropDescriptors(
Steve Block6ded16b2010-05-10 14:33:55 +0100499 function_without_prototype_map);
500 empty_fm->set_instance_descriptors(
Steve Block44f0eee2011-05-26 01:26:41 +0100501 function_without_prototype_map->instance_descriptors());
Andrei Popescu31002712010-02-23 13:46:05 +0000502 empty_fm->set_prototype(global_context()->object_function()->prototype());
503 empty_function->set_map(*empty_fm);
504 return empty_function;
505}
506
507
Steve Block44f0eee2011-05-26 01:26:41 +0100508Handle<DescriptorArray> Genesis::ComputeStrictFunctionInstanceDescriptor(
509 PrototypePropertyMode prototypeMode,
510 Handle<FixedArray> arguments,
511 Handle<FixedArray> caller) {
Steve Block44f0eee2011-05-26 01:26:41 +0100512 Handle<DescriptorArray> descriptors =
Ben Murdoch257744e2011-11-30 15:57:28 +0000513 factory()->NewDescriptorArray(prototypeMode == DONT_ADD_PROTOTYPE
514 ? 4
515 : 5);
Steve Block44f0eee2011-05-26 01:26:41 +0100516 PropertyAttributes attributes = static_cast<PropertyAttributes>(
517 DONT_ENUM | DONT_DELETE | READ_ONLY);
518
519 { // length
Ben Murdoch257744e2011-11-30 15:57:28 +0000520 Handle<Foreign> foreign = factory()->NewForeign(&Accessors::FunctionLength);
521 CallbacksDescriptor d(*factory()->length_symbol(), *foreign, attributes);
Steve Block44f0eee2011-05-26 01:26:41 +0100522 descriptors->Set(0, &d);
523 }
524 { // name
Ben Murdoch257744e2011-11-30 15:57:28 +0000525 Handle<Foreign> foreign = factory()->NewForeign(&Accessors::FunctionName);
526 CallbacksDescriptor d(*factory()->name_symbol(), *foreign, attributes);
Steve Block44f0eee2011-05-26 01:26:41 +0100527 descriptors->Set(1, &d);
528 }
529 { // arguments
Ben Murdoch257744e2011-11-30 15:57:28 +0000530 CallbacksDescriptor d(*factory()->arguments_symbol(),
531 *arguments,
532 attributes);
Steve Block44f0eee2011-05-26 01:26:41 +0100533 descriptors->Set(2, &d);
534 }
535 { // caller
Ben Murdoch257744e2011-11-30 15:57:28 +0000536 CallbacksDescriptor d(*factory()->caller_symbol(), *caller, attributes);
Steve Block44f0eee2011-05-26 01:26:41 +0100537 descriptors->Set(3, &d);
538 }
539
540 // prototype
541 if (prototypeMode != DONT_ADD_PROTOTYPE) {
542 if (prototypeMode == ADD_WRITEABLE_PROTOTYPE) {
543 attributes = static_cast<PropertyAttributes>(attributes & ~READ_ONLY);
544 }
Ben Murdoch257744e2011-11-30 15:57:28 +0000545 Handle<Foreign> foreign =
546 factory()->NewForeign(&Accessors::FunctionPrototype);
547 CallbacksDescriptor d(*factory()->prototype_symbol(), *foreign, attributes);
Steve Block44f0eee2011-05-26 01:26:41 +0100548 descriptors->Set(4, &d);
549 }
550
551 descriptors->Sort();
552 return descriptors;
553}
554
555
556// ECMAScript 5th Edition, 13.2.3
Ben Murdoch257744e2011-11-30 15:57:28 +0000557Handle<JSFunction> Genesis::GetThrowTypeErrorFunction() {
558 if (throw_type_error_function.is_null()) {
559 Handle<String> name = factory()->LookupAsciiSymbol("ThrowTypeError");
560 throw_type_error_function =
561 factory()->NewFunctionWithoutPrototype(name, kNonStrictMode);
562 Handle<Code> code(isolate()->builtins()->builtin(
563 Builtins::kStrictModePoisonPill));
564 throw_type_error_function->set_map(
565 global_context()->function_map());
566 throw_type_error_function->set_code(*code);
567 throw_type_error_function->shared()->set_code(*code);
568 throw_type_error_function->shared()->DontAdaptArguments();
Steve Block053d10c2011-06-13 19:13:29 +0100569
Ben Murdoch257744e2011-11-30 15:57:28 +0000570 PreventExtensions(throw_type_error_function);
571 }
572 return throw_type_error_function;
Steve Block44f0eee2011-05-26 01:26:41 +0100573}
574
575
576Handle<Map> Genesis::CreateStrictModeFunctionMap(
577 PrototypePropertyMode prototype_mode,
578 Handle<JSFunction> empty_function,
579 Handle<FixedArray> arguments_callbacks,
580 Handle<FixedArray> caller_callbacks) {
Ben Murdoch257744e2011-11-30 15:57:28 +0000581 Handle<Map> map = factory()->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
Steve Block44f0eee2011-05-26 01:26:41 +0100582 Handle<DescriptorArray> descriptors =
583 ComputeStrictFunctionInstanceDescriptor(prototype_mode,
584 arguments_callbacks,
585 caller_callbacks);
586 map->set_instance_descriptors(*descriptors);
587 map->set_function_with_prototype(prototype_mode != DONT_ADD_PROTOTYPE);
588 map->set_prototype(*empty_function);
589 return map;
590}
591
592
593void Genesis::CreateStrictModeFunctionMaps(Handle<JSFunction> empty) {
594 // Create the callbacks arrays for ThrowTypeError functions.
595 // The get/set callacks are filled in after the maps are created below.
Ben Murdoch257744e2011-11-30 15:57:28 +0000596 Factory* factory = empty->GetIsolate()->factory();
Steve Block44f0eee2011-05-26 01:26:41 +0100597 Handle<FixedArray> arguments = factory->NewFixedArray(2, TENURED);
598 Handle<FixedArray> caller = factory->NewFixedArray(2, TENURED);
599
600 // Allocate map for the strict mode function instances.
Ben Murdoch8b112d22011-06-08 16:22:53 +0100601 Handle<Map> strict_mode_function_instance_map =
602 CreateStrictModeFunctionMap(
603 ADD_WRITEABLE_PROTOTYPE, empty, arguments, caller);
Steve Block44f0eee2011-05-26 01:26:41 +0100604 global_context()->set_strict_mode_function_instance_map(
Ben Murdoch8b112d22011-06-08 16:22:53 +0100605 *strict_mode_function_instance_map);
Steve Block44f0eee2011-05-26 01:26:41 +0100606
607 // Allocate map for the prototype-less strict mode instances.
Ben Murdoch8b112d22011-06-08 16:22:53 +0100608 Handle<Map> strict_mode_function_without_prototype_map =
609 CreateStrictModeFunctionMap(
610 DONT_ADD_PROTOTYPE, empty, arguments, caller);
Steve Block44f0eee2011-05-26 01:26:41 +0100611 global_context()->set_strict_mode_function_without_prototype_map(
Ben Murdoch8b112d22011-06-08 16:22:53 +0100612 *strict_mode_function_without_prototype_map);
Steve Block44f0eee2011-05-26 01:26:41 +0100613
614 // Allocate map for the strict mode functions. This map is temporary, used
615 // only for processing of builtins.
616 // Later the map is replaced with writable prototype map, allocated below.
Ben Murdoch8b112d22011-06-08 16:22:53 +0100617 Handle<Map> strict_mode_function_map =
618 CreateStrictModeFunctionMap(
619 ADD_READONLY_PROTOTYPE, empty, arguments, caller);
Steve Block44f0eee2011-05-26 01:26:41 +0100620 global_context()->set_strict_mode_function_map(
Ben Murdoch8b112d22011-06-08 16:22:53 +0100621 *strict_mode_function_map);
Steve Block44f0eee2011-05-26 01:26:41 +0100622
623 // The final map for the strict mode functions. Writeable prototype.
624 // This map is installed in MakeFunctionInstancePrototypeWritable.
625 strict_mode_function_instance_map_writable_prototype_ =
626 CreateStrictModeFunctionMap(
627 ADD_WRITEABLE_PROTOTYPE, empty, arguments, caller);
628
Ben Murdoch257744e2011-11-30 15:57:28 +0000629 // Create the ThrowTypeError function instance.
630 Handle<JSFunction> throw_function =
631 GetThrowTypeErrorFunction();
Steve Block44f0eee2011-05-26 01:26:41 +0100632
633 // Complete the callback fixed arrays.
Ben Murdoch257744e2011-11-30 15:57:28 +0000634 arguments->set(0, *throw_function);
635 arguments->set(1, *throw_function);
636 caller->set(0, *throw_function);
637 caller->set(1, *throw_function);
Steve Block44f0eee2011-05-26 01:26:41 +0100638}
639
640
Ben Murdochb0fe1622011-05-05 13:52:32 +0100641static void AddToWeakGlobalContextList(Context* context) {
642 ASSERT(context->IsGlobalContext());
Ben Murdoch257744e2011-11-30 15:57:28 +0000643 Heap* heap = context->GetIsolate()->heap();
Ben Murdochb0fe1622011-05-05 13:52:32 +0100644#ifdef DEBUG
645 { // NOLINT
646 ASSERT(context->get(Context::NEXT_CONTEXT_LINK)->IsUndefined());
647 // Check that context is not in the list yet.
Steve Block44f0eee2011-05-26 01:26:41 +0100648 for (Object* current = heap->global_contexts_list();
Ben Murdochb0fe1622011-05-05 13:52:32 +0100649 !current->IsUndefined();
650 current = Context::cast(current)->get(Context::NEXT_CONTEXT_LINK)) {
651 ASSERT(current != context);
652 }
653 }
654#endif
Steve Block44f0eee2011-05-26 01:26:41 +0100655 context->set(Context::NEXT_CONTEXT_LINK, heap->global_contexts_list());
656 heap->set_global_contexts_list(context);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100657}
658
659
Andrei Popescu31002712010-02-23 13:46:05 +0000660void Genesis::CreateRoots() {
661 // Allocate the global context FixedArray first and then patch the
662 // closure and extension object later (we need the empty function
663 // and the global object, but in order to create those, we need the
664 // global context).
Ben Murdoch257744e2011-11-30 15:57:28 +0000665 global_context_ = Handle<Context>::cast(isolate()->global_handles()->Create(
666 *factory()->NewGlobalContext()));
Ben Murdochb0fe1622011-05-05 13:52:32 +0100667 AddToWeakGlobalContextList(*global_context_);
Ben Murdoch257744e2011-11-30 15:57:28 +0000668 isolate()->set_context(*global_context());
Andrei Popescu31002712010-02-23 13:46:05 +0000669
670 // Allocate the message listeners object.
671 {
672 v8::NeanderArray listeners;
673 global_context()->set_message_listeners(*listeners.value());
674 }
675}
676
677
678Handle<JSGlobalProxy> Genesis::CreateNewGlobals(
679 v8::Handle<v8::ObjectTemplate> global_template,
680 Handle<Object> global_object,
681 Handle<GlobalObject>* inner_global_out) {
682 // The argument global_template aka data is an ObjectTemplateInfo.
683 // It has a constructor pointer that points at global_constructor which is a
684 // FunctionTemplateInfo.
685 // The global_constructor is used to create or reinitialize the global_proxy.
686 // The global_constructor also has a prototype_template pointer that points at
687 // js_global_template which is an ObjectTemplateInfo.
688 // That in turn has a constructor pointer that points at
689 // js_global_constructor which is a FunctionTemplateInfo.
690 // js_global_constructor is used to make js_global_function
691 // js_global_function is used to make the new inner_global.
692 //
693 // --- G l o b a l ---
694 // Step 1: Create a fresh inner JSGlobalObject.
695 Handle<JSFunction> js_global_function;
696 Handle<ObjectTemplateInfo> js_global_template;
697 if (!global_template.IsEmpty()) {
698 // Get prototype template of the global_template.
699 Handle<ObjectTemplateInfo> data =
700 v8::Utils::OpenHandle(*global_template);
701 Handle<FunctionTemplateInfo> global_constructor =
702 Handle<FunctionTemplateInfo>(
703 FunctionTemplateInfo::cast(data->constructor()));
704 Handle<Object> proto_template(global_constructor->prototype_template());
705 if (!proto_template->IsUndefined()) {
706 js_global_template =
707 Handle<ObjectTemplateInfo>::cast(proto_template);
708 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000709 }
710
Andrei Popescu31002712010-02-23 13:46:05 +0000711 if (js_global_template.is_null()) {
Ben Murdoch257744e2011-11-30 15:57:28 +0000712 Handle<String> name = Handle<String>(heap()->empty_symbol());
713 Handle<Code> code = Handle<Code>(isolate()->builtins()->builtin(
Steve Block44f0eee2011-05-26 01:26:41 +0100714 Builtins::kIllegal));
Andrei Popescu31002712010-02-23 13:46:05 +0000715 js_global_function =
Ben Murdoch257744e2011-11-30 15:57:28 +0000716 factory()->NewFunction(name, JS_GLOBAL_OBJECT_TYPE,
717 JSGlobalObject::kSize, code, true);
Andrei Popescu31002712010-02-23 13:46:05 +0000718 // Change the constructor property of the prototype of the
719 // hidden global function to refer to the Object function.
720 Handle<JSObject> prototype =
721 Handle<JSObject>(
722 JSObject::cast(js_global_function->instance_prototype()));
Steve Block1e0659c2011-05-24 12:43:12 +0100723 SetLocalPropertyNoThrow(
Steve Block44f0eee2011-05-26 01:26:41 +0100724 prototype,
Ben Murdoch257744e2011-11-30 15:57:28 +0000725 factory()->constructor_symbol(),
726 isolate()->object_function(),
Steve Block44f0eee2011-05-26 01:26:41 +0100727 NONE);
Andrei Popescu31002712010-02-23 13:46:05 +0000728 } else {
729 Handle<FunctionTemplateInfo> js_global_constructor(
730 FunctionTemplateInfo::cast(js_global_template->constructor()));
731 js_global_function =
Ben Murdoch257744e2011-11-30 15:57:28 +0000732 factory()->CreateApiFunction(js_global_constructor,
733 factory()->InnerGlobalObject);
Steve Blocka7e24c12009-10-30 11:49:00 +0000734 }
735
Andrei Popescu31002712010-02-23 13:46:05 +0000736 js_global_function->initial_map()->set_is_hidden_prototype();
737 Handle<GlobalObject> inner_global =
Ben Murdoch257744e2011-11-30 15:57:28 +0000738 factory()->NewGlobalObject(js_global_function);
Andrei Popescu31002712010-02-23 13:46:05 +0000739 if (inner_global_out != NULL) {
740 *inner_global_out = inner_global;
741 }
742
743 // Step 2: create or re-initialize the global proxy object.
744 Handle<JSFunction> global_proxy_function;
745 if (global_template.IsEmpty()) {
Ben Murdoch257744e2011-11-30 15:57:28 +0000746 Handle<String> name = Handle<String>(heap()->empty_symbol());
747 Handle<Code> code = Handle<Code>(isolate()->builtins()->builtin(
Steve Block44f0eee2011-05-26 01:26:41 +0100748 Builtins::kIllegal));
Andrei Popescu31002712010-02-23 13:46:05 +0000749 global_proxy_function =
Ben Murdoch257744e2011-11-30 15:57:28 +0000750 factory()->NewFunction(name, JS_GLOBAL_PROXY_TYPE,
751 JSGlobalProxy::kSize, code, true);
Andrei Popescu31002712010-02-23 13:46:05 +0000752 } else {
753 Handle<ObjectTemplateInfo> data =
754 v8::Utils::OpenHandle(*global_template);
755 Handle<FunctionTemplateInfo> global_constructor(
756 FunctionTemplateInfo::cast(data->constructor()));
757 global_proxy_function =
Ben Murdoch257744e2011-11-30 15:57:28 +0000758 factory()->CreateApiFunction(global_constructor,
759 factory()->OuterGlobalObject);
Andrei Popescu31002712010-02-23 13:46:05 +0000760 }
761
Ben Murdoch257744e2011-11-30 15:57:28 +0000762 Handle<String> global_name = factory()->LookupAsciiSymbol("global");
Andrei Popescu31002712010-02-23 13:46:05 +0000763 global_proxy_function->shared()->set_instance_class_name(*global_name);
764 global_proxy_function->initial_map()->set_is_access_check_needed(true);
765
766 // Set global_proxy.__proto__ to js_global after ConfigureGlobalObjects
767 // Return the global proxy.
768
769 if (global_object.location() != NULL) {
770 ASSERT(global_object->IsJSGlobalProxy());
771 return ReinitializeJSGlobalProxy(
772 global_proxy_function,
773 Handle<JSGlobalProxy>::cast(global_object));
774 } else {
775 return Handle<JSGlobalProxy>::cast(
Ben Murdoch257744e2011-11-30 15:57:28 +0000776 factory()->NewJSObject(global_proxy_function, TENURED));
Andrei Popescu31002712010-02-23 13:46:05 +0000777 }
778}
779
780
781void Genesis::HookUpGlobalProxy(Handle<GlobalObject> inner_global,
782 Handle<JSGlobalProxy> global_proxy) {
783 // Set the global context for the global object.
784 inner_global->set_global_context(*global_context());
785 inner_global->set_global_receiver(*global_proxy);
786 global_proxy->set_context(*global_context());
787 global_context()->set_global_proxy(*global_proxy);
788}
789
790
Andrei Popescu402d9372010-02-26 13:31:12 +0000791void Genesis::HookUpInnerGlobal(Handle<GlobalObject> inner_global) {
792 Handle<GlobalObject> inner_global_from_snapshot(
793 GlobalObject::cast(global_context_->extension()));
794 Handle<JSBuiltinsObject> builtins_global(global_context_->builtins());
795 global_context_->set_extension(*inner_global);
796 global_context_->set_global(*inner_global);
797 global_context_->set_security_token(*inner_global);
798 static const PropertyAttributes attributes =
799 static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE);
800 ForceSetProperty(builtins_global,
Ben Murdoch257744e2011-11-30 15:57:28 +0000801 factory()->LookupAsciiSymbol("global"),
Andrei Popescu402d9372010-02-26 13:31:12 +0000802 inner_global,
803 attributes);
804 // Setup the reference from the global object to the builtins object.
805 JSGlobalObject::cast(*inner_global)->set_builtins(*builtins_global);
806 TransferNamedProperties(inner_global_from_snapshot, inner_global);
807 TransferIndexedProperties(inner_global_from_snapshot, inner_global);
808}
809
810
811// This is only called if we are not using snapshots. The equivalent
812// work in the snapshot case is done in HookUpInnerGlobal.
Andrei Popescu31002712010-02-23 13:46:05 +0000813void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
814 Handle<JSFunction> empty_function) {
815 // --- G l o b a l C o n t e x t ---
816 // Use the empty function as closure (no scope info).
817 global_context()->set_closure(*empty_function);
Andrei Popescu31002712010-02-23 13:46:05 +0000818 global_context()->set_previous(NULL);
819 // Set extension and global object.
820 global_context()->set_extension(*inner_global);
821 global_context()->set_global(*inner_global);
822 // Security setup: Set the security token of the global object to
823 // its the inner global. This makes the security check between two
824 // different contexts fail by default even in case of global
825 // object reinitialization.
826 global_context()->set_security_token(*inner_global);
827
Ben Murdoch257744e2011-11-30 15:57:28 +0000828 Isolate* isolate = inner_global->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +0100829 Factory* factory = isolate->factory();
830 Heap* heap = isolate->heap();
831
832 Handle<String> object_name = Handle<String>(heap->Object_symbol());
Steve Block1e0659c2011-05-24 12:43:12 +0100833 SetLocalPropertyNoThrow(inner_global, object_name,
Steve Block44f0eee2011-05-26 01:26:41 +0100834 isolate->object_function(), DONT_ENUM);
Andrei Popescu31002712010-02-23 13:46:05 +0000835
Steve Blocka7e24c12009-10-30 11:49:00 +0000836 Handle<JSObject> global = Handle<JSObject>(global_context()->global());
837
838 // Install global Function object
839 InstallFunction(global, "Function", JS_FUNCTION_TYPE, JSFunction::kSize,
Steve Block44f0eee2011-05-26 01:26:41 +0100840 empty_function, Builtins::kIllegal, true); // ECMA native.
Steve Blocka7e24c12009-10-30 11:49:00 +0000841
842 { // --- A r r a y ---
843 Handle<JSFunction> array_function =
844 InstallFunction(global, "Array", JS_ARRAY_TYPE, JSArray::kSize,
Steve Block44f0eee2011-05-26 01:26:41 +0100845 isolate->initial_object_prototype(),
846 Builtins::kArrayCode, true);
Steve Blocka7e24c12009-10-30 11:49:00 +0000847 array_function->shared()->set_construct_stub(
Steve Block44f0eee2011-05-26 01:26:41 +0100848 isolate->builtins()->builtin(Builtins::kArrayConstructCode));
Steve Blocka7e24c12009-10-30 11:49:00 +0000849 array_function->shared()->DontAdaptArguments();
850
851 // This seems a bit hackish, but we need to make sure Array.length
852 // is 1.
853 array_function->shared()->set_length(1);
854 Handle<DescriptorArray> array_descriptors =
Ben Murdoch257744e2011-11-30 15:57:28 +0000855 factory->CopyAppendForeignDescriptor(
Steve Block44f0eee2011-05-26 01:26:41 +0100856 factory->empty_descriptor_array(),
857 factory->length_symbol(),
Ben Murdoch257744e2011-11-30 15:57:28 +0000858 factory->NewForeign(&Accessors::ArrayLength),
Steve Blocka7e24c12009-10-30 11:49:00 +0000859 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE));
860
861 // Cache the fast JavaScript array map
862 global_context()->set_js_array_map(array_function->initial_map());
863 global_context()->js_array_map()->set_instance_descriptors(
864 *array_descriptors);
865 // array_function is used internally. JS code creating array object should
866 // search for the 'Array' property on the global object and use that one
867 // as the constructor. 'Array' property on a global object can be
868 // overwritten by JS code.
869 global_context()->set_array_function(*array_function);
870 }
871
872 { // --- N u m b e r ---
873 Handle<JSFunction> number_fun =
874 InstallFunction(global, "Number", JS_VALUE_TYPE, JSValue::kSize,
Steve Block44f0eee2011-05-26 01:26:41 +0100875 isolate->initial_object_prototype(),
876 Builtins::kIllegal, true);
Steve Blocka7e24c12009-10-30 11:49:00 +0000877 global_context()->set_number_function(*number_fun);
878 }
879
880 { // --- B o o l e a n ---
881 Handle<JSFunction> boolean_fun =
882 InstallFunction(global, "Boolean", JS_VALUE_TYPE, JSValue::kSize,
Steve Block44f0eee2011-05-26 01:26:41 +0100883 isolate->initial_object_prototype(),
884 Builtins::kIllegal, true);
Steve Blocka7e24c12009-10-30 11:49:00 +0000885 global_context()->set_boolean_function(*boolean_fun);
886 }
887
888 { // --- S t r i n g ---
889 Handle<JSFunction> string_fun =
890 InstallFunction(global, "String", JS_VALUE_TYPE, JSValue::kSize,
Steve Block44f0eee2011-05-26 01:26:41 +0100891 isolate->initial_object_prototype(),
892 Builtins::kIllegal, true);
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100893 string_fun->shared()->set_construct_stub(
Steve Block44f0eee2011-05-26 01:26:41 +0100894 isolate->builtins()->builtin(Builtins::kStringConstructCode));
Steve Blocka7e24c12009-10-30 11:49:00 +0000895 global_context()->set_string_function(*string_fun);
896 // Add 'length' property to strings.
897 Handle<DescriptorArray> string_descriptors =
Ben Murdoch257744e2011-11-30 15:57:28 +0000898 factory->CopyAppendForeignDescriptor(
Steve Block44f0eee2011-05-26 01:26:41 +0100899 factory->empty_descriptor_array(),
900 factory->length_symbol(),
Ben Murdoch257744e2011-11-30 15:57:28 +0000901 factory->NewForeign(&Accessors::StringLength),
Steve Blocka7e24c12009-10-30 11:49:00 +0000902 static_cast<PropertyAttributes>(DONT_ENUM |
903 DONT_DELETE |
904 READ_ONLY));
905
906 Handle<Map> string_map =
907 Handle<Map>(global_context()->string_function()->initial_map());
908 string_map->set_instance_descriptors(*string_descriptors);
909 }
910
911 { // --- D a t e ---
912 // Builtin functions for Date.prototype.
913 Handle<JSFunction> date_fun =
914 InstallFunction(global, "Date", JS_VALUE_TYPE, JSValue::kSize,
Steve Block44f0eee2011-05-26 01:26:41 +0100915 isolate->initial_object_prototype(),
916 Builtins::kIllegal, true);
Steve Blocka7e24c12009-10-30 11:49:00 +0000917
918 global_context()->set_date_function(*date_fun);
919 }
920
921
922 { // -- R e g E x p
923 // Builtin functions for RegExp.prototype.
924 Handle<JSFunction> regexp_fun =
925 InstallFunction(global, "RegExp", JS_REGEXP_TYPE, JSRegExp::kSize,
Steve Block44f0eee2011-05-26 01:26:41 +0100926 isolate->initial_object_prototype(),
927 Builtins::kIllegal, true);
Steve Blocka7e24c12009-10-30 11:49:00 +0000928 global_context()->set_regexp_function(*regexp_fun);
Steve Block6ded16b2010-05-10 14:33:55 +0100929
930 ASSERT(regexp_fun->has_initial_map());
931 Handle<Map> initial_map(regexp_fun->initial_map());
932
933 ASSERT_EQ(0, initial_map->inobject_properties());
934
Steve Block44f0eee2011-05-26 01:26:41 +0100935 Handle<DescriptorArray> descriptors = factory->NewDescriptorArray(5);
Steve Block6ded16b2010-05-10 14:33:55 +0100936 PropertyAttributes final =
937 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
938 int enum_index = 0;
939 {
940 // ECMA-262, section 15.10.7.1.
Steve Block44f0eee2011-05-26 01:26:41 +0100941 FieldDescriptor field(heap->source_symbol(),
Steve Block6ded16b2010-05-10 14:33:55 +0100942 JSRegExp::kSourceFieldIndex,
943 final,
944 enum_index++);
945 descriptors->Set(0, &field);
946 }
947 {
948 // ECMA-262, section 15.10.7.2.
Steve Block44f0eee2011-05-26 01:26:41 +0100949 FieldDescriptor field(heap->global_symbol(),
Steve Block6ded16b2010-05-10 14:33:55 +0100950 JSRegExp::kGlobalFieldIndex,
951 final,
952 enum_index++);
953 descriptors->Set(1, &field);
954 }
955 {
956 // ECMA-262, section 15.10.7.3.
Steve Block44f0eee2011-05-26 01:26:41 +0100957 FieldDescriptor field(heap->ignore_case_symbol(),
Steve Block6ded16b2010-05-10 14:33:55 +0100958 JSRegExp::kIgnoreCaseFieldIndex,
959 final,
960 enum_index++);
961 descriptors->Set(2, &field);
962 }
963 {
964 // ECMA-262, section 15.10.7.4.
Steve Block44f0eee2011-05-26 01:26:41 +0100965 FieldDescriptor field(heap->multiline_symbol(),
Steve Block6ded16b2010-05-10 14:33:55 +0100966 JSRegExp::kMultilineFieldIndex,
967 final,
968 enum_index++);
969 descriptors->Set(3, &field);
970 }
971 {
972 // ECMA-262, section 15.10.7.5.
973 PropertyAttributes writable =
974 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
Steve Block44f0eee2011-05-26 01:26:41 +0100975 FieldDescriptor field(heap->last_index_symbol(),
Steve Block6ded16b2010-05-10 14:33:55 +0100976 JSRegExp::kLastIndexFieldIndex,
977 writable,
978 enum_index++);
979 descriptors->Set(4, &field);
980 }
981 descriptors->SetNextEnumerationIndex(enum_index);
982 descriptors->Sort();
983
984 initial_map->set_inobject_properties(5);
985 initial_map->set_pre_allocated_property_fields(5);
986 initial_map->set_unused_property_fields(0);
987 initial_map->set_instance_size(
988 initial_map->instance_size() + 5 * kPointerSize);
989 initial_map->set_instance_descriptors(*descriptors);
Iain Merrick75681382010-08-19 15:07:18 +0100990 initial_map->set_visitor_id(StaticVisitorBase::GetVisitorId(*initial_map));
Steve Blocka7e24c12009-10-30 11:49:00 +0000991 }
992
993 { // -- J S O N
Steve Block44f0eee2011-05-26 01:26:41 +0100994 Handle<String> name = factory->NewStringFromAscii(CStrVector("JSON"));
995 Handle<JSFunction> cons = factory->NewFunction(
Steve Blocka7e24c12009-10-30 11:49:00 +0000996 name,
Steve Block44f0eee2011-05-26 01:26:41 +0100997 factory->the_hole_value());
Steve Blocka7e24c12009-10-30 11:49:00 +0000998 cons->SetInstancePrototype(global_context()->initial_object_prototype());
999 cons->SetInstanceClassName(*name);
Steve Block44f0eee2011-05-26 01:26:41 +01001000 Handle<JSObject> json_object = factory->NewJSObject(cons, TENURED);
Steve Blocka7e24c12009-10-30 11:49:00 +00001001 ASSERT(json_object->IsJSObject());
Steve Block1e0659c2011-05-24 12:43:12 +01001002 SetLocalPropertyNoThrow(global, name, json_object, DONT_ENUM);
Steve Blocka7e24c12009-10-30 11:49:00 +00001003 global_context()->set_json_object(*json_object);
1004 }
1005
1006 { // --- arguments_boilerplate_
1007 // Make sure we can recognize argument objects at runtime.
1008 // This is done by introducing an anonymous function with
1009 // class_name equals 'Arguments'.
Steve Block44f0eee2011-05-26 01:26:41 +01001010 Handle<String> symbol = factory->LookupAsciiSymbol("Arguments");
1011 Handle<Code> code = Handle<Code>(
1012 isolate->builtins()->builtin(Builtins::kIllegal));
Steve Blocka7e24c12009-10-30 11:49:00 +00001013 Handle<JSObject> prototype =
1014 Handle<JSObject>(
1015 JSObject::cast(global_context()->object_function()->prototype()));
1016
1017 Handle<JSFunction> function =
Steve Block44f0eee2011-05-26 01:26:41 +01001018 factory->NewFunctionWithPrototype(symbol,
Steve Blocka7e24c12009-10-30 11:49:00 +00001019 JS_OBJECT_TYPE,
1020 JSObject::kHeaderSize,
1021 prototype,
1022 code,
1023 false);
1024 ASSERT(!function->has_initial_map());
1025 function->shared()->set_instance_class_name(*symbol);
1026 function->shared()->set_expected_nof_properties(2);
Steve Block44f0eee2011-05-26 01:26:41 +01001027 Handle<JSObject> result = factory->NewJSObject(function);
Steve Blocka7e24c12009-10-30 11:49:00 +00001028
1029 global_context()->set_arguments_boilerplate(*result);
Steve Block44f0eee2011-05-26 01:26:41 +01001030 // Note: length must be added as the first property and
1031 // callee must be added as the second property.
1032 SetLocalPropertyNoThrow(result, factory->length_symbol(),
1033 factory->undefined_value(),
Steve Block1e0659c2011-05-24 12:43:12 +01001034 DONT_ENUM);
Steve Block44f0eee2011-05-26 01:26:41 +01001035 SetLocalPropertyNoThrow(result, factory->callee_symbol(),
1036 factory->undefined_value(),
Steve Block1e0659c2011-05-24 12:43:12 +01001037 DONT_ENUM);
Steve Blocka7e24c12009-10-30 11:49:00 +00001038
1039#ifdef DEBUG
1040 LookupResult lookup;
Steve Block44f0eee2011-05-26 01:26:41 +01001041 result->LocalLookup(heap->callee_symbol(), &lookup);
Andrei Popescu402d9372010-02-26 13:31:12 +00001042 ASSERT(lookup.IsProperty() && (lookup.type() == FIELD));
Steve Block44f0eee2011-05-26 01:26:41 +01001043 ASSERT(lookup.GetFieldIndex() == Heap::kArgumentsCalleeIndex);
Steve Blocka7e24c12009-10-30 11:49:00 +00001044
Steve Block44f0eee2011-05-26 01:26:41 +01001045 result->LocalLookup(heap->length_symbol(), &lookup);
Andrei Popescu402d9372010-02-26 13:31:12 +00001046 ASSERT(lookup.IsProperty() && (lookup.type() == FIELD));
Steve Block44f0eee2011-05-26 01:26:41 +01001047 ASSERT(lookup.GetFieldIndex() == Heap::kArgumentsLengthIndex);
Steve Blocka7e24c12009-10-30 11:49:00 +00001048
Steve Block44f0eee2011-05-26 01:26:41 +01001049 ASSERT(result->map()->inobject_properties() > Heap::kArgumentsCalleeIndex);
1050 ASSERT(result->map()->inobject_properties() > Heap::kArgumentsLengthIndex);
1051
1052 // Check the state of the object.
1053 ASSERT(result->HasFastProperties());
1054 ASSERT(result->HasFastElements());
1055#endif
1056 }
1057
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001058 { // --- aliased_arguments_boilerplate_
1059 Handle<Map> old_map(global_context()->arguments_boilerplate()->map());
1060 Handle<Map> new_map = factory->CopyMapDropTransitions(old_map);
1061 new_map->set_pre_allocated_property_fields(2);
1062 Handle<JSObject> result = factory->NewJSObjectFromMap(new_map);
1063 new_map->set_elements_kind(JSObject::NON_STRICT_ARGUMENTS_ELEMENTS);
1064 // Set up a well-formed parameter map to make assertions happy.
1065 Handle<FixedArray> elements = factory->NewFixedArray(2);
1066 elements->set_map(heap->non_strict_arguments_elements_map());
1067 Handle<FixedArray> array;
1068 array = factory->NewFixedArray(0);
1069 elements->set(0, *array);
1070 array = factory->NewFixedArray(0);
1071 elements->set(1, *array);
1072 result->set_elements(*elements);
1073 global_context()->set_aliased_arguments_boilerplate(*result);
1074 }
1075
Steve Block44f0eee2011-05-26 01:26:41 +01001076 { // --- strict mode arguments boilerplate
1077 const PropertyAttributes attributes =
1078 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
1079
1080 // Create the ThrowTypeError functions.
1081 Handle<FixedArray> callee = factory->NewFixedArray(2, TENURED);
1082 Handle<FixedArray> caller = factory->NewFixedArray(2, TENURED);
1083
Ben Murdoch257744e2011-11-30 15:57:28 +00001084 Handle<JSFunction> throw_function =
1085 GetThrowTypeErrorFunction();
Steve Block44f0eee2011-05-26 01:26:41 +01001086
1087 // Install the ThrowTypeError functions.
Ben Murdoch257744e2011-11-30 15:57:28 +00001088 callee->set(0, *throw_function);
1089 callee->set(1, *throw_function);
1090 caller->set(0, *throw_function);
1091 caller->set(1, *throw_function);
Steve Block44f0eee2011-05-26 01:26:41 +01001092
1093 // Create the descriptor array for the arguments object.
1094 Handle<DescriptorArray> descriptors = factory->NewDescriptorArray(3);
1095 { // length
1096 FieldDescriptor d(*factory->length_symbol(), 0, DONT_ENUM);
1097 descriptors->Set(0, &d);
1098 }
1099 { // callee
1100 CallbacksDescriptor d(*factory->callee_symbol(), *callee, attributes);
1101 descriptors->Set(1, &d);
1102 }
1103 { // caller
1104 CallbacksDescriptor d(*factory->caller_symbol(), *caller, attributes);
1105 descriptors->Set(2, &d);
1106 }
1107 descriptors->Sort();
1108
1109 // Create the map. Allocate one in-object field for length.
1110 Handle<Map> map = factory->NewMap(JS_OBJECT_TYPE,
1111 Heap::kArgumentsObjectSizeStrict);
1112 map->set_instance_descriptors(*descriptors);
1113 map->set_function_with_prototype(true);
1114 map->set_prototype(global_context()->object_function()->prototype());
1115 map->set_pre_allocated_property_fields(1);
1116 map->set_inobject_properties(1);
1117
1118 // Copy constructor from the non-strict arguments boilerplate.
1119 map->set_constructor(
1120 global_context()->arguments_boilerplate()->map()->constructor());
1121
1122 // Allocate the arguments boilerplate object.
1123 Handle<JSObject> result = factory->NewJSObjectFromMap(map);
1124 global_context()->set_strict_mode_arguments_boilerplate(*result);
1125
1126 // Add length property only for strict mode boilerplate.
1127 SetLocalPropertyNoThrow(result, factory->length_symbol(),
1128 factory->undefined_value(),
1129 DONT_ENUM);
1130
1131#ifdef DEBUG
1132 LookupResult lookup;
1133 result->LocalLookup(heap->length_symbol(), &lookup);
1134 ASSERT(lookup.IsProperty() && (lookup.type() == FIELD));
1135 ASSERT(lookup.GetFieldIndex() == Heap::kArgumentsLengthIndex);
1136
1137 ASSERT(result->map()->inobject_properties() > Heap::kArgumentsLengthIndex);
Steve Blocka7e24c12009-10-30 11:49:00 +00001138
1139 // Check the state of the object.
1140 ASSERT(result->HasFastProperties());
1141 ASSERT(result->HasFastElements());
1142#endif
1143 }
1144
1145 { // --- context extension
1146 // Create a function for the context extension objects.
Steve Block44f0eee2011-05-26 01:26:41 +01001147 Handle<Code> code = Handle<Code>(
1148 isolate->builtins()->builtin(Builtins::kIllegal));
Steve Blocka7e24c12009-10-30 11:49:00 +00001149 Handle<JSFunction> context_extension_fun =
Steve Block44f0eee2011-05-26 01:26:41 +01001150 factory->NewFunction(factory->empty_symbol(),
Steve Blocka7e24c12009-10-30 11:49:00 +00001151 JS_CONTEXT_EXTENSION_OBJECT_TYPE,
1152 JSObject::kHeaderSize,
1153 code,
1154 true);
1155
Steve Block44f0eee2011-05-26 01:26:41 +01001156 Handle<String> name = factory->LookupAsciiSymbol("context_extension");
Steve Blocka7e24c12009-10-30 11:49:00 +00001157 context_extension_fun->shared()->set_instance_class_name(*name);
1158 global_context()->set_context_extension_function(*context_extension_fun);
1159 }
1160
1161
1162 {
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001163 // Set up the call-as-function delegate.
Steve Blocka7e24c12009-10-30 11:49:00 +00001164 Handle<Code> code =
Steve Block44f0eee2011-05-26 01:26:41 +01001165 Handle<Code>(isolate->builtins()->builtin(
1166 Builtins::kHandleApiCallAsFunction));
Steve Blocka7e24c12009-10-30 11:49:00 +00001167 Handle<JSFunction> delegate =
Steve Block44f0eee2011-05-26 01:26:41 +01001168 factory->NewFunction(factory->empty_symbol(), JS_OBJECT_TYPE,
Steve Blocka7e24c12009-10-30 11:49:00 +00001169 JSObject::kHeaderSize, code, true);
1170 global_context()->set_call_as_function_delegate(*delegate);
1171 delegate->shared()->DontAdaptArguments();
1172 }
1173
1174 {
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001175 // Set up the call-as-constructor delegate.
Steve Blocka7e24c12009-10-30 11:49:00 +00001176 Handle<Code> code =
Steve Block44f0eee2011-05-26 01:26:41 +01001177 Handle<Code>(isolate->builtins()->builtin(
1178 Builtins::kHandleApiCallAsConstructor));
Steve Blocka7e24c12009-10-30 11:49:00 +00001179 Handle<JSFunction> delegate =
Steve Block44f0eee2011-05-26 01:26:41 +01001180 factory->NewFunction(factory->empty_symbol(), JS_OBJECT_TYPE,
Steve Blocka7e24c12009-10-30 11:49:00 +00001181 JSObject::kHeaderSize, code, true);
1182 global_context()->set_call_as_constructor_delegate(*delegate);
1183 delegate->shared()->DontAdaptArguments();
1184 }
1185
Steve Blocka7e24c12009-10-30 11:49:00 +00001186 // Initialize the out of memory slot.
Steve Block44f0eee2011-05-26 01:26:41 +01001187 global_context()->set_out_of_memory(heap->false_value());
Steve Blocka7e24c12009-10-30 11:49:00 +00001188
1189 // Initialize the data slot.
Steve Block44f0eee2011-05-26 01:26:41 +01001190 global_context()->set_data(heap->undefined_value());
Steve Blocka7e24c12009-10-30 11:49:00 +00001191}
1192
1193
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001194void Genesis::InitializeExperimentalGlobal() {
1195 Handle<JSObject> global = Handle<JSObject>(global_context()->global());
1196
1197 // TODO(mstarzinger): Move this into Genesis::InitializeGlobal once we no
1198 // longer need to live behind a flag, so WeakMap gets added to the snapshot.
1199 if (FLAG_harmony_weakmaps) { // -- W e a k M a p
1200 Handle<JSObject> prototype =
1201 factory()->NewJSObject(isolate()->object_function(), TENURED);
1202 InstallFunction(global, "WeakMap", JS_WEAK_MAP_TYPE, JSWeakMap::kSize,
1203 prototype, Builtins::kIllegal, true);
1204 }
1205}
1206
1207
Ben Murdoch257744e2011-11-30 15:57:28 +00001208bool Genesis::CompileBuiltin(Isolate* isolate, int index) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001209 Vector<const char> name = Natives::GetScriptName(index);
Steve Block44f0eee2011-05-26 01:26:41 +01001210 Handle<String> source_code =
Ben Murdoch257744e2011-11-30 15:57:28 +00001211 isolate->bootstrapper()->NativesSourceLookup(index);
1212 return CompileNative(name, source_code);
1213}
1214
1215
1216bool Genesis::CompileExperimentalBuiltin(Isolate* isolate, int index) {
1217 Vector<const char> name = ExperimentalNatives::GetScriptName(index);
1218 Factory* factory = isolate->factory();
1219 Handle<String> source_code =
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001220 factory->NewStringFromAscii(
1221 ExperimentalNatives::GetRawScriptSource(index));
Steve Blocka7e24c12009-10-30 11:49:00 +00001222 return CompileNative(name, source_code);
1223}
1224
1225
1226bool Genesis::CompileNative(Vector<const char> name, Handle<String> source) {
1227 HandleScope scope;
Ben Murdoch257744e2011-11-30 15:57:28 +00001228 Isolate* isolate = source->GetIsolate();
Steve Blocka7e24c12009-10-30 11:49:00 +00001229#ifdef ENABLE_DEBUGGER_SUPPORT
Steve Block44f0eee2011-05-26 01:26:41 +01001230 isolate->debugger()->set_compiling_natives(true);
Steve Blocka7e24c12009-10-30 11:49:00 +00001231#endif
Andrei Popescu31002712010-02-23 13:46:05 +00001232 bool result = CompileScriptCached(name,
1233 source,
1234 NULL,
1235 NULL,
Steve Block44f0eee2011-05-26 01:26:41 +01001236 Handle<Context>(isolate->context()),
Andrei Popescu31002712010-02-23 13:46:05 +00001237 true);
Steve Block44f0eee2011-05-26 01:26:41 +01001238 ASSERT(isolate->has_pending_exception() != result);
1239 if (!result) isolate->clear_pending_exception();
Steve Blocka7e24c12009-10-30 11:49:00 +00001240#ifdef ENABLE_DEBUGGER_SUPPORT
Steve Block44f0eee2011-05-26 01:26:41 +01001241 isolate->debugger()->set_compiling_natives(false);
Steve Blocka7e24c12009-10-30 11:49:00 +00001242#endif
1243 return result;
1244}
1245
1246
1247bool Genesis::CompileScriptCached(Vector<const char> name,
1248 Handle<String> source,
1249 SourceCodeCache* cache,
1250 v8::Extension* extension,
Andrei Popescu31002712010-02-23 13:46:05 +00001251 Handle<Context> top_context,
Steve Blocka7e24c12009-10-30 11:49:00 +00001252 bool use_runtime_context) {
Ben Murdoch257744e2011-11-30 15:57:28 +00001253 Factory* factory = source->GetIsolate()->factory();
Steve Blocka7e24c12009-10-30 11:49:00 +00001254 HandleScope scope;
Steve Block6ded16b2010-05-10 14:33:55 +01001255 Handle<SharedFunctionInfo> function_info;
Steve Blocka7e24c12009-10-30 11:49:00 +00001256
1257 // If we can't find the function in the cache, we compile a new
1258 // function and insert it into the cache.
Steve Block6ded16b2010-05-10 14:33:55 +01001259 if (cache == NULL || !cache->Lookup(name, &function_info)) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001260 ASSERT(source->IsAsciiRepresentation());
Steve Block44f0eee2011-05-26 01:26:41 +01001261 Handle<String> script_name = factory->NewStringFromUtf8(name);
Steve Block6ded16b2010-05-10 14:33:55 +01001262 function_info = Compiler::Compile(
Andrei Popescu31002712010-02-23 13:46:05 +00001263 source,
1264 script_name,
1265 0,
1266 0,
1267 extension,
1268 NULL,
Andrei Popescu402d9372010-02-26 13:31:12 +00001269 Handle<String>::null(),
Andrei Popescu31002712010-02-23 13:46:05 +00001270 use_runtime_context ? NATIVES_CODE : NOT_NATIVES_CODE);
Steve Block6ded16b2010-05-10 14:33:55 +01001271 if (function_info.is_null()) return false;
1272 if (cache != NULL) cache->Add(name, function_info);
Steve Blocka7e24c12009-10-30 11:49:00 +00001273 }
1274
1275 // Setup the function context. Conceptually, we should clone the
1276 // function before overwriting the context but since we're in a
1277 // single-threaded environment it is not strictly necessary.
Andrei Popescu31002712010-02-23 13:46:05 +00001278 ASSERT(top_context->IsGlobalContext());
Steve Blocka7e24c12009-10-30 11:49:00 +00001279 Handle<Context> context =
1280 Handle<Context>(use_runtime_context
Andrei Popescu31002712010-02-23 13:46:05 +00001281 ? Handle<Context>(top_context->runtime_context())
1282 : top_context);
Steve Blocka7e24c12009-10-30 11:49:00 +00001283 Handle<JSFunction> fun =
Steve Block44f0eee2011-05-26 01:26:41 +01001284 factory->NewFunctionFromSharedFunctionInfo(function_info, context);
Steve Blocka7e24c12009-10-30 11:49:00 +00001285
Leon Clarke4515c472010-02-03 11:58:03 +00001286 // Call function using either the runtime object or the global
Steve Blocka7e24c12009-10-30 11:49:00 +00001287 // object as the receiver. Provide no parameters.
1288 Handle<Object> receiver =
1289 Handle<Object>(use_runtime_context
Andrei Popescu31002712010-02-23 13:46:05 +00001290 ? top_context->builtins()
1291 : top_context->global());
Steve Blocka7e24c12009-10-30 11:49:00 +00001292 bool has_pending_exception;
Ben Murdoch257744e2011-11-30 15:57:28 +00001293 Execution::Call(fun, receiver, 0, NULL, &has_pending_exception);
Steve Blocka7e24c12009-10-30 11:49:00 +00001294 if (has_pending_exception) return false;
Andrei Popescu402d9372010-02-26 13:31:12 +00001295 return true;
Steve Blocka7e24c12009-10-30 11:49:00 +00001296}
1297
1298
Ben Murdoch257744e2011-11-30 15:57:28 +00001299#define INSTALL_NATIVE(Type, name, var) \
1300 Handle<String> var##_name = factory()->LookupAsciiSymbol(name); \
1301 Object* var##_native = \
1302 global_context()->builtins()->GetPropertyNoExceptionThrown( \
1303 *var##_name); \
Ben Murdoch8b112d22011-06-08 16:22:53 +01001304 global_context()->set_##var(Type::cast(var##_native));
Steve Blocka7e24c12009-10-30 11:49:00 +00001305
Steve Block44f0eee2011-05-26 01:26:41 +01001306
Steve Blocka7e24c12009-10-30 11:49:00 +00001307void Genesis::InstallNativeFunctions() {
1308 HandleScope scope;
1309 INSTALL_NATIVE(JSFunction, "CreateDate", create_date_fun);
1310 INSTALL_NATIVE(JSFunction, "ToNumber", to_number_fun);
1311 INSTALL_NATIVE(JSFunction, "ToString", to_string_fun);
1312 INSTALL_NATIVE(JSFunction, "ToDetailString", to_detail_string_fun);
1313 INSTALL_NATIVE(JSFunction, "ToObject", to_object_fun);
1314 INSTALL_NATIVE(JSFunction, "ToInteger", to_integer_fun);
1315 INSTALL_NATIVE(JSFunction, "ToUint32", to_uint32_fun);
1316 INSTALL_NATIVE(JSFunction, "ToInt32", to_int32_fun);
Leon Clarkee46be812010-01-19 14:06:41 +00001317 INSTALL_NATIVE(JSFunction, "GlobalEval", global_eval_fun);
Steve Blocka7e24c12009-10-30 11:49:00 +00001318 INSTALL_NATIVE(JSFunction, "Instantiate", instantiate_fun);
1319 INSTALL_NATIVE(JSFunction, "ConfigureTemplateInstance",
1320 configure_instance_fun);
Steve Blocka7e24c12009-10-30 11:49:00 +00001321 INSTALL_NATIVE(JSFunction, "GetStackTraceLine", get_stack_trace_line_fun);
1322 INSTALL_NATIVE(JSObject, "functionCache", function_cache);
1323}
1324
Ben Murdoch257744e2011-11-30 15:57:28 +00001325void Genesis::InstallExperimentalNativeFunctions() {
1326 if (FLAG_harmony_proxies) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001327 INSTALL_NATIVE(JSFunction, "DerivedHasTrap", derived_has_trap);
Ben Murdoch257744e2011-11-30 15:57:28 +00001328 INSTALL_NATIVE(JSFunction, "DerivedGetTrap", derived_get_trap);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001329 INSTALL_NATIVE(JSFunction, "DerivedSetTrap", derived_set_trap);
Ben Murdoch257744e2011-11-30 15:57:28 +00001330 }
1331}
1332
Steve Blocka7e24c12009-10-30 11:49:00 +00001333#undef INSTALL_NATIVE
1334
1335
1336bool Genesis::InstallNatives() {
1337 HandleScope scope;
1338
1339 // Create a function for the builtins object. Allocate space for the
1340 // JavaScript builtins, a reference to the builtins object
1341 // (itself) and a reference to the global_context directly in the object.
Steve Block44f0eee2011-05-26 01:26:41 +01001342 Handle<Code> code = Handle<Code>(
Ben Murdoch257744e2011-11-30 15:57:28 +00001343 isolate()->builtins()->builtin(Builtins::kIllegal));
Steve Blocka7e24c12009-10-30 11:49:00 +00001344 Handle<JSFunction> builtins_fun =
Ben Murdoch257744e2011-11-30 15:57:28 +00001345 factory()->NewFunction(factory()->empty_symbol(),
1346 JS_BUILTINS_OBJECT_TYPE,
1347 JSBuiltinsObject::kSize, code, true);
Steve Blocka7e24c12009-10-30 11:49:00 +00001348
Ben Murdoch257744e2011-11-30 15:57:28 +00001349 Handle<String> name = factory()->LookupAsciiSymbol("builtins");
Steve Blocka7e24c12009-10-30 11:49:00 +00001350 builtins_fun->shared()->set_instance_class_name(*name);
1351
1352 // Allocate the builtins object.
1353 Handle<JSBuiltinsObject> builtins =
Ben Murdoch257744e2011-11-30 15:57:28 +00001354 Handle<JSBuiltinsObject>::cast(factory()->NewGlobalObject(builtins_fun));
Steve Blocka7e24c12009-10-30 11:49:00 +00001355 builtins->set_builtins(*builtins);
1356 builtins->set_global_context(*global_context());
1357 builtins->set_global_receiver(*builtins);
1358
1359 // Setup the 'global' properties of the builtins object. The
1360 // 'global' property that refers to the global object is the only
1361 // way to get from code running in the builtins context to the
1362 // global object.
1363 static const PropertyAttributes attributes =
1364 static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE);
Ben Murdoch257744e2011-11-30 15:57:28 +00001365 Handle<String> global_symbol = factory()->LookupAsciiSymbol("global");
Steve Block1e0659c2011-05-24 12:43:12 +01001366 Handle<Object> global_obj(global_context()->global());
1367 SetLocalPropertyNoThrow(builtins, global_symbol, global_obj, attributes);
Steve Blocka7e24c12009-10-30 11:49:00 +00001368
1369 // Setup the reference from the global object to the builtins object.
1370 JSGlobalObject::cast(global_context()->global())->set_builtins(*builtins);
1371
1372 // Create a bridge function that has context in the global context.
1373 Handle<JSFunction> bridge =
Ben Murdoch257744e2011-11-30 15:57:28 +00001374 factory()->NewFunction(factory()->empty_symbol(),
1375 factory()->undefined_value());
1376 ASSERT(bridge->context() == *isolate()->global_context());
Steve Blocka7e24c12009-10-30 11:49:00 +00001377
1378 // Allocate the builtins context.
1379 Handle<Context> context =
Ben Murdoch257744e2011-11-30 15:57:28 +00001380 factory()->NewFunctionContext(Context::MIN_CONTEXT_SLOTS, bridge);
Steve Blocka7e24c12009-10-30 11:49:00 +00001381 context->set_global(*builtins); // override builtins global object
1382
1383 global_context()->set_runtime_context(*context);
1384
1385 { // -- S c r i p t
1386 // Builtin functions for Script.
1387 Handle<JSFunction> script_fun =
1388 InstallFunction(builtins, "Script", JS_VALUE_TYPE, JSValue::kSize,
Ben Murdoch257744e2011-11-30 15:57:28 +00001389 isolate()->initial_object_prototype(),
Steve Block44f0eee2011-05-26 01:26:41 +01001390 Builtins::kIllegal, false);
Steve Blocka7e24c12009-10-30 11:49:00 +00001391 Handle<JSObject> prototype =
Ben Murdoch257744e2011-11-30 15:57:28 +00001392 factory()->NewJSObject(isolate()->object_function(), TENURED);
Steve Blocka7e24c12009-10-30 11:49:00 +00001393 SetPrototype(script_fun, prototype);
1394 global_context()->set_script_function(*script_fun);
1395
1396 // Add 'source' and 'data' property to scripts.
1397 PropertyAttributes common_attributes =
1398 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
Ben Murdoch257744e2011-11-30 15:57:28 +00001399 Handle<Foreign> foreign_source =
1400 factory()->NewForeign(&Accessors::ScriptSource);
Steve Blocka7e24c12009-10-30 11:49:00 +00001401 Handle<DescriptorArray> script_descriptors =
Ben Murdoch257744e2011-11-30 15:57:28 +00001402 factory()->CopyAppendForeignDescriptor(
1403 factory()->empty_descriptor_array(),
1404 factory()->LookupAsciiSymbol("source"),
1405 foreign_source,
Steve Blocka7e24c12009-10-30 11:49:00 +00001406 common_attributes);
Ben Murdoch257744e2011-11-30 15:57:28 +00001407 Handle<Foreign> foreign_name =
1408 factory()->NewForeign(&Accessors::ScriptName);
Steve Blocka7e24c12009-10-30 11:49:00 +00001409 script_descriptors =
Ben Murdoch257744e2011-11-30 15:57:28 +00001410 factory()->CopyAppendForeignDescriptor(
Steve Blocka7e24c12009-10-30 11:49:00 +00001411 script_descriptors,
Ben Murdoch257744e2011-11-30 15:57:28 +00001412 factory()->LookupAsciiSymbol("name"),
1413 foreign_name,
Steve Blocka7e24c12009-10-30 11:49:00 +00001414 common_attributes);
Ben Murdoch257744e2011-11-30 15:57:28 +00001415 Handle<Foreign> foreign_id = factory()->NewForeign(&Accessors::ScriptId);
Steve Blocka7e24c12009-10-30 11:49:00 +00001416 script_descriptors =
Ben Murdoch257744e2011-11-30 15:57:28 +00001417 factory()->CopyAppendForeignDescriptor(
Steve Blocka7e24c12009-10-30 11:49:00 +00001418 script_descriptors,
Ben Murdoch257744e2011-11-30 15:57:28 +00001419 factory()->LookupAsciiSymbol("id"),
1420 foreign_id,
Steve Blocka7e24c12009-10-30 11:49:00 +00001421 common_attributes);
Ben Murdoch257744e2011-11-30 15:57:28 +00001422 Handle<Foreign> foreign_line_offset =
1423 factory()->NewForeign(&Accessors::ScriptLineOffset);
Steve Blocka7e24c12009-10-30 11:49:00 +00001424 script_descriptors =
Ben Murdoch257744e2011-11-30 15:57:28 +00001425 factory()->CopyAppendForeignDescriptor(
Steve Blocka7e24c12009-10-30 11:49:00 +00001426 script_descriptors,
Ben Murdoch257744e2011-11-30 15:57:28 +00001427 factory()->LookupAsciiSymbol("line_offset"),
1428 foreign_line_offset,
Steve Blocka7e24c12009-10-30 11:49:00 +00001429 common_attributes);
Ben Murdoch257744e2011-11-30 15:57:28 +00001430 Handle<Foreign> foreign_column_offset =
1431 factory()->NewForeign(&Accessors::ScriptColumnOffset);
Steve Blocka7e24c12009-10-30 11:49:00 +00001432 script_descriptors =
Ben Murdoch257744e2011-11-30 15:57:28 +00001433 factory()->CopyAppendForeignDescriptor(
Steve Blocka7e24c12009-10-30 11:49:00 +00001434 script_descriptors,
Ben Murdoch257744e2011-11-30 15:57:28 +00001435 factory()->LookupAsciiSymbol("column_offset"),
1436 foreign_column_offset,
Steve Blocka7e24c12009-10-30 11:49:00 +00001437 common_attributes);
Ben Murdoch257744e2011-11-30 15:57:28 +00001438 Handle<Foreign> foreign_data =
1439 factory()->NewForeign(&Accessors::ScriptData);
Steve Blocka7e24c12009-10-30 11:49:00 +00001440 script_descriptors =
Ben Murdoch257744e2011-11-30 15:57:28 +00001441 factory()->CopyAppendForeignDescriptor(
Steve Blocka7e24c12009-10-30 11:49:00 +00001442 script_descriptors,
Ben Murdoch257744e2011-11-30 15:57:28 +00001443 factory()->LookupAsciiSymbol("data"),
1444 foreign_data,
Steve Blocka7e24c12009-10-30 11:49:00 +00001445 common_attributes);
Ben Murdoch257744e2011-11-30 15:57:28 +00001446 Handle<Foreign> foreign_type =
1447 factory()->NewForeign(&Accessors::ScriptType);
Steve Blocka7e24c12009-10-30 11:49:00 +00001448 script_descriptors =
Ben Murdoch257744e2011-11-30 15:57:28 +00001449 factory()->CopyAppendForeignDescriptor(
Steve Blocka7e24c12009-10-30 11:49:00 +00001450 script_descriptors,
Ben Murdoch257744e2011-11-30 15:57:28 +00001451 factory()->LookupAsciiSymbol("type"),
1452 foreign_type,
Steve Blocka7e24c12009-10-30 11:49:00 +00001453 common_attributes);
Ben Murdoch257744e2011-11-30 15:57:28 +00001454 Handle<Foreign> foreign_compilation_type =
1455 factory()->NewForeign(&Accessors::ScriptCompilationType);
Steve Blocka7e24c12009-10-30 11:49:00 +00001456 script_descriptors =
Ben Murdoch257744e2011-11-30 15:57:28 +00001457 factory()->CopyAppendForeignDescriptor(
Steve Blocka7e24c12009-10-30 11:49:00 +00001458 script_descriptors,
Ben Murdoch257744e2011-11-30 15:57:28 +00001459 factory()->LookupAsciiSymbol("compilation_type"),
1460 foreign_compilation_type,
Steve Blocka7e24c12009-10-30 11:49:00 +00001461 common_attributes);
Ben Murdoch257744e2011-11-30 15:57:28 +00001462 Handle<Foreign> foreign_line_ends =
1463 factory()->NewForeign(&Accessors::ScriptLineEnds);
Steve Blocka7e24c12009-10-30 11:49:00 +00001464 script_descriptors =
Ben Murdoch257744e2011-11-30 15:57:28 +00001465 factory()->CopyAppendForeignDescriptor(
Steve Blocka7e24c12009-10-30 11:49:00 +00001466 script_descriptors,
Ben Murdoch257744e2011-11-30 15:57:28 +00001467 factory()->LookupAsciiSymbol("line_ends"),
1468 foreign_line_ends,
Steve Blocka7e24c12009-10-30 11:49:00 +00001469 common_attributes);
Ben Murdoch257744e2011-11-30 15:57:28 +00001470 Handle<Foreign> foreign_context_data =
1471 factory()->NewForeign(&Accessors::ScriptContextData);
Steve Blocka7e24c12009-10-30 11:49:00 +00001472 script_descriptors =
Ben Murdoch257744e2011-11-30 15:57:28 +00001473 factory()->CopyAppendForeignDescriptor(
Steve Blocka7e24c12009-10-30 11:49:00 +00001474 script_descriptors,
Ben Murdoch257744e2011-11-30 15:57:28 +00001475 factory()->LookupAsciiSymbol("context_data"),
1476 foreign_context_data,
Steve Blocka7e24c12009-10-30 11:49:00 +00001477 common_attributes);
Ben Murdoch257744e2011-11-30 15:57:28 +00001478 Handle<Foreign> foreign_eval_from_script =
1479 factory()->NewForeign(&Accessors::ScriptEvalFromScript);
Steve Blocka7e24c12009-10-30 11:49:00 +00001480 script_descriptors =
Ben Murdoch257744e2011-11-30 15:57:28 +00001481 factory()->CopyAppendForeignDescriptor(
Steve Blocka7e24c12009-10-30 11:49:00 +00001482 script_descriptors,
Ben Murdoch257744e2011-11-30 15:57:28 +00001483 factory()->LookupAsciiSymbol("eval_from_script"),
1484 foreign_eval_from_script,
Steve Blocka7e24c12009-10-30 11:49:00 +00001485 common_attributes);
Ben Murdoch257744e2011-11-30 15:57:28 +00001486 Handle<Foreign> foreign_eval_from_script_position =
1487 factory()->NewForeign(&Accessors::ScriptEvalFromScriptPosition);
Steve Blocka7e24c12009-10-30 11:49:00 +00001488 script_descriptors =
Ben Murdoch257744e2011-11-30 15:57:28 +00001489 factory()->CopyAppendForeignDescriptor(
Steve Blocka7e24c12009-10-30 11:49:00 +00001490 script_descriptors,
Ben Murdoch257744e2011-11-30 15:57:28 +00001491 factory()->LookupAsciiSymbol("eval_from_script_position"),
1492 foreign_eval_from_script_position,
Steve Blockd0582a62009-12-15 09:54:21 +00001493 common_attributes);
Ben Murdoch257744e2011-11-30 15:57:28 +00001494 Handle<Foreign> foreign_eval_from_function_name =
1495 factory()->NewForeign(&Accessors::ScriptEvalFromFunctionName);
Steve Blockd0582a62009-12-15 09:54:21 +00001496 script_descriptors =
Ben Murdoch257744e2011-11-30 15:57:28 +00001497 factory()->CopyAppendForeignDescriptor(
Steve Blockd0582a62009-12-15 09:54:21 +00001498 script_descriptors,
Ben Murdoch257744e2011-11-30 15:57:28 +00001499 factory()->LookupAsciiSymbol("eval_from_function_name"),
1500 foreign_eval_from_function_name,
Steve Blocka7e24c12009-10-30 11:49:00 +00001501 common_attributes);
1502
1503 Handle<Map> script_map = Handle<Map>(script_fun->initial_map());
1504 script_map->set_instance_descriptors(*script_descriptors);
1505
1506 // Allocate the empty script.
Ben Murdoch257744e2011-11-30 15:57:28 +00001507 Handle<Script> script = factory()->NewScript(factory()->empty_string());
Steve Blocka7e24c12009-10-30 11:49:00 +00001508 script->set_type(Smi::FromInt(Script::TYPE_NATIVE));
Ben Murdoch257744e2011-11-30 15:57:28 +00001509 heap()->public_set_empty_script(*script);
Steve Blocka7e24c12009-10-30 11:49:00 +00001510 }
Steve Block6ded16b2010-05-10 14:33:55 +01001511 {
1512 // Builtin function for OpaqueReference -- a JSValue-based object,
1513 // that keeps its field isolated from JavaScript code. It may store
1514 // objects, that JavaScript code may not access.
1515 Handle<JSFunction> opaque_reference_fun =
1516 InstallFunction(builtins, "OpaqueReference", JS_VALUE_TYPE,
Steve Block44f0eee2011-05-26 01:26:41 +01001517 JSValue::kSize,
Ben Murdoch257744e2011-11-30 15:57:28 +00001518 isolate()->initial_object_prototype(),
Steve Block44f0eee2011-05-26 01:26:41 +01001519 Builtins::kIllegal, false);
Steve Block6ded16b2010-05-10 14:33:55 +01001520 Handle<JSObject> prototype =
Ben Murdoch257744e2011-11-30 15:57:28 +00001521 factory()->NewJSObject(isolate()->object_function(), TENURED);
Steve Block6ded16b2010-05-10 14:33:55 +01001522 SetPrototype(opaque_reference_fun, prototype);
1523 global_context()->set_opaque_reference_function(*opaque_reference_fun);
1524 }
1525
Ben Murdoche0cee9b2011-05-25 10:26:03 +01001526 { // --- I n t e r n a l A r r a y ---
1527 // An array constructor on the builtins object that works like
1528 // the public Array constructor, except that its prototype
1529 // doesn't inherit from Object.prototype.
1530 // To be used only for internal work by builtins. Instances
1531 // must not be leaked to user code.
1532 // Only works correctly when called as a constructor. The normal
1533 // Array code uses Array.prototype as prototype when called as
1534 // a function.
1535 Handle<JSFunction> array_function =
1536 InstallFunction(builtins,
1537 "InternalArray",
1538 JS_ARRAY_TYPE,
1539 JSArray::kSize,
Ben Murdoch257744e2011-11-30 15:57:28 +00001540 isolate()->initial_object_prototype(),
Steve Block44f0eee2011-05-26 01:26:41 +01001541 Builtins::kArrayCode,
Ben Murdoche0cee9b2011-05-25 10:26:03 +01001542 true);
1543 Handle<JSObject> prototype =
Ben Murdoch257744e2011-11-30 15:57:28 +00001544 factory()->NewJSObject(isolate()->object_function(), TENURED);
Ben Murdoche0cee9b2011-05-25 10:26:03 +01001545 SetPrototype(array_function, prototype);
1546
1547 array_function->shared()->set_construct_stub(
Ben Murdoch257744e2011-11-30 15:57:28 +00001548 isolate()->builtins()->builtin(Builtins::kArrayConstructCode));
Ben Murdoche0cee9b2011-05-25 10:26:03 +01001549 array_function->shared()->DontAdaptArguments();
1550
1551 // Make "length" magic on instances.
1552 Handle<DescriptorArray> array_descriptors =
Ben Murdoch257744e2011-11-30 15:57:28 +00001553 factory()->CopyAppendForeignDescriptor(
1554 factory()->empty_descriptor_array(),
1555 factory()->length_symbol(),
1556 factory()->NewForeign(&Accessors::ArrayLength),
Ben Murdoche0cee9b2011-05-25 10:26:03 +01001557 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE));
1558
1559 array_function->initial_map()->set_instance_descriptors(
1560 *array_descriptors);
1561 }
1562
Steve Block6ded16b2010-05-10 14:33:55 +01001563 if (FLAG_disable_native_files) {
1564 PrintF("Warning: Running without installed natives!\n");
1565 return true;
1566 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001567
Andrei Popescu31002712010-02-23 13:46:05 +00001568 // Install natives.
1569 for (int i = Natives::GetDebuggerCount();
1570 i < Natives::GetBuiltinsCount();
1571 i++) {
Ben Murdoch257744e2011-11-30 15:57:28 +00001572 if (!CompileBuiltin(isolate(), i)) return false;
Andrei Popescu402d9372010-02-26 13:31:12 +00001573 // TODO(ager): We really only need to install the JS builtin
1574 // functions on the builtins object after compiling and running
1575 // runtime.js.
1576 if (!InstallJSBuiltins(builtins)) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00001577 }
1578
1579 InstallNativeFunctions();
1580
Iain Merrick75681382010-08-19 15:07:18 +01001581 // Store the map for the string prototype after the natives has been compiled
1582 // and the String function has been setup.
1583 Handle<JSFunction> string_function(global_context()->string_function());
1584 ASSERT(JSObject::cast(
1585 string_function->initial_map()->prototype())->HasFastProperties());
1586 global_context()->set_string_function_prototype_map(
1587 HeapObject::cast(string_function->initial_map()->prototype())->map());
1588
Steve Blocka7e24c12009-10-30 11:49:00 +00001589 // Install Function.prototype.call and apply.
Ben Murdoch257744e2011-11-30 15:57:28 +00001590 { Handle<String> key = factory()->function_class_symbol();
Steve Blocka7e24c12009-10-30 11:49:00 +00001591 Handle<JSFunction> function =
Ben Murdoch257744e2011-11-30 15:57:28 +00001592 Handle<JSFunction>::cast(GetProperty(isolate()->global(), key));
Steve Blocka7e24c12009-10-30 11:49:00 +00001593 Handle<JSObject> proto =
1594 Handle<JSObject>(JSObject::cast(function->instance_prototype()));
1595
1596 // Install the call and the apply functions.
1597 Handle<JSFunction> call =
1598 InstallFunction(proto, "call", JS_OBJECT_TYPE, JSObject::kHeaderSize,
Steve Block6ded16b2010-05-10 14:33:55 +01001599 Handle<JSObject>::null(),
Steve Block44f0eee2011-05-26 01:26:41 +01001600 Builtins::kFunctionCall,
Steve Blocka7e24c12009-10-30 11:49:00 +00001601 false);
1602 Handle<JSFunction> apply =
1603 InstallFunction(proto, "apply", JS_OBJECT_TYPE, JSObject::kHeaderSize,
Steve Block6ded16b2010-05-10 14:33:55 +01001604 Handle<JSObject>::null(),
Steve Block44f0eee2011-05-26 01:26:41 +01001605 Builtins::kFunctionApply,
Steve Blocka7e24c12009-10-30 11:49:00 +00001606 false);
1607
1608 // Make sure that Function.prototype.call appears to be compiled.
1609 // The code will never be called, but inline caching for call will
1610 // only work if it appears to be compiled.
1611 call->shared()->DontAdaptArguments();
1612 ASSERT(call->is_compiled());
1613
1614 // Set the expected parameters for apply to 2; required by builtin.
1615 apply->shared()->set_formal_parameter_count(2);
1616
1617 // Set the lengths for the functions to satisfy ECMA-262.
1618 call->shared()->set_length(1);
1619 apply->shared()->set_length(2);
1620 }
1621
Ben Murdoch42effa52011-08-19 16:40:31 +01001622 InstallBuiltinFunctionIds();
1623
Steve Block6ded16b2010-05-10 14:33:55 +01001624 // Create a constructor for RegExp results (a variant of Array that
1625 // predefines the two properties index and match).
1626 {
1627 // RegExpResult initial map.
1628
1629 // Find global.Array.prototype to inherit from.
1630 Handle<JSFunction> array_constructor(global_context()->array_function());
1631 Handle<JSObject> array_prototype(
1632 JSObject::cast(array_constructor->instance_prototype()));
1633
1634 // Add initial map.
1635 Handle<Map> initial_map =
Ben Murdoch257744e2011-11-30 15:57:28 +00001636 factory()->NewMap(JS_ARRAY_TYPE, JSRegExpResult::kSize);
Steve Block6ded16b2010-05-10 14:33:55 +01001637 initial_map->set_constructor(*array_constructor);
1638
1639 // Set prototype on map.
1640 initial_map->set_non_instance_prototype(false);
1641 initial_map->set_prototype(*array_prototype);
1642
1643 // Update map with length accessor from Array and add "index" and "input".
1644 Handle<Map> array_map(global_context()->js_array_map());
1645 Handle<DescriptorArray> array_descriptors(
1646 array_map->instance_descriptors());
1647 ASSERT_EQ(1, array_descriptors->number_of_descriptors());
1648
1649 Handle<DescriptorArray> reresult_descriptors =
Ben Murdoch257744e2011-11-30 15:57:28 +00001650 factory()->NewDescriptorArray(3);
Steve Block6ded16b2010-05-10 14:33:55 +01001651
1652 reresult_descriptors->CopyFrom(0, *array_descriptors, 0);
1653
1654 int enum_index = 0;
1655 {
Ben Murdoch257744e2011-11-30 15:57:28 +00001656 FieldDescriptor index_field(heap()->index_symbol(),
Steve Block6ded16b2010-05-10 14:33:55 +01001657 JSRegExpResult::kIndexIndex,
1658 NONE,
1659 enum_index++);
1660 reresult_descriptors->Set(1, &index_field);
1661 }
1662
1663 {
Ben Murdoch257744e2011-11-30 15:57:28 +00001664 FieldDescriptor input_field(heap()->input_symbol(),
Steve Block6ded16b2010-05-10 14:33:55 +01001665 JSRegExpResult::kInputIndex,
1666 NONE,
1667 enum_index++);
1668 reresult_descriptors->Set(2, &input_field);
1669 }
1670 reresult_descriptors->Sort();
1671
1672 initial_map->set_inobject_properties(2);
1673 initial_map->set_pre_allocated_property_fields(2);
1674 initial_map->set_unused_property_fields(0);
1675 initial_map->set_instance_descriptors(*reresult_descriptors);
1676
1677 global_context()->set_regexp_result_map(*initial_map);
1678 }
1679
Ben Murdoche0cee9b2011-05-25 10:26:03 +01001680
Steve Blocka7e24c12009-10-30 11:49:00 +00001681#ifdef DEBUG
1682 builtins->Verify();
1683#endif
Andrei Popescu31002712010-02-23 13:46:05 +00001684
Steve Blocka7e24c12009-10-30 11:49:00 +00001685 return true;
1686}
1687
1688
Ben Murdoch257744e2011-11-30 15:57:28 +00001689bool Genesis::InstallExperimentalNatives() {
1690 for (int i = ExperimentalNatives::GetDebuggerCount();
1691 i < ExperimentalNatives::GetBuiltinsCount();
1692 i++) {
1693 if (FLAG_harmony_proxies &&
1694 strcmp(ExperimentalNatives::GetScriptName(i).start(),
1695 "native proxy.js") == 0) {
1696 if (!CompileExperimentalBuiltin(isolate(), i)) return false;
1697 }
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001698 if (FLAG_harmony_weakmaps &&
1699 strcmp(ExperimentalNatives::GetScriptName(i).start(),
1700 "native weakmap.js") == 0) {
1701 if (!CompileExperimentalBuiltin(isolate(), i)) return false;
1702 }
Ben Murdoch257744e2011-11-30 15:57:28 +00001703 }
1704
1705 InstallExperimentalNativeFunctions();
1706
1707 return true;
1708}
1709
1710
Ben Murdochb0fe1622011-05-05 13:52:32 +01001711static Handle<JSObject> ResolveBuiltinIdHolder(
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001712 Handle<Context> global_context,
1713 const char* holder_expr) {
Ben Murdoch257744e2011-11-30 15:57:28 +00001714 Factory* factory = global_context->GetIsolate()->factory();
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001715 Handle<GlobalObject> global(global_context->global());
1716 const char* period_pos = strchr(holder_expr, '.');
1717 if (period_pos == NULL) {
1718 return Handle<JSObject>::cast(
Steve Block44f0eee2011-05-26 01:26:41 +01001719 GetProperty(global, factory->LookupAsciiSymbol(holder_expr)));
Steve Block59151502010-09-22 15:07:15 +01001720 }
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001721 ASSERT_EQ(".prototype", period_pos);
1722 Vector<const char> property(holder_expr,
1723 static_cast<int>(period_pos - holder_expr));
1724 Handle<JSFunction> function = Handle<JSFunction>::cast(
Steve Block44f0eee2011-05-26 01:26:41 +01001725 GetProperty(global, factory->LookupSymbol(property)));
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001726 return Handle<JSObject>(JSObject::cast(function->prototype()));
1727}
1728
1729
Ben Murdochb0fe1622011-05-05 13:52:32 +01001730static void InstallBuiltinFunctionId(Handle<JSObject> holder,
1731 const char* function_name,
1732 BuiltinFunctionId id) {
Ben Murdoch257744e2011-11-30 15:57:28 +00001733 Factory* factory = holder->GetIsolate()->factory();
1734 Handle<String> name = factory->LookupAsciiSymbol(function_name);
John Reck59135872010-11-02 12:39:01 -07001735 Object* function_object = holder->GetProperty(*name)->ToObjectUnchecked();
1736 Handle<JSFunction> function(JSFunction::cast(function_object));
Kristian Monsen25f61362010-05-21 11:50:48 +01001737 function->shared()->set_function_data(Smi::FromInt(id));
1738}
1739
1740
Ben Murdochb0fe1622011-05-05 13:52:32 +01001741void Genesis::InstallBuiltinFunctionIds() {
Kristian Monsen25f61362010-05-21 11:50:48 +01001742 HandleScope scope;
Ben Murdochb0fe1622011-05-05 13:52:32 +01001743#define INSTALL_BUILTIN_ID(holder_expr, fun_name, name) \
1744 { \
1745 Handle<JSObject> holder = ResolveBuiltinIdHolder( \
1746 global_context(), #holder_expr); \
1747 BuiltinFunctionId id = k##name; \
1748 InstallBuiltinFunctionId(holder, #fun_name, id); \
Kristian Monsen25f61362010-05-21 11:50:48 +01001749 }
Ben Murdochb0fe1622011-05-05 13:52:32 +01001750 FUNCTIONS_WITH_ID_LIST(INSTALL_BUILTIN_ID)
1751#undef INSTALL_BUILTIN_ID
Kristian Monsen25f61362010-05-21 11:50:48 +01001752}
1753
1754
Steve Block6ded16b2010-05-10 14:33:55 +01001755// Do not forget to update macros.py with named constant
1756// of cache id.
1757#define JSFUNCTION_RESULT_CACHE_LIST(F) \
1758 F(16, global_context()->regexp_function())
1759
1760
Ben Murdoch257744e2011-11-30 15:57:28 +00001761static FixedArray* CreateCache(int size, Handle<JSFunction> factory_function) {
1762 Factory* factory = factory_function->GetIsolate()->factory();
Steve Block6ded16b2010-05-10 14:33:55 +01001763 // Caches are supposed to live for a long time, allocate in old space.
1764 int array_size = JSFunctionResultCache::kEntriesIndex + 2 * size;
1765 // Cannot use cast as object is not fully initialized yet.
1766 JSFunctionResultCache* cache = reinterpret_cast<JSFunctionResultCache*>(
Ben Murdoch257744e2011-11-30 15:57:28 +00001767 *factory->NewFixedArrayWithHoles(array_size, TENURED));
1768 cache->set(JSFunctionResultCache::kFactoryIndex, *factory_function);
Steve Block6ded16b2010-05-10 14:33:55 +01001769 cache->MakeZeroSize();
1770 return cache;
1771}
1772
1773
1774void Genesis::InstallJSFunctionResultCaches() {
1775 const int kNumberOfCaches = 0 +
1776#define F(size, func) + 1
1777 JSFUNCTION_RESULT_CACHE_LIST(F)
1778#undef F
1779 ;
1780
Steve Block44f0eee2011-05-26 01:26:41 +01001781 Handle<FixedArray> caches = FACTORY->NewFixedArray(kNumberOfCaches, TENURED);
Steve Block6ded16b2010-05-10 14:33:55 +01001782
1783 int index = 0;
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001784
Ben Murdoch257744e2011-11-30 15:57:28 +00001785#define F(size, func) do { \
1786 FixedArray* cache = CreateCache((size), Handle<JSFunction>(func)); \
1787 caches->set(index++, cache); \
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001788 } while (false)
1789
1790 JSFUNCTION_RESULT_CACHE_LIST(F);
1791
Steve Block6ded16b2010-05-10 14:33:55 +01001792#undef F
1793
1794 global_context()->set_jsfunction_result_caches(*caches);
1795}
1796
1797
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001798void Genesis::InitializeNormalizedMapCaches() {
1799 Handle<FixedArray> array(
Steve Block44f0eee2011-05-26 01:26:41 +01001800 FACTORY->NewFixedArray(NormalizedMapCache::kEntries, TENURED));
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001801 global_context()->set_normalized_map_cache(NormalizedMapCache::cast(*array));
1802}
1803
1804
Andrei Popescu31002712010-02-23 13:46:05 +00001805bool Bootstrapper::InstallExtensions(Handle<Context> global_context,
1806 v8::ExtensionConfiguration* extensions) {
Ben Murdoch257744e2011-11-30 15:57:28 +00001807 Isolate* isolate = global_context->GetIsolate();
Andrei Popescu31002712010-02-23 13:46:05 +00001808 BootstrapperActive active;
Steve Block44f0eee2011-05-26 01:26:41 +01001809 SaveContext saved_context(isolate);
1810 isolate->set_context(*global_context);
Andrei Popescu31002712010-02-23 13:46:05 +00001811 if (!Genesis::InstallExtensions(global_context, extensions)) return false;
1812 Genesis::InstallSpecialObjects(global_context);
1813 return true;
1814}
1815
1816
1817void Genesis::InstallSpecialObjects(Handle<Context> global_context) {
Ben Murdoch257744e2011-11-30 15:57:28 +00001818 Factory* factory = global_context->GetIsolate()->factory();
Steve Blocka7e24c12009-10-30 11:49:00 +00001819 HandleScope scope;
1820 Handle<JSGlobalObject> js_global(
Andrei Popescu31002712010-02-23 13:46:05 +00001821 JSGlobalObject::cast(global_context->global()));
Steve Blocka7e24c12009-10-30 11:49:00 +00001822 // Expose the natives in global if a name for it is specified.
1823 if (FLAG_expose_natives_as != NULL && strlen(FLAG_expose_natives_as) != 0) {
1824 Handle<String> natives_string =
Steve Block44f0eee2011-05-26 01:26:41 +01001825 factory->LookupAsciiSymbol(FLAG_expose_natives_as);
Steve Block1e0659c2011-05-24 12:43:12 +01001826 SetLocalPropertyNoThrow(js_global, natives_string,
1827 Handle<JSObject>(js_global->builtins()), DONT_ENUM);
Steve Blocka7e24c12009-10-30 11:49:00 +00001828 }
1829
1830 Handle<Object> Error = GetProperty(js_global, "Error");
1831 if (Error->IsJSObject()) {
Steve Block44f0eee2011-05-26 01:26:41 +01001832 Handle<String> name = factory->LookupAsciiSymbol("stackTraceLimit");
Steve Block1e0659c2011-05-24 12:43:12 +01001833 SetLocalPropertyNoThrow(Handle<JSObject>::cast(Error),
1834 name,
1835 Handle<Smi>(Smi::FromInt(FLAG_stack_trace_limit)),
1836 NONE);
Steve Blocka7e24c12009-10-30 11:49:00 +00001837 }
1838
1839#ifdef ENABLE_DEBUGGER_SUPPORT
1840 // Expose the debug global object in global if a name for it is specified.
1841 if (FLAG_expose_debug_as != NULL && strlen(FLAG_expose_debug_as) != 0) {
Steve Block44f0eee2011-05-26 01:26:41 +01001842 Debug* debug = Isolate::Current()->debug();
Steve Blocka7e24c12009-10-30 11:49:00 +00001843 // If loading fails we just bail out without installing the
1844 // debugger but without tanking the whole context.
Steve Block44f0eee2011-05-26 01:26:41 +01001845 if (!debug->Load()) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00001846 // Set the security token for the debugger context to the same as
1847 // the shell global context to allow calling between these (otherwise
1848 // exposing debug global object doesn't make much sense).
Steve Block44f0eee2011-05-26 01:26:41 +01001849 debug->debug_context()->set_security_token(
Andrei Popescu31002712010-02-23 13:46:05 +00001850 global_context->security_token());
Steve Blocka7e24c12009-10-30 11:49:00 +00001851
1852 Handle<String> debug_string =
Steve Block44f0eee2011-05-26 01:26:41 +01001853 factory->LookupAsciiSymbol(FLAG_expose_debug_as);
1854 Handle<Object> global_proxy(debug->debug_context()->global_proxy());
Steve Block1e0659c2011-05-24 12:43:12 +01001855 SetLocalPropertyNoThrow(js_global, debug_string, global_proxy, DONT_ENUM);
Steve Blocka7e24c12009-10-30 11:49:00 +00001856 }
1857#endif
Steve Blocka7e24c12009-10-30 11:49:00 +00001858}
1859
1860
Andrei Popescu31002712010-02-23 13:46:05 +00001861bool Genesis::InstallExtensions(Handle<Context> global_context,
1862 v8::ExtensionConfiguration* extensions) {
Steve Block44f0eee2011-05-26 01:26:41 +01001863 // TODO(isolates): Extensions on multiple isolates may take a little more
1864 // effort. (The external API reads 'ignore'-- does that mean
1865 // we can break the interface?)
1866
Steve Blocka7e24c12009-10-30 11:49:00 +00001867 // Clear coloring of extension list
1868 v8::RegisteredExtension* current = v8::RegisteredExtension::first_extension();
1869 while (current != NULL) {
1870 current->set_state(v8::UNVISITED);
1871 current = current->next();
1872 }
Andrei Popescu31002712010-02-23 13:46:05 +00001873 // Install auto extensions.
Steve Blocka7e24c12009-10-30 11:49:00 +00001874 current = v8::RegisteredExtension::first_extension();
1875 while (current != NULL) {
1876 if (current->extension()->auto_enable())
1877 InstallExtension(current);
1878 current = current->next();
1879 }
1880
1881 if (FLAG_expose_gc) InstallExtension("v8/gc");
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01001882 if (FLAG_expose_externalize_string) InstallExtension("v8/externalize");
Steve Blocka7e24c12009-10-30 11:49:00 +00001883
1884 if (extensions == NULL) return true;
1885 // Install required extensions
1886 int count = v8::ImplementationUtilities::GetNameCount(extensions);
1887 const char** names = v8::ImplementationUtilities::GetNames(extensions);
1888 for (int i = 0; i < count; i++) {
1889 if (!InstallExtension(names[i]))
1890 return false;
1891 }
1892
1893 return true;
1894}
1895
1896
1897// Installs a named extension. This methods is unoptimized and does
1898// not scale well if we want to support a large number of extensions.
1899bool Genesis::InstallExtension(const char* name) {
1900 v8::RegisteredExtension* current = v8::RegisteredExtension::first_extension();
1901 // Loop until we find the relevant extension
1902 while (current != NULL) {
1903 if (strcmp(name, current->extension()->name()) == 0) break;
1904 current = current->next();
1905 }
1906 // Didn't find the extension; fail.
1907 if (current == NULL) {
1908 v8::Utils::ReportApiFailure(
1909 "v8::Context::New()", "Cannot find required extension");
1910 return false;
1911 }
1912 return InstallExtension(current);
1913}
1914
1915
1916bool Genesis::InstallExtension(v8::RegisteredExtension* current) {
1917 HandleScope scope;
1918
1919 if (current->state() == v8::INSTALLED) return true;
1920 // The current node has already been visited so there must be a
1921 // cycle in the dependency graph; fail.
1922 if (current->state() == v8::VISITED) {
1923 v8::Utils::ReportApiFailure(
1924 "v8::Context::New()", "Circular extension dependency");
1925 return false;
1926 }
1927 ASSERT(current->state() == v8::UNVISITED);
1928 current->set_state(v8::VISITED);
1929 v8::Extension* extension = current->extension();
1930 // Install the extension's dependencies
1931 for (int i = 0; i < extension->dependency_count(); i++) {
1932 if (!InstallExtension(extension->dependencies()[i])) return false;
1933 }
Steve Block44f0eee2011-05-26 01:26:41 +01001934 Isolate* isolate = Isolate::Current();
Steve Blocka7e24c12009-10-30 11:49:00 +00001935 Vector<const char> source = CStrVector(extension->source());
Steve Block44f0eee2011-05-26 01:26:41 +01001936 Handle<String> source_code = isolate->factory()->NewStringFromAscii(source);
Steve Blocka7e24c12009-10-30 11:49:00 +00001937 bool result = CompileScriptCached(CStrVector(extension->name()),
1938 source_code,
Steve Block44f0eee2011-05-26 01:26:41 +01001939 isolate->bootstrapper()->extensions_cache(),
Andrei Popescu31002712010-02-23 13:46:05 +00001940 extension,
Steve Block44f0eee2011-05-26 01:26:41 +01001941 Handle<Context>(isolate->context()),
Steve Blocka7e24c12009-10-30 11:49:00 +00001942 false);
Steve Block44f0eee2011-05-26 01:26:41 +01001943 ASSERT(isolate->has_pending_exception() != result);
Steve Blocka7e24c12009-10-30 11:49:00 +00001944 if (!result) {
Steve Block44f0eee2011-05-26 01:26:41 +01001945 isolate->clear_pending_exception();
Steve Blocka7e24c12009-10-30 11:49:00 +00001946 }
1947 current->set_state(v8::INSTALLED);
1948 return result;
1949}
1950
1951
Andrei Popescu402d9372010-02-26 13:31:12 +00001952bool Genesis::InstallJSBuiltins(Handle<JSBuiltinsObject> builtins) {
1953 HandleScope scope;
Ben Murdoch257744e2011-11-30 15:57:28 +00001954 Factory* factory = builtins->GetIsolate()->factory();
Andrei Popescu402d9372010-02-26 13:31:12 +00001955 for (int i = 0; i < Builtins::NumberOfJavaScriptBuiltins(); i++) {
1956 Builtins::JavaScript id = static_cast<Builtins::JavaScript>(i);
Ben Murdoch257744e2011-11-30 15:57:28 +00001957 Handle<String> name = factory->LookupAsciiSymbol(Builtins::GetName(id));
John Reck59135872010-11-02 12:39:01 -07001958 Object* function_object = builtins->GetPropertyNoExceptionThrown(*name);
Andrei Popescu402d9372010-02-26 13:31:12 +00001959 Handle<JSFunction> function
John Reck59135872010-11-02 12:39:01 -07001960 = Handle<JSFunction>(JSFunction::cast(function_object));
Andrei Popescu402d9372010-02-26 13:31:12 +00001961 builtins->set_javascript_builtin(id, *function);
1962 Handle<SharedFunctionInfo> shared
1963 = Handle<SharedFunctionInfo>(function->shared());
1964 if (!EnsureCompiled(shared, CLEAR_EXCEPTION)) return false;
Iain Merrick75681382010-08-19 15:07:18 +01001965 // Set the code object on the function object.
Ben Murdochb0fe1622011-05-05 13:52:32 +01001966 function->ReplaceCode(function->shared()->code());
Steve Block6ded16b2010-05-10 14:33:55 +01001967 builtins->set_javascript_builtin_code(id, shared->code());
Andrei Popescu402d9372010-02-26 13:31:12 +00001968 }
1969 return true;
Andrei Popescu31002712010-02-23 13:46:05 +00001970}
1971
1972
Steve Blocka7e24c12009-10-30 11:49:00 +00001973bool Genesis::ConfigureGlobalObjects(
1974 v8::Handle<v8::ObjectTemplate> global_proxy_template) {
1975 Handle<JSObject> global_proxy(
1976 JSObject::cast(global_context()->global_proxy()));
Andrei Popescu402d9372010-02-26 13:31:12 +00001977 Handle<JSObject> inner_global(JSObject::cast(global_context()->global()));
Steve Blocka7e24c12009-10-30 11:49:00 +00001978
1979 if (!global_proxy_template.IsEmpty()) {
1980 // Configure the global proxy object.
1981 Handle<ObjectTemplateInfo> proxy_data =
1982 v8::Utils::OpenHandle(*global_proxy_template);
1983 if (!ConfigureApiObject(global_proxy, proxy_data)) return false;
1984
1985 // Configure the inner global object.
1986 Handle<FunctionTemplateInfo> proxy_constructor(
1987 FunctionTemplateInfo::cast(proxy_data->constructor()));
1988 if (!proxy_constructor->prototype_template()->IsUndefined()) {
1989 Handle<ObjectTemplateInfo> inner_data(
1990 ObjectTemplateInfo::cast(proxy_constructor->prototype_template()));
Andrei Popescu402d9372010-02-26 13:31:12 +00001991 if (!ConfigureApiObject(inner_global, inner_data)) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00001992 }
1993 }
1994
Andrei Popescu402d9372010-02-26 13:31:12 +00001995 SetObjectPrototype(global_proxy, inner_global);
Steve Blocka7e24c12009-10-30 11:49:00 +00001996 return true;
1997}
1998
1999
2000bool Genesis::ConfigureApiObject(Handle<JSObject> object,
2001 Handle<ObjectTemplateInfo> object_template) {
2002 ASSERT(!object_template.is_null());
2003 ASSERT(object->IsInstanceOf(
2004 FunctionTemplateInfo::cast(object_template->constructor())));
2005
2006 bool pending_exception = false;
2007 Handle<JSObject> obj =
2008 Execution::InstantiateObject(object_template, &pending_exception);
2009 if (pending_exception) {
Ben Murdoch257744e2011-11-30 15:57:28 +00002010 ASSERT(isolate()->has_pending_exception());
2011 isolate()->clear_pending_exception();
Steve Blocka7e24c12009-10-30 11:49:00 +00002012 return false;
2013 }
2014 TransferObject(obj, object);
2015 return true;
2016}
2017
2018
2019void Genesis::TransferNamedProperties(Handle<JSObject> from,
2020 Handle<JSObject> to) {
2021 if (from->HasFastProperties()) {
2022 Handle<DescriptorArray> descs =
2023 Handle<DescriptorArray>(from->map()->instance_descriptors());
2024 for (int i = 0; i < descs->number_of_descriptors(); i++) {
2025 PropertyDetails details = PropertyDetails(descs->GetDetails(i));
2026 switch (details.type()) {
2027 case FIELD: {
2028 HandleScope inner;
2029 Handle<String> key = Handle<String>(descs->GetKey(i));
2030 int index = descs->GetFieldIndex(i);
2031 Handle<Object> value = Handle<Object>(from->FastPropertyAt(index));
Steve Block1e0659c2011-05-24 12:43:12 +01002032 SetLocalPropertyNoThrow(to, key, value, details.attributes());
Steve Blocka7e24c12009-10-30 11:49:00 +00002033 break;
2034 }
2035 case CONSTANT_FUNCTION: {
2036 HandleScope inner;
2037 Handle<String> key = Handle<String>(descs->GetKey(i));
2038 Handle<JSFunction> fun =
2039 Handle<JSFunction>(descs->GetConstantFunction(i));
Steve Block1e0659c2011-05-24 12:43:12 +01002040 SetLocalPropertyNoThrow(to, key, fun, details.attributes());
Steve Blocka7e24c12009-10-30 11:49:00 +00002041 break;
2042 }
2043 case CALLBACKS: {
2044 LookupResult result;
2045 to->LocalLookup(descs->GetKey(i), &result);
2046 // If the property is already there we skip it
Andrei Popescu402d9372010-02-26 13:31:12 +00002047 if (result.IsProperty()) continue;
Steve Blocka7e24c12009-10-30 11:49:00 +00002048 HandleScope inner;
Andrei Popescu31002712010-02-23 13:46:05 +00002049 ASSERT(!to->HasFastProperties());
2050 // Add to dictionary.
Steve Blocka7e24c12009-10-30 11:49:00 +00002051 Handle<String> key = Handle<String>(descs->GetKey(i));
Andrei Popescu31002712010-02-23 13:46:05 +00002052 Handle<Object> callbacks(descs->GetCallbacksObject(i));
2053 PropertyDetails d =
2054 PropertyDetails(details.attributes(), CALLBACKS, details.index());
2055 SetNormalizedProperty(to, key, callbacks, d);
Steve Blocka7e24c12009-10-30 11:49:00 +00002056 break;
2057 }
2058 case MAP_TRANSITION:
Steve Block44f0eee2011-05-26 01:26:41 +01002059 case EXTERNAL_ARRAY_TRANSITION:
Steve Blocka7e24c12009-10-30 11:49:00 +00002060 case CONSTANT_TRANSITION:
2061 case NULL_DESCRIPTOR:
2062 // Ignore non-properties.
2063 break;
2064 case NORMAL:
2065 // Do not occur since the from object has fast properties.
Ben Murdoch257744e2011-11-30 15:57:28 +00002066 case HANDLER:
Steve Blocka7e24c12009-10-30 11:49:00 +00002067 case INTERCEPTOR:
Ben Murdoch257744e2011-11-30 15:57:28 +00002068 // No element in instance descriptors have proxy or interceptor type.
Steve Blocka7e24c12009-10-30 11:49:00 +00002069 UNREACHABLE();
2070 break;
2071 }
2072 }
2073 } else {
2074 Handle<StringDictionary> properties =
2075 Handle<StringDictionary>(from->property_dictionary());
2076 int capacity = properties->Capacity();
2077 for (int i = 0; i < capacity; i++) {
2078 Object* raw_key(properties->KeyAt(i));
2079 if (properties->IsKey(raw_key)) {
2080 ASSERT(raw_key->IsString());
2081 // If the property is already there we skip it.
2082 LookupResult result;
2083 to->LocalLookup(String::cast(raw_key), &result);
Andrei Popescu402d9372010-02-26 13:31:12 +00002084 if (result.IsProperty()) continue;
Steve Blocka7e24c12009-10-30 11:49:00 +00002085 // Set the property.
2086 Handle<String> key = Handle<String>(String::cast(raw_key));
2087 Handle<Object> value = Handle<Object>(properties->ValueAt(i));
2088 if (value->IsJSGlobalPropertyCell()) {
2089 value = Handle<Object>(JSGlobalPropertyCell::cast(*value)->value());
2090 }
2091 PropertyDetails details = properties->DetailsAt(i);
Steve Block1e0659c2011-05-24 12:43:12 +01002092 SetLocalPropertyNoThrow(to, key, value, details.attributes());
Steve Blocka7e24c12009-10-30 11:49:00 +00002093 }
2094 }
2095 }
2096}
2097
2098
2099void Genesis::TransferIndexedProperties(Handle<JSObject> from,
2100 Handle<JSObject> to) {
2101 // Cloning the elements array is sufficient.
2102 Handle<FixedArray> from_elements =
2103 Handle<FixedArray>(FixedArray::cast(from->elements()));
Steve Block44f0eee2011-05-26 01:26:41 +01002104 Handle<FixedArray> to_elements = FACTORY->CopyFixedArray(from_elements);
Steve Blocka7e24c12009-10-30 11:49:00 +00002105 to->set_elements(*to_elements);
2106}
2107
2108
2109void Genesis::TransferObject(Handle<JSObject> from, Handle<JSObject> to) {
2110 HandleScope outer;
Ben Murdoch257744e2011-11-30 15:57:28 +00002111 Factory* factory = from->GetIsolate()->factory();
Steve Blocka7e24c12009-10-30 11:49:00 +00002112
2113 ASSERT(!from->IsJSArray());
2114 ASSERT(!to->IsJSArray());
2115
2116 TransferNamedProperties(from, to);
2117 TransferIndexedProperties(from, to);
2118
2119 // Transfer the prototype (new map is needed).
2120 Handle<Map> old_to_map = Handle<Map>(to->map());
Ben Murdoch257744e2011-11-30 15:57:28 +00002121 Handle<Map> new_to_map = factory->CopyMapDropTransitions(old_to_map);
Steve Blocka7e24c12009-10-30 11:49:00 +00002122 new_to_map->set_prototype(from->map()->prototype());
2123 to->set_map(*new_to_map);
2124}
2125
2126
2127void Genesis::MakeFunctionInstancePrototypeWritable() {
Steve Block44f0eee2011-05-26 01:26:41 +01002128 // The maps with writable prototype are created in CreateEmptyFunction
2129 // and CreateStrictModeFunctionMaps respectively. Initially the maps are
2130 // created with read-only prototype for JS builtins processing.
2131 ASSERT(!function_instance_map_writable_prototype_.is_null());
2132 ASSERT(!strict_mode_function_instance_map_writable_prototype_.is_null());
Steve Blocka7e24c12009-10-30 11:49:00 +00002133
Steve Block44f0eee2011-05-26 01:26:41 +01002134 // Replace function instance maps to make prototype writable.
2135 global_context()->set_function_map(
2136 *function_instance_map_writable_prototype_);
2137 global_context()->set_strict_mode_function_map(
2138 *strict_mode_function_instance_map_writable_prototype_);
Steve Blocka7e24c12009-10-30 11:49:00 +00002139}
2140
2141
Ben Murdoch257744e2011-11-30 15:57:28 +00002142Genesis::Genesis(Isolate* isolate,
2143 Handle<Object> global_object,
Steve Blocka7e24c12009-10-30 11:49:00 +00002144 v8::Handle<v8::ObjectTemplate> global_template,
Ben Murdoch257744e2011-11-30 15:57:28 +00002145 v8::ExtensionConfiguration* extensions) : isolate_(isolate) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002146 result_ = Handle<Context>::null();
Steve Blocka7e24c12009-10-30 11:49:00 +00002147 // If V8 isn't running and cannot be initialized, just return.
2148 if (!V8::IsRunning() && !V8::Initialize(NULL)) return;
2149
2150 // Before creating the roots we must save the context and restore it
2151 // on all function exits.
2152 HandleScope scope;
Steve Block44f0eee2011-05-26 01:26:41 +01002153 SaveContext saved_context(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002154
Andrei Popescu31002712010-02-23 13:46:05 +00002155 Handle<Context> new_context = Snapshot::NewContextFromSnapshot();
2156 if (!new_context.is_null()) {
2157 global_context_ =
Steve Block44f0eee2011-05-26 01:26:41 +01002158 Handle<Context>::cast(isolate->global_handles()->Create(*new_context));
Ben Murdochb0fe1622011-05-05 13:52:32 +01002159 AddToWeakGlobalContextList(*global_context_);
Steve Block44f0eee2011-05-26 01:26:41 +01002160 isolate->set_context(*global_context_);
2161 isolate->counters()->contexts_created_by_snapshot()->Increment();
Andrei Popescu402d9372010-02-26 13:31:12 +00002162 Handle<GlobalObject> inner_global;
Andrei Popescu31002712010-02-23 13:46:05 +00002163 Handle<JSGlobalProxy> global_proxy =
2164 CreateNewGlobals(global_template,
2165 global_object,
Andrei Popescu402d9372010-02-26 13:31:12 +00002166 &inner_global);
2167
Andrei Popescu31002712010-02-23 13:46:05 +00002168 HookUpGlobalProxy(inner_global, global_proxy);
Andrei Popescu402d9372010-02-26 13:31:12 +00002169 HookUpInnerGlobal(inner_global);
2170
Andrei Popescu31002712010-02-23 13:46:05 +00002171 if (!ConfigureGlobalObjects(global_template)) return;
2172 } else {
2173 // We get here if there was no context snapshot.
2174 CreateRoots();
Ben Murdoch257744e2011-11-30 15:57:28 +00002175 Handle<JSFunction> empty_function = CreateEmptyFunction(isolate);
Steve Block44f0eee2011-05-26 01:26:41 +01002176 CreateStrictModeFunctionMaps(empty_function);
Andrei Popescu31002712010-02-23 13:46:05 +00002177 Handle<GlobalObject> inner_global;
2178 Handle<JSGlobalProxy> global_proxy =
2179 CreateNewGlobals(global_template, global_object, &inner_global);
2180 HookUpGlobalProxy(inner_global, global_proxy);
2181 InitializeGlobal(inner_global, empty_function);
Steve Block6ded16b2010-05-10 14:33:55 +01002182 InstallJSFunctionResultCaches();
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002183 InitializeNormalizedMapCaches();
Kristian Monsen25f61362010-05-21 11:50:48 +01002184 if (!InstallNatives()) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00002185
Andrei Popescu31002712010-02-23 13:46:05 +00002186 MakeFunctionInstancePrototypeWritable();
Steve Blocka7e24c12009-10-30 11:49:00 +00002187
Andrei Popescu31002712010-02-23 13:46:05 +00002188 if (!ConfigureGlobalObjects(global_template)) return;
Steve Block44f0eee2011-05-26 01:26:41 +01002189 isolate->counters()->contexts_created_from_scratch()->Increment();
Andrei Popescu31002712010-02-23 13:46:05 +00002190 }
Steve Blocka7e24c12009-10-30 11:49:00 +00002191
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002192 // Initialize experimental globals and install experimental natives.
2193 InitializeExperimentalGlobal();
Ben Murdoch257744e2011-11-30 15:57:28 +00002194 if (!InstallExperimentalNatives()) return;
2195
Steve Blocka7e24c12009-10-30 11:49:00 +00002196 result_ = global_context_;
2197}
2198
2199
2200// Support for thread preemption.
2201
2202// Reserve space for statics needing saving and restoring.
2203int Bootstrapper::ArchiveSpacePerThread() {
Steve Block44f0eee2011-05-26 01:26:41 +01002204 return sizeof(NestingCounterType);
Steve Blocka7e24c12009-10-30 11:49:00 +00002205}
2206
2207
2208// Archive statics that are thread local.
2209char* Bootstrapper::ArchiveState(char* to) {
Steve Block44f0eee2011-05-26 01:26:41 +01002210 *reinterpret_cast<NestingCounterType*>(to) = nesting_;
2211 nesting_ = 0;
2212 return to + sizeof(NestingCounterType);
Steve Blocka7e24c12009-10-30 11:49:00 +00002213}
2214
2215
2216// Restore statics that are thread local.
2217char* Bootstrapper::RestoreState(char* from) {
Steve Block44f0eee2011-05-26 01:26:41 +01002218 nesting_ = *reinterpret_cast<NestingCounterType*>(from);
2219 return from + sizeof(NestingCounterType);
Steve Blocka7e24c12009-10-30 11:49:00 +00002220}
2221
2222
2223// Called when the top-level V8 mutex is destroyed.
2224void Bootstrapper::FreeThreadResources() {
Steve Block44f0eee2011-05-26 01:26:41 +01002225 ASSERT(!IsActive());
Steve Blocka7e24c12009-10-30 11:49:00 +00002226}
2227
2228} } // namespace v8::internal