Ejemplo n.º 1
0
    void DictImpl::decodeJSON( JSON::Entity const &entity, void *data ) const
    {
      entity.requireObject();

      RC::ConstHandle<StringImpl> keyImplAsStringImpl;
      if ( isString( m_keyImpl->getType() ) )
        keyImplAsStringImpl = RC::ConstHandle<StringImpl>::StaticCast( m_keyImpl );
      
      disposeData( data );
      memset( data, 0, sizeof(bits_t *) );
        
      void *keyData = alloca( m_keySize );
      m_keyImpl->initializeData( m_keyImpl->getDefaultData(), keyData );
      JSON::ObjectDecoder jsonObjectDecoder( entity );
      JSON::Entity keyString, valueEntity;
      while ( jsonObjectDecoder.getNext( keyString, valueEntity ) )
      {
        if ( keyImplAsStringImpl )
        {
          keyString.stringGetData( StringImpl::GetMutableValueData( keyData, keyString.stringLength() ) );
        }
        else
        {
          char *mutableData;
          char const *data;
          if ( keyString.stringIsShort() )
            data = keyString.stringShortData();
          else
          {
            mutableData = reinterpret_cast<char *>( alloca( keyString.stringLength() ) );
            keyString.stringGetData( mutableData );
            data = mutableData;
          }
          
          JSON::Decoder jsonDecoder( data, keyString.value.string.length );
          JSON::Entity jsonDecodedEntity;
          if ( !jsonDecoder.getNext( jsonDecodedEntity ) )
            throw Exception( "invalid JSON key" );
          m_keyImpl->decodeJSON( jsonDecodedEntity, keyData );
          if ( jsonDecoder.getNext( jsonDecodedEntity ) )
            throw Exception( "invalid JSON key" );
        }
        
        void *valueData = getMutable( data, keyData );
        m_valueImpl->decodeJSON( valueEntity, valueData );
      }
      m_keyImpl->disposeData( keyData );
    }
Ejemplo n.º 2
0
    Inst::Inst(
      RC::ConstHandle<IO::Dir> const &extensionDir,
      std::string const &extensionName,
      std::string const &jsonDesc,
      std::vector<std::string> const &pluginDirs,
      RC::Handle<CG::Manager> const &cgManager,
      EDK::Callbacks const &callbacks,
      std::map< std::string, void (*)( void * ) > &implNameToDestructorMap
      )
      : m_name( extensionName )
      , m_jsonDesc( jsonDesc )
    {
      try
      {
        JSON::Decoder jsonDecode( jsonDesc.data(), jsonDesc.length() );
        JSON::Entity jsonEntity;
        if ( !jsonDecode.getNext( jsonEntity ) )
          throw Exception( "missing JSON entity" );
        jsonEntity.requireObject();
        m_desc = parseDesc( jsonEntity );
        if ( jsonDecode.getNext( jsonEntity ) )
          throw Exception( "extra JSON entity" );
      }
      catch ( Exception e )
      {
        throw "JSON description: " + e;
      }
      
      /*
      m_fabricLIBObject = LIB::NakedObject::Create();
      m_fabricLIBObject->set( "hostTriple", LIB::ReferencedString::Create( Util::getHostTriple() ) );
      m_fabricLIBObject->set( "DependencyGraph", LIBDG::Namespace::Create( dgContext ) );
      */
      std::vector< std::string > libs;
      m_desc.libs.appendMatching( Util::getHostTriple(), libs );
      std::string libSuffix = "-" + std::string(buildOS) + "-" + std::string(buildArch);
      
      for ( size_t i=0; i<libs.size(); ++i )
      {
        std::string resolvedName;
        SOLibHandle soLibHandle = SOLibOpen( libs[i]+libSuffix, resolvedName, false, pluginDirs );
        m_resolvedNameToSOLibHandleMap.insert( ResolvedNameToSOLibHandleMap::value_type( resolvedName, soLibHandle ) );
        m_orderedSOLibHandles.push_back( soLibHandle );
      }

      if ( !m_orderedSOLibHandles.empty() )
      {
        void *resolvedFabricEDKInitFunction = 0;
        for ( size_t i=0; i<m_orderedSOLibHandles.size(); ++i )
        {
          resolvedFabricEDKInitFunction = SOLibResolve( m_orderedSOLibHandles[i], "FabricEDKInit" );
          if ( resolvedFabricEDKInitFunction )
            break;
        }
        if ( !resolvedFabricEDKInitFunction )
          throw Exception( "error: extension doesn't implement function FabricEDKInit through macro IMPLEMENT_FABRIC_EDK_ENTRIES" );

        ( *( FabricEDKInitPtr )resolvedFabricEDKInitFunction )( callbacks );
      }
      
      for ( size_t i=0; i<m_orderedSOLibHandles.size(); ++i )
      {
        /*
        OnLoadFn onLoadFn = (OnLoadFn)SOLibResolve( m_orderedSOLibHandles[i], "FabricOnLoad" );
        if ( onLoadFn )
          onLoadFn( SDK::Value::Bind( m_fabricLIBObject ) );
        */
      }
      
      /*
      for ( size_t i=0; i<m_desc.interface.methods.size(); ++i )
      {
        std::string const &methodName = m_desc.interface.methods[i];
        Method method = 0;
        for ( size_t j=0; j<m_orderedSOLibHandles.size(); ++j )
        {
          SOLibHandle soLibHandle = m_orderedSOLibHandles[j];
          method = (Method)SOLibResolve( soLibHandle, methodName );
          if ( method )
            break;
        }
        if ( !method )
          throw Exception( "method "+_(methodName)+" not found" );
        m_methodMap.insert( MethodMap::value_type( methodName, method ) );
      }
      */
      
      
      std::vector<std::string> codeFiles;
      m_desc.code.appendMatching( Util::getHostTriple(), codeFiles );
      std::string filename;
      m_code = "";
      for ( std::vector<std::string>::const_iterator it=codeFiles.begin(); it!=codeFiles.end(); ++it )
      {
        std::string const &codeEntry = *it;
        
        if ( filename.empty() )
          filename = codeEntry;
          
        std::string code;
        try
        {
          code = extensionDir->getFileContents( codeEntry );
        }
        catch ( Exception e )
        {
          throw _(codeEntry) + ": " + e;
        }
        m_code += code + "\n";
      }
      
      RC::ConstHandle<KL::Source> source = KL::StringSource::Create( filename, m_code );
      RC::Handle<KL::Scanner> scanner = KL::Scanner::Create( source );
      m_ast = KL::Parse( scanner, m_diagnostics );
      if ( !m_diagnostics.containsError() )
        m_ast->registerTypes( cgManager, m_diagnostics );
      for ( CG::Diagnostics::const_iterator it=m_diagnostics.begin(); it!=m_diagnostics.end(); ++it )
      {
        CG::Location const &location = it->first;
        CG::Diagnostic const &diagnostic = it->second;
        FABRIC_LOG( "[%s] %s:%u:%u: %s: %s", extensionName.c_str(), location.getFilename()->c_str(), (unsigned)location.getLine(), (unsigned)location.getColumn(), diagnostic.getLevelDesc(), diagnostic.getDesc().c_str() );
      }
      if ( m_diagnostics.containsError() )
        throw Exception( "KL compile failed" );
      
      std::vector< RC::ConstHandle<AST::FunctionBase> > functionBases;
      m_ast->collectFunctionBases( functionBases );
      for ( std::vector< RC::ConstHandle<AST::FunctionBase> >::const_iterator it=functionBases.begin(); it!=functionBases.end(); ++it )
      {
        RC::ConstHandle<AST::FunctionBase> const &functionBase = *it;
        
        if ( !functionBase->getBody() )
        {
          std::string symbolName = functionBase->getSymbolName( cgManager );
          void *resolvedFunction = 0;
          for ( size_t i=0; i<m_orderedSOLibHandles.size(); ++i )
          {
            resolvedFunction = SOLibResolve( m_orderedSOLibHandles[i], symbolName );
            if ( resolvedFunction )
              break;
          }
          if ( !resolvedFunction )
            throw Exception( "error: symbol " + _(symbolName) + ", prototyped in KL, not found in native code" );
          m_externalFunctionMap.insert( ExternalFunctionMap::value_type( symbolName, resolvedFunction ) );
          
          if ( functionBase->isDestructor() )
          {
            RC::ConstHandle<AST::Destructor> destructor = RC::ConstHandle<AST::Destructor>::StaticCast( functionBase );
            std::string thisTypeName = destructor->getThisTypeName();
            implNameToDestructorMap[thisTypeName] = (void (*)( void * )) resolvedFunction;
          }
        }
      }

      m_jsConstants = m_desc.jsConstants.concatMatching( Util::getHostTriple() );
    }