From 3fa9fb36ed204c6fc4a9276d47fbee3b1acff42a Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Sun, 15 Nov 2020 00:07:52 +0100 Subject: [PATCH] Fix runtime assert when hashing module object (#522) The blanket `std::hash::Hash` impl for instances of `v8::Data` invokes `v8::internal::Object::GetHash()` but that crashes for `v8::Module` objects. Use a custom impl that calls `v8::Module::get_identity_hash()`. Fixes the following runtime assertion: # Fatal error in ../../../v8/src/objects/objects-inl.h, line 1043 # Debug check failed: object.IsJSReceiver(). Refs: https://github.com/denoland/deno/pull/8354#discussion_r522157813 --- src/data.rs | 1 - src/module.rs | 8 ++++++++ tests/test_api.rs | 3 +++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/data.rs b/src/data.rs index 556eacc1..e56c1dc3 100644 --- a/src/data.rs +++ b/src/data.rs @@ -348,7 +348,6 @@ pub struct Module(Opaque); impl_deref! { Data for Module } impl_try_from! { Data for Module if d => d.is_module() } impl_eq! { for Module } -impl_hash! { for Module } impl_partial_eq! { Data for Module use identity } impl_partial_eq! { Module for Module use identity } diff --git a/src/module.rs b/src/module.rs index 1adf1e07..5083dae0 100644 --- a/src/module.rs +++ b/src/module.rs @@ -1,4 +1,6 @@ use std::convert::TryInto; +use std::hash::Hash; +use std::hash::Hasher; use std::mem::MaybeUninit; use std::ptr::null; @@ -371,3 +373,9 @@ impl Module { .into() } } + +impl Hash for Module { + fn hash(&self, state: &mut H) { + state.write_i32(self.get_identity_hash()); + } +} diff --git a/tests/test_api.rs b/tests/test_api.rs index 3671ab40..e7790296 100644 --- a/tests/test_api.rs +++ b/tests/test_api.rs @@ -4,8 +4,10 @@ extern crate lazy_static; use std::any::type_name; +use std::collections::hash_map::DefaultHasher; use std::convert::{Into, TryFrom, TryInto}; use std::ffi::c_void; +use std::hash::Hash; use std::ptr::NonNull; use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::Mutex; @@ -1989,6 +1991,7 @@ fn module_evaluation() { assert!(module.is_source_text_module()); assert!(!module.is_synthetic_module()); assert_eq!(v8::ModuleStatus::Uninstantiated, module.get_status()); + module.hash(&mut DefaultHasher::new()); // Should not crash. let result = module .instantiate_module(scope, compile_specifier_as_module_resolve_callback);