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
46e50492
Commit
46e50492
authored
May 23, 2015
by
take_cheeze
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Move `mrb_codedump_all` to "src/codedump.c".
Related to #2760.
parent
b97c6d10
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
453 additions
and
447 deletions
+453
-447
src/codedump.c
src/codedump.c
+453
-0
src/codegen.c
src/codegen.c
+0
-447
No files found.
src/codedump.c
0 → 100644
View file @
46e50492
#include "mruby.h"
#include "mruby/irep.h"
#include "mruby/debug.h"
#include "mruby/opcode.h"
#include "mruby/string.h"
#include "mruby/proc.h"
#ifdef ENABLE_STDIO
static
int
print_r
(
mrb_state
*
mrb
,
mrb_irep
*
irep
,
size_t
n
,
int
pre
)
{
size_t
i
;
if
(
n
==
0
)
return
0
;
for
(
i
=
0
;
i
+
1
<
irep
->
nlocals
;
i
++
)
{
if
(
irep
->
lv
[
i
].
r
==
n
)
{
mrb_sym
sym
=
irep
->
lv
[
i
].
name
;
if
(
pre
)
printf
(
" "
);
printf
(
"R%d:%s"
,
(
int
)
n
,
mrb_sym2name
(
mrb
,
sym
));
return
1
;
}
}
return
0
;
}
#define RA 1
#define RB 2
#define RAB 3
static
void
print_lv
(
mrb_state
*
mrb
,
mrb_irep
*
irep
,
mrb_code
c
,
int
r
)
{
int
pre
=
0
;
if
(
!
irep
->
lv
||
((
!
(
r
&
RA
)
||
GETARG_A
(
c
)
>=
irep
->
nlocals
)
&&
(
!
(
r
&
RB
)
||
GETARG_B
(
c
)
>=
irep
->
nlocals
)))
{
printf
(
"
\n
"
);
return
;
}
printf
(
"
\t
; "
);
if
(
r
&
RA
)
{
pre
=
print_r
(
mrb
,
irep
,
GETARG_A
(
c
),
0
);
}
if
(
r
&
RB
)
{
print_r
(
mrb
,
irep
,
GETARG_B
(
c
),
pre
);
}
printf
(
"
\n
"
);
}
#endif
static
void
codedump
(
mrb_state
*
mrb
,
mrb_irep
*
irep
)
{
#ifdef ENABLE_STDIO
int
i
;
int
ai
;
mrb_code
c
;
const
char
*
file
=
NULL
,
*
next_file
;
int32_t
line
;
if
(
!
irep
)
return
;
printf
(
"irep %p nregs=%d nlocals=%d pools=%d syms=%d reps=%d
\n
"
,
(
void
*
)
irep
,
irep
->
nregs
,
irep
->
nlocals
,
(
int
)
irep
->
plen
,
(
int
)
irep
->
slen
,
(
int
)
irep
->
rlen
);
for
(
i
=
0
;
i
<
(
int
)
irep
->
ilen
;
i
++
)
{
ai
=
mrb_gc_arena_save
(
mrb
);
next_file
=
mrb_debug_get_filename
(
irep
,
i
);
if
(
next_file
&&
file
!=
next_file
)
{
printf
(
"file: %s
\n
"
,
next_file
);
file
=
next_file
;
}
line
=
mrb_debug_get_line
(
irep
,
i
);
if
(
line
<
0
)
{
printf
(
" "
);
}
else
{
printf
(
"%5d "
,
line
);
}
printf
(
"%03d "
,
i
);
c
=
irep
->
iseq
[
i
];
switch
(
GET_OPCODE
(
c
))
{
case
OP_NOP
:
printf
(
"OP_NOP
\n
"
);
break
;
case
OP_MOVE
:
printf
(
"OP_MOVE
\t
R%d
\t
R%d
\t
"
,
GETARG_A
(
c
),
GETARG_B
(
c
));
print_lv
(
mrb
,
irep
,
c
,
RAB
);
break
;
case
OP_LOADL
:
{
mrb_value
v
=
irep
->
pool
[
GETARG_Bx
(
c
)];
mrb_value
s
=
mrb_inspect
(
mrb
,
v
);
printf
(
"OP_LOADL
\t
R%d
\t
L(%d)
\t
; %s"
,
GETARG_A
(
c
),
GETARG_Bx
(
c
),
RSTRING_PTR
(
s
));
}
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_LOADI
:
printf
(
"OP_LOADI
\t
R%d
\t
%d
\t
"
,
GETARG_A
(
c
),
GETARG_sBx
(
c
));
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_LOADSYM
:
printf
(
"OP_LOADSYM
\t
R%d
\t
:%s"
,
GETARG_A
(
c
),
mrb_sym2name
(
mrb
,
irep
->
syms
[
GETARG_Bx
(
c
)]));
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_LOADNIL
:
printf
(
"OP_LOADNIL
\t
R%d
\t\t
"
,
GETARG_A
(
c
));
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_LOADSELF
:
printf
(
"OP_LOADSELF
\t
R%d
\t\t
"
,
GETARG_A
(
c
));
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_LOADT
:
printf
(
"OP_LOADT
\t
R%d
\t\t
"
,
GETARG_A
(
c
));
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_LOADF
:
printf
(
"OP_LOADF
\t
R%d
\t\t
"
,
GETARG_A
(
c
));
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_GETGLOBAL
:
printf
(
"OP_GETGLOBAL
\t
R%d
\t
:%s"
,
GETARG_A
(
c
),
mrb_sym2name
(
mrb
,
irep
->
syms
[
GETARG_Bx
(
c
)]));
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_SETGLOBAL
:
printf
(
"OP_SETGLOBAL
\t
:%s
\t
R%d
\t
"
,
mrb_sym2name
(
mrb
,
irep
->
syms
[
GETARG_Bx
(
c
)]),
GETARG_A
(
c
));
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_GETCONST
:
printf
(
"OP_GETCONST
\t
R%d
\t
:%s"
,
GETARG_A
(
c
),
mrb_sym2name
(
mrb
,
irep
->
syms
[
GETARG_Bx
(
c
)]));
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_SETCONST
:
printf
(
"OP_SETCONST
\t
:%s
\t
R%d
\t
"
,
mrb_sym2name
(
mrb
,
irep
->
syms
[
GETARG_Bx
(
c
)]),
GETARG_A
(
c
));
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_GETMCNST
:
printf
(
"OP_GETMCNST
\t
R%d
\t
R%d::%s"
,
GETARG_A
(
c
),
GETARG_A
(
c
),
mrb_sym2name
(
mrb
,
irep
->
syms
[
GETARG_Bx
(
c
)]));
print_lv
(
mrb
,
irep
,
c
,
RAB
);
break
;
case
OP_SETMCNST
:
printf
(
"OP_SETMCNST
\t
R%d::%s
\t
R%d"
,
GETARG_A
(
c
)
+
1
,
mrb_sym2name
(
mrb
,
irep
->
syms
[
GETARG_Bx
(
c
)]),
GETARG_A
(
c
));
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_GETIV
:
printf
(
"OP_GETIV
\t
R%d
\t
%s"
,
GETARG_A
(
c
),
mrb_sym2name
(
mrb
,
irep
->
syms
[
GETARG_Bx
(
c
)]));
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_SETIV
:
printf
(
"OP_SETIV
\t
%s
\t
R%d"
,
mrb_sym2name
(
mrb
,
irep
->
syms
[
GETARG_Bx
(
c
)]),
GETARG_A
(
c
));
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_GETUPVAR
:
printf
(
"OP_GETUPVAR
\t
R%d
\t
%d
\t
%d"
,
GETARG_A
(
c
),
GETARG_B
(
c
),
GETARG_C
(
c
));
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_SETUPVAR
:
printf
(
"OP_SETUPVAR
\t
R%d
\t
%d
\t
%d"
,
GETARG_A
(
c
),
GETARG_B
(
c
),
GETARG_C
(
c
));
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_GETCV
:
printf
(
"OP_GETCV
\t
R%d
\t
%s"
,
GETARG_A
(
c
),
mrb_sym2name
(
mrb
,
irep
->
syms
[
GETARG_Bx
(
c
)]));
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_SETCV
:
printf
(
"OP_SETCV
\t
%s
\t
R%d"
,
mrb_sym2name
(
mrb
,
irep
->
syms
[
GETARG_Bx
(
c
)]),
GETARG_A
(
c
));
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_JMP
:
printf
(
"OP_JMP
\t\t
%03d
\n
"
,
i
+
GETARG_sBx
(
c
));
break
;
case
OP_JMPIF
:
printf
(
"OP_JMPIF
\t
R%d
\t
%03d
\n
"
,
GETARG_A
(
c
),
i
+
GETARG_sBx
(
c
));
break
;
case
OP_JMPNOT
:
printf
(
"OP_JMPNOT
\t
R%d
\t
%03d
\n
"
,
GETARG_A
(
c
),
i
+
GETARG_sBx
(
c
));
break
;
case
OP_SEND
:
printf
(
"OP_SEND
\t
R%d
\t
:%s
\t
%d
\n
"
,
GETARG_A
(
c
),
mrb_sym2name
(
mrb
,
irep
->
syms
[
GETARG_B
(
c
)]),
GETARG_C
(
c
));
break
;
case
OP_SENDB
:
printf
(
"OP_SENDB
\t
R%d
\t
:%s
\t
%d
\n
"
,
GETARG_A
(
c
),
mrb_sym2name
(
mrb
,
irep
->
syms
[
GETARG_B
(
c
)]),
GETARG_C
(
c
));
break
;
case
OP_TAILCALL
:
printf
(
"OP_TAILCALL
\t
R%d
\t
:%s
\t
%d
\n
"
,
GETARG_A
(
c
),
mrb_sym2name
(
mrb
,
irep
->
syms
[
GETARG_B
(
c
)]),
GETARG_C
(
c
));
break
;
case
OP_SUPER
:
printf
(
"OP_SUPER
\t
R%d
\t
%d
\n
"
,
GETARG_A
(
c
),
GETARG_C
(
c
));
break
;
case
OP_ARGARY
:
printf
(
"OP_ARGARY
\t
R%d
\t
%d:%d:%d:%d"
,
GETARG_A
(
c
),
(
GETARG_Bx
(
c
)
>>
10
)
&
0x3f
,
(
GETARG_Bx
(
c
)
>>
9
)
&
0x1
,
(
GETARG_Bx
(
c
)
>>
4
)
&
0x1f
,
(
GETARG_Bx
(
c
)
>>
0
)
&
0xf
);
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_ENTER
:
printf
(
"OP_ENTER
\t
%d:%d:%d:%d:%d:%d:%d
\n
"
,
(
GETARG_Ax
(
c
)
>>
18
)
&
0x1f
,
(
GETARG_Ax
(
c
)
>>
13
)
&
0x1f
,
(
GETARG_Ax
(
c
)
>>
12
)
&
0x1
,
(
GETARG_Ax
(
c
)
>>
7
)
&
0x1f
,
(
GETARG_Ax
(
c
)
>>
2
)
&
0x1f
,
(
GETARG_Ax
(
c
)
>>
1
)
&
0x1
,
GETARG_Ax
(
c
)
&
0x1
);
break
;
case
OP_RETURN
:
printf
(
"OP_RETURN
\t
R%d"
,
GETARG_A
(
c
));
switch
(
GETARG_B
(
c
))
{
case
OP_R_NORMAL
:
case
OP_R_RETURN
:
printf
(
"
\t
return"
);
break
;
case
OP_R_BREAK
:
printf
(
"
\t
break"
);
break
;
default:
printf
(
"
\t
broken"
);
break
;
break
;
}
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_BLKPUSH
:
printf
(
"OP_BLKPUSH
\t
R%d
\t
%d:%d:%d:%d"
,
GETARG_A
(
c
),
(
GETARG_Bx
(
c
)
>>
10
)
&
0x3f
,
(
GETARG_Bx
(
c
)
>>
9
)
&
0x1
,
(
GETARG_Bx
(
c
)
>>
4
)
&
0x1f
,
(
GETARG_Bx
(
c
)
>>
0
)
&
0xf
);
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_LAMBDA
:
printf
(
"OP_LAMBDA
\t
R%d
\t
I(%+d)
\t
%d"
,
GETARG_A
(
c
),
GETARG_b
(
c
)
+
1
,
GETARG_c
(
c
));
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_RANGE
:
printf
(
"OP_RANGE
\t
R%d
\t
R%d
\t
%d"
,
GETARG_A
(
c
),
GETARG_B
(
c
),
GETARG_C
(
c
));
print_lv
(
mrb
,
irep
,
c
,
RAB
);
break
;
case
OP_METHOD
:
printf
(
"OP_METHOD
\t
R%d
\t
:%s"
,
GETARG_A
(
c
),
mrb_sym2name
(
mrb
,
irep
->
syms
[
GETARG_B
(
c
)]));
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_ADD
:
printf
(
"OP_ADD
\t
R%d
\t
:%s
\t
%d
\n
"
,
GETARG_A
(
c
),
mrb_sym2name
(
mrb
,
irep
->
syms
[
GETARG_B
(
c
)]),
GETARG_C
(
c
));
break
;
case
OP_ADDI
:
printf
(
"OP_ADDI
\t
R%d
\t
:%s
\t
%d
\n
"
,
GETARG_A
(
c
),
mrb_sym2name
(
mrb
,
irep
->
syms
[
GETARG_B
(
c
)]),
GETARG_C
(
c
));
break
;
case
OP_SUB
:
printf
(
"OP_SUB
\t
R%d
\t
:%s
\t
%d
\n
"
,
GETARG_A
(
c
),
mrb_sym2name
(
mrb
,
irep
->
syms
[
GETARG_B
(
c
)]),
GETARG_C
(
c
));
break
;
case
OP_SUBI
:
printf
(
"OP_SUBI
\t
R%d
\t
:%s
\t
%d
\n
"
,
GETARG_A
(
c
),
mrb_sym2name
(
mrb
,
irep
->
syms
[
GETARG_B
(
c
)]),
GETARG_C
(
c
));
break
;
case
OP_MUL
:
printf
(
"OP_MUL
\t
R%d
\t
:%s
\t
%d
\n
"
,
GETARG_A
(
c
),
mrb_sym2name
(
mrb
,
irep
->
syms
[
GETARG_B
(
c
)]),
GETARG_C
(
c
));
break
;
case
OP_DIV
:
printf
(
"OP_DIV
\t
R%d
\t
:%s
\t
%d
\n
"
,
GETARG_A
(
c
),
mrb_sym2name
(
mrb
,
irep
->
syms
[
GETARG_B
(
c
)]),
GETARG_C
(
c
));
break
;
case
OP_LT
:
printf
(
"OP_LT
\t
R%d
\t
:%s
\t
%d
\n
"
,
GETARG_A
(
c
),
mrb_sym2name
(
mrb
,
irep
->
syms
[
GETARG_B
(
c
)]),
GETARG_C
(
c
));
break
;
case
OP_LE
:
printf
(
"OP_LE
\t
R%d
\t
:%s
\t
%d
\n
"
,
GETARG_A
(
c
),
mrb_sym2name
(
mrb
,
irep
->
syms
[
GETARG_B
(
c
)]),
GETARG_C
(
c
));
break
;
case
OP_GT
:
printf
(
"OP_GT
\t
R%d
\t
:%s
\t
%d
\n
"
,
GETARG_A
(
c
),
mrb_sym2name
(
mrb
,
irep
->
syms
[
GETARG_B
(
c
)]),
GETARG_C
(
c
));
break
;
case
OP_GE
:
printf
(
"OP_GE
\t
R%d
\t
:%s
\t
%d
\n
"
,
GETARG_A
(
c
),
mrb_sym2name
(
mrb
,
irep
->
syms
[
GETARG_B
(
c
)]),
GETARG_C
(
c
));
break
;
case
OP_EQ
:
printf
(
"OP_EQ
\t
R%d
\t
:%s
\t
%d
\n
"
,
GETARG_A
(
c
),
mrb_sym2name
(
mrb
,
irep
->
syms
[
GETARG_B
(
c
)]),
GETARG_C
(
c
));
break
;
case
OP_STOP
:
printf
(
"OP_STOP
\n
"
);
break
;
case
OP_ARRAY
:
printf
(
"OP_ARRAY
\t
R%d
\t
R%d
\t
%d"
,
GETARG_A
(
c
),
GETARG_B
(
c
),
GETARG_C
(
c
));
print_lv
(
mrb
,
irep
,
c
,
RAB
);
break
;
case
OP_ARYCAT
:
printf
(
"OP_ARYCAT
\t
R%d
\t
R%d
\t
"
,
GETARG_A
(
c
),
GETARG_B
(
c
));
print_lv
(
mrb
,
irep
,
c
,
RAB
);
break
;
case
OP_ARYPUSH
:
printf
(
"OP_ARYPUSH
\t
R%d
\t
R%d
\t
"
,
GETARG_A
(
c
),
GETARG_B
(
c
));
print_lv
(
mrb
,
irep
,
c
,
RAB
);
break
;
case
OP_AREF
:
printf
(
"OP_AREF
\t
R%d
\t
R%d
\t
%d"
,
GETARG_A
(
c
),
GETARG_B
(
c
),
GETARG_C
(
c
));
print_lv
(
mrb
,
irep
,
c
,
RAB
);
break
;
case
OP_APOST
:
printf
(
"OP_APOST
\t
R%d
\t
%d
\t
%d"
,
GETARG_A
(
c
),
GETARG_B
(
c
),
GETARG_C
(
c
));
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_STRING
:
{
mrb_value
v
=
irep
->
pool
[
GETARG_Bx
(
c
)];
mrb_value
s
=
mrb_str_dump
(
mrb
,
mrb_str_new
(
mrb
,
RSTRING_PTR
(
v
),
RSTRING_LEN
(
v
)));
printf
(
"OP_STRING
\t
R%d
\t
L(%d)
\t
; %s"
,
GETARG_A
(
c
),
GETARG_Bx
(
c
),
RSTRING_PTR
(
s
));
}
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_STRCAT
:
printf
(
"OP_STRCAT
\t
R%d
\t
R%d
\t
"
,
GETARG_A
(
c
),
GETARG_B
(
c
));
print_lv
(
mrb
,
irep
,
c
,
RAB
);
break
;
case
OP_HASH
:
printf
(
"OP_HASH
\t
R%d
\t
R%d
\t
%d"
,
GETARG_A
(
c
),
GETARG_B
(
c
),
GETARG_C
(
c
));
print_lv
(
mrb
,
irep
,
c
,
RAB
);
break
;
case
OP_OCLASS
:
printf
(
"OP_OCLASS
\t
R%d
\t\t
"
,
GETARG_A
(
c
));
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_CLASS
:
printf
(
"OP_CLASS
\t
R%d
\t
:%s"
,
GETARG_A
(
c
),
mrb_sym2name
(
mrb
,
irep
->
syms
[
GETARG_B
(
c
)]));
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_MODULE
:
printf
(
"OP_MODULE
\t
R%d
\t
:%s"
,
GETARG_A
(
c
),
mrb_sym2name
(
mrb
,
irep
->
syms
[
GETARG_B
(
c
)]));
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_EXEC
:
printf
(
"OP_EXEC
\t
R%d
\t
I(%+d)"
,
GETARG_A
(
c
),
GETARG_Bx
(
c
)
+
1
);
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_SCLASS
:
printf
(
"OP_SCLASS
\t
R%d
\t
R%d
\t
"
,
GETARG_A
(
c
),
GETARG_B
(
c
));
print_lv
(
mrb
,
irep
,
c
,
RAB
);
break
;
case
OP_TCLASS
:
printf
(
"OP_TCLASS
\t
R%d
\t\t
"
,
GETARG_A
(
c
));
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_ERR
:
{
mrb_value
v
=
irep
->
pool
[
GETARG_Bx
(
c
)];
mrb_value
s
=
mrb_str_dump
(
mrb
,
mrb_str_new
(
mrb
,
RSTRING_PTR
(
v
),
RSTRING_LEN
(
v
)));
printf
(
"OP_ERR
\t
%s
\n
"
,
RSTRING_PTR
(
s
));
}
break
;
case
OP_EPUSH
:
printf
(
"OP_EPUSH
\t
:I(%+d)
\n
"
,
GETARG_Bx
(
c
)
+
1
);
break
;
case
OP_ONERR
:
printf
(
"OP_ONERR
\t
%03d
\n
"
,
i
+
GETARG_sBx
(
c
));
break
;
case
OP_RESCUE
:
printf
(
"OP_RESCUE
\t
R%d
\t\t
"
,
GETARG_A
(
c
));
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_RAISE
:
printf
(
"OP_RAISE
\t
R%d
\t\t
"
,
GETARG_A
(
c
));
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_POPERR
:
printf
(
"OP_POPERR
\t
%d
\t\t
"
,
GETARG_A
(
c
));
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_EPOP
:
printf
(
"OP_EPOP
\t
%d
\n
"
,
GETARG_A
(
c
));
break
;
default:
printf
(
"OP_unknown %d
\t
%d
\t
%d
\t
%d
\n
"
,
GET_OPCODE
(
c
),
GETARG_A
(
c
),
GETARG_B
(
c
),
GETARG_C
(
c
));
break
;
}
mrb_gc_arena_restore
(
mrb
,
ai
);
}
printf
(
"
\n
"
);
#endif
}
static
void
codedump_recur
(
mrb_state
*
mrb
,
mrb_irep
*
irep
)
{
size_t
i
;
codedump
(
mrb
,
irep
);
for
(
i
=
0
;
i
<
irep
->
rlen
;
i
++
)
{
codedump_recur
(
mrb
,
irep
->
reps
[
i
]);
}
}
void
mrb_codedump_all
(
mrb_state
*
mrb
,
struct
RProc
*
proc
)
{
codedump_recur
(
mrb
,
proc
->
body
.
irep
);
}
src/codegen.c
View file @
46e50492
...
...
@@ -2687,453 +2687,6 @@ loop_pop(codegen_scope *s, int val)
if
(
val
)
push
();
}
#ifdef ENABLE_STDIO
static
int
print_r
(
mrb_state
*
mrb
,
mrb_irep
*
irep
,
size_t
n
,
int
pre
)
{
size_t
i
;
if
(
n
==
0
)
return
0
;
for
(
i
=
0
;
i
+
1
<
irep
->
nlocals
;
i
++
)
{
if
(
irep
->
lv
[
i
].
r
==
n
)
{
mrb_sym
sym
=
irep
->
lv
[
i
].
name
;
if
(
pre
)
printf
(
" "
);
printf
(
"R%d:%s"
,
(
int
)
n
,
mrb_sym2name
(
mrb
,
sym
));
return
1
;
}
}
return
0
;
}
#define RA 1
#define RB 2
#define RAB 3
static
void
print_lv
(
mrb_state
*
mrb
,
mrb_irep
*
irep
,
mrb_code
c
,
int
r
)
{
int
pre
=
0
;
if
(
!
irep
->
lv
||
((
!
(
r
&
RA
)
||
GETARG_A
(
c
)
>=
irep
->
nlocals
)
&&
(
!
(
r
&
RB
)
||
GETARG_B
(
c
)
>=
irep
->
nlocals
)))
{
printf
(
"
\n
"
);
return
;
}
printf
(
"
\t
; "
);
if
(
r
&
RA
)
{
pre
=
print_r
(
mrb
,
irep
,
GETARG_A
(
c
),
0
);
}
if
(
r
&
RB
)
{
print_r
(
mrb
,
irep
,
GETARG_B
(
c
),
pre
);
}
printf
(
"
\n
"
);
}
#endif
static
void
codedump
(
mrb_state
*
mrb
,
mrb_irep
*
irep
)
{
#ifdef ENABLE_STDIO
int
i
;
int
ai
;
mrb_code
c
;
const
char
*
file
=
NULL
,
*
next_file
;
int32_t
line
;
if
(
!
irep
)
return
;
printf
(
"irep %p nregs=%d nlocals=%d pools=%d syms=%d reps=%d
\n
"
,
(
void
*
)
irep
,
irep
->
nregs
,
irep
->
nlocals
,
(
int
)
irep
->
plen
,
(
int
)
irep
->
slen
,
(
int
)
irep
->
rlen
);
for
(
i
=
0
;
i
<
(
int
)
irep
->
ilen
;
i
++
)
{
ai
=
mrb_gc_arena_save
(
mrb
);
next_file
=
mrb_debug_get_filename
(
irep
,
i
);
if
(
next_file
&&
file
!=
next_file
)
{
printf
(
"file: %s
\n
"
,
next_file
);
file
=
next_file
;
}
line
=
mrb_debug_get_line
(
irep
,
i
);
if
(
line
<
0
)
{
printf
(
" "
);
}
else
{
printf
(
"%5d "
,
line
);
}
printf
(
"%03d "
,
i
);
c
=
irep
->
iseq
[
i
];
switch
(
GET_OPCODE
(
c
))
{
case
OP_NOP
:
printf
(
"OP_NOP
\n
"
);
break
;
case
OP_MOVE
:
printf
(
"OP_MOVE
\t
R%d
\t
R%d
\t
"
,
GETARG_A
(
c
),
GETARG_B
(
c
));
print_lv
(
mrb
,
irep
,
c
,
RAB
);
break
;
case
OP_LOADL
:
{
mrb_value
v
=
irep
->
pool
[
GETARG_Bx
(
c
)];
mrb_value
s
=
mrb_inspect
(
mrb
,
v
);
printf
(
"OP_LOADL
\t
R%d
\t
L(%d)
\t
; %s"
,
GETARG_A
(
c
),
GETARG_Bx
(
c
),
RSTRING_PTR
(
s
));
}
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_LOADI
:
printf
(
"OP_LOADI
\t
R%d
\t
%d
\t
"
,
GETARG_A
(
c
),
GETARG_sBx
(
c
));
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_LOADSYM
:
printf
(
"OP_LOADSYM
\t
R%d
\t
:%s"
,
GETARG_A
(
c
),
mrb_sym2name
(
mrb
,
irep
->
syms
[
GETARG_Bx
(
c
)]));
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_LOADNIL
:
printf
(
"OP_LOADNIL
\t
R%d
\t\t
"
,
GETARG_A
(
c
));
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_LOADSELF
:
printf
(
"OP_LOADSELF
\t
R%d
\t\t
"
,
GETARG_A
(
c
));
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_LOADT
:
printf
(
"OP_LOADT
\t
R%d
\t\t
"
,
GETARG_A
(
c
));
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_LOADF
:
printf
(
"OP_LOADF
\t
R%d
\t\t
"
,
GETARG_A
(
c
));
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_GETGLOBAL
:
printf
(
"OP_GETGLOBAL
\t
R%d
\t
:%s"
,
GETARG_A
(
c
),
mrb_sym2name
(
mrb
,
irep
->
syms
[
GETARG_Bx
(
c
)]));
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_SETGLOBAL
:
printf
(
"OP_SETGLOBAL
\t
:%s
\t
R%d
\t
"
,
mrb_sym2name
(
mrb
,
irep
->
syms
[
GETARG_Bx
(
c
)]),
GETARG_A
(
c
));
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_GETCONST
:
printf
(
"OP_GETCONST
\t
R%d
\t
:%s"
,
GETARG_A
(
c
),
mrb_sym2name
(
mrb
,
irep
->
syms
[
GETARG_Bx
(
c
)]));
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_SETCONST
:
printf
(
"OP_SETCONST
\t
:%s
\t
R%d
\t
"
,
mrb_sym2name
(
mrb
,
irep
->
syms
[
GETARG_Bx
(
c
)]),
GETARG_A
(
c
));
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_GETMCNST
:
printf
(
"OP_GETMCNST
\t
R%d
\t
R%d::%s"
,
GETARG_A
(
c
),
GETARG_A
(
c
),
mrb_sym2name
(
mrb
,
irep
->
syms
[
GETARG_Bx
(
c
)]));
print_lv
(
mrb
,
irep
,
c
,
RAB
);
break
;
case
OP_SETMCNST
:
printf
(
"OP_SETMCNST
\t
R%d::%s
\t
R%d"
,
GETARG_A
(
c
)
+
1
,
mrb_sym2name
(
mrb
,
irep
->
syms
[
GETARG_Bx
(
c
)]),
GETARG_A
(
c
));
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_GETIV
:
printf
(
"OP_GETIV
\t
R%d
\t
%s"
,
GETARG_A
(
c
),
mrb_sym2name
(
mrb
,
irep
->
syms
[
GETARG_Bx
(
c
)]));
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_SETIV
:
printf
(
"OP_SETIV
\t
%s
\t
R%d"
,
mrb_sym2name
(
mrb
,
irep
->
syms
[
GETARG_Bx
(
c
)]),
GETARG_A
(
c
));
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_GETUPVAR
:
printf
(
"OP_GETUPVAR
\t
R%d
\t
%d
\t
%d"
,
GETARG_A
(
c
),
GETARG_B
(
c
),
GETARG_C
(
c
));
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_SETUPVAR
:
printf
(
"OP_SETUPVAR
\t
R%d
\t
%d
\t
%d"
,
GETARG_A
(
c
),
GETARG_B
(
c
),
GETARG_C
(
c
));
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_GETCV
:
printf
(
"OP_GETCV
\t
R%d
\t
%s"
,
GETARG_A
(
c
),
mrb_sym2name
(
mrb
,
irep
->
syms
[
GETARG_Bx
(
c
)]));
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_SETCV
:
printf
(
"OP_SETCV
\t
%s
\t
R%d"
,
mrb_sym2name
(
mrb
,
irep
->
syms
[
GETARG_Bx
(
c
)]),
GETARG_A
(
c
));
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_JMP
:
printf
(
"OP_JMP
\t\t
%03d
\n
"
,
i
+
GETARG_sBx
(
c
));
break
;
case
OP_JMPIF
:
printf
(
"OP_JMPIF
\t
R%d
\t
%03d
\n
"
,
GETARG_A
(
c
),
i
+
GETARG_sBx
(
c
));
break
;
case
OP_JMPNOT
:
printf
(
"OP_JMPNOT
\t
R%d
\t
%03d
\n
"
,
GETARG_A
(
c
),
i
+
GETARG_sBx
(
c
));
break
;
case
OP_SEND
:
printf
(
"OP_SEND
\t
R%d
\t
:%s
\t
%d
\n
"
,
GETARG_A
(
c
),
mrb_sym2name
(
mrb
,
irep
->
syms
[
GETARG_B
(
c
)]),
GETARG_C
(
c
));
break
;
case
OP_SENDB
:
printf
(
"OP_SENDB
\t
R%d
\t
:%s
\t
%d
\n
"
,
GETARG_A
(
c
),
mrb_sym2name
(
mrb
,
irep
->
syms
[
GETARG_B
(
c
)]),
GETARG_C
(
c
));
break
;
case
OP_TAILCALL
:
printf
(
"OP_TAILCALL
\t
R%d
\t
:%s
\t
%d
\n
"
,
GETARG_A
(
c
),
mrb_sym2name
(
mrb
,
irep
->
syms
[
GETARG_B
(
c
)]),
GETARG_C
(
c
));
break
;
case
OP_SUPER
:
printf
(
"OP_SUPER
\t
R%d
\t
%d
\n
"
,
GETARG_A
(
c
),
GETARG_C
(
c
));
break
;
case
OP_ARGARY
:
printf
(
"OP_ARGARY
\t
R%d
\t
%d:%d:%d:%d"
,
GETARG_A
(
c
),
(
GETARG_Bx
(
c
)
>>
10
)
&
0x3f
,
(
GETARG_Bx
(
c
)
>>
9
)
&
0x1
,
(
GETARG_Bx
(
c
)
>>
4
)
&
0x1f
,
(
GETARG_Bx
(
c
)
>>
0
)
&
0xf
);
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_ENTER
:
printf
(
"OP_ENTER
\t
%d:%d:%d:%d:%d:%d:%d
\n
"
,
(
GETARG_Ax
(
c
)
>>
18
)
&
0x1f
,
(
GETARG_Ax
(
c
)
>>
13
)
&
0x1f
,
(
GETARG_Ax
(
c
)
>>
12
)
&
0x1
,
(
GETARG_Ax
(
c
)
>>
7
)
&
0x1f
,
(
GETARG_Ax
(
c
)
>>
2
)
&
0x1f
,
(
GETARG_Ax
(
c
)
>>
1
)
&
0x1
,
GETARG_Ax
(
c
)
&
0x1
);
break
;
case
OP_RETURN
:
printf
(
"OP_RETURN
\t
R%d"
,
GETARG_A
(
c
));
switch
(
GETARG_B
(
c
))
{
case
OP_R_NORMAL
:
case
OP_R_RETURN
:
printf
(
"
\t
return"
);
break
;
case
OP_R_BREAK
:
printf
(
"
\t
break"
);
break
;
default:
printf
(
"
\t
broken"
);
break
;
break
;
}
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_BLKPUSH
:
printf
(
"OP_BLKPUSH
\t
R%d
\t
%d:%d:%d:%d"
,
GETARG_A
(
c
),
(
GETARG_Bx
(
c
)
>>
10
)
&
0x3f
,
(
GETARG_Bx
(
c
)
>>
9
)
&
0x1
,
(
GETARG_Bx
(
c
)
>>
4
)
&
0x1f
,
(
GETARG_Bx
(
c
)
>>
0
)
&
0xf
);
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_LAMBDA
:
printf
(
"OP_LAMBDA
\t
R%d
\t
I(%+d)
\t
%d"
,
GETARG_A
(
c
),
GETARG_b
(
c
)
+
1
,
GETARG_c
(
c
));
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_RANGE
:
printf
(
"OP_RANGE
\t
R%d
\t
R%d
\t
%d"
,
GETARG_A
(
c
),
GETARG_B
(
c
),
GETARG_C
(
c
));
print_lv
(
mrb
,
irep
,
c
,
RAB
);
break
;
case
OP_METHOD
:
printf
(
"OP_METHOD
\t
R%d
\t
:%s"
,
GETARG_A
(
c
),
mrb_sym2name
(
mrb
,
irep
->
syms
[
GETARG_B
(
c
)]));
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_ADD
:
printf
(
"OP_ADD
\t
R%d
\t
:%s
\t
%d
\n
"
,
GETARG_A
(
c
),
mrb_sym2name
(
mrb
,
irep
->
syms
[
GETARG_B
(
c
)]),
GETARG_C
(
c
));
break
;
case
OP_ADDI
:
printf
(
"OP_ADDI
\t
R%d
\t
:%s
\t
%d
\n
"
,
GETARG_A
(
c
),
mrb_sym2name
(
mrb
,
irep
->
syms
[
GETARG_B
(
c
)]),
GETARG_C
(
c
));
break
;
case
OP_SUB
:
printf
(
"OP_SUB
\t
R%d
\t
:%s
\t
%d
\n
"
,
GETARG_A
(
c
),
mrb_sym2name
(
mrb
,
irep
->
syms
[
GETARG_B
(
c
)]),
GETARG_C
(
c
));
break
;
case
OP_SUBI
:
printf
(
"OP_SUBI
\t
R%d
\t
:%s
\t
%d
\n
"
,
GETARG_A
(
c
),
mrb_sym2name
(
mrb
,
irep
->
syms
[
GETARG_B
(
c
)]),
GETARG_C
(
c
));
break
;
case
OP_MUL
:
printf
(
"OP_MUL
\t
R%d
\t
:%s
\t
%d
\n
"
,
GETARG_A
(
c
),
mrb_sym2name
(
mrb
,
irep
->
syms
[
GETARG_B
(
c
)]),
GETARG_C
(
c
));
break
;
case
OP_DIV
:
printf
(
"OP_DIV
\t
R%d
\t
:%s
\t
%d
\n
"
,
GETARG_A
(
c
),
mrb_sym2name
(
mrb
,
irep
->
syms
[
GETARG_B
(
c
)]),
GETARG_C
(
c
));
break
;
case
OP_LT
:
printf
(
"OP_LT
\t
R%d
\t
:%s
\t
%d
\n
"
,
GETARG_A
(
c
),
mrb_sym2name
(
mrb
,
irep
->
syms
[
GETARG_B
(
c
)]),
GETARG_C
(
c
));
break
;
case
OP_LE
:
printf
(
"OP_LE
\t
R%d
\t
:%s
\t
%d
\n
"
,
GETARG_A
(
c
),
mrb_sym2name
(
mrb
,
irep
->
syms
[
GETARG_B
(
c
)]),
GETARG_C
(
c
));
break
;
case
OP_GT
:
printf
(
"OP_GT
\t
R%d
\t
:%s
\t
%d
\n
"
,
GETARG_A
(
c
),
mrb_sym2name
(
mrb
,
irep
->
syms
[
GETARG_B
(
c
)]),
GETARG_C
(
c
));
break
;
case
OP_GE
:
printf
(
"OP_GE
\t
R%d
\t
:%s
\t
%d
\n
"
,
GETARG_A
(
c
),
mrb_sym2name
(
mrb
,
irep
->
syms
[
GETARG_B
(
c
)]),
GETARG_C
(
c
));
break
;
case
OP_EQ
:
printf
(
"OP_EQ
\t
R%d
\t
:%s
\t
%d
\n
"
,
GETARG_A
(
c
),
mrb_sym2name
(
mrb
,
irep
->
syms
[
GETARG_B
(
c
)]),
GETARG_C
(
c
));
break
;
case
OP_STOP
:
printf
(
"OP_STOP
\n
"
);
break
;
case
OP_ARRAY
:
printf
(
"OP_ARRAY
\t
R%d
\t
R%d
\t
%d"
,
GETARG_A
(
c
),
GETARG_B
(
c
),
GETARG_C
(
c
));
print_lv
(
mrb
,
irep
,
c
,
RAB
);
break
;
case
OP_ARYCAT
:
printf
(
"OP_ARYCAT
\t
R%d
\t
R%d
\t
"
,
GETARG_A
(
c
),
GETARG_B
(
c
));
print_lv
(
mrb
,
irep
,
c
,
RAB
);
break
;
case
OP_ARYPUSH
:
printf
(
"OP_ARYPUSH
\t
R%d
\t
R%d
\t
"
,
GETARG_A
(
c
),
GETARG_B
(
c
));
print_lv
(
mrb
,
irep
,
c
,
RAB
);
break
;
case
OP_AREF
:
printf
(
"OP_AREF
\t
R%d
\t
R%d
\t
%d"
,
GETARG_A
(
c
),
GETARG_B
(
c
),
GETARG_C
(
c
));
print_lv
(
mrb
,
irep
,
c
,
RAB
);
break
;
case
OP_APOST
:
printf
(
"OP_APOST
\t
R%d
\t
%d
\t
%d"
,
GETARG_A
(
c
),
GETARG_B
(
c
),
GETARG_C
(
c
));
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_STRING
:
{
mrb_value
v
=
irep
->
pool
[
GETARG_Bx
(
c
)];
mrb_value
s
=
mrb_str_dump
(
mrb
,
mrb_str_new
(
mrb
,
RSTRING_PTR
(
v
),
RSTRING_LEN
(
v
)));
printf
(
"OP_STRING
\t
R%d
\t
L(%d)
\t
; %s"
,
GETARG_A
(
c
),
GETARG_Bx
(
c
),
RSTRING_PTR
(
s
));
}
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_STRCAT
:
printf
(
"OP_STRCAT
\t
R%d
\t
R%d
\t
"
,
GETARG_A
(
c
),
GETARG_B
(
c
));
print_lv
(
mrb
,
irep
,
c
,
RAB
);
break
;
case
OP_HASH
:
printf
(
"OP_HASH
\t
R%d
\t
R%d
\t
%d"
,
GETARG_A
(
c
),
GETARG_B
(
c
),
GETARG_C
(
c
));
print_lv
(
mrb
,
irep
,
c
,
RAB
);
break
;
case
OP_OCLASS
:
printf
(
"OP_OCLASS
\t
R%d
\t\t
"
,
GETARG_A
(
c
));
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_CLASS
:
printf
(
"OP_CLASS
\t
R%d
\t
:%s"
,
GETARG_A
(
c
),
mrb_sym2name
(
mrb
,
irep
->
syms
[
GETARG_B
(
c
)]));
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_MODULE
:
printf
(
"OP_MODULE
\t
R%d
\t
:%s"
,
GETARG_A
(
c
),
mrb_sym2name
(
mrb
,
irep
->
syms
[
GETARG_B
(
c
)]));
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_EXEC
:
printf
(
"OP_EXEC
\t
R%d
\t
I(%+d)"
,
GETARG_A
(
c
),
GETARG_Bx
(
c
)
+
1
);
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_SCLASS
:
printf
(
"OP_SCLASS
\t
R%d
\t
R%d
\t
"
,
GETARG_A
(
c
),
GETARG_B
(
c
));
print_lv
(
mrb
,
irep
,
c
,
RAB
);
break
;
case
OP_TCLASS
:
printf
(
"OP_TCLASS
\t
R%d
\t\t
"
,
GETARG_A
(
c
));
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_ERR
:
{
mrb_value
v
=
irep
->
pool
[
GETARG_Bx
(
c
)];
mrb_value
s
=
mrb_str_dump
(
mrb
,
mrb_str_new
(
mrb
,
RSTRING_PTR
(
v
),
RSTRING_LEN
(
v
)));
printf
(
"OP_ERR
\t
%s
\n
"
,
RSTRING_PTR
(
s
));
}
break
;
case
OP_EPUSH
:
printf
(
"OP_EPUSH
\t
:I(%+d)
\n
"
,
GETARG_Bx
(
c
)
+
1
);
break
;
case
OP_ONERR
:
printf
(
"OP_ONERR
\t
%03d
\n
"
,
i
+
GETARG_sBx
(
c
));
break
;
case
OP_RESCUE
:
printf
(
"OP_RESCUE
\t
R%d
\t\t
"
,
GETARG_A
(
c
));
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_RAISE
:
printf
(
"OP_RAISE
\t
R%d
\t\t
"
,
GETARG_A
(
c
));
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_POPERR
:
printf
(
"OP_POPERR
\t
%d
\t\t
"
,
GETARG_A
(
c
));
print_lv
(
mrb
,
irep
,
c
,
RA
);
break
;
case
OP_EPOP
:
printf
(
"OP_EPOP
\t
%d
\n
"
,
GETARG_A
(
c
));
break
;
default:
printf
(
"OP_unknown %d
\t
%d
\t
%d
\t
%d
\n
"
,
GET_OPCODE
(
c
),
GETARG_A
(
c
),
GETARG_B
(
c
),
GETARG_C
(
c
));
break
;
}
mrb_gc_arena_restore
(
mrb
,
ai
);
}
printf
(
"
\n
"
);
#endif
}
static
void
codedump_recur
(
mrb_state
*
mrb
,
mrb_irep
*
irep
)
{
size_t
i
;
codedump
(
mrb
,
irep
);
for
(
i
=
0
;
i
<
irep
->
rlen
;
i
++
)
{
codedump_recur
(
mrb
,
irep
->
reps
[
i
]);
}
}
void
mrb_codedump_all
(
mrb_state
*
mrb
,
struct
RProc
*
proc
)
{
codedump_recur
(
mrb
,
proc
->
body
.
irep
);
}
MRB_API
struct
RProc
*
mrb_generate_code
(
mrb_state
*
mrb
,
parser_state
*
p
)
{
...
...
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