| 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 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 59 #include "runtime.h" | 59 #include "runtime.h" |
| 60 #include "scopeinfo.h" | 60 #include "scopeinfo.h" |
| 61 #include "smart-pointers.h" | 61 #include "smart-pointers.h" |
| 62 #include "string-search.h" | 62 #include "string-search.h" |
| 63 #include "stub-cache.h" | 63 #include "stub-cache.h" |
| 64 #include "uri.h" | 64 #include "uri.h" |
| 65 #include "v8conversions.h" | 65 #include "v8conversions.h" |
| 66 #include "v8threads.h" | 66 #include "v8threads.h" |
| 67 #include "vm-state-inl.h" | 67 #include "vm-state-inl.h" |
| 68 | 68 |
| 69 #ifdef V8_I18N_SUPPORT | |
| 70 #include "i18n.h" | |
| 71 #include "unicode/brkiter.h" | |
| 72 #include "unicode/calendar.h" | |
| 73 #include "unicode/coll.h" | |
| 74 #include "unicode/datefmt.h" | |
| 75 #include "unicode/dtfmtsym.h" | |
| 76 #include "unicode/dtptngen.h" | |
| 77 #include "unicode/locid.h" | |
| 78 #include "unicode/numfmt.h" | |
| 79 #include "unicode/numsys.h" | |
| 80 #include "unicode/smpdtfmt.h" | |
| 81 #include "unicode/timezone.h" | |
| 82 #include "unicode/uloc.h" | |
| 83 #include "unicode/uversion.h" | |
| 84 #endif | |
| 85 | |
| 86 #ifndef _STLP_VENDOR_CSTD | 69 #ifndef _STLP_VENDOR_CSTD |
| 87 // STLPort doesn't import fpclassify and isless into the std namespace. | 70 // STLPort doesn't import fpclassify and isless into the std namespace. |
| 88 using std::fpclassify; | 71 using std::fpclassify; |
| 89 using std::isless; | 72 using std::isless; |
| 90 #endif | 73 #endif |
| 91 | 74 |
| 92 namespace v8 { | 75 namespace v8 { |
| 93 namespace internal { | 76 namespace internal { |
| 94 | 77 |
| 95 | 78 |
| (...skipping 7150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7246 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberXor) { | 7229 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberXor) { |
| 7247 SealHandleScope shs(isolate); | 7230 SealHandleScope shs(isolate); |
| 7248 ASSERT(args.length() == 2); | 7231 ASSERT(args.length() == 2); |
| 7249 | 7232 |
| 7250 CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]); | 7233 CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]); |
| 7251 CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]); | 7234 CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]); |
| 7252 return isolate->heap()->NumberFromInt32(x ^ y); | 7235 return isolate->heap()->NumberFromInt32(x ^ y); |
| 7253 } | 7236 } |
| 7254 | 7237 |
| 7255 | 7238 |
| 7239 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberNot) { |
| 7240 SealHandleScope shs(isolate); |
| 7241 ASSERT(args.length() == 1); |
| 7242 |
| 7243 CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]); |
| 7244 return isolate->heap()->NumberFromInt32(~x); |
| 7245 } |
| 7246 |
| 7247 |
| 7256 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberShl) { | 7248 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberShl) { |
| 7257 SealHandleScope shs(isolate); | 7249 SealHandleScope shs(isolate); |
| 7258 ASSERT(args.length() == 2); | 7250 ASSERT(args.length() == 2); |
| 7259 | 7251 |
| 7260 CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]); | 7252 CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]); |
| 7261 CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]); | 7253 CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]); |
| 7262 return isolate->heap()->NumberFromInt32(x << (y & 0x1f)); | 7254 return isolate->heap()->NumberFromInt32(x << (y & 0x1f)); |
| 7263 } | 7255 } |
| 7264 | 7256 |
| 7265 | 7257 |
| (...skipping 1282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8548 // The top JS function is this one, the PC is somewhere in the | 8540 // The top JS function is this one, the PC is somewhere in the |
| 8549 // unoptimized code. | 8541 // unoptimized code. |
| 8550 JavaScriptFrameIterator it(isolate); | 8542 JavaScriptFrameIterator it(isolate); |
| 8551 JavaScriptFrame* frame = it.frame(); | 8543 JavaScriptFrame* frame = it.frame(); |
| 8552 ASSERT(frame->function() == *function); | 8544 ASSERT(frame->function() == *function); |
| 8553 ASSERT(frame->LookupCode() == *unoptimized); | 8545 ASSERT(frame->LookupCode() == *unoptimized); |
| 8554 ASSERT(unoptimized->contains(frame->pc())); | 8546 ASSERT(unoptimized->contains(frame->pc())); |
| 8555 | 8547 |
| 8556 // Use linear search of the unoptimized code's back edge table to find | 8548 // Use linear search of the unoptimized code's back edge table to find |
| 8557 // the AST id matching the PC. | 8549 // the AST id matching the PC. |
| 8558 uint32_t target_pc_offset = | 8550 Address start = unoptimized->instruction_start(); |
| 8559 static_cast<uint32_t>(frame->pc() - unoptimized->instruction_start()); | 8551 unsigned target_pc_offset = static_cast<unsigned>(frame->pc() - start); |
| 8552 Address table_cursor = start + unoptimized->back_edge_table_offset(); |
| 8553 uint32_t table_length = Memory::uint32_at(table_cursor); |
| 8554 table_cursor += kIntSize; |
| 8560 uint32_t loop_depth = 0; | 8555 uint32_t loop_depth = 0; |
| 8561 | 8556 for (unsigned i = 0; i < table_length; ++i) { |
| 8562 for (FullCodeGenerator::BackEdgeTableIterator back_edges(*unoptimized); | 8557 // Table entries are (AST id, pc offset) pairs. |
| 8563 !back_edges.Done(); | 8558 uint32_t pc_offset = Memory::uint32_at(table_cursor + kIntSize); |
| 8564 back_edges.Next()) { | 8559 if (pc_offset == target_pc_offset) { |
| 8565 if (back_edges.pc_offset() == target_pc_offset) { | 8560 ast_id = BailoutId(static_cast<int>(Memory::uint32_at(table_cursor))); |
| 8566 ast_id = back_edges.ast_id(); | 8561 loop_depth = Memory::uint32_at(table_cursor + 2 * kIntSize); |
| 8567 loop_depth = back_edges.loop_depth(); | |
| 8568 break; | 8562 break; |
| 8569 } | 8563 } |
| 8564 table_cursor += FullCodeGenerator::kBackEdgeEntrySize; |
| 8570 } | 8565 } |
| 8571 ASSERT(!ast_id.IsNone()); | 8566 ASSERT(!ast_id.IsNone()); |
| 8572 | |
| 8573 if (FLAG_trace_osr) { | 8567 if (FLAG_trace_osr) { |
| 8574 PrintF("[replacing on-stack at AST id %d, loop depth %d in ", | 8568 PrintF("[replacing on-stack at AST id %d, loop depth %d in ", |
| 8575 ast_id.ToInt(), loop_depth); | 8569 ast_id.ToInt(), loop_depth); |
| 8576 function->PrintName(); | 8570 function->PrintName(); |
| 8577 PrintF("]\n"); | 8571 PrintF("]\n"); |
| 8578 } | 8572 } |
| 8579 | 8573 |
| 8580 // Try to compile the optimized code. A true return value from | 8574 // Try to compile the optimized code. A true return value from |
| 8581 // CompileOptimized means that compilation succeeded, not necessarily | 8575 // CompileOptimized means that compilation succeeded, not necessarily |
| 8582 // that optimization succeeded. | 8576 // that optimization succeeded. |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8679 | 8673 |
| 8680 | 8674 |
| 8681 RUNTIME_FUNCTION(MaybeObject*, Runtime_Apply) { | 8675 RUNTIME_FUNCTION(MaybeObject*, Runtime_Apply) { |
| 8682 HandleScope scope(isolate); | 8676 HandleScope scope(isolate); |
| 8683 ASSERT(args.length() == 5); | 8677 ASSERT(args.length() == 5); |
| 8684 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, fun, 0); | 8678 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, fun, 0); |
| 8685 Handle<Object> receiver = args.at<Object>(1); | 8679 Handle<Object> receiver = args.at<Object>(1); |
| 8686 CONVERT_ARG_HANDLE_CHECKED(JSObject, arguments, 2); | 8680 CONVERT_ARG_HANDLE_CHECKED(JSObject, arguments, 2); |
| 8687 CONVERT_SMI_ARG_CHECKED(offset, 3); | 8681 CONVERT_SMI_ARG_CHECKED(offset, 3); |
| 8688 CONVERT_SMI_ARG_CHECKED(argc, 4); | 8682 CONVERT_SMI_ARG_CHECKED(argc, 4); |
| 8689 RUNTIME_ASSERT(offset >= 0); | 8683 ASSERT(offset >= 0); |
| 8690 RUNTIME_ASSERT(argc >= 0); | 8684 ASSERT(argc >= 0); |
| 8691 | 8685 |
| 8692 // If there are too many arguments, allocate argv via malloc. | 8686 // If there are too many arguments, allocate argv via malloc. |
| 8693 const int argv_small_size = 10; | 8687 const int argv_small_size = 10; |
| 8694 Handle<Object> argv_small_buffer[argv_small_size]; | 8688 Handle<Object> argv_small_buffer[argv_small_size]; |
| 8695 SmartArrayPointer<Handle<Object> > argv_large_buffer; | 8689 SmartArrayPointer<Handle<Object> > argv_large_buffer; |
| 8696 Handle<Object>* argv = argv_small_buffer; | 8690 Handle<Object>* argv = argv_small_buffer; |
| 8697 if (argc > argv_small_size) { | 8691 if (argc > argv_small_size) { |
| 8698 argv = new Handle<Object>[argc]; | 8692 argv = new Handle<Object>[argc]; |
| 8699 if (argv == NULL) return isolate->StackOverflow(); | 8693 if (argv == NULL) return isolate->StackOverflow(); |
| 8700 argv_large_buffer = SmartArrayPointer<Handle<Object> >(argv); | 8694 argv_large_buffer = SmartArrayPointer<Handle<Object> >(argv); |
| (...skipping 772 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9473 if (!global->IsJSGlobalObject()) return isolate->heap()->null_value(); | 9467 if (!global->IsJSGlobalObject()) return isolate->heap()->null_value(); |
| 9474 return JSGlobalObject::cast(global)->global_receiver(); | 9468 return JSGlobalObject::cast(global)->global_receiver(); |
| 9475 } | 9469 } |
| 9476 | 9470 |
| 9477 | 9471 |
| 9478 RUNTIME_FUNCTION(MaybeObject*, Runtime_ParseJson) { | 9472 RUNTIME_FUNCTION(MaybeObject*, Runtime_ParseJson) { |
| 9479 HandleScope scope(isolate); | 9473 HandleScope scope(isolate); |
| 9480 ASSERT_EQ(1, args.length()); | 9474 ASSERT_EQ(1, args.length()); |
| 9481 CONVERT_ARG_HANDLE_CHECKED(String, source, 0); | 9475 CONVERT_ARG_HANDLE_CHECKED(String, source, 0); |
| 9482 | 9476 |
| 9483 source = Handle<String>(FlattenGetString(source)); | 9477 source = Handle<String>(source->TryFlattenGetString()); |
| 9484 // Optimized fast case where we only have ASCII characters. | 9478 // Optimized fast case where we only have ASCII characters. |
| 9485 Handle<Object> result; | 9479 Handle<Object> result; |
| 9486 if (source->IsSeqOneByteString()) { | 9480 if (source->IsSeqOneByteString()) { |
| 9487 result = JsonParser<true>::Parse(source); | 9481 result = JsonParser<true>::Parse(source); |
| 9488 } else { | 9482 } else { |
| 9489 result = JsonParser<false>::Parse(source); | 9483 result = JsonParser<false>::Parse(source); |
| 9490 } | 9484 } |
| 9491 if (result.is_null()) { | 9485 if (result.is_null()) { |
| 9492 // Syntax error or stack overflow in scanner. | 9486 // Syntax error or stack overflow in scanner. |
| 9493 ASSERT(isolate->has_pending_exception()); | 9487 ASSERT(isolate->has_pending_exception()); |
| (...skipping 3869 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13363 int usage = static_cast<int>(isolate->heap()->SizeOfObjects()); | 13357 int usage = static_cast<int>(isolate->heap()->SizeOfObjects()); |
| 13364 if (!Smi::IsValid(usage)) { | 13358 if (!Smi::IsValid(usage)) { |
| 13365 return *isolate->factory()->NewNumberFromInt(usage); | 13359 return *isolate->factory()->NewNumberFromInt(usage); |
| 13366 } | 13360 } |
| 13367 return Smi::FromInt(usage); | 13361 return Smi::FromInt(usage); |
| 13368 } | 13362 } |
| 13369 | 13363 |
| 13370 #endif // ENABLE_DEBUGGER_SUPPORT | 13364 #endif // ENABLE_DEBUGGER_SUPPORT |
| 13371 | 13365 |
| 13372 | 13366 |
| 13373 #ifdef V8_I18N_SUPPORT | |
| 13374 RUNTIME_FUNCTION(MaybeObject*, Runtime_CanonicalizeLanguageTag) { | |
| 13375 HandleScope scope(isolate); | |
| 13376 | |
| 13377 ASSERT(args.length() == 1); | |
| 13378 CONVERT_ARG_HANDLE_CHECKED(String, locale_id_str, 0); | |
| 13379 | |
| 13380 v8::String::Utf8Value locale_id(v8::Utils::ToLocal(locale_id_str)); | |
| 13381 | |
| 13382 // Return value which denotes invalid language tag. | |
| 13383 const char* const kInvalidTag = "invalid-tag"; | |
| 13384 | |
| 13385 UErrorCode error = U_ZERO_ERROR; | |
| 13386 char icu_result[ULOC_FULLNAME_CAPACITY]; | |
| 13387 int icu_length = 0; | |
| 13388 | |
| 13389 uloc_forLanguageTag(*locale_id, icu_result, ULOC_FULLNAME_CAPACITY, | |
| 13390 &icu_length, &error); | |
| 13391 if (U_FAILURE(error) || icu_length == 0) { | |
| 13392 return isolate->heap()->AllocateStringFromOneByte(CStrVector(kInvalidTag)); | |
| 13393 } | |
| 13394 | |
| 13395 char result[ULOC_FULLNAME_CAPACITY]; | |
| 13396 | |
| 13397 // Force strict BCP47 rules. | |
| 13398 uloc_toLanguageTag(icu_result, result, ULOC_FULLNAME_CAPACITY, TRUE, &error); | |
| 13399 | |
| 13400 if (U_FAILURE(error)) { | |
| 13401 return isolate->heap()->AllocateStringFromOneByte(CStrVector(kInvalidTag)); | |
| 13402 } | |
| 13403 | |
| 13404 return isolate->heap()->AllocateStringFromOneByte(CStrVector(result)); | |
| 13405 } | |
| 13406 | |
| 13407 | |
| 13408 RUNTIME_FUNCTION(MaybeObject*, Runtime_AvailableLocalesOf) { | |
| 13409 HandleScope scope(isolate); | |
| 13410 | |
| 13411 ASSERT(args.length() == 1); | |
| 13412 CONVERT_ARG_HANDLE_CHECKED(String, service, 0); | |
| 13413 | |
| 13414 const icu::Locale* available_locales = NULL; | |
| 13415 int32_t count = 0; | |
| 13416 | |
| 13417 if (service->IsUtf8EqualTo(CStrVector("collator"))) { | |
| 13418 available_locales = icu::Collator::getAvailableLocales(count); | |
| 13419 } else if (service->IsUtf8EqualTo(CStrVector("numberformat"))) { | |
| 13420 available_locales = icu::NumberFormat::getAvailableLocales(count); | |
| 13421 } else if (service->IsUtf8EqualTo(CStrVector("dateformat"))) { | |
| 13422 available_locales = icu::DateFormat::getAvailableLocales(count); | |
| 13423 } else if (service->IsUtf8EqualTo(CStrVector("breakiterator"))) { | |
| 13424 available_locales = icu::BreakIterator::getAvailableLocales(count); | |
| 13425 } | |
| 13426 | |
| 13427 UErrorCode error = U_ZERO_ERROR; | |
| 13428 char result[ULOC_FULLNAME_CAPACITY]; | |
| 13429 Handle<JSObject> locales = | |
| 13430 isolate->factory()->NewJSObject(isolate->object_function()); | |
| 13431 | |
| 13432 for (int32_t i = 0; i < count; ++i) { | |
| 13433 const char* icu_name = available_locales[i].getName(); | |
| 13434 | |
| 13435 error = U_ZERO_ERROR; | |
| 13436 // No need to force strict BCP47 rules. | |
| 13437 uloc_toLanguageTag(icu_name, result, ULOC_FULLNAME_CAPACITY, FALSE, &error); | |
| 13438 if (U_FAILURE(error)) { | |
| 13439 // This shouldn't happen, but lets not break the user. | |
| 13440 continue; | |
| 13441 } | |
| 13442 | |
| 13443 RETURN_IF_EMPTY_HANDLE(isolate, | |
| 13444 JSObject::SetLocalPropertyIgnoreAttributes( | |
| 13445 locales, | |
| 13446 isolate->factory()->NewStringFromAscii(CStrVector(result)), | |
| 13447 isolate->factory()->NewNumber(i), | |
| 13448 NONE)); | |
| 13449 } | |
| 13450 | |
| 13451 return *locales; | |
| 13452 } | |
| 13453 | |
| 13454 | |
| 13455 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetDefaultICULocale) { | |
| 13456 SealHandleScope shs(isolate); | |
| 13457 | |
| 13458 ASSERT(args.length() == 0); | |
| 13459 | |
| 13460 icu::Locale default_locale; | |
| 13461 | |
| 13462 // Set the locale | |
| 13463 char result[ULOC_FULLNAME_CAPACITY]; | |
| 13464 UErrorCode status = U_ZERO_ERROR; | |
| 13465 uloc_toLanguageTag( | |
| 13466 default_locale.getName(), result, ULOC_FULLNAME_CAPACITY, FALSE, &status); | |
| 13467 if (U_SUCCESS(status)) { | |
| 13468 return isolate->heap()->AllocateStringFromOneByte(CStrVector(result)); | |
| 13469 } | |
| 13470 | |
| 13471 return isolate->heap()->AllocateStringFromOneByte(CStrVector("und")); | |
| 13472 } | |
| 13473 | |
| 13474 | |
| 13475 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetLanguageTagVariants) { | |
| 13476 HandleScope scope(isolate); | |
| 13477 | |
| 13478 ASSERT(args.length() == 1); | |
| 13479 | |
| 13480 CONVERT_ARG_HANDLE_CHECKED(JSArray, input, 0); | |
| 13481 | |
| 13482 uint32_t length = static_cast<uint32_t>(input->length()->Number()); | |
| 13483 Handle<FixedArray> output = isolate->factory()->NewFixedArray(length); | |
| 13484 Handle<Name> maximized = | |
| 13485 isolate->factory()->NewStringFromAscii(CStrVector("maximized")); | |
| 13486 Handle<Name> base = | |
| 13487 isolate->factory()->NewStringFromAscii(CStrVector("base")); | |
| 13488 for (unsigned int i = 0; i < length; ++i) { | |
| 13489 MaybeObject* maybe_string = input->GetElement(i); | |
| 13490 Object* locale_id; | |
| 13491 if (!maybe_string->ToObject(&locale_id) || !locale_id->IsString()) { | |
| 13492 return isolate->Throw(isolate->heap()->illegal_argument_string()); | |
| 13493 } | |
| 13494 | |
| 13495 v8::String::Utf8Value utf8_locale_id( | |
| 13496 v8::Utils::ToLocal(Handle<String>(String::cast(locale_id)))); | |
| 13497 | |
| 13498 UErrorCode error = U_ZERO_ERROR; | |
| 13499 | |
| 13500 // Convert from BCP47 to ICU format. | |
| 13501 // de-DE-u-co-phonebk -> de_DE@collation=phonebook | |
| 13502 char icu_locale[ULOC_FULLNAME_CAPACITY]; | |
| 13503 int icu_locale_length = 0; | |
| 13504 uloc_forLanguageTag(*utf8_locale_id, icu_locale, ULOC_FULLNAME_CAPACITY, | |
| 13505 &icu_locale_length, &error); | |
| 13506 if (U_FAILURE(error) || icu_locale_length == 0) { | |
| 13507 return isolate->Throw(isolate->heap()->illegal_argument_string()); | |
| 13508 } | |
| 13509 | |
| 13510 // Maximize the locale. | |
| 13511 // de_DE@collation=phonebook -> de_Latn_DE@collation=phonebook | |
| 13512 char icu_max_locale[ULOC_FULLNAME_CAPACITY]; | |
| 13513 uloc_addLikelySubtags( | |
| 13514 icu_locale, icu_max_locale, ULOC_FULLNAME_CAPACITY, &error); | |
| 13515 | |
| 13516 // Remove extensions from maximized locale. | |
| 13517 // de_Latn_DE@collation=phonebook -> de_Latn_DE | |
| 13518 char icu_base_max_locale[ULOC_FULLNAME_CAPACITY]; | |
| 13519 uloc_getBaseName( | |
| 13520 icu_max_locale, icu_base_max_locale, ULOC_FULLNAME_CAPACITY, &error); | |
| 13521 | |
| 13522 // Get original name without extensions. | |
| 13523 // de_DE@collation=phonebook -> de_DE | |
| 13524 char icu_base_locale[ULOC_FULLNAME_CAPACITY]; | |
| 13525 uloc_getBaseName( | |
| 13526 icu_locale, icu_base_locale, ULOC_FULLNAME_CAPACITY, &error); | |
| 13527 | |
| 13528 // Convert from ICU locale format to BCP47 format. | |
| 13529 // de_Latn_DE -> de-Latn-DE | |
| 13530 char base_max_locale[ULOC_FULLNAME_CAPACITY]; | |
| 13531 uloc_toLanguageTag(icu_base_max_locale, base_max_locale, | |
| 13532 ULOC_FULLNAME_CAPACITY, FALSE, &error); | |
| 13533 | |
| 13534 // de_DE -> de-DE | |
| 13535 char base_locale[ULOC_FULLNAME_CAPACITY]; | |
| 13536 uloc_toLanguageTag( | |
| 13537 icu_base_locale, base_locale, ULOC_FULLNAME_CAPACITY, FALSE, &error); | |
| 13538 | |
| 13539 if (U_FAILURE(error)) { | |
| 13540 return isolate->Throw(isolate->heap()->illegal_argument_string()); | |
| 13541 } | |
| 13542 | |
| 13543 Handle<JSObject> result = | |
| 13544 isolate->factory()->NewJSObject(isolate->object_function()); | |
| 13545 RETURN_IF_EMPTY_HANDLE(isolate, | |
| 13546 JSObject::SetLocalPropertyIgnoreAttributes( | |
| 13547 result, | |
| 13548 maximized, | |
| 13549 isolate->factory()->NewStringFromAscii(CStrVector(base_max_locale)), | |
| 13550 NONE)); | |
| 13551 RETURN_IF_EMPTY_HANDLE(isolate, | |
| 13552 JSObject::SetLocalPropertyIgnoreAttributes( | |
| 13553 result, | |
| 13554 base, | |
| 13555 isolate->factory()->NewStringFromAscii(CStrVector(base_locale)), | |
| 13556 NONE)); | |
| 13557 output->set(i, *result); | |
| 13558 } | |
| 13559 | |
| 13560 Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements(output); | |
| 13561 result->set_length(Smi::FromInt(length)); | |
| 13562 return *result; | |
| 13563 } | |
| 13564 | |
| 13565 | |
| 13566 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateDateTimeFormat) { | |
| 13567 HandleScope scope(isolate); | |
| 13568 | |
| 13569 ASSERT(args.length() == 3); | |
| 13570 | |
| 13571 CONVERT_ARG_HANDLE_CHECKED(String, locale, 0); | |
| 13572 CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1); | |
| 13573 CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2); | |
| 13574 | |
| 13575 Handle<ObjectTemplateInfo> date_format_template = | |
| 13576 I18N::GetTemplate(isolate); | |
| 13577 | |
| 13578 // Create an empty object wrapper. | |
| 13579 bool has_pending_exception = false; | |
| 13580 Handle<JSObject> local_object = Execution::InstantiateObject( | |
| 13581 date_format_template, &has_pending_exception); | |
| 13582 if (has_pending_exception) { | |
| 13583 ASSERT(isolate->has_pending_exception()); | |
| 13584 return Failure::Exception(); | |
| 13585 } | |
| 13586 | |
| 13587 // Set date time formatter as internal field of the resulting JS object. | |
| 13588 icu::SimpleDateFormat* date_format = DateFormat::InitializeDateTimeFormat( | |
| 13589 isolate, locale, options, resolved); | |
| 13590 | |
| 13591 if (!date_format) return isolate->ThrowIllegalOperation(); | |
| 13592 | |
| 13593 local_object->SetInternalField(0, reinterpret_cast<Smi*>(date_format)); | |
| 13594 | |
| 13595 RETURN_IF_EMPTY_HANDLE(isolate, | |
| 13596 JSObject::SetLocalPropertyIgnoreAttributes( | |
| 13597 local_object, | |
| 13598 isolate->factory()->NewStringFromAscii(CStrVector("dateFormat")), | |
| 13599 isolate->factory()->NewStringFromAscii(CStrVector("valid")), | |
| 13600 NONE)); | |
| 13601 | |
| 13602 Persistent<v8::Object> wrapper(reinterpret_cast<v8::Isolate*>(isolate), | |
| 13603 v8::Utils::ToLocal(local_object)); | |
| 13604 // Make object handle weak so we can delete the data format once GC kicks in. | |
| 13605 wrapper.MakeWeak<void>(NULL, &DateFormat::DeleteDateFormat); | |
| 13606 Handle<Object> result = Utils::OpenPersistent(wrapper); | |
| 13607 wrapper.ClearAndLeak(); | |
| 13608 return *result; | |
| 13609 } | |
| 13610 | |
| 13611 | |
| 13612 RUNTIME_FUNCTION(MaybeObject*, Runtime_InternalDateFormat) { | |
| 13613 HandleScope scope(isolate); | |
| 13614 | |
| 13615 ASSERT(args.length() == 2); | |
| 13616 | |
| 13617 CONVERT_ARG_HANDLE_CHECKED(JSObject, date_format_holder, 0); | |
| 13618 CONVERT_ARG_HANDLE_CHECKED(JSDate, date, 1); | |
| 13619 | |
| 13620 bool has_pending_exception = false; | |
| 13621 double millis = Execution::ToNumber(date, &has_pending_exception)->Number(); | |
| 13622 if (has_pending_exception) { | |
| 13623 ASSERT(isolate->has_pending_exception()); | |
| 13624 return Failure::Exception(); | |
| 13625 } | |
| 13626 | |
| 13627 icu::SimpleDateFormat* date_format = | |
| 13628 DateFormat::UnpackDateFormat(isolate, date_format_holder); | |
| 13629 if (!date_format) return isolate->ThrowIllegalOperation(); | |
| 13630 | |
| 13631 icu::UnicodeString result; | |
| 13632 date_format->format(millis, result); | |
| 13633 | |
| 13634 return *isolate->factory()->NewStringFromTwoByte( | |
| 13635 Vector<const uint16_t>( | |
| 13636 reinterpret_cast<const uint16_t*>(result.getBuffer()), | |
| 13637 result.length())); | |
| 13638 } | |
| 13639 | |
| 13640 | |
| 13641 RUNTIME_FUNCTION(MaybeObject*, Runtime_InternalDateParse) { | |
| 13642 HandleScope scope(isolate); | |
| 13643 | |
| 13644 ASSERT(args.length() == 2); | |
| 13645 | |
| 13646 CONVERT_ARG_HANDLE_CHECKED(JSObject, date_format_holder, 0); | |
| 13647 CONVERT_ARG_HANDLE_CHECKED(String, date_string, 1); | |
| 13648 | |
| 13649 v8::String::Utf8Value utf8_date(v8::Utils::ToLocal(date_string)); | |
| 13650 icu::UnicodeString u_date(icu::UnicodeString::fromUTF8(*utf8_date)); | |
| 13651 icu::SimpleDateFormat* date_format = | |
| 13652 DateFormat::UnpackDateFormat(isolate, date_format_holder); | |
| 13653 if (!date_format) return isolate->ThrowIllegalOperation(); | |
| 13654 | |
| 13655 UErrorCode status = U_ZERO_ERROR; | |
| 13656 UDate date = date_format->parse(u_date, status); | |
| 13657 if (U_FAILURE(status)) return isolate->heap()->undefined_value(); | |
| 13658 | |
| 13659 bool has_pending_exception = false; | |
| 13660 Handle<JSDate> result = Handle<JSDate>::cast( | |
| 13661 Execution::NewDate(static_cast<double>(date), &has_pending_exception)); | |
| 13662 if (has_pending_exception) { | |
| 13663 ASSERT(isolate->has_pending_exception()); | |
| 13664 return Failure::Exception(); | |
| 13665 } | |
| 13666 return *result; | |
| 13667 } | |
| 13668 #endif // V8_I18N_SUPPORT | |
| 13669 | |
| 13670 | |
| 13671 // Finds the script object from the script data. NOTE: This operation uses | 13367 // Finds the script object from the script data. NOTE: This operation uses |
| 13672 // heap traversal to find the function generated for the source position | 13368 // heap traversal to find the function generated for the source position |
| 13673 // for the requested break point. For lazily compiled functions several heap | 13369 // for the requested break point. For lazily compiled functions several heap |
| 13674 // traversals might be required rendering this operation as a rather slow | 13370 // traversals might be required rendering this operation as a rather slow |
| 13675 // operation. However for setting break points which is normally done through | 13371 // operation. However for setting break points which is normally done through |
| 13676 // some kind of user interaction the performance is not crucial. | 13372 // some kind of user interaction the performance is not crucial. |
| 13677 static Handle<Object> Runtime_GetScriptFromScriptName( | 13373 static Handle<Object> Runtime_GetScriptFromScriptName( |
| 13678 Handle<String> script_name) { | 13374 Handle<String> script_name) { |
| 13679 // Scan the heap for Script objects to find the script with the requested | 13375 // Scan the heap for Script objects to find the script with the requested |
| 13680 // script data. | 13376 // script data. |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13779 | 13475 |
| 13780 RUNTIME_FUNCTION(MaybeObject*, Runtime_FlattenString) { | 13476 RUNTIME_FUNCTION(MaybeObject*, Runtime_FlattenString) { |
| 13781 HandleScope scope(isolate); | 13477 HandleScope scope(isolate); |
| 13782 ASSERT(args.length() == 1); | 13478 ASSERT(args.length() == 1); |
| 13783 CONVERT_ARG_HANDLE_CHECKED(String, str, 0); | 13479 CONVERT_ARG_HANDLE_CHECKED(String, str, 0); |
| 13784 FlattenString(str); | 13480 FlattenString(str); |
| 13785 return isolate->heap()->undefined_value(); | 13481 return isolate->heap()->undefined_value(); |
| 13786 } | 13482 } |
| 13787 | 13483 |
| 13788 | 13484 |
| 13789 RUNTIME_FUNCTION(MaybeObject*, Runtime_MigrateInstance) { | |
| 13790 HandleScope scope(isolate); | |
| 13791 ASSERT(args.length() == 1); | |
| 13792 CONVERT_ARG_HANDLE_CHECKED(Object, object, 0); | |
| 13793 if (!object->IsJSObject()) return Smi::FromInt(0); | |
| 13794 Handle<JSObject> js_object = Handle<JSObject>::cast(object); | |
| 13795 if (!js_object->map()->is_deprecated()) return Smi::FromInt(0); | |
| 13796 JSObject::MigrateInstance(js_object); | |
| 13797 return *object; | |
| 13798 } | |
| 13799 | |
| 13800 | |
| 13801 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFromCache) { | 13485 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFromCache) { |
| 13802 SealHandleScope shs(isolate); | 13486 SealHandleScope shs(isolate); |
| 13803 // This is only called from codegen, so checks might be more lax. | 13487 // This is only called from codegen, so checks might be more lax. |
| 13804 CONVERT_ARG_CHECKED(JSFunctionResultCache, cache, 0); | 13488 CONVERT_ARG_CHECKED(JSFunctionResultCache, cache, 0); |
| 13805 Object* key = args[1]; | 13489 Object* key = args[1]; |
| 13806 | 13490 |
| 13807 int finger_index = cache->finger_index(); | 13491 int finger_index = cache->finger_index(); |
| 13808 Object* o = cache->get(finger_index); | 13492 Object* o = cache->get(finger_index); |
| 13809 if (o == key) { | 13493 if (o == key) { |
| 13810 // The fastest case: hit the same place again. | 13494 // The fastest case: hit the same place again. |
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14034 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetIsObserved) { | 13718 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetIsObserved) { |
| 14035 SealHandleScope shs(isolate); | 13719 SealHandleScope shs(isolate); |
| 14036 ASSERT(args.length() == 1); | 13720 ASSERT(args.length() == 1); |
| 14037 CONVERT_ARG_CHECKED(JSReceiver, obj, 0); | 13721 CONVERT_ARG_CHECKED(JSReceiver, obj, 0); |
| 14038 if (obj->IsJSGlobalProxy()) { | 13722 if (obj->IsJSGlobalProxy()) { |
| 14039 Object* proto = obj->GetPrototype(); | 13723 Object* proto = obj->GetPrototype(); |
| 14040 if (proto->IsNull()) return isolate->heap()->undefined_value(); | 13724 if (proto->IsNull()) return isolate->heap()->undefined_value(); |
| 14041 ASSERT(proto->IsJSGlobalObject()); | 13725 ASSERT(proto->IsJSGlobalObject()); |
| 14042 obj = JSReceiver::cast(proto); | 13726 obj = JSReceiver::cast(proto); |
| 14043 } | 13727 } |
| 14044 if (obj->IsJSProxy()) | |
| 14045 return isolate->heap()->undefined_value(); | |
| 14046 | |
| 14047 ASSERT(!(obj->map()->is_observed() && obj->IsJSObject() && | 13728 ASSERT(!(obj->map()->is_observed() && obj->IsJSObject() && |
| 14048 JSObject::cast(obj)->HasFastElements())); | 13729 JSObject::cast(obj)->HasFastElements())); |
| 14049 ASSERT(obj->IsJSObject()); | 13730 ASSERT(obj->IsJSObject()); |
| 14050 return JSObject::cast(obj)->SetObserved(isolate); | 13731 return JSObject::cast(obj)->SetObserved(isolate); |
| 14051 } | 13732 } |
| 14052 | 13733 |
| 14053 | 13734 |
| 14054 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetObserverDeliveryPending) { | 13735 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetObserverDeliveryPending) { |
| 14055 SealHandleScope shs(isolate); | 13736 SealHandleScope shs(isolate); |
| 14056 ASSERT(args.length() == 0); | 13737 ASSERT(args.length() == 0); |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14274 // Handle last resort GC and make sure to allow future allocations | 13955 // Handle last resort GC and make sure to allow future allocations |
| 14275 // to grow the heap without causing GCs (if possible). | 13956 // to grow the heap without causing GCs (if possible). |
| 14276 isolate->counters()->gc_last_resort_from_js()->Increment(); | 13957 isolate->counters()->gc_last_resort_from_js()->Increment(); |
| 14277 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, | 13958 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, |
| 14278 "Runtime::PerformGC"); | 13959 "Runtime::PerformGC"); |
| 14279 } | 13960 } |
| 14280 } | 13961 } |
| 14281 | 13962 |
| 14282 | 13963 |
| 14283 } } // namespace v8::internal | 13964 } } // namespace v8::internal |
| OLD | NEW |