Added support for strict mode parameter and object property validation.

Fixed a couple of crash bugs.


git-svn-id: http://v8.googlecode.com/svn/trunk@6521 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/test/cctest/cctest.status b/test/cctest/cctest.status
index b056403..1009f85 100644
--- a/test/cctest/cctest.status
+++ b/test/cctest/cctest.status
@@ -51,6 +51,8 @@
 test-serialize/TestThatAlwaysFails: FAIL
 test-serialize/DependentTestThatAlwaysFails: FAIL
 
+# BUG(1079)
+test-api/CaptureStackTraceForUncaughtException: PASS || FAIL
 
 ##############################################################################
 [ $arch == x64 ]
@@ -101,6 +103,11 @@
 test-debug/DebuggerAgentProtocolOverflowHeader: SKIP
 test-sockets/Socket: SKIP
 
+# BUG(1075): Some deserialization tests fail om ARM
+test-serialize/Deserialize: SKIP
+test-serialize/DeserializeFromSecondSerializationAndRunScript2: SKIP
+test-serialize/DeserializeAndRunScript2: SKIP
+test-serialize/DeserializeFromSecondSerialization: SKIP
 
 ##############################################################################
 [ $arch == arm && $crankshaft ]
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index 90f4996..48dc72e 100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -2389,6 +2389,11 @@
   CompileRun("asdf;");
   v8::Handle<Value> string = CompileRun("try { asdf; } catch(e) { e + ''; }");
   CHECK(string->Equals(v8_str("Whoops")));
+  CompileRun("ReferenceError.prototype.constructor = new Object();"
+             "ReferenceError.prototype.constructor.name = 1;"
+             "Number.prototype.toString = function() { return 'Whoops'; };"
+             "ReferenceError.prototype.toString = Object.prototype.toString;");
+  CompileRun("asdf;");
   v8::V8::RemoveMessageListeners(check_message);
 }
 
diff --git a/test/cctest/test-assembler-arm.cc b/test/cctest/test-assembler-arm.cc
index 0f12f98..af1a4e8 100644
--- a/test/cctest/test-assembler-arm.cc
+++ b/test/cctest/test-assembler-arm.cc
@@ -45,11 +45,7 @@
 static v8::Persistent<v8::Context> env;
 
 
-// The test framework does not accept flags on the command line, so we set them
 static void InitializeVM() {
-  // enable generation of comments
-  FLAG_debug_code = true;
-
   if (env.IsEmpty()) {
     env = v8::Context::New();
   }
diff --git a/test/cctest/test-assembler-mips.cc b/test/cctest/test-assembler-mips.cc
index 955562b..ecb42e2 100644
--- a/test/cctest/test-assembler-mips.cc
+++ b/test/cctest/test-assembler-mips.cc
@@ -47,14 +47,10 @@
 static v8::Persistent<v8::Context> env;
 
 
-// The test framework does not accept flags on the command line, so we set them.
 static void InitializeVM() {
   // Disable compilation of natives.
   FLAG_disable_native_files = true;
 
-  // Enable generation of comments.
-  FLAG_debug_code = true;
-
   if (env.IsEmpty()) {
     env = v8::Context::New();
   }
diff --git a/test/mjsunit/delete-global-properties.js b/test/mjsunit/delete-global-properties.js
index b3813dc..2acf591 100644
--- a/test/mjsunit/delete-global-properties.js
+++ b/test/mjsunit/delete-global-properties.js
@@ -1,4 +1,4 @@
-// Copyright 2008 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -32,6 +32,17 @@
 assertTrue("tmp" in this);
 function f() { return 1; }
 assertFalse(delete f);  // should be DONT_DELETE
-assertEquals(1, f());  
+assertEquals(1, f());
 
-/* Perhaps related to bugs/11? */
+// Check that deleting and reintroducing global variables works.
+// Get into the IC case for storing to a deletable global property.
+function introduce_x() { x = 42; }
+for (var i = 0; i < 10; i++) introduce_x();
+// Check that the property has been introduced.
+assertTrue(this.hasOwnProperty('x'));
+// Check that deletion works.
+delete x;
+assertFalse(this.hasOwnProperty('x'));
+// Check that reintroduction works.
+introduce_x();
+assertTrue(this.hasOwnProperty('x'));
diff --git a/test/mjsunit/strict-mode.js b/test/mjsunit/strict-mode.js
index 83a22cc..6f3a244 100644
--- a/test/mjsunit/strict-mode.js
+++ b/test/mjsunit/strict-mode.js
@@ -44,6 +44,23 @@
     }", exception);
 }
 
+function CheckFunctionConstructorStrictMode() {
+  var args = [];
+  for (var i = 0; i < arguments.length; i ++) {
+    args[i] = arguments[i];
+  }
+  // Create non-strict function. No exception.
+  args[arguments.length] = "";
+  assertDoesNotThrow(function() {
+    Function.apply(this, args);
+  });
+  // Create strict mode function. Exception expected.
+  args[arguments.length] = "'use strict';";
+  assertThrows(function() {
+    Function.apply(this, args);
+  }, SyntaxError);
+}
+
 // Incorrect 'use strict' directive.
 function UseStrictEscape() {
   "use\\x20strict";
@@ -76,19 +93,29 @@
 CheckStrictMode("function arguments() {}", SyntaxError)
 
 // Function parameter named 'eval'.
-//CheckStrictMode("function foo(a, b, eval, c, d) {}", SyntaxError)
+CheckStrictMode("function foo(a, b, eval, c, d) {}", SyntaxError)
 
 // Function parameter named 'arguments'.
-//CheckStrictMode("function foo(a, b, arguments, c, d) {}", SyntaxError)
+CheckStrictMode("function foo(a, b, arguments, c, d) {}", SyntaxError)
 
 // Property accessor parameter named 'eval'.
-//CheckStrictMode("var o = { set foo(eval) {} }", SyntaxError)
+CheckStrictMode("var o = { set foo(eval) {} }", SyntaxError)
 
 // Property accessor parameter named 'arguments'.
-//CheckStrictMode("var o = { set foo(arguments) {} }", SyntaxError)
+CheckStrictMode("var o = { set foo(arguments) {} }", SyntaxError)
 
 // Duplicate function parameter name.
-//CheckStrictMode("function foo(a, b, c, d, b) {}", SyntaxError)
+CheckStrictMode("function foo(a, b, c, d, b) {}", SyntaxError)
+
+// Function constructor: eval parameter name.
+CheckFunctionConstructorStrictMode("eval")
+
+// Function constructor: arguments parameter name.
+CheckFunctionConstructorStrictMode("arguments")
+
+// Function constructor: duplicate parameter name.
+CheckFunctionConstructorStrictMode("a", "b", "c", "b")
+CheckFunctionConstructorStrictMode("a,b,c,b")
 
 // catch(eval)
 CheckStrictMode("try{}catch(eval){};", SyntaxError)
@@ -103,10 +130,10 @@
 CheckStrictMode("var arguments;", SyntaxError)
 
 // Strict mode applies to the function in which the directive is used..
-//assertThrows('\
-//function foo(eval) {\
-//  "use strict";\
-//}', SyntaxError);
+assertThrows('\
+function foo(eval) {\
+  "use strict";\
+}', SyntaxError);
 
 // Strict mode doesn't affect the outer stop of strict code.
 function NotStrict(eval) {
@@ -129,3 +156,112 @@
     "octal\\032directive";\
     "use strict";\
   }', SyntaxError);
+
+// Duplicate data properties.
+CheckStrictMode("var x = { dupe : 1, nondupe: 3, dupe : 2 };", SyntaxError)
+CheckStrictMode("var x = { '1234' : 1, '2345' : 2, '1234' : 3 };", SyntaxError)
+CheckStrictMode("var x = { '1234' : 1, '2345' : 2, 1234 : 3 };", SyntaxError)
+CheckStrictMode("var x = { 3.14 : 1, 2.71 : 2, 3.14 : 3 };", SyntaxError)
+CheckStrictMode("var x = { 3.14 : 1, '3.14' : 2 };", SyntaxError)
+CheckStrictMode("var x = { 123: 1, 123.00000000000000000000000000000000000000000000000000000000000000000001 : 2 }", SyntaxError)
+
+// Non-conflicting data properties.
+function StrictModeNonDuplicate() {
+  "use strict";
+  var x = { 123 : 1, "0123" : 2 };
+  var x = { 123: 1, '123.00000000000000000000000000000000000000000000000000000000000000000001' : 2 }
+}
+
+// Two getters (non-strict)
+assertThrows("var x = { get foo() { }, get foo() { } };", SyntaxError)
+assertThrows("var x = { get foo(){}, get 'foo'(){}};", SyntaxError)
+assertThrows("var x = { get 12(){}, get '12'(){}};", SyntaxError)
+
+// Two setters (non-strict)
+assertThrows("var x = { set foo(v) { }, set foo(v) { } };", SyntaxError)
+assertThrows("var x = { set foo(v) { }, set 'foo'(v) { } };", SyntaxError)
+assertThrows("var x = { set 13(v) { }, set '13'(v) { } };", SyntaxError)
+
+// Setter and data (non-strict)
+assertThrows("var x = { foo: 'data', set foo(v) { } };", SyntaxError)
+assertThrows("var x = { set foo(v) { }, foo: 'data' };", SyntaxError)
+assertThrows("var x = { foo: 'data', set 'foo'(v) { } };", SyntaxError)
+assertThrows("var x = { set foo(v) { }, 'foo': 'data' };", SyntaxError)
+assertThrows("var x = { 'foo': 'data', set foo(v) { } };", SyntaxError)
+assertThrows("var x = { set 'foo'(v) { }, foo: 'data' };", SyntaxError)
+assertThrows("var x = { 'foo': 'data', set 'foo'(v) { } };", SyntaxError)
+assertThrows("var x = { set 'foo'(v) { }, 'foo': 'data' };", SyntaxError)
+assertThrows("var x = { 12: 1, set '12'(v){}};", SyntaxError);
+assertThrows("var x = { 12: 1, set 12(v){}};", SyntaxError);
+assertThrows("var x = { '12': 1, set '12'(v){}};", SyntaxError);
+assertThrows("var x = { '12': 1, set 12(v){}};", SyntaxError);
+
+// Getter and data (non-strict)
+assertThrows("var x = { foo: 'data', get foo() { } };", SyntaxError)
+assertThrows("var x = { get foo() { }, foo: 'data' };", SyntaxError)
+assertThrows("var x = { 'foo': 'data', get foo() { } };", SyntaxError)
+assertThrows("var x = { get 'foo'() { }, 'foo': 'data' };", SyntaxError)
+assertThrows("var x = { '12': 1, get '12'(){}};", SyntaxError);
+assertThrows("var x = { '12': 1, get 12(){}};", SyntaxError);
+
+// Assignment to eval or arguments
+CheckStrictMode("function strict() { eval = undefined; }", SyntaxError)
+CheckStrictMode("function strict() { arguments = undefined; }", SyntaxError)
+CheckStrictMode("function strict() { print(eval = undefined); }", SyntaxError)
+CheckStrictMode("function strict() { print(arguments = undefined); }", SyntaxError)
+CheckStrictMode("function strict() { var x = eval = undefined; }", SyntaxError)
+CheckStrictMode("function strict() { var x = arguments = undefined; }", SyntaxError)
+
+// Compound assignment to eval or arguments
+CheckStrictMode("function strict() { eval *= undefined; }", SyntaxError)
+CheckStrictMode("function strict() { arguments /= undefined; }", SyntaxError)
+CheckStrictMode("function strict() { print(eval %= undefined); }", SyntaxError)
+CheckStrictMode("function strict() { print(arguments %= undefined); }", SyntaxError)
+CheckStrictMode("function strict() { var x = eval += undefined; }", SyntaxError)
+CheckStrictMode("function strict() { var x = arguments -= undefined; }", SyntaxError)
+CheckStrictMode("function strict() { eval <<= undefined; }", SyntaxError)
+CheckStrictMode("function strict() { arguments >>= undefined; }", SyntaxError)
+CheckStrictMode("function strict() { print(eval >>>= undefined); }", SyntaxError)
+CheckStrictMode("function strict() { print(arguments &= undefined); }", SyntaxError)
+CheckStrictMode("function strict() { var x = eval ^= undefined; }", SyntaxError)
+CheckStrictMode("function strict() { var x = arguments |= undefined; }", SyntaxError)
+
+// Postfix increment with eval or arguments
+CheckStrictMode("function strict() { eval++; }", SyntaxError)
+CheckStrictMode("function strict() { arguments++; }", SyntaxError)
+CheckStrictMode("function strict() { print(eval++); }", SyntaxError)
+CheckStrictMode("function strict() { print(arguments++); }", SyntaxError)
+CheckStrictMode("function strict() { var x = eval++; }", SyntaxError)
+CheckStrictMode("function strict() { var x = arguments++; }", SyntaxError)
+
+// Postfix decrement with eval or arguments
+CheckStrictMode("function strict() { eval--; }", SyntaxError)
+CheckStrictMode("function strict() { arguments--; }", SyntaxError)
+CheckStrictMode("function strict() { print(eval--); }", SyntaxError)
+CheckStrictMode("function strict() { print(arguments--); }", SyntaxError)
+CheckStrictMode("function strict() { var x = eval--; }", SyntaxError)
+CheckStrictMode("function strict() { var x = arguments--; }", SyntaxError)
+
+// Prefix increment with eval or arguments
+CheckStrictMode("function strict() { ++eval; }", SyntaxError)
+CheckStrictMode("function strict() { ++arguments; }", SyntaxError)
+CheckStrictMode("function strict() { print(++eval); }", SyntaxError)
+CheckStrictMode("function strict() { print(++arguments); }", SyntaxError)
+CheckStrictMode("function strict() { var x = ++eval; }", SyntaxError)
+CheckStrictMode("function strict() { var x = ++arguments; }", SyntaxError)
+
+// Prefix decrement with eval or arguments
+CheckStrictMode("function strict() { --eval; }", SyntaxError)
+CheckStrictMode("function strict() { --arguments; }", SyntaxError)
+CheckStrictMode("function strict() { print(--eval); }", SyntaxError)
+CheckStrictMode("function strict() { print(--arguments); }", SyntaxError)
+CheckStrictMode("function strict() { var x = --eval; }", SyntaxError)
+CheckStrictMode("function strict() { var x = --arguments; }", SyntaxError)
+
+// Prefix unary operators other than delete, ++, -- are valid in strict mode
+function StrictModeUnaryOperators() {
+  "use strict";
+  var x = [void eval, typeof eval, +eval, -eval, ~eval, !eval];
+  var y = [void arguments, typeof arguments,
+           +arguments, -arguments, ~arguments, !arguments];
+}
\ No newline at end of file