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 ); }
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() ); }