[runtime] Fix derived class instantiation

Bug: chromium:806388
Change-Id: Ieb343f0d532c16b6102e85222b77713f23bacf8c
Reviewed-on: https://chromium-review.googlesource.com/894942
Reviewed-by: Igor Sheludko <ishell@chromium.org>
Commit-Queue: Camillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#50990}
diff --git a/src/objects.cc b/src/objects.cc
index 9cdc77d..47ef551 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -13018,14 +13018,19 @@
                           constructor_initial_map->UnusedPropertyFields();
       int instance_size;
       int in_object_properties;
-      CalculateInstanceSizeForDerivedClass(function, instance_type,
-                                           embedder_fields, &instance_size,
-                                           &in_object_properties);
+      bool success = CalculateInstanceSizeForDerivedClass(
+          function, instance_type, embedder_fields, &instance_size,
+          &in_object_properties);
 
       int unused_property_fields = in_object_properties - pre_allocated;
-      Handle<Map> map =
-          Map::CopyInitialMap(constructor_initial_map, instance_size,
-                              in_object_properties, unused_property_fields);
+
+      Handle<Map> map;
+      if (success) {
+        map = Map::CopyInitialMap(constructor_initial_map, instance_size,
+                                  in_object_properties, unused_property_fields);
+      } else {
+        map = Map::CopyInitialMap(constructor_initial_map);
+      }
       map->set_new_target_is_base(false);
 
       JSFunction::SetInitialMap(function, map, prototype);
@@ -13781,12 +13786,14 @@
                           requested_embedder_fields;
 }
 
-void JSFunction::CalculateInstanceSizeForDerivedClass(
+// static
+bool JSFunction::CalculateInstanceSizeForDerivedClass(
     Handle<JSFunction> function, InstanceType instance_type,
     int requested_embedder_fields, int* instance_size,
     int* in_object_properties) {
   Isolate* isolate = function->GetIsolate();
   int expected_nof_properties = 0;
+  bool result = true;
   for (PrototypeIterator iter(isolate, function, kStartAtReceiver);
        !iter.IsAtEnd(); iter.Advance()) {
     Handle<JSReceiver> current =
@@ -13800,6 +13807,11 @@
         Compiler::Compile(func, Compiler::CLEAR_EXCEPTION)) {
       DCHECK(shared->is_compiled());
       expected_nof_properties += shared->expected_nof_properties();
+    } else if (!shared->is_compiled()) {
+      // In case there was a compilation error for the constructor we will
+      // throw an error during instantiation. Hence we directly return 0;
+      result = false;
+      break;
     }
     if (!IsDerivedConstructor(shared->kind())) {
       break;
@@ -13808,6 +13820,7 @@
   CalculateInstanceSizeHelper(instance_type, true, requested_embedder_fields,
                               expected_nof_properties, instance_size,
                               in_object_properties);
+  return result;
 }
 
 
diff --git a/src/objects.h b/src/objects.h
index c8e401e..b76233c 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -3680,7 +3680,7 @@
   DECL_CAST(JSFunction)
 
   // Calculate the instance size and in-object properties count.
-  static void CalculateInstanceSizeForDerivedClass(
+  static bool CalculateInstanceSizeForDerivedClass(
       Handle<JSFunction> function, InstanceType instance_type,
       int requested_embedder_fields, int* instance_size,
       int* in_object_properties);
diff --git a/test/mjsunit/regress/regress-crbug-806388.js b/test/mjsunit/regress/regress-crbug-806388.js
new file mode 100644
index 0000000..b55b501
--- /dev/null
+++ b/test/mjsunit/regress/regress-crbug-806388.js
@@ -0,0 +1,20 @@
+// Copyright 2018 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --allow-natives-syntax --enable-slow-asserts --expose-gc
+
+class Derived extends Array {
+    constructor(a) {
+      // Syntax Error.
+      const a = 1;
+    }
+}
+
+// Derived is not a subclass of RegExp
+let o = Reflect.construct(RegExp, [], Derived);
+o.lastIndex = 0x1234;
+%HeapObjectVerify(o);
+
+gc();
+%HeapObjectVerify(o);