| OLD | NEW |
| (Empty) |
| 1 // Copyright 2015 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 #include <stdlib.h> | |
| 6 | |
| 7 #include "src/v8.h" | |
| 8 | |
| 9 #include "src/ast/ast.h" | |
| 10 #include "src/ast/ast-expression-visitor.h" | |
| 11 #include "src/ast/scopes.h" | |
| 12 #include "src/parsing/parser.h" | |
| 13 #include "src/parsing/rewriter.h" | |
| 14 #include "src/typing-reset.h" | |
| 15 #include "test/cctest/cctest.h" | |
| 16 #include "test/cctest/compiler/function-tester.h" | |
| 17 #include "test/cctest/expression-type-collector.h" | |
| 18 #include "test/cctest/expression-type-collector-macros.h" | |
| 19 | |
| 20 #define INT32_TYPE Bounds(Type::Signed32(), Type::Signed32()) | |
| 21 | |
| 22 using namespace v8::internal; | |
| 23 | |
| 24 namespace { | |
| 25 | |
| 26 class TypeSetter : public AstExpressionVisitor { | |
| 27 public: | |
| 28 TypeSetter(Isolate* isolate, FunctionLiteral* root) | |
| 29 : AstExpressionVisitor(isolate, root) {} | |
| 30 | |
| 31 protected: | |
| 32 void VisitExpression(Expression* expression) { | |
| 33 expression->set_bounds(INT32_TYPE); | |
| 34 } | |
| 35 }; | |
| 36 | |
| 37 | |
| 38 void CheckAllSame(ZoneVector<ExpressionTypeEntry>& types, | |
| 39 Bounds expected_type) { | |
| 40 CHECK_TYPES_BEGIN { | |
| 41 // function logSum | |
| 42 CHECK_EXPR(FunctionLiteral, expected_type) { | |
| 43 CHECK_EXPR(FunctionLiteral, expected_type) { | |
| 44 CHECK_EXPR(Assignment, expected_type) { | |
| 45 CHECK_VAR(start, expected_type); | |
| 46 CHECK_EXPR(BinaryOperation, expected_type) { | |
| 47 CHECK_VAR(start, expected_type); | |
| 48 CHECK_EXPR(Literal, expected_type); | |
| 49 } | |
| 50 } | |
| 51 CHECK_EXPR(Assignment, expected_type) { | |
| 52 CHECK_VAR(end, expected_type); | |
| 53 CHECK_EXPR(BinaryOperation, expected_type) { | |
| 54 CHECK_VAR(end, expected_type); | |
| 55 CHECK_EXPR(Literal, expected_type); | |
| 56 } | |
| 57 } | |
| 58 CHECK_EXPR(Assignment, expected_type) { | |
| 59 CHECK_VAR(sum, expected_type); | |
| 60 CHECK_EXPR(Literal, expected_type); | |
| 61 } | |
| 62 CHECK_EXPR(Assignment, expected_type) { | |
| 63 CHECK_VAR(p, expected_type); | |
| 64 CHECK_EXPR(Literal, expected_type); | |
| 65 } | |
| 66 CHECK_EXPR(Assignment, expected_type) { | |
| 67 CHECK_VAR(q, expected_type); | |
| 68 CHECK_EXPR(Literal, expected_type); | |
| 69 } | |
| 70 // for (p = start << 3, q = end << 3; | |
| 71 CHECK_EXPR(BinaryOperation, expected_type) { | |
| 72 CHECK_EXPR(Assignment, expected_type) { | |
| 73 CHECK_VAR(p, expected_type); | |
| 74 CHECK_EXPR(BinaryOperation, expected_type) { | |
| 75 CHECK_VAR(start, expected_type); | |
| 76 CHECK_EXPR(Literal, expected_type); | |
| 77 } | |
| 78 } | |
| 79 CHECK_EXPR(Assignment, expected_type) { | |
| 80 CHECK_VAR(q, expected_type); | |
| 81 CHECK_EXPR(BinaryOperation, expected_type) { | |
| 82 CHECK_VAR(end, expected_type); | |
| 83 CHECK_EXPR(Literal, expected_type); | |
| 84 } | |
| 85 } | |
| 86 } | |
| 87 // (p|0) < (q|0); | |
| 88 CHECK_EXPR(CompareOperation, expected_type) { | |
| 89 CHECK_EXPR(BinaryOperation, expected_type) { | |
| 90 CHECK_VAR(p, expected_type); | |
| 91 CHECK_EXPR(Literal, expected_type); | |
| 92 } | |
| 93 CHECK_EXPR(BinaryOperation, expected_type) { | |
| 94 CHECK_VAR(q, expected_type); | |
| 95 CHECK_EXPR(Literal, expected_type); | |
| 96 } | |
| 97 } | |
| 98 // p = (p + 8)|0) {\n" | |
| 99 CHECK_EXPR(Assignment, expected_type) { | |
| 100 CHECK_VAR(p, expected_type); | |
| 101 CHECK_EXPR(BinaryOperation, expected_type) { | |
| 102 CHECK_EXPR(BinaryOperation, expected_type) { | |
| 103 CHECK_VAR(p, expected_type); | |
| 104 CHECK_EXPR(Literal, expected_type); | |
| 105 } | |
| 106 CHECK_EXPR(Literal, expected_type); | |
| 107 } | |
| 108 } | |
| 109 // sum = sum + +log(values[p>>3]); | |
| 110 CHECK_EXPR(Assignment, expected_type) { | |
| 111 CHECK_VAR(sum, expected_type); | |
| 112 CHECK_EXPR(BinaryOperation, expected_type) { | |
| 113 CHECK_VAR(sum, expected_type); | |
| 114 CHECK_EXPR(BinaryOperation, expected_type) { | |
| 115 CHECK_EXPR(Call, expected_type) { | |
| 116 CHECK_VAR(log, expected_type); | |
| 117 CHECK_EXPR(Property, expected_type) { | |
| 118 CHECK_VAR(values, expected_type); | |
| 119 CHECK_EXPR(BinaryOperation, expected_type) { | |
| 120 CHECK_VAR(p, expected_type); | |
| 121 CHECK_EXPR(Literal, expected_type); | |
| 122 } | |
| 123 } | |
| 124 } | |
| 125 CHECK_EXPR(Literal, expected_type); | |
| 126 } | |
| 127 } | |
| 128 } | |
| 129 // return +sum; | |
| 130 CHECK_EXPR(BinaryOperation, expected_type) { | |
| 131 CHECK_VAR(sum, expected_type); | |
| 132 CHECK_EXPR(Literal, expected_type); | |
| 133 } | |
| 134 } | |
| 135 // function geometricMean | |
| 136 CHECK_EXPR(FunctionLiteral, expected_type) { | |
| 137 CHECK_EXPR(Assignment, expected_type) { | |
| 138 CHECK_VAR(start, expected_type); | |
| 139 CHECK_EXPR(BinaryOperation, expected_type) { | |
| 140 CHECK_VAR(start, expected_type); | |
| 141 CHECK_EXPR(Literal, expected_type); | |
| 142 } | |
| 143 } | |
| 144 CHECK_EXPR(Assignment, expected_type) { | |
| 145 CHECK_VAR(end, expected_type); | |
| 146 CHECK_EXPR(BinaryOperation, expected_type) { | |
| 147 CHECK_VAR(end, expected_type); | |
| 148 CHECK_EXPR(Literal, expected_type); | |
| 149 } | |
| 150 } | |
| 151 // return +exp(+logSum(start, end) / +((end - start)|0)); | |
| 152 CHECK_EXPR(BinaryOperation, expected_type) { | |
| 153 CHECK_EXPR(Call, expected_type) { | |
| 154 CHECK_VAR(exp, expected_type); | |
| 155 CHECK_EXPR(BinaryOperation, expected_type) { | |
| 156 CHECK_EXPR(BinaryOperation, expected_type) { | |
| 157 CHECK_EXPR(Call, expected_type) { | |
| 158 CHECK_VAR(logSum, expected_type); | |
| 159 CHECK_VAR(start, expected_type); | |
| 160 CHECK_VAR(end, expected_type); | |
| 161 } | |
| 162 CHECK_EXPR(Literal, expected_type); | |
| 163 } | |
| 164 CHECK_EXPR(BinaryOperation, expected_type) { | |
| 165 CHECK_EXPR(BinaryOperation, expected_type) { | |
| 166 CHECK_EXPR(BinaryOperation, expected_type) { | |
| 167 CHECK_VAR(end, expected_type); | |
| 168 CHECK_VAR(start, expected_type); | |
| 169 } | |
| 170 CHECK_EXPR(Literal, expected_type); | |
| 171 } | |
| 172 CHECK_EXPR(Literal, expected_type); | |
| 173 } | |
| 174 } | |
| 175 } | |
| 176 CHECK_EXPR(Literal, expected_type); | |
| 177 } | |
| 178 } | |
| 179 // "use asm"; | |
| 180 CHECK_EXPR(Literal, expected_type); | |
| 181 // var exp = stdlib.Math.exp; | |
| 182 CHECK_EXPR(Assignment, expected_type) { | |
| 183 CHECK_VAR(exp, expected_type); | |
| 184 CHECK_EXPR(Property, expected_type) { | |
| 185 CHECK_EXPR(Property, expected_type) { | |
| 186 CHECK_VAR(stdlib, expected_type); | |
| 187 CHECK_EXPR(Literal, expected_type); | |
| 188 } | |
| 189 CHECK_EXPR(Literal, expected_type); | |
| 190 } | |
| 191 } | |
| 192 // var log = stdlib.Math.log; | |
| 193 CHECK_EXPR(Assignment, expected_type) { | |
| 194 CHECK_VAR(log, expected_type); | |
| 195 CHECK_EXPR(Property, expected_type) { | |
| 196 CHECK_EXPR(Property, expected_type) { | |
| 197 CHECK_VAR(stdlib, expected_type); | |
| 198 CHECK_EXPR(Literal, expected_type); | |
| 199 } | |
| 200 CHECK_EXPR(Literal, expected_type); | |
| 201 } | |
| 202 } | |
| 203 // var values = new stdlib.Float64Array(buffer); | |
| 204 CHECK_EXPR(Assignment, expected_type) { | |
| 205 CHECK_VAR(values, expected_type); | |
| 206 CHECK_EXPR(CallNew, expected_type) { | |
| 207 CHECK_EXPR(Property, expected_type) { | |
| 208 CHECK_VAR(stdlib, expected_type); | |
| 209 CHECK_EXPR(Literal, expected_type); | |
| 210 } | |
| 211 CHECK_VAR(buffer, expected_type); | |
| 212 } | |
| 213 } | |
| 214 // return { geometricMean: geometricMean }; | |
| 215 CHECK_EXPR(ObjectLiteral, expected_type) { | |
| 216 CHECK_VAR(geometricMean, expected_type); | |
| 217 } | |
| 218 } | |
| 219 } | |
| 220 CHECK_TYPES_END | |
| 221 } | |
| 222 | |
| 223 } // namespace | |
| 224 | |
| 225 | |
| 226 TEST(ResetTypingInfo) { | |
| 227 const char test_function[] = | |
| 228 "function GeometricMean(stdlib, foreign, buffer) {\n" | |
| 229 " \"use asm\";\n" | |
| 230 "\n" | |
| 231 " var exp = stdlib.Math.exp;\n" | |
| 232 " var log = stdlib.Math.log;\n" | |
| 233 " var values = new stdlib.Float64Array(buffer);\n" | |
| 234 "\n" | |
| 235 " function logSum(start, end) {\n" | |
| 236 " start = start|0;\n" | |
| 237 " end = end|0;\n" | |
| 238 "\n" | |
| 239 " var sum = 0.0, p = 0, q = 0;\n" | |
| 240 "\n" | |
| 241 " // asm.js forces byte addressing of the heap by requiring shifting " | |
| 242 "by 3\n" | |
| 243 " for (p = start << 3, q = end << 3; (p|0) < (q|0); p = (p + 8)|0) {\n" | |
| 244 " sum = sum + +log(values[p>>3]);\n" | |
| 245 " }\n" | |
| 246 "\n" | |
| 247 " return +sum;\n" | |
| 248 " }\n" | |
| 249 "\n" | |
| 250 " function geometricMean(start, end) {\n" | |
| 251 " start = start|0;\n" | |
| 252 " end = end|0;\n" | |
| 253 "\n" | |
| 254 " return +exp(+logSum(start, end) / +((end - start)|0));\n" | |
| 255 " }\n" | |
| 256 "\n" | |
| 257 " return { geometricMean: geometricMean };\n" | |
| 258 "}\n"; | |
| 259 | |
| 260 v8::V8::Initialize(); | |
| 261 HandleAndZoneScope handles; | |
| 262 | |
| 263 i::Isolate* isolate = CcTest::i_isolate(); | |
| 264 i::Factory* factory = isolate->factory(); | |
| 265 | |
| 266 i::Handle<i::String> source_code = | |
| 267 factory->NewStringFromUtf8(i::CStrVector(test_function)) | |
| 268 .ToHandleChecked(); | |
| 269 | |
| 270 i::Handle<i::Script> script = factory->NewScript(source_code); | |
| 271 | |
| 272 i::ParseInfo info(handles.main_zone(), script); | |
| 273 i::Parser parser(&info); | |
| 274 info.set_global(); | |
| 275 info.set_lazy(false); | |
| 276 info.set_allow_lazy_parsing(false); | |
| 277 info.set_toplevel(true); | |
| 278 | |
| 279 CHECK(i::Compiler::ParseAndAnalyze(&info)); | |
| 280 FunctionLiteral* root = | |
| 281 info.scope()->declarations()->at(0)->AsFunctionDeclaration()->fun(); | |
| 282 | |
| 283 // Core of the test. | |
| 284 ZoneVector<ExpressionTypeEntry> types(handles.main_zone()); | |
| 285 ExpressionTypeCollector(isolate, root, &types).Run(); | |
| 286 CheckAllSame(types, Bounds::Unbounded()); | |
| 287 | |
| 288 TypeSetter(isolate, root).Run(); | |
| 289 | |
| 290 ExpressionTypeCollector(isolate, root, &types).Run(); | |
| 291 CheckAllSame(types, INT32_TYPE); | |
| 292 | |
| 293 TypingReseter(isolate, root).Run(); | |
| 294 | |
| 295 ExpressionTypeCollector(isolate, root, &types).Run(); | |
| 296 CheckAllSame(types, Bounds::Unbounded()); | |
| 297 } | |
| OLD | NEW |