OLD | NEW |
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 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 1358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1369 // of the key to detect a named property. | 1369 // of the key to detect a named property. |
1370 if (prop != NULL) { | 1370 if (prop != NULL) { |
1371 assign_type = | 1371 assign_type = |
1372 (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY; | 1372 (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY; |
1373 } | 1373 } |
1374 | 1374 |
1375 // Evaluate expression and get value. | 1375 // Evaluate expression and get value. |
1376 if (assign_type == VARIABLE) { | 1376 if (assign_type == VARIABLE) { |
1377 ASSERT(expr->expression()->AsVariableProxy()->var() != NULL); | 1377 ASSERT(expr->expression()->AsVariableProxy()->var() != NULL); |
1378 Location saved_location = location_; | 1378 Location saved_location = location_; |
1379 location_ = kStack; | 1379 location_ = kAccumulator; |
1380 EmitVariableLoad(expr->expression()->AsVariableProxy()->var(), | 1380 EmitVariableLoad(expr->expression()->AsVariableProxy()->var(), |
1381 Expression::kValue); | 1381 Expression::kValue); |
1382 location_ = saved_location; | 1382 location_ = saved_location; |
1383 } else { | 1383 } else { |
1384 // Reserve space for result of postfix operation. | 1384 // Reserve space for result of postfix operation. |
1385 if (expr->is_postfix() && context_ != Expression::kEffect) { | 1385 if (expr->is_postfix() && context_ != Expression::kEffect) { |
1386 __ mov(ip, Operand(Smi::FromInt(0))); | 1386 __ mov(ip, Operand(Smi::FromInt(0))); |
1387 __ push(ip); | 1387 __ push(ip); |
1388 } | 1388 } |
1389 VisitForValue(prop->obj(), kStack); | 1389 VisitForValue(prop->obj(), kStack); |
1390 if (assign_type == NAMED_PROPERTY) { | 1390 if (assign_type == NAMED_PROPERTY) { |
1391 EmitNamedPropertyLoad(prop); | 1391 EmitNamedPropertyLoad(prop); |
1392 } else { | 1392 } else { |
1393 VisitForValue(prop->key(), kStack); | 1393 VisitForValue(prop->key(), kStack); |
1394 EmitKeyedPropertyLoad(prop); | 1394 EmitKeyedPropertyLoad(prop); |
1395 } | 1395 } |
1396 __ push(r0); | |
1397 } | 1396 } |
1398 | 1397 |
1399 // Convert to number. | 1398 // Call ToNumber only if operand is not a smi. |
| 1399 Label no_conversion; |
| 1400 __ tst(r0, Operand(kSmiTagMask)); |
| 1401 __ b(eq, &no_conversion); |
| 1402 __ push(r0); |
1400 __ InvokeBuiltin(Builtins::TO_NUMBER, CALL_JS); | 1403 __ InvokeBuiltin(Builtins::TO_NUMBER, CALL_JS); |
| 1404 __ bind(&no_conversion); |
1401 | 1405 |
1402 // Save result for postfix expressions. | 1406 // Save result for postfix expressions. |
1403 if (expr->is_postfix()) { | 1407 if (expr->is_postfix()) { |
1404 switch (context_) { | 1408 switch (context_) { |
1405 case Expression::kUninitialized: | 1409 case Expression::kUninitialized: |
1406 UNREACHABLE(); | 1410 UNREACHABLE(); |
1407 case Expression::kEffect: | 1411 case Expression::kEffect: |
1408 // Do not save result. | 1412 // Do not save result. |
1409 break; | 1413 break; |
1410 case Expression::kValue: | 1414 case Expression::kValue: |
(...skipping 11 matching lines...) Expand all Loading... |
1422 __ str(r0, MemOperand(sp, kPointerSize)); | 1426 __ str(r0, MemOperand(sp, kPointerSize)); |
1423 break; | 1427 break; |
1424 case KEYED_PROPERTY: | 1428 case KEYED_PROPERTY: |
1425 __ str(r0, MemOperand(sp, 2 * kPointerSize)); | 1429 __ str(r0, MemOperand(sp, 2 * kPointerSize)); |
1426 break; | 1430 break; |
1427 } | 1431 } |
1428 break; | 1432 break; |
1429 } | 1433 } |
1430 } | 1434 } |
1431 | 1435 |
1432 // Call stub for +1/-1. | 1436 |
| 1437 // Inline smi case if we are in a loop. |
| 1438 Label stub_call, done; |
| 1439 if (loop_depth() > 0) { |
| 1440 __ add(r0, r0, Operand(expr->op() == Token::INC |
| 1441 ? Smi::FromInt(1) |
| 1442 : Smi::FromInt(-1))); |
| 1443 __ b(vs, &stub_call); |
| 1444 // We could eliminate this smi check if we split the code at |
| 1445 // the first smi check before calling ToNumber. |
| 1446 __ tst(r0, Operand(kSmiTagMask)); |
| 1447 __ b(eq, &done); |
| 1448 __ bind(&stub_call); |
| 1449 // Call stub. Undo operation first. |
| 1450 __ sub(r0, r0, Operand(r1)); |
| 1451 } |
1433 __ mov(r1, Operand(expr->op() == Token::INC | 1452 __ mov(r1, Operand(expr->op() == Token::INC |
1434 ? Smi::FromInt(1) | 1453 ? Smi::FromInt(1) |
1435 : Smi::FromInt(-1))); | 1454 : Smi::FromInt(-1))); |
1436 GenericBinaryOpStub stub(Token::ADD, NO_OVERWRITE); | 1455 GenericBinaryOpStub stub(Token::ADD, NO_OVERWRITE); |
1437 __ CallStub(&stub); | 1456 __ CallStub(&stub); |
| 1457 __ bind(&done); |
1438 | 1458 |
1439 // Store the value returned in r0. | 1459 // Store the value returned in r0. |
1440 switch (assign_type) { | 1460 switch (assign_type) { |
1441 case VARIABLE: | 1461 case VARIABLE: |
1442 if (expr->is_postfix()) { | 1462 if (expr->is_postfix()) { |
1443 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 1463 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
1444 Expression::kEffect); | 1464 Expression::kEffect); |
1445 // For all contexts except kEffect: We have the result on | 1465 // For all contexts except kEffect: We have the result on |
1446 // top of the stack. | 1466 // top of the stack. |
1447 if (context_ != Expression::kEffect) { | 1467 if (context_ != Expression::kEffect) { |
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1680 __ pop(result_register()); | 1700 __ pop(result_register()); |
1681 ASSERT_EQ(1, kSmiTagSize + kSmiShiftSize); | 1701 ASSERT_EQ(1, kSmiTagSize + kSmiShiftSize); |
1682 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. | 1702 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. |
1683 __ add(pc, r1, Operand(masm_->CodeObject())); | 1703 __ add(pc, r1, Operand(masm_->CodeObject())); |
1684 } | 1704 } |
1685 | 1705 |
1686 | 1706 |
1687 #undef __ | 1707 #undef __ |
1688 | 1708 |
1689 } } // namespace v8::internal | 1709 } } // namespace v8::internal |
OLD | NEW |