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 |