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

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

Issue 7824038: Remove variable rewrites and the unneccesary Slot class. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 3 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
OLDNEW
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 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
193 } else { 193 } else {
194 __ CallRuntime(Runtime::kNewFunctionContext, 1); 194 __ CallRuntime(Runtime::kNewFunctionContext, 1);
195 } 195 }
196 function_in_register = false; 196 function_in_register = false;
197 // Context is returned in both v0 and cp. It replaces the context 197 // Context is returned in both v0 and cp. It replaces the context
198 // passed to us. It's saved in the stack and kept live in cp. 198 // passed to us. It's saved in the stack and kept live in cp.
199 __ sw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 199 __ sw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
200 // Copy any necessary parameters into the context. 200 // Copy any necessary parameters into the context.
201 int num_parameters = info->scope()->num_parameters(); 201 int num_parameters = info->scope()->num_parameters();
202 for (int i = 0; i < num_parameters; i++) { 202 for (int i = 0; i < num_parameters; i++) {
203 Slot* slot = scope()->parameter(i)->AsSlot(); 203 Slot* slot = scope()->parameter(i)->rewrite();
204 if (slot != NULL && slot->type() == Slot::CONTEXT) { 204 if (slot != NULL && slot->type() == Slot::CONTEXT) {
205 int parameter_offset = StandardFrameConstants::kCallerSPOffset + 205 int parameter_offset = StandardFrameConstants::kCallerSPOffset +
206 (num_parameters - 1 - i) * kPointerSize; 206 (num_parameters - 1 - i) * kPointerSize;
207 // Load parameter from stack. 207 // Load parameter from stack.
208 __ lw(a0, MemOperand(fp, parameter_offset)); 208 __ lw(a0, MemOperand(fp, parameter_offset));
209 // Store it in the context. 209 // Store it in the context.
210 __ li(a1, Operand(Context::SlotOffset(slot->index()))); 210 __ li(a1, Operand(Context::SlotOffset(slot->index())));
211 __ addu(a2, cp, a1); 211 __ addu(a2, cp, a1);
212 __ sw(a0, MemOperand(a2, 0)); 212 __ sw(a0, MemOperand(a2, 0));
213 // Update the write barrier. This clobbers all involved 213 // Update the write barrier. This clobbers all involved
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
245 if (is_strict_mode()) { 245 if (is_strict_mode()) {
246 type = ArgumentsAccessStub::NEW_STRICT; 246 type = ArgumentsAccessStub::NEW_STRICT;
247 } else if (function()->has_duplicate_parameters()) { 247 } else if (function()->has_duplicate_parameters()) {
248 type = ArgumentsAccessStub::NEW_NON_STRICT_SLOW; 248 type = ArgumentsAccessStub::NEW_NON_STRICT_SLOW;
249 } else { 249 } else {
250 type = ArgumentsAccessStub::NEW_NON_STRICT_FAST; 250 type = ArgumentsAccessStub::NEW_NON_STRICT_FAST;
251 } 251 }
252 ArgumentsAccessStub stub(type); 252 ArgumentsAccessStub stub(type);
253 __ CallStub(&stub); 253 __ CallStub(&stub);
254 254
255 Move(arguments->AsSlot(), v0, a1, a2); 255 Move(arguments->rewrite(), v0, a1, a2);
256 } 256 }
257 257
258 if (FLAG_trace) { 258 if (FLAG_trace) {
259 __ CallRuntime(Runtime::kTraceEnter, 0); 259 __ CallRuntime(Runtime::kTraceEnter, 0);
260 } 260 }
261 261
262 // Visit the declarations and body unless there is an illegal 262 // Visit the declarations and body unless there is an illegal
263 // redeclaration. 263 // redeclaration.
264 if (scope()->HasIllegalRedeclaration()) { 264 if (scope()->HasIllegalRedeclaration()) {
265 Comment cmnt(masm_, "[ Declarations"); 265 Comment cmnt(masm_, "[ Declarations");
(...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after
626 case Slot::PARAMETER: 626 case Slot::PARAMETER:
627 case Slot::LOCAL: 627 case Slot::LOCAL:
628 return MemOperand(fp, SlotOffset(slot)); 628 return MemOperand(fp, SlotOffset(slot));
629 case Slot::CONTEXT: { 629 case Slot::CONTEXT: {
630 int context_chain_length = 630 int context_chain_length =
631 scope()->ContextChainLength(slot->var()->scope()); 631 scope()->ContextChainLength(slot->var()->scope());
632 __ LoadContext(scratch, context_chain_length); 632 __ LoadContext(scratch, context_chain_length);
633 return ContextOperand(scratch, slot->index()); 633 return ContextOperand(scratch, slot->index());
634 } 634 }
635 case Slot::LOOKUP: 635 case Slot::LOOKUP:
636 case Slot::GLOBAL:
636 UNREACHABLE(); 637 UNREACHABLE();
637 } 638 }
638 UNREACHABLE(); 639 UNREACHABLE();
639 return MemOperand(v0, 0); 640 return MemOperand(v0, 0);
640 } 641 }
641 642
642 643
643 void FullCodeGenerator::Move(Register destination, Slot* source) { 644 void FullCodeGenerator::Move(Register destination, Slot* source) {
644 // Use destination as scratch. 645 // Use destination as scratch.
645 MemOperand slot_operand = EmitSlotSearch(source, destination); 646 MemOperand slot_operand = EmitSlotSearch(source, destination);
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
689 src); 690 src);
690 } 691 }
691 } 692 }
692 693
693 694
694 void FullCodeGenerator::EmitDeclaration(Variable* variable, 695 void FullCodeGenerator::EmitDeclaration(Variable* variable,
695 Variable::Mode mode, 696 Variable::Mode mode,
696 FunctionLiteral* function) { 697 FunctionLiteral* function) {
697 Comment cmnt(masm_, "[ Declaration"); 698 Comment cmnt(masm_, "[ Declaration");
698 ASSERT(variable != NULL); // Must have been resolved. 699 ASSERT(variable != NULL); // Must have been resolved.
699 Slot* slot = variable->AsSlot(); 700 Slot* slot = variable->rewrite();
700 ASSERT(slot != NULL); 701 ASSERT(slot != NULL);
701 switch (slot->type()) { 702 switch (slot->type()) {
702 case Slot::PARAMETER: 703 case Slot::PARAMETER:
703 case Slot::LOCAL: 704 case Slot::LOCAL:
704 if (function != NULL) { 705 if (function != NULL) {
705 VisitForAccumulatorValue(function); 706 VisitForAccumulatorValue(function);
706 __ sw(result_register(), MemOperand(fp, SlotOffset(slot))); 707 __ sw(result_register(), MemOperand(fp, SlotOffset(slot)));
707 } else if (mode == Variable::CONST || mode == Variable::LET) { 708 } else if (mode == Variable::CONST || mode == Variable::LET) {
708 __ LoadRoot(t0, Heap::kTheHoleValueRootIndex); 709 __ LoadRoot(t0, Heap::kTheHoleValueRootIndex);
709 __ sw(t0, MemOperand(fp, SlotOffset(slot))); 710 __ sw(t0, MemOperand(fp, SlotOffset(slot)));
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
762 __ Push(cp, a2, a1, a0); 763 __ Push(cp, a2, a1, a0);
763 } else { 764 } else {
764 ASSERT(Smi::FromInt(0) == 0); 765 ASSERT(Smi::FromInt(0) == 0);
765 // No initial value! 766 // No initial value!
766 __ mov(a0, zero_reg); // Operand(Smi::FromInt(0))); 767 __ mov(a0, zero_reg); // Operand(Smi::FromInt(0)));
767 __ Push(cp, a2, a1, a0); 768 __ Push(cp, a2, a1, a0);
768 } 769 }
769 __ CallRuntime(Runtime::kDeclareContextSlot, 4); 770 __ CallRuntime(Runtime::kDeclareContextSlot, 4);
770 break; 771 break;
771 } 772 }
773
774 case Slot::GLOBAL:
775 UNREACHABLE();
772 } 776 }
773 } 777 }
774 778
775 779
776 void FullCodeGenerator::VisitDeclaration(Declaration* decl) { 780 void FullCodeGenerator::VisitDeclaration(Declaration* decl) {
777 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun()); 781 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun());
778 } 782 }
779 783
780 784
781 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 785 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after
1182 Label* done) { 1186 Label* done) {
1183 // Generate fast-case code for variables that might be shadowed by 1187 // Generate fast-case code for variables that might be shadowed by
1184 // eval-introduced variables. Eval is used a lot without 1188 // eval-introduced variables. Eval is used a lot without
1185 // introducing variables. In those cases, we do not want to 1189 // introducing variables. In those cases, we do not want to
1186 // perform a runtime call for all variables in the scope 1190 // perform a runtime call for all variables in the scope
1187 // containing the eval. 1191 // containing the eval.
1188 if (slot->var()->mode() == Variable::DYNAMIC_GLOBAL) { 1192 if (slot->var()->mode() == Variable::DYNAMIC_GLOBAL) {
1189 EmitLoadGlobalSlotCheckExtensions(slot, typeof_state, slow); 1193 EmitLoadGlobalSlotCheckExtensions(slot, typeof_state, slow);
1190 __ Branch(done); 1194 __ Branch(done);
1191 } else if (slot->var()->mode() == Variable::DYNAMIC_LOCAL) { 1195 } else if (slot->var()->mode() == Variable::DYNAMIC_LOCAL) {
1192 Slot* potential_slot = slot->var()->local_if_not_shadowed()->AsSlot(); 1196 Slot* potential_slot = slot->var()->local_if_not_shadowed()->rewrite();
1193 Expression* rewrite = slot->var()->local_if_not_shadowed()->rewrite(); 1197 Expression* rewrite = slot->var()->local_if_not_shadowed()->rewrite();
1194 if (potential_slot != NULL) { 1198 if (potential_slot != NULL) {
1195 // Generate fast case for locals that rewrite to slots. 1199 // Generate fast case for locals that rewrite to slots.
1196 __ lw(v0, ContextSlotOperandCheckExtensions(potential_slot, slow)); 1200 __ lw(v0, ContextSlotOperandCheckExtensions(potential_slot, slow));
1197 if (potential_slot->var()->mode() == Variable::CONST) { 1201 if (potential_slot->var()->mode() == Variable::CONST) {
1198 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 1202 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
1199 __ subu(at, v0, at); // Sub as compare: at == 0 on eq. 1203 __ subu(at, v0, at); // Sub as compare: at == 0 on eq.
1200 __ LoadRoot(a0, Heap::kUndefinedValueRootIndex); 1204 __ LoadRoot(a0, Heap::kUndefinedValueRootIndex);
1201 __ movz(v0, a0, at); // Conditional move. 1205 __ movz(v0, a0, at); // Conditional move.
1202 } 1206 }
1203 __ Branch(done); 1207 __ Branch(done);
1204 } else if (rewrite != NULL) { 1208 } else if (rewrite != NULL) {
1205 // Generate fast case for calls of an argument function. 1209 // Generate fast case for calls of an argument function.
1206 Property* property = rewrite->AsProperty(); 1210 Property* property = rewrite->AsProperty();
1207 if (property != NULL) { 1211 if (property != NULL) {
1208 VariableProxy* obj_proxy = property->obj()->AsVariableProxy(); 1212 VariableProxy* obj_proxy = property->obj()->AsVariableProxy();
1209 Literal* key_literal = property->key()->AsLiteral(); 1213 Literal* key_literal = property->key()->AsLiteral();
1210 if (obj_proxy != NULL && 1214 if (obj_proxy != NULL &&
1211 key_literal != NULL && 1215 key_literal != NULL &&
1212 obj_proxy->IsArguments() && 1216 obj_proxy->IsArguments() &&
1213 key_literal->handle()->IsSmi()) { 1217 key_literal->handle()->IsSmi()) {
1214 // Load arguments object if there are no eval-introduced 1218 // Load arguments object if there are no eval-introduced
1215 // variables. Then load the argument from the arguments 1219 // variables. Then load the argument from the arguments
1216 // object using keyed load. 1220 // object using keyed load.
1217 __ lw(a1, 1221 __ lw(a1,
1218 ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(), 1222 ContextSlotOperandCheckExtensions(obj_proxy->var()->rewrite(),
1219 slow)); 1223 slow));
1220 __ li(a0, Operand(key_literal->handle())); 1224 __ li(a0, Operand(key_literal->handle()));
1221 Handle<Code> ic = 1225 Handle<Code> ic =
1222 isolate()->builtins()->KeyedLoadIC_Initialize(); 1226 isolate()->builtins()->KeyedLoadIC_Initialize();
1223 __ Call(ic, RelocInfo::CODE_TARGET, GetPropertyId(property)); 1227 __ Call(ic, RelocInfo::CODE_TARGET, GetPropertyId(property));
1224 __ Branch(done); 1228 __ Branch(done);
1225 } 1229 }
1226 } 1230 }
1227 } 1231 }
1228 } 1232 }
1229 } 1233 }
1230 1234
1231 1235
1232 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { 1236 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) {
1233 // Record position before possible IC call. 1237 // Record position before possible IC call.
1234 SetSourcePosition(proxy->position()); 1238 SetSourcePosition(proxy->position());
1235 Variable* var = proxy->var(); 1239 Variable* var = proxy->var();
1236 1240
1237 // Three cases: non-this global variables, lookup slots, and all other 1241 // Three cases: non-this global variables, lookup slots, and all other
1238 // types of slots. 1242 // types of slots.
1239 Slot* slot = var->AsSlot(); 1243 Slot* slot = var->rewrite();
1240 ASSERT((var->is_global() && !var->is_this()) == (slot == NULL)); 1244 ASSERT((var->is_global() && !var->is_this()) == (slot == NULL));
1241 1245
1242 if (slot == NULL) { 1246 if (slot == NULL) {
1243 Comment cmnt(masm_, "Global variable"); 1247 Comment cmnt(masm_, "Global variable");
1244 // Use inline caching. Variable name is passed in a2 and the global 1248 // Use inline caching. Variable name is passed in a2 and the global
1245 // object (receiver) in a0. 1249 // object (receiver) in a0.
1246 __ lw(a0, GlobalObjectOperand()); 1250 __ lw(a0, GlobalObjectOperand());
1247 __ li(a2, Operand(var->name())); 1251 __ li(a2, Operand(var->name()));
1248 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 1252 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
1249 __ Call(ic, RelocInfo::CODE_TARGET_CONTEXT); 1253 __ Call(ic, RelocInfo::CODE_TARGET_CONTEXT);
(...skipping 576 matching lines...) Expand 10 before | Expand all | Expand 10 after
1826 } 1830 }
1827 } 1831 }
1828 PrepareForBailoutForId(bailout_ast_id, TOS_REG); 1832 PrepareForBailoutForId(bailout_ast_id, TOS_REG);
1829 context()->Plug(v0); 1833 context()->Plug(v0);
1830 } 1834 }
1831 1835
1832 1836
1833 void FullCodeGenerator::EmitVariableAssignment(Variable* var, 1837 void FullCodeGenerator::EmitVariableAssignment(Variable* var,
1834 Token::Value op) { 1838 Token::Value op) {
1835 ASSERT(var != NULL); 1839 ASSERT(var != NULL);
1836 ASSERT(var->is_global() || var->AsSlot() != NULL); 1840 ASSERT(var->is_global() || var->rewrite() != NULL);
1837 1841
1838 if (var->is_global()) { 1842 if (var->is_global()) {
1839 ASSERT(!var->is_this()); 1843 ASSERT(!var->is_this());
1840 // Assignment to a global variable. Use inline caching for the 1844 // Assignment to a global variable. Use inline caching for the
1841 // assignment. Right-hand-side value is passed in a0, variable name in 1845 // assignment. Right-hand-side value is passed in a0, variable name in
1842 // a2, and the global object in a1. 1846 // a2, and the global object in a1.
1843 __ mov(a0, result_register()); 1847 __ mov(a0, result_register());
1844 __ li(a2, Operand(var->name())); 1848 __ li(a2, Operand(var->name()));
1845 __ lw(a1, GlobalObjectOperand()); 1849 __ lw(a1, GlobalObjectOperand());
1846 Handle<Code> ic = is_strict_mode() 1850 Handle<Code> ic = is_strict_mode()
1847 ? isolate()->builtins()->StoreIC_Initialize_Strict() 1851 ? isolate()->builtins()->StoreIC_Initialize_Strict()
1848 : isolate()->builtins()->StoreIC_Initialize(); 1852 : isolate()->builtins()->StoreIC_Initialize();
1849 __ Call(ic, RelocInfo::CODE_TARGET_CONTEXT); 1853 __ Call(ic, RelocInfo::CODE_TARGET_CONTEXT);
1850 1854
1851 } else if (op == Token::INIT_CONST) { 1855 } else if (op == Token::INIT_CONST) {
1852 // Like var declarations, const declarations are hoisted to function 1856 // Like var declarations, const declarations are hoisted to function
1853 // scope. However, unlike var initializers, const initializers are able 1857 // scope. However, unlike var initializers, const initializers are able
1854 // to drill a hole to that function context, even from inside a 'with' 1858 // to drill a hole to that function context, even from inside a 'with'
1855 // context. We thus bypass the normal static scope lookup. 1859 // context. We thus bypass the normal static scope lookup.
1856 Slot* slot = var->AsSlot(); 1860 Slot* slot = var->rewrite();
1857 Label skip; 1861 Label skip;
1858 switch (slot->type()) { 1862 switch (slot->type()) {
1859 case Slot::PARAMETER: 1863 case Slot::PARAMETER:
1860 // No const parameters. 1864 // No const parameters.
1861 UNREACHABLE(); 1865 UNREACHABLE();
1862 break; 1866 break;
1863 case Slot::LOCAL: 1867 case Slot::LOCAL:
1864 // Detect const reinitialization by checking for the hole value. 1868 // Detect const reinitialization by checking for the hole value.
1865 __ lw(a1, MemOperand(fp, SlotOffset(slot))); 1869 __ lw(a1, MemOperand(fp, SlotOffset(slot)));
1866 __ LoadRoot(t0, Heap::kTheHoleValueRootIndex); 1870 __ LoadRoot(t0, Heap::kTheHoleValueRootIndex);
1867 __ Branch(&skip, ne, a1, Operand(t0)); 1871 __ Branch(&skip, ne, a1, Operand(t0));
1868 __ sw(result_register(), MemOperand(fp, SlotOffset(slot))); 1872 __ sw(result_register(), MemOperand(fp, SlotOffset(slot)));
1869 break; 1873 break;
1870 case Slot::CONTEXT: 1874 case Slot::CONTEXT:
1871 case Slot::LOOKUP: 1875 case Slot::LOOKUP:
1872 __ push(result_register()); 1876 __ push(result_register());
1873 __ li(a0, Operand(slot->var()->name())); 1877 __ li(a0, Operand(slot->var()->name()));
1874 __ Push(cp, a0); // Context and name. 1878 __ Push(cp, a0); // Context and name.
1875 __ CallRuntime(Runtime::kInitializeConstContextSlot, 3); 1879 __ CallRuntime(Runtime::kInitializeConstContextSlot, 3);
1876 break; 1880 break;
1881 case Slot::GLOBAL:
1882 UNREACHABLE();
1877 } 1883 }
1878 __ bind(&skip); 1884 __ bind(&skip);
1879 } else if (var->mode() == Variable::LET && op != Token::INIT_LET) { 1885 } else if (var->mode() == Variable::LET && op != Token::INIT_LET) {
1880 // Perform the assignment for non-const variables. Const assignments 1886 // Perform the assignment for non-const variables. Const assignments
1881 // are simply skipped. 1887 // are simply skipped.
1882 Slot* slot = var->AsSlot(); 1888 Slot* slot = var->AsSlot();
1883 switch (slot->type()) { 1889 switch (slot->type()) {
1884 case Slot::PARAMETER: 1890 case Slot::PARAMETER:
1885 case Slot::LOCAL: { 1891 case Slot::LOCAL: {
1886 Label assign; 1892 Label assign;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1923 __ li(a1, Operand(slot->var()->name())); 1929 __ li(a1, Operand(slot->var()->name()));
1924 __ li(a0, Operand(Smi::FromInt(strict_mode_flag()))); 1930 __ li(a0, Operand(Smi::FromInt(strict_mode_flag())));
1925 __ Push(cp, a1, a0); // Context, name, strict mode. 1931 __ Push(cp, a1, a0); // Context, name, strict mode.
1926 __ CallRuntime(Runtime::kStoreContextSlot, 4); 1932 __ CallRuntime(Runtime::kStoreContextSlot, 4);
1927 break; 1933 break;
1928 } 1934 }
1929 1935
1930 } else if (var->mode() != Variable::CONST) { 1936 } else if (var->mode() != Variable::CONST) {
1931 // Perform the assignment for non-const variables. Const assignments 1937 // Perform the assignment for non-const variables. Const assignments
1932 // are simply skipped. 1938 // are simply skipped.
1933 Slot* slot = var->AsSlot(); 1939 Slot* slot = var->rewrite();
1934 switch (slot->type()) { 1940 switch (slot->type()) {
1935 case Slot::PARAMETER: 1941 case Slot::PARAMETER:
1936 case Slot::LOCAL: 1942 case Slot::LOCAL:
1937 // Perform the assignment. 1943 // Perform the assignment.
1938 __ sw(result_register(), MemOperand(fp, SlotOffset(slot))); 1944 __ sw(result_register(), MemOperand(fp, SlotOffset(slot)));
1939 break; 1945 break;
1940 1946
1941 case Slot::CONTEXT: { 1947 case Slot::CONTEXT: {
1942 MemOperand target = EmitSlotSearch(slot, a1); 1948 MemOperand target = EmitSlotSearch(slot, a1);
1943 // Perform the assignment and issue the write barrier. 1949 // Perform the assignment and issue the write barrier.
1944 __ sw(result_register(), target); 1950 __ sw(result_register(), target);
1945 // RecordWrite may destroy all its register arguments. 1951 // RecordWrite may destroy all its register arguments.
1946 __ mov(a3, result_register()); 1952 __ mov(a3, result_register());
1947 int offset = FixedArray::kHeaderSize + slot->index() * kPointerSize; 1953 int offset = FixedArray::kHeaderSize + slot->index() * kPointerSize;
1948 __ RecordWrite(a1, Operand(offset), a2, a3); 1954 __ RecordWrite(a1, Operand(offset), a2, a3);
1949 break; 1955 break;
1950 } 1956 }
1951 1957
1952 case Slot::LOOKUP: 1958 case Slot::LOOKUP:
1953 // Call the runtime for the assignment. 1959 // Call the runtime for the assignment.
1954 __ push(v0); // Value. 1960 __ push(v0); // Value.
1955 __ li(a1, Operand(slot->var()->name())); 1961 __ li(a1, Operand(slot->var()->name()));
1956 __ li(a0, Operand(Smi::FromInt(strict_mode_flag()))); 1962 __ li(a0, Operand(Smi::FromInt(strict_mode_flag())));
1957 __ Push(cp, a1, a0); // Context, name, strict mode. 1963 __ Push(cp, a1, a0); // Context, name, strict mode.
1958 __ CallRuntime(Runtime::kStoreContextSlot, 4); 1964 __ CallRuntime(Runtime::kStoreContextSlot, 4);
1959 break; 1965 break;
1966
1967 case Slot::GLOBAL:
1968 UNREACHABLE();
1960 } 1969 }
1961 } 1970 }
1962 } 1971 }
1963 1972
1964 1973
1965 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { 1974 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
1966 // Assignment to a property, using a named store IC. 1975 // Assignment to a property, using a named store IC.
1967 Property* prop = expr->target()->AsProperty(); 1976 Property* prop = expr->target()->AsProperty();
1968 ASSERT(prop != NULL); 1977 ASSERT(prop != NULL);
1969 ASSERT(prop->key()->AsLiteral() != NULL); 1978 ASSERT(prop->key()->AsLiteral() != NULL);
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
2217 2226
2218 // Push the arguments. 2227 // Push the arguments.
2219 for (int i = 0; i < arg_count; i++) { 2228 for (int i = 0; i < arg_count; i++) {
2220 VisitForStackValue(args->at(i)); 2229 VisitForStackValue(args->at(i));
2221 } 2230 }
2222 // If we know that eval can only be shadowed by eval-introduced 2231 // If we know that eval can only be shadowed by eval-introduced
2223 // variables we attempt to load the global eval function directly 2232 // variables we attempt to load the global eval function directly
2224 // in generated code. If we succeed, there is no need to perform a 2233 // in generated code. If we succeed, there is no need to perform a
2225 // context lookup in the runtime system. 2234 // context lookup in the runtime system.
2226 Label done; 2235 Label done;
2227 if (var->AsSlot() != NULL && var->mode() == Variable::DYNAMIC_GLOBAL) { 2236 if (var->rewrite() != NULL && var->mode() == Variable::DYNAMIC_GLOBAL) {
2228 Label slow; 2237 Label slow;
2229 EmitLoadGlobalSlotCheckExtensions(var->AsSlot(), 2238 EmitLoadGlobalSlotCheckExtensions(var->rewrite(),
2230 NOT_INSIDE_TYPEOF, 2239 NOT_INSIDE_TYPEOF,
2231 &slow); 2240 &slow);
2232 // Push the function and resolve eval. 2241 // Push the function and resolve eval.
2233 __ push(v0); 2242 __ push(v0);
2234 EmitResolvePossiblyDirectEval(SKIP_CONTEXT_LOOKUP, arg_count); 2243 EmitResolvePossiblyDirectEval(SKIP_CONTEXT_LOOKUP, arg_count);
2235 __ jmp(&done); 2244 __ jmp(&done);
2236 __ bind(&slow); 2245 __ bind(&slow);
2237 } 2246 }
2238 2247
2239 // Push copy of the function (found below the arguments) and 2248 // Push copy of the function (found below the arguments) and
(...skipping 17 matching lines...) Expand all
2257 __ CallStub(&stub); 2266 __ CallStub(&stub);
2258 RecordJSReturnSite(expr); 2267 RecordJSReturnSite(expr);
2259 // Restore context register. 2268 // Restore context register.
2260 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2269 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2261 context()->DropAndPlug(1, v0); 2270 context()->DropAndPlug(1, v0);
2262 } else if (var != NULL && !var->is_this() && var->is_global()) { 2271 } else if (var != NULL && !var->is_this() && var->is_global()) {
2263 // Push global object as receiver for the call IC. 2272 // Push global object as receiver for the call IC.
2264 __ lw(a0, GlobalObjectOperand()); 2273 __ lw(a0, GlobalObjectOperand());
2265 __ push(a0); 2274 __ push(a0);
2266 EmitCallWithIC(expr, var->name(), RelocInfo::CODE_TARGET_CONTEXT); 2275 EmitCallWithIC(expr, var->name(), RelocInfo::CODE_TARGET_CONTEXT);
2267 } else if (var != NULL && var->AsSlot() != NULL && 2276 } else if (var != NULL && var->rewrite() != NULL &&
2268 var->AsSlot()->type() == Slot::LOOKUP) { 2277 var->rewrite()->type() == Slot::LOOKUP) {
2269 // Call to a lookup slot (dynamically introduced variable). 2278 // Call to a lookup slot (dynamically introduced variable).
2270 Label slow, done; 2279 Label slow, done;
2271 2280
2272 { PreservePositionScope scope(masm()->positions_recorder()); 2281 { PreservePositionScope scope(masm()->positions_recorder());
2273 // Generate code for loading from variables potentially shadowed 2282 // Generate code for loading from variables potentially shadowed
2274 // by eval-introduced variables. 2283 // by eval-introduced variables.
2275 EmitDynamicLoadFromSlotFastCase(var->AsSlot(), 2284 EmitDynamicLoadFromSlotFastCase(var->rewrite(),
2276 NOT_INSIDE_TYPEOF, 2285 NOT_INSIDE_TYPEOF,
2277 &slow, 2286 &slow,
2278 &done); 2287 &done);
2279 } 2288 }
2280 2289
2281 __ bind(&slow); 2290 __ bind(&slow);
2282 // Call the runtime to find the function to call (returned in v0) 2291 // Call the runtime to find the function to call (returned in v0)
2283 // and the object holding it (returned in v1). 2292 // and the object holding it (returned in v1).
2284 __ push(context_register()); 2293 __ push(context_register());
2285 __ li(a2, Operand(var->name())); 2294 __ li(a2, Operand(var->name()));
(...skipping 1384 matching lines...) Expand 10 before | Expand all | Expand 10 after
3670 // Delete of an unqualified identifier is disallowed in strict mode 3679 // Delete of an unqualified identifier is disallowed in strict mode
3671 // but "delete this" is. 3680 // but "delete this" is.
3672 ASSERT(strict_mode_flag() == kNonStrictMode || var->is_this()); 3681 ASSERT(strict_mode_flag() == kNonStrictMode || var->is_this());
3673 if (var->is_global()) { 3682 if (var->is_global()) {
3674 __ lw(a2, GlobalObjectOperand()); 3683 __ lw(a2, GlobalObjectOperand());
3675 __ li(a1, Operand(var->name())); 3684 __ li(a1, Operand(var->name()));
3676 __ li(a0, Operand(Smi::FromInt(kNonStrictMode))); 3685 __ li(a0, Operand(Smi::FromInt(kNonStrictMode)));
3677 __ Push(a2, a1, a0); 3686 __ Push(a2, a1, a0);
3678 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); 3687 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
3679 context()->Plug(v0); 3688 context()->Plug(v0);
3680 } else if (var->AsSlot() != NULL && 3689 } else if (var->rewrite() != NULL &&
3681 var->AsSlot()->type() != Slot::LOOKUP) { 3690 var->rewrite()->type() != Slot::LOOKUP) {
3682 // Result of deleting non-global, non-dynamic variables is false. 3691 // Result of deleting non-global, non-dynamic variables is false.
3683 // The subexpression does not have side effects. 3692 // The subexpression does not have side effects.
3684 context()->Plug(false); 3693 context()->Plug(false);
3685 } else { 3694 } else {
3686 // Non-global variable. Call the runtime to try to delete from the 3695 // Non-global variable. Call the runtime to try to delete from the
3687 // context where the variable was introduced. 3696 // context where the variable was introduced.
3688 __ push(context_register()); 3697 __ push(context_register());
3689 __ li(a2, Operand(var->name())); 3698 __ li(a2, Operand(var->name()));
3690 __ push(a2); 3699 __ push(a2);
3691 __ CallRuntime(Runtime::kDeleteContextSlot, 2); 3700 __ CallRuntime(Runtime::kDeleteContextSlot, 2);
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after
3961 Comment cmnt(masm_, "Global variable"); 3970 Comment cmnt(masm_, "Global variable");
3962 __ lw(a0, GlobalObjectOperand()); 3971 __ lw(a0, GlobalObjectOperand());
3963 __ li(a2, Operand(proxy->name())); 3972 __ li(a2, Operand(proxy->name()));
3964 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 3973 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
3965 // Use a regular load, not a contextual load, to avoid a reference 3974 // Use a regular load, not a contextual load, to avoid a reference
3966 // error. 3975 // error.
3967 __ Call(ic); 3976 __ Call(ic);
3968 PrepareForBailout(expr, TOS_REG); 3977 PrepareForBailout(expr, TOS_REG);
3969 context()->Plug(v0); 3978 context()->Plug(v0);
3970 } else if (proxy != NULL && 3979 } else if (proxy != NULL &&
3971 proxy->var()->AsSlot() != NULL && 3980 proxy->var()->rewrite() != NULL &&
3972 proxy->var()->AsSlot()->type() == Slot::LOOKUP) { 3981 proxy->var()->rewrite()->type() == Slot::LOOKUP) {
3973 Label done, slow; 3982 Label done, slow;
3974 3983
3975 // Generate code for loading from variables potentially shadowed 3984 // Generate code for loading from variables potentially shadowed
3976 // by eval-introduced variables. 3985 // by eval-introduced variables.
3977 Slot* slot = proxy->var()->AsSlot(); 3986 Slot* slot = proxy->var()->rewrite();
3978 EmitDynamicLoadFromSlotFastCase(slot, INSIDE_TYPEOF, &slow, &done); 3987 EmitDynamicLoadFromSlotFastCase(slot, INSIDE_TYPEOF, &slow, &done);
3979 3988
3980 __ bind(&slow); 3989 __ bind(&slow);
3981 __ li(a0, Operand(proxy->name())); 3990 __ li(a0, Operand(proxy->name()));
3982 __ Push(cp, a0); 3991 __ Push(cp, a0);
3983 __ CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2); 3992 __ CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2);
3984 PrepareForBailout(expr, TOS_REG); 3993 PrepareForBailout(expr, TOS_REG);
3985 __ bind(&done); 3994 __ bind(&done);
3986 3995
3987 context()->Plug(v0); 3996 context()->Plug(v0);
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after
4286 __ Addu(at, a1, Operand(masm_->CodeObject())); 4295 __ Addu(at, a1, Operand(masm_->CodeObject()));
4287 __ Jump(at); 4296 __ Jump(at);
4288 } 4297 }
4289 4298
4290 4299
4291 #undef __ 4300 #undef __
4292 4301
4293 } } // namespace v8::internal 4302 } } // namespace v8::internal
4294 4303
4295 #endif // V8_TARGET_ARCH_MIPS 4304 #endif // V8_TARGET_ARCH_MIPS
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698