Subversion Repositories HomeAutomation

Rev

Rev 1229 | Rev 1405 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | SVN | RSS feed

  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. {
  51.     stop();
  52.  
  53.     myCommandThread.stop();
  54.  
  55.     ///FIXME: Verify that this works and does not cause segfaults
  56.     for (map<unsigned long int, SocketThread*>::iterator iter = mySocketThreads.begin(); iter != mySocketThreads.end(); iter++)
  57.     {
  58.         iter->second->stop();
  59.         delete iter->second;
  60.         //mySocketThreads.erase(iter);
  61.     }
  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();
  73. }
  74.  
  75. void VirtualMachine::run()
  76. {
  77.     myGlobal = ObjectTemplate::New();
  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));
  86.     myGlobal->Set(String::New("setIntervalThreadTimeout"), FunctionTemplate::New(VirtualMachine::_setIntervalThreadTimeout));
  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));
  90.     myGlobal->Set(String::New("loadDataStore"), FunctionTemplate::New(VirtualMachine::_loadDataStore));
  91.     myGlobal->Set(String::New("getFileContents"), FunctionTemplate::New(VirtualMachine::_getFileContents));
  92.     myGlobal->Set(String::New("system"), FunctionTemplate::New(VirtualMachine::_system));
  93.     myGlobal->Set(String::New("uint2hex"), FunctionTemplate::New(VirtualMachine::_uint2hex));
  94.     myGlobal->Set(String::New("hex2bin"), FunctionTemplate::New(VirtualMachine::_hex2bin));
  95.     myGlobal->Set(String::New("bin2hex"), FunctionTemplate::New(VirtualMachine::_bin2hex));
  96.     myGlobal->Set(String::New("bin2float"), FunctionTemplate::New(VirtualMachine::_bin2float));
  97.     myGlobal->Set(String::New("float2bin"), FunctionTemplate::New(VirtualMachine::_float2bin));
  98.     myGlobal->Set(String::New("bin2uint"), FunctionTemplate::New(VirtualMachine::_bin2uint));
  99.     myGlobal->Set(String::New("uint2bin"), FunctionTemplate::New(VirtualMachine::_uint2bin));
  100.     myGlobal->Set(String::New("hex2uint"), FunctionTemplate::New(VirtualMachine::_hex2uint));
  101.     myGlobal->Set(String::New("sleep"), FunctionTemplate::New(VirtualMachine::_sleep));
  102.     myContext = Context::New(NULL, myGlobal);
  103.  
  104.  
  105.     if (loadScript("System/Base.js"))
  106.     {
  107.         loadScript("System/Startup.js");
  108.  
  109.         loadScript("Autostart.js");
  110.  
  111.         Context::Scope contextScope(myContext);
  112.  
  113.         myFunctionStartup = Handle<Function>::Cast(myContext->Global()->Get(String::New("startup")));
  114.     }
  115.     else
  116.     {
  117.         ///FIXME: We should probably exit the application here
  118.         return;
  119.     }
  120.  
  121.     const int argc = 0;
  122.     Handle<Value> argv[argc] = { };
  123.     Handle<Value> result = myFunctionStartup->Call(myFunctionStartup, argc, argv);
  124.  
  125.  
  126.     string commandPort = Settings::get("CommandPort");
  127.     if (commandPort != "")
  128.     {
  129.         myCommandThread.setSettings(stoi(commandPort), "Command console");
  130.         myCommandThread.start();
  131.     }
  132.     else
  133.     {
  134.         Logger &log = Logger::getInstance();
  135.         log.add("CommandPort is not defined, can not start Command console socket\n");
  136.     }
  137.  
  138.  
  139.     mySemaphore.lock();
  140.  
  141.     while (true)
  142.     {
  143.         while (myExpressions.size() > 0)
  144.         {
  145.             runExpression(myExpressions.pop());
  146.         }
  147.  
  148.         mySemaphore.wait();
  149.     }
  150.  
  151.     mySemaphore.unlock();
  152. }
  153.  
  154. void VirtualMachine::queueExpression(Expression expression)
  155. {
  156.     myExpressions.push(expression);
  157.     mySemaphore.broadcast();
  158. }
  159.  
  160. string VirtualMachine::formatException(TryCatch* tryCatch)
  161. {
  162.     string result;
  163.  
  164.     HandleScope handleScope;
  165.     String::Utf8Value exception(tryCatch->Exception());
  166.     Handle<v8::Message> message = tryCatch->Message();
  167.  
  168.     string strException = *exception;
  169.  
  170.     if (message.IsEmpty())
  171.     {
  172.         result += strException + "\n";
  173.     }
  174.     else
  175.     {
  176.         String::Utf8Value filename(message->GetScriptResourceName());
  177.         string strFilename = *filename;
  178.  
  179.         result += strFilename + ":" + itos(message->GetLineNumber()) + ": " + strException + "\n";
  180.  
  181.         String::Utf8Value sourceline(message->GetSourceLine());
  182.         string strSourceline = *sourceline;
  183.  
  184.         result += strSourceline + "\n";
  185.  
  186.         string underline = rpad("", message->GetStartColumn(), ' ');
  187.         underline = rpad(underline, message->GetEndColumn(), '^');
  188.  
  189.         result += underline + "\n";
  190.     }
  191.  
  192.     return result;
  193. }
  194.  
  195. bool VirtualMachine::loadDataStore(string storeName)
  196. {
  197.     Logger &log = Logger::getInstance();
  198.  
  199.     string basePath = Settings::get("BasePath") + "Services/DataStores/";
  200.     string scriptFileName = basePath + storeName + ".js";
  201.  
  202.     if (!file_exists(scriptFileName))
  203.     {
  204.         log.add("Failed to load datastore " + scriptFileName + ", file does not exist.\n");
  205.         return false;
  206.     }
  207.  
  208.     string scriptSource = file_get_contents(scriptFileName);
  209.  
  210.     scriptSource = "DataStore.addStore('" + storeName + "', " + str_replace("\n", "", scriptSource) + ");";
  211.  
  212.     Handle<String> source =  String::New(scriptSource.c_str(), scriptSource.length());
  213.     Handle<String> name = String::New(scriptFileName.c_str(), scriptFileName.length());
  214.  
  215.     Context::Scope contextScope(myContext);
  216.  
  217.     TryCatch tryCatch;
  218.  
  219.     Handle<Script> script = Script::Compile(source, name);
  220.  
  221.     if (script.IsEmpty())
  222.     {
  223.         log.add(formatException(&tryCatch));
  224.         return false;
  225.     }
  226.     else
  227.     {
  228.         Handle<Value> result = script->Run();
  229.  
  230.         if (result.IsEmpty())
  231.         {
  232.             log.add(formatException(&tryCatch));
  233.             return false;
  234.         }
  235.  
  236.         log.add("Loaded datastore " + storeName + "\n");
  237.     }
  238.  
  239.     return true;
  240. }
  241.  
  242. bool VirtualMachine::loadScript(string scriptName)
  243. {
  244.     Logger &log = Logger::getInstance();
  245.  
  246.     string basePath = Settings::get("BasePath") + "Services/";
  247.     string scriptFileName = basePath + scriptName;
  248.  
  249.     if (!file_exists(scriptFileName))
  250.     {
  251.         log.add("Failed to load " + scriptFileName + ", file does not exist.\n");
  252.         return false;
  253.     }
  254.  
  255.     string scriptSource = file_get_contents(scriptFileName);
  256.  
  257.     Handle<String> source =  String::New(scriptSource.c_str(), scriptSource.length());
  258.     Handle<String> name = String::New(scriptName.c_str(), scriptName.length());
  259.  
  260.     Context::Scope contextScope(myContext);
  261.  
  262.     TryCatch tryCatch;
  263.  
  264.     Handle<Script> script = Script::Compile(source, name);
  265.  
  266.     if (script.IsEmpty())
  267.     {
  268.         log.addToSyslog(formatException(&tryCatch));
  269.         return false;
  270.     }
  271.     else
  272.     {
  273.         Handle<Value> result = script->Run();
  274.  
  275.         if (result.IsEmpty())
  276.         {
  277.             log.addToSyslog(formatException(&tryCatch));
  278.             return false;
  279.         }
  280.  
  281.         log.add("Loaded " + scriptName + "\n");
  282.     }
  283.  
  284.     return true;
  285. }
  286.  
  287. unsigned int VirtualMachine::startIntervalThread(unsigned int timeout)
  288. {
  289.     IntervalThread *intervalThread = new IntervalThread(timeout);
  290.  
  291.     myIntervalThreads[intervalThread->getId()] = intervalThread;
  292.     myIntervalThreads[intervalThread->getId()]->start();
  293.  
  294.     return intervalThread->getId();
  295. }
  296.  
  297. bool VirtualMachine::stopIntervalThread(unsigned int id)
  298. {
  299.     if (myIntervalThreads.find(id) != myIntervalThreads.end())
  300.     {
  301.         myIntervalThreads[id]->stop();
  302.         delete myIntervalThreads[id];
  303.         myIntervalThreads.erase(id);
  304.  
  305.         return true;
  306.     }
  307.  
  308.     return false;
  309. }
  310.  
  311. bool VirtualMachine::setIntervalThreadTimeout(unsigned int id, unsigned int timeout)
  312. {
  313.     if (myIntervalThreads.find(id) != myIntervalThreads.end())
  314.     {
  315.         myIntervalThreads[id]->setTimeout(timeout);
  316.         return true;
  317.     }
  318.  
  319.     return false;
  320. }
  321.  
  322. unsigned int VirtualMachine::startSocketThread(string address, int port, unsigned int reconnectTimeout)
  323. {
  324.     SocketThread *socketThread = new SocketThread(address, port, reconnectTimeout);
  325.     mySocketThreads[socketThread->getId()] = socketThread;
  326.     mySocketThreads[socketThread->getId()]->start();
  327.     mySocketThreads[socketThread->getId()]->startSocket();
  328.  
  329.     return socketThread->getId();
  330. }
  331.  
  332. bool VirtualMachine::stopSocketThread(unsigned int id)
  333. {
  334.     if (mySocketThreads.find(id) != mySocketThreads.end())
  335.     {
  336.         delete mySocketThreads[id];
  337.         mySocketThreads.erase(id);
  338.         return true;
  339.     }
  340.  
  341.     return false;
  342. }
  343.  
  344. void VirtualMachine::sendToSocketThread(unsigned int id, string data)
  345. {
  346.     if (mySocketThreads.find(id) != mySocketThreads.end())
  347.     {
  348.         mySocketThreads[id]->send(data);
  349.     }
  350. }
  351.  
  352. void VirtualMachine::disconnectCommandClient(unsigned int id)
  353. {
  354.     myCommandThread.disconnectClient(id);
  355. }
  356.  
  357. void VirtualMachine::sendToCommandClient(unsigned int id, string data)
  358. {
  359.     myCommandThread.sendTo(id, data);
  360. }
  361.  
  362. void VirtualMachine::print(unsigned int id, string data)
  363. {
  364.     if (id == 0)
  365.     {
  366.         Logger &log = Logger::getInstance();
  367.         log.add(data);
  368.     }
  369.     else
  370.     {
  371.         VirtualMachine &vm = VirtualMachine::getInstance();
  372.         vm.sendToCommandClient(id, data);
  373.     }
  374. }
  375.  
  376. bool VirtualMachine::runExpression(Expression expression)
  377. {
  378.     string scriptName = "runExpression";
  379.  
  380.     string scriptData = expression.getScript();
  381.  
  382.     scriptData = "setClientId(" + itos(expression.getTargetId()) + ");\n" + scriptData + "\n";
  383.  
  384.     Handle<String> source =  String::New(scriptData.c_str(), scriptData.length());
  385.     Handle<String> name = String::New(scriptName.c_str(), scriptName.length());
  386.  
  387.     Context::Scope contextScope(myContext);
  388.  
  389.     TryCatch tryCatch;
  390.  
  391.     Handle<Script> script = Script::Compile(source, name);
  392.  
  393.     if (script.IsEmpty())
  394.     {
  395.         print(expression.getTargetId(), formatException(&tryCatch));
  396.         return false;
  397.     }
  398.     else
  399.     {
  400.         Handle<Value> result = script->Run();
  401.  
  402.         if (result.IsEmpty())
  403.         {
  404.             print(expression.getTargetId(), formatException(&tryCatch));
  405.             return false;
  406.         }
  407.         else if (expression.getTargetId() != 0)
  408.         {
  409.              String::AsciiValue ascii(result);
  410.              string resultString = *ascii;
  411.  
  412.              if (resultString != "undefined")
  413.              {
  414.                 print(expression.getTargetId(), resultString + "\n");
  415.              }
  416.         }
  417.     }
  418.  
  419.     return true;
  420. }
  421.  
  422.  
  423. Handle<Value> VirtualMachine::_quit(const Arguments& args)
  424. {
  425.     VirtualMachine &vm = VirtualMachine::getInstance();
  426.  
  427.     vm.disconnectCommandClient(args[0]->Uint32Value());
  428.  
  429.     return Undefined();
  430. }
  431.  
  432. Handle<Value> VirtualMachine::_log(const Arguments& args)
  433. {
  434.     Logger &log = Logger::getInstance();
  435.  
  436.     String::AsciiValue str(args[0]);
  437.  
  438.     log.add(*str);
  439.  
  440.     return Undefined();
  441. }
  442.  
  443. Handle<Value> VirtualMachine::_print(const Arguments& args)
  444. {
  445.     VirtualMachine &vm = VirtualMachine::getInstance();
  446.  
  447.     String::AsciiValue str(args[1]);
  448.  
  449.     vm.print(args[0]->Uint32Value(), *str);
  450.  
  451.     return Undefined();
  452. }
  453.  
  454. Handle<Value> VirtualMachine::_sendCanMessage(const Arguments& args)
  455. {
  456.     CanNetManager &canMan = CanNetManager::getInstance();
  457.  
  458.     CanMessage canMessage;
  459.  
  460.     String::AsciiValue className(args[0]);
  461.     canMessage.setClassName(*className);
  462.     String::AsciiValue directionFlag(args[1]);
  463.     canMessage.setDirectionFlag(*directionFlag);
  464.     String::AsciiValue moduleName(args[2]);
  465.     canMessage.setModuleName(*moduleName);
  466.     canMessage.setModuleId(args[3]->Uint32Value());
  467.     String::AsciiValue commandName(args[4]);
  468.     canMessage.setCommandName(*commandName);
  469.  
  470.     String::AsciiValue dataString(args[5]);
  471.  
  472.     vector<string> parts = explode(",", trim(*dataString, ','));
  473.     map<string, CanVariable> data;
  474.  
  475.     for (int n = 0; n < parts.size(); n++)
  476.     {
  477.         vector<string> keyAndValue = explode(":", parts[n]);
  478.  
  479.         /* decode base64 on the data part */
  480.         keyAndValue[1] = base64_decode(keyAndValue[1]);
  481.  
  482.         data[keyAndValue[0]] = CanVariable(keyAndValue[0], keyAndValue[1]);
  483.     }
  484.  
  485.     canMessage.setData(data);
  486.    
  487.     canMan.sendMessage(canMessage);
  488.  
  489.     return Undefined();
  490. }
  491.  
  492. Handle<Value> VirtualMachine::_sendCanNMTMessage(const Arguments& args)
  493. {
  494.     CanNetManager &canMan = CanNetManager::getInstance();
  495.  
  496.     CanMessage canMessage;
  497.  
  498.     String::AsciiValue className(args[0]);
  499.     canMessage.setClassName(*className);
  500.     String::AsciiValue commandName(args[1]);
  501.     canMessage.setCommandName(*commandName);
  502.  
  503.     String::AsciiValue dataString(args[2]);
  504.  
  505.     vector<string> parts = explode(",", trim(*dataString, ','));
  506.     map<string, CanVariable> data;
  507.  
  508.     for (int n = 0; n < parts.size(); n++)
  509.     {
  510.         vector<string> keyAndValue = explode(":", parts[n]);
  511.  
  512.         data[keyAndValue[0]] = CanVariable(keyAndValue[0], keyAndValue[1]);
  513.     }
  514.  
  515.     canMessage.setData(data);
  516.  
  517.     canMan.sendMessage(canMessage);
  518.  
  519.     return Undefined();
  520. }
  521.  
  522. Handle<Value> VirtualMachine::_loadScript(const Arguments& args)
  523. {
  524.     VirtualMachine &vm = VirtualMachine::getInstance();
  525.  
  526.     String::AsciiValue str(args[0]);
  527.  
  528.     return Boolean::New(vm.loadScript(*str));
  529. }
  530.  
  531. Handle<Value> VirtualMachine::_loadDataStore(const Arguments& args)
  532. {
  533.     VirtualMachine &vm = VirtualMachine::getInstance();
  534.  
  535.     String::AsciiValue str(args[0]);
  536.  
  537.     return Boolean::New(vm.loadDataStore(*str));
  538. }
  539.  
  540. Handle<Value> VirtualMachine::_startIntervalThread(const Arguments& args)
  541. {
  542.     VirtualMachine &vm = VirtualMachine::getInstance();
  543.     return Integer::New(vm.startIntervalThread(args[0]->Uint32Value()));
  544. }
  545.  
  546. Handle<Value> VirtualMachine::_stopIntervalThread(const Arguments& args)
  547. {
  548.     VirtualMachine &vm = VirtualMachine::getInstance();
  549.     return Boolean::New(vm.stopIntervalThread(args[0]->Uint32Value()));
  550. }
  551.  
  552. Handle<Value> VirtualMachine::_setIntervalThreadTimeout(const Arguments& args)
  553. {
  554.     VirtualMachine &vm = VirtualMachine::getInstance();
  555.     return Integer::New(vm.setIntervalThreadTimeout(args[0]->Uint32Value(), args[1]->Uint32Value()));
  556. }
  557.  
  558. Handle<Value> VirtualMachine::_startSocketThread(const Arguments& args)
  559. {
  560.     VirtualMachine &vm = VirtualMachine::getInstance();
  561.  
  562.     String::AsciiValue address(args[0]);
  563.  
  564.     return Integer::New(vm.startSocketThread(*address, args[1]->Uint32Value(), args[2]->Uint32Value()));
  565. }
  566.  
  567. Handle<Value> VirtualMachine::_stopSocketThread(const Arguments& args)
  568. {
  569.     VirtualMachine &vm = VirtualMachine::getInstance();
  570.  
  571.     return Boolean::New(vm.stopSocketThread(args[0]->Uint32Value()));
  572. }
  573.  
  574. Handle<Value> VirtualMachine::_sendToSocketThread(const Arguments& args)
  575. {
  576.     VirtualMachine &vm = VirtualMachine::getInstance();
  577.  
  578.     String::AsciiValue data(args[1]);
  579.  
  580.     vm.sendToSocketThread(args[0]->Uint32Value(), *data);
  581.  
  582.     return Undefined();
  583. }
  584.  
  585. Handle<Value> VirtualMachine::_getFileContents(const Arguments& args)
  586. {
  587.     String::AsciiValue filename(args[0]);
  588.  
  589.     if (!file_exists(*filename))
  590.     {
  591.         return Undefined();
  592.     }
  593.  
  594.     string content = file_get_contents(*filename);
  595.  
  596.     return String::New(content.c_str());
  597. }
  598.  
  599. #include <string>
  600. #include <iostream>
  601. #include <stdio.h>
  602.  
  603. std::string exec(string cmd) {
  604.     FILE* pipe = popen(cmd.c_str(), "r");
  605.     if (!pipe) return "ERROR";
  606.     char buffer[128];
  607.     std::string result = "";
  608.     while(!feof(pipe)) {
  609.         if(fgets(buffer, 128, pipe) != NULL)
  610.                 result += buffer;
  611.     }
  612.     pclose(pipe);
  613.     return result;
  614. }
  615.  
  616. Handle<Value> VirtualMachine::_system(const Arguments& args)
  617. {
  618.     String::AsciiValue command(args[0]);
  619.    
  620.     string output = exec(*command);
  621.    
  622.     return String::New(output.c_str());
  623. }
  624.  
  625. Handle<Value> VirtualMachine::_uint2hex(const Arguments& args)
  626. {
  627.     string hex = uint2hex(args[0]->Uint32Value(), args[1]->Uint32Value());
  628.     return String::New(hex.c_str());
  629. }
  630.  
  631. Handle<Value> VirtualMachine::_hex2bin(const Arguments& args)
  632. {
  633.     String::AsciiValue hex(args[0]);
  634.     string bin = hex2bin(*hex);
  635.     return String::New(bin.c_str());
  636. }
  637.  
  638. Handle<Value> VirtualMachine::_bin2hex(const Arguments& args)
  639. {
  640.     String::AsciiValue bin(args[0]);
  641.     string hex = bin2hex(*bin);
  642.     return String::New(hex.c_str());
  643. }
  644.  
  645. Handle<Value> VirtualMachine::_bin2float(const Arguments& args)
  646. {
  647.     String::AsciiValue bin(args[0]);
  648.     float f = bin2float(*bin);
  649.     return Number::New(f);
  650. }
  651.  
  652. Handle<Value> VirtualMachine::_float2bin(const Arguments& args)
  653. {
  654.     string bin = float2bin(args[0]->NumberValue(), args[1]->Uint32Value());
  655.     return String::New(bin.c_str());
  656. }
  657.  
  658. Handle<Value> VirtualMachine::_bin2uint(const Arguments& args)
  659. {
  660.     String::AsciiValue bin(args[0]);
  661.     unsigned int num = bin2uint(*bin);
  662.     return Number::New(num);
  663. }
  664.  
  665. Handle<Value> VirtualMachine::_uint2bin(const Arguments& args)
  666. {
  667.     string bin = uint2bin(args[0]->Uint32Value(), args[1]->Uint32Value());
  668.     return String::New(bin.c_str());
  669. }
  670.  
  671. Handle<Value> VirtualMachine::_hex2uint(const Arguments& args)
  672. {
  673.     String::AsciiValue hex(args[0]);
  674.     unsigned int num = hex2uint(*hex);
  675.     return Number::New(num);
  676. }
  677.  
  678. Handle<Value> VirtualMachine::_sleep(const Arguments& args)
  679. {
  680.     usleep(args[0]->Uint32Value());
  681.     return Undefined();
  682. }
  683.