| OLD | NEW | 
|     1 // Copyright 2016 the V8 project authors. All rights reserved. |     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 |     2 // Use of this source code is governed by a BSD-style license that can be | 
|     3 // found in the LICENSE file. |     3 // found in the LICENSE file. | 
|     4  |     4  | 
|     5 #include "src/asmjs/asm-typer.h" |     5 #include "src/asmjs/asm-typer.h" | 
|     6  |     6  | 
|     7 #include <limits> |     7 #include <limits> | 
|     8 #include <string> |     8 #include <string> | 
|     9  |     9  | 
|    10 #include "src/v8.h" |    10 #include "src/v8.h" | 
| (...skipping 793 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   804   CHECK(value != nullptr); |   804   CHECK(value != nullptr); | 
|   805   ZoneList<Expression*>* pointers = value->values(); |   805   ZoneList<Expression*>* pointers = value->values(); | 
|   806  |   806  | 
|   807   // The function table size must be n = 2 ** m, for m >= 0; |   807   // The function table size must be n = 2 ** m, for m >= 0; | 
|   808   // TODO(jpp): should this be capped? |   808   // TODO(jpp): should this be capped? | 
|   809   if (!base::bits::IsPowerOfTwo32(pointers->length())) { |   809   if (!base::bits::IsPowerOfTwo32(pointers->length())) { | 
|   810     FAIL(assign, "Invalid length for function pointer table."); |   810     FAIL(assign, "Invalid length for function pointer table."); | 
|   811   } |   811   } | 
|   812  |   812  | 
|   813   AsmType* table_element_type = nullptr; |   813   AsmType* table_element_type = nullptr; | 
|   814   AsmCallableType* callable_type = nullptr; |  | 
|   815   for (auto* initializer : *pointers) { |   814   for (auto* initializer : *pointers) { | 
|   816     auto* var_proxy = initializer->AsVariableProxy(); |   815     auto* var_proxy = initializer->AsVariableProxy(); | 
|   817     if (var_proxy == nullptr) { |   816     if (var_proxy == nullptr) { | 
|   818       FAIL(initializer, |   817       FAIL(initializer, | 
|   819            "Function pointer table initializer must be a function name."); |   818            "Function pointer table initializer must be a function name."); | 
|   820     } |   819     } | 
|   821  |   820  | 
|   822     auto* var_info = Lookup(var_proxy->var()); |   821     auto* var_info = Lookup(var_proxy->var()); | 
|   823     if (var_info == nullptr) { |   822     if (var_info == nullptr) { | 
|   824       FAIL(var_proxy, |   823       FAIL(var_proxy, | 
|   825            "Undefined identifier in function pointer table initializer."); |   824            "Undefined identifier in function pointer table initializer."); | 
|   826     } |   825     } | 
|   827  |   826  | 
|   828     if (var_info->standard_member() != kNone) { |   827     if (var_info->standard_member() != kNone) { | 
|   829       FAIL(initializer, |   828       FAIL(initializer, | 
|   830            "Function pointer table must not be a member of the standard " |   829            "Function pointer table must not be a member of the standard " | 
|   831            "library."); |   830            "library."); | 
|   832     } |   831     } | 
|   833  |   832  | 
|   834     auto* initializer_callable = var_info->type()->AsFunctionType(); |   833     auto* initializer_type = var_info->type(); | 
|   835     if (initializer_callable == nullptr) { |   834     if (initializer_type->AsFunctionType() == nullptr) { | 
|   836       FAIL(initializer, |   835       FAIL(initializer, | 
|   837            "Function pointer table initializer must be an asm.js function."); |   836            "Function pointer table initializer must be an asm.js function."); | 
|   838     } |   837     } | 
|   839  |   838  | 
|   840     DCHECK(var_info->type()->AsFFIType() == nullptr); |   839     DCHECK(var_info->type()->AsFFIType() == nullptr); | 
|   841     DCHECK(var_info->type()->AsFunctionTableType() == nullptr); |   840     DCHECK(var_info->type()->AsFunctionTableType() == nullptr); | 
|   842  |   841  | 
|   843     if (callable_type == nullptr) { |   842     if (table_element_type == nullptr) { | 
|   844       table_element_type = var_info->type(); |   843       table_element_type = initializer_type; | 
|   845       callable_type = initializer_callable; |   844     } else if (!initializer_type->IsA(table_element_type)) { | 
|   846     } else if (callable_type->ValidateCall(initializer_callable->ReturnType(), |  | 
|   847                                            initializer_callable->Arguments()) == |  | 
|   848                AsmType::None()) { |  | 
|   849       FAIL(initializer, "Type mismatch in function pointer table initializer."); |   845       FAIL(initializer, "Type mismatch in function pointer table initializer."); | 
|   850     } |   846     } | 
|   851   } |   847   } | 
|   852  |   848  | 
|   853   auto* target_info = Lookup(target_variable); |   849   auto* target_info = Lookup(target_variable); | 
|   854   if (target_info == nullptr) { |   850   if (target_info == nullptr) { | 
|   855     // Function pointer tables are the last entities to be validates, so this is |   851     // Function pointer tables are the last entities to be validates, so this is | 
|   856     // unlikely to happen: only unreferenced function tables will not already |   852     // unlikely to happen: only unreferenced function tables will not already | 
|   857     // have an entry in the global scope. |   853     // have an entry in the global scope. | 
|   858     target_info = new (zone_) VariableInfo(AsmType::FunctionTableType( |   854     target_info = new (zone_) VariableInfo(AsmType::FunctionTableType( | 
| (...skipping 16 matching lines...) Expand all  Loading... | 
|   875   } |   871   } | 
|   876  |   872  | 
|   877   if (!target_info->missing_definition()) { |   873   if (!target_info->missing_definition()) { | 
|   878     FAIL(assign, "Identifier redefined (function table name)."); |   874     FAIL(assign, "Identifier redefined (function table name)."); | 
|   879   } |   875   } | 
|   880  |   876  | 
|   881   if (target_info_table->length() != pointers->length()) { |   877   if (target_info_table->length() != pointers->length()) { | 
|   882     FAIL(assign, "Function table size mismatch."); |   878     FAIL(assign, "Function table size mismatch."); | 
|   883   } |   879   } | 
|   884  |   880  | 
|   885   auto* function_type = callable_type->AsFunctionType(); |   881   DCHECK(target_info_table->signature()->AsFunctionType()); | 
|   886   if (target_info_table->ValidateCall(function_type->ReturnType(), |   882   if (!table_element_type->IsA(target_info_table->signature())) { | 
|   887                                       function_type->Arguments()) == |  | 
|   888       AsmType::None()) { |  | 
|   889     FAIL(assign, "Function table initializer does not match previous type."); |   883     FAIL(assign, "Function table initializer does not match previous type."); | 
|   890   } |   884   } | 
|   891  |   885  | 
|   892   target_info->MarkDefined(); |   886   target_info->MarkDefined(); | 
|   893   DCHECK(target_info->type() != AsmType::None()); |   887   DCHECK(target_info->type() != AsmType::None()); | 
|   894   SetTypeOf(value, target_info->type()); |   888   SetTypeOf(value, target_info->type()); | 
|   895  |   889  | 
|   896   return target_info->type(); |   890   return target_info->type(); | 
|   897 } |   891 } | 
|   898  |   892  | 
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1043  |  1037  | 
|  1044   auto* fun_type = AsmType::Function(zone_, return_type_); |  1038   auto* fun_type = AsmType::Function(zone_, return_type_); | 
|  1045   auto* fun_type_as_function = fun_type->AsFunctionType(); |  1039   auto* fun_type_as_function = fun_type->AsFunctionType(); | 
|  1046   for (auto* param_type : parameter_types) { |  1040   for (auto* param_type : parameter_types) { | 
|  1047     fun_type_as_function->AddArgument(param_type); |  1041     fun_type_as_function->AddArgument(param_type); | 
|  1048   } |  1042   } | 
|  1049  |  1043  | 
|  1050   auto* fun_var = fun_decl_proxy->var(); |  1044   auto* fun_var = fun_decl_proxy->var(); | 
|  1051   auto* fun_info = new (zone_) VariableInfo(fun_type); |  1045   auto* fun_info = new (zone_) VariableInfo(fun_type); | 
|  1052   fun_info->set_mutability(VariableInfo::kImmutableGlobal); |  1046   fun_info->set_mutability(VariableInfo::kImmutableGlobal); | 
|  1053   auto* old_fun_type = Lookup(fun_var); |  1047   auto* old_fun_info = Lookup(fun_var); | 
|  1054   if (old_fun_type == nullptr) { |  1048   if (old_fun_info == nullptr) { | 
|  1055     if (!ValidAsmIdentifier(fun_var->name())) { |  1049     if (!ValidAsmIdentifier(fun_var->name())) { | 
|  1056       FAIL(fun_decl_proxy, "Invalid asm.js identifier in function name."); |  1050       FAIL(fun_decl_proxy, "Invalid asm.js identifier in function name."); | 
|  1057     } |  1051     } | 
|  1058     if (!AddGlobal(fun_var, fun_info)) { |  1052     if (!AddGlobal(fun_var, fun_info)) { | 
|  1059       DCHECK(false); |  1053       DCHECK(false); | 
|  1060       FAIL(fun_decl, "Redeclared global identifier."); |  1054       FAIL(fun_decl, "Redeclared global identifier."); | 
|  1061     } |  1055     } | 
|  1062  |  1056  | 
|  1063     SetTypeOf(fun, fun_type); |  1057     SetTypeOf(fun, fun_type); | 
|  1064     return fun_type; |  1058     return fun_type; | 
|  1065   } |  1059   } | 
|  1066  |  1060  | 
|  1067   // Not necessarily an error -- fun_decl might have been used before being |  1061   // Not necessarily an error -- fun_decl might have been used before being | 
|  1068   // defined. If that's the case, then the type in the global environment must |  1062   // defined. If that's the case, then the type in the global environment must | 
|  1069   // be the same as the type inferred by the parameter/return type annotations. |  1063   // be the same as the type inferred by the parameter/return type annotations. | 
|  1070   auto* old_fun_callable = old_fun_type->type()->AsCallableType(); |  1064   auto* old_fun_type = old_fun_info->type(); | 
|  1071   if (old_fun_callable == nullptr) { |  1065   if (old_fun_type->AsFunctionType() == nullptr) { | 
|  1072     FAIL(fun_decl, "Identifier redefined as function."); |  1066     FAIL(fun_decl, "Identifier redefined as function."); | 
|  1073   } |  1067   } | 
|  1074  |  1068  | 
|  1075   if (!old_fun_type->missing_definition()) { |  1069   if (!old_fun_info->missing_definition()) { | 
|  1076     FAIL(fun_decl, "Identifier redefined (function name)."); |  1070     FAIL(fun_decl, "Identifier redefined (function name)."); | 
|  1077   } |  1071   } | 
|  1078  |  1072  | 
|  1079   if (old_fun_callable->ValidateCall(fun_type_as_function->ReturnType(), |  1073   if (!fun_type->IsA(old_fun_type)) { | 
|  1080                                      fun_type_as_function->Arguments()) == |  | 
|  1081       AsmType::None()) { |  | 
|  1082     FAIL(fun_decl, "Signature mismatch when defining function."); |  1074     FAIL(fun_decl, "Signature mismatch when defining function."); | 
|  1083   } |  1075   } | 
|  1084  |  1076  | 
|  1085   old_fun_type->MarkDefined(); |  1077   old_fun_info->MarkDefined(); | 
|  1086   SetTypeOf(fun, fun_type); |  1078   SetTypeOf(fun, fun_type); | 
|  1087  |  1079  | 
|  1088   return fun_type; |  1080   return fun_type; | 
|  1089 } |  1081 } | 
|  1090  |  1082  | 
|  1091 // 6.5 ValidateStatement |  1083 // 6.5 ValidateStatement | 
|  1092 AsmType* AsmTyper::ValidateStatement(Statement* statement) { |  1084 AsmType* AsmTyper::ValidateStatement(Statement* statement) { | 
|  1093   switch (statement->node_type()) { |  1085   switch (statement->node_type()) { | 
|  1094     default: |  1086     default: | 
|  1095       FAIL(statement, "Statement type invalid for asm.js."); |  1087       FAIL(statement, "Statement type invalid for asm.js."); | 
| (...skipping 1533 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  2629     return true; |  2621     return true; | 
|  2630   } |  2622   } | 
|  2631  |  2623  | 
|  2632   *error_message = typer.error_message(); |  2624   *error_message = typer.error_message(); | 
|  2633   return false; |  2625   return false; | 
|  2634 } |  2626 } | 
|  2635  |  2627  | 
|  2636 }  // namespace wasm |  2628 }  // namespace wasm | 
|  2637 }  // namespace internal |  2629 }  // namespace internal | 
|  2638 }  // namespace v8 |  2630 }  // namespace v8 | 
| OLD | NEW |