Improve error reporting for duplicate object template properties.
authorverwaest@chromium.org <verwaest@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 1 Jul 2014 10:00:19 +0000 (10:00 +0000)
committerverwaest@chromium.org <verwaest@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 1 Jul 2014 10:00:19 +0000 (10:00 +0000)
BUG=
R=yangguo@chromium.org

Review URL: https://codereview.chromium.org/359413007

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@22112 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/apinatives.js
src/messages.js
src/runtime.cc
src/runtime.h
test/mjsunit/runtime-gen/addpropertyfortemplate.js [new file with mode: 0644]
tools/generate-runtime-tests.py

index 50c753e..0ba5c68 100644 (file)
@@ -99,7 +99,7 @@ function ConfigureTemplateInstance(obj, data) {
         var prop_data = properties[i + 2];
         var attributes = properties[i + 3];
         var value = Instantiate(prop_data, name);
-        %AddProperty(obj, name, value, attributes);
+        %AddPropertyForTemplate(obj, name, value, attributes);
       } else if (length == 4 || length == 5) {
         // TODO(verwaest): The 5th value used to be access_control. Remove once
         // the bindings are updated.
index 8f83a62..da373b2 100644 (file)
@@ -26,6 +26,7 @@ var kMessages = {
   newline_after_throw:           ["Illegal newline after throw"],
   label_redeclaration:           ["Label '", "%0", "' has already been declared"],
   var_redeclaration:             ["Identifier '", "%0", "' has already been declared"],
+  duplicate_template_property:   ["Object template has duplicate property '", "%0", "'"],
   no_catch_or_finally:           ["Missing catch or finally after try"],
   unknown_label:                 ["Undefined label '", "%0", "'"],
   uncaught_exception:            ["Uncaught ", "%0"],
index 339c45d..37e2fde 100644 (file)
@@ -5339,15 +5339,59 @@ RUNTIME_FUNCTION(Runtime_AddProperty) {
       static_cast<PropertyAttributes>(unchecked_attributes);
 
 #ifdef DEBUG
+  bool duplicate;
   if (key->IsName()) {
     LookupIterator it(object, Handle<Name>::cast(key),
                       LookupIterator::CHECK_OWN_REAL);
     JSReceiver::GetPropertyAttributes(&it);
-    RUNTIME_ASSERT(!it.IsFound());
+    duplicate = it.IsFound();
   } else {
     uint32_t index = 0;
     RUNTIME_ASSERT(key->ToArrayIndex(&index));
-    RUNTIME_ASSERT(!JSReceiver::HasOwnElement(object, index));
+    duplicate = JSReceiver::HasOwnElement(object, index);
+  }
+  RUNTIME_ASSERT(!duplicate);
+#endif
+
+  Handle<Object> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, result,
+      Runtime::DefineObjectProperty(object, key, value, attributes));
+  return *result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_AddPropertyForTemplate) {
+  HandleScope scope(isolate);
+  RUNTIME_ASSERT(args.length() == 4);
+
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
+  CONVERT_SMI_ARG_CHECKED(unchecked_attributes, 3);
+  RUNTIME_ASSERT(
+      (unchecked_attributes & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
+  // Compute attributes.
+  PropertyAttributes attributes =
+      static_cast<PropertyAttributes>(unchecked_attributes);
+
+#ifdef DEBUG
+  bool duplicate;
+  if (key->IsName()) {
+    LookupIterator it(object, Handle<Name>::cast(key),
+                      LookupIterator::CHECK_OWN_REAL);
+    JSReceiver::GetPropertyAttributes(&it);
+    duplicate = it.IsFound();
+  } else {
+    uint32_t index = 0;
+    RUNTIME_ASSERT(key->ToArrayIndex(&index));
+    duplicate = JSReceiver::HasOwnElement(object, index);
+  }
+  if (duplicate) {
+    Handle<Object> args[1] = { key };
+    Handle<Object> error = isolate->factory()->NewTypeError(
+        "duplicate_template_property", HandleVector(args, 1));
+    return isolate->Throw(*error);
   }
 #endif
 
index ebc8598..f4fe6f7 100644 (file)
@@ -225,6 +225,7 @@ namespace internal {
   F(IsAttachedGlobal, 1, 1) \
   \
   F(AddProperty, 4, 1) \
+  F(AddPropertyForTemplate, 4, 1) \
   F(SetProperty, 4, 1) \
   F(DefineDataPropertyUnchecked, 4, 1) \
   F(DefineAccessorPropertyUnchecked, 5, 1) \
diff --git a/test/mjsunit/runtime-gen/addpropertyfortemplate.js b/test/mjsunit/runtime-gen/addpropertyfortemplate.js
new file mode 100644 (file)
index 0000000..bb8cf36
--- /dev/null
@@ -0,0 +1,8 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
+// Flags: --allow-natives-syntax --harmony
+var _object = new Object();
+var arg1 = 10;
+var _value = new Object();
+var _unchecked_attributes = 1;
+%AddPropertyForTemplate(_object, arg1, _value, _unchecked_attributes);
index f018cf0..c6049bf 100755 (executable)
@@ -47,8 +47,8 @@ EXPAND_MACROS = [
 # that the parser doesn't bit-rot. Change the values as needed when you add,
 # remove or change runtime functions, but make sure we don't lose our ability
 # to parse them!
-EXPECTED_FUNCTION_COUNT = 416
-EXPECTED_FUZZABLE_COUNT = 331
+EXPECTED_FUNCTION_COUNT = 417
+EXPECTED_FUZZABLE_COUNT = 332
 EXPECTED_CCTEST_COUNT = 6
 EXPECTED_UNKNOWN_COUNT = 4
 EXPECTED_BUILTINS_COUNT = 809
@@ -212,6 +212,7 @@ _NUMBER_FORMAT = (
 # None means "fall back to autodetected value".
 CUSTOM_KNOWN_GOOD_INPUT = {
   "AddProperty": [None, 10, None, None, None],
+  "AddPropertyForTemplate": [None, 10, None, None, None],
   "Apply": ["function() {}", None, None, None, None, None],
   "ArrayBufferSliceImpl": [None, None, 0, None],
   "ArrayConcat": ["[1, 'a']", None],