Repository: swc-project/swc
File: crates/swc_plugin_runner/src/transform_executor.rs (Rust)

Code before:
                let serialized_len = serialized_len
                    .try_into()
                    .expect("Should able to convert size");
                caller.alloc(serialized_len).unwrap_or_else(|_| {
                    panic!("Should able to allocate memory for the size of {serialized_len}")
                })
            },
        );

        let returned_ptr_result = self.instance.transform(
            guest_program_ptr.0,
            guest_program_ptr.1,
            unresolved_mark.as_u32(),
            should_enable_comments_proxy,
        )?;

        self.instance
            .caller()?
            .free(guest_program_ptr.0, guest_program_ptr.1)?;
        self.instance.cleanup()?;

        // Construct serialized struct from raw bytes.
        // Since we have finished transformation, it's safe to fetch the data from
        // Arc<Mutex<T>>
        drop(self.instance);
        let transformed_result = Arc::try_unwrap(self.transform_result).unwrap().into_inner();
        let ret = PluginSerializedBytes::from_bytes(transformed_result);

        let ret = if returned_ptr_result == 0 {
            Ok(ret)
        } else {
            let err: PluginError = ret.deserialize()?.into_inner();
            match err {
                PluginError::SizeInteropFailure(msg) => Err(anyhow!(
                    "Failed to convert pointer size to calculate: {msg}"
                )),
                PluginError::Deserialize(msg) | PluginError::Serialize(msg) => {
                    Err(anyhow!("{msg}"))
                }
                _ => Err(anyhow!(
                    "Unexpected error occurred while running plugin transform"
                )),
            }
        };

        ret
    }

    /**
     * Check compile-time version of AST schema between the plugin and
     * the host. Returns true if it's compatible, false otherwise.

Review comment (bug):
Using `unwrap()` on `Arc::try_unwrap()` will panic if there are other strong references to `transform_result`. While the comment suggests it's safe after transformation is finished, there's no guarantee that other parts of the code (e.g., the host environment setup in `setup_plugin_env_exports`) don't retain references. Consider using `expect()` with a descriptive message or `?` with proper error handling to make failures more debuggable.
```suggestion
        let transformed_result = Arc::try_unwrap(self.transform_result)
            .map_err(|_| anyhow!("Failed to unwrap Arc: other references to transform_result exist"))?
            .into_inner();
```

Code after:
                let serialized_len = serialized_len
                    .try_into()
                    .expect("Should able to convert size");
                caller.alloc(serialized_len).unwrap_or_else(|_| {
                    panic!("Should able to allocate memory for the size of {serialized_len}")
                })
            },
        );

        let returned_ptr_result = self.instance.transform(
            guest_program_ptr.0,
            guest_program_ptr.1,
            unresolved_mark.as_u32(),
            should_enable_comments_proxy,
        )?;

        self.instance
            .caller()?
            .free(guest_program_ptr.0, guest_program_ptr.1)?;
        self.instance.cleanup()?;

        // Construct serialized struct from raw bytes.
        // Since we have finished transformation, it's safe to fetch the data from
        // Arc<Mutex<T>>
        drop(self.instance);
        let transformed_result = Arc::try_unwrap(self.transform_result)
            .map_err(|_| {
                anyhow!("Failed to unwrap Arc: other references to transform_result exist")
            })?
            .into_inner();
        let ret = PluginSerializedBytes::from_bytes(transformed_result);

        let ret = if returned_ptr_result == 0 {
            Ok(ret)
        } else {
            let err: PluginError = ret.deserialize()?.into_inner();
            match err {
                PluginError::SizeInteropFailure(msg) => Err(anyhow!(
                    "Failed to convert pointer size to calculate: {msg}"
                )),
                PluginError::Deserialize(msg) | PluginError::Serialize(msg) => {
                    Err(anyhow!("{msg}"))
                }
                _ => Err(anyhow!(
                    "Unexpected error occurred while running plugin transform"
                )),
            }
        };

        ret
    }