Commit 1e77461d authored by Yang Guo's avatar Yang Guo Committed by Commit Bot

Perform stack check on Proxy call trap.

Proxy's call trap can be used to cause recursion.

R=bmeurer@chromium.org, tebbi@chromium.org

Bug: chromium:779344
Change-Id: I19c989f618f7230028ebe18c3415bc3f4bd72b93
Reviewed-on: https://chromium-review.googlesource.com/743782Reviewed-by: 's avatarBenedikt Meurer <bmeurer@chromium.org>
Commit-Queue: Yang Guo <yangguo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#49069}
parent 781f7685
......@@ -135,6 +135,8 @@ TF_BUILTIN(CallProxy, ProxiesCodeStubAssembler) {
CSA_ASSERT(this, IsJSProxy(proxy));
CSA_ASSERT(this, IsCallable(proxy));
PerformStackCheck(context);
Label throw_proxy_handler_revoked(this, Label::kDeferred),
trap_undefined(this);
......
......@@ -10709,5 +10709,25 @@ void CodeStubAssembler::Print(const char* prefix, Node* tagged_value) {
CallRuntime(Runtime::kDebugPrint, NoContextConstant(), tagged_value);
}
void CodeStubAssembler::PerformStackCheck(Node* context) {
Label ok(this), stack_check_interrupt(this, Label::kDeferred);
Node* sp = LoadStackPointer();
Node* stack_limit = Load(
MachineType::Pointer(),
ExternalConstant(ExternalReference::address_of_stack_limit(isolate())));
Node* interrupt = UintPtrLessThan(sp, stack_limit);
Branch(interrupt, &stack_check_interrupt, &ok);
BIND(&stack_check_interrupt);
{
CallRuntime(Runtime::kStackGuard, context);
Goto(&ok);
}
BIND(&ok);
}
} // namespace internal
} // namespace v8
......@@ -1823,6 +1823,8 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
Unreachable();
}
void PerformStackCheck(Node* context);
protected:
void DescriptorLookup(Node* unique_name, Node* descriptors, Node* bitfield3,
Label* if_found, Variable* var_name_index,
......
......@@ -1295,14 +1295,6 @@ void InterpreterAssembler::UpdateInterruptBudgetOnReturn() {
UpdateInterruptBudget(profiling_weight, true);
}
Node* InterpreterAssembler::StackCheckTriggeredInterrupt() {
Node* sp = LoadStackPointer();
Node* stack_limit = Load(
MachineType::Pointer(),
ExternalConstant(ExternalReference::address_of_stack_limit(isolate())));
return UintPtrLessThan(sp, stack_limit);
}
Node* InterpreterAssembler::LoadOSRNestingLevel() {
return LoadObjectField(BytecodeArrayTaggedPointer(),
BytecodeArray::kOSRNestingLevelOffset,
......
......@@ -208,9 +208,6 @@ class V8_EXPORT_PRIVATE InterpreterAssembler : public CodeStubAssembler {
void JumpIfWordNotEqual(compiler::Node* lhs, compiler::Node* rhs,
compiler::Node* jump_offset);
// Returns true if the stack guard check triggers an interrupt.
compiler::Node* StackCheckTriggeredInterrupt();
// Updates the profiler interrupt budget for a return.
void UpdateInterruptBudgetOnReturn();
......
......@@ -2731,20 +2731,9 @@ IGNITION_HANDLER(CreateRestParameter, InterpreterAssembler) {
//
// Performs a stack guard check.
IGNITION_HANDLER(StackCheck, InterpreterAssembler) {
Label ok(this), stack_check_interrupt(this, Label::kDeferred);
Node* interrupt = StackCheckTriggeredInterrupt();
Branch(interrupt, &stack_check_interrupt, &ok);
BIND(&ok);
Dispatch();
BIND(&stack_check_interrupt);
{
Node* context = GetContext();
CallRuntime(Runtime::kStackGuard, context);
PerformStackCheck(context);
Dispatch();
}
}
// SetPendingMessage
......
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
var o = {};
var proxy = new Proxy(() => {}, o);
o.apply = proxy;
assertThrows(
() => Function.prototype.call.call(proxy)
);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment