| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 1182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1193 } else { | 1193 } else { |
| 1194 VisitForValue(expr->key(), kStack); | 1194 VisitForValue(expr->key(), kStack); |
| 1195 EmitKeyedPropertyLoad(expr); | 1195 EmitKeyedPropertyLoad(expr); |
| 1196 // Drop key and receiver left on the stack by IC. | 1196 // Drop key and receiver left on the stack by IC. |
| 1197 DropAndApply(2, context_, rax); | 1197 DropAndApply(2, context_, rax); |
| 1198 } | 1198 } |
| 1199 } | 1199 } |
| 1200 | 1200 |
| 1201 | 1201 |
| 1202 void FullCodeGenerator::EmitCallWithIC(Call* expr, | 1202 void FullCodeGenerator::EmitCallWithIC(Call* expr, |
| 1203 Handle<Object> ignored, | 1203 Handle<Object> name, |
| 1204 RelocInfo::Mode mode) { | 1204 RelocInfo::Mode mode) { |
| 1205 // Code common for calls using the IC. | 1205 // Code common for calls using the IC. |
| 1206 ZoneList<Expression*>* args = expr->arguments(); | 1206 ZoneList<Expression*>* args = expr->arguments(); |
| 1207 int arg_count = args->length(); | 1207 int arg_count = args->length(); |
| 1208 for (int i = 0; i < arg_count; i++) { | 1208 for (int i = 0; i < arg_count; i++) { |
| 1209 VisitForValue(args->at(i), kStack); | 1209 VisitForValue(args->at(i), kStack); |
| 1210 } | 1210 } |
| 1211 __ Move(rcx, name); |
| 1211 // Record source position for debugger. | 1212 // Record source position for debugger. |
| 1212 SetSourcePosition(expr->position()); | 1213 SetSourcePosition(expr->position()); |
| 1213 // Call the IC initialization code. | 1214 // Call the IC initialization code. |
| 1214 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; | 1215 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; |
| 1215 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, | 1216 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, |
| 1216 in_loop); | 1217 in_loop); |
| 1217 __ Call(ic, mode); | 1218 __ Call(ic, mode); |
| 1218 // Restore context register. | 1219 // Restore context register. |
| 1219 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 1220 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
| 1220 // Discard the function left on TOS. | 1221 Apply(context_, rax); |
| 1221 DropAndApply(1, context_, rax); | |
| 1222 } | 1222 } |
| 1223 | 1223 |
| 1224 | 1224 |
| 1225 void FullCodeGenerator::EmitCallWithStub(Call* expr) { | 1225 void FullCodeGenerator::EmitCallWithStub(Call* expr) { |
| 1226 // Code common for calls using the call stub. | 1226 // Code common for calls using the call stub. |
| 1227 ZoneList<Expression*>* args = expr->arguments(); | 1227 ZoneList<Expression*>* args = expr->arguments(); |
| 1228 int arg_count = args->length(); | 1228 int arg_count = args->length(); |
| 1229 for (int i = 0; i < arg_count; i++) { | 1229 for (int i = 0; i < arg_count; i++) { |
| 1230 VisitForValue(args->at(i), kStack); | 1230 VisitForValue(args->at(i), kStack); |
| 1231 } | 1231 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1243 void FullCodeGenerator::VisitCall(Call* expr) { | 1243 void FullCodeGenerator::VisitCall(Call* expr) { |
| 1244 Comment cmnt(masm_, "[ Call"); | 1244 Comment cmnt(masm_, "[ Call"); |
| 1245 Expression* fun = expr->expression(); | 1245 Expression* fun = expr->expression(); |
| 1246 Variable* var = fun->AsVariableProxy()->AsVariable(); | 1246 Variable* var = fun->AsVariableProxy()->AsVariable(); |
| 1247 | 1247 |
| 1248 if (var != NULL && var->is_possibly_eval()) { | 1248 if (var != NULL && var->is_possibly_eval()) { |
| 1249 // Call to the identifier 'eval'. | 1249 // Call to the identifier 'eval'. |
| 1250 UNREACHABLE(); | 1250 UNREACHABLE(); |
| 1251 } else if (var != NULL && !var->is_this() && var->is_global()) { | 1251 } else if (var != NULL && !var->is_this() && var->is_global()) { |
| 1252 // Call to a global variable. | 1252 // Call to a global variable. |
| 1253 __ Push(var->name()); | |
| 1254 // Push global object as receiver for the call IC lookup. | 1253 // Push global object as receiver for the call IC lookup. |
| 1255 __ push(CodeGenerator::GlobalObject()); | 1254 __ push(CodeGenerator::GlobalObject()); |
| 1256 EmitCallWithIC(expr, var->name(), RelocInfo::CODE_TARGET_CONTEXT); | 1255 EmitCallWithIC(expr, var->name(), RelocInfo::CODE_TARGET_CONTEXT); |
| 1257 } else if (var != NULL && var->slot() != NULL && | 1256 } else if (var != NULL && var->slot() != NULL && |
| 1258 var->slot()->type() == Slot::LOOKUP) { | 1257 var->slot()->type() == Slot::LOOKUP) { |
| 1259 // Call to a lookup slot. | 1258 // Call to a lookup slot. |
| 1260 UNREACHABLE(); | 1259 UNREACHABLE(); |
| 1261 } else if (fun->AsProperty() != NULL) { | 1260 } else if (fun->AsProperty() != NULL) { |
| 1262 // Call to an object property. | 1261 // Call to an object property. |
| 1263 Property* prop = fun->AsProperty(); | 1262 Property* prop = fun->AsProperty(); |
| 1264 Literal* key = prop->key()->AsLiteral(); | 1263 Literal* key = prop->key()->AsLiteral(); |
| 1265 if (key != NULL && key->handle()->IsSymbol()) { | 1264 if (key != NULL && key->handle()->IsSymbol()) { |
| 1266 // Call to a named property, use call IC. | 1265 // Call to a named property, use call IC. |
| 1267 __ Push(key->handle()); | |
| 1268 VisitForValue(prop->obj(), kStack); | 1266 VisitForValue(prop->obj(), kStack); |
| 1269 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET); | 1267 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET); |
| 1270 } else { | 1268 } else { |
| 1271 // Call to a keyed property, use keyed load IC followed by function | 1269 // Call to a keyed property, use keyed load IC followed by function |
| 1272 // call. | 1270 // call. |
| 1273 VisitForValue(prop->obj(), kStack); | 1271 VisitForValue(prop->obj(), kStack); |
| 1274 VisitForValue(prop->key(), kStack); | 1272 VisitForValue(prop->key(), kStack); |
| 1275 // Record source code position for IC call. | 1273 // Record source code position for IC call. |
| 1276 SetSourcePosition(prop->position()); | 1274 SetSourcePosition(prop->position()); |
| 1277 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); | 1275 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1348 DropAndApply(1, context_, rax); | 1346 DropAndApply(1, context_, rax); |
| 1349 } | 1347 } |
| 1350 | 1348 |
| 1351 | 1349 |
| 1352 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { | 1350 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { |
| 1353 Comment cmnt(masm_, "[ CallRuntime"); | 1351 Comment cmnt(masm_, "[ CallRuntime"); |
| 1354 ZoneList<Expression*>* args = expr->arguments(); | 1352 ZoneList<Expression*>* args = expr->arguments(); |
| 1355 | 1353 |
| 1356 if (expr->is_jsruntime()) { | 1354 if (expr->is_jsruntime()) { |
| 1357 // Prepare for calling JS runtime function. | 1355 // Prepare for calling JS runtime function. |
| 1358 __ Push(expr->name()); | |
| 1359 __ movq(rax, CodeGenerator::GlobalObject()); | 1356 __ movq(rax, CodeGenerator::GlobalObject()); |
| 1360 __ push(FieldOperand(rax, GlobalObject::kBuiltinsOffset)); | 1357 __ push(FieldOperand(rax, GlobalObject::kBuiltinsOffset)); |
| 1361 } | 1358 } |
| 1362 | 1359 |
| 1363 // Push the arguments ("left-to-right"). | 1360 // Push the arguments ("left-to-right"). |
| 1364 int arg_count = args->length(); | 1361 int arg_count = args->length(); |
| 1365 for (int i = 0; i < arg_count; i++) { | 1362 for (int i = 0; i < arg_count; i++) { |
| 1366 VisitForValue(args->at(i), kStack); | 1363 VisitForValue(args->at(i), kStack); |
| 1367 } | 1364 } |
| 1368 | 1365 |
| 1369 if (expr->is_jsruntime()) { | 1366 if (expr->is_jsruntime()) { |
| 1370 // Call the JS runtime function. | 1367 // Call the JS runtime function using a call IC. |
| 1371 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, | 1368 __ Move(rcx, expr->name()); |
| 1372 NOT_IN_LOOP); | 1369 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; |
| 1370 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, in_loop); |
| 1373 __ call(ic, RelocInfo::CODE_TARGET); | 1371 __ call(ic, RelocInfo::CODE_TARGET); |
| 1374 // Restore context register. | 1372 // Restore context register. |
| 1375 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 1373 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
| 1376 // Discard the function left on TOS. | |
| 1377 DropAndApply(1, context_, rax); | |
| 1378 } else { | 1374 } else { |
| 1379 __ CallRuntime(expr->function(), arg_count); | 1375 __ CallRuntime(expr->function(), arg_count); |
| 1380 Apply(context_, rax); | |
| 1381 } | 1376 } |
| 1377 Apply(context_, rax); |
| 1382 } | 1378 } |
| 1383 | 1379 |
| 1384 | 1380 |
| 1385 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { | 1381 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { |
| 1386 switch (expr->op()) { | 1382 switch (expr->op()) { |
| 1387 case Token::VOID: { | 1383 case Token::VOID: { |
| 1388 Comment cmnt(masm_, "[ UnaryOperation (VOID)"); | 1384 Comment cmnt(masm_, "[ UnaryOperation (VOID)"); |
| 1389 VisitForEffect(expr->expression()); | 1385 VisitForEffect(expr->expression()); |
| 1390 switch (context_) { | 1386 switch (context_) { |
| 1391 case Expression::kUninitialized: | 1387 case Expression::kUninitialized: |
| (...skipping 508 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1900 __ movq(Operand(rsp, 0), rdx); | 1896 __ movq(Operand(rsp, 0), rdx); |
| 1901 // And return. | 1897 // And return. |
| 1902 __ ret(0); | 1898 __ ret(0); |
| 1903 } | 1899 } |
| 1904 | 1900 |
| 1905 | 1901 |
| 1906 #undef __ | 1902 #undef __ |
| 1907 | 1903 |
| 1908 | 1904 |
| 1909 } } // namespace v8::internal | 1905 } } // namespace v8::internal |
| OLD | NEW |