Skip to content

Instantly share code, notes, and snippets.

@matz
Created July 7, 2012 16:00
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save matz/3066997 to your computer and use it in GitHub Desktop.
Save matz/3066997 to your computer and use it in GitHub Desktop.
code to migrate between 2 mrb_state
#include "mruby.h"
#include "mruby/string.h"
#include "mruby/array.h"
mrb_value
migrate_simple_value(mrb_state *mrb, mrb_value v, mrb_state *mrb2)
{
mrb_value nv; /* new value */
const char *s;
int len;
nv.tt = v.tt;
switch (mrb_type(v)) {
case MRB_TT_FALSE:
case MRB_TT_TRUE:
case MRB_TT_FIXNUM:
nv.value.i = v.value.i;
break;
case MRB_TT_SYMBOL:
nv = mrb_symbol_value(mrb_intern_str(mrb2, v));
break;
case MRB_TT_FLOAT:
nv.value.f = v.value.f;
break;
case MRB_TT_STRING:
{
struct RString *str = mrb_str_ptr(v);
s = str->ptr;
len = str->len;
nv = mrb_str_new(mrb2, s, len);
}
break;
case MRB_TT_ARRAY:
{
struct RArray *a0, *a1;
int i;
a0 = mrb_ary_ptr(v);
nv = mrb_ary_new_capa(mrb2, a0->len);
a1 = mrb_ary_ptr(nv);
for (i=0; i<a0->len; i++) {
int ai = mrb_gc_arena_save(mrb2);
a1->ptr[i] = migrate_simple_value(mrb, a0->ptr[i], mrb2);
a1->len++;
mrb_gc_arena_restore(mrb2, ai);
}
}
break;
default:
mrb_raise(mrb, E_TYPE_ERROR, "cannot migrate object");
break;
}
return nv;
}
@masuidrive
Copy link

  • @masuidrive: 異なるmrb_state間で値をやりとりするために、直接、もう一方のmrb_valueにアクセスして値コピーしたりしてもいいんですか?ダメな気もするけど、
  • @yukihiro_matz: immediate(fixnum,float,symbol,boolean,nil)以外はダメですね。mrb_state間でデータを受け渡すコードはまだ用意してません。
  • @masuidrive: Threadの代わりにmrb_stateが違うブロックを作る命令を作りたいなと思ってます。受け渡しのコードって結構先ですか?
  • @yukihiro_matz: 渡すものによりますね。あらゆるオブジェクトを受け渡そうとするとかなり大規模なものになりますが、渡すのが数値、文字列、シンボル、それらだけを含んだ配列くらいでよければすぐに作れます。ってか、そういうコードを書くんで(コアに入れず)そっちで使って欲しいです
  • @yukihiro_matz: 書いてみました。コンパイルだけ。未テスト。 code to migrate between 2 mrb_state — Gist - http://bit.ly/N8n48W

https://twitter.com/masuidrive/status/221611038930509825

@masamitsu-murase
Copy link

      a0 = mrb_ary_ptr(v);
      nv = mrb_ary_new_capa(mrb2, a1->len);
      a1 = mrb_ary_ptr(nv);

      a0 = mrb_ary_ptr(v);
      nv = mrb_ary_new_capa(mrb2, a0->len); /* a1 => a0 */
      a1 = mrb_ary_ptr(nv);

ではないでしょうか?

@matz
Copy link
Author

matz commented Jul 9, 2012

そうですね。後からコピペする人のために修正しておきました。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment