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/compilation-cache.h" 34 #include "src/execution.h" 35 #include "src/isolate.h" 36 #include "src/parser.h" 37 #include "src/platform.h" 38 #include "src/snapshot.h" 39 #include "src/unicode-inl.h" 40 #include "src/utils.h" 41 #include "test/cctest/cctest.h" 42 43 using ::v8::Context; 44 using ::v8::Extension; 45 using ::v8::Function; 46 using ::v8::FunctionTemplate; 47 using ::v8::Handle; 48 using ::v8::HandleScope; 49 using ::v8::Local; 50 using ::v8::Message; 51 using ::v8::MessageCallback; 52 using ::v8::Object; 53 using ::v8::ObjectTemplate; 54 using ::v8::Persistent; 55 using ::v8::Script; 56 using ::v8::StackTrace; 57 using ::v8::String; 58 using ::v8::TryCatch; 59 using ::v8::Undefined; 60 using ::v8::V8; 61 using ::v8::Value; 62 63 static void ExpectBoolean(bool expected, Local<Value> result) { 64 CHECK(result->IsBoolean()); 65 CHECK_EQ(expected, result->BooleanValue()); 66 } 67 68 69 static void ExpectInt32(int32_t expected, Local<Value> result) { 70 CHECK(result->IsInt32()); 71 CHECK_EQ(expected, result->Int32Value()); 72 } 73 74 75 static void ExpectNumber(double expected, Local<Value> result) { 76 CHECK(result->IsNumber()); 77 CHECK_EQ(expected, result->NumberValue()); 78 } 79 80 81 static void ExpectUndefined(Local<Value> result) { 82 CHECK(result->IsUndefined()); 83 } 84 85 86 // Tests are sorted by order of implementation. 87 88 TEST(simple_value) { 89 LocalContext env; 90 v8::HandleScope scope(env->GetIsolate()); 91 Local<Value> result = CompileRun("0x271828;"); 92 ExpectInt32(0x271828, result); 93 } 94 95 96 TEST(global_variable) { 97 LocalContext env; 98 v8::HandleScope scope(env->GetIsolate()); 99 Local<Value> result = CompileRun("var my_global_var = 0x123; my_global_var;"); 100 ExpectInt32(0x123, result); 101 } 102 103 104 TEST(simple_function_call) { 105 LocalContext env; 106 v8::HandleScope scope(env->GetIsolate()); 107 Local<Value> result = CompileRun( 108 "function foo() { return 0x314; }" 109 "foo();"); 110 ExpectInt32(0x314, result); 111 } 112 113 114 TEST(binary_op) { 115 LocalContext env; 116 v8::HandleScope scope(env->GetIsolate()); 117 Local<Value> result = CompileRun( 118 "function foo() {" 119 " var a = 0x1200;" 120 " var b = 0x0035;" 121 " return 2 * (a + b - 1);" 122 "}" 123 "foo();"); 124 ExpectInt32(0x2468, result); 125 } 126 127 static void if_comparison_testcontext_helper( 128 char const * op, 129 char const * lhs, 130 char const * rhs, 131 int expect) { 132 char buffer[256]; 133 snprintf(buffer, sizeof(buffer), 134 "var lhs = %s;" 135 "var rhs = %s;" 136 "if ( lhs %s rhs ) { 1; }" 137 "else { 0; }", 138 lhs, rhs, op); 139 Local<Value> result = CompileRun(buffer); 140 ExpectInt32(expect, result); 141 } 142 143 static void if_comparison_effectcontext_helper( 144 char const * op, 145 char const * lhs, 146 char const * rhs, 147 int expect) { 148 char buffer[256]; 149 snprintf(buffer, sizeof(buffer), 150 "var lhs = %s;" 151 "var rhs = %s;" 152 "var test = lhs %s rhs;" 153 "if ( test ) { 1; }" 154 "else { 0; }", 155 lhs, rhs, op); 156 Local<Value> result = CompileRun(buffer); 157 ExpectInt32(expect, result); 158 } 159 160 static void if_comparison_helper( 161 char const * op, 162 int expect_when_lt, 163 int expect_when_eq, 164 int expect_when_gt) { 165 // TODO(all): Non-SMI tests. 166 167 if_comparison_testcontext_helper(op, "1", "3", expect_when_lt); 168 if_comparison_testcontext_helper(op, "5", "5", expect_when_eq); 169 if_comparison_testcontext_helper(op, "9", "7", expect_when_gt); 170 171 if_comparison_effectcontext_helper(op, "1", "3", expect_when_lt); 172 if_comparison_effectcontext_helper(op, "5", "5", expect_when_eq); 173 if_comparison_effectcontext_helper(op, "9", "7", expect_when_gt); 174 } 175 176 177 TEST(if_comparison) { 178 LocalContext env; 179 v8::HandleScope scope(env->GetIsolate()); 180 181 if_comparison_helper("<", 1, 0, 0); 182 if_comparison_helper("<=", 1, 1, 0); 183 if_comparison_helper("==", 0, 1, 0); 184 if_comparison_helper("===", 0, 1, 0); 185 if_comparison_helper(">=", 0, 1, 1); 186 if_comparison_helper(">", 0, 0, 1); 187 if_comparison_helper("!=", 1, 0, 1); 188 if_comparison_helper("!==", 1, 0, 1); 189 } 190 191 192 TEST(unary_plus) { 193 LocalContext env; 194 v8::HandleScope scope(env->GetIsolate()); 195 Local<Value> result; 196 // SMI 197 result = CompileRun("var a = 1234; +a"); 198 ExpectInt32(1234, result); 199 // Number 200 result = CompileRun("var a = 1234.5; +a"); 201 ExpectNumber(1234.5, result); 202 // String (SMI) 203 result = CompileRun("var a = '1234'; +a"); 204 ExpectInt32(1234, result); 205 // String (Number) 206 result = CompileRun("var a = '1234.5'; +a"); 207 ExpectNumber(1234.5, result); 208 // Check side effects. 209 result = CompileRun("var a = 1234; +(a = 4321); a"); 210 ExpectInt32(4321, result); 211 } 212 213 214 TEST(unary_minus) { 215 LocalContext env; 216 v8::HandleScope scope(env->GetIsolate()); 217 Local<Value> result; 218 result = CompileRun("var a = 1234; -a"); 219 ExpectInt32(-1234, result); 220 result = CompileRun("var a = 1234.5; -a"); 221 ExpectNumber(-1234.5, result); 222 result = CompileRun("var a = 1234; -(a = 4321); a"); 223 ExpectInt32(4321, result); 224 result = CompileRun("var a = '1234'; -a"); 225 ExpectInt32(-1234, result); 226 result = CompileRun("var a = '1234.5'; -a"); 227 ExpectNumber(-1234.5, result); 228 } 229 230 231 TEST(unary_void) { 232 LocalContext env; 233 v8::HandleScope scope(env->GetIsolate()); 234 Local<Value> result; 235 result = CompileRun("var a = 1234; void (a);"); 236 ExpectUndefined(result); 237 result = CompileRun("var a = 0; void (a = 42); a"); 238 ExpectInt32(42, result); 239 result = CompileRun("var a = 0; void (a = 42);"); 240 ExpectUndefined(result); 241 } 242 243 244 TEST(unary_not) { 245 LocalContext env; 246 v8::HandleScope scope(env->GetIsolate()); 247 Local<Value> result; 248 result = CompileRun("var a = 1234; !a"); 249 ExpectBoolean(false, result); 250 result = CompileRun("var a = 0; !a"); 251 ExpectBoolean(true, result); 252 result = CompileRun("var a = 0; !(a = 1234); a"); 253 ExpectInt32(1234, result); 254 result = CompileRun("var a = '1234'; !a"); 255 ExpectBoolean(false, result); 256 result = CompileRun("var a = ''; !a"); 257 ExpectBoolean(true, result); 258 result = CompileRun("var a = 1234; !!a"); 259 ExpectBoolean(true, result); 260 result = CompileRun("var a = 0; !!a"); 261 ExpectBoolean(false, result); 262 result = CompileRun("var a = 0; if ( !a ) { 1; } else { 0; }"); 263 ExpectInt32(1, result); 264 result = CompileRun("var a = 1; if ( !a ) { 1; } else { 0; }"); 265 ExpectInt32(0, result); 266 } 267