SMOP

 view release on metacpan or  search on metacpan

p5/src/sv.ri  view on Meta::CPAN

%include <smop/p5.h>
%prefix smop_p5_sv
%attr SV* sv
%attr SMOP__Object* p5interpreter;
%RI.id Wrapped SV*
%idconst STORE
%idconst continuation
%idconst goto

%{
  extern SMOP__Object* SMOP__P5__smop_interpreter;
  SMOP__Object* SMOP__P5__smop_p5interpreter;

  SMOP__Object* SV2SMOP__Object(SMOP__Object* interpreter,SMOP__Object* p5interpreter,SV* sv) {
    return SMOP__P5__SV_create(interpreter,p5interpreter,sv);
  }
  SMOP__Object* SMOP__P5__SV_create(SMOP__Object* interpreter,SMOP__Object* p5interpreter,SV* sv) {
    SMOP__Object* ret =  smop_nagc_alloc(sizeof(smop_p5_sv_struct));
    ret->RI = (SMOP__ResponderInterface*) RI;
    ((smop_p5_sv_struct*)ret)->sv = SvREFCNT_inc(sv);
    ((smop_p5_sv_struct*)ret)->p5interpreter = p5interpreter;
    return ret;
  }

  I32 magic_STORE(pTHX_ IV obj_address,SV* sv) {
    SMOP__Object* object = (SMOP__Object*) obj_address;
    SMOP__Object* interpreter = SMOP__P5__smop_interpreter;
    SMOP__P5__result_sv = NULL;
    SMOP__P5__transfer_to_main_coro(aTHX_ interpreter);

    SMOP__Object* rvalue = SV2SMOP__Object(interpreter,SMOP_REFERENCE(interpreter,SMOP__P5__smop_p5interpreter),sv);


    SMOP__Object* ret = SMOP_DISPATCH(interpreter,SMOP_RI(object),SMOP__ID__STORE,SMOP__NATIVE__capture_create(interpreter,(SMOP__Object*[]) {SMOP_REFERENCE(interpreter,object),rvalue,NULL},(SMOP__Object*[]) {NULL}));
    SMOP_RELEASE(interpreter,ret);
    return 0;
  }
  I32 magic_FETCH(pTHX_ IV obj_address,SV* sv) {

    SMOP__Object* object = (SMOP__Object*) obj_address;
    SMOP__Object* interpreter = SMOP__P5__smop_interpreter;

    SMOP__P5__result_sv = sv;

    SMOP__Object* ret = SMOP_DISPATCH(interpreter,SMOP_RI(object),SMOP__ID__FETCH,SMOP__NATIVE__capture_create(interpreter,(SMOP__Object*[]) {SMOP_REFERENCE(interpreter,object),NULL},(SMOP__Object*[]) {NULL}));

    SV* ret_sv = SMOP__Object2SV(interpreter,aTHX_ ret);

    /*if (ret->RI == RI) {
        SvSetSV_nosteal(sv,ret_sv);
    } else {
    }*/
    sv_setsv_flags(sv,ret_sv, SV_NOSTEAL);
    SMOP__P5__transfer_to_main_coro(aTHX_ interpreter);
    return 0;
  }
  SV* SMOP__Object2SV(SMOP__Object* interpreter,pTHX_ SMOP__Object* object) {
    if (object->RI == (SMOP__ResponderInterface*)RI) {
      SV* ret = ((smop_p5_sv_struct*)object)->sv;
      SMOP_RELEASE(interpreter,object);
      return SvREFCNT_inc(ret);
    } else {
      SV* pointer = newSViv(PTR2IV(object));
      HV* class = gv_stashpv("SMOP::Object", GV_ADD);
      struct ufuncs uf;
      uf.uf_index = PTR2IV(object);
      uf.uf_set = &magic_STORE;
      uf.uf_val = &magic_FETCH;
      SV* sv = sv_bless(newRV_noinc(pointer), class);
      sv_magic(sv,0,PERL_MAGIC_uvar, (char*)&uf,sizeof(uf));
      return sv;
    }
  }
%}

%message {
  /*___NATIVE_CAPTURE_ONLY___;
  ___CONST_IDENTIFIER_ONLY___;*/

  SMOP__P5__smop_interpreter  = interpreter;

  SMOP__Object* invocant = (SMOP__Object*) SMOP__NATIVE__capture_positional(interpreter, capture,0);
  SMOP__Object* ret = SMOP__NATIVE__bool_false;
  PerlInterpreter* my_perl = SMOP__P5__p5interpreter_unbox(interpreter,((smop_p5_sv_struct*)invocant)->p5interpreter);
  %%METHODS%%
  {
    SMOP__P5__smop_p5interpreter = ((smop_p5_sv_struct*)invocant)->p5interpreter;

    int len;
    char* method = SMOP__NATIVE__idconst_fetch_with_null(identifier,&len);

    dSP;

    ENTER;
    SAVETMPS;
    PUSHMARK(SP);
    XPUSHs(SMOP__Object2SV(interpreter,aTHX_ invocant));

    XPUSHs(sv_2mortal(newSVpvn(method,len)));

    int positionals = SMOP__NATIVE__capture_positional_count(interpreter,capture);
    int i;
    for (i=1;i < positionals;i++) {
      SMOP__Object* object = SMOP__NATIVE__capture_positional(interpreter,capture,i);
      XPUSHs(SMOP__Object2SV(interpreter,aTHX_ object));
    }

    PUTBACK;

    int count = call_pv("SMOP::coro_from_methodcall",G_SCALAR);
    if (count != 1) croak("Big trouble");


    SPAGAIN;
 

    SV* on_stack = POPs;
    SV* coro_sv = newSVsv(on_stack);
    assert(coro_sv);
    
    PUTBACK;
    FREETMPS;
    LEAVE;

    SMOP__Object* coro = SMOP__P5__Coro_create(interpreter,SMOP_REFERENCE(interpreter,SMOP__P5__smop_p5interpreter),coro_sv);

    SMOP__Object* frame = SMOP__Yeast__Frame_create(interpreter,SMOP_REFERENCE(interpreter,mold_run_coro));

    SMOP__Object* continuation = SMOP_DISPATCH(interpreter, SMOP_RI(interpreter),
      SMOP__ID__continuation,
      SMOP__NATIVE__capture_create(interpreter,
        (SMOP__Object*[]) {SMOP_REFERENCE(interpreter,interpreter),NULL},
        (SMOP__Object*[]) {NULL}));

    yeast_reg_set(interpreter,frame,0,SMOP_REFERENCE(interpreter,interpreter));
    yeast_reg_set(interpreter,frame,1,coro);
    yeast_reg_set(interpreter,frame,2,continuation);
    SMOP_DISPATCH(interpreter, SMOP_RI(interpreter), SMOP__ID__goto,SMOP__NATIVE__capture_create(interpreter,(SMOP__Object*[]) {SMOP_REFERENCE(interpreter,interpreter), frame, NULL}, (SMOP__Object*[]) {NULL}));

    free(method);
  }
  if (invocant) SMOP_RELEASE(interpreter,invocant);
  SMOP_RELEASE(interpreter,capture);
  return ret;
%}
%method FETCH
  ___VALUE_FETCH___

%method STORE
  ___VALUE_STORE___

%method Str
  STRLEN len;
  char* str = SvPV(((smop_p5_sv_struct*)invocant)->sv,len);
  ret = SMOP__NATIVE__idconst_createn(str,len);

%method int
  ret = SMOP__NATIVE__int_create(SvIV(((smop_p5_sv_struct*)invocant)->sv));

%method DESTROYALL
  SvREFCNT_dec(((smop_p5_sv_struct*)invocant)->sv); 
  SMOP_RELEASE(interpreter,((smop_p5_sv_struct*)invocant)->p5interpreter); 

%method postcircumfix:( )()

  assert(SMOP__NATIVE__capture_positional_count(interpreter,capture) == 2);
  SMOP__Object* real_capture = SMOP__NATIVE__capture_positional(interpreter,capture,1);

  dSP;

  ENTER;
  SAVETMPS;
  PUSHMARK(SP);
  XPUSHs(((smop_p5_sv_struct*)invocant)->sv);

  int positionals = SMOP__NATIVE__capture_positional_count(interpreter,real_capture);
  int i;
  for (i=0;i < positionals;i++) {
    SMOP__Object* object = SMOP__NATIVE__capture_positional(interpreter,real_capture,i);
    XPUSHs(SMOP__Object2SV(interpreter,aTHX_ object));
  }

  SMOP_RELEASE(interpreter,real_capture);

  PUTBACK;

  int count = call_pv("SMOP::coro_from_subcall",G_SCALAR);
  if (count != 1) croak("Big trouble");


  SPAGAIN;
 

  SV* on_stack = POPs;
  SV* coro_sv = newSVsv(on_stack);
  assert(coro_sv);
  
  PUTBACK;
  FREETMPS;
  LEAVE;

  SMOP__Object* coro = SMOP__P5__Coro_create(interpreter,SMOP_REFERENCE(interpreter,SMOP__P5__smop_p5interpreter),coro_sv);

  SMOP__Object* frame = SMOP__Yeast__Frame_create(interpreter,SMOP_REFERENCE(interpreter,mold_run_coro));

  SMOP__Object* continuation = SMOP_DISPATCH(interpreter, SMOP_RI(interpreter),
    SMOP__ID__continuation,
    SMOP__NATIVE__capture_create(interpreter,
      (SMOP__Object*[]) {SMOP_REFERENCE(interpreter,interpreter),NULL},
      (SMOP__Object*[]) {NULL}));

  yeast_reg_set(interpreter,frame,0,SMOP_REFERENCE(interpreter,interpreter));
  yeast_reg_set(interpreter,frame,1,coro);
  yeast_reg_set(interpreter,frame,2,continuation);

  SMOP_DISPATCH(interpreter, SMOP_RI(interpreter), SMOP__ID__goto,SMOP__NATIVE__capture_create(interpreter,(SMOP__Object*[]) {SMOP_REFERENCE(interpreter,interpreter), frame, NULL}, (SMOP__Object*[]) {NULL}));

%yeast mold_run_coro
  my $interpreter;
  my $coro;
  my $back;
  my $void = $coro."set_back"($back);
  my $void = $interpreter."goto"($coro);




( run in 0.369 second using v1.01-cache-2.11-cpan-8f98c5d2c55 )