diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h index bf1399da87e..4c7e36a5fda 100644 --- a/runtime/include/dart_api.h +++ b/runtime/include/dart_api.h @@ -546,7 +546,7 @@ typedef struct { * for each part. */ -#define DART_FLAGS_CURRENT_VERSION (0x00000004) +#define DART_FLAGS_CURRENT_VERSION (0x00000005) typedef struct { int32_t version; @@ -560,6 +560,7 @@ typedef struct { bool obfuscate; Dart_QualifiedFunctionName* entry_points; bool reify_generic_functions; + bool strong; } Dart_IsolateFlags; /** diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h index 1af3cf041f4..4ca349f65ad 100644 --- a/runtime/vm/isolate.h +++ b/runtime/vm/isolate.h @@ -137,6 +137,7 @@ typedef FixedCache CatchEntryStateCache; V(NONPRODUCT, asserts, EnableAsserts, enable_asserts, FLAG_enable_asserts) \ V(NONPRODUCT, reify_generic_functions, ReifyGenericFunctions, \ reify_generic_functions, FLAG_reify_generic_functions) \ + V(NONPRODUCT, strong, Strong, strong, FLAG_strong) \ V(NONPRODUCT, error_on_bad_type, ErrorOnBadType, enable_error_on_bad_type, \ FLAG_error_on_bad_type) \ V(NONPRODUCT, error_on_bad_override, ErrorOnBadOverride, \ @@ -845,6 +846,7 @@ class Isolate : public BaseIsolate { V(ErrorOnBadType) \ V(ErrorOnBadOverride) \ V(ReifyGenericFunctions) \ + V(Strong) \ V(UseFieldGuards) \ V(UseOsr) \ V(Obfuscate) \ diff --git a/runtime/vm/kernel_isolate.cc b/runtime/vm/kernel_isolate.cc index 7a0846fe8f9..f33c9bc53a3 100644 --- a/runtime/vm/kernel_isolate.cc +++ b/runtime/vm/kernel_isolate.cc @@ -69,6 +69,7 @@ class RunKernelTask : public ThreadPool::Task { api_flags.enable_error_on_bad_type = false; api_flags.enable_error_on_bad_override = false; api_flags.reify_generic_functions = false; + api_flags.strong = false; #if !defined(DART_PRECOMPILER) api_flags.use_field_guards = true; api_flags.use_osr = true; diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc index 8faa7da2960..59706b5a5e2 100644 --- a/runtime/vm/object.cc +++ b/runtime/vm/object.cc @@ -3802,7 +3802,8 @@ bool Class::TypeTestNonRecursive(const Class& cls, // strong mode. // However, DynamicType is not more specific than any type. if (thsi.IsDynamicClass()) { - return !FLAG_strong && (test_kind == Class::kIsSubtypeOf); + return !Isolate::Current()->strong() && + (test_kind == Class::kIsSubtypeOf); } // Check for ObjectType. Any type that is not NullType or DynamicType // (already checked above), is more specific than ObjectType/VoidType. @@ -3834,7 +3835,8 @@ bool Class::TypeTestNonRecursive(const Class& cls, // Other type can't be more specific than this one because for that // it would have to have all dynamic type arguments which is checked // above. - return !FLAG_strong && (test_kind == Class::kIsSubtypeOf); + return !Isolate::Current()->strong() && + (test_kind == Class::kIsSubtypeOf); } return type_arguments.TypeTest(test_kind, other_type_arguments, from_index, num_type_params, bound_error, @@ -6336,7 +6338,7 @@ bool Function::HasCompatibleParametersWith(const Function& other, // HasCompatibleParametersWith is called at compile time to check for bad // overrides and can only detect some obviously wrong overrides, but it // should never give false negatives. - if (FLAG_strong) { + if (Isolate::Current()->strong()) { // Instantiating all type parameters to dynamic is not the right thing // to do in strong mode, because of contravariance of parameter types. // It is better to skip the test than to give a false negative. @@ -6349,7 +6351,7 @@ bool Function::HasCompatibleParametersWith(const Function& other, } Function& other_fun = Function::Handle(other.raw()); if (!other_fun.HasInstantiatedSignature(kCurrentClass)) { - if (FLAG_strong) { + if (Isolate::Current()->strong()) { // See comment above. return true; } @@ -6467,9 +6469,10 @@ bool Function::TestParameterType(TypeTestKind test_kind, Error* bound_error, TrailPtr bound_trail, Heap::Space space) const { + Isolate* isolate = Isolate::Current(); const AbstractType& other_param_type = AbstractType::Handle(other.ParameterTypeAt(other_parameter_position)); - if (!FLAG_strong && other_param_type.IsDynamicType()) { + if (!isolate->strong() && other_param_type.IsDynamicType()) { return true; } const AbstractType& param_type = @@ -6478,8 +6481,9 @@ bool Function::TestParameterType(TypeTestKind test_kind, return test_kind == kIsSubtypeOf; } if (test_kind == kIsSubtypeOf) { - if (!((!FLAG_strong && param_type.IsSubtypeOf(other_param_type, bound_error, - bound_trail, space)) || + if (!((!isolate->strong() && + param_type.IsSubtypeOf(other_param_type, bound_error, bound_trail, + space)) || other_param_type.IsSubtypeOf(param_type, bound_error, bound_trail, space))) { return false; @@ -6553,7 +6557,8 @@ bool Function::TypeTest(TypeTestKind test_kind, (num_opt_named_params < other_num_opt_named_params)) { return false; } - if (Isolate::Current()->reify_generic_functions()) { + Isolate* isolate = Isolate::Current(); + if (isolate->reify_generic_functions()) { // Check the type parameters and bounds of generic functions. if (!HasSameTypeParametersAndBounds(other)) { return false; @@ -6572,8 +6577,9 @@ bool Function::TypeTest(TypeTestKind test_kind, if (test_kind == kIsSubtypeOf) { if (!(res_type.IsSubtypeOf(other_res_type, bound_error, bound_trail, space) || - (!FLAG_strong && other_res_type.IsSubtypeOf(res_type, bound_error, - bound_trail, space)))) { + (!isolate->strong() && + other_res_type.IsSubtypeOf(res_type, bound_error, bound_trail, + space)))) { return false; } } else { diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc index 808d4e8fe41..6efdae0ea0e 100644 --- a/runtime/vm/parser.cc +++ b/runtime/vm/parser.cc @@ -7644,6 +7644,7 @@ void Parser::FinalizeFormalParameterTypes(const ParamList* params) { // with the formal parameter types and names. void Parser::AddFormalParamsToFunction(const ParamList* params, const Function& func) { + Isolate* isolate = Isolate::Current(); ASSERT((params != NULL) && (params->parameters != NULL)); ASSERT((params->num_optional_parameters > 0) == (params->has_optional_positional_parameters || @@ -7677,7 +7678,7 @@ void Parser::AddFormalParamsToFunction(const ParamList* params, } // In non-strong mode, the covariant keyword is ignored. In strong mode, // the parameter type is changed to Object. - if (FLAG_strong) { + if (isolate->strong()) { param_type = Type::ObjectType(); } } diff --git a/runtime/vm/service_isolate.cc b/runtime/vm/service_isolate.cc index e7eb1305418..5a09c881bbf 100644 --- a/runtime/vm/service_isolate.cc +++ b/runtime/vm/service_isolate.cc @@ -331,11 +331,12 @@ class RunServiceTask : public ThreadPool::Task { Dart_IsolateFlags api_flags; Isolate::FlagsInitialize(&api_flags); - if (FLAG_strong) { + if (api_flags.strong) { // TODO(dartbug.com/31203) currently we don't have a strong version of // vm service so disable type checking in the service completely. api_flags.enable_type_checks = false; api_flags.enable_asserts = false; + api_flags.strong = false; } isolate = reinterpret_cast(create_callback(