summaryrefslogtreecommitdiff
path: root/deps/v8/src/bootstrapper.cc
diff options
context:
space:
mode:
authorRyan Dahl <ry@tinyclouds.org>2011-06-29 17:26:51 +0200
committerRyan Dahl <ry@tinyclouds.org>2011-06-29 17:26:51 +0200
commit33af2720f26c2b25bc7f75ce7eb454ff99db6d35 (patch)
tree9a38f0c96420edf503eebd6325dd8d2d8249f653 /deps/v8/src/bootstrapper.cc
parent6afdca885adeeeed9eef8cbb01c3d97af0bc084d (diff)
downloadnode-33af2720f26c2b25bc7f75ce7eb454ff99db6d35.tar.gz
Upgrade V8 to 3.4.8
Diffstat (limited to 'deps/v8/src/bootstrapper.cc')
-rw-r--r--deps/v8/src/bootstrapper.cc1210
1 files changed, 764 insertions, 446 deletions
diff --git a/deps/v8/src/bootstrapper.cc b/deps/v8/src/bootstrapper.cc
index 415d2dd8c..8e34b9cf5 100644
--- a/deps/v8/src/bootstrapper.cc
+++ b/deps/v8/src/bootstrapper.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -44,100 +44,60 @@
namespace v8 {
namespace internal {
-// A SourceCodeCache uses a FixedArray to store pairs of
-// (AsciiString*, JSFunction*), mapping names of native code files
-// (runtime.js, etc.) to precompiled functions. Instead of mapping
-// names to functions it might make sense to let the JS2C tool
-// generate an index for each native JS file.
-class SourceCodeCache BASE_EMBEDDED {
- public:
- explicit SourceCodeCache(Script::Type type): type_(type), cache_(NULL) { }
-
- void Initialize(bool create_heap_objects) {
- cache_ = create_heap_objects ? Heap::empty_fixed_array() : NULL;
- }
-
- void Iterate(ObjectVisitor* v) {
- v->VisitPointer(BitCast<Object**>(&cache_));
- }
-
-
- bool Lookup(Vector<const char> name, Handle<SharedFunctionInfo>* handle) {
- for (int i = 0; i < cache_->length(); i+=2) {
- SeqAsciiString* str = SeqAsciiString::cast(cache_->get(i));
- if (str->IsEqualTo(name)) {
- *handle = Handle<SharedFunctionInfo>(
- SharedFunctionInfo::cast(cache_->get(i + 1)));
- return true;
- }
- }
- return false;
- }
-
-
- void Add(Vector<const char> name, Handle<SharedFunctionInfo> shared) {
- HandleScope scope;
- int length = cache_->length();
- Handle<FixedArray> new_array =
- Factory::NewFixedArray(length + 2, TENURED);
- cache_->CopyTo(0, *new_array, 0, cache_->length());
- cache_ = *new_array;
- Handle<String> str = Factory::NewStringFromAscii(name, TENURED);
- cache_->set(length, *str);
- cache_->set(length + 1, *shared);
- Script::cast(shared->script())->set_type(Smi::FromInt(type_));
- }
-
- private:
- Script::Type type_;
- FixedArray* cache_;
- DISALLOW_COPY_AND_ASSIGN(SourceCodeCache);
-};
-
-static SourceCodeCache extensions_cache(Script::TYPE_EXTENSION);
-// This is for delete, not delete[].
-static List<char*>* delete_these_non_arrays_on_tear_down = NULL;
-// This is for delete[]
-static List<char*>* delete_these_arrays_on_tear_down = NULL;
-
-NativesExternalStringResource::NativesExternalStringResource(const char* source)
- : data_(source), length_(StrLength(source)) {
- if (delete_these_non_arrays_on_tear_down == NULL) {
- delete_these_non_arrays_on_tear_down = new List<char*>(2);
+NativesExternalStringResource::NativesExternalStringResource(
+ Bootstrapper* bootstrapper,
+ const char* source,
+ size_t length)
+ : data_(source), length_(length) {
+ if (bootstrapper->delete_these_non_arrays_on_tear_down_ == NULL) {
+ bootstrapper->delete_these_non_arrays_on_tear_down_ = new List<char*>(2);
}
// The resources are small objects and we only make a fixed number of
// them, but let's clean them up on exit for neatness.
- delete_these_non_arrays_on_tear_down->
+ bootstrapper->delete_these_non_arrays_on_tear_down_->
Add(reinterpret_cast<char*>(this));
}
+Bootstrapper::Bootstrapper()
+ : nesting_(0),
+ extensions_cache_(Script::TYPE_EXTENSION),
+ delete_these_non_arrays_on_tear_down_(NULL),
+ delete_these_arrays_on_tear_down_(NULL) {
+}
+
+
Handle<String> Bootstrapper::NativesSourceLookup(int index) {
ASSERT(0 <= index && index < Natives::GetBuiltinsCount());
- if (Heap::natives_source_cache()->get(index)->IsUndefined()) {
+ Isolate* isolate = Isolate::Current();
+ Factory* factory = isolate->factory();
+ Heap* heap = isolate->heap();
+ if (heap->natives_source_cache()->get(index)->IsUndefined()) {
if (!Snapshot::IsEnabled() || FLAG_new_snapshot) {
// We can use external strings for the natives.
+ Vector<const char> source = Natives::GetRawScriptSource(index);
NativesExternalStringResource* resource =
- new NativesExternalStringResource(
- Natives::GetScriptSource(index).start());
+ new NativesExternalStringResource(this,
+ source.start(),
+ source.length());
Handle<String> source_code =
- Factory::NewExternalStringFromAscii(resource);
- Heap::natives_source_cache()->set(index, *source_code);
+ factory->NewExternalStringFromAscii(resource);
+ heap->natives_source_cache()->set(index, *source_code);
} else {
// Old snapshot code can't cope with external strings at all.
Handle<String> source_code =
- Factory::NewStringFromAscii(Natives::GetScriptSource(index));
- Heap::natives_source_cache()->set(index, *source_code);
+ factory->NewStringFromAscii(Natives::GetRawScriptSource(index));
+ heap->natives_source_cache()->set(index, *source_code);
}
}
- Handle<Object> cached_source(Heap::natives_source_cache()->get(index));
+ Handle<Object> cached_source(heap->natives_source_cache()->get(index));
return Handle<String>::cast(cached_source);
}
void Bootstrapper::Initialize(bool create_heap_objects) {
- extensions_cache.Initialize(create_heap_objects);
+ extensions_cache_.Initialize(create_heap_objects);
GCExtension::Register();
ExternalizeStringExtension::Register();
}
@@ -146,45 +106,46 @@ void Bootstrapper::Initialize(bool create_heap_objects) {
char* Bootstrapper::AllocateAutoDeletedArray(int bytes) {
char* memory = new char[bytes];
if (memory != NULL) {
- if (delete_these_arrays_on_tear_down == NULL) {
- delete_these_arrays_on_tear_down = new List<char*>(2);
+ if (delete_these_arrays_on_tear_down_ == NULL) {
+ delete_these_arrays_on_tear_down_ = new List<char*>(2);
}
- delete_these_arrays_on_tear_down->Add(memory);
+ delete_these_arrays_on_tear_down_->Add(memory);
}
return memory;
}
void Bootstrapper::TearDown() {
- if (delete_these_non_arrays_on_tear_down != NULL) {
- int len = delete_these_non_arrays_on_tear_down->length();
+ if (delete_these_non_arrays_on_tear_down_ != NULL) {
+ int len = delete_these_non_arrays_on_tear_down_->length();
ASSERT(len < 20); // Don't use this mechanism for unbounded allocations.
for (int i = 0; i < len; i++) {
- delete delete_these_non_arrays_on_tear_down->at(i);
- delete_these_non_arrays_on_tear_down->at(i) = NULL;
+ delete delete_these_non_arrays_on_tear_down_->at(i);
+ delete_these_non_arrays_on_tear_down_->at(i) = NULL;
}
- delete delete_these_non_arrays_on_tear_down;
- delete_these_non_arrays_on_tear_down = NULL;
+ delete delete_these_non_arrays_on_tear_down_;
+ delete_these_non_arrays_on_tear_down_ = NULL;
}
- if (delete_these_arrays_on_tear_down != NULL) {
- int len = delete_these_arrays_on_tear_down->length();
+ if (delete_these_arrays_on_tear_down_ != NULL) {
+ int len = delete_these_arrays_on_tear_down_->length();
ASSERT(len < 1000); // Don't use this mechanism for unbounded allocations.
for (int i = 0; i < len; i++) {
- delete[] delete_these_arrays_on_tear_down->at(i);
- delete_these_arrays_on_tear_down->at(i) = NULL;
+ delete[] delete_these_arrays_on_tear_down_->at(i);
+ delete_these_arrays_on_tear_down_->at(i) = NULL;
}
- delete delete_these_arrays_on_tear_down;
- delete_these_arrays_on_tear_down = NULL;
+ delete delete_these_arrays_on_tear_down_;
+ delete_these_arrays_on_tear_down_ = NULL;
}
- extensions_cache.Initialize(false); // Yes, symmetrical
+ extensions_cache_.Initialize(false); // Yes, symmetrical
}
class Genesis BASE_EMBEDDED {
public:
- Genesis(Handle<Object> global_object,
+ Genesis(Isolate* isolate,
+ Handle<Object> global_object,
v8::Handle<v8::ObjectTemplate> global_template,
v8::ExtensionConfiguration* extensions);
~Genesis() { }
@@ -193,8 +154,13 @@ class Genesis BASE_EMBEDDED {
Genesis* previous() { return previous_; }
+ Isolate* isolate() const { return isolate_; }
+ Factory* factory() const { return isolate_->factory(); }
+ Heap* heap() const { return isolate_->heap(); }
+
private:
Handle<Context> global_context_;
+ Isolate* isolate_;
// There may be more than one active genesis object: When GC is
// triggered during environment creation there may be weak handle
@@ -206,7 +172,11 @@ class Genesis BASE_EMBEDDED {
// Creates some basic objects. Used for creating a context from scratch.
void CreateRoots();
// Creates the empty function. Used for creating a context from scratch.
- Handle<JSFunction> CreateEmptyFunction();
+ Handle<JSFunction> CreateEmptyFunction(Isolate* isolate);
+ // Creates the ThrowTypeError function. ECMA 5th Ed. 13.2.3
+ Handle<JSFunction> GetThrowTypeErrorFunction();
+
+ void CreateStrictModeFunctionMaps(Handle<JSFunction> empty);
// Creates the global objects using the global and the template passed in
// through the API. We call this regardless of whether we are building a
// context from scratch or using a deserialized one from the partial snapshot
@@ -232,7 +202,9 @@ class Genesis BASE_EMBEDDED {
// Installs the contents of the native .js files on the global objects.
// Used for creating a context from scratch.
void InstallNativeFunctions();
+ void InstallExperimentalNativeFunctions();
bool InstallNatives();
+ bool InstallExperimentalNatives();
void InstallBuiltinFunctionIds();
void InstallJSFunctionResultCaches();
void InitializeNormalizedMapCaches();
@@ -260,11 +232,26 @@ class Genesis BASE_EMBEDDED {
ADD_READONLY_PROTOTYPE,
ADD_WRITEABLE_PROTOTYPE
};
+
+ Handle<Map> CreateFunctionMap(PrototypePropertyMode prototype_mode);
+
Handle<DescriptorArray> ComputeFunctionInstanceDescriptor(
PrototypePropertyMode prototypeMode);
void MakeFunctionInstancePrototypeWritable();
- static bool CompileBuiltin(int index);
+ Handle<Map> CreateStrictModeFunctionMap(
+ PrototypePropertyMode prototype_mode,
+ Handle<JSFunction> empty_function,
+ Handle<FixedArray> arguments_callbacks,
+ Handle<FixedArray> caller_callbacks);
+
+ Handle<DescriptorArray> ComputeStrictFunctionInstanceDescriptor(
+ PrototypePropertyMode propertyMode,
+ Handle<FixedArray> arguments,
+ Handle<FixedArray> caller);
+
+ static bool CompileBuiltin(Isolate* isolate, int index);
+ static bool CompileExperimentalBuiltin(Isolate* isolate, int index);
static bool CompileNative(Vector<const char> name, Handle<String> source);
static bool CompileScriptCached(Vector<const char> name,
Handle<String> source,
@@ -274,25 +261,34 @@ class Genesis BASE_EMBEDDED {
bool use_runtime_context);
Handle<Context> result_;
- Handle<JSFunction> empty_function_;
+
+ // Function instance maps. Function literal maps are created initially with
+ // a read only prototype for the processing of JS builtins. Later the function
+ // instance maps are replaced in order to make prototype writable.
+ // These are the final, writable prototype, maps.
+ Handle<Map> function_instance_map_writable_prototype_;
+ Handle<Map> strict_mode_function_instance_map_writable_prototype_;
+ Handle<JSFunction> throw_type_error_function;
+
BootstrapperActive active_;
friend class Bootstrapper;
};
void Bootstrapper::Iterate(ObjectVisitor* v) {
- extensions_cache.Iterate(v);
+ extensions_cache_.Iterate(v);
v->Synchronize("Extensions");
}
Handle<Context> Bootstrapper::CreateEnvironment(
+ Isolate* isolate,
Handle<Object> global_object,
v8::Handle<v8::ObjectTemplate> global_template,
v8::ExtensionConfiguration* extensions) {
HandleScope scope;
Handle<Context> env;
- Genesis genesis(global_object, global_template, extensions);
+ Genesis genesis(isolate, global_object, global_template, extensions);
env = genesis.result();
if (!env.is_null()) {
if (InstallExtensions(env, extensions)) {
@@ -305,17 +301,19 @@ Handle<Context> Bootstrapper::CreateEnvironment(
static void SetObjectPrototype(Handle<JSObject> object, Handle<Object> proto) {
// object.__proto__ = proto;
+ Factory* factory = object->GetIsolate()->factory();
Handle<Map> old_to_map = Handle<Map>(object->map());
- Handle<Map> new_to_map = Factory::CopyMapDropTransitions(old_to_map);
+ Handle<Map> new_to_map = factory->CopyMapDropTransitions(old_to_map);
new_to_map->set_prototype(*proto);
object->set_map(*new_to_map);
}
void Bootstrapper::DetachGlobal(Handle<Context> env) {
- JSGlobalProxy::cast(env->global_proxy())->set_context(*Factory::null_value());
+ Factory* factory = env->GetIsolate()->factory();
+ JSGlobalProxy::cast(env->global_proxy())->set_context(*factory->null_value());
SetObjectPrototype(Handle<JSObject>(env->global_proxy()),
- Factory::null_value());
+ factory->null_value());
env->set_global_proxy(env->global());
env->global()->set_global_receiver(env->global());
}
@@ -339,11 +337,13 @@ static Handle<JSFunction> InstallFunction(Handle<JSObject> target,
Handle<JSObject> prototype,
Builtins::Name call,
bool is_ecma_native) {
- Handle<String> symbol = Factory::LookupAsciiSymbol(name);
- Handle<Code> call_code = Handle<Code>(Builtins::builtin(call));
+ Isolate* isolate = target->GetIsolate();
+ Factory* factory = isolate->factory();
+ Handle<String> symbol = factory->LookupAsciiSymbol(name);
+ Handle<Code> call_code = Handle<Code>(isolate->builtins()->builtin(call));
Handle<JSFunction> function = prototype.is_null() ?
- Factory::NewFunctionWithoutPrototype(symbol, call_code) :
- Factory::NewFunctionWithPrototype(symbol,
+ factory->NewFunctionWithoutPrototype(symbol, call_code) :
+ factory->NewFunctionWithPrototype(symbol,
type,
instance_size,
prototype,
@@ -359,161 +359,300 @@ static Handle<JSFunction> InstallFunction(Handle<JSObject> target,
Handle<DescriptorArray> Genesis::ComputeFunctionInstanceDescriptor(
PrototypePropertyMode prototypeMode) {
- Handle<DescriptorArray> result = Factory::empty_descriptor_array();
+ Handle<DescriptorArray> descriptors =
+ factory()->NewDescriptorArray(prototypeMode == DONT_ADD_PROTOTYPE
+ ? 4
+ : 5);
+ PropertyAttributes attributes =
+ static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
+ { // Add length.
+ Handle<Foreign> foreign = factory()->NewForeign(&Accessors::FunctionLength);
+ CallbacksDescriptor d(*factory()->length_symbol(), *foreign, attributes);
+ descriptors->Set(0, &d);
+ }
+ { // Add name.
+ Handle<Foreign> foreign = factory()->NewForeign(&Accessors::FunctionName);
+ CallbacksDescriptor d(*factory()->name_symbol(), *foreign, attributes);
+ descriptors->Set(1, &d);
+ }
+ { // Add arguments.
+ Handle<Foreign> foreign =
+ factory()->NewForeign(&Accessors::FunctionArguments);
+ CallbacksDescriptor d(*factory()->arguments_symbol(), *foreign, attributes);
+ descriptors->Set(2, &d);
+ }
+ { // Add caller.
+ Handle<Foreign> foreign = factory()->NewForeign(&Accessors::FunctionCaller);
+ CallbacksDescriptor d(*factory()->caller_symbol(), *foreign, attributes);
+ descriptors->Set(3, &d);
+ }
if (prototypeMode != DONT_ADD_PROTOTYPE) {
- PropertyAttributes attributes = static_cast<PropertyAttributes>(
- DONT_ENUM |
- DONT_DELETE |
- (prototypeMode == ADD_READONLY_PROTOTYPE ? READ_ONLY : 0));
- result =
- Factory::CopyAppendProxyDescriptor(
- result,
- Factory::prototype_symbol(),
- Factory::NewProxy(&Accessors::FunctionPrototype),
- attributes);
+ // Add prototype.
+ if (prototypeMode == ADD_WRITEABLE_PROTOTYPE) {
+ attributes = static_cast<PropertyAttributes>(attributes & ~READ_ONLY);
+ }
+ Handle<Foreign> foreign =
+ factory()->NewForeign(&Accessors::FunctionPrototype);
+ CallbacksDescriptor d(*factory()->prototype_symbol(), *foreign, attributes);
+ descriptors->Set(4, &d);
}
+ descriptors->Sort();
+ return descriptors;
+}
- PropertyAttributes attributes =
- static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
- // Add length.
- result =
- Factory::CopyAppendProxyDescriptor(
- result,
- Factory::length_symbol(),
- Factory::NewProxy(&Accessors::FunctionLength),
- attributes);
-
- // Add name.
- result =
- Factory::CopyAppendProxyDescriptor(
- result,
- Factory::name_symbol(),
- Factory::NewProxy(&Accessors::FunctionName),
- attributes);
-
- // Add arguments.
- result =
- Factory::CopyAppendProxyDescriptor(
- result,
- Factory::arguments_symbol(),
- Factory::NewProxy(&Accessors::FunctionArguments),
- attributes);
-
- // Add caller.
- result =
- Factory::CopyAppendProxyDescriptor(
- result,
- Factory::caller_symbol(),
- Factory::NewProxy(&Accessors::FunctionCaller),
- attributes);
- return result;
+Handle<Map> Genesis::CreateFunctionMap(PrototypePropertyMode prototype_mode) {
+ Handle<Map> map = factory()->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
+ Handle<DescriptorArray> descriptors =
+ ComputeFunctionInstanceDescriptor(prototype_mode);
+ map->set_instance_descriptors(*descriptors);
+ map->set_function_with_prototype(prototype_mode != DONT_ADD_PROTOTYPE);
+ return map;
}
-Handle<JSFunction> Genesis::CreateEmptyFunction() {
- // Allocate the map for function instances.
- Handle<Map> fm = Factory::NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
- global_context()->set_function_instance_map(*fm);
+Handle<JSFunction> Genesis::CreateEmptyFunction(Isolate* isolate) {
+ // Allocate the map for function instances. Maps are allocated first and their
+ // prototypes patched later, once empty function is created.
+
// Please note that the prototype property for function instances must be
// writable.
- Handle<DescriptorArray> function_map_descriptors =
- ComputeFunctionInstanceDescriptor(ADD_WRITEABLE_PROTOTYPE);
- fm->set_instance_descriptors(*function_map_descriptors);
- fm->set_function_with_prototype(true);
+ Handle<Map> function_instance_map =
+ CreateFunctionMap(ADD_WRITEABLE_PROTOTYPE);
+ global_context()->set_function_instance_map(*function_instance_map);
// Functions with this map will not have a 'prototype' property, and
// can not be used as constructors.
Handle<Map> function_without_prototype_map =
- Factory::NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
+ CreateFunctionMap(DONT_ADD_PROTOTYPE);
global_context()->set_function_without_prototype_map(
*function_without_prototype_map);
- Handle<DescriptorArray> function_without_prototype_map_descriptors =
- ComputeFunctionInstanceDescriptor(DONT_ADD_PROTOTYPE);
- function_without_prototype_map->set_instance_descriptors(
- *function_without_prototype_map_descriptors);
- function_without_prototype_map->set_function_with_prototype(false);
- // Allocate the function map first and then patch the prototype later
- fm = Factory::NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
- global_context()->set_function_map(*fm);
- function_map_descriptors =
- ComputeFunctionInstanceDescriptor(ADD_READONLY_PROTOTYPE);
- fm->set_instance_descriptors(*function_map_descriptors);
- fm->set_function_with_prototype(true);
+ // Allocate the function map. This map is temporary, used only for processing
+ // of builtins.
+ // Later the map is replaced with writable prototype map, allocated below.
+ Handle<Map> function_map = CreateFunctionMap(ADD_READONLY_PROTOTYPE);
+ global_context()->set_function_map(*function_map);
- Handle<String> object_name = Handle<String>(Heap::Object_symbol());
+ // The final map for functions. Writeable prototype.
+ // This map is installed in MakeFunctionInstancePrototypeWritable.
+ function_instance_map_writable_prototype_ =
+ CreateFunctionMap(ADD_WRITEABLE_PROTOTYPE);
+
+ Factory* factory = isolate->factory();
+ Heap* heap = isolate->heap();
+
+ Handle<String> object_name = Handle<String>(heap->Object_symbol());
{ // --- O b j e c t ---
Handle<JSFunction> object_fun =
- Factory::NewFunction(object_name, Factory::null_value());
+ factory->NewFunction(object_name, factory->null_value());
Handle<Map> object_function_map =
- Factory::NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
+ factory->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
object_fun->set_initial_map(*object_function_map);
object_function_map->set_constructor(*object_fun);
global_context()->set_object_function(*object_fun);
// Allocate a new prototype for the object function.
- Handle<JSObject> prototype = Factory::NewJSObject(Top::object_function(),
- TENURED);
+ Handle<JSObject> prototype = factory->NewJSObject(
+ isolate->object_function(),
+ TENURED);
global_context()->set_initial_object_prototype(*prototype);
SetPrototype(object_fun, prototype);
object_function_map->
- set_instance_descriptors(Heap::empty_descriptor_array());
+ set_instance_descriptors(heap->empty_descriptor_array());
}
// Allocate the empty function as the prototype for function ECMAScript
// 262 15.3.4.
- Handle<String> symbol = Factory::LookupAsciiSymbol("Empty");
+ Handle<String> symbol = factory->LookupAsciiSymbol("Empty");
Handle<JSFunction> empty_function =
- Factory::NewFunctionWithoutPrototype(symbol);
+ factory->NewFunctionWithoutPrototype(symbol, kNonStrictMode);
// --- E m p t y ---
Handle<Code> code =
- Handle<Code>(Builtins::builtin(Builtins::EmptyFunction));
+ Handle<Code>(isolate->builtins()->builtin(
+ Builtins::kEmptyFunction));
empty_function->set_code(*code);
empty_function->shared()->set_code(*code);
- Handle<String> source = Factory::NewStringFromAscii(CStrVector("() {}"));
- Handle<Script> script = Factory::NewScript(source);
+ Handle<String> source = factory->NewStringFromAscii(CStrVector("() {}"));
+ Handle<Script> script = factory->NewScript(source);
script->set_type(Smi::FromInt(Script::TYPE_NATIVE));
empty_function->shared()->set_script(*script);
empty_function->shared()->set_start_position(0);
empty_function->shared()->set_end_position(source->length());
empty_function->shared()->DontAdaptArguments();
+
+ // Set prototypes for the function maps.
global_context()->function_map()->set_prototype(*empty_function);
global_context()->function_instance_map()->set_prototype(*empty_function);
global_context()->function_without_prototype_map()->
set_prototype(*empty_function);
+ function_instance_map_writable_prototype_->set_prototype(*empty_function);
// Allocate the function map first and then patch the prototype later
- Handle<Map> empty_fm = Factory::CopyMapDropDescriptors(
+ Handle<Map> empty_fm = factory->CopyMapDropDescriptors(
function_without_prototype_map);
empty_fm->set_instance_descriptors(
- *function_without_prototype_map_descriptors);
+ function_without_prototype_map->instance_descriptors());
empty_fm->set_prototype(global_context()->object_function()->prototype());
empty_function->set_map(*empty_fm);
return empty_function;
}
+Handle<DescriptorArray> Genesis::ComputeStrictFunctionInstanceDescriptor(
+ PrototypePropertyMode prototypeMode,
+ Handle<FixedArray> arguments,
+ Handle<FixedArray> caller) {
+ Handle<DescriptorArray> descriptors =
+ factory()->NewDescriptorArray(prototypeMode == DONT_ADD_PROTOTYPE
+ ? 4
+ : 5);
+ PropertyAttributes attributes = static_cast<PropertyAttributes>(
+ DONT_ENUM | DONT_DELETE | READ_ONLY);
+
+ { // length
+ Handle<Foreign> foreign = factory()->NewForeign(&Accessors::FunctionLength);
+ CallbacksDescriptor d(*factory()->length_symbol(), *foreign, attributes);
+ descriptors->Set(0, &d);
+ }
+ { // name
+ Handle<Foreign> foreign = factory()->NewForeign(&Accessors::FunctionName);
+ CallbacksDescriptor d(*factory()->name_symbol(), *foreign, attributes);
+ descriptors->Set(1, &d);
+ }
+ { // arguments
+ CallbacksDescriptor d(*factory()->arguments_symbol(),
+ *arguments,
+ attributes);
+ descriptors->Set(2, &d);
+ }
+ { // caller
+ CallbacksDescriptor d(*factory()->caller_symbol(), *caller, attributes);
+ descriptors->Set(3, &d);
+ }
+
+ // prototype
+ if (prototypeMode != DONT_ADD_PROTOTYPE) {
+ if (prototypeMode == ADD_WRITEABLE_PROTOTYPE) {
+ attributes = static_cast<PropertyAttributes>(attributes & ~READ_ONLY);
+ }
+ Handle<Foreign> foreign =
+ factory()->NewForeign(&Accessors::FunctionPrototype);
+ CallbacksDescriptor d(*factory()->prototype_symbol(), *foreign, attributes);
+ descriptors->Set(4, &d);
+ }
+
+ descriptors->Sort();
+ return descriptors;
+}
+
+
+// ECMAScript 5th Edition, 13.2.3
+Handle<JSFunction> Genesis::GetThrowTypeErrorFunction() {
+ if (throw_type_error_function.is_null()) {
+ Handle<String> name = factory()->LookupAsciiSymbol("ThrowTypeError");
+ throw_type_error_function =
+ factory()->NewFunctionWithoutPrototype(name, kNonStrictMode);
+ Handle<Code> code(isolate()->builtins()->builtin(
+ Builtins::kStrictModePoisonPill));
+ throw_type_error_function->set_map(
+ global_context()->function_map());
+ throw_type_error_function->set_code(*code);
+ throw_type_error_function->shared()->set_code(*code);
+ throw_type_error_function->shared()->DontAdaptArguments();
+
+ PreventExtensions(throw_type_error_function);
+ }
+ return throw_type_error_function;
+}
+
+
+Handle<Map> Genesis::CreateStrictModeFunctionMap(
+ PrototypePropertyMode prototype_mode,
+ Handle<JSFunction> empty_function,
+ Handle<FixedArray> arguments_callbacks,
+ Handle<FixedArray> caller_callbacks) {
+ Handle<Map> map = factory()->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
+ Handle<DescriptorArray> descriptors =
+ ComputeStrictFunctionInstanceDescriptor(prototype_mode,
+ arguments_callbacks,
+ caller_callbacks);
+ map->set_instance_descriptors(*descriptors);
+ map->set_function_with_prototype(prototype_mode != DONT_ADD_PROTOTYPE);
+ map->set_prototype(*empty_function);
+ return map;
+}
+
+
+void Genesis::CreateStrictModeFunctionMaps(Handle<JSFunction> empty) {
+ // Create the callbacks arrays for ThrowTypeError functions.
+ // The get/set callacks are filled in after the maps are created below.
+ Factory* factory = empty->GetIsolate()->factory();
+ Handle<FixedArray> arguments = factory->NewFixedArray(2, TENURED);
+ Handle<FixedArray> caller = factory->NewFixedArray(2, TENURED);
+
+ // Allocate map for the strict mode function instances.
+ Handle<Map> strict_mode_function_instance_map =
+ CreateStrictModeFunctionMap(
+ ADD_WRITEABLE_PROTOTYPE, empty, arguments, caller);
+ global_context()->set_strict_mode_function_instance_map(
+ *strict_mode_function_instance_map);
+
+ // Allocate map for the prototype-less strict mode instances.
+ Handle<Map> strict_mode_function_without_prototype_map =
+ CreateStrictModeFunctionMap(
+ DONT_ADD_PROTOTYPE, empty, arguments, caller);
+ global_context()->set_strict_mode_function_without_prototype_map(
+ *strict_mode_function_without_prototype_map);
+
+ // Allocate map for the strict mode functions. This map is temporary, used
+ // only for processing of builtins.
+ // Later the map is replaced with writable prototype map, allocated below.
+ Handle<Map> strict_mode_function_map =
+ CreateStrictModeFunctionMap(
+ ADD_READONLY_PROTOTYPE, empty, arguments, caller);
+ global_context()->set_strict_mode_function_map(
+ *strict_mode_function_map);
+
+ // The final map for the strict mode functions. Writeable prototype.
+ // This map is installed in MakeFunctionInstancePrototypeWritable.
+ strict_mode_function_instance_map_writable_prototype_ =
+ CreateStrictModeFunctionMap(
+ ADD_WRITEABLE_PROTOTYPE, empty, arguments, caller);
+
+ // Create the ThrowTypeError function instance.
+ Handle<JSFunction> throw_function =
+ GetThrowTypeErrorFunction();
+
+ // Complete the callback fixed arrays.
+ arguments->set(0, *throw_function);
+ arguments->set(1, *throw_function);
+ caller->set(0, *throw_function);
+ caller->set(1, *throw_function);
+}
+
+
static void AddToWeakGlobalContextList(Context* context) {
ASSERT(context->IsGlobalContext());
+ Heap* heap = context->GetIsolate()->heap();
#ifdef DEBUG
{ // NOLINT
ASSERT(context->get(Context::NEXT_CONTEXT_LINK)->IsUndefined());
// Check that context is not in the list yet.
- for (Object* current = Heap::global_contexts_list();
+ for (Object* current = heap->global_contexts_list();
!current->IsUndefined();
current = Context::cast(current)->get(Context::NEXT_CONTEXT_LINK)) {
ASSERT(current != context);
}
}
#endif
- context->set(Context::NEXT_CONTEXT_LINK, Heap::global_contexts_list());
- Heap::set_global_contexts_list(context);
+ context->set(Context::NEXT_CONTEXT_LINK, heap->global_contexts_list());
+ heap->set_global_contexts_list(context);
}
@@ -522,11 +661,10 @@ void Genesis::CreateRoots() {
// closure and extension object later (we need the empty function
// and the global object, but in order to create those, we need the
// global context).
- global_context_ =
- Handle<Context>::cast(
- GlobalHandles::Create(*Factory::NewGlobalContext()));
+ global_context_ = Handle<Context>::cast(isolate()->global_handles()->Create(
+ *factory()->NewGlobalContext()));
AddToWeakGlobalContextList(*global_context_);
- Top::set_context(*global_context());
+ isolate()->set_context(*global_context());
// Allocate the message listeners object.
{
@@ -570,29 +708,33 @@ Handle<JSGlobalProxy> Genesis::CreateNewGlobals(
}
if (js_global_template.is_null()) {
- Handle<String> name = Handle<String>(Heap::empty_symbol());
- Handle<Code> code = Handle<Code>(Builtins::builtin(Builtins::Illegal));
+ Handle<String> name = Handle<String>(heap()->empty_symbol());
+ Handle<Code> code = Handle<Code>(isolate()->builtins()->builtin(
+ Builtins::kIllegal));
js_global_function =
- Factory::NewFunction(name, JS_GLOBAL_OBJECT_TYPE,
- JSGlobalObject::kSize, code, true);
+ factory()->NewFunction(name, JS_GLOBAL_OBJECT_TYPE,
+ JSGlobalObject::kSize, code, true);
// Change the constructor property of the prototype of the
// hidden global function to refer to the Object function.
Handle<JSObject> prototype =
Handle<JSObject>(
JSObject::cast(js_global_function->instance_prototype()));
SetLocalPropertyNoThrow(
- prototype, Factory::constructor_symbol(), Top::object_function(), NONE);
+ prototype,
+ factory()->constructor_symbol(),
+ isolate()->object_function(),
+ NONE);
} else {
Handle<FunctionTemplateInfo> js_global_constructor(
FunctionTemplateInfo::cast(js_global_template->constructor()));
js_global_function =
- Factory::CreateApiFunction(js_global_constructor,
- Factory::InnerGlobalObject);
+ factory()->CreateApiFunction(js_global_constructor,
+ factory()->InnerGlobalObject);
}
js_global_function->initial_map()->set_is_hidden_prototype();
Handle<GlobalObject> inner_global =
- Factory::NewGlobalObject(js_global_function);
+ factory()->NewGlobalObject(js_global_function);
if (inner_global_out != NULL) {
*inner_global_out = inner_global;
}
@@ -600,22 +742,23 @@ Handle<JSGlobalProxy> Genesis::CreateNewGlobals(
// Step 2: create or re-initialize the global proxy object.
Handle<JSFunction> global_proxy_function;
if (global_template.IsEmpty()) {
- Handle<String> name = Handle<String>(Heap::empty_symbol());
- Handle<Code> code = Handle<Code>(Builtins::builtin(Builtins::Illegal));
+ Handle<String> name = Handle<String>(heap()->empty_symbol());
+ Handle<Code> code = Handle<Code>(isolate()->builtins()->builtin(
+ Builtins::kIllegal));
global_proxy_function =
- Factory::NewFunction(name, JS_GLOBAL_PROXY_TYPE,
- JSGlobalProxy::kSize, code, true);
+ factory()->NewFunction(name, JS_GLOBAL_PROXY_TYPE,
+ JSGlobalProxy::kSize, code, true);
} else {
Handle<ObjectTemplateInfo> data =
v8::Utils::OpenHandle(*global_template);
Handle<FunctionTemplateInfo> global_constructor(
FunctionTemplateInfo::cast(data->constructor()));
global_proxy_function =
- Factory::CreateApiFunction(global_constructor,
- Factory::OuterGlobalObject);
+ factory()->CreateApiFunction(global_constructor,
+ factory()->OuterGlobalObject);
}
- Handle<String> global_name = Factory::LookupAsciiSymbol("global");
+ Handle<String> global_name = factory()->LookupAsciiSymbol("global");
global_proxy_function->shared()->set_instance_class_name(*global_name);
global_proxy_function->initial_map()->set_is_access_check_needed(true);
@@ -629,7 +772,7 @@ Handle<JSGlobalProxy> Genesis::CreateNewGlobals(
Handle<JSGlobalProxy>::cast(global_object));
} else {
return Handle<JSGlobalProxy>::cast(
- Factory::NewJSObject(global_proxy_function, TENURED));
+ factory()->NewJSObject(global_proxy_function, TENURED));
}
}
@@ -654,7 +797,7 @@ void Genesis::HookUpInnerGlobal(Handle<GlobalObject> inner_global) {
static const PropertyAttributes attributes =
static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE);
ForceSetProperty(builtins_global,
- Factory::LookupAsciiSymbol("global"),
+ factory()->LookupAsciiSymbol("global"),
inner_global,
attributes);
// Setup the reference from the global object to the builtins object.
@@ -671,7 +814,6 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
// --- G l o b a l C o n t e x t ---
// Use the empty function as closure (no scope info).
global_context()->set_closure(*empty_function);
- global_context()->set_fcontext(*global_context());
global_context()->set_previous(NULL);
// Set extension and global object.
global_context()->set_extension(*inner_global);
@@ -682,33 +824,37 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
// object reinitialization.
global_context()->set_security_token(*inner_global);
- Handle<String> object_name = Handle<String>(Heap::Object_symbol());
+ Isolate* isolate = inner_global->GetIsolate();
+ Factory* factory = isolate->factory();
+ Heap* heap = isolate->heap();
+
+ Handle<String> object_name = Handle<String>(heap->Object_symbol());
SetLocalPropertyNoThrow(inner_global, object_name,
- Top::object_function(), DONT_ENUM);
+ isolate->object_function(), DONT_ENUM);
Handle<JSObject> global = Handle<JSObject>(global_context()->global());
// Install global Function object
InstallFunction(global, "Function", JS_FUNCTION_TYPE, JSFunction::kSize,
- empty_function, Builtins::Illegal, true); // ECMA native.
+ empty_function, Builtins::kIllegal, true); // ECMA native.
{ // --- A r r a y ---
Handle<JSFunction> array_function =
InstallFunction(global, "Array", JS_ARRAY_TYPE, JSArray::kSize,
- Top::initial_object_prototype(), Builtins::ArrayCode,
- true);
+ isolate->initial_object_prototype(),
+ Builtins::kArrayCode, true);
array_function->shared()->set_construct_stub(
- Builtins::builtin(Builtins::ArrayConstructCode));
+ isolate->builtins()->builtin(Builtins::kArrayConstructCode));
array_function->shared()->DontAdaptArguments();
// This seems a bit hackish, but we need to make sure Array.length
// is 1.
array_function->shared()->set_length(1);
Handle<DescriptorArray> array_descriptors =
- Factory::CopyAppendProxyDescriptor(
- Factory::empty_descriptor_array(),
- Factory::length_symbol(),
- Factory::NewProxy(&Accessors::ArrayLength),
+ factory->CopyAppendForeignDescriptor(
+ factory->empty_descriptor_array(),
+ factory->length_symbol(),
+ factory->NewForeign(&Accessors::ArrayLength),
static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE));
// Cache the fast JavaScript array map
@@ -725,33 +871,33 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
{ // --- N u m b e r ---
Handle<JSFunction> number_fun =
InstallFunction(global, "Number", JS_VALUE_TYPE, JSValue::kSize,
- Top::initial_object_prototype(), Builtins::Illegal,
- true);
+ isolate->initial_object_prototype(),
+ Builtins::kIllegal, true);
global_context()->set_number_function(*number_fun);
}
{ // --- B o o l e a n ---
Handle<JSFunction> boolean_fun =
InstallFunction(global, "Boolean", JS_VALUE_TYPE, JSValue::kSize,
- Top::initial_object_prototype(), Builtins::Illegal,
- true);
+ isolate->initial_object_prototype(),
+ Builtins::kIllegal, true);
global_context()->set_boolean_function(*boolean_fun);
}
{ // --- S t r i n g ---
Handle<JSFunction> string_fun =
InstallFunction(global, "String", JS_VALUE_TYPE, JSValue::kSize,
- Top::initial_object_prototype(), Builtins::Illegal,
- true);
+ isolate->initial_object_prototype(),
+ Builtins::kIllegal, true);
string_fun->shared()->set_construct_stub(
- Builtins::builtin(Builtins::StringConstructCode));
+ isolate->builtins()->builtin(Builtins::kStringConstructCode));
global_context()->set_string_function(*string_fun);
// Add 'length' property to strings.
Handle<DescriptorArray> string_descriptors =
- Factory::CopyAppendProxyDescriptor(
- Factory::empty_descriptor_array(),
- Factory::length_symbol(),
- Factory::NewProxy(&Accessors::StringLength),
+ factory->CopyAppendForeignDescriptor(
+ factory->empty_descriptor_array(),
+ factory->length_symbol(),
+ factory->NewForeign(&Accessors::StringLength),
static_cast<PropertyAttributes>(DONT_ENUM |
DONT_DELETE |
READ_ONLY));
@@ -765,8 +911,8 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
// Builtin functions for Date.prototype.
Handle<JSFunction> date_fun =
InstallFunction(global, "Date", JS_VALUE_TYPE, JSValue::kSize,
- Top::initial_object_prototype(), Builtins::Illegal,
- true);
+ isolate->initial_object_prototype(),
+ Builtins::kIllegal, true);
global_context()->set_date_function(*date_fun);
}
@@ -776,8 +922,8 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
// Builtin functions for RegExp.prototype.
Handle<JSFunction> regexp_fun =
InstallFunction(global, "RegExp", JS_REGEXP_TYPE, JSRegExp::kSize,
- Top::initial_object_prototype(), Builtins::Illegal,
- true);
+ isolate->initial_object_prototype(),
+ Builtins::kIllegal, true);
global_context()->set_regexp_function(*regexp_fun);
ASSERT(regexp_fun->has_initial_map());
@@ -785,13 +931,13 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
ASSERT_EQ(0, initial_map->inobject_properties());
- Handle<DescriptorArray> descriptors = Factory::NewDescriptorArray(5);
+ Handle<DescriptorArray> descriptors = factory->NewDescriptorArray(5);
PropertyAttributes final =
static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
int enum_index = 0;
{
// ECMA-262, section 15.10.7.1.
- FieldDescriptor field(Heap::source_symbol(),
+ FieldDescriptor field(heap->source_symbol(),
JSRegExp::kSourceFieldIndex,
final,
enum_index++);
@@ -799,7 +945,7 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
}
{
// ECMA-262, section 15.10.7.2.
- FieldDescriptor field(Heap::global_symbol(),
+ FieldDescriptor field(heap->global_symbol(),
JSRegExp::kGlobalFieldIndex,
final,
enum_index++);
@@ -807,7 +953,7 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
}
{
// ECMA-262, section 15.10.7.3.
- FieldDescriptor field(Heap::ignore_case_symbol(),
+ FieldDescriptor field(heap->ignore_case_symbol(),
JSRegExp::kIgnoreCaseFieldIndex,
final,
enum_index++);
@@ -815,7 +961,7 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
}
{
// ECMA-262, section 15.10.7.4.
- FieldDescriptor field(Heap::multiline_symbol(),
+ FieldDescriptor field(heap->multiline_symbol(),
JSRegExp::kMultilineFieldIndex,
final,
enum_index++);
@@ -825,7 +971,7 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
// ECMA-262, section 15.10.7.5.
PropertyAttributes writable =
static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
- FieldDescriptor field(Heap::last_index_symbol(),
+ FieldDescriptor field(heap->last_index_symbol(),
JSRegExp::kLastIndexFieldIndex,
writable,
enum_index++);
@@ -844,13 +990,13 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
}
{ // -- J S O N
- Handle<String> name = Factory::NewStringFromAscii(CStrVector("JSON"));
- Handle<JSFunction> cons = Factory::NewFunction(
+ Handle<String> name = factory->NewStringFromAscii(CStrVector("JSON"));
+ Handle<JSFunction> cons = factory->NewFunction(
name,
- Factory::the_hole_value());
+ factory->the_hole_value());
cons->SetInstancePrototype(global_context()->initial_object_prototype());
cons->SetInstanceClassName(*name);
- Handle<JSObject> json_object = Factory::NewJSObject(cons, TENURED);
+ Handle<JSObject> json_object = factory->NewJSObject(cons, TENURED);
ASSERT(json_object->IsJSObject());
SetLocalPropertyNoThrow(global, name, json_object, DONT_ENUM);
global_context()->set_json_object(*json_object);
@@ -860,14 +1006,15 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
// Make sure we can recognize argument objects at runtime.
// This is done by introducing an anonymous function with
// class_name equals 'Arguments'.
- Handle<String> symbol = Factory::LookupAsciiSymbol("Arguments");
- Handle<Code> code = Handle<Code>(Builtins::builtin(Builtins::Illegal));
+ Handle<String> symbol = factory->LookupAsciiSymbol("Arguments");
+ Handle<Code> code = Handle<Code>(
+ isolate->builtins()->builtin(Builtins::kIllegal));
Handle<JSObject> prototype =
Handle<JSObject>(
JSObject::cast(global_context()->object_function()->prototype()));
Handle<JSFunction> function =
- Factory::NewFunctionWithPrototype(symbol,
+ factory->NewFunctionWithPrototype(symbol,
JS_OBJECT_TYPE,
JSObject::kHeaderSize,
prototype,
@@ -876,30 +1023,117 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
ASSERT(!function->has_initial_map());
function->shared()->set_instance_class_name(*symbol);
function->shared()->set_expected_nof_properties(2);
- Handle<JSObject> result = Factory::NewJSObject(function);
+ Handle<JSObject> result = factory->NewJSObject(function);
global_context()->set_arguments_boilerplate(*result);
- // Note: callee must be added as the first property and
- // length must be added as the second property.
- SetLocalPropertyNoThrow(result, Factory::callee_symbol(),
- Factory::undefined_value(),
+ // Note: length must be added as the first property and
+ // callee must be added as the second property.
+ SetLocalPropertyNoThrow(result, factory->length_symbol(),
+ factory->undefined_value(),
DONT_ENUM);
- SetLocalPropertyNoThrow(result, Factory::length_symbol(),
- Factory::undefined_value(),
+ SetLocalPropertyNoThrow(result, factory->callee_symbol(),
+ factory->undefined_value(),
DONT_ENUM);
#ifdef DEBUG
LookupResult lookup;
- result->LocalLookup(Heap::callee_symbol(), &lookup);
+ result->LocalLookup(heap->callee_symbol(), &lookup);
+ ASSERT(lookup.IsProperty() && (lookup.type() == FIELD));
+ ASSERT(lookup.GetFieldIndex() == Heap::kArgumentsCalleeIndex);
+
+ result->LocalLookup(heap->length_symbol(), &lookup);
ASSERT(lookup.IsProperty() && (lookup.type() == FIELD));
- ASSERT(lookup.GetFieldIndex() == Heap::arguments_callee_index);
+ ASSERT(lookup.GetFieldIndex() == Heap::kArgumentsLengthIndex);
+
+ ASSERT(result->map()->inobject_properties() > Heap::kArgumentsCalleeIndex);
+ ASSERT(result->map()->inobject_properties() > Heap::kArgumentsLengthIndex);
+
+ // Check the state of the object.
+ ASSERT(result->HasFastProperties());
+ ASSERT(result->HasFastElements());
+#endif
+ }
+
+ { // --- aliased_arguments_boilerplate_
+ Handle<Map> old_map(global_context()->arguments_boilerplate()->map());
+ Handle<Map> new_map = factory->CopyMapDropTransitions(old_map);
+ new_map->set_pre_allocated_property_fields(2);
+ Handle<JSObject> result = factory->NewJSObjectFromMap(new_map);
+ new_map->set_elements_kind(JSObject::NON_STRICT_ARGUMENTS_ELEMENTS);
+ // Set up a well-formed parameter map to make assertions happy.
+ Handle<FixedArray> elements = factory->NewFixedArray(2);
+ elements->set_map(heap->non_strict_arguments_elements_map());
+ Handle<FixedArray> array;
+ array = factory->NewFixedArray(0);
+ elements->set(0, *array);
+ array = factory->NewFixedArray(0);
+ elements->set(1, *array);
+ result->set_elements(*elements);
+ global_context()->set_aliased_arguments_boilerplate(*result);
+ }
+
+ { // --- strict mode arguments boilerplate
+ const PropertyAttributes attributes =
+ static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
+
+ // Create the ThrowTypeError functions.
+ Handle<FixedArray> callee = factory->NewFixedArray(2, TENURED);
+ Handle<FixedArray> caller = factory->NewFixedArray(2, TENURED);
+
+ Handle<JSFunction> throw_function =
+ GetThrowTypeErrorFunction();
+
+ // Install the ThrowTypeError functions.
+ callee->set(0, *throw_function);
+ callee->set(1, *throw_function);
+ caller->set(0, *throw_function);
+ caller->set(1, *throw_function);
+
+ // Create the descriptor array for the arguments object.
+ Handle<DescriptorArray> descriptors = factory->NewDescriptorArray(3);
+ { // length
+ FieldDescriptor d(*factory->length_symbol(), 0, DONT_ENUM);
+ descriptors->Set(0, &d);
+ }
+ { // callee
+ CallbacksDescriptor d(*factory->callee_symbol(), *callee, attributes);
+ descriptors->Set(1, &d);
+ }
+ { // caller
+ CallbacksDescriptor d(*factory->caller_symbol(), *caller, attributes);
+ descriptors->Set(2, &d);
+ }
+ descriptors->Sort();
+
+ // Create the map. Allocate one in-object field for length.
+ Handle<Map> map = factory->NewMap(JS_OBJECT_TYPE,
+ Heap::kArgumentsObjectSizeStrict);
+ map->set_instance_descriptors(*descriptors);
+ map->set_function_with_prototype(true);
+ map->set_prototype(global_context()->object_function()->prototype());
+ map->set_pre_allocated_property_fields(1);
+ map->set_inobject_properties(1);
+
+ // Copy constructor from the non-strict arguments boilerplate.
+ map->set_constructor(
+ global_context()->arguments_boilerplate()->map()->constructor());
+
+ // Allocate the arguments boilerplate object.
+ Handle<JSObject> result = factory->NewJSObjectFromMap(map);
+ global_context()->set_strict_mode_arguments_boilerplate(*result);
+
+ // Add length property only for strict mode boilerplate.
+ SetLocalPropertyNoThrow(result, factory->length_symbol(),
+ factory->undefined_value(),
+ DONT_ENUM);
- result->LocalLookup(Heap::length_symbol(), &lookup);
+#ifdef DEBUG
+ LookupResult lookup;
+ result->LocalLookup(heap->length_symbol(), &lookup);
ASSERT(lookup.IsProperty() && (lookup.type() == FIELD));
- ASSERT(lookup.GetFieldIndex() == Heap::arguments_length_index);
+ ASSERT(lookup.GetFieldIndex() == Heap::kArgumentsLengthIndex);
- ASSERT(result->map()->inobject_properties() > Heap::arguments_callee_index);
- ASSERT(result->map()->inobject_properties() > Heap::arguments_length_index);
+ ASSERT(result->map()->inobject_properties() > Heap::kArgumentsLengthIndex);
// Check the state of the object.
ASSERT(result->HasFastProperties());
@@ -909,15 +1143,16 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
{ // --- context extension
// Create a function for the context extension objects.
- Handle<Code> code = Handle<Code>(Builtins::builtin(Builtins::Illegal));
+ Handle<Code> code = Handle<Code>(
+ isolate->builtins()->builtin(Builtins::kIllegal));
Handle<JSFunction> context_extension_fun =
- Factory::NewFunction(Factory::empty_symbol(),
+ factory->NewFunction(factory->empty_symbol(),
JS_CONTEXT_EXTENSION_OBJECT_TYPE,
JSObject::kHeaderSize,
code,
true);
- Handle<String> name = Factory::LookupAsciiSymbol("context_extension");
+ Handle<String> name = factory->LookupAsciiSymbol("context_extension");
context_extension_fun->shared()->set_instance_class_name(*name);
global_context()->set_context_extension_function(*context_extension_fun);
}
@@ -926,9 +1161,10 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
{
// Setup the call-as-function delegate.
Handle<Code> code =
- Handle<Code>(Builtins::builtin(Builtins::HandleApiCallAsFunction));
+ Handle<Code>(isolate->builtins()->builtin(
+ Builtins::kHandleApiCallAsFunction));
Handle<JSFunction> delegate =
- Factory::NewFunction(Factory::empty_symbol(), JS_OBJECT_TYPE,
+ factory->NewFunction(factory->empty_symbol(), JS_OBJECT_TYPE,
JSObject::kHeaderSize, code, true);
global_context()->set_call_as_function_delegate(*delegate);
delegate->shared()->DontAdaptArguments();
@@ -937,44 +1173,57 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
{
// Setup the call-as-constructor delegate.
Handle<Code> code =
- Handle<Code>(Builtins::builtin(Builtins::HandleApiCallAsConstructor));
+ Handle<Code>(isolate->builtins()->builtin(
+ Builtins::kHandleApiCallAsConstructor));
Handle<JSFunction> delegate =
- Factory::NewFunction(Factory::empty_symbol(), JS_OBJECT_TYPE,
+ factory->NewFunction(factory->empty_symbol(), JS_OBJECT_TYPE,
JSObject::kHeaderSize, code, true);
global_context()->set_call_as_constructor_delegate(*delegate);
delegate->shared()->DontAdaptArguments();
}
// Initialize the out of memory slot.
- global_context()->set_out_of_memory(Heap::false_value());
+ global_context()->set_out_of_memory(heap->false_value());
// Initialize the data slot.
- global_context()->set_data(Heap::undefined_value());
+ global_context()->set_data(heap->undefined_value());
}
-bool Genesis::CompileBuiltin(int index) {
+bool Genesis::CompileBuiltin(Isolate* isolate, int index) {
Vector<const char> name = Natives::GetScriptName(index);
- Handle<String> source_code = Bootstrapper::NativesSourceLookup(index);
+ Handle<String> source_code =
+ isolate->bootstrapper()->NativesSourceLookup(index);
+ return CompileNative(name, source_code);
+}
+
+
+bool Genesis::CompileExperimentalBuiltin(Isolate* isolate, int index) {
+ Vector<const char> name = ExperimentalNatives::GetScriptName(index);
+ Factory* factory = isolate->factory();
+ Handle<String> source_code =
+ factory->NewStringFromAscii(
+ ExperimentalNatives::GetRawScriptSource(index));
return CompileNative(name, source_code);
}
bool Genesis::CompileNative(Vector<const char> name, Handle<String> source) {
HandleScope scope;
+ Isolate* isolate = source->GetIsolate();
#ifdef ENABLE_DEBUGGER_SUPPORT
- Debugger::set_compiling_natives(true);
+ isolate->debugger()->set_compiling_natives(true);
#endif
bool result = CompileScriptCached(name,
source,
NULL,
NULL,
- Handle<Context>(Top::context()),
+ Handle<Context>(isolate->context()),
true);
- ASSERT(Top::has_pending_exception() != result);
- if (!result) Top::clear_pending_exception();
+ ASSERT(isolate->has_pending_exception() != result);
+ if (!result) isolate->clear_pending_exception();
#ifdef ENABLE_DEBUGGER_SUPPORT
- Debugger::set_compiling_natives(false);
+ isolate->debugger()->set_compiling_natives(false);
#endif
return result;
}
@@ -986,6 +1235,7 @@ bool Genesis::CompileScriptCached(Vector<const char> name,
v8::Extension* extension,
Handle<Context> top_context,
bool use_runtime_context) {
+ Factory* factory = source->GetIsolate()->factory();
HandleScope scope;
Handle<SharedFunctionInfo> function_info;
@@ -993,7 +1243,7 @@ bool Genesis::CompileScriptCached(Vector<const char> name,
// function and insert it into the cache.
if (cache == NULL || !cache->Lookup(name, &function_info)) {
ASSERT(source->IsAsciiRepresentation());
- Handle<String> script_name = Factory::NewStringFromUtf8(name);
+ Handle<String> script_name = factory->NewStringFromUtf8(name);
function_info = Compiler::Compile(
source,
script_name,
@@ -1016,7 +1266,7 @@ bool Genesis::CompileScriptCached(Vector<const char> name,
? Handle<Context>(top_context->runtime_context())
: top_context);
Handle<JSFunction> fun =
- Factory::NewFunctionFromSharedFunctionInfo(function_info, context);
+ factory->NewFunctionFromSharedFunctionInfo(function_info, context);
// Call function using either the runtime object or the global
// object as the receiver. Provide no parameters.
@@ -1025,17 +1275,19 @@ bool Genesis::CompileScriptCached(Vector<const char> name,
? top_context->builtins()
: top_context->global());
bool has_pending_exception;
- Handle<Object> result =
- Execution::Call(fun, receiver, 0, NULL, &has_pending_exception);
+ Execution::Call(fun, receiver, 0, NULL, &has_pending_exception);
if (has_pending_exception) return false;
return true;
}
-#define INSTALL_NATIVE(Type, name, var) \
- Handle<String> var##_name = Factory::LookupAsciiSymbol(name); \
- global_context()->set_##var(Type::cast( \
- global_context()->builtins()->GetPropertyNoExceptionThrown(*var##_name)));
+#define INSTALL_NATIVE(Type, name, var) \
+ Handle<String> var##_name = factory()->LookupAsciiSymbol(name); \
+ Object* var##_native = \
+ global_context()->builtins()->GetPropertyNoExceptionThrown( \
+ *var##_name); \
+ global_context()->set_##var(Type::cast(var##_native));
+
void Genesis::InstallNativeFunctions() {
HandleScope scope;
@@ -1055,6 +1307,13 @@ void Genesis::InstallNativeFunctions() {
INSTALL_NATIVE(JSObject, "functionCache", function_cache);
}
+void Genesis::InstallExperimentalNativeFunctions() {
+ if (FLAG_harmony_proxies) {
+ INSTALL_NATIVE(JSFunction, "DerivedGetTrap", derived_get_trap);
+ INSTALL_NATIVE(JSFunction, "DerivedSetTrap", derived_set_trap);
+ }
+}
+
#undef INSTALL_NATIVE
@@ -1064,17 +1323,19 @@ bool Genesis::InstallNatives() {
// Create a function for the builtins object. Allocate space for the
// JavaScript builtins, a reference to the builtins object
// (itself) and a reference to the global_context directly in the object.
- Handle<Code> code = Handle<Code>(Builtins::builtin(Builtins::Illegal));
+ Handle<Code> code = Handle<Code>(
+ isolate()->builtins()->builtin(Builtins::kIllegal));
Handle<JSFunction> builtins_fun =
- Factory::NewFunction(Factory::empty_symbol(), JS_BUILTINS_OBJECT_TYPE,
- JSBuiltinsObject::kSize, code, true);
+ factory()->NewFunction(factory()->empty_symbol(),
+ JS_BUILTINS_OBJECT_TYPE,
+ JSBuiltinsObject::kSize, code, true);
- Handle<String> name = Factory::LookupAsciiSymbol("builtins");
+ Handle<String> name = factory()->LookupAsciiSymbol("builtins");
builtins_fun->shared()->set_instance_class_name(*name);
// Allocate the builtins object.
Handle<JSBuiltinsObject> builtins =
- Handle<JSBuiltinsObject>::cast(Factory::NewGlobalObject(builtins_fun));
+ Handle<JSBuiltinsObject>::cast(factory()->NewGlobalObject(builtins_fun));
builtins->set_builtins(*builtins);
builtins->set_global_context(*global_context());
builtins->set_global_receiver(*builtins);
@@ -1085,7 +1346,7 @@ bool Genesis::InstallNatives() {
// global object.
static const PropertyAttributes attributes =
static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE);
- Handle<String> global_symbol = Factory::LookupAsciiSymbol("global");
+ Handle<String> global_symbol = factory()->LookupAsciiSymbol("global");
Handle<Object> global_obj(global_context()->global());
SetLocalPropertyNoThrow(builtins, global_symbol, global_obj, attributes);
@@ -1094,12 +1355,13 @@ bool Genesis::InstallNatives() {
// Create a bridge function that has context in the global context.
Handle<JSFunction> bridge =
- Factory::NewFunction(Factory::empty_symbol(), Factory::undefined_value());
- ASSERT(bridge->context() == *Top::global_context());
+ factory()->NewFunction(factory()->empty_symbol(),
+ factory()->undefined_value());
+ ASSERT(bridge->context() == *isolate()->global_context());
// Allocate the builtins context.
Handle<Context> context =
- Factory::NewFunctionContext(Context::MIN_CONTEXT_SLOTS, bridge);
+ factory()->NewFunctionContext(Context::MIN_CONTEXT_SLOTS, bridge);
context->set_global(*builtins); // override builtins global object
global_context()->set_runtime_context(*context);
@@ -1108,123 +1370,127 @@ bool Genesis::InstallNatives() {
// Builtin functions for Script.
Handle<JSFunction> script_fun =
InstallFunction(builtins, "Script", JS_VALUE_TYPE, JSValue::kSize,
- Top::initial_object_prototype(), Builtins::Illegal,
- false);
+ isolate()->initial_object_prototype(),
+ Builtins::kIllegal, false);
Handle<JSObject> prototype =
- Factory::NewJSObject(Top::object_function(), TENURED);
+ factory()->NewJSObject(isolate()->object_function(), TENURED);
SetPrototype(script_fun, prototype);
global_context()->set_script_function(*script_fun);
// Add 'source' and 'data' property to scripts.
PropertyAttributes common_attributes =
static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
- Handle<Proxy> proxy_source = Factory::NewProxy(&Accessors::ScriptSource);
+ Handle<Foreign> foreign_source =
+ factory()->NewForeign(&Accessors::ScriptSource);
Handle<DescriptorArray> script_descriptors =
- Factory::CopyAppendProxyDescriptor(
- Factory::empty_descriptor_array(),
- Factory::LookupAsciiSymbol("source"),
- proxy_source,
+ factory()->CopyAppendForeignDescriptor(
+ factory()->empty_descriptor_array(),
+ factory()->LookupAsciiSymbol("source"),
+ foreign_source,
common_attributes);
- Handle<Proxy> proxy_name = Factory::NewProxy(&Accessors::ScriptName);
+ Handle<Foreign> foreign_name =
+ factory()->NewForeign(&Accessors::ScriptName);
script_descriptors =
- Factory::CopyAppendProxyDescriptor(
+ factory()->CopyAppendForeignDescriptor(
script_descriptors,
- Factory::LookupAsciiSymbol("name"),
- proxy_name,
+ factory()->LookupAsciiSymbol("name"),
+ foreign_name,
common_attributes);
- Handle<Proxy> proxy_id = Factory::NewProxy(&Accessors::ScriptId);
+ Handle<Foreign> foreign_id = factory()->NewForeign(&Accessors::ScriptId);
script_descriptors =
- Factory::CopyAppendProxyDescriptor(
+ factory()->CopyAppendForeignDescriptor(
script_descriptors,
- Factory::LookupAsciiSymbol("id"),
- proxy_id,
+ factory()->LookupAsciiSymbol("id"),
+ foreign_id,
common_attributes);
- Handle<Proxy> proxy_line_offset =
- Factory::NewProxy(&Accessors::ScriptLineOffset);
+ Handle<Foreign> foreign_line_offset =
+ factory()->NewForeign(&Accessors::ScriptLineOffset);
script_descriptors =
- Factory::CopyAppendProxyDescriptor(
+ factory()->CopyAppendForeignDescriptor(
script_descriptors,
- Factory::LookupAsciiSymbol("line_offset"),
- proxy_line_offset,
+ factory()->LookupAsciiSymbol("line_offset"),
+ foreign_line_offset,
common_attributes);
- Handle<Proxy> proxy_column_offset =
- Factory::NewProxy(&Accessors::ScriptColumnOffset);
+ Handle<Foreign> foreign_column_offset =
+ factory()->NewForeign(&Accessors::ScriptColumnOffset);
script_descriptors =
- Factory::CopyAppendProxyDescriptor(
+ factory()->CopyAppendForeignDescriptor(
script_descriptors,
- Factory::LookupAsciiSymbol("column_offset"),
- proxy_column_offset,
+ factory()->LookupAsciiSymbol("column_offset"),
+ foreign_column_offset,
common_attributes);
- Handle<Proxy> proxy_data = Factory::NewProxy(&Accessors::ScriptData);
+ Handle<Foreign> foreign_data =
+ factory()->NewForeign(&Accessors::ScriptData);
script_descriptors =
- Factory::CopyAppendProxyDescriptor(
+ factory()->CopyAppendForeignDescriptor(
script_descriptors,
- Factory::LookupAsciiSymbol("data"),
- proxy_data,
+ factory()->LookupAsciiSymbol("data"),
+ foreign_data,
common_attributes);
- Handle<Proxy> proxy_type = Factory::NewProxy(&Accessors::ScriptType);
+ Handle<Foreign> foreign_type =
+ factory()->NewForeign(&Accessors::ScriptType);
script_descriptors =
- Factory::CopyAppendProxyDescriptor(
+ factory()->CopyAppendForeignDescriptor(
script_descriptors,
- Factory::LookupAsciiSymbol("type"),
- proxy_type,
+ factory()->LookupAsciiSymbol("type"),
+ foreign_type,
common_attributes);
- Handle<Proxy> proxy_compilation_type =
- Factory::NewProxy(&Accessors::ScriptCompilationType);
+ Handle<Foreign> foreign_compilation_type =
+ factory()->NewForeign(&Accessors::ScriptCompilationType);
script_descriptors =
- Factory::CopyAppendProxyDescriptor(
+ factory()->CopyAppendForeignDescriptor(
script_descriptors,
- Factory::LookupAsciiSymbol("compilation_type"),
- proxy_compilation_type,
+ factory()->LookupAsciiSymbol("compilation_type"),
+ foreign_compilation_type,
common_attributes);
- Handle<Proxy> proxy_line_ends =
- Factory::NewProxy(&Accessors::ScriptLineEnds);
+ Handle<Foreign> foreign_line_ends =
+ factory()->NewForeign(&Accessors::ScriptLineEnds);
script_descriptors =
- Factory::CopyAppendProxyDescriptor(
+ factory()->CopyAppendForeignDescriptor(
script_descriptors,
- Factory::LookupAsciiSymbol("line_ends"),
- proxy_line_ends,
+ factory()->LookupAsciiSymbol("line_ends"),
+ foreign_line_ends,
common_attributes);
- Handle<Proxy> proxy_context_data =
- Factory::NewProxy(&Accessors::ScriptContextData);
+ Handle<Foreign> foreign_context_data =
+ factory()->NewForeign(&Accessors::ScriptContextData);
script_descriptors =
- Factory::CopyAppendProxyDescriptor(
+ factory()->CopyAppendForeignDescriptor(
script_descriptors,
- Factory::LookupAsciiSymbol("context_data"),
- proxy_context_data,
+ factory()->LookupAsciiSymbol("context_data"),
+ foreign_context_data,
common_attributes);
- Handle<Proxy> proxy_eval_from_script =
- Factory::NewProxy(&Accessors::ScriptEvalFromScript);
+ Handle<Foreign> foreign_eval_from_script =
+ factory()->NewForeign(&Accessors::ScriptEvalFromScript);
script_descriptors =
- Factory::CopyAppendProxyDescriptor(
+ factory()->CopyAppendForeignDescriptor(
script_descriptors,
- Factory::LookupAsciiSymbol("eval_from_script"),
- proxy_eval_from_script,
+ factory()->LookupAsciiSymbol("eval_from_script"),
+ foreign_eval_from_script,
common_attributes);
- Handle<Proxy> proxy_eval_from_script_position =
- Factory::NewProxy(&Accessors::ScriptEvalFromScriptPosition);
+ Handle<Foreign> foreign_eval_from_script_position =
+ factory()->NewForeign(&Accessors::ScriptEvalFromScriptPosition);
script_descriptors =
- Factory::CopyAppendProxyDescriptor(
+ factory()->CopyAppendForeignDescriptor(
script_descriptors,
- Factory::LookupAsciiSymbol("eval_from_script_position"),
- proxy_eval_from_script_position,
+ factory()->LookupAsciiSymbol("eval_from_script_position"),
+ foreign_eval_from_script_position,
common_attributes);
- Handle<Proxy> proxy_eval_from_function_name =
- Factory::NewProxy(&Accessors::ScriptEvalFromFunctionName);
+ Handle<Foreign> foreign_eval_from_function_name =
+ factory()->NewForeign(&Accessors::ScriptEvalFromFunctionName);
script_descriptors =
- Factory::CopyAppendProxyDescriptor(
+ factory()->CopyAppendForeignDescriptor(
script_descriptors,
- Factory::LookupAsciiSymbol("eval_from_function_name"),
- proxy_eval_from_function_name,
+ factory()->LookupAsciiSymbol("eval_from_function_name"),
+ foreign_eval_from_function_name,
common_attributes);
Handle<Map> script_map = Handle<Map>(script_fun->initial_map());
script_map->set_instance_descriptors(*script_descriptors);
// Allocate the empty script.
- Handle<Script> script = Factory::NewScript(Factory::empty_string());
+ Handle<Script> script = factory()->NewScript(factory()->empty_string());
script->set_type(Smi::FromInt(Script::TYPE_NATIVE));
- Heap::public_set_empty_script(*script);
+ heap()->public_set_empty_script(*script);
}
{
// Builtin function for OpaqueReference -- a JSValue-based object,
@@ -1232,14 +1498,52 @@ bool Genesis::InstallNatives() {
// objects, that JavaScript code may not access.
Handle<JSFunction> opaque_reference_fun =
InstallFunction(builtins, "OpaqueReference", JS_VALUE_TYPE,
- JSValue::kSize, Top::initial_object_prototype(),
- Builtins::Illegal, false);
+ JSValue::kSize,
+ isolate()->initial_object_prototype(),
+ Builtins::kIllegal, false);
Handle<JSObject> prototype =
- Factory::NewJSObject(Top::object_function(), TENURED);
+ factory()->NewJSObject(isolate()->object_function(), TENURED);
SetPrototype(opaque_reference_fun, prototype);
global_context()->set_opaque_reference_function(*opaque_reference_fun);
}
+ { // --- I n t e r n a l A r r a y ---
+ // An array constructor on the builtins object that works like
+ // the public Array constructor, except that its prototype
+ // doesn't inherit from Object.prototype.
+ // To be used only for internal work by builtins. Instances
+ // must not be leaked to user code.
+ // Only works correctly when called as a constructor. The normal
+ // Array code uses Array.prototype as prototype when called as
+ // a function.
+ Handle<JSFunction> array_function =
+ InstallFunction(builtins,
+ "InternalArray",
+ JS_ARRAY_TYPE,
+ JSArray::kSize,
+ isolate()->initial_object_prototype(),
+ Builtins::kArrayCode,
+ true);
+ Handle<JSObject> prototype =
+ factory()->NewJSObject(isolate()->object_function(), TENURED);
+ SetPrototype(array_function, prototype);
+
+ array_function->shared()->set_construct_stub(
+ isolate()->builtins()->builtin(Builtins::kArrayConstructCode));
+ array_function->shared()->DontAdaptArguments();
+
+ // Make "length" magic on instances.
+ Handle<DescriptorArray> array_descriptors =
+ factory()->CopyAppendForeignDescriptor(
+ factory()->empty_descriptor_array(),
+ factory()->length_symbol(),
+ factory()->NewForeign(&Accessors::ArrayLength),
+ static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE));
+
+ array_function->initial_map()->set_instance_descriptors(
+ *array_descriptors);
+ }
+
if (FLAG_disable_native_files) {
PrintF("Warning: Running without installed natives!\n");
return true;
@@ -1249,8 +1553,7 @@ bool Genesis::InstallNatives() {
for (int i = Natives::GetDebuggerCount();
i < Natives::GetBuiltinsCount();
i++) {
- Vector<const char> name = Natives::GetScriptName(i);
- if (!CompileBuiltin(i)) return false;
+ if (!CompileBuiltin(isolate(), i)) return false;
// TODO(ager): We really only need to install the JS builtin
// functions on the builtins object after compiling and running
// runtime.js.
@@ -1270,9 +1573,9 @@ bool Genesis::InstallNatives() {
InstallBuiltinFunctionIds();
// Install Function.prototype.call and apply.
- { Handle<String> key = Factory::function_class_symbol();
+ { Handle<String> key = factory()->function_class_symbol();
Handle<JSFunction> function =
- Handle<JSFunction>::cast(GetProperty(Top::global(), key));
+ Handle<JSFunction>::cast(GetProperty(isolate()->global(), key));
Handle<JSObject> proto =
Handle<JSObject>(JSObject::cast(function->instance_prototype()));
@@ -1280,12 +1583,12 @@ bool Genesis::InstallNatives() {
Handle<JSFunction> call =
InstallFunction(proto, "call", JS_OBJECT_TYPE, JSObject::kHeaderSize,
Handle<JSObject>::null(),
- Builtins::FunctionCall,
+ Builtins::kFunctionCall,
false);
Handle<JSFunction> apply =
InstallFunction(proto, "apply", JS_OBJECT_TYPE, JSObject::kHeaderSize,
Handle<JSObject>::null(),
- Builtins::FunctionApply,
+ Builtins::kFunctionApply,
false);
// Make sure that Function.prototype.call appears to be compiled.
@@ -1314,7 +1617,7 @@ bool Genesis::InstallNatives() {
// Add initial map.
Handle<Map> initial_map =
- Factory::NewMap(JS_ARRAY_TYPE, JSRegExpResult::kSize);
+ factory()->NewMap(JS_ARRAY_TYPE, JSRegExpResult::kSize);
initial_map->set_constructor(*array_constructor);
// Set prototype on map.
@@ -1328,13 +1631,13 @@ bool Genesis::InstallNatives() {
ASSERT_EQ(1, array_descriptors->number_of_descriptors());
Handle<DescriptorArray> reresult_descriptors =
- Factory::NewDescriptorArray(3);
+ factory()->NewDescriptorArray(3);
reresult_descriptors->CopyFrom(0, *array_descriptors, 0);
int enum_index = 0;
{
- FieldDescriptor index_field(Heap::index_symbol(),
+ FieldDescriptor index_field(heap()->index_symbol(),
JSRegExpResult::kIndexIndex,
NONE,
enum_index++);
@@ -1342,7 +1645,7 @@ bool Genesis::InstallNatives() {
}
{
- FieldDescriptor input_field(Heap::input_symbol(),
+ FieldDescriptor input_field(heap()->input_symbol(),
JSRegExpResult::kInputIndex,
NONE,
enum_index++);
@@ -1358,6 +1661,7 @@ bool Genesis::InstallNatives() {
global_context()->set_regexp_result_map(*initial_map);
}
+
#ifdef DEBUG
builtins->Verify();
#endif
@@ -1366,20 +1670,38 @@ bool Genesis::InstallNatives() {
}
+bool Genesis::InstallExperimentalNatives() {
+ for (int i = ExperimentalNatives::GetDebuggerCount();
+ i < ExperimentalNatives::GetBuiltinsCount();
+ i++) {
+ if (FLAG_harmony_proxies &&
+ strcmp(ExperimentalNatives::GetScriptName(i).start(),
+ "native proxy.js") == 0) {
+ if (!CompileExperimentalBuiltin(isolate(), i)) return false;
+ }
+ }
+
+ InstallExperimentalNativeFunctions();
+
+ return true;
+}
+
+
static Handle<JSObject> ResolveBuiltinIdHolder(
Handle<Context> global_context,
const char* holder_expr) {
+ Factory* factory = global_context->GetIsolate()->factory();
Handle<GlobalObject> global(global_context->global());
const char* period_pos = strchr(holder_expr, '.');
if (period_pos == NULL) {
return Handle<JSObject>::cast(
- GetProperty(global, Factory::LookupAsciiSymbol(holder_expr)));
+ GetProperty(global, factory->LookupAsciiSymbol(holder_expr)));
}
ASSERT_EQ(".prototype", period_pos);
Vector<const char> property(holder_expr,
static_cast<int>(period_pos - holder_expr));
Handle<JSFunction> function = Handle<JSFunction>::cast(
- GetProperty(global, Factory::LookupSymbol(property)));
+ GetProperty(global, factory->LookupSymbol(property)));
return Handle<JSObject>(JSObject::cast(function->prototype()));
}
@@ -1387,7 +1709,8 @@ static Handle<JSObject> ResolveBuiltinIdHolder(
static void InstallBuiltinFunctionId(Handle<JSObject> holder,
const char* function_name,
BuiltinFunctionId id) {
- Handle<String> name = Factory::LookupAsciiSymbol(function_name);
+ Factory* factory = holder->GetIsolate()->factory();
+ Handle<String> name = factory->LookupAsciiSymbol(function_name);
Object* function_object = holder->GetProperty(*name)->ToObjectUnchecked();
Handle<JSFunction> function(JSFunction::cast(function_object));
function->shared()->set_function_data(Smi::FromInt(id));
@@ -1414,13 +1737,14 @@ void Genesis::InstallBuiltinFunctionIds() {
F(16, global_context()->regexp_function())
-static FixedArray* CreateCache(int size, JSFunction* factory) {
+static FixedArray* CreateCache(int size, Handle<JSFunction> factory_function) {
+ Factory* factory = factory_function->GetIsolate()->factory();
// Caches are supposed to live for a long time, allocate in old space.
int array_size = JSFunctionResultCache::kEntriesIndex + 2 * size;
// Cannot use cast as object is not fully initialized yet.
JSFunctionResultCache* cache = reinterpret_cast<JSFunctionResultCache*>(
- *Factory::NewFixedArrayWithHoles(array_size, TENURED));
- cache->set(JSFunctionResultCache::kFactoryIndex, factory);
+ *factory->NewFixedArrayWithHoles(array_size, TENURED));
+ cache->set(JSFunctionResultCache::kFactoryIndex, *factory_function);
cache->MakeZeroSize();
return cache;
}
@@ -1433,13 +1757,13 @@ void Genesis::InstallJSFunctionResultCaches() {
#undef F
;
- Handle<FixedArray> caches = Factory::NewFixedArray(kNumberOfCaches, TENURED);
+ Handle<FixedArray> caches = FACTORY->NewFixedArray(kNumberOfCaches, TENURED);
int index = 0;
-#define F(size, func) do { \
- FixedArray* cache = CreateCache((size), (func)); \
- caches->set(index++, cache); \
+#define F(size, func) do { \
+ FixedArray* cache = CreateCache((size), Handle<JSFunction>(func)); \
+ caches->set(index++, cache); \
} while (false)
JSFUNCTION_RESULT_CACHE_LIST(F);
@@ -1452,19 +1776,17 @@ void Genesis::InstallJSFunctionResultCaches() {
void Genesis::InitializeNormalizedMapCaches() {
Handle<FixedArray> array(
- Factory::NewFixedArray(NormalizedMapCache::kEntries, TENURED));
+ FACTORY->NewFixedArray(NormalizedMapCache::kEntries, TENURED));
global_context()->set_normalized_map_cache(NormalizedMapCache::cast(*array));
}
-int BootstrapperActive::nesting_ = 0;
-
-
bool Bootstrapper::InstallExtensions(Handle<Context> global_context,
v8::ExtensionConfiguration* extensions) {
+ Isolate* isolate = global_context->GetIsolate();
BootstrapperActive active;
- SaveContext saved_context;
- Top::set_context(*global_context);
+ SaveContext saved_context(isolate);
+ isolate->set_context(*global_context);
if (!Genesis::InstallExtensions(global_context, extensions)) return false;
Genesis::InstallSpecialObjects(global_context);
return true;
@@ -1472,20 +1794,21 @@ bool Bootstrapper::InstallExtensions(Handle<Context> global_context,
void Genesis::InstallSpecialObjects(Handle<Context> global_context) {
+ Factory* factory = global_context->GetIsolate()->factory();
HandleScope scope;
Handle<JSGlobalObject> js_global(
JSGlobalObject::cast(global_context->global()));
// Expose the natives in global if a name for it is specified.
if (FLAG_expose_natives_as != NULL && strlen(FLAG_expose_natives_as) != 0) {
Handle<String> natives_string =
- Factory::LookupAsciiSymbol(FLAG_expose_natives_as);
+ factory->LookupAsciiSymbol(FLAG_expose_natives_as);
SetLocalPropertyNoThrow(js_global, natives_string,
Handle<JSObject>(js_global->builtins()), DONT_ENUM);
}
Handle<Object> Error = GetProperty(js_global, "Error");
if (Error->IsJSObject()) {
- Handle<String> name = Factory::LookupAsciiSymbol("stackTraceLimit");
+ Handle<String> name = factory->LookupAsciiSymbol("stackTraceLimit");
SetLocalPropertyNoThrow(Handle<JSObject>::cast(Error),
name,
Handle<Smi>(Smi::FromInt(FLAG_stack_trace_limit)),
@@ -1495,18 +1818,19 @@ void Genesis::InstallSpecialObjects(Handle<Context> global_context) {
#ifdef ENABLE_DEBUGGER_SUPPORT
// Expose the debug global object in global if a name for it is specified.
if (FLAG_expose_debug_as != NULL && strlen(FLAG_expose_debug_as) != 0) {
+ Debug* debug = Isolate::Current()->debug();
// If loading fails we just bail out without installing the
// debugger but without tanking the whole context.
- if (!Debug::Load()) return;
+ if (!debug->Load()) return;
// Set the security token for the debugger context to the same as
// the shell global context to allow calling between these (otherwise
// exposing debug global object doesn't make much sense).
- Debug::debug_context()->set_security_token(
+ debug->debug_context()->set_security_token(
global_context->security_token());
Handle<String> debug_string =
- Factory::LookupAsciiSymbol(FLAG_expose_debug_as);
- Handle<Object> global_proxy(Debug::debug_context()->global_proxy());
+ factory->LookupAsciiSymbol(FLAG_expose_debug_as);
+ Handle<Object> global_proxy(debug->debug_context()->global_proxy());
SetLocalPropertyNoThrow(js_global, debug_string, global_proxy, DONT_ENUM);
}
#endif
@@ -1515,6 +1839,10 @@ void Genesis::InstallSpecialObjects(Handle<Context> global_context) {
bool Genesis::InstallExtensions(Handle<Context> global_context,
v8::ExtensionConfiguration* extensions) {
+ // TODO(isolates): Extensions on multiple isolates may take a little more
+ // effort. (The external API reads 'ignore'-- does that mean
+ // we can break the interface?)
+
// Clear coloring of extension list
v8::RegisteredExtension* current = v8::RegisteredExtension::first_extension();
while (current != NULL) {
@@ -1582,17 +1910,18 @@ bool Genesis::InstallExtension(v8::RegisteredExtension* current) {
for (int i = 0; i < extension->dependency_count(); i++) {
if (!InstallExtension(extension->dependencies()[i])) return false;
}
+ Isolate* isolate = Isolate::Current();
Vector<const char> source = CStrVector(extension->source());
- Handle<String> source_code = Factory::NewStringFromAscii(source);
+ Handle<String> source_code = isolate->factory()->NewStringFromAscii(source);
bool result = CompileScriptCached(CStrVector(extension->name()),
source_code,
- &extensions_cache,
+ isolate->bootstrapper()->extensions_cache(),
extension,
- Handle<Context>(Top::context()),
+ Handle<Context>(isolate->context()),
false);
- ASSERT(Top::has_pending_exception() != result);
+ ASSERT(isolate->has_pending_exception() != result);
if (!result) {
- Top::clear_pending_exception();
+ isolate->clear_pending_exception();
}
current->set_state(v8::INSTALLED);
return result;
@@ -1601,9 +1930,10 @@ bool Genesis::InstallExtension(v8::RegisteredExtension* current) {
bool Genesis::InstallJSBuiltins(Handle<JSBuiltinsObject> builtins) {
HandleScope scope;
+ Factory* factory = builtins->GetIsolate()->factory();
for (int i = 0; i < Builtins::NumberOfJavaScriptBuiltins(); i++) {
Builtins::JavaScript id = static_cast<Builtins::JavaScript>(i);
- Handle<String> name = Factory::LookupAsciiSymbol(Builtins::GetName(id));
+ Handle<String> name = factory->LookupAsciiSymbol(Builtins::GetName(id));
Object* function_object = builtins->GetPropertyNoExceptionThrown(*name);
Handle<JSFunction> function
= Handle<JSFunction>(JSFunction::cast(function_object));
@@ -1656,8 +1986,8 @@ bool Genesis::ConfigureApiObject(Handle<JSObject> object,
Handle<JSObject> obj =
Execution::InstantiateObject(object_template, &pending_exception);
if (pending_exception) {
- ASSERT(Top::has_pending_exception());
- Top::clear_pending_exception();
+ ASSERT(isolate()->has_pending_exception());
+ isolate()->clear_pending_exception();
return false;
}
TransferObject(obj, object);
@@ -1705,14 +2035,16 @@ void Genesis::TransferNamedProperties(Handle<JSObject> from,
break;
}
case MAP_TRANSITION:
+ case EXTERNAL_ARRAY_TRANSITION:
case CONSTANT_TRANSITION:
case NULL_DESCRIPTOR:
// Ignore non-properties.
break;
case NORMAL:
// Do not occur since the from object has fast properties.
+ case HANDLER:
case INTERCEPTOR:
- // No element in instance descriptors have interceptor type.
+ // No element in instance descriptors have proxy or interceptor type.
UNREACHABLE();
break;
}
@@ -1748,13 +2080,14 @@ void Genesis::TransferIndexedProperties(Handle<JSObject> from,
// Cloning the elements array is sufficient.
Handle<FixedArray> from_elements =
Handle<FixedArray>(FixedArray::cast(from->elements()));
- Handle<FixedArray> to_elements = Factory::CopyFixedArray(from_elements);
+ Handle<FixedArray> to_elements = FACTORY->CopyFixedArray(from_elements);
to->set_elements(*to_elements);
}
void Genesis::TransferObject(Handle<JSObject> from, Handle<JSObject> to) {
HandleScope outer;
+ Factory* factory = from->GetIsolate()->factory();
ASSERT(!from->IsJSArray());
ASSERT(!to->IsJSArray());
@@ -1764,29 +2097,31 @@ void Genesis::TransferObject(Handle<JSObject> from, Handle<JSObject> to) {
// Transfer the prototype (new map is needed).
Handle<Map> old_to_map = Handle<Map>(to->map());
- Handle<Map> new_to_map = Factory::CopyMapDropTransitions(old_to_map);
+ Handle<Map> new_to_map = factory->CopyMapDropTransitions(old_to_map);
new_to_map->set_prototype(from->map()->prototype());
to->set_map(*new_to_map);
}
void Genesis::MakeFunctionInstancePrototypeWritable() {
- // Make a new function map so all future functions
- // will have settable and enumerable prototype properties.
- HandleScope scope;
-
- Handle<DescriptorArray> function_map_descriptors =
- ComputeFunctionInstanceDescriptor(ADD_WRITEABLE_PROTOTYPE);
- Handle<Map> fm = Factory::CopyMapDropDescriptors(Top::function_map());
- fm->set_instance_descriptors(*function_map_descriptors);
- fm->set_function_with_prototype(true);
- Top::context()->global_context()->set_function_map(*fm);
+ // The maps with writable prototype are created in CreateEmptyFunction
+ // and CreateStrictModeFunctionMaps respectively. Initially the maps are
+ // created with read-only prototype for JS builtins processing.
+ ASSERT(!function_instance_map_writable_prototype_.is_null());
+ ASSERT(!strict_mode_function_instance_map_writable_prototype_.is_null());
+
+ // Replace function instance maps to make prototype writable.
+ global_context()->set_function_map(
+ *function_instance_map_writable_prototype_);
+ global_context()->set_strict_mode_function_map(
+ *strict_mode_function_instance_map_writable_prototype_);
}
-Genesis::Genesis(Handle<Object> global_object,
+Genesis::Genesis(Isolate* isolate,
+ Handle<Object> global_object,
v8::Handle<v8::ObjectTemplate> global_template,
- v8::ExtensionConfiguration* extensions) {
+ v8::ExtensionConfiguration* extensions) : isolate_(isolate) {
result_ = Handle<Context>::null();
// If V8 isn't running and cannot be initialized, just return.
if (!V8::IsRunning() && !V8::Initialize(NULL)) return;
@@ -1794,18 +2129,15 @@ Genesis::Genesis(Handle<Object> global_object,
// Before creating the roots we must save the context and restore it
// on all function exits.
HandleScope scope;
- SaveContext saved_context;
+ SaveContext saved_context(isolate);
Handle<Context> new_context = Snapshot::NewContextFromSnapshot();
if (!new_context.is_null()) {
global_context_ =
- Handle<Context>::cast(GlobalHandles::Create(*new_context));
+ Handle<Context>::cast(isolate->global_handles()->Create(*new_context));
AddToWeakGlobalContextList(*global_context_);
- Top::set_context(*global_context_);
- i::Counters::contexts_created_by_snapshot.Increment();
- JSFunction* empty_function =
- JSFunction::cast(global_context_->function_map()->prototype());
- empty_function_ = Handle<JSFunction>(empty_function);
+ isolate->set_context(*global_context_);
+ isolate->counters()->contexts_created_by_snapshot()->Increment();
Handle<GlobalObject> inner_global;
Handle<JSGlobalProxy> global_proxy =
CreateNewGlobals(global_template,
@@ -1819,7 +2151,8 @@ Genesis::Genesis(Handle<Object> global_object,
} else {
// We get here if there was no context snapshot.
CreateRoots();
- Handle<JSFunction> empty_function = CreateEmptyFunction();
+ Handle<JSFunction> empty_function = CreateEmptyFunction(isolate);
+ CreateStrictModeFunctionMaps(empty_function);
Handle<GlobalObject> inner_global;
Handle<JSGlobalProxy> global_proxy =
CreateNewGlobals(global_template, global_object, &inner_global);
@@ -1832,9 +2165,12 @@ Genesis::Genesis(Handle<Object> global_object,
MakeFunctionInstancePrototypeWritable();
if (!ConfigureGlobalObjects(global_template)) return;
- i::Counters::contexts_created_from_scratch.Increment();
+ isolate->counters()->contexts_created_from_scratch()->Increment();
}
+ // Install experimental natives.
+ if (!InstallExperimentalNatives()) return;
+
result_ = global_context_;
}
@@ -1843,46 +2179,28 @@ Genesis::Genesis(Handle<Object> global_object,
// Reserve space for statics needing saving and restoring.
int Bootstrapper::ArchiveSpacePerThread() {
- return BootstrapperActive::ArchiveSpacePerThread();
+ return sizeof(NestingCounterType);
}
// Archive statics that are thread local.
char* Bootstrapper::ArchiveState(char* to) {
- return BootstrapperActive::ArchiveState(to);
+ *reinterpret_cast<NestingCounterType*>(to) = nesting_;
+ nesting_ = 0;
+ return to + sizeof(NestingCounterType);
}
// Restore statics that are thread local.
char* Bootstrapper::RestoreState(char* from) {
- return BootstrapperActive::RestoreState(from);
+ nesting_ = *reinterpret_cast<NestingCounterType*>(from);
+ return from + sizeof(NestingCounterType);
}
// Called when the top-level V8 mutex is destroyed.
void Bootstrapper::FreeThreadResources() {
- ASSERT(!BootstrapperActive::IsActive());
-}
-
-
-// Reserve space for statics needing saving and restoring.
-int BootstrapperActive::ArchiveSpacePerThread() {
- return sizeof(nesting_);
-}
-
-
-// Archive statics that are thread local.
-char* BootstrapperActive::ArchiveState(char* to) {
- *reinterpret_cast<int*>(to) = nesting_;
- nesting_ = 0;
- return to + sizeof(nesting_);
-}
-
-
-// Restore statics that are thread local.
-char* BootstrapperActive::RestoreState(char* from) {
- nesting_ = *reinterpret_cast<int*>(from);
- return from + sizeof(nesting_);
+ ASSERT(!IsActive());
}
} } // namespace v8::internal