| Index: runtime/vm/intermediate_language.cc
|
| ===================================================================
|
| --- runtime/vm/intermediate_language.cc (revision 7707)
|
| +++ runtime/vm/intermediate_language.cc (working copy)
|
| @@ -288,4 +288,251 @@
|
| }
|
|
|
|
|
| +// ==== Support for propagating static type.
|
| +RawAbstractType* ConstantVal::StaticType() const {
|
| + if (value().IsInstance()) {
|
| + Instance& instance = Instance::Handle();
|
| + instance ^= value().raw();
|
| + return instance.GetType();
|
| + } else {
|
| + UNREACHABLE();
|
| + return AbstractType::null();
|
| + }
|
| +}
|
| +
|
| +
|
| +RawAbstractType* UseVal::StaticType() const {
|
| + return definition()->StaticType();
|
| +}
|
| +
|
| +
|
| +RawAbstractType* AssertAssignableComp::StaticType() const {
|
| + return dst_type().raw();
|
| +}
|
| +
|
| +
|
| +RawAbstractType* AssertBooleanComp::StaticType() const {
|
| + return Type::BoolInterface();
|
| +}
|
| +
|
| +
|
| +RawAbstractType* CurrentContextComp::StaticType() const {
|
| + UNREACHABLE();
|
| + return AbstractType::null();
|
| +}
|
| +
|
| +
|
| +RawAbstractType* StoreContextComp::StaticType() const {
|
| + UNREACHABLE();
|
| + return AbstractType::null();
|
| +}
|
| +
|
| +
|
| +RawAbstractType* ClosureCallComp::StaticType() const {
|
| + // The closure is the first argument to the call.
|
| + const AbstractType& function_type =
|
| + AbstractType::Handle(ArgumentAt(0)->StaticType());
|
| + if (function_type.IsDynamicType() || function_type.IsFunctionInterface()) {
|
| + // The function type is not statically known or simply Function.
|
| + return Type::DynamicType();
|
| + }
|
| + const Class& signature_class = Class::Handle(function_type.type_class());
|
| + ASSERT(signature_class.IsSignatureClass());
|
| + const Function& signature_function =
|
| + Function::Handle(signature_class.signature_function());
|
| + // TODO(regis): The result type may be generic.
|
| + return signature_function.result_type();
|
| +}
|
| +
|
| +
|
| +RawAbstractType* InstanceCallComp::StaticType() const {
|
| + return Type::DynamicType();
|
| +}
|
| +
|
| +
|
| +RawAbstractType* StaticCallComp::StaticType() const {
|
| + return function().result_type();
|
| +}
|
| +
|
| +
|
| +RawAbstractType* LoadLocalComp::StaticType() const {
|
| + return local().type().raw();
|
| +}
|
| +
|
| +
|
| +RawAbstractType* StoreLocalComp::StaticType() const {
|
| + const AbstractType& assigned_value_type =
|
| + AbstractType::Handle(value()->StaticType());
|
| + if (assigned_value_type.IsDynamicType()) {
|
| + // Static type of assigned value is unknown, return static type of local.
|
| + return local().type().raw();
|
| + }
|
| + return assigned_value_type.raw();
|
| +}
|
| +
|
| +
|
| +RawAbstractType* StrictCompareComp::StaticType() const {
|
| + return Type::BoolInterface();
|
| +}
|
| +
|
| +
|
| +RawAbstractType* EqualityCompareComp::StaticType() const {
|
| + return Type::BoolInterface();
|
| +}
|
| +
|
| +
|
| +RawAbstractType* NativeCallComp::StaticType() const {
|
| + // The result type of the native function is identical to the result type of
|
| + // the enclosing native Dart function.
|
| + // TODO(regis): Can we trust it or should we check anyway? Check for now.
|
| + return Type::DynamicType();
|
| +}
|
| +
|
| +
|
| +RawAbstractType* StoreIndexedComp::StaticType() const {
|
| + return value()->StaticType();
|
| +}
|
| +
|
| +
|
| +RawAbstractType* InstanceSetterComp::StaticType() const {
|
| + // TODO(regis): Would it be correct to return value()->StaticType()?
|
| + return Type::DynamicType();
|
| +}
|
| +
|
| +
|
| +RawAbstractType* StaticSetterComp::StaticType() const {
|
| + // TODO(regis): Would it be correct/better to return value()->StaticType()?
|
| + return setter_function().result_type();
|
| +}
|
| +
|
| +
|
| +RawAbstractType* LoadInstanceFieldComp::StaticType() const {
|
| + return field().type();
|
| +}
|
| +
|
| +
|
| +RawAbstractType* StoreInstanceFieldComp::StaticType() const {
|
| + const AbstractType& assigned_value_type =
|
| + AbstractType::Handle(value()->StaticType());
|
| + if (assigned_value_type.IsDynamicType()) {
|
| + // Static type of assigned value is unknown, return static type of field.
|
| + return field().type();
|
| + }
|
| + return assigned_value_type.raw();
|
| +}
|
| +
|
| +
|
| +RawAbstractType* LoadStaticFieldComp::StaticType() const {
|
| + return field().type();
|
| +}
|
| +
|
| +
|
| +RawAbstractType* StoreStaticFieldComp::StaticType() const {
|
| + const AbstractType& assigned_value_type =
|
| + AbstractType::Handle(value()->StaticType());
|
| + if (assigned_value_type.IsDynamicType()) {
|
| + // Static type of assigned value is unknown, return static type of field.
|
| + return field().type();
|
| + }
|
| + return assigned_value_type.raw();
|
| +}
|
| +
|
| +
|
| +RawAbstractType* BooleanNegateComp::StaticType() const {
|
| + return Type::BoolInterface();
|
| +}
|
| +
|
| +
|
| +RawAbstractType* InstanceOfComp::StaticType() const {
|
| + return Type::BoolInterface();
|
| +}
|
| +
|
| +
|
| +RawAbstractType* CreateArrayComp::StaticType() const {
|
| + UNREACHABLE();
|
| + return AbstractType::null();
|
| +}
|
| +
|
| +
|
| +RawAbstractType* CreateClosureComp::StaticType() const {
|
| + const Function& fun = function();
|
| + const Class& signature_class = Class::Handle(fun.signature_class());
|
| + // TODO(regis): Can we take (constant) type_arguments() into consideration?
|
| + // For now, we return Dynamic (no type test elimination) if the signature
|
| + // class is parameterized, or a non-parameterized finalized type otherwise.
|
| + if (signature_class.HasTypeArguments()) {
|
| + return Type::DynamicType();
|
| + }
|
| + // Make sure we use the canonical signature class.
|
| + const Type& type = Type::Handle(signature_class.SignatureType());
|
| + const Class& canonical_signature_class = Class::Handle(type.type_class());
|
| + return Type::NewNonParameterizedType(canonical_signature_class);
|
| +}
|
| +
|
| +
|
| +RawAbstractType* AllocateObjectComp::StaticType() const {
|
| + UNREACHABLE();
|
| + return AbstractType::null();
|
| +}
|
| +
|
| +
|
| +RawAbstractType* AllocateObjectWithBoundsCheckComp::StaticType() const {
|
| + UNREACHABLE();
|
| + return AbstractType::null();
|
| +}
|
| +
|
| +
|
| +RawAbstractType* NativeLoadFieldComp::StaticType() const {
|
| + ASSERT(!type().IsNull());
|
| + return type().raw();
|
| +}
|
| +
|
| +
|
| +RawAbstractType* NativeStoreFieldComp::StaticType() const {
|
| + return value()->StaticType();
|
| +}
|
| +
|
| +
|
| +RawAbstractType* InstantiateTypeArgumentsComp::StaticType() const {
|
| + UNREACHABLE();
|
| + return AbstractType::null();
|
| +}
|
| +
|
| +
|
| +RawAbstractType* ExtractConstructorTypeArgumentsComp::StaticType() const {
|
| + UNREACHABLE();
|
| + return AbstractType::null();
|
| +}
|
| +
|
| +
|
| +RawAbstractType* ExtractConstructorInstantiatorComp::StaticType() const {
|
| + UNREACHABLE();
|
| + return AbstractType::null();
|
| +}
|
| +
|
| +
|
| +RawAbstractType* AllocateContextComp::StaticType() const {
|
| + UNREACHABLE();
|
| + return AbstractType::null();
|
| +}
|
| +
|
| +
|
| +RawAbstractType* ChainContextComp::StaticType() const {
|
| + UNREACHABLE();
|
| + return AbstractType::null();
|
| +}
|
| +
|
| +
|
| +RawAbstractType* CloneContextComp::StaticType() const {
|
| + UNREACHABLE();
|
| + return AbstractType::null();
|
| +}
|
| +
|
| +
|
| +RawAbstractType* CatchEntryComp::StaticType() const {
|
| + UNREACHABLE();
|
| + return AbstractType::null();
|
| +}
|
| +
|
| +
|
| } // namespace dart
|
|
|