Commit 6dd1251e authored by Michael Starzinger's avatar Michael Starzinger Committed by Commit Bot

Handlify FrameFunctionIterator to allow for GCs.

R=tebbi@chromium.org
TEST=mjsunit/regress/regress-crbug-755044
BUG=chromium:755044

Change-Id: I909eeeccaf4e4e9757a2f952c00f557ee6c495ee
Reviewed-on: https://chromium-review.googlesource.com/625878Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Commit-Queue: Michael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47510}
parent 749b9c06
......@@ -928,20 +928,21 @@ static inline bool AllowAccessToFunction(Context* current_context,
class FrameFunctionIterator {
public:
FrameFunctionIterator(Isolate* isolate, const DisallowHeapAllocation& promise)
explicit FrameFunctionIterator(Isolate* isolate)
: isolate_(isolate), frame_iterator_(isolate), frames_(2), index_(0) {
GetFrames();
}
JSFunction* next() {
MaybeHandle<JSFunction> next() {
while (true) {
if (frames_.length() == 0) return NULL;
JSFunction* next_function = *frames_[index_].AsJavaScript().function();
if (frames_.length() == 0) return MaybeHandle<JSFunction>();
Handle<JSFunction> next_function =
frames_[index_].AsJavaScript().function();
index_--;
if (index_ < 0) {
GetFrames();
}
// Skip functions from other origins.
if (!AllowAccessToFunction(isolate_->context(), next_function)) continue;
if (!AllowAccessToFunction(isolate_->context(), *next_function)) continue;
return next_function;
}
}
......@@ -949,13 +950,12 @@ class FrameFunctionIterator {
// Iterate through functions until the first occurrence of 'function'.
// Returns true if 'function' is found, and false if the iterator ends
// without finding it.
bool Find(JSFunction* function) {
JSFunction* next_function;
bool Find(Handle<JSFunction> function) {
Handle<JSFunction> next_function;
do {
next_function = next();
if (next_function == function) return true;
} while (next_function != NULL);
return false;
if (!next().ToHandle(&next_function)) return false;
} while (!next_function.is_identical_to(function));
return true;
}
private:
......@@ -977,33 +977,31 @@ class FrameFunctionIterator {
MaybeHandle<JSFunction> FindCaller(Isolate* isolate,
Handle<JSFunction> function) {
DisallowHeapAllocation no_allocation;
FrameFunctionIterator it(isolate, no_allocation);
FrameFunctionIterator it(isolate);
if (function->shared()->native()) {
return MaybeHandle<JSFunction>();
}
// Find the function from the frames.
if (!it.Find(*function)) {
if (!it.Find(function)) {
// No frame corresponding to the given function found. Return null.
return MaybeHandle<JSFunction>();
}
// Find previously called non-toplevel function.
JSFunction* caller;
Handle<JSFunction> caller;
do {
caller = it.next();
if (caller == NULL) return MaybeHandle<JSFunction>();
if (!it.next().ToHandle(&caller)) return MaybeHandle<JSFunction>();
} while (caller->shared()->is_toplevel());
// If caller is not user code and caller's caller is also not user code,
// use that instead.
JSFunction* potential_caller = caller;
while (potential_caller != NULL &&
!potential_caller->shared()->IsUserJavaScript()) {
caller = potential_caller;
MaybeHandle<JSFunction> potential_caller = caller;
while (!potential_caller.is_null() &&
!potential_caller.ToHandleChecked()->shared()->IsUserJavaScript()) {
caller = potential_caller.ToHandleChecked();
potential_caller = it.next();
}
if (!caller->shared()->native() && potential_caller != NULL) {
caller = potential_caller;
if (!caller->shared()->native() && !potential_caller.is_null()) {
caller = potential_caller.ToHandleChecked();
}
// Censor if the caller is not a sloppy mode function.
// Change from ES5, which used to throw, see:
......@@ -1012,10 +1010,10 @@ MaybeHandle<JSFunction> FindCaller(Isolate* isolate,
return MaybeHandle<JSFunction>();
}
// Don't return caller from another security context.
if (!AllowAccessToFunction(isolate->context(), caller)) {
if (!AllowAccessToFunction(isolate->context(), *caller)) {
return MaybeHandle<JSFunction>();
}
return Handle<JSFunction>(caller);
return caller;
}
......
// 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.
// Flags: --allow-natives-syntax
function foo(f){
f.caller;
}
function bar(f) {
new foo(f);
}
bar(function() {});
%OptimizeFunctionOnNextCall(bar);
bar(function() {});
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