Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(130)

Unified Diff: src/bootstrapper.cc

Issue 6691003: Strict mode poision pills. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Kraken fix. Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/arm/lithium-codegen-arm.cc ('k') | src/builtins.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/bootstrapper.cc
diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc
index 8cd29b218aa9473f7468038c9ac7cbdbf48cf385..f824dced02451f45829d775338737d9ee981ef44 100644
--- a/src/bootstrapper.cc
+++ b/src/bootstrapper.cc
@@ -207,6 +207,10 @@ class Genesis BASE_EMBEDDED {
void CreateRoots();
// Creates the empty function. Used for creating a context from scratch.
Handle<JSFunction> CreateEmptyFunction();
+ void CreateThrowTypeErrorCallbacks(
+ Handle<FixedArray> callbacks,
+ Builtins::Name builtin);
+ void CreateThrowTypeError(Handle<JSFunction> empty);
// Creates the global objects using the global and the template passed in
// through the API. We call this regardless of whether we are building a
// context from scratch or using a deserialized one from the partial snapshot
@@ -263,6 +267,10 @@ class Genesis BASE_EMBEDDED {
Handle<DescriptorArray> ComputeFunctionInstanceDescriptor(
PrototypePropertyMode prototypeMode);
void MakeFunctionInstancePrototypeWritable();
+ Handle<DescriptorArray> ComputeStrictFunctionDescriptor(
+ PrototypePropertyMode propertyMode,
+ Handle<FixedArray> arguments,
+ Handle<FixedArray> caller);
static bool CompileBuiltin(int index);
static bool CompileNative(Vector<const char> name, Handle<String> source);
@@ -499,6 +507,113 @@ Handle<JSFunction> Genesis::CreateEmptyFunction() {
}
+Handle<DescriptorArray> Genesis::ComputeStrictFunctionDescriptor(
+ PrototypePropertyMode prototypeMode,
+ Handle<FixedArray> arguments,
+ Handle<FixedArray> caller) {
+ Handle<DescriptorArray> descriptors =
+ Factory::NewDescriptorArray(prototypeMode == DONT_ADD_PROTOTYPE ? 4 : 5);
+ PropertyAttributes attributes = static_cast<PropertyAttributes>(
+ DONT_ENUM | DONT_DELETE | READ_ONLY);
+
+ { // length
+ Handle<Proxy> proxy = Factory::NewProxy(&Accessors::FunctionLength);
+ CallbacksDescriptor d(*Factory::length_symbol(), *proxy, attributes);
+ descriptors->Set(0, &d);
+ }
+ { // name
+ Handle<Proxy> proxy = Factory::NewProxy(&Accessors::FunctionName);
+ CallbacksDescriptor d(*Factory::name_symbol(), *proxy, attributes);
+ descriptors->Set(1, &d);
+ }
+ { // arguments
+ CallbacksDescriptor d(*Factory::arguments_symbol(), *arguments, attributes);
+ descriptors->Set(2, &d);
+ }
+ { // caller
+ CallbacksDescriptor d(*Factory::caller_symbol(), *caller, attributes);
+ descriptors->Set(3, &d);
+ }
+
+ // prototype
+ if (prototypeMode != DONT_ADD_PROTOTYPE) {
+ if (prototypeMode == ADD_WRITEABLE_PROTOTYPE) {
+ attributes = static_cast<PropertyAttributes>(attributes & ~READ_ONLY);
+ }
+ CallbacksDescriptor d(
+ *Factory::prototype_symbol(),
+ *Factory::NewProxy(&Accessors::FunctionPrototype),
+ attributes);
+ descriptors->Set(4, &d);
+ }
+
+ descriptors->Sort();
+ return descriptors;
+}
+
+
+void Genesis::CreateThrowTypeErrorCallbacks(
+ Handle<FixedArray> callbacks,
+ Builtins::Name builtin) {
+ // Create the ThrowTypeError function.
+ Handle<String> name = Factory::LookupAsciiSymbol("ThrowTypeError");
+ Handle<JSFunction> pill = Factory::NewFunctionWithoutPrototypeStrict(name);
+ Handle<Code> code = Handle<Code>(Builtins::builtin(builtin));
+ pill->set_map(global_context()->function_map_strict());
+ pill->set_code(*code);
+ pill->shared()->set_code(*code);
+ pill->shared()->DontAdaptArguments();
+
+ // Install the poison pills into the calbacks array.
+ callbacks->set(0, *pill);
+ callbacks->set(1, *pill);
+
+ PreventExtensions(pill);
+}
+
+
+// ECMAScript 5th Edition, 13.2.3
+void Genesis::CreateThrowTypeError(Handle<JSFunction> empty) {
+ // Create the pill callbacks arrays. The get/set callacks are installed
+ // after the maps get created below.
+ Handle<FixedArray> arguments = Factory::NewFixedArray(2, TENURED);
+ Handle<FixedArray> caller = Factory::NewFixedArray(2, TENURED);
+
+ { // Allocate map for the strict mode function instances.
+ Handle<Map> map = Factory::NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
+ global_context()->set_function_instance_map_strict(*map);
+ Handle<DescriptorArray> descriptors = ComputeStrictFunctionDescriptor(
+ ADD_WRITEABLE_PROTOTYPE, arguments, caller);
+ map->set_instance_descriptors(*descriptors);
+ map->set_function_with_prototype(true);
+ map->set_prototype(*empty);
+ }
+
+ { // Allocate map for the prototype-less strict mode instances.
+ Handle<Map> map = Factory::NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
+ global_context()->set_function_without_prototype_map_strict(*map);
+ Handle<DescriptorArray> descriptors = ComputeStrictFunctionDescriptor(
+ DONT_ADD_PROTOTYPE, arguments, caller);
+ map->set_instance_descriptors(*descriptors);
+ map->set_function_with_prototype(false);
+ map->set_prototype(*empty);
+ }
+
+ { // Allocate map for the strict mode functions.
+ Handle<Map> map = Factory::NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
+ global_context()->set_function_map_strict(*map);
+ Handle<DescriptorArray> descriptors = ComputeStrictFunctionDescriptor(
+ ADD_READONLY_PROTOTYPE, arguments, caller);
+ map->set_instance_descriptors(*descriptors);
+ map->set_function_with_prototype(true);
+ map->set_prototype(*empty);
+ }
+
+ CreateThrowTypeErrorCallbacks(arguments, Builtins::StrictFunctionArguments);
+ CreateThrowTypeErrorCallbacks(caller, Builtins::StrictFunctionCaller);
+}
+
+
static void AddToWeakGlobalContextList(Context* context) {
ASSERT(context->IsGlobalContext());
#ifdef DEBUG
@@ -1813,12 +1928,37 @@ void Genesis::MakeFunctionInstancePrototypeWritable() {
// will have settable and enumerable prototype properties.
HandleScope scope;
- Handle<DescriptorArray> function_map_descriptors =
- ComputeFunctionInstanceDescriptor(ADD_WRITEABLE_PROTOTYPE);
- Handle<Map> fm = Factory::CopyMapDropDescriptors(Top::function_map());
- fm->set_instance_descriptors(*function_map_descriptors);
- fm->set_function_with_prototype(true);
- Top::context()->global_context()->set_function_map(*fm);
+ { // function_map
+ Handle<DescriptorArray> function_map_descriptors =
+ ComputeFunctionInstanceDescriptor(ADD_WRITEABLE_PROTOTYPE);
+ Handle<Map> fm = Factory::CopyMapDropDescriptors(Top::function_map());
+ fm->set_instance_descriptors(*function_map_descriptors);
+ fm->set_function_with_prototype(true);
+ Top::context()->global_context()->set_function_map(*fm);
+ }
+
+ { // function_map_strict
+ // Extract arguments and caller from the original strict function map.
+ Handle<Map> old_map(global_context()->function_map_strict());
+ Handle<DescriptorArray> old_descriptors(old_map->instance_descriptors());
+ int arguments_index = old_descriptors->Search(*Factory::arguments_symbol());
+ int caller_index = old_descriptors->Search(*Factory::caller_symbol());
+ ASSERT(arguments_index != DescriptorArray::kNotFound);
+ ASSERT(caller_index != DescriptorArray::kNotFound);
+ Handle<FixedArray> arguments(
+ FixedArray::cast(old_descriptors->GetValue(arguments_index)));
+ Handle<FixedArray> caller(
+ FixedArray::cast(old_descriptors->GetValue(caller_index)));
+
+ // Create the map with writeable prototype for strict mode functions.
+ Handle<Map> map = Factory::NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
+ global_context()->set_function_map_strict(*map);
+ Handle<DescriptorArray> descriptors = ComputeStrictFunctionDescriptor(
+ ADD_WRITEABLE_PROTOTYPE, arguments, caller);
+ map->set_instance_descriptors(*descriptors);
+ map->set_function_with_prototype(true);
+ map->set_prototype(old_map->prototype());
+ }
}
@@ -1858,6 +1998,7 @@ Genesis::Genesis(Handle<Object> global_object,
// We get here if there was no context snapshot.
CreateRoots();
Handle<JSFunction> empty_function = CreateEmptyFunction();
+ CreateThrowTypeError(empty_function);
Handle<GlobalObject> inner_global;
Handle<JSGlobalProxy> global_proxy =
CreateNewGlobals(global_template, global_object, &inner_global);
« no previous file with comments | « src/arm/lithium-codegen-arm.cc ('k') | src/builtins.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698