Rust 1.64 ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด ๋ฆด๋ฆฌ์Šค

Mozilla ํ”„๋กœ์ ํŠธ์— ์˜ํ•ด ์„ค๋ฆฝ๋˜์—ˆ์ง€๋งŒ ํ˜„์žฌ๋Š” ๋…๋ฆฝ์ ์ธ ๋น„์˜๋ฆฌ ์กฐ์ง์ธ Rust Foundation์˜ ํ›„์›์œผ๋กœ ๊ฐœ๋ฐœ๋œ Rust 1.64 ๋ฒ”์šฉ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์˜ ์ถœ์‹œ๊ฐ€ ๋ฐœํ‘œ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด ์–ธ์–ด๋Š” ๋ฉ”๋ชจ๋ฆฌ ์•ˆ์ „์— ์ค‘์ ์„ ๋‘๊ณ  ๊ฐ€๋น„์ง€ ์ˆ˜์ง‘๊ธฐ ๋ฐ ๋Ÿฐํƒ€์ž„(๋Ÿฐํƒ€์ž„์€ ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ๊ธฐ๋ณธ ์ดˆ๊ธฐํ™” ๋ฐ ์œ ์ง€ ๊ด€๋ฆฌ๋กœ ์ถ•์†Œ๋จ)์˜ ์‚ฌ์šฉ์„ ํ”ผํ•˜๋ฉด์„œ ๋†’์€ ์ž‘์—… ๋ณ‘๋ ฌ์„ฑ์„ ๋‹ฌ์„ฑํ•  ์ˆ˜ ์žˆ๋Š” ์ˆ˜๋‹จ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

Rust์˜ ๋ฉ”๋ชจ๋ฆฌ ์ฒ˜๋ฆฌ ๋ฐฉ๋ฒ•์€ ํฌ์ธํ„ฐ๋ฅผ ์กฐ์ž‘ํ•  ๋•Œ ๊ฐœ๋ฐœ์ž๋ฅผ ์˜ค๋ฅ˜๋กœ๋ถ€ํ„ฐ ๋ณดํ˜ธํ•˜๊ณ  ๋ฉ”๋ชจ๋ฆฌ ์˜์—ญ์ด ํ•ด์ œ๋œ ํ›„ ์•ก์„ธ์Šค, null ํฌ์ธํ„ฐ ์—ญ์ฐธ์กฐ, ๋ฒ„ํผ ์˜ค๋ฒ„๋Ÿฐ ๋“ฑ๊ณผ ๊ฐ™์€ ์ €์ˆ˜์ค€ ๋ฉ”๋ชจ๋ฆฌ ์ฒ˜๋ฆฌ๋กœ ์ธํ•ด ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ๋กœ๋ถ€ํ„ฐ ๋ณดํ˜ธํ•ฉ๋‹ˆ๋‹ค. ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ฐฐํฌ, ๋นŒ๋“œ ์ œ๊ณต ๋ฐ ์ข…์†์„ฑ ๊ด€๋ฆฌ๋ฅผ ์œ„ํ•ด ํ”„๋กœ์ ํŠธ๋Š” Cargo ํŒจํ‚ค์ง€ ๊ด€๋ฆฌ์ž๋ฅผ ๊ฐœ๋ฐœํ•ฉ๋‹ˆ๋‹ค. crates.io ์ €์žฅ์†Œ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํ˜ธ์ŠคํŒ…์„ ์œ„ํ•ด ์ง€์›๋ฉ๋‹ˆ๋‹ค.

๋ฉ”๋ชจ๋ฆฌ ์•ˆ์ „์€ ์ปดํŒŒ์ผ ์‹œ๊ฐ„์— ์ฐธ์กฐ ํ™•์ธ, ๊ฐœ์ฒด ์†Œ์œ ๊ถŒ ์ถ”์ , ๊ฐœ์ฒด ์ˆ˜๋ช…(๋ฒ”์œ„) ์ถ”์  ๋ฐ ์ฝ”๋“œ ์‹คํ–‰ ์ค‘ ๋ฉ”๋ชจ๋ฆฌ ์•ก์„ธ์Šค์˜ ์ •ํ™•์„ฑ ํ‰๊ฐ€๋ฅผ ํ†ตํ•ด Rust์—์„œ ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค. Rust๋Š” ๋˜ํ•œ ์ •์ˆ˜ ์˜ค๋ฒ„ํ”Œ๋กœ์— ๋Œ€ํ•œ ๋ณดํ˜ธ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๊ณ , ์‚ฌ์šฉํ•˜๊ธฐ ์ „์— ๋ณ€์ˆ˜ ๊ฐ’์˜ ํ•„์ˆ˜ ์ดˆ๊ธฐํ™”๊ฐ€ ํ•„์š”ํ•˜๋ฉฐ, ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ์˜ค๋ฅ˜๋ฅผ ๋” ์ž˜ ์ฒ˜๋ฆฌํ•˜๊ณ , ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ถˆ๋ณ€ ์ฐธ์กฐ ๋ฐ ๋ณ€์ˆ˜ ๊ฐœ๋…์„ ์ ์šฉํ•˜๊ณ , ๊ฐ•๋ ฅํ•œ ์ •์  ์œ ํ˜• ์ง€์ •์„ ์ œ๊ณตํ•˜์—ฌ ๋…ผ๋ฆฌ์  ์˜ค๋ฅ˜๋ฅผ ์ตœ์†Œํ™”ํ•ฉ๋‹ˆ๋‹ค.

์ฃผ์š” ํ˜์‹ :

  • ์ปดํŒŒ์ผ๋Ÿฌ, Cargo ํŒจํ‚ค์ง€ ๊ด€๋ฆฌ์ž ๋ฐ libstd ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ Linux ํ™˜๊ฒฝ์— ๋Œ€ํ•œ ์š”๊ตฌ ์‚ฌํ•ญ์ด ์ฆ๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. Glibc์— ๋Œ€ํ•œ ์ตœ์†Œ ์š”๊ตฌ ์‚ฌํ•ญ์€ ๋ฒ„์ „ 2.11์—์„œ 2.17๋กœ, Linux ์ปค๋„์€ ๋ฒ„์ „ 2.6.32์—์„œ 3.2๋กœ ์ฆ๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ œํ•œ์‚ฌํ•ญ์€ libstd๋กœ ๋นŒ๋“œ๋œ Rust ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹คํ–‰ ํŒŒ์ผ์—๋„ ์ ์šฉ๋ฉ๋‹ˆ๋‹ค. ๋ฐฐํฌ ํ‚คํŠธ RHEL 7, SLES 12-SP5, Debian 8 ๋ฐ Ubuntu 14.04๋Š” ์ƒˆ๋กœ์šด ์š”๊ตฌ ์‚ฌํ•ญ์„ ์ถฉ์กฑํ•ฉ๋‹ˆ๋‹ค. RHEL 6, SLES 11-SP4, Debian 7 ๋ฐ Ubuntu 12.04์— ๋Œ€ํ•œ ์ง€์›์ด ์ค‘๋‹จ๋ฉ๋‹ˆ๋‹ค. ์ด์ „ Linux ์ปค๋„์ด ์žˆ๋Š” ํ™˜๊ฒฝ์—์„œ Rust ๊ธฐ๋ฐ˜ ์‹คํ–‰ ํŒŒ์ผ์„ ์‚ฌ์šฉํ•˜๋Š” ์‚ฌ์šฉ์ž๋Š” ์‹œ์Šคํ…œ์„ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๊ฑฐ๋‚˜, ์ด์ „ ๋ฒ„์ „์˜ ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ์œ ์ง€ํ•˜๊ฑฐ๋‚˜, ํ˜ธํ™˜์„ฑ์„ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ๊ณ„์ธต์ด ์žˆ๋Š” ์ž์ฒด libstd ํฌํฌ๋ฅผ ์œ ์ง€ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

    ์ด์ „ Linux ์‹œ์Šคํ…œ์— ๋Œ€ํ•œ ์ง€์›์„ ์ข…๋ฃŒํ•˜๋Š” ์ด์œ  ์ค‘์—๋Š” ์ด์ „ ํ™˜๊ฒฝ๊ณผ์˜ ํ˜ธํ™˜์„ฑ์„ ๊ณ„์† ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•œ ๋ฆฌ์†Œ์Šค๊ฐ€ ์ œํ•œ๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋ ˆ๊ฑฐ์‹œ Glibc๋ฅผ ์ง€์›ํ•˜๋ ค๋ฉด LLVM ๋ฐ ํฌ๋กœ์Šค ์ปดํŒŒ์ผ ์œ ํ‹ธ๋ฆฌํ‹ฐ์˜ ๋ฒ„์ „ ์š”๊ตฌ ์‚ฌํ•ญ์ด ์ฆ๊ฐ€ํ•จ์— ๋”ฐ๋ผ ์ง€์†์ ์ธ ํ†ตํ•ฉ ์‹œ์Šคํ…œ์„ ์ฒดํฌ์ธํ•  ๋•Œ ๋ ˆ๊ฑฐ์‹œ ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ปค๋„ ๋ฒ„์ „ ์š”๊ตฌ ์‚ฌํ•ญ์ด ์ฆ๊ฐ€ํ•œ ์ด์œ ๋Š” ์ด์ „ ์ปค๋„๊ณผ์˜ ํ˜ธํ™˜์„ฑ์„ ๋ณด์žฅํ•˜๊ธฐ ์œ„ํ•ด ๊ณ„์ธต์„ ์œ ์ง€ํ•  ํ•„์š” ์—†์ด libstd์—์„œ ์ƒˆ๋กœ์šด ์‹œ์Šคํ…œ ํ˜ธ์ถœ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

  • IntoFuture ํŠน์„ฑ์€ ์•ˆ์ •ํ™”๋˜์–ด IntoIterator์™€ ์œ ์‚ฌํ•˜์ง€๋งŒ "for ... in ..." ๋ฃจํ”„ ๋Œ€์‹  ".await"๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋Š” ์ ์—์„œ ํ›„์ž์™€ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. IntoFuture์™€ ๊ฒฐํ•ฉํ•˜๋ฉด ".await" ํ‚ค์›Œ๋“œ๋Š” Future ํŠน์„ฑ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ Future๋กœ ๋ณ€ํ™˜๋  ์ˆ˜ ์žˆ๋Š” ๋‹ค๋ฅธ ์œ ํ˜•๋„ ๊ธฐ๋Œ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • Rust-analyzer ์œ ํ‹ธ๋ฆฌํ‹ฐ๋Š” Rust ๋ฆด๋ฆฌ์Šค์™€ ํ•จ๊ป˜ ์ œ๊ณต๋˜๋Š” ์œ ํ‹ธ๋ฆฌํ‹ฐ ๋ชจ์Œ์— ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ์œ ํ‹ธ๋ฆฌํ‹ฐ๋Š” Rustup(Rustup ๊ตฌ์„ฑ ์š”์†Œ์— Rust-Analyzer ์ถ”๊ฐ€)์„ ์‚ฌ์šฉํ•˜์—ฌ ์„ค์น˜ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
  • Cargo ํŒจํ‚ค์ง€ ๊ด€๋ฆฌ์ž์—๋Š” Rust ๋ฒ„์ „ ๋ฐ ์ €์žฅ์†Œ URL๊ณผ ๊ฐ™์€ ํŒจํ‚ค์ง€ ๊ฐ„ ๊ณตํ†ต ํ•„๋“œ ๊ฐ’์˜ ์ค‘๋ณต์„ ์ œ๊ฑฐํ•˜๊ธฐ ์œ„ํ•ด ์ž‘์—…๊ณต๊ฐ„ ์ƒ์†์ด ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ํ•œ ๋ฒˆ์— ์—ฌ๋Ÿฌ ๋Œ€์ƒ ํ”Œ๋žซํผ์„ ๋นŒ๋“œํ•˜๊ธฐ ์œ„ํ•œ ์ง€์›๋„ ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค(์ด์ œ "--target" ์˜ต์…˜์— ๋‘˜ ์ด์ƒ์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค).
  • API์˜ ์ƒˆ๋กœ์šด ๋ถ€๋ถ„์ด ์•ˆ์ •ํ™”๋œ ํŠน์„ฑ์˜ ๋ฉ”์„œ๋“œ ๋ฐ ๊ตฌํ˜„์„ ํฌํ•จํ•˜์—ฌ ์•ˆ์ •์ ์ธ ๋ฒ”์ฃผ๋กœ ์ด๋™๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
    • ๋ฏธ๋ž˜::์ธํˆฌํ“จ์ฒ˜
    • ์ˆซ์ž::NonZero*::checked_mul
    • ์ˆซ์ž::NonZero*::checked_pow
    • ์ˆซ์ž::NonZero*::saturating_mul
    • ์ˆซ์ž::NonZero*::saturating_pow
    • ์ˆซ์ž::NonZeroI*::abs
    • ์ˆซ์ž::NonZeroI*::checked_abs
    • ์ˆซ์ž::NonZeroI*::overflowing_abs
    • ์ˆซ์ž::NonZeroI*::saturating_abs
    • ์ˆซ์ž::NonZeroI*::unsigned_abs
    • ์ˆซ์ž::NonZeroI*::wrapping_abs
    • ์ˆซ์ž::NonZeroU*::checked_add
    • ์ˆซ์ž::NonZeroU*::checked_next_power_of_two
    • ์ˆซ์ž::NonZeroU*::saturating_add
    • os::unix::ํ”„๋กœ์„ธ์Šค::CommandExt::process_group
    • os::windows::fs::FileTypeExt::is_symlink_dir
    • os::windows::fs::FileTypeExt::is_symlink_file
  • ์ด์ „์— std::ffi ๋ชจ๋“ˆ์—์„œ ์•ˆ์ •ํ™”๋œ C ํ˜ธํ™˜ ์œ ํ˜•์ด ์ฝ”์–ด ๋ฐ alloc ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
    • ์ฝ”์–ด::ffi::CStr
    • ์ฝ”์–ด::ffi::FromBytesWithNulError
    • ํ• ๋‹น::ffi::CString
    • alloc::ffi::FromVecWithNulError
    • alloc::ffi::IntoStringError
    • ํ• ๋‹น::ffi::NulError
  • ์ด์ „์— std::os::raw ๋ชจ๋“ˆ์—์„œ ์•ˆ์ •ํ™”๋œ C ์œ ํ˜•์ด core::ffi ๋ฐ std::ffi ๋ชจ๋“ˆ์— ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค(์˜ˆ๋ฅผ ๋“ค์–ด uint ๋ฐ ulong C ์œ ํ˜•์— ๋Œ€ํ•ด c_uint ๋ฐ c_ulong ์œ ํ˜•์ด ์ œ์•ˆ๋˜์—ˆ์Šต๋‹ˆ๋‹ค).
    • ffi::c_char
    • ffi::c_double
    • ffi::c_float
    • ffi::c_int
    • ffi::c_long
    • ffi::c_longlong
    • ffi::c_schar
    • ffi::c_short
    • ffi::c_uchar
    • ffi::c_uint
    • ffi::c_ulong
    • ffi::c_ulonglong
    • ffi::c_ushort
  • Poll ๋ฉ”์ปค๋‹ˆ์ฆ˜๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜์œ„ ์ˆ˜์ค€ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ์•ˆ์ •ํ™”๋˜์—ˆ์Šต๋‹ˆ๋‹ค(ํ–ฅํ›„์—๋Š” Pull ๋ฐ Pin๊ณผ ๊ฐ™์€ ํ•˜์œ„ ์ˆ˜์ค€ ๊ตฌ์กฐ๋ฅผ ์‚ฌ์šฉํ•  ํ•„์š”๊ฐ€ ์—†๋Š” ๋‹จ์ˆœํ™”๋œ API๋ฅผ ์ œ๊ณตํ•  ๊ณ„ํš์ž…๋‹ˆ๋‹ค).

    • ๋ฏธ๋ž˜::poll_fn
    • ์ž‘์—…::์ค€๋น„!
  • ์ƒ์ˆ˜ ๋Œ€์‹  ๋ชจ๋“  ์ปจํ…์ŠคํŠธ์—์„œ ์‚ฌ์šฉํ•  ๊ฐ€๋Šฅ์„ฑ์„ ๊ฒฐ์ •ํ•˜๋Š” "const" ์†์„ฑ์€ Slice::from_raw_parts ํ•จ์ˆ˜์—์„œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
  • ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด๋‹ค ์ปดํŒฉํŠธํ•˜๊ฒŒ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•ด Ipv4Addr, Ipv6Addr, SocketAddrV4 ๋ฐ SocketAddrV6 ๊ตฌ์กฐ์˜ ๋ฉ”๋ชจ๋ฆฌ ๋ ˆ์ด์•„์›ƒ์ด ๋ณ€๊ฒฝ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋‚ฎ์€ ์ˆ˜์ค€์˜ ๊ตฌ์กฐ ์กฐ์ž‘์„ ์œ„ํ•ด std::mem::transmute๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋‹จ์ผ ํฌ๋ ˆ์ดํŠธ ํŒจํ‚ค์ง€์—๋Š” ํ˜ธํ™˜์„ฑ ๋ฌธ์ œ๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • Windows ํ”Œ๋žซํผ์šฉ Rust ์ปดํŒŒ์ผ๋Ÿฌ ๋นŒ๋“œ์—์„œ๋Š” PGO ์ตœ์ ํ™”(ํ”„๋กœํŒŒ์ผ ๊ธฐ๋ฐ˜ ์ตœ์ ํ™”)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ฝ”๋“œ ์ปดํŒŒ์ผ ์„ฑ๋Šฅ์„ 10-20% ํ–ฅ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ํŠน์ • ๊ตฌ์กฐ์—์„œ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ํ•„๋“œ์— ๋Œ€ํ•œ ์ƒˆ๋กœ์šด ๊ฒฝ๊ณ ๋ฅผ ๊ตฌํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ gccrs ํ”„๋กœ์ ํŠธ(GCC Rust)์—์„œ ์ค€๋น„ํ•˜๊ณ  GCC์— ํฌํ•จํ•˜๋„๋ก ์Šน์ธ๋œ Rust ์–ธ์–ด ์ปดํŒŒ์ผ๋Ÿฌ์˜ ๋Œ€์ฒด ๊ตฌํ˜„ ๊ฐœ๋ฐœ์— ๋Œ€ํ•œ ์ƒํƒœ ๋ณด๊ณ ์„œ๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ”„๋ŸฐํŠธ์—”๋“œ๋ฅผ ํ†ตํ•ฉํ•œ ํ›„ ํ‘œ์ค€ GCC ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด LLVM ๊ฐœ๋ฐœ์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌ์ถ•๋œ Rustc ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ์„ค์น˜ํ•  ํ•„์š” ์—†์ด Rust ์–ธ์–ด๋กœ ํ”„๋กœ๊ทธ๋žจ์„ ์ปดํŒŒ์ผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ์ด ์ˆœ์กฐ๋กญ๊ฒŒ ์ง„ํ–‰๋˜๊ณ  ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š” ํ•œ, Rust ํ”„๋ŸฐํŠธ์—”๋“œ๋Š” ๋‚ด๋…„ 13์›”๋กœ ์˜ˆ์ •๋œ GCC 13 ๋ฆด๋ฆฌ์Šค์— ํ†ตํ•ฉ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. Rust์˜ GCC XNUMX ๊ตฌํ˜„์€ ๋ฒ ํƒ€ ์ƒํƒœ์ด๋ฉฐ ์•„์ง ๊ธฐ๋ณธ์ ์œผ๋กœ ํ™œ์„ฑํ™”๋˜์–ด ์žˆ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ถœ์ฒ˜ : opennet.ru

์ฝ”๋ฉ˜ํŠธ๋ฅผ ์ถ”๊ฐ€