Changeset 351

Show
Ignore:
Timestamp:
08/24/08 20:32:09 (3 months ago)
Author:
JarrettBillingsley
Message:

finished the timelib.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/v2new/minid/api.d

    r350 r351  
    4646import minid.mathlib; 
    4747import minid.stringlib; 
     48import minid.timelib; 
    4849 
    4950// ================================================================================================================================================ 
     
    154155    */ 
    155156    Regexp =  128, 
    156  
    157     /** 
    158     This flag is an OR of Array, Char, Math, String, Table, and Regexp.  It represents all 
    159     the libraries which are "safe", i.e. malicious scripts would not be able to use the IO 
     157     
     158    /** 
     159    Time functions. 
     160    */ 
     161    Time = 256, 
     162 
     163    /** 
     164    This flag is an OR of Array, Char, Math, String, Table, Regexp, and Time.  It represents 
     165    all the libraries which are "safe", i.e. malicious scripts would not be able to use the IO 
    160166    or OS libraries to do bad things. 
    161167    */ 
    162     Safe = Array | Char | Math | String | Table | Regexp
     168    Safe = Array | Char | Math | String | Table | Regexp | Time
    163169 
    164170    /** 
     
    169175 
    170176/** 
    171 Load the standard libraries into the context of the given thread.   
     177Load the standard libraries into the context of the given thread. 
    172178 
    173179Params: 
     
    200206//  if(libs & MDStdlib.Table) 
    201207//      TableLib.init(ret); 
     208 
     209    if(libs & MDStdlib.Time) 
     210        TimeLib.init(t); 
    202211} 
    203212 
  • branches/v2new/minid/interpreter.d

    r350 r351  
    507507 
    508508/** 
    509 Push the given thread onto this thread's stack. 
     509Pushes the given thread onto this thread's stack. 
    510510 
    511511Params: 
     
    521521 
    522522/** 
    523 Push a reference to a native (D) object onto the stack. 
     523Pushes a reference to a native (D) object onto the stack. 
    524524 
    525525Params: 
     
    536536 
    537537/** 
    538 Duplicate a value at the given stack index and push it onto the stack. 
     538Duplicates a value at the given stack index and pushes it onto the stack. 
    539539 
    540540Params: 
     
    553553 
    554554/** 
    555 Insert the value at the top of the stack into the given _slot, shifting up the values in that _slot 
     555Swaps the two values at the given swap indices.  The second index defaults to the top-of-stack. 
     556 
     557Params: 
     558    first = The first stack index. 
     559    second = The second stack index. 
     560*/ 
     561public void swap(MDThread* t, word first, word second = -1) 
     562
     563    auto f = fakeToAbs(t, first); 
     564    auto s = fakeToAbs(t, second); 
     565 
     566    if(f == s) 
     567        return; 
     568 
     569    auto tmp = t.stack[f]; 
     570    t.stack[f] = t.stack[s]; 
     571    t.stack[s] = tmp; 
     572
     573 
     574/** 
     575Inserts the value at the top of the stack into the given _slot, shifting up the values in that _slot 
    556576and everything after it up by a _slot.  This means the stack will stay the same size.  Similar to a 
    557577"rotate" operation common to many stack machines. 
     
    605625 
    606626/** 
    607 Pop a number of items off the stack.  Throws an error if you try to pop more items than there are 
     627Pops a number of items off the stack.  Throws an error if you try to pop more items than there are 
    608628on the stack.  'this' is not counted; so if there is 'this' and one value, and you try to pop 2 
    609629values, an error is thrown. 
  • branches/v2new/minid/timelib.d

    r305 r351  
    11/****************************************************************************** 
    22License: 
    3 Copyright (c) 2007 Jarrett Billingsley 
     3Copyright (c) 2008 Jarrett Billingsley 
    44 
    55This software is provided 'as-is', without any express or implied warranty. 
     
    2424module minid.timelib; 
    2525 
     26import tango.text.locale.Convert; 
     27import tango.text.locale.Core; 
     28import tango.time.chrono.Gregorian; 
     29import tango.time.Clock; 
     30import tango.time.StopWatch; 
     31import tango.time.Time; 
     32import tango.time.WallClock; 
     33import Utf = tango.text.convert.Utf; 
     34 
     35import minid.ex; 
     36import minid.interpreter; 
    2637import minid.types; 
    2738import minid.utils; 
    28  
    29 import tango.text.locale.Convert; 
    30 import tango.text.locale.Core; 
    31 import tango.time.Clock; 
    32 import tango.time.Time; 
    33 import tango.time.StopWatch; 
    34 import tango.time.WallClock; 
    35 import tango.time.chrono.Gregorian; 
    3639 
    3740version(Windows) 
     
    4750    static assert(false, "No valid platform defined"); 
    4851 
    49 final class TimeLib 
     52struct TimeLib 
    5053{ 
    5154static: 
    52     private MDValue YearString; 
    53     private MDValue MonthString; 
    54     private MDValue DayString; 
    55     private MDValue HourString; 
    56     private MDValue MinString; 
    57     private MDValue SecString; 
    58     version(Windows) ulong performanceFreq; 
    59  
    60     static this() 
    61     { 
    62         YearString = new MDString("year"d); 
    63         MonthString = new MDString("month"d); 
    64         DayString = new MDString("day"d); 
    65         HourString = new MDString("hour"d); 
    66         MinString = new MDString("min"d); 
    67         SecString = new MDString("sec"d); 
    68  
    69         version(Windows) 
     55    version(Windows) 
     56    { 
     57        ulong performanceFreq; 
     58 
     59        static this() 
    7060        { 
    7161            if(!QueryPerformanceFrequency(&performanceFreq)) 
     
    7464    } 
    7565 
    76     public void init(MDContext context) 
    77     { 
    78         context.setModuleLoader("time", context.newClosure(function int(MDState s, uint numParams) 
    79         { 
    80             auto perfCounterClass = new MDPerfCounterClass(s.context.globals.get!(MDObject)("Object"d)); 
    81  
    82             auto lib = s.getParam!(MDNamespace)(1); 
    83  
    84             lib.addList 
    85             ( 
    86                 "PerfCounter"d,  perfCounterClass, 
    87                 "microTime"d,    new MDClosure(lib, &microTime,  "times.microTime"), 
    88                 "dateString"d,   new MDClosure(lib, &dateString, "time.dateString"), 
    89                 "dateTime"d,     new MDClosure(lib, &dateTime,   "time.dateTime"), 
    90                 "culture"d,      new MDClosure(lib, &culture,    "time.culture"), 
    91                 "timestamp"d,    new MDClosure(lib, &timestamp,  "time.timestamp") 
    92             ); 
     66    public void init(MDThread* t) 
     67    { 
     68        pushGlobal(t, "modules"); 
     69        field(t, -1, "customLoaders"); 
     70         
     71        newFunction(t, function uword(MDThread* t, uword numParams) 
     72        { 
     73            Timer.init(t); 
     74            newFunction(t, &microTime,  "microTime");  newGlobal(t, "microTime"); 
     75            newFunction(t, &dateString, "dateString"); newGlobal(t, "dateString"); 
     76            newFunction(t, &dateTime,   "dateTime");   newGlobal(t, "dateTime"); 
     77            newFunction(t, &culture,    "culture");    newGlobal(t, "culture"); 
     78            newFunction(t, &timestamp,  "timestamp");  newGlobal(t, "timestamp"); 
    9379 
    9480            return 0; 
    95         }, "time")); 
    96  
    97         context.importModule("time"); 
    98     } 
    99  
    100     int microTime(MDState s, uint numParams) 
     81        }, "time"); 
     82 
     83        fielda(t, -2, "time"); 
     84        pop(t); 
     85 
     86        importModule(t, "time"); 
     87    } 
     88     
     89    uword microTime(MDThread* t, uword numParams) 
    10190    { 
    10291        version(Windows) 
     
    10493            ulong time; 
    10594            QueryPerformanceCounter(&time); 
    106  
     95         
    10796            if(time < 0x8637BD05AF6L) 
    108                 s.push((time * 1_000_000) / performanceFreq); 
     97                pushInt(t, cast(mdint)((time * 1_000_000) / performanceFreq)); 
    10998            else 
    110                 s.push((time / performanceFreq) * 1_000_000); 
     99                pushInt(t, cast(mdint)((time / performanceFreq) * 1_000_000)); 
    111100        } 
    112101        else 
     
    114103            timeval tv; 
    115104            gettimeofday(&tv, null); 
    116             s.push(tv.tv_sec * 1_000_000L + tv.tv_usec); 
    117         } 
    118          
    119         return 1; 
    120     } 
    121      
    122     int dateString(MDState s, uint numParams) 
    123     { 
    124         Time time; 
    125         char[40] buffer; 
    126         char[] format = "G"; 
    127         Culture culture = null; 
    128  
    129         if(numParams > 0) 
    130             format = s.getParam!(char[])(0); 
    131  
    132         if(numParams > 1 && !s.isParam!("null")(1)) 
    133             time = TableToTime(s, s.getParam!(MDTable)(1)); 
     105            pushInt(t, cast(mdint)(tv.tv_sec * 1_000_000L + tv.tv_usec)); 
     106        } 
     107 
     108        return 1; 
     109    } 
     110 
     111    uword dateString(MDThread* t, uword numParams) 
     112    { 
     113        char[] format = numParams > 0 ? GetFormat(t, 1) : "G"; 
     114 
     115        Time time = void; 
     116 
     117        if(numParams > 1 && !isNull(t, 2)) 
     118            time = TableToTime(t, 2); 
    134119        else if(format == "R") 
    135120            time = Clock.now; 
     
    137122            time = WallClock.now; 
    138123 
     124        Culture culture = null; 
     125 
    139126        if(numParams > 2) 
    140             culture = s.safeCode(Culture.getCulture(s.getParam!(char[])(2))); 
    141  
    142         s.push(s.safeCode(formatDateTime(buffer, time, format, culture))); 
    143         return 1; 
    144     } 
    145      
    146     int dateTime(MDState s, uint numParams) 
     127        { 
     128            char[24] buf = void; 
     129            auto name = StrToCulture(t, 1, buf); 
     130            culture = safeCode(t, Culture.getCulture(name)); 
     131        } 
     132 
     133        char[40] buffer; 
     134        auto ret = safeCode(t, formatDateTime(buffer, time, format, culture)); 
     135 
     136        dchar[40] outbuf; 
     137        uint ate = 0; 
     138        pushString(t, Utf.toString32(ret, outbuf, &ate)); 
     139        return 1; 
     140    } 
     141     
     142    uword dateTime(MDThread* t, uword numParams) 
    147143    { 
    148144        bool useGMT = false; 
    149         MDTable t = null; 
    150          
    151         if(numParams > 0) 
    152         { 
    153             if(s.isParam!("bool")(0)) 
     145        word tab; 
     146 
     147        if(numParams == 0) 
     148            tab = newTable(t); 
     149        else if(isBool(t, 1)) 
     150        { 
     151            useGMT = getBool(t, 1); 
     152 
     153            if(numParams > 1) 
    154154            { 
    155                 useGMT = s.getParam!(bool)(0); 
    156                  
    157                 if(numParams > 1) 
    158                     t = s.getParam!(MDTable)(1); 
     155                checkParam(t, 2, MDValue.Type.Table); 
     156                tab = 2; 
    159157            } 
    160158            else 
    161                 t = s.getParam!(MDTable)(0); 
    162         } 
    163  
    164         s.push(DateTimeToTable(s, useGMT ? Clock.toDate : WallClock.toDate, t)); 
    165         return 1; 
    166     } 
    167  
    168     int culture(MDState s, uint numParams) 
    169     { 
    170         s.push(Culture.current.name); 
     159                tab = newTable(t); 
     160        } 
     161        else 
     162        { 
     163            checkParam(t, 1, MDValue.Type.Table); 
     164            tab = 1; 
     165        } 
     166 
     167        DateTimeToTable(t, useGMT ? Clock.toDate : WallClock.toDate, tab); 
     168        dup(t, tab); 
     169        return 1; 
     170    } 
     171 
     172    uword culture(MDThread* t, uword numParams) 
     173    { 
     174        CultureToStr(t, Culture.current.name); 
    171175 
    172176        if(numParams > 0) 
    173             Culture.current = s.safeCode(Culture.getCulture(s.getParam!(char[])(0))); 
    174  
    175         return 1; 
    176     } 
    177  
    178     Time TableToTime(MDState s, MDTable tab) 
    179     { 
    180         MDValue table = MDValue(tab); 
    181         Time time; 
    182  
    183         with(s) 
    184         { 
    185             MDValue year = idx(table, YearString); 
    186             MDValue month = idx(table, MonthString); 
    187             MDValue day = idx(table, DayString); 
    188             MDValue hour = idx(table, HourString); 
    189             MDValue min = idx(table, MinString); 
    190             MDValue sec = idx(table, SecString); 
    191  
    192             if(!year.isInt() || !month.isInt() || !day.isInt()) 
    193                 s.throwRuntimeException("year, month, and day fields in time table must exist and must be integers"); 
    194  
    195             if(hour.isInt() && min.isInt() && sec.isInt()) 
    196                 time = Gregorian.generic.toTime(year.as!(int), month.as!(int), day.as!(int), hour.as!(int), min.as!(int), sec.as!(int), 0, 0); 
    197             else 
    198                 time = Gregorian.generic.toTime(year.as!(int), month.as!(int), day.as!(int), 0, 0, 0, 0, 0); 
    199         } 
     177        { 
     178            char[24] buf = void; 
     179            auto name = StrToCulture(t, 1, buf); 
     180            Culture.current = safeCode(t, Culture.getCulture(name)); 
     181        } 
     182 
     183        return 1; 
     184    } 
     185 
     186    // longest possible is 5 chars * 4 bytes per char = 20 bytes? 
     187    char[] StrToCulture(MDThread* t, word slot, char[24] outbuf) 
     188    { 
     189        checkStringParam(t, slot); 
     190 
     191        if(len(t, slot) != 5) 
     192            throwException(t, "Culture name {} is not supported.", getString(t, slot)); 
     193 
     194        uint ate = 0; 
     195        return Utf.toString(getString(t, slot), outbuf, &ate); 
     196    } 
     197 
     198    word CultureToStr(MDThread* t, char[] culture) 
     199    { 
     200        // eh, let's be safe.. 
     201        dchar[8] buf; 
     202        uint ate = 0; 
     203        return pushString(t, Utf.toString32(culture, buf, &ate)); 
     204    } 
     205     
     206    char[] GetFormat(MDThread* t, word slot) 
     207    { 
     208        switch(checkStringParam(t, slot)) 
     209        { 
     210            case "d": return "d"; 
     211            case "D": return "D"; 
     212            case "t": return "t"; 
     213            case "T": return "T"; 
     214            case "g": return "g"; 
     215            case "G": return "G"; 
     216            case "M": return "M"; 
     217            case "R": return "R"; 
     218            case "s": return "s"; 
     219            case "Y": return "Y"; 
     220 
     221            default: 
     222                throwException(t, "invalid format string"); 
     223        } 
     224         
     225        assert(false); 
     226    } 
     227 
     228    Time TableToTime(MDThread* t, word tab) 
     229    { 
     230        auto year = field(t, tab, "year"); 
     231        auto month = field(t, tab, "month"); 
     232        auto day = field(t, tab, "day"); 
     233        auto hour = field(t, tab, "hour"); 
     234        auto min = field(t, tab, "min"); 
     235        auto sec = field(t, tab, "sec"); 
     236 
     237        if(!isInt(t, year) || !isInt(t, month) || !isInt(t, day)) 
     238            throwException(t, "year, month, and day fields in time table must exist and must be integers"); 
     239             
     240        Time time = void; 
     241 
     242        if(isInt(t, hour) && isInt(t, min) && isInt(t, sec)) 
     243            time = Gregorian.generic.toTime(getInt(t, year), getInt(t, month), getInt(t, day), getInt(t, hour), getInt(t, min), getInt(t, sec), 0, 0); 
     244        else 
     245            time = Gregorian.generic.toTime(getInt(t, year), getInt(t, month), getInt(t, day), 0, 0, 0, 0, 0); 
     246             
     247        pop(t, 6); 
    200248 
    201249        return time; 
    202250    } 
    203251 
    204     MDTable DateTimeToTable(MDState s, DateTime time, MDTable dest) 
    205     { 
    206         if(dest is null) 
    207             dest = new MDTable(); 
    208  
    209         MDValue table = dest; 
    210  
    211         with(s) 
    212         { 
    213             idxa(table, YearString, MDValue(time.date.year)); 
    214             idxa(table, MonthString, MDValue(time.date.month)); 
    215             idxa(table, DayString, MDValue(time.date.day)); 
    216             idxa(table, HourString, MDValue(time.time.hours)); 
    217             idxa(table, MinString, MDValue(time.time.minutes)); 
    218             idxa(table, SecString, MDValue(time.time.seconds)); 
    219         } 
    220          
    221         return dest; 
    222     } 
    223      
    224     int timestamp(MDState s, uint numParams) 
    225     { 
    226         s.push(cast(int)(Clock.now - Time.epoch1970).seconds); 
    227         return 1; 
    228     } 
    229  
    230     static class MDPerfCounterClass : MDObject 
    231     { 
    232         static class MDPerfCounter : MDObject 
     252    void DateTimeToTable(MDThread* t, DateTime time, word dest) 
     253    { 
     254//      dest = absIndex(t, dest); 
     255//  
     256//      if(isNull(t, dest)) 
     257//      { 
     258//          newTable(t); 
     259//          swap(t, dest); 
     260//          pop(t); 
     261//      } 
     262//  
     263        pushInt(t, time.date.year);    fielda(t, dest, "year"); 
     264        pushInt(t, time.date.month);   fielda(t, dest, "month"); 
     265        pushInt(t, time.date.day);     fielda(t, dest, "day"); 
     266        pushInt(t, time.time.hours);   fielda(t, dest, "hour"); 
     267        pushInt(t, time.time.minutes); fielda(t, dest, "min"); 
     268        pushInt(t, time.time.seconds); fielda(t, dest, "sec"); 
     269    } 
     270 
     271    uword timestamp(MDThread* t, uword numParams) 
     272    { 
     273        pushInt(t, cast(mdint)(Clock.now - Time.epoch1970).seconds); 
     274        return 1; 
     275    } 
     276 
     277    static struct Timer 
     278    { 
     279    static: 
     280        private Members* getThis(MDThread* t) 
     281        { 
     282            return checkObjParam!(Members)(t, 0, "Timer"); 
     283        } 
     284     
     285        void init(MDThread* t) 
     286        { 
     287            CreateObject(t, "Timer", (CreateObject* o) 
     288            { 
     289                o.method("clone", &clone); 
     290                o.method("start", &start); 
     291                o.method("stop", &stop); 
     292                o.method("seconds", &seconds); 
     293                o.method("millisecs", &millisecs); 
     294                o.method("microsecs", &microsecs); 
     295            }); 
     296     
     297            newGlobal(t, "Timer"); 
     298        } 
     299     
     300        struct Members 
    233301        { 
    234302            protected StopWatch mWatch; 
    235303            protected mdfloat mTime = 0; 
    236              
    237             public this(MDObject owner) 
    238             { 
    239                 super("PerfCounter", owner); 
    240             } 
    241         } 
    242  
    243         public this(MDObject owner) 
    244         { 
    245             super("PerfCounter", owner); 
    246  
    247             fields.addList 
    248             ( 
    249                 "clone"d,     new MDClosure(fields, &clone,     "PerfCounter.clone"), 
    250                 "start"d,     new MDClosure(fields, &start,     "PerfCounter.start"), 
    251                 "stop"d,      new MDClosure(fields, &stop,      "PerfCounter.stop"), 
    252                 "seconds"d,   new MDClosure(fields, &seconds,   "PerfCounter.seconds"), 
    253                 "millisecs"d, new MDClosure(fields, &millisecs, "PerfCounter.millisecs"), 
    254                 "microsecs"d, new MDClosure(fields, &microsecs, "PerfCounter.microsecs") 
    255             ); 
    256         } 
    257  
    258         public int clone(MDState s, uint numParams) 
    259         { 
    260             s.push(new MDPerfCounter(this)); 
     304        } 
     305     
     306        uword clone(MDThread* t, uword numParams) 
     307        { 
     308            newObject(t, 0, null, 0, Members.sizeof); 
     309            *getMembers!(Members)(t, -1) = Members.init; 
    261310            return 1; 
    262311        } 
    263  
    264         public int start(MDState s, uint numParams) 
    265         { 
    266             s.getContext!(MDPerfCounter).mWatch.start(); 
     312     
     313        uword start(MDThread* t, uword numParams) 
     314        { 
     315            getThis(t).mWatch.start(); 
    267316            return 0; 
    268317        } 
    269  
    270         public int stop(MDState s, uint numParams) 
    271         { 
    272             auto self = s.getContext!(MDPerfCounter); 
    273             self.mTime = self.mWatch.stop(); 
     318     
     319        uword stop(MDThread* t, uword numParams) 
     320        { 
     321            auto members = getThis(t); 
     322            members.mTime = members.mWatch.stop(); 
    274323            return 0; 
    275324        } 
    276  
    277         public int seconds(MDState s, uint numParams) 
    278         { 
    279             s.push(s.getContext!(MDPerfCounter).mTime); 
     325     
     326        uword seconds(MDThread* t, uword numParams) 
     327        { 
     328            pushFloat(t, getThis(t).mTime); 
    280329            return 1; 
    281330        } 
    282  
    283         public int millisecs(MDState s, uint numParams) 
    284         { 
    285             s.push(s.getContext!(MDPerfCounter).mTime * 1_000); 
     331     
     332        uword millisecs(MDThread* t, uword numParams) 
     333        { 
     334            pushFloat(t, getThis(t).mTime * 1_000); 
    286335            return 1; 
    287336        } 
    288  
    289         public int microsecs(MDState s, uint numParams) 
    290         { 
    291             s.push(s.getContext!(MDPerfCounter).mTime * 1_000_000); 
     337     
     338        uword microsecs(MDThread* t, uword numParams) 
     339        { 
     340            pushFloat(t, getThis(t).mTime * 1_000_000); 
    292341            return 1; 
    293342        } 
  • branches/v2new/samples/simple.md

    r350 r351  
    11module samples.simple 
    2  
    3  
    42 
    53/+ 
  • branches/v2new/test.d

    r349 r351  
    3636    loadStdlibs(t); 
    3737 
    38     // This is all stdlib crap! 
    39     newFunction(t, &microTime, "microTime"); 
    40     newGlobal(t, "microTime"); 
    41     Timer.init(t); 
    42  
    43         importModule(t, "samples.simple"); 
     38    importModule(t, "samples.simple"); 
    4439 
    4540    Stdout.newline.format("MiniD using {} bytes before GC, ", bytesAllocated(vm)).flush; 
     
    5045    delete vm; 
    5146} 
    52  
    53 private extern(Windows) int QueryPerformanceFrequency(ulong* frequency); 
    54 private extern(Windows) int QueryPerformanceCounter(ulong* count); 
    55 ulong performanceFreq; 
    56  
    57 static this() 
    58 { 
    59     if(!QueryPerformanceFrequency(&performanceFreq)) 
    60         performanceFreq = 0x7fffffffffffffffL; 
    61 } 
    62  
    63 uword microTime(MDThread* t, uword numParams) 
    64 { 
    65     ulong time; 
    66     QueryPerformanceCounter(&time); 
    67  
    68     if(time < 0x8637BD05AF6L) 
    69         pushInt(t, cast(mdint)((time * 1_000_000) / performanceFreq)); 
    70     else 
    71         pushInt(t, cast(mdint)((time / performanceFreq) * 1_000_000)); 
    72  
    73     return 1; 
    74 } 
    75  
    76 import tango.time.StopWatch; 
    77 struct Timer 
    78 { 
    79 static: 
    80     private Members* getThis(MDThread* t) 
    81     { 
    82         return checkObjParam!(Members)(t, 0, "Timer"); 
    83     } 
    84  
    85     void init(MDThread* t) 
    86     { 
    87         CreateObject(t, "Timer", (CreateObject* o) 
    88         { 
    89             o.method("clone", &clone); 
    90             o.method("start", &start); 
    91             o.method("stop", &stop); 
    92             o.method("seconds", &seconds); 
    93             o.method("millisecs", &millisecs); 
    94             o.method("microsecs", &microsecs); 
    95         }); 
    96  
    97         newGlobal(t, "Timer"); 
    98     } 
    99  
    100     struct Members 
    101     { 
    102         protected StopWatch mWatch; 
    103         protected mdfloat mTime = 0; 
    104     } 
    105  
    106     uword clone(MDThread* t, uword numParams) 
    107     { 
    108         newObject(t, 0, null, 0, Members.sizeof); 
    109         *getMembers!(Members)(t, -1) = Members.init; 
    110         return 1; 
    111     } 
    112  
    113     uword start(MDThread* t, uword numParams) 
    114     { 
    115         getThis(t).mWatch.start(); 
    116         return 0; 
    117     } 
    118  
    119     uword stop(MDThread* t, uword numParams) 
    120     { 
    121         auto members = getThis(t); 
    122         members.mTime = members.mWatch.stop(); 
    123         return 0; 
    124     } 
    125  
    126     uword seconds(MDThread* t, uword numParams) 
    127     { 
    128         pushFloat(t, getThis(t).mTime); 
    129         return 1; 
    130     } 
    131  
    132     uword millisecs(MDThread* t, uword numParams) 
    133     { 
    134         pushFloat(t, getThis(t).mTime * 1_000); 
    135         return 1; 
    136     } 
    137  
    138     uword microsecs(MDThread* t, uword numParams) 
    139     { 
    140         pushFloat(t, getThis(t).mTime * 1_000_000); 
    141         return 1; 
    142     } 
    143 }