blob: 29c16ee936fb6c3cc29f69c6fd8ac0ef1fecc102 [file] [log] [blame]
Ben Murdoch257744e2011-11-30 15:57:28 +00001// Copyright 2011 the V8 project authors. All rights reserved.
Steve Blocka7e24c12009-10-30 11:49:00 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#include "v8.h"
29
30#include "accessors.h"
31#include "api.h"
32#include "bootstrapper.h"
33#include "compiler.h"
34#include "debug.h"
35#include "execution.h"
36#include "global-handles.h"
Ben Murdoch592a9fc2012-03-05 11:04:45 +000037#include "isolate-inl.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000038#include "macro-assembler.h"
39#include "natives.h"
Iain Merrick75681382010-08-19 15:07:18 +010040#include "objects-visiting.h"
Ben Murdoch592a9fc2012-03-05 11:04:45 +000041#include "platform.h"
Steve Blockd0582a62009-12-15 09:54:21 +000042#include "snapshot.h"
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -080043#include "extensions/externalize-string-extension.h"
44#include "extensions/gc-extension.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000045
46namespace v8 {
47namespace internal {
48
Steve Blocka7e24c12009-10-30 11:49:00 +000049
Steve Block44f0eee2011-05-26 01:26:41 +010050NativesExternalStringResource::NativesExternalStringResource(
51 Bootstrapper* bootstrapper,
Ben Murdoch3fb3ca82011-12-02 17:19:32 +000052 const char* source,
53 size_t length)
54 : data_(source), length_(length) {
Steve Block44f0eee2011-05-26 01:26:41 +010055 if (bootstrapper->delete_these_non_arrays_on_tear_down_ == NULL) {
56 bootstrapper->delete_these_non_arrays_on_tear_down_ = new List<char*>(2);
Steve Blockd0582a62009-12-15 09:54:21 +000057 }
58 // The resources are small objects and we only make a fixed number of
59 // them, but let's clean them up on exit for neatness.
Steve Block44f0eee2011-05-26 01:26:41 +010060 bootstrapper->delete_these_non_arrays_on_tear_down_->
Steve Blockd0582a62009-12-15 09:54:21 +000061 Add(reinterpret_cast<char*>(this));
62}
Steve Blocka7e24c12009-10-30 11:49:00 +000063
64
Steve Block44f0eee2011-05-26 01:26:41 +010065Bootstrapper::Bootstrapper()
66 : nesting_(0),
67 extensions_cache_(Script::TYPE_EXTENSION),
68 delete_these_non_arrays_on_tear_down_(NULL),
69 delete_these_arrays_on_tear_down_(NULL) {
70}
71
72
Steve Blocka7e24c12009-10-30 11:49:00 +000073Handle<String> Bootstrapper::NativesSourceLookup(int index) {
74 ASSERT(0 <= index && index < Natives::GetBuiltinsCount());
Steve Block44f0eee2011-05-26 01:26:41 +010075 Isolate* isolate = Isolate::Current();
76 Factory* factory = isolate->factory();
77 Heap* heap = isolate->heap();
78 if (heap->natives_source_cache()->get(index)->IsUndefined()) {
Steve Blockd0582a62009-12-15 09:54:21 +000079 if (!Snapshot::IsEnabled() || FLAG_new_snapshot) {
80 // We can use external strings for the natives.
Ben Murdoch3fb3ca82011-12-02 17:19:32 +000081 Vector<const char> source = Natives::GetRawScriptSource(index);
Steve Blockd0582a62009-12-15 09:54:21 +000082 NativesExternalStringResource* resource =
Steve Block44f0eee2011-05-26 01:26:41 +010083 new NativesExternalStringResource(this,
Ben Murdoch3fb3ca82011-12-02 17:19:32 +000084 source.start(),
85 source.length());
Steve Blockd0582a62009-12-15 09:54:21 +000086 Handle<String> source_code =
Steve Block44f0eee2011-05-26 01:26:41 +010087 factory->NewExternalStringFromAscii(resource);
88 heap->natives_source_cache()->set(index, *source_code);
Steve Blockd0582a62009-12-15 09:54:21 +000089 } else {
90 // Old snapshot code can't cope with external strings at all.
91 Handle<String> source_code =
Ben Murdoch3fb3ca82011-12-02 17:19:32 +000092 factory->NewStringFromAscii(Natives::GetRawScriptSource(index));
Steve Block44f0eee2011-05-26 01:26:41 +010093 heap->natives_source_cache()->set(index, *source_code);
Steve Blockd0582a62009-12-15 09:54:21 +000094 }
Steve Blocka7e24c12009-10-30 11:49:00 +000095 }
Steve Block44f0eee2011-05-26 01:26:41 +010096 Handle<Object> cached_source(heap->natives_source_cache()->get(index));
Steve Blocka7e24c12009-10-30 11:49:00 +000097 return Handle<String>::cast(cached_source);
98}
99
100
Steve Blocka7e24c12009-10-30 11:49:00 +0000101void Bootstrapper::Initialize(bool create_heap_objects) {
Steve Block44f0eee2011-05-26 01:26:41 +0100102 extensions_cache_.Initialize(create_heap_objects);
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800103 GCExtension::Register();
104 ExternalizeStringExtension::Register();
Steve Blocka7e24c12009-10-30 11:49:00 +0000105}
106
107
Leon Clarkee46be812010-01-19 14:06:41 +0000108char* Bootstrapper::AllocateAutoDeletedArray(int bytes) {
109 char* memory = new char[bytes];
110 if (memory != NULL) {
Steve Block44f0eee2011-05-26 01:26:41 +0100111 if (delete_these_arrays_on_tear_down_ == NULL) {
112 delete_these_arrays_on_tear_down_ = new List<char*>(2);
Leon Clarkee46be812010-01-19 14:06:41 +0000113 }
Steve Block44f0eee2011-05-26 01:26:41 +0100114 delete_these_arrays_on_tear_down_->Add(memory);
Leon Clarkee46be812010-01-19 14:06:41 +0000115 }
116 return memory;
117}
118
119
Steve Blocka7e24c12009-10-30 11:49:00 +0000120void Bootstrapper::TearDown() {
Steve Block44f0eee2011-05-26 01:26:41 +0100121 if (delete_these_non_arrays_on_tear_down_ != NULL) {
122 int len = delete_these_non_arrays_on_tear_down_->length();
Steve Blockd0582a62009-12-15 09:54:21 +0000123 ASSERT(len < 20); // Don't use this mechanism for unbounded allocations.
124 for (int i = 0; i < len; i++) {
Steve Block44f0eee2011-05-26 01:26:41 +0100125 delete delete_these_non_arrays_on_tear_down_->at(i);
126 delete_these_non_arrays_on_tear_down_->at(i) = NULL;
Steve Blockd0582a62009-12-15 09:54:21 +0000127 }
Steve Block44f0eee2011-05-26 01:26:41 +0100128 delete delete_these_non_arrays_on_tear_down_;
129 delete_these_non_arrays_on_tear_down_ = NULL;
Steve Blockd0582a62009-12-15 09:54:21 +0000130 }
131
Steve Block44f0eee2011-05-26 01:26:41 +0100132 if (delete_these_arrays_on_tear_down_ != NULL) {
133 int len = delete_these_arrays_on_tear_down_->length();
Leon Clarkee46be812010-01-19 14:06:41 +0000134 ASSERT(len < 1000); // Don't use this mechanism for unbounded allocations.
135 for (int i = 0; i < len; i++) {
Steve Block44f0eee2011-05-26 01:26:41 +0100136 delete[] delete_these_arrays_on_tear_down_->at(i);
137 delete_these_arrays_on_tear_down_->at(i) = NULL;
Leon Clarkee46be812010-01-19 14:06:41 +0000138 }
Steve Block44f0eee2011-05-26 01:26:41 +0100139 delete delete_these_arrays_on_tear_down_;
140 delete_these_arrays_on_tear_down_ = NULL;
Leon Clarkee46be812010-01-19 14:06:41 +0000141 }
142
Steve Block44f0eee2011-05-26 01:26:41 +0100143 extensions_cache_.Initialize(false); // Yes, symmetrical
Steve Blocka7e24c12009-10-30 11:49:00 +0000144}
145
146
Steve Blocka7e24c12009-10-30 11:49:00 +0000147class Genesis BASE_EMBEDDED {
148 public:
Ben Murdoch257744e2011-11-30 15:57:28 +0000149 Genesis(Isolate* isolate,
150 Handle<Object> global_object,
Steve Blocka7e24c12009-10-30 11:49:00 +0000151 v8::Handle<v8::ObjectTemplate> global_template,
152 v8::ExtensionConfiguration* extensions);
Andrei Popescu31002712010-02-23 13:46:05 +0000153 ~Genesis() { }
Steve Blocka7e24c12009-10-30 11:49:00 +0000154
155 Handle<Context> result() { return result_; }
156
157 Genesis* previous() { return previous_; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000158
Ben Murdoch257744e2011-11-30 15:57:28 +0000159 Isolate* isolate() const { return isolate_; }
160 Factory* factory() const { return isolate_->factory(); }
161 Heap* heap() const { return isolate_->heap(); }
162
Steve Blocka7e24c12009-10-30 11:49:00 +0000163 private:
164 Handle<Context> global_context_;
Ben Murdoch257744e2011-11-30 15:57:28 +0000165 Isolate* isolate_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000166
167 // There may be more than one active genesis object: When GC is
168 // triggered during environment creation there may be weak handle
169 // processing callbacks which may create new environments.
170 Genesis* previous_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000171
172 Handle<Context> global_context() { return global_context_; }
173
Andrei Popescu31002712010-02-23 13:46:05 +0000174 // Creates some basic objects. Used for creating a context from scratch.
175 void CreateRoots();
176 // Creates the empty function. Used for creating a context from scratch.
Ben Murdoch257744e2011-11-30 15:57:28 +0000177 Handle<JSFunction> CreateEmptyFunction(Isolate* isolate);
Steve Block44f0eee2011-05-26 01:26:41 +0100178 // Creates the ThrowTypeError function. ECMA 5th Ed. 13.2.3
Ben Murdoch257744e2011-11-30 15:57:28 +0000179 Handle<JSFunction> GetThrowTypeErrorFunction();
Steve Block44f0eee2011-05-26 01:26:41 +0100180
181 void CreateStrictModeFunctionMaps(Handle<JSFunction> empty);
Andrei Popescu31002712010-02-23 13:46:05 +0000182 // Creates the global objects using the global and the template passed in
183 // through the API. We call this regardless of whether we are building a
184 // context from scratch or using a deserialized one from the partial snapshot
185 // but in the latter case we don't use the objects it produces directly, as
186 // we have to used the deserialized ones that are linked together with the
187 // rest of the context snapshot.
188 Handle<JSGlobalProxy> CreateNewGlobals(
189 v8::Handle<v8::ObjectTemplate> global_template,
190 Handle<Object> global_object,
191 Handle<GlobalObject>* global_proxy_out);
192 // Hooks the given global proxy into the context. If the context was created
193 // by deserialization then this will unhook the global proxy that was
194 // deserialized, leaving the GC to pick it up.
195 void HookUpGlobalProxy(Handle<GlobalObject> inner_global,
196 Handle<JSGlobalProxy> global_proxy);
Andrei Popescu402d9372010-02-26 13:31:12 +0000197 // Similarly, we want to use the inner global that has been created by the
198 // templates passed through the API. The inner global from the snapshot is
199 // detached from the other objects in the snapshot.
200 void HookUpInnerGlobal(Handle<GlobalObject> inner_global);
Andrei Popescu31002712010-02-23 13:46:05 +0000201 // New context initialization. Used for creating a context from scratch.
202 void InitializeGlobal(Handle<GlobalObject> inner_global,
203 Handle<JSFunction> empty_function);
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000204 void InitializeExperimentalGlobal();
Andrei Popescu31002712010-02-23 13:46:05 +0000205 // Installs the contents of the native .js files on the global objects.
206 // Used for creating a context from scratch.
Steve Blocka7e24c12009-10-30 11:49:00 +0000207 void InstallNativeFunctions();
Ben Murdoch257744e2011-11-30 15:57:28 +0000208 void InstallExperimentalNativeFunctions();
Steve Blocka7e24c12009-10-30 11:49:00 +0000209 bool InstallNatives();
Ben Murdoch257744e2011-11-30 15:57:28 +0000210 bool InstallExperimentalNatives();
Ben Murdochb0fe1622011-05-05 13:52:32 +0100211 void InstallBuiltinFunctionIds();
Steve Block6ded16b2010-05-10 14:33:55 +0100212 void InstallJSFunctionResultCaches();
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100213 void InitializeNormalizedMapCaches();
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000214
215 enum ExtensionTraversalState {
216 UNVISITED, VISITED, INSTALLED
217 };
218
219 class ExtensionStates {
220 public:
221 ExtensionStates();
222 ExtensionTraversalState get_state(RegisteredExtension* extension);
223 void set_state(RegisteredExtension* extension,
224 ExtensionTraversalState state);
225 private:
226 Allocator allocator_;
227 HashMap map_;
228 DISALLOW_COPY_AND_ASSIGN(ExtensionStates);
229 };
230
Andrei Popescu31002712010-02-23 13:46:05 +0000231 // Used both for deserialized and from-scratch contexts to add the extensions
232 // provided.
233 static bool InstallExtensions(Handle<Context> global_context,
234 v8::ExtensionConfiguration* extensions);
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000235 static bool InstallExtension(const char* name,
236 ExtensionStates* extension_states);
237 static bool InstallExtension(v8::RegisteredExtension* current,
238 ExtensionStates* extension_states);
Andrei Popescu31002712010-02-23 13:46:05 +0000239 static void InstallSpecialObjects(Handle<Context> global_context);
Andrei Popescu402d9372010-02-26 13:31:12 +0000240 bool InstallJSBuiltins(Handle<JSBuiltinsObject> builtins);
Steve Blocka7e24c12009-10-30 11:49:00 +0000241 bool ConfigureApiObject(Handle<JSObject> object,
242 Handle<ObjectTemplateInfo> object_template);
243 bool ConfigureGlobalObjects(v8::Handle<v8::ObjectTemplate> global_template);
244
245 // Migrates all properties from the 'from' object to the 'to'
246 // object and overrides the prototype in 'to' with the one from
247 // 'from'.
248 void TransferObject(Handle<JSObject> from, Handle<JSObject> to);
249 void TransferNamedProperties(Handle<JSObject> from, Handle<JSObject> to);
250 void TransferIndexedProperties(Handle<JSObject> from, Handle<JSObject> to);
251
Steve Block6ded16b2010-05-10 14:33:55 +0100252 enum PrototypePropertyMode {
253 DONT_ADD_PROTOTYPE,
254 ADD_READONLY_PROTOTYPE,
255 ADD_WRITEABLE_PROTOTYPE
256 };
Steve Block44f0eee2011-05-26 01:26:41 +0100257
258 Handle<Map> CreateFunctionMap(PrototypePropertyMode prototype_mode);
259
Steve Blocka7e24c12009-10-30 11:49:00 +0000260 Handle<DescriptorArray> ComputeFunctionInstanceDescriptor(
Steve Block6ded16b2010-05-10 14:33:55 +0100261 PrototypePropertyMode prototypeMode);
Steve Blocka7e24c12009-10-30 11:49:00 +0000262 void MakeFunctionInstancePrototypeWritable();
263
Steve Block44f0eee2011-05-26 01:26:41 +0100264 Handle<Map> CreateStrictModeFunctionMap(
265 PrototypePropertyMode prototype_mode,
266 Handle<JSFunction> empty_function,
267 Handle<FixedArray> arguments_callbacks,
268 Handle<FixedArray> caller_callbacks);
269
270 Handle<DescriptorArray> ComputeStrictFunctionInstanceDescriptor(
271 PrototypePropertyMode propertyMode,
272 Handle<FixedArray> arguments,
273 Handle<FixedArray> caller);
274
Ben Murdoch257744e2011-11-30 15:57:28 +0000275 static bool CompileBuiltin(Isolate* isolate, int index);
276 static bool CompileExperimentalBuiltin(Isolate* isolate, int index);
Steve Blocka7e24c12009-10-30 11:49:00 +0000277 static bool CompileNative(Vector<const char> name, Handle<String> source);
278 static bool CompileScriptCached(Vector<const char> name,
279 Handle<String> source,
280 SourceCodeCache* cache,
281 v8::Extension* extension,
Andrei Popescu31002712010-02-23 13:46:05 +0000282 Handle<Context> top_context,
Steve Blocka7e24c12009-10-30 11:49:00 +0000283 bool use_runtime_context);
284
285 Handle<Context> result_;
Steve Block44f0eee2011-05-26 01:26:41 +0100286
287 // Function instance maps. Function literal maps are created initially with
288 // a read only prototype for the processing of JS builtins. Later the function
289 // instance maps are replaced in order to make prototype writable.
290 // These are the final, writable prototype, maps.
291 Handle<Map> function_instance_map_writable_prototype_;
292 Handle<Map> strict_mode_function_instance_map_writable_prototype_;
Ben Murdoch257744e2011-11-30 15:57:28 +0000293 Handle<JSFunction> throw_type_error_function;
Steve Block44f0eee2011-05-26 01:26:41 +0100294
Andrei Popescu31002712010-02-23 13:46:05 +0000295 BootstrapperActive active_;
296 friend class Bootstrapper;
Steve Blocka7e24c12009-10-30 11:49:00 +0000297};
298
Steve Blocka7e24c12009-10-30 11:49:00 +0000299
300void Bootstrapper::Iterate(ObjectVisitor* v) {
Steve Block44f0eee2011-05-26 01:26:41 +0100301 extensions_cache_.Iterate(v);
Steve Blockd0582a62009-12-15 09:54:21 +0000302 v->Synchronize("Extensions");
Steve Blocka7e24c12009-10-30 11:49:00 +0000303}
304
305
Steve Blocka7e24c12009-10-30 11:49:00 +0000306Handle<Context> Bootstrapper::CreateEnvironment(
Ben Murdoch257744e2011-11-30 15:57:28 +0000307 Isolate* isolate,
Steve Blocka7e24c12009-10-30 11:49:00 +0000308 Handle<Object> global_object,
309 v8::Handle<v8::ObjectTemplate> global_template,
310 v8::ExtensionConfiguration* extensions) {
Andrei Popescu31002712010-02-23 13:46:05 +0000311 HandleScope scope;
312 Handle<Context> env;
Ben Murdoch257744e2011-11-30 15:57:28 +0000313 Genesis genesis(isolate, global_object, global_template, extensions);
Andrei Popescu31002712010-02-23 13:46:05 +0000314 env = genesis.result();
315 if (!env.is_null()) {
316 if (InstallExtensions(env, extensions)) {
317 return env;
318 }
319 }
320 return Handle<Context>();
Steve Blocka7e24c12009-10-30 11:49:00 +0000321}
322
323
324static void SetObjectPrototype(Handle<JSObject> object, Handle<Object> proto) {
325 // object.__proto__ = proto;
Ben Murdoch257744e2011-11-30 15:57:28 +0000326 Factory* factory = object->GetIsolate()->factory();
Steve Blocka7e24c12009-10-30 11:49:00 +0000327 Handle<Map> old_to_map = Handle<Map>(object->map());
Ben Murdoch257744e2011-11-30 15:57:28 +0000328 Handle<Map> new_to_map = factory->CopyMapDropTransitions(old_to_map);
Steve Blocka7e24c12009-10-30 11:49:00 +0000329 new_to_map->set_prototype(*proto);
330 object->set_map(*new_to_map);
331}
332
333
334void Bootstrapper::DetachGlobal(Handle<Context> env) {
Ben Murdoch257744e2011-11-30 15:57:28 +0000335 Factory* factory = env->GetIsolate()->factory();
Steve Block44f0eee2011-05-26 01:26:41 +0100336 JSGlobalProxy::cast(env->global_proxy())->set_context(*factory->null_value());
Steve Blocka7e24c12009-10-30 11:49:00 +0000337 SetObjectPrototype(Handle<JSObject>(env->global_proxy()),
Steve Block44f0eee2011-05-26 01:26:41 +0100338 factory->null_value());
Steve Blocka7e24c12009-10-30 11:49:00 +0000339 env->set_global_proxy(env->global());
340 env->global()->set_global_receiver(env->global());
341}
342
343
Andrei Popescu74b3c142010-03-29 12:03:09 +0100344void Bootstrapper::ReattachGlobal(Handle<Context> env,
345 Handle<Object> global_object) {
346 ASSERT(global_object->IsJSGlobalProxy());
347 Handle<JSGlobalProxy> global = Handle<JSGlobalProxy>::cast(global_object);
348 env->global()->set_global_receiver(*global);
349 env->set_global_proxy(*global);
350 SetObjectPrototype(global, Handle<JSObject>(env->global()));
351 global->set_context(*env);
352}
353
354
Steve Blocka7e24c12009-10-30 11:49:00 +0000355static Handle<JSFunction> InstallFunction(Handle<JSObject> target,
356 const char* name,
357 InstanceType type,
358 int instance_size,
359 Handle<JSObject> prototype,
360 Builtins::Name call,
361 bool is_ecma_native) {
Ben Murdoch257744e2011-11-30 15:57:28 +0000362 Isolate* isolate = target->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +0100363 Factory* factory = isolate->factory();
364 Handle<String> symbol = factory->LookupAsciiSymbol(name);
365 Handle<Code> call_code = Handle<Code>(isolate->builtins()->builtin(call));
Steve Block6ded16b2010-05-10 14:33:55 +0100366 Handle<JSFunction> function = prototype.is_null() ?
Steve Block44f0eee2011-05-26 01:26:41 +0100367 factory->NewFunctionWithoutPrototype(symbol, call_code) :
368 factory->NewFunctionWithPrototype(symbol,
Steve Blocka7e24c12009-10-30 11:49:00 +0000369 type,
370 instance_size,
371 prototype,
372 call_code,
373 is_ecma_native);
Ben Murdoch589d6972011-11-30 16:04:58 +0000374 PropertyAttributes attributes;
375 if (target->IsJSBuiltinsObject()) {
376 attributes =
377 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
378 } else {
379 attributes = DONT_ENUM;
380 }
381 SetLocalPropertyNoThrow(target, symbol, function, attributes);
Steve Blocka7e24c12009-10-30 11:49:00 +0000382 if (is_ecma_native) {
383 function->shared()->set_instance_class_name(*symbol);
384 }
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000385 function->shared()->set_native(true);
Steve Blocka7e24c12009-10-30 11:49:00 +0000386 return function;
387}
388
389
390Handle<DescriptorArray> Genesis::ComputeFunctionInstanceDescriptor(
Steve Block6ded16b2010-05-10 14:33:55 +0100391 PrototypePropertyMode prototypeMode) {
Steve Block44f0eee2011-05-26 01:26:41 +0100392 Handle<DescriptorArray> descriptors =
Ben Murdoch257744e2011-11-30 15:57:28 +0000393 factory()->NewDescriptorArray(prototypeMode == DONT_ADD_PROTOTYPE
394 ? 4
395 : 5);
Steve Block6ded16b2010-05-10 14:33:55 +0100396 PropertyAttributes attributes =
Steve Blocka7e24c12009-10-30 11:49:00 +0000397 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
Steve Blocka7e24c12009-10-30 11:49:00 +0000398
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000399 DescriptorArray::WhitenessWitness witness(*descriptors);
400
Steve Block44f0eee2011-05-26 01:26:41 +0100401 { // Add length.
Ben Murdoch257744e2011-11-30 15:57:28 +0000402 Handle<Foreign> foreign = factory()->NewForeign(&Accessors::FunctionLength);
403 CallbacksDescriptor d(*factory()->length_symbol(), *foreign, attributes);
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000404 descriptors->Set(0, &d, witness);
Steve Block44f0eee2011-05-26 01:26:41 +0100405 }
406 { // Add name.
Ben Murdoch257744e2011-11-30 15:57:28 +0000407 Handle<Foreign> foreign = factory()->NewForeign(&Accessors::FunctionName);
408 CallbacksDescriptor d(*factory()->name_symbol(), *foreign, attributes);
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000409 descriptors->Set(1, &d, witness);
Steve Block44f0eee2011-05-26 01:26:41 +0100410 }
411 { // Add arguments.
Ben Murdoch257744e2011-11-30 15:57:28 +0000412 Handle<Foreign> foreign =
413 factory()->NewForeign(&Accessors::FunctionArguments);
414 CallbacksDescriptor d(*factory()->arguments_symbol(), *foreign, attributes);
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000415 descriptors->Set(2, &d, witness);
Steve Block44f0eee2011-05-26 01:26:41 +0100416 }
417 { // Add caller.
Ben Murdoch257744e2011-11-30 15:57:28 +0000418 Handle<Foreign> foreign = factory()->NewForeign(&Accessors::FunctionCaller);
419 CallbacksDescriptor d(*factory()->caller_symbol(), *foreign, attributes);
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000420 descriptors->Set(3, &d, witness);
Steve Block44f0eee2011-05-26 01:26:41 +0100421 }
422 if (prototypeMode != DONT_ADD_PROTOTYPE) {
423 // Add prototype.
424 if (prototypeMode == ADD_WRITEABLE_PROTOTYPE) {
425 attributes = static_cast<PropertyAttributes>(attributes & ~READ_ONLY);
426 }
Ben Murdoch257744e2011-11-30 15:57:28 +0000427 Handle<Foreign> foreign =
428 factory()->NewForeign(&Accessors::FunctionPrototype);
429 CallbacksDescriptor d(*factory()->prototype_symbol(), *foreign, attributes);
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000430 descriptors->Set(4, &d, witness);
Steve Block44f0eee2011-05-26 01:26:41 +0100431 }
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000432 descriptors->Sort(witness);
Steve Block44f0eee2011-05-26 01:26:41 +0100433 return descriptors;
434}
Steve Blocka7e24c12009-10-30 11:49:00 +0000435
Steve Blocka7e24c12009-10-30 11:49:00 +0000436
Steve Block44f0eee2011-05-26 01:26:41 +0100437Handle<Map> Genesis::CreateFunctionMap(PrototypePropertyMode prototype_mode) {
Ben Murdoch257744e2011-11-30 15:57:28 +0000438 Handle<Map> map = factory()->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
Steve Block44f0eee2011-05-26 01:26:41 +0100439 Handle<DescriptorArray> descriptors =
440 ComputeFunctionInstanceDescriptor(prototype_mode);
441 map->set_instance_descriptors(*descriptors);
442 map->set_function_with_prototype(prototype_mode != DONT_ADD_PROTOTYPE);
443 return map;
Steve Blocka7e24c12009-10-30 11:49:00 +0000444}
445
446
Ben Murdoch257744e2011-11-30 15:57:28 +0000447Handle<JSFunction> Genesis::CreateEmptyFunction(Isolate* isolate) {
Steve Block44f0eee2011-05-26 01:26:41 +0100448 // Allocate the map for function instances. Maps are allocated first and their
449 // prototypes patched later, once empty function is created.
450
Steve Blocka7e24c12009-10-30 11:49:00 +0000451 // Please note that the prototype property for function instances must be
452 // writable.
Ben Murdoch8b112d22011-06-08 16:22:53 +0100453 Handle<Map> function_instance_map =
454 CreateFunctionMap(ADD_WRITEABLE_PROTOTYPE);
455 global_context()->set_function_instance_map(*function_instance_map);
Steve Block6ded16b2010-05-10 14:33:55 +0100456
457 // Functions with this map will not have a 'prototype' property, and
458 // can not be used as constructors.
Ben Murdoch8b112d22011-06-08 16:22:53 +0100459 Handle<Map> function_without_prototype_map =
460 CreateFunctionMap(DONT_ADD_PROTOTYPE);
Steve Block6ded16b2010-05-10 14:33:55 +0100461 global_context()->set_function_without_prototype_map(
Ben Murdoch8b112d22011-06-08 16:22:53 +0100462 *function_without_prototype_map);
Steve Blocka7e24c12009-10-30 11:49:00 +0000463
Steve Block44f0eee2011-05-26 01:26:41 +0100464 // Allocate the function map. This map is temporary, used only for processing
465 // of builtins.
466 // Later the map is replaced with writable prototype map, allocated below.
Ben Murdoch8b112d22011-06-08 16:22:53 +0100467 Handle<Map> function_map = CreateFunctionMap(ADD_READONLY_PROTOTYPE);
468 global_context()->set_function_map(*function_map);
Steve Blocka7e24c12009-10-30 11:49:00 +0000469
Steve Block44f0eee2011-05-26 01:26:41 +0100470 // The final map for functions. Writeable prototype.
471 // This map is installed in MakeFunctionInstancePrototypeWritable.
472 function_instance_map_writable_prototype_ =
473 CreateFunctionMap(ADD_WRITEABLE_PROTOTYPE);
474
Steve Block44f0eee2011-05-26 01:26:41 +0100475 Factory* factory = isolate->factory();
476 Heap* heap = isolate->heap();
477
478 Handle<String> object_name = Handle<String>(heap->Object_symbol());
Steve Blocka7e24c12009-10-30 11:49:00 +0000479
480 { // --- O b j e c t ---
481 Handle<JSFunction> object_fun =
Steve Block44f0eee2011-05-26 01:26:41 +0100482 factory->NewFunction(object_name, factory->null_value());
Steve Blocka7e24c12009-10-30 11:49:00 +0000483 Handle<Map> object_function_map =
Steve Block44f0eee2011-05-26 01:26:41 +0100484 factory->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
Steve Blocka7e24c12009-10-30 11:49:00 +0000485 object_fun->set_initial_map(*object_function_map);
486 object_function_map->set_constructor(*object_fun);
487
488 global_context()->set_object_function(*object_fun);
489
490 // Allocate a new prototype for the object function.
Steve Block44f0eee2011-05-26 01:26:41 +0100491 Handle<JSObject> prototype = factory->NewJSObject(
492 isolate->object_function(),
493 TENURED);
Steve Blocka7e24c12009-10-30 11:49:00 +0000494
495 global_context()->set_initial_object_prototype(*prototype);
496 SetPrototype(object_fun, prototype);
497 object_function_map->
Steve Block44f0eee2011-05-26 01:26:41 +0100498 set_instance_descriptors(heap->empty_descriptor_array());
Steve Blocka7e24c12009-10-30 11:49:00 +0000499 }
500
501 // Allocate the empty function as the prototype for function ECMAScript
502 // 262 15.3.4.
Steve Block44f0eee2011-05-26 01:26:41 +0100503 Handle<String> symbol = factory->LookupAsciiSymbol("Empty");
Steve Blocka7e24c12009-10-30 11:49:00 +0000504 Handle<JSFunction> empty_function =
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000505 factory->NewFunctionWithoutPrototype(symbol, CLASSIC_MODE);
Steve Blocka7e24c12009-10-30 11:49:00 +0000506
Andrei Popescu31002712010-02-23 13:46:05 +0000507 // --- E m p t y ---
508 Handle<Code> code =
Steve Block44f0eee2011-05-26 01:26:41 +0100509 Handle<Code>(isolate->builtins()->builtin(
510 Builtins::kEmptyFunction));
Andrei Popescu31002712010-02-23 13:46:05 +0000511 empty_function->set_code(*code);
Iain Merrick75681382010-08-19 15:07:18 +0100512 empty_function->shared()->set_code(*code);
Steve Block44f0eee2011-05-26 01:26:41 +0100513 Handle<String> source = factory->NewStringFromAscii(CStrVector("() {}"));
514 Handle<Script> script = factory->NewScript(source);
Andrei Popescu31002712010-02-23 13:46:05 +0000515 script->set_type(Smi::FromInt(Script::TYPE_NATIVE));
516 empty_function->shared()->set_script(*script);
517 empty_function->shared()->set_start_position(0);
518 empty_function->shared()->set_end_position(source->length());
519 empty_function->shared()->DontAdaptArguments();
Steve Block44f0eee2011-05-26 01:26:41 +0100520
521 // Set prototypes for the function maps.
Andrei Popescu31002712010-02-23 13:46:05 +0000522 global_context()->function_map()->set_prototype(*empty_function);
523 global_context()->function_instance_map()->set_prototype(*empty_function);
Steve Block6ded16b2010-05-10 14:33:55 +0100524 global_context()->function_without_prototype_map()->
525 set_prototype(*empty_function);
Steve Block44f0eee2011-05-26 01:26:41 +0100526 function_instance_map_writable_prototype_->set_prototype(*empty_function);
Steve Blocka7e24c12009-10-30 11:49:00 +0000527
Andrei Popescu31002712010-02-23 13:46:05 +0000528 // Allocate the function map first and then patch the prototype later
Steve Block44f0eee2011-05-26 01:26:41 +0100529 Handle<Map> empty_fm = factory->CopyMapDropDescriptors(
Steve Block6ded16b2010-05-10 14:33:55 +0100530 function_without_prototype_map);
531 empty_fm->set_instance_descriptors(
Steve Block44f0eee2011-05-26 01:26:41 +0100532 function_without_prototype_map->instance_descriptors());
Andrei Popescu31002712010-02-23 13:46:05 +0000533 empty_fm->set_prototype(global_context()->object_function()->prototype());
534 empty_function->set_map(*empty_fm);
535 return empty_function;
536}
537
538
Steve Block44f0eee2011-05-26 01:26:41 +0100539Handle<DescriptorArray> Genesis::ComputeStrictFunctionInstanceDescriptor(
540 PrototypePropertyMode prototypeMode,
541 Handle<FixedArray> arguments,
542 Handle<FixedArray> caller) {
Steve Block44f0eee2011-05-26 01:26:41 +0100543 Handle<DescriptorArray> descriptors =
Ben Murdoch257744e2011-11-30 15:57:28 +0000544 factory()->NewDescriptorArray(prototypeMode == DONT_ADD_PROTOTYPE
545 ? 4
546 : 5);
Steve Block44f0eee2011-05-26 01:26:41 +0100547 PropertyAttributes attributes = static_cast<PropertyAttributes>(
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000548 DONT_ENUM | DONT_DELETE);
549
550 DescriptorArray::WhitenessWitness witness(*descriptors);
Steve Block44f0eee2011-05-26 01:26:41 +0100551
552 { // length
Ben Murdoch257744e2011-11-30 15:57:28 +0000553 Handle<Foreign> foreign = factory()->NewForeign(&Accessors::FunctionLength);
554 CallbacksDescriptor d(*factory()->length_symbol(), *foreign, attributes);
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000555 descriptors->Set(0, &d, witness);
Steve Block44f0eee2011-05-26 01:26:41 +0100556 }
557 { // name
Ben Murdoch257744e2011-11-30 15:57:28 +0000558 Handle<Foreign> foreign = factory()->NewForeign(&Accessors::FunctionName);
559 CallbacksDescriptor d(*factory()->name_symbol(), *foreign, attributes);
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000560 descriptors->Set(1, &d, witness);
Steve Block44f0eee2011-05-26 01:26:41 +0100561 }
562 { // arguments
Ben Murdoch257744e2011-11-30 15:57:28 +0000563 CallbacksDescriptor d(*factory()->arguments_symbol(),
564 *arguments,
565 attributes);
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000566 descriptors->Set(2, &d, witness);
Steve Block44f0eee2011-05-26 01:26:41 +0100567 }
568 { // caller
Ben Murdoch257744e2011-11-30 15:57:28 +0000569 CallbacksDescriptor d(*factory()->caller_symbol(), *caller, attributes);
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000570 descriptors->Set(3, &d, witness);
Steve Block44f0eee2011-05-26 01:26:41 +0100571 }
572
573 // prototype
574 if (prototypeMode != DONT_ADD_PROTOTYPE) {
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000575 if (prototypeMode != ADD_WRITEABLE_PROTOTYPE) {
576 attributes = static_cast<PropertyAttributes>(attributes | READ_ONLY);
Steve Block44f0eee2011-05-26 01:26:41 +0100577 }
Ben Murdoch257744e2011-11-30 15:57:28 +0000578 Handle<Foreign> foreign =
579 factory()->NewForeign(&Accessors::FunctionPrototype);
580 CallbacksDescriptor d(*factory()->prototype_symbol(), *foreign, attributes);
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000581 descriptors->Set(4, &d, witness);
Steve Block44f0eee2011-05-26 01:26:41 +0100582 }
583
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000584 descriptors->Sort(witness);
Steve Block44f0eee2011-05-26 01:26:41 +0100585 return descriptors;
586}
587
588
589// ECMAScript 5th Edition, 13.2.3
Ben Murdoch257744e2011-11-30 15:57:28 +0000590Handle<JSFunction> Genesis::GetThrowTypeErrorFunction() {
591 if (throw_type_error_function.is_null()) {
592 Handle<String> name = factory()->LookupAsciiSymbol("ThrowTypeError");
593 throw_type_error_function =
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000594 factory()->NewFunctionWithoutPrototype(name, CLASSIC_MODE);
Ben Murdoch257744e2011-11-30 15:57:28 +0000595 Handle<Code> code(isolate()->builtins()->builtin(
596 Builtins::kStrictModePoisonPill));
597 throw_type_error_function->set_map(
598 global_context()->function_map());
599 throw_type_error_function->set_code(*code);
600 throw_type_error_function->shared()->set_code(*code);
601 throw_type_error_function->shared()->DontAdaptArguments();
Steve Block053d10c2011-06-13 19:13:29 +0100602
Ben Murdoch257744e2011-11-30 15:57:28 +0000603 PreventExtensions(throw_type_error_function);
604 }
605 return throw_type_error_function;
Steve Block44f0eee2011-05-26 01:26:41 +0100606}
607
608
609Handle<Map> Genesis::CreateStrictModeFunctionMap(
610 PrototypePropertyMode prototype_mode,
611 Handle<JSFunction> empty_function,
612 Handle<FixedArray> arguments_callbacks,
613 Handle<FixedArray> caller_callbacks) {
Ben Murdoch257744e2011-11-30 15:57:28 +0000614 Handle<Map> map = factory()->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
Steve Block44f0eee2011-05-26 01:26:41 +0100615 Handle<DescriptorArray> descriptors =
616 ComputeStrictFunctionInstanceDescriptor(prototype_mode,
617 arguments_callbacks,
618 caller_callbacks);
619 map->set_instance_descriptors(*descriptors);
620 map->set_function_with_prototype(prototype_mode != DONT_ADD_PROTOTYPE);
621 map->set_prototype(*empty_function);
622 return map;
623}
624
625
626void Genesis::CreateStrictModeFunctionMaps(Handle<JSFunction> empty) {
627 // Create the callbacks arrays for ThrowTypeError functions.
628 // The get/set callacks are filled in after the maps are created below.
Ben Murdoch257744e2011-11-30 15:57:28 +0000629 Factory* factory = empty->GetIsolate()->factory();
Steve Block44f0eee2011-05-26 01:26:41 +0100630 Handle<FixedArray> arguments = factory->NewFixedArray(2, TENURED);
631 Handle<FixedArray> caller = factory->NewFixedArray(2, TENURED);
632
633 // Allocate map for the strict mode function instances.
Ben Murdoch8b112d22011-06-08 16:22:53 +0100634 Handle<Map> strict_mode_function_instance_map =
635 CreateStrictModeFunctionMap(
636 ADD_WRITEABLE_PROTOTYPE, empty, arguments, caller);
Steve Block44f0eee2011-05-26 01:26:41 +0100637 global_context()->set_strict_mode_function_instance_map(
Ben Murdoch8b112d22011-06-08 16:22:53 +0100638 *strict_mode_function_instance_map);
Steve Block44f0eee2011-05-26 01:26:41 +0100639
640 // Allocate map for the prototype-less strict mode instances.
Ben Murdoch8b112d22011-06-08 16:22:53 +0100641 Handle<Map> strict_mode_function_without_prototype_map =
642 CreateStrictModeFunctionMap(
643 DONT_ADD_PROTOTYPE, empty, arguments, caller);
Steve Block44f0eee2011-05-26 01:26:41 +0100644 global_context()->set_strict_mode_function_without_prototype_map(
Ben Murdoch8b112d22011-06-08 16:22:53 +0100645 *strict_mode_function_without_prototype_map);
Steve Block44f0eee2011-05-26 01:26:41 +0100646
647 // Allocate map for the strict mode functions. This map is temporary, used
648 // only for processing of builtins.
649 // Later the map is replaced with writable prototype map, allocated below.
Ben Murdoch8b112d22011-06-08 16:22:53 +0100650 Handle<Map> strict_mode_function_map =
651 CreateStrictModeFunctionMap(
652 ADD_READONLY_PROTOTYPE, empty, arguments, caller);
Steve Block44f0eee2011-05-26 01:26:41 +0100653 global_context()->set_strict_mode_function_map(
Ben Murdoch8b112d22011-06-08 16:22:53 +0100654 *strict_mode_function_map);
Steve Block44f0eee2011-05-26 01:26:41 +0100655
656 // The final map for the strict mode functions. Writeable prototype.
657 // This map is installed in MakeFunctionInstancePrototypeWritable.
658 strict_mode_function_instance_map_writable_prototype_ =
659 CreateStrictModeFunctionMap(
660 ADD_WRITEABLE_PROTOTYPE, empty, arguments, caller);
661
Ben Murdoch257744e2011-11-30 15:57:28 +0000662 // Create the ThrowTypeError function instance.
663 Handle<JSFunction> throw_function =
664 GetThrowTypeErrorFunction();
Steve Block44f0eee2011-05-26 01:26:41 +0100665
666 // Complete the callback fixed arrays.
Ben Murdoch257744e2011-11-30 15:57:28 +0000667 arguments->set(0, *throw_function);
668 arguments->set(1, *throw_function);
669 caller->set(0, *throw_function);
670 caller->set(1, *throw_function);
Steve Block44f0eee2011-05-26 01:26:41 +0100671}
672
673
Ben Murdochb0fe1622011-05-05 13:52:32 +0100674static void AddToWeakGlobalContextList(Context* context) {
675 ASSERT(context->IsGlobalContext());
Ben Murdoch257744e2011-11-30 15:57:28 +0000676 Heap* heap = context->GetIsolate()->heap();
Ben Murdochb0fe1622011-05-05 13:52:32 +0100677#ifdef DEBUG
678 { // NOLINT
679 ASSERT(context->get(Context::NEXT_CONTEXT_LINK)->IsUndefined());
680 // Check that context is not in the list yet.
Steve Block44f0eee2011-05-26 01:26:41 +0100681 for (Object* current = heap->global_contexts_list();
Ben Murdochb0fe1622011-05-05 13:52:32 +0100682 !current->IsUndefined();
683 current = Context::cast(current)->get(Context::NEXT_CONTEXT_LINK)) {
684 ASSERT(current != context);
685 }
686 }
687#endif
Steve Block44f0eee2011-05-26 01:26:41 +0100688 context->set(Context::NEXT_CONTEXT_LINK, heap->global_contexts_list());
689 heap->set_global_contexts_list(context);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100690}
691
692
Andrei Popescu31002712010-02-23 13:46:05 +0000693void Genesis::CreateRoots() {
694 // Allocate the global context FixedArray first and then patch the
695 // closure and extension object later (we need the empty function
696 // and the global object, but in order to create those, we need the
697 // global context).
Ben Murdoch257744e2011-11-30 15:57:28 +0000698 global_context_ = Handle<Context>::cast(isolate()->global_handles()->Create(
699 *factory()->NewGlobalContext()));
Ben Murdochb0fe1622011-05-05 13:52:32 +0100700 AddToWeakGlobalContextList(*global_context_);
Ben Murdoch257744e2011-11-30 15:57:28 +0000701 isolate()->set_context(*global_context());
Andrei Popescu31002712010-02-23 13:46:05 +0000702
703 // Allocate the message listeners object.
704 {
705 v8::NeanderArray listeners;
706 global_context()->set_message_listeners(*listeners.value());
707 }
708}
709
710
711Handle<JSGlobalProxy> Genesis::CreateNewGlobals(
712 v8::Handle<v8::ObjectTemplate> global_template,
713 Handle<Object> global_object,
714 Handle<GlobalObject>* inner_global_out) {
715 // The argument global_template aka data is an ObjectTemplateInfo.
716 // It has a constructor pointer that points at global_constructor which is a
717 // FunctionTemplateInfo.
718 // The global_constructor is used to create or reinitialize the global_proxy.
719 // The global_constructor also has a prototype_template pointer that points at
720 // js_global_template which is an ObjectTemplateInfo.
721 // That in turn has a constructor pointer that points at
722 // js_global_constructor which is a FunctionTemplateInfo.
723 // js_global_constructor is used to make js_global_function
724 // js_global_function is used to make the new inner_global.
725 //
726 // --- G l o b a l ---
727 // Step 1: Create a fresh inner JSGlobalObject.
728 Handle<JSFunction> js_global_function;
729 Handle<ObjectTemplateInfo> js_global_template;
730 if (!global_template.IsEmpty()) {
731 // Get prototype template of the global_template.
732 Handle<ObjectTemplateInfo> data =
733 v8::Utils::OpenHandle(*global_template);
734 Handle<FunctionTemplateInfo> global_constructor =
735 Handle<FunctionTemplateInfo>(
736 FunctionTemplateInfo::cast(data->constructor()));
737 Handle<Object> proto_template(global_constructor->prototype_template());
738 if (!proto_template->IsUndefined()) {
739 js_global_template =
740 Handle<ObjectTemplateInfo>::cast(proto_template);
741 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000742 }
743
Andrei Popescu31002712010-02-23 13:46:05 +0000744 if (js_global_template.is_null()) {
Ben Murdoch257744e2011-11-30 15:57:28 +0000745 Handle<String> name = Handle<String>(heap()->empty_symbol());
746 Handle<Code> code = Handle<Code>(isolate()->builtins()->builtin(
Steve Block44f0eee2011-05-26 01:26:41 +0100747 Builtins::kIllegal));
Andrei Popescu31002712010-02-23 13:46:05 +0000748 js_global_function =
Ben Murdoch257744e2011-11-30 15:57:28 +0000749 factory()->NewFunction(name, JS_GLOBAL_OBJECT_TYPE,
750 JSGlobalObject::kSize, code, true);
Andrei Popescu31002712010-02-23 13:46:05 +0000751 // Change the constructor property of the prototype of the
752 // hidden global function to refer to the Object function.
753 Handle<JSObject> prototype =
754 Handle<JSObject>(
755 JSObject::cast(js_global_function->instance_prototype()));
Steve Block1e0659c2011-05-24 12:43:12 +0100756 SetLocalPropertyNoThrow(
Steve Block44f0eee2011-05-26 01:26:41 +0100757 prototype,
Ben Murdoch257744e2011-11-30 15:57:28 +0000758 factory()->constructor_symbol(),
759 isolate()->object_function(),
Steve Block44f0eee2011-05-26 01:26:41 +0100760 NONE);
Andrei Popescu31002712010-02-23 13:46:05 +0000761 } else {
762 Handle<FunctionTemplateInfo> js_global_constructor(
763 FunctionTemplateInfo::cast(js_global_template->constructor()));
764 js_global_function =
Ben Murdoch257744e2011-11-30 15:57:28 +0000765 factory()->CreateApiFunction(js_global_constructor,
766 factory()->InnerGlobalObject);
Steve Blocka7e24c12009-10-30 11:49:00 +0000767 }
768
Andrei Popescu31002712010-02-23 13:46:05 +0000769 js_global_function->initial_map()->set_is_hidden_prototype();
770 Handle<GlobalObject> inner_global =
Ben Murdoch257744e2011-11-30 15:57:28 +0000771 factory()->NewGlobalObject(js_global_function);
Andrei Popescu31002712010-02-23 13:46:05 +0000772 if (inner_global_out != NULL) {
773 *inner_global_out = inner_global;
774 }
775
776 // Step 2: create or re-initialize the global proxy object.
777 Handle<JSFunction> global_proxy_function;
778 if (global_template.IsEmpty()) {
Ben Murdoch257744e2011-11-30 15:57:28 +0000779 Handle<String> name = Handle<String>(heap()->empty_symbol());
780 Handle<Code> code = Handle<Code>(isolate()->builtins()->builtin(
Steve Block44f0eee2011-05-26 01:26:41 +0100781 Builtins::kIllegal));
Andrei Popescu31002712010-02-23 13:46:05 +0000782 global_proxy_function =
Ben Murdoch257744e2011-11-30 15:57:28 +0000783 factory()->NewFunction(name, JS_GLOBAL_PROXY_TYPE,
784 JSGlobalProxy::kSize, code, true);
Andrei Popescu31002712010-02-23 13:46:05 +0000785 } else {
786 Handle<ObjectTemplateInfo> data =
787 v8::Utils::OpenHandle(*global_template);
788 Handle<FunctionTemplateInfo> global_constructor(
789 FunctionTemplateInfo::cast(data->constructor()));
790 global_proxy_function =
Ben Murdoch257744e2011-11-30 15:57:28 +0000791 factory()->CreateApiFunction(global_constructor,
792 factory()->OuterGlobalObject);
Andrei Popescu31002712010-02-23 13:46:05 +0000793 }
794
Ben Murdoch257744e2011-11-30 15:57:28 +0000795 Handle<String> global_name = factory()->LookupAsciiSymbol("global");
Andrei Popescu31002712010-02-23 13:46:05 +0000796 global_proxy_function->shared()->set_instance_class_name(*global_name);
797 global_proxy_function->initial_map()->set_is_access_check_needed(true);
798
799 // Set global_proxy.__proto__ to js_global after ConfigureGlobalObjects
800 // Return the global proxy.
801
802 if (global_object.location() != NULL) {
803 ASSERT(global_object->IsJSGlobalProxy());
804 return ReinitializeJSGlobalProxy(
805 global_proxy_function,
806 Handle<JSGlobalProxy>::cast(global_object));
807 } else {
808 return Handle<JSGlobalProxy>::cast(
Ben Murdoch257744e2011-11-30 15:57:28 +0000809 factory()->NewJSObject(global_proxy_function, TENURED));
Andrei Popescu31002712010-02-23 13:46:05 +0000810 }
811}
812
813
814void Genesis::HookUpGlobalProxy(Handle<GlobalObject> inner_global,
815 Handle<JSGlobalProxy> global_proxy) {
816 // Set the global context for the global object.
817 inner_global->set_global_context(*global_context());
818 inner_global->set_global_receiver(*global_proxy);
819 global_proxy->set_context(*global_context());
820 global_context()->set_global_proxy(*global_proxy);
821}
822
823
Andrei Popescu402d9372010-02-26 13:31:12 +0000824void Genesis::HookUpInnerGlobal(Handle<GlobalObject> inner_global) {
825 Handle<GlobalObject> inner_global_from_snapshot(
826 GlobalObject::cast(global_context_->extension()));
827 Handle<JSBuiltinsObject> builtins_global(global_context_->builtins());
828 global_context_->set_extension(*inner_global);
829 global_context_->set_global(*inner_global);
830 global_context_->set_security_token(*inner_global);
831 static const PropertyAttributes attributes =
832 static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE);
833 ForceSetProperty(builtins_global,
Ben Murdoch257744e2011-11-30 15:57:28 +0000834 factory()->LookupAsciiSymbol("global"),
Andrei Popescu402d9372010-02-26 13:31:12 +0000835 inner_global,
836 attributes);
837 // Setup the reference from the global object to the builtins object.
838 JSGlobalObject::cast(*inner_global)->set_builtins(*builtins_global);
839 TransferNamedProperties(inner_global_from_snapshot, inner_global);
840 TransferIndexedProperties(inner_global_from_snapshot, inner_global);
841}
842
843
844// This is only called if we are not using snapshots. The equivalent
845// work in the snapshot case is done in HookUpInnerGlobal.
Andrei Popescu31002712010-02-23 13:46:05 +0000846void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
847 Handle<JSFunction> empty_function) {
848 // --- G l o b a l C o n t e x t ---
849 // Use the empty function as closure (no scope info).
850 global_context()->set_closure(*empty_function);
Andrei Popescu31002712010-02-23 13:46:05 +0000851 global_context()->set_previous(NULL);
852 // Set extension and global object.
853 global_context()->set_extension(*inner_global);
854 global_context()->set_global(*inner_global);
855 // Security setup: Set the security token of the global object to
856 // its the inner global. This makes the security check between two
857 // different contexts fail by default even in case of global
858 // object reinitialization.
859 global_context()->set_security_token(*inner_global);
860
Ben Murdoch257744e2011-11-30 15:57:28 +0000861 Isolate* isolate = inner_global->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +0100862 Factory* factory = isolate->factory();
863 Heap* heap = isolate->heap();
864
865 Handle<String> object_name = Handle<String>(heap->Object_symbol());
Steve Block1e0659c2011-05-24 12:43:12 +0100866 SetLocalPropertyNoThrow(inner_global, object_name,
Steve Block44f0eee2011-05-26 01:26:41 +0100867 isolate->object_function(), DONT_ENUM);
Andrei Popescu31002712010-02-23 13:46:05 +0000868
Steve Blocka7e24c12009-10-30 11:49:00 +0000869 Handle<JSObject> global = Handle<JSObject>(global_context()->global());
870
871 // Install global Function object
872 InstallFunction(global, "Function", JS_FUNCTION_TYPE, JSFunction::kSize,
Steve Block44f0eee2011-05-26 01:26:41 +0100873 empty_function, Builtins::kIllegal, true); // ECMA native.
Steve Blocka7e24c12009-10-30 11:49:00 +0000874
875 { // --- A r r a y ---
876 Handle<JSFunction> array_function =
877 InstallFunction(global, "Array", JS_ARRAY_TYPE, JSArray::kSize,
Steve Block44f0eee2011-05-26 01:26:41 +0100878 isolate->initial_object_prototype(),
879 Builtins::kArrayCode, true);
Steve Blocka7e24c12009-10-30 11:49:00 +0000880 array_function->shared()->set_construct_stub(
Steve Block44f0eee2011-05-26 01:26:41 +0100881 isolate->builtins()->builtin(Builtins::kArrayConstructCode));
Steve Blocka7e24c12009-10-30 11:49:00 +0000882 array_function->shared()->DontAdaptArguments();
883
884 // This seems a bit hackish, but we need to make sure Array.length
885 // is 1.
886 array_function->shared()->set_length(1);
887 Handle<DescriptorArray> array_descriptors =
Ben Murdoch257744e2011-11-30 15:57:28 +0000888 factory->CopyAppendForeignDescriptor(
Steve Block44f0eee2011-05-26 01:26:41 +0100889 factory->empty_descriptor_array(),
890 factory->length_symbol(),
Ben Murdoch257744e2011-11-30 15:57:28 +0000891 factory->NewForeign(&Accessors::ArrayLength),
Steve Blocka7e24c12009-10-30 11:49:00 +0000892 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE));
893
894 // Cache the fast JavaScript array map
895 global_context()->set_js_array_map(array_function->initial_map());
896 global_context()->js_array_map()->set_instance_descriptors(
897 *array_descriptors);
898 // array_function is used internally. JS code creating array object should
899 // search for the 'Array' property on the global object and use that one
900 // as the constructor. 'Array' property on a global object can be
901 // overwritten by JS code.
902 global_context()->set_array_function(*array_function);
903 }
904
905 { // --- N u m b e r ---
906 Handle<JSFunction> number_fun =
907 InstallFunction(global, "Number", JS_VALUE_TYPE, JSValue::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_number_function(*number_fun);
911 }
912
913 { // --- B o o l e a n ---
914 Handle<JSFunction> boolean_fun =
915 InstallFunction(global, "Boolean", JS_VALUE_TYPE, JSValue::kSize,
Steve Block44f0eee2011-05-26 01:26:41 +0100916 isolate->initial_object_prototype(),
917 Builtins::kIllegal, true);
Steve Blocka7e24c12009-10-30 11:49:00 +0000918 global_context()->set_boolean_function(*boolean_fun);
919 }
920
921 { // --- S t r i n g ---
922 Handle<JSFunction> string_fun =
923 InstallFunction(global, "String", JS_VALUE_TYPE, JSValue::kSize,
Steve Block44f0eee2011-05-26 01:26:41 +0100924 isolate->initial_object_prototype(),
925 Builtins::kIllegal, true);
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100926 string_fun->shared()->set_construct_stub(
Steve Block44f0eee2011-05-26 01:26:41 +0100927 isolate->builtins()->builtin(Builtins::kStringConstructCode));
Steve Blocka7e24c12009-10-30 11:49:00 +0000928 global_context()->set_string_function(*string_fun);
929 // Add 'length' property to strings.
930 Handle<DescriptorArray> string_descriptors =
Ben Murdoch257744e2011-11-30 15:57:28 +0000931 factory->CopyAppendForeignDescriptor(
Steve Block44f0eee2011-05-26 01:26:41 +0100932 factory->empty_descriptor_array(),
933 factory->length_symbol(),
Ben Murdoch257744e2011-11-30 15:57:28 +0000934 factory->NewForeign(&Accessors::StringLength),
Steve Blocka7e24c12009-10-30 11:49:00 +0000935 static_cast<PropertyAttributes>(DONT_ENUM |
936 DONT_DELETE |
937 READ_ONLY));
938
939 Handle<Map> string_map =
940 Handle<Map>(global_context()->string_function()->initial_map());
941 string_map->set_instance_descriptors(*string_descriptors);
942 }
943
944 { // --- D a t e ---
945 // Builtin functions for Date.prototype.
946 Handle<JSFunction> date_fun =
947 InstallFunction(global, "Date", JS_VALUE_TYPE, JSValue::kSize,
Steve Block44f0eee2011-05-26 01:26:41 +0100948 isolate->initial_object_prototype(),
949 Builtins::kIllegal, true);
Steve Blocka7e24c12009-10-30 11:49:00 +0000950
951 global_context()->set_date_function(*date_fun);
952 }
953
954
955 { // -- R e g E x p
956 // Builtin functions for RegExp.prototype.
957 Handle<JSFunction> regexp_fun =
958 InstallFunction(global, "RegExp", JS_REGEXP_TYPE, JSRegExp::kSize,
Steve Block44f0eee2011-05-26 01:26:41 +0100959 isolate->initial_object_prototype(),
960 Builtins::kIllegal, true);
Steve Blocka7e24c12009-10-30 11:49:00 +0000961 global_context()->set_regexp_function(*regexp_fun);
Steve Block6ded16b2010-05-10 14:33:55 +0100962
963 ASSERT(regexp_fun->has_initial_map());
964 Handle<Map> initial_map(regexp_fun->initial_map());
965
966 ASSERT_EQ(0, initial_map->inobject_properties());
967
Steve Block44f0eee2011-05-26 01:26:41 +0100968 Handle<DescriptorArray> descriptors = factory->NewDescriptorArray(5);
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000969 DescriptorArray::WhitenessWitness witness(*descriptors);
Steve Block6ded16b2010-05-10 14:33:55 +0100970 PropertyAttributes final =
971 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
972 int enum_index = 0;
973 {
974 // ECMA-262, section 15.10.7.1.
Steve Block44f0eee2011-05-26 01:26:41 +0100975 FieldDescriptor field(heap->source_symbol(),
Steve Block6ded16b2010-05-10 14:33:55 +0100976 JSRegExp::kSourceFieldIndex,
977 final,
978 enum_index++);
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000979 descriptors->Set(0, &field, witness);
Steve Block6ded16b2010-05-10 14:33:55 +0100980 }
981 {
982 // ECMA-262, section 15.10.7.2.
Steve Block44f0eee2011-05-26 01:26:41 +0100983 FieldDescriptor field(heap->global_symbol(),
Steve Block6ded16b2010-05-10 14:33:55 +0100984 JSRegExp::kGlobalFieldIndex,
985 final,
986 enum_index++);
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000987 descriptors->Set(1, &field, witness);
Steve Block6ded16b2010-05-10 14:33:55 +0100988 }
989 {
990 // ECMA-262, section 15.10.7.3.
Steve Block44f0eee2011-05-26 01:26:41 +0100991 FieldDescriptor field(heap->ignore_case_symbol(),
Steve Block6ded16b2010-05-10 14:33:55 +0100992 JSRegExp::kIgnoreCaseFieldIndex,
993 final,
994 enum_index++);
Ben Murdoch592a9fc2012-03-05 11:04:45 +0000995 descriptors->Set(2, &field, witness);
Steve Block6ded16b2010-05-10 14:33:55 +0100996 }
997 {
998 // ECMA-262, section 15.10.7.4.
Steve Block44f0eee2011-05-26 01:26:41 +0100999 FieldDescriptor field(heap->multiline_symbol(),
Steve Block6ded16b2010-05-10 14:33:55 +01001000 JSRegExp::kMultilineFieldIndex,
1001 final,
1002 enum_index++);
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001003 descriptors->Set(3, &field, witness);
Steve Block6ded16b2010-05-10 14:33:55 +01001004 }
1005 {
1006 // ECMA-262, section 15.10.7.5.
1007 PropertyAttributes writable =
1008 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
Steve Block44f0eee2011-05-26 01:26:41 +01001009 FieldDescriptor field(heap->last_index_symbol(),
Steve Block6ded16b2010-05-10 14:33:55 +01001010 JSRegExp::kLastIndexFieldIndex,
1011 writable,
1012 enum_index++);
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001013 descriptors->Set(4, &field, witness);
Steve Block6ded16b2010-05-10 14:33:55 +01001014 }
1015 descriptors->SetNextEnumerationIndex(enum_index);
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001016 descriptors->Sort(witness);
Steve Block6ded16b2010-05-10 14:33:55 +01001017
1018 initial_map->set_inobject_properties(5);
1019 initial_map->set_pre_allocated_property_fields(5);
1020 initial_map->set_unused_property_fields(0);
1021 initial_map->set_instance_size(
1022 initial_map->instance_size() + 5 * kPointerSize);
1023 initial_map->set_instance_descriptors(*descriptors);
Iain Merrick75681382010-08-19 15:07:18 +01001024 initial_map->set_visitor_id(StaticVisitorBase::GetVisitorId(*initial_map));
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001025
1026 // RegExp prototype object is itself a RegExp.
1027 Handle<Map> proto_map = factory->CopyMapDropTransitions(initial_map);
1028 proto_map->set_prototype(global_context()->initial_object_prototype());
1029 Handle<JSObject> proto = factory->NewJSObjectFromMap(proto_map);
1030 proto->InObjectPropertyAtPut(JSRegExp::kSourceFieldIndex,
1031 heap->empty_string());
1032 proto->InObjectPropertyAtPut(JSRegExp::kGlobalFieldIndex,
1033 heap->false_value());
1034 proto->InObjectPropertyAtPut(JSRegExp::kIgnoreCaseFieldIndex,
1035 heap->false_value());
1036 proto->InObjectPropertyAtPut(JSRegExp::kMultilineFieldIndex,
1037 heap->false_value());
1038 proto->InObjectPropertyAtPut(JSRegExp::kLastIndexFieldIndex,
1039 Smi::FromInt(0),
1040 SKIP_WRITE_BARRIER); // It's a Smi.
1041 initial_map->set_prototype(*proto);
1042 factory->SetRegExpIrregexpData(Handle<JSRegExp>::cast(proto),
1043 JSRegExp::IRREGEXP, factory->empty_string(),
1044 JSRegExp::Flags(0), 0);
Steve Blocka7e24c12009-10-30 11:49:00 +00001045 }
1046
1047 { // -- J S O N
Steve Block44f0eee2011-05-26 01:26:41 +01001048 Handle<String> name = factory->NewStringFromAscii(CStrVector("JSON"));
1049 Handle<JSFunction> cons = factory->NewFunction(
Steve Blocka7e24c12009-10-30 11:49:00 +00001050 name,
Steve Block44f0eee2011-05-26 01:26:41 +01001051 factory->the_hole_value());
Steve Blocka7e24c12009-10-30 11:49:00 +00001052 cons->SetInstancePrototype(global_context()->initial_object_prototype());
1053 cons->SetInstanceClassName(*name);
Steve Block44f0eee2011-05-26 01:26:41 +01001054 Handle<JSObject> json_object = factory->NewJSObject(cons, TENURED);
Steve Blocka7e24c12009-10-30 11:49:00 +00001055 ASSERT(json_object->IsJSObject());
Steve Block1e0659c2011-05-24 12:43:12 +01001056 SetLocalPropertyNoThrow(global, name, json_object, DONT_ENUM);
Steve Blocka7e24c12009-10-30 11:49:00 +00001057 global_context()->set_json_object(*json_object);
1058 }
1059
1060 { // --- arguments_boilerplate_
1061 // Make sure we can recognize argument objects at runtime.
1062 // This is done by introducing an anonymous function with
1063 // class_name equals 'Arguments'.
Steve Block44f0eee2011-05-26 01:26:41 +01001064 Handle<String> symbol = factory->LookupAsciiSymbol("Arguments");
1065 Handle<Code> code = Handle<Code>(
1066 isolate->builtins()->builtin(Builtins::kIllegal));
Steve Blocka7e24c12009-10-30 11:49:00 +00001067 Handle<JSObject> prototype =
1068 Handle<JSObject>(
1069 JSObject::cast(global_context()->object_function()->prototype()));
1070
1071 Handle<JSFunction> function =
Steve Block44f0eee2011-05-26 01:26:41 +01001072 factory->NewFunctionWithPrototype(symbol,
Steve Blocka7e24c12009-10-30 11:49:00 +00001073 JS_OBJECT_TYPE,
1074 JSObject::kHeaderSize,
1075 prototype,
1076 code,
1077 false);
1078 ASSERT(!function->has_initial_map());
1079 function->shared()->set_instance_class_name(*symbol);
1080 function->shared()->set_expected_nof_properties(2);
Steve Block44f0eee2011-05-26 01:26:41 +01001081 Handle<JSObject> result = factory->NewJSObject(function);
Steve Blocka7e24c12009-10-30 11:49:00 +00001082
1083 global_context()->set_arguments_boilerplate(*result);
Steve Block44f0eee2011-05-26 01:26:41 +01001084 // Note: length must be added as the first property and
1085 // callee must be added as the second property.
1086 SetLocalPropertyNoThrow(result, factory->length_symbol(),
1087 factory->undefined_value(),
Steve Block1e0659c2011-05-24 12:43:12 +01001088 DONT_ENUM);
Steve Block44f0eee2011-05-26 01:26:41 +01001089 SetLocalPropertyNoThrow(result, factory->callee_symbol(),
1090 factory->undefined_value(),
Steve Block1e0659c2011-05-24 12:43:12 +01001091 DONT_ENUM);
Steve Blocka7e24c12009-10-30 11:49:00 +00001092
1093#ifdef DEBUG
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001094 LookupResult lookup(isolate);
Steve Block44f0eee2011-05-26 01:26:41 +01001095 result->LocalLookup(heap->callee_symbol(), &lookup);
Andrei Popescu402d9372010-02-26 13:31:12 +00001096 ASSERT(lookup.IsProperty() && (lookup.type() == FIELD));
Steve Block44f0eee2011-05-26 01:26:41 +01001097 ASSERT(lookup.GetFieldIndex() == Heap::kArgumentsCalleeIndex);
Steve Blocka7e24c12009-10-30 11:49:00 +00001098
Steve Block44f0eee2011-05-26 01:26:41 +01001099 result->LocalLookup(heap->length_symbol(), &lookup);
Andrei Popescu402d9372010-02-26 13:31:12 +00001100 ASSERT(lookup.IsProperty() && (lookup.type() == FIELD));
Steve Block44f0eee2011-05-26 01:26:41 +01001101 ASSERT(lookup.GetFieldIndex() == Heap::kArgumentsLengthIndex);
Steve Blocka7e24c12009-10-30 11:49:00 +00001102
Steve Block44f0eee2011-05-26 01:26:41 +01001103 ASSERT(result->map()->inobject_properties() > Heap::kArgumentsCalleeIndex);
1104 ASSERT(result->map()->inobject_properties() > Heap::kArgumentsLengthIndex);
1105
1106 // Check the state of the object.
1107 ASSERT(result->HasFastProperties());
1108 ASSERT(result->HasFastElements());
1109#endif
1110 }
1111
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001112 { // --- aliased_arguments_boilerplate_
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001113 // Set up a well-formed parameter map to make assertions happy.
1114 Handle<FixedArray> elements = factory->NewFixedArray(2);
1115 elements->set_map(heap->non_strict_arguments_elements_map());
1116 Handle<FixedArray> array;
1117 array = factory->NewFixedArray(0);
1118 elements->set(0, *array);
1119 array = factory->NewFixedArray(0);
1120 elements->set(1, *array);
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001121
1122 Handle<Map> old_map(global_context()->arguments_boilerplate()->map());
1123 Handle<Map> new_map = factory->CopyMapDropTransitions(old_map);
1124 new_map->set_pre_allocated_property_fields(2);
1125 Handle<JSObject> result = factory->NewJSObjectFromMap(new_map);
1126 // Set elements kind after allocating the object because
1127 // NewJSObjectFromMap assumes a fast elements map.
1128 new_map->set_elements_kind(NON_STRICT_ARGUMENTS_ELEMENTS);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001129 result->set_elements(*elements);
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001130 ASSERT(result->HasNonStrictArgumentsElements());
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001131 global_context()->set_aliased_arguments_boilerplate(*result);
1132 }
1133
Steve Block44f0eee2011-05-26 01:26:41 +01001134 { // --- strict mode arguments boilerplate
1135 const PropertyAttributes attributes =
1136 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
1137
1138 // Create the ThrowTypeError functions.
1139 Handle<FixedArray> callee = factory->NewFixedArray(2, TENURED);
1140 Handle<FixedArray> caller = factory->NewFixedArray(2, TENURED);
1141
Ben Murdoch257744e2011-11-30 15:57:28 +00001142 Handle<JSFunction> throw_function =
1143 GetThrowTypeErrorFunction();
Steve Block44f0eee2011-05-26 01:26:41 +01001144
1145 // Install the ThrowTypeError functions.
Ben Murdoch257744e2011-11-30 15:57:28 +00001146 callee->set(0, *throw_function);
1147 callee->set(1, *throw_function);
1148 caller->set(0, *throw_function);
1149 caller->set(1, *throw_function);
Steve Block44f0eee2011-05-26 01:26:41 +01001150
1151 // Create the descriptor array for the arguments object.
1152 Handle<DescriptorArray> descriptors = factory->NewDescriptorArray(3);
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001153 DescriptorArray::WhitenessWitness witness(*descriptors);
Steve Block44f0eee2011-05-26 01:26:41 +01001154 { // length
1155 FieldDescriptor d(*factory->length_symbol(), 0, DONT_ENUM);
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001156 descriptors->Set(0, &d, witness);
Steve Block44f0eee2011-05-26 01:26:41 +01001157 }
1158 { // callee
1159 CallbacksDescriptor d(*factory->callee_symbol(), *callee, attributes);
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001160 descriptors->Set(1, &d, witness);
Steve Block44f0eee2011-05-26 01:26:41 +01001161 }
1162 { // caller
1163 CallbacksDescriptor d(*factory->caller_symbol(), *caller, attributes);
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001164 descriptors->Set(2, &d, witness);
Steve Block44f0eee2011-05-26 01:26:41 +01001165 }
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001166 descriptors->Sort(witness);
Steve Block44f0eee2011-05-26 01:26:41 +01001167
1168 // Create the map. Allocate one in-object field for length.
1169 Handle<Map> map = factory->NewMap(JS_OBJECT_TYPE,
1170 Heap::kArgumentsObjectSizeStrict);
1171 map->set_instance_descriptors(*descriptors);
1172 map->set_function_with_prototype(true);
1173 map->set_prototype(global_context()->object_function()->prototype());
1174 map->set_pre_allocated_property_fields(1);
1175 map->set_inobject_properties(1);
1176
1177 // Copy constructor from the non-strict arguments boilerplate.
1178 map->set_constructor(
1179 global_context()->arguments_boilerplate()->map()->constructor());
1180
1181 // Allocate the arguments boilerplate object.
1182 Handle<JSObject> result = factory->NewJSObjectFromMap(map);
1183 global_context()->set_strict_mode_arguments_boilerplate(*result);
1184
1185 // Add length property only for strict mode boilerplate.
1186 SetLocalPropertyNoThrow(result, factory->length_symbol(),
1187 factory->undefined_value(),
1188 DONT_ENUM);
1189
1190#ifdef DEBUG
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001191 LookupResult lookup(isolate);
Steve Block44f0eee2011-05-26 01:26:41 +01001192 result->LocalLookup(heap->length_symbol(), &lookup);
1193 ASSERT(lookup.IsProperty() && (lookup.type() == FIELD));
1194 ASSERT(lookup.GetFieldIndex() == Heap::kArgumentsLengthIndex);
1195
1196 ASSERT(result->map()->inobject_properties() > Heap::kArgumentsLengthIndex);
Steve Blocka7e24c12009-10-30 11:49:00 +00001197
1198 // Check the state of the object.
1199 ASSERT(result->HasFastProperties());
1200 ASSERT(result->HasFastElements());
1201#endif
1202 }
1203
1204 { // --- context extension
1205 // Create a function for the context extension objects.
Steve Block44f0eee2011-05-26 01:26:41 +01001206 Handle<Code> code = Handle<Code>(
1207 isolate->builtins()->builtin(Builtins::kIllegal));
Steve Blocka7e24c12009-10-30 11:49:00 +00001208 Handle<JSFunction> context_extension_fun =
Steve Block44f0eee2011-05-26 01:26:41 +01001209 factory->NewFunction(factory->empty_symbol(),
Steve Blocka7e24c12009-10-30 11:49:00 +00001210 JS_CONTEXT_EXTENSION_OBJECT_TYPE,
1211 JSObject::kHeaderSize,
1212 code,
1213 true);
1214
Steve Block44f0eee2011-05-26 01:26:41 +01001215 Handle<String> name = factory->LookupAsciiSymbol("context_extension");
Steve Blocka7e24c12009-10-30 11:49:00 +00001216 context_extension_fun->shared()->set_instance_class_name(*name);
1217 global_context()->set_context_extension_function(*context_extension_fun);
1218 }
1219
1220
1221 {
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001222 // Set up the call-as-function delegate.
Steve Blocka7e24c12009-10-30 11:49:00 +00001223 Handle<Code> code =
Steve Block44f0eee2011-05-26 01:26:41 +01001224 Handle<Code>(isolate->builtins()->builtin(
1225 Builtins::kHandleApiCallAsFunction));
Steve Blocka7e24c12009-10-30 11:49:00 +00001226 Handle<JSFunction> delegate =
Steve Block44f0eee2011-05-26 01:26:41 +01001227 factory->NewFunction(factory->empty_symbol(), JS_OBJECT_TYPE,
Steve Blocka7e24c12009-10-30 11:49:00 +00001228 JSObject::kHeaderSize, code, true);
1229 global_context()->set_call_as_function_delegate(*delegate);
1230 delegate->shared()->DontAdaptArguments();
1231 }
1232
1233 {
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001234 // Set up the call-as-constructor delegate.
Steve Blocka7e24c12009-10-30 11:49:00 +00001235 Handle<Code> code =
Steve Block44f0eee2011-05-26 01:26:41 +01001236 Handle<Code>(isolate->builtins()->builtin(
1237 Builtins::kHandleApiCallAsConstructor));
Steve Blocka7e24c12009-10-30 11:49:00 +00001238 Handle<JSFunction> delegate =
Steve Block44f0eee2011-05-26 01:26:41 +01001239 factory->NewFunction(factory->empty_symbol(), JS_OBJECT_TYPE,
Steve Blocka7e24c12009-10-30 11:49:00 +00001240 JSObject::kHeaderSize, code, true);
1241 global_context()->set_call_as_constructor_delegate(*delegate);
1242 delegate->shared()->DontAdaptArguments();
1243 }
1244
Steve Blocka7e24c12009-10-30 11:49:00 +00001245 // Initialize the out of memory slot.
Steve Block44f0eee2011-05-26 01:26:41 +01001246 global_context()->set_out_of_memory(heap->false_value());
Steve Blocka7e24c12009-10-30 11:49:00 +00001247
1248 // Initialize the data slot.
Steve Block44f0eee2011-05-26 01:26:41 +01001249 global_context()->set_data(heap->undefined_value());
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001250
1251 {
1252 // Initialize the random seed slot.
1253 Handle<ByteArray> zeroed_byte_array(
1254 factory->NewByteArray(kRandomStateSize));
1255 global_context()->set_random_seed(*zeroed_byte_array);
1256 memset(zeroed_byte_array->GetDataStartAddress(), 0, kRandomStateSize);
1257 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001258}
1259
1260
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001261void Genesis::InitializeExperimentalGlobal() {
1262 Handle<JSObject> global = Handle<JSObject>(global_context()->global());
1263
1264 // TODO(mstarzinger): Move this into Genesis::InitializeGlobal once we no
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001265 // longer need to live behind a flag, so functions get added to the snapshot.
1266 if (FLAG_harmony_collections) {
1267 { // -- S e t
1268 Handle<JSObject> prototype =
1269 factory()->NewJSObject(isolate()->object_function(), TENURED);
1270 InstallFunction(global, "Set", JS_SET_TYPE, JSSet::kSize,
1271 prototype, Builtins::kIllegal, true);
1272 }
1273 { // -- M a p
1274 Handle<JSObject> prototype =
1275 factory()->NewJSObject(isolate()->object_function(), TENURED);
1276 InstallFunction(global, "Map", JS_MAP_TYPE, JSMap::kSize,
1277 prototype, Builtins::kIllegal, true);
1278 }
1279 { // -- W e a k M a p
1280 Handle<JSObject> prototype =
1281 factory()->NewJSObject(isolate()->object_function(), TENURED);
1282 InstallFunction(global, "WeakMap", JS_WEAK_MAP_TYPE, JSWeakMap::kSize,
1283 prototype, Builtins::kIllegal, true);
1284 }
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001285 }
1286}
1287
1288
Ben Murdoch257744e2011-11-30 15:57:28 +00001289bool Genesis::CompileBuiltin(Isolate* isolate, int index) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001290 Vector<const char> name = Natives::GetScriptName(index);
Steve Block44f0eee2011-05-26 01:26:41 +01001291 Handle<String> source_code =
Ben Murdoch257744e2011-11-30 15:57:28 +00001292 isolate->bootstrapper()->NativesSourceLookup(index);
1293 return CompileNative(name, source_code);
1294}
1295
1296
1297bool Genesis::CompileExperimentalBuiltin(Isolate* isolate, int index) {
1298 Vector<const char> name = ExperimentalNatives::GetScriptName(index);
1299 Factory* factory = isolate->factory();
1300 Handle<String> source_code =
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001301 factory->NewStringFromAscii(
1302 ExperimentalNatives::GetRawScriptSource(index));
Steve Blocka7e24c12009-10-30 11:49:00 +00001303 return CompileNative(name, source_code);
1304}
1305
1306
1307bool Genesis::CompileNative(Vector<const char> name, Handle<String> source) {
1308 HandleScope scope;
Ben Murdoch257744e2011-11-30 15:57:28 +00001309 Isolate* isolate = source->GetIsolate();
Steve Blocka7e24c12009-10-30 11:49:00 +00001310#ifdef ENABLE_DEBUGGER_SUPPORT
Steve Block44f0eee2011-05-26 01:26:41 +01001311 isolate->debugger()->set_compiling_natives(true);
Steve Blocka7e24c12009-10-30 11:49:00 +00001312#endif
Andrei Popescu31002712010-02-23 13:46:05 +00001313 bool result = CompileScriptCached(name,
1314 source,
1315 NULL,
1316 NULL,
Steve Block44f0eee2011-05-26 01:26:41 +01001317 Handle<Context>(isolate->context()),
Andrei Popescu31002712010-02-23 13:46:05 +00001318 true);
Steve Block44f0eee2011-05-26 01:26:41 +01001319 ASSERT(isolate->has_pending_exception() != result);
1320 if (!result) isolate->clear_pending_exception();
Steve Blocka7e24c12009-10-30 11:49:00 +00001321#ifdef ENABLE_DEBUGGER_SUPPORT
Steve Block44f0eee2011-05-26 01:26:41 +01001322 isolate->debugger()->set_compiling_natives(false);
Steve Blocka7e24c12009-10-30 11:49:00 +00001323#endif
1324 return result;
1325}
1326
1327
1328bool Genesis::CompileScriptCached(Vector<const char> name,
1329 Handle<String> source,
1330 SourceCodeCache* cache,
1331 v8::Extension* extension,
Andrei Popescu31002712010-02-23 13:46:05 +00001332 Handle<Context> top_context,
Steve Blocka7e24c12009-10-30 11:49:00 +00001333 bool use_runtime_context) {
Ben Murdoch257744e2011-11-30 15:57:28 +00001334 Factory* factory = source->GetIsolate()->factory();
Steve Blocka7e24c12009-10-30 11:49:00 +00001335 HandleScope scope;
Steve Block6ded16b2010-05-10 14:33:55 +01001336 Handle<SharedFunctionInfo> function_info;
Steve Blocka7e24c12009-10-30 11:49:00 +00001337
1338 // If we can't find the function in the cache, we compile a new
1339 // function and insert it into the cache.
Steve Block6ded16b2010-05-10 14:33:55 +01001340 if (cache == NULL || !cache->Lookup(name, &function_info)) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001341 ASSERT(source->IsAsciiRepresentation());
Steve Block44f0eee2011-05-26 01:26:41 +01001342 Handle<String> script_name = factory->NewStringFromUtf8(name);
Steve Block6ded16b2010-05-10 14:33:55 +01001343 function_info = Compiler::Compile(
Andrei Popescu31002712010-02-23 13:46:05 +00001344 source,
1345 script_name,
1346 0,
1347 0,
1348 extension,
1349 NULL,
Andrei Popescu402d9372010-02-26 13:31:12 +00001350 Handle<String>::null(),
Andrei Popescu31002712010-02-23 13:46:05 +00001351 use_runtime_context ? NATIVES_CODE : NOT_NATIVES_CODE);
Steve Block6ded16b2010-05-10 14:33:55 +01001352 if (function_info.is_null()) return false;
1353 if (cache != NULL) cache->Add(name, function_info);
Steve Blocka7e24c12009-10-30 11:49:00 +00001354 }
1355
1356 // Setup the function context. Conceptually, we should clone the
1357 // function before overwriting the context but since we're in a
1358 // single-threaded environment it is not strictly necessary.
Andrei Popescu31002712010-02-23 13:46:05 +00001359 ASSERT(top_context->IsGlobalContext());
Steve Blocka7e24c12009-10-30 11:49:00 +00001360 Handle<Context> context =
1361 Handle<Context>(use_runtime_context
Andrei Popescu31002712010-02-23 13:46:05 +00001362 ? Handle<Context>(top_context->runtime_context())
1363 : top_context);
Steve Blocka7e24c12009-10-30 11:49:00 +00001364 Handle<JSFunction> fun =
Steve Block44f0eee2011-05-26 01:26:41 +01001365 factory->NewFunctionFromSharedFunctionInfo(function_info, context);
Steve Blocka7e24c12009-10-30 11:49:00 +00001366
Leon Clarke4515c472010-02-03 11:58:03 +00001367 // Call function using either the runtime object or the global
Steve Blocka7e24c12009-10-30 11:49:00 +00001368 // object as the receiver. Provide no parameters.
1369 Handle<Object> receiver =
1370 Handle<Object>(use_runtime_context
Andrei Popescu31002712010-02-23 13:46:05 +00001371 ? top_context->builtins()
1372 : top_context->global());
Steve Blocka7e24c12009-10-30 11:49:00 +00001373 bool has_pending_exception;
Ben Murdoch257744e2011-11-30 15:57:28 +00001374 Execution::Call(fun, receiver, 0, NULL, &has_pending_exception);
Steve Blocka7e24c12009-10-30 11:49:00 +00001375 if (has_pending_exception) return false;
Andrei Popescu402d9372010-02-26 13:31:12 +00001376 return true;
Steve Blocka7e24c12009-10-30 11:49:00 +00001377}
1378
1379
Ben Murdoch257744e2011-11-30 15:57:28 +00001380#define INSTALL_NATIVE(Type, name, var) \
1381 Handle<String> var##_name = factory()->LookupAsciiSymbol(name); \
1382 Object* var##_native = \
1383 global_context()->builtins()->GetPropertyNoExceptionThrown( \
1384 *var##_name); \
Ben Murdoch8b112d22011-06-08 16:22:53 +01001385 global_context()->set_##var(Type::cast(var##_native));
Steve Blocka7e24c12009-10-30 11:49:00 +00001386
Steve Block44f0eee2011-05-26 01:26:41 +01001387
Steve Blocka7e24c12009-10-30 11:49:00 +00001388void Genesis::InstallNativeFunctions() {
1389 HandleScope scope;
1390 INSTALL_NATIVE(JSFunction, "CreateDate", create_date_fun);
1391 INSTALL_NATIVE(JSFunction, "ToNumber", to_number_fun);
1392 INSTALL_NATIVE(JSFunction, "ToString", to_string_fun);
1393 INSTALL_NATIVE(JSFunction, "ToDetailString", to_detail_string_fun);
1394 INSTALL_NATIVE(JSFunction, "ToObject", to_object_fun);
1395 INSTALL_NATIVE(JSFunction, "ToInteger", to_integer_fun);
1396 INSTALL_NATIVE(JSFunction, "ToUint32", to_uint32_fun);
1397 INSTALL_NATIVE(JSFunction, "ToInt32", to_int32_fun);
Leon Clarkee46be812010-01-19 14:06:41 +00001398 INSTALL_NATIVE(JSFunction, "GlobalEval", global_eval_fun);
Steve Blocka7e24c12009-10-30 11:49:00 +00001399 INSTALL_NATIVE(JSFunction, "Instantiate", instantiate_fun);
1400 INSTALL_NATIVE(JSFunction, "ConfigureTemplateInstance",
1401 configure_instance_fun);
Steve Blocka7e24c12009-10-30 11:49:00 +00001402 INSTALL_NATIVE(JSFunction, "GetStackTraceLine", get_stack_trace_line_fun);
1403 INSTALL_NATIVE(JSObject, "functionCache", function_cache);
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001404 INSTALL_NATIVE(JSFunction, "ToCompletePropertyDescriptor",
1405 to_complete_property_descriptor);
Steve Blocka7e24c12009-10-30 11:49:00 +00001406}
1407
Ben Murdoch257744e2011-11-30 15:57:28 +00001408void Genesis::InstallExperimentalNativeFunctions() {
1409 if (FLAG_harmony_proxies) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001410 INSTALL_NATIVE(JSFunction, "DerivedHasTrap", derived_has_trap);
Ben Murdoch257744e2011-11-30 15:57:28 +00001411 INSTALL_NATIVE(JSFunction, "DerivedGetTrap", derived_get_trap);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001412 INSTALL_NATIVE(JSFunction, "DerivedSetTrap", derived_set_trap);
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001413 INSTALL_NATIVE(JSFunction, "ProxyEnumerate", proxy_enumerate);
Ben Murdoch257744e2011-11-30 15:57:28 +00001414 }
1415}
1416
Steve Blocka7e24c12009-10-30 11:49:00 +00001417#undef INSTALL_NATIVE
1418
1419
1420bool Genesis::InstallNatives() {
1421 HandleScope scope;
1422
1423 // Create a function for the builtins object. Allocate space for the
1424 // JavaScript builtins, a reference to the builtins object
1425 // (itself) and a reference to the global_context directly in the object.
Steve Block44f0eee2011-05-26 01:26:41 +01001426 Handle<Code> code = Handle<Code>(
Ben Murdoch257744e2011-11-30 15:57:28 +00001427 isolate()->builtins()->builtin(Builtins::kIllegal));
Steve Blocka7e24c12009-10-30 11:49:00 +00001428 Handle<JSFunction> builtins_fun =
Ben Murdoch257744e2011-11-30 15:57:28 +00001429 factory()->NewFunction(factory()->empty_symbol(),
1430 JS_BUILTINS_OBJECT_TYPE,
1431 JSBuiltinsObject::kSize, code, true);
Steve Blocka7e24c12009-10-30 11:49:00 +00001432
Ben Murdoch257744e2011-11-30 15:57:28 +00001433 Handle<String> name = factory()->LookupAsciiSymbol("builtins");
Steve Blocka7e24c12009-10-30 11:49:00 +00001434 builtins_fun->shared()->set_instance_class_name(*name);
1435
1436 // Allocate the builtins object.
1437 Handle<JSBuiltinsObject> builtins =
Ben Murdoch257744e2011-11-30 15:57:28 +00001438 Handle<JSBuiltinsObject>::cast(factory()->NewGlobalObject(builtins_fun));
Steve Blocka7e24c12009-10-30 11:49:00 +00001439 builtins->set_builtins(*builtins);
1440 builtins->set_global_context(*global_context());
1441 builtins->set_global_receiver(*builtins);
1442
1443 // Setup the 'global' properties of the builtins object. The
1444 // 'global' property that refers to the global object is the only
1445 // way to get from code running in the builtins context to the
1446 // global object.
1447 static const PropertyAttributes attributes =
1448 static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE);
Ben Murdoch257744e2011-11-30 15:57:28 +00001449 Handle<String> global_symbol = factory()->LookupAsciiSymbol("global");
Steve Block1e0659c2011-05-24 12:43:12 +01001450 Handle<Object> global_obj(global_context()->global());
1451 SetLocalPropertyNoThrow(builtins, global_symbol, global_obj, attributes);
Steve Blocka7e24c12009-10-30 11:49:00 +00001452
1453 // Setup the reference from the global object to the builtins object.
1454 JSGlobalObject::cast(global_context()->global())->set_builtins(*builtins);
1455
1456 // Create a bridge function that has context in the global context.
1457 Handle<JSFunction> bridge =
Ben Murdoch257744e2011-11-30 15:57:28 +00001458 factory()->NewFunction(factory()->empty_symbol(),
1459 factory()->undefined_value());
1460 ASSERT(bridge->context() == *isolate()->global_context());
Steve Blocka7e24c12009-10-30 11:49:00 +00001461
1462 // Allocate the builtins context.
1463 Handle<Context> context =
Ben Murdoch257744e2011-11-30 15:57:28 +00001464 factory()->NewFunctionContext(Context::MIN_CONTEXT_SLOTS, bridge);
Steve Blocka7e24c12009-10-30 11:49:00 +00001465 context->set_global(*builtins); // override builtins global object
1466
1467 global_context()->set_runtime_context(*context);
1468
1469 { // -- S c r i p t
1470 // Builtin functions for Script.
1471 Handle<JSFunction> script_fun =
1472 InstallFunction(builtins, "Script", JS_VALUE_TYPE, JSValue::kSize,
Ben Murdoch257744e2011-11-30 15:57:28 +00001473 isolate()->initial_object_prototype(),
Steve Block44f0eee2011-05-26 01:26:41 +01001474 Builtins::kIllegal, false);
Steve Blocka7e24c12009-10-30 11:49:00 +00001475 Handle<JSObject> prototype =
Ben Murdoch257744e2011-11-30 15:57:28 +00001476 factory()->NewJSObject(isolate()->object_function(), TENURED);
Steve Blocka7e24c12009-10-30 11:49:00 +00001477 SetPrototype(script_fun, prototype);
1478 global_context()->set_script_function(*script_fun);
1479
1480 // Add 'source' and 'data' property to scripts.
1481 PropertyAttributes common_attributes =
1482 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
Ben Murdoch257744e2011-11-30 15:57:28 +00001483 Handle<Foreign> foreign_source =
1484 factory()->NewForeign(&Accessors::ScriptSource);
Steve Blocka7e24c12009-10-30 11:49:00 +00001485 Handle<DescriptorArray> script_descriptors =
Ben Murdoch257744e2011-11-30 15:57:28 +00001486 factory()->CopyAppendForeignDescriptor(
1487 factory()->empty_descriptor_array(),
1488 factory()->LookupAsciiSymbol("source"),
1489 foreign_source,
Steve Blocka7e24c12009-10-30 11:49:00 +00001490 common_attributes);
Ben Murdoch257744e2011-11-30 15:57:28 +00001491 Handle<Foreign> foreign_name =
1492 factory()->NewForeign(&Accessors::ScriptName);
Steve Blocka7e24c12009-10-30 11:49:00 +00001493 script_descriptors =
Ben Murdoch257744e2011-11-30 15:57:28 +00001494 factory()->CopyAppendForeignDescriptor(
Steve Blocka7e24c12009-10-30 11:49:00 +00001495 script_descriptors,
Ben Murdoch257744e2011-11-30 15:57:28 +00001496 factory()->LookupAsciiSymbol("name"),
1497 foreign_name,
Steve Blocka7e24c12009-10-30 11:49:00 +00001498 common_attributes);
Ben Murdoch257744e2011-11-30 15:57:28 +00001499 Handle<Foreign> foreign_id = factory()->NewForeign(&Accessors::ScriptId);
Steve Blocka7e24c12009-10-30 11:49:00 +00001500 script_descriptors =
Ben Murdoch257744e2011-11-30 15:57:28 +00001501 factory()->CopyAppendForeignDescriptor(
Steve Blocka7e24c12009-10-30 11:49:00 +00001502 script_descriptors,
Ben Murdoch257744e2011-11-30 15:57:28 +00001503 factory()->LookupAsciiSymbol("id"),
1504 foreign_id,
Steve Blocka7e24c12009-10-30 11:49:00 +00001505 common_attributes);
Ben Murdoch257744e2011-11-30 15:57:28 +00001506 Handle<Foreign> foreign_line_offset =
1507 factory()->NewForeign(&Accessors::ScriptLineOffset);
Steve Blocka7e24c12009-10-30 11:49:00 +00001508 script_descriptors =
Ben Murdoch257744e2011-11-30 15:57:28 +00001509 factory()->CopyAppendForeignDescriptor(
Steve Blocka7e24c12009-10-30 11:49:00 +00001510 script_descriptors,
Ben Murdoch257744e2011-11-30 15:57:28 +00001511 factory()->LookupAsciiSymbol("line_offset"),
1512 foreign_line_offset,
Steve Blocka7e24c12009-10-30 11:49:00 +00001513 common_attributes);
Ben Murdoch257744e2011-11-30 15:57:28 +00001514 Handle<Foreign> foreign_column_offset =
1515 factory()->NewForeign(&Accessors::ScriptColumnOffset);
Steve Blocka7e24c12009-10-30 11:49:00 +00001516 script_descriptors =
Ben Murdoch257744e2011-11-30 15:57:28 +00001517 factory()->CopyAppendForeignDescriptor(
Steve Blocka7e24c12009-10-30 11:49:00 +00001518 script_descriptors,
Ben Murdoch257744e2011-11-30 15:57:28 +00001519 factory()->LookupAsciiSymbol("column_offset"),
1520 foreign_column_offset,
Steve Blocka7e24c12009-10-30 11:49:00 +00001521 common_attributes);
Ben Murdoch257744e2011-11-30 15:57:28 +00001522 Handle<Foreign> foreign_data =
1523 factory()->NewForeign(&Accessors::ScriptData);
Steve Blocka7e24c12009-10-30 11:49:00 +00001524 script_descriptors =
Ben Murdoch257744e2011-11-30 15:57:28 +00001525 factory()->CopyAppendForeignDescriptor(
Steve Blocka7e24c12009-10-30 11:49:00 +00001526 script_descriptors,
Ben Murdoch257744e2011-11-30 15:57:28 +00001527 factory()->LookupAsciiSymbol("data"),
1528 foreign_data,
Steve Blocka7e24c12009-10-30 11:49:00 +00001529 common_attributes);
Ben Murdoch257744e2011-11-30 15:57:28 +00001530 Handle<Foreign> foreign_type =
1531 factory()->NewForeign(&Accessors::ScriptType);
Steve Blocka7e24c12009-10-30 11:49:00 +00001532 script_descriptors =
Ben Murdoch257744e2011-11-30 15:57:28 +00001533 factory()->CopyAppendForeignDescriptor(
Steve Blocka7e24c12009-10-30 11:49:00 +00001534 script_descriptors,
Ben Murdoch257744e2011-11-30 15:57:28 +00001535 factory()->LookupAsciiSymbol("type"),
1536 foreign_type,
Steve Blocka7e24c12009-10-30 11:49:00 +00001537 common_attributes);
Ben Murdoch257744e2011-11-30 15:57:28 +00001538 Handle<Foreign> foreign_compilation_type =
1539 factory()->NewForeign(&Accessors::ScriptCompilationType);
Steve Blocka7e24c12009-10-30 11:49:00 +00001540 script_descriptors =
Ben Murdoch257744e2011-11-30 15:57:28 +00001541 factory()->CopyAppendForeignDescriptor(
Steve Blocka7e24c12009-10-30 11:49:00 +00001542 script_descriptors,
Ben Murdoch257744e2011-11-30 15:57:28 +00001543 factory()->LookupAsciiSymbol("compilation_type"),
1544 foreign_compilation_type,
Steve Blocka7e24c12009-10-30 11:49:00 +00001545 common_attributes);
Ben Murdoch257744e2011-11-30 15:57:28 +00001546 Handle<Foreign> foreign_line_ends =
1547 factory()->NewForeign(&Accessors::ScriptLineEnds);
Steve Blocka7e24c12009-10-30 11:49:00 +00001548 script_descriptors =
Ben Murdoch257744e2011-11-30 15:57:28 +00001549 factory()->CopyAppendForeignDescriptor(
Steve Blocka7e24c12009-10-30 11:49:00 +00001550 script_descriptors,
Ben Murdoch257744e2011-11-30 15:57:28 +00001551 factory()->LookupAsciiSymbol("line_ends"),
1552 foreign_line_ends,
Steve Blocka7e24c12009-10-30 11:49:00 +00001553 common_attributes);
Ben Murdoch257744e2011-11-30 15:57:28 +00001554 Handle<Foreign> foreign_context_data =
1555 factory()->NewForeign(&Accessors::ScriptContextData);
Steve Blocka7e24c12009-10-30 11:49:00 +00001556 script_descriptors =
Ben Murdoch257744e2011-11-30 15:57:28 +00001557 factory()->CopyAppendForeignDescriptor(
Steve Blocka7e24c12009-10-30 11:49:00 +00001558 script_descriptors,
Ben Murdoch257744e2011-11-30 15:57:28 +00001559 factory()->LookupAsciiSymbol("context_data"),
1560 foreign_context_data,
Steve Blocka7e24c12009-10-30 11:49:00 +00001561 common_attributes);
Ben Murdoch257744e2011-11-30 15:57:28 +00001562 Handle<Foreign> foreign_eval_from_script =
1563 factory()->NewForeign(&Accessors::ScriptEvalFromScript);
Steve Blocka7e24c12009-10-30 11:49:00 +00001564 script_descriptors =
Ben Murdoch257744e2011-11-30 15:57:28 +00001565 factory()->CopyAppendForeignDescriptor(
Steve Blocka7e24c12009-10-30 11:49:00 +00001566 script_descriptors,
Ben Murdoch257744e2011-11-30 15:57:28 +00001567 factory()->LookupAsciiSymbol("eval_from_script"),
1568 foreign_eval_from_script,
Steve Blocka7e24c12009-10-30 11:49:00 +00001569 common_attributes);
Ben Murdoch257744e2011-11-30 15:57:28 +00001570 Handle<Foreign> foreign_eval_from_script_position =
1571 factory()->NewForeign(&Accessors::ScriptEvalFromScriptPosition);
Steve Blocka7e24c12009-10-30 11:49:00 +00001572 script_descriptors =
Ben Murdoch257744e2011-11-30 15:57:28 +00001573 factory()->CopyAppendForeignDescriptor(
Steve Blocka7e24c12009-10-30 11:49:00 +00001574 script_descriptors,
Ben Murdoch257744e2011-11-30 15:57:28 +00001575 factory()->LookupAsciiSymbol("eval_from_script_position"),
1576 foreign_eval_from_script_position,
Steve Blockd0582a62009-12-15 09:54:21 +00001577 common_attributes);
Ben Murdoch257744e2011-11-30 15:57:28 +00001578 Handle<Foreign> foreign_eval_from_function_name =
1579 factory()->NewForeign(&Accessors::ScriptEvalFromFunctionName);
Steve Blockd0582a62009-12-15 09:54:21 +00001580 script_descriptors =
Ben Murdoch257744e2011-11-30 15:57:28 +00001581 factory()->CopyAppendForeignDescriptor(
Steve Blockd0582a62009-12-15 09:54:21 +00001582 script_descriptors,
Ben Murdoch257744e2011-11-30 15:57:28 +00001583 factory()->LookupAsciiSymbol("eval_from_function_name"),
1584 foreign_eval_from_function_name,
Steve Blocka7e24c12009-10-30 11:49:00 +00001585 common_attributes);
1586
1587 Handle<Map> script_map = Handle<Map>(script_fun->initial_map());
1588 script_map->set_instance_descriptors(*script_descriptors);
1589
1590 // Allocate the empty script.
Ben Murdoch257744e2011-11-30 15:57:28 +00001591 Handle<Script> script = factory()->NewScript(factory()->empty_string());
Steve Blocka7e24c12009-10-30 11:49:00 +00001592 script->set_type(Smi::FromInt(Script::TYPE_NATIVE));
Ben Murdoch257744e2011-11-30 15:57:28 +00001593 heap()->public_set_empty_script(*script);
Steve Blocka7e24c12009-10-30 11:49:00 +00001594 }
Steve Block6ded16b2010-05-10 14:33:55 +01001595 {
1596 // Builtin function for OpaqueReference -- a JSValue-based object,
1597 // that keeps its field isolated from JavaScript code. It may store
1598 // objects, that JavaScript code may not access.
1599 Handle<JSFunction> opaque_reference_fun =
1600 InstallFunction(builtins, "OpaqueReference", JS_VALUE_TYPE,
Steve Block44f0eee2011-05-26 01:26:41 +01001601 JSValue::kSize,
Ben Murdoch257744e2011-11-30 15:57:28 +00001602 isolate()->initial_object_prototype(),
Steve Block44f0eee2011-05-26 01:26:41 +01001603 Builtins::kIllegal, false);
Steve Block6ded16b2010-05-10 14:33:55 +01001604 Handle<JSObject> prototype =
Ben Murdoch257744e2011-11-30 15:57:28 +00001605 factory()->NewJSObject(isolate()->object_function(), TENURED);
Steve Block6ded16b2010-05-10 14:33:55 +01001606 SetPrototype(opaque_reference_fun, prototype);
1607 global_context()->set_opaque_reference_function(*opaque_reference_fun);
1608 }
1609
Ben Murdoche0cee9b2011-05-25 10:26:03 +01001610 { // --- I n t e r n a l A r r a y ---
1611 // An array constructor on the builtins object that works like
1612 // the public Array constructor, except that its prototype
1613 // doesn't inherit from Object.prototype.
1614 // To be used only for internal work by builtins. Instances
1615 // must not be leaked to user code.
1616 // Only works correctly when called as a constructor. The normal
1617 // Array code uses Array.prototype as prototype when called as
1618 // a function.
1619 Handle<JSFunction> array_function =
1620 InstallFunction(builtins,
1621 "InternalArray",
1622 JS_ARRAY_TYPE,
1623 JSArray::kSize,
Ben Murdoch257744e2011-11-30 15:57:28 +00001624 isolate()->initial_object_prototype(),
Steve Block44f0eee2011-05-26 01:26:41 +01001625 Builtins::kArrayCode,
Ben Murdoche0cee9b2011-05-25 10:26:03 +01001626 true);
1627 Handle<JSObject> prototype =
Ben Murdoch257744e2011-11-30 15:57:28 +00001628 factory()->NewJSObject(isolate()->object_function(), TENURED);
Ben Murdoche0cee9b2011-05-25 10:26:03 +01001629 SetPrototype(array_function, prototype);
1630
1631 array_function->shared()->set_construct_stub(
Ben Murdoch257744e2011-11-30 15:57:28 +00001632 isolate()->builtins()->builtin(Builtins::kArrayConstructCode));
Ben Murdoche0cee9b2011-05-25 10:26:03 +01001633 array_function->shared()->DontAdaptArguments();
1634
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001635 // InternalArrays should not use Smi-Only array optimizations. There are too
1636 // many places in the C++ runtime code (e.g. RegEx) that assume that
1637 // elements in InternalArrays can be set to non-Smi values without going
1638 // through a common bottleneck that would make the SMI_ONLY -> FAST_ELEMENT
1639 // transition easy to trap. Moreover, they rarely are smi-only.
1640 MaybeObject* maybe_map =
1641 array_function->initial_map()->CopyDropTransitions();
1642 Map* new_map;
1643 if (!maybe_map->To<Map>(&new_map)) return maybe_map;
1644 new_map->set_elements_kind(FAST_ELEMENTS);
1645 array_function->set_initial_map(new_map);
1646
Ben Murdoche0cee9b2011-05-25 10:26:03 +01001647 // Make "length" magic on instances.
1648 Handle<DescriptorArray> array_descriptors =
Ben Murdoch257744e2011-11-30 15:57:28 +00001649 factory()->CopyAppendForeignDescriptor(
1650 factory()->empty_descriptor_array(),
1651 factory()->length_symbol(),
1652 factory()->NewForeign(&Accessors::ArrayLength),
Ben Murdoche0cee9b2011-05-25 10:26:03 +01001653 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE));
1654
1655 array_function->initial_map()->set_instance_descriptors(
1656 *array_descriptors);
1657 }
1658
Steve Block6ded16b2010-05-10 14:33:55 +01001659 if (FLAG_disable_native_files) {
1660 PrintF("Warning: Running without installed natives!\n");
1661 return true;
1662 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001663
Andrei Popescu31002712010-02-23 13:46:05 +00001664 // Install natives.
1665 for (int i = Natives::GetDebuggerCount();
1666 i < Natives::GetBuiltinsCount();
1667 i++) {
Ben Murdoch257744e2011-11-30 15:57:28 +00001668 if (!CompileBuiltin(isolate(), i)) return false;
Andrei Popescu402d9372010-02-26 13:31:12 +00001669 // TODO(ager): We really only need to install the JS builtin
1670 // functions on the builtins object after compiling and running
1671 // runtime.js.
1672 if (!InstallJSBuiltins(builtins)) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00001673 }
1674
1675 InstallNativeFunctions();
1676
Iain Merrick75681382010-08-19 15:07:18 +01001677 // Store the map for the string prototype after the natives has been compiled
1678 // and the String function has been setup.
1679 Handle<JSFunction> string_function(global_context()->string_function());
1680 ASSERT(JSObject::cast(
1681 string_function->initial_map()->prototype())->HasFastProperties());
1682 global_context()->set_string_function_prototype_map(
1683 HeapObject::cast(string_function->initial_map()->prototype())->map());
1684
Steve Blocka7e24c12009-10-30 11:49:00 +00001685 // Install Function.prototype.call and apply.
Ben Murdoch257744e2011-11-30 15:57:28 +00001686 { Handle<String> key = factory()->function_class_symbol();
Steve Blocka7e24c12009-10-30 11:49:00 +00001687 Handle<JSFunction> function =
Ben Murdoch257744e2011-11-30 15:57:28 +00001688 Handle<JSFunction>::cast(GetProperty(isolate()->global(), key));
Steve Blocka7e24c12009-10-30 11:49:00 +00001689 Handle<JSObject> proto =
1690 Handle<JSObject>(JSObject::cast(function->instance_prototype()));
1691
1692 // Install the call and the apply functions.
1693 Handle<JSFunction> call =
1694 InstallFunction(proto, "call", JS_OBJECT_TYPE, JSObject::kHeaderSize,
Steve Block6ded16b2010-05-10 14:33:55 +01001695 Handle<JSObject>::null(),
Steve Block44f0eee2011-05-26 01:26:41 +01001696 Builtins::kFunctionCall,
Steve Blocka7e24c12009-10-30 11:49:00 +00001697 false);
1698 Handle<JSFunction> apply =
1699 InstallFunction(proto, "apply", JS_OBJECT_TYPE, JSObject::kHeaderSize,
Steve Block6ded16b2010-05-10 14:33:55 +01001700 Handle<JSObject>::null(),
Steve Block44f0eee2011-05-26 01:26:41 +01001701 Builtins::kFunctionApply,
Steve Blocka7e24c12009-10-30 11:49:00 +00001702 false);
1703
1704 // Make sure that Function.prototype.call appears to be compiled.
1705 // The code will never be called, but inline caching for call will
1706 // only work if it appears to be compiled.
1707 call->shared()->DontAdaptArguments();
1708 ASSERT(call->is_compiled());
1709
1710 // Set the expected parameters for apply to 2; required by builtin.
1711 apply->shared()->set_formal_parameter_count(2);
1712
1713 // Set the lengths for the functions to satisfy ECMA-262.
1714 call->shared()->set_length(1);
1715 apply->shared()->set_length(2);
1716 }
1717
Ben Murdoch42effa52011-08-19 16:40:31 +01001718 InstallBuiltinFunctionIds();
1719
Steve Block6ded16b2010-05-10 14:33:55 +01001720 // Create a constructor for RegExp results (a variant of Array that
1721 // predefines the two properties index and match).
1722 {
1723 // RegExpResult initial map.
1724
1725 // Find global.Array.prototype to inherit from.
1726 Handle<JSFunction> array_constructor(global_context()->array_function());
1727 Handle<JSObject> array_prototype(
1728 JSObject::cast(array_constructor->instance_prototype()));
1729
1730 // Add initial map.
1731 Handle<Map> initial_map =
Ben Murdoch257744e2011-11-30 15:57:28 +00001732 factory()->NewMap(JS_ARRAY_TYPE, JSRegExpResult::kSize);
Steve Block6ded16b2010-05-10 14:33:55 +01001733 initial_map->set_constructor(*array_constructor);
1734
1735 // Set prototype on map.
1736 initial_map->set_non_instance_prototype(false);
1737 initial_map->set_prototype(*array_prototype);
1738
1739 // Update map with length accessor from Array and add "index" and "input".
1740 Handle<Map> array_map(global_context()->js_array_map());
1741 Handle<DescriptorArray> array_descriptors(
1742 array_map->instance_descriptors());
1743 ASSERT_EQ(1, array_descriptors->number_of_descriptors());
1744
1745 Handle<DescriptorArray> reresult_descriptors =
Ben Murdoch257744e2011-11-30 15:57:28 +00001746 factory()->NewDescriptorArray(3);
Steve Block6ded16b2010-05-10 14:33:55 +01001747
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001748 DescriptorArray::WhitenessWitness witness(*reresult_descriptors);
1749
1750 reresult_descriptors->CopyFrom(0, *array_descriptors, 0, witness);
Steve Block6ded16b2010-05-10 14:33:55 +01001751
1752 int enum_index = 0;
1753 {
Ben Murdoch257744e2011-11-30 15:57:28 +00001754 FieldDescriptor index_field(heap()->index_symbol(),
Steve Block6ded16b2010-05-10 14:33:55 +01001755 JSRegExpResult::kIndexIndex,
1756 NONE,
1757 enum_index++);
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001758 reresult_descriptors->Set(1, &index_field, witness);
Steve Block6ded16b2010-05-10 14:33:55 +01001759 }
1760
1761 {
Ben Murdoch257744e2011-11-30 15:57:28 +00001762 FieldDescriptor input_field(heap()->input_symbol(),
Steve Block6ded16b2010-05-10 14:33:55 +01001763 JSRegExpResult::kInputIndex,
1764 NONE,
1765 enum_index++);
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001766 reresult_descriptors->Set(2, &input_field, witness);
Steve Block6ded16b2010-05-10 14:33:55 +01001767 }
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001768 reresult_descriptors->Sort(witness);
Steve Block6ded16b2010-05-10 14:33:55 +01001769
1770 initial_map->set_inobject_properties(2);
1771 initial_map->set_pre_allocated_property_fields(2);
1772 initial_map->set_unused_property_fields(0);
1773 initial_map->set_instance_descriptors(*reresult_descriptors);
1774
1775 global_context()->set_regexp_result_map(*initial_map);
1776 }
1777
Steve Blocka7e24c12009-10-30 11:49:00 +00001778#ifdef DEBUG
1779 builtins->Verify();
1780#endif
Andrei Popescu31002712010-02-23 13:46:05 +00001781
Steve Blocka7e24c12009-10-30 11:49:00 +00001782 return true;
1783}
1784
1785
Ben Murdoch257744e2011-11-30 15:57:28 +00001786bool Genesis::InstallExperimentalNatives() {
1787 for (int i = ExperimentalNatives::GetDebuggerCount();
1788 i < ExperimentalNatives::GetBuiltinsCount();
1789 i++) {
1790 if (FLAG_harmony_proxies &&
1791 strcmp(ExperimentalNatives::GetScriptName(i).start(),
1792 "native proxy.js") == 0) {
1793 if (!CompileExperimentalBuiltin(isolate(), i)) return false;
1794 }
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001795 if (FLAG_harmony_collections &&
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001796 strcmp(ExperimentalNatives::GetScriptName(i).start(),
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001797 "native collection.js") == 0) {
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001798 if (!CompileExperimentalBuiltin(isolate(), i)) return false;
1799 }
Ben Murdoch257744e2011-11-30 15:57:28 +00001800 }
1801
1802 InstallExperimentalNativeFunctions();
1803
1804 return true;
1805}
1806
1807
Ben Murdochb0fe1622011-05-05 13:52:32 +01001808static Handle<JSObject> ResolveBuiltinIdHolder(
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001809 Handle<Context> global_context,
1810 const char* holder_expr) {
Ben Murdoch257744e2011-11-30 15:57:28 +00001811 Factory* factory = global_context->GetIsolate()->factory();
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001812 Handle<GlobalObject> global(global_context->global());
1813 const char* period_pos = strchr(holder_expr, '.');
1814 if (period_pos == NULL) {
1815 return Handle<JSObject>::cast(
Steve Block44f0eee2011-05-26 01:26:41 +01001816 GetProperty(global, factory->LookupAsciiSymbol(holder_expr)));
Steve Block59151502010-09-22 15:07:15 +01001817 }
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001818 ASSERT_EQ(".prototype", period_pos);
1819 Vector<const char> property(holder_expr,
1820 static_cast<int>(period_pos - holder_expr));
1821 Handle<JSFunction> function = Handle<JSFunction>::cast(
Steve Block44f0eee2011-05-26 01:26:41 +01001822 GetProperty(global, factory->LookupSymbol(property)));
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001823 return Handle<JSObject>(JSObject::cast(function->prototype()));
1824}
1825
1826
Ben Murdochb0fe1622011-05-05 13:52:32 +01001827static void InstallBuiltinFunctionId(Handle<JSObject> holder,
1828 const char* function_name,
1829 BuiltinFunctionId id) {
Ben Murdoch257744e2011-11-30 15:57:28 +00001830 Factory* factory = holder->GetIsolate()->factory();
1831 Handle<String> name = factory->LookupAsciiSymbol(function_name);
John Reck59135872010-11-02 12:39:01 -07001832 Object* function_object = holder->GetProperty(*name)->ToObjectUnchecked();
1833 Handle<JSFunction> function(JSFunction::cast(function_object));
Kristian Monsen25f61362010-05-21 11:50:48 +01001834 function->shared()->set_function_data(Smi::FromInt(id));
1835}
1836
1837
Ben Murdochb0fe1622011-05-05 13:52:32 +01001838void Genesis::InstallBuiltinFunctionIds() {
Kristian Monsen25f61362010-05-21 11:50:48 +01001839 HandleScope scope;
Ben Murdochb0fe1622011-05-05 13:52:32 +01001840#define INSTALL_BUILTIN_ID(holder_expr, fun_name, name) \
1841 { \
1842 Handle<JSObject> holder = ResolveBuiltinIdHolder( \
1843 global_context(), #holder_expr); \
1844 BuiltinFunctionId id = k##name; \
1845 InstallBuiltinFunctionId(holder, #fun_name, id); \
Kristian Monsen25f61362010-05-21 11:50:48 +01001846 }
Ben Murdochb0fe1622011-05-05 13:52:32 +01001847 FUNCTIONS_WITH_ID_LIST(INSTALL_BUILTIN_ID)
1848#undef INSTALL_BUILTIN_ID
Kristian Monsen25f61362010-05-21 11:50:48 +01001849}
1850
1851
Steve Block6ded16b2010-05-10 14:33:55 +01001852// Do not forget to update macros.py with named constant
1853// of cache id.
1854#define JSFUNCTION_RESULT_CACHE_LIST(F) \
1855 F(16, global_context()->regexp_function())
1856
1857
Ben Murdoch257744e2011-11-30 15:57:28 +00001858static FixedArray* CreateCache(int size, Handle<JSFunction> factory_function) {
1859 Factory* factory = factory_function->GetIsolate()->factory();
Steve Block6ded16b2010-05-10 14:33:55 +01001860 // Caches are supposed to live for a long time, allocate in old space.
1861 int array_size = JSFunctionResultCache::kEntriesIndex + 2 * size;
1862 // Cannot use cast as object is not fully initialized yet.
1863 JSFunctionResultCache* cache = reinterpret_cast<JSFunctionResultCache*>(
Ben Murdoch257744e2011-11-30 15:57:28 +00001864 *factory->NewFixedArrayWithHoles(array_size, TENURED));
1865 cache->set(JSFunctionResultCache::kFactoryIndex, *factory_function);
Steve Block6ded16b2010-05-10 14:33:55 +01001866 cache->MakeZeroSize();
1867 return cache;
1868}
1869
1870
1871void Genesis::InstallJSFunctionResultCaches() {
1872 const int kNumberOfCaches = 0 +
1873#define F(size, func) + 1
1874 JSFUNCTION_RESULT_CACHE_LIST(F)
1875#undef F
1876 ;
1877
Steve Block44f0eee2011-05-26 01:26:41 +01001878 Handle<FixedArray> caches = FACTORY->NewFixedArray(kNumberOfCaches, TENURED);
Steve Block6ded16b2010-05-10 14:33:55 +01001879
1880 int index = 0;
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001881
Ben Murdoch257744e2011-11-30 15:57:28 +00001882#define F(size, func) do { \
1883 FixedArray* cache = CreateCache((size), Handle<JSFunction>(func)); \
1884 caches->set(index++, cache); \
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001885 } while (false)
1886
1887 JSFUNCTION_RESULT_CACHE_LIST(F);
1888
Steve Block6ded16b2010-05-10 14:33:55 +01001889#undef F
1890
1891 global_context()->set_jsfunction_result_caches(*caches);
1892}
1893
1894
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001895void Genesis::InitializeNormalizedMapCaches() {
1896 Handle<FixedArray> array(
Steve Block44f0eee2011-05-26 01:26:41 +01001897 FACTORY->NewFixedArray(NormalizedMapCache::kEntries, TENURED));
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001898 global_context()->set_normalized_map_cache(NormalizedMapCache::cast(*array));
1899}
1900
1901
Andrei Popescu31002712010-02-23 13:46:05 +00001902bool Bootstrapper::InstallExtensions(Handle<Context> global_context,
1903 v8::ExtensionConfiguration* extensions) {
Ben Murdoch257744e2011-11-30 15:57:28 +00001904 Isolate* isolate = global_context->GetIsolate();
Andrei Popescu31002712010-02-23 13:46:05 +00001905 BootstrapperActive active;
Steve Block44f0eee2011-05-26 01:26:41 +01001906 SaveContext saved_context(isolate);
1907 isolate->set_context(*global_context);
Andrei Popescu31002712010-02-23 13:46:05 +00001908 if (!Genesis::InstallExtensions(global_context, extensions)) return false;
1909 Genesis::InstallSpecialObjects(global_context);
1910 return true;
1911}
1912
1913
1914void Genesis::InstallSpecialObjects(Handle<Context> global_context) {
Ben Murdoch257744e2011-11-30 15:57:28 +00001915 Factory* factory = global_context->GetIsolate()->factory();
Steve Blocka7e24c12009-10-30 11:49:00 +00001916 HandleScope scope;
1917 Handle<JSGlobalObject> js_global(
Andrei Popescu31002712010-02-23 13:46:05 +00001918 JSGlobalObject::cast(global_context->global()));
Steve Blocka7e24c12009-10-30 11:49:00 +00001919 // Expose the natives in global if a name for it is specified.
1920 if (FLAG_expose_natives_as != NULL && strlen(FLAG_expose_natives_as) != 0) {
1921 Handle<String> natives_string =
Steve Block44f0eee2011-05-26 01:26:41 +01001922 factory->LookupAsciiSymbol(FLAG_expose_natives_as);
Steve Block1e0659c2011-05-24 12:43:12 +01001923 SetLocalPropertyNoThrow(js_global, natives_string,
1924 Handle<JSObject>(js_global->builtins()), DONT_ENUM);
Steve Blocka7e24c12009-10-30 11:49:00 +00001925 }
1926
1927 Handle<Object> Error = GetProperty(js_global, "Error");
1928 if (Error->IsJSObject()) {
Steve Block44f0eee2011-05-26 01:26:41 +01001929 Handle<String> name = factory->LookupAsciiSymbol("stackTraceLimit");
Steve Block1e0659c2011-05-24 12:43:12 +01001930 SetLocalPropertyNoThrow(Handle<JSObject>::cast(Error),
1931 name,
1932 Handle<Smi>(Smi::FromInt(FLAG_stack_trace_limit)),
1933 NONE);
Steve Blocka7e24c12009-10-30 11:49:00 +00001934 }
1935
1936#ifdef ENABLE_DEBUGGER_SUPPORT
1937 // Expose the debug global object in global if a name for it is specified.
1938 if (FLAG_expose_debug_as != NULL && strlen(FLAG_expose_debug_as) != 0) {
Steve Block44f0eee2011-05-26 01:26:41 +01001939 Debug* debug = Isolate::Current()->debug();
Steve Blocka7e24c12009-10-30 11:49:00 +00001940 // If loading fails we just bail out without installing the
1941 // debugger but without tanking the whole context.
Steve Block44f0eee2011-05-26 01:26:41 +01001942 if (!debug->Load()) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00001943 // Set the security token for the debugger context to the same as
1944 // the shell global context to allow calling between these (otherwise
1945 // exposing debug global object doesn't make much sense).
Steve Block44f0eee2011-05-26 01:26:41 +01001946 debug->debug_context()->set_security_token(
Andrei Popescu31002712010-02-23 13:46:05 +00001947 global_context->security_token());
Steve Blocka7e24c12009-10-30 11:49:00 +00001948
1949 Handle<String> debug_string =
Steve Block44f0eee2011-05-26 01:26:41 +01001950 factory->LookupAsciiSymbol(FLAG_expose_debug_as);
1951 Handle<Object> global_proxy(debug->debug_context()->global_proxy());
Steve Block1e0659c2011-05-24 12:43:12 +01001952 SetLocalPropertyNoThrow(js_global, debug_string, global_proxy, DONT_ENUM);
Steve Blocka7e24c12009-10-30 11:49:00 +00001953 }
1954#endif
Steve Blocka7e24c12009-10-30 11:49:00 +00001955}
1956
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001957static uint32_t Hash(RegisteredExtension* extension) {
1958 return v8::internal::ComputePointerHash(extension);
1959}
1960
1961static bool MatchRegisteredExtensions(void* key1, void* key2) {
1962 return key1 == key2;
1963}
1964
1965Genesis::ExtensionStates::ExtensionStates()
1966 : allocator_(),
1967 map_(MatchRegisteredExtensions, &allocator_, 8)
1968 {}
1969
1970Genesis::ExtensionTraversalState Genesis::ExtensionStates::get_state(
1971 RegisteredExtension* extension) {
1972 i::HashMap::Entry* entry = map_.Lookup(extension, Hash(extension), false);
1973 if (entry == NULL) {
1974 return UNVISITED;
1975 }
1976 return static_cast<ExtensionTraversalState>(
1977 reinterpret_cast<intptr_t>(entry->value));
1978}
1979
1980void Genesis::ExtensionStates::set_state(RegisteredExtension* extension,
1981 ExtensionTraversalState state) {
1982 map_.Lookup(extension, Hash(extension), true)->value =
1983 reinterpret_cast<void*>(static_cast<intptr_t>(state));
1984}
Steve Blocka7e24c12009-10-30 11:49:00 +00001985
Andrei Popescu31002712010-02-23 13:46:05 +00001986bool Genesis::InstallExtensions(Handle<Context> global_context,
1987 v8::ExtensionConfiguration* extensions) {
Steve Block44f0eee2011-05-26 01:26:41 +01001988 // TODO(isolates): Extensions on multiple isolates may take a little more
1989 // effort. (The external API reads 'ignore'-- does that mean
1990 // we can break the interface?)
1991
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001992
1993 ExtensionStates extension_states; // All extensions have state UNVISITED.
1994 // Install auto extensions.
Steve Blocka7e24c12009-10-30 11:49:00 +00001995 v8::RegisteredExtension* current = v8::RegisteredExtension::first_extension();
1996 while (current != NULL) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001997 if (current->extension()->auto_enable())
Ben Murdoch592a9fc2012-03-05 11:04:45 +00001998 InstallExtension(current, &extension_states);
Steve Blocka7e24c12009-10-30 11:49:00 +00001999 current = current->next();
2000 }
2001
Ben Murdoch592a9fc2012-03-05 11:04:45 +00002002 if (FLAG_expose_gc) InstallExtension("v8/gc", &extension_states);
2003 if (FLAG_expose_externalize_string) {
2004 InstallExtension("v8/externalize", &extension_states);
2005 }
Steve Blocka7e24c12009-10-30 11:49:00 +00002006
2007 if (extensions == NULL) return true;
2008 // Install required extensions
2009 int count = v8::ImplementationUtilities::GetNameCount(extensions);
2010 const char** names = v8::ImplementationUtilities::GetNames(extensions);
2011 for (int i = 0; i < count; i++) {
Ben Murdoch592a9fc2012-03-05 11:04:45 +00002012 if (!InstallExtension(names[i], &extension_states))
Steve Blocka7e24c12009-10-30 11:49:00 +00002013 return false;
2014 }
2015
2016 return true;
2017}
2018
2019
2020// Installs a named extension. This methods is unoptimized and does
2021// not scale well if we want to support a large number of extensions.
Ben Murdoch592a9fc2012-03-05 11:04:45 +00002022bool Genesis::InstallExtension(const char* name,
2023 ExtensionStates* extension_states) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002024 v8::RegisteredExtension* current = v8::RegisteredExtension::first_extension();
2025 // Loop until we find the relevant extension
2026 while (current != NULL) {
2027 if (strcmp(name, current->extension()->name()) == 0) break;
2028 current = current->next();
2029 }
2030 // Didn't find the extension; fail.
2031 if (current == NULL) {
2032 v8::Utils::ReportApiFailure(
2033 "v8::Context::New()", "Cannot find required extension");
2034 return false;
2035 }
Ben Murdoch592a9fc2012-03-05 11:04:45 +00002036 return InstallExtension(current, extension_states);
Steve Blocka7e24c12009-10-30 11:49:00 +00002037}
2038
2039
Ben Murdoch592a9fc2012-03-05 11:04:45 +00002040bool Genesis::InstallExtension(v8::RegisteredExtension* current,
2041 ExtensionStates* extension_states) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002042 HandleScope scope;
2043
Ben Murdoch592a9fc2012-03-05 11:04:45 +00002044 if (extension_states->get_state(current) == INSTALLED) return true;
Steve Blocka7e24c12009-10-30 11:49:00 +00002045 // The current node has already been visited so there must be a
2046 // cycle in the dependency graph; fail.
Ben Murdoch592a9fc2012-03-05 11:04:45 +00002047 if (extension_states->get_state(current) == VISITED) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002048 v8::Utils::ReportApiFailure(
2049 "v8::Context::New()", "Circular extension dependency");
2050 return false;
2051 }
Ben Murdoch592a9fc2012-03-05 11:04:45 +00002052 ASSERT(extension_states->get_state(current) == UNVISITED);
2053 extension_states->set_state(current, VISITED);
Steve Blocka7e24c12009-10-30 11:49:00 +00002054 v8::Extension* extension = current->extension();
2055 // Install the extension's dependencies
2056 for (int i = 0; i < extension->dependency_count(); i++) {
Ben Murdoch592a9fc2012-03-05 11:04:45 +00002057 if (!InstallExtension(extension->dependencies()[i], extension_states))
2058 return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00002059 }
Steve Block44f0eee2011-05-26 01:26:41 +01002060 Isolate* isolate = Isolate::Current();
Ben Murdoch592a9fc2012-03-05 11:04:45 +00002061 Handle<String> source_code =
2062 isolate->factory()->NewExternalStringFromAscii(extension->source());
2063 bool result = CompileScriptCached(
2064 CStrVector(extension->name()),
2065 source_code,
2066 isolate->bootstrapper()->extensions_cache(),
2067 extension,
2068 Handle<Context>(isolate->context()),
2069 false);
Steve Block44f0eee2011-05-26 01:26:41 +01002070 ASSERT(isolate->has_pending_exception() != result);
Steve Blocka7e24c12009-10-30 11:49:00 +00002071 if (!result) {
Ben Murdoch592a9fc2012-03-05 11:04:45 +00002072 // We print out the name of the extension that fail to install.
2073 // When an error is thrown during bootstrapping we automatically print
2074 // the line number at which this happened to the console in the isolate
2075 // error throwing functionality.
2076 OS::PrintError("Error installing extension '%s'.\n",
2077 current->extension()->name());
Steve Block44f0eee2011-05-26 01:26:41 +01002078 isolate->clear_pending_exception();
Steve Blocka7e24c12009-10-30 11:49:00 +00002079 }
Ben Murdoch592a9fc2012-03-05 11:04:45 +00002080 extension_states->set_state(current, INSTALLED);
2081 isolate->NotifyExtensionInstalled();
Steve Blocka7e24c12009-10-30 11:49:00 +00002082 return result;
2083}
2084
2085
Andrei Popescu402d9372010-02-26 13:31:12 +00002086bool Genesis::InstallJSBuiltins(Handle<JSBuiltinsObject> builtins) {
2087 HandleScope scope;
Ben Murdoch257744e2011-11-30 15:57:28 +00002088 Factory* factory = builtins->GetIsolate()->factory();
Andrei Popescu402d9372010-02-26 13:31:12 +00002089 for (int i = 0; i < Builtins::NumberOfJavaScriptBuiltins(); i++) {
2090 Builtins::JavaScript id = static_cast<Builtins::JavaScript>(i);
Ben Murdoch257744e2011-11-30 15:57:28 +00002091 Handle<String> name = factory->LookupAsciiSymbol(Builtins::GetName(id));
John Reck59135872010-11-02 12:39:01 -07002092 Object* function_object = builtins->GetPropertyNoExceptionThrown(*name);
Andrei Popescu402d9372010-02-26 13:31:12 +00002093 Handle<JSFunction> function
John Reck59135872010-11-02 12:39:01 -07002094 = Handle<JSFunction>(JSFunction::cast(function_object));
Andrei Popescu402d9372010-02-26 13:31:12 +00002095 builtins->set_javascript_builtin(id, *function);
2096 Handle<SharedFunctionInfo> shared
2097 = Handle<SharedFunctionInfo>(function->shared());
Ben Murdoch592a9fc2012-03-05 11:04:45 +00002098 if (!SharedFunctionInfo::EnsureCompiled(shared, CLEAR_EXCEPTION)) {
2099 return false;
2100 }
Iain Merrick75681382010-08-19 15:07:18 +01002101 // Set the code object on the function object.
Ben Murdochb0fe1622011-05-05 13:52:32 +01002102 function->ReplaceCode(function->shared()->code());
Steve Block6ded16b2010-05-10 14:33:55 +01002103 builtins->set_javascript_builtin_code(id, shared->code());
Andrei Popescu402d9372010-02-26 13:31:12 +00002104 }
2105 return true;
Andrei Popescu31002712010-02-23 13:46:05 +00002106}
2107
2108
Steve Blocka7e24c12009-10-30 11:49:00 +00002109bool Genesis::ConfigureGlobalObjects(
2110 v8::Handle<v8::ObjectTemplate> global_proxy_template) {
2111 Handle<JSObject> global_proxy(
2112 JSObject::cast(global_context()->global_proxy()));
Andrei Popescu402d9372010-02-26 13:31:12 +00002113 Handle<JSObject> inner_global(JSObject::cast(global_context()->global()));
Steve Blocka7e24c12009-10-30 11:49:00 +00002114
2115 if (!global_proxy_template.IsEmpty()) {
2116 // Configure the global proxy object.
2117 Handle<ObjectTemplateInfo> proxy_data =
2118 v8::Utils::OpenHandle(*global_proxy_template);
2119 if (!ConfigureApiObject(global_proxy, proxy_data)) return false;
2120
2121 // Configure the inner global object.
2122 Handle<FunctionTemplateInfo> proxy_constructor(
2123 FunctionTemplateInfo::cast(proxy_data->constructor()));
2124 if (!proxy_constructor->prototype_template()->IsUndefined()) {
2125 Handle<ObjectTemplateInfo> inner_data(
2126 ObjectTemplateInfo::cast(proxy_constructor->prototype_template()));
Andrei Popescu402d9372010-02-26 13:31:12 +00002127 if (!ConfigureApiObject(inner_global, inner_data)) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00002128 }
2129 }
2130
Andrei Popescu402d9372010-02-26 13:31:12 +00002131 SetObjectPrototype(global_proxy, inner_global);
Steve Blocka7e24c12009-10-30 11:49:00 +00002132 return true;
2133}
2134
2135
2136bool Genesis::ConfigureApiObject(Handle<JSObject> object,
2137 Handle<ObjectTemplateInfo> object_template) {
2138 ASSERT(!object_template.is_null());
2139 ASSERT(object->IsInstanceOf(
2140 FunctionTemplateInfo::cast(object_template->constructor())));
2141
2142 bool pending_exception = false;
2143 Handle<JSObject> obj =
2144 Execution::InstantiateObject(object_template, &pending_exception);
2145 if (pending_exception) {
Ben Murdoch257744e2011-11-30 15:57:28 +00002146 ASSERT(isolate()->has_pending_exception());
2147 isolate()->clear_pending_exception();
Steve Blocka7e24c12009-10-30 11:49:00 +00002148 return false;
2149 }
2150 TransferObject(obj, object);
2151 return true;
2152}
2153
2154
2155void Genesis::TransferNamedProperties(Handle<JSObject> from,
2156 Handle<JSObject> to) {
2157 if (from->HasFastProperties()) {
2158 Handle<DescriptorArray> descs =
2159 Handle<DescriptorArray>(from->map()->instance_descriptors());
2160 for (int i = 0; i < descs->number_of_descriptors(); i++) {
2161 PropertyDetails details = PropertyDetails(descs->GetDetails(i));
2162 switch (details.type()) {
2163 case FIELD: {
2164 HandleScope inner;
2165 Handle<String> key = Handle<String>(descs->GetKey(i));
2166 int index = descs->GetFieldIndex(i);
2167 Handle<Object> value = Handle<Object>(from->FastPropertyAt(index));
Steve Block1e0659c2011-05-24 12:43:12 +01002168 SetLocalPropertyNoThrow(to, key, value, details.attributes());
Steve Blocka7e24c12009-10-30 11:49:00 +00002169 break;
2170 }
2171 case CONSTANT_FUNCTION: {
2172 HandleScope inner;
2173 Handle<String> key = Handle<String>(descs->GetKey(i));
2174 Handle<JSFunction> fun =
2175 Handle<JSFunction>(descs->GetConstantFunction(i));
Steve Block1e0659c2011-05-24 12:43:12 +01002176 SetLocalPropertyNoThrow(to, key, fun, details.attributes());
Steve Blocka7e24c12009-10-30 11:49:00 +00002177 break;
2178 }
2179 case CALLBACKS: {
Ben Murdoch592a9fc2012-03-05 11:04:45 +00002180 LookupResult result(isolate());
Steve Blocka7e24c12009-10-30 11:49:00 +00002181 to->LocalLookup(descs->GetKey(i), &result);
2182 // If the property is already there we skip it
Andrei Popescu402d9372010-02-26 13:31:12 +00002183 if (result.IsProperty()) continue;
Steve Blocka7e24c12009-10-30 11:49:00 +00002184 HandleScope inner;
Andrei Popescu31002712010-02-23 13:46:05 +00002185 ASSERT(!to->HasFastProperties());
2186 // Add to dictionary.
Steve Blocka7e24c12009-10-30 11:49:00 +00002187 Handle<String> key = Handle<String>(descs->GetKey(i));
Andrei Popescu31002712010-02-23 13:46:05 +00002188 Handle<Object> callbacks(descs->GetCallbacksObject(i));
2189 PropertyDetails d =
2190 PropertyDetails(details.attributes(), CALLBACKS, details.index());
2191 SetNormalizedProperty(to, key, callbacks, d);
Steve Blocka7e24c12009-10-30 11:49:00 +00002192 break;
2193 }
2194 case MAP_TRANSITION:
Ben Murdoch589d6972011-11-30 16:04:58 +00002195 case ELEMENTS_TRANSITION:
Steve Blocka7e24c12009-10-30 11:49:00 +00002196 case CONSTANT_TRANSITION:
2197 case NULL_DESCRIPTOR:
2198 // Ignore non-properties.
2199 break;
2200 case NORMAL:
2201 // Do not occur since the from object has fast properties.
Ben Murdoch257744e2011-11-30 15:57:28 +00002202 case HANDLER:
Steve Blocka7e24c12009-10-30 11:49:00 +00002203 case INTERCEPTOR:
Ben Murdoch257744e2011-11-30 15:57:28 +00002204 // No element in instance descriptors have proxy or interceptor type.
Steve Blocka7e24c12009-10-30 11:49:00 +00002205 UNREACHABLE();
2206 break;
2207 }
2208 }
2209 } else {
2210 Handle<StringDictionary> properties =
2211 Handle<StringDictionary>(from->property_dictionary());
2212 int capacity = properties->Capacity();
2213 for (int i = 0; i < capacity; i++) {
2214 Object* raw_key(properties->KeyAt(i));
2215 if (properties->IsKey(raw_key)) {
2216 ASSERT(raw_key->IsString());
2217 // If the property is already there we skip it.
Ben Murdoch592a9fc2012-03-05 11:04:45 +00002218 LookupResult result(isolate());
Steve Blocka7e24c12009-10-30 11:49:00 +00002219 to->LocalLookup(String::cast(raw_key), &result);
Andrei Popescu402d9372010-02-26 13:31:12 +00002220 if (result.IsProperty()) continue;
Steve Blocka7e24c12009-10-30 11:49:00 +00002221 // Set the property.
2222 Handle<String> key = Handle<String>(String::cast(raw_key));
2223 Handle<Object> value = Handle<Object>(properties->ValueAt(i));
2224 if (value->IsJSGlobalPropertyCell()) {
2225 value = Handle<Object>(JSGlobalPropertyCell::cast(*value)->value());
2226 }
2227 PropertyDetails details = properties->DetailsAt(i);
Steve Block1e0659c2011-05-24 12:43:12 +01002228 SetLocalPropertyNoThrow(to, key, value, details.attributes());
Steve Blocka7e24c12009-10-30 11:49:00 +00002229 }
2230 }
2231 }
2232}
2233
2234
2235void Genesis::TransferIndexedProperties(Handle<JSObject> from,
2236 Handle<JSObject> to) {
2237 // Cloning the elements array is sufficient.
2238 Handle<FixedArray> from_elements =
2239 Handle<FixedArray>(FixedArray::cast(from->elements()));
Steve Block44f0eee2011-05-26 01:26:41 +01002240 Handle<FixedArray> to_elements = FACTORY->CopyFixedArray(from_elements);
Steve Blocka7e24c12009-10-30 11:49:00 +00002241 to->set_elements(*to_elements);
2242}
2243
2244
2245void Genesis::TransferObject(Handle<JSObject> from, Handle<JSObject> to) {
2246 HandleScope outer;
Ben Murdoch257744e2011-11-30 15:57:28 +00002247 Factory* factory = from->GetIsolate()->factory();
Steve Blocka7e24c12009-10-30 11:49:00 +00002248
2249 ASSERT(!from->IsJSArray());
2250 ASSERT(!to->IsJSArray());
2251
2252 TransferNamedProperties(from, to);
2253 TransferIndexedProperties(from, to);
2254
2255 // Transfer the prototype (new map is needed).
2256 Handle<Map> old_to_map = Handle<Map>(to->map());
Ben Murdoch257744e2011-11-30 15:57:28 +00002257 Handle<Map> new_to_map = factory->CopyMapDropTransitions(old_to_map);
Steve Blocka7e24c12009-10-30 11:49:00 +00002258 new_to_map->set_prototype(from->map()->prototype());
2259 to->set_map(*new_to_map);
2260}
2261
2262
2263void Genesis::MakeFunctionInstancePrototypeWritable() {
Steve Block44f0eee2011-05-26 01:26:41 +01002264 // The maps with writable prototype are created in CreateEmptyFunction
2265 // and CreateStrictModeFunctionMaps respectively. Initially the maps are
2266 // created with read-only prototype for JS builtins processing.
2267 ASSERT(!function_instance_map_writable_prototype_.is_null());
2268 ASSERT(!strict_mode_function_instance_map_writable_prototype_.is_null());
Steve Blocka7e24c12009-10-30 11:49:00 +00002269
Steve Block44f0eee2011-05-26 01:26:41 +01002270 // Replace function instance maps to make prototype writable.
2271 global_context()->set_function_map(
2272 *function_instance_map_writable_prototype_);
2273 global_context()->set_strict_mode_function_map(
2274 *strict_mode_function_instance_map_writable_prototype_);
Steve Blocka7e24c12009-10-30 11:49:00 +00002275}
2276
2277
Ben Murdoch257744e2011-11-30 15:57:28 +00002278Genesis::Genesis(Isolate* isolate,
2279 Handle<Object> global_object,
Steve Blocka7e24c12009-10-30 11:49:00 +00002280 v8::Handle<v8::ObjectTemplate> global_template,
Ben Murdoch257744e2011-11-30 15:57:28 +00002281 v8::ExtensionConfiguration* extensions) : isolate_(isolate) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002282 result_ = Handle<Context>::null();
Steve Blocka7e24c12009-10-30 11:49:00 +00002283 // If V8 isn't running and cannot be initialized, just return.
2284 if (!V8::IsRunning() && !V8::Initialize(NULL)) return;
2285
2286 // Before creating the roots we must save the context and restore it
2287 // on all function exits.
2288 HandleScope scope;
Steve Block44f0eee2011-05-26 01:26:41 +01002289 SaveContext saved_context(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002290
Andrei Popescu31002712010-02-23 13:46:05 +00002291 Handle<Context> new_context = Snapshot::NewContextFromSnapshot();
2292 if (!new_context.is_null()) {
2293 global_context_ =
Steve Block44f0eee2011-05-26 01:26:41 +01002294 Handle<Context>::cast(isolate->global_handles()->Create(*new_context));
Ben Murdochb0fe1622011-05-05 13:52:32 +01002295 AddToWeakGlobalContextList(*global_context_);
Steve Block44f0eee2011-05-26 01:26:41 +01002296 isolate->set_context(*global_context_);
2297 isolate->counters()->contexts_created_by_snapshot()->Increment();
Andrei Popescu402d9372010-02-26 13:31:12 +00002298 Handle<GlobalObject> inner_global;
Andrei Popescu31002712010-02-23 13:46:05 +00002299 Handle<JSGlobalProxy> global_proxy =
2300 CreateNewGlobals(global_template,
2301 global_object,
Andrei Popescu402d9372010-02-26 13:31:12 +00002302 &inner_global);
2303
Andrei Popescu31002712010-02-23 13:46:05 +00002304 HookUpGlobalProxy(inner_global, global_proxy);
Andrei Popescu402d9372010-02-26 13:31:12 +00002305 HookUpInnerGlobal(inner_global);
2306
Andrei Popescu31002712010-02-23 13:46:05 +00002307 if (!ConfigureGlobalObjects(global_template)) return;
2308 } else {
2309 // We get here if there was no context snapshot.
2310 CreateRoots();
Ben Murdoch257744e2011-11-30 15:57:28 +00002311 Handle<JSFunction> empty_function = CreateEmptyFunction(isolate);
Steve Block44f0eee2011-05-26 01:26:41 +01002312 CreateStrictModeFunctionMaps(empty_function);
Andrei Popescu31002712010-02-23 13:46:05 +00002313 Handle<GlobalObject> inner_global;
2314 Handle<JSGlobalProxy> global_proxy =
2315 CreateNewGlobals(global_template, global_object, &inner_global);
2316 HookUpGlobalProxy(inner_global, global_proxy);
2317 InitializeGlobal(inner_global, empty_function);
Steve Block6ded16b2010-05-10 14:33:55 +01002318 InstallJSFunctionResultCaches();
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002319 InitializeNormalizedMapCaches();
Kristian Monsen25f61362010-05-21 11:50:48 +01002320 if (!InstallNatives()) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00002321
Andrei Popescu31002712010-02-23 13:46:05 +00002322 MakeFunctionInstancePrototypeWritable();
Steve Blocka7e24c12009-10-30 11:49:00 +00002323
Andrei Popescu31002712010-02-23 13:46:05 +00002324 if (!ConfigureGlobalObjects(global_template)) return;
Steve Block44f0eee2011-05-26 01:26:41 +01002325 isolate->counters()->contexts_created_from_scratch()->Increment();
Andrei Popescu31002712010-02-23 13:46:05 +00002326 }
Steve Blocka7e24c12009-10-30 11:49:00 +00002327
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002328 // Initialize experimental globals and install experimental natives.
2329 InitializeExperimentalGlobal();
Ben Murdoch257744e2011-11-30 15:57:28 +00002330 if (!InstallExperimentalNatives()) return;
2331
Steve Blocka7e24c12009-10-30 11:49:00 +00002332 result_ = global_context_;
2333}
2334
2335
2336// Support for thread preemption.
2337
2338// Reserve space for statics needing saving and restoring.
2339int Bootstrapper::ArchiveSpacePerThread() {
Steve Block44f0eee2011-05-26 01:26:41 +01002340 return sizeof(NestingCounterType);
Steve Blocka7e24c12009-10-30 11:49:00 +00002341}
2342
2343
2344// Archive statics that are thread local.
2345char* Bootstrapper::ArchiveState(char* to) {
Steve Block44f0eee2011-05-26 01:26:41 +01002346 *reinterpret_cast<NestingCounterType*>(to) = nesting_;
2347 nesting_ = 0;
2348 return to + sizeof(NestingCounterType);
Steve Blocka7e24c12009-10-30 11:49:00 +00002349}
2350
2351
2352// Restore statics that are thread local.
2353char* Bootstrapper::RestoreState(char* from) {
Steve Block44f0eee2011-05-26 01:26:41 +01002354 nesting_ = *reinterpret_cast<NestingCounterType*>(from);
2355 return from + sizeof(NestingCounterType);
Steve Blocka7e24c12009-10-30 11:49:00 +00002356}
2357
2358
2359// Called when the top-level V8 mutex is destroyed.
2360void Bootstrapper::FreeThreadResources() {
Steve Block44f0eee2011-05-26 01:26:41 +01002361 ASSERT(!IsActive());
Steve Blocka7e24c12009-10-30 11:49:00 +00002362}
2363
2364} } // namespace v8::internal