Chromium Code Reviews| 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 |