/*
 *	alloca.h
 *
 *	alloca()丄GNU C偺慻傒崬傒娭悢屳姺婡擻
 *
 *	* Tue Oct 16 11:50:08 JST 2012 Naoyuki Sawa
 *	- 1st 儕儕乕僗丅
 *	- 幚憰偼丄clipalca.c 偵偁傝傑偡丅
 */
#ifndef __ALLOCA_H__
#define __ALLOCA_H__

/*****************************************************************************
 *	alloca
 *****************************************************************************/

/* 帺摦揑偵夝曻偝傟傞儊儌儕傪妱傝摉偰傑偡
 * [in]
 *	size	妱傝摉偰傞儊儌儕偺僶僀僩悢
 * [out]
 *	栠傝抣	妱傝摉偰偨儊儌儕偺傾僪儗僗
 *		妱傝摉偰偵幐攕偟偨応崌丄杮娭悢偼僄儔乕掆巭偟傑偡丅NULL傪曉偡偙偲偼偁傝傑偣傫丅
 * [note]
 *	- pseudo_alloca()偺幚憰偼丄僗僞僢僋忋偵儊儌儕傪妋曐偡傞偺偱側偔丄娭悢偺栠傝傾僪儗僗傪僼僢僋偟偰丄儊儌儕傪奐曻偟傑偡丅
 *	  偦偺偨傔丄杮暔偺alloca()偵偼柍偄丄埲壓偺栤戣揰偑偁傝傑偡丅
 *	  佀alloca()傪屇傃弌偟偨娭悢偑丄setjmp/longjmp偱張棟傪敳偗傞偲丄儊儌儕偑奐曻偝傟側偄丅
 *	- alloca()傪捈愙丄娭悢偲偟偰幚憰偟側偄棟桼偼丄埲壓偺偲偍傝偱偡丅
 *	  昗弨揑側alloca.h偼丄乽#define alloca __builtin_alloca乿偺掕媊傪娷傫偱偄傑偡丅
 *	  傑偨僜僼僩偺拞偵偼丄乽#define alloca __builtin_alloca乿偺掕媊傪慜採偲偟偰偄傞傕偺偑偁傝傑偡丅(GNU Bison version 1.28偑惗惉偡傞丄y.tab.c摍)
 *	  壓婰偺傛偆偵掕媊偡傟偽丄僜僼僩偑帺慜偱乽#define alloca __builtin_alloca乿傪掕媊偟偨偲偟偰傕丄栤戣側偔僐儞僷僀儖偡傞偙偲偑偱偒傑偡丅
 */
#define alloca __builtin_alloca
#define        __builtin_alloca pseudo_alloca
void*                           pseudo_alloca(size_t size);

/*****************************************************************************
 *	GNU C偺慻傒崬傒娭悢屳姺婡擻
 *****************************************************************************/

//FFFFFFFF劇劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劉
//        劆                                      丒                                      劆
//        劆                                      丒                                      劆
//        劆                                      丒                                      劆
//        劌劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劎
//        劆 幚峴拞偺娭悢傪屇傃弌偟偨娭悢傪屇傃弌偟偨娭悢偺栠傝傾僪儗僗                   劆 仼 get_return_address(2) 偑曉偡抣
//        劌劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劎 仼 get_return_address_p(2) 偑曉偡傾僪儗僗
//        劆(幚峴拞偺娭悢傪屇傃弌偟偨娭悢傪屇傃弌偟偨娭悢偑 pushn %rb     偱妋曐偟偨椞堟) 劆
//        劌劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劎
//        劆(幚峴拞偺娭悢傪屇傃弌偟偨娭悢傪屇傃弌偟偨娭悢偑 sub %sp,imm10 偱妋曐偟偨椞堟) 劆
//        劌劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劎 仼 get_frame_address(2) 偑曉偡傾僪儗僗
//        劆 幚峴拞偺娭悢傪屇傃弌偟偨娭悢偺栠傝傾僪儗僗                                   劆 仼 get_return_address(1) 偑曉偡抣
//        劌劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劎 仼 get_return_address_p(1) 偑曉偡傾僪儗僗
//        劆(幚峴拞偺娭悢傪屇傃弌偟偨娭悢偑 pushn %rb     偱妋曐偟偨椞堟)                 劆
//        劌劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劎
//        劆(幚峴拞偺娭悢傪屇傃弌偟偨娭悢偑 sub %sp,imm10 偱妋曐偟偨椞堟)                 劆
//        劌劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劎 仼 get_frame_address(1) 偑曉偡傾僪儗僗
//        劆 幚峴拞偺娭悢偺栠傝傾僪儗僗                                                   劆 仼 get_return_address(0) 偑曉偡抣
//        劌劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劎 仼 get_return_address_p(0) 偑曉偡傾僪儗僗
//        劆(幚峴拞偺娭悢偑 pushn %rb     偱妋曐偟偨椞堟)                                 劆
//        劌劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劎
//        劆(幚峴拞偺娭悢偑 sub %sp,imm10 偱妋曐偟偨椞堟)                                 劆
//        劌劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劎 仼 get_frame_address(0) 偑曉偡傾僪儗僗
//        劆                                      丒                                      劆
//        劆                                      丒                                      劆
//        劆                                      丒                                      劆
//00000000劋劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劅劊

/* 娭悢偺僗僞僢僋僼儗乕儉傾僪儗僗傪庢摼偟傑偡
 * [in]
 *	level	0傪巜掕偡傞偲丄__builtin_frame_address()傪屇傃弌偟偨娭悢偺僗僞僢僋僼儗乕儉傾僪儗僗傪庢摼偟傑偡丅
 *		1傪巜掕偡傞偲丄__builtin_frame_address()傪屇傃弌偟偨娭悢傪丄屇傃弌偟偨娭悢偺僗僞僢僋僼儗乕儉傾僪儗僗傪庢摼偟傑偡丅
 *		2傪巜掕偡傞偲丄__builtin_frame_address()傪屇傃弌偟偨娭悢傪丄屇傃弌偟偨娭悢傪丄屇傃弌偟偨娭悢偺僗僞僢僋僼儗乕儉傾僪儗僗傪庢摼偟傑偡丅
 *		(埲崀摨條偱偁傞偨傔丄愢柧傪徣棯偟傑偡丅)
 * [out]
 *	栠傝抣	娭悢偺僗僞僢僋僼儗乕儉傾僪儗僗
 * [note]
 *	- GNU C偺慻傒崬傒娭悢__builtin_frame_address()偲屳姺偱偡丅
 *	- __builtin_frame_address()傪娭悢偲偟偰幚憰偣偢丄__builtin_frame_address()儅僋儘偲get_frame_address()娭悢偵暘偗偨棟桼偼丄埲壓偺偲偍傝偱偡丅
 *	  P/ECE奐敪娐嫬偺僐儞僷僀儔gcc33偼丄__builtin_frame_address()慻傒崬傒娭悢傪擣幆偟傑偡偑丄娫堘偭偨僐乕僪傪惗惉偡傞偨傔丄巊偭偰偼偄偗傑偣傫丅
 *	  gcc33偵__builtin_frame_address()傪慻傒崬傒娭悢偲偟偰擣幆偝偣側偄傛偆丄儅僋儘偲偟偰掕媊偟丄gcc33傊堷偒搉偡慜偵get_frame_address()偵曄姺偟傑偡丅
 */
#define __builtin_frame_address get_frame_address
void*                           get_frame_address(unsigned int level);

/* 娭悢偺栠傝傾僪儗僗傪庢摼偟傑偡
 * [in]
 *	level	0傪巜掕偡傞偲丄__builtin_return_address()傪屇傃弌偟偨娭悢偺栠傝傾僪儗僗傪庢摼偟傑偡丅
 *		1傪巜掕偡傞偲丄__builtin_return_address()傪屇傃弌偟偨娭悢傪丄屇傃弌偟偨娭悢偺栠傝傾僪儗僗傪庢摼偟傑偡丅
 *		2傪巜掕偡傞偲丄__builtin_return_address()傪屇傃弌偟偨娭悢傪丄屇傃弌偟偨娭悢傪丄屇傃弌偟偨娭悢偺栠傝傾僪儗僗傪庢摼偟傑偡丅
 *		(埲崀摨條偱偁傞偨傔丄愢柧傪徣棯偟傑偡丅)
 * [out]
 *	栠傝抣	娭悢偺栠傝傾僪儗僗
 * [note]
 *	- GNU C偺慻傒崬傒娭悢__builtin_return_address()偲屳姺偱偡丅
 *	- __builtin_return_address()傪娭悢偲偟偰幚憰偣偢丄__builtin_return_address()儅僋儘偲get_return_address()娭悢偵暘偗偨棟桼偼丄埲壓偺偲偍傝偱偡丅
 *	  P/ECE奐敪娐嫬偺僐儞僷僀儔gcc33偼丄__builtin_return_address()慻傒崬傒娭悢傪擣幆偟傑偡偑丄娫堘偭偨僐乕僪傪惗惉偡傞偨傔丄巊偭偰偼偄偗傑偣傫丅
 *	  gcc33偵__builtin_return_address()傪慻傒崬傒娭悢偲偟偰擣幆偝偣側偄傛偆丄儅僋儘偲偟偰掕媊偟丄gcc33傊堷偒搉偡慜偵get_return_address()偵曄姺偟傑偡丅
 */
#define __builtin_return_address get_return_address
void*                            get_return_address(unsigned int level);

/* 娭悢偺栠傝傾僪儗僗偑奿擺偝傟偰偄傞傾僪儗僗傪庢摼偟傑偡
 * [in]
 *	level	0傪巜掕偡傞偲丄get_return_address_p()傪屇傃弌偟偨娭悢偺栠傝傾僪儗僗偑奿擺偝傟偰偄傞傾僪儗僗傪庢摼偟傑偡丅
 *		1傪巜掕偡傞偲丄get_return_address_p()傪屇傃弌偟偨娭悢傪丄屇傃弌偟偨娭悢偺栠傝傾僪儗僗偑奿擺偝傟偰偄傞傾僪儗僗傪庢摼偟傑偡丅
 *		2傪巜掕偡傞偲丄get_return_address_p()傪屇傃弌偟偨娭悢傪丄屇傃弌偟偨娭悢傪丄屇傃弌偟偨娭悢偺栠傝傾僪儗僗偑奿擺偝傟偰偄傞傾僪儗僗傪庢摼偟傑偡丅
 *		(埲崀摨條偱偁傞偨傔丄愢柧傪徣棯偟傑偡丅)
 * [out]
 *	栠傝抣	娭悢偺栠傝傾僪儗僗偑奿擺偝傟偰偄傞傾僪儗僗
 * [note]
 *	- 偙偺婡擻偵懳墳偡傞丄GNU C偺慻傒崬傒娭悢偼偁傝傑偣傫丅
 *	- pseudo_alloca()偺幚憰偵偍偄偰丄娭悢偺栠傝傾僪儗僗傪僼僢僋偡傞偨傔偵昁梫側婡擻偲偟偰丄杮娭悢傪嶌惉偟傑偟偨丅
 */
void** get_return_address_p(unsigned int level);

#endif /*__ALLOCA_H__*/
