Remove JS natives support, step 1
The natives blob is deprecated and will be removed in the next release. This commit does two things, 1. it disables the v8_extra_library_files gn argument which will make building natives_blob.bin through gn impossible; 2. it marks API functions associated with the natives blob as V8_DEPRECATE_SOON. Embedders should remove any uses of SetNativesDataBlob and replace all calls to InitializeExternalStartupData(const char*, const char*) with the new function InitializeExternalStartupDataFromFile(const char*) Step 2 is to mark API functions as V8_DEPRECATED. Step 3, in the next V8 release, is to remove these functions and all other natives support in V8. Bug: v8:7624 Change-Id: I745e96c60204a9b94d9240be65dd59bb9bdd0699 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1824944 Commit-Queue: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Reviewed-by: Ulan Degenbaev <ulan@chromium.org> Auto-Submit: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#64080}
This commit is contained in:
parent
65d05bef39
commit
28a9dc2b81
8
BUILD.gn
8
BUILD.gn
@ -156,9 +156,7 @@ declare_args() {
|
||||
|
||||
# List of extra files to snapshot. They will be snapshotted in order so
|
||||
# if files export symbols used by later files, they should go first.
|
||||
#
|
||||
# This default is used by cctests. Projects using V8 will want to override.
|
||||
v8_extra_library_files = [ "//test/cctest/test-extra.js" ]
|
||||
v8_extra_library_files = []
|
||||
|
||||
v8_enable_gdbjit =
|
||||
((v8_current_cpu == "x86" || v8_current_cpu == "x64") &&
|
||||
@ -258,6 +256,10 @@ assert(
|
||||
assert(v8_use_snapshot || !v8_enable_shared_ro_heap,
|
||||
"Shared read-only heap requires snapshot")
|
||||
|
||||
assert(v8_extra_library_files == [],
|
||||
"v8_extra_library_files is no longer supported. Consider implementing " +
|
||||
"custom API in C++ instead.")
|
||||
|
||||
v8_random_seed = "314159265"
|
||||
v8_toolset_for_shell = "host"
|
||||
|
||||
|
12
include/v8.h
12
include/v8.h
@ -9004,7 +9004,9 @@ class V8_EXPORT V8 {
|
||||
* handled entirely on the embedders' side.
|
||||
* - The call will abort if the data is invalid.
|
||||
*/
|
||||
static void SetNativesDataBlob(StartupData* startup_blob);
|
||||
V8_DEPRECATE_SOON(
|
||||
"The natives blob is deprecated (https://crbug.com/v8/7624).",
|
||||
static void SetNativesDataBlob(StartupData* startup_blob));
|
||||
static void SetSnapshotDataBlob(StartupData* startup_blob);
|
||||
|
||||
/** Set the callback to invoke in case of Dcheck failures. */
|
||||
@ -9100,8 +9102,12 @@ class V8_EXPORT V8 {
|
||||
* not perform any file IO.
|
||||
*/
|
||||
static void InitializeExternalStartupData(const char* directory_path);
|
||||
static void InitializeExternalStartupData(const char* natives_blob,
|
||||
const char* snapshot_blob);
|
||||
V8_DEPRECATE_SOON(
|
||||
"The natives blob is deprecated (https://crbug.com/v8/7624).",
|
||||
static void InitializeExternalStartupData(const char* natives_blob,
|
||||
const char* snapshot_blob));
|
||||
static void InitializeExternalStartupDataFromFile(const char* snapshot_blob);
|
||||
|
||||
/**
|
||||
* Sets the v8::Platform to use. This should be invoked before V8 is
|
||||
* initialized.
|
||||
|
@ -5723,6 +5723,11 @@ void v8::V8::InitializeExternalStartupData(const char* natives_blob,
|
||||
i::InitializeExternalStartupData(natives_blob, snapshot_blob);
|
||||
}
|
||||
|
||||
// static
|
||||
void v8::V8::InitializeExternalStartupDataFromFile(const char* snapshot_blob) {
|
||||
i::InitializeExternalStartupDataFromFile(snapshot_blob);
|
||||
}
|
||||
|
||||
const char* v8::V8::GetVersion() { return i::Version::GetVersion(); }
|
||||
|
||||
template <typename ObjectType>
|
||||
|
@ -3001,9 +3001,6 @@ bool Shell::SetOptions(int argc, char* argv[]) {
|
||||
options.icu_locale = argv[i] + 13;
|
||||
argv[i] = nullptr;
|
||||
#ifdef V8_USE_EXTERNAL_STARTUP_DATA
|
||||
} else if (strncmp(argv[i], "--natives_blob=", 15) == 0) {
|
||||
options.natives_blob = argv[i] + 15;
|
||||
argv[i] = nullptr;
|
||||
} else if (strncmp(argv[i], "--snapshot_blob=", 16) == 0) {
|
||||
options.snapshot_blob = argv[i] + 16;
|
||||
argv[i] = nullptr;
|
||||
@ -3592,9 +3589,8 @@ int Shell::Main(int argc, char* argv[]) {
|
||||
}
|
||||
v8::V8::InitializePlatform(g_platform.get());
|
||||
v8::V8::Initialize();
|
||||
if (options.natives_blob || options.snapshot_blob) {
|
||||
v8::V8::InitializeExternalStartupData(options.natives_blob,
|
||||
options.snapshot_blob);
|
||||
if (options.snapshot_blob) {
|
||||
v8::V8::InitializeExternalStartupDataFromFile(options.snapshot_blob);
|
||||
} else {
|
||||
v8::V8::InitializeExternalStartupData(argv[0]);
|
||||
}
|
||||
|
@ -285,7 +285,6 @@ class ShellOptions {
|
||||
SourceGroup* isolate_sources = nullptr;
|
||||
const char* icu_data_file = nullptr;
|
||||
const char* icu_locale = nullptr;
|
||||
const char* natives_blob = nullptr;
|
||||
const char* snapshot_blob = nullptr;
|
||||
bool trace_enabled = false;
|
||||
const char* trace_path = nullptr;
|
||||
|
@ -38,6 +38,10 @@ void FreeStartupData() {
|
||||
DeleteStartupData(&g_snapshot);
|
||||
}
|
||||
|
||||
// TODO(jgruber): Rename to FreeStartupData once natives support has been
|
||||
// removed (https://crbug.com/v8/7624).
|
||||
void FreeStartupDataSnapshotOnly() { DeleteStartupData(&g_snapshot); }
|
||||
|
||||
void Load(const char* blob_file, v8::StartupData* startup_data,
|
||||
void (*setter_fn)(v8::StartupData*)) {
|
||||
ClearStartupData(startup_data);
|
||||
@ -67,7 +71,7 @@ void Load(const char* blob_file, v8::StartupData* startup_data,
|
||||
}
|
||||
|
||||
void LoadFromFiles(const char* natives_blob, const char* snapshot_blob) {
|
||||
Load(natives_blob, &g_natives, v8::V8::SetNativesDataBlob);
|
||||
Load(natives_blob, &g_natives, i::V8::SetNativesBlob);
|
||||
Load(snapshot_blob, &g_snapshot, v8::V8::SetSnapshotDataBlob);
|
||||
|
||||
atexit(&FreeStartupData);
|
||||
@ -101,5 +105,12 @@ void InitializeExternalStartupData(const char* natives_blob,
|
||||
#endif // V8_USE_EXTERNAL_STARTUP_DATA
|
||||
}
|
||||
|
||||
void InitializeExternalStartupDataFromFile(const char* snapshot_blob) {
|
||||
#ifdef V8_USE_EXTERNAL_STARTUP_DATA
|
||||
Load(snapshot_blob, &g_snapshot, v8::V8::SetSnapshotDataBlob);
|
||||
atexit(&FreeStartupDataSnapshotOnly);
|
||||
#endif // V8_USE_EXTERNAL_STARTUP_DATA
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
@ -21,6 +21,7 @@ void InitializeExternalStartupData(const char* directory_path);
|
||||
|
||||
void InitializeExternalStartupData(const char* natives_blob,
|
||||
const char* snapshot_blob);
|
||||
void InitializeExternalStartupDataFromFile(const char* snapshot_blob);
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
@ -24478,280 +24478,6 @@ TEST(SealHandleScopeNested) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void ExtrasBindingTestRuntimeFunction(
|
||||
const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
CHECK_EQ(
|
||||
3,
|
||||
args[0]->Int32Value(args.GetIsolate()->GetCurrentContext()).FromJust());
|
||||
args.GetReturnValue().Set(v8_num(7));
|
||||
}
|
||||
|
||||
TEST(ExtrasFunctionSource) {
|
||||
v8::Isolate* isolate = CcTest::isolate();
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
LocalContext env;
|
||||
|
||||
v8::Local<v8::Object> binding = env->GetExtrasBindingObject();
|
||||
|
||||
// Functions defined in extras do not expose source code.
|
||||
auto func = binding->Get(env.local(), v8_str("testFunctionToString"))
|
||||
.ToLocalChecked()
|
||||
.As<v8::Function>();
|
||||
auto undefined = v8::Undefined(isolate);
|
||||
auto result = func->Call(env.local(), undefined, 0, {})
|
||||
.ToLocalChecked()
|
||||
.As<v8::String>();
|
||||
CHECK(result->StrictEquals(v8_str("function foo() { [native code] }")));
|
||||
|
||||
// Functions defined in extras do not show up in the stack trace.
|
||||
auto wrapper = binding->Get(env.local(), v8_str("testStackTrace"))
|
||||
.ToLocalChecked()
|
||||
.As<v8::Function>();
|
||||
CHECK(env->Global()->Set(env.local(), v8_str("wrapper"), wrapper).FromJust());
|
||||
ExpectString(
|
||||
"function f(x) { return wrapper(x) }"
|
||||
"function g() { return new Error().stack; }"
|
||||
"f(g)",
|
||||
"Error\n"
|
||||
" at g (<anonymous>:1:58)\n"
|
||||
" at f (<anonymous>:1:24)\n"
|
||||
" at <anonymous>:1:78");
|
||||
}
|
||||
|
||||
TEST(ExtrasBindingObject) {
|
||||
v8::Isolate* isolate = CcTest::isolate();
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
LocalContext env;
|
||||
|
||||
// standalone.gypi ensures we include the test-extra.js file, which should
|
||||
// export the tested functions.
|
||||
v8::Local<v8::Object> binding = env->GetExtrasBindingObject();
|
||||
|
||||
auto func = binding->Get(env.local(), v8_str("testExtraShouldReturnFive"))
|
||||
.ToLocalChecked()
|
||||
.As<v8::Function>();
|
||||
auto undefined = v8::Undefined(isolate);
|
||||
auto result = func->Call(env.local(), undefined, 0, {})
|
||||
.ToLocalChecked()
|
||||
.As<v8::Number>();
|
||||
CHECK_EQ(5, result->Int32Value(env.local()).FromJust());
|
||||
|
||||
v8::Local<v8::FunctionTemplate> runtimeFunction =
|
||||
v8::FunctionTemplate::New(isolate, ExtrasBindingTestRuntimeFunction);
|
||||
binding->Set(env.local(), v8_str("runtime"),
|
||||
runtimeFunction->GetFunction(env.local()).ToLocalChecked())
|
||||
.FromJust();
|
||||
func = binding->Get(env.local(), v8_str("testExtraShouldCallToRuntime"))
|
||||
.ToLocalChecked()
|
||||
.As<v8::Function>();
|
||||
result = func->Call(env.local(), undefined, 0, {})
|
||||
.ToLocalChecked()
|
||||
.As<v8::Number>();
|
||||
CHECK_EQ(7, result->Int32Value(env.local()).FromJust());
|
||||
}
|
||||
|
||||
|
||||
TEST(ExtrasCreatePromise) {
|
||||
i::FLAG_allow_natives_syntax = true;
|
||||
LocalContext context;
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
|
||||
LocalContext env;
|
||||
v8::Local<v8::Object> binding = env->GetExtrasBindingObject();
|
||||
|
||||
auto func = binding->Get(env.local(), v8_str("testCreatePromise"))
|
||||
.ToLocalChecked()
|
||||
.As<v8::Function>();
|
||||
CHECK(env->Global()->Set(env.local(), v8_str("func"), func).FromJust());
|
||||
|
||||
auto promise = CompileRun(
|
||||
"%PrepareFunctionForOptimization(func);\n"
|
||||
"func();\n"
|
||||
"func();\n"
|
||||
"%OptimizeFunctionOnNextCall(func);\n"
|
||||
"func()\n")
|
||||
.As<v8::Promise>();
|
||||
CHECK_EQ(v8::Promise::kPending, promise->State());
|
||||
}
|
||||
|
||||
TEST(ExtrasCreatePromiseWithParent) {
|
||||
i::FLAG_allow_natives_syntax = true;
|
||||
LocalContext context;
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
|
||||
LocalContext env;
|
||||
v8::Local<v8::Object> binding = env->GetExtrasBindingObject();
|
||||
|
||||
auto func = binding->Get(env.local(), v8_str("testCreatePromiseWithParent"))
|
||||
.ToLocalChecked()
|
||||
.As<v8::Function>();
|
||||
CHECK(env->Global()->Set(env.local(), v8_str("func"), func).FromJust());
|
||||
|
||||
auto promise = CompileRun(
|
||||
"var parent = new Promise((a, b) => {});\n"
|
||||
"%PrepareFunctionForOptimization(func);\n"
|
||||
"func(parent);\n"
|
||||
"func(parent);\n"
|
||||
"%OptimizeFunctionOnNextCall(func);\n"
|
||||
"func(parent)\n")
|
||||
.As<v8::Promise>();
|
||||
CHECK_EQ(v8::Promise::kPending, promise->State());
|
||||
}
|
||||
|
||||
TEST(ExtrasRejectPromise) {
|
||||
i::FLAG_allow_natives_syntax = true;
|
||||
LocalContext context;
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
|
||||
LocalContext env;
|
||||
v8::Local<v8::Object> binding = env->GetExtrasBindingObject();
|
||||
|
||||
auto func = binding->Get(env.local(), v8_str("testRejectPromise"))
|
||||
.ToLocalChecked()
|
||||
.As<v8::Function>();
|
||||
CHECK(env->Global()->Set(env.local(), v8_str("func"), func).FromJust());
|
||||
|
||||
auto rejected_promise = CompileRun(
|
||||
"function newPromise() {\n"
|
||||
" return new Promise((a, b) => {});\n"
|
||||
"}\n"
|
||||
"%PrepareFunctionForOptimization(func);\n"
|
||||
"func(newPromise(), 1);\n"
|
||||
"func(newPromise(), 1);\n"
|
||||
"%OptimizeFunctionOnNextCall(func);\n"
|
||||
"var promise = newPromise();\n"
|
||||
"func(promise, 1);\n"
|
||||
"promise;\n")
|
||||
.As<v8::Promise>();
|
||||
CHECK_EQ(v8::Promise::kRejected, rejected_promise->State());
|
||||
CHECK_EQ(1, rejected_promise->Result()->Int32Value(env.local()).FromJust());
|
||||
}
|
||||
|
||||
TEST(ExtrasResolvePromise) {
|
||||
i::FLAG_allow_natives_syntax = true;
|
||||
LocalContext context;
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
|
||||
LocalContext env;
|
||||
v8::Local<v8::Object> binding = env->GetExtrasBindingObject();
|
||||
|
||||
auto func = binding->Get(env.local(), v8_str("testResolvePromise"))
|
||||
.ToLocalChecked()
|
||||
.As<v8::Function>();
|
||||
CHECK(env->Global()->Set(env.local(), v8_str("func"), func).FromJust());
|
||||
|
||||
auto pending_promise = CompileRun(
|
||||
"function newPromise() {\n"
|
||||
" return new Promise((a, b) => {});\n"
|
||||
"}\n"
|
||||
"%PrepareFunctionForOptimization(func);\n"
|
||||
"func(newPromise(), newPromise());\n"
|
||||
"func(newPromise(), newPromise());\n"
|
||||
"%OptimizeFunctionOnNextCall(func);\n"
|
||||
"var promise = newPromise();\n"
|
||||
"func(promise, newPromise());\n"
|
||||
"promise;\n")
|
||||
.As<v8::Promise>();
|
||||
CHECK_EQ(v8::Promise::kPending, pending_promise->State());
|
||||
|
||||
auto fulfilled_promise = CompileRun(
|
||||
"function newPromise() {\n"
|
||||
" return new Promise((a, b) => {});\n"
|
||||
"}\n"
|
||||
"%PrepareFunctionForOptimization(func);\n"
|
||||
"func(newPromise(), 1);\n"
|
||||
"func(newPromise(), 1);\n"
|
||||
"%OptimizeFunctionOnNextCall(func);\n"
|
||||
"var promise = newPromise();\n"
|
||||
"func(promise, 1);\n"
|
||||
"promise;\n")
|
||||
.As<v8::Promise>();
|
||||
CHECK_EQ(v8::Promise::kFulfilled, fulfilled_promise->State());
|
||||
CHECK_EQ(1, fulfilled_promise->Result()->Int32Value(env.local()).FromJust());
|
||||
}
|
||||
|
||||
TEST(ExtrasUtilsObject) {
|
||||
LocalContext context;
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
|
||||
LocalContext env;
|
||||
v8::Local<v8::Object> binding = env->GetExtrasBindingObject();
|
||||
|
||||
auto func = binding->Get(env.local(), v8_str("testExtraCanUseUtils"))
|
||||
.ToLocalChecked()
|
||||
.As<v8::Function>();
|
||||
auto undefined = v8::Undefined(isolate);
|
||||
auto result = func->Call(env.local(), undefined, 0, {})
|
||||
.ToLocalChecked()
|
||||
.As<v8::Object>();
|
||||
|
||||
auto private_symbol = result->Get(env.local(), v8_str("privateSymbol"))
|
||||
.ToLocalChecked()
|
||||
.As<v8::Symbol>();
|
||||
i::Handle<i::Symbol> ips = v8::Utils::OpenHandle(*private_symbol);
|
||||
CHECK(ips->IsPrivate());
|
||||
|
||||
CompileRun("var result = 0; function store(x) { result = x; }");
|
||||
auto store = CompileRun("store").As<v8::Function>();
|
||||
|
||||
auto fulfilled_promise = result->Get(env.local(), v8_str("fulfilledPromise"))
|
||||
.ToLocalChecked()
|
||||
.As<v8::Promise>();
|
||||
fulfilled_promise->Then(env.local(), store).ToLocalChecked();
|
||||
isolate->RunMicrotasks();
|
||||
CHECK_EQ(1, CompileRun("result")->Int32Value(env.local()).FromJust());
|
||||
|
||||
auto fulfilled_promise_2 =
|
||||
result->Get(env.local(), v8_str("fulfilledPromise2"))
|
||||
.ToLocalChecked()
|
||||
.As<v8::Promise>();
|
||||
fulfilled_promise_2->Then(env.local(), store).ToLocalChecked();
|
||||
isolate->RunMicrotasks();
|
||||
CHECK_EQ(2, CompileRun("result")->Int32Value(env.local()).FromJust());
|
||||
|
||||
auto rejected_promise = result->Get(env.local(), v8_str("rejectedPromise"))
|
||||
.ToLocalChecked()
|
||||
.As<v8::Promise>();
|
||||
rejected_promise->Catch(env.local(), store).ToLocalChecked();
|
||||
isolate->RunMicrotasks();
|
||||
CHECK_EQ(3, CompileRun("result")->Int32Value(env.local()).FromJust());
|
||||
|
||||
auto rejected_but_handled_promise =
|
||||
result->Get(env.local(), v8_str("rejectedButHandledPromise"))
|
||||
.ToLocalChecked()
|
||||
.As<v8::Promise>();
|
||||
CHECK(rejected_but_handled_promise->HasHandler());
|
||||
|
||||
auto promise_states = result->Get(env.local(), v8_str("promiseStates"))
|
||||
.ToLocalChecked()
|
||||
.As<v8::String>();
|
||||
String::Utf8Value promise_states_string(isolate, promise_states);
|
||||
CHECK_EQ(0, strcmp(*promise_states_string, "pending fulfilled rejected"));
|
||||
|
||||
auto promise_is_promise = result->Get(env.local(), v8_str("promiseIsPromise"))
|
||||
.ToLocalChecked()
|
||||
.As<v8::Boolean>();
|
||||
CHECK_EQ(true, promise_is_promise->Value());
|
||||
|
||||
auto thenable_is_promise =
|
||||
result->Get(env.local(), v8_str("thenableIsPromise"))
|
||||
.ToLocalChecked()
|
||||
.As<v8::Boolean>();
|
||||
CHECK_EQ(false, thenable_is_promise->Value());
|
||||
|
||||
auto uncurry_this = result->Get(env.local(), v8_str("uncurryThis"))
|
||||
.ToLocalChecked()
|
||||
.As<v8::Boolean>();
|
||||
CHECK_EQ(true, uncurry_this->Value());
|
||||
}
|
||||
|
||||
|
||||
TEST(Map) {
|
||||
v8::Isolate* isolate = CcTest::isolate();
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
|
@ -4509,7 +4509,7 @@ UNINITIALIZED_TEST(LoadedAtStartupScripts) {
|
||||
}
|
||||
}
|
||||
CHECK_EQ(count_by_type[i::Script::TYPE_NATIVE], 0);
|
||||
CHECK_EQ(count_by_type[i::Script::TYPE_EXTENSION], 2);
|
||||
CHECK_EQ(count_by_type[i::Script::TYPE_EXTENSION], 1);
|
||||
CHECK_EQ(count_by_type[i::Script::TYPE_NORMAL], 1);
|
||||
CHECK_EQ(count_by_type[i::Script::TYPE_WASM], 0);
|
||||
CHECK_EQ(count_by_type[i::Script::TYPE_INSPECTOR], 0);
|
||||
|
@ -265,7 +265,9 @@ def BuildMetadata(sources, source_bytes, native_type):
|
||||
|
||||
metadata = {
|
||||
"builtin_count": len(sources.modules),
|
||||
"sources_declaration": SOURCES_DECLARATION % ToCArray(source_bytes),
|
||||
"sources_declaration":
|
||||
SOURCES_DECLARATION % ToCArray(
|
||||
source_bytes if len(source_bytes) != 0 else "\0"),
|
||||
"total_length": total_length,
|
||||
"get_index_cases": "".join(get_index_cases),
|
||||
"get_script_source_cases": "".join(get_script_source_cases),
|
||||
|
Loading…
Reference in New Issue
Block a user