Remove the template magic from types.(h|cc), remove types-inl.h.
This CL removes the Config templatization from the types. It is not necessary anymore, after the HeapTypes have been removed. The CL also changes the type hierarchy - the specific type kinds are not inner classes of the Type class and they do not inherit from Type. This is partly because it seems impossible to make this work without templates. Instead, a new TypeBase class is introduced and all the structural (i.e., non-bitset) types inherit from it. The bitset type still requires the bit-munging hack and some nasty reinterpret-casts to pretend bitsets are of type Type*. Additionally, there is now the same hack for TypeBase - all pointers to the sub-types of TypeBase are reinterpret-casted to Type*. This is to keep the type constructors in inline method definitions (although it is unclear how much that actually buys us). In future, we would like to move to a model where we encapsulate Type* into a class (or possibly use Type where we used to use Type*). This would loosen the coupling between bitset size and pointer size, and eventually we would be able to have more bits. TBR=bradnelson@chromium.org Review URL: https://codereview.chromium.org/1655833002 Cr-Commit-Position: refs/heads/master@{#33656}
This commit is contained in:
parent
eea1a4c003
commit
ef35f11c43
1
BUILD.gn
1
BUILD.gn
@ -1303,7 +1303,6 @@ source_set("v8_base") {
|
||||
"src/type-feedback-vector.h",
|
||||
"src/type-info.cc",
|
||||
"src/type-info.h",
|
||||
"src/types-inl.h",
|
||||
"src/types.cc",
|
||||
"src/types.h",
|
||||
"src/typing-asm.cc",
|
||||
|
@ -819,14 +819,12 @@ void AstVisitor::VisitExpressions(ZoneList<Expression*>* expressions) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CaseClause::CaseClause(Zone* zone, Expression* label,
|
||||
ZoneList<Statement*>* statements, int pos)
|
||||
: Expression(zone, pos),
|
||||
label_(label),
|
||||
statements_(statements),
|
||||
compare_type_(Type::None(zone)) {}
|
||||
|
||||
compare_type_(Type::None()) {}
|
||||
|
||||
uint32_t Literal::Hash() {
|
||||
return raw_value()->IsString()
|
||||
|
@ -2379,7 +2379,7 @@ class CompareOperation final : public Expression {
|
||||
op_(op),
|
||||
left_(left),
|
||||
right_(right),
|
||||
combined_type_(Type::None(zone)) {
|
||||
combined_type_(Type::None()) {
|
||||
DCHECK(Token::IsCompareOp(op));
|
||||
}
|
||||
static int parent_num_ids() { return Expression::num_ids(); }
|
||||
|
@ -134,7 +134,8 @@ class Genesis BASE_EMBEDDED {
|
||||
public:
|
||||
Genesis(Isolate* isolate, MaybeHandle<JSGlobalProxy> maybe_global_proxy,
|
||||
v8::Local<v8::ObjectTemplate> global_proxy_template,
|
||||
v8::ExtensionConfiguration* extensions, ContextType context_type);
|
||||
v8::ExtensionConfiguration* extensions,
|
||||
GlobalContextType context_type);
|
||||
~Genesis() { }
|
||||
|
||||
Isolate* isolate() const { return isolate_; }
|
||||
@ -187,10 +188,10 @@ class Genesis BASE_EMBEDDED {
|
||||
// New context initialization. Used for creating a context from scratch.
|
||||
void InitializeGlobal(Handle<JSGlobalObject> global_object,
|
||||
Handle<JSFunction> empty_function,
|
||||
ContextType context_type);
|
||||
GlobalContextType context_type);
|
||||
void InitializeExperimentalGlobal();
|
||||
// Depending on the situation, expose and/or get rid of the utils object.
|
||||
void ConfigureUtilsObject(ContextType context_type);
|
||||
void ConfigureUtilsObject(GlobalContextType context_type);
|
||||
|
||||
#define DECLARE_FEATURE_INITIALIZATION(id, descr) \
|
||||
void InitializeGlobal_##id();
|
||||
@ -206,7 +207,7 @@ class Genesis BASE_EMBEDDED {
|
||||
Handle<JSFunction> InstallInternalArray(Handle<JSObject> target,
|
||||
const char* name,
|
||||
ElementsKind elements_kind);
|
||||
bool InstallNatives(ContextType context_type);
|
||||
bool InstallNatives(GlobalContextType context_type);
|
||||
|
||||
void InstallTypedArray(const char* name, ElementsKind elements_kind,
|
||||
Handle<JSFunction>* fun);
|
||||
@ -318,11 +319,10 @@ void Bootstrapper::Iterate(ObjectVisitor* v) {
|
||||
v->Synchronize(VisitorSynchronization::kExtensions);
|
||||
}
|
||||
|
||||
|
||||
Handle<Context> Bootstrapper::CreateEnvironment(
|
||||
MaybeHandle<JSGlobalProxy> maybe_global_proxy,
|
||||
v8::Local<v8::ObjectTemplate> global_proxy_template,
|
||||
v8::ExtensionConfiguration* extensions, ContextType context_type) {
|
||||
v8::ExtensionConfiguration* extensions, GlobalContextType context_type) {
|
||||
HandleScope scope(isolate_);
|
||||
Genesis genesis(isolate_, maybe_global_proxy, global_proxy_template,
|
||||
extensions, context_type);
|
||||
@ -1066,7 +1066,7 @@ static void InstallWithIntrinsicDefaultProto(Isolate* isolate,
|
||||
// work in the snapshot case is done in HookUpGlobalObject.
|
||||
void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
|
||||
Handle<JSFunction> empty_function,
|
||||
ContextType context_type) {
|
||||
GlobalContextType context_type) {
|
||||
// --- N a t i v e C o n t e x t ---
|
||||
// Use the empty function as closure (no scope info).
|
||||
native_context()->set_closure(*empty_function);
|
||||
@ -1993,8 +1993,7 @@ static Handle<JSObject> ResolveBuiltinIdHolder(Handle<Context> native_context,
|
||||
return Handle<JSObject>::cast(value);
|
||||
}
|
||||
|
||||
|
||||
void Genesis::ConfigureUtilsObject(ContextType context_type) {
|
||||
void Genesis::ConfigureUtilsObject(GlobalContextType context_type) {
|
||||
switch (context_type) {
|
||||
// We still need the utils object to find debug functions.
|
||||
case DEBUG_CONTEXT:
|
||||
@ -2607,8 +2606,7 @@ Handle<JSFunction> Genesis::InstallInternalArray(Handle<JSObject> target,
|
||||
return array_function;
|
||||
}
|
||||
|
||||
|
||||
bool Genesis::InstallNatives(ContextType context_type) {
|
||||
bool Genesis::InstallNatives(GlobalContextType context_type) {
|
||||
HandleScope scope(isolate());
|
||||
|
||||
// Set up the utils object as shared container between native scripts.
|
||||
@ -3490,12 +3488,11 @@ class NoTrackDoubleFieldsForSerializerScope {
|
||||
bool enabled_;
|
||||
};
|
||||
|
||||
|
||||
Genesis::Genesis(Isolate* isolate,
|
||||
MaybeHandle<JSGlobalProxy> maybe_global_proxy,
|
||||
v8::Local<v8::ObjectTemplate> global_proxy_template,
|
||||
v8::ExtensionConfiguration* extensions,
|
||||
ContextType context_type)
|
||||
GlobalContextType context_type)
|
||||
: isolate_(isolate), active_(isolate->bootstrapper()) {
|
||||
NoTrackDoubleFieldsForSerializerScope disable_scope(isolate);
|
||||
result_ = Handle<Context>::null();
|
||||
|
@ -61,7 +61,7 @@ class SourceCodeCache final BASE_EMBEDDED {
|
||||
DISALLOW_COPY_AND_ASSIGN(SourceCodeCache);
|
||||
};
|
||||
|
||||
enum ContextType { FULL_CONTEXT, THIN_CONTEXT, DEBUG_CONTEXT };
|
||||
enum GlobalContextType { FULL_CONTEXT, THIN_CONTEXT, DEBUG_CONTEXT };
|
||||
|
||||
// The Boostrapper is the public interface for creating a JavaScript global
|
||||
// context.
|
||||
@ -80,7 +80,7 @@ class Bootstrapper final {
|
||||
MaybeHandle<JSGlobalProxy> maybe_global_proxy,
|
||||
v8::Local<v8::ObjectTemplate> global_object_template,
|
||||
v8::ExtensionConfiguration* extensions,
|
||||
ContextType context_type = FULL_CONTEXT);
|
||||
GlobalContextType context_type = FULL_CONTEXT);
|
||||
|
||||
// Detach the environment from its outer global object.
|
||||
void DetachGlobal(Handle<Context> env);
|
||||
|
@ -318,7 +318,7 @@ template <>
|
||||
HValue* CodeStubGraphBuilder<NumberToStringStub>::BuildCodeStub() {
|
||||
info()->MarkAsSavesCallerDoubles();
|
||||
HValue* number = GetParameter(NumberToStringStub::kNumber);
|
||||
return BuildNumberToString(number, Type::Number(zone()));
|
||||
return BuildNumberToString(number, Type::Number());
|
||||
}
|
||||
|
||||
|
||||
@ -1468,10 +1468,9 @@ HValue* CodeStubGraphBuilder<BinaryOpICStub>::BuildCodeInitializedStub() {
|
||||
if_leftisstring.If<HIsStringAndBranch>(left);
|
||||
if_leftisstring.Then();
|
||||
{
|
||||
Push(BuildBinaryOperation(state.op(), left, right, Type::String(zone()),
|
||||
right_type, result_type,
|
||||
state.fixed_right_arg(), allocation_mode,
|
||||
state.strength()));
|
||||
Push(BuildBinaryOperation(
|
||||
state.op(), left, right, Type::String(), right_type, result_type,
|
||||
state.fixed_right_arg(), allocation_mode, state.strength()));
|
||||
}
|
||||
if_leftisstring.Else();
|
||||
{
|
||||
@ -1486,10 +1485,9 @@ HValue* CodeStubGraphBuilder<BinaryOpICStub>::BuildCodeInitializedStub() {
|
||||
if_rightisstring.If<HIsStringAndBranch>(right);
|
||||
if_rightisstring.Then();
|
||||
{
|
||||
Push(BuildBinaryOperation(state.op(), left, right, left_type,
|
||||
Type::String(zone()), result_type,
|
||||
state.fixed_right_arg(), allocation_mode,
|
||||
state.strength()));
|
||||
Push(BuildBinaryOperation(
|
||||
state.op(), left, right, left_type, Type::String(), result_type,
|
||||
state.fixed_right_arg(), allocation_mode, state.strength()));
|
||||
}
|
||||
if_rightisstring.Else();
|
||||
{
|
||||
|
@ -555,18 +555,17 @@ std::ostream& operator<<(std::ostream& os, const CompareNilICStub::State& s) {
|
||||
|
||||
Type* CompareNilICStub::GetType(Zone* zone, Handle<Map> map) {
|
||||
State state = this->state();
|
||||
if (state.Contains(CompareNilICStub::GENERIC)) return Type::Any(zone);
|
||||
if (state.Contains(CompareNilICStub::GENERIC)) return Type::Any();
|
||||
|
||||
Type* result = Type::None(zone);
|
||||
Type* result = Type::None();
|
||||
if (state.Contains(CompareNilICStub::UNDEFINED)) {
|
||||
result = Type::Union(result, Type::Undefined(zone), zone);
|
||||
result = Type::Union(result, Type::Undefined(), zone);
|
||||
}
|
||||
if (state.Contains(CompareNilICStub::NULL_TYPE)) {
|
||||
result = Type::Union(result, Type::Null(zone), zone);
|
||||
result = Type::Union(result, Type::Null(), zone);
|
||||
}
|
||||
if (state.Contains(CompareNilICStub::MONOMORPHIC_MAP)) {
|
||||
Type* type =
|
||||
map.is_null() ? Type::Detectable(zone) : Type::Class(map, zone);
|
||||
Type* type = map.is_null() ? Type::Detectable() : Type::Class(map, zone);
|
||||
result = Type::Union(result, type, zone);
|
||||
}
|
||||
|
||||
@ -576,8 +575,7 @@ Type* CompareNilICStub::GetType(Zone* zone, Handle<Map> map) {
|
||||
|
||||
Type* CompareNilICStub::GetInputType(Zone* zone, Handle<Map> map) {
|
||||
Type* output_type = GetType(zone, map);
|
||||
Type* nil_type =
|
||||
nil_value() == kNullValue ? Type::Null(zone) : Type::Undefined(zone);
|
||||
Type* nil_type = nil_value() == kNullValue ? Type::Null() : Type::Undefined();
|
||||
return Type::Union(output_type, nil_type, zone);
|
||||
}
|
||||
|
||||
|
@ -6,9 +6,9 @@
|
||||
|
||||
#include "src/contexts.h"
|
||||
#include "src/frames.h"
|
||||
#include "src/handles-inl.h"
|
||||
#include "src/heap/heap.h"
|
||||
#include "src/type-cache.h"
|
||||
#include "src/types-inl.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
@ -10,7 +10,6 @@
|
||||
#include "src/field-index-inl.h"
|
||||
#include "src/objects-inl.h" // TODO(mstarzinger): Temporary cycle breaker!
|
||||
#include "src/type-cache.h"
|
||||
#include "src/types-inl.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
@ -14,11 +14,7 @@ namespace internal {
|
||||
|
||||
// Forward declarations.
|
||||
class ExternalReference;
|
||||
template <class>
|
||||
class TypeImpl;
|
||||
struct ZoneTypeConfig;
|
||||
typedef TypeImpl<ZoneTypeConfig> Type;
|
||||
|
||||
class Type;
|
||||
|
||||
namespace compiler {
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include "src/compiler/node-properties.h"
|
||||
#include "src/compiler/operator-properties.h"
|
||||
#include "src/compiler/verifier.h"
|
||||
#include "src/types-inl.h"
|
||||
#include "src/handles-inl.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
@ -7,7 +7,7 @@
|
||||
#include "src/base/lazy-instance.h"
|
||||
#include "src/compiler/opcodes.h"
|
||||
#include "src/compiler/operator.h"
|
||||
#include "src/types-inl.h"
|
||||
#include "src/types.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
@ -15,10 +15,7 @@ namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
// Forward declarations.
|
||||
template <class>
|
||||
class TypeImpl;
|
||||
struct ZoneTypeConfig;
|
||||
typedef TypeImpl<ZoneTypeConfig> Type;
|
||||
class Type;
|
||||
class Zone;
|
||||
|
||||
|
||||
|
@ -29,10 +29,8 @@ class Typer::Decorator final : public GraphDecorator {
|
||||
Typer* const typer_;
|
||||
};
|
||||
|
||||
|
||||
Typer::Typer(Isolate* isolate, Graph* graph, Flags flags,
|
||||
CompilationDependencies* dependencies,
|
||||
Type::FunctionType* function_type)
|
||||
CompilationDependencies* dependencies, FunctionType* function_type)
|
||||
: isolate_(isolate),
|
||||
graph_(graph),
|
||||
flags_(flags),
|
||||
@ -243,11 +241,10 @@ class Typer::Visitor : public Reducer {
|
||||
static Type* NumberToInt32(Type*, Typer*);
|
||||
static Type* NumberToUint32(Type*, Typer*);
|
||||
|
||||
static Type* JSAddRanger(Type::RangeType*, Type::RangeType*, Typer*);
|
||||
static Type* JSSubtractRanger(Type::RangeType*, Type::RangeType*, Typer*);
|
||||
static Type* JSMultiplyRanger(Type::RangeType*, Type::RangeType*, Typer*);
|
||||
static Type* JSDivideRanger(Type::RangeType*, Type::RangeType*, Typer*);
|
||||
static Type* JSModulusRanger(Type::RangeType*, Type::RangeType*, Typer*);
|
||||
static Type* JSAddRanger(RangeType*, RangeType*, Typer*);
|
||||
static Type* JSSubtractRanger(RangeType*, RangeType*, Typer*);
|
||||
static Type* JSDivideRanger(RangeType*, RangeType*, Typer*);
|
||||
static Type* JSModulusRanger(RangeType*, RangeType*, Typer*);
|
||||
|
||||
static ComparisonOutcome JSCompareTyper(Type*, Type*, Typer*);
|
||||
|
||||
@ -513,9 +510,7 @@ Type* Typer::Visitor::NumberToUint32(Type* type, Typer* t) {
|
||||
|
||||
// Control operators.
|
||||
|
||||
|
||||
Type* Typer::Visitor::TypeStart(Node* node) { return Type::Internal(zone()); }
|
||||
|
||||
Type* Typer::Visitor::TypeStart(Node* node) { return Type::Internal(); }
|
||||
|
||||
Type* Typer::Visitor::TypeIfException(Node* node) { return Type::Any(); }
|
||||
|
||||
@ -524,7 +519,7 @@ Type* Typer::Visitor::TypeIfException(Node* node) { return Type::Any(); }
|
||||
|
||||
|
||||
Type* Typer::Visitor::TypeParameter(Node* node) {
|
||||
if (Type::FunctionType* function_type = typer_->function_type()) {
|
||||
if (FunctionType* function_type = typer_->function_type()) {
|
||||
int const index = ParameterIndexOf(node->op());
|
||||
if (index >= 0 && index < function_type->Arity()) {
|
||||
return function_type->Parameter(index);
|
||||
@ -578,7 +573,7 @@ Type* Typer::Visitor::TypeHeapConstant(Node* node) {
|
||||
|
||||
|
||||
Type* Typer::Visitor::TypeExternalConstant(Node* node) {
|
||||
return Type::Internal(zone());
|
||||
return Type::Internal();
|
||||
}
|
||||
|
||||
|
||||
@ -627,22 +622,15 @@ Type* Typer::Visitor::TypeFinishRegion(Node* node) { return Operand(node, 0); }
|
||||
|
||||
Type* Typer::Visitor::TypeFrameState(Node* node) {
|
||||
// TODO(rossberg): Ideally FrameState wouldn't have a value output.
|
||||
return Type::Internal(zone());
|
||||
return Type::Internal();
|
||||
}
|
||||
|
||||
Type* Typer::Visitor::TypeStateValues(Node* node) { return Type::Internal(); }
|
||||
|
||||
Type* Typer::Visitor::TypeStateValues(Node* node) {
|
||||
return Type::Internal(zone());
|
||||
}
|
||||
|
||||
|
||||
Type* Typer::Visitor::TypeObjectState(Node* node) {
|
||||
return Type::Internal(zone());
|
||||
}
|
||||
|
||||
Type* Typer::Visitor::TypeObjectState(Node* node) { return Type::Internal(); }
|
||||
|
||||
Type* Typer::Visitor::TypeTypedStateValues(Node* node) {
|
||||
return Type::Internal(zone());
|
||||
return Type::Internal();
|
||||
}
|
||||
|
||||
|
||||
@ -955,9 +943,7 @@ static double array_max(double a[], size_t n) {
|
||||
return x == 0 ? 0 : x; // -0 -> 0
|
||||
}
|
||||
|
||||
|
||||
Type* Typer::Visitor::JSAddRanger(Type::RangeType* lhs, Type::RangeType* rhs,
|
||||
Typer* t) {
|
||||
Type* Typer::Visitor::JSAddRanger(RangeType* lhs, RangeType* rhs, Typer* t) {
|
||||
double results[4];
|
||||
results[0] = lhs->Min() + rhs->Min();
|
||||
results[1] = lhs->Min() + rhs->Max();
|
||||
@ -1003,9 +989,8 @@ Type* Typer::Visitor::JSAddTyper(Type* lhs, Type* rhs, Typer* t) {
|
||||
return Type::Number();
|
||||
}
|
||||
|
||||
|
||||
Type* Typer::Visitor::JSSubtractRanger(Type::RangeType* lhs,
|
||||
Type::RangeType* rhs, Typer* t) {
|
||||
Type* Typer::Visitor::JSSubtractRanger(RangeType* lhs, RangeType* rhs,
|
||||
Typer* t) {
|
||||
double results[4];
|
||||
results[0] = lhs->Min() - rhs->Min();
|
||||
results[1] = lhs->Min() - rhs->Max();
|
||||
@ -1042,41 +1027,38 @@ Type* Typer::Visitor::JSSubtractTyper(Type* lhs, Type* rhs, Typer* t) {
|
||||
}
|
||||
|
||||
|
||||
Type* Typer::Visitor::JSMultiplyRanger(Type::RangeType* lhs,
|
||||
Type::RangeType* rhs, Typer* t) {
|
||||
double results[4];
|
||||
double lmin = lhs->Min();
|
||||
double lmax = lhs->Max();
|
||||
double rmin = rhs->Min();
|
||||
double rmax = rhs->Max();
|
||||
results[0] = lmin * rmin;
|
||||
results[1] = lmin * rmax;
|
||||
results[2] = lmax * rmin;
|
||||
results[3] = lmax * rmax;
|
||||
// If the result may be nan, we give up on calculating a precise type, because
|
||||
// the discontinuity makes it too complicated. Note that even if none of the
|
||||
// "results" above is nan, the actual result may still be, so we have to do a
|
||||
// different check:
|
||||
bool maybe_nan = (lhs->Maybe(t->cache_.kSingletonZero) &&
|
||||
(rmin == -V8_INFINITY || rmax == +V8_INFINITY)) ||
|
||||
(rhs->Maybe(t->cache_.kSingletonZero) &&
|
||||
(lmin == -V8_INFINITY || lmax == +V8_INFINITY));
|
||||
if (maybe_nan) return t->cache_.kIntegerOrMinusZeroOrNaN; // Giving up.
|
||||
bool maybe_minuszero = (lhs->Maybe(t->cache_.kSingletonZero) && rmin < 0) ||
|
||||
(rhs->Maybe(t->cache_.kSingletonZero) && lmin < 0);
|
||||
Type* range =
|
||||
Type::Range(array_min(results, 4), array_max(results, 4), t->zone());
|
||||
return maybe_minuszero ? Type::Union(range, Type::MinusZero(), t->zone())
|
||||
: range;
|
||||
}
|
||||
|
||||
|
||||
Type* Typer::Visitor::JSMultiplyTyper(Type* lhs, Type* rhs, Typer* t) {
|
||||
lhs = Rangify(ToNumber(lhs, t), t);
|
||||
rhs = Rangify(ToNumber(rhs, t), t);
|
||||
if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN();
|
||||
if (lhs->IsRange() && rhs->IsRange()) {
|
||||
return JSMultiplyRanger(lhs->AsRange(), rhs->AsRange(), t);
|
||||
double results[4];
|
||||
double lmin = lhs->AsRange()->Min();
|
||||
double lmax = lhs->AsRange()->Max();
|
||||
double rmin = rhs->AsRange()->Min();
|
||||
double rmax = rhs->AsRange()->Max();
|
||||
results[0] = lmin * rmin;
|
||||
results[1] = lmin * rmax;
|
||||
results[2] = lmax * rmin;
|
||||
results[3] = lmax * rmax;
|
||||
// If the result may be nan, we give up on calculating a precise type,
|
||||
// because
|
||||
// the discontinuity makes it too complicated. Note that even if none of
|
||||
// the
|
||||
// "results" above is nan, the actual result may still be, so we have to do
|
||||
// a
|
||||
// different check:
|
||||
bool maybe_nan = (lhs->Maybe(t->cache_.kSingletonZero) &&
|
||||
(rmin == -V8_INFINITY || rmax == +V8_INFINITY)) ||
|
||||
(rhs->Maybe(t->cache_.kSingletonZero) &&
|
||||
(lmin == -V8_INFINITY || lmax == +V8_INFINITY));
|
||||
if (maybe_nan) return t->cache_.kIntegerOrMinusZeroOrNaN; // Giving up.
|
||||
bool maybe_minuszero = (lhs->Maybe(t->cache_.kSingletonZero) && rmin < 0) ||
|
||||
(rhs->Maybe(t->cache_.kSingletonZero) && lmin < 0);
|
||||
Type* range =
|
||||
Type::Range(array_min(results, 4), array_max(results, 4), t->zone());
|
||||
return maybe_minuszero ? Type::Union(range, Type::MinusZero(), t->zone())
|
||||
: range;
|
||||
}
|
||||
return Type::Number();
|
||||
}
|
||||
@ -1095,9 +1077,8 @@ Type* Typer::Visitor::JSDivideTyper(Type* lhs, Type* rhs, Typer* t) {
|
||||
return maybe_nan ? Type::Number() : Type::OrderedNumber();
|
||||
}
|
||||
|
||||
|
||||
Type* Typer::Visitor::JSModulusRanger(Type::RangeType* lhs,
|
||||
Type::RangeType* rhs, Typer* t) {
|
||||
Type* Typer::Visitor::JSModulusRanger(RangeType* lhs, RangeType* rhs,
|
||||
Typer* t) {
|
||||
double lmin = lhs->Min();
|
||||
double lmax = lhs->Max();
|
||||
double rmin = rhs->Min();
|
||||
@ -1291,8 +1272,8 @@ Type* Typer::Visitor::TypeJSLoadNamed(Node* node) {
|
||||
} else if (receiver->IsClass() &&
|
||||
receiver->AsClass()->Map()->IsJSFunctionMap()) {
|
||||
Handle<Map> map = receiver->AsClass()->Map();
|
||||
return map->has_non_instance_prototype() ? Type::Primitive(zone())
|
||||
: Type::Receiver(zone());
|
||||
return map->has_non_instance_prototype() ? Type::Primitive()
|
||||
: Type::Receiver();
|
||||
}
|
||||
}
|
||||
return Type::Any();
|
||||
@ -1340,8 +1321,8 @@ Type* Typer::Visitor::Weaken(Node* node, Type* current_type,
|
||||
// Only weaken if there is range involved; we should converge quickly
|
||||
// for all other types (the exception is a union of many constants,
|
||||
// but we currently do not increase the number of constants in unions).
|
||||
Type::RangeType* previous = previous_integer->GetRange();
|
||||
Type::RangeType* current = current_integer->GetRange();
|
||||
Type* previous = previous_integer->GetRange();
|
||||
Type* current = current_integer->GetRange();
|
||||
if (current == nullptr || previous == nullptr) {
|
||||
return current_type;
|
||||
}
|
||||
@ -1402,19 +1383,12 @@ Type* Typer::Visitor::TypeJSStoreGlobal(Node* node) {
|
||||
|
||||
|
||||
Type* Typer::Visitor::TypeJSDeleteProperty(Node* node) {
|
||||
return Type::Boolean(zone());
|
||||
return Type::Boolean();
|
||||
}
|
||||
|
||||
Type* Typer::Visitor::TypeJSHasProperty(Node* node) { return Type::Boolean(); }
|
||||
|
||||
Type* Typer::Visitor::TypeJSHasProperty(Node* node) {
|
||||
return Type::Boolean(zone());
|
||||
}
|
||||
|
||||
|
||||
Type* Typer::Visitor::TypeJSInstanceOf(Node* node) {
|
||||
return Type::Boolean(zone());
|
||||
}
|
||||
|
||||
Type* Typer::Visitor::TypeJSInstanceOf(Node* node) { return Type::Boolean(); }
|
||||
|
||||
// JS context operators.
|
||||
|
||||
@ -1563,7 +1537,7 @@ Type* Typer::Visitor::TypeJSCallRuntime(Node* node) {
|
||||
case Runtime::kInlineIsFunction:
|
||||
case Runtime::kInlineIsRegExp:
|
||||
case Runtime::kInlineIsJSReceiver:
|
||||
return Type::Boolean(zone());
|
||||
return Type::Boolean();
|
||||
case Runtime::kInlineDoubleLo:
|
||||
case Runtime::kInlineDoubleHi:
|
||||
return Type::Signed32();
|
||||
@ -1627,11 +1601,7 @@ Type* Typer::Visitor::TypeJSForInPrepare(Node* node) {
|
||||
return Type::Tuple(cache_type, cache_array, cache_length, zone());
|
||||
}
|
||||
|
||||
|
||||
Type* Typer::Visitor::TypeJSForInDone(Node* node) {
|
||||
return Type::Boolean(zone());
|
||||
}
|
||||
|
||||
Type* Typer::Visitor::TypeJSForInDone(Node* node) { return Type::Boolean(); }
|
||||
|
||||
Type* Typer::Visitor::TypeJSForInStep(Node* node) {
|
||||
STATIC_ASSERT(Map::EnumLengthBits::kMax <= FixedArray::kMaxLength);
|
||||
@ -1653,82 +1623,57 @@ Type* Typer::Visitor::TypeJSStackCheck(Node* node) { return Type::Any(); }
|
||||
|
||||
// Simplified operators.
|
||||
|
||||
|
||||
Type* Typer::Visitor::TypeBooleanNot(Node* node) {
|
||||
return Type::Boolean(zone());
|
||||
}
|
||||
|
||||
Type* Typer::Visitor::TypeBooleanNot(Node* node) { return Type::Boolean(); }
|
||||
|
||||
Type* Typer::Visitor::TypeBooleanToNumber(Node* node) {
|
||||
return TypeUnaryOp(node, ToNumber);
|
||||
}
|
||||
|
||||
Type* Typer::Visitor::TypeNumberEqual(Node* node) { return Type::Boolean(); }
|
||||
|
||||
Type* Typer::Visitor::TypeNumberEqual(Node* node) {
|
||||
return Type::Boolean(zone());
|
||||
}
|
||||
|
||||
|
||||
Type* Typer::Visitor::TypeNumberLessThan(Node* node) {
|
||||
return Type::Boolean(zone());
|
||||
}
|
||||
|
||||
Type* Typer::Visitor::TypeNumberLessThan(Node* node) { return Type::Boolean(); }
|
||||
|
||||
Type* Typer::Visitor::TypeNumberLessThanOrEqual(Node* node) {
|
||||
return Type::Boolean(zone());
|
||||
return Type::Boolean();
|
||||
}
|
||||
|
||||
Type* Typer::Visitor::TypeNumberAdd(Node* node) { return Type::Number(); }
|
||||
|
||||
Type* Typer::Visitor::TypeNumberAdd(Node* node) { return Type::Number(zone()); }
|
||||
Type* Typer::Visitor::TypeNumberSubtract(Node* node) { return Type::Number(); }
|
||||
|
||||
Type* Typer::Visitor::TypeNumberMultiply(Node* node) { return Type::Number(); }
|
||||
|
||||
Type* Typer::Visitor::TypeNumberSubtract(Node* node) {
|
||||
return Type::Number(zone());
|
||||
}
|
||||
|
||||
|
||||
Type* Typer::Visitor::TypeNumberMultiply(Node* node) {
|
||||
return Type::Number(zone());
|
||||
}
|
||||
|
||||
|
||||
Type* Typer::Visitor::TypeNumberDivide(Node* node) {
|
||||
return Type::Number(zone());
|
||||
}
|
||||
|
||||
|
||||
Type* Typer::Visitor::TypeNumberModulus(Node* node) {
|
||||
return Type::Number(zone());
|
||||
}
|
||||
Type* Typer::Visitor::TypeNumberDivide(Node* node) { return Type::Number(); }
|
||||
|
||||
Type* Typer::Visitor::TypeNumberModulus(Node* node) { return Type::Number(); }
|
||||
|
||||
Type* Typer::Visitor::TypeNumberBitwiseOr(Node* node) {
|
||||
return Type::Signed32(zone());
|
||||
return Type::Signed32();
|
||||
}
|
||||
|
||||
|
||||
Type* Typer::Visitor::TypeNumberBitwiseXor(Node* node) {
|
||||
return Type::Signed32(zone());
|
||||
return Type::Signed32();
|
||||
}
|
||||
|
||||
|
||||
Type* Typer::Visitor::TypeNumberBitwiseAnd(Node* node) {
|
||||
return Type::Signed32(zone());
|
||||
return Type::Signed32();
|
||||
}
|
||||
|
||||
|
||||
Type* Typer::Visitor::TypeNumberShiftLeft(Node* node) {
|
||||
return Type::Signed32(zone());
|
||||
return Type::Signed32();
|
||||
}
|
||||
|
||||
|
||||
Type* Typer::Visitor::TypeNumberShiftRight(Node* node) {
|
||||
return Type::Signed32(zone());
|
||||
return Type::Signed32();
|
||||
}
|
||||
|
||||
|
||||
Type* Typer::Visitor::TypeNumberShiftRightLogical(Node* node) {
|
||||
return Type::Unsigned32(zone());
|
||||
return Type::Unsigned32();
|
||||
}
|
||||
|
||||
|
||||
@ -1743,7 +1688,7 @@ Type* Typer::Visitor::TypeNumberToUint32(Node* node) {
|
||||
|
||||
|
||||
Type* Typer::Visitor::TypeNumberIsHoleNaN(Node* node) {
|
||||
return Type::Boolean(zone());
|
||||
return Type::Boolean();
|
||||
}
|
||||
|
||||
|
||||
@ -1765,19 +1710,12 @@ Type* Typer::Visitor::TypeReferenceEqual(Node* node) {
|
||||
return TypeBinaryOp(node, ReferenceEqualTyper);
|
||||
}
|
||||
|
||||
Type* Typer::Visitor::TypeStringEqual(Node* node) { return Type::Boolean(); }
|
||||
|
||||
Type* Typer::Visitor::TypeStringEqual(Node* node) {
|
||||
return Type::Boolean(zone());
|
||||
}
|
||||
|
||||
|
||||
Type* Typer::Visitor::TypeStringLessThan(Node* node) {
|
||||
return Type::Boolean(zone());
|
||||
}
|
||||
|
||||
Type* Typer::Visitor::TypeStringLessThan(Node* node) { return Type::Boolean(); }
|
||||
|
||||
Type* Typer::Visitor::TypeStringLessThanOrEqual(Node* node) {
|
||||
return Type::Boolean(zone());
|
||||
return Type::Boolean();
|
||||
}
|
||||
|
||||
|
||||
|
@ -30,7 +30,7 @@ class Typer {
|
||||
|
||||
Typer(Isolate* isolate, Graph* graph, Flags flags = kNoFlags,
|
||||
CompilationDependencies* dependencies = nullptr,
|
||||
Type::FunctionType* function_type = nullptr);
|
||||
FunctionType* function_type = nullptr);
|
||||
~Typer();
|
||||
|
||||
void Run();
|
||||
@ -46,13 +46,13 @@ class Typer {
|
||||
Isolate* isolate() const { return isolate_; }
|
||||
Flags flags() const { return flags_; }
|
||||
CompilationDependencies* dependencies() const { return dependencies_; }
|
||||
Type::FunctionType* function_type() const { return function_type_; }
|
||||
FunctionType* function_type() const { return function_type_; }
|
||||
|
||||
Isolate* const isolate_;
|
||||
Graph* const graph_;
|
||||
Flags const flags_;
|
||||
CompilationDependencies* const dependencies_;
|
||||
Type::FunctionType* function_type_;
|
||||
FunctionType* function_type_;
|
||||
Decorator* decorator_;
|
||||
TypeCache const& cache_;
|
||||
|
||||
|
@ -22,7 +22,6 @@
|
||||
#include "src/compiler/schedule.h"
|
||||
#include "src/compiler/simplified-operator.h"
|
||||
#include "src/ostreams.h"
|
||||
#include "src/types-inl.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
@ -4,9 +4,8 @@
|
||||
|
||||
#include "src/crankshaft/hydrogen-types.h"
|
||||
|
||||
#include "src/handles-inl.h"
|
||||
#include "src/ostreams.h"
|
||||
#include "src/types-inl.h"
|
||||
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
@ -10906,7 +10906,7 @@ HValue* HGraphBuilder::TruncateToNumber(HValue* value, Type** expected) {
|
||||
Maybe<HConstant*> number =
|
||||
constant->CopyToTruncatedNumber(isolate(), zone());
|
||||
if (number.IsJust()) {
|
||||
*expected = Type::Number(zone());
|
||||
*expected = Type::Number();
|
||||
return AddInstruction(number.FromJust());
|
||||
}
|
||||
}
|
||||
@ -10920,20 +10920,20 @@ HValue* HGraphBuilder::TruncateToNumber(HValue* value, Type** expected) {
|
||||
|
||||
// Separate the number type from the rest.
|
||||
Type* expected_obj =
|
||||
Type::Intersect(expected_type, Type::NonNumber(zone()), zone());
|
||||
Type::Intersect(expected_type, Type::NonNumber(), zone());
|
||||
Type* expected_number =
|
||||
Type::Intersect(expected_type, Type::Number(zone()), zone());
|
||||
Type::Intersect(expected_type, Type::Number(), zone());
|
||||
|
||||
// We expect to get a number.
|
||||
// (We need to check first, since Type::None->Is(Type::Any()) == true.
|
||||
if (expected_obj->Is(Type::None())) {
|
||||
DCHECK(!expected_number->Is(Type::None(zone())));
|
||||
DCHECK(!expected_number->Is(Type::None()));
|
||||
return value;
|
||||
}
|
||||
|
||||
if (expected_obj->Is(Type::Undefined(zone()))) {
|
||||
if (expected_obj->Is(Type::Undefined())) {
|
||||
// This is already done by HChange.
|
||||
*expected = Type::Union(expected_number, Type::Number(zone()), zone());
|
||||
*expected = Type::Union(expected_number, Type::Number(), zone());
|
||||
return value;
|
||||
}
|
||||
|
||||
@ -11008,7 +11008,7 @@ HValue* HGraphBuilder::BuildBinaryOperation(
|
||||
Add<HDeoptimize>(
|
||||
Deoptimizer::kInsufficientTypeFeedbackForLHSOfBinaryOperation,
|
||||
Deoptimizer::SOFT);
|
||||
left_type = Type::Any(zone());
|
||||
left_type = Type::Any();
|
||||
left_rep = RepresentationFor(left_type);
|
||||
maybe_string_add = op == Token::ADD;
|
||||
}
|
||||
@ -11017,7 +11017,7 @@ HValue* HGraphBuilder::BuildBinaryOperation(
|
||||
Add<HDeoptimize>(
|
||||
Deoptimizer::kInsufficientTypeFeedbackForRHSOfBinaryOperation,
|
||||
Deoptimizer::SOFT);
|
||||
right_type = Type::Any(zone());
|
||||
right_type = Type::Any();
|
||||
right_rep = RepresentationFor(right_type);
|
||||
maybe_string_add = op == Token::ADD;
|
||||
}
|
||||
@ -11571,7 +11571,7 @@ HControlInstruction* HOptimizedGraphBuilder::BuildCompareInstruction(
|
||||
Add<HDeoptimize>(
|
||||
Deoptimizer::kInsufficientTypeFeedbackForCombinedTypeOfBinaryOperation,
|
||||
Deoptimizer::SOFT);
|
||||
combined_type = left_type = right_type = Type::Any(zone());
|
||||
combined_type = left_type = right_type = Type::Any();
|
||||
}
|
||||
|
||||
Representation left_rep = RepresentationFor(left_type);
|
||||
@ -11757,7 +11757,8 @@ void HOptimizedGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr,
|
||||
} else {
|
||||
DCHECK_EQ(Token::EQ, expr->op());
|
||||
Type* type = expr->combined_type()->Is(Type::None())
|
||||
? Type::Any(zone()) : expr->combined_type();
|
||||
? Type::Any()
|
||||
: expr->combined_type();
|
||||
HIfContinuation continuation;
|
||||
BuildCompareNil(value, type, &continuation);
|
||||
return ast_context()->ReturnContinuation(&continuation, expr->id());
|
||||
@ -12320,10 +12321,10 @@ void HOptimizedGraphBuilder::GenerateToName(CallRuntime* call) {
|
||||
CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
|
||||
HValue* input = Pop();
|
||||
if (input->type().IsSmi()) {
|
||||
HValue* result = BuildNumberToString(input, Type::SignedSmall(zone()));
|
||||
HValue* result = BuildNumberToString(input, Type::SignedSmall());
|
||||
return ast_context()->ReturnValue(result);
|
||||
} else if (input->type().IsTaggedNumber()) {
|
||||
HValue* result = BuildNumberToString(input, Type::Number(zone()));
|
||||
HValue* result = BuildNumberToString(input, Type::Number());
|
||||
return ast_context()->ReturnValue(result);
|
||||
} else if (input->type().IsString()) {
|
||||
return ast_context()->ReturnValue(input);
|
||||
@ -12744,7 +12745,7 @@ void HOptimizedGraphBuilder::GenerateNumberToString(CallRuntime* call) {
|
||||
DCHECK_EQ(1, call->arguments()->length());
|
||||
CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
|
||||
HValue* number = Pop();
|
||||
HValue* result = BuildNumberToString(number, Type::Any(zone()));
|
||||
HValue* result = BuildNumberToString(number, Type::Any());
|
||||
return ast_context()->ReturnValue(result);
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,7 @@ AstTyper::AstTyper(Isolate* isolate, Zone* zone, Handle<JSFunction> closure,
|
||||
|
||||
Effect AstTyper::ObservedOnStack(Object* value) {
|
||||
Type* lower = Type::NowOf(value, zone());
|
||||
return Effect(Bounds(lower, Type::Any(zone())));
|
||||
return Effect(Bounds(lower, Type::Any()));
|
||||
}
|
||||
|
||||
|
||||
@ -393,7 +393,7 @@ void AstTyper::VisitLiteral(Literal* expr) {
|
||||
|
||||
void AstTyper::VisitRegExpLiteral(RegExpLiteral* expr) {
|
||||
// TODO(rossberg): Reintroduce RegExp type.
|
||||
NarrowType(expr, Bounds(Type::Object(zone())));
|
||||
NarrowType(expr, Bounds(Type::Object()));
|
||||
}
|
||||
|
||||
|
||||
@ -421,7 +421,7 @@ void AstTyper::VisitObjectLiteral(ObjectLiteral* expr) {
|
||||
RECURSE(Visit(prop->value()));
|
||||
}
|
||||
|
||||
NarrowType(expr, Bounds(Type::Object(zone())));
|
||||
NarrowType(expr, Bounds(Type::Object()));
|
||||
}
|
||||
|
||||
|
||||
@ -432,7 +432,7 @@ void AstTyper::VisitArrayLiteral(ArrayLiteral* expr) {
|
||||
RECURSE(Visit(value));
|
||||
}
|
||||
|
||||
NarrowType(expr, Bounds(Type::Object(zone())));
|
||||
NarrowType(expr, Bounds(Type::Object()));
|
||||
}
|
||||
|
||||
|
||||
@ -485,7 +485,7 @@ void AstTyper::VisitThrow(Throw* expr) {
|
||||
RECURSE(Visit(expr->exception()));
|
||||
// TODO(rossberg): is it worth having a non-termination effect?
|
||||
|
||||
NarrowType(expr, Bounds(Type::None(zone())));
|
||||
NarrowType(expr, Bounds(Type::None()));
|
||||
}
|
||||
|
||||
|
||||
@ -569,7 +569,7 @@ void AstTyper::VisitCallNew(CallNew* expr) {
|
||||
RECURSE(Visit(arg));
|
||||
}
|
||||
|
||||
NarrowType(expr, Bounds(Type::None(zone()), Type::Receiver(zone())));
|
||||
NarrowType(expr, Bounds(Type::None(), Type::Receiver()));
|
||||
}
|
||||
|
||||
|
||||
@ -596,13 +596,13 @@ void AstTyper::VisitUnaryOperation(UnaryOperation* expr) {
|
||||
switch (expr->op()) {
|
||||
case Token::NOT:
|
||||
case Token::DELETE:
|
||||
NarrowType(expr, Bounds(Type::Boolean(zone())));
|
||||
NarrowType(expr, Bounds(Type::Boolean()));
|
||||
break;
|
||||
case Token::VOID:
|
||||
NarrowType(expr, Bounds(Type::Undefined(zone())));
|
||||
NarrowType(expr, Bounds(Type::Undefined()));
|
||||
break;
|
||||
case Token::TYPEOF:
|
||||
NarrowType(expr, Bounds(Type::InternalizedString(zone())));
|
||||
NarrowType(expr, Bounds(Type::InternalizedString()));
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
@ -624,7 +624,7 @@ void AstTyper::VisitCountOperation(CountOperation* expr) {
|
||||
|
||||
RECURSE(Visit(expr->expression()));
|
||||
|
||||
NarrowType(expr, Bounds(Type::SignedSmall(zone()), Type::Number(zone())));
|
||||
NarrowType(expr, Bounds(Type::SignedSmall(), Type::Number()));
|
||||
|
||||
VariableProxy* proxy = expr->expression()->AsVariableProxy();
|
||||
if (proxy != NULL && proxy->var()->IsStackAllocated()) {
|
||||
@ -679,8 +679,8 @@ void AstTyper::VisitBinaryOperation(BinaryOperation* expr) {
|
||||
RECURSE(Visit(expr->right()));
|
||||
Type* upper = Type::Union(
|
||||
expr->left()->bounds().upper, expr->right()->bounds().upper, zone());
|
||||
if (!upper->Is(Type::Signed32())) upper = Type::Signed32(zone());
|
||||
Type* lower = Type::Intersect(Type::SignedSmall(zone()), upper, zone());
|
||||
if (!upper->Is(Type::Signed32())) upper = Type::Signed32();
|
||||
Type* lower = Type::Intersect(Type::SignedSmall(), upper, zone());
|
||||
NarrowType(expr, Bounds(lower, upper));
|
||||
break;
|
||||
}
|
||||
@ -689,8 +689,7 @@ void AstTyper::VisitBinaryOperation(BinaryOperation* expr) {
|
||||
case Token::SAR:
|
||||
RECURSE(Visit(expr->left()));
|
||||
RECURSE(Visit(expr->right()));
|
||||
NarrowType(expr,
|
||||
Bounds(Type::SignedSmall(zone()), Type::Signed32(zone())));
|
||||
NarrowType(expr, Bounds(Type::SignedSmall(), Type::Signed32()));
|
||||
break;
|
||||
case Token::SHR:
|
||||
RECURSE(Visit(expr->left()));
|
||||
@ -698,7 +697,7 @@ void AstTyper::VisitBinaryOperation(BinaryOperation* expr) {
|
||||
// TODO(rossberg): The upper bound would be Unsigned32, but since there
|
||||
// is no 'positive Smi' type for the lower bound, we use the smallest
|
||||
// union of Smi and Unsigned32 as upper bound instead.
|
||||
NarrowType(expr, Bounds(Type::SignedSmall(zone()), Type::Number(zone())));
|
||||
NarrowType(expr, Bounds(Type::SignedSmall(), Type::Number()));
|
||||
break;
|
||||
case Token::ADD: {
|
||||
RECURSE(Visit(expr->left()));
|
||||
@ -706,17 +705,19 @@ void AstTyper::VisitBinaryOperation(BinaryOperation* expr) {
|
||||
Bounds l = expr->left()->bounds();
|
||||
Bounds r = expr->right()->bounds();
|
||||
Type* lower =
|
||||
!l.lower->IsInhabited() || !r.lower->IsInhabited() ?
|
||||
Type::None(zone()) :
|
||||
l.lower->Is(Type::String()) || r.lower->Is(Type::String()) ?
|
||||
Type::String(zone()) :
|
||||
l.lower->Is(Type::Number()) && r.lower->Is(Type::Number()) ?
|
||||
Type::SignedSmall(zone()) : Type::None(zone());
|
||||
!l.lower->IsInhabited() || !r.lower->IsInhabited()
|
||||
? Type::None()
|
||||
: l.lower->Is(Type::String()) || r.lower->Is(Type::String())
|
||||
? Type::String()
|
||||
: l.lower->Is(Type::Number()) && r.lower->Is(Type::Number())
|
||||
? Type::SignedSmall()
|
||||
: Type::None();
|
||||
Type* upper =
|
||||
l.upper->Is(Type::String()) || r.upper->Is(Type::String()) ?
|
||||
Type::String(zone()) :
|
||||
l.upper->Is(Type::Number()) && r.upper->Is(Type::Number()) ?
|
||||
Type::Number(zone()) : Type::NumberOrString(zone());
|
||||
l.upper->Is(Type::String()) || r.upper->Is(Type::String())
|
||||
? Type::String()
|
||||
: l.upper->Is(Type::Number()) && r.upper->Is(Type::Number())
|
||||
? Type::Number()
|
||||
: Type::NumberOrString();
|
||||
NarrowType(expr, Bounds(lower, upper));
|
||||
break;
|
||||
}
|
||||
@ -726,7 +727,7 @@ void AstTyper::VisitBinaryOperation(BinaryOperation* expr) {
|
||||
case Token::MOD:
|
||||
RECURSE(Visit(expr->left()));
|
||||
RECURSE(Visit(expr->right()));
|
||||
NarrowType(expr, Bounds(Type::SignedSmall(zone()), Type::Number(zone())));
|
||||
NarrowType(expr, Bounds(Type::SignedSmall(), Type::Number()));
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
@ -748,7 +749,7 @@ void AstTyper::VisitCompareOperation(CompareOperation* expr) {
|
||||
RECURSE(Visit(expr->left()));
|
||||
RECURSE(Visit(expr->right()));
|
||||
|
||||
NarrowType(expr, Bounds(Type::Boolean(zone())));
|
||||
NarrowType(expr, Bounds(Type::Boolean()));
|
||||
}
|
||||
|
||||
|
||||
|
@ -371,25 +371,25 @@ const char* CompareICState::GetStateName(State state) {
|
||||
Type* CompareICState::StateToType(Zone* zone, State state, Handle<Map> map) {
|
||||
switch (state) {
|
||||
case UNINITIALIZED:
|
||||
return Type::None(zone);
|
||||
return Type::None();
|
||||
case BOOLEAN:
|
||||
return Type::Boolean(zone);
|
||||
return Type::Boolean();
|
||||
case SMI:
|
||||
return Type::SignedSmall(zone);
|
||||
return Type::SignedSmall();
|
||||
case NUMBER:
|
||||
return Type::Number(zone);
|
||||
return Type::Number();
|
||||
case STRING:
|
||||
return Type::String(zone);
|
||||
return Type::String();
|
||||
case INTERNALIZED_STRING:
|
||||
return Type::InternalizedString(zone);
|
||||
return Type::InternalizedString();
|
||||
case UNIQUE_NAME:
|
||||
return Type::UniqueName(zone);
|
||||
return Type::UniqueName();
|
||||
case RECEIVER:
|
||||
return Type::Receiver(zone);
|
||||
return Type::Receiver();
|
||||
case KNOWN_RECEIVER:
|
||||
return map.is_null() ? Type::Receiver(zone) : Type::Class(map, zone);
|
||||
return map.is_null() ? Type::Receiver() : Type::Class(map, zone);
|
||||
case GENERIC:
|
||||
return Type::Any(zone);
|
||||
return Type::Any();
|
||||
}
|
||||
UNREACHABLE();
|
||||
return NULL;
|
||||
|
@ -31,12 +31,12 @@ Type* ExternalPointer(Zone* zone) {
|
||||
}
|
||||
} // namespace
|
||||
|
||||
|
||||
Type::FunctionType* CallInterfaceDescriptor::BuildDefaultFunctionType(
|
||||
FunctionType* CallInterfaceDescriptor::BuildDefaultFunctionType(
|
||||
Isolate* isolate, int parameter_count) {
|
||||
Zone* zone = isolate->interface_descriptor_zone();
|
||||
Type::FunctionType* function = Type::FunctionType::New(
|
||||
AnyTagged(zone), Type::Undefined(), parameter_count, zone);
|
||||
FunctionType* function =
|
||||
Type::Function(AnyTagged(zone), Type::Undefined(), parameter_count, zone)
|
||||
->AsFunction();
|
||||
while (parameter_count-- != 0) {
|
||||
function->InitParameter(parameter_count, AnyTagged(zone));
|
||||
}
|
||||
@ -86,12 +86,11 @@ void VoidDescriptor::InitializePlatformSpecific(
|
||||
data->InitializePlatformSpecific(0, nullptr);
|
||||
}
|
||||
|
||||
|
||||
Type::FunctionType* LoadDescriptor::BuildCallInterfaceDescriptorFunctionType(
|
||||
FunctionType* LoadDescriptor::BuildCallInterfaceDescriptorFunctionType(
|
||||
Isolate* isolate, int paramater_count) {
|
||||
Zone* zone = isolate->interface_descriptor_zone();
|
||||
Type::FunctionType* function =
|
||||
Type::FunctionType::New(AnyTagged(zone), Type::Undefined(), 3, zone);
|
||||
FunctionType* function =
|
||||
Type::Function(AnyTagged(zone), Type::Undefined(), 3, zone)->AsFunction();
|
||||
function->InitParameter(0, AnyTagged(zone));
|
||||
function->InitParameter(1, AnyTagged(zone));
|
||||
function->InitParameter(2, SmiType(zone));
|
||||
@ -136,13 +135,12 @@ void VectorStoreTransitionDescriptor::InitializePlatformSpecific(
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Type::FunctionType*
|
||||
FunctionType*
|
||||
StoreTransitionDescriptor::BuildCallInterfaceDescriptorFunctionType(
|
||||
Isolate* isolate, int paramater_count) {
|
||||
Zone* zone = isolate->interface_descriptor_zone();
|
||||
Type::FunctionType* function =
|
||||
Type::FunctionType::New(AnyTagged(zone), Type::Undefined(), 4, zone);
|
||||
FunctionType* function =
|
||||
Type::Function(AnyTagged(zone), Type::Undefined(), 4, zone)->AsFunction();
|
||||
function->InitParameter(0, AnyTagged(zone)); // Receiver
|
||||
function->InitParameter(1, AnyTagged(zone)); // Name
|
||||
function->InitParameter(2, AnyTagged(zone)); // Value
|
||||
@ -150,13 +148,12 @@ StoreTransitionDescriptor::BuildCallInterfaceDescriptorFunctionType(
|
||||
return function;
|
||||
}
|
||||
|
||||
|
||||
Type::FunctionType*
|
||||
FunctionType*
|
||||
LoadGlobalViaContextDescriptor::BuildCallInterfaceDescriptorFunctionType(
|
||||
Isolate* isolate, int paramater_count) {
|
||||
Zone* zone = isolate->interface_descriptor_zone();
|
||||
Type::FunctionType* function =
|
||||
Type::FunctionType::New(AnyTagged(zone), Type::Undefined(), 1, zone);
|
||||
FunctionType* function =
|
||||
Type::Function(AnyTagged(zone), Type::Undefined(), 1, zone)->AsFunction();
|
||||
function->InitParameter(0, UntaggedIntegral32(zone));
|
||||
return function;
|
||||
}
|
||||
@ -168,13 +165,12 @@ void LoadGlobalViaContextDescriptor::InitializePlatformSpecific(
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
|
||||
Type::FunctionType*
|
||||
FunctionType*
|
||||
StoreGlobalViaContextDescriptor::BuildCallInterfaceDescriptorFunctionType(
|
||||
Isolate* isolate, int paramater_count) {
|
||||
Zone* zone = isolate->interface_descriptor_zone();
|
||||
Type::FunctionType* function =
|
||||
Type::FunctionType::New(AnyTagged(zone), Type::Undefined(), 2, zone);
|
||||
FunctionType* function =
|
||||
Type::Function(AnyTagged(zone), Type::Undefined(), 2, zone)->AsFunction();
|
||||
function->InitParameter(0, UntaggedIntegral32(zone));
|
||||
function->InitParameter(1, AnyTagged(zone));
|
||||
return function;
|
||||
@ -243,13 +239,12 @@ void MathPowIntegerDescriptor::InitializePlatformSpecific(
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
|
||||
Type::FunctionType*
|
||||
FunctionType*
|
||||
LoadWithVectorDescriptor::BuildCallInterfaceDescriptorFunctionType(
|
||||
Isolate* isolate, int paramater_count) {
|
||||
Zone* zone = isolate->interface_descriptor_zone();
|
||||
Type::FunctionType* function =
|
||||
Type::FunctionType::New(AnyTagged(zone), Type::Undefined(), 4, zone);
|
||||
FunctionType* function =
|
||||
Type::Function(AnyTagged(zone), Type::Undefined(), 4, zone)->AsFunction();
|
||||
function->InitParameter(0, AnyTagged(zone));
|
||||
function->InitParameter(1, AnyTagged(zone));
|
||||
function->InitParameter(2, SmiType(zone));
|
||||
@ -265,15 +260,15 @@ void LoadWithVectorDescriptor::InitializePlatformSpecific(
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
|
||||
Type::FunctionType*
|
||||
FunctionType*
|
||||
VectorStoreTransitionDescriptor::BuildCallInterfaceDescriptorFunctionType(
|
||||
Isolate* isolate, int paramater_count) {
|
||||
Zone* zone = isolate->interface_descriptor_zone();
|
||||
bool has_slot = !VectorStoreTransitionDescriptor::SlotRegister().is(no_reg);
|
||||
int arg_count = has_slot ? 6 : 5;
|
||||
Type::FunctionType* function = Type::FunctionType::New(
|
||||
AnyTagged(zone), Type::Undefined(), arg_count, zone);
|
||||
FunctionType* function =
|
||||
Type::Function(AnyTagged(zone), Type::Undefined(), arg_count, zone)
|
||||
->AsFunction();
|
||||
int index = 0;
|
||||
function->InitParameter(index++, AnyTagged(zone)); // receiver
|
||||
function->InitParameter(index++, AnyTagged(zone)); // name
|
||||
@ -286,13 +281,11 @@ VectorStoreTransitionDescriptor::BuildCallInterfaceDescriptorFunctionType(
|
||||
return function;
|
||||
}
|
||||
|
||||
|
||||
Type::FunctionType*
|
||||
VectorStoreICDescriptor::BuildCallInterfaceDescriptorFunctionType(
|
||||
FunctionType* VectorStoreICDescriptor::BuildCallInterfaceDescriptorFunctionType(
|
||||
Isolate* isolate, int paramater_count) {
|
||||
Zone* zone = isolate->interface_descriptor_zone();
|
||||
Type::FunctionType* function =
|
||||
Type::FunctionType::New(AnyTagged(zone), Type::Undefined(), 5, zone);
|
||||
FunctionType* function =
|
||||
Type::Function(AnyTagged(zone), Type::Undefined(), 5, zone)->AsFunction();
|
||||
function->InitParameter(0, AnyTagged(zone));
|
||||
function->InitParameter(1, AnyTagged(zone));
|
||||
function->InitParameter(2, AnyTagged(zone));
|
||||
@ -309,13 +302,12 @@ void VectorStoreICDescriptor::InitializePlatformSpecific(
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
|
||||
Type::FunctionType*
|
||||
FunctionType*
|
||||
VectorStoreICTrampolineDescriptor::BuildCallInterfaceDescriptorFunctionType(
|
||||
Isolate* isolate, int paramater_count) {
|
||||
Zone* zone = isolate->interface_descriptor_zone();
|
||||
Type::FunctionType* function =
|
||||
Type::FunctionType::New(AnyTagged(zone), Type::Undefined(), 4, zone);
|
||||
FunctionType* function =
|
||||
Type::Function(AnyTagged(zone), Type::Undefined(), 4, zone)->AsFunction();
|
||||
function->InitParameter(0, AnyTagged(zone));
|
||||
function->InitParameter(1, AnyTagged(zone));
|
||||
function->InitParameter(2, AnyTagged(zone));
|
||||
@ -331,13 +323,11 @@ void VectorStoreICTrampolineDescriptor::InitializePlatformSpecific(
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
|
||||
Type::FunctionType*
|
||||
ApiGetterDescriptor::BuildCallInterfaceDescriptorFunctionType(
|
||||
FunctionType* ApiGetterDescriptor::BuildCallInterfaceDescriptorFunctionType(
|
||||
Isolate* isolate, int paramater_count) {
|
||||
Zone* zone = isolate->interface_descriptor_zone();
|
||||
Type::FunctionType* function =
|
||||
Type::FunctionType::New(AnyTagged(zone), Type::Undefined(), 1, zone);
|
||||
FunctionType* function =
|
||||
Type::Function(AnyTagged(zone), Type::Undefined(), 1, zone)->AsFunction();
|
||||
function->InitParameter(0, ExternalPointer(zone));
|
||||
return function;
|
||||
}
|
||||
@ -356,13 +346,12 @@ void ArgumentsAccessReadDescriptor::InitializePlatformSpecific(
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
|
||||
Type::FunctionType*
|
||||
FunctionType*
|
||||
ArgumentsAccessNewDescriptor::BuildCallInterfaceDescriptorFunctionType(
|
||||
Isolate* isolate, int paramater_count) {
|
||||
Zone* zone = isolate->interface_descriptor_zone();
|
||||
Type::FunctionType* function =
|
||||
Type::FunctionType::New(AnyTagged(zone), Type::Undefined(), 3, zone);
|
||||
FunctionType* function =
|
||||
Type::Function(AnyTagged(zone), Type::Undefined(), 3, zone)->AsFunction();
|
||||
function->InitParameter(0, AnyTagged(zone));
|
||||
function->InitParameter(1, SmiType(zone));
|
||||
function->InitParameter(2, ExternalPointer(zone));
|
||||
@ -376,13 +365,12 @@ void ArgumentsAccessNewDescriptor::InitializePlatformSpecific(
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
|
||||
Type::FunctionType*
|
||||
FunctionType*
|
||||
RestParamAccessDescriptor::BuildCallInterfaceDescriptorFunctionType(
|
||||
Isolate* isolate, int paramater_count) {
|
||||
Zone* zone = isolate->interface_descriptor_zone();
|
||||
Type::FunctionType* function =
|
||||
Type::FunctionType::New(AnyTagged(zone), Type::Undefined(), 3, zone);
|
||||
FunctionType* function =
|
||||
Type::Function(AnyTagged(zone), Type::Undefined(), 3, zone)->AsFunction();
|
||||
function->InitParameter(0, SmiType(zone));
|
||||
function->InitParameter(1, ExternalPointer(zone));
|
||||
function->InitParameter(2, SmiType(zone));
|
||||
@ -410,13 +398,12 @@ void GrowArrayElementsDescriptor::InitializePlatformSpecific(
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
|
||||
Type::FunctionType*
|
||||
FunctionType*
|
||||
FastCloneRegExpDescriptor::BuildCallInterfaceDescriptorFunctionType(
|
||||
Isolate* isolate, int paramater_count) {
|
||||
Zone* zone = isolate->interface_descriptor_zone();
|
||||
Type::FunctionType* function =
|
||||
Type::FunctionType::New(AnyTagged(zone), Type::Undefined(), 4, zone);
|
||||
FunctionType* function =
|
||||
Type::Function(AnyTagged(zone), Type::Undefined(), 4, zone)->AsFunction();
|
||||
function->InitParameter(0, AnyTagged(zone)); // closure
|
||||
function->InitParameter(1, SmiType(zone)); // literal_index
|
||||
function->InitParameter(2, AnyTagged(zone)); // pattern
|
||||
@ -424,63 +411,57 @@ FastCloneRegExpDescriptor::BuildCallInterfaceDescriptorFunctionType(
|
||||
return function;
|
||||
}
|
||||
|
||||
|
||||
Type::FunctionType*
|
||||
FunctionType*
|
||||
FastCloneShallowArrayDescriptor::BuildCallInterfaceDescriptorFunctionType(
|
||||
Isolate* isolate, int paramater_count) {
|
||||
Zone* zone = isolate->interface_descriptor_zone();
|
||||
Type::FunctionType* function =
|
||||
Type::FunctionType::New(AnyTagged(zone), Type::Undefined(), 3, zone);
|
||||
FunctionType* function =
|
||||
Type::Function(AnyTagged(zone), Type::Undefined(), 3, zone)->AsFunction();
|
||||
function->InitParameter(0, AnyTagged(zone));
|
||||
function->InitParameter(1, SmiType(zone));
|
||||
function->InitParameter(2, AnyTagged(zone));
|
||||
return function;
|
||||
}
|
||||
|
||||
|
||||
Type::FunctionType*
|
||||
FunctionType*
|
||||
CreateAllocationSiteDescriptor::BuildCallInterfaceDescriptorFunctionType(
|
||||
Isolate* isolate, int paramater_count) {
|
||||
Zone* zone = isolate->interface_descriptor_zone();
|
||||
Type::FunctionType* function =
|
||||
Type::FunctionType::New(AnyTagged(zone), Type::Undefined(), 2, zone);
|
||||
FunctionType* function =
|
||||
Type::Function(AnyTagged(zone), Type::Undefined(), 2, zone)->AsFunction();
|
||||
function->InitParameter(0, AnyTagged(zone));
|
||||
function->InitParameter(1, SmiType(zone));
|
||||
return function;
|
||||
}
|
||||
|
||||
|
||||
Type::FunctionType*
|
||||
FunctionType*
|
||||
CreateWeakCellDescriptor::BuildCallInterfaceDescriptorFunctionType(
|
||||
Isolate* isolate, int paramater_count) {
|
||||
Zone* zone = isolate->interface_descriptor_zone();
|
||||
Type::FunctionType* function =
|
||||
Type::FunctionType::New(AnyTagged(zone), Type::Undefined(), 3, zone);
|
||||
FunctionType* function =
|
||||
Type::Function(AnyTagged(zone), Type::Undefined(), 3, zone)->AsFunction();
|
||||
function->InitParameter(0, AnyTagged(zone));
|
||||
function->InitParameter(1, SmiType(zone));
|
||||
function->InitParameter(2, AnyTagged(zone));
|
||||
return function;
|
||||
}
|
||||
|
||||
|
||||
Type::FunctionType*
|
||||
FunctionType*
|
||||
CallTrampolineDescriptor::BuildCallInterfaceDescriptorFunctionType(
|
||||
Isolate* isolate, int paramater_count) {
|
||||
Zone* zone = isolate->interface_descriptor_zone();
|
||||
Type::FunctionType* function =
|
||||
Type::FunctionType::New(AnyTagged(zone), Type::Undefined(), 2, zone);
|
||||
FunctionType* function =
|
||||
Type::Function(AnyTagged(zone), Type::Undefined(), 2, zone)->AsFunction();
|
||||
function->InitParameter(0, AnyTagged(zone)); // target
|
||||
function->InitParameter(1, UntaggedIntegral32(zone)); // actual #arguments
|
||||
return function;
|
||||
}
|
||||
|
||||
|
||||
Type::FunctionType*
|
||||
ConstructStubDescriptor::BuildCallInterfaceDescriptorFunctionType(
|
||||
FunctionType* ConstructStubDescriptor::BuildCallInterfaceDescriptorFunctionType(
|
||||
Isolate* isolate, int paramater_count) {
|
||||
Zone* zone = isolate->interface_descriptor_zone();
|
||||
Type::FunctionType* function =
|
||||
Type::FunctionType::New(AnyTagged(zone), Type::Undefined(), 4, zone);
|
||||
FunctionType* function =
|
||||
Type::Function(AnyTagged(zone), Type::Undefined(), 4, zone)->AsFunction();
|
||||
function->InitParameter(0, AnyTagged(zone)); // target
|
||||
function->InitParameter(1, AnyTagged(zone)); // new.target
|
||||
function->InitParameter(2, UntaggedIntegral32(zone)); // actual #arguments
|
||||
@ -488,76 +469,70 @@ ConstructStubDescriptor::BuildCallInterfaceDescriptorFunctionType(
|
||||
return function;
|
||||
}
|
||||
|
||||
|
||||
Type::FunctionType*
|
||||
FunctionType*
|
||||
ConstructTrampolineDescriptor::BuildCallInterfaceDescriptorFunctionType(
|
||||
Isolate* isolate, int paramater_count) {
|
||||
Zone* zone = isolate->interface_descriptor_zone();
|
||||
Type::FunctionType* function =
|
||||
Type::FunctionType::New(AnyTagged(zone), Type::Undefined(), 3, zone);
|
||||
FunctionType* function =
|
||||
Type::Function(AnyTagged(zone), Type::Undefined(), 3, zone)->AsFunction();
|
||||
function->InitParameter(0, AnyTagged(zone)); // target
|
||||
function->InitParameter(1, AnyTagged(zone)); // new.target
|
||||
function->InitParameter(2, UntaggedIntegral32(zone)); // actual #arguments
|
||||
return function;
|
||||
}
|
||||
|
||||
|
||||
Type::FunctionType*
|
||||
FunctionType*
|
||||
CallFunctionWithFeedbackDescriptor::BuildCallInterfaceDescriptorFunctionType(
|
||||
Isolate* isolate, int paramater_count) {
|
||||
Zone* zone = isolate->interface_descriptor_zone();
|
||||
Type::FunctionType* function =
|
||||
Type::FunctionType::New(AnyTagged(zone), Type::Undefined(), 2, zone);
|
||||
FunctionType* function =
|
||||
Type::Function(AnyTagged(zone), Type::Undefined(), 2, zone)->AsFunction();
|
||||
function->InitParameter(0, Type::Receiver()); // JSFunction
|
||||
function->InitParameter(1, SmiType(zone));
|
||||
return function;
|
||||
}
|
||||
|
||||
|
||||
Type::FunctionType* CallFunctionWithFeedbackAndVectorDescriptor::
|
||||
FunctionType* CallFunctionWithFeedbackAndVectorDescriptor::
|
||||
BuildCallInterfaceDescriptorFunctionType(Isolate* isolate,
|
||||
int paramater_count) {
|
||||
Zone* zone = isolate->interface_descriptor_zone();
|
||||
Type::FunctionType* function =
|
||||
Type::FunctionType::New(AnyTagged(zone), Type::Undefined(), 3, zone);
|
||||
FunctionType* function =
|
||||
Type::Function(AnyTagged(zone), Type::Undefined(), 3, zone)->AsFunction();
|
||||
function->InitParameter(0, Type::Receiver()); // JSFunction
|
||||
function->InitParameter(1, SmiType(zone));
|
||||
function->InitParameter(2, AnyTagged(zone));
|
||||
return function;
|
||||
}
|
||||
|
||||
|
||||
Type::FunctionType*
|
||||
FunctionType*
|
||||
ArrayConstructorDescriptor::BuildCallInterfaceDescriptorFunctionType(
|
||||
Isolate* isolate, int paramater_count) {
|
||||
Zone* zone = isolate->interface_descriptor_zone();
|
||||
Type::FunctionType* function =
|
||||
Type::FunctionType::New(AnyTagged(zone), Type::Undefined(), 3, zone);
|
||||
FunctionType* function =
|
||||
Type::Function(AnyTagged(zone), Type::Undefined(), 3, zone)->AsFunction();
|
||||
function->InitParameter(0, Type::Receiver()); // JSFunction
|
||||
function->InitParameter(1, AnyTagged(zone));
|
||||
function->InitParameter(2, UntaggedIntegral32(zone));
|
||||
return function;
|
||||
}
|
||||
|
||||
|
||||
Type::FunctionType*
|
||||
FunctionType*
|
||||
InternalArrayConstructorDescriptor::BuildCallInterfaceDescriptorFunctionType(
|
||||
Isolate* isolate, int paramater_count) {
|
||||
Zone* zone = isolate->interface_descriptor_zone();
|
||||
Type::FunctionType* function =
|
||||
Type::FunctionType::New(AnyTagged(zone), Type::Undefined(), 2, zone);
|
||||
FunctionType* function =
|
||||
Type::Function(AnyTagged(zone), Type::Undefined(), 2, zone)->AsFunction();
|
||||
function->InitParameter(0, Type::Receiver()); // JSFunction
|
||||
function->InitParameter(1, UntaggedIntegral32(zone));
|
||||
return function;
|
||||
}
|
||||
|
||||
|
||||
Type::FunctionType*
|
||||
FunctionType*
|
||||
ArgumentAdaptorDescriptor::BuildCallInterfaceDescriptorFunctionType(
|
||||
Isolate* isolate, int paramater_count) {
|
||||
Zone* zone = isolate->interface_descriptor_zone();
|
||||
Type::FunctionType* function =
|
||||
Type::FunctionType::New(AnyTagged(zone), Type::Undefined(), 4, zone);
|
||||
FunctionType* function =
|
||||
Type::Function(AnyTagged(zone), Type::Undefined(), 4, zone)->AsFunction();
|
||||
function->InitParameter(0, Type::Receiver()); // JSFunction
|
||||
function->InitParameter(1, AnyTagged(zone)); // the new target
|
||||
function->InitParameter(2, UntaggedIntegral32(zone)); // actual #arguments
|
||||
@ -565,13 +540,11 @@ ArgumentAdaptorDescriptor::BuildCallInterfaceDescriptorFunctionType(
|
||||
return function;
|
||||
}
|
||||
|
||||
|
||||
Type::FunctionType*
|
||||
ApiFunctionDescriptor::BuildCallInterfaceDescriptorFunctionType(
|
||||
FunctionType* ApiFunctionDescriptor::BuildCallInterfaceDescriptorFunctionType(
|
||||
Isolate* isolate, int paramater_count) {
|
||||
Zone* zone = isolate->interface_descriptor_zone();
|
||||
Type::FunctionType* function =
|
||||
Type::FunctionType::New(AnyTagged(zone), Type::Undefined(), 5, zone);
|
||||
FunctionType* function =
|
||||
Type::Function(AnyTagged(zone), Type::Undefined(), 5, zone)->AsFunction();
|
||||
function->InitParameter(0, AnyTagged(zone)); // callee
|
||||
function->InitParameter(1, AnyTagged(zone)); // call_data
|
||||
function->InitParameter(2, AnyTagged(zone)); // holder
|
||||
@ -580,13 +553,11 @@ ApiFunctionDescriptor::BuildCallInterfaceDescriptorFunctionType(
|
||||
return function;
|
||||
}
|
||||
|
||||
|
||||
Type::FunctionType*
|
||||
ApiAccessorDescriptor::BuildCallInterfaceDescriptorFunctionType(
|
||||
FunctionType* ApiAccessorDescriptor::BuildCallInterfaceDescriptorFunctionType(
|
||||
Isolate* isolate, int paramater_count) {
|
||||
Zone* zone = isolate->interface_descriptor_zone();
|
||||
Type::FunctionType* function =
|
||||
Type::FunctionType::New(AnyTagged(zone), Type::Undefined(), 4, zone);
|
||||
FunctionType* function =
|
||||
Type::Function(AnyTagged(zone), Type::Undefined(), 4, zone)->AsFunction();
|
||||
function->InitParameter(0, AnyTagged(zone)); // callee
|
||||
function->InitParameter(1, AnyTagged(zone)); // call_data
|
||||
function->InitParameter(2, AnyTagged(zone)); // holder
|
||||
|
@ -89,7 +89,7 @@ class CallInterfaceDescriptorData {
|
||||
// A copy of the passed in registers and param_representations is made
|
||||
// and owned by the CallInterfaceDescriptorData.
|
||||
|
||||
void InitializePlatformIndependent(Type::FunctionType* function_type) {
|
||||
void InitializePlatformIndependent(FunctionType* function_type) {
|
||||
function_type_ = function_type;
|
||||
}
|
||||
|
||||
@ -112,7 +112,7 @@ class CallInterfaceDescriptorData {
|
||||
return platform_specific_descriptor_;
|
||||
}
|
||||
|
||||
Type::FunctionType* function_type() const { return function_type_; }
|
||||
FunctionType* function_type() const { return function_type_; }
|
||||
|
||||
private:
|
||||
int register_param_count_;
|
||||
@ -124,7 +124,7 @@ class CallInterfaceDescriptorData {
|
||||
base::SmartArrayPointer<Register> register_params_;
|
||||
|
||||
// Specifies types for parameters and return
|
||||
Type::FunctionType* function_type_;
|
||||
FunctionType* function_type_;
|
||||
|
||||
PlatformInterfaceDescriptor* platform_specific_descriptor_;
|
||||
|
||||
@ -175,21 +175,19 @@ class CallInterfaceDescriptor {
|
||||
return data()->platform_specific_descriptor();
|
||||
}
|
||||
|
||||
Type::FunctionType* GetFunctionType() const {
|
||||
return data()->function_type();
|
||||
}
|
||||
FunctionType* GetFunctionType() const { return data()->function_type(); }
|
||||
|
||||
static const Register ContextRegister();
|
||||
|
||||
const char* DebugName(Isolate* isolate) const;
|
||||
|
||||
static Type::FunctionType* BuildDefaultFunctionType(Isolate* isolate,
|
||||
int paramater_count);
|
||||
static FunctionType* BuildDefaultFunctionType(Isolate* isolate,
|
||||
int paramater_count);
|
||||
|
||||
protected:
|
||||
const CallInterfaceDescriptorData* data() const { return data_; }
|
||||
|
||||
virtual Type::FunctionType* BuildCallInterfaceDescriptorFunctionType(
|
||||
virtual FunctionType* BuildCallInterfaceDescriptorFunctionType(
|
||||
Isolate* isolate, int register_param_count) {
|
||||
return BuildDefaultFunctionType(isolate, register_param_count);
|
||||
}
|
||||
@ -202,9 +200,8 @@ class CallInterfaceDescriptor {
|
||||
if (!data()->IsInitialized()) {
|
||||
CallInterfaceDescriptorData* d = isolate->call_descriptor_data(key);
|
||||
InitializePlatformSpecific(d);
|
||||
Type::FunctionType* function_type =
|
||||
BuildCallInterfaceDescriptorFunctionType(isolate,
|
||||
d->register_param_count());
|
||||
FunctionType* function_type = BuildCallInterfaceDescriptorFunctionType(
|
||||
isolate, d->register_param_count());
|
||||
d->InitializePlatformIndependent(function_type);
|
||||
}
|
||||
}
|
||||
@ -226,16 +223,14 @@ class CallInterfaceDescriptor {
|
||||
public: \
|
||||
static inline CallDescriptors::Key key();
|
||||
|
||||
|
||||
#define DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(name, base) \
|
||||
DECLARE_DESCRIPTOR(name, base) \
|
||||
protected: \
|
||||
Type::FunctionType* BuildCallInterfaceDescriptorFunctionType( \
|
||||
FunctionType* BuildCallInterfaceDescriptorFunctionType( \
|
||||
Isolate* isolate, int register_param_count) override; \
|
||||
\
|
||||
public:
|
||||
|
||||
|
||||
class VoidDescriptor : public CallInterfaceDescriptor {
|
||||
public:
|
||||
DECLARE_DESCRIPTOR(VoidDescriptor, CallInterfaceDescriptor)
|
||||
|
@ -71,6 +71,7 @@ class CallSite {
|
||||
int32_t pos_;
|
||||
};
|
||||
|
||||
|
||||
#define MESSAGE_TEMPLATES(T) \
|
||||
/* Error */ \
|
||||
T(None, "") \
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "src/conversions-inl.h"
|
||||
#include "src/factory.h"
|
||||
#include "src/field-index-inl.h"
|
||||
#include "src/handles-inl.h"
|
||||
#include "src/heap/heap-inl.h"
|
||||
#include "src/heap/heap.h"
|
||||
#include "src/isolate.h"
|
||||
@ -28,7 +29,6 @@
|
||||
#include "src/prototype.h"
|
||||
#include "src/transitions-inl.h"
|
||||
#include "src/type-feedback-vector-inl.h"
|
||||
#include "src/types-inl.h"
|
||||
#include "src/v8memory.h"
|
||||
|
||||
namespace v8 {
|
||||
|
@ -56,9 +56,7 @@ STATIC_ASSERT(((SKIP_STRINGS | SKIP_SYMBOLS | ONLY_ALL_CAN_READ) &
|
||||
|
||||
|
||||
class Smi;
|
||||
template<class> class TypeImpl;
|
||||
struct ZoneTypeConfig;
|
||||
typedef TypeImpl<ZoneTypeConfig> Type;
|
||||
class Type;
|
||||
class TypeInfo;
|
||||
|
||||
// Type of properties.
|
||||
|
@ -5,7 +5,6 @@
|
||||
#include "src/type-cache.h"
|
||||
|
||||
#include "src/base/lazy-instance.h"
|
||||
#include "src/types-inl.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
@ -200,7 +200,7 @@ void TypeFeedbackOracle::CompareType(TypeFeedbackId id,
|
||||
Handle<Object> info = GetInfo(id);
|
||||
if (!info->IsCode()) {
|
||||
// For some comparisons we don't have ICs, e.g. LiteralCompareTypeof.
|
||||
*left_type = *right_type = *combined_type = Type::None(zone());
|
||||
*left_type = *right_type = *combined_type = Type::None();
|
||||
return;
|
||||
}
|
||||
Handle<Code> code = Handle<Code>::cast(info);
|
||||
@ -235,7 +235,7 @@ void TypeFeedbackOracle::BinaryType(TypeFeedbackId id,
|
||||
// operations covered by the BinaryOpIC we should always have them.
|
||||
DCHECK(op < BinaryOpICState::FIRST_TOKEN ||
|
||||
op > BinaryOpICState::LAST_TOKEN);
|
||||
*left = *right = *result = Type::None(zone());
|
||||
*left = *right = *result = Type::None();
|
||||
*fixed_right_arg = Nothing<int>();
|
||||
*allocation_site = Handle<AllocationSite>::null();
|
||||
return;
|
||||
@ -261,7 +261,7 @@ void TypeFeedbackOracle::BinaryType(TypeFeedbackId id,
|
||||
|
||||
Type* TypeFeedbackOracle::CountType(TypeFeedbackId id) {
|
||||
Handle<Object> object = GetInfo(id);
|
||||
if (!object->IsCode()) return Type::None(zone());
|
||||
if (!object->IsCode()) return Type::None();
|
||||
Handle<Code> code = Handle<Code>::cast(object);
|
||||
DCHECK_EQ(Code::BINARY_OP_IC, code->kind());
|
||||
BinaryOpICState state(isolate(), code->extra_ic_state());
|
||||
|
286
src/types-inl.h
286
src/types-inl.h
@ -1,286 +0,0 @@
|
||||
// Copyright 2014 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.
|
||||
|
||||
#ifndef V8_TYPES_INL_H_
|
||||
#define V8_TYPES_INL_H_
|
||||
|
||||
#include "src/types.h"
|
||||
|
||||
#include "src/factory.h"
|
||||
#include "src/handles-inl.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// TypeImpl
|
||||
|
||||
template<class Config>
|
||||
typename TypeImpl<Config>::bitset TypeImpl<Config>::BitsetType::SignedSmall() {
|
||||
return i::SmiValuesAre31Bits() ? kSigned31 : kSigned32;
|
||||
}
|
||||
|
||||
|
||||
template<class Config>
|
||||
typename TypeImpl<Config>::bitset
|
||||
TypeImpl<Config>::BitsetType::UnsignedSmall() {
|
||||
return i::SmiValuesAre31Bits() ? kUnsigned30 : kUnsigned31;
|
||||
}
|
||||
|
||||
|
||||
#define CONSTRUCT_SIMD_TYPE(NAME, Name, name, lane_count, lane_type) \
|
||||
template<class Config> \
|
||||
typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Name( \
|
||||
Isolate* isolate, Region* region) { \
|
||||
return Class(i::handle(isolate->heap()->name##_map()), region); \
|
||||
}
|
||||
SIMD128_TYPES(CONSTRUCT_SIMD_TYPE)
|
||||
#undef CONSTRUCT_SIMD_TYPE
|
||||
|
||||
|
||||
template<class Config>
|
||||
TypeImpl<Config>* TypeImpl<Config>::cast(typename Config::Base* object) {
|
||||
TypeImpl* t = static_cast<TypeImpl*>(object);
|
||||
DCHECK(t->IsBitset() || t->IsClass() || t->IsConstant() || t->IsRange() ||
|
||||
t->IsUnion() || t->IsArray() || t->IsFunction() || t->IsContext());
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
// Most precise _current_ type of a value (usually its class).
|
||||
template<class Config>
|
||||
typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::NowOf(
|
||||
i::Object* value, Region* region) {
|
||||
if (value->IsSmi() ||
|
||||
i::HeapObject::cast(value)->map()->instance_type() == HEAP_NUMBER_TYPE) {
|
||||
return Of(value, region);
|
||||
}
|
||||
return Class(i::handle(i::HeapObject::cast(value)->map()), region);
|
||||
}
|
||||
|
||||
|
||||
template<class Config>
|
||||
bool TypeImpl<Config>::NowContains(i::Object* value) {
|
||||
DisallowHeapAllocation no_allocation;
|
||||
if (this->IsAny()) return true;
|
||||
if (value->IsHeapObject()) {
|
||||
i::Map* map = i::HeapObject::cast(value)->map();
|
||||
for (Iterator<i::Map> it = this->Classes(); !it.Done(); it.Advance()) {
|
||||
if (*it.Current() == map) return true;
|
||||
}
|
||||
}
|
||||
return this->Contains(value);
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// ZoneTypeConfig
|
||||
|
||||
// static
|
||||
template<class T>
|
||||
T* ZoneTypeConfig::handle(T* type) {
|
||||
return type;
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
template<class T>
|
||||
T* ZoneTypeConfig::cast(Type* type) {
|
||||
return static_cast<T*>(type);
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
bool ZoneTypeConfig::is_bitset(Type* type) {
|
||||
return reinterpret_cast<uintptr_t>(type) & 1;
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
bool ZoneTypeConfig::is_struct(Type* type, int tag) {
|
||||
DCHECK(tag != kRangeStructTag);
|
||||
if (is_bitset(type)) return false;
|
||||
int type_tag = struct_tag(as_struct(type));
|
||||
return type_tag == tag;
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
bool ZoneTypeConfig::is_range(Type* type) {
|
||||
if (is_bitset(type)) return false;
|
||||
int type_tag = struct_tag(as_struct(type));
|
||||
return type_tag == kRangeStructTag;
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
bool ZoneTypeConfig::is_class(Type* type) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
ZoneTypeConfig::Type::bitset ZoneTypeConfig::as_bitset(Type* type) {
|
||||
DCHECK(is_bitset(type));
|
||||
return static_cast<Type::bitset>(reinterpret_cast<uintptr_t>(type) ^ 1u);
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
ZoneTypeConfig::Struct* ZoneTypeConfig::as_struct(Type* type) {
|
||||
DCHECK(!is_bitset(type));
|
||||
return reinterpret_cast<Struct*>(type);
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
ZoneTypeConfig::Range* ZoneTypeConfig::as_range(Type* type) {
|
||||
DCHECK(!is_bitset(type));
|
||||
return reinterpret_cast<Range*>(type);
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
i::Handle<i::Map> ZoneTypeConfig::as_class(Type* type) {
|
||||
UNREACHABLE();
|
||||
return i::Handle<i::Map>();
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
ZoneTypeConfig::Type* ZoneTypeConfig::from_bitset(Type::bitset bitset) {
|
||||
return reinterpret_cast<Type*>(static_cast<uintptr_t>(bitset | 1u));
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
ZoneTypeConfig::Type* ZoneTypeConfig::from_bitset(
|
||||
Type::bitset bitset, Zone* Zone) {
|
||||
return from_bitset(bitset);
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
ZoneTypeConfig::Type* ZoneTypeConfig::from_struct(Struct* structure) {
|
||||
return reinterpret_cast<Type*>(structure);
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
ZoneTypeConfig::Type* ZoneTypeConfig::from_range(Range* range) {
|
||||
return reinterpret_cast<Type*>(range);
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
ZoneTypeConfig::Type* ZoneTypeConfig::from_class(
|
||||
i::Handle<i::Map> map, Zone* zone) {
|
||||
return from_bitset(0);
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
ZoneTypeConfig::Struct* ZoneTypeConfig::struct_create(
|
||||
int tag, int length, Zone* zone) {
|
||||
DCHECK(tag != kRangeStructTag);
|
||||
Struct* structure = reinterpret_cast<Struct*>(
|
||||
zone->New(sizeof(void*) * (length + 2))); // NOLINT
|
||||
structure[0] = reinterpret_cast<void*>(tag);
|
||||
structure[1] = reinterpret_cast<void*>(length);
|
||||
return structure;
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
void ZoneTypeConfig::struct_shrink(Struct* structure, int length) {
|
||||
DCHECK(0 <= length && length <= struct_length(structure));
|
||||
structure[1] = reinterpret_cast<void*>(length);
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
int ZoneTypeConfig::struct_tag(Struct* structure) {
|
||||
return static_cast<int>(reinterpret_cast<intptr_t>(structure[0]));
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
int ZoneTypeConfig::struct_length(Struct* structure) {
|
||||
return static_cast<int>(reinterpret_cast<intptr_t>(structure[1]));
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
Type* ZoneTypeConfig::struct_get(Struct* structure, int i) {
|
||||
DCHECK(0 <= i && i <= struct_length(structure));
|
||||
return static_cast<Type*>(structure[2 + i]);
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
void ZoneTypeConfig::struct_set(Struct* structure, int i, Type* x) {
|
||||
DCHECK(0 <= i && i <= struct_length(structure));
|
||||
structure[2 + i] = x;
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
template<class V>
|
||||
i::Handle<V> ZoneTypeConfig::struct_get_value(Struct* structure, int i) {
|
||||
DCHECK(0 <= i && i <= struct_length(structure));
|
||||
return i::Handle<V>(static_cast<V**>(structure[2 + i]));
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
template<class V>
|
||||
void ZoneTypeConfig::struct_set_value(
|
||||
Struct* structure, int i, i::Handle<V> x) {
|
||||
DCHECK(0 <= i && i <= struct_length(structure));
|
||||
structure[2 + i] = x.location();
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
ZoneTypeConfig::Range* ZoneTypeConfig::range_create(Zone* zone) {
|
||||
Range* range = reinterpret_cast<Range*>(zone->New(sizeof(Range))); // NOLINT
|
||||
range->tag = reinterpret_cast<void*>(kRangeStructTag);
|
||||
range->bitset = 0;
|
||||
range->limits[0] = 1;
|
||||
range->limits[1] = 0;
|
||||
return range;
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
int ZoneTypeConfig::range_get_bitset(ZoneTypeConfig::Range* range) {
|
||||
return range->bitset;
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
void ZoneTypeConfig::range_set_bitset(ZoneTypeConfig::Range* range, int value) {
|
||||
range->bitset = value;
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
double ZoneTypeConfig::range_get_double(ZoneTypeConfig::Range* range,
|
||||
int index) {
|
||||
DCHECK(index >= 0 && index < 2);
|
||||
return range->limits[index];
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
void ZoneTypeConfig::range_set_double(ZoneTypeConfig::Range* range, int index,
|
||||
double value, Zone*) {
|
||||
DCHECK(index >= 0 && index < 2);
|
||||
range->limits[index] = value;
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
||||
#endif // V8_TYPES_INL_H_
|
492
src/types.cc
492
src/types.cc
@ -6,8 +6,8 @@
|
||||
|
||||
#include "src/types.h"
|
||||
|
||||
#include "src/handles-inl.h"
|
||||
#include "src/ostreams.h"
|
||||
#include "src/types-inl.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
@ -16,19 +16,17 @@ namespace internal {
|
||||
// NOTE: If code is marked as being a "shortcut", this means that removing
|
||||
// the code won't affect the semantics of the surrounding function definition.
|
||||
|
||||
// static
|
||||
bool Type::IsInteger(i::Object* x) {
|
||||
return x->IsNumber() && Type::IsInteger(x->Number());
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Range-related helper functions.
|
||||
|
||||
template <class Config>
|
||||
bool TypeImpl<Config>::Limits::IsEmpty() {
|
||||
return this->min > this->max;
|
||||
}
|
||||
bool RangeType::Limits::IsEmpty() { return this->min > this->max; }
|
||||
|
||||
|
||||
template<class Config>
|
||||
typename TypeImpl<Config>::Limits TypeImpl<Config>::Limits::Intersect(
|
||||
Limits lhs, Limits rhs) {
|
||||
RangeType::Limits RangeType::Limits::Intersect(Limits lhs, Limits rhs) {
|
||||
DisallowHeapAllocation no_allocation;
|
||||
Limits result(lhs);
|
||||
if (lhs.min < rhs.min) result.min = rhs.min;
|
||||
@ -36,10 +34,7 @@ typename TypeImpl<Config>::Limits TypeImpl<Config>::Limits::Intersect(
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
template <class Config>
|
||||
typename TypeImpl<Config>::Limits TypeImpl<Config>::Limits::Union(
|
||||
Limits lhs, Limits rhs) {
|
||||
RangeType::Limits RangeType::Limits::Union(Limits lhs, Limits rhs) {
|
||||
DisallowHeapAllocation no_allocation;
|
||||
if (lhs.IsEmpty()) return rhs;
|
||||
if (rhs.IsEmpty()) return lhs;
|
||||
@ -49,38 +44,26 @@ typename TypeImpl<Config>::Limits TypeImpl<Config>::Limits::Union(
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
template<class Config>
|
||||
bool TypeImpl<Config>::Overlap(
|
||||
typename TypeImpl<Config>::RangeType* lhs,
|
||||
typename TypeImpl<Config>::RangeType* rhs) {
|
||||
bool Type::Overlap(RangeType* lhs, RangeType* rhs) {
|
||||
DisallowHeapAllocation no_allocation;
|
||||
return !Limits::Intersect(Limits(lhs), Limits(rhs)).IsEmpty();
|
||||
return !RangeType::Limits::Intersect(RangeType::Limits(lhs),
|
||||
RangeType::Limits(rhs))
|
||||
.IsEmpty();
|
||||
}
|
||||
|
||||
|
||||
template<class Config>
|
||||
bool TypeImpl<Config>::Contains(
|
||||
typename TypeImpl<Config>::RangeType* lhs,
|
||||
typename TypeImpl<Config>::RangeType* rhs) {
|
||||
bool Type::Contains(RangeType* lhs, RangeType* rhs) {
|
||||
DisallowHeapAllocation no_allocation;
|
||||
return lhs->Min() <= rhs->Min() && rhs->Max() <= lhs->Max();
|
||||
}
|
||||
|
||||
|
||||
template <class Config>
|
||||
bool TypeImpl<Config>::Contains(typename TypeImpl<Config>::RangeType* lhs,
|
||||
typename TypeImpl<Config>::ConstantType* rhs) {
|
||||
bool Type::Contains(RangeType* lhs, ConstantType* rhs) {
|
||||
DisallowHeapAllocation no_allocation;
|
||||
return IsInteger(*rhs->Value()) &&
|
||||
lhs->Min() <= rhs->Value()->Number() &&
|
||||
rhs->Value()->Number() <= lhs->Max();
|
||||
}
|
||||
|
||||
|
||||
template<class Config>
|
||||
bool TypeImpl<Config>::Contains(
|
||||
typename TypeImpl<Config>::RangeType* range, i::Object* val) {
|
||||
bool Type::Contains(RangeType* range, i::Object* val) {
|
||||
DisallowHeapAllocation no_allocation;
|
||||
return IsInteger(val) &&
|
||||
range->Min() <= val->Number() && val->Number() <= range->Max();
|
||||
@ -90,8 +73,7 @@ bool TypeImpl<Config>::Contains(
|
||||
// -----------------------------------------------------------------------------
|
||||
// Min and Max computation.
|
||||
|
||||
template<class Config>
|
||||
double TypeImpl<Config>::Min() {
|
||||
double Type::Min() {
|
||||
DCHECK(this->SemanticIs(Number()));
|
||||
if (this->IsBitset()) return BitsetType::Min(this->AsBitset());
|
||||
if (this->IsUnion()) {
|
||||
@ -107,9 +89,7 @@ double TypeImpl<Config>::Min() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
template<class Config>
|
||||
double TypeImpl<Config>::Max() {
|
||||
double Type::Max() {
|
||||
DCHECK(this->SemanticIs(Number()));
|
||||
if (this->IsBitset()) return BitsetType::Max(this->AsBitset());
|
||||
if (this->IsUnion()) {
|
||||
@ -131,12 +111,10 @@ double TypeImpl<Config>::Max() {
|
||||
|
||||
|
||||
// The largest bitset subsumed by this type.
|
||||
template<class Config>
|
||||
typename TypeImpl<Config>::bitset
|
||||
TypeImpl<Config>::BitsetType::Glb(TypeImpl* type) {
|
||||
Type::bitset BitsetType::Glb(Type* type) {
|
||||
DisallowHeapAllocation no_allocation;
|
||||
// Fast case.
|
||||
if (type->IsBitset()) {
|
||||
if (IsBitset(type)) {
|
||||
return type->AsBitset();
|
||||
} else if (type->IsUnion()) {
|
||||
SLOW_DCHECK(type->AsUnion()->Wellformed());
|
||||
@ -153,11 +131,9 @@ TypeImpl<Config>::BitsetType::Glb(TypeImpl* type) {
|
||||
|
||||
|
||||
// The smallest bitset subsuming this type, possibly not a proper one.
|
||||
template<class Config>
|
||||
typename TypeImpl<Config>::bitset
|
||||
TypeImpl<Config>::BitsetType::Lub(TypeImpl* type) {
|
||||
Type::bitset BitsetType::Lub(Type* type) {
|
||||
DisallowHeapAllocation no_allocation;
|
||||
if (type->IsBitset()) return type->AsBitset();
|
||||
if (IsBitset(type)) return type->AsBitset();
|
||||
if (type->IsUnion()) {
|
||||
// Take the representation from the first element, which is always
|
||||
// a bitset.
|
||||
@ -179,10 +155,7 @@ TypeImpl<Config>::BitsetType::Lub(TypeImpl* type) {
|
||||
return kNone;
|
||||
}
|
||||
|
||||
|
||||
template<class Config>
|
||||
typename TypeImpl<Config>::bitset
|
||||
TypeImpl<Config>::BitsetType::Lub(i::Map* map) {
|
||||
Type::bitset BitsetType::Lub(i::Map* map) {
|
||||
DisallowHeapAllocation no_allocation;
|
||||
switch (map->instance_type()) {
|
||||
case STRING_TYPE:
|
||||
@ -318,10 +291,7 @@ TypeImpl<Config>::BitsetType::Lub(i::Map* map) {
|
||||
return kNone;
|
||||
}
|
||||
|
||||
|
||||
template<class Config>
|
||||
typename TypeImpl<Config>::bitset
|
||||
TypeImpl<Config>::BitsetType::Lub(i::Object* value) {
|
||||
Type::bitset BitsetType::Lub(i::Object* value) {
|
||||
DisallowHeapAllocation no_allocation;
|
||||
if (value->IsNumber()) {
|
||||
return Lub(value->Number()) &
|
||||
@ -330,10 +300,7 @@ TypeImpl<Config>::BitsetType::Lub(i::Object* value) {
|
||||
return Lub(i::HeapObject::cast(value)->map());
|
||||
}
|
||||
|
||||
|
||||
template<class Config>
|
||||
typename TypeImpl<Config>::bitset
|
||||
TypeImpl<Config>::BitsetType::Lub(double value) {
|
||||
Type::bitset BitsetType::Lub(double value) {
|
||||
DisallowHeapAllocation no_allocation;
|
||||
if (i::IsMinusZero(value)) return kMinusZero;
|
||||
if (std::isnan(value)) return kNaN;
|
||||
@ -343,36 +310,24 @@ TypeImpl<Config>::BitsetType::Lub(double value) {
|
||||
|
||||
|
||||
// Minimum values of plain numeric bitsets.
|
||||
template <class Config>
|
||||
const typename TypeImpl<Config>::BitsetType::Boundary
|
||||
TypeImpl<Config>::BitsetType::BoundariesArray[] = {
|
||||
{kOtherNumber, kPlainNumber, -V8_INFINITY},
|
||||
{kOtherSigned32, kNegative32, kMinInt},
|
||||
{kNegative31, kNegative31, -0x40000000},
|
||||
{kUnsigned30, kUnsigned30, 0},
|
||||
{kOtherUnsigned31, kUnsigned31, 0x40000000},
|
||||
{kOtherUnsigned32, kUnsigned32, 0x80000000},
|
||||
{kOtherNumber, kPlainNumber, static_cast<double>(kMaxUInt32) + 1}};
|
||||
const BitsetType::Boundary BitsetType::BoundariesArray[] = {
|
||||
{kOtherNumber, kPlainNumber, -V8_INFINITY},
|
||||
{kOtherSigned32, kNegative32, kMinInt},
|
||||
{kNegative31, kNegative31, -0x40000000},
|
||||
{kUnsigned30, kUnsigned30, 0},
|
||||
{kOtherUnsigned31, kUnsigned31, 0x40000000},
|
||||
{kOtherUnsigned32, kUnsigned32, 0x80000000},
|
||||
{kOtherNumber, kPlainNumber, static_cast<double>(kMaxUInt32) + 1}};
|
||||
|
||||
const BitsetType::Boundary* BitsetType::Boundaries() { return BoundariesArray; }
|
||||
|
||||
template <class Config>
|
||||
const typename TypeImpl<Config>::BitsetType::Boundary*
|
||||
TypeImpl<Config>::BitsetType::Boundaries() {
|
||||
return BoundariesArray;
|
||||
}
|
||||
|
||||
|
||||
template <class Config>
|
||||
size_t TypeImpl<Config>::BitsetType::BoundariesSize() {
|
||||
size_t BitsetType::BoundariesSize() {
|
||||
// Windows doesn't like arraysize here.
|
||||
// return arraysize(BoundariesArray);
|
||||
return 7;
|
||||
}
|
||||
|
||||
|
||||
template <class Config>
|
||||
typename TypeImpl<Config>::bitset TypeImpl<Config>::BitsetType::ExpandInternals(
|
||||
typename TypeImpl<Config>::bitset bits) {
|
||||
Type::bitset BitsetType::ExpandInternals(Type::bitset bits) {
|
||||
DisallowHeapAllocation no_allocation;
|
||||
if (!(bits & SEMANTIC(kPlainNumber))) return bits; // Shortcut.
|
||||
const Boundary* boundaries = Boundaries();
|
||||
@ -384,10 +339,7 @@ typename TypeImpl<Config>::bitset TypeImpl<Config>::BitsetType::ExpandInternals(
|
||||
return bits;
|
||||
}
|
||||
|
||||
|
||||
template<class Config>
|
||||
typename TypeImpl<Config>::bitset
|
||||
TypeImpl<Config>::BitsetType::Lub(double min, double max) {
|
||||
Type::bitset BitsetType::Lub(double min, double max) {
|
||||
DisallowHeapAllocation no_allocation;
|
||||
int lub = kNone;
|
||||
const Boundary* mins = Boundaries();
|
||||
@ -401,17 +353,11 @@ TypeImpl<Config>::BitsetType::Lub(double min, double max) {
|
||||
return lub | mins[BoundariesSize() - 1].internal;
|
||||
}
|
||||
|
||||
|
||||
template <class Config>
|
||||
typename TypeImpl<Config>::bitset TypeImpl<Config>::BitsetType::NumberBits(
|
||||
bitset bits) {
|
||||
Type::bitset BitsetType::NumberBits(bitset bits) {
|
||||
return SEMANTIC(bits & kPlainNumber);
|
||||
}
|
||||
|
||||
|
||||
template <class Config>
|
||||
typename TypeImpl<Config>::bitset TypeImpl<Config>::BitsetType::Glb(
|
||||
double min, double max) {
|
||||
Type::bitset BitsetType::Glb(double min, double max) {
|
||||
DisallowHeapAllocation no_allocation;
|
||||
int glb = kNone;
|
||||
const Boundary* mins = Boundaries();
|
||||
@ -430,9 +376,7 @@ typename TypeImpl<Config>::bitset TypeImpl<Config>::BitsetType::Glb(
|
||||
return glb & ~(SEMANTIC(kOtherNumber));
|
||||
}
|
||||
|
||||
|
||||
template <class Config>
|
||||
double TypeImpl<Config>::BitsetType::Min(bitset bits) {
|
||||
double BitsetType::Min(bitset bits) {
|
||||
DisallowHeapAllocation no_allocation;
|
||||
DCHECK(Is(SEMANTIC(bits), kNumber));
|
||||
const Boundary* mins = Boundaries();
|
||||
@ -446,9 +390,7 @@ double TypeImpl<Config>::BitsetType::Min(bitset bits) {
|
||||
return std::numeric_limits<double>::quiet_NaN();
|
||||
}
|
||||
|
||||
|
||||
template<class Config>
|
||||
double TypeImpl<Config>::BitsetType::Max(bitset bits) {
|
||||
double BitsetType::Max(bitset bits) {
|
||||
DisallowHeapAllocation no_allocation;
|
||||
DCHECK(Is(SEMANTIC(bits), kNumber));
|
||||
const Boundary* mins = Boundaries();
|
||||
@ -470,9 +412,7 @@ double TypeImpl<Config>::BitsetType::Max(bitset bits) {
|
||||
// -----------------------------------------------------------------------------
|
||||
// Predicates.
|
||||
|
||||
|
||||
template<class Config>
|
||||
bool TypeImpl<Config>::SimplyEquals(TypeImpl* that) {
|
||||
bool Type::SimplyEquals(Type* that) {
|
||||
DisallowHeapAllocation no_allocation;
|
||||
if (this->IsClass()) {
|
||||
return that->IsClass()
|
||||
@ -520,16 +460,13 @@ bool TypeImpl<Config>::SimplyEquals(TypeImpl* that) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
template <class Config>
|
||||
typename TypeImpl<Config>::bitset TypeImpl<Config>::Representation() {
|
||||
Type::bitset Type::Representation() {
|
||||
return REPRESENTATION(this->BitsetLub());
|
||||
}
|
||||
|
||||
|
||||
// Check if [this] <= [that].
|
||||
template<class Config>
|
||||
bool TypeImpl<Config>::SlowIs(TypeImpl* that) {
|
||||
bool Type::SlowIs(Type* that) {
|
||||
DisallowHeapAllocation no_allocation;
|
||||
|
||||
// Fast bitset cases
|
||||
@ -553,8 +490,7 @@ bool TypeImpl<Config>::SlowIs(TypeImpl* that) {
|
||||
|
||||
// Check if SEMANTIC([this]) <= SEMANTIC([that]). The result of the method
|
||||
// should be independent of the representation axis of the types.
|
||||
template <class Config>
|
||||
bool TypeImpl<Config>::SemanticIs(TypeImpl* that) {
|
||||
bool Type::SemanticIs(Type* that) {
|
||||
DisallowHeapAllocation no_allocation;
|
||||
|
||||
if (this == that) return true;
|
||||
@ -577,7 +513,7 @@ bool TypeImpl<Config>::SemanticIs(TypeImpl* that) {
|
||||
// T <= (T1 \/ ... \/ Tn) if (T <= T1) \/ ... \/ (T <= Tn)
|
||||
if (that->IsUnion()) {
|
||||
for (int i = 0, n = that->AsUnion()->Length(); i < n; ++i) {
|
||||
if (this->SemanticIs(that->AsUnion()->Get(i)->unhandle())) return true;
|
||||
if (this->SemanticIs(that->AsUnion()->Get(i))) return true;
|
||||
if (i > 1 && this->IsRange()) return false; // Shortcut.
|
||||
}
|
||||
return false;
|
||||
@ -593,9 +529,28 @@ bool TypeImpl<Config>::SemanticIs(TypeImpl* that) {
|
||||
return this->SimplyEquals(that);
|
||||
}
|
||||
|
||||
// Most precise _current_ type of a value (usually its class).
|
||||
Type* Type::NowOf(i::Object* value, Zone* zone) {
|
||||
if (value->IsSmi() ||
|
||||
i::HeapObject::cast(value)->map()->instance_type() == HEAP_NUMBER_TYPE) {
|
||||
return Of(value, zone);
|
||||
}
|
||||
return Class(i::handle(i::HeapObject::cast(value)->map()), zone);
|
||||
}
|
||||
|
||||
template<class Config>
|
||||
bool TypeImpl<Config>::NowIs(TypeImpl* that) {
|
||||
bool Type::NowContains(i::Object* value) {
|
||||
DisallowHeapAllocation no_allocation;
|
||||
if (this->IsAny()) return true;
|
||||
if (value->IsHeapObject()) {
|
||||
i::Map* map = i::HeapObject::cast(value)->map();
|
||||
for (Iterator<i::Map> it = this->Classes(); !it.Done(); it.Advance()) {
|
||||
if (*it.Current() == map) return true;
|
||||
}
|
||||
}
|
||||
return this->Contains(value);
|
||||
}
|
||||
|
||||
bool Type::NowIs(Type* that) {
|
||||
DisallowHeapAllocation no_allocation;
|
||||
|
||||
// TODO(rossberg): this is incorrect for
|
||||
@ -615,16 +570,14 @@ bool TypeImpl<Config>::NowIs(TypeImpl* that) {
|
||||
|
||||
|
||||
// Check if [this] contains only (currently) stable classes.
|
||||
template<class Config>
|
||||
bool TypeImpl<Config>::NowStable() {
|
||||
bool Type::NowStable() {
|
||||
DisallowHeapAllocation no_allocation;
|
||||
return !this->IsClass() || this->AsClass()->Map()->is_stable();
|
||||
}
|
||||
|
||||
|
||||
// Check if [this] and [that] overlap.
|
||||
template<class Config>
|
||||
bool TypeImpl<Config>::Maybe(TypeImpl* that) {
|
||||
bool Type::Maybe(Type* that) {
|
||||
DisallowHeapAllocation no_allocation;
|
||||
|
||||
// Take care of the representation part (and also approximate
|
||||
@ -635,8 +588,7 @@ bool TypeImpl<Config>::Maybe(TypeImpl* that) {
|
||||
return SemanticMaybe(that);
|
||||
}
|
||||
|
||||
template <class Config>
|
||||
bool TypeImpl<Config>::SemanticMaybe(TypeImpl* that) {
|
||||
bool Type::SemanticMaybe(Type* that) {
|
||||
DisallowHeapAllocation no_allocation;
|
||||
|
||||
// (T1 \/ ... \/ Tn) overlaps T if (T1 overlaps T) \/ ... \/ (Tn overlaps T)
|
||||
@ -650,7 +602,7 @@ bool TypeImpl<Config>::SemanticMaybe(TypeImpl* that) {
|
||||
// T overlaps (T1 \/ ... \/ Tn) if (T overlaps T1) \/ ... \/ (T overlaps Tn)
|
||||
if (that->IsUnion()) {
|
||||
for (int i = 0, n = that->AsUnion()->Length(); i < n; ++i) {
|
||||
if (this->SemanticMaybe(that->AsUnion()->Get(i)->unhandle())) return true;
|
||||
if (this->SemanticMaybe(that->AsUnion()->Get(i))) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -690,33 +642,28 @@ bool TypeImpl<Config>::SemanticMaybe(TypeImpl* that) {
|
||||
|
||||
|
||||
// Return the range in [this], or [NULL].
|
||||
template<class Config>
|
||||
typename TypeImpl<Config>::RangeType* TypeImpl<Config>::GetRange() {
|
||||
Type* Type::GetRange() {
|
||||
DisallowHeapAllocation no_allocation;
|
||||
if (this->IsRange()) return this->AsRange();
|
||||
if (this->IsRange()) return this;
|
||||
if (this->IsUnion() && this->AsUnion()->Get(1)->IsRange()) {
|
||||
return this->AsUnion()->Get(1)->AsRange();
|
||||
return this->AsUnion()->Get(1);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
template<class Config>
|
||||
bool TypeImpl<Config>::Contains(i::Object* value) {
|
||||
bool Type::Contains(i::Object* value) {
|
||||
DisallowHeapAllocation no_allocation;
|
||||
for (Iterator<i::Object> it = this->Constants(); !it.Done(); it.Advance()) {
|
||||
if (*it.Current() == value) return true;
|
||||
}
|
||||
if (IsInteger(value)) {
|
||||
RangeType* range = this->GetRange();
|
||||
if (range != NULL && Contains(range, value)) return true;
|
||||
Type* range = this->GetRange();
|
||||
if (range != NULL && Contains(range->AsRange(), value)) return true;
|
||||
}
|
||||
return BitsetType::New(BitsetType::Lub(value))->Is(this);
|
||||
}
|
||||
|
||||
|
||||
template<class Config>
|
||||
bool TypeImpl<Config>::UnionType::Wellformed() {
|
||||
bool UnionType::Wellformed() {
|
||||
DisallowHeapAllocation no_allocation;
|
||||
// This checks the invariants of the union representation:
|
||||
// 1. There are at least two elements.
|
||||
@ -735,7 +682,7 @@ bool TypeImpl<Config>::UnionType::Wellformed() {
|
||||
DCHECK(!this->Get(i)->IsUnion()); // (4)
|
||||
for (int j = 0; j < this->Length(); ++j) {
|
||||
if (i != j && i != 0)
|
||||
DCHECK(!this->Get(i)->SemanticIs(this->Get(j)->unhandle())); // (5)
|
||||
DCHECK(!this->Get(i)->SemanticIs(this->Get(j))); // (5)
|
||||
}
|
||||
}
|
||||
DCHECK(!this->Get(1)->IsRange() ||
|
||||
@ -755,14 +702,10 @@ static bool AddIsSafe(int x, int y) {
|
||||
y >= std::numeric_limits<int>::min() - x;
|
||||
}
|
||||
|
||||
|
||||
template<class Config>
|
||||
typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Intersect(
|
||||
TypeHandle type1, TypeHandle type2, Region* region) {
|
||||
|
||||
Type* Type::Intersect(Type* type1, Type* type2, Zone* zone) {
|
||||
// Fast case: bit sets.
|
||||
if (type1->IsBitset() && type2->IsBitset()) {
|
||||
return BitsetType::New(type1->AsBitset() & type2->AsBitset(), region);
|
||||
return BitsetType::New(type1->AsBitset() & type2->AsBitset());
|
||||
}
|
||||
|
||||
// Fast case: top or bottom types.
|
||||
@ -786,47 +729,45 @@ typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Intersect(
|
||||
// semi-fast case above - we should behave the same way regardless of
|
||||
// representations. Intersection with a universal bitset should only update
|
||||
// the representations.
|
||||
if (type1->SemanticIs(type2->unhandle())) {
|
||||
type2 = Any(region);
|
||||
} else if (type2->SemanticIs(type1->unhandle())) {
|
||||
type1 = Any(region);
|
||||
if (type1->SemanticIs(type2)) {
|
||||
type2 = Any();
|
||||
} else if (type2->SemanticIs(type1)) {
|
||||
type1 = Any();
|
||||
}
|
||||
|
||||
bitset bits =
|
||||
SEMANTIC(type1->BitsetGlb() & type2->BitsetGlb()) | representation;
|
||||
int size1 = type1->IsUnion() ? type1->AsUnion()->Length() : 1;
|
||||
int size2 = type2->IsUnion() ? type2->AsUnion()->Length() : 1;
|
||||
if (!AddIsSafe(size1, size2)) return Any(region);
|
||||
if (!AddIsSafe(size1, size2)) return Any();
|
||||
int size = size1 + size2;
|
||||
if (!AddIsSafe(size, 2)) return Any(region);
|
||||
if (!AddIsSafe(size, 2)) return Any();
|
||||
size += 2;
|
||||
UnionHandle result = UnionType::New(size, region);
|
||||
Type* result_type = UnionType::New(size, zone);
|
||||
UnionType* result = result_type->AsUnion();
|
||||
size = 0;
|
||||
|
||||
// Deal with bitsets.
|
||||
result->Set(size++, BitsetType::New(bits, region));
|
||||
result->Set(size++, BitsetType::New(bits));
|
||||
|
||||
Limits lims = Limits::Empty();
|
||||
size = IntersectAux(type1, type2, result, size, &lims, region);
|
||||
RangeType::Limits lims = RangeType::Limits::Empty();
|
||||
size = IntersectAux(type1, type2, result, size, &lims, zone);
|
||||
|
||||
// If the range is not empty, then insert it into the union and
|
||||
// remove the number bits from the bitset.
|
||||
if (!lims.IsEmpty()) {
|
||||
size = UpdateRange(RangeType::New(lims, representation, region), result,
|
||||
size, region);
|
||||
size = UpdateRange(RangeType::New(lims, representation, zone), result, size,
|
||||
zone);
|
||||
|
||||
// Remove the number bits.
|
||||
bitset number_bits = BitsetType::NumberBits(bits);
|
||||
bits &= ~number_bits;
|
||||
result->Set(0, BitsetType::New(bits, region));
|
||||
result->Set(0, BitsetType::New(bits));
|
||||
}
|
||||
return NormalizeUnion(result, size, region);
|
||||
return NormalizeUnion(result_type, size, zone);
|
||||
}
|
||||
|
||||
|
||||
template<class Config>
|
||||
int TypeImpl<Config>::UpdateRange(
|
||||
RangeHandle range, UnionHandle result, int size, Region* region) {
|
||||
int Type::UpdateRange(Type* range, UnionType* result, int size, Zone* zone) {
|
||||
if (size == 1) {
|
||||
result->Set(size++, range);
|
||||
} else {
|
||||
@ -837,7 +778,7 @@ int TypeImpl<Config>::UpdateRange(
|
||||
|
||||
// Remove any components that just got subsumed.
|
||||
for (int i = 2; i < size; ) {
|
||||
if (result->Get(i)->SemanticIs(range->unhandle())) {
|
||||
if (result->Get(i)->SemanticIs(range)) {
|
||||
result->Set(i, result->Get(--size));
|
||||
} else {
|
||||
++i;
|
||||
@ -846,44 +787,37 @@ int TypeImpl<Config>::UpdateRange(
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
template <class Config>
|
||||
typename TypeImpl<Config>::Limits TypeImpl<Config>::ToLimits(bitset bits,
|
||||
Region* region) {
|
||||
RangeType::Limits Type::ToLimits(bitset bits, Zone* zone) {
|
||||
bitset number_bits = BitsetType::NumberBits(bits);
|
||||
|
||||
if (number_bits == BitsetType::kNone) {
|
||||
return Limits::Empty();
|
||||
return RangeType::Limits::Empty();
|
||||
}
|
||||
|
||||
return Limits(BitsetType::Min(number_bits), BitsetType::Max(number_bits));
|
||||
return RangeType::Limits(BitsetType::Min(number_bits),
|
||||
BitsetType::Max(number_bits));
|
||||
}
|
||||
|
||||
|
||||
template <class Config>
|
||||
typename TypeImpl<Config>::Limits TypeImpl<Config>::IntersectRangeAndBitset(
|
||||
TypeHandle range, TypeHandle bitset, Region* region) {
|
||||
Limits range_lims(range->AsRange());
|
||||
Limits bitset_lims = ToLimits(bitset->AsBitset(), region);
|
||||
return Limits::Intersect(range_lims, bitset_lims);
|
||||
RangeType::Limits Type::IntersectRangeAndBitset(Type* range, Type* bitset,
|
||||
Zone* zone) {
|
||||
RangeType::Limits range_lims(range->AsRange());
|
||||
RangeType::Limits bitset_lims = ToLimits(bitset->AsBitset(), zone);
|
||||
return RangeType::Limits::Intersect(range_lims, bitset_lims);
|
||||
}
|
||||
|
||||
|
||||
template <class Config>
|
||||
int TypeImpl<Config>::IntersectAux(TypeHandle lhs, TypeHandle rhs,
|
||||
UnionHandle result, int size, Limits* lims,
|
||||
Region* region) {
|
||||
int Type::IntersectAux(Type* lhs, Type* rhs, UnionType* result, int size,
|
||||
RangeType::Limits* lims, Zone* zone) {
|
||||
if (lhs->IsUnion()) {
|
||||
for (int i = 0, n = lhs->AsUnion()->Length(); i < n; ++i) {
|
||||
size =
|
||||
IntersectAux(lhs->AsUnion()->Get(i), rhs, result, size, lims, region);
|
||||
IntersectAux(lhs->AsUnion()->Get(i), rhs, result, size, lims, zone);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
if (rhs->IsUnion()) {
|
||||
for (int i = 0, n = rhs->AsUnion()->Length(); i < n; ++i) {
|
||||
size =
|
||||
IntersectAux(lhs, rhs->AsUnion()->Get(i), result, size, lims, region);
|
||||
IntersectAux(lhs, rhs->AsUnion()->Get(i), result, size, lims, zone);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
@ -894,40 +828,41 @@ int TypeImpl<Config>::IntersectAux(TypeHandle lhs, TypeHandle rhs,
|
||||
|
||||
if (lhs->IsRange()) {
|
||||
if (rhs->IsBitset()) {
|
||||
Limits lim = IntersectRangeAndBitset(lhs, rhs, region);
|
||||
RangeType::Limits lim = IntersectRangeAndBitset(lhs, rhs, zone);
|
||||
|
||||
if (!lim.IsEmpty()) {
|
||||
*lims = Limits::Union(lim, *lims);
|
||||
*lims = RangeType::Limits::Union(lim, *lims);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
if (rhs->IsClass()) {
|
||||
*lims = Limits::Union(Limits(lhs->AsRange()), *lims);
|
||||
*lims =
|
||||
RangeType::Limits::Union(RangeType::Limits(lhs->AsRange()), *lims);
|
||||
}
|
||||
if (rhs->IsConstant() && Contains(lhs->AsRange(), rhs->AsConstant())) {
|
||||
return AddToUnion(rhs, result, size, region);
|
||||
return AddToUnion(rhs, result, size, zone);
|
||||
}
|
||||
if (rhs->IsRange()) {
|
||||
Limits lim = Limits::Intersect(
|
||||
Limits(lhs->AsRange()), Limits(rhs->AsRange()));
|
||||
RangeType::Limits lim = RangeType::Limits::Intersect(
|
||||
RangeType::Limits(lhs->AsRange()), RangeType::Limits(rhs->AsRange()));
|
||||
if (!lim.IsEmpty()) {
|
||||
*lims = Limits::Union(lim, *lims);
|
||||
*lims = RangeType::Limits::Union(lim, *lims);
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
if (rhs->IsRange()) {
|
||||
// This case is handled symmetrically above.
|
||||
return IntersectAux(rhs, lhs, result, size, lims, region);
|
||||
return IntersectAux(rhs, lhs, result, size, lims, zone);
|
||||
}
|
||||
if (lhs->IsBitset() || rhs->IsBitset()) {
|
||||
return AddToUnion(lhs->IsBitset() ? rhs : lhs, result, size, region);
|
||||
return AddToUnion(lhs->IsBitset() ? rhs : lhs, result, size, zone);
|
||||
}
|
||||
if (lhs->IsClass() != rhs->IsClass()) {
|
||||
return AddToUnion(lhs->IsClass() ? rhs : lhs, result, size, region);
|
||||
return AddToUnion(lhs->IsClass() ? rhs : lhs, result, size, zone);
|
||||
}
|
||||
if (lhs->SimplyEquals(rhs->unhandle())) {
|
||||
return AddToUnion(lhs, result, size, region);
|
||||
if (lhs->SimplyEquals(rhs)) {
|
||||
return AddToUnion(lhs, result, size, zone);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
@ -937,9 +872,7 @@ int TypeImpl<Config>::IntersectAux(TypeHandle lhs, TypeHandle rhs,
|
||||
// If the range is non-empty, the number bits in the bitset should be
|
||||
// clear. Moreover, if we have a canonical range (such as Signed32),
|
||||
// we want to produce a bitset rather than a range.
|
||||
template <class Config>
|
||||
typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::NormalizeRangeAndBitset(
|
||||
RangeHandle range, bitset* bits, Region* region) {
|
||||
Type* Type::NormalizeRangeAndBitset(Type* range, bitset* bits, Zone* zone) {
|
||||
// Fast path: If the bitset does not mention numbers, we can just keep the
|
||||
// range.
|
||||
bitset number_bits = BitsetType::NumberBits(*bits);
|
||||
@ -951,7 +884,7 @@ typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::NormalizeRangeAndBitset(
|
||||
// leave the bitset untouched.
|
||||
bitset range_lub = SEMANTIC(range->BitsetLub());
|
||||
if (BitsetType::Is(range_lub, *bits)) {
|
||||
return None(region);
|
||||
return None();
|
||||
}
|
||||
|
||||
// Slow path: reconcile the bitset range and the range.
|
||||
@ -977,17 +910,13 @@ typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::NormalizeRangeAndBitset(
|
||||
if (bitset_max > range_max) {
|
||||
range_max = bitset_max;
|
||||
}
|
||||
return RangeType::New(range_min, range_max,
|
||||
BitsetType::New(BitsetType::kNone, region), region);
|
||||
return RangeType::New(range_min, range_max, BitsetType::kNone, zone);
|
||||
}
|
||||
|
||||
|
||||
template<class Config>
|
||||
typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Union(
|
||||
TypeHandle type1, TypeHandle type2, Region* region) {
|
||||
Type* Type::Union(Type* type1, Type* type2, Zone* zone) {
|
||||
// Fast case: bit sets.
|
||||
if (type1->IsBitset() && type2->IsBitset()) {
|
||||
return BitsetType::New(type1->AsBitset() | type2->AsBitset(), region);
|
||||
return BitsetType::New(type1->AsBitset() | type2->AsBitset());
|
||||
}
|
||||
|
||||
// Fast case: top or bottom types.
|
||||
@ -1008,63 +937,62 @@ typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Union(
|
||||
// Slow case: create union.
|
||||
int size1 = type1->IsUnion() ? type1->AsUnion()->Length() : 1;
|
||||
int size2 = type2->IsUnion() ? type2->AsUnion()->Length() : 1;
|
||||
if (!AddIsSafe(size1, size2)) return Any(region);
|
||||
if (!AddIsSafe(size1, size2)) return Any();
|
||||
int size = size1 + size2;
|
||||
if (!AddIsSafe(size, 2)) return Any(region);
|
||||
if (!AddIsSafe(size, 2)) return Any();
|
||||
size += 2;
|
||||
UnionHandle result = UnionType::New(size, region);
|
||||
Type* result_type = UnionType::New(size, zone);
|
||||
UnionType* result = result_type->AsUnion();
|
||||
size = 0;
|
||||
|
||||
// Compute the new bitset.
|
||||
bitset new_bitset = SEMANTIC(type1->BitsetGlb() | type2->BitsetGlb());
|
||||
|
||||
// Deal with ranges.
|
||||
TypeHandle range = None(region);
|
||||
RangeType* range1 = type1->GetRange();
|
||||
RangeType* range2 = type2->GetRange();
|
||||
Type* range = None();
|
||||
Type* range1 = type1->GetRange();
|
||||
Type* range2 = type2->GetRange();
|
||||
if (range1 != NULL && range2 != NULL) {
|
||||
Limits lims = Limits::Union(Limits(range1), Limits(range2));
|
||||
RangeHandle union_range = RangeType::New(lims, representation, region);
|
||||
range = NormalizeRangeAndBitset(union_range, &new_bitset, region);
|
||||
RangeType::Limits lims =
|
||||
RangeType::Limits::Union(RangeType::Limits(range1->AsRange()),
|
||||
RangeType::Limits(range2->AsRange()));
|
||||
Type* union_range = RangeType::New(lims, representation, zone);
|
||||
range = NormalizeRangeAndBitset(union_range, &new_bitset, zone);
|
||||
} else if (range1 != NULL) {
|
||||
range = NormalizeRangeAndBitset(handle(range1), &new_bitset, region);
|
||||
range = NormalizeRangeAndBitset(range1, &new_bitset, zone);
|
||||
} else if (range2 != NULL) {
|
||||
range = NormalizeRangeAndBitset(handle(range2), &new_bitset, region);
|
||||
range = NormalizeRangeAndBitset(range2, &new_bitset, zone);
|
||||
}
|
||||
new_bitset = SEMANTIC(new_bitset) | representation;
|
||||
TypeHandle bits = BitsetType::New(new_bitset, region);
|
||||
Type* bits = BitsetType::New(new_bitset);
|
||||
result->Set(size++, bits);
|
||||
if (!range->IsNone()) result->Set(size++, range);
|
||||
|
||||
size = AddToUnion(type1, result, size, region);
|
||||
size = AddToUnion(type2, result, size, region);
|
||||
return NormalizeUnion(result, size, region);
|
||||
size = AddToUnion(type1, result, size, zone);
|
||||
size = AddToUnion(type2, result, size, zone);
|
||||
return NormalizeUnion(result_type, size, zone);
|
||||
}
|
||||
|
||||
|
||||
// Add [type] to [result] unless [type] is bitset, range, or already subsumed.
|
||||
// Return new size of [result].
|
||||
template<class Config>
|
||||
int TypeImpl<Config>::AddToUnion(
|
||||
TypeHandle type, UnionHandle result, int size, Region* region) {
|
||||
int Type::AddToUnion(Type* type, UnionType* result, int size, Zone* zone) {
|
||||
if (type->IsBitset() || type->IsRange()) return size;
|
||||
if (type->IsUnion()) {
|
||||
for (int i = 0, n = type->AsUnion()->Length(); i < n; ++i) {
|
||||
size = AddToUnion(type->AsUnion()->Get(i), result, size, region);
|
||||
size = AddToUnion(type->AsUnion()->Get(i), result, size, zone);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
for (int i = 0; i < size; ++i) {
|
||||
if (type->SemanticIs(result->Get(i)->unhandle())) return size;
|
||||
if (type->SemanticIs(result->Get(i))) return size;
|
||||
}
|
||||
result->Set(size++, type);
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
template <class Config>
|
||||
typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::NormalizeUnion(
|
||||
UnionHandle unioned, int size, Region* region) {
|
||||
Type* Type::NormalizeUnion(Type* union_type, int size, Zone* zone) {
|
||||
UnionType* unioned = union_type->AsUnion();
|
||||
DCHECK(size >= 1);
|
||||
DCHECK(unioned->Get(0)->IsBitset());
|
||||
// If the union has just one element, return it.
|
||||
@ -1080,13 +1008,13 @@ typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::NormalizeUnion(
|
||||
}
|
||||
if (unioned->Get(1)->IsRange()) {
|
||||
return RangeType::New(unioned->Get(1)->AsRange()->Min(),
|
||||
unioned->Get(1)->AsRange()->Max(), unioned->Get(0),
|
||||
region);
|
||||
unioned->Get(1)->AsRange()->Max(),
|
||||
unioned->Get(0)->AsBitset(), zone);
|
||||
}
|
||||
}
|
||||
unioned->Shrink(size);
|
||||
SLOW_DCHECK(unioned->Wellformed());
|
||||
return unioned;
|
||||
return union_type;
|
||||
}
|
||||
|
||||
|
||||
@ -1094,26 +1022,21 @@ typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::NormalizeUnion(
|
||||
// Component extraction
|
||||
|
||||
// static
|
||||
template <class Config>
|
||||
typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Representation(
|
||||
TypeHandle t, Region* region) {
|
||||
return BitsetType::New(t->Representation(), region);
|
||||
Type* Type::Representation(Type* t, Zone* zone) {
|
||||
return BitsetType::New(t->Representation());
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
template <class Config>
|
||||
typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Semantic(
|
||||
TypeHandle t, Region* region) {
|
||||
return Intersect(t, BitsetType::New(BitsetType::kSemantic, region), region);
|
||||
Type* Type::Semantic(Type* t, Zone* zone) {
|
||||
return Intersect(t, BitsetType::New(BitsetType::kSemantic), zone);
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Iteration.
|
||||
|
||||
template<class Config>
|
||||
int TypeImpl<Config>::NumClasses() {
|
||||
int Type::NumClasses() {
|
||||
DisallowHeapAllocation no_allocation;
|
||||
if (this->IsClass()) {
|
||||
return 1;
|
||||
@ -1128,9 +1051,7 @@ int TypeImpl<Config>::NumClasses() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class Config>
|
||||
int TypeImpl<Config>::NumConstants() {
|
||||
int Type::NumConstants() {
|
||||
DisallowHeapAllocation no_allocation;
|
||||
if (this->IsConstant()) {
|
||||
return 1;
|
||||
@ -1145,10 +1066,8 @@ int TypeImpl<Config>::NumConstants() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class Config> template<class T>
|
||||
typename TypeImpl<Config>::TypeHandle
|
||||
TypeImpl<Config>::Iterator<T>::get_type() {
|
||||
template <class T>
|
||||
Type* Type::Iterator<T>::get_type() {
|
||||
DCHECK(!Done());
|
||||
return type_->IsUnion() ? type_->AsUnion()->Get(index_) : type_;
|
||||
}
|
||||
@ -1156,46 +1075,40 @@ TypeImpl<Config>::Iterator<T>::get_type() {
|
||||
|
||||
// C++ cannot specialise nested templates, so we have to go through this
|
||||
// contortion with an auxiliary template to simulate it.
|
||||
template<class Config, class T>
|
||||
template <class T>
|
||||
struct TypeImplIteratorAux {
|
||||
static bool matches(typename TypeImpl<Config>::TypeHandle type);
|
||||
static i::Handle<T> current(typename TypeImpl<Config>::TypeHandle type);
|
||||
static bool matches(Type* type);
|
||||
static i::Handle<T> current(Type* type);
|
||||
};
|
||||
|
||||
template<class Config>
|
||||
struct TypeImplIteratorAux<Config, i::Map> {
|
||||
static bool matches(typename TypeImpl<Config>::TypeHandle type) {
|
||||
return type->IsClass();
|
||||
}
|
||||
static i::Handle<i::Map> current(typename TypeImpl<Config>::TypeHandle type) {
|
||||
template <>
|
||||
struct TypeImplIteratorAux<i::Map> {
|
||||
static bool matches(Type* type) { return type->IsClass(); }
|
||||
static i::Handle<i::Map> current(Type* type) {
|
||||
return type->AsClass()->Map();
|
||||
}
|
||||
};
|
||||
|
||||
template<class Config>
|
||||
struct TypeImplIteratorAux<Config, i::Object> {
|
||||
static bool matches(typename TypeImpl<Config>::TypeHandle type) {
|
||||
return type->IsConstant();
|
||||
}
|
||||
static i::Handle<i::Object> current(
|
||||
typename TypeImpl<Config>::TypeHandle type) {
|
||||
template <>
|
||||
struct TypeImplIteratorAux<i::Object> {
|
||||
static bool matches(Type* type) { return type->IsConstant(); }
|
||||
static i::Handle<i::Object> current(Type* type) {
|
||||
return type->AsConstant()->Value();
|
||||
}
|
||||
};
|
||||
|
||||
template<class Config> template<class T>
|
||||
bool TypeImpl<Config>::Iterator<T>::matches(TypeHandle type) {
|
||||
return TypeImplIteratorAux<Config, T>::matches(type);
|
||||
template <class T>
|
||||
bool Type::Iterator<T>::matches(Type* type) {
|
||||
return TypeImplIteratorAux<T>::matches(type);
|
||||
}
|
||||
|
||||
template<class Config> template<class T>
|
||||
i::Handle<T> TypeImpl<Config>::Iterator<T>::Current() {
|
||||
return TypeImplIteratorAux<Config, T>::current(get_type());
|
||||
template <class T>
|
||||
i::Handle<T> Type::Iterator<T>::Current() {
|
||||
return TypeImplIteratorAux<T>::current(get_type());
|
||||
}
|
||||
|
||||
|
||||
template<class Config> template<class T>
|
||||
void TypeImpl<Config>::Iterator<T>::Advance() {
|
||||
template <class T>
|
||||
void Type::Iterator<T>::Advance() {
|
||||
DisallowHeapAllocation no_allocation;
|
||||
++index_;
|
||||
if (type_->IsUnion()) {
|
||||
@ -1212,8 +1125,7 @@ void TypeImpl<Config>::Iterator<T>::Advance() {
|
||||
// -----------------------------------------------------------------------------
|
||||
// Printing.
|
||||
|
||||
template<class Config>
|
||||
const char* TypeImpl<Config>::BitsetType::Name(bitset bits) {
|
||||
const char* BitsetType::Name(bitset bits) {
|
||||
switch (bits) {
|
||||
case REPRESENTATION(kAny): return "Any";
|
||||
#define RETURN_NAMED_REPRESENTATION_TYPE(type, value) \
|
||||
@ -1232,10 +1144,8 @@ const char* TypeImpl<Config>::BitsetType::Name(bitset bits) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <class Config>
|
||||
void TypeImpl<Config>::BitsetType::Print(std::ostream& os, // NOLINT
|
||||
bitset bits) {
|
||||
void BitsetType::Print(std::ostream& os, // NOLINT
|
||||
bitset bits) {
|
||||
DisallowHeapAllocation no_allocation;
|
||||
const char* name = Name(bits);
|
||||
if (name != NULL) {
|
||||
@ -1271,9 +1181,7 @@ void TypeImpl<Config>::BitsetType::Print(std::ostream& os, // NOLINT
|
||||
os << ")";
|
||||
}
|
||||
|
||||
|
||||
template <class Config>
|
||||
void TypeImpl<Config>::PrintTo(std::ostream& os, PrintDimension dim) {
|
||||
void Type::PrintTo(std::ostream& os, PrintDimension dim) {
|
||||
DisallowHeapAllocation no_allocation;
|
||||
if (dim != REPRESENTATION_DIM) {
|
||||
if (this->IsBitset()) {
|
||||
@ -1298,7 +1206,7 @@ void TypeImpl<Config>::PrintTo(std::ostream& os, PrintDimension dim) {
|
||||
} else if (this->IsUnion()) {
|
||||
os << "(";
|
||||
for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
|
||||
TypeHandle type_i = this->AsUnion()->Get(i);
|
||||
Type* type_i = this->AsUnion()->Get(i);
|
||||
if (i > 0) os << " | ";
|
||||
type_i->PrintTo(os, dim);
|
||||
}
|
||||
@ -1322,7 +1230,7 @@ void TypeImpl<Config>::PrintTo(std::ostream& os, PrintDimension dim) {
|
||||
} else if (this->IsTuple()) {
|
||||
os << "<";
|
||||
for (int i = 0, n = this->AsTuple()->Arity(); i < n; ++i) {
|
||||
TypeHandle type_i = this->AsTuple()->Element(i);
|
||||
Type* type_i = this->AsTuple()->Element(i);
|
||||
if (i > 0) os << ", ";
|
||||
type_i->PrintTo(os, dim);
|
||||
}
|
||||
@ -1339,14 +1247,12 @@ void TypeImpl<Config>::PrintTo(std::ostream& os, PrintDimension dim) {
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
template <class Config>
|
||||
void TypeImpl<Config>::Print() {
|
||||
void Type::Print() {
|
||||
OFStream os(stdout);
|
||||
PrintTo(os);
|
||||
os << std::endl;
|
||||
}
|
||||
template <class Config>
|
||||
void TypeImpl<Config>::BitsetType::Print(bitset bits) {
|
||||
void BitsetType::Print(bitset bits) {
|
||||
OFStream os(stdout);
|
||||
Print(os, bits);
|
||||
os << std::endl;
|
||||
@ -1440,12 +1346,26 @@ void FieldType::PrintTo(std::ostream& os) {
|
||||
}
|
||||
}
|
||||
|
||||
BitsetType::bitset BitsetType::SignedSmall() {
|
||||
return i::SmiValuesAre31Bits() ? kSigned31 : kSigned32;
|
||||
}
|
||||
|
||||
BitsetType::bitset BitsetType::UnsignedSmall() {
|
||||
return i::SmiValuesAre31Bits() ? kUnsigned30 : kUnsigned31;
|
||||
}
|
||||
|
||||
#define CONSTRUCT_SIMD_TYPE(NAME, Name, name, lane_count, lane_type) \
|
||||
Type* Type::Name(Isolate* isolate, Zone* zone) { \
|
||||
return Class(i::handle(isolate->heap()->name##_map()), zone); \
|
||||
}
|
||||
SIMD128_TYPES(CONSTRUCT_SIMD_TYPE)
|
||||
#undef CONSTRUCT_SIMD_TYPE
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Instantiations.
|
||||
|
||||
template class TypeImpl<ZoneTypeConfig>;
|
||||
template class TypeImpl<ZoneTypeConfig>::Iterator<i::Map>;
|
||||
template class TypeImpl<ZoneTypeConfig>::Iterator<i::Object>;
|
||||
template class Type::Iterator<i::Map>;
|
||||
template class Type::Iterator<i::Object>;
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
1258
src/types.h
1258
src/types.h
File diff suppressed because it is too large
Load Diff
@ -89,7 +89,7 @@ void AsmTyper::VisitAsmModule(FunctionLiteral* fun) {
|
||||
for (int i = 0; i < scope->num_parameters(); ++i) {
|
||||
Variable* param = scope->parameter(i);
|
||||
DCHECK(GetType(param) == NULL);
|
||||
SetType(param, Type::None(zone()));
|
||||
SetType(param, Type::None());
|
||||
}
|
||||
|
||||
ZoneList<Declaration*>* decls = scope->declarations();
|
||||
@ -126,8 +126,7 @@ void AsmTyper::VisitAsmModule(FunctionLiteral* fun) {
|
||||
for (int i = 0; i < decls->length(); ++i) {
|
||||
FunctionDeclaration* decl = decls->at(i)->AsFunctionDeclaration();
|
||||
if (decl != NULL) {
|
||||
RECURSE(
|
||||
VisitWithExpectation(decl->fun(), Type::Any(zone()), "UNREACHABLE"));
|
||||
RECURSE(VisitWithExpectation(decl->fun(), Type::Any(), "UNREACHABLE"));
|
||||
if (!computed_type_->IsFunction()) {
|
||||
FAIL(decl->fun(), "function literal expected to be a function");
|
||||
}
|
||||
@ -149,7 +148,7 @@ void AsmTyper::VisitVariableDeclaration(VariableDeclaration* decl) {
|
||||
Variable* var = decl->proxy()->var();
|
||||
if (var->location() != VariableLocation::PARAMETER) {
|
||||
if (GetType(var) == NULL) {
|
||||
SetType(var, Type::Any(zone()));
|
||||
SetType(var, Type::Any());
|
||||
} else {
|
||||
DCHECK(!GetType(var)->IsFunction());
|
||||
}
|
||||
@ -166,20 +165,20 @@ void AsmTyper::VisitFunctionDeclaration(FunctionDeclaration* decl) {
|
||||
// Set function type so global references to functions have some type
|
||||
// (so they can give a more useful error).
|
||||
Variable* var = decl->proxy()->var();
|
||||
SetType(var, Type::Function(zone()));
|
||||
SetType(var, Type::Function());
|
||||
}
|
||||
|
||||
|
||||
void AsmTyper::VisitFunctionAnnotation(FunctionLiteral* fun) {
|
||||
// Extract result type.
|
||||
ZoneList<Statement*>* body = fun->body();
|
||||
Type* result_type = Type::Undefined(zone());
|
||||
Type* result_type = Type::Undefined();
|
||||
if (body->length() > 0) {
|
||||
ReturnStatement* stmt = body->last()->AsReturnStatement();
|
||||
if (stmt != NULL) {
|
||||
Literal* literal = stmt->expression()->AsLiteral();
|
||||
Type* old_expected = expected_type_;
|
||||
expected_type_ = Type::Any(zone());
|
||||
expected_type_ = Type::Any();
|
||||
if (literal) {
|
||||
RECURSE(VisitLiteral(literal, true));
|
||||
} else {
|
||||
@ -189,9 +188,8 @@ void AsmTyper::VisitFunctionAnnotation(FunctionLiteral* fun) {
|
||||
result_type = computed_type_;
|
||||
}
|
||||
}
|
||||
Type::FunctionType* type = Type::Function(result_type, Type::Any(zone()),
|
||||
fun->parameter_count(), zone())
|
||||
->AsFunction();
|
||||
Type* type =
|
||||
Type::Function(result_type, Type::Any(), fun->parameter_count(), zone());
|
||||
|
||||
// Extract parameter types.
|
||||
bool good = true;
|
||||
@ -213,7 +211,7 @@ void AsmTyper::VisitFunctionAnnotation(FunctionLiteral* fun) {
|
||||
property_info_ = NULL;
|
||||
}
|
||||
SetType(var, computed_type_);
|
||||
type->InitParameter(i, computed_type_);
|
||||
type->AsFunction()->InitParameter(i, computed_type_);
|
||||
good = true;
|
||||
}
|
||||
if (!good) FAIL(fun, "missing parameter type annotations");
|
||||
@ -266,7 +264,7 @@ void AsmTyper::VisitExpressionAnnotation(Expression* expr, Variable* var,
|
||||
|
||||
// Numbers or the undefined literal (for empty returns).
|
||||
if (expr->IsLiteral()) {
|
||||
RECURSE(VisitWithExpectation(expr, Type::Any(zone()), "invalid literal"));
|
||||
RECURSE(VisitWithExpectation(expr, Type::Any(), "invalid literal"));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -316,7 +314,7 @@ void AsmTyper::VisitBlock(Block* stmt) {
|
||||
|
||||
|
||||
void AsmTyper::VisitExpressionStatement(ExpressionStatement* stmt) {
|
||||
RECURSE(VisitWithExpectation(stmt->expression(), Type::Any(zone()),
|
||||
RECURSE(VisitWithExpectation(stmt->expression(), Type::Any(),
|
||||
"expression statement expected to be any"));
|
||||
}
|
||||
|
||||
@ -368,7 +366,7 @@ void AsmTyper::VisitReturnStatement(ReturnStatement* stmt) {
|
||||
VisitLiteral(literal, true);
|
||||
} else {
|
||||
RECURSE(
|
||||
VisitWithExpectation(stmt->expression(), Type::Any(zone()),
|
||||
VisitWithExpectation(stmt->expression(), Type::Any(),
|
||||
"return expression expected to have return type"));
|
||||
}
|
||||
if (!computed_type_->Is(return_type_) || !return_type_->Is(computed_type_)) {
|
||||
@ -500,9 +498,9 @@ void AsmTyper::VisitFunctionLiteral(FunctionLiteral* expr) {
|
||||
FAIL(expr, "invalid function literal");
|
||||
}
|
||||
|
||||
Type::FunctionType* type = expr->bounds().upper->AsFunction();
|
||||
Type* type = expr->bounds().upper;
|
||||
Type* save_return_type = return_type_;
|
||||
return_type_ = type->Result();
|
||||
return_type_ = type->AsFunction()->Result();
|
||||
in_function_ = true;
|
||||
local_variable_type_.Clear();
|
||||
RECURSE(VisitDeclarations(scope->declarations()));
|
||||
@ -527,7 +525,7 @@ void AsmTyper::VisitConditional(Conditional* expr) {
|
||||
if (!in_function_) {
|
||||
FAIL(expr, "ternary operator inside module body");
|
||||
}
|
||||
RECURSE(VisitWithExpectation(expr->condition(), Type::Number(zone()),
|
||||
RECURSE(VisitWithExpectation(expr->condition(), Type::Number(),
|
||||
"condition expected to be integer"));
|
||||
if (!computed_type_->Is(cache_.kAsmInt)) {
|
||||
FAIL(expr->condition(), "condition must be of type int");
|
||||
@ -572,7 +570,7 @@ void AsmTyper::VisitVariableProxy(VariableProxy* expr, bool assignment) {
|
||||
}
|
||||
if (info == NULL || info->type == NULL) {
|
||||
if (var->mode() == TEMPORARY) {
|
||||
SetType(var, Type::Any(zone()));
|
||||
SetType(var, Type::Any());
|
||||
info = GetVariableInfo(var, false);
|
||||
} else {
|
||||
FAIL(expr, "unbound variable");
|
||||
@ -637,13 +635,13 @@ void AsmTyper::VisitObjectLiteral(ObjectLiteral* expr) {
|
||||
ZoneList<ObjectLiteralProperty*>* props = expr->properties();
|
||||
for (int i = 0; i < props->length(); ++i) {
|
||||
ObjectLiteralProperty* prop = props->at(i);
|
||||
RECURSE(VisitWithExpectation(prop->value(), Type::Any(zone()),
|
||||
RECURSE(VisitWithExpectation(prop->value(), Type::Any(),
|
||||
"object property expected to be a function"));
|
||||
if (!computed_type_->IsFunction()) {
|
||||
FAIL(prop->value(), "non-function in function table");
|
||||
}
|
||||
}
|
||||
IntersectResult(expr, Type::Object(zone()));
|
||||
IntersectResult(expr, Type::Object());
|
||||
}
|
||||
|
||||
|
||||
@ -653,10 +651,10 @@ void AsmTyper::VisitArrayLiteral(ArrayLiteral* expr) {
|
||||
}
|
||||
// Allowed for function tables.
|
||||
ZoneList<Expression*>* values = expr->values();
|
||||
Type* elem_type = Type::None(zone());
|
||||
Type* elem_type = Type::None();
|
||||
for (int i = 0; i < values->length(); ++i) {
|
||||
Expression* value = values->at(i);
|
||||
RECURSE(VisitWithExpectation(value, Type::Any(zone()), "UNREACHABLE"));
|
||||
RECURSE(VisitWithExpectation(value, Type::Any(), "UNREACHABLE"));
|
||||
if (!computed_type_->IsFunction()) {
|
||||
FAIL(value, "array component expected to be a function");
|
||||
}
|
||||
@ -693,7 +691,7 @@ void AsmTyper::VisitAssignment(Assignment* expr) {
|
||||
VisitVariableProxy(expr->target()->AsVariableProxy(), true);
|
||||
} else if (expr->target()->IsProperty()) {
|
||||
Property* property = expr->target()->AsProperty();
|
||||
RECURSE(VisitWithExpectation(property->obj(), Type::Any(zone()),
|
||||
RECURSE(VisitWithExpectation(property->obj(), Type::Any(),
|
||||
"bad propety object"));
|
||||
if (!computed_type_->IsArray()) {
|
||||
FAIL(property->obj(), "array expected");
|
||||
@ -734,9 +732,9 @@ Type* AsmTyper::StorageType(Type* type) {
|
||||
|
||||
void AsmTyper::VisitHeapAccess(Property* expr, bool assigning,
|
||||
Type* assignment_type) {
|
||||
Type::ArrayType* array_type = computed_type_->AsArray();
|
||||
ArrayType* array_type = computed_type_->AsArray();
|
||||
// size_t size = array_size_;
|
||||
Type* type = array_type->AsArray()->Element();
|
||||
Type* type = array_type->Element();
|
||||
if (type->IsFunction()) {
|
||||
if (assigning) {
|
||||
FAIL(expr, "assigning to function table is illegal");
|
||||
@ -902,8 +900,7 @@ void AsmTyper::VisitProperty(Property* expr) {
|
||||
|
||||
// Only recurse at this point so that we avoid needing
|
||||
// stdlib.Math to have a real type.
|
||||
RECURSE(VisitWithExpectation(expr->obj(), Type::Any(zone()),
|
||||
"bad propety object"));
|
||||
RECURSE(VisitWithExpectation(expr->obj(), Type::Any(), "bad propety object"));
|
||||
|
||||
// For heap view or function table access.
|
||||
if (computed_type_->IsArray()) {
|
||||
@ -928,7 +925,7 @@ void AsmTyper::VisitProperty(Property* expr) {
|
||||
|
||||
void AsmTyper::VisitCall(Call* expr) {
|
||||
Type* expected_type = expected_type_;
|
||||
RECURSE(VisitWithExpectation(expr->expression(), Type::Any(zone()),
|
||||
RECURSE(VisitWithExpectation(expr->expression(), Type::Any(),
|
||||
"callee expected to be any"));
|
||||
StandardMember standard_member = kNone;
|
||||
VariableProxy* proxy = expr->expression()->AsVariableProxy();
|
||||
@ -942,7 +939,7 @@ void AsmTyper::VisitCall(Call* expr) {
|
||||
FAIL(expr, "calls must be to bound variables or function tables");
|
||||
}
|
||||
if (computed_type_->IsFunction()) {
|
||||
Type::FunctionType* fun_type = computed_type_->AsFunction();
|
||||
FunctionType* fun_type = computed_type_->AsFunction();
|
||||
Type* result_type = fun_type->Result();
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
if (fun_type->Arity() != args->length()) {
|
||||
@ -983,12 +980,12 @@ void AsmTyper::VisitCall(Call* expr) {
|
||||
}
|
||||
intish_ = 0;
|
||||
IntersectResult(expr, result_type);
|
||||
} else if (computed_type_->Is(Type::Any(zone()))) {
|
||||
} else if (computed_type_->Is(Type::Any())) {
|
||||
// For foreign calls.
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
for (int i = 0; i < args->length(); ++i) {
|
||||
Expression* arg = args->at(i);
|
||||
RECURSE(VisitWithExpectation(arg, Type::Any(zone()),
|
||||
RECURSE(VisitWithExpectation(arg, Type::Any(),
|
||||
"foreign call argument expected to be any"));
|
||||
// Checking for asm extern types explicitly, as the type system
|
||||
// doesn't correctly check their inheritance relationship.
|
||||
@ -1000,7 +997,7 @@ void AsmTyper::VisitCall(Call* expr) {
|
||||
}
|
||||
}
|
||||
intish_ = kMaxUncombinedAdditiveSteps;
|
||||
expr->expression()->set_bounds(Bounds(Type::Function(zone())));
|
||||
expr->expression()->set_bounds(Bounds(Type::Function()));
|
||||
IntersectResult(expr, expected_type);
|
||||
} else {
|
||||
FAIL(expr, "invalid callee");
|
||||
@ -1012,10 +1009,10 @@ void AsmTyper::VisitCallNew(CallNew* expr) {
|
||||
if (in_function_) {
|
||||
FAIL(expr, "new not allowed in module function");
|
||||
}
|
||||
RECURSE(VisitWithExpectation(expr->expression(), Type::Any(zone()),
|
||||
RECURSE(VisitWithExpectation(expr->expression(), Type::Any(),
|
||||
"expected stdlib function"));
|
||||
if (computed_type_->IsFunction()) {
|
||||
Type::FunctionType* fun_type = computed_type_->AsFunction();
|
||||
FunctionType* fun_type = computed_type_->AsFunction();
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
if (fun_type->Arity() != args->length())
|
||||
FAIL(expr, "call with wrong arity");
|
||||
@ -1069,7 +1066,7 @@ void AsmTyper::VisitIntegerBitwiseOperator(BinaryOperation* expr,
|
||||
Type* left_expected,
|
||||
Type* right_expected,
|
||||
Type* result_type, bool conversion) {
|
||||
RECURSE(VisitWithExpectation(expr->left(), Type::Number(zone()),
|
||||
RECURSE(VisitWithExpectation(expr->left(), Type::Number(),
|
||||
"left bitwise operand expected to be a number"));
|
||||
int left_intish = intish_;
|
||||
Type* left_type = computed_type_;
|
||||
@ -1081,7 +1078,7 @@ void AsmTyper::VisitIntegerBitwiseOperator(BinaryOperation* expr,
|
||||
}
|
||||
|
||||
RECURSE(
|
||||
VisitWithExpectation(expr->right(), Type::Number(zone()),
|
||||
VisitWithExpectation(expr->right(), Type::Number(),
|
||||
"right bitwise operand expected to be a number"));
|
||||
int right_intish = intish_;
|
||||
Type* right_type = computed_type_;
|
||||
@ -1121,9 +1118,9 @@ void AsmTyper::VisitBinaryOperation(BinaryOperation* expr) {
|
||||
}
|
||||
switch (expr->op()) {
|
||||
case Token::COMMA: {
|
||||
RECURSE(VisitWithExpectation(expr->left(), Type::Any(zone()),
|
||||
RECURSE(VisitWithExpectation(expr->left(), Type::Any(),
|
||||
"left comma operand expected to be any"));
|
||||
RECURSE(VisitWithExpectation(expr->right(), Type::Any(zone()),
|
||||
RECURSE(VisitWithExpectation(expr->right(), Type::Any(),
|
||||
"right comma operand expected to be any"));
|
||||
IntersectResult(expr, computed_type_);
|
||||
return;
|
||||
@ -1133,7 +1130,7 @@ void AsmTyper::VisitBinaryOperation(BinaryOperation* expr) {
|
||||
FAIL(expr, "illegal logical operator");
|
||||
case Token::BIT_OR: {
|
||||
// BIT_OR allows Any since it is used as a type coercion.
|
||||
VisitIntegerBitwiseOperator(expr, Type::Any(zone()), cache_.kAsmInt,
|
||||
VisitIntegerBitwiseOperator(expr, Type::Any(), cache_.kAsmInt,
|
||||
cache_.kAsmSigned, true);
|
||||
if (expr->left()->IsCall() && expr->op() == Token::BIT_OR) {
|
||||
expr->left()->set_bounds(Bounds(cache_.kAsmSigned));
|
||||
@ -1155,7 +1152,7 @@ void AsmTyper::VisitBinaryOperation(BinaryOperation* expr) {
|
||||
}
|
||||
}
|
||||
// BIT_XOR allows Number since it is used as a type coercion (via ~~).
|
||||
VisitIntegerBitwiseOperator(expr, Type::Number(zone()), cache_.kAsmInt,
|
||||
VisitIntegerBitwiseOperator(expr, Type::Number(), cache_.kAsmInt,
|
||||
cache_.kAsmSigned, true);
|
||||
return;
|
||||
}
|
||||
@ -1177,12 +1174,12 @@ void AsmTyper::VisitBinaryOperation(BinaryOperation* expr) {
|
||||
case Token::DIV:
|
||||
case Token::MOD: {
|
||||
RECURSE(VisitWithExpectation(
|
||||
expr->left(), Type::Number(zone()),
|
||||
expr->left(), Type::Number(),
|
||||
"left arithmetic operand expected to be number"));
|
||||
Type* left_type = computed_type_;
|
||||
int left_intish = intish_;
|
||||
RECURSE(VisitWithExpectation(
|
||||
expr->right(), Type::Number(zone()),
|
||||
expr->right(), Type::Number(),
|
||||
"right arithmetic operand expected to be number"));
|
||||
Type* right_type = computed_type_;
|
||||
int right_intish = intish_;
|
||||
@ -1260,7 +1257,7 @@ void AsmTyper::VisitCompareOperation(CompareOperation* expr) {
|
||||
}
|
||||
|
||||
RECURSE(
|
||||
VisitWithExpectation(expr->left(), Type::Number(zone()),
|
||||
VisitWithExpectation(expr->left(), Type::Number(),
|
||||
"left comparison operand expected to be number"));
|
||||
Type* left_type = computed_type_;
|
||||
if (!left_type->Is(cache_.kAsmComparable)) {
|
||||
@ -1268,7 +1265,7 @@ void AsmTyper::VisitCompareOperation(CompareOperation* expr) {
|
||||
}
|
||||
|
||||
RECURSE(
|
||||
VisitWithExpectation(expr->right(), Type::Number(zone()),
|
||||
VisitWithExpectation(expr->right(), Type::Number(),
|
||||
"right comparison operand expected to be number"));
|
||||
Type* right_type = computed_type_;
|
||||
if (!right_type->Is(cache_.kAsmComparable)) {
|
||||
@ -1327,10 +1324,10 @@ void AsmTyper::VisitSuperCallReference(SuperCallReference* expr) {
|
||||
void AsmTyper::InitializeStdlibSIMD() {
|
||||
#define V(NAME, Name, name, lane_count, lane_type) \
|
||||
{ \
|
||||
Type* type = Type::Function(Type::Name(isolate_, zone()), \
|
||||
Type::Any(zone()), lane_count, zone()); \
|
||||
Type* type = Type::Function(Type::Name(isolate_, zone()), Type::Any(), \
|
||||
lane_count, zone()); \
|
||||
for (int i = 0; i < lane_count; ++i) { \
|
||||
type->AsFunction()->InitParameter(i, Type::Number(zone())); \
|
||||
type->AsFunction()->InitParameter(i, Type::Number()); \
|
||||
} \
|
||||
stdlib_simd_##name##_constructor_type_ = new (zone()) VariableInfo(type); \
|
||||
stdlib_simd_##name##_constructor_type_->is_constructor_function = true; \
|
||||
@ -1344,7 +1341,7 @@ void AsmTyper::InitializeStdlib() {
|
||||
if (allow_simd_) {
|
||||
InitializeStdlibSIMD();
|
||||
}
|
||||
Type* number_type = Type::Number(zone());
|
||||
Type* number_type = Type::Number();
|
||||
Type* double_type = cache_.kAsmDouble;
|
||||
Type* double_fn1_type = Type::Function(double_type, double_type, zone());
|
||||
Type* double_fn2_type =
|
||||
@ -1401,7 +1398,7 @@ void AsmTyper::InitializeStdlib() {
|
||||
stdlib_types_["Infinity"]->standard_member = kInfinity;
|
||||
stdlib_types_["NaN"] = new (zone()) VariableInfo(double_type);
|
||||
stdlib_types_["NaN"]->standard_member = kNaN;
|
||||
Type* buffer_type = Type::Any(zone());
|
||||
Type* buffer_type = Type::Any();
|
||||
#define TYPED_ARRAY(TypeName, type_name, TYPE_NAME, ctype, size) \
|
||||
stdlib_types_[#TypeName "Array"] = new (zone()) VariableInfo( \
|
||||
Type::Function(cache_.k##TypeName##Array, buffer_type, zone()));
|
||||
@ -1518,7 +1515,7 @@ void AsmTyper::VisitWithExpectation(Expression* expr, Type* expected_type,
|
||||
expected_type_ = expected_type;
|
||||
RECURSE(Visit(expr));
|
||||
Type* bounded_type = Type::Intersect(computed_type_, expected_type_, zone());
|
||||
if (bounded_type->Is(Type::None(zone()))) {
|
||||
if (bounded_type->Is(Type::None())) {
|
||||
#ifdef DEBUG
|
||||
PrintF("Computed type: ");
|
||||
computed_type_->Print();
|
||||
|
@ -336,7 +336,7 @@ class AsmWasmBuilderImpl : public AstVisitor {
|
||||
Scope* scope = expr->scope();
|
||||
if (in_function_) {
|
||||
if (expr->bounds().lower->IsFunction()) {
|
||||
Type::FunctionType* func_type = expr->bounds().lower->AsFunction();
|
||||
FunctionType* func_type = expr->bounds().lower->AsFunction();
|
||||
LocalType return_type = TypeFrom(func_type->Result());
|
||||
current_function_builder_->ReturnType(return_type);
|
||||
for (int i = 0; i < expr->parameter_count(); i++) {
|
||||
@ -465,7 +465,7 @@ class AsmWasmBuilderImpl : public AstVisitor {
|
||||
}
|
||||
|
||||
void AddFunctionTable(VariableProxy* table, ArrayLiteral* funcs) {
|
||||
Type::FunctionType* func_type =
|
||||
FunctionType* func_type =
|
||||
funcs->bounds().lower->AsArray()->Element()->AsFunction();
|
||||
LocalType return_type = TypeFrom(func_type->Result());
|
||||
FunctionSig::Builder sig(zone(), return_type == kAstStmt ? 0 : 1,
|
||||
@ -551,7 +551,7 @@ class AsmWasmBuilderImpl : public AstVisitor {
|
||||
void VisitProperty(Property* expr) {
|
||||
Expression* obj = expr->obj();
|
||||
DCHECK(obj->bounds().lower == obj->bounds().upper);
|
||||
TypeImpl<ZoneTypeConfig>* type = obj->bounds().lower;
|
||||
Type* type = obj->bounds().lower;
|
||||
MachineType mtype;
|
||||
int size;
|
||||
if (type->Is(cache_.kUint8Array)) {
|
||||
@ -951,7 +951,7 @@ class AsmWasmBuilderImpl : public AstVisitor {
|
||||
|
||||
TypeIndex TypeIndexOf(Expression* expr) {
|
||||
DCHECK(expr->bounds().lower == expr->bounds().upper);
|
||||
TypeImpl<ZoneTypeConfig>* type = expr->bounds().lower;
|
||||
Type* type = expr->bounds().lower;
|
||||
if (type->Is(cache_.kAsmFixnum)) {
|
||||
return kFixnum;
|
||||
} else if (type->Is(cache_.kAsmSigned)) {
|
||||
@ -1063,7 +1063,7 @@ class AsmWasmBuilderImpl : public AstVisitor {
|
||||
return TypeFrom(expr->bounds().lower);
|
||||
}
|
||||
|
||||
LocalType TypeFrom(TypeImpl<ZoneTypeConfig>* type) {
|
||||
LocalType TypeFrom(Type* type) {
|
||||
if (type->Is(cache_.kAsmInt)) {
|
||||
return kAstI32;
|
||||
} else if (type->Is(cache_.kAsmFloat)) {
|
||||
|
@ -16,15 +16,15 @@
|
||||
#include "test/cctest/expression-type-collector-macros.h"
|
||||
|
||||
// Macros for function types.
|
||||
#define FUNC_BARE_TYPE Bounds(Type::Function(zone))
|
||||
#define FUNC_V_TYPE Bounds(Type::Function(Type::Undefined(zone), zone))
|
||||
#define FUNC_BARE_TYPE Bounds(Type::Function())
|
||||
#define FUNC_V_TYPE Bounds(Type::Function(Type::Undefined(), zone))
|
||||
#define FUNC_I_TYPE Bounds(Type::Function(cache.kAsmSigned, zone))
|
||||
#define FUNC_F_TYPE Bounds(Type::Function(cache.kAsmFloat, zone))
|
||||
#define FUNC_D_TYPE Bounds(Type::Function(cache.kAsmDouble, zone))
|
||||
#define FUNC_D2D_TYPE \
|
||||
Bounds(Type::Function(cache.kAsmDouble, cache.kAsmDouble, zone))
|
||||
#define FUNC_N2F_TYPE \
|
||||
Bounds(Type::Function(cache.kAsmFloat, Type::Number(zone), zone))
|
||||
Bounds(Type::Function(cache.kAsmFloat, Type::Number(), zone))
|
||||
#define FUNC_I2I_TYPE \
|
||||
Bounds(Type::Function(cache.kAsmSigned, cache.kAsmInt, zone))
|
||||
#define FUNC_II2D_TYPE \
|
||||
@ -34,11 +34,10 @@
|
||||
#define FUNC_DD2D_TYPE \
|
||||
Bounds(Type::Function(cache.kAsmDouble, cache.kAsmDouble, cache.kAsmDouble, \
|
||||
zone))
|
||||
#define FUNC_NN2N_TYPE \
|
||||
Bounds(Type::Function(Type::Number(zone), Type::Number(zone), \
|
||||
Type::Number(zone), zone))
|
||||
#define FUNC_NN2N_TYPE \
|
||||
Bounds(Type::Function(Type::Number(), Type::Number(), Type::Number(), zone))
|
||||
#define FUNC_N2N_TYPE \
|
||||
Bounds(Type::Function(Type::Number(zone), Type::Number(zone), zone))
|
||||
Bounds(Type::Function(Type::Number(), Type::Number(), zone))
|
||||
|
||||
// Macros for array types.
|
||||
#define FLOAT64_ARRAY_TYPE Bounds(Type::Array(cache.kAsmDouble, zone))
|
||||
@ -266,7 +265,7 @@ TEST(ValidateMinimum) {
|
||||
}
|
||||
}
|
||||
// "use asm";
|
||||
CHECK_EXPR(Literal, Bounds(Type::String(zone)));
|
||||
CHECK_EXPR(Literal, Bounds(Type::String()));
|
||||
// var exp = stdlib.Math.exp;
|
||||
CHECK_EXPR(Assignment, FUNC_D2D_TYPE) {
|
||||
CHECK_VAR(exp, FUNC_D2D_TYPE);
|
||||
@ -519,12 +518,11 @@ void CheckStdlibShortcuts2(Zone* zone, ZoneVector<ExpressionTypeEntry>& types,
|
||||
CHECK_EXPR(FunctionLiteral, Bounds::Unbounded()) {
|
||||
#define CHECK_FUNC_TYPES_END_1() \
|
||||
/* "use asm"; */ \
|
||||
CHECK_EXPR(Literal, Bounds(Type::String(zone))); \
|
||||
CHECK_EXPR(Literal, Bounds(Type::String())); \
|
||||
/* stdlib shortcuts. */ \
|
||||
CheckStdlibShortcuts1(zone, types, index, depth, cache); \
|
||||
CheckStdlibShortcuts2(zone, types, index, depth, cache);
|
||||
|
||||
|
||||
#define CHECK_FUNC_TYPES_END_2() \
|
||||
/* return { foo: foo }; */ \
|
||||
CHECK_EXPR(ObjectLiteral, Bounds::Unbounded()) { \
|
||||
@ -565,10 +563,10 @@ TEST(ReturnVoid) {
|
||||
"function foo() { bar(); }") {
|
||||
CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
|
||||
// return undefined;
|
||||
CHECK_EXPR(Literal, Bounds(Type::Undefined(zone)));
|
||||
CHECK_EXPR(Literal, Bounds(Type::Undefined()));
|
||||
}
|
||||
CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
|
||||
CHECK_EXPR(Call, Bounds(Type::Undefined(zone))) {
|
||||
CHECK_EXPR(Call, Bounds(Type::Undefined())) {
|
||||
CHECK_VAR(bar, FUNC_V_TYPE);
|
||||
}
|
||||
}
|
||||
@ -583,7 +581,7 @@ TEST(EmptyBody) {
|
||||
"function foo() { bar(); }") {
|
||||
CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE);
|
||||
CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
|
||||
CHECK_EXPR(Call, Bounds(Type::Undefined(zone))) {
|
||||
CHECK_EXPR(Call, Bounds(Type::Undefined())) {
|
||||
CHECK_VAR(bar, FUNC_V_TYPE);
|
||||
}
|
||||
}
|
||||
@ -603,7 +601,7 @@ TEST(DoesNothing) {
|
||||
}
|
||||
}
|
||||
CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) {
|
||||
CHECK_EXPR(Call, Bounds(Type::Undefined(zone))) {
|
||||
CHECK_EXPR(Call, Bounds(Type::Undefined())) {
|
||||
CHECK_VAR(bar, FUNC_V_TYPE);
|
||||
}
|
||||
}
|
||||
@ -1067,7 +1065,7 @@ TEST(UnsignedDivide) {
|
||||
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
||||
}
|
||||
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
|
||||
CHECK_EXPR(BinaryOperation, Bounds(Type::None(zone), Type::Any(zone))) {
|
||||
CHECK_EXPR(BinaryOperation, Bounds(Type::None(), Type::Any())) {
|
||||
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmUnsigned)) {
|
||||
CHECK_VAR(x, Bounds(cache.kAsmInt));
|
||||
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
||||
@ -1742,9 +1740,9 @@ TEST(ForeignFunction) {
|
||||
}
|
||||
}
|
||||
CHECK_FUNC_TYPES_END_1()
|
||||
CHECK_EXPR(Assignment, Bounds(Type::Any(zone))) {
|
||||
CHECK_VAR(baz, Bounds(Type::Any(zone)));
|
||||
CHECK_EXPR(Property, Bounds(Type::Any(zone))) {
|
||||
CHECK_EXPR(Assignment, Bounds(Type::Any())) {
|
||||
CHECK_VAR(baz, Bounds(Type::Any()));
|
||||
CHECK_EXPR(Property, Bounds(Type::Any())) {
|
||||
CHECK_VAR(foreign, Bounds::Unbounded());
|
||||
CHECK_EXPR(Literal, Bounds::Unbounded());
|
||||
}
|
||||
@ -2010,7 +2008,7 @@ TEST(SwitchTest) {
|
||||
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
||||
}
|
||||
}
|
||||
CHECK_EXPR(Literal, Bounds(Type::Undefined(zone)));
|
||||
CHECK_EXPR(Literal, Bounds(Type::Undefined()));
|
||||
CHECK_VAR(.switch_tag, Bounds(cache.kAsmSigned));
|
||||
// case 1: return 23;
|
||||
CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum));
|
||||
@ -2154,11 +2152,11 @@ TEST(Imports) {
|
||||
}
|
||||
}
|
||||
// "use asm";
|
||||
CHECK_EXPR(Literal, Bounds(Type::String(zone)));
|
||||
CHECK_EXPR(Literal, Bounds(Type::String()));
|
||||
// var func = foreign.foo;
|
||||
CHECK_EXPR(Assignment, Bounds(Type::Any(zone))) {
|
||||
CHECK_VAR(ffunc, Bounds(Type::Any(zone)));
|
||||
CHECK_EXPR(Property, Bounds(Type::Any(zone))) {
|
||||
CHECK_EXPR(Assignment, Bounds(Type::Any())) {
|
||||
CHECK_VAR(ffunc, Bounds(Type::Any()));
|
||||
CHECK_EXPR(Property, Bounds(Type::Any())) {
|
||||
CHECK_VAR(foreign, Bounds::Unbounded());
|
||||
CHECK_EXPR(Literal, Bounds::Unbounded());
|
||||
}
|
||||
@ -2167,7 +2165,7 @@ TEST(Imports) {
|
||||
CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) {
|
||||
CHECK_VAR(fint, Bounds(cache.kAsmInt));
|
||||
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) {
|
||||
CHECK_EXPR(Property, Bounds(Type::Number(zone))) {
|
||||
CHECK_EXPR(Property, Bounds(Type::Number())) {
|
||||
CHECK_VAR(foreign, Bounds::Unbounded());
|
||||
CHECK_EXPR(Literal, Bounds::Unbounded());
|
||||
}
|
||||
@ -2178,7 +2176,7 @@ TEST(Imports) {
|
||||
CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) {
|
||||
CHECK_VAR(fdouble, Bounds(cache.kAsmDouble));
|
||||
CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmDouble)) {
|
||||
CHECK_EXPR(Property, Bounds(Type::Number(zone))) {
|
||||
CHECK_EXPR(Property, Bounds(Type::Number())) {
|
||||
CHECK_VAR(foreign, Bounds::Unbounded());
|
||||
CHECK_EXPR(Literal, Bounds::Unbounded());
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -35,19 +35,18 @@ namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
|
||||
template<class Type, class TypeHandle, class Region>
|
||||
class Types {
|
||||
public:
|
||||
Types(Region* region, Isolate* isolate, v8::base::RandomNumberGenerator* rng)
|
||||
: region_(region), isolate_(isolate), rng_(rng) {
|
||||
#define DECLARE_TYPE(name, value) \
|
||||
name = Type::name(region); \
|
||||
types.push_back(name);
|
||||
Types(Zone* zone, Isolate* isolate, v8::base::RandomNumberGenerator* rng)
|
||||
: zone_(zone), isolate_(isolate), rng_(rng) {
|
||||
#define DECLARE_TYPE(name, value) \
|
||||
name = Type::name(); \
|
||||
types.push_back(name);
|
||||
PROPER_BITSET_TYPE_LIST(DECLARE_TYPE)
|
||||
#undef DECLARE_TYPE
|
||||
|
||||
SignedSmall = Type::SignedSmall(region);
|
||||
UnsignedSmall = Type::UnsignedSmall(region);
|
||||
SignedSmall = Type::SignedSmall();
|
||||
UnsignedSmall = Type::UnsignedSmall();
|
||||
|
||||
object_map = isolate->factory()->NewMap(
|
||||
JS_OBJECT_TYPE, JSObject::kHeaderSize);
|
||||
@ -56,16 +55,16 @@ class Types {
|
||||
number_map = isolate->factory()->NewMap(
|
||||
HEAP_NUMBER_TYPE, HeapNumber::kSize);
|
||||
uninitialized_map = isolate->factory()->uninitialized_map();
|
||||
ObjectClass = Type::Class(object_map, region);
|
||||
ArrayClass = Type::Class(array_map, region);
|
||||
NumberClass = Type::Class(number_map, region);
|
||||
UninitializedClass = Type::Class(uninitialized_map, region);
|
||||
ObjectClass = Type::Class(object_map, zone);
|
||||
ArrayClass = Type::Class(array_map, zone);
|
||||
NumberClass = Type::Class(number_map, zone);
|
||||
UninitializedClass = Type::Class(uninitialized_map, zone);
|
||||
|
||||
maps.push_back(object_map);
|
||||
maps.push_back(array_map);
|
||||
maps.push_back(uninitialized_map);
|
||||
for (MapVector::iterator it = maps.begin(); it != maps.end(); ++it) {
|
||||
types.push_back(Type::Class(*it, region));
|
||||
types.push_back(Type::Class(*it, zone));
|
||||
}
|
||||
|
||||
smi = handle(Smi::FromInt(666), isolate);
|
||||
@ -74,13 +73,13 @@ class Types {
|
||||
object2 = isolate->factory()->NewJSObjectFromMap(object_map);
|
||||
array = isolate->factory()->NewJSArray(20);
|
||||
uninitialized = isolate->factory()->uninitialized_value();
|
||||
SmiConstant = Type::Constant(smi, region);
|
||||
Signed32Constant = Type::Constant(signed32, region);
|
||||
SmiConstant = Type::Constant(smi, zone);
|
||||
Signed32Constant = Type::Constant(signed32, zone);
|
||||
|
||||
ObjectConstant1 = Type::Constant(object1, region);
|
||||
ObjectConstant2 = Type::Constant(object2, region);
|
||||
ArrayConstant = Type::Constant(array, region);
|
||||
UninitializedConstant = Type::Constant(uninitialized, region);
|
||||
ObjectConstant1 = Type::Constant(object1, zone);
|
||||
ObjectConstant2 = Type::Constant(object2, zone);
|
||||
ArrayConstant = Type::Constant(array, zone);
|
||||
UninitializedConstant = Type::Constant(uninitialized, zone);
|
||||
|
||||
values.push_back(smi);
|
||||
values.push_back(signed32);
|
||||
@ -89,7 +88,7 @@ class Types {
|
||||
values.push_back(array);
|
||||
values.push_back(uninitialized);
|
||||
for (ValueVector::iterator it = values.begin(); it != values.end(); ++it) {
|
||||
types.push_back(Type::Constant(*it, region));
|
||||
types.push_back(Type::Constant(*it, zone));
|
||||
}
|
||||
|
||||
integers.push_back(isolate->factory()->NewNumber(-V8_INFINITY));
|
||||
@ -103,16 +102,16 @@ class Types {
|
||||
if (!IsMinusZero(x)) integers.push_back(isolate->factory()->NewNumber(x));
|
||||
}
|
||||
|
||||
Integer = Type::Range(-V8_INFINITY, +V8_INFINITY, region);
|
||||
Integer = Type::Range(-V8_INFINITY, +V8_INFINITY, zone);
|
||||
|
||||
NumberArray = Type::Array(Number, region);
|
||||
StringArray = Type::Array(String, region);
|
||||
AnyArray = Type::Array(Any, region);
|
||||
NumberArray = Type::Array(Number, zone);
|
||||
StringArray = Type::Array(String, zone);
|
||||
AnyArray = Type::Array(Any, zone);
|
||||
|
||||
SignedFunction1 = Type::Function(SignedSmall, SignedSmall, region);
|
||||
NumberFunction1 = Type::Function(Number, Number, region);
|
||||
NumberFunction2 = Type::Function(Number, Number, Number, region);
|
||||
MethodFunction = Type::Function(String, Object, 0, region);
|
||||
SignedFunction1 = Type::Function(SignedSmall, SignedSmall, zone);
|
||||
NumberFunction1 = Type::Function(Number, Number, zone);
|
||||
NumberFunction2 = Type::Function(Number, Number, Number, zone);
|
||||
MethodFunction = Type::Function(String, Object, 0, zone);
|
||||
|
||||
for (int i = 0; i < 30; ++i) {
|
||||
types.push_back(Fuzz());
|
||||
@ -131,40 +130,40 @@ class Types {
|
||||
Handle<i::JSArray> array;
|
||||
Handle<i::Oddball> uninitialized;
|
||||
|
||||
#define DECLARE_TYPE(name, value) TypeHandle name;
|
||||
#define DECLARE_TYPE(name, value) Type* name;
|
||||
PROPER_BITSET_TYPE_LIST(DECLARE_TYPE)
|
||||
#undef DECLARE_TYPE
|
||||
|
||||
#define DECLARE_TYPE(name, value) TypeHandle Mask##name##ForTesting;
|
||||
#define DECLARE_TYPE(name, value) Type* Mask##name##ForTesting;
|
||||
MASK_BITSET_TYPE_LIST(DECLARE_TYPE)
|
||||
#undef DECLARE_TYPE
|
||||
TypeHandle SignedSmall;
|
||||
TypeHandle UnsignedSmall;
|
||||
Type* SignedSmall;
|
||||
Type* UnsignedSmall;
|
||||
|
||||
TypeHandle ObjectClass;
|
||||
TypeHandle ArrayClass;
|
||||
TypeHandle NumberClass;
|
||||
TypeHandle UninitializedClass;
|
||||
Type* ObjectClass;
|
||||
Type* ArrayClass;
|
||||
Type* NumberClass;
|
||||
Type* UninitializedClass;
|
||||
|
||||
TypeHandle SmiConstant;
|
||||
TypeHandle Signed32Constant;
|
||||
TypeHandle ObjectConstant1;
|
||||
TypeHandle ObjectConstant2;
|
||||
TypeHandle ArrayConstant;
|
||||
TypeHandle UninitializedConstant;
|
||||
Type* SmiConstant;
|
||||
Type* Signed32Constant;
|
||||
Type* ObjectConstant1;
|
||||
Type* ObjectConstant2;
|
||||
Type* ArrayConstant;
|
||||
Type* UninitializedConstant;
|
||||
|
||||
TypeHandle Integer;
|
||||
Type* Integer;
|
||||
|
||||
TypeHandle NumberArray;
|
||||
TypeHandle StringArray;
|
||||
TypeHandle AnyArray;
|
||||
Type* NumberArray;
|
||||
Type* StringArray;
|
||||
Type* AnyArray;
|
||||
|
||||
TypeHandle SignedFunction1;
|
||||
TypeHandle NumberFunction1;
|
||||
TypeHandle NumberFunction2;
|
||||
TypeHandle MethodFunction;
|
||||
Type* SignedFunction1;
|
||||
Type* NumberFunction1;
|
||||
Type* NumberFunction2;
|
||||
Type* MethodFunction;
|
||||
|
||||
typedef std::vector<TypeHandle> TypeVector;
|
||||
typedef std::vector<Type*> TypeVector;
|
||||
typedef std::vector<Handle<i::Map> > MapVector;
|
||||
typedef std::vector<Handle<i::Object> > ValueVector;
|
||||
|
||||
@ -173,94 +172,70 @@ class Types {
|
||||
ValueVector values;
|
||||
ValueVector integers; // "Integer" values used for range limits.
|
||||
|
||||
TypeHandle Of(Handle<i::Object> value) {
|
||||
return Type::Of(value, region_);
|
||||
Type* Of(Handle<i::Object> value) { return Type::Of(value, zone_); }
|
||||
|
||||
Type* NowOf(Handle<i::Object> value) { return Type::NowOf(value, zone_); }
|
||||
|
||||
Type* Class(Handle<i::Map> map) { return Type::Class(map, zone_); }
|
||||
|
||||
Type* Constant(Handle<i::Object> value) {
|
||||
return Type::Constant(value, zone_);
|
||||
}
|
||||
|
||||
TypeHandle NowOf(Handle<i::Object> value) {
|
||||
return Type::NowOf(value, region_);
|
||||
Type* Range(double min, double max) { return Type::Range(min, max, zone_); }
|
||||
|
||||
Type* Context(Type* outer) { return Type::Context(outer, zone_); }
|
||||
|
||||
Type* Array1(Type* element) { return Type::Array(element, zone_); }
|
||||
|
||||
Type* Function0(Type* result, Type* receiver) {
|
||||
return Type::Function(result, receiver, 0, zone_);
|
||||
}
|
||||
|
||||
TypeHandle Class(Handle<i::Map> map) {
|
||||
return Type::Class(map, region_);
|
||||
}
|
||||
|
||||
TypeHandle Constant(Handle<i::Object> value) {
|
||||
return Type::Constant(value, region_);
|
||||
}
|
||||
|
||||
TypeHandle Range(double min, double max) {
|
||||
return Type::Range(min, max, region_);
|
||||
}
|
||||
|
||||
TypeHandle Context(TypeHandle outer) {
|
||||
return Type::Context(outer, region_);
|
||||
}
|
||||
|
||||
TypeHandle Array1(TypeHandle element) {
|
||||
return Type::Array(element, region_);
|
||||
}
|
||||
|
||||
TypeHandle Function0(TypeHandle result, TypeHandle receiver) {
|
||||
return Type::Function(result, receiver, 0, region_);
|
||||
}
|
||||
|
||||
TypeHandle Function1(TypeHandle result, TypeHandle receiver, TypeHandle arg) {
|
||||
TypeHandle type = Type::Function(result, receiver, 1, region_);
|
||||
Type* Function1(Type* result, Type* receiver, Type* arg) {
|
||||
Type* type = Type::Function(result, receiver, 1, zone_);
|
||||
type->AsFunction()->InitParameter(0, arg);
|
||||
return type;
|
||||
}
|
||||
|
||||
TypeHandle Function2(TypeHandle result, TypeHandle arg1, TypeHandle arg2) {
|
||||
return Type::Function(result, arg1, arg2, region_);
|
||||
Type* Function2(Type* result, Type* arg1, Type* arg2) {
|
||||
return Type::Function(result, arg1, arg2, zone_);
|
||||
}
|
||||
|
||||
TypeHandle Union(TypeHandle t1, TypeHandle t2) {
|
||||
return Type::Union(t1, t2, region_);
|
||||
}
|
||||
Type* Union(Type* t1, Type* t2) { return Type::Union(t1, t2, zone_); }
|
||||
|
||||
TypeHandle Intersect(TypeHandle t1, TypeHandle t2) {
|
||||
return Type::Intersect(t1, t2, region_);
|
||||
}
|
||||
Type* Intersect(Type* t1, Type* t2) { return Type::Intersect(t1, t2, zone_); }
|
||||
|
||||
TypeHandle Representation(TypeHandle t) {
|
||||
return Type::Representation(t, region_);
|
||||
}
|
||||
Type* Representation(Type* t) { return Type::Representation(t, zone_); }
|
||||
|
||||
// TypeHandle Semantic(TypeHandle t) { return Intersect(t,
|
||||
// Type* Semantic(Type* t) { return Intersect(t,
|
||||
// MaskSemanticForTesting); }
|
||||
TypeHandle Semantic(TypeHandle t) { return Type::Semantic(t, region_); }
|
||||
Type* Semantic(Type* t) { return Type::Semantic(t, zone_); }
|
||||
|
||||
template<class Type2, class TypeHandle2>
|
||||
TypeHandle Convert(TypeHandle2 t) {
|
||||
return Type::template Convert<Type2>(t, region_);
|
||||
}
|
||||
|
||||
TypeHandle Random() {
|
||||
Type* Random() {
|
||||
return types[rng_->NextInt(static_cast<int>(types.size()))];
|
||||
}
|
||||
|
||||
TypeHandle Fuzz(int depth = 4) {
|
||||
Type* Fuzz(int depth = 4) {
|
||||
switch (rng_->NextInt(depth == 0 ? 3 : 20)) {
|
||||
case 0: { // bitset
|
||||
#define COUNT_BITSET_TYPES(type, value) + 1
|
||||
int n = 0 PROPER_BITSET_TYPE_LIST(COUNT_BITSET_TYPES);
|
||||
#undef COUNT_BITSET_TYPES
|
||||
// Pick a bunch of named bitsets and return their intersection.
|
||||
TypeHandle result = Type::Any(region_);
|
||||
Type* result = Type::Any();
|
||||
for (int i = 0, m = 1 + rng_->NextInt(3); i < m; ++i) {
|
||||
int j = rng_->NextInt(n);
|
||||
#define PICK_BITSET_TYPE(type, value) \
|
||||
if (j-- == 0) { \
|
||||
TypeHandle tmp = Type::Intersect( \
|
||||
result, Type::type(region_), region_); \
|
||||
if (tmp->Is(Type::None()) && i != 0) { \
|
||||
break; \
|
||||
} else { \
|
||||
result = tmp; \
|
||||
continue; \
|
||||
} \
|
||||
}
|
||||
#define PICK_BITSET_TYPE(type, value) \
|
||||
if (j-- == 0) { \
|
||||
Type* tmp = Type::Intersect(result, Type::type(), zone_); \
|
||||
if (tmp->Is(Type::None()) && i != 0) { \
|
||||
break; \
|
||||
} else { \
|
||||
result = tmp; \
|
||||
continue; \
|
||||
} \
|
||||
}
|
||||
PROPER_BITSET_TYPE_LIST(PICK_BITSET_TYPE)
|
||||
#undef PICK_BITSET_TYPE
|
||||
}
|
||||
@ -268,11 +243,11 @@ class Types {
|
||||
}
|
||||
case 1: { // class
|
||||
int i = rng_->NextInt(static_cast<int>(maps.size()));
|
||||
return Type::Class(maps[i], region_);
|
||||
return Type::Class(maps[i], zone_);
|
||||
}
|
||||
case 2: { // constant
|
||||
int i = rng_->NextInt(static_cast<int>(values.size()));
|
||||
return Type::Constant(values[i], region_);
|
||||
return Type::Constant(values[i], zone_);
|
||||
}
|
||||
case 3: { // range
|
||||
int i = rng_->NextInt(static_cast<int>(integers.size()));
|
||||
@ -280,26 +255,26 @@ class Types {
|
||||
double min = integers[i]->Number();
|
||||
double max = integers[j]->Number();
|
||||
if (min > max) std::swap(min, max);
|
||||
return Type::Range(min, max, region_);
|
||||
return Type::Range(min, max, zone_);
|
||||
}
|
||||
case 4: { // context
|
||||
int depth = rng_->NextInt(3);
|
||||
TypeHandle type = Type::Internal(region_);
|
||||
for (int i = 0; i < depth; ++i) type = Type::Context(type, region_);
|
||||
Type* type = Type::Internal();
|
||||
for (int i = 0; i < depth; ++i) type = Type::Context(type, zone_);
|
||||
return type;
|
||||
}
|
||||
case 5: { // array
|
||||
TypeHandle element = Fuzz(depth / 2);
|
||||
return Type::Array(element, region_);
|
||||
Type* element = Fuzz(depth / 2);
|
||||
return Type::Array(element, zone_);
|
||||
}
|
||||
case 6:
|
||||
case 7: { // function
|
||||
TypeHandle result = Fuzz(depth / 2);
|
||||
TypeHandle receiver = Fuzz(depth / 2);
|
||||
Type* result = Fuzz(depth / 2);
|
||||
Type* receiver = Fuzz(depth / 2);
|
||||
int arity = rng_->NextInt(3);
|
||||
TypeHandle type = Type::Function(result, receiver, arity, region_);
|
||||
Type* type = Type::Function(result, receiver, arity, zone_);
|
||||
for (int i = 0; i < type->AsFunction()->Arity(); ++i) {
|
||||
TypeHandle parameter = Fuzz(depth / 2);
|
||||
Type* parameter = Fuzz(depth / 2);
|
||||
type->AsFunction()->InitParameter(i, parameter);
|
||||
}
|
||||
return type;
|
||||
@ -309,21 +284,21 @@ class Types {
|
||||
#define COUNT_SIMD_TYPE(NAME, Name, name, lane_count, lane_type) +1
|
||||
SIMD128_TYPES(COUNT_SIMD_TYPE);
|
||||
#undef COUNT_SIMD_TYPE
|
||||
TypeHandle (*simd_constructors[num_simd_types])(Isolate*, Region*) = {
|
||||
Type* (*simd_constructors[num_simd_types])(Isolate*, Zone*) = {
|
||||
#define COUNT_SIMD_TYPE(NAME, Name, name, lane_count, lane_type) \
|
||||
&Type::Name,
|
||||
SIMD128_TYPES(COUNT_SIMD_TYPE)
|
||||
SIMD128_TYPES(COUNT_SIMD_TYPE)
|
||||
#undef COUNT_SIMD_TYPE
|
||||
};
|
||||
return simd_constructors[rng_->NextInt(num_simd_types)](
|
||||
isolate_, region_);
|
||||
return simd_constructors[rng_->NextInt(num_simd_types)](isolate_,
|
||||
zone_);
|
||||
}
|
||||
default: { // union
|
||||
int n = rng_->NextInt(10);
|
||||
TypeHandle type = None;
|
||||
Type* type = None;
|
||||
for (int i = 0; i < n; ++i) {
|
||||
TypeHandle operand = Fuzz(depth - 1);
|
||||
type = Type::Union(type, operand, region_);
|
||||
Type* operand = Fuzz(depth - 1);
|
||||
type = Type::Union(type, operand, zone_);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
@ -331,10 +306,10 @@ class Types {
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
Region* region() { return region_; }
|
||||
Zone* zone() { return zone_; }
|
||||
|
||||
private:
|
||||
Region* region_;
|
||||
Zone* zone_;
|
||||
Isolate* isolate_;
|
||||
v8::base::RandomNumberGenerator* rng_;
|
||||
};
|
||||
|
@ -9,7 +9,7 @@
|
||||
#include "src/compiler/js-graph.h"
|
||||
#include "src/compiler/node-properties.h"
|
||||
#include "src/compiler/simplified-operator.h"
|
||||
#include "src/types-inl.h"
|
||||
#include "src/types.h"
|
||||
#include "src/zone-containers.h"
|
||||
#include "test/unittests/compiler/graph-unittest.h"
|
||||
|
||||
|
@ -7,7 +7,6 @@
|
||||
#include "src/compiler/js-graph.h"
|
||||
#include "src/compiler/js-intrinsic-lowering.h"
|
||||
#include "src/compiler/js-operator.h"
|
||||
#include "src/types-inl.h"
|
||||
#include "test/unittests/compiler/graph-unittest.h"
|
||||
#include "test/unittests/compiler/node-test-utils.h"
|
||||
#include "testing/gmock-support.h"
|
||||
|
@ -17,11 +17,8 @@ class ExternalReference;
|
||||
template <typename T>
|
||||
class Handle;
|
||||
class HeapObject;
|
||||
template <class>
|
||||
class TypeImpl;
|
||||
class Type;
|
||||
enum TypeofMode : int;
|
||||
struct ZoneTypeConfig;
|
||||
typedef TypeImpl<ZoneTypeConfig> Type;
|
||||
|
||||
namespace compiler {
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
#include "src/compiler/operator.h"
|
||||
#include "src/compiler/operator-properties.h"
|
||||
#include "src/compiler/simplified-operator.h"
|
||||
#include "src/types-inl.h"
|
||||
#include "src/types.h"
|
||||
#include "test/unittests/test-utils.h"
|
||||
|
||||
namespace v8 {
|
||||
|
@ -49,7 +49,7 @@ class TyperTest : public TypedGraphTest {
|
||||
}
|
||||
}
|
||||
|
||||
Types<Type, Type*, Zone> types_;
|
||||
Types types_;
|
||||
JSOperatorBuilder javascript_;
|
||||
BinaryOperationHints const hints_ = BinaryOperationHints::Any();
|
||||
Node* context_node_;
|
||||
@ -115,7 +115,7 @@ class TyperTest : public TypedGraphTest {
|
||||
return result;
|
||||
}
|
||||
|
||||
double RandomInt(Type::RangeType* range) {
|
||||
double RandomInt(RangeType* range) {
|
||||
return RandomInt(range->Min(), range->Max());
|
||||
}
|
||||
|
||||
@ -149,12 +149,12 @@ class TyperTest : public TypedGraphTest {
|
||||
void TestBinaryArithOp(const Operator* op, BinaryFunction opfun) {
|
||||
TestBinaryArithOpCloseToZero(op, opfun, 8);
|
||||
for (int i = 0; i < 100; ++i) {
|
||||
Type::RangeType* r1 = RandomRange()->AsRange();
|
||||
Type::RangeType* r2 = RandomRange()->AsRange();
|
||||
Type* r1 = RandomRange();
|
||||
Type* r2 = RandomRange();
|
||||
Type* expected_type = TypeBinaryOp(op, r1, r2);
|
||||
for (int i = 0; i < 10; i++) {
|
||||
double x1 = RandomInt(r1);
|
||||
double x2 = RandomInt(r2);
|
||||
double x1 = RandomInt(r1->AsRange());
|
||||
double x2 = RandomInt(r2->AsRange());
|
||||
double result_value = opfun(x1, x2);
|
||||
Type* result_type = Type::Constant(
|
||||
isolate()->factory()->NewNumber(result_value), zone());
|
||||
@ -166,12 +166,12 @@ class TyperTest : public TypedGraphTest {
|
||||
template <class BinaryFunction>
|
||||
void TestBinaryCompareOp(const Operator* op, BinaryFunction opfun) {
|
||||
for (int i = 0; i < 100; ++i) {
|
||||
Type::RangeType* r1 = RandomRange()->AsRange();
|
||||
Type::RangeType* r2 = RandomRange()->AsRange();
|
||||
Type* r1 = RandomRange();
|
||||
Type* r2 = RandomRange();
|
||||
Type* expected_type = TypeBinaryOp(op, r1, r2);
|
||||
for (int i = 0; i < 10; i++) {
|
||||
double x1 = RandomInt(r1);
|
||||
double x2 = RandomInt(r2);
|
||||
double x1 = RandomInt(r1->AsRange());
|
||||
double x2 = RandomInt(r2->AsRange());
|
||||
bool result_value = opfun(x1, x2);
|
||||
Type* result_type =
|
||||
Type::Constant(result_value ? isolate()->factory()->true_value()
|
||||
@ -185,12 +185,12 @@ class TyperTest : public TypedGraphTest {
|
||||
template <class BinaryFunction>
|
||||
void TestBinaryBitOp(const Operator* op, BinaryFunction opfun) {
|
||||
for (int i = 0; i < 100; ++i) {
|
||||
Type::RangeType* r1 = RandomRange(true)->AsRange();
|
||||
Type::RangeType* r2 = RandomRange(true)->AsRange();
|
||||
Type* r1 = RandomRange(true);
|
||||
Type* r2 = RandomRange(true);
|
||||
Type* expected_type = TypeBinaryOp(op, r1, r2);
|
||||
for (int i = 0; i < 10; i++) {
|
||||
int32_t x1 = static_cast<int32_t>(RandomInt(r1));
|
||||
int32_t x2 = static_cast<int32_t>(RandomInt(r2));
|
||||
int32_t x1 = static_cast<int32_t>(RandomInt(r1->AsRange()));
|
||||
int32_t x2 = static_cast<int32_t>(RandomInt(r2->AsRange()));
|
||||
double result_value = opfun(x1, x2);
|
||||
Type* result_type = Type::Constant(
|
||||
isolate()->factory()->NewNumber(result_value), zone());
|
||||
|
@ -1066,7 +1066,6 @@
|
||||
'../../src/type-feedback-vector.h',
|
||||
'../../src/type-info.cc',
|
||||
'../../src/type-info.h',
|
||||
'../../src/types-inl.h',
|
||||
'../../src/types.cc',
|
||||
'../../src/types.h',
|
||||
'../../src/typing-asm.cc',
|
||||
|
Loading…
Reference in New Issue
Block a user