Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(350)

Unified Diff: src/asmjs/asm-parser.h

Issue 2757693003: [wasm][asm.js] Asm.js -> wasm custom parser. (Closed)
Patch Set: fix Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/asmjs/asm-js.cc ('k') | src/asmjs/asm-parser.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/asmjs/asm-parser.h
diff --git a/src/asmjs/asm-parser.h b/src/asmjs/asm-parser.h
new file mode 100644
index 0000000000000000000000000000000000000000..86aec71636945215fdd008e2c45ad5281b1b97de
--- /dev/null
+++ b/src/asmjs/asm-parser.h
@@ -0,0 +1,304 @@
+// Copyright 2017 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_ASMJS_ASM_PARSER_H_
+#define V8_ASMJS_ASM_PARSER_H_
+
+#include <list>
+#include <string>
+#include <vector>
+
+#include "src/asmjs/asm-scanner.h"
+#include "src/asmjs/asm-typer.h"
+#include "src/asmjs/asm-types.h"
+#include "src/wasm/signature-map.h"
+#include "src/wasm/wasm-module-builder.h"
+#include "src/zone/zone-containers.h"
+
+namespace v8 {
+namespace internal {
+namespace wasm {
+
+// A custom parser + validator + wasm converter for asm.js:
+// http://asmjs.org/spec/latest/
+// This parser intentionally avoids the portion of JavaScript parsing
+// that are not required to determine if code is valid asm.js code.
+// * It is mostly one pass.
+// * It bails out on unexpected input.
+// * It assumes strict ordering insofar as permitted by asm.js validation rules.
+// * It relies on a custom scanner that provides de-duped identifiers in two
+// scopes (local + module wide).
+class AsmJsParser {
+ public:
+ explicit AsmJsParser(Isolate* isolate, Zone* zone, Handle<Script> script,
+ int start, int end);
+ bool Run();
+ const char* failure_message() const { return failure_message_.c_str(); }
+ int failure_location() const { return failure_location_; }
+ WasmModuleBuilder* module_builder() { return module_builder_; }
+ const AsmTyper::StdlibSet* stdlib_uses() const { return &stdlib_uses_; }
+
+ private:
+ // clang-format off
+ enum class VarKind {
+ kUnused,
+ kLocal,
+ kGlobal,
+ kSpecial,
+ kFunction,
+ kTable,
+ kImportedFunction,
+#define V(_unused0, Name, _unused1, _unused2) kMath##Name,
+ STDLIB_MATH_FUNCTION_LIST(V)
+#undef V
+#define V(Name) kMath##Name,
+ STDLIB_MATH_VALUE_LIST(V)
+#undef V
+ };
+ // clang-format on
+
+ struct FunctionImportInfo {
+ std::string name;
+ SignatureMap cache;
+ std::vector<uint32_t> cache_index;
+ };
+
+ struct VarInfo {
+ AsmType* type;
+ WasmFunctionBuilder* function_builder;
+ FunctionImportInfo* import;
+ int32_t mask;
+ uint32_t index;
+ VarKind kind;
+ bool mutable_variable;
+ bool function_defined;
+
+ VarInfo();
+ void DeclareGlobalImport(AsmType* type, uint32_t index);
+ void DeclareStdlibFunc(VarKind kind, AsmType* type);
+ };
+
+ struct GlobalImport {
+ std::string import_name;
+ uint32_t import_index;
+ uint32_t global_index;
+ bool needs_init;
+ };
+
+ enum class BlockKind { kRegular, kLoop, kOther };
+
+ struct BlockInfo {
+ BlockKind kind;
+ AsmJsScanner::token_t label;
+ };
+
+ Zone* zone_;
+ AsmJsScanner scanner_;
+ WasmModuleBuilder* module_builder_;
+ WasmFunctionBuilder* current_function_builder_;
+ AsmType* return_type_;
+ std::uintptr_t stack_limit_;
+ AsmTyper::StdlibSet stdlib_uses_;
+ std::list<FunctionImportInfo> function_import_info_;
+ ZoneVector<VarInfo> global_var_info_;
+ ZoneVector<VarInfo> local_var_info_;
+
+ int function_temp_locals_offset_;
+ int function_temp_locals_used_;
+
+ // Error Handling related
+ bool failed_;
+ std::string failure_message_;
+ int failure_location_;
+
+ // Module Related.
+ AsmJsScanner::token_t stdlib_name_;
+ AsmJsScanner::token_t foreign_name_;
+ AsmJsScanner::token_t heap_name_;
+
+ static const AsmJsScanner::token_t kTokenNone = 0;
+
+ // Track if parsing a heap assignment.
+ bool inside_heap_assignment_;
+ AsmType* heap_access_type_;
+
+ ZoneVector<BlockInfo> block_stack_;
+
+ // Types used for stdlib function and their set up.
+ AsmType* stdlib_dq2d_;
+ AsmType* stdlib_dqdq2d_;
+ AsmType* stdlib_fq2f_;
+ AsmType* stdlib_i2s_;
+ AsmType* stdlib_ii2s_;
+ AsmType* stdlib_minmax_;
+ AsmType* stdlib_abs_;
+ AsmType* stdlib_ceil_like_;
+ AsmType* stdlib_fround_;
+
+ // When making calls, the return type is needed to lookup signatures.
+ // For +callsite(..) or fround(callsite(..)) use this value to pass
+ // along the coercion.
+ AsmType* call_coercion_;
+
+ // Used to track the last label we've seen so it can be matched to later
+ // statements it's attached to.
+ AsmJsScanner::token_t pending_label_;
+
+ // Global imports.
+ // NOTE: Holds the strings referenced in wasm-module-builder for imports.
+ ZoneLinkedList<GlobalImport> global_imports_;
+
+ Zone* zone() { return zone_; }
+
+ inline bool Peek(AsmJsScanner::token_t token) {
+ return scanner_.Token() == token;
+ }
+
+ inline bool Check(AsmJsScanner::token_t token) {
+ if (scanner_.Token() == token) {
+ scanner_.Next();
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ inline bool CheckForZero() {
+ if (scanner_.IsUnsigned() && scanner_.AsUnsigned() == 0) {
+ scanner_.Next();
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ inline bool CheckForDouble(double* value) {
+ if (scanner_.IsDouble()) {
+ *value = scanner_.AsDouble();
+ scanner_.Next();
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ inline bool CheckForUnsigned(uint64_t* value) {
+ if (scanner_.IsUnsigned()) {
+ *value = scanner_.AsUnsigned();
+ scanner_.Next();
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ inline bool CheckForUnsignedBelow(uint64_t limit, uint64_t* value) {
+ if (scanner_.IsUnsigned() && scanner_.AsUnsigned() < limit) {
+ *value = scanner_.AsUnsigned();
+ scanner_.Next();
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ inline AsmJsScanner::token_t Consume() {
+ AsmJsScanner::token_t ret = scanner_.Token();
+ scanner_.Next();
+ return ret;
+ }
+
+ void SkipSemicolon();
+
+ VarInfo* GetVarInfo(AsmJsScanner::token_t token);
+ uint32_t VarIndex(VarInfo* info);
+ void DeclareGlobal(VarInfo* info, bool mutable_variable, AsmType* type,
+ ValueType vtype,
+ const WasmInitExpr& init = WasmInitExpr());
+
+ int32_t TempVariable(int i);
+
+ void AddGlobalImport(std::string name, AsmType* type, ValueType vtype,
+ bool mutable_variable, VarInfo* info);
+
+ // Use to set up block stack layers (including synthetic ones for if-else).
+ // Begin/Loop/End below are implemented with these plus code generation.
+ void BareBegin(BlockKind kind = BlockKind::kOther,
+ AsmJsScanner::token_t label = 0);
+ void BareEnd();
+ int FindContinueLabelDepth(AsmJsScanner::token_t label);
+ int FindBreakLabelDepth(AsmJsScanner::token_t label);
+
+ // Use to set up actual wasm blocks/loops.
+ void Begin(AsmJsScanner::token_t label = 0);
+ void Loop(AsmJsScanner::token_t label = 0);
+ void End();
+
+ void InitializeStdlibTypes();
+
+ FunctionSig* ConvertSignature(AsmType* return_type,
+ const std::vector<AsmType*>& params);
+
+ // 6.1 ValidateModule
+ void ValidateModule();
+ void ValidateModuleParameters();
+ void ValidateModuleVars();
+ void ValidateModuleVar(bool mutable_variable);
+ bool ValidateModuleVarImport(VarInfo* info, bool mutable_variable);
+ void ValidateModuleVarStdlib(VarInfo* info);
+ void ValidateModuleVarNewStdlib(VarInfo* info);
+ void ValidateModuleVarFloat(VarInfo* info, bool mutable_variable);
+
+ void ValidateExport(); // 6.2 ValidateExport
+ void ValidateFunctionTable(); // 6.3 ValidateFunctionTable
+ void ValidateFunction(); // 6.4 ValidateFunction
+ void ValidateFunctionParams(std::vector<AsmType*>* params);
+ void ValidateFunctionLocals(size_t param_count,
+ std::vector<ValueType>* locals);
+ void ValidateStatement(); // ValidateStatement
+ void Block(); // 6.5.1 Block
+ void ExpressionStatement(); // 6.5.2 ExpressionStatement
+ void EmptyStatement(); // 6.5.3 EmptyStatement
+ void IfStatement(); // 6.5.4 IfStatement
+ void ReturnStatement(); // 6.5.5 ReturnStatement
+ bool IterationStatement(); // 6.5.6 IterationStatement
+ void WhileStatement(); // 6.5.6 IterationStatement - while
+ void DoStatement(); // 6.5.6 IterationStatement - do
+ void ForStatement(); // 6.5.6 IterationStatement - for
+ void BreakStatement(); // 6.5.7 BreakStatement
+ void ContinueStatement(); // 6.5.8 ContinueStatement
+ void LabelledStatement(); // 6.5.9 LabelledStatement
+ void SwitchStatement(); // 6.5.10 SwitchStatement
+ void ValidateCase(); // 6.6. ValidateCase
+ void ValidateDefault(); // 6.7 ValidateDefault
+ AsmType* ValidateExpression(); // 6.8 ValidateExpression
+ AsmType* Expression(AsmType* expect); // 6.8.1 Expression
+ AsmType* NumericLiteral(); // 6.8.2 NumericLiteral
+ AsmType* Identifier(); // 6.8.3 Identifier
+ AsmType* CallExpression(); // 6.8.4 CallExpression
+ AsmType* MemberExpression(); // 6.8.5 MemberExpression
+ AsmType* AssignmentExpression(); // 6.8.6 AssignmentExpression
+ AsmType* UnaryExpression(); // 6.8.7 UnaryExpression
+ AsmType* MultiplicativeExpression(); // 6.8.8 MultaplicativeExpression
+ AsmType* AdditiveExpression(); // 6.8.9 AdditiveExpression
+ AsmType* ShiftExpression(); // 6.8.10 ShiftExpression
+ AsmType* RelationalExpression(); // 6.8.11 RelationalExpression
+ AsmType* EqualityExpression(); // 6.8.12 EqualityExpression
+ AsmType* BitwiseANDExpression(); // 6.8.13 BitwiseANDExpression
+ AsmType* BitwiseXORExpression(); // 6.8.14 BitwiseXORExpression
+ AsmType* BitwiseORExpression(); // 6.8.15 BitwiseORExpression
+ AsmType* ConditionalExpression(); // 6.8.16 ConditionalExpression
+ AsmType* ParenthesizedExpression(); // 6.8.17 ParenthesiedExpression
+ AsmType* ValidateCall(); // 6.9 ValidateCall
+ bool PeekCall(); // 6.9 ValidateCall - helper
+ void ValidateHeapAccess(); // 6.10 ValidateHeapAccess
+ void ValidateFloatCoercion(); // 6.11 ValidateFloatCoercion
+
+ void GatherCases(std::vector<int32_t>* cases);
+};
+
+} // namespace wasm
+} // namespace internal
+} // namespace v8
+#endif
« no previous file with comments | « src/asmjs/asm-js.cc ('k') | src/asmjs/asm-parser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698