LCOV - code coverage report
Current view: top level - src/asmjs - asm-typer.h (source / functions) Hit Total Coverage
Test: app.info Lines: 18 18 100.0 %
Date: 2017-04-26 Functions: 1 1 100.0 %

          Line data    Source code
       1             : // Copyright 2016 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #ifndef SRC_ASMJS_ASM_TYPER_H_
       6             : #define SRC_ASMJS_ASM_TYPER_H_
       7             : 
       8             : #include <cstdint>
       9             : #include <string>
      10             : #include <unordered_map>
      11             : #include <unordered_set>
      12             : 
      13             : #include "src/allocation.h"
      14             : #include "src/asmjs/asm-names.h"
      15             : #include "src/asmjs/asm-types.h"
      16             : #include "src/ast/ast-type-bounds.h"
      17             : #include "src/ast/ast-types.h"
      18             : #include "src/ast/ast.h"
      19             : #include "src/effects.h"
      20             : #include "src/messages.h"
      21             : #include "src/type-info.h"
      22             : #include "src/zone/zone-containers.h"
      23             : #include "src/zone/zone.h"
      24             : 
      25             : namespace v8 {
      26             : namespace internal {
      27             : namespace wasm {
      28             : 
      29             : class AsmType;
      30             : class AsmTyperHarnessBuilder;
      31             : class SourceLayoutTracker;
      32             : 
      33             : class AsmTyper final {
      34             :  public:
      35             :   enum StandardMember {
      36             :     kHeap = -4,
      37             :     kFFI = -3,
      38             :     kStdlib = -2,
      39             :     kModule = -1,
      40             :     kNone = 0,
      41             :     kInfinity,
      42             :     kNaN,
      43             : #define V(_unused1, name, _unused2, _unused3) kMath##name,
      44             :     STDLIB_MATH_FUNCTION_LIST(V)
      45             : #undef V
      46             : #define V(name, _unused1) kMath##name,
      47             :         STDLIB_MATH_VALUE_LIST(V)
      48             : #undef V
      49             : #define V(name, _unused1, _unused2, _unused3) k##name,
      50             :             STDLIB_ARRAY_TYPE_LIST(V)
      51             : #undef V
      52             :   };
      53             : 
      54      709392 :   ~AsmTyper() = default;
      55             :   AsmTyper(Isolate* isolate, Zone* zone, Handle<Script> script,
      56             :            FunctionLiteral* root);
      57             : 
      58             :   bool Validate();
      59             :   // Do asm.js validation in phases (to interleave with conversion to wasm).
      60             :   bool ValidateBeforeFunctionsPhase();
      61             :   bool ValidateInnerFunction(FunctionDeclaration* decl);
      62             :   bool ValidateAfterFunctionsPhase();
      63             :   void ClearFunctionNodeTypes();
      64             : 
      65             :   Handle<JSMessageObject> error_message() const { return error_message_; }
      66             :   const MessageLocation* message_location() const { return &message_location_; }
      67             : 
      68             :   AsmType* TriggerParsingError();
      69             : 
      70             :   AsmType* TypeOf(AstNode* node) const;
      71             :   AsmType* TypeOf(Variable* v) const;
      72             :   StandardMember VariableAsStandardMember(Variable* var);
      73             : 
      74             :   // Allow the asm-wasm-builder to trigger failures (for interleaved
      75             :   // validating).
      76             :   AsmType* FailWithMessage(const char* text);
      77             : 
      78             :   typedef std::unordered_set<StandardMember, std::hash<int> > StdlibSet;
      79             : 
      80             :   StdlibSet StdlibUses() const { return stdlib_uses_; }
      81             : 
      82             :   // Each FFI import has a usage-site signature associated with it.
      83       32482 :   struct FFIUseSignature {
      84             :     Variable* var;
      85             :     ZoneVector<AsmType*> arg_types_;
      86             :     AsmType* return_type_;
      87             :     FFIUseSignature(Variable* v, Zone* zone)
      88       13962 :         : var(v), arg_types_(zone), return_type_(nullptr) {}
      89             :   };
      90             : 
      91             :   const ZoneVector<FFIUseSignature>& FFIUseSignatures() {
      92             :     return ffi_use_signatures_;
      93             :   }
      94             : 
      95             :  private:
      96             :   friend class v8::internal::wasm::AsmTyperHarnessBuilder;
      97             : 
      98             :   class VariableInfo : public ZoneObject {
      99             :    public:
     100             :     enum Mutability {
     101             :       kInvalidMutability,
     102             :       kLocal,
     103             :       kMutableGlobal,
     104             :       // *VIOLATION* We support const variables in asm.js, as per the
     105             :       //
     106             :       // https://discourse.wicg.io/t/allow-const-global-variables/684
     107             :       //
     108             :       // Global const variables are treated as if they were numeric literals,
     109             :       // and can be used anywhere a literal can be used.
     110             :       kConstGlobal,
     111             :       kImmutableGlobal,
     112             :     };
     113             : 
     114    13722775 :     explicit VariableInfo(AsmType* t) : type_(t) {}
     115             : 
     116             :     VariableInfo* Clone(Zone* zone) const;
     117             : 
     118             :     bool IsMutable() const {
     119      143987 :       return mutability_ == kLocal || mutability_ == kMutableGlobal;
     120             :     }
     121             : 
     122             :     bool IsGlobal() const {
     123       30628 :       return mutability_ == kImmutableGlobal || mutability_ == kConstGlobal ||
     124             :              mutability_ == kMutableGlobal;
     125             :     }
     126             : 
     127             :     bool IsStdlib() const { return standard_member_ == kStdlib; }
     128             :     bool IsFFI() const { return standard_member_ == kFFI; }
     129             :     bool IsHeap() const { return standard_member_ == kHeap; }
     130             : 
     131        2671 :     void MarkDefined() { missing_definition_ = false; }
     132             :     void SetFirstForwardUse(const MessageLocation& source_location);
     133             : 
     134             :     StandardMember standard_member() const { return standard_member_; }
     135             :     void set_standard_member(StandardMember standard_member) {
     136    13276257 :       standard_member_ = standard_member;
     137             :     }
     138             : 
     139             :     AsmType* type() const { return type_; }
     140             :     void set_type(AsmType* type) { type_ = type; }
     141             : 
     142             :     Mutability mutability() const { return mutability_; }
     143    13345377 :     void set_mutability(Mutability mutability) { mutability_ = mutability; }
     144             : 
     145             :     bool missing_definition() const { return missing_definition_; }
     146             : 
     147             :     const MessageLocation* source_location() { return &source_location_; }
     148             : 
     149             :     static VariableInfo* ForSpecialSymbol(Zone* zone,
     150             :                                           StandardMember standard_member);
     151             : 
     152             :    private:
     153             :     AsmType* type_;
     154             :     StandardMember standard_member_ = kNone;
     155             :     Mutability mutability_ = kInvalidMutability;
     156             :     // missing_definition_ is set to true for forward definition - i.e., use
     157             :     // before definition.
     158             :     bool missing_definition_ = false;
     159             :     // Used for error messages.
     160             :     MessageLocation source_location_;
     161             :   };
     162             : 
     163             :   // RAII-style manager for the in_function_ member variable.
     164             :   struct FunctionScope {
     165             :     explicit FunctionScope(AsmTyper* typer) : typer_(typer) {
     166             :       DCHECK(!typer_->in_function_);
     167       11690 :       typer_->in_function_ = true;
     168             :       typer_->local_scope_.Clear();
     169       11690 :       typer_->return_type_ = AsmType::None();
     170             :     }
     171             : 
     172             :     ~FunctionScope() {
     173             :       DCHECK(typer_->in_function_);
     174       11690 :       typer_->in_function_ = false;
     175             :     }
     176             : 
     177             :     AsmTyper* typer_;
     178             :   };
     179             : 
     180             :   // FlattenedStatements is an iterator class for ZoneList<Statement*> that
     181             :   // flattens the Block construct in the AST. This is here because we need it in
     182             :   // the tests.
     183             :   class FlattenedStatements {
     184             :    public:
     185             :     explicit FlattenedStatements(Zone* zone, ZoneList<Statement*>* s);
     186             :     Statement* Next();
     187             : 
     188             :    private:
     189             :     struct Context {
     190      134855 :       explicit Context(ZoneList<Statement*>* s) : statements_(s) {}
     191             :       ZoneList<Statement*>* statements_;
     192             :       int next_index_ = 0;
     193             :     };
     194             : 
     195             :     ZoneVector<Context> context_stack_;
     196             : 
     197             :     DISALLOW_IMPLICIT_CONSTRUCTORS(FlattenedStatements);
     198             :   };
     199             : 
     200             :   class SourceLayoutTracker {
     201             :    public:
     202             :     SourceLayoutTracker() = default;
     203             :     bool IsValid() const;
     204        4542 :     void AddUseAsm(const AstNode& node) { use_asm_.AddNewElement(node); }
     205       13738 :     void AddGlobal(const AstNode& node) { globals_.AddNewElement(node); }
     206       11089 :     void AddFunction(const AstNode& node) { functions_.AddNewElement(node); }
     207         264 :     void AddTable(const AstNode& node) { tables_.AddNewElement(node); }
     208        3677 :     void AddExport(const AstNode& node) { exports_.AddNewElement(node); }
     209             : 
     210             :    private:
     211             :     class Section {
     212             :      public:
     213             :       Section() = default;
     214             :       Section(const Section&) = default;
     215             :       Section& operator=(const Section&) = default;
     216             : 
     217             :       void AddNewElement(const AstNode& node);
     218             :       bool IsPrecededBy(const Section& other) const;
     219             : 
     220             :      private:
     221             :       int start_ = kNoSourcePosition;
     222             :       int end_ = kNoSourcePosition;
     223             :     };
     224             : 
     225             :     Section use_asm_;
     226             :     Section globals_;
     227             :     Section functions_;
     228             :     Section tables_;
     229             :     Section exports_;
     230             : 
     231             :     DISALLOW_COPY_AND_ASSIGN(SourceLayoutTracker);
     232             :   };
     233             : 
     234             :   using ObjectTypeMap = ZoneMap<std::string, VariableInfo*>;
     235             :   void InitializeStdlib();
     236             :   void SetTypeOf(AstNode* node, AsmType* type);
     237             : 
     238             :   void AddForwardReference(VariableProxy* proxy, VariableInfo* info);
     239             :   bool AddGlobal(Variable* global, VariableInfo* info);
     240             :   bool AddLocal(Variable* global, VariableInfo* info);
     241             :   // Used for 5.5 GlobalVariableTypeAnnotations
     242             :   VariableInfo* ImportLookup(Property* expr);
     243             :   // 3.3 Environment Lookup
     244             :   // NOTE: In the spec, the lookup function's prototype is
     245             :   //
     246             :   //   Lookup(Delta, Gamma, x)
     247             :   //
     248             :   // Delta is the global_scope_ member, and Gamma, local_scope_.
     249             :   VariableInfo* Lookup(Variable* variable) const;
     250             : 
     251             :   // All of the ValidateXXX methods below return AsmType::None() in case of
     252             :   // validation failure.
     253             : 
     254             :   // 6.1 ValidateModule
     255             :   AsmType* ValidateModuleBeforeFunctionsPhase(FunctionLiteral* fun);
     256             :   AsmType* ValidateModuleFunction(FunctionDeclaration* fun_decl);
     257             :   AsmType* ValidateModuleFunctions(FunctionLiteral* fun);
     258             :   AsmType* ValidateModuleAfterFunctionsPhase(FunctionLiteral* fun);
     259             :   AsmType* ValidateGlobalDeclaration(Assignment* assign);
     260             :   // 6.2 ValidateExport
     261             :   AsmType* ExportType(VariableProxy* fun_export);
     262             :   AsmType* ValidateExport(ReturnStatement* exports);
     263             :   // 6.3 ValidateFunctionTable
     264             :   AsmType* ValidateFunctionTable(Assignment* assign);
     265             :   // 6.4 ValidateFunction
     266             :   AsmType* ValidateFunction(FunctionDeclaration* fun_decl);
     267             :   // 6.5 ValidateStatement
     268             :   AsmType* ValidateStatement(Statement* statement);
     269             :   // 6.5.1 BlockStatement
     270             :   AsmType* ValidateBlockStatement(Block* block);
     271             :   // 6.5.2 ExpressionStatement
     272             :   AsmType* ValidateExpressionStatement(ExpressionStatement* expr);
     273             :   // 6.5.3 EmptyStatement
     274             :   AsmType* ValidateEmptyStatement(EmptyStatement* empty);
     275             :   // 6.5.4 IfStatement
     276             :   AsmType* ValidateIfStatement(IfStatement* if_stmt);
     277             :   // 6.5.5 ReturnStatement
     278             :   AsmType* ValidateReturnStatement(ReturnStatement* ret_stmt);
     279             :   // 6.5.6 IterationStatement
     280             :   // 6.5.6.a WhileStatement
     281             :   AsmType* ValidateWhileStatement(WhileStatement* while_stmt);
     282             :   // 6.5.6.b DoWhileStatement
     283             :   AsmType* ValidateDoWhileStatement(DoWhileStatement* do_while);
     284             :   // 6.5.6.c ForStatement
     285             :   AsmType* ValidateForStatement(ForStatement* for_stmt);
     286             :   // 6.5.7 BreakStatement
     287             :   AsmType* ValidateBreakStatement(BreakStatement* brk_stmt);
     288             :   // 6.5.8 ContinueStatement
     289             :   AsmType* ValidateContinueStatement(ContinueStatement* cont_stmt);
     290             :   // 6.5.9 LabelledStatement
     291             :   // NOTE: we don't need to handle these: Labelled statements are
     292             :   // BreakableStatements in our AST, but BreakableStatement is not a concrete
     293             :   // class -- and we're handling all of BreakableStatement's subclasses.
     294             :   // 6.5.10 SwitchStatement
     295             :   AsmType* ValidateSwitchStatement(SwitchStatement* stmt);
     296             :   // 6.6 ValidateCase
     297             :   AsmType* ValidateCase(CaseClause* label, int32_t* case_lbl);
     298             :   // 6.7 ValidateDefault
     299             :   AsmType* ValidateDefault(CaseClause* label);
     300             :   // 6.8 ValidateExpression
     301             :   AsmType* ValidateExpression(Expression* expr);
     302             :   AsmType* ValidateCompareOperation(CompareOperation* cmp);
     303             :   AsmType* ValidateBinaryOperation(BinaryOperation* binop);
     304             :   // 6.8.1 Expression
     305             :   AsmType* ValidateCommaExpression(BinaryOperation* comma);
     306             :   // 6.8.2 NumericLiteral
     307             :   AsmType* ValidateNumericLiteral(Literal* literal);
     308             :   // 6.8.3 Identifier
     309             :   AsmType* ValidateIdentifier(VariableProxy* proxy);
     310             :   // 6.8.4 CallExpression
     311             :   AsmType* ValidateCallExpression(Call* call);
     312             :   // 6.8.5 MemberExpression
     313             :   AsmType* ValidateMemberExpression(Property* prop);
     314             :   // 6.8.6 AssignmentExpression
     315             :   AsmType* ValidateAssignmentExpression(Assignment* assignment);
     316             :   // 6.8.7 UnaryExpression
     317             :   AsmType* ValidateUnaryExpression(UnaryOperation* unop);
     318             :   // 6.8.8 MultiplicativeExpression
     319             :   AsmType* ValidateMultiplicativeExpression(BinaryOperation* binop);
     320             :   // 6.8.9 AdditiveExpression
     321             :   AsmType* ValidateAdditiveExpression(BinaryOperation* binop,
     322             :                                       uint32_t intish_count);
     323             :   // 6.8.10 ShiftExpression
     324             :   AsmType* ValidateShiftExpression(BinaryOperation* binop);
     325             :   // 6.8.11 RelationalExpression
     326             :   AsmType* ValidateRelationalExpression(CompareOperation* cmpop);
     327             :   // 6.8.12 EqualityExpression
     328             :   AsmType* ValidateEqualityExpression(CompareOperation* cmpop);
     329             :   // 6.8.13 BitwiseANDExpression
     330             :   AsmType* ValidateBitwiseANDExpression(BinaryOperation* binop);
     331             :   // 6.8.14 BitwiseXORExpression
     332             :   AsmType* ValidateBitwiseXORExpression(BinaryOperation* binop);
     333             :   // 6.8.15 BitwiseORExpression
     334             :   AsmType* ValidateBitwiseORExpression(BinaryOperation* binop);
     335             :   // 6.8.16 ConditionalExpression
     336             :   AsmType* ValidateConditionalExpression(Conditional* cond);
     337             :   // 6.9 ValidateCall
     338             :   AsmType* ValidateCall(AsmType* return_type, Call* call);
     339             :   // 6.10 ValidateHeapAccess
     340             :   enum HeapAccessType { LoadFromHeap, StoreToHeap };
     341             :   AsmType* ValidateHeapAccess(Property* heap, HeapAccessType access_type);
     342             :   // 6.11 ValidateFloatCoercion
     343             :   bool IsCallToFround(Call* call);
     344             :   AsmType* ValidateFloatCoercion(Call* call);
     345             : 
     346             :   // 5.1 ParameterTypeAnnotations
     347             :   AsmType* ParameterTypeAnnotations(Variable* parameter,
     348             :                                     Expression* annotation);
     349             :   // 5.2 ReturnTypeAnnotations
     350             :   AsmType* ReturnTypeAnnotations(Expression* ret_expr);
     351             :   // 5.4 VariableTypeAnnotations
     352             :   // 5.5 GlobalVariableTypeAnnotations
     353             :   AsmType* VariableTypeAnnotations(
     354             :       Expression* initializer,
     355             :       VariableInfo::Mutability global = VariableInfo::kLocal);
     356             :   AsmType* ImportExpression(Property* import);
     357             :   AsmType* NewHeapView(CallNew* new_heap_view);
     358             : 
     359             :   Isolate* isolate_;
     360             :   Zone* zone_;
     361             :   Handle<Script> script_;
     362             :   FunctionLiteral* root_;
     363             :   bool in_function_ = false;
     364             : 
     365             :   AsmType* return_type_ = nullptr;
     366             : 
     367             :   ZoneVector<VariableInfo*> forward_definitions_;
     368             :   ZoneVector<FFIUseSignature> ffi_use_signatures_;
     369             :   ObjectTypeMap stdlib_types_;
     370             :   ObjectTypeMap stdlib_math_types_;
     371             : 
     372             :   // The ASM module name. This member is used to prevent globals from redefining
     373             :   // the module name.
     374             :   VariableInfo* module_info_;
     375             :   Handle<String> module_name_;
     376             : 
     377             :   // 3 Environments
     378             :   ZoneHashMap global_scope_;  // 3.1 Global environment
     379             :   ZoneHashMap local_scope_;   // 3.2 Variable environment
     380             : 
     381             :   std::uintptr_t stack_limit_;
     382             :   bool stack_overflow_ = false;
     383             :   std::unordered_map<AstNode*, AsmType*> module_node_types_;
     384             :   std::unordered_map<AstNode*, AsmType*> function_node_types_;
     385             :   static const int kErrorMessageLimit = 128;
     386             :   AsmType* fround_type_;
     387             :   AsmType* ffi_type_;
     388             :   Handle<JSMessageObject> error_message_;
     389             :   MessageLocation message_location_;
     390             :   StdlibSet stdlib_uses_;
     391             : 
     392             :   SourceLayoutTracker source_layout_;
     393             :   ReturnStatement* module_return_;
     394             :   ZoneVector<Assignment*> function_pointer_tables_;
     395             : 
     396             :   DISALLOW_IMPLICIT_CONSTRUCTORS(AsmTyper);
     397             : };
     398             : 
     399             : }  // namespace wasm
     400             : }  // namespace internal
     401             : }  // namespace v8
     402             : 
     403             : #endif  // SRC_ASMJS_ASM_TYPER_H_

Generated by: LCOV version 1.10