Reviewers: Kevin Millikin,

Description:
Make functions on the built-in object non-writable.


Please review this at http://codereview.chromium.org/7736018/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files:
  M src/arm/full-codegen-arm.cc
  src/bootstrapper.cc
  M src/full-codegen.h
  M src/full-codegen.cc
  M src/ia32/full-codegen-ia32.cc
  src/messages.js
  M src/mips/full-codegen-mips.cc
  M src/runtime.h
  M src/runtime.cc
  M src/v8globals.h
  M src/x64/full-codegen-x64.cc


Index: src/arm/full-codegen-arm.cc
diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc
index b58743de41a66e6dea3c420551b52d497dd515a0..55910e9155d8f40e3a2fdf9a338b2bfc6102a9d7 100644
--- a/src/arm/full-codegen-arm.cc
+++ b/src/arm/full-codegen-arm.cc
@@ -775,9 +775,9 @@ void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
   // The context is the first argument.
   __ mov(r2, Operand(pairs));
   __ mov(r1, Operand(Smi::FromInt(is_eval() ? 1 : 0)));
-  __ mov(r0, Operand(Smi::FromInt(strict_mode_flag())));
+  __ mov(r0, Operand(Smi::FromInt(DeclareGlobalsFlags())));
   __ Push(cp, r2, r1, r0);
-  __ CallRuntime(Runtime::kDeclareGlobals, 4);
+  __ CallRuntime(Runtime::kDeclareGlobals, 3);
   // Return value is ignored.
 }

Index: src/bootstrapper.cc
diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc
index 4f7cf409404e9e909aaa0bde8d36fd3b139acccf..b0804c3e7496856b9d56c876857c80c5f8098b65 100644
--- a/src/bootstrapper.cc
+++ b/src/bootstrapper.cc
@@ -350,7 +350,14 @@ static Handle<JSFunction> InstallFunction(Handle<JSObject> target,
                                       prototype,
                                       call_code,
                                       is_ecma_native);
-  SetLocalPropertyNoThrow(target, symbol, function, DONT_ENUM);
+  PropertyAttributes attributes;
+  if (target->IsJSBuiltinsObject()) {
+    attributes =
+ static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
+  } else {
+    attributes = DONT_ENUM;
+  }
+  SetLocalPropertyNoThrow(target, symbol, function, attributes);
   if (is_ecma_native) {
     function->shared()->set_instance_class_name(*symbol);
   }
@@ -1677,7 +1684,6 @@ bool Genesis::InstallNatives() {
     global_context()->set_regexp_result_map(*initial_map);
   }

-
 #ifdef DEBUG
   builtins->Verify();
 #endif
Index: src/full-codegen.cc
diff --git a/src/full-codegen.cc b/src/full-codegen.cc
index fc7b6899bcbffb29127b009fe5ffceff22ff3908..0f44cf233ea9efc1497ff78c151ae08bf6b82ede 100644
--- a/src/full-codegen.cc
+++ b/src/full-codegen.cc
@@ -584,6 +584,15 @@ void FullCodeGenerator::VisitDeclarations(
 }


+int FullCodeGenerator::DeclareGlobalsFlags() {
+  int flags = 0;
+  if (is_eval()) flags |= kDeclareGlobalsEvalFlag;
+  if (is_strict_mode()) flags |= kDeclareGlobalsStrictModeFlag;
+  if (is_native()) flags |= kDeclareGlobalsNativeFlag;
+  return flags;
+}
+
+
 void FullCodeGenerator::SetFunctionPosition(FunctionLiteral* fun) {
   CodeGenerator::RecordPositions(masm_, fun->start_position());
 }
Index: src/full-codegen.h
diff --git a/src/full-codegen.h b/src/full-codegen.h
index 0ed26a149e8da8d04cd968411daf0217ef7c7270..56bfe85cac4965b85ad7add517c35ded0fbd3a35 100644
--- a/src/full-codegen.h
+++ b/src/full-codegen.h
@@ -358,6 +358,7 @@ class FullCodeGenerator: public AstVisitor {

   void VisitDeclarations(ZoneList<Declaration*>* declarations);
   void DeclareGlobals(Handle<FixedArray> pairs);
+  int DeclareGlobalsFlags();

   // Try to perform a comparison as a fast inlined literal compare if
   // the operands allow it.  Returns true if the compare operations
@@ -555,6 +556,7 @@ class FullCodeGenerator: public AstVisitor {

   Handle<Script> script() { return info_->script(); }
   bool is_eval() { return info_->is_eval(); }
+  bool is_native() { return info_->is_native(); }
   bool is_strict_mode() { return function()->strict_mode(); }
   StrictModeFlag strict_mode_flag() {
     return is_strict_mode() ? kStrictMode : kNonStrictMode;
Index: src/ia32/full-codegen-ia32.cc
diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc
index 799ba73a26328d62e60c36807af3d3ef0dcf8335..762974f9ef89ccde611453046d9e0f8efeeb9272 100644
--- a/src/ia32/full-codegen-ia32.cc
+++ b/src/ia32/full-codegen-ia32.cc
@@ -770,9 +770,8 @@ void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
   // Call the runtime to declare the globals.
   __ push(esi);  // The context is the first argument.
   __ push(Immediate(pairs));
-  __ push(Immediate(Smi::FromInt(is_eval() ? 1 : 0)));
-  __ push(Immediate(Smi::FromInt(strict_mode_flag())));
-  __ CallRuntime(Runtime::kDeclareGlobals, 4);
+  __ push(Immediate(Smi::FromInt(DeclareGlobalsFlags())));
+  __ CallRuntime(Runtime::kDeclareGlobals, 3);
   // Return value is ignored.
 }

Index: src/messages.js
diff --git a/src/messages.js b/src/messages.js
index cbbb70eb1a8e37392676cc8258cdfb17afacd89b..0a00d356246a52a0e7ae62e924f921ba6e8f959f 100644
--- a/src/messages.js
+++ b/src/messages.js
@@ -29,17 +29,17 @@
 // -------------------------------------------------------------------
 //
 // Matches Script::Type from objects.h
-var TYPE_NATIVE = 0;
-var TYPE_EXTENSION = 1;
-var TYPE_NORMAL = 2;
+const TYPE_NATIVE = 0;
+const TYPE_EXTENSION = 1;
+const TYPE_NORMAL = 2;

 // Matches Script::CompilationType from objects.h
-var COMPILATION_TYPE_HOST = 0;
-var COMPILATION_TYPE_EVAL = 1;
-var COMPILATION_TYPE_JSON = 2;
+const COMPILATION_TYPE_HOST = 0;
+const COMPILATION_TYPE_EVAL = 1;
+const COMPILATION_TYPE_JSON = 2;

 // Matches Messages::kNoLineNumberInfo from v8.h
-var kNoLineNumberInfo = 0;
+const kNoLineNumberInfo = 0;

 // If this object gets passed to an error constructor the error will
 // get an accessor for .message that constructs a descriptive error
@@ -1007,7 +1007,7 @@ function DefineError(f) {
   // user code.
   var name = f.name;
   %SetProperty(global, name, f, DONT_ENUM);
-  this['$' + name] = f;
+  %SetProperty(this, '$' + name, f, DONT_ENUM | DONT_DELETE | READ_ONLY);
   // Configure the error function.
   if (name == 'Error') {
     // The prototype of the Error object must itself be an error.
@@ -1024,7 +1024,7 @@ function DefineError(f) {
   %FunctionSetInstanceClassName(f, 'Error');
   %SetProperty(f.prototype, 'constructor', f, DONT_ENUM);
   // The name property on the prototype of error objects is not
-  // specified as being read-one and dont-delete. However, allowing
+  // specified as being read-only and dont-delete. However, allowing
   // overwriting allows leaks of error objects between script blocks
   // in the same context in a browser setting. Therefore we fix the
   // name.
Index: src/mips/full-codegen-mips.cc
diff --git a/src/mips/full-codegen-mips.cc b/src/mips/full-codegen-mips.cc
index cf48ccfd4fa0af4798baacd37b68aa3a2150deef..1435f7723def102035c5551253978a7255912778 100644
--- a/src/mips/full-codegen-mips.cc
+++ b/src/mips/full-codegen-mips.cc
@@ -782,9 +782,9 @@ void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
   // The context is the first argument.
   __ li(a2, Operand(pairs));
   __ li(a1, Operand(Smi::FromInt(is_eval() ? 1 : 0)));
-  __ li(a0, Operand(Smi::FromInt(strict_mode_flag())));
+  __ li(a0, Operand(Smi::FromInt(DeclareGlobalsFlags())));
   __ Push(cp, a2, a1, a0);
-  __ CallRuntime(Runtime::kDeclareGlobals, 4);
+  __ CallRuntime(Runtime::kDeclareGlobals, 3);
   // Return value is ignored.
 }

Index: src/runtime.cc
diff --git a/src/runtime.cc b/src/runtime.cc
index 802fd6845d0204cabeba1de5cd070261ebbf3e66..b8885124d95951c1963795ddf3dc027b0660e03d 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -1149,16 +1149,19 @@ static Failure* ThrowRedeclarationError(Isolate* isolate,


 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareGlobals) {
-  ASSERT(args.length() == 4);
+  ASSERT(args.length() == 3);
   HandleScope scope(isolate);
   Handle<GlobalObject> global = Handle<GlobalObject>(
       isolate->context()->global());

   Handle<Context> context = args.at<Context>(0);
   CONVERT_ARG_CHECKED(FixedArray, pairs, 1);
-  bool is_eval = args.smi_at(2) == 1;
-  StrictModeFlag strict_mode = static_cast<StrictModeFlag>(args.smi_at(3));
-  ASSERT(strict_mode == kStrictMode || strict_mode == kNonStrictMode);
+  CONVERT_SMI_ARG_CHECKED(flags, 2);
+  bool is_eval = (flags & kDeclareGlobalsEvalFlag) != 0;
+  StrictModeFlag strict_mode =
+      ((flags & kDeclareGlobalsStrictModeFlag) != 0) ? kStrictMode
+                                                     : kNonStrictMode;
+  bool is_native = (flags & kDeclareGlobalsNativeFlag) != 0;

   // Compute the property attributes. According to ECMA-262, section
   // 13, page 71, the property must be read-only and
@@ -1177,7 +1180,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareGlobals) {
     // assign to it when evaluating the assignment for "const x =
     // <expr>" the initial value is the hole.
     bool is_const_property = value->IsTheHole();
-
+    bool is_function_declaration = false;
     if (value->IsUndefined() || is_const_property) {
       // Lookup the property in the global object, and don't set the
       // value of the variable if the property is already there.
@@ -1226,6 +1229,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareGlobals) {
         }
       }
     } else {
+      is_function_declaration = true;
       // Copy the function and update its context. Use it as value.
       Handle<SharedFunctionInfo> shared =
           Handle<SharedFunctionInfo>::cast(value);
@@ -1239,7 +1243,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareGlobals) {
     LookupResult lookup;
     global->LocalLookup(*name, &lookup);

-    PropertyAttributes attributes = is_const_property
+    PropertyAttributes attributes =
+        (is_const_property || (is_native && is_function_declaration))
         ? static_cast<PropertyAttributes>(base | READ_ONLY)
         : base;

Index: src/runtime.h
diff --git a/src/runtime.h b/src/runtime.h
index 91a19dfd453d592aec932b884862a06e3ff14ce0..7db26db90d5f723e797e78becaf2a20dc50dc9f0 100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -317,7 +317,7 @@ namespace internal {
   F(StoreContextSlot, 4, 1) \
   \
   /* Declarations and initialization */ \
-  F(DeclareGlobals, 4, 1) \
+  F(DeclareGlobals, 3, 1) \
   F(DeclareContextSlot, 4, 1) \
   F(InitializeVarGlobal, -1 /* 2 or 3 */, 1) \
   F(InitializeConstGlobal, 2, 1) \
@@ -663,6 +663,16 @@ class Runtime : public AllStatic {
   static void PerformGC(Object* result);
 };

+
+//---------------------------------------------------------------------------
+// Constants used by interface to runtime functions.
+
+enum kDeclareGlobalsFlags {
+  kDeclareGlobalsEvalFlag = 1 << 0,
+  kDeclareGlobalsStrictModeFlag = 1 << 1,
+  kDeclareGlobalsNativeFlag = 1 << 2
+};
+
 } }  // namespace v8::internal

 #endif  // V8_RUNTIME_H_
Index: src/v8globals.h
diff --git a/src/v8globals.h b/src/v8globals.h
index aff27579f8d78b6cd8337f9b8fba578237993c42..1fcd812b3ddd9e16f0a248373ab5eb91077f3614 100644
--- a/src/v8globals.h
+++ b/src/v8globals.h
@@ -482,8 +482,8 @@ enum CpuFeature { SSE4_1 = 32 + 19,  // x86

 // The Strict Mode (ECMA-262 5th edition, 4.2.2).
 enum StrictModeFlag {
-  kNonStrictMode,
-  kStrictMode,
+  kNonStrictMode = 0,
+  kStrictMode = 1,
// This value is never used, but is needed to prevent GCC 4.5 from failing
   // to compile when we assert that a flag is either kNonStrictMode or
   // kStrictMode.
Index: src/x64/full-codegen-x64.cc
diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc
index dd35053a654ff44e468e1db5d3053cc85361c07b..3e3afc29823f769cfaae3fd17b21c359d27429d0 100644
--- a/src/x64/full-codegen-x64.cc
+++ b/src/x64/full-codegen-x64.cc
@@ -741,9 +741,8 @@ void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
   // Call the runtime to declare the globals.
   __ push(rsi);  // The context is the first argument.
   __ Push(pairs);
-  __ Push(Smi::FromInt(is_eval() ? 1 : 0));
-  __ Push(Smi::FromInt(strict_mode_flag()));
-  __ CallRuntime(Runtime::kDeclareGlobals, 4);
+  __ Push(Smi::FromInt(DeclareGlobalsFlags()));
+  __ CallRuntime(Runtime::kDeclareGlobals, 3);
   // Return value is ignored.
 }



--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to