OLD | NEW |
1 // Copyright 2007-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2007-2008 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 2145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2156 v8::Handle<v8::Value> argv_bar_3[2] = { | 2156 v8::Handle<v8::Value> argv_bar_3[2] = { |
2157 v8::String::New("Hello, world!"), | 2157 v8::String::New("Hello, world!"), |
2158 v8::Number::New(barbar_break_position + 1) | 2158 v8::Number::New(barbar_break_position + 1) |
2159 }; | 2159 }; |
2160 bar->Call(env->Global(), 2, argv_bar_3); | 2160 bar->Call(env->Global(), 2, argv_bar_3); |
2161 | 2161 |
2162 v8::Debug::SetDebugEventListener(NULL); | 2162 v8::Debug::SetDebugEventListener(NULL); |
2163 CheckDebuggerUnloaded(); | 2163 CheckDebuggerUnloaded(); |
2164 } | 2164 } |
2165 | 2165 |
| 2166 // Copies a C string to a 16-bit string. Does not check for buffer overflow. |
| 2167 // Does not use the V8 engine to convert strings, so it can be used |
| 2168 // in any thread. Returns the length of the string. |
| 2169 int AsciiToUtf16(const char* input_buffer, uint16_t* output_buffer) { |
| 2170 int i; |
| 2171 for (i = 0; input_buffer[i] != '\0'; ++i) { |
| 2172 // ASCII does not use chars > 127, but be careful anyway. |
| 2173 output_buffer[i] = static_cast<unsigned char>(input_buffer[i]); |
| 2174 } |
| 2175 output_buffer[i] = 0; |
| 2176 return i; |
| 2177 } |
| 2178 |
| 2179 // Copies a 16-bit string to a C string by dropping the high byte of |
| 2180 // each character. Does not check for buffer overflow. |
| 2181 // Can be used in any thread. Requires string length as an input. |
| 2182 int Utf16ToAscii(const uint16_t* input_buffer, int length, |
| 2183 char* output_buffer, int output_len = -1) { |
| 2184 if (output_len >= 0) { |
| 2185 if (length > output_len - 1) { |
| 2186 length = output_len - 1; |
| 2187 } |
| 2188 } |
| 2189 |
| 2190 for (int i = 0; i < length; ++i) { |
| 2191 output_buffer[i] = static_cast<char>(input_buffer[i]); |
| 2192 } |
| 2193 output_buffer[length] = '\0'; |
| 2194 return length; |
| 2195 } |
| 2196 |
| 2197 |
| 2198 // We match parts of the message to get evaluate result int value. |
| 2199 bool GetEvaluateStringResult(char *message, char* buffer, int buffer_size) { |
| 2200 const char* value = "\"value\":"; |
| 2201 char* pos = strstr(message, value); |
| 2202 if (pos == NULL) { |
| 2203 return false; |
| 2204 } |
| 2205 strncpy(buffer, pos, buffer_size); |
| 2206 buffer[buffer_size - 1] = '\0'; |
| 2207 return true; |
| 2208 } |
| 2209 |
| 2210 |
| 2211 struct EvaluateResult { |
| 2212 static const int kBufferSize = 20; |
| 2213 char buffer[kBufferSize]; |
| 2214 }; |
| 2215 |
| 2216 struct DebugProcessDebugMessagesData { |
| 2217 static const int kArraySize = 5; |
| 2218 int counter; |
| 2219 EvaluateResult results[kArraySize]; |
| 2220 |
| 2221 void reset() { |
| 2222 counter = 0; |
| 2223 } |
| 2224 EvaluateResult* current() { |
| 2225 return &results[counter % kArraySize]; |
| 2226 } |
| 2227 void next() { |
| 2228 counter++; |
| 2229 } |
| 2230 }; |
| 2231 |
| 2232 DebugProcessDebugMessagesData process_debug_messages_data; |
| 2233 |
| 2234 static void DebugProcessDebugMessagesHandler( |
| 2235 const uint16_t* message, |
| 2236 int length, |
| 2237 v8::Debug::ClientData* client_data) { |
| 2238 |
| 2239 const int kBufferSize = 100000; |
| 2240 char print_buffer[kBufferSize]; |
| 2241 Utf16ToAscii(message, length, print_buffer, kBufferSize); |
| 2242 |
| 2243 EvaluateResult* array_item = process_debug_messages_data.current(); |
| 2244 |
| 2245 bool res = GetEvaluateStringResult(print_buffer, |
| 2246 array_item->buffer, |
| 2247 EvaluateResult::kBufferSize); |
| 2248 if (res) { |
| 2249 process_debug_messages_data.next(); |
| 2250 } |
| 2251 } |
| 2252 |
| 2253 // Test that the evaluation of expressions works even from ProcessDebugMessages |
| 2254 // i.e. with empty stack. |
| 2255 TEST(DebugEvaluateWithoutStack) { |
| 2256 v8::Debug::SetMessageHandler(DebugProcessDebugMessagesHandler); |
| 2257 |
| 2258 v8::HandleScope scope; |
| 2259 DebugLocalContext env; |
| 2260 |
| 2261 const char* source = |
| 2262 "var v1 = 'Pinguin';\n function getAnimal() { return 'Capy' + 'bara'; }"; |
| 2263 |
| 2264 v8::Script::Compile(v8::String::New(source))->Run(); |
| 2265 |
| 2266 v8::Debug::ProcessDebugMessages(); |
| 2267 |
| 2268 const int kBufferSize = 1000; |
| 2269 uint16_t buffer[kBufferSize]; |
| 2270 |
| 2271 const char* command_111 = "{\"seq\":111," |
| 2272 "\"type\":\"request\"," |
| 2273 "\"command\":\"evaluate\"," |
| 2274 "\"arguments\":{" |
| 2275 " \"global\":true," |
| 2276 " \"expression\":\"v1\",\"disable_break\":true" |
| 2277 "}}"; |
| 2278 |
| 2279 v8::Debug::SendCommand(buffer, AsciiToUtf16(command_111, buffer)); |
| 2280 |
| 2281 const char* command_112 = "{\"seq\":112," |
| 2282 "\"type\":\"request\"," |
| 2283 "\"command\":\"evaluate\"," |
| 2284 "\"arguments\":{" |
| 2285 " \"global\":true," |
| 2286 " \"expression\":\"getAnimal()\",\"disable_break\":true" |
| 2287 "}}"; |
| 2288 |
| 2289 v8::Debug::SendCommand(buffer, AsciiToUtf16(command_112, buffer)); |
| 2290 |
| 2291 const char* command_113 = "{\"seq\":113," |
| 2292 "\"type\":\"request\"," |
| 2293 "\"command\":\"evaluate\"," |
| 2294 "\"arguments\":{" |
| 2295 " \"global\":true," |
| 2296 " \"expression\":\"239 + 566\",\"disable_break\":true" |
| 2297 "}}"; |
| 2298 |
| 2299 v8::Debug::SendCommand(buffer, AsciiToUtf16(command_113, buffer)); |
| 2300 |
| 2301 v8::Debug::ProcessDebugMessages(); |
| 2302 |
| 2303 CHECK_EQ(3, process_debug_messages_data.counter); |
| 2304 |
| 2305 CHECK(strcmp("Pinguin", process_debug_messages_data.results[0].buffer)); |
| 2306 CHECK(strcmp("Captbara", process_debug_messages_data.results[1].buffer)); |
| 2307 CHECK(strcmp("805", process_debug_messages_data.results[2].buffer)); |
| 2308 |
| 2309 v8::Debug::SetMessageHandler(NULL); |
| 2310 v8::Debug::SetDebugEventListener(NULL); |
| 2311 CheckDebuggerUnloaded(); |
| 2312 } |
| 2313 |
2166 | 2314 |
2167 // Simple test of the stepping mechanism using only store ICs. | 2315 // Simple test of the stepping mechanism using only store ICs. |
2168 TEST(DebugStepLinear) { | 2316 TEST(DebugStepLinear) { |
2169 v8::HandleScope scope; | 2317 v8::HandleScope scope; |
2170 DebugLocalContext env; | 2318 DebugLocalContext env; |
2171 | 2319 |
2172 // Create a function for testing stepping. | 2320 // Create a function for testing stepping. |
2173 v8::Local<v8::Function> foo = CompileFunction(&env, | 2321 v8::Local<v8::Function> foo = CompileFunction(&env, |
2174 "function foo(){a=1;b=1;c=1;}", | 2322 "function foo(){a=1;b=1;c=1;}", |
2175 "foo"); | 2323 "foo"); |
(...skipping 1410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3586 "obj_mirror.property('a').value().value() == 1")->BooleanValue()); | 3734 "obj_mirror.property('a').value().value() == 1")->BooleanValue()); |
3587 CHECK(CompileRun( | 3735 CHECK(CompileRun( |
3588 "obj_mirror.property('b').value().value() == 2")->BooleanValue()); | 3736 "obj_mirror.property('b').value().value() == 2")->BooleanValue()); |
3589 } | 3737 } |
3590 | 3738 |
3591 | 3739 |
3592 // Multithreaded tests of JSON debugger protocol | 3740 // Multithreaded tests of JSON debugger protocol |
3593 | 3741 |
3594 // Support classes | 3742 // Support classes |
3595 | 3743 |
3596 // Copies a C string to a 16-bit string. Does not check for buffer overflow. | |
3597 // Does not use the V8 engine to convert strings, so it can be used | |
3598 // in any thread. Returns the length of the string. | |
3599 int AsciiToUtf16(const char* input_buffer, uint16_t* output_buffer) { | |
3600 int i; | |
3601 for (i = 0; input_buffer[i] != '\0'; ++i) { | |
3602 // ASCII does not use chars > 127, but be careful anyway. | |
3603 output_buffer[i] = static_cast<unsigned char>(input_buffer[i]); | |
3604 } | |
3605 output_buffer[i] = 0; | |
3606 return i; | |
3607 } | |
3608 | |
3609 // Copies a 16-bit string to a C string by dropping the high byte of | |
3610 // each character. Does not check for buffer overflow. | |
3611 // Can be used in any thread. Requires string length as an input. | |
3612 int Utf16ToAscii(const uint16_t* input_buffer, int length, | |
3613 char* output_buffer) { | |
3614 for (int i = 0; i < length; ++i) { | |
3615 output_buffer[i] = static_cast<char>(input_buffer[i]); | |
3616 } | |
3617 output_buffer[length] = '\0'; | |
3618 return length; | |
3619 } | |
3620 | |
3621 // Provides synchronization between k threads, where k is an input to the | 3744 // Provides synchronization between k threads, where k is an input to the |
3622 // constructor. The Wait() call blocks a thread until it is called for the | 3745 // constructor. The Wait() call blocks a thread until it is called for the |
3623 // k'th time, then all calls return. Each ThreadBarrier object can only | 3746 // k'th time, then all calls return. Each ThreadBarrier object can only |
3624 // be used once. | 3747 // be used once. |
3625 class ThreadBarrier { | 3748 class ThreadBarrier { |
3626 public: | 3749 public: |
3627 explicit ThreadBarrier(int num_threads); | 3750 explicit ThreadBarrier(int num_threads); |
3628 ~ThreadBarrier(); | 3751 ~ThreadBarrier(); |
3629 void Wait(); | 3752 void Wait(); |
3630 private: | 3753 private: |
(...skipping 2196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5827 | 5950 |
5828 break_point_hit_count = 0; | 5951 break_point_hit_count = 0; |
5829 foo->Call(env->Global(), 0, NULL); | 5952 foo->Call(env->Global(), 0, NULL); |
5830 CHECK_EQ(1, break_point_hit_count); | 5953 CHECK_EQ(1, break_point_hit_count); |
5831 | 5954 |
5832 v8::Debug::SetDebugEventListener(NULL); | 5955 v8::Debug::SetDebugEventListener(NULL); |
5833 debugee_context = v8::Handle<v8::Context>(); | 5956 debugee_context = v8::Handle<v8::Context>(); |
5834 debugger_context = v8::Handle<v8::Context>(); | 5957 debugger_context = v8::Handle<v8::Context>(); |
5835 CheckDebuggerUnloaded(); | 5958 CheckDebuggerUnloaded(); |
5836 } | 5959 } |
OLD | NEW |