Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 1 | // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 | // Redistribution and use in source and binary forms, with or without |
| 3 | // modification, are permitted provided that the following conditions are |
| 4 | // met: |
| 5 | // |
| 6 | // * Redistributions of source code must retain the above copyright |
| 7 | // notice, this list of conditions and the following disclaimer. |
| 8 | // * Redistributions in binary form must reproduce the above |
| 9 | // copyright notice, this list of conditions and the following |
| 10 | // disclaimer in the documentation and/or other materials provided |
| 11 | // with the distribution. |
| 12 | // * Neither the name of Google Inc. nor the names of its |
| 13 | // contributors may be used to endorse or promote products derived |
| 14 | // from this software without specific prior written permission. |
| 15 | // |
| 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 17 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 18 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 19 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 20 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 21 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 22 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 23 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 24 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 25 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 26 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | |
| 28 | #include <limits.h> |
| 29 | |
| 30 | #include "src/v8.h" |
| 31 | |
| 32 | #include "src/api.h" |
| 33 | #include "src/base/platform/platform.h" |
| 34 | #include "src/compilation-cache.h" |
| 35 | #include "src/execution.h" |
| 36 | #include "src/isolate.h" |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 37 | #include "src/parsing/parser.h" |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 38 | #include "src/unicode-inl.h" |
| 39 | #include "src/utils.h" |
| 40 | #include "test/cctest/cctest.h" |
| 41 | |
| 42 | using ::v8::Context; |
| 43 | using ::v8::Extension; |
| 44 | using ::v8::Function; |
| 45 | using ::v8::FunctionTemplate; |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 46 | using ::v8::HandleScope; |
| 47 | using ::v8::Local; |
| 48 | using ::v8::Message; |
| 49 | using ::v8::MessageCallback; |
| 50 | using ::v8::Object; |
| 51 | using ::v8::ObjectTemplate; |
| 52 | using ::v8::Persistent; |
| 53 | using ::v8::Script; |
| 54 | using ::v8::StackTrace; |
| 55 | using ::v8::String; |
| 56 | using ::v8::TryCatch; |
| 57 | using ::v8::Undefined; |
| 58 | using ::v8::V8; |
| 59 | using ::v8::Value; |
| 60 | |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 61 | static void ExpectBoolean(Local<Context> context, bool expected, |
| 62 | Local<Value> result) { |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 63 | CHECK(result->IsBoolean()); |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 64 | CHECK_EQ(expected, result->BooleanValue(context).FromJust()); |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 65 | } |
| 66 | |
| 67 | |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 68 | static void ExpectInt32(Local<Context> context, int32_t expected, |
| 69 | Local<Value> result) { |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 70 | CHECK(result->IsInt32()); |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 71 | CHECK_EQ(expected, result->Int32Value(context).FromJust()); |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 72 | } |
| 73 | |
| 74 | |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 75 | static void ExpectNumber(Local<Context> context, double expected, |
| 76 | Local<Value> result) { |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 77 | CHECK(result->IsNumber()); |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 78 | CHECK_EQ(expected, result->NumberValue(context).FromJust()); |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 79 | } |
| 80 | |
| 81 | |
| 82 | static void ExpectUndefined(Local<Value> result) { |
| 83 | CHECK(result->IsUndefined()); |
| 84 | } |
| 85 | |
| 86 | |
| 87 | // Tests are sorted by order of implementation. |
| 88 | |
| 89 | TEST(simple_value) { |
| 90 | LocalContext env; |
| 91 | v8::HandleScope scope(env->GetIsolate()); |
| 92 | Local<Value> result = CompileRun("0x271828;"); |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 93 | ExpectInt32(env.local(), 0x271828, result); |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 94 | } |
| 95 | |
| 96 | |
| 97 | TEST(global_variable) { |
| 98 | LocalContext env; |
| 99 | v8::HandleScope scope(env->GetIsolate()); |
| 100 | Local<Value> result = CompileRun("var my_global_var = 0x123; my_global_var;"); |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 101 | ExpectInt32(env.local(), 0x123, result); |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 102 | } |
| 103 | |
| 104 | |
| 105 | TEST(simple_function_call) { |
| 106 | LocalContext env; |
| 107 | v8::HandleScope scope(env->GetIsolate()); |
| 108 | Local<Value> result = CompileRun( |
| 109 | "function foo() { return 0x314; }" |
| 110 | "foo();"); |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 111 | ExpectInt32(env.local(), 0x314, result); |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 112 | } |
| 113 | |
| 114 | |
| 115 | TEST(binary_op) { |
| 116 | LocalContext env; |
| 117 | v8::HandleScope scope(env->GetIsolate()); |
| 118 | Local<Value> result = CompileRun( |
| 119 | "function foo() {" |
| 120 | " var a = 0x1200;" |
| 121 | " var b = 0x0035;" |
| 122 | " return 2 * (a + b - 1);" |
| 123 | "}" |
| 124 | "foo();"); |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 125 | ExpectInt32(env.local(), 0x2468, result); |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 126 | } |
| 127 | |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 128 | static void if_comparison_testcontext_helper(Local<Context> context, |
| 129 | char const* op, char const* lhs, |
| 130 | char const* rhs, int expect) { |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 131 | char buffer[256]; |
| 132 | snprintf(buffer, sizeof(buffer), |
| 133 | "var lhs = %s;" |
| 134 | "var rhs = %s;" |
| 135 | "if ( lhs %s rhs ) { 1; }" |
| 136 | "else { 0; }", |
| 137 | lhs, rhs, op); |
| 138 | Local<Value> result = CompileRun(buffer); |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 139 | ExpectInt32(context, expect, result); |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 140 | } |
| 141 | |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 142 | static void if_comparison_effectcontext_helper(Local<Context> context, |
| 143 | char const* op, char const* lhs, |
| 144 | char const* rhs, int expect) { |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 145 | char buffer[256]; |
| 146 | snprintf(buffer, sizeof(buffer), |
| 147 | "var lhs = %s;" |
| 148 | "var rhs = %s;" |
| 149 | "var test = lhs %s rhs;" |
| 150 | "if ( test ) { 1; }" |
| 151 | "else { 0; }", |
| 152 | lhs, rhs, op); |
| 153 | Local<Value> result = CompileRun(buffer); |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 154 | ExpectInt32(context, expect, result); |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 155 | } |
| 156 | |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 157 | static void if_comparison_helper(Local<Context> context, char const* op, |
| 158 | int expect_when_lt, int expect_when_eq, |
| 159 | int expect_when_gt) { |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 160 | // TODO(all): Non-SMI tests. |
| 161 | |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 162 | if_comparison_testcontext_helper(context, op, "1", "3", expect_when_lt); |
| 163 | if_comparison_testcontext_helper(context, op, "5", "5", expect_when_eq); |
| 164 | if_comparison_testcontext_helper(context, op, "9", "7", expect_when_gt); |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 165 | |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 166 | if_comparison_effectcontext_helper(context, op, "1", "3", expect_when_lt); |
| 167 | if_comparison_effectcontext_helper(context, op, "5", "5", expect_when_eq); |
| 168 | if_comparison_effectcontext_helper(context, op, "9", "7", expect_when_gt); |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 169 | } |
| 170 | |
| 171 | |
| 172 | TEST(if_comparison) { |
| 173 | LocalContext env; |
| 174 | v8::HandleScope scope(env->GetIsolate()); |
| 175 | |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 176 | if_comparison_helper(env.local(), "<", 1, 0, 0); |
| 177 | if_comparison_helper(env.local(), "<=", 1, 1, 0); |
| 178 | if_comparison_helper(env.local(), "==", 0, 1, 0); |
| 179 | if_comparison_helper(env.local(), "===", 0, 1, 0); |
| 180 | if_comparison_helper(env.local(), ">=", 0, 1, 1); |
| 181 | if_comparison_helper(env.local(), ">", 0, 0, 1); |
| 182 | if_comparison_helper(env.local(), "!=", 1, 0, 1); |
| 183 | if_comparison_helper(env.local(), "!==", 1, 0, 1); |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 184 | } |
| 185 | |
| 186 | |
| 187 | TEST(unary_plus) { |
| 188 | LocalContext env; |
| 189 | v8::HandleScope scope(env->GetIsolate()); |
| 190 | Local<Value> result; |
| 191 | // SMI |
| 192 | result = CompileRun("var a = 1234; +a"); |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 193 | ExpectInt32(env.local(), 1234, result); |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 194 | // Number |
| 195 | result = CompileRun("var a = 1234.5; +a"); |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 196 | ExpectNumber(env.local(), 1234.5, result); |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 197 | // String (SMI) |
| 198 | result = CompileRun("var a = '1234'; +a"); |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 199 | ExpectInt32(env.local(), 1234, result); |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 200 | // String (Number) |
| 201 | result = CompileRun("var a = '1234.5'; +a"); |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 202 | ExpectNumber(env.local(), 1234.5, result); |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 203 | // Check side effects. |
| 204 | result = CompileRun("var a = 1234; +(a = 4321); a"); |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 205 | ExpectInt32(env.local(), 4321, result); |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 206 | } |
| 207 | |
| 208 | |
| 209 | TEST(unary_minus) { |
| 210 | LocalContext env; |
| 211 | v8::HandleScope scope(env->GetIsolate()); |
| 212 | Local<Value> result; |
| 213 | result = CompileRun("var a = 1234; -a"); |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 214 | ExpectInt32(env.local(), -1234, result); |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 215 | result = CompileRun("var a = 1234.5; -a"); |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 216 | ExpectNumber(env.local(), -1234.5, result); |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 217 | result = CompileRun("var a = 1234; -(a = 4321); a"); |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 218 | ExpectInt32(env.local(), 4321, result); |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 219 | result = CompileRun("var a = '1234'; -a"); |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 220 | ExpectInt32(env.local(), -1234, result); |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 221 | result = CompileRun("var a = '1234.5'; -a"); |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 222 | ExpectNumber(env.local(), -1234.5, result); |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 223 | } |
| 224 | |
| 225 | |
| 226 | TEST(unary_void) { |
| 227 | LocalContext env; |
| 228 | v8::HandleScope scope(env->GetIsolate()); |
| 229 | Local<Value> result; |
| 230 | result = CompileRun("var a = 1234; void (a);"); |
| 231 | ExpectUndefined(result); |
| 232 | result = CompileRun("var a = 0; void (a = 42); a"); |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 233 | ExpectInt32(env.local(), 42, result); |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 234 | result = CompileRun("var a = 0; void (a = 42);"); |
| 235 | ExpectUndefined(result); |
| 236 | } |
| 237 | |
| 238 | |
| 239 | TEST(unary_not) { |
| 240 | LocalContext env; |
| 241 | v8::HandleScope scope(env->GetIsolate()); |
| 242 | Local<Value> result; |
| 243 | result = CompileRun("var a = 1234; !a"); |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 244 | ExpectBoolean(env.local(), false, result); |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 245 | result = CompileRun("var a = 0; !a"); |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 246 | ExpectBoolean(env.local(), true, result); |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 247 | result = CompileRun("var a = 0; !(a = 1234); a"); |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 248 | ExpectInt32(env.local(), 1234, result); |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 249 | result = CompileRun("var a = '1234'; !a"); |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 250 | ExpectBoolean(env.local(), false, result); |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 251 | result = CompileRun("var a = ''; !a"); |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 252 | ExpectBoolean(env.local(), true, result); |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 253 | result = CompileRun("var a = 1234; !!a"); |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 254 | ExpectBoolean(env.local(), true, result); |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 255 | result = CompileRun("var a = 0; !!a"); |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 256 | ExpectBoolean(env.local(), false, result); |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 257 | result = CompileRun("var a = 0; if ( !a ) { 1; } else { 0; }"); |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 258 | ExpectInt32(env.local(), 1, result); |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 259 | result = CompileRun("var a = 1; if ( !a ) { 1; } else { 0; }"); |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 260 | ExpectInt32(env.local(), 0, result); |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 261 | } |