OLD | NEW |
(Empty) | |
| 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 |
| 11 #include "src/allocation.h" |
| 12 #include "src/asmjs/asm-types.h" |
| 13 #include "src/ast/ast-type-bounds.h" |
| 14 #include "src/ast/ast.h" |
| 15 #include "src/effects.h" |
| 16 #include "src/type-info.h" |
| 17 #include "src/types.h" |
| 18 #include "src/zone-containers.h" |
| 19 #include "src/zone.h" |
| 20 |
| 21 namespace v8 { |
| 22 namespace internal { |
| 23 namespace wasm { |
| 24 |
| 25 class AsmTyperHarnessBuilder; |
| 26 |
| 27 class AsmTyper final { |
| 28 public: |
| 29 enum StandardMember { |
| 30 kHeap = -4, |
| 31 kFFI = -3, |
| 32 kStdlib = -2, |
| 33 kModule = -1, |
| 34 kNone = 0, |
| 35 kInfinity, |
| 36 kNaN, |
| 37 kMathAcos, |
| 38 kMathAsin, |
| 39 kMathAtan, |
| 40 kMathCos, |
| 41 kMathSin, |
| 42 kMathTan, |
| 43 kMathExp, |
| 44 kMathLog, |
| 45 kMathCeil, |
| 46 kMathFloor, |
| 47 kMathSqrt, |
| 48 kMathAbs, |
| 49 kMathMin, |
| 50 kMathMax, |
| 51 kMathAtan2, |
| 52 kMathPow, |
| 53 kMathImul, |
| 54 kMathFround, |
| 55 kMathE, |
| 56 kMathLN10, |
| 57 kMathLN2, |
| 58 kMathLOG2E, |
| 59 kMathLOG10E, |
| 60 kMathPI, |
| 61 kMathSQRT1_2, |
| 62 kMathSQRT2, |
| 63 }; |
| 64 |
| 65 ~AsmTyper() = default; |
| 66 AsmTyper(Isolate* isolate, Zone* zone, Script* script, FunctionLiteral* root); |
| 67 |
| 68 bool Validate(); |
| 69 |
| 70 const char* error_message() const { return error_message_; } |
| 71 |
| 72 AsmType* TypeOf(AstNode* node) const; |
| 73 StandardMember VariableAsStandardMember(Variable* var); |
| 74 |
| 75 private: |
| 76 friend class v8::internal::wasm::AsmTyperHarnessBuilder; |
| 77 |
| 78 class VariableInfo : public ZoneObject { |
| 79 public: |
| 80 enum Mutability { |
| 81 kInvalidMutability, |
| 82 kLocal, |
| 83 kMutableGlobal, |
| 84 kImmutableGlobal, |
| 85 }; |
| 86 |
| 87 VariableInfo() = default; |
| 88 explicit VariableInfo(AsmType* t) : type_(t) {} |
| 89 |
| 90 VariableInfo* Clone(Zone* zone) const; |
| 91 |
| 92 bool IsMutable() const { |
| 93 return mutability_ == kLocal || mutability_ == kMutableGlobal; |
| 94 } |
| 95 |
| 96 bool IsGlobal() const { |
| 97 return mutability_ == kImmutableGlobal || mutability_ == kMutableGlobal; |
| 98 } |
| 99 |
| 100 bool IsStdlib() const { return standard_member_ == kStdlib; } |
| 101 bool IsFFI() const { return standard_member_ == kFFI; } |
| 102 bool IsHeap() const { return standard_member_ == kHeap; } |
| 103 |
| 104 void MarkDefined() { missing_definition_ = false; } |
| 105 void FirstForwardUseIs(VariableProxy* var); |
| 106 |
| 107 StandardMember standard_member() const { return standard_member_; } |
| 108 void set_standard_member(StandardMember standard_member) { |
| 109 standard_member_ = standard_member; |
| 110 } |
| 111 |
| 112 AsmType* type() const { return type_; } |
| 113 void set_type(AsmType* type) { type_ = type; } |
| 114 |
| 115 Mutability mutability() const { return mutability_; } |
| 116 void set_mutability(Mutability mutability) { mutability_ = mutability; } |
| 117 |
| 118 bool missing_definition() const { return missing_definition_; } |
| 119 |
| 120 VariableProxy* first_forward_use() const { return first_forward_use_; } |
| 121 |
| 122 private: |
| 123 AsmType* type_ = AsmType::None(); |
| 124 StandardMember standard_member_ = kNone; |
| 125 Mutability mutability_ = kInvalidMutability; |
| 126 // missing_definition_ is set to true for forward definition - i.e., use |
| 127 // before definition. |
| 128 bool missing_definition_ = false; |
| 129 // first_forward_use_ holds the AST node that first referenced this |
| 130 // VariableInfo. Used for error messages. |
| 131 VariableProxy* first_forward_use_ = nullptr; |
| 132 }; |
| 133 |
| 134 // RAII-style manager for the in_function_ member variable. |
| 135 struct FunctionScope { |
| 136 explicit FunctionScope(AsmTyper* typer) : typer_(typer) { |
| 137 DCHECK(!typer_->in_function_); |
| 138 typer_->in_function_ = true; |
| 139 typer_->local_scope_.Clear(); |
| 140 typer_->return_type_ = AsmType::None(); |
| 141 } |
| 142 |
| 143 ~FunctionScope() { |
| 144 DCHECK(typer_->in_function_); |
| 145 typer_->in_function_ = false; |
| 146 } |
| 147 |
| 148 AsmTyper* typer_; |
| 149 }; |
| 150 |
| 151 // FlattenedStatements is an iterator class for ZoneList<Statement*> that |
| 152 // flattens the Block construct in the AST. This is here because we need it in |
| 153 // the tests. |
| 154 class FlattenedStatements { |
| 155 public: |
| 156 explicit FlattenedStatements(Zone* zone, ZoneList<Statement*>* s); |
| 157 Statement* Next(); |
| 158 |
| 159 private: |
| 160 struct Context { |
| 161 explicit Context(ZoneList<Statement*>* s) : statements_(s) {} |
| 162 ZoneList<Statement*>* statements_; |
| 163 int next_index_ = 0; |
| 164 }; |
| 165 |
| 166 ZoneVector<Context> context_stack_; |
| 167 |
| 168 DISALLOW_IMPLICIT_CONSTRUCTORS(FlattenedStatements); |
| 169 }; |
| 170 |
| 171 using ObjectTypeMap = ZoneMap<std::string, VariableInfo*>; |
| 172 void InitializeStdlib(); |
| 173 void SetTypeOf(AstNode* node, AsmType* type); |
| 174 |
| 175 void AddForwardReference(VariableProxy* proxy, VariableInfo* info); |
| 176 bool AddGlobal(Variable* global, VariableInfo* info); |
| 177 bool AddLocal(Variable* global, VariableInfo* info); |
| 178 // Used for 5.5 GlobalVariableTypeAnnotations |
| 179 VariableInfo* ImportLookup(Property* expr); |
| 180 // 3.3 Environment Lookup |
| 181 // NOTE: In the spec, the lookup function's prototype is |
| 182 // |
| 183 // Lookup(Delta, Gamma, x) |
| 184 // |
| 185 // Delta is the global_scope_ member, and Gamma, local_scope_. |
| 186 VariableInfo* Lookup(Variable* variable); |
| 187 |
| 188 // All of the ValidateXXX methods below return AsmType::None() in case of |
| 189 // validation failure. |
| 190 |
| 191 // 6.1 ValidateModule |
| 192 AsmType* ValidateModule(FunctionLiteral* fun); |
| 193 AsmType* ValidateGlobalDeclaration(Assignment* assign); |
| 194 // 6.2 ValidateExport |
| 195 AsmType* ExportType(VariableProxy* fun_export); |
| 196 AsmType* ValidateExport(ReturnStatement* exports); |
| 197 // 6.3 ValidateFunctionTable |
| 198 AsmType* ValidateFunctionTable(Assignment* assign); |
| 199 // 6.4 ValidateFunction |
| 200 AsmType* ValidateFunction(FunctionDeclaration* fun_decl); |
| 201 // 6.5 ValidateStatement |
| 202 AsmType* ValidateStatement(Statement* statement); |
| 203 // 6.5.1 BlockStatement |
| 204 AsmType* ValidateBlockStatement(Block* block); |
| 205 // 6.5.2 ExpressionStatement |
| 206 AsmType* ValidateExpressionStatement(ExpressionStatement* expr); |
| 207 // 6.5.3 EmptyStatement |
| 208 AsmType* ValidateEmptyStatement(EmptyStatement* empty); |
| 209 // 6.5.4 IfStatement |
| 210 AsmType* ValidateIfStatement(IfStatement* if_stmt); |
| 211 // 6.5.5 ReturnStatement |
| 212 AsmType* ValidateReturnStatement(ReturnStatement* ret_stmt); |
| 213 // 6.5.6 IterationStatement |
| 214 // 6.5.6.a WhileStatement |
| 215 AsmType* ValidateWhileStatement(WhileStatement* while_stmt); |
| 216 // 6.5.6.b DoWhileStatement |
| 217 AsmType* ValidateDoWhileStatement(DoWhileStatement* do_while); |
| 218 // 6.5.6.c ForStatement |
| 219 AsmType* ValidateForStatement(ForStatement* for_stmt); |
| 220 // 6.5.7 BreakStatement |
| 221 AsmType* ValidateBreakStatement(BreakStatement* brk_stmt); |
| 222 // 6.5.8 ContinueStatement |
| 223 AsmType* ValidateContinueStatement(ContinueStatement* cont_stmt); |
| 224 // 6.5.9 LabelledStatement |
| 225 // NOTE: we don't need to handle these: Labelled statements are |
| 226 // BreakableStatements in our AST, but BreakableStatement is not a concrete |
| 227 // class -- and we're handling all of BreakableStatement's subclasses. |
| 228 // 6.5.10 SwitchStatement |
| 229 AsmType* ValidateSwitchStatement(SwitchStatement* stmt); |
| 230 // 6.6 ValidateCase |
| 231 AsmType* ValidateCase(CaseClause* label, int32_t* case_lbl); |
| 232 // 6.7 ValidateDefault |
| 233 AsmType* ValidateDefault(CaseClause* label); |
| 234 // 6.8 ValidateExpression |
| 235 AsmType* ValidateExpression(Expression* expr); |
| 236 AsmType* ValidateCompareOperation(CompareOperation* cmp); |
| 237 AsmType* ValidateBinaryOperation(BinaryOperation* binop); |
| 238 // 6.8.1 Expression |
| 239 AsmType* ValidateCommaExpression(BinaryOperation* comma); |
| 240 // 6.8.2 NumericLiteral |
| 241 AsmType* ValidateNumericLiteral(Literal* literal); |
| 242 // 6.8.3 Identifier |
| 243 AsmType* ValidateIdentifier(VariableProxy* proxy); |
| 244 // 6.8.4 CallExpression |
| 245 AsmType* ValidateCallExpression(Call* call); |
| 246 // 6.8.5 MemberExpression |
| 247 AsmType* ValidateMemberExpression(Property* prop); |
| 248 // 6.8.6 AssignmentExpression |
| 249 AsmType* ValidateAssignmentExpression(Assignment* assignment); |
| 250 // 6.8.7 UnaryExpression |
| 251 AsmType* ValidateUnaryExpression(UnaryOperation* unop); |
| 252 // 6.8.8 MultiplicativeExpression |
| 253 AsmType* ValidateMultiplicativeExpression(BinaryOperation* binop); |
| 254 // 6.8.9 AdditiveExpression |
| 255 AsmType* ValidateAdditiveExpression(BinaryOperation* binop, |
| 256 uint32_t intish_count); |
| 257 // 6.8.10 ShiftExpression |
| 258 AsmType* ValidateShiftExpression(BinaryOperation* binop); |
| 259 // 6.8.11 RelationalExpression |
| 260 AsmType* ValidateRelationalExpression(CompareOperation* cmpop); |
| 261 // 6.8.12 EqualityExpression |
| 262 AsmType* ValidateEqualityExpression(CompareOperation* cmpop); |
| 263 // 6.8.13 BitwiseANDExpression |
| 264 AsmType* ValidateBitwiseANDExpression(BinaryOperation* binop); |
| 265 // 6.8.14 BitwiseXORExpression |
| 266 AsmType* ValidateBitwiseXORExpression(BinaryOperation* binop); |
| 267 // 6.8.15 BitwiseORExpression |
| 268 AsmType* ValidateBitwiseORExpression(BinaryOperation* binop); |
| 269 // 6.8.16 ConditionalExpression |
| 270 AsmType* ValidateConditionalExpression(Conditional* cond); |
| 271 // 6.9 ValidateCall |
| 272 AsmType* ValidateCall(AsmType* return_type, Call* call); |
| 273 // 6.10 ValidateHeapAccess |
| 274 enum HeapAccessType { LoadFromHeap, StoreToHeap }; |
| 275 AsmType* ValidateHeapAccess(Property* heap, HeapAccessType access_type); |
| 276 // 6.11 ValidateFloatCoercion |
| 277 bool IsCallToFround(Call* call); |
| 278 AsmType* ValidateFloatCoercion(Call* call); |
| 279 |
| 280 // 5.1 ParameterTypeAnnotations |
| 281 AsmType* ParameterTypeAnnotations(Variable* parameter, |
| 282 Expression* annotation); |
| 283 // 5.2 ReturnTypeAnnotations |
| 284 AsmType* ReturnTypeAnnotations(ReturnStatement* statement); |
| 285 // 5.4 VariableTypeAnnotations |
| 286 AsmType* VariableTypeAnnotations(Expression* initializer); |
| 287 // 5.5 GlobalVariableTypeAnnotations |
| 288 AsmType* ImportExpression(Property* import); |
| 289 AsmType* NewHeapView(CallNew* new_heap_view); |
| 290 |
| 291 Isolate* isolate_; |
| 292 Zone* zone_; |
| 293 Script* script_; |
| 294 FunctionLiteral* root_; |
| 295 bool in_function_ = false; |
| 296 |
| 297 AsmType* return_type_ = nullptr; |
| 298 |
| 299 ZoneVector<VariableInfo*> forward_definitions_; |
| 300 ObjectTypeMap stdlib_types_; |
| 301 ObjectTypeMap stdlib_math_types_; |
| 302 |
| 303 // The ASM module name. This member is used to prevent globals from redefining |
| 304 // the module name. |
| 305 VariableInfo module_info_; |
| 306 Handle<String> module_name_; |
| 307 |
| 308 // 3 Environments |
| 309 ZoneHashMap global_scope_; // 3.1 Global environment |
| 310 ZoneHashMap local_scope_; // 3.2 Variable environment |
| 311 |
| 312 std::uintptr_t stack_limit_; |
| 313 bool stack_overflow_ = false; |
| 314 ZoneMap<AstNode*, AsmType*> node_types_; |
| 315 static const int kErrorMessageLimit = 100; |
| 316 char error_message_[kErrorMessageLimit]; |
| 317 |
| 318 DISALLOW_IMPLICIT_CONSTRUCTORS(AsmTyper); |
| 319 }; |
| 320 |
| 321 } // namespace wasm |
| 322 } // namespace internal |
| 323 } // namespace v8 |
| 324 |
| 325 #endif // SRC_ASMJS_ASM_TYPER_H_ |
OLD | NEW |