OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 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/builtins.h" | 5 #include "src/builtins/builtins.h" |
6 #include "src/builtins/builtins-utils.h" | 6 #include "src/builtins/builtins-utils.h" |
7 | 7 |
8 #include "src/code-factory.h" | 8 #include "src/code-factory.h" |
9 | 9 |
10 namespace v8 { | 10 namespace v8 { |
11 namespace internal { | 11 namespace internal { |
12 | 12 |
| 13 typedef CodeStubAssembler::ResultMode ResultMode; |
| 14 typedef CodeStubAssembler::RelationalComparisonMode RelationalComparisonMode; |
| 15 |
13 namespace { | 16 namespace { |
14 | 17 |
15 enum ResultMode { kDontNegateResult, kNegateResult }; | |
16 | |
17 void GenerateStringEqual(CodeStubAssembler* assembler, ResultMode mode) { | 18 void GenerateStringEqual(CodeStubAssembler* assembler, ResultMode mode) { |
18 // Here's pseudo-code for the algorithm below in case of kDontNegateResult | 19 // Here's pseudo-code for the algorithm below in case of kDontNegateResult |
19 // mode; for kNegateResult mode we properly negate the result. | 20 // mode; for kNegateResult mode we properly negate the result. |
20 // | 21 // |
21 // if (lhs == rhs) return true; | 22 // if (lhs == rhs) return true; |
22 // if (lhs->length() != rhs->length()) return false; | 23 // if (lhs->length() != rhs->length()) return false; |
23 // if (lhs->IsInternalizedString() && rhs->IsInternalizedString()) { | 24 // if (lhs->IsInternalizedString() && rhs->IsInternalizedString()) { |
24 // return false; | 25 // return false; |
25 // } | 26 // } |
26 // if (lhs->IsSeqOneByteString() && rhs->IsSeqOneByteString()) { | 27 // if (lhs->IsSeqOneByteString() && rhs->IsSeqOneByteString()) { |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
161 | 162 |
162 assembler->Bind(&if_done); | 163 assembler->Bind(&if_done); |
163 assembler->Goto(&if_equal); | 164 assembler->Goto(&if_equal); |
164 } | 165 } |
165 } | 166 } |
166 | 167 |
167 assembler->Bind(&if_notbothonebyteseqstrings); | 168 assembler->Bind(&if_notbothonebyteseqstrings); |
168 { | 169 { |
169 // TODO(bmeurer): Add fast case support for flattened cons strings; | 170 // TODO(bmeurer): Add fast case support for flattened cons strings; |
170 // also add support for two byte string equality checks. | 171 // also add support for two byte string equality checks. |
171 Runtime::FunctionId function_id = (mode == kDontNegateResult) | 172 Runtime::FunctionId function_id = |
172 ? Runtime::kStringEqual | 173 (mode == ResultMode::kDontNegateResult) |
173 : Runtime::kStringNotEqual; | 174 ? Runtime::kStringEqual |
| 175 : Runtime::kStringNotEqual; |
174 assembler->TailCallRuntime(function_id, context, lhs, rhs); | 176 assembler->TailCallRuntime(function_id, context, lhs, rhs); |
175 } | 177 } |
176 } | 178 } |
177 } | 179 } |
178 | 180 |
179 assembler->Bind(&if_lengthisnotequal); | 181 assembler->Bind(&if_lengthisnotequal); |
180 { | 182 { |
181 // Mismatch in length of {lhs} and {rhs}, cannot be equal. | 183 // Mismatch in length of {lhs} and {rhs}, cannot be equal. |
182 assembler->Goto(&if_notequal); | 184 assembler->Goto(&if_notequal); |
183 } | 185 } |
184 } | 186 } |
185 | 187 |
186 assembler->Bind(&if_equal); | 188 assembler->Bind(&if_equal); |
187 assembler->Return(assembler->BooleanConstant(mode == kDontNegateResult)); | 189 assembler->Return( |
| 190 assembler->BooleanConstant(mode == ResultMode::kDontNegateResult)); |
188 | 191 |
189 assembler->Bind(&if_notequal); | 192 assembler->Bind(&if_notequal); |
190 assembler->Return(assembler->BooleanConstant(mode == kNegateResult)); | 193 assembler->Return( |
| 194 assembler->BooleanConstant(mode == ResultMode::kNegateResult)); |
191 } | 195 } |
192 | 196 |
193 enum RelationalComparisonMode { | |
194 kLessThan, | |
195 kLessThanOrEqual, | |
196 kGreaterThan, | |
197 kGreaterThanOrEqual | |
198 }; | |
199 | 197 |
200 void GenerateStringRelationalComparison(CodeStubAssembler* assembler, | 198 void GenerateStringRelationalComparison(CodeStubAssembler* assembler, |
201 RelationalComparisonMode mode) { | 199 RelationalComparisonMode mode) { |
202 typedef CodeStubAssembler::Label Label; | 200 typedef CodeStubAssembler::Label Label; |
203 typedef compiler::Node Node; | 201 typedef compiler::Node Node; |
204 typedef CodeStubAssembler::Variable Variable; | 202 typedef CodeStubAssembler::Variable Variable; |
205 | 203 |
206 Node* lhs = assembler->Parameter(0); | 204 Node* lhs = assembler->Parameter(0); |
207 Node* rhs = assembler->Parameter(1); | 205 Node* rhs = assembler->Parameter(1); |
208 Node* context = assembler->Parameter(2); | 206 Node* context = assembler->Parameter(2); |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
313 &if_greater); | 311 &if_greater); |
314 } | 312 } |
315 } | 313 } |
316 } | 314 } |
317 | 315 |
318 assembler->Bind(&if_notbothonebyteseqstrings); | 316 assembler->Bind(&if_notbothonebyteseqstrings); |
319 { | 317 { |
320 // TODO(bmeurer): Add fast case support for flattened cons strings; | 318 // TODO(bmeurer): Add fast case support for flattened cons strings; |
321 // also add support for two byte string relational comparisons. | 319 // also add support for two byte string relational comparisons. |
322 switch (mode) { | 320 switch (mode) { |
323 case kLessThan: | 321 case RelationalComparisonMode::kLessThan: |
324 assembler->TailCallRuntime(Runtime::kStringLessThan, context, lhs, | 322 assembler->TailCallRuntime(Runtime::kStringLessThan, context, lhs, |
325 rhs); | 323 rhs); |
326 break; | 324 break; |
327 case kLessThanOrEqual: | 325 case RelationalComparisonMode::kLessThanOrEqual: |
328 assembler->TailCallRuntime(Runtime::kStringLessThanOrEqual, context, | 326 assembler->TailCallRuntime(Runtime::kStringLessThanOrEqual, context, |
329 lhs, rhs); | 327 lhs, rhs); |
330 break; | 328 break; |
331 case kGreaterThan: | 329 case RelationalComparisonMode::kGreaterThan: |
332 assembler->TailCallRuntime(Runtime::kStringGreaterThan, context, lhs, | 330 assembler->TailCallRuntime(Runtime::kStringGreaterThan, context, lhs, |
333 rhs); | 331 rhs); |
334 break; | 332 break; |
335 case kGreaterThanOrEqual: | 333 case RelationalComparisonMode::kGreaterThanOrEqual: |
336 assembler->TailCallRuntime(Runtime::kStringGreaterThanOrEqual, | 334 assembler->TailCallRuntime(Runtime::kStringGreaterThanOrEqual, |
337 context, lhs, rhs); | 335 context, lhs, rhs); |
338 break; | 336 break; |
339 } | 337 } |
340 } | 338 } |
341 } | 339 } |
342 | 340 |
343 assembler->Bind(&if_less); | 341 assembler->Bind(&if_less); |
344 switch (mode) { | 342 switch (mode) { |
345 case kLessThan: | 343 case RelationalComparisonMode::kLessThan: |
346 case kLessThanOrEqual: | 344 case RelationalComparisonMode::kLessThanOrEqual: |
347 assembler->Return(assembler->BooleanConstant(true)); | 345 assembler->Return(assembler->BooleanConstant(true)); |
348 break; | 346 break; |
349 | 347 |
350 case kGreaterThan: | 348 case RelationalComparisonMode::kGreaterThan: |
351 case kGreaterThanOrEqual: | 349 case RelationalComparisonMode::kGreaterThanOrEqual: |
352 assembler->Return(assembler->BooleanConstant(false)); | 350 assembler->Return(assembler->BooleanConstant(false)); |
353 break; | 351 break; |
354 } | 352 } |
355 | 353 |
356 assembler->Bind(&if_equal); | 354 assembler->Bind(&if_equal); |
357 switch (mode) { | 355 switch (mode) { |
358 case kLessThan: | 356 case RelationalComparisonMode::kLessThan: |
359 case kGreaterThan: | 357 case RelationalComparisonMode::kGreaterThan: |
360 assembler->Return(assembler->BooleanConstant(false)); | 358 assembler->Return(assembler->BooleanConstant(false)); |
361 break; | 359 break; |
362 | 360 |
363 case kLessThanOrEqual: | 361 case RelationalComparisonMode::kLessThanOrEqual: |
364 case kGreaterThanOrEqual: | 362 case RelationalComparisonMode::kGreaterThanOrEqual: |
365 assembler->Return(assembler->BooleanConstant(true)); | 363 assembler->Return(assembler->BooleanConstant(true)); |
366 break; | 364 break; |
367 } | 365 } |
368 | 366 |
369 assembler->Bind(&if_greater); | 367 assembler->Bind(&if_greater); |
370 switch (mode) { | 368 switch (mode) { |
371 case kLessThan: | 369 case RelationalComparisonMode::kLessThan: |
372 case kLessThanOrEqual: | 370 case RelationalComparisonMode::kLessThanOrEqual: |
373 assembler->Return(assembler->BooleanConstant(false)); | 371 assembler->Return(assembler->BooleanConstant(false)); |
374 break; | 372 break; |
375 | 373 |
376 case kGreaterThan: | 374 case RelationalComparisonMode::kGreaterThan: |
377 case kGreaterThanOrEqual: | 375 case RelationalComparisonMode::kGreaterThanOrEqual: |
378 assembler->Return(assembler->BooleanConstant(true)); | 376 assembler->Return(assembler->BooleanConstant(true)); |
379 break; | 377 break; |
380 } | 378 } |
381 } | 379 } |
382 | 380 |
383 } // namespace | 381 } // namespace |
384 | 382 |
385 // static | 383 // static |
386 void Builtins::Generate_StringEqual(CodeStubAssembler* assembler) { | 384 void Builtins::Generate_StringEqual(CodeStubAssembler* assembler) { |
387 GenerateStringEqual(assembler, kDontNegateResult); | 385 GenerateStringEqual(assembler, ResultMode::kDontNegateResult); |
388 } | 386 } |
389 | 387 |
390 // static | 388 // static |
391 void Builtins::Generate_StringNotEqual(CodeStubAssembler* assembler) { | 389 void Builtins::Generate_StringNotEqual(CodeStubAssembler* assembler) { |
392 GenerateStringEqual(assembler, kNegateResult); | 390 GenerateStringEqual(assembler, ResultMode::kNegateResult); |
393 } | 391 } |
394 | 392 |
395 // static | 393 // static |
396 void Builtins::Generate_StringLessThan(CodeStubAssembler* assembler) { | 394 void Builtins::Generate_StringLessThan(CodeStubAssembler* assembler) { |
397 GenerateStringRelationalComparison(assembler, kLessThan); | 395 GenerateStringRelationalComparison(assembler, |
| 396 RelationalComparisonMode::kLessThan); |
398 } | 397 } |
399 | 398 |
400 // static | 399 // static |
401 void Builtins::Generate_StringLessThanOrEqual(CodeStubAssembler* assembler) { | 400 void Builtins::Generate_StringLessThanOrEqual(CodeStubAssembler* assembler) { |
402 GenerateStringRelationalComparison(assembler, kLessThanOrEqual); | 401 GenerateStringRelationalComparison( |
| 402 assembler, RelationalComparisonMode::kLessThanOrEqual); |
403 } | 403 } |
404 | 404 |
405 // static | 405 // static |
406 void Builtins::Generate_StringGreaterThan(CodeStubAssembler* assembler) { | 406 void Builtins::Generate_StringGreaterThan(CodeStubAssembler* assembler) { |
407 GenerateStringRelationalComparison(assembler, kGreaterThan); | 407 GenerateStringRelationalComparison(assembler, |
| 408 RelationalComparisonMode::kGreaterThan); |
408 } | 409 } |
409 | 410 |
410 // static | 411 // static |
411 void Builtins::Generate_StringGreaterThanOrEqual(CodeStubAssembler* assembler) { | 412 void Builtins::Generate_StringGreaterThanOrEqual(CodeStubAssembler* assembler) { |
412 GenerateStringRelationalComparison(assembler, kGreaterThanOrEqual); | 413 GenerateStringRelationalComparison( |
| 414 assembler, RelationalComparisonMode::kGreaterThanOrEqual); |
413 } | 415 } |
414 | 416 |
415 // ----------------------------------------------------------------------------- | 417 // ----------------------------------------------------------------------------- |
416 // ES6 section 21.1 String Objects | 418 // ES6 section 21.1 String Objects |
417 | 419 |
418 // ES6 section 21.1.2.1 String.fromCharCode ( ...codeUnits ) | 420 // ES6 section 21.1.2.1 String.fromCharCode ( ...codeUnits ) |
419 void Builtins::Generate_StringFromCharCode(CodeStubAssembler* assembler) { | 421 void Builtins::Generate_StringFromCharCode(CodeStubAssembler* assembler) { |
420 typedef CodeStubAssembler::Label Label; | 422 typedef CodeStubAssembler::Label Label; |
421 typedef compiler::Node Node; | 423 typedef compiler::Node Node; |
422 typedef CodeStubAssembler::Variable Variable; | 424 typedef CodeStubAssembler::Variable Variable; |
(...skipping 916 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1339 Runtime::kThrowIncompatibleMethodReceiver, context, | 1341 Runtime::kThrowIncompatibleMethodReceiver, context, |
1340 assembler->HeapConstant(assembler->factory()->NewStringFromAsciiChecked( | 1342 assembler->HeapConstant(assembler->factory()->NewStringFromAsciiChecked( |
1341 "String Iterator.prototype.next", TENURED)), | 1343 "String Iterator.prototype.next", TENURED)), |
1342 iterator); | 1344 iterator); |
1343 assembler->Return(result); // Never reached. | 1345 assembler->Return(result); // Never reached. |
1344 } | 1346 } |
1345 } | 1347 } |
1346 | 1348 |
1347 } // namespace internal | 1349 } // namespace internal |
1348 } // namespace v8 | 1350 } // namespace v8 |
OLD | NEW |