mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 18:59:04 +08:00
Impl Eq+Hash for ConstantData, make CodeInfo.constants an IndexSet
This commit is contained in:
4 files changed
+56
-11
No files matched your search
Generated
+1
-1
@@ -1101,7 +1101,7 @@ checksum = "8dd5a6d5999d9907cda8ed67bbd137d3af8085216c2ac62de5be860bd41f304a"
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.2"
|
||||
source = "git+https://github.com/coolreader18/parking_lot?branch=remutex-is_owned#391cf555e94c05450cea2e88b42c95c6631ab163"
|
||||
source = "git+https://github.com/Amanieu/parking_lot#2b3032f95d4aa5b1ccdf41b937c60603f569763c"
|
||||
dependencies = [
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
+50
-4
@@ -11,7 +11,7 @@ use num_bigint::BigInt;
|
||||
use num_complex::Complex64;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::BTreeSet;
|
||||
use std::fmt;
|
||||
use std::{fmt, hash};
|
||||
|
||||
/// Sourcecode location.
|
||||
#[derive(Clone, Copy, Debug, Default, PartialEq, Serialize, Deserialize)]
|
||||
@@ -103,7 +103,7 @@ impl ConstantBag for BasicBag {
|
||||
|
||||
/// Primary container of a single code object. Each python function has
|
||||
/// a codeobject. Also a module has a codeobject.
|
||||
#[derive(Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[derive(Clone, Serialize, Deserialize)]
|
||||
pub struct CodeObject<C: Constant = ConstantData> {
|
||||
pub instructions: Box<[Instruction]>,
|
||||
pub locations: Box<[Location]>,
|
||||
@@ -400,8 +400,9 @@ bitflags! {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub enum ConstantData {
|
||||
Tuple { elements: Vec<ConstantData> },
|
||||
Integer { value: BigInt },
|
||||
Float { value: f64 },
|
||||
Complex { value: Complex64 },
|
||||
@@ -409,11 +410,56 @@ pub enum ConstantData {
|
||||
Str { value: String },
|
||||
Bytes { value: Vec<u8> },
|
||||
Code { code: Box<CodeObject> },
|
||||
Tuple { elements: Vec<ConstantData> },
|
||||
None,
|
||||
Ellipsis,
|
||||
}
|
||||
|
||||
impl PartialEq for ConstantData {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
use ConstantData::*;
|
||||
match (self, other) {
|
||||
(Integer { value: a }, Integer { value: b }) => a == b,
|
||||
// we want to compare floats *by actual value* - if we have the *exact same* float
|
||||
// already in a constant cache, we want to use that
|
||||
(Float { value: a }, Float { value: b }) => a.to_bits() == b.to_bits(),
|
||||
(Complex { value: a }, Complex { value: b }) => {
|
||||
a.re.to_bits() == b.re.to_bits() && a.im.to_bits() == b.im.to_bits()
|
||||
}
|
||||
(Boolean { value: a }, Boolean { value: b }) => a == b,
|
||||
(Str { value: a }, Str { value: b }) => a == b,
|
||||
(Bytes { value: a }, Bytes { value: b }) => a == b,
|
||||
(Code { code: a }, Code { code: b }) => std::ptr::eq(a.as_ref(), b.as_ref()),
|
||||
(Tuple { elements: a }, Tuple { elements: b }) => a == b,
|
||||
(None, None) => true,
|
||||
(Ellipsis, Ellipsis) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
impl Eq for ConstantData {}
|
||||
|
||||
impl hash::Hash for ConstantData {
|
||||
fn hash<H: hash::Hasher>(&self, state: &mut H) {
|
||||
use ConstantData::*;
|
||||
std::mem::discriminant(self).hash(state);
|
||||
match self {
|
||||
Integer { value } => value.hash(state),
|
||||
Float { value } => value.to_bits().hash(state),
|
||||
Complex { value } => {
|
||||
value.re.to_bits().hash(state);
|
||||
value.im.to_bits().hash(state);
|
||||
}
|
||||
Boolean { value } => value.hash(state),
|
||||
Str { value } => value.hash(state),
|
||||
Bytes { value } => value.hash(state),
|
||||
Code { code } => std::ptr::hash(code.as_ref(), state),
|
||||
Tuple { elements } => elements.hash(state),
|
||||
None => {}
|
||||
Ellipsis => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub enum BorrowedConstant<'a, C: Constant> {
|
||||
Integer { value: &'a BigInt },
|
||||
Float { value: f64 },
|
||||
|
||||
@@ -157,7 +157,7 @@ impl Compiler {
|
||||
|
||||
blocks: vec![ir::Block::default()],
|
||||
current_block: bytecode::Label(0),
|
||||
constants: Vec::new(),
|
||||
constants: IndexSet::default(),
|
||||
name_cache: IndexSet::default(),
|
||||
varname_cache: IndexSet::default(),
|
||||
cellvar_cache: IndexSet::default(),
|
||||
@@ -235,7 +235,7 @@ impl Compiler {
|
||||
|
||||
blocks: vec![ir::Block::default()],
|
||||
current_block: bytecode::Label(0),
|
||||
constants: Vec::new(),
|
||||
constants: IndexSet::default(),
|
||||
name_cache: IndexSet::default(),
|
||||
varname_cache: IndexSet::default(),
|
||||
cellvar_cache,
|
||||
@@ -2377,8 +2377,7 @@ impl Compiler {
|
||||
|
||||
fn emit_constant(&mut self, constant: ConstantData) {
|
||||
let info = self.current_codeinfo();
|
||||
let idx = info.constants.len() as u32;
|
||||
info.constants.push(constant);
|
||||
let idx = info.constants.insert_full(constant).0 as u32;
|
||||
self.emit(Instruction::LoadConst { idx })
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -37,7 +37,7 @@ pub struct CodeInfo {
|
||||
|
||||
pub blocks: Vec<Block>,
|
||||
pub current_block: BlockIdx,
|
||||
pub constants: Vec<ConstantData>,
|
||||
pub constants: IndexSet<ConstantData>,
|
||||
pub name_cache: IndexSet<String>,
|
||||
pub varname_cache: IndexSet<String>,
|
||||
pub cellvar_cache: IndexSet<String>,
|
||||
@@ -104,7 +104,7 @@ impl CodeInfo {
|
||||
max_stacksize,
|
||||
instructions: instructions.into_boxed_slice(),
|
||||
locations: locations.into_boxed_slice(),
|
||||
constants: constants.into(),
|
||||
constants: constants.into_iter().collect(),
|
||||
names: name_cache.into_iter().collect(),
|
||||
varnames: varname_cache.into_iter().collect(),
|
||||
cellvars: cellvar_cache.into_iter().collect(),
|
||||
|
||||
Reference in new issue
Block a user