Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
mruby
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Libraries
mruby
Commits
4b29abc5
Commit
4b29abc5
authored
Apr 27, 2018
by
kimu_shu
Committed by
Yukihiro "Matz" Matsumoto
Apr 28, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix Enumerable#hash on non 32-bit integer conf.
parent
84b499d0
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
55 additions
and
13 deletions
+55
-13
mrblib/enum.rb
mrblib/enum.rb
+0
-12
src/enum.c
src/enum.c
+55
-1
No files found.
mrblib/enum.rb
View file @
4b29abc5
...
...
@@ -333,16 +333,4 @@ module Enumerable
#
# ISO 15.3.2.2.20
alias
to_a
entries
# redefine #hash 15.3.1.3.15
def
hash
h
=
12347
i
=
0
self
.
each
do
|
e
|
n
=
(
e
.
hash
&
(
0x7fffffff
>>
(
i
%
16
)))
<<
(
i
%
16
)
h
^=
n
i
+=
1
end
h
end
end
src/enum.c
View file @
4b29abc5
...
...
@@ -5,10 +5,64 @@
*/
#include <mruby.h>
#include <mruby/proc.h>
typedef
struct
enumerable_hash_context
{
mrb_int
hash
;
mrb_int
index
;
}
enumerable_hash_context
;
static
mrb_value
enumerable_hash_each
(
mrb_state
*
mrb
,
mrb_value
self
)
{
mrb_value
item
;
mrb_value
closure
;
mrb_get_args
(
mrb
,
"o"
,
&
item
);
closure
=
mrb_proc_cfunc_env_get
(
mrb
,
0
);
if
(
mrb_cptr_p
(
closure
))
{
mrb_value
item_hash
;
enumerable_hash_context
*
context
=
(
enumerable_hash_context
*
)
mrb_cptr
(
closure
);
item_hash
=
mrb_funcall
(
mrb
,
item
,
"hash"
,
0
);
if
(
mrb_fixnum_p
(
item_hash
))
{
context
->
hash
^=
(
mrb_fixnum
(
item_hash
)
<<
(
context
->
index
%
16
));
++
context
->
index
;
return
mrb_nil_value
();
}
}
mrb_raise
(
mrb
,
E_TYPE_ERROR
,
"can't calculate hash"
);
}
static
mrb_value
enumerable_hash
(
mrb_state
*
mrb
,
mrb_value
self
)
{
/* redefine #hash 15.3.1.3.15 */
struct
RProc
*
proc
;
enumerable_hash_context
context
;
mrb_value
closure
;
mrb_value
blk
;
int
ai
=
mrb_gc_arena_save
(
mrb
);
context
.
hash
=
12347
;
context
.
index
=
0
;
closure
=
mrb_cptr_value
(
mrb
,
&
context
);
proc
=
mrb_proc_new_cfunc_with_env
(
mrb
,
enumerable_hash_each
,
1
,
&
closure
);
blk
=
mrb_obj_value
(
proc
);
mrb_funcall_with_block
(
mrb
,
self
,
mrb_intern_cstr
(
mrb
,
"each"
),
0
,
NULL
,
blk
);
mrb_gc_arena_restore
(
mrb
,
ai
);
return
mrb_fixnum_value
(
context
.
hash
);
}
void
mrb_init_enumerable
(
mrb_state
*
mrb
)
{
mrb_define_module
(
mrb
,
"Enumerable"
);
/* 15.3.2 */
struct
RClass
*
enumerable
;
enumerable
=
mrb_define_module
(
mrb
,
"Enumerable"
);
/* 15.3.2 */
mrb_define_module_function
(
mrb
,
enumerable
,
"hash"
,
enumerable_hash
,
MRB_ARGS_NONE
());
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment