7223024658
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}
175 lines
6.5 KiB
C++
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
|