| Index: src/builtins.cc
|
| diff --git a/src/builtins.cc b/src/builtins.cc
|
| index 07817fe8c0899444decbddebeb73acd90d6a5e6c..6e604ed5e9a9f13bb6c6db7ac932005a35b4b30c 100644
|
| --- a/src/builtins.cc
|
| +++ b/src/builtins.cc
|
| @@ -4102,8 +4102,48 @@ void Builtins::Generate_DatePrototypeGetUTCSeconds(MacroAssembler* masm) {
|
|
|
| namespace {
|
|
|
| +// Walk up the stack expecting:
|
| +// - ExitFrame
|
| +// - call() (maybe)
|
| +// - apply() (maybe)
|
| +// - bind() (maybe)
|
| +// - JSFunction caller (maybe)
|
| +//
|
| +// return true if the caller has access to the callee or if an exit frame was
|
| +// hit, in which case allow it through, as it could have come through the api.
|
| +bool HasAccessToContextForCreateDynamicFunction(
|
| + Isolate* isolate, Handle<JSObject> target_global_proxy) {
|
| + bool exit_handled = true;
|
| + bool has_access = true;
|
| + bool done = false;
|
| + StackFrameIterator it(isolate);
|
| + // Skip exit frame that corresponds to the builtin call.
|
| + it.Advance();
|
| + for (; !it.done() && !done; it.Advance()) {
|
| + StackFrame* raw_frame = it.frame();
|
| + if (!raw_frame->is_java_script()) {
|
| + if (raw_frame->is_exit()) exit_handled = false;
|
| + continue;
|
| + }
|
| + JavaScriptFrame* outer_frame = JavaScriptFrame::cast(raw_frame);
|
| + List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
|
| + outer_frame->Summarize(&frames);
|
| + for (int i = frames.length() - 1; i >= 0 && !done; --i) {
|
| + FrameSummary& frame = frames[i];
|
| + Handle<JSFunction> fun = frame.function();
|
| + if (!isolate->MayAccess(handle(fun->context()), target_global_proxy)) {
|
| + has_access = false;
|
| + done = true;
|
| + continue;
|
| + }
|
| + done = true;
|
| + }
|
| + }
|
| + return !exit_handled || has_access;
|
| +}
|
| +
|
| // ES6 section 19.2.1.1.1 CreateDynamicFunction
|
| -MaybeHandle<JSFunction> CreateDynamicFunction(
|
| +MaybeHandle<Object> CreateDynamicFunction(
|
| Isolate* isolate,
|
| BuiltinArguments<BuiltinExtraArguments::kTargetAndNewTarget> args,
|
| const char* token) {
|
| @@ -4111,6 +4151,15 @@ MaybeHandle<JSFunction> CreateDynamicFunction(
|
| DCHECK_LE(1, args.length());
|
| int const argc = args.length() - 1;
|
|
|
| + Handle<JSFunction> target = args.target<JSFunction>();
|
| + Handle<JSObject> target_global_proxy(target->global_proxy(), isolate);
|
| +
|
| + if (!HasAccessToContextForCreateDynamicFunction(isolate,
|
| + target_global_proxy)) {
|
| + isolate->CountUsage(v8::Isolate::kFunctionConstructorReturnedUndefined);
|
| + return isolate->factory()->undefined_value();
|
| + }
|
| +
|
| // Build the source string.
|
| Handle<String> source;
|
| {
|
| @@ -4125,7 +4174,7 @@ MaybeHandle<JSFunction> CreateDynamicFunction(
|
| Handle<String> param;
|
| ASSIGN_RETURN_ON_EXCEPTION(
|
| isolate, param, Object::ToString(isolate, args.at<Object>(i)),
|
| - JSFunction);
|
| + Object);
|
| param = String::Flatten(param);
|
| builder.AppendString(param);
|
| // If the formal parameters string include ) - an illegal
|
| @@ -4150,37 +4199,35 @@ MaybeHandle<JSFunction> CreateDynamicFunction(
|
| Handle<String> body;
|
| ASSIGN_RETURN_ON_EXCEPTION(
|
| isolate, body, Object::ToString(isolate, args.at<Object>(argc)),
|
| - JSFunction);
|
| + Object);
|
| builder.AppendString(body);
|
| }
|
| builder.AppendCString("\n})");
|
| - ASSIGN_RETURN_ON_EXCEPTION(isolate, source, builder.Finish(), JSFunction);
|
| + ASSIGN_RETURN_ON_EXCEPTION(isolate, source, builder.Finish(), Object);
|
|
|
| // The SyntaxError must be thrown after all the (observable) ToString
|
| // conversions are done.
|
| if (parenthesis_in_arg_string) {
|
| THROW_NEW_ERROR(isolate,
|
| NewSyntaxError(MessageTemplate::kParenthesisInArgString),
|
| - JSFunction);
|
| + Object);
|
| }
|
| }
|
|
|
| // Compile the string in the constructor and not a helper so that errors to
|
| // come from here.
|
| - Handle<JSFunction> target = args.target<JSFunction>();
|
| - Handle<JSObject> target_global_proxy(target->global_proxy(), isolate);
|
| Handle<JSFunction> function;
|
| {
|
| ASSIGN_RETURN_ON_EXCEPTION(
|
| isolate, function,
|
| CompileString(handle(target->native_context(), isolate), source,
|
| ONLY_SINGLE_FUNCTION_LITERAL),
|
| - JSFunction);
|
| + Object);
|
| Handle<Object> result;
|
| ASSIGN_RETURN_ON_EXCEPTION(
|
| isolate, result,
|
| Execution::Call(isolate, function, target_global_proxy, 0, nullptr),
|
| - JSFunction);
|
| + Object);
|
| function = Handle<JSFunction>::cast(result);
|
| function->shared()->set_name_should_print_as_anonymous(true);
|
| }
|
| @@ -4199,7 +4246,7 @@ MaybeHandle<JSFunction> CreateDynamicFunction(
|
| Handle<Map> initial_map;
|
| ASSIGN_RETURN_ON_EXCEPTION(
|
| isolate, initial_map,
|
| - JSFunction::GetDerivedMap(isolate, target, new_target), JSFunction);
|
| + JSFunction::GetDerivedMap(isolate, target, new_target), Object);
|
|
|
| Handle<SharedFunctionInfo> shared_info(function->shared(), isolate);
|
| Handle<Map> map = Map::AsLanguageMode(
|
| @@ -4218,7 +4265,7 @@ MaybeHandle<JSFunction> CreateDynamicFunction(
|
| // ES6 section 19.2.1.1 Function ( p1, p2, ... , pn, body )
|
| BUILTIN(FunctionConstructor) {
|
| HandleScope scope(isolate);
|
| - Handle<JSFunction> result;
|
| + Handle<Object> result;
|
| ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
|
| isolate, result, CreateDynamicFunction(isolate, args, "function"));
|
| return *result;
|
|
|