| 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 |