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 |