Show
Ignore:
Timestamp:
05/17/07 16:25:27 (18 months ago)
Author:
krobillard
Message:

Thread safe Thune -

The only globals are now the static ur_global & ur_envGlobal.
Each thread has own data store.
Series data now accessed through functions which take thread pointer.
Word names now part of UrlanEnv? - no longer a binary!
Hold/release now implemented with a block.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • branches/thune/thread_safe/eval.c

    r385 r387  
    1919 
    2020 
    21 #include "os.h" 
    22 #include "urlan.h" 
     21#include "internal.h" 
    2322#include "urlan_atoms.h" 
    24 #include "internal.h" 
    2523#include "bignum.h" 
    2624 
    2725 
     26extern UContext ur_global; 
     27extern UContext ur_envGlobal; 
     28 
    2829extern void uc_console_out( UThread*, UCell* ); 
    2930 
    3031 
    3132#ifdef DEBUG 
    32 void ur_dumpBlock( UIndex blkN ) 
     33void ur_dumpBlock( UThread* ut, UIndex blkN ) 
    3334{ 
    3435    UCell* cell; 
     
    5859 
    5960 
    60 static void _infuseOpcodes( UThread* thr, UIndex blkN ) 
     61static void _infuseOpcodes( UThread* ut, UIndex blkN ) 
    6162{ 
    6263    UBlock* blk; 
    63     UBlock* gblk; 
     64    UContext* global; 
    6465    const UCell* ctx; 
    6566    int wrdN; 
    6667 
    67     blk = ur_bind( blkN, &ur_global ); 
    68  
    69     wrdN = ur_lookup( &ur_global, UR_ATOM_KERNEL_OPS ); 
    70     //assert( wrdN > -1 ); 
    71     if( wrdN > -1 ) 
    72     { 
    73         gblk = ur_blockPtr( GLOBAL_VAL_BLKN ); 
    74         ctx = gblk->ptr.cells + wrdN; 
    75  
    76         assert( ctx->id.type == UT_CONTEXT ); 
    77  
    78         ur_infuse( thr, blk, ctx ); 
     68    global = (ut->env->blocks.arr.used) ? &ur_envGlobal : &ur_global; 
     69 
     70    wrdN = ur_lookup( global, UR_ATOM_KERNEL_OPS ); 
     71    assert( wrdN > -1 ); 
     72    //if( wrdN > -1 ) 
     73    { 
     74        blk = ur_blockPtr( global->ctx.valBlk ); 
     75        ctx = blk->ptr.cells + wrdN; 
     76 
     77        assert( ur_is(ctx, UT_CONTEXT) ); 
     78 
     79        blk = ur_blockPtr( blkN ); 
     80        ur_infuse( ut, blk, ctx ); 
    7981    } 
    8082} 
     
    8688   returned. 
    8789*/ 
    88 static int ur_itLen( UCell* cell ) 
     90static int ur_itLen( UThread* ut, UCell* cell ) 
    8991{ 
    9092    int len = ur_seriesLen( cell ); 
     
    101103  Res may be the same as sel. 
    102104*/ 
    103 int ur_getSelector( UThread* ur_thread, const UCell* sel, UCell* res ) 
     105int ur_getSelector( UThread* ut, const UCell* sel, UCell* res ) 
    104106{ 
    105107#define ATOM_OFF(val,atm)   (((unsigned int) val) - atm) 
     
    107109    UCell* val; 
    108110 
    109     val = ur_wordCell( ur_thread, sel ); 
     111    val = ur_wordCell( ut, sel ); 
    110112    if( ! val ) 
    111113        return 0; 
     
    157159                if( ur_type(val) >= UT_BI_COUNT ) 
    158160                { 
    159                     UDatatypeSelFunc func = ur_thread->env->customDT 
     161                    UDatatypeSelFunc func = ut->env->customDT 
    160162                                [ ur_type(val) - UT_BI_COUNT ].selectAtom; 
    161163                    if( func ) 
    162                         return func( ur_thread, val, sel, res ); 
     164                        return func( ut, val, sel, res ); 
    163165                } 
    164166                goto set_none; 
     
    167169    else 
    168170    { 
    169         if( ur_pick( val, ur_sel(sel) - 1, res ) ) 
     171        if( ur_pick( ut, val, ur_sel(sel) - 1, res ) ) 
    170172            return 1; 
    171173    } 
    172174 
    173     ur_throwErr( ur_thread, UR_EX_SCRIPT, "Invalid select!" ); 
     175    ur_throwErr( UR_ERR_SCRIPT, "Invalid select!" ); 
    174176    return 0; 
    175177 
     
    184186  Returns non-zero if successful. 
    185187*/ 
    186 int ur_setSelector( UThread* ur_thread, const UCell* sel, const UCell* nval ) 
     188int ur_setSelector( UThread* ut, const UCell* sel, const UCell* nval ) 
    187189{ 
    188190    UBlock* blk; 
    189191    UCell* val; 
    190192 
    191     val = ur_wordCell( ur_thread, sel ); 
     193    val = ur_wordCell( ut, sel ); 
    192194    if( ! val ) 
    193195        return 0; 
     
    242244            if( ! ur_selIsAtom(sel) ) 
    243245            { 
    244                 if( ur_poke( val, ur_sel(sel) - 1, nval ) ) 
    245                     return 1; 
    246             } 
    247             break; 
    248     } 
    249  
    250     ur_throwErr( ur_thread, UR_EX_SCRIPT, "Invalid select!" ); 
     246                if( ur_poke( ut, val, ur_sel(sel) - 1, nval ) ) 
     247                    return 1; 
     248            } 
     249            break; 
     250    } 
     251 
     252    ur_throwErr( UR_ERR_SCRIPT, "Invalid select!" ); 
    251253    return 0; 
    252254} 
     
    283285    { 
    284286        UCell* val; 
    285         val = ur_wordCell( ur_thread, tos ); 
     287        val = ur_wordCell( ut, tos ); 
    286288        if( val ) 
    287289        { 
     
    317319 
    318320 
    319 static void _appendTraceBlk( UCellError* err, int n, int it ) 
     321static void _appendTraceBlk( UThread* ut, UCellError* err, int n, int it ) 
    320322{ 
    321323    if( err->traceBlk ) 
     
    334336#define _throwUnbound(th,cell)  _throwUnsetF(th,cell,"unbound") 
    335337 
    336 static void _throwUnsetF( UThread* ur_thread, const UCell* wcell, 
    337                           const char* umsg ) 
     338static void _throwUnsetF( UThread* ut, const UCell* wcell, const char* umsg ) 
    338339{ 
    339340    UString* str; 
    340     str = ur_binPtr( ur_thread->callTempBinN ); 
     341    str = ur_threadTmp( ut ); 
    341342    str->used = 0; 
    342343    ur_atomStr( ur_atom(wcell), str ); 
    343344    ur_termCStr( str ); 
    344     ur_throwErr( ur_thread, UR_EX_SCRIPT, 
    345                  "word '%s is %s", str->ptr.c, umsg ); 
    346 } 
    347  
    348  
    349 /* 
     345    ur_throwErr( UR_ERR_SCRIPT, "word '%s is %s", str->ptr.c, umsg ); 
     346} 
     347 
     348 
     349/** 
    350350   Returns cell pointer or zero if word does not reference a valid cell. 
    351351*/ 
    352 UCell* ur_wordCell( UThread* ur_thread, const UCell* pc ) 
    353 { 
    354     UCell* val; 
    355     int i; 
    356     
    357     i = pc->word.valBlk; 
    358     if( i < 0 ) 
    359     { 
    360         // Find function local frame i. 
    361  
    362         LocalFrame* it; 
    363         LocalFrame* end; 
    364  
    365         it  = UR_LF_BEG; 
    366         end = UR_LF_END; 
    367         while( it != end ) 
    368         { 
    369             if( it->localFrame.n == i ) 
    370             { 
    371                 val = it->localFrame.cell; 
    372                 goto val_set; 
    373             } 
    374             ++it; 
    375         } 
    376  
    377         _throwUnsetF( ur_thread, pc, "out-of-scope local" ); 
     352UCell* ur_wordCell( UThread* ut, const UCell* pc ) 
     353{ 
     354    UBlock* blk; 
     355    int wrdN; 
     356 
     357    wrdN = pc->word.index; 
     358    if( wrdN < 0 ) 
     359    { 
     360        _throwUnbound( ut, pc);     // UR_UNBOUND 
    378361        return 0; 
    379362    } 
    380     else 
    381     { 
    382         val = ur_blockPtr( i )->ptr.cells; 
    383     } 
    384  
    385 val_set: 
    386  
    387     i = pc->word.index; 
    388     if( i < 0 ) 
    389     { 
    390         _throwUnbound(ur_thread, pc); 
    391         return 0; 
    392     } 
    393  
    394     return val + i; 
    395 } 
    396  
    397  
    398 int ur_evalCStr( UThread* ur_thread, const char* cmd, int len ) 
     363 
     364    switch( pc->word.flags & UR_FLAG_BIND_MASK ) 
     365    { 
     366        case UR_BIND_THREAD: 
     367            // ur_blockPtr( pc->word.valBlk ) 
     368            blk = (((UBlock*) ut->blocks.arr.ptr.v) + pc->word.valBlk); 
     369            return blk->ptr.cells + wrdN; 
     370 
     371        case UR_BIND_GLOBAL: 
     372            // ur_blockPtr( pc->word.valBlk ) 
     373            blk = (((UBlock*) ut->env->blocks.arr.ptr.v) - pc->word.valBlk); 
     374            return blk->ptr.cells + wrdN; 
     375 
     376        case UR_BIND_LOCAL: 
     377#if 1 
     378        { 
     379            LocalFrame* it  = UR_LF_BEG; 
     380            LocalFrame* end = UR_LF_END; 
     381            while( it != end ) 
     382            { 
     383                if( it->n == pc->word.wordBlk ) 
     384                    return it->cell + wrdN; 
     385                ++it; 
     386            } 
     387            _throwUnsetF( ut, pc, "out-of-scope local" ); 
     388            return 0; 
     389        } 
     390#else 
     391            if( pc->word.wordBlk != ut->localWordBlk ) 
     392            { 
     393                _throwUnsetF( ut, pc, "out-of-scope local" ); 
     394                return 0; 
     395            } 
     396#if 0 
     397            blk = ((UBlock*) ut->blocks.arr.ptr.v) + BLK_DSTACK; 
     398            return blk->ptr.cells + wrdN + ut->localIdx; 
     399#else 
     400            return ut->localPos + wrdN; 
     401#endif 
     402#endif 
     403    } 
     404 
     405    return 0; 
     406} 
     407 
     408 
     409int ur_evalCStr( UThread* ut, const char* cmd, int len ) 
    399410{ 
    400411    const char* end; 
     
    417428    if( end != cmd ) 
    418429    { 
    419         blkN = ur_tokenize( ur_thread, cmd, end, 0 ); 
     430        blkN = ur_tokenize( ut, cmd, end, 0 ); 
    420431        if( blkN ) 
    421432        { 
    422             _infuseOpcodes( ur_thread, blkN ); 
    423             return ur_eval( ur_thread, blkN, 0 ); 
     433            _infuseOpcodes( ut, blkN ); 
     434            return ur_eval( ut, blkN, 0 ); 
    424435        } 
    425436        return UR_EVAL_ERROR; 
     
    437448  Returns 1 if equivalent or zero if not. 
    438449*/ 
    439 int ur_equal( const UCell* a, const UCell* b ) 
     450int ur_equal( UThread* ut, const UCell* a, const UCell* b ) 
    440451{ 
    441452    switch( ur_type(a) ) 
     
    581592            int len; 
    582593 
    583             if( ur_blockSlice( a, &cpA1, &cpA2 ) ) 
    584             { 
    585                 if( ur_blockSlice( b, &cpB1, &cpB2 ) ) 
     594            if( ur_blockSlice( ut, a, &cpA1, &cpA2 ) ) 
     595            { 
     596                if( ur_blockSlice( ut, b, &cpB1, &cpB2 ) ) 
    586597                { 
    587598                    len = cpB2 - cpB1; 
     
    592603                        while( cpA1 != cpA2 ) 
    593604                        { 
    594                             if( ! ur_equal( cpA1++, cpB1++ ) ) 
     605                            if( ! ur_equal( ut, cpA1++, cpB1++ ) ) 
    595606                                return 0; 
    596607                        } 
     
    610621            int len; 
    611622 
    612             if( ur_stringSlice( a, &cpA1, &cpA2 ) ) 
    613             { 
    614                 if( ur_stringSlice( b, &cpB1, &cpB2 ) ) 
     623            if( ur_stringSlice( ut, a, &cpA1, &cpA2 ) ) 
     624            { 
     625                if( ur_stringSlice( ut, b, &cpB1, &cpB2 ) ) 
    615626                { 
    616627                    // TODO: Handle different encodings. 
     
    628639                } 
    629640            } 
    630             else if( ur_binarySlice( a, &cpA1, &cpA2 ) ) 
    631             { 
    632                 if( ur_binarySlice( b, &cpB1, &cpB2 ) ) 
     641            else if( ur_binarySlice( ut, a, &cpA1, &cpA2 ) ) 
     642            { 
     643                if( ur_binarySlice( ut, b, &cpB1, &cpB2 ) ) 
    633644                    goto eq_bin_slice; 
    634645            } 
     
    643654  Returns 1 if cells are of the same type and value or zero if not. 
    644655*/ 
    645 int ur_same( const UCell* a, const UCell* b ) 
    646 { 
     656int ur_same( UThread* ut, const UCell* a, const UCell* b ) 
     657{ 
     658    (void) ut; 
     659 
    647660    if( ur_type(a) != ur_type(b) ) 
    648661        return 0; 
     
    700713{ 
    701714    UR_S_DROP; 
    702     ur_logic(UR_TOS) = ur_equal( UR_TOS, tos ); 
     715    ur_logic(UR_TOS) = ur_equal( ut, UR_TOS, tos ); 
    703716    ur_initType( UR_TOS, UT_LOGIC ); 
    704717} 
     
    713726    UR_S_DROP; 
    714727 
    715     same = ur_same( res, tos ); 
     728    same = ur_same( ut, res, tos ); 
    716729    ur_initType( res, UT_LOGIC ); 
    717730    ur_logic(res) = same; 
     
    761774    ur_initType(tos, UT_WORD); 
    762775    tos->word.wordBlk = 0; 
    763     tos->word.valBlk  = GLOBAL_VAL_BLKN; 
     776    tos->word.valBlk  = BLK_GLOBAL_VAL; 
    764777    tos->word.index   = t; 
    765778    tos->word.atom    = t; 
     
    772785#if 1 
    773786    UString* str; 
    774     str = ur_binPtr( ur_thread->callTempBinN ); 
     787    str = ur_threadTmp( ut ); 
    775788    str->used = 0; 
    776789    ur_toStr( tos, str, 0 ); 
     
    781794    tos = UR_TOS; 
    782795    ur_initType( tos, UT_STRING ); 
    783     ur_setSeries( tos, ur_thread->callTempBinN, 0 ); 
    784     uc_console_out( ur_thread, tos ); 
     796    ur_setSeries( tos, BIN_THREAD_TMP, 0 ); 
     797    uc_console_out( ut, tos ); 
    785798#else 
    786799    UString str; 
     
    805818UR_CALL( uc_showTOS ) 
    806819{ 
    807     _probe( ur_thread, tos ); 
     820    _probe( ut, tos ); 
    808821    UR_S_SAFE_DROP; 
    809822} 
     
    815828{ 
    816829    UCell* it = tos; 
    817     UCell* end = ur_thread->dstack; 
     830    UCell* end = ut->dstack; 
    818831 
    819832    if( it >= (end + UR_DSTACK_SIZE) ) 
     
    825838    while( it != end ) 
    826839    { 
    827         _probe( ur_thread, it ); 
     840        _probe( ut, it ); 
    828841        --it; 
    829842    } 
     
    857870        if( ur_wordIsUnbound(tos) ) 
    858871        { 
    859             if( tos->word.valBlk == GLOBAL_VAL_BLKN ) 
     872            if( tos->word.valBlk == BLK_GLOBAL_VAL ) 
    860873            { 
    861874                tos->word.index = ur_internWord( &ur_global, ur_atom(tos) ); 
     
    863876            else     
    864877            { 
    865                 _throwUnbound( ur_thread, tos ); 
     878                _throwUnbound( ut, tos ); 
    866879                return; 
    867880            } 
    868881        } 
    869882 
    870         cell = ur_wordCell( ur_thread, tos ); 
     883        cell = ur_wordCell( ut, tos ); 
    871884        if( ! cell ) 
    872885            return; 
     
    888901                if( ur_isAWord(it) ) 
    889902                { 
    890                     cell = ur_wordCell( ur_thread, it ); 
     903                    cell = ur_wordCell( ut, it ); 
    891904                    if( ! cell ) 
    892905                        return; 
    893                     ur_pick( val, n++, cell ); 
     906                    ur_pick( ut, val, n++, cell ); 
    894907                } 
    895908                ++it; 
     
    902915                if( ur_isAWord(it) ) 
    903916                { 
    904                     cell = ur_wordCell( ur_thread, it ); 
     917                    cell = ur_wordCell( ut, it ); 
    905918                    if( ! cell ) 
    906919                        return; 
     
    945958    if( ur_isAWord(tos) ) 
    946959    { 
    947         val = ur_wordCell( ur_thread, tos ); 
     960        val = ur_wordCell( ut, tos ); 
    948961        if( val ) 
    949962        { 
     
    968981                /* 
    969982                if( ur_is(ctx, UT_UNSET) ) 
    970                     _throwUnset( ur_thread, ctx ); 
     983                    _throwUnset( ut, ctx ); 
    971984                */ 
    972985            } 
     
    981994    } 
    982995 
    983     ur_throwErr( ur_thread, UR_EX_DATATYPE, "get expected word!" ); 
     996    ur_throwErr( UR_ERR_DATATYPE, "get expected word!" ); 
    984997} 
    985998 
     
    10131026                char* spA; 
    10141027                char* spB; 
    1015                 if( ur_stringSlice(val, &spA, &spB) && spA ) 
     1028                if( ur_stringSlice(ut, val, &spA, &spB) && spA ) 
    10161029                { 
    10171030                    ur_initType(val, UT_WORD); 
    1018                     ur_setUnbound( val, UR_INTERN( spA, spB - spA ) ); 
     1031                    ur_setUnbound( val, ur_intern( spA, spB - spA ) ); 
    10191032                } 
    10201033            } 
     
    10761089                    // Must copy so UArray->used will be accurate. 
    10771090                    UIndex binN; 
    1078                     binN = ur_makeBinaryFrom( val ); 
     1091                    binN = ur_makeBinaryFrom( ut, val ); 
    10791092                    ur_setSeries(val, binN, 0); 
    10801093                } 
     
    11611174            if( ur_is(val, UT_STRING) ) 
    11621175            { 
    1163                 ur_clone( val, UR_COPY_ALL, 0 ); 
     1176                ur_clone( ut, val, UR_COPY_ALL, 0 ); 
    11641177                UR_S_DROP; 
    11651178                return; 
     
    11681181    } 
    11691182 
    1170     uc_as( ur_thread, tos ); 
     1183    uc_as( ut, tos ); 
    11711184} 
    11721185 
     
    11911204    } 
    11921205 
    1193     ur_throwErr( ur_thread, UR_EX_DATATYPE, "Invalid bind values" ); 
     1206    ur_throwErr( UR_ERR_DATATYPE, "Invalid bind values" ); 
    11941207} 
    11951208 
    11961209 
    11971210// Find function local frame for N. 
    1198 static UCell* _localCells( UThread* ur_thread, int n ) 
    1199 { 
    1200     LocalFrame* it; 
    1201     LocalFrame* end; 
    1202     it  = UR_LF_BEG; 
    1203     end = UR_LF_END; 
     1211static UCell* _localCells( UThread* ut, UIndex wordBlk ) 
     1212{ 
     1213#if 0 
     1214    assert( ut->localWordBlk == wordBlk ); 
     1215    return ut->localPos; 
     1216#else 
     1217    LocalFrame* it  = UR_LF_BEG; 
     1218    LocalFrame* end = UR_LF_END; 
    12041219    while( it != end ) 
    12051220    { 
    1206         if( it->localFrame.n == n ) 
    1207             return it->localFrame.cell; 
     1221        if( it->n == wordBlk ) 
     1222            return it->cell; 
    12081223        ++it; 
    12091224    } 
    12101225    assert( 0 ); 
    12111226    return 0; 
     1227#endif 
    12121228} 
    12131229 
     
    12171233  the context. 
    12181234*/ 
    1219 void ur_infuse( UThread* thr, UBlock* blk, const UContext* cc ) 
     1235void ur_infuse( UThread* ut, UBlock* blk, const UContext* cc ) 
    12201236{ 
    12211237    UCell* it  = blk->ptr.cells; 
     
    12241240    int flags; 
    12251241 
    1226     if( cc->ctx.valBlk < 0 ) 
    1227     { 
    1228         values = _localCells( thr, cc->ctx.valBlk ); 
     1242    if( ur_bindType(cc) == UR_BIND_LOCAL ) 
     1243    { 
     1244        values = _localCells( ut, cc->ctx.wordBlk ); 
    12291245    } 
    12301246    else 
     
    12511267        else if( ur_is(it, UT_BLOCK) || ur_is(it, UT_PAREN) ) 
    12521268        { 
    1253             ur_infuse( thr, ur_blockPtr( it->series.n ), cc ); 
     1269            ur_infuse( ut, ur_blockPtr( it->series.n ), cc ); 
    12541270        } 
    12551271        else if( ur_is(it, UT_SELECT) ) 
     
    12951311    { 
    12961312        if( ur_is(bc, UT_BLOCK) ) 
    1297             ur_infuse( ur_thread, ur_block(bc), tos ); 
     1313            ur_infuse( ut, ur_block(bc), tos ); 
    12981314    } 
    12991315    UR_S_DROP; 
     
    13081324static 
    13091325#endif 
    1310 UIndex _funcSignature( const UCell* scell, int* pArgc, int* pVarc ) 
     1326UIndex _funcSignature( UThread* ut, const UCell* scell, int* pArgc, int* pVarc ) 
    13111327{ 
    13121328    UIndex sigN; 
     
    14211437 
    14221438        // Scan signature 
    1423         sigN = _funcSignature( res, &argc, &varc ); 
    1424  
    1425         lctx.ctx.wordBlk =  sigN; 
    1426         lctx.ctx.valBlk  = -sigN;   // Negative valBlk denotes stack storage. 
    1427  
    1428         ur_bind( bodN, &lctx ); 
     1439        sigN = _funcSignature( ut, res, &argc, &varc ); 
     1440 
     1441        lctx.ctx.wordBlk = sigN; 
     1442        lctx.ctx.valBlk  = 0;   //BLK_DSTACK; 
     1443 
     1444        ur_bindT( ut, bodN, &lctx, UR_BIND_LOCAL ); 
    14291445 
    14301446        ur_initType( res, UT_FUNCTION ); 
     
    15021518    { 
    15031519        UIndex strN = ur_makeBinary( 0 ); 
    1504         ur_toStrNatural( tos, ur_binPtr(strN), 0 ); 
     1520        ur_toStrNatural( ut, tos, ur_binPtr(strN), 0 ); 
    15051521        ur_initString(tos, strN, 0); 
    15061522    } 
     
    15171533    if( ur_isAWord(tos) ) 
    15181534    { 
    1519         hash = ur_atomHash( ur_thread->env, ur_atom(tos) ); 
    1520     } 
    1521     else if( ur_stringSlice(tos, &cpA, &cpB) ) 
     1535        hash = ur_atomHash( ut->env, ur_atom(tos) ); 
     1536    } 
     1537    else if( ur_stringSlice(ut, tos, &cpA, &cpB) ) 
    15221538    { 
    15231539        hash = ur_hash( cpA, cpB ); 
     
    15391555{ 
    15401556    UR_CALL_UNUSED_TOS 
    1541     ur_recycle( ur_thread->env ); 
     1557    ur_recycle( ut ); 
    15421558} 
    15431559