OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/builtins.h" | 5 #include "src/builtins.h" |
6 | 6 |
7 #include "src/api-arguments.h" | 7 #include "src/api-arguments.h" |
8 #include "src/api-natives.h" | 8 #include "src/api-natives.h" |
9 #include "src/api.h" | 9 #include "src/api.h" |
10 #include "src/base/ieee754.h" | 10 #include "src/base/ieee754.h" |
(...skipping 4615 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4626 | 4626 |
4627 // ES6 section 21.1.2.1 String.fromCharCode ( ...codeUnits ) | 4627 // ES6 section 21.1.2.1 String.fromCharCode ( ...codeUnits ) |
4628 void Builtins::Generate_StringFromCharCode(CodeStubAssembler* assembler) { | 4628 void Builtins::Generate_StringFromCharCode(CodeStubAssembler* assembler) { |
4629 typedef CodeStubAssembler::Label Label; | 4629 typedef CodeStubAssembler::Label Label; |
4630 typedef compiler::Node Node; | 4630 typedef compiler::Node Node; |
4631 typedef CodeStubAssembler::Variable Variable; | 4631 typedef CodeStubAssembler::Variable Variable; |
4632 | 4632 |
4633 Node* code = assembler->Parameter(1); | 4633 Node* code = assembler->Parameter(1); |
4634 Node* context = assembler->Parameter(4); | 4634 Node* context = assembler->Parameter(4); |
4635 | 4635 |
4636 // Check if we have exactly one arguments (plus the implicit receiver), i.e. | 4636 // Check if we have exactly one argument (plus the implicit receiver), i.e. |
4637 // if the parent frame is not an arguments adaptor frame. | 4637 // if the parent frame is not an arguments adaptor frame. |
4638 Label if_oneargument(assembler), if_notoneargument(assembler); | 4638 Label if_oneargument(assembler), if_notoneargument(assembler); |
4639 Node* parent_frame_pointer = assembler->LoadParentFramePointer(); | 4639 Node* parent_frame_pointer = assembler->LoadParentFramePointer(); |
4640 Node* parent_frame_type = | 4640 Node* parent_frame_type = |
4641 assembler->Load(MachineType::Pointer(), parent_frame_pointer, | 4641 assembler->Load(MachineType::Pointer(), parent_frame_pointer, |
4642 assembler->IntPtrConstant( | 4642 assembler->IntPtrConstant( |
4643 CommonFrameConstants::kContextOrFrameTypeOffset)); | 4643 CommonFrameConstants::kContextOrFrameTypeOffset)); |
4644 assembler->Branch( | 4644 assembler->Branch( |
4645 assembler->WordEqual( | 4645 assembler->WordEqual( |
4646 parent_frame_type, | 4646 parent_frame_type, |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4804 assembler->Bind(&done_floop); | 4804 assembler->Bind(&done_floop); |
4805 assembler->Return(cresult); | 4805 assembler->Return(cresult); |
4806 } | 4806 } |
4807 } | 4807 } |
4808 | 4808 |
4809 assembler->Bind(&done_loop); | 4809 assembler->Bind(&done_loop); |
4810 assembler->Return(result); | 4810 assembler->Return(result); |
4811 } | 4811 } |
4812 } | 4812 } |
4813 | 4813 |
| 4814 namespace { // for String.fromCodePoint |
| 4815 |
| 4816 bool IsValidCodePoint(Isolate* isolate, Handle<Object> value) { |
| 4817 if (!value->IsNumber() && !Object::ToNumber(value).ToHandle(&value)) { |
| 4818 return false; |
| 4819 } |
| 4820 |
| 4821 if (Object::ToInteger(isolate, value).ToHandleChecked()->Number() != |
| 4822 value->Number()) { |
| 4823 return false; |
| 4824 } |
| 4825 |
| 4826 if (value->Number() < 0 || value->Number() > 0x10FFFF) { |
| 4827 return false; |
| 4828 } |
| 4829 |
| 4830 return true; |
| 4831 } |
| 4832 |
| 4833 uc32 NextCodePoint(Isolate* isolate, BuiltinArguments args, int index) { |
| 4834 Handle<Object> value = args.at<Object>(1 + index); |
| 4835 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, value, Object::ToNumber(value), -1); |
| 4836 if (!IsValidCodePoint(isolate, value)) { |
| 4837 isolate->Throw(*isolate->factory()->NewRangeError( |
| 4838 MessageTemplate::kInvalidCodePoint, value)); |
| 4839 return -1; |
| 4840 } |
| 4841 return DoubleToUint32(value->Number()); |
| 4842 } |
| 4843 |
| 4844 } // namespace |
| 4845 |
| 4846 // ES6 section 21.1.2.2 String.fromCodePoint ( ...codePoints ) |
| 4847 BUILTIN(StringFromCodePoint) { |
| 4848 HandleScope scope(isolate); |
| 4849 int const length = args.length() - 1; |
| 4850 if (length == 0) return isolate->heap()->empty_string(); |
| 4851 DCHECK_LT(0, length); |
| 4852 |
| 4853 // Optimistically assume that the resulting String contains only one byte |
| 4854 // characters. |
| 4855 List<uint8_t> one_byte_buffer(length); |
| 4856 uc32 code = 0; |
| 4857 int index; |
| 4858 for (index = 0; index < length; index++) { |
| 4859 code = NextCodePoint(isolate, args, index); |
| 4860 if (code < 0) { |
| 4861 return isolate->heap()->exception(); |
| 4862 } |
| 4863 if (code > String::kMaxOneByteCharCode) { |
| 4864 break; |
| 4865 } |
| 4866 one_byte_buffer.Add(code); |
| 4867 } |
| 4868 |
| 4869 if (index == length) { |
| 4870 RETURN_RESULT_OR_FAILURE(isolate, isolate->factory()->NewStringFromOneByte( |
| 4871 one_byte_buffer.ToConstVector())); |
| 4872 } |
| 4873 |
| 4874 List<uc16> two_byte_buffer(length - index); |
| 4875 |
| 4876 while (true) { |
| 4877 if (code <= unibrow::Utf16::kMaxNonSurrogateCharCode) { |
| 4878 two_byte_buffer.Add(code); |
| 4879 } else { |
| 4880 two_byte_buffer.Add(unibrow::Utf16::LeadSurrogate(code)); |
| 4881 two_byte_buffer.Add(unibrow::Utf16::TrailSurrogate(code)); |
| 4882 } |
| 4883 |
| 4884 if (++index == length) { |
| 4885 break; |
| 4886 } |
| 4887 code = NextCodePoint(isolate, args, index); |
| 4888 if (code < 0) { |
| 4889 return isolate->heap()->exception(); |
| 4890 } |
| 4891 } |
| 4892 |
| 4893 Handle<SeqTwoByteString> result; |
| 4894 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
| 4895 isolate, result, |
| 4896 isolate->factory()->NewRawTwoByteString(one_byte_buffer.length() + |
| 4897 two_byte_buffer.length())); |
| 4898 |
| 4899 CopyChars(result->GetChars(), one_byte_buffer.ToConstVector().start(), |
| 4900 one_byte_buffer.length()); |
| 4901 CopyChars(result->GetChars() + one_byte_buffer.length(), |
| 4902 two_byte_buffer.ToConstVector().start(), two_byte_buffer.length()); |
| 4903 |
| 4904 return *result; |
| 4905 } |
| 4906 |
4814 // ES6 section 21.1.3.1 String.prototype.charAt ( pos ) | 4907 // ES6 section 21.1.3.1 String.prototype.charAt ( pos ) |
4815 void Builtins::Generate_StringPrototypeCharAt(CodeStubAssembler* assembler) { | 4908 void Builtins::Generate_StringPrototypeCharAt(CodeStubAssembler* assembler) { |
4816 typedef CodeStubAssembler::Label Label; | 4909 typedef CodeStubAssembler::Label Label; |
4817 typedef compiler::Node Node; | 4910 typedef compiler::Node Node; |
4818 typedef CodeStubAssembler::Variable Variable; | 4911 typedef CodeStubAssembler::Variable Variable; |
4819 | 4912 |
4820 Node* receiver = assembler->Parameter(0); | 4913 Node* receiver = assembler->Parameter(0); |
4821 Node* position = assembler->Parameter(1); | 4914 Node* position = assembler->Parameter(1); |
4822 Node* context = assembler->Parameter(4); | 4915 Node* context = assembler->Parameter(4); |
4823 | 4916 |
(...skipping 1319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6143 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) | 6236 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) |
6144 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) | 6237 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) |
6145 #undef DEFINE_BUILTIN_ACCESSOR_C | 6238 #undef DEFINE_BUILTIN_ACCESSOR_C |
6146 #undef DEFINE_BUILTIN_ACCESSOR_A | 6239 #undef DEFINE_BUILTIN_ACCESSOR_A |
6147 #undef DEFINE_BUILTIN_ACCESSOR_T | 6240 #undef DEFINE_BUILTIN_ACCESSOR_T |
6148 #undef DEFINE_BUILTIN_ACCESSOR_S | 6241 #undef DEFINE_BUILTIN_ACCESSOR_S |
6149 #undef DEFINE_BUILTIN_ACCESSOR_H | 6242 #undef DEFINE_BUILTIN_ACCESSOR_H |
6150 | 6243 |
6151 } // namespace internal | 6244 } // namespace internal |
6152 } // namespace v8 | 6245 } // namespace v8 |
OLD | NEW |