| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 665 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 676 ASSERT(args.length() == 1); | 676 ASSERT(args.length() == 1); |
| 677 Object* obj = args[0]; | 677 Object* obj = args[0]; |
| 678 if (!obj->IsJSObject()) return isolate->heap()->null_value(); | 678 if (!obj->IsJSObject()) return isolate->heap()->null_value(); |
| 679 return JSObject::cast(obj)->class_name(); | 679 return JSObject::cast(obj)->class_name(); |
| 680 } | 680 } |
| 681 | 681 |
| 682 | 682 |
| 683 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPrototype) { | 683 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPrototype) { |
| 684 NoHandleAllocation ha; | 684 NoHandleAllocation ha; |
| 685 ASSERT(args.length() == 1); | 685 ASSERT(args.length() == 1); |
| 686 Object* obj = args[0]; | 686 CONVERT_CHECKED(JSReceiver, input_obj, args[0]); |
| 687 Object* obj = input_obj; |
| 688 // We don't expect access checks to be needed on JSProxy objects. |
| 689 ASSERT(!obj->IsAccessCheckNeeded() || obj->IsJSObject()); |
| 687 do { | 690 do { |
| 691 if (obj->IsAccessCheckNeeded() && |
| 692 !isolate->MayNamedAccess(JSObject::cast(obj), |
| 693 isolate->heap()->Proto_symbol(), |
| 694 v8::ACCESS_GET)) { |
| 695 isolate->ReportFailedAccessCheck(JSObject::cast(obj), v8::ACCESS_GET); |
| 696 return isolate->heap()->undefined_value(); |
| 697 } |
| 688 obj = obj->GetPrototype(); | 698 obj = obj->GetPrototype(); |
| 689 } while (obj->IsJSObject() && | 699 } while (obj->IsJSObject() && |
| 690 JSObject::cast(obj)->map()->is_hidden_prototype()); | 700 JSObject::cast(obj)->map()->is_hidden_prototype()); |
| 691 return obj; | 701 return obj; |
| 692 } | 702 } |
| 693 | 703 |
| 694 | 704 |
| 695 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsInPrototypeChain) { | 705 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsInPrototypeChain) { |
| 696 NoHandleAllocation ha; | 706 NoHandleAllocation ha; |
| 697 ASSERT(args.length() == 2); | 707 ASSERT(args.length() == 2); |
| (...skipping 1958 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2656 } | 2666 } |
| 2657 | 2667 |
| 2658 ZoneList<ReplacementPart> parts_; | 2668 ZoneList<ReplacementPart> parts_; |
| 2659 ZoneList<Handle<String> > replacement_substrings_; | 2669 ZoneList<Handle<String> > replacement_substrings_; |
| 2660 }; | 2670 }; |
| 2661 | 2671 |
| 2662 | 2672 |
| 2663 void CompiledReplacement::Compile(Handle<String> replacement, | 2673 void CompiledReplacement::Compile(Handle<String> replacement, |
| 2664 int capture_count, | 2674 int capture_count, |
| 2665 int subject_length) { | 2675 int subject_length) { |
| 2666 ASSERT(replacement->IsFlat()); | 2676 { |
| 2667 if (replacement->IsAsciiRepresentation()) { | |
| 2668 AssertNoAllocation no_alloc; | 2677 AssertNoAllocation no_alloc; |
| 2669 ParseReplacementPattern(&parts_, | 2678 String::FlatContent content = replacement->GetFlatContent(); |
| 2670 replacement->ToAsciiVector(), | 2679 ASSERT(content.IsFlat()); |
| 2671 capture_count, | 2680 if (content.IsAscii()) { |
| 2672 subject_length); | 2681 ParseReplacementPattern(&parts_, |
| 2673 } else { | 2682 content.ToAsciiVector(), |
| 2674 ASSERT(replacement->IsTwoByteRepresentation()); | 2683 capture_count, |
| 2675 AssertNoAllocation no_alloc; | 2684 subject_length); |
| 2676 | 2685 } else { |
| 2677 ParseReplacementPattern(&parts_, | 2686 ASSERT(content.IsTwoByte()); |
| 2678 replacement->ToUC16Vector(), | 2687 ParseReplacementPattern(&parts_, |
| 2679 capture_count, | 2688 content.ToUC16Vector(), |
| 2680 subject_length); | 2689 capture_count, |
| 2690 subject_length); |
| 2691 } |
| 2681 } | 2692 } |
| 2682 Isolate* isolate = replacement->GetIsolate(); | 2693 Isolate* isolate = replacement->GetIsolate(); |
| 2683 // Find substrings of replacement string and create them as String objects. | 2694 // Find substrings of replacement string and create them as String objects. |
| 2684 int substring_index = 0; | 2695 int substring_index = 0; |
| 2685 for (int i = 0, n = parts_.length(); i < n; i++) { | 2696 for (int i = 0, n = parts_.length(); i < n; i++) { |
| 2686 int tag = parts_[i].tag; | 2697 int tag = parts_[i].tag; |
| 2687 if (tag <= 0) { // A replacement string slice. | 2698 if (tag <= 0) { // A replacement string slice. |
| 2688 int from = -tag; | 2699 int from = -tag; |
| 2689 int to = parts_[i].data; | 2700 int to = parts_[i].data; |
| 2690 replacement_substrings_.Add( | 2701 replacement_substrings_.Add( |
| (...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3045 if (pattern_length == 0) return start_index; | 3056 if (pattern_length == 0) return start_index; |
| 3046 | 3057 |
| 3047 int subject_length = sub->length(); | 3058 int subject_length = sub->length(); |
| 3048 if (start_index + pattern_length > subject_length) return -1; | 3059 if (start_index + pattern_length > subject_length) return -1; |
| 3049 | 3060 |
| 3050 if (!sub->IsFlat()) FlattenString(sub); | 3061 if (!sub->IsFlat()) FlattenString(sub); |
| 3051 if (!pat->IsFlat()) FlattenString(pat); | 3062 if (!pat->IsFlat()) FlattenString(pat); |
| 3052 | 3063 |
| 3053 AssertNoAllocation no_heap_allocation; // ensure vectors stay valid | 3064 AssertNoAllocation no_heap_allocation; // ensure vectors stay valid |
| 3054 // Extract flattened substrings of cons strings before determining asciiness. | 3065 // Extract flattened substrings of cons strings before determining asciiness. |
| 3055 String* seq_sub = *sub; | 3066 String::FlatContent seq_sub = sub->GetFlatContent(); |
| 3056 if (seq_sub->IsConsString()) seq_sub = ConsString::cast(seq_sub)->first(); | 3067 String::FlatContent seq_pat = pat->GetFlatContent(); |
| 3057 String* seq_pat = *pat; | |
| 3058 if (seq_pat->IsConsString()) seq_pat = ConsString::cast(seq_pat)->first(); | |
| 3059 | 3068 |
| 3060 // dispatch on type of strings | 3069 // dispatch on type of strings |
| 3061 if (seq_pat->IsAsciiRepresentation()) { | 3070 if (seq_pat.IsAscii()) { |
| 3062 Vector<const char> pat_vector = seq_pat->ToAsciiVector(); | 3071 Vector<const char> pat_vector = seq_pat.ToAsciiVector(); |
| 3063 if (seq_sub->IsAsciiRepresentation()) { | 3072 if (seq_sub.IsAscii()) { |
| 3064 return SearchString(isolate, | 3073 return SearchString(isolate, |
| 3065 seq_sub->ToAsciiVector(), | 3074 seq_sub.ToAsciiVector(), |
| 3066 pat_vector, | 3075 pat_vector, |
| 3067 start_index); | 3076 start_index); |
| 3068 } | 3077 } |
| 3069 return SearchString(isolate, | 3078 return SearchString(isolate, |
| 3070 seq_sub->ToUC16Vector(), | 3079 seq_sub.ToUC16Vector(), |
| 3071 pat_vector, | 3080 pat_vector, |
| 3072 start_index); | 3081 start_index); |
| 3073 } | 3082 } |
| 3074 Vector<const uc16> pat_vector = seq_pat->ToUC16Vector(); | 3083 Vector<const uc16> pat_vector = seq_pat.ToUC16Vector(); |
| 3075 if (seq_sub->IsAsciiRepresentation()) { | 3084 if (seq_sub.IsAscii()) { |
| 3076 return SearchString(isolate, | 3085 return SearchString(isolate, |
| 3077 seq_sub->ToAsciiVector(), | 3086 seq_sub.ToAsciiVector(), |
| 3078 pat_vector, | 3087 pat_vector, |
| 3079 start_index); | 3088 start_index); |
| 3080 } | 3089 } |
| 3081 return SearchString(isolate, | 3090 return SearchString(isolate, |
| 3082 seq_sub->ToUC16Vector(), | 3091 seq_sub.ToUC16Vector(), |
| 3083 pat_vector, | 3092 pat_vector, |
| 3084 start_index); | 3093 start_index); |
| 3085 } | 3094 } |
| 3086 | 3095 |
| 3087 | 3096 |
| 3088 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringIndexOf) { | 3097 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringIndexOf) { |
| 3089 HandleScope scope(isolate); // create a new handle scope | 3098 HandleScope scope(isolate); // create a new handle scope |
| 3090 ASSERT(args.length() == 3); | 3099 ASSERT(args.length() == 3); |
| 3091 | 3100 |
| 3092 CONVERT_ARG_CHECKED(String, sub, 0); | 3101 CONVERT_ARG_CHECKED(String, sub, 0); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3155 start_index = sub_length - pat_length; | 3164 start_index = sub_length - pat_length; |
| 3156 } | 3165 } |
| 3157 | 3166 |
| 3158 if (pat_length == 0) { | 3167 if (pat_length == 0) { |
| 3159 return Smi::FromInt(start_index); | 3168 return Smi::FromInt(start_index); |
| 3160 } | 3169 } |
| 3161 | 3170 |
| 3162 if (!sub->IsFlat()) FlattenString(sub); | 3171 if (!sub->IsFlat()) FlattenString(sub); |
| 3163 if (!pat->IsFlat()) FlattenString(pat); | 3172 if (!pat->IsFlat()) FlattenString(pat); |
| 3164 | 3173 |
| 3174 int position = -1; |
| 3165 AssertNoAllocation no_heap_allocation; // ensure vectors stay valid | 3175 AssertNoAllocation no_heap_allocation; // ensure vectors stay valid |
| 3166 | 3176 |
| 3167 int position = -1; | 3177 String::FlatContent sub_content = sub->GetFlatContent(); |
| 3178 String::FlatContent pat_content = pat->GetFlatContent(); |
| 3168 | 3179 |
| 3169 if (pat->IsAsciiRepresentation()) { | 3180 if (pat_content.IsAscii()) { |
| 3170 Vector<const char> pat_vector = pat->ToAsciiVector(); | 3181 Vector<const char> pat_vector = pat_content.ToAsciiVector(); |
| 3171 if (sub->IsAsciiRepresentation()) { | 3182 if (sub_content.IsAscii()) { |
| 3172 position = StringMatchBackwards(sub->ToAsciiVector(), | 3183 position = StringMatchBackwards(sub_content.ToAsciiVector(), |
| 3173 pat_vector, | 3184 pat_vector, |
| 3174 start_index); | 3185 start_index); |
| 3175 } else { | 3186 } else { |
| 3176 position = StringMatchBackwards(sub->ToUC16Vector(), | 3187 position = StringMatchBackwards(sub_content.ToUC16Vector(), |
| 3177 pat_vector, | 3188 pat_vector, |
| 3178 start_index); | 3189 start_index); |
| 3179 } | 3190 } |
| 3180 } else { | 3191 } else { |
| 3181 Vector<const uc16> pat_vector = pat->ToUC16Vector(); | 3192 Vector<const uc16> pat_vector = pat_content.ToUC16Vector(); |
| 3182 if (sub->IsAsciiRepresentation()) { | 3193 if (sub_content.IsAscii()) { |
| 3183 position = StringMatchBackwards(sub->ToAsciiVector(), | 3194 position = StringMatchBackwards(sub_content.ToAsciiVector(), |
| 3184 pat_vector, | 3195 pat_vector, |
| 3185 start_index); | 3196 start_index); |
| 3186 } else { | 3197 } else { |
| 3187 position = StringMatchBackwards(sub->ToUC16Vector(), | 3198 position = StringMatchBackwards(sub_content.ToUC16Vector(), |
| 3188 pat_vector, | 3199 pat_vector, |
| 3189 start_index); | 3200 start_index); |
| 3190 } | 3201 } |
| 3191 } | 3202 } |
| 3192 | 3203 |
| 3193 return Smi::FromInt(position); | 3204 return Smi::FromInt(position); |
| 3194 } | 3205 } |
| 3195 | 3206 |
| 3196 | 3207 |
| 3197 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringLocaleCompare) { | 3208 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringLocaleCompare) { |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3395 FixedArrayBuilder* builder) { | 3406 FixedArrayBuilder* builder) { |
| 3396 ASSERT(subject->IsFlat()); | 3407 ASSERT(subject->IsFlat()); |
| 3397 ASSERT(pattern->IsFlat()); | 3408 ASSERT(pattern->IsFlat()); |
| 3398 | 3409 |
| 3399 // Treating as if a previous match was before first character. | 3410 // Treating as if a previous match was before first character. |
| 3400 int match_pos = -pattern->length(); | 3411 int match_pos = -pattern->length(); |
| 3401 | 3412 |
| 3402 for (;;) { // Break when search complete. | 3413 for (;;) { // Break when search complete. |
| 3403 builder->EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch); | 3414 builder->EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch); |
| 3404 AssertNoAllocation no_gc; | 3415 AssertNoAllocation no_gc; |
| 3405 if (subject->IsAsciiRepresentation()) { | 3416 String::FlatContent subject_content = subject->GetFlatContent(); |
| 3406 Vector<const char> subject_vector = subject->ToAsciiVector(); | 3417 String::FlatContent pattern_content = pattern->GetFlatContent(); |
| 3407 if (pattern->IsAsciiRepresentation()) { | 3418 if (subject_content.IsAscii()) { |
| 3419 Vector<const char> subject_vector = subject_content.ToAsciiVector(); |
| 3420 if (pattern_content.IsAscii()) { |
| 3408 if (SearchStringMultiple(isolate, | 3421 if (SearchStringMultiple(isolate, |
| 3409 subject_vector, | 3422 subject_vector, |
| 3410 pattern->ToAsciiVector(), | 3423 pattern_content.ToAsciiVector(), |
| 3411 *pattern, | 3424 *pattern, |
| 3412 builder, | 3425 builder, |
| 3413 &match_pos)) break; | 3426 &match_pos)) break; |
| 3414 } else { | 3427 } else { |
| 3415 if (SearchStringMultiple(isolate, | 3428 if (SearchStringMultiple(isolate, |
| 3416 subject_vector, | 3429 subject_vector, |
| 3417 pattern->ToUC16Vector(), | 3430 pattern_content.ToUC16Vector(), |
| 3418 *pattern, | 3431 *pattern, |
| 3419 builder, | 3432 builder, |
| 3420 &match_pos)) break; | 3433 &match_pos)) break; |
| 3421 } | 3434 } |
| 3422 } else { | 3435 } else { |
| 3423 Vector<const uc16> subject_vector = subject->ToUC16Vector(); | 3436 Vector<const uc16> subject_vector = subject_content.ToUC16Vector(); |
| 3424 if (pattern->IsAsciiRepresentation()) { | 3437 if (pattern_content.IsAscii()) { |
| 3425 if (SearchStringMultiple(isolate, | 3438 if (SearchStringMultiple(isolate, |
| 3426 subject_vector, | 3439 subject_vector, |
| 3427 pattern->ToAsciiVector(), | 3440 pattern_content.ToAsciiVector(), |
| 3428 *pattern, | 3441 *pattern, |
| 3429 builder, | 3442 builder, |
| 3430 &match_pos)) break; | 3443 &match_pos)) break; |
| 3431 } else { | 3444 } else { |
| 3432 if (SearchStringMultiple(isolate, | 3445 if (SearchStringMultiple(isolate, |
| 3433 subject_vector, | 3446 subject_vector, |
| 3434 pattern->ToUC16Vector(), | 3447 pattern_content.ToUC16Vector(), |
| 3435 *pattern, | 3448 *pattern, |
| 3436 builder, | 3449 builder, |
| 3437 &match_pos)) break; | 3450 &match_pos)) break; |
| 3438 } | 3451 } |
| 3439 } | 3452 } |
| 3440 } | 3453 } |
| 3441 | 3454 |
| 3442 if (match_pos >= 0) { | 3455 if (match_pos >= 0) { |
| 3443 SetLastMatchInfoNoCaptures(subject, | 3456 SetLastMatchInfoNoCaptures(subject, |
| 3444 last_match_info, | 3457 last_match_info, |
| (...skipping 1404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4849 if (instance_type < FIRST_NONSTRING_TYPE) { | 4862 if (instance_type < FIRST_NONSTRING_TYPE) { |
| 4850 return isolate->heap()->string_symbol(); | 4863 return isolate->heap()->string_symbol(); |
| 4851 } | 4864 } |
| 4852 | 4865 |
| 4853 switch (instance_type) { | 4866 switch (instance_type) { |
| 4854 case ODDBALL_TYPE: | 4867 case ODDBALL_TYPE: |
| 4855 if (heap_obj->IsTrue() || heap_obj->IsFalse()) { | 4868 if (heap_obj->IsTrue() || heap_obj->IsFalse()) { |
| 4856 return isolate->heap()->boolean_symbol(); | 4869 return isolate->heap()->boolean_symbol(); |
| 4857 } | 4870 } |
| 4858 if (heap_obj->IsNull()) { | 4871 if (heap_obj->IsNull()) { |
| 4859 return isolate->heap()->object_symbol(); | 4872 return FLAG_harmony_typeof |
| 4873 ? isolate->heap()->null_symbol() |
| 4874 : isolate->heap()->object_symbol(); |
| 4860 } | 4875 } |
| 4861 ASSERT(heap_obj->IsUndefined()); | 4876 ASSERT(heap_obj->IsUndefined()); |
| 4862 return isolate->heap()->undefined_symbol(); | 4877 return isolate->heap()->undefined_symbol(); |
| 4863 case JS_FUNCTION_TYPE: | 4878 case JS_FUNCTION_TYPE: |
| 4864 return isolate->heap()->function_symbol(); | 4879 return isolate->heap()->function_symbol(); |
| 4865 default: | 4880 default: |
| 4866 // For any kind of object not handled above, the spec rule for | 4881 // For any kind of object not handled above, the spec rule for |
| 4867 // host objects gives that it is okay to return "object" | 4882 // host objects gives that it is okay to return "object" |
| 4868 return isolate->heap()->object_symbol(); | 4883 return isolate->heap()->object_symbol(); |
| 4869 } | 4884 } |
| (...skipping 540 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5410 CONVERT_CHECKED(String, str, args[0]); | 5425 CONVERT_CHECKED(String, str, args[0]); |
| 5411 if (!str->IsFlat()) { | 5426 if (!str->IsFlat()) { |
| 5412 MaybeObject* try_flatten = str->TryFlatten(); | 5427 MaybeObject* try_flatten = str->TryFlatten(); |
| 5413 Object* flat; | 5428 Object* flat; |
| 5414 if (!try_flatten->ToObject(&flat)) { | 5429 if (!try_flatten->ToObject(&flat)) { |
| 5415 return try_flatten; | 5430 return try_flatten; |
| 5416 } | 5431 } |
| 5417 str = String::cast(flat); | 5432 str = String::cast(flat); |
| 5418 ASSERT(str->IsFlat()); | 5433 ASSERT(str->IsFlat()); |
| 5419 } | 5434 } |
| 5420 if (str->IsTwoByteRepresentation()) { | 5435 String::FlatContent flat = str->GetFlatContent(); |
| 5436 ASSERT(flat.IsFlat()); |
| 5437 if (flat.IsTwoByte()) { |
| 5421 return QuoteJsonString<uc16, SeqTwoByteString, false>(isolate, | 5438 return QuoteJsonString<uc16, SeqTwoByteString, false>(isolate, |
| 5422 str->ToUC16Vector()); | 5439 flat.ToUC16Vector()); |
| 5423 } else { | 5440 } else { |
| 5424 return QuoteJsonString<char, SeqAsciiString, false>(isolate, | 5441 return QuoteJsonString<char, SeqAsciiString, false>(isolate, |
| 5425 str->ToAsciiVector()); | 5442 flat.ToAsciiVector()); |
| 5426 } | 5443 } |
| 5427 } | 5444 } |
| 5428 | 5445 |
| 5429 | 5446 |
| 5430 RUNTIME_FUNCTION(MaybeObject*, Runtime_QuoteJSONStringComma) { | 5447 RUNTIME_FUNCTION(MaybeObject*, Runtime_QuoteJSONStringComma) { |
| 5431 NoHandleAllocation ha; | 5448 NoHandleAllocation ha; |
| 5432 CONVERT_CHECKED(String, str, args[0]); | 5449 CONVERT_CHECKED(String, str, args[0]); |
| 5433 if (!str->IsFlat()) { | 5450 if (!str->IsFlat()) { |
| 5434 MaybeObject* try_flatten = str->TryFlatten(); | 5451 MaybeObject* try_flatten = str->TryFlatten(); |
| 5435 Object* flat; | 5452 Object* flat; |
| 5436 if (!try_flatten->ToObject(&flat)) { | 5453 if (!try_flatten->ToObject(&flat)) { |
| 5437 return try_flatten; | 5454 return try_flatten; |
| 5438 } | 5455 } |
| 5439 str = String::cast(flat); | 5456 str = String::cast(flat); |
| 5440 ASSERT(str->IsFlat()); | 5457 ASSERT(str->IsFlat()); |
| 5441 } | 5458 } |
| 5442 if (str->IsTwoByteRepresentation()) { | 5459 String::FlatContent flat = str->GetFlatContent(); |
| 5460 if (flat.IsTwoByte()) { |
| 5443 return QuoteJsonString<uc16, SeqTwoByteString, true>(isolate, | 5461 return QuoteJsonString<uc16, SeqTwoByteString, true>(isolate, |
| 5444 str->ToUC16Vector()); | 5462 flat.ToUC16Vector()); |
| 5445 } else { | 5463 } else { |
| 5446 return QuoteJsonString<char, SeqAsciiString, true>(isolate, | 5464 return QuoteJsonString<char, SeqAsciiString, true>(isolate, |
| 5447 str->ToAsciiVector()); | 5465 flat.ToAsciiVector()); |
| 5448 } | 5466 } |
| 5449 } | 5467 } |
| 5450 | 5468 |
| 5451 | 5469 |
| 5452 template <typename Char, typename StringType> | 5470 template <typename Char, typename StringType> |
| 5453 static MaybeObject* QuoteJsonStringArray(Isolate* isolate, | 5471 static MaybeObject* QuoteJsonStringArray(Isolate* isolate, |
| 5454 FixedArray* array, | 5472 FixedArray* array, |
| 5455 int worst_case_length) { | 5473 int worst_case_length) { |
| 5456 int length = array->length(); | 5474 int length = array->length(); |
| 5457 | 5475 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 5472 StringType* new_string = StringType::cast(new_object); | 5490 StringType* new_string = StringType::cast(new_object); |
| 5473 ASSERT(isolate->heap()->new_space()->Contains(new_string)); | 5491 ASSERT(isolate->heap()->new_space()->Contains(new_string)); |
| 5474 | 5492 |
| 5475 STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqAsciiString::kHeaderSize); | 5493 STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqAsciiString::kHeaderSize); |
| 5476 Char* write_cursor = reinterpret_cast<Char*>( | 5494 Char* write_cursor = reinterpret_cast<Char*>( |
| 5477 new_string->address() + SeqAsciiString::kHeaderSize); | 5495 new_string->address() + SeqAsciiString::kHeaderSize); |
| 5478 *(write_cursor++) = '['; | 5496 *(write_cursor++) = '['; |
| 5479 for (int i = 0; i < length; i++) { | 5497 for (int i = 0; i < length; i++) { |
| 5480 if (i != 0) *(write_cursor++) = ','; | 5498 if (i != 0) *(write_cursor++) = ','; |
| 5481 String* str = String::cast(array->get(i)); | 5499 String* str = String::cast(array->get(i)); |
| 5482 if (str->IsTwoByteRepresentation()) { | 5500 String::FlatContent content = str->GetFlatContent(); |
| 5501 ASSERT(content.IsFlat()); |
| 5502 if (content.IsTwoByte()) { |
| 5483 write_cursor = WriteQuoteJsonString<Char, uc16>(isolate, | 5503 write_cursor = WriteQuoteJsonString<Char, uc16>(isolate, |
| 5484 write_cursor, | 5504 write_cursor, |
| 5485 str->ToUC16Vector()); | 5505 content.ToUC16Vector()); |
| 5486 } else { | 5506 } else { |
| 5487 write_cursor = WriteQuoteJsonString<Char, char>(isolate, | 5507 write_cursor = WriteQuoteJsonString<Char, char>(isolate, |
| 5488 write_cursor, | 5508 write_cursor, |
| 5489 str->ToAsciiVector()); | 5509 content.ToAsciiVector()); |
| 5490 } | 5510 } |
| 5491 } | 5511 } |
| 5492 *(write_cursor++) = ']'; | 5512 *(write_cursor++) = ']'; |
| 5493 | 5513 |
| 5494 int final_length = static_cast<int>( | 5514 int final_length = static_cast<int>( |
| 5495 write_cursor - reinterpret_cast<Char*>( | 5515 write_cursor - reinterpret_cast<Char*>( |
| 5496 new_string->address() + SeqAsciiString::kHeaderSize)); | 5516 new_string->address() + SeqAsciiString::kHeaderSize)); |
| 5497 isolate->heap()->new_space()-> | 5517 isolate->heap()->new_space()-> |
| 5498 template ShrinkStringAtAllocationBoundary<StringType>( | 5518 template ShrinkStringAtAllocationBoundary<StringType>( |
| 5499 new_string, final_length); | 5519 new_string, final_length); |
| (...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5958 | 5978 |
| 5959 ZoneScope scope(isolate, DELETE_ON_EXIT); | 5979 ZoneScope scope(isolate, DELETE_ON_EXIT); |
| 5960 | 5980 |
| 5961 // Find (up to limit) indices of separator and end-of-string in subject | 5981 // Find (up to limit) indices of separator and end-of-string in subject |
| 5962 int initial_capacity = Min<uint32_t>(kMaxInitialListCapacity, limit); | 5982 int initial_capacity = Min<uint32_t>(kMaxInitialListCapacity, limit); |
| 5963 ZoneList<int> indices(initial_capacity); | 5983 ZoneList<int> indices(initial_capacity); |
| 5964 if (!pattern->IsFlat()) FlattenString(pattern); | 5984 if (!pattern->IsFlat()) FlattenString(pattern); |
| 5965 | 5985 |
| 5966 // No allocation block. | 5986 // No allocation block. |
| 5967 { | 5987 { |
| 5968 AssertNoAllocation nogc; | 5988 AssertNoAllocation no_gc; |
| 5969 if (subject->IsAsciiRepresentation()) { | 5989 String::FlatContent subject_content = subject->GetFlatContent(); |
| 5970 Vector<const char> subject_vector = subject->ToAsciiVector(); | 5990 String::FlatContent pattern_content = pattern->GetFlatContent(); |
| 5971 if (pattern->IsAsciiRepresentation()) { | 5991 ASSERT(subject_content.IsFlat()); |
| 5972 Vector<const char> pattern_vector = pattern->ToAsciiVector(); | 5992 ASSERT(pattern_content.IsFlat()); |
| 5993 if (subject_content.IsAscii()) { |
| 5994 Vector<const char> subject_vector = subject_content.ToAsciiVector(); |
| 5995 if (pattern_content.IsAscii()) { |
| 5996 Vector<const char> pattern_vector = pattern_content.ToAsciiVector(); |
| 5973 if (pattern_vector.length() == 1) { | 5997 if (pattern_vector.length() == 1) { |
| 5974 FindAsciiStringIndices(subject_vector, | 5998 FindAsciiStringIndices(subject_vector, |
| 5975 pattern_vector[0], | 5999 pattern_vector[0], |
| 5976 &indices, | 6000 &indices, |
| 5977 limit); | 6001 limit); |
| 5978 } else { | 6002 } else { |
| 5979 FindStringIndices(isolate, | 6003 FindStringIndices(isolate, |
| 5980 subject_vector, | 6004 subject_vector, |
| 5981 pattern_vector, | 6005 pattern_vector, |
| 5982 &indices, | 6006 &indices, |
| 5983 limit); | 6007 limit); |
| 5984 } | 6008 } |
| 5985 } else { | 6009 } else { |
| 5986 FindStringIndices(isolate, | 6010 FindStringIndices(isolate, |
| 5987 subject_vector, | 6011 subject_vector, |
| 5988 pattern->ToUC16Vector(), | 6012 pattern_content.ToUC16Vector(), |
| 5989 &indices, | 6013 &indices, |
| 5990 limit); | 6014 limit); |
| 5991 } | 6015 } |
| 5992 } else { | 6016 } else { |
| 5993 Vector<const uc16> subject_vector = subject->ToUC16Vector(); | 6017 Vector<const uc16> subject_vector = subject_content.ToUC16Vector(); |
| 5994 if (pattern->IsAsciiRepresentation()) { | 6018 if (pattern->IsAsciiRepresentation()) { |
| 5995 FindStringIndices(isolate, | 6019 FindStringIndices(isolate, |
| 5996 subject_vector, | 6020 subject_vector, |
| 5997 pattern->ToAsciiVector(), | 6021 pattern_content.ToAsciiVector(), |
| 5998 &indices, | 6022 &indices, |
| 5999 limit); | 6023 limit); |
| 6000 } else { | 6024 } else { |
| 6001 FindStringIndices(isolate, | 6025 FindStringIndices(isolate, |
| 6002 subject_vector, | 6026 subject_vector, |
| 6003 pattern->ToUC16Vector(), | 6027 pattern_content.ToUC16Vector(), |
| 6004 &indices, | 6028 &indices, |
| 6005 limit); | 6029 limit); |
| 6006 } | 6030 } |
| 6007 } | 6031 } |
| 6008 } | 6032 } |
| 6009 | 6033 |
| 6010 if (static_cast<uint32_t>(indices.length()) < limit) { | 6034 if (static_cast<uint32_t>(indices.length()) < limit) { |
| 6011 indices.Add(subject_length); | 6035 indices.Add(subject_length); |
| 6012 } | 6036 } |
| 6013 | 6037 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 6042 | 6066 |
| 6043 | 6067 |
| 6044 // Copies ascii characters to the given fixed array looking up | 6068 // Copies ascii characters to the given fixed array looking up |
| 6045 // one-char strings in the cache. Gives up on the first char that is | 6069 // one-char strings in the cache. Gives up on the first char that is |
| 6046 // not in the cache and fills the remainder with smi zeros. Returns | 6070 // not in the cache and fills the remainder with smi zeros. Returns |
| 6047 // the length of the successfully copied prefix. | 6071 // the length of the successfully copied prefix. |
| 6048 static int CopyCachedAsciiCharsToArray(Heap* heap, | 6072 static int CopyCachedAsciiCharsToArray(Heap* heap, |
| 6049 const char* chars, | 6073 const char* chars, |
| 6050 FixedArray* elements, | 6074 FixedArray* elements, |
| 6051 int length) { | 6075 int length) { |
| 6052 AssertNoAllocation nogc; | 6076 AssertNoAllocation no_gc; |
| 6053 FixedArray* ascii_cache = heap->single_character_string_cache(); | 6077 FixedArray* ascii_cache = heap->single_character_string_cache(); |
| 6054 Object* undefined = heap->undefined_value(); | 6078 Object* undefined = heap->undefined_value(); |
| 6055 int i; | 6079 int i; |
| 6056 for (i = 0; i < length; ++i) { | 6080 for (i = 0; i < length; ++i) { |
| 6057 Object* value = ascii_cache->get(chars[i]); | 6081 Object* value = ascii_cache->get(chars[i]); |
| 6058 if (value == undefined) break; | 6082 if (value == undefined) break; |
| 6059 ASSERT(!heap->InNewSpace(value)); | 6083 ASSERT(!heap->InNewSpace(value)); |
| 6060 elements->set(i, value, SKIP_WRITE_BARRIER); | 6084 elements->set(i, value, SKIP_WRITE_BARRIER); |
| 6061 } | 6085 } |
| 6062 if (i < length) { | 6086 if (i < length) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 6075 | 6099 |
| 6076 | 6100 |
| 6077 // Converts a String to JSArray. | 6101 // Converts a String to JSArray. |
| 6078 // For example, "foo" => ["f", "o", "o"]. | 6102 // For example, "foo" => ["f", "o", "o"]. |
| 6079 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringToArray) { | 6103 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringToArray) { |
| 6080 HandleScope scope(isolate); | 6104 HandleScope scope(isolate); |
| 6081 ASSERT(args.length() == 2); | 6105 ASSERT(args.length() == 2); |
| 6082 CONVERT_ARG_CHECKED(String, s, 0); | 6106 CONVERT_ARG_CHECKED(String, s, 0); |
| 6083 CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]); | 6107 CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]); |
| 6084 | 6108 |
| 6085 s->TryFlatten(); | 6109 s = FlattenGetString(s); |
| 6086 const int length = static_cast<int>(Min<uint32_t>(s->length(), limit)); | 6110 const int length = static_cast<int>(Min<uint32_t>(s->length(), limit)); |
| 6087 | 6111 |
| 6088 Handle<FixedArray> elements; | 6112 Handle<FixedArray> elements; |
| 6113 int position = 0; |
| 6089 if (s->IsFlat() && s->IsAsciiRepresentation()) { | 6114 if (s->IsFlat() && s->IsAsciiRepresentation()) { |
| 6115 // Try using cached chars where possible. |
| 6090 Object* obj; | 6116 Object* obj; |
| 6091 { MaybeObject* maybe_obj = | 6117 { MaybeObject* maybe_obj = |
| 6092 isolate->heap()->AllocateUninitializedFixedArray(length); | 6118 isolate->heap()->AllocateUninitializedFixedArray(length); |
| 6093 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 6119 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 6094 } | 6120 } |
| 6095 elements = Handle<FixedArray>(FixedArray::cast(obj), isolate); | 6121 elements = Handle<FixedArray>(FixedArray::cast(obj), isolate); |
| 6096 | 6122 String::FlatContent content = s->GetFlatContent(); |
| 6097 Vector<const char> chars = s->ToAsciiVector(); | 6123 if (content.IsAscii()) { |
| 6098 // Note, this will initialize all elements (not only the prefix) | 6124 Vector<const char> chars = content.ToAsciiVector(); |
| 6099 // to prevent GC from seeing partially initialized array. | 6125 // Note, this will initialize all elements (not only the prefix) |
| 6100 int num_copied_from_cache = CopyCachedAsciiCharsToArray(isolate->heap(), | 6126 // to prevent GC from seeing partially initialized array. |
| 6101 chars.start(), | 6127 position = CopyCachedAsciiCharsToArray(isolate->heap(), |
| 6102 *elements, | 6128 chars.start(), |
| 6103 length); | 6129 *elements, |
| 6104 | 6130 length); |
| 6105 for (int i = num_copied_from_cache; i < length; ++i) { | 6131 } else { |
| 6106 Handle<Object> str = LookupSingleCharacterStringFromCode(chars[i]); | 6132 MemsetPointer(elements->data_start(), |
| 6107 elements->set(i, *str); | 6133 isolate->heap()->undefined_value(), |
| 6134 length); |
| 6108 } | 6135 } |
| 6109 } else { | 6136 } else { |
| 6110 elements = isolate->factory()->NewFixedArray(length); | 6137 elements = isolate->factory()->NewFixedArray(length); |
| 6111 for (int i = 0; i < length; ++i) { | 6138 } |
| 6112 Handle<Object> str = LookupSingleCharacterStringFromCode(s->Get(i)); | 6139 for (int i = position; i < length; ++i) { |
| 6113 elements->set(i, *str); | 6140 Handle<Object> str = LookupSingleCharacterStringFromCode(s->Get(i)); |
| 6114 } | 6141 elements->set(i, *str); |
| 6115 } | 6142 } |
| 6116 | 6143 |
| 6117 #ifdef DEBUG | 6144 #ifdef DEBUG |
| 6118 for (int i = 0; i < length; ++i) { | 6145 for (int i = 0; i < length; ++i) { |
| 6119 ASSERT(String::cast(elements->get(i))->length() == 1); | 6146 ASSERT(String::cast(elements->get(i))->length() == 1); |
| 6120 } | 6147 } |
| 6121 #endif | 6148 #endif |
| 6122 | 6149 |
| 6123 return *isolate->factory()->NewJSArrayWithElements(elements); | 6150 return *isolate->factory()->NewJSArrayWithElements(elements); |
| 6124 } | 6151 } |
| (...skipping 790 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6915 ASSERT(y->IsFlat()); | 6942 ASSERT(y->IsFlat()); |
| 6916 Object* equal_prefix_result = Smi::FromInt(EQUAL); | 6943 Object* equal_prefix_result = Smi::FromInt(EQUAL); |
| 6917 int prefix_length = x->length(); | 6944 int prefix_length = x->length(); |
| 6918 if (y->length() < prefix_length) { | 6945 if (y->length() < prefix_length) { |
| 6919 prefix_length = y->length(); | 6946 prefix_length = y->length(); |
| 6920 equal_prefix_result = Smi::FromInt(GREATER); | 6947 equal_prefix_result = Smi::FromInt(GREATER); |
| 6921 } else if (y->length() > prefix_length) { | 6948 } else if (y->length() > prefix_length) { |
| 6922 equal_prefix_result = Smi::FromInt(LESS); | 6949 equal_prefix_result = Smi::FromInt(LESS); |
| 6923 } | 6950 } |
| 6924 int r; | 6951 int r; |
| 6925 if (x->IsAsciiRepresentation()) { | 6952 String::FlatContent x_content = x->GetFlatContent(); |
| 6926 Vector<const char> x_chars = x->ToAsciiVector(); | 6953 String::FlatContent y_content = y->GetFlatContent(); |
| 6927 if (y->IsAsciiRepresentation()) { | 6954 if (x_content.IsAscii()) { |
| 6928 Vector<const char> y_chars = y->ToAsciiVector(); | 6955 Vector<const char> x_chars = x_content.ToAsciiVector(); |
| 6956 if (y_content.IsAscii()) { |
| 6957 Vector<const char> y_chars = y_content.ToAsciiVector(); |
| 6929 r = CompareChars(x_chars.start(), y_chars.start(), prefix_length); | 6958 r = CompareChars(x_chars.start(), y_chars.start(), prefix_length); |
| 6930 } else { | 6959 } else { |
| 6931 Vector<const uc16> y_chars = y->ToUC16Vector(); | 6960 Vector<const uc16> y_chars = y_content.ToUC16Vector(); |
| 6932 r = CompareChars(x_chars.start(), y_chars.start(), prefix_length); | 6961 r = CompareChars(x_chars.start(), y_chars.start(), prefix_length); |
| 6933 } | 6962 } |
| 6934 } else { | 6963 } else { |
| 6935 Vector<const uc16> x_chars = x->ToUC16Vector(); | 6964 Vector<const uc16> x_chars = x_content.ToUC16Vector(); |
| 6936 if (y->IsAsciiRepresentation()) { | 6965 if (y_content.IsAscii()) { |
| 6937 Vector<const char> y_chars = y->ToAsciiVector(); | 6966 Vector<const char> y_chars = y_content.ToAsciiVector(); |
| 6938 r = CompareChars(x_chars.start(), y_chars.start(), prefix_length); | 6967 r = CompareChars(x_chars.start(), y_chars.start(), prefix_length); |
| 6939 } else { | 6968 } else { |
| 6940 Vector<const uc16> y_chars = y->ToUC16Vector(); | 6969 Vector<const uc16> y_chars = y_content.ToUC16Vector(); |
| 6941 r = CompareChars(x_chars.start(), y_chars.start(), prefix_length); | 6970 r = CompareChars(x_chars.start(), y_chars.start(), prefix_length); |
| 6942 } | 6971 } |
| 6943 } | 6972 } |
| 6944 Object* result; | 6973 Object* result; |
| 6945 if (r == 0) { | 6974 if (r == 0) { |
| 6946 result = equal_prefix_result; | 6975 result = equal_prefix_result; |
| 6947 } else { | 6976 } else { |
| 6948 result = (r < 0) ? Smi::FromInt(LESS) : Smi::FromInt(GREATER); | 6977 result = (r < 0) ? Smi::FromInt(LESS) : Smi::FromInt(GREATER); |
| 6949 } | 6978 } |
| 6950 ASSERT(result == | 6979 ASSERT(result == |
| (...skipping 1359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8310 isolate->heap()->AllocateCatchContext(function, | 8339 isolate->heap()->AllocateCatchContext(function, |
| 8311 isolate->context(), | 8340 isolate->context(), |
| 8312 name, | 8341 name, |
| 8313 thrown_object); | 8342 thrown_object); |
| 8314 if (!maybe_context->To(&context)) return maybe_context; | 8343 if (!maybe_context->To(&context)) return maybe_context; |
| 8315 isolate->set_context(context); | 8344 isolate->set_context(context); |
| 8316 return context; | 8345 return context; |
| 8317 } | 8346 } |
| 8318 | 8347 |
| 8319 | 8348 |
| 8349 RUNTIME_FUNCTION(MaybeObject*, Runtime_PushBlockContext) { |
| 8350 NoHandleAllocation ha; |
| 8351 ASSERT(args.length() == 2); |
| 8352 SerializedScopeInfo* scope_info = SerializedScopeInfo::cast(args[0]); |
| 8353 JSFunction* function; |
| 8354 if (args[1]->IsSmi()) { |
| 8355 // A smi sentinel indicates a context nested inside global code rather |
| 8356 // than some function. There is a canonical empty function that can be |
| 8357 // gotten from the global context. |
| 8358 function = isolate->context()->global_context()->closure(); |
| 8359 } else { |
| 8360 function = JSFunction::cast(args[1]); |
| 8361 } |
| 8362 Context* context; |
| 8363 MaybeObject* maybe_context = |
| 8364 isolate->heap()->AllocateBlockContext(function, |
| 8365 isolate->context(), |
| 8366 scope_info); |
| 8367 if (!maybe_context->To(&context)) return maybe_context; |
| 8368 isolate->set_context(context); |
| 8369 return context; |
| 8370 } |
| 8371 |
| 8372 |
| 8320 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeleteContextSlot) { | 8373 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeleteContextSlot) { |
| 8321 HandleScope scope(isolate); | 8374 HandleScope scope(isolate); |
| 8322 ASSERT(args.length() == 2); | 8375 ASSERT(args.length() == 2); |
| 8323 | 8376 |
| 8324 CONVERT_ARG_CHECKED(Context, context, 0); | 8377 CONVERT_ARG_CHECKED(Context, context, 0); |
| 8325 CONVERT_ARG_CHECKED(String, name, 1); | 8378 CONVERT_ARG_CHECKED(String, name, 1); |
| 8326 | 8379 |
| 8327 int index; | 8380 int index; |
| 8328 PropertyAttributes attributes; | 8381 PropertyAttributes attributes; |
| 8329 ContextLookupFlags flags = FOLLOW_CHAINS; | 8382 ContextLookupFlags flags = FOLLOW_CHAINS; |
| (...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8787 FlattenString(str); | 8840 FlattenString(str); |
| 8788 | 8841 |
| 8789 CONVERT_ARG_CHECKED(JSArray, output, 1); | 8842 CONVERT_ARG_CHECKED(JSArray, output, 1); |
| 8790 RUNTIME_ASSERT(output->HasFastElements()); | 8843 RUNTIME_ASSERT(output->HasFastElements()); |
| 8791 | 8844 |
| 8792 AssertNoAllocation no_allocation; | 8845 AssertNoAllocation no_allocation; |
| 8793 | 8846 |
| 8794 FixedArray* output_array = FixedArray::cast(output->elements()); | 8847 FixedArray* output_array = FixedArray::cast(output->elements()); |
| 8795 RUNTIME_ASSERT(output_array->length() >= DateParser::OUTPUT_SIZE); | 8848 RUNTIME_ASSERT(output_array->length() >= DateParser::OUTPUT_SIZE); |
| 8796 bool result; | 8849 bool result; |
| 8797 if (str->IsAsciiRepresentation()) { | 8850 String::FlatContent str_content = str->GetFlatContent(); |
| 8798 result = DateParser::Parse(str->ToAsciiVector(), | 8851 if (str_content.IsAscii()) { |
| 8852 result = DateParser::Parse(str_content.ToAsciiVector(), |
| 8799 output_array, | 8853 output_array, |
| 8800 isolate->unicode_cache()); | 8854 isolate->unicode_cache()); |
| 8801 } else { | 8855 } else { |
| 8802 ASSERT(str->IsTwoByteRepresentation()); | 8856 ASSERT(str_content.IsTwoByte()); |
| 8803 result = DateParser::Parse(str->ToUC16Vector(), | 8857 result = DateParser::Parse(str_content.ToUC16Vector(), |
| 8804 output_array, | 8858 output_array, |
| 8805 isolate->unicode_cache()); | 8859 isolate->unicode_cache()); |
| 8806 } | 8860 } |
| 8807 | 8861 |
| 8808 if (result) { | 8862 if (result) { |
| 8809 return *output; | 8863 return *output; |
| 8810 } else { | 8864 } else { |
| 8811 return isolate->heap()->null_value(); | 8865 return isolate->heap()->null_value(); |
| 8812 } | 8866 } |
| 8813 } | 8867 } |
| (...skipping 836 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9650 CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]); | 9704 CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]); |
| 9651 return object->PrepareElementsForSort(limit); | 9705 return object->PrepareElementsForSort(limit); |
| 9652 } | 9706 } |
| 9653 | 9707 |
| 9654 | 9708 |
| 9655 // Move contents of argument 0 (an array) to argument 1 (an array) | 9709 // Move contents of argument 0 (an array) to argument 1 (an array) |
| 9656 RUNTIME_FUNCTION(MaybeObject*, Runtime_MoveArrayContents) { | 9710 RUNTIME_FUNCTION(MaybeObject*, Runtime_MoveArrayContents) { |
| 9657 ASSERT(args.length() == 2); | 9711 ASSERT(args.length() == 2); |
| 9658 CONVERT_CHECKED(JSArray, from, args[0]); | 9712 CONVERT_CHECKED(JSArray, from, args[0]); |
| 9659 CONVERT_CHECKED(JSArray, to, args[1]); | 9713 CONVERT_CHECKED(JSArray, to, args[1]); |
| 9660 HeapObject* new_elements = from->elements(); | 9714 FixedArrayBase* new_elements = from->elements(); |
| 9661 MaybeObject* maybe_new_map; | 9715 MaybeObject* maybe_new_map; |
| 9662 if (new_elements->map() == isolate->heap()->fixed_array_map() || | 9716 if (new_elements->map() == isolate->heap()->fixed_array_map() || |
| 9663 new_elements->map() == isolate->heap()->fixed_cow_array_map()) { | 9717 new_elements->map() == isolate->heap()->fixed_cow_array_map()) { |
| 9664 maybe_new_map = to->map()->GetFastElementsMap(); | 9718 maybe_new_map = to->map()->GetFastElementsMap(); |
| 9665 } else if (new_elements->map() == | 9719 } else if (new_elements->map() == |
| 9666 isolate->heap()->fixed_double_array_map()) { | 9720 isolate->heap()->fixed_double_array_map()) { |
| 9667 maybe_new_map = to->map()->GetFastDoubleElementsMap(); | 9721 maybe_new_map = to->map()->GetFastDoubleElementsMap(); |
| 9668 } else { | 9722 } else { |
| 9669 maybe_new_map = to->map()->GetSlowElementsMap(); | 9723 maybe_new_map = to->map()->GetSlowElementsMap(); |
| 9670 } | 9724 } |
| (...skipping 964 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10635 Handle<JSObject> catch_scope = | 10689 Handle<JSObject> catch_scope = |
| 10636 isolate->factory()->NewJSObject(isolate->object_function()); | 10690 isolate->factory()->NewJSObject(isolate->object_function()); |
| 10637 RETURN_IF_EMPTY_HANDLE_VALUE( | 10691 RETURN_IF_EMPTY_HANDLE_VALUE( |
| 10638 isolate, | 10692 isolate, |
| 10639 SetProperty(catch_scope, name, thrown_object, NONE, kNonStrictMode), | 10693 SetProperty(catch_scope, name, thrown_object, NONE, kNonStrictMode), |
| 10640 Handle<JSObject>()); | 10694 Handle<JSObject>()); |
| 10641 return catch_scope; | 10695 return catch_scope; |
| 10642 } | 10696 } |
| 10643 | 10697 |
| 10644 | 10698 |
| 10699 // Create a plain JSObject which materializes the block scope for the specified |
| 10700 // block context. |
| 10701 static Handle<JSObject> MaterializeBlockScope( |
| 10702 Isolate* isolate, |
| 10703 Handle<Context> context) { |
| 10704 ASSERT(context->IsBlockContext()); |
| 10705 Handle<SerializedScopeInfo> serialized_scope_info( |
| 10706 SerializedScopeInfo::cast(context->extension())); |
| 10707 ScopeInfo<> scope_info(*serialized_scope_info); |
| 10708 |
| 10709 // Allocate and initialize a JSObject with all the arguments, stack locals |
| 10710 // heap locals and extension properties of the debugged function. |
| 10711 Handle<JSObject> block_scope = |
| 10712 isolate->factory()->NewJSObject(isolate->object_function()); |
| 10713 |
| 10714 // Fill all context locals. |
| 10715 if (scope_info.number_of_context_slots() > Context::MIN_CONTEXT_SLOTS) { |
| 10716 if (!CopyContextLocalsToScopeObject(isolate, |
| 10717 serialized_scope_info, scope_info, |
| 10718 context, block_scope)) { |
| 10719 return Handle<JSObject>(); |
| 10720 } |
| 10721 } |
| 10722 |
| 10723 return block_scope; |
| 10724 } |
| 10725 |
| 10726 |
| 10645 // Iterate over the actual scopes visible from a stack frame. All scopes are | 10727 // Iterate over the actual scopes visible from a stack frame. All scopes are |
| 10646 // backed by an actual context except the local scope, which is inserted | 10728 // backed by an actual context except the local scope, which is inserted |
| 10647 // "artifically" in the context chain. | 10729 // "artifically" in the context chain. |
| 10648 class ScopeIterator { | 10730 class ScopeIterator { |
| 10649 public: | 10731 public: |
| 10650 enum ScopeType { | 10732 enum ScopeType { |
| 10651 ScopeTypeGlobal = 0, | 10733 ScopeTypeGlobal = 0, |
| 10652 ScopeTypeLocal, | 10734 ScopeTypeLocal, |
| 10653 ScopeTypeWith, | 10735 ScopeTypeWith, |
| 10654 ScopeTypeClosure, | 10736 ScopeTypeClosure, |
| 10655 ScopeTypeCatch | 10737 ScopeTypeCatch, |
| 10738 ScopeTypeBlock |
| 10656 }; | 10739 }; |
| 10657 | 10740 |
| 10658 ScopeIterator(Isolate* isolate, | 10741 ScopeIterator(Isolate* isolate, |
| 10659 JavaScriptFrame* frame, | 10742 JavaScriptFrame* frame, |
| 10660 int inlined_frame_index) | 10743 int inlined_frame_index) |
| 10661 : isolate_(isolate), | 10744 : isolate_(isolate), |
| 10662 frame_(frame), | 10745 frame_(frame), |
| 10663 inlined_frame_index_(inlined_frame_index), | 10746 inlined_frame_index_(inlined_frame_index), |
| 10664 function_(JSFunction::cast(frame->function())), | 10747 function_(JSFunction::cast(frame->function())), |
| 10665 context_(Context::cast(frame->context())), | 10748 context_(Context::cast(frame->context())), |
| 10666 local_done_(false), | 10749 local_done_(false), |
| 10667 at_local_(false) { | 10750 at_local_(false) { |
| 10668 | 10751 |
| 10669 // Check whether the first scope is actually a local scope. | 10752 // Check whether the first scope is actually a local scope. |
| 10670 if (context_->IsGlobalContext()) { | 10753 if (context_->IsGlobalContext()) { |
| 10671 // If there is a stack slot for .result then this local scope has been | 10754 // If there is a stack slot for .result then this local scope has been |
| 10672 // created for evaluating top level code and it is not a real local scope. | 10755 // created for evaluating top level code and it is not a real local scope. |
| 10673 // Checking for the existence of .result seems fragile, but the scope info | 10756 // Checking for the existence of .result seems fragile, but the scope info |
| 10674 // saved with the code object does not otherwise have that information. | 10757 // saved with the code object does not otherwise have that information. |
| 10675 int index = function_->shared()->scope_info()-> | 10758 int index = function_->shared()->scope_info()-> |
| 10676 StackSlotIndex(isolate_->heap()->result_symbol()); | 10759 StackSlotIndex(isolate_->heap()->result_symbol()); |
| 10677 at_local_ = index < 0; | 10760 at_local_ = index < 0; |
| 10678 } else if (context_->IsFunctionContext()) { | 10761 } else if (context_->IsFunctionContext()) { |
| 10679 at_local_ = true; | 10762 at_local_ = true; |
| 10680 } else if (context_->closure() != *function_) { | 10763 } else if (context_->closure() != *function_) { |
| 10681 // The context_ is a with or catch block from the outer function. | 10764 // The context_ is a block or with or catch block from the outer function. |
| 10682 ASSERT(context_->IsWithContext() || context_->IsCatchContext()); | 10765 ASSERT(context_->IsWithContext() || |
| 10766 context_->IsCatchContext() || |
| 10767 context_->IsBlockContext()); |
| 10683 at_local_ = true; | 10768 at_local_ = true; |
| 10684 } | 10769 } |
| 10685 } | 10770 } |
| 10686 | 10771 |
| 10687 // More scopes? | 10772 // More scopes? |
| 10688 bool Done() { return context_.is_null(); } | 10773 bool Done() { return context_.is_null(); } |
| 10689 | 10774 |
| 10690 // Move to the next scope. | 10775 // Move to the next scope. |
| 10691 void Next() { | 10776 void Next() { |
| 10692 // If at a local scope mark the local scope as passed. | 10777 // If at a local scope mark the local scope as passed. |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10727 if (context_->IsGlobalContext()) { | 10812 if (context_->IsGlobalContext()) { |
| 10728 ASSERT(context_->global()->IsGlobalObject()); | 10813 ASSERT(context_->global()->IsGlobalObject()); |
| 10729 return ScopeTypeGlobal; | 10814 return ScopeTypeGlobal; |
| 10730 } | 10815 } |
| 10731 if (context_->IsFunctionContext()) { | 10816 if (context_->IsFunctionContext()) { |
| 10732 return ScopeTypeClosure; | 10817 return ScopeTypeClosure; |
| 10733 } | 10818 } |
| 10734 if (context_->IsCatchContext()) { | 10819 if (context_->IsCatchContext()) { |
| 10735 return ScopeTypeCatch; | 10820 return ScopeTypeCatch; |
| 10736 } | 10821 } |
| 10822 if (context_->IsBlockContext()) { |
| 10823 return ScopeTypeBlock; |
| 10824 } |
| 10737 ASSERT(context_->IsWithContext()); | 10825 ASSERT(context_->IsWithContext()); |
| 10738 return ScopeTypeWith; | 10826 return ScopeTypeWith; |
| 10739 } | 10827 } |
| 10740 | 10828 |
| 10741 // Return the JavaScript object with the content of the current scope. | 10829 // Return the JavaScript object with the content of the current scope. |
| 10742 Handle<JSObject> ScopeObject() { | 10830 Handle<JSObject> ScopeObject() { |
| 10743 switch (Type()) { | 10831 switch (Type()) { |
| 10744 case ScopeIterator::ScopeTypeGlobal: | 10832 case ScopeIterator::ScopeTypeGlobal: |
| 10745 return Handle<JSObject>(CurrentContext()->global()); | 10833 return Handle<JSObject>(CurrentContext()->global()); |
| 10746 case ScopeIterator::ScopeTypeLocal: | 10834 case ScopeIterator::ScopeTypeLocal: |
| 10747 // Materialize the content of the local scope into a JSObject. | 10835 // Materialize the content of the local scope into a JSObject. |
| 10748 return MaterializeLocalScope(isolate_, frame_, inlined_frame_index_); | 10836 return MaterializeLocalScope(isolate_, frame_, inlined_frame_index_); |
| 10749 case ScopeIterator::ScopeTypeWith: | 10837 case ScopeIterator::ScopeTypeWith: |
| 10750 // Return the with object. | 10838 // Return the with object. |
| 10751 return Handle<JSObject>(JSObject::cast(CurrentContext()->extension())); | 10839 return Handle<JSObject>(JSObject::cast(CurrentContext()->extension())); |
| 10752 case ScopeIterator::ScopeTypeCatch: | 10840 case ScopeIterator::ScopeTypeCatch: |
| 10753 return MaterializeCatchScope(isolate_, CurrentContext()); | 10841 return MaterializeCatchScope(isolate_, CurrentContext()); |
| 10754 case ScopeIterator::ScopeTypeClosure: | 10842 case ScopeIterator::ScopeTypeClosure: |
| 10755 // Materialize the content of the closure scope into a JSObject. | 10843 // Materialize the content of the closure scope into a JSObject. |
| 10756 return MaterializeClosure(isolate_, CurrentContext()); | 10844 return MaterializeClosure(isolate_, CurrentContext()); |
| 10845 case ScopeIterator::ScopeTypeBlock: |
| 10846 return MaterializeBlockScope(isolate_, CurrentContext()); |
| 10757 } | 10847 } |
| 10758 UNREACHABLE(); | 10848 UNREACHABLE(); |
| 10759 return Handle<JSObject>(); | 10849 return Handle<JSObject>(); |
| 10760 } | 10850 } |
| 10761 | 10851 |
| 10762 // Return the context for this scope. For the local context there might not | 10852 // Return the context for this scope. For the local context there might not |
| 10763 // be an actual context. | 10853 // be an actual context. |
| 10764 Handle<Context> CurrentContext() { | 10854 Handle<Context> CurrentContext() { |
| 10765 if (at_local_ && context_->closure() != *function_) { | 10855 if (at_local_ && context_->closure() != *function_) { |
| 10766 return Handle<Context>(); | 10856 return Handle<Context>(); |
| (...skipping 541 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11308 CopyWithContextChain(isolate, function, previous, base); | 11398 CopyWithContextChain(isolate, function, previous, base); |
| 11309 Handle<Context> new_current; | 11399 Handle<Context> new_current; |
| 11310 if (current->IsCatchContext()) { | 11400 if (current->IsCatchContext()) { |
| 11311 Handle<String> name(String::cast(current->extension())); | 11401 Handle<String> name(String::cast(current->extension())); |
| 11312 Handle<Object> thrown_object(current->get(Context::THROWN_OBJECT_INDEX)); | 11402 Handle<Object> thrown_object(current->get(Context::THROWN_OBJECT_INDEX)); |
| 11313 new_current = | 11403 new_current = |
| 11314 isolate->factory()->NewCatchContext(function, | 11404 isolate->factory()->NewCatchContext(function, |
| 11315 new_previous, | 11405 new_previous, |
| 11316 name, | 11406 name, |
| 11317 thrown_object); | 11407 thrown_object); |
| 11408 } else if (current->IsBlockContext()) { |
| 11409 Handle<SerializedScopeInfo> scope_info( |
| 11410 SerializedScopeInfo::cast(current->extension())); |
| 11411 new_current = |
| 11412 isolate->factory()->NewBlockContext(function, new_previous, scope_info); |
| 11413 // Copy context slots. |
| 11414 int num_context_slots = scope_info->NumberOfContextSlots(); |
| 11415 for (int i = Context::MIN_CONTEXT_SLOTS; i < num_context_slots; ++i) { |
| 11416 new_current->set(i, current->get(i)); |
| 11417 } |
| 11318 } else { | 11418 } else { |
| 11419 ASSERT(current->IsWithContext()); |
| 11319 Handle<JSObject> extension(JSObject::cast(current->extension())); | 11420 Handle<JSObject> extension(JSObject::cast(current->extension())); |
| 11320 new_current = | 11421 new_current = |
| 11321 isolate->factory()->NewWithContext(function, new_previous, extension); | 11422 isolate->factory()->NewWithContext(function, new_previous, extension); |
| 11322 } | 11423 } |
| 11323 return scope.CloseAndEscape(new_current); | 11424 return scope.CloseAndEscape(new_current); |
| 11324 } | 11425 } |
| 11325 | 11426 |
| 11326 | 11427 |
| 11327 // Helper function to find or create the arguments object for | 11428 // Helper function to find or create the arguments object for |
| 11328 // Runtime_DebugEvaluate. | 11429 // Runtime_DebugEvaluate. |
| (...skipping 1443 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12772 Handle<JSArray> result = factory->NewJSArrayWithElements(elements); | 12873 Handle<JSArray> result = factory->NewJSArrayWithElements(elements); |
| 12773 return *result; | 12874 return *result; |
| 12774 } | 12875 } |
| 12775 #endif | 12876 #endif |
| 12776 | 12877 |
| 12777 | 12878 |
| 12778 RUNTIME_FUNCTION(MaybeObject*, Runtime_Log) { | 12879 RUNTIME_FUNCTION(MaybeObject*, Runtime_Log) { |
| 12779 ASSERT(args.length() == 2); | 12880 ASSERT(args.length() == 2); |
| 12780 CONVERT_CHECKED(String, format, args[0]); | 12881 CONVERT_CHECKED(String, format, args[0]); |
| 12781 CONVERT_CHECKED(JSArray, elms, args[1]); | 12882 CONVERT_CHECKED(JSArray, elms, args[1]); |
| 12782 Vector<const char> chars = format->ToAsciiVector(); | 12883 String::FlatContent format_content = format->GetFlatContent(); |
| 12884 RUNTIME_ASSERT(format_content.IsAscii()); |
| 12885 Vector<const char> chars = format_content.ToAsciiVector(); |
| 12783 LOGGER->LogRuntime(chars, elms); | 12886 LOGGER->LogRuntime(chars, elms); |
| 12784 return isolate->heap()->undefined_value(); | 12887 return isolate->heap()->undefined_value(); |
| 12785 } | 12888 } |
| 12786 | 12889 |
| 12787 | 12890 |
| 12788 RUNTIME_FUNCTION(MaybeObject*, Runtime_IS_VAR) { | 12891 RUNTIME_FUNCTION(MaybeObject*, Runtime_IS_VAR) { |
| 12789 UNREACHABLE(); // implemented as macro in the parser | 12892 UNREACHABLE(); // implemented as macro in the parser |
| 12790 return NULL; | 12893 return NULL; |
| 12791 } | 12894 } |
| 12792 | 12895 |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12889 } else { | 12992 } else { |
| 12890 // Handle last resort GC and make sure to allow future allocations | 12993 // Handle last resort GC and make sure to allow future allocations |
| 12891 // to grow the heap without causing GCs (if possible). | 12994 // to grow the heap without causing GCs (if possible). |
| 12892 isolate->counters()->gc_last_resort_from_js()->Increment(); | 12995 isolate->counters()->gc_last_resort_from_js()->Increment(); |
| 12893 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags); | 12996 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags); |
| 12894 } | 12997 } |
| 12895 } | 12998 } |
| 12896 | 12999 |
| 12897 | 13000 |
| 12898 } } // namespace v8::internal | 13001 } } // namespace v8::internal |
| OLD | NEW |