OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/full-codegen/full-codegen.h" | 5 #include "src/full-codegen/full-codegen.h" |
6 | 6 |
7 #include "src/ast/ast.h" | 7 #include "src/ast/ast.h" |
8 #include "src/ast/ast-numbering.h" | 8 #include "src/ast/ast-numbering.h" |
9 #include "src/ast/prettyprinter.h" | 9 #include "src/ast/prettyprinter.h" |
10 #include "src/ast/scopeinfo.h" | 10 #include "src/ast/scopeinfo.h" |
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
270 void FullCodeGenerator::EffectContext::Plug(Register reg) const { | 270 void FullCodeGenerator::EffectContext::Plug(Register reg) const { |
271 } | 271 } |
272 | 272 |
273 | 273 |
274 void FullCodeGenerator::AccumulatorValueContext::Plug(Register reg) const { | 274 void FullCodeGenerator::AccumulatorValueContext::Plug(Register reg) const { |
275 __ Move(result_register(), reg); | 275 __ Move(result_register(), reg); |
276 } | 276 } |
277 | 277 |
278 | 278 |
279 void FullCodeGenerator::StackValueContext::Plug(Register reg) const { | 279 void FullCodeGenerator::StackValueContext::Plug(Register reg) const { |
280 codegen()->OperandStackDepthIncrement(1); | |
Jarin
2016/02/19 06:52:04
Could not you call codegen()->PushOperand here?
(
Michael Starzinger
2016/02/19 09:24:04
Done. Here and below.
| |
280 __ Push(reg); | 281 __ Push(reg); |
281 } | 282 } |
282 | 283 |
283 | 284 |
284 void FullCodeGenerator::TestContext::Plug(Register reg) const { | 285 void FullCodeGenerator::TestContext::Plug(Register reg) const { |
285 // For simplicity we always test the accumulator register. | 286 // For simplicity we always test the accumulator register. |
286 __ Move(result_register(), reg); | 287 __ Move(result_register(), reg); |
287 codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL); | 288 codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL); |
288 codegen()->DoTest(this); | 289 codegen()->DoTest(this); |
289 } | 290 } |
290 | 291 |
291 | 292 |
292 void FullCodeGenerator::EffectContext::Plug(bool flag) const {} | 293 void FullCodeGenerator::EffectContext::Plug(bool flag) const {} |
293 | 294 |
294 | 295 |
295 void FullCodeGenerator::EffectContext::PlugTOS() const { | 296 void FullCodeGenerator::EffectContext::PlugTOS() const { |
297 codegen()->OperandStackDepthDecrement(1); | |
296 __ Drop(1); | 298 __ Drop(1); |
297 } | 299 } |
298 | 300 |
299 | 301 |
300 void FullCodeGenerator::AccumulatorValueContext::PlugTOS() const { | 302 void FullCodeGenerator::AccumulatorValueContext::PlugTOS() const { |
303 codegen()->OperandStackDepthDecrement(1); | |
301 __ Pop(result_register()); | 304 __ Pop(result_register()); |
302 } | 305 } |
303 | 306 |
304 | 307 |
305 void FullCodeGenerator::StackValueContext::PlugTOS() const { | 308 void FullCodeGenerator::StackValueContext::PlugTOS() const { |
306 } | 309 } |
307 | 310 |
308 | 311 |
309 void FullCodeGenerator::TestContext::PlugTOS() const { | 312 void FullCodeGenerator::TestContext::PlugTOS() const { |
313 codegen()->OperandStackDepthDecrement(1); | |
310 // For simplicity we always test the accumulator register. | 314 // For simplicity we always test the accumulator register. |
311 __ Pop(result_register()); | 315 __ Pop(result_register()); |
312 codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL); | 316 codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL); |
313 codegen()->DoTest(this); | 317 codegen()->DoTest(this); |
314 } | 318 } |
315 | 319 |
316 | 320 |
317 void FullCodeGenerator::EffectContext::PrepareTest( | 321 void FullCodeGenerator::EffectContext::PrepareTest( |
318 Label* materialize_true, | 322 Label* materialize_true, |
319 Label* materialize_false, | 323 Label* materialize_false, |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
431 } | 435 } |
432 | 436 |
433 | 437 |
434 int FullCodeGenerator::DeclareGlobalsFlags() { | 438 int FullCodeGenerator::DeclareGlobalsFlags() { |
435 DCHECK(DeclareGlobalsLanguageMode::is_valid(language_mode())); | 439 DCHECK(DeclareGlobalsLanguageMode::is_valid(language_mode())); |
436 return DeclareGlobalsEvalFlag::encode(is_eval()) | | 440 return DeclareGlobalsEvalFlag::encode(is_eval()) | |
437 DeclareGlobalsNativeFlag::encode(is_native()) | | 441 DeclareGlobalsNativeFlag::encode(is_native()) | |
438 DeclareGlobalsLanguageMode::encode(language_mode()); | 442 DeclareGlobalsLanguageMode::encode(language_mode()); |
439 } | 443 } |
440 | 444 |
445 void FullCodeGenerator::PushOperand(MemOperand operand) { | |
446 OperandStackDepthIncrement(1); | |
447 __ Push(operand); | |
448 } | |
449 | |
450 void FullCodeGenerator::PushOperand(Handle<Object> handle) { | |
451 OperandStackDepthIncrement(1); | |
452 __ Push(handle); | |
453 } | |
454 | |
455 void FullCodeGenerator::PushOperand(Smi* smi) { | |
456 OperandStackDepthIncrement(1); | |
457 __ Push(smi); | |
458 } | |
459 | |
460 void FullCodeGenerator::PushOperand(Register reg) { | |
461 OperandStackDepthIncrement(1); | |
462 __ Push(reg); | |
463 } | |
464 | |
465 void FullCodeGenerator::PopOperand(Register reg) { | |
466 OperandStackDepthDecrement(1); | |
467 __ Pop(reg); | |
468 } | |
469 | |
470 void FullCodeGenerator::DropOperands(int count) { | |
471 OperandStackDepthDecrement(count); | |
472 __ Drop(count); | |
473 } | |
474 | |
475 void FullCodeGenerator::CallRuntimeWithOperands(Runtime::FunctionId id) { | |
476 OperandStackDepthDecrement(Runtime::FunctionForId(id)->nargs); | |
477 __ CallRuntime(id); | |
478 } | |
479 | |
480 void FullCodeGenerator::OperandStackDepthIncrement(int count) { | |
481 DCHECK_GE(operand_stack_depth_, 0); | |
482 operand_stack_depth_ += count; | |
483 } | |
484 | |
485 void FullCodeGenerator::OperandStackDepthDecrement(int count) { | |
486 DCHECK_GE(operand_stack_depth_, count); | |
487 operand_stack_depth_ -= count; | |
488 } | |
441 | 489 |
442 void FullCodeGenerator::EmitSubString(CallRuntime* expr) { | 490 void FullCodeGenerator::EmitSubString(CallRuntime* expr) { |
443 // Load the arguments on the stack and call the stub. | 491 // Load the arguments on the stack and call the stub. |
444 SubStringStub stub(isolate()); | 492 SubStringStub stub(isolate()); |
445 ZoneList<Expression*>* args = expr->arguments(); | 493 ZoneList<Expression*>* args = expr->arguments(); |
446 DCHECK(args->length() == 3); | 494 DCHECK(args->length() == 3); |
447 VisitForStackValue(args->at(0)); | 495 VisitForStackValue(args->at(0)); |
448 VisitForStackValue(args->at(1)); | 496 VisitForStackValue(args->at(1)); |
449 VisitForStackValue(args->at(2)); | 497 VisitForStackValue(args->at(2)); |
450 __ CallStub(&stub); | 498 __ CallStub(&stub); |
499 OperandStackDepthDecrement(3); | |
451 context()->Plug(result_register()); | 500 context()->Plug(result_register()); |
452 } | 501 } |
453 | 502 |
454 | 503 |
455 void FullCodeGenerator::EmitRegExpExec(CallRuntime* expr) { | 504 void FullCodeGenerator::EmitRegExpExec(CallRuntime* expr) { |
456 // Load the arguments on the stack and call the stub. | 505 // Load the arguments on the stack and call the stub. |
457 RegExpExecStub stub(isolate()); | 506 RegExpExecStub stub(isolate()); |
458 ZoneList<Expression*>* args = expr->arguments(); | 507 ZoneList<Expression*>* args = expr->arguments(); |
459 DCHECK(args->length() == 4); | 508 DCHECK(args->length() == 4); |
460 VisitForStackValue(args->at(0)); | 509 VisitForStackValue(args->at(0)); |
461 VisitForStackValue(args->at(1)); | 510 VisitForStackValue(args->at(1)); |
462 VisitForStackValue(args->at(2)); | 511 VisitForStackValue(args->at(2)); |
463 VisitForStackValue(args->at(3)); | 512 VisitForStackValue(args->at(3)); |
464 __ CallStub(&stub); | 513 __ CallStub(&stub); |
514 OperandStackDepthDecrement(4); | |
465 context()->Plug(result_register()); | 515 context()->Plug(result_register()); |
466 } | 516 } |
467 | 517 |
468 | 518 |
469 void FullCodeGenerator::EmitMathPow(CallRuntime* expr) { | 519 void FullCodeGenerator::EmitMathPow(CallRuntime* expr) { |
470 // Load the arguments on the stack and call the runtime function. | 520 // Load the arguments on the stack and call the runtime function. |
521 MathPowStub stub(isolate(), MathPowStub::ON_STACK); | |
471 ZoneList<Expression*>* args = expr->arguments(); | 522 ZoneList<Expression*>* args = expr->arguments(); |
472 DCHECK(args->length() == 2); | 523 DCHECK(args->length() == 2); |
473 VisitForStackValue(args->at(0)); | 524 VisitForStackValue(args->at(0)); |
474 VisitForStackValue(args->at(1)); | 525 VisitForStackValue(args->at(1)); |
475 | |
476 MathPowStub stub(isolate(), MathPowStub::ON_STACK); | |
477 __ CallStub(&stub); | 526 __ CallStub(&stub); |
527 OperandStackDepthDecrement(2); | |
478 context()->Plug(result_register()); | 528 context()->Plug(result_register()); |
479 } | 529 } |
480 | 530 |
481 | 531 |
482 void FullCodeGenerator::EmitIntrinsicAsStubCall(CallRuntime* expr, | 532 void FullCodeGenerator::EmitIntrinsicAsStubCall(CallRuntime* expr, |
483 const Callable& callable) { | 533 const Callable& callable) { |
484 ZoneList<Expression*>* args = expr->arguments(); | 534 ZoneList<Expression*>* args = expr->arguments(); |
485 int param_count = callable.descriptor().GetRegisterParameterCount(); | 535 int param_count = callable.descriptor().GetRegisterParameterCount(); |
486 DCHECK_EQ(args->length(), param_count); | 536 DCHECK_EQ(args->length(), param_count); |
487 | 537 |
488 if (param_count > 0) { | 538 if (param_count > 0) { |
489 int last = param_count - 1; | 539 int last = param_count - 1; |
490 // Put all but last arguments on stack. | 540 // Put all but last arguments on stack. |
491 for (int i = 0; i < last; i++) { | 541 for (int i = 0; i < last; i++) { |
492 VisitForStackValue(args->at(i)); | 542 VisitForStackValue(args->at(i)); |
493 } | 543 } |
494 // The last argument goes to the accumulator. | 544 // The last argument goes to the accumulator. |
495 VisitForAccumulatorValue(args->at(last)); | 545 VisitForAccumulatorValue(args->at(last)); |
496 | 546 |
497 // Move the arguments to the registers, as required by the stub. | 547 // Move the arguments to the registers, as required by the stub. |
498 __ Move(callable.descriptor().GetRegisterParameter(last), | 548 __ Move(callable.descriptor().GetRegisterParameter(last), |
499 result_register()); | 549 result_register()); |
500 for (int i = last; i-- > 0;) { | 550 for (int i = last; i-- > 0;) { |
501 __ Pop(callable.descriptor().GetRegisterParameter(i)); | 551 PopOperand(callable.descriptor().GetRegisterParameter(i)); |
502 } | 552 } |
503 } | 553 } |
504 __ Call(callable.code(), RelocInfo::CODE_TARGET); | 554 __ Call(callable.code(), RelocInfo::CODE_TARGET); |
505 context()->Plug(result_register()); | 555 context()->Plug(result_register()); |
506 } | 556 } |
507 | 557 |
508 | 558 |
509 void FullCodeGenerator::EmitNumberToString(CallRuntime* expr) { | 559 void FullCodeGenerator::EmitNumberToString(CallRuntime* expr) { |
510 EmitIntrinsicAsStubCall(expr, CodeFactory::NumberToString(isolate())); | 560 EmitIntrinsicAsStubCall(expr, CodeFactory::NumberToString(isolate())); |
511 } | 561 } |
(...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
945 current = current->Exit(&stack_depth, &context_length); | 995 current = current->Exit(&stack_depth, &context_length); |
946 } | 996 } |
947 __ Drop(stack_depth); | 997 __ Drop(stack_depth); |
948 EmitReturnSequence(); | 998 EmitReturnSequence(); |
949 } | 999 } |
950 | 1000 |
951 | 1001 |
952 void FullCodeGenerator::EmitPropertyKey(ObjectLiteralProperty* property, | 1002 void FullCodeGenerator::EmitPropertyKey(ObjectLiteralProperty* property, |
953 BailoutId bailout_id) { | 1003 BailoutId bailout_id) { |
954 VisitForStackValue(property->key()); | 1004 VisitForStackValue(property->key()); |
955 __ CallRuntime(Runtime::kToName); | 1005 CallRuntimeWithOperands(Runtime::kToName); |
956 PrepareForBailoutForId(bailout_id, NO_REGISTERS); | 1006 PrepareForBailoutForId(bailout_id, NO_REGISTERS); |
957 __ Push(result_register()); | 1007 PushOperand(result_register()); |
958 } | 1008 } |
959 | 1009 |
960 | 1010 |
961 void FullCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { | 1011 void FullCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { |
962 Comment cmnt(masm_, "[ ReturnStatement"); | 1012 Comment cmnt(masm_, "[ ReturnStatement"); |
963 SetStatementPosition(stmt); | 1013 SetStatementPosition(stmt); |
964 Expression* expr = stmt->expression(); | 1014 Expression* expr = stmt->expression(); |
965 VisitForAccumulatorValue(expr); | 1015 VisitForAccumulatorValue(expr); |
966 EmitUnwindAndReturn(); | 1016 EmitUnwindAndReturn(); |
967 } | 1017 } |
968 | 1018 |
969 | 1019 |
970 void FullCodeGenerator::VisitWithStatement(WithStatement* stmt) { | 1020 void FullCodeGenerator::VisitWithStatement(WithStatement* stmt) { |
971 Comment cmnt(masm_, "[ WithStatement"); | 1021 Comment cmnt(masm_, "[ WithStatement"); |
972 SetStatementPosition(stmt); | 1022 SetStatementPosition(stmt); |
973 | 1023 |
974 VisitForAccumulatorValue(stmt->expression()); | 1024 VisitForAccumulatorValue(stmt->expression()); |
975 Callable callable = CodeFactory::ToObject(isolate()); | 1025 Callable callable = CodeFactory::ToObject(isolate()); |
976 __ Move(callable.descriptor().GetRegisterParameter(0), result_register()); | 1026 __ Move(callable.descriptor().GetRegisterParameter(0), result_register()); |
977 __ Call(callable.code(), RelocInfo::CODE_TARGET); | 1027 __ Call(callable.code(), RelocInfo::CODE_TARGET); |
978 PrepareForBailoutForId(stmt->ToObjectId(), NO_REGISTERS); | 1028 PrepareForBailoutForId(stmt->ToObjectId(), NO_REGISTERS); |
979 __ Push(result_register()); | 1029 PushOperand(result_register()); |
980 PushFunctionArgumentForContextAllocation(); | 1030 PushFunctionArgumentForContextAllocation(); |
981 __ CallRuntime(Runtime::kPushWithContext); | 1031 CallRuntimeWithOperands(Runtime::kPushWithContext); |
982 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); | 1032 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); |
983 PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); | 1033 PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); |
984 | 1034 |
985 Scope* saved_scope = scope(); | 1035 Scope* saved_scope = scope(); |
986 scope_ = stmt->scope(); | 1036 scope_ = stmt->scope(); |
987 { WithOrCatch body(this); | 1037 { WithOrCatch body(this); |
988 Visit(stmt->statement()); | 1038 Visit(stmt->statement()); |
989 } | 1039 } |
990 scope_ = saved_scope; | 1040 scope_ = saved_scope; |
991 | 1041 |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1164 // result register. | 1214 // result register. |
1165 | 1215 |
1166 Label try_entry, handler_entry, exit; | 1216 Label try_entry, handler_entry, exit; |
1167 __ jmp(&try_entry); | 1217 __ jmp(&try_entry); |
1168 __ bind(&handler_entry); | 1218 __ bind(&handler_entry); |
1169 ClearPendingMessage(); | 1219 ClearPendingMessage(); |
1170 | 1220 |
1171 // Exception handler code, the exception is in the result register. | 1221 // Exception handler code, the exception is in the result register. |
1172 // Extend the context before executing the catch block. | 1222 // Extend the context before executing the catch block. |
1173 { Comment cmnt(masm_, "[ Extend catch context"); | 1223 { Comment cmnt(masm_, "[ Extend catch context"); |
1174 __ Push(stmt->variable()->name()); | 1224 PushOperand(stmt->variable()->name()); |
1175 __ Push(result_register()); | 1225 PushOperand(result_register()); |
1176 PushFunctionArgumentForContextAllocation(); | 1226 PushFunctionArgumentForContextAllocation(); |
1177 __ CallRuntime(Runtime::kPushCatchContext); | 1227 CallRuntimeWithOperands(Runtime::kPushCatchContext); |
1178 StoreToFrameField(StandardFrameConstants::kContextOffset, | 1228 StoreToFrameField(StandardFrameConstants::kContextOffset, |
1179 context_register()); | 1229 context_register()); |
1180 } | 1230 } |
1181 | 1231 |
1182 Scope* saved_scope = scope(); | 1232 Scope* saved_scope = scope(); |
1183 scope_ = stmt->scope(); | 1233 scope_ = stmt->scope(); |
1184 DCHECK(scope_->declarations()->is_empty()); | 1234 DCHECK(scope_->declarations()->is_empty()); |
1185 { WithOrCatch catch_body(this); | 1235 { WithOrCatch catch_body(this); |
1186 Visit(stmt->catch_block()); | 1236 Visit(stmt->catch_block()); |
1187 } | 1237 } |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1255 // value in the result register with one that's safe for GC because the | 1305 // value in the result register with one that's safe for GC because the |
1256 // finally block will unconditionally preserve the result register on the | 1306 // finally block will unconditionally preserve the result register on the |
1257 // stack. | 1307 // stack. |
1258 ClearAccumulator(); | 1308 ClearAccumulator(); |
1259 deferred.EmitFallThrough(); | 1309 deferred.EmitFallThrough(); |
1260 // Fall through to the finally block. | 1310 // Fall through to the finally block. |
1261 | 1311 |
1262 // Finally block implementation. | 1312 // Finally block implementation. |
1263 __ bind(&finally_entry); | 1313 __ bind(&finally_entry); |
1264 Comment cmnt_finally(masm(), "[ Finally block"); | 1314 Comment cmnt_finally(masm(), "[ Finally block"); |
1315 OperandStackDepthIncrement(2); // Token and accumulator are on stack. | |
1265 EnterFinallyBlock(); | 1316 EnterFinallyBlock(); |
1266 { | 1317 { |
1267 Finally finally_body(this); | 1318 Finally finally_body(this); |
1268 Visit(stmt->finally_block()); | 1319 Visit(stmt->finally_block()); |
1269 } | 1320 } |
1270 ExitFinallyBlock(); // Return to the calling code. | 1321 ExitFinallyBlock(); |
1322 OperandStackDepthDecrement(2); // Token and accumulator are on stack. | |
Jarin
2016/02/19 06:52:04
Nit: are -> were
Michael Starzinger
2016/02/19 09:24:04
Done.
| |
1271 | 1323 |
1272 { | 1324 { |
1273 Comment cmnt_deferred(masm(), "[ Post-finally dispatch"); | 1325 Comment cmnt_deferred(masm(), "[ Post-finally dispatch"); |
1274 deferred.EmitCommands(); | 1326 deferred.EmitCommands(); // Return to the calling code. |
1275 } | 1327 } |
1276 } | 1328 } |
1277 | 1329 |
1278 | 1330 |
1279 void FullCodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) { | 1331 void FullCodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) { |
1280 Comment cmnt(masm_, "[ DebuggerStatement"); | 1332 Comment cmnt(masm_, "[ DebuggerStatement"); |
1281 SetStatementPosition(stmt); | 1333 SetStatementPosition(stmt); |
1282 | 1334 |
1283 __ DebugBreak(); | 1335 __ DebugBreak(); |
1284 // Ignore the return value. | 1336 // Ignore the return value. |
1285 | 1337 |
1286 PrepareForBailoutForId(stmt->DebugBreakId(), NO_REGISTERS); | 1338 PrepareForBailoutForId(stmt->DebugBreakId(), NO_REGISTERS); |
1287 } | 1339 } |
1288 | 1340 |
1289 | 1341 |
1290 void FullCodeGenerator::VisitCaseClause(CaseClause* clause) { | 1342 void FullCodeGenerator::VisitCaseClause(CaseClause* clause) { |
1291 UNREACHABLE(); | 1343 UNREACHABLE(); |
1292 } | 1344 } |
1293 | 1345 |
1294 | 1346 |
1295 void FullCodeGenerator::VisitConditional(Conditional* expr) { | 1347 void FullCodeGenerator::VisitConditional(Conditional* expr) { |
1296 Comment cmnt(masm_, "[ Conditional"); | 1348 Comment cmnt(masm_, "[ Conditional"); |
1297 Label true_case, false_case, done; | 1349 Label true_case, false_case, done; |
1298 VisitForControl(expr->condition(), &true_case, &false_case, &true_case); | 1350 VisitForControl(expr->condition(), &true_case, &false_case, &true_case); |
1299 | 1351 |
1352 int original_stack_depth = operand_stack_depth_; | |
1300 PrepareForBailoutForId(expr->ThenId(), NO_REGISTERS); | 1353 PrepareForBailoutForId(expr->ThenId(), NO_REGISTERS); |
1301 __ bind(&true_case); | 1354 __ bind(&true_case); |
1302 SetExpressionPosition(expr->then_expression()); | 1355 SetExpressionPosition(expr->then_expression()); |
1303 if (context()->IsTest()) { | 1356 if (context()->IsTest()) { |
1304 const TestContext* for_test = TestContext::cast(context()); | 1357 const TestContext* for_test = TestContext::cast(context()); |
1305 VisitForControl(expr->then_expression(), | 1358 VisitForControl(expr->then_expression(), |
1306 for_test->true_label(), | 1359 for_test->true_label(), |
1307 for_test->false_label(), | 1360 for_test->false_label(), |
1308 NULL); | 1361 NULL); |
1309 } else { | 1362 } else { |
1310 VisitInDuplicateContext(expr->then_expression()); | 1363 VisitInDuplicateContext(expr->then_expression()); |
1311 __ jmp(&done); | 1364 __ jmp(&done); |
1312 } | 1365 } |
1313 | 1366 |
1367 operand_stack_depth_ = original_stack_depth; | |
1314 PrepareForBailoutForId(expr->ElseId(), NO_REGISTERS); | 1368 PrepareForBailoutForId(expr->ElseId(), NO_REGISTERS); |
1315 __ bind(&false_case); | 1369 __ bind(&false_case); |
1316 SetExpressionPosition(expr->else_expression()); | 1370 SetExpressionPosition(expr->else_expression()); |
1317 VisitInDuplicateContext(expr->else_expression()); | 1371 VisitInDuplicateContext(expr->else_expression()); |
1318 // If control flow falls through Visit, merge it with true case here. | 1372 // If control flow falls through Visit, merge it with true case here. |
1319 if (!context()->IsTest()) { | 1373 if (!context()->IsTest()) { |
1320 __ bind(&done); | 1374 __ bind(&done); |
1321 } | 1375 } |
1322 } | 1376 } |
1323 | 1377 |
(...skipping 21 matching lines...) Expand all Loading... | |
1345 void FullCodeGenerator::VisitClassLiteral(ClassLiteral* lit) { | 1399 void FullCodeGenerator::VisitClassLiteral(ClassLiteral* lit) { |
1346 Comment cmnt(masm_, "[ ClassLiteral"); | 1400 Comment cmnt(masm_, "[ ClassLiteral"); |
1347 | 1401 |
1348 { | 1402 { |
1349 EnterBlockScopeIfNeeded block_scope_state( | 1403 EnterBlockScopeIfNeeded block_scope_state( |
1350 this, lit->scope(), lit->EntryId(), lit->DeclsId(), lit->ExitId()); | 1404 this, lit->scope(), lit->EntryId(), lit->DeclsId(), lit->ExitId()); |
1351 | 1405 |
1352 if (lit->extends() != NULL) { | 1406 if (lit->extends() != NULL) { |
1353 VisitForStackValue(lit->extends()); | 1407 VisitForStackValue(lit->extends()); |
1354 } else { | 1408 } else { |
1355 __ Push(isolate()->factory()->the_hole_value()); | 1409 PushOperand(isolate()->factory()->the_hole_value()); |
1356 } | 1410 } |
1357 | 1411 |
1358 VisitForStackValue(lit->constructor()); | 1412 VisitForStackValue(lit->constructor()); |
1359 | 1413 |
1360 __ Push(Smi::FromInt(lit->start_position())); | 1414 PushOperand(Smi::FromInt(lit->start_position())); |
1361 __ Push(Smi::FromInt(lit->end_position())); | 1415 PushOperand(Smi::FromInt(lit->end_position())); |
1362 | 1416 |
1363 __ CallRuntime(Runtime::kDefineClass); | 1417 CallRuntimeWithOperands(Runtime::kDefineClass); |
1364 PrepareForBailoutForId(lit->CreateLiteralId(), TOS_REG); | 1418 PrepareForBailoutForId(lit->CreateLiteralId(), TOS_REG); |
1365 __ Push(result_register()); | 1419 PushOperand(result_register()); |
1366 | 1420 |
1367 // Load the "prototype" from the constructor. | 1421 // Load the "prototype" from the constructor. |
1368 __ Move(LoadDescriptor::ReceiverRegister(), result_register()); | 1422 __ Move(LoadDescriptor::ReceiverRegister(), result_register()); |
1369 __ LoadRoot(LoadDescriptor::NameRegister(), | 1423 __ LoadRoot(LoadDescriptor::NameRegister(), |
1370 Heap::kprototype_stringRootIndex); | 1424 Heap::kprototype_stringRootIndex); |
1371 __ Move(LoadDescriptor::SlotRegister(), SmiFromSlot(lit->PrototypeSlot())); | 1425 __ Move(LoadDescriptor::SlotRegister(), SmiFromSlot(lit->PrototypeSlot())); |
1372 CallLoadIC(NOT_INSIDE_TYPEOF); | 1426 CallLoadIC(NOT_INSIDE_TYPEOF); |
1373 PrepareForBailoutForId(lit->PrototypeId(), TOS_REG); | 1427 PrepareForBailoutForId(lit->PrototypeId(), TOS_REG); |
1374 __ Push(result_register()); | 1428 PushOperand(result_register()); |
1375 | 1429 |
1376 EmitClassDefineProperties(lit); | 1430 EmitClassDefineProperties(lit); |
1377 | 1431 |
1378 // Set both the prototype and constructor to have fast properties, and also | 1432 // Set both the prototype and constructor to have fast properties, and also |
1379 // freeze them in strong mode. | 1433 // freeze them in strong mode. |
1380 __ CallRuntime(Runtime::kFinalizeClassDefinition); | 1434 CallRuntimeWithOperands(Runtime::kFinalizeClassDefinition); |
1381 | 1435 |
1382 if (lit->class_variable_proxy() != nullptr) { | 1436 if (lit->class_variable_proxy() != nullptr) { |
1383 EmitVariableAssignment(lit->class_variable_proxy()->var(), Token::INIT, | 1437 EmitVariableAssignment(lit->class_variable_proxy()->var(), Token::INIT, |
1384 lit->ProxySlot()); | 1438 lit->ProxySlot()); |
1385 } | 1439 } |
1386 } | 1440 } |
1387 | 1441 |
1388 context()->Plug(result_register()); | 1442 context()->Plug(result_register()); |
1389 } | 1443 } |
1390 | 1444 |
1391 | 1445 |
1392 void FullCodeGenerator::VisitNativeFunctionLiteral( | 1446 void FullCodeGenerator::VisitNativeFunctionLiteral( |
1393 NativeFunctionLiteral* expr) { | 1447 NativeFunctionLiteral* expr) { |
1394 Comment cmnt(masm_, "[ NativeFunctionLiteral"); | 1448 Comment cmnt(masm_, "[ NativeFunctionLiteral"); |
1395 Handle<SharedFunctionInfo> shared = | 1449 Handle<SharedFunctionInfo> shared = |
1396 Compiler::GetSharedFunctionInfoForNative(expr->extension(), expr->name()); | 1450 Compiler::GetSharedFunctionInfoForNative(expr->extension(), expr->name()); |
1397 EmitNewClosure(shared, false); | 1451 EmitNewClosure(shared, false); |
1398 } | 1452 } |
1399 | 1453 |
1400 | 1454 |
1401 void FullCodeGenerator::VisitThrow(Throw* expr) { | 1455 void FullCodeGenerator::VisitThrow(Throw* expr) { |
1402 Comment cmnt(masm_, "[ Throw"); | 1456 Comment cmnt(masm_, "[ Throw"); |
1403 VisitForStackValue(expr->exception()); | 1457 VisitForStackValue(expr->exception()); |
1404 SetExpressionPosition(expr); | 1458 SetExpressionPosition(expr); |
1405 __ CallRuntime(Runtime::kThrow); | 1459 CallRuntimeWithOperands(Runtime::kThrow); |
1406 // Never returns here. | 1460 // Never returns here. |
1461 | |
1462 // Even though this expression doesn't produce a value, we need to simulate | |
1463 // plugging of the value context to ensure stack depth tracking is in sync. | |
1464 if (context()->IsStackValue()) OperandStackDepthIncrement(1); | |
1407 } | 1465 } |
1408 | 1466 |
1409 | 1467 |
1410 void FullCodeGenerator::EnterTryBlock(int handler_index, Label* handler) { | 1468 void FullCodeGenerator::EnterTryBlock(int handler_index, Label* handler) { |
1411 HandlerTableEntry* entry = &handler_table_[handler_index]; | 1469 HandlerTableEntry* entry = &handler_table_[handler_index]; |
1412 entry->range_start = masm()->pc_offset(); | 1470 entry->range_start = masm()->pc_offset(); |
1413 entry->handler_offset = handler->pos(); | 1471 entry->handler_offset = handler->pos(); |
1414 entry->try_catch_depth = try_catch_depth_; | 1472 entry->try_catch_depth = try_catch_depth_; |
1473 entry->stack_depth = operand_stack_depth_; | |
1415 | 1474 |
1416 // Determine expression stack depth of try statement. | 1475 // We are using the operand stack depth, check for accuracy. |
1417 int stack_depth = info_->scope()->num_stack_slots(); // Include stack locals. | 1476 EmitOperandStackDepthCheck(); |
1418 for (NestedStatement* current = nesting_stack_; current != NULL; /*nop*/) { | |
1419 current = current->AccumulateDepth(&stack_depth); | |
1420 } | |
1421 entry->stack_depth = stack_depth; | |
1422 | 1477 |
1423 // Push context onto operand stack. | 1478 // Push context onto operand stack. |
1424 STATIC_ASSERT(TryBlockConstant::kElementCount == 1); | 1479 STATIC_ASSERT(TryBlockConstant::kElementCount == 1); |
1425 __ Push(context_register()); | 1480 PushOperand(context_register()); |
1426 } | 1481 } |
1427 | 1482 |
1428 | 1483 |
1429 void FullCodeGenerator::ExitTryBlock(int handler_index) { | 1484 void FullCodeGenerator::ExitTryBlock(int handler_index) { |
1430 HandlerTableEntry* entry = &handler_table_[handler_index]; | 1485 HandlerTableEntry* entry = &handler_table_[handler_index]; |
1431 entry->range_end = masm()->pc_offset(); | 1486 entry->range_end = masm()->pc_offset(); |
1432 | 1487 |
1433 // Drop context from operand stack. | 1488 // Drop context from operand stack. |
1434 __ Drop(TryBlockConstant::kElementCount); | 1489 DropOperands(TryBlockConstant::kElementCount); |
1435 } | 1490 } |
1436 | 1491 |
1437 | 1492 |
1438 void FullCodeGenerator::VisitCall(Call* expr) { | 1493 void FullCodeGenerator::VisitCall(Call* expr) { |
1439 #ifdef DEBUG | 1494 #ifdef DEBUG |
1440 // We want to verify that RecordJSReturnSite gets called on all paths | 1495 // We want to verify that RecordJSReturnSite gets called on all paths |
1441 // through this function. Avoid early returns. | 1496 // through this function. Avoid early returns. |
1442 expr->return_is_recorded_ = false; | 1497 expr->return_is_recorded_ = false; |
1443 #endif | 1498 #endif |
1444 | 1499 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1477 break; | 1532 break; |
1478 case Call::KEYED_SUPER_PROPERTY_CALL: | 1533 case Call::KEYED_SUPER_PROPERTY_CALL: |
1479 EmitKeyedSuperCallWithLoadIC(expr); | 1534 EmitKeyedSuperCallWithLoadIC(expr); |
1480 break; | 1535 break; |
1481 case Call::SUPER_CALL: | 1536 case Call::SUPER_CALL: |
1482 EmitSuperConstructorCall(expr); | 1537 EmitSuperConstructorCall(expr); |
1483 break; | 1538 break; |
1484 case Call::OTHER_CALL: | 1539 case Call::OTHER_CALL: |
1485 // Call to an arbitrary expression not handled specially above. | 1540 // Call to an arbitrary expression not handled specially above. |
1486 VisitForStackValue(callee); | 1541 VisitForStackValue(callee); |
1542 OperandStackDepthIncrement(1); | |
1487 __ PushRoot(Heap::kUndefinedValueRootIndex); | 1543 __ PushRoot(Heap::kUndefinedValueRootIndex); |
1488 // Emit function call. | 1544 // Emit function call. |
1489 EmitCall(expr); | 1545 EmitCall(expr); |
1490 break; | 1546 break; |
1491 } | 1547 } |
1492 | 1548 |
1493 #ifdef DEBUG | 1549 #ifdef DEBUG |
1494 // RecordJSReturnSite should have been called. | 1550 // RecordJSReturnSite should have been called. |
1495 DCHECK(expr->return_is_recorded_); | 1551 DCHECK(expr->return_is_recorded_); |
1496 #endif | 1552 #endif |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1693 | 1749 |
1694 if (scope == NULL) { | 1750 if (scope == NULL) { |
1695 codegen_->PrepareForBailoutForId(entry_id, NO_REGISTERS); | 1751 codegen_->PrepareForBailoutForId(entry_id, NO_REGISTERS); |
1696 needs_block_context_ = false; | 1752 needs_block_context_ = false; |
1697 } else { | 1753 } else { |
1698 needs_block_context_ = scope->NeedsContext(); | 1754 needs_block_context_ = scope->NeedsContext(); |
1699 codegen_->scope_ = scope; | 1755 codegen_->scope_ = scope; |
1700 { | 1756 { |
1701 if (needs_block_context_) { | 1757 if (needs_block_context_) { |
1702 Comment cmnt(masm(), "[ Extend block context"); | 1758 Comment cmnt(masm(), "[ Extend block context"); |
1703 __ Push(scope->GetScopeInfo(codegen->isolate())); | 1759 codegen_->PushOperand(scope->GetScopeInfo(codegen->isolate())); |
1704 codegen_->PushFunctionArgumentForContextAllocation(); | 1760 codegen_->PushFunctionArgumentForContextAllocation(); |
1705 __ CallRuntime(Runtime::kPushBlockContext); | 1761 codegen_->CallRuntimeWithOperands(Runtime::kPushBlockContext); |
1706 | 1762 |
1707 // Replace the context stored in the frame. | 1763 // Replace the context stored in the frame. |
1708 codegen_->StoreToFrameField(StandardFrameConstants::kContextOffset, | 1764 codegen_->StoreToFrameField(StandardFrameConstants::kContextOffset, |
1709 codegen_->context_register()); | 1765 codegen_->context_register()); |
1710 } | 1766 } |
1711 CHECK_EQ(0, scope->num_stack_slots()); | 1767 CHECK_EQ(0, scope->num_stack_slots()); |
1712 codegen_->PrepareForBailoutForId(entry_id, NO_REGISTERS); | 1768 codegen_->PrepareForBailoutForId(entry_id, NO_REGISTERS); |
1713 } | 1769 } |
1714 { | 1770 { |
1715 Comment cmnt(masm(), "[ Declarations"); | 1771 Comment cmnt(masm(), "[ Declarations"); |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1790 return var->mode() == CONST_LEGACY || var->scope()->is_nonlinear() || | 1846 return var->mode() == CONST_LEGACY || var->scope()->is_nonlinear() || |
1791 var->initializer_position() >= proxy->position(); | 1847 var->initializer_position() >= proxy->position(); |
1792 } | 1848 } |
1793 | 1849 |
1794 | 1850 |
1795 #undef __ | 1851 #undef __ |
1796 | 1852 |
1797 | 1853 |
1798 } // namespace internal | 1854 } // namespace internal |
1799 } // namespace v8 | 1855 } // namespace v8 |
OLD | NEW |