-
Notifications
You must be signed in to change notification settings - Fork 306
Bringing over some hash-table related functions to remacs. #251
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
5ee43a8
WIP commit for bringing over hashtable related functions to remacs. T…
ffe501b
Removing unneeded argument references in LispHashTableRef related fun…
2f6027c
Adding 'Fcopy_sequence' calls to hashtable::copy_hash_table. Adding s…
fbf10d9
Adding 'tag_ptr' to LispObject. This will allow a user to tag an obje…
a192a75
Removing uneeded mem::transmute calls. Running cargo fmt. Reorganizin…
c06e705
Fixing issue where "key_and_value" was not being copied over in copy_…
19be908
Updating docstring for 'copy-hash-table' to provide additional inform…
5e3d1c1
Merge branch 'master' into hash-tablev2
DavidDeSimone 2c4fb56
Minor style improvement to 'copy-hash-table', to avoid creating uneed…
bee9030
Marking HashTableRef::copy as unsafe, as it could trigger unsafe beha…
78e7b02
Running cargo fmt
6ae813c
Revert "Running cargo fmt"
95cf731
Running cargo fmt
624fcd2
Merge branch 'master' into hash-tablev2
75b4136
Merge branch 'master' into hash-tablev2
d50109d
Running cargo fmt
f90ecba
Merge branch 'master' into hash-tablev2
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,90 @@ | ||
| use remacs_macros::lisp_fn; | ||
| use lisp::{LispObject, ExternalPtr}; | ||
| use remacs_sys::{Lisp_Hash_Table, PseudovecType, Fcopy_sequence}; | ||
| use std::ptr; | ||
|
|
||
| pub type LispHashTableRef = ExternalPtr<Lisp_Hash_Table>; | ||
|
|
||
| impl LispHashTableRef { | ||
| pub fn allocate() -> LispHashTableRef { | ||
| let vec_ptr = | ||
| allocate_pseudovector!(Lisp_Hash_Table, count, PseudovecType::PVEC_HASH_TABLE); | ||
| LispHashTableRef::new(vec_ptr) | ||
| } | ||
|
|
||
| pub unsafe fn copy(&mut self, other: LispHashTableRef) { | ||
| ptr::copy_nonoverlapping(other.as_ptr(), self.as_mut(), 1); | ||
| } | ||
|
|
||
| pub fn set_next_weak(&mut self, other: LispHashTableRef) { | ||
| self.next_weak = other.as_ptr() as *mut Lisp_Hash_Table; | ||
| } | ||
|
|
||
| pub fn get_next_weak(&self) -> LispHashTableRef { | ||
| LispHashTableRef::new(self.next_weak) | ||
| } | ||
|
|
||
| pub fn set_hash(&mut self, hash: LispObject) { | ||
| self.hash = hash.to_raw(); | ||
| } | ||
|
|
||
| pub fn get_hash(&self) -> LispObject { | ||
| LispObject::from_raw(self.hash) | ||
| } | ||
|
|
||
| pub fn set_next(&mut self, next: LispObject) { | ||
| self.next = next.to_raw(); | ||
| } | ||
|
|
||
| pub fn get_next(&self) -> LispObject { | ||
| LispObject::from_raw(self.next) | ||
| } | ||
|
|
||
| pub fn set_index(&mut self, index: LispObject) { | ||
| self.index = index.to_raw(); | ||
| } | ||
|
|
||
| pub fn get_index(&self) -> LispObject { | ||
| LispObject::from_raw(self.index) | ||
| } | ||
|
|
||
| pub fn get_key_and_value(&self) -> LispObject { | ||
| LispObject::from_raw(self.key_and_value) | ||
| } | ||
|
|
||
| pub fn set_key_and_value(&mut self, key_and_value: LispObject) { | ||
| self.key_and_value = key_and_value.to_raw(); | ||
| } | ||
|
|
||
| pub fn get_weak(&self) -> LispObject { | ||
| LispObject::from_raw(self.weak) | ||
| } | ||
| } | ||
|
|
||
| /// Return a copy of hash table TABLE. | ||
| /// Keys and values are not copied, only the table itself is. | ||
| #[lisp_fn] | ||
| fn copy_hash_table(htable: LispObject) -> LispObject { | ||
| let mut table = htable.as_hash_table_or_error(); | ||
| let mut new_table = LispHashTableRef::allocate(); | ||
| unsafe { new_table.copy(table) }; | ||
| assert!(new_table.as_ptr() != table.as_ptr()); | ||
|
|
||
| let key_and_value = LispObject::from_raw(unsafe { | ||
| Fcopy_sequence(new_table.get_key_and_value().to_raw()) | ||
| }); | ||
| let hash = LispObject::from_raw(unsafe { Fcopy_sequence(new_table.get_hash().to_raw()) }); | ||
| let next = LispObject::from_raw(unsafe { Fcopy_sequence(new_table.get_next().to_raw()) }); | ||
| let index = LispObject::from_raw(unsafe { Fcopy_sequence(new_table.get_index().to_raw()) }); | ||
| new_table.set_key_and_value(key_and_value); | ||
| new_table.set_hash(hash); | ||
| new_table.set_next(next); | ||
| new_table.set_index(index); | ||
|
|
||
| if new_table.get_weak().is_not_nil() { | ||
| new_table.set_next_weak(table.get_next_weak()); | ||
| table.set_next_weak(new_table); | ||
| } | ||
|
|
||
| LispObject::from_hash_table(new_table) | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,22 +9,24 @@ use std::mem; | |
| use std::slice; | ||
| use std::ops::{Deref, DerefMut}; | ||
| use std::fmt::{Debug, Formatter, Error}; | ||
| use libc::{c_void, intptr_t}; | ||
| use libc::{c_void, intptr_t, uintptr_t}; | ||
|
|
||
| use multibyte::{Codepoint, LispStringRef, MAX_CHAR}; | ||
| use symbols::LispSymbolRef; | ||
| use vectors::LispVectorlikeRef; | ||
| use buffers::LispBufferRef; | ||
| use windows::LispWindowRef; | ||
| use marker::LispMarkerRef; | ||
| use hashtable::LispHashTableRef; | ||
| use fonts::LispFontRef; | ||
|
|
||
| use remacs_sys::{EmacsInt, EmacsUint, EmacsDouble, VALMASK, VALBITS, INTTYPEBITS, INTMASK, | ||
| USE_LSB_TAG, MOST_POSITIVE_FIXNUM, MOST_NEGATIVE_FIXNUM, Lisp_Type, | ||
| Lisp_Misc_Any, Lisp_Misc_Type, Lisp_Float, Lisp_Cons, Lisp_Object, lispsym, | ||
| make_float, circular_list, internal_equal, Fcons, CHECK_IMPURE, Qnil, Qt, | ||
| Qnumberp, Qfloatp, Qstringp, Qsymbolp, Qnumber_or_marker_p, Qwholenump, Qvectorp, | ||
| Qcharacterp, Qlistp, Qintegerp, Qconsp, SYMBOL_NAME, PseudovecType, EqualKind}; | ||
| Qcharacterp, Qlistp, Qintegerp, Qhash_table_p, Qconsp, SYMBOL_NAME, | ||
| PseudovecType, EqualKind}; | ||
|
|
||
| // TODO: tweak Makefile to rebuild C files if this changes. | ||
|
|
||
|
|
@@ -96,6 +98,22 @@ impl LispObject { | |
| unsafe { mem::transmute(res) } | ||
| } | ||
|
|
||
| pub fn tag_ptr<T>(external: ExternalPtr<T>, ty: Lisp_Type) -> LispObject { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Handy! |
||
| let raw = external.as_ptr() as intptr_t; | ||
| let res; | ||
| if USE_LSB_TAG { | ||
| let ptr = raw as intptr_t; | ||
| let tag = ty as intptr_t; | ||
| res = (ptr + tag) as EmacsInt; | ||
| } else { | ||
| let ptr = raw as EmacsUint as uintptr_t; | ||
| let tag = ty as EmacsUint as uintptr_t; | ||
| res = ((tag << VALBITS) + ptr) as EmacsInt; | ||
| } | ||
|
|
||
| LispObject::from_raw(res) | ||
| } | ||
|
|
||
| #[inline] | ||
| pub fn get_untaggedptr(self) -> *mut c_void { | ||
| (self.to_raw() & VALMASK) as intptr_t as *mut c_void | ||
|
|
@@ -182,6 +200,10 @@ impl<T> ExternalPtr<T> { | |
| pub fn as_ptr(&self) -> *const T { | ||
| self.0 | ||
| } | ||
|
|
||
| pub fn as_mut(&mut self) -> *mut T { | ||
| self.0 | ||
| } | ||
| } | ||
|
|
||
| impl<T> Deref for ExternalPtr<T> { | ||
|
|
@@ -485,6 +507,36 @@ impl LispObject { | |
| } | ||
| } | ||
|
|
||
| impl LispObject { | ||
| pub fn as_hash_table_or_error(&self) -> LispHashTableRef { | ||
| if self.is_hash_table() { | ||
| LispHashTableRef::new(unsafe { mem::transmute(self.get_untaggedptr()) }) | ||
| } else { | ||
| wrong_type!(Qhash_table_p, *self); | ||
| } | ||
| } | ||
|
|
||
| pub fn as_hash_table(&self) -> Option<LispHashTableRef> { | ||
| if self.is_hash_table() { | ||
| Some(LispHashTableRef::new( | ||
| unsafe { mem::transmute(self.get_untaggedptr()) }, | ||
| )) | ||
| } else { | ||
| None | ||
| } | ||
| } | ||
|
|
||
| pub fn from_hash_table(hashtable: LispHashTableRef) -> LispObject { | ||
| let object = LispObject::tag_ptr(hashtable, Lisp_Type::Lisp_Vectorlike); | ||
| debug_assert!( | ||
| object.is_vectorlike() && object.get_untaggedptr() == hashtable.as_ptr() as *mut c_void | ||
| ); | ||
|
|
||
| debug_assert!(object.is_hash_table()); | ||
| object | ||
| } | ||
| } | ||
|
|
||
| // Cons support (LispType == 6 | 3) | ||
|
|
||
| /// From FOR_EACH_TAIL_INTERNAL in lisp.h | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still need to look into why we were repr(isize) here, and if we need to switch over to repr(C) now that we are invoking a C function with this enum.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Based on discussions in other threads, I believe that changing this to repr(C) is the right call.