| Index: src/types.h
|
| diff --git a/src/types.h b/src/types.h
|
| index 5ca3a81452c2fa3a10b789f3ed71b07630d96a75..1fdfdae5bfa662f15ef2cef1b1e04857c26ef79b 100644
|
| --- a/src/types.h
|
| +++ b/src/types.h
|
| @@ -45,10 +45,14 @@ namespace internal {
|
| // Constant(x) < T iff instance_type(map(x)) < T
|
| // Array(T) < Array
|
| // Function(R, S, T0, T1, ...) < Function
|
| +// Context(T) < Internal
|
| //
|
| -// Both structural Array and Function types are invariant in all parameters.
|
| -// Relaxing this would make Union and Intersect operations more involved.
|
| -// Note that Constant(x) < Class(map(x)) does _not_ hold, since x's map can
|
| +// Both structural Array and Function types are invariant in all parameters;
|
| +// relaxing this would make Union and Intersect operations more involved.
|
| +// There is no subtyping relation between Array, Function, or Context types
|
| +// and respective Constant types, since these types cannot be reconstructed
|
| +// for arbitrary heap values.
|
| +// Note also that Constant(x) < Class(map(x)) does _not_ hold, since x's map can
|
| // change! (Its instance type cannot, however.)
|
| // TODO(rossberg): the latter is not currently true for proxies, because of fix,
|
| // but will hold once we implement direct proxies.
|
| @@ -129,14 +133,15 @@ namespace internal {
|
|
|
|
|
| #define MASK_BITSET_TYPE_LIST(V) \
|
| - V(Representation, static_cast<int>(0xff800000)) \
|
| - V(Semantic, static_cast<int>(0x007fffff))
|
| + V(Representation, static_cast<int>(0xffc00000)) \
|
| + V(Semantic, static_cast<int>(0x003fffff))
|
|
|
| -#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) \
|
| + V(UntaggedInt1, 1 << 22 | kSemantic) \
|
| V(UntaggedInt8, 1 << 23 | kSemantic) \
|
| V(UntaggedInt16, 1 << 24 | kSemantic) \
|
| V(UntaggedInt32, 1 << 25 | kSemantic) \
|
| @@ -146,44 +151,54 @@ namespace internal {
|
| V(TaggedInt, 1 << 29 | kSemantic) \
|
| V(TaggedPtr, -1 << 30 | kSemantic) /* MSB has to be sign-extended */ \
|
| \
|
| - V(UntaggedInt, kUntaggedInt8 | kUntaggedInt16 | kUntaggedInt32) \
|
| - V(UntaggedFloat, kUntaggedFloat32 | kUntaggedFloat64) \
|
| - V(UntaggedNumber, kUntaggedInt | kUntaggedFloat) \
|
| - V(Untagged, kUntaggedNumber | kUntaggedPtr) \
|
| + V(UntaggedInt, kUntaggedInt1 | kUntaggedInt8 | \
|
| + kUntaggedInt16 | kUntaggedInt32) \
|
| + V(UntaggedFloat, kUntaggedFloat32 | kUntaggedFloat64) \
|
| + V(UntaggedNumber, kUntaggedInt | kUntaggedFloat) \
|
| + V(Untagged, kUntaggedNumber | kUntaggedPtr) \
|
| V(Tagged, kTaggedInt | kTaggedPtr)
|
|
|
| #define SEMANTIC_BITSET_TYPE_LIST(V) \
|
| V(Null, 1 << 0 | REPRESENTATION(kTaggedPtr)) \
|
| V(Undefined, 1 << 1 | REPRESENTATION(kTaggedPtr)) \
|
| V(Boolean, 1 << 2 | REPRESENTATION(kTaggedPtr)) \
|
| - V(SignedSmall, 1 << 3 | REPRESENTATION(kTagged | kUntaggedNumber)) \
|
| - V(OtherSigned32, 1 << 4 | REPRESENTATION(kTagged | kUntaggedNumber)) \
|
| - V(Unsigned32, 1 << 5 | REPRESENTATION(kTagged | kUntaggedNumber)) \
|
| - V(Float, 1 << 6 | REPRESENTATION(kTagged | kUntaggedNumber)) \
|
| - V(Symbol, 1 << 7 | REPRESENTATION(kTaggedPtr)) \
|
| - V(InternalizedString, 1 << 8 | REPRESENTATION(kTaggedPtr)) \
|
| - V(OtherString, 1 << 9 | REPRESENTATION(kTaggedPtr)) \
|
| - V(Undetectable, 1 << 10 | REPRESENTATION(kTaggedPtr)) \
|
| - V(Array, 1 << 11 | REPRESENTATION(kTaggedPtr)) \
|
| - V(Function, 1 << 12 | REPRESENTATION(kTaggedPtr)) \
|
| - V(RegExp, 1 << 13 | REPRESENTATION(kTaggedPtr)) \
|
| - V(OtherObject, 1 << 14 | REPRESENTATION(kTaggedPtr)) \
|
| - V(Proxy, 1 << 15 | REPRESENTATION(kTaggedPtr)) \
|
| - V(Internal, 1 << 16 | REPRESENTATION(kTagged | kUntagged)) \
|
| + V(UnsignedSmall, 1 << 3 | REPRESENTATION(kTagged | kUntaggedNumber)) \
|
| + V(OtherSignedSmall, 1 << 4 | REPRESENTATION(kTagged | kUntaggedNumber)) \
|
| + V(OtherUnsigned31, 1 << 5 | REPRESENTATION(kTagged | kUntaggedNumber)) \
|
| + V(OtherUnsigned32, 1 << 6 | REPRESENTATION(kTagged | kUntaggedNumber)) \
|
| + V(OtherSigned32, 1 << 7 | REPRESENTATION(kTagged | kUntaggedNumber)) \
|
| + V(MinusZero, 1 << 8 | REPRESENTATION(kTagged | kUntaggedNumber)) \
|
| + V(NaN, 1 << 9 | REPRESENTATION(kTagged | kUntaggedNumber)) \
|
| + V(OtherNumber, 1 << 10 | REPRESENTATION(kTagged | kUntaggedNumber)) \
|
| + V(Symbol, 1 << 11 | REPRESENTATION(kTaggedPtr)) \
|
| + V(InternalizedString, 1 << 12 | REPRESENTATION(kTaggedPtr)) \
|
| + V(OtherString, 1 << 13 | REPRESENTATION(kTaggedPtr)) \
|
| + V(Undetectable, 1 << 14 | REPRESENTATION(kTaggedPtr)) \
|
| + V(Array, 1 << 15 | REPRESENTATION(kTaggedPtr)) \
|
| + V(Buffer, 1 << 16 | REPRESENTATION(kTaggedPtr)) \
|
| + V(Function, 1 << 17 | REPRESENTATION(kTaggedPtr)) \
|
| + V(RegExp, 1 << 18 | REPRESENTATION(kTaggedPtr)) \
|
| + V(OtherObject, 1 << 19 | REPRESENTATION(kTaggedPtr)) \
|
| + V(Proxy, 1 << 20 | REPRESENTATION(kTaggedPtr)) \
|
| + V(Internal, 1 << 21 | REPRESENTATION(kTagged | kUntagged)) \
|
| \
|
| - V(Signed32, kSignedSmall | kOtherSigned32) \
|
| - V(Number, kSigned32 | kUnsigned32 | kFloat) \
|
| - V(String, kInternalizedString | kOtherString) \
|
| - V(UniqueName, kSymbol | kInternalizedString) \
|
| - V(Name, kSymbol | kString) \
|
| - V(NumberOrString, kNumber | kString) \
|
| - V(DetectableObject, kArray | kFunction | kRegExp | kOtherObject) \
|
| - V(DetectableReceiver, kDetectableObject | kProxy) \
|
| - V(Detectable, kDetectableReceiver | kNumber | kName) \
|
| - V(Object, kDetectableObject | kUndetectable) \
|
| - V(Receiver, kObject | kProxy) \
|
| - V(NonNumber, kBoolean | kName | kNull | kReceiver | \
|
| - kUndefined | kInternal) \
|
| + V(SignedSmall, kUnsignedSmall | kOtherSignedSmall) \
|
| + V(Signed32, kSignedSmall | kOtherUnsigned31 | kOtherSigned32) \
|
| + V(Unsigned32, kUnsignedSmall | kOtherUnsigned31 | kOtherUnsigned32) \
|
| + V(Integral32, kSigned32 | kUnsigned32) \
|
| + V(Number, kIntegral32 | kMinusZero | kNaN | kOtherNumber) \
|
| + V(String, kInternalizedString | kOtherString) \
|
| + V(UniqueName, kSymbol | kInternalizedString) \
|
| + V(Name, kSymbol | kString) \
|
| + V(NumberOrString, kNumber | kString) \
|
| + V(Primitive, kNumber | kName | kBoolean | kNull | kUndefined) \
|
| + V(DetectableObject, kArray | kFunction | kRegExp | kOtherObject) \
|
| + V(DetectableReceiver, kDetectableObject | kProxy) \
|
| + V(Detectable, kDetectableReceiver | kNumber | kName) \
|
| + V(Object, kDetectableObject | kUndetectable) \
|
| + V(Receiver, kObject | kProxy) \
|
| + V(NonNumber, kBoolean | kName | kNull | kReceiver | \
|
| + kUndefined | kInternal) \
|
| V(Any, -1)
|
|
|
| #define BITSET_TYPE_LIST(V) \
|
| @@ -230,12 +245,14 @@ class TypeImpl : public Config::Base {
|
|
|
| class ClassType;
|
| class ConstantType;
|
| + class ContextType;
|
| class ArrayType;
|
| class FunctionType;
|
|
|
| typedef typename Config::template Handle<TypeImpl>::type TypeHandle;
|
| typedef typename Config::template Handle<ClassType>::type ClassHandle;
|
| typedef typename Config::template Handle<ConstantType>::type ConstantHandle;
|
| + typedef typename Config::template Handle<ContextType>::type ContextHandle;
|
| typedef typename Config::template Handle<ArrayType>::type ArrayHandle;
|
| typedef typename Config::template Handle<FunctionType>::type FunctionHandle;
|
| typedef typename Config::template Handle<UnionType>::type UnionHandle;
|
| @@ -255,6 +272,9 @@ class TypeImpl : public Config::Base {
|
| static TypeHandle Constant(i::Handle<i::Object> value, Region* region) {
|
| return ConstantType::New(value, region);
|
| }
|
| + static TypeHandle Context(TypeHandle outer, Region* region) {
|
| + return ContextType::New(outer, region);
|
| + }
|
| static TypeHandle Array(TypeHandle element, Region* region) {
|
| return ArrayType::New(element, region);
|
| }
|
| @@ -278,10 +298,22 @@ class TypeImpl : public Config::Base {
|
| function->InitParameter(1, param1);
|
| return function;
|
| }
|
| + static TypeHandle Function(
|
| + TypeHandle result, TypeHandle param0, TypeHandle param1,
|
| + TypeHandle param2, Region* region) {
|
| + FunctionHandle function = Function(result, Any(region), 3, region);
|
| + function->InitParameter(0, param0);
|
| + function->InitParameter(1, param1);
|
| + function->InitParameter(2, param2);
|
| + return function;
|
| + }
|
|
|
| static TypeHandle Union(TypeHandle type1, TypeHandle type2, Region* reg);
|
| static TypeHandle Intersect(TypeHandle type1, TypeHandle type2, Region* reg);
|
|
|
| + static TypeHandle Of(double value, Region* region) {
|
| + return Config::from_bitset(BitsetType::Lub(value), region);
|
| + }
|
| static TypeHandle Of(i::Object* value, Region* region) {
|
| return Config::from_bitset(BitsetType::Lub(value), region);
|
| }
|
| @@ -325,6 +357,9 @@ class TypeImpl : public Config::Base {
|
|
|
| bool IsClass() { return Config::is_class(this); }
|
| bool IsConstant() { return Config::is_constant(this); }
|
| + bool IsContext() {
|
| + return Config::is_struct(this, StructuralType::kContextTag);
|
| + }
|
| bool IsArray() { return Config::is_struct(this, StructuralType::kArrayTag); }
|
| bool IsFunction() {
|
| return Config::is_struct(this, StructuralType::kFunctionTag);
|
| @@ -332,6 +367,7 @@ class TypeImpl : public Config::Base {
|
|
|
| ClassType* AsClass() { return ClassType::cast(this); }
|
| ConstantType* AsConstant() { return ConstantType::cast(this); }
|
| + ContextType* AsContext() { return ContextType::cast(this); }
|
| ArrayType* AsArray() { return ArrayType::cast(this); }
|
| FunctionType* AsFunction() { return FunctionType::cast(this); }
|
|
|
| @@ -355,6 +391,7 @@ class TypeImpl : public Config::Base {
|
| typename OtherTypeImpl::TypeHandle type, Region* region);
|
|
|
| enum PrintDimension { BOTH_DIMS, SEMANTIC_DIM, REPRESENTATION_DIM };
|
| + void PrintTo(StringStream* stream, PrintDimension = BOTH_DIMS);
|
| void TypePrint(PrintDimension = BOTH_DIMS);
|
| void TypePrint(FILE* out, PrintDimension = BOTH_DIMS);
|
|
|
| @@ -419,10 +456,14 @@ class TypeImpl<Config>::BitsetType : public TypeImpl<Config> {
|
| static int Glb(TypeImpl* type); // greatest lower bound that's a bitset
|
| static int Lub(TypeImpl* type); // least upper bound that's a bitset
|
| static int Lub(i::Object* value);
|
| + static int Lub(double value);
|
| + static int Lub(int32_t value);
|
| + static int Lub(uint32_t value);
|
| static int Lub(i::Map* map);
|
|
|
| static const char* Name(int bitset);
|
| - static void BitsetTypePrint(FILE* out, int bitset);
|
| + static void PrintTo(StringStream* stream, int bitset);
|
| + using TypeImpl::PrintTo;
|
| };
|
|
|
|
|
| @@ -438,6 +479,7 @@ class TypeImpl<Config>::StructuralType : public TypeImpl<Config> {
|
| enum Tag {
|
| kClassTag,
|
| kConstantTag,
|
| + kContextTag,
|
| kArrayTag,
|
| kFunctionTag,
|
| kUnionTag
|
| @@ -496,6 +538,25 @@ class TypeImpl<Config>::ConstantType : public TypeImpl<Config> {
|
| };
|
|
|
|
|
| +template<class Config>
|
| +class TypeImpl<Config>::ContextType : public StructuralType {
|
| + public:
|
| + TypeHandle Outer() { return this->Get(0); }
|
| +
|
| + static ContextHandle New(TypeHandle outer, Region* region) {
|
| + ContextHandle type = Config::template cast<ContextType>(
|
| + StructuralType::New(StructuralType::kContextTag, 1, region));
|
| + type->Set(0, outer);
|
| + return type;
|
| + }
|
| +
|
| + static ContextType* cast(TypeImpl* type) {
|
| + ASSERT(type->IsContext());
|
| + return static_cast<ContextType*>(type);
|
| + }
|
| +};
|
| +
|
| +
|
| // Internal
|
| // A union is a structured type with the following invariants:
|
| // - its length is at least 2
|
|
|