Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(272)

Side by Side Diff: src/arm/full-codegen-arm.cc

Issue 9704054: Refactoring of code generation for declarations, in preparation for modules. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed Florian's comments. Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | src/full-codegen.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
284 if (scope()->HasIllegalRedeclaration()) { 284 if (scope()->HasIllegalRedeclaration()) {
285 Comment cmnt(masm_, "[ Declarations"); 285 Comment cmnt(masm_, "[ Declarations");
286 scope()->VisitIllegalRedeclaration(this); 286 scope()->VisitIllegalRedeclaration(this);
287 287
288 } else { 288 } else {
289 PrepareForBailoutForId(AstNode::kFunctionEntryId, NO_REGISTERS); 289 PrepareForBailoutForId(AstNode::kFunctionEntryId, NO_REGISTERS);
290 { Comment cmnt(masm_, "[ Declarations"); 290 { Comment cmnt(masm_, "[ Declarations");
291 // For named function expressions, declare the function name as a 291 // For named function expressions, declare the function name as a
292 // constant. 292 // constant.
293 if (scope()->is_function_scope() && scope()->function() != NULL) { 293 if (scope()->is_function_scope() && scope()->function() != NULL) {
294 VariableProxy* proxy = scope()->function(); 294 VariableDeclaration* function = scope()->function();
295 ASSERT(proxy->var()->mode() == CONST || 295 ASSERT(function->proxy()->var()->mode() == CONST ||
296 proxy->var()->mode() == CONST_HARMONY); 296 function->proxy()->var()->mode() == CONST_HARMONY);
297 ASSERT(proxy->var()->location() != Variable::UNALLOCATED); 297 ASSERT(function->proxy()->var()->location() != Variable::UNALLOCATED);
298 EmitDeclaration(proxy, proxy->var()->mode(), NULL); 298 VisitVariableDeclaration(function);
299 } 299 }
300 VisitDeclarations(scope()->declarations()); 300 VisitDeclarations(scope()->declarations());
301 } 301 }
302 302
303 { Comment cmnt(masm_, "[ Stack check"); 303 { Comment cmnt(masm_, "[ Stack check");
304 PrepareForBailoutForId(AstNode::kDeclarationsId, NO_REGISTERS); 304 PrepareForBailoutForId(AstNode::kDeclarationsId, NO_REGISTERS);
305 Label ok; 305 Label ok;
306 __ LoadRoot(ip, Heap::kStackLimitRootIndex); 306 __ LoadRoot(ip, Heap::kStackLimitRootIndex);
307 __ cmp(sp, Operand(ip)); 307 __ cmp(sp, Operand(ip));
308 __ b(hs, &ok); 308 __ b(hs, &ok);
(...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after
724 PrepareForBailout(expr, TOS_REG); 724 PrepareForBailout(expr, TOS_REG);
725 if (should_normalize) { 725 if (should_normalize) {
726 __ LoadRoot(ip, Heap::kTrueValueRootIndex); 726 __ LoadRoot(ip, Heap::kTrueValueRootIndex);
727 __ cmp(r0, ip); 727 __ cmp(r0, ip);
728 Split(eq, if_true, if_false, NULL); 728 Split(eq, if_true, if_false, NULL);
729 __ bind(&skip); 729 __ bind(&skip);
730 } 730 }
731 } 731 }
732 732
733 733
734 void FullCodeGenerator::EmitDeclaration(VariableProxy* proxy, 734 void FullCodeGenerator::EmitDebugCheckDeclarationContext(Variable* variable) {
735 VariableMode mode, 735 // The variable in the declaration always resides in the current function
736 FunctionLiteral* function) { 736 // context.
737 ASSERT_EQ(0, scope()->ContextChainLength(variable->scope()));
738 if (FLAG_debug_code) {
739 // Check that we're not inside a with or catch context.
740 __ ldr(r1, FieldMemOperand(cp, HeapObject::kMapOffset));
741 __ CompareRoot(r1, Heap::kWithContextMapRootIndex);
742 __ Check(ne, "Declaration in with context.");
743 __ CompareRoot(r1, Heap::kCatchContextMapRootIndex);
744 __ Check(ne, "Declaration in catch context.");
745 }
746 }
747
748
749 void FullCodeGenerator::VisitVariableDeclaration(
750 VariableDeclaration* declaration) {
737 // If it was not possible to allocate the variable at compile time, we 751 // If it was not possible to allocate the variable at compile time, we
738 // need to "declare" it at runtime to make sure it actually exists in the 752 // need to "declare" it at runtime to make sure it actually exists in the
739 // local context. 753 // local context.
754 VariableProxy* proxy = declaration->proxy();
755 VariableMode mode = declaration->mode();
740 Variable* variable = proxy->var(); 756 Variable* variable = proxy->var();
741 bool binding_needs_init = (function == NULL) && 757 bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET;
742 (mode == CONST || mode == CONST_HARMONY || mode == LET);
743 switch (variable->location()) { 758 switch (variable->location()) {
744 case Variable::UNALLOCATED: 759 case Variable::UNALLOCATED:
745 ++global_count_; 760 ++global_count_;
746 break; 761 break;
747 762
748 case Variable::PARAMETER: 763 case Variable::PARAMETER:
749 case Variable::LOCAL: 764 case Variable::LOCAL:
750 if (function != NULL) { 765 if (hole_init) {
751 Comment cmnt(masm_, "[ Declaration"); 766 Comment cmnt(masm_, "[ VariableDeclaration");
752 VisitForAccumulatorValue(function);
753 __ str(result_register(), StackOperand(variable));
754 } else if (binding_needs_init) {
755 Comment cmnt(masm_, "[ Declaration");
756 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); 767 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
757 __ str(ip, StackOperand(variable)); 768 __ str(ip, StackOperand(variable));
758 } 769 }
759 break; 770 break;
760 771
761 case Variable::CONTEXT: 772 case Variable::CONTEXT:
762 // The variable in the decl always resides in the current function 773 if (hole_init) {
763 // context. 774 Comment cmnt(masm_, "[ VariableDeclaration");
764 ASSERT_EQ(0, scope()->ContextChainLength(variable->scope())); 775 EmitDebugCheckDeclarationContext(variable);
765 if (FLAG_debug_code) {
766 // Check that we're not inside a with or catch context.
767 __ ldr(r1, FieldMemOperand(cp, HeapObject::kMapOffset));
768 __ CompareRoot(r1, Heap::kWithContextMapRootIndex);
769 __ Check(ne, "Declaration in with context.");
770 __ CompareRoot(r1, Heap::kCatchContextMapRootIndex);
771 __ Check(ne, "Declaration in catch context.");
772 }
773 if (function != NULL) {
774 Comment cmnt(masm_, "[ Declaration");
775 VisitForAccumulatorValue(function);
776 __ str(result_register(), ContextOperand(cp, variable->index()));
777 int offset = Context::SlotOffset(variable->index());
778 // We know that we have written a function, which is not a smi.
779 __ RecordWriteContextSlot(cp,
780 offset,
781 result_register(),
782 r2,
783 kLRHasBeenSaved,
784 kDontSaveFPRegs,
785 EMIT_REMEMBERED_SET,
786 OMIT_SMI_CHECK);
787 PrepareForBailoutForId(proxy->id(), NO_REGISTERS);
788 } else if (binding_needs_init) {
789 Comment cmnt(masm_, "[ Declaration");
790 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); 776 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
791 __ str(ip, ContextOperand(cp, variable->index())); 777 __ str(ip, ContextOperand(cp, variable->index()));
792 // No write barrier since the_hole_value is in old space. 778 // No write barrier since the_hole_value is in old space.
793 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); 779 PrepareForBailoutForId(proxy->id(), NO_REGISTERS);
794 } 780 }
795 break; 781 break;
796 782
797 case Variable::LOOKUP: { 783 case Variable::LOOKUP: {
798 Comment cmnt(masm_, "[ Declaration"); 784 Comment cmnt(masm_, "[ VariableDeclaration");
799 __ mov(r2, Operand(variable->name())); 785 __ mov(r2, Operand(variable->name()));
800 // Declaration nodes are always introduced in one of four modes. 786 // Declaration nodes are always introduced in one of four modes.
801 ASSERT(mode == VAR || 787 ASSERT(mode == VAR || mode == LET ||
802 mode == CONST || 788 mode == CONST || mode == CONST_HARMONY);
803 mode == CONST_HARMONY ||
804 mode == LET);
805 PropertyAttributes attr = (mode == CONST || mode == CONST_HARMONY) 789 PropertyAttributes attr = (mode == CONST || mode == CONST_HARMONY)
806 ? READ_ONLY : NONE; 790 ? READ_ONLY : NONE;
807 __ mov(r1, Operand(Smi::FromInt(attr))); 791 __ mov(r1, Operand(Smi::FromInt(attr)));
808 // Push initial value, if any. 792 // Push initial value, if any.
809 // Note: For variables we must not push an initial value (such as 793 // Note: For variables we must not push an initial value (such as
810 // 'undefined') because we may have a (legal) redeclaration and we 794 // 'undefined') because we may have a (legal) redeclaration and we
811 // must not destroy the current value. 795 // must not destroy the current value.
812 if (function != NULL) { 796 if (hole_init) {
813 __ Push(cp, r2, r1);
814 // Push initial value for function declaration.
815 VisitForStackValue(function);
816 } else if (binding_needs_init) {
817 __ LoadRoot(r0, Heap::kTheHoleValueRootIndex); 797 __ LoadRoot(r0, Heap::kTheHoleValueRootIndex);
818 __ Push(cp, r2, r1, r0); 798 __ Push(cp, r2, r1, r0);
819 } else { 799 } else {
820 __ mov(r0, Operand(Smi::FromInt(0))); // Indicates no initial value. 800 __ mov(r0, Operand(Smi::FromInt(0))); // Indicates no initial value.
821 __ Push(cp, r2, r1, r0); 801 __ Push(cp, r2, r1, r0);
822 } 802 }
823 __ CallRuntime(Runtime::kDeclareContextSlot, 4); 803 __ CallRuntime(Runtime::kDeclareContextSlot, 4);
824 break; 804 break;
825 } 805 }
826 } 806 }
827 } 807 }
828 808
829 809
810 void FullCodeGenerator::VisitFunctionDeclaration(
811 FunctionDeclaration* declaration) {
812 VariableProxy* proxy = declaration->proxy();
813 Variable* variable = proxy->var();
814 switch (variable->location()) {
815 case Variable::UNALLOCATED:
816 ++global_count_;
817 break;
818
819 case Variable::PARAMETER:
820 case Variable::LOCAL: {
821 Comment cmnt(masm_, "[ FunctionDeclaration");
822 VisitForAccumulatorValue(declaration->fun());
823 __ str(result_register(), StackOperand(variable));
824 break;
825 }
826
827 case Variable::CONTEXT: {
828 Comment cmnt(masm_, "[ FunctionDeclaration");
829 EmitDebugCheckDeclarationContext(variable);
830 VisitForAccumulatorValue(declaration->fun());
831 __ str(result_register(), ContextOperand(cp, variable->index()));
832 int offset = Context::SlotOffset(variable->index());
833 // We know that we have written a function, which is not a smi.
834 __ RecordWriteContextSlot(cp,
835 offset,
836 result_register(),
837 r2,
838 kLRHasBeenSaved,
839 kDontSaveFPRegs,
840 EMIT_REMEMBERED_SET,
841 OMIT_SMI_CHECK);
842 PrepareForBailoutForId(proxy->id(), NO_REGISTERS);
843 break;
844 }
845
846 case Variable::LOOKUP: {
847 Comment cmnt(masm_, "[ FunctionDeclaration");
848 __ mov(r2, Operand(variable->name()));
849 __ mov(r1, Operand(Smi::FromInt(NONE)));
850 __ Push(cp, r2, r1);
851 // Push initial value for function declaration.
852 VisitForStackValue(declaration->fun());
853 __ CallRuntime(Runtime::kDeclareContextSlot, 4);
854 break;
855 }
856 }
857 }
858
859
860 void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) {
861 VariableProxy* proxy = declaration->proxy();
862 Variable* variable = proxy->var();
863 switch (variable->location()) {
864 case Variable::UNALLOCATED:
865 ++global_count_;
866 break;
867
868 case Variable::CONTEXT: {
869 Comment cmnt(masm_, "[ ModuleDeclaration");
870 EmitDebugCheckDeclarationContext(variable);
871 // TODO(rossberg): initialize module instance object
872 break;
873 }
874
875 case Variable::PARAMETER:
876 case Variable::LOCAL:
877 case Variable::LOOKUP:
878 UNREACHABLE();
879 }
880 }
881
882
883 void FullCodeGenerator::VisitImportDeclaration(ImportDeclaration* declaration) {
884 VariableProxy* proxy = declaration->proxy();
885 Variable* variable = proxy->var();
886 switch (variable->location()) {
887 case Variable::UNALLOCATED:
888 ++global_count_;
889 break;
890
891 case Variable::CONTEXT: {
892 Comment cmnt(masm_, "[ ImportDeclaration");
893 EmitDebugCheckDeclarationContext(variable);
894 // TODO(rossberg)
895 break;
896 }
897
898 case Variable::PARAMETER:
899 case Variable::LOCAL:
900 case Variable::LOOKUP:
901 UNREACHABLE();
902 }
903 }
904
905
906 void FullCodeGenerator::VisitExportDeclaration(ExportDeclaration* declaration) {
907 // TODO(rossberg)
908 }
909
910
830 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 911 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
831 // Call the runtime to declare the globals. 912 // Call the runtime to declare the globals.
832 // The context is the first argument. 913 // The context is the first argument.
833 __ mov(r1, Operand(pairs)); 914 __ mov(r1, Operand(pairs));
834 __ mov(r0, Operand(Smi::FromInt(DeclareGlobalsFlags()))); 915 __ mov(r0, Operand(Smi::FromInt(DeclareGlobalsFlags())));
835 __ Push(cp, r1, r0); 916 __ Push(cp, r1, r0);
836 __ CallRuntime(Runtime::kDeclareGlobals, 3); 917 __ CallRuntime(Runtime::kDeclareGlobals, 3);
837 // Return value is ignored. 918 // Return value is ignored.
838 } 919 }
839 920
(...skipping 3609 matching lines...) Expand 10 before | Expand all | Expand 10 after
4449 *context_length = 0; 4530 *context_length = 0;
4450 return previous_; 4531 return previous_;
4451 } 4532 }
4452 4533
4453 4534
4454 #undef __ 4535 #undef __
4455 4536
4456 } } // namespace v8::internal 4537 } } // namespace v8::internal
4457 4538
4458 #endif // V8_TARGET_ARCH_ARM 4539 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « no previous file | src/full-codegen.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698