OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 824 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
835 __ j(not_equal, &next_test); | 835 __ j(not_equal, &next_test); |
836 __ Drop(1); // Switch value is no longer needed. | 836 __ Drop(1); // Switch value is no longer needed. |
837 __ jmp(clause->body_target()); | 837 __ jmp(clause->body_target()); |
838 } | 838 } |
839 | 839 |
840 // Discard the test value and jump to the default if present, otherwise to | 840 // Discard the test value and jump to the default if present, otherwise to |
841 // the end of the statement. | 841 // the end of the statement. |
842 __ bind(&next_test); | 842 __ bind(&next_test); |
843 __ Drop(1); // Switch value is no longer needed. | 843 __ Drop(1); // Switch value is no longer needed. |
844 if (default_clause == NULL) { | 844 if (default_clause == NULL) { |
845 __ jmp(nested_statement.break_target()); | 845 __ jmp(nested_statement.break_label()); |
846 } else { | 846 } else { |
847 __ jmp(default_clause->body_target()); | 847 __ jmp(default_clause->body_target()); |
848 } | 848 } |
849 | 849 |
850 // Compile all the case bodies. | 850 // Compile all the case bodies. |
851 for (int i = 0; i < clauses->length(); i++) { | 851 for (int i = 0; i < clauses->length(); i++) { |
852 Comment cmnt(masm_, "[ Case body"); | 852 Comment cmnt(masm_, "[ Case body"); |
853 CaseClause* clause = clauses->at(i); | 853 CaseClause* clause = clauses->at(i); |
854 __ bind(clause->body_target()); | 854 __ bind(clause->body_target()); |
855 PrepareForBailoutForId(clause->EntryId(), NO_REGISTERS); | 855 PrepareForBailoutForId(clause->EntryId(), NO_REGISTERS); |
856 VisitStatements(clause->statements()); | 856 VisitStatements(clause->statements()); |
857 } | 857 } |
858 | 858 |
859 __ bind(nested_statement.break_target()); | 859 __ bind(nested_statement.break_label()); |
860 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); | 860 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); |
861 } | 861 } |
862 | 862 |
863 | 863 |
864 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { | 864 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { |
865 Comment cmnt(masm_, "[ ForInStatement"); | 865 Comment cmnt(masm_, "[ ForInStatement"); |
866 SetStatementPosition(stmt); | 866 SetStatementPosition(stmt); |
867 | 867 |
868 Label loop, exit; | 868 Label loop, exit; |
869 ForIn loop_statement(this, stmt); | 869 ForIn loop_statement(this, stmt); |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
975 __ Push(Smi::FromInt(0)); // Map (0) - force slow check. | 975 __ Push(Smi::FromInt(0)); // Map (0) - force slow check. |
976 __ push(rax); | 976 __ push(rax); |
977 __ movq(rax, FieldOperand(rax, FixedArray::kLengthOffset)); | 977 __ movq(rax, FieldOperand(rax, FixedArray::kLengthOffset)); |
978 __ push(rax); // Fixed array length (as smi). | 978 __ push(rax); // Fixed array length (as smi). |
979 __ Push(Smi::FromInt(0)); // Initial index. | 979 __ Push(Smi::FromInt(0)); // Initial index. |
980 | 980 |
981 // Generate code for doing the condition check. | 981 // Generate code for doing the condition check. |
982 __ bind(&loop); | 982 __ bind(&loop); |
983 __ movq(rax, Operand(rsp, 0 * kPointerSize)); // Get the current index. | 983 __ movq(rax, Operand(rsp, 0 * kPointerSize)); // Get the current index. |
984 __ cmpq(rax, Operand(rsp, 1 * kPointerSize)); // Compare to the array length. | 984 __ cmpq(rax, Operand(rsp, 1 * kPointerSize)); // Compare to the array length. |
985 __ j(above_equal, loop_statement.break_target()); | 985 __ j(above_equal, loop_statement.break_label()); |
986 | 986 |
987 // Get the current entry of the array into register rbx. | 987 // Get the current entry of the array into register rbx. |
988 __ movq(rbx, Operand(rsp, 2 * kPointerSize)); | 988 __ movq(rbx, Operand(rsp, 2 * kPointerSize)); |
989 SmiIndex index = masm()->SmiToIndex(rax, rax, kPointerSizeLog2); | 989 SmiIndex index = masm()->SmiToIndex(rax, rax, kPointerSizeLog2); |
990 __ movq(rbx, FieldOperand(rbx, | 990 __ movq(rbx, FieldOperand(rbx, |
991 index.reg, | 991 index.reg, |
992 index.scale, | 992 index.scale, |
993 FixedArray::kHeaderSize)); | 993 FixedArray::kHeaderSize)); |
994 | 994 |
995 // Get the expected map from the stack or a zero map in the | 995 // Get the expected map from the stack or a zero map in the |
996 // permanent slow case into register rdx. | 996 // permanent slow case into register rdx. |
997 __ movq(rdx, Operand(rsp, 3 * kPointerSize)); | 997 __ movq(rdx, Operand(rsp, 3 * kPointerSize)); |
998 | 998 |
999 // Check if the expected map still matches that of the enumerable. | 999 // Check if the expected map still matches that of the enumerable. |
1000 // If not, we have to filter the key. | 1000 // If not, we have to filter the key. |
1001 Label update_each; | 1001 Label update_each; |
1002 __ movq(rcx, Operand(rsp, 4 * kPointerSize)); | 1002 __ movq(rcx, Operand(rsp, 4 * kPointerSize)); |
1003 __ cmpq(rdx, FieldOperand(rcx, HeapObject::kMapOffset)); | 1003 __ cmpq(rdx, FieldOperand(rcx, HeapObject::kMapOffset)); |
1004 __ j(equal, &update_each, Label::kNear); | 1004 __ j(equal, &update_each, Label::kNear); |
1005 | 1005 |
1006 // Convert the entry to a string or null if it isn't a property | 1006 // Convert the entry to a string or null if it isn't a property |
1007 // anymore. If the property has been removed while iterating, we | 1007 // anymore. If the property has been removed while iterating, we |
1008 // just skip it. | 1008 // just skip it. |
1009 __ push(rcx); // Enumerable. | 1009 __ push(rcx); // Enumerable. |
1010 __ push(rbx); // Current entry. | 1010 __ push(rbx); // Current entry. |
1011 __ InvokeBuiltin(Builtins::FILTER_KEY, CALL_FUNCTION); | 1011 __ InvokeBuiltin(Builtins::FILTER_KEY, CALL_FUNCTION); |
1012 __ Cmp(rax, Smi::FromInt(0)); | 1012 __ Cmp(rax, Smi::FromInt(0)); |
1013 __ j(equal, loop_statement.continue_target()); | 1013 __ j(equal, loop_statement.continue_label()); |
1014 __ movq(rbx, rax); | 1014 __ movq(rbx, rax); |
1015 | 1015 |
1016 // Update the 'each' property or variable from the possibly filtered | 1016 // Update the 'each' property or variable from the possibly filtered |
1017 // entry in register rbx. | 1017 // entry in register rbx. |
1018 __ bind(&update_each); | 1018 __ bind(&update_each); |
1019 __ movq(result_register(), rbx); | 1019 __ movq(result_register(), rbx); |
1020 // Perform the assignment as if via '='. | 1020 // Perform the assignment as if via '='. |
1021 { EffectContext context(this); | 1021 { EffectContext context(this); |
1022 EmitAssignment(stmt->each(), stmt->AssignmentId()); | 1022 EmitAssignment(stmt->each(), stmt->AssignmentId()); |
1023 } | 1023 } |
1024 | 1024 |
1025 // Generate code for the body of the loop. | 1025 // Generate code for the body of the loop. |
1026 Visit(stmt->body()); | 1026 Visit(stmt->body()); |
1027 | 1027 |
1028 // Generate code for going to the next element by incrementing the | 1028 // Generate code for going to the next element by incrementing the |
1029 // index (smi) stored on top of the stack. | 1029 // index (smi) stored on top of the stack. |
1030 __ bind(loop_statement.continue_target()); | 1030 __ bind(loop_statement.continue_label()); |
1031 __ SmiAddConstant(Operand(rsp, 0 * kPointerSize), Smi::FromInt(1)); | 1031 __ SmiAddConstant(Operand(rsp, 0 * kPointerSize), Smi::FromInt(1)); |
1032 | 1032 |
1033 EmitStackCheck(stmt); | 1033 EmitStackCheck(stmt); |
1034 __ jmp(&loop); | 1034 __ jmp(&loop); |
1035 | 1035 |
1036 // Remove the pointers stored on the stack. | 1036 // Remove the pointers stored on the stack. |
1037 __ bind(loop_statement.break_target()); | 1037 __ bind(loop_statement.break_label()); |
1038 __ addq(rsp, Immediate(5 * kPointerSize)); | 1038 __ addq(rsp, Immediate(5 * kPointerSize)); |
1039 | 1039 |
1040 // Exit and decrement the loop depth. | 1040 // Exit and decrement the loop depth. |
1041 __ bind(&exit); | 1041 __ bind(&exit); |
1042 decrement_loop_depth(); | 1042 decrement_loop_depth(); |
1043 } | 1043 } |
1044 | 1044 |
1045 | 1045 |
1046 void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info, | 1046 void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info, |
1047 bool pretenure) { | 1047 bool pretenure) { |
(...skipping 3189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4237 __ jmp(rdx); | 4237 __ jmp(rdx); |
4238 } | 4238 } |
4239 | 4239 |
4240 | 4240 |
4241 #undef __ | 4241 #undef __ |
4242 | 4242 |
4243 | 4243 |
4244 } } // namespace v8::internal | 4244 } } // namespace v8::internal |
4245 | 4245 |
4246 #endif // V8_TARGET_ARCH_X64 | 4246 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |