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

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

Issue 10105026: Version 3.10.3 (Closed) Base URL: http://v8.googlecode.com/svn/trunk/
Patch Set: 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 | « src/arm/code-stubs-arm.cc ('k') | src/arm/lithium-codegen-arm.cc » ('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 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
259 if (scope()->HasIllegalRedeclaration()) { 259 if (scope()->HasIllegalRedeclaration()) {
260 Comment cmnt(masm_, "[ Declarations"); 260 Comment cmnt(masm_, "[ Declarations");
261 scope()->VisitIllegalRedeclaration(this); 261 scope()->VisitIllegalRedeclaration(this);
262 262
263 } else { 263 } else {
264 PrepareForBailoutForId(AstNode::kFunctionEntryId, NO_REGISTERS); 264 PrepareForBailoutForId(AstNode::kFunctionEntryId, NO_REGISTERS);
265 { Comment cmnt(masm_, "[ Declarations"); 265 { Comment cmnt(masm_, "[ Declarations");
266 // For named function expressions, declare the function name as a 266 // For named function expressions, declare the function name as a
267 // constant. 267 // constant.
268 if (scope()->is_function_scope() && scope()->function() != NULL) { 268 if (scope()->is_function_scope() && scope()->function() != NULL) {
269 VariableProxy* proxy = scope()->function(); 269 VariableDeclaration* function = scope()->function();
270 ASSERT(proxy->var()->mode() == CONST || 270 ASSERT(function->proxy()->var()->mode() == CONST ||
271 proxy->var()->mode() == CONST_HARMONY); 271 function->proxy()->var()->mode() == CONST_HARMONY);
272 ASSERT(proxy->var()->location() != Variable::UNALLOCATED); 272 ASSERT(function->proxy()->var()->location() != Variable::UNALLOCATED);
273 EmitDeclaration(proxy, proxy->var()->mode(), NULL); 273 VisitVariableDeclaration(function);
274 } 274 }
275 VisitDeclarations(scope()->declarations()); 275 VisitDeclarations(scope()->declarations());
276 } 276 }
277 277
278 { Comment cmnt(masm_, "[ Stack check"); 278 { Comment cmnt(masm_, "[ Stack check");
279 PrepareForBailoutForId(AstNode::kDeclarationsId, NO_REGISTERS); 279 PrepareForBailoutForId(AstNode::kDeclarationsId, NO_REGISTERS);
280 Label ok; 280 Label ok;
281 __ LoadRoot(ip, Heap::kStackLimitRootIndex); 281 __ LoadRoot(ip, Heap::kStackLimitRootIndex);
282 __ cmp(sp, Operand(ip)); 282 __ cmp(sp, Operand(ip));
283 __ b(hs, &ok); 283 __ b(hs, &ok);
(...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after
773 PrepareForBailout(expr, TOS_REG); 773 PrepareForBailout(expr, TOS_REG);
774 if (should_normalize) { 774 if (should_normalize) {
775 __ LoadRoot(ip, Heap::kTrueValueRootIndex); 775 __ LoadRoot(ip, Heap::kTrueValueRootIndex);
776 __ cmp(r0, ip); 776 __ cmp(r0, ip);
777 Split(eq, if_true, if_false, NULL); 777 Split(eq, if_true, if_false, NULL);
778 __ bind(&skip); 778 __ bind(&skip);
779 } 779 }
780 } 780 }
781 781
782 782
783 void FullCodeGenerator::EmitDeclaration(VariableProxy* proxy, 783 void FullCodeGenerator::EmitDebugCheckDeclarationContext(Variable* variable) {
784 VariableMode mode, 784 // The variable in the declaration always resides in the current function
785 FunctionLiteral* function) { 785 // context.
786 ASSERT_EQ(0, scope()->ContextChainLength(variable->scope()));
787 if (FLAG_debug_code) {
788 // Check that we're not inside a with or catch context.
789 __ ldr(r1, FieldMemOperand(cp, HeapObject::kMapOffset));
790 __ CompareRoot(r1, Heap::kWithContextMapRootIndex);
791 __ Check(ne, "Declaration in with context.");
792 __ CompareRoot(r1, Heap::kCatchContextMapRootIndex);
793 __ Check(ne, "Declaration in catch context.");
794 }
795 }
796
797
798 void FullCodeGenerator::VisitVariableDeclaration(
799 VariableDeclaration* declaration) {
786 // If it was not possible to allocate the variable at compile time, we 800 // If it was not possible to allocate the variable at compile time, we
787 // need to "declare" it at runtime to make sure it actually exists in the 801 // need to "declare" it at runtime to make sure it actually exists in the
788 // local context. 802 // local context.
803 VariableProxy* proxy = declaration->proxy();
804 VariableMode mode = declaration->mode();
789 Variable* variable = proxy->var(); 805 Variable* variable = proxy->var();
790 bool binding_needs_init = (function == NULL) && 806 bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET;
791 (mode == CONST || mode == CONST_HARMONY || mode == LET);
792 switch (variable->location()) { 807 switch (variable->location()) {
793 case Variable::UNALLOCATED: 808 case Variable::UNALLOCATED:
794 ++global_count_; 809 globals_->Add(variable->name());
810 globals_->Add(variable->binding_needs_init()
811 ? isolate()->factory()->the_hole_value()
812 : isolate()->factory()->undefined_value());
795 break; 813 break;
796 814
797 case Variable::PARAMETER: 815 case Variable::PARAMETER:
798 case Variable::LOCAL: 816 case Variable::LOCAL:
799 if (function != NULL) { 817 if (hole_init) {
800 Comment cmnt(masm_, "[ Declaration"); 818 Comment cmnt(masm_, "[ VariableDeclaration");
801 VisitForAccumulatorValue(function);
802 __ str(result_register(), StackOperand(variable));
803 } else if (binding_needs_init) {
804 Comment cmnt(masm_, "[ Declaration");
805 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); 819 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
806 __ str(ip, StackOperand(variable)); 820 __ str(ip, StackOperand(variable));
807 } 821 }
808 break; 822 break;
809 823
810 case Variable::CONTEXT: 824 case Variable::CONTEXT:
811 // The variable in the decl always resides in the current function 825 if (hole_init) {
812 // context. 826 Comment cmnt(masm_, "[ VariableDeclaration");
813 ASSERT_EQ(0, scope()->ContextChainLength(variable->scope())); 827 EmitDebugCheckDeclarationContext(variable);
814 if (FLAG_debug_code) {
815 // Check that we're not inside a with or catch context.
816 __ ldr(r1, FieldMemOperand(cp, HeapObject::kMapOffset));
817 __ CompareRoot(r1, Heap::kWithContextMapRootIndex);
818 __ Check(ne, "Declaration in with context.");
819 __ CompareRoot(r1, Heap::kCatchContextMapRootIndex);
820 __ Check(ne, "Declaration in catch context.");
821 }
822 if (function != NULL) {
823 Comment cmnt(masm_, "[ Declaration");
824 VisitForAccumulatorValue(function);
825 __ str(result_register(), ContextOperand(cp, variable->index()));
826 int offset = Context::SlotOffset(variable->index());
827 // We know that we have written a function, which is not a smi.
828 __ RecordWriteContextSlot(cp,
829 offset,
830 result_register(),
831 r2,
832 kLRHasBeenSaved,
833 kDontSaveFPRegs,
834 EMIT_REMEMBERED_SET,
835 OMIT_SMI_CHECK);
836 PrepareForBailoutForId(proxy->id(), NO_REGISTERS);
837 } else if (binding_needs_init) {
838 Comment cmnt(masm_, "[ Declaration");
839 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); 828 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
840 __ str(ip, ContextOperand(cp, variable->index())); 829 __ str(ip, ContextOperand(cp, variable->index()));
841 // No write barrier since the_hole_value is in old space. 830 // No write barrier since the_hole_value is in old space.
842 PrepareForBailoutForId(proxy->id(), NO_REGISTERS); 831 PrepareForBailoutForId(proxy->id(), NO_REGISTERS);
843 } 832 }
844 break; 833 break;
845 834
846 case Variable::LOOKUP: { 835 case Variable::LOOKUP: {
847 Comment cmnt(masm_, "[ Declaration"); 836 Comment cmnt(masm_, "[ VariableDeclaration");
848 __ mov(r2, Operand(variable->name())); 837 __ mov(r2, Operand(variable->name()));
849 // Declaration nodes are always introduced in one of four modes. 838 // Declaration nodes are always introduced in one of four modes.
850 ASSERT(mode == VAR || 839 ASSERT(mode == VAR || mode == LET ||
851 mode == CONST || 840 mode == CONST || mode == CONST_HARMONY);
852 mode == CONST_HARMONY ||
853 mode == LET);
854 PropertyAttributes attr = (mode == CONST || mode == CONST_HARMONY) 841 PropertyAttributes attr = (mode == CONST || mode == CONST_HARMONY)
855 ? READ_ONLY : NONE; 842 ? READ_ONLY : NONE;
856 __ mov(r1, Operand(Smi::FromInt(attr))); 843 __ mov(r1, Operand(Smi::FromInt(attr)));
857 // Push initial value, if any. 844 // Push initial value, if any.
858 // Note: For variables we must not push an initial value (such as 845 // Note: For variables we must not push an initial value (such as
859 // 'undefined') because we may have a (legal) redeclaration and we 846 // 'undefined') because we may have a (legal) redeclaration and we
860 // must not destroy the current value. 847 // must not destroy the current value.
861 if (function != NULL) { 848 if (hole_init) {
862 __ Push(cp, r2, r1);
863 // Push initial value for function declaration.
864 VisitForStackValue(function);
865 } else if (binding_needs_init) {
866 __ LoadRoot(r0, Heap::kTheHoleValueRootIndex); 849 __ LoadRoot(r0, Heap::kTheHoleValueRootIndex);
867 __ Push(cp, r2, r1, r0); 850 __ Push(cp, r2, r1, r0);
868 } else { 851 } else {
869 __ mov(r0, Operand(Smi::FromInt(0))); // Indicates no initial value. 852 __ mov(r0, Operand(Smi::FromInt(0))); // Indicates no initial value.
870 __ Push(cp, r2, r1, r0); 853 __ Push(cp, r2, r1, r0);
871 } 854 }
872 __ CallRuntime(Runtime::kDeclareContextSlot, 4); 855 __ CallRuntime(Runtime::kDeclareContextSlot, 4);
873 break; 856 break;
874 } 857 }
875 } 858 }
876 } 859 }
877 860
878 861
862 void FullCodeGenerator::VisitFunctionDeclaration(
863 FunctionDeclaration* declaration) {
864 VariableProxy* proxy = declaration->proxy();
865 Variable* variable = proxy->var();
866 switch (variable->location()) {
867 case Variable::UNALLOCATED: {
868 globals_->Add(variable->name());
869 Handle<SharedFunctionInfo> function =
870 Compiler::BuildFunctionInfo(declaration->fun(), script());
871 // Check for stack-overflow exception.
872 if (function.is_null()) return SetStackOverflow();
873 globals_->Add(function);
874 break;
875 }
876
877 case Variable::PARAMETER:
878 case Variable::LOCAL: {
879 Comment cmnt(masm_, "[ FunctionDeclaration");
880 VisitForAccumulatorValue(declaration->fun());
881 __ str(result_register(), StackOperand(variable));
882 break;
883 }
884
885 case Variable::CONTEXT: {
886 Comment cmnt(masm_, "[ FunctionDeclaration");
887 EmitDebugCheckDeclarationContext(variable);
888 VisitForAccumulatorValue(declaration->fun());
889 __ str(result_register(), ContextOperand(cp, variable->index()));
890 int offset = Context::SlotOffset(variable->index());
891 // We know that we have written a function, which is not a smi.
892 __ RecordWriteContextSlot(cp,
893 offset,
894 result_register(),
895 r2,
896 kLRHasBeenSaved,
897 kDontSaveFPRegs,
898 EMIT_REMEMBERED_SET,
899 OMIT_SMI_CHECK);
900 PrepareForBailoutForId(proxy->id(), NO_REGISTERS);
901 break;
902 }
903
904 case Variable::LOOKUP: {
905 Comment cmnt(masm_, "[ FunctionDeclaration");
906 __ mov(r2, Operand(variable->name()));
907 __ mov(r1, Operand(Smi::FromInt(NONE)));
908 __ Push(cp, r2, r1);
909 // Push initial value for function declaration.
910 VisitForStackValue(declaration->fun());
911 __ CallRuntime(Runtime::kDeclareContextSlot, 4);
912 break;
913 }
914 }
915 }
916
917
918 void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) {
919 VariableProxy* proxy = declaration->proxy();
920 Variable* variable = proxy->var();
921 Handle<JSModule> instance = declaration->module()->interface()->Instance();
922 ASSERT(!instance.is_null());
923
924 switch (variable->location()) {
925 case Variable::UNALLOCATED: {
926 Comment cmnt(masm_, "[ ModuleDeclaration");
927 globals_->Add(variable->name());
928 globals_->Add(instance);
929 Visit(declaration->module());
930 break;
931 }
932
933 case Variable::CONTEXT: {
934 Comment cmnt(masm_, "[ ModuleDeclaration");
935 EmitDebugCheckDeclarationContext(variable);
936 __ mov(r1, Operand(instance));
937 __ str(r1, ContextOperand(cp, variable->index()));
938 Visit(declaration->module());
939 break;
940 }
941
942 case Variable::PARAMETER:
943 case Variable::LOCAL:
944 case Variable::LOOKUP:
945 UNREACHABLE();
946 }
947 }
948
949
950 void FullCodeGenerator::VisitImportDeclaration(ImportDeclaration* declaration) {
951 VariableProxy* proxy = declaration->proxy();
952 Variable* variable = proxy->var();
953 switch (variable->location()) {
954 case Variable::UNALLOCATED:
955 // TODO(rossberg)
956 break;
957
958 case Variable::CONTEXT: {
959 Comment cmnt(masm_, "[ ImportDeclaration");
960 EmitDebugCheckDeclarationContext(variable);
961 // TODO(rossberg)
962 break;
963 }
964
965 case Variable::PARAMETER:
966 case Variable::LOCAL:
967 case Variable::LOOKUP:
968 UNREACHABLE();
969 }
970 }
971
972
973 void FullCodeGenerator::VisitExportDeclaration(ExportDeclaration* declaration) {
974 // TODO(rossberg)
975 }
976
977
879 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 978 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
880 // Call the runtime to declare the globals. 979 // Call the runtime to declare the globals.
881 // The context is the first argument. 980 // The context is the first argument.
882 __ mov(r1, Operand(pairs)); 981 __ mov(r1, Operand(pairs));
883 __ mov(r0, Operand(Smi::FromInt(DeclareGlobalsFlags()))); 982 __ mov(r0, Operand(Smi::FromInt(DeclareGlobalsFlags())));
884 __ Push(cp, r1, r0); 983 __ Push(cp, r1, r0);
885 __ CallRuntime(Runtime::kDeclareGlobals, 3); 984 __ CallRuntime(Runtime::kDeclareGlobals, 3);
886 // Return value is ignored. 985 // Return value is ignored.
887 } 986 }
888 987
(...skipping 3550 matching lines...) Expand 10 before | Expand all | Expand 10 after
4439 } 4538 }
4440 4539
4441 4540
4442 void FullCodeGenerator::LoadContextField(Register dst, int context_index) { 4541 void FullCodeGenerator::LoadContextField(Register dst, int context_index) {
4443 __ ldr(dst, ContextOperand(cp, context_index)); 4542 __ ldr(dst, ContextOperand(cp, context_index));
4444 } 4543 }
4445 4544
4446 4545
4447 void FullCodeGenerator::PushFunctionArgumentForContextAllocation() { 4546 void FullCodeGenerator::PushFunctionArgumentForContextAllocation() {
4448 Scope* declaration_scope = scope()->DeclarationScope(); 4547 Scope* declaration_scope = scope()->DeclarationScope();
4449 if (declaration_scope->is_global_scope()) { 4548 if (declaration_scope->is_global_scope() ||
4549 declaration_scope->is_module_scope()) {
4450 // Contexts nested in the global context have a canonical empty function 4550 // Contexts nested in the global context have a canonical empty function
4451 // as their closure, not the anonymous closure containing the global 4551 // as their closure, not the anonymous closure containing the global
4452 // code. Pass a smi sentinel and let the runtime look up the empty 4552 // code. Pass a smi sentinel and let the runtime look up the empty
4453 // function. 4553 // function.
4454 __ mov(ip, Operand(Smi::FromInt(0))); 4554 __ mov(ip, Operand(Smi::FromInt(0)));
4455 } else if (declaration_scope->is_eval_scope()) { 4555 } else if (declaration_scope->is_eval_scope()) {
4456 // Contexts created by a call to eval have the same closure as the 4556 // Contexts created by a call to eval have the same closure as the
4457 // context calling eval, not the anonymous closure containing the eval 4557 // context calling eval, not the anonymous closure containing the eval
4458 // code. Fetch it from the context. 4558 // code. Fetch it from the context.
4459 __ ldr(ip, ContextOperand(cp, Context::CLOSURE_INDEX)); 4559 __ ldr(ip, ContextOperand(cp, Context::CLOSURE_INDEX));
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
4519 *context_length = 0; 4619 *context_length = 0;
4520 return previous_; 4620 return previous_;
4521 } 4621 }
4522 4622
4523 4623
4524 #undef __ 4624 #undef __
4525 4625
4526 } } // namespace v8::internal 4626 } } // namespace v8::internal
4527 4627
4528 #endif // V8_TARGET_ARCH_ARM 4628 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/code-stubs-arm.cc ('k') | src/arm/lithium-codegen-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698