| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 |
| 11 // with the distribution. | 11 // with the distribution. |
| 12 // * Neither the name of Google Inc. nor the names of its | 12 // * Neither the name of Google Inc. nor the names of its |
| 13 // contributors may be used to endorse or promote products derived | 13 // contributors may be used to endorse or promote products derived |
| 14 // from this software without specific prior written permission. | 14 // from this software without specific prior written permission. |
| 15 // | 15 // |
| 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 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. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | 27 |
| 28 // TODO(jochen): Remove this after the setting is turned on globally. |
| 29 #define V8_IMMINENT_DEPRECATION_WARNINGS |
| 30 |
| 28 #include <stdlib.h> | 31 #include <stdlib.h> |
| 29 | 32 |
| 30 #include "src/v8.h" | 33 #include "src/v8.h" |
| 31 | 34 |
| 32 #include "src/api.h" | 35 #include "src/api.h" |
| 33 #include "src/base/platform/condition-variable.h" | 36 #include "src/base/platform/condition-variable.h" |
| 34 #include "src/base/platform/platform.h" | 37 #include "src/base/platform/platform.h" |
| 35 #include "src/compilation-cache.h" | 38 #include "src/compilation-cache.h" |
| 36 #include "src/debug/debug.h" | 39 #include "src/debug/debug.h" |
| 37 #include "src/deoptimizer.h" | 40 #include "src/deoptimizer.h" |
| (...skipping 28 matching lines...) Expand all Loading... |
| 66 #define SMALL_STRING_BUFFER_SIZE 80 | 69 #define SMALL_STRING_BUFFER_SIZE 80 |
| 67 | 70 |
| 68 // --- H e l p e r C l a s s e s | 71 // --- H e l p e r C l a s s e s |
| 69 | 72 |
| 70 | 73 |
| 71 // Helper class for creating a V8 enviromnent for running tests | 74 // Helper class for creating a V8 enviromnent for running tests |
| 72 class DebugLocalContext { | 75 class DebugLocalContext { |
| 73 public: | 76 public: |
| 74 inline DebugLocalContext( | 77 inline DebugLocalContext( |
| 75 v8::Isolate* isolate, v8::ExtensionConfiguration* extensions = 0, | 78 v8::Isolate* isolate, v8::ExtensionConfiguration* extensions = 0, |
| 76 v8::Handle<v8::ObjectTemplate> global_template = | 79 v8::Local<v8::ObjectTemplate> global_template = |
| 77 v8::Handle<v8::ObjectTemplate>(), | 80 v8::Local<v8::ObjectTemplate>(), |
| 78 v8::Handle<v8::Value> global_object = v8::Handle<v8::Value>()) | 81 v8::Local<v8::Value> global_object = v8::Local<v8::Value>()) |
| 79 : scope_(isolate), | 82 : scope_(isolate), |
| 80 context_(v8::Context::New(isolate, extensions, global_template, | 83 context_(v8::Context::New(isolate, extensions, global_template, |
| 81 global_object)) { | 84 global_object)) { |
| 82 context_->Enter(); | 85 context_->Enter(); |
| 83 } | 86 } |
| 84 inline DebugLocalContext( | 87 inline DebugLocalContext( |
| 85 v8::ExtensionConfiguration* extensions = 0, | 88 v8::ExtensionConfiguration* extensions = 0, |
| 86 v8::Handle<v8::ObjectTemplate> global_template = | 89 v8::Local<v8::ObjectTemplate> global_template = |
| 87 v8::Handle<v8::ObjectTemplate>(), | 90 v8::Local<v8::ObjectTemplate>(), |
| 88 v8::Handle<v8::Value> global_object = v8::Handle<v8::Value>()) | 91 v8::Local<v8::Value> global_object = v8::Local<v8::Value>()) |
| 89 : scope_(CcTest::isolate()), | 92 : scope_(CcTest::isolate()), |
| 90 context_(v8::Context::New(CcTest::isolate(), extensions, | 93 context_(v8::Context::New(CcTest::isolate(), extensions, |
| 91 global_template, global_object)) { | 94 global_template, global_object)) { |
| 92 context_->Enter(); | 95 context_->Enter(); |
| 93 } | 96 } |
| 94 inline ~DebugLocalContext() { | 97 inline ~DebugLocalContext() { |
| 95 context_->Exit(); | 98 context_->Exit(); |
| 96 } | 99 } |
| 97 inline v8::Local<v8::Context> context() { return context_; } | 100 inline v8::Local<v8::Context> context() { return context_; } |
| 98 inline v8::Context* operator->() { return *context_; } | 101 inline v8::Context* operator->() { return *context_; } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 120 } | 123 } |
| 121 | 124 |
| 122 private: | 125 private: |
| 123 v8::HandleScope scope_; | 126 v8::HandleScope scope_; |
| 124 v8::Local<v8::Context> context_; | 127 v8::Local<v8::Context> context_; |
| 125 }; | 128 }; |
| 126 | 129 |
| 127 | 130 |
| 128 // --- H e l p e r F u n c t i o n s | 131 // --- H e l p e r F u n c t i o n s |
| 129 | 132 |
| 130 | |
| 131 // Compile and run the supplied source and return the fequested function. | |
| 132 static v8::Local<v8::Function> CompileFunction(DebugLocalContext* env, | |
| 133 const char* source, | |
| 134 const char* function_name) { | |
| 135 v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), source)) | |
| 136 ->Run(); | |
| 137 return v8::Local<v8::Function>::Cast((*env)->Global()->Get( | |
| 138 v8::String::NewFromUtf8(env->GetIsolate(), function_name))); | |
| 139 } | |
| 140 | |
| 141 | |
| 142 // Compile and run the supplied source and return the requested function. | 133 // Compile and run the supplied source and return the requested function. |
| 143 static v8::Local<v8::Function> CompileFunction(v8::Isolate* isolate, | 134 static v8::Local<v8::Function> CompileFunction(v8::Isolate* isolate, |
| 144 const char* source, | 135 const char* source, |
| 145 const char* function_name) { | 136 const char* function_name) { |
| 146 v8::Script::Compile(v8::String::NewFromUtf8(isolate, source))->Run(); | 137 CompileRunChecked(isolate, source); |
| 147 v8::Local<v8::Object> global = isolate->GetCurrentContext()->Global(); | 138 v8::Local<v8::String> name = v8_str(isolate, function_name); |
| 148 return v8::Local<v8::Function>::Cast( | 139 v8::Local<v8::Context> context = isolate->GetCurrentContext(); |
| 149 global->Get(v8::String::NewFromUtf8(isolate, function_name))); | 140 v8::MaybeLocal<v8::Value> maybe_function = |
| 141 context->Global()->Get(context, name); |
| 142 return v8::Local<v8::Function>::Cast(maybe_function.ToLocalChecked()); |
| 143 } |
| 144 |
| 145 |
| 146 // Compile and run the supplied source and return the requested function. |
| 147 static v8::Local<v8::Function> CompileFunction(DebugLocalContext* env, |
| 148 const char* source, |
| 149 const char* function_name) { |
| 150 return CompileFunction(env->GetIsolate(), source, function_name); |
| 150 } | 151 } |
| 151 | 152 |
| 152 | 153 |
| 153 // Is there any debug info for the function? | 154 // Is there any debug info for the function? |
| 154 static bool HasDebugInfo(v8::Handle<v8::Function> fun) { | 155 static bool HasDebugInfo(v8::Local<v8::Function> fun) { |
| 155 Handle<v8::internal::JSFunction> f = | 156 Handle<v8::internal::JSFunction> f = |
| 156 Handle<v8::internal::JSFunction>::cast(v8::Utils::OpenHandle(*fun)); | 157 Handle<v8::internal::JSFunction>::cast(v8::Utils::OpenHandle(*fun)); |
| 157 Handle<v8::internal::SharedFunctionInfo> shared(f->shared()); | 158 Handle<v8::internal::SharedFunctionInfo> shared(f->shared()); |
| 158 return shared->HasDebugInfo(); | 159 return shared->HasDebugInfo(); |
| 159 } | 160 } |
| 160 | 161 |
| 161 | 162 |
| 162 // Set a break point in a function and return the associated break point | 163 // Set a break point in a function and return the associated break point |
| 163 // number. | 164 // number. |
| 164 static int SetBreakPoint(Handle<v8::internal::JSFunction> fun, int position) { | 165 static int SetBreakPoint(Handle<v8::internal::JSFunction> fun, int position) { |
| 165 static int break_point = 0; | 166 static int break_point = 0; |
| 166 v8::internal::Isolate* isolate = fun->GetIsolate(); | 167 v8::internal::Isolate* isolate = fun->GetIsolate(); |
| 167 v8::internal::Debug* debug = isolate->debug(); | 168 v8::internal::Debug* debug = isolate->debug(); |
| 168 debug->SetBreakPoint( | 169 debug->SetBreakPoint( |
| 169 fun, | 170 fun, |
| 170 Handle<Object>(v8::internal::Smi::FromInt(++break_point), isolate), | 171 Handle<Object>(v8::internal::Smi::FromInt(++break_point), isolate), |
| 171 &position); | 172 &position); |
| 172 return break_point; | 173 return break_point; |
| 173 } | 174 } |
| 174 | 175 |
| 175 | 176 |
| 176 // Set a break point in a function and return the associated break point | 177 // Set a break point in a function and return the associated break point |
| 177 // number. | 178 // number. |
| 178 static int SetBreakPoint(v8::Handle<v8::Function> fun, int position) { | 179 static int SetBreakPoint(v8::Local<v8::Function> fun, int position) { |
| 179 return SetBreakPoint( | 180 return SetBreakPoint( |
| 180 i::Handle<i::JSFunction>::cast(v8::Utils::OpenHandle(*fun)), position); | 181 i::Handle<i::JSFunction>::cast(v8::Utils::OpenHandle(*fun)), position); |
| 181 } | 182 } |
| 182 | 183 |
| 183 | 184 |
| 184 // Set a break point in a function using the Debug object and return the | 185 // Set a break point in a function using the Debug object and return the |
| 185 // associated break point number. | 186 // associated break point number. |
| 186 static int SetBreakPointFromJS(v8::Isolate* isolate, | 187 static int SetBreakPointFromJS(v8::Isolate* isolate, |
| 187 const char* function_name, | 188 const char* function_name, |
| 188 int line, int position) { | 189 int line, int position) { |
| 189 EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; | 190 EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; |
| 190 SNPrintF(buffer, | 191 SNPrintF(buffer, |
| 191 "debug.Debug.setBreakPoint(%s,%d,%d)", | 192 "debug.Debug.setBreakPoint(%s,%d,%d)", |
| 192 function_name, line, position); | 193 function_name, line, position); |
| 193 buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0'; | 194 buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0'; |
| 194 v8::Handle<v8::String> str = v8::String::NewFromUtf8(isolate, buffer.start()); | 195 v8::Local<v8::Value> value = CompileRunChecked(isolate, buffer.start()); |
| 195 return v8::Script::Compile(str)->Run()->Int32Value(); | 196 return value->Int32Value(isolate->GetCurrentContext()).FromJust(); |
| 196 } | 197 } |
| 197 | 198 |
| 198 | 199 |
| 199 // Set a break point in a script identified by id using the global Debug object. | 200 // Set a break point in a script identified by id using the global Debug object. |
| 200 static int SetScriptBreakPointByIdFromJS(v8::Isolate* isolate, int script_id, | 201 static int SetScriptBreakPointByIdFromJS(v8::Isolate* isolate, int script_id, |
| 201 int line, int column) { | 202 int line, int column) { |
| 202 EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; | 203 EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; |
| 203 if (column >= 0) { | 204 if (column >= 0) { |
| 204 // Column specified set script break point on precise location. | 205 // Column specified set script break point on precise location. |
| 205 SNPrintF(buffer, | 206 SNPrintF(buffer, |
| 206 "debug.Debug.setScriptBreakPointById(%d,%d,%d)", | 207 "debug.Debug.setScriptBreakPointById(%d,%d,%d)", |
| 207 script_id, line, column); | 208 script_id, line, column); |
| 208 } else { | 209 } else { |
| 209 // Column not specified set script break point on line. | 210 // Column not specified set script break point on line. |
| 210 SNPrintF(buffer, | 211 SNPrintF(buffer, |
| 211 "debug.Debug.setScriptBreakPointById(%d,%d)", | 212 "debug.Debug.setScriptBreakPointById(%d,%d)", |
| 212 script_id, line); | 213 script_id, line); |
| 213 } | 214 } |
| 214 buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0'; | 215 buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0'; |
| 215 { | 216 { |
| 216 v8::TryCatch try_catch(isolate); | 217 v8::TryCatch try_catch(isolate); |
| 217 v8::Handle<v8::String> str = | 218 v8::Local<v8::Value> value = CompileRunChecked(isolate, buffer.start()); |
| 218 v8::String::NewFromUtf8(isolate, buffer.start()); | |
| 219 v8::Handle<v8::Value> value = v8::Script::Compile(str)->Run(); | |
| 220 CHECK(!try_catch.HasCaught()); | 219 CHECK(!try_catch.HasCaught()); |
| 221 return value->Int32Value(); | 220 return value->Int32Value(isolate->GetCurrentContext()).FromJust(); |
| 222 } | 221 } |
| 223 } | 222 } |
| 224 | 223 |
| 225 | 224 |
| 226 // Set a break point in a script identified by name using the global Debug | 225 // Set a break point in a script identified by name using the global Debug |
| 227 // object. | 226 // object. |
| 228 static int SetScriptBreakPointByNameFromJS(v8::Isolate* isolate, | 227 static int SetScriptBreakPointByNameFromJS(v8::Isolate* isolate, |
| 229 const char* script_name, int line, | 228 const char* script_name, int line, |
| 230 int column) { | 229 int column) { |
| 231 EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; | 230 EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; |
| 232 if (column >= 0) { | 231 if (column >= 0) { |
| 233 // Column specified set script break point on precise location. | 232 // Column specified set script break point on precise location. |
| 234 SNPrintF(buffer, | 233 SNPrintF(buffer, |
| 235 "debug.Debug.setScriptBreakPointByName(\"%s\",%d,%d)", | 234 "debug.Debug.setScriptBreakPointByName(\"%s\",%d,%d)", |
| 236 script_name, line, column); | 235 script_name, line, column); |
| 237 } else { | 236 } else { |
| 238 // Column not specified set script break point on line. | 237 // Column not specified set script break point on line. |
| 239 SNPrintF(buffer, | 238 SNPrintF(buffer, |
| 240 "debug.Debug.setScriptBreakPointByName(\"%s\",%d)", | 239 "debug.Debug.setScriptBreakPointByName(\"%s\",%d)", |
| 241 script_name, line); | 240 script_name, line); |
| 242 } | 241 } |
| 243 buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0'; | 242 buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0'; |
| 244 { | 243 { |
| 245 v8::TryCatch try_catch(isolate); | 244 v8::TryCatch try_catch(isolate); |
| 246 v8::Handle<v8::String> str = | 245 v8::Local<v8::Value> value = CompileRunChecked(isolate, buffer.start()); |
| 247 v8::String::NewFromUtf8(isolate, buffer.start()); | |
| 248 v8::Handle<v8::Value> value = v8::Script::Compile(str)->Run(); | |
| 249 CHECK(!try_catch.HasCaught()); | 246 CHECK(!try_catch.HasCaught()); |
| 250 return value->Int32Value(); | 247 return value->Int32Value(isolate->GetCurrentContext()).FromJust(); |
| 251 } | 248 } |
| 252 } | 249 } |
| 253 | 250 |
| 254 | 251 |
| 255 // Clear a break point. | 252 // Clear a break point. |
| 256 static void ClearBreakPoint(int break_point) { | 253 static void ClearBreakPoint(int break_point) { |
| 257 v8::internal::Isolate* isolate = CcTest::i_isolate(); | 254 v8::internal::Isolate* isolate = CcTest::i_isolate(); |
| 258 v8::internal::Debug* debug = isolate->debug(); | 255 v8::internal::Debug* debug = isolate->debug(); |
| 259 debug->ClearBreakPoint( | 256 debug->ClearBreakPoint( |
| 260 Handle<Object>(v8::internal::Smi::FromInt(break_point), isolate)); | 257 Handle<Object>(v8::internal::Smi::FromInt(break_point), isolate)); |
| 261 } | 258 } |
| 262 | 259 |
| 263 | 260 |
| 264 // Clear a break point using the global Debug object. | 261 // Clear a break point using the global Debug object. |
| 265 static void ClearBreakPointFromJS(v8::Isolate* isolate, | 262 static void ClearBreakPointFromJS(v8::Isolate* isolate, |
| 266 int break_point_number) { | 263 int break_point_number) { |
| 267 EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; | 264 EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; |
| 268 SNPrintF(buffer, | 265 SNPrintF(buffer, |
| 269 "debug.Debug.clearBreakPoint(%d)", | 266 "debug.Debug.clearBreakPoint(%d)", |
| 270 break_point_number); | 267 break_point_number); |
| 271 buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0'; | 268 buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0'; |
| 272 v8::Script::Compile(v8::String::NewFromUtf8(isolate, buffer.start()))->Run(); | 269 CompileRunChecked(isolate, buffer.start()); |
| 273 } | 270 } |
| 274 | 271 |
| 275 | 272 |
| 276 static void EnableScriptBreakPointFromJS(v8::Isolate* isolate, | 273 static void EnableScriptBreakPointFromJS(v8::Isolate* isolate, |
| 277 int break_point_number) { | 274 int break_point_number) { |
| 278 EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; | 275 EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; |
| 279 SNPrintF(buffer, | 276 SNPrintF(buffer, |
| 280 "debug.Debug.enableScriptBreakPoint(%d)", | 277 "debug.Debug.enableScriptBreakPoint(%d)", |
| 281 break_point_number); | 278 break_point_number); |
| 282 buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0'; | 279 buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0'; |
| 283 v8::Script::Compile(v8::String::NewFromUtf8(isolate, buffer.start()))->Run(); | 280 CompileRunChecked(isolate, buffer.start()); |
| 284 } | 281 } |
| 285 | 282 |
| 286 | 283 |
| 287 static void DisableScriptBreakPointFromJS(v8::Isolate* isolate, | 284 static void DisableScriptBreakPointFromJS(v8::Isolate* isolate, |
| 288 int break_point_number) { | 285 int break_point_number) { |
| 289 EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; | 286 EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; |
| 290 SNPrintF(buffer, | 287 SNPrintF(buffer, |
| 291 "debug.Debug.disableScriptBreakPoint(%d)", | 288 "debug.Debug.disableScriptBreakPoint(%d)", |
| 292 break_point_number); | 289 break_point_number); |
| 293 buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0'; | 290 buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0'; |
| 294 v8::Script::Compile(v8::String::NewFromUtf8(isolate, buffer.start()))->Run(); | 291 CompileRunChecked(isolate, buffer.start()); |
| 295 } | 292 } |
| 296 | 293 |
| 297 | 294 |
| 298 static void ChangeScriptBreakPointConditionFromJS(v8::Isolate* isolate, | 295 static void ChangeScriptBreakPointConditionFromJS(v8::Isolate* isolate, |
| 299 int break_point_number, | 296 int break_point_number, |
| 300 const char* condition) { | 297 const char* condition) { |
| 301 EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; | 298 EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; |
| 302 SNPrintF(buffer, | 299 SNPrintF(buffer, |
| 303 "debug.Debug.changeScriptBreakPointCondition(%d, \"%s\")", | 300 "debug.Debug.changeScriptBreakPointCondition(%d, \"%s\")", |
| 304 break_point_number, condition); | 301 break_point_number, condition); |
| 305 buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0'; | 302 buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0'; |
| 306 v8::Script::Compile(v8::String::NewFromUtf8(isolate, buffer.start()))->Run(); | 303 CompileRunChecked(isolate, buffer.start()); |
| 307 } | 304 } |
| 308 | 305 |
| 309 | 306 |
| 310 static void ChangeScriptBreakPointIgnoreCountFromJS(v8::Isolate* isolate, | 307 static void ChangeScriptBreakPointIgnoreCountFromJS(v8::Isolate* isolate, |
| 311 int break_point_number, | 308 int break_point_number, |
| 312 int ignoreCount) { | 309 int ignoreCount) { |
| 313 EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; | 310 EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; |
| 314 SNPrintF(buffer, | 311 SNPrintF(buffer, |
| 315 "debug.Debug.changeScriptBreakPointIgnoreCount(%d, %d)", | 312 "debug.Debug.changeScriptBreakPointIgnoreCount(%d, %d)", |
| 316 break_point_number, ignoreCount); | 313 break_point_number, ignoreCount); |
| 317 buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0'; | 314 buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0'; |
| 318 v8::Script::Compile(v8::String::NewFromUtf8(isolate, buffer.start()))->Run(); | 315 CompileRunChecked(isolate, buffer.start()); |
| 319 } | 316 } |
| 320 | 317 |
| 321 | 318 |
| 322 // Change break on exception. | 319 // Change break on exception. |
| 323 static void ChangeBreakOnException(bool caught, bool uncaught) { | 320 static void ChangeBreakOnException(bool caught, bool uncaught) { |
| 324 v8::internal::Debug* debug = CcTest::i_isolate()->debug(); | 321 v8::internal::Debug* debug = CcTest::i_isolate()->debug(); |
| 325 debug->ChangeBreakOnException(v8::internal::BreakException, caught); | 322 debug->ChangeBreakOnException(v8::internal::BreakException, caught); |
| 326 debug->ChangeBreakOnException(v8::internal::BreakUncaughtException, uncaught); | 323 debug->ChangeBreakOnException(v8::internal::BreakUncaughtException, uncaught); |
| 327 } | 324 } |
| 328 | 325 |
| 329 | 326 |
| 330 // Change break on exception using the global Debug object. | 327 // Change break on exception using the global Debug object. |
| 331 static void ChangeBreakOnExceptionFromJS(v8::Isolate* isolate, bool caught, | 328 static void ChangeBreakOnExceptionFromJS(v8::Isolate* isolate, bool caught, |
| 332 bool uncaught) { | 329 bool uncaught) { |
| 333 if (caught) { | 330 if (caught) { |
| 334 v8::Script::Compile( | 331 CompileRunChecked(isolate, "debug.Debug.setBreakOnException()"); |
| 335 v8::String::NewFromUtf8(isolate, "debug.Debug.setBreakOnException()")) | |
| 336 ->Run(); | |
| 337 } else { | 332 } else { |
| 338 v8::Script::Compile( | 333 CompileRunChecked(isolate, "debug.Debug.clearBreakOnException()"); |
| 339 v8::String::NewFromUtf8(isolate, "debug.Debug.clearBreakOnException()")) | |
| 340 ->Run(); | |
| 341 } | 334 } |
| 342 if (uncaught) { | 335 if (uncaught) { |
| 343 v8::Script::Compile( | 336 CompileRunChecked(isolate, "debug.Debug.setBreakOnUncaughtException()"); |
| 344 v8::String::NewFromUtf8( | |
| 345 isolate, "debug.Debug.setBreakOnUncaughtException()"))->Run(); | |
| 346 } else { | 337 } else { |
| 347 v8::Script::Compile( | 338 CompileRunChecked(isolate, "debug.Debug.clearBreakOnUncaughtException()"); |
| 348 v8::String::NewFromUtf8( | |
| 349 isolate, "debug.Debug.clearBreakOnUncaughtException()"))->Run(); | |
| 350 } | 339 } |
| 351 } | 340 } |
| 352 | 341 |
| 353 | 342 |
| 354 // Prepare to step to next break location. | 343 // Prepare to step to next break location. |
| 355 static void PrepareStep(StepAction step_action) { | 344 static void PrepareStep(StepAction step_action) { |
| 356 v8::internal::Debug* debug = CcTest::i_isolate()->debug(); | 345 v8::internal::Debug* debug = CcTest::i_isolate()->debug(); |
| 357 debug->PrepareStep(step_action, 1, StackFrame::NO_ID); | 346 debug->PrepareStep(step_action, 1, StackFrame::NO_ID); |
| 358 } | 347 } |
| 359 | 348 |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 513 " return exec_state.frame(0).func().script().name();" | 502 " return exec_state.frame(0).func().script().name();" |
| 514 "}"; | 503 "}"; |
| 515 v8::Local<v8::Function> frame_script_name; | 504 v8::Local<v8::Function> frame_script_name; |
| 516 | 505 |
| 517 | 506 |
| 518 // Source for the JavaScript function which returns the number of frames. | 507 // Source for the JavaScript function which returns the number of frames. |
| 519 static const char* frame_count_source = | 508 static const char* frame_count_source = |
| 520 "function frame_count(exec_state) {" | 509 "function frame_count(exec_state) {" |
| 521 " return exec_state.frameCount();" | 510 " return exec_state.frameCount();" |
| 522 "}"; | 511 "}"; |
| 523 v8::Handle<v8::Function> frame_count; | 512 v8::Local<v8::Function> frame_count; |
| 524 | 513 |
| 525 | 514 |
| 526 // Global variable to store the last function hit - used by some tests. | 515 // Global variable to store the last function hit - used by some tests. |
| 527 char last_function_hit[80]; | 516 char last_function_hit[80]; |
| 528 | 517 |
| 529 // Global variable to store the name for last script hit - used by some tests. | 518 // Global variable to store the name for last script hit - used by some tests. |
| 530 char last_script_name_hit[80]; | 519 char last_script_name_hit[80]; |
| 531 | 520 |
| 532 // Global variables to store the last source position - used by some tests. | 521 // Global variables to store the last source position - used by some tests. |
| 533 int last_source_line = -1; | 522 int last_source_line = -1; |
| 534 int last_source_column = -1; | 523 int last_source_column = -1; |
| 535 | 524 |
| 536 // Debug event handler which counts the break points which have been hit. | 525 // Debug event handler which counts the break points which have been hit. |
| 537 int break_point_hit_count = 0; | 526 int break_point_hit_count = 0; |
| 538 int break_point_hit_count_deoptimize = 0; | 527 int break_point_hit_count_deoptimize = 0; |
| 539 static void DebugEventBreakPointHitCount( | 528 static void DebugEventBreakPointHitCount( |
| 540 const v8::Debug::EventDetails& event_details) { | 529 const v8::Debug::EventDetails& event_details) { |
| 541 v8::DebugEvent event = event_details.GetEvent(); | 530 v8::DebugEvent event = event_details.GetEvent(); |
| 542 v8::Handle<v8::Object> exec_state = event_details.GetExecutionState(); | 531 v8::Local<v8::Object> exec_state = event_details.GetExecutionState(); |
| 532 v8::Local<v8::Context> context = CcTest::isolate()->GetCurrentContext(); |
| 543 v8::internal::Isolate* isolate = CcTest::i_isolate(); | 533 v8::internal::Isolate* isolate = CcTest::i_isolate(); |
| 544 Debug* debug = isolate->debug(); | 534 Debug* debug = isolate->debug(); |
| 545 // When hitting a debug event listener there must be a break set. | 535 // When hitting a debug event listener there must be a break set. |
| 546 CHECK_NE(debug->break_id(), 0); | 536 CHECK_NE(debug->break_id(), 0); |
| 547 | 537 |
| 548 // Count the number of breaks. | 538 // Count the number of breaks. |
| 549 if (event == v8::Break) { | 539 if (event == v8::Break) { |
| 550 break_point_hit_count++; | 540 break_point_hit_count++; |
| 551 if (!frame_function_name.IsEmpty()) { | 541 if (!frame_function_name.IsEmpty()) { |
| 552 // Get the name of the function. | 542 // Get the name of the function. |
| 553 const int argc = 2; | 543 const int argc = 2; |
| 554 v8::Handle<v8::Value> argv[argc] = { | 544 v8::Local<v8::Value> argv[argc] = { |
| 555 exec_state, v8::Integer::New(CcTest::isolate(), 0) | 545 exec_state, v8::Integer::New(CcTest::isolate(), 0)}; |
| 556 }; | 546 v8::Local<v8::Value> result = |
| 557 v8::Handle<v8::Value> result = frame_function_name->Call(exec_state, | 547 frame_function_name->Call(context, exec_state, argc, argv) |
| 558 argc, argv); | 548 .ToLocalChecked(); |
| 559 if (result->IsUndefined()) { | 549 if (result->IsUndefined()) { |
| 560 last_function_hit[0] = '\0'; | 550 last_function_hit[0] = '\0'; |
| 561 } else { | 551 } else { |
| 562 CHECK(result->IsString()); | 552 CHECK(result->IsString()); |
| 563 v8::Handle<v8::String> function_name(result.As<v8::String>()); | 553 v8::Local<v8::String> function_name(result.As<v8::String>()); |
| 564 function_name->WriteUtf8(last_function_hit); | 554 function_name->WriteUtf8(last_function_hit); |
| 565 } | 555 } |
| 566 } | 556 } |
| 567 | 557 |
| 568 if (!frame_source_line.IsEmpty()) { | 558 if (!frame_source_line.IsEmpty()) { |
| 569 // Get the source line. | 559 // Get the source line. |
| 570 const int argc = 1; | 560 const int argc = 1; |
| 571 v8::Handle<v8::Value> argv[argc] = { exec_state }; | 561 v8::Local<v8::Value> argv[argc] = {exec_state}; |
| 572 v8::Handle<v8::Value> result = frame_source_line->Call(exec_state, | 562 v8::Local<v8::Value> result = |
| 573 argc, argv); | 563 frame_source_line->Call(context, exec_state, argc, argv) |
| 564 .ToLocalChecked(); |
| 574 CHECK(result->IsNumber()); | 565 CHECK(result->IsNumber()); |
| 575 last_source_line = result->Int32Value(); | 566 last_source_line = result->Int32Value(context).FromJust(); |
| 576 } | 567 } |
| 577 | 568 |
| 578 if (!frame_source_column.IsEmpty()) { | 569 if (!frame_source_column.IsEmpty()) { |
| 579 // Get the source column. | 570 // Get the source column. |
| 580 const int argc = 1; | 571 const int argc = 1; |
| 581 v8::Handle<v8::Value> argv[argc] = { exec_state }; | 572 v8::Local<v8::Value> argv[argc] = {exec_state}; |
| 582 v8::Handle<v8::Value> result = frame_source_column->Call(exec_state, | 573 v8::Local<v8::Value> result = |
| 583 argc, argv); | 574 frame_source_column->Call(context, exec_state, argc, argv) |
| 575 .ToLocalChecked(); |
| 584 CHECK(result->IsNumber()); | 576 CHECK(result->IsNumber()); |
| 585 last_source_column = result->Int32Value(); | 577 last_source_column = result->Int32Value(context).FromJust(); |
| 586 } | 578 } |
| 587 | 579 |
| 588 if (!frame_script_name.IsEmpty()) { | 580 if (!frame_script_name.IsEmpty()) { |
| 589 // Get the script name of the function script. | 581 // Get the script name of the function script. |
| 590 const int argc = 1; | 582 const int argc = 1; |
| 591 v8::Handle<v8::Value> argv[argc] = { exec_state }; | 583 v8::Local<v8::Value> argv[argc] = {exec_state}; |
| 592 v8::Handle<v8::Value> result = frame_script_name->Call(exec_state, | 584 v8::Local<v8::Value> result = |
| 593 argc, argv); | 585 frame_script_name->Call(context, exec_state, argc, argv) |
| 586 .ToLocalChecked(); |
| 594 if (result->IsUndefined()) { | 587 if (result->IsUndefined()) { |
| 595 last_script_name_hit[0] = '\0'; | 588 last_script_name_hit[0] = '\0'; |
| 596 } else { | 589 } else { |
| 597 CHECK(result->IsString()); | 590 CHECK(result->IsString()); |
| 598 v8::Handle<v8::String> script_name(result.As<v8::String>()); | 591 v8::Local<v8::String> script_name(result.As<v8::String>()); |
| 599 script_name->WriteUtf8(last_script_name_hit); | 592 script_name->WriteUtf8(last_script_name_hit); |
| 600 } | 593 } |
| 601 } | 594 } |
| 602 | 595 |
| 603 // Perform a full deoptimization when the specified number of | 596 // Perform a full deoptimization when the specified number of |
| 604 // breaks have been hit. | 597 // breaks have been hit. |
| 605 if (break_point_hit_count == break_point_hit_count_deoptimize) { | 598 if (break_point_hit_count == break_point_hit_count_deoptimize) { |
| 606 i::Deoptimizer::DeoptimizeAll(isolate); | 599 i::Deoptimizer::DeoptimizeAll(isolate); |
| 607 } | 600 } |
| 608 } | 601 } |
| 609 } | 602 } |
| 610 | 603 |
| 611 | 604 |
| 612 // Debug event handler which counts a number of events and collects the stack | 605 // Debug event handler which counts a number of events and collects the stack |
| 613 // height if there is a function compiled for that. | 606 // height if there is a function compiled for that. |
| 614 int exception_hit_count = 0; | 607 int exception_hit_count = 0; |
| 615 int uncaught_exception_hit_count = 0; | 608 int uncaught_exception_hit_count = 0; |
| 616 int last_js_stack_height = -1; | 609 int last_js_stack_height = -1; |
| 617 v8::Handle<v8::Function> debug_event_listener_callback; | 610 v8::Local<v8::Function> debug_event_listener_callback; |
| 618 int debug_event_listener_callback_result; | 611 int debug_event_listener_callback_result; |
| 619 | 612 |
| 620 static void DebugEventCounterClear() { | 613 static void DebugEventCounterClear() { |
| 621 break_point_hit_count = 0; | 614 break_point_hit_count = 0; |
| 622 exception_hit_count = 0; | 615 exception_hit_count = 0; |
| 623 uncaught_exception_hit_count = 0; | 616 uncaught_exception_hit_count = 0; |
| 624 } | 617 } |
| 625 | 618 |
| 626 static void DebugEventCounter( | 619 static void DebugEventCounter( |
| 627 const v8::Debug::EventDetails& event_details) { | 620 const v8::Debug::EventDetails& event_details) { |
| 628 v8::DebugEvent event = event_details.GetEvent(); | 621 v8::DebugEvent event = event_details.GetEvent(); |
| 629 v8::Handle<v8::Object> exec_state = event_details.GetExecutionState(); | 622 v8::Local<v8::Object> exec_state = event_details.GetExecutionState(); |
| 630 v8::Handle<v8::Object> event_data = event_details.GetEventData(); | 623 v8::Local<v8::Object> event_data = event_details.GetEventData(); |
| 624 v8::Local<v8::Context> context = CcTest::isolate()->GetCurrentContext(); |
| 631 v8::internal::Debug* debug = CcTest::i_isolate()->debug(); | 625 v8::internal::Debug* debug = CcTest::i_isolate()->debug(); |
| 632 | 626 |
| 633 // When hitting a debug event listener there must be a break set. | 627 // When hitting a debug event listener there must be a break set. |
| 634 CHECK_NE(debug->break_id(), 0); | 628 CHECK_NE(debug->break_id(), 0); |
| 635 | 629 |
| 636 // Count the number of breaks. | 630 // Count the number of breaks. |
| 637 if (event == v8::Break) { | 631 if (event == v8::Break) { |
| 638 break_point_hit_count++; | 632 break_point_hit_count++; |
| 639 } else if (event == v8::Exception) { | 633 } else if (event == v8::Exception) { |
| 640 exception_hit_count++; | 634 exception_hit_count++; |
| 641 | 635 |
| 642 // Check whether the exception was uncaught. | 636 // Check whether the exception was uncaught. |
| 643 v8::Local<v8::String> fun_name = | 637 v8::Local<v8::String> fun_name = v8_str(CcTest::isolate(), "uncaught"); |
| 644 v8::String::NewFromUtf8(CcTest::isolate(), "uncaught"); | 638 v8::Local<v8::Function> fun = v8::Local<v8::Function>::Cast( |
| 645 v8::Local<v8::Function> fun = | 639 event_data->Get(context, fun_name).ToLocalChecked()); |
| 646 v8::Local<v8::Function>::Cast(event_data->Get(fun_name)); | 640 v8::Local<v8::Value> result = |
| 647 v8::Local<v8::Value> result = fun->Call(event_data, 0, NULL); | 641 fun->Call(context, event_data, 0, NULL).ToLocalChecked(); |
| 648 if (result->IsTrue()) { | 642 if (result->IsTrue()) { |
| 649 uncaught_exception_hit_count++; | 643 uncaught_exception_hit_count++; |
| 650 } | 644 } |
| 651 } | 645 } |
| 652 | 646 |
| 653 // Collect the JavsScript stack height if the function frame_count is | 647 // Collect the JavsScript stack height if the function frame_count is |
| 654 // compiled. | 648 // compiled. |
| 655 if (!frame_count.IsEmpty()) { | 649 if (!frame_count.IsEmpty()) { |
| 656 static const int kArgc = 1; | 650 static const int kArgc = 1; |
| 657 v8::Handle<v8::Value> argv[kArgc] = { exec_state }; | 651 v8::Local<v8::Value> argv[kArgc] = {exec_state}; |
| 658 // Using exec_state as receiver is just to have a receiver. | 652 // Using exec_state as receiver is just to have a receiver. |
| 659 v8::Handle<v8::Value> result = frame_count->Call(exec_state, kArgc, argv); | 653 v8::Local<v8::Value> result = |
| 660 last_js_stack_height = result->Int32Value(); | 654 frame_count->Call(context, exec_state, kArgc, argv).ToLocalChecked(); |
| 655 last_js_stack_height = result->Int32Value(context).FromJust(); |
| 661 } | 656 } |
| 662 | 657 |
| 663 // Run callback from DebugEventListener and check the result. | 658 // Run callback from DebugEventListener and check the result. |
| 664 if (!debug_event_listener_callback.IsEmpty()) { | 659 if (!debug_event_listener_callback.IsEmpty()) { |
| 665 v8::Handle<v8::Value> result = | 660 v8::Local<v8::Value> result = |
| 666 debug_event_listener_callback->Call(event_data, 0, NULL); | 661 debug_event_listener_callback->Call(context, event_data, 0, NULL) |
| 662 .ToLocalChecked(); |
| 667 CHECK(!result.IsEmpty()); | 663 CHECK(!result.IsEmpty()); |
| 668 CHECK_EQ(debug_event_listener_callback_result, result->Int32Value()); | 664 CHECK_EQ(debug_event_listener_callback_result, |
| 665 result->Int32Value(context).FromJust()); |
| 669 } | 666 } |
| 670 } | 667 } |
| 671 | 668 |
| 672 | 669 |
| 673 // Debug event handler which evaluates a number of expressions when a break | 670 // Debug event handler which evaluates a number of expressions when a break |
| 674 // point is hit. Each evaluated expression is compared with an expected value. | 671 // point is hit. Each evaluated expression is compared with an expected value. |
| 675 // For this debug event handler to work the following two global varaibles | 672 // For this debug event handler to work the following two global varaibles |
| 676 // must be initialized. | 673 // must be initialized. |
| 677 // checks: An array of expressions and expected results | 674 // checks: An array of expressions and expected results |
| 678 // evaluate_check_function: A JavaScript function (see below) | 675 // evaluate_check_function: A JavaScript function (see below) |
| 679 | 676 |
| 680 // Structure for holding checks to do. | 677 // Structure for holding checks to do. |
| 681 struct EvaluateCheck { | 678 struct EvaluateCheck { |
| 682 const char* expr; // An expression to evaluate when a break point is hit. | 679 const char* expr; // An expression to evaluate when a break point is hit. |
| 683 v8::Handle<v8::Value> expected; // The expected result. | 680 v8::Local<v8::Value> expected; // The expected result. |
| 684 }; | 681 }; |
| 685 | 682 |
| 686 | 683 |
| 687 // Array of checks to do. | 684 // Array of checks to do. |
| 688 struct EvaluateCheck* checks = NULL; | 685 struct EvaluateCheck* checks = NULL; |
| 689 // Source for The JavaScript function which can do the evaluation when a break | 686 // Source for The JavaScript function which can do the evaluation when a break |
| 690 // point is hit. | 687 // point is hit. |
| 691 const char* evaluate_check_source = | 688 const char* evaluate_check_source = |
| 692 "function evaluate_check(exec_state, expr, expected) {" | 689 "function evaluate_check(exec_state, expr, expected) {" |
| 693 " return exec_state.frame(0).evaluate(expr).value() === expected;" | 690 " return exec_state.frame(0).evaluate(expr).value() === expected;" |
| 694 "}"; | 691 "}"; |
| 695 v8::Local<v8::Function> evaluate_check_function; | 692 v8::Local<v8::Function> evaluate_check_function; |
| 696 | 693 |
| 697 // The actual debug event described by the longer comment above. | 694 // The actual debug event described by the longer comment above. |
| 698 static void DebugEventEvaluate( | 695 static void DebugEventEvaluate( |
| 699 const v8::Debug::EventDetails& event_details) { | 696 const v8::Debug::EventDetails& event_details) { |
| 700 v8::DebugEvent event = event_details.GetEvent(); | 697 v8::DebugEvent event = event_details.GetEvent(); |
| 701 v8::Handle<v8::Object> exec_state = event_details.GetExecutionState(); | 698 v8::Local<v8::Object> exec_state = event_details.GetExecutionState(); |
| 699 v8::Isolate* isolate = CcTest::isolate(); |
| 700 v8::Local<v8::Context> context = isolate->GetCurrentContext(); |
| 702 v8::internal::Debug* debug = CcTest::i_isolate()->debug(); | 701 v8::internal::Debug* debug = CcTest::i_isolate()->debug(); |
| 703 // When hitting a debug event listener there must be a break set. | 702 // When hitting a debug event listener there must be a break set. |
| 704 CHECK_NE(debug->break_id(), 0); | 703 CHECK_NE(debug->break_id(), 0); |
| 705 | 704 |
| 706 if (event == v8::Break) { | 705 if (event == v8::Break) { |
| 707 break_point_hit_count++; | 706 break_point_hit_count++; |
| 708 for (int i = 0; checks[i].expr != NULL; i++) { | 707 for (int i = 0; checks[i].expr != NULL; i++) { |
| 709 const int argc = 3; | 708 const int argc = 3; |
| 710 v8::Handle<v8::Value> argv[argc] = { | 709 v8::Local<v8::String> string = v8_str(isolate, checks[i].expr); |
| 711 exec_state, | 710 v8::Local<v8::Value> argv[argc] = {exec_state, string, |
| 712 v8::String::NewFromUtf8(CcTest::isolate(), checks[i].expr), | 711 checks[i].expected}; |
| 713 checks[i].expected}; | 712 v8::Local<v8::Value> result = |
| 714 v8::Handle<v8::Value> result = | 713 evaluate_check_function->Call(context, exec_state, argc, argv) |
| 715 evaluate_check_function->Call(exec_state, argc, argv); | 714 .ToLocalChecked(); |
| 716 if (!result->IsTrue()) { | 715 if (!result->IsTrue()) { |
| 717 v8::String::Utf8Value utf8(checks[i].expected); | 716 v8::String::Utf8Value utf8(checks[i].expected); |
| 718 V8_Fatal(__FILE__, __LINE__, "%s != %s", checks[i].expr, *utf8); | 717 V8_Fatal(__FILE__, __LINE__, "%s != %s", checks[i].expr, *utf8); |
| 719 } | 718 } |
| 720 } | 719 } |
| 721 } | 720 } |
| 722 } | 721 } |
| 723 | 722 |
| 724 | 723 |
| 725 // This debug event listener removes a breakpoint in a function | 724 // This debug event listener removes a breakpoint in a function |
| 726 int debug_event_remove_break_point = 0; | 725 int debug_event_remove_break_point = 0; |
| 727 static void DebugEventRemoveBreakPoint( | 726 static void DebugEventRemoveBreakPoint( |
| 728 const v8::Debug::EventDetails& event_details) { | 727 const v8::Debug::EventDetails& event_details) { |
| 729 v8::DebugEvent event = event_details.GetEvent(); | 728 v8::DebugEvent event = event_details.GetEvent(); |
| 730 v8::Handle<v8::Value> data = event_details.GetCallbackData(); | 729 v8::Local<v8::Value> data = event_details.GetCallbackData(); |
| 731 v8::internal::Debug* debug = CcTest::i_isolate()->debug(); | 730 v8::internal::Debug* debug = CcTest::i_isolate()->debug(); |
| 732 // When hitting a debug event listener there must be a break set. | 731 // When hitting a debug event listener there must be a break set. |
| 733 CHECK_NE(debug->break_id(), 0); | 732 CHECK_NE(debug->break_id(), 0); |
| 734 | 733 |
| 735 if (event == v8::Break) { | 734 if (event == v8::Break) { |
| 736 break_point_hit_count++; | 735 break_point_hit_count++; |
| 737 CHECK(data->IsFunction()); | 736 CHECK(data->IsFunction()); |
| 738 ClearBreakPoint(debug_event_remove_break_point); | 737 ClearBreakPoint(debug_event_remove_break_point); |
| 739 } | 738 } |
| 740 } | 739 } |
| (...skipping 24 matching lines...) Expand all Loading... |
| 765 // frame_function_name: A JavaScript function (see below). | 764 // frame_function_name: A JavaScript function (see below). |
| 766 | 765 |
| 767 // String containing the expected function call sequence. Note: this only works | 766 // String containing the expected function call sequence. Note: this only works |
| 768 // if functions have name length of one. | 767 // if functions have name length of one. |
| 769 const char* expected_step_sequence = NULL; | 768 const char* expected_step_sequence = NULL; |
| 770 | 769 |
| 771 // The actual debug event described by the longer comment above. | 770 // The actual debug event described by the longer comment above. |
| 772 static void DebugEventStepSequence( | 771 static void DebugEventStepSequence( |
| 773 const v8::Debug::EventDetails& event_details) { | 772 const v8::Debug::EventDetails& event_details) { |
| 774 v8::DebugEvent event = event_details.GetEvent(); | 773 v8::DebugEvent event = event_details.GetEvent(); |
| 775 v8::Handle<v8::Object> exec_state = event_details.GetExecutionState(); | 774 v8::Local<v8::Object> exec_state = event_details.GetExecutionState(); |
| 776 v8::internal::Debug* debug = CcTest::i_isolate()->debug(); | 775 v8::internal::Debug* debug = CcTest::i_isolate()->debug(); |
| 777 // When hitting a debug event listener there must be a break set. | 776 // When hitting a debug event listener there must be a break set. |
| 778 CHECK_NE(debug->break_id(), 0); | 777 CHECK_NE(debug->break_id(), 0); |
| 779 | 778 |
| 780 if (event == v8::Break || event == v8::Exception) { | 779 if (event == v8::Break || event == v8::Exception) { |
| 781 // Check that the current function is the expected. | 780 // Check that the current function is the expected. |
| 782 CHECK(break_point_hit_count < | 781 CHECK(break_point_hit_count < |
| 783 StrLength(expected_step_sequence)); | 782 StrLength(expected_step_sequence)); |
| 784 const int argc = 2; | 783 const int argc = 2; |
| 785 v8::Handle<v8::Value> argv[argc] = { | 784 v8::Local<v8::Value> argv[argc] = {exec_state, |
| 786 exec_state, v8::Integer::New(CcTest::isolate(), 0) | 785 v8::Integer::New(CcTest::isolate(), 0)}; |
| 787 }; | 786 v8::Local<v8::Context> context = CcTest::isolate()->GetCurrentContext(); |
| 788 v8::Handle<v8::Value> result = frame_function_name->Call(exec_state, | 787 v8::Local<v8::Value> result = |
| 789 argc, argv); | 788 frame_function_name->Call(context, exec_state, argc, argv) |
| 789 .ToLocalChecked(); |
| 790 CHECK(result->IsString()); | 790 CHECK(result->IsString()); |
| 791 v8::String::Utf8Value function_name(result->ToString(CcTest::isolate())); | 791 v8::String::Utf8Value function_name( |
| 792 result->ToString(context).ToLocalChecked()); |
| 792 CHECK_EQ(1, StrLength(*function_name)); | 793 CHECK_EQ(1, StrLength(*function_name)); |
| 793 CHECK_EQ((*function_name)[0], | 794 CHECK_EQ((*function_name)[0], |
| 794 expected_step_sequence[break_point_hit_count]); | 795 expected_step_sequence[break_point_hit_count]); |
| 795 | 796 |
| 796 // Perform step. | 797 // Perform step. |
| 797 break_point_hit_count++; | 798 break_point_hit_count++; |
| 798 PrepareStep(step_action); | 799 PrepareStep(step_action); |
| 799 } | 800 } |
| 800 } | 801 } |
| 801 | 802 |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 863 if (event == v8::Break) { | 864 if (event == v8::Break) { |
| 864 if (break_point_hit_count < max_break_point_hit_count) { | 865 if (break_point_hit_count < max_break_point_hit_count) { |
| 865 // Count the number of breaks. | 866 // Count the number of breaks. |
| 866 break_point_hit_count++; | 867 break_point_hit_count++; |
| 867 | 868 |
| 868 // Set the break flag again to come back here as soon as possible. | 869 // Set the break flag again to come back here as soon as possible. |
| 869 v8::Debug::DebugBreak(v8_isolate); | 870 v8::Debug::DebugBreak(v8_isolate); |
| 870 | 871 |
| 871 } else if (terminate_after_max_break_point_hit) { | 872 } else if (terminate_after_max_break_point_hit) { |
| 872 // Terminate execution after the last break if requested. | 873 // Terminate execution after the last break if requested. |
| 873 v8::V8::TerminateExecution(v8_isolate); | 874 v8_isolate->TerminateExecution(); |
| 874 } | 875 } |
| 875 | 876 |
| 876 // Perform a full deoptimization when the specified number of | 877 // Perform a full deoptimization when the specified number of |
| 877 // breaks have been hit. | 878 // breaks have been hit. |
| 878 if (break_point_hit_count == break_point_hit_count_deoptimize) { | 879 if (break_point_hit_count == break_point_hit_count_deoptimize) { |
| 879 i::Deoptimizer::DeoptimizeAll(isolate); | 880 i::Deoptimizer::DeoptimizeAll(isolate); |
| 880 } | 881 } |
| 881 } | 882 } |
| 882 } | 883 } |
| 883 | 884 |
| 884 | 885 |
| 885 // --- M e s s a g e C a l l b a c k | 886 // --- M e s s a g e C a l l b a c k |
| 886 | 887 |
| 887 | 888 |
| 888 // Message callback which counts the number of messages. | 889 // Message callback which counts the number of messages. |
| 889 int message_callback_count = 0; | 890 int message_callback_count = 0; |
| 890 | 891 |
| 891 static void MessageCallbackCountClear() { | 892 static void MessageCallbackCountClear() { |
| 892 message_callback_count = 0; | 893 message_callback_count = 0; |
| 893 } | 894 } |
| 894 | 895 |
| 895 static void MessageCallbackCount(v8::Handle<v8::Message> message, | 896 static void MessageCallbackCount(v8::Local<v8::Message> message, |
| 896 v8::Handle<v8::Value> data) { | 897 v8::Local<v8::Value> data) { |
| 897 message_callback_count++; | 898 message_callback_count++; |
| 898 } | 899 } |
| 899 | 900 |
| 900 | 901 |
| 901 // --- T h e A c t u a l T e s t s | 902 // --- T h e A c t u a l T e s t s |
| 902 | 903 |
| 903 // Test that the debug info in the VM is in sync with the functions being | 904 // Test that the debug info in the VM is in sync with the functions being |
| 904 // debugged. | 905 // debugged. |
| 905 TEST(DebugInfo) { | 906 TEST(DebugInfo) { |
| 906 DebugLocalContext env; | 907 DebugLocalContext env; |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 939 } | 940 } |
| 940 | 941 |
| 941 | 942 |
| 942 // Test that a break point can be set at an IC store location. | 943 // Test that a break point can be set at an IC store location. |
| 943 TEST(BreakPointICStore) { | 944 TEST(BreakPointICStore) { |
| 944 break_point_hit_count = 0; | 945 break_point_hit_count = 0; |
| 945 DebugLocalContext env; | 946 DebugLocalContext env; |
| 946 v8::HandleScope scope(env->GetIsolate()); | 947 v8::HandleScope scope(env->GetIsolate()); |
| 947 | 948 |
| 948 v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); | 949 v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); |
| 949 v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), | 950 v8::Local<v8::Function> foo = |
| 950 "function foo(){bar=0;}"))->Run(); | 951 CompileFunction(&env, "function foo(){bar=0;}", "foo"); |
| 951 v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast( | |
| 952 env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "foo"))); | |
| 953 | 952 |
| 954 // Run without breakpoints. | 953 // Run without breakpoints. |
| 955 foo->Call(env->Global(), 0, NULL); | 954 foo->Call(env.context(), env->Global(), 0, NULL).ToLocalChecked(); |
| 956 CHECK_EQ(0, break_point_hit_count); | 955 CHECK_EQ(0, break_point_hit_count); |
| 957 | 956 |
| 958 // Run with breakpoint | 957 // Run with breakpoint |
| 959 int bp = SetBreakPoint(foo, 0); | 958 int bp = SetBreakPoint(foo, 0); |
| 960 foo->Call(env->Global(), 0, NULL); | 959 foo->Call(env.context(), env->Global(), 0, NULL).ToLocalChecked(); |
| 961 CHECK_EQ(1, break_point_hit_count); | 960 CHECK_EQ(1, break_point_hit_count); |
| 962 foo->Call(env->Global(), 0, NULL); | 961 foo->Call(env.context(), env->Global(), 0, NULL).ToLocalChecked(); |
| 963 CHECK_EQ(2, break_point_hit_count); | 962 CHECK_EQ(2, break_point_hit_count); |
| 964 | 963 |
| 965 // Run without breakpoints. | 964 // Run without breakpoints. |
| 966 ClearBreakPoint(bp); | 965 ClearBreakPoint(bp); |
| 967 foo->Call(env->Global(), 0, NULL); | 966 foo->Call(env.context(), env->Global(), 0, NULL).ToLocalChecked(); |
| 968 CHECK_EQ(2, break_point_hit_count); | 967 CHECK_EQ(2, break_point_hit_count); |
| 969 | 968 |
| 970 v8::Debug::SetDebugEventListener(NULL); | 969 v8::Debug::SetDebugEventListener(NULL); |
| 971 CheckDebuggerUnloaded(); | 970 CheckDebuggerUnloaded(); |
| 972 } | 971 } |
| 973 | 972 |
| 974 | 973 |
| 975 // Test that a break point can be set at an IC load location. | 974 // Test that a break point can be set at an IC load location. |
| 976 TEST(BreakPointICLoad) { | 975 TEST(BreakPointICLoad) { |
| 977 break_point_hit_count = 0; | 976 break_point_hit_count = 0; |
| 978 DebugLocalContext env; | 977 DebugLocalContext env; |
| 979 v8::HandleScope scope(env->GetIsolate()); | 978 v8::HandleScope scope(env->GetIsolate()); |
| 980 v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); | 979 v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); |
| 981 v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), "bar=1")) | 980 |
| 982 ->Run(); | 981 CompileRunChecked(env->GetIsolate(), "bar=1"); |
| 983 v8::Script::Compile( | 982 v8::Local<v8::Function> foo = |
| 984 v8::String::NewFromUtf8(env->GetIsolate(), "function foo(){var x=bar;}")) | 983 CompileFunction(&env, "function foo(){var x=bar;}", "foo"); |
| 985 ->Run(); | |
| 986 v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast( | |
| 987 env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "foo"))); | |
| 988 | 984 |
| 989 // Run without breakpoints. | 985 // Run without breakpoints. |
| 990 foo->Call(env->Global(), 0, NULL); | 986 foo->Call(env.context(), env->Global(), 0, NULL).ToLocalChecked(); |
| 991 CHECK_EQ(0, break_point_hit_count); | 987 CHECK_EQ(0, break_point_hit_count); |
| 992 | 988 |
| 993 // Run with breakpoint. | 989 // Run with breakpoint. |
| 994 int bp = SetBreakPoint(foo, 0); | 990 int bp = SetBreakPoint(foo, 0); |
| 995 foo->Call(env->Global(), 0, NULL); | 991 foo->Call(env.context(), env->Global(), 0, NULL).ToLocalChecked(); |
| 996 CHECK_EQ(1, break_point_hit_count); | 992 CHECK_EQ(1, break_point_hit_count); |
| 997 foo->Call(env->Global(), 0, NULL); | 993 foo->Call(env.context(), env->Global(), 0, NULL).ToLocalChecked(); |
| 998 CHECK_EQ(2, break_point_hit_count); | 994 CHECK_EQ(2, break_point_hit_count); |
| 999 | 995 |
| 1000 // Run without breakpoints. | 996 // Run without breakpoints. |
| 1001 ClearBreakPoint(bp); | 997 ClearBreakPoint(bp); |
| 1002 foo->Call(env->Global(), 0, NULL); | 998 foo->Call(env.context(), env->Global(), 0, NULL).ToLocalChecked(); |
| 1003 CHECK_EQ(2, break_point_hit_count); | 999 CHECK_EQ(2, break_point_hit_count); |
| 1004 | 1000 |
| 1005 v8::Debug::SetDebugEventListener(NULL); | 1001 v8::Debug::SetDebugEventListener(NULL); |
| 1006 CheckDebuggerUnloaded(); | 1002 CheckDebuggerUnloaded(); |
| 1007 } | 1003 } |
| 1008 | 1004 |
| 1009 | 1005 |
| 1010 // Test that a break point can be set at an IC call location. | 1006 // Test that a break point can be set at an IC call location. |
| 1011 TEST(BreakPointICCall) { | 1007 TEST(BreakPointICCall) { |
| 1012 break_point_hit_count = 0; | 1008 break_point_hit_count = 0; |
| 1013 DebugLocalContext env; | 1009 DebugLocalContext env; |
| 1014 v8::HandleScope scope(env->GetIsolate()); | 1010 v8::HandleScope scope(env->GetIsolate()); |
| 1015 v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); | 1011 v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); |
| 1016 v8::Script::Compile( | 1012 CompileRunChecked(env->GetIsolate(), "function bar(){}"); |
| 1017 v8::String::NewFromUtf8(env->GetIsolate(), "function bar(){}"))->Run(); | 1013 v8::Local<v8::Function> foo = |
| 1018 v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), | 1014 CompileFunction(&env, "function foo(){bar();}", "foo"); |
| 1019 "function foo(){bar();}"))->Run(); | |
| 1020 v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast( | |
| 1021 env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "foo"))); | |
| 1022 | 1015 |
| 1023 // Run without breakpoints. | 1016 // Run without breakpoints. |
| 1024 foo->Call(env->Global(), 0, NULL); | 1017 foo->Call(env.context(), env->Global(), 0, NULL).ToLocalChecked(); |
| 1025 CHECK_EQ(0, break_point_hit_count); | 1018 CHECK_EQ(0, break_point_hit_count); |
| 1026 | 1019 |
| 1027 // Run with breakpoint | 1020 // Run with breakpoint |
| 1028 int bp = SetBreakPoint(foo, 0); | 1021 int bp = SetBreakPoint(foo, 0); |
| 1029 foo->Call(env->Global(), 0, NULL); | 1022 foo->Call(env.context(), env->Global(), 0, NULL).ToLocalChecked(); |
| 1030 CHECK_EQ(1, break_point_hit_count); | 1023 CHECK_EQ(1, break_point_hit_count); |
| 1031 foo->Call(env->Global(), 0, NULL); | 1024 foo->Call(env.context(), env->Global(), 0, NULL).ToLocalChecked(); |
| 1032 CHECK_EQ(2, break_point_hit_count); | 1025 CHECK_EQ(2, break_point_hit_count); |
| 1033 | 1026 |
| 1034 // Run without breakpoints. | 1027 // Run without breakpoints. |
| 1035 ClearBreakPoint(bp); | 1028 ClearBreakPoint(bp); |
| 1036 foo->Call(env->Global(), 0, NULL); | 1029 foo->Call(env.context(), env->Global(), 0, NULL).ToLocalChecked(); |
| 1037 CHECK_EQ(2, break_point_hit_count); | 1030 CHECK_EQ(2, break_point_hit_count); |
| 1038 | 1031 |
| 1039 v8::Debug::SetDebugEventListener(NULL); | 1032 v8::Debug::SetDebugEventListener(NULL); |
| 1040 CheckDebuggerUnloaded(); | 1033 CheckDebuggerUnloaded(); |
| 1041 } | 1034 } |
| 1042 | 1035 |
| 1043 | 1036 |
| 1044 // Test that a break point can be set at an IC call location and survive a GC. | 1037 // Test that a break point can be set at an IC call location and survive a GC. |
| 1045 TEST(BreakPointICCallWithGC) { | 1038 TEST(BreakPointICCallWithGC) { |
| 1046 break_point_hit_count = 0; | 1039 break_point_hit_count = 0; |
| 1047 DebugLocalContext env; | 1040 DebugLocalContext env; |
| 1048 v8::HandleScope scope(env->GetIsolate()); | 1041 v8::HandleScope scope(env->GetIsolate()); |
| 1049 v8::Debug::SetDebugEventListener(DebugEventBreakPointCollectGarbage); | 1042 v8::Debug::SetDebugEventListener(DebugEventBreakPointCollectGarbage); |
| 1050 v8::Script::Compile( | 1043 CompileRunChecked(env->GetIsolate(), "function bar(){return 1;}"); |
| 1051 v8::String::NewFromUtf8(env->GetIsolate(), "function bar(){return 1;}")) | 1044 v8::Local<v8::Function> foo = |
| 1052 ->Run(); | 1045 CompileFunction(&env, "function foo(){return bar();}", "foo"); |
| 1053 v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), | 1046 v8::Local<v8::Context> context = env.context(); |
| 1054 "function foo(){return bar();}")) | |
| 1055 ->Run(); | |
| 1056 v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast( | |
| 1057 env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "foo"))); | |
| 1058 | 1047 |
| 1059 // Run without breakpoints. | 1048 // Run without breakpoints. |
| 1060 CHECK_EQ(1, foo->Call(env->Global(), 0, NULL)->Int32Value()); | 1049 CHECK_EQ(1, foo->Call(context, env->Global(), 0, NULL) |
| 1050 .ToLocalChecked() |
| 1051 ->Int32Value(context) |
| 1052 .FromJust()); |
| 1061 CHECK_EQ(0, break_point_hit_count); | 1053 CHECK_EQ(0, break_point_hit_count); |
| 1062 | 1054 |
| 1063 // Run with breakpoint. | 1055 // Run with breakpoint. |
| 1064 int bp = SetBreakPoint(foo, 0); | 1056 int bp = SetBreakPoint(foo, 0); |
| 1065 CHECK_EQ(1, foo->Call(env->Global(), 0, NULL)->Int32Value()); | 1057 CHECK_EQ(1, foo->Call(context, env->Global(), 0, NULL) |
| 1058 .ToLocalChecked() |
| 1059 ->Int32Value(context) |
| 1060 .FromJust()); |
| 1066 CHECK_EQ(1, break_point_hit_count); | 1061 CHECK_EQ(1, break_point_hit_count); |
| 1067 CHECK_EQ(1, foo->Call(env->Global(), 0, NULL)->Int32Value()); | 1062 CHECK_EQ(1, foo->Call(context, env->Global(), 0, NULL) |
| 1063 .ToLocalChecked() |
| 1064 ->Int32Value(context) |
| 1065 .FromJust()); |
| 1068 CHECK_EQ(2, break_point_hit_count); | 1066 CHECK_EQ(2, break_point_hit_count); |
| 1069 | 1067 |
| 1070 // Run without breakpoints. | 1068 // Run without breakpoints. |
| 1071 ClearBreakPoint(bp); | 1069 ClearBreakPoint(bp); |
| 1072 foo->Call(env->Global(), 0, NULL); | 1070 foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 1073 CHECK_EQ(2, break_point_hit_count); | 1071 CHECK_EQ(2, break_point_hit_count); |
| 1074 | 1072 |
| 1075 v8::Debug::SetDebugEventListener(NULL); | 1073 v8::Debug::SetDebugEventListener(NULL); |
| 1076 CheckDebuggerUnloaded(); | 1074 CheckDebuggerUnloaded(); |
| 1077 } | 1075 } |
| 1078 | 1076 |
| 1079 | 1077 |
| 1080 // Test that a break point can be set at an IC call location and survive a GC. | 1078 // Test that a break point can be set at an IC call location and survive a GC. |
| 1081 TEST(BreakPointConstructCallWithGC) { | 1079 TEST(BreakPointConstructCallWithGC) { |
| 1082 break_point_hit_count = 0; | 1080 break_point_hit_count = 0; |
| 1083 DebugLocalContext env; | 1081 DebugLocalContext env; |
| 1084 v8::HandleScope scope(env->GetIsolate()); | 1082 v8::HandleScope scope(env->GetIsolate()); |
| 1085 v8::Debug::SetDebugEventListener(DebugEventBreakPointCollectGarbage); | 1083 v8::Debug::SetDebugEventListener(DebugEventBreakPointCollectGarbage); |
| 1086 v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), | 1084 CompileRunChecked(env->GetIsolate(), "function bar(){ this.x = 1;}"); |
| 1087 "function bar(){ this.x = 1;}")) | 1085 v8::Local<v8::Function> foo = |
| 1088 ->Run(); | 1086 CompileFunction(&env, "function foo(){return new bar(1).x;}", "foo"); |
| 1089 v8::Script::Compile( | 1087 v8::Local<v8::Context> context = env.context(); |
| 1090 v8::String::NewFromUtf8(env->GetIsolate(), | |
| 1091 "function foo(){return new bar(1).x;}"))->Run(); | |
| 1092 v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast( | |
| 1093 env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "foo"))); | |
| 1094 | 1088 |
| 1095 // Run without breakpoints. | 1089 // Run without breakpoints. |
| 1096 CHECK_EQ(1, foo->Call(env->Global(), 0, NULL)->Int32Value()); | 1090 CHECK_EQ(1, foo->Call(context, env->Global(), 0, NULL) |
| 1091 .ToLocalChecked() |
| 1092 ->Int32Value(context) |
| 1093 .FromJust()); |
| 1097 CHECK_EQ(0, break_point_hit_count); | 1094 CHECK_EQ(0, break_point_hit_count); |
| 1098 | 1095 |
| 1099 // Run with breakpoint. | 1096 // Run with breakpoint. |
| 1100 int bp = SetBreakPoint(foo, 0); | 1097 int bp = SetBreakPoint(foo, 0); |
| 1101 CHECK_EQ(1, foo->Call(env->Global(), 0, NULL)->Int32Value()); | 1098 CHECK_EQ(1, foo->Call(context, env->Global(), 0, NULL) |
| 1099 .ToLocalChecked() |
| 1100 ->Int32Value(context) |
| 1101 .FromJust()); |
| 1102 CHECK_EQ(1, break_point_hit_count); | 1102 CHECK_EQ(1, break_point_hit_count); |
| 1103 CHECK_EQ(1, foo->Call(env->Global(), 0, NULL)->Int32Value()); | 1103 CHECK_EQ(1, foo->Call(context, env->Global(), 0, NULL) |
| 1104 .ToLocalChecked() |
| 1105 ->Int32Value(context) |
| 1106 .FromJust()); |
| 1104 CHECK_EQ(2, break_point_hit_count); | 1107 CHECK_EQ(2, break_point_hit_count); |
| 1105 | 1108 |
| 1106 // Run without breakpoints. | 1109 // Run without breakpoints. |
| 1107 ClearBreakPoint(bp); | 1110 ClearBreakPoint(bp); |
| 1108 foo->Call(env->Global(), 0, NULL); | 1111 foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 1109 CHECK_EQ(2, break_point_hit_count); | 1112 CHECK_EQ(2, break_point_hit_count); |
| 1110 | 1113 |
| 1111 v8::Debug::SetDebugEventListener(NULL); | 1114 v8::Debug::SetDebugEventListener(NULL); |
| 1112 CheckDebuggerUnloaded(); | 1115 CheckDebuggerUnloaded(); |
| 1113 } | 1116 } |
| 1114 | 1117 |
| 1115 | 1118 |
| 1116 // Test that a break point can be set at a return store location. | 1119 // Test that a break point can be set at a return store location. |
| 1117 TEST(BreakPointReturn) { | 1120 TEST(BreakPointReturn) { |
| 1118 break_point_hit_count = 0; | 1121 break_point_hit_count = 0; |
| 1119 DebugLocalContext env; | 1122 DebugLocalContext env; |
| 1120 v8::HandleScope scope(env->GetIsolate()); | 1123 v8::HandleScope scope(env->GetIsolate()); |
| 1121 | 1124 |
| 1122 // Create a functions for checking the source line and column when hitting | 1125 // Create a functions for checking the source line and column when hitting |
| 1123 // a break point. | 1126 // a break point. |
| 1124 frame_source_line = CompileFunction(&env, | 1127 frame_source_line = CompileFunction(&env, |
| 1125 frame_source_line_source, | 1128 frame_source_line_source, |
| 1126 "frame_source_line"); | 1129 "frame_source_line"); |
| 1127 frame_source_column = CompileFunction(&env, | 1130 frame_source_column = CompileFunction(&env, |
| 1128 frame_source_column_source, | 1131 frame_source_column_source, |
| 1129 "frame_source_column"); | 1132 "frame_source_column"); |
| 1130 | 1133 |
| 1131 | 1134 |
| 1132 v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); | 1135 v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); |
| 1133 v8::Script::Compile( | 1136 v8::Local<v8::Function> foo = |
| 1134 v8::String::NewFromUtf8(env->GetIsolate(), "function foo(){}"))->Run(); | 1137 CompileFunction(&env, "function foo(){}", "foo"); |
| 1135 v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast( | 1138 v8::Local<v8::Context> context = env.context(); |
| 1136 env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "foo"))); | |
| 1137 | 1139 |
| 1138 // Run without breakpoints. | 1140 // Run without breakpoints. |
| 1139 foo->Call(env->Global(), 0, NULL); | 1141 foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 1140 CHECK_EQ(0, break_point_hit_count); | 1142 CHECK_EQ(0, break_point_hit_count); |
| 1141 | 1143 |
| 1142 // Run with breakpoint | 1144 // Run with breakpoint |
| 1143 int bp = SetBreakPoint(foo, 0); | 1145 int bp = SetBreakPoint(foo, 0); |
| 1144 foo->Call(env->Global(), 0, NULL); | 1146 foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 1145 CHECK_EQ(1, break_point_hit_count); | 1147 CHECK_EQ(1, break_point_hit_count); |
| 1146 CHECK_EQ(0, last_source_line); | 1148 CHECK_EQ(0, last_source_line); |
| 1147 CHECK_EQ(15, last_source_column); | 1149 CHECK_EQ(15, last_source_column); |
| 1148 foo->Call(env->Global(), 0, NULL); | 1150 foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 1149 CHECK_EQ(2, break_point_hit_count); | 1151 CHECK_EQ(2, break_point_hit_count); |
| 1150 CHECK_EQ(0, last_source_line); | 1152 CHECK_EQ(0, last_source_line); |
| 1151 CHECK_EQ(15, last_source_column); | 1153 CHECK_EQ(15, last_source_column); |
| 1152 | 1154 |
| 1153 // Run without breakpoints. | 1155 // Run without breakpoints. |
| 1154 ClearBreakPoint(bp); | 1156 ClearBreakPoint(bp); |
| 1155 foo->Call(env->Global(), 0, NULL); | 1157 foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 1156 CHECK_EQ(2, break_point_hit_count); | 1158 CHECK_EQ(2, break_point_hit_count); |
| 1157 | 1159 |
| 1158 v8::Debug::SetDebugEventListener(NULL); | 1160 v8::Debug::SetDebugEventListener(NULL); |
| 1159 CheckDebuggerUnloaded(); | 1161 CheckDebuggerUnloaded(); |
| 1160 } | 1162 } |
| 1161 | 1163 |
| 1162 | 1164 |
| 1163 static void CallWithBreakPoints(v8::Local<v8::Object> recv, | 1165 static void CallWithBreakPoints(v8::Local<v8::Context> context, |
| 1166 v8::Local<v8::Object> recv, |
| 1164 v8::Local<v8::Function> f, | 1167 v8::Local<v8::Function> f, |
| 1165 int break_point_count, | 1168 int break_point_count, int call_count) { |
| 1166 int call_count) { | |
| 1167 break_point_hit_count = 0; | 1169 break_point_hit_count = 0; |
| 1168 for (int i = 0; i < call_count; i++) { | 1170 for (int i = 0; i < call_count; i++) { |
| 1169 f->Call(recv, 0, NULL); | 1171 f->Call(context, recv, 0, NULL).ToLocalChecked(); |
| 1170 CHECK_EQ((i + 1) * break_point_count, break_point_hit_count); | 1172 CHECK_EQ((i + 1) * break_point_count, break_point_hit_count); |
| 1171 } | 1173 } |
| 1172 } | 1174 } |
| 1173 | 1175 |
| 1174 | 1176 |
| 1175 // Test GC during break point processing. | 1177 // Test GC during break point processing. |
| 1176 TEST(GCDuringBreakPointProcessing) { | 1178 TEST(GCDuringBreakPointProcessing) { |
| 1177 break_point_hit_count = 0; | 1179 break_point_hit_count = 0; |
| 1178 DebugLocalContext env; | 1180 DebugLocalContext env; |
| 1179 v8::HandleScope scope(env->GetIsolate()); | 1181 v8::HandleScope scope(env->GetIsolate()); |
| 1182 v8::Local<v8::Context> context = env.context(); |
| 1180 | 1183 |
| 1181 v8::Debug::SetDebugEventListener(DebugEventBreakPointCollectGarbage); | 1184 v8::Debug::SetDebugEventListener(DebugEventBreakPointCollectGarbage); |
| 1182 v8::Local<v8::Function> foo; | 1185 v8::Local<v8::Function> foo; |
| 1183 | 1186 |
| 1184 // Test IC store break point with garbage collection. | 1187 // Test IC store break point with garbage collection. |
| 1185 foo = CompileFunction(&env, "function foo(){bar=0;}", "foo"); | 1188 foo = CompileFunction(&env, "function foo(){bar=0;}", "foo"); |
| 1186 SetBreakPoint(foo, 0); | 1189 SetBreakPoint(foo, 0); |
| 1187 CallWithBreakPoints(env->Global(), foo, 1, 10); | 1190 CallWithBreakPoints(context, env->Global(), foo, 1, 10); |
| 1188 | 1191 |
| 1189 // Test IC load break point with garbage collection. | 1192 // Test IC load break point with garbage collection. |
| 1190 foo = CompileFunction(&env, "bar=1;function foo(){var x=bar;}", "foo"); | 1193 foo = CompileFunction(&env, "bar=1;function foo(){var x=bar;}", "foo"); |
| 1191 SetBreakPoint(foo, 0); | 1194 SetBreakPoint(foo, 0); |
| 1192 CallWithBreakPoints(env->Global(), foo, 1, 10); | 1195 CallWithBreakPoints(context, env->Global(), foo, 1, 10); |
| 1193 | 1196 |
| 1194 // Test IC call break point with garbage collection. | 1197 // Test IC call break point with garbage collection. |
| 1195 foo = CompileFunction(&env, "function bar(){};function foo(){bar();}", "foo"); | 1198 foo = CompileFunction(&env, "function bar(){};function foo(){bar();}", "foo"); |
| 1196 SetBreakPoint(foo, 0); | 1199 SetBreakPoint(foo, 0); |
| 1197 CallWithBreakPoints(env->Global(), foo, 1, 10); | 1200 CallWithBreakPoints(context, env->Global(), foo, 1, 10); |
| 1198 | 1201 |
| 1199 // Test return break point with garbage collection. | 1202 // Test return break point with garbage collection. |
| 1200 foo = CompileFunction(&env, "function foo(){}", "foo"); | 1203 foo = CompileFunction(&env, "function foo(){}", "foo"); |
| 1201 SetBreakPoint(foo, 0); | 1204 SetBreakPoint(foo, 0); |
| 1202 CallWithBreakPoints(env->Global(), foo, 1, 25); | 1205 CallWithBreakPoints(context, env->Global(), foo, 1, 25); |
| 1203 | 1206 |
| 1204 // Test debug break slot break point with garbage collection. | 1207 // Test debug break slot break point with garbage collection. |
| 1205 foo = CompileFunction(&env, "function foo(){var a;}", "foo"); | 1208 foo = CompileFunction(&env, "function foo(){var a;}", "foo"); |
| 1206 SetBreakPoint(foo, 0); | 1209 SetBreakPoint(foo, 0); |
| 1207 CallWithBreakPoints(env->Global(), foo, 1, 25); | 1210 CallWithBreakPoints(context, env->Global(), foo, 1, 25); |
| 1208 | 1211 |
| 1209 v8::Debug::SetDebugEventListener(NULL); | 1212 v8::Debug::SetDebugEventListener(NULL); |
| 1210 CheckDebuggerUnloaded(); | 1213 CheckDebuggerUnloaded(); |
| 1211 } | 1214 } |
| 1212 | 1215 |
| 1213 | 1216 |
| 1214 // Call the function three times with different garbage collections in between | 1217 // Call the function three times with different garbage collections in between |
| 1215 // and make sure that the break point survives. | 1218 // and make sure that the break point survives. |
| 1216 static void CallAndGC(v8::Local<v8::Object> recv, | 1219 static void CallAndGC(v8::Local<v8::Context> context, |
| 1217 v8::Local<v8::Function> f) { | 1220 v8::Local<v8::Object> recv, v8::Local<v8::Function> f) { |
| 1218 break_point_hit_count = 0; | 1221 break_point_hit_count = 0; |
| 1219 | 1222 |
| 1220 for (int i = 0; i < 3; i++) { | 1223 for (int i = 0; i < 3; i++) { |
| 1221 // Call function. | 1224 // Call function. |
| 1222 f->Call(recv, 0, NULL); | 1225 f->Call(context, recv, 0, NULL).ToLocalChecked(); |
| 1223 CHECK_EQ(1 + i * 3, break_point_hit_count); | 1226 CHECK_EQ(1 + i * 3, break_point_hit_count); |
| 1224 | 1227 |
| 1225 // Scavenge and call function. | 1228 // Scavenge and call function. |
| 1226 CcTest::heap()->CollectGarbage(v8::internal::NEW_SPACE); | 1229 CcTest::heap()->CollectGarbage(v8::internal::NEW_SPACE); |
| 1227 f->Call(recv, 0, NULL); | 1230 f->Call(context, recv, 0, NULL).ToLocalChecked(); |
| 1228 CHECK_EQ(2 + i * 3, break_point_hit_count); | 1231 CHECK_EQ(2 + i * 3, break_point_hit_count); |
| 1229 | 1232 |
| 1230 // Mark sweep (and perhaps compact) and call function. | 1233 // Mark sweep (and perhaps compact) and call function. |
| 1231 CcTest::heap()->CollectAllGarbage(); | 1234 CcTest::heap()->CollectAllGarbage(); |
| 1232 f->Call(recv, 0, NULL); | 1235 f->Call(context, recv, 0, NULL).ToLocalChecked(); |
| 1233 CHECK_EQ(3 + i * 3, break_point_hit_count); | 1236 CHECK_EQ(3 + i * 3, break_point_hit_count); |
| 1234 } | 1237 } |
| 1235 } | 1238 } |
| 1236 | 1239 |
| 1237 | 1240 |
| 1238 // Test that a break point can be set at a return store location. | 1241 // Test that a break point can be set at a return store location. |
| 1239 TEST(BreakPointSurviveGC) { | 1242 TEST(BreakPointSurviveGC) { |
| 1240 break_point_hit_count = 0; | 1243 break_point_hit_count = 0; |
| 1241 DebugLocalContext env; | 1244 DebugLocalContext env; |
| 1242 v8::HandleScope scope(env->GetIsolate()); | 1245 v8::HandleScope scope(env->GetIsolate()); |
| 1246 v8::Local<v8::Context> context = env.context(); |
| 1243 | 1247 |
| 1244 v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); | 1248 v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); |
| 1245 v8::Local<v8::Function> foo; | 1249 v8::Local<v8::Function> foo; |
| 1246 | 1250 |
| 1247 // Test IC store break point with garbage collection. | 1251 // Test IC store break point with garbage collection. |
| 1248 { | 1252 { |
| 1249 CompileFunction(&env, "function foo(){}", "foo"); | 1253 CompileFunction(&env, "function foo(){}", "foo"); |
| 1250 foo = CompileFunction(&env, "function foo(){bar=0;}", "foo"); | 1254 foo = CompileFunction(&env, "function foo(){bar=0;}", "foo"); |
| 1251 SetBreakPoint(foo, 0); | 1255 SetBreakPoint(foo, 0); |
| 1252 } | 1256 } |
| 1253 CallAndGC(env->Global(), foo); | 1257 CallAndGC(context, env->Global(), foo); |
| 1254 | 1258 |
| 1255 // Test IC load break point with garbage collection. | 1259 // Test IC load break point with garbage collection. |
| 1256 { | 1260 { |
| 1257 CompileFunction(&env, "function foo(){}", "foo"); | 1261 CompileFunction(&env, "function foo(){}", "foo"); |
| 1258 foo = CompileFunction(&env, "bar=1;function foo(){var x=bar;}", "foo"); | 1262 foo = CompileFunction(&env, "bar=1;function foo(){var x=bar;}", "foo"); |
| 1259 SetBreakPoint(foo, 0); | 1263 SetBreakPoint(foo, 0); |
| 1260 } | 1264 } |
| 1261 CallAndGC(env->Global(), foo); | 1265 CallAndGC(context, env->Global(), foo); |
| 1262 | 1266 |
| 1263 // Test IC call break point with garbage collection. | 1267 // Test IC call break point with garbage collection. |
| 1264 { | 1268 { |
| 1265 CompileFunction(&env, "function foo(){}", "foo"); | 1269 CompileFunction(&env, "function foo(){}", "foo"); |
| 1266 foo = CompileFunction(&env, | 1270 foo = CompileFunction(&env, |
| 1267 "function bar(){};function foo(){bar();}", | 1271 "function bar(){};function foo(){bar();}", |
| 1268 "foo"); | 1272 "foo"); |
| 1269 SetBreakPoint(foo, 0); | 1273 SetBreakPoint(foo, 0); |
| 1270 } | 1274 } |
| 1271 CallAndGC(env->Global(), foo); | 1275 CallAndGC(context, env->Global(), foo); |
| 1272 | 1276 |
| 1273 // Test return break point with garbage collection. | 1277 // Test return break point with garbage collection. |
| 1274 { | 1278 { |
| 1275 CompileFunction(&env, "function foo(){}", "foo"); | 1279 CompileFunction(&env, "function foo(){}", "foo"); |
| 1276 foo = CompileFunction(&env, "function foo(){}", "foo"); | 1280 foo = CompileFunction(&env, "function foo(){}", "foo"); |
| 1277 SetBreakPoint(foo, 0); | 1281 SetBreakPoint(foo, 0); |
| 1278 } | 1282 } |
| 1279 CallAndGC(env->Global(), foo); | 1283 CallAndGC(context, env->Global(), foo); |
| 1280 | 1284 |
| 1281 // Test non IC break point with garbage collection. | 1285 // Test non IC break point with garbage collection. |
| 1282 { | 1286 { |
| 1283 CompileFunction(&env, "function foo(){}", "foo"); | 1287 CompileFunction(&env, "function foo(){}", "foo"); |
| 1284 foo = CompileFunction(&env, "function foo(){var bar=0;}", "foo"); | 1288 foo = CompileFunction(&env, "function foo(){var bar=0;}", "foo"); |
| 1285 SetBreakPoint(foo, 0); | 1289 SetBreakPoint(foo, 0); |
| 1286 } | 1290 } |
| 1287 CallAndGC(env->Global(), foo); | 1291 CallAndGC(context, env->Global(), foo); |
| 1288 | 1292 |
| 1289 | 1293 |
| 1290 v8::Debug::SetDebugEventListener(NULL); | 1294 v8::Debug::SetDebugEventListener(NULL); |
| 1291 CheckDebuggerUnloaded(); | 1295 CheckDebuggerUnloaded(); |
| 1292 } | 1296 } |
| 1293 | 1297 |
| 1294 | 1298 |
| 1295 // Test that break points can be set using the global Debug object. | 1299 // Test that break points can be set using the global Debug object. |
| 1296 TEST(BreakPointThroughJavaScript) { | 1300 TEST(BreakPointThroughJavaScript) { |
| 1297 break_point_hit_count = 0; | 1301 break_point_hit_count = 0; |
| 1298 DebugLocalContext env; | 1302 DebugLocalContext env; |
| 1299 v8::HandleScope scope(env->GetIsolate()); | 1303 v8::Isolate* isolate = env->GetIsolate(); |
| 1304 v8::HandleScope scope(isolate); |
| 1305 v8::Local<v8::Context> context = env.context(); |
| 1300 env.ExposeDebug(); | 1306 env.ExposeDebug(); |
| 1301 | 1307 |
| 1302 v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); | 1308 v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); |
| 1303 v8::Script::Compile( | 1309 CompileRunChecked(isolate, "function bar(){}"); |
| 1304 v8::String::NewFromUtf8(env->GetIsolate(), "function bar(){}"))->Run(); | 1310 CompileFunction(isolate, "function foo(){bar();bar();}", "foo"); |
| 1305 v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), | 1311 // 012345678901234567890 |
| 1306 "function foo(){bar();bar();}")) | 1312 // 1 2 |
| 1307 ->Run(); | |
| 1308 // 012345678901234567890 | |
| 1309 // 1 2 | |
| 1310 // Break points are set at position 3 and 9 | 1313 // Break points are set at position 3 and 9 |
| 1314 v8::Local<v8::String> source = v8_str(env->GetIsolate(), "foo()"); |
| 1311 v8::Local<v8::Script> foo = | 1315 v8::Local<v8::Script> foo = |
| 1312 v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), "foo()")); | 1316 v8::Script::Compile(context, source).ToLocalChecked(); |
| 1313 | 1317 |
| 1314 // Run without breakpoints. | |
| 1315 foo->Run(); | |
| 1316 CHECK_EQ(0, break_point_hit_count); | 1318 CHECK_EQ(0, break_point_hit_count); |
| 1317 | 1319 |
| 1318 // Run with one breakpoint | 1320 // Run with one breakpoint |
| 1319 int bp1 = SetBreakPointFromJS(env->GetIsolate(), "foo", 0, 3); | 1321 int bp1 = SetBreakPointFromJS(env->GetIsolate(), "foo", 0, 3); |
| 1320 foo->Run(); | 1322 foo->Run(context).ToLocalChecked(); |
| 1321 CHECK_EQ(1, break_point_hit_count); | 1323 CHECK_EQ(1, break_point_hit_count); |
| 1322 foo->Run(); | 1324 foo->Run(context).ToLocalChecked(); |
| 1323 CHECK_EQ(2, break_point_hit_count); | 1325 CHECK_EQ(2, break_point_hit_count); |
| 1324 | 1326 |
| 1325 // Run with two breakpoints | 1327 // Run with two breakpoints |
| 1326 int bp2 = SetBreakPointFromJS(env->GetIsolate(), "foo", 0, 9); | 1328 int bp2 = SetBreakPointFromJS(env->GetIsolate(), "foo", 0, 9); |
| 1327 foo->Run(); | 1329 foo->Run(context).ToLocalChecked(); |
| 1328 CHECK_EQ(4, break_point_hit_count); | 1330 CHECK_EQ(4, break_point_hit_count); |
| 1329 foo->Run(); | 1331 foo->Run(context).ToLocalChecked(); |
| 1330 CHECK_EQ(6, break_point_hit_count); | 1332 CHECK_EQ(6, break_point_hit_count); |
| 1331 | 1333 |
| 1332 // Run with one breakpoint | 1334 // Run with one breakpoint |
| 1333 ClearBreakPointFromJS(env->GetIsolate(), bp2); | 1335 ClearBreakPointFromJS(env->GetIsolate(), bp2); |
| 1334 foo->Run(); | 1336 foo->Run(context).ToLocalChecked(); |
| 1335 CHECK_EQ(7, break_point_hit_count); | 1337 CHECK_EQ(7, break_point_hit_count); |
| 1336 foo->Run(); | 1338 foo->Run(context).ToLocalChecked(); |
| 1337 CHECK_EQ(8, break_point_hit_count); | 1339 CHECK_EQ(8, break_point_hit_count); |
| 1338 | 1340 |
| 1339 // Run without breakpoints. | 1341 // Run without breakpoints. |
| 1340 ClearBreakPointFromJS(env->GetIsolate(), bp1); | 1342 ClearBreakPointFromJS(env->GetIsolate(), bp1); |
| 1341 foo->Run(); | 1343 foo->Run(context).ToLocalChecked(); |
| 1342 CHECK_EQ(8, break_point_hit_count); | 1344 CHECK_EQ(8, break_point_hit_count); |
| 1343 | 1345 |
| 1344 v8::Debug::SetDebugEventListener(NULL); | 1346 v8::Debug::SetDebugEventListener(NULL); |
| 1345 CheckDebuggerUnloaded(); | 1347 CheckDebuggerUnloaded(); |
| 1346 | 1348 |
| 1347 // Make sure that the break point numbers are consecutive. | 1349 // Make sure that the break point numbers are consecutive. |
| 1348 CHECK_EQ(1, bp1); | 1350 CHECK_EQ(1, bp1); |
| 1349 CHECK_EQ(2, bp2); | 1351 CHECK_EQ(2, bp2); |
| 1350 } | 1352 } |
| 1351 | 1353 |
| 1352 | 1354 |
| 1353 // Test that break points on scripts identified by name can be set using the | 1355 // Test that break points on scripts identified by name can be set using the |
| 1354 // global Debug object. | 1356 // global Debug object. |
| 1355 TEST(ScriptBreakPointByNameThroughJavaScript) { | 1357 TEST(ScriptBreakPointByNameThroughJavaScript) { |
| 1356 break_point_hit_count = 0; | 1358 break_point_hit_count = 0; |
| 1357 DebugLocalContext env; | 1359 DebugLocalContext env; |
| 1358 v8::HandleScope scope(env->GetIsolate()); | 1360 v8::Isolate* isolate = env->GetIsolate(); |
| 1361 v8::HandleScope scope(isolate); |
| 1362 v8::Local<v8::Context> context = env.context(); |
| 1359 env.ExposeDebug(); | 1363 env.ExposeDebug(); |
| 1360 | 1364 |
| 1361 v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); | 1365 v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); |
| 1362 | 1366 |
| 1363 v8::Local<v8::String> script = v8::String::NewFromUtf8( | 1367 v8::Local<v8::String> script = v8_str(isolate, |
| 1364 env->GetIsolate(), | 1368 "function f() {\n" |
| 1365 "function f() {\n" | 1369 " function h() {\n" |
| 1366 " function h() {\n" | 1370 " a = 0; // line 2\n" |
| 1367 " a = 0; // line 2\n" | 1371 " }\n" |
| 1368 " }\n" | 1372 " b = 1; // line 4\n" |
| 1369 " b = 1; // line 4\n" | 1373 " return h();\n" |
| 1370 " return h();\n" | 1374 "}\n" |
| 1371 "}\n" | 1375 "\n" |
| 1372 "\n" | 1376 "function g() {\n" |
| 1373 "function g() {\n" | 1377 " function h() {\n" |
| 1374 " function h() {\n" | 1378 " a = 0;\n" |
| 1375 " a = 0;\n" | 1379 " }\n" |
| 1376 " }\n" | 1380 " b = 2; // line 12\n" |
| 1377 " b = 2; // line 12\n" | 1381 " h();\n" |
| 1378 " h();\n" | 1382 " b = 3; // line 14\n" |
| 1379 " b = 3; // line 14\n" | 1383 " f(); // line 15\n" |
| 1380 " f(); // line 15\n" | 1384 "}"); |
| 1381 "}"); | |
| 1382 | 1385 |
| 1383 // Compile the script and get the two functions. | 1386 // Compile the script and get the two functions. |
| 1384 v8::ScriptOrigin origin = | 1387 v8::ScriptOrigin origin = v8::ScriptOrigin(v8_str(isolate, "test")); |
| 1385 v8::ScriptOrigin(v8::String::NewFromUtf8(env->GetIsolate(), "test")); | 1388 v8::Script::Compile(context, script, &origin) |
| 1386 v8::Script::Compile(script, &origin)->Run(); | 1389 .ToLocalChecked() |
| 1390 ->Run(context) |
| 1391 .ToLocalChecked(); |
| 1387 v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( | 1392 v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( |
| 1388 env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); | 1393 env->Global()->Get(context, v8_str(isolate, "f")).ToLocalChecked()); |
| 1389 v8::Local<v8::Function> g = v8::Local<v8::Function>::Cast( | 1394 v8::Local<v8::Function> g = v8::Local<v8::Function>::Cast( |
| 1390 env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "g"))); | 1395 env->Global()->Get(context, v8_str(isolate, "g")).ToLocalChecked()); |
| 1391 | 1396 |
| 1392 // Call f and g without break points. | 1397 // Call f and g without break points. |
| 1393 break_point_hit_count = 0; | 1398 break_point_hit_count = 0; |
| 1394 f->Call(env->Global(), 0, NULL); | 1399 f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 1395 CHECK_EQ(0, break_point_hit_count); | 1400 CHECK_EQ(0, break_point_hit_count); |
| 1396 g->Call(env->Global(), 0, NULL); | 1401 g->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 1397 CHECK_EQ(0, break_point_hit_count); | 1402 CHECK_EQ(0, break_point_hit_count); |
| 1398 | 1403 |
| 1399 // Call f and g with break point on line 12. | 1404 // Call f and g with break point on line 12. |
| 1400 int sbp1 = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test", 12, 0); | 1405 int sbp1 = SetScriptBreakPointByNameFromJS(isolate, "test", 12, 0); |
| 1401 break_point_hit_count = 0; | 1406 break_point_hit_count = 0; |
| 1402 f->Call(env->Global(), 0, NULL); | 1407 f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 1403 CHECK_EQ(0, break_point_hit_count); | 1408 CHECK_EQ(0, break_point_hit_count); |
| 1404 g->Call(env->Global(), 0, NULL); | 1409 g->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 1405 CHECK_EQ(1, break_point_hit_count); | 1410 CHECK_EQ(1, break_point_hit_count); |
| 1406 | 1411 |
| 1407 // Remove the break point again. | 1412 // Remove the break point again. |
| 1408 break_point_hit_count = 0; | 1413 break_point_hit_count = 0; |
| 1409 ClearBreakPointFromJS(env->GetIsolate(), sbp1); | 1414 ClearBreakPointFromJS(env->GetIsolate(), sbp1); |
| 1410 f->Call(env->Global(), 0, NULL); | 1415 f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 1411 CHECK_EQ(0, break_point_hit_count); | 1416 CHECK_EQ(0, break_point_hit_count); |
| 1412 g->Call(env->Global(), 0, NULL); | 1417 g->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 1413 CHECK_EQ(0, break_point_hit_count); | 1418 CHECK_EQ(0, break_point_hit_count); |
| 1414 | 1419 |
| 1415 // Call f and g with break point on line 2. | 1420 // Call f and g with break point on line 2. |
| 1416 int sbp2 = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test", 2, 0); | 1421 int sbp2 = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test", 2, 0); |
| 1417 break_point_hit_count = 0; | 1422 break_point_hit_count = 0; |
| 1418 f->Call(env->Global(), 0, NULL); | 1423 f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 1419 CHECK_EQ(1, break_point_hit_count); | 1424 CHECK_EQ(1, break_point_hit_count); |
| 1420 g->Call(env->Global(), 0, NULL); | 1425 g->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 1421 CHECK_EQ(2, break_point_hit_count); | 1426 CHECK_EQ(2, break_point_hit_count); |
| 1422 | 1427 |
| 1423 // Call f and g with break point on line 2, 4, 12, 14 and 15. | 1428 // Call f and g with break point on line 2, 4, 12, 14 and 15. |
| 1424 int sbp3 = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test", 4, 0); | 1429 int sbp3 = SetScriptBreakPointByNameFromJS(isolate, "test", 4, 0); |
| 1425 int sbp4 = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test", 12, 0); | 1430 int sbp4 = SetScriptBreakPointByNameFromJS(isolate, "test", 12, 0); |
| 1426 int sbp5 = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test", 14, 0); | 1431 int sbp5 = SetScriptBreakPointByNameFromJS(isolate, "test", 14, 0); |
| 1427 int sbp6 = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test", 15, 0); | 1432 int sbp6 = SetScriptBreakPointByNameFromJS(isolate, "test", 15, 0); |
| 1428 break_point_hit_count = 0; | 1433 break_point_hit_count = 0; |
| 1429 f->Call(env->Global(), 0, NULL); | 1434 f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 1430 CHECK_EQ(2, break_point_hit_count); | 1435 CHECK_EQ(2, break_point_hit_count); |
| 1431 g->Call(env->Global(), 0, NULL); | 1436 g->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 1432 CHECK_EQ(7, break_point_hit_count); | 1437 CHECK_EQ(7, break_point_hit_count); |
| 1433 | 1438 |
| 1434 // Remove all the break points again. | 1439 // Remove all the break points again. |
| 1435 break_point_hit_count = 0; | 1440 break_point_hit_count = 0; |
| 1436 ClearBreakPointFromJS(env->GetIsolate(), sbp2); | 1441 ClearBreakPointFromJS(isolate, sbp2); |
| 1437 ClearBreakPointFromJS(env->GetIsolate(), sbp3); | 1442 ClearBreakPointFromJS(isolate, sbp3); |
| 1438 ClearBreakPointFromJS(env->GetIsolate(), sbp4); | 1443 ClearBreakPointFromJS(isolate, sbp4); |
| 1439 ClearBreakPointFromJS(env->GetIsolate(), sbp5); | 1444 ClearBreakPointFromJS(isolate, sbp5); |
| 1440 ClearBreakPointFromJS(env->GetIsolate(), sbp6); | 1445 ClearBreakPointFromJS(isolate, sbp6); |
| 1441 f->Call(env->Global(), 0, NULL); | 1446 f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 1442 CHECK_EQ(0, break_point_hit_count); | 1447 CHECK_EQ(0, break_point_hit_count); |
| 1443 g->Call(env->Global(), 0, NULL); | 1448 g->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 1444 CHECK_EQ(0, break_point_hit_count); | 1449 CHECK_EQ(0, break_point_hit_count); |
| 1445 | 1450 |
| 1446 v8::Debug::SetDebugEventListener(NULL); | 1451 v8::Debug::SetDebugEventListener(NULL); |
| 1447 CheckDebuggerUnloaded(); | 1452 CheckDebuggerUnloaded(); |
| 1448 | 1453 |
| 1449 // Make sure that the break point numbers are consecutive. | 1454 // Make sure that the break point numbers are consecutive. |
| 1450 CHECK_EQ(1, sbp1); | 1455 CHECK_EQ(1, sbp1); |
| 1451 CHECK_EQ(2, sbp2); | 1456 CHECK_EQ(2, sbp2); |
| 1452 CHECK_EQ(3, sbp3); | 1457 CHECK_EQ(3, sbp3); |
| 1453 CHECK_EQ(4, sbp4); | 1458 CHECK_EQ(4, sbp4); |
| 1454 CHECK_EQ(5, sbp5); | 1459 CHECK_EQ(5, sbp5); |
| 1455 CHECK_EQ(6, sbp6); | 1460 CHECK_EQ(6, sbp6); |
| 1456 } | 1461 } |
| 1457 | 1462 |
| 1458 | 1463 |
| 1459 TEST(ScriptBreakPointByIdThroughJavaScript) { | 1464 TEST(ScriptBreakPointByIdThroughJavaScript) { |
| 1460 break_point_hit_count = 0; | 1465 break_point_hit_count = 0; |
| 1461 DebugLocalContext env; | 1466 DebugLocalContext env; |
| 1462 v8::HandleScope scope(env->GetIsolate()); | 1467 v8::Isolate* isolate = env->GetIsolate(); |
| 1468 v8::HandleScope scope(isolate); |
| 1469 v8::Local<v8::Context> context = env.context(); |
| 1463 env.ExposeDebug(); | 1470 env.ExposeDebug(); |
| 1464 | 1471 |
| 1465 v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); | 1472 v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); |
| 1466 | 1473 |
| 1467 v8::Local<v8::String> source = v8::String::NewFromUtf8( | 1474 v8::Local<v8::String> source = v8_str(isolate, |
| 1468 env->GetIsolate(), | 1475 "function f() {\n" |
| 1469 "function f() {\n" | 1476 " function h() {\n" |
| 1470 " function h() {\n" | 1477 " a = 0; // line 2\n" |
| 1471 " a = 0; // line 2\n" | 1478 " }\n" |
| 1472 " }\n" | 1479 " b = 1; // line 4\n" |
| 1473 " b = 1; // line 4\n" | 1480 " return h();\n" |
| 1474 " return h();\n" | 1481 "}\n" |
| 1475 "}\n" | 1482 "\n" |
| 1476 "\n" | 1483 "function g() {\n" |
| 1477 "function g() {\n" | 1484 " function h() {\n" |
| 1478 " function h() {\n" | 1485 " a = 0;\n" |
| 1479 " a = 0;\n" | 1486 " }\n" |
| 1480 " }\n" | 1487 " b = 2; // line 12\n" |
| 1481 " b = 2; // line 12\n" | 1488 " h();\n" |
| 1482 " h();\n" | 1489 " b = 3; // line 14\n" |
| 1483 " b = 3; // line 14\n" | 1490 " f(); // line 15\n" |
| 1484 " f(); // line 15\n" | 1491 "}"); |
| 1485 "}"); | |
| 1486 | 1492 |
| 1487 // Compile the script and get the two functions. | 1493 // Compile the script and get the two functions. |
| 1488 v8::ScriptOrigin origin = | 1494 v8::ScriptOrigin origin = v8::ScriptOrigin(v8_str(isolate, "test")); |
| 1489 v8::ScriptOrigin(v8::String::NewFromUtf8(env->GetIsolate(), "test")); | 1495 v8::Local<v8::Script> script = |
| 1490 v8::Local<v8::Script> script = v8::Script::Compile(source, &origin); | 1496 v8::Script::Compile(context, source, &origin).ToLocalChecked(); |
| 1491 script->Run(); | 1497 script->Run(context).ToLocalChecked(); |
| 1492 v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( | 1498 v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( |
| 1493 env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); | 1499 env->Global()->Get(context, v8_str(isolate, "f")).ToLocalChecked()); |
| 1494 v8::Local<v8::Function> g = v8::Local<v8::Function>::Cast( | 1500 v8::Local<v8::Function> g = v8::Local<v8::Function>::Cast( |
| 1495 env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "g"))); | 1501 env->Global()->Get(context, v8_str(isolate, "g")).ToLocalChecked()); |
| 1496 | 1502 |
| 1497 // Get the script id knowing that internally it is a 32 integer. | 1503 // Get the script id knowing that internally it is a 32 integer. |
| 1498 int script_id = script->GetUnboundScript()->GetId(); | 1504 int script_id = script->GetUnboundScript()->GetId(); |
| 1499 | 1505 |
| 1500 // Call f and g without break points. | 1506 // Call f and g without break points. |
| 1501 break_point_hit_count = 0; | 1507 break_point_hit_count = 0; |
| 1502 f->Call(env->Global(), 0, NULL); | 1508 f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 1503 CHECK_EQ(0, break_point_hit_count); | 1509 CHECK_EQ(0, break_point_hit_count); |
| 1504 g->Call(env->Global(), 0, NULL); | 1510 g->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 1505 CHECK_EQ(0, break_point_hit_count); | 1511 CHECK_EQ(0, break_point_hit_count); |
| 1506 | 1512 |
| 1507 // Call f and g with break point on line 12. | 1513 // Call f and g with break point on line 12. |
| 1508 int sbp1 = SetScriptBreakPointByIdFromJS(env->GetIsolate(), script_id, 12, 0); | 1514 int sbp1 = SetScriptBreakPointByIdFromJS(env->GetIsolate(), script_id, 12, 0); |
| 1509 break_point_hit_count = 0; | 1515 break_point_hit_count = 0; |
| 1510 f->Call(env->Global(), 0, NULL); | 1516 f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 1511 CHECK_EQ(0, break_point_hit_count); | 1517 CHECK_EQ(0, break_point_hit_count); |
| 1512 g->Call(env->Global(), 0, NULL); | 1518 g->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 1513 CHECK_EQ(1, break_point_hit_count); | 1519 CHECK_EQ(1, break_point_hit_count); |
| 1514 | 1520 |
| 1515 // Remove the break point again. | 1521 // Remove the break point again. |
| 1516 break_point_hit_count = 0; | 1522 break_point_hit_count = 0; |
| 1517 ClearBreakPointFromJS(env->GetIsolate(), sbp1); | 1523 ClearBreakPointFromJS(env->GetIsolate(), sbp1); |
| 1518 f->Call(env->Global(), 0, NULL); | 1524 f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 1519 CHECK_EQ(0, break_point_hit_count); | 1525 CHECK_EQ(0, break_point_hit_count); |
| 1520 g->Call(env->Global(), 0, NULL); | 1526 g->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 1521 CHECK_EQ(0, break_point_hit_count); | 1527 CHECK_EQ(0, break_point_hit_count); |
| 1522 | 1528 |
| 1523 // Call f and g with break point on line 2. | 1529 // Call f and g with break point on line 2. |
| 1524 int sbp2 = SetScriptBreakPointByIdFromJS(env->GetIsolate(), script_id, 2, 0); | 1530 int sbp2 = SetScriptBreakPointByIdFromJS(env->GetIsolate(), script_id, 2, 0); |
| 1525 break_point_hit_count = 0; | 1531 break_point_hit_count = 0; |
| 1526 f->Call(env->Global(), 0, NULL); | 1532 f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 1527 CHECK_EQ(1, break_point_hit_count); | 1533 CHECK_EQ(1, break_point_hit_count); |
| 1528 g->Call(env->Global(), 0, NULL); | 1534 g->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 1529 CHECK_EQ(2, break_point_hit_count); | 1535 CHECK_EQ(2, break_point_hit_count); |
| 1530 | 1536 |
| 1531 // Call f and g with break point on line 2, 4, 12, 14 and 15. | 1537 // Call f and g with break point on line 2, 4, 12, 14 and 15. |
| 1532 int sbp3 = SetScriptBreakPointByIdFromJS(env->GetIsolate(), script_id, 4, 0); | 1538 int sbp3 = SetScriptBreakPointByIdFromJS(env->GetIsolate(), script_id, 4, 0); |
| 1533 int sbp4 = SetScriptBreakPointByIdFromJS(env->GetIsolate(), script_id, 12, 0); | 1539 int sbp4 = SetScriptBreakPointByIdFromJS(env->GetIsolate(), script_id, 12, 0); |
| 1534 int sbp5 = SetScriptBreakPointByIdFromJS(env->GetIsolate(), script_id, 14, 0); | 1540 int sbp5 = SetScriptBreakPointByIdFromJS(env->GetIsolate(), script_id, 14, 0); |
| 1535 int sbp6 = SetScriptBreakPointByIdFromJS(env->GetIsolate(), script_id, 15, 0); | 1541 int sbp6 = SetScriptBreakPointByIdFromJS(env->GetIsolate(), script_id, 15, 0); |
| 1536 break_point_hit_count = 0; | 1542 break_point_hit_count = 0; |
| 1537 f->Call(env->Global(), 0, NULL); | 1543 f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 1538 CHECK_EQ(2, break_point_hit_count); | 1544 CHECK_EQ(2, break_point_hit_count); |
| 1539 g->Call(env->Global(), 0, NULL); | 1545 g->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 1540 CHECK_EQ(7, break_point_hit_count); | 1546 CHECK_EQ(7, break_point_hit_count); |
| 1541 | 1547 |
| 1542 // Remove all the break points again. | 1548 // Remove all the break points again. |
| 1543 break_point_hit_count = 0; | 1549 break_point_hit_count = 0; |
| 1544 ClearBreakPointFromJS(env->GetIsolate(), sbp2); | 1550 ClearBreakPointFromJS(env->GetIsolate(), sbp2); |
| 1545 ClearBreakPointFromJS(env->GetIsolate(), sbp3); | 1551 ClearBreakPointFromJS(env->GetIsolate(), sbp3); |
| 1546 ClearBreakPointFromJS(env->GetIsolate(), sbp4); | 1552 ClearBreakPointFromJS(env->GetIsolate(), sbp4); |
| 1547 ClearBreakPointFromJS(env->GetIsolate(), sbp5); | 1553 ClearBreakPointFromJS(env->GetIsolate(), sbp5); |
| 1548 ClearBreakPointFromJS(env->GetIsolate(), sbp6); | 1554 ClearBreakPointFromJS(env->GetIsolate(), sbp6); |
| 1549 f->Call(env->Global(), 0, NULL); | 1555 f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 1550 CHECK_EQ(0, break_point_hit_count); | 1556 CHECK_EQ(0, break_point_hit_count); |
| 1551 g->Call(env->Global(), 0, NULL); | 1557 g->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 1552 CHECK_EQ(0, break_point_hit_count); | 1558 CHECK_EQ(0, break_point_hit_count); |
| 1553 | 1559 |
| 1554 v8::Debug::SetDebugEventListener(NULL); | 1560 v8::Debug::SetDebugEventListener(NULL); |
| 1555 CheckDebuggerUnloaded(); | 1561 CheckDebuggerUnloaded(); |
| 1556 | 1562 |
| 1557 // Make sure that the break point numbers are consecutive. | 1563 // Make sure that the break point numbers are consecutive. |
| 1558 CHECK_EQ(1, sbp1); | 1564 CHECK_EQ(1, sbp1); |
| 1559 CHECK_EQ(2, sbp2); | 1565 CHECK_EQ(2, sbp2); |
| 1560 CHECK_EQ(3, sbp3); | 1566 CHECK_EQ(3, sbp3); |
| 1561 CHECK_EQ(4, sbp4); | 1567 CHECK_EQ(4, sbp4); |
| 1562 CHECK_EQ(5, sbp5); | 1568 CHECK_EQ(5, sbp5); |
| 1563 CHECK_EQ(6, sbp6); | 1569 CHECK_EQ(6, sbp6); |
| 1564 } | 1570 } |
| 1565 | 1571 |
| 1566 | 1572 |
| 1567 // Test conditional script break points. | 1573 // Test conditional script break points. |
| 1568 TEST(EnableDisableScriptBreakPoint) { | 1574 TEST(EnableDisableScriptBreakPoint) { |
| 1569 break_point_hit_count = 0; | 1575 break_point_hit_count = 0; |
| 1570 DebugLocalContext env; | 1576 DebugLocalContext env; |
| 1571 v8::HandleScope scope(env->GetIsolate()); | 1577 v8::Isolate* isolate = env->GetIsolate(); |
| 1578 v8::HandleScope scope(isolate); |
| 1579 v8::Local<v8::Context> context = env.context(); |
| 1572 env.ExposeDebug(); | 1580 env.ExposeDebug(); |
| 1573 | 1581 |
| 1574 v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); | 1582 v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); |
| 1575 | 1583 |
| 1576 v8::Local<v8::String> script = v8::String::NewFromUtf8( | 1584 v8::Local<v8::String> script = v8_str(isolate, |
| 1577 env->GetIsolate(), | 1585 "function f() {\n" |
| 1578 "function f() {\n" | 1586 " a = 0; // line 1\n" |
| 1579 " a = 0; // line 1\n" | 1587 "};"); |
| 1580 "};"); | |
| 1581 | 1588 |
| 1582 // Compile the script and get function f. | 1589 // Compile the script and get function f. |
| 1583 v8::ScriptOrigin origin = | 1590 v8::ScriptOrigin origin = v8::ScriptOrigin(v8_str(isolate, "test")); |
| 1584 v8::ScriptOrigin(v8::String::NewFromUtf8(env->GetIsolate(), "test")); | 1591 v8::Script::Compile(context, script, &origin) |
| 1585 v8::Script::Compile(script, &origin)->Run(); | 1592 .ToLocalChecked() |
| 1593 ->Run(context) |
| 1594 .ToLocalChecked(); |
| 1586 v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( | 1595 v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( |
| 1587 env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); | 1596 env->Global()->Get(context, v8_str(isolate, "f")).ToLocalChecked()); |
| 1588 | 1597 |
| 1589 // Set script break point on line 1 (in function f). | 1598 // Set script break point on line 1 (in function f). |
| 1590 int sbp = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test", 1, 0); | 1599 int sbp = SetScriptBreakPointByNameFromJS(isolate, "test", 1, 0); |
| 1591 | 1600 |
| 1592 // Call f while enabeling and disabling the script break point. | 1601 // Call f while enabeling and disabling the script break point. |
| 1593 break_point_hit_count = 0; | 1602 break_point_hit_count = 0; |
| 1594 f->Call(env->Global(), 0, NULL); | 1603 f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 1595 CHECK_EQ(1, break_point_hit_count); | 1604 CHECK_EQ(1, break_point_hit_count); |
| 1596 | 1605 |
| 1597 DisableScriptBreakPointFromJS(env->GetIsolate(), sbp); | 1606 DisableScriptBreakPointFromJS(isolate, sbp); |
| 1598 f->Call(env->Global(), 0, NULL); | 1607 f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 1599 CHECK_EQ(1, break_point_hit_count); | 1608 CHECK_EQ(1, break_point_hit_count); |
| 1600 | 1609 |
| 1601 EnableScriptBreakPointFromJS(env->GetIsolate(), sbp); | 1610 EnableScriptBreakPointFromJS(isolate, sbp); |
| 1602 f->Call(env->Global(), 0, NULL); | 1611 f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 1603 CHECK_EQ(2, break_point_hit_count); | 1612 CHECK_EQ(2, break_point_hit_count); |
| 1604 | 1613 |
| 1605 DisableScriptBreakPointFromJS(env->GetIsolate(), sbp); | 1614 DisableScriptBreakPointFromJS(isolate, sbp); |
| 1606 f->Call(env->Global(), 0, NULL); | 1615 f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 1607 CHECK_EQ(2, break_point_hit_count); | 1616 CHECK_EQ(2, break_point_hit_count); |
| 1608 | 1617 |
| 1609 // Reload the script and get f again checking that the disabeling survives. | 1618 // Reload the script and get f again checking that the disabling survives. |
| 1610 v8::Script::Compile(script, &origin)->Run(); | 1619 v8::Script::Compile(context, script, &origin) |
| 1620 .ToLocalChecked() |
| 1621 ->Run(context) |
| 1622 .ToLocalChecked(); |
| 1611 f = v8::Local<v8::Function>::Cast( | 1623 f = v8::Local<v8::Function>::Cast( |
| 1612 env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); | 1624 env->Global()->Get(context, v8_str(isolate, "f")).ToLocalChecked()); |
| 1613 f->Call(env->Global(), 0, NULL); | 1625 f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 1614 CHECK_EQ(2, break_point_hit_count); | 1626 CHECK_EQ(2, break_point_hit_count); |
| 1615 | 1627 |
| 1616 EnableScriptBreakPointFromJS(env->GetIsolate(), sbp); | 1628 EnableScriptBreakPointFromJS(isolate, sbp); |
| 1617 f->Call(env->Global(), 0, NULL); | 1629 f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 1618 CHECK_EQ(3, break_point_hit_count); | 1630 CHECK_EQ(3, break_point_hit_count); |
| 1619 | 1631 |
| 1620 v8::Debug::SetDebugEventListener(NULL); | 1632 v8::Debug::SetDebugEventListener(NULL); |
| 1621 CheckDebuggerUnloaded(); | 1633 CheckDebuggerUnloaded(); |
| 1622 } | 1634 } |
| 1623 | 1635 |
| 1624 | 1636 |
| 1625 // Test conditional script break points. | 1637 // Test conditional script break points. |
| 1626 TEST(ConditionalScriptBreakPoint) { | 1638 TEST(ConditionalScriptBreakPoint) { |
| 1627 break_point_hit_count = 0; | 1639 break_point_hit_count = 0; |
| 1628 DebugLocalContext env; | 1640 DebugLocalContext env; |
| 1629 v8::HandleScope scope(env->GetIsolate()); | 1641 v8::HandleScope scope(env->GetIsolate()); |
| 1630 env.ExposeDebug(); | 1642 env.ExposeDebug(); |
| 1631 | 1643 |
| 1632 v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); | 1644 v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); |
| 1633 | 1645 |
| 1634 v8::Local<v8::String> script = v8::String::NewFromUtf8( | 1646 v8::Local<v8::String> script = v8_str(env->GetIsolate(), |
| 1635 env->GetIsolate(), | 1647 "count = 0;\n" |
| 1636 "count = 0;\n" | 1648 "function f() {\n" |
| 1637 "function f() {\n" | 1649 " g(count++); // line 2\n" |
| 1638 " g(count++); // line 2\n" | 1650 "};\n" |
| 1639 "};\n" | 1651 "function g(x) {\n" |
| 1640 "function g(x) {\n" | 1652 " var a=x; // line 5\n" |
| 1641 " var a=x; // line 5\n" | 1653 "};"); |
| 1642 "};"); | |
| 1643 | 1654 |
| 1644 // Compile the script and get function f. | 1655 // Compile the script and get function f. |
| 1645 v8::ScriptOrigin origin = | 1656 v8::Local<v8::Context> context = env.context(); |
| 1646 v8::ScriptOrigin(v8::String::NewFromUtf8(env->GetIsolate(), "test")); | 1657 v8::ScriptOrigin origin = v8::ScriptOrigin(v8_str(env->GetIsolate(), "test")); |
| 1647 v8::Script::Compile(script, &origin)->Run(); | 1658 v8::Script::Compile(context, script, &origin) |
| 1659 .ToLocalChecked() |
| 1660 ->Run(context) |
| 1661 .ToLocalChecked(); |
| 1648 v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( | 1662 v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( |
| 1649 env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); | 1663 env->Global() |
| 1664 ->Get(context, v8_str(env->GetIsolate(), "f")) |
| 1665 .ToLocalChecked()); |
| 1650 | 1666 |
| 1651 // Set script break point on line 5 (in function g). | 1667 // Set script break point on line 5 (in function g). |
| 1652 int sbp1 = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test", 5, 0); | 1668 int sbp1 = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test", 5, 0); |
| 1653 | 1669 |
| 1654 // Call f with different conditions on the script break point. | 1670 // Call f with different conditions on the script break point. |
| 1655 break_point_hit_count = 0; | 1671 break_point_hit_count = 0; |
| 1656 ChangeScriptBreakPointConditionFromJS(env->GetIsolate(), sbp1, "false"); | 1672 ChangeScriptBreakPointConditionFromJS(env->GetIsolate(), sbp1, "false"); |
| 1657 f->Call(env->Global(), 0, NULL); | 1673 f->Call(env.context(), env->Global(), 0, NULL).ToLocalChecked(); |
| 1658 CHECK_EQ(0, break_point_hit_count); | 1674 CHECK_EQ(0, break_point_hit_count); |
| 1659 | 1675 |
| 1660 ChangeScriptBreakPointConditionFromJS(env->GetIsolate(), sbp1, "true"); | 1676 ChangeScriptBreakPointConditionFromJS(env->GetIsolate(), sbp1, "true"); |
| 1661 break_point_hit_count = 0; | 1677 break_point_hit_count = 0; |
| 1662 f->Call(env->Global(), 0, NULL); | 1678 f->Call(env.context(), env->Global(), 0, NULL).ToLocalChecked(); |
| 1663 CHECK_EQ(1, break_point_hit_count); | 1679 CHECK_EQ(1, break_point_hit_count); |
| 1664 | 1680 |
| 1665 ChangeScriptBreakPointConditionFromJS(env->GetIsolate(), sbp1, "x % 2 == 0"); | 1681 ChangeScriptBreakPointConditionFromJS(env->GetIsolate(), sbp1, "x % 2 == 0"); |
| 1666 break_point_hit_count = 0; | 1682 break_point_hit_count = 0; |
| 1667 for (int i = 0; i < 10; i++) { | 1683 for (int i = 0; i < 10; i++) { |
| 1668 f->Call(env->Global(), 0, NULL); | 1684 f->Call(env.context(), env->Global(), 0, NULL).ToLocalChecked(); |
| 1669 } | 1685 } |
| 1670 CHECK_EQ(5, break_point_hit_count); | 1686 CHECK_EQ(5, break_point_hit_count); |
| 1671 | 1687 |
| 1672 // Reload the script and get f again checking that the condition survives. | 1688 // Reload the script and get f again checking that the condition survives. |
| 1673 v8::Script::Compile(script, &origin)->Run(); | 1689 v8::Script::Compile(context, script, &origin) |
| 1690 .ToLocalChecked() |
| 1691 ->Run(context) |
| 1692 .ToLocalChecked(); |
| 1674 f = v8::Local<v8::Function>::Cast( | 1693 f = v8::Local<v8::Function>::Cast( |
| 1675 env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); | 1694 env->Global() |
| 1695 ->Get(context, v8_str(env->GetIsolate(), "f")) |
| 1696 .ToLocalChecked()); |
| 1676 | 1697 |
| 1677 break_point_hit_count = 0; | 1698 break_point_hit_count = 0; |
| 1678 for (int i = 0; i < 10; i++) { | 1699 for (int i = 0; i < 10; i++) { |
| 1679 f->Call(env->Global(), 0, NULL); | 1700 f->Call(env.context(), env->Global(), 0, NULL).ToLocalChecked(); |
| 1680 } | 1701 } |
| 1681 CHECK_EQ(5, break_point_hit_count); | 1702 CHECK_EQ(5, break_point_hit_count); |
| 1682 | 1703 |
| 1683 v8::Debug::SetDebugEventListener(NULL); | 1704 v8::Debug::SetDebugEventListener(NULL); |
| 1684 CheckDebuggerUnloaded(); | 1705 CheckDebuggerUnloaded(); |
| 1685 } | 1706 } |
| 1686 | 1707 |
| 1687 | 1708 |
| 1688 // Test ignore count on script break points. | 1709 // Test ignore count on script break points. |
| 1689 TEST(ScriptBreakPointIgnoreCount) { | 1710 TEST(ScriptBreakPointIgnoreCount) { |
| 1690 break_point_hit_count = 0; | 1711 break_point_hit_count = 0; |
| 1691 DebugLocalContext env; | 1712 DebugLocalContext env; |
| 1692 v8::HandleScope scope(env->GetIsolate()); | 1713 v8::HandleScope scope(env->GetIsolate()); |
| 1693 env.ExposeDebug(); | 1714 env.ExposeDebug(); |
| 1694 | 1715 |
| 1695 v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); | 1716 v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); |
| 1696 | 1717 |
| 1697 v8::Local<v8::String> script = v8::String::NewFromUtf8( | 1718 v8::Local<v8::String> script = v8_str(env->GetIsolate(), |
| 1698 env->GetIsolate(), | 1719 "function f() {\n" |
| 1699 "function f() {\n" | 1720 " a = 0; // line 1\n" |
| 1700 " a = 0; // line 1\n" | 1721 "};"); |
| 1701 "};"); | |
| 1702 | 1722 |
| 1703 // Compile the script and get function f. | 1723 // Compile the script and get function f. |
| 1704 v8::ScriptOrigin origin = | 1724 v8::Local<v8::Context> context = env.context(); |
| 1705 v8::ScriptOrigin(v8::String::NewFromUtf8(env->GetIsolate(), "test")); | 1725 v8::ScriptOrigin origin = v8::ScriptOrigin(v8_str(env->GetIsolate(), "test")); |
| 1706 v8::Script::Compile(script, &origin)->Run(); | 1726 v8::Script::Compile(context, script, &origin) |
| 1727 .ToLocalChecked() |
| 1728 ->Run(context) |
| 1729 .ToLocalChecked(); |
| 1707 v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( | 1730 v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( |
| 1708 env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); | 1731 env->Global() |
| 1732 ->Get(context, v8_str(env->GetIsolate(), "f")) |
| 1733 .ToLocalChecked()); |
| 1709 | 1734 |
| 1710 // Set script break point on line 1 (in function f). | 1735 // Set script break point on line 1 (in function f). |
| 1711 int sbp = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test", 1, 0); | 1736 int sbp = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test", 1, 0); |
| 1712 | 1737 |
| 1713 // Call f with different ignores on the script break point. | 1738 // Call f with different ignores on the script break point. |
| 1714 break_point_hit_count = 0; | 1739 break_point_hit_count = 0; |
| 1715 ChangeScriptBreakPointIgnoreCountFromJS(env->GetIsolate(), sbp, 1); | 1740 ChangeScriptBreakPointIgnoreCountFromJS(env->GetIsolate(), sbp, 1); |
| 1716 f->Call(env->Global(), 0, NULL); | 1741 f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 1717 CHECK_EQ(0, break_point_hit_count); | 1742 CHECK_EQ(0, break_point_hit_count); |
| 1718 f->Call(env->Global(), 0, NULL); | 1743 f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 1719 CHECK_EQ(1, break_point_hit_count); | 1744 CHECK_EQ(1, break_point_hit_count); |
| 1720 | 1745 |
| 1721 ChangeScriptBreakPointIgnoreCountFromJS(env->GetIsolate(), sbp, 5); | 1746 ChangeScriptBreakPointIgnoreCountFromJS(env->GetIsolate(), sbp, 5); |
| 1722 break_point_hit_count = 0; | 1747 break_point_hit_count = 0; |
| 1723 for (int i = 0; i < 10; i++) { | 1748 for (int i = 0; i < 10; i++) { |
| 1724 f->Call(env->Global(), 0, NULL); | 1749 f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 1725 } | 1750 } |
| 1726 CHECK_EQ(5, break_point_hit_count); | 1751 CHECK_EQ(5, break_point_hit_count); |
| 1727 | 1752 |
| 1728 // Reload the script and get f again checking that the ignore survives. | 1753 // Reload the script and get f again checking that the ignore survives. |
| 1729 v8::Script::Compile(script, &origin)->Run(); | 1754 v8::Script::Compile(context, script, &origin) |
| 1755 .ToLocalChecked() |
| 1756 ->Run(context) |
| 1757 .ToLocalChecked(); |
| 1730 f = v8::Local<v8::Function>::Cast( | 1758 f = v8::Local<v8::Function>::Cast( |
| 1731 env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); | 1759 env->Global() |
| 1760 ->Get(context, v8_str(env->GetIsolate(), "f")) |
| 1761 .ToLocalChecked()); |
| 1732 | 1762 |
| 1733 break_point_hit_count = 0; | 1763 break_point_hit_count = 0; |
| 1734 for (int i = 0; i < 10; i++) { | 1764 for (int i = 0; i < 10; i++) { |
| 1735 f->Call(env->Global(), 0, NULL); | 1765 f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 1736 } | 1766 } |
| 1737 CHECK_EQ(5, break_point_hit_count); | 1767 CHECK_EQ(5, break_point_hit_count); |
| 1738 | 1768 |
| 1739 v8::Debug::SetDebugEventListener(NULL); | 1769 v8::Debug::SetDebugEventListener(NULL); |
| 1740 CheckDebuggerUnloaded(); | 1770 CheckDebuggerUnloaded(); |
| 1741 } | 1771 } |
| 1742 | 1772 |
| 1743 | 1773 |
| 1744 // Test that script break points survive when a script is reloaded. | 1774 // Test that script break points survive when a script is reloaded. |
| 1745 TEST(ScriptBreakPointReload) { | 1775 TEST(ScriptBreakPointReload) { |
| 1746 break_point_hit_count = 0; | 1776 break_point_hit_count = 0; |
| 1747 DebugLocalContext env; | 1777 DebugLocalContext env; |
| 1748 v8::HandleScope scope(env->GetIsolate()); | 1778 v8::HandleScope scope(env->GetIsolate()); |
| 1749 env.ExposeDebug(); | 1779 env.ExposeDebug(); |
| 1750 | 1780 |
| 1751 v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); | 1781 v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); |
| 1752 | 1782 |
| 1783 v8::Local<v8::Context> context = env.context(); |
| 1753 v8::Local<v8::Function> f; | 1784 v8::Local<v8::Function> f; |
| 1754 v8::Local<v8::String> script = v8::String::NewFromUtf8( | 1785 v8::Local<v8::String> script = v8_str(env->GetIsolate(), |
| 1755 env->GetIsolate(), | 1786 "function f() {\n" |
| 1756 "function f() {\n" | 1787 " function h() {\n" |
| 1757 " function h() {\n" | 1788 " a = 0; // line 2\n" |
| 1758 " a = 0; // line 2\n" | 1789 " }\n" |
| 1759 " }\n" | 1790 " b = 1; // line 4\n" |
| 1760 " b = 1; // line 4\n" | 1791 " return h();\n" |
| 1761 " return h();\n" | 1792 "}"); |
| 1762 "}"); | |
| 1763 | 1793 |
| 1764 v8::ScriptOrigin origin_1 = | 1794 v8::ScriptOrigin origin_1 = v8::ScriptOrigin(v8_str(env->GetIsolate(), "1")); |
| 1765 v8::ScriptOrigin(v8::String::NewFromUtf8(env->GetIsolate(), "1")); | 1795 v8::ScriptOrigin origin_2 = v8::ScriptOrigin(v8_str(env->GetIsolate(), "2")); |
| 1766 v8::ScriptOrigin origin_2 = | |
| 1767 v8::ScriptOrigin(v8::String::NewFromUtf8(env->GetIsolate(), "2")); | |
| 1768 | 1796 |
| 1769 // Set a script break point before the script is loaded. | 1797 // Set a script break point before the script is loaded. |
| 1770 SetScriptBreakPointByNameFromJS(env->GetIsolate(), "1", 2, 0); | 1798 SetScriptBreakPointByNameFromJS(env->GetIsolate(), "1", 2, 0); |
| 1771 | 1799 |
| 1772 // Compile the script and get the function. | 1800 // Compile the script and get the function. |
| 1773 v8::Script::Compile(script, &origin_1)->Run(); | 1801 v8::Script::Compile(context, script, &origin_1) |
| 1802 .ToLocalChecked() |
| 1803 ->Run(context) |
| 1804 .ToLocalChecked(); |
| 1774 f = v8::Local<v8::Function>::Cast( | 1805 f = v8::Local<v8::Function>::Cast( |
| 1775 env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); | 1806 env->Global() |
| 1807 ->Get(context, v8_str(env->GetIsolate(), "f")) |
| 1808 .ToLocalChecked()); |
| 1776 | 1809 |
| 1777 // Call f and check that the script break point is active. | 1810 // Call f and check that the script break point is active. |
| 1778 break_point_hit_count = 0; | 1811 break_point_hit_count = 0; |
| 1779 f->Call(env->Global(), 0, NULL); | 1812 f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 1780 CHECK_EQ(1, break_point_hit_count); | 1813 CHECK_EQ(1, break_point_hit_count); |
| 1781 | 1814 |
| 1782 // Compile the script again with a different script data and get the | 1815 // Compile the script again with a different script data and get the |
| 1783 // function. | 1816 // function. |
| 1784 v8::Script::Compile(script, &origin_2)->Run(); | 1817 v8::Script::Compile(context, script, &origin_2) |
| 1818 .ToLocalChecked() |
| 1819 ->Run(context) |
| 1820 .ToLocalChecked(); |
| 1785 f = v8::Local<v8::Function>::Cast( | 1821 f = v8::Local<v8::Function>::Cast( |
| 1786 env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); | 1822 env->Global() |
| 1823 ->Get(context, v8_str(env->GetIsolate(), "f")) |
| 1824 .ToLocalChecked()); |
| 1787 | 1825 |
| 1788 // Call f and check that no break points are set. | 1826 // Call f and check that no break points are set. |
| 1789 break_point_hit_count = 0; | 1827 break_point_hit_count = 0; |
| 1790 f->Call(env->Global(), 0, NULL); | 1828 f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 1791 CHECK_EQ(0, break_point_hit_count); | 1829 CHECK_EQ(0, break_point_hit_count); |
| 1792 | 1830 |
| 1793 // Compile the script again and get the function. | 1831 // Compile the script again and get the function. |
| 1794 v8::Script::Compile(script, &origin_1)->Run(); | 1832 v8::Script::Compile(context, script, &origin_1) |
| 1833 .ToLocalChecked() |
| 1834 ->Run(context) |
| 1835 .ToLocalChecked(); |
| 1795 f = v8::Local<v8::Function>::Cast( | 1836 f = v8::Local<v8::Function>::Cast( |
| 1796 env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); | 1837 env->Global() |
| 1838 ->Get(context, v8_str(env->GetIsolate(), "f")) |
| 1839 .ToLocalChecked()); |
| 1797 | 1840 |
| 1798 // Call f and check that the script break point is active. | 1841 // Call f and check that the script break point is active. |
| 1799 break_point_hit_count = 0; | 1842 break_point_hit_count = 0; |
| 1800 f->Call(env->Global(), 0, NULL); | 1843 f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 1801 CHECK_EQ(1, break_point_hit_count); | 1844 CHECK_EQ(1, break_point_hit_count); |
| 1802 | 1845 |
| 1803 v8::Debug::SetDebugEventListener(NULL); | 1846 v8::Debug::SetDebugEventListener(NULL); |
| 1804 CheckDebuggerUnloaded(); | 1847 CheckDebuggerUnloaded(); |
| 1805 } | 1848 } |
| 1806 | 1849 |
| 1807 | 1850 |
| 1808 // Test when several scripts has the same script data | 1851 // Test when several scripts has the same script data |
| 1809 TEST(ScriptBreakPointMultiple) { | 1852 TEST(ScriptBreakPointMultiple) { |
| 1810 break_point_hit_count = 0; | 1853 break_point_hit_count = 0; |
| 1811 DebugLocalContext env; | 1854 DebugLocalContext env; |
| 1812 v8::HandleScope scope(env->GetIsolate()); | 1855 v8::HandleScope scope(env->GetIsolate()); |
| 1813 env.ExposeDebug(); | 1856 env.ExposeDebug(); |
| 1814 | 1857 |
| 1815 v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); | 1858 v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); |
| 1816 | 1859 |
| 1860 v8::Local<v8::Context> context = env.context(); |
| 1817 v8::Local<v8::Function> f; | 1861 v8::Local<v8::Function> f; |
| 1818 v8::Local<v8::String> script_f = | 1862 v8::Local<v8::String> script_f = v8_str(env->GetIsolate(), |
| 1819 v8::String::NewFromUtf8(env->GetIsolate(), | 1863 "function f() {\n" |
| 1820 "function f() {\n" | 1864 " a = 0; // line 1\n" |
| 1821 " a = 0; // line 1\n" | 1865 "}"); |
| 1822 "}"); | |
| 1823 | 1866 |
| 1824 v8::Local<v8::Function> g; | 1867 v8::Local<v8::Function> g; |
| 1825 v8::Local<v8::String> script_g = | 1868 v8::Local<v8::String> script_g = v8_str(env->GetIsolate(), |
| 1826 v8::String::NewFromUtf8(env->GetIsolate(), | 1869 "function g() {\n" |
| 1827 "function g() {\n" | 1870 " b = 0; // line 1\n" |
| 1828 " b = 0; // line 1\n" | 1871 "}"); |
| 1829 "}"); | |
| 1830 | 1872 |
| 1831 v8::ScriptOrigin origin = | 1873 v8::ScriptOrigin origin = v8::ScriptOrigin(v8_str(env->GetIsolate(), "test")); |
| 1832 v8::ScriptOrigin(v8::String::NewFromUtf8(env->GetIsolate(), "test")); | |
| 1833 | 1874 |
| 1834 // Set a script break point before the scripts are loaded. | 1875 // Set a script break point before the scripts are loaded. |
| 1835 int sbp = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test", 1, 0); | 1876 int sbp = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test", 1, 0); |
| 1836 | 1877 |
| 1837 // Compile the scripts with same script data and get the functions. | 1878 // Compile the scripts with same script data and get the functions. |
| 1838 v8::Script::Compile(script_f, &origin)->Run(); | 1879 v8::Script::Compile(context, script_f, &origin) |
| 1880 .ToLocalChecked() |
| 1881 ->Run(context) |
| 1882 .ToLocalChecked(); |
| 1839 f = v8::Local<v8::Function>::Cast( | 1883 f = v8::Local<v8::Function>::Cast( |
| 1840 env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); | 1884 env->Global() |
| 1841 v8::Script::Compile(script_g, &origin)->Run(); | 1885 ->Get(context, v8_str(env->GetIsolate(), "f")) |
| 1886 .ToLocalChecked()); |
| 1887 v8::Script::Compile(context, script_g, &origin) |
| 1888 .ToLocalChecked() |
| 1889 ->Run(context) |
| 1890 .ToLocalChecked(); |
| 1842 g = v8::Local<v8::Function>::Cast( | 1891 g = v8::Local<v8::Function>::Cast( |
| 1843 env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "g"))); | 1892 env->Global() |
| 1893 ->Get(context, v8_str(env->GetIsolate(), "g")) |
| 1894 .ToLocalChecked()); |
| 1844 | 1895 |
| 1845 // Call f and g and check that the script break point is active. | 1896 // Call f and g and check that the script break point is active. |
| 1846 break_point_hit_count = 0; | 1897 break_point_hit_count = 0; |
| 1847 f->Call(env->Global(), 0, NULL); | 1898 f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 1848 CHECK_EQ(1, break_point_hit_count); | 1899 CHECK_EQ(1, break_point_hit_count); |
| 1849 g->Call(env->Global(), 0, NULL); | 1900 g->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 1850 CHECK_EQ(2, break_point_hit_count); | 1901 CHECK_EQ(2, break_point_hit_count); |
| 1851 | 1902 |
| 1852 // Clear the script break point. | 1903 // Clear the script break point. |
| 1853 ClearBreakPointFromJS(env->GetIsolate(), sbp); | 1904 ClearBreakPointFromJS(env->GetIsolate(), sbp); |
| 1854 | 1905 |
| 1855 // Call f and g and check that the script break point is no longer active. | 1906 // Call f and g and check that the script break point is no longer active. |
| 1856 break_point_hit_count = 0; | 1907 break_point_hit_count = 0; |
| 1857 f->Call(env->Global(), 0, NULL); | 1908 f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 1858 CHECK_EQ(0, break_point_hit_count); | 1909 CHECK_EQ(0, break_point_hit_count); |
| 1859 g->Call(env->Global(), 0, NULL); | 1910 g->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 1860 CHECK_EQ(0, break_point_hit_count); | 1911 CHECK_EQ(0, break_point_hit_count); |
| 1861 | 1912 |
| 1862 // Set script break point with the scripts loaded. | 1913 // Set script break point with the scripts loaded. |
| 1863 sbp = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test", 1, 0); | 1914 sbp = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test", 1, 0); |
| 1864 | 1915 |
| 1865 // Call f and g and check that the script break point is active. | 1916 // Call f and g and check that the script break point is active. |
| 1866 break_point_hit_count = 0; | 1917 break_point_hit_count = 0; |
| 1867 f->Call(env->Global(), 0, NULL); | 1918 f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 1868 CHECK_EQ(1, break_point_hit_count); | 1919 CHECK_EQ(1, break_point_hit_count); |
| 1869 g->Call(env->Global(), 0, NULL); | 1920 g->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 1870 CHECK_EQ(2, break_point_hit_count); | 1921 CHECK_EQ(2, break_point_hit_count); |
| 1871 | 1922 |
| 1872 v8::Debug::SetDebugEventListener(NULL); | 1923 v8::Debug::SetDebugEventListener(NULL); |
| 1873 CheckDebuggerUnloaded(); | 1924 CheckDebuggerUnloaded(); |
| 1874 } | 1925 } |
| 1875 | 1926 |
| 1876 | 1927 |
| 1877 // Test the script origin which has both name and line offset. | 1928 // Test the script origin which has both name and line offset. |
| 1878 TEST(ScriptBreakPointLineOffset) { | 1929 TEST(ScriptBreakPointLineOffset) { |
| 1879 break_point_hit_count = 0; | 1930 break_point_hit_count = 0; |
| 1880 DebugLocalContext env; | 1931 DebugLocalContext env; |
| 1881 v8::HandleScope scope(env->GetIsolate()); | 1932 v8::HandleScope scope(env->GetIsolate()); |
| 1882 env.ExposeDebug(); | 1933 env.ExposeDebug(); |
| 1883 | 1934 |
| 1884 v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); | 1935 v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); |
| 1885 | 1936 |
| 1937 v8::Local<v8::Context> context = env.context(); |
| 1886 v8::Local<v8::Function> f; | 1938 v8::Local<v8::Function> f; |
| 1887 v8::Local<v8::String> script = v8::String::NewFromUtf8( | 1939 v8::Local<v8::String> script = |
| 1888 env->GetIsolate(), | 1940 v8_str(env->GetIsolate(), |
| 1889 "function f() {\n" | 1941 "function f() {\n" |
| 1890 " a = 0; // line 8 as this script has line offset 7\n" | 1942 " a = 0; // line 8 as this script has line offset 7\n" |
| 1891 " b = 0; // line 9 as this script has line offset 7\n" | 1943 " b = 0; // line 9 as this script has line offset 7\n" |
| 1892 "}"); | 1944 "}"); |
| 1893 | 1945 |
| 1894 // Create script origin both name and line offset. | 1946 // Create script origin both name and line offset. |
| 1895 v8::ScriptOrigin origin( | 1947 v8::ScriptOrigin origin(v8_str(env->GetIsolate(), "test.html"), |
| 1896 v8::String::NewFromUtf8(env->GetIsolate(), "test.html"), | 1948 v8::Integer::New(env->GetIsolate(), 7)); |
| 1897 v8::Integer::New(env->GetIsolate(), 7)); | |
| 1898 | 1949 |
| 1899 // Set two script break points before the script is loaded. | 1950 // Set two script break points before the script is loaded. |
| 1900 int sbp1 = | 1951 int sbp1 = |
| 1901 SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 8, 0); | 1952 SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 8, 0); |
| 1902 int sbp2 = | 1953 int sbp2 = |
| 1903 SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 9, 0); | 1954 SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 9, 0); |
| 1904 | 1955 |
| 1905 // Compile the script and get the function. | 1956 // Compile the script and get the function. |
| 1906 v8::Script::Compile(script, &origin)->Run(); | 1957 v8::Script::Compile(context, script, &origin) |
| 1958 .ToLocalChecked() |
| 1959 ->Run(context) |
| 1960 .ToLocalChecked(); |
| 1907 f = v8::Local<v8::Function>::Cast( | 1961 f = v8::Local<v8::Function>::Cast( |
| 1908 env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); | 1962 env->Global() |
| 1963 ->Get(context, v8_str(env->GetIsolate(), "f")) |
| 1964 .ToLocalChecked()); |
| 1909 | 1965 |
| 1910 // Call f and check that the script break point is active. | 1966 // Call f and check that the script break point is active. |
| 1911 break_point_hit_count = 0; | 1967 break_point_hit_count = 0; |
| 1912 f->Call(env->Global(), 0, NULL); | 1968 f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 1913 CHECK_EQ(2, break_point_hit_count); | 1969 CHECK_EQ(2, break_point_hit_count); |
| 1914 | 1970 |
| 1915 // Clear the script break points. | 1971 // Clear the script break points. |
| 1916 ClearBreakPointFromJS(env->GetIsolate(), sbp1); | 1972 ClearBreakPointFromJS(env->GetIsolate(), sbp1); |
| 1917 ClearBreakPointFromJS(env->GetIsolate(), sbp2); | 1973 ClearBreakPointFromJS(env->GetIsolate(), sbp2); |
| 1918 | 1974 |
| 1919 // Call f and check that no script break points are active. | 1975 // Call f and check that no script break points are active. |
| 1920 break_point_hit_count = 0; | 1976 break_point_hit_count = 0; |
| 1921 f->Call(env->Global(), 0, NULL); | 1977 f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 1922 CHECK_EQ(0, break_point_hit_count); | 1978 CHECK_EQ(0, break_point_hit_count); |
| 1923 | 1979 |
| 1924 // Set a script break point with the script loaded. | 1980 // Set a script break point with the script loaded. |
| 1925 sbp1 = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 9, 0); | 1981 sbp1 = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 9, 0); |
| 1926 | 1982 |
| 1927 // Call f and check that the script break point is active. | 1983 // Call f and check that the script break point is active. |
| 1928 break_point_hit_count = 0; | 1984 break_point_hit_count = 0; |
| 1929 f->Call(env->Global(), 0, NULL); | 1985 f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 1930 CHECK_EQ(1, break_point_hit_count); | 1986 CHECK_EQ(1, break_point_hit_count); |
| 1931 | 1987 |
| 1932 v8::Debug::SetDebugEventListener(NULL); | 1988 v8::Debug::SetDebugEventListener(NULL); |
| 1933 CheckDebuggerUnloaded(); | 1989 CheckDebuggerUnloaded(); |
| 1934 } | 1990 } |
| 1935 | 1991 |
| 1936 | 1992 |
| 1937 // Test script break points set on lines. | 1993 // Test script break points set on lines. |
| 1938 TEST(ScriptBreakPointLine) { | 1994 TEST(ScriptBreakPointLine) { |
| 1939 DebugLocalContext env; | 1995 DebugLocalContext env; |
| 1940 v8::HandleScope scope(env->GetIsolate()); | 1996 v8::HandleScope scope(env->GetIsolate()); |
| 1941 env.ExposeDebug(); | 1997 env.ExposeDebug(); |
| 1942 | 1998 |
| 1943 // Create a function for checking the function when hitting a break point. | 1999 // Create a function for checking the function when hitting a break point. |
| 1944 frame_function_name = CompileFunction(&env, | 2000 frame_function_name = CompileFunction(&env, |
| 1945 frame_function_name_source, | 2001 frame_function_name_source, |
| 1946 "frame_function_name"); | 2002 "frame_function_name"); |
| 1947 | 2003 |
| 1948 v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); | 2004 v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); |
| 1949 | 2005 |
| 2006 v8::Local<v8::Context> context = env.context(); |
| 1950 v8::Local<v8::Function> f; | 2007 v8::Local<v8::Function> f; |
| 1951 v8::Local<v8::Function> g; | 2008 v8::Local<v8::Function> g; |
| 1952 v8::Local<v8::String> script = | 2009 v8::Local<v8::String> script = |
| 1953 v8::String::NewFromUtf8(env->GetIsolate(), | 2010 v8_str(env->GetIsolate(), |
| 1954 "a = 0 // line 0\n" | 2011 "a = 0 // line 0\n" |
| 1955 "function f() {\n" | 2012 "function f() {\n" |
| 1956 " a = 1; // line 2\n" | 2013 " a = 1; // line 2\n" |
| 1957 "}\n" | 2014 "}\n" |
| 1958 " a = 2; // line 4\n" | 2015 " a = 2; // line 4\n" |
| 1959 " /* xx */ function g() { // line 5\n" | 2016 " /* xx */ function g() { // line 5\n" |
| 1960 " function h() { // line 6\n" | 2017 " function h() { // line 6\n" |
| 1961 " a = 3; // line 7\n" | 2018 " a = 3; // line 7\n" |
| 1962 " }\n" | 2019 " }\n" |
| 1963 " h(); // line 9\n" | 2020 " h(); // line 9\n" |
| 1964 " a = 4; // line 10\n" | 2021 " a = 4; // line 10\n" |
| 1965 " }\n" | 2022 " }\n" |
| 1966 " a=5; // line 12"); | 2023 " a=5; // line 12"); |
| 1967 | 2024 |
| 1968 // Set a couple script break point before the script is loaded. | 2025 // Set a couple script break point before the script is loaded. |
| 1969 int sbp1 = | 2026 int sbp1 = |
| 1970 SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 0, -1); | 2027 SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 0, -1); |
| 1971 int sbp2 = | 2028 int sbp2 = |
| 1972 SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 1, -1); | 2029 SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 1, -1); |
| 1973 int sbp3 = | 2030 int sbp3 = |
| 1974 SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 5, -1); | 2031 SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 5, -1); |
| 1975 | 2032 |
| 1976 // Compile the script and get the function. | 2033 // Compile the script and get the function. |
| 1977 break_point_hit_count = 0; | 2034 break_point_hit_count = 0; |
| 1978 v8::ScriptOrigin origin( | 2035 v8::ScriptOrigin origin(v8_str(env->GetIsolate(), "test.html"), |
| 1979 v8::String::NewFromUtf8(env->GetIsolate(), "test.html"), | 2036 v8::Integer::New(env->GetIsolate(), 0)); |
| 1980 v8::Integer::New(env->GetIsolate(), 0)); | 2037 v8::Script::Compile(context, script, &origin) |
| 1981 v8::Script::Compile(script, &origin)->Run(); | 2038 .ToLocalChecked() |
| 2039 ->Run(context) |
| 2040 .ToLocalChecked(); |
| 1982 f = v8::Local<v8::Function>::Cast( | 2041 f = v8::Local<v8::Function>::Cast( |
| 1983 env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); | 2042 env->Global() |
| 2043 ->Get(context, v8_str(env->GetIsolate(), "f")) |
| 2044 .ToLocalChecked()); |
| 1984 g = v8::Local<v8::Function>::Cast( | 2045 g = v8::Local<v8::Function>::Cast( |
| 1985 env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "g"))); | 2046 env->Global() |
| 2047 ->Get(context, v8_str(env->GetIsolate(), "g")) |
| 2048 .ToLocalChecked()); |
| 1986 | 2049 |
| 1987 // Check that a break point was hit when the script was run. | 2050 // Check that a break point was hit when the script was run. |
| 1988 CHECK_EQ(1, break_point_hit_count); | 2051 CHECK_EQ(1, break_point_hit_count); |
| 1989 CHECK_EQ(0, StrLength(last_function_hit)); | 2052 CHECK_EQ(0, StrLength(last_function_hit)); |
| 1990 | 2053 |
| 1991 // Call f and check that the script break point. | 2054 // Call f and check that the script break point. |
| 1992 f->Call(env->Global(), 0, NULL); | 2055 f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 1993 CHECK_EQ(2, break_point_hit_count); | 2056 CHECK_EQ(2, break_point_hit_count); |
| 1994 CHECK_EQ(0, strcmp("f", last_function_hit)); | 2057 CHECK_EQ(0, strcmp("f", last_function_hit)); |
| 1995 | 2058 |
| 1996 // Call g and check that the script break point. | 2059 // Call g and check that the script break point. |
| 1997 g->Call(env->Global(), 0, NULL); | 2060 g->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 1998 CHECK_EQ(3, break_point_hit_count); | 2061 CHECK_EQ(3, break_point_hit_count); |
| 1999 CHECK_EQ(0, strcmp("g", last_function_hit)); | 2062 CHECK_EQ(0, strcmp("g", last_function_hit)); |
| 2000 | 2063 |
| 2001 // Clear the script break point on g and set one on h. | 2064 // Clear the script break point on g and set one on h. |
| 2002 ClearBreakPointFromJS(env->GetIsolate(), sbp3); | 2065 ClearBreakPointFromJS(env->GetIsolate(), sbp3); |
| 2003 int sbp4 = | 2066 int sbp4 = |
| 2004 SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 6, -1); | 2067 SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 6, -1); |
| 2005 | 2068 |
| 2006 // Call g and check that the script break point in h is hit. | 2069 // Call g and check that the script break point in h is hit. |
| 2007 g->Call(env->Global(), 0, NULL); | 2070 g->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 2008 CHECK_EQ(4, break_point_hit_count); | 2071 CHECK_EQ(4, break_point_hit_count); |
| 2009 CHECK_EQ(0, strcmp("h", last_function_hit)); | 2072 CHECK_EQ(0, strcmp("h", last_function_hit)); |
| 2010 | 2073 |
| 2011 // Clear break points in f and h. Set a new one in the script between | 2074 // Clear break points in f and h. Set a new one in the script between |
| 2012 // functions f and g and test that there is no break points in f and g any | 2075 // functions f and g and test that there is no break points in f and g any |
| 2013 // more. | 2076 // more. |
| 2014 ClearBreakPointFromJS(env->GetIsolate(), sbp2); | 2077 ClearBreakPointFromJS(env->GetIsolate(), sbp2); |
| 2015 ClearBreakPointFromJS(env->GetIsolate(), sbp4); | 2078 ClearBreakPointFromJS(env->GetIsolate(), sbp4); |
| 2016 int sbp5 = | 2079 int sbp5 = |
| 2017 SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 4, -1); | 2080 SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 4, -1); |
| 2018 break_point_hit_count = 0; | 2081 break_point_hit_count = 0; |
| 2019 f->Call(env->Global(), 0, NULL); | 2082 f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 2020 g->Call(env->Global(), 0, NULL); | 2083 g->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 2021 CHECK_EQ(0, break_point_hit_count); | 2084 CHECK_EQ(0, break_point_hit_count); |
| 2022 | 2085 |
| 2023 // Reload the script which should hit two break points. | 2086 // Reload the script which should hit two break points. |
| 2024 break_point_hit_count = 0; | 2087 break_point_hit_count = 0; |
| 2025 v8::Script::Compile(script, &origin)->Run(); | 2088 v8::Script::Compile(context, script, &origin) |
| 2089 .ToLocalChecked() |
| 2090 ->Run(context) |
| 2091 .ToLocalChecked(); |
| 2026 CHECK_EQ(2, break_point_hit_count); | 2092 CHECK_EQ(2, break_point_hit_count); |
| 2027 CHECK_EQ(0, StrLength(last_function_hit)); | 2093 CHECK_EQ(0, StrLength(last_function_hit)); |
| 2028 | 2094 |
| 2029 // Set a break point in the code after the last function decleration. | 2095 // Set a break point in the code after the last function decleration. |
| 2030 int sbp6 = | 2096 int sbp6 = |
| 2031 SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 12, -1); | 2097 SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 12, -1); |
| 2032 | 2098 |
| 2033 // Reload the script which should hit three break points. | 2099 // Reload the script which should hit three break points. |
| 2034 break_point_hit_count = 0; | 2100 break_point_hit_count = 0; |
| 2035 v8::Script::Compile(script, &origin)->Run(); | 2101 v8::Script::Compile(context, script, &origin) |
| 2102 .ToLocalChecked() |
| 2103 ->Run(context) |
| 2104 .ToLocalChecked(); |
| 2036 CHECK_EQ(3, break_point_hit_count); | 2105 CHECK_EQ(3, break_point_hit_count); |
| 2037 CHECK_EQ(0, StrLength(last_function_hit)); | 2106 CHECK_EQ(0, StrLength(last_function_hit)); |
| 2038 | 2107 |
| 2039 // Clear the last break points, and reload the script which should not hit any | 2108 // Clear the last break points, and reload the script which should not hit any |
| 2040 // break points. | 2109 // break points. |
| 2041 ClearBreakPointFromJS(env->GetIsolate(), sbp1); | 2110 ClearBreakPointFromJS(env->GetIsolate(), sbp1); |
| 2042 ClearBreakPointFromJS(env->GetIsolate(), sbp5); | 2111 ClearBreakPointFromJS(env->GetIsolate(), sbp5); |
| 2043 ClearBreakPointFromJS(env->GetIsolate(), sbp6); | 2112 ClearBreakPointFromJS(env->GetIsolate(), sbp6); |
| 2044 break_point_hit_count = 0; | 2113 break_point_hit_count = 0; |
| 2045 v8::Script::Compile(script, &origin)->Run(); | 2114 v8::Script::Compile(context, script, &origin) |
| 2115 .ToLocalChecked() |
| 2116 ->Run(context) |
| 2117 .ToLocalChecked(); |
| 2046 CHECK_EQ(0, break_point_hit_count); | 2118 CHECK_EQ(0, break_point_hit_count); |
| 2047 | 2119 |
| 2048 v8::Debug::SetDebugEventListener(NULL); | 2120 v8::Debug::SetDebugEventListener(NULL); |
| 2049 CheckDebuggerUnloaded(); | 2121 CheckDebuggerUnloaded(); |
| 2050 } | 2122 } |
| 2051 | 2123 |
| 2052 | 2124 |
| 2053 // Test top level script break points set on lines. | 2125 // Test top level script break points set on lines. |
| 2054 TEST(ScriptBreakPointLineTopLevel) { | 2126 TEST(ScriptBreakPointLineTopLevel) { |
| 2055 DebugLocalContext env; | 2127 DebugLocalContext env; |
| 2056 v8::HandleScope scope(env->GetIsolate()); | 2128 v8::HandleScope scope(env->GetIsolate()); |
| 2057 env.ExposeDebug(); | 2129 env.ExposeDebug(); |
| 2058 | 2130 |
| 2059 v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); | 2131 v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); |
| 2060 | 2132 |
| 2133 v8::Local<v8::Context> context = env.context(); |
| 2061 v8::Local<v8::String> script = | 2134 v8::Local<v8::String> script = |
| 2062 v8::String::NewFromUtf8(env->GetIsolate(), | 2135 v8_str(env->GetIsolate(), |
| 2063 "function f() {\n" | 2136 "function f() {\n" |
| 2064 " a = 1; // line 1\n" | 2137 " a = 1; // line 1\n" |
| 2065 "}\n" | 2138 "}\n" |
| 2066 "a = 2; // line 3\n"); | 2139 "a = 2; // line 3\n"); |
| 2067 v8::Local<v8::Function> f; | 2140 v8::Local<v8::Function> f; |
| 2068 { | 2141 { |
| 2069 v8::HandleScope scope(env->GetIsolate()); | 2142 v8::HandleScope scope(env->GetIsolate()); |
| 2070 CompileRunWithOrigin(script, "test.html"); | 2143 CompileRunWithOrigin(script, "test.html"); |
| 2071 } | 2144 } |
| 2072 f = v8::Local<v8::Function>::Cast( | 2145 f = v8::Local<v8::Function>::Cast( |
| 2073 env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); | 2146 env->Global() |
| 2147 ->Get(context, v8_str(env->GetIsolate(), "f")) |
| 2148 .ToLocalChecked()); |
| 2074 | 2149 |
| 2075 CcTest::heap()->CollectAllGarbage(); | 2150 CcTest::heap()->CollectAllGarbage(); |
| 2076 | 2151 |
| 2077 SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 3, -1); | 2152 SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 3, -1); |
| 2078 | 2153 |
| 2079 // Call f and check that there was no break points. | 2154 // Call f and check that there was no break points. |
| 2080 break_point_hit_count = 0; | 2155 break_point_hit_count = 0; |
| 2081 f->Call(env->Global(), 0, NULL); | 2156 f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 2082 CHECK_EQ(0, break_point_hit_count); | 2157 CHECK_EQ(0, break_point_hit_count); |
| 2083 | 2158 |
| 2084 // Recompile and run script and check that break point was hit. | 2159 // Recompile and run script and check that break point was hit. |
| 2085 break_point_hit_count = 0; | 2160 break_point_hit_count = 0; |
| 2086 CompileRunWithOrigin(script, "test.html"); | 2161 CompileRunWithOrigin(script, "test.html"); |
| 2087 CHECK_EQ(1, break_point_hit_count); | 2162 CHECK_EQ(1, break_point_hit_count); |
| 2088 | 2163 |
| 2089 // Call f and check that there are still no break points. | 2164 // Call f and check that there are still no break points. |
| 2090 break_point_hit_count = 0; | 2165 break_point_hit_count = 0; |
| 2091 f = v8::Local<v8::Function>::Cast( | 2166 f = v8::Local<v8::Function>::Cast( |
| 2092 env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); | 2167 env->Global() |
| 2168 ->Get(context, v8_str(env->GetIsolate(), "f")) |
| 2169 .ToLocalChecked()); |
| 2093 CHECK_EQ(0, break_point_hit_count); | 2170 CHECK_EQ(0, break_point_hit_count); |
| 2094 | 2171 |
| 2095 v8::Debug::SetDebugEventListener(NULL); | 2172 v8::Debug::SetDebugEventListener(NULL); |
| 2096 CheckDebuggerUnloaded(); | 2173 CheckDebuggerUnloaded(); |
| 2097 } | 2174 } |
| 2098 | 2175 |
| 2099 | 2176 |
| 2100 // Test that it is possible to add and remove break points in a top level | 2177 // Test that it is possible to add and remove break points in a top level |
| 2101 // function which has no references but has not been collected yet. | 2178 // function which has no references but has not been collected yet. |
| 2102 TEST(ScriptBreakPointTopLevelCrash) { | 2179 TEST(ScriptBreakPointTopLevelCrash) { |
| 2103 DebugLocalContext env; | 2180 DebugLocalContext env; |
| 2104 v8::HandleScope scope(env->GetIsolate()); | 2181 v8::HandleScope scope(env->GetIsolate()); |
| 2105 env.ExposeDebug(); | 2182 env.ExposeDebug(); |
| 2106 | 2183 |
| 2107 v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); | 2184 v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); |
| 2108 | 2185 |
| 2109 v8::Local<v8::String> script_source = | 2186 v8::Local<v8::String> script_source = v8_str(env->GetIsolate(), |
| 2110 v8::String::NewFromUtf8(env->GetIsolate(), | 2187 "function f() {\n" |
| 2111 "function f() {\n" | 2188 " return 0;\n" |
| 2112 " return 0;\n" | 2189 "}\n" |
| 2113 "}\n" | 2190 "f()"); |
| 2114 "f()"); | |
| 2115 | 2191 |
| 2116 int sbp1 = | 2192 int sbp1 = |
| 2117 SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 3, -1); | 2193 SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 3, -1); |
| 2118 { | 2194 { |
| 2119 v8::HandleScope scope(env->GetIsolate()); | 2195 v8::HandleScope scope(env->GetIsolate()); |
| 2120 break_point_hit_count = 0; | 2196 break_point_hit_count = 0; |
| 2121 CompileRunWithOrigin(script_source, "test.html"); | 2197 CompileRunWithOrigin(script_source, "test.html"); |
| 2122 CHECK_EQ(1, break_point_hit_count); | 2198 CHECK_EQ(1, break_point_hit_count); |
| 2123 } | 2199 } |
| 2124 | 2200 |
| 2125 int sbp2 = | 2201 int sbp2 = |
| 2126 SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 3, -1); | 2202 SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 3, -1); |
| 2127 ClearBreakPointFromJS(env->GetIsolate(), sbp1); | 2203 ClearBreakPointFromJS(env->GetIsolate(), sbp1); |
| 2128 ClearBreakPointFromJS(env->GetIsolate(), sbp2); | 2204 ClearBreakPointFromJS(env->GetIsolate(), sbp2); |
| 2129 | 2205 |
| 2130 v8::Debug::SetDebugEventListener(NULL); | 2206 v8::Debug::SetDebugEventListener(NULL); |
| 2131 CheckDebuggerUnloaded(); | 2207 CheckDebuggerUnloaded(); |
| 2132 } | 2208 } |
| 2133 | 2209 |
| 2134 | 2210 |
| 2135 // Test that it is possible to remove the last break point for a function | 2211 // Test that it is possible to remove the last break point for a function |
| 2136 // inside the break handling of that break point. | 2212 // inside the break handling of that break point. |
| 2137 TEST(RemoveBreakPointInBreak) { | 2213 TEST(RemoveBreakPointInBreak) { |
| 2138 DebugLocalContext env; | 2214 DebugLocalContext env; |
| 2139 v8::HandleScope scope(env->GetIsolate()); | 2215 v8::HandleScope scope(env->GetIsolate()); |
| 2140 | 2216 |
| 2217 v8::Local<v8::Context> context = env.context(); |
| 2141 v8::Local<v8::Function> foo = | 2218 v8::Local<v8::Function> foo = |
| 2142 CompileFunction(&env, "function foo(){a=1;}", "foo"); | 2219 CompileFunction(&env, "function foo(){a=1;}", "foo"); |
| 2143 | 2220 |
| 2144 // Register the debug event listener pasing the function | 2221 // Register the debug event listener pasing the function |
| 2145 v8::Debug::SetDebugEventListener(DebugEventRemoveBreakPoint, foo); | 2222 v8::Debug::SetDebugEventListener(DebugEventRemoveBreakPoint, foo); |
| 2146 | 2223 |
| 2147 debug_event_remove_break_point = SetBreakPoint(foo, 0); | 2224 debug_event_remove_break_point = SetBreakPoint(foo, 0); |
| 2148 | 2225 |
| 2149 break_point_hit_count = 0; | 2226 break_point_hit_count = 0; |
| 2150 foo->Call(env->Global(), 0, NULL); | 2227 foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 2151 CHECK_EQ(1, break_point_hit_count); | 2228 CHECK_EQ(1, break_point_hit_count); |
| 2152 | 2229 |
| 2153 break_point_hit_count = 0; | 2230 break_point_hit_count = 0; |
| 2154 foo->Call(env->Global(), 0, NULL); | 2231 foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 2155 CHECK_EQ(0, break_point_hit_count); | 2232 CHECK_EQ(0, break_point_hit_count); |
| 2156 | 2233 |
| 2157 v8::Debug::SetDebugEventListener(NULL); | 2234 v8::Debug::SetDebugEventListener(NULL); |
| 2158 CheckDebuggerUnloaded(); | 2235 CheckDebuggerUnloaded(); |
| 2159 } | 2236 } |
| 2160 | 2237 |
| 2161 | 2238 |
| 2162 // Test that the debugger statement causes a break. | 2239 // Test that the debugger statement causes a break. |
| 2163 TEST(DebuggerStatement) { | 2240 TEST(DebuggerStatement) { |
| 2164 break_point_hit_count = 0; | 2241 break_point_hit_count = 0; |
| 2165 DebugLocalContext env; | 2242 DebugLocalContext env; |
| 2166 v8::HandleScope scope(env->GetIsolate()); | 2243 v8::HandleScope scope(env->GetIsolate()); |
| 2167 v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); | 2244 v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); |
| 2245 v8::Local<v8::Context> context = env.context(); |
| 2246 v8::Script::Compile(context, |
| 2247 v8_str(env->GetIsolate(), "function bar(){debugger}")) |
| 2248 .ToLocalChecked() |
| 2249 ->Run(context) |
| 2250 .ToLocalChecked(); |
| 2168 v8::Script::Compile( | 2251 v8::Script::Compile( |
| 2169 v8::String::NewFromUtf8(env->GetIsolate(), "function bar(){debugger}")) | 2252 context, v8_str(env->GetIsolate(), "function foo(){debugger;debugger;}")) |
| 2170 ->Run(); | 2253 .ToLocalChecked() |
| 2171 v8::Script::Compile( | 2254 ->Run(context) |
| 2172 v8::String::NewFromUtf8(env->GetIsolate(), | 2255 .ToLocalChecked(); |
| 2173 "function foo(){debugger;debugger;}"))->Run(); | |
| 2174 v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast( | 2256 v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast( |
| 2175 env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "foo"))); | 2257 env->Global() |
| 2258 ->Get(context, v8_str(env->GetIsolate(), "foo")) |
| 2259 .ToLocalChecked()); |
| 2176 v8::Local<v8::Function> bar = v8::Local<v8::Function>::Cast( | 2260 v8::Local<v8::Function> bar = v8::Local<v8::Function>::Cast( |
| 2177 env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "bar"))); | 2261 env->Global() |
| 2262 ->Get(context, v8_str(env->GetIsolate(), "bar")) |
| 2263 .ToLocalChecked()); |
| 2178 | 2264 |
| 2179 // Run function with debugger statement | 2265 // Run function with debugger statement |
| 2180 bar->Call(env->Global(), 0, NULL); | 2266 bar->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 2181 CHECK_EQ(1, break_point_hit_count); | 2267 CHECK_EQ(1, break_point_hit_count); |
| 2182 | 2268 |
| 2183 // Run function with two debugger statement | 2269 // Run function with two debugger statement |
| 2184 foo->Call(env->Global(), 0, NULL); | 2270 foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 2185 CHECK_EQ(3, break_point_hit_count); | 2271 CHECK_EQ(3, break_point_hit_count); |
| 2186 | 2272 |
| 2187 v8::Debug::SetDebugEventListener(NULL); | 2273 v8::Debug::SetDebugEventListener(NULL); |
| 2188 CheckDebuggerUnloaded(); | 2274 CheckDebuggerUnloaded(); |
| 2189 } | 2275 } |
| 2190 | 2276 |
| 2191 | 2277 |
| 2192 // Test setting a breakpoint on the debugger statement. | 2278 // Test setting a breakpoint on the debugger statement. |
| 2193 TEST(DebuggerStatementBreakpoint) { | 2279 TEST(DebuggerStatementBreakpoint) { |
| 2194 break_point_hit_count = 0; | 2280 break_point_hit_count = 0; |
| 2195 DebugLocalContext env; | 2281 DebugLocalContext env; |
| 2196 v8::HandleScope scope(env->GetIsolate()); | 2282 v8::HandleScope scope(env->GetIsolate()); |
| 2283 v8::Local<v8::Context> context = env.context(); |
| 2197 v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); | 2284 v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); |
| 2198 v8::Script::Compile( | 2285 v8::Script::Compile(context, |
| 2199 v8::String::NewFromUtf8(env->GetIsolate(), "function foo(){debugger;}")) | 2286 v8_str(env->GetIsolate(), "function foo(){debugger;}")) |
| 2200 ->Run(); | 2287 .ToLocalChecked() |
| 2288 ->Run(context) |
| 2289 .ToLocalChecked(); |
| 2201 v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast( | 2290 v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast( |
| 2202 env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "foo"))); | 2291 env->Global() |
| 2292 ->Get(context, v8_str(env->GetIsolate(), "foo")) |
| 2293 .ToLocalChecked()); |
| 2203 | 2294 |
| 2204 // The debugger statement triggers breakpoint hit | 2295 // The debugger statement triggers breakpoint hit |
| 2205 foo->Call(env->Global(), 0, NULL); | 2296 foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 2206 CHECK_EQ(1, break_point_hit_count); | 2297 CHECK_EQ(1, break_point_hit_count); |
| 2207 | 2298 |
| 2208 int bp = SetBreakPoint(foo, 0); | 2299 int bp = SetBreakPoint(foo, 0); |
| 2209 | 2300 |
| 2210 // Set breakpoint does not duplicate hits | 2301 // Set breakpoint does not duplicate hits |
| 2211 foo->Call(env->Global(), 0, NULL); | 2302 foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 2212 CHECK_EQ(2, break_point_hit_count); | 2303 CHECK_EQ(2, break_point_hit_count); |
| 2213 | 2304 |
| 2214 ClearBreakPoint(bp); | 2305 ClearBreakPoint(bp); |
| 2215 v8::Debug::SetDebugEventListener(NULL); | 2306 v8::Debug::SetDebugEventListener(NULL); |
| 2216 CheckDebuggerUnloaded(); | 2307 CheckDebuggerUnloaded(); |
| 2217 } | 2308 } |
| 2218 | 2309 |
| 2219 | 2310 |
| 2220 // Test that the evaluation of expressions when a break point is hit generates | 2311 // Test that the evaluation of expressions when a break point is hit generates |
| 2221 // the correct results. | 2312 // the correct results. |
| 2222 TEST(DebugEvaluate) { | 2313 TEST(DebugEvaluate) { |
| 2223 DebugLocalContext env; | 2314 DebugLocalContext env; |
| 2224 v8::Isolate* isolate = env->GetIsolate(); | 2315 v8::Isolate* isolate = env->GetIsolate(); |
| 2225 v8::HandleScope scope(isolate); | 2316 v8::HandleScope scope(isolate); |
| 2226 env.ExposeDebug(); | 2317 env.ExposeDebug(); |
| 2227 | 2318 |
| 2228 // Create a function for checking the evaluation when hitting a break point. | 2319 // Create a function for checking the evaluation when hitting a break point. |
| 2229 evaluate_check_function = CompileFunction(&env, | 2320 evaluate_check_function = CompileFunction(&env, |
| 2230 evaluate_check_source, | 2321 evaluate_check_source, |
| 2231 "evaluate_check"); | 2322 "evaluate_check"); |
| 2232 // Register the debug event listener | 2323 // Register the debug event listener |
| 2233 v8::Debug::SetDebugEventListener(DebugEventEvaluate); | 2324 v8::Debug::SetDebugEventListener(DebugEventEvaluate); |
| 2234 | 2325 |
| 2235 // Different expected vaules of x and a when in a break point (u = undefined, | 2326 // Different expected vaules of x and a when in a break point (u = undefined, |
| 2236 // d = Hello, world!). | 2327 // d = Hello, world!). |
| 2237 struct EvaluateCheck checks_uu[] = { | 2328 struct EvaluateCheck checks_uu[] = {{"x", v8::Undefined(isolate)}, |
| 2238 {"x", v8::Undefined(isolate)}, | 2329 {"a", v8::Undefined(isolate)}, |
| 2239 {"a", v8::Undefined(isolate)}, | 2330 {NULL, v8::Local<v8::Value>()}}; |
| 2240 {NULL, v8::Handle<v8::Value>()} | |
| 2241 }; | |
| 2242 struct EvaluateCheck checks_hu[] = { | 2331 struct EvaluateCheck checks_hu[] = { |
| 2243 {"x", v8::String::NewFromUtf8(env->GetIsolate(), "Hello, world!")}, | 2332 {"x", v8_str(env->GetIsolate(), "Hello, world!")}, |
| 2244 {"a", v8::Undefined(isolate)}, | 2333 {"a", v8::Undefined(isolate)}, |
| 2245 {NULL, v8::Handle<v8::Value>()} | 2334 {NULL, v8::Local<v8::Value>()}}; |
| 2246 }; | |
| 2247 struct EvaluateCheck checks_hh[] = { | 2335 struct EvaluateCheck checks_hh[] = { |
| 2248 {"x", v8::String::NewFromUtf8(env->GetIsolate(), "Hello, world!")}, | 2336 {"x", v8_str(env->GetIsolate(), "Hello, world!")}, |
| 2249 {"a", v8::String::NewFromUtf8(env->GetIsolate(), "Hello, world!")}, | 2337 {"a", v8_str(env->GetIsolate(), "Hello, world!")}, |
| 2250 {NULL, v8::Handle<v8::Value>()} | 2338 {NULL, v8::Local<v8::Value>()}}; |
| 2251 }; | |
| 2252 | 2339 |
| 2253 // Simple test function. The "y=0" is in the function foo to provide a break | 2340 // Simple test function. The "y=0" is in the function foo to provide a break |
| 2254 // location. For "y=0" the "y" is at position 15 in the foo function | 2341 // location. For "y=0" the "y" is at position 15 in the foo function |
| 2255 // therefore setting breakpoint at position 15 will break at "y=0" and | 2342 // therefore setting breakpoint at position 15 will break at "y=0" and |
| 2256 // setting it higher will break after. | 2343 // setting it higher will break after. |
| 2257 v8::Local<v8::Function> foo = CompileFunction(&env, | 2344 v8::Local<v8::Function> foo = CompileFunction(&env, |
| 2258 "function foo(x) {" | 2345 "function foo(x) {" |
| 2259 " var a;" | 2346 " var a;" |
| 2260 " y=0;" // To ensure break location 1. | 2347 " y=0;" // To ensure break location 1. |
| 2261 " a=x;" | 2348 " a=x;" |
| 2262 " y=0;" // To ensure break location 2. | 2349 " y=0;" // To ensure break location 2. |
| 2263 "}", | 2350 "}", |
| 2264 "foo"); | 2351 "foo"); |
| 2265 const int foo_break_position_1 = 15; | 2352 const int foo_break_position_1 = 15; |
| 2266 const int foo_break_position_2 = 29; | 2353 const int foo_break_position_2 = 29; |
| 2267 | 2354 |
| 2355 v8::Local<v8::Context> context = env.context(); |
| 2268 // Arguments with one parameter "Hello, world!" | 2356 // Arguments with one parameter "Hello, world!" |
| 2269 v8::Handle<v8::Value> argv_foo[1] = { | 2357 v8::Local<v8::Value> argv_foo[1] = { |
| 2270 v8::String::NewFromUtf8(env->GetIsolate(), "Hello, world!")}; | 2358 v8_str(env->GetIsolate(), "Hello, world!")}; |
| 2271 | 2359 |
| 2272 // Call foo with breakpoint set before a=x and undefined as parameter. | 2360 // Call foo with breakpoint set before a=x and undefined as parameter. |
| 2273 int bp = SetBreakPoint(foo, foo_break_position_1); | 2361 int bp = SetBreakPoint(foo, foo_break_position_1); |
| 2274 checks = checks_uu; | 2362 checks = checks_uu; |
| 2275 foo->Call(env->Global(), 0, NULL); | 2363 foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 2276 | 2364 |
| 2277 // Call foo with breakpoint set before a=x and parameter "Hello, world!". | 2365 // Call foo with breakpoint set before a=x and parameter "Hello, world!". |
| 2278 checks = checks_hu; | 2366 checks = checks_hu; |
| 2279 foo->Call(env->Global(), 1, argv_foo); | 2367 foo->Call(context, env->Global(), 1, argv_foo).ToLocalChecked(); |
| 2280 | 2368 |
| 2281 // Call foo with breakpoint set after a=x and parameter "Hello, world!". | 2369 // Call foo with breakpoint set after a=x and parameter "Hello, world!". |
| 2282 ClearBreakPoint(bp); | 2370 ClearBreakPoint(bp); |
| 2283 SetBreakPoint(foo, foo_break_position_2); | 2371 SetBreakPoint(foo, foo_break_position_2); |
| 2284 checks = checks_hh; | 2372 checks = checks_hh; |
| 2285 foo->Call(env->Global(), 1, argv_foo); | 2373 foo->Call(context, env->Global(), 1, argv_foo).ToLocalChecked(); |
| 2286 | 2374 |
| 2287 // Test that overriding Object.prototype will not interfere into evaluation | 2375 // Test that overriding Object.prototype will not interfere into evaluation |
| 2288 // on call frame. | 2376 // on call frame. |
| 2289 v8::Local<v8::Function> zoo = | 2377 v8::Local<v8::Function> zoo = |
| 2290 CompileFunction(&env, | 2378 CompileFunction(&env, |
| 2291 "x = undefined;" | 2379 "x = undefined;" |
| 2292 "function zoo(t) {" | 2380 "function zoo(t) {" |
| 2293 " var a=x;" | 2381 " var a=x;" |
| 2294 " Object.prototype.x = 42;" | 2382 " Object.prototype.x = 42;" |
| 2295 " x=t;" | 2383 " x=t;" |
| 2296 " y=0;" // To ensure break location. | 2384 " y=0;" // To ensure break location. |
| 2297 " delete Object.prototype.x;" | 2385 " delete Object.prototype.x;" |
| 2298 " x=a;" | 2386 " x=a;" |
| 2299 "}", | 2387 "}", |
| 2300 "zoo"); | 2388 "zoo"); |
| 2301 const int zoo_break_position = 50; | 2389 const int zoo_break_position = 50; |
| 2302 | 2390 |
| 2303 // Arguments with one parameter "Hello, world!" | 2391 // Arguments with one parameter "Hello, world!" |
| 2304 v8::Handle<v8::Value> argv_zoo[1] = { | 2392 v8::Local<v8::Value> argv_zoo[1] = { |
| 2305 v8::String::NewFromUtf8(env->GetIsolate(), "Hello, world!")}; | 2393 v8_str(env->GetIsolate(), "Hello, world!")}; |
| 2306 | 2394 |
| 2307 // Call zoo with breakpoint set at y=0. | 2395 // Call zoo with breakpoint set at y=0. |
| 2308 DebugEventCounterClear(); | 2396 DebugEventCounterClear(); |
| 2309 bp = SetBreakPoint(zoo, zoo_break_position); | 2397 bp = SetBreakPoint(zoo, zoo_break_position); |
| 2310 checks = checks_hu; | 2398 checks = checks_hu; |
| 2311 zoo->Call(env->Global(), 1, argv_zoo); | 2399 zoo->Call(context, env->Global(), 1, argv_zoo).ToLocalChecked(); |
| 2312 CHECK_EQ(1, break_point_hit_count); | 2400 CHECK_EQ(1, break_point_hit_count); |
| 2313 ClearBreakPoint(bp); | 2401 ClearBreakPoint(bp); |
| 2314 | 2402 |
| 2315 // Test function with an inner function. The "y=0" is in function barbar | 2403 // Test function with an inner function. The "y=0" is in function barbar |
| 2316 // to provide a break location. For "y=0" the "y" is at position 8 in the | 2404 // to provide a break location. For "y=0" the "y" is at position 8 in the |
| 2317 // barbar function therefore setting breakpoint at position 8 will break at | 2405 // barbar function therefore setting breakpoint at position 8 will break at |
| 2318 // "y=0" and setting it higher will break after. | 2406 // "y=0" and setting it higher will break after. |
| 2319 v8::Local<v8::Function> bar = CompileFunction(&env, | 2407 v8::Local<v8::Function> bar = CompileFunction(&env, |
| 2320 "y = 0;" | 2408 "y = 0;" |
| 2321 "x = 'Goodbye, world!';" | 2409 "x = 'Goodbye, world!';" |
| 2322 "function bar(x, b) {" | 2410 "function bar(x, b) {" |
| 2323 " var a;" | 2411 " var a;" |
| 2324 " function barbar() {" | 2412 " function barbar() {" |
| 2325 " y=0; /* To ensure break location.*/" | 2413 " y=0; /* To ensure break location.*/" |
| 2326 " a=x;" | 2414 " a=x;" |
| 2327 " };" | 2415 " };" |
| 2328 " debug.Debug.clearAllBreakPoints();" | 2416 " debug.Debug.clearAllBreakPoints();" |
| 2329 " barbar();" | 2417 " barbar();" |
| 2330 " y=0;a=x;" | 2418 " y=0;a=x;" |
| 2331 "}", | 2419 "}", |
| 2332 "bar"); | 2420 "bar"); |
| 2333 const int barbar_break_position = 8; | 2421 const int barbar_break_position = 8; |
| 2334 | 2422 |
| 2335 // Call bar setting breakpoint before a=x in barbar and undefined as | 2423 // Call bar setting breakpoint before a=x in barbar and undefined as |
| 2336 // parameter. | 2424 // parameter. |
| 2337 checks = checks_uu; | 2425 checks = checks_uu; |
| 2338 v8::Handle<v8::Value> argv_bar_1[2] = { | 2426 v8::Local<v8::Value> argv_bar_1[2] = { |
| 2339 v8::Undefined(isolate), | 2427 v8::Undefined(isolate), v8::Number::New(isolate, barbar_break_position)}; |
| 2340 v8::Number::New(isolate, barbar_break_position) | 2428 bar->Call(context, env->Global(), 2, argv_bar_1).ToLocalChecked(); |
| 2341 }; | |
| 2342 bar->Call(env->Global(), 2, argv_bar_1); | |
| 2343 | 2429 |
| 2344 // Call bar setting breakpoint before a=x in barbar and parameter | 2430 // Call bar setting breakpoint before a=x in barbar and parameter |
| 2345 // "Hello, world!". | 2431 // "Hello, world!". |
| 2346 checks = checks_hu; | 2432 checks = checks_hu; |
| 2347 v8::Handle<v8::Value> argv_bar_2[2] = { | 2433 v8::Local<v8::Value> argv_bar_2[2] = { |
| 2348 v8::String::NewFromUtf8(env->GetIsolate(), "Hello, world!"), | 2434 v8_str(env->GetIsolate(), "Hello, world!"), |
| 2349 v8::Number::New(env->GetIsolate(), barbar_break_position) | 2435 v8::Number::New(env->GetIsolate(), barbar_break_position)}; |
| 2350 }; | 2436 bar->Call(context, env->Global(), 2, argv_bar_2).ToLocalChecked(); |
| 2351 bar->Call(env->Global(), 2, argv_bar_2); | |
| 2352 | 2437 |
| 2353 // Call bar setting breakpoint after a=x in barbar and parameter | 2438 // Call bar setting breakpoint after a=x in barbar and parameter |
| 2354 // "Hello, world!". | 2439 // "Hello, world!". |
| 2355 checks = checks_hh; | 2440 checks = checks_hh; |
| 2356 v8::Handle<v8::Value> argv_bar_3[2] = { | 2441 v8::Local<v8::Value> argv_bar_3[2] = { |
| 2357 v8::String::NewFromUtf8(env->GetIsolate(), "Hello, world!"), | 2442 v8_str(env->GetIsolate(), "Hello, world!"), |
| 2358 v8::Number::New(env->GetIsolate(), barbar_break_position + 1) | 2443 v8::Number::New(env->GetIsolate(), barbar_break_position + 1)}; |
| 2359 }; | 2444 bar->Call(context, env->Global(), 2, argv_bar_3).ToLocalChecked(); |
| 2360 bar->Call(env->Global(), 2, argv_bar_3); | |
| 2361 | 2445 |
| 2362 v8::Debug::SetDebugEventListener(NULL); | 2446 v8::Debug::SetDebugEventListener(NULL); |
| 2363 CheckDebuggerUnloaded(); | 2447 CheckDebuggerUnloaded(); |
| 2364 } | 2448 } |
| 2365 | 2449 |
| 2366 | 2450 |
| 2367 int debugEventCount = 0; | 2451 int debugEventCount = 0; |
| 2368 static void CheckDebugEvent(const v8::Debug::EventDetails& eventDetails) { | 2452 static void CheckDebugEvent(const v8::Debug::EventDetails& eventDetails) { |
| 2369 if (eventDetails.GetEvent() == v8::Break) ++debugEventCount; | 2453 if (eventDetails.GetEvent() == v8::Break) ++debugEventCount; |
| 2370 } | 2454 } |
| 2371 | 2455 |
| 2372 | 2456 |
| 2373 // Test that the conditional breakpoints work event if code generation from | 2457 // Test that the conditional breakpoints work event if code generation from |
| 2374 // strings is prohibited in the debugee context. | 2458 // strings is prohibited in the debugee context. |
| 2375 TEST(ConditionalBreakpointWithCodeGenerationDisallowed) { | 2459 TEST(ConditionalBreakpointWithCodeGenerationDisallowed) { |
| 2376 DebugLocalContext env; | 2460 DebugLocalContext env; |
| 2377 v8::HandleScope scope(env->GetIsolate()); | 2461 v8::HandleScope scope(env->GetIsolate()); |
| 2378 env.ExposeDebug(); | 2462 env.ExposeDebug(); |
| 2379 | 2463 |
| 2380 v8::Debug::SetDebugEventListener(CheckDebugEvent); | 2464 v8::Debug::SetDebugEventListener(CheckDebugEvent); |
| 2381 | 2465 |
| 2466 v8::Local<v8::Context> context = env.context(); |
| 2382 v8::Local<v8::Function> foo = CompileFunction(&env, | 2467 v8::Local<v8::Function> foo = CompileFunction(&env, |
| 2383 "function foo(x) {\n" | 2468 "function foo(x) {\n" |
| 2384 " var s = 'String value2';\n" | 2469 " var s = 'String value2';\n" |
| 2385 " return s + x;\n" | 2470 " return s + x;\n" |
| 2386 "}", | 2471 "}", |
| 2387 "foo"); | 2472 "foo"); |
| 2388 | 2473 |
| 2389 // Set conditional breakpoint with condition 'true'. | 2474 // Set conditional breakpoint with condition 'true'. |
| 2390 CompileRun("debug.Debug.setBreakPoint(foo, 2, 0, 'true')"); | 2475 CompileRun("debug.Debug.setBreakPoint(foo, 2, 0, 'true')"); |
| 2391 | 2476 |
| 2392 debugEventCount = 0; | 2477 debugEventCount = 0; |
| 2393 env->AllowCodeGenerationFromStrings(false); | 2478 env->AllowCodeGenerationFromStrings(false); |
| 2394 foo->Call(env->Global(), 0, NULL); | 2479 foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 2395 CHECK_EQ(1, debugEventCount); | 2480 CHECK_EQ(1, debugEventCount); |
| 2396 | 2481 |
| 2397 v8::Debug::SetDebugEventListener(NULL); | 2482 v8::Debug::SetDebugEventListener(NULL); |
| 2398 CheckDebuggerUnloaded(); | 2483 CheckDebuggerUnloaded(); |
| 2399 } | 2484 } |
| 2400 | 2485 |
| 2401 | 2486 |
| 2402 bool checkedDebugEvals = true; | 2487 bool checkedDebugEvals = true; |
| 2403 v8::Handle<v8::Function> checkGlobalEvalFunction; | 2488 v8::Local<v8::Function> checkGlobalEvalFunction; |
| 2404 v8::Handle<v8::Function> checkFrameEvalFunction; | 2489 v8::Local<v8::Function> checkFrameEvalFunction; |
| 2405 static void CheckDebugEval(const v8::Debug::EventDetails& eventDetails) { | 2490 static void CheckDebugEval(const v8::Debug::EventDetails& eventDetails) { |
| 2406 if (eventDetails.GetEvent() == v8::Break) { | 2491 if (eventDetails.GetEvent() == v8::Break) { |
| 2407 ++debugEventCount; | 2492 ++debugEventCount; |
| 2408 v8::HandleScope handleScope(CcTest::isolate()); | 2493 v8::HandleScope handleScope(CcTest::isolate()); |
| 2409 | 2494 |
| 2410 v8::Handle<v8::Value> args[] = { eventDetails.GetExecutionState() }; | 2495 v8::Local<v8::Value> args[] = {eventDetails.GetExecutionState()}; |
| 2411 CHECK(checkGlobalEvalFunction->Call( | 2496 CHECK( |
| 2412 eventDetails.GetEventContext()->Global(), 1, args)->IsTrue()); | 2497 checkGlobalEvalFunction->Call(eventDetails.GetEventContext(), |
| 2413 CHECK(checkFrameEvalFunction->Call( | 2498 eventDetails.GetEventContext()->Global(), |
| 2414 eventDetails.GetEventContext()->Global(), 1, args)->IsTrue()); | 2499 1, args) |
| 2500 .ToLocalChecked() |
| 2501 ->IsTrue()); |
| 2502 CHECK(checkFrameEvalFunction->Call(eventDetails.GetEventContext(), |
| 2503 eventDetails.GetEventContext()->Global(), |
| 2504 1, args) |
| 2505 .ToLocalChecked() |
| 2506 ->IsTrue()); |
| 2415 } | 2507 } |
| 2416 } | 2508 } |
| 2417 | 2509 |
| 2418 | 2510 |
| 2419 // Test that the evaluation of expressions when a break point is hit generates | 2511 // Test that the evaluation of expressions when a break point is hit generates |
| 2420 // the correct results in case code generation from strings is disallowed in the | 2512 // the correct results in case code generation from strings is disallowed in the |
| 2421 // debugee context. | 2513 // debugee context. |
| 2422 TEST(DebugEvaluateWithCodeGenerationDisallowed) { | 2514 TEST(DebugEvaluateWithCodeGenerationDisallowed) { |
| 2423 DebugLocalContext env; | 2515 DebugLocalContext env; |
| 2424 v8::HandleScope scope(env->GetIsolate()); | 2516 v8::HandleScope scope(env->GetIsolate()); |
| 2425 env.ExposeDebug(); | 2517 env.ExposeDebug(); |
| 2426 | 2518 |
| 2427 v8::Debug::SetDebugEventListener(CheckDebugEval); | 2519 v8::Debug::SetDebugEventListener(CheckDebugEval); |
| 2428 | 2520 |
| 2521 v8::Local<v8::Context> context = env.context(); |
| 2429 v8::Local<v8::Function> foo = CompileFunction(&env, | 2522 v8::Local<v8::Function> foo = CompileFunction(&env, |
| 2430 "var global = 'Global';\n" | 2523 "var global = 'Global';\n" |
| 2431 "function foo(x) {\n" | 2524 "function foo(x) {\n" |
| 2432 " var local = 'Local';\n" | 2525 " var local = 'Local';\n" |
| 2433 " debugger;\n" | 2526 " debugger;\n" |
| 2434 " return local + x;\n" | 2527 " return local + x;\n" |
| 2435 "}", | 2528 "}", |
| 2436 "foo"); | 2529 "foo"); |
| 2437 checkGlobalEvalFunction = CompileFunction(&env, | 2530 checkGlobalEvalFunction = CompileFunction(&env, |
| 2438 "function checkGlobalEval(exec_state) {\n" | 2531 "function checkGlobalEval(exec_state) {\n" |
| 2439 " return exec_state.evaluateGlobal('global').value() === 'Global';\n" | 2532 " return exec_state.evaluateGlobal('global').value() === 'Global';\n" |
| 2440 "}", | 2533 "}", |
| 2441 "checkGlobalEval"); | 2534 "checkGlobalEval"); |
| 2442 | 2535 |
| 2443 checkFrameEvalFunction = CompileFunction(&env, | 2536 checkFrameEvalFunction = CompileFunction(&env, |
| 2444 "function checkFrameEval(exec_state) {\n" | 2537 "function checkFrameEval(exec_state) {\n" |
| 2445 " return exec_state.frame(0).evaluate('local').value() === 'Local';\n" | 2538 " return exec_state.frame(0).evaluate('local').value() === 'Local';\n" |
| 2446 "}", | 2539 "}", |
| 2447 "checkFrameEval"); | 2540 "checkFrameEval"); |
| 2448 debugEventCount = 0; | 2541 debugEventCount = 0; |
| 2449 env->AllowCodeGenerationFromStrings(false); | 2542 env->AllowCodeGenerationFromStrings(false); |
| 2450 foo->Call(env->Global(), 0, NULL); | 2543 foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 2451 CHECK_EQ(1, debugEventCount); | 2544 CHECK_EQ(1, debugEventCount); |
| 2452 | 2545 |
| 2453 checkGlobalEvalFunction.Clear(); | 2546 checkGlobalEvalFunction.Clear(); |
| 2454 checkFrameEvalFunction.Clear(); | 2547 checkFrameEvalFunction.Clear(); |
| 2455 v8::Debug::SetDebugEventListener(NULL); | 2548 v8::Debug::SetDebugEventListener(NULL); |
| 2456 CheckDebuggerUnloaded(); | 2549 CheckDebuggerUnloaded(); |
| 2457 } | 2550 } |
| 2458 | 2551 |
| 2459 | 2552 |
| 2460 // Copies a C string to a 16-bit string. Does not check for buffer overflow. | 2553 // Copies a C string to a 16-bit string. Does not check for buffer overflow. |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2534 } | 2627 } |
| 2535 void next() { | 2628 void next() { |
| 2536 counter++; | 2629 counter++; |
| 2537 } | 2630 } |
| 2538 }; | 2631 }; |
| 2539 | 2632 |
| 2540 DebugProcessDebugMessagesData process_debug_messages_data; | 2633 DebugProcessDebugMessagesData process_debug_messages_data; |
| 2541 | 2634 |
| 2542 static void DebugProcessDebugMessagesHandler( | 2635 static void DebugProcessDebugMessagesHandler( |
| 2543 const v8::Debug::Message& message) { | 2636 const v8::Debug::Message& message) { |
| 2544 v8::Handle<v8::String> json = message.GetJSON(); | 2637 v8::Local<v8::String> json = message.GetJSON(); |
| 2545 v8::String::Utf8Value utf8(json); | 2638 v8::String::Utf8Value utf8(json); |
| 2546 EvaluateResult* array_item = process_debug_messages_data.current(); | 2639 EvaluateResult* array_item = process_debug_messages_data.current(); |
| 2547 | 2640 |
| 2548 bool res = GetEvaluateStringResult(*utf8, | 2641 bool res = GetEvaluateStringResult(*utf8, |
| 2549 array_item->buffer, | 2642 array_item->buffer, |
| 2550 EvaluateResult::kBufferSize); | 2643 EvaluateResult::kBufferSize); |
| 2551 if (res) { | 2644 if (res) { |
| 2552 process_debug_messages_data.next(); | 2645 process_debug_messages_data.next(); |
| 2553 } | 2646 } |
| 2554 } | 2647 } |
| 2555 | 2648 |
| 2556 | 2649 |
| 2557 // Test that the evaluation of expressions works even from ProcessDebugMessages | 2650 // Test that the evaluation of expressions works even from ProcessDebugMessages |
| 2558 // i.e. with empty stack. | 2651 // i.e. with empty stack. |
| 2559 TEST(DebugEvaluateWithoutStack) { | 2652 TEST(DebugEvaluateWithoutStack) { |
| 2560 v8::Debug::SetMessageHandler(DebugProcessDebugMessagesHandler); | 2653 v8::Debug::SetMessageHandler(DebugProcessDebugMessagesHandler); |
| 2561 | 2654 |
| 2562 DebugLocalContext env; | 2655 DebugLocalContext env; |
| 2563 v8::HandleScope scope(env->GetIsolate()); | 2656 v8::HandleScope scope(env->GetIsolate()); |
| 2564 | 2657 |
| 2565 const char* source = | 2658 const char* source = |
| 2566 "var v1 = 'Pinguin';\n function getAnimal() { return 'Capy' + 'bara'; }"; | 2659 "var v1 = 'Pinguin';\n function getAnimal() { return 'Capy' + 'bara'; }"; |
| 2567 | 2660 |
| 2568 v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), source)) | 2661 v8::Local<v8::Context> context = env.context(); |
| 2569 ->Run(); | 2662 v8::Script::Compile(context, v8_str(env->GetIsolate(), source)) |
| 2663 .ToLocalChecked() |
| 2664 ->Run(context) |
| 2665 .ToLocalChecked(); |
| 2570 | 2666 |
| 2571 v8::Debug::ProcessDebugMessages(); | 2667 v8::Debug::ProcessDebugMessages(); |
| 2572 | 2668 |
| 2573 const int kBufferSize = 1000; | 2669 const int kBufferSize = 1000; |
| 2574 uint16_t buffer[kBufferSize]; | 2670 uint16_t buffer[kBufferSize]; |
| 2575 | 2671 |
| 2576 const char* command_111 = "{\"seq\":111," | 2672 const char* command_111 = "{\"seq\":111," |
| 2577 "\"type\":\"request\"," | 2673 "\"type\":\"request\"," |
| 2578 "\"command\":\"evaluate\"," | 2674 "\"command\":\"evaluate\"," |
| 2579 "\"arguments\":{" | 2675 "\"arguments\":{" |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2632 // Run foo to allow it to get optimized. | 2728 // Run foo to allow it to get optimized. |
| 2633 CompileRun("a=0; b=0; c=0; foo();"); | 2729 CompileRun("a=0; b=0; c=0; foo();"); |
| 2634 | 2730 |
| 2635 // Register a debug event listener which steps and counts. | 2731 // Register a debug event listener which steps and counts. |
| 2636 v8::Debug::SetDebugEventListener(DebugEventStep); | 2732 v8::Debug::SetDebugEventListener(DebugEventStep); |
| 2637 | 2733 |
| 2638 SetBreakPoint(foo, 3); | 2734 SetBreakPoint(foo, 3); |
| 2639 | 2735 |
| 2640 step_action = StepIn; | 2736 step_action = StepIn; |
| 2641 break_point_hit_count = 0; | 2737 break_point_hit_count = 0; |
| 2642 foo->Call(env->Global(), 0, NULL); | 2738 v8::Local<v8::Context> context = env.context(); |
| 2739 foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 2643 | 2740 |
| 2644 // With stepping all break locations are hit. | 2741 // With stepping all break locations are hit. |
| 2645 CHECK_EQ(4, break_point_hit_count); | 2742 CHECK_EQ(4, break_point_hit_count); |
| 2646 | 2743 |
| 2647 v8::Debug::SetDebugEventListener(NULL); | 2744 v8::Debug::SetDebugEventListener(NULL); |
| 2648 CheckDebuggerUnloaded(); | 2745 CheckDebuggerUnloaded(); |
| 2649 | 2746 |
| 2650 // Register a debug event listener which just counts. | 2747 // Register a debug event listener which just counts. |
| 2651 v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); | 2748 v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); |
| 2652 | 2749 |
| 2653 SetBreakPoint(foo, 3); | 2750 SetBreakPoint(foo, 3); |
| 2654 break_point_hit_count = 0; | 2751 break_point_hit_count = 0; |
| 2655 foo->Call(env->Global(), 0, NULL); | 2752 foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 2656 | 2753 |
| 2657 // Without stepping only active break points are hit. | 2754 // Without stepping only active break points are hit. |
| 2658 CHECK_EQ(1, break_point_hit_count); | 2755 CHECK_EQ(1, break_point_hit_count); |
| 2659 | 2756 |
| 2660 v8::Debug::SetDebugEventListener(NULL); | 2757 v8::Debug::SetDebugEventListener(NULL); |
| 2661 CheckDebuggerUnloaded(); | 2758 CheckDebuggerUnloaded(); |
| 2662 } | 2759 } |
| 2663 | 2760 |
| 2664 | 2761 |
| 2665 // Test of the stepping mechanism for keyed load in a loop. | 2762 // Test of the stepping mechanism for keyed load in a loop. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2678 " var x;\n" | 2775 " var x;\n" |
| 2679 " var len = a.length;\n" | 2776 " var len = a.length;\n" |
| 2680 " for (var i = 0; i < len; i++) {\n" | 2777 " for (var i = 0; i < len; i++) {\n" |
| 2681 " y = 1;\n" | 2778 " y = 1;\n" |
| 2682 " x = a[i];\n" | 2779 " x = a[i];\n" |
| 2683 " }\n" | 2780 " }\n" |
| 2684 "}\n" | 2781 "}\n" |
| 2685 "y=0\n", | 2782 "y=0\n", |
| 2686 "foo"); | 2783 "foo"); |
| 2687 | 2784 |
| 2785 v8::Local<v8::Context> context = env.context(); |
| 2688 // Create array [0,1,2,3,4,5,6,7,8,9] | 2786 // Create array [0,1,2,3,4,5,6,7,8,9] |
| 2689 v8::Local<v8::Array> a = v8::Array::New(env->GetIsolate(), 10); | 2787 v8::Local<v8::Array> a = v8::Array::New(env->GetIsolate(), 10); |
| 2690 for (int i = 0; i < 10; i++) { | 2788 for (int i = 0; i < 10; i++) { |
| 2691 a->Set(v8::Number::New(env->GetIsolate(), i), | 2789 CHECK(a->Set(context, v8::Number::New(env->GetIsolate(), i), |
| 2692 v8::Number::New(env->GetIsolate(), i)); | 2790 v8::Number::New(env->GetIsolate(), i)) |
| 2791 .FromJust()); |
| 2693 } | 2792 } |
| 2694 | 2793 |
| 2695 // Call function without any break points to ensure inlining is in place. | 2794 // Call function without any break points to ensure inlining is in place. |
| 2696 const int kArgc = 1; | 2795 const int kArgc = 1; |
| 2697 v8::Handle<v8::Value> args[kArgc] = { a }; | 2796 v8::Local<v8::Value> args[kArgc] = {a}; |
| 2698 foo->Call(env->Global(), kArgc, args); | 2797 foo->Call(context, env->Global(), kArgc, args).ToLocalChecked(); |
| 2699 | 2798 |
| 2700 // Set up break point and step through the function. | 2799 // Set up break point and step through the function. |
| 2701 SetBreakPoint(foo, 3); | 2800 SetBreakPoint(foo, 3); |
| 2702 step_action = StepNext; | 2801 step_action = StepNext; |
| 2703 break_point_hit_count = 0; | 2802 break_point_hit_count = 0; |
| 2704 foo->Call(env->Global(), kArgc, args); | 2803 foo->Call(context, env->Global(), kArgc, args).ToLocalChecked(); |
| 2705 | 2804 |
| 2706 // With stepping all break locations are hit. | 2805 // With stepping all break locations are hit. |
| 2707 CHECK_EQ(45, break_point_hit_count); | 2806 CHECK_EQ(45, break_point_hit_count); |
| 2708 | 2807 |
| 2709 v8::Debug::SetDebugEventListener(NULL); | 2808 v8::Debug::SetDebugEventListener(NULL); |
| 2710 CheckDebuggerUnloaded(); | 2809 CheckDebuggerUnloaded(); |
| 2711 } | 2810 } |
| 2712 | 2811 |
| 2713 | 2812 |
| 2714 // Test of the stepping mechanism for keyed store in a loop. | 2813 // Test of the stepping mechanism for keyed store in a loop. |
| (...skipping 11 matching lines...) Expand all Loading... |
| 2726 "function foo(a) {\n" | 2825 "function foo(a) {\n" |
| 2727 " var len = a.length;\n" | 2826 " var len = a.length;\n" |
| 2728 " for (var i = 0; i < len; i++) {\n" | 2827 " for (var i = 0; i < len; i++) {\n" |
| 2729 " y = 1;\n" | 2828 " y = 1;\n" |
| 2730 " a[i] = 42;\n" | 2829 " a[i] = 42;\n" |
| 2731 " }\n" | 2830 " }\n" |
| 2732 "}\n" | 2831 "}\n" |
| 2733 "y=0\n", | 2832 "y=0\n", |
| 2734 "foo"); | 2833 "foo"); |
| 2735 | 2834 |
| 2835 v8::Local<v8::Context> context = env.context(); |
| 2736 // Create array [0,1,2,3,4,5,6,7,8,9] | 2836 // Create array [0,1,2,3,4,5,6,7,8,9] |
| 2737 v8::Local<v8::Array> a = v8::Array::New(env->GetIsolate(), 10); | 2837 v8::Local<v8::Array> a = v8::Array::New(env->GetIsolate(), 10); |
| 2738 for (int i = 0; i < 10; i++) { | 2838 for (int i = 0; i < 10; i++) { |
| 2739 a->Set(v8::Number::New(env->GetIsolate(), i), | 2839 CHECK(a->Set(context, v8::Number::New(env->GetIsolate(), i), |
| 2740 v8::Number::New(env->GetIsolate(), i)); | 2840 v8::Number::New(env->GetIsolate(), i)) |
| 2841 .FromJust()); |
| 2741 } | 2842 } |
| 2742 | 2843 |
| 2743 // Call function without any break points to ensure inlining is in place. | 2844 // Call function without any break points to ensure inlining is in place. |
| 2744 const int kArgc = 1; | 2845 const int kArgc = 1; |
| 2745 v8::Handle<v8::Value> args[kArgc] = { a }; | 2846 v8::Local<v8::Value> args[kArgc] = {a}; |
| 2746 foo->Call(env->Global(), kArgc, args); | 2847 foo->Call(context, env->Global(), kArgc, args).ToLocalChecked(); |
| 2747 | 2848 |
| 2748 // Set up break point and step through the function. | 2849 // Set up break point and step through the function. |
| 2749 SetBreakPoint(foo, 3); | 2850 SetBreakPoint(foo, 3); |
| 2750 step_action = StepNext; | 2851 step_action = StepNext; |
| 2751 break_point_hit_count = 0; | 2852 break_point_hit_count = 0; |
| 2752 foo->Call(env->Global(), kArgc, args); | 2853 foo->Call(context, env->Global(), kArgc, args).ToLocalChecked(); |
| 2753 | 2854 |
| 2754 // With stepping all break locations are hit. | 2855 // With stepping all break locations are hit. |
| 2755 CHECK_EQ(44, break_point_hit_count); | 2856 CHECK_EQ(44, break_point_hit_count); |
| 2756 | 2857 |
| 2757 v8::Debug::SetDebugEventListener(NULL); | 2858 v8::Debug::SetDebugEventListener(NULL); |
| 2758 CheckDebuggerUnloaded(); | 2859 CheckDebuggerUnloaded(); |
| 2759 } | 2860 } |
| 2760 | 2861 |
| 2761 | 2862 |
| 2762 // Test of the stepping mechanism for named load in a loop. | 2863 // Test of the stepping mechanism for named load in a loop. |
| 2763 TEST(DebugStepNamedLoadLoop) { | 2864 TEST(DebugStepNamedLoadLoop) { |
| 2764 DebugLocalContext env; | 2865 DebugLocalContext env; |
| 2765 v8::HandleScope scope(env->GetIsolate()); | 2866 v8::HandleScope scope(env->GetIsolate()); |
| 2766 | 2867 |
| 2767 // Register a debug event listener which steps and counts. | 2868 // Register a debug event listener which steps and counts. |
| 2768 v8::Debug::SetDebugEventListener(DebugEventStep); | 2869 v8::Debug::SetDebugEventListener(DebugEventStep); |
| 2769 | 2870 |
| 2871 v8::Local<v8::Context> context = env.context(); |
| 2770 // Create a function for testing stepping of named load. | 2872 // Create a function for testing stepping of named load. |
| 2771 v8::Local<v8::Function> foo = CompileFunction( | 2873 v8::Local<v8::Function> foo = CompileFunction( |
| 2772 &env, | 2874 &env, |
| 2773 "function foo() {\n" | 2875 "function foo() {\n" |
| 2774 " var a = [];\n" | 2876 " var a = [];\n" |
| 2775 " var s = \"\";\n" | 2877 " var s = \"\";\n" |
| 2776 " for (var i = 0; i < 10; i++) {\n" | 2878 " for (var i = 0; i < 10; i++) {\n" |
| 2777 " var v = new V(i, i + 1);\n" | 2879 " var v = new V(i, i + 1);\n" |
| 2778 " v.y;\n" | 2880 " v.y;\n" |
| 2779 " a.length;\n" // Special case: array length. | 2881 " a.length;\n" // Special case: array length. |
| 2780 " s.length;\n" // Special case: string length. | 2882 " s.length;\n" // Special case: string length. |
| 2781 " }\n" | 2883 " }\n" |
| 2782 "}\n" | 2884 "}\n" |
| 2783 "function V(x, y) {\n" | 2885 "function V(x, y) {\n" |
| 2784 " this.x = x;\n" | 2886 " this.x = x;\n" |
| 2785 " this.y = y;\n" | 2887 " this.y = y;\n" |
| 2786 "}\n", | 2888 "}\n", |
| 2787 "foo"); | 2889 "foo"); |
| 2788 | 2890 |
| 2789 // Call function without any break points to ensure inlining is in place. | 2891 // Call function without any break points to ensure inlining is in place. |
| 2790 foo->Call(env->Global(), 0, NULL); | 2892 foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 2791 | 2893 |
| 2792 // Set up break point and step through the function. | 2894 // Set up break point and step through the function. |
| 2793 SetBreakPoint(foo, 4); | 2895 SetBreakPoint(foo, 4); |
| 2794 step_action = StepNext; | 2896 step_action = StepNext; |
| 2795 break_point_hit_count = 0; | 2897 break_point_hit_count = 0; |
| 2796 foo->Call(env->Global(), 0, NULL); | 2898 foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 2797 | 2899 |
| 2798 // With stepping all break locations are hit. | 2900 // With stepping all break locations are hit. |
| 2799 CHECK_EQ(65, break_point_hit_count); | 2901 CHECK_EQ(65, break_point_hit_count); |
| 2800 | 2902 |
| 2801 v8::Debug::SetDebugEventListener(NULL); | 2903 v8::Debug::SetDebugEventListener(NULL); |
| 2802 CheckDebuggerUnloaded(); | 2904 CheckDebuggerUnloaded(); |
| 2803 } | 2905 } |
| 2804 | 2906 |
| 2805 | 2907 |
| 2806 static void DoDebugStepNamedStoreLoop(int expected) { | 2908 static void DoDebugStepNamedStoreLoop(int expected) { |
| 2807 DebugLocalContext env; | 2909 DebugLocalContext env; |
| 2808 v8::HandleScope scope(env->GetIsolate()); | 2910 v8::HandleScope scope(env->GetIsolate()); |
| 2809 | 2911 |
| 2810 // Register a debug event listener which steps and counts. | 2912 // Register a debug event listener which steps and counts. |
| 2811 v8::Debug::SetDebugEventListener(DebugEventStep); | 2913 v8::Debug::SetDebugEventListener(DebugEventStep); |
| 2812 | 2914 |
| 2813 // Create a function for testing stepping of named store. | 2915 // Create a function for testing stepping of named store. |
| 2916 v8::Local<v8::Context> context = env.context(); |
| 2814 v8::Local<v8::Function> foo = CompileFunction( | 2917 v8::Local<v8::Function> foo = CompileFunction( |
| 2815 &env, | 2918 &env, |
| 2816 "function foo() {\n" | 2919 "function foo() {\n" |
| 2817 " var a = {a:1};\n" | 2920 " var a = {a:1};\n" |
| 2818 " for (var i = 0; i < 10; i++) {\n" | 2921 " for (var i = 0; i < 10; i++) {\n" |
| 2819 " a.a = 2\n" | 2922 " a.a = 2\n" |
| 2820 " }\n" | 2923 " }\n" |
| 2821 "}\n", | 2924 "}\n", |
| 2822 "foo"); | 2925 "foo"); |
| 2823 | 2926 |
| 2824 // Call function without any break points to ensure inlining is in place. | 2927 // Call function without any break points to ensure inlining is in place. |
| 2825 foo->Call(env->Global(), 0, NULL); | 2928 foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 2826 | 2929 |
| 2827 // Set up break point and step through the function. | 2930 // Set up break point and step through the function. |
| 2828 SetBreakPoint(foo, 3); | 2931 SetBreakPoint(foo, 3); |
| 2829 step_action = StepNext; | 2932 step_action = StepNext; |
| 2830 break_point_hit_count = 0; | 2933 break_point_hit_count = 0; |
| 2831 foo->Call(env->Global(), 0, NULL); | 2934 foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 2832 | 2935 |
| 2833 // With stepping all expected break locations are hit. | 2936 // With stepping all expected break locations are hit. |
| 2834 CHECK_EQ(expected, break_point_hit_count); | 2937 CHECK_EQ(expected, break_point_hit_count); |
| 2835 | 2938 |
| 2836 v8::Debug::SetDebugEventListener(NULL); | 2939 v8::Debug::SetDebugEventListener(NULL); |
| 2837 CheckDebuggerUnloaded(); | 2940 CheckDebuggerUnloaded(); |
| 2838 } | 2941 } |
| 2839 | 2942 |
| 2840 | 2943 |
| 2841 // Test of the stepping mechanism for named load in a loop. | 2944 // Test of the stepping mechanism for named load in a loop. |
| 2842 TEST(DebugStepNamedStoreLoop) { DoDebugStepNamedStoreLoop(34); } | 2945 TEST(DebugStepNamedStoreLoop) { DoDebugStepNamedStoreLoop(34); } |
| 2843 | 2946 |
| 2844 | 2947 |
| 2845 // Test the stepping mechanism with different ICs. | 2948 // Test the stepping mechanism with different ICs. |
| 2846 TEST(DebugStepLinearMixedICs) { | 2949 TEST(DebugStepLinearMixedICs) { |
| 2847 DebugLocalContext env; | 2950 DebugLocalContext env; |
| 2848 v8::HandleScope scope(env->GetIsolate()); | 2951 v8::HandleScope scope(env->GetIsolate()); |
| 2849 | 2952 |
| 2850 // Register a debug event listener which steps and counts. | 2953 // Register a debug event listener which steps and counts. |
| 2851 v8::Debug::SetDebugEventListener(DebugEventStep); | 2954 v8::Debug::SetDebugEventListener(DebugEventStep); |
| 2852 | 2955 |
| 2956 v8::Local<v8::Context> context = env.context(); |
| 2853 // Create a function for testing stepping. | 2957 // Create a function for testing stepping. |
| 2854 v8::Local<v8::Function> foo = CompileFunction(&env, | 2958 v8::Local<v8::Function> foo = CompileFunction(&env, |
| 2855 "function bar() {};" | 2959 "function bar() {};" |
| 2856 "function foo() {" | 2960 "function foo() {" |
| 2857 " var x;" | 2961 " var x;" |
| 2858 " var index='name';" | 2962 " var index='name';" |
| 2859 " var y = {};" | 2963 " var y = {};" |
| 2860 " a=1;b=2;x=a;y[index]=3;x=y[index];bar();}", "foo"); | 2964 " a=1;b=2;x=a;y[index]=3;x=y[index];bar();}", "foo"); |
| 2861 | 2965 |
| 2862 // Run functions to allow them to get optimized. | 2966 // Run functions to allow them to get optimized. |
| 2863 CompileRun("a=0; b=0; bar(); foo();"); | 2967 CompileRun("a=0; b=0; bar(); foo();"); |
| 2864 | 2968 |
| 2865 SetBreakPoint(foo, 0); | 2969 SetBreakPoint(foo, 0); |
| 2866 | 2970 |
| 2867 step_action = StepIn; | 2971 step_action = StepIn; |
| 2868 break_point_hit_count = 0; | 2972 break_point_hit_count = 0; |
| 2869 foo->Call(env->Global(), 0, NULL); | 2973 foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 2870 | 2974 |
| 2871 // With stepping all break locations are hit. | 2975 // With stepping all break locations are hit. |
| 2872 CHECK_EQ(11, break_point_hit_count); | 2976 CHECK_EQ(11, break_point_hit_count); |
| 2873 | 2977 |
| 2874 v8::Debug::SetDebugEventListener(NULL); | 2978 v8::Debug::SetDebugEventListener(NULL); |
| 2875 CheckDebuggerUnloaded(); | 2979 CheckDebuggerUnloaded(); |
| 2876 | 2980 |
| 2877 // Register a debug event listener which just counts. | 2981 // Register a debug event listener which just counts. |
| 2878 v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); | 2982 v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); |
| 2879 | 2983 |
| 2880 SetBreakPoint(foo, 0); | 2984 SetBreakPoint(foo, 0); |
| 2881 break_point_hit_count = 0; | 2985 break_point_hit_count = 0; |
| 2882 foo->Call(env->Global(), 0, NULL); | 2986 foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 2883 | 2987 |
| 2884 // Without stepping only active break points are hit. | 2988 // Without stepping only active break points are hit. |
| 2885 CHECK_EQ(1, break_point_hit_count); | 2989 CHECK_EQ(1, break_point_hit_count); |
| 2886 | 2990 |
| 2887 v8::Debug::SetDebugEventListener(NULL); | 2991 v8::Debug::SetDebugEventListener(NULL); |
| 2888 CheckDebuggerUnloaded(); | 2992 CheckDebuggerUnloaded(); |
| 2889 } | 2993 } |
| 2890 | 2994 |
| 2891 | 2995 |
| 2892 TEST(DebugStepDeclarations) { | 2996 TEST(DebugStepDeclarations) { |
| 2893 DebugLocalContext env; | 2997 DebugLocalContext env; |
| 2894 v8::HandleScope scope(env->GetIsolate()); | 2998 v8::HandleScope scope(env->GetIsolate()); |
| 2895 | 2999 |
| 2896 // Register a debug event listener which steps and counts. | 3000 // Register a debug event listener which steps and counts. |
| 2897 v8::Debug::SetDebugEventListener(DebugEventStep); | 3001 v8::Debug::SetDebugEventListener(DebugEventStep); |
| 2898 | 3002 |
| 3003 v8::Local<v8::Context> context = env.context(); |
| 2899 // Create a function for testing stepping. Run it to allow it to get | 3004 // Create a function for testing stepping. Run it to allow it to get |
| 2900 // optimized. | 3005 // optimized. |
| 2901 const char* src = "function foo() { " | 3006 const char* src = "function foo() { " |
| 2902 " var a;" | 3007 " var a;" |
| 2903 " var b = 1;" | 3008 " var b = 1;" |
| 2904 " var c = foo;" | 3009 " var c = foo;" |
| 2905 " var d = Math.floor;" | 3010 " var d = Math.floor;" |
| 2906 " var e = b + d(1.2);" | 3011 " var e = b + d(1.2);" |
| 2907 "}" | 3012 "}" |
| 2908 "foo()"; | 3013 "foo()"; |
| 2909 v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); | 3014 v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); |
| 2910 | 3015 |
| 2911 SetBreakPoint(foo, 0); | 3016 SetBreakPoint(foo, 0); |
| 2912 | 3017 |
| 2913 // Stepping through the declarations. | 3018 // Stepping through the declarations. |
| 2914 step_action = StepIn; | 3019 step_action = StepIn; |
| 2915 break_point_hit_count = 0; | 3020 break_point_hit_count = 0; |
| 2916 foo->Call(env->Global(), 0, NULL); | 3021 foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 2917 CHECK_EQ(6, break_point_hit_count); | 3022 CHECK_EQ(6, break_point_hit_count); |
| 2918 | 3023 |
| 2919 // Get rid of the debug event listener. | 3024 // Get rid of the debug event listener. |
| 2920 v8::Debug::SetDebugEventListener(NULL); | 3025 v8::Debug::SetDebugEventListener(NULL); |
| 2921 CheckDebuggerUnloaded(); | 3026 CheckDebuggerUnloaded(); |
| 2922 } | 3027 } |
| 2923 | 3028 |
| 2924 | 3029 |
| 2925 TEST(DebugStepLocals) { | 3030 TEST(DebugStepLocals) { |
| 2926 DebugLocalContext env; | 3031 DebugLocalContext env; |
| 2927 v8::HandleScope scope(env->GetIsolate()); | 3032 v8::HandleScope scope(env->GetIsolate()); |
| 2928 | 3033 |
| 2929 // Register a debug event listener which steps and counts. | 3034 // Register a debug event listener which steps and counts. |
| 2930 v8::Debug::SetDebugEventListener(DebugEventStep); | 3035 v8::Debug::SetDebugEventListener(DebugEventStep); |
| 2931 | 3036 |
| 3037 v8::Local<v8::Context> context = env.context(); |
| 2932 // Create a function for testing stepping. Run it to allow it to get | 3038 // Create a function for testing stepping. Run it to allow it to get |
| 2933 // optimized. | 3039 // optimized. |
| 2934 const char* src = "function foo() { " | 3040 const char* src = "function foo() { " |
| 2935 " var a,b;" | 3041 " var a,b;" |
| 2936 " a = 1;" | 3042 " a = 1;" |
| 2937 " b = a + 2;" | 3043 " b = a + 2;" |
| 2938 " b = 1 + 2 + 3;" | 3044 " b = 1 + 2 + 3;" |
| 2939 " a = Math.floor(b);" | 3045 " a = Math.floor(b);" |
| 2940 "}" | 3046 "}" |
| 2941 "foo()"; | 3047 "foo()"; |
| 2942 v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); | 3048 v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); |
| 2943 | 3049 |
| 2944 SetBreakPoint(foo, 0); | 3050 SetBreakPoint(foo, 0); |
| 2945 | 3051 |
| 2946 // Stepping through the declarations. | 3052 // Stepping through the declarations. |
| 2947 step_action = StepIn; | 3053 step_action = StepIn; |
| 2948 break_point_hit_count = 0; | 3054 break_point_hit_count = 0; |
| 2949 foo->Call(env->Global(), 0, NULL); | 3055 foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 2950 CHECK_EQ(6, break_point_hit_count); | 3056 CHECK_EQ(6, break_point_hit_count); |
| 2951 | 3057 |
| 2952 // Get rid of the debug event listener. | 3058 // Get rid of the debug event listener. |
| 2953 v8::Debug::SetDebugEventListener(NULL); | 3059 v8::Debug::SetDebugEventListener(NULL); |
| 2954 CheckDebuggerUnloaded(); | 3060 CheckDebuggerUnloaded(); |
| 2955 } | 3061 } |
| 2956 | 3062 |
| 2957 | 3063 |
| 2958 TEST(DebugStepIf) { | 3064 TEST(DebugStepIf) { |
| 2959 DebugLocalContext env; | 3065 DebugLocalContext env; |
| 2960 v8::Isolate* isolate = env->GetIsolate(); | 3066 v8::Isolate* isolate = env->GetIsolate(); |
| 2961 v8::HandleScope scope(isolate); | 3067 v8::HandleScope scope(isolate); |
| 2962 | 3068 |
| 2963 // Register a debug event listener which steps and counts. | 3069 // Register a debug event listener which steps and counts. |
| 2964 v8::Debug::SetDebugEventListener(DebugEventStep); | 3070 v8::Debug::SetDebugEventListener(DebugEventStep); |
| 2965 | 3071 |
| 3072 v8::Local<v8::Context> context = env.context(); |
| 2966 // Create a function for testing stepping. Run it to allow it to get | 3073 // Create a function for testing stepping. Run it to allow it to get |
| 2967 // optimized. | 3074 // optimized. |
| 2968 const int argc = 1; | 3075 const int argc = 1; |
| 2969 const char* src = "function foo(x) { " | 3076 const char* src = "function foo(x) { " |
| 2970 " a = 1;" | 3077 " a = 1;" |
| 2971 " if (x) {" | 3078 " if (x) {" |
| 2972 " b = 1;" | 3079 " b = 1;" |
| 2973 " } else {" | 3080 " } else {" |
| 2974 " c = 1;" | 3081 " c = 1;" |
| 2975 " d = 1;" | 3082 " d = 1;" |
| 2976 " }" | 3083 " }" |
| 2977 "}" | 3084 "}" |
| 2978 "a=0; b=0; c=0; d=0; foo()"; | 3085 "a=0; b=0; c=0; d=0; foo()"; |
| 2979 v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); | 3086 v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); |
| 2980 SetBreakPoint(foo, 0); | 3087 SetBreakPoint(foo, 0); |
| 2981 | 3088 |
| 2982 // Stepping through the true part. | 3089 // Stepping through the true part. |
| 2983 step_action = StepIn; | 3090 step_action = StepIn; |
| 2984 break_point_hit_count = 0; | 3091 break_point_hit_count = 0; |
| 2985 v8::Handle<v8::Value> argv_true[argc] = { v8::True(isolate) }; | 3092 v8::Local<v8::Value> argv_true[argc] = {v8::True(isolate)}; |
| 2986 foo->Call(env->Global(), argc, argv_true); | 3093 foo->Call(context, env->Global(), argc, argv_true).ToLocalChecked(); |
| 2987 CHECK_EQ(4, break_point_hit_count); | 3094 CHECK_EQ(4, break_point_hit_count); |
| 2988 | 3095 |
| 2989 // Stepping through the false part. | 3096 // Stepping through the false part. |
| 2990 step_action = StepIn; | 3097 step_action = StepIn; |
| 2991 break_point_hit_count = 0; | 3098 break_point_hit_count = 0; |
| 2992 v8::Handle<v8::Value> argv_false[argc] = { v8::False(isolate) }; | 3099 v8::Local<v8::Value> argv_false[argc] = {v8::False(isolate)}; |
| 2993 foo->Call(env->Global(), argc, argv_false); | 3100 foo->Call(context, env->Global(), argc, argv_false).ToLocalChecked(); |
| 2994 CHECK_EQ(5, break_point_hit_count); | 3101 CHECK_EQ(5, break_point_hit_count); |
| 2995 | 3102 |
| 2996 // Get rid of the debug event listener. | 3103 // Get rid of the debug event listener. |
| 2997 v8::Debug::SetDebugEventListener(NULL); | 3104 v8::Debug::SetDebugEventListener(NULL); |
| 2998 CheckDebuggerUnloaded(); | 3105 CheckDebuggerUnloaded(); |
| 2999 } | 3106 } |
| 3000 | 3107 |
| 3001 | 3108 |
| 3002 TEST(DebugStepSwitch) { | 3109 TEST(DebugStepSwitch) { |
| 3003 DebugLocalContext env; | 3110 DebugLocalContext env; |
| 3004 v8::Isolate* isolate = env->GetIsolate(); | 3111 v8::Isolate* isolate = env->GetIsolate(); |
| 3005 v8::HandleScope scope(isolate); | 3112 v8::HandleScope scope(isolate); |
| 3006 | 3113 |
| 3007 // Register a debug event listener which steps and counts. | 3114 // Register a debug event listener which steps and counts. |
| 3008 v8::Debug::SetDebugEventListener(DebugEventStep); | 3115 v8::Debug::SetDebugEventListener(DebugEventStep); |
| 3009 | 3116 |
| 3117 v8::Local<v8::Context> context = env.context(); |
| 3010 // Create a function for testing stepping. Run it to allow it to get | 3118 // Create a function for testing stepping. Run it to allow it to get |
| 3011 // optimized. | 3119 // optimized. |
| 3012 const int argc = 1; | 3120 const int argc = 1; |
| 3013 const char* src = "function foo(x) { " | 3121 const char* src = "function foo(x) { " |
| 3014 " a = 1;" | 3122 " a = 1;" |
| 3015 " switch (x) {" | 3123 " switch (x) {" |
| 3016 " case 1:" | 3124 " case 1:" |
| 3017 " b = 1;" | 3125 " b = 1;" |
| 3018 " case 2:" | 3126 " case 2:" |
| 3019 " c = 1;" | 3127 " c = 1;" |
| 3020 " break;" | 3128 " break;" |
| 3021 " case 3:" | 3129 " case 3:" |
| 3022 " d = 1;" | 3130 " d = 1;" |
| 3023 " e = 1;" | 3131 " e = 1;" |
| 3024 " f = 1;" | 3132 " f = 1;" |
| 3025 " break;" | 3133 " break;" |
| 3026 " }" | 3134 " }" |
| 3027 "}" | 3135 "}" |
| 3028 "a=0; b=0; c=0; d=0; e=0; f=0; foo()"; | 3136 "a=0; b=0; c=0; d=0; e=0; f=0; foo()"; |
| 3029 v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); | 3137 v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); |
| 3030 SetBreakPoint(foo, 0); | 3138 SetBreakPoint(foo, 0); |
| 3031 | 3139 |
| 3032 // One case with fall-through. | 3140 // One case with fall-through. |
| 3033 step_action = StepIn; | 3141 step_action = StepIn; |
| 3034 break_point_hit_count = 0; | 3142 break_point_hit_count = 0; |
| 3035 v8::Handle<v8::Value> argv_1[argc] = { v8::Number::New(isolate, 1) }; | 3143 v8::Local<v8::Value> argv_1[argc] = {v8::Number::New(isolate, 1)}; |
| 3036 foo->Call(env->Global(), argc, argv_1); | 3144 foo->Call(context, env->Global(), argc, argv_1).ToLocalChecked(); |
| 3037 CHECK_EQ(6, break_point_hit_count); | 3145 CHECK_EQ(6, break_point_hit_count); |
| 3038 | 3146 |
| 3039 // Another case. | 3147 // Another case. |
| 3040 step_action = StepIn; | 3148 step_action = StepIn; |
| 3041 break_point_hit_count = 0; | 3149 break_point_hit_count = 0; |
| 3042 v8::Handle<v8::Value> argv_2[argc] = { v8::Number::New(isolate, 2) }; | 3150 v8::Local<v8::Value> argv_2[argc] = {v8::Number::New(isolate, 2)}; |
| 3043 foo->Call(env->Global(), argc, argv_2); | 3151 foo->Call(context, env->Global(), argc, argv_2).ToLocalChecked(); |
| 3044 CHECK_EQ(5, break_point_hit_count); | 3152 CHECK_EQ(5, break_point_hit_count); |
| 3045 | 3153 |
| 3046 // Last case. | 3154 // Last case. |
| 3047 step_action = StepIn; | 3155 step_action = StepIn; |
| 3048 break_point_hit_count = 0; | 3156 break_point_hit_count = 0; |
| 3049 v8::Handle<v8::Value> argv_3[argc] = { v8::Number::New(isolate, 3) }; | 3157 v8::Local<v8::Value> argv_3[argc] = {v8::Number::New(isolate, 3)}; |
| 3050 foo->Call(env->Global(), argc, argv_3); | 3158 foo->Call(context, env->Global(), argc, argv_3).ToLocalChecked(); |
| 3051 CHECK_EQ(7, break_point_hit_count); | 3159 CHECK_EQ(7, break_point_hit_count); |
| 3052 | 3160 |
| 3053 // Get rid of the debug event listener. | 3161 // Get rid of the debug event listener. |
| 3054 v8::Debug::SetDebugEventListener(NULL); | 3162 v8::Debug::SetDebugEventListener(NULL); |
| 3055 CheckDebuggerUnloaded(); | 3163 CheckDebuggerUnloaded(); |
| 3056 } | 3164 } |
| 3057 | 3165 |
| 3058 | 3166 |
| 3059 TEST(DebugStepWhile) { | 3167 TEST(DebugStepWhile) { |
| 3060 DebugLocalContext env; | 3168 DebugLocalContext env; |
| 3061 v8::Isolate* isolate = env->GetIsolate(); | 3169 v8::Isolate* isolate = env->GetIsolate(); |
| 3062 v8::HandleScope scope(isolate); | 3170 v8::HandleScope scope(isolate); |
| 3063 | 3171 |
| 3064 // Register a debug event listener which steps and counts. | 3172 // Register a debug event listener which steps and counts. |
| 3065 v8::Debug::SetDebugEventListener(DebugEventStep); | 3173 v8::Debug::SetDebugEventListener(DebugEventStep); |
| 3066 | 3174 |
| 3175 v8::Local<v8::Context> context = env.context(); |
| 3067 // Create a function for testing stepping. Run it to allow it to get | 3176 // Create a function for testing stepping. Run it to allow it to get |
| 3068 // optimized. | 3177 // optimized. |
| 3069 const int argc = 1; | 3178 const int argc = 1; |
| 3070 const char* src = "function foo(x) { " | 3179 const char* src = "function foo(x) { " |
| 3071 " var a = 0;" | 3180 " var a = 0;" |
| 3072 " while (a < x) {" | 3181 " while (a < x) {" |
| 3073 " a++;" | 3182 " a++;" |
| 3074 " }" | 3183 " }" |
| 3075 "}" | 3184 "}" |
| 3076 "foo()"; | 3185 "foo()"; |
| 3077 v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); | 3186 v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); |
| 3078 SetBreakPoint(foo, 8); // "var a = 0;" | 3187 SetBreakPoint(foo, 8); // "var a = 0;" |
| 3079 | 3188 |
| 3080 // Looping 0 times. We still should break at the while-condition once. | 3189 // Looping 0 times. We still should break at the while-condition once. |
| 3081 step_action = StepIn; | 3190 step_action = StepIn; |
| 3082 break_point_hit_count = 0; | 3191 break_point_hit_count = 0; |
| 3083 v8::Handle<v8::Value> argv_0[argc] = { v8::Number::New(isolate, 0) }; | 3192 v8::Local<v8::Value> argv_0[argc] = {v8::Number::New(isolate, 0)}; |
| 3084 foo->Call(env->Global(), argc, argv_0); | 3193 foo->Call(context, env->Global(), argc, argv_0).ToLocalChecked(); |
| 3085 CHECK_EQ(3, break_point_hit_count); | 3194 CHECK_EQ(3, break_point_hit_count); |
| 3086 | 3195 |
| 3087 // Looping 10 times. | 3196 // Looping 10 times. |
| 3088 step_action = StepIn; | 3197 step_action = StepIn; |
| 3089 break_point_hit_count = 0; | 3198 break_point_hit_count = 0; |
| 3090 v8::Handle<v8::Value> argv_10[argc] = { v8::Number::New(isolate, 10) }; | 3199 v8::Local<v8::Value> argv_10[argc] = {v8::Number::New(isolate, 10)}; |
| 3091 foo->Call(env->Global(), argc, argv_10); | 3200 foo->Call(context, env->Global(), argc, argv_10).ToLocalChecked(); |
| 3092 CHECK_EQ(23, break_point_hit_count); | 3201 CHECK_EQ(23, break_point_hit_count); |
| 3093 | 3202 |
| 3094 // Looping 100 times. | 3203 // Looping 100 times. |
| 3095 step_action = StepIn; | 3204 step_action = StepIn; |
| 3096 break_point_hit_count = 0; | 3205 break_point_hit_count = 0; |
| 3097 v8::Handle<v8::Value> argv_100[argc] = { v8::Number::New(isolate, 100) }; | 3206 v8::Local<v8::Value> argv_100[argc] = {v8::Number::New(isolate, 100)}; |
| 3098 foo->Call(env->Global(), argc, argv_100); | 3207 foo->Call(context, env->Global(), argc, argv_100).ToLocalChecked(); |
| 3099 CHECK_EQ(203, break_point_hit_count); | 3208 CHECK_EQ(203, break_point_hit_count); |
| 3100 | 3209 |
| 3101 // Get rid of the debug event listener. | 3210 // Get rid of the debug event listener. |
| 3102 v8::Debug::SetDebugEventListener(NULL); | 3211 v8::Debug::SetDebugEventListener(NULL); |
| 3103 CheckDebuggerUnloaded(); | 3212 CheckDebuggerUnloaded(); |
| 3104 } | 3213 } |
| 3105 | 3214 |
| 3106 | 3215 |
| 3107 TEST(DebugStepDoWhile) { | 3216 TEST(DebugStepDoWhile) { |
| 3108 DebugLocalContext env; | 3217 DebugLocalContext env; |
| 3109 v8::Isolate* isolate = env->GetIsolate(); | 3218 v8::Isolate* isolate = env->GetIsolate(); |
| 3110 v8::HandleScope scope(isolate); | 3219 v8::HandleScope scope(isolate); |
| 3111 | 3220 |
| 3112 // Register a debug event listener which steps and counts. | 3221 // Register a debug event listener which steps and counts. |
| 3113 v8::Debug::SetDebugEventListener(DebugEventStep); | 3222 v8::Debug::SetDebugEventListener(DebugEventStep); |
| 3114 | 3223 |
| 3224 v8::Local<v8::Context> context = env.context(); |
| 3115 // Create a function for testing stepping. Run it to allow it to get | 3225 // Create a function for testing stepping. Run it to allow it to get |
| 3116 // optimized. | 3226 // optimized. |
| 3117 const int argc = 1; | 3227 const int argc = 1; |
| 3118 const char* src = "function foo(x) { " | 3228 const char* src = "function foo(x) { " |
| 3119 " var a = 0;" | 3229 " var a = 0;" |
| 3120 " do {" | 3230 " do {" |
| 3121 " a++;" | 3231 " a++;" |
| 3122 " } while (a < x)" | 3232 " } while (a < x)" |
| 3123 "}" | 3233 "}" |
| 3124 "foo()"; | 3234 "foo()"; |
| 3125 v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); | 3235 v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); |
| 3126 SetBreakPoint(foo, 8); // "var a = 0;" | 3236 SetBreakPoint(foo, 8); // "var a = 0;" |
| 3127 | 3237 |
| 3128 // Looping 0 times. | 3238 // Looping 0 times. |
| 3129 step_action = StepIn; | 3239 step_action = StepIn; |
| 3130 break_point_hit_count = 0; | 3240 break_point_hit_count = 0; |
| 3131 v8::Handle<v8::Value> argv_0[argc] = {v8::Number::New(isolate, 0)}; | 3241 v8::Local<v8::Value> argv_0[argc] = {v8::Number::New(isolate, 0)}; |
| 3132 foo->Call(env->Global(), argc, argv_0); | 3242 foo->Call(context, env->Global(), argc, argv_0).ToLocalChecked(); |
| 3133 CHECK_EQ(4, break_point_hit_count); | 3243 CHECK_EQ(4, break_point_hit_count); |
| 3134 | 3244 |
| 3135 // Looping 10 times. | 3245 // Looping 10 times. |
| 3136 step_action = StepIn; | 3246 step_action = StepIn; |
| 3137 break_point_hit_count = 0; | 3247 break_point_hit_count = 0; |
| 3138 v8::Handle<v8::Value> argv_10[argc] = { v8::Number::New(isolate, 10) }; | 3248 v8::Local<v8::Value> argv_10[argc] = {v8::Number::New(isolate, 10)}; |
| 3139 foo->Call(env->Global(), argc, argv_10); | 3249 foo->Call(context, env->Global(), argc, argv_10).ToLocalChecked(); |
| 3140 CHECK_EQ(22, break_point_hit_count); | 3250 CHECK_EQ(22, break_point_hit_count); |
| 3141 | 3251 |
| 3142 // Looping 100 times. | 3252 // Looping 100 times. |
| 3143 step_action = StepIn; | 3253 step_action = StepIn; |
| 3144 break_point_hit_count = 0; | 3254 break_point_hit_count = 0; |
| 3145 v8::Handle<v8::Value> argv_100[argc] = { v8::Number::New(isolate, 100) }; | 3255 v8::Local<v8::Value> argv_100[argc] = {v8::Number::New(isolate, 100)}; |
| 3146 foo->Call(env->Global(), argc, argv_100); | 3256 foo->Call(context, env->Global(), argc, argv_100).ToLocalChecked(); |
| 3147 CHECK_EQ(202, break_point_hit_count); | 3257 CHECK_EQ(202, break_point_hit_count); |
| 3148 | 3258 |
| 3149 // Get rid of the debug event listener. | 3259 // Get rid of the debug event listener. |
| 3150 v8::Debug::SetDebugEventListener(NULL); | 3260 v8::Debug::SetDebugEventListener(NULL); |
| 3151 CheckDebuggerUnloaded(); | 3261 CheckDebuggerUnloaded(); |
| 3152 } | 3262 } |
| 3153 | 3263 |
| 3154 | 3264 |
| 3155 TEST(DebugStepFor) { | 3265 TEST(DebugStepFor) { |
| 3156 DebugLocalContext env; | 3266 DebugLocalContext env; |
| 3157 v8::Isolate* isolate = env->GetIsolate(); | 3267 v8::Isolate* isolate = env->GetIsolate(); |
| 3158 v8::HandleScope scope(isolate); | 3268 v8::HandleScope scope(isolate); |
| 3159 | 3269 |
| 3160 // Register a debug event listener which steps and counts. | 3270 // Register a debug event listener which steps and counts. |
| 3161 v8::Debug::SetDebugEventListener(DebugEventStep); | 3271 v8::Debug::SetDebugEventListener(DebugEventStep); |
| 3162 | 3272 |
| 3273 v8::Local<v8::Context> context = env.context(); |
| 3163 // Create a function for testing stepping. Run it to allow it to get | 3274 // Create a function for testing stepping. Run it to allow it to get |
| 3164 // optimized. | 3275 // optimized. |
| 3165 const int argc = 1; | 3276 const int argc = 1; |
| 3166 const char* src = "function foo(x) { " | 3277 const char* src = "function foo(x) { " |
| 3167 " a = 1;" | 3278 " a = 1;" |
| 3168 " for (i = 0; i < x; i++) {" | 3279 " for (i = 0; i < x; i++) {" |
| 3169 " b = 1;" | 3280 " b = 1;" |
| 3170 " }" | 3281 " }" |
| 3171 "}" | 3282 "}" |
| 3172 "a=0; b=0; i=0; foo()"; | 3283 "a=0; b=0; i=0; foo()"; |
| 3173 v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); | 3284 v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); |
| 3174 | 3285 |
| 3175 SetBreakPoint(foo, 8); // "a = 1;" | 3286 SetBreakPoint(foo, 8); // "a = 1;" |
| 3176 | 3287 |
| 3177 // Looping 0 times. | 3288 // Looping 0 times. |
| 3178 step_action = StepIn; | 3289 step_action = StepIn; |
| 3179 break_point_hit_count = 0; | 3290 break_point_hit_count = 0; |
| 3180 v8::Handle<v8::Value> argv_0[argc] = {v8::Number::New(isolate, 0)}; | 3291 v8::Local<v8::Value> argv_0[argc] = {v8::Number::New(isolate, 0)}; |
| 3181 foo->Call(env->Global(), argc, argv_0); | 3292 foo->Call(context, env->Global(), argc, argv_0).ToLocalChecked(); |
| 3182 CHECK_EQ(4, break_point_hit_count); | 3293 CHECK_EQ(4, break_point_hit_count); |
| 3183 | 3294 |
| 3184 // Looping 10 times. | 3295 // Looping 10 times. |
| 3185 step_action = StepIn; | 3296 step_action = StepIn; |
| 3186 break_point_hit_count = 0; | 3297 break_point_hit_count = 0; |
| 3187 v8::Handle<v8::Value> argv_10[argc] = { v8::Number::New(isolate, 10) }; | 3298 v8::Local<v8::Value> argv_10[argc] = {v8::Number::New(isolate, 10)}; |
| 3188 foo->Call(env->Global(), argc, argv_10); | 3299 foo->Call(context, env->Global(), argc, argv_10).ToLocalChecked(); |
| 3189 CHECK_EQ(34, break_point_hit_count); | 3300 CHECK_EQ(34, break_point_hit_count); |
| 3190 | 3301 |
| 3191 // Looping 100 times. | 3302 // Looping 100 times. |
| 3192 step_action = StepIn; | 3303 step_action = StepIn; |
| 3193 break_point_hit_count = 0; | 3304 break_point_hit_count = 0; |
| 3194 v8::Handle<v8::Value> argv_100[argc] = { v8::Number::New(isolate, 100) }; | 3305 v8::Local<v8::Value> argv_100[argc] = {v8::Number::New(isolate, 100)}; |
| 3195 foo->Call(env->Global(), argc, argv_100); | 3306 foo->Call(context, env->Global(), argc, argv_100).ToLocalChecked(); |
| 3196 CHECK_EQ(304, break_point_hit_count); | 3307 CHECK_EQ(304, break_point_hit_count); |
| 3197 | 3308 |
| 3198 // Get rid of the debug event listener. | 3309 // Get rid of the debug event listener. |
| 3199 v8::Debug::SetDebugEventListener(NULL); | 3310 v8::Debug::SetDebugEventListener(NULL); |
| 3200 CheckDebuggerUnloaded(); | 3311 CheckDebuggerUnloaded(); |
| 3201 } | 3312 } |
| 3202 | 3313 |
| 3203 | 3314 |
| 3204 TEST(DebugStepForContinue) { | 3315 TEST(DebugStepForContinue) { |
| 3205 DebugLocalContext env; | 3316 DebugLocalContext env; |
| 3206 v8::Isolate* isolate = env->GetIsolate(); | 3317 v8::Isolate* isolate = env->GetIsolate(); |
| 3207 v8::HandleScope scope(isolate); | 3318 v8::HandleScope scope(isolate); |
| 3208 | 3319 |
| 3209 // Register a debug event listener which steps and counts. | 3320 // Register a debug event listener which steps and counts. |
| 3210 v8::Debug::SetDebugEventListener(DebugEventStep); | 3321 v8::Debug::SetDebugEventListener(DebugEventStep); |
| 3211 | 3322 |
| 3323 v8::Local<v8::Context> context = env.context(); |
| 3212 // Create a function for testing stepping. Run it to allow it to get | 3324 // Create a function for testing stepping. Run it to allow it to get |
| 3213 // optimized. | 3325 // optimized. |
| 3214 const int argc = 1; | 3326 const int argc = 1; |
| 3215 const char* src = "function foo(x) { " | 3327 const char* src = "function foo(x) { " |
| 3216 " var a = 0;" | 3328 " var a = 0;" |
| 3217 " var b = 0;" | 3329 " var b = 0;" |
| 3218 " var c = 0;" | 3330 " var c = 0;" |
| 3219 " for (var i = 0; i < x; i++) {" | 3331 " for (var i = 0; i < x; i++) {" |
| 3220 " a++;" | 3332 " a++;" |
| 3221 " if (a % 2 == 0) continue;" | 3333 " if (a % 2 == 0) continue;" |
| 3222 " b++;" | 3334 " b++;" |
| 3223 " c++;" | 3335 " c++;" |
| 3224 " }" | 3336 " }" |
| 3225 " return b;" | 3337 " return b;" |
| 3226 "}" | 3338 "}" |
| 3227 "foo()"; | 3339 "foo()"; |
| 3228 v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); | 3340 v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); |
| 3229 v8::Handle<v8::Value> result; | 3341 v8::Local<v8::Value> result; |
| 3230 SetBreakPoint(foo, 8); // "var a = 0;" | 3342 SetBreakPoint(foo, 8); // "var a = 0;" |
| 3231 | 3343 |
| 3232 // Each loop generates 4 or 5 steps depending on whether a is equal. | 3344 // Each loop generates 4 or 5 steps depending on whether a is equal. |
| 3233 | 3345 |
| 3234 // Looping 10 times. | 3346 // Looping 10 times. |
| 3235 step_action = StepIn; | 3347 step_action = StepIn; |
| 3236 break_point_hit_count = 0; | 3348 break_point_hit_count = 0; |
| 3237 v8::Handle<v8::Value> argv_10[argc] = { v8::Number::New(isolate, 10) }; | 3349 v8::Local<v8::Value> argv_10[argc] = {v8::Number::New(isolate, 10)}; |
| 3238 result = foo->Call(env->Global(), argc, argv_10); | 3350 result = foo->Call(context, env->Global(), argc, argv_10).ToLocalChecked(); |
| 3239 CHECK_EQ(5, result->Int32Value()); | 3351 CHECK_EQ(5, result->Int32Value(context).FromJust()); |
| 3240 CHECK_EQ(62, break_point_hit_count); | 3352 CHECK_EQ(62, break_point_hit_count); |
| 3241 | 3353 |
| 3242 // Looping 100 times. | 3354 // Looping 100 times. |
| 3243 step_action = StepIn; | 3355 step_action = StepIn; |
| 3244 break_point_hit_count = 0; | 3356 break_point_hit_count = 0; |
| 3245 v8::Handle<v8::Value> argv_100[argc] = { v8::Number::New(isolate, 100) }; | 3357 v8::Local<v8::Value> argv_100[argc] = {v8::Number::New(isolate, 100)}; |
| 3246 result = foo->Call(env->Global(), argc, argv_100); | 3358 result = foo->Call(context, env->Global(), argc, argv_100).ToLocalChecked(); |
| 3247 CHECK_EQ(50, result->Int32Value()); | 3359 CHECK_EQ(50, result->Int32Value(context).FromJust()); |
| 3248 CHECK_EQ(557, break_point_hit_count); | 3360 CHECK_EQ(557, break_point_hit_count); |
| 3249 | 3361 |
| 3250 // Get rid of the debug event listener. | 3362 // Get rid of the debug event listener. |
| 3251 v8::Debug::SetDebugEventListener(NULL); | 3363 v8::Debug::SetDebugEventListener(NULL); |
| 3252 CheckDebuggerUnloaded(); | 3364 CheckDebuggerUnloaded(); |
| 3253 } | 3365 } |
| 3254 | 3366 |
| 3255 | 3367 |
| 3256 TEST(DebugStepForBreak) { | 3368 TEST(DebugStepForBreak) { |
| 3257 DebugLocalContext env; | 3369 DebugLocalContext env; |
| 3258 v8::Isolate* isolate = env->GetIsolate(); | 3370 v8::Isolate* isolate = env->GetIsolate(); |
| 3259 v8::HandleScope scope(isolate); | 3371 v8::HandleScope scope(isolate); |
| 3260 | 3372 |
| 3261 // Register a debug event listener which steps and counts. | 3373 // Register a debug event listener which steps and counts. |
| 3262 v8::Debug::SetDebugEventListener(DebugEventStep); | 3374 v8::Debug::SetDebugEventListener(DebugEventStep); |
| 3263 | 3375 |
| 3376 v8::Local<v8::Context> context = env.context(); |
| 3264 // Create a function for testing stepping. Run it to allow it to get | 3377 // Create a function for testing stepping. Run it to allow it to get |
| 3265 // optimized. | 3378 // optimized. |
| 3266 const int argc = 1; | 3379 const int argc = 1; |
| 3267 const char* src = "function foo(x) { " | 3380 const char* src = "function foo(x) { " |
| 3268 " var a = 0;" | 3381 " var a = 0;" |
| 3269 " var b = 0;" | 3382 " var b = 0;" |
| 3270 " var c = 0;" | 3383 " var c = 0;" |
| 3271 " for (var i = 0; i < 1000; i++) {" | 3384 " for (var i = 0; i < 1000; i++) {" |
| 3272 " a++;" | 3385 " a++;" |
| 3273 " if (a == x) break;" | 3386 " if (a == x) break;" |
| 3274 " b++;" | 3387 " b++;" |
| 3275 " c++;" | 3388 " c++;" |
| 3276 " }" | 3389 " }" |
| 3277 " return b;" | 3390 " return b;" |
| 3278 "}" | 3391 "}" |
| 3279 "foo()"; | 3392 "foo()"; |
| 3280 v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); | 3393 v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); |
| 3281 v8::Handle<v8::Value> result; | 3394 v8::Local<v8::Value> result; |
| 3282 SetBreakPoint(foo, 8); // "var a = 0;" | 3395 SetBreakPoint(foo, 8); // "var a = 0;" |
| 3283 | 3396 |
| 3284 // Each loop generates 5 steps except for the last (when break is executed) | 3397 // Each loop generates 5 steps except for the last (when break is executed) |
| 3285 // which only generates 4. | 3398 // which only generates 4. |
| 3286 | 3399 |
| 3287 // Looping 10 times. | 3400 // Looping 10 times. |
| 3288 step_action = StepIn; | 3401 step_action = StepIn; |
| 3289 break_point_hit_count = 0; | 3402 break_point_hit_count = 0; |
| 3290 v8::Handle<v8::Value> argv_10[argc] = { v8::Number::New(isolate, 10) }; | 3403 v8::Local<v8::Value> argv_10[argc] = {v8::Number::New(isolate, 10)}; |
| 3291 result = foo->Call(env->Global(), argc, argv_10); | 3404 result = foo->Call(context, env->Global(), argc, argv_10).ToLocalChecked(); |
| 3292 CHECK_EQ(9, result->Int32Value()); | 3405 CHECK_EQ(9, result->Int32Value(context).FromJust()); |
| 3293 CHECK_EQ(64, break_point_hit_count); | 3406 CHECK_EQ(64, break_point_hit_count); |
| 3294 | 3407 |
| 3295 // Looping 100 times. | 3408 // Looping 100 times. |
| 3296 step_action = StepIn; | 3409 step_action = StepIn; |
| 3297 break_point_hit_count = 0; | 3410 break_point_hit_count = 0; |
| 3298 v8::Handle<v8::Value> argv_100[argc] = { v8::Number::New(isolate, 100) }; | 3411 v8::Local<v8::Value> argv_100[argc] = {v8::Number::New(isolate, 100)}; |
| 3299 result = foo->Call(env->Global(), argc, argv_100); | 3412 result = foo->Call(context, env->Global(), argc, argv_100).ToLocalChecked(); |
| 3300 CHECK_EQ(99, result->Int32Value()); | 3413 CHECK_EQ(99, result->Int32Value(context).FromJust()); |
| 3301 CHECK_EQ(604, break_point_hit_count); | 3414 CHECK_EQ(604, break_point_hit_count); |
| 3302 | 3415 |
| 3303 // Get rid of the debug event listener. | 3416 // Get rid of the debug event listener. |
| 3304 v8::Debug::SetDebugEventListener(NULL); | 3417 v8::Debug::SetDebugEventListener(NULL); |
| 3305 CheckDebuggerUnloaded(); | 3418 CheckDebuggerUnloaded(); |
| 3306 } | 3419 } |
| 3307 | 3420 |
| 3308 | 3421 |
| 3309 TEST(DebugStepForIn) { | 3422 TEST(DebugStepForIn) { |
| 3310 DebugLocalContext env; | 3423 DebugLocalContext env; |
| 3311 v8::HandleScope scope(env->GetIsolate()); | 3424 v8::HandleScope scope(env->GetIsolate()); |
| 3312 | 3425 |
| 3313 // Register a debug event listener which steps and counts. | 3426 // Register a debug event listener which steps and counts. |
| 3314 v8::Debug::SetDebugEventListener(DebugEventStep); | 3427 v8::Debug::SetDebugEventListener(DebugEventStep); |
| 3315 | 3428 |
| 3429 v8::Local<v8::Context> context = env.context(); |
| 3316 // Create a function for testing stepping. Run it to allow it to get | 3430 // Create a function for testing stepping. Run it to allow it to get |
| 3317 // optimized. | 3431 // optimized. |
| 3318 v8::Local<v8::Function> foo; | 3432 v8::Local<v8::Function> foo; |
| 3319 const char* src_1 = "function foo() { " | 3433 const char* src_1 = "function foo() { " |
| 3320 " var a = [1, 2];" | 3434 " var a = [1, 2];" |
| 3321 " for (x in a) {" | 3435 " for (x in a) {" |
| 3322 " b = 0;" | 3436 " b = 0;" |
| 3323 " }" | 3437 " }" |
| 3324 "}" | 3438 "}" |
| 3325 "foo()"; | 3439 "foo()"; |
| 3326 foo = CompileFunction(&env, src_1, "foo"); | 3440 foo = CompileFunction(&env, src_1, "foo"); |
| 3327 SetBreakPoint(foo, 0); // "var a = ..." | 3441 SetBreakPoint(foo, 0); // "var a = ..." |
| 3328 | 3442 |
| 3329 step_action = StepIn; | 3443 step_action = StepIn; |
| 3330 break_point_hit_count = 0; | 3444 break_point_hit_count = 0; |
| 3331 foo->Call(env->Global(), 0, NULL); | 3445 foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 3332 CHECK_EQ(8, break_point_hit_count); | 3446 CHECK_EQ(8, break_point_hit_count); |
| 3333 | 3447 |
| 3334 // Create a function for testing stepping. Run it to allow it to get | 3448 // Create a function for testing stepping. Run it to allow it to get |
| 3335 // optimized. | 3449 // optimized. |
| 3336 const char* src_2 = "function foo() { " | 3450 const char* src_2 = "function foo() { " |
| 3337 " var a = {a:[1, 2, 3]};" | 3451 " var a = {a:[1, 2, 3]};" |
| 3338 " for (x in a.a) {" | 3452 " for (x in a.a) {" |
| 3339 " b = 0;" | 3453 " b = 0;" |
| 3340 " }" | 3454 " }" |
| 3341 "}" | 3455 "}" |
| 3342 "foo()"; | 3456 "foo()"; |
| 3343 foo = CompileFunction(&env, src_2, "foo"); | 3457 foo = CompileFunction(&env, src_2, "foo"); |
| 3344 SetBreakPoint(foo, 0); // "var a = ..." | 3458 SetBreakPoint(foo, 0); // "var a = ..." |
| 3345 | 3459 |
| 3346 step_action = StepIn; | 3460 step_action = StepIn; |
| 3347 break_point_hit_count = 0; | 3461 break_point_hit_count = 0; |
| 3348 foo->Call(env->Global(), 0, NULL); | 3462 foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 3349 CHECK_EQ(10, break_point_hit_count); | 3463 CHECK_EQ(10, break_point_hit_count); |
| 3350 | 3464 |
| 3351 // Get rid of the debug event listener. | 3465 // Get rid of the debug event listener. |
| 3352 v8::Debug::SetDebugEventListener(NULL); | 3466 v8::Debug::SetDebugEventListener(NULL); |
| 3353 CheckDebuggerUnloaded(); | 3467 CheckDebuggerUnloaded(); |
| 3354 } | 3468 } |
| 3355 | 3469 |
| 3356 | 3470 |
| 3357 TEST(DebugStepWith) { | 3471 TEST(DebugStepWith) { |
| 3358 DebugLocalContext env; | 3472 DebugLocalContext env; |
| 3359 v8::HandleScope scope(env->GetIsolate()); | 3473 v8::HandleScope scope(env->GetIsolate()); |
| 3360 | 3474 |
| 3361 // Register a debug event listener which steps and counts. | 3475 // Register a debug event listener which steps and counts. |
| 3362 v8::Debug::SetDebugEventListener(DebugEventStep); | 3476 v8::Debug::SetDebugEventListener(DebugEventStep); |
| 3363 | 3477 |
| 3478 v8::Local<v8::Context> context = env.context(); |
| 3364 // Create a function for testing stepping. Run it to allow it to get | 3479 // Create a function for testing stepping. Run it to allow it to get |
| 3365 // optimized. | 3480 // optimized. |
| 3366 const char* src = "function foo(x) { " | 3481 const char* src = "function foo(x) { " |
| 3367 " var a = {};" | 3482 " var a = {};" |
| 3368 " with (a) {}" | 3483 " with (a) {}" |
| 3369 " with (b) {}" | 3484 " with (b) {}" |
| 3370 "}" | 3485 "}" |
| 3371 "foo()"; | 3486 "foo()"; |
| 3372 env->Global()->Set(v8::String::NewFromUtf8(env->GetIsolate(), "b"), | 3487 CHECK(env->Global() |
| 3373 v8::Object::New(env->GetIsolate())); | 3488 ->Set(context, v8_str(env->GetIsolate(), "b"), |
| 3489 v8::Object::New(env->GetIsolate())) |
| 3490 .FromJust()); |
| 3374 v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); | 3491 v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); |
| 3375 v8::Handle<v8::Value> result; | 3492 v8::Local<v8::Value> result; |
| 3376 SetBreakPoint(foo, 8); // "var a = {};" | 3493 SetBreakPoint(foo, 8); // "var a = {};" |
| 3377 | 3494 |
| 3378 step_action = StepIn; | 3495 step_action = StepIn; |
| 3379 break_point_hit_count = 0; | 3496 break_point_hit_count = 0; |
| 3380 foo->Call(env->Global(), 0, NULL); | 3497 foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 3381 CHECK_EQ(4, break_point_hit_count); | 3498 CHECK_EQ(4, break_point_hit_count); |
| 3382 | 3499 |
| 3383 // Get rid of the debug event listener. | 3500 // Get rid of the debug event listener. |
| 3384 v8::Debug::SetDebugEventListener(NULL); | 3501 v8::Debug::SetDebugEventListener(NULL); |
| 3385 CheckDebuggerUnloaded(); | 3502 CheckDebuggerUnloaded(); |
| 3386 } | 3503 } |
| 3387 | 3504 |
| 3388 | 3505 |
| 3389 TEST(DebugConditional) { | 3506 TEST(DebugConditional) { |
| 3390 DebugLocalContext env; | 3507 DebugLocalContext env; |
| 3391 v8::Isolate* isolate = env->GetIsolate(); | 3508 v8::Isolate* isolate = env->GetIsolate(); |
| 3392 v8::HandleScope scope(isolate); | 3509 v8::HandleScope scope(isolate); |
| 3393 | 3510 |
| 3394 // Register a debug event listener which steps and counts. | 3511 // Register a debug event listener which steps and counts. |
| 3395 v8::Debug::SetDebugEventListener(DebugEventStep); | 3512 v8::Debug::SetDebugEventListener(DebugEventStep); |
| 3396 | 3513 |
| 3514 v8::Local<v8::Context> context = env.context(); |
| 3397 // Create a function for testing stepping. Run it to allow it to get | 3515 // Create a function for testing stepping. Run it to allow it to get |
| 3398 // optimized. | 3516 // optimized. |
| 3399 const char* src = "function foo(x) { " | 3517 const char* src = "function foo(x) { " |
| 3400 " var a;" | 3518 " var a;" |
| 3401 " a = x ? 1 : 2;" | 3519 " a = x ? 1 : 2;" |
| 3402 " return a;" | 3520 " return a;" |
| 3403 "}" | 3521 "}" |
| 3404 "foo()"; | 3522 "foo()"; |
| 3405 v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); | 3523 v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); |
| 3406 SetBreakPoint(foo, 0); // "var a;" | 3524 SetBreakPoint(foo, 0); // "var a;" |
| 3407 | 3525 |
| 3408 step_action = StepIn; | 3526 step_action = StepIn; |
| 3409 break_point_hit_count = 0; | 3527 break_point_hit_count = 0; |
| 3410 foo->Call(env->Global(), 0, NULL); | 3528 foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 3411 CHECK_EQ(4, break_point_hit_count); | 3529 CHECK_EQ(4, break_point_hit_count); |
| 3412 | 3530 |
| 3413 step_action = StepIn; | 3531 step_action = StepIn; |
| 3414 break_point_hit_count = 0; | 3532 break_point_hit_count = 0; |
| 3415 const int argc = 1; | 3533 const int argc = 1; |
| 3416 v8::Handle<v8::Value> argv_true[argc] = { v8::True(isolate) }; | 3534 v8::Local<v8::Value> argv_true[argc] = {v8::True(isolate)}; |
| 3417 foo->Call(env->Global(), argc, argv_true); | 3535 foo->Call(context, env->Global(), argc, argv_true).ToLocalChecked(); |
| 3418 CHECK_EQ(4, break_point_hit_count); | 3536 CHECK_EQ(4, break_point_hit_count); |
| 3419 | 3537 |
| 3420 // Get rid of the debug event listener. | 3538 // Get rid of the debug event listener. |
| 3421 v8::Debug::SetDebugEventListener(NULL); | 3539 v8::Debug::SetDebugEventListener(NULL); |
| 3422 CheckDebuggerUnloaded(); | 3540 CheckDebuggerUnloaded(); |
| 3423 } | 3541 } |
| 3424 | 3542 |
| 3425 | 3543 |
| 3426 TEST(StepInOutSimple) { | 3544 TEST(StepInOutSimple) { |
| 3427 DebugLocalContext env; | 3545 DebugLocalContext env; |
| 3428 v8::HandleScope scope(env->GetIsolate()); | 3546 v8::HandleScope scope(env->GetIsolate()); |
| 3429 | 3547 |
| 3430 // Create a function for checking the function when hitting a break point. | 3548 // Create a function for checking the function when hitting a break point. |
| 3431 frame_function_name = CompileFunction(&env, | 3549 frame_function_name = CompileFunction(&env, |
| 3432 frame_function_name_source, | 3550 frame_function_name_source, |
| 3433 "frame_function_name"); | 3551 "frame_function_name"); |
| 3434 | 3552 |
| 3435 // Register a debug event listener which steps and counts. | 3553 // Register a debug event listener which steps and counts. |
| 3436 v8::Debug::SetDebugEventListener(DebugEventStepSequence); | 3554 v8::Debug::SetDebugEventListener(DebugEventStepSequence); |
| 3437 | 3555 |
| 3556 v8::Local<v8::Context> context = env.context(); |
| 3438 // Create a function for testing stepping. Run it to allow it to get | 3557 // Create a function for testing stepping. Run it to allow it to get |
| 3439 // optimized. | 3558 // optimized. |
| 3440 const char* src = "function a() {b();c();}; " | 3559 const char* src = "function a() {b();c();}; " |
| 3441 "function b() {c();}; " | 3560 "function b() {c();}; " |
| 3442 "function c() {}; " | 3561 "function c() {}; " |
| 3443 "a(); b(); c()"; | 3562 "a(); b(); c()"; |
| 3444 v8::Local<v8::Function> a = CompileFunction(&env, src, "a"); | 3563 v8::Local<v8::Function> a = CompileFunction(&env, src, "a"); |
| 3445 SetBreakPoint(a, 0); | 3564 SetBreakPoint(a, 0); |
| 3446 | 3565 |
| 3447 // Step through invocation of a with step in. | 3566 // Step through invocation of a with step in. |
| 3448 step_action = StepIn; | 3567 step_action = StepIn; |
| 3449 break_point_hit_count = 0; | 3568 break_point_hit_count = 0; |
| 3450 expected_step_sequence = "abcbaca"; | 3569 expected_step_sequence = "abcbaca"; |
| 3451 a->Call(env->Global(), 0, NULL); | 3570 a->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 3452 CHECK_EQ(StrLength(expected_step_sequence), | 3571 CHECK_EQ(StrLength(expected_step_sequence), |
| 3453 break_point_hit_count); | 3572 break_point_hit_count); |
| 3454 | 3573 |
| 3455 // Step through invocation of a with step next. | 3574 // Step through invocation of a with step next. |
| 3456 step_action = StepNext; | 3575 step_action = StepNext; |
| 3457 break_point_hit_count = 0; | 3576 break_point_hit_count = 0; |
| 3458 expected_step_sequence = "aaa"; | 3577 expected_step_sequence = "aaa"; |
| 3459 a->Call(env->Global(), 0, NULL); | 3578 a->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 3460 CHECK_EQ(StrLength(expected_step_sequence), | 3579 CHECK_EQ(StrLength(expected_step_sequence), |
| 3461 break_point_hit_count); | 3580 break_point_hit_count); |
| 3462 | 3581 |
| 3463 // Step through invocation of a with step out. | 3582 // Step through invocation of a with step out. |
| 3464 step_action = StepOut; | 3583 step_action = StepOut; |
| 3465 break_point_hit_count = 0; | 3584 break_point_hit_count = 0; |
| 3466 expected_step_sequence = "a"; | 3585 expected_step_sequence = "a"; |
| 3467 a->Call(env->Global(), 0, NULL); | 3586 a->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 3468 CHECK_EQ(StrLength(expected_step_sequence), | 3587 CHECK_EQ(StrLength(expected_step_sequence), |
| 3469 break_point_hit_count); | 3588 break_point_hit_count); |
| 3470 | 3589 |
| 3471 // Get rid of the debug event listener. | 3590 // Get rid of the debug event listener. |
| 3472 v8::Debug::SetDebugEventListener(NULL); | 3591 v8::Debug::SetDebugEventListener(NULL); |
| 3473 CheckDebuggerUnloaded(); | 3592 CheckDebuggerUnloaded(); |
| 3474 } | 3593 } |
| 3475 | 3594 |
| 3476 | 3595 |
| 3477 TEST(StepInOutTree) { | 3596 TEST(StepInOutTree) { |
| 3478 DebugLocalContext env; | 3597 DebugLocalContext env; |
| 3479 v8::HandleScope scope(env->GetIsolate()); | 3598 v8::HandleScope scope(env->GetIsolate()); |
| 3480 | 3599 |
| 3481 // Create a function for checking the function when hitting a break point. | 3600 // Create a function for checking the function when hitting a break point. |
| 3482 frame_function_name = CompileFunction(&env, | 3601 frame_function_name = CompileFunction(&env, |
| 3483 frame_function_name_source, | 3602 frame_function_name_source, |
| 3484 "frame_function_name"); | 3603 "frame_function_name"); |
| 3485 | 3604 |
| 3486 // Register a debug event listener which steps and counts. | 3605 // Register a debug event listener which steps and counts. |
| 3487 v8::Debug::SetDebugEventListener(DebugEventStepSequence); | 3606 v8::Debug::SetDebugEventListener(DebugEventStepSequence); |
| 3488 | 3607 |
| 3608 v8::Local<v8::Context> context = env.context(); |
| 3489 // Create a function for testing stepping. Run it to allow it to get | 3609 // Create a function for testing stepping. Run it to allow it to get |
| 3490 // optimized. | 3610 // optimized. |
| 3491 const char* src = "function a() {b(c(d()),d());c(d());d()}; " | 3611 const char* src = "function a() {b(c(d()),d());c(d());d()}; " |
| 3492 "function b(x,y) {c();}; " | 3612 "function b(x,y) {c();}; " |
| 3493 "function c(x) {}; " | 3613 "function c(x) {}; " |
| 3494 "function d() {}; " | 3614 "function d() {}; " |
| 3495 "a(); b(); c(); d()"; | 3615 "a(); b(); c(); d()"; |
| 3496 v8::Local<v8::Function> a = CompileFunction(&env, src, "a"); | 3616 v8::Local<v8::Function> a = CompileFunction(&env, src, "a"); |
| 3497 SetBreakPoint(a, 0); | 3617 SetBreakPoint(a, 0); |
| 3498 | 3618 |
| 3499 // Step through invocation of a with step in. | 3619 // Step through invocation of a with step in. |
| 3500 step_action = StepIn; | 3620 step_action = StepIn; |
| 3501 break_point_hit_count = 0; | 3621 break_point_hit_count = 0; |
| 3502 expected_step_sequence = "adacadabcbadacada"; | 3622 expected_step_sequence = "adacadabcbadacada"; |
| 3503 a->Call(env->Global(), 0, NULL); | 3623 a->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 3504 CHECK_EQ(StrLength(expected_step_sequence), | 3624 CHECK_EQ(StrLength(expected_step_sequence), |
| 3505 break_point_hit_count); | 3625 break_point_hit_count); |
| 3506 | 3626 |
| 3507 // Step through invocation of a with step next. | 3627 // Step through invocation of a with step next. |
| 3508 step_action = StepNext; | 3628 step_action = StepNext; |
| 3509 break_point_hit_count = 0; | 3629 break_point_hit_count = 0; |
| 3510 expected_step_sequence = "aaaa"; | 3630 expected_step_sequence = "aaaa"; |
| 3511 a->Call(env->Global(), 0, NULL); | 3631 a->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 3512 CHECK_EQ(StrLength(expected_step_sequence), | 3632 CHECK_EQ(StrLength(expected_step_sequence), |
| 3513 break_point_hit_count); | 3633 break_point_hit_count); |
| 3514 | 3634 |
| 3515 // Step through invocation of a with step out. | 3635 // Step through invocation of a with step out. |
| 3516 step_action = StepOut; | 3636 step_action = StepOut; |
| 3517 break_point_hit_count = 0; | 3637 break_point_hit_count = 0; |
| 3518 expected_step_sequence = "a"; | 3638 expected_step_sequence = "a"; |
| 3519 a->Call(env->Global(), 0, NULL); | 3639 a->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 3520 CHECK_EQ(StrLength(expected_step_sequence), | 3640 CHECK_EQ(StrLength(expected_step_sequence), |
| 3521 break_point_hit_count); | 3641 break_point_hit_count); |
| 3522 | 3642 |
| 3523 // Get rid of the debug event listener. | 3643 // Get rid of the debug event listener. |
| 3524 v8::Debug::SetDebugEventListener(NULL); | 3644 v8::Debug::SetDebugEventListener(NULL); |
| 3525 CheckDebuggerUnloaded(true); | 3645 CheckDebuggerUnloaded(true); |
| 3526 } | 3646 } |
| 3527 | 3647 |
| 3528 | 3648 |
| 3529 TEST(StepInOutBranch) { | 3649 TEST(StepInOutBranch) { |
| 3530 DebugLocalContext env; | 3650 DebugLocalContext env; |
| 3531 v8::HandleScope scope(env->GetIsolate()); | 3651 v8::HandleScope scope(env->GetIsolate()); |
| 3532 | 3652 |
| 3533 // Create a function for checking the function when hitting a break point. | 3653 // Create a function for checking the function when hitting a break point. |
| 3534 frame_function_name = CompileFunction(&env, | 3654 frame_function_name = CompileFunction(&env, |
| 3535 frame_function_name_source, | 3655 frame_function_name_source, |
| 3536 "frame_function_name"); | 3656 "frame_function_name"); |
| 3537 | 3657 |
| 3538 // Register a debug event listener which steps and counts. | 3658 // Register a debug event listener which steps and counts. |
| 3539 v8::Debug::SetDebugEventListener(DebugEventStepSequence); | 3659 v8::Debug::SetDebugEventListener(DebugEventStepSequence); |
| 3540 | 3660 |
| 3661 v8::Local<v8::Context> context = env.context(); |
| 3541 // Create a function for testing stepping. Run it to allow it to get | 3662 // Create a function for testing stepping. Run it to allow it to get |
| 3542 // optimized. | 3663 // optimized. |
| 3543 const char* src = "function a() {b(false);c();}; " | 3664 const char* src = "function a() {b(false);c();}; " |
| 3544 "function b(x) {if(x){c();};}; " | 3665 "function b(x) {if(x){c();};}; " |
| 3545 "function c() {}; " | 3666 "function c() {}; " |
| 3546 "a(); b(); c()"; | 3667 "a(); b(); c()"; |
| 3547 v8::Local<v8::Function> a = CompileFunction(&env, src, "a"); | 3668 v8::Local<v8::Function> a = CompileFunction(&env, src, "a"); |
| 3548 SetBreakPoint(a, 0); | 3669 SetBreakPoint(a, 0); |
| 3549 | 3670 |
| 3550 // Step through invocation of a. | 3671 // Step through invocation of a. |
| 3551 step_action = StepIn; | 3672 step_action = StepIn; |
| 3552 break_point_hit_count = 0; | 3673 break_point_hit_count = 0; |
| 3553 expected_step_sequence = "abbaca"; | 3674 expected_step_sequence = "abbaca"; |
| 3554 a->Call(env->Global(), 0, NULL); | 3675 a->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 3555 CHECK_EQ(StrLength(expected_step_sequence), | 3676 CHECK_EQ(StrLength(expected_step_sequence), |
| 3556 break_point_hit_count); | 3677 break_point_hit_count); |
| 3557 | 3678 |
| 3558 // Get rid of the debug event listener. | 3679 // Get rid of the debug event listener. |
| 3559 v8::Debug::SetDebugEventListener(NULL); | 3680 v8::Debug::SetDebugEventListener(NULL); |
| 3560 CheckDebuggerUnloaded(); | 3681 CheckDebuggerUnloaded(); |
| 3561 } | 3682 } |
| 3562 | 3683 |
| 3563 | 3684 |
| 3564 // Test that step in does not step into native functions. | 3685 // Test that step in does not step into native functions. |
| 3565 TEST(DebugStepNatives) { | 3686 TEST(DebugStepNatives) { |
| 3566 DebugLocalContext env; | 3687 DebugLocalContext env; |
| 3567 v8::HandleScope scope(env->GetIsolate()); | 3688 v8::HandleScope scope(env->GetIsolate()); |
| 3568 | 3689 |
| 3569 // Create a function for testing stepping. | 3690 // Create a function for testing stepping. |
| 3570 v8::Local<v8::Function> foo = CompileFunction( | 3691 v8::Local<v8::Function> foo = CompileFunction( |
| 3571 &env, | 3692 &env, |
| 3572 "function foo(){debugger;Math.sin(1);}", | 3693 "function foo(){debugger;Math.sin(1);}", |
| 3573 "foo"); | 3694 "foo"); |
| 3574 | 3695 |
| 3575 // Register a debug event listener which steps and counts. | 3696 // Register a debug event listener which steps and counts. |
| 3576 v8::Debug::SetDebugEventListener(DebugEventStep); | 3697 v8::Debug::SetDebugEventListener(DebugEventStep); |
| 3577 | 3698 |
| 3699 v8::Local<v8::Context> context = env.context(); |
| 3578 step_action = StepIn; | 3700 step_action = StepIn; |
| 3579 break_point_hit_count = 0; | 3701 break_point_hit_count = 0; |
| 3580 foo->Call(env->Global(), 0, NULL); | 3702 foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 3581 | 3703 |
| 3582 // With stepping all break locations are hit. | 3704 // With stepping all break locations are hit. |
| 3583 CHECK_EQ(3, break_point_hit_count); | 3705 CHECK_EQ(3, break_point_hit_count); |
| 3584 | 3706 |
| 3585 v8::Debug::SetDebugEventListener(NULL); | 3707 v8::Debug::SetDebugEventListener(NULL); |
| 3586 CheckDebuggerUnloaded(); | 3708 CheckDebuggerUnloaded(); |
| 3587 | 3709 |
| 3588 // Register a debug event listener which just counts. | 3710 // Register a debug event listener which just counts. |
| 3589 v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); | 3711 v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); |
| 3590 | 3712 |
| 3591 break_point_hit_count = 0; | 3713 break_point_hit_count = 0; |
| 3592 foo->Call(env->Global(), 0, NULL); | 3714 foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 3593 | 3715 |
| 3594 // Without stepping only active break points are hit. | 3716 // Without stepping only active break points are hit. |
| 3595 CHECK_EQ(1, break_point_hit_count); | 3717 CHECK_EQ(1, break_point_hit_count); |
| 3596 | 3718 |
| 3597 v8::Debug::SetDebugEventListener(NULL); | 3719 v8::Debug::SetDebugEventListener(NULL); |
| 3598 CheckDebuggerUnloaded(); | 3720 CheckDebuggerUnloaded(); |
| 3599 } | 3721 } |
| 3600 | 3722 |
| 3601 | 3723 |
| 3602 // Test that step in works with function.apply. | 3724 // Test that step in works with function.apply. |
| 3603 TEST(DebugStepFunctionApply) { | 3725 TEST(DebugStepFunctionApply) { |
| 3604 DebugLocalContext env; | 3726 DebugLocalContext env; |
| 3605 v8::HandleScope scope(env->GetIsolate()); | 3727 v8::HandleScope scope(env->GetIsolate()); |
| 3606 | 3728 |
| 3607 // Create a function for testing stepping. | 3729 // Create a function for testing stepping. |
| 3608 v8::Local<v8::Function> foo = CompileFunction( | 3730 v8::Local<v8::Function> foo = CompileFunction( |
| 3609 &env, | 3731 &env, |
| 3610 "function bar(x, y, z) { if (x == 1) { a = y; b = z; } }" | 3732 "function bar(x, y, z) { if (x == 1) { a = y; b = z; } }" |
| 3611 "function foo(){ debugger; bar.apply(this, [1,2,3]); }", | 3733 "function foo(){ debugger; bar.apply(this, [1,2,3]); }", |
| 3612 "foo"); | 3734 "foo"); |
| 3613 | 3735 |
| 3614 // Register a debug event listener which steps and counts. | 3736 // Register a debug event listener which steps and counts. |
| 3615 v8::Debug::SetDebugEventListener(DebugEventStep); | 3737 v8::Debug::SetDebugEventListener(DebugEventStep); |
| 3616 | 3738 |
| 3739 v8::Local<v8::Context> context = env.context(); |
| 3617 step_action = StepIn; | 3740 step_action = StepIn; |
| 3618 break_point_hit_count = 0; | 3741 break_point_hit_count = 0; |
| 3619 foo->Call(env->Global(), 0, NULL); | 3742 foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 3620 | 3743 |
| 3621 // With stepping all break locations are hit. | 3744 // With stepping all break locations are hit. |
| 3622 CHECK_EQ(7, break_point_hit_count); | 3745 CHECK_EQ(7, break_point_hit_count); |
| 3623 | 3746 |
| 3624 v8::Debug::SetDebugEventListener(NULL); | 3747 v8::Debug::SetDebugEventListener(NULL); |
| 3625 CheckDebuggerUnloaded(); | 3748 CheckDebuggerUnloaded(); |
| 3626 | 3749 |
| 3627 // Register a debug event listener which just counts. | 3750 // Register a debug event listener which just counts. |
| 3628 v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); | 3751 v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); |
| 3629 | 3752 |
| 3630 break_point_hit_count = 0; | 3753 break_point_hit_count = 0; |
| 3631 foo->Call(env->Global(), 0, NULL); | 3754 foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 3632 | 3755 |
| 3633 // Without stepping only the debugger statement is hit. | 3756 // Without stepping only the debugger statement is hit. |
| 3634 CHECK_EQ(1, break_point_hit_count); | 3757 CHECK_EQ(1, break_point_hit_count); |
| 3635 | 3758 |
| 3636 v8::Debug::SetDebugEventListener(NULL); | 3759 v8::Debug::SetDebugEventListener(NULL); |
| 3637 CheckDebuggerUnloaded(); | 3760 CheckDebuggerUnloaded(); |
| 3638 } | 3761 } |
| 3639 | 3762 |
| 3640 | 3763 |
| 3641 // Test that step in works with function.call. | 3764 // Test that step in works with function.call. |
| 3642 TEST(DebugStepFunctionCall) { | 3765 TEST(DebugStepFunctionCall) { |
| 3643 DebugLocalContext env; | 3766 DebugLocalContext env; |
| 3644 v8::Isolate* isolate = env->GetIsolate(); | 3767 v8::Isolate* isolate = env->GetIsolate(); |
| 3645 v8::HandleScope scope(isolate); | 3768 v8::HandleScope scope(isolate); |
| 3646 | 3769 |
| 3770 v8::Local<v8::Context> context = env.context(); |
| 3647 // Create a function for testing stepping. | 3771 // Create a function for testing stepping. |
| 3648 v8::Local<v8::Function> foo = CompileFunction( | 3772 v8::Local<v8::Function> foo = CompileFunction( |
| 3649 &env, | 3773 &env, |
| 3650 "function bar(x, y, z) { if (x == 1) { a = y; b = z; } }" | 3774 "function bar(x, y, z) { if (x == 1) { a = y; b = z; } }" |
| 3651 "function foo(a){ debugger;" | 3775 "function foo(a){ debugger;" |
| 3652 " if (a) {" | 3776 " if (a) {" |
| 3653 " bar.call(this, 1, 2, 3);" | 3777 " bar.call(this, 1, 2, 3);" |
| 3654 " } else {" | 3778 " } else {" |
| 3655 " bar.call(this, 0);" | 3779 " bar.call(this, 0);" |
| 3656 " }" | 3780 " }" |
| 3657 "}", | 3781 "}", |
| 3658 "foo"); | 3782 "foo"); |
| 3659 | 3783 |
| 3660 // Register a debug event listener which steps and counts. | 3784 // Register a debug event listener which steps and counts. |
| 3661 v8::Debug::SetDebugEventListener(DebugEventStep); | 3785 v8::Debug::SetDebugEventListener(DebugEventStep); |
| 3662 step_action = StepIn; | 3786 step_action = StepIn; |
| 3663 | 3787 |
| 3664 // Check stepping where the if condition in bar is false. | 3788 // Check stepping where the if condition in bar is false. |
| 3665 break_point_hit_count = 0; | 3789 break_point_hit_count = 0; |
| 3666 foo->Call(env->Global(), 0, NULL); | 3790 foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 3667 CHECK_EQ(6, break_point_hit_count); | 3791 CHECK_EQ(6, break_point_hit_count); |
| 3668 | 3792 |
| 3669 // Check stepping where the if condition in bar is true. | 3793 // Check stepping where the if condition in bar is true. |
| 3670 break_point_hit_count = 0; | 3794 break_point_hit_count = 0; |
| 3671 const int argc = 1; | 3795 const int argc = 1; |
| 3672 v8::Handle<v8::Value> argv[argc] = { v8::True(isolate) }; | 3796 v8::Local<v8::Value> argv[argc] = {v8::True(isolate)}; |
| 3673 foo->Call(env->Global(), argc, argv); | 3797 foo->Call(context, env->Global(), argc, argv).ToLocalChecked(); |
| 3674 CHECK_EQ(8, break_point_hit_count); | 3798 CHECK_EQ(8, break_point_hit_count); |
| 3675 | 3799 |
| 3676 v8::Debug::SetDebugEventListener(NULL); | 3800 v8::Debug::SetDebugEventListener(NULL); |
| 3677 CheckDebuggerUnloaded(); | 3801 CheckDebuggerUnloaded(); |
| 3678 | 3802 |
| 3679 // Register a debug event listener which just counts. | 3803 // Register a debug event listener which just counts. |
| 3680 v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); | 3804 v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); |
| 3681 | 3805 |
| 3682 break_point_hit_count = 0; | 3806 break_point_hit_count = 0; |
| 3683 foo->Call(env->Global(), 0, NULL); | 3807 foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 3684 | 3808 |
| 3685 // Without stepping only the debugger statement is hit. | 3809 // Without stepping only the debugger statement is hit. |
| 3686 CHECK_EQ(1, break_point_hit_count); | 3810 CHECK_EQ(1, break_point_hit_count); |
| 3687 | 3811 |
| 3688 v8::Debug::SetDebugEventListener(NULL); | 3812 v8::Debug::SetDebugEventListener(NULL); |
| 3689 CheckDebuggerUnloaded(); | 3813 CheckDebuggerUnloaded(); |
| 3690 } | 3814 } |
| 3691 | 3815 |
| 3692 | 3816 |
| 3693 // Test that step in works with Function.call.apply. | 3817 // Test that step in works with Function.call.apply. |
| 3694 TEST(DebugStepFunctionCallApply) { | 3818 TEST(DebugStepFunctionCallApply) { |
| 3695 DebugLocalContext env; | 3819 DebugLocalContext env; |
| 3696 v8::Isolate* isolate = env->GetIsolate(); | 3820 v8::Isolate* isolate = env->GetIsolate(); |
| 3697 v8::HandleScope scope(isolate); | 3821 v8::HandleScope scope(isolate); |
| 3698 | 3822 |
| 3823 v8::Local<v8::Context> context = env.context(); |
| 3699 // Create a function for testing stepping. | 3824 // Create a function for testing stepping. |
| 3700 v8::Local<v8::Function> foo = | 3825 v8::Local<v8::Function> foo = |
| 3701 CompileFunction(&env, | 3826 CompileFunction(&env, |
| 3702 "function bar() { }" | 3827 "function bar() { }" |
| 3703 "function foo(){ debugger;" | 3828 "function foo(){ debugger;" |
| 3704 " Function.call.apply(bar);" | 3829 " Function.call.apply(bar);" |
| 3705 " Function.call.apply(Function.call, " | 3830 " Function.call.apply(Function.call, " |
| 3706 "[Function.call, bar]);" | 3831 "[Function.call, bar]);" |
| 3707 "}", | 3832 "}", |
| 3708 "foo"); | 3833 "foo"); |
| 3709 | 3834 |
| 3710 // Register a debug event listener which steps and counts. | 3835 // Register a debug event listener which steps and counts. |
| 3711 v8::Debug::SetDebugEventListener(DebugEventStep); | 3836 v8::Debug::SetDebugEventListener(DebugEventStep); |
| 3712 step_action = StepIn; | 3837 step_action = StepIn; |
| 3713 | 3838 |
| 3714 break_point_hit_count = 0; | 3839 break_point_hit_count = 0; |
| 3715 foo->Call(env->Global(), 0, NULL); | 3840 foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 3716 CHECK_EQ(5, break_point_hit_count); | 3841 CHECK_EQ(5, break_point_hit_count); |
| 3717 | 3842 |
| 3718 v8::Debug::SetDebugEventListener(NULL); | 3843 v8::Debug::SetDebugEventListener(NULL); |
| 3719 CheckDebuggerUnloaded(); | 3844 CheckDebuggerUnloaded(); |
| 3720 | 3845 |
| 3721 // Register a debug event listener which just counts. | 3846 // Register a debug event listener which just counts. |
| 3722 v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); | 3847 v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); |
| 3723 | 3848 |
| 3724 break_point_hit_count = 0; | 3849 break_point_hit_count = 0; |
| 3725 foo->Call(env->Global(), 0, NULL); | 3850 foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 3726 | 3851 |
| 3727 // Without stepping only the debugger statement is hit. | 3852 // Without stepping only the debugger statement is hit. |
| 3728 CHECK_EQ(1, break_point_hit_count); | 3853 CHECK_EQ(1, break_point_hit_count); |
| 3729 | 3854 |
| 3730 v8::Debug::SetDebugEventListener(NULL); | 3855 v8::Debug::SetDebugEventListener(NULL); |
| 3731 CheckDebuggerUnloaded(); | 3856 CheckDebuggerUnloaded(); |
| 3732 } | 3857 } |
| 3733 | 3858 |
| 3734 | 3859 |
| 3735 // Tests that breakpoint will be hit if it's set in script. | 3860 // Tests that breakpoint will be hit if it's set in script. |
| 3736 TEST(PauseInScript) { | 3861 TEST(PauseInScript) { |
| 3737 DebugLocalContext env; | 3862 DebugLocalContext env; |
| 3738 v8::HandleScope scope(env->GetIsolate()); | 3863 v8::HandleScope scope(env->GetIsolate()); |
| 3739 env.ExposeDebug(); | 3864 env.ExposeDebug(); |
| 3740 | 3865 |
| 3741 // Register a debug event listener which counts. | 3866 // Register a debug event listener which counts. |
| 3742 v8::Debug::SetDebugEventListener(DebugEventCounter); | 3867 v8::Debug::SetDebugEventListener(DebugEventCounter); |
| 3743 | 3868 |
| 3869 v8::Local<v8::Context> context = env.context(); |
| 3744 // Create a script that returns a function. | 3870 // Create a script that returns a function. |
| 3745 const char* src = "(function (evt) {})"; | 3871 const char* src = "(function (evt) {})"; |
| 3746 const char* script_name = "StepInHandlerTest"; | 3872 const char* script_name = "StepInHandlerTest"; |
| 3747 | 3873 |
| 3748 // Set breakpoint in the script. | 3874 // Set breakpoint in the script. |
| 3749 SetScriptBreakPointByNameFromJS(env->GetIsolate(), script_name, 0, -1); | 3875 SetScriptBreakPointByNameFromJS(env->GetIsolate(), script_name, 0, -1); |
| 3750 break_point_hit_count = 0; | 3876 break_point_hit_count = 0; |
| 3751 | 3877 |
| 3752 v8::ScriptOrigin origin( | 3878 v8::ScriptOrigin origin(v8_str(env->GetIsolate(), script_name), |
| 3753 v8::String::NewFromUtf8(env->GetIsolate(), script_name), | 3879 v8::Integer::New(env->GetIsolate(), 0)); |
| 3754 v8::Integer::New(env->GetIsolate(), 0)); | 3880 v8::Local<v8::Script> script = |
| 3755 v8::Handle<v8::Script> script = v8::Script::Compile( | 3881 v8::Script::Compile(context, v8_str(env->GetIsolate(), src), &origin) |
| 3756 v8::String::NewFromUtf8(env->GetIsolate(), src), &origin); | 3882 .ToLocalChecked(); |
| 3757 v8::Local<v8::Value> r = script->Run(); | 3883 v8::Local<v8::Value> r = script->Run(context).ToLocalChecked(); |
| 3758 | 3884 |
| 3759 CHECK(r->IsFunction()); | 3885 CHECK(r->IsFunction()); |
| 3760 CHECK_EQ(1, break_point_hit_count); | 3886 CHECK_EQ(1, break_point_hit_count); |
| 3761 | 3887 |
| 3762 // Get rid of the debug event listener. | 3888 // Get rid of the debug event listener. |
| 3763 v8::Debug::SetDebugEventListener(NULL); | 3889 v8::Debug::SetDebugEventListener(NULL); |
| 3764 CheckDebuggerUnloaded(); | 3890 CheckDebuggerUnloaded(); |
| 3765 } | 3891 } |
| 3766 | 3892 |
| 3767 | 3893 |
| 3768 static void DebugEventCounterCheck(int caught, int uncaught, int message) { | 3894 static void DebugEventCounterCheck(int caught, int uncaught, int message) { |
| 3769 CHECK_EQ(caught, exception_hit_count); | 3895 CHECK_EQ(caught, exception_hit_count); |
| 3770 CHECK_EQ(uncaught, uncaught_exception_hit_count); | 3896 CHECK_EQ(uncaught, uncaught_exception_hit_count); |
| 3771 CHECK_EQ(message, message_callback_count); | 3897 CHECK_EQ(message, message_callback_count); |
| 3772 } | 3898 } |
| 3773 | 3899 |
| 3774 | 3900 |
| 3775 // Test break on exceptions. For each exception break combination the number | 3901 // Test break on exceptions. For each exception break combination the number |
| 3776 // of debug event exception callbacks and message callbacks are collected. The | 3902 // of debug event exception callbacks and message callbacks are collected. The |
| 3777 // number of debug event exception callbacks are used to check that the | 3903 // number of debug event exception callbacks are used to check that the |
| 3778 // debugger is called correctly and the number of message callbacks is used to | 3904 // debugger is called correctly and the number of message callbacks is used to |
| 3779 // check that uncaught exceptions are still returned even if there is a break | 3905 // check that uncaught exceptions are still returned even if there is a break |
| 3780 // for them. | 3906 // for them. |
| 3781 TEST(BreakOnException) { | 3907 TEST(BreakOnException) { |
| 3782 DebugLocalContext env; | 3908 DebugLocalContext env; |
| 3783 v8::HandleScope scope(env->GetIsolate()); | 3909 v8::HandleScope scope(env->GetIsolate()); |
| 3784 env.ExposeDebug(); | 3910 env.ExposeDebug(); |
| 3785 | 3911 |
| 3912 v8::Local<v8::Context> context = env.context(); |
| 3786 // Create functions for testing break on exception. | 3913 // Create functions for testing break on exception. |
| 3787 CompileFunction(&env, "function throws(){throw 1;}", "throws"); | 3914 CompileFunction(&env, "function throws(){throw 1;}", "throws"); |
| 3788 v8::Local<v8::Function> caught = | 3915 v8::Local<v8::Function> caught = |
| 3789 CompileFunction(&env, | 3916 CompileFunction(&env, |
| 3790 "function caught(){try {throws();} catch(e) {};}", | 3917 "function caught(){try {throws();} catch(e) {};}", |
| 3791 "caught"); | 3918 "caught"); |
| 3792 v8::Local<v8::Function> notCaught = | 3919 v8::Local<v8::Function> notCaught = |
| 3793 CompileFunction(&env, "function notCaught(){throws();}", "notCaught"); | 3920 CompileFunction(&env, "function notCaught(){throws();}", "notCaught"); |
| 3794 v8::Local<v8::Function> notCaughtFinally = CompileFunction( | 3921 v8::Local<v8::Function> notCaughtFinally = CompileFunction( |
| 3795 &env, "function notCaughtFinally(){try{throws();}finally{}}", | 3922 &env, "function notCaughtFinally(){try{throws();}finally{}}", |
| 3796 "notCaughtFinally"); | 3923 "notCaughtFinally"); |
| 3797 // In this edge case, even though this finally does not propagate the | 3924 // In this edge case, even though this finally does not propagate the |
| 3798 // exception, the debugger considers this uncaught, since we want to break | 3925 // exception, the debugger considers this uncaught, since we want to break |
| 3799 // at the first throw for the general case where finally implicitly rethrows. | 3926 // at the first throw for the general case where finally implicitly rethrows. |
| 3800 v8::Local<v8::Function> edgeCaseFinally = CompileFunction( | 3927 v8::Local<v8::Function> edgeCaseFinally = CompileFunction( |
| 3801 &env, "function caughtFinally(){L:try{throws();}finally{break L;}}", | 3928 &env, "function caughtFinally(){L:try{throws();}finally{break L;}}", |
| 3802 "caughtFinally"); | 3929 "caughtFinally"); |
| 3803 | 3930 |
| 3804 v8::V8::AddMessageListener(MessageCallbackCount); | 3931 env->GetIsolate()->AddMessageListener(MessageCallbackCount); |
| 3805 v8::Debug::SetDebugEventListener(DebugEventCounter); | 3932 v8::Debug::SetDebugEventListener(DebugEventCounter); |
| 3806 | 3933 |
| 3807 // Initial state should be no break on exceptions. | 3934 // Initial state should be no break on exceptions. |
| 3808 DebugEventCounterClear(); | 3935 DebugEventCounterClear(); |
| 3809 MessageCallbackCountClear(); | 3936 MessageCallbackCountClear(); |
| 3810 caught->Call(env->Global(), 0, NULL); | 3937 caught->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 3811 DebugEventCounterCheck(0, 0, 0); | 3938 DebugEventCounterCheck(0, 0, 0); |
| 3812 notCaught->Call(env->Global(), 0, NULL); | 3939 CHECK(notCaught->Call(context, env->Global(), 0, NULL).IsEmpty()); |
| 3813 DebugEventCounterCheck(0, 0, 1); | 3940 DebugEventCounterCheck(0, 0, 1); |
| 3814 notCaughtFinally->Call(env->Global(), 0, NULL); | 3941 CHECK(notCaughtFinally->Call(context, env->Global(), 0, NULL).IsEmpty()); |
| 3815 DebugEventCounterCheck(0, 0, 2); | 3942 DebugEventCounterCheck(0, 0, 2); |
| 3816 edgeCaseFinally->Call(env->Global(), 0, NULL); | 3943 edgeCaseFinally->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 3817 DebugEventCounterCheck(0, 0, 2); | 3944 DebugEventCounterCheck(0, 0, 2); |
| 3818 | 3945 |
| 3819 // No break on exception | 3946 // No break on exception |
| 3820 DebugEventCounterClear(); | 3947 DebugEventCounterClear(); |
| 3821 MessageCallbackCountClear(); | 3948 MessageCallbackCountClear(); |
| 3822 ChangeBreakOnException(false, false); | 3949 ChangeBreakOnException(false, false); |
| 3823 caught->Call(env->Global(), 0, NULL); | 3950 caught->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 3824 DebugEventCounterCheck(0, 0, 0); | 3951 DebugEventCounterCheck(0, 0, 0); |
| 3825 notCaught->Call(env->Global(), 0, NULL); | 3952 CHECK(notCaught->Call(context, env->Global(), 0, NULL).IsEmpty()); |
| 3826 DebugEventCounterCheck(0, 0, 1); | 3953 DebugEventCounterCheck(0, 0, 1); |
| 3827 notCaughtFinally->Call(env->Global(), 0, NULL); | 3954 CHECK(notCaughtFinally->Call(context, env->Global(), 0, NULL).IsEmpty()); |
| 3828 DebugEventCounterCheck(0, 0, 2); | 3955 DebugEventCounterCheck(0, 0, 2); |
| 3829 edgeCaseFinally->Call(env->Global(), 0, NULL); | 3956 edgeCaseFinally->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 3830 DebugEventCounterCheck(0, 0, 2); | 3957 DebugEventCounterCheck(0, 0, 2); |
| 3831 | 3958 |
| 3832 // Break on uncaught exception | 3959 // Break on uncaught exception |
| 3833 DebugEventCounterClear(); | 3960 DebugEventCounterClear(); |
| 3834 MessageCallbackCountClear(); | 3961 MessageCallbackCountClear(); |
| 3835 ChangeBreakOnException(false, true); | 3962 ChangeBreakOnException(false, true); |
| 3836 caught->Call(env->Global(), 0, NULL); | 3963 caught->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 3837 DebugEventCounterCheck(0, 0, 0); | 3964 DebugEventCounterCheck(0, 0, 0); |
| 3838 notCaught->Call(env->Global(), 0, NULL); | 3965 CHECK(notCaught->Call(context, env->Global(), 0, NULL).IsEmpty()); |
| 3839 DebugEventCounterCheck(1, 1, 1); | 3966 DebugEventCounterCheck(1, 1, 1); |
| 3840 notCaughtFinally->Call(env->Global(), 0, NULL); | 3967 CHECK(notCaughtFinally->Call(context, env->Global(), 0, NULL).IsEmpty()); |
| 3841 DebugEventCounterCheck(2, 2, 2); | 3968 DebugEventCounterCheck(2, 2, 2); |
| 3842 edgeCaseFinally->Call(env->Global(), 0, NULL); | 3969 edgeCaseFinally->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 3843 DebugEventCounterCheck(3, 3, 2); | 3970 DebugEventCounterCheck(3, 3, 2); |
| 3844 | 3971 |
| 3845 // Break on exception and uncaught exception | 3972 // Break on exception and uncaught exception |
| 3846 DebugEventCounterClear(); | 3973 DebugEventCounterClear(); |
| 3847 MessageCallbackCountClear(); | 3974 MessageCallbackCountClear(); |
| 3848 ChangeBreakOnException(true, true); | 3975 ChangeBreakOnException(true, true); |
| 3849 caught->Call(env->Global(), 0, NULL); | 3976 caught->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 3850 DebugEventCounterCheck(1, 0, 0); | 3977 DebugEventCounterCheck(1, 0, 0); |
| 3851 notCaught->Call(env->Global(), 0, NULL); | 3978 CHECK(notCaught->Call(context, env->Global(), 0, NULL).IsEmpty()); |
| 3852 DebugEventCounterCheck(2, 1, 1); | 3979 DebugEventCounterCheck(2, 1, 1); |
| 3853 notCaughtFinally->Call(env->Global(), 0, NULL); | 3980 CHECK(notCaughtFinally->Call(context, env->Global(), 0, NULL).IsEmpty()); |
| 3854 DebugEventCounterCheck(3, 2, 2); | 3981 DebugEventCounterCheck(3, 2, 2); |
| 3855 edgeCaseFinally->Call(env->Global(), 0, NULL); | 3982 edgeCaseFinally->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 3856 DebugEventCounterCheck(4, 3, 2); | 3983 DebugEventCounterCheck(4, 3, 2); |
| 3857 | 3984 |
| 3858 // Break on exception | 3985 // Break on exception |
| 3859 DebugEventCounterClear(); | 3986 DebugEventCounterClear(); |
| 3860 MessageCallbackCountClear(); | 3987 MessageCallbackCountClear(); |
| 3861 ChangeBreakOnException(true, false); | 3988 ChangeBreakOnException(true, false); |
| 3862 caught->Call(env->Global(), 0, NULL); | 3989 caught->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 3863 DebugEventCounterCheck(1, 0, 0); | 3990 DebugEventCounterCheck(1, 0, 0); |
| 3864 notCaught->Call(env->Global(), 0, NULL); | 3991 CHECK(notCaught->Call(context, env->Global(), 0, NULL).IsEmpty()); |
| 3865 DebugEventCounterCheck(2, 1, 1); | 3992 DebugEventCounterCheck(2, 1, 1); |
| 3866 notCaughtFinally->Call(env->Global(), 0, NULL); | 3993 CHECK(notCaughtFinally->Call(context, env->Global(), 0, NULL).IsEmpty()); |
| 3867 DebugEventCounterCheck(3, 2, 2); | 3994 DebugEventCounterCheck(3, 2, 2); |
| 3868 edgeCaseFinally->Call(env->Global(), 0, NULL); | 3995 edgeCaseFinally->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 3869 DebugEventCounterCheck(4, 3, 2); | 3996 DebugEventCounterCheck(4, 3, 2); |
| 3870 | 3997 |
| 3871 // No break on exception using JavaScript | 3998 // No break on exception using JavaScript |
| 3872 DebugEventCounterClear(); | 3999 DebugEventCounterClear(); |
| 3873 MessageCallbackCountClear(); | 4000 MessageCallbackCountClear(); |
| 3874 ChangeBreakOnExceptionFromJS(env->GetIsolate(), false, false); | 4001 ChangeBreakOnExceptionFromJS(env->GetIsolate(), false, false); |
| 3875 caught->Call(env->Global(), 0, NULL); | 4002 caught->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 3876 DebugEventCounterCheck(0, 0, 0); | 4003 DebugEventCounterCheck(0, 0, 0); |
| 3877 notCaught->Call(env->Global(), 0, NULL); | 4004 CHECK(notCaught->Call(context, env->Global(), 0, NULL).IsEmpty()); |
| 3878 DebugEventCounterCheck(0, 0, 1); | 4005 DebugEventCounterCheck(0, 0, 1); |
| 3879 notCaughtFinally->Call(env->Global(), 0, NULL); | 4006 CHECK(notCaughtFinally->Call(context, env->Global(), 0, NULL).IsEmpty()); |
| 3880 DebugEventCounterCheck(0, 0, 2); | 4007 DebugEventCounterCheck(0, 0, 2); |
| 3881 edgeCaseFinally->Call(env->Global(), 0, NULL); | 4008 edgeCaseFinally->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 3882 DebugEventCounterCheck(0, 0, 2); | 4009 DebugEventCounterCheck(0, 0, 2); |
| 3883 | 4010 |
| 3884 // Break on uncaught exception using JavaScript | 4011 // Break on uncaught exception using JavaScript |
| 3885 DebugEventCounterClear(); | 4012 DebugEventCounterClear(); |
| 3886 MessageCallbackCountClear(); | 4013 MessageCallbackCountClear(); |
| 3887 ChangeBreakOnExceptionFromJS(env->GetIsolate(), false, true); | 4014 ChangeBreakOnExceptionFromJS(env->GetIsolate(), false, true); |
| 3888 caught->Call(env->Global(), 0, NULL); | 4015 caught->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 3889 DebugEventCounterCheck(0, 0, 0); | 4016 DebugEventCounterCheck(0, 0, 0); |
| 3890 notCaught->Call(env->Global(), 0, NULL); | 4017 CHECK(notCaught->Call(context, env->Global(), 0, NULL).IsEmpty()); |
| 3891 DebugEventCounterCheck(1, 1, 1); | 4018 DebugEventCounterCheck(1, 1, 1); |
| 3892 notCaughtFinally->Call(env->Global(), 0, NULL); | 4019 CHECK(notCaughtFinally->Call(context, env->Global(), 0, NULL).IsEmpty()); |
| 3893 DebugEventCounterCheck(2, 2, 2); | 4020 DebugEventCounterCheck(2, 2, 2); |
| 3894 edgeCaseFinally->Call(env->Global(), 0, NULL); | 4021 edgeCaseFinally->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 3895 DebugEventCounterCheck(3, 3, 2); | 4022 DebugEventCounterCheck(3, 3, 2); |
| 3896 | 4023 |
| 3897 // Break on exception and uncaught exception using JavaScript | 4024 // Break on exception and uncaught exception using JavaScript |
| 3898 DebugEventCounterClear(); | 4025 DebugEventCounterClear(); |
| 3899 MessageCallbackCountClear(); | 4026 MessageCallbackCountClear(); |
| 3900 ChangeBreakOnExceptionFromJS(env->GetIsolate(), true, true); | 4027 ChangeBreakOnExceptionFromJS(env->GetIsolate(), true, true); |
| 3901 caught->Call(env->Global(), 0, NULL); | 4028 caught->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 3902 DebugEventCounterCheck(1, 0, 0); | 4029 DebugEventCounterCheck(1, 0, 0); |
| 3903 notCaught->Call(env->Global(), 0, NULL); | 4030 CHECK(notCaught->Call(context, env->Global(), 0, NULL).IsEmpty()); |
| 3904 DebugEventCounterCheck(2, 1, 1); | 4031 DebugEventCounterCheck(2, 1, 1); |
| 3905 notCaughtFinally->Call(env->Global(), 0, NULL); | 4032 CHECK(notCaughtFinally->Call(context, env->Global(), 0, NULL).IsEmpty()); |
| 3906 DebugEventCounterCheck(3, 2, 2); | 4033 DebugEventCounterCheck(3, 2, 2); |
| 3907 edgeCaseFinally->Call(env->Global(), 0, NULL); | 4034 edgeCaseFinally->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 3908 DebugEventCounterCheck(4, 3, 2); | 4035 DebugEventCounterCheck(4, 3, 2); |
| 3909 | 4036 |
| 3910 // Break on exception using JavaScript | 4037 // Break on exception using JavaScript |
| 3911 DebugEventCounterClear(); | 4038 DebugEventCounterClear(); |
| 3912 MessageCallbackCountClear(); | 4039 MessageCallbackCountClear(); |
| 3913 ChangeBreakOnExceptionFromJS(env->GetIsolate(), true, false); | 4040 ChangeBreakOnExceptionFromJS(env->GetIsolate(), true, false); |
| 3914 caught->Call(env->Global(), 0, NULL); | 4041 caught->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 3915 DebugEventCounterCheck(1, 0, 0); | 4042 DebugEventCounterCheck(1, 0, 0); |
| 3916 notCaught->Call(env->Global(), 0, NULL); | 4043 CHECK(notCaught->Call(context, env->Global(), 0, NULL).IsEmpty()); |
| 3917 DebugEventCounterCheck(2, 1, 1); | 4044 DebugEventCounterCheck(2, 1, 1); |
| 3918 notCaughtFinally->Call(env->Global(), 0, NULL); | 4045 CHECK(notCaughtFinally->Call(context, env->Global(), 0, NULL).IsEmpty()); |
| 3919 DebugEventCounterCheck(3, 2, 2); | 4046 DebugEventCounterCheck(3, 2, 2); |
| 3920 edgeCaseFinally->Call(env->Global(), 0, NULL); | 4047 edgeCaseFinally->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 3921 DebugEventCounterCheck(4, 3, 2); | 4048 DebugEventCounterCheck(4, 3, 2); |
| 3922 | 4049 |
| 3923 v8::Debug::SetDebugEventListener(NULL); | 4050 v8::Debug::SetDebugEventListener(NULL); |
| 3924 CheckDebuggerUnloaded(); | 4051 CheckDebuggerUnloaded(); |
| 3925 v8::V8::RemoveMessageListeners(MessageCallbackCount); | 4052 env->GetIsolate()->RemoveMessageListeners(MessageCallbackCount); |
| 3926 } | 4053 } |
| 3927 | 4054 |
| 3928 | 4055 |
| 3929 static void try_finally_original_message(v8::Handle<v8::Message> message, | 4056 static void try_finally_original_message(v8::Local<v8::Message> message, |
| 3930 v8::Handle<v8::Value> data) { | 4057 v8::Local<v8::Value> data) { |
| 3931 CHECK_EQ(2, message->GetLineNumber()); | 4058 v8::Local<v8::Context> context = CcTest::isolate()->GetCurrentContext(); |
| 3932 CHECK_EQ(2, message->GetStartColumn()); | 4059 CHECK_EQ(2, message->GetLineNumber(context).FromJust()); |
| 4060 CHECK_EQ(2, message->GetStartColumn(context).FromJust()); |
| 3933 message_callback_count++; | 4061 message_callback_count++; |
| 3934 } | 4062 } |
| 3935 | 4063 |
| 3936 | 4064 |
| 3937 TEST(TryFinallyOriginalMessage) { | 4065 TEST(TryFinallyOriginalMessage) { |
| 3938 // Test that the debugger plays nicely with the pending message. | 4066 // Test that the debugger plays nicely with the pending message. |
| 3939 message_callback_count = 0; | 4067 message_callback_count = 0; |
| 3940 DebugEventCounterClear(); | 4068 DebugEventCounterClear(); |
| 3941 v8::V8::AddMessageListener(try_finally_original_message); | 4069 DebugLocalContext env; |
| 4070 v8::Isolate* isolate = CcTest::isolate(); |
| 4071 isolate->AddMessageListener(try_finally_original_message); |
| 3942 v8::Debug::SetDebugEventListener(DebugEventCounter); | 4072 v8::Debug::SetDebugEventListener(DebugEventCounter); |
| 3943 ChangeBreakOnException(true, true); | 4073 ChangeBreakOnException(true, true); |
| 3944 DebugLocalContext env; | |
| 3945 v8::Isolate* isolate = CcTest::isolate(); | |
| 3946 v8::HandleScope scope(isolate); | 4074 v8::HandleScope scope(isolate); |
| 3947 CompileRun( | 4075 CompileRun( |
| 3948 "try {\n" | 4076 "try {\n" |
| 3949 " throw 1;\n" | 4077 " throw 1;\n" |
| 3950 "} finally {\n" | 4078 "} finally {\n" |
| 3951 "}\n"); | 4079 "}\n"); |
| 3952 DebugEventCounterCheck(1, 1, 1); | 4080 DebugEventCounterCheck(1, 1, 1); |
| 3953 v8::Debug::SetDebugEventListener(NULL); | 4081 v8::Debug::SetDebugEventListener(NULL); |
| 3954 v8::V8::RemoveMessageListeners(try_finally_original_message); | 4082 isolate->RemoveMessageListeners(try_finally_original_message); |
| 3955 } | 4083 } |
| 3956 | 4084 |
| 3957 | 4085 |
| 3958 TEST(EvalJSInDebugEventListenerOnNativeReThrownException) { | 4086 TEST(EvalJSInDebugEventListenerOnNativeReThrownException) { |
| 3959 DebugLocalContext env; | 4087 DebugLocalContext env; |
| 3960 v8::HandleScope scope(env->GetIsolate()); | 4088 v8::HandleScope scope(env->GetIsolate()); |
| 3961 env.ExposeDebug(); | 4089 env.ExposeDebug(); |
| 3962 | 4090 |
| 3963 // Create functions for testing break on exception. | 4091 // Create functions for testing break on exception. |
| 3964 v8::Local<v8::Function> noThrowJS = CompileFunction( | 4092 v8::Local<v8::Function> noThrowJS = CompileFunction( |
| 3965 &env, "function noThrowJS(){var a=[1]; a.push(2); return a.length;}", | 4093 &env, "function noThrowJS(){var a=[1]; a.push(2); return a.length;}", |
| 3966 "noThrowJS"); | 4094 "noThrowJS"); |
| 3967 | 4095 |
| 3968 debug_event_listener_callback = noThrowJS; | 4096 debug_event_listener_callback = noThrowJS; |
| 3969 debug_event_listener_callback_result = 2; | 4097 debug_event_listener_callback_result = 2; |
| 3970 | 4098 |
| 3971 v8::V8::AddMessageListener(MessageCallbackCount); | 4099 env->GetIsolate()->AddMessageListener(MessageCallbackCount); |
| 3972 v8::Debug::SetDebugEventListener(DebugEventCounter); | 4100 v8::Debug::SetDebugEventListener(DebugEventCounter); |
| 3973 // Break on uncaught exception | 4101 // Break on uncaught exception |
| 3974 ChangeBreakOnException(false, true); | 4102 ChangeBreakOnException(false, true); |
| 3975 DebugEventCounterClear(); | 4103 DebugEventCounterClear(); |
| 3976 MessageCallbackCountClear(); | 4104 MessageCallbackCountClear(); |
| 3977 | 4105 |
| 3978 // ReThrow native error | 4106 // ReThrow native error |
| 3979 { | 4107 { |
| 3980 v8::TryCatch tryCatch(env->GetIsolate()); | 4108 v8::TryCatch tryCatch(env->GetIsolate()); |
| 3981 env->GetIsolate()->ThrowException(v8::Exception::TypeError( | 4109 env->GetIsolate()->ThrowException( |
| 3982 v8::String::NewFromUtf8(env->GetIsolate(), "Type error"))); | 4110 v8::Exception::TypeError(v8_str(env->GetIsolate(), "Type error"))); |
| 3983 CHECK(tryCatch.HasCaught()); | 4111 CHECK(tryCatch.HasCaught()); |
| 3984 tryCatch.ReThrow(); | 4112 tryCatch.ReThrow(); |
| 3985 } | 4113 } |
| 3986 CHECK_EQ(1, exception_hit_count); | 4114 CHECK_EQ(1, exception_hit_count); |
| 3987 CHECK_EQ(1, uncaught_exception_hit_count); | 4115 CHECK_EQ(1, uncaught_exception_hit_count); |
| 3988 CHECK_EQ(0, message_callback_count); // FIXME: Should it be 1 ? | 4116 CHECK_EQ(0, message_callback_count); // FIXME: Should it be 1 ? |
| 3989 CHECK(!debug_event_listener_callback.IsEmpty()); | 4117 CHECK(!debug_event_listener_callback.IsEmpty()); |
| 3990 | 4118 |
| 3991 debug_event_listener_callback.Clear(); | 4119 debug_event_listener_callback.Clear(); |
| 3992 } | 4120 } |
| 3993 | 4121 |
| 3994 | 4122 |
| 3995 // Test break on exception from compiler errors. When compiling using | 4123 // Test break on exception from compiler errors. When compiling using |
| 3996 // v8::Script::Compile there is no JavaScript stack whereas when compiling using | 4124 // v8::Script::Compile there is no JavaScript stack whereas when compiling using |
| 3997 // eval there are JavaScript frames. | 4125 // eval there are JavaScript frames. |
| 3998 TEST(BreakOnCompileException) { | 4126 TEST(BreakOnCompileException) { |
| 3999 DebugLocalContext env; | 4127 DebugLocalContext env; |
| 4000 v8::HandleScope scope(env->GetIsolate()); | 4128 v8::HandleScope scope(env->GetIsolate()); |
| 4001 | 4129 |
| 4130 v8::Local<v8::Context> context = env.context(); |
| 4002 // For this test, we want to break on uncaught exceptions: | 4131 // For this test, we want to break on uncaught exceptions: |
| 4003 ChangeBreakOnException(false, true); | 4132 ChangeBreakOnException(false, true); |
| 4004 | 4133 |
| 4005 // Create a function for checking the function when hitting a break point. | 4134 // Create a function for checking the function when hitting a break point. |
| 4006 frame_count = CompileFunction(&env, frame_count_source, "frame_count"); | 4135 frame_count = CompileFunction(&env, frame_count_source, "frame_count"); |
| 4007 | 4136 |
| 4008 v8::V8::AddMessageListener(MessageCallbackCount); | 4137 env->GetIsolate()->AddMessageListener(MessageCallbackCount); |
| 4009 v8::Debug::SetDebugEventListener(DebugEventCounter); | 4138 v8::Debug::SetDebugEventListener(DebugEventCounter); |
| 4010 | 4139 |
| 4011 DebugEventCounterClear(); | 4140 DebugEventCounterClear(); |
| 4012 MessageCallbackCountClear(); | 4141 MessageCallbackCountClear(); |
| 4013 | 4142 |
| 4014 // Check initial state. | 4143 // Check initial state. |
| 4015 CHECK_EQ(0, exception_hit_count); | 4144 CHECK_EQ(0, exception_hit_count); |
| 4016 CHECK_EQ(0, uncaught_exception_hit_count); | 4145 CHECK_EQ(0, uncaught_exception_hit_count); |
| 4017 CHECK_EQ(0, message_callback_count); | 4146 CHECK_EQ(0, message_callback_count); |
| 4018 CHECK_EQ(-1, last_js_stack_height); | 4147 CHECK_EQ(-1, last_js_stack_height); |
| 4019 | 4148 |
| 4020 // Throws SyntaxError: Unexpected end of input | 4149 // Throws SyntaxError: Unexpected end of input |
| 4021 v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), "+++")); | 4150 CHECK( |
| 4151 v8::Script::Compile(context, v8_str(env->GetIsolate(), "+++")).IsEmpty()); |
| 4022 CHECK_EQ(1, exception_hit_count); | 4152 CHECK_EQ(1, exception_hit_count); |
| 4023 CHECK_EQ(1, uncaught_exception_hit_count); | 4153 CHECK_EQ(1, uncaught_exception_hit_count); |
| 4024 CHECK_EQ(1, message_callback_count); | 4154 CHECK_EQ(1, message_callback_count); |
| 4025 CHECK_EQ(0, last_js_stack_height); // No JavaScript stack. | 4155 CHECK_EQ(0, last_js_stack_height); // No JavaScript stack. |
| 4026 | 4156 |
| 4027 // Throws SyntaxError: Unexpected identifier | 4157 // Throws SyntaxError: Unexpected identifier |
| 4028 v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), "x x")); | 4158 CHECK( |
| 4159 v8::Script::Compile(context, v8_str(env->GetIsolate(), "x x")).IsEmpty()); |
| 4029 CHECK_EQ(2, exception_hit_count); | 4160 CHECK_EQ(2, exception_hit_count); |
| 4030 CHECK_EQ(2, uncaught_exception_hit_count); | 4161 CHECK_EQ(2, uncaught_exception_hit_count); |
| 4031 CHECK_EQ(2, message_callback_count); | 4162 CHECK_EQ(2, message_callback_count); |
| 4032 CHECK_EQ(0, last_js_stack_height); // No JavaScript stack. | 4163 CHECK_EQ(0, last_js_stack_height); // No JavaScript stack. |
| 4033 | 4164 |
| 4034 // Throws SyntaxError: Unexpected end of input | 4165 // Throws SyntaxError: Unexpected end of input |
| 4035 v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), "eval('+++')")) | 4166 CHECK(v8::Script::Compile(context, v8_str(env->GetIsolate(), "eval('+++')")) |
| 4036 ->Run(); | 4167 .ToLocalChecked() |
| 4168 ->Run(context) |
| 4169 .IsEmpty()); |
| 4037 CHECK_EQ(3, exception_hit_count); | 4170 CHECK_EQ(3, exception_hit_count); |
| 4038 CHECK_EQ(3, uncaught_exception_hit_count); | 4171 CHECK_EQ(3, uncaught_exception_hit_count); |
| 4039 CHECK_EQ(3, message_callback_count); | 4172 CHECK_EQ(3, message_callback_count); |
| 4040 CHECK_EQ(1, last_js_stack_height); | 4173 CHECK_EQ(1, last_js_stack_height); |
| 4041 | 4174 |
| 4042 // Throws SyntaxError: Unexpected identifier | 4175 // Throws SyntaxError: Unexpected identifier |
| 4043 v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), "eval('x x')")) | 4176 CHECK(v8::Script::Compile(context, v8_str(env->GetIsolate(), "eval('x x')")) |
| 4044 ->Run(); | 4177 .ToLocalChecked() |
| 4178 ->Run(context) |
| 4179 .IsEmpty()); |
| 4045 CHECK_EQ(4, exception_hit_count); | 4180 CHECK_EQ(4, exception_hit_count); |
| 4046 CHECK_EQ(4, uncaught_exception_hit_count); | 4181 CHECK_EQ(4, uncaught_exception_hit_count); |
| 4047 CHECK_EQ(4, message_callback_count); | 4182 CHECK_EQ(4, message_callback_count); |
| 4048 CHECK_EQ(1, last_js_stack_height); | 4183 CHECK_EQ(1, last_js_stack_height); |
| 4049 } | 4184 } |
| 4050 | 4185 |
| 4051 | 4186 |
| 4052 TEST(StepWithException) { | 4187 TEST(StepWithException) { |
| 4053 DebugLocalContext env; | 4188 DebugLocalContext env; |
| 4054 v8::HandleScope scope(env->GetIsolate()); | 4189 v8::HandleScope scope(env->GetIsolate()); |
| 4055 | 4190 |
| 4056 // For this test, we want to break on uncaught exceptions: | 4191 // For this test, we want to break on uncaught exceptions: |
| 4057 ChangeBreakOnException(false, true); | 4192 ChangeBreakOnException(false, true); |
| 4058 | 4193 |
| 4059 // Create a function for checking the function when hitting a break point. | 4194 // Create a function for checking the function when hitting a break point. |
| 4060 frame_function_name = CompileFunction(&env, | 4195 frame_function_name = CompileFunction(&env, |
| 4061 frame_function_name_source, | 4196 frame_function_name_source, |
| 4062 "frame_function_name"); | 4197 "frame_function_name"); |
| 4063 | 4198 |
| 4064 // Register a debug event listener which steps and counts. | 4199 // Register a debug event listener which steps and counts. |
| 4065 v8::Debug::SetDebugEventListener(DebugEventStepSequence); | 4200 v8::Debug::SetDebugEventListener(DebugEventStepSequence); |
| 4066 | 4201 |
| 4202 v8::Local<v8::Context> context = env.context(); |
| 4067 // Create functions for testing stepping. | 4203 // Create functions for testing stepping. |
| 4068 const char* src = "function a() { n(); }; " | 4204 const char* src = "function a() { n(); }; " |
| 4069 "function b() { c(); }; " | 4205 "function b() { c(); }; " |
| 4070 "function c() { n(); }; " | 4206 "function c() { n(); }; " |
| 4071 "function d() { x = 1; try { e(); } catch(x) { x = 2; } }; " | 4207 "function d() { x = 1; try { e(); } catch(x) { x = 2; } }; " |
| 4072 "function e() { n(); }; " | 4208 "function e() { n(); }; " |
| 4073 "function f() { x = 1; try { g(); } catch(x) { x = 2; } }; " | 4209 "function f() { x = 1; try { g(); } catch(x) { x = 2; } }; " |
| 4074 "function g() { h(); }; " | 4210 "function g() { h(); }; " |
| 4075 "function h() { x = 1; throw 1; }; "; | 4211 "function h() { x = 1; throw 1; }; "; |
| 4076 | 4212 |
| 4077 // Step through invocation of a. | 4213 // Step through invocation of a. |
| 4078 v8::Local<v8::Function> a = CompileFunction(&env, src, "a"); | 4214 v8::Local<v8::Function> a = CompileFunction(&env, src, "a"); |
| 4079 SetBreakPoint(a, 0); | 4215 SetBreakPoint(a, 0); |
| 4080 step_action = StepIn; | 4216 step_action = StepIn; |
| 4081 break_point_hit_count = 0; | 4217 break_point_hit_count = 0; |
| 4082 expected_step_sequence = "aa"; | 4218 expected_step_sequence = "aa"; |
| 4083 a->Call(env->Global(), 0, NULL); | 4219 CHECK(a->Call(context, env->Global(), 0, NULL).IsEmpty()); |
| 4084 CHECK_EQ(StrLength(expected_step_sequence), | 4220 CHECK_EQ(StrLength(expected_step_sequence), |
| 4085 break_point_hit_count); | 4221 break_point_hit_count); |
| 4086 | 4222 |
| 4087 // Step through invocation of b + c. | 4223 // Step through invocation of b + c. |
| 4088 v8::Local<v8::Function> b = CompileFunction(&env, src, "b"); | 4224 v8::Local<v8::Function> b = CompileFunction(&env, src, "b"); |
| 4089 SetBreakPoint(b, 0); | 4225 SetBreakPoint(b, 0); |
| 4090 step_action = StepIn; | 4226 step_action = StepIn; |
| 4091 break_point_hit_count = 0; | 4227 break_point_hit_count = 0; |
| 4092 expected_step_sequence = "bcc"; | 4228 expected_step_sequence = "bcc"; |
| 4093 b->Call(env->Global(), 0, NULL); | 4229 CHECK(b->Call(context, env->Global(), 0, NULL).IsEmpty()); |
| 4094 CHECK_EQ(StrLength(expected_step_sequence), | 4230 CHECK_EQ(StrLength(expected_step_sequence), |
| 4095 break_point_hit_count); | 4231 break_point_hit_count); |
| 4096 // Step through invocation of d + e. | 4232 // Step through invocation of d + e. |
| 4097 v8::Local<v8::Function> d = CompileFunction(&env, src, "d"); | 4233 v8::Local<v8::Function> d = CompileFunction(&env, src, "d"); |
| 4098 SetBreakPoint(d, 0); | 4234 SetBreakPoint(d, 0); |
| 4099 ChangeBreakOnException(false, true); | 4235 ChangeBreakOnException(false, true); |
| 4100 step_action = StepIn; | 4236 step_action = StepIn; |
| 4101 break_point_hit_count = 0; | 4237 break_point_hit_count = 0; |
| 4102 expected_step_sequence = "ddedd"; | 4238 expected_step_sequence = "ddedd"; |
| 4103 d->Call(env->Global(), 0, NULL); | 4239 d->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 4104 CHECK_EQ(StrLength(expected_step_sequence), | 4240 CHECK_EQ(StrLength(expected_step_sequence), |
| 4105 break_point_hit_count); | 4241 break_point_hit_count); |
| 4106 | 4242 |
| 4107 // Step through invocation of d + e now with break on caught exceptions. | 4243 // Step through invocation of d + e now with break on caught exceptions. |
| 4108 ChangeBreakOnException(true, true); | 4244 ChangeBreakOnException(true, true); |
| 4109 step_action = StepIn; | 4245 step_action = StepIn; |
| 4110 break_point_hit_count = 0; | 4246 break_point_hit_count = 0; |
| 4111 expected_step_sequence = "ddeedd"; | 4247 expected_step_sequence = "ddeedd"; |
| 4112 d->Call(env->Global(), 0, NULL); | 4248 d->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 4113 CHECK_EQ(StrLength(expected_step_sequence), | 4249 CHECK_EQ(StrLength(expected_step_sequence), |
| 4114 break_point_hit_count); | 4250 break_point_hit_count); |
| 4115 | 4251 |
| 4116 // Step through invocation of f + g + h. | 4252 // Step through invocation of f + g + h. |
| 4117 v8::Local<v8::Function> f = CompileFunction(&env, src, "f"); | 4253 v8::Local<v8::Function> f = CompileFunction(&env, src, "f"); |
| 4118 SetBreakPoint(f, 0); | 4254 SetBreakPoint(f, 0); |
| 4119 ChangeBreakOnException(false, true); | 4255 ChangeBreakOnException(false, true); |
| 4120 step_action = StepIn; | 4256 step_action = StepIn; |
| 4121 break_point_hit_count = 0; | 4257 break_point_hit_count = 0; |
| 4122 expected_step_sequence = "ffghhff"; | 4258 expected_step_sequence = "ffghhff"; |
| 4123 f->Call(env->Global(), 0, NULL); | 4259 f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 4124 CHECK_EQ(StrLength(expected_step_sequence), | 4260 CHECK_EQ(StrLength(expected_step_sequence), |
| 4125 break_point_hit_count); | 4261 break_point_hit_count); |
| 4126 | 4262 |
| 4127 // Step through invocation of f + g + h now with break on caught exceptions. | 4263 // Step through invocation of f + g + h now with break on caught exceptions. |
| 4128 ChangeBreakOnException(true, true); | 4264 ChangeBreakOnException(true, true); |
| 4129 step_action = StepIn; | 4265 step_action = StepIn; |
| 4130 break_point_hit_count = 0; | 4266 break_point_hit_count = 0; |
| 4131 expected_step_sequence = "ffghhhff"; | 4267 expected_step_sequence = "ffghhhff"; |
| 4132 f->Call(env->Global(), 0, NULL); | 4268 f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 4133 CHECK_EQ(StrLength(expected_step_sequence), | 4269 CHECK_EQ(StrLength(expected_step_sequence), |
| 4134 break_point_hit_count); | 4270 break_point_hit_count); |
| 4135 | 4271 |
| 4136 // Get rid of the debug event listener. | 4272 // Get rid of the debug event listener. |
| 4137 v8::Debug::SetDebugEventListener(NULL); | 4273 v8::Debug::SetDebugEventListener(NULL); |
| 4138 CheckDebuggerUnloaded(); | 4274 CheckDebuggerUnloaded(); |
| 4139 } | 4275 } |
| 4140 | 4276 |
| 4141 | 4277 |
| 4142 TEST(DebugBreak) { | 4278 TEST(DebugBreak) { |
| 4143 i::FLAG_stress_compaction = false; | 4279 i::FLAG_stress_compaction = false; |
| 4144 #ifdef VERIFY_HEAP | 4280 #ifdef VERIFY_HEAP |
| 4145 i::FLAG_verify_heap = true; | 4281 i::FLAG_verify_heap = true; |
| 4146 #endif | 4282 #endif |
| 4147 DebugLocalContext env; | 4283 DebugLocalContext env; |
| 4148 v8::Isolate* isolate = env->GetIsolate(); | 4284 v8::Isolate* isolate = env->GetIsolate(); |
| 4149 v8::HandleScope scope(isolate); | 4285 v8::HandleScope scope(isolate); |
| 4150 | 4286 |
| 4151 // Register a debug event listener which sets the break flag and counts. | 4287 // Register a debug event listener which sets the break flag and counts. |
| 4152 v8::Debug::SetDebugEventListener(DebugEventBreak); | 4288 v8::Debug::SetDebugEventListener(DebugEventBreak); |
| 4153 | 4289 |
| 4290 v8::Local<v8::Context> context = env.context(); |
| 4154 // Create a function for testing stepping. | 4291 // Create a function for testing stepping. |
| 4155 const char* src = "function f0() {}" | 4292 const char* src = "function f0() {}" |
| 4156 "function f1(x1) {}" | 4293 "function f1(x1) {}" |
| 4157 "function f2(x1,x2) {}" | 4294 "function f2(x1,x2) {}" |
| 4158 "function f3(x1,x2,x3) {}"; | 4295 "function f3(x1,x2,x3) {}"; |
| 4159 v8::Local<v8::Function> f0 = CompileFunction(&env, src, "f0"); | 4296 v8::Local<v8::Function> f0 = CompileFunction(&env, src, "f0"); |
| 4160 v8::Local<v8::Function> f1 = CompileFunction(&env, src, "f1"); | 4297 v8::Local<v8::Function> f1 = CompileFunction(&env, src, "f1"); |
| 4161 v8::Local<v8::Function> f2 = CompileFunction(&env, src, "f2"); | 4298 v8::Local<v8::Function> f2 = CompileFunction(&env, src, "f2"); |
| 4162 v8::Local<v8::Function> f3 = CompileFunction(&env, src, "f3"); | 4299 v8::Local<v8::Function> f3 = CompileFunction(&env, src, "f3"); |
| 4163 | 4300 |
| 4164 // Call the function to make sure it is compiled. | 4301 // Call the function to make sure it is compiled. |
| 4165 v8::Handle<v8::Value> argv[] = { v8::Number::New(isolate, 1), | 4302 v8::Local<v8::Value> argv[] = { |
| 4166 v8::Number::New(isolate, 1), | 4303 v8::Number::New(isolate, 1), v8::Number::New(isolate, 1), |
| 4167 v8::Number::New(isolate, 1), | 4304 v8::Number::New(isolate, 1), v8::Number::New(isolate, 1)}; |
| 4168 v8::Number::New(isolate, 1) }; | |
| 4169 | 4305 |
| 4170 // Call all functions to make sure that they are compiled. | 4306 // Call all functions to make sure that they are compiled. |
| 4171 f0->Call(env->Global(), 0, NULL); | 4307 f0->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 4172 f1->Call(env->Global(), 0, NULL); | 4308 f1->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 4173 f2->Call(env->Global(), 0, NULL); | 4309 f2->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 4174 f3->Call(env->Global(), 0, NULL); | 4310 f3->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 4175 | 4311 |
| 4176 // Set the debug break flag. | 4312 // Set the debug break flag. |
| 4177 v8::Debug::DebugBreak(env->GetIsolate()); | 4313 v8::Debug::DebugBreak(env->GetIsolate()); |
| 4178 CHECK(v8::Debug::CheckDebugBreak(env->GetIsolate())); | 4314 CHECK(v8::Debug::CheckDebugBreak(env->GetIsolate())); |
| 4179 | 4315 |
| 4180 // Call all functions with different argument count. | 4316 // Call all functions with different argument count. |
| 4181 break_point_hit_count = 0; | 4317 break_point_hit_count = 0; |
| 4182 for (unsigned int i = 0; i < arraysize(argv); i++) { | 4318 for (unsigned int i = 0; i < arraysize(argv); i++) { |
| 4183 f0->Call(env->Global(), i, argv); | 4319 f0->Call(context, env->Global(), i, argv).ToLocalChecked(); |
| 4184 f1->Call(env->Global(), i, argv); | 4320 f1->Call(context, env->Global(), i, argv).ToLocalChecked(); |
| 4185 f2->Call(env->Global(), i, argv); | 4321 f2->Call(context, env->Global(), i, argv).ToLocalChecked(); |
| 4186 f3->Call(env->Global(), i, argv); | 4322 f3->Call(context, env->Global(), i, argv).ToLocalChecked(); |
| 4187 } | 4323 } |
| 4188 | 4324 |
| 4189 // One break for each function called. | 4325 // One break for each function called. |
| 4190 CHECK(4 * arraysize(argv) == break_point_hit_count); | 4326 CHECK(4 * arraysize(argv) == break_point_hit_count); |
| 4191 | 4327 |
| 4192 // Get rid of the debug event listener. | 4328 // Get rid of the debug event listener. |
| 4193 v8::Debug::SetDebugEventListener(NULL); | 4329 v8::Debug::SetDebugEventListener(NULL); |
| 4194 CheckDebuggerUnloaded(); | 4330 CheckDebuggerUnloaded(); |
| 4195 } | 4331 } |
| 4196 | 4332 |
| 4197 | 4333 |
| 4198 // Test to ensure that JavaScript code keeps running while the debug break | 4334 // Test to ensure that JavaScript code keeps running while the debug break |
| 4199 // through the stack limit flag is set but breaks are disabled. | 4335 // through the stack limit flag is set but breaks are disabled. |
| 4200 TEST(DisableBreak) { | 4336 TEST(DisableBreak) { |
| 4201 DebugLocalContext env; | 4337 DebugLocalContext env; |
| 4202 v8::HandleScope scope(env->GetIsolate()); | 4338 v8::HandleScope scope(env->GetIsolate()); |
| 4203 | 4339 |
| 4204 // Register a debug event listener which sets the break flag and counts. | 4340 // Register a debug event listener which sets the break flag and counts. |
| 4205 v8::Debug::SetDebugEventListener(DebugEventCounter); | 4341 v8::Debug::SetDebugEventListener(DebugEventCounter); |
| 4206 | 4342 |
| 4343 v8::Local<v8::Context> context = env.context(); |
| 4207 // Create a function for testing stepping. | 4344 // Create a function for testing stepping. |
| 4208 const char* src = "function f() {g()};function g(){i=0; while(i<10){i++}}"; | 4345 const char* src = "function f() {g()};function g(){i=0; while(i<10){i++}}"; |
| 4209 v8::Local<v8::Function> f = CompileFunction(&env, src, "f"); | 4346 v8::Local<v8::Function> f = CompileFunction(&env, src, "f"); |
| 4210 | 4347 |
| 4211 // Set, test and cancel debug break. | 4348 // Set, test and cancel debug break. |
| 4212 v8::Debug::DebugBreak(env->GetIsolate()); | 4349 v8::Debug::DebugBreak(env->GetIsolate()); |
| 4213 CHECK(v8::Debug::CheckDebugBreak(env->GetIsolate())); | 4350 CHECK(v8::Debug::CheckDebugBreak(env->GetIsolate())); |
| 4214 v8::Debug::CancelDebugBreak(env->GetIsolate()); | 4351 v8::Debug::CancelDebugBreak(env->GetIsolate()); |
| 4215 CHECK(!v8::Debug::CheckDebugBreak(env->GetIsolate())); | 4352 CHECK(!v8::Debug::CheckDebugBreak(env->GetIsolate())); |
| 4216 | 4353 |
| 4217 // Set the debug break flag. | 4354 // Set the debug break flag. |
| 4218 v8::Debug::DebugBreak(env->GetIsolate()); | 4355 v8::Debug::DebugBreak(env->GetIsolate()); |
| 4219 | 4356 |
| 4220 // Call all functions with different argument count. | 4357 // Call all functions with different argument count. |
| 4221 break_point_hit_count = 0; | 4358 break_point_hit_count = 0; |
| 4222 f->Call(env->Global(), 0, NULL); | 4359 f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 4223 CHECK_EQ(1, break_point_hit_count); | 4360 CHECK_EQ(1, break_point_hit_count); |
| 4224 | 4361 |
| 4225 { | 4362 { |
| 4226 v8::Debug::DebugBreak(env->GetIsolate()); | 4363 v8::Debug::DebugBreak(env->GetIsolate()); |
| 4227 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(env->GetIsolate()); | 4364 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(env->GetIsolate()); |
| 4228 v8::internal::DisableBreak disable_break(isolate->debug(), true); | 4365 v8::internal::DisableBreak disable_break(isolate->debug(), true); |
| 4229 f->Call(env->Global(), 0, NULL); | 4366 f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 4230 CHECK_EQ(1, break_point_hit_count); | 4367 CHECK_EQ(1, break_point_hit_count); |
| 4231 } | 4368 } |
| 4232 | 4369 |
| 4233 f->Call(env->Global(), 0, NULL); | 4370 f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 4234 CHECK_EQ(2, break_point_hit_count); | 4371 CHECK_EQ(2, break_point_hit_count); |
| 4235 | 4372 |
| 4236 // Get rid of the debug event listener. | 4373 // Get rid of the debug event listener. |
| 4237 v8::Debug::SetDebugEventListener(NULL); | 4374 v8::Debug::SetDebugEventListener(NULL); |
| 4238 CheckDebuggerUnloaded(); | 4375 CheckDebuggerUnloaded(); |
| 4239 } | 4376 } |
| 4240 | 4377 |
| 4241 static const char* kSimpleExtensionSource = | 4378 static const char* kSimpleExtensionSource = |
| 4242 "(function Foo() {" | 4379 "(function Foo() {" |
| 4243 " return 4;" | 4380 " return 4;" |
| (...skipping 24 matching lines...) Expand all Loading... |
| 4268 // Check that no DebugBreak events occured during the context creation. | 4405 // Check that no DebugBreak events occured during the context creation. |
| 4269 CHECK_EQ(0, break_point_hit_count); | 4406 CHECK_EQ(0, break_point_hit_count); |
| 4270 | 4407 |
| 4271 // Get rid of the debug event listener. | 4408 // Get rid of the debug event listener. |
| 4272 v8::Debug::SetDebugEventListener(NULL); | 4409 v8::Debug::SetDebugEventListener(NULL); |
| 4273 CheckDebuggerUnloaded(); | 4410 CheckDebuggerUnloaded(); |
| 4274 } | 4411 } |
| 4275 | 4412 |
| 4276 | 4413 |
| 4277 static void NamedEnum(const v8::PropertyCallbackInfo<v8::Array>& info) { | 4414 static void NamedEnum(const v8::PropertyCallbackInfo<v8::Array>& info) { |
| 4278 v8::Handle<v8::Array> result = v8::Array::New(info.GetIsolate(), 3); | 4415 v8::Local<v8::Array> result = v8::Array::New(info.GetIsolate(), 3); |
| 4279 result->Set(v8::Integer::New(info.GetIsolate(), 0), | 4416 v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext(); |
| 4280 v8::String::NewFromUtf8(info.GetIsolate(), "a")); | 4417 CHECK(result->Set(context, v8::Integer::New(info.GetIsolate(), 0), |
| 4281 result->Set(v8::Integer::New(info.GetIsolate(), 1), | 4418 v8_str(info.GetIsolate(), "a")) |
| 4282 v8::String::NewFromUtf8(info.GetIsolate(), "b")); | 4419 .FromJust()); |
| 4283 result->Set(v8::Integer::New(info.GetIsolate(), 2), | 4420 CHECK(result->Set(context, v8::Integer::New(info.GetIsolate(), 1), |
| 4284 v8::String::NewFromUtf8(info.GetIsolate(), "c")); | 4421 v8_str(info.GetIsolate(), "b")) |
| 4422 .FromJust()); |
| 4423 CHECK(result->Set(context, v8::Integer::New(info.GetIsolate(), 2), |
| 4424 v8_str(info.GetIsolate(), "c")) |
| 4425 .FromJust()); |
| 4285 info.GetReturnValue().Set(result); | 4426 info.GetReturnValue().Set(result); |
| 4286 } | 4427 } |
| 4287 | 4428 |
| 4288 | 4429 |
| 4289 static void IndexedEnum(const v8::PropertyCallbackInfo<v8::Array>& info) { | 4430 static void IndexedEnum(const v8::PropertyCallbackInfo<v8::Array>& info) { |
| 4290 v8::Isolate* isolate = info.GetIsolate(); | 4431 v8::Isolate* isolate = info.GetIsolate(); |
| 4291 v8::Handle<v8::Array> result = v8::Array::New(isolate, 2); | 4432 v8::Local<v8::Array> result = v8::Array::New(isolate, 2); |
| 4292 result->Set(v8::Integer::New(isolate, 0), v8::Number::New(isolate, 1)); | 4433 v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext(); |
| 4293 result->Set(v8::Integer::New(isolate, 1), v8::Number::New(isolate, 10)); | 4434 CHECK(result->Set(context, v8::Integer::New(isolate, 0), |
| 4435 v8::Number::New(isolate, 1)) |
| 4436 .FromJust()); |
| 4437 CHECK(result->Set(context, v8::Integer::New(isolate, 1), |
| 4438 v8::Number::New(isolate, 10)) |
| 4439 .FromJust()); |
| 4294 info.GetReturnValue().Set(result); | 4440 info.GetReturnValue().Set(result); |
| 4295 } | 4441 } |
| 4296 | 4442 |
| 4297 | 4443 |
| 4298 static void NamedGetter(v8::Local<v8::Name> name, | 4444 static void NamedGetter(v8::Local<v8::Name> name, |
| 4299 const v8::PropertyCallbackInfo<v8::Value>& info) { | 4445 const v8::PropertyCallbackInfo<v8::Value>& info) { |
| 4300 if (name->IsSymbol()) return; | 4446 if (name->IsSymbol()) return; |
| 4301 v8::String::Utf8Value n(v8::Local<v8::String>::Cast(name)); | 4447 v8::String::Utf8Value n(v8::Local<v8::String>::Cast(name)); |
| 4302 if (strcmp(*n, "a") == 0) { | 4448 if (strcmp(*n, "a") == 0) { |
| 4303 info.GetReturnValue().Set(v8::String::NewFromUtf8(info.GetIsolate(), "AA")); | 4449 info.GetReturnValue().Set(v8_str(info.GetIsolate(), "AA")); |
| 4304 return; | 4450 return; |
| 4305 } else if (strcmp(*n, "b") == 0) { | 4451 } else if (strcmp(*n, "b") == 0) { |
| 4306 info.GetReturnValue().Set(v8::String::NewFromUtf8(info.GetIsolate(), "BB")); | 4452 info.GetReturnValue().Set(v8_str(info.GetIsolate(), "BB")); |
| 4307 return; | 4453 return; |
| 4308 } else if (strcmp(*n, "c") == 0) { | 4454 } else if (strcmp(*n, "c") == 0) { |
| 4309 info.GetReturnValue().Set(v8::String::NewFromUtf8(info.GetIsolate(), "CC")); | 4455 info.GetReturnValue().Set(v8_str(info.GetIsolate(), "CC")); |
| 4310 return; | 4456 return; |
| 4311 } else { | 4457 } else { |
| 4312 info.GetReturnValue().SetUndefined(); | 4458 info.GetReturnValue().SetUndefined(); |
| 4313 return; | 4459 return; |
| 4314 } | 4460 } |
| 4315 info.GetReturnValue().Set(name); | 4461 info.GetReturnValue().Set(name); |
| 4316 } | 4462 } |
| 4317 | 4463 |
| 4318 | 4464 |
| 4319 static void IndexedGetter(uint32_t index, | 4465 static void IndexedGetter(uint32_t index, |
| 4320 const v8::PropertyCallbackInfo<v8::Value>& info) { | 4466 const v8::PropertyCallbackInfo<v8::Value>& info) { |
| 4321 info.GetReturnValue().Set(static_cast<double>(index + 1)); | 4467 info.GetReturnValue().Set(static_cast<double>(index + 1)); |
| 4322 } | 4468 } |
| 4323 | 4469 |
| 4324 | 4470 |
| 4325 TEST(InterceptorPropertyMirror) { | 4471 TEST(InterceptorPropertyMirror) { |
| 4326 // Create a V8 environment with debug access. | 4472 // Create a V8 environment with debug access. |
| 4327 DebugLocalContext env; | 4473 DebugLocalContext env; |
| 4328 v8::Isolate* isolate = env->GetIsolate(); | 4474 v8::Isolate* isolate = env->GetIsolate(); |
| 4329 v8::HandleScope scope(isolate); | 4475 v8::HandleScope scope(isolate); |
| 4330 env.ExposeDebug(); | 4476 env.ExposeDebug(); |
| 4331 | 4477 |
| 4478 v8::Local<v8::Context> context = env.context(); |
| 4332 // Create object with named interceptor. | 4479 // Create object with named interceptor. |
| 4333 v8::Handle<v8::ObjectTemplate> named = v8::ObjectTemplate::New(isolate); | 4480 v8::Local<v8::ObjectTemplate> named = v8::ObjectTemplate::New(isolate); |
| 4334 named->SetHandler(v8::NamedPropertyHandlerConfiguration( | 4481 named->SetHandler(v8::NamedPropertyHandlerConfiguration( |
| 4335 NamedGetter, NULL, NULL, NULL, NamedEnum)); | 4482 NamedGetter, NULL, NULL, NULL, NamedEnum)); |
| 4336 env->Global()->Set( | 4483 CHECK(env->Global() |
| 4337 v8::String::NewFromUtf8(isolate, "intercepted_named"), | 4484 ->Set(context, v8_str(isolate, "intercepted_named"), |
| 4338 named->NewInstance()); | 4485 named->NewInstance(context).ToLocalChecked()) |
| 4486 .FromJust()); |
| 4339 | 4487 |
| 4340 // Create object with indexed interceptor. | 4488 // Create object with indexed interceptor. |
| 4341 v8::Handle<v8::ObjectTemplate> indexed = v8::ObjectTemplate::New(isolate); | 4489 v8::Local<v8::ObjectTemplate> indexed = v8::ObjectTemplate::New(isolate); |
| 4342 indexed->SetHandler(v8::IndexedPropertyHandlerConfiguration( | 4490 indexed->SetHandler(v8::IndexedPropertyHandlerConfiguration( |
| 4343 IndexedGetter, NULL, NULL, NULL, IndexedEnum)); | 4491 IndexedGetter, NULL, NULL, NULL, IndexedEnum)); |
| 4344 env->Global()->Set( | 4492 CHECK(env->Global() |
| 4345 v8::String::NewFromUtf8(isolate, "intercepted_indexed"), | 4493 ->Set(context, v8_str(isolate, "intercepted_indexed"), |
| 4346 indexed->NewInstance()); | 4494 indexed->NewInstance(context).ToLocalChecked()) |
| 4495 .FromJust()); |
| 4347 | 4496 |
| 4348 // Create object with both named and indexed interceptor. | 4497 // Create object with both named and indexed interceptor. |
| 4349 v8::Handle<v8::ObjectTemplate> both = v8::ObjectTemplate::New(isolate); | 4498 v8::Local<v8::ObjectTemplate> both = v8::ObjectTemplate::New(isolate); |
| 4350 both->SetHandler(v8::NamedPropertyHandlerConfiguration( | 4499 both->SetHandler(v8::NamedPropertyHandlerConfiguration( |
| 4351 NamedGetter, NULL, NULL, NULL, NamedEnum)); | 4500 NamedGetter, NULL, NULL, NULL, NamedEnum)); |
| 4352 both->SetHandler(v8::IndexedPropertyHandlerConfiguration( | 4501 both->SetHandler(v8::IndexedPropertyHandlerConfiguration( |
| 4353 IndexedGetter, NULL, NULL, NULL, IndexedEnum)); | 4502 IndexedGetter, NULL, NULL, NULL, IndexedEnum)); |
| 4354 env->Global()->Set( | 4503 CHECK(env->Global() |
| 4355 v8::String::NewFromUtf8(isolate, "intercepted_both"), | 4504 ->Set(context, v8_str(isolate, "intercepted_both"), |
| 4356 both->NewInstance()); | 4505 both->NewInstance(context).ToLocalChecked()) |
| 4506 .FromJust()); |
| 4357 | 4507 |
| 4358 // Get mirrors for the three objects with interceptor. | 4508 // Get mirrors for the three objects with interceptor. |
| 4359 CompileRun( | 4509 CompileRun( |
| 4360 "var named_mirror = debug.MakeMirror(intercepted_named);" | 4510 "var named_mirror = debug.MakeMirror(intercepted_named);" |
| 4361 "var indexed_mirror = debug.MakeMirror(intercepted_indexed);" | 4511 "var indexed_mirror = debug.MakeMirror(intercepted_indexed);" |
| 4362 "var both_mirror = debug.MakeMirror(intercepted_both)"); | 4512 "var both_mirror = debug.MakeMirror(intercepted_both)"); |
| 4363 CHECK(CompileRun( | 4513 CHECK(CompileRun("named_mirror instanceof debug.ObjectMirror") |
| 4364 "named_mirror instanceof debug.ObjectMirror")->BooleanValue()); | 4514 ->BooleanValue(context) |
| 4365 CHECK(CompileRun( | 4515 .FromJust()); |
| 4366 "indexed_mirror instanceof debug.ObjectMirror")->BooleanValue()); | 4516 CHECK(CompileRun("indexed_mirror instanceof debug.ObjectMirror") |
| 4367 CHECK(CompileRun( | 4517 ->BooleanValue(context) |
| 4368 "both_mirror instanceof debug.ObjectMirror")->BooleanValue()); | 4518 .FromJust()); |
| 4519 CHECK(CompileRun("both_mirror instanceof debug.ObjectMirror") |
| 4520 ->BooleanValue(context) |
| 4521 .FromJust()); |
| 4369 | 4522 |
| 4370 // Get the property names from the interceptors | 4523 // Get the property names from the interceptors |
| 4371 CompileRun( | 4524 CompileRun( |
| 4372 "named_names = named_mirror.propertyNames();" | 4525 "named_names = named_mirror.propertyNames();" |
| 4373 "indexed_names = indexed_mirror.propertyNames();" | 4526 "indexed_names = indexed_mirror.propertyNames();" |
| 4374 "both_names = both_mirror.propertyNames()"); | 4527 "both_names = both_mirror.propertyNames()"); |
| 4375 CHECK_EQ(3, CompileRun("named_names.length")->Int32Value()); | 4528 CHECK_EQ(3, CompileRun("named_names.length")->Int32Value(context).FromJust()); |
| 4376 CHECK_EQ(2, CompileRun("indexed_names.length")->Int32Value()); | 4529 CHECK_EQ(2, |
| 4377 CHECK_EQ(5, CompileRun("both_names.length")->Int32Value()); | 4530 CompileRun("indexed_names.length")->Int32Value(context).FromJust()); |
| 4531 CHECK_EQ(5, CompileRun("both_names.length")->Int32Value(context).FromJust()); |
| 4378 | 4532 |
| 4379 // Check the expected number of properties. | 4533 // Check the expected number of properties. |
| 4380 const char* source; | 4534 const char* source; |
| 4381 source = "named_mirror.properties().length"; | 4535 source = "named_mirror.properties().length"; |
| 4382 CHECK_EQ(3, CompileRun(source)->Int32Value()); | 4536 CHECK_EQ(3, CompileRun(source)->Int32Value(context).FromJust()); |
| 4383 | 4537 |
| 4384 source = "indexed_mirror.properties().length"; | 4538 source = "indexed_mirror.properties().length"; |
| 4385 CHECK_EQ(2, CompileRun(source)->Int32Value()); | 4539 CHECK_EQ(2, CompileRun(source)->Int32Value(context).FromJust()); |
| 4386 | 4540 |
| 4387 source = "both_mirror.properties().length"; | 4541 source = "both_mirror.properties().length"; |
| 4388 CHECK_EQ(5, CompileRun(source)->Int32Value()); | 4542 CHECK_EQ(5, CompileRun(source)->Int32Value(context).FromJust()); |
| 4389 | 4543 |
| 4390 // 1 is PropertyKind.Named; | 4544 // 1 is PropertyKind.Named; |
| 4391 source = "both_mirror.properties(1).length"; | 4545 source = "both_mirror.properties(1).length"; |
| 4392 CHECK_EQ(3, CompileRun(source)->Int32Value()); | 4546 CHECK_EQ(3, CompileRun(source)->Int32Value(context).FromJust()); |
| 4393 | 4547 |
| 4394 // 2 is PropertyKind.Indexed; | 4548 // 2 is PropertyKind.Indexed; |
| 4395 source = "both_mirror.properties(2).length"; | 4549 source = "both_mirror.properties(2).length"; |
| 4396 CHECK_EQ(2, CompileRun(source)->Int32Value()); | 4550 CHECK_EQ(2, CompileRun(source)->Int32Value(context).FromJust()); |
| 4397 | 4551 |
| 4398 // 3 is PropertyKind.Named | PropertyKind.Indexed; | 4552 // 3 is PropertyKind.Named | PropertyKind.Indexed; |
| 4399 source = "both_mirror.properties(3).length"; | 4553 source = "both_mirror.properties(3).length"; |
| 4400 CHECK_EQ(5, CompileRun(source)->Int32Value()); | 4554 CHECK_EQ(5, CompileRun(source)->Int32Value(context).FromJust()); |
| 4401 | 4555 |
| 4402 // Get the interceptor properties for the object with only named interceptor. | 4556 // Get the interceptor properties for the object with only named interceptor. |
| 4403 CompileRun("var named_values = named_mirror.properties()"); | 4557 CompileRun("var named_values = named_mirror.properties()"); |
| 4404 | 4558 |
| 4405 // Check that the properties are interceptor properties. | 4559 // Check that the properties are interceptor properties. |
| 4406 for (int i = 0; i < 3; i++) { | 4560 for (int i = 0; i < 3; i++) { |
| 4407 EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; | 4561 EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; |
| 4408 SNPrintF(buffer, | 4562 SNPrintF(buffer, |
| 4409 "named_values[%d] instanceof debug.PropertyMirror", i); | 4563 "named_values[%d] instanceof debug.PropertyMirror", i); |
| 4410 CHECK(CompileRun(buffer.start())->BooleanValue()); | 4564 CHECK(CompileRun(buffer.start())->BooleanValue(context).FromJust()); |
| 4411 | 4565 |
| 4412 SNPrintF(buffer, "named_values[%d].isNative()", i); | 4566 SNPrintF(buffer, "named_values[%d].isNative()", i); |
| 4413 CHECK(CompileRun(buffer.start())->BooleanValue()); | 4567 CHECK(CompileRun(buffer.start())->BooleanValue(context).FromJust()); |
| 4414 } | 4568 } |
| 4415 | 4569 |
| 4416 // Get the interceptor properties for the object with only indexed | 4570 // Get the interceptor properties for the object with only indexed |
| 4417 // interceptor. | 4571 // interceptor. |
| 4418 CompileRun("var indexed_values = indexed_mirror.properties()"); | 4572 CompileRun("var indexed_values = indexed_mirror.properties()"); |
| 4419 | 4573 |
| 4420 // Check that the properties are interceptor properties. | 4574 // Check that the properties are interceptor properties. |
| 4421 for (int i = 0; i < 2; i++) { | 4575 for (int i = 0; i < 2; i++) { |
| 4422 EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; | 4576 EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; |
| 4423 SNPrintF(buffer, | 4577 SNPrintF(buffer, |
| 4424 "indexed_values[%d] instanceof debug.PropertyMirror", i); | 4578 "indexed_values[%d] instanceof debug.PropertyMirror", i); |
| 4425 CHECK(CompileRun(buffer.start())->BooleanValue()); | 4579 CHECK(CompileRun(buffer.start())->BooleanValue(context).FromJust()); |
| 4426 } | 4580 } |
| 4427 | 4581 |
| 4428 // Get the interceptor properties for the object with both types of | 4582 // Get the interceptor properties for the object with both types of |
| 4429 // interceptors. | 4583 // interceptors. |
| 4430 CompileRun("var both_values = both_mirror.properties()"); | 4584 CompileRun("var both_values = both_mirror.properties()"); |
| 4431 | 4585 |
| 4432 // Check that the properties are interceptor properties. | 4586 // Check that the properties are interceptor properties. |
| 4433 for (int i = 0; i < 5; i++) { | 4587 for (int i = 0; i < 5; i++) { |
| 4434 EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; | 4588 EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; |
| 4435 SNPrintF(buffer, "both_values[%d] instanceof debug.PropertyMirror", i); | 4589 SNPrintF(buffer, "both_values[%d] instanceof debug.PropertyMirror", i); |
| 4436 CHECK(CompileRun(buffer.start())->BooleanValue()); | 4590 CHECK(CompileRun(buffer.start())->BooleanValue(context).FromJust()); |
| 4437 } | 4591 } |
| 4438 | 4592 |
| 4439 // Check the property names. | 4593 // Check the property names. |
| 4440 source = "both_values[0].name() == 'a'"; | 4594 source = "both_values[0].name() == 'a'"; |
| 4441 CHECK(CompileRun(source)->BooleanValue()); | 4595 CHECK(CompileRun(source)->BooleanValue(context).FromJust()); |
| 4442 | 4596 |
| 4443 source = "both_values[1].name() == 'b'"; | 4597 source = "both_values[1].name() == 'b'"; |
| 4444 CHECK(CompileRun(source)->BooleanValue()); | 4598 CHECK(CompileRun(source)->BooleanValue(context).FromJust()); |
| 4445 | 4599 |
| 4446 source = "both_values[2].name() == 'c'"; | 4600 source = "both_values[2].name() == 'c'"; |
| 4447 CHECK(CompileRun(source)->BooleanValue()); | 4601 CHECK(CompileRun(source)->BooleanValue(context).FromJust()); |
| 4448 | 4602 |
| 4449 source = "both_values[3].name() == 1"; | 4603 source = "both_values[3].name() == 1"; |
| 4450 CHECK(CompileRun(source)->BooleanValue()); | 4604 CHECK(CompileRun(source)->BooleanValue(context).FromJust()); |
| 4451 | 4605 |
| 4452 source = "both_values[4].name() == 10"; | 4606 source = "both_values[4].name() == 10"; |
| 4453 CHECK(CompileRun(source)->BooleanValue()); | 4607 CHECK(CompileRun(source)->BooleanValue(context).FromJust()); |
| 4454 } | 4608 } |
| 4455 | 4609 |
| 4456 | 4610 |
| 4457 TEST(HiddenPrototypePropertyMirror) { | 4611 TEST(HiddenPrototypePropertyMirror) { |
| 4458 // Create a V8 environment with debug access. | 4612 // Create a V8 environment with debug access. |
| 4459 DebugLocalContext env; | 4613 DebugLocalContext env; |
| 4460 v8::Isolate* isolate = env->GetIsolate(); | 4614 v8::Isolate* isolate = env->GetIsolate(); |
| 4461 v8::HandleScope scope(isolate); | 4615 v8::HandleScope scope(isolate); |
| 4462 env.ExposeDebug(); | 4616 env.ExposeDebug(); |
| 4463 | 4617 |
| 4464 v8::Handle<v8::FunctionTemplate> t0 = v8::FunctionTemplate::New(isolate); | 4618 v8::Local<v8::FunctionTemplate> t0 = v8::FunctionTemplate::New(isolate); |
| 4465 t0->InstanceTemplate()->Set(v8::String::NewFromUtf8(isolate, "x"), | 4619 t0->InstanceTemplate()->Set(v8_str(isolate, "x"), |
| 4466 v8::Number::New(isolate, 0)); | 4620 v8::Number::New(isolate, 0)); |
| 4467 v8::Handle<v8::FunctionTemplate> t1 = v8::FunctionTemplate::New(isolate); | 4621 v8::Local<v8::FunctionTemplate> t1 = v8::FunctionTemplate::New(isolate); |
| 4468 t1->SetHiddenPrototype(true); | 4622 t1->SetHiddenPrototype(true); |
| 4469 t1->InstanceTemplate()->Set(v8::String::NewFromUtf8(isolate, "y"), | 4623 t1->InstanceTemplate()->Set(v8_str(isolate, "y"), |
| 4470 v8::Number::New(isolate, 1)); | 4624 v8::Number::New(isolate, 1)); |
| 4471 v8::Handle<v8::FunctionTemplate> t2 = v8::FunctionTemplate::New(isolate); | 4625 v8::Local<v8::FunctionTemplate> t2 = v8::FunctionTemplate::New(isolate); |
| 4472 t2->SetHiddenPrototype(true); | 4626 t2->SetHiddenPrototype(true); |
| 4473 t2->InstanceTemplate()->Set(v8::String::NewFromUtf8(isolate, "z"), | 4627 t2->InstanceTemplate()->Set(v8_str(isolate, "z"), |
| 4474 v8::Number::New(isolate, 2)); | 4628 v8::Number::New(isolate, 2)); |
| 4475 v8::Handle<v8::FunctionTemplate> t3 = v8::FunctionTemplate::New(isolate); | 4629 v8::Local<v8::FunctionTemplate> t3 = v8::FunctionTemplate::New(isolate); |
| 4476 t3->InstanceTemplate()->Set(v8::String::NewFromUtf8(isolate, "u"), | 4630 t3->InstanceTemplate()->Set(v8_str(isolate, "u"), |
| 4477 v8::Number::New(isolate, 3)); | 4631 v8::Number::New(isolate, 3)); |
| 4478 | 4632 |
| 4633 v8::Local<v8::Context> context = env.context(); |
| 4479 // Create object and set them on the global object. | 4634 // Create object and set them on the global object. |
| 4480 v8::Handle<v8::Object> o0 = t0->GetFunction()->NewInstance(); | 4635 v8::Local<v8::Object> o0 = t0->GetFunction(context) |
| 4481 env->Global()->Set(v8::String::NewFromUtf8(isolate, "o0"), o0); | 4636 .ToLocalChecked() |
| 4482 v8::Handle<v8::Object> o1 = t1->GetFunction()->NewInstance(); | 4637 ->NewInstance(context) |
| 4483 env->Global()->Set(v8::String::NewFromUtf8(isolate, "o1"), o1); | 4638 .ToLocalChecked(); |
| 4484 v8::Handle<v8::Object> o2 = t2->GetFunction()->NewInstance(); | 4639 CHECK(env->Global()->Set(context, v8_str(isolate, "o0"), o0).FromJust()); |
| 4485 env->Global()->Set(v8::String::NewFromUtf8(isolate, "o2"), o2); | 4640 v8::Local<v8::Object> o1 = t1->GetFunction(context) |
| 4486 v8::Handle<v8::Object> o3 = t3->GetFunction()->NewInstance(); | 4641 .ToLocalChecked() |
| 4487 env->Global()->Set(v8::String::NewFromUtf8(isolate, "o3"), o3); | 4642 ->NewInstance(context) |
| 4643 .ToLocalChecked(); |
| 4644 CHECK(env->Global()->Set(context, v8_str(isolate, "o1"), o1).FromJust()); |
| 4645 v8::Local<v8::Object> o2 = t2->GetFunction(context) |
| 4646 .ToLocalChecked() |
| 4647 ->NewInstance(context) |
| 4648 .ToLocalChecked(); |
| 4649 CHECK(env->Global()->Set(context, v8_str(isolate, "o2"), o2).FromJust()); |
| 4650 v8::Local<v8::Object> o3 = t3->GetFunction(context) |
| 4651 .ToLocalChecked() |
| 4652 ->NewInstance(context) |
| 4653 .ToLocalChecked(); |
| 4654 CHECK(env->Global()->Set(context, v8_str(isolate, "o3"), o3).FromJust()); |
| 4488 | 4655 |
| 4489 // Get mirrors for the four objects. | 4656 // Get mirrors for the four objects. |
| 4490 CompileRun( | 4657 CompileRun( |
| 4491 "var o0_mirror = debug.MakeMirror(o0);" | 4658 "var o0_mirror = debug.MakeMirror(o0);" |
| 4492 "var o1_mirror = debug.MakeMirror(o1);" | 4659 "var o1_mirror = debug.MakeMirror(o1);" |
| 4493 "var o2_mirror = debug.MakeMirror(o2);" | 4660 "var o2_mirror = debug.MakeMirror(o2);" |
| 4494 "var o3_mirror = debug.MakeMirror(o3)"); | 4661 "var o3_mirror = debug.MakeMirror(o3)"); |
| 4495 CHECK(CompileRun("o0_mirror instanceof debug.ObjectMirror")->BooleanValue()); | 4662 CHECK(CompileRun("o0_mirror instanceof debug.ObjectMirror") |
| 4496 CHECK(CompileRun("o1_mirror instanceof debug.ObjectMirror")->BooleanValue()); | 4663 ->BooleanValue(context) |
| 4497 CHECK(CompileRun("o2_mirror instanceof debug.ObjectMirror")->BooleanValue()); | 4664 .FromJust()); |
| 4498 CHECK(CompileRun("o3_mirror instanceof debug.ObjectMirror")->BooleanValue()); | 4665 CHECK(CompileRun("o1_mirror instanceof debug.ObjectMirror") |
| 4666 ->BooleanValue(context) |
| 4667 .FromJust()); |
| 4668 CHECK(CompileRun("o2_mirror instanceof debug.ObjectMirror") |
| 4669 ->BooleanValue(context) |
| 4670 .FromJust()); |
| 4671 CHECK(CompileRun("o3_mirror instanceof debug.ObjectMirror") |
| 4672 ->BooleanValue(context) |
| 4673 .FromJust()); |
| 4499 | 4674 |
| 4500 // Check that each object has one property. | 4675 // Check that each object has one property. |
| 4501 CHECK_EQ(1, CompileRun( | 4676 CHECK_EQ(1, CompileRun("o0_mirror.propertyNames().length") |
| 4502 "o0_mirror.propertyNames().length")->Int32Value()); | 4677 ->Int32Value(context) |
| 4503 CHECK_EQ(1, CompileRun( | 4678 .FromJust()); |
| 4504 "o1_mirror.propertyNames().length")->Int32Value()); | 4679 CHECK_EQ(1, CompileRun("o1_mirror.propertyNames().length") |
| 4505 CHECK_EQ(1, CompileRun( | 4680 ->Int32Value(context) |
| 4506 "o2_mirror.propertyNames().length")->Int32Value()); | 4681 .FromJust()); |
| 4507 CHECK_EQ(1, CompileRun( | 4682 CHECK_EQ(1, CompileRun("o2_mirror.propertyNames().length") |
| 4508 "o3_mirror.propertyNames().length")->Int32Value()); | 4683 ->Int32Value(context) |
| 4684 .FromJust()); |
| 4685 CHECK_EQ(1, CompileRun("o3_mirror.propertyNames().length") |
| 4686 ->Int32Value(context) |
| 4687 .FromJust()); |
| 4509 | 4688 |
| 4510 // Set o1 as prototype for o0. o1 has the hidden prototype flag so all | 4689 // Set o1 as prototype for o0. o1 has the hidden prototype flag so all |
| 4511 // properties on o1 should be seen on o0. | 4690 // properties on o1 should be seen on o0. |
| 4512 o0->Set(v8::String::NewFromUtf8(isolate, "__proto__"), o1); | 4691 CHECK(o0->Set(context, v8_str(isolate, "__proto__"), o1).FromJust()); |
| 4513 CHECK_EQ(2, CompileRun( | 4692 CHECK_EQ(2, CompileRun("o0_mirror.propertyNames().length") |
| 4514 "o0_mirror.propertyNames().length")->Int32Value()); | 4693 ->Int32Value(context) |
| 4515 CHECK_EQ(0, CompileRun( | 4694 .FromJust()); |
| 4516 "o0_mirror.property('x').value().value()")->Int32Value()); | 4695 CHECK_EQ(0, CompileRun("o0_mirror.property('x').value().value()") |
| 4517 CHECK_EQ(1, CompileRun( | 4696 ->Int32Value(context) |
| 4518 "o0_mirror.property('y').value().value()")->Int32Value()); | 4697 .FromJust()); |
| 4698 CHECK_EQ(1, CompileRun("o0_mirror.property('y').value().value()") |
| 4699 ->Int32Value(context) |
| 4700 .FromJust()); |
| 4519 | 4701 |
| 4520 // Set o2 as prototype for o0 (it will end up after o1 as o1 has the hidden | 4702 // Set o2 as prototype for o0 (it will end up after o1 as o1 has the hidden |
| 4521 // prototype flag. o2 also has the hidden prototype flag so all properties | 4703 // prototype flag. o2 also has the hidden prototype flag so all properties |
| 4522 // on o2 should be seen on o0 as well as properties on o1. | 4704 // on o2 should be seen on o0 as well as properties on o1. |
| 4523 o0->Set(v8::String::NewFromUtf8(isolate, "__proto__"), o2); | 4705 CHECK(o0->Set(context, v8_str(isolate, "__proto__"), o2).FromJust()); |
| 4524 CHECK_EQ(3, CompileRun( | 4706 CHECK_EQ(3, CompileRun("o0_mirror.propertyNames().length") |
| 4525 "o0_mirror.propertyNames().length")->Int32Value()); | 4707 ->Int32Value(context) |
| 4526 CHECK_EQ(0, CompileRun( | 4708 .FromJust()); |
| 4527 "o0_mirror.property('x').value().value()")->Int32Value()); | 4709 CHECK_EQ(0, CompileRun("o0_mirror.property('x').value().value()") |
| 4528 CHECK_EQ(1, CompileRun( | 4710 ->Int32Value(context) |
| 4529 "o0_mirror.property('y').value().value()")->Int32Value()); | 4711 .FromJust()); |
| 4530 CHECK_EQ(2, CompileRun( | 4712 CHECK_EQ(1, CompileRun("o0_mirror.property('y').value().value()") |
| 4531 "o0_mirror.property('z').value().value()")->Int32Value()); | 4713 ->Int32Value(context) |
| 4714 .FromJust()); |
| 4715 CHECK_EQ(2, CompileRun("o0_mirror.property('z').value().value()") |
| 4716 ->Int32Value(context) |
| 4717 .FromJust()); |
| 4532 | 4718 |
| 4533 // Set o3 as prototype for o0 (it will end up after o1 and o2 as both o1 and | 4719 // Set o3 as prototype for o0 (it will end up after o1 and o2 as both o1 and |
| 4534 // o2 has the hidden prototype flag. o3 does not have the hidden prototype | 4720 // o2 has the hidden prototype flag. o3 does not have the hidden prototype |
| 4535 // flag so properties on o3 should not be seen on o0 whereas the properties | 4721 // flag so properties on o3 should not be seen on o0 whereas the properties |
| 4536 // from o1 and o2 should still be seen on o0. | 4722 // from o1 and o2 should still be seen on o0. |
| 4537 // Final prototype chain: o0 -> o1 -> o2 -> o3 | 4723 // Final prototype chain: o0 -> o1 -> o2 -> o3 |
| 4538 // Hidden prototypes: ^^ ^^ | 4724 // Hidden prototypes: ^^ ^^ |
| 4539 o0->Set(v8::String::NewFromUtf8(isolate, "__proto__"), o3); | 4725 CHECK(o0->Set(context, v8_str(isolate, "__proto__"), o3).FromJust()); |
| 4540 CHECK_EQ(3, CompileRun( | 4726 CHECK_EQ(3, CompileRun("o0_mirror.propertyNames().length") |
| 4541 "o0_mirror.propertyNames().length")->Int32Value()); | 4727 ->Int32Value(context) |
| 4542 CHECK_EQ(1, CompileRun( | 4728 .FromJust()); |
| 4543 "o3_mirror.propertyNames().length")->Int32Value()); | 4729 CHECK_EQ(1, CompileRun("o3_mirror.propertyNames().length") |
| 4544 CHECK_EQ(0, CompileRun( | 4730 ->Int32Value(context) |
| 4545 "o0_mirror.property('x').value().value()")->Int32Value()); | 4731 .FromJust()); |
| 4546 CHECK_EQ(1, CompileRun( | 4732 CHECK_EQ(0, CompileRun("o0_mirror.property('x').value().value()") |
| 4547 "o0_mirror.property('y').value().value()")->Int32Value()); | 4733 ->Int32Value(context) |
| 4548 CHECK_EQ(2, CompileRun( | 4734 .FromJust()); |
| 4549 "o0_mirror.property('z').value().value()")->Int32Value()); | 4735 CHECK_EQ(1, CompileRun("o0_mirror.property('y').value().value()") |
| 4550 CHECK(CompileRun("o0_mirror.property('u').isUndefined()")->BooleanValue()); | 4736 ->Int32Value(context) |
| 4737 .FromJust()); |
| 4738 CHECK_EQ(2, CompileRun("o0_mirror.property('z').value().value()") |
| 4739 ->Int32Value(context) |
| 4740 .FromJust()); |
| 4741 CHECK(CompileRun("o0_mirror.property('u').isUndefined()") |
| 4742 ->BooleanValue(context) |
| 4743 .FromJust()); |
| 4551 | 4744 |
| 4552 // The prototype (__proto__) for o0 should be o3 as o1 and o2 are hidden. | 4745 // The prototype (__proto__) for o0 should be o3 as o1 and o2 are hidden. |
| 4553 CHECK(CompileRun("o0_mirror.protoObject() == o3_mirror")->BooleanValue()); | 4746 CHECK(CompileRun("o0_mirror.protoObject() == o3_mirror") |
| 4747 ->BooleanValue(context) |
| 4748 .FromJust()); |
| 4554 } | 4749 } |
| 4555 | 4750 |
| 4556 | 4751 |
| 4557 static void ProtperyXNativeGetter( | 4752 static void ProtperyXNativeGetter( |
| 4558 v8::Local<v8::String> property, | 4753 v8::Local<v8::String> property, |
| 4559 const v8::PropertyCallbackInfo<v8::Value>& info) { | 4754 const v8::PropertyCallbackInfo<v8::Value>& info) { |
| 4560 info.GetReturnValue().Set(10); | 4755 info.GetReturnValue().Set(10); |
| 4561 } | 4756 } |
| 4562 | 4757 |
| 4563 | 4758 |
| 4564 TEST(NativeGetterPropertyMirror) { | 4759 TEST(NativeGetterPropertyMirror) { |
| 4565 // Create a V8 environment with debug access. | 4760 // Create a V8 environment with debug access. |
| 4566 DebugLocalContext env; | 4761 DebugLocalContext env; |
| 4567 v8::Isolate* isolate = env->GetIsolate(); | 4762 v8::Isolate* isolate = env->GetIsolate(); |
| 4568 v8::HandleScope scope(isolate); | 4763 v8::HandleScope scope(isolate); |
| 4569 env.ExposeDebug(); | 4764 env.ExposeDebug(); |
| 4570 | 4765 |
| 4571 v8::Handle<v8::String> name = v8::String::NewFromUtf8(isolate, "x"); | 4766 v8::Local<v8::Context> context = env.context(); |
| 4767 v8::Local<v8::String> name = v8_str(isolate, "x"); |
| 4572 // Create object with named accessor. | 4768 // Create object with named accessor. |
| 4573 v8::Handle<v8::ObjectTemplate> named = v8::ObjectTemplate::New(isolate); | 4769 v8::Local<v8::ObjectTemplate> named = v8::ObjectTemplate::New(isolate); |
| 4574 named->SetAccessor(name, &ProtperyXNativeGetter, NULL, | 4770 named->SetAccessor(name, &ProtperyXNativeGetter, NULL, v8::Local<v8::Value>(), |
| 4575 v8::Handle<v8::Value>(), v8::DEFAULT, v8::None); | 4771 v8::DEFAULT, v8::None); |
| 4576 | 4772 |
| 4577 // Create object with named property getter. | 4773 // Create object with named property getter. |
| 4578 env->Global()->Set(v8::String::NewFromUtf8(isolate, "instance"), | 4774 CHECK(env->Global() |
| 4579 named->NewInstance()); | 4775 ->Set(context, v8_str(isolate, "instance"), |
| 4580 CHECK_EQ(10, CompileRun("instance.x")->Int32Value()); | 4776 named->NewInstance(context).ToLocalChecked()) |
| 4777 .FromJust()); |
| 4778 CHECK_EQ(10, CompileRun("instance.x")->Int32Value(context).FromJust()); |
| 4581 | 4779 |
| 4582 // Get mirror for the object with property getter. | 4780 // Get mirror for the object with property getter. |
| 4583 CompileRun("var instance_mirror = debug.MakeMirror(instance);"); | 4781 CompileRun("var instance_mirror = debug.MakeMirror(instance);"); |
| 4584 CHECK(CompileRun( | 4782 CHECK(CompileRun("instance_mirror instanceof debug.ObjectMirror") |
| 4585 "instance_mirror instanceof debug.ObjectMirror")->BooleanValue()); | 4783 ->BooleanValue(context) |
| 4784 .FromJust()); |
| 4586 | 4785 |
| 4587 CompileRun("var named_names = instance_mirror.propertyNames();"); | 4786 CompileRun("var named_names = instance_mirror.propertyNames();"); |
| 4588 CHECK_EQ(1, CompileRun("named_names.length")->Int32Value()); | 4787 CHECK_EQ(1, CompileRun("named_names.length")->Int32Value(context).FromJust()); |
| 4589 CHECK(CompileRun("named_names[0] == 'x'")->BooleanValue()); | 4788 CHECK(CompileRun("named_names[0] == 'x'")->BooleanValue(context).FromJust()); |
| 4590 CHECK(CompileRun( | 4789 CHECK(CompileRun("instance_mirror.property('x').value().isNumber()") |
| 4591 "instance_mirror.property('x').value().isNumber()")->BooleanValue()); | 4790 ->BooleanValue(context) |
| 4592 CHECK(CompileRun( | 4791 .FromJust()); |
| 4593 "instance_mirror.property('x').value().value() == 10")->BooleanValue()); | 4792 CHECK(CompileRun("instance_mirror.property('x').value().value() == 10") |
| 4793 ->BooleanValue(context) |
| 4794 .FromJust()); |
| 4594 } | 4795 } |
| 4595 | 4796 |
| 4596 | 4797 |
| 4597 static void ProtperyXNativeGetterThrowingError( | 4798 static void ProtperyXNativeGetterThrowingError( |
| 4598 v8::Local<v8::String> property, | 4799 v8::Local<v8::String> property, |
| 4599 const v8::PropertyCallbackInfo<v8::Value>& info) { | 4800 const v8::PropertyCallbackInfo<v8::Value>& info) { |
| 4600 CompileRun("throw new Error('Error message');"); | 4801 CompileRun("throw new Error('Error message');"); |
| 4601 } | 4802 } |
| 4602 | 4803 |
| 4603 | 4804 |
| 4604 TEST(NativeGetterThrowingErrorPropertyMirror) { | 4805 TEST(NativeGetterThrowingErrorPropertyMirror) { |
| 4605 // Create a V8 environment with debug access. | 4806 // Create a V8 environment with debug access. |
| 4606 DebugLocalContext env; | 4807 DebugLocalContext env; |
| 4607 v8::Isolate* isolate = env->GetIsolate(); | 4808 v8::Isolate* isolate = env->GetIsolate(); |
| 4608 v8::HandleScope scope(isolate); | 4809 v8::HandleScope scope(isolate); |
| 4609 env.ExposeDebug(); | 4810 env.ExposeDebug(); |
| 4610 | 4811 |
| 4611 v8::Handle<v8::String> name = v8::String::NewFromUtf8(isolate, "x"); | 4812 v8::Local<v8::Context> context = env.context(); |
| 4813 v8::Local<v8::String> name = v8_str(isolate, "x"); |
| 4612 // Create object with named accessor. | 4814 // Create object with named accessor. |
| 4613 v8::Handle<v8::ObjectTemplate> named = v8::ObjectTemplate::New(isolate); | 4815 v8::Local<v8::ObjectTemplate> named = v8::ObjectTemplate::New(isolate); |
| 4614 named->SetAccessor(name, &ProtperyXNativeGetterThrowingError, NULL, | 4816 named->SetAccessor(name, &ProtperyXNativeGetterThrowingError, NULL, |
| 4615 v8::Handle<v8::Value>(), v8::DEFAULT, v8::None); | 4817 v8::Local<v8::Value>(), v8::DEFAULT, v8::None); |
| 4616 | 4818 |
| 4617 // Create object with named property getter. | 4819 // Create object with named property getter. |
| 4618 env->Global()->Set(v8::String::NewFromUtf8(isolate, "instance"), | 4820 CHECK(env->Global() |
| 4619 named->NewInstance()); | 4821 ->Set(context, v8_str(isolate, "instance"), |
| 4822 named->NewInstance(context).ToLocalChecked()) |
| 4823 .FromJust()); |
| 4620 | 4824 |
| 4621 // Get mirror for the object with property getter. | 4825 // Get mirror for the object with property getter. |
| 4622 CompileRun("var instance_mirror = debug.MakeMirror(instance);"); | 4826 CompileRun("var instance_mirror = debug.MakeMirror(instance);"); |
| 4623 CHECK(CompileRun( | 4827 CHECK(CompileRun("instance_mirror instanceof debug.ObjectMirror") |
| 4624 "instance_mirror instanceof debug.ObjectMirror")->BooleanValue()); | 4828 ->BooleanValue(context) |
| 4829 .FromJust()); |
| 4625 CompileRun("named_names = instance_mirror.propertyNames();"); | 4830 CompileRun("named_names = instance_mirror.propertyNames();"); |
| 4626 CHECK_EQ(1, CompileRun("named_names.length")->Int32Value()); | 4831 CHECK_EQ(1, CompileRun("named_names.length")->Int32Value(context).FromJust()); |
| 4627 CHECK(CompileRun("named_names[0] == 'x'")->BooleanValue()); | 4832 CHECK(CompileRun("named_names[0] == 'x'")->BooleanValue(context).FromJust()); |
| 4628 CHECK(CompileRun( | 4833 CHECK(CompileRun("instance_mirror.property('x').value().isError()") |
| 4629 "instance_mirror.property('x').value().isError()")->BooleanValue()); | 4834 ->BooleanValue(context) |
| 4835 .FromJust()); |
| 4630 | 4836 |
| 4631 // Check that the message is that passed to the Error constructor. | 4837 // Check that the message is that passed to the Error constructor. |
| 4632 CHECK(CompileRun( | 4838 CHECK( |
| 4633 "instance_mirror.property('x').value().message() == 'Error message'")-> | 4839 CompileRun( |
| 4634 BooleanValue()); | 4840 "instance_mirror.property('x').value().message() == 'Error message'") |
| 4841 ->BooleanValue(context) |
| 4842 .FromJust()); |
| 4635 } | 4843 } |
| 4636 | 4844 |
| 4637 | 4845 |
| 4638 // Test that hidden properties object is not returned as an unnamed property | 4846 // Test that hidden properties object is not returned as an unnamed property |
| 4639 // among regular properties. | 4847 // among regular properties. |
| 4640 // See http://crbug.com/26491 | 4848 // See http://crbug.com/26491 |
| 4641 TEST(NoHiddenProperties) { | 4849 TEST(NoHiddenProperties) { |
| 4642 // Create a V8 environment with debug access. | 4850 // Create a V8 environment with debug access. |
| 4643 DebugLocalContext env; | 4851 DebugLocalContext env; |
| 4644 v8::Isolate* isolate = env->GetIsolate(); | 4852 v8::Isolate* isolate = env->GetIsolate(); |
| 4645 v8::HandleScope scope(isolate); | 4853 v8::HandleScope scope(isolate); |
| 4646 env.ExposeDebug(); | 4854 env.ExposeDebug(); |
| 4647 | 4855 |
| 4856 v8::Local<v8::Context> context = env.context(); |
| 4648 // Create an object in the global scope. | 4857 // Create an object in the global scope. |
| 4649 const char* source = "var obj = {a: 1};"; | 4858 const char* source = "var obj = {a: 1};"; |
| 4650 v8::Script::Compile(v8::String::NewFromUtf8(isolate, source)) | 4859 v8::Script::Compile(context, v8_str(isolate, source)) |
| 4651 ->Run(); | 4860 .ToLocalChecked() |
| 4861 ->Run(context) |
| 4862 .ToLocalChecked(); |
| 4652 v8::Local<v8::Object> obj = v8::Local<v8::Object>::Cast( | 4863 v8::Local<v8::Object> obj = v8::Local<v8::Object>::Cast( |
| 4653 env->Global()->Get(v8::String::NewFromUtf8(isolate, "obj"))); | 4864 env->Global()->Get(context, v8_str(isolate, "obj")).ToLocalChecked()); |
| 4654 // Set a hidden property on the object. | 4865 // Set a hidden property on the object. |
| 4655 obj->SetPrivate(env.context(), | 4866 obj->SetPrivate( |
| 4656 v8::Private::New(isolate, v8::String::NewFromUtf8( | 4867 env.context(), |
| 4657 isolate, "v8::test-debug::a")), | 4868 v8::Private::New(isolate, v8_str(isolate, "v8::test-debug::a")), |
| 4658 v8::Int32::New(isolate, 11)) | 4869 v8::Int32::New(isolate, 11)) |
| 4659 .FromJust(); | 4870 .FromJust(); |
| 4660 | 4871 |
| 4661 // Get mirror for the object with property getter. | 4872 // Get mirror for the object with property getter. |
| 4662 CompileRun("var obj_mirror = debug.MakeMirror(obj);"); | 4873 CompileRun("var obj_mirror = debug.MakeMirror(obj);"); |
| 4663 CHECK(CompileRun( | 4874 CHECK(CompileRun("obj_mirror instanceof debug.ObjectMirror") |
| 4664 "obj_mirror instanceof debug.ObjectMirror")->BooleanValue()); | 4875 ->BooleanValue(context) |
| 4876 .FromJust()); |
| 4665 CompileRun("var named_names = obj_mirror.propertyNames();"); | 4877 CompileRun("var named_names = obj_mirror.propertyNames();"); |
| 4666 // There should be exactly one property. But there is also an unnamed | 4878 // There should be exactly one property. But there is also an unnamed |
| 4667 // property whose value is hidden properties dictionary. The latter | 4879 // property whose value is hidden properties dictionary. The latter |
| 4668 // property should not be in the list of reguar properties. | 4880 // property should not be in the list of reguar properties. |
| 4669 CHECK_EQ(1, CompileRun("named_names.length")->Int32Value()); | 4881 CHECK_EQ(1, CompileRun("named_names.length")->Int32Value(context).FromJust()); |
| 4670 CHECK(CompileRun("named_names[0] == 'a'")->BooleanValue()); | 4882 CHECK(CompileRun("named_names[0] == 'a'")->BooleanValue(context).FromJust()); |
| 4671 CHECK(CompileRun( | 4883 CHECK(CompileRun("obj_mirror.property('a').value().value() == 1") |
| 4672 "obj_mirror.property('a').value().value() == 1")->BooleanValue()); | 4884 ->BooleanValue(context) |
| 4885 .FromJust()); |
| 4673 | 4886 |
| 4674 // Object created by t0 will become hidden prototype of object 'obj'. | 4887 // Object created by t0 will become hidden prototype of object 'obj'. |
| 4675 v8::Handle<v8::FunctionTemplate> t0 = v8::FunctionTemplate::New(isolate); | 4888 v8::Local<v8::FunctionTemplate> t0 = v8::FunctionTemplate::New(isolate); |
| 4676 t0->InstanceTemplate()->Set(v8::String::NewFromUtf8(isolate, "b"), | 4889 t0->InstanceTemplate()->Set(v8_str(isolate, "b"), |
| 4677 v8::Number::New(isolate, 2)); | 4890 v8::Number::New(isolate, 2)); |
| 4678 t0->SetHiddenPrototype(true); | 4891 t0->SetHiddenPrototype(true); |
| 4679 v8::Handle<v8::FunctionTemplate> t1 = v8::FunctionTemplate::New(isolate); | 4892 v8::Local<v8::FunctionTemplate> t1 = v8::FunctionTemplate::New(isolate); |
| 4680 t1->InstanceTemplate()->Set(v8::String::NewFromUtf8(isolate, "c"), | 4893 t1->InstanceTemplate()->Set(v8_str(isolate, "c"), |
| 4681 v8::Number::New(isolate, 3)); | 4894 v8::Number::New(isolate, 3)); |
| 4682 | 4895 |
| 4683 // Create proto objects, add hidden properties to them and set them on | 4896 // Create proto objects, add hidden properties to them and set them on |
| 4684 // the global object. | 4897 // the global object. |
| 4685 v8::Handle<v8::Object> protoObj = t0->GetFunction()->NewInstance(); | 4898 v8::Local<v8::Object> protoObj = t0->GetFunction(context) |
| 4899 .ToLocalChecked() |
| 4900 ->NewInstance(context) |
| 4901 .ToLocalChecked(); |
| 4686 protoObj->SetPrivate( | 4902 protoObj->SetPrivate( |
| 4687 env.context(), | 4903 env.context(), |
| 4688 v8::Private::New(isolate, v8::String::NewFromUtf8( | 4904 v8::Private::New(isolate, v8_str(isolate, "v8::test-debug::b")), |
| 4689 isolate, "v8::test-debug::b")), | |
| 4690 v8::Int32::New(isolate, 12)) | 4905 v8::Int32::New(isolate, 12)) |
| 4691 .FromJust(); | 4906 .FromJust(); |
| 4692 env->Global()->Set(v8::String::NewFromUtf8(isolate, "protoObj"), | 4907 CHECK(env->Global() |
| 4693 protoObj); | 4908 ->Set(context, v8_str(isolate, "protoObj"), protoObj) |
| 4694 v8::Handle<v8::Object> grandProtoObj = t1->GetFunction()->NewInstance(); | 4909 .FromJust()); |
| 4695 grandProtoObj->SetPrivate( | 4910 v8::Local<v8::Object> grandProtoObj = t1->GetFunction(context) |
| 4696 env.context(), | 4911 .ToLocalChecked() |
| 4697 v8::Private::New(isolate, v8::String::NewFromUtf8( | 4912 ->NewInstance(context) |
| 4698 isolate, "v8::test-debug::c")), | 4913 .ToLocalChecked(); |
| 4699 v8::Int32::New(isolate, 13)) | 4914 grandProtoObj->SetPrivate(env.context(), |
| 4915 v8::Private::New( |
| 4916 isolate, v8_str(isolate, "v8::test-debug::c")), |
| 4917 v8::Int32::New(isolate, 13)) |
| 4700 .FromJust(); | 4918 .FromJust(); |
| 4701 env->Global()->Set(v8::String::NewFromUtf8(isolate, "grandProtoObj"), | 4919 CHECK(env->Global() |
| 4702 grandProtoObj); | 4920 ->Set(context, v8_str(isolate, "grandProtoObj"), grandProtoObj) |
| 4921 .FromJust()); |
| 4703 | 4922 |
| 4704 // Setting prototypes: obj->protoObj->grandProtoObj | 4923 // Setting prototypes: obj->protoObj->grandProtoObj |
| 4705 protoObj->Set(v8::String::NewFromUtf8(isolate, "__proto__"), | 4924 CHECK(protoObj->Set(context, v8_str(isolate, "__proto__"), grandProtoObj) |
| 4706 grandProtoObj); | 4925 .FromJust()); |
| 4707 obj->Set(v8::String::NewFromUtf8(isolate, "__proto__"), protoObj); | 4926 CHECK(obj->Set(context, v8_str(isolate, "__proto__"), protoObj).FromJust()); |
| 4708 | 4927 |
| 4709 // Get mirror for the object with property getter. | 4928 // Get mirror for the object with property getter. |
| 4710 CompileRun("var obj_mirror = debug.MakeMirror(obj);"); | 4929 CompileRun("var obj_mirror = debug.MakeMirror(obj);"); |
| 4711 CHECK(CompileRun( | 4930 CHECK(CompileRun("obj_mirror instanceof debug.ObjectMirror") |
| 4712 "obj_mirror instanceof debug.ObjectMirror")->BooleanValue()); | 4931 ->BooleanValue(context) |
| 4932 .FromJust()); |
| 4713 CompileRun("var named_names = obj_mirror.propertyNames();"); | 4933 CompileRun("var named_names = obj_mirror.propertyNames();"); |
| 4714 // There should be exactly two properties - one from the object itself and | 4934 // There should be exactly two properties - one from the object itself and |
| 4715 // another from its hidden prototype. | 4935 // another from its hidden prototype. |
| 4716 CHECK_EQ(2, CompileRun("named_names.length")->Int32Value()); | 4936 CHECK_EQ(2, CompileRun("named_names.length")->Int32Value(context).FromJust()); |
| 4717 CHECK(CompileRun("named_names.sort(); named_names[0] == 'a' &&" | 4937 CHECK(CompileRun("named_names.sort(); named_names[0] == 'a' &&" |
| 4718 "named_names[1] == 'b'")->BooleanValue()); | 4938 "named_names[1] == 'b'") |
| 4719 CHECK(CompileRun( | 4939 ->BooleanValue(context) |
| 4720 "obj_mirror.property('a').value().value() == 1")->BooleanValue()); | 4940 .FromJust()); |
| 4721 CHECK(CompileRun( | 4941 CHECK(CompileRun("obj_mirror.property('a').value().value() == 1") |
| 4722 "obj_mirror.property('b').value().value() == 2")->BooleanValue()); | 4942 ->BooleanValue(context) |
| 4943 .FromJust()); |
| 4944 CHECK(CompileRun("obj_mirror.property('b').value().value() == 2") |
| 4945 ->BooleanValue(context) |
| 4946 .FromJust()); |
| 4723 } | 4947 } |
| 4724 | 4948 |
| 4725 | 4949 |
| 4726 // Multithreaded tests of JSON debugger protocol | 4950 // Multithreaded tests of JSON debugger protocol |
| 4727 | 4951 |
| 4728 // Support classes | 4952 // Support classes |
| 4729 | 4953 |
| 4730 // Provides synchronization between N threads, where N is a template parameter. | 4954 // Provides synchronization between N threads, where N is a template parameter. |
| 4731 // The Wait() call blocks a thread until it is called for the Nth time, then all | 4955 // The Wait() call blocks a thread until it is called for the Nth time, then all |
| 4732 // calls return. Each ThreadBarrier object can only be used once. | 4956 // calls return. Each ThreadBarrier object can only be used once. |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4882 // placing JSON debugger commands in the queue. | 5106 // placing JSON debugger commands in the queue. |
| 4883 class MessageQueueDebuggerThread : public v8::base::Thread { | 5107 class MessageQueueDebuggerThread : public v8::base::Thread { |
| 4884 public: | 5108 public: |
| 4885 MessageQueueDebuggerThread() | 5109 MessageQueueDebuggerThread() |
| 4886 : Thread(Options("MessageQueueDebuggerThread")) {} | 5110 : Thread(Options("MessageQueueDebuggerThread")) {} |
| 4887 void Run(); | 5111 void Run(); |
| 4888 }; | 5112 }; |
| 4889 | 5113 |
| 4890 | 5114 |
| 4891 static void MessageHandler(const v8::Debug::Message& message) { | 5115 static void MessageHandler(const v8::Debug::Message& message) { |
| 4892 v8::Handle<v8::String> json = message.GetJSON(); | 5116 v8::Local<v8::String> json = message.GetJSON(); |
| 4893 v8::String::Utf8Value utf8(json); | 5117 v8::String::Utf8Value utf8(json); |
| 4894 if (IsBreakEventMessage(*utf8)) { | 5118 if (IsBreakEventMessage(*utf8)) { |
| 4895 // Lets test script wait until break occurs to send commands. | 5119 // Lets test script wait until break occurs to send commands. |
| 4896 // Signals when a break is reported. | 5120 // Signals when a break is reported. |
| 4897 message_queue_barriers.semaphore_2.Signal(); | 5121 message_queue_barriers.semaphore_2.Signal(); |
| 4898 } | 5122 } |
| 4899 | 5123 |
| 4900 // Allow message handler to block on a semaphore, to test queueing of | 5124 // Allow message handler to block on a semaphore, to test queueing of |
| 4901 // messages while blocked. | 5125 // messages while blocked. |
| 4902 message_queue_barriers.semaphore_1.Wait(); | 5126 message_queue_barriers.semaphore_1.Wait(); |
| (...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5199 | 5423 |
| 5200 v8::Isolate::CreateParams create_params; | 5424 v8::Isolate::CreateParams create_params; |
| 5201 create_params.array_buffer_allocator = CcTest::array_buffer_allocator(); | 5425 create_params.array_buffer_allocator = CcTest::array_buffer_allocator(); |
| 5202 isolate_ = v8::Isolate::New(create_params); | 5426 isolate_ = v8::Isolate::New(create_params); |
| 5203 threaded_debugging_barriers.barrier_3.Wait(); | 5427 threaded_debugging_barriers.barrier_3.Wait(); |
| 5204 { | 5428 { |
| 5205 v8::Isolate::Scope isolate_scope(isolate_); | 5429 v8::Isolate::Scope isolate_scope(isolate_); |
| 5206 DebugLocalContext env(isolate_); | 5430 DebugLocalContext env(isolate_); |
| 5207 v8::HandleScope scope(isolate_); | 5431 v8::HandleScope scope(isolate_); |
| 5208 v8::Debug::SetMessageHandler(&ThreadedMessageHandler); | 5432 v8::Debug::SetMessageHandler(&ThreadedMessageHandler); |
| 5209 v8::Handle<v8::ObjectTemplate> global_template = | 5433 v8::Local<v8::ObjectTemplate> global_template = |
| 5210 v8::ObjectTemplate::New(env->GetIsolate()); | 5434 v8::ObjectTemplate::New(env->GetIsolate()); |
| 5211 global_template->Set( | 5435 global_template->Set( |
| 5212 v8::String::NewFromUtf8(env->GetIsolate(), "ThreadedAtBarrier1"), | 5436 v8_str(env->GetIsolate(), "ThreadedAtBarrier1"), |
| 5213 v8::FunctionTemplate::New(isolate_, ThreadedAtBarrier1)); | 5437 v8::FunctionTemplate::New(isolate_, ThreadedAtBarrier1)); |
| 5214 v8::Handle<v8::Context> context = | 5438 v8::Local<v8::Context> context = |
| 5215 v8::Context::New(isolate_, NULL, global_template); | 5439 v8::Context::New(isolate_, NULL, global_template); |
| 5216 v8::Context::Scope context_scope(context); | 5440 v8::Context::Scope context_scope(context); |
| 5217 | 5441 |
| 5218 CompileRun(source); | 5442 CompileRun(source); |
| 5219 } | 5443 } |
| 5220 threaded_debugging_barriers.barrier_4.Wait(); | 5444 threaded_debugging_barriers.barrier_4.Wait(); |
| 5221 isolate_->Dispose(); | 5445 isolate_->Dispose(); |
| 5222 } | 5446 } |
| 5223 | 5447 |
| 5224 | 5448 |
| (...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5508 | 5732 |
| 5509 | 5733 |
| 5510 // Source for a JavaScript function which returns the data parameter of a | 5734 // Source for a JavaScript function which returns the data parameter of a |
| 5511 // function called in the context of the debugger. If no data parameter is | 5735 // function called in the context of the debugger. If no data parameter is |
| 5512 // passed it throws an exception. | 5736 // passed it throws an exception. |
| 5513 static const char* debugger_call_with_data_source = | 5737 static const char* debugger_call_with_data_source = |
| 5514 "function debugger_call_with_data(exec_state, data) {" | 5738 "function debugger_call_with_data(exec_state, data) {" |
| 5515 " if (data) return data;" | 5739 " if (data) return data;" |
| 5516 " throw 'No data!'" | 5740 " throw 'No data!'" |
| 5517 "}"; | 5741 "}"; |
| 5518 v8::Handle<v8::Function> debugger_call_with_data; | 5742 v8::Local<v8::Function> debugger_call_with_data; |
| 5519 | 5743 |
| 5520 | 5744 |
| 5521 // Source for a JavaScript function which returns the data parameter of a | 5745 // Source for a JavaScript function which returns the data parameter of a |
| 5522 // function called in the context of the debugger. If no data parameter is | 5746 // function called in the context of the debugger. If no data parameter is |
| 5523 // passed it throws an exception. | 5747 // passed it throws an exception. |
| 5524 static const char* debugger_call_with_closure_source = | 5748 static const char* debugger_call_with_closure_source = |
| 5525 "var x = 3;" | 5749 "var x = 3;" |
| 5526 "(function (exec_state) {" | 5750 "(function (exec_state) {" |
| 5527 " if (exec_state.y) return x - 1;" | 5751 " if (exec_state.y) return x - 1;" |
| 5528 " exec_state.y = x;" | 5752 " exec_state.y = x;" |
| 5529 " return exec_state.y" | 5753 " return exec_state.y" |
| 5530 "})"; | 5754 "})"; |
| 5531 v8::Handle<v8::Function> debugger_call_with_closure; | 5755 v8::Local<v8::Function> debugger_call_with_closure; |
| 5532 | 5756 |
| 5533 // Function to retrieve the number of JavaScript frames by calling a JavaScript | 5757 // Function to retrieve the number of JavaScript frames by calling a JavaScript |
| 5534 // in the debugger. | 5758 // in the debugger. |
| 5535 static void CheckFrameCount(const v8::FunctionCallbackInfo<v8::Value>& args) { | 5759 static void CheckFrameCount(const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 5536 CHECK(v8::Debug::Call(frame_count)->IsNumber()); | 5760 v8::Local<v8::Context> context = args.GetIsolate()->GetCurrentContext(); |
| 5537 CHECK_EQ(args[0]->Int32Value(), | 5761 CHECK(v8::Debug::Call(context, frame_count).ToLocalChecked()->IsNumber()); |
| 5538 v8::Debug::Call(frame_count)->Int32Value()); | 5762 CHECK_EQ(args[0]->Int32Value(context).FromJust(), |
| 5763 v8::Debug::Call(context, frame_count) |
| 5764 .ToLocalChecked() |
| 5765 ->Int32Value(context) |
| 5766 .FromJust()); |
| 5539 } | 5767 } |
| 5540 | 5768 |
| 5541 | 5769 |
| 5542 // Function to retrieve the source line of the top JavaScript frame by calling a | 5770 // Function to retrieve the source line of the top JavaScript frame by calling a |
| 5543 // JavaScript function in the debugger. | 5771 // JavaScript function in the debugger. |
| 5544 static void CheckSourceLine(const v8::FunctionCallbackInfo<v8::Value>& args) { | 5772 static void CheckSourceLine(const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 5545 CHECK(v8::Debug::Call(frame_source_line)->IsNumber()); | 5773 v8::Local<v8::Context> context = args.GetIsolate()->GetCurrentContext(); |
| 5546 CHECK_EQ(args[0]->Int32Value(), | 5774 CHECK( |
| 5547 v8::Debug::Call(frame_source_line)->Int32Value()); | 5775 v8::Debug::Call(context, frame_source_line).ToLocalChecked()->IsNumber()); |
| 5776 CHECK_EQ(args[0]->Int32Value(context).FromJust(), |
| 5777 v8::Debug::Call(context, frame_source_line) |
| 5778 .ToLocalChecked() |
| 5779 ->Int32Value(context) |
| 5780 .FromJust()); |
| 5548 } | 5781 } |
| 5549 | 5782 |
| 5550 | 5783 |
| 5551 // Function to test passing an additional parameter to a JavaScript function | 5784 // Function to test passing an additional parameter to a JavaScript function |
| 5552 // called in the debugger. It also tests that functions called in the debugger | 5785 // called in the debugger. It also tests that functions called in the debugger |
| 5553 // can throw exceptions. | 5786 // can throw exceptions. |
| 5554 static void CheckDataParameter( | 5787 static void CheckDataParameter( |
| 5555 const v8::FunctionCallbackInfo<v8::Value>& args) { | 5788 const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 5556 v8::Handle<v8::String> data = | 5789 v8::Local<v8::String> data = v8_str(args.GetIsolate(), "Test"); |
| 5557 v8::String::NewFromUtf8(args.GetIsolate(), "Test"); | 5790 v8::Local<v8::Context> context = args.GetIsolate()->GetCurrentContext(); |
| 5558 CHECK(v8::Debug::Call(debugger_call_with_data, data)->IsString()); | 5791 CHECK(v8::Debug::Call(context, debugger_call_with_data, data) |
| 5792 .ToLocalChecked() |
| 5793 ->IsString()); |
| 5559 | 5794 |
| 5560 for (int i = 0; i < 3; i++) { | 5795 for (int i = 0; i < 3; i++) { |
| 5561 v8::TryCatch catcher(args.GetIsolate()); | 5796 v8::TryCatch catcher(args.GetIsolate()); |
| 5562 CHECK(v8::Debug::Call(debugger_call_with_data).IsEmpty()); | 5797 CHECK(v8::Debug::Call(context, debugger_call_with_data).IsEmpty()); |
| 5563 CHECK(catcher.HasCaught()); | 5798 CHECK(catcher.HasCaught()); |
| 5564 CHECK(catcher.Exception()->IsString()); | 5799 CHECK(catcher.Exception()->IsString()); |
| 5565 } | 5800 } |
| 5566 } | 5801 } |
| 5567 | 5802 |
| 5568 | 5803 |
| 5569 // Function to test using a JavaScript with closure in the debugger. | 5804 // Function to test using a JavaScript with closure in the debugger. |
| 5570 static void CheckClosure(const v8::FunctionCallbackInfo<v8::Value>& args) { | 5805 static void CheckClosure(const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 5571 CHECK(v8::Debug::Call(debugger_call_with_closure)->IsNumber()); | 5806 v8::Local<v8::Context> context = args.GetIsolate()->GetCurrentContext(); |
| 5572 CHECK_EQ(3, v8::Debug::Call(debugger_call_with_closure)->Int32Value()); | 5807 CHECK(v8::Debug::Call(context, debugger_call_with_closure) |
| 5808 .ToLocalChecked() |
| 5809 ->IsNumber()); |
| 5810 CHECK_EQ(3, v8::Debug::Call(context, debugger_call_with_closure) |
| 5811 .ToLocalChecked() |
| 5812 ->Int32Value(context) |
| 5813 .FromJust()); |
| 5573 } | 5814 } |
| 5574 | 5815 |
| 5575 | 5816 |
| 5576 // Test functions called through the debugger. | 5817 // Test functions called through the debugger. |
| 5577 TEST(CallFunctionInDebugger) { | 5818 TEST(CallFunctionInDebugger) { |
| 5578 // Create and enter a context with the functions CheckFrameCount, | 5819 // Create and enter a context with the functions CheckFrameCount, |
| 5579 // CheckSourceLine and CheckDataParameter installed. | 5820 // CheckSourceLine and CheckDataParameter installed. |
| 5580 v8::Isolate* isolate = CcTest::isolate(); | 5821 v8::Isolate* isolate = CcTest::isolate(); |
| 5581 v8::HandleScope scope(isolate); | 5822 v8::HandleScope scope(isolate); |
| 5582 v8::Handle<v8::ObjectTemplate> global_template = | 5823 v8::Local<v8::ObjectTemplate> global_template = |
| 5583 v8::ObjectTemplate::New(isolate); | 5824 v8::ObjectTemplate::New(isolate); |
| 5584 global_template->Set( | 5825 global_template->Set(v8_str(isolate, "CheckFrameCount"), |
| 5585 v8::String::NewFromUtf8(isolate, "CheckFrameCount"), | 5826 v8::FunctionTemplate::New(isolate, CheckFrameCount)); |
| 5586 v8::FunctionTemplate::New(isolate, CheckFrameCount)); | 5827 global_template->Set(v8_str(isolate, "CheckSourceLine"), |
| 5587 global_template->Set( | 5828 v8::FunctionTemplate::New(isolate, CheckSourceLine)); |
| 5588 v8::String::NewFromUtf8(isolate, "CheckSourceLine"), | 5829 global_template->Set(v8_str(isolate, "CheckDataParameter"), |
| 5589 v8::FunctionTemplate::New(isolate, CheckSourceLine)); | 5830 v8::FunctionTemplate::New(isolate, CheckDataParameter)); |
| 5590 global_template->Set( | 5831 global_template->Set(v8_str(isolate, "CheckClosure"), |
| 5591 v8::String::NewFromUtf8(isolate, "CheckDataParameter"), | 5832 v8::FunctionTemplate::New(isolate, CheckClosure)); |
| 5592 v8::FunctionTemplate::New(isolate, CheckDataParameter)); | 5833 v8::Local<v8::Context> context = |
| 5593 global_template->Set( | 5834 v8::Context::New(isolate, NULL, global_template); |
| 5594 v8::String::NewFromUtf8(isolate, "CheckClosure"), | |
| 5595 v8::FunctionTemplate::New(isolate, CheckClosure)); | |
| 5596 v8::Handle<v8::Context> context = v8::Context::New(isolate, | |
| 5597 NULL, | |
| 5598 global_template); | |
| 5599 v8::Context::Scope context_scope(context); | 5835 v8::Context::Scope context_scope(context); |
| 5600 | 5836 |
| 5601 // Compile a function for checking the number of JavaScript frames. | 5837 // Compile a function for checking the number of JavaScript frames. |
| 5602 v8::Script::Compile( | 5838 v8::Script::Compile(context, v8_str(isolate, frame_count_source)) |
| 5603 v8::String::NewFromUtf8(isolate, frame_count_source))->Run(); | 5839 .ToLocalChecked() |
| 5604 frame_count = v8::Local<v8::Function>::Cast(context->Global()->Get( | 5840 ->Run(context) |
| 5605 v8::String::NewFromUtf8(isolate, "frame_count"))); | 5841 .ToLocalChecked(); |
| 5842 frame_count = v8::Local<v8::Function>::Cast( |
| 5843 context->Global() |
| 5844 ->Get(context, v8_str(isolate, "frame_count")) |
| 5845 .ToLocalChecked()); |
| 5606 | 5846 |
| 5607 // Compile a function for returning the source line for the top frame. | 5847 // Compile a function for returning the source line for the top frame. |
| 5608 v8::Script::Compile(v8::String::NewFromUtf8(isolate, | 5848 v8::Script::Compile(context, v8_str(isolate, frame_source_line_source)) |
| 5609 frame_source_line_source))->Run(); | 5849 .ToLocalChecked() |
| 5610 frame_source_line = v8::Local<v8::Function>::Cast(context->Global()->Get( | 5850 ->Run(context) |
| 5611 v8::String::NewFromUtf8(isolate, "frame_source_line"))); | 5851 .ToLocalChecked(); |
| 5852 frame_source_line = v8::Local<v8::Function>::Cast( |
| 5853 context->Global() |
| 5854 ->Get(context, v8_str(isolate, "frame_source_line")) |
| 5855 .ToLocalChecked()); |
| 5612 | 5856 |
| 5613 // Compile a function returning the data parameter. | 5857 // Compile a function returning the data parameter. |
| 5614 v8::Script::Compile(v8::String::NewFromUtf8(isolate, | 5858 v8::Script::Compile(context, v8_str(isolate, debugger_call_with_data_source)) |
| 5615 debugger_call_with_data_source)) | 5859 .ToLocalChecked() |
| 5616 ->Run(); | 5860 ->Run(context) |
| 5861 .ToLocalChecked(); |
| 5617 debugger_call_with_data = v8::Local<v8::Function>::Cast( | 5862 debugger_call_with_data = v8::Local<v8::Function>::Cast( |
| 5618 context->Global()->Get(v8::String::NewFromUtf8( | 5863 context->Global() |
| 5619 isolate, "debugger_call_with_data"))); | 5864 ->Get(context, v8_str(isolate, "debugger_call_with_data")) |
| 5865 .ToLocalChecked()); |
| 5620 | 5866 |
| 5621 // Compile a function capturing closure. | 5867 // Compile a function capturing closure. |
| 5622 debugger_call_with_closure = | 5868 debugger_call_with_closure = v8::Local<v8::Function>::Cast( |
| 5623 v8::Local<v8::Function>::Cast(v8::Script::Compile( | 5869 v8::Script::Compile(context, |
| 5624 v8::String::NewFromUtf8(isolate, | 5870 v8_str(isolate, debugger_call_with_closure_source)) |
| 5625 debugger_call_with_closure_source))->Run()); | 5871 .ToLocalChecked() |
| 5872 ->Run(context) |
| 5873 .ToLocalChecked()); |
| 5626 | 5874 |
| 5627 // Calling a function through the debugger returns 0 frames if there are | 5875 // Calling a function through the debugger returns 0 frames if there are |
| 5628 // no JavaScript frames. | 5876 // no JavaScript frames. |
| 5629 CHECK(v8::Integer::New(isolate, 0)->Equals(v8::Debug::Call(frame_count))); | 5877 CHECK(v8::Integer::New(isolate, 0) |
| 5878 ->Equals(context, |
| 5879 v8::Debug::Call(context, frame_count).ToLocalChecked()) |
| 5880 .FromJust()); |
| 5630 | 5881 |
| 5631 // Test that the number of frames can be retrieved. | 5882 // Test that the number of frames can be retrieved. |
| 5632 v8::Script::Compile( | 5883 v8::Script::Compile(context, v8_str(isolate, "CheckFrameCount(1)")) |
| 5633 v8::String::NewFromUtf8(isolate, "CheckFrameCount(1)"))->Run(); | 5884 .ToLocalChecked() |
| 5634 v8::Script::Compile(v8::String::NewFromUtf8(isolate, | 5885 ->Run(context) |
| 5635 "function f() {" | 5886 .ToLocalChecked(); |
| 5636 " CheckFrameCount(2);" | 5887 v8::Script::Compile(context, v8_str(isolate, |
| 5637 "}; f()"))->Run(); | 5888 "function f() {" |
| 5889 " CheckFrameCount(2);" |
| 5890 "}; f()")) |
| 5891 .ToLocalChecked() |
| 5892 ->Run(context) |
| 5893 .ToLocalChecked(); |
| 5638 | 5894 |
| 5639 // Test that the source line can be retrieved. | 5895 // Test that the source line can be retrieved. |
| 5640 v8::Script::Compile( | 5896 v8::Script::Compile(context, v8_str(isolate, "CheckSourceLine(0)")) |
| 5641 v8::String::NewFromUtf8(isolate, "CheckSourceLine(0)"))->Run(); | 5897 .ToLocalChecked() |
| 5642 v8::Script::Compile(v8::String::NewFromUtf8(isolate, | 5898 ->Run(context) |
| 5643 "function f() {\n" | 5899 .ToLocalChecked(); |
| 5644 " CheckSourceLine(1)\n" | 5900 v8::Script::Compile(context, v8_str(isolate, |
| 5645 " CheckSourceLine(2)\n" | 5901 "function f() {\n" |
| 5646 " CheckSourceLine(3)\n" | 5902 " CheckSourceLine(1)\n" |
| 5647 "}; f()"))->Run(); | 5903 " CheckSourceLine(2)\n" |
| 5904 " CheckSourceLine(3)\n" |
| 5905 "}; f()")) |
| 5906 .ToLocalChecked() |
| 5907 ->Run(context) |
| 5908 .ToLocalChecked(); |
| 5648 | 5909 |
| 5649 // Test that a parameter can be passed to a function called in the debugger. | 5910 // Test that a parameter can be passed to a function called in the debugger. |
| 5650 v8::Script::Compile(v8::String::NewFromUtf8(isolate, | 5911 v8::Script::Compile(context, v8_str(isolate, "CheckDataParameter()")) |
| 5651 "CheckDataParameter()"))->Run(); | 5912 .ToLocalChecked() |
| 5913 ->Run(context) |
| 5914 .ToLocalChecked(); |
| 5652 | 5915 |
| 5653 // Test that a function with closure can be run in the debugger. | 5916 // Test that a function with closure can be run in the debugger. |
| 5654 v8::Script::Compile( | 5917 v8::Script::Compile(context, v8_str(isolate, "CheckClosure()")) |
| 5655 v8::String::NewFromUtf8(isolate, "CheckClosure()"))->Run(); | 5918 .ToLocalChecked() |
| 5919 ->Run(context) |
| 5920 .ToLocalChecked(); |
| 5656 | 5921 |
| 5657 // Test that the source line is correct when there is a line offset. | 5922 // Test that the source line is correct when there is a line offset. |
| 5658 v8::ScriptOrigin origin(v8::String::NewFromUtf8(isolate, "test"), | 5923 v8::ScriptOrigin origin(v8_str(isolate, "test"), |
| 5659 v8::Integer::New(isolate, 7)); | 5924 v8::Integer::New(isolate, 7)); |
| 5660 v8::Script::Compile( | 5925 v8::Script::Compile(context, v8_str(isolate, "CheckSourceLine(7)"), &origin) |
| 5661 v8::String::NewFromUtf8(isolate, "CheckSourceLine(7)"), &origin) | 5926 .ToLocalChecked() |
| 5662 ->Run(); | 5927 ->Run(context) |
| 5663 v8::Script::Compile(v8::String::NewFromUtf8(isolate, | 5928 .ToLocalChecked(); |
| 5664 "function f() {\n" | 5929 v8::Script::Compile(context, v8_str(isolate, |
| 5665 " CheckSourceLine(8)\n" | 5930 "function f() {\n" |
| 5666 " CheckSourceLine(9)\n" | 5931 " CheckSourceLine(8)\n" |
| 5667 " CheckSourceLine(10)\n" | 5932 " CheckSourceLine(9)\n" |
| 5668 "}; f()"), | 5933 " CheckSourceLine(10)\n" |
| 5669 &origin)->Run(); | 5934 "}; f()"), |
| 5935 &origin) |
| 5936 .ToLocalChecked() |
| 5937 ->Run(context) |
| 5938 .ToLocalChecked(); |
| 5670 } | 5939 } |
| 5671 | 5940 |
| 5672 | 5941 |
| 5673 // Debugger message handler which counts the number of breaks. | 5942 // Debugger message handler which counts the number of breaks. |
| 5674 static void SendContinueCommand(); | 5943 static void SendContinueCommand(); |
| 5675 static void MessageHandlerBreakPointHitCount( | 5944 static void MessageHandlerBreakPointHitCount( |
| 5676 const v8::Debug::Message& message) { | 5945 const v8::Debug::Message& message) { |
| 5677 if (message.IsEvent() && message.GetEvent() == v8::Break) { | 5946 if (message.IsEvent() && message.GetEvent() == v8::Break) { |
| 5678 // Count the number of breaks. | 5947 // Count the number of breaks. |
| 5679 break_point_hit_count++; | 5948 break_point_hit_count++; |
| 5680 | 5949 |
| 5681 SendContinueCommand(); | 5950 SendContinueCommand(); |
| 5682 } | 5951 } |
| 5683 } | 5952 } |
| 5684 | 5953 |
| 5685 | 5954 |
| 5686 // Test that clearing the debug event listener actually clears all break points | 5955 // Test that clearing the debug event listener actually clears all break points |
| 5687 // and related information. | 5956 // and related information. |
| 5688 TEST(DebuggerUnload) { | 5957 TEST(DebuggerUnload) { |
| 5689 DebugLocalContext env; | 5958 DebugLocalContext env; |
| 5690 | 5959 |
| 5691 // Check debugger is unloaded before it is used. | 5960 // Check debugger is unloaded before it is used. |
| 5692 CheckDebuggerUnloaded(); | 5961 CheckDebuggerUnloaded(); |
| 5693 | 5962 |
| 5694 // Set a debug event listener. | 5963 // Set a debug event listener. |
| 5695 break_point_hit_count = 0; | 5964 break_point_hit_count = 0; |
| 5696 v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); | 5965 v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); |
| 5966 v8::Local<v8::Context> context = env.context(); |
| 5697 { | 5967 { |
| 5698 v8::HandleScope scope(env->GetIsolate()); | 5968 v8::HandleScope scope(env->GetIsolate()); |
| 5699 // Create a couple of functions for the test. | 5969 // Create a couple of functions for the test. |
| 5700 v8::Local<v8::Function> foo = | 5970 v8::Local<v8::Function> foo = |
| 5701 CompileFunction(&env, "function foo(){x=1}", "foo"); | 5971 CompileFunction(&env, "function foo(){x=1}", "foo"); |
| 5702 v8::Local<v8::Function> bar = | 5972 v8::Local<v8::Function> bar = |
| 5703 CompileFunction(&env, "function bar(){y=2}", "bar"); | 5973 CompileFunction(&env, "function bar(){y=2}", "bar"); |
| 5704 | 5974 |
| 5705 // Set some break points. | 5975 // Set some break points. |
| 5706 SetBreakPoint(foo, 0); | 5976 SetBreakPoint(foo, 0); |
| 5707 SetBreakPoint(foo, 4); | 5977 SetBreakPoint(foo, 4); |
| 5708 SetBreakPoint(bar, 0); | 5978 SetBreakPoint(bar, 0); |
| 5709 SetBreakPoint(bar, 4); | 5979 SetBreakPoint(bar, 4); |
| 5710 | 5980 |
| 5711 // Make sure that the break points are there. | 5981 // Make sure that the break points are there. |
| 5712 break_point_hit_count = 0; | 5982 break_point_hit_count = 0; |
| 5713 foo->Call(env->Global(), 0, NULL); | 5983 foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 5714 CHECK_EQ(2, break_point_hit_count); | 5984 CHECK_EQ(2, break_point_hit_count); |
| 5715 bar->Call(env->Global(), 0, NULL); | 5985 bar->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 5716 CHECK_EQ(4, break_point_hit_count); | 5986 CHECK_EQ(4, break_point_hit_count); |
| 5717 } | 5987 } |
| 5718 | 5988 |
| 5719 // Remove the debug event listener without clearing breakpoints. Do this | 5989 // Remove the debug event listener without clearing breakpoints. Do this |
| 5720 // outside a handle scope. | 5990 // outside a handle scope. |
| 5721 v8::Debug::SetDebugEventListener(NULL); | 5991 v8::Debug::SetDebugEventListener(NULL); |
| 5722 CheckDebuggerUnloaded(true); | 5992 CheckDebuggerUnloaded(true); |
| 5723 | 5993 |
| 5724 // Now set a debug message handler. | 5994 // Now set a debug message handler. |
| 5725 break_point_hit_count = 0; | 5995 break_point_hit_count = 0; |
| 5726 v8::Debug::SetMessageHandler(MessageHandlerBreakPointHitCount); | 5996 v8::Debug::SetMessageHandler(MessageHandlerBreakPointHitCount); |
| 5727 { | 5997 { |
| 5728 v8::HandleScope scope(env->GetIsolate()); | 5998 v8::HandleScope scope(env->GetIsolate()); |
| 5729 | 5999 |
| 5730 // Get the test functions again. | 6000 // Get the test functions again. |
| 5731 v8::Local<v8::Function> foo(v8::Local<v8::Function>::Cast( | 6001 v8::Local<v8::Function> foo(v8::Local<v8::Function>::Cast( |
| 5732 env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "foo")))); | 6002 env->Global() |
| 6003 ->Get(context, v8_str(env->GetIsolate(), "foo")) |
| 6004 .ToLocalChecked())); |
| 5733 | 6005 |
| 5734 foo->Call(env->Global(), 0, NULL); | 6006 foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 5735 CHECK_EQ(0, break_point_hit_count); | 6007 CHECK_EQ(0, break_point_hit_count); |
| 5736 | 6008 |
| 5737 // Set break points and run again. | 6009 // Set break points and run again. |
| 5738 SetBreakPoint(foo, 0); | 6010 SetBreakPoint(foo, 0); |
| 5739 SetBreakPoint(foo, 4); | 6011 SetBreakPoint(foo, 4); |
| 5740 foo->Call(env->Global(), 0, NULL); | 6012 foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 5741 CHECK_EQ(2, break_point_hit_count); | 6013 CHECK_EQ(2, break_point_hit_count); |
| 5742 } | 6014 } |
| 5743 | 6015 |
| 5744 // Remove the debug message handler without clearing breakpoints. Do this | 6016 // Remove the debug message handler without clearing breakpoints. Do this |
| 5745 // outside a handle scope. | 6017 // outside a handle scope. |
| 5746 v8::Debug::SetMessageHandler(NULL); | 6018 v8::Debug::SetMessageHandler(NULL); |
| 5747 CheckDebuggerUnloaded(true); | 6019 CheckDebuggerUnloaded(true); |
| 5748 } | 6020 } |
| 5749 | 6021 |
| 5750 | 6022 |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5854 private: | 6126 private: |
| 5855 ::v8::internal::EmbeddedVector<uint16_t, 1> empty_; | 6127 ::v8::internal::EmbeddedVector<uint16_t, 1> empty_; |
| 5856 }; | 6128 }; |
| 5857 | 6129 |
| 5858 | 6130 |
| 5859 TEST(DebugGetLoadedScripts) { | 6131 TEST(DebugGetLoadedScripts) { |
| 5860 DebugLocalContext env; | 6132 DebugLocalContext env; |
| 5861 v8::HandleScope scope(env->GetIsolate()); | 6133 v8::HandleScope scope(env->GetIsolate()); |
| 5862 env.ExposeDebug(); | 6134 env.ExposeDebug(); |
| 5863 | 6135 |
| 6136 v8::Local<v8::Context> context = env.context(); |
| 5864 EmptyExternalStringResource source_ext_str; | 6137 EmptyExternalStringResource source_ext_str; |
| 5865 v8::Local<v8::String> source = | 6138 v8::Local<v8::String> source = |
| 5866 v8::String::NewExternal(env->GetIsolate(), &source_ext_str); | 6139 v8::String::NewExternalTwoByte(env->GetIsolate(), &source_ext_str) |
| 5867 v8::Handle<v8::Script> evil_script(v8::Script::Compile(source)); | 6140 .ToLocalChecked(); |
| 5868 // "use" evil_script to make the compiler happy. | 6141 CHECK(v8::Script::Compile(context, source).IsEmpty()); |
| 5869 USE(evil_script); | |
| 5870 Handle<i::ExternalTwoByteString> i_source( | 6142 Handle<i::ExternalTwoByteString> i_source( |
| 5871 i::ExternalTwoByteString::cast(*v8::Utils::OpenHandle(*source))); | 6143 i::ExternalTwoByteString::cast(*v8::Utils::OpenHandle(*source))); |
| 5872 // This situation can happen if source was an external string disposed | 6144 // This situation can happen if source was an external string disposed |
| 5873 // by its owner. | 6145 // by its owner. |
| 5874 i_source->set_resource(0); | 6146 i_source->set_resource(0); |
| 5875 | 6147 |
| 5876 bool allow_natives_syntax = i::FLAG_allow_natives_syntax; | 6148 bool allow_natives_syntax = i::FLAG_allow_natives_syntax; |
| 5877 i::FLAG_allow_natives_syntax = true; | 6149 i::FLAG_allow_natives_syntax = true; |
| 5878 EnableDebugger(); | 6150 EnableDebugger(); |
| 5879 v8::MaybeLocal<v8::Value> result = | 6151 v8::MaybeLocal<v8::Value> result = |
| 5880 CompileRun(env.context(), | 6152 CompileRun(env.context(), |
| 5881 "var scripts = %DebugGetLoadedScripts();" | 6153 "var scripts = %DebugGetLoadedScripts();" |
| 5882 "var count = scripts.length;" | 6154 "var count = scripts.length;" |
| 5883 "for (var i = 0; i < count; ++i) {" | 6155 "for (var i = 0; i < count; ++i) {" |
| 5884 " var lines = scripts[i].lineCount();" | 6156 " var lines = scripts[i].lineCount();" |
| 5885 " if (lines < 1) throw 'lineCount';" | 6157 " if (lines < 1) throw 'lineCount';" |
| 5886 " var last = -1;" | 6158 " var last = -1;" |
| 5887 " for (var j = 0; j < lines; ++j) {" | 6159 " for (var j = 0; j < lines; ++j) {" |
| 5888 " var end = scripts[i].lineEnd(j);" | 6160 " var end = scripts[i].lineEnd(j);" |
| 5889 " if (last >= end) throw 'lineEnd';" | 6161 " if (last >= end) throw 'lineEnd';" |
| 5890 " last = end;" | 6162 " last = end;" |
| 5891 " }" | 6163 " }" |
| 5892 "}"); | 6164 "}"); |
| 5893 CHECK(!result.IsEmpty()); | 6165 CHECK(!result.IsEmpty()); |
| 5894 DisableDebugger(); | 6166 DisableDebugger(); |
| 5895 // Must not crash while accessing line_ends. | 6167 // Must not crash while accessing line_ends. |
| 5896 i::FLAG_allow_natives_syntax = allow_natives_syntax; | 6168 i::FLAG_allow_natives_syntax = allow_natives_syntax; |
| 5897 | 6169 |
| 5898 // Some scripts are retrieved - at least the number of native scripts. | 6170 // Some scripts are retrieved - at least the number of native scripts. |
| 5899 CHECK_GT((*env) | 6171 CHECK_GT(env->Global() |
| 5900 ->Global() | 6172 ->Get(context, v8_str(env->GetIsolate(), "count")) |
| 5901 ->Get(v8::String::NewFromUtf8(env->GetIsolate(), "count")) | 6173 .ToLocalChecked() |
| 5902 ->Int32Value(), | 6174 ->Int32Value(context) |
| 6175 .FromJust(), |
| 5903 8); | 6176 8); |
| 5904 } | 6177 } |
| 5905 | 6178 |
| 5906 | 6179 |
| 5907 // Test script break points set on lines. | 6180 // Test script break points set on lines. |
| 5908 TEST(ScriptNameAndData) { | 6181 TEST(ScriptNameAndData) { |
| 5909 DebugLocalContext env; | 6182 DebugLocalContext env; |
| 5910 v8::HandleScope scope(env->GetIsolate()); | 6183 v8::HandleScope scope(env->GetIsolate()); |
| 5911 env.ExposeDebug(); | 6184 env.ExposeDebug(); |
| 5912 | 6185 |
| 5913 // Create functions for retrieving script name and data for the function on | 6186 // Create functions for retrieving script name and data for the function on |
| 5914 // the top frame when hitting a break point. | 6187 // the top frame when hitting a break point. |
| 5915 frame_script_name = CompileFunction(&env, | 6188 frame_script_name = CompileFunction(&env, |
| 5916 frame_script_name_source, | 6189 frame_script_name_source, |
| 5917 "frame_script_name"); | 6190 "frame_script_name"); |
| 5918 | 6191 |
| 5919 v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); | 6192 v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); |
| 5920 | 6193 |
| 6194 v8::Local<v8::Context> context = env.context(); |
| 5921 // Test function source. | 6195 // Test function source. |
| 5922 v8::Local<v8::String> script = v8::String::NewFromUtf8(env->GetIsolate(), | 6196 v8::Local<v8::String> script = v8_str(env->GetIsolate(), |
| 5923 "function f() {\n" | 6197 "function f() {\n" |
| 5924 " debugger;\n" | 6198 " debugger;\n" |
| 5925 "}\n"); | 6199 "}\n"); |
| 5926 | 6200 |
| 5927 v8::ScriptOrigin origin1 = | 6201 v8::ScriptOrigin origin1 = |
| 5928 v8::ScriptOrigin(v8::String::NewFromUtf8(env->GetIsolate(), "name")); | 6202 v8::ScriptOrigin(v8_str(env->GetIsolate(), "name")); |
| 5929 v8::Handle<v8::Script> script1 = v8::Script::Compile(script, &origin1); | 6203 v8::Local<v8::Script> script1 = |
| 5930 script1->Run(); | 6204 v8::Script::Compile(context, script, &origin1).ToLocalChecked(); |
| 6205 script1->Run(context).ToLocalChecked(); |
| 5931 v8::Local<v8::Function> f; | 6206 v8::Local<v8::Function> f; |
| 5932 f = v8::Local<v8::Function>::Cast( | 6207 f = v8::Local<v8::Function>::Cast( |
| 5933 env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); | 6208 env->Global() |
| 6209 ->Get(context, v8_str(env->GetIsolate(), "f")) |
| 6210 .ToLocalChecked()); |
| 5934 | 6211 |
| 5935 f->Call(env->Global(), 0, NULL); | 6212 f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 5936 CHECK_EQ(1, break_point_hit_count); | 6213 CHECK_EQ(1, break_point_hit_count); |
| 5937 CHECK_EQ(0, strcmp("name", last_script_name_hit)); | 6214 CHECK_EQ(0, strcmp("name", last_script_name_hit)); |
| 5938 | 6215 |
| 5939 // Compile the same script again without setting data. As the compilation | 6216 // Compile the same script again without setting data. As the compilation |
| 5940 // cache is disabled when debugging expect the data to be missing. | 6217 // cache is disabled when debugging expect the data to be missing. |
| 5941 v8::Script::Compile(script, &origin1)->Run(); | 6218 v8::Script::Compile(context, script, &origin1) |
| 6219 .ToLocalChecked() |
| 6220 ->Run(context) |
| 6221 .ToLocalChecked(); |
| 5942 f = v8::Local<v8::Function>::Cast( | 6222 f = v8::Local<v8::Function>::Cast( |
| 5943 env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); | 6223 env->Global() |
| 5944 f->Call(env->Global(), 0, NULL); | 6224 ->Get(context, v8_str(env->GetIsolate(), "f")) |
| 6225 .ToLocalChecked()); |
| 6226 f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 5945 CHECK_EQ(2, break_point_hit_count); | 6227 CHECK_EQ(2, break_point_hit_count); |
| 5946 CHECK_EQ(0, strcmp("name", last_script_name_hit)); | 6228 CHECK_EQ(0, strcmp("name", last_script_name_hit)); |
| 5947 | 6229 |
| 5948 v8::Local<v8::String> data_obj_source = v8::String::NewFromUtf8( | 6230 v8::Local<v8::String> data_obj_source = |
| 5949 env->GetIsolate(), | 6231 v8_str(env->GetIsolate(), |
| 5950 "({ a: 'abc',\n" | 6232 "({ a: 'abc',\n" |
| 5951 " b: 123,\n" | 6233 " b: 123,\n" |
| 5952 " toString: function() { return this.a + ' ' + this.b; }\n" | 6234 " toString: function() { return this.a + ' ' + this.b; }\n" |
| 5953 "})\n"); | 6235 "})\n"); |
| 5954 v8::Script::Compile(data_obj_source)->Run(); | 6236 v8::Script::Compile(context, data_obj_source) |
| 6237 .ToLocalChecked() |
| 6238 ->Run(context) |
| 6239 .ToLocalChecked(); |
| 5955 v8::ScriptOrigin origin2 = | 6240 v8::ScriptOrigin origin2 = |
| 5956 v8::ScriptOrigin(v8::String::NewFromUtf8(env->GetIsolate(), "new name")); | 6241 v8::ScriptOrigin(v8_str(env->GetIsolate(), "new name")); |
| 5957 v8::Handle<v8::Script> script2 = v8::Script::Compile(script, &origin2); | 6242 v8::Local<v8::Script> script2 = |
| 5958 script2->Run(); | 6243 v8::Script::Compile(context, script, &origin2).ToLocalChecked(); |
| 6244 script2->Run(context).ToLocalChecked(); |
| 5959 f = v8::Local<v8::Function>::Cast( | 6245 f = v8::Local<v8::Function>::Cast( |
| 5960 env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); | 6246 env->Global() |
| 5961 f->Call(env->Global(), 0, NULL); | 6247 ->Get(context, v8_str(env->GetIsolate(), "f")) |
| 6248 .ToLocalChecked()); |
| 6249 f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 5962 CHECK_EQ(3, break_point_hit_count); | 6250 CHECK_EQ(3, break_point_hit_count); |
| 5963 CHECK_EQ(0, strcmp("new name", last_script_name_hit)); | 6251 CHECK_EQ(0, strcmp("new name", last_script_name_hit)); |
| 5964 | 6252 |
| 5965 v8::Handle<v8::Script> script3 = v8::Script::Compile(script, &origin2); | 6253 v8::Local<v8::Script> script3 = |
| 5966 script3->Run(); | 6254 v8::Script::Compile(context, script, &origin2).ToLocalChecked(); |
| 6255 script3->Run(context).ToLocalChecked(); |
| 5967 f = v8::Local<v8::Function>::Cast( | 6256 f = v8::Local<v8::Function>::Cast( |
| 5968 env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); | 6257 env->Global() |
| 5969 f->Call(env->Global(), 0, NULL); | 6258 ->Get(context, v8_str(env->GetIsolate(), "f")) |
| 6259 .ToLocalChecked()); |
| 6260 f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 5970 CHECK_EQ(4, break_point_hit_count); | 6261 CHECK_EQ(4, break_point_hit_count); |
| 5971 } | 6262 } |
| 5972 | 6263 |
| 5973 | 6264 |
| 5974 static v8::Handle<v8::Context> expected_context; | 6265 static v8::Local<v8::Context> expected_context; |
| 5975 static v8::Handle<v8::Value> expected_context_data; | 6266 static v8::Local<v8::Value> expected_context_data; |
| 5976 | 6267 |
| 5977 | 6268 |
| 5978 // Check that the expected context is the one generating the debug event. | 6269 // Check that the expected context is the one generating the debug event. |
| 5979 static void ContextCheckMessageHandler(const v8::Debug::Message& message) { | 6270 static void ContextCheckMessageHandler(const v8::Debug::Message& message) { |
| 5980 CHECK(message.GetEventContext() == expected_context); | 6271 CHECK(message.GetEventContext() == expected_context); |
| 5981 CHECK(message.GetEventContext()->GetEmbedderData(0)->StrictEquals( | 6272 CHECK(message.GetEventContext()->GetEmbedderData(0)->StrictEquals( |
| 5982 expected_context_data)); | 6273 expected_context_data)); |
| 5983 message_handler_hit_count++; | 6274 message_handler_hit_count++; |
| 5984 | 6275 |
| 5985 static char print_buffer[1000]; | 6276 static char print_buffer[1000]; |
| 5986 v8::String::Value json(message.GetJSON()); | 6277 v8::String::Value json(message.GetJSON()); |
| 5987 Utf16ToAscii(*json, json.length(), print_buffer); | 6278 Utf16ToAscii(*json, json.length(), print_buffer); |
| 5988 | 6279 |
| 5989 // Send a continue command for break events. | 6280 // Send a continue command for break events. |
| 5990 if (IsBreakEventMessage(print_buffer)) { | 6281 if (IsBreakEventMessage(print_buffer)) { |
| 5991 SendContinueCommand(); | 6282 SendContinueCommand(); |
| 5992 } | 6283 } |
| 5993 } | 6284 } |
| 5994 | 6285 |
| 5995 | 6286 |
| 5996 // Test which creates two contexts and sets different embedder data on each. | 6287 // Test which creates two contexts and sets different embedder data on each. |
| 5997 // Checks that this data is set correctly and that when the debug message | 6288 // Checks that this data is set correctly and that when the debug message |
| 5998 // handler is called the expected context is the one active. | 6289 // handler is called the expected context is the one active. |
| 5999 TEST(ContextData) { | 6290 TEST(ContextData) { |
| 6000 v8::Isolate* isolate = CcTest::isolate(); | 6291 v8::Isolate* isolate = CcTest::isolate(); |
| 6001 v8::HandleScope scope(isolate); | 6292 v8::HandleScope scope(isolate); |
| 6002 | 6293 |
| 6003 // Create two contexts. | 6294 // Create two contexts. |
| 6004 v8::Handle<v8::Context> context_1; | 6295 v8::Local<v8::Context> context_1; |
| 6005 v8::Handle<v8::Context> context_2; | 6296 v8::Local<v8::Context> context_2; |
| 6006 v8::Handle<v8::ObjectTemplate> global_template = | 6297 v8::Local<v8::ObjectTemplate> global_template = |
| 6007 v8::Handle<v8::ObjectTemplate>(); | 6298 v8::Local<v8::ObjectTemplate>(); |
| 6008 v8::Handle<v8::Value> global_object = v8::Handle<v8::Value>(); | 6299 v8::Local<v8::Value> global_object = v8::Local<v8::Value>(); |
| 6009 context_1 = v8::Context::New(isolate, NULL, global_template, global_object); | 6300 context_1 = v8::Context::New(isolate, NULL, global_template, global_object); |
| 6010 context_2 = v8::Context::New(isolate, NULL, global_template, global_object); | 6301 context_2 = v8::Context::New(isolate, NULL, global_template, global_object); |
| 6011 | 6302 |
| 6012 v8::Debug::SetMessageHandler(ContextCheckMessageHandler); | 6303 v8::Debug::SetMessageHandler(ContextCheckMessageHandler); |
| 6013 | 6304 |
| 6014 // Default data value is undefined. | 6305 // Default data value is undefined. |
| 6015 CHECK(context_1->GetEmbedderData(0)->IsUndefined()); | 6306 CHECK(context_1->GetEmbedderData(0)->IsUndefined()); |
| 6016 CHECK(context_2->GetEmbedderData(0)->IsUndefined()); | 6307 CHECK(context_2->GetEmbedderData(0)->IsUndefined()); |
| 6017 | 6308 |
| 6018 // Set and check different data values. | 6309 // Set and check different data values. |
| 6019 v8::Handle<v8::String> data_1 = v8::String::NewFromUtf8(isolate, "1"); | 6310 v8::Local<v8::String> data_1 = v8_str(isolate, "1"); |
| 6020 v8::Handle<v8::String> data_2 = v8::String::NewFromUtf8(isolate, "2"); | 6311 v8::Local<v8::String> data_2 = v8_str(isolate, "2"); |
| 6021 context_1->SetEmbedderData(0, data_1); | 6312 context_1->SetEmbedderData(0, data_1); |
| 6022 context_2->SetEmbedderData(0, data_2); | 6313 context_2->SetEmbedderData(0, data_2); |
| 6023 CHECK(context_1->GetEmbedderData(0)->StrictEquals(data_1)); | 6314 CHECK(context_1->GetEmbedderData(0)->StrictEquals(data_1)); |
| 6024 CHECK(context_2->GetEmbedderData(0)->StrictEquals(data_2)); | 6315 CHECK(context_2->GetEmbedderData(0)->StrictEquals(data_2)); |
| 6025 | 6316 |
| 6026 // Simple test function which causes a break. | 6317 // Simple test function which causes a break. |
| 6027 const char* source = "function f() { debugger; }"; | 6318 const char* source = "function f() { debugger; }"; |
| 6028 | 6319 |
| 6029 // Enter and run function in the first context. | 6320 // Enter and run function in the first context. |
| 6030 { | 6321 { |
| 6031 v8::Context::Scope context_scope(context_1); | 6322 v8::Context::Scope context_scope(context_1); |
| 6032 expected_context = context_1; | 6323 expected_context = context_1; |
| 6033 expected_context_data = data_1; | 6324 expected_context_data = data_1; |
| 6034 v8::Local<v8::Function> f = CompileFunction(isolate, source, "f"); | 6325 v8::Local<v8::Function> f = CompileFunction(isolate, source, "f"); |
| 6035 f->Call(context_1->Global(), 0, NULL); | 6326 f->Call(context_1, context_1->Global(), 0, NULL).ToLocalChecked(); |
| 6036 } | 6327 } |
| 6037 | 6328 |
| 6038 | 6329 |
| 6039 // Enter and run function in the second context. | 6330 // Enter and run function in the second context. |
| 6040 { | 6331 { |
| 6041 v8::Context::Scope context_scope(context_2); | 6332 v8::Context::Scope context_scope(context_2); |
| 6042 expected_context = context_2; | 6333 expected_context = context_2; |
| 6043 expected_context_data = data_2; | 6334 expected_context_data = data_2; |
| 6044 v8::Local<v8::Function> f = CompileFunction(isolate, source, "f"); | 6335 v8::Local<v8::Function> f = CompileFunction(isolate, source, "f"); |
| 6045 f->Call(context_2->Global(), 0, NULL); | 6336 f->Call(context_2, context_2->Global(), 0, NULL).ToLocalChecked(); |
| 6046 } | 6337 } |
| 6047 | 6338 |
| 6048 // Two times compile event and two times break event. | 6339 // Two times compile event and two times break event. |
| 6049 CHECK_GT(message_handler_hit_count, 4); | 6340 CHECK_GT(message_handler_hit_count, 4); |
| 6050 | 6341 |
| 6051 v8::Debug::SetMessageHandler(NULL); | 6342 v8::Debug::SetMessageHandler(NULL); |
| 6052 CheckDebuggerUnloaded(); | 6343 CheckDebuggerUnloaded(); |
| 6053 } | 6344 } |
| 6054 | 6345 |
| 6055 | 6346 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 6073 | 6364 |
| 6074 | 6365 |
| 6075 // Test that a debug break can be scheduled while in a message handler. | 6366 // Test that a debug break can be scheduled while in a message handler. |
| 6076 TEST(DebugBreakInMessageHandler) { | 6367 TEST(DebugBreakInMessageHandler) { |
| 6077 i::FLAG_turbo_inlining = false; // Make sure g is not inlined into f. | 6368 i::FLAG_turbo_inlining = false; // Make sure g is not inlined into f. |
| 6078 DebugLocalContext env; | 6369 DebugLocalContext env; |
| 6079 v8::HandleScope scope(env->GetIsolate()); | 6370 v8::HandleScope scope(env->GetIsolate()); |
| 6080 | 6371 |
| 6081 v8::Debug::SetMessageHandler(DebugBreakMessageHandler); | 6372 v8::Debug::SetMessageHandler(DebugBreakMessageHandler); |
| 6082 | 6373 |
| 6374 v8::Local<v8::Context> context = env.context(); |
| 6083 // Test functions. | 6375 // Test functions. |
| 6084 const char* script = "function f() { debugger; g(); } function g() { }"; | 6376 const char* script = "function f() { debugger; g(); } function g() { }"; |
| 6085 CompileRun(script); | 6377 CompileRun(script); |
| 6086 v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( | 6378 v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( |
| 6087 env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); | 6379 env->Global() |
| 6380 ->Get(context, v8_str(env->GetIsolate(), "f")) |
| 6381 .ToLocalChecked()); |
| 6088 v8::Local<v8::Function> g = v8::Local<v8::Function>::Cast( | 6382 v8::Local<v8::Function> g = v8::Local<v8::Function>::Cast( |
| 6089 env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "g"))); | 6383 env->Global() |
| 6384 ->Get(context, v8_str(env->GetIsolate(), "g")) |
| 6385 .ToLocalChecked()); |
| 6090 | 6386 |
| 6091 // Call f then g. The debugger statement in f will cause a break which will | 6387 // Call f then g. The debugger statement in f will cause a break which will |
| 6092 // cause another break. | 6388 // cause another break. |
| 6093 f->Call(env->Global(), 0, NULL); | 6389 f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 6094 CHECK_EQ(2, message_handler_break_hit_count); | 6390 CHECK_EQ(2, message_handler_break_hit_count); |
| 6095 // Calling g will not cause any additional breaks. | 6391 // Calling g will not cause any additional breaks. |
| 6096 g->Call(env->Global(), 0, NULL); | 6392 g->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 6097 CHECK_EQ(2, message_handler_break_hit_count); | 6393 CHECK_EQ(2, message_handler_break_hit_count); |
| 6098 } | 6394 } |
| 6099 | 6395 |
| 6100 | 6396 |
| 6101 #ifndef V8_INTERPRETED_REGEXP | 6397 #ifndef V8_INTERPRETED_REGEXP |
| 6102 // Debug event handler which gets the function on the top frame and schedules a | 6398 // Debug event handler which gets the function on the top frame and schedules a |
| 6103 // break a number of times. | 6399 // break a number of times. |
| 6104 static void DebugEventDebugBreak( | 6400 static void DebugEventDebugBreak( |
| 6105 const v8::Debug::EventDetails& event_details) { | 6401 const v8::Debug::EventDetails& event_details) { |
| 6106 v8::DebugEvent event = event_details.GetEvent(); | 6402 v8::DebugEvent event = event_details.GetEvent(); |
| 6107 v8::Handle<v8::Object> exec_state = event_details.GetExecutionState(); | 6403 v8::Local<v8::Object> exec_state = event_details.GetExecutionState(); |
| 6108 | 6404 v8::Local<v8::Context> context = CcTest::isolate()->GetCurrentContext(); |
| 6109 if (event == v8::Break) { | 6405 if (event == v8::Break) { |
| 6110 break_point_hit_count++; | 6406 break_point_hit_count++; |
| 6111 | 6407 |
| 6112 // Get the name of the top frame function. | 6408 // Get the name of the top frame function. |
| 6113 if (!frame_function_name.IsEmpty()) { | 6409 if (!frame_function_name.IsEmpty()) { |
| 6114 // Get the name of the function. | 6410 // Get the name of the function. |
| 6115 const int argc = 2; | 6411 const int argc = 2; |
| 6116 v8::Handle<v8::Value> argv[argc] = { | 6412 v8::Local<v8::Value> argv[argc] = { |
| 6117 exec_state, v8::Integer::New(CcTest::isolate(), 0) | 6413 exec_state, v8::Integer::New(CcTest::isolate(), 0)}; |
| 6118 }; | 6414 v8::Local<v8::Value> result = |
| 6119 v8::Handle<v8::Value> result = frame_function_name->Call(exec_state, | 6415 frame_function_name->Call(context, exec_state, argc, argv) |
| 6120 argc, argv); | 6416 .ToLocalChecked(); |
| 6121 if (result->IsUndefined()) { | 6417 if (result->IsUndefined()) { |
| 6122 last_function_hit[0] = '\0'; | 6418 last_function_hit[0] = '\0'; |
| 6123 } else { | 6419 } else { |
| 6124 CHECK(result->IsString()); | 6420 CHECK(result->IsString()); |
| 6125 v8::Handle<v8::String> function_name( | 6421 v8::Local<v8::String> function_name( |
| 6126 result->ToString(CcTest::isolate())); | 6422 result->ToString(context).ToLocalChecked()); |
| 6127 function_name->WriteUtf8(last_function_hit); | 6423 function_name->WriteUtf8(last_function_hit); |
| 6128 } | 6424 } |
| 6129 } | 6425 } |
| 6130 | 6426 |
| 6131 // Keep forcing breaks. | 6427 // Keep forcing breaks. |
| 6132 if (break_point_hit_count < 20) { | 6428 if (break_point_hit_count < 20) { |
| 6133 v8::Debug::DebugBreak(CcTest::isolate()); | 6429 v8::Debug::DebugBreak(CcTest::isolate()); |
| 6134 } | 6430 } |
| 6135 } | 6431 } |
| 6136 } | 6432 } |
| 6137 | 6433 |
| 6138 | 6434 |
| 6139 TEST(RegExpDebugBreak) { | 6435 TEST(RegExpDebugBreak) { |
| 6140 // This test only applies to native regexps. | 6436 // This test only applies to native regexps. |
| 6141 DebugLocalContext env; | 6437 DebugLocalContext env; |
| 6142 v8::HandleScope scope(env->GetIsolate()); | 6438 v8::HandleScope scope(env->GetIsolate()); |
| 6143 | 6439 v8::Local<v8::Context> context = env.context(); |
| 6144 // Create a function for checking the function when hitting a break point. | 6440 // Create a function for checking the function when hitting a break point. |
| 6145 frame_function_name = CompileFunction(&env, | 6441 frame_function_name = CompileFunction(&env, |
| 6146 frame_function_name_source, | 6442 frame_function_name_source, |
| 6147 "frame_function_name"); | 6443 "frame_function_name"); |
| 6148 | 6444 |
| 6149 // Test RegExp which matches white spaces and comments at the begining of a | 6445 // Test RegExp which matches white spaces and comments at the begining of a |
| 6150 // source line. | 6446 // source line. |
| 6151 const char* script = | 6447 const char* script = |
| 6152 "var sourceLineBeginningSkip = /^(?:[ \\v\\h]*(?:\\/\\*.*?\\*\\/)*)*/;\n" | 6448 "var sourceLineBeginningSkip = /^(?:[ \\v\\h]*(?:\\/\\*.*?\\*\\/)*)*/;\n" |
| 6153 "function f(s) { return s.match(sourceLineBeginningSkip)[0].length; }"; | 6449 "function f(s) { return s.match(sourceLineBeginningSkip)[0].length; }"; |
| 6154 | 6450 |
| 6155 v8::Local<v8::Function> f = CompileFunction(env->GetIsolate(), script, "f"); | 6451 v8::Local<v8::Function> f = CompileFunction(env->GetIsolate(), script, "f"); |
| 6156 const int argc = 1; | 6452 const int argc = 1; |
| 6157 v8::Handle<v8::Value> argv[argc] = { | 6453 v8::Local<v8::Value> argv[argc] = { |
| 6158 v8::String::NewFromUtf8(env->GetIsolate(), " /* xxx */ a=0;")}; | 6454 v8_str(env->GetIsolate(), " /* xxx */ a=0;")}; |
| 6159 v8::Local<v8::Value> result = f->Call(env->Global(), argc, argv); | 6455 v8::Local<v8::Value> result = |
| 6160 CHECK_EQ(12, result->Int32Value()); | 6456 f->Call(context, env->Global(), argc, argv).ToLocalChecked(); |
| 6457 CHECK_EQ(12, result->Int32Value(context).FromJust()); |
| 6161 | 6458 |
| 6162 v8::Debug::SetDebugEventListener(DebugEventDebugBreak); | 6459 v8::Debug::SetDebugEventListener(DebugEventDebugBreak); |
| 6163 v8::Debug::DebugBreak(env->GetIsolate()); | 6460 v8::Debug::DebugBreak(env->GetIsolate()); |
| 6164 result = f->Call(env->Global(), argc, argv); | 6461 result = f->Call(context, env->Global(), argc, argv).ToLocalChecked(); |
| 6165 | 6462 |
| 6166 // Check that there was only one break event. Matching RegExp should not | 6463 // Check that there was only one break event. Matching RegExp should not |
| 6167 // cause Break events. | 6464 // cause Break events. |
| 6168 CHECK_EQ(1, break_point_hit_count); | 6465 CHECK_EQ(1, break_point_hit_count); |
| 6169 CHECK_EQ(0, strcmp("f", last_function_hit)); | 6466 CHECK_EQ(0, strcmp("f", last_function_hit)); |
| 6170 } | 6467 } |
| 6171 #endif // V8_INTERPRETED_REGEXP | 6468 #endif // V8_INTERPRETED_REGEXP |
| 6172 | 6469 |
| 6173 | 6470 |
| 6174 // Common part of EvalContextData and NestedBreakEventContextData tests. | 6471 // Common part of EvalContextData and NestedBreakEventContextData tests. |
| 6175 static void ExecuteScriptForContextCheck( | 6472 static void ExecuteScriptForContextCheck( |
| 6176 v8::Debug::MessageHandler message_handler) { | 6473 v8::Debug::MessageHandler message_handler) { |
| 6177 // Create a context. | 6474 // Create a context. |
| 6178 v8::Handle<v8::Context> context_1; | 6475 v8::Local<v8::Context> context_1; |
| 6179 v8::Handle<v8::ObjectTemplate> global_template = | 6476 v8::Local<v8::ObjectTemplate> global_template = |
| 6180 v8::Handle<v8::ObjectTemplate>(); | 6477 v8::Local<v8::ObjectTemplate>(); |
| 6181 context_1 = | 6478 context_1 = |
| 6182 v8::Context::New(CcTest::isolate(), NULL, global_template); | 6479 v8::Context::New(CcTest::isolate(), NULL, global_template); |
| 6183 | 6480 |
| 6184 v8::Debug::SetMessageHandler(message_handler); | 6481 v8::Debug::SetMessageHandler(message_handler); |
| 6185 | 6482 |
| 6186 // Default data value is undefined. | 6483 // Default data value is undefined. |
| 6187 CHECK(context_1->GetEmbedderData(0)->IsUndefined()); | 6484 CHECK(context_1->GetEmbedderData(0)->IsUndefined()); |
| 6188 | 6485 |
| 6189 // Set and check a data value. | 6486 // Set and check a data value. |
| 6190 v8::Handle<v8::String> data_1 = | 6487 v8::Local<v8::String> data_1 = v8_str(CcTest::isolate(), "1"); |
| 6191 v8::String::NewFromUtf8(CcTest::isolate(), "1"); | |
| 6192 context_1->SetEmbedderData(0, data_1); | 6488 context_1->SetEmbedderData(0, data_1); |
| 6193 CHECK(context_1->GetEmbedderData(0)->StrictEquals(data_1)); | 6489 CHECK(context_1->GetEmbedderData(0)->StrictEquals(data_1)); |
| 6194 | 6490 |
| 6195 // Simple test function with eval that causes a break. | 6491 // Simple test function with eval that causes a break. |
| 6196 const char* source = "function f() { eval('debugger;'); }"; | 6492 const char* source = "function f() { eval('debugger;'); }"; |
| 6197 | 6493 |
| 6198 // Enter and run function in the context. | 6494 // Enter and run function in the context. |
| 6199 { | 6495 { |
| 6200 v8::Context::Scope context_scope(context_1); | 6496 v8::Context::Scope context_scope(context_1); |
| 6201 expected_context = context_1; | 6497 expected_context = context_1; |
| 6202 expected_context_data = data_1; | 6498 expected_context_data = data_1; |
| 6203 v8::Local<v8::Function> f = CompileFunction(CcTest::isolate(), source, "f"); | 6499 v8::Local<v8::Function> f = CompileFunction(CcTest::isolate(), source, "f"); |
| 6204 f->Call(context_1->Global(), 0, NULL); | 6500 f->Call(context_1, context_1->Global(), 0, NULL).ToLocalChecked(); |
| 6205 } | 6501 } |
| 6206 | 6502 |
| 6207 v8::Debug::SetMessageHandler(NULL); | 6503 v8::Debug::SetMessageHandler(NULL); |
| 6208 } | 6504 } |
| 6209 | 6505 |
| 6210 | 6506 |
| 6211 // Test which creates a context and sets embedder data on it. Checks that this | 6507 // Test which creates a context and sets embedder data on it. Checks that this |
| 6212 // data is set correctly and that when the debug message handler is called for | 6508 // data is set correctly and that when the debug message handler is called for |
| 6213 // break event in an eval statement the expected context is the one returned by | 6509 // break event in an eval statement the expected context is the one returned by |
| 6214 // Message.GetEventContext. | 6510 // Message.GetEventContext. |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6303 } | 6599 } |
| 6304 } | 6600 } |
| 6305 } | 6601 } |
| 6306 | 6602 |
| 6307 | 6603 |
| 6308 // Tests that after compile event is sent as many times as there are scripts | 6604 // Tests that after compile event is sent as many times as there are scripts |
| 6309 // compiled. | 6605 // compiled. |
| 6310 TEST(AfterCompileMessageWhenMessageHandlerIsReset) { | 6606 TEST(AfterCompileMessageWhenMessageHandlerIsReset) { |
| 6311 DebugLocalContext env; | 6607 DebugLocalContext env; |
| 6312 v8::HandleScope scope(env->GetIsolate()); | 6608 v8::HandleScope scope(env->GetIsolate()); |
| 6609 v8::Local<v8::Context> context = env.context(); |
| 6313 after_compile_message_count = 0; | 6610 after_compile_message_count = 0; |
| 6314 const char* script = "var a=1"; | 6611 const char* script = "var a=1"; |
| 6315 | 6612 |
| 6316 v8::Debug::SetMessageHandler(AfterCompileMessageHandler); | 6613 v8::Debug::SetMessageHandler(AfterCompileMessageHandler); |
| 6317 v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), script)) | 6614 v8::Script::Compile(context, v8_str(env->GetIsolate(), script)) |
| 6318 ->Run(); | 6615 .ToLocalChecked() |
| 6616 ->Run(context) |
| 6617 .ToLocalChecked(); |
| 6319 v8::Debug::SetMessageHandler(NULL); | 6618 v8::Debug::SetMessageHandler(NULL); |
| 6320 | 6619 |
| 6321 v8::Debug::SetMessageHandler(AfterCompileMessageHandler); | 6620 v8::Debug::SetMessageHandler(AfterCompileMessageHandler); |
| 6322 v8::Debug::DebugBreak(env->GetIsolate()); | 6621 v8::Debug::DebugBreak(env->GetIsolate()); |
| 6323 v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), script)) | 6622 v8::Script::Compile(context, v8_str(env->GetIsolate(), script)) |
| 6324 ->Run(); | 6623 .ToLocalChecked() |
| 6624 ->Run(context) |
| 6625 .ToLocalChecked(); |
| 6325 | 6626 |
| 6326 // Setting listener to NULL should cause debugger unload. | 6627 // Setting listener to NULL should cause debugger unload. |
| 6327 v8::Debug::SetMessageHandler(NULL); | 6628 v8::Debug::SetMessageHandler(NULL); |
| 6328 CheckDebuggerUnloaded(); | 6629 CheckDebuggerUnloaded(); |
| 6329 | 6630 |
| 6330 // Compilation cache should be disabled when debugger is active. | 6631 // Compilation cache should be disabled when debugger is active. |
| 6331 CHECK_EQ(2, after_compile_message_count); | 6632 CHECK_EQ(2, after_compile_message_count); |
| 6332 } | 6633 } |
| 6333 | 6634 |
| 6334 | 6635 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 6352 // Tests that syntax error event is sent as many times as there are scripts | 6653 // Tests that syntax error event is sent as many times as there are scripts |
| 6353 // with syntax error compiled. | 6654 // with syntax error compiled. |
| 6354 TEST(SyntaxErrorMessageOnSyntaxException) { | 6655 TEST(SyntaxErrorMessageOnSyntaxException) { |
| 6355 DebugLocalContext env; | 6656 DebugLocalContext env; |
| 6356 v8::HandleScope scope(env->GetIsolate()); | 6657 v8::HandleScope scope(env->GetIsolate()); |
| 6357 | 6658 |
| 6358 // For this test, we want to break on uncaught exceptions: | 6659 // For this test, we want to break on uncaught exceptions: |
| 6359 ChangeBreakOnException(false, true); | 6660 ChangeBreakOnException(false, true); |
| 6360 | 6661 |
| 6361 v8::Debug::SetDebugEventListener(CompileErrorEventCounter); | 6662 v8::Debug::SetDebugEventListener(CompileErrorEventCounter); |
| 6663 v8::Local<v8::Context> context = env.context(); |
| 6362 | 6664 |
| 6363 CompileErrorEventCounterClear(); | 6665 CompileErrorEventCounterClear(); |
| 6364 | 6666 |
| 6365 // Check initial state. | 6667 // Check initial state. |
| 6366 CHECK_EQ(0, compile_error_event_count); | 6668 CHECK_EQ(0, compile_error_event_count); |
| 6367 | 6669 |
| 6368 // Throws SyntaxError: Unexpected end of input | 6670 // Throws SyntaxError: Unexpected end of input |
| 6369 v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), "+++")); | 6671 CHECK( |
| 6672 v8::Script::Compile(context, v8_str(env->GetIsolate(), "+++")).IsEmpty()); |
| 6370 CHECK_EQ(1, compile_error_event_count); | 6673 CHECK_EQ(1, compile_error_event_count); |
| 6371 | 6674 |
| 6372 v8::Script::Compile( | 6675 CHECK(v8::Script::Compile(context, v8_str(env->GetIsolate(), "/sel\\/: \\")) |
| 6373 v8::String::NewFromUtf8(env->GetIsolate(), "/sel\\/: \\")); | 6676 .IsEmpty()); |
| 6374 CHECK_EQ(2, compile_error_event_count); | 6677 CHECK_EQ(2, compile_error_event_count); |
| 6375 | 6678 |
| 6376 v8::Local<v8::Script> script = v8::Script::Compile( | 6679 v8::Local<v8::Script> script = |
| 6377 v8::String::NewFromUtf8(env->GetIsolate(), "JSON.parse('1234:')")); | 6680 v8::Script::Compile(context, |
| 6681 v8_str(env->GetIsolate(), "JSON.parse('1234:')")) |
| 6682 .ToLocalChecked(); |
| 6378 CHECK_EQ(2, compile_error_event_count); | 6683 CHECK_EQ(2, compile_error_event_count); |
| 6379 script->Run(); | 6684 CHECK(script->Run(context).IsEmpty()); |
| 6380 CHECK_EQ(3, compile_error_event_count); | 6685 CHECK_EQ(3, compile_error_event_count); |
| 6381 | 6686 |
| 6382 v8::Script::Compile( | 6687 v8::Script::Compile(context, |
| 6383 v8::String::NewFromUtf8(env->GetIsolate(), "new RegExp('/\\/\\\\');")); | 6688 v8_str(env->GetIsolate(), "new RegExp('/\\/\\\\');")) |
| 6689 .ToLocalChecked(); |
| 6384 CHECK_EQ(3, compile_error_event_count); | 6690 CHECK_EQ(3, compile_error_event_count); |
| 6385 | 6691 |
| 6386 v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), "throw 1;")); | 6692 v8::Script::Compile(context, v8_str(env->GetIsolate(), "throw 1;")) |
| 6693 .ToLocalChecked(); |
| 6387 CHECK_EQ(3, compile_error_event_count); | 6694 CHECK_EQ(3, compile_error_event_count); |
| 6388 } | 6695 } |
| 6389 | 6696 |
| 6390 | 6697 |
| 6391 // Tests that break event is sent when message handler is reset. | 6698 // Tests that break event is sent when message handler is reset. |
| 6392 TEST(BreakMessageWhenMessageHandlerIsReset) { | 6699 TEST(BreakMessageWhenMessageHandlerIsReset) { |
| 6393 DebugLocalContext env; | 6700 DebugLocalContext env; |
| 6394 v8::HandleScope scope(env->GetIsolate()); | 6701 v8::HandleScope scope(env->GetIsolate()); |
| 6702 v8::Local<v8::Context> context = env.context(); |
| 6395 after_compile_message_count = 0; | 6703 after_compile_message_count = 0; |
| 6396 const char* script = "function f() {};"; | 6704 const char* script = "function f() {};"; |
| 6397 | 6705 |
| 6398 v8::Debug::SetMessageHandler(AfterCompileMessageHandler); | 6706 v8::Debug::SetMessageHandler(AfterCompileMessageHandler); |
| 6399 v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), script)) | 6707 v8::Script::Compile(context, v8_str(env->GetIsolate(), script)) |
| 6400 ->Run(); | 6708 .ToLocalChecked() |
| 6709 ->Run(context) |
| 6710 .ToLocalChecked(); |
| 6401 v8::Debug::SetMessageHandler(NULL); | 6711 v8::Debug::SetMessageHandler(NULL); |
| 6402 | 6712 |
| 6403 v8::Debug::SetMessageHandler(AfterCompileMessageHandler); | 6713 v8::Debug::SetMessageHandler(AfterCompileMessageHandler); |
| 6404 v8::Debug::DebugBreak(env->GetIsolate()); | 6714 v8::Debug::DebugBreak(env->GetIsolate()); |
| 6405 v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( | 6715 v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( |
| 6406 env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); | 6716 env->Global() |
| 6407 f->Call(env->Global(), 0, NULL); | 6717 ->Get(context, v8_str(env->GetIsolate(), "f")) |
| 6718 .ToLocalChecked()); |
| 6719 f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 6408 | 6720 |
| 6409 // Setting message handler to NULL should cause debugger unload. | 6721 // Setting message handler to NULL should cause debugger unload. |
| 6410 v8::Debug::SetMessageHandler(NULL); | 6722 v8::Debug::SetMessageHandler(NULL); |
| 6411 CheckDebuggerUnloaded(); | 6723 CheckDebuggerUnloaded(); |
| 6412 | 6724 |
| 6413 // Compilation cache should be disabled when debugger is active. | 6725 // Compilation cache should be disabled when debugger is active. |
| 6414 CHECK_EQ(1, after_compile_message_count); | 6726 CHECK_EQ(1, after_compile_message_count); |
| 6415 } | 6727 } |
| 6416 | 6728 |
| 6417 | 6729 |
| 6418 static int exception_event_count = 0; | 6730 static int exception_event_count = 0; |
| 6419 static void ExceptionMessageHandler(const v8::Debug::Message& message) { | 6731 static void ExceptionMessageHandler(const v8::Debug::Message& message) { |
| 6420 if (message.IsEvent() && message.GetEvent() == v8::Exception) { | 6732 if (message.IsEvent() && message.GetEvent() == v8::Exception) { |
| 6421 exception_event_count++; | 6733 exception_event_count++; |
| 6422 SendContinueCommand(); | 6734 SendContinueCommand(); |
| 6423 } | 6735 } |
| 6424 } | 6736 } |
| 6425 | 6737 |
| 6426 | 6738 |
| 6427 // Tests that exception event is sent when message handler is reset. | 6739 // Tests that exception event is sent when message handler is reset. |
| 6428 TEST(ExceptionMessageWhenMessageHandlerIsReset) { | 6740 TEST(ExceptionMessageWhenMessageHandlerIsReset) { |
| 6429 DebugLocalContext env; | 6741 DebugLocalContext env; |
| 6430 v8::HandleScope scope(env->GetIsolate()); | 6742 v8::HandleScope scope(env->GetIsolate()); |
| 6431 | 6743 |
| 6744 v8::Local<v8::Context> context = env.context(); |
| 6432 // For this test, we want to break on uncaught exceptions: | 6745 // For this test, we want to break on uncaught exceptions: |
| 6433 ChangeBreakOnException(false, true); | 6746 ChangeBreakOnException(false, true); |
| 6434 | 6747 |
| 6435 exception_event_count = 0; | 6748 exception_event_count = 0; |
| 6436 const char* script = "function f() {throw new Error()};"; | 6749 const char* script = "function f() {throw new Error()};"; |
| 6437 | 6750 |
| 6438 v8::Debug::SetMessageHandler(AfterCompileMessageHandler); | 6751 v8::Debug::SetMessageHandler(AfterCompileMessageHandler); |
| 6439 v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), script)) | 6752 v8::Script::Compile(context, v8_str(env->GetIsolate(), script)) |
| 6440 ->Run(); | 6753 .ToLocalChecked() |
| 6754 ->Run(context) |
| 6755 .ToLocalChecked(); |
| 6441 v8::Debug::SetMessageHandler(NULL); | 6756 v8::Debug::SetMessageHandler(NULL); |
| 6442 | 6757 |
| 6443 v8::Debug::SetMessageHandler(ExceptionMessageHandler); | 6758 v8::Debug::SetMessageHandler(ExceptionMessageHandler); |
| 6444 v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( | 6759 v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( |
| 6445 env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); | 6760 env->Global() |
| 6446 f->Call(env->Global(), 0, NULL); | 6761 ->Get(context, v8_str(env->GetIsolate(), "f")) |
| 6762 .ToLocalChecked()); |
| 6763 CHECK(f->Call(context, env->Global(), 0, NULL).IsEmpty()); |
| 6447 | 6764 |
| 6448 // Setting message handler to NULL should cause debugger unload. | 6765 // Setting message handler to NULL should cause debugger unload. |
| 6449 v8::Debug::SetMessageHandler(NULL); | 6766 v8::Debug::SetMessageHandler(NULL); |
| 6450 CheckDebuggerUnloaded(); | 6767 CheckDebuggerUnloaded(); |
| 6451 | 6768 |
| 6452 CHECK_EQ(1, exception_event_count); | 6769 CHECK_EQ(1, exception_event_count); |
| 6453 } | 6770 } |
| 6454 | 6771 |
| 6455 | 6772 |
| 6456 // Tests after compile event is sent when there are some provisional | 6773 // Tests after compile event is sent when there are some provisional |
| 6457 // breakpoints out of the scripts lines range. | 6774 // breakpoints out of the scripts lines range. |
| 6458 TEST(ProvisionalBreakpointOnLineOutOfRange) { | 6775 TEST(ProvisionalBreakpointOnLineOutOfRange) { |
| 6459 DebugLocalContext env; | 6776 DebugLocalContext env; |
| 6460 v8::HandleScope scope(env->GetIsolate()); | 6777 v8::HandleScope scope(env->GetIsolate()); |
| 6461 env.ExposeDebug(); | 6778 env.ExposeDebug(); |
| 6462 const char* script = "function f() {};"; | 6779 const char* script = "function f() {};"; |
| 6463 const char* resource_name = "test_resource"; | 6780 const char* resource_name = "test_resource"; |
| 6464 | 6781 |
| 6465 v8::Debug::SetMessageHandler(AfterCompileMessageHandler); | 6782 v8::Debug::SetMessageHandler(AfterCompileMessageHandler); |
| 6783 v8::Local<v8::Context> context = env.context(); |
| 6466 | 6784 |
| 6467 // Set a couple of provisional breakpoint on lines out of the script lines | 6785 // Set a couple of provisional breakpoint on lines out of the script lines |
| 6468 // range. | 6786 // range. |
| 6469 int sbp1 = SetScriptBreakPointByNameFromJS(env->GetIsolate(), resource_name, | 6787 int sbp1 = SetScriptBreakPointByNameFromJS(env->GetIsolate(), resource_name, |
| 6470 3, -1 /* no column */); | 6788 3, -1 /* no column */); |
| 6471 int sbp2 = | 6789 int sbp2 = |
| 6472 SetScriptBreakPointByNameFromJS(env->GetIsolate(), resource_name, 5, 5); | 6790 SetScriptBreakPointByNameFromJS(env->GetIsolate(), resource_name, 5, 5); |
| 6473 | 6791 |
| 6474 after_compile_message_count = 0; | 6792 after_compile_message_count = 0; |
| 6475 | 6793 |
| 6476 v8::ScriptOrigin origin( | 6794 v8::ScriptOrigin origin(v8_str(env->GetIsolate(), resource_name), |
| 6477 v8::String::NewFromUtf8(env->GetIsolate(), resource_name), | 6795 v8::Integer::New(env->GetIsolate(), 10), |
| 6478 v8::Integer::New(env->GetIsolate(), 10), | 6796 v8::Integer::New(env->GetIsolate(), 1)); |
| 6479 v8::Integer::New(env->GetIsolate(), 1)); | |
| 6480 // Compile a script whose first line number is greater than the breakpoints' | 6797 // Compile a script whose first line number is greater than the breakpoints' |
| 6481 // lines. | 6798 // lines. |
| 6482 v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), script), | 6799 v8::Script::Compile(context, v8_str(env->GetIsolate(), script), &origin) |
| 6483 &origin)->Run(); | 6800 .ToLocalChecked() |
| 6801 ->Run(context) |
| 6802 .ToLocalChecked(); |
| 6484 | 6803 |
| 6485 // If the script is compiled successfully there is exactly one after compile | 6804 // If the script is compiled successfully there is exactly one after compile |
| 6486 // event. In case of an exception in debugger code after compile event is not | 6805 // event. In case of an exception in debugger code after compile event is not |
| 6487 // sent. | 6806 // sent. |
| 6488 CHECK_EQ(1, after_compile_message_count); | 6807 CHECK_EQ(1, after_compile_message_count); |
| 6489 | 6808 |
| 6490 ClearBreakPointFromJS(env->GetIsolate(), sbp1); | 6809 ClearBreakPointFromJS(env->GetIsolate(), sbp1); |
| 6491 ClearBreakPointFromJS(env->GetIsolate(), sbp2); | 6810 ClearBreakPointFromJS(env->GetIsolate(), sbp2); |
| 6492 v8::Debug::SetMessageHandler(NULL); | 6811 v8::Debug::SetMessageHandler(NULL); |
| 6493 } | 6812 } |
| (...skipping 20 matching lines...) Expand all Loading... |
| 6514 CHECK_EQ(current_count, break_point_hit_count); | 6833 CHECK_EQ(current_count, break_point_hit_count); |
| 6515 } | 6834 } |
| 6516 } | 6835 } |
| 6517 | 6836 |
| 6518 | 6837 |
| 6519 // Test that if DebugBreak is forced it is ignored when code from | 6838 // Test that if DebugBreak is forced it is ignored when code from |
| 6520 // debug-delay.js is executed. | 6839 // debug-delay.js is executed. |
| 6521 TEST(NoDebugBreakInAfterCompileMessageHandler) { | 6840 TEST(NoDebugBreakInAfterCompileMessageHandler) { |
| 6522 DebugLocalContext env; | 6841 DebugLocalContext env; |
| 6523 v8::HandleScope scope(env->GetIsolate()); | 6842 v8::HandleScope scope(env->GetIsolate()); |
| 6843 v8::Local<v8::Context> context = env.context(); |
| 6524 | 6844 |
| 6525 // Register a debug event listener which sets the break flag and counts. | 6845 // Register a debug event listener which sets the break flag and counts. |
| 6526 v8::Debug::SetMessageHandler(BreakMessageHandler); | 6846 v8::Debug::SetMessageHandler(BreakMessageHandler); |
| 6527 | 6847 |
| 6528 // Set the debug break flag. | 6848 // Set the debug break flag. |
| 6529 v8::Debug::DebugBreak(env->GetIsolate()); | 6849 v8::Debug::DebugBreak(env->GetIsolate()); |
| 6530 | 6850 |
| 6531 // Create a function for testing stepping. | 6851 // Create a function for testing stepping. |
| 6532 const char* src = "function f() { eval('var x = 10;'); } "; | 6852 const char* src = "function f() { eval('var x = 10;'); } "; |
| 6533 v8::Local<v8::Function> f = CompileFunction(&env, src, "f"); | 6853 v8::Local<v8::Function> f = CompileFunction(&env, src, "f"); |
| 6534 | 6854 |
| 6535 // There should be only one break event. | 6855 // There should be only one break event. |
| 6536 CHECK_EQ(1, break_point_hit_count); | 6856 CHECK_EQ(1, break_point_hit_count); |
| 6537 | 6857 |
| 6538 // Set the debug break flag again. | 6858 // Set the debug break flag again. |
| 6539 v8::Debug::DebugBreak(env->GetIsolate()); | 6859 v8::Debug::DebugBreak(env->GetIsolate()); |
| 6540 f->Call(env->Global(), 0, NULL); | 6860 f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 6541 // There should be one more break event when the script is evaluated in 'f'. | 6861 // There should be one more break event when the script is evaluated in 'f'. |
| 6542 CHECK_EQ(2, break_point_hit_count); | 6862 CHECK_EQ(2, break_point_hit_count); |
| 6543 | 6863 |
| 6544 // Get rid of the debug message handler. | 6864 // Get rid of the debug message handler. |
| 6545 v8::Debug::SetMessageHandler(NULL); | 6865 v8::Debug::SetMessageHandler(NULL); |
| 6546 CheckDebuggerUnloaded(); | 6866 CheckDebuggerUnloaded(); |
| 6547 } | 6867 } |
| 6548 | 6868 |
| 6549 | 6869 |
| 6550 static int counting_message_handler_counter; | 6870 static int counting_message_handler_counter; |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6632 timer.Start(); | 6952 timer.Start(); |
| 6633 CHECK_EQ(i, counting_message_handler_counter); | 6953 CHECK_EQ(i, counting_message_handler_counter); |
| 6634 // Queue debug message. | 6954 // Queue debug message. |
| 6635 v8::Debug::SendCommand(isolate_, buffer, length); | 6955 v8::Debug::SendCommand(isolate_, buffer, length); |
| 6636 // Wait for the message handler to pick up the response. | 6956 // Wait for the message handler to pick up the response. |
| 6637 semaphore_.Wait(); | 6957 semaphore_.Wait(); |
| 6638 i::PrintF("iteration %d took %f ms\n", i, | 6958 i::PrintF("iteration %d took %f ms\n", i, |
| 6639 timer.Elapsed().InMillisecondsF()); | 6959 timer.Elapsed().InMillisecondsF()); |
| 6640 } | 6960 } |
| 6641 | 6961 |
| 6642 v8::V8::TerminateExecution(isolate_); | 6962 isolate_->TerminateExecution(); |
| 6643 } | 6963 } |
| 6644 | 6964 |
| 6645 void StartSending() { semaphore_.Signal(); } | 6965 void StartSending() { semaphore_.Signal(); } |
| 6646 | 6966 |
| 6647 private: | 6967 private: |
| 6648 v8::base::Semaphore semaphore_; | 6968 v8::base::Semaphore semaphore_; |
| 6649 v8::Isolate* isolate_; | 6969 v8::Isolate* isolate_; |
| 6650 }; | 6970 }; |
| 6651 | 6971 |
| 6652 | 6972 |
| 6653 static void StartSendingCommands( | 6973 static void StartSendingCommands( |
| 6654 const v8::FunctionCallbackInfo<v8::Value>& info) { | 6974 const v8::FunctionCallbackInfo<v8::Value>& info) { |
| 6655 send_command_thread_->StartSending(); | 6975 send_command_thread_->StartSending(); |
| 6656 } | 6976 } |
| 6657 | 6977 |
| 6658 | 6978 |
| 6659 TEST(ProcessDebugMessagesThreaded) { | 6979 TEST(ProcessDebugMessagesThreaded) { |
| 6660 DebugLocalContext env; | 6980 DebugLocalContext env; |
| 6661 v8::Isolate* isolate = env->GetIsolate(); | 6981 v8::Isolate* isolate = env->GetIsolate(); |
| 6662 v8::HandleScope scope(isolate); | 6982 v8::HandleScope scope(isolate); |
| 6983 v8::Local<v8::Context> context = env.context(); |
| 6663 | 6984 |
| 6664 counting_message_handler_counter = 0; | 6985 counting_message_handler_counter = 0; |
| 6665 | 6986 |
| 6666 v8::Debug::SetMessageHandler( | 6987 v8::Debug::SetMessageHandler( |
| 6667 SendCommandThread::CountingAndSignallingMessageHandler); | 6988 SendCommandThread::CountingAndSignallingMessageHandler); |
| 6668 send_command_thread_ = new SendCommandThread(isolate); | 6989 send_command_thread_ = new SendCommandThread(isolate); |
| 6669 send_command_thread_->Start(); | 6990 send_command_thread_->Start(); |
| 6670 | 6991 |
| 6671 v8::Handle<v8::FunctionTemplate> start = | 6992 v8::Local<v8::FunctionTemplate> start = |
| 6672 v8::FunctionTemplate::New(isolate, StartSendingCommands); | 6993 v8::FunctionTemplate::New(isolate, StartSendingCommands); |
| 6673 env->Global()->Set(v8_str("start"), start->GetFunction()); | 6994 CHECK(env->Global() |
| 6995 ->Set(context, v8_str("start"), |
| 6996 start->GetFunction(context).ToLocalChecked()) |
| 6997 .FromJust()); |
| 6674 | 6998 |
| 6675 CompileRun("start(); while (true) { }"); | 6999 CompileRun("start(); while (true) { }"); |
| 6676 | 7000 |
| 6677 CHECK_EQ(20, counting_message_handler_counter); | 7001 CHECK_EQ(20, counting_message_handler_counter); |
| 6678 | 7002 |
| 6679 v8::Debug::SetMessageHandler(NULL); | 7003 v8::Debug::SetMessageHandler(NULL); |
| 6680 CheckDebuggerUnloaded(); | 7004 CheckDebuggerUnloaded(); |
| 6681 } | 7005 } |
| 6682 | 7006 |
| 6683 | 7007 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 6696 }; | 7020 }; |
| 6697 | 7021 |
| 6698 int BacktraceData::frame_counter; | 7022 int BacktraceData::frame_counter; |
| 6699 | 7023 |
| 6700 | 7024 |
| 6701 // Test that debug messages get processed when ProcessDebugMessages is called. | 7025 // Test that debug messages get processed when ProcessDebugMessages is called. |
| 6702 TEST(Backtrace) { | 7026 TEST(Backtrace) { |
| 6703 DebugLocalContext env; | 7027 DebugLocalContext env; |
| 6704 v8::Isolate* isolate = env->GetIsolate(); | 7028 v8::Isolate* isolate = env->GetIsolate(); |
| 6705 v8::HandleScope scope(isolate); | 7029 v8::HandleScope scope(isolate); |
| 7030 v8::Local<v8::Context> context = env.context(); |
| 6706 | 7031 |
| 6707 v8::Debug::SetMessageHandler(BacktraceData::MessageHandler); | 7032 v8::Debug::SetMessageHandler(BacktraceData::MessageHandler); |
| 6708 | 7033 |
| 6709 const int kBufferSize = 1000; | 7034 const int kBufferSize = 1000; |
| 6710 uint16_t buffer[kBufferSize]; | 7035 uint16_t buffer[kBufferSize]; |
| 6711 const char* scripts_command = | 7036 const char* scripts_command = |
| 6712 "{\"seq\":0," | 7037 "{\"seq\":0," |
| 6713 "\"type\":\"request\"," | 7038 "\"type\":\"request\"," |
| 6714 "\"command\":\"backtrace\"}"; | 7039 "\"command\":\"backtrace\"}"; |
| 6715 | 7040 |
| 6716 // Check backtrace from ProcessDebugMessages. | 7041 // Check backtrace from ProcessDebugMessages. |
| 6717 BacktraceData::frame_counter = -10; | 7042 BacktraceData::frame_counter = -10; |
| 6718 v8::Debug::SendCommand( | 7043 v8::Debug::SendCommand( |
| 6719 isolate, | 7044 isolate, |
| 6720 buffer, | 7045 buffer, |
| 6721 AsciiToUtf16(scripts_command, buffer), | 7046 AsciiToUtf16(scripts_command, buffer), |
| 6722 NULL); | 7047 NULL); |
| 6723 v8::Debug::ProcessDebugMessages(); | 7048 v8::Debug::ProcessDebugMessages(); |
| 6724 CHECK_EQ(BacktraceData::frame_counter, 0); | 7049 CHECK_EQ(BacktraceData::frame_counter, 0); |
| 6725 | 7050 |
| 6726 v8::Handle<v8::String> void0 = | 7051 v8::Local<v8::String> void0 = v8_str(env->GetIsolate(), "void(0)"); |
| 6727 v8::String::NewFromUtf8(env->GetIsolate(), "void(0)"); | 7052 v8::Local<v8::Script> script = CompileWithOrigin(void0, void0); |
| 6728 v8::Handle<v8::Script> script = CompileWithOrigin(void0, void0); | |
| 6729 | 7053 |
| 6730 // Check backtrace from "void(0)" script. | 7054 // Check backtrace from "void(0)" script. |
| 6731 BacktraceData::frame_counter = -10; | 7055 BacktraceData::frame_counter = -10; |
| 6732 v8::Debug::SendCommand( | 7056 v8::Debug::SendCommand( |
| 6733 isolate, | 7057 isolate, |
| 6734 buffer, | 7058 buffer, |
| 6735 AsciiToUtf16(scripts_command, buffer), | 7059 AsciiToUtf16(scripts_command, buffer), |
| 6736 NULL); | 7060 NULL); |
| 6737 script->Run(); | 7061 script->Run(context).ToLocalChecked(); |
| 6738 CHECK_EQ(BacktraceData::frame_counter, 1); | 7062 CHECK_EQ(BacktraceData::frame_counter, 1); |
| 6739 | 7063 |
| 6740 // Get rid of the debug message handler. | 7064 // Get rid of the debug message handler. |
| 6741 v8::Debug::SetMessageHandler(NULL); | 7065 v8::Debug::SetMessageHandler(NULL); |
| 6742 CheckDebuggerUnloaded(); | 7066 CheckDebuggerUnloaded(); |
| 6743 } | 7067 } |
| 6744 | 7068 |
| 6745 | 7069 |
| 6746 TEST(GetMirror) { | 7070 TEST(GetMirror) { |
| 6747 DebugLocalContext env; | 7071 DebugLocalContext env; |
| 6748 v8::Isolate* isolate = env->GetIsolate(); | 7072 v8::Isolate* isolate = env->GetIsolate(); |
| 6749 v8::HandleScope scope(isolate); | 7073 v8::HandleScope scope(isolate); |
| 6750 v8::Handle<v8::Value> obj = | 7074 v8::Local<v8::Context> context = env.context(); |
| 6751 v8::Debug::GetMirror(v8::String::NewFromUtf8(isolate, "hodja")); | 7075 v8::Local<v8::Value> obj = |
| 7076 v8::Debug::GetMirror(context, v8_str(isolate, "hodja")).ToLocalChecked(); |
| 6752 v8::ScriptCompiler::Source source(v8_str( | 7077 v8::ScriptCompiler::Source source(v8_str( |
| 6753 "function runTest(mirror) {" | 7078 "function runTest(mirror) {" |
| 6754 " return mirror.isString() && (mirror.length() == 5);" | 7079 " return mirror.isString() && (mirror.length() == 5);" |
| 6755 "}" | 7080 "}" |
| 6756 "" | 7081 "" |
| 6757 "runTest;")); | 7082 "runTest;")); |
| 6758 v8::Handle<v8::Function> run_test = v8::Handle<v8::Function>::Cast( | 7083 v8::Local<v8::Function> run_test = v8::Local<v8::Function>::Cast( |
| 6759 v8::ScriptCompiler::CompileUnbound(isolate, &source) | 7084 v8::ScriptCompiler::CompileUnboundScript(isolate, &source) |
| 7085 .ToLocalChecked() |
| 6760 ->BindToCurrentContext() | 7086 ->BindToCurrentContext() |
| 6761 ->Run()); | 7087 ->Run(context) |
| 6762 v8::Handle<v8::Value> result = run_test->Call(env->Global(), 1, &obj); | 7088 .ToLocalChecked()); |
| 7089 v8::Local<v8::Value> result = |
| 7090 run_test->Call(context, env->Global(), 1, &obj).ToLocalChecked(); |
| 6763 CHECK(result->IsTrue()); | 7091 CHECK(result->IsTrue()); |
| 6764 } | 7092 } |
| 6765 | 7093 |
| 6766 | 7094 |
| 6767 // Test that the debug break flag works with function.apply. | 7095 // Test that the debug break flag works with function.apply. |
| 6768 TEST(DebugBreakFunctionApply) { | 7096 TEST(DebugBreakFunctionApply) { |
| 6769 DebugLocalContext env; | 7097 DebugLocalContext env; |
| 6770 v8::HandleScope scope(env->GetIsolate()); | 7098 v8::HandleScope scope(env->GetIsolate()); |
| 7099 v8::Local<v8::Context> context = env.context(); |
| 6771 | 7100 |
| 6772 // Create a function for testing breaking in apply. | 7101 // Create a function for testing breaking in apply. |
| 6773 v8::Local<v8::Function> foo = CompileFunction( | 7102 v8::Local<v8::Function> foo = CompileFunction( |
| 6774 &env, | 7103 &env, |
| 6775 "function baz(x) { }" | 7104 "function baz(x) { }" |
| 6776 "function bar(x) { baz(); }" | 7105 "function bar(x) { baz(); }" |
| 6777 "function foo(){ bar.apply(this, [1]); }", | 7106 "function foo(){ bar.apply(this, [1]); }", |
| 6778 "foo"); | 7107 "foo"); |
| 6779 | 7108 |
| 6780 // Register a debug event listener which steps and counts. | 7109 // Register a debug event listener which steps and counts. |
| 6781 v8::Debug::SetDebugEventListener(DebugEventBreakMax); | 7110 v8::Debug::SetDebugEventListener(DebugEventBreakMax); |
| 6782 | 7111 |
| 6783 // Set the debug break flag before calling the code using function.apply. | 7112 // Set the debug break flag before calling the code using function.apply. |
| 6784 v8::Debug::DebugBreak(env->GetIsolate()); | 7113 v8::Debug::DebugBreak(env->GetIsolate()); |
| 6785 | 7114 |
| 6786 // Limit the number of debug breaks. This is a regression test for issue 493 | 7115 // Limit the number of debug breaks. This is a regression test for issue 493 |
| 6787 // where this test would enter an infinite loop. | 7116 // where this test would enter an infinite loop. |
| 6788 break_point_hit_count = 0; | 7117 break_point_hit_count = 0; |
| 6789 max_break_point_hit_count = 10000; // 10000 => infinite loop. | 7118 max_break_point_hit_count = 10000; // 10000 => infinite loop. |
| 6790 foo->Call(env->Global(), 0, NULL); | 7119 foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); |
| 6791 | 7120 |
| 6792 // When keeping the debug break several break will happen. | 7121 // When keeping the debug break several break will happen. |
| 6793 CHECK_GT(break_point_hit_count, 1); | 7122 CHECK_GT(break_point_hit_count, 1); |
| 6794 | 7123 |
| 6795 v8::Debug::SetDebugEventListener(NULL); | 7124 v8::Debug::SetDebugEventListener(NULL); |
| 6796 CheckDebuggerUnloaded(); | 7125 CheckDebuggerUnloaded(); |
| 6797 } | 7126 } |
| 6798 | 7127 |
| 6799 | 7128 |
| 6800 v8::Handle<v8::Context> debugee_context; | 7129 v8::Local<v8::Context> debugee_context; |
| 6801 v8::Handle<v8::Context> debugger_context; | 7130 v8::Local<v8::Context> debugger_context; |
| 6802 | 7131 |
| 6803 | 7132 |
| 6804 // Property getter that checks that current and calling contexts | 7133 // Property getter that checks that current and calling contexts |
| 6805 // are both the debugee contexts. | 7134 // are both the debugee contexts. |
| 6806 static void NamedGetterWithCallingContextCheck( | 7135 static void NamedGetterWithCallingContextCheck( |
| 6807 v8::Local<v8::String> name, | 7136 v8::Local<v8::String> name, |
| 6808 const v8::PropertyCallbackInfo<v8::Value>& info) { | 7137 const v8::PropertyCallbackInfo<v8::Value>& info) { |
| 6809 CHECK_EQ(0, strcmp(*v8::String::Utf8Value(name), "a")); | 7138 CHECK_EQ(0, strcmp(*v8::String::Utf8Value(name), "a")); |
| 6810 v8::Handle<v8::Context> current = info.GetIsolate()->GetCurrentContext(); | 7139 v8::Local<v8::Context> current = info.GetIsolate()->GetCurrentContext(); |
| 6811 CHECK(current == debugee_context); | 7140 CHECK(current == debugee_context); |
| 6812 CHECK(current != debugger_context); | 7141 CHECK(current != debugger_context); |
| 6813 info.GetReturnValue().Set(1); | 7142 info.GetReturnValue().Set(1); |
| 6814 } | 7143 } |
| 6815 | 7144 |
| 6816 | 7145 |
| 6817 // Debug event listener that checks if the first argument of a function is | 7146 // Debug event listener that checks if the first argument of a function is |
| 6818 // an object with property 'a' == 1. If the property has custom accessor | 7147 // an object with property 'a' == 1. If the property has custom accessor |
| 6819 // this handler will eventually invoke it. | 7148 // this handler will eventually invoke it. |
| 6820 static void DebugEventGetAtgumentPropertyValue( | 7149 static void DebugEventGetAtgumentPropertyValue( |
| 6821 const v8::Debug::EventDetails& event_details) { | 7150 const v8::Debug::EventDetails& event_details) { |
| 6822 v8::DebugEvent event = event_details.GetEvent(); | 7151 v8::DebugEvent event = event_details.GetEvent(); |
| 6823 v8::Handle<v8::Object> exec_state = event_details.GetExecutionState(); | 7152 v8::Local<v8::Object> exec_state = event_details.GetExecutionState(); |
| 6824 if (event == v8::Break) { | 7153 if (event == v8::Break) { |
| 6825 break_point_hit_count++; | 7154 break_point_hit_count++; |
| 6826 CHECK(debugger_context == CcTest::isolate()->GetCurrentContext()); | 7155 CHECK(debugger_context == CcTest::isolate()->GetCurrentContext()); |
| 6827 v8::Handle<v8::Function> func = v8::Handle<v8::Function>::Cast(CompileRun( | 7156 v8::Local<v8::Function> func = v8::Local<v8::Function>::Cast(CompileRun( |
| 6828 "(function(exec_state) {\n" | 7157 "(function(exec_state) {\n" |
| 6829 " return (exec_state.frame(0).argumentValue(0).property('a').\n" | 7158 " return (exec_state.frame(0).argumentValue(0).property('a').\n" |
| 6830 " value().value() == 1);\n" | 7159 " value().value() == 1);\n" |
| 6831 "})")); | 7160 "})")); |
| 6832 const int argc = 1; | 7161 const int argc = 1; |
| 6833 v8::Handle<v8::Value> argv[argc] = { exec_state }; | 7162 v8::Local<v8::Value> argv[argc] = {exec_state}; |
| 6834 v8::Handle<v8::Value> result = func->Call(exec_state, argc, argv); | 7163 v8::Local<v8::Value> result = |
| 7164 func->Call(debugger_context, exec_state, argc, argv).ToLocalChecked(); |
| 6835 CHECK(result->IsTrue()); | 7165 CHECK(result->IsTrue()); |
| 6836 } | 7166 } |
| 6837 } | 7167 } |
| 6838 | 7168 |
| 6839 | 7169 |
| 6840 TEST(CallingContextIsNotDebugContext) { | 7170 TEST(CallingContextIsNotDebugContext) { |
| 6841 v8::internal::Debug* debug = CcTest::i_isolate()->debug(); | 7171 v8::internal::Debug* debug = CcTest::i_isolate()->debug(); |
| 6842 // Create and enter a debugee context. | 7172 // Create and enter a debugee context. |
| 6843 DebugLocalContext env; | 7173 DebugLocalContext env; |
| 6844 v8::Isolate* isolate = env->GetIsolate(); | 7174 v8::Isolate* isolate = env->GetIsolate(); |
| 6845 v8::HandleScope scope(isolate); | 7175 v8::HandleScope scope(isolate); |
| 6846 env.ExposeDebug(); | 7176 env.ExposeDebug(); |
| 6847 | 7177 |
| 6848 // Save handles to the debugger and debugee contexts to be used in | 7178 // Save handles to the debugger and debugee contexts to be used in |
| 6849 // NamedGetterWithCallingContextCheck. | 7179 // NamedGetterWithCallingContextCheck. |
| 6850 debugee_context = env.context(); | 7180 debugee_context = env.context(); |
| 6851 debugger_context = v8::Utils::ToLocal(debug->debug_context()); | 7181 debugger_context = v8::Utils::ToLocal(debug->debug_context()); |
| 6852 | 7182 |
| 6853 // Create object with 'a' property accessor. | 7183 // Create object with 'a' property accessor. |
| 6854 v8::Handle<v8::ObjectTemplate> named = v8::ObjectTemplate::New(isolate); | 7184 v8::Local<v8::ObjectTemplate> named = v8::ObjectTemplate::New(isolate); |
| 6855 named->SetAccessor(v8::String::NewFromUtf8(isolate, "a"), | 7185 named->SetAccessor(v8_str(isolate, "a"), NamedGetterWithCallingContextCheck); |
| 6856 NamedGetterWithCallingContextCheck); | 7186 CHECK(env->Global() |
| 6857 env->Global()->Set(v8::String::NewFromUtf8(isolate, "obj"), | 7187 ->Set(debugee_context, v8_str(isolate, "obj"), |
| 6858 named->NewInstance()); | 7188 named->NewInstance(debugee_context).ToLocalChecked()) |
| 7189 .FromJust()); |
| 6859 | 7190 |
| 6860 // Register the debug event listener | 7191 // Register the debug event listener |
| 6861 v8::Debug::SetDebugEventListener(DebugEventGetAtgumentPropertyValue); | 7192 v8::Debug::SetDebugEventListener(DebugEventGetAtgumentPropertyValue); |
| 6862 | 7193 |
| 6863 // Create a function that invokes debugger. | 7194 // Create a function that invokes debugger. |
| 6864 v8::Local<v8::Function> foo = CompileFunction( | 7195 v8::Local<v8::Function> foo = CompileFunction( |
| 6865 &env, | 7196 &env, |
| 6866 "function bar(x) { debugger; }" | 7197 "function bar(x) { debugger; }" |
| 6867 "function foo(){ bar(obj); }", | 7198 "function foo(){ bar(obj); }", |
| 6868 "foo"); | 7199 "foo"); |
| 6869 | 7200 |
| 6870 break_point_hit_count = 0; | 7201 break_point_hit_count = 0; |
| 6871 foo->Call(env->Global(), 0, NULL); | 7202 foo->Call(debugee_context, env->Global(), 0, NULL).ToLocalChecked(); |
| 6872 CHECK_EQ(1, break_point_hit_count); | 7203 CHECK_EQ(1, break_point_hit_count); |
| 6873 | 7204 |
| 6874 v8::Debug::SetDebugEventListener(NULL); | 7205 v8::Debug::SetDebugEventListener(NULL); |
| 6875 debugee_context = v8::Handle<v8::Context>(); | 7206 debugee_context = v8::Local<v8::Context>(); |
| 6876 debugger_context = v8::Handle<v8::Context>(); | 7207 debugger_context = v8::Local<v8::Context>(); |
| 6877 CheckDebuggerUnloaded(); | 7208 CheckDebuggerUnloaded(); |
| 6878 } | 7209 } |
| 6879 | 7210 |
| 6880 | 7211 |
| 6881 TEST(DebugContextIsPreservedBetweenAccesses) { | 7212 TEST(DebugContextIsPreservedBetweenAccesses) { |
| 6882 v8::HandleScope scope(CcTest::isolate()); | 7213 v8::HandleScope scope(CcTest::isolate()); |
| 6883 v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); | 7214 v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); |
| 6884 v8::Local<v8::Context> context1 = v8::Debug::GetDebugContext(); | 7215 v8::Local<v8::Context> context1 = v8::Debug::GetDebugContext(); |
| 6885 v8::Local<v8::Context> context2 = v8::Debug::GetDebugContext(); | 7216 v8::Local<v8::Context> context2 = v8::Debug::GetDebugContext(); |
| 6886 CHECK(v8::Utils::OpenHandle(*context1).is_identical_to( | 7217 CHECK(v8::Utils::OpenHandle(*context1).is_identical_to( |
| 6887 v8::Utils::OpenHandle(*context2))); | 7218 v8::Utils::OpenHandle(*context2))); |
| 6888 v8::Debug::SetDebugEventListener(NULL); | 7219 v8::Debug::SetDebugEventListener(NULL); |
| 6889 } | 7220 } |
| 6890 | 7221 |
| 6891 | 7222 |
| 6892 TEST(NoDebugContextWhenDebuggerDisabled) { | 7223 TEST(NoDebugContextWhenDebuggerDisabled) { |
| 6893 v8::HandleScope scope(CcTest::isolate()); | 7224 v8::HandleScope scope(CcTest::isolate()); |
| 6894 v8::Local<v8::Context> context = v8::Debug::GetDebugContext(); | 7225 v8::Local<v8::Context> context = v8::Debug::GetDebugContext(); |
| 6895 CHECK(context.IsEmpty()); | 7226 CHECK(context.IsEmpty()); |
| 6896 } | 7227 } |
| 6897 | 7228 |
| 6898 | 7229 |
| 6899 static v8::Handle<v8::Value> expected_callback_data; | 7230 static v8::Local<v8::Value> expected_callback_data; |
| 6900 static void DebugEventContextChecker(const v8::Debug::EventDetails& details) { | 7231 static void DebugEventContextChecker(const v8::Debug::EventDetails& details) { |
| 6901 CHECK(details.GetEventContext() == expected_context); | 7232 CHECK(details.GetEventContext() == expected_context); |
| 6902 CHECK(expected_callback_data->Equals(details.GetCallbackData())); | 7233 CHECK(expected_callback_data->Equals(details.GetEventContext(), |
| 7234 details.GetCallbackData()) |
| 7235 .FromJust()); |
| 6903 } | 7236 } |
| 6904 | 7237 |
| 6905 | 7238 |
| 6906 // Check that event details contain context where debug event occured. | 7239 // Check that event details contain context where debug event occured. |
| 6907 TEST(DebugEventContext) { | 7240 TEST(DebugEventContext) { |
| 6908 v8::Isolate* isolate = CcTest::isolate(); | 7241 v8::Isolate* isolate = CcTest::isolate(); |
| 6909 v8::HandleScope scope(isolate); | 7242 v8::HandleScope scope(isolate); |
| 6910 expected_context = v8::Context::New(isolate); | 7243 expected_context = v8::Context::New(isolate); |
| 6911 expected_callback_data = v8::Int32::New(isolate, 2010); | 7244 expected_callback_data = v8::Int32::New(isolate, 2010); |
| 6912 v8::Debug::SetDebugEventListener(DebugEventContextChecker, | 7245 v8::Debug::SetDebugEventListener(DebugEventContextChecker, |
| 6913 expected_callback_data); | 7246 expected_callback_data); |
| 6914 v8::Context::Scope context_scope(expected_context); | 7247 v8::Context::Scope context_scope(expected_context); |
| 6915 v8::Script::Compile( | 7248 v8::Script::Compile(expected_context, |
| 6916 v8::String::NewFromUtf8(isolate, "(function(){debugger;})();"))->Run(); | 7249 v8_str(isolate, "(function(){debugger;})();")) |
| 7250 .ToLocalChecked() |
| 7251 ->Run(expected_context) |
| 7252 .ToLocalChecked(); |
| 6917 expected_context.Clear(); | 7253 expected_context.Clear(); |
| 6918 v8::Debug::SetDebugEventListener(NULL); | 7254 v8::Debug::SetDebugEventListener(NULL); |
| 6919 expected_context_data = v8::Handle<v8::Value>(); | 7255 expected_context_data = v8::Local<v8::Value>(); |
| 6920 CheckDebuggerUnloaded(); | 7256 CheckDebuggerUnloaded(); |
| 6921 } | 7257 } |
| 6922 | 7258 |
| 6923 | 7259 |
| 6924 static bool debug_event_break_deoptimize_done = false; | 7260 static bool debug_event_break_deoptimize_done = false; |
| 6925 | 7261 |
| 6926 static void DebugEventBreakDeoptimize( | 7262 static void DebugEventBreakDeoptimize( |
| 6927 const v8::Debug::EventDetails& event_details) { | 7263 const v8::Debug::EventDetails& event_details) { |
| 6928 v8::DebugEvent event = event_details.GetEvent(); | 7264 v8::DebugEvent event = event_details.GetEvent(); |
| 6929 v8::Handle<v8::Object> exec_state = event_details.GetExecutionState(); | 7265 v8::Local<v8::Object> exec_state = event_details.GetExecutionState(); |
| 7266 v8::Local<v8::Context> context = CcTest::isolate()->GetCurrentContext(); |
| 6930 if (event == v8::Break) { | 7267 if (event == v8::Break) { |
| 6931 if (!frame_function_name.IsEmpty()) { | 7268 if (!frame_function_name.IsEmpty()) { |
| 6932 // Get the name of the function. | 7269 // Get the name of the function. |
| 6933 const int argc = 2; | 7270 const int argc = 2; |
| 6934 v8::Handle<v8::Value> argv[argc] = { | 7271 v8::Local<v8::Value> argv[argc] = { |
| 6935 exec_state, v8::Integer::New(CcTest::isolate(), 0) | 7272 exec_state, v8::Integer::New(CcTest::isolate(), 0)}; |
| 6936 }; | 7273 v8::Local<v8::Value> result = |
| 6937 v8::Handle<v8::Value> result = | 7274 frame_function_name->Call(context, exec_state, argc, argv) |
| 6938 frame_function_name->Call(exec_state, argc, argv); | 7275 .ToLocalChecked(); |
| 6939 if (!result->IsUndefined()) { | 7276 if (!result->IsUndefined()) { |
| 6940 char fn[80]; | 7277 char fn[80]; |
| 6941 CHECK(result->IsString()); | 7278 CHECK(result->IsString()); |
| 6942 v8::Handle<v8::String> function_name( | 7279 v8::Local<v8::String> function_name( |
| 6943 result->ToString(CcTest::isolate())); | 7280 result->ToString(context).ToLocalChecked()); |
| 6944 function_name->WriteUtf8(fn); | 7281 function_name->WriteUtf8(fn); |
| 6945 if (strcmp(fn, "bar") == 0) { | 7282 if (strcmp(fn, "bar") == 0) { |
| 6946 i::Deoptimizer::DeoptimizeAll(CcTest::i_isolate()); | 7283 i::Deoptimizer::DeoptimizeAll(CcTest::i_isolate()); |
| 6947 debug_event_break_deoptimize_done = true; | 7284 debug_event_break_deoptimize_done = true; |
| 6948 } | 7285 } |
| 6949 } | 7286 } |
| 6950 } | 7287 } |
| 6951 | 7288 |
| 6952 v8::Debug::DebugBreak(CcTest::isolate()); | 7289 v8::Debug::DebugBreak(CcTest::isolate()); |
| 6953 } | 7290 } |
| 6954 } | 7291 } |
| 6955 | 7292 |
| 6956 | 7293 |
| 6957 // Test deoptimization when execution is broken using the debug break stack | 7294 // Test deoptimization when execution is broken using the debug break stack |
| 6958 // check interrupt. | 7295 // check interrupt. |
| 6959 TEST(DeoptimizeDuringDebugBreak) { | 7296 TEST(DeoptimizeDuringDebugBreak) { |
| 6960 DebugLocalContext env; | 7297 DebugLocalContext env; |
| 6961 v8::HandleScope scope(env->GetIsolate()); | 7298 v8::HandleScope scope(env->GetIsolate()); |
| 6962 env.ExposeDebug(); | 7299 env.ExposeDebug(); |
| 7300 v8::Local<v8::Context> context = env.context(); |
| 6963 | 7301 |
| 6964 // Create a function for checking the function when hitting a break point. | 7302 // Create a function for checking the function when hitting a break point. |
| 6965 frame_function_name = CompileFunction(&env, | 7303 frame_function_name = CompileFunction(&env, |
| 6966 frame_function_name_source, | 7304 frame_function_name_source, |
| 6967 "frame_function_name"); | 7305 "frame_function_name"); |
| 6968 | 7306 |
| 6969 // Set a debug event listener which will keep interrupting execution until | 7307 // Set a debug event listener which will keep interrupting execution until |
| 6970 // debug break. When inside function bar it will deoptimize all functions. | 7308 // debug break. When inside function bar it will deoptimize all functions. |
| 6971 // This tests lazy deoptimization bailout for the stack check, as the first | 7309 // This tests lazy deoptimization bailout for the stack check, as the first |
| 6972 // time in function bar when using debug break and no break points will be at | 7310 // time in function bar when using debug break and no break points will be at |
| 6973 // the initial stack check. | 7311 // the initial stack check. |
| 6974 v8::Debug::SetDebugEventListener(DebugEventBreakDeoptimize); | 7312 v8::Debug::SetDebugEventListener(DebugEventBreakDeoptimize); |
| 6975 | 7313 |
| 6976 // Compile and run function bar which will optimize it for some flag settings. | 7314 // Compile and run function bar which will optimize it for some flag settings. |
| 6977 v8::Local<v8::Function> f = CompileFunction(&env, "function bar(){}", "bar"); | 7315 v8::Local<v8::Function> f = CompileFunction(&env, "function bar(){}", "bar"); |
| 6978 f->Call(v8::Undefined(env->GetIsolate()), 0, NULL); | 7316 f->Call(context, v8::Undefined(env->GetIsolate()), 0, NULL).ToLocalChecked(); |
| 6979 | 7317 |
| 6980 // Set debug break and call bar again. | 7318 // Set debug break and call bar again. |
| 6981 v8::Debug::DebugBreak(env->GetIsolate()); | 7319 v8::Debug::DebugBreak(env->GetIsolate()); |
| 6982 f->Call(v8::Undefined(env->GetIsolate()), 0, NULL); | 7320 f->Call(context, v8::Undefined(env->GetIsolate()), 0, NULL).ToLocalChecked(); |
| 6983 | 7321 |
| 6984 CHECK(debug_event_break_deoptimize_done); | 7322 CHECK(debug_event_break_deoptimize_done); |
| 6985 | 7323 |
| 6986 v8::Debug::SetDebugEventListener(NULL); | 7324 v8::Debug::SetDebugEventListener(NULL); |
| 6987 } | 7325 } |
| 6988 | 7326 |
| 6989 | 7327 |
| 6990 static void DebugEventBreakWithOptimizedStack( | 7328 static void DebugEventBreakWithOptimizedStack( |
| 6991 const v8::Debug::EventDetails& event_details) { | 7329 const v8::Debug::EventDetails& event_details) { |
| 6992 v8::Isolate* isolate = event_details.GetEventContext()->GetIsolate(); | 7330 v8::Isolate* isolate = event_details.GetEventContext()->GetIsolate(); |
| 6993 v8::DebugEvent event = event_details.GetEvent(); | 7331 v8::DebugEvent event = event_details.GetEvent(); |
| 6994 v8::Handle<v8::Object> exec_state = event_details.GetExecutionState(); | 7332 v8::Local<v8::Object> exec_state = event_details.GetExecutionState(); |
| 7333 v8::Local<v8::Context> context = isolate->GetCurrentContext(); |
| 6995 if (event == v8::Break) { | 7334 if (event == v8::Break) { |
| 6996 if (!frame_function_name.IsEmpty()) { | 7335 if (!frame_function_name.IsEmpty()) { |
| 6997 for (int i = 0; i < 2; i++) { | 7336 for (int i = 0; i < 2; i++) { |
| 6998 const int argc = 2; | 7337 const int argc = 2; |
| 6999 v8::Handle<v8::Value> argv[argc] = { | 7338 v8::Local<v8::Value> argv[argc] = {exec_state, |
| 7000 exec_state, v8::Integer::New(isolate, i) | 7339 v8::Integer::New(isolate, i)}; |
| 7001 }; | |
| 7002 // Get the name of the function in frame i. | 7340 // Get the name of the function in frame i. |
| 7003 v8::Handle<v8::Value> result = | 7341 v8::Local<v8::Value> result = |
| 7004 frame_function_name->Call(exec_state, argc, argv); | 7342 frame_function_name->Call(context, exec_state, argc, argv) |
| 7343 .ToLocalChecked(); |
| 7005 CHECK(result->IsString()); | 7344 CHECK(result->IsString()); |
| 7006 v8::Handle<v8::String> function_name(result->ToString(isolate)); | 7345 v8::Local<v8::String> function_name( |
| 7007 CHECK(function_name->Equals(v8::String::NewFromUtf8(isolate, "loop"))); | 7346 result->ToString(context).ToLocalChecked()); |
| 7347 CHECK( |
| 7348 function_name->Equals(context, v8_str(isolate, "loop")).FromJust()); |
| 7008 // Get the name of the first argument in frame i. | 7349 // Get the name of the first argument in frame i. |
| 7009 result = frame_argument_name->Call(exec_state, argc, argv); | 7350 result = frame_argument_name->Call(context, exec_state, argc, argv) |
| 7351 .ToLocalChecked(); |
| 7010 CHECK(result->IsString()); | 7352 CHECK(result->IsString()); |
| 7011 v8::Handle<v8::String> argument_name(result->ToString(isolate)); | 7353 v8::Local<v8::String> argument_name( |
| 7012 CHECK(argument_name->Equals(v8::String::NewFromUtf8(isolate, "count"))); | 7354 result->ToString(context).ToLocalChecked()); |
| 7355 CHECK(argument_name->Equals(context, v8_str(isolate, "count")) |
| 7356 .FromJust()); |
| 7013 // Get the value of the first argument in frame i. If the | 7357 // Get the value of the first argument in frame i. If the |
| 7014 // funtion is optimized the value will be undefined, otherwise | 7358 // funtion is optimized the value will be undefined, otherwise |
| 7015 // the value will be '1 - i'. | 7359 // the value will be '1 - i'. |
| 7016 // | 7360 // |
| 7017 // TODO(3141533): We should be able to get the real value for | 7361 // TODO(3141533): We should be able to get the real value for |
| 7018 // optimized frames. | 7362 // optimized frames. |
| 7019 result = frame_argument_value->Call(exec_state, argc, argv); | 7363 result = frame_argument_value->Call(context, exec_state, argc, argv) |
| 7020 CHECK(result->IsUndefined() || (result->Int32Value() == 1 - i)); | 7364 .ToLocalChecked(); |
| 7365 CHECK(result->IsUndefined() || |
| 7366 (result->Int32Value(context).FromJust() == 1 - i)); |
| 7021 // Get the name of the first local variable. | 7367 // Get the name of the first local variable. |
| 7022 result = frame_local_name->Call(exec_state, argc, argv); | 7368 result = frame_local_name->Call(context, exec_state, argc, argv) |
| 7369 .ToLocalChecked(); |
| 7023 CHECK(result->IsString()); | 7370 CHECK(result->IsString()); |
| 7024 v8::Handle<v8::String> local_name(result->ToString(isolate)); | 7371 v8::Local<v8::String> local_name( |
| 7025 CHECK(local_name->Equals(v8::String::NewFromUtf8(isolate, "local"))); | 7372 result->ToString(context).ToLocalChecked()); |
| 7373 CHECK(local_name->Equals(context, v8_str(isolate, "local")).FromJust()); |
| 7026 // Get the value of the first local variable. If the function | 7374 // Get the value of the first local variable. If the function |
| 7027 // is optimized the value will be undefined, otherwise it will | 7375 // is optimized the value will be undefined, otherwise it will |
| 7028 // be 42. | 7376 // be 42. |
| 7029 // | 7377 // |
| 7030 // TODO(3141533): We should be able to get the real value for | 7378 // TODO(3141533): We should be able to get the real value for |
| 7031 // optimized frames. | 7379 // optimized frames. |
| 7032 result = frame_local_value->Call(exec_state, argc, argv); | 7380 result = frame_local_value->Call(context, exec_state, argc, argv) |
| 7033 CHECK(result->IsUndefined() || (result->Int32Value() == 42)); | 7381 .ToLocalChecked(); |
| 7382 CHECK(result->IsUndefined() || |
| 7383 (result->Int32Value(context).FromJust() == 42)); |
| 7034 } | 7384 } |
| 7035 } | 7385 } |
| 7036 } | 7386 } |
| 7037 } | 7387 } |
| 7038 | 7388 |
| 7039 | 7389 |
| 7040 static void ScheduleBreak(const v8::FunctionCallbackInfo<v8::Value>& args) { | 7390 static void ScheduleBreak(const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 7041 v8::Debug::SetDebugEventListener(DebugEventBreakWithOptimizedStack); | 7391 v8::Debug::SetDebugEventListener(DebugEventBreakWithOptimizedStack); |
| 7042 v8::Debug::DebugBreak(args.GetIsolate()); | 7392 v8::Debug::DebugBreak(args.GetIsolate()); |
| 7043 } | 7393 } |
| 7044 | 7394 |
| 7045 | 7395 |
| 7046 TEST(DebugBreakStackInspection) { | 7396 TEST(DebugBreakStackInspection) { |
| 7047 DebugLocalContext env; | 7397 DebugLocalContext env; |
| 7048 v8::HandleScope scope(env->GetIsolate()); | 7398 v8::HandleScope scope(env->GetIsolate()); |
| 7399 v8::Local<v8::Context> context = env.context(); |
| 7049 | 7400 |
| 7050 frame_function_name = | 7401 frame_function_name = |
| 7051 CompileFunction(&env, frame_function_name_source, "frame_function_name"); | 7402 CompileFunction(&env, frame_function_name_source, "frame_function_name"); |
| 7052 frame_argument_name = | 7403 frame_argument_name = |
| 7053 CompileFunction(&env, frame_argument_name_source, "frame_argument_name"); | 7404 CompileFunction(&env, frame_argument_name_source, "frame_argument_name"); |
| 7054 frame_argument_value = CompileFunction(&env, | 7405 frame_argument_value = CompileFunction(&env, |
| 7055 frame_argument_value_source, | 7406 frame_argument_value_source, |
| 7056 "frame_argument_value"); | 7407 "frame_argument_value"); |
| 7057 frame_local_name = | 7408 frame_local_name = |
| 7058 CompileFunction(&env, frame_local_name_source, "frame_local_name"); | 7409 CompileFunction(&env, frame_local_name_source, "frame_local_name"); |
| 7059 frame_local_value = | 7410 frame_local_value = |
| 7060 CompileFunction(&env, frame_local_value_source, "frame_local_value"); | 7411 CompileFunction(&env, frame_local_value_source, "frame_local_value"); |
| 7061 | 7412 |
| 7062 v8::Handle<v8::FunctionTemplate> schedule_break_template = | 7413 v8::Local<v8::FunctionTemplate> schedule_break_template = |
| 7063 v8::FunctionTemplate::New(env->GetIsolate(), ScheduleBreak); | 7414 v8::FunctionTemplate::New(env->GetIsolate(), ScheduleBreak); |
| 7064 v8::Handle<v8::Function> schedule_break = | 7415 v8::Local<v8::Function> schedule_break = |
| 7065 schedule_break_template->GetFunction(); | 7416 schedule_break_template->GetFunction(context).ToLocalChecked(); |
| 7066 env->Global()->Set(v8_str("scheduleBreak"), schedule_break); | 7417 CHECK(env->Global() |
| 7418 ->Set(context, v8_str("scheduleBreak"), schedule_break) |
| 7419 .FromJust()); |
| 7067 | 7420 |
| 7068 const char* src = | 7421 const char* src = |
| 7069 "function loop(count) {" | 7422 "function loop(count) {" |
| 7070 " var local = 42;" | 7423 " var local = 42;" |
| 7071 " if (count < 1) { scheduleBreak(); loop(count + 1); }" | 7424 " if (count < 1) { scheduleBreak(); loop(count + 1); }" |
| 7072 "}" | 7425 "}" |
| 7073 "loop(0);"; | 7426 "loop(0);"; |
| 7074 v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), src))->Run(); | 7427 v8::Script::Compile(context, v8_str(env->GetIsolate(), src)) |
| 7428 .ToLocalChecked() |
| 7429 ->Run(context) |
| 7430 .ToLocalChecked(); |
| 7075 } | 7431 } |
| 7076 | 7432 |
| 7077 | 7433 |
| 7078 // Test that setting the terminate execution flag during debug break processing. | 7434 // Test that setting the terminate execution flag during debug break processing. |
| 7079 static void TestDebugBreakInLoop(const char* loop_head, | 7435 static void TestDebugBreakInLoop(const char* loop_head, |
| 7080 const char** loop_bodies, | 7436 const char** loop_bodies, |
| 7081 const char* loop_tail) { | 7437 const char* loop_tail) { |
| 7082 // Receive 10 breaks for each test and then terminate JavaScript execution. | 7438 // Receive 10 breaks for each test and then terminate JavaScript execution. |
| 7083 static const int kBreaksPerTest = 10; | 7439 static const int kBreaksPerTest = 10; |
| 7084 | 7440 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 7105 // Function with infinite loop. | 7461 // Function with infinite loop. |
| 7106 CompileRun(buffer.start()); | 7462 CompileRun(buffer.start()); |
| 7107 | 7463 |
| 7108 // Set the debug break to enter the debugger as soon as possible. | 7464 // Set the debug break to enter the debugger as soon as possible. |
| 7109 v8::Debug::DebugBreak(CcTest::isolate()); | 7465 v8::Debug::DebugBreak(CcTest::isolate()); |
| 7110 | 7466 |
| 7111 // Call function with infinite loop. | 7467 // Call function with infinite loop. |
| 7112 CompileRun("f();"); | 7468 CompileRun("f();"); |
| 7113 CHECK_EQ(kBreaksPerTest, break_point_hit_count); | 7469 CHECK_EQ(kBreaksPerTest, break_point_hit_count); |
| 7114 | 7470 |
| 7115 CHECK(!v8::V8::IsExecutionTerminating()); | 7471 CHECK(!CcTest::isolate()->IsExecutionTerminating()); |
| 7116 } | 7472 } |
| 7117 } | 7473 } |
| 7118 } | 7474 } |
| 7119 | 7475 |
| 7120 | 7476 |
| 7121 static const char* loop_bodies_1[] = {"", | 7477 static const char* loop_bodies_1[] = {"", |
| 7122 "g()", | 7478 "g()", |
| 7123 "if (a == 0) { g() }", | 7479 "if (a == 0) { g() }", |
| 7124 "if (a == 1) { g() }", | 7480 "if (a == 1) { g() }", |
| 7125 "if (a == 0) { g() } else { h() }", | 7481 "if (a == 0) { g() } else { h() }", |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7211 TEST(DebugBreakInForCondition2) { | 7567 TEST(DebugBreakInForCondition2) { |
| 7212 DebugBreakLoop("for (;a == 1;) {", loop_bodies_2, "}"); | 7568 DebugBreakLoop("for (;a == 1;) {", loop_bodies_2, "}"); |
| 7213 } | 7569 } |
| 7214 | 7570 |
| 7215 | 7571 |
| 7216 v8::Local<v8::Script> inline_script; | 7572 v8::Local<v8::Script> inline_script; |
| 7217 | 7573 |
| 7218 static void DebugBreakInlineListener( | 7574 static void DebugBreakInlineListener( |
| 7219 const v8::Debug::EventDetails& event_details) { | 7575 const v8::Debug::EventDetails& event_details) { |
| 7220 v8::DebugEvent event = event_details.GetEvent(); | 7576 v8::DebugEvent event = event_details.GetEvent(); |
| 7577 v8::Local<v8::Context> context = CcTest::isolate()->GetCurrentContext(); |
| 7221 if (event != v8::Break) return; | 7578 if (event != v8::Break) return; |
| 7222 | 7579 |
| 7223 int expected_frame_count = 4; | 7580 int expected_frame_count = 4; |
| 7224 int expected_line_number[] = {1, 4, 7, 12}; | 7581 int expected_line_number[] = {1, 4, 7, 12}; |
| 7225 | 7582 |
| 7226 i::Handle<i::Object> compiled_script = v8::Utils::OpenHandle(*inline_script); | 7583 i::Handle<i::Object> compiled_script = v8::Utils::OpenHandle(*inline_script); |
| 7227 i::Handle<i::Script> source_script = i::Handle<i::Script>(i::Script::cast( | 7584 i::Handle<i::Script> source_script = i::Handle<i::Script>(i::Script::cast( |
| 7228 i::JSFunction::cast(*compiled_script)->shared()->script())); | 7585 i::JSFunction::cast(*compiled_script)->shared()->script())); |
| 7229 | 7586 |
| 7230 int break_id = CcTest::i_isolate()->debug()->break_id(); | 7587 int break_id = CcTest::i_isolate()->debug()->break_id(); |
| 7231 char script[128]; | 7588 char script[128]; |
| 7232 i::Vector<char> script_vector(script, sizeof(script)); | 7589 i::Vector<char> script_vector(script, sizeof(script)); |
| 7233 SNPrintF(script_vector, "%%GetFrameCount(%d)", break_id); | 7590 SNPrintF(script_vector, "%%GetFrameCount(%d)", break_id); |
| 7234 v8::Local<v8::Value> result = CompileRun(script); | 7591 v8::Local<v8::Value> result = CompileRun(script); |
| 7235 | 7592 |
| 7236 int frame_count = result->Int32Value(); | 7593 int frame_count = result->Int32Value(context).FromJust(); |
| 7237 CHECK_EQ(expected_frame_count, frame_count); | 7594 CHECK_EQ(expected_frame_count, frame_count); |
| 7238 | 7595 |
| 7239 for (int i = 0; i < frame_count; i++) { | 7596 for (int i = 0; i < frame_count; i++) { |
| 7240 // The 5. element in the returned array of GetFrameDetails contains the | 7597 // The 5. element in the returned array of GetFrameDetails contains the |
| 7241 // source position of that frame. | 7598 // source position of that frame. |
| 7242 SNPrintF(script_vector, "%%GetFrameDetails(%d, %d)[5]", break_id, i); | 7599 SNPrintF(script_vector, "%%GetFrameDetails(%d, %d)[5]", break_id, i); |
| 7243 v8::Local<v8::Value> result = CompileRun(script); | 7600 v8::Local<v8::Value> result = CompileRun(script); |
| 7244 CHECK_EQ(expected_line_number[i], | 7601 CHECK_EQ(expected_line_number[i], |
| 7245 i::Script::GetLineNumber(source_script, result->Int32Value())); | 7602 i::Script::GetLineNumber(source_script, |
| 7603 result->Int32Value(context).FromJust())); |
| 7246 } | 7604 } |
| 7247 v8::Debug::SetDebugEventListener(NULL); | 7605 v8::Debug::SetDebugEventListener(NULL); |
| 7248 v8::V8::TerminateExecution(CcTest::isolate()); | 7606 CcTest::isolate()->TerminateExecution(); |
| 7249 } | 7607 } |
| 7250 | 7608 |
| 7251 | 7609 |
| 7252 TEST(DebugBreakInline) { | 7610 TEST(DebugBreakInline) { |
| 7253 i::FLAG_allow_natives_syntax = true; | 7611 i::FLAG_allow_natives_syntax = true; |
| 7254 DebugLocalContext env; | 7612 DebugLocalContext env; |
| 7255 v8::HandleScope scope(env->GetIsolate()); | 7613 v8::HandleScope scope(env->GetIsolate()); |
| 7614 v8::Local<v8::Context> context = env.context(); |
| 7256 const char* source = | 7615 const char* source = |
| 7257 "function debug(b) { \n" | 7616 "function debug(b) { \n" |
| 7258 " if (b) debugger; \n" | 7617 " if (b) debugger; \n" |
| 7259 "} \n" | 7618 "} \n" |
| 7260 "function f(b) { \n" | 7619 "function f(b) { \n" |
| 7261 " debug(b) \n" | 7620 " debug(b) \n" |
| 7262 "}; \n" | 7621 "}; \n" |
| 7263 "function g(b) { \n" | 7622 "function g(b) { \n" |
| 7264 " f(b); \n" | 7623 " f(b); \n" |
| 7265 "}; \n" | 7624 "}; \n" |
| 7266 "g(false); \n" | 7625 "g(false); \n" |
| 7267 "g(false); \n" | 7626 "g(false); \n" |
| 7268 "%OptimizeFunctionOnNextCall(g); \n" | 7627 "%OptimizeFunctionOnNextCall(g); \n" |
| 7269 "g(true);"; | 7628 "g(true);"; |
| 7270 v8::Debug::SetDebugEventListener(DebugBreakInlineListener); | 7629 v8::Debug::SetDebugEventListener(DebugBreakInlineListener); |
| 7271 inline_script = | 7630 inline_script = |
| 7272 v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), source)); | 7631 v8::Script::Compile(context, v8_str(env->GetIsolate(), source)) |
| 7273 inline_script->Run(); | 7632 .ToLocalChecked(); |
| 7633 inline_script->Run(context).ToLocalChecked(); |
| 7274 } | 7634 } |
| 7275 | 7635 |
| 7276 | 7636 |
| 7277 static void DebugEventStepNext( | 7637 static void DebugEventStepNext( |
| 7278 const v8::Debug::EventDetails& event_details) { | 7638 const v8::Debug::EventDetails& event_details) { |
| 7279 v8::DebugEvent event = event_details.GetEvent(); | 7639 v8::DebugEvent event = event_details.GetEvent(); |
| 7280 if (event == v8::Break) { | 7640 if (event == v8::Break) { |
| 7281 PrepareStep(StepNext); | 7641 PrepareStep(StepNext); |
| 7282 } | 7642 } |
| 7283 } | 7643 } |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7408 | 7768 |
| 7409 static void AddDebugBreak(const v8::FunctionCallbackInfo<v8::Value>& args) { | 7769 static void AddDebugBreak(const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 7410 v8::Debug::DebugBreak(args.GetIsolate()); | 7770 v8::Debug::DebugBreak(args.GetIsolate()); |
| 7411 } | 7771 } |
| 7412 | 7772 |
| 7413 | 7773 |
| 7414 TEST(DebugBreakStackTrace) { | 7774 TEST(DebugBreakStackTrace) { |
| 7415 DebugLocalContext env; | 7775 DebugLocalContext env; |
| 7416 v8::HandleScope scope(env->GetIsolate()); | 7776 v8::HandleScope scope(env->GetIsolate()); |
| 7417 v8::Debug::SetDebugEventListener(DebugBreakStackTraceListener); | 7777 v8::Debug::SetDebugEventListener(DebugBreakStackTraceListener); |
| 7418 v8::Handle<v8::FunctionTemplate> add_debug_break_template = | 7778 v8::Local<v8::Context> context = env.context(); |
| 7779 v8::Local<v8::FunctionTemplate> add_debug_break_template = |
| 7419 v8::FunctionTemplate::New(env->GetIsolate(), AddDebugBreak); | 7780 v8::FunctionTemplate::New(env->GetIsolate(), AddDebugBreak); |
| 7420 v8::Handle<v8::Function> add_debug_break = | 7781 v8::Local<v8::Function> add_debug_break = |
| 7421 add_debug_break_template->GetFunction(); | 7782 add_debug_break_template->GetFunction(context).ToLocalChecked(); |
| 7422 env->Global()->Set(v8_str("add_debug_break"), add_debug_break); | 7783 CHECK(env->Global() |
| 7784 ->Set(context, v8_str("add_debug_break"), add_debug_break) |
| 7785 .FromJust()); |
| 7423 | 7786 |
| 7424 CompileRun("(function loop() {" | 7787 CompileRun("(function loop() {" |
| 7425 " for (var j = 0; j < 1000; j++) {" | 7788 " for (var j = 0; j < 1000; j++) {" |
| 7426 " for (var i = 0; i < 1000; i++) {" | 7789 " for (var i = 0; i < 1000; i++) {" |
| 7427 " if (i == 999) add_debug_break();" | 7790 " if (i == 999) add_debug_break();" |
| 7428 " }" | 7791 " }" |
| 7429 " }" | 7792 " }" |
| 7430 "})()"); | 7793 "})()"); |
| 7431 } | 7794 } |
| 7432 | 7795 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 7446 } | 7809 } |
| 7447 | 7810 |
| 7448 | 7811 |
| 7449 class TerminationThread : public v8::base::Thread { | 7812 class TerminationThread : public v8::base::Thread { |
| 7450 public: | 7813 public: |
| 7451 explicit TerminationThread(v8::Isolate* isolate) | 7814 explicit TerminationThread(v8::Isolate* isolate) |
| 7452 : Thread(Options("terminator")), isolate_(isolate) {} | 7815 : Thread(Options("terminator")), isolate_(isolate) {} |
| 7453 | 7816 |
| 7454 virtual void Run() { | 7817 virtual void Run() { |
| 7455 terminate_requested_semaphore.Wait(); | 7818 terminate_requested_semaphore.Wait(); |
| 7456 v8::V8::TerminateExecution(isolate_); | 7819 isolate_->TerminateExecution(); |
| 7457 terminate_fired_semaphore.Signal(); | 7820 terminate_fired_semaphore.Signal(); |
| 7458 } | 7821 } |
| 7459 | 7822 |
| 7460 private: | 7823 private: |
| 7461 v8::Isolate* isolate_; | 7824 v8::Isolate* isolate_; |
| 7462 }; | 7825 }; |
| 7463 | 7826 |
| 7464 | 7827 |
| 7465 TEST(DebugBreakOffThreadTerminate) { | 7828 TEST(DebugBreakOffThreadTerminate) { |
| 7466 DebugLocalContext env; | 7829 DebugLocalContext env; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 7489 CompileRun("throw 'rejection';"); | 7852 CompileRun("throw 'rejection';"); |
| 7490 CHECK(try_catch.HasCaught()); | 7853 CHECK(try_catch.HasCaught()); |
| 7491 } | 7854 } |
| 7492 | 7855 |
| 7493 | 7856 |
| 7494 TEST(DebugPromiseInterceptedByTryCatch) { | 7857 TEST(DebugPromiseInterceptedByTryCatch) { |
| 7495 DebugLocalContext env; | 7858 DebugLocalContext env; |
| 7496 v8::Isolate* isolate = env->GetIsolate(); | 7859 v8::Isolate* isolate = env->GetIsolate(); |
| 7497 v8::HandleScope scope(isolate); | 7860 v8::HandleScope scope(isolate); |
| 7498 v8::Debug::SetDebugEventListener(&DebugEventExpectNoException); | 7861 v8::Debug::SetDebugEventListener(&DebugEventExpectNoException); |
| 7862 v8::Local<v8::Context> context = env.context(); |
| 7499 ChangeBreakOnException(false, true); | 7863 ChangeBreakOnException(false, true); |
| 7500 | 7864 |
| 7501 v8::Handle<v8::FunctionTemplate> fun = | 7865 v8::Local<v8::FunctionTemplate> fun = |
| 7502 v8::FunctionTemplate::New(isolate, TryCatchWrappedThrowCallback); | 7866 v8::FunctionTemplate::New(isolate, TryCatchWrappedThrowCallback); |
| 7503 env->Global()->Set(v8_str("fun"), fun->GetFunction()); | 7867 CHECK(env->Global() |
| 7868 ->Set(context, v8_str("fun"), |
| 7869 fun->GetFunction(context).ToLocalChecked()) |
| 7870 .FromJust()); |
| 7504 | 7871 |
| 7505 CompileRun("var p = new Promise(function(res, rej) { fun(); res(); });"); | 7872 CompileRun("var p = new Promise(function(res, rej) { fun(); res(); });"); |
| 7506 CompileRun( | 7873 CompileRun( |
| 7507 "var r;" | 7874 "var r;" |
| 7508 "p.chain(function() { r = 'resolved'; }," | 7875 "p.chain(function() { r = 'resolved'; }," |
| 7509 " function() { r = 'rejected'; });"); | 7876 " function() { r = 'rejected'; });"); |
| 7510 CHECK(CompileRun("r")->Equals(v8_str("resolved"))); | 7877 CHECK(CompileRun("r")->Equals(context, v8_str("resolved")).FromJust()); |
| 7511 } | 7878 } |
| 7512 | 7879 |
| 7513 | 7880 |
| 7514 static int exception_event_counter = 0; | 7881 static int exception_event_counter = 0; |
| 7515 | 7882 |
| 7516 | 7883 |
| 7517 static void DebugEventCountException( | 7884 static void DebugEventCountException( |
| 7518 const v8::Debug::EventDetails& event_details) { | 7885 const v8::Debug::EventDetails& event_details) { |
| 7519 v8::DebugEvent event = event_details.GetEvent(); | 7886 v8::DebugEvent event = event_details.GetEvent(); |
| 7520 if (event == v8::Exception) exception_event_counter++; | 7887 if (event == v8::Exception) exception_event_counter++; |
| 7521 } | 7888 } |
| 7522 | 7889 |
| 7523 | 7890 |
| 7524 static void ThrowCallback(const v8::FunctionCallbackInfo<v8::Value>& args) { | 7891 static void ThrowCallback(const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 7525 CompileRun("throw 'rejection';"); | 7892 CompileRun("throw 'rejection';"); |
| 7526 } | 7893 } |
| 7527 | 7894 |
| 7528 | 7895 |
| 7529 TEST(DebugPromiseRejectedByCallback) { | 7896 TEST(DebugPromiseRejectedByCallback) { |
| 7530 DebugLocalContext env; | 7897 DebugLocalContext env; |
| 7531 v8::Isolate* isolate = env->GetIsolate(); | 7898 v8::Isolate* isolate = env->GetIsolate(); |
| 7532 v8::HandleScope scope(isolate); | 7899 v8::HandleScope scope(isolate); |
| 7533 v8::Debug::SetDebugEventListener(&DebugEventCountException); | 7900 v8::Debug::SetDebugEventListener(&DebugEventCountException); |
| 7901 v8::Local<v8::Context> context = env.context(); |
| 7534 ChangeBreakOnException(false, true); | 7902 ChangeBreakOnException(false, true); |
| 7535 exception_event_counter = 0; | 7903 exception_event_counter = 0; |
| 7536 | 7904 |
| 7537 v8::Handle<v8::FunctionTemplate> fun = | 7905 v8::Local<v8::FunctionTemplate> fun = |
| 7538 v8::FunctionTemplate::New(isolate, ThrowCallback); | 7906 v8::FunctionTemplate::New(isolate, ThrowCallback); |
| 7539 env->Global()->Set(v8_str("fun"), fun->GetFunction()); | 7907 CHECK(env->Global() |
| 7908 ->Set(context, v8_str("fun"), |
| 7909 fun->GetFunction(context).ToLocalChecked()) |
| 7910 .FromJust()); |
| 7540 | 7911 |
| 7541 CompileRun("var p = new Promise(function(res, rej) { fun(); res(); });"); | 7912 CompileRun("var p = new Promise(function(res, rej) { fun(); res(); });"); |
| 7542 CompileRun( | 7913 CompileRun( |
| 7543 "var r;" | 7914 "var r;" |
| 7544 "p.chain(function() { r = 'resolved'; }," | 7915 "p.chain(function() { r = 'resolved'; }," |
| 7545 " function(e) { r = 'rejected' + e; });"); | 7916 " function(e) { r = 'rejected' + e; });"); |
| 7546 CHECK(CompileRun("r")->Equals(v8_str("rejectedrejection"))); | 7917 CHECK( |
| 7918 CompileRun("r")->Equals(context, v8_str("rejectedrejection")).FromJust()); |
| 7547 CHECK_EQ(1, exception_event_counter); | 7919 CHECK_EQ(1, exception_event_counter); |
| 7548 } | 7920 } |
| 7549 | 7921 |
| 7550 | 7922 |
| 7551 TEST(DebugBreakOnExceptionInObserveCallback) { | 7923 TEST(DebugBreakOnExceptionInObserveCallback) { |
| 7552 DebugLocalContext env; | 7924 DebugLocalContext env; |
| 7553 v8::Isolate* isolate = env->GetIsolate(); | 7925 v8::Isolate* isolate = env->GetIsolate(); |
| 7554 v8::HandleScope scope(isolate); | 7926 v8::HandleScope scope(isolate); |
| 7555 v8::Debug::SetDebugEventListener(&DebugEventCountException); | 7927 v8::Debug::SetDebugEventListener(&DebugEventCountException); |
| 7928 v8::Local<v8::Context> context = env.context(); |
| 7556 // Break on uncaught exception | 7929 // Break on uncaught exception |
| 7557 ChangeBreakOnException(false, true); | 7930 ChangeBreakOnException(false, true); |
| 7558 exception_event_counter = 0; | 7931 exception_event_counter = 0; |
| 7559 | 7932 |
| 7560 v8::Handle<v8::FunctionTemplate> fun = | 7933 v8::Local<v8::FunctionTemplate> fun = |
| 7561 v8::FunctionTemplate::New(isolate, ThrowCallback); | 7934 v8::FunctionTemplate::New(isolate, ThrowCallback); |
| 7562 env->Global()->Set(v8_str("fun"), fun->GetFunction()); | 7935 CHECK(env->Global() |
| 7936 ->Set(context, v8_str("fun"), |
| 7937 fun->GetFunction(context).ToLocalChecked()) |
| 7938 .FromJust()); |
| 7563 | 7939 |
| 7564 CompileRun( | 7940 CompileRun( |
| 7565 "var obj = {};" | 7941 "var obj = {};" |
| 7566 "var callbackRan = false;" | 7942 "var callbackRan = false;" |
| 7567 "Object.observe(obj, function() {" | 7943 "Object.observe(obj, function() {" |
| 7568 " callbackRan = true;" | 7944 " callbackRan = true;" |
| 7569 " throw Error('foo');" | 7945 " throw Error('foo');" |
| 7570 "});" | 7946 "});" |
| 7571 "obj.prop = 1"); | 7947 "obj.prop = 1"); |
| 7572 CHECK(CompileRun("callbackRan")->BooleanValue()); | 7948 CHECK(CompileRun("callbackRan")->BooleanValue(context).FromJust()); |
| 7573 CHECK_EQ(1, exception_event_counter); | 7949 CHECK_EQ(1, exception_event_counter); |
| 7574 } | 7950 } |
| 7575 | 7951 |
| 7576 | 7952 |
| 7577 static void DebugHarmonyScopingListener( | 7953 static void DebugHarmonyScopingListener( |
| 7578 const v8::Debug::EventDetails& event_details) { | 7954 const v8::Debug::EventDetails& event_details) { |
| 7579 v8::DebugEvent event = event_details.GetEvent(); | 7955 v8::DebugEvent event = event_details.GetEvent(); |
| 7580 if (event != v8::Break) return; | 7956 if (event != v8::Break) return; |
| 7581 | 7957 |
| 7582 int break_id = CcTest::i_isolate()->debug()->break_id(); | 7958 int break_id = CcTest::i_isolate()->debug()->break_id(); |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7646 CompileRun("function foo() {}; foo();"); | 8022 CompileRun("function foo() {}; foo();"); |
| 7647 --after_compile_handler_depth; | 8023 --after_compile_handler_depth; |
| 7648 } | 8024 } |
| 7649 | 8025 |
| 7650 | 8026 |
| 7651 TEST(NoInterruptsInDebugListener) { | 8027 TEST(NoInterruptsInDebugListener) { |
| 7652 DebugLocalContext env; | 8028 DebugLocalContext env; |
| 7653 v8::Debug::SetDebugEventListener(NoInterruptsOnDebugEvent); | 8029 v8::Debug::SetDebugEventListener(NoInterruptsOnDebugEvent); |
| 7654 CompileRun("void(0);"); | 8030 CompileRun("void(0);"); |
| 7655 } | 8031 } |
| OLD | NEW |