Ignore:
Timestamp:
11/25/12 10:44:29 (12 years ago)
Author:
tbretz
Message:
A lot of bug fixes; improved ConvertEvent; ensure that an exception in a included script will stop execution; moved some stuff from 'dim' to 'v8' and 'console'; fixed a crash in the callbacks; wait throws an exception now in case of timeout (mayb we should invent a TimeoutException)
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/FACT++/src/InterpreterV8.cc

    r14674 r14688  
    2020#include <v8.h>
    2121
     22#include "dim.h"
    2223#include "tools.h"
    2324#include "externals/izstream.h"
     
    118119        "(function(){"
    119120        "var t=new Date();"
    120         "while ((new Date()-t)<"+to_string(args[0]->Int32Value())+") dim.sleep();"
     121        "while ((new Date()-t)<"+to_string(args[0]->Int32Value())+") v8.sleep();"
    121122        "})();";
    122123
     
    143144    TryCatch exception;
    144145
    145     const bool rc = ms==0 || !ExecuteInternal("dim.sleep("+to_string(ms)+");").IsEmpty();
     146    const bool rc = ms==0 || !ExecuteInternal("v8.sleep("+to_string(ms)+");").IsEmpty();
    146147    if (rc)
    147148        func->Call(func, 0, NULL);
     
    190191    Handle<Object> self = args.This();
    191192
    192     self->SetInternalField(0, Integer::New(id));
     193    self->Set(String::New("id"), Integer::NewFromUnsigned(id), ReadOnly);
    193194    self->Set(String::New("kill"), FunctionTemplate::New(WrapKill)->GetFunction(), ReadOnly);
    194195
     
    198199Handle<Value> InterpreterV8::FuncKill(const Arguments& args)
    199200{
    200     const int id = args.This()->GetInternalField(0)->Int32Value();
     201    const uint32_t id = args.This()->Get(String::New("id"))->Uint32Value();
    201202
    202203    V8::TerminateExecution(id);
     
    250251        return ThrowException(String::New(e.what()));
    251252    }
    252 
    253253}
    254254
     
    268268        return ThrowException(String::New("Argument 2 not an int32 and not a string."));
    269269
    270     if (args.Length()==3 && !args[2]->IsUint32())
    271         return ThrowException(String::New("Argument 3 not an uint32."));
     270    if (args.Length()==3 && !args[2]->IsInt32())
     271        return ThrowException(String::New("Argument 3 not an int32."));
    272272
    273273    // Using a Javascript function has the advantage that it is fully
     
    294294                      "{"
    295295                         "var s = dim.state(name);"
    296                          "if(!"+index+")throw new Error('Waitig for state "+arg1+" of server "+arg0+" failed.');"
     296                         "if(!s)throw new Error('Waitig for state "+arg1+" of server "+arg0+" failed.');"
    297297                         "if(state=="+index+")return true;";
    298298    if (timeout)
    299         code +=          "if((new Date()-t)>ms)return false;";
    300 
    301     code +=              "dim.sleep();"
    302                       "}"
     299        code +=          "if((new Date()-t)>Math.abs(ms))break;";
     300
     301    code +=              "v8.sleep();"
     302                      "}";
     303    if (timeout)
     304        code +=    "if(ms>0)throw new Error('Waitig for state "+arg1+" of server "+arg0+" timed out.');";
     305    code +=        "return false;"
    303306                   "})('"+arg0+"',"+arg1;
    304307    if (timeout)
     
    486489
    487490        if (!ExecuteFile(*file))
    488             return Boolean::New(false);
    489     }
     491        {
     492            V8::TerminateExecution(fThreadId);
     493            return ThrowException(Null());
     494        }
     495    }
     496
    490497    return Boolean::New(true);
    491498}
     
    541548
    542549    return handle_scope.Close(arr);
    543 }
    544 
    545 Handle<Value> InterpreterV8::FuncVersion(const Arguments&)
    546 {
    547     return String::New(V8::GetVersion());
    548550}
    549551
     
    797799    case 'S':  { Handle<Value> v=Integer::NewFromUnsigned(*reinterpret_cast<const uint16_t*>(ptr)); ptr += 2; return v; }
    798800    case 'C':  { Handle<Value> v=Integer::NewFromUnsigned((uint16_t)*reinterpret_cast<const uint8_t*>(ptr));  ptr += 1; return v; }
    799     case ':':  { Handle<Value> v=String::New(ptr); return v; }
    800801    }
    801802    return Undefined();
     
    808809    //const void *ptr = Local<External>::Cast(args.Holder()->GetInternalField(0))->Value();
    809810
    810     const String::AsciiValue str(args.Holder()->Get(String::New("name")));
     811    const String::AsciiValue str(args.This()->Get(String::New("name")));
    811812
    812813    const auto it = fReverseMap.find(*str);
     
    883884    {
    884885        size_t pos = 1;
    885         for (auto it=tok.begin(); it!=tok.end() && ptr<end; it++, pos++)
     886        for (auto it=tok.begin(); it<tok.end() && ptr<end; it++, pos++)
    886887        {
    887888            char type = (*it)[0];
    888889            it++;
    889890
    890             if (it==tok.end() && type=='C')
    891                 type = ':';
    892 
    893             if (it==tok.end() && type!=':')
    894                 return Exception::Error(String::New(("Format string invalid '"+evt->GetFormat()+"'").c_str()));
    895 
    896891            string name = pos<vec.size() ? vec[pos].name : "";
    897892            if (tok.size()==1)
    898893                name = "data";
    899894
    900             const uint32_t cnt = it==tok.end() ? 1 : stoi(it->c_str());
     895            // Get element size
     896            uint32_t sz = 1;
     897            switch (type)
     898            {
     899            case 'X':
     900            case 'D': sz = 8; break;
     901            case 'F':
     902            case 'I':
     903            case 'L': sz = 4; break;
     904            case 'S': sz = 2; break;
     905            case 'C': sz = 1; break;
     906            }
     907
     908            // Check if no number is attached if the size of the
     909            // received data is consistent with the format string
     910            if (it==tok.end() && (end-ptr)%sz>0)
     911                return Exception::Error(String::New(("Number of received bytes ["+to_string(evt->GetSize())+"] does not match format ["+evt->GetFormat()+"]").c_str()));
     912
     913            // Check if format has a number attached.
     914            // If no number is attached calculate number of elements
     915            const uint32_t cnt = it==tok.end() ? (end-ptr)/sz : stoi(it->c_str());
     916
     917            // is_str: Array of type C but unknown size (String)
     918            // is_one: Array of known size, but size is 1 (I:1)
     919            const bool is_str = type=='C' && it==tok.end();
     920            const bool is_one = cnt==1    && it!=tok.end();
    901921
    902922            Handle<Value> v;
    903             if (cnt==1)
    904             {
     923
     924            if (is_str)
     925                v = String::New(ptr);
     926            if (is_one)
    905927                v = Convert(type, ptr);
    906             }
    907             else
     928
     929            // Array of known (I:5) or unknown size (I), but no string
     930            if (!is_str && !is_one)
    908931            {
    909932                Handle<Object> a = Array::New(cnt);
     
    919942            if (tok.size()>1)
    920943                arr->Set(pos-1, v);
     944            else
     945                ret->Set(String::New("data"), v, ReadOnly);
    921946
    922947            if (!name.empty())
     
    925950                named->Set(n, v);
    926951            }
    927 
    928             if (it==tok.end())
    929                 break;
    930952        }
    931953
     
    9791001    HandleScope handle_scope;
    9801002
    981     const Handle<Script> sleep = Script::Compile(String::New("dim.sleep();"), String::New("internal"));
     1003    const Handle<Script> sleep = Script::Compile(String::New("v8.sleep();"), String::New("internal"));
    9821004    if (sleep.IsEmpty())
    9831005        return Undefined();
     
    11271149    }
    11281150
     1151    const HandleScope handle_scope;
     1152
    11291153    it->second->CreationContext()->Enter();
    1130 
    1131     const HandleScope handle_scope;
    11321154
    11331155    // -------------------------------------------------------------------
     
    16171639
    16181640        HandleException(exception, "code");
    1619         return Undefined();
     1641        return Handle<Value>();
    16201642    }
    16211643
     
    17621784    // Create a template for the global object.
    17631785    Handle<ObjectTemplate> dim = ObjectTemplate::New();
    1764     dim->Set(String::New("print"),     FunctionTemplate::New(WrapPrint),     ReadOnly);
    1765     dim->Set(String::New("alarm"),     FunctionTemplate::New(WrapAlarm),     ReadOnly);
    1766     dim->Set(String::New("out"),       FunctionTemplate::New(WrapOut),       ReadOnly);
    1767     dim->Set(String::New("wait"),      FunctionTemplate::New(WrapWait),      ReadOnly);
    1768     dim->Set(String::New("send"),      FunctionTemplate::New(WrapSend),      ReadOnly);
    1769     dim->Set(String::New("state"),     FunctionTemplate::New(WrapState),     ReadOnly);
    1770     dim->Set(String::New("sleep"),     FunctionTemplate::New(WrapSleep),     ReadOnly);
     1786    dim->Set(String::New("print"),   FunctionTemplate::New(WrapPrint), ReadOnly);
     1787    dim->Set(String::New("alarm"),   FunctionTemplate::New(WrapAlarm), ReadOnly);
     1788    dim->Set(String::New("wait"),    FunctionTemplate::New(WrapWait),  ReadOnly);
     1789    dim->Set(String::New("send"),    FunctionTemplate::New(WrapSend),  ReadOnly);
     1790    dim->Set(String::New("state"),   FunctionTemplate::New(WrapState), ReadOnly);
     1791    dim->Set(String::New("version"), Integer::New(DIM_VERSION_NUMBER), ReadOnly);
    17711792
    17721793    Handle<ObjectTemplate> dimctrl = ObjectTemplate::New();
     
    17751796    dimctrl->Set(String::New("getState"),  FunctionTemplate::New(WrapGetState),  ReadOnly);
    17761797
    1777     // new class State ?
     1798    Handle<ObjectTemplate> v8 = ObjectTemplate::New();
     1799    v8->Set(String::New("sleep"),   FunctionTemplate::New(WrapSleep), ReadOnly);
     1800    v8->Set(String::New("version"), String::New(V8::GetVersion()),    ReadOnly);
     1801
     1802    Handle<ObjectTemplate> console = ObjectTemplate::New();
     1803    console->Set(String::New("out"), FunctionTemplate::New(WrapOut), ReadOnly);
    17781804
    17791805    Handle<ObjectTemplate> onchange = ObjectTemplate::New();
    17801806    onchange->SetNamedPropertyHandler(OnChangeGet, WrapOnChangeSet);
    1781     dim->Set(v8::String::New("onchange"), onchange);
     1807    dim->Set(String::New("onchange"), onchange);
    17821808
    17831809    Handle<ObjectTemplate> global = ObjectTemplate::New();
    1784     global->Set(String::New("dim"),      dim,     ReadOnly);
    1785     global->Set(String::New("dimctrl"),  dimctrl, ReadOnly);
    1786     global->Set(String::New("include"),  FunctionTemplate::New(WrapInclude),                ReadOnly);
    1787     global->Set(String::New("exit"),     FunctionTemplate::New(WrapExit),                   ReadOnly);
    1788     global->Set(String::New("version"),  FunctionTemplate::New(InterpreterV8::FuncVersion), ReadOnly);
     1810    global->Set(String::New("v8"),      v8,      ReadOnly);
     1811    global->Set(String::New("dim"),     dim,     ReadOnly);
     1812    global->Set(String::New("dimctrl"), dimctrl, ReadOnly);
     1813    global->Set(String::New("console"), console, ReadOnly);
     1814    global->Set(String::New("include"), FunctionTemplate::New(WrapInclude),                ReadOnly);
     1815    global->Set(String::New("exit"),    FunctionTemplate::New(WrapExit),                   ReadOnly);
    17891816
    17901817    Handle<FunctionTemplate> sub = FunctionTemplate::New(WrapSubscription);
     
    18001827    Handle<FunctionTemplate> thread = FunctionTemplate::New(WrapThread);
    18011828    thread->SetClassName(String::New("Thread"));
    1802     thread->InstanceTemplate()->SetInternalFieldCount(1);
    18031829    global->Set(String::New("Thread"), thread, ReadOnly);
    18041830
    18051831    Handle<FunctionTemplate> file = FunctionTemplate::New(WrapFile);
    18061832    file->SetClassName(String::New("File"));
    1807     file->InstanceTemplate()->SetInternalFieldCount(1);
    18081833    global->Set(String::New("File"), file, ReadOnly);
    18091834
     
    18371862    if (context.IsEmpty())
    18381863    {
    1839         //printf("Error creating context\n");
     1864        JsException("Creation of global context failed...");
     1865        JsEnd(filename);
    18401866        return false;
    18411867    }
     
    18541880    //V8::ResumeProfiler();
    18551881
    1856     bool rc;
    1857 
    18581882    TryCatch exception;
    18591883
    18601884    AddFormatToGlobal();
    18611885
     1886    bool rc = true;
    18621887    if (!exception.HasCaught())
    18631888    {
     
    18661891        Locker::StartPreemption(10);
    18671892
    1868         rc = ExecuteFile(filename, true);
     1893        rc &= ExecuteFile(filename, true);
    18691894
    18701895        Locker::StopPreemption();
     
    18771902
    18781903    // Handle an exception
    1879     rc = HandleException(exception, "main");
     1904    rc &= HandleException(exception, "main");
    18801905
    18811906    // IsProfilerPaused()
     
    19301955    JsEnd(filename);
    19311956
    1932     return rc;
     1957    return true;
    19331958}
    19341959
Note: See TracChangeset for help on using the changeset viewer.