Ejemplo n.º 1
0
Function &OptimizeForRuntime(Function &F) {
#ifdef DEBUG
  static PassManagerBuilder Builder = getDebugBuilder();
#else
  static PassManagerBuilder Builder = getBuilder();
#endif
  Module *M = F.getParent();
  opt::GenerateOutput = true;
  polly::opt::PollyParallel = true;

  FunctionPassManager PM = FunctionPassManager(M);

  Builder.populateFunctionPassManager(PM);
  PM.doInitialization();
  PM.run(F);
  PM.doFinalization();

  if (opt::havePapi()) {
    PassManager MPM;
    Builder.populateModulePassManager(MPM);
    MPM.add(polli::createTraceMarkerPass());
    MPM.run(*M);
  }

  if (opt::haveLikwid()) {
    PassManager MPM;
    Builder.populateModulePassManager(MPM);
    MPM.add(polli::createLikwidMarkerPass());
    MPM.run(*M);
  }

  DEBUG(
  StoreModule(*M, M->getModuleIdentifier() + ".after.polly.ll")
  );
  opt::GenerateOutput = false;

  return F;
}
Ejemplo n.º 2
0
void ModuleLoader::StorePreBuiltModule( v8::Isolate* isolate, v8::Local<v8::Object>& exportObject, const std::string& name )
{
  StoreModule( "", name, name, isolate, exportObject );
}
Ejemplo n.º 3
0
/**
 * ### var module = require("module-name");
 *
 *
 * There is no standard for modules or the 'require' keyword in JavaScript.<br />
 * However CommonJS have this: http://wiki.commonjs.org/wiki/Modules/1.1.1  ( used by Node.js).
 * <br /> <br />
 *
 * The concept behind 'require' keyword is simple, it allows you to include another
 * JavaScript file, which exports an API / function / constructor / singleton.
 *
 *
 *     // example_module.js
 *     exports.hello = function() { return "hello world" }
 *
 * <br />
 *
 *     // main.js
 *     var example = require( "example_module.js");
 *
 *     log( example.hello() );
 *
 *

 * ### Module writers guide:
 *
 *
 * #### Exporting as a namespace
 *
 * Example of using a namespace to export functions / objects.
 *
 *     // filesystem-helper.js
 *     exports.version = "FileSystem helper 1.0";
 *     exports.open = function() { }
 *     exports.close = function() { }
 *     exports.read = function() { }
 *     exports.write = function() { ... }
 *     exports.fileSize = function() {...}
 *
 * <br />
 *
 *     // main.js
 *     var fs = require( "filesystem-helper.js");
 *
 *     log( fs.version );
 *
 *     var file = fs.open("myfile.txt");
 *     var data = fs.read( file );
 *
 *
 *
 * #### Exporting as a function
 *
 * In this example we are using module.exports directly to change it
 * from an object literal with name-value pairs (exports object) to a function.
 *
 *     // my_first_module.js
 *     module.exports = function() {  log("hello-world"); }
 *
 * <br />
 *
 *     // main.js
 *     var func = require("my_first_module.js");
 *     func();      // prints out hello-world
 *
 *
 * #### Exporting as a constructor
 *
 *
 *     // ImageActor.js
 *     function ImageActor( position, orientation, image, name )
 *     {
 *         this = new dali.ImageActor( image );
 *         this.position = position;
 *         this.orientation = orientation;
 *         this.name = name;
 *     }
 *     module.exports = ImageActor;
 *
 * <br />
 *
 *     // main.js
 *
 *     var ImageActor = require(" ImageActor.js");
 *
 *     var imageActor = new ImageActor( position, orientation, image, "my first image actor");
 *
 * #### Exporting as a singleton
 *
 * By exporting a singleton you have an object which has shared state between
 * any modules using it.
 *
 * example:
 *
 *     // image-database.js
 *
 *     function ImageDatabase( )
 *     {
 *       this.addImage  = function() {  ... };
 *       this.removeImage = function() { ... };
 *       this.getImage = function()  { ...};
 *       this.getImageCount = function() { ... };
 *     }
 *
 *     module.exports = new ImageDatabase();
 *
 *
 * <br />
 *
 *     // main.js
 *
 *     var database = require('image-database.js');
 *
 *     database.addImage( myImage );
 *
 * <br />
 *
 *     // another-module.js
 *     var database = require('image-database.js');
 *
 *     // gets the same database object as main.js
 *
 *
 * The first call to require('image-database.js') will create the image database.
 * Further calls, will return the same instance, because require caches module.exports.
 * Otherwise it would have to recompile and run the module every time require is called.
 *
 * ## Notes
 *
 * #### Automatic wrapping of a module by DALi:
 *
 * The module is automatically wrapped in a function by DALi before being executed ( similar technique to Node.js). </br>
 * This is to prevent any functions / variables declared by the module entering the global namespace. </br>
 * Currently the module will have access to all DALi global functions, like log, require and the DALi API ( actors / stage etc).</br>
 *
 *
 *     // Parameters passed to the internally generated function
 *     // module = reference to current module
 *     // module.exports = defines what the module exports
 *     // exports = reference to module.exports
 *     // __filename = module filename
 *     // __dirname = module directory
 *
 *     function createModuleXYZ( exports ( === module.exports), module, __filename, __dirname )
 *     {
 *       //
 *       // Module code automatically inserted here.
 *       //
 *       log(" my first module ");
 *       var version = "1.3";      // this won't pollute global namespace
 *       exports.version = version;
 *       exports.logActorPosition = function( actorName )
 *       {
 *         var actor = dali.stage.getRootLayer().findChildByName(actorName );
 *         log( actor.x + "," + actor.y + "," + actor.z );
 *        }
 *       //
 *       // End module code
 *       //
 *
 *       return module.exports;
 *     }

 *
 * Initially module.exports is an object literal with name-value pairs ( exports object).
 * However it can be re-assigned to a constructor / function / singleton object as shown
 * in the examples above.
 *
 *
 *  ### Circular dependencies:
 *
 *  DALi JS supports circular dependencies as required by the CommonJS specification.
 *
 *  #### a.js
 *
 *
 *     export.version = "1.3"
 *     export.loaded = false;
 *     var bModule = require('b.js')
 *     export.loaded = true;
 *
 *  #### b.js
 *
 *     var aModule = require('a.js')
 *     log( "aModule version = " + aModule.version + ", aModule loaded = " + aModule.loaded );
 *
 *     //prints  aModule = 1.3, aModule loaded = false
 *
 *  #### main.js
 *
 *      var aModule = require("a.js");
 *
 *
 *  When b.js requires a.js, it is given everything that is exported from a.js, up to the point
 *  b.js is required by a.js.
 *
 * ### 'require' background
 *
 * There is alternative to module spec in CommonJS called RequireJs ( http://requirejs.org/docs/node.html) <br />
 * DALi JS tries to follows the CommonJS  specification (used by Node.js) as it
 * is supposed to be better suited to server side development. <br /><br />
 *
 * @method require
 * @for ModuleLoader
 *
 */
void ModuleLoader::Require(const v8::FunctionCallbackInfo< v8::Value >& args )
{
  v8::Isolate* isolate = args.GetIsolate();
  v8::HandleScope handleScope( isolate );

  bool found( false );
  std::string fileName = V8Utils::GetStringParameter( PARAMETER_0, found, isolate , args );
  if( !found )
  {
    DALI_SCRIPT_EXCEPTION( isolate, "require missing module name");
    return;
  }

  // strip off any path / .js
  std::string moduleName;
  V8Utils::GetModuleName( fileName, moduleName );

  // see if the module already exists
  const Module* existingModule = FindModule( moduleName );
  if( existingModule )
  {
    // printf(" using existing module %s \n",moduleName.c_str() );
    args.GetReturnValue().Set( existingModule->mExportsObject );
    return;
  }

  std::string path = mCurrentScriptPath;  // path of top level script being executed
  std::string contents;
  V8Utils::GetFileContents(path + fileName, contents);

  // wrap the module in a function to protect global namespace.
  // the create function itself is global so we make it unique for each module
  // For reference nodeJs does this as an anonymous function, but we're calling it from native side
  // so need to pass parameters  / get a name for it.
  std::string functionName ="__createModule" +  moduleName;
  std::string source = "function " + functionName + "( exports, module, __filename, __directory)  { ";
  source+= contents;
  source+=" \n };";  // close the function

  CompileAndRun( isolate, source, fileName );

  // We need to create module object, so that the module can read / write properties to it

  v8::Local<v8::Object> moduleObject = v8::Object::New( isolate );
  v8::Local<v8::Object> exportsObject = v8::Object::New( isolate );
  moduleObject->Set( v8::String::NewFromUtf8( isolate, "exports"),  exportsObject );
  moduleObject->Set( v8::String::NewFromUtf8( isolate, "id"), v8::String::NewFromUtf8( isolate ,moduleName.c_str() ) );

  // store the module exports object now, this is to allow for circular dependencies.
  // If this-module requires another module, which then requires this module ( creating a circle), it will be given an export object
  // which contains everything exported so far.
  Module* module = StoreModule( path, fileName, moduleName, isolate, exportsObject );

  v8::Local<v8::Context> currentContext =  isolate->GetCurrentContext();

  // get the CreateModule function
  v8::Local<v8::Function> createModule = v8::Local<v8::Function>::Cast(currentContext->Global()->Get(v8::String::NewFromUtf8( isolate, functionName.c_str() )));

  // add the arguments
  std::vector< v8::Local<v8::Value> > arguments;
  arguments.push_back( exportsObject );
  arguments.push_back( moduleObject );
  arguments.push_back( v8::String::NewFromUtf8( isolate, fileName.c_str() ));
  arguments.push_back( v8::String::NewFromUtf8( isolate, path.c_str() ));


  // call the CreateModule function
  createModule->Call( createModule, arguments.size(), &arguments[0]); //[0]

  // get the module.export object, the module writer may have re-assinged module.exports, so the exports object
  // no longer references it.
  v8::Local<v8::Value> moduleExportsValue = moduleObject->Get( v8::String::NewFromUtf8( isolate, "exports"));
  v8::Local<v8::Object>  moduleExports = moduleExportsValue->ToObject();

  // Re-store the export ( possible nothing happens, because exports hasn't been re-assigned).
  module->mExportsObject.Reset( isolate, moduleExports);

  args.GetReturnValue().Set( moduleExports );

}
Ejemplo n.º 4
0
Handle poly_dispatch_c(TaskData *taskData, Handle args, Handle code)
{
    unsigned c = get_C_unsigned(taskData, DEREFWORDHANDLE(code));
    switch (c)
    {
    case 1:
        return exportNative(taskData, args); // Export
    case 2:
        raise_syscall(taskData, "C Export has been withdrawn", 0);
        return 0;
    case 3:
        return exportPortable(taskData, args); // Export as portable format

    case 9: // Return the GIT version if appropriate
        {
             return SAVE(C_string_to_Poly(taskData, GitVersion));
        }

    case 10: // Return the RTS version string.
        {
            const char *version;
            switch (machineDependent->MachineArchitecture())
            {
            case MA_Interpreted:    version = "Portable-" TextVersion; break;
            case MA_I386:           version = "I386-" TextVersion; break;
            case MA_X86_64:         version = "X86_64-" TextVersion; break;
            default:                version = "Unknown-" TextVersion; break;
            }
            return SAVE(C_string_to_Poly(taskData, version));
        }

    case 11: // Return the RTS copyright string
        return SAVE(C_string_to_Poly(taskData, poly_runtime_system_copyright));

    case 12: // Return the architecture
        {
            const char *arch;
            switch (machineDependent->MachineArchitecture())
            {
            case MA_Interpreted:    arch = "Interpreted"; break;
            case MA_I386:           arch = "I386"; break;
            case MA_X86_64:         arch = "X86_64"; break;
            default:                arch = "Unknown"; break;
            }
            return SAVE(C_string_to_Poly(taskData, arch));
        }

    case 13: // Share common immutable data.
        {
            ShareData(taskData, args);
            return SAVE(TAGGED(0));
        }

        // ObjSize and ShowSize have their own IO vector entries but really they don't
        // need them.  Include them here and add ObjProfile.
    case 14:
        return ObjSize(taskData, args);

    case 15:
        return ShowSize(taskData, args);

    case 16:
        return ObjProfile(taskData, args);

    /* 17 and 18 are no longer used. */

    case 19: // Return the RTS argument help string.
        return SAVE(C_string_to_Poly(taskData, RTSArgHelp()));

    case 20: // Write a saved state file.
        return SaveState(taskData, args);

    case 21: // Load a saved state file and any ancestors.
        return LoadState(taskData, false, args);

    case 22: // Show the hierarchy.
        return ShowHierarchy(taskData);

    case 23: // Change the name of the immediate parent stored in a child
        return RenameParent(taskData, args);

    case 24: // Return the name of the immediate parent stored in a child
        return ShowParent(taskData, args);

    case 25: // Old statistics - now removed
    case 26:
        raise_exception_string(taskData, EXC_Fail, "No statistics available");

    case 27: // Get number of user statistics available
        return Make_arbitrary_precision(taskData, N_PS_USER);

    case 28: // Set an entry in the user stats table.
        {
            unsigned index = get_C_unsigned(taskData, DEREFHANDLE(args)->Get(0));
            if (index >= N_PS_USER)
                raise_exception0(taskData, EXC_subscript);
            POLYSIGNED value = getPolySigned(taskData, DEREFHANDLE(args)->Get(1));
            globalStats.setUserCounter(index, value);
            Make_arbitrary_precision(taskData, 0);
        }

    case 29: // Get local statistics.
        return globalStats.getLocalStatistics(taskData);

    case 30: // Get remote statistics.  The argument is the process ID to get the statistics.
        return globalStats.getRemoteStatistics(taskData, getPolyUnsigned(taskData, DEREFHANDLE(args)));

    case 31: // Store a module
        return StoreModule(taskData, args);

    case 32: // Load a module
        return LoadModule(taskData, args);

    case 33: // Load hierarchy.  This provides a complete list of children and parents.
        return LoadState(taskData, true, args);

    case 34: // Return the system directory for modules.  This is configured differently
        // in Unix and in Windows.
#if (defined(MODULEDIR))
    return SAVE(C_string_to_Poly(taskData, Xstr(MODULEDIR)));
#elif (defined(_WIN32) && ! defined(__CYGWIN__))
        {
            // This registry key is configured when Poly/ML is installed using the installer.
            // It gives the path to the Poly/ML installation directory.  We return the
            // Modules subdirectory.
            HKEY hk;
            if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
                    _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\PolyML.exe"), 0,
                    KEY_QUERY_VALUE, &hk) == ERROR_SUCCESS)
            {
                DWORD valSize;
                if (RegQueryValueEx(hk, _T("Path"), 0, NULL, NULL, &valSize) == ERROR_SUCCESS)
                {
#define MODULEDIR _T("Modules")
                    TempString buff((TCHAR*)malloc(valSize + (_tcslen(MODULEDIR) + 1)*sizeof(TCHAR)));
                    DWORD dwType;
                    if (RegQueryValueEx(hk, _T("Path"), 0, &dwType, (LPBYTE)(LPTSTR)buff, &valSize) == ERROR_SUCCESS)
                    {
                        RegCloseKey(hk);
                        // The registry entry should end with a backslash.
                        _tcscat(buff, MODULEDIR);
                        return SAVE(C_string_to_Poly(taskData, buff));
                    }
                }
                RegCloseKey(hk);
            }
            return SAVE(C_string_to_Poly(taskData, ""));
        }
#else
        return SAVE(C_string_to_Poly(taskData, ""));
#endif

    case 50: // GCD
        return gcd_arbitrary(taskData, SAVE(DEREFHANDLE(args)->Get(0)), SAVE(DEREFHANDLE(args)->Get(1)));
    case 51: // LCM
        return lcm_arbitrary(taskData, SAVE(DEREFHANDLE(args)->Get(0)), SAVE(DEREFHANDLE(args)->Get(1)));

        // These next ones were originally in process_env and have now been moved here,
    case 100: /* Return the maximum word segment size. */
            return taskData->saveVec.push(TAGGED(MAX_OBJECT_SIZE));
    case 101: /* Return the maximum string size (in bytes).
                 It is the maximum number of bytes in a segment
                 less one word for the length field. */
            return taskData->saveVec.push(TAGGED((MAX_OBJECT_SIZE)*sizeof(PolyWord) - sizeof(PolyWord)));
    case 102: /* Test whether the supplied address is in the io area.
                 This was previously done by having get_flags return
                 256 but this was changed so that get_flags simply
                 returns the top byte of the length word. */
        {
            PolyWord *pt = (PolyWord*)DEREFWORDHANDLE(args);
            if (gMem.IsIOPointer(pt))
                return Make_arbitrary_precision(taskData, 1);
            else return Make_arbitrary_precision(taskData, 0);
        }
    case 103: /* Return the register mask for the given function.
                 This is used by the code-generator to find out
                 which registers are modified by the function and
                 so need to be saved if they are used by the caller. */
        {
            PolyObject *pt = DEREFWORDHANDLE(args);
            if (gMem.IsIOPointer(pt))
            {
                /* IO area.  We need to get this from the vector. */
                int i;
                for (i=0; i < POLY_SYS_vecsize; i++)
                {
                    if (pt == (PolyObject*)IoEntry(i))
                    {
                        int regMask = taskData->GetIOFunctionRegisterMask(i);
                        POLYUNSIGNED props = rtsProperties(taskData, i);
                        return taskData->saveVec.push(TAGGED(regMask | props));
                    }
                }
                raise_exception_string(taskData, EXC_Fail, "Io pointer not found");
            }
            else
            {
                /* We may have a pointer to the code or a pointer to
                   a closure.  If it's a closure we have to find the
                   code. */
                if (! pt->IsCodeObject() && ! pt->IsByteObject())
                    pt = pt->Get(0).AsObjPtr();

                /* Should now be a code object. */
                if (pt->IsCodeObject())
                {
                    /* Compiled code.  This is the second constant in the
                       constant area. */
                    PolyWord *codePt = pt->ConstPtrForCode();
                    PolyWord mask = codePt[1];
                    // A real mask will be an integer.
                    if (IS_INT(mask)) return SAVE(mask);
                    else raise_exception_string(taskData, EXC_Fail, "Invalid mask");
                }
                else raise_exception_string(taskData, EXC_Fail, "Not a code pointer");
            }
        }

    case 104: return Make_arbitrary_precision(taskData, POLY_version_number);

    case 105: /* Get the name of the function. */
        {
            PolyObject *pt = DEREFWORDHANDLE(args);
            if (gMem.IsIOPointer(pt))
            {
                /* IO area. */
                int i;
                for (i=0; i < POLY_SYS_vecsize; i++)
                {
                    if (pt == (PolyObject*)IoEntry(i))
                    {
                        char buff[8];
                        sprintf(buff, "RTS%d", i);
                        return SAVE(C_string_to_Poly(taskData, buff));
                    }
                }
                raise_syscall(taskData, "Io pointer not found", 0);
            }
            else if (pt->IsCodeObject()) /* Should now be a code object. */ 
            {
                /* Compiled code.  This is the first constant in the constant area. */
                PolyWord *codePt = pt->ConstPtrForCode();
                PolyWord name = codePt[0];
                /* May be zero indicating an anonymous segment - return null string. */
                if (name == PolyWord::FromUnsigned(0))
                    return SAVE(C_string_to_Poly(taskData, ""));
                else return SAVE(name);
            }
            else raise_syscall(taskData, "Not a code pointer", 0);
        }

    default:
        {
            char msg[100];
            sprintf(msg, "Unknown poly-specific function: %d", c);
            raise_exception_string(taskData, EXC_Fail, msg);
            return 0;
        }
    }
}