OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 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 | 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/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/ast/ast.h" | 7 #include "src/ast/ast.h" |
8 #include "src/ast/ast-expression-visitor.h" | 8 #include "src/ast/ast-expression-visitor.h" |
9 #include "src/ast/scopes.h" | 9 #include "src/ast/scopes.h" |
10 #include "src/parsing/parser.h" | 10 #include "src/parsing/parser.h" |
(...skipping 1708 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1719 } | 1719 } |
1720 | 1720 |
1721 | 1721 |
1722 TEST(ForeignFunction) { | 1722 TEST(ForeignFunction) { |
1723 CHECK_FUNC_TYPES_BEGIN( | 1723 CHECK_FUNC_TYPES_BEGIN( |
1724 "var baz = foreign.baz;\n" | 1724 "var baz = foreign.baz;\n" |
1725 "function bar() { return baz(1, 2)|0; }\n" | 1725 "function bar() { return baz(1, 2)|0; }\n" |
1726 "function foo() { bar(); }") { | 1726 "function foo() { bar(); }") { |
1727 CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) { | 1727 CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) { |
1728 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { | 1728 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { |
1729 CHECK_EXPR(Call, Bounds(Type::Number(zone))) { | 1729 CHECK_EXPR(Call, Bounds(cache.kAsmSigned)) { |
1730 CHECK_VAR(baz, Bounds(Type::Any(zone))); | 1730 CHECK_VAR(baz, Bounds(Type::Any(zone))); |
1731 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); | 1731 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); |
1732 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); | 1732 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); |
1733 } | 1733 } |
1734 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); | 1734 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); |
1735 } | 1735 } |
1736 } | 1736 } |
1737 CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) { | 1737 CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) { |
1738 CHECK_EXPR(Call, Bounds(cache.kAsmSigned)) { | 1738 CHECK_EXPR(Call, Bounds(cache.kAsmSigned)) { |
1739 CHECK_VAR(bar, FUNC_I_TYPE); | 1739 CHECK_VAR(bar, FUNC_I_TYPE); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1781 "function foo() { bar(); }", | 1781 "function foo() { bar(); }", |
1782 "asm: line 39: illegal type in assignment\n"); | 1782 "asm: line 39: illegal type in assignment\n"); |
1783 } | 1783 } |
1784 | 1784 |
1785 | 1785 |
1786 TEST(BadStandardFunctionCallOutside) { | 1786 TEST(BadStandardFunctionCallOutside) { |
1787 CHECK_FUNC_ERROR( | 1787 CHECK_FUNC_ERROR( |
1788 "var s0 = sin(0);\n" | 1788 "var s0 = sin(0);\n" |
1789 "function bar() { }\n" | 1789 "function bar() { }\n" |
1790 "function foo() { bar(); }", | 1790 "function foo() { bar(); }", |
1791 "asm: line 39: calls forbidden outside function bodies\n"); | 1791 "asm: line 39: illegal variable reference in module body\n"); |
1792 } | 1792 } |
1793 | 1793 |
1794 | 1794 |
1795 TEST(BadFunctionCallOutside) { | 1795 TEST(BadFunctionCallOutside) { |
1796 CHECK_FUNC_ERROR( | 1796 CHECK_FUNC_ERROR( |
1797 "function bar() { return 0.0; }\n" | 1797 "function bar() { return 0.0; }\n" |
1798 "var s0 = bar(0);\n" | 1798 "var s0 = bar(0);\n" |
1799 "function foo() { bar(); }", | 1799 "function foo() { bar(); }", |
1800 "asm: line 40: calls forbidden outside function bodies\n"); | 1800 "asm: line 40: illegal variable reference in module body\n"); |
1801 } | 1801 } |
1802 | 1802 |
1803 | 1803 |
1804 TEST(NestedVariableAssignment) { | 1804 TEST(NestedVariableAssignment) { |
1805 CHECK_FUNC_TYPES_BEGIN( | 1805 CHECK_FUNC_TYPES_BEGIN( |
1806 "function bar() { var x = 0; x = x = 4; }\n" | 1806 "function bar() { var x = 0; x = x = 4; }\n" |
1807 "function foo() { bar(); }") { | 1807 "function foo() { bar(); }") { |
1808 CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) { | 1808 CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) { |
1809 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { | 1809 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { |
1810 CHECK_VAR(x, Bounds(cache.kAsmInt)); | 1810 CHECK_VAR(x, Bounds(cache.kAsmInt)); |
(...skipping 19 matching lines...) Expand all Loading... |
1830 "function foo() { bar(); }") { | 1830 "function foo() { bar(); }") { |
1831 CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) { | 1831 CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) { |
1832 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { | 1832 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { |
1833 CHECK_VAR(x, Bounds(cache.kAsmInt)); | 1833 CHECK_VAR(x, Bounds(cache.kAsmInt)); |
1834 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); | 1834 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); |
1835 } | 1835 } |
1836 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { | 1836 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { |
1837 CHECK_EXPR(Property, Bounds::Unbounded()) { | 1837 CHECK_EXPR(Property, Bounds::Unbounded()) { |
1838 CHECK_VAR(i8, Bounds(cache.kInt8Array)); | 1838 CHECK_VAR(i8, Bounds(cache.kInt8Array)); |
1839 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { | 1839 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { |
1840 CHECK_EXPR(Assignment, Bounds(cache.kAsmSigned)) { | 1840 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { |
1841 CHECK_VAR(x, Bounds(cache.kAsmInt)); | 1841 CHECK_VAR(x, Bounds(cache.kAsmInt)); |
1842 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); | 1842 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); |
1843 } | 1843 } |
1844 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); | 1844 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); |
1845 } | 1845 } |
1846 } | 1846 } |
1847 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); | 1847 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); |
1848 } | 1848 } |
1849 } | 1849 } |
1850 CHECK_SKIP(); | 1850 CHECK_SKIP(); |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2043 "asm: line 39: duplicate case value\n"); | 2043 "asm: line 39: duplicate case value\n"); |
2044 } | 2044 } |
2045 | 2045 |
2046 | 2046 |
2047 TEST(BadSwitchOrder) { | 2047 TEST(BadSwitchOrder) { |
2048 CHECK_FUNC_ERROR( | 2048 CHECK_FUNC_ERROR( |
2049 "function bar() { switch (1) { default: case 0: } }\n" | 2049 "function bar() { switch (1) { default: case 0: } }\n" |
2050 "function foo() { bar(); }", | 2050 "function foo() { bar(); }", |
2051 "asm: line 39: default case out of order\n"); | 2051 "asm: line 39: default case out of order\n"); |
2052 } | 2052 } |
| 2053 |
| 2054 TEST(BadForeignCall) { |
| 2055 const char test_function[] = |
| 2056 "function TestModule(stdlib, foreign, buffer) {\n" |
| 2057 " \"use asm\";\n" |
| 2058 " var ffunc = foreign.foo;\n" |
| 2059 " function test1() { var x = 0; ffunc(x); }\n" |
| 2060 " return { testFunc1: test1 };\n" |
| 2061 "}\n"; |
| 2062 v8::V8::Initialize(); |
| 2063 HandleAndZoneScope handles; |
| 2064 Zone* zone = handles.main_zone(); |
| 2065 ZoneVector<ExpressionTypeEntry> types(zone); |
| 2066 CHECK_EQ( |
| 2067 "asm: line 4: foreign call argument expected to be int, double, or " |
| 2068 "fixnum\n", |
| 2069 Validate(zone, test_function, &types)); |
| 2070 } |
| 2071 |
| 2072 TEST(BadImports) { |
| 2073 const char test_function[] = |
| 2074 "function TestModule(stdlib, foreign, buffer) {\n" |
| 2075 " \"use asm\";\n" |
| 2076 " var fint = (foreign.bar | 0) | 0;\n" |
| 2077 " function test1() {}\n" |
| 2078 " return { testFunc1: test1 };\n" |
| 2079 "}\n"; |
| 2080 v8::V8::Initialize(); |
| 2081 HandleAndZoneScope handles; |
| 2082 Zone* zone = handles.main_zone(); |
| 2083 ZoneVector<ExpressionTypeEntry> types(zone); |
| 2084 CHECK_EQ("asm: line 3: illegal computation inside module body\n", |
| 2085 Validate(zone, test_function, &types)); |
| 2086 } |
| 2087 |
| 2088 TEST(BadVariableReference) { |
| 2089 const char test_function[] = |
| 2090 "function TestModule(stdlib, foreign, buffer) {\n" |
| 2091 " \"use asm\";\n" |
| 2092 " var x = 0;\n" |
| 2093 " var y = x;\n" |
| 2094 " function test1() {}\n" |
| 2095 " return { testFunc1: test1 };\n" |
| 2096 "}\n"; |
| 2097 v8::V8::Initialize(); |
| 2098 HandleAndZoneScope handles; |
| 2099 Zone* zone = handles.main_zone(); |
| 2100 ZoneVector<ExpressionTypeEntry> types(zone); |
| 2101 CHECK_EQ("asm: line 4: illegal variable reference in module body\n", |
| 2102 Validate(zone, test_function, &types)); |
| 2103 } |
| 2104 |
| 2105 TEST(Imports) { |
| 2106 const char test_function[] = |
| 2107 "function TestModule(stdlib, foreign, buffer) {\n" |
| 2108 " \"use asm\";\n" |
| 2109 " var ffunc = foreign.foo;\n" |
| 2110 " var fint = foreign.bar | 0;\n" |
| 2111 " var fdouble = +foreign.baz;\n" |
| 2112 " function test1() { return ffunc(fint|0, fdouble) | 0; }\n" |
| 2113 " function test2() { return +ffunc(fdouble, fint|0); }\n" |
| 2114 " return { testFunc1: test1, testFunc2: test2 };\n" |
| 2115 "}\n"; |
| 2116 |
| 2117 v8::V8::Initialize(); |
| 2118 HandleAndZoneScope handles; |
| 2119 Zone* zone = handles.main_zone(); |
| 2120 ZoneVector<ExpressionTypeEntry> types(zone); |
| 2121 CHECK_EQ("", Validate(zone, test_function, &types)); |
| 2122 TypeCache cache; |
| 2123 |
| 2124 CHECK_TYPES_BEGIN { |
| 2125 // Module. |
| 2126 CHECK_EXPR(FunctionLiteral, Bounds::Unbounded()) { |
| 2127 // function test1 |
| 2128 CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) { |
| 2129 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { |
| 2130 CHECK_EXPR(Call, Bounds(cache.kAsmSigned)) { |
| 2131 CHECK_VAR(ffunc, Bounds(Type::Any(zone))); |
| 2132 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { |
| 2133 CHECK_VAR(fint, Bounds(cache.kAsmInt)); |
| 2134 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); |
| 2135 } |
| 2136 CHECK_VAR(fdouble, Bounds(cache.kAsmDouble)); |
| 2137 } |
| 2138 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); |
| 2139 } |
| 2140 } |
| 2141 // function test2 |
| 2142 CHECK_EXPR(FunctionLiteral, FUNC_D_TYPE) { |
| 2143 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmDouble)) { |
| 2144 CHECK_EXPR(Call, Bounds(cache.kAsmDouble)) { |
| 2145 CHECK_VAR(ffunc, Bounds(Type::Any(zone))); |
| 2146 CHECK_VAR(fdouble, Bounds(cache.kAsmDouble)); |
| 2147 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { |
| 2148 CHECK_VAR(fint, Bounds(cache.kAsmInt)); |
| 2149 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); |
| 2150 } |
| 2151 } |
| 2152 CHECK_EXPR(Literal, Bounds(cache.kAsmDouble)); |
| 2153 } |
| 2154 } |
| 2155 // "use asm"; |
| 2156 CHECK_EXPR(Literal, Bounds(Type::String(zone))); |
| 2157 // var func = foreign.foo; |
| 2158 CHECK_EXPR(Assignment, Bounds(Type::Any(zone))) { |
| 2159 CHECK_VAR(ffunc, Bounds(Type::Any(zone))); |
| 2160 CHECK_EXPR(Property, Bounds(Type::Any(zone))) { |
| 2161 CHECK_VAR(foreign, Bounds::Unbounded()); |
| 2162 CHECK_EXPR(Literal, Bounds::Unbounded()); |
| 2163 } |
| 2164 } |
| 2165 // var fint = foreign.bar | 0; |
| 2166 CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { |
| 2167 CHECK_VAR(fint, Bounds(cache.kAsmInt)); |
| 2168 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { |
| 2169 CHECK_EXPR(Property, Bounds(Type::Number())) { |
| 2170 CHECK_VAR(foreign, Bounds::Unbounded()); |
| 2171 CHECK_EXPR(Literal, Bounds::Unbounded()); |
| 2172 } |
| 2173 CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); |
| 2174 } |
| 2175 } |
| 2176 // var fdouble = +foreign.baz; |
| 2177 CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) { |
| 2178 CHECK_VAR(fdouble, Bounds(cache.kAsmDouble)); |
| 2179 CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmDouble)) { |
| 2180 CHECK_EXPR(Property, Bounds(Type::Number())) { |
| 2181 CHECK_VAR(foreign, Bounds::Unbounded()); |
| 2182 CHECK_EXPR(Literal, Bounds::Unbounded()); |
| 2183 } |
| 2184 CHECK_EXPR(Literal, Bounds(cache.kAsmDouble)); |
| 2185 } |
| 2186 } |
| 2187 // return { testFunc1: test1, testFunc2: test2 }; |
| 2188 CHECK_EXPR(ObjectLiteral, Bounds::Unbounded()) { |
| 2189 CHECK_VAR(test1, FUNC_I_TYPE); |
| 2190 CHECK_VAR(test2, FUNC_D_TYPE); |
| 2191 } |
| 2192 } |
| 2193 } |
| 2194 CHECK_TYPES_END |
| 2195 } |
OLD | NEW |