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
ac8d04fb
Commit
ac8d04fb
authored
Mar 07, 2014
by
Yukihiro "Matz" Matsumoto
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1820 from ksss/string-embed
Embed small string
parents
035898c7
4bc19d5f
Changes
12
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
312 additions
and
208 deletions
+312
-208
include/mruby/string.h
include/mruby/string.h
+35
-9
mrbgems/mruby-print/src/print.c
mrbgems/mruby-print/src/print.c
+2
-4
mrbgems/mruby-sprintf/src/sprintf.c
mrbgems/mruby-sprintf/src/sprintf.c
+7
-1
mrbgems/mruby-string-ext/src/string.c
mrbgems/mruby-string-ext/src/string.c
+2
-2
src/class.c
src/class.c
+7
-9
src/object.c
src/object.c
+1
-3
src/print.c
src/print.c
+3
-6
src/state.c
src/state.c
+14
-9
src/string.c
src/string.c
+215
-156
src/symbol.c
src/symbol.c
+4
-4
test/driver.c
test/driver.c
+2
-4
test/t/string.rb
test/t/string.rb
+20
-1
No files found.
include/mruby/string.h
View file @
ac8d04fb
...
...
@@ -15,25 +15,51 @@ extern "C" {
extern
const
char
mrb_digitmap
[];
/* (sizeof(mrb_int)*2+sizeof(char*))/sizeof(char)-1 */
#if defined(MRB_INT16)
# define RSTRING_EMBED_LEN_MAX 9
#elif defined(MRB_INT64)
# define RSTRING_EMBED_LEN_MAX 15
#else
# define RSTRING_EMBED_LEN_MAX 11
#endif
struct
RString
{
MRB_OBJECT_HEADER
;
mrb_int
len
;
union
{
mrb_int
capa
;
struct
mrb_shared_string
*
shared
;
}
aux
;
char
*
ptr
;
struct
{
mrb_int
len
;
union
{
mrb_int
capa
;
struct
mrb_shared_string
*
shared
;
}
aux
;
char
*
ptr
;
}
heap
;
char
ary
[
RSTRING_EMBED_LEN_MAX
+
1
];
}
as
;
};
#define mrb_str_ptr(s) ((struct RString*)(mrb_ptr(s)))
#define RSTRING(s) ((struct RString*)(mrb_ptr(s)))
#define RSTRING_PTR(s) (RSTRING(s)->ptr)
#define RSTRING_LEN(s) (RSTRING(s)->len)
#define RSTRING_CAPA(s) (RSTRING(s)->aux.capa)
#define RSTRING_END(s) (RSTRING(s)->ptr + RSTRING(s)->len)
#define RSTRING_PTR(s)\
((RSTRING(s)->flags & MRB_STR_EMBED) ?\
RSTRING(s)->as.ary :\
RSTRING(s)->as.heap.ptr)
#define RSTRING_LEN(s)\
((RSTRING(s)->flags & MRB_STR_EMBED) ?\
(mrb_int)((RSTRING(s)->flags & MRB_STR_EMBED_LEN_MASK) >> MRB_STR_EMBED_LEN_SHIFT) :\
RSTRING(s)->as.heap.len)
#define RSTRING_CAPA(s)\
((RSTRING(s)->flags & MRB_STR_EMBED) ?\
RSTRING_EMBED_LEN_MAX :\
RSTRING(s)->as.heap.aux.capa)
#define RSTRING_END(s) (RSTRING_PTR(s) + RSTRING_LEN(s))
#define MRB_STR_SHARED 1
#define MRB_STR_NOFREE 2
#define MRB_STR_EMBED 4
#define MRB_STR_EMBED_LEN_MASK 120
#define MRB_STR_EMBED_LEN_SHIFT 3
void
mrb_gc_free_str
(
mrb_state
*
,
struct
RString
*
);
void
mrb_str_modify
(
mrb_state
*
,
struct
RString
*
);
...
...
mrbgems/mruby-print/src/print.c
View file @
ac8d04fb
...
...
@@ -5,14 +5,12 @@
static
void
printstr
(
mrb_state
*
mrb
,
mrb_value
obj
)
{
struct
RString
*
str
;
char
*
s
;
int
len
;
if
(
mrb_string_p
(
obj
))
{
str
=
mrb_str_ptr
(
obj
);
s
=
str
->
ptr
;
len
=
str
->
len
;
s
=
RSTRING_PTR
(
obj
);
len
=
RSTRING_LEN
(
obj
);
fwrite
(
s
,
len
,
1
,
stdout
);
}
}
...
...
mrbgems/mruby-sprintf/src/sprintf.c
View file @
ac8d04fb
...
...
@@ -712,7 +712,13 @@ retry:
if
(
*
p
==
'p'
)
arg
=
mrb_inspect
(
mrb
,
arg
);
str
=
mrb_obj_as_string
(
mrb
,
arg
);
len
=
RSTRING_LEN
(
str
);
RSTRING_LEN
(
result
)
=
blen
;
if
(
RSTRING
(
result
)
->
flags
&
MRB_STR_EMBED
)
{
int
tmp_n
=
len
;
RSTRING
(
result
)
->
flags
&=
~
MRB_STR_EMBED_LEN_MASK
;
RSTRING
(
result
)
->
flags
|=
tmp_n
<<
MRB_STR_EMBED_LEN_SHIFT
;
}
else
{
RSTRING
(
result
)
->
as
.
heap
.
len
=
blen
;
}
if
(
flags
&
(
FPREC
|
FWIDTH
))
{
slen
=
RSTRING_LEN
(
str
);
if
(
slen
<
0
)
{
...
...
mrbgems/mruby-string-ext/src/string.c
View file @
ac8d04fb
...
...
@@ -33,8 +33,8 @@ mrb_str_swapcase_bang(mrb_state *mrb, mrb_value str)
struct
RString
*
s
=
mrb_str_ptr
(
str
);
mrb_str_modify
(
mrb
,
s
);
p
=
s
->
ptr
;
pend
=
s
->
ptr
+
s
->
len
;
p
=
RSTRING_PTR
(
str
)
;
pend
=
RSTRING_PTR
(
str
)
+
RSTRING_LEN
(
str
)
;
while
(
p
<
pend
)
{
if
(
ISUPPER
(
*
p
))
{
*
p
=
TOLOWER
(
*
p
);
...
...
src/class.c
View file @
ac8d04fb
...
...
@@ -511,7 +511,6 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
case
's'
:
{
mrb_value
ss
;
struct
RString
*
s
;
char
**
ps
=
0
;
int
*
pl
=
0
;
...
...
@@ -519,9 +518,8 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
pl
=
va_arg
(
ap
,
int
*
);
if
(
i
<
argc
)
{
ss
=
to_str
(
mrb
,
*
sp
++
);
s
=
mrb_str_ptr
(
ss
);
*
ps
=
s
->
ptr
;
*
pl
=
s
->
len
;
*
ps
=
RSTRING_PTR
(
ss
);
*
pl
=
RSTRING_LEN
(
ss
);
i
++
;
}
}
...
...
@@ -537,14 +535,14 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
if
(
i
<
argc
)
{
ss
=
to_str
(
mrb
,
*
sp
++
);
s
=
mrb_str_ptr
(
ss
);
len
=
(
mrb_int
)
strlen
(
s
->
ptr
);
if
(
len
<
s
->
len
)
{
len
=
(
mrb_int
)
strlen
(
RSTRING_PTR
(
ss
)
);
if
(
len
<
RSTRING_LEN
(
ss
)
)
{
mrb_raise
(
mrb
,
E_ARGUMENT_ERROR
,
"string contains null byte"
);
}
else
if
(
len
>
s
->
len
)
{
else
if
(
len
>
RSTRING_LEN
(
ss
)
)
{
mrb_str_modify
(
mrb
,
s
);
}
*
ps
=
s
->
ptr
;
*
ps
=
RSTRING_PTR
(
ss
)
;
i
++
;
}
}
...
...
@@ -1298,7 +1296,7 @@ mrb_class_name(mrb_state *mrb, struct RClass* c)
mrb_str_concat
(
mrb
,
path
,
mrb_ptr_to_str
(
mrb
,
c
));
mrb_str_cat_lit
(
mrb
,
path
,
">"
);
}
return
mrb_str_ptr
(
path
)
->
ptr
;
return
RSTRING_PTR
(
path
)
;
}
const
char
*
...
...
src/object.c
View file @
ac8d04fb
...
...
@@ -390,7 +390,6 @@ void
mrb_check_type
(
mrb_state
*
mrb
,
mrb_value
x
,
enum
mrb_vtype
t
)
{
const
struct
types
*
type
=
builtin_types
;
struct
RString
*
s
;
enum
mrb_vtype
xt
;
xt
=
mrb_type
(
x
);
...
...
@@ -409,8 +408,7 @@ mrb_check_type(mrb_state *mrb, mrb_value x, enum mrb_vtype t)
etype
=
"Symbol"
;
}
else
if
(
mrb_special_const_p
(
x
))
{
s
=
mrb_str_ptr
(
mrb_obj_as_string
(
mrb
,
x
));
etype
=
s
->
ptr
;
etype
=
RSTRING_PTR
(
mrb_obj_as_string
(
mrb
,
x
));
}
else
{
etype
=
mrb_obj_classname
(
mrb
,
x
);
...
...
src/print.c
View file @
ac8d04fb
...
...
@@ -12,14 +12,12 @@ static void
printstr
(
mrb_state
*
mrb
,
mrb_value
obj
)
{
#ifdef ENABLE_STDIO
struct
RString
*
str
;
char
*
s
;
int
len
;
if
(
mrb_string_p
(
obj
))
{
str
=
mrb_str_ptr
(
obj
);
s
=
str
->
ptr
;
len
=
str
->
len
;
s
=
RSTRING_PTR
(
obj
);
len
=
RSTRING_LEN
(
obj
);
fwrite
(
s
,
len
,
1
,
stdout
);
}
#endif
...
...
@@ -44,8 +42,7 @@ mrb_print_error(mrb_state *mrb)
mrb_print_backtrace
(
mrb
);
s
=
mrb_funcall
(
mrb
,
mrb_obj_value
(
mrb
->
exc
),
"inspect"
,
0
);
if
(
mrb_string_p
(
s
))
{
struct
RString
*
str
=
mrb_str_ptr
(
s
);
fwrite
(
str
->
ptr
,
str
->
len
,
1
,
stderr
);
fwrite
(
RSTRING_PTR
(
s
),
RSTRING_LEN
(
s
),
1
,
stderr
);
putc
(
'\n'
,
stderr
);
}
#endif
...
...
src/state.c
View file @
ac8d04fb
...
...
@@ -135,8 +135,8 @@ mrb_irep_free(mrb_state *mrb, mrb_irep *irep)
mrb_free
(
mrb
,
irep
->
iseq
);
for
(
i
=
0
;
i
<
irep
->
plen
;
i
++
)
{
if
(
mrb_type
(
irep
->
pool
[
i
])
==
MRB_TT_STRING
)
{
if
((
mrb_str_ptr
(
irep
->
pool
[
i
])
->
flags
&
MRB_STR_NOFREE
)
==
0
)
{
mrb_free
(
mrb
,
mrb_str_ptr
(
irep
->
pool
[
i
])
->
ptr
);
if
((
mrb_str_ptr
(
irep
->
pool
[
i
])
->
flags
&
(
MRB_STR_NOFREE
|
MRB_STR_EMBED
)
)
==
0
)
{
mrb_free
(
mrb
,
RSTRING_PTR
(
irep
->
pool
[
i
])
);
}
mrb_free
(
mrb
,
mrb_obj_ptr
(
irep
->
pool
[
i
]));
}
...
...
@@ -163,25 +163,30 @@ mrb_str_pool(mrb_state *mrb, mrb_value str)
{
struct
RString
*
s
=
mrb_str_ptr
(
str
);
struct
RString
*
ns
;
char
*
ptr
;
mrb_int
len
;
ns
=
(
struct
RString
*
)
mrb_malloc
(
mrb
,
sizeof
(
struct
RString
));
ns
->
tt
=
MRB_TT_STRING
;
ns
->
c
=
mrb
->
string_class
;
len
=
s
->
len
;
ns
->
len
=
len
;
if
(
s
->
flags
&
MRB_STR_EMBED
)
len
=
(
mrb_int
)((
s
->
flags
&
MRB_STR_EMBED_LEN_MASK
)
>>
MRB_STR_EMBED_LEN_SHIFT
);
else
len
=
s
->
as
.
heap
.
len
;
ns
->
as
.
heap
.
len
=
len
;
if
(
s
->
flags
&
MRB_STR_NOFREE
)
{
ns
->
ptr
=
s
->
ptr
;
ns
->
as
.
heap
.
ptr
=
s
->
as
.
heap
.
ptr
;
ns
->
flags
=
MRB_STR_NOFREE
;
}
else
{
ns
->
flags
=
0
;
ns
->
ptr
=
(
char
*
)
mrb_malloc
(
mrb
,
(
size_t
)
len
+
1
);
if
(
s
->
ptr
)
{
memcpy
(
ns
->
ptr
,
s
->
ptr
,
len
);
ns
->
as
.
heap
.
ptr
=
(
char
*
)
mrb_malloc
(
mrb
,
(
size_t
)
len
+
1
);
ptr
=
(
s
->
flags
&
MRB_STR_EMBED
)
?
s
->
as
.
ary
:
s
->
as
.
heap
.
ptr
;
if
(
ptr
)
{
memcpy
(
ns
->
as
.
heap
.
ptr
,
ptr
,
len
);
}
ns
->
ptr
[
len
]
=
'\0'
;
ns
->
as
.
heap
.
ptr
[
len
]
=
'\0'
;
}
return
mrb_obj_value
(
ns
);
}
...
...
src/string.c
View file @
ac8d04fb
This diff is collapsed.
Click to expand it.
src/symbol.c
View file @
ac8d04fb
...
...
@@ -397,11 +397,11 @@ sym_inspect(mrb_state *mrb, mrb_value sym)
name
=
mrb_sym2name_len
(
mrb
,
id
,
&
len
);
str
=
mrb_str_new
(
mrb
,
0
,
len
+
1
);
RSTRING
(
str
)
->
ptr
[
0
]
=
':'
;
memcpy
(
RSTRING
(
str
)
->
ptr
+
1
,
name
,
len
);
RSTRING
_PTR
(
str
)
[
0
]
=
':'
;
memcpy
(
RSTRING
_PTR
(
str
)
+
1
,
name
,
len
);
if
(
!
symname_p
(
name
)
||
strlen
(
name
)
!=
len
)
{
str
=
mrb_str_dump
(
mrb
,
str
);
memcpy
(
RSTRING
(
str
)
->
ptr
,
":
\"
"
,
2
);
memcpy
(
RSTRING
_PTR
(
str
)
,
":
\"
"
,
2
);
}
return
str
;
}
...
...
@@ -428,7 +428,7 @@ mrb_sym2name(mrb_state *mrb, mrb_sym sym)
}
else
{
mrb_value
str
=
mrb_str_dump
(
mrb
,
mrb_str_new_static
(
mrb
,
name
,
len
));
return
RSTRING
(
str
)
->
ptr
;
return
RSTRING
_PTR
(
str
)
;
}
}
...
...
test/driver.c
View file @
ac8d04fb
...
...
@@ -61,14 +61,12 @@ eval_test(mrb_state *mrb)
static
void
t_printstr
(
mrb_state
*
mrb
,
mrb_value
obj
)
{
struct
RString
*
str
;
char
*
s
;
int
len
;
if
(
mrb_string_p
(
obj
))
{
str
=
mrb_str_ptr
(
obj
);
s
=
str
->
ptr
;
len
=
str
->
len
;
s
=
RSTRING_PTR
(
obj
);
len
=
RSTRING_LEN
(
obj
);
fwrite
(
s
,
len
,
1
,
stdout
);
}
}
...
...
test/t/string.rb
View file @
ac8d04fb
...
...
@@ -86,6 +86,7 @@ assert('String#[] with Range') do
g1
=
'abc'
[
-
2
..
3
]
h1
=
'abc'
[
3
..
4
]
i1
=
'abc'
[
4
..
5
]
j1
=
'abcdefghijklmnopqrstuvwxyz'
[
1
..
3
]
a2
=
'abc'
[
1
...
0
]
b2
=
'abc'
[
1
...
1
]
c2
=
'abc'
[
1
...
2
]
...
...
@@ -95,6 +96,7 @@ assert('String#[] with Range') do
g2
=
'abc'
[
-
2
...
3
]
h2
=
'abc'
[
3
...
4
]
i2
=
'abc'
[
4
...
5
]
j2
=
'abcdefghijklmnopqrstuvwxyz'
[
1
...
3
]
assert_equal
''
,
a1
assert_equal
'b'
,
b1
...
...
@@ -105,6 +107,7 @@ assert('String#[] with Range') do
assert_equal
'bc'
,
g1
assert_equal
''
,
h1
assert_nil
i2
assert_equal
'bcd'
,
j1
assert_equal
''
,
a2
assert_equal
''
,
b2
assert_equal
'b'
,
c2
...
...
@@ -114,6 +117,7 @@ assert('String#[] with Range') do
assert_equal
'bc'
,
g2
assert_equal
''
,
h2
assert_nil
i2
assert_equal
'bc'
,
j2
end
assert
(
'String#capitalize'
,
'15.2.10.5.7'
)
do
...
...
@@ -281,8 +285,10 @@ end
assert
(
'String#initialize'
,
'15.2.10.5.23'
)
do
a
=
''
a
.
initialize
(
'abc'
)
assert_equal
'abc'
,
a
a
.
initialize
(
'abcdefghijklmnopqrstuvwxyz'
)
assert_equal
'abcdefghijklmnopqrstuvwxyz'
,
a
end
assert
(
'String#initialize_copy'
,
'15.2.10.5.24'
)
do
...
...
@@ -307,6 +313,13 @@ assert('String#replace', '15.2.10.5.28') do
a
.
replace
(
'abc'
)
assert_equal
'abc'
,
a
assert_equal
'abc'
,
'cba'
.
replace
(
a
)
b
=
'abc'
*
10
c
=
(
'cba'
*
10
).
dup
b
.
replace
(
c
);
c
.
replace
(
b
);
assert_equal
c
,
b
end
assert
(
'String#reverse'
,
'15.2.10.5.29'
)
do
...
...
@@ -452,6 +465,12 @@ assert('String#upcase!', '15.2.10.5.43') do
assert_equal
'ABC'
,
a
assert_equal
nil
,
'ABC'
.
upcase!
a
=
'abcdefghijklmnopqrstuvwxyz'
b
=
a
.
dup
a
.
upcase!
b
.
upcase!
assert_equal
'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
,
b
end
# Not ISO specified
...
...
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