Subversion Repositories HomeAutomation

Rev

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