Merge V8 at 3.9.24.13
Bug: 5688872
Change-Id: Id0aa8d23375030494d3189c31774059c0f5398fc
diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc
index f07e625..0e95b4b 100644
--- a/src/bootstrapper.cc
+++ b/src/bootstrapper.cc
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 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:
@@ -34,9 +34,11 @@
#include "debug.h"
#include "execution.h"
#include "global-handles.h"
+#include "isolate-inl.h"
#include "macro-assembler.h"
#include "natives.h"
#include "objects-visiting.h"
+#include "platform.h"
#include "snapshot.h"
#include "extensions/externalize-string-extension.h"
#include "extensions/gc-extension.h"
@@ -74,22 +76,15 @@
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(this,
- source.start(),
- source.length());
- Handle<String> 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::GetRawScriptSource(index));
- heap->natives_source_cache()->set(index, *source_code);
- }
+ // We can use external strings for the natives.
+ Vector<const char> source = Natives::GetRawScriptSource(index);
+ NativesExternalStringResource* resource =
+ new NativesExternalStringResource(this,
+ source.start(),
+ source.length());
+ Handle<String> source_code =
+ factory->NewExternalStringFromAscii(resource);
+ heap->natives_source_cache()->set(index, *source_code);
}
Handle<Object> cached_source(heap->natives_source_cache()->get(index));
return Handle<String>::cast(cached_source);
@@ -177,6 +172,10 @@
Handle<JSFunction> GetThrowTypeErrorFunction();
void CreateStrictModeFunctionMaps(Handle<JSFunction> empty);
+
+ // Make the "arguments" and "caller" properties throw a TypeError on access.
+ void PoisonArgumentsAndCaller(Handle<Map> map);
+
// 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
@@ -197,7 +196,7 @@
// detached from the other objects in the snapshot.
void HookUpInnerGlobal(Handle<GlobalObject> inner_global);
// New context initialization. Used for creating a context from scratch.
- void InitializeGlobal(Handle<GlobalObject> inner_global,
+ bool InitializeGlobal(Handle<GlobalObject> inner_global,
Handle<JSFunction> empty_function);
void InitializeExperimentalGlobal();
// Installs the contents of the native .js files on the global objects.
@@ -209,12 +208,30 @@
void InstallBuiltinFunctionIds();
void InstallJSFunctionResultCaches();
void InitializeNormalizedMapCaches();
+
+ enum ExtensionTraversalState {
+ UNVISITED, VISITED, INSTALLED
+ };
+
+ class ExtensionStates {
+ public:
+ ExtensionStates();
+ ExtensionTraversalState get_state(RegisteredExtension* extension);
+ void set_state(RegisteredExtension* extension,
+ ExtensionTraversalState state);
+ private:
+ HashMap map_;
+ DISALLOW_COPY_AND_ASSIGN(ExtensionStates);
+ };
+
// Used both for deserialized and from-scratch contexts to add the extensions
// provided.
static bool InstallExtensions(Handle<Context> global_context,
v8::ExtensionConfiguration* extensions);
- static bool InstallExtension(const char* name);
- static bool InstallExtension(v8::RegisteredExtension* current);
+ static bool InstallExtension(const char* name,
+ ExtensionStates* extension_states);
+ static bool InstallExtension(v8::RegisteredExtension* current,
+ ExtensionStates* extension_states);
static void InstallSpecialObjects(Handle<Context> global_context);
bool InstallJSBuiltins(Handle<JSBuiltinsObject> builtins);
bool ConfigureApiObject(Handle<JSObject> object,
@@ -242,14 +259,10 @@
Handle<Map> CreateStrictModeFunctionMap(
PrototypePropertyMode prototype_mode,
- Handle<JSFunction> empty_function,
- Handle<FixedArray> arguments_callbacks,
- Handle<FixedArray> caller_callbacks);
+ Handle<JSFunction> empty_function);
Handle<DescriptorArray> ComputeStrictFunctionInstanceDescriptor(
- PrototypePropertyMode propertyMode,
- Handle<FixedArray> arguments,
- Handle<FixedArray> caller);
+ PrototypePropertyMode propertyMode);
static bool CompileBuiltin(Isolate* isolate, int index);
static bool CompileExperimentalBuiltin(Isolate* isolate, int index);
@@ -278,7 +291,7 @@
void Bootstrapper::Iterate(ObjectVisitor* v) {
extensions_cache_.Iterate(v);
- v->Synchronize("Extensions");
+ v->Synchronize(VisitorSynchronization::kExtensions);
}
@@ -357,55 +370,56 @@
} else {
attributes = DONT_ENUM;
}
- SetLocalPropertyNoThrow(target, symbol, function, attributes);
+ CHECK_NOT_EMPTY_HANDLE(isolate,
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ target, symbol, function, attributes));
if (is_ecma_native) {
function->shared()->set_instance_class_name(*symbol);
}
+ function->shared()->set_native(true);
return function;
}
Handle<DescriptorArray> Genesis::ComputeFunctionInstanceDescriptor(
PrototypePropertyMode prototypeMode) {
- Handle<DescriptorArray> descriptors =
- factory()->NewDescriptorArray(prototypeMode == DONT_ADD_PROTOTYPE
- ? 4
- : 5);
- PropertyAttributes attributes =
- static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
+ int size = (prototypeMode == DONT_ADD_PROTOTYPE) ? 4 : 5;
+ Handle<DescriptorArray> descriptors(factory()->NewDescriptorArray(size));
+ PropertyAttributes attribs = static_cast<PropertyAttributes>(
+ DONT_ENUM | DONT_DELETE | READ_ONLY);
+
+ DescriptorArray::WhitenessWitness witness(*descriptors);
{ // Add length.
- Handle<Foreign> foreign = factory()->NewForeign(&Accessors::FunctionLength);
- CallbacksDescriptor d(*factory()->length_symbol(), *foreign, attributes);
- descriptors->Set(0, &d);
+ Handle<Foreign> f(factory()->NewForeign(&Accessors::FunctionLength));
+ CallbacksDescriptor d(*factory()->length_symbol(), *f, attribs);
+ descriptors->Set(0, &d, witness);
}
{ // Add name.
- Handle<Foreign> foreign = factory()->NewForeign(&Accessors::FunctionName);
- CallbacksDescriptor d(*factory()->name_symbol(), *foreign, attributes);
- descriptors->Set(1, &d);
+ Handle<Foreign> f(factory()->NewForeign(&Accessors::FunctionName));
+ CallbacksDescriptor d(*factory()->name_symbol(), *f, attribs);
+ descriptors->Set(1, &d, witness);
}
{ // Add arguments.
- Handle<Foreign> foreign =
- factory()->NewForeign(&Accessors::FunctionArguments);
- CallbacksDescriptor d(*factory()->arguments_symbol(), *foreign, attributes);
- descriptors->Set(2, &d);
+ Handle<Foreign> f(factory()->NewForeign(&Accessors::FunctionArguments));
+ CallbacksDescriptor d(*factory()->arguments_symbol(), *f, attribs);
+ descriptors->Set(2, &d, witness);
}
{ // Add caller.
- Handle<Foreign> foreign = factory()->NewForeign(&Accessors::FunctionCaller);
- CallbacksDescriptor d(*factory()->caller_symbol(), *foreign, attributes);
- descriptors->Set(3, &d);
+ Handle<Foreign> f(factory()->NewForeign(&Accessors::FunctionCaller));
+ CallbacksDescriptor d(*factory()->caller_symbol(), *f, attribs);
+ descriptors->Set(3, &d, witness);
}
if (prototypeMode != DONT_ADD_PROTOTYPE) {
// Add prototype.
if (prototypeMode == ADD_WRITEABLE_PROTOTYPE) {
- attributes = static_cast<PropertyAttributes>(attributes & ~READ_ONLY);
+ attribs = static_cast<PropertyAttributes>(attribs & ~READ_ONLY);
}
- Handle<Foreign> foreign =
- factory()->NewForeign(&Accessors::FunctionPrototype);
- CallbacksDescriptor d(*factory()->prototype_symbol(), *foreign, attributes);
- descriptors->Set(4, &d);
+ Handle<Foreign> f(factory()->NewForeign(&Accessors::FunctionPrototype));
+ CallbacksDescriptor d(*factory()->prototype_symbol(), *f, attribs);
+ descriptors->Set(4, &d, witness);
}
- descriptors->Sort();
+ descriptors->Sort(witness);
return descriptors;
}
@@ -478,7 +492,7 @@
// 262 15.3.4.
Handle<String> symbol = factory->LookupAsciiSymbol("Empty");
Handle<JSFunction> empty_function =
- factory->NewFunctionWithoutPrototype(symbol, kNonStrictMode);
+ factory->NewFunctionWithoutPrototype(symbol, CLASSIC_MODE);
// --- E m p t y ---
Handle<Code> code =
@@ -513,49 +527,46 @@
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);
+ PrototypePropertyMode prototypeMode) {
+ int size = (prototypeMode == DONT_ADD_PROTOTYPE) ? 4 : 5;
+ Handle<DescriptorArray> descriptors(factory()->NewDescriptorArray(size));
+ PropertyAttributes attribs = static_cast<PropertyAttributes>(
+ DONT_ENUM | DONT_DELETE);
- { // length
- Handle<Foreign> foreign = factory()->NewForeign(&Accessors::FunctionLength);
- CallbacksDescriptor d(*factory()->length_symbol(), *foreign, attributes);
- descriptors->Set(0, &d);
+ DescriptorArray::WhitenessWitness witness(*descriptors);
+
+ { // Add length.
+ Handle<Foreign> f(factory()->NewForeign(&Accessors::FunctionLength));
+ CallbacksDescriptor d(*factory()->length_symbol(), *f, attribs);
+ descriptors->Set(0, &d, witness);
}
- { // name
- Handle<Foreign> foreign = factory()->NewForeign(&Accessors::FunctionName);
- CallbacksDescriptor d(*factory()->name_symbol(), *foreign, attributes);
- descriptors->Set(1, &d);
+ { // Add name.
+ Handle<Foreign> f(factory()->NewForeign(&Accessors::FunctionName));
+ CallbacksDescriptor d(*factory()->name_symbol(), *f, attribs);
+ descriptors->Set(1, &d, witness);
}
- { // arguments
- CallbacksDescriptor d(*factory()->arguments_symbol(),
- *arguments,
- attributes);
- descriptors->Set(2, &d);
+ { // Add arguments.
+ Handle<AccessorPair> arguments(factory()->NewAccessorPair());
+ CallbacksDescriptor d(*factory()->arguments_symbol(), *arguments, attribs);
+ descriptors->Set(2, &d, witness);
}
- { // caller
- CallbacksDescriptor d(*factory()->caller_symbol(), *caller, attributes);
- descriptors->Set(3, &d);
+ { // Add caller.
+ Handle<AccessorPair> caller(factory()->NewAccessorPair());
+ CallbacksDescriptor d(*factory()->caller_symbol(), *caller, attribs);
+ descriptors->Set(3, &d, witness);
}
- // prototype
if (prototypeMode != DONT_ADD_PROTOTYPE) {
- if (prototypeMode == ADD_WRITEABLE_PROTOTYPE) {
- attributes = static_cast<PropertyAttributes>(attributes & ~READ_ONLY);
+ // Add prototype.
+ if (prototypeMode != ADD_WRITEABLE_PROTOTYPE) {
+ attribs = static_cast<PropertyAttributes>(attribs | READ_ONLY);
}
- Handle<Foreign> foreign =
- factory()->NewForeign(&Accessors::FunctionPrototype);
- CallbacksDescriptor d(*factory()->prototype_symbol(), *foreign, attributes);
- descriptors->Set(4, &d);
+ Handle<Foreign> f(factory()->NewForeign(&Accessors::FunctionPrototype));
+ CallbacksDescriptor d(*factory()->prototype_symbol(), *f, attribs);
+ descriptors->Set(4, &d, witness);
}
- descriptors->Sort();
+ descriptors->Sort(witness);
return descriptors;
}
@@ -565,7 +576,7 @@
if (throw_type_error_function.is_null()) {
Handle<String> name = factory()->LookupAsciiSymbol("ThrowTypeError");
throw_type_error_function =
- factory()->NewFunctionWithoutPrototype(name, kNonStrictMode);
+ factory()->NewFunctionWithoutPrototype(name, CLASSIC_MODE);
Handle<Code> code(isolate()->builtins()->builtin(
Builtins::kStrictModePoisonPill));
throw_type_error_function->set_map(
@@ -574,7 +585,7 @@
throw_type_error_function->shared()->set_code(*code);
throw_type_error_function->shared()->DontAdaptArguments();
- PreventExtensions(throw_type_error_function);
+ JSObject::PreventExtensions(throw_type_error_function);
}
return throw_type_error_function;
}
@@ -582,14 +593,10 @@
Handle<Map> Genesis::CreateStrictModeFunctionMap(
PrototypePropertyMode prototype_mode,
- Handle<JSFunction> empty_function,
- Handle<FixedArray> arguments_callbacks,
- Handle<FixedArray> caller_callbacks) {
+ Handle<JSFunction> empty_function) {
Handle<Map> map = factory()->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
Handle<DescriptorArray> descriptors =
- ComputeStrictFunctionInstanceDescriptor(prototype_mode,
- arguments_callbacks,
- caller_callbacks);
+ ComputeStrictFunctionInstanceDescriptor(prototype_mode);
map->set_instance_descriptors(*descriptors);
map->set_function_with_prototype(prototype_mode != DONT_ADD_PROTOTYPE);
map->set_prototype(*empty_function);
@@ -598,23 +605,15 @@
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);
+ CreateStrictModeFunctionMap(ADD_WRITEABLE_PROTOTYPE, empty);
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);
+ CreateStrictModeFunctionMap(DONT_ADD_PROTOTYPE, empty);
global_context()->set_strict_mode_function_without_prototype_map(
*strict_mode_function_without_prototype_map);
@@ -622,26 +621,38 @@
// 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);
+ CreateStrictModeFunctionMap(ADD_READONLY_PROTOTYPE, empty);
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);
+ CreateStrictModeFunctionMap(ADD_WRITEABLE_PROTOTYPE, empty);
- // Create the ThrowTypeError function instance.
- Handle<JSFunction> throw_function =
- GetThrowTypeErrorFunction();
+ // Complete the callbacks.
+ PoisonArgumentsAndCaller(strict_mode_function_instance_map);
+ PoisonArgumentsAndCaller(strict_mode_function_without_prototype_map);
+ PoisonArgumentsAndCaller(strict_mode_function_map);
+ PoisonArgumentsAndCaller(
+ strict_mode_function_instance_map_writable_prototype_);
+}
- // 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 SetAccessors(Handle<Map> map,
+ Handle<String> name,
+ Handle<JSFunction> func) {
+ DescriptorArray* descs = map->instance_descriptors();
+ int number = descs->Search(*name);
+ AccessorPair* accessors = AccessorPair::cast(descs->GetValue(number));
+ accessors->set_getter(*func);
+ accessors->set_setter(*func);
+}
+
+
+void Genesis::PoisonArgumentsAndCaller(Handle<Map> map) {
+ SetAccessors(map, factory()->arguments_symbol(), GetThrowTypeErrorFunction());
+ SetAccessors(map, factory()->caller_symbol(), GetThrowTypeErrorFunction());
}
@@ -727,11 +738,10 @@
Handle<JSObject> prototype =
Handle<JSObject>(
JSObject::cast(js_global_function->instance_prototype()));
- SetLocalPropertyNoThrow(
- prototype,
- factory()->constructor_symbol(),
- isolate()->object_function(),
- NONE);
+ CHECK_NOT_EMPTY_HANDLE(isolate(),
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ prototype, factory()->constructor_symbol(),
+ isolate()->object_function(), NONE));
} else {
Handle<FunctionTemplateInfo> js_global_constructor(
FunctionTemplateInfo::cast(js_global_template->constructor()));
@@ -808,7 +818,7 @@
factory()->LookupAsciiSymbol("global"),
inner_global,
attributes);
- // Setup the reference from the global object to the builtins object.
+ // Set up the reference from the global object to the builtins object.
JSGlobalObject::cast(*inner_global)->set_builtins(*builtins_global);
TransferNamedProperties(inner_global_from_snapshot, inner_global);
TransferIndexedProperties(inner_global_from_snapshot, inner_global);
@@ -817,7 +827,7 @@
// This is only called if we are not using snapshots. The equivalent
// work in the snapshot case is done in HookUpInnerGlobal.
-void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
+bool Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
Handle<JSFunction> empty_function) {
// --- G l o b a l C o n t e x t ---
// Use the empty function as closure (no scope info).
@@ -837,8 +847,10 @@
Heap* heap = isolate->heap();
Handle<String> object_name = Handle<String>(heap->Object_symbol());
- SetLocalPropertyNoThrow(inner_global, object_name,
- isolate->object_function(), DONT_ENUM);
+ CHECK_NOT_EMPTY_HANDLE(isolate,
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ inner_global, object_name,
+ isolate->object_function(), DONT_ENUM));
Handle<JSObject> global = Handle<JSObject>(global_context()->global());
@@ -865,15 +877,12 @@
factory->NewForeign(&Accessors::ArrayLength),
static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE));
- // Cache the fast JavaScript array map
- global_context()->set_js_array_map(array_function->initial_map());
- global_context()->js_array_map()->set_instance_descriptors(
- *array_descriptors);
// array_function is used internally. JS code creating array object should
// search for the 'Array' property on the global object and use that one
// as the constructor. 'Array' property on a global object can be
// overwritten by JS code.
global_context()->set_array_function(*array_function);
+ array_function->initial_map()->set_instance_descriptors(*array_descriptors);
}
{ // --- N u m b e r ---
@@ -918,7 +927,7 @@
{ // --- D a t e ---
// Builtin functions for Date.prototype.
Handle<JSFunction> date_fun =
- InstallFunction(global, "Date", JS_VALUE_TYPE, JSValue::kSize,
+ InstallFunction(global, "Date", JS_DATE_TYPE, JSDate::kSize,
isolate->initial_object_prototype(),
Builtins::kIllegal, true);
@@ -940,6 +949,7 @@
ASSERT_EQ(0, initial_map->inobject_properties());
Handle<DescriptorArray> descriptors = factory->NewDescriptorArray(5);
+ DescriptorArray::WhitenessWitness witness(*descriptors);
PropertyAttributes final =
static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
int enum_index = 0;
@@ -949,7 +959,7 @@
JSRegExp::kSourceFieldIndex,
final,
enum_index++);
- descriptors->Set(0, &field);
+ descriptors->Set(0, &field, witness);
}
{
// ECMA-262, section 15.10.7.2.
@@ -957,7 +967,7 @@
JSRegExp::kGlobalFieldIndex,
final,
enum_index++);
- descriptors->Set(1, &field);
+ descriptors->Set(1, &field, witness);
}
{
// ECMA-262, section 15.10.7.3.
@@ -965,7 +975,7 @@
JSRegExp::kIgnoreCaseFieldIndex,
final,
enum_index++);
- descriptors->Set(2, &field);
+ descriptors->Set(2, &field, witness);
}
{
// ECMA-262, section 15.10.7.4.
@@ -973,7 +983,7 @@
JSRegExp::kMultilineFieldIndex,
final,
enum_index++);
- descriptors->Set(3, &field);
+ descriptors->Set(3, &field, witness);
}
{
// ECMA-262, section 15.10.7.5.
@@ -983,10 +993,10 @@
JSRegExp::kLastIndexFieldIndex,
writable,
enum_index++);
- descriptors->Set(4, &field);
+ descriptors->Set(4, &field, witness);
}
descriptors->SetNextEnumerationIndex(enum_index);
- descriptors->Sort();
+ descriptors->Sort(witness);
initial_map->set_inobject_properties(5);
initial_map->set_pre_allocated_property_fields(5);
@@ -995,18 +1005,42 @@
initial_map->instance_size() + 5 * kPointerSize);
initial_map->set_instance_descriptors(*descriptors);
initial_map->set_visitor_id(StaticVisitorBase::GetVisitorId(*initial_map));
+
+ // RegExp prototype object is itself a RegExp.
+ Handle<Map> proto_map = factory->CopyMapDropTransitions(initial_map);
+ proto_map->set_prototype(global_context()->initial_object_prototype());
+ Handle<JSObject> proto = factory->NewJSObjectFromMap(proto_map);
+ proto->InObjectPropertyAtPut(JSRegExp::kSourceFieldIndex,
+ heap->empty_string());
+ proto->InObjectPropertyAtPut(JSRegExp::kGlobalFieldIndex,
+ heap->false_value());
+ proto->InObjectPropertyAtPut(JSRegExp::kIgnoreCaseFieldIndex,
+ heap->false_value());
+ proto->InObjectPropertyAtPut(JSRegExp::kMultilineFieldIndex,
+ heap->false_value());
+ proto->InObjectPropertyAtPut(JSRegExp::kLastIndexFieldIndex,
+ Smi::FromInt(0),
+ SKIP_WRITE_BARRIER); // It's a Smi.
+ initial_map->set_prototype(*proto);
+ factory->SetRegExpIrregexpData(Handle<JSRegExp>::cast(proto),
+ JSRegExp::IRREGEXP, factory->empty_string(),
+ JSRegExp::Flags(0), 0);
}
{ // -- J S O N
Handle<String> name = factory->NewStringFromAscii(CStrVector("JSON"));
- Handle<JSFunction> cons = factory->NewFunction(
- name,
- factory->the_hole_value());
- cons->SetInstancePrototype(global_context()->initial_object_prototype());
+ Handle<JSFunction> cons = factory->NewFunction(name,
+ factory->the_hole_value());
+ { MaybeObject* result = cons->SetInstancePrototype(
+ global_context()->initial_object_prototype());
+ if (result->IsFailure()) return false;
+ }
cons->SetInstanceClassName(*name);
Handle<JSObject> json_object = factory->NewJSObject(cons, TENURED);
ASSERT(json_object->IsJSObject());
- SetLocalPropertyNoThrow(global, name, json_object, DONT_ENUM);
+ CHECK_NOT_EMPTY_HANDLE(isolate,
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ global, name, json_object, DONT_ENUM));
global_context()->set_json_object(*json_object);
}
@@ -1036,21 +1070,23 @@
global_context()->set_arguments_boilerplate(*result);
// 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->callee_symbol(),
- factory->undefined_value(),
- DONT_ENUM);
+ CHECK_NOT_EMPTY_HANDLE(isolate,
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ result, factory->length_symbol(),
+ factory->undefined_value(), DONT_ENUM));
+ CHECK_NOT_EMPTY_HANDLE(isolate,
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ result, factory->callee_symbol(),
+ factory->undefined_value(), DONT_ENUM));
#ifdef DEBUG
- LookupResult lookup;
+ LookupResult lookup(isolate);
result->LocalLookup(heap->callee_symbol(), &lookup);
- ASSERT(lookup.IsProperty() && (lookup.type() == FIELD));
+ ASSERT(lookup.IsFound() && (lookup.type() == FIELD));
ASSERT(lookup.GetFieldIndex() == Heap::kArgumentsCalleeIndex);
result->LocalLookup(heap->length_symbol(), &lookup);
- ASSERT(lookup.IsProperty() && (lookup.type() == FIELD));
+ ASSERT(lookup.IsFound() && (lookup.type() == FIELD));
ASSERT(lookup.GetFieldIndex() == Heap::kArgumentsLengthIndex);
ASSERT(result->map()->inobject_properties() > Heap::kArgumentsCalleeIndex);
@@ -1063,11 +1099,6 @@
}
{ // --- 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(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());
@@ -1076,7 +1107,16 @@
elements->set(0, *array);
array = factory->NewFixedArray(0);
elements->set(1, *array);
+
+ 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);
+ // Set elements kind after allocating the object because
+ // NewJSObjectFromMap assumes a fast elements map.
+ new_map->set_elements_kind(NON_STRICT_ARGUMENTS_ELEMENTS);
result->set_elements(*elements);
+ ASSERT(result->HasNonStrictArgumentsElements());
global_context()->set_aliased_arguments_boilerplate(*result);
}
@@ -1085,33 +1125,34 @@
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<AccessorPair> callee = factory->NewAccessorPair();
+ Handle<AccessorPair> caller = factory->NewAccessorPair();
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);
+ callee->set_getter(*throw_function);
+ callee->set_setter(*throw_function);
+ caller->set_getter(*throw_function);
+ caller->set_setter(*throw_function);
// Create the descriptor array for the arguments object.
Handle<DescriptorArray> descriptors = factory->NewDescriptorArray(3);
+ DescriptorArray::WhitenessWitness witness(*descriptors);
{ // length
FieldDescriptor d(*factory->length_symbol(), 0, DONT_ENUM);
- descriptors->Set(0, &d);
+ descriptors->Set(0, &d, witness);
}
{ // callee
CallbacksDescriptor d(*factory->callee_symbol(), *callee, attributes);
- descriptors->Set(1, &d);
+ descriptors->Set(1, &d, witness);
}
{ // caller
CallbacksDescriptor d(*factory->caller_symbol(), *caller, attributes);
- descriptors->Set(2, &d);
+ descriptors->Set(2, &d, witness);
}
- descriptors->Sort();
+ descriptors->Sort(witness);
// Create the map. Allocate one in-object field for length.
Handle<Map> map = factory->NewMap(JS_OBJECT_TYPE,
@@ -1131,14 +1172,15 @@
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);
+ CHECK_NOT_EMPTY_HANDLE(isolate,
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ result, factory->length_symbol(),
+ factory->undefined_value(), DONT_ENUM));
#ifdef DEBUG
- LookupResult lookup;
+ LookupResult lookup(isolate);
result->LocalLookup(heap->length_symbol(), &lookup);
- ASSERT(lookup.IsProperty() && (lookup.type() == FIELD));
+ ASSERT(lookup.IsFound() && (lookup.type() == FIELD));
ASSERT(lookup.GetFieldIndex() == Heap::kArgumentsLengthIndex);
ASSERT(result->map()->inobject_properties() > Heap::kArgumentsLengthIndex);
@@ -1195,6 +1237,15 @@
// Initialize the data slot.
global_context()->set_data(heap->undefined_value());
+
+ {
+ // Initialize the random seed slot.
+ Handle<ByteArray> zeroed_byte_array(
+ factory->NewByteArray(kRandomStateSize));
+ global_context()->set_random_seed(*zeroed_byte_array);
+ memset(zeroed_byte_array->GetDataStartAddress(), 0, kRandomStateSize);
+ }
+ return true;
}
@@ -1202,12 +1253,26 @@
Handle<JSObject> global = Handle<JSObject>(global_context()->global());
// TODO(mstarzinger): Move this into Genesis::InitializeGlobal once we no
- // longer need to live behind a flag, so WeakMap gets added to the snapshot.
- if (FLAG_harmony_weakmaps) { // -- W e a k M a p
- Handle<JSObject> prototype =
- factory()->NewJSObject(isolate()->object_function(), TENURED);
- InstallFunction(global, "WeakMap", JS_WEAK_MAP_TYPE, JSWeakMap::kSize,
- prototype, Builtins::kIllegal, true);
+ // longer need to live behind a flag, so functions get added to the snapshot.
+ if (FLAG_harmony_collections) {
+ { // -- S e t
+ Handle<JSObject> prototype =
+ factory()->NewJSObject(isolate()->object_function(), TENURED);
+ InstallFunction(global, "Set", JS_SET_TYPE, JSSet::kSize,
+ prototype, Builtins::kIllegal, true);
+ }
+ { // -- M a p
+ Handle<JSObject> prototype =
+ factory()->NewJSObject(isolate()->object_function(), TENURED);
+ InstallFunction(global, "Map", JS_MAP_TYPE, JSMap::kSize,
+ prototype, Builtins::kIllegal, true);
+ }
+ { // -- W e a k M a p
+ Handle<JSObject> prototype =
+ factory()->NewJSObject(isolate()->object_function(), TENURED);
+ InstallFunction(global, "WeakMap", JS_WEAK_MAP_TYPE, JSWeakMap::kSize,
+ prototype, Builtins::kIllegal, true);
+ }
}
}
@@ -1236,6 +1301,12 @@
#ifdef ENABLE_DEBUGGER_SUPPORT
isolate->debugger()->set_compiling_natives(true);
#endif
+ // During genesis, the boilerplate for stack overflow won't work until the
+ // environment has been at least partially initialized. Add a stack check
+ // before entering JS code to catch overflow early.
+ StackLimitCheck check(Isolate::Current());
+ if (check.HasOverflowed()) return false;
+
bool result = CompileScriptCached(name,
source,
NULL,
@@ -1279,7 +1350,7 @@
if (cache != NULL) cache->Add(name, function_info);
}
- // Setup the function context. Conceptually, we should clone the
+ // Set up the function context. Conceptually, we should clone the
// function before overwriting the context but since we're in a
// single-threaded environment it is not strictly necessary.
ASSERT(top_context->IsGlobalContext());
@@ -1327,6 +1398,8 @@
configure_instance_fun);
INSTALL_NATIVE(JSFunction, "GetStackTraceLine", get_stack_trace_line_fun);
INSTALL_NATIVE(JSObject, "functionCache", function_cache);
+ INSTALL_NATIVE(JSFunction, "ToCompletePropertyDescriptor",
+ to_complete_property_descriptor);
}
void Genesis::InstallExperimentalNativeFunctions() {
@@ -1334,6 +1407,7 @@
INSTALL_NATIVE(JSFunction, "DerivedHasTrap", derived_has_trap);
INSTALL_NATIVE(JSFunction, "DerivedGetTrap", derived_get_trap);
INSTALL_NATIVE(JSFunction, "DerivedSetTrap", derived_set_trap);
+ INSTALL_NATIVE(JSFunction, "ProxyEnumerate", proxy_enumerate);
}
}
@@ -1363,7 +1437,7 @@
builtins->set_global_context(*global_context());
builtins->set_global_receiver(*builtins);
- // Setup the 'global' properties of the builtins object. The
+ // Set up the 'global' properties of the builtins object. The
// 'global' property that refers to the global object is the only
// way to get from code running in the builtins context to the
// global object.
@@ -1371,9 +1445,11 @@
static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE);
Handle<String> global_symbol = factory()->LookupAsciiSymbol("global");
Handle<Object> global_obj(global_context()->global());
- SetLocalPropertyNoThrow(builtins, global_symbol, global_obj, attributes);
+ CHECK_NOT_EMPTY_HANDLE(isolate(),
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ builtins, global_symbol, global_obj, attributes));
- // Setup the reference from the global object to the builtins object.
+ // Set up the reference from the global object to the builtins object.
JSGlobalObject::cast(global_context()->global())->set_builtins(*builtins);
// Create a bridge function that has context in the global context.
@@ -1536,16 +1612,13 @@
// 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,
+ Builtins::kInternalArrayCode,
true);
Handle<JSObject> prototype =
factory()->NewJSObject(isolate()->object_function(), TENURED);
@@ -1555,6 +1628,18 @@
isolate()->builtins()->builtin(Builtins::kArrayConstructCode));
array_function->shared()->DontAdaptArguments();
+ // InternalArrays should not use Smi-Only array optimizations. There are too
+ // many places in the C++ runtime code (e.g. RegEx) that assume that
+ // elements in InternalArrays can be set to non-Smi values without going
+ // through a common bottleneck that would make the SMI_ONLY -> FAST_ELEMENT
+ // transition easy to trap. Moreover, they rarely are smi-only.
+ MaybeObject* maybe_map =
+ array_function->initial_map()->CopyDropTransitions();
+ Map* new_map;
+ if (!maybe_map->To<Map>(&new_map)) return false;
+ new_map->set_elements_kind(FAST_ELEMENTS);
+ array_function->set_initial_map(new_map);
+
// Make "length" magic on instances.
Handle<DescriptorArray> array_descriptors =
factory()->CopyAppendForeignDescriptor(
@@ -1565,6 +1650,8 @@
array_function->initial_map()->set_instance_descriptors(
*array_descriptors);
+
+ global_context()->set_internal_array_function(*array_function);
}
if (FLAG_disable_native_files) {
@@ -1586,7 +1673,7 @@
InstallNativeFunctions();
// Store the map for the string prototype after the natives has been compiled
- // and the String function has been setup.
+ // and the String function has been set up.
Handle<JSFunction> string_function(global_context()->string_function());
ASSERT(JSObject::cast(
string_function->initial_map()->prototype())->HasFastProperties());
@@ -1648,15 +1735,17 @@
initial_map->set_prototype(*array_prototype);
// Update map with length accessor from Array and add "index" and "input".
- Handle<Map> array_map(global_context()->js_array_map());
- Handle<DescriptorArray> array_descriptors(
- array_map->instance_descriptors());
- ASSERT_EQ(1, array_descriptors->number_of_descriptors());
-
Handle<DescriptorArray> reresult_descriptors =
factory()->NewDescriptorArray(3);
+ DescriptorArray::WhitenessWitness witness(*reresult_descriptors);
- reresult_descriptors->CopyFrom(0, *array_descriptors, 0);
+ JSFunction* array_function = global_context()->array_function();
+ Handle<DescriptorArray> array_descriptors(
+ array_function->initial_map()->instance_descriptors());
+ int index = array_descriptors->SearchWithCache(heap()->length_symbol());
+ MaybeObject* copy_result =
+ reresult_descriptors->CopyFrom(0, *array_descriptors, index, witness);
+ if (copy_result->IsFailure()) return false;
int enum_index = 0;
{
@@ -1664,7 +1753,7 @@
JSRegExpResult::kIndexIndex,
NONE,
enum_index++);
- reresult_descriptors->Set(1, &index_field);
+ reresult_descriptors->Set(1, &index_field, witness);
}
{
@@ -1672,9 +1761,9 @@
JSRegExpResult::kInputIndex,
NONE,
enum_index++);
- reresult_descriptors->Set(2, &input_field);
+ reresult_descriptors->Set(2, &input_field, witness);
}
- reresult_descriptors->Sort();
+ reresult_descriptors->Sort(witness);
initial_map->set_inobject_properties(2);
initial_map->set_pre_allocated_property_fields(2);
@@ -1701,9 +1790,9 @@
"native proxy.js") == 0) {
if (!CompileExperimentalBuiltin(isolate(), i)) return false;
}
- if (FLAG_harmony_weakmaps &&
+ if (FLAG_harmony_collections &&
strcmp(ExperimentalNatives::GetScriptName(i).start(),
- "native weakmap.js") == 0) {
+ "native collection.js") == 0) {
if (!CompileExperimentalBuiltin(isolate(), i)) return false;
}
}
@@ -1821,25 +1910,28 @@
void Genesis::InstallSpecialObjects(Handle<Context> global_context) {
- Factory* factory = global_context->GetIsolate()->factory();
+ Isolate* isolate = global_context->GetIsolate();
+ Factory* factory = isolate->factory();
HandleScope scope;
- Handle<JSGlobalObject> js_global(
- JSGlobalObject::cast(global_context->global()));
+ Handle<JSGlobalObject> 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);
- SetLocalPropertyNoThrow(js_global, natives_string,
- Handle<JSObject>(js_global->builtins()), DONT_ENUM);
+ Handle<String> natives = factory->LookupAsciiSymbol(FLAG_expose_natives_as);
+ CHECK_NOT_EMPTY_HANDLE(isolate,
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ global, natives,
+ Handle<JSObject>(global->builtins()),
+ DONT_ENUM));
}
- Handle<Object> Error = GetProperty(js_global, "Error");
+ Handle<Object> Error = GetProperty(global, "Error");
if (Error->IsJSObject()) {
Handle<String> name = factory->LookupAsciiSymbol("stackTraceLimit");
- SetLocalPropertyNoThrow(Handle<JSObject>::cast(Error),
- name,
- Handle<Smi>(Smi::FromInt(FLAG_stack_trace_limit)),
- NONE);
+ Handle<Smi> stack_trace_limit(Smi::FromInt(FLAG_stack_trace_limit));
+ CHECK_NOT_EMPTY_HANDLE(isolate,
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ Handle<JSObject>::cast(Error), name,
+ stack_trace_limit, NONE));
}
#ifdef ENABLE_DEBUGGER_SUPPORT
@@ -1858,11 +1950,39 @@
Handle<String> debug_string =
factory->LookupAsciiSymbol(FLAG_expose_debug_as);
Handle<Object> global_proxy(debug->debug_context()->global_proxy());
- SetLocalPropertyNoThrow(js_global, debug_string, global_proxy, DONT_ENUM);
+ CHECK_NOT_EMPTY_HANDLE(isolate,
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ global, debug_string, global_proxy, DONT_ENUM));
}
#endif
}
+static uint32_t Hash(RegisteredExtension* extension) {
+ return v8::internal::ComputePointerHash(extension);
+}
+
+static bool MatchRegisteredExtensions(void* key1, void* key2) {
+ return key1 == key2;
+}
+
+Genesis::ExtensionStates::ExtensionStates()
+ : map_(MatchRegisteredExtensions, 8) { }
+
+Genesis::ExtensionTraversalState Genesis::ExtensionStates::get_state(
+ RegisteredExtension* extension) {
+ i::HashMap::Entry* entry = map_.Lookup(extension, Hash(extension), false);
+ if (entry == NULL) {
+ return UNVISITED;
+ }
+ return static_cast<ExtensionTraversalState>(
+ reinterpret_cast<intptr_t>(entry->value));
+}
+
+void Genesis::ExtensionStates::set_state(RegisteredExtension* extension,
+ ExtensionTraversalState state) {
+ map_.Lookup(extension, Hash(extension), true)->value =
+ reinterpret_cast<void*>(static_cast<intptr_t>(state));
+}
bool Genesis::InstallExtensions(Handle<Context> global_context,
v8::ExtensionConfiguration* extensions) {
@@ -1870,29 +1990,27 @@
// effort. (The external API reads 'ignore'-- does that mean
// we can break the interface?)
- // Clear coloring of extension list
+
+ ExtensionStates extension_states; // All extensions have state UNVISITED.
+ // Install auto extensions.
v8::RegisteredExtension* current = v8::RegisteredExtension::first_extension();
while (current != NULL) {
- current->set_state(v8::UNVISITED);
- current = current->next();
- }
- // Install auto extensions.
- current = v8::RegisteredExtension::first_extension();
- while (current != NULL) {
if (current->extension()->auto_enable())
- InstallExtension(current);
+ InstallExtension(current, &extension_states);
current = current->next();
}
- if (FLAG_expose_gc) InstallExtension("v8/gc");
- if (FLAG_expose_externalize_string) InstallExtension("v8/externalize");
+ if (FLAG_expose_gc) InstallExtension("v8/gc", &extension_states);
+ if (FLAG_expose_externalize_string) {
+ InstallExtension("v8/externalize", &extension_states);
+ }
if (extensions == NULL) return true;
// Install required extensions
int count = v8::ImplementationUtilities::GetNameCount(extensions);
const char** names = v8::ImplementationUtilities::GetNames(extensions);
for (int i = 0; i < count; i++) {
- if (!InstallExtension(names[i]))
+ if (!InstallExtension(names[i], &extension_states))
return false;
}
@@ -1902,7 +2020,8 @@
// Installs a named extension. This methods is unoptimized and does
// not scale well if we want to support a large number of extensions.
-bool Genesis::InstallExtension(const char* name) {
+bool Genesis::InstallExtension(const char* name,
+ ExtensionStates* extension_states) {
v8::RegisteredExtension* current = v8::RegisteredExtension::first_extension();
// Loop until we find the relevant extension
while (current != NULL) {
@@ -1915,42 +2034,52 @@
"v8::Context::New()", "Cannot find required extension");
return false;
}
- return InstallExtension(current);
+ return InstallExtension(current, extension_states);
}
-bool Genesis::InstallExtension(v8::RegisteredExtension* current) {
+bool Genesis::InstallExtension(v8::RegisteredExtension* current,
+ ExtensionStates* extension_states) {
HandleScope scope;
- if (current->state() == v8::INSTALLED) return true;
+ if (extension_states->get_state(current) == INSTALLED) return true;
// The current node has already been visited so there must be a
// cycle in the dependency graph; fail.
- if (current->state() == v8::VISITED) {
+ if (extension_states->get_state(current) == VISITED) {
v8::Utils::ReportApiFailure(
"v8::Context::New()", "Circular extension dependency");
return false;
}
- ASSERT(current->state() == v8::UNVISITED);
- current->set_state(v8::VISITED);
+ ASSERT(extension_states->get_state(current) == UNVISITED);
+ extension_states->set_state(current, VISITED);
v8::Extension* extension = current->extension();
// Install the extension's dependencies
for (int i = 0; i < extension->dependency_count(); i++) {
- if (!InstallExtension(extension->dependencies()[i])) return false;
+ if (!InstallExtension(extension->dependencies()[i], extension_states))
+ return false;
}
Isolate* isolate = Isolate::Current();
- Vector<const char> source = CStrVector(extension->source());
- Handle<String> source_code = isolate->factory()->NewStringFromAscii(source);
- bool result = CompileScriptCached(CStrVector(extension->name()),
- source_code,
- isolate->bootstrapper()->extensions_cache(),
- extension,
- Handle<Context>(isolate->context()),
- false);
+ Handle<String> source_code =
+ isolate->factory()->NewExternalStringFromAscii(extension->source());
+ bool result = CompileScriptCached(
+ CStrVector(extension->name()),
+ source_code,
+ isolate->bootstrapper()->extensions_cache(),
+ extension,
+ Handle<Context>(isolate->context()),
+ false);
ASSERT(isolate->has_pending_exception() != result);
if (!result) {
+ // We print out the name of the extension that fail to install.
+ // When an error is thrown during bootstrapping we automatically print
+ // the line number at which this happened to the console in the isolate
+ // error throwing functionality.
+ OS::PrintError("Error installing extension '%s'.\n",
+ current->extension()->name());
isolate->clear_pending_exception();
}
- current->set_state(v8::INSTALLED);
+ extension_states->set_state(current, INSTALLED);
+ isolate->NotifyExtensionInstalled();
return result;
}
@@ -1967,7 +2096,9 @@
builtins->set_javascript_builtin(id, *function);
Handle<SharedFunctionInfo> shared
= Handle<SharedFunctionInfo>(function->shared());
- if (!EnsureCompiled(shared, CLEAR_EXCEPTION)) return false;
+ if (!SharedFunctionInfo::EnsureCompiled(shared, CLEAR_EXCEPTION)) {
+ return false;
+ }
// Set the code object on the function object.
function->ReplaceCode(function->shared()->code());
builtins->set_javascript_builtin_code(id, shared->code());
@@ -2035,7 +2166,9 @@
Handle<String> key = Handle<String>(descs->GetKey(i));
int index = descs->GetFieldIndex(i);
Handle<Object> value = Handle<Object>(from->FastPropertyAt(index));
- SetLocalPropertyNoThrow(to, key, value, details.attributes());
+ CHECK_NOT_EMPTY_HANDLE(to->GetIsolate(),
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ to, key, value, details.attributes()));
break;
}
case CONSTANT_FUNCTION: {
@@ -2043,11 +2176,13 @@
Handle<String> key = Handle<String>(descs->GetKey(i));
Handle<JSFunction> fun =
Handle<JSFunction>(descs->GetConstantFunction(i));
- SetLocalPropertyNoThrow(to, key, fun, details.attributes());
+ CHECK_NOT_EMPTY_HANDLE(to->GetIsolate(),
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ to, key, fun, details.attributes()));
break;
}
case CALLBACKS: {
- LookupResult result;
+ LookupResult result(isolate());
to->LocalLookup(descs->GetKey(i), &result);
// If the property is already there we skip it
if (result.IsProperty()) continue;
@@ -2058,7 +2193,7 @@
Handle<Object> callbacks(descs->GetCallbacksObject(i));
PropertyDetails d =
PropertyDetails(details.attributes(), CALLBACKS, details.index());
- SetNormalizedProperty(to, key, callbacks, d);
+ JSObject::SetNormalizedProperty(to, key, callbacks, d);
break;
}
case MAP_TRANSITION:
@@ -2085,7 +2220,7 @@
if (properties->IsKey(raw_key)) {
ASSERT(raw_key->IsString());
// If the property is already there we skip it.
- LookupResult result;
+ LookupResult result(isolate());
to->LocalLookup(String::cast(raw_key), &result);
if (result.IsProperty()) continue;
// Set the property.
@@ -2095,7 +2230,9 @@
value = Handle<Object>(JSGlobalPropertyCell::cast(*value)->value());
}
PropertyDetails details = properties->DetailsAt(i);
- SetLocalPropertyNoThrow(to, key, value, details.attributes());
+ CHECK_NOT_EMPTY_HANDLE(to->GetIsolate(),
+ JSObject::SetLocalPropertyIgnoreAttributes(
+ to, key, value, details.attributes()));
}
}
}
@@ -2158,6 +2295,12 @@
HandleScope scope;
SaveContext saved_context(isolate);
+ // During genesis, the boilerplate for stack overflow won't work until the
+ // environment has been at least partially initialized. Add a stack check
+ // before entering JS code to catch overflow early.
+ StackLimitCheck check(Isolate::Current());
+ if (check.HasOverflowed()) return;
+
Handle<Context> new_context = Snapshot::NewContextFromSnapshot();
if (!new_context.is_null()) {
global_context_ =
@@ -2184,7 +2327,7 @@
Handle<JSGlobalProxy> global_proxy =
CreateNewGlobals(global_template, global_object, &inner_global);
HookUpGlobalProxy(inner_global, global_proxy);
- InitializeGlobal(inner_global, empty_function);
+ if (!InitializeGlobal(inner_global, empty_function)) return;
InstallJSFunctionResultCaches();
InitializeNormalizedMapCaches();
if (!InstallNatives()) return;