Index: trunk/abdev/BasicCompiler_Common/src/Exception.cpp
===================================================================
--- trunk/abdev/BasicCompiler_Common/src/Exception.cpp	(revision 359)
+++ trunk/abdev/BasicCompiler_Common/src/Exception.cpp	(revision 361)
@@ -11,8 +11,34 @@
 namespace Exception{
 
+class CatchScope
+{
+	Type paramType;
+	long codePos;
+public:
+	CatchScope( const Type &paramType, long codePos )
+		: paramType( paramType )
+		, codePos( codePos )
+	{
+	}
+	~CatchScope()
+	{
+	}
+
+	const Type &GetParamType() const
+	{
+		return paramType;
+	}
+	long GetCodePos() const
+	{
+		return codePos;
+	}
+};
+typedef std::vector<CatchScope> CatchScopes;
+
 class TryScope
 {
-	bool isCatched;
 	bool isDefinedFinally;
+
+	CatchScopes catchScopes;
 
 	std::vector<const PertialSchedule *> finallySchedules;
@@ -31,11 +57,10 @@
 	}
 
+	const PertialSchedule *pPertialScheduleForCatchAddress;
 	const PertialSchedule *pPertialScheduleForFinallyAddress;
 
 public:
-	const PertialSchedule *pPertialScheduleForCatchAddress;
 	TryScope()
-		: isCatched( false )
-		, isDefinedFinally( false )
+		: isDefinedFinally( false )
 	{
 	}
@@ -44,7 +69,11 @@
 	}
 
+	const CatchScopes &GetCatchScopes() const
+	{
+		return catchScopes;
+	}
 	bool IsCatched() const
 	{
-		return isCatched;
+		return ( catchScopes.size() != 0 );
 	}
 	bool IsDefinedFinally() const
@@ -56,4 +85,8 @@
 	{
 		this->pPertialScheduleForCatchAddress = pPertialScheduleForCatchAddress;
+	}
+	const PertialSchedule *GetPertialScheduleForCatchAddress() const
+	{
+		return pPertialScheduleForCatchAddress;
 	}
 	void RegistPertialScheduleForFinallyAddress( const PertialSchedule *pPertialScheduleForFinallyAddress )
@@ -72,5 +105,5 @@
 	}
 
-	void Catch()
+	void Catch( Type &paramType )
 	{
 		if( isDefinedFinally )
@@ -80,7 +113,7 @@
 		}
 
-		isCatched = true;
-
 		JmpFinally();
+
+		catchScopes.push_back( CatchScope( paramType, compiler.codeGenerator.GetNativeCodeSize() ) );
 	}
 	void Finally()
@@ -103,4 +136,48 @@
 			Finally();
 		}
+	}
+
+	int GenerateCatchTable()
+	{
+		int size = static_cast<int>(( (catchScopes.size()+1)*2 ) * sizeof(LONG_PTR));
+		BYTE *buffer = (BYTE *)calloc( size, 1 );
+
+		int pos = 0;
+		BOOST_FOREACH( const CatchScope &catchScope, catchScopes )
+		{
+			// パラメータのクラス名
+			char paramName[VN_SIZE] = "";
+			int paramNameDataTableOffset = 0;
+			if( catchScope.GetParamType().IsObject() )
+			{
+				lstrcpy( paramName, catchScope.GetParamType().GetClass().GetFullName().c_str() );
+			}
+			paramNameDataTableOffset = compiler.GetObjectModule().dataTable.AddString( paramName );
+			*((LONG_PTR *)(buffer+pos)) = paramNameDataTableOffset;
+			pos += sizeof(LONG_PTR);
+
+			// Catchアドレス
+			*((LONG_PTR *)(buffer+pos)) = catchScope.GetCodePos();
+			pos += sizeof(LONG_PTR);
+		}
+
+		int dataTableOffset = compiler.GetObjectModule().dataTable.AddBinary( buffer, size );
+
+		free( buffer );
+
+		pos = 0;
+		BOOST_FOREACH( const CatchScope &catchScope, catchScopes )
+		{
+			// パラメータのクラス名
+			compiler.GetObjectModule().dataTable.schedules.push_back( Schedule( Schedule::DataTable, dataTableOffset + pos ) );
+			pos += sizeof(LONG_PTR);
+
+			// Catchアドレス
+			compiler.GetObjectModule().dataTable.schedules.push_back( Schedule( &UserProc::CompilingUserProc(), dataTableOffset + pos ) );
+			compiler.GetObjectModule().dataTable.schedules.back().SpecifyCatchAddress();
+			pos += sizeof(LONG_PTR);
+		}
+
+		return dataTableOffset;
 	}
 };
@@ -154,10 +231,5 @@
 	}
 
-	// パラメータの扱いが未完成
-
-	tryScopes.back().Catch();
-
-	// _System_GetNowScopeCatchAddressesを解決
-	compiler.codeGenerator.opfix( tryScopes.back().pPertialScheduleForCatchAddress, compiler.codeGenerator.GetNativeCodeSize() );
+	tryScopes.back().Catch( paramType );
 }
 void FinallyCommand()
@@ -185,11 +257,8 @@
 	}
 
-	int backCp = cp;
-
-	if( !tryScopes.back().IsCatched() )
-	{
-		// _System_GetNowScopeCatchAddressesを解決
-		compiler.codeGenerator.opfix( tryScopes.back().pPertialScheduleForCatchAddress, 0 );
-	}
+	int dataTableOffset = tryScopes.back().GenerateCatchTable();
+
+	// _System_GetNowScopeCatchAddressesを解決
+	compiler.codeGenerator.opfix( tryScopes.back().GetPertialScheduleForCatchAddress(), dataTableOffset );
 
 	if( !tryScopes.back().IsDefinedFinally() )
@@ -198,4 +267,6 @@
 		FinallyCommand();
 	}
+
+	int backCp = cp;
 
 	char temporary[1024];
@@ -215,5 +286,12 @@
 
 	char temporary[1024];
-	lstrcpy( temporary, "_System_pobj_AllThreads->GetCurrentException()->_Throw()" );
+	if( Parameter[0] )
+	{
+		sprintf( temporary, "_System_pobj_AllThreads->GetCurrentException()->_ThrowWithParam(%s)", Parameter );
+	}
+	else
+	{
+		lstrcpy( temporary, "_System_pobj_AllThreads->GetCurrentException()->_ThrowNoneParam()" );
+	}
 	MakeMiddleCode( temporary );
 	ChangeOpcode( temporary );
@@ -232,8 +310,8 @@
 #ifdef _WIN64
 	//mov rax,catchAddress
-	const PertialSchedule *pPertialSchedule = compiler.codeGenerator.op_mov_RV( sizeof(long), REG_RAX, 0, Schedule::CatchAddress, true );
+	const PertialSchedule *pPertialSchedule = compiler.codeGenerator.op_mov_RV( sizeof(long), REG_RAX, 0, Schedule::DataTable, true );
 #else
 	//mov eax,catchAddress
-	const PertialSchedule *pPertialSchedule = compiler.codeGenerator.op_mov_RV( REG_EAX, 0, Schedule::CatchAddress, true );
+	const PertialSchedule *pPertialSchedule = compiler.codeGenerator.op_mov_RV( REG_EAX, 0, Schedule::DataTable, true );
 #endif
 
