| Index: src/types.h
|
| diff --git a/src/types.h b/src/types.h
|
| index 5ca3a81452c2fa3a10b789f3ed71b07630d96a75..245cf76435325dc1fd4770c9b7de2d6382a9d276 100644
|
| --- a/src/types.h
|
| +++ b/src/types.h
|
| @@ -132,8 +132,8 @@ namespace internal {
|
| V(Representation, static_cast<int>(0xff800000)) \
|
| V(Semantic, static_cast<int>(0x007fffff))
|
|
|
| -#define REPRESENTATION(k) ((k) & kRepresentation)
|
| -#define SEMANTIC(k) ((k) & kSemantic)
|
| +#define REPRESENTATION(k) ((k) & BitsetType::kRepresentation)
|
| +#define SEMANTIC(k) ((k) & BitsetType::kSemantic)
|
|
|
| #define REPRESENTATION_BITSET_TYPE_LIST(V) \
|
| V(None, 0) \
|
| @@ -202,16 +202,13 @@ namespace internal {
|
| // template<class T> static Handle<T>::type cast(Handle<Type>::type);
|
| // static bool is_bitset(Type*);
|
| // static bool is_class(Type*);
|
| -// static bool is_constant(Type*);
|
| // static bool is_struct(Type*, int tag);
|
| // static int as_bitset(Type*);
|
| // static i::Handle<i::Map> as_class(Type*);
|
| -// static i::Handle<i::Object> as_constant(Type*);
|
| // static Handle<Struct>::type as_struct(Type*);
|
| // static Type* from_bitset(int bitset);
|
| // static Handle<Type>::type from_bitset(int bitset, Region*);
|
| -// static Handle<Type>::type from_class(i::Handle<Map>, int lub, Region*);
|
| -// static Handle<Type>::type from_constant(i::Handle<Object>, int, Region*);
|
| +// static Handle<Type>::type from_class(i::Handle<Map>, Region*);
|
| // static Handle<Type>::type from_struct(Handle<Struct>::type, int tag);
|
| // static Handle<Struct>::type struct_create(int tag, int length, Region*);
|
| // static void struct_shrink(Handle<Struct>::type, int length);
|
| @@ -219,7 +216,10 @@ namespace internal {
|
| // static int struct_length(Handle<Struct>::type);
|
| // static Handle<Type>::type struct_get(Handle<Struct>::type, int);
|
| // static void struct_set(Handle<Struct>::type, int, Handle<Type>::type);
|
| -// static int lub_bitset(Type*);
|
| +// template<class V>
|
| +// static i::Handle<V> struct_get_value(Handle<Struct>::type, int);
|
| +// template<class V>
|
| +// static void struct_set_value(Handle<Struct>::type, int, i::Handle<V>);
|
| // }
|
| template<class Config>
|
| class TypeImpl : public Config::Base {
|
| @@ -289,9 +289,7 @@ class TypeImpl : public Config::Base {
|
| return Of(*value, region);
|
| }
|
|
|
| - bool IsInhabited() {
|
| - return !this->IsBitset() || BitsetType::IsInhabited(this->AsBitset());
|
| - }
|
| + bool IsInhabited() { return BitsetType::IsInhabited(this->BitsetLub()); }
|
|
|
| bool Is(TypeImpl* that) { return this == that || this->SlowIs(that); }
|
| template<class TypeHandle>
|
| @@ -323,9 +321,16 @@ class TypeImpl : public Config::Base {
|
|
|
| bool NowStable();
|
|
|
| - bool IsClass() { return Config::is_class(this); }
|
| - bool IsConstant() { return Config::is_constant(this); }
|
| - bool IsArray() { return Config::is_struct(this, StructuralType::kArrayTag); }
|
| + bool IsClass() {
|
| + return Config::is_class(this)
|
| + || Config::is_struct(this, StructuralType::kClassTag);
|
| + }
|
| + bool IsConstant() {
|
| + return Config::is_struct(this, StructuralType::kConstantTag);
|
| + }
|
| + bool IsArray() {
|
| + return Config::is_struct(this, StructuralType::kArrayTag);
|
| + }
|
| bool IsFunction() {
|
| return Config::is_struct(this, StructuralType::kFunctionTag);
|
| }
|
| @@ -366,6 +371,7 @@ class TypeImpl : public Config::Base {
|
| static typename Config::template Handle<T>::type handle(T* type) {
|
| return Config::handle(type);
|
| }
|
| + TypeImpl* unhandle() { return this; }
|
|
|
| bool IsNone() { return this == None(); }
|
| bool IsAny() { return this == Any(); }
|
| @@ -380,14 +386,17 @@ class TypeImpl : public Config::Base {
|
|
|
| bool SlowIs(TypeImpl* that);
|
|
|
| - bool InUnion(UnionHandle unioned, int current_size);
|
| + TypeHandle Narrow(int bitset, Region* region);
|
| + int BoundBy(TypeImpl* that);
|
| + int IndexInUnion(int bound, UnionHandle unioned, int current_size);
|
| static int ExtendUnion(
|
| - UnionHandle unioned, TypeHandle t, int current_size);
|
| - static int ExtendIntersection(
|
| - UnionHandle unioned, TypeHandle t, TypeHandle other, int current_size);
|
| + UnionHandle unioned, int current_size, TypeHandle t,
|
| + TypeHandle other, bool is_intersect, Region* region);
|
| + static int NormalizeUnion(UnionHandle unioned, int current_size, int bitset);
|
|
|
| int BitsetGlb() { return BitsetType::Glb(this); }
|
| int BitsetLub() { return BitsetType::Lub(this); }
|
| + int InherentBitsetLub() { return BitsetType::InherentLub(this); }
|
| };
|
|
|
|
|
| @@ -405,7 +414,7 @@ class TypeImpl<Config>::BitsetType : public TypeImpl<Config> {
|
|
|
| int Bitset() { return Config::as_bitset(this); }
|
|
|
| - static BitsetType* New(int bitset) {
|
| + static TypeImpl* New(int bitset) {
|
| return static_cast<BitsetType*>(Config::from_bitset(bitset));
|
| }
|
| static TypeHandle New(int bitset, Region* region) {
|
| @@ -420,6 +429,7 @@ class TypeImpl<Config>::BitsetType : public TypeImpl<Config> {
|
| static int Lub(TypeImpl* type); // least upper bound that's a bitset
|
| static int Lub(i::Object* value);
|
| static int Lub(i::Map* map);
|
| + static int InherentLub(TypeImpl* type);
|
|
|
| static const char* Name(int bitset);
|
| static void BitsetTypePrint(FILE* out, int bitset);
|
| @@ -447,29 +457,88 @@ class TypeImpl<Config>::StructuralType : public TypeImpl<Config> {
|
| return Config::struct_length(Config::as_struct(this));
|
| }
|
| TypeHandle Get(int i) {
|
| + ASSERT(0 <= i && i < this->Length());
|
| return Config::struct_get(Config::as_struct(this), i);
|
| }
|
| void Set(int i, TypeHandle type) {
|
| + ASSERT(0 <= i && i < this->Length());
|
| Config::struct_set(Config::as_struct(this), i, type);
|
| }
|
| void Shrink(int length) {
|
| + ASSERT(2 <= length && length <= this->Length());
|
| Config::struct_shrink(Config::as_struct(this), length);
|
| }
|
| + template<class V> i::Handle<V> GetValue(int i) {
|
| + ASSERT(0 <= i && i < this->Length());
|
| + return Config::template struct_get_value<V>(Config::as_struct(this), i);
|
| + }
|
| + template<class V> void SetValue(int i, i::Handle<V> x) {
|
| + ASSERT(0 <= i && i < this->Length());
|
| + Config::struct_set_value(Config::as_struct(this), i, x);
|
| + }
|
|
|
| static TypeHandle New(Tag tag, int length, Region* region) {
|
| + ASSERT(1 <= length);
|
| return Config::from_struct(Config::struct_create(tag, length, region));
|
| }
|
| };
|
|
|
|
|
| +// Internal
|
| +// A union is a structured type with the following invariants:
|
| +// - its length is at least 2
|
| +// - at most one field is a bitset, and it must go into index 0
|
| +// - no field is a union
|
| +// - no field is a subtype of any other field
|
| template<class Config>
|
| -class TypeImpl<Config>::ClassType : public TypeImpl<Config> {
|
| +class TypeImpl<Config>::UnionType : public StructuralType {
|
| public:
|
| - i::Handle<i::Map> Map() { return Config::as_class(this); }
|
| + static UnionHandle New(int length, Region* region) {
|
| + return Config::template cast<UnionType>(
|
| + StructuralType::New(StructuralType::kUnionTag, length, region));
|
| + }
|
| +
|
| + static UnionType* cast(TypeImpl* type) {
|
| + ASSERT(type->IsUnion());
|
| + return static_cast<UnionType*>(type);
|
| + }
|
| +
|
| + bool Wellformed();
|
| +};
|
| +
|
| +
|
| +template<class Config>
|
| +class TypeImpl<Config>::ClassType : public StructuralType {
|
| + public:
|
| + TypeHandle Bound(Region* region) {
|
| + return Config::is_class(this)
|
| + ? BitsetType::New(BitsetType::Lub(*Config::as_class(this)), region)
|
| + : this->Get(0);
|
| + }
|
| + i::Handle<i::Map> Map() {
|
| + return Config::is_class(this)
|
| + ? Config::as_class(this)
|
| + : this->template GetValue<i::Map>(1);
|
| + }
|
| +
|
| + static ClassHandle New(
|
| + i::Handle<i::Map> map, TypeHandle bound, Region* region) {
|
| + ClassHandle type = Config::template cast<ClassType>(
|
| + StructuralType::New(StructuralType::kClassTag, 2, region));
|
| + type->Set(0, bound);
|
| + type->SetValue(1, map);
|
| + return type;
|
| + }
|
|
|
| static ClassHandle New(i::Handle<i::Map> map, Region* region) {
|
| - return Config::template cast<ClassType>(
|
| - Config::from_class(map, BitsetType::Lub(*map), region));
|
| + ClassHandle type =
|
| + Config::template cast<ClassType>(Config::from_class(map, region));
|
| + if (type->IsClass()) {
|
| + return type;
|
| + } else {
|
| + TypeHandle bound = BitsetType::New(BitsetType::Lub(*map), region);
|
| + return New(map, bound, region);
|
| + }
|
| }
|
|
|
| static ClassType* cast(TypeImpl* type) {
|
| @@ -480,13 +549,23 @@ class TypeImpl<Config>::ClassType : public TypeImpl<Config> {
|
|
|
|
|
| template<class Config>
|
| -class TypeImpl<Config>::ConstantType : public TypeImpl<Config> {
|
| +class TypeImpl<Config>::ConstantType : public StructuralType {
|
| public:
|
| - i::Handle<i::Object> Value() { return Config::as_constant(this); }
|
| + TypeHandle Bound() { return this->Get(0); }
|
| + i::Handle<i::Object> Value() { return this->template GetValue<i::Object>(1); }
|
| +
|
| + static ConstantHandle New(
|
| + i::Handle<i::Object> value, TypeHandle bound, Region* region) {
|
| + ConstantHandle type = Config::template cast<ConstantType>(
|
| + StructuralType::New(StructuralType::kConstantTag, 2, region));
|
| + type->Set(0, bound);
|
| + type->SetValue(1, value);
|
| + return type;
|
| + }
|
|
|
| static ConstantHandle New(i::Handle<i::Object> value, Region* region) {
|
| - return Config::template cast<ConstantType>(
|
| - Config::from_constant(value, BitsetType::Lub(*value), region));
|
| + TypeHandle bound = BitsetType::New(BitsetType::Lub(*value), region);
|
| + return New(value, bound, region);
|
| }
|
|
|
| static ConstantType* cast(TypeImpl* type) {
|
| @@ -496,38 +575,26 @@ class TypeImpl<Config>::ConstantType : public TypeImpl<Config> {
|
| };
|
|
|
|
|
| -// Internal
|
| -// A union is a structured type with the following invariants:
|
| -// - its length is at least 2
|
| -// - at most one field is a bitset, and it must go into index 0
|
| -// - no field is a union
|
| -template<class Config>
|
| -class TypeImpl<Config>::UnionType : public StructuralType {
|
| - public:
|
| - static UnionHandle New(int length, Region* region) {
|
| - return Config::template cast<UnionType>(
|
| - StructuralType::New(StructuralType::kUnionTag, length, region));
|
| - }
|
| -
|
| - static UnionType* cast(TypeImpl* type) {
|
| - ASSERT(type->IsUnion());
|
| - return static_cast<UnionType*>(type);
|
| - }
|
| -};
|
| -
|
| -
|
| template<class Config>
|
| class TypeImpl<Config>::ArrayType : public StructuralType {
|
| public:
|
| - TypeHandle Element() { return this->Get(0); }
|
| + TypeHandle Bound() { return this->Get(0); }
|
| + TypeHandle Element() { return this->Get(1); }
|
|
|
| - static ArrayHandle New(TypeHandle element, Region* region) {
|
| + static ArrayHandle New(TypeHandle element, TypeHandle bound, Region* region) {
|
| + ASSERT(SEMANTIC(bound->AsBitset()) == SEMANTIC(BitsetType::kArray));
|
| ArrayHandle type = Config::template cast<ArrayType>(
|
| - StructuralType::New(StructuralType::kArrayTag, 1, region));
|
| - type->Set(0, element);
|
| + StructuralType::New(StructuralType::kArrayTag, 2, region));
|
| + type->Set(0, bound);
|
| + type->Set(1, element);
|
| return type;
|
| }
|
|
|
| + static ArrayHandle New(TypeHandle element, Region* region) {
|
| + TypeHandle bound = BitsetType::New(BitsetType::kArray, region);
|
| + return New(element, bound, region);
|
| + }
|
| +
|
| static ArrayType* cast(TypeImpl* type) {
|
| ASSERT(type->IsArray());
|
| return static_cast<ArrayType*>(type);
|
| @@ -538,22 +605,32 @@ class TypeImpl<Config>::ArrayType : public StructuralType {
|
| template<class Config>
|
| class TypeImpl<Config>::FunctionType : public StructuralType {
|
| public:
|
| - int Arity() { return this->Length() - 2; }
|
| - TypeHandle Result() { return this->Get(0); }
|
| - TypeHandle Receiver() { return this->Get(1); }
|
| - TypeHandle Parameter(int i) { return this->Get(2 + i); }
|
| + int Arity() { return this->Length() - 3; }
|
| + TypeHandle Bound() { return this->Get(0); }
|
| + TypeHandle Result() { return this->Get(1); }
|
| + TypeHandle Receiver() { return this->Get(2); }
|
| + TypeHandle Parameter(int i) { return this->Get(3 + i); }
|
|
|
| - void InitParameter(int i, TypeHandle type) { this->Set(2 + i, type); }
|
| + void InitParameter(int i, TypeHandle type) { this->Set(3 + i, type); }
|
|
|
| static FunctionHandle New(
|
| - TypeHandle result, TypeHandle receiver, int arity, Region* region) {
|
| + TypeHandle result, TypeHandle receiver, TypeHandle bound,
|
| + int arity, Region* region) {
|
| + ASSERT(SEMANTIC(bound->AsBitset()) == SEMANTIC(BitsetType::kFunction));
|
| FunctionHandle type = Config::template cast<FunctionType>(
|
| - StructuralType::New(StructuralType::kFunctionTag, 2 + arity, region));
|
| - type->Set(0, result);
|
| - type->Set(1, receiver);
|
| + StructuralType::New(StructuralType::kFunctionTag, 3 + arity, region));
|
| + type->Set(0, bound);
|
| + type->Set(1, result);
|
| + type->Set(2, receiver);
|
| return type;
|
| }
|
|
|
| + static FunctionHandle New(
|
| + TypeHandle result, TypeHandle receiver, int arity, Region* region) {
|
| + TypeHandle bound = BitsetType::New(BitsetType::kFunction, region);
|
| + return New(result, receiver, bound, arity, region);
|
| + }
|
| +
|
| static FunctionType* cast(TypeImpl* type) {
|
| ASSERT(type->IsFunction());
|
| return static_cast<FunctionType*>(type);
|
| @@ -598,29 +675,27 @@ struct ZoneTypeConfig {
|
|
|
| static inline bool is_bitset(Type* type);
|
| static inline bool is_class(Type* type);
|
| - static inline bool is_constant(Type* type);
|
| static inline bool is_struct(Type* type, int tag);
|
|
|
| static inline int as_bitset(Type* type);
|
| - static inline Struct* as_struct(Type* type);
|
| static inline i::Handle<i::Map> as_class(Type* type);
|
| - static inline i::Handle<i::Object> as_constant(Type* type);
|
| + static inline Struct* as_struct(Type* type);
|
|
|
| static inline Type* from_bitset(int bitset);
|
| static inline Type* from_bitset(int bitset, Zone* zone);
|
| + static inline Type* from_class(i::Handle<i::Map> map, Zone* zone);
|
| static inline Type* from_struct(Struct* structured);
|
| - static inline Type* from_class(i::Handle<i::Map> map, int lub, Zone* zone);
|
| - static inline Type* from_constant(
|
| - i::Handle<i::Object> value, int lub, Zone* zone);
|
|
|
| static inline Struct* struct_create(int tag, int length, Zone* zone);
|
| - static inline void struct_shrink(Struct* structured, int length);
|
| - static inline int struct_tag(Struct* structured);
|
| - static inline int struct_length(Struct* structured);
|
| - static inline Type* struct_get(Struct* structured, int i);
|
| - static inline void struct_set(Struct* structured, int i, Type* type);
|
| -
|
| - static inline int lub_bitset(Type* type);
|
| + static inline void struct_shrink(Struct* structure, int length);
|
| + static inline int struct_tag(Struct* structure);
|
| + static inline int struct_length(Struct* structure);
|
| + static inline Type* struct_get(Struct* structure, int i);
|
| + static inline void struct_set(Struct* structure, int i, Type* type);
|
| + template<class V>
|
| + static inline i::Handle<V> struct_get_value(Struct* structure, int i);
|
| + template<class V> static inline void struct_set_value(
|
| + Struct* structure, int i, i::Handle<V> x);
|
| };
|
|
|
| typedef TypeImpl<ZoneTypeConfig> Type;
|
| @@ -640,32 +715,32 @@ struct HeapTypeConfig {
|
|
|
| static inline bool is_bitset(Type* type);
|
| static inline bool is_class(Type* type);
|
| - static inline bool is_constant(Type* type);
|
| static inline bool is_struct(Type* type, int tag);
|
|
|
| static inline int as_bitset(Type* type);
|
| static inline i::Handle<i::Map> as_class(Type* type);
|
| - static inline i::Handle<i::Object> as_constant(Type* type);
|
| static inline i::Handle<Struct> as_struct(Type* type);
|
|
|
| static inline Type* from_bitset(int bitset);
|
| static inline i::Handle<Type> from_bitset(int bitset, Isolate* isolate);
|
| static inline i::Handle<Type> from_class(
|
| - i::Handle<i::Map> map, int lub, Isolate* isolate);
|
| - static inline i::Handle<Type> from_constant(
|
| - i::Handle<i::Object> value, int lub, Isolate* isolate);
|
| - static inline i::Handle<Type> from_struct(i::Handle<Struct> structured);
|
| + i::Handle<i::Map> map, Isolate* isolate);
|
| + static inline i::Handle<Type> from_struct(i::Handle<Struct> structure);
|
|
|
| static inline i::Handle<Struct> struct_create(
|
| int tag, int length, Isolate* isolate);
|
| - static inline void struct_shrink(i::Handle<Struct> structured, int length);
|
| - static inline int struct_tag(i::Handle<Struct> structured);
|
| - static inline int struct_length(i::Handle<Struct> structured);
|
| - static inline i::Handle<Type> struct_get(i::Handle<Struct> structured, int i);
|
| + static inline void struct_shrink(i::Handle<Struct> structure, int length);
|
| + static inline int struct_tag(i::Handle<Struct> structure);
|
| + static inline int struct_length(i::Handle<Struct> structure);
|
| + static inline i::Handle<Type> struct_get(i::Handle<Struct> structure, int i);
|
| static inline void struct_set(
|
| - i::Handle<Struct> structured, int i, i::Handle<Type> type);
|
| -
|
| - static inline int lub_bitset(Type* type);
|
| + i::Handle<Struct> structure, int i, i::Handle<Type> type);
|
| + template<class V>
|
| + static inline i::Handle<V> struct_get_value(
|
| + i::Handle<Struct> structure, int i);
|
| + template<class V>
|
| + static inline void struct_set_value(
|
| + i::Handle<Struct> structure, int i, i::Handle<V> x);
|
| };
|
|
|
| typedef TypeImpl<HeapTypeConfig> HeapType;
|
|
|