void AdvancedCompilerOptionsDlg::OnRegexTest(wxCommandEvent& WXUNUSED(event))
{
    if (m_SelectedRegex == -1)
        return;
    wxString text = XRCCTRL(*this, "txtRegexTest", wxTextCtrl)->GetValue();
    if (text.IsEmpty())
    {
        cbMessageBox(_("Please enter a compiler line in the \"Compiler output\" text box..."), _("Error"), wxICON_ERROR, this);
        return;
    }

    Compiler* compiler = CompilerFactory::GetCompiler(m_CompilerId);
    if (!compiler)
        return;

    // backup regexes
    RegExArray regex_copy = m_Regexes;
    SaveRegexDetails(m_SelectedRegex);

    // test-run
    compiler->SetRegExArray(m_Regexes);
    CompilerLineType clt = compiler->CheckForWarningsAndErrors(text);

    // restore regexes
    compiler->SetRegExArray(regex_copy);
    m_Regexes = regex_copy;

    wxString msg;
    msg.Printf(_("Regular expression analyzed as follows:\n\n"
                 "Type: %s message\n"
                 "Filename: %s\n"
                 "Line number: %s\n"
                 "Message: %s"),
                    clt == cltNormal ? _("Normal")
                 : (clt == cltInfo   ? _("Info")
                 : (clt == cltError  ? _("Error") : _("Warning") ) ),
                compiler->GetLastErrorFilename().wx_str(),
                compiler->GetLastErrorLine().wx_str(),
                compiler->GetLastError().wx_str()
              );

    cbMessageBox(msg, _("Test results"), wxICON_INFORMATION, this);
}
Exemple #2
0
Compiler::value NumberSTD::pow_mpz_mpz(Compiler& c, std::vector<Compiler::value> args) {
	auto r = [&]() {
		if (args[0].t.temporary) return args[0];
		if (args[1].t.temporary) return args[1];
		return c.new_mpz();
	}();
	auto r_addr = c.insn_address_of(r);
	auto a = c.insn_address_of(args[0]);
	auto b = c.insn_address_of(args[1]);
	auto p = c.insn_call(Type::LONG, {b}, &mpz_get_ui);
	c.insn_call(Type::VOID, {r_addr, a, p}, &mpz_pow_ui);
	if (args[1].t.temporary && args[1] != r) {
		c.insn_delete_mpz(args[1]);
	}
	return r;
}
Exemple #3
0
Compiler::value NumberSTD::sub_mpz_int(Compiler& c, std::vector<Compiler::value> args) {
	auto a = c.insn_address_of(args[0]);
	auto b = args[1];
	auto r = c.new_mpz();
	auto r_addr = c.insn_address_of(r);

	jit_label_t label_end = jit_label_undefined;
	jit_label_t label_else = jit_label_undefined;

	auto cond = c.insn_lt(b, c.new_integer(0));
	jit_insn_branch_if_not(c.F, cond.v, &label_else);

	Compiler::value neg_b = {jit_insn_neg(c.F, b.v), Type::INTEGER};
	c.insn_call(Type::VOID, {r_addr, a, neg_b}, &mpz_add_ui);
	jit_insn_branch(c.F, &label_end);

	jit_insn_label(c.F, &label_else);
	c.insn_call(Type::VOID, {r_addr, a, b}, &mpz_sub_ui);
	jit_insn_label(c.F, &label_end);
	if (args[0].t.temporary) {
		c.insn_delete_mpz(args[0]);
	}
	return r;
}
Exemple #4
0
void PrintReturnStack() {
    *rstack_top++ = (Value)pc;
    Value *rstack_cur = rstack_top;
    while (rstack_bottom < rstack_cur) {
	Value *v = (Value *)*--rstack_cur;
	if (v == 0) {
	    std::cout << "  <repl>";
	} else {
	    std::string name = compiler.name_for_value((Value *)*v);
	    if (!name.empty()) {
		if ((*v & 3) == 3) {
		    std::cout << "  <prim:" << name << ">";
		} else {
		    std::cout << "  " << name;
		}
	    } else {
		std::cout << "  <clause:" << v << ">";
	    }
	}
	std::cout << " (" << v << ")" << std::endl;
    }
    rstack_top--;
}
Exemple #5
0
void Project :: compile(ident_t filePath, Compiler& compiler, Parser& parser, ModuleInfo& moduleInfo, Unresolveds& unresolved)
{
   try {
      // based on the target type generate the syntax tree for the file
      Path fullPath(StrSetting(_ELENA_::opProjectPath));
      fullPath.combine(filePath);

      // parse
      TextFileReader sourceFile(fullPath.c_str(), getDefaultEncoding(), true);
      if (!sourceFile.isOpened())
         raiseError(errInvalidFile, filePath);

      SyntaxTree tree;
      DerivationWriter writer(tree);
      parser.parse(&sourceFile, writer, getTabSize());

      // compile the syntax tree
      compiler.compileModule(*this, filePath, tree.readRoot(), moduleInfo, unresolved);
   }
   catch (LineTooLong& e)
   {
      raiseError(errLineTooLong, filePath, e.row, 1);
   }
   catch (InvalidChar& e)
   {
      size_t destLength = 6;

      _ELENA_::String<char, 6> symbol;
      _ELENA_::Convertor::copy(symbol, (_ELENA_::unic_c*)&e.ch, 1, destLength);

      raiseError(errInvalidChar, filePath, e.row, e.column, (const char*)symbol);
   }
   catch (SyntaxError& e)
   {
      raiseError(e.error, filePath, e.row, e.column, e.token);
   }
}
Exemple #6
0
void Project :: compile(ident_t filePath, Compiler& compiler, ScriptParser parser, ModuleInfo& moduleInfo, Unresolveds& unresolved)
{
   try {
      // based on the target type generate the syntax tree for the file
      Path fullPath(StrSetting(_ELENA_::opProjectPath));
      fullPath.combine(filePath);

      // parse
      SyntaxTree tree;
      parser.parse(fullPath.c_str(), tree/*, getTabSize()*/);

      // compile the syntax tree
      compiler.compileModule(*this, filePath, tree.readRoot(), moduleInfo, unresolved);
   }
   catch (LineTooLong& e)
   {
      raiseError(errLineTooLong, filePath, e.row, 1);
   }
   catch (InvalidChar& e)
   {
      size_t destLength = 6;

      _ELENA_::String<char, 6> symbol;
      _ELENA_::Convertor::copy(symbol, (_ELENA_::unic_c*)&e.ch, 1, destLength);

      raiseError(errInvalidChar, filePath, e.row, e.column, (const char*)symbol);
   }
   catch (SyntaxError& e)
   {
      raiseError(e.error, filePath, e.row, e.column, e.token);
   }
   catch (ScriptError& e)
   {
      raiseError(e.error, filePath);
   }
}
AutoDetectResult CompilerICC::AutoDetectInstallationDir()
{
    wxString sep = wxFileName::GetPathSeparator();
    wxString extraDir = _T("");
    if (platform::windows)
    {
        if (wxDirExists(_T("C:\\Program Files\\Intel\\Compiler")))
        {
            wxDir icc_dir(_T("C:\\Program Files\\Intel\\Compiler\\C++"));
            if (icc_dir.IsOpened())
            {
                wxArrayString dirs;
                wxIccDirTraverser IccDirTraverser(dirs);
                icc_dir.Traverse(IccDirTraverser);
                if (!dirs.IsEmpty())
                {
                    // Now sort the array in reverse order to get the latest version's path
                    dirs.Sort(true);
                    m_MasterPath = dirs[0];
                    m_MasterPath.Append(_T("\\IA32"));

                    // Now check for the installation of MSVC
                    const wxString msvcIds[4] = { _T("msvc6"),
                                                  _T("msvctk"),
                                                  _T("msvc8"),
                                                  _T("msvc10") };

                    bool msvcFound = false;
                    for (unsigned int which_msvc = 0; which_msvc < array_size(msvcIds); ++which_msvc)
                    {
                        Compiler* vcComp = CompilerFactory::GetCompiler(msvcIds[which_msvc]);
                        if (vcComp)
                        {
                            if (vcComp->AutoDetectInstallationDir() == adrDetected)
                            {
                                const wxString& vcMasterPath = vcComp->GetMasterPath();
                                if (m_ExtraPaths.Index(vcMasterPath) == wxNOT_FOUND &&
                                    wxDirExists(vcMasterPath))
                                {
                                    m_ExtraPaths.Add(vcMasterPath);
                                }
                                AddIncludeDir(vcMasterPath + _T("\\Include"));
                                AddLibDir(vcMasterPath + _T("\\Lib"));
                                AddResourceIncludeDir(vcMasterPath + _T("\\Include"));

                                const wxArrayString& vcExtraPaths = vcComp->GetExtraPaths();
                                for (size_t i = 0; i < vcExtraPaths.GetCount(); ++i)
                                {
                                    if (m_ExtraPaths.Index(vcExtraPaths[i]) == wxNOT_FOUND &&
                                        wxDirExists(vcExtraPaths[i]))
                                    {
                                        m_ExtraPaths.Add(vcExtraPaths[i]);
                                    }
                                }
                                const wxArrayString& vcIncludeDirs = vcComp->GetIncludeDirs();
                                for (size_t i = 0; i < vcIncludeDirs.GetCount(); ++i)
                                {
                                    if (wxDirExists(vcIncludeDirs[i]))
                                    {
                                        if (m_IncludeDirs.Index(vcIncludeDirs[i]) == wxNOT_FOUND)
                                        {
                                            AddIncludeDir(vcIncludeDirs[i]);
                                        }
                                        if (m_ResIncludeDirs.Index(vcIncludeDirs[i]) == wxNOT_FOUND)
                                        {
                                            AddResourceIncludeDir(vcIncludeDirs[i]);
                                        }
                                    }
                                }
                                const wxArrayString& vcLibDirs = vcComp->GetLibDirs();
                                for (size_t i = 0; i < vcLibDirs.GetCount(); ++i)
                                {
                                    if (m_LibDirs.Index(vcLibDirs[i]) == wxNOT_FOUND &&
                                        wxDirExists(vcLibDirs[i]))
                                    {
                                        AddLibDir(vcLibDirs[i]);
                                    }
                                }
                                msvcFound = true;
                                break;
                            }
                        }
                    }

                    if (!msvcFound)
                    {
                        cbMessageBox(_T("It seems your computer doesn't have a working MSVC compiler.\n\n"
                                        "This compiler requires MS compiler for proper functioning and\n"
                                        "it may not work without it."),
                                     _T("Error"), wxOK | wxICON_ERROR);

                    }
                }
            }
        }

        // Read the ICPP_COMPILER90 environment variable
        wxGetEnv(_T("ICPP_COMPILER90"), &m_MasterPath);
        extraDir = sep + _T("IA32");// Intel also provides compiler for Itanium processors

        if (m_MasterPath.IsEmpty())
        {
            // just a guess the default installation dir
            wxString Programs = _T("C:\\Program Files");
            // what's the "Program Files" location
            // TO DO : support 64 bit ->    32 bit apps are in "ProgramFiles(x86)"
            //                              64 bit apps are in "ProgramFiles"
            wxGetEnv(_T("ProgramFiles"), &Programs);
            m_MasterPath = Programs + _T("\\Intel\\Compiler\\C++\\9.0");
        }
    }
    else
    {
        m_MasterPath = _T("/opt/intel/cc/9.0");
        if (wxDirExists(_T("/opt/intel")))
        {
            wxDir icc_dir(_T("/opt/intel/cc"));
            if (icc_dir.IsOpened())
            {
                wxArrayString dirs;
                wxIccDirTraverser IccDirTraverser(dirs);
                icc_dir.Traverse(IccDirTraverser);
                if (!dirs.IsEmpty())
                {
                    // Now sort the array in reverse order to get the latest version's path
                    dirs.Sort(true);
                    m_MasterPath = dirs[0];
                }
            }
        }
    }

    AutoDetectResult ret = wxFileExists(m_MasterPath + sep + _T("bin") + sep + m_Programs.C) ? adrDetected : adrGuessed;
    if (ret == adrDetected)
    {
        m_IncludeDirs.Insert(m_MasterPath + sep + _T("Include"), 0);
        m_LibDirs.Insert(m_MasterPath + sep + _T("Lib"), 0);
        m_ResIncludeDirs.Insert(m_MasterPath + sep + _T("Include"), 0);
    }
    // Try to detect the debugger. If not detected successfully the debugger plugin will
    // complain, so only the autodetection of compiler is considered in return value
    wxString path;
    wxString dbg;
    if (platform::windows)
    {
        dbg = _T("idb.exe");
        wxGetEnv(_T("IDB_PATH"), &path);
        path += _T("IDB\\9.0\\IA32");
    }
    else
    {
        dbg = _T("idb");
        path= _T("/opt/intel/idb/9.0");
        if (wxDirExists(_T("/opt/intel")))
        {
            wxDir icc_debug_dir(_T("/opt/intel/idb"));
            if (icc_debug_dir.IsOpened())
            {
                wxArrayString debug_dirs;
                wxIccDirTraverser IccDebugDirTraverser(debug_dirs);
                icc_debug_dir.Traverse(IccDebugDirTraverser);
                if (!debug_dirs.IsEmpty())
                {
                    // Now sort the array in reverse order to get the latest version's path
                    debug_dirs.Sort(true);
                    path = debug_dirs[0];
                }
            }
        }
    }

    if (wxFileExists(path + sep + _T("bin") + sep + dbg))
        m_ExtraPaths.Add(path);

    return ret;
}
Exemple #8
0
Compiler::value If::compile(Compiler& c) const {

	auto label_then = c.insn_init_label("then");
	auto label_else = c.insn_init_label("else");
	auto label_end = c.insn_init_label("end");
	Compiler::value then_v;
	Compiler::value else_v;

	auto cond = condition->compile(c);
	condition->compile_end(c);
	auto cond_boolean = c.insn_to_bool(cond);
	c.insn_delete_temporary(cond);
	c.insn_if_new(cond_boolean, &label_then, &label_else);

	c.insn_label(&label_then);

	then_v = c.insn_convert(then->compile(c), type.fold());
	if (!then_v.v) then_v = c.insn_convert(c.new_null(), type.fold());
	then->compile_end(c);

	c.insn_branch(&label_end);
	label_then.block = Compiler::builder.GetInsertBlock();

	c.insn_label(&label_else);

	if (elze != nullptr) {
		else_v = c.insn_convert(elze->compile(c), type.fold());
		elze->compile_end(c);
	} else {
		else_v = c.insn_convert(c.new_null(), type.fold());
	}

	c.insn_branch(&label_end);
	label_else.block = Compiler::builder.GetInsertBlock();

	c.insn_label(&label_end);
	
	if (type.is_void()) {
		return {};
	} else {
		return c.insn_phi(type, then_v, label_then, else_v, label_else);
	}
}
Exemple #9
0
/*
ipfc 1.0 flags are:
    /INF -- generate an *.inf file
    /S ---- suppress search table generation
    /X ---- generate cross-reference list
    /Wn --- warning level n
    /COUNTRY=nnn
    /CODEPAGE=nnn
    /LANGUAGE=XYZse
ipfc 2.0 flags are:
    -i ------- generate an *.inf file
    -s ------- suppress search table generation
    -x ------- generate cross-reference list
    -Wn ------ set warning level
    -d:nnn --- set 3 digit country code
    -c:nnnn -- set 4 digit code page
    -l:xyz  -- set 3 letter language identifier
    -X:? ----- help on option '?'

We support the version 2 flags
*/
static void processCommandLine(int argc, char **argv, Compiler& c)
{
    if (argc < 2)
        usage();
    int inIndex( 0 );
    int outIndex( 0 );
    bool info( false );
    for( int count = 1; count < argc; ++count ) {
#ifdef __UNIX__
        if( argv[count][0] == '-' ) {
#else
        if( argv[count][0] == '-' || argv[count][0] == '/' ) {
#endif
            switch( argv[count][1] ) {
                case 'C':
                case 'c':
                case 'd':
                    std::cout << "Country code and code page selection are not supported." << std::endl;
                    std::cout << "Use the 'l' option to select a localization file instead." << std::endl;
                    if (argv[count][2] == '?')
                        info = true;
                    break;
                case 'I':
                case 'i':
                    c.setOutputType( Compiler::INF );
                    break;
                case 'L':
                case 'l':
                    if (argv[count][2] == '?') {
                        std::cout << "xx_YY is the root name of a localization file" << std::endl;
                        std::cout << "with the full name xx_YY.nls\nSee en_US.nls for an example." << std::endl;
                        info = true;
                    }
                    else
                        c.setLocalization( argv[++count] );
                    break;
                case 'O':
                case 'o':
                    outIndex = ++count;
                    break;
                case 'Q':
                case 'q':
                    c.noBanner();
                    break;
                case 'S':
                case 's':
                    c.noSearch();
                    break;
                case 'w':
                case 'W':
                    if (argv[count][2] == '?') {
                        std::cout << "-wN where N is one of 1, 2, or 3" << std::endl;
                        info = true;
                    }
                    else
                        c.setWarningLevel( std::atoi( argv[count] + 2 ));
                    break;
                case 'X':
                case 'x':
                    c.setXRef( true );
                    break;
                default:
                    usage();
                    break;
            }
        }
        else if( !inIndex )
            inIndex = count;
        else
            std::cout << "Warning: extra filename '" << argv[count] << "' will be ignored" << std::endl;
    }
    if( inIndex ) {
        std::string fullpath( canonicalPath( argv[ inIndex ] ) );
        c.setInputFile( fullpath );
        if( !outIndex ) {
            std::string outFile( fullpath );
            outFile.erase( outFile.rfind( '.' ) );
            if( c.outputType() == Compiler::INF )
                outFile += ".inf";
            else
                outFile += ".hlp";
            c.setOutputFile( outFile );
        }
    }
    else {
        std::cout << "Fatal Error: You must specify an input file" << std::endl;
        std::exit( EXIT_FAILURE );
    }
    if( outIndex ) {
        std::string fullpath( canonicalPath( argv[ outIndex ] ) );
        c.setOutputFile( fullpath );
    }
    if( info )
        std::exit( EXIT_SUCCESS );
}
/*****************************************************************************/
static void usage()
{
    printBanner();
    std::cout << "Usage:" << std::endl;
    std::cout << "wipfc [-switches] [-options] infile [outfile]" << std::endl;
    std::cout << std::endl;
    std::cout << "Switches" << std::endl;
    std::cout << "-i  generate outfile.inf instead of outfile.hlp" << std::endl;
    std::cout << "-s  do not generate full text search tables" << std::endl;
    std::cout << "-x  generate and display cross-reference list" << std::endl;
    std::cout <<  std::endl;
    std::cout << "Options\n" << std::endl;
    std::cout << "-l xx_YY localization code (default: en_US)" << std::endl;
    std::cout << "-o name  set the output file path, name and extension" << std::endl;
    std::cout << "-q       operate quietly" << std::endl;
    std::cout << "-wn      1 digit warning level  (default: 3)" << std::endl;
    std::cout << "-X?      display help on option X" << std::endl;
    std::exit( EXIT_FAILURE );
}
Exemple #10
0
AutoDetectResult CompilerICC::AutoDetectInstallationDir()
{
    wxString sep = wxFileName::GetPathSeparator();

    if (platform::windows)
    {
        if ( wxDirExists(_T("C:\\Program Files\\Intel\\Compiler")) )
        {
            wxDir icc_dir(_T("C:\\Program Files\\Intel\\Compiler\\C++"));
            if (icc_dir.IsOpened())
            {
                wxArrayString dirs;
                wxIccDirTraverser IccDirTraverser(dirs);
                icc_dir.Traverse(IccDirTraverser);
                if (!dirs.IsEmpty())
                {
                    // Now sort the array in reverse order to get the latest version's path
                    dirs.Sort(true);
                    m_MasterPath = dirs[0];
                    m_MasterPath.Append(_T("\\IA32"));
                }
            }
        }

        int version = 0;
        while ( m_MasterPath.IsEmpty() || !wxDirExists(m_MasterPath) )
        {
            wxString iccEnvVar;
            if (version==0)
            {
                // Try default w/o version number
                iccEnvVar = _T("ICPP_COMPILER");
                version = 8;
            }
            else if (version>15)
                break;  // exit while-loop
            else
            {
                // Try ICPP_COMPILER80 ... ICPP_COMPILER12
                iccEnvVar.Printf(wxT("ICPP_COMPILER%d0"), version);
                version++;
            }

            // Read the ICPP_COMPILER[XX] environment variable
            if ( !wxGetEnv(iccEnvVar, &m_MasterPath) )
                m_MasterPath.Clear();
        }

        // Now check for the installation of MSVC
        const wxString msvcIds[4] = { _T("msvc6"),
                                      _T("msvctk"),
                                      _T("msvc8"),
                                      _T("msvc10") };
        bool msvcFound = false;
        for (unsigned int which_msvc = 0; which_msvc < array_size(msvcIds); ++which_msvc)
        {
            Compiler* vcComp = CompilerFactory::GetCompiler(msvcIds[which_msvc]);
            if (!vcComp)
                continue; // compiler not registered? try next one

            wxString vcMasterNoMacros = vcComp->GetMasterPath();
            Manager::Get()->GetMacrosManager()->ReplaceMacros(vcMasterNoMacros);
            if (   !wxFileExists(vcMasterNoMacros + sep + wxT("bin") + sep + vcComp->GetPrograms().C)
                && !wxFileExists(vcMasterNoMacros + sep + vcComp->GetPrograms().C) )
                continue; // this MSVC is not installed; try next one

            const wxString& vcMasterPath = vcComp->GetMasterPath();
            if (m_ExtraPaths.Index(vcMasterPath) == wxNOT_FOUND)
                m_ExtraPaths.Add(vcMasterPath);
            if (  !vcMasterPath.EndsWith(wxT("bin"))
                && m_ExtraPaths.Index(vcMasterPath + sep + wxT("bin")) == wxNOT_FOUND )
            {
                m_ExtraPaths.Add(vcMasterPath + sep + wxT("bin"));
            }
            AddIncludeDir(vcMasterPath + _T("\\Include"));
            AddLibDir(vcMasterPath + _T("\\Lib"));
            AddResourceIncludeDir(vcMasterPath + _T("\\Include"));

            const wxArrayString& vcExtraPaths = vcComp->GetExtraPaths();
            for (size_t i = 0; i < vcExtraPaths.GetCount(); ++i)
            {
                if (   m_ExtraPaths.Index(vcExtraPaths[i]) == wxNOT_FOUND
                    && wxDirExists(vcExtraPaths[i]) )
                {
                    m_ExtraPaths.Add(vcExtraPaths[i]);
                }
            }
            const wxArrayString& vcIncludeDirs = vcComp->GetIncludeDirs();
            for (size_t i = 0; i < vcIncludeDirs.GetCount(); ++i)
            {
                if (wxDirExists(vcIncludeDirs[i]))
                {
                    if (m_IncludeDirs.Index(vcIncludeDirs[i]) == wxNOT_FOUND)
                        AddIncludeDir(vcIncludeDirs[i]);

                    if (m_ResIncludeDirs.Index(vcIncludeDirs[i]) == wxNOT_FOUND)
                        AddResourceIncludeDir(vcIncludeDirs[i]);
                }
            }
            const wxArrayString& vcLibDirs = vcComp->GetLibDirs();
            for (size_t i = 0; i < vcLibDirs.GetCount(); ++i)
            {
                if (   m_LibDirs.Index(vcLibDirs[i]) == wxNOT_FOUND
                    && wxDirExists(vcLibDirs[i]) )
                {
                    AddLibDir(vcLibDirs[i]);
                }
            }
            msvcFound = true;
            break;
        }

        if ( m_MasterPath.IsEmpty() || !wxDirExists(m_MasterPath) )
        {
            // Just a final guess for the default installation dir
            wxString Programs = _T("C:\\Program Files");
            // what's the "Program Files" location
            // TO DO : support 64 bit ->    32 bit apps are in "ProgramFiles(x86)"
            //                              64 bit apps are in "ProgramFiles"
            wxGetEnv(_T("ProgramFiles"), &Programs);
            m_MasterPath = Programs + _T("\\Intel\\Compiler\\C++\\9.0");
        }
        else if (!msvcFound)
        {
            cbMessageBox(_T("It seems your computer doesn't have a MSVC compiler installed.\n\n"
                            "The ICC compiler requires MSVC for proper functioning and\n"
                            "it may not work without it."),
                         _T("Error"), wxOK | wxICON_ERROR);
        }
    }
    else
    {
        m_MasterPath = _T("/opt/intel/cc/9.0");
        if (wxDirExists(_T("/opt/intel")))
        {
            wxDir icc_dir(_T("/opt/intel/cc"));
            if (icc_dir.IsOpened())
            {
                wxArrayString dirs;
                wxIccDirTraverser IccDirTraverser(dirs);
                icc_dir.Traverse(IccDirTraverser);
                if (!dirs.IsEmpty())
                {
                    // Now sort the array in reverse order to get the latest version's path
                    dirs.Sort(true);
                    m_MasterPath = dirs[0];
                }
            }
        }
    }

    AutoDetectResult ret = wxFileExists(m_MasterPath + sep + _T("bin") + sep + m_Programs.C) ? adrDetected : adrGuessed;
    if (ret == adrGuessed)
        ret = wxFileExists(m_MasterPath + sep + _T("bin") + sep + _T("ia32") + sep + m_Programs.C) ? adrDetected : adrGuessed;
    if (ret == adrGuessed)
        ret = wxFileExists(m_MasterPath + sep + _T("bin") + sep + _T("intel64") + sep + m_Programs.C) ? adrDetected : adrGuessed;

    if (ret == adrDetected)
    {
        if ( wxFileExists(m_MasterPath + sep + _T("bin") + sep + _T("ia32") + sep + m_Programs.C) )
            m_ExtraPaths.Add(m_MasterPath + sep + _T("bin") + sep + _T("ia32"));
        if ( wxFileExists(m_MasterPath + sep + _T("bin") + sep + _T("intel64") + sep + m_Programs.C) )
            m_ExtraPaths.Add(m_MasterPath + sep + _T("bin") + sep + _T("intel64"));

        if ( wxDirExists(m_MasterPath + sep + _T("include")) )
        {
            m_IncludeDirs.Insert(m_MasterPath + sep + _T("include"), 0);
            m_ResIncludeDirs.Insert(m_MasterPath + sep + _T("include"), 0);
        }
        if ( wxDirExists(m_MasterPath + sep + _T("compiler") + sep + _T("include")) )
        {
            m_IncludeDirs.Insert(m_MasterPath + sep + _T("compiler") + sep + _T("include"), 0);
            m_ResIncludeDirs.Insert(m_MasterPath + sep + _T("compiler") + sep + _T("include"), 0);
        }

        if ( wxDirExists(m_MasterPath + sep + _T("lib")) )
        {
            m_IncludeDirs.Insert(m_MasterPath + sep + _T("lib"), 0);
            m_ResIncludeDirs.Insert(m_MasterPath + sep + _T("lib"), 0);
        }

        if ( wxDirExists(m_MasterPath + sep + _T("compiler") + sep + _T("lib")) )
            m_LibDirs.Insert(m_MasterPath + sep + _T("compiler") + sep + _T("lib"), 0);
        if ( wxDirExists(m_MasterPath + sep + _T("compiler") + sep + _T("lib") + sep + _T("ia32")) )
            m_LibDirs.Insert(m_MasterPath + sep + _T("compiler") + sep + _T("lib") + sep + _T("ia32"), 0);
        if ( wxDirExists(m_MasterPath + sep + _T("compiler") + sep + _T("lib") + sep + _T("intel64")) )
            m_LibDirs.Insert(m_MasterPath + sep + _T("compiler") + sep + _T("lib") + sep + _T("intel64"), 0);
    }
    // Try to detect the debugger. If not detected successfully the debugger plugin will
    // complain, so only the autodetection of compiler is considered in return value
    wxString path;
    wxString dbg;
    if (platform::windows)
    {
        dbg = _T("idb.exe");
        wxGetEnv(_T("IDB_PATH"), &path);
        if ( !path.IsEmpty() && wxDirExists(path) )
        {
            int version = 9;
            while ( true )
            {
                wxString idbPath = path + sep + _T("IDB") + sep + wxString::Format(_T("%d.0"), version) + sep + _T("IA32");
                if ( wxDirExists(idbPath) )
                {
                    path = idbPath; // found
                    break;  // exit while-loop
                }
                else if (version>15)
                    break;  // exit while-loop
                else
                    version++;
            }
        }
    }
    else
    {
        dbg  = _T("idb");
        path = _T("/opt/intel/idb/9.0");
        if ( wxDirExists(_T("/opt/intel")) )
        {
            wxDir icc_debug_dir(_T("/opt/intel/idb"));
            if (icc_debug_dir.IsOpened())
            {
                wxArrayString debug_dirs;
                wxIccDirTraverser IccDebugDirTraverser(debug_dirs);
                icc_debug_dir.Traverse(IccDebugDirTraverser);
                if (!debug_dirs.IsEmpty())
                {
                    // Now sort the array in reverse order to get the latest version's path
                    debug_dirs.Sort(true);
                    path = debug_dirs[0];
                }
            }
        }
    }

    if ( wxFileExists(path + sep + _T("bin") + sep + dbg) )
        m_ExtraPaths.Add(path);

    return ret;
}
Exemple #11
0
llvm_value CompileExpression::DoRewrite(RewriteCandidate &cand)
// ----------------------------------------------------------------------------
//   Generate code for a particular rewwrite candidate
// ----------------------------------------------------------------------------
{
    Infix *rw = cand.rewrite;
    llvm_value result = NULL;

    IFTRACE(calltypes)
        std::cerr << "Rewrite: " << rw << "\n";

    // Evaluate parameters
    llvm_values args;
    RewriteBindings &bnds = cand.bindings;
    RewriteBindings::iterator b;
    for (b = bnds.begin(); b != bnds.end(); b++)
    {
        Tree *tree = (*b).value;
        IFTRACE(calltypes)
            std::cerr << "  Arg: " << tree << ": ";
        if (llvm_value closure = (*b).Closure(unit))
        {
            args.push_back(closure);
            IFTRACE(calltypes)
                llvm::errs() << "  closure " << *closure << "\n";
        }
        else if (llvm_value value = Value(tree))
        {
            args.push_back(value);
            llvm_type mtype = value->getType();
            if (unit->compiler->IsClosureType(mtype))
                (*b).closure = value;
            IFTRACE(calltypes)
                llvm::errs() << "  value " << *value
                             << " mtype " << *mtype << "\n";
        }
    }

    // Check if this is an LLVM builtin
    Tree *builtin = NULL;
    if (Tree *value = rw->right)
        if (Prefix *prefix = value->AsPrefix())
            if (Name *name = prefix->left->AsName())
                if (name->value == "opcode")
                    builtin = prefix->right;

    if (builtin)
    {
        llvm_builder bld = unit->code;
        if (Prefix *prefix = builtin->AsPrefix())
        {
            if (Name *name = prefix->left->AsName())
            {
                if (name->value == "data")
                {
                    bld = unit->data;
                    builtin = prefix->right;
                }
            }
        }

        Name *name = builtin->AsName();
        if (!name)
        {
            Ooops("Malformed primitive $1", builtin);
            result = unit->CallFormError(builtin);
        }
        else
        {
            Compiler *compiler = unit->compiler;
            text op = name->value;
            uint sz = args.size();
            llvm_value *a = &args[0];
            result = compiler->Primitive(*unit, bld, op, sz, a);
            if (!result)
                Ooops("Invalid primitive $1", builtin);
            IFTRACE(calltypes)
                llvm::errs() << "  = Primitive: " << *result << "\n";
        }
    }
    else
    {
        llvm_value function = unit->Compile(cand, args);
        IFTRACE(calltypes)
            llvm::errs() << "  < Function: " << *function << "\n";
        if (function)
            result = unit->code->CreateCall(function, LLVMS_ARGS(args));
        IFTRACE(calltypes)
            llvm::errs() << "  =Call: " << *result << "\n";
    }

    return result;
}
Exemple #12
0
int main()
{
    using namespace moon;

    Compiler compiler; // Script parsing and bytecode output.
    VM       vm;       // Executes bytecode produced by a Compiler.

    try
    {
        compiler.parseScript(&vm, "tests/script/globals.ml");
        compiler.compile(&vm);

        // Init the globals:
        logStream() << "C++: First run...\n";
        vm.execute();

        // Print the current values:
        logStream() << "C++: Calling print_globals()...\n";
        vm.call("print_globals");

        // Change them:
        logStream() << "C++: Editing globals vars...\n";
        {
            Variant var;

            var.type = Variant::Type::Integer;
            var.value.asInteger = 1337;
            MOON_ASSERT(vm.globals.setGlobal("an_integer", var) == true);

            var.type = Variant::Type::Float;
            var.value.asFloat = 3.141592;
            MOON_ASSERT(vm.globals.setGlobal("a_float", var) == true);

            var.type = Variant::Type::Range;
            var.value.asRange.begin = -5;
            var.value.asRange.end   = +5;
            MOON_ASSERT(vm.globals.setGlobal("a_range", var) == true);

            var.type = Variant::Type::Str;
            const char * s = "hello from C++";
            var.value.asString = Str::newFromString(vm, s, std::strlen(s), true);
            MOON_ASSERT(vm.globals.setGlobal("a_string", var) == true);
        }

        // Print the new values:
        logStream() << "C++: Calling print_globals() again...\n";
        vm.call("print_globals");
    }
    catch (...)
    {
        #if MOON_SAVE_SCRIPT_CALLSTACK
        if (!vm.callstack.isEmpty())
        {
            vm.printStackTrace(logStream());
        }
        #endif // MOON_SAVE_SCRIPT_CALLSTACK

        logStream() << color::red() << "terminating with error(s)...\n" << color::restore();
        return EXIT_FAILURE;
    }
}
static bool slang_reflect(const Compiler &vertex_compiler, const Compiler &fragment_compiler,
      const ShaderResources &vertex, const ShaderResources &fragment,
      slang_reflection *reflection)
{
   // Validate use of unexpected types.
   if (
         !vertex.sampled_images.empty() ||
         !vertex.storage_buffers.empty() ||
         !vertex.subpass_inputs.empty() ||
         !vertex.storage_images.empty() ||
         !vertex.atomic_counters.empty() ||
         !fragment.storage_buffers.empty() ||
         !fragment.subpass_inputs.empty() ||
         !fragment.storage_images.empty() ||
         !fragment.atomic_counters.empty())
   {
      RARCH_ERR("[slang]: Invalid resource type detected.\n");
      return false;
   }

   // Validate vertex input.
   if (vertex.stage_inputs.size() != 2)
   {
      RARCH_ERR("[slang]: Vertex must have two attributes.\n");
      return false;
   }

   if (fragment.stage_outputs.size() != 1)
   {
      RARCH_ERR("[slang]: Multiple render targets not supported.\n");
      return false;
   }

   if (fragment_compiler.get_decoration(fragment.stage_outputs[0].id, spv::DecorationLocation) != 0)
   {
      RARCH_ERR("[slang]: Render target must use location = 0.\n");
      return false;
   }

   uint32_t location_mask = 0;
   for (auto &input : vertex.stage_inputs)
      location_mask |= 1 << vertex_compiler.get_decoration(input.id, spv::DecorationLocation);

   if (location_mask != 0x3)
   {
      RARCH_ERR("[slang]: The two vertex attributes do not use location = 0 and location = 1.\n");
      return false;
   }

   // Validate the single uniform buffer.
   if (vertex.uniform_buffers.size() > 1)
   {
      RARCH_ERR("[slang]: Vertex must use zero or one uniform buffer.\n");
      return false;
   }

   if (fragment.uniform_buffers.size() > 1)
   {
      RARCH_ERR("[slang]: Fragment must use zero or one uniform buffer.\n");
      return false;
   }

   // Validate the single push constant buffer.
   if (vertex.push_constant_buffers.size() > 1)
   {
      RARCH_ERR("[slang]: Vertex must use zero or one push constant buffers.\n");
      return false;
   }

   if (fragment.push_constant_buffers.size() > 1)
   {
      RARCH_ERR("[slang]: Fragment must use zero or one push cosntant buffer.\n");
      return false;
   }

   uint32_t vertex_ubo = vertex.uniform_buffers.empty() ? 0 : vertex.uniform_buffers[0].id;
   uint32_t fragment_ubo = fragment.uniform_buffers.empty() ? 0 : fragment.uniform_buffers[0].id;
   uint32_t vertex_push = vertex.push_constant_buffers.empty() ? 0 : vertex.push_constant_buffers[0].id;
   uint32_t fragment_push = fragment.push_constant_buffers.empty() ? 0 : fragment.push_constant_buffers[0].id;

   if (vertex_ubo &&
         vertex_compiler.get_decoration(vertex_ubo, spv::DecorationDescriptorSet) != 0)
   {
      RARCH_ERR("[slang]: Resources must use descriptor set #0.\n");
      return false;
   }

   if (fragment_ubo &&
         fragment_compiler.get_decoration(fragment_ubo, spv::DecorationDescriptorSet) != 0)
   {
      RARCH_ERR("[slang]: Resources must use descriptor set #0.\n");
      return false;
   }

   unsigned vertex_ubo_binding = vertex_ubo ?
      vertex_compiler.get_decoration(vertex_ubo, spv::DecorationBinding) : -1u;
   unsigned fragment_ubo_binding = fragment_ubo ?
      fragment_compiler.get_decoration(fragment_ubo, spv::DecorationBinding) : -1u;
   bool has_ubo = vertex_ubo || fragment_ubo;

   if (vertex_ubo_binding != -1u &&
         fragment_ubo_binding != -1u &&
         vertex_ubo_binding != fragment_ubo_binding)
   {
      RARCH_ERR("[slang]: Vertex and fragment uniform buffer must have same binding.\n");
      return false;
   }

   unsigned ubo_binding = vertex_ubo_binding != -1u ? vertex_ubo_binding : fragment_ubo_binding;

   if (has_ubo && ubo_binding >= SLANG_NUM_BINDINGS)
   {
      RARCH_ERR("[slang]: Binding %u is out of range.\n", ubo_binding);
      return false;
   }

   reflection->ubo_binding = has_ubo ? ubo_binding : 0;
   reflection->ubo_stage_mask = 0;
   reflection->ubo_size = 0;
   reflection->push_constant_size = 0;
   reflection->push_constant_stage_mask = 0;

   if (vertex_ubo)
   {
      reflection->ubo_stage_mask |= SLANG_STAGE_VERTEX_MASK;
      reflection->ubo_size = max(reflection->ubo_size,
            vertex_compiler.get_declared_struct_size(vertex_compiler.get_type(vertex.uniform_buffers[0].base_type_id)));
   }

   if (fragment_ubo)
   {
      reflection->ubo_stage_mask |= SLANG_STAGE_FRAGMENT_MASK;
      reflection->ubo_size = max(reflection->ubo_size,
            fragment_compiler.get_declared_struct_size(fragment_compiler.get_type(fragment.uniform_buffers[0].base_type_id)));
   }

   if (vertex_push)
   {
      reflection->push_constant_stage_mask |= SLANG_STAGE_VERTEX_MASK;
      reflection->push_constant_size = max(reflection->push_constant_size,
            vertex_compiler.get_declared_struct_size(vertex_compiler.get_type(vertex.push_constant_buffers[0].base_type_id)));
   }

   if (fragment_push)
   {
      reflection->push_constant_stage_mask |= SLANG_STAGE_FRAGMENT_MASK;
      reflection->push_constant_size = max(reflection->push_constant_size,
            fragment_compiler.get_declared_struct_size(fragment_compiler.get_type(fragment.push_constant_buffers[0].base_type_id)));
   }

   // Validate push constant size against Vulkan's minimum spec to avoid cross-vendor issues.
   if (reflection->push_constant_size > 128)
   {
      RARCH_ERR("[slang]: Exceeded maximum size of 128 bytes for push constant buffer.\n");
      return false;
   }

   // Find all relevant uniforms and push constants.
   if (vertex_ubo && !add_active_buffer_ranges(vertex_compiler, vertex.uniform_buffers[0], reflection, false))
      return false;
   if (fragment_ubo && !add_active_buffer_ranges(fragment_compiler, fragment.uniform_buffers[0], reflection, false))
      return false;
   if (vertex_push && !add_active_buffer_ranges(vertex_compiler, vertex.push_constant_buffers[0], reflection, true))
      return false;
   if (fragment_push && !add_active_buffer_ranges(fragment_compiler, fragment.push_constant_buffers[0], reflection, true))
      return false;

   uint32_t binding_mask = has_ubo ? (1 << ubo_binding) : 0;

   // On to textures.
   for (auto &texture : fragment.sampled_images)
   {
      unsigned set = fragment_compiler.get_decoration(texture.id,
            spv::DecorationDescriptorSet);
      unsigned binding = fragment_compiler.get_decoration(texture.id,
            spv::DecorationBinding);

      if (set != 0)
      {
         RARCH_ERR("[slang]: Resources must use descriptor set #0.\n");
         return false;
      }

      if (binding >= SLANG_NUM_BINDINGS)
      {
         RARCH_ERR("[slang]: Binding %u is out of range.\n", ubo_binding);
         return false;
      }

      if (binding_mask & (1 << binding))
      {
         RARCH_ERR("[slang]: Binding %u is already in use.\n", binding);
         return false;
      }
      binding_mask |= 1 << binding;

      unsigned array_index = 0;
      slang_texture_semantic index = slang_name_to_texture_semantic(*reflection->texture_semantic_map,
            texture.name, &array_index);
      
      if (index == SLANG_INVALID_TEXTURE_SEMANTIC)
      {
         RARCH_ERR("[slang]: Non-semantic textures not supported yet.\n");
         return false;
      }

      resize_minimum(reflection->semantic_textures[index], array_index + 1);
      auto &semantic = reflection->semantic_textures[index][array_index];
      semantic.binding = binding;
      semantic.stage_mask = SLANG_STAGE_FRAGMENT_MASK;
      semantic.texture = true;
   }

   RARCH_LOG("[slang]: Reflection\n");
   RARCH_LOG("[slang]:   Textures:\n");
   for (unsigned i = 0; i < SLANG_NUM_TEXTURE_SEMANTICS; i++)
   {
      unsigned index = 0;
      for (auto &sem : reflection->semantic_textures[i])
      {
         if (sem.texture)
            RARCH_LOG("[slang]:      %s (#%u)\n", texture_semantic_names[i], index);
         index++;
      }
   }

   RARCH_LOG("[slang]:\n");
   RARCH_LOG("[slang]:   Uniforms (Vertex: %s, Fragment: %s):\n",
         reflection->ubo_stage_mask & SLANG_STAGE_VERTEX_MASK ? "yes": "no",
         reflection->ubo_stage_mask & SLANG_STAGE_FRAGMENT_MASK ? "yes": "no");
   RARCH_LOG("[slang]:   Push Constants (Vertex: %s, Fragment: %s):\n",
         reflection->push_constant_stage_mask & SLANG_STAGE_VERTEX_MASK ? "yes": "no",
         reflection->push_constant_stage_mask & SLANG_STAGE_FRAGMENT_MASK ? "yes": "no");

   for (unsigned i = 0; i < SLANG_NUM_SEMANTICS; i++)
   {
      if (reflection->semantics[i].uniform)
      {
         RARCH_LOG("[slang]:      %s (Offset: %u)\n", semantic_uniform_names[i],
               unsigned(reflection->semantics[i].ubo_offset));
      }

      if (reflection->semantics[i].push_constant)
      {
         RARCH_LOG("[slang]:      %s (PushOffset: %u)\n", semantic_uniform_names[i],
               unsigned(reflection->semantics[i].push_constant_offset));
      }
   }

   for (unsigned i = 0; i < SLANG_NUM_TEXTURE_SEMANTICS; i++)
   {
      unsigned index = 0;
      for (auto &sem : reflection->semantic_textures[i])
      {
         if (sem.uniform)
         {
            RARCH_LOG("[slang]:      %s (#%u) (Offset: %u)\n", texture_semantic_uniform_names[i],
                  index,
                  unsigned(sem.ubo_offset));
         }

         if (sem.push_constant)
         {
            RARCH_LOG("[slang]:      %s (#%u) (PushOffset: %u)\n", texture_semantic_uniform_names[i],
                  index,
                  unsigned(sem.push_constant_offset));
         }
         index++;
      }
   }

   RARCH_LOG("[slang]:\n");
   RARCH_LOG("[slang]:   Parameters:\n");
   unsigned i = 0;
   for (auto &param : reflection->semantic_float_parameters)
   {
      if (param.uniform)
         RARCH_LOG("[slang]:     #%u (Offset: %u)\n", i, param.ubo_offset);
      if (param.push_constant)
         RARCH_LOG("[slang]:     #%u (PushOffset: %u)\n", i, param.push_constant_offset);
      i++;
   }

   return true;
}
static bool add_active_buffer_ranges(const Compiler &compiler, const Resource &resource,
      slang_reflection *reflection, bool push_constant)
{
   // Get which uniforms are actually in use by this shader.
   auto ranges = compiler.get_active_buffer_ranges(resource.id);
   for (auto &range : ranges)
   {
      auto &name = compiler.get_member_name(resource.base_type_id, range.index);
      auto &type = compiler.get_type(compiler.get_type(resource.base_type_id).member_types[range.index]);

      unsigned sem_index = 0;
      unsigned tex_sem_index = 0;
      auto sem = slang_uniform_name_to_semantic(*reflection->semantic_map, name, &sem_index);
      auto tex_sem = slang_uniform_name_to_texture_semantic(*reflection->texture_semantic_uniform_map,
            name, &tex_sem_index);

      if (tex_sem == SLANG_TEXTURE_SEMANTIC_PASS_OUTPUT && tex_sem_index >= reflection->pass_number)
      {
         RARCH_ERR("[slang]: Non causal filter chain detected. Shader is trying to use output from pass #%u, but this shader is pass #%u.\n",
               tex_sem_index, reflection->pass_number);
         return false;
      }

      if (sem != SLANG_INVALID_SEMANTIC)
      {
         if (!validate_type_for_semantic(type, sem))
         {
            RARCH_ERR("[slang]: Underlying type of semantic is invalid.\n");
            return false;
         }

         switch (sem)
         {
            case SLANG_SEMANTIC_FLOAT_PARAMETER:
               if (!set_ubo_float_parameter_offset(reflection, sem_index, range.offset, type.vecsize, push_constant))
                  return false;
               break;

            default:
               if (!set_ubo_offset(reflection, sem, range.offset, type.vecsize, push_constant))
                  return false;
               break;
         }
      }
      else if (tex_sem != SLANG_INVALID_TEXTURE_SEMANTIC)
      {
         if (!validate_type_for_texture_semantic(type))
         {
            RARCH_ERR("[slang]: Underlying type of texture semantic is invalid.\n");
            return false;
         }

         if (!set_ubo_texture_offset(reflection, tex_sem, tex_sem_index, range.offset, push_constant))
            return false;
      }
      else
      {
         RARCH_ERR("[slang]: Unknown semantic found.\n");
         return false;
      }
   }
   return true;
}
Compiler * CompilerGNUPOWERPC::CreateCopy()
{
    Compiler* c = new CompilerGNUPOWERPC(*this);
    c->SetExtraPaths(m_ExtraPaths); // wxArrayString doesn't seem to be copied with the default copy ctor...
    return c;
}
Exemple #16
0
bool AstIdentifier::emit_lvalue(Compiler &c) const {
	c.push_inst(Instruction::make_get(name.c_str(), Instruction::GET_NAME_REF));
	return false;
}
void NodePrintLine::accept(Compiler& c) { c.nodePrintLine(*this); }
Exemple #18
0
//------------------------------------------------------------------------
// TreeNodeInfoInitCall: Set the NodeInfo for a call.
//
// Arguments:
//    call - The call node of interest
//
// Return Value:
//    None.
//
void Lowering::TreeNodeInfoInitCall(GenTreeCall* call)
{
    TreeNodeInfo*   info              = &(call->gtLsraInfo);
    LinearScan*     l                 = m_lsra;
    Compiler*       compiler          = comp;
    bool            hasMultiRegRetVal = false;
    ReturnTypeDesc* retTypeDesc       = nullptr;

    info->srcCount = 0;
    if (call->TypeGet() != TYP_VOID)
    {
        hasMultiRegRetVal = call->HasMultiRegRetVal();
        if (hasMultiRegRetVal)
        {
            // dst count = number of registers in which the value is returned by call
            retTypeDesc    = call->GetReturnTypeDesc();
            info->dstCount = retTypeDesc->GetReturnRegCount();
        }
        else
        {
            info->dstCount = 1;
        }
    }
    else
    {
        info->dstCount = 0;
    }

    GenTree* ctrlExpr = call->gtControlExpr;
    if (call->gtCallType == CT_INDIRECT)
    {
        // either gtControlExpr != null or gtCallAddr != null.
        // Both cannot be non-null at the same time.
        assert(ctrlExpr == nullptr);
        assert(call->gtCallAddr != nullptr);
        ctrlExpr = call->gtCallAddr;
    }

    // set reg requirements on call target represented as control sequence.
    if (ctrlExpr != nullptr)
    {
        // we should never see a gtControlExpr whose type is void.
        assert(ctrlExpr->TypeGet() != TYP_VOID);

        info->srcCount++;

        // In case of fast tail implemented as jmp, make sure that gtControlExpr is
        // computed into a register.
        if (call->IsFastTailCall())
        {
            NYI_ARM("tail call");

#ifdef _TARGET_ARM64_
            // Fast tail call - make sure that call target is always computed in IP0
            // so that epilog sequence can generate "br xip0" to achieve fast tail call.
            ctrlExpr->gtLsraInfo.setSrcCandidates(l, genRegMask(REG_IP0));
#endif // _TARGET_ARM64_
        }
    }
#ifdef _TARGET_ARM_
    else
    {
        info->internalIntCount = 1;
    }
#endif // _TARGET_ARM_

    RegisterType registerType = call->TypeGet();

// Set destination candidates for return value of the call.

#ifdef _TARGET_ARM_
    if (call->IsHelperCall(compiler, CORINFO_HELP_INIT_PINVOKE_FRAME))
    {
        // The ARM CORINFO_HELP_INIT_PINVOKE_FRAME helper uses a custom calling convention that returns with
        // TCB in REG_PINVOKE_TCB. fgMorphCall() sets the correct argument registers.
        info->setDstCandidates(l, RBM_PINVOKE_TCB);
    }
    else
#endif // _TARGET_ARM_
        if (hasMultiRegRetVal)
    {
        assert(retTypeDesc != nullptr);
        info->setDstCandidates(l, retTypeDesc->GetABIReturnRegs());
    }
    else if (varTypeIsFloating(registerType))
    {
        info->setDstCandidates(l, RBM_FLOATRET);
    }
    else if (registerType == TYP_LONG)
    {
        info->setDstCandidates(l, RBM_LNGRET);
    }
    else
    {
        info->setDstCandidates(l, RBM_INTRET);
    }

    // If there is an explicit this pointer, we don't want that node to produce anything
    // as it is redundant
    if (call->gtCallObjp != nullptr)
    {
        GenTreePtr thisPtrNode = call->gtCallObjp;

        if (thisPtrNode->gtOper == GT_PUTARG_REG)
        {
            l->clearOperandCounts(thisPtrNode);
            thisPtrNode->SetContained();
            l->clearDstCount(thisPtrNode->gtOp.gtOp1);
        }
        else
        {
            l->clearDstCount(thisPtrNode);
        }
    }

    // First, count reg args
    bool callHasFloatRegArgs = false;

    for (GenTreePtr list = call->gtCallLateArgs; list; list = list->MoveNext())
    {
        assert(list->OperIsList());

        GenTreePtr argNode = list->Current();

        fgArgTabEntryPtr curArgTabEntry = compiler->gtArgEntryByNode(call, argNode);
        assert(curArgTabEntry);

        if (curArgTabEntry->regNum == REG_STK)
        {
            // late arg that is not passed in a register
            assert(argNode->gtOper == GT_PUTARG_STK);

            TreeNodeInfoInitPutArgStk(argNode->AsPutArgStk(), curArgTabEntry);
            continue;
        }

        // A GT_FIELD_LIST has a TYP_VOID, but is used to represent a multireg struct
        if (argNode->OperGet() == GT_FIELD_LIST)
        {
            argNode->SetContained();

            // There could be up to 2-4 PUTARG_REGs in the list (3 or 4 can only occur for HFAs)
            regNumber argReg = curArgTabEntry->regNum;
            for (GenTreeFieldList* entry = argNode->AsFieldList(); entry != nullptr; entry = entry->Rest())
            {
                TreeNodeInfoInitPutArgReg(entry->Current()->AsUnOp(), argReg, *info, false, &callHasFloatRegArgs);

                // Update argReg for the next putarg_reg (if any)
                argReg = genRegArgNext(argReg);

#if defined(_TARGET_ARM_)
                // A double register is modelled as an even-numbered single one
                if (entry->Current()->TypeGet() == TYP_DOUBLE)
                {
                    argReg = genRegArgNext(argReg);
                }
#endif // _TARGET_ARM_
            }
        }
#ifdef _TARGET_ARM_
        else if (argNode->OperGet() == GT_PUTARG_SPLIT)
        {
            fgArgTabEntryPtr curArgTabEntry = compiler->gtArgEntryByNode(call, argNode);
            TreeNodeInfoInitPutArgSplit(argNode->AsPutArgSplit(), *info, curArgTabEntry);
        }
#endif
        else
        {
            TreeNodeInfoInitPutArgReg(argNode->AsUnOp(), curArgTabEntry->regNum, *info, false, &callHasFloatRegArgs);
        }
    }

    // Now, count stack args
    // Note that these need to be computed into a register, but then
    // they're just stored to the stack - so the reg doesn't
    // need to remain live until the call.  In fact, it must not
    // because the code generator doesn't actually consider it live,
    // so it can't be spilled.

    GenTreePtr args = call->gtCallArgs;
    while (args)
    {
        GenTreePtr arg = args->gtOp.gtOp1;

        // Skip arguments that have been moved to the Late Arg list
        if (!(args->gtFlags & GTF_LATE_ARG))
        {
            if (arg->gtOper == GT_PUTARG_STK)
            {
                fgArgTabEntryPtr curArgTabEntry = compiler->gtArgEntryByNode(call, arg);
                assert(curArgTabEntry);

                assert(curArgTabEntry->regNum == REG_STK);

                TreeNodeInfoInitPutArgStk(arg->AsPutArgStk(), curArgTabEntry);
            }
#ifdef _TARGET_ARM_
            else if (arg->OperGet() == GT_PUTARG_SPLIT)
            {
                fgArgTabEntryPtr curArgTabEntry = compiler->gtArgEntryByNode(call, arg);
                TreeNodeInfoInitPutArgSplit(arg->AsPutArgSplit(), *info, curArgTabEntry);
            }
#endif
            else
            {
                TreeNodeInfo* argInfo = &(arg->gtLsraInfo);
                if (argInfo->dstCount != 0)
                {
                    argInfo->isLocalDefUse = true;
                }

                argInfo->dstCount = 0;
            }
        }
        args = args->gtOp.gtOp2;
    }

    // If it is a fast tail call, it is already preferenced to use IP0.
    // Therefore, no need set src candidates on call tgt again.
    if (call->IsVarargs() && callHasFloatRegArgs && !call->IsFastTailCall() && (ctrlExpr != nullptr))
    {
        NYI_ARM("float reg varargs");

        // Don't assign the call target to any of the argument registers because
        // we will use them to also pass floating point arguments as required
        // by Arm64 ABI.
        ctrlExpr->gtLsraInfo.setSrcCandidates(l, l->allRegs(TYP_INT) & ~(RBM_ARG_REGS));
    }

#ifdef _TARGET_ARM_

    if (call->NeedsNullCheck())
    {
        info->internalIntCount++;
    }

#endif // _TARGET_ARM_
}
Exemple #19
0
// Don't call this function from within the scope of:
//      ClangPlugin::OnEditorHook
//      ClangPlugin::OnTimer
int ClangPlugin::UpdateCompileCommand(cbEditor* ed)
{
    wxString compileCommand;
    ProjectFile* pf = ed->GetProjectFile();

    m_UpdateCompileCommand++;
    if ( m_UpdateCompileCommand > 1 )
    {
        // Re-entry is not allowed
        m_UpdateCompileCommand--;
        return 0;
    }

    ProjectBuildTarget* target = nullptr;
    Compiler* comp = nullptr;
    if (pf && pf->GetParentProject() && !pf->GetBuildTargets().IsEmpty())
    {
        target = pf->GetParentProject()->GetBuildTarget(pf->GetBuildTargets()[0]);
        comp = CompilerFactory::GetCompiler(target->GetCompilerID());
    }
    cbProject* proj = (pf ? pf->GetParentProject() : nullptr);
    if ( (!comp) && proj)
        comp = CompilerFactory::GetCompiler(proj->GetCompilerID());
    if (!comp)
    {
        cbProject* tmpPrj = Manager::Get()->GetProjectManager()->GetActiveProject();
        if (tmpPrj)
            comp = CompilerFactory::GetCompiler(tmpPrj->GetCompilerID());
    }
    if (!comp)
        comp = CompilerFactory::GetDefaultCompiler();

    if (pf && (!pf->GetBuildTargets().IsEmpty()) )
    {
        target = pf->GetParentProject()->GetBuildTarget(pf->GetBuildTargets()[0]);

        if (pf->GetUseCustomBuildCommand(target->GetCompilerID() ))
            compileCommand = pf->GetCustomBuildCommand(target->GetCompilerID()).AfterFirst(wxT(' '));

    }

    if (compileCommand.IsEmpty())
        compileCommand = wxT("$options $includes");
    CompilerCommandGenerator* gen = comp->GetCommandGenerator(proj);
    if (gen)
        gen->GenerateCommandLine(compileCommand, target, pf, ed->GetFilename(),
                g_InvalidStr, g_InvalidStr, g_InvalidStr );
    delete gen;

    wxStringTokenizer tokenizer(compileCommand);
    compileCommand.Empty();
    wxString pathStr;
    while (tokenizer.HasMoreTokens())
    {
        wxString flag = tokenizer.GetNextToken();
        // make all include paths absolute, so clang does not choke if Code::Blocks switches directories
        if (flag.StartsWith(wxT("-I"), &pathStr))
        {
            wxFileName path(pathStr);
            if (path.Normalize(wxPATH_NORM_ALL & ~wxPATH_NORM_CASE))
                flag = wxT("-I") + path.GetFullPath();
        }
        compileCommand += flag + wxT(" ");
    }
    compileCommand += GetCompilerInclDirs(comp->GetID());

    m_UpdateCompileCommand--;

    if (compileCommand != m_CompileCommand)
    {
        m_CompileCommand = compileCommand;
        return 1;
    }
    return 0;
}
void ProjectFile::SetObjName(const wxString& name)
{
    bool extendedObjectNames = project->GetExtendedObjectNamesGeneration();
    wxFileName fname(name);
    m_ObjName = name;
    FileType ft = FileTypeOf(name);
    if (ft == ftResource || ft == ftResourceBin)
    {
        if (extendedObjectNames)
            m_ObjName += FileFilters::RESOURCEBIN_DOT_EXT;
        else
        {
            fname.SetExt(FileFilters::RESOURCEBIN_EXT);
            m_ObjName = fname.GetFullPath();
        }
    }
    else if (ft == ftHeader) // support precompiled headers?
    {
        Compiler* compiler = CompilerFactory::GetCompiler(project->GetCompilerID());
        if (compiler && compiler->GetSwitches().supportsPCH)
        {
            // PCHs are always using the extended name mode (at least for GCC)
            // the extension is set to "h.gch"
            if (project->GetModeForPCH() == pchSourceFile)
                fname.Assign(relativeFilename);
            fname.SetExt(compiler->GetSwitches().PCHExtension);
            m_ObjName = fname.GetFullPath();
        }
    }
    else
    {
        if (project)
        {
            Compiler* compiler = CompilerFactory::GetCompiler(project->GetCompilerID());
            if (compiler)
            {
                if (extendedObjectNames)
                    m_ObjName += _T('.') + compiler->GetSwitches().objectExtension;
                else
                {
                    fname.SetExt(compiler->GetSwitches().objectExtension);
                    m_ObjName = fname.GetFullPath();
                }
            }
        }
        else
        {
            if (extendedObjectNames)
                m_ObjName += _T(".o"); // fallback?
            else
            {
                fname.SetExt(_T(".o"));
                m_ObjName = fname.GetFullPath();
            }
        }
    }
//#ifdef __WXMSW__
//    // special case for windows and files on a different drive
//    if (name.Length() > 1 && name.GetChar(1) == _T(':'))
//    {
//        m_ObjName.Remove(1, 1); // NOTE (mandrav): why remove the colon???
//    }
//#endif
}
Exemple #21
0
void NodeTernary::accept(Compiler& c) { c.nodeTernary(*this); }
void pfDetails::Update(ProjectBuildTarget* target, ProjectFile* pf)
{
    wxString sep = wxFILE_SEP_PATH;
    wxFileName tmp;

    wxFileName prjbase(target->GetParentProject()->GetBasePath());

    wxString objOut = target ? target->GetObjectOutput() : _T(".");
    wxString depsOut = target ? target->GetDepsOutput() : _T(".");

    // we must replace any macros here early because if the macros expand
    // to absolute paths (like global vars usually do), we 're gonna create
    // invalid filenames below
    Manager::Get()->GetMacrosManager()->ReplaceMacros(objOut, target);
    Manager::Get()->GetMacrosManager()->ReplaceMacros(depsOut, target);
    source_file_native = pf->relativeFilename;
    source_file_absolute_native = pf->file.GetFullPath();

    tmp = pf->GetObjName();
    FileType ft = FileTypeOf(pf->relativeFilename);

    Compiler* compiler = target
                            ? CompilerFactory::GetCompiler(target->GetCompilerID())
                            : CompilerFactory::GetDefaultCompiler();

    // support for precompiled headers
    if (target && ft == ftHeader && compiler && compiler->GetSwitches().supportsPCH)
    {
        switch (target->GetParentProject()->GetModeForPCH())
        {
            case pchSourceDir:
            {
                // if PCH is for a file called all.h, we create
                // all.h.gch/<target>_all.h.gch
                // (that's right: a directory)
                wxString new_gch = target->GetTitle() + _T('_') + pf->GetObjName();
                // make sure we 're not generating subdirs
                size_t len = new_gch.Length();
                for (size_t i = 0; i < len; ++i)
                {
                    wxChar c = new_gch[i];
                    if (c == _T('/') || c == _T('\\') || c == _T('.'))
                        new_gch[i] = _T('_');
                }

                wxFileName fn(source_file_native);
                object_file_native = fn.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR) +
                                    fn.GetName() + _T('.') + compiler->GetSwitches().PCHExtension +
                                    wxFILE_SEP_PATH +
                                    new_gch;
                object_file_flat_native = object_file_native;
                break;
            }

            case pchObjectDir:
            {
                object_file_native = objOut + sep + tmp.GetFullPath();
                object_file_flat_native = objOut + sep + tmp.GetFullName();
                break;
            }

            case pchSourceFile:
            {
                object_file_native = pf->GetObjName();
                object_file_flat_native = object_file_native;
                break;
            }
        }
    }
    else
    {
        if (pf->GetParentProject())
        {
            wxFileName fname(pf->relativeToCommonTopLevelPath);
            if (pf->generatedFiles.size())
            {
                // for files generating other files,
                // use the first generated file's "object name"
                fname.Assign(pf->generatedFiles[0]->relativeToCommonTopLevelPath);
            }
            /* NOTE: In case the source file resides in a different volume
            * than the volume where project file is,
            * then the object file will be created as follows.
            *
            * Project object output dir: C:\Foo\obj\Debug
            * Source: D:\Source\foo.cpp
            * Obj file: C:\Foo\obj\Debug\D\Source\foo.o
            */
            wxString fileVol = fname.GetVolume();
            wxString obj_file_full_path = fname.GetFullPath();
            bool diffVolume = false;

            if (platform::windows
                && (!fileVol.IsEmpty() && !fileVol.IsSameAs(prjbase.GetVolume())))
            {
                objOut += fileVol;
                obj_file_full_path = obj_file_full_path.AfterFirst(_T('\\'));
                diffVolume = true;
            }

            if (ft == ftResource || ft == ftResourceBin)
            {
                if (pf->GetParentProject()->GetExtendedObjectNamesGeneration())
                {
                    object_file_native = objOut + sep + obj_file_full_path;
                    object_file_flat_native = objOut + sep + fname.GetFullName();

                    object_file_native += FileFilters::RESOURCEBIN_DOT_EXT;
                    object_file_flat_native += FileFilters::RESOURCEBIN_DOT_EXT;
                }
                else
                {
                    fname.SetExt(FileFilters::RESOURCEBIN_EXT);
                    wxString obj_file_path = fname.GetFullPath();
                    if (diffVolume)
                        obj_file_path = obj_file_path.AfterFirst(_T('\\'));
                    object_file_native = objOut + sep + obj_file_path;
                    object_file_flat_native = objOut + sep + fname.GetFullName();
                }
            }
            else
            {
                if (pf->GetParentProject()->GetExtendedObjectNamesGeneration())
                {
                    object_file_native = objOut + sep + obj_file_full_path;
                    object_file_flat_native = objOut + sep + fname.GetFullName();

                    if (compiler)
                    {
                        object_file_native += _T('.') + compiler->GetSwitches().objectExtension;
                        object_file_flat_native += _T('.') + compiler->GetSwitches().objectExtension;
                    }
                }
                else
                {
                    if (compiler)
                        fname.SetExt(compiler->GetSwitches().objectExtension);
                    wxString obj_file_path = fname.GetFullPath();
                    if (diffVolume)
                        obj_file_path = obj_file_path.AfterFirst(_T('\\'));
                    object_file_native = objOut + sep + obj_file_path;
                    object_file_flat_native = objOut + sep + fname.GetFullName();
                }
            }
        }
    }
    wxFileName o_file(object_file_native);
    wxFileName o_file_flat(object_file_flat_native);
    o_file.MakeAbsolute(prjbase.GetFullPath());
    o_file_flat.MakeAbsolute(prjbase.GetFullPath());
    object_dir_native = o_file.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR);
    object_dir_flat_native = o_file_flat.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR);
    object_file_absolute_native = o_file.GetFullPath();
    object_file_flat_absolute_native = o_file_flat.GetFullPath();
    tmp.SetExt(_T("depend"));
    dep_file_native = depsOut + sep + tmp.GetFullPath();
    wxFileName d_file(dep_file_native);
    d_file.MakeAbsolute(prjbase.GetFullPath());
    dep_dir_native = d_file.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR);
    dep_file_absolute_native = o_file.GetFullPath();

    source_file = UnixFilename(source_file_native);
    QuoteStringIfNeeded(source_file);

    object_file = UnixFilename(object_file_native);
    QuoteStringIfNeeded(object_file);

    object_file_flat = UnixFilename(object_file_flat_native);
    QuoteStringIfNeeded(object_file_flat);

    dep_file = UnixFilename(dep_file_native);
    QuoteStringIfNeeded(dep_file);

    object_dir = UnixFilename(object_dir_native);
    QuoteStringIfNeeded(object_dir);

    object_dir_flat = UnixFilename(object_dir_flat_native);
    QuoteStringIfNeeded(object_dir_flat);

    dep_dir = UnixFilename(dep_dir_native);
    QuoteStringIfNeeded(dep_dir);

    Manager::Get()->GetMacrosManager()->ReplaceEnvVars(object_file_native);
    Manager::Get()->GetMacrosManager()->ReplaceEnvVars(object_file_flat_native);
    Manager::Get()->GetMacrosManager()->ReplaceEnvVars(object_dir_native);
    Manager::Get()->GetMacrosManager()->ReplaceEnvVars(object_dir_flat_native);
    Manager::Get()->GetMacrosManager()->ReplaceEnvVars(object_file_absolute_native);
    Manager::Get()->GetMacrosManager()->ReplaceEnvVars(object_file_flat_absolute_native);
    Manager::Get()->GetMacrosManager()->ReplaceEnvVars(dep_file_native);
    Manager::Get()->GetMacrosManager()->ReplaceEnvVars(dep_dir_native);
    Manager::Get()->GetMacrosManager()->ReplaceEnvVars(dep_file_absolute_native);
    Manager::Get()->GetMacrosManager()->ReplaceEnvVars(dep_dir);
    Manager::Get()->GetMacrosManager()->ReplaceEnvVars(object_dir);
    Manager::Get()->GetMacrosManager()->ReplaceEnvVars(object_dir_flat);
    Manager::Get()->GetMacrosManager()->ReplaceEnvVars(dep_file);
    Manager::Get()->GetMacrosManager()->ReplaceEnvVars(object_file);
    Manager::Get()->GetMacrosManager()->ReplaceEnvVars(object_file_flat);
    Manager::Get()->GetMacrosManager()->ReplaceEnvVars(source_file);
}
Exemple #23
0
/*****************************************************************************
 * gsMarkPtrsAndAssignGroups
 * Walk a tree looking for assignment groups, variables whose value is used
 * in a *p store or use, and variable passed to calls.  This info is then used
 * to determine parameters which are vulnerable.
 * This function carries a state to know if it is under an assign node, call node
 * or indirection node.  It starts a new tree walk for it's subtrees when the state
 * changes.
 */
Compiler::fgWalkResult Compiler::gsMarkPtrsAndAssignGroups(GenTreePtr *pTree, fgWalkData *data)
{
    struct MarkPtrsInfo *pState= (MarkPtrsInfo *)data->pCallbackData;
    struct MarkPtrsInfo newState = *pState;
    Compiler *comp = data->compiler;
    GenTreePtr tree = *pTree;
    ShadowParamVarInfo *shadowVarInfo = pState->comp->gsShadowVarInfo;
    assert(shadowVarInfo);
    bool fIsBlk = false;
    unsigned lclNum;

    assert(!pState->isAssignSrc || pState->lvAssignDef != (unsigned)-1);

    if (pState->skipNextNode)
    {
        pState->skipNextNode = false;
        return WALK_CONTINUE;
    }

    switch (tree->OperGet())
    {
    // Indirections - look for *p uses and defs
    case GT_INITBLK:
    case GT_COPYOBJ:
    case GT_COPYBLK:
        fIsBlk = true;
        // fallthrough
    case GT_IND:
    case GT_LDOBJ:
    case GT_ARR_ELEM:
    case GT_ARR_INDEX:
    case GT_ARR_OFFSET:
    case GT_FIELD:

        newState.isUnderIndir = true;
        {
            if (fIsBlk)
            {
                // Blk nodes have implicit indirections.
                comp->fgWalkTreePre(&tree->gtOp.gtOp1, comp->gsMarkPtrsAndAssignGroups, (void *)&newState);

                if (tree->OperGet() == GT_INITBLK)
                {
                    newState.isUnderIndir = false;
                }
                comp->fgWalkTreePre(&tree->gtOp.gtOp2, comp->gsMarkPtrsAndAssignGroups, (void *)&newState);
            }
            else
            {
                newState.skipNextNode = true;  // Don't have to worry about which kind of node we're dealing with
                comp->fgWalkTreePre(&tree, comp->gsMarkPtrsAndAssignGroups, (void *)&newState);
            }
        }

        return WALK_SKIP_SUBTREES;

    // local vars and param uses
    case GT_LCL_VAR:
    case GT_LCL_FLD:
        lclNum = tree->gtLclVarCommon.gtLclNum;

        if (pState->isUnderIndir)
        {
            // The variable is being dereferenced for a read or a write.
            comp->lvaTable[lclNum].lvIsPtr = 1;
        }

        if (pState->isAssignSrc)
        {
            //
            // Add lvAssignDef and lclNum to a common assign group
            if (shadowVarInfo[pState->lvAssignDef].assignGroup)
            {
                if (shadowVarInfo[lclNum].assignGroup)
                {
                    // OR both bit vector
                    shadowVarInfo[pState->lvAssignDef].assignGroup->bitVectOr(shadowVarInfo[lclNum].assignGroup);
                }
                else
                {
                    shadowVarInfo[pState->lvAssignDef].assignGroup->bitVectSet(lclNum);
                }
            
                // Point both to the same bit vector
                shadowVarInfo[lclNum].assignGroup = shadowVarInfo[pState->lvAssignDef].assignGroup;
            }
            else if (shadowVarInfo[lclNum].assignGroup)
            {
                shadowVarInfo[lclNum].assignGroup->bitVectSet(pState->lvAssignDef);
            
                // Point both to the same bit vector
                shadowVarInfo[pState->lvAssignDef].assignGroup = shadowVarInfo[lclNum].assignGroup;
            }
            else
            {
                FixedBitVect *bv = FixedBitVect::bitVectInit(pState->comp->lvaCount, pState->comp);

                // (shadowVarInfo[pState->lvAssignDef] == NULL && shadowVarInfo[lclNew] == NULL);
                // Neither of them has an assign group yet.  Make a new one.
                shadowVarInfo[pState->lvAssignDef].assignGroup = bv;
                shadowVarInfo[lclNum].assignGroup = bv;
                bv->bitVectSet(pState->lvAssignDef);
                bv->bitVectSet(lclNum);
            }

        }
        return WALK_CONTINUE;
    
    // Calls - Mark arg variables
    case GT_CALL:

        newState.isUnderIndir = false;
        newState.isAssignSrc = false;
        {
            if (tree->gtCall.gtCallObjp)
            {
                newState.isUnderIndir = true;
                comp->fgWalkTreePre(&tree->gtCall.gtCallObjp, gsMarkPtrsAndAssignGroups, (void *)&newState);
            }

            for (GenTreeArgList* args = tree->gtCall.gtCallArgs; args; args = args->Rest())
            {
                comp->fgWalkTreePre(&args->Current(), gsMarkPtrsAndAssignGroups, (void *)&newState);
            }
            for (GenTreeArgList* args = tree->gtCall.gtCallLateArgs; args; args = args->Rest())
            {
                comp->fgWalkTreePre(&args->Current(), gsMarkPtrsAndAssignGroups, (void *)&newState);
            }

            if (tree->gtCall.gtCallType == CT_INDIRECT)
            {
                newState.isUnderIndir = true;

                // A function pointer is treated like a write-through pointer since
                // it controls what code gets executed, and so indirectly can cause
                // a write to memory.
                comp->fgWalkTreePre(&tree->gtCall.gtCallAddr, gsMarkPtrsAndAssignGroups, (void *)&newState);
            }
        }
        return WALK_SKIP_SUBTREES;


    case GT_ADDR:
        newState.isUnderIndir = false;
        // We'll assume p in "**p = " can be vulnerable because by changing 'p', someone
        // could control where **p stores to.
        {
            comp->fgWalkTreePre(&tree->gtOp.gtOp1, comp->gsMarkPtrsAndAssignGroups, (void *)&newState);
        }
        return WALK_SKIP_SUBTREES;


    default:
        // Assignments - track assign groups and *p defs.
        if (tree->OperIsAssignment())
        {
            bool isLocVar;
            bool isLocFld;

            // Walk dst side
            comp->fgWalkTreePre(&tree->gtOp.gtOp1, comp->gsMarkPtrsAndAssignGroups, (void *)&newState);
            
            // Now handle src side
            isLocVar = tree->gtOp.gtOp1->OperGet() == GT_LCL_VAR;
            isLocFld = tree->gtOp.gtOp1->OperGet() == GT_LCL_FLD;

            if ((isLocVar || isLocFld) && tree->gtOp.gtOp2)
            {
                lclNum = tree->gtOp.gtOp1->gtLclVarCommon.gtLclNum;
                newState.lvAssignDef = lclNum;
                newState.isAssignSrc = true;
            }

            comp->fgWalkTreePre(&tree->gtOp.gtOp2, comp->gsMarkPtrsAndAssignGroups, (void *)&newState);

            return WALK_SKIP_SUBTREES;
        }
    }

    return WALK_CONTINUE;
}
std::shared_ptr<Operand> PredicateParser::createPrimitive(const std::string& fullExpression, size_t from, size_t to)
{
    from = skipSpace(fullExpression, from, to);
    while(to > from && std::isspace(fullExpression.at(to - 1)))
    {
        --to;
    }

    if(from >= to)
    {
        return nullptr;
    }

    char c = fullExpression.at(from);
    switch(c)
    {
    case '"':
    {
        auto last = skipString(fullExpression, from + 1, to);
        auto str = fullExpression.substr(from + 1, last - from - 1);
        if(last == to)
        {
            throw std::logic_error(str + " not a string");
        }

        return std::make_shared<StringOperand>(str);
    }
    case '^':
    case '.':
    {
        Compiler subCompiler;
        auto subExpression = subCompiler.compile(fullExpression, from, to);
        return std::make_shared<LocationOperand>(subExpression);
    }
    case '{':
    case '[':
    {
        std::stack<char> unmatched;
        unmatched.push(c);
        auto last = skip2MatchParenthesis(unmatched, fullExpression, from + 1, to);
        auto str = fullExpression.substr(from, last - from + 1);
        if(last == to)
        {
            throw std::logic_error(str + " not a json");
        }

        json value = json::parse(str);
        return std::make_shared<JsonOperand>(value);
    }
    case '/':
    {
        auto toPos = skip2(fullExpression, from + 1, '/', to);
        auto regex = fullExpression.substr(from + 1, toPos - from - 1);
        return std::make_shared<RegexOperand>(regex);
    }
    case '$':
    {
        auto variableName = fullExpression.substr(from + 1, to - from - 1);
        return std::make_shared<VariableOperand>(variableName);
    }
    default:
        if(isBool(fullExpression, from, to) && '0' != fullExpression.at(from) && '1' != fullExpression.at(from))
        {
            bool v = convert2Bool(fullExpression, from, to);
            return std::make_shared<BoolOperand>(v);
        }
        else if(isInt(fullExpression, from, to))
        {
            int v = convert2Int(fullExpression, from, to);
            return std::make_shared<IntOperand>(v);
        }
        else if(isReal(fullExpression, from, to))
        {
            double v = convert2Real(fullExpression, from, to);
            return std::make_shared<RealOperand>(v);
        }
        else
        {
            throw std::logic_error(fullExpression.substr(from, to - from) + " can't be interpreted as an operand");
        }
    }
}
Exemple #25
0
void NodeBody::accept(Compiler& c) { c.nodeBody(*this); }
Exemple #26
0
	void AsebaNetworkInterface::LoadScripts(const QString& fileName, const QDBusMessage &message)
	{
		QFile file(fileName);
		if (!file.open(QFile::ReadOnly))
		{
			DBusConnectionBus().send(message.createErrorReply(QDBusError::InvalidArgs, QString("file %0 does not exists").arg(fileName)));
			return;
		}
		
		QDomDocument document("aesl-source");
		QString errorMsg;
		int errorLine;
		int errorColumn;
		if (!document.setContent(&file, false, &errorMsg, &errorLine, &errorColumn))
		{
			DBusConnectionBus().send(message.createErrorReply(QDBusError::Other, QString("Error in XML source file: %0 at line %1, column %2").arg(errorMsg).arg(errorLine).arg(errorColumn)));
			return;
		}
		
		commonDefinitions.events.clear();
		commonDefinitions.constants.clear();
		userDefinedVariablesMap.clear();
		
		int noNodeCount = 0;
		QDomNode domNode = document.documentElement().firstChild();
		
		// FIXME: this code depends on event and contants being before any code
		bool wasError = false;
		while (!domNode.isNull())
		{
			if (domNode.isElement())
			{
				QDomElement element = domNode.toElement();
				if (element.tagName() == "node")
				{
					bool ok;
					const unsigned nodeId(getNodeId(element.attribute("name").toStdWString(), element.attribute("nodeId", 0).toUInt(), &ok));
					if (ok)
					{
						std::wistringstream is(element.firstChild().toText().data().toStdWString());
						Error error;
						BytecodeVector bytecode;
						unsigned allocatedVariablesCount;
						
						Compiler compiler;
						compiler.setTargetDescription(getDescription(nodeId));
						compiler.setCommonDefinitions(&commonDefinitions);
						bool result = compiler.compile(is, bytecode, allocatedVariablesCount, error);
						
						if (result)
						{
							typedef std::vector<Message*> MessageVector;
							MessageVector messages;
							sendBytecode(messages, nodeId, std::vector<uint16>(bytecode.begin(), bytecode.end()));
							for (MessageVector::const_iterator it = messages.begin(); it != messages.end(); ++it)
							{
								hub->sendMessage(*it);
								delete *it;
							}
							Run msg(nodeId);
							hub->sendMessage(msg);
						}
						else
						{
							DBusConnectionBus().send(message.createErrorReply(QDBusError::Failed, QString::fromStdWString(error.toWString())));
							wasError = true;
							break;
						}
						// retrieve user-defined variables for use in get/set
						userDefinedVariablesMap[element.attribute("name")] = *compiler.getVariablesMap();
					}
					else
						noNodeCount++;
				}
				else if (element.tagName() == "event")
				{
					const QString eventName(element.attribute("name"));
					const unsigned eventSize(element.attribute("size").toUInt());
					if (eventSize > ASEBA_MAX_EVENT_ARG_SIZE)
					{
						DBusConnectionBus().send(message.createErrorReply(QDBusError::Failed, QString("Event %1 has a length %2 larger than maximum %3").arg(eventName).arg(eventSize).arg(ASEBA_MAX_EVENT_ARG_SIZE)));
						wasError = true;
						break;
					}
					else
					{
						commonDefinitions.events.push_back(NamedValue(eventName.toStdWString(), eventSize));
					}
				}
				else if (element.tagName() == "constant")
				{
					commonDefinitions.constants.push_back(NamedValue(element.attribute("name").toStdWString(), element.attribute("value").toInt()));
				}
			}
			domNode = domNode.nextSibling();
		}
		
		// check if there was an error
		if (wasError)
		{
			std::wcerr << QString("There was an error while loading script %1").arg(fileName).toStdWString() << std::endl;
			commonDefinitions.events.clear();
			commonDefinitions.constants.clear();
			userDefinedVariablesMap.clear();
		}
		
		// check if there was some matching problem
		if (noNodeCount)
		{
			std::wcerr << QString("%0 scripts have no corresponding nodes in the current network and have not been loaded.").arg(noNodeCount).toStdWString() << std::endl;
		}
	}
Exemple #27
0
jit_value_t Break::compile_jit(Compiler& c, jit_function_t& F, Type) const {

	jit_insn_branch(F, c.get_current_loop_end_label());

	return JIT_CREATE_CONST_POINTER(F, LSNull::null_var);
}
Exemple #28
0
bool AstMember::emit_lvalue(Compiler& c) const {
	if (node->emit(c)) return true;
	c.push_inst(Instruction::make_get(name.c_str(), Instruction::GET_MEMBER_REF));
	return false;
}
Exemple #29
0
int main(int, char**)
{
  Compiler c;

  FileLogger logger(stderr);
  c.setLogger(&logger);

  c.newFunction(CALL_CONV_DEFAULT, FunctionBuilder0<Void>());

  Label L_A = c.newLabel();
  Label L_B = c.newLabel();
  Label L_C = c.newLabel();

  c.jmp(L_B);

  c.bind(L_A);
  c.jmp(L_C);

  c.bind(L_B);
  c.jmp(L_A);

  c.bind(L_C);

  c.ret();
  c.endFunction();

  VoidFn fn = function_cast<VoidFn>(c.make());

  // Ensure that everything is ok.
  if (!fn)
  {
    printf("Error making jit function (%u).\n", c.getError());
    return 1;
  }

  // Free the JIT function if it's not needed anymore.
  MemoryManager::getGlobal()->free((void*)fn);

  return 0;
}
Exemple #30
0
bool AstAssign::emit(Compiler& c) const {
	if (src->emit(c)) return true;
	if (dst->emit_lvalue(c)) return true;
	c.push_inst(Instruction::make_set());
	return false;
}