| 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 "vm/dart_api_impl.h" | 5 #include "vm/dart_api_impl.h" |
| 6 #include "bin/builtin.h" | 6 #include "bin/builtin.h" |
| 7 #include "include/dart_api.h" | 7 #include "include/dart_api.h" |
| 8 #include "include/dart_mirrors_api.h" | 8 #include "include/dart_mirrors_api.h" |
| 9 #include "include/dart_native_api.h" | 9 #include "include/dart_native_api.h" |
| 10 #include "include/dart_tools_api.h" | 10 #include "include/dart_tools_api.h" |
| 11 #include "platform/assert.h" | 11 #include "platform/assert.h" |
| 12 #include "platform/text_buffer.h" | 12 #include "platform/text_buffer.h" |
| 13 #include "platform/utils.h" | 13 #include "platform/utils.h" |
| 14 #include "vm/class_finalizer.h" | 14 #include "vm/class_finalizer.h" |
| 15 #include "vm/compiler.h" | 15 #include "vm/compiler.h" |
| 16 #include "vm/dart_api_state.h" | 16 #include "vm/dart_api_state.h" |
| 17 #include "vm/lockers.h" | 17 #include "vm/lockers.h" |
| 18 #include "vm/timeline.h" | 18 #include "vm/timeline.h" |
| 19 #include "vm/unit_test.h" | 19 #include "vm/unit_test.h" |
| 20 #include "vm/verifier.h" | 20 #include "vm/verifier.h" |
| 21 | 21 |
| 22 namespace dart { | 22 namespace dart { |
| 23 | 23 |
| 24 DECLARE_FLAG(bool, verify_acquired_data); | 24 DECLARE_FLAG(bool, verify_acquired_data); |
| 25 DECLARE_FLAG(bool, ignore_patch_signature_mismatch); | 25 DECLARE_FLAG(bool, ignore_patch_signature_mismatch); |
| 26 DECLARE_FLAG(bool, support_externalizable_strings); | |
| 27 DECLARE_FLAG(bool, use_dart_frontend); | 26 DECLARE_FLAG(bool, use_dart_frontend); |
| 28 | 27 |
| 29 #ifndef PRODUCT | 28 #ifndef PRODUCT |
| 30 | 29 |
| 31 TEST_CASE(DartAPI_ErrorHandleBasics) { | 30 TEST_CASE(DartAPI_ErrorHandleBasics) { |
| 32 const char* kScriptChars = | 31 const char* kScriptChars = |
| 33 "void testMain() {\n" | 32 "void testMain() {\n" |
| 34 " throw new Exception(\"bad news\");\n" | 33 " throw new Exception(\"bad news\");\n" |
| 35 "}\n"; | 34 "}\n"; |
| 36 | 35 |
| (...skipping 5442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5479 ASSERT(function_name != NULL); | 5478 ASSERT(function_name != NULL); |
| 5480 if (!strcmp(function_name, "NativeArgument_Create")) { | 5479 if (!strcmp(function_name, "NativeArgument_Create")) { |
| 5481 return reinterpret_cast<Dart_NativeFunction>(&NativeArgumentCreate); | 5480 return reinterpret_cast<Dart_NativeFunction>(&NativeArgumentCreate); |
| 5482 } else if (!strcmp(function_name, "NativeArgument_Access")) { | 5481 } else if (!strcmp(function_name, "NativeArgument_Access")) { |
| 5483 return reinterpret_cast<Dart_NativeFunction>(&NativeArgumentAccess); | 5482 return reinterpret_cast<Dart_NativeFunction>(&NativeArgumentAccess); |
| 5484 } | 5483 } |
| 5485 return NULL; | 5484 return NULL; |
| 5486 } | 5485 } |
| 5487 | 5486 |
| 5488 TEST_CASE(DartAPI_GetNativeArguments) { | 5487 TEST_CASE(DartAPI_GetNativeArguments) { |
| 5489 const bool saved_flag = FLAG_support_externalizable_strings; | |
| 5490 FLAG_support_externalizable_strings = true; | |
| 5491 | |
| 5492 const char* kScriptChars = | 5488 const char* kScriptChars = |
| 5493 "import 'dart:nativewrappers';" | 5489 "import 'dart:nativewrappers';" |
| 5494 "class MyObject extends NativeFieldWrapperClass2 {" | 5490 "class MyObject extends NativeFieldWrapperClass2 {" |
| 5495 " static MyObject createObject() native 'NativeArgument_Create';" | 5491 " static MyObject createObject() native 'NativeArgument_Create';" |
| 5496 " int accessFields(int arg1," | 5492 " int accessFields(int arg1," |
| 5497 " int arg2," | 5493 " int arg2," |
| 5498 " bool arg3," | 5494 " bool arg3," |
| 5499 " double arg4," | 5495 " double arg4," |
| 5500 " String arg5," | 5496 " String arg5," |
| 5501 " String arg6," | 5497 " String arg6," |
| 5502 " MyObject arg7) native 'NativeArgument_Access';" | 5498 " MyObject arg7) native 'NativeArgument_Access';" |
| 5503 "}" | 5499 "}" |
| 5504 "int testMain(String extstr) {" | 5500 "int testMain(String extstr) {" |
| 5505 " String str = 'abcdefg';" | 5501 " String str = 'abcdefg';" |
| 5506 " MyObject obj1 = MyObject.createObject();" | 5502 " MyObject obj1 = MyObject.createObject();" |
| 5507 " MyObject obj2 = MyObject.createObject();" | 5503 " MyObject obj2 = MyObject.createObject();" |
| 5508 " return obj1.accessFields(77," | 5504 " return obj1.accessFields(77," |
| 5509 " 1 << 63," | 5505 " 1 << 63," |
| 5510 " true," | 5506 " true," |
| 5511 " 3.14," | 5507 " 3.14," |
| 5512 " str," | 5508 " str," |
| 5513 " extstr," | 5509 " extstr," |
| 5514 " obj2);" | 5510 " obj2);" |
| 5515 "}"; | 5511 "}"; |
| 5516 | 5512 |
| 5517 Dart_Handle lib = TestCase::LoadTestScript( | 5513 Dart_Handle lib = TestCase::LoadTestScript( |
| 5518 kScriptChars, | 5514 kScriptChars, |
| 5519 reinterpret_cast<Dart_NativeEntryResolver>(native_args_lookup)); | 5515 reinterpret_cast<Dart_NativeEntryResolver>(native_args_lookup)); |
| 5520 | 5516 |
| 5521 intptr_t size; | 5517 const char* ascii_str = "string"; |
| 5522 Dart_Handle ascii_str = NewString("string"); | 5518 Dart_Handle extstr = Dart_NewExternalLatin1String( |
| 5523 EXPECT_VALID(ascii_str); | 5519 reinterpret_cast<const uint8_t*>(ascii_str), strlen(ascii_str), |
| 5524 EXPECT_VALID(Dart_StringStorageSize(ascii_str, &size)); | |
| 5525 uint8_t ext_ascii_str[10]; | |
| 5526 Dart_Handle extstr = Dart_MakeExternalString( | |
| 5527 ascii_str, ext_ascii_str, size, | |
| 5528 reinterpret_cast<void*>(&native_arg_str_peer), NULL); | 5520 reinterpret_cast<void*>(&native_arg_str_peer), NULL); |
| 5529 | 5521 |
| 5530 Dart_Handle args[1]; | 5522 Dart_Handle args[1]; |
| 5531 args[0] = extstr; | 5523 args[0] = extstr; |
| 5532 Dart_Handle result = Dart_Invoke(lib, NewString("testMain"), 1, args); | 5524 Dart_Handle result = Dart_Invoke(lib, NewString("testMain"), 1, args); |
| 5533 EXPECT_VALID(result); | 5525 EXPECT_VALID(result); |
| 5534 EXPECT(Dart_IsInteger(result)); | 5526 EXPECT(Dart_IsInteger(result)); |
| 5535 | |
| 5536 FLAG_support_externalizable_strings = saved_flag; | |
| 5537 } | 5527 } |
| 5538 | 5528 |
| 5539 static void NativeArgumentCounter(Dart_NativeArguments args) { | 5529 static void NativeArgumentCounter(Dart_NativeArguments args) { |
| 5540 Dart_EnterScope(); | 5530 Dart_EnterScope(); |
| 5541 int count = Dart_GetNativeArgumentCount(args); | 5531 int count = Dart_GetNativeArgumentCount(args); |
| 5542 Dart_SetReturnValue(args, Dart_NewInteger(count)); | 5532 Dart_SetReturnValue(args, Dart_NewInteger(count)); |
| 5543 Dart_ExitScope(); | 5533 Dart_ExitScope(); |
| 5544 } | 5534 } |
| 5545 | 5535 |
| 5546 static Dart_NativeFunction gnac_lookup(Dart_Handle name, | 5536 static Dart_NativeFunction gnac_lookup(Dart_Handle name, |
| (...skipping 2760 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8307 EXPECT(o2 == reinterpret_cast<void*>(&p2)); | 8297 EXPECT(o2 == reinterpret_cast<void*>(&p2)); |
| 8308 } | 8298 } |
| 8309 Dart_ExitScope(); | 8299 Dart_ExitScope(); |
| 8310 { | 8300 { |
| 8311 TransitionNativeToVM transition(thread); | 8301 TransitionNativeToVM transition(thread); |
| 8312 isolate->heap()->CollectGarbage(Heap::kOld); | 8302 isolate->heap()->CollectGarbage(Heap::kOld); |
| 8313 EXPECT_EQ(0, isolate->heap()->PeerCount()); | 8303 EXPECT_EQ(0, isolate->heap()->PeerCount()); |
| 8314 } | 8304 } |
| 8315 } | 8305 } |
| 8316 | 8306 |
| 8317 // Test API call to make strings external. | |
| 8318 static void MakeExternalCback(void* peer) { | |
| 8319 *static_cast<int*>(peer) *= 2; | |
| 8320 } | |
| 8321 | |
| 8322 TEST_CASE(DartAPI_MakeExternalString) { | |
| 8323 const bool saved_flag = FLAG_support_externalizable_strings; | |
| 8324 FLAG_support_externalizable_strings = true; | |
| 8325 | |
| 8326 static int peer8 = 40; | |
| 8327 static int peer16 = 41; | |
| 8328 static int canonical_str_peer = 42; | |
| 8329 intptr_t length = 0; | |
| 8330 intptr_t expected_length = 0; | |
| 8331 { | |
| 8332 Dart_EnterScope(); | |
| 8333 | |
| 8334 // First test some negative conditions. | |
| 8335 uint8_t data8[] = {'h', 'e', 'l', 'l', 'o'}; | |
| 8336 const char* err = "string"; | |
| 8337 Dart_Handle err_str = NewString(err); | |
| 8338 Dart_Handle ext_err_str = | |
| 8339 Dart_NewExternalLatin1String(data8, ARRAY_SIZE(data8), NULL, NULL); | |
| 8340 Dart_Handle result = Dart_MakeExternalString(Dart_Null(), data8, | |
| 8341 ARRAY_SIZE(data8), NULL, NULL); | |
| 8342 EXPECT(Dart_IsError(result)); // Null string object passed in. | |
| 8343 result = | |
| 8344 Dart_MakeExternalString(err_str, NULL, ARRAY_SIZE(data8), NULL, NULL); | |
| 8345 EXPECT(Dart_IsError(result)); // Null array pointer passed in. | |
| 8346 result = Dart_MakeExternalString(err_str, data8, 1, NULL, NULL); | |
| 8347 EXPECT(Dart_IsError(result)); // Invalid length passed in. | |
| 8348 | |
| 8349 const intptr_t kLength = 10; | |
| 8350 intptr_t size = 0; | |
| 8351 | |
| 8352 // Test with an external string. | |
| 8353 result = Dart_MakeExternalString(ext_err_str, data8, ARRAY_SIZE(data8), | |
| 8354 NULL, NULL); | |
| 8355 EXPECT(Dart_IsString(result)); | |
| 8356 EXPECT(Dart_IsExternalString(result)); | |
| 8357 | |
| 8358 // Test with an empty string. | |
| 8359 Dart_Handle empty_str = NewString(""); | |
| 8360 EXPECT(Dart_IsString(empty_str)); | |
| 8361 EXPECT(!Dart_IsExternalString(empty_str)); | |
| 8362 uint8_t ext_empty_str[kLength]; | |
| 8363 Dart_Handle str = | |
| 8364 Dart_MakeExternalString(empty_str, ext_empty_str, kLength, NULL, NULL); | |
| 8365 EXPECT(Dart_IsString(str)); | |
| 8366 EXPECT(Dart_IsString(empty_str)); | |
| 8367 EXPECT(Dart_IsStringLatin1(str)); | |
| 8368 EXPECT(Dart_IsStringLatin1(empty_str)); | |
| 8369 EXPECT(Dart_IsExternalString(str)); | |
| 8370 EXPECT(Dart_IsExternalString(empty_str)); | |
| 8371 EXPECT_VALID(Dart_StringLength(str, &length)); | |
| 8372 EXPECT_EQ(0, length); | |
| 8373 | |
| 8374 // Test with single character canonical string, it should not become | |
| 8375 // external string but the peer should be setup for it. | |
| 8376 Dart_Handle canonical_str = | |
| 8377 Api::NewHandle(thread, Symbols::New(thread, "*")); | |
| 8378 EXPECT(Dart_IsString(canonical_str)); | |
| 8379 EXPECT(!Dart_IsExternalString(canonical_str)); | |
| 8380 uint8_t ext_canonical_str[kLength]; | |
| 8381 str = Dart_MakeExternalString(canonical_str, ext_canonical_str, kLength, | |
| 8382 &canonical_str_peer, MakeExternalCback); | |
| 8383 EXPECT(Dart_IsString(str)); | |
| 8384 EXPECT(!Dart_IsExternalString(canonical_str)); | |
| 8385 EXPECT_EQ(canonical_str, str); | |
| 8386 EXPECT(Dart_IsString(canonical_str)); | |
| 8387 EXPECT(!Dart_IsExternalString(canonical_str)); | |
| 8388 void* peer; | |
| 8389 EXPECT_VALID(Dart_StringGetProperties(str, &size, &length, &peer)); | |
| 8390 EXPECT_EQ(1, size); | |
| 8391 EXPECT_EQ(1, length); | |
| 8392 EXPECT_EQ(reinterpret_cast<void*>(&canonical_str_peer), peer); | |
| 8393 | |
| 8394 // Test with a one byte ascii string. | |
| 8395 const char* ascii = "?unseen"; | |
| 8396 expected_length = strlen(ascii); | |
| 8397 Dart_Handle ascii_str = NewString(ascii); | |
| 8398 EXPECT_VALID(ascii_str); | |
| 8399 EXPECT(Dart_IsString(ascii_str)); | |
| 8400 EXPECT(Dart_IsStringLatin1(ascii_str)); | |
| 8401 EXPECT(!Dart_IsExternalString(ascii_str)); | |
| 8402 EXPECT_VALID(Dart_StringLength(ascii_str, &length)); | |
| 8403 EXPECT_EQ(expected_length, length); | |
| 8404 | |
| 8405 uint8_t ext_ascii_str[kLength]; | |
| 8406 EXPECT_VALID(Dart_StringStorageSize(ascii_str, &size)); | |
| 8407 str = Dart_MakeExternalString(ascii_str, ext_ascii_str, size, &peer8, | |
| 8408 MakeExternalCback); | |
| 8409 EXPECT(Dart_IsString(str)); | |
| 8410 EXPECT(Dart_IsString(ascii_str)); | |
| 8411 EXPECT(Dart_IsStringLatin1(str)); | |
| 8412 EXPECT(Dart_IsStringLatin1(ascii_str)); | |
| 8413 EXPECT(Dart_IsExternalString(str)); | |
| 8414 EXPECT(Dart_IsExternalString(ascii_str)); | |
| 8415 EXPECT_VALID(Dart_StringLength(str, &length)); | |
| 8416 EXPECT_EQ(expected_length, length); | |
| 8417 EXPECT_VALID(Dart_StringLength(ascii_str, &length)); | |
| 8418 EXPECT_EQ(expected_length, length); | |
| 8419 EXPECT(Dart_IdentityEquals(str, ascii_str)); | |
| 8420 for (intptr_t i = 0; i < length; i++) { | |
| 8421 EXPECT_EQ(ascii[i], ext_ascii_str[i]); | |
| 8422 } | |
| 8423 | |
| 8424 uint8_t data[] = {0xE4, 0xBA, 0x8c}; // U+4E8C. | |
| 8425 expected_length = 1; | |
| 8426 Dart_Handle utf16_str = Dart_NewStringFromUTF8(data, ARRAY_SIZE(data)); | |
| 8427 EXPECT_VALID(utf16_str); | |
| 8428 EXPECT(Dart_IsString(utf16_str)); | |
| 8429 EXPECT(!Dart_IsStringLatin1(utf16_str)); | |
| 8430 EXPECT(!Dart_IsExternalString(utf16_str)); | |
| 8431 EXPECT_VALID(Dart_StringLength(utf16_str, &length)); | |
| 8432 EXPECT_EQ(expected_length, length); | |
| 8433 | |
| 8434 // Test with a two byte string. | |
| 8435 uint16_t ext_utf16_str[kLength]; | |
| 8436 EXPECT_VALID(Dart_StringStorageSize(utf16_str, &size)); | |
| 8437 str = Dart_MakeExternalString(utf16_str, ext_utf16_str, size, &peer16, | |
| 8438 MakeExternalCback); | |
| 8439 EXPECT(Dart_IsString(str)); | |
| 8440 EXPECT(Dart_IsString(utf16_str)); | |
| 8441 EXPECT(!Dart_IsStringLatin1(str)); | |
| 8442 EXPECT(!Dart_IsStringLatin1(utf16_str)); | |
| 8443 EXPECT(Dart_IsExternalString(str)); | |
| 8444 EXPECT(Dart_IsExternalString(utf16_str)); | |
| 8445 EXPECT_VALID(Dart_StringLength(str, &length)); | |
| 8446 EXPECT_EQ(expected_length, length); | |
| 8447 EXPECT_VALID(Dart_StringLength(utf16_str, &length)); | |
| 8448 EXPECT_EQ(expected_length, length); | |
| 8449 EXPECT(Dart_IdentityEquals(str, utf16_str)); | |
| 8450 for (intptr_t i = 0; i < length; i++) { | |
| 8451 EXPECT_EQ(0x4e8c, ext_utf16_str[i]); | |
| 8452 } | |
| 8453 | |
| 8454 Zone* zone = thread->zone(); | |
| 8455 // Test with a symbol (hash value should be preserved on externalization). | |
| 8456 const char* symbol_ascii = "?unseen"; | |
| 8457 expected_length = strlen(symbol_ascii); | |
| 8458 Dart_Handle symbol_str = Api::NewHandle( | |
| 8459 thread, Symbols::New(thread, symbol_ascii, expected_length)); | |
| 8460 EXPECT_VALID(symbol_str); | |
| 8461 EXPECT(Dart_IsString(symbol_str)); | |
| 8462 EXPECT(Dart_IsStringLatin1(symbol_str)); | |
| 8463 EXPECT(!Dart_IsExternalString(symbol_str)); | |
| 8464 EXPECT_VALID(Dart_StringLength(symbol_str, &length)); | |
| 8465 EXPECT_EQ(expected_length, length); | |
| 8466 EXPECT(Api::UnwrapStringHandle(zone, symbol_str).HasHash()); | |
| 8467 | |
| 8468 uint8_t ext_symbol_ascii[kLength]; | |
| 8469 EXPECT_VALID(Dart_StringStorageSize(symbol_str, &size)); | |
| 8470 str = Dart_MakeExternalString(symbol_str, ext_symbol_ascii, size, &peer8, | |
| 8471 MakeExternalCback); | |
| 8472 EXPECT(Api::UnwrapStringHandle(zone, str).HasHash()); | |
| 8473 EXPECT(Api::UnwrapStringHandle(zone, str).Hash() == | |
| 8474 Api::UnwrapStringHandle(zone, symbol_str).Hash()); | |
| 8475 EXPECT(Dart_IsString(str)); | |
| 8476 EXPECT(Dart_IsString(symbol_str)); | |
| 8477 EXPECT(Dart_IsStringLatin1(str)); | |
| 8478 EXPECT(Dart_IsStringLatin1(symbol_str)); | |
| 8479 EXPECT(Dart_IsExternalString(str)); | |
| 8480 EXPECT(Dart_IsExternalString(symbol_str)); | |
| 8481 EXPECT_VALID(Dart_StringLength(str, &length)); | |
| 8482 EXPECT_EQ(expected_length, length); | |
| 8483 EXPECT_VALID(Dart_StringLength(symbol_str, &length)); | |
| 8484 EXPECT_EQ(expected_length, length); | |
| 8485 EXPECT(Dart_IdentityEquals(str, symbol_str)); | |
| 8486 for (intptr_t i = 0; i < length; i++) { | |
| 8487 EXPECT_EQ(symbol_ascii[i], ext_symbol_ascii[i]); | |
| 8488 } | |
| 8489 | |
| 8490 Dart_ExitScope(); | |
| 8491 } | |
| 8492 EXPECT_EQ(40, peer8); | |
| 8493 EXPECT_EQ(41, peer16); | |
| 8494 EXPECT_EQ(42, canonical_str_peer); | |
| 8495 { | |
| 8496 TransitionNativeToVM transition(thread); | |
| 8497 Isolate::Current()->heap()->CollectAllGarbage(); | |
| 8498 GCTestHelper::WaitForGCTasks(); | |
| 8499 } | |
| 8500 EXPECT_EQ(80, peer8); | |
| 8501 EXPECT_EQ(82, peer16); | |
| 8502 EXPECT_EQ(42, canonical_str_peer); // "*" Symbol is not removed on GC. | |
| 8503 | |
| 8504 FLAG_support_externalizable_strings = saved_flag; | |
| 8505 } | |
| 8506 | |
| 8507 TEST_CASE(DartAPI_ExternalizeConstantStrings) { | |
| 8508 const bool saved_flag = FLAG_support_externalizable_strings; | |
| 8509 FLAG_support_externalizable_strings = true; | |
| 8510 | |
| 8511 const char* kScriptChars = | |
| 8512 "String testMain() {\n" | |
| 8513 " return 'constant string';\n" | |
| 8514 "}\n"; | |
| 8515 | |
| 8516 Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL); | |
| 8517 Dart_Handle result = Dart_Invoke(lib, NewString("testMain"), 0, NULL); | |
| 8518 const char* expected_str = "constant string"; | |
| 8519 const intptr_t kExpectedLen = 15; | |
| 8520 uint8_t ext_str[kExpectedLen]; | |
| 8521 Dart_Handle str = | |
| 8522 Dart_MakeExternalString(result, ext_str, kExpectedLen, NULL, NULL); | |
| 8523 | |
| 8524 EXPECT(Dart_IsExternalString(str)); | |
| 8525 for (intptr_t i = 0; i < kExpectedLen; i++) { | |
| 8526 EXPECT_EQ(expected_str[i], ext_str[i]); | |
| 8527 } | |
| 8528 | |
| 8529 FLAG_support_externalizable_strings = saved_flag; | |
| 8530 } | |
| 8531 | |
| 8532 TEST_CASE(DartAPI_LazyLoadDeoptimizes) { | 8307 TEST_CASE(DartAPI_LazyLoadDeoptimizes) { |
| 8533 const char* kLoadFirst = | 8308 const char* kLoadFirst = |
| 8534 "library L;\n" | 8309 "library L;\n" |
| 8535 "start(a) {\n" | 8310 "start(a) {\n" |
| 8536 " var obj = (a == 1) ? createB() : new A();\n" | 8311 " var obj = (a == 1) ? createB() : new A();\n" |
| 8537 " for (int i = 0; i < 4000; i++) {\n" | 8312 " for (int i = 0; i < 4000; i++) {\n" |
| 8538 " var res = obj.foo();\n" | 8313 " var res = obj.foo();\n" |
| 8539 " if (a == 1) { if (res != 1) throw 'Error'; }\n" | 8314 " if (a == 1) { if (res != 1) throw 'Error'; }\n" |
| 8540 " else if (res != 2) throw 'Error'; \n" | 8315 " else if (res != 2) throw 'Error'; \n" |
| 8541 " }\n" | 8316 " }\n" |
| (...skipping 22 matching lines...) Expand all Loading... |
| 8564 Dart_Handle url = NewString(TestCase::url()); | 8339 Dart_Handle url = NewString(TestCase::url()); |
| 8565 Dart_LoadSource(TestCase::lib(), url, Dart_Null(), source, 0, 0); | 8340 Dart_LoadSource(TestCase::lib(), url, Dart_Null(), source, 0, 0); |
| 8566 result = Dart_FinalizeLoading(false); | 8341 result = Dart_FinalizeLoading(false); |
| 8567 EXPECT_VALID(result); | 8342 EXPECT_VALID(result); |
| 8568 | 8343 |
| 8569 dart_args[0] = Dart_NewInteger(1); | 8344 dart_args[0] = Dart_NewInteger(1); |
| 8570 result = Dart_Invoke(lib1, NewString("start"), 1, dart_args); | 8345 result = Dart_Invoke(lib1, NewString("start"), 1, dart_args); |
| 8571 EXPECT_VALID(result); | 8346 EXPECT_VALID(result); |
| 8572 } | 8347 } |
| 8573 | 8348 |
| 8574 // Test external strings and optimized code. | |
| 8575 static void ExternalStringDeoptimize_Finalize(void* peer) { | |
| 8576 delete[] reinterpret_cast<char*>(peer); | |
| 8577 } | |
| 8578 | |
| 8579 static void A_change_str_native(Dart_NativeArguments args) { | |
| 8580 Dart_EnterScope(); | |
| 8581 Dart_Handle str = Dart_GetNativeArgument(args, 0); | |
| 8582 EXPECT(Dart_IsString(str)); | |
| 8583 void* peer; | |
| 8584 Dart_Handle str_arg = Dart_GetNativeStringArgument(args, 0, &peer); | |
| 8585 EXPECT(Dart_IsString(str_arg)); | |
| 8586 EXPECT(!peer); | |
| 8587 intptr_t size = 0; | |
| 8588 EXPECT_VALID(Dart_StringStorageSize(str, &size)); | |
| 8589 intptr_t arg_size = 0; | |
| 8590 EXPECT_VALID(Dart_StringStorageSize(str_arg, &arg_size)); | |
| 8591 EXPECT_EQ(size, arg_size); | |
| 8592 char* str_data = new char[size]; | |
| 8593 Dart_Handle result = Dart_MakeExternalString( | |
| 8594 str, str_data, size, str_data, &ExternalStringDeoptimize_Finalize); | |
| 8595 EXPECT_VALID(result); | |
| 8596 EXPECT(Dart_IsExternalString(result)); | |
| 8597 Dart_ExitScope(); | |
| 8598 } | |
| 8599 | |
| 8600 static Dart_NativeFunction ExternalStringDeoptimize_native_lookup( | |
| 8601 Dart_Handle name, | |
| 8602 int argument_count, | |
| 8603 bool* auto_setup_scope) { | |
| 8604 ASSERT(auto_setup_scope != NULL); | |
| 8605 *auto_setup_scope = true; | |
| 8606 return reinterpret_cast<Dart_NativeFunction>(&A_change_str_native); | |
| 8607 } | |
| 8608 | |
| 8609 // Do not use guarding mechanism on externalizable classes, since their class | |
| 8610 // can change on the fly, | |
| 8611 TEST_CASE(DartAPI_GuardExternalizedString) { | |
| 8612 const bool saved_flag = FLAG_support_externalizable_strings; | |
| 8613 FLAG_support_externalizable_strings = true; | |
| 8614 | |
| 8615 const char* kScriptChars = | |
| 8616 "main() {\n" | |
| 8617 " var a = new A('hello');\n" | |
| 8618 " var res = runOne(a);\n" | |
| 8619 " if (res != 10640000) return -1;\n" | |
| 8620 " change_str(a.f);\n" | |
| 8621 " res = runOne(a);\n" | |
| 8622 " return res;\n" | |
| 8623 "}\n" | |
| 8624 "runOne(a) {\n" | |
| 8625 " var sum = 0;\n" | |
| 8626 " for (int i = 0; i < 20000; i++) {\n" | |
| 8627 " for (int j = 0; j < a.f.length; j++) {\n" | |
| 8628 " sum += a.f.codeUnitAt(j);\n" | |
| 8629 " }\n" | |
| 8630 " }\n" | |
| 8631 " return sum;\n" | |
| 8632 "}\n" | |
| 8633 "class A {\n" | |
| 8634 " var f;\n" | |
| 8635 " A(this.f);\n" | |
| 8636 "}\n" | |
| 8637 "change_str(String s) native 'A_change_str';\n" | |
| 8638 ""; | |
| 8639 Dart_Handle lib = TestCase::LoadTestScript( | |
| 8640 kScriptChars, &ExternalStringDeoptimize_native_lookup); | |
| 8641 Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL); | |
| 8642 int64_t value = 0; | |
| 8643 result = Dart_IntegerToInt64(result, &value); | |
| 8644 EXPECT_VALID(result); | |
| 8645 EXPECT_EQ(10640000, value); | |
| 8646 | |
| 8647 FLAG_support_externalizable_strings = saved_flag; | |
| 8648 } | |
| 8649 | |
| 8650 TEST_CASE(DartAPI_ExternalStringDeoptimize) { | |
| 8651 const bool saved_flag = FLAG_support_externalizable_strings; | |
| 8652 FLAG_support_externalizable_strings = true; | |
| 8653 | |
| 8654 const char* kScriptChars = | |
| 8655 "String str = 'A';\n" | |
| 8656 "class A {\n" | |
| 8657 " static change_str(String s) native 'A_change_str';\n" | |
| 8658 "}\n" | |
| 8659 "sum_chars(String s, bool b) {\n" | |
| 8660 " var result = 0;\n" | |
| 8661 " for (var i = 0; i < s.length; i++) {\n" | |
| 8662 " if (b && i == 0) A.change_str(str);\n" | |
| 8663 " result += s.codeUnitAt(i);" | |
| 8664 " }\n" | |
| 8665 " return result;\n" | |
| 8666 "}\n" | |
| 8667 "main() {\n" | |
| 8668 " str = '$str$str';\n" | |
| 8669 " for (var i = 0; i < 2000; i++) sum_chars(str, false);\n" | |
| 8670 " var x = sum_chars(str, false);\n" | |
| 8671 " var y = sum_chars(str, true);\n" | |
| 8672 " return x + y;\n" | |
| 8673 "}\n"; | |
| 8674 Dart_Handle lib = TestCase::LoadTestScript( | |
| 8675 kScriptChars, &ExternalStringDeoptimize_native_lookup); | |
| 8676 Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL); | |
| 8677 int64_t value = 0; | |
| 8678 result = Dart_IntegerToInt64(result, &value); | |
| 8679 EXPECT_VALID(result); | |
| 8680 EXPECT_EQ(260, value); | |
| 8681 | |
| 8682 FLAG_support_externalizable_strings = saved_flag; | |
| 8683 } | |
| 8684 | |
| 8685 TEST_CASE(DartAPI_ExternalStringPolymorphicDeoptimize) { | |
| 8686 const bool saved_flag = FLAG_support_externalizable_strings; | |
| 8687 FLAG_support_externalizable_strings = true; | |
| 8688 | |
| 8689 const char* kScriptChars = | |
| 8690 "const strA = 'AAAA';\n" | |
| 8691 "class A {\n" | |
| 8692 " static change_str(String s) native 'A_change_str';\n" | |
| 8693 "}\n" | |
| 8694 "compare(a, b, [i = 0]) {\n" | |
| 8695 " return a.codeUnitAt(i) == b.codeUnitAt(i);\n" | |
| 8696 "}\n" | |
| 8697 "compareA(b, [i = 0]) {\n" | |
| 8698 " return compare(strA, b, i);\n" | |
| 8699 "}\n" | |
| 8700 "main() {\n" | |
| 8701 " var externalA = 'AA' + 'AA';\n" | |
| 8702 " A.change_str(externalA);\n" | |
| 8703 " compare('AA' + 'AA', strA);\n" | |
| 8704 " compare(externalA, strA);\n" | |
| 8705 " for (var i = 0; i < 10000; i++) compareA(strA);\n" | |
| 8706 " A.change_str(strA);\n" | |
| 8707 " return compareA('AA' + 'AA');\n" | |
| 8708 "}\n"; | |
| 8709 Dart_Handle lib = TestCase::LoadTestScript( | |
| 8710 kScriptChars, &ExternalStringDeoptimize_native_lookup); | |
| 8711 Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL); | |
| 8712 EXPECT_VALID(result); | |
| 8713 bool value = false; | |
| 8714 result = Dart_BooleanValue(result, &value); | |
| 8715 EXPECT_VALID(result); | |
| 8716 EXPECT(value); | |
| 8717 | |
| 8718 FLAG_support_externalizable_strings = saved_flag; | |
| 8719 } | |
| 8720 | |
| 8721 TEST_CASE(DartAPI_ExternalStringLoadElimination) { | |
| 8722 const bool saved_flag = FLAG_support_externalizable_strings; | |
| 8723 FLAG_support_externalizable_strings = true; | |
| 8724 | |
| 8725 const char* kScriptChars = | |
| 8726 "class A {\n" | |
| 8727 " static change_str(String s) native 'A_change_str';\n" | |
| 8728 "}\n" | |
| 8729 "double_char0(str) {\n" | |
| 8730 " return str.codeUnitAt(0) + str.codeUnitAt(0);\n" | |
| 8731 "}\n" | |
| 8732 "main() {\n" | |
| 8733 " var externalA = 'AA' + 'AA';\n" | |
| 8734 " A.change_str(externalA);\n" | |
| 8735 " for (var i = 0; i < 10000; i++) double_char0(externalA);\n" | |
| 8736 " var result = double_char0(externalA);\n" | |
| 8737 " return result == 130;\n" | |
| 8738 "}\n"; | |
| 8739 Dart_Handle lib = TestCase::LoadTestScript( | |
| 8740 kScriptChars, &ExternalStringDeoptimize_native_lookup); | |
| 8741 Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL); | |
| 8742 EXPECT_VALID(result); | |
| 8743 bool value = false; | |
| 8744 result = Dart_BooleanValue(result, &value); | |
| 8745 EXPECT_VALID(result); | |
| 8746 EXPECT(value); | |
| 8747 | |
| 8748 FLAG_support_externalizable_strings = saved_flag; | |
| 8749 } | |
| 8750 | |
| 8751 TEST_CASE(DartAPI_ExternalStringGuardFieldDeoptimize) { | |
| 8752 const bool saved_flag = FLAG_support_externalizable_strings; | |
| 8753 FLAG_support_externalizable_strings = true; | |
| 8754 | |
| 8755 const char* kScriptChars = | |
| 8756 "const strA = 'AAAA';\n" | |
| 8757 "class A {\n" | |
| 8758 " static change_str(String s) native 'A_change_str';\n" | |
| 8759 "}\n" | |
| 8760 "class G { var f = 'A'; }\n" | |
| 8761 "final guard = new G();\n" | |
| 8762 "var shouldExternalize = false;\n" | |
| 8763 "ext() { if (shouldExternalize) A.change_str(strA); }\n" | |
| 8764 "compare(a, b, [i = 0]) {\n" | |
| 8765 " guard.f = a;\n" | |
| 8766 " ext();" | |
| 8767 " return a.codeUnitAt(i) == b.codeUnitAt(i);\n" | |
| 8768 "}\n" | |
| 8769 "compareA(b, [i = 0]) {\n" | |
| 8770 " return compare(strA, b, i);\n" | |
| 8771 "}\n" | |
| 8772 "main() {\n" | |
| 8773 " var externalA = 'AA' + 'AA';\n" | |
| 8774 " A.change_str(externalA);\n" | |
| 8775 " compare('AA' + 'AA', strA);\n" | |
| 8776 " for (var i = 0; i < 10000; i++) compareA(strA);\n" | |
| 8777 " shouldExternalize = true;\n" | |
| 8778 " return compareA('AA' + 'AA');\n" | |
| 8779 "}\n"; | |
| 8780 Dart_Handle lib = TestCase::LoadTestScript( | |
| 8781 kScriptChars, &ExternalStringDeoptimize_native_lookup); | |
| 8782 Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL); | |
| 8783 EXPECT_VALID(result); | |
| 8784 bool value = false; | |
| 8785 result = Dart_BooleanValue(result, &value); | |
| 8786 EXPECT_VALID(result); | |
| 8787 EXPECT(value); | |
| 8788 | |
| 8789 FLAG_support_externalizable_strings = saved_flag; | |
| 8790 } | |
| 8791 | |
| 8792 TEST_CASE(DartAPI_ExternalStringStaticFieldDeoptimize) { | |
| 8793 const bool saved_flag = FLAG_support_externalizable_strings; | |
| 8794 FLAG_support_externalizable_strings = true; | |
| 8795 | |
| 8796 const char* kScriptChars = | |
| 8797 "const strA = 'AAAA';\n" | |
| 8798 "class A {\n" | |
| 8799 " static change_str(String s) native 'A_change_str';\n" | |
| 8800 "}\n" | |
| 8801 "class G { static final f = strA; }\n" | |
| 8802 "compare(a, b, [i = 0]) {\n" | |
| 8803 " return a.codeUnitAt(i) == b.codeUnitAt(i);\n" | |
| 8804 "}\n" | |
| 8805 "compareA(b, [i = 0]) {\n" | |
| 8806 " return compare(G.f, b, i);\n" | |
| 8807 "}\n" | |
| 8808 "main() {\n" | |
| 8809 " var externalA = 'AA' + 'AA';\n" | |
| 8810 " A.change_str(externalA);\n" | |
| 8811 " compare('AA' + 'AA', strA);\n" | |
| 8812 " for (var i = 0; i < 10000; i++) compareA(strA);\n" | |
| 8813 " A.change_str(G.f);" | |
| 8814 " return compareA('AA' + 'AA');\n" | |
| 8815 "}\n"; | |
| 8816 Dart_Handle lib = TestCase::LoadTestScript( | |
| 8817 kScriptChars, &ExternalStringDeoptimize_native_lookup); | |
| 8818 Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL); | |
| 8819 EXPECT_VALID(result); | |
| 8820 bool value = false; | |
| 8821 result = Dart_BooleanValue(result, &value); | |
| 8822 EXPECT_VALID(result); | |
| 8823 EXPECT(value); | |
| 8824 | |
| 8825 FLAG_support_externalizable_strings = saved_flag; | |
| 8826 } | |
| 8827 | |
| 8828 TEST_CASE(DartAPI_ExternalStringTrimDoubleParse) { | |
| 8829 const bool saved_flag = FLAG_support_externalizable_strings; | |
| 8830 FLAG_support_externalizable_strings = true; | |
| 8831 | |
| 8832 const char* kScriptChars = | |
| 8833 "String str = 'A';\n" | |
| 8834 "class A {\n" | |
| 8835 " static change_str(String s) native 'A_change_str';\n" | |
| 8836 "}\n" | |
| 8837 "main() {\n" | |
| 8838 " var externalOneByteString = ' 0.2\\xA0 ';\n;" | |
| 8839 " A.change_str(externalOneByteString);\n" | |
| 8840 " var externalTwoByteString = ' \\u{2029}0.6\\u{2029} ';\n" | |
| 8841 " A.change_str(externalTwoByteString);\n" | |
| 8842 " var x = double.parse(externalOneByteString);\n" | |
| 8843 " var y = double.parse(externalTwoByteString);\n" | |
| 8844 " return ((x + y) * 10).toInt();\n" | |
| 8845 "}\n"; | |
| 8846 Dart_Handle lib = TestCase::LoadTestScript( | |
| 8847 kScriptChars, &ExternalStringDeoptimize_native_lookup); | |
| 8848 Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL); | |
| 8849 int64_t value = 0; | |
| 8850 result = Dart_IntegerToInt64(result, &value); | |
| 8851 EXPECT_VALID(result); | |
| 8852 EXPECT_EQ(8, value); | |
| 8853 | |
| 8854 FLAG_support_externalizable_strings = saved_flag; | |
| 8855 } | |
| 8856 | |
| 8857 TEST_CASE(DartAPI_ExternalStringDoubleParse) { | |
| 8858 const bool saved_flag = FLAG_support_externalizable_strings; | |
| 8859 FLAG_support_externalizable_strings = true; | |
| 8860 | |
| 8861 const char* kScriptChars = | |
| 8862 "String str = 'A';\n" | |
| 8863 "class A {\n" | |
| 8864 " static change_str(String s) native 'A_change_str';\n" | |
| 8865 "}\n" | |
| 8866 "main() {\n" | |
| 8867 " var externalOneByteString = '0.2';\n;" | |
| 8868 " A.change_str(externalOneByteString);\n" | |
| 8869 " var externalTwoByteString = '0.6';\n" | |
| 8870 " A.change_str(externalTwoByteString);\n" | |
| 8871 " var x = double.parse(externalOneByteString);\n" | |
| 8872 " var y = double.parse(externalTwoByteString);\n" | |
| 8873 " return ((x + y) * 10).toInt();\n" | |
| 8874 "}\n"; | |
| 8875 Dart_Handle lib = TestCase::LoadTestScript( | |
| 8876 kScriptChars, &ExternalStringDeoptimize_native_lookup); | |
| 8877 Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL); | |
| 8878 int64_t value = 0; | |
| 8879 result = Dart_IntegerToInt64(result, &value); | |
| 8880 EXPECT_VALID(result); | |
| 8881 EXPECT_EQ(8, value); | |
| 8882 | |
| 8883 FLAG_support_externalizable_strings = saved_flag; | |
| 8884 } | |
| 8885 | |
| 8886 TEST_CASE(DartAPI_ExternalStringIndexOf) { | 8349 TEST_CASE(DartAPI_ExternalStringIndexOf) { |
| 8887 const char* kScriptChars = | 8350 const char* kScriptChars = |
| 8888 "main(String pattern) {\n" | 8351 "main(String pattern) {\n" |
| 8889 " var str = 'Hello World';\n" | 8352 " var str = 'Hello World';\n" |
| 8890 " return str.indexOf(pattern);\n" | 8353 " return str.indexOf(pattern);\n" |
| 8891 "}\n"; | 8354 "}\n"; |
| 8892 Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL); | 8355 Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL); |
| 8893 | 8356 |
| 8894 uint8_t data8[] = {'W'}; | 8357 uint8_t data8[] = {'W'}; |
| 8895 Dart_Handle ext8 = | 8358 Dart_Handle ext8 = |
| (...skipping 790 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9686 EXPECT_VALID(result); | 9149 EXPECT_VALID(result); |
| 9687 result = Dart_FinalizeLoading(false); | 9150 result = Dart_FinalizeLoading(false); |
| 9688 EXPECT_VALID(result); | 9151 EXPECT_VALID(result); |
| 9689 result = Dart_Invoke(lib, NewString("foozoo"), 0, NULL); | 9152 result = Dart_Invoke(lib, NewString("foozoo"), 0, NULL); |
| 9690 EXPECT(Dart_IsError(result)); | 9153 EXPECT(Dart_IsError(result)); |
| 9691 } | 9154 } |
| 9692 | 9155 |
| 9693 #endif // !PRODUCT | 9156 #endif // !PRODUCT |
| 9694 | 9157 |
| 9695 } // namespace dart | 9158 } // namespace dart |
| OLD | NEW |