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" 37#include "src/parser.h" 38#include "src/snapshot.h" 39#include "src/unicode-inl.h" 40#include "src/utils.h" 41#include "test/cctest/cctest.h" 42 43using ::v8::Context; 44using ::v8::Extension; 45using ::v8::Function; 46using ::v8::FunctionTemplate; 47using ::v8::Handle; 48using ::v8::HandleScope; 49using ::v8::Local; 50using ::v8::Message; 51using ::v8::MessageCallback; 52using ::v8::Object; 53using ::v8::ObjectTemplate; 54using ::v8::Persistent; 55using ::v8::Script; 56using ::v8::StackTrace; 57using ::v8::String; 58using ::v8::TryCatch; 59using ::v8::Undefined; 60using ::v8::V8; 61using ::v8::Value; 62 63static void ExpectBoolean(bool expected, Local<Value> result) { 64 CHECK(result->IsBoolean()); 65 CHECK_EQ(expected, result->BooleanValue()); 66} 67 68 69static void ExpectInt32(int32_t expected, Local<Value> result) { 70 CHECK(result->IsInt32()); 71 CHECK_EQ(expected, result->Int32Value()); 72} 73 74 75static void ExpectNumber(double expected, Local<Value> result) { 76 CHECK(result->IsNumber()); 77 CHECK_EQ(expected, result->NumberValue()); 78} 79 80 81static void ExpectUndefined(Local<Value> result) { 82 CHECK(result->IsUndefined()); 83} 84 85 86// Tests are sorted by order of implementation. 87 88TEST(simple_value) { 89 LocalContext env; 90 v8::HandleScope scope(env->GetIsolate()); 91 Local<Value> result = CompileRun("0x271828;"); 92 ExpectInt32(0x271828, result); 93} 94 95 96TEST(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 104TEST(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 114TEST(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 127static 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 143static 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 160static 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 177TEST(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 192TEST(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 214TEST(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 231TEST(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 244TEST(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