| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "platform/globals.h" | 5 #include "platform/globals.h" |
| 6 | 6 |
| 7 #include "vm/assembler.h" | 7 #include "vm/assembler.h" |
| 8 #include "vm/bigint_operations.h" | 8 #include "vm/bigint_operations.h" |
| 9 #include "vm/class_finalizer.h" | 9 #include "vm/class_finalizer.h" |
| 10 #include "vm/dart_api_impl.h" | 10 #include "vm/dart_api_impl.h" |
| (...skipping 4196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4207 ObjectAccumulator acc(&objects); | 4207 ObjectAccumulator acc(&objects); |
| 4208 heap->IterateObjects(&acc); | 4208 heap->IterateObjects(&acc); |
| 4209 for (intptr_t i = 0; i < objects.length(); ++i) { | 4209 for (intptr_t i = 0; i < objects.length(); ++i) { |
| 4210 JSONStream js; | 4210 JSONStream js; |
| 4211 objects[i]->PrintJSON(&js, false); | 4211 objects[i]->PrintJSON(&js, false); |
| 4212 EXPECT_SUBSTRING("\"type\":", js.ToCString()); | 4212 EXPECT_SUBSTRING("\"type\":", js.ToCString()); |
| 4213 } | 4213 } |
| 4214 } | 4214 } |
| 4215 | 4215 |
| 4216 | 4216 |
| 4217 // Elide a substring which starts with some prefix and ends with a ". |
| 4218 // |
| 4219 // This is used to remove non-deterministic or fragile substrings from |
| 4220 // JSON output. |
| 4221 // |
| 4222 // For example: |
| 4223 // |
| 4224 // prefix = "classes" |
| 4225 // in = "\"id\":\"classes/46\"" |
| 4226 // |
| 4227 // Yields: |
| 4228 // |
| 4229 // out = "\"id\":\"\"" |
| 4230 // |
| 4231 static void elideSubstring(const char* prefix, const char* in, char* out) { |
| 4232 char* pos = strstr(in, prefix); |
| 4233 while (pos != NULL) { |
| 4234 // Copy up to pos into the output buffer. |
| 4235 while (in < pos) { |
| 4236 *out++ = *in++; |
| 4237 } |
| 4238 |
| 4239 // Skip to the close quote. |
| 4240 in += strcspn(in, "\""); |
| 4241 pos = strstr(in, prefix); |
| 4242 } |
| 4243 // Copy the remainder of in to out. |
| 4244 while (*in != '\0') { |
| 4245 *out++ = *in++; |
| 4246 } |
| 4247 *out = '\0'; |
| 4248 } |
| 4249 |
| 4250 |
| 4251 TEST_CASE(PrintJSONPrimitives) { |
| 4252 char buffer[1024]; |
| 4253 Isolate* isolate = Isolate::Current(); |
| 4254 |
| 4255 // Class reference |
| 4256 { |
| 4257 JSONStream js; |
| 4258 Class& cls = Class::Handle(isolate->object_store()->bool_class()); |
| 4259 cls.PrintJSON(&js, true); |
| 4260 elideSubstring("classes", js.ToCString(), buffer); |
| 4261 EXPECT_STREQ( |
| 4262 "{\"type\":\"@Class\",\"id\":\"\",\"name\":\"bool\"}", |
| 4263 buffer); |
| 4264 } |
| 4265 // Function reference |
| 4266 { |
| 4267 JSONStream js; |
| 4268 Class& cls = Class::Handle(isolate->object_store()->bool_class()); |
| 4269 const String& func_name = String::Handle(String::New("toString")); |
| 4270 Function& func = Function::Handle(cls.LookupFunction(func_name)); |
| 4271 ASSERT(!func.IsNull()); |
| 4272 func.PrintJSON(&js, true); |
| 4273 elideSubstring("classes", js.ToCString(), buffer); |
| 4274 EXPECT_STREQ( |
| 4275 "{\"type\":\"@Function\",\"id\":\"\",\"name\":\"toString\"," |
| 4276 "\"owningClass\":{\"type\":\"@Class\",\"id\":\"\",\"name\":\"bool\"}," |
| 4277 "\"kind\":\"kRegularFunction\"}", |
| 4278 buffer); |
| 4279 } |
| 4280 // Library reference |
| 4281 { |
| 4282 JSONStream js; |
| 4283 Library& lib = Library::Handle(isolate->object_store()->core_library()); |
| 4284 lib.PrintJSON(&js, true); |
| 4285 elideSubstring("libraries", js.ToCString(), buffer); |
| 4286 EXPECT_STREQ( |
| 4287 "{\"type\":\"@Library\",\"id\":\"\",\"name\":\"dart.core\"," |
| 4288 "\"url\":\"dart:core\"}", |
| 4289 buffer); |
| 4290 } |
| 4291 // Bool reference |
| 4292 { |
| 4293 JSONStream js; |
| 4294 Bool::True().PrintJSON(&js, true); |
| 4295 elideSubstring("classes", js.ToCString(), buffer); |
| 4296 EXPECT_STREQ("{\"type\":\"@Bool\",\"id\":\"objects\\/bool-true\"," |
| 4297 "\"class\":{\"type\":\"@Class\",\"id\":\"\"," |
| 4298 "\"name\":\"bool\"},\"valueAsString\":\"true\"}", |
| 4299 buffer); |
| 4300 } |
| 4301 // Smi reference |
| 4302 { |
| 4303 JSONStream js; |
| 4304 const Integer& smi = Integer::Handle(Integer::New(7)); |
| 4305 smi.PrintJSON(&js, true); |
| 4306 elideSubstring("classes", js.ToCString(), buffer); |
| 4307 elideSubstring("_Smi@", buffer, buffer); |
| 4308 EXPECT_STREQ( |
| 4309 "{\"type\":\"@Smi\"," |
| 4310 "\"class\":{\"type\":\"@Class\",\"id\":\"\",\"name\":\"_Smi\"," |
| 4311 "\"vmName\":\"\"}," |
| 4312 "\"id\":\"objects\\/int-7\",\"valueAsString\":\"7\"}", |
| 4313 buffer); |
| 4314 } |
| 4315 // Mint reference |
| 4316 { |
| 4317 JSONStream js; |
| 4318 const Integer& smi = Integer::Handle(Integer::New(Mint::kMinValue)); |
| 4319 smi.PrintJSON(&js, true); |
| 4320 elideSubstring("classes", js.ToCString(), buffer); |
| 4321 elideSubstring("objects", buffer, buffer); |
| 4322 elideSubstring("_Mint@", buffer, buffer); |
| 4323 EXPECT_STREQ( |
| 4324 "{\"type\":\"@Mint\"," |
| 4325 "\"class\":{\"type\":\"@Class\",\"id\":\"\",\"name\":\"_Mint\"," |
| 4326 "\"vmName\":\"\"}," |
| 4327 "\"id\":\"\",\"valueAsString\":\"-9223372036854775808\"}", |
| 4328 buffer); |
| 4329 } |
| 4330 // Bigint reference |
| 4331 { |
| 4332 JSONStream js; |
| 4333 const String& bigint_str = |
| 4334 String::Handle(String::New("44444444444444444444444444444444")); |
| 4335 const Integer& bigint = Integer::Handle(Integer::New(bigint_str)); |
| 4336 bigint.PrintJSON(&js, true); |
| 4337 elideSubstring("classes", js.ToCString(), buffer); |
| 4338 elideSubstring("objects", buffer, buffer); |
| 4339 elideSubstring("_Bigint@", buffer, buffer); |
| 4340 EXPECT_STREQ( |
| 4341 "{\"type\":\"@Bigint\"," |
| 4342 "\"class\":{\"type\":\"@Class\",\"id\":\"\",\"name\":\"_Bigint\"," |
| 4343 "\"vmName\":\"\"}," |
| 4344 "\"id\":\"\",\"valueAsString\":\"44444444444444444444444444444444\"}", |
| 4345 buffer); |
| 4346 } |
| 4347 // Double reference |
| 4348 { |
| 4349 JSONStream js; |
| 4350 const Double& dub = Double::Handle(Double::New(0.1234)); |
| 4351 dub.PrintJSON(&js, true); |
| 4352 elideSubstring("classes", js.ToCString(), buffer); |
| 4353 elideSubstring("objects", buffer, buffer); |
| 4354 elideSubstring("_Double@", buffer, buffer); |
| 4355 EXPECT_STREQ( |
| 4356 "{\"type\":\"@Double\"," |
| 4357 "\"class\":{\"type\":\"@Class\",\"id\":\"\",\"name\":\"_Double\"," |
| 4358 "\"vmName\":\"\"}," |
| 4359 "\"id\":\"\",\"valueAsString\":\"0.1234\"}", |
| 4360 buffer); |
| 4361 } |
| 4362 // String reference |
| 4363 { |
| 4364 JSONStream js; |
| 4365 const String& str = String::Handle(String::New("dw")); |
| 4366 str.PrintJSON(&js, true); |
| 4367 elideSubstring("classes", js.ToCString(), buffer); |
| 4368 elideSubstring("objects", buffer, buffer); |
| 4369 elideSubstring("_OneByteString@", buffer, buffer); |
| 4370 EXPECT_STREQ( |
| 4371 "{\"type\":\"@String\"," |
| 4372 "\"class\":{\"type\":\"@Class\",\"id\":\"\"," |
| 4373 "\"name\":\"_OneByteString\",\"vmName\":\"\"}," |
| 4374 "\"id\":\"\",\"valueAsString\":\"\\\"dw\\\"\"}", |
| 4375 buffer); |
| 4376 } |
| 4377 // Array reference |
| 4378 { |
| 4379 JSONStream js; |
| 4380 const Array& array = Array::Handle(Array::New(0)); |
| 4381 array.PrintJSON(&js, true); |
| 4382 elideSubstring("classes", js.ToCString(), buffer); |
| 4383 elideSubstring("objects", buffer, buffer); |
| 4384 elideSubstring("_List@", buffer, buffer); |
| 4385 EXPECT_STREQ( |
| 4386 "{\"type\":\"@Array\"," |
| 4387 "\"class\":{\"type\":\"@Class\",\"id\":\"\",\"name\":\"_List\"," |
| 4388 "\"vmName\":\"\"}," |
| 4389 "\"id\":\"\",\"length\":0}", |
| 4390 buffer); |
| 4391 } |
| 4392 // GrowableObjectArray reference |
| 4393 { |
| 4394 JSONStream js; |
| 4395 const GrowableObjectArray& array = |
| 4396 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
| 4397 array.PrintJSON(&js, true); |
| 4398 elideSubstring("classes", js.ToCString(), buffer); |
| 4399 elideSubstring("objects", buffer, buffer); |
| 4400 elideSubstring("_GrowableList@", buffer, buffer); |
| 4401 EXPECT_STREQ( |
| 4402 "{\"type\":\"@GrowableObjectArray\"," |
| 4403 "\"class\":{\"type\":\"@Class\",\"id\":\"\",\"name\":\"_GrowableList\"," |
| 4404 "\"vmName\":\"\"},\"id\":\"\",\"length\":0}", |
| 4405 buffer); |
| 4406 } |
| 4407 // LinkedHashMap reference |
| 4408 { |
| 4409 JSONStream js; |
| 4410 const LinkedHashMap& array = LinkedHashMap::Handle(LinkedHashMap::New()); |
| 4411 array.PrintJSON(&js, true); |
| 4412 elideSubstring("classes", js.ToCString(), buffer); |
| 4413 elideSubstring("objects", buffer, buffer); |
| 4414 elideSubstring("_InternalLinkedHashMap@", buffer, buffer); |
| 4415 EXPECT_STREQ( |
| 4416 "{\"type\":\"@LinkedHashMap\"," |
| 4417 "\"class\":{\"type\":\"@Class\",\"id\":\"\"," |
| 4418 "\"name\":\"_InternalLinkedHashMap\",\"vmName\":\"\"},\"id\":\"\"}", |
| 4419 buffer); |
| 4420 } |
| 4421 // UserTag reference |
| 4422 { |
| 4423 JSONStream js; |
| 4424 Instance& tag = Instance::Handle(isolate->object_store()->default_tag()); |
| 4425 tag.PrintJSON(&js, true); |
| 4426 elideSubstring("classes", js.ToCString(), buffer); |
| 4427 elideSubstring("objects", buffer, buffer); |
| 4428 elideSubstring("_UserTag@", buffer, buffer); |
| 4429 EXPECT_STREQ( |
| 4430 "{\"type\":\"@UserTag\"," |
| 4431 "\"class\":{\"type\":\"@Class\",\"id\":\"\",\"name\":\"_UserTag\"," |
| 4432 "\"vmName\":\"\"}," |
| 4433 "\"id\":\"\"}", |
| 4434 buffer); |
| 4435 } |
| 4436 // Type reference |
| 4437 // TODO(turnidge): Add in all of the other Type siblings. |
| 4438 { |
| 4439 JSONStream js; |
| 4440 Instance& type = Instance::Handle(isolate->object_store()->bool_type()); |
| 4441 type.PrintJSON(&js, true); |
| 4442 elideSubstring("classes", js.ToCString(), buffer); |
| 4443 elideSubstring("objects", buffer, buffer); |
| 4444 elideSubstring("_Type@", buffer, buffer); |
| 4445 EXPECT_STREQ( |
| 4446 "{\"type\":\"@Type\"," |
| 4447 "\"class\":{\"type\":\"@Class\",\"id\":\"\",\"name\":\"_Type\"," |
| 4448 "\"vmName\":\"\"},\"id\":\"\"," |
| 4449 "\"typeClass\":{\"type\":\"@Class\",\"id\":\"\",\"name\":\"bool\"}," |
| 4450 "\"name\":\"bool\"}", |
| 4451 buffer); |
| 4452 } |
| 4453 // Null reference |
| 4454 { |
| 4455 JSONStream js; |
| 4456 Object::null_object().PrintJSON(&js, true); |
| 4457 EXPECT_STREQ( |
| 4458 "{\"type\":\"@Null\",\"id\":\"objects\\/null\"," |
| 4459 "\"valueAsString\":\"null\"}", |
| 4460 js.ToCString()); |
| 4461 } |
| 4462 // Sentinel reference |
| 4463 { |
| 4464 JSONStream js; |
| 4465 Object::sentinel().PrintJSON(&js, true); |
| 4466 EXPECT_STREQ( |
| 4467 "{\"type\":\"Sentinel\",\"id\":\"objects\\/not-initialized\"," |
| 4468 "\"valueAsString\":\"<not initialized>\"}", |
| 4469 js.ToCString()); |
| 4470 } |
| 4471 // Transition sentinel reference |
| 4472 { |
| 4473 JSONStream js; |
| 4474 Object::transition_sentinel().PrintJSON(&js, true); |
| 4475 EXPECT_STREQ( |
| 4476 "{\"type\":\"Sentinel\",\"id\":\"objects\\/being-initialized\"," |
| 4477 "\"valueAsString\":\"<being initialized>\"}", |
| 4478 js.ToCString()); |
| 4479 } |
| 4480 // LiteralToken reference. This is meant to be an example of a |
| 4481 // "weird" type that isn't usually returned by the VM Service except |
| 4482 // when we are doing direct heap inspection. |
| 4483 { |
| 4484 JSONStream js; |
| 4485 LiteralToken& tok = LiteralToken::Handle(LiteralToken::New()); |
| 4486 tok.PrintJSON(&js, true); |
| 4487 elideSubstring("objects", js.ToCString(), buffer); |
| 4488 EXPECT_STREQ( |
| 4489 "{\"type\":\"@LiteralToken\",\"id\":\"\"}", |
| 4490 buffer); |
| 4491 } |
| 4492 } |
| 4493 |
| 4494 |
| 4217 TEST_CASE(InstanceEquality) { | 4495 TEST_CASE(InstanceEquality) { |
| 4218 // Test that Instance::OperatorEquals can call a user-defined operator==. | 4496 // Test that Instance::OperatorEquals can call a user-defined operator==. |
| 4219 const char* kScript = | 4497 const char* kScript = |
| 4220 "class A {\n" | 4498 "class A {\n" |
| 4221 " bool operator==(A other) { return true; }\n" | 4499 " bool operator==(A other) { return true; }\n" |
| 4222 "}\n" | 4500 "}\n" |
| 4223 "main() {\n" | 4501 "main() {\n" |
| 4224 " A a = new A();\n" | 4502 " A a = new A();\n" |
| 4225 "}"; | 4503 "}"; |
| 4226 | 4504 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4259 EXPECT_VALID(h_result); | 4537 EXPECT_VALID(h_result); |
| 4260 Integer& result = Integer::Handle(); | 4538 Integer& result = Integer::Handle(); |
| 4261 result ^= Api::UnwrapHandle(h_result); | 4539 result ^= Api::UnwrapHandle(h_result); |
| 4262 String& foo = String::Handle(String::New("foo")); | 4540 String& foo = String::Handle(String::New("foo")); |
| 4263 Integer& expected = Integer::Handle(); | 4541 Integer& expected = Integer::Handle(); |
| 4264 expected ^= foo.HashCode(); | 4542 expected ^= foo.HashCode(); |
| 4265 EXPECT(result.IsIdenticalTo(expected)); | 4543 EXPECT(result.IsIdenticalTo(expected)); |
| 4266 } | 4544 } |
| 4267 | 4545 |
| 4268 } // namespace dart | 4546 } // namespace dart |
| OLD | NEW |