diff options
Diffstat (limited to 'deps/v8/src/bootstrapper.cc')
-rw-r--r-- | deps/v8/src/bootstrapper.cc | 1289 |
1 files changed, 644 insertions, 645 deletions
diff --git a/deps/v8/src/bootstrapper.cc b/deps/v8/src/bootstrapper.cc index 1e59f725c..240be7191 100644 --- a/deps/v8/src/bootstrapper.cc +++ b/deps/v8/src/bootstrapper.cc @@ -2,19 +2,19 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "bootstrapper.h" - -#include "accessors.h" -#include "isolate-inl.h" -#include "natives.h" -#include "snapshot.h" -#include "trig-table.h" -#include "extensions/externalize-string-extension.h" -#include "extensions/free-buffer-extension.h" -#include "extensions/gc-extension.h" -#include "extensions/statistics-extension.h" -#include "extensions/trigger-failure-extension.h" -#include "code-stubs.h" +#include "src/bootstrapper.h" + +#include "src/accessors.h" +#include "src/code-stubs.h" +#include "src/extensions/externalize-string-extension.h" +#include "src/extensions/free-buffer-extension.h" +#include "src/extensions/gc-extension.h" +#include "src/extensions/statistics-extension.h" +#include "src/extensions/trigger-failure-extension.h" +#include "src/isolate-inl.h" +#include "src/natives.h" +#include "src/snapshot.h" +#include "third_party/fdlibm/fdlibm.h" namespace v8 { namespace internal { @@ -44,7 +44,7 @@ Bootstrapper::Bootstrapper(Isolate* isolate) Handle<String> Bootstrapper::NativesSourceLookup(int index) { - ASSERT(0 <= index && index < Natives::GetBuiltinsCount()); + DCHECK(0 <= index && index < Natives::GetBuiltinsCount()); Heap* heap = isolate_->heap(); if (heap->natives_source_cache()->get(index)->IsUndefined()) { // We can use external strings for the natives. @@ -121,7 +121,7 @@ char* Bootstrapper::AllocateAutoDeletedArray(int bytes) { void Bootstrapper::TearDown() { if (delete_these_non_arrays_on_tear_down_ != NULL) { int len = delete_these_non_arrays_on_tear_down_->length(); - ASSERT(len < 24); // Don't use this mechanism for unbounded allocations. + DCHECK(len < 27); // 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; @@ -132,7 +132,7 @@ void Bootstrapper::TearDown() { 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. + DCHECK(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; @@ -148,8 +148,8 @@ void Bootstrapper::TearDown() { class Genesis BASE_EMBEDDED { public: Genesis(Isolate* isolate, - Handle<Object> global_object, - v8::Handle<v8::ObjectTemplate> global_template, + MaybeHandle<JSGlobalProxy> maybe_global_proxy, + v8::Handle<v8::ObjectTemplate> global_proxy_template, v8::ExtensionConfiguration* extensions); ~Genesis() { } @@ -167,7 +167,9 @@ class Genesis BASE_EMBEDDED { // Creates the empty function. Used for creating a context from scratch. Handle<JSFunction> CreateEmptyFunction(Isolate* isolate); // Creates the ThrowTypeError function. ECMA 5th Ed. 13.2.3 - Handle<JSFunction> GetThrowTypeErrorFunction(); + Handle<JSFunction> GetStrictPoisonFunction(); + // Poison for sloppy generator function arguments/callee. + Handle<JSFunction> GetGeneratorPoisonFunction(); void CreateStrictModeFunctionMaps(Handle<JSFunction> empty); @@ -181,26 +183,25 @@ class Genesis BASE_EMBEDDED { // we have to used the deserialized ones that are linked together with the // rest of the context snapshot. Handle<JSGlobalProxy> CreateNewGlobals( - v8::Handle<v8::ObjectTemplate> global_template, - Handle<Object> global_object, - Handle<GlobalObject>* global_proxy_out); + v8::Handle<v8::ObjectTemplate> global_proxy_template, + MaybeHandle<JSGlobalProxy> maybe_global_proxy, + Handle<GlobalObject>* global_object_out); // Hooks the given global proxy into the context. If the context was created // by deserialization then this will unhook the global proxy that was // deserialized, leaving the GC to pick it up. - void HookUpGlobalProxy(Handle<GlobalObject> inner_global, + void HookUpGlobalProxy(Handle<GlobalObject> global_object, Handle<JSGlobalProxy> global_proxy); - // Similarly, we want to use the inner global that has been created by the - // templates passed through the API. The inner global from the snapshot is - // detached from the other objects in the snapshot. - void HookUpInnerGlobal(Handle<GlobalObject> inner_global); + // Similarly, we want to use the global that has been created by the templates + // passed through the API. The global from the snapshot is detached from the + // other objects in the snapshot. + void HookUpGlobalObject(Handle<GlobalObject> global_object); // New context initialization. Used for creating a context from scratch. - void InitializeGlobal(Handle<GlobalObject> inner_global, + void InitializeGlobal(Handle<GlobalObject> global_object, Handle<JSFunction> empty_function); void InitializeExperimentalGlobal(); // Installs the contents of the native .js files on the global objects. // Used for creating a context from scratch. void InstallNativeFunctions(); - void InstallExperimentalBuiltinFunctionIds(); void InstallExperimentalNativeFunctions(); Handle<JSFunction> InstallInternalArray(Handle<JSBuiltinsObject> builtins, const char* name, @@ -251,7 +252,8 @@ class Genesis BASE_EMBEDDED { bool InstallJSBuiltins(Handle<JSBuiltinsObject> builtins); bool ConfigureApiObject(Handle<JSObject> object, Handle<ObjectTemplateInfo> object_template); - bool ConfigureGlobalObjects(v8::Handle<v8::ObjectTemplate> global_template); + bool ConfigureGlobalObjects( + v8::Handle<v8::ObjectTemplate> global_proxy_template); // Migrates all properties from the 'from' object to the 'to' // object and overrides the prototype in 'to' with the one from @@ -260,24 +262,32 @@ class Genesis BASE_EMBEDDED { void TransferNamedProperties(Handle<JSObject> from, Handle<JSObject> to); void TransferIndexedProperties(Handle<JSObject> from, Handle<JSObject> to); - enum PrototypePropertyMode { - DONT_ADD_PROTOTYPE, - ADD_READONLY_PROTOTYPE, - ADD_WRITEABLE_PROTOTYPE + enum FunctionMode { + // With prototype. + FUNCTION_WITH_WRITEABLE_PROTOTYPE, + FUNCTION_WITH_READONLY_PROTOTYPE, + // Without prototype. + FUNCTION_WITHOUT_PROTOTYPE, + BOUND_FUNCTION }; - Handle<Map> CreateFunctionMap(PrototypePropertyMode prototype_mode); + static bool IsFunctionModeWithPrototype(FunctionMode function_mode) { + return (function_mode == FUNCTION_WITH_WRITEABLE_PROTOTYPE || + function_mode == FUNCTION_WITH_READONLY_PROTOTYPE); + } + + Handle<Map> CreateFunctionMap(FunctionMode function_mode); void SetFunctionInstanceDescriptor(Handle<Map> map, - PrototypePropertyMode prototypeMode); + FunctionMode function_mode); void MakeFunctionInstancePrototypeWritable(); Handle<Map> CreateStrictFunctionMap( - PrototypePropertyMode prototype_mode, + FunctionMode function_mode, Handle<JSFunction> empty_function); void SetStrictFunctionInstanceDescriptor(Handle<Map> map, - PrototypePropertyMode propertyMode); + FunctionMode function_mode); static bool CompileBuiltin(Isolate* isolate, int index); static bool CompileExperimentalBuiltin(Isolate* isolate, int index); @@ -302,7 +312,8 @@ class Genesis BASE_EMBEDDED { // prototype, maps. Handle<Map> sloppy_function_map_writable_prototype_; Handle<Map> strict_function_map_writable_prototype_; - Handle<JSFunction> throw_type_error_function; + Handle<JSFunction> strict_poison_function; + Handle<JSFunction> generator_poison_function; BootstrapperActive active_; friend class Bootstrapper; @@ -316,11 +327,12 @@ void Bootstrapper::Iterate(ObjectVisitor* v) { Handle<Context> Bootstrapper::CreateEnvironment( - Handle<Object> global_object, - v8::Handle<v8::ObjectTemplate> global_template, + MaybeHandle<JSGlobalProxy> maybe_global_proxy, + v8::Handle<v8::ObjectTemplate> global_proxy_template, v8::ExtensionConfiguration* extensions) { HandleScope scope(isolate_); - Genesis genesis(isolate_, global_object, global_template, extensions); + Genesis genesis( + isolate_, maybe_global_proxy, global_proxy_template, extensions); Handle<Context> env = genesis.result(); if (env.is_null() || !InstallExtensions(env, extensions)) { return Handle<Context>(); @@ -331,10 +343,10 @@ Handle<Context> Bootstrapper::CreateEnvironment( static void SetObjectPrototype(Handle<JSObject> object, Handle<Object> proto) { // object.__proto__ = proto; - Handle<Map> old_to_map = Handle<Map>(object->map()); - Handle<Map> new_to_map = Map::Copy(old_to_map); - new_to_map->set_prototype(*proto); - object->set_map(*new_to_map); + Handle<Map> old_map = Handle<Map>(object->map()); + Handle<Map> new_map = Map::Copy(old_map); + new_map->set_prototype(*proto); + JSObject::MigrateToMap(object, new_map); } @@ -343,6 +355,7 @@ void Bootstrapper::DetachGlobal(Handle<Context> env) { Handle<JSGlobalProxy> global_proxy(JSGlobalProxy::cast(env->global_proxy())); global_proxy->set_native_context(*factory->null_value()); SetObjectPrototype(global_proxy, factory->null_value()); + global_proxy->map()->set_constructor(*factory->null_value()); } @@ -350,22 +363,17 @@ static Handle<JSFunction> InstallFunction(Handle<JSObject> target, const char* name, InstanceType type, int instance_size, - Handle<JSObject> prototype, - Builtins::Name call, - bool install_initial_map, - bool set_instance_class_name) { + MaybeHandle<JSObject> maybe_prototype, + Builtins::Name call) { Isolate* isolate = target->GetIsolate(); Factory* factory = isolate->factory(); Handle<String> internalized_name = factory->InternalizeUtf8String(name); Handle<Code> call_code = Handle<Code>(isolate->builtins()->builtin(call)); - Handle<JSFunction> function = prototype.is_null() - ? factory->NewFunction(internalized_name, call_code) - : factory->NewFunctionWithPrototype(internalized_name, - type, - instance_size, - prototype, - call_code, - install_initial_map); + Handle<JSObject> prototype; + Handle<JSFunction> function = maybe_prototype.ToHandle(&prototype) + ? factory->NewFunction(internalized_name, call_code, prototype, + type, instance_size) + : factory->NewFunctionWithoutPrototype(internalized_name, call_code); PropertyAttributes attributes; if (target->IsJSBuiltinsObject()) { attributes = @@ -373,9 +381,8 @@ static Handle<JSFunction> InstallFunction(Handle<JSObject> target, } else { attributes = DONT_ENUM; } - JSObject::SetLocalPropertyIgnoreAttributes( - target, internalized_name, function, attributes).Check(); - if (set_instance_class_name) { + JSObject::AddProperty(target, internalized_name, function, attributes); + if (target->IsJSGlobalObject()) { function->shared()->set_instance_class_name(*internalized_name); } function->shared()->set_native(true); @@ -384,8 +391,8 @@ static Handle<JSFunction> InstallFunction(Handle<JSObject> target, void Genesis::SetFunctionInstanceDescriptor( - Handle<Map> map, PrototypePropertyMode prototypeMode) { - int size = (prototypeMode == DONT_ADD_PROTOTYPE) ? 4 : 5; + Handle<Map> map, FunctionMode function_mode) { + int size = IsFunctionModeWithPrototype(function_mode) ? 5 : 4; Map::EnsureDescriptorSlack(map, size); PropertyAttributes attribs = static_cast<PropertyAttributes>( @@ -419,8 +426,8 @@ void Genesis::SetFunctionInstanceDescriptor( caller, attribs); map->AppendDescriptor(&d); } - if (prototypeMode != DONT_ADD_PROTOTYPE) { - if (prototypeMode == ADD_WRITEABLE_PROTOTYPE) { + if (IsFunctionModeWithPrototype(function_mode)) { + if (function_mode == FUNCTION_WITH_WRITEABLE_PROTOTYPE) { attribs = static_cast<PropertyAttributes>(attribs & ~READ_ONLY); } Handle<AccessorInfo> prototype = @@ -432,10 +439,10 @@ void Genesis::SetFunctionInstanceDescriptor( } -Handle<Map> Genesis::CreateFunctionMap(PrototypePropertyMode prototype_mode) { +Handle<Map> Genesis::CreateFunctionMap(FunctionMode function_mode) { Handle<Map> map = factory()->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize); - SetFunctionInstanceDescriptor(map, prototype_mode); - map->set_function_with_prototype(prototype_mode != DONT_ADD_PROTOTYPE); + SetFunctionInstanceDescriptor(map, function_mode); + map->set_function_with_prototype(IsFunctionModeWithPrototype(function_mode)); return map; } @@ -447,32 +454,36 @@ Handle<JSFunction> Genesis::CreateEmptyFunction(Isolate* isolate) { // Functions with this map will not have a 'prototype' property, and // can not be used as constructors. Handle<Map> function_without_prototype_map = - CreateFunctionMap(DONT_ADD_PROTOTYPE); + CreateFunctionMap(FUNCTION_WITHOUT_PROTOTYPE); native_context()->set_sloppy_function_without_prototype_map( *function_without_prototype_map); // 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); + Handle<Map> function_map = + CreateFunctionMap(FUNCTION_WITH_READONLY_PROTOTYPE); native_context()->set_sloppy_function_map(*function_map); + native_context()->set_sloppy_function_with_readonly_prototype_map( + *function_map); // The final map for functions. Writeable prototype. // This map is installed in MakeFunctionInstancePrototypeWritable. sloppy_function_map_writable_prototype_ = - CreateFunctionMap(ADD_WRITEABLE_PROTOTYPE); + CreateFunctionMap(FUNCTION_WITH_WRITEABLE_PROTOTYPE); Factory* factory = isolate->factory(); Handle<String> object_name = factory->Object_string(); { // --- O b j e c t --- - Handle<JSFunction> object_fun = factory->NewFunctionWithPrototype( - object_name, factory->null_value()); + Handle<JSFunction> object_fun = factory->NewFunction(object_name); Handle<Map> object_function_map = factory->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); - object_fun->set_initial_map(*object_function_map); - object_function_map->set_constructor(*object_fun); + JSFunction::SetInitialMap(object_fun, object_function_map, + isolate->factory()->null_value()); + object_function_map->set_unused_property_fields( + JSObject::kInitialGlobalObjectUnusedPropertiesCount); native_context()->set_object_function(*object_fun); @@ -480,6 +491,9 @@ Handle<JSFunction> Genesis::CreateEmptyFunction(Isolate* isolate) { Handle<JSObject> prototype = factory->NewJSObject( isolate->object_function(), TENURED); + Handle<Map> map = Map::Copy(handle(prototype->map())); + map->set_is_prototype_map(true); + prototype->set_map(*map); native_context()->set_initial_object_prototype(*prototype); // For bootstrapping set the array prototype to be the same as the object @@ -494,7 +508,17 @@ Handle<JSFunction> Genesis::CreateEmptyFunction(Isolate* isolate) { Handle<String> empty_string = factory->InternalizeOneByteString(STATIC_ASCII_VECTOR("Empty")); Handle<Code> code(isolate->builtins()->builtin(Builtins::kEmptyFunction)); - Handle<JSFunction> empty_function = factory->NewFunction(empty_string, code); + Handle<JSFunction> empty_function = factory->NewFunctionWithoutPrototype( + empty_string, code); + + // Allocate the function map first and then patch the prototype later + Handle<Map> empty_function_map = + CreateFunctionMap(FUNCTION_WITHOUT_PROTOTYPE); + DCHECK(!empty_function_map->is_dictionary_map()); + empty_function_map->set_prototype( + native_context()->object_function()->prototype()); + empty_function_map->set_is_prototype_map(true); + empty_function->set_map(*empty_function_map); // --- E m p t y --- Handle<String> source = factory->NewStringFromStaticAscii("() {}"); @@ -510,19 +534,13 @@ Handle<JSFunction> Genesis::CreateEmptyFunction(Isolate* isolate) { native_context()->sloppy_function_without_prototype_map()-> set_prototype(*empty_function); sloppy_function_map_writable_prototype_->set_prototype(*empty_function); - - // Allocate the function map first and then patch the prototype later - Handle<Map> empty_function_map = CreateFunctionMap(DONT_ADD_PROTOTYPE); - empty_function_map->set_prototype( - native_context()->object_function()->prototype()); - empty_function->set_map(*empty_function_map); return empty_function; } void Genesis::SetStrictFunctionInstanceDescriptor( - Handle<Map> map, PrototypePropertyMode prototypeMode) { - int size = (prototypeMode == DONT_ADD_PROTOTYPE) ? 4 : 5; + Handle<Map> map, FunctionMode function_mode) { + int size = IsFunctionModeWithPrototype(function_mode) ? 5 : 4; Map::EnsureDescriptorSlack(map, size); Handle<AccessorPair> arguments(factory()->NewAccessorPair()); @@ -532,9 +550,17 @@ void Genesis::SetStrictFunctionInstanceDescriptor( PropertyAttributes ro_attribs = static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY); - Handle<AccessorInfo> length = - Accessors::FunctionLengthInfo(isolate(), ro_attribs); - { // Add length. + // Add length. + if (function_mode == BOUND_FUNCTION) { + Handle<String> length_string = isolate()->factory()->length_string(); + FieldDescriptor d(length_string, 0, ro_attribs, Representation::Tagged()); + map->AppendDescriptor(&d); + } else { + DCHECK(function_mode == FUNCTION_WITH_WRITEABLE_PROTOTYPE || + function_mode == FUNCTION_WITH_READONLY_PROTOTYPE || + function_mode == FUNCTION_WITHOUT_PROTOTYPE); + Handle<AccessorInfo> length = + Accessors::FunctionLengthInfo(isolate(), ro_attribs); CallbacksDescriptor d(Handle<Name>(Name::cast(length->name())), length, ro_attribs); map->AppendDescriptor(&d); @@ -555,10 +581,11 @@ void Genesis::SetStrictFunctionInstanceDescriptor( CallbacksDescriptor d(factory()->caller_string(), caller, rw_attribs); map->AppendDescriptor(&d); } - if (prototypeMode != DONT_ADD_PROTOTYPE) { + if (IsFunctionModeWithPrototype(function_mode)) { // Add prototype. PropertyAttributes attribs = - prototypeMode == ADD_WRITEABLE_PROTOTYPE ? rw_attribs : ro_attribs; + function_mode == FUNCTION_WITH_WRITEABLE_PROTOTYPE ? rw_attribs + : ro_attribs; Handle<AccessorInfo> prototype = Accessors::FunctionPrototypeInfo(isolate(), attribs); CallbacksDescriptor d(Handle<Name>(Name::cast(prototype->name())), @@ -569,28 +596,45 @@ void Genesis::SetStrictFunctionInstanceDescriptor( // ECMAScript 5th Edition, 13.2.3 -Handle<JSFunction> Genesis::GetThrowTypeErrorFunction() { - if (throw_type_error_function.is_null()) { +Handle<JSFunction> Genesis::GetStrictPoisonFunction() { + if (strict_poison_function.is_null()) { Handle<String> name = factory()->InternalizeOneByteString( STATIC_ASCII_VECTOR("ThrowTypeError")); Handle<Code> code(isolate()->builtins()->builtin( Builtins::kStrictModePoisonPill)); - throw_type_error_function = factory()->NewFunction(name, code); - throw_type_error_function->set_map(native_context()->sloppy_function_map()); - throw_type_error_function->shared()->DontAdaptArguments(); + strict_poison_function = factory()->NewFunctionWithoutPrototype(name, code); + strict_poison_function->set_map(native_context()->sloppy_function_map()); + strict_poison_function->shared()->DontAdaptArguments(); - JSObject::PreventExtensions(throw_type_error_function).Assert(); + JSObject::PreventExtensions(strict_poison_function).Assert(); } - return throw_type_error_function; + return strict_poison_function; +} + + +Handle<JSFunction> Genesis::GetGeneratorPoisonFunction() { + if (generator_poison_function.is_null()) { + Handle<String> name = factory()->InternalizeOneByteString( + STATIC_ASCII_VECTOR("ThrowTypeError")); + Handle<Code> code(isolate()->builtins()->builtin( + Builtins::kGeneratorPoisonPill)); + generator_poison_function = factory()->NewFunctionWithoutPrototype( + name, code); + generator_poison_function->set_map(native_context()->sloppy_function_map()); + generator_poison_function->shared()->DontAdaptArguments(); + + JSObject::PreventExtensions(generator_poison_function).Assert(); + } + return generator_poison_function; } Handle<Map> Genesis::CreateStrictFunctionMap( - PrototypePropertyMode prototype_mode, + FunctionMode function_mode, Handle<JSFunction> empty_function) { Handle<Map> map = factory()->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize); - SetStrictFunctionInstanceDescriptor(map, prototype_mode); - map->set_function_with_prototype(prototype_mode != DONT_ADD_PROTOTYPE); + SetStrictFunctionInstanceDescriptor(map, function_mode); + map->set_function_with_prototype(IsFunctionModeWithPrototype(function_mode)); map->set_prototype(*empty_function); return map; } @@ -599,7 +643,7 @@ Handle<Map> Genesis::CreateStrictFunctionMap( void Genesis::CreateStrictModeFunctionMaps(Handle<JSFunction> empty) { // Allocate map for the prototype-less strict mode instances. Handle<Map> strict_function_without_prototype_map = - CreateStrictFunctionMap(DONT_ADD_PROTOTYPE, empty); + CreateStrictFunctionMap(FUNCTION_WITHOUT_PROTOTYPE, empty); native_context()->set_strict_function_without_prototype_map( *strict_function_without_prototype_map); @@ -607,18 +651,23 @@ void Genesis::CreateStrictModeFunctionMaps(Handle<JSFunction> empty) { // only for processing of builtins. // Later the map is replaced with writable prototype map, allocated below. Handle<Map> strict_function_map = - CreateStrictFunctionMap(ADD_READONLY_PROTOTYPE, empty); + CreateStrictFunctionMap(FUNCTION_WITH_READONLY_PROTOTYPE, empty); native_context()->set_strict_function_map(*strict_function_map); // The final map for the strict mode functions. Writeable prototype. // This map is installed in MakeFunctionInstancePrototypeWritable. strict_function_map_writable_prototype_ = - CreateStrictFunctionMap(ADD_WRITEABLE_PROTOTYPE, empty); + CreateStrictFunctionMap(FUNCTION_WITH_WRITEABLE_PROTOTYPE, empty); + // Special map for bound functions. + Handle<Map> bound_function_map = + CreateStrictFunctionMap(BOUND_FUNCTION, empty); + native_context()->set_bound_function_map(*bound_function_map); // Complete the callbacks. PoisonArgumentsAndCaller(strict_function_without_prototype_map); PoisonArgumentsAndCaller(strict_function_map); PoisonArgumentsAndCaller(strict_function_map_writable_prototype_); + PoisonArgumentsAndCaller(bound_function_map); } @@ -633,23 +682,34 @@ static void SetAccessors(Handle<Map> map, } +static void ReplaceAccessors(Handle<Map> map, + Handle<String> name, + PropertyAttributes attributes, + Handle<AccessorPair> accessor_pair) { + DescriptorArray* descriptors = map->instance_descriptors(); + int idx = descriptors->SearchWithCache(*name, *map); + CallbacksDescriptor descriptor(name, accessor_pair, attributes); + descriptors->Replace(idx, &descriptor); +} + + void Genesis::PoisonArgumentsAndCaller(Handle<Map> map) { - SetAccessors(map, factory()->arguments_string(), GetThrowTypeErrorFunction()); - SetAccessors(map, factory()->caller_string(), GetThrowTypeErrorFunction()); + SetAccessors(map, factory()->arguments_string(), GetStrictPoisonFunction()); + SetAccessors(map, factory()->caller_string(), GetStrictPoisonFunction()); } static void AddToWeakNativeContextList(Context* context) { - ASSERT(context->IsNativeContext()); + DCHECK(context->IsNativeContext()); Heap* heap = context->GetIsolate()->heap(); #ifdef DEBUG { // NOLINT - ASSERT(context->get(Context::NEXT_CONTEXT_LINK)->IsUndefined()); + DCHECK(context->get(Context::NEXT_CONTEXT_LINK)->IsUndefined()); // Check that context is not in the list yet. for (Object* current = heap->native_contexts_list(); !current->IsUndefined(); current = Context::cast(current)->get(Context::NEXT_CONTEXT_LINK)) { - ASSERT(current != context); + DCHECK(current != context); } } #endif @@ -676,89 +736,89 @@ void Genesis::CreateRoots() { Handle<JSGlobalProxy> Genesis::CreateNewGlobals( - v8::Handle<v8::ObjectTemplate> global_template, - Handle<Object> global_object, - Handle<GlobalObject>* inner_global_out) { - // The argument global_template aka data is an ObjectTemplateInfo. + v8::Handle<v8::ObjectTemplate> global_proxy_template, + MaybeHandle<JSGlobalProxy> maybe_global_proxy, + Handle<GlobalObject>* global_object_out) { + // The argument global_proxy_template aka data is an ObjectTemplateInfo. // It has a constructor pointer that points at global_constructor which is a // FunctionTemplateInfo. - // The global_constructor is used to create or reinitialize the global_proxy. - // The global_constructor also has a prototype_template pointer that points at - // js_global_template which is an ObjectTemplateInfo. + // The global_proxy_constructor is used to create or reinitialize the + // global_proxy. The global_proxy_constructor also has a prototype_template + // pointer that points at js_global_object_template which is an + // ObjectTemplateInfo. // That in turn has a constructor pointer that points at - // js_global_constructor which is a FunctionTemplateInfo. - // js_global_constructor is used to make js_global_function - // js_global_function is used to make the new inner_global. + // js_global_object_constructor which is a FunctionTemplateInfo. + // js_global_object_constructor is used to make js_global_object_function + // js_global_object_function is used to make the new global_object. // // --- G l o b a l --- - // Step 1: Create a fresh inner JSGlobalObject. - Handle<JSFunction> js_global_function; - Handle<ObjectTemplateInfo> js_global_template; - if (!global_template.IsEmpty()) { - // Get prototype template of the global_template. + // Step 1: Create a fresh JSGlobalObject. + Handle<JSFunction> js_global_object_function; + Handle<ObjectTemplateInfo> js_global_object_template; + if (!global_proxy_template.IsEmpty()) { + // Get prototype template of the global_proxy_template. Handle<ObjectTemplateInfo> data = - v8::Utils::OpenHandle(*global_template); + v8::Utils::OpenHandle(*global_proxy_template); Handle<FunctionTemplateInfo> global_constructor = Handle<FunctionTemplateInfo>( FunctionTemplateInfo::cast(data->constructor())); Handle<Object> proto_template(global_constructor->prototype_template(), isolate()); if (!proto_template->IsUndefined()) { - js_global_template = + js_global_object_template = Handle<ObjectTemplateInfo>::cast(proto_template); } } - if (js_global_template.is_null()) { + if (js_global_object_template.is_null()) { Handle<String> name = Handle<String>(heap()->empty_string()); Handle<Code> code = Handle<Code>(isolate()->builtins()->builtin( Builtins::kIllegal)); - js_global_function = - 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())); - JSObject::SetLocalPropertyIgnoreAttributes( - prototype, factory()->constructor_string(), - isolate()->object_function(), NONE).Check(); + factory()->NewFunctionPrototype(isolate()->object_function()); + js_global_object_function = factory()->NewFunction( + name, code, prototype, JS_GLOBAL_OBJECT_TYPE, JSGlobalObject::kSize); +#ifdef DEBUG + LookupIterator it(prototype, factory()->constructor_string(), + LookupIterator::CHECK_OWN_REAL); + Handle<Object> value = JSReceiver::GetProperty(&it).ToHandleChecked(); + DCHECK(it.IsFound()); + DCHECK_EQ(*isolate()->object_function(), *value); +#endif } else { - Handle<FunctionTemplateInfo> js_global_constructor( - FunctionTemplateInfo::cast(js_global_template->constructor())); - js_global_function = - factory()->CreateApiFunction(js_global_constructor, + Handle<FunctionTemplateInfo> js_global_object_constructor( + FunctionTemplateInfo::cast(js_global_object_template->constructor())); + js_global_object_function = + factory()->CreateApiFunction(js_global_object_constructor, factory()->the_hole_value(), - factory()->InnerGlobalObject); + factory()->GlobalObjectType); } - js_global_function->initial_map()->set_is_hidden_prototype(); - js_global_function->initial_map()->set_dictionary_map(true); - Handle<GlobalObject> inner_global = - factory()->NewGlobalObject(js_global_function); - if (inner_global_out != NULL) { - *inner_global_out = inner_global; + js_global_object_function->initial_map()->set_is_hidden_prototype(); + js_global_object_function->initial_map()->set_dictionary_map(true); + Handle<GlobalObject> global_object = + factory()->NewGlobalObject(js_global_object_function); + if (global_object_out != NULL) { + *global_object_out = global_object; } // Step 2: create or re-initialize the global proxy object. Handle<JSFunction> global_proxy_function; - if (global_template.IsEmpty()) { + if (global_proxy_template.IsEmpty()) { Handle<String> name = Handle<String>(heap()->empty_string()); Handle<Code> code = Handle<Code>(isolate()->builtins()->builtin( Builtins::kIllegal)); - global_proxy_function = - factory()->NewFunction(name, JS_GLOBAL_PROXY_TYPE, - JSGlobalProxy::kSize, code, true); + global_proxy_function = factory()->NewFunction( + name, code, JS_GLOBAL_PROXY_TYPE, JSGlobalProxy::kSize); } else { Handle<ObjectTemplateInfo> data = - v8::Utils::OpenHandle(*global_template); + v8::Utils::OpenHandle(*global_proxy_template); Handle<FunctionTemplateInfo> global_constructor( FunctionTemplateInfo::cast(data->constructor())); global_proxy_function = factory()->CreateApiFunction(global_constructor, factory()->the_hole_value(), - factory()->OuterGlobalObject); + factory()->GlobalProxyType); } Handle<String> global_name = factory()->InternalizeOneByteString( @@ -770,9 +830,7 @@ Handle<JSGlobalProxy> Genesis::CreateNewGlobals( // Return the global proxy. Handle<JSGlobalProxy> global_proxy; - if (global_object.location() != NULL) { - ASSERT(global_object->IsJSGlobalProxy()); - global_proxy = Handle<JSGlobalProxy>::cast(global_object); + if (maybe_global_proxy.ToHandle(&global_proxy)) { factory()->ReinitializeJSGlobalProxy(global_proxy, global_proxy_function); } else { global_proxy = Handle<JSGlobalProxy>::cast( @@ -783,75 +841,73 @@ Handle<JSGlobalProxy> Genesis::CreateNewGlobals( } -void Genesis::HookUpGlobalProxy(Handle<GlobalObject> inner_global, +void Genesis::HookUpGlobalProxy(Handle<GlobalObject> global_object, Handle<JSGlobalProxy> global_proxy) { // Set the native context for the global object. - inner_global->set_native_context(*native_context()); - inner_global->set_global_context(*native_context()); - inner_global->set_global_receiver(*global_proxy); + global_object->set_native_context(*native_context()); + global_object->set_global_context(*native_context()); + global_object->set_global_proxy(*global_proxy); global_proxy->set_native_context(*native_context()); native_context()->set_global_proxy(*global_proxy); } -void Genesis::HookUpInnerGlobal(Handle<GlobalObject> inner_global) { - Handle<GlobalObject> inner_global_from_snapshot( +void Genesis::HookUpGlobalObject(Handle<GlobalObject> global_object) { + Handle<GlobalObject> global_object_from_snapshot( GlobalObject::cast(native_context()->extension())); Handle<JSBuiltinsObject> builtins_global(native_context()->builtins()); - native_context()->set_extension(*inner_global); - native_context()->set_global_object(*inner_global); - native_context()->set_security_token(*inner_global); + native_context()->set_extension(*global_object); + native_context()->set_global_object(*global_object); + native_context()->set_security_token(*global_object); static const PropertyAttributes attributes = static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE); - Runtime::ForceSetObjectProperty(builtins_global, - factory()->InternalizeOneByteString( - STATIC_ASCII_VECTOR("global")), - inner_global, - attributes).Assert(); + Runtime::DefineObjectProperty(builtins_global, + factory()->InternalizeOneByteString( + STATIC_ASCII_VECTOR("global")), + global_object, + attributes).Assert(); // 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); + JSGlobalObject::cast(*global_object)->set_builtins(*builtins_global); + TransferNamedProperties(global_object_from_snapshot, global_object); + TransferIndexedProperties(global_object_from_snapshot, global_object); } // 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, +// work in the snapshot case is done in HookUpGlobalObject. +void Genesis::InitializeGlobal(Handle<GlobalObject> global_object, Handle<JSFunction> empty_function) { // --- N a t i v e C o n t e x t --- // Use the empty function as closure (no scope info). native_context()->set_closure(*empty_function); native_context()->set_previous(NULL); // Set extension and global object. - native_context()->set_extension(*inner_global); - native_context()->set_global_object(*inner_global); - // Security setup: Set the security token of the global object to - // its the inner global. This makes the security check between two - // different contexts fail by default even in case of global - // object reinitialization. - native_context()->set_security_token(*inner_global); - - Isolate* isolate = inner_global->GetIsolate(); + native_context()->set_extension(*global_object); + native_context()->set_global_object(*global_object); + // Security setup: Set the security token of the native context to the global + // object. This makes the security check between two different contexts fail + // by default even in case of global object reinitialization. + native_context()->set_security_token(*global_object); + + Isolate* isolate = global_object->GetIsolate(); Factory* factory = isolate->factory(); Heap* heap = isolate->heap(); Handle<String> object_name = factory->Object_string(); - JSObject::SetLocalPropertyIgnoreAttributes( - inner_global, object_name, - isolate->object_function(), DONT_ENUM).Check(); + JSObject::AddProperty( + global_object, object_name, isolate->object_function(), DONT_ENUM); - Handle<JSObject> global = Handle<JSObject>(native_context()->global_object()); + Handle<JSObject> global(native_context()->global_object()); // Install global Function object InstallFunction(global, "Function", JS_FUNCTION_TYPE, JSFunction::kSize, - empty_function, Builtins::kIllegal, true, true); + empty_function, Builtins::kIllegal); { // --- A r r a y --- Handle<JSFunction> array_function = InstallFunction(global, "Array", JS_ARRAY_TYPE, JSArray::kSize, isolate->initial_object_prototype(), - Builtins::kArrayCode, true, true); + Builtins::kArrayCode); array_function->shared()->DontAdaptArguments(); array_function->shared()->set_function_data(Smi::FromInt(kArrayCode)); @@ -863,7 +919,7 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global, // This assert protects an optimization in // HGraphBuilder::JSArrayBuilder::EmitMapCode() - ASSERT(initial_map->elements_kind() == GetInitialFastElementsKind()); + DCHECK(initial_map->elements_kind() == GetInitialFastElementsKind()); Map::EnsureDescriptorSlack(initial_map, 1); PropertyAttributes attribs = static_cast<PropertyAttributes>( @@ -895,7 +951,7 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global, Handle<JSFunction> number_fun = InstallFunction(global, "Number", JS_VALUE_TYPE, JSValue::kSize, isolate->initial_object_prototype(), - Builtins::kIllegal, true, true); + Builtins::kIllegal); native_context()->set_number_function(*number_fun); } @@ -903,7 +959,7 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global, Handle<JSFunction> boolean_fun = InstallFunction(global, "Boolean", JS_VALUE_TYPE, JSValue::kSize, isolate->initial_object_prototype(), - Builtins::kIllegal, true, true); + Builtins::kIllegal); native_context()->set_boolean_function(*boolean_fun); } @@ -911,7 +967,7 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global, Handle<JSFunction> string_fun = InstallFunction(global, "String", JS_VALUE_TYPE, JSValue::kSize, isolate->initial_object_prototype(), - Builtins::kIllegal, true, true); + Builtins::kIllegal); string_fun->shared()->set_construct_stub( isolate->builtins()->builtin(Builtins::kStringConstructCode)); native_context()->set_string_function(*string_fun); @@ -931,12 +987,20 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global, } } + { + // --- S y m b o l --- + Handle<JSFunction> symbol_fun = InstallFunction( + global, "Symbol", JS_VALUE_TYPE, JSValue::kSize, + isolate->initial_object_prototype(), Builtins::kIllegal); + native_context()->set_symbol_function(*symbol_fun); + } + { // --- D a t e --- // Builtin functions for Date.prototype. Handle<JSFunction> date_fun = InstallFunction(global, "Date", JS_DATE_TYPE, JSDate::kSize, isolate->initial_object_prototype(), - Builtins::kIllegal, true, true); + Builtins::kIllegal); native_context()->set_date_function(*date_fun); } @@ -947,13 +1011,13 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global, Handle<JSFunction> regexp_fun = InstallFunction(global, "RegExp", JS_REGEXP_TYPE, JSRegExp::kSize, isolate->initial_object_prototype(), - Builtins::kIllegal, true, true); + Builtins::kIllegal); native_context()->set_regexp_function(*regexp_fun); - ASSERT(regexp_fun->has_initial_map()); + DCHECK(regexp_fun->has_initial_map()); Handle<Map> initial_map(regexp_fun->initial_map()); - ASSERT_EQ(0, initial_map->inobject_properties()); + DCHECK_EQ(0, initial_map->inobject_properties()); PropertyAttributes final = static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY); @@ -1024,6 +1088,7 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global, proto->InObjectPropertyAtPut(JSRegExp::kLastIndexFieldIndex, Smi::FromInt(0), SKIP_WRITE_BARRIER); // It's a Smi. + proto_map->set_is_prototype_map(true); initial_map->set_prototype(*proto); factory->SetRegExpIrregexpData(Handle<JSRegExp>::cast(proto), JSRegExp::IRREGEXP, factory->empty_string(), @@ -1032,29 +1097,27 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global, { // -- J S O N Handle<String> name = factory->InternalizeUtf8String("JSON"); - Handle<JSFunction> cons = factory->NewFunctionWithPrototype( - name, factory->the_hole_value()); + Handle<JSFunction> cons = factory->NewFunction(name); JSFunction::SetInstancePrototype(cons, Handle<Object>(native_context()->initial_object_prototype(), isolate)); cons->SetInstanceClassName(*name); Handle<JSObject> json_object = factory->NewJSObject(cons, TENURED); - ASSERT(json_object->IsJSObject()); - JSObject::SetLocalPropertyIgnoreAttributes( - global, name, json_object, DONT_ENUM).Check(); + DCHECK(json_object->IsJSObject()); + JSObject::AddProperty(global, name, json_object, DONT_ENUM); native_context()->set_json_object(*json_object); } - { // -- A r r a y B u f f e r + { // -- A r r a y B u f f e r Handle<JSFunction> array_buffer_fun = InstallFunction( global, "ArrayBuffer", JS_ARRAY_BUFFER_TYPE, JSArrayBuffer::kSizeWithInternalFields, isolate->initial_object_prototype(), - Builtins::kIllegal, true, true); + Builtins::kIllegal); native_context()->set_array_buffer_fun(*array_buffer_fun); } - { // -- T y p e d A r r a y s + { // -- T y p e d A r r a y s #define INSTALL_TYPED_ARRAY(Type, type, TYPE, ctype, size) \ { \ Handle<JSFunction> fun; \ @@ -1074,99 +1137,102 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global, global, "DataView", JS_DATA_VIEW_TYPE, JSDataView::kSizeWithInternalFields, isolate->initial_object_prototype(), - Builtins::kIllegal, true, true); + Builtins::kIllegal); native_context()->set_data_view_fun(*data_view_fun); } - { // -- W e a k M a p - InstallFunction(global, "WeakMap", JS_WEAK_MAP_TYPE, JSWeakMap::kSize, - isolate->initial_object_prototype(), - Builtins::kIllegal, true, true); - } + // -- M a p + InstallFunction(global, "Map", JS_MAP_TYPE, JSMap::kSize, + isolate->initial_object_prototype(), Builtins::kIllegal); - { // -- W e a k S e t - InstallFunction(global, "WeakSet", JS_WEAK_SET_TYPE, JSWeakSet::kSize, - isolate->initial_object_prototype(), - Builtins::kIllegal, true, true); + // -- S e t + InstallFunction(global, "Set", JS_SET_TYPE, JSSet::kSize, + isolate->initial_object_prototype(), Builtins::kIllegal); + + { // Set up the iterator result object + STATIC_ASSERT(JSGeneratorObject::kResultPropertyCount == 2); + Handle<JSFunction> object_function(native_context()->object_function()); + DCHECK(object_function->initial_map()->inobject_properties() == 0); + Handle<Map> iterator_result_map = + Map::Create(object_function, JSGeneratorObject::kResultPropertyCount); + DCHECK(iterator_result_map->inobject_properties() == + JSGeneratorObject::kResultPropertyCount); + Map::EnsureDescriptorSlack(iterator_result_map, + JSGeneratorObject::kResultPropertyCount); + + FieldDescriptor value_descr(factory->value_string(), + JSGeneratorObject::kResultValuePropertyIndex, + NONE, Representation::Tagged()); + iterator_result_map->AppendDescriptor(&value_descr); + + FieldDescriptor done_descr(factory->done_string(), + JSGeneratorObject::kResultDonePropertyIndex, + NONE, Representation::Tagged()); + iterator_result_map->AppendDescriptor(&done_descr); + + iterator_result_map->set_unused_property_fields(0); + DCHECK_EQ(JSGeneratorObject::kResultSize, + iterator_result_map->instance_size()); + native_context()->set_iterator_result_map(*iterator_result_map); } - { // --- arguments_boilerplate_ + // -- W e a k M a p + InstallFunction(global, "WeakMap", JS_WEAK_MAP_TYPE, JSWeakMap::kSize, + isolate->initial_object_prototype(), Builtins::kIllegal); + // -- W e a k S e t + InstallFunction(global, "WeakSet", JS_WEAK_SET_TYPE, JSWeakSet::kSize, + isolate->initial_object_prototype(), Builtins::kIllegal); + + { // --- sloppy arguments map // Make sure we can recognize argument objects at runtime. // This is done by introducing an anonymous function with // class_name equals 'Arguments'. Handle<String> arguments_string = factory->InternalizeOneByteString( STATIC_ASCII_VECTOR("Arguments")); Handle<Code> code(isolate->builtins()->builtin(Builtins::kIllegal)); - Handle<JSObject> prototype( - JSObject::cast(native_context()->object_function()->prototype())); - - Handle<JSFunction> function = - factory->NewFunctionWithPrototype(arguments_string, - JS_OBJECT_TYPE, - JSObject::kHeaderSize, - prototype, - code, - false); - ASSERT(!function->has_initial_map()); + Handle<JSFunction> function = factory->NewFunctionWithoutPrototype( + arguments_string, code); function->shared()->set_instance_class_name(*arguments_string); - function->shared()->set_expected_nof_properties(2); - Handle<JSObject> result = factory->NewJSObject(function); - - native_context()->set_sloppy_arguments_boilerplate(*result); - // Note: length must be added as the first property and - // callee must be added as the second property. - JSObject::SetLocalPropertyIgnoreAttributes( - result, factory->length_string(), - factory->undefined_value(), DONT_ENUM, - Object::FORCE_TAGGED, FORCE_FIELD).Check(); - JSObject::SetLocalPropertyIgnoreAttributes( - result, factory->callee_string(), - factory->undefined_value(), DONT_ENUM, - Object::FORCE_TAGGED, FORCE_FIELD).Check(); -#ifdef DEBUG - LookupResult lookup(isolate); - result->LocalLookup(factory->callee_string(), &lookup); - ASSERT(lookup.IsField()); - ASSERT(lookup.GetFieldIndex().field_index() == Heap::kArgumentsCalleeIndex); + Handle<Map> map = + factory->NewMap(JS_OBJECT_TYPE, Heap::kSloppyArgumentsObjectSize); + // Create the descriptor array for the arguments object. + Map::EnsureDescriptorSlack(map, 2); + + { // length + FieldDescriptor d(factory->length_string(), Heap::kArgumentsLengthIndex, + DONT_ENUM, Representation::Tagged()); + map->AppendDescriptor(&d); + } + { // callee + FieldDescriptor d(factory->callee_string(), Heap::kArgumentsCalleeIndex, + DONT_ENUM, Representation::Tagged()); + map->AppendDescriptor(&d); + } - result->LocalLookup(factory->length_string(), &lookup); - ASSERT(lookup.IsField()); - ASSERT(lookup.GetFieldIndex().field_index() == Heap::kArgumentsLengthIndex); + map->set_function_with_prototype(true); + map->set_pre_allocated_property_fields(2); + map->set_inobject_properties(2); + native_context()->set_sloppy_arguments_map(*map); - ASSERT(result->map()->inobject_properties() > Heap::kArgumentsCalleeIndex); - ASSERT(result->map()->inobject_properties() > Heap::kArgumentsLengthIndex); + DCHECK(!function->has_initial_map()); + JSFunction::SetInitialMap(function, map, + isolate->initial_object_prototype()); - // Check the state of the object. - ASSERT(result->HasFastProperties()); - ASSERT(result->HasFastObjectElements()); -#endif + DCHECK(map->inobject_properties() > Heap::kArgumentsCalleeIndex); + DCHECK(map->inobject_properties() > Heap::kArgumentsLengthIndex); + DCHECK(!map->is_dictionary_map()); + DCHECK(IsFastObjectElementsKind(map->elements_kind())); } - { // --- aliased_arguments_boilerplate_ - // Set up a well-formed parameter map to make assertions happy. - Handle<FixedArray> elements = factory->NewFixedArray(2); - elements->set_map(heap->sloppy_arguments_elements_map()); - Handle<FixedArray> array; - array = factory->NewFixedArray(0); - elements->set(0, *array); - array = factory->NewFixedArray(0); - elements->set(1, *array); - - Handle<Map> old_map( - native_context()->sloppy_arguments_boilerplate()->map()); - Handle<Map> new_map = Map::Copy(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(SLOPPY_ARGUMENTS_ELEMENTS); - result->set_elements(*elements); - ASSERT(result->HasSloppyArgumentsElements()); - native_context()->set_aliased_arguments_boilerplate(*result); - } - - { // --- strict mode arguments boilerplate + { // --- aliased arguments map + Handle<Map> map = Map::Copy(isolate->sloppy_arguments_map()); + map->set_elements_kind(SLOPPY_ARGUMENTS_ELEMENTS); + DCHECK_EQ(2, map->pre_allocated_property_fields()); + native_context()->set_aliased_arguments_map(*map); + } + + { // --- strict mode arguments map const PropertyAttributes attributes = static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY); @@ -1174,14 +1240,13 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global, Handle<AccessorPair> callee = factory->NewAccessorPair(); Handle<AccessorPair> caller = factory->NewAccessorPair(); - Handle<JSFunction> throw_function = - GetThrowTypeErrorFunction(); + Handle<JSFunction> poison = GetStrictPoisonFunction(); // Install the ThrowTypeError functions. - callee->set_getter(*throw_function); - callee->set_setter(*throw_function); - caller->set_getter(*throw_function); - caller->set_setter(*throw_function); + callee->set_getter(*poison); + callee->set_setter(*poison); + caller->set_getter(*poison); + caller->set_setter(*poison); // Create the map. Allocate one in-object field for length. Handle<Map> map = factory->NewMap(JS_OBJECT_TYPE, @@ -1190,20 +1255,16 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global, Map::EnsureDescriptorSlack(map, 3); { // length - FieldDescriptor d( - factory->length_string(), 0, DONT_ENUM, Representation::Tagged()); + FieldDescriptor d(factory->length_string(), Heap::kArgumentsLengthIndex, + DONT_ENUM, Representation::Tagged()); map->AppendDescriptor(&d); } { // callee - CallbacksDescriptor d(factory->callee_string(), - callee, - attributes); + CallbacksDescriptor d(factory->callee_string(), callee, attributes); map->AppendDescriptor(&d); } { // caller - CallbacksDescriptor d(factory->caller_string(), - caller, - attributes); + CallbacksDescriptor d(factory->caller_string(), caller, attributes); map->AppendDescriptor(&d); } @@ -1214,41 +1275,22 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global, // Copy constructor from the sloppy arguments boilerplate. map->set_constructor( - native_context()->sloppy_arguments_boilerplate()->map()->constructor()); - - // Allocate the arguments boilerplate object. - Handle<JSObject> result = factory->NewJSObjectFromMap(map); - native_context()->set_strict_arguments_boilerplate(*result); + native_context()->sloppy_arguments_map()->constructor()); - // Add length property only for strict mode boilerplate. - JSObject::SetLocalPropertyIgnoreAttributes( - result, factory->length_string(), - factory->undefined_value(), DONT_ENUM).Check(); + native_context()->set_strict_arguments_map(*map); -#ifdef DEBUG - LookupResult lookup(isolate); - result->LocalLookup(factory->length_string(), &lookup); - ASSERT(lookup.IsField()); - ASSERT(lookup.GetFieldIndex().field_index() == Heap::kArgumentsLengthIndex); - - ASSERT(result->map()->inobject_properties() > Heap::kArgumentsLengthIndex); - - // Check the state of the object. - ASSERT(result->HasFastProperties()); - ASSERT(result->HasFastObjectElements()); -#endif + DCHECK(map->inobject_properties() > Heap::kArgumentsLengthIndex); + DCHECK(!map->is_dictionary_map()); + DCHECK(IsFastObjectElementsKind(map->elements_kind())); } { // --- context extension // Create a function for the context extension objects. Handle<Code> code = Handle<Code>( isolate->builtins()->builtin(Builtins::kIllegal)); - Handle<JSFunction> context_extension_fun = - factory->NewFunction(factory->empty_string(), - JS_CONTEXT_EXTENSION_OBJECT_TYPE, - JSObject::kHeaderSize, - code, - true); + Handle<JSFunction> context_extension_fun = factory->NewFunction( + factory->empty_string(), code, JS_CONTEXT_EXTENSION_OBJECT_TYPE, + JSObject::kHeaderSize); Handle<String> name = factory->InternalizeOneByteString( STATIC_ASCII_VECTOR("context_extension")); @@ -1262,9 +1304,8 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global, Handle<Code> code = Handle<Code>(isolate->builtins()->builtin( Builtins::kHandleApiCallAsFunction)); - Handle<JSFunction> delegate = - factory->NewFunction(factory->empty_string(), JS_OBJECT_TYPE, - JSObject::kHeaderSize, code, true); + Handle<JSFunction> delegate = factory->NewFunction( + factory->empty_string(), code, JS_OBJECT_TYPE, JSObject::kHeaderSize); native_context()->set_call_as_function_delegate(*delegate); delegate->shared()->DontAdaptArguments(); } @@ -1274,9 +1315,8 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global, Handle<Code> code = Handle<Code>(isolate->builtins()->builtin( Builtins::kHandleApiCallAsConstructor)); - Handle<JSFunction> delegate = - factory->NewFunction(factory->empty_string(), JS_OBJECT_TYPE, - JSObject::kHeaderSize, code, true); + Handle<JSFunction> delegate = factory->NewFunction( + factory->empty_string(), code, JS_OBJECT_TYPE, JSObject::kHeaderSize); native_context()->set_call_as_constructor_delegate(*delegate); delegate->shared()->DontAdaptArguments(); } @@ -1293,16 +1333,16 @@ void Genesis::InstallTypedArray( Handle<JSFunction>* fun, Handle<Map>* external_map) { Handle<JSObject> global = Handle<JSObject>(native_context()->global_object()); - Handle<JSFunction> result = InstallFunction(global, name, JS_TYPED_ARRAY_TYPE, - JSTypedArray::kSize, isolate()->initial_object_prototype(), - Builtins::kIllegal, false, true); + Handle<JSFunction> result = InstallFunction( + global, name, JS_TYPED_ARRAY_TYPE, JSTypedArray::kSize, + isolate()->initial_object_prototype(), Builtins::kIllegal); Handle<Map> initial_map = isolate()->factory()->NewMap( JS_TYPED_ARRAY_TYPE, JSTypedArray::kSizeWithInternalFields, elements_kind); - result->set_initial_map(*initial_map); - initial_map->set_constructor(*result); + JSFunction::SetInitialMap(result, initial_map, + handle(initial_map->prototype(), isolate())); *fun = result; ElementsKind external_kind = GetNextTransitionElementsKind(elements_kind); @@ -1311,74 +1351,61 @@ void Genesis::InstallTypedArray( void Genesis::InitializeExperimentalGlobal() { - Handle<JSObject> global = Handle<JSObject>(native_context()->global_object()); - // TODO(mstarzinger): Move this into Genesis::InitializeGlobal once we no // longer need to live behind flags, so functions get added to the snapshot. - if (FLAG_harmony_symbols) { - // --- S y m b o l --- - Handle<JSFunction> symbol_fun = - InstallFunction(global, "Symbol", JS_VALUE_TYPE, JSValue::kSize, - isolate()->initial_object_prototype(), - Builtins::kIllegal, true, true); - native_context()->set_symbol_function(*symbol_fun); - } - - if (FLAG_harmony_collections) { - { // -- M a p - InstallFunction(global, "Map", JS_MAP_TYPE, JSMap::kSize, - isolate()->initial_object_prototype(), - Builtins::kIllegal, true, true); - } - { // -- S e t - InstallFunction(global, "Set", JS_SET_TYPE, JSSet::kSize, - isolate()->initial_object_prototype(), - Builtins::kIllegal, true, true); - } - { // -- S e t I t e r a t o r - Handle<Map> map = isolate()->factory()->NewMap( - JS_SET_ITERATOR_TYPE, JSSetIterator::kSize); - native_context()->set_set_iterator_map(*map); - } - { // -- M a p I t e r a t o r - Handle<Map> map = isolate()->factory()->NewMap( - JS_MAP_ITERATOR_TYPE, JSMapIterator::kSize); - native_context()->set_map_iterator_map(*map); - } - } - if (FLAG_harmony_generators) { // Create generator meta-objects and install them on the builtins object. Handle<JSObject> builtins(native_context()->builtins()); Handle<JSObject> generator_object_prototype = factory()->NewJSObject(isolate()->object_function(), TENURED); - Handle<JSFunction> generator_function_prototype = - InstallFunction(builtins, "GeneratorFunctionPrototype", - JS_FUNCTION_TYPE, JSFunction::kHeaderSize, - generator_object_prototype, Builtins::kIllegal, - false, false); + Handle<JSFunction> generator_function_prototype = InstallFunction( + builtins, "GeneratorFunctionPrototype", JS_FUNCTION_TYPE, + JSFunction::kHeaderSize, generator_object_prototype, + Builtins::kIllegal); InstallFunction(builtins, "GeneratorFunction", JS_FUNCTION_TYPE, JSFunction::kSize, - generator_function_prototype, Builtins::kIllegal, - false, false); + generator_function_prototype, Builtins::kIllegal); // Create maps for generator functions and their prototypes. Store those // maps in the native context. - Handle<Map> function_map(native_context()->sloppy_function_map()); - Handle<Map> generator_function_map = Map::Copy(function_map); + Handle<Map> sloppy_function_map(native_context()->sloppy_function_map()); + Handle<Map> generator_function_map = Map::Copy(sloppy_function_map); generator_function_map->set_prototype(*generator_function_prototype); native_context()->set_sloppy_generator_function_map( *generator_function_map); - Handle<Map> strict_mode_function_map( - native_context()->strict_function_map()); - Handle<Map> strict_mode_generator_function_map = - Map::Copy(strict_mode_function_map); - strict_mode_generator_function_map->set_prototype( - *generator_function_prototype); + // The "arguments" and "caller" instance properties aren't specified, so + // technically we could leave them out. They make even less sense for + // generators than for functions. Still, the same argument that it makes + // sense to keep them around but poisoned in strict mode applies to + // generators as well. With poisoned accessors, naive callers can still + // iterate over the properties without accessing them. + // + // We can't use PoisonArgumentsAndCaller because that mutates accessor pairs + // in place, and the initial state of the generator function map shares the + // accessor pair with sloppy functions. Also the error message should be + // different. Also unhappily, we can't use the API accessors to implement + // poisoning, because API accessors present themselves as data properties, + // not accessor properties, and so getOwnPropertyDescriptor raises an + // exception as it tries to get the values. Sadness. + Handle<AccessorPair> poison_pair(factory()->NewAccessorPair()); + PropertyAttributes rw_attribs = + static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE); + Handle<JSFunction> poison_function = GetGeneratorPoisonFunction(); + poison_pair->set_getter(*poison_function); + poison_pair->set_setter(*poison_function); + ReplaceAccessors(generator_function_map, factory()->arguments_string(), + rw_attribs, poison_pair); + ReplaceAccessors(generator_function_map, factory()->caller_string(), + rw_attribs, poison_pair); + + Handle<Map> strict_function_map(native_context()->strict_function_map()); + Handle<Map> strict_generator_function_map = Map::Copy(strict_function_map); + // "arguments" and "caller" already poisoned. + strict_generator_function_map->set_prototype(*generator_function_prototype); native_context()->set_strict_generator_function_map( - *strict_mode_generator_function_map); + *strict_generator_function_map); Handle<JSFunction> object_function(native_context()->object_function()); Handle<Map> generator_object_prototype_map = Map::Create( @@ -1388,38 +1415,6 @@ void Genesis::InitializeExperimentalGlobal() { native_context()->set_generator_object_prototype_map( *generator_object_prototype_map); } - - if (FLAG_harmony_collections || FLAG_harmony_generators) { - // Collection forEach uses an iterator result object. - // Generators return iteraror result objects. - - STATIC_ASSERT(JSGeneratorObject::kResultPropertyCount == 2); - Handle<JSFunction> object_function(native_context()->object_function()); - ASSERT(object_function->initial_map()->inobject_properties() == 0); - Handle<Map> iterator_result_map = Map::Create( - object_function, JSGeneratorObject::kResultPropertyCount); - ASSERT(iterator_result_map->inobject_properties() == - JSGeneratorObject::kResultPropertyCount); - Map::EnsureDescriptorSlack( - iterator_result_map, JSGeneratorObject::kResultPropertyCount); - - FieldDescriptor value_descr(isolate()->factory()->value_string(), - JSGeneratorObject::kResultValuePropertyIndex, - NONE, - Representation::Tagged()); - iterator_result_map->AppendDescriptor(&value_descr); - - FieldDescriptor done_descr(isolate()->factory()->done_string(), - JSGeneratorObject::kResultDonePropertyIndex, - NONE, - Representation::Tagged()); - iterator_result_map->AppendDescriptor(&done_descr); - - iterator_result_map->set_unused_property_fields(0); - ASSERT_EQ(JSGeneratorObject::kResultSize, - iterator_result_map->instance_size()); - native_context()->set_iterator_result_map(*iterator_result_map); - } } @@ -1448,7 +1443,7 @@ bool Genesis::CompileNative(Isolate* isolate, Vector<const char> name, Handle<String> source) { HandleScope scope(isolate); - isolate->debugger()->set_compiling_natives(true); + SuppressDebug compiling_natives(isolate->debug()); // 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. @@ -1462,9 +1457,8 @@ bool Genesis::CompileNative(Isolate* isolate, NULL, Handle<Context>(isolate->context()), true); - ASSERT(isolate->has_pending_exception() != result); + DCHECK(isolate->has_pending_exception() != result); if (!result) isolate->clear_pending_exception(); - isolate->debugger()->set_compiling_natives(false); return result; } @@ -1483,19 +1477,12 @@ bool Genesis::CompileScriptCached(Isolate* isolate, // If we can't find the function in the cache, we compile a new // function and insert it into the cache. if (cache == NULL || !cache->Lookup(name, &function_info)) { - ASSERT(source->IsOneByteRepresentation()); + DCHECK(source->IsOneByteRepresentation()); Handle<String> script_name = factory->NewStringFromUtf8(name).ToHandleChecked(); function_info = Compiler::CompileScript( - source, - script_name, - 0, - 0, - false, - top_context, - extension, - NULL, - NO_CACHED_DATA, + source, script_name, 0, 0, false, top_context, extension, NULL, + ScriptCompiler::kNoCompileOptions, use_runtime_context ? NATIVES_CODE : NOT_NATIVES_CODE); if (function_info.is_null()) return false; if (cache != NULL) cache->Add(name, function_info); @@ -1504,7 +1491,7 @@ bool Genesis::CompileScriptCached(Isolate* isolate, // 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->IsNativeContext()); + DCHECK(top_context->IsNativeContext()); Handle<Context> context = Handle<Context>(use_runtime_context ? Handle<Context>(top_context->runtime_context()) @@ -1524,6 +1511,38 @@ bool Genesis::CompileScriptCached(Isolate* isolate, } +static Handle<JSObject> ResolveBuiltinIdHolder(Handle<Context> native_context, + const char* holder_expr) { + Isolate* isolate = native_context->GetIsolate(); + Factory* factory = isolate->factory(); + Handle<GlobalObject> global(native_context->global_object()); + const char* period_pos = strchr(holder_expr, '.'); + if (period_pos == NULL) { + return Handle<JSObject>::cast( + Object::GetPropertyOrElement( + global, factory->InternalizeUtf8String(holder_expr)) + .ToHandleChecked()); + } + const char* inner = period_pos + 1; + DCHECK_EQ(NULL, strchr(inner, '.')); + Vector<const char> property(holder_expr, + static_cast<int>(period_pos - holder_expr)); + Handle<String> property_string = factory->InternalizeUtf8String(property); + DCHECK(!property_string.is_null()); + Handle<JSObject> object = Handle<JSObject>::cast( + Object::GetProperty(global, property_string).ToHandleChecked()); + if (strcmp("prototype", inner) == 0) { + Handle<JSFunction> function = Handle<JSFunction>::cast(object); + return Handle<JSObject>(JSObject::cast(function->prototype())); + } + Handle<String> inner_string = factory->InternalizeUtf8String(inner); + DCHECK(!inner_string.is_null()); + Handle<Object> value = + Object::GetProperty(object, inner_string).ToHandleChecked(); + return Handle<JSObject>::cast(value); +} + + #define INSTALL_NATIVE(Type, name, var) \ Handle<String> var##_name = \ factory()->InternalizeOneByteString(STATIC_ASCII_VECTOR(name)); \ @@ -1531,6 +1550,12 @@ bool Genesis::CompileScriptCached(Isolate* isolate, handle(native_context()->builtins()), var##_name).ToHandleChecked(); \ native_context()->set_##var(Type::cast(*var##_native)); +#define INSTALL_NATIVE_MATH(name) \ + { \ + Handle<Object> fun = \ + ResolveBuiltinIdHolder(native_context(), "Math." #name); \ + native_context()->set_math_##name##_fun(JSFunction::cast(*fun)); \ + } void Genesis::InstallNativeFunctions() { HandleScope scope(isolate()); @@ -1559,6 +1584,7 @@ void Genesis::InstallNativeFunctions() { INSTALL_NATIVE(JSFunction, "PromiseReject", promise_reject); INSTALL_NATIVE(JSFunction, "PromiseChain", promise_chain); INSTALL_NATIVE(JSFunction, "PromiseCatch", promise_catch); + INSTALL_NATIVE(JSFunction, "PromiseThen", promise_then); INSTALL_NATIVE(JSFunction, "NotifyChange", observers_notify_change); INSTALL_NATIVE(JSFunction, "EnqueueSpliceRecord", observers_enqueue_splice); @@ -1572,13 +1598,33 @@ void Genesis::InstallNativeFunctions() { native_object_get_notifier); INSTALL_NATIVE(JSFunction, "NativeObjectNotifierPerformChange", native_object_notifier_perform_change); + + INSTALL_NATIVE(Symbol, "symbolIterator", iterator_symbol); + INSTALL_NATIVE(Symbol, "symbolUnscopables", unscopables_symbol); + + INSTALL_NATIVE_MATH(abs) + INSTALL_NATIVE_MATH(acos) + INSTALL_NATIVE_MATH(asin) + INSTALL_NATIVE_MATH(atan) + INSTALL_NATIVE_MATH(atan2) + INSTALL_NATIVE_MATH(ceil) + INSTALL_NATIVE_MATH(cos) + INSTALL_NATIVE_MATH(exp) + INSTALL_NATIVE_MATH(floor) + INSTALL_NATIVE_MATH(imul) + INSTALL_NATIVE_MATH(log) + INSTALL_NATIVE_MATH(max) + INSTALL_NATIVE_MATH(min) + INSTALL_NATIVE_MATH(pow) + INSTALL_NATIVE_MATH(random) + INSTALL_NATIVE_MATH(round) + INSTALL_NATIVE_MATH(sin) + INSTALL_NATIVE_MATH(sqrt) + INSTALL_NATIVE_MATH(tan) } void Genesis::InstallExperimentalNativeFunctions() { - INSTALL_NATIVE(JSFunction, "RunMicrotasks", run_microtasks); - INSTALL_NATIVE(JSFunction, "EnqueueMicrotask", enqueue_microtask); - if (FLAG_harmony_proxies) { INSTALL_NATIVE(JSFunction, "DerivedHasTrap", derived_has_trap); INSTALL_NATIVE(JSFunction, "DerivedGetTrap", derived_get_trap); @@ -1600,17 +1646,11 @@ Handle<JSFunction> Genesis::InstallInternalArray( // doesn't inherit from Object.prototype. // To be used only for internal work by builtins. Instances // must not be leaked to user code. - Handle<JSFunction> array_function = - InstallFunction(builtins, - name, - JS_ARRAY_TYPE, - JSArray::kSize, - isolate()->initial_object_prototype(), - Builtins::kInternalArrayCode, - true, true); Handle<JSObject> prototype = factory()->NewJSObject(isolate()->object_function(), TENURED); - Accessors::FunctionSetPrototype(array_function, prototype); + Handle<JSFunction> array_function = InstallFunction( + builtins, name, JS_ARRAY_TYPE, JSArray::kSize, + prototype, Builtins::kInternalArrayCode); InternalArrayConstructorStub internal_array_constructor_stub(isolate()); Handle<Code> code = internal_array_constructor_stub.GetCode(); @@ -1620,7 +1660,7 @@ Handle<JSFunction> Genesis::InstallInternalArray( Handle<Map> original_map(array_function->initial_map()); Handle<Map> initial_map = Map::Copy(original_map); initial_map->set_elements_kind(elements_kind); - array_function->set_initial_map(*initial_map); + JSFunction::SetInitialMap(array_function, initial_map, prototype); // Make "length" magic on instances. Map::EnsureDescriptorSlack(initial_map, 1); @@ -1648,10 +1688,9 @@ bool Genesis::InstallNatives() { // (itself) and a reference to the native_context directly in the object. Handle<Code> code = Handle<Code>( isolate()->builtins()->builtin(Builtins::kIllegal)); - Handle<JSFunction> builtins_fun = - factory()->NewFunction(factory()->empty_string(), - JS_BUILTINS_OBJECT_TYPE, - JSBuiltinsObject::kSize, code, true); + Handle<JSFunction> builtins_fun = factory()->NewFunction( + factory()->empty_string(), code, JS_BUILTINS_OBJECT_TYPE, + JSBuiltinsObject::kSize); Handle<String> name = factory()->InternalizeOneByteString(STATIC_ASCII_VECTOR("builtins")); @@ -1665,8 +1704,7 @@ bool Genesis::InstallNatives() { builtins->set_builtins(*builtins); builtins->set_native_context(*native_context()); builtins->set_global_context(*native_context()); - builtins->set_global_receiver(*builtins); - builtins->set_global_receiver(native_context()->global_proxy()); + builtins->set_global_proxy(native_context()->global_proxy()); // Set up the 'global' properties of the builtins object. The @@ -1678,21 +1716,18 @@ bool Genesis::InstallNatives() { Handle<String> global_string = factory()->InternalizeOneByteString(STATIC_ASCII_VECTOR("global")); Handle<Object> global_obj(native_context()->global_object(), isolate()); - JSObject::SetLocalPropertyIgnoreAttributes( - builtins, global_string, global_obj, attributes).Check(); + JSObject::AddProperty(builtins, global_string, global_obj, attributes); Handle<String> builtins_string = factory()->InternalizeOneByteString(STATIC_ASCII_VECTOR("builtins")); - JSObject::SetLocalPropertyIgnoreAttributes( - builtins, builtins_string, builtins, attributes).Check(); + JSObject::AddProperty(builtins, builtins_string, builtins, attributes); // Set up the reference from the global object to the builtins object. JSGlobalObject::cast(native_context()->global_object())-> set_builtins(*builtins); // Create a bridge function that has context in the native context. - Handle<JSFunction> bridge = factory()->NewFunctionWithPrototype( - factory()->empty_string(), factory()->undefined_value()); - ASSERT(bridge->context() == *isolate()->native_context()); + Handle<JSFunction> bridge = factory()->NewFunction(factory()->empty_string()); + DCHECK(bridge->context() == *isolate()->native_context()); // Allocate the builtins context. Handle<Context> context = @@ -1703,17 +1738,16 @@ bool Genesis::InstallNatives() { { // -- S c r i p t // Builtin functions for Script. - Handle<JSFunction> script_fun = - InstallFunction(builtins, "Script", JS_VALUE_TYPE, JSValue::kSize, - isolate()->initial_object_prototype(), - Builtins::kIllegal, false, false); + Handle<JSFunction> script_fun = InstallFunction( + builtins, "Script", JS_VALUE_TYPE, JSValue::kSize, + isolate()->initial_object_prototype(), Builtins::kIllegal); Handle<JSObject> prototype = factory()->NewJSObject(isolate()->object_function(), TENURED); Accessors::FunctionSetPrototype(script_fun, prototype); native_context()->set_script_function(*script_fun); Handle<Map> script_map = Handle<Map>(script_fun->initial_map()); - Map::EnsureDescriptorSlack(script_map, 13); + Map::EnsureDescriptorSlack(script_map, 14); PropertyAttributes attribs = static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY); @@ -1820,6 +1854,23 @@ bool Genesis::InstallNatives() { script_map->AppendDescriptor(&d); } + Handle<AccessorInfo> script_source_url = + Accessors::ScriptSourceUrlInfo(isolate(), attribs); + { + CallbacksDescriptor d(Handle<Name>(Name::cast(script_source_url->name())), + script_source_url, attribs); + script_map->AppendDescriptor(&d); + } + + Handle<AccessorInfo> script_source_mapping_url = + Accessors::ScriptSourceMappingUrlInfo(isolate(), attribs); + { + CallbacksDescriptor d( + Handle<Name>(Name::cast(script_source_mapping_url->name())), + script_source_mapping_url, attribs); + script_map->AppendDescriptor(&d); + } + // Allocate the empty script. Handle<Script> script = factory()->NewScript(factory()->empty_string()); script->set_type(Smi::FromInt(Script::TYPE_NATIVE)); @@ -1829,11 +1880,9 @@ bool Genesis::InstallNatives() { // Builtin function for OpaqueReference -- a JSValue-based object, // that keeps its field isolated from JavaScript code. It may store // objects, that JavaScript code may not access. - Handle<JSFunction> opaque_reference_fun = - InstallFunction(builtins, "OpaqueReference", JS_VALUE_TYPE, - JSValue::kSize, - isolate()->initial_object_prototype(), - Builtins::kIllegal, false, false); + Handle<JSFunction> opaque_reference_fun = InstallFunction( + builtins, "OpaqueReference", JS_VALUE_TYPE, JSValue::kSize, + isolate()->initial_object_prototype(), Builtins::kIllegal); Handle<JSObject> prototype = factory()->NewJSObject(isolate()->object_function(), TENURED); Accessors::FunctionSetPrototype(opaque_reference_fun, prototype); @@ -1855,6 +1904,22 @@ bool Genesis::InstallNatives() { InstallInternalArray(builtins, "InternalPackedArray", FAST_ELEMENTS); } + { // -- S e t I t e r a t o r + Handle<JSFunction> set_iterator_function = InstallFunction( + builtins, "SetIterator", JS_SET_ITERATOR_TYPE, JSSetIterator::kSize, + isolate()->initial_object_prototype(), Builtins::kIllegal); + native_context()->set_set_iterator_map( + set_iterator_function->initial_map()); + } + + { // -- M a p I t e r a t o r + Handle<JSFunction> map_iterator_function = InstallFunction( + builtins, "MapIterator", JS_MAP_ITERATOR_TYPE, JSMapIterator::kSize, + isolate()->initial_object_prototype(), Builtins::kIllegal); + native_context()->set_map_iterator_map( + map_iterator_function->initial_map()); + } + if (FLAG_disable_native_files) { PrintF("Warning: Running without installed natives!\n"); return true; @@ -1876,7 +1941,7 @@ bool Genesis::InstallNatives() { // Store the map for the string prototype after the natives has been compiled // and the String function has been set up. Handle<JSFunction> string_function(native_context()->string_function()); - ASSERT(JSObject::cast( + DCHECK(JSObject::cast( string_function->initial_map()->prototype())->HasFastProperties()); native_context()->set_string_function_prototype_map( HeapObject::cast(string_function->initial_map()->prototype())->map()); @@ -1885,27 +1950,29 @@ bool Genesis::InstallNatives() { { Handle<String> key = factory()->function_class_string(); Handle<JSFunction> function = Handle<JSFunction>::cast(Object::GetProperty( - isolate()->global_object(), key).ToHandleChecked()); + handle(native_context()->global_object()), key).ToHandleChecked()); Handle<JSObject> proto = Handle<JSObject>(JSObject::cast(function->instance_prototype())); // Install the call and the apply functions. Handle<JSFunction> call = InstallFunction(proto, "call", JS_OBJECT_TYPE, JSObject::kHeaderSize, - Handle<JSObject>::null(), - Builtins::kFunctionCall, - false, false); + MaybeHandle<JSObject>(), Builtins::kFunctionCall); Handle<JSFunction> apply = InstallFunction(proto, "apply", JS_OBJECT_TYPE, JSObject::kHeaderSize, - Handle<JSObject>::null(), - Builtins::kFunctionApply, - false, false); + MaybeHandle<JSObject>(), Builtins::kFunctionApply); + if (FLAG_vector_ics) { + // Apply embeds an IC, so we need a type vector of size 1 in the shared + // function info. + Handle<FixedArray> feedback_vector = factory()->NewTypeFeedbackVector(1); + apply->shared()->set_feedback_vector(*feedback_vector); + } // Make sure that Function.prototype.call appears to be compiled. // The code will never be called, but inline caching for call will // only work if it appears to be compiled. call->shared()->DontAdaptArguments(); - ASSERT(call->is_compiled()); + DCHECK(call->is_compiled()); // Set the expected parameters for apply to 2; required by builtin. apply->shared()->set_formal_parameter_count(2); @@ -1946,7 +2013,7 @@ bool Genesis::InstallNatives() { Handle<String> length = factory()->length_string(); int old = array_descriptors->SearchWithCache( *length, array_function->initial_map()); - ASSERT(old != DescriptorArray::kNotFound); + DCHECK(old != DescriptorArray::kNotFound); CallbacksDescriptor desc(length, handle(array_descriptors->GetValue(old), isolate()), @@ -1996,44 +2063,17 @@ bool Genesis::InstallExperimentalNatives() { for (int i = ExperimentalNatives::GetDebuggerCount(); i < ExperimentalNatives::GetBuiltinsCount(); i++) { - INSTALL_EXPERIMENTAL_NATIVE(i, symbols, "symbol.js") INSTALL_EXPERIMENTAL_NATIVE(i, proxies, "proxy.js") - INSTALL_EXPERIMENTAL_NATIVE(i, collections, "collection.js") INSTALL_EXPERIMENTAL_NATIVE(i, generators, "generator.js") - INSTALL_EXPERIMENTAL_NATIVE(i, iteration, "array-iterator.js") INSTALL_EXPERIMENTAL_NATIVE(i, strings, "harmony-string.js") INSTALL_EXPERIMENTAL_NATIVE(i, arrays, "harmony-array.js") - INSTALL_EXPERIMENTAL_NATIVE(i, maths, "harmony-math.js") } InstallExperimentalNativeFunctions(); - InstallExperimentalBuiltinFunctionIds(); return true; } -static Handle<JSObject> ResolveBuiltinIdHolder( - Handle<Context> native_context, - const char* holder_expr) { - Isolate* isolate = native_context->GetIsolate(); - Factory* factory = isolate->factory(); - Handle<GlobalObject> global(native_context->global_object()); - const char* period_pos = strchr(holder_expr, '.'); - if (period_pos == NULL) { - return Handle<JSObject>::cast(Object::GetPropertyOrElement( - global, factory->InternalizeUtf8String(holder_expr)).ToHandleChecked()); - } - ASSERT_EQ(".prototype", period_pos); - Vector<const char> property(holder_expr, - static_cast<int>(period_pos - holder_expr)); - Handle<String> property_string = factory->InternalizeUtf8String(property); - ASSERT(!property_string.is_null()); - Handle<JSFunction> function = Handle<JSFunction>::cast( - Object::GetProperty(global, property_string).ToHandleChecked()); - return Handle<JSObject>(JSObject::cast(function->prototype())); -} - - static void InstallBuiltinFunctionId(Handle<JSObject> holder, const char* function_name, BuiltinFunctionId id) { @@ -2059,15 +2099,6 @@ void Genesis::InstallBuiltinFunctionIds() { } -void Genesis::InstallExperimentalBuiltinFunctionIds() { - HandleScope scope(isolate()); - if (FLAG_harmony_maths) { - Handle<JSObject> holder = ResolveBuiltinIdHolder(native_context(), "Math"); - InstallBuiltinFunctionId(holder, "clz32", kMathClz32); - } -} - - // Do not forget to update macros.py with named constant // of cache id. #define JSFUNCTION_RESULT_CACHE_LIST(F) \ @@ -2130,56 +2161,55 @@ bool Bootstrapper::InstallExtensions(Handle<Context> native_context, bool Genesis::InstallSpecialObjects(Handle<Context> native_context) { Isolate* isolate = native_context->GetIsolate(); + // Don't install extensions into the snapshot. + if (isolate->serializer_enabled()) return true; + Factory* factory = isolate->factory(); HandleScope scope(isolate); Handle<JSGlobalObject> global(JSGlobalObject::cast( native_context->global_object())); + + Handle<JSObject> Error = Handle<JSObject>::cast( + Object::GetProperty(isolate, global, "Error").ToHandleChecked()); + Handle<String> name = + factory->InternalizeOneByteString(STATIC_ASCII_VECTOR("stackTraceLimit")); + Handle<Smi> stack_trace_limit(Smi::FromInt(FLAG_stack_trace_limit), isolate); + JSObject::AddProperty(Error, name, stack_trace_limit, NONE); + // 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 = factory->InternalizeUtf8String(FLAG_expose_natives_as); - RETURN_ON_EXCEPTION_VALUE( - isolate, - JSObject::SetLocalPropertyIgnoreAttributes( - global, natives, Handle<JSObject>(global->builtins()), DONT_ENUM), - false); - } - - Handle<Object> Error = Object::GetProperty( - isolate, global, "Error").ToHandleChecked(); - if (Error->IsJSObject()) { - Handle<String> name = factory->InternalizeOneByteString( - STATIC_ASCII_VECTOR("stackTraceLimit")); - Handle<Smi> stack_trace_limit( - Smi::FromInt(FLAG_stack_trace_limit), isolate); - RETURN_ON_EXCEPTION_VALUE( - isolate, - JSObject::SetLocalPropertyIgnoreAttributes( - Handle<JSObject>::cast(Error), name, stack_trace_limit, NONE), - false); - } + JSObject::AddProperty(global, natives, handle(global->builtins()), + DONT_ENUM); + } + + // Expose the stack trace symbol to native JS. + RETURN_ON_EXCEPTION_VALUE( + isolate, + JSObject::SetOwnPropertyIgnoreAttributes( + handle(native_context->builtins(), isolate), + factory->InternalizeOneByteString( + STATIC_ASCII_VECTOR("stack_trace_symbol")), + factory->stack_trace_symbol(), + NONE), + false); // 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->debug(); // If loading fails we just bail out without installing the // debugger but without tanking the whole context. + Debug* debug = isolate->debug(); if (!debug->Load()) return true; + Handle<Context> debug_context = debug->debug_context(); // Set the security token for the debugger context to the same as // the shell native context to allow calling between these (otherwise // exposing debug global object doesn't make much sense). - debug->debug_context()->set_security_token( - native_context->security_token()); - + debug_context->set_security_token(native_context->security_token()); Handle<String> debug_string = factory->InternalizeUtf8String(FLAG_expose_debug_as); - Handle<Object> global_proxy( - debug->debug_context()->global_proxy(), isolate); - RETURN_ON_EXCEPTION_VALUE( - isolate, - JSObject::SetLocalPropertyIgnoreAttributes( - global, debug_string, global_proxy, DONT_ENUM), - false); + Handle<Object> global_proxy(debug_context->global_proxy(), isolate); + JSObject::AddProperty(global, debug_string, global_proxy, DONT_ENUM); } return true; } @@ -2283,7 +2313,7 @@ bool Genesis::InstallExtension(Isolate* isolate, "Circular extension dependency")) { return false; } - ASSERT(extension_states->get_state(current) == UNVISITED); + DCHECK(extension_states->get_state(current) == UNVISITED); extension_states->set_state(current, VISITED); v8::Extension* extension = current->extension(); // Install the extension's dependencies @@ -2305,14 +2335,14 @@ bool Genesis::InstallExtension(Isolate* isolate, extension, Handle<Context>(isolate->context()), false); - ASSERT(isolate->has_pending_exception() != result); + DCHECK(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()); + base::OS::PrintError("Error installing extension '%s'.\n", + current->extension()->name()); isolate->clear_pending_exception(); } extension_states->set_state(current, INSTALLED); @@ -2329,6 +2359,10 @@ bool Genesis::InstallJSBuiltins(Handle<JSBuiltinsObject> builtins) { isolate(), builtins, Builtins::GetName(id)).ToHandleChecked(); Handle<JSFunction> function = Handle<JSFunction>::cast(function_object); builtins->set_javascript_builtin(id, *function); + // TODO(mstarzinger): This is just a temporary hack to make TurboFan work, + // the correct solution is to restore the context register after invoking + // builtins from full-codegen. + function->shared()->set_optimization_disabled(true); if (!Compiler::EnsureCompiled(function, CLEAR_EXCEPTION)) { return false; } @@ -2342,26 +2376,26 @@ bool Genesis::ConfigureGlobalObjects( v8::Handle<v8::ObjectTemplate> global_proxy_template) { Handle<JSObject> global_proxy( JSObject::cast(native_context()->global_proxy())); - Handle<JSObject> inner_global( + Handle<JSObject> global_object( JSObject::cast(native_context()->global_object())); if (!global_proxy_template.IsEmpty()) { // Configure the global proxy object. - Handle<ObjectTemplateInfo> proxy_data = + Handle<ObjectTemplateInfo> global_proxy_data = v8::Utils::OpenHandle(*global_proxy_template); - if (!ConfigureApiObject(global_proxy, proxy_data)) return false; + if (!ConfigureApiObject(global_proxy, global_proxy_data)) return false; - // Configure the inner global object. + // Configure the global object. Handle<FunctionTemplateInfo> proxy_constructor( - FunctionTemplateInfo::cast(proxy_data->constructor())); + FunctionTemplateInfo::cast(global_proxy_data->constructor())); if (!proxy_constructor->prototype_template()->IsUndefined()) { - Handle<ObjectTemplateInfo> inner_data( + Handle<ObjectTemplateInfo> global_object_data( ObjectTemplateInfo::cast(proxy_constructor->prototype_template())); - if (!ConfigureApiObject(inner_global, inner_data)) return false; + if (!ConfigureApiObject(global_object, global_object_data)) return false; } } - SetObjectPrototype(global_proxy, inner_global); + SetObjectPrototype(global_proxy, global_object); native_context()->set_initial_array_prototype( JSArray::cast(native_context()->array_function()->prototype())); @@ -2371,16 +2405,16 @@ bool Genesis::ConfigureGlobalObjects( bool Genesis::ConfigureApiObject(Handle<JSObject> object, - Handle<ObjectTemplateInfo> object_template) { - ASSERT(!object_template.is_null()); - ASSERT(FunctionTemplateInfo::cast(object_template->constructor()) + Handle<ObjectTemplateInfo> object_template) { + DCHECK(!object_template.is_null()); + DCHECK(FunctionTemplateInfo::cast(object_template->constructor()) ->IsTemplateFor(object->map()));; MaybeHandle<JSObject> maybe_obj = Execution::InstantiateObject(object_template); Handle<JSObject> obj; if (!maybe_obj.ToHandle(&obj)) { - ASSERT(isolate()->has_pending_exception()); + DCHECK(isolate()->has_pending_exception()); isolate()->clear_pending_exception(); return false; } @@ -2400,30 +2434,28 @@ void Genesis::TransferNamedProperties(Handle<JSObject> from, case FIELD: { HandleScope inner(isolate()); Handle<Name> key = Handle<Name>(descs->GetKey(i)); - int index = descs->GetFieldIndex(i); - ASSERT(!descs->GetDetails(i).representation().IsDouble()); + FieldIndex index = FieldIndex::ForDescriptor(from->map(), i); + DCHECK(!descs->GetDetails(i).representation().IsDouble()); Handle<Object> value = Handle<Object>(from->RawFastPropertyAt(index), isolate()); - JSObject::SetLocalPropertyIgnoreAttributes( - to, key, value, details.attributes()).Check(); + JSObject::AddProperty(to, key, value, details.attributes()); break; } case CONSTANT: { HandleScope inner(isolate()); Handle<Name> key = Handle<Name>(descs->GetKey(i)); Handle<Object> constant(descs->GetConstant(i), isolate()); - JSObject::SetLocalPropertyIgnoreAttributes( - to, key, constant, details.attributes()).Check(); + JSObject::AddProperty(to, key, constant, details.attributes()); break; } case CALLBACKS: { LookupResult result(isolate()); Handle<Name> key(Name::cast(descs->GetKey(i)), isolate()); - to->LocalLookup(key, &result); + to->LookupOwn(key, &result); // If the property is already there we skip it if (result.IsFound()) continue; HandleScope inner(isolate()); - ASSERT(!to->HasFastProperties()); + DCHECK(!to->HasFastProperties()); // Add to dictionary. Handle<Object> callbacks(descs->GetCallbacksObject(i), isolate()); PropertyDetails d = PropertyDetails( @@ -2448,23 +2480,22 @@ void Genesis::TransferNamedProperties(Handle<JSObject> from, for (int i = 0; i < capacity; i++) { Object* raw_key(properties->KeyAt(i)); if (properties->IsKey(raw_key)) { - ASSERT(raw_key->IsName()); + DCHECK(raw_key->IsName()); // If the property is already there we skip it. LookupResult result(isolate()); Handle<Name> key(Name::cast(raw_key)); - to->LocalLookup(key, &result); + to->LookupOwn(key, &result); if (result.IsFound()) continue; // Set the property. Handle<Object> value = Handle<Object>(properties->ValueAt(i), isolate()); - ASSERT(!value->IsCell()); + DCHECK(!value->IsCell()); if (value->IsPropertyCell()) { value = Handle<Object>(PropertyCell::cast(*value)->value(), isolate()); } PropertyDetails details = properties->DetailsAt(i); - JSObject::SetLocalPropertyIgnoreAttributes( - to, key, value, details.attributes()).Check(); + JSObject::AddProperty(to, key, value, details.attributes()); } } } @@ -2484,17 +2515,15 @@ void Genesis::TransferIndexedProperties(Handle<JSObject> from, void Genesis::TransferObject(Handle<JSObject> from, Handle<JSObject> to) { HandleScope outer(isolate()); - ASSERT(!from->IsJSArray()); - ASSERT(!to->IsJSArray()); + DCHECK(!from->IsJSArray()); + DCHECK(!to->IsJSArray()); TransferNamedProperties(from, to); TransferIndexedProperties(from, to); // Transfer the prototype (new map is needed). - Handle<Map> old_to_map = Handle<Map>(to->map()); - Handle<Map> new_to_map = Map::Copy(old_to_map); - new_to_map->set_prototype(from->map()->prototype()); - to->set_map(*new_to_map); + Handle<Object> proto(from->map()->prototype(), isolate()); + SetObjectPrototype(to, proto); } @@ -2502,8 +2531,8 @@ void Genesis::MakeFunctionInstancePrototypeWritable() { // 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(!sloppy_function_map_writable_prototype_.is_null()); - ASSERT(!strict_function_map_writable_prototype_.is_null()); + DCHECK(!sloppy_function_map_writable_prototype_.is_null()); + DCHECK(!strict_function_map_writable_prototype_.is_null()); // Replace function instance maps to make prototype writable. native_context()->set_sloppy_function_map( @@ -2516,8 +2545,8 @@ void Genesis::MakeFunctionInstancePrototypeWritable() { class NoTrackDoubleFieldsForSerializerScope { public: explicit NoTrackDoubleFieldsForSerializerScope(Isolate* isolate) - : isolate_(isolate), flag_(FLAG_track_double_fields) { - if (Serializer::enabled(isolate)) { + : flag_(FLAG_track_double_fields) { + if (isolate->serializer_enabled()) { // Disable tracking double fields because heap numbers treated as // immutable by the serializer. FLAG_track_double_fields = false; @@ -2525,20 +2554,17 @@ class NoTrackDoubleFieldsForSerializerScope { } ~NoTrackDoubleFieldsForSerializerScope() { - if (Serializer::enabled(isolate_)) { - FLAG_track_double_fields = flag_; - } + FLAG_track_double_fields = flag_; } private: - Isolate* isolate_; bool flag_; }; Genesis::Genesis(Isolate* isolate, - Handle<Object> global_object, - v8::Handle<v8::ObjectTemplate> global_template, + MaybeHandle<JSGlobalProxy> maybe_global_proxy, + v8::Handle<v8::ObjectTemplate> global_proxy_template, v8::ExtensionConfiguration* extensions) : isolate_(isolate), active_(isolate->bootstrapper()) { @@ -2569,35 +2595,33 @@ Genesis::Genesis(Isolate* isolate, AddToWeakNativeContextList(*native_context()); isolate->set_context(*native_context()); isolate->counters()->contexts_created_by_snapshot()->Increment(); - Handle<GlobalObject> inner_global; - Handle<JSGlobalProxy> global_proxy = - CreateNewGlobals(global_template, - global_object, - &inner_global); - - HookUpGlobalProxy(inner_global, global_proxy); - HookUpInnerGlobal(inner_global); - native_context()->builtins()->set_global_receiver( + Handle<GlobalObject> global_object; + Handle<JSGlobalProxy> global_proxy = CreateNewGlobals( + global_proxy_template, maybe_global_proxy, &global_object); + + HookUpGlobalProxy(global_object, global_proxy); + HookUpGlobalObject(global_object); + native_context()->builtins()->set_global_proxy( native_context()->global_proxy()); - if (!ConfigureGlobalObjects(global_template)) return; + if (!ConfigureGlobalObjects(global_proxy_template)) return; } else { // We get here if there was no context snapshot. CreateRoots(); Handle<JSFunction> empty_function = CreateEmptyFunction(isolate); CreateStrictModeFunctionMaps(empty_function); - Handle<GlobalObject> inner_global; - Handle<JSGlobalProxy> global_proxy = - CreateNewGlobals(global_template, global_object, &inner_global); - HookUpGlobalProxy(inner_global, global_proxy); - InitializeGlobal(inner_global, empty_function); + Handle<GlobalObject> global_object; + Handle<JSGlobalProxy> global_proxy = CreateNewGlobals( + global_proxy_template, maybe_global_proxy, &global_object); + HookUpGlobalProxy(global_object, global_proxy); + InitializeGlobal(global_object, empty_function); InstallJSFunctionResultCaches(); InitializeNormalizedMapCaches(); if (!InstallNatives()) return; MakeFunctionInstancePrototypeWritable(); - if (!ConfigureGlobalObjects(global_template)) return; + if (!ConfigureGlobalObjects(global_proxy_template)) return; isolate->counters()->contexts_created_from_scratch()->Increment(); } @@ -2608,7 +2632,7 @@ Genesis::Genesis(Isolate* isolate, // We can't (de-)serialize typed arrays currently, but we are lucky: The state // of the random number generator needs no initialization during snapshot // creation time and we don't need trigonometric functions then. - if (!Serializer::enabled(isolate)) { + if (!isolate->serializer_enabled()) { // Initially seed the per-context random number generator using the // per-isolate random number generator. const int num_elems = 2; @@ -2624,50 +2648,25 @@ Genesis::Genesis(Isolate* isolate, Utils::OpenHandle(*buffer)->set_should_be_freed(true); v8::Local<v8::Uint32Array> ta = v8::Uint32Array::New(buffer, 0, num_elems); Handle<JSBuiltinsObject> builtins(native_context()->builtins()); - Runtime::ForceSetObjectProperty(builtins, - factory()->InternalizeOneByteString( - STATIC_ASCII_VECTOR("rngstate")), - Utils::OpenHandle(*ta), - NONE).Assert(); + Runtime::DefineObjectProperty(builtins, + factory()->InternalizeOneByteString( + STATIC_ASCII_VECTOR("rngstate")), + Utils::OpenHandle(*ta), + NONE).Assert(); // Initialize trigonometric lookup tables and constants. - const int table_num_bytes = TrigonometricLookupTable::table_num_bytes(); - v8::Local<v8::ArrayBuffer> sin_buffer = v8::ArrayBuffer::New( - reinterpret_cast<v8::Isolate*>(isolate), - TrigonometricLookupTable::sin_table(), table_num_bytes); - v8::Local<v8::ArrayBuffer> cos_buffer = v8::ArrayBuffer::New( + const int constants_size = ARRAY_SIZE(fdlibm::MathConstants::constants); + const int table_num_bytes = constants_size * kDoubleSize; + v8::Local<v8::ArrayBuffer> trig_buffer = v8::ArrayBuffer::New( reinterpret_cast<v8::Isolate*>(isolate), - TrigonometricLookupTable::cos_x_interval_table(), table_num_bytes); - v8::Local<v8::Float64Array> sin_table = v8::Float64Array::New( - sin_buffer, 0, TrigonometricLookupTable::table_size()); - v8::Local<v8::Float64Array> cos_table = v8::Float64Array::New( - cos_buffer, 0, TrigonometricLookupTable::table_size()); - - Runtime::ForceSetObjectProperty(builtins, - factory()->InternalizeOneByteString( - STATIC_ASCII_VECTOR("kSinTable")), - Utils::OpenHandle(*sin_table), - NONE).Assert(); - Runtime::ForceSetObjectProperty( - builtins, - factory()->InternalizeOneByteString( - STATIC_ASCII_VECTOR("kCosXIntervalTable")), - Utils::OpenHandle(*cos_table), - NONE).Assert(); - Runtime::ForceSetObjectProperty( - builtins, - factory()->InternalizeOneByteString( - STATIC_ASCII_VECTOR("kSamples")), - factory()->NewHeapNumber( - TrigonometricLookupTable::samples()), - NONE).Assert(); - Runtime::ForceSetObjectProperty( + const_cast<double*>(fdlibm::MathConstants::constants), table_num_bytes); + v8::Local<v8::Float64Array> trig_table = + v8::Float64Array::New(trig_buffer, 0, constants_size); + + Runtime::DefineObjectProperty( builtins, - factory()->InternalizeOneByteString( - STATIC_ASCII_VECTOR("kIndexConvert")), - factory()->NewHeapNumber( - TrigonometricLookupTable::samples_over_pi_half()), - NONE).Assert(); + factory()->InternalizeOneByteString(STATIC_ASCII_VECTOR("kMath")), + Utils::OpenHandle(*trig_table), NONE).Assert(); } result_ = native_context(); @@ -2682,7 +2681,7 @@ int Bootstrapper::ArchiveSpacePerThread() { } -// Archive statics that are thread local. +// Archive statics that are thread-local. char* Bootstrapper::ArchiveState(char* to) { *reinterpret_cast<NestingCounterType*>(to) = nesting_; nesting_ = 0; @@ -2690,7 +2689,7 @@ char* Bootstrapper::ArchiveState(char* to) { } -// Restore statics that are thread local. +// Restore statics that are thread-local. char* Bootstrapper::RestoreState(char* from) { nesting_ = *reinterpret_cast<NestingCounterType*>(from); return from + sizeof(NestingCounterType); @@ -2699,7 +2698,7 @@ char* Bootstrapper::RestoreState(char* from) { // Called when the top-level V8 mutex is destroyed. void Bootstrapper::FreeThreadResources() { - ASSERT(!IsActive()); + DCHECK(!IsActive()); } } } // namespace v8::internal |