| OLD | NEW | 
|     1 // Copyright 2013 the V8 project authors. All rights reserved. |     1 // Copyright 2013 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 #if V8_TARGET_ARCH_ARM64 |     5 #if V8_TARGET_ARCH_ARM64 | 
|     6  |     6  | 
|     7 #include "src/ast/scopes.h" |     7 #include "src/ast/scopes.h" | 
|     8 #include "src/code-factory.h" |     8 #include "src/code-factory.h" | 
|     9 #include "src/code-stubs.h" |     9 #include "src/code-stubs.h" | 
|    10 #include "src/codegen.h" |    10 #include "src/codegen.h" | 
| (...skipping 4384 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  4395     } |  4395     } | 
|  4396  |  4396  | 
|  4397     case Yield::kFinal: { |  4397     case Yield::kFinal: { | 
|  4398       // Pop value from top-of-stack slot, box result into result register. |  4398       // Pop value from top-of-stack slot, box result into result register. | 
|  4399       EmitCreateIteratorResult(true); |  4399       EmitCreateIteratorResult(true); | 
|  4400       EmitUnwindBeforeReturn(); |  4400       EmitUnwindBeforeReturn(); | 
|  4401       EmitReturnSequence(); |  4401       EmitReturnSequence(); | 
|  4402       break; |  4402       break; | 
|  4403     } |  4403     } | 
|  4404  |  4404  | 
|  4405     case Yield::kDelegating: { |  4405     case Yield::kDelegating: | 
|  4406       VisitForStackValue(expr->generator_object()); |  4406       UNREACHABLE(); | 
|  4407  |  | 
|  4408       // Initial stack layout is as follows: |  | 
|  4409       // [sp + 1 * kPointerSize] iter |  | 
|  4410       // [sp + 0 * kPointerSize] g |  | 
|  4411  |  | 
|  4412       Label l_catch, l_try, l_suspend, l_continuation, l_resume; |  | 
|  4413       Label l_next, l_call, l_loop; |  | 
|  4414       Register load_receiver = LoadDescriptor::ReceiverRegister(); |  | 
|  4415       Register load_name = LoadDescriptor::NameRegister(); |  | 
|  4416  |  | 
|  4417       // Initial send value is undefined. |  | 
|  4418       __ LoadRoot(x0, Heap::kUndefinedValueRootIndex); |  | 
|  4419       __ B(&l_next); |  | 
|  4420  |  | 
|  4421       // catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; } |  | 
|  4422       __ Bind(&l_catch); |  | 
|  4423       __ LoadRoot(load_name, Heap::kthrow_stringRootIndex);  // "throw" |  | 
|  4424       __ Peek(x3, 1 * kPointerSize);                         // iter |  | 
|  4425       __ Push(load_name, x3, x0);                       // "throw", iter, except |  | 
|  4426       __ B(&l_call); |  | 
|  4427  |  | 
|  4428       // try { received = %yield result } |  | 
|  4429       // Shuffle the received result above a try handler and yield it without |  | 
|  4430       // re-boxing. |  | 
|  4431       __ Bind(&l_try); |  | 
|  4432       __ Pop(x0);                                        // result |  | 
|  4433       int handler_index = NewHandlerTableEntry(); |  | 
|  4434       EnterTryBlock(handler_index, &l_catch); |  | 
|  4435       const int try_block_size = TryCatch::kElementCount * kPointerSize; |  | 
|  4436       __ Push(x0);                                       // result |  | 
|  4437  |  | 
|  4438       __ B(&l_suspend); |  | 
|  4439       // TODO(jbramley): This label is bound here because the following code |  | 
|  4440       // looks at its pos(). Is it possible to do something more efficient here, |  | 
|  4441       // perhaps using Adr? |  | 
|  4442       __ Bind(&l_continuation); |  | 
|  4443       __ RecordGeneratorContinuation(); |  | 
|  4444       __ B(&l_resume); |  | 
|  4445  |  | 
|  4446       __ Bind(&l_suspend); |  | 
|  4447       const int generator_object_depth = kPointerSize + try_block_size; |  | 
|  4448       __ Peek(x0, generator_object_depth); |  | 
|  4449       __ Push(x0);                                       // g |  | 
|  4450       __ Push(Smi::FromInt(handler_index));              // handler-index |  | 
|  4451       DCHECK((l_continuation.pos() > 0) && Smi::IsValid(l_continuation.pos())); |  | 
|  4452       __ Mov(x1, Smi::FromInt(l_continuation.pos())); |  | 
|  4453       __ Str(x1, FieldMemOperand(x0, JSGeneratorObject::kContinuationOffset)); |  | 
|  4454       __ Str(cp, FieldMemOperand(x0, JSGeneratorObject::kContextOffset)); |  | 
|  4455       __ Mov(x1, cp); |  | 
|  4456       __ RecordWriteField(x0, JSGeneratorObject::kContextOffset, x1, x2, |  | 
|  4457                           kLRHasBeenSaved, kDontSaveFPRegs); |  | 
|  4458       __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 2); |  | 
|  4459       __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |  | 
|  4460       __ Pop(x0);                                        // result |  | 
|  4461       EmitReturnSequence(); |  | 
|  4462       __ Bind(&l_resume);                                // received in x0 |  | 
|  4463       ExitTryBlock(handler_index); |  | 
|  4464  |  | 
|  4465       // receiver = iter; f = 'next'; arg = received; |  | 
|  4466       __ Bind(&l_next); |  | 
|  4467  |  | 
|  4468       __ LoadRoot(load_name, Heap::knext_stringRootIndex);  // "next" |  | 
|  4469       __ Peek(x3, 1 * kPointerSize);                        // iter |  | 
|  4470       __ Push(load_name, x3, x0);                      // "next", iter, received |  | 
|  4471  |  | 
|  4472       // result = receiver[f](arg); |  | 
|  4473       __ Bind(&l_call); |  | 
|  4474       __ Peek(load_receiver, 1 * kPointerSize); |  | 
|  4475       __ Peek(load_name, 2 * kPointerSize); |  | 
|  4476       __ Mov(LoadDescriptor::SlotRegister(), |  | 
|  4477              SmiFromSlot(expr->KeyedLoadFeedbackSlot())); |  | 
|  4478       Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), SLOPPY).code(); |  | 
|  4479       CallIC(ic, TypeFeedbackId::None()); |  | 
|  4480       __ Mov(x1, x0); |  | 
|  4481       __ Poke(x1, 2 * kPointerSize); |  | 
|  4482       SetCallPosition(expr); |  | 
|  4483       __ Mov(x0, 1); |  | 
|  4484       __ Call( |  | 
|  4485           isolate()->builtins()->Call(ConvertReceiverMode::kNotNullOrUndefined), |  | 
|  4486           RelocInfo::CODE_TARGET); |  | 
|  4487  |  | 
|  4488       __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |  | 
|  4489       __ Drop(1);  // The function is still on the stack; drop it. |  | 
|  4490  |  | 
|  4491       // if (!result.done) goto l_try; |  | 
|  4492       __ Bind(&l_loop); |  | 
|  4493       __ Move(load_receiver, x0); |  | 
|  4494  |  | 
|  4495       __ Push(load_receiver);                               // save result |  | 
|  4496       __ LoadRoot(load_name, Heap::kdone_stringRootIndex);  // "done" |  | 
|  4497       __ Mov(LoadDescriptor::SlotRegister(), |  | 
|  4498              SmiFromSlot(expr->DoneFeedbackSlot())); |  | 
|  4499       CallLoadIC(NOT_INSIDE_TYPEOF);  // x0=result.done |  | 
|  4500       // The ToBooleanStub argument (result.done) is in x0. |  | 
|  4501       Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); |  | 
|  4502       CallIC(bool_ic); |  | 
|  4503       __ CompareRoot(result_register(), Heap::kTrueValueRootIndex); |  | 
|  4504       __ B(ne, &l_try); |  | 
|  4505  |  | 
|  4506       // result.value |  | 
|  4507       __ Pop(load_receiver);                                 // result |  | 
|  4508       __ LoadRoot(load_name, Heap::kvalue_stringRootIndex);  // "value" |  | 
|  4509       __ Mov(LoadDescriptor::SlotRegister(), |  | 
|  4510              SmiFromSlot(expr->ValueFeedbackSlot())); |  | 
|  4511       CallLoadIC(NOT_INSIDE_TYPEOF);                         // x0=result.value |  | 
|  4512       context()->DropAndPlug(2, x0);                         // drop iter and g |  | 
|  4513       break; |  | 
|  4514     } |  | 
|  4515   } |  4407   } | 
|  4516 } |  4408 } | 
|  4517  |  4409  | 
|  4518  |  4410  | 
|  4519 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, |  4411 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, | 
|  4520     Expression *value, |  4412     Expression *value, | 
|  4521     JSGeneratorObject::ResumeMode resume_mode) { |  4413     JSGeneratorObject::ResumeMode resume_mode) { | 
|  4522   ASM_LOCATION("FullCodeGenerator::EmitGeneratorResume"); |  4414   ASM_LOCATION("FullCodeGenerator::EmitGeneratorResume"); | 
|  4523   Register generator_object = x1; |  4415   Register generator_object = x1; | 
|  4524   Register the_hole = x2; |  4416   Register the_hole = x2; | 
| (...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  4852   } |  4744   } | 
|  4853  |  4745  | 
|  4854   return INTERRUPT; |  4746   return INTERRUPT; | 
|  4855 } |  4747 } | 
|  4856  |  4748  | 
|  4857  |  4749  | 
|  4858 }  // namespace internal |  4750 }  // namespace internal | 
|  4859 }  // namespace v8 |  4751 }  // namespace v8 | 
|  4860  |  4752  | 
|  4861 #endif  // V8_TARGET_ARCH_ARM64 |  4753 #endif  // V8_TARGET_ARCH_ARM64 | 
| OLD | NEW |