@@ -2480,6 +2480,63 @@ static void WriteString(const FunctionCallbackInfo<Value>& args) {
24802480 }
24812481}
24822482
2483+ static void WriteFileUtf8 (const FunctionCallbackInfo<Value>& args) {
2484+ // Fast C++ path for fs.writeFileSync(path, data) with utf8 encoding
2485+ // (file, data, options.flag, options.mode)
2486+
2487+ Environment* env = Environment::GetCurrent (args);
2488+ auto isolate = env->isolate ();
2489+
2490+ CHECK_GE (args.Length (), 4 );
2491+
2492+ CHECK (args[2 ]->IsInt32 ());
2493+ const int flags = args[2 ].As <Int32>()->Value ();
2494+
2495+ CHECK (args[3 ]->IsInt32 ());
2496+ const int mode = args[3 ].As <Int32>()->Value ();
2497+
2498+ uv_file file;
2499+ uv_fs_t req;
2500+
2501+ bool is_fd = args[0 ]->IsInt32 ();
2502+
2503+ // Check for file descriptor
2504+ if (is_fd) {
2505+ file = args[0 ].As <Int32>()->Value ();
2506+ } else {
2507+ BufferValue path (env->isolate (), args[0 ]);
2508+ CHECK_NOT_NULL (*path);
2509+ if (CheckOpenPermissions (env, path, flags).IsNothing ()) return ;
2510+
2511+ FS_SYNC_TRACE_BEGIN (open);
2512+ file = uv_fs_open (nullptr , &req, *path, flags, mode, nullptr );
2513+ FS_SYNC_TRACE_END (open);
2514+ if (req.result < 0 ) {
2515+ uv_fs_req_cleanup (&req);
2516+ // req will be cleaned up by scope leave.
2517+ return env->ThrowUVException (req.result , " open" , nullptr , path.out ());
2518+ }
2519+ }
2520+
2521+ auto defer_close = OnScopeLeave ([file, is_fd, &req]() {
2522+ if (!is_fd) {
2523+ FS_SYNC_TRACE_BEGIN (close);
2524+ CHECK_EQ (0 , uv_fs_close (nullptr , &req, file, nullptr ));
2525+ FS_SYNC_TRACE_END (close);
2526+ }
2527+ uv_fs_req_cleanup (&req);
2528+ });
2529+
2530+ CHECK (args[1 ]->IsString ());
2531+ node::Utf8Value value (isolate, args[1 ]);
2532+
2533+ uv_buf_t uvbuf = uv_buf_init (*value, value.length ());
2534+
2535+ FS_SYNC_TRACE_BEGIN (write);
2536+ uv_fs_write (nullptr , &req, file, &uvbuf, 1 , 0 , nullptr );
2537+ FS_SYNC_TRACE_END (write);
2538+ }
2539+
24832540
24842541/*
24852542 * Wrapper for read(2).
@@ -3393,6 +3450,7 @@ static void CreatePerIsolateProperties(IsolateData* isolate_data,
33933450 SetMethod (isolate, target, " writeBuffer" , WriteBuffer);
33943451 SetMethod (isolate, target, " writeBuffers" , WriteBuffers);
33953452 SetMethod (isolate, target, " writeString" , WriteString);
3453+ SetMethod (isolate, target, " writeFileUtf8" , WriteFileUtf8);
33963454 SetMethod (isolate, target, " realpath" , RealPath);
33973455 SetMethod (isolate, target, " copyFile" , CopyFile);
33983456 SetMethodNoSideEffect (isolate, target, " copyFileSync" , CopyFileSync);
@@ -3518,6 +3576,7 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
35183576 registry->Register (WriteBuffer);
35193577 registry->Register (WriteBuffers);
35203578 registry->Register (WriteString);
3579+ registry->Register (WriteFileUtf8);
35213580 registry->Register (RealPath);
35223581 registry->Register (CopyFile);
35233582 registry->Register (CopyFileSync);
0 commit comments