v8/src/builtins/builtins-console.cc
jgruber 7223024658 [factory] Simplify JSFunction creation
There's three common situations in which we need to create JSFunction
objects.  1) from the compiler, 2) from tests, and 3) everything else
(mostly during bootstrapping).

This is an attempt to simplify case 3), which previously relied on
several Factory::NewFunction overloads where it was not clear how the
semantics of each overload differed.

This CL removes all but one overload, and packs arguments into a new
NewFunctionArgs helper class.

It also removes the hacks around
SFI::set_lazy_deserialization_builtin_id by explicitly passing
builtin_id into Factory::NewSharedFunctionInfo.

Drive-by-fix: Properly set is_constructor hint in
SimpleCreateSharedFunctionInfo.

Bug: v8:6624
Cq-Include-Trybots: master.tryserver.chromium.linux:linux_chromium_rel_ng
Change-Id: Ica94d95e72e443055db5e7ff9e8cdf4115201ef1
Reviewed-on: https://chromium-review.googlesource.com/757094
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: Michael Starzinger <mstarzinger@chromium.org>
Reviewed-by: Andreas Haas <ahaas@chromium.org>
Cr-Commit-Position: refs/heads/master@{#49224}
2017-11-08 13:52:13 +00:00

175 lines
6.5 KiB
C++

// 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.
#include "src/builtins/builtins-utils.h"
#include "src/builtins/builtins.h"
#include "src/api.h"
#include "src/debug/interface-types.h"
#include "src/objects-inl.h"
namespace v8 {
namespace internal {
// -----------------------------------------------------------------------------
// Console
#define CONSOLE_METHOD_LIST(V) \
V(Debug, debug) \
V(Error, error) \
V(Info, info) \
V(Log, log) \
V(Warn, warn) \
V(Dir, dir) \
V(DirXml, dirXml) \
V(Table, table) \
V(Trace, trace) \
V(Group, group) \
V(GroupCollapsed, groupCollapsed) \
V(GroupEnd, groupEnd) \
V(Clear, clear) \
V(Count, count) \
V(Assert, assert) \
V(MarkTimeline, markTimeline) \
V(Profile, profile) \
V(ProfileEnd, profileEnd) \
V(Timeline, timeline) \
V(TimelineEnd, timelineEnd)
namespace {
void ConsoleCall(
Isolate* isolate, internal::BuiltinArguments& args,
void (debug::ConsoleDelegate::*func)(const v8::debug::ConsoleCallArguments&,
const v8::debug::ConsoleContext&)) {
CHECK(!isolate->has_pending_exception());
CHECK(!isolate->has_scheduled_exception());
if (!isolate->console_delegate()) return;
HandleScope scope(isolate);
debug::ConsoleCallArguments wrapper(args);
Handle<Object> context_id_obj = JSObject::GetDataProperty(
args.target(), isolate->factory()->console_context_id_symbol());
int context_id =
context_id_obj->IsSmi() ? Handle<Smi>::cast(context_id_obj)->value() : 0;
Handle<Object> context_name_obj = JSObject::GetDataProperty(
args.target(), isolate->factory()->console_context_name_symbol());
Handle<String> context_name = context_name_obj->IsString()
? Handle<String>::cast(context_name_obj)
: isolate->factory()->anonymous_string();
(isolate->console_delegate()->*func)(
wrapper,
v8::debug::ConsoleContext(context_id, Utils::ToLocal(context_name)));
}
void LogTimerEvent(Isolate* isolate, BuiltinArguments args,
Logger::StartEnd se) {
if (!isolate->logger()->is_logging()) return;
HandleScope scope(isolate);
std::unique_ptr<char[]> name;
const char* raw_name = "default";
if (args.length() > 1 && args[1]->IsString()) {
// Try converting the first argument to a string.
name = args.at<String>(1)->ToCString();
raw_name = name.get();
}
LOG(isolate, TimerEvent(se, raw_name));
}
} // namespace
#define CONSOLE_BUILTIN_IMPLEMENTATION(call, name) \
BUILTIN(Console##call) { \
ConsoleCall(isolate, args, &debug::ConsoleDelegate::call); \
RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); \
return isolate->heap()->undefined_value(); \
}
CONSOLE_METHOD_LIST(CONSOLE_BUILTIN_IMPLEMENTATION)
#undef CONSOLE_BUILTIN_IMPLEMENTATION
BUILTIN(ConsoleTime) {
LogTimerEvent(isolate, args, Logger::START);
ConsoleCall(isolate, args, &debug::ConsoleDelegate::Time);
RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
return isolate->heap()->undefined_value();
}
BUILTIN(ConsoleTimeEnd) {
LogTimerEvent(isolate, args, Logger::END);
ConsoleCall(isolate, args, &debug::ConsoleDelegate::TimeEnd);
RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
return isolate->heap()->undefined_value();
}
BUILTIN(ConsoleTimeStamp) {
LogTimerEvent(isolate, args, Logger::STAMP);
ConsoleCall(isolate, args, &debug::ConsoleDelegate::TimeStamp);
RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
return isolate->heap()->undefined_value();
}
namespace {
void InstallContextFunction(Handle<JSObject> target, const char* name,
Builtins::Name builtin_id, int context_id,
Handle<Object> context_name) {
Factory* const factory = target->GetIsolate()->factory();
Handle<Code> code(target->GetIsolate()->builtins()->builtin(builtin_id));
Handle<String> name_string =
Name::ToFunctionName(factory->InternalizeUtf8String(name))
.ToHandleChecked();
NewFunctionArgs args = NewFunctionArgs::ForBuiltinWithoutPrototype(
name_string, code, builtin_id, i::LanguageMode::kSloppy);
Handle<JSFunction> fun = factory->NewFunction(args);
fun->shared()->set_native(true);
fun->shared()->DontAdaptArguments();
fun->shared()->set_length(1);
JSObject::AddProperty(fun, factory->console_context_id_symbol(),
handle(Smi::FromInt(context_id), target->GetIsolate()),
NONE);
if (context_name->IsString()) {
JSObject::AddProperty(fun, factory->console_context_name_symbol(),
context_name, NONE);
}
JSObject::AddProperty(target, name_string, fun, NONE);
}
} // namespace
BUILTIN(ConsoleContext) {
HandleScope scope(isolate);
Factory* const factory = isolate->factory();
Handle<String> name = factory->InternalizeUtf8String("Context");
NewFunctionArgs arguments = NewFunctionArgs::ForFunctionWithoutCode(
name, isolate->sloppy_function_map(), LanguageMode::kSloppy);
Handle<JSFunction> cons = factory->NewFunction(arguments);
Handle<JSObject> prototype = factory->NewJSObject(isolate->object_function());
JSFunction::SetPrototype(cons, prototype);
Handle<JSObject> context = factory->NewJSObject(cons, TENURED);
DCHECK(context->IsJSObject());
int id = isolate->last_console_context_id() + 1;
isolate->set_last_console_context_id(id);
#define CONSOLE_BUILTIN_SETUP(call, name) \
InstallContextFunction(context, #name, Builtins::kConsole##call, id, \
args.at(1));
CONSOLE_METHOD_LIST(CONSOLE_BUILTIN_SETUP)
#undef CONSOLE_BUILTIN_SETUP
InstallContextFunction(context, "time", Builtins::kConsoleTime, id,
args.at(1));
InstallContextFunction(context, "timeEnd", Builtins::kConsoleTimeEnd, id,
args.at(1));
InstallContextFunction(context, "timeStamp", Builtins::kConsoleTimeStamp, id,
args.at(1));
return *context;
}
#undef CONSOLE_METHOD_LIST
} // namespace internal
} // namespace v8