| Index: src/asmjs/asm-typer.h
|
| diff --git a/src/asmjs/asm-typer.h b/src/asmjs/asm-typer.h
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..dd05f6097d13bede07eca978480cad7fe6180017
|
| --- /dev/null
|
| +++ b/src/asmjs/asm-typer.h
|
| @@ -0,0 +1,325 @@
|
| +// Copyright 2016 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 SRC_ASMJS_ASM_TYPER_H_
|
| +#define SRC_ASMJS_ASM_TYPER_H_
|
| +
|
| +#include <cstdint>
|
| +#include <string>
|
| +
|
| +#include "src/allocation.h"
|
| +#include "src/asmjs/asm-types.h"
|
| +#include "src/ast/ast-type-bounds.h"
|
| +#include "src/ast/ast.h"
|
| +#include "src/effects.h"
|
| +#include "src/type-info.h"
|
| +#include "src/types.h"
|
| +#include "src/zone-containers.h"
|
| +#include "src/zone.h"
|
| +
|
| +namespace v8 {
|
| +namespace internal {
|
| +namespace wasm {
|
| +
|
| +class AsmTyperHarnessBuilder;
|
| +
|
| +class AsmTyper final {
|
| + public:
|
| + enum StandardMember {
|
| + kHeap = -4,
|
| + kFFI = -3,
|
| + kStdlib = -2,
|
| + kModule = -1,
|
| + kNone = 0,
|
| + kInfinity,
|
| + kNaN,
|
| + kMathAcos,
|
| + kMathAsin,
|
| + kMathAtan,
|
| + kMathCos,
|
| + kMathSin,
|
| + kMathTan,
|
| + kMathExp,
|
| + kMathLog,
|
| + kMathCeil,
|
| + kMathFloor,
|
| + kMathSqrt,
|
| + kMathAbs,
|
| + kMathMin,
|
| + kMathMax,
|
| + kMathAtan2,
|
| + kMathPow,
|
| + kMathImul,
|
| + kMathFround,
|
| + kMathE,
|
| + kMathLN10,
|
| + kMathLN2,
|
| + kMathLOG2E,
|
| + kMathLOG10E,
|
| + kMathPI,
|
| + kMathSQRT1_2,
|
| + kMathSQRT2,
|
| + };
|
| +
|
| + ~AsmTyper() = default;
|
| + AsmTyper(Isolate* isolate, Zone* zone, Script* script, FunctionLiteral* root);
|
| +
|
| + bool Validate();
|
| +
|
| + const char* error_message() const { return error_message_; }
|
| +
|
| + AsmType* TypeOf(AstNode* node) const;
|
| + StandardMember VariableAsStandardMember(Variable* var);
|
| +
|
| + private:
|
| + friend class v8::internal::wasm::AsmTyperHarnessBuilder;
|
| +
|
| + class VariableInfo : public ZoneObject {
|
| + public:
|
| + enum Mutability {
|
| + kInvalidMutability,
|
| + kLocal,
|
| + kMutableGlobal,
|
| + kImmutableGlobal,
|
| + };
|
| +
|
| + VariableInfo() = default;
|
| + explicit VariableInfo(AsmType* t) : type_(t) {}
|
| +
|
| + VariableInfo* Clone(Zone* zone) const;
|
| +
|
| + bool IsMutable() const {
|
| + return mutability_ == kLocal || mutability_ == kMutableGlobal;
|
| + }
|
| +
|
| + bool IsGlobal() const {
|
| + return mutability_ == kImmutableGlobal || mutability_ == kMutableGlobal;
|
| + }
|
| +
|
| + bool IsStdlib() const { return standard_member_ == kStdlib; }
|
| + bool IsFFI() const { return standard_member_ == kFFI; }
|
| + bool IsHeap() const { return standard_member_ == kHeap; }
|
| +
|
| + void MarkDefined() { missing_definition_ = false; }
|
| + void FirstForwardUseIs(VariableProxy* var);
|
| +
|
| + StandardMember standard_member() const { return standard_member_; }
|
| + void set_standard_member(StandardMember standard_member) {
|
| + standard_member_ = standard_member;
|
| + }
|
| +
|
| + AsmType* type() const { return type_; }
|
| + void set_type(AsmType* type) { type_ = type; }
|
| +
|
| + Mutability mutability() const { return mutability_; }
|
| + void set_mutability(Mutability mutability) { mutability_ = mutability; }
|
| +
|
| + bool missing_definition() const { return missing_definition_; }
|
| +
|
| + VariableProxy* first_forward_use() const { return first_forward_use_; }
|
| +
|
| + private:
|
| + AsmType* type_ = AsmType::None();
|
| + StandardMember standard_member_ = kNone;
|
| + Mutability mutability_ = kInvalidMutability;
|
| + // missing_definition_ is set to true for forward definition - i.e., use
|
| + // before definition.
|
| + bool missing_definition_ = false;
|
| + // first_forward_use_ holds the AST node that first referenced this
|
| + // VariableInfo. Used for error messages.
|
| + VariableProxy* first_forward_use_ = nullptr;
|
| + };
|
| +
|
| + // RAII-style manager for the in_function_ member variable.
|
| + struct FunctionScope {
|
| + explicit FunctionScope(AsmTyper* typer) : typer_(typer) {
|
| + DCHECK(!typer_->in_function_);
|
| + typer_->in_function_ = true;
|
| + typer_->local_scope_.Clear();
|
| + typer_->return_type_ = AsmType::None();
|
| + }
|
| +
|
| + ~FunctionScope() {
|
| + DCHECK(typer_->in_function_);
|
| + typer_->in_function_ = false;
|
| + }
|
| +
|
| + AsmTyper* typer_;
|
| + };
|
| +
|
| + // FlattenedStatements is an iterator class for ZoneList<Statement*> that
|
| + // flattens the Block construct in the AST. This is here because we need it in
|
| + // the tests.
|
| + class FlattenedStatements {
|
| + public:
|
| + explicit FlattenedStatements(Zone* zone, ZoneList<Statement*>* s);
|
| + Statement* Next();
|
| +
|
| + private:
|
| + struct Context {
|
| + explicit Context(ZoneList<Statement*>* s) : statements_(s) {}
|
| + ZoneList<Statement*>* statements_;
|
| + int next_index_ = 0;
|
| + };
|
| +
|
| + ZoneVector<Context> context_stack_;
|
| +
|
| + DISALLOW_IMPLICIT_CONSTRUCTORS(FlattenedStatements);
|
| + };
|
| +
|
| + using ObjectTypeMap = ZoneMap<std::string, VariableInfo*>;
|
| + void InitializeStdlib();
|
| + void SetTypeOf(AstNode* node, AsmType* type);
|
| +
|
| + void AddForwardReference(VariableProxy* proxy, VariableInfo* info);
|
| + bool AddGlobal(Variable* global, VariableInfo* info);
|
| + bool AddLocal(Variable* global, VariableInfo* info);
|
| + // Used for 5.5 GlobalVariableTypeAnnotations
|
| + VariableInfo* ImportLookup(Property* expr);
|
| + // 3.3 Environment Lookup
|
| + // NOTE: In the spec, the lookup function's prototype is
|
| + //
|
| + // Lookup(Delta, Gamma, x)
|
| + //
|
| + // Delta is the global_scope_ member, and Gamma, local_scope_.
|
| + VariableInfo* Lookup(Variable* variable);
|
| +
|
| + // All of the ValidateXXX methods below return AsmType::None() in case of
|
| + // validation failure.
|
| +
|
| + // 6.1 ValidateModule
|
| + AsmType* ValidateModule(FunctionLiteral* fun);
|
| + AsmType* ValidateGlobalDeclaration(Assignment* assign);
|
| + // 6.2 ValidateExport
|
| + AsmType* ExportType(VariableProxy* fun_export);
|
| + AsmType* ValidateExport(ReturnStatement* exports);
|
| + // 6.3 ValidateFunctionTable
|
| + AsmType* ValidateFunctionTable(Assignment* assign);
|
| + // 6.4 ValidateFunction
|
| + AsmType* ValidateFunction(FunctionDeclaration* fun_decl);
|
| + // 6.5 ValidateStatement
|
| + AsmType* ValidateStatement(Statement* statement);
|
| + // 6.5.1 BlockStatement
|
| + AsmType* ValidateBlockStatement(Block* block);
|
| + // 6.5.2 ExpressionStatement
|
| + AsmType* ValidateExpressionStatement(ExpressionStatement* expr);
|
| + // 6.5.3 EmptyStatement
|
| + AsmType* ValidateEmptyStatement(EmptyStatement* empty);
|
| + // 6.5.4 IfStatement
|
| + AsmType* ValidateIfStatement(IfStatement* if_stmt);
|
| + // 6.5.5 ReturnStatement
|
| + AsmType* ValidateReturnStatement(ReturnStatement* ret_stmt);
|
| + // 6.5.6 IterationStatement
|
| + // 6.5.6.a WhileStatement
|
| + AsmType* ValidateWhileStatement(WhileStatement* while_stmt);
|
| + // 6.5.6.b DoWhileStatement
|
| + AsmType* ValidateDoWhileStatement(DoWhileStatement* do_while);
|
| + // 6.5.6.c ForStatement
|
| + AsmType* ValidateForStatement(ForStatement* for_stmt);
|
| + // 6.5.7 BreakStatement
|
| + AsmType* ValidateBreakStatement(BreakStatement* brk_stmt);
|
| + // 6.5.8 ContinueStatement
|
| + AsmType* ValidateContinueStatement(ContinueStatement* cont_stmt);
|
| + // 6.5.9 LabelledStatement
|
| + // NOTE: we don't need to handle these: Labelled statements are
|
| + // BreakableStatements in our AST, but BreakableStatement is not a concrete
|
| + // class -- and we're handling all of BreakableStatement's subclasses.
|
| + // 6.5.10 SwitchStatement
|
| + AsmType* ValidateSwitchStatement(SwitchStatement* stmt);
|
| + // 6.6 ValidateCase
|
| + AsmType* ValidateCase(CaseClause* label, int32_t* case_lbl);
|
| + // 6.7 ValidateDefault
|
| + AsmType* ValidateDefault(CaseClause* label);
|
| + // 6.8 ValidateExpression
|
| + AsmType* ValidateExpression(Expression* expr);
|
| + AsmType* ValidateCompareOperation(CompareOperation* cmp);
|
| + AsmType* ValidateBinaryOperation(BinaryOperation* binop);
|
| + // 6.8.1 Expression
|
| + AsmType* ValidateCommaExpression(BinaryOperation* comma);
|
| + // 6.8.2 NumericLiteral
|
| + AsmType* ValidateNumericLiteral(Literal* literal);
|
| + // 6.8.3 Identifier
|
| + AsmType* ValidateIdentifier(VariableProxy* proxy);
|
| + // 6.8.4 CallExpression
|
| + AsmType* ValidateCallExpression(Call* call);
|
| + // 6.8.5 MemberExpression
|
| + AsmType* ValidateMemberExpression(Property* prop);
|
| + // 6.8.6 AssignmentExpression
|
| + AsmType* ValidateAssignmentExpression(Assignment* assignment);
|
| + // 6.8.7 UnaryExpression
|
| + AsmType* ValidateUnaryExpression(UnaryOperation* unop);
|
| + // 6.8.8 MultiplicativeExpression
|
| + AsmType* ValidateMultiplicativeExpression(BinaryOperation* binop);
|
| + // 6.8.9 AdditiveExpression
|
| + AsmType* ValidateAdditiveExpression(BinaryOperation* binop,
|
| + uint32_t intish_count);
|
| + // 6.8.10 ShiftExpression
|
| + AsmType* ValidateShiftExpression(BinaryOperation* binop);
|
| + // 6.8.11 RelationalExpression
|
| + AsmType* ValidateRelationalExpression(CompareOperation* cmpop);
|
| + // 6.8.12 EqualityExpression
|
| + AsmType* ValidateEqualityExpression(CompareOperation* cmpop);
|
| + // 6.8.13 BitwiseANDExpression
|
| + AsmType* ValidateBitwiseANDExpression(BinaryOperation* binop);
|
| + // 6.8.14 BitwiseXORExpression
|
| + AsmType* ValidateBitwiseXORExpression(BinaryOperation* binop);
|
| + // 6.8.15 BitwiseORExpression
|
| + AsmType* ValidateBitwiseORExpression(BinaryOperation* binop);
|
| + // 6.8.16 ConditionalExpression
|
| + AsmType* ValidateConditionalExpression(Conditional* cond);
|
| + // 6.9 ValidateCall
|
| + AsmType* ValidateCall(AsmType* return_type, Call* call);
|
| + // 6.10 ValidateHeapAccess
|
| + enum HeapAccessType { LoadFromHeap, StoreToHeap };
|
| + AsmType* ValidateHeapAccess(Property* heap, HeapAccessType access_type);
|
| + // 6.11 ValidateFloatCoercion
|
| + bool IsCallToFround(Call* call);
|
| + AsmType* ValidateFloatCoercion(Call* call);
|
| +
|
| + // 5.1 ParameterTypeAnnotations
|
| + AsmType* ParameterTypeAnnotations(Variable* parameter,
|
| + Expression* annotation);
|
| + // 5.2 ReturnTypeAnnotations
|
| + AsmType* ReturnTypeAnnotations(ReturnStatement* statement);
|
| + // 5.4 VariableTypeAnnotations
|
| + AsmType* VariableTypeAnnotations(Expression* initializer);
|
| + // 5.5 GlobalVariableTypeAnnotations
|
| + AsmType* ImportExpression(Property* import);
|
| + AsmType* NewHeapView(CallNew* new_heap_view);
|
| +
|
| + Isolate* isolate_;
|
| + Zone* zone_;
|
| + Script* script_;
|
| + FunctionLiteral* root_;
|
| + bool in_function_ = false;
|
| +
|
| + AsmType* return_type_ = nullptr;
|
| +
|
| + ZoneVector<VariableInfo*> forward_definitions_;
|
| + ObjectTypeMap stdlib_types_;
|
| + ObjectTypeMap stdlib_math_types_;
|
| +
|
| + // The ASM module name. This member is used to prevent globals from redefining
|
| + // the module name.
|
| + VariableInfo module_info_;
|
| + Handle<String> module_name_;
|
| +
|
| + // 3 Environments
|
| + ZoneHashMap global_scope_; // 3.1 Global environment
|
| + ZoneHashMap local_scope_; // 3.2 Variable environment
|
| +
|
| + std::uintptr_t stack_limit_;
|
| + bool stack_overflow_ = false;
|
| + ZoneMap<AstNode*, AsmType*> node_types_;
|
| + static const int kErrorMessageLimit = 100;
|
| + char error_message_[kErrorMessageLimit];
|
| +
|
| + DISALLOW_IMPLICIT_CONSTRUCTORS(AsmTyper);
|
| +};
|
| +
|
| +} // namespace wasm
|
| +} // namespace internal
|
| +} // namespace v8
|
| +
|
| +#endif // SRC_ASMJS_ASM_TYPER_H_
|
|
|