Chromium Code Reviews| 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 1477 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1488 // frame. | 1488 // frame. |
| 1489 frame_->PushElementAt(target.size() - 1); | 1489 frame_->PushElementAt(target.size() - 1); |
| 1490 // Result ignored = frame_->CallRuntime(Runtime::kToSlowProperties, 1); | 1490 // Result ignored = frame_->CallRuntime(Runtime::kToSlowProperties, 1); |
| 1491 } | 1491 } |
| 1492 if (node->op() == Token::ASSIGN || | 1492 if (node->op() == Token::ASSIGN || |
| 1493 node->op() == Token::INIT_VAR || | 1493 node->op() == Token::INIT_VAR || |
| 1494 node->op() == Token::INIT_CONST) { | 1494 node->op() == Token::INIT_CONST) { |
| 1495 Load(node->value()); | 1495 Load(node->value()); |
| 1496 | 1496 |
| 1497 } else { | 1497 } else { |
| 1498 // TODO(X64): Make compound assignments work. | |
| 1499 /* | |
| 1500 Literal* literal = node->value()->AsLiteral(); | 1498 Literal* literal = node->value()->AsLiteral(); |
| 1501 bool overwrite_value = | 1499 bool overwrite_value = |
| 1502 (node->value()->AsBinaryOperation() != NULL && | 1500 (node->value()->AsBinaryOperation() != NULL && |
| 1503 node->value()->AsBinaryOperation()->ResultOverwriteAllowed()); | 1501 node->value()->AsBinaryOperation()->ResultOverwriteAllowed()); |
| 1504 Variable* right_var = node->value()->AsVariableProxy()->AsVariable(); | 1502 Variable* right_var = node->value()->AsVariableProxy()->AsVariable(); |
| 1505 // There are two cases where the target is not read in the right hand | 1503 // There are two cases where the target is not read in the right hand |
| 1506 // side, that are easy to test for: the right hand side is a literal, | 1504 // side, that are easy to test for: the right hand side is a literal, |
| 1507 // or the right hand side is a different variable. TakeValue invalidates | 1505 // or the right hand side is a different variable. TakeValue invalidates |
| 1508 // the target, with an implicit promise that it will be written to again | 1506 // the target, with an implicit promise that it will be written to again |
| 1509 // before it is read. | 1507 // before it is read. |
| 1510 if (literal != NULL || (right_var != NULL && right_var != var)) { | 1508 // TODO(X64): Implement TakeValue optimization. |
| 1511 target.TakeValue(NOT_INSIDE_TYPEOF); | 1509 if (false && literal != NULL || (right_var != NULL && right_var != var)) { |
| 1510 // target.TakeValue(NOT_INSIDE_TYPEOF); | |
| 1512 } else { | 1511 } else { |
| 1513 target.GetValue(NOT_INSIDE_TYPEOF); | 1512 target.GetValue(NOT_INSIDE_TYPEOF); |
| 1514 } | 1513 } |
| 1515 */ | |
| 1516 Load(node->value()); | 1514 Load(node->value()); |
| 1517 /* | |
| 1518 GenericBinaryOperation(node->binary_op(), | 1515 GenericBinaryOperation(node->binary_op(), |
| 1519 node->type(), | 1516 node->type(), |
| 1520 overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE); | 1517 overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE); |
| 1521 */ | |
| 1522 } | 1518 } |
| 1523 | 1519 |
| 1524 if (var != NULL && | 1520 if (var != NULL && |
| 1525 var->mode() == Variable::CONST && | 1521 var->mode() == Variable::CONST && |
| 1526 node->op() != Token::INIT_VAR && node->op() != Token::INIT_CONST) { | 1522 node->op() != Token::INIT_VAR && node->op() != Token::INIT_CONST) { |
| 1527 // Assignment ignored - leave the value on the stack. | 1523 // Assignment ignored - leave the value on the stack. |
| 1528 } else { | 1524 } else { |
| 1529 CodeForSourcePosition(node->position()); | 1525 CodeForSourcePosition(node->position()); |
| 1530 if (node->op() == Token::INIT_CONST) { | 1526 if (node->op() == Token::INIT_CONST) { |
| 1531 // Dynamic constant initializations must use the function context | 1527 // Dynamic constant initializations must use the function context |
| (...skipping 736 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2268 Comparison(cc, strict, destination()); | 2264 Comparison(cc, strict, destination()); |
| 2269 } | 2265 } |
| 2270 | 2266 |
| 2271 | 2267 |
| 2272 void CodeGenerator::VisitThisFunction(ThisFunction* node) { | 2268 void CodeGenerator::VisitThisFunction(ThisFunction* node) { |
| 2273 frame_->PushFunction(); | 2269 frame_->PushFunction(); |
| 2274 } | 2270 } |
| 2275 | 2271 |
| 2276 | 2272 |
| 2277 void CodeGenerator::GenerateArgumentsAccess(ZoneList<Expression*>* args) { | 2273 void CodeGenerator::GenerateArgumentsAccess(ZoneList<Expression*>* args) { |
| 2278 UNIMPLEMENTED(); | 2274 ASSERT(args->length() == 1); |
| 2275 | |
| 2276 // ArgumentsAccessStub expects the key in edx and the formal | |
| 2277 // parameter count in eax. | |
|
Lasse Reichstein
2009/06/25 11:54:59
rdx * 2
| |
| 2278 Load(args->at(0)); | |
| 2279 Result key = frame_->Pop(); | |
| 2280 // Explicitly create a constant result. | |
| 2281 Result count(Handle<Smi>(Smi::FromInt(scope_->num_parameters()))); | |
| 2282 // Call the shared stub to get to arguments[key]. | |
| 2283 ArgumentsAccessStub stub(ArgumentsAccessStub::READ_ELEMENT); | |
| 2284 Result result = frame_->CallStub(&stub, &key, &count); | |
| 2285 frame_->Push(&result); | |
| 2279 } | 2286 } |
| 2280 | 2287 |
| 2288 | |
| 2289 void CodeGenerator::GenerateIsArray(ZoneList<Expression*>* args) { | |
| 2290 ASSERT(args->length() == 1); | |
| 2291 Load(args->at(0)); | |
| 2292 Result value = frame_->Pop(); | |
| 2293 value.ToRegister(); | |
| 2294 ASSERT(value.is_valid()); | |
| 2295 __ testl(value.reg(), Immediate(kSmiTagMask)); | |
| 2296 destination()->false_target()->Branch(equal); | |
| 2297 // It is a heap object - get map. | |
| 2298 // Check if the object is a JS array or not. | |
| 2299 __ CmpObjectType(value.reg(), JS_ARRAY_TYPE, kScratchRegister); | |
| 2300 value.Unuse(); | |
| 2301 destination()->Split(equal); | |
| 2302 } | |
| 2303 | |
| 2304 | |
| 2281 void CodeGenerator::GenerateArgumentsLength(ZoneList<Expression*>* args) { | 2305 void CodeGenerator::GenerateArgumentsLength(ZoneList<Expression*>* args) { |
| 2282 UNIMPLEMENTED();} | 2306 ASSERT(args->length() == 0); |
| 2307 // ArgumentsAccessStub takes the parameter count as an input argument | |
| 2308 // in register eax. Create a constant result for it. | |
|
Lasse Reichstein
2009/06/25 11:54:59
rax
| |
| 2309 Result count(Handle<Smi>(Smi::FromInt(scope_->num_parameters()))); | |
| 2310 // Call the shared stub to get to the arguments.length. | |
| 2311 ArgumentsAccessStub stub(ArgumentsAccessStub::READ_LENGTH); | |
| 2312 Result result = frame_->CallStub(&stub, &count); | |
| 2313 frame_->Push(&result); | |
| 2314 } | |
| 2315 | |
| 2283 | 2316 |
| 2284 void CodeGenerator::GenerateFastCharCodeAt(ZoneList<Expression*>* a) { | 2317 void CodeGenerator::GenerateFastCharCodeAt(ZoneList<Expression*>* a) { |
| 2285 UNIMPLEMENTED(); | 2318 UNIMPLEMENTED(); |
| 2286 } | 2319 } |
| 2287 | 2320 |
| 2288 void CodeGenerator::GenerateIsArray(ZoneList<Expression*>* args) { | |
| 2289 UNIMPLEMENTED(); | |
| 2290 } | |
| 2291 | 2321 |
| 2292 void CodeGenerator::GenerateIsNonNegativeSmi(ZoneList<Expression*>* args) { | 2322 void CodeGenerator::GenerateIsNonNegativeSmi(ZoneList<Expression*>* args) { |
| 2293 UNIMPLEMENTED(); | 2323 UNIMPLEMENTED(); |
| 2294 } | 2324 } |
| 2295 | 2325 |
| 2326 | |
| 2296 void CodeGenerator::GenerateIsSmi(ZoneList<Expression*>* args) { | 2327 void CodeGenerator::GenerateIsSmi(ZoneList<Expression*>* args) { |
| 2297 UNIMPLEMENTED(); | 2328 ASSERT(args->length() == 1); |
| 2329 Load(args->at(0)); | |
| 2330 Result value = frame_->Pop(); | |
| 2331 value.ToRegister(); | |
| 2332 ASSERT(value.is_valid()); | |
| 2333 __ testl(value.reg(), Immediate(kSmiTagMask)); | |
| 2334 value.Unuse(); | |
| 2335 destination()->Split(zero); | |
| 2298 } | 2336 } |
| 2299 | 2337 |
| 2338 | |
| 2300 void CodeGenerator::GenerateLog(ZoneList<Expression*>* a) { | 2339 void CodeGenerator::GenerateLog(ZoneList<Expression*>* a) { |
| 2301 UNIMPLEMENTED(); | 2340 UNIMPLEMENTED(); |
| 2302 } | 2341 } |
| 2303 | 2342 |
| 2304 void CodeGenerator::GenerateObjectEquals(ZoneList<Expression*>* args) { | 2343 void CodeGenerator::GenerateObjectEquals(ZoneList<Expression*>* args) { |
| 2305 UNIMPLEMENTED(); | 2344 ASSERT(args->length() == 2); |
| 2345 | |
| 2346 // Load the two objects into registers and perform the comparison. | |
| 2347 Load(args->at(0)); | |
| 2348 Load(args->at(1)); | |
| 2349 Result right = frame_->Pop(); | |
| 2350 Result left = frame_->Pop(); | |
| 2351 right.ToRegister(); | |
| 2352 left.ToRegister(); | |
| 2353 __ cmpq(right.reg(), left.reg()); | |
| 2354 right.Unuse(); | |
| 2355 left.Unuse(); | |
| 2356 destination()->Split(equal); | |
| 2306 } | 2357 } |
| 2307 | 2358 |
| 2359 | |
| 2360 | |
| 2308 void CodeGenerator::GenerateRandomPositiveSmi(ZoneList<Expression*>* a) { | 2361 void CodeGenerator::GenerateRandomPositiveSmi(ZoneList<Expression*>* a) { |
| 2309 UNIMPLEMENTED(); | 2362 UNIMPLEMENTED(); |
| 2310 } | 2363 } |
| 2311 | 2364 |
| 2312 void CodeGenerator::GenerateFastMathOp(MathOp op, ZoneList<Expression*>* args) { | 2365 void CodeGenerator::GenerateFastMathOp(MathOp op, ZoneList<Expression*>* args) { |
| 2313 UNIMPLEMENTED(); | 2366 UNIMPLEMENTED(); |
| 2314 } | 2367 } |
| 2315 | 2368 |
| 2369 | |
| 2316 void CodeGenerator::GenerateSetValueOf(ZoneList<Expression*>* args) { | 2370 void CodeGenerator::GenerateSetValueOf(ZoneList<Expression*>* args) { |
| 2317 UNIMPLEMENTED(); | 2371 ASSERT(args->length() == 2); |
| 2372 JumpTarget leave; | |
| 2373 Load(args->at(0)); // Load the object. | |
| 2374 Load(args->at(1)); // Load the value. | |
| 2375 Result value = frame_->Pop(); | |
| 2376 Result object = frame_->Pop(); | |
| 2377 value.ToRegister(); | |
| 2378 object.ToRegister(); | |
| 2379 | |
| 2380 // if (object->IsSmi()) return value. | |
| 2381 __ testl(object.reg(), Immediate(kSmiTagMask)); | |
| 2382 leave.Branch(zero, &value); | |
| 2383 | |
| 2384 // It is a heap object - get its map. | |
| 2385 Result scratch = allocator_->Allocate(); | |
| 2386 ASSERT(scratch.is_valid()); | |
| 2387 // if (!object->IsJSValue()) return value. | |
| 2388 __ CmpObjectType(object.reg(), JS_VALUE_TYPE, scratch.reg()); | |
| 2389 leave.Branch(not_equal, &value); | |
| 2390 | |
| 2391 // Store the value. | |
| 2392 __ movq(FieldOperand(object.reg(), JSValue::kValueOffset), value.reg()); | |
| 2393 // Update the write barrier. Save the value as it will be | |
| 2394 // overwritten by the write barrier code and is needed afterward. | |
| 2395 Result duplicate_value = allocator_->Allocate(); | |
| 2396 ASSERT(duplicate_value.is_valid()); | |
| 2397 __ movq(duplicate_value.reg(), value.reg()); | |
| 2398 // The object register is also overwritten by the write barrier and | |
| 2399 // possibly aliased in the frame. | |
| 2400 frame_->Spill(object.reg()); | |
| 2401 __ RecordWrite(object.reg(), JSValue::kValueOffset, duplicate_value.reg(), | |
| 2402 scratch.reg()); | |
| 2403 object.Unuse(); | |
| 2404 scratch.Unuse(); | |
| 2405 duplicate_value.Unuse(); | |
| 2406 | |
| 2407 // Leave. | |
| 2408 leave.Bind(&value); | |
| 2409 frame_->Push(&value); | |
| 2318 } | 2410 } |
| 2319 | 2411 |
| 2412 | |
| 2320 void CodeGenerator::GenerateValueOf(ZoneList<Expression*>* args) { | 2413 void CodeGenerator::GenerateValueOf(ZoneList<Expression*>* args) { |
| 2321 UNIMPLEMENTED(); | 2414 UNIMPLEMENTED(); |
| 2322 } | 2415 } |
| 2323 | 2416 |
| 2324 // ----------------------------------------------------------------------------- | 2417 // ----------------------------------------------------------------------------- |
| 2325 // CodeGenerator implementation of Expressions | 2418 // CodeGenerator implementation of Expressions |
| 2326 | 2419 |
| 2327 void CodeGenerator::Load(Expression* x, TypeofState typeof_state) { | 2420 void CodeGenerator::Load(Expression* x, TypeofState typeof_state) { |
| 2328 #ifdef DEBUG | 2421 #ifdef DEBUG |
| 2329 int original_height = frame_->height(); | 2422 int original_height = frame_->height(); |
| (...skipping 3173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5503 break; | 5596 break; |
| 5504 default: | 5597 default: |
| 5505 UNREACHABLE(); | 5598 UNREACHABLE(); |
| 5506 } | 5599 } |
| 5507 } | 5600 } |
| 5508 | 5601 |
| 5509 | 5602 |
| 5510 #undef __ | 5603 #undef __ |
| 5511 | 5604 |
| 5512 } } // namespace v8::internal | 5605 } } // namespace v8::internal |
| OLD | NEW |