@@ -2797,6 +2797,51 @@ static void Mkdtemp(const FunctionCallbackInfo<Value>& args) {
27972797 }
27982798}
27992799
2800+ static void GetFormatOfExtensionlessFile (
2801+ const FunctionCallbackInfo<Value>& args) {
2802+ CHECK_EQ (args.Length (), 1 );
2803+ CHECK (args[0 ]->IsString ());
2804+
2805+ Environment* env = Environment::GetCurrent (args);
2806+ node::Utf8Value input (args.GetIsolate (), args[0 ]);
2807+
2808+ THROW_IF_INSUFFICIENT_PERMISSIONS (
2809+ env, permission::PermissionScope::kFileSystemRead , input.ToStringView ());
2810+
2811+ uv_fs_t req;
2812+ FS_SYNC_TRACE_BEGIN (open)
2813+ uv_file file = uv_fs_open (nullptr , &req, input.out (), O_RDONLY, 0 , nullptr );
2814+ FS_SYNC_TRACE_END (open);
2815+
2816+ if (req.result < 0 ) {
2817+ return args.GetReturnValue ().Set (EXTENSIONLESS_FORMAT_JAVASCRIPT);
2818+ }
2819+
2820+ auto cleanup = OnScopeLeave ([&req, &file]() {
2821+ FS_SYNC_TRACE_BEGIN (close);
2822+ CHECK_EQ (0 , uv_fs_close (nullptr , &req, file, nullptr ));
2823+ FS_SYNC_TRACE_END (close);
2824+ uv_fs_req_cleanup (&req);
2825+ });
2826+
2827+ char buffer[4 ];
2828+ uv_buf_t buf = uv_buf_init (buffer, sizeof (buffer));
2829+ int err = uv_fs_read (nullptr , &req, file, &buf, 1 , 0 , nullptr );
2830+
2831+ if (err < 0 ) {
2832+ return args.GetReturnValue ().Set (EXTENSIONLESS_FORMAT_JAVASCRIPT);
2833+ }
2834+
2835+ // We do this by taking advantage of the fact that all Wasm files start with
2836+ // the header `0x00 0x61 0x73 0x6d`
2837+ if (buffer[0 ] == 0x00 && buffer[1 ] == 0x61 && buffer[2 ] == 0x73 &&
2838+ buffer[3 ] == 0x6d ) {
2839+ return args.GetReturnValue ().Set (EXTENSIONLESS_FORMAT_WASM);
2840+ }
2841+
2842+ return args.GetReturnValue ().Set (EXTENSIONLESS_FORMAT_JAVASCRIPT);
2843+ }
2844+
28002845static bool FileURLToPath (
28012846 Environment* env,
28022847 const ada::url_aggregator& file_url,
@@ -3209,6 +3254,10 @@ static void CreatePerIsolateProperties(IsolateData* isolate_data,
32093254 Local<ObjectTemplate> target) {
32103255 Isolate* isolate = isolate_data->isolate ();
32113256
3257+ SetMethod (isolate,
3258+ target,
3259+ " getFormatOfExtensionlessFile" ,
3260+ GetFormatOfExtensionlessFile);
32123261 SetMethod (isolate, target, " access" , Access);
32133262 SetMethod (isolate, target, " close" , Close);
32143263 SetMethod (isolate, target, " existsSync" , ExistsSync);
@@ -3329,6 +3378,7 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
33293378 StatWatcher::RegisterExternalReferences (registry);
33303379 BindingData::RegisterExternalReferences (registry);
33313380
3381+ registry->Register (GetFormatOfExtensionlessFile);
33323382 registry->Register (Close);
33333383 registry->Register (ExistsSync);
33343384 registry->Register (Open);
0 commit comments