Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(45)

Unified Diff: src/arm64/builtins-arm64.cc

Issue 913073003: [es6] implement Reflect.apply() & Reflect.construct() (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix arm Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/arm/builtins-arm.cc ('k') | src/bootstrapper.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/arm64/builtins-arm64.cc
diff --git a/src/arm64/builtins-arm64.cc b/src/arm64/builtins-arm64.cc
index 89e304051abf6b426a7eff0505c5f68d1349271d..a638d8dfbdc3543e5b54022548eb338f0e47771c 100644
--- a/src/arm64/builtins-arm64.cc
+++ b/src/arm64/builtins-arm64.cc
@@ -1324,53 +1324,107 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) {
}
-void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
- ASM_LOCATION("Builtins::Generate_FunctionApply");
- const int kIndexOffset =
- StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize);
- const int kLimitOffset =
- StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize);
- const int kArgsOffset = 2 * kPointerSize;
- const int kReceiverOffset = 3 * kPointerSize;
- const int kFunctionOffset = 4 * kPointerSize;
+static void Generate_CheckStackOverflow(MacroAssembler* masm,
+ const int calleeOffset) {
+ Register argc = x0;
+ Register receiver = x14;
+ Register function = x15;
+
+ // Check the stack for overflow.
+ // We are not trying to catch interruptions (e.g. debug break and
+ // preemption) here, so the "real stack limit" is checked.
+ Label enough_stack_space;
+ __ LoadRoot(x10, Heap::kRealStackLimitRootIndex);
+ __ Ldr(function, MemOperand(fp, calleeOffset));
+ // Make x10 the space we have left. The stack might already be overflowed
+ // here which will cause x10 to become negative.
+ // TODO(jbramley): Check that the stack usage here is safe.
+ __ Sub(x10, jssp, x10);
+ // Check if the arguments will overflow the stack.
+ __ Cmp(x10, Operand::UntagSmiAndScale(argc, kPointerSizeLog2));
+ __ B(gt, &enough_stack_space);
+ // There is not enough stack space, so use a builtin to throw an appropriate
+ // error.
+ __ Push(function, argc);
+ __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
+ // We should never return from the APPLY_OVERFLOW builtin.
+ if (__ emit_debug_code()) {
+ __ Unreachable();
+ }
+
+ __ Bind(&enough_stack_space);
+}
+
+
+static void Generate_PushAppliedArguments(MacroAssembler* masm,
+ const int argumentsOffset,
+ const int indexOffset,
+ const int limitOffset) {
+ Label entry, loop;
+ Register current = x0;
+ __ Ldr(current, MemOperand(fp, indexOffset));
+ __ B(&entry);
+
+ __ Bind(&loop);
+ // Load the current argument from the arguments array and push it.
+ // TODO(all): Couldn't we optimize this for JS arrays?
+
+ __ Ldr(x1, MemOperand(fp, argumentsOffset));
+ __ Push(x1, current);
+
+ // Call the runtime to access the property in the arguments array.
+ __ CallRuntime(Runtime::kGetProperty, 2);
+ __ Push(x0);
+
+ // Use inline caching to access the arguments.
+ __ Ldr(current, MemOperand(fp, indexOffset));
+ __ Add(current, current, Smi::FromInt(1));
+ __ Str(current, MemOperand(fp, indexOffset));
+
+ // Test if the copy loop has finished copying all the elements from the
+ // arguments object.
+ __ Bind(&entry);
+ __ Ldr(x1, MemOperand(fp, limitOffset));
+ __ Cmp(current, x1);
+ __ B(ne, &loop);
+
+ // On exit, the pushed arguments count is in x0, untagged
+ __ SmiUntag(current);
+}
+
+
+static void Generate_ApplyHelper(MacroAssembler* masm, bool targetIsArgument) {
+ const int kFormalParameters = targetIsArgument ? 3 : 2;
+ const int kStackSize = kFormalParameters + 1;
{
FrameScope frame_scope(masm, StackFrame::INTERNAL);
+ const int kArgumentsOffset = kFPOnStackSize + kPCOnStackSize;
+ const int kReceiverOffset = kArgumentsOffset + kPointerSize;
+ const int kFunctionOffset = kReceiverOffset + kPointerSize;
+ const int kIndexOffset =
+ StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize);
+ const int kLimitOffset =
+ StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize);
+
Register args = x12;
Register receiver = x14;
Register function = x15;
// Get the length of the arguments via a builtin call.
__ Ldr(function, MemOperand(fp, kFunctionOffset));
- __ Ldr(args, MemOperand(fp, kArgsOffset));
+ __ Ldr(args, MemOperand(fp, kArgumentsOffset));
__ Push(function, args);
- __ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION);
+ if (targetIsArgument) {
+ __ InvokeBuiltin(Builtins::REFLECT_APPLY_PREPARE, CALL_FUNCTION);
+ } else {
+ __ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION);
+ }
Register argc = x0;
- // Check the stack for overflow.
- // We are not trying to catch interruptions (e.g. debug break and
- // preemption) here, so the "real stack limit" is checked.
- Label enough_stack_space;
- __ LoadRoot(x10, Heap::kRealStackLimitRootIndex);
- __ Ldr(function, MemOperand(fp, kFunctionOffset));
- // Make x10 the space we have left. The stack might already be overflowed
- // here which will cause x10 to become negative.
- // TODO(jbramley): Check that the stack usage here is safe.
- __ Sub(x10, jssp, x10);
- // Check if the arguments will overflow the stack.
- __ Cmp(x10, Operand::UntagSmiAndScale(argc, kPointerSizeLog2));
- __ B(gt, &enough_stack_space);
- // There is not enough stack space, so use a builtin to throw an appropriate
- // error.
- __ Push(function, argc);
- __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
- // We should never return from the APPLY_OVERFLOW builtin.
- if (__ emit_debug_code()) {
- __ Unreachable();
- }
+ Generate_CheckStackOverflow(masm, kFunctionOffset);
- __ Bind(&enough_stack_space);
// Push current limit and index.
__ Mov(x1, 0); // Initial index.
__ Push(argc, x1);
@@ -1424,33 +1478,8 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
__ Push(receiver);
// Copy all arguments from the array to the stack.
- Label entry, loop;
- Register current = x0;
- __ Ldr(current, MemOperand(fp, kIndexOffset));
- __ B(&entry);
-
- __ Bind(&loop);
- // Load the current argument from the arguments array and push it.
- // TODO(all): Couldn't we optimize this for JS arrays?
-
- __ Ldr(x1, MemOperand(fp, kArgsOffset));
- __ Push(x1, current);
-
- // Call the runtime to access the property in the arguments array.
- __ CallRuntime(Runtime::kGetProperty, 2);
- __ Push(x0);
-
- // Use inline caching to access the arguments.
- __ Ldr(current, MemOperand(fp, kIndexOffset));
- __ Add(current, current, Smi::FromInt(1));
- __ Str(current, MemOperand(fp, kIndexOffset));
-
- // Test if the copy loop has finished copying all the elements from the
- // arguments object.
- __ Bind(&entry);
- __ Ldr(x1, MemOperand(fp, kLimitOffset));
- __ Cmp(current, x1);
- __ B(ne, &loop);
+ Generate_PushAppliedArguments(
+ masm, kArgumentsOffset, kIndexOffset, kLimitOffset);
// At the end of the loop, the number of arguments is stored in 'current',
// represented as a smi.
@@ -1460,12 +1489,11 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
// Call the function.
Label call_proxy;
- ParameterCount actual(current);
- __ SmiUntag(current);
+ ParameterCount actual(x0);
__ JumpIfNotObjectType(function, x10, x11, JS_FUNCTION_TYPE, &call_proxy);
__ InvokeFunction(function, actual, CALL_FUNCTION, NullCallWrapper());
frame_scope.GenerateLeaveFrame();
- __ Drop(3);
+ __ Drop(kStackSize);
__ Ret();
// Call the function proxy.
@@ -1479,11 +1507,94 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
__ Call(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
RelocInfo::CODE_TARGET);
}
- __ Drop(3);
+ __ Drop(kStackSize);
__ Ret();
}
+static void Generate_ConstructHelper(MacroAssembler* masm) {
+ const int kFormalParameters = 3;
+ const int kStackSize = kFormalParameters + 1;
+
+ {
+ FrameScope frame_scope(masm, StackFrame::INTERNAL);
+
+ const int kNewTargetOffset = kFPOnStackSize + kPCOnStackSize;
+ const int kArgumentsOffset = kNewTargetOffset + kPointerSize;
+ const int kFunctionOffset = kArgumentsOffset + kPointerSize;
+
+ const int kIndexOffset =
+ StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize);
+ const int kLimitOffset =
+ StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize);
+
+ // Is x11 safe to use?
+ Register newTarget = x11;
+ Register args = x12;
+ Register receiver = x14;
+ Register function = x15;
+
+ // If newTarget is not supplied, set it to constructor
+ Label validate_arguments;
+ __ Ldr(x0, MemOperand(fp, kNewTargetOffset));
+ __ CompareRoot(x0, Heap::kUndefinedValueRootIndex);
+ __ B(ne, &validate_arguments);
+ __ Ldr(x0, MemOperand(fp, kFunctionOffset));
+ __ Str(x0, MemOperand(fp, kNewTargetOffset));
+
+ // Validate arguments
+ __ Bind(&validate_arguments);
+ __ Ldr(function, MemOperand(fp, kFunctionOffset));
+ __ Ldr(args, MemOperand(fp, kArgumentsOffset));
+ __ Ldr(newTarget, MemOperand(fp, kNewTargetOffset));
+ __ Push(function, args, newTarget);
+ __ InvokeBuiltin(Builtins::REFLECT_CONSTRUCT_PREPARE, CALL_FUNCTION);
+ Register argc = x0;
+
+ Generate_CheckStackOverflow(masm, kFunctionOffset);
+
+ // Push current limit and index, constructor & newTarget
+ __ Mov(x1, 0); // Initial index.
+ __ Ldr(newTarget, MemOperand(fp, kNewTargetOffset));
+ __ Push(argc, x1, newTarget, function);
+
+ // Copy all arguments from the array to the stack.
+ Generate_PushAppliedArguments(
+ masm, kArgumentsOffset, kIndexOffset, kLimitOffset);
+
+ __ Ldr(x1, MemOperand(fp, kFunctionOffset));
+ // Use undefined feedback vector
+ __ LoadRoot(x2, Heap::kUndefinedValueRootIndex);
+
+ // Call the function.
+ CallConstructStub stub(masm->isolate(), SUPER_CONSTRUCTOR_CALL);
+ __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL);
+
+ __ Drop(1);
+ }
+ __ Drop(kStackSize);
+ __ Ret();
+}
+
+
+void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
+ ASM_LOCATION("Builtins::Generate_FunctionApply");
+ Generate_ApplyHelper(masm, false);
+}
+
+
+void Builtins::Generate_ReflectApply(MacroAssembler* masm) {
+ ASM_LOCATION("Builtins::Generate_ReflectApply");
+ Generate_ApplyHelper(masm, true);
+}
+
+
+void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) {
+ ASM_LOCATION("Builtins::Generate_ReflectConstruct");
+ Generate_ConstructHelper(masm);
+}
+
+
static void ArgumentAdaptorStackCheck(MacroAssembler* masm,
Label* stack_overflow) {
// ----------- S t a t e -------------
« no previous file with comments | « src/arm/builtins-arm.cc ('k') | src/bootstrapper.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698