| Index: src/asmjs/typing-asm.cc
|
| diff --git a/src/typing-asm.cc b/src/asmjs/typing-asm.cc
|
| similarity index 99%
|
| rename from src/typing-asm.cc
|
| rename to src/asmjs/typing-asm.cc
|
| index 4b681418d7b3f6c0826a4d3ee3fee87cd6a1365e..f3a4ad82ce9e2856654c770f794cec6e2657f0f0 100644
|
| --- a/src/typing-asm.cc
|
| +++ b/src/asmjs/typing-asm.cc
|
| @@ -2,7 +2,7 @@
|
| // Use of this source code is governed by a BSD-style license that can be
|
| // found in the LICENSE file.
|
|
|
| -#include "src/typing-asm.h"
|
| +#include "src/asmjs/typing-asm.h"
|
|
|
| #include <limits>
|
|
|
| @@ -43,6 +43,7 @@ AsmTyper::AsmTyper(Isolate* isolate, Zone* zone, Script* script,
|
| root_(root),
|
| valid_(true),
|
| allow_simd_(false),
|
| + fixed_signature_(false),
|
| property_info_(nullptr),
|
| intish_(0),
|
| stdlib_types_(zone),
|
| @@ -67,13 +68,11 @@ AsmTyper::AsmTyper(Isolate* isolate, Zone* zone, Script* script,
|
| InitializeStdlib();
|
| }
|
|
|
| -
|
| bool AsmTyper::Validate() {
|
| VisitAsmModule(root_);
|
| return valid_ && !HasStackOverflow();
|
| }
|
|
|
| -
|
| void AsmTyper::VisitAsmModule(FunctionLiteral* fun) {
|
| Scope* scope = fun->scope();
|
| if (!scope->is_function_scope()) FAIL(fun, "not at function scope");
|
| @@ -85,6 +84,13 @@ void AsmTyper::VisitAsmModule(FunctionLiteral* fun) {
|
| if (!use_asm_literal->raw_value()->AsString()->IsOneByteEqualTo("use asm"))
|
| FAIL(fun, "missing \"use asm\"");
|
|
|
| + // TODO(bradnelson): Generalize this.
|
| + if (fixed_signature_ && scope->num_parameters() != 3) {
|
| + FAIL(fun,
|
| + "only asm modules with (stdlib, foreign, heap) "
|
| + "parameters currently supported");
|
| + }
|
| +
|
| // Module parameters.
|
| for (int i = 0; i < scope->num_parameters(); ++i) {
|
| Variable* param = scope->parameter(i);
|
| @@ -143,7 +149,6 @@ void AsmTyper::VisitAsmModule(FunctionLiteral* fun) {
|
| "expected object export"));
|
| }
|
|
|
| -
|
| void AsmTyper::VisitVariableDeclaration(VariableDeclaration* decl) {
|
| Variable* var = decl->proxy()->var();
|
| if (var->location() != VariableLocation::PARAMETER) {
|
| @@ -157,7 +162,6 @@ void AsmTyper::VisitVariableDeclaration(VariableDeclaration* decl) {
|
| intish_ = 0;
|
| }
|
|
|
| -
|
| void AsmTyper::VisitFunctionDeclaration(FunctionDeclaration* decl) {
|
| if (in_function_) {
|
| FAIL(decl, "function declared inside another");
|
| @@ -172,7 +176,6 @@ void AsmTyper::VisitFunctionDeclaration(FunctionDeclaration* decl) {
|
| SetType(var, Type::Function());
|
| }
|
|
|
| -
|
| void AsmTyper::VisitFunctionAnnotation(FunctionLiteral* fun) {
|
| // Extract result type.
|
| ZoneList<Statement*>* body = fun->body();
|
| @@ -223,7 +226,6 @@ void AsmTyper::VisitFunctionAnnotation(FunctionLiteral* fun) {
|
| SetResult(fun, type);
|
| }
|
|
|
| -
|
| void AsmTyper::VisitExpressionAnnotation(Expression* expr, Variable* var,
|
| bool is_return) {
|
| // Normal +x or x|0 annotations.
|
| @@ -303,7 +305,6 @@ void AsmTyper::VisitExpressionAnnotation(Expression* expr, Variable* var,
|
| FAIL(expr, "invalid type annotation");
|
| }
|
|
|
| -
|
| void AsmTyper::VisitStatements(ZoneList<Statement*>* stmts) {
|
| for (int i = 0; i < stmts->length(); ++i) {
|
| Statement* stmt = stmts->at(i);
|
| @@ -311,30 +312,24 @@ void AsmTyper::VisitStatements(ZoneList<Statement*>* stmts) {
|
| }
|
| }
|
|
|
| -
|
| void AsmTyper::VisitBlock(Block* stmt) {
|
| RECURSE(VisitStatements(stmt->statements()));
|
| }
|
|
|
| -
|
| void AsmTyper::VisitExpressionStatement(ExpressionStatement* stmt) {
|
| RECURSE(VisitWithExpectation(stmt->expression(), Type::Any(),
|
| "expression statement expected to be any"));
|
| }
|
|
|
| -
|
| void AsmTyper::VisitEmptyStatement(EmptyStatement* stmt) {}
|
|
|
| -
|
| void AsmTyper::VisitSloppyBlockFunctionStatement(
|
| SloppyBlockFunctionStatement* stmt) {
|
| Visit(stmt->statement());
|
| }
|
|
|
| -
|
| void AsmTyper::VisitEmptyParentheses(EmptyParentheses* expr) { UNREACHABLE(); }
|
|
|
| -
|
| void AsmTyper::VisitIfStatement(IfStatement* stmt) {
|
| if (!in_function_) {
|
| FAIL(stmt, "if statement inside module body");
|
| @@ -348,21 +343,18 @@ void AsmTyper::VisitIfStatement(IfStatement* stmt) {
|
| RECURSE(Visit(stmt->else_statement()));
|
| }
|
|
|
| -
|
| void AsmTyper::VisitContinueStatement(ContinueStatement* stmt) {
|
| if (!in_function_) {
|
| FAIL(stmt, "continue statement inside module body");
|
| }
|
| }
|
|
|
| -
|
| void AsmTyper::VisitBreakStatement(BreakStatement* stmt) {
|
| if (!in_function_) {
|
| FAIL(stmt, "continue statement inside module body");
|
| }
|
| }
|
|
|
| -
|
| void AsmTyper::VisitReturnStatement(ReturnStatement* stmt) {
|
| // Handle module return statement in VisitAsmModule.
|
| if (!in_function_) {
|
| @@ -381,12 +373,10 @@ void AsmTyper::VisitReturnStatement(ReturnStatement* stmt) {
|
| }
|
| }
|
|
|
| -
|
| void AsmTyper::VisitWithStatement(WithStatement* stmt) {
|
| FAIL(stmt, "bad with statement");
|
| }
|
|
|
| -
|
| void AsmTyper::VisitSwitchStatement(SwitchStatement* stmt) {
|
| if (!in_function_) {
|
| FAIL(stmt, "switch statement inside module body");
|
| @@ -427,10 +417,8 @@ void AsmTyper::VisitSwitchStatement(SwitchStatement* stmt) {
|
| }
|
| }
|
|
|
| -
|
| void AsmTyper::VisitCaseClause(CaseClause* clause) { UNREACHABLE(); }
|
|
|
| -
|
| void AsmTyper::VisitDoWhileStatement(DoWhileStatement* stmt) {
|
| if (!in_function_) {
|
| FAIL(stmt, "do statement inside module body");
|
| @@ -443,7 +431,6 @@ void AsmTyper::VisitDoWhileStatement(DoWhileStatement* stmt) {
|
| }
|
| }
|
|
|
| -
|
| void AsmTyper::VisitWhileStatement(WhileStatement* stmt) {
|
| if (!in_function_) {
|
| FAIL(stmt, "while statement inside module body");
|
| @@ -456,7 +443,6 @@ void AsmTyper::VisitWhileStatement(WhileStatement* stmt) {
|
| RECURSE(Visit(stmt->body()));
|
| }
|
|
|
| -
|
| void AsmTyper::VisitForStatement(ForStatement* stmt) {
|
| if (!in_function_) {
|
| FAIL(stmt, "for statement inside module body");
|
| @@ -477,32 +463,26 @@ void AsmTyper::VisitForStatement(ForStatement* stmt) {
|
| RECURSE(Visit(stmt->body()));
|
| }
|
|
|
| -
|
| void AsmTyper::VisitForInStatement(ForInStatement* stmt) {
|
| FAIL(stmt, "for-in statement encountered");
|
| }
|
|
|
| -
|
| void AsmTyper::VisitForOfStatement(ForOfStatement* stmt) {
|
| FAIL(stmt, "for-of statement encountered");
|
| }
|
|
|
| -
|
| void AsmTyper::VisitTryCatchStatement(TryCatchStatement* stmt) {
|
| FAIL(stmt, "try statement encountered");
|
| }
|
|
|
| -
|
| void AsmTyper::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
|
| FAIL(stmt, "try statement encountered");
|
| }
|
|
|
| -
|
| void AsmTyper::VisitDebuggerStatement(DebuggerStatement* stmt) {
|
| FAIL(stmt, "debugger statement encountered");
|
| }
|
|
|
| -
|
| void AsmTyper::VisitFunctionLiteral(FunctionLiteral* expr) {
|
| if (in_function_) {
|
| FAIL(expr, "invalid nested function");
|
| @@ -526,17 +506,14 @@ void AsmTyper::VisitFunctionLiteral(FunctionLiteral* expr) {
|
| RECURSE(IntersectResult(expr, type));
|
| }
|
|
|
| -
|
| void AsmTyper::VisitNativeFunctionLiteral(NativeFunctionLiteral* expr) {
|
| FAIL(expr, "function info literal encountered");
|
| }
|
|
|
| -
|
| void AsmTyper::VisitDoExpression(DoExpression* expr) {
|
| FAIL(expr, "do-expression encountered");
|
| }
|
|
|
| -
|
| void AsmTyper::VisitConditional(Conditional* expr) {
|
| if (!in_function_) {
|
| FAIL(expr, "ternary operator inside module body");
|
| @@ -572,7 +549,6 @@ void AsmTyper::VisitConditional(Conditional* expr) {
|
| RECURSE(IntersectResult(expr, then_type));
|
| }
|
|
|
| -
|
| void AsmTyper::VisitVariableProxy(VariableProxy* expr) {
|
| Variable* var = expr->var();
|
| VariableInfo* info = GetVariableInfo(var);
|
| @@ -627,15 +603,12 @@ void AsmTyper::VisitLiteral(Literal* expr, bool is_return) {
|
| }
|
| }
|
|
|
| -
|
| void AsmTyper::VisitLiteral(Literal* expr) { VisitLiteral(expr, false); }
|
|
|
| -
|
| void AsmTyper::VisitRegExpLiteral(RegExpLiteral* expr) {
|
| FAIL(expr, "regular expression encountered");
|
| }
|
|
|
| -
|
| void AsmTyper::VisitObjectLiteral(ObjectLiteral* expr) {
|
| if (in_function_) {
|
| FAIL(expr, "object literal in function");
|
| @@ -653,7 +626,6 @@ void AsmTyper::VisitObjectLiteral(ObjectLiteral* expr) {
|
| RECURSE(IntersectResult(expr, Type::Object()));
|
| }
|
|
|
| -
|
| void AsmTyper::VisitArrayLiteral(ArrayLiteral* expr) {
|
| if (in_function_) {
|
| FAIL(expr, "array literal inside a function");
|
| @@ -673,7 +645,6 @@ void AsmTyper::VisitArrayLiteral(ArrayLiteral* expr) {
|
| RECURSE(IntersectResult(expr, Type::Array(elem_type, zone())));
|
| }
|
|
|
| -
|
| void AsmTyper::VisitAssignment(Assignment* expr) {
|
| // Handle function tables and everything else in different passes.
|
| if (!in_function_) {
|
| @@ -739,17 +710,14 @@ void AsmTyper::VisitAssignment(Assignment* expr) {
|
| RECURSE(IntersectResult(expr, target_type));
|
| }
|
|
|
| -
|
| void AsmTyper::VisitYield(Yield* expr) {
|
| FAIL(expr, "yield expression encountered");
|
| }
|
|
|
| -
|
| void AsmTyper::VisitThrow(Throw* expr) {
|
| FAIL(expr, "throw statement encountered");
|
| }
|
|
|
| -
|
| int AsmTyper::ElementShiftSize(Type* type) {
|
| if (type->Is(cache_.kAsmSize8)) return 0;
|
| if (type->Is(cache_.kAsmSize16)) return 1;
|
| @@ -758,7 +726,6 @@ int AsmTyper::ElementShiftSize(Type* type) {
|
| return -1;
|
| }
|
|
|
| -
|
| Type* AsmTyper::StorageType(Type* type) {
|
| if (type->Is(cache_.kAsmInt)) {
|
| return cache_.kAsmInt;
|
| @@ -767,7 +734,6 @@ Type* AsmTyper::StorageType(Type* type) {
|
| }
|
| }
|
|
|
| -
|
| void AsmTyper::VisitHeapAccess(Property* expr, bool assigning,
|
| Type* assignment_type) {
|
| ArrayType* array_type = computed_type_->AsArray();
|
| @@ -861,7 +827,6 @@ void AsmTyper::VisitHeapAccess(Property* expr, bool assigning,
|
| }
|
| }
|
|
|
| -
|
| bool AsmTyper::IsStdlibObject(Expression* expr) {
|
| VariableProxy* proxy = expr->AsVariableProxy();
|
| if (proxy == nullptr) {
|
| @@ -881,7 +846,6 @@ bool AsmTyper::IsStdlibObject(Expression* expr) {
|
| return true;
|
| }
|
|
|
| -
|
| Expression* AsmTyper::GetReceiverOfPropertyAccess(Expression* expr,
|
| const char* name) {
|
| Property* property = expr->AsProperty();
|
| @@ -896,25 +860,21 @@ Expression* AsmTyper::GetReceiverOfPropertyAccess(Expression* expr,
|
| return property->obj();
|
| }
|
|
|
| -
|
| bool AsmTyper::IsMathObject(Expression* expr) {
|
| Expression* obj = GetReceiverOfPropertyAccess(expr, "Math");
|
| return obj && IsStdlibObject(obj);
|
| }
|
|
|
| -
|
| bool AsmTyper::IsSIMDObject(Expression* expr) {
|
| Expression* obj = GetReceiverOfPropertyAccess(expr, "SIMD");
|
| return obj && IsStdlibObject(obj);
|
| }
|
|
|
| -
|
| bool AsmTyper::IsSIMDTypeObject(Expression* expr, const char* name) {
|
| Expression* obj = GetReceiverOfPropertyAccess(expr, name);
|
| return obj && IsSIMDObject(obj);
|
| }
|
|
|
| -
|
| void AsmTyper::VisitProperty(Property* expr) {
|
| if (IsMathObject(expr->obj())) {
|
| VisitLibraryAccess(&stdlib_math_types_, expr);
|
| @@ -1078,7 +1038,6 @@ void AsmTyper::VisitCall(Call* expr) {
|
| }
|
| }
|
|
|
| -
|
| void AsmTyper::VisitCallNew(CallNew* expr) {
|
| if (in_function_) {
|
| FAIL(expr, "new not allowed in module function");
|
| @@ -1103,12 +1062,10 @@ void AsmTyper::VisitCallNew(CallNew* expr) {
|
| FAIL(expr, "ill-typed new operator");
|
| }
|
|
|
| -
|
| void AsmTyper::VisitCallRuntime(CallRuntime* expr) {
|
| FAIL(expr, "runtime call not allowed");
|
| }
|
|
|
| -
|
| void AsmTyper::VisitUnaryOperation(UnaryOperation* expr) {
|
| if (!in_function_) {
|
| FAIL(expr, "unary operator inside module body");
|
| @@ -1130,12 +1087,10 @@ void AsmTyper::VisitUnaryOperation(UnaryOperation* expr) {
|
| }
|
| }
|
|
|
| -
|
| void AsmTyper::VisitCountOperation(CountOperation* expr) {
|
| FAIL(expr, "increment or decrement operator encountered");
|
| }
|
|
|
| -
|
| void AsmTyper::VisitIntegerBitwiseOperator(BinaryOperation* expr,
|
| Type* left_expected,
|
| Type* right_expected,
|
| @@ -1179,7 +1134,6 @@ void AsmTyper::VisitIntegerBitwiseOperator(BinaryOperation* expr,
|
| RECURSE(IntersectResult(expr, result_type));
|
| }
|
|
|
| -
|
| void AsmTyper::VisitBinaryOperation(BinaryOperation* expr) {
|
| if (!in_function_) {
|
| if (expr->op() != Token::BIT_OR && expr->op() != Token::MUL) {
|
| @@ -1377,7 +1331,6 @@ void AsmTyper::VisitBinaryOperation(BinaryOperation* expr) {
|
| }
|
| }
|
|
|
| -
|
| void AsmTyper::VisitCompareOperation(CompareOperation* expr) {
|
| if (!in_function_) {
|
| FAIL(expr, "comparison inside module body");
|
| @@ -1416,12 +1369,10 @@ void AsmTyper::VisitCompareOperation(CompareOperation* expr) {
|
| RECURSE(IntersectResult(expr, cache_.kAsmSigned));
|
| }
|
|
|
| -
|
| void AsmTyper::VisitThisFunction(ThisFunction* expr) {
|
| FAIL(expr, "this function not allowed");
|
| }
|
|
|
| -
|
| void AsmTyper::VisitDeclarations(ZoneList<Declaration*>* decls) {
|
| for (int i = 0; i < decls->length(); ++i) {
|
| Declaration* decl = decls->at(i);
|
| @@ -1429,30 +1380,24 @@ void AsmTyper::VisitDeclarations(ZoneList<Declaration*>* decls) {
|
| }
|
| }
|
|
|
| -
|
| void AsmTyper::VisitImportDeclaration(ImportDeclaration* decl) {
|
| FAIL(decl, "import declaration encountered");
|
| }
|
|
|
| -
|
| void AsmTyper::VisitClassLiteral(ClassLiteral* expr) {
|
| FAIL(expr, "class literal not allowed");
|
| }
|
|
|
| -
|
| void AsmTyper::VisitSpread(Spread* expr) { FAIL(expr, "spread not allowed"); }
|
|
|
| -
|
| void AsmTyper::VisitSuperPropertyReference(SuperPropertyReference* expr) {
|
| FAIL(expr, "super property reference not allowed");
|
| }
|
|
|
| -
|
| void AsmTyper::VisitSuperCallReference(SuperCallReference* expr) {
|
| FAIL(expr, "call reference not allowed");
|
| }
|
|
|
| -
|
| void AsmTyper::InitializeStdlibSIMD() {
|
| #define V(NAME, Name, name, lane_count, lane_type) \
|
| { \
|
| @@ -1468,7 +1413,6 @@ void AsmTyper::InitializeStdlibSIMD() {
|
| #undef V
|
| }
|
|
|
| -
|
| void AsmTyper::InitializeStdlib() {
|
| if (allow_simd_) {
|
| InitializeStdlibSIMD();
|
| @@ -1544,7 +1488,6 @@ void AsmTyper::InitializeStdlib() {
|
| #undef TYPED_ARRAY
|
| }
|
|
|
| -
|
| void AsmTyper::VisitLibraryAccess(ObjectTypeMap* map, Property* expr) {
|
| Literal* key = expr->key()->AsLiteral();
|
| if (key == nullptr || !key->IsPropertyName())
|
| @@ -1557,7 +1500,6 @@ void AsmTyper::VisitLibraryAccess(ObjectTypeMap* map, Property* expr) {
|
| property_info_ = info;
|
| }
|
|
|
| -
|
| AsmTyper::VariableInfo* AsmTyper::LibType(ObjectTypeMap* map,
|
| Handle<String> name) {
|
| base::SmartArrayPointer<char> aname = name->ToCString();
|
| @@ -1568,13 +1510,11 @@ AsmTyper::VariableInfo* AsmTyper::LibType(ObjectTypeMap* map,
|
| return i->second;
|
| }
|
|
|
| -
|
| void AsmTyper::SetType(Variable* variable, Type* type) {
|
| VariableInfo* info = MakeVariableInfo(variable);
|
| info->type = type;
|
| }
|
|
|
| -
|
| Type* AsmTyper::GetType(Variable* variable) {
|
| VariableInfo* info = GetVariableInfo(variable);
|
| if (!info) return nullptr;
|
| @@ -1610,7 +1550,6 @@ void AsmTyper::SetVariableInfo(Variable* variable, const VariableInfo* info) {
|
| dest->standard_member = info->standard_member;
|
| }
|
|
|
| -
|
| AsmTyper::StandardMember AsmTyper::VariableAsStandardMember(
|
| Variable* variable) {
|
| VariableInfo* info = GetVariableInfo(variable);
|
| @@ -1618,13 +1557,11 @@ AsmTyper::StandardMember AsmTyper::VariableAsStandardMember(
|
| return info->standard_member;
|
| }
|
|
|
| -
|
| void AsmTyper::SetResult(Expression* expr, Type* type) {
|
| computed_type_ = type;
|
| bounds_.set(expr, Bounds(computed_type_));
|
| }
|
|
|
| -
|
| void AsmTyper::IntersectResult(Expression* expr, Type* type) {
|
| computed_type_ = type;
|
| Type* bounded_type = Type::Intersect(computed_type_, expected_type_, zone());
|
| @@ -1640,7 +1577,6 @@ void AsmTyper::IntersectResult(Expression* expr, Type* type) {
|
| bounds_.set(expr, Bounds(bounded_type));
|
| }
|
|
|
| -
|
| void AsmTyper::VisitWithExpectation(Expression* expr, Type* expected_type,
|
| const char* msg) {
|
| Type* save = expected_type_;
|
| @@ -1659,11 +1595,9 @@ void AsmTyper::VisitWithExpectation(Expression* expr, Type* expected_type,
|
| expected_type_ = save;
|
| }
|
|
|
| -
|
| void AsmTyper::VisitRewritableExpression(RewritableExpression* expr) {
|
| RECURSE(Visit(expr->expression()));
|
| }
|
|
|
| -
|
| } // namespace internal
|
| } // namespace v8
|
|
|