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/parsing/parser.h" 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; 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 61 static void ExpectBoolean(Local<Context> context, bool expected, 62 Local<Value> result) { 63 CHECK(result->IsBoolean()); 64 CHECK_EQ(expected, result->BooleanValue(context).FromJust()); 65 } 66 67 68 static void ExpectInt32(Local<Context> context, int32_t expected, 69 Local<Value> result) { 70 CHECK(result->IsInt32()); 71 CHECK_EQ(expected, result->Int32Value(context).FromJust()); 72 } 73 74 75 static void ExpectNumber(Local<Context> context, double expected, 76 Local<Value> result) { 77 CHECK(result->IsNumber()); 78 CHECK_EQ(expected, result->NumberValue(context).FromJust()); 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;"); 93 ExpectInt32(env.local(), 0x271828, result); 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;"); 101 ExpectInt32(env.local(), 0x123, result); 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();"); 111 ExpectInt32(env.local(), 0x314, result); 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();"); 125 ExpectInt32(env.local(), 0x2468, result); 126 } 127 128 static void if_comparison_testcontext_helper(Local<Context> context, 129 char const* op, char const* lhs, 130 char const* rhs, int expect) { 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); 139 ExpectInt32(context, expect, result); 140 } 141 142 static void if_comparison_effectcontext_helper(Local<Context> context, 143 char const* op, char const* lhs, 144 char const* rhs, int expect) { 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); 154 ExpectInt32(context, expect, result); 155 } 156 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) { 160 // TODO(all): Non-SMI tests. 161 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); 165 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); 169 } 170 171 172 TEST(if_comparison) { 173 LocalContext env; 174 v8::HandleScope scope(env->GetIsolate()); 175 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); 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"); 193 ExpectInt32(env.local(), 1234, result); 194 // Number 195 result = CompileRun("var a = 1234.5; +a"); 196 ExpectNumber(env.local(), 1234.5, result); 197 // String (SMI) 198 result = CompileRun("var a = '1234'; +a"); 199 ExpectInt32(env.local(), 1234, result); 200 // String (Number) 201 result = CompileRun("var a = '1234.5'; +a"); 202 ExpectNumber(env.local(), 1234.5, result); 203 // Check side effects. 204 result = CompileRun("var a = 1234; +(a = 4321); a"); 205 ExpectInt32(env.local(), 4321, result); 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"); 214 ExpectInt32(env.local(), -1234, result); 215 result = CompileRun("var a = 1234.5; -a"); 216 ExpectNumber(env.local(), -1234.5, result); 217 result = CompileRun("var a = 1234; -(a = 4321); a"); 218 ExpectInt32(env.local(), 4321, result); 219 result = CompileRun("var a = '1234'; -a"); 220 ExpectInt32(env.local(), -1234, result); 221 result = CompileRun("var a = '1234.5'; -a"); 222 ExpectNumber(env.local(), -1234.5, result); 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"); 233 ExpectInt32(env.local(), 42, result); 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"); 244 ExpectBoolean(env.local(), false, result); 245 result = CompileRun("var a = 0; !a"); 246 ExpectBoolean(env.local(), true, result); 247 result = CompileRun("var a = 0; !(a = 1234); a"); 248 ExpectInt32(env.local(), 1234, result); 249 result = CompileRun("var a = '1234'; !a"); 250 ExpectBoolean(env.local(), false, result); 251 result = CompileRun("var a = ''; !a"); 252 ExpectBoolean(env.local(), true, result); 253 result = CompileRun("var a = 1234; !!a"); 254 ExpectBoolean(env.local(), true, result); 255 result = CompileRun("var a = 0; !!a"); 256 ExpectBoolean(env.local(), false, result); 257 result = CompileRun("var a = 0; if ( !a ) { 1; } else { 0; }"); 258 ExpectInt32(env.local(), 1, result); 259 result = CompileRun("var a = 1; if ( !a ) { 1; } else { 0; }"); 260 ExpectInt32(env.local(), 0, result); 261 } 262