Re: A patch for _ENV support

  • From: 云风 <cloudwu@xxxxxxxxx>
  • To: luajit@xxxxxxxxxxxxx
  • Date: Fri, 26 Oct 2012 11:56:47 +0800

IMHO, Let luajit support lua 5.2 is better :)  My point is we don't
need stay on lua 5.1 if luajit fully support lua 5.2.
Anyone implement lua 4.0's tag methods with lua 5's metatable ? or
still use lua 5.0 's vararg arg?

2012/10/26 Coda Highland <chighland@xxxxxxxxx>:
> I never said they were equivalent. I also never said that setfenv() is
> better. What I said was that you can implement setfenv() using _ENV in
> order to make code that works in Lua 5.1, Lua 5.2, and LuaJIT.
>
> /s/ Adam
>
> On Thu, Oct 25, 2012 at 7:22 PM, 云风 <cloudwu@xxxxxxxxx> wrote:
>> I think _ENV is better than setfenv , because it simplify  the
>> language . _ENV is only a syntactic sugar , so that we don't need the
>> concept of global and environment in the language.
>>
>> setfenv is not equal to _ENV. For example, if we need to change the
>> environment each call , we can pass the _ENV explicitly .
>>
>> function foobar(_ENV)
>>   a = 1
>>   coroutine.yield()
>>   a = 2
>> end
>>
>> 2012/10/25 Coda Highland <chighland@xxxxxxxxx>:
>>> On Thu, Oct 25, 2012 at 12:06 AM, 云风 <cloudwu@xxxxxxxxx> wrote:
>>>> It looks like that  Mike dislike _ENV  ;) But I really need it  to
>>>> compatible my lua 5.2 code in luajit 2.0 .
>>>>
>>>> So I make a patch to support it. I guess someone would need it , too.
>>>>
>>>> Here it is:
>>>>
>>>> diff --git a/src/lib_base.c b/src/lib_base.c
>>>> index 568216e..b58a5a4 100644
>>>> --- a/src/lib_base.c
>>>> +++ b/src/lib_base.c
>>>> @@ -363,6 +363,10 @@ static int load_aux(lua_State *L, int status, int 
>>>> envarg)
>>>>        GCtab *t = tabV(L->base+envarg-1);
>>>>        setgcref(fn->c.env, obj2gco(t));
>>>>        lj_gc_objbarrier(L, fn, t);
>>>> +      if (LJ_52) {
>>>> +        lua_pushvalue(L, envarg);
>>>> +        lua_setupvalue(L, -2, 1);
>>>> +         }
>>>>      }
>>>>      return 1;
>>>>    } else {
>>>> diff --git a/src/lj_lex.c b/src/lj_lex.c
>>>> index b54d2a2..59b2b84 100644
>>>> --- a/src/lj_lex.c
>>>> +++ b/src/lj_lex.c
>>>> @@ -381,6 +381,7 @@ int lj_lex_setup(lua_State *L, LexState *ls)
>>>>    ls->lookahead = TK_eof;  /* No look-ahead token. */
>>>>    ls->linenumber = 1;
>>>>    ls->lastline = 1;
>>>> +  ls->env = NULL;
>>>>    lj_str_resizebuf(ls->L, &ls->sb, LJ_MIN_SBUF);
>>>>    next(ls);  /* Read-ahead first char. */
>>>>    if (ls->current == 0xef && ls->n >= 2 && char2int(ls->p[0]) == 0xbb &&
>>>> diff --git a/src/lj_lex.h b/src/lj_lex.h
>>>> index d16461a..37c15eb 100644
>>>> --- a/src/lj_lex.h
>>>> +++ b/src/lj_lex.h
>>>> @@ -73,6 +73,7 @@ typedef struct LexState {
>>>>    BCInsLine *bcstack;  /* Stack for bytecode instructions/line numbers. */
>>>>    MSize sizebcstack;   /* Size of bytecode stack. */
>>>>    uint32_t level;      /* Syntactical nesting level. */
>>>> +  GCstr *env;  /* const _ENV */
>>>>  } LexState;
>>>>
>>>>  LJ_FUNC int lj_lex_setup(lua_State *L, LexState *ls);
>>>> diff --git a/src/lj_load.c b/src/lj_load.c
>>>> index e30421e..5a389af 100644
>>>> --- a/src/lj_load.c
>>>> +++ b/src/lj_load.c
>>>> @@ -40,6 +40,9 @@ static TValue *cpparser(lua_State *L, lua_CFunction
>>>> dummy, void *ud)
>>>>    }
>>>>    pt = bc ? lj_bcread(ls) : lj_parse(ls);
>>>>    fn = lj_func_newL_empty(L, pt, tabref(L->env));
>>>> +  if (LJ_52) {
>>>> +    settabV(L, uvval(&gcref(fn->l.uvptr[0])->uv), tabref(L->env));     /*
>>>> Set env table to upvalue 1 */
>>>> +  }
>>>>    /* Don't combine above/below into one statement. */
>>>>    setfuncV(L, L->top++, fn);
>>>>    return NULL;
>>>> diff --git a/src/lj_parse.c b/src/lj_parse.c
>>>> index 29def7b..2f435a5 100644
>>>> --- a/src/lj_parse.c
>>>> +++ b/src/lj_parse.c
>>>> @@ -1112,6 +1112,12 @@ static MSize var_lookup_(FuncState *fs, GCstr
>>>> *name, ExpDesc *e, int first)
>>>>         fscope_uvmark(fs, reg);  /* Scope now has an upvalue. */
>>>>        return (MSize)(e->u.s.aux = (uint32_t)fs->varmap[reg]);
>>>>      } else {
>>>> +      if (LJ_52 && name == fs->ls->env && fs->prev == NULL) {
>>>> +        fscope_uvmark(fs,0);
>>>> +        expr_init(e, VUPVAL, 0);
>>>> +        e->u.s.aux = 0;
>>>> +        return 0;
>>>> +      }
>>>>        MSize vidx = var_lookup_(fs->prev, name, e, 0);  /* Var in outer 
>>>> func? */
>>>>        if ((int32_t)vidx >= 0) {  /* Yes, make it an upvalue here. */
>>>>         e->u.s.info = (uint8_t)var_lookup_uv(fs, vidx, e);
>>>> @@ -1128,7 +1134,9 @@ static MSize var_lookup_(FuncState *fs, GCstr
>>>> *name, ExpDesc *e, int first)
>>>>
>>>>  /* Lookup variable name. */
>>>>  #define var_lookup(ls, e) \
>>>> -  var_lookup_((ls)->fs, lex_str(ls), (e), 1)
>>>> +  var_lookup_((ls)->fs, lex_str(ls), (e), 1); if (LJ_52 && (e)->k ==
>>>> VGLOBAL) var_global_((ls), (e))
>>>> +
>>>> +static void var_global_(LexState *ls, ExpDesc *e);
>>>>
>>>>  /* -- Goto an label handling 
>>>> ---------------------------------------------- */
>>>>
>>>> @@ -1687,6 +1695,18 @@ static void expr_index(FuncState *fs, ExpDesc
>>>> *t, ExpDesc *e)
>>>>    t->u.s.aux = expr_toanyreg(fs, e);  /* 0..255: register */
>>>>  }
>>>>
>>>> +/* Convert global to _ENV index. */
>>>> +static void var_global_(LexState *ls, ExpDesc *e)
>>>> +{
>>>> +  FuncState *fs = ls->fs;
>>>> +  ExpDesc key;
>>>> +  expr_init(&key, VKSTR, 0);
>>>> +  key.u.sval = e->u.sval;
>>>> +  var_lookup_(fs, ls->env, e, 1);
>>>> +  expr_toanyreg(fs, e);
>>>> +  expr_index(fs, e, &key);
>>>> +}
>>>> +
>>>>  /* Parse index expression with named field. */
>>>>  static void expr_field(LexState *ls, ExpDesc *v)
>>>>  {
>>>> @@ -2732,6 +2752,16 @@ GCproto *lj_parse(LexState *ls)
>>>>    fs.bcbase = NULL;
>>>>    fs.bclim = 0;
>>>>    fs.flags |= PROTO_VARARG;  /* Main chunk is always a vararg func. */
>>>> +
>>>> +  if (LJ_52) {
>>>> +    /* Create upvalue named _ENV */
>>>> +    ls->env = lj_parse_keepstr(ls, "_ENV", 4);  /* Anchor _ENV
>>>> string, 4 is sizeof _ENV */
>>>> +    var_new(ls, 0, ls->env);
>>>> +    fs.uvmap[0] = 0;
>>>> +    fs.uvtmp[0] = 0;
>>>> +    fs.nuv = 1;
>>>> +  }
>>>> +
>>>>    fscope_begin(&fs, &bl, 0);
>>>>    bcemit_AD(&fs, BC_FUNCV, 0, 0);  /* Placeholder. */
>>>>    lj_lex_next(ls);  /* Read-ahead first token. */
>>>>
>>>>
>>>> --
>>>> http://blog.codingnow.com
>>>>
>>>
>>> Most people just go the other way around -- it's not all that hard to
>>> implement setfenv() in terms of _ENV to make Lua 5.2 capable of
>>> running Lua 5.1 scripts.
>>>
>>> /s/ Adam
>>>
>>
>>
>>
>> --
>> http://blog.codingnow.com
>>
>



-- 
http://blog.codingnow.com

Other related posts: