blob: 9c9bac767bf72bfa2e5b4799523c7d1305ad0adc [file] [log] [blame]
Steve Blocka7e24c12009-10-30 11:49:00 +00001// Copyright 2006-2008 the V8 project authors. All rights reserved.
2// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#include "v8.h"
29
30#include "accessors.h"
31#include "api.h"
32#include "bootstrapper.h"
33#include "compiler.h"
34#include "debug.h"
35#include "execution.h"
36#include "global-handles.h"
37#include "macro-assembler.h"
38#include "natives.h"
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,
50 const char* source)
Steve Blockd0582a62009-12-15 09:54:21 +000051 : data_(source), length_(StrLength(source)) {
Steve Block44f0eee2011-05-26 01:26:41 +010052 if (bootstrapper->delete_these_non_arrays_on_tear_down_ == NULL) {
53 bootstrapper->delete_these_non_arrays_on_tear_down_ = new List<char*>(2);
Steve Blockd0582a62009-12-15 09:54:21 +000054 }
55 // The resources are small objects and we only make a fixed number of
56 // them, but let's clean them up on exit for neatness.
Steve Block44f0eee2011-05-26 01:26:41 +010057 bootstrapper->delete_these_non_arrays_on_tear_down_->
Steve Blockd0582a62009-12-15 09:54:21 +000058 Add(reinterpret_cast<char*>(this));
59}
Steve Blocka7e24c12009-10-30 11:49:00 +000060
61
Steve Block44f0eee2011-05-26 01:26:41 +010062Bootstrapper::Bootstrapper()
63 : nesting_(0),
64 extensions_cache_(Script::TYPE_EXTENSION),
65 delete_these_non_arrays_on_tear_down_(NULL),
66 delete_these_arrays_on_tear_down_(NULL) {
67}
68
69
Steve Blocka7e24c12009-10-30 11:49:00 +000070Handle<String> Bootstrapper::NativesSourceLookup(int index) {
71 ASSERT(0 <= index && index < Natives::GetBuiltinsCount());
Steve Block44f0eee2011-05-26 01:26:41 +010072 Isolate* isolate = Isolate::Current();
73 Factory* factory = isolate->factory();
74 Heap* heap = isolate->heap();
75 if (heap->natives_source_cache()->get(index)->IsUndefined()) {
Steve Blockd0582a62009-12-15 09:54:21 +000076 if (!Snapshot::IsEnabled() || FLAG_new_snapshot) {
77 // We can use external strings for the natives.
78 NativesExternalStringResource* resource =
Steve Block44f0eee2011-05-26 01:26:41 +010079 new NativesExternalStringResource(this,
Steve Blockd0582a62009-12-15 09:54:21 +000080 Natives::GetScriptSource(index).start());
81 Handle<String> source_code =
Steve Block44f0eee2011-05-26 01:26:41 +010082 factory->NewExternalStringFromAscii(resource);
83 heap->natives_source_cache()->set(index, *source_code);
Steve Blockd0582a62009-12-15 09:54:21 +000084 } else {
85 // Old snapshot code can't cope with external strings at all.
86 Handle<String> source_code =
Steve Block44f0eee2011-05-26 01:26:41 +010087 factory->NewStringFromAscii(Natives::GetScriptSource(index));
88 heap->natives_source_cache()->set(index, *source_code);
Steve Blockd0582a62009-12-15 09:54:21 +000089 }
Steve Blocka7e24c12009-10-30 11:49:00 +000090 }
Steve Block44f0eee2011-05-26 01:26:41 +010091 Handle<Object> cached_source(heap->natives_source_cache()->get(index));
Steve Blocka7e24c12009-10-30 11:49:00 +000092 return Handle<String>::cast(cached_source);
93}
94
95
Steve Blocka7e24c12009-10-30 11:49:00 +000096void Bootstrapper::Initialize(bool create_heap_objects) {
Steve Block44f0eee2011-05-26 01:26:41 +010097 extensions_cache_.Initialize(create_heap_objects);
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -080098 GCExtension::Register();
99 ExternalizeStringExtension::Register();
Steve Blocka7e24c12009-10-30 11:49:00 +0000100}
101
102
Leon Clarkee46be812010-01-19 14:06:41 +0000103char* Bootstrapper::AllocateAutoDeletedArray(int bytes) {
104 char* memory = new char[bytes];
105 if (memory != NULL) {
Steve Block44f0eee2011-05-26 01:26:41 +0100106 if (delete_these_arrays_on_tear_down_ == NULL) {
107 delete_these_arrays_on_tear_down_ = new List<char*>(2);
Leon Clarkee46be812010-01-19 14:06:41 +0000108 }
Steve Block44f0eee2011-05-26 01:26:41 +0100109 delete_these_arrays_on_tear_down_->Add(memory);
Leon Clarkee46be812010-01-19 14:06:41 +0000110 }
111 return memory;
112}
113
114
Steve Blocka7e24c12009-10-30 11:49:00 +0000115void Bootstrapper::TearDown() {
Steve Block44f0eee2011-05-26 01:26:41 +0100116 if (delete_these_non_arrays_on_tear_down_ != NULL) {
117 int len = delete_these_non_arrays_on_tear_down_->length();
Steve Blockd0582a62009-12-15 09:54:21 +0000118 ASSERT(len < 20); // Don't use this mechanism for unbounded allocations.
119 for (int i = 0; i < len; i++) {
Steve Block44f0eee2011-05-26 01:26:41 +0100120 delete delete_these_non_arrays_on_tear_down_->at(i);
121 delete_these_non_arrays_on_tear_down_->at(i) = NULL;
Steve Blockd0582a62009-12-15 09:54:21 +0000122 }
Steve Block44f0eee2011-05-26 01:26:41 +0100123 delete delete_these_non_arrays_on_tear_down_;
124 delete_these_non_arrays_on_tear_down_ = NULL;
Steve Blockd0582a62009-12-15 09:54:21 +0000125 }
126
Steve Block44f0eee2011-05-26 01:26:41 +0100127 if (delete_these_arrays_on_tear_down_ != NULL) {
128 int len = delete_these_arrays_on_tear_down_->length();
Leon Clarkee46be812010-01-19 14:06:41 +0000129 ASSERT(len < 1000); // Don't use this mechanism for unbounded allocations.
130 for (int i = 0; i < len; i++) {
Steve Block44f0eee2011-05-26 01:26:41 +0100131 delete[] delete_these_arrays_on_tear_down_->at(i);
132 delete_these_arrays_on_tear_down_->at(i) = NULL;
Leon Clarkee46be812010-01-19 14:06:41 +0000133 }
Steve Block44f0eee2011-05-26 01:26:41 +0100134 delete delete_these_arrays_on_tear_down_;
135 delete_these_arrays_on_tear_down_ = NULL;
Leon Clarkee46be812010-01-19 14:06:41 +0000136 }
137
Steve Block44f0eee2011-05-26 01:26:41 +0100138 extensions_cache_.Initialize(false); // Yes, symmetrical
Steve Blocka7e24c12009-10-30 11:49:00 +0000139}
140
141
Steve Blocka7e24c12009-10-30 11:49:00 +0000142class Genesis BASE_EMBEDDED {
143 public:
144 Genesis(Handle<Object> global_object,
145 v8::Handle<v8::ObjectTemplate> global_template,
146 v8::ExtensionConfiguration* extensions);
Andrei Popescu31002712010-02-23 13:46:05 +0000147 ~Genesis() { }
Steve Blocka7e24c12009-10-30 11:49:00 +0000148
149 Handle<Context> result() { return result_; }
150
151 Genesis* previous() { return previous_; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000152
153 private:
154 Handle<Context> global_context_;
155
156 // There may be more than one active genesis object: When GC is
157 // triggered during environment creation there may be weak handle
158 // processing callbacks which may create new environments.
159 Genesis* previous_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000160
161 Handle<Context> global_context() { return global_context_; }
162
Andrei Popescu31002712010-02-23 13:46:05 +0000163 // Creates some basic objects. Used for creating a context from scratch.
164 void CreateRoots();
165 // Creates the empty function. Used for creating a context from scratch.
166 Handle<JSFunction> CreateEmptyFunction();
Steve Block44f0eee2011-05-26 01:26:41 +0100167 // Creates the ThrowTypeError function. ECMA 5th Ed. 13.2.3
168 Handle<JSFunction> CreateThrowTypeErrorFunction(Builtins::Name builtin);
169
170 void CreateStrictModeFunctionMaps(Handle<JSFunction> empty);
Andrei Popescu31002712010-02-23 13:46:05 +0000171 // Creates the global objects using the global and the template passed in
172 // through the API. We call this regardless of whether we are building a
173 // context from scratch or using a deserialized one from the partial snapshot
174 // but in the latter case we don't use the objects it produces directly, as
175 // we have to used the deserialized ones that are linked together with the
176 // rest of the context snapshot.
177 Handle<JSGlobalProxy> CreateNewGlobals(
178 v8::Handle<v8::ObjectTemplate> global_template,
179 Handle<Object> global_object,
180 Handle<GlobalObject>* global_proxy_out);
181 // Hooks the given global proxy into the context. If the context was created
182 // by deserialization then this will unhook the global proxy that was
183 // deserialized, leaving the GC to pick it up.
184 void HookUpGlobalProxy(Handle<GlobalObject> inner_global,
185 Handle<JSGlobalProxy> global_proxy);
Andrei Popescu402d9372010-02-26 13:31:12 +0000186 // Similarly, we want to use the inner global that has been created by the
187 // templates passed through the API. The inner global from the snapshot is
188 // detached from the other objects in the snapshot.
189 void HookUpInnerGlobal(Handle<GlobalObject> inner_global);
Andrei Popescu31002712010-02-23 13:46:05 +0000190 // New context initialization. Used for creating a context from scratch.
191 void InitializeGlobal(Handle<GlobalObject> inner_global,
192 Handle<JSFunction> empty_function);
193 // Installs the contents of the native .js files on the global objects.
194 // Used for creating a context from scratch.
Steve Blocka7e24c12009-10-30 11:49:00 +0000195 void InstallNativeFunctions();
196 bool InstallNatives();
Ben Murdochb0fe1622011-05-05 13:52:32 +0100197 void InstallBuiltinFunctionIds();
Steve Block6ded16b2010-05-10 14:33:55 +0100198 void InstallJSFunctionResultCaches();
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100199 void InitializeNormalizedMapCaches();
Andrei Popescu31002712010-02-23 13:46:05 +0000200 // Used both for deserialized and from-scratch contexts to add the extensions
201 // provided.
202 static bool InstallExtensions(Handle<Context> global_context,
203 v8::ExtensionConfiguration* extensions);
204 static bool InstallExtension(const char* name);
205 static bool InstallExtension(v8::RegisteredExtension* current);
206 static void InstallSpecialObjects(Handle<Context> global_context);
Andrei Popescu402d9372010-02-26 13:31:12 +0000207 bool InstallJSBuiltins(Handle<JSBuiltinsObject> builtins);
Steve Blocka7e24c12009-10-30 11:49:00 +0000208 bool ConfigureApiObject(Handle<JSObject> object,
209 Handle<ObjectTemplateInfo> object_template);
210 bool ConfigureGlobalObjects(v8::Handle<v8::ObjectTemplate> global_template);
211
212 // Migrates all properties from the 'from' object to the 'to'
213 // object and overrides the prototype in 'to' with the one from
214 // 'from'.
215 void TransferObject(Handle<JSObject> from, Handle<JSObject> to);
216 void TransferNamedProperties(Handle<JSObject> from, Handle<JSObject> to);
217 void TransferIndexedProperties(Handle<JSObject> from, Handle<JSObject> to);
218
Steve Block6ded16b2010-05-10 14:33:55 +0100219 enum PrototypePropertyMode {
220 DONT_ADD_PROTOTYPE,
221 ADD_READONLY_PROTOTYPE,
222 ADD_WRITEABLE_PROTOTYPE
223 };
Steve Block44f0eee2011-05-26 01:26:41 +0100224
225 Handle<Map> CreateFunctionMap(PrototypePropertyMode prototype_mode);
226
Steve Blocka7e24c12009-10-30 11:49:00 +0000227 Handle<DescriptorArray> ComputeFunctionInstanceDescriptor(
Steve Block6ded16b2010-05-10 14:33:55 +0100228 PrototypePropertyMode prototypeMode);
Steve Blocka7e24c12009-10-30 11:49:00 +0000229 void MakeFunctionInstancePrototypeWritable();
230
Steve Block44f0eee2011-05-26 01:26:41 +0100231 Handle<Map> CreateStrictModeFunctionMap(
232 PrototypePropertyMode prototype_mode,
233 Handle<JSFunction> empty_function,
234 Handle<FixedArray> arguments_callbacks,
235 Handle<FixedArray> caller_callbacks);
236
237 Handle<DescriptorArray> ComputeStrictFunctionInstanceDescriptor(
238 PrototypePropertyMode propertyMode,
239 Handle<FixedArray> arguments,
240 Handle<FixedArray> caller);
241
Steve Blocka7e24c12009-10-30 11:49:00 +0000242 static bool CompileBuiltin(int index);
243 static bool CompileNative(Vector<const char> name, Handle<String> source);
244 static bool CompileScriptCached(Vector<const char> name,
245 Handle<String> source,
246 SourceCodeCache* cache,
247 v8::Extension* extension,
Andrei Popescu31002712010-02-23 13:46:05 +0000248 Handle<Context> top_context,
Steve Blocka7e24c12009-10-30 11:49:00 +0000249 bool use_runtime_context);
250
251 Handle<Context> result_;
Steve Block44f0eee2011-05-26 01:26:41 +0100252
253 // Function instance maps. Function literal maps are created initially with
254 // a read only prototype for the processing of JS builtins. Later the function
255 // instance maps are replaced in order to make prototype writable.
256 // These are the final, writable prototype, maps.
257 Handle<Map> function_instance_map_writable_prototype_;
258 Handle<Map> strict_mode_function_instance_map_writable_prototype_;
259
Andrei Popescu31002712010-02-23 13:46:05 +0000260 BootstrapperActive active_;
261 friend class Bootstrapper;
Steve Blocka7e24c12009-10-30 11:49:00 +0000262};
263
Steve Blocka7e24c12009-10-30 11:49:00 +0000264
265void Bootstrapper::Iterate(ObjectVisitor* v) {
Steve Block44f0eee2011-05-26 01:26:41 +0100266 extensions_cache_.Iterate(v);
Steve Blockd0582a62009-12-15 09:54:21 +0000267 v->Synchronize("Extensions");
Steve Blocka7e24c12009-10-30 11:49:00 +0000268}
269
270
Steve Blocka7e24c12009-10-30 11:49:00 +0000271Handle<Context> Bootstrapper::CreateEnvironment(
272 Handle<Object> global_object,
273 v8::Handle<v8::ObjectTemplate> global_template,
274 v8::ExtensionConfiguration* extensions) {
Andrei Popescu31002712010-02-23 13:46:05 +0000275 HandleScope scope;
276 Handle<Context> env;
Steve Blocka7e24c12009-10-30 11:49:00 +0000277 Genesis genesis(global_object, global_template, extensions);
Andrei Popescu31002712010-02-23 13:46:05 +0000278 env = genesis.result();
279 if (!env.is_null()) {
280 if (InstallExtensions(env, extensions)) {
281 return env;
282 }
283 }
284 return Handle<Context>();
Steve Blocka7e24c12009-10-30 11:49:00 +0000285}
286
287
288static void SetObjectPrototype(Handle<JSObject> object, Handle<Object> proto) {
289 // object.__proto__ = proto;
290 Handle<Map> old_to_map = Handle<Map>(object->map());
Steve Block44f0eee2011-05-26 01:26:41 +0100291 Handle<Map> new_to_map = FACTORY->CopyMapDropTransitions(old_to_map);
Steve Blocka7e24c12009-10-30 11:49:00 +0000292 new_to_map->set_prototype(*proto);
293 object->set_map(*new_to_map);
294}
295
296
297void Bootstrapper::DetachGlobal(Handle<Context> env) {
Steve Block44f0eee2011-05-26 01:26:41 +0100298 Factory* factory = Isolate::Current()->factory();
299 JSGlobalProxy::cast(env->global_proxy())->set_context(*factory->null_value());
Steve Blocka7e24c12009-10-30 11:49:00 +0000300 SetObjectPrototype(Handle<JSObject>(env->global_proxy()),
Steve Block44f0eee2011-05-26 01:26:41 +0100301 factory->null_value());
Steve Blocka7e24c12009-10-30 11:49:00 +0000302 env->set_global_proxy(env->global());
303 env->global()->set_global_receiver(env->global());
304}
305
306
Andrei Popescu74b3c142010-03-29 12:03:09 +0100307void Bootstrapper::ReattachGlobal(Handle<Context> env,
308 Handle<Object> global_object) {
309 ASSERT(global_object->IsJSGlobalProxy());
310 Handle<JSGlobalProxy> global = Handle<JSGlobalProxy>::cast(global_object);
311 env->global()->set_global_receiver(*global);
312 env->set_global_proxy(*global);
313 SetObjectPrototype(global, Handle<JSObject>(env->global()));
314 global->set_context(*env);
315}
316
317
Steve Blocka7e24c12009-10-30 11:49:00 +0000318static Handle<JSFunction> InstallFunction(Handle<JSObject> target,
319 const char* name,
320 InstanceType type,
321 int instance_size,
322 Handle<JSObject> prototype,
323 Builtins::Name call,
324 bool is_ecma_native) {
Steve Block44f0eee2011-05-26 01:26:41 +0100325 Isolate* isolate = Isolate::Current();
326 Factory* factory = isolate->factory();
327 Handle<String> symbol = factory->LookupAsciiSymbol(name);
328 Handle<Code> call_code = Handle<Code>(isolate->builtins()->builtin(call));
Steve Block6ded16b2010-05-10 14:33:55 +0100329 Handle<JSFunction> function = prototype.is_null() ?
Steve Block44f0eee2011-05-26 01:26:41 +0100330 factory->NewFunctionWithoutPrototype(symbol, call_code) :
331 factory->NewFunctionWithPrototype(symbol,
Steve Blocka7e24c12009-10-30 11:49:00 +0000332 type,
333 instance_size,
334 prototype,
335 call_code,
336 is_ecma_native);
Steve Block1e0659c2011-05-24 12:43:12 +0100337 SetLocalPropertyNoThrow(target, symbol, function, DONT_ENUM);
Steve Blocka7e24c12009-10-30 11:49:00 +0000338 if (is_ecma_native) {
339 function->shared()->set_instance_class_name(*symbol);
340 }
341 return function;
342}
343
344
345Handle<DescriptorArray> Genesis::ComputeFunctionInstanceDescriptor(
Steve Block6ded16b2010-05-10 14:33:55 +0100346 PrototypePropertyMode prototypeMode) {
Steve Block44f0eee2011-05-26 01:26:41 +0100347 Factory* factory = Isolate::Current()->factory();
348 Handle<DescriptorArray> descriptors =
349 factory->NewDescriptorArray(prototypeMode == DONT_ADD_PROTOTYPE ? 4 : 5);
Steve Block6ded16b2010-05-10 14:33:55 +0100350 PropertyAttributes attributes =
Steve Blocka7e24c12009-10-30 11:49:00 +0000351 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
Steve Blocka7e24c12009-10-30 11:49:00 +0000352
Steve Block44f0eee2011-05-26 01:26:41 +0100353 { // Add length.
354 Handle<Proxy> proxy = factory->NewProxy(&Accessors::FunctionLength);
355 CallbacksDescriptor d(*factory->length_symbol(), *proxy, attributes);
356 descriptors->Set(0, &d);
357 }
358 { // Add name.
359 Handle<Proxy> proxy = factory->NewProxy(&Accessors::FunctionName);
360 CallbacksDescriptor d(*factory->name_symbol(), *proxy, attributes);
361 descriptors->Set(1, &d);
362 }
363 { // Add arguments.
364 Handle<Proxy> proxy = factory->NewProxy(&Accessors::FunctionArguments);
365 CallbacksDescriptor d(*factory->arguments_symbol(), *proxy, attributes);
366 descriptors->Set(2, &d);
367 }
368 { // Add caller.
369 Handle<Proxy> proxy = factory->NewProxy(&Accessors::FunctionCaller);
370 CallbacksDescriptor d(*factory->caller_symbol(), *proxy, attributes);
371 descriptors->Set(3, &d);
372 }
373 if (prototypeMode != DONT_ADD_PROTOTYPE) {
374 // Add prototype.
375 if (prototypeMode == ADD_WRITEABLE_PROTOTYPE) {
376 attributes = static_cast<PropertyAttributes>(attributes & ~READ_ONLY);
377 }
378 Handle<Proxy> proxy = factory->NewProxy(&Accessors::FunctionPrototype);
379 CallbacksDescriptor d(*factory->prototype_symbol(), *proxy, attributes);
380 descriptors->Set(4, &d);
381 }
382 descriptors->Sort();
383 return descriptors;
384}
Steve Blocka7e24c12009-10-30 11:49:00 +0000385
Steve Blocka7e24c12009-10-30 11:49:00 +0000386
Steve Block44f0eee2011-05-26 01:26:41 +0100387Handle<Map> Genesis::CreateFunctionMap(PrototypePropertyMode prototype_mode) {
388 Handle<Map> map = FACTORY->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
389 Handle<DescriptorArray> descriptors =
390 ComputeFunctionInstanceDescriptor(prototype_mode);
391 map->set_instance_descriptors(*descriptors);
392 map->set_function_with_prototype(prototype_mode != DONT_ADD_PROTOTYPE);
393 return map;
Steve Blocka7e24c12009-10-30 11:49:00 +0000394}
395
396
Andrei Popescu31002712010-02-23 13:46:05 +0000397Handle<JSFunction> Genesis::CreateEmptyFunction() {
Steve Block44f0eee2011-05-26 01:26:41 +0100398 // Allocate the map for function instances. Maps are allocated first and their
399 // prototypes patched later, once empty function is created.
400
Steve Blocka7e24c12009-10-30 11:49:00 +0000401 // Please note that the prototype property for function instances must be
402 // writable.
Steve Block44f0eee2011-05-26 01:26:41 +0100403 global_context()->set_function_instance_map(
404 *CreateFunctionMap(ADD_WRITEABLE_PROTOTYPE));
Steve Block6ded16b2010-05-10 14:33:55 +0100405
406 // Functions with this map will not have a 'prototype' property, and
407 // can not be used as constructors.
Steve Block6ded16b2010-05-10 14:33:55 +0100408 global_context()->set_function_without_prototype_map(
Steve Block44f0eee2011-05-26 01:26:41 +0100409 *CreateFunctionMap(DONT_ADD_PROTOTYPE));
Steve Blocka7e24c12009-10-30 11:49:00 +0000410
Steve Block44f0eee2011-05-26 01:26:41 +0100411 // Allocate the function map. This map is temporary, used only for processing
412 // of builtins.
413 // Later the map is replaced with writable prototype map, allocated below.
414 global_context()->set_function_map(
415 *CreateFunctionMap(ADD_READONLY_PROTOTYPE));
Steve Blocka7e24c12009-10-30 11:49:00 +0000416
Steve Block44f0eee2011-05-26 01:26:41 +0100417 // The final map for functions. Writeable prototype.
418 // This map is installed in MakeFunctionInstancePrototypeWritable.
419 function_instance_map_writable_prototype_ =
420 CreateFunctionMap(ADD_WRITEABLE_PROTOTYPE);
421
422 Isolate* isolate = Isolate::Current();
423 Factory* factory = isolate->factory();
424 Heap* heap = isolate->heap();
425
426 Handle<String> object_name = Handle<String>(heap->Object_symbol());
Steve Blocka7e24c12009-10-30 11:49:00 +0000427
428 { // --- O b j e c t ---
429 Handle<JSFunction> object_fun =
Steve Block44f0eee2011-05-26 01:26:41 +0100430 factory->NewFunction(object_name, factory->null_value());
Steve Blocka7e24c12009-10-30 11:49:00 +0000431 Handle<Map> object_function_map =
Steve Block44f0eee2011-05-26 01:26:41 +0100432 factory->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
Steve Blocka7e24c12009-10-30 11:49:00 +0000433 object_fun->set_initial_map(*object_function_map);
434 object_function_map->set_constructor(*object_fun);
435
436 global_context()->set_object_function(*object_fun);
437
438 // Allocate a new prototype for the object function.
Steve Block44f0eee2011-05-26 01:26:41 +0100439 Handle<JSObject> prototype = factory->NewJSObject(
440 isolate->object_function(),
441 TENURED);
Steve Blocka7e24c12009-10-30 11:49:00 +0000442
443 global_context()->set_initial_object_prototype(*prototype);
444 SetPrototype(object_fun, prototype);
445 object_function_map->
Steve Block44f0eee2011-05-26 01:26:41 +0100446 set_instance_descriptors(heap->empty_descriptor_array());
Steve Blocka7e24c12009-10-30 11:49:00 +0000447 }
448
449 // Allocate the empty function as the prototype for function ECMAScript
450 // 262 15.3.4.
Steve Block44f0eee2011-05-26 01:26:41 +0100451 Handle<String> symbol = factory->LookupAsciiSymbol("Empty");
Steve Blocka7e24c12009-10-30 11:49:00 +0000452 Handle<JSFunction> empty_function =
Steve Block44f0eee2011-05-26 01:26:41 +0100453 factory->NewFunctionWithoutPrototype(symbol, kNonStrictMode);
Steve Blocka7e24c12009-10-30 11:49:00 +0000454
Andrei Popescu31002712010-02-23 13:46:05 +0000455 // --- E m p t y ---
456 Handle<Code> code =
Steve Block44f0eee2011-05-26 01:26:41 +0100457 Handle<Code>(isolate->builtins()->builtin(
458 Builtins::kEmptyFunction));
Andrei Popescu31002712010-02-23 13:46:05 +0000459 empty_function->set_code(*code);
Iain Merrick75681382010-08-19 15:07:18 +0100460 empty_function->shared()->set_code(*code);
Steve Block44f0eee2011-05-26 01:26:41 +0100461 Handle<String> source = factory->NewStringFromAscii(CStrVector("() {}"));
462 Handle<Script> script = factory->NewScript(source);
Andrei Popescu31002712010-02-23 13:46:05 +0000463 script->set_type(Smi::FromInt(Script::TYPE_NATIVE));
464 empty_function->shared()->set_script(*script);
465 empty_function->shared()->set_start_position(0);
466 empty_function->shared()->set_end_position(source->length());
467 empty_function->shared()->DontAdaptArguments();
Steve Block44f0eee2011-05-26 01:26:41 +0100468
469 // Set prototypes for the function maps.
Andrei Popescu31002712010-02-23 13:46:05 +0000470 global_context()->function_map()->set_prototype(*empty_function);
471 global_context()->function_instance_map()->set_prototype(*empty_function);
Steve Block6ded16b2010-05-10 14:33:55 +0100472 global_context()->function_without_prototype_map()->
473 set_prototype(*empty_function);
Steve Block44f0eee2011-05-26 01:26:41 +0100474 function_instance_map_writable_prototype_->set_prototype(*empty_function);
Steve Blocka7e24c12009-10-30 11:49:00 +0000475
Andrei Popescu31002712010-02-23 13:46:05 +0000476 // Allocate the function map first and then patch the prototype later
Steve Block44f0eee2011-05-26 01:26:41 +0100477 Handle<Map> function_without_prototype_map(
478 global_context()->function_without_prototype_map());
479 Handle<Map> empty_fm = factory->CopyMapDropDescriptors(
Steve Block6ded16b2010-05-10 14:33:55 +0100480 function_without_prototype_map);
481 empty_fm->set_instance_descriptors(
Steve Block44f0eee2011-05-26 01:26:41 +0100482 function_without_prototype_map->instance_descriptors());
Andrei Popescu31002712010-02-23 13:46:05 +0000483 empty_fm->set_prototype(global_context()->object_function()->prototype());
484 empty_function->set_map(*empty_fm);
485 return empty_function;
486}
487
488
Steve Block44f0eee2011-05-26 01:26:41 +0100489Handle<DescriptorArray> Genesis::ComputeStrictFunctionInstanceDescriptor(
490 PrototypePropertyMode prototypeMode,
491 Handle<FixedArray> arguments,
492 Handle<FixedArray> caller) {
493 Factory* factory = Isolate::Current()->factory();
494 Handle<DescriptorArray> descriptors =
495 factory->NewDescriptorArray(prototypeMode == DONT_ADD_PROTOTYPE ? 4 : 5);
496 PropertyAttributes attributes = static_cast<PropertyAttributes>(
497 DONT_ENUM | DONT_DELETE | READ_ONLY);
498
499 { // length
500 Handle<Proxy> proxy = factory->NewProxy(&Accessors::FunctionLength);
501 CallbacksDescriptor d(*factory->length_symbol(), *proxy, attributes);
502 descriptors->Set(0, &d);
503 }
504 { // name
505 Handle<Proxy> proxy = factory->NewProxy(&Accessors::FunctionName);
506 CallbacksDescriptor d(*factory->name_symbol(), *proxy, attributes);
507 descriptors->Set(1, &d);
508 }
509 { // arguments
510 CallbacksDescriptor d(*factory->arguments_symbol(), *arguments, attributes);
511 descriptors->Set(2, &d);
512 }
513 { // caller
514 CallbacksDescriptor d(*factory->caller_symbol(), *caller, attributes);
515 descriptors->Set(3, &d);
516 }
517
518 // prototype
519 if (prototypeMode != DONT_ADD_PROTOTYPE) {
520 if (prototypeMode == ADD_WRITEABLE_PROTOTYPE) {
521 attributes = static_cast<PropertyAttributes>(attributes & ~READ_ONLY);
522 }
523 Handle<Proxy> proxy = factory->NewProxy(&Accessors::FunctionPrototype);
524 CallbacksDescriptor d(*factory->prototype_symbol(), *proxy, attributes);
525 descriptors->Set(4, &d);
526 }
527
528 descriptors->Sort();
529 return descriptors;
530}
531
532
533// ECMAScript 5th Edition, 13.2.3
534Handle<JSFunction> Genesis::CreateThrowTypeErrorFunction(
535 Builtins::Name builtin) {
536 Isolate* isolate = Isolate::Current();
537 Factory* factory = isolate->factory();
538
539 Handle<String> name = factory->LookupAsciiSymbol("ThrowTypeError");
540 Handle<JSFunction> throw_type_error =
541 factory->NewFunctionWithoutPrototype(name, kStrictMode);
542 Handle<Code> code = Handle<Code>(
543 isolate->builtins()->builtin(builtin));
544
545 throw_type_error->set_map(global_context()->strict_mode_function_map());
546 throw_type_error->set_code(*code);
547 throw_type_error->shared()->set_code(*code);
548 throw_type_error->shared()->DontAdaptArguments();
549
550 PreventExtensions(throw_type_error);
551
552 return throw_type_error;
553}
554
555
556Handle<Map> Genesis::CreateStrictModeFunctionMap(
557 PrototypePropertyMode prototype_mode,
558 Handle<JSFunction> empty_function,
559 Handle<FixedArray> arguments_callbacks,
560 Handle<FixedArray> caller_callbacks) {
561 Handle<Map> map = FACTORY->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
562 Handle<DescriptorArray> descriptors =
563 ComputeStrictFunctionInstanceDescriptor(prototype_mode,
564 arguments_callbacks,
565 caller_callbacks);
566 map->set_instance_descriptors(*descriptors);
567 map->set_function_with_prototype(prototype_mode != DONT_ADD_PROTOTYPE);
568 map->set_prototype(*empty_function);
569 return map;
570}
571
572
573void Genesis::CreateStrictModeFunctionMaps(Handle<JSFunction> empty) {
574 // Create the callbacks arrays for ThrowTypeError functions.
575 // The get/set callacks are filled in after the maps are created below.
576 Factory* factory = Isolate::Current()->factory();
577 Handle<FixedArray> arguments = factory->NewFixedArray(2, TENURED);
578 Handle<FixedArray> caller = factory->NewFixedArray(2, TENURED);
579
580 // Allocate map for the strict mode function instances.
581 global_context()->set_strict_mode_function_instance_map(
582 *CreateStrictModeFunctionMap(
583 ADD_WRITEABLE_PROTOTYPE, empty, arguments, caller));
584
585 // Allocate map for the prototype-less strict mode instances.
586 global_context()->set_strict_mode_function_without_prototype_map(
587 *CreateStrictModeFunctionMap(
588 DONT_ADD_PROTOTYPE, empty, arguments, caller));
589
590 // Allocate map for the strict mode functions. This map is temporary, used
591 // only for processing of builtins.
592 // Later the map is replaced with writable prototype map, allocated below.
593 global_context()->set_strict_mode_function_map(
594 *CreateStrictModeFunctionMap(
595 ADD_READONLY_PROTOTYPE, empty, arguments, caller));
596
597 // The final map for the strict mode functions. Writeable prototype.
598 // This map is installed in MakeFunctionInstancePrototypeWritable.
599 strict_mode_function_instance_map_writable_prototype_ =
600 CreateStrictModeFunctionMap(
601 ADD_WRITEABLE_PROTOTYPE, empty, arguments, caller);
602
603 // Create the ThrowTypeError function instances.
604 Handle<JSFunction> arguments_throw =
605 CreateThrowTypeErrorFunction(Builtins::kStrictFunctionArguments);
606 Handle<JSFunction> caller_throw =
607 CreateThrowTypeErrorFunction(Builtins::kStrictFunctionCaller);
608
609 // Complete the callback fixed arrays.
610 arguments->set(0, *arguments_throw);
611 arguments->set(1, *arguments_throw);
612 caller->set(0, *caller_throw);
613 caller->set(1, *caller_throw);
614}
615
616
Ben Murdochb0fe1622011-05-05 13:52:32 +0100617static void AddToWeakGlobalContextList(Context* context) {
618 ASSERT(context->IsGlobalContext());
Steve Block44f0eee2011-05-26 01:26:41 +0100619 Heap* heap = Isolate::Current()->heap();
Ben Murdochb0fe1622011-05-05 13:52:32 +0100620#ifdef DEBUG
621 { // NOLINT
622 ASSERT(context->get(Context::NEXT_CONTEXT_LINK)->IsUndefined());
623 // Check that context is not in the list yet.
Steve Block44f0eee2011-05-26 01:26:41 +0100624 for (Object* current = heap->global_contexts_list();
Ben Murdochb0fe1622011-05-05 13:52:32 +0100625 !current->IsUndefined();
626 current = Context::cast(current)->get(Context::NEXT_CONTEXT_LINK)) {
627 ASSERT(current != context);
628 }
629 }
630#endif
Steve Block44f0eee2011-05-26 01:26:41 +0100631 context->set(Context::NEXT_CONTEXT_LINK, heap->global_contexts_list());
632 heap->set_global_contexts_list(context);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100633}
634
635
Andrei Popescu31002712010-02-23 13:46:05 +0000636void Genesis::CreateRoots() {
Steve Block44f0eee2011-05-26 01:26:41 +0100637 Isolate* isolate = Isolate::Current();
Andrei Popescu31002712010-02-23 13:46:05 +0000638 // Allocate the global context FixedArray first and then patch the
639 // closure and extension object later (we need the empty function
640 // and the global object, but in order to create those, we need the
641 // global context).
Steve Block44f0eee2011-05-26 01:26:41 +0100642 global_context_ = Handle<Context>::cast(isolate->global_handles()->Create(
643 *isolate->factory()->NewGlobalContext()));
Ben Murdochb0fe1622011-05-05 13:52:32 +0100644 AddToWeakGlobalContextList(*global_context_);
Steve Block44f0eee2011-05-26 01:26:41 +0100645 isolate->set_context(*global_context());
Andrei Popescu31002712010-02-23 13:46:05 +0000646
647 // Allocate the message listeners object.
648 {
649 v8::NeanderArray listeners;
650 global_context()->set_message_listeners(*listeners.value());
651 }
652}
653
654
655Handle<JSGlobalProxy> Genesis::CreateNewGlobals(
656 v8::Handle<v8::ObjectTemplate> global_template,
657 Handle<Object> global_object,
658 Handle<GlobalObject>* inner_global_out) {
659 // The argument global_template aka data is an ObjectTemplateInfo.
660 // It has a constructor pointer that points at global_constructor which is a
661 // FunctionTemplateInfo.
662 // The global_constructor is used to create or reinitialize the global_proxy.
663 // The global_constructor also has a prototype_template pointer that points at
664 // js_global_template which is an ObjectTemplateInfo.
665 // That in turn has a constructor pointer that points at
666 // js_global_constructor which is a FunctionTemplateInfo.
667 // js_global_constructor is used to make js_global_function
668 // js_global_function is used to make the new inner_global.
669 //
670 // --- G l o b a l ---
671 // Step 1: Create a fresh inner JSGlobalObject.
672 Handle<JSFunction> js_global_function;
673 Handle<ObjectTemplateInfo> js_global_template;
674 if (!global_template.IsEmpty()) {
675 // Get prototype template of the global_template.
676 Handle<ObjectTemplateInfo> data =
677 v8::Utils::OpenHandle(*global_template);
678 Handle<FunctionTemplateInfo> global_constructor =
679 Handle<FunctionTemplateInfo>(
680 FunctionTemplateInfo::cast(data->constructor()));
681 Handle<Object> proto_template(global_constructor->prototype_template());
682 if (!proto_template->IsUndefined()) {
683 js_global_template =
684 Handle<ObjectTemplateInfo>::cast(proto_template);
685 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000686 }
687
Steve Block44f0eee2011-05-26 01:26:41 +0100688 Isolate* isolate = Isolate::Current();
689 Factory* factory = isolate->factory();
690 Heap* heap = isolate->heap();
691
Andrei Popescu31002712010-02-23 13:46:05 +0000692 if (js_global_template.is_null()) {
Steve Block44f0eee2011-05-26 01:26:41 +0100693 Handle<String> name = Handle<String>(heap->empty_symbol());
694 Handle<Code> code = Handle<Code>(isolate->builtins()->builtin(
695 Builtins::kIllegal));
Andrei Popescu31002712010-02-23 13:46:05 +0000696 js_global_function =
Steve Block44f0eee2011-05-26 01:26:41 +0100697 factory->NewFunction(name, JS_GLOBAL_OBJECT_TYPE,
Andrei Popescu402d9372010-02-26 13:31:12 +0000698 JSGlobalObject::kSize, code, true);
Andrei Popescu31002712010-02-23 13:46:05 +0000699 // Change the constructor property of the prototype of the
700 // hidden global function to refer to the Object function.
701 Handle<JSObject> prototype =
702 Handle<JSObject>(
703 JSObject::cast(js_global_function->instance_prototype()));
Steve Block1e0659c2011-05-24 12:43:12 +0100704 SetLocalPropertyNoThrow(
Steve Block44f0eee2011-05-26 01:26:41 +0100705 prototype,
706 factory->constructor_symbol(),
707 isolate->object_function(),
708 NONE);
Andrei Popescu31002712010-02-23 13:46:05 +0000709 } else {
710 Handle<FunctionTemplateInfo> js_global_constructor(
711 FunctionTemplateInfo::cast(js_global_template->constructor()));
712 js_global_function =
Steve Block44f0eee2011-05-26 01:26:41 +0100713 factory->CreateApiFunction(js_global_constructor,
714 factory->InnerGlobalObject);
Steve Blocka7e24c12009-10-30 11:49:00 +0000715 }
716
Andrei Popescu31002712010-02-23 13:46:05 +0000717 js_global_function->initial_map()->set_is_hidden_prototype();
718 Handle<GlobalObject> inner_global =
Steve Block44f0eee2011-05-26 01:26:41 +0100719 factory->NewGlobalObject(js_global_function);
Andrei Popescu31002712010-02-23 13:46:05 +0000720 if (inner_global_out != NULL) {
721 *inner_global_out = inner_global;
722 }
723
724 // Step 2: create or re-initialize the global proxy object.
725 Handle<JSFunction> global_proxy_function;
726 if (global_template.IsEmpty()) {
Steve Block44f0eee2011-05-26 01:26:41 +0100727 Handle<String> name = Handle<String>(heap->empty_symbol());
728 Handle<Code> code = Handle<Code>(isolate->builtins()->builtin(
729 Builtins::kIllegal));
Andrei Popescu31002712010-02-23 13:46:05 +0000730 global_proxy_function =
Steve Block44f0eee2011-05-26 01:26:41 +0100731 factory->NewFunction(name, JS_GLOBAL_PROXY_TYPE,
Andrei Popescu31002712010-02-23 13:46:05 +0000732 JSGlobalProxy::kSize, code, true);
733 } else {
734 Handle<ObjectTemplateInfo> data =
735 v8::Utils::OpenHandle(*global_template);
736 Handle<FunctionTemplateInfo> global_constructor(
737 FunctionTemplateInfo::cast(data->constructor()));
738 global_proxy_function =
Steve Block44f0eee2011-05-26 01:26:41 +0100739 factory->CreateApiFunction(global_constructor,
740 factory->OuterGlobalObject);
Andrei Popescu31002712010-02-23 13:46:05 +0000741 }
742
Steve Block44f0eee2011-05-26 01:26:41 +0100743 Handle<String> global_name = factory->LookupAsciiSymbol("global");
Andrei Popescu31002712010-02-23 13:46:05 +0000744 global_proxy_function->shared()->set_instance_class_name(*global_name);
745 global_proxy_function->initial_map()->set_is_access_check_needed(true);
746
747 // Set global_proxy.__proto__ to js_global after ConfigureGlobalObjects
748 // Return the global proxy.
749
750 if (global_object.location() != NULL) {
751 ASSERT(global_object->IsJSGlobalProxy());
752 return ReinitializeJSGlobalProxy(
753 global_proxy_function,
754 Handle<JSGlobalProxy>::cast(global_object));
755 } else {
756 return Handle<JSGlobalProxy>::cast(
Steve Block44f0eee2011-05-26 01:26:41 +0100757 factory->NewJSObject(global_proxy_function, TENURED));
Andrei Popescu31002712010-02-23 13:46:05 +0000758 }
759}
760
761
762void Genesis::HookUpGlobalProxy(Handle<GlobalObject> inner_global,
763 Handle<JSGlobalProxy> global_proxy) {
764 // Set the global context for the global object.
765 inner_global->set_global_context(*global_context());
766 inner_global->set_global_receiver(*global_proxy);
767 global_proxy->set_context(*global_context());
768 global_context()->set_global_proxy(*global_proxy);
769}
770
771
Andrei Popescu402d9372010-02-26 13:31:12 +0000772void Genesis::HookUpInnerGlobal(Handle<GlobalObject> inner_global) {
773 Handle<GlobalObject> inner_global_from_snapshot(
774 GlobalObject::cast(global_context_->extension()));
775 Handle<JSBuiltinsObject> builtins_global(global_context_->builtins());
776 global_context_->set_extension(*inner_global);
777 global_context_->set_global(*inner_global);
778 global_context_->set_security_token(*inner_global);
779 static const PropertyAttributes attributes =
780 static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE);
781 ForceSetProperty(builtins_global,
Steve Block44f0eee2011-05-26 01:26:41 +0100782 FACTORY->LookupAsciiSymbol("global"),
Andrei Popescu402d9372010-02-26 13:31:12 +0000783 inner_global,
784 attributes);
785 // Setup the reference from the global object to the builtins object.
786 JSGlobalObject::cast(*inner_global)->set_builtins(*builtins_global);
787 TransferNamedProperties(inner_global_from_snapshot, inner_global);
788 TransferIndexedProperties(inner_global_from_snapshot, inner_global);
789}
790
791
792// This is only called if we are not using snapshots. The equivalent
793// work in the snapshot case is done in HookUpInnerGlobal.
Andrei Popescu31002712010-02-23 13:46:05 +0000794void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
795 Handle<JSFunction> empty_function) {
796 // --- G l o b a l C o n t e x t ---
797 // Use the empty function as closure (no scope info).
798 global_context()->set_closure(*empty_function);
799 global_context()->set_fcontext(*global_context());
800 global_context()->set_previous(NULL);
801 // Set extension and global object.
802 global_context()->set_extension(*inner_global);
803 global_context()->set_global(*inner_global);
804 // Security setup: Set the security token of the global object to
805 // its the inner global. This makes the security check between two
806 // different contexts fail by default even in case of global
807 // object reinitialization.
808 global_context()->set_security_token(*inner_global);
809
Steve Block44f0eee2011-05-26 01:26:41 +0100810 Isolate* isolate = Isolate::Current();
811 Factory* factory = isolate->factory();
812 Heap* heap = isolate->heap();
813
814 Handle<String> object_name = Handle<String>(heap->Object_symbol());
Steve Block1e0659c2011-05-24 12:43:12 +0100815 SetLocalPropertyNoThrow(inner_global, object_name,
Steve Block44f0eee2011-05-26 01:26:41 +0100816 isolate->object_function(), DONT_ENUM);
Andrei Popescu31002712010-02-23 13:46:05 +0000817
Steve Blocka7e24c12009-10-30 11:49:00 +0000818 Handle<JSObject> global = Handle<JSObject>(global_context()->global());
819
820 // Install global Function object
821 InstallFunction(global, "Function", JS_FUNCTION_TYPE, JSFunction::kSize,
Steve Block44f0eee2011-05-26 01:26:41 +0100822 empty_function, Builtins::kIllegal, true); // ECMA native.
Steve Blocka7e24c12009-10-30 11:49:00 +0000823
824 { // --- A r r a y ---
825 Handle<JSFunction> array_function =
826 InstallFunction(global, "Array", JS_ARRAY_TYPE, JSArray::kSize,
Steve Block44f0eee2011-05-26 01:26:41 +0100827 isolate->initial_object_prototype(),
828 Builtins::kArrayCode, true);
Steve Blocka7e24c12009-10-30 11:49:00 +0000829 array_function->shared()->set_construct_stub(
Steve Block44f0eee2011-05-26 01:26:41 +0100830 isolate->builtins()->builtin(Builtins::kArrayConstructCode));
Steve Blocka7e24c12009-10-30 11:49:00 +0000831 array_function->shared()->DontAdaptArguments();
832
833 // This seems a bit hackish, but we need to make sure Array.length
834 // is 1.
835 array_function->shared()->set_length(1);
836 Handle<DescriptorArray> array_descriptors =
Steve Block44f0eee2011-05-26 01:26:41 +0100837 factory->CopyAppendProxyDescriptor(
838 factory->empty_descriptor_array(),
839 factory->length_symbol(),
840 factory->NewProxy(&Accessors::ArrayLength),
Steve Blocka7e24c12009-10-30 11:49:00 +0000841 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE));
842
843 // Cache the fast JavaScript array map
844 global_context()->set_js_array_map(array_function->initial_map());
845 global_context()->js_array_map()->set_instance_descriptors(
846 *array_descriptors);
847 // array_function is used internally. JS code creating array object should
848 // search for the 'Array' property on the global object and use that one
849 // as the constructor. 'Array' property on a global object can be
850 // overwritten by JS code.
851 global_context()->set_array_function(*array_function);
852 }
853
854 { // --- N u m b e r ---
855 Handle<JSFunction> number_fun =
856 InstallFunction(global, "Number", JS_VALUE_TYPE, JSValue::kSize,
Steve Block44f0eee2011-05-26 01:26:41 +0100857 isolate->initial_object_prototype(),
858 Builtins::kIllegal, true);
Steve Blocka7e24c12009-10-30 11:49:00 +0000859 global_context()->set_number_function(*number_fun);
860 }
861
862 { // --- B o o l e a n ---
863 Handle<JSFunction> boolean_fun =
864 InstallFunction(global, "Boolean", JS_VALUE_TYPE, JSValue::kSize,
Steve Block44f0eee2011-05-26 01:26:41 +0100865 isolate->initial_object_prototype(),
866 Builtins::kIllegal, true);
Steve Blocka7e24c12009-10-30 11:49:00 +0000867 global_context()->set_boolean_function(*boolean_fun);
868 }
869
870 { // --- S t r i n g ---
871 Handle<JSFunction> string_fun =
872 InstallFunction(global, "String", JS_VALUE_TYPE, JSValue::kSize,
Steve Block44f0eee2011-05-26 01:26:41 +0100873 isolate->initial_object_prototype(),
874 Builtins::kIllegal, true);
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100875 string_fun->shared()->set_construct_stub(
Steve Block44f0eee2011-05-26 01:26:41 +0100876 isolate->builtins()->builtin(Builtins::kStringConstructCode));
Steve Blocka7e24c12009-10-30 11:49:00 +0000877 global_context()->set_string_function(*string_fun);
878 // Add 'length' property to strings.
879 Handle<DescriptorArray> string_descriptors =
Steve Block44f0eee2011-05-26 01:26:41 +0100880 factory->CopyAppendProxyDescriptor(
881 factory->empty_descriptor_array(),
882 factory->length_symbol(),
883 factory->NewProxy(&Accessors::StringLength),
Steve Blocka7e24c12009-10-30 11:49:00 +0000884 static_cast<PropertyAttributes>(DONT_ENUM |
885 DONT_DELETE |
886 READ_ONLY));
887
888 Handle<Map> string_map =
889 Handle<Map>(global_context()->string_function()->initial_map());
890 string_map->set_instance_descriptors(*string_descriptors);
891 }
892
893 { // --- D a t e ---
894 // Builtin functions for Date.prototype.
895 Handle<JSFunction> date_fun =
896 InstallFunction(global, "Date", JS_VALUE_TYPE, JSValue::kSize,
Steve Block44f0eee2011-05-26 01:26:41 +0100897 isolate->initial_object_prototype(),
898 Builtins::kIllegal, true);
Steve Blocka7e24c12009-10-30 11:49:00 +0000899
900 global_context()->set_date_function(*date_fun);
901 }
902
903
904 { // -- R e g E x p
905 // Builtin functions for RegExp.prototype.
906 Handle<JSFunction> regexp_fun =
907 InstallFunction(global, "RegExp", JS_REGEXP_TYPE, JSRegExp::kSize,
Steve Block44f0eee2011-05-26 01:26:41 +0100908 isolate->initial_object_prototype(),
909 Builtins::kIllegal, true);
Steve Blocka7e24c12009-10-30 11:49:00 +0000910 global_context()->set_regexp_function(*regexp_fun);
Steve Block6ded16b2010-05-10 14:33:55 +0100911
912 ASSERT(regexp_fun->has_initial_map());
913 Handle<Map> initial_map(regexp_fun->initial_map());
914
915 ASSERT_EQ(0, initial_map->inobject_properties());
916
Steve Block44f0eee2011-05-26 01:26:41 +0100917 Handle<DescriptorArray> descriptors = factory->NewDescriptorArray(5);
Steve Block6ded16b2010-05-10 14:33:55 +0100918 PropertyAttributes final =
919 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
920 int enum_index = 0;
921 {
922 // ECMA-262, section 15.10.7.1.
Steve Block44f0eee2011-05-26 01:26:41 +0100923 FieldDescriptor field(heap->source_symbol(),
Steve Block6ded16b2010-05-10 14:33:55 +0100924 JSRegExp::kSourceFieldIndex,
925 final,
926 enum_index++);
927 descriptors->Set(0, &field);
928 }
929 {
930 // ECMA-262, section 15.10.7.2.
Steve Block44f0eee2011-05-26 01:26:41 +0100931 FieldDescriptor field(heap->global_symbol(),
Steve Block6ded16b2010-05-10 14:33:55 +0100932 JSRegExp::kGlobalFieldIndex,
933 final,
934 enum_index++);
935 descriptors->Set(1, &field);
936 }
937 {
938 // ECMA-262, section 15.10.7.3.
Steve Block44f0eee2011-05-26 01:26:41 +0100939 FieldDescriptor field(heap->ignore_case_symbol(),
Steve Block6ded16b2010-05-10 14:33:55 +0100940 JSRegExp::kIgnoreCaseFieldIndex,
941 final,
942 enum_index++);
943 descriptors->Set(2, &field);
944 }
945 {
946 // ECMA-262, section 15.10.7.4.
Steve Block44f0eee2011-05-26 01:26:41 +0100947 FieldDescriptor field(heap->multiline_symbol(),
Steve Block6ded16b2010-05-10 14:33:55 +0100948 JSRegExp::kMultilineFieldIndex,
949 final,
950 enum_index++);
951 descriptors->Set(3, &field);
952 }
953 {
954 // ECMA-262, section 15.10.7.5.
955 PropertyAttributes writable =
956 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
Steve Block44f0eee2011-05-26 01:26:41 +0100957 FieldDescriptor field(heap->last_index_symbol(),
Steve Block6ded16b2010-05-10 14:33:55 +0100958 JSRegExp::kLastIndexFieldIndex,
959 writable,
960 enum_index++);
961 descriptors->Set(4, &field);
962 }
963 descriptors->SetNextEnumerationIndex(enum_index);
964 descriptors->Sort();
965
966 initial_map->set_inobject_properties(5);
967 initial_map->set_pre_allocated_property_fields(5);
968 initial_map->set_unused_property_fields(0);
969 initial_map->set_instance_size(
970 initial_map->instance_size() + 5 * kPointerSize);
971 initial_map->set_instance_descriptors(*descriptors);
Iain Merrick75681382010-08-19 15:07:18 +0100972 initial_map->set_visitor_id(StaticVisitorBase::GetVisitorId(*initial_map));
Steve Blocka7e24c12009-10-30 11:49:00 +0000973 }
974
975 { // -- J S O N
Steve Block44f0eee2011-05-26 01:26:41 +0100976 Handle<String> name = factory->NewStringFromAscii(CStrVector("JSON"));
977 Handle<JSFunction> cons = factory->NewFunction(
Steve Blocka7e24c12009-10-30 11:49:00 +0000978 name,
Steve Block44f0eee2011-05-26 01:26:41 +0100979 factory->the_hole_value());
Steve Blocka7e24c12009-10-30 11:49:00 +0000980 cons->SetInstancePrototype(global_context()->initial_object_prototype());
981 cons->SetInstanceClassName(*name);
Steve Block44f0eee2011-05-26 01:26:41 +0100982 Handle<JSObject> json_object = factory->NewJSObject(cons, TENURED);
Steve Blocka7e24c12009-10-30 11:49:00 +0000983 ASSERT(json_object->IsJSObject());
Steve Block1e0659c2011-05-24 12:43:12 +0100984 SetLocalPropertyNoThrow(global, name, json_object, DONT_ENUM);
Steve Blocka7e24c12009-10-30 11:49:00 +0000985 global_context()->set_json_object(*json_object);
986 }
987
988 { // --- arguments_boilerplate_
989 // Make sure we can recognize argument objects at runtime.
990 // This is done by introducing an anonymous function with
991 // class_name equals 'Arguments'.
Steve Block44f0eee2011-05-26 01:26:41 +0100992 Handle<String> symbol = factory->LookupAsciiSymbol("Arguments");
993 Handle<Code> code = Handle<Code>(
994 isolate->builtins()->builtin(Builtins::kIllegal));
Steve Blocka7e24c12009-10-30 11:49:00 +0000995 Handle<JSObject> prototype =
996 Handle<JSObject>(
997 JSObject::cast(global_context()->object_function()->prototype()));
998
999 Handle<JSFunction> function =
Steve Block44f0eee2011-05-26 01:26:41 +01001000 factory->NewFunctionWithPrototype(symbol,
Steve Blocka7e24c12009-10-30 11:49:00 +00001001 JS_OBJECT_TYPE,
1002 JSObject::kHeaderSize,
1003 prototype,
1004 code,
1005 false);
1006 ASSERT(!function->has_initial_map());
1007 function->shared()->set_instance_class_name(*symbol);
1008 function->shared()->set_expected_nof_properties(2);
Steve Block44f0eee2011-05-26 01:26:41 +01001009 Handle<JSObject> result = factory->NewJSObject(function);
Steve Blocka7e24c12009-10-30 11:49:00 +00001010
1011 global_context()->set_arguments_boilerplate(*result);
Steve Block44f0eee2011-05-26 01:26:41 +01001012 // Note: length must be added as the first property and
1013 // callee must be added as the second property.
1014 SetLocalPropertyNoThrow(result, factory->length_symbol(),
1015 factory->undefined_value(),
Steve Block1e0659c2011-05-24 12:43:12 +01001016 DONT_ENUM);
Steve Block44f0eee2011-05-26 01:26:41 +01001017 SetLocalPropertyNoThrow(result, factory->callee_symbol(),
1018 factory->undefined_value(),
Steve Block1e0659c2011-05-24 12:43:12 +01001019 DONT_ENUM);
Steve Blocka7e24c12009-10-30 11:49:00 +00001020
1021#ifdef DEBUG
1022 LookupResult lookup;
Steve Block44f0eee2011-05-26 01:26:41 +01001023 result->LocalLookup(heap->callee_symbol(), &lookup);
Andrei Popescu402d9372010-02-26 13:31:12 +00001024 ASSERT(lookup.IsProperty() && (lookup.type() == FIELD));
Steve Block44f0eee2011-05-26 01:26:41 +01001025 ASSERT(lookup.GetFieldIndex() == Heap::kArgumentsCalleeIndex);
Steve Blocka7e24c12009-10-30 11:49:00 +00001026
Steve Block44f0eee2011-05-26 01:26:41 +01001027 result->LocalLookup(heap->length_symbol(), &lookup);
Andrei Popescu402d9372010-02-26 13:31:12 +00001028 ASSERT(lookup.IsProperty() && (lookup.type() == FIELD));
Steve Block44f0eee2011-05-26 01:26:41 +01001029 ASSERT(lookup.GetFieldIndex() == Heap::kArgumentsLengthIndex);
Steve Blocka7e24c12009-10-30 11:49:00 +00001030
Steve Block44f0eee2011-05-26 01:26:41 +01001031 ASSERT(result->map()->inobject_properties() > Heap::kArgumentsCalleeIndex);
1032 ASSERT(result->map()->inobject_properties() > Heap::kArgumentsLengthIndex);
1033
1034 // Check the state of the object.
1035 ASSERT(result->HasFastProperties());
1036 ASSERT(result->HasFastElements());
1037#endif
1038 }
1039
1040 { // --- strict mode arguments boilerplate
1041 const PropertyAttributes attributes =
1042 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
1043
1044 // Create the ThrowTypeError functions.
1045 Handle<FixedArray> callee = factory->NewFixedArray(2, TENURED);
1046 Handle<FixedArray> caller = factory->NewFixedArray(2, TENURED);
1047
1048 Handle<JSFunction> callee_throw =
1049 CreateThrowTypeErrorFunction(Builtins::kStrictArgumentsCallee);
1050 Handle<JSFunction> caller_throw =
1051 CreateThrowTypeErrorFunction(Builtins::kStrictArgumentsCaller);
1052
1053 // Install the ThrowTypeError functions.
1054 callee->set(0, *callee_throw);
1055 callee->set(1, *callee_throw);
1056 caller->set(0, *caller_throw);
1057 caller->set(1, *caller_throw);
1058
1059 // Create the descriptor array for the arguments object.
1060 Handle<DescriptorArray> descriptors = factory->NewDescriptorArray(3);
1061 { // length
1062 FieldDescriptor d(*factory->length_symbol(), 0, DONT_ENUM);
1063 descriptors->Set(0, &d);
1064 }
1065 { // callee
1066 CallbacksDescriptor d(*factory->callee_symbol(), *callee, attributes);
1067 descriptors->Set(1, &d);
1068 }
1069 { // caller
1070 CallbacksDescriptor d(*factory->caller_symbol(), *caller, attributes);
1071 descriptors->Set(2, &d);
1072 }
1073 descriptors->Sort();
1074
1075 // Create the map. Allocate one in-object field for length.
1076 Handle<Map> map = factory->NewMap(JS_OBJECT_TYPE,
1077 Heap::kArgumentsObjectSizeStrict);
1078 map->set_instance_descriptors(*descriptors);
1079 map->set_function_with_prototype(true);
1080 map->set_prototype(global_context()->object_function()->prototype());
1081 map->set_pre_allocated_property_fields(1);
1082 map->set_inobject_properties(1);
1083
1084 // Copy constructor from the non-strict arguments boilerplate.
1085 map->set_constructor(
1086 global_context()->arguments_boilerplate()->map()->constructor());
1087
1088 // Allocate the arguments boilerplate object.
1089 Handle<JSObject> result = factory->NewJSObjectFromMap(map);
1090 global_context()->set_strict_mode_arguments_boilerplate(*result);
1091
1092 // Add length property only for strict mode boilerplate.
1093 SetLocalPropertyNoThrow(result, factory->length_symbol(),
1094 factory->undefined_value(),
1095 DONT_ENUM);
1096
1097#ifdef DEBUG
1098 LookupResult lookup;
1099 result->LocalLookup(heap->length_symbol(), &lookup);
1100 ASSERT(lookup.IsProperty() && (lookup.type() == FIELD));
1101 ASSERT(lookup.GetFieldIndex() == Heap::kArgumentsLengthIndex);
1102
1103 ASSERT(result->map()->inobject_properties() > Heap::kArgumentsLengthIndex);
Steve Blocka7e24c12009-10-30 11:49:00 +00001104
1105 // Check the state of the object.
1106 ASSERT(result->HasFastProperties());
1107 ASSERT(result->HasFastElements());
1108#endif
1109 }
1110
1111 { // --- context extension
1112 // Create a function for the context extension objects.
Steve Block44f0eee2011-05-26 01:26:41 +01001113 Handle<Code> code = Handle<Code>(
1114 isolate->builtins()->builtin(Builtins::kIllegal));
Steve Blocka7e24c12009-10-30 11:49:00 +00001115 Handle<JSFunction> context_extension_fun =
Steve Block44f0eee2011-05-26 01:26:41 +01001116 factory->NewFunction(factory->empty_symbol(),
Steve Blocka7e24c12009-10-30 11:49:00 +00001117 JS_CONTEXT_EXTENSION_OBJECT_TYPE,
1118 JSObject::kHeaderSize,
1119 code,
1120 true);
1121
Steve Block44f0eee2011-05-26 01:26:41 +01001122 Handle<String> name = factory->LookupAsciiSymbol("context_extension");
Steve Blocka7e24c12009-10-30 11:49:00 +00001123 context_extension_fun->shared()->set_instance_class_name(*name);
1124 global_context()->set_context_extension_function(*context_extension_fun);
1125 }
1126
1127
1128 {
1129 // Setup the call-as-function delegate.
1130 Handle<Code> code =
Steve Block44f0eee2011-05-26 01:26:41 +01001131 Handle<Code>(isolate->builtins()->builtin(
1132 Builtins::kHandleApiCallAsFunction));
Steve Blocka7e24c12009-10-30 11:49:00 +00001133 Handle<JSFunction> delegate =
Steve Block44f0eee2011-05-26 01:26:41 +01001134 factory->NewFunction(factory->empty_symbol(), JS_OBJECT_TYPE,
Steve Blocka7e24c12009-10-30 11:49:00 +00001135 JSObject::kHeaderSize, code, true);
1136 global_context()->set_call_as_function_delegate(*delegate);
1137 delegate->shared()->DontAdaptArguments();
1138 }
1139
1140 {
1141 // Setup the call-as-constructor delegate.
1142 Handle<Code> code =
Steve Block44f0eee2011-05-26 01:26:41 +01001143 Handle<Code>(isolate->builtins()->builtin(
1144 Builtins::kHandleApiCallAsConstructor));
Steve Blocka7e24c12009-10-30 11:49:00 +00001145 Handle<JSFunction> delegate =
Steve Block44f0eee2011-05-26 01:26:41 +01001146 factory->NewFunction(factory->empty_symbol(), JS_OBJECT_TYPE,
Steve Blocka7e24c12009-10-30 11:49:00 +00001147 JSObject::kHeaderSize, code, true);
1148 global_context()->set_call_as_constructor_delegate(*delegate);
1149 delegate->shared()->DontAdaptArguments();
1150 }
1151
Steve Blocka7e24c12009-10-30 11:49:00 +00001152 // Initialize the out of memory slot.
Steve Block44f0eee2011-05-26 01:26:41 +01001153 global_context()->set_out_of_memory(heap->false_value());
Steve Blocka7e24c12009-10-30 11:49:00 +00001154
1155 // Initialize the data slot.
Steve Block44f0eee2011-05-26 01:26:41 +01001156 global_context()->set_data(heap->undefined_value());
Steve Blocka7e24c12009-10-30 11:49:00 +00001157}
1158
1159
1160bool Genesis::CompileBuiltin(int index) {
1161 Vector<const char> name = Natives::GetScriptName(index);
Steve Block44f0eee2011-05-26 01:26:41 +01001162 Handle<String> source_code =
1163 Isolate::Current()->bootstrapper()->NativesSourceLookup(index);
Steve Blocka7e24c12009-10-30 11:49:00 +00001164 return CompileNative(name, source_code);
1165}
1166
1167
1168bool Genesis::CompileNative(Vector<const char> name, Handle<String> source) {
1169 HandleScope scope;
Steve Block44f0eee2011-05-26 01:26:41 +01001170 Isolate* isolate = Isolate::Current();
Steve Blocka7e24c12009-10-30 11:49:00 +00001171#ifdef ENABLE_DEBUGGER_SUPPORT
Steve Block44f0eee2011-05-26 01:26:41 +01001172 isolate->debugger()->set_compiling_natives(true);
Steve Blocka7e24c12009-10-30 11:49:00 +00001173#endif
Andrei Popescu31002712010-02-23 13:46:05 +00001174 bool result = CompileScriptCached(name,
1175 source,
1176 NULL,
1177 NULL,
Steve Block44f0eee2011-05-26 01:26:41 +01001178 Handle<Context>(isolate->context()),
Andrei Popescu31002712010-02-23 13:46:05 +00001179 true);
Steve Block44f0eee2011-05-26 01:26:41 +01001180 ASSERT(isolate->has_pending_exception() != result);
1181 if (!result) isolate->clear_pending_exception();
Steve Blocka7e24c12009-10-30 11:49:00 +00001182#ifdef ENABLE_DEBUGGER_SUPPORT
Steve Block44f0eee2011-05-26 01:26:41 +01001183 isolate->debugger()->set_compiling_natives(false);
Steve Blocka7e24c12009-10-30 11:49:00 +00001184#endif
1185 return result;
1186}
1187
1188
1189bool Genesis::CompileScriptCached(Vector<const char> name,
1190 Handle<String> source,
1191 SourceCodeCache* cache,
1192 v8::Extension* extension,
Andrei Popescu31002712010-02-23 13:46:05 +00001193 Handle<Context> top_context,
Steve Blocka7e24c12009-10-30 11:49:00 +00001194 bool use_runtime_context) {
Steve Block44f0eee2011-05-26 01:26:41 +01001195 Factory* factory = Isolate::Current()->factory();
Steve Blocka7e24c12009-10-30 11:49:00 +00001196 HandleScope scope;
Steve Block6ded16b2010-05-10 14:33:55 +01001197 Handle<SharedFunctionInfo> function_info;
Steve Blocka7e24c12009-10-30 11:49:00 +00001198
1199 // If we can't find the function in the cache, we compile a new
1200 // function and insert it into the cache.
Steve Block6ded16b2010-05-10 14:33:55 +01001201 if (cache == NULL || !cache->Lookup(name, &function_info)) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001202 ASSERT(source->IsAsciiRepresentation());
Steve Block44f0eee2011-05-26 01:26:41 +01001203 Handle<String> script_name = factory->NewStringFromUtf8(name);
Steve Block6ded16b2010-05-10 14:33:55 +01001204 function_info = Compiler::Compile(
Andrei Popescu31002712010-02-23 13:46:05 +00001205 source,
1206 script_name,
1207 0,
1208 0,
1209 extension,
1210 NULL,
Andrei Popescu402d9372010-02-26 13:31:12 +00001211 Handle<String>::null(),
Andrei Popescu31002712010-02-23 13:46:05 +00001212 use_runtime_context ? NATIVES_CODE : NOT_NATIVES_CODE);
Steve Block6ded16b2010-05-10 14:33:55 +01001213 if (function_info.is_null()) return false;
1214 if (cache != NULL) cache->Add(name, function_info);
Steve Blocka7e24c12009-10-30 11:49:00 +00001215 }
1216
1217 // Setup the function context. Conceptually, we should clone the
1218 // function before overwriting the context but since we're in a
1219 // single-threaded environment it is not strictly necessary.
Andrei Popescu31002712010-02-23 13:46:05 +00001220 ASSERT(top_context->IsGlobalContext());
Steve Blocka7e24c12009-10-30 11:49:00 +00001221 Handle<Context> context =
1222 Handle<Context>(use_runtime_context
Andrei Popescu31002712010-02-23 13:46:05 +00001223 ? Handle<Context>(top_context->runtime_context())
1224 : top_context);
Steve Blocka7e24c12009-10-30 11:49:00 +00001225 Handle<JSFunction> fun =
Steve Block44f0eee2011-05-26 01:26:41 +01001226 factory->NewFunctionFromSharedFunctionInfo(function_info, context);
Steve Blocka7e24c12009-10-30 11:49:00 +00001227
Leon Clarke4515c472010-02-03 11:58:03 +00001228 // Call function using either the runtime object or the global
Steve Blocka7e24c12009-10-30 11:49:00 +00001229 // object as the receiver. Provide no parameters.
1230 Handle<Object> receiver =
1231 Handle<Object>(use_runtime_context
Andrei Popescu31002712010-02-23 13:46:05 +00001232 ? top_context->builtins()
1233 : top_context->global());
Steve Blocka7e24c12009-10-30 11:49:00 +00001234 bool has_pending_exception;
1235 Handle<Object> result =
1236 Execution::Call(fun, receiver, 0, NULL, &has_pending_exception);
1237 if (has_pending_exception) return false;
Andrei Popescu402d9372010-02-26 13:31:12 +00001238 return true;
Steve Blocka7e24c12009-10-30 11:49:00 +00001239}
1240
1241
John Reck59135872010-11-02 12:39:01 -07001242#define INSTALL_NATIVE(Type, name, var) \
Steve Block44f0eee2011-05-26 01:26:41 +01001243 Handle<String> var##_name = factory->LookupAsciiSymbol(name); \
John Reck59135872010-11-02 12:39:01 -07001244 global_context()->set_##var(Type::cast( \
1245 global_context()->builtins()->GetPropertyNoExceptionThrown(*var##_name)));
Steve Blocka7e24c12009-10-30 11:49:00 +00001246
Steve Block44f0eee2011-05-26 01:26:41 +01001247
Steve Blocka7e24c12009-10-30 11:49:00 +00001248void Genesis::InstallNativeFunctions() {
Steve Block44f0eee2011-05-26 01:26:41 +01001249 Factory* factory = Isolate::Current()->factory();
Steve Blocka7e24c12009-10-30 11:49:00 +00001250 HandleScope scope;
1251 INSTALL_NATIVE(JSFunction, "CreateDate", create_date_fun);
1252 INSTALL_NATIVE(JSFunction, "ToNumber", to_number_fun);
1253 INSTALL_NATIVE(JSFunction, "ToString", to_string_fun);
1254 INSTALL_NATIVE(JSFunction, "ToDetailString", to_detail_string_fun);
1255 INSTALL_NATIVE(JSFunction, "ToObject", to_object_fun);
1256 INSTALL_NATIVE(JSFunction, "ToInteger", to_integer_fun);
1257 INSTALL_NATIVE(JSFunction, "ToUint32", to_uint32_fun);
1258 INSTALL_NATIVE(JSFunction, "ToInt32", to_int32_fun);
Leon Clarkee46be812010-01-19 14:06:41 +00001259 INSTALL_NATIVE(JSFunction, "GlobalEval", global_eval_fun);
Steve Blocka7e24c12009-10-30 11:49:00 +00001260 INSTALL_NATIVE(JSFunction, "Instantiate", instantiate_fun);
1261 INSTALL_NATIVE(JSFunction, "ConfigureTemplateInstance",
1262 configure_instance_fun);
Steve Blocka7e24c12009-10-30 11:49:00 +00001263 INSTALL_NATIVE(JSFunction, "GetStackTraceLine", get_stack_trace_line_fun);
1264 INSTALL_NATIVE(JSObject, "functionCache", function_cache);
1265}
1266
1267#undef INSTALL_NATIVE
1268
1269
1270bool Genesis::InstallNatives() {
1271 HandleScope scope;
Steve Block44f0eee2011-05-26 01:26:41 +01001272 Isolate* isolate = Isolate::Current();
1273 Factory* factory = isolate->factory();
1274 Heap* heap = isolate->heap();
Steve Blocka7e24c12009-10-30 11:49:00 +00001275
1276 // Create a function for the builtins object. Allocate space for the
1277 // JavaScript builtins, a reference to the builtins object
1278 // (itself) and a reference to the global_context directly in the object.
Steve Block44f0eee2011-05-26 01:26:41 +01001279 Handle<Code> code = Handle<Code>(
1280 isolate->builtins()->builtin(Builtins::kIllegal));
Steve Blocka7e24c12009-10-30 11:49:00 +00001281 Handle<JSFunction> builtins_fun =
Steve Block44f0eee2011-05-26 01:26:41 +01001282 factory->NewFunction(factory->empty_symbol(), JS_BUILTINS_OBJECT_TYPE,
Steve Blocka7e24c12009-10-30 11:49:00 +00001283 JSBuiltinsObject::kSize, code, true);
1284
Steve Block44f0eee2011-05-26 01:26:41 +01001285 Handle<String> name = factory->LookupAsciiSymbol("builtins");
Steve Blocka7e24c12009-10-30 11:49:00 +00001286 builtins_fun->shared()->set_instance_class_name(*name);
1287
1288 // Allocate the builtins object.
1289 Handle<JSBuiltinsObject> builtins =
Steve Block44f0eee2011-05-26 01:26:41 +01001290 Handle<JSBuiltinsObject>::cast(factory->NewGlobalObject(builtins_fun));
Steve Blocka7e24c12009-10-30 11:49:00 +00001291 builtins->set_builtins(*builtins);
1292 builtins->set_global_context(*global_context());
1293 builtins->set_global_receiver(*builtins);
1294
1295 // Setup the 'global' properties of the builtins object. The
1296 // 'global' property that refers to the global object is the only
1297 // way to get from code running in the builtins context to the
1298 // global object.
1299 static const PropertyAttributes attributes =
1300 static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE);
Steve Block44f0eee2011-05-26 01:26:41 +01001301 Handle<String> global_symbol = factory->LookupAsciiSymbol("global");
Steve Block1e0659c2011-05-24 12:43:12 +01001302 Handle<Object> global_obj(global_context()->global());
1303 SetLocalPropertyNoThrow(builtins, global_symbol, global_obj, attributes);
Steve Blocka7e24c12009-10-30 11:49:00 +00001304
1305 // Setup the reference from the global object to the builtins object.
1306 JSGlobalObject::cast(global_context()->global())->set_builtins(*builtins);
1307
1308 // Create a bridge function that has context in the global context.
1309 Handle<JSFunction> bridge =
Steve Block44f0eee2011-05-26 01:26:41 +01001310 factory->NewFunction(factory->empty_symbol(), factory->undefined_value());
1311 ASSERT(bridge->context() == *isolate->global_context());
Steve Blocka7e24c12009-10-30 11:49:00 +00001312
1313 // Allocate the builtins context.
1314 Handle<Context> context =
Steve Block44f0eee2011-05-26 01:26:41 +01001315 factory->NewFunctionContext(Context::MIN_CONTEXT_SLOTS, bridge);
Steve Blocka7e24c12009-10-30 11:49:00 +00001316 context->set_global(*builtins); // override builtins global object
1317
1318 global_context()->set_runtime_context(*context);
1319
1320 { // -- S c r i p t
1321 // Builtin functions for Script.
1322 Handle<JSFunction> script_fun =
1323 InstallFunction(builtins, "Script", JS_VALUE_TYPE, JSValue::kSize,
Steve Block44f0eee2011-05-26 01:26:41 +01001324 isolate->initial_object_prototype(),
1325 Builtins::kIllegal, false);
Steve Blocka7e24c12009-10-30 11:49:00 +00001326 Handle<JSObject> prototype =
Steve Block44f0eee2011-05-26 01:26:41 +01001327 factory->NewJSObject(isolate->object_function(), TENURED);
Steve Blocka7e24c12009-10-30 11:49:00 +00001328 SetPrototype(script_fun, prototype);
1329 global_context()->set_script_function(*script_fun);
1330
1331 // Add 'source' and 'data' property to scripts.
1332 PropertyAttributes common_attributes =
1333 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
Steve Block44f0eee2011-05-26 01:26:41 +01001334 Handle<Proxy> proxy_source = factory->NewProxy(&Accessors::ScriptSource);
Steve Blocka7e24c12009-10-30 11:49:00 +00001335 Handle<DescriptorArray> script_descriptors =
Steve Block44f0eee2011-05-26 01:26:41 +01001336 factory->CopyAppendProxyDescriptor(
1337 factory->empty_descriptor_array(),
1338 factory->LookupAsciiSymbol("source"),
Steve Blocka7e24c12009-10-30 11:49:00 +00001339 proxy_source,
1340 common_attributes);
Steve Block44f0eee2011-05-26 01:26:41 +01001341 Handle<Proxy> proxy_name = factory->NewProxy(&Accessors::ScriptName);
Steve Blocka7e24c12009-10-30 11:49:00 +00001342 script_descriptors =
Steve Block44f0eee2011-05-26 01:26:41 +01001343 factory->CopyAppendProxyDescriptor(
Steve Blocka7e24c12009-10-30 11:49:00 +00001344 script_descriptors,
Steve Block44f0eee2011-05-26 01:26:41 +01001345 factory->LookupAsciiSymbol("name"),
Steve Blocka7e24c12009-10-30 11:49:00 +00001346 proxy_name,
1347 common_attributes);
Steve Block44f0eee2011-05-26 01:26:41 +01001348 Handle<Proxy> proxy_id = factory->NewProxy(&Accessors::ScriptId);
Steve Blocka7e24c12009-10-30 11:49:00 +00001349 script_descriptors =
Steve Block44f0eee2011-05-26 01:26:41 +01001350 factory->CopyAppendProxyDescriptor(
Steve Blocka7e24c12009-10-30 11:49:00 +00001351 script_descriptors,
Steve Block44f0eee2011-05-26 01:26:41 +01001352 factory->LookupAsciiSymbol("id"),
Steve Blocka7e24c12009-10-30 11:49:00 +00001353 proxy_id,
1354 common_attributes);
1355 Handle<Proxy> proxy_line_offset =
Steve Block44f0eee2011-05-26 01:26:41 +01001356 factory->NewProxy(&Accessors::ScriptLineOffset);
Steve Blocka7e24c12009-10-30 11:49:00 +00001357 script_descriptors =
Steve Block44f0eee2011-05-26 01:26:41 +01001358 factory->CopyAppendProxyDescriptor(
Steve Blocka7e24c12009-10-30 11:49:00 +00001359 script_descriptors,
Steve Block44f0eee2011-05-26 01:26:41 +01001360 factory->LookupAsciiSymbol("line_offset"),
Steve Blocka7e24c12009-10-30 11:49:00 +00001361 proxy_line_offset,
1362 common_attributes);
1363 Handle<Proxy> proxy_column_offset =
Steve Block44f0eee2011-05-26 01:26:41 +01001364 factory->NewProxy(&Accessors::ScriptColumnOffset);
Steve Blocka7e24c12009-10-30 11:49:00 +00001365 script_descriptors =
Steve Block44f0eee2011-05-26 01:26:41 +01001366 factory->CopyAppendProxyDescriptor(
Steve Blocka7e24c12009-10-30 11:49:00 +00001367 script_descriptors,
Steve Block44f0eee2011-05-26 01:26:41 +01001368 factory->LookupAsciiSymbol("column_offset"),
Steve Blocka7e24c12009-10-30 11:49:00 +00001369 proxy_column_offset,
1370 common_attributes);
Steve Block44f0eee2011-05-26 01:26:41 +01001371 Handle<Proxy> proxy_data = factory->NewProxy(&Accessors::ScriptData);
Steve Blocka7e24c12009-10-30 11:49:00 +00001372 script_descriptors =
Steve Block44f0eee2011-05-26 01:26:41 +01001373 factory->CopyAppendProxyDescriptor(
Steve Blocka7e24c12009-10-30 11:49:00 +00001374 script_descriptors,
Steve Block44f0eee2011-05-26 01:26:41 +01001375 factory->LookupAsciiSymbol("data"),
Steve Blocka7e24c12009-10-30 11:49:00 +00001376 proxy_data,
1377 common_attributes);
Steve Block44f0eee2011-05-26 01:26:41 +01001378 Handle<Proxy> proxy_type = factory->NewProxy(&Accessors::ScriptType);
Steve Blocka7e24c12009-10-30 11:49:00 +00001379 script_descriptors =
Steve Block44f0eee2011-05-26 01:26:41 +01001380 factory->CopyAppendProxyDescriptor(
Steve Blocka7e24c12009-10-30 11:49:00 +00001381 script_descriptors,
Steve Block44f0eee2011-05-26 01:26:41 +01001382 factory->LookupAsciiSymbol("type"),
Steve Blocka7e24c12009-10-30 11:49:00 +00001383 proxy_type,
1384 common_attributes);
1385 Handle<Proxy> proxy_compilation_type =
Steve Block44f0eee2011-05-26 01:26:41 +01001386 factory->NewProxy(&Accessors::ScriptCompilationType);
Steve Blocka7e24c12009-10-30 11:49:00 +00001387 script_descriptors =
Steve Block44f0eee2011-05-26 01:26:41 +01001388 factory->CopyAppendProxyDescriptor(
Steve Blocka7e24c12009-10-30 11:49:00 +00001389 script_descriptors,
Steve Block44f0eee2011-05-26 01:26:41 +01001390 factory->LookupAsciiSymbol("compilation_type"),
Steve Blocka7e24c12009-10-30 11:49:00 +00001391 proxy_compilation_type,
1392 common_attributes);
1393 Handle<Proxy> proxy_line_ends =
Steve Block44f0eee2011-05-26 01:26:41 +01001394 factory->NewProxy(&Accessors::ScriptLineEnds);
Steve Blocka7e24c12009-10-30 11:49:00 +00001395 script_descriptors =
Steve Block44f0eee2011-05-26 01:26:41 +01001396 factory->CopyAppendProxyDescriptor(
Steve Blocka7e24c12009-10-30 11:49:00 +00001397 script_descriptors,
Steve Block44f0eee2011-05-26 01:26:41 +01001398 factory->LookupAsciiSymbol("line_ends"),
Steve Blocka7e24c12009-10-30 11:49:00 +00001399 proxy_line_ends,
1400 common_attributes);
1401 Handle<Proxy> proxy_context_data =
Steve Block44f0eee2011-05-26 01:26:41 +01001402 factory->NewProxy(&Accessors::ScriptContextData);
Steve Blocka7e24c12009-10-30 11:49:00 +00001403 script_descriptors =
Steve Block44f0eee2011-05-26 01:26:41 +01001404 factory->CopyAppendProxyDescriptor(
Steve Blocka7e24c12009-10-30 11:49:00 +00001405 script_descriptors,
Steve Block44f0eee2011-05-26 01:26:41 +01001406 factory->LookupAsciiSymbol("context_data"),
Steve Blocka7e24c12009-10-30 11:49:00 +00001407 proxy_context_data,
1408 common_attributes);
Steve Blockd0582a62009-12-15 09:54:21 +00001409 Handle<Proxy> proxy_eval_from_script =
Steve Block44f0eee2011-05-26 01:26:41 +01001410 factory->NewProxy(&Accessors::ScriptEvalFromScript);
Steve Blocka7e24c12009-10-30 11:49:00 +00001411 script_descriptors =
Steve Block44f0eee2011-05-26 01:26:41 +01001412 factory->CopyAppendProxyDescriptor(
Steve Blocka7e24c12009-10-30 11:49:00 +00001413 script_descriptors,
Steve Block44f0eee2011-05-26 01:26:41 +01001414 factory->LookupAsciiSymbol("eval_from_script"),
Steve Blockd0582a62009-12-15 09:54:21 +00001415 proxy_eval_from_script,
Steve Blocka7e24c12009-10-30 11:49:00 +00001416 common_attributes);
Steve Blockd0582a62009-12-15 09:54:21 +00001417 Handle<Proxy> proxy_eval_from_script_position =
Steve Block44f0eee2011-05-26 01:26:41 +01001418 factory->NewProxy(&Accessors::ScriptEvalFromScriptPosition);
Steve Blocka7e24c12009-10-30 11:49:00 +00001419 script_descriptors =
Steve Block44f0eee2011-05-26 01:26:41 +01001420 factory->CopyAppendProxyDescriptor(
Steve Blocka7e24c12009-10-30 11:49:00 +00001421 script_descriptors,
Steve Block44f0eee2011-05-26 01:26:41 +01001422 factory->LookupAsciiSymbol("eval_from_script_position"),
Steve Blockd0582a62009-12-15 09:54:21 +00001423 proxy_eval_from_script_position,
1424 common_attributes);
1425 Handle<Proxy> proxy_eval_from_function_name =
Steve Block44f0eee2011-05-26 01:26:41 +01001426 factory->NewProxy(&Accessors::ScriptEvalFromFunctionName);
Steve Blockd0582a62009-12-15 09:54:21 +00001427 script_descriptors =
Steve Block44f0eee2011-05-26 01:26:41 +01001428 factory->CopyAppendProxyDescriptor(
Steve Blockd0582a62009-12-15 09:54:21 +00001429 script_descriptors,
Steve Block44f0eee2011-05-26 01:26:41 +01001430 factory->LookupAsciiSymbol("eval_from_function_name"),
Steve Blockd0582a62009-12-15 09:54:21 +00001431 proxy_eval_from_function_name,
Steve Blocka7e24c12009-10-30 11:49:00 +00001432 common_attributes);
1433
1434 Handle<Map> script_map = Handle<Map>(script_fun->initial_map());
1435 script_map->set_instance_descriptors(*script_descriptors);
1436
1437 // Allocate the empty script.
Steve Block44f0eee2011-05-26 01:26:41 +01001438 Handle<Script> script = factory->NewScript(factory->empty_string());
Steve Blocka7e24c12009-10-30 11:49:00 +00001439 script->set_type(Smi::FromInt(Script::TYPE_NATIVE));
Steve Block44f0eee2011-05-26 01:26:41 +01001440 heap->public_set_empty_script(*script);
Steve Blocka7e24c12009-10-30 11:49:00 +00001441 }
Steve Block6ded16b2010-05-10 14:33:55 +01001442 {
1443 // Builtin function for OpaqueReference -- a JSValue-based object,
1444 // that keeps its field isolated from JavaScript code. It may store
1445 // objects, that JavaScript code may not access.
1446 Handle<JSFunction> opaque_reference_fun =
1447 InstallFunction(builtins, "OpaqueReference", JS_VALUE_TYPE,
Steve Block44f0eee2011-05-26 01:26:41 +01001448 JSValue::kSize,
1449 isolate->initial_object_prototype(),
1450 Builtins::kIllegal, false);
Steve Block6ded16b2010-05-10 14:33:55 +01001451 Handle<JSObject> prototype =
Steve Block44f0eee2011-05-26 01:26:41 +01001452 factory->NewJSObject(isolate->object_function(), TENURED);
Steve Block6ded16b2010-05-10 14:33:55 +01001453 SetPrototype(opaque_reference_fun, prototype);
1454 global_context()->set_opaque_reference_function(*opaque_reference_fun);
1455 }
1456
Ben Murdoche0cee9b2011-05-25 10:26:03 +01001457 { // --- I n t e r n a l A r r a y ---
1458 // An array constructor on the builtins object that works like
1459 // the public Array constructor, except that its prototype
1460 // doesn't inherit from Object.prototype.
1461 // To be used only for internal work by builtins. Instances
1462 // must not be leaked to user code.
1463 // Only works correctly when called as a constructor. The normal
1464 // Array code uses Array.prototype as prototype when called as
1465 // a function.
1466 Handle<JSFunction> array_function =
1467 InstallFunction(builtins,
1468 "InternalArray",
1469 JS_ARRAY_TYPE,
1470 JSArray::kSize,
Steve Block44f0eee2011-05-26 01:26:41 +01001471 isolate->initial_object_prototype(),
1472 Builtins::kArrayCode,
Ben Murdoche0cee9b2011-05-25 10:26:03 +01001473 true);
1474 Handle<JSObject> prototype =
Steve Block44f0eee2011-05-26 01:26:41 +01001475 factory->NewJSObject(isolate->object_function(), TENURED);
Ben Murdoche0cee9b2011-05-25 10:26:03 +01001476 SetPrototype(array_function, prototype);
1477
1478 array_function->shared()->set_construct_stub(
Steve Block44f0eee2011-05-26 01:26:41 +01001479 isolate->builtins()->builtin(Builtins::kArrayConstructCode));
Ben Murdoche0cee9b2011-05-25 10:26:03 +01001480 array_function->shared()->DontAdaptArguments();
1481
1482 // Make "length" magic on instances.
1483 Handle<DescriptorArray> array_descriptors =
Steve Block44f0eee2011-05-26 01:26:41 +01001484 factory->CopyAppendProxyDescriptor(
1485 factory->empty_descriptor_array(),
1486 factory->length_symbol(),
1487 factory->NewProxy(&Accessors::ArrayLength),
Ben Murdoche0cee9b2011-05-25 10:26:03 +01001488 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE));
1489
1490 array_function->initial_map()->set_instance_descriptors(
1491 *array_descriptors);
1492 }
1493
Steve Block6ded16b2010-05-10 14:33:55 +01001494 if (FLAG_disable_native_files) {
1495 PrintF("Warning: Running without installed natives!\n");
1496 return true;
1497 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001498
Andrei Popescu31002712010-02-23 13:46:05 +00001499 // Install natives.
1500 for (int i = Natives::GetDebuggerCount();
1501 i < Natives::GetBuiltinsCount();
1502 i++) {
1503 Vector<const char> name = Natives::GetScriptName(i);
1504 if (!CompileBuiltin(i)) return false;
Andrei Popescu402d9372010-02-26 13:31:12 +00001505 // TODO(ager): We really only need to install the JS builtin
1506 // functions on the builtins object after compiling and running
1507 // runtime.js.
1508 if (!InstallJSBuiltins(builtins)) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00001509 }
1510
1511 InstallNativeFunctions();
1512
Iain Merrick75681382010-08-19 15:07:18 +01001513 // Store the map for the string prototype after the natives has been compiled
1514 // and the String function has been setup.
1515 Handle<JSFunction> string_function(global_context()->string_function());
1516 ASSERT(JSObject::cast(
1517 string_function->initial_map()->prototype())->HasFastProperties());
1518 global_context()->set_string_function_prototype_map(
1519 HeapObject::cast(string_function->initial_map()->prototype())->map());
1520
Ben Murdochb0fe1622011-05-05 13:52:32 +01001521 InstallBuiltinFunctionIds();
Kristian Monsen25f61362010-05-21 11:50:48 +01001522
Steve Blocka7e24c12009-10-30 11:49:00 +00001523 // Install Function.prototype.call and apply.
Steve Block44f0eee2011-05-26 01:26:41 +01001524 { Handle<String> key = factory->function_class_symbol();
Steve Blocka7e24c12009-10-30 11:49:00 +00001525 Handle<JSFunction> function =
Steve Block44f0eee2011-05-26 01:26:41 +01001526 Handle<JSFunction>::cast(GetProperty(isolate->global(), key));
Steve Blocka7e24c12009-10-30 11:49:00 +00001527 Handle<JSObject> proto =
1528 Handle<JSObject>(JSObject::cast(function->instance_prototype()));
1529
1530 // Install the call and the apply functions.
1531 Handle<JSFunction> call =
1532 InstallFunction(proto, "call", JS_OBJECT_TYPE, JSObject::kHeaderSize,
Steve Block6ded16b2010-05-10 14:33:55 +01001533 Handle<JSObject>::null(),
Steve Block44f0eee2011-05-26 01:26:41 +01001534 Builtins::kFunctionCall,
Steve Blocka7e24c12009-10-30 11:49:00 +00001535 false);
1536 Handle<JSFunction> apply =
1537 InstallFunction(proto, "apply", JS_OBJECT_TYPE, JSObject::kHeaderSize,
Steve Block6ded16b2010-05-10 14:33:55 +01001538 Handle<JSObject>::null(),
Steve Block44f0eee2011-05-26 01:26:41 +01001539 Builtins::kFunctionApply,
Steve Blocka7e24c12009-10-30 11:49:00 +00001540 false);
1541
1542 // Make sure that Function.prototype.call appears to be compiled.
1543 // The code will never be called, but inline caching for call will
1544 // only work if it appears to be compiled.
1545 call->shared()->DontAdaptArguments();
1546 ASSERT(call->is_compiled());
1547
1548 // Set the expected parameters for apply to 2; required by builtin.
1549 apply->shared()->set_formal_parameter_count(2);
1550
1551 // Set the lengths for the functions to satisfy ECMA-262.
1552 call->shared()->set_length(1);
1553 apply->shared()->set_length(2);
1554 }
1555
Steve Block6ded16b2010-05-10 14:33:55 +01001556 // Create a constructor for RegExp results (a variant of Array that
1557 // predefines the two properties index and match).
1558 {
1559 // RegExpResult initial map.
1560
1561 // Find global.Array.prototype to inherit from.
1562 Handle<JSFunction> array_constructor(global_context()->array_function());
1563 Handle<JSObject> array_prototype(
1564 JSObject::cast(array_constructor->instance_prototype()));
1565
1566 // Add initial map.
1567 Handle<Map> initial_map =
Steve Block44f0eee2011-05-26 01:26:41 +01001568 factory->NewMap(JS_ARRAY_TYPE, JSRegExpResult::kSize);
Steve Block6ded16b2010-05-10 14:33:55 +01001569 initial_map->set_constructor(*array_constructor);
1570
1571 // Set prototype on map.
1572 initial_map->set_non_instance_prototype(false);
1573 initial_map->set_prototype(*array_prototype);
1574
1575 // Update map with length accessor from Array and add "index" and "input".
1576 Handle<Map> array_map(global_context()->js_array_map());
1577 Handle<DescriptorArray> array_descriptors(
1578 array_map->instance_descriptors());
1579 ASSERT_EQ(1, array_descriptors->number_of_descriptors());
1580
1581 Handle<DescriptorArray> reresult_descriptors =
Steve Block44f0eee2011-05-26 01:26:41 +01001582 factory->NewDescriptorArray(3);
Steve Block6ded16b2010-05-10 14:33:55 +01001583
1584 reresult_descriptors->CopyFrom(0, *array_descriptors, 0);
1585
1586 int enum_index = 0;
1587 {
Steve Block44f0eee2011-05-26 01:26:41 +01001588 FieldDescriptor index_field(heap->index_symbol(),
Steve Block6ded16b2010-05-10 14:33:55 +01001589 JSRegExpResult::kIndexIndex,
1590 NONE,
1591 enum_index++);
1592 reresult_descriptors->Set(1, &index_field);
1593 }
1594
1595 {
Steve Block44f0eee2011-05-26 01:26:41 +01001596 FieldDescriptor input_field(heap->input_symbol(),
Steve Block6ded16b2010-05-10 14:33:55 +01001597 JSRegExpResult::kInputIndex,
1598 NONE,
1599 enum_index++);
1600 reresult_descriptors->Set(2, &input_field);
1601 }
1602 reresult_descriptors->Sort();
1603
1604 initial_map->set_inobject_properties(2);
1605 initial_map->set_pre_allocated_property_fields(2);
1606 initial_map->set_unused_property_fields(0);
1607 initial_map->set_instance_descriptors(*reresult_descriptors);
1608
1609 global_context()->set_regexp_result_map(*initial_map);
1610 }
1611
Ben Murdoche0cee9b2011-05-25 10:26:03 +01001612
Steve Blocka7e24c12009-10-30 11:49:00 +00001613#ifdef DEBUG
1614 builtins->Verify();
1615#endif
Andrei Popescu31002712010-02-23 13:46:05 +00001616
Steve Blocka7e24c12009-10-30 11:49:00 +00001617 return true;
1618}
1619
1620
Ben Murdochb0fe1622011-05-05 13:52:32 +01001621static Handle<JSObject> ResolveBuiltinIdHolder(
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001622 Handle<Context> global_context,
1623 const char* holder_expr) {
Steve Block44f0eee2011-05-26 01:26:41 +01001624 Factory* factory = Isolate::Current()->factory();
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001625 Handle<GlobalObject> global(global_context->global());
1626 const char* period_pos = strchr(holder_expr, '.');
1627 if (period_pos == NULL) {
1628 return Handle<JSObject>::cast(
Steve Block44f0eee2011-05-26 01:26:41 +01001629 GetProperty(global, factory->LookupAsciiSymbol(holder_expr)));
Steve Block59151502010-09-22 15:07:15 +01001630 }
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001631 ASSERT_EQ(".prototype", period_pos);
1632 Vector<const char> property(holder_expr,
1633 static_cast<int>(period_pos - holder_expr));
1634 Handle<JSFunction> function = Handle<JSFunction>::cast(
Steve Block44f0eee2011-05-26 01:26:41 +01001635 GetProperty(global, factory->LookupSymbol(property)));
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001636 return Handle<JSObject>(JSObject::cast(function->prototype()));
1637}
1638
1639
Ben Murdochb0fe1622011-05-05 13:52:32 +01001640static void InstallBuiltinFunctionId(Handle<JSObject> holder,
1641 const char* function_name,
1642 BuiltinFunctionId id) {
Steve Block44f0eee2011-05-26 01:26:41 +01001643 Handle<String> name = FACTORY->LookupAsciiSymbol(function_name);
John Reck59135872010-11-02 12:39:01 -07001644 Object* function_object = holder->GetProperty(*name)->ToObjectUnchecked();
1645 Handle<JSFunction> function(JSFunction::cast(function_object));
Kristian Monsen25f61362010-05-21 11:50:48 +01001646 function->shared()->set_function_data(Smi::FromInt(id));
1647}
1648
1649
Ben Murdochb0fe1622011-05-05 13:52:32 +01001650void Genesis::InstallBuiltinFunctionIds() {
Kristian Monsen25f61362010-05-21 11:50:48 +01001651 HandleScope scope;
Ben Murdochb0fe1622011-05-05 13:52:32 +01001652#define INSTALL_BUILTIN_ID(holder_expr, fun_name, name) \
1653 { \
1654 Handle<JSObject> holder = ResolveBuiltinIdHolder( \
1655 global_context(), #holder_expr); \
1656 BuiltinFunctionId id = k##name; \
1657 InstallBuiltinFunctionId(holder, #fun_name, id); \
Kristian Monsen25f61362010-05-21 11:50:48 +01001658 }
Ben Murdochb0fe1622011-05-05 13:52:32 +01001659 FUNCTIONS_WITH_ID_LIST(INSTALL_BUILTIN_ID)
1660#undef INSTALL_BUILTIN_ID
Kristian Monsen25f61362010-05-21 11:50:48 +01001661}
1662
1663
Steve Block6ded16b2010-05-10 14:33:55 +01001664// Do not forget to update macros.py with named constant
1665// of cache id.
1666#define JSFUNCTION_RESULT_CACHE_LIST(F) \
1667 F(16, global_context()->regexp_function())
1668
1669
1670static FixedArray* CreateCache(int size, JSFunction* factory) {
1671 // Caches are supposed to live for a long time, allocate in old space.
1672 int array_size = JSFunctionResultCache::kEntriesIndex + 2 * size;
1673 // Cannot use cast as object is not fully initialized yet.
1674 JSFunctionResultCache* cache = reinterpret_cast<JSFunctionResultCache*>(
Steve Block44f0eee2011-05-26 01:26:41 +01001675 *FACTORY->NewFixedArrayWithHoles(array_size, TENURED));
Steve Block6ded16b2010-05-10 14:33:55 +01001676 cache->set(JSFunctionResultCache::kFactoryIndex, factory);
1677 cache->MakeZeroSize();
1678 return cache;
1679}
1680
1681
1682void Genesis::InstallJSFunctionResultCaches() {
1683 const int kNumberOfCaches = 0 +
1684#define F(size, func) + 1
1685 JSFUNCTION_RESULT_CACHE_LIST(F)
1686#undef F
1687 ;
1688
Steve Block44f0eee2011-05-26 01:26:41 +01001689 Handle<FixedArray> caches = FACTORY->NewFixedArray(kNumberOfCaches, TENURED);
Steve Block6ded16b2010-05-10 14:33:55 +01001690
1691 int index = 0;
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001692
1693#define F(size, func) do { \
1694 FixedArray* cache = CreateCache((size), (func)); \
1695 caches->set(index++, cache); \
1696 } while (false)
1697
1698 JSFUNCTION_RESULT_CACHE_LIST(F);
1699
Steve Block6ded16b2010-05-10 14:33:55 +01001700#undef F
1701
1702 global_context()->set_jsfunction_result_caches(*caches);
1703}
1704
1705
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001706void Genesis::InitializeNormalizedMapCaches() {
1707 Handle<FixedArray> array(
Steve Block44f0eee2011-05-26 01:26:41 +01001708 FACTORY->NewFixedArray(NormalizedMapCache::kEntries, TENURED));
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001709 global_context()->set_normalized_map_cache(NormalizedMapCache::cast(*array));
1710}
1711
1712
Andrei Popescu31002712010-02-23 13:46:05 +00001713bool Bootstrapper::InstallExtensions(Handle<Context> global_context,
1714 v8::ExtensionConfiguration* extensions) {
Steve Block44f0eee2011-05-26 01:26:41 +01001715 Isolate* isolate = Isolate::Current();
Andrei Popescu31002712010-02-23 13:46:05 +00001716 BootstrapperActive active;
Steve Block44f0eee2011-05-26 01:26:41 +01001717 SaveContext saved_context(isolate);
1718 isolate->set_context(*global_context);
Andrei Popescu31002712010-02-23 13:46:05 +00001719 if (!Genesis::InstallExtensions(global_context, extensions)) return false;
1720 Genesis::InstallSpecialObjects(global_context);
1721 return true;
1722}
1723
1724
1725void Genesis::InstallSpecialObjects(Handle<Context> global_context) {
Steve Block44f0eee2011-05-26 01:26:41 +01001726 Factory* factory = Isolate::Current()->factory();
Steve Blocka7e24c12009-10-30 11:49:00 +00001727 HandleScope scope;
1728 Handle<JSGlobalObject> js_global(
Andrei Popescu31002712010-02-23 13:46:05 +00001729 JSGlobalObject::cast(global_context->global()));
Steve Blocka7e24c12009-10-30 11:49:00 +00001730 // Expose the natives in global if a name for it is specified.
1731 if (FLAG_expose_natives_as != NULL && strlen(FLAG_expose_natives_as) != 0) {
1732 Handle<String> natives_string =
Steve Block44f0eee2011-05-26 01:26:41 +01001733 factory->LookupAsciiSymbol(FLAG_expose_natives_as);
Steve Block1e0659c2011-05-24 12:43:12 +01001734 SetLocalPropertyNoThrow(js_global, natives_string,
1735 Handle<JSObject>(js_global->builtins()), DONT_ENUM);
Steve Blocka7e24c12009-10-30 11:49:00 +00001736 }
1737
1738 Handle<Object> Error = GetProperty(js_global, "Error");
1739 if (Error->IsJSObject()) {
Steve Block44f0eee2011-05-26 01:26:41 +01001740 Handle<String> name = factory->LookupAsciiSymbol("stackTraceLimit");
Steve Block1e0659c2011-05-24 12:43:12 +01001741 SetLocalPropertyNoThrow(Handle<JSObject>::cast(Error),
1742 name,
1743 Handle<Smi>(Smi::FromInt(FLAG_stack_trace_limit)),
1744 NONE);
Steve Blocka7e24c12009-10-30 11:49:00 +00001745 }
1746
1747#ifdef ENABLE_DEBUGGER_SUPPORT
1748 // Expose the debug global object in global if a name for it is specified.
1749 if (FLAG_expose_debug_as != NULL && strlen(FLAG_expose_debug_as) != 0) {
Steve Block44f0eee2011-05-26 01:26:41 +01001750 Debug* debug = Isolate::Current()->debug();
Steve Blocka7e24c12009-10-30 11:49:00 +00001751 // If loading fails we just bail out without installing the
1752 // debugger but without tanking the whole context.
Steve Block44f0eee2011-05-26 01:26:41 +01001753 if (!debug->Load()) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00001754 // Set the security token for the debugger context to the same as
1755 // the shell global context to allow calling between these (otherwise
1756 // exposing debug global object doesn't make much sense).
Steve Block44f0eee2011-05-26 01:26:41 +01001757 debug->debug_context()->set_security_token(
Andrei Popescu31002712010-02-23 13:46:05 +00001758 global_context->security_token());
Steve Blocka7e24c12009-10-30 11:49:00 +00001759
1760 Handle<String> debug_string =
Steve Block44f0eee2011-05-26 01:26:41 +01001761 factory->LookupAsciiSymbol(FLAG_expose_debug_as);
1762 Handle<Object> global_proxy(debug->debug_context()->global_proxy());
Steve Block1e0659c2011-05-24 12:43:12 +01001763 SetLocalPropertyNoThrow(js_global, debug_string, global_proxy, DONT_ENUM);
Steve Blocka7e24c12009-10-30 11:49:00 +00001764 }
1765#endif
Steve Blocka7e24c12009-10-30 11:49:00 +00001766}
1767
1768
Andrei Popescu31002712010-02-23 13:46:05 +00001769bool Genesis::InstallExtensions(Handle<Context> global_context,
1770 v8::ExtensionConfiguration* extensions) {
Steve Block44f0eee2011-05-26 01:26:41 +01001771 // TODO(isolates): Extensions on multiple isolates may take a little more
1772 // effort. (The external API reads 'ignore'-- does that mean
1773 // we can break the interface?)
1774
Steve Blocka7e24c12009-10-30 11:49:00 +00001775 // Clear coloring of extension list
1776 v8::RegisteredExtension* current = v8::RegisteredExtension::first_extension();
1777 while (current != NULL) {
1778 current->set_state(v8::UNVISITED);
1779 current = current->next();
1780 }
Andrei Popescu31002712010-02-23 13:46:05 +00001781 // Install auto extensions.
Steve Blocka7e24c12009-10-30 11:49:00 +00001782 current = v8::RegisteredExtension::first_extension();
1783 while (current != NULL) {
1784 if (current->extension()->auto_enable())
1785 InstallExtension(current);
1786 current = current->next();
1787 }
1788
1789 if (FLAG_expose_gc) InstallExtension("v8/gc");
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01001790 if (FLAG_expose_externalize_string) InstallExtension("v8/externalize");
Steve Blocka7e24c12009-10-30 11:49:00 +00001791
1792 if (extensions == NULL) return true;
1793 // Install required extensions
1794 int count = v8::ImplementationUtilities::GetNameCount(extensions);
1795 const char** names = v8::ImplementationUtilities::GetNames(extensions);
1796 for (int i = 0; i < count; i++) {
1797 if (!InstallExtension(names[i]))
1798 return false;
1799 }
1800
1801 return true;
1802}
1803
1804
1805// Installs a named extension. This methods is unoptimized and does
1806// not scale well if we want to support a large number of extensions.
1807bool Genesis::InstallExtension(const char* name) {
1808 v8::RegisteredExtension* current = v8::RegisteredExtension::first_extension();
1809 // Loop until we find the relevant extension
1810 while (current != NULL) {
1811 if (strcmp(name, current->extension()->name()) == 0) break;
1812 current = current->next();
1813 }
1814 // Didn't find the extension; fail.
1815 if (current == NULL) {
1816 v8::Utils::ReportApiFailure(
1817 "v8::Context::New()", "Cannot find required extension");
1818 return false;
1819 }
1820 return InstallExtension(current);
1821}
1822
1823
1824bool Genesis::InstallExtension(v8::RegisteredExtension* current) {
1825 HandleScope scope;
1826
1827 if (current->state() == v8::INSTALLED) return true;
1828 // The current node has already been visited so there must be a
1829 // cycle in the dependency graph; fail.
1830 if (current->state() == v8::VISITED) {
1831 v8::Utils::ReportApiFailure(
1832 "v8::Context::New()", "Circular extension dependency");
1833 return false;
1834 }
1835 ASSERT(current->state() == v8::UNVISITED);
1836 current->set_state(v8::VISITED);
1837 v8::Extension* extension = current->extension();
1838 // Install the extension's dependencies
1839 for (int i = 0; i < extension->dependency_count(); i++) {
1840 if (!InstallExtension(extension->dependencies()[i])) return false;
1841 }
Steve Block44f0eee2011-05-26 01:26:41 +01001842 Isolate* isolate = Isolate::Current();
Steve Blocka7e24c12009-10-30 11:49:00 +00001843 Vector<const char> source = CStrVector(extension->source());
Steve Block44f0eee2011-05-26 01:26:41 +01001844 Handle<String> source_code = isolate->factory()->NewStringFromAscii(source);
Steve Blocka7e24c12009-10-30 11:49:00 +00001845 bool result = CompileScriptCached(CStrVector(extension->name()),
1846 source_code,
Steve Block44f0eee2011-05-26 01:26:41 +01001847 isolate->bootstrapper()->extensions_cache(),
Andrei Popescu31002712010-02-23 13:46:05 +00001848 extension,
Steve Block44f0eee2011-05-26 01:26:41 +01001849 Handle<Context>(isolate->context()),
Steve Blocka7e24c12009-10-30 11:49:00 +00001850 false);
Steve Block44f0eee2011-05-26 01:26:41 +01001851 ASSERT(isolate->has_pending_exception() != result);
Steve Blocka7e24c12009-10-30 11:49:00 +00001852 if (!result) {
Steve Block44f0eee2011-05-26 01:26:41 +01001853 isolate->clear_pending_exception();
Steve Blocka7e24c12009-10-30 11:49:00 +00001854 }
1855 current->set_state(v8::INSTALLED);
1856 return result;
1857}
1858
1859
Andrei Popescu402d9372010-02-26 13:31:12 +00001860bool Genesis::InstallJSBuiltins(Handle<JSBuiltinsObject> builtins) {
1861 HandleScope scope;
1862 for (int i = 0; i < Builtins::NumberOfJavaScriptBuiltins(); i++) {
1863 Builtins::JavaScript id = static_cast<Builtins::JavaScript>(i);
Steve Block44f0eee2011-05-26 01:26:41 +01001864 Handle<String> name = FACTORY->LookupAsciiSymbol(Builtins::GetName(id));
John Reck59135872010-11-02 12:39:01 -07001865 Object* function_object = builtins->GetPropertyNoExceptionThrown(*name);
Andrei Popescu402d9372010-02-26 13:31:12 +00001866 Handle<JSFunction> function
John Reck59135872010-11-02 12:39:01 -07001867 = Handle<JSFunction>(JSFunction::cast(function_object));
Andrei Popescu402d9372010-02-26 13:31:12 +00001868 builtins->set_javascript_builtin(id, *function);
1869 Handle<SharedFunctionInfo> shared
1870 = Handle<SharedFunctionInfo>(function->shared());
1871 if (!EnsureCompiled(shared, CLEAR_EXCEPTION)) return false;
Iain Merrick75681382010-08-19 15:07:18 +01001872 // Set the code object on the function object.
Ben Murdochb0fe1622011-05-05 13:52:32 +01001873 function->ReplaceCode(function->shared()->code());
Steve Block6ded16b2010-05-10 14:33:55 +01001874 builtins->set_javascript_builtin_code(id, shared->code());
Andrei Popescu402d9372010-02-26 13:31:12 +00001875 }
1876 return true;
Andrei Popescu31002712010-02-23 13:46:05 +00001877}
1878
1879
Steve Blocka7e24c12009-10-30 11:49:00 +00001880bool Genesis::ConfigureGlobalObjects(
1881 v8::Handle<v8::ObjectTemplate> global_proxy_template) {
1882 Handle<JSObject> global_proxy(
1883 JSObject::cast(global_context()->global_proxy()));
Andrei Popescu402d9372010-02-26 13:31:12 +00001884 Handle<JSObject> inner_global(JSObject::cast(global_context()->global()));
Steve Blocka7e24c12009-10-30 11:49:00 +00001885
1886 if (!global_proxy_template.IsEmpty()) {
1887 // Configure the global proxy object.
1888 Handle<ObjectTemplateInfo> proxy_data =
1889 v8::Utils::OpenHandle(*global_proxy_template);
1890 if (!ConfigureApiObject(global_proxy, proxy_data)) return false;
1891
1892 // Configure the inner global object.
1893 Handle<FunctionTemplateInfo> proxy_constructor(
1894 FunctionTemplateInfo::cast(proxy_data->constructor()));
1895 if (!proxy_constructor->prototype_template()->IsUndefined()) {
1896 Handle<ObjectTemplateInfo> inner_data(
1897 ObjectTemplateInfo::cast(proxy_constructor->prototype_template()));
Andrei Popescu402d9372010-02-26 13:31:12 +00001898 if (!ConfigureApiObject(inner_global, inner_data)) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00001899 }
1900 }
1901
Andrei Popescu402d9372010-02-26 13:31:12 +00001902 SetObjectPrototype(global_proxy, inner_global);
Steve Blocka7e24c12009-10-30 11:49:00 +00001903 return true;
1904}
1905
1906
1907bool Genesis::ConfigureApiObject(Handle<JSObject> object,
1908 Handle<ObjectTemplateInfo> object_template) {
1909 ASSERT(!object_template.is_null());
1910 ASSERT(object->IsInstanceOf(
1911 FunctionTemplateInfo::cast(object_template->constructor())));
1912
Steve Block44f0eee2011-05-26 01:26:41 +01001913 Isolate* isolate = Isolate::Current();
Steve Blocka7e24c12009-10-30 11:49:00 +00001914 bool pending_exception = false;
1915 Handle<JSObject> obj =
1916 Execution::InstantiateObject(object_template, &pending_exception);
1917 if (pending_exception) {
Steve Block44f0eee2011-05-26 01:26:41 +01001918 ASSERT(isolate->has_pending_exception());
1919 isolate->clear_pending_exception();
Steve Blocka7e24c12009-10-30 11:49:00 +00001920 return false;
1921 }
1922 TransferObject(obj, object);
1923 return true;
1924}
1925
1926
1927void Genesis::TransferNamedProperties(Handle<JSObject> from,
1928 Handle<JSObject> to) {
1929 if (from->HasFastProperties()) {
1930 Handle<DescriptorArray> descs =
1931 Handle<DescriptorArray>(from->map()->instance_descriptors());
1932 for (int i = 0; i < descs->number_of_descriptors(); i++) {
1933 PropertyDetails details = PropertyDetails(descs->GetDetails(i));
1934 switch (details.type()) {
1935 case FIELD: {
1936 HandleScope inner;
1937 Handle<String> key = Handle<String>(descs->GetKey(i));
1938 int index = descs->GetFieldIndex(i);
1939 Handle<Object> value = Handle<Object>(from->FastPropertyAt(index));
Steve Block1e0659c2011-05-24 12:43:12 +01001940 SetLocalPropertyNoThrow(to, key, value, details.attributes());
Steve Blocka7e24c12009-10-30 11:49:00 +00001941 break;
1942 }
1943 case CONSTANT_FUNCTION: {
1944 HandleScope inner;
1945 Handle<String> key = Handle<String>(descs->GetKey(i));
1946 Handle<JSFunction> fun =
1947 Handle<JSFunction>(descs->GetConstantFunction(i));
Steve Block1e0659c2011-05-24 12:43:12 +01001948 SetLocalPropertyNoThrow(to, key, fun, details.attributes());
Steve Blocka7e24c12009-10-30 11:49:00 +00001949 break;
1950 }
1951 case CALLBACKS: {
1952 LookupResult result;
1953 to->LocalLookup(descs->GetKey(i), &result);
1954 // If the property is already there we skip it
Andrei Popescu402d9372010-02-26 13:31:12 +00001955 if (result.IsProperty()) continue;
Steve Blocka7e24c12009-10-30 11:49:00 +00001956 HandleScope inner;
Andrei Popescu31002712010-02-23 13:46:05 +00001957 ASSERT(!to->HasFastProperties());
1958 // Add to dictionary.
Steve Blocka7e24c12009-10-30 11:49:00 +00001959 Handle<String> key = Handle<String>(descs->GetKey(i));
Andrei Popescu31002712010-02-23 13:46:05 +00001960 Handle<Object> callbacks(descs->GetCallbacksObject(i));
1961 PropertyDetails d =
1962 PropertyDetails(details.attributes(), CALLBACKS, details.index());
1963 SetNormalizedProperty(to, key, callbacks, d);
Steve Blocka7e24c12009-10-30 11:49:00 +00001964 break;
1965 }
1966 case MAP_TRANSITION:
Steve Block44f0eee2011-05-26 01:26:41 +01001967 case EXTERNAL_ARRAY_TRANSITION:
Steve Blocka7e24c12009-10-30 11:49:00 +00001968 case CONSTANT_TRANSITION:
1969 case NULL_DESCRIPTOR:
1970 // Ignore non-properties.
1971 break;
1972 case NORMAL:
1973 // Do not occur since the from object has fast properties.
1974 case INTERCEPTOR:
1975 // No element in instance descriptors have interceptor type.
1976 UNREACHABLE();
1977 break;
1978 }
1979 }
1980 } else {
1981 Handle<StringDictionary> properties =
1982 Handle<StringDictionary>(from->property_dictionary());
1983 int capacity = properties->Capacity();
1984 for (int i = 0; i < capacity; i++) {
1985 Object* raw_key(properties->KeyAt(i));
1986 if (properties->IsKey(raw_key)) {
1987 ASSERT(raw_key->IsString());
1988 // If the property is already there we skip it.
1989 LookupResult result;
1990 to->LocalLookup(String::cast(raw_key), &result);
Andrei Popescu402d9372010-02-26 13:31:12 +00001991 if (result.IsProperty()) continue;
Steve Blocka7e24c12009-10-30 11:49:00 +00001992 // Set the property.
1993 Handle<String> key = Handle<String>(String::cast(raw_key));
1994 Handle<Object> value = Handle<Object>(properties->ValueAt(i));
1995 if (value->IsJSGlobalPropertyCell()) {
1996 value = Handle<Object>(JSGlobalPropertyCell::cast(*value)->value());
1997 }
1998 PropertyDetails details = properties->DetailsAt(i);
Steve Block1e0659c2011-05-24 12:43:12 +01001999 SetLocalPropertyNoThrow(to, key, value, details.attributes());
Steve Blocka7e24c12009-10-30 11:49:00 +00002000 }
2001 }
2002 }
2003}
2004
2005
2006void Genesis::TransferIndexedProperties(Handle<JSObject> from,
2007 Handle<JSObject> to) {
2008 // Cloning the elements array is sufficient.
2009 Handle<FixedArray> from_elements =
2010 Handle<FixedArray>(FixedArray::cast(from->elements()));
Steve Block44f0eee2011-05-26 01:26:41 +01002011 Handle<FixedArray> to_elements = FACTORY->CopyFixedArray(from_elements);
Steve Blocka7e24c12009-10-30 11:49:00 +00002012 to->set_elements(*to_elements);
2013}
2014
2015
2016void Genesis::TransferObject(Handle<JSObject> from, Handle<JSObject> to) {
2017 HandleScope outer;
2018
2019 ASSERT(!from->IsJSArray());
2020 ASSERT(!to->IsJSArray());
2021
2022 TransferNamedProperties(from, to);
2023 TransferIndexedProperties(from, to);
2024
2025 // Transfer the prototype (new map is needed).
2026 Handle<Map> old_to_map = Handle<Map>(to->map());
Steve Block44f0eee2011-05-26 01:26:41 +01002027 Handle<Map> new_to_map = FACTORY->CopyMapDropTransitions(old_to_map);
Steve Blocka7e24c12009-10-30 11:49:00 +00002028 new_to_map->set_prototype(from->map()->prototype());
2029 to->set_map(*new_to_map);
2030}
2031
2032
2033void Genesis::MakeFunctionInstancePrototypeWritable() {
Steve Block44f0eee2011-05-26 01:26:41 +01002034 // The maps with writable prototype are created in CreateEmptyFunction
2035 // and CreateStrictModeFunctionMaps respectively. Initially the maps are
2036 // created with read-only prototype for JS builtins processing.
2037 ASSERT(!function_instance_map_writable_prototype_.is_null());
2038 ASSERT(!strict_mode_function_instance_map_writable_prototype_.is_null());
Steve Blocka7e24c12009-10-30 11:49:00 +00002039
Steve Block44f0eee2011-05-26 01:26:41 +01002040 // Replace function instance maps to make prototype writable.
2041 global_context()->set_function_map(
2042 *function_instance_map_writable_prototype_);
2043 global_context()->set_strict_mode_function_map(
2044 *strict_mode_function_instance_map_writable_prototype_);
Steve Blocka7e24c12009-10-30 11:49:00 +00002045}
2046
2047
Steve Blocka7e24c12009-10-30 11:49:00 +00002048Genesis::Genesis(Handle<Object> global_object,
2049 v8::Handle<v8::ObjectTemplate> global_template,
2050 v8::ExtensionConfiguration* extensions) {
Steve Block44f0eee2011-05-26 01:26:41 +01002051 Isolate* isolate = Isolate::Current();
Steve Blocka7e24c12009-10-30 11:49:00 +00002052 result_ = Handle<Context>::null();
Steve Blocka7e24c12009-10-30 11:49:00 +00002053 // If V8 isn't running and cannot be initialized, just return.
2054 if (!V8::IsRunning() && !V8::Initialize(NULL)) return;
2055
2056 // Before creating the roots we must save the context and restore it
2057 // on all function exits.
2058 HandleScope scope;
Steve Block44f0eee2011-05-26 01:26:41 +01002059 SaveContext saved_context(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002060
Andrei Popescu31002712010-02-23 13:46:05 +00002061 Handle<Context> new_context = Snapshot::NewContextFromSnapshot();
2062 if (!new_context.is_null()) {
2063 global_context_ =
Steve Block44f0eee2011-05-26 01:26:41 +01002064 Handle<Context>::cast(isolate->global_handles()->Create(*new_context));
Ben Murdochb0fe1622011-05-05 13:52:32 +01002065 AddToWeakGlobalContextList(*global_context_);
Steve Block44f0eee2011-05-26 01:26:41 +01002066 isolate->set_context(*global_context_);
2067 isolate->counters()->contexts_created_by_snapshot()->Increment();
Andrei Popescu402d9372010-02-26 13:31:12 +00002068 Handle<GlobalObject> inner_global;
Andrei Popescu31002712010-02-23 13:46:05 +00002069 Handle<JSGlobalProxy> global_proxy =
2070 CreateNewGlobals(global_template,
2071 global_object,
Andrei Popescu402d9372010-02-26 13:31:12 +00002072 &inner_global);
2073
Andrei Popescu31002712010-02-23 13:46:05 +00002074 HookUpGlobalProxy(inner_global, global_proxy);
Andrei Popescu402d9372010-02-26 13:31:12 +00002075 HookUpInnerGlobal(inner_global);
2076
Andrei Popescu31002712010-02-23 13:46:05 +00002077 if (!ConfigureGlobalObjects(global_template)) return;
2078 } else {
2079 // We get here if there was no context snapshot.
2080 CreateRoots();
2081 Handle<JSFunction> empty_function = CreateEmptyFunction();
Steve Block44f0eee2011-05-26 01:26:41 +01002082 CreateStrictModeFunctionMaps(empty_function);
Andrei Popescu31002712010-02-23 13:46:05 +00002083 Handle<GlobalObject> inner_global;
2084 Handle<JSGlobalProxy> global_proxy =
2085 CreateNewGlobals(global_template, global_object, &inner_global);
2086 HookUpGlobalProxy(inner_global, global_proxy);
2087 InitializeGlobal(inner_global, empty_function);
Steve Block6ded16b2010-05-10 14:33:55 +01002088 InstallJSFunctionResultCaches();
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002089 InitializeNormalizedMapCaches();
Kristian Monsen25f61362010-05-21 11:50:48 +01002090 if (!InstallNatives()) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00002091
Andrei Popescu31002712010-02-23 13:46:05 +00002092 MakeFunctionInstancePrototypeWritable();
Steve Blocka7e24c12009-10-30 11:49:00 +00002093
Andrei Popescu31002712010-02-23 13:46:05 +00002094 if (!ConfigureGlobalObjects(global_template)) return;
Steve Block44f0eee2011-05-26 01:26:41 +01002095 isolate->counters()->contexts_created_from_scratch()->Increment();
Andrei Popescu31002712010-02-23 13:46:05 +00002096 }
Steve Blocka7e24c12009-10-30 11:49:00 +00002097
2098 result_ = global_context_;
2099}
2100
2101
2102// Support for thread preemption.
2103
2104// Reserve space for statics needing saving and restoring.
2105int Bootstrapper::ArchiveSpacePerThread() {
Steve Block44f0eee2011-05-26 01:26:41 +01002106 return sizeof(NestingCounterType);
Steve Blocka7e24c12009-10-30 11:49:00 +00002107}
2108
2109
2110// Archive statics that are thread local.
2111char* Bootstrapper::ArchiveState(char* to) {
Steve Block44f0eee2011-05-26 01:26:41 +01002112 *reinterpret_cast<NestingCounterType*>(to) = nesting_;
2113 nesting_ = 0;
2114 return to + sizeof(NestingCounterType);
Steve Blocka7e24c12009-10-30 11:49:00 +00002115}
2116
2117
2118// Restore statics that are thread local.
2119char* Bootstrapper::RestoreState(char* from) {
Steve Block44f0eee2011-05-26 01:26:41 +01002120 nesting_ = *reinterpret_cast<NestingCounterType*>(from);
2121 return from + sizeof(NestingCounterType);
Steve Blocka7e24c12009-10-30 11:49:00 +00002122}
2123
2124
2125// Called when the top-level V8 mutex is destroyed.
2126void Bootstrapper::FreeThreadResources() {
Steve Block44f0eee2011-05-26 01:26:41 +01002127 ASSERT(!IsActive());
Steve Blocka7e24c12009-10-30 11:49:00 +00002128}
2129
2130} } // namespace v8::internal