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
10459a5e
Commit
10459a5e
authored
May 14, 2014
by
Yukihiro "Matz" Matsumoto
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'dump_lv' of
https://github.com/take-cheeze/mruby
into take-cheeze-dump_lv
parents
e1b84143
5073d14e
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
293 additions
and
4 deletions
+293
-4
include/mruby/dump.h
include/mruby/dump.h
+5
-0
mrbgems/mruby-proc-ext/src/proc.c
mrbgems/mruby-proc-ext/src/proc.c
+24
-0
mrbgems/mruby-proc-ext/test/proc.rb
mrbgems/mruby-proc-ext/test/proc.rb
+8
-0
src/codegen.c
src/codegen.c
+2
-1
src/dump.c
src/dump.c
+152
-3
src/load.c
src/load.c
+102
-0
No files found.
include/mruby/dump.h
View file @
10459a5e
...
...
@@ -53,6 +53,7 @@ mrb_irep *mrb_read_irep(mrb_state*, const uint8_t*);
#define RITE_SECTION_IREP_IDENTIFIER "IREP"
#define RITE_SECTION_LINENO_IDENTIFIER "LINE"
#define RITE_SECTION_DEBUG_IDENTIFIER "DBG\0"
#define RITE_SECTION_LV_IDENTIFIER "LOCV"
#define MRB_DUMP_DEFAULT_STR_LEN 128
...
...
@@ -89,6 +90,10 @@ struct rite_section_debug_header {
RITE_SECTION_HEADER
;
};
struct
rite_section_lv_header
{
RITE_SECTION_HEADER
;
};
struct
rite_binary_footer
{
RITE_SECTION_HEADER
;
};
...
...
mrbgems/mruby-proc-ext/src/proc.c
View file @
10459a5e
...
...
@@ -122,6 +122,29 @@ mrb_kernel_proc(mrb_state *mrb, mrb_value self)
return
blk
;
}
static
mrb_value
mrb_local_variables
(
mrb_state
*
mrb
,
mrb_value
self
)
{
mrb_value
ret
;
struct
RProc
*
proc
;
struct
mrb_irep
*
irep
;
size_t
i
;
proc
=
mrb
->
c
->
ci
[
-
1
].
proc
;
if
(
MRB_PROC_CFUNC_P
(
proc
))
{
return
mrb_ary_new
(
mrb
);
}
irep
=
proc
->
body
.
irep
;
ret
=
mrb_ary_new_capa
(
mrb
,
irep
->
nlocals
-
1
);
for
(
i
=
0
;
i
<
(
irep
->
nlocals
-
1
);
++
i
)
{
mrb_ary_push
(
mrb
,
ret
,
mrb_symbol_value
(
irep
->
lv
[
i
].
name
));
}
return
ret
;
}
void
mrb_mruby_proc_ext_gem_init
(
mrb_state
*
mrb
)
{
...
...
@@ -133,6 +156,7 @@ mrb_mruby_proc_ext_gem_init(mrb_state* mrb)
mrb_define_class_method
(
mrb
,
mrb
->
kernel_module
,
"proc"
,
mrb_kernel_proc
,
MRB_ARGS_NONE
());
mrb_define_method
(
mrb
,
mrb
->
kernel_module
,
"proc"
,
mrb_kernel_proc
,
MRB_ARGS_NONE
());
mrb_define_module_function
(
mrb
,
mrb
->
kernel_module
,
"local_variables"
,
mrb_local_variables
,
MRB_ARGS_NONE
());
}
void
...
...
mrbgems/mruby-proc-ext/test/proc.rb
View file @
10459a5e
...
...
@@ -74,3 +74,11 @@ assert('mrb_cfunc_env_get') do
assert_equal
1
,
t
.
get_int
(
1
)
end
assert
(
'Kernel.local_variables'
)
do
a
,
b
=
0
,
1
a
+=
b
vars
=
Kernel
.
local_variables
.
sort
assert_equal
[
:a
,
:b
,
:vars
],
vars
end
src/codegen.c
View file @
10459a5e
...
...
@@ -2500,11 +2500,12 @@ scope_new(mrb_state *mrb, codegen_scope *prev, node *lv)
node
*
n
=
lv
;
size_t
i
=
0
;
p
->
irep
->
lv
=
(
struct
mrb_locals
*
)
mrb_malloc
(
mrb
,
sizeof
(
struct
mrb_locals
)
*
p
->
nlocals
);
p
->
irep
->
lv
=
(
struct
mrb_locals
*
)
mrb_malloc
(
mrb
,
sizeof
(
struct
mrb_locals
)
*
(
p
->
nlocals
-
1
)
);
for
(
i
=
0
,
n
=
lv
;
n
;
i
++
,
n
=
n
->
cdr
)
{
p
->
irep
->
lv
[
i
].
name
=
lv_name
(
n
);
p
->
irep
->
lv
[
i
].
r
=
lv_idx
(
p
,
lv_name
(
n
));
}
mrb_assert
(
i
==
(
p
->
nlocals
-
1
));
}
p
->
ai
=
mrb_gc_arena_save
(
mrb
);
...
...
src/dump.c
View file @
10459a5e
...
...
@@ -500,7 +500,7 @@ get_debug_record_size(mrb_state *mrb, mrb_irep *irep)
}
static
int
find_filename_index
(
const
mrb_sym
*
ary
,
uint16_
t
ary_len
,
mrb_sym
s
)
find_filename_index
(
const
mrb_sym
*
ary
,
in
t
ary_len
,
mrb_sym
s
)
{
int
i
;
...
...
@@ -692,6 +692,141 @@ write_section_debug(mrb_state *mrb, mrb_irep *irep, uint8_t *cur)
return
MRB_DUMP_OK
;
}
static
void
create_lv_sym_table
(
mrb_state
*
mrb
,
const
mrb_irep
*
irep
,
mrb_sym
**
syms
,
uint32_t
*
syms_len
)
{
size_t
i
;
if
(
*
syms
==
NULL
)
{
*
syms
=
(
mrb_sym
*
)
mrb_malloc
(
mrb
,
sizeof
(
mrb_sym
)
*
1
);
}
for
(
i
=
0
;
i
<
(
irep
->
nlocals
-
1
);
++
i
)
{
mrb_sym
const
name
=
irep
->
lv
[
i
].
name
;
if
(
find_filename_index
(
*
syms
,
*
syms_len
,
name
)
!=
-
1
)
continue
;
++
(
*
syms_len
);
*
syms
=
(
mrb_sym
*
)
mrb_realloc
(
mrb
,
*
syms
,
sizeof
(
mrb_sym
)
*
(
*
syms_len
));
(
*
syms
)[
*
syms_len
-
1
]
=
name
;
}
for
(
i
=
0
;
i
<
irep
->
rlen
;
++
i
)
{
create_lv_sym_table
(
mrb
,
irep
->
reps
[
i
],
syms
,
syms_len
);
}
}
static
int
write_lv_sym_table
(
mrb_state
*
mrb
,
uint8_t
**
start
,
mrb_sym
const
*
syms
,
uint32_t
syms_len
)
{
uint8_t
*
cur
=
*
start
;
uint32_t
i
;
const
char
*
str
;
mrb_int
str_len
;
cur
+=
uint32_to_bin
(
syms_len
,
cur
);
for
(
i
=
0
;
i
<
syms_len
;
++
i
)
{
str
=
mrb_sym2name_len
(
mrb
,
syms
[
i
],
&
str_len
);
cur
+=
uint16_to_bin
(
str_len
,
cur
);
memcpy
(
cur
,
str
,
str_len
);
cur
+=
str_len
;
}
*
start
=
cur
;
return
MRB_DUMP_OK
;
}
static
int
write_lv_record
(
mrb_state
*
mrb
,
const
mrb_irep
*
irep
,
uint8_t
**
start
,
mrb_sym
const
*
syms
,
uint32_t
syms_len
)
{
uint8_t
*
cur
=
*
start
;
size_t
i
;
for
(
i
=
0
;
i
<
(
irep
->
nlocals
-
1
);
++
i
)
{
int
const
sym_idx
=
find_filename_index
(
syms
,
syms_len
,
irep
->
lv
[
i
].
name
);
mrb_assert
(
sym_idx
!=
-
1
);
/* local variable name must be in syms */
cur
+=
uint16_to_bin
(
sym_idx
,
cur
);
cur
+=
uint32_to_bin
(
irep
->
lv
[
i
].
r
,
cur
);
}
for
(
i
=
0
;
i
<
irep
->
rlen
;
++
i
)
{
write_lv_record
(
mrb
,
irep
->
reps
[
i
],
&
cur
,
syms
,
syms_len
);
}
*
start
=
cur
;
return
MRB_DUMP_OK
;
}
static
size_t
get_lv_record_size
(
mrb_state
*
mrb
,
mrb_irep
*
irep
)
{
size_t
ret
=
0
,
i
;
ret
+=
(
sizeof
(
uint16_t
)
+
sizeof
(
uint32_t
))
*
(
irep
->
nlocals
-
1
);
for
(
i
=
0
;
i
<
irep
->
rlen
;
++
i
)
{
ret
+=
get_lv_record_size
(
mrb
,
irep
->
reps
[
i
]);
}
return
ret
;
}
static
size_t
get_lv_section_size
(
mrb_state
*
mrb
,
mrb_irep
*
irep
,
mrb_sym
const
*
syms
,
uint32_t
syms_len
)
{
size_t
ret
=
0
,
i
;
ret
+=
sizeof
(
uint32_t
);
/* syms_len */
ret
+=
sizeof
(
uint16_t
)
*
syms_len
;
/* symbol name lengths */
for
(
i
=
0
;
i
<
syms_len
;
++
i
)
{
mrb_int
str_len
;
mrb_sym2name_len
(
mrb
,
syms
[
i
],
&
str_len
);
ret
+=
str_len
;
}
ret
+=
get_lv_record_size
(
mrb
,
irep
);
return
ret
;
}
static
int
write_section_lv
(
mrb_state
*
mrb
,
mrb_irep
*
irep
,
uint8_t
*
start
,
mrb_sym
const
*
syms
,
uint32_t
const
syms_len
)
{
uint8_t
*
cur
=
start
;
struct
rite_section_lv_header
*
header
;
ptrdiff_t
diff
;
int
result
=
MRB_DUMP_OK
;
if
(
mrb
==
NULL
||
cur
==
NULL
)
{
return
MRB_DUMP_INVALID_ARGUMENT
;
}
header
=
(
struct
rite_section_lv_header
*
)
cur
;
cur
+=
sizeof
(
struct
rite_section_lv_header
);
result
=
write_lv_sym_table
(
mrb
,
&
cur
,
syms
,
syms_len
);
if
(
result
!=
MRB_DUMP_OK
)
{
goto
lv_section_exit
;
}
result
=
write_lv_record
(
mrb
,
irep
,
&
cur
,
syms
,
syms_len
);
if
(
result
!=
MRB_DUMP_OK
)
{
goto
lv_section_exit
;
}
memcpy
(
header
->
section_identify
,
RITE_SECTION_LV_IDENTIFIER
,
sizeof
(
header
->
section_identify
));
diff
=
cur
-
start
;
mrb_assert_int_fit
(
ptrdiff_t
,
diff
,
size_t
,
SIZE_MAX
);
uint32_to_bin
(
diff
,
header
->
section_size
);
lv_section_exit:
return
result
;
}
static
int
write_rite_binary_header
(
mrb_state
*
mrb
,
size_t
binary_size
,
uint8_t
*
bin
)
{
...
...
@@ -730,9 +865,10 @@ mrb_dump_irep(mrb_state *mrb, mrb_irep *irep, int debug_info, uint8_t **bin, siz
{
int
result
=
MRB_DUMP_GENERAL_FAILURE
;
size_t
section_irep_size
;
size_t
section_lineno_size
=
0
;
size_t
section_lineno_size
=
0
,
section_lv_size
=
0
;
uint8_t
*
cur
=
NULL
;
mrb_bool
const
debug_info_defined
=
is_debug_info_defined
(
irep
);
mrb_sym
*
lv_syms
=
NULL
;
uint32_t
lv_syms_len
=
0
;
if
(
mrb
==
NULL
)
{
*
bin
=
NULL
;
...
...
@@ -764,8 +900,12 @@ mrb_dump_irep(mrb_state *mrb, mrb_irep *irep, int debug_info, uint8_t **bin, siz
}
}
section_lv_size
+=
sizeof
(
struct
rite_section_lv_header
);
create_lv_sym_table
(
mrb
,
irep
,
&
lv_syms
,
&
lv_syms_len
);
section_lv_size
+=
get_lv_section_size
(
mrb
,
irep
,
lv_syms
,
lv_syms_len
);
*
bin_size
=
sizeof
(
struct
rite_binary_header
)
+
section_irep_size
+
section_lineno_size
+
section_irep_size
+
section_lineno_size
+
section_lv_size
+
sizeof
(
struct
rite_binary_footer
);
cur
=
*
bin
=
(
uint8_t
*
)
mrb_malloc
(
mrb
,
*
bin_size
);
if
(
cur
==
NULL
)
{
...
...
@@ -793,6 +933,12 @@ mrb_dump_irep(mrb_state *mrb, mrb_irep *irep, int debug_info, uint8_t **bin, siz
cur
+=
section_lineno_size
;
}
result
=
write_section_lv
(
mrb
,
irep
,
cur
,
lv_syms
,
lv_syms_len
);
if
(
result
!=
MRB_DUMP_OK
)
{
goto
error_exit
;
}
cur
+=
section_lv_size
;
write_footer
(
mrb
,
cur
);
write_rite_binary_header
(
mrb
,
*
bin_size
,
*
bin
);
...
...
@@ -801,6 +947,9 @@ error_exit:
mrb_free
(
mrb
,
*
bin
);
*
bin
=
NULL
;
}
if
(
lv_syms
)
{
mrb_free
(
mrb
,
lv_syms
);
}
return
result
;
}
...
...
src/load.c
View file @
10459a5e
...
...
@@ -399,6 +399,86 @@ debug_exit:
return
result
;
}
static
int
read_lv_record
(
mrb_state
*
mrb
,
const
uint8_t
*
start
,
mrb_irep
*
irep
,
size_t
*
record_len
,
mrb_sym
const
*
syms
,
uint32_t
syms_len
)
{
const
uint8_t
*
bin
=
start
;
size_t
i
;
ptrdiff_t
diff
;
irep
->
lv
=
(
struct
mrb_locals
*
)
mrb_malloc
(
mrb
,
sizeof
(
struct
mrb_locals
)
*
(
irep
->
nlocals
-
1
));
for
(
i
=
0
;
i
<
(
irep
->
nlocals
-
1
);
++
i
)
{
uint16_t
const
sym_idx
=
bin_to_uint16
(
bin
);
bin
+=
sizeof
(
uint16_t
);
if
(
sym_idx
>=
syms_len
)
{
return
MRB_DUMP_GENERAL_FAILURE
;
}
irep
->
lv
[
i
].
name
=
syms
[
sym_idx
];
irep
->
lv
[
i
].
r
=
bin_to_uint32
(
bin
);
bin
+=
sizeof
(
uint32_t
);
}
for
(
i
=
0
;
i
<
irep
->
rlen
;
++
i
)
{
size_t
len
;
int
ret
;
ret
=
read_lv_record
(
mrb
,
bin
,
irep
->
reps
[
i
],
&
len
,
syms
,
syms_len
);
if
(
ret
!=
MRB_DUMP_OK
)
return
ret
;
bin
+=
len
;
}
diff
=
bin
-
start
;
mrb_assert_int_fit
(
ptrdiff_t
,
diff
,
size_t
,
SIZE_MAX
);
*
record_len
=
(
size_t
)
diff
;
return
MRB_DUMP_OK
;
}
static
int
read_section_lv
(
mrb_state
*
mrb
,
const
uint8_t
*
start
,
mrb_irep
*
irep
,
mrb_bool
alloc
)
{
const
uint8_t
*
bin
;
ptrdiff_t
diff
;
struct
rite_section_lv_header
const
*
header
;
uint32_t
i
;
size_t
len
=
0
;
int
result
;
uint32_t
syms_len
;
mrb_sym
*
syms
;
mrb_sym
(
*
intern_func
)(
mrb_state
*
,
const
char
*
,
size_t
)
=
alloc
?
mrb_intern
:
mrb_intern_static
;
bin
=
start
;
header
=
(
struct
rite_section_lv_header
const
*
)
bin
;
bin
+=
sizeof
(
struct
rite_section_lv_header
);
syms_len
=
bin_to_uint32
(
bin
);
bin
+=
sizeof
(
uint32_t
);
syms
=
(
mrb_sym
*
)
mrb_malloc
(
mrb
,
sizeof
(
mrb_sym
)
*
(
size_t
)
syms_len
);
for
(
i
=
0
;
i
<
syms_len
;
++
i
)
{
uint16_t
const
str_len
=
bin_to_uint16
(
bin
);
bin
+=
sizeof
(
uint16_t
);
syms
[
i
]
=
intern_func
(
mrb
,
(
const
char
*
)
bin
,
str_len
);
bin
+=
str_len
;
}
result
=
read_lv_record
(
mrb
,
bin
,
irep
,
&
len
,
syms
,
syms_len
);
if
(
result
!=
MRB_DUMP_OK
)
goto
lv_exit
;
bin
+=
len
;
diff
=
bin
-
start
;
mrb_assert_int_fit
(
ptrdiff_t
,
diff
,
size_t
,
SIZE_MAX
);
if
((
uint32_t
)
diff
!=
bin_to_uint32
(
header
->
section_size
))
{
result
=
MRB_DUMP_GENERAL_FAILURE
;
}
lv_exit:
mrb_free
(
mrb
,
syms
);
return
result
;
}
static
int
read_binary_header
(
const
uint8_t
*
bin
,
size_t
*
bin_size
,
uint16_t
*
crc
)
{
...
...
@@ -465,6 +545,13 @@ mrb_read_irep(mrb_state *mrb, const uint8_t *bin)
return
NULL
;
}
}
else
if
(
memcmp
(
section_header
->
section_identify
,
RITE_SECTION_LV_IDENTIFIER
,
sizeof
(
section_header
->
section_identify
))
==
0
)
{
if
(
!
irep
)
return
NULL
;
result
=
read_section_lv
(
mrb
,
bin
,
irep
,
FALSE
);
if
(
result
<
MRB_DUMP_OK
)
{
return
NULL
;
}
}
bin
+=
bin_to_uint32
(
section_header
->
section_size
);
}
while
(
memcmp
(
section_header
->
section_identify
,
RITE_BINARY_EOF
,
sizeof
(
section_header
->
section_identify
))
!=
0
);
...
...
@@ -684,6 +771,21 @@ mrb_read_irep_file(mrb_state *mrb, FILE* fp)
}
if
(
result
<
MRB_DUMP_OK
)
return
NULL
;
}
else
if
(
memcmp
(
section_header
.
section_identify
,
RITE_SECTION_LV_IDENTIFIER
,
sizeof
(
section_header
.
section_identify
))
==
0
)
{
if
(
!
irep
)
return
NULL
;
else
{
uint8_t
*
const
bin
=
(
uint8_t
*
)
mrb_malloc
(
mrb
,
section_size
);
fseek
(
fp
,
fpos
,
SEEK_SET
);
if
(
fread
((
char
*
)
bin
,
section_size
,
1
,
fp
)
!=
1
)
{
mrb_free
(
mrb
,
bin
);
return
NULL
;
}
result
=
read_section_lv
(
mrb
,
bin
,
irep
,
TRUE
);
mrb_free
(
mrb
,
bin
);
}
if
(
result
<
MRB_DUMP_OK
)
return
NULL
;
}
fseek
(
fp
,
fpos
+
section_size
,
SEEK_SET
);
}
while
(
memcmp
(
section_header
.
section_identify
,
RITE_BINARY_EOF
,
sizeof
(
section_header
.
section_identify
))
!=
0
);
...
...
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