OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2017 the V8 project authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #ifndef V8_INTL_SUPPORT | |
6 #error Internationalization is expected to be enabled. | |
7 #endif // V8_INTL_SUPPORT | |
8 | |
9 #include "src/builtins/builtins-utils-gen.h" | |
10 #include "src/code-stub-assembler.h" | |
11 | |
12 namespace v8 { | |
13 namespace internal { | |
14 | |
15 class IntlBuiltinsAssembler : public CodeStubAssembler { | |
16 public: | |
17 explicit IntlBuiltinsAssembler(compiler::CodeAssemblerState* state) | |
18 : CodeStubAssembler(state) {} | |
19 }; | |
20 | |
21 TF_BUILTIN(StringPrototypeToLowerCaseIntl, IntlBuiltinsAssembler) { | |
22 Node* const maybe_string = Parameter(Descriptor::kReceiver); | |
23 Node* const context = Parameter(Descriptor::kContext); | |
24 | |
25 Node* const string = | |
26 ToThisString(context, maybe_string, "String.prototype.toLowerCase"); | |
27 | |
28 Label call_c(this), return_string(this), runtime(this, Label::kDeferred); | |
29 | |
30 // Early exit on empty strings. | |
31 Node* const length = SmiUntag(LoadStringLength(string)); | |
32 GotoIf(IntPtrEqual(length, IntPtrConstant(0)), &return_string); | |
33 | |
34 // Unpack strings if possible, and bail to runtime unless we get a one-byte | |
35 // flat string. | |
36 ToDirectStringAssembler to_direct( | |
37 state(), string, ToDirectStringAssembler::kDontUnpackSlicedStrings); | |
38 to_direct.TryToDirect(&runtime); | |
39 | |
40 GotoIfNot(IsOneByteStringInstanceType(to_direct.instance_type()), &runtime); | |
Camillo Bruni
2017/05/05 11:44:26
Would you mind adding the following assert (I thin
jgruber
2017/05/05 15:26:58
Sure, we can just assert that the string is not in
| |
41 | |
42 // For short strings, do the conversion in CSA through the lookup table. | |
43 | |
44 Node* const dst = AllocateSeqOneByteString(context, length); | |
45 | |
46 const int kMaxShortStringLength = 24; // Determined empirically. | |
47 GotoIf(IntPtrGreaterThan(length, IntPtrConstant(kMaxShortStringLength)), | |
48 &call_c); | |
49 | |
50 { | |
51 Node* const dst_ptr = PointerToSeqStringData(dst); | |
52 VARIABLE(var_cursor, MachineType::PointerRepresentation(), | |
53 IntPtrConstant(0)); | |
54 | |
55 Node* const start_address = to_direct.PointerToData(&call_c); | |
56 Node* const end_address = IntPtrAdd(start_address, length); | |
57 | |
58 Node* const to_lower_table_addr = ExternalConstant( | |
59 ExternalReference::intl_to_latin1_lower_table(isolate())); | |
60 | |
61 VariableList push_vars({&var_cursor}, zone()); | |
62 BuildFastLoop( | |
63 push_vars, start_address, end_address, | |
64 [=, &var_cursor](Node* current) { | |
65 Node* c = ChangeInt32ToIntPtr(Load(MachineType::Uint8(), current)); | |
66 Node* lower = Load(MachineType::Uint8(), to_lower_table_addr, c); | |
67 StoreNoWriteBarrier(MachineRepresentation::kWord8, dst_ptr, | |
68 var_cursor.value(), lower); | |
69 Increment(var_cursor); | |
70 }, | |
71 kCharSize, INTPTR_PARAMETERS, IndexAdvanceMode::kPost); | |
72 | |
73 // All lower-case. | |
74 Return(dst); | |
75 } | |
76 | |
77 // Call into C for case conversion. The signature is: | |
78 // Object* ConvertOneByteToLower(String* src, String* dst, Isolate* isolate); | |
79 BIND(&call_c); | |
80 { | |
81 Node* const src = to_direct.string(); | |
82 | |
83 Node* const function_addr = ExternalConstant( | |
84 ExternalReference::intl_convert_one_byte_to_lower(isolate())); | |
85 Node* const isolate_ptr = | |
86 ExternalConstant(ExternalReference::isolate_address(isolate())); | |
87 | |
88 MachineType type_ptr = MachineType::Pointer(); | |
89 MachineType type_tagged = MachineType::AnyTagged(); | |
90 | |
91 Node* const result = | |
92 CallCFunction3(type_tagged, type_tagged, type_tagged, type_ptr, | |
93 function_addr, src, dst, isolate_ptr); | |
94 | |
95 Return(result); | |
96 } | |
97 | |
98 BIND(&return_string); | |
99 Return(string); | |
100 | |
101 BIND(&runtime); | |
102 { | |
103 Node* const result = | |
104 CallRuntime(Runtime::kStringToLowerCaseIntl, context, string); | |
105 Return(result); | |
106 } | |
107 } | |
108 | |
109 } // namespace internal | |
110 } // namespace v8 | |
OLD | NEW |