Subversion Repositories HomeAutomation

Rev

Rev 1042 | Rev 1203 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | SVN | RSS feed

Rev Author Line No. Line
969 runge 1
/***************************************************************************
2
 *   Copyright (C) December 10, 2008 by Mattias Runge                             *
3
 *   mattias@runge.se                                                      *
4
 *   virtualmachine.cpp                                            *
5
 *                                                                         *
6
 *   This program is free software; you can redistribute it and/or modify  *
7
 *   it under the terms of the GNU General Public License as published by  *
8
 *   the Free Software Foundation; either version 2 of the License, or     *
9
 *   (at your option) any later version.                                   *
10
 *                                                                         *
11
 *   This program is distributed in the hope that it will be useful,       *
12
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
13
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
14
 *   GNU General Public License for more details.                          *
15
 *                                                                         *
16
 *   You should have received a copy of the GNU General Public License     *
17
 *   along with this program; if not, write to the                         *
18
 *   Free Software Foundation, Inc.,                                       *
19
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
20
 ***************************************************************************/
21
 
22
#include "virtualmachine.h"
23
 
24
VirtualMachine* VirtualMachine::myInstance = NULL;
25
 
26
VirtualMachine& VirtualMachine::getInstance()
27
{
28
    if (myInstance == NULL)
29
    {
30
        myInstance = new VirtualMachine();
31
    }
32
 
33
    return *myInstance;
34
}
35
 
36
void VirtualMachine::deleteInstance()
37
{
38
    if (myInstance != NULL)
39
    {
40
        delete myInstance;
41
        myInstance = NULL;
42
    }
43
}
44
 
45
VirtualMachine::VirtualMachine()
46
{
47
}
48
 
49
VirtualMachine::~VirtualMachine()
50
{
981 runge 51
    stop();
997 runge 52
 
999 runge 53
    myCommandThread.stop();
54
 
997 runge 55
    ///FIXME: Verify that this works and does not cause segfaults
56
    for (map<int, SocketThread*>::iterator iter = mySocketThreads.begin(); iter != mySocketThreads.end(); iter++)
57
    {
999 runge 58
        iter->second->stop();
997 runge 59
        delete iter->second;
999 runge 60
        //mySocketThreads.erase(iter);
997 runge 61
    }
999 runge 62
 
63
    mySocketThreads.clear();
64
 
65
    for (map<int, IntervalThread*>::iterator iter = myIntervalThreads.begin(); iter != myIntervalThreads.end(); iter++)
66
    {
67
        iter->second->stop();
68
        delete iter->second;
69
        //myIntervalThreads.erase(iter);
70
    }
71
 
72
    myIntervalThreads.clear();
969 runge 73
}
74
 
75
void VirtualMachine::run()
76
{
77
    myGlobal = ObjectTemplate::New();
999 runge 78
    myGlobal->Set(String::New("_quit"), FunctionTemplate::New(VirtualMachine::_quit));
79
    myGlobal->Set(String::New("_print"), FunctionTemplate::New(VirtualMachine::_print));
80
    myGlobal->Set(String::New("log"), FunctionTemplate::New(VirtualMachine::_log));
81
    myGlobal->Set(String::New("sendCanMessage"), FunctionTemplate::New(VirtualMachine::_sendCanMessage));
82
    myGlobal->Set(String::New("sendCanNMTMessage"), FunctionTemplate::New(VirtualMachine::_sendCanNMTMessage));
83
    myGlobal->Set(String::New("loadScript"), FunctionTemplate::New(VirtualMachine::_loadScript));
84
    myGlobal->Set(String::New("startIntervalThread"), FunctionTemplate::New(VirtualMachine::_startIntervalThread));
85
    myGlobal->Set(String::New("stopIntervalThread"), FunctionTemplate::New(VirtualMachine::_stopIntervalThread));
1042 runge 86
    myGlobal->Set(String::New("setIntervalThreadTimeout"), FunctionTemplate::New(VirtualMachine::_setIntervalThreadTimeout));
999 runge 87
    myGlobal->Set(String::New("startSocketThread"), FunctionTemplate::New(VirtualMachine::_startSocketThread));
88
    myGlobal->Set(String::New("stopSocketThread"), FunctionTemplate::New(VirtualMachine::_stopSocketThread));
89
    myGlobal->Set(String::New("sendToSocketThread"), FunctionTemplate::New(VirtualMachine::_sendToSocketThread));
1007 runge 90
    myGlobal->Set(String::New("loadDataStore"), FunctionTemplate::New(VirtualMachine::_loadDataStore));
1008 runge 91
    myGlobal->Set(String::New("getFileContents"), FunctionTemplate::New(VirtualMachine::_getFileContents));
1011 runge 92
    myGlobal->Set(String::New("uint2hex"), FunctionTemplate::New(VirtualMachine::_uint2hex));
93
    myGlobal->Set(String::New("hex2bin"), FunctionTemplate::New(VirtualMachine::_hex2bin));
94
    myGlobal->Set(String::New("bin2hex"), FunctionTemplate::New(VirtualMachine::_bin2hex));
95
    myGlobal->Set(String::New("bin2float"), FunctionTemplate::New(VirtualMachine::_bin2float));
96
    myGlobal->Set(String::New("float2bin"), FunctionTemplate::New(VirtualMachine::_float2bin));
97
    myGlobal->Set(String::New("bin2uint"), FunctionTemplate::New(VirtualMachine::_bin2uint));
98
    myGlobal->Set(String::New("uint2bin"), FunctionTemplate::New(VirtualMachine::_uint2bin));
99
    myGlobal->Set(String::New("hex2uint"), FunctionTemplate::New(VirtualMachine::_hex2uint));
1060 runge 100
    myGlobal->Set(String::New("sleep"), FunctionTemplate::New(VirtualMachine::_sleep));
969 runge 101
    myContext = Context::New(NULL, myGlobal);
102
 
103
 
997 runge 104
    if (loadScript("System/Base.js"))
105
    {
106
        loadScript("System/Startup.js");
969 runge 107
 
997 runge 108
        loadScript("Autostart.js");
109
 
110
        Context::Scope contextScope(myContext);
111
 
112
        myFunctionStartup = Handle<Function>::Cast(myContext->Global()->Get(String::New("startup")));
969 runge 113
    }
114
    else
115
    {
997 runge 116
        ///FIXME: We should probably exit the application here
117
        return;
969 runge 118
    }
119
 
120
    const int argc = 0;
121
    Handle<Value> argv[argc] = { };
997 runge 122
    Handle<Value> result = myFunctionStartup->Call(myFunctionStartup, argc, argv);
969 runge 123
 
999 runge 124
 
125
    string commandPort = Settings::get("CommandPort");
126
    if (commandPort != "")
127
    {
128
        myCommandThread.setSettings(stoi(commandPort), "Command console");
129
        myCommandThread.start();
130
    }
131
    else
132
    {
1024 runge 133
        Logger &log = Logger::getInstance();
134
        log.add("CommandPort is not defined, can not start Command console socket\n");
999 runge 135
    }
136
 
137
 
969 runge 138
    mySemaphore.lock();
139
 
997 runge 140
    while (true)
969 runge 141
    {
142
        while (myExpressions.size() > 0)
143
        {
999 runge 144
            runExpression(myExpressions.pop());
969 runge 145
        }
146
 
147
        mySemaphore.wait();
148
    }
149
 
150
    mySemaphore.unlock();
151
}
152
 
999 runge 153
void VirtualMachine::queueExpression(Expression expression)
969 runge 154
{
999 runge 155
    myExpressions.push(expression);
969 runge 156
    mySemaphore.broadcast();
157
}
158
 
999 runge 159
string VirtualMachine::formatException(TryCatch* tryCatch)
969 runge 160
{
999 runge 161
    string result;
162
 
163
    HandleScope handleScope;
164
    String::Utf8Value exception(tryCatch->Exception());
165
    Handle<v8::Message> message = tryCatch->Message();
166
 
167
    string strException = *exception;
168
 
169
    if (message.IsEmpty())
170
    {
171
        result += strException + "\n";
172
    }
173
    else
174
    {
175
        String::Utf8Value filename(message->GetScriptResourceName());
176
        string strFilename = *filename;
177
 
178
        result += strFilename + ":" + itos(message->GetLineNumber()) + ": " + strException + "\n";
179
 
180
        String::Utf8Value sourceline(message->GetSourceLine());
181
        string strSourceline = *sourceline;
182
 
183
        result += strSourceline + "\n";
184
 
185
        string underline = rpad("", message->GetStartColumn(), ' ');
186
        underline = rpad(underline, message->GetEndColumn(), '^');
187
 
188
        result += underline + "\n";
189
    }
190
 
191
    return result;
969 runge 192
}
193
 
1007 runge 194
bool VirtualMachine::loadDataStore(string storeName)
195
{
1024 runge 196
    Logger &log = Logger::getInstance();
1007 runge 197
 
198
    string basePath = Settings::get("BasePath") + "Services/DataStores/";
199
    string scriptFileName = basePath + storeName + ".js";
200
 
201
    if (!file_exists(scriptFileName))
202
    {
1024 runge 203
        log.add("Failed to load datastore " + scriptFileName + ", file does not exist.\n");
1007 runge 204
        return false;
205
    }
206
 
207
    string scriptSource = file_get_contents(scriptFileName);
208
 
209
    scriptSource = "DataStore.addStore('" + storeName + "', " + str_replace("\n", "", scriptSource) + ");";
210
 
211
    Handle<String> source =  String::New(scriptSource.c_str(), scriptSource.length());
212
    Handle<String> name = String::New(scriptFileName.c_str(), scriptFileName.length());
213
 
214
    Context::Scope contextScope(myContext);
215
 
216
    TryCatch tryCatch;
217
 
218
    Handle<Script> script = Script::Compile(source, name);
219
 
220
    if (script.IsEmpty())
221
    {
1024 runge 222
        log.add(formatException(&tryCatch));
1007 runge 223
        return false;
224
    }
225
    else
226
    {
227
        Handle<Value> result = script->Run();
228
 
229
        if (result.IsEmpty())
230
        {
1024 runge 231
            log.add(formatException(&tryCatch));
1007 runge 232
            return false;
233
        }
234
 
1024 runge 235
        log.add("Loaded datastore " + storeName + "\n");
1007 runge 236
    }
237
 
238
    return true;
239
}
240
 
969 runge 241
bool VirtualMachine::loadScript(string scriptName)
242
{
1024 runge 243
    Logger &log = Logger::getInstance();
969 runge 244
 
981 runge 245
    string basePath = Settings::get("BasePath") + "Services/";
969 runge 246
    string scriptFileName = basePath + scriptName;
247
 
248
    if (!file_exists(scriptFileName))
249
    {
1024 runge 250
        log.add("Failed to load " + scriptFileName + ", file does not exist.\n");
969 runge 251
        return false;
252
    }
253
 
254
    string scriptSource = file_get_contents(scriptFileName);
255
 
256
    Handle<String> source =  String::New(scriptSource.c_str(), scriptSource.length());
257
    Handle<String> name = String::New(scriptName.c_str(), scriptName.length());
258
 
997 runge 259
    Context::Scope contextScope(myContext);
260
 
995 runge 261
    TryCatch tryCatch;
997 runge 262
 
969 runge 263
    Handle<Script> script = Script::Compile(source, name);
264
 
265
    if (script.IsEmpty())
266
    {
1024 runge 267
        log.addToSyslog(formatException(&tryCatch));
969 runge 268
        return false;
269
    }
270
    else
271
    {
272
        Handle<Value> result = script->Run();
273
 
274
        if (result.IsEmpty())
275
        {
1024 runge 276
            log.addToSyslog(formatException(&tryCatch));
969 runge 277
            return false;
278
        }
977 runge 279
 
1024 runge 280
        log.add("Loaded " + scriptName + "\n");
969 runge 281
    }
282
 
283
    return true;
284
}
285
 
971 runge 286
unsigned int VirtualMachine::startIntervalThread(unsigned int timeout)
969 runge 287
{
999 runge 288
    IntervalThread *intervalThread = new IntervalThread(timeout);
969 runge 289
 
999 runge 290
    myIntervalThreads[intervalThread->getId()] = intervalThread;
291
    myIntervalThreads[intervalThread->getId()]->start();
969 runge 292
 
999 runge 293
    return intervalThread->getId();
969 runge 294
}
295
 
971 runge 296
bool VirtualMachine::stopIntervalThread(unsigned int id)
969 runge 297
{
971 runge 298
    if (myIntervalThreads.find(id) != myIntervalThreads.end())
969 runge 299
    {
1042 runge 300
        myIntervalThreads[id]->stop();
999 runge 301
        delete myIntervalThreads[id];
971 runge 302
        myIntervalThreads.erase(id);
1042 runge 303
 
969 runge 304
        return true;
305
    }
306
 
307
    return false;
308
}
309
 
1042 runge 310
bool VirtualMachine::setIntervalThreadTimeout(unsigned int id, unsigned int timeout)
311
{
312
    if (myIntervalThreads.find(id) != myIntervalThreads.end())
313
    {
314
        myIntervalThreads[id]->setTimeout(timeout);
315
        return true;
316
    }
317
 
318
    return false;
319
}
320
 
976 runge 321
unsigned int VirtualMachine::startSocketThread(string address, int port, unsigned int reconnectTimeout)
322
{
983 runge 323
    SocketThread *socketThread = new SocketThread(address, port, reconnectTimeout);
324
    mySocketThreads[socketThread->getId()] = socketThread;
325
    mySocketThreads[socketThread->getId()]->start();
976 runge 326
 
983 runge 327
    return socketThread->getId();
976 runge 328
}
329
 
330
bool VirtualMachine::stopSocketThread(unsigned int id)
331
{
332
    if (mySocketThreads.find(id) != mySocketThreads.end())
333
    {
983 runge 334
        delete mySocketThreads[id];
976 runge 335
        mySocketThreads.erase(id);
336
        return true;
337
    }
338
 
339
    return false;
340
}
341
 
342
void VirtualMachine::sendToSocketThread(unsigned int id, string data)
343
{
344
    if (mySocketThreads.find(id) != mySocketThreads.end())
345
    {
983 runge 346
        mySocketThreads[id]->send(data);
976 runge 347
    }
348
}
349
 
999 runge 350
void VirtualMachine::disconnectCommandClient(unsigned int id)
969 runge 351
{
999 runge 352
    myCommandThread.disconnectClient(id);
353
}
354
 
355
void VirtualMachine::sendToCommandClient(unsigned int id, string data)
356
{
357
    myCommandThread.sendTo(id, data);
358
}
359
 
360
void VirtualMachine::print(unsigned int id, string data)
361
{
362
    if (id == 0)
363
    {
1024 runge 364
        Logger &log = Logger::getInstance();
365
        log.add(data);
999 runge 366
    }
367
    else
368
    {
369
        VirtualMachine &vm = VirtualMachine::getInstance();
370
        vm.sendToCommandClient(id, data);
371
    }
372
}
373
 
374
bool VirtualMachine::runExpression(Expression expression)
375
{
969 runge 376
    string scriptName = "runExpression";
377
 
999 runge 378
    string scriptData = expression.getScript();
379
 
1008 runge 380
    scriptData = "setClientId(" + itos(expression.getTargetId()) + ");\n" + scriptData + "\n";
999 runge 381
 
382
    Handle<String> source =  String::New(scriptData.c_str(), scriptData.length());
969 runge 383
    Handle<String> name = String::New(scriptName.c_str(), scriptName.length());
384
 
997 runge 385
    Context::Scope contextScope(myContext);
386
 
995 runge 387
    TryCatch tryCatch;
997 runge 388
 
969 runge 389
    Handle<Script> script = Script::Compile(source, name);
390
 
391
    if (script.IsEmpty())
392
    {
999 runge 393
        print(expression.getTargetId(), formatException(&tryCatch));
969 runge 394
        return false;
395
    }
396
    else
397
    {
398
        Handle<Value> result = script->Run();
399
 
400
        if (result.IsEmpty())
401
        {
999 runge 402
            print(expression.getTargetId(), formatException(&tryCatch));
969 runge 403
            return false;
404
        }
999 runge 405
        else if (expression.getTargetId() != 0)
406
        {
407
             String::AsciiValue ascii(result);
408
             string resultString = *ascii;
409
 
410
             if (resultString != "undefined")
411
             {
412
                print(expression.getTargetId(), resultString + "\n");
413
             }
414
        }
969 runge 415
    }
416
 
417
    return true;
418
}
419
 
999 runge 420
 
421
Handle<Value> VirtualMachine::_quit(const Arguments& args)
995 runge 422
{
999 runge 423
    VirtualMachine &vm = VirtualMachine::getInstance();
995 runge 424
 
999 runge 425
    vm.disconnectCommandClient(args[0]->Uint32Value());
995 runge 426
 
999 runge 427
    return Undefined();
428
}
995 runge 429
 
999 runge 430
Handle<Value> VirtualMachine::_log(const Arguments& args)
431
{
1024 runge 432
    Logger &log = Logger::getInstance();
995 runge 433
 
999 runge 434
    String::AsciiValue str(args[0]);
995 runge 435
 
1024 runge 436
    log.add(*str);
995 runge 437
 
999 runge 438
    return Undefined();
995 runge 439
}
440
 
999 runge 441
Handle<Value> VirtualMachine::_print(const Arguments& args)
969 runge 442
{
999 runge 443
    VirtualMachine &vm = VirtualMachine::getInstance();
969 runge 444
 
999 runge 445
    String::AsciiValue str(args[1]);
969 runge 446
 
999 runge 447
    vm.print(args[0]->Uint32Value(), *str);
969 runge 448
 
449
    return Undefined();
450
}
451
 
999 runge 452
Handle<Value> VirtualMachine::_sendCanMessage(const Arguments& args)
969 runge 453
{
454
    CanNetManager &canMan = CanNetManager::getInstance();
455
 
456
    CanMessage canMessage;
457
 
458
    String::AsciiValue className(args[0]);
459
    canMessage.setClassName(*className);
460
    String::AsciiValue directionFlag(args[1]);
461
    canMessage.setDirectionFlag(*directionFlag);
462
    String::AsciiValue moduleName(args[2]);
463
    canMessage.setModuleName(*moduleName);
464
    canMessage.setModuleId(args[3]->Uint32Value());
465
    String::AsciiValue commandName(args[4]);
466
    canMessage.setCommandName(*commandName);
467
 
468
    String::AsciiValue dataString(args[5]);
469
 
470
    vector<string> parts = explode(",", trim(*dataString, ','));
471
    map<string, CanVariable> data;
472
 
473
    for (int n = 0; n < parts.size(); n++)
474
    {
475
        vector<string> keyAndValue = explode(":", parts[n]);
476
 
477
        data[keyAndValue[0]] = CanVariable(keyAndValue[0], keyAndValue[1]);
478
    }
479
 
480
    canMessage.setData(data);
481
 
482
    canMan.sendMessage(canMessage);
483
 
484
    return Undefined();
485
}
486
 
999 runge 487
Handle<Value> VirtualMachine::_sendCanNMTMessage(const Arguments& args)
986 runge 488
{
489
    CanNetManager &canMan = CanNetManager::getInstance();
490
 
491
    CanMessage canMessage;
492
 
493
    String::AsciiValue className(args[0]);
494
    canMessage.setClassName(*className);
495
    String::AsciiValue commandName(args[1]);
496
    canMessage.setCommandName(*commandName);
497
 
498
    String::AsciiValue dataString(args[2]);
499
 
500
    vector<string> parts = explode(",", trim(*dataString, ','));
501
    map<string, CanVariable> data;
502
 
503
    for (int n = 0; n < parts.size(); n++)
504
    {
505
        vector<string> keyAndValue = explode(":", parts[n]);
506
 
507
        data[keyAndValue[0]] = CanVariable(keyAndValue[0], keyAndValue[1]);
508
    }
509
 
510
    canMessage.setData(data);
511
 
512
    canMan.sendMessage(canMessage);
513
 
514
    return Undefined();
515
}
516
 
999 runge 517
Handle<Value> VirtualMachine::_loadScript(const Arguments& args)
969 runge 518
{
519
    VirtualMachine &vm = VirtualMachine::getInstance();
520
 
521
    String::AsciiValue str(args[0]);
522
 
523
    return Boolean::New(vm.loadScript(*str));
524
}
525
 
1007 runge 526
Handle<Value> VirtualMachine::_loadDataStore(const Arguments& args)
527
{
528
    VirtualMachine &vm = VirtualMachine::getInstance();
529
 
530
    String::AsciiValue str(args[0]);
531
 
532
    return Boolean::New(vm.loadDataStore(*str));
533
}
534
 
999 runge 535
Handle<Value> VirtualMachine::_startIntervalThread(const Arguments& args)
969 runge 536
{
537
    VirtualMachine &vm = VirtualMachine::getInstance();
999 runge 538
    return Integer::New(vm.startIntervalThread(args[0]->Uint32Value()));
969 runge 539
}
540
 
999 runge 541
Handle<Value> VirtualMachine::_stopIntervalThread(const Arguments& args)
969 runge 542
{
543
    VirtualMachine &vm = VirtualMachine::getInstance();
999 runge 544
    return Boolean::New(vm.stopIntervalThread(args[0]->Uint32Value()));
969 runge 545
}
976 runge 546
 
1042 runge 547
Handle<Value> VirtualMachine::_setIntervalThreadTimeout(const Arguments& args)
548
{
549
    VirtualMachine &vm = VirtualMachine::getInstance();
550
    return Integer::New(vm.setIntervalThreadTimeout(args[0]->Uint32Value(), args[1]->Uint32Value()));
551
}
552
 
999 runge 553
Handle<Value> VirtualMachine::_startSocketThread(const Arguments& args)
976 runge 554
{
555
    VirtualMachine &vm = VirtualMachine::getInstance();
556
 
557
    String::AsciiValue address(args[0]);
558
 
999 runge 559
    return Integer::New(vm.startSocketThread(*address, args[1]->Uint32Value(), args[2]->Uint32Value()));
976 runge 560
}
561
 
999 runge 562
Handle<Value> VirtualMachine::_stopSocketThread(const Arguments& args)
976 runge 563
{
564
    VirtualMachine &vm = VirtualMachine::getInstance();
565
 
999 runge 566
    return Boolean::New(vm.stopSocketThread(args[0]->Uint32Value()));
976 runge 567
}
568
 
999 runge 569
Handle<Value> VirtualMachine::_sendToSocketThread(const Arguments& args)
976 runge 570
{
571
    VirtualMachine &vm = VirtualMachine::getInstance();
572
 
573
    String::AsciiValue data(args[1]);
574
 
999 runge 575
    vm.sendToSocketThread(args[0]->Uint32Value(), *data);
976 runge 576
 
577
    return Undefined();
578
}
579
 
1008 runge 580
Handle<Value> VirtualMachine::_getFileContents(const Arguments& args)
581
{
582
    String::AsciiValue filename(args[0]);
583
 
584
    if (!file_exists(*filename))
585
    {
586
        return Undefined();
587
    }
588
 
589
    string content = file_get_contents(*filename);
590
 
591
    return String::New(content.c_str());
592
}
593
 
1010 runge 594
Handle<Value> VirtualMachine::_uint2hex(const Arguments& args)
595
{
596
    string hex = uint2hex(args[0]->Uint32Value(), args[1]->Uint32Value());
597
    return String::New(hex.c_str());
598
}
599
 
600
Handle<Value> VirtualMachine::_hex2bin(const Arguments& args)
601
{
602
    String::AsciiValue hex(args[0]);
603
    string bin = hex2bin(*hex);
604
    return String::New(bin.c_str());
605
}
606
 
607
Handle<Value> VirtualMachine::_bin2hex(const Arguments& args)
608
{
609
    String::AsciiValue bin(args[0]);
610
    string hex = bin2hex(*bin);
611
    return String::New(hex.c_str());
612
}
613
 
614
Handle<Value> VirtualMachine::_bin2float(const Arguments& args)
615
{
616
    String::AsciiValue bin(args[0]);
617
    float f = bin2float(*bin);
618
    return Number::New(f);
619
}
620
 
621
Handle<Value> VirtualMachine::_float2bin(const Arguments& args)
622
{
623
    string bin = float2bin(args[0]->NumberValue(), args[1]->Uint32Value());
624
    return String::New(bin.c_str());
625
}
626
 
627
Handle<Value> VirtualMachine::_bin2uint(const Arguments& args)
628
{
629
    String::AsciiValue bin(args[0]);
630
    unsigned int num = bin2uint(*bin);
1012 runge 631
    return Number::New(num);
1010 runge 632
}
633
 
634
Handle<Value> VirtualMachine::_uint2bin(const Arguments& args)
635
{
636
    string bin = uint2bin(args[0]->Uint32Value(), args[1]->Uint32Value());
637
    return String::New(bin.c_str());
638
}
639
 
1011 runge 640
Handle<Value> VirtualMachine::_hex2uint(const Arguments& args)
641
{
642
    String::AsciiValue hex(args[0]);
643
    unsigned int num = hex2uint(*hex);
1012 runge 644
    return Number::New(num);
1011 runge 645
}
1060 runge 646
 
647
Handle<Value> VirtualMachine::_sleep(const Arguments& args)
648
{
649
    usleep(args[0]->Uint32Value());
650
    return Undefined();
651
}