Reviewers: rossberg, Benedikt Meurer,
Message:
PTAL
Description:
[strong] weak classes can't inherit from strong ones
Prerequisite for sealing strong class instances.
Depends on https://codereview.chromium.org/1314203002/
BUG=v8:3956
LOG=N
Please review this at https://codereview.chromium.org/1316333002/
Base URL: https://chromium.googlesource.com/v8/v8.git@master
Affected files (+43, -52 lines):
M src/compiler/ast-graph-builder.cc
M src/full-codegen/full-codegen.cc
M src/messages.h
M src/runtime/runtime.h
M src/runtime/runtime-classes.cc
M test/mjsunit/strong/class-object-frozen.js
A test/mjsunit/strong/class-weak-extend.js
M test/mjsunit/strong/literals.js
Index: src/compiler/ast-graph-builder.cc
diff --git a/src/compiler/ast-graph-builder.cc
b/src/compiler/ast-graph-builder.cc
index
10abec7b8824741217a09e39e69e8e35b4a9224c..3eebbbcf677dd78b52c8cfae82aa8474c86d1515
100644
--- a/src/compiler/ast-graph-builder.cc
+++ b/src/compiler/ast-graph-builder.cc
@@ -1564,10 +1564,7 @@ void
AstGraphBuilder::VisitClassLiteralContents(ClassLiteral* expr) {
Node* name = environment()->Pop();
Node* start = jsgraph()->Constant(expr->start_position());
Node* end = jsgraph()->Constant(expr->end_position());
- const Operator* opc = javascript()->CallRuntime(
- is_strong(language_mode()) ? Runtime::kDefineClassStrong
- : Runtime::kDefineClass,
- 5);
+ const Operator* opc = javascript()->CallRuntime(Runtime::kDefineClass,
5);
Node* literal = NewNode(opc, name, extends, constructor, start, end);
PrepareFrameState(literal, expr->CreateLiteralId(),
OutputFrameStateCombine::Push());
Index: src/full-codegen/full-codegen.cc
diff --git a/src/full-codegen/full-codegen.cc
b/src/full-codegen/full-codegen.cc
index
fa2f921d016786a56b276f854f99360db42db684..5ef9d0a0b935eb2f163cb43f4bd1785010135320
100644
--- a/src/full-codegen/full-codegen.cc
+++ b/src/full-codegen/full-codegen.cc
@@ -1297,9 +1297,7 @@ void
FullCodeGenerator::VisitClassLiteral(ClassLiteral* lit) {
__ Push(Smi::FromInt(lit->start_position()));
__ Push(Smi::FromInt(lit->end_position()));
- __ CallRuntime(is_strong(language_mode()) ? Runtime::kDefineClassStrong
- : Runtime::kDefineClass,
- 5);
+ __ CallRuntime(Runtime::kDefineClass, 5);
PrepareForBailoutForId(lit->CreateLiteralId(), TOS_REG);
int store_slot_index = 0;
Index: src/messages.h
diff --git a/src/messages.h b/src/messages.h
index
409353dc5c1bf87f6aae2a82073e6f47946c8810..4ed94780d1b3fd841b45bdfc9ba8aa1553aa8c98
100644
--- a/src/messages.h
+++ b/src/messages.h
@@ -225,6 +225,7 @@ class CallSite {
"to be non-writable is
deprecated") \
T(StrongSetProto,
\
"On strong object %, redefining the internal prototype is
deprecated") \
+ T(StrongWeakExtend, "Non-strong class % cannot extend a strong
object") \
T(SymbolKeyFor, "% is not a
symbol") \
T(SymbolToNumber, "Cannot convert a Symbol value to a
number") \
T(SymbolToString, "Cannot convert a Symbol value to a
string") \
Index: src/runtime/runtime-classes.cc
diff --git a/src/runtime/runtime-classes.cc b/src/runtime/runtime-classes.cc
index
bc273eec307279c02024b674b0ac1843e8d72a73..f76ee81f2d1079580164b0163960712bfe1051f0
100644
--- a/src/runtime/runtime-classes.cc
+++ b/src/runtime/runtime-classes.cc
@@ -138,6 +138,18 @@ static MaybeHandle<Object> DefineClass(Isolate*
isolate, Handle<Object> name,
isolate->factory()->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
if (constructor->map()->is_strong()) {
map->set_is_strong();
+ // Strong class is not permitted to extend null.
+ if (super_class->IsNull()) {
+ THROW_NEW_ERROR(isolate,
NewTypeError(MessageTemplate::kStrongExtendNull),
+ Object);
+ }
+ } else {
+ if (Handle<HeapObject>::cast(super_class)->map()->is_strong()) {
+ // Weak class is not permitted to extend strong class.
+ THROW_NEW_ERROR(isolate,
+ NewTypeError(MessageTemplate::kStrongWeakExtend,
name),
+ Object);
+ }
}
Map::SetPrototype(map, prototype_parent);
map->SetConstructor(*constructor);
@@ -212,28 +224,6 @@ RUNTIME_FUNCTION(Runtime_DefineClass) {
}
-RUNTIME_FUNCTION(Runtime_DefineClassStrong) {
- HandleScope scope(isolate);
- DCHECK(args.length() == 5);
- CONVERT_ARG_HANDLE_CHECKED(Object, name, 0);
- CONVERT_ARG_HANDLE_CHECKED(Object, super_class, 1);
- CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, 2);
- CONVERT_SMI_ARG_CHECKED(start_position, 3);
- CONVERT_SMI_ARG_CHECKED(end_position, 4);
-
- if (super_class->IsNull()) {
- THROW_NEW_ERROR_RETURN_FAILURE(
- isolate, NewTypeError(MessageTemplate::kStrongExtendNull));
- }
-
- Handle<Object> result;
- ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
- isolate, result, DefineClass(isolate, name, super_class, constructor,
- start_position, end_position));
- return *result;
-}
-
-
RUNTIME_FUNCTION(Runtime_DefineClassMethod) {
HandleScope scope(isolate);
DCHECK(args.length() == 3);
Index: src/runtime/runtime.h
diff --git a/src/runtime/runtime.h b/src/runtime/runtime.h
index
4ae9b8846ad5054d42de92b5c9eed94e55ec43e2..d6a98c96a7752f3731eeee4737a084f1d55e0a6e
100644
--- a/src/runtime/runtime.h
+++ b/src/runtime/runtime.h
@@ -84,7 +84,6 @@ namespace internal {
F(ToMethod, 2, 1) \
F(HomeObjectSymbol, 0, 1) \
F(DefineClass, 5, 1) \
- F(DefineClassStrong, 5, 1) \
F(FinalizeClassDefinition, 2, 1) \
F(DefineClassMethod, 3, 1) \
F(ClassGetSourceCode, 1, 1) \
Index: test/mjsunit/strong/class-object-frozen.js
diff --git a/test/mjsunit/strong/class-object-frozen.js
b/test/mjsunit/strong/class-object-frozen.js
index
2c442c0d5168258986211dd297b7ac05907b459f..49426d8bb29fd20bb74d5adb39457bf129857f8a
100644
--- a/test/mjsunit/strong/class-object-frozen.js
+++ b/test/mjsunit/strong/class-object-frozen.js
@@ -79,20 +79,3 @@ testStrongClass(getClassExprStrong);
assertDoesNotThrow(function(){addProperty(parent)});
assertDoesNotThrow(function(){convertPropertyToData(parent)});
})();
-
-// Check strong classes don't freeze their children.
-(function() {
- let parent = getClassStrong();
-
- let classFunc = function() {
- class Foo extends parent {
- static get bar() { return 0 }
- get bar() { return 0 }
- }
- return Foo;
- }
-
- assertThrows(function(){addProperty(parent)}, TypeError);
- assertThrows(function(){convertPropertyToData(parent)}, TypeError);
- testWeakClass(classFunc);
-})();
Index: test/mjsunit/strong/class-weak-extend.js
diff --git a/test/mjsunit/strong/class-weak-extend.js
b/test/mjsunit/strong/class-weak-extend.js
new file mode 100644
index
0000000000000000000000000000000000000000..e4faf6f88506984e11387267397fed744c681400
--- /dev/null
+++ b/test/mjsunit/strong/class-weak-extend.js
@@ -0,0 +1,28 @@
+// Copyright 2015 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: --strong-mode --allow-natives-syntax
+
+function getStrongClass() {
+ "use strong";
+ return (class {});
+}
+
+function weakClass() {
+ "use strict";
+ class Weak extends getStrongClass() {}
+}
+
+function strongClass() {
+ "use strong";
+ class Strong extends getStrongClass() {}
+}
+
+assertThrows(weakClass, TypeError);
+%OptimizeFunctionOnNextCall(weakClass);
+assertThrows(weakClass, TypeError);
+
+assertDoesNotThrow(strongClass);
+%OptimizeFunctionOnNextCall(strongClass);
+assertDoesNotThrow(strongClass);
Index: test/mjsunit/strong/literals.js
diff --git a/test/mjsunit/strong/literals.js
b/test/mjsunit/strong/literals.js
index
28123c218ee1d7675f36164758378d7c25940c7c..347ea1ccacbd567296ab0952f110826df03032e1
100644
--- a/test/mjsunit/strong/literals.js
+++ b/test/mjsunit/strong/literals.js
@@ -285,24 +285,19 @@ let GeneratorPrototype = (function*(){}).__proto__;
class D extends C {};
class E extends Object {};
// class F extends null {};
- const S = (() => {'use strong'; return class {}})();
- class G extends S {};
assertWeakClass(C);
assertWeakClass(D);
assertWeakClass(E);
// assertWeakClass(F);
- assertWeakClass(G);
assertWeakClass(class {});
assertWeakClass(class extends Object {});
// assertWeakClass(class extends null {});
assertWeakClass(class extends C {});
- assertWeakClass(class extends S {});
assertWeakClass(class extends class {} {});
assertWeakClass(class C {});
assertWeakClass(class D extends Object {});
// assertWeakClass(class D extends null {});
assertWeakClass(class D extends C {});
- assertWeakClass(class D extends S {});
assertWeakClass(class D extends class {} {});
})();
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.