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
5c0b9b70
Commit
5c0b9b70
authored
May 20, 2013
by
Yukihiro "Matz" Matsumoto
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
primary mruby fiber implementation
parent
35ee8516
Changes
16
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
508 additions
and
228 deletions
+508
-228
include/mruby.h
include/mruby.h
+17
-12
include/mruby/gc.h
include/mruby/gc.h
+1
-0
include/mruby/value.h
include/mruby/value.h
+9
-2
mrbgems/default.gembox
mrbgems/default.gembox
+3
-0
mrbgems/mruby-fiber/mrbgem.rake
mrbgems/mruby-fiber/mrbgem.rake
+4
-0
mrbgems/mruby-fiber/src/fiber.c
mrbgems/mruby-fiber/src/fiber.c
+179
-0
mrbgems/mruby-struct/src/struct.c
mrbgems/mruby-struct/src/struct.c
+2
-2
src/backtrace.c
src/backtrace.c
+3
-3
src/class.c
src/class.c
+6
-6
src/error.c
src/error.c
+3
-3
src/gc.c
src/gc.c
+73
-22
src/kernel.c
src/kernel.c
+5
-5
src/proc.c
src/proc.c
+9
-9
src/state.c
src/state.c
+17
-4
src/variable.c
src/variable.c
+11
-11
src/vm.c
src/vm.c
+166
-149
No files found.
include/mruby.h
View file @
5c0b9b70
...
...
@@ -61,16 +61,8 @@ typedef struct {
struct
REnv
*
env
;
}
mrb_callinfo
;
enum
gc_state
{
GC_STATE_NONE
=
0
,
GC_STATE_MARK
,
GC_STATE_SWEEP
};
typedef
struct
mrb_state
{
void
*
jmp
;
mrb_allocf
allocf
;
struct
mrb_context
{
struct
mrb_context
*
prev
;
mrb_value
*
stack
;
mrb_value
*
stbase
,
*
stend
;
...
...
@@ -82,10 +74,24 @@ typedef struct mrb_state {
int
rsize
;
struct
RProc
**
ensure
;
int
esize
;
};
enum
gc_state
{
GC_STATE_NONE
=
0
,
GC_STATE_MARK
,
GC_STATE_SWEEP
};
typedef
struct
mrb_state
{
void
*
jmp
;
mrb_allocf
allocf
;
struct
mrb_context
*
c
;
struct
mrb_context
*
root_c
;
struct
RObject
*
exc
;
struct
iv_tbl
*
globals
;
struct
mrb_irep
**
irep
;
size_t
irep_len
,
irep_capa
;
...
...
@@ -140,7 +146,6 @@ typedef struct mrb_state {
struct
RClass
*
eStandardError_class
;
void
*
ud
;
/* auxiliary data */
}
mrb_state
;
typedef
mrb_value
(
*
mrb_func_t
)(
mrb_state
*
mrb
,
mrb_value
);
...
...
include/mruby/gc.h
View file @
5c0b9b70
...
...
@@ -12,5 +12,6 @@
typedef
void
(
each_object_callback
)(
mrb_state
*
mrb
,
struct
RBasic
*
obj
,
void
*
data
);
void
mrb_objspace_each_objects
(
mrb_state
*
mrb
,
each_object_callback
*
callback
,
void
*
data
);
void
mrb_free_context
(
mrb_state
*
mrb
,
struct
mrb_context
*
c
);
#endif
/* MRUBY_GC_H */
include/mruby/value.h
View file @
5c0b9b70
...
...
@@ -34,7 +34,8 @@ enum mrb_vtype {
MRB_TT_FILE
,
/* 19 */
MRB_TT_ENV
,
/* 20 */
MRB_TT_DATA
,
/* 21 */
MRB_TT_MAXDEFINE
/* 22 */
MRB_TT_FIBER
,
/* 22 */
MRB_TT_MAXDEFINE
/* 23 */
};
typedef
struct
mrb_value
{
...
...
@@ -92,7 +93,8 @@ enum mrb_vtype {
MRB_TT_FILE
,
/* 20 */
MRB_TT_ENV
,
/* 21 */
MRB_TT_DATA
,
/* 22 */
MRB_TT_MAXDEFINE
/* 23 */
MRB_TT_FIBER
,
/* 23 */
MRB_TT_MAXDEFINE
/* 24 */
};
#ifdef MRB_ENDIAN_BIG
...
...
@@ -202,6 +204,11 @@ struct RObject {
#define mrb_immediate_p(x) (mrb_type(x) <= MRB_TT_VOIDP)
#define mrb_special_const_p(x) mrb_immediate_p(x)
struct
RFiber
{
MRB_OBJECT_HEADER
;
struct
mrb_context
*
cxt
;
};
static
inline
mrb_value
mrb_fixnum_value
(
mrb_int
i
)
{
...
...
mrbgems/default.gembox
View file @
5c0b9b70
...
...
@@ -44,6 +44,9 @@ MRuby::GemBox.new do |conf|
# Use ObjectSpace class
conf.gem :core => "mruby-objectspace"
# Use Fiber class
conf.gem :core => "mruby-fiber"
# Generate mirb command
conf.gem :core => "mruby-bin-mirb"
...
...
mrbgems/mruby-fiber/mrbgem.rake
0 → 100644
View file @
5c0b9b70
MRuby
::
Gem
::
Specification
.
new
(
'mruby-fiber'
)
do
|
spec
|
spec
.
license
=
'MIT'
spec
.
authors
=
'mruby developers'
end
mrbgems/mruby-fiber/src/fiber.c
0 → 100644
View file @
5c0b9b70
#include "mruby.h"
#include "mruby/array.h"
#include "mruby/class.h"
#include "mruby/proc.h"
#define FIBER_STACK_INIT_SIZE 64
#define FIBER_CI_INIT_SIZE 8
/*
* call-seq:
* Fiber.new{...} -> obj
*
* Creates an fiber, whose execution is suspend until it explicitly
* resumed using <code>Fibder#resume</code> method.
* <code>resume</code>. Arguments passed to resume will be the value of
* the <code>Fiber.yield</code> expression or will be passed as block
* parameters to the fiber's block if this is the first <code>resume</code>.
*
* Alternatively, when resume is called it evaluates to the arguments passed
* to the next <code>Fiber.yield</code> statement inside the fiber's block
* or to the block value if it runs to completion without any
* <code>Fiber.yield</code>
*/
static
mrb_value
fiber_init
(
mrb_state
*
mrb
,
mrb_value
self
)
{
static
const
struct
mrb_context
mrb_context_zero
=
{
0
};
struct
RFiber
*
f
=
(
struct
RFiber
*
)
self
.
value
.
p
;
struct
mrb_context
*
c
;
struct
RProc
*
p
;
mrb_callinfo
*
ci
;
mrb_value
blk
;
mrb_get_args
(
mrb
,
"&"
,
&
blk
);
if
(
mrb_nil_p
(
blk
))
{
mrb_raise
(
mrb
,
E_ARGUMENT_ERROR
,
"tried to create Fiber object without a block"
);
}
p
=
mrb_proc_ptr
(
blk
);
if
(
MRB_PROC_CFUNC_P
(
p
))
{
mrb_raise
(
mrb
,
E_ARGUMENT_ERROR
,
"tried to create Fiber from C defined method"
);
}
f
->
cxt
=
(
struct
mrb_context
*
)
mrb_malloc
(
mrb
,
sizeof
(
struct
mrb_context
));
*
f
->
cxt
=
mrb_context_zero
;
/* initialize VM stack */
c
=
f
->
cxt
;
c
->
stbase
=
(
mrb_value
*
)
mrb_calloc
(
mrb
,
FIBER_STACK_INIT_SIZE
,
sizeof
(
mrb_value
));
c
->
stend
=
c
->
stbase
+
FIBER_STACK_INIT_SIZE
;
c
->
stack
=
c
->
stbase
;
/* copy receiver from a block */
c
->
stack
[
0
]
=
mrb
->
c
->
stack
[
0
];
/* initialize callinfo stack */
c
->
cibase
=
(
mrb_callinfo
*
)
mrb_calloc
(
mrb
,
FIBER_CI_INIT_SIZE
,
sizeof
(
mrb_callinfo
));
c
->
ciend
=
c
->
cibase
+
FIBER_CI_INIT_SIZE
;
c
->
ci
=
c
->
cibase
;
/* adjust return callinfo */
ci
=
c
->
ci
;
ci
->
target_class
=
p
->
target_class
;
ci
->
proc
=
p
;
ci
->
pc
=
p
->
body
.
irep
->
iseq
;
ci
->
nregs
=
p
->
body
.
irep
->
nregs
;
ci
[
1
]
=
ci
[
0
];
c
->
ci
++
;
/* push dummy callinfo */
return
self
;
}
static
struct
mrb_context
*
fiber_check
(
mrb_state
*
mrb
,
mrb_value
fib
)
{
struct
RFiber
*
f
=
(
struct
RFiber
*
)
fib
.
value
.
p
;
if
(
!
f
->
cxt
)
{
mrb_raise
(
mrb
,
E_ARGUMENT_ERROR
,
"uninitialized Fiber"
);
}
return
f
->
cxt
;
}
static
mrb_value
fiber_result
(
mrb_state
*
mrb
,
mrb_value
*
a
,
int
len
)
{
if
(
len
==
0
)
return
mrb_nil_value
();
if
(
len
==
1
)
return
a
[
0
];
return
mrb_ary_new_from_values
(
mrb
,
len
,
a
);
}
/*
* call-seq:
* fiber.resume(args, ...) -> obj
*
* Resumes the fiber from the point at which the last <code>Fiber.yield</code>
* was called, or starts running it if it is the first call to
* <code>resume</code>. Arguments passed to resume will be the value of
* the <code>Fiber.yield</code> expression or will be passed as block
* parameters to the fiber's block if this is the first <code>resume</code>.
*
* Alternatively, when resume is called it evaluates to the arguments passed
* to the next <code>Fiber.yield</code> statement inside the fiber's block
* or to the block value if it runs to completion without any
* <code>Fiber.yield</code>
*/
static
mrb_value
fiber_resume
(
mrb_state
*
mrb
,
mrb_value
self
)
{
struct
mrb_context
*
c
=
fiber_check
(
mrb
,
self
);
mrb_value
*
a
;
int
len
;
mrb_get_args
(
mrb
,
"*"
,
&
a
,
&
len
);
if
(
!
c
->
prev
)
{
/* first call */
mrb_value
*
b
=
c
->
stack
+
1
;
mrb_value
*
e
=
b
+
len
;
while
(
b
<
e
)
{
*
b
++
=
*
a
++
;
}
c
->
ci
->
argc
=
len
;
c
->
prev
=
mrb
->
c
;
mrb
->
c
=
c
;
return
c
->
ci
->
proc
->
env
->
stack
[
0
];
}
if
(
c
->
ci
==
c
->
cibase
)
{
mrb_raise
(
mrb
,
E_RUNTIME_ERROR
,
"resuming dead Fiber"
);
}
c
->
prev
=
mrb
->
c
;
mrb
->
c
=
c
;
return
fiber_result
(
mrb
,
a
,
len
);
}
/*
* call-seq:
* Fiber.yield(args, ...) -> obj
*
* Yields control back to the context that resumed the fiber, passing
* along any arguments that were passed to it. The fiber will resume
* processing at this point when <code>resume</code> is called next.
* Any arguments passed to the next <code>resume</code> will be the
* value that this <code>Fiber.yield</code> expression evaluates to.
*/
static
mrb_value
fiber_yield
(
mrb_state
*
mrb
,
mrb_value
self
)
{
struct
mrb_context
*
c
=
mrb
->
c
;
mrb_value
*
a
;
int
len
;
if
(
!
c
->
prev
)
{
mrb_raise
(
mrb
,
E_ARGUMENT_ERROR
,
"can't yield from root Fiber"
);
}
mrb_get_args
(
mrb
,
"*"
,
&
a
,
&
len
);
mrb
->
c
=
c
->
prev
;
return
fiber_result
(
mrb
,
a
,
len
);
}
void
mrb_mruby_fiber_gem_init
(
mrb_state
*
mrb
)
{
struct
RClass
*
c
;
c
=
mrb_define_class
(
mrb
,
"Fiber"
,
mrb
->
object_class
);
MRB_SET_INSTANCE_TT
(
c
,
MRB_TT_FIBER
);
mrb_define_method
(
mrb
,
c
,
"initialize"
,
fiber_init
,
MRB_ARGS_NONE
());
mrb_define_method
(
mrb
,
c
,
"resume"
,
fiber_resume
,
MRB_ARGS_ANY
());
mrb_define_class_method
(
mrb
,
c
,
"yield"
,
fiber_yield
,
MRB_ARGS_ANY
());
}
void
mrb_mruby_fiber_gem_final
(
mrb_state
*
mrb
)
{
}
mrbgems/mruby-struct/src/struct.c
View file @
5c0b9b70
...
...
@@ -132,7 +132,7 @@ mrb_struct_getmember(mrb_state *mrb, mrb_value obj, mrb_sym id)
static
mrb_value
mrb_struct_ref
(
mrb_state
*
mrb
,
mrb_value
obj
)
{
return
mrb_struct_getmember
(
mrb
,
obj
,
mrb
->
ci
->
mid
);
return
mrb_struct_getmember
(
mrb
,
obj
,
mrb
->
c
->
c
i
->
mid
);
}
static
mrb_value
mrb_struct_ref0
(
mrb_state
*
mrb
,
mrb_value
obj
)
{
return
RSTRUCT_PTR
(
obj
)[
0
];}
...
...
@@ -191,7 +191,7 @@ mrb_struct_set(mrb_state *mrb, mrb_value obj, mrb_value val)
mrb_value
members
,
slot
,
*
ptr
,
*
ptr_members
;
/* get base id */
name
=
mrb_sym2name_len
(
mrb
,
mrb
->
ci
->
mid
,
&
len
);
name
=
mrb_sym2name_len
(
mrb
,
mrb
->
c
->
c
i
->
mid
,
&
len
);
mid
=
mrb_intern2
(
mrb
,
name
,
len
-
1
);
/* omit last "=" */
members
=
mrb_struct_members
(
mrb
,
obj
);
...
...
src/backtrace.c
View file @
5c0b9b70
...
...
@@ -19,11 +19,11 @@ mrb_print_backtrace(mrb_state *mrb)
printf
(
"trace:
\n
"
);
ciidx
=
mrb_fixnum
(
mrb_obj_iv_get
(
mrb
,
mrb
->
exc
,
mrb_intern
(
mrb
,
"ciidx"
)));
if
(
ciidx
>=
mrb
->
c
iend
-
mrb
->
cibase
)
if
(
ciidx
>=
mrb
->
c
->
ciend
-
mrb
->
c
->
cibase
)
ciidx
=
10
;
/* ciidx is broken... */
for
(
i
=
ciidx
;
i
>=
0
;
i
--
)
{
ci
=
&
mrb
->
cibase
[
i
];
ci
=
&
mrb
->
c
->
c
ibase
[
i
];
filename
=
"(unknown)"
;
line
=
-
1
;
...
...
@@ -38,7 +38,7 @@ mrb_print_backtrace(mrb_state *mrb)
mrb_code
*
pc
;
if
(
i
+
1
<=
ciidx
)
{
pc
=
mrb
->
cibase
[
i
+
1
].
pc
;
pc
=
mrb
->
c
->
c
ibase
[
i
+
1
].
pc
;
}
else
{
pc
=
(
mrb_code
*
)
mrb_voidp
(
mrb_obj_iv_get
(
mrb
,
mrb
->
exc
,
mrb_intern
(
mrb
,
"lastpc"
)));
...
...
src/class.c
View file @
5c0b9b70
...
...
@@ -391,14 +391,14 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
{
char
c
;
int
i
=
0
;
mrb_value
*
sp
=
mrb
->
stack
+
1
;
mrb_value
*
sp
=
mrb
->
c
->
stack
+
1
;
va_list
ap
;
int
argc
=
mrb
->
ci
->
argc
;
int
argc
=
mrb
->
c
->
c
i
->
argc
;
int
opt
=
0
;
va_start
(
ap
,
format
);
if
(
argc
<
0
)
{
struct
RArray
*
a
=
mrb_ary_ptr
(
mrb
->
stack
[
1
]);
struct
RArray
*
a
=
mrb_ary_ptr
(
mrb
->
c
->
stack
[
1
]);
argc
=
a
->
len
;
sp
=
a
->
ptr
;
...
...
@@ -620,11 +620,11 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
mrb_value
*
p
,
*
bp
;
p
=
va_arg
(
ap
,
mrb_value
*
);
if
(
mrb
->
ci
->
argc
<
0
)
{
bp
=
mrb
->
stack
+
2
;
if
(
mrb
->
c
->
c
i
->
argc
<
0
)
{
bp
=
mrb
->
c
->
stack
+
2
;
}
else
{
bp
=
mrb
->
stack
+
mrb
->
ci
->
argc
+
1
;
bp
=
mrb
->
c
->
stack
+
mrb
->
c
->
ci
->
argc
+
1
;
}
*
p
=
*
bp
;
}
...
...
src/error.c
View file @
5c0b9b70
...
...
@@ -189,12 +189,12 @@ exc_equal(mrb_state *mrb, mrb_value exc)
static
void
exc_debug_info
(
mrb_state
*
mrb
,
struct
RObject
*
exc
)
{
mrb_callinfo
*
ci
=
mrb
->
ci
;
mrb_callinfo
*
ci
=
mrb
->
c
->
c
i
;
mrb_code
*
pc
=
ci
->
pc
;
mrb_obj_iv_set
(
mrb
,
exc
,
mrb_intern2
(
mrb
,
"ciidx"
,
5
),
mrb_fixnum_value
(
ci
-
mrb
->
cibase
));
mrb_obj_iv_set
(
mrb
,
exc
,
mrb_intern2
(
mrb
,
"ciidx"
,
5
),
mrb_fixnum_value
(
ci
-
mrb
->
c
->
c
ibase
));
ci
--
;
while
(
ci
>=
mrb
->
cibase
)
{
while
(
ci
>=
mrb
->
c
->
c
ibase
)
{
if
(
ci
->
proc
&&
!
MRB_PROC_CFUNC_P
(
ci
->
proc
))
{
mrb_irep
*
irep
=
ci
->
proc
->
body
.
irep
;
...
...
src/gc.c
View file @
5c0b9b70
...
...
@@ -386,6 +386,35 @@ add_gray_list(mrb_state *mrb, struct RBasic *obj)
mrb
->
gray_list
=
obj
;
}
static
void
mark_context
(
mrb_state
*
mrb
,
struct
mrb_context
*
c
)
{
size_t
i
;
size_t
e
;
mrb_callinfo
*
ci
;
/* mark stack */
e
=
c
->
stack
-
c
->
stbase
;
if
(
c
->
ci
)
e
+=
c
->
ci
->
nregs
;
if
(
c
->
stbase
+
e
>
c
->
stend
)
e
=
c
->
stend
-
c
->
stbase
;
for
(
i
=
0
;
i
<
e
;
i
++
)
{
mrb_gc_mark_value
(
mrb
,
c
->
stbase
[
i
]);
}
/* mark ensure stack */
e
=
(
c
->
ci
)
?
c
->
ci
->
eidx
:
0
;
for
(
i
=
0
;
i
<
e
;
i
++
)
{
mrb_gc_mark
(
mrb
,
(
struct
RBasic
*
)
c
->
ensure
[
i
]);
}
/* mark closure */
for
(
ci
=
c
->
cibase
;
ci
<=
c
->
ci
;
ci
++
)
{
if
(
!
ci
)
continue
;
mrb_gc_mark
(
mrb
,
(
struct
RBasic
*
)
ci
->
env
);
mrb_gc_mark
(
mrb
,
(
struct
RBasic
*
)
ci
->
proc
);
mrb_gc_mark
(
mrb
,
(
struct
RBasic
*
)
ci
->
target_class
);
}
if
(
c
->
prev
)
mark_context
(
mrb
,
c
->
prev
);
}
static
void
gc_mark_children
(
mrb_state
*
mrb
,
struct
RBasic
*
obj
)
{
...
...
@@ -438,6 +467,15 @@ gc_mark_children(mrb_state *mrb, struct RBasic *obj)
}
break
;
case
MRB_TT_FIBER
:
{
struct
mrb_context
*
c
=
((
struct
RFiber
*
)
obj
)
->
cxt
;
mark_context
(
mrb
,
c
);
((
struct
RFiber
*
)
obj
)
->
cxt
=
NULL
;
}
break
;
case
MRB_TT_ARRAY
:
{
struct
RArray
*
a
=
(
struct
RArray
*
)
obj
;
...
...
@@ -517,6 +555,14 @@ obj_free(mrb_state *mrb, struct RBasic *obj)
}
break
;
case
MRB_TT_FIBER
:
{
struct
mrb_context
*
c
=
((
struct
RFiber
*
)
obj
)
->
cxt
;
mrb_free_context
(
mrb
,
c
);
}
break
;
case
MRB_TT_ARRAY
:
if
(
obj
->
flags
&
MRB_ARY_SHARED
)
mrb_ary_decref
(
mrb
,
((
struct
RArray
*
)
obj
)
->
aux
.
shared
);
...
...
@@ -557,9 +603,7 @@ static void
root_scan_phase
(
mrb_state
*
mrb
)
{
int
j
;
size_t
i
;
size_t
e
;
mrb_callinfo
*
ci
;
size_t
i
,
e
;
if
(
!
is_minor_gc
(
mrb
))
{
mrb
->
gray_list
=
0
;
...
...
@@ -577,25 +621,8 @@ root_scan_phase(mrb_state *mrb)
mrb_gc_mark
(
mrb
,
(
struct
RBasic
*
)
mrb
->
top_self
);
/* mark exception */
mrb_gc_mark
(
mrb
,
(
struct
RBasic
*
)
mrb
->
exc
);
/* mark stack */
e
=
mrb
->
stack
-
mrb
->
stbase
;
if
(
mrb
->
ci
)
e
+=
mrb
->
ci
->
nregs
;
if
(
mrb
->
stbase
+
e
>
mrb
->
stend
)
e
=
mrb
->
stend
-
mrb
->
stbase
;
for
(
i
=
0
;
i
<
e
;
i
++
)
{
mrb_gc_mark_value
(
mrb
,
mrb
->
stbase
[
i
]);
}
/* mark ensure stack */
e
=
(
mrb
->
ci
)
?
mrb
->
ci
->
eidx
:
0
;
for
(
i
=
0
;
i
<
e
;
i
++
)
{
mrb_gc_mark
(
mrb
,
(
struct
RBasic
*
)
mrb
->
ensure
[
i
]);
}
/* mark closure */
for
(
ci
=
mrb
->
cibase
;
ci
<=
mrb
->
ci
;
ci
++
)
{
if
(
!
ci
)
continue
;
mrb_gc_mark
(
mrb
,
(
struct
RBasic
*
)
ci
->
env
);
mrb_gc_mark
(
mrb
,
(
struct
RBasic
*
)
ci
->
proc
);
mrb_gc_mark
(
mrb
,
(
struct
RBasic
*
)
ci
->
target_class
);
}
mark_context
(
mrb
,
mrb
->
c
);
/* mark irep pool */
if
(
mrb
->
irep
)
{
size_t
len
=
mrb
->
irep_len
;
...
...
@@ -643,6 +670,30 @@ gc_gray_mark(mrb_state *mrb, struct RBasic *obj)
children
+=
(
int
)
obj
->
flags
;
break
;
case
MRB_TT_FIBER
:
{
struct
mrb_context
*
c
=
((
struct
RFiber
*
)
obj
)
->
cxt
;
size_t
i
;
mrb_callinfo
*
ci
;
/* mark stack */
i
=
c
->
stack
-
c
->
stbase
;
if
(
c
->
ci
)
i
+=
c
->
ci
->
nregs
;
if
(
c
->
stbase
+
i
>
c
->
stend
)
i
=
c
->
stend
-
c
->
stbase
;
children
+=
i
;
/* mark ensure stack */
children
+=
(
c
->
ci
)
?
c
->
ci
->
eidx
:
0
;
/* mark closure */
if
(
c
->
cibase
)
{
for
(
i
=
0
,
ci
=
c
->
cibase
;
ci
<=
c
->
ci
;
i
++
,
ci
++
)
;
}
children
+=
i
;
}
break
;
case
MRB_TT_ARRAY
:
{
struct
RArray
*
a
=
(
struct
RArray
*
)
obj
;
...
...
src/kernel.c
View file @
5c0b9b70
...
...
@@ -214,19 +214,19 @@ mrb_f_send(mrb_state *mrb, mrb_value self)
static
mrb_value
mrb_f_block_given_p_m
(
mrb_state
*
mrb
,
mrb_value
self
)
{
mrb_callinfo
*
ci
=
mrb
->
ci
;
mrb_callinfo
*
ci
=
mrb
->
c
->
c
i
;
mrb_value
*
bp
;
mrb_bool
given_p
;
bp
=
mrb
->
stbase
+
ci
->
stackidx
+
1
;
bp
=
mrb
->
c
->
stbase
+
ci
->
stackidx
+
1
;
ci
--
;
if
(
ci
<=
mrb
->
cibase
)
{
if
(
ci
<=
mrb
->
c
->
c
ibase
)
{
given_p
=
0
;
}
else
{
/* block_given? called within block; check upper scope */
if
(
ci
->
proc
->
env
&&
ci
->
proc
->
env
->
stack
)
{
given_p
=
!
(
ci
->
proc
->
env
->
stack
==
mrb
->
stbase
||
given_p
=
!
(
ci
->
proc
->
env
->
stack
==
mrb
->
c
->
stbase
||
mrb_nil_p
(
ci
->
proc
->
env
->
stack
[
1
]));
}
else
{
...
...
@@ -894,7 +894,7 @@ mrb_f_raise(mrb_state *mrb, mrb_value self)
/* fall through */
default:
exc
=
mrb_make_exception
(
mrb
,
argc
,
a
);
mrb_obj_iv_set
(
mrb
,
mrb_obj_ptr
(
exc
),
mrb_intern2
(
mrb
,
"lastpc"
,
6
),
mrb_voidp_value
(
mrb
->
ci
->
pc
));
mrb_obj_iv_set
(
mrb
,
mrb_obj_ptr
(
exc
),
mrb_intern2
(
mrb
,
"lastpc"
,
6
),
mrb_voidp_value
(
mrb
->
c
->
c
i
->
pc
));
mrb_exc_raise
(
mrb
,
exc
);
break
;
}
...
...
src/proc.c
View file @
5c0b9b70
...
...
@@ -19,7 +19,7 @@ mrb_proc_new(mrb_state *mrb, mrb_irep *irep)
struct
RProc
*
p
;
p
=
(
struct
RProc
*
)
mrb_obj_alloc
(
mrb
,
MRB_TT_PROC
,
mrb
->
proc_class
);
p
->
target_class
=
(
mrb
->
c
i
)
?
mrb
->
ci
->
target_class
:
0
;
p
->
target_class
=
(
mrb
->
c
->
ci
)
?
mrb
->
c
->
ci
->
target_class
:
0
;
p
->
body
.
irep
=
irep
;
p
->
env
=
0
;
...
...
@@ -31,16 +31,16 @@ closure_setup(mrb_state *mrb, struct RProc *p, int nlocals)
{
struct
REnv
*
e
;
if
(
!
mrb
->
ci
->
env
)
{
e
=
(
struct
REnv
*
)
mrb_obj_alloc
(
mrb
,
MRB_TT_ENV
,
(
struct
RClass
*
)
mrb
->
ci
->
proc
->
env
);
if
(
!
mrb
->
c
->
c
i
->
env
)
{
e
=
(
struct
REnv
*
)
mrb_obj_alloc
(
mrb
,
MRB_TT_ENV
,
(
struct
RClass
*
)
mrb
->
c
->
c
i
->
proc
->
env
);
e
->
flags
=
(
unsigned
int
)
nlocals
;
e
->
mid
=
mrb
->
ci
->
mid
;
e
->
cioff
=
mrb
->
c
i
-
mrb
->
cibase
;
e
->
stack
=
mrb
->
stack
;
mrb
->
ci
->
env
=
e
;
e
->
mid
=
mrb
->
c
->
c
i
->
mid
;
e
->
cioff
=
mrb
->
c
->
ci
-
mrb
->
c
->
cibase
;
e
->
stack
=
mrb
->
c
->
stack
;
mrb
->
c
->
c
i
->
env
=
e
;
}
else
{
e
=
mrb
->
ci
->
env
;
e
=
mrb
->
c
->
c
i
->
env
;
}
p
->
env
=
e
;
}
...
...
@@ -50,7 +50,7 @@ mrb_closure_new(mrb_state *mrb, mrb_irep *irep)
{
struct
RProc
*
p
=
mrb_proc_new
(
mrb
,
irep
);
closure_setup
(
mrb
,
p
,
mrb
->
ci
->
proc
->
body
.
irep
->
nlocals
);
closure_setup
(
mrb
,
p
,
mrb
->
c
->
c
i
->
proc
->
body
.
irep
->
nlocals
);
return
p
;
}
...
...
src/state.c
View file @
5c0b9b70
...
...
@@ -25,6 +25,7 @@ mrb_state*
mrb_open_allocf
(
mrb_allocf
f
,
void
*
ud
)
{
static
const
mrb_state
mrb_state_zero
=
{
0
};
static
const
struct
mrb_context
mrb_context_zero
=
{
0
};
mrb_state
*
mrb
=
(
mrb_state
*
)(
f
)(
NULL
,
NULL
,
sizeof
(
mrb_state
),
ud
);
if
(
mrb
==
NULL
)
return
NULL
;
...
...
@@ -34,7 +35,11 @@ mrb_open_allocf(mrb_allocf f, void *ud)
mrb
->
current_white_part
=
MRB_GC_WHITE_A
;
mrb_init_heap
(
mrb
);
mrb
->
c
=
(
struct
mrb_context
*
)
mrb_malloc
(
mrb
,
sizeof
(
struct
mrb_context
));
*
mrb
->
c
=
mrb_context_zero
;
mrb
->
root_c
=
mrb
->
c
;
mrb_init_core
(
mrb
);
return
mrb
;
}
...
...
@@ -106,6 +111,17 @@ mrb_irep_free(mrb_state *mrb, struct mrb_irep *irep)
mrb_free
(
mrb
,
irep
);
}
void
mrb_free_context
(
mrb_state
*
mrb
,
struct
mrb_context
*
c
)
{
if
(
!
c
)
return
;
mrb_free
(
mrb
,
c
->
stbase
);
mrb_free
(
mrb
,
c
->
cibase
);
mrb_free
(
mrb
,
c
->
rescue
);
mrb_free
(
mrb
,
c
->
ensure
);
mrb_free
(
mrb
,
c
);
}
void
mrb_close
(
mrb_state
*
mrb
)
{
...
...
@@ -115,14 +131,11 @@ mrb_close(mrb_state *mrb)
/* free */
mrb_gc_free_gv
(
mrb
);
mrb_free
(
mrb
,
mrb
->
stbase
);
mrb_free
(
mrb
,
mrb
->
cibase
);
for
(
i
=
0
;
i
<
mrb
->
irep_len
;
i
++
)
{
mrb_irep_free
(
mrb
,
mrb
->
irep
[
i
]);
}
mrb_free
(
mrb
,
mrb
->
irep
);
mrb_free
(
mrb
,
mrb
->
rescue
);
mrb_free
(
mrb
,
mrb
->
ensure
);
mrb_free_context
(
mrb
,
mrb
->
root_c
);
mrb_free_symtbl
(
mrb
);
mrb_free_heap
(
mrb
);
mrb_alloca_free
(
mrb
);
...
...
src/variable.c
View file @
5c0b9b70
...
...
@@ -579,14 +579,14 @@ mrb_value
mrb_vm_iv_get
(
mrb_state
*
mrb
,
mrb_sym
sym
)
{
/* get self */
return
mrb_iv_get
(
mrb
,
mrb
->
stack
[
0
],
sym
);
return
mrb_iv_get
(
mrb
,
mrb
->
c
->
stack
[
0
],
sym
);
}
void
mrb_vm_iv_set
(
mrb_state
*
mrb
,
mrb_sym
sym
,
mrb_value
v
)
{
/* get self */
mrb_iv_set
(
mrb
,
mrb
->
stack
[
0
],
sym
,
v
);
mrb_iv_set
(
mrb
,
mrb
->
c
->
stack
[
0
],
sym
,
v
);
}
static
int
...
...
@@ -763,9 +763,9 @@ mrb_cv_defined(mrb_state *mrb, mrb_value mod, mrb_sym sym)
mrb_value
mrb_vm_cv_get
(
mrb_state
*
mrb
,
mrb_sym
sym
)
{
struct
RClass
*
c
=
mrb
->
ci
->
proc
->
target_class
;
struct
RClass
*
c
=
mrb
->
c
->
c
i
->
proc
->
target_class
;
if
(
!
c
)
c
=
mrb
->
ci
->
target_class
;
if
(
!
c
)
c
=
mrb
->
c
->
c
i
->
target_class
;
return
mrb_mod_cv_get
(
mrb
,
c
,
sym
);
}
...
...
@@ -773,9 +773,9 @@ mrb_vm_cv_get(mrb_state *mrb, mrb_sym sym)
void
mrb_vm_cv_set
(
mrb_state
*
mrb
,
mrb_sym
sym
,
mrb_value
v
)
{
struct
RClass
*
c
=
mrb
->
ci
->
proc
->
target_class
;
struct
RClass
*
c
=
mrb
->
c
->
c
i
->
proc
->
target_class
;
if
(
!
c
)
c
=
mrb
->
ci
->
target_class
;
if
(
!
c
)
c
=
mrb
->
c
->
c
i
->
target_class
;
while
(
c
)
{
if
(
c
->
iv
)
{
iv_tbl
*
t
=
c
->
iv
;
...
...
@@ -788,7 +788,7 @@ mrb_vm_cv_set(mrb_state *mrb, mrb_sym sym, mrb_value v)
}
c
=
c
->
super
;
}
c
=
mrb
->
ci
->
target_class
;
c
=
mrb
->
c
->
c
i
->
target_class
;
if
(
!
c
->
iv
)
{
c
->
iv
=
iv_new
(
mrb
);
}
...
...
@@ -868,9 +868,9 @@ mrb_const_get(mrb_state *mrb, mrb_value mod, mrb_sym sym)
mrb_value
mrb_vm_const_get
(
mrb_state
*
mrb
,
mrb_sym
sym
)
{
struct
RClass
*
c
=
mrb
->
ci
->
proc
->
target_class
;
struct
RClass
*
c
=
mrb
->
c
->
c
i
->
proc
->
target_class
;
if
(
!
c
)
c
=
mrb
->
ci
->
target_class
;
if
(
!
c
)
c
=
mrb
->
c
->
c
i
->
target_class
;
if
(
c
)
{
struct
RClass
*
c2
;
mrb_value
v
;
...
...
@@ -900,9 +900,9 @@ mrb_const_set(mrb_state *mrb, mrb_value mod, mrb_sym sym, mrb_value v)
void
mrb_vm_const_set
(
mrb_state
*
mrb
,
mrb_sym
sym
,
mrb_value
v
)
{
struct
RClass
*
c
=
mrb
->
ci
->
proc
->
target_class
;
struct
RClass
*
c
=
mrb
->
c
->
c
i
->
proc
->
target_class
;
if
(
!
c
)
c
=
mrb
->
ci
->
target_class
;
if
(
!
c
)
c
=
mrb
->
c
->
c
i
->
target_class
;
mrb_obj_iv_set
(
mrb
,
(
struct
RObject
*
)
c
,
sym
,
v
);
}
...
...
src/vm.c
View file @
5c0b9b70
This diff is collapsed.
Click to expand it.
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