Esempio n. 1
0
void code_term()
{
#if TERMCODE
    code *cn;
    int count = 0;

    while (code_list)
    {   cn = code_next(code_list);
        mem_ffree(code_list);
        code_list = cn;
        count++;
    }
#ifdef DEBUG
    printf("Max # of codes = %d\n",count);
#endif
#else
#ifdef DEBUG
    int count = 0;

    for (code *cn = code_list; cn; cn = code_next(cn))
        count++;
    printf("Max # of codes = %d\n",count);
#endif
#endif
}
Esempio n. 2
0
static int cmdfunc( int cmd )
{
	//		実行処理 (命令実行時に呼ばれます)
	//
	code_next();							// 次のコードを取得(最初に必ず必要です)

	switch( cmd ) {							// サブコマンドごとの分岐
		case 0x00: hsplua_cmd::hl_newstate();             break;
		case 0x01: hsplua_cmd::hl_switchstate();          break;
		case 0x02: hsplua_cmd::hl_close();                break;
		case 0x04: hsplua_cmd::hl_gccollect();            break;
		case 0x05: hsplua_cmd::hl_gcgen();                break;
		case 0x06: hsplua_cmd::hl_gcinc();                break;
		case 0x07: hsplua_cmd::hl_gcrestart();            break;
		case 0x08: hsplua_cmd::hl_gcsetpause();           break;
		case 0x09: hsplua_cmd::hl_gcsetstepmul();         break;
		case 0x0a: hsplua_cmd::hl_gcstep();               break;
		case 0x0b: hsplua_cmd::hl_gcstop();               break;
		case 0x10: hsplua_cmd::hl_pop();                  break;
		case 0x11: hsplua_cmd::hl_pushboolean();          break;
		case 0x12: hsplua_cmd::hl_pushfunction();         break;
		case 0x13: hsplua_cmd::hl_pushinteger();          break;
		case 0x14: hsplua_cmd::hl_pushlightuserdata();    break;
		case 0x15: hsplua_cmd::hl_pushlstring();          break;
		case 0x16: hsplua_cmd::hl_pushnil();              break;
		case 0x17: hsplua_cmd::hl_pushnumber();           break;
		case 0x18: hsplua_cmd::hl_pushstring();           break;
		case 0x19: hsplua_cmd::hl_pushvalue();            break;
		case 0x1a: hsplua_cmd::hl_pushvarptr();           break;
		default: puterror( HSPERR_UNSUPPORTED_FUNCTION ); break;
	}
	return RUNMODE_RUN;
}
Esempio n. 3
0
static void *reffunc( int *type_res, int cmd )
{
	//		関数・システム変数の実行処理 (値の参照時に呼ばれます)
	//

	int answerType = 0;

	//			'('で始まるかを調べる
	//
	if ( *type != TYPE_MARK ) puterror( HSPERR_INVALID_FUNCPARAM );
	if ( *val != '(' ) puterror( HSPERR_INVALID_FUNCPARAM );
	code_next();

	switch( cmd ) {							// サブコマンドごとの分岐
		case 0x80: *type_res = hsplua_func::hl_isboolean();       break;
		case 0x81: *type_res = hsplua_func::hl_iscfunction();     break;
		case 0x82: *type_res = hsplua_func::hl_isfunction();      break;
		case 0x83: *type_res = hsplua_func::hl_islightuserdata(); break;
		case 0x84: *type_res = hsplua_func::hl_isnil();           break;
		case 0x85: *type_res = hsplua_func::hl_isnone();          break;
		case 0x86: *type_res = hsplua_func::hl_isnoneornil();     break;
		case 0x87: *type_res = hsplua_func::hl_isnumber();        break;
		case 0x88: *type_res = hsplua_func::hl_isstring();        break;
		case 0x89: *type_res = hsplua_func::hl_istable();         break;
		case 0x8a: *type_res = hsplua_func::hl_isthread();        break;
		case 0x8b: *type_res = hsplua_func::hl_isuserdata();      break;
		case 0x90: *type_res = hsplua_func::hl_toboolean();       break;
		case 0x91: *type_res = hsplua_func::hl_tocfunction();     break;
		case 0x92: *type_res = hsplua_func::hl_tointeger();       break;
		case 0x93: *type_res = hsplua_func::hl_tonumber();        break;
		case 0x94: *type_res = hsplua_func::hl_topointer();       break;
		case 0x95: *type_res = hsplua_func::hl_tostring();        break;
		case 0x96: *type_res = hsplua_func::hl_touserdata();      break;
		case 0x98: *type_res = hsplua_func::hl_gccount();         break;
		case 0x99: *type_res = hsplua_func::hl_gcisrunning();     break;
		default: puterror( HSPERR_UNSUPPORTED_FUNCTION );         break;
	}

	//			'('で終わるかを調べる
	//
	if ( *type != TYPE_MARK ) puterror( HSPERR_INVALID_FUNCPARAM );
	if ( *val != ')' ) puterror( HSPERR_INVALID_FUNCPARAM );
	code_next();

	return (void *)&ref_val;
}
Esempio n. 4
0
static void *reffunc_function( int *type_res, int arg )
{
    void *ptr;
    
    //		返値のタイプを設定する
    //
    *type_res = HSPVAR_FLAG_INT;			// 返値のタイプを指定する
    ptr = &reffunc_intfunc_ivalue;			// 返値のポインタ
    
    //			'('で始まるかを調べる
    //
    if ( *type != TYPE_MARK ) throw HSPERR_INVALID_FUNCPARAM;
    if ( *val != '(' ) throw HSPERR_INVALID_FUNCPARAM;
    code_next();
    
    switch( arg & 0xff ) {
            
            //	int function
            
        case 0x002:								// dirinfo
            p1 = code_geti();
            ptr = getdir( p1 );
            *type_res = HSPVAR_FLAG_STR;
            break;
            
        case 0x003:								// sysinfo
            p1 = code_geti();
            *type_res = sysinfo( p1 );
            ptr = ctx->stmp;
            break;
            
        default:
            throw HSPERR_UNSUPPORTED_FUNCTION;
    }
    
    //			')'で終わるかを調べる
    //
    if ( *type != TYPE_MARK ) throw HSPERR_INVALID_FUNCPARAM;
    if ( *val != ')' ) throw HSPERR_INVALID_FUNCPARAM;
    code_next();
    
    return ptr;
}
Esempio n. 5
0
static int cmdfunc_ax2dllcmd(int cmd)
{
	code_next();
	switch ( cmd )
	{
	case 0x000:
		code_gets();
		code_gets();
		code_gets();
		code_next();
		break;
	case 0x001:
		code_gets();
		break;
	default:
		throw HSPERR_UNSUPPORTED_FUNCTION;
	}
	return 0;
}
Esempio n. 6
0
void code_free(code *cstart)
{   code **pc;
    code *c;

    for (pc = &cstart; (c = *pc) != NULL; pc = &code_next(c))
    {
        if (c->Iop == ASM)
        {
            mem_free(c->IEV1.as.bytes);
        }
    }
    *pc = code_list;
    code_list = cstart;
}
Esempio n. 7
0
code *code_calloc()
{   code *c;
    static code czero;

    //printf("code %x\n", sizeof(code));
    c = code_list;
    if (c)
        code_list = code_next(c);
    else
        c = (code *)mem_fmalloc(sizeof(*c));
    *c = czero;                         // zero it out
    //dbg_printf("code_calloc: %p\n",c);
    return c;
}
Esempio n. 8
0
static void *reffunc_dllcmd( int *type_res, int arg )
{
	//		reffunc : TYPE_DLLFUNC
	//		(拡張DLL関数)
	//

	//			'('で始まるかを調べる
	//
	if ( *type != TYPE_MARK ) throw ( HSPERR_INVALID_FUNCPARAM );
	if ( *val != '(' ) throw ( HSPERR_INVALID_FUNCPARAM );

	*type_res = HSPVAR_FLAG_INT;
	exec_dllcmd( arg, STRUCTDAT_OT_FUNCTION );
	reffunc_intfunc_ivalue = hspctx->stat;

	//			')'で終わるかを調べる
	//
	if ( *type != TYPE_MARK ) throw ( HSPERR_INVALID_FUNCPARAM );
	if ( *val != ')' ) throw ( HSPERR_INVALID_FUNCPARAM );
	code_next();

	return &reffunc_intfunc_ivalue;
}
Esempio n. 9
0
void except_fillInEHTable(symbol *s)
{
    unsigned fsize = NPTRSIZE;             // target size of function pointer
    dt_t **pdt = &s->Sdt;

    /*
        void*           pointer to start of function (Windows)
        unsigned        offset of ESP from EBP
        unsigned        offset from start of function to return code
        unsigned nguards;       // dimension of guard[] (Linux)
        Guard guard[];          // sorted such that the enclosing guarded sections come first
      catchoffset:
        unsigned ncatches;      // number of catch blocks
        {   void *type;         // symbol representing type
            unsigned bpoffset;  // EBP offset of catch variable
            void *handler;      // catch handler code
        } catch[];
     */

/* Be careful of this, as we need the sizeof Guard on the target, not
 * in the compiler.
 */
    unsigned GUARD_SIZE;
    if (config.ehmethod == EH_DM)
        GUARD_SIZE = (I64 ? 3*8 : 5*4);
    else if (config.ehmethod == EH_WIN32)
        GUARD_SIZE = 3*4;
    else
        assert(0);

    int sz = 0;

    // Address of start of function
    if (config.ehmethod == EH_WIN32)
    {
        symbol_debug(funcsym_p);
        pdt = dtxoff(pdt,funcsym_p,0,TYnptr);
        sz += fsize;
    }

    //printf("ehtables: func = %s, offset = x%x, startblock->Boffset = x%x\n", funcsym_p->Sident, funcsym_p->Soffset, startblock->Boffset);

    // Get offset of ESP from EBP
    long spoff = cod3_spoff();
    pdt = dtdword(pdt,spoff);
    sz += 4;

    // Offset from start of function to return code
    pdt = dtdword(pdt,retoffset);
    sz += 4;

    // First, calculate starting catch offset
    int guarddim = 0;                               // max dimension of guard[]
    int ndctors = 0;                                // number of ESCdctor's
    for (block *b = startblock; b; b = b->Bnext)
    {
        if (b->BC == BC_try && b->Bscope_index >= guarddim)
            guarddim = b->Bscope_index + 1;
//      printf("b->BC = %2d, Bscope_index = %2d, last_index = %2d, offset = x%x\n",
//              b->BC, b->Bscope_index, b->Blast_index, b->Boffset);
        if (usednteh & EHcleanup)
            for (code *c = b->Bcode; c; c = code_next(c))
            {
                if (c->Iop == (ESCAPE | ESCddtor))
                    ndctors++;
            }
    }
    //printf("guarddim = %d, ndctors = %d\n", guarddim, ndctors);

    if (config.ehmethod == EH_DM)
    {
        pdt = dtsize_t(pdt,guarddim + ndctors);
        sz += NPTRSIZE;
    }

    unsigned catchoffset = sz + (guarddim + ndctors) * GUARD_SIZE;

    // Generate guard[]
    int i = 0;
    for (block *b = startblock; b; b = b->Bnext)
    {
        //printf("b = %p, b->Btry = %p, b->offset = %x\n", b, b->Btry, b->Boffset);
        if (b->BC == BC_try)
        {
            assert(b->Bscope_index >= i);
            if (i < b->Bscope_index)
            {   int fillsize = (b->Bscope_index - i) * GUARD_SIZE;
                pdt = dtnzeros(pdt, fillsize);
                sz += fillsize;
            }
            i = b->Bscope_index + 1;

            int nsucc = b->numSucc();

            if (config.ehmethod == EH_DM)
            {
            //printf("DHandlerInfo: offset = %x", (int)(b->Boffset - startblock->Boffset));
            pdt = dtdword(pdt,b->Boffset - startblock->Boffset);        // offset to start of block

            // Compute ending offset
            unsigned endoffset;
            for (block *bn = b->Bnext; 1; bn = bn->Bnext)
            {
                //printf("\tbn = %p, bn->Btry = %p, bn->offset = %x\n", bn, bn->Btry, bn->Boffset);
                assert(bn);
                if (bn->Btry == b->Btry)
                {    endoffset = bn->Boffset - startblock->Boffset;
                     break;
                }
            }
            //printf(" endoffset = %x, prev_index = %d\n", endoffset, b->Blast_index);
            pdt = dtdword(pdt,endoffset);               // offset past end of guarded block
            }

            pdt = dtdword(pdt,b->Blast_index);          // parent index

            if (b->jcatchvar)                           // if try-catch
            {
                assert(catchoffset);
                pdt = dtdword(pdt,catchoffset);
                pdt = dtsize_t(pdt,0);                  // no finally handler

                catchoffset += NPTRSIZE + (nsucc - 1) * (3 * NPTRSIZE);
            }
            else                                        // else try-finally
            {
                assert(nsucc == 2);
                pdt = dtdword(pdt,0);           // no catch offset
                block *bhandler = b->nthSucc(1);
                assert(bhandler->BC == BC_finally);
                // To successor of BC_finally block
                bhandler = bhandler->nthSucc(0);
                // finally handler address
                if (config.ehmethod == EH_DM)
                {
                    assert(bhandler->Boffset > startblock->Boffset);
                    pdt = dtsize_t(pdt,bhandler->Boffset - startblock->Boffset);    // finally handler offset
                }
                else
                    pdt = dtcoff(pdt,bhandler->Boffset);
            }
            sz += GUARD_SIZE;
        }
    }

    /* Append to guard[] the guard blocks for temporaries that are created and destroyed
     * within a single expression. These are marked by the special instruction pairs
     * (ESCAPE | ESCdctor) and (ESCAPE | ESCddtor).
     */
    if (usednteh & EHcleanup)
    {
        #define STACKINC 16
        int stackbuf[STACKINC];
        int *stack = stackbuf;
        int stackmax = STACKINC;

    int scopeindex = guarddim;
    for (block *b = startblock; b; b = b->Bnext)
    {
        /* Set up stack of scope indices
         */
        stack[0] = b->Btry ? b->Btry->Bscope_index : -1;
        int stacki = 1;

        unsigned boffset = b->Boffset;
        for (code *c = b->Bcode; c; c = code_next(c))
        {
            if (c->Iop == (ESCAPE | ESCdctor))
            {
                code *c2 = code_next(c);
                if (config.flags2 & CFG2seh)
                    nteh_patchindex(c2, scopeindex);
                if (config.ehmethod == EH_DM)
                    pdt = dtdword(pdt,boffset - startblock->Boffset); // guard offset
                // Find corresponding ddtor instruction
                int n = 0;
                unsigned eoffset = boffset;
                unsigned foffset;
                for (; 1; c2 = code_next(c2))
                {
                    // Bugzilla 13720: optimizer might elide the corresponding ddtor
                    if (!c2)
                        goto Lnodtor;

                    if (c2->Iop == (ESCAPE | ESCddtor))
                    {
                        if (n)
                            n--;
                        else
                        {
                            foffset = eoffset;
                            code *cf = code_next(c2);
                            if (config.flags2 & CFG2seh)
                            {
                                nteh_patchindex(cf, stack[stacki - 1]);
                                foffset += calccodsize(cf);
                                cf = code_next(cf);
                            }
                            foffset += calccodsize(cf);
                            while (!cf->isJumpOP())
                            {
                                cf = code_next(cf);
                                foffset += calccodsize(cf);
                            }
                            // issue 9438
                            //cf = code_next(cf);
                            //foffset += calccodsize(cf);
                            if (config.ehmethod == EH_DM)
                                pdt = dtdword(pdt,eoffset - startblock->Boffset); // guard offset
                            break;
                        }
                    }
                    else if (c2->Iop == (ESCAPE | ESCdctor))
                    {
                        n++;
                    }
                    else
                        eoffset += calccodsize(c2);
                }
                //printf("boffset = %x, eoffset = %x, foffset = %x\n", boffset, eoffset, foffset);
                pdt = dtdword(pdt,stack[stacki - 1]);   // parent index
                pdt = dtdword(pdt,0);           // no catch offset
                if (config.ehmethod == EH_DM)
                {
                    assert(foffset > startblock->Boffset);
                    pdt = dtsize_t(pdt,foffset - startblock->Boffset);    // finally handler offset
                }
                else
                    pdt = dtcoff(pdt,foffset);  // finally handler address
                if (stacki == stackmax)
                {   // stack[] is out of space; enlarge it
                    int *pi = (int *)malloc((stackmax + STACKINC) * sizeof(int));
                    assert(pi);
                    memcpy(pi, stack, stackmax * sizeof(int));
                    if (stack != stackbuf)
                        free(stack);
                    stack = pi;
                    stackmax += STACKINC;
                }
                stack[stacki++] = scopeindex;
                ++scopeindex;
                sz += GUARD_SIZE;
            }
            else if (c->Iop == (ESCAPE | ESCddtor))
            {
                stacki--;
                assert(stacki != 0);
            }
        Lnodtor:
            boffset += calccodsize(c);
        }
    }
        if (stack != stackbuf)
            free(stack);
    }

    // Generate catch[]
    for (block *b = startblock; b; b = b->Bnext)
    {
        if (b->BC == BC_try && b->jcatchvar)         // if try-catch
        {
            int nsucc = b->numSucc();
            pdt = dtsize_t(pdt,nsucc - 1);           // # of catch blocks
            sz += NPTRSIZE;

            for (int i = 1; i < nsucc; ++i)
            {
                block *bcatch = b->nthSucc(i);

                pdt = dtxoff(pdt,bcatch->Bcatchtype,0,TYnptr);

                pdt = dtsize_t(pdt,cod3_bpoffset(b->jcatchvar));     // EBP offset

                // catch handler address
                if (config.ehmethod == EH_DM)
                {
                    assert(bcatch->Boffset > startblock->Boffset);
                    pdt = dtsize_t(pdt,bcatch->Boffset - startblock->Boffset);  // catch handler offset
                }
                else
                    pdt = dtcoff(pdt,bcatch->Boffset);

                sz += 3 * NPTRSIZE;
            }
        }
    }
    assert(sz != 0);
}
Esempio n. 10
0
static int cmdfunc_extcmd( int cmd )
{
    //		cmdfunc : TYPE_EXTCMD
    //		(内蔵GUIコマンド)
    //
    code_next();							// 次のコードを取得(最初に必ず必要です)
    switch( cmd ) {							// サブコマンドごとの分岐
            
        case 0x02:								// exec
        {
            char *ps;
            char fname[HSP_MAX_PATH];
            strncpy( fname, code_gets(), HSP_MAX_PATH-1 );
            p1 = code_getdi( 0 );
            ps = code_getds( "" );
            ExecFile( fname, ps, p1 );
            break;
        }
            
        case 0x03:								// dialog
            cmdfunc_dialog();
            break;
            
        case 0x0f:								// mes,print
        {
            //char stmp[1024];
            char *ptr;
            int chk;
            chk = code_get();
            if ( chk<=PARAM_END ) {
                printf( "¥n" );
                break;
            }
            ptr = (char *)(HspVarCorePtr(mpval));
            if ( mpval->flag != HSPVAR_FLAG_STR ) {
                ptr = (char *)HspVarCoreCnv( mpval->flag, HSPVAR_FLAG_STR, ptr );	// 型が一致しない場合は変換
            }
            printf( "%s¥n",ptr );
            //strsp_ini();
            //while(1) {
            //	chk = strsp_get( ptr, stmp, 0, 1022 );
            //	printf( "%s¥n",stmp );
            //	if ( chk == 0 ) break;
            //}
            break;
        }
            
        case 0x27:								// input (console)
        {
            PVal *pval;
            APTR aptr;
            char *pp2;
            char *vptr;
            int strsize;
            int a;
            strsize = 0;
            aptr = code_getva( &pval );
            //pp2 = code_getvptr( &pval, &size );
            p2 = code_getdi( 0x4000 );
            p3 = code_getdi( 0 );
            
            if ( p2 < 64 ) p2 = 64;
            pp2 = code_stmp( p2+1 );
            
            switch( p3 & 15 ) {
                case 0:
                    while(1) {
                        if ( p2<=0 ) break;
                        a = getchar();
                        if ( a==EOF ) break;
                        *pp2++ = a;
                        p2--;
                        strsize++;
                    }
                    break;
                case 1:
                    while(1) {
                        if ( p2<=0 ) break;
                        a = getchar();
                        if (( a==EOF )||( a=='\n' )) break;
                        *pp2++ = a;
                        p2--;
                        strsize++;
                    }
                    break;
                case 2:
                    while(1) {
                        if ( p2<=0 ) break;
                        a = getchar();
                        if ( a == '\r' ) {
                            int c = getchar();
                            if( c != '\n' ) {
                                ungetc(c, stdin);
                            }
                            break;
                        }
                        if (( a==EOF )||( a=='\n' )) break;
                        *pp2++ = a;
                        p2--;
                        strsize++;
                    }
                    break;
            }
            
            *pp2 = 0;
            ctx->strsize = strsize + 1;
            
            if ( p3 & 16 ) {
                if (( pval->support & HSPVAR_SUPPORT_FLEXSTORAGE ) == 0 ) throw HSPERR_TYPE_MISMATCH;
                //HspVarCoreAllocBlock( pval, (PDAT *)vptr, strsize );
                vptr = (char *)HspVarCorePtrAPTR( pval, aptr );
                memcpy( vptr, ctx->stmp, strsize );
            } else {
                code_setva( pval, aptr, TYPE_STRING, ctx->stmp );
            }
            break;
        }
            
        default:
            throw HSPERR_UNSUPPORTED_FUNCTION;
    }
    return RUNMODE_RUN;
}
Esempio n. 11
0
static int cmdfunc_intcmd( int cmd )
{
	//		cmdfunc : TYPE_INTCMD
	//		(内蔵コマンド)
	//
	int p1,p2,p3;
	//
	code_next();							// 次のコードを取得(最初に必ず必要です)

	switch( cmd ) {							// サブコマンドごとの分岐

	case 0x00:								// onexit
	case 0x01:								// onerror
	case 0x02:								// onkey
	case 0x03:								// onclick
	case 0x04:								// oncmd
		{

/*
	rev 45
	不具合 : (onxxx系命令) (ラベル型変数)  形式の書式でエラー
	に対処
*/

		int tval = *type;
		int opt = IRQ_OPT_GOTO;
		int cust;
		int actid;
		IRQDAT *irq;
		unsigned short *sbr;

		if ( tval == TYPE_VAR ) {
			if ( ( ctx->mem_var + *val )->flag == HSPVAR_FLAG_LABEL )
				tval = TYPE_LABEL;
		}

		if (( tval != TYPE_PROGCMD )&&( tval != TYPE_LABEL )) {		// ON/OFF切り替え
			int i = code_geti();
			code_enableirq( cmd, i );
			break;
		}

		if ( tval == TYPE_PROGCMD ) {	// ジャンプ方法指定
			opt = *val;
			if ( opt >= 2 ) throw HSPERR_SYNTAX;
			code_next();
		}

		sbr = code_getlb2();
		if ( cmd != 0x04 ) {
			code_setirq( cmd, opt, -1, sbr );
			break;
		}
		cust = code_geti();
		actid = *(exinfo->actscr);
		irq = code_seekirq( actid, cust );
		if ( irq == NULL ) irq = code_addirq();
		irq->flag = IRQ_FLAG_ENABLE;
		irq->opt = opt;
		irq->ptr = sbr;
		irq->custom = cust;
		irq->custom2 = actid;
		break;
		}

	case 0x11:								// exist
	case 0x12:								// delete
	case 0x13:								// mkdir
	case 0x14:								// chdir
		code_event( HSPEVENT_FNAME, 0, 0, code_gets() );
		code_event( HSPEVENT_FEXIST + (cmd - 0x11), 0, 0, NULL );
		break;

	case 0x15:								// dirlist
		{
		PVal *pval;
		APTR aptr;
		char *ptr;
		aptr = code_getva( &pval );
		code_event( HSPEVENT_FNAME, 0, 0, code_gets() );
		p1=code_getdi(0);
		code_event( HSPEVENT_FDIRLIST1, p1, 0, &ptr );
		code_setva( pval, aptr, TYPE_STRING, ptr );
		code_event( HSPEVENT_FDIRLIST2, 0, 0, NULL );
		break;
		}
	case 0x16:								// bload
	case 0x17:								// bsave
		{
		PVal *pval;
		char *ptr;
		int size;
		int tmpsize;
		code_event( HSPEVENT_FNAME, 0, 0, code_gets() );
		ptr = code_getvptr( &pval, &size );
		p1 = code_getdi( -1 );
		p2 = code_getdi( -1 );
		if (( p1 < 0 )||( p1 > size )) p1 = size;
		if ( cmd == 0x16 ) {
			tmpsize = p2;if ( tmpsize<0 ) tmpsize = 0;
			code_event( HSPEVENT_FREAD, tmpsize, p1, ptr );
		} else {
			code_event( HSPEVENT_FWRITE, p2, p1, ptr );
		}
		break;
		}
	case 0x18:								// bcopy
		code_event( HSPEVENT_FNAME, 0, 0, code_gets() );
		code_event( HSPEVENT_FCOPY, 0, 0, code_gets() );
		break;
	case 0x19:								// memfile
		{
		PVal *pval;
		char *ptr;
		int size;
		ptr = code_getvptr( &pval, &size );
		p1=code_getdi( 0 );
		p2=code_getdi( 0 );
		if ( p2==0 ) p2 = size - p1;
		dpm_memfile( ptr+p1, p2 );
		break;
		}

	case 0x1a:								// poke
	case 0x1b:								// wpoke
	case 0x1c:								// lpoke
		{
		PVal *pval;
		char *ptr;
		int size;
		int fl;
		int len;
		char *bp;
		ptr = code_getvptr( &pval, &size );
		p1 = code_getdi( 0 );
		if ( p1<0 ) throw HSPERR_BUFFER_OVERFLOW;
		ptr += p1;

		if ( code_get() <= PARAM_END ) {
			fl = HSPVAR_FLAG_INT;
			bp = (char *)&p2; p2 = 0;
		} else {
			fl = mpval->flag;
			bp = mpval->pt;
		}

		if ( cmd == 0x1a ) {
			switch( fl ) {
			case HSPVAR_FLAG_INT:
				if ( p1 >= size ) throw HSPERR_BUFFER_OVERFLOW;
				*ptr = *bp;
				break;
			case HSPVAR_FLAG_STR:
				len = (int)strlen( bp );
				ctx->strsize = len;
				len++;
				if ( (p1+len)>size ) throw HSPERR_BUFFER_OVERFLOW;
				strcpy( ptr, bp );
				break;
			default:
				throw HSPERR_TYPE_MISMATCH;
			}
			break;
		}

		if ( fl != HSPVAR_FLAG_INT ) throw HSPERR_TYPE_MISMATCH;
		if ( cmd == 0x1b ) {
			if ( (p1+2)>size ) throw HSPERR_BUFFER_OVERFLOW;
			*(short *)ptr = (short)(*(short *)bp);
		} else {
			if ( (p1+4)>size ) throw HSPERR_BUFFER_OVERFLOW;
			*(int *)ptr = (*(int *)bp);
		}
		break;
		}

	case 0x1d:								// getstr
		{
		PVal *pval2;
		PVal *pval;
		APTR aptr;
		char *ptr;
		char *p;
		int size;
		aptr = code_getva( &pval );
		ptr = code_getvptr( &pval2, &size );
		p1 = code_getdi( 0 );
		p2 = code_getdi( 0 );
		p3 = code_getdi( 1024 );
		if ( p1 >= size ) throw HSPERR_BUFFER_OVERFLOW;
		ptr += p1;
		p = code_stmp( p3 + 1 );
		strsp_ini();
		ctx->stat = strsp_get( ptr, p, p2, p3 );
		ctx->strsize = strsp_getptr();
		code_setva( pval, aptr, HSPVAR_FLAG_STR, p );
		break;
		}
	case 0x1e:								// chdpm
		code_event( HSPEVENT_FNAME, 0, 0, code_gets() );
		p1 = code_getdi( -1 );
		dpm_bye();
		p2 = dpm_ini( ctx->fnbuffer, 0, -1, p1 );
		if ( p2 ) throw HSPERR_FILE_IO;
#ifndef HSP3IMP
#ifdef HSPWIN
		Sleep( 1000 );
#endif
#endif
		break;
	case 0x1f:								// memexpand
		{
		PVal *pval;
		APTR aptr;
		PDAT *ptr;
		aptr = code_getva( &pval );
		ptr = HspVarCorePtrAPTR( pval, aptr );
		if (( pval->support & HSPVAR_SUPPORT_FLEXSTORAGE ) == 0 ) throw HSPERR_TYPE_MISMATCH;
		p1 = code_getdi( 0 );
		if ( p1 < 64 ) p1 = 64;
		HspVarCoreAllocBlock( pval, ptr, p1 );
		break;
		}

	case 0x20:								// memcpy
		{
		PVal *pval;
		char *sptr;
		char *tptr;
		int bufsize_t,bufsize_s;

		tptr = code_getvptr( &pval, &bufsize_t );
		sptr = code_getvptr( &pval, &bufsize_s );
		p1 = code_getdi( 0 );
		p2 = code_getdi( 0 );
		p3 = code_getdi( 0 );
		if( p2 < 0 || p3 < 0 ) throw HSPERR_BUFFER_OVERFLOW;

		tptr += p2;
		sptr += p3;
		if ( (p1+p2)>bufsize_t ) throw HSPERR_BUFFER_OVERFLOW;
		if ( (p1+p3)>bufsize_s ) throw HSPERR_BUFFER_OVERFLOW;
		if ( p1>0 ) {
			memmove( tptr, sptr, p1 );
		}
		break;
		}
	case 0x21:								// memset
		{
		PVal *pval;
		char *ptr;
		int size;
		ptr = code_getvptr( &pval, &size );
		p1 = code_getdi( 0 );
		p2 = code_getdi( 0 );
		p3 = code_getdi( 0 );
		if ( p3 < 0 ) throw HSPERR_BUFFER_OVERFLOW;
		ptr += p3;
		if ( (p3+p2)>size ) throw HSPERR_BUFFER_OVERFLOW;
		if ( p2>0 ) {
			memset( ptr, p1, p2 );
		}
		break;
		}

	case 0x22:								// notesel
		ctx->notep_aptr = ctx->note_aptr;
		ctx->notep_pval = ctx->note_pval;
		ctx->note_aptr = code_getva( &ctx->note_pval );
		if ( ctx->note_pval->flag != HSPVAR_FLAG_STR ) {
			code_setva( ctx->note_pval, ctx->note_aptr, TYPE_STRING, "" );
		}
		break;
	case 0x23:								// noteadd
		{
		char *np;
		char *ps;
		char *tmp;
		int size;
		np = note_update();
		ps = code_gets();
		size = (int)strlen( ps ) + 8;
		HspVarCoreAllocBlock( ctx->note_pval, (PDAT *)np, (int)strlen(np) + size );

		tmp = code_stmpstr( ps );

		p1 = code_getdi( -1 );
		p2 = code_getdi( 0 );
		np = note_update();
		note.PutLine( tmp, p1, p2 );
		break;
		}
	case 0x24:								// notedel
		p1 = code_getdi( 0 );
		note_update();
		note.PutLine( NULL, p1, 1 );
		break;
	case 0x25:								// noteload
		{
		int size;
		char *ptr;
		char *pdat;

		code_event( HSPEVENT_FNAME, 0, 0, code_gets() );
		p1 = code_getdi( -1 );
		code_event( HSPEVENT_FEXIST, 0, 0, NULL );
		size = ctx->strsize;
		if ( size < 0 ) throw HSPERR_FILE_IO;
		if ( p1>=0 ) if ( size >= p1 ) { ctx->strsize = size = p1; }

		pdat = note_update();
		HspVarCoreAllocBlock( ctx->note_pval, (PDAT *)pdat, size+1 );
		ptr = (char *)note_update();
		code_event( HSPEVENT_FREAD, 0, size, ptr );
		ptr[size] = 0;
		break;
		}
	case 0x26:								// notesave
		{
		char *pdat;
		int size;
		code_event( HSPEVENT_FNAME, 0, 0, code_gets() );
		pdat = note_update();
		size = (int)strlen( pdat );
		code_event( HSPEVENT_FWRITE, -1, size, pdat );
		break;
		}
	case 0x27:								// randomize
#ifdef HSPWIN
		p2 = (int)GetTickCount();	// Windowsの場合はtickをシード値とする
#else
		p2 = (int)time(0);			// Windows以外のランダムシード値
#endif
		p1 = code_getdi( p2 );
#ifdef HSPRANDMT
		mt.seed( p1 );
#else
		srand( p1 );
#endif
		break;
	case 0x28:								// noteunsel
		ctx->note_aptr = ctx->notep_aptr;
		ctx->note_pval = ctx->notep_pval;
		break;
	case 0x29:								// noteget
		{
		PVal *pval;
		APTR aptr;
		char *p;
		note_update();
		aptr = code_getva( &pval );
		p1 = code_getdi( 0 );
		p = note.GetLineDirect( p1 );
		code_setva( pval, aptr, TYPE_STRING, p );
		note.ResumeLineDirect();
		break;
		}
	case 0x2a:								// split
		{
		//	指定した文字列で分割された要素を代入する(fujidig)
		PVal *pval = NULL;
		int aptr = 0;
		char *sptr;
		char *sep;
		char *newsptr;
		int size;
		int sep_len;
		int n = 0;
		int is_last = 0;
		
		sptr = code_getvptr( &pval, &size );
		if ( pval->flag != HSPVAR_FLAG_STR ) throw HSPERR_TYPE_MISMATCH;
		sep = code_gets();
		sep_len = (int)strlen( sep );
		
		while (1) {
			newsptr = strstr2( sptr, sep );
			if ( !is_last && *exinfo->npexflg & EXFLG_1 ) {
				// 分割結果の数が格納する変数より多ければ最後の変数に配列で格納していく
				// ただし最後の要素が a.2 のように要素指定があればそれ以降は全く格納しない
				if ( aptr != 0 ) pval = NULL;
				is_last = 1;
				aptr = 0;
			}
			if ( is_last ) {
				aptr ++;
				if ( pval != NULL && aptr >= pval->len[1] ) {
					if ( pval->len[2] != 0 ) throw HSPVAR_ERROR_ARRAYOVER;
					HspVarCoreReDim( pval, 1, aptr+1 );
				}
			} else {
				aptr = code_getva( &pval );
			}
			if ( pval != NULL ) {
				if ( newsptr == NULL ) {
					code_setva( pval, aptr, HSPVAR_FLAG_STR, sptr );
				} else {
					var_set_str_len( pval, aptr, sptr, (int)(newsptr - sptr) );
				}
			}
			n ++;
			if ( newsptr == NULL ) {
				// 格納する変数の数が分割できた数より多ければ残った変数それぞれに空文字列を格納する
				while( ( *exinfo->npexflg & EXFLG_1 ) == 0 ) {
					aptr = code_getva( &pval );
					code_setva( pval, aptr, HSPVAR_FLAG_STR, "" );
				}
				break;
			}
			sptr = newsptr + sep_len;
		}
		ctx->stat = n;
		break;
		}

	case 0x02b:								// strrep
		{
		PVal *pval;
		APTR aptr;
		char *ss;
		char *s_rep;
		char *s_buffer;
		char *s_result;

		aptr = code_getva( &pval );
		if ( pval->flag != HSPVAR_FLAG_STR ) throw HSPERR_TYPE_MISMATCH;
		s_buffer = (char *)HspVarCorePtrAPTR( pval, aptr );

		ss = code_gets();
		if ( *ss == 0 ) throw HSPERR_ILLEGAL_FUNCTION;
		ReplaceSetMatch( s_buffer, ss );

		s_rep = code_gets();
		s_result = ReplaceStr( s_rep );
		code_setva( pval, aptr, TYPE_STRING, s_result );
		ctx->stat = ReplaceDone();
		break;
		}

	case 0x02c:								// setease
		{
		HSPREAL dval;
		HSPREAL dval2;
		dval = code_getd();
		dval2 = code_getd();
		p1 = code_getdi( ease_type );
		setEase( p1, dval, dval2 );
		break;
		}

	case 0x02d:								// sortval
		{
		int a,i;
		PVal *p1;
		APTR ap;
		int order;

		ap = code_getva( &p1 );		// パラメータ1:変数
		order = code_getdi( 0 );	// パラメータ2:数値

		i=p1->len[1];
		if (i<=0) throw HSPERR_ILLEGAL_FUNCTION;
		switch(p1->flag) {
			case HSPVAR_FLAG_DOUBLE:
			{
			double *dp;
			dp=(double *)p1->pt;
			DataIni( i );
			for(a=0;a<i;a++) {
				dtmp[a].as.dkey=dp[a];
				dtmp[a].info=a;
			}
			if (order == 0) {
				std::sort(dtmp, dtmp + i, less_double_1);
			}
			else {
				std::sort(dtmp, dtmp + i, less_double_0);
			}
			for(a=0;a<i;a++) {
				code_setva( p1, a, HSPVAR_FLAG_DOUBLE, &(dtmp[a].as.dkey) );	// 変数に値を代入
			}
			break;
			}
		case HSPVAR_FLAG_INT:
			{
			int *p;
			p=(int *)p1->pt;
			DataIni( i );
			for(a=0;a<i;a++) {
				dtmp[a].as.ikey=p[a];
				dtmp[a].info=a;
			}
			if (order == 0) {
				std::sort(dtmp, dtmp + i, less_int_1);
			}
			else {
				std::sort(dtmp, dtmp + i, less_int_0);
			}
			for(a=0;a<i;a++) {
				p[a]=dtmp[a].as.ikey;
			}
			break;
			}
		default:
			throw HSPERR_ILLEGAL_FUNCTION;
		}
		break;
		}

	case 0x02e:								// sortstr
		{
		int i,len,order;
		char *p;
		PVal *pv;
		APTR ap;
		HspVarProc *proc;
		char **pvstr;

		ap = code_getva( &pv );		// パラメータ1:変数
		order = code_getdi( 0 );	// パラメータ2:数値

		if ( pv->flag != 2 ) throw HSPERR_TYPE_MISMATCH;
		if (( pv->len[2] != 0 )||( ap != 0 )) throw HSPERR_ILLEGAL_FUNCTION;

		proc = HspVarCoreGetProc( pv->flag );

		len = pv->len[1];
		DataIni( len );

		for(i=0;i<len;i++) {
			p = (char *)HspVarCorePtrAPTR( pv, i );
			dtmp[i].as.skey = p;
			dtmp[i].info = i;
		}

		if (order == 0) {
			std::sort(dtmp, dtmp + i, less_str_1);
		}
		else {
			std::sort(dtmp, dtmp + i, less_str_0);
		}

		pvstr = (char **)(pv->master);	// 変数に直接sbポインタを書き戻す
		for(i=0;i<len;i++) {
			if ( i == 0 ) {
				pv->pt = dtmp[i].as.skey;
				sbSetOption(pv->pt, &pv->pt);
			} else {
				pvstr[i] = dtmp[i].as.skey;
				sbSetOption(pvstr[i], &pvstr[i]);
			}
		}
		break;
		}

	case 0x02f:								// sortnote
		{
		int i,sflag;
		char *p;
		char *stmp;
		PVal *pv;
		APTR ap;

		ap = code_getva( &pv );		// パラメータ1:変数
		sflag = code_getdi( 0 );	// パラメータ2:数値

		p = (char *)HspVarCorePtrAPTR( pv, ap );
		i = GetNoteLines(p);
		if ( i <= 0 ) throw HSPERR_ILLEGAL_FUNCTION;

		DataIni( i );

		NoteToData( p, dtmp );
		if (sflag == 0) {
			std::sort(dtmp, dtmp + i, less_str_1);
		}
		else {
			std::sort(dtmp, dtmp + i, less_str_0);
		}

		stmp = code_stmp( (int)DataToNoteLen( dtmp, i ) + 1 );
		DataToNote( dtmp, stmp, i );

		code_setva( pv, ap, HSPVAR_FLAG_STR, stmp );	// 変数に値を代入

		break;
		}

	case 0x030:								// sortget
		{
		PVal *pv;
		APTR ap;
		int result;
		int n;

		ap = code_getva( &pv );
		n = code_getdi( 0 );

		if ( dtmp == NULL ) throw HSPERR_ILLEGAL_FUNCTION;
		if (0 <= n && n < dtmp_size ) {
			result=dtmp[n].info;
		} else {
			result=0;
		}
		code_setva( pv, ap, HSPVAR_FLAG_INT, &result );
		break;
		}

	default:
		throw HSPERR_UNSUPPORTED_FUNCTION;
	}
	return RUNMODE_RUN;
}
Esempio n. 12
0
static void *reffunc_intfunc( int *type_res, int arg )
{
	//		reffunc : TYPE_INTFUNC
	//		(内蔵関数)
	//
	void *ptr;
	int chk;
	HSPREAL dval;
	HSPREAL dval2;
	int ival;
	char *sval;
	int p1,p2,p3;

	//			'('で始まるかを調べる
	//
	if ( *type != TYPE_MARK ) throw HSPERR_INVALID_FUNCPARAM;
	if ( *val != '(' ) throw HSPERR_INVALID_FUNCPARAM;
	code_next();

	//		返値のタイプをargをもとに設定する
	//		0~255   : int
	//		256~383 : string
	//		384~511 : double(HSPREAL)
	//
	switch( arg>>7 ) {
		case 2:										// 返値がstr
			*type_res = HSPVAR_FLAG_STR;			// 返値のタイプを指定する
			ptr = NULL;								// 返値のポインタ
			break;
		case 3:										// 返値がdouble
			*type_res = HSPVAR_FLAG_DOUBLE;			// 返値のタイプを指定する
			ptr = &reffunc_intfunc_value;			// 返値のポインタ
			break;
		default:									// 返値がint
			*type_res = HSPVAR_FLAG_INT;			// 返値のタイプを指定する
			ptr = &reffunc_intfunc_ivalue;			// 返値のポインタ
			break;
	}

	switch( arg ) {

	//	int function
	case 0x000:								// int
		{
		int *ip;
		chk = code_get();
		if ( chk <= PARAM_END ) { throw HSPERR_INVALID_FUNCPARAM; }
		ip = (int *)HspVarCoreCnvPtr( mpval, HSPVAR_FLAG_INT );
		reffunc_intfunc_ivalue = *ip;
		break;
		}
	case 0x001:								// rnd
		ival = code_geti();
		if ( ival == 0 ) throw HSPERR_DIVIDED_BY_ZERO;
#ifdef HSPRANDMT
		{
			std::uniform_int_distribution<int> dist( 0, ival - 1 );
			reffunc_intfunc_ivalue = dist( mt );
		}
#else
		reffunc_intfunc_ivalue = rand()%ival;
#endif
		break;
	case 0x002:								// strlen
		sval = code_gets();
		reffunc_intfunc_ivalue = (int) strlen( sval );
		break;

	case 0x003:								// length(3.0)
	case 0x004:								// length2(3.0)
	case 0x005:								// length3(3.0)
	case 0x006:								// length4(3.0)
		{
		PVal *pv;
		pv = code_getpval();
		reffunc_intfunc_ivalue = pv->len[ arg - 0x002 ];
		break;
		}

	case 0x007:								// vartype(3.0)
		{
		PVal *pv;
		HspVarProc *proc;
		if ( *type == TYPE_STRING ) {
			sval = code_gets();
			proc = HspVarCoreSeekProc( sval );
			if ( proc == NULL ) throw HSPERR_ILLEGAL_FUNCTION;
			reffunc_intfunc_ivalue = proc->flag;
		} else {
			code_getva( &pv );
			reffunc_intfunc_ivalue = pv->flag;
		}
		break;
		}

	case 0x008:								// gettime
		ival = code_geti();
		reffunc_intfunc_ivalue = gettime( ival );
		break;

	case 0x009:								// peek
	case 0x00a:								// wpeek
	case 0x00b:								// lpeek
		{
		PVal *pval;
		char *ptr;
		int size;
		ptr = code_getvptr( &pval, &size );
		p1 = code_getdi( 0 );
		if ( p1<0 ) throw HSPERR_ILLEGAL_FUNCTION;
		ptr += p1;
		if ( arg == 0x09 ) {
			if ( (p1+1)>size ) throw HSPERR_ILLEGAL_FUNCTION;
			reffunc_intfunc_ivalue = ((int)(*ptr)) & 0xff;
		} else if ( arg == 0x0a ) {
			if ( (p1+2)>size ) throw HSPERR_ILLEGAL_FUNCTION;
			reffunc_intfunc_ivalue = ((int)(*(short *)ptr)) & 0xffff;
		} else {
			if ( (p1+4)>size ) throw HSPERR_ILLEGAL_FUNCTION;
			reffunc_intfunc_ivalue = *(int *)ptr;
		}
		break;
		}
	case 0x00c:								// varptr
		{
		PVal *pval;
		APTR aptr;
		PDAT *pdat;
		STRUCTDAT *st;
		if ( *type == TYPE_DLLFUNC ) {
			st = &(ctx->mem_finfo[ *val ]);
			reffunc_intfunc_ivalue = (int)(size_t)(st->proc);
			code_next();
			break;
		}
		aptr = code_getva( &pval );
		pdat = HspVarCorePtrAPTR( pval, aptr );
		reffunc_intfunc_ivalue = (int)(size_t)(pdat);
		break;
		}
	case 0x00d:								// varuse
		{
		PVal *pval;
		APTR aptr;
		PDAT *pdat;
		aptr = code_getva( &pval );
		if ( pval->support & HSPVAR_SUPPORT_VARUSE ) {
			pdat = HspVarCorePtrAPTR( pval, aptr );
			reffunc_intfunc_ivalue = HspVarCoreGetUsing( pval, pdat );
		} else throw HSPERR_TYPE_MISMATCH;
		break;
		}
	case 0x00e:								// noteinfo
		ival = code_getdi(0);
		note_update();
		switch( ival ) {
		case 0:
			reffunc_intfunc_ivalue = note.GetMaxLine();
			break;
		case 1:
			reffunc_intfunc_ivalue = note.GetSize();
			break;
		default:
			throw HSPERR_ILLEGAL_FUNCTION;
		}
		break;

	case 0x00f:								// instr
		{
		PVal *pval;
		char *ptr;
		char *ps;
		char *ps2;
		int size;
		int p1;
		ptr = code_getvptr( &pval, &size );
		if ( pval->flag != HSPVAR_FLAG_STR ) throw HSPERR_TYPE_MISMATCH;
		p1 = code_getdi(0);
		if ( p1 >= size ) throw HSPERR_BUFFER_OVERFLOW;
		ps = code_gets();
		if ( p1 >= 0 ) {
			ptr += p1;
			ps2 = strstr2( ptr, ps );
		} else {
			ps2 = NULL;
		}
		if ( ps2 == NULL ) {
			reffunc_intfunc_ivalue = -1;
		} else {
			reffunc_intfunc_ivalue = (int)(ps2 - ptr);
		}
		break;
		}

	case 0x010:								// abs
		reffunc_intfunc_ivalue = code_geti();
		if ( reffunc_intfunc_ivalue < 0 ) reffunc_intfunc_ivalue = -reffunc_intfunc_ivalue;
		break;

	case 0x011:								// limit
		p1 = code_geti();
		p2 = code_geti();
		p3 = code_geti();
		reffunc_intfunc_ivalue = GetLimit( p1, p2, p3 );
		break;

	case 0x012:								// getease
		p1 = code_geti();
		p2 = code_getdi(-1);
		reffunc_intfunc_ivalue = getEaseInt( p1, p2 );
		break;

	case 0x013:								// notefind
		{
		char *ps;
		char *p;
		int findopt;
		ps = code_gets();
		p = code_stmpstr( ps );
		findopt = code_getdi(0);
		note_update();
		reffunc_intfunc_ivalue = note.FindLine( p, findopt );
		break;
		}


	// str function
	case 0x100:								// str
		{
		char *sp;
		chk = code_get();
		if ( chk <= PARAM_END ) { throw HSPERR_INVALID_FUNCPARAM; }
		sp = (char *)HspVarCoreCnvPtr( mpval, HSPVAR_FLAG_STR );
		ptr = (void *)sp;
		break;
		}
	case 0x101:								// strmid
		{
		PVal *pval;
		char *sptr;
		char *p;
		char chrtmp;
		int size;
		int i;
		int slen;
		sptr = code_getvptr( &pval, &size );
		if ( pval->flag != HSPVAR_FLAG_STR ) throw HSPERR_TYPE_MISMATCH;
		p1 = code_geti();
		p2 = code_geti();

		slen=(int)strlen( sptr );
		if ( p1 < 0 ) {
			p1=slen - p2;
			if ( p1 < 0 ) p1 = 0;
		}
		if ( p1 >= slen )
			p2 = 0;
		if ( p2 > slen ) p2 = slen;
		sptr += p1;
		ptr = p = code_stmp( p2 + 1 );
		for(i=0;i<p2;i++) {
			chrtmp = *sptr++;
			*p++ = chrtmp;
			if (chrtmp==0) break;
		}
		*p = 0;
		break;
		}

	case 0x103:								// strf
		ptr = cnvformat();
		break;
	case 0x104:								// getpath
		{
		char *p;
		char pathname[HSP_MAX_PATH];
		p = ctx->stmp;
		strncpy( pathname, code_gets(), HSP_MAX_PATH-1 );
		p1=code_geti();
		getpath( pathname, p, p1 );
		ptr = p;
		break;
		}
	case 0x105:								// strtrim
		{
		PVal *pval;
		char *sptr;
		char *p;
		int size;
		sptr = code_getvptr( &pval, &size );
		if ( pval->flag != HSPVAR_FLAG_STR ) throw HSPERR_TYPE_MISMATCH;
		p1 = code_getdi(0);
		p2 = code_getdi(32);
		ptr = p = code_stmp( size + 1 );
		strcpy( p, sptr );
		switch( p1 ) {
		case 0:
			TrimCodeL( p, p2 );
			TrimCodeR( p, p2 );
			break;
		case 1:
			TrimCodeL( p, p2 );
			break;
		case 2:
			TrimCodeR( p, p2 );
			break;
		case 3:
			TrimCode( p, p2 );
			break;
		}
		break;
		}

	//	double function
	case 0x180:								// sin
		dval = code_getd();
		reffunc_intfunc_value = sin( dval );
		break;
	case 0x181:								// cos
		dval = code_getd();
		reffunc_intfunc_value = cos( dval );
		break;
	case 0x182:								// tan
		dval = code_getd();
		reffunc_intfunc_value = tan( dval );
		break;
	case 0x183:								// atan
		dval = code_getd();
		dval2 = code_getdd( 1.0 );
		reffunc_intfunc_value = atan2( dval, dval2 );
		break;
	case 0x184:								// sqrt
		dval = code_getd();
		reffunc_intfunc_value = sqrt( dval );
		break;
	case 0x185:								// double
		{
		HSPREAL *dp;
		chk = code_get();
		if ( chk <= PARAM_END ) { throw HSPERR_INVALID_FUNCPARAM; }
		dp = (HSPREAL *)HspVarCoreCnvPtr( mpval, HSPVAR_FLAG_DOUBLE );
		reffunc_intfunc_value = *dp;
		break;
		}
	case 0x186:								// absf
		reffunc_intfunc_value = code_getd();
		if ( reffunc_intfunc_value < 0 ) reffunc_intfunc_value = -reffunc_intfunc_value;
		break;
	case 0x187:								// expf
		dval = code_getd();
		reffunc_intfunc_value = exp( dval );
		break;
	case 0x188:								// logf
		dval = code_getd();
		reffunc_intfunc_value = log( dval );
		break;
	case 0x189:								// limitf
		{
		HSPREAL d1,d2,d3;
		d1 = code_getd();
		d2 = code_getd();
		d3 = code_getd();
		if ( d1 < d2 ) d1 = d2;
		if ( d1 > d3 ) d1 = d3;
		reffunc_intfunc_value = d1;
		break;
		}
	case 0x18a:								// powf
		dval = code_getd();
		dval2 = code_getd();
		reffunc_intfunc_value = pow( dval, dval2 );
		break;
	case 0x18b:								// geteasef
		dval = code_getd();
		dval2 = code_getdd(1.0);
		if ( dval2 == 1.0 ) {
			reffunc_intfunc_value = getEase( dval );
		} else {
			reffunc_intfunc_value = getEase( dval, dval2 );
		}
		break;

	default:
		throw HSPERR_UNSUPPORTED_FUNCTION;
	}

	//			')'で終わるかを調べる
	//
	if ( *type != TYPE_MARK ) throw HSPERR_INVALID_FUNCPARAM;
	if ( *val != ')' ) throw HSPERR_INVALID_FUNCPARAM;
	code_next();

	return ptr;
}
Esempio n. 13
0
static void *reffunc_ctrlfunc( int *type_res, int arg )
{
	//		reffunc : TYPE_DLLCTRL
	//		(拡張DLLコントロール関数)
	//
	void *ptr;
	int p1,p2;

	//			'('で始まるかを調べる
	//
	if ( *type != TYPE_MARK ) throw ( HSPERR_INVALID_FUNCPARAM );
	if ( *val != '(' ) throw ( HSPERR_INVALID_FUNCPARAM );
	code_next();

	ptr = &reffunc_intfunc_ivalue;
	*type_res = HSPVAR_FLAG_INT;

	switch( arg ) {							// サブコマンドごとの分岐
	case 0x100:								// callfunc
		{
		PVal *pval;
		PDAT *p;
		pval = code_getpval();
		p = HspVarCorePtrAPTR( pval, 0 );
		p1 = code_geti();
		p2 = code_geti();
		reffunc_intfunc_ivalue = call_extfunc( (void *)p1, (int *)p, p2 );
		break;
		}
	case 0x101:								// cnvwtos
		{
		PVal *pval;
		char *sptr;
		int size;
		sptr = code_getvptr( &pval, &size );
		hspctx->stmp = sbExpand( hspctx->stmp, size );
		ptr = hspctx->stmp;
		cnvsjis( ptr, sptr, size  );
		*type_res = HSPVAR_FLAG_STR;
		break;
		}

	case 0x102:								// 	comevdisp
#ifdef HSP_COM_UNSUPPORTED
		throw ( HSPERR_UNSUPPORTED_FUNCTION );
#else
		{
		PVal *pval;
		APTR aptr;
		IUnknown **ppunk;
		// 第1パラメータ:COMオブジェクト変数
		aptr = code_getva( &pval );
		if ( pval->flag != TYPE_COMOBJ ) throw ( HSPERR_TYPE_MISMATCH );
		ppunk = (IUnknown **)HspVarCorePtrAPTR( pval, aptr );
		if ( !IsVaridComPtr(ppunk) ) throw ( HSPERR_COMDLL_ERROR );

		// イベントの DISPID 取得
		reffunc_intfunc_ivalue = GetEventDispID( *ppunk );
		break;
		}
#endif	// HSP_COM_UNSUPPORTED

	case 0x103:								// 	libptr
		{
		//LIBDAT *lib;
		STRUCTDAT *st;
		switch( *type ) {
		case TYPE_DLLFUNC:
		case TYPE_MODCMD:
			p1 = *val;
			break;
		case TYPE_DLLCTRL:
			p1 = *val;
			if ( p1 >= TYPE_OFFSET_COMOBJ ) {
				p1 -= TYPE_OFFSET_COMOBJ;
				break;
			}
		default:
			throw ( HSPERR_TYPE_MISMATCH );
		}
		code_next();
		st = GetPRM( p1 );
		//lib = &hspctx->mem_linfo[ st->index ];
		reffunc_intfunc_ivalue = (int)st;
		break;
		}

	default:
		throw ( HSPERR_SYNTAX );
	}

	//			')'で終わるかを調べる
	//
	if ( *type != TYPE_MARK ) throw ( HSPERR_INVALID_FUNCPARAM );
	if ( *val != ')' ) throw ( HSPERR_INVALID_FUNCPARAM );
	code_next();

	return ptr;
}
Esempio n. 14
0
static int cmdfunc_ctrlcmd( int cmd )
{
	//		cmdfunc : TYPE_DLLCTRL
	//		(拡張DLLコントロールコマンド)
	//
	code_next();							// 次のコードを取得(最初に必ず必要です)

	if ( cmd >= TYPE_OFFSET_COMOBJ ) {
#ifdef HSP_COM_UNSUPPORTED
		throw ( HSPERR_UNSUPPORTED_FUNCTION );
#else
		// COM インターフェースメソッドの呼び出し
		STRUCTDAT *st;
		st = GetPRM( cmd - TYPE_OFFSET_COMOBJ );
		hspctx->stat = code_expand_and_call( st );
		return RUNMODE_RUN;
#endif
	}

	switch( cmd ) {							// サブコマンドごとの分岐


	case 0x00:								// newcom
#ifdef HSP_COM_UNSUPPORTED
		throw ( HSPERR_UNSUPPORTED_FUNCTION );
#else
		{
		PVal *pval;
		APTR aptr;
		IUnknown **ppunkNew, *punkDef;
		CLSID clsid;
		char *clsid_name;
		const IID *piid, *piid2;
		void *iptr;
		LIBDAT *lib;
		STRUCTDAT *st;
		int inimode;

		// 第1パラメータ:新しいインターフェースポインタを格納する変数
		// (変数にNULLポインタを格納)
		aptr = code_getva( &pval );
		iptr = NULL;
		code_setva( pval, aptr, TYPE_COMOBJ, &iptr );
		ppunkNew = (IUnknown **)HspVarCorePtrAPTR( pval, aptr );

		// CLSID / IID 情報を取得
		if ( !code_getexflg() && *type == TYPE_DLLCTRL ) {
			// 第2パラメータ:#usecom 登録情報
			st = code_getcomst();
			if ( st->otindex != -1 ) throw HSPERR_TYPE_MISMATCH;
			lib = &hspctx->mem_linfo[ st->index ];
			if ( lib->clsid == -1 ) throw HSPERR_INVALID_PARAMETER;
			clsid_name = strp(lib->clsid);
			piid  = (IID *)strp( lib->nameidx );
			piid2 = NULL;
		} else {
			// 第2パラメータ:文字列 CLSID
			// (IID はデフォルトで IID_IDispatch, サポートされていなければ IID_IUnknown )
			clsid_name = code_getds("");
			piid  = &IID_IDispatch;
			piid2 = &IID_IUnknown;
		}
		inimode = code_getdi(0);				// 初期化モード
		punkDef = (IUnknown *)code_getdi(0);	// デフォルトオブジェクト

		// 新規CLSIDからインスタンスを作成
		hspctx->stat = 0;
		switch ( inimode ) {
		 case 0:
			// 新規にロード
			if ( clsid_name[0]!='\0' ) {
				if ( GetIIDFromString(&clsid,clsid_name,true) != FALSE &&
					 SUCCEEDED( CoCreateInstance( clsid, NULL, CLSCTX_SERVER, *piid, (void**)ppunkNew )) &&
					 *ppunkNew != NULL )
				{
					break;
				}
				if ( piid2 != NULL &&
					 SUCCEEDED( CoCreateInstance( clsid, NULL, CLSCTX_SERVER, *piid2, (void**)ppunkNew )) &&
					 *ppunkNew != NULL )
				{
					break;
				}
				hspctx->stat = 1;
			}
			break;
		 case -2:
			// オブジェクトを明示的に指定する場合 ( AddRef() あり)
			if ( punkDef != NULL ) punkDef->AddRef();
		 case -1:
			// オブジェクトを明示的に指定する場合 ( AddRef() なし)
			*ppunkNew = punkDef;
			break;
		 default:
			throw HSPERR_UNSUPPORTED_FUNCTION;
		}
	#ifdef HSP_COMOBJ_DEBUG
		COM_DBG_MSG( "newcom : pObj=%p : &pObj=%p\n", *ppunkNew, ppunkNew);
	#endif
		break;
		}
#endif	// HSP_COM_UNSUPPORTED

	case 0x01:								// querycom
#ifdef HSP_COM_UNSUPPORTED
		throw HSPERR_UNSUPPORTED_FUNCTION;
#else
		{
		PVal *pval, *pvalNew;
		APTR aptr, aptrNew;
		IUnknown **ppunkDst, **ppunkSrc;
		IID iid;
		const IID *piid;
		void *iptr;
		STRUCTDAT *st;
		LIBDAT *lib;

		// 第1パラメータ:新しいインターフェースポインタを格納する変数
		aptrNew = code_getva( &pvalNew );

		// 第2パラメータ:既存のCOMオブジェクト
		aptr = code_getva( &pval );
		if ( pval->flag != TYPE_COMOBJ ) throw ( HSPERR_TYPE_MISMATCH );
		ppunkSrc = (IUnknown **)HspVarCorePtrAPTR( pval, aptr );
		if ( ! IsVaridComPtr(ppunkSrc) ) throw ( HSPERR_COMDLL_ERROR );

		// IID 情報を取得
		if ( *type == TYPE_DLLCTRL ) {
			// 第3パラメータ:#usecom 登録情報
			st = code_getcomst();
			if ( st->otindex != -1 ) throw ( HSPERR_TYPE_MISMATCH );
			lib = &hspctx->mem_linfo[ st->index ];
			piid = (IID *)strp( lib->nameidx );
		} else {
			// 第3パラメータ:文字列 IID
			GetIIDFromString( &iid, code_gets() );
			piid = &iid;
		}

		if ( pvalNew->flag != TYPE_COMOBJ ) {
			// 代入により型変換
			iptr = NULL;
			code_setva( pvalNew, aptrNew, TYPE_COMOBJ, &iptr );
		}
		ppunkDst = (IUnknown **)HspVarCorePtrAPTR( pvalNew, aptrNew );

		// query によりインスタンスを得る
		QueryComPtr( ppunkDst, *ppunkSrc, piid );
		if ( IsVaridComPtr(ppunkSrc) )
			hspctx->stat = 0;
		else
			hspctx->stat = 1;
		break;
		}
#endif	// HSP_COM_UNSUPPORTED

	case 0x02:								// delcom
#ifdef HSP_COM_UNSUPPORTED
		throw ( HSPERR_UNSUPPORTED_FUNCTION );
#else
		{
		PVal *pval;
		APTR aptr;
		IUnknown **ppunk;
		VARIANT *var;
		void *ptr;

		// 第1パラメータ:解放するCOMオブジェクト変数
		aptr = code_getva( &pval );
		ptr = HspVarCorePtrAPTR( pval, aptr );
		switch ( pval->flag ) {
		case TYPE_COMOBJ:
			ppunk = (IUnknown **)ptr;
			ReleaseComPtr( ppunk );
			break;
		case TYPE_VARIANT:
			var = (VARIANT *)ptr;
			VariantClear( var );
			break;
		default:
			throw HSPERR_TYPE_MISMATCH;
		}

		// このタイミングで一時オブジェクトも削除しちゃう
		if ( comconv_var.vt != VT_EMPTY ) VariantClear( &comconv_var );
		break;
		}
#endif	// HSP_COM_UNSUPPORTED

	case 0x03:								// 	cnvstow
		{
		PVal *pval;
		char *ptr;
		char *ps;
		int size;
		ptr = code_getvptr( &pval, &size );
		ps = code_gets();
		cnvwstr( ptr, ps, size/2 );
		break;
		}

	case 0x04:								// 	comres
#ifdef HSP_COM_UNSUPPORTED
		throw ( HSPERR_UNSUPPORTED_FUNCTION );
#else
		if ( code_getexflg() ) {
			comres_pval = NULL;
			comres_aptr = 0;
		} else {
			comres_aptr = code_getva( &comres_pval );
		}
		break;
#endif	// HSP_COM_UNSUPPORTED

	case 0x05:								// 	axobj
#ifdef HSP_COM_UNSUPPORTED
		throw ( HSPERR_UNSUPPORTED_FUNCTION );
#else
		{
		PVal *pval;
		APTR aptr;
		const IID *piid;
		void *iptr;
		BMSCR *bm;
		HWND hwnd;
		int id,sx,sy;
		char clsid_name[1024];
		IUnknown **ppunk, *punkObj, *punkObj2;
		STRUCTDAT *st;
		LIBDAT *lib;
		HRESULT hr;

		bm = GetBMSCR();

		// 第1パラメータ:新しいインターフェースポインタを格納する変数
		// (あらかじめ変数にNULLを格納)
		aptr = code_getva( &pval );
		iptr = NULL;
		code_setva( pval, aptr, TYPE_COMOBJ, &iptr );
		ppunk = (IUnknown **)HspVarCorePtrAPTR( pval, aptr );

		// オブジェクトの CLSID, ProgID, etc.
		if ( *type == TYPE_DLLCTRL ) {
			// 第2パラメータ:#usecom 登録情報から取得
			st = code_getcomst();
			if ( st->otindex != -1 ) throw ( HSPERR_TYPE_MISMATCH );
			lib = &hspctx->mem_linfo[ st->index ];
			piid = (IID *)strp( lib->nameidx );
			if ( lib->clsid == -1 ) throw ( HSPERR_INVALID_PARAMETER );
			strncpy( clsid_name, strp(lib->clsid), sizeof(clsid_name)-1 );
		} else {
			// 第2パラメータ:文字列 CLSID or ProgID を取得 (IID は IDispatch)
			piid = &IID_IDispatch;
			strncpy( clsid_name, code_gets(), sizeof(clsid_name)-1 );
		}

		// コントロールのサイズ
		sx = code_getdi( bm->sx );
		sy = code_getdi( bm->sy );

		//		ActiveXとしてロード
		//
		if ( fn_atxinit == NULL ) throw ( HSPERR_UNSUPPORTED_FUNCTION );
		hwnd = CreateWindow( atxwndclass, clsid_name,
				WS_CHILD, 			// 最初は WS_VISIBLE なし (後で ShowWindow() )
				bm->cx, bm->cy, sx, sy,
				bm->hwnd, (HMENU)0, (HINSTANCE)hspctx->instance, NULL );

		punkObj2 = NULL;
		if ( hwnd ) {
			punkObj = NULL;
			fn_atxgetctrl( hwnd, (void**)&punkObj );
			if ( punkObj ) {
				// 指定 IID が存在するかどうか
				hr = punkObj->QueryInterface( *piid, (void**)&punkObj2 );
				punkObj->Release();
			}
		}
		if ( punkObj2 == NULL ) {
			// 目的オブジェクトではないときコントロールを削除
			if (hwnd) { DestroyWindow( hwnd ); }
			hspctx->stat = -1;
			break;
		}
		// COM 型変数に格納
		*ppunk = punkObj2;

		// HSPのウインドゥオブジェクトとして登録する
		ShowWindow( hwnd, SW_SHOW );
		id = AddHSPObject( hwnd, HSPOBJ_TAB_SKIP, sy );
#ifdef HSP_COMOBJ_DEBUG
		Alertf( "axobj : pObj=%p : &pObj=%p\n", *ppunk, ppunk);
	#endif
		break;
		}
#endif	// HSP_COM_UNSUPPORTED

	case 0x06:								// 	winobj
		{
#ifdef HSPDISH
		throw ( HSPERR_UNSUPPORTED_FUNCTION );
#else
		char clsname[1024];
		char winname[1024];
		HWND hwnd;
		char *ps;
		BMSCR *bm;
		int i;
		int prm[6];

		ps = code_gets(); strncpy( clsname, ps, 1023 );
		ps = code_gets(); strncpy( winname, ps, 1023 );

		bm = GetBMSCR();
		for(i=0;i<6;i++) {
			prm[i] = code_getdi(0);
		}
		if ( prm[2] <= 0 ) prm[2] = bm->ox;
		if ( prm[3] <= 0 ) prm[3] = bm->oy;

		hwnd = CreateWindowEx(
		    (DWORD) prm[0],			// 拡張ウィンドウスタイル
		    clsname,				// ウィンドウクラス名
		    winname,				// ウィンドウ名
		    (DWORD) prm[1],			// ウィンドウスタイル
			bm->cx, bm->cy, prm[2], prm[3],		// X,Y,SIZEX,SIZEY
			bm->hwnd,				// 親ウィンドウのハンドル
		    (HMENU) prm[4],			// メニューハンドルまたは子ウィンドウID
			bm->hInst,				// インスタンスハンドル
		    (PVOID) prm[5]			// ウィンドウ作成データ
			);

		// AddHSPObject( hwnd, HSPOBJ_TAB_SKIP, prm[3], NULL, 0 );			// HSPのウインドゥオブジェクトとして登録する
		AddHSPObject( hwnd, HSPOBJ_TAB_SKIP, prm[3] );
		break;
#endif	// HSPDISH
		}

	case 0x07:								// 	sendmsg
		{
		int hw,p1,p2,p3,p4,fl,sz;
		char *vptr;
		hw = code_getdi(0);
		p1 = code_getdi(0);

		vptr = code_getsptr( &fl );
		if ( fl == TYPE_STRING ) {
			p2 = (int)code_stmpstr( vptr );
		} else {
			p2 = *(int *)vptr;
		}

		vptr = code_getsptr( &fl );
		if ( fl == TYPE_STRING ) {
			p3 = (int)vptr;
		} else {
			p3 = *(int *)vptr;
		}

		//Alertf( "SEND[%x][%x][%x]",p1,p2,p3 );
		hspctx->stat = (int)SendMessage( (HWND)hw, p1, p2, p3 );
		break;
		}

	case 0x08:								// 	comevent
#ifdef HSP_COM_UNSUPPORTED
		throw ( HSPERR_UNSUPPORTED_FUNCTION );
#else
		{
		PVal *pval;
		APTR aptr;
		void* iptr;
		char *ps;
		IID iid, *piid;
		unsigned short *subr;
		IUnknown **ppunk, **ppunkEvent;

		// 第1パラメータ:イベントハンドラオブジェクト (IEventHandler) を格納する変数
		// (あらかじめ NULL で初期化)
		aptr = code_getva( &pval );
		iptr = NULL;
		code_setva( pval, aptr, TYPE_COMOBJ, &iptr );
		ppunkEvent = (IUnknown **)HspVarCorePtrAPTR( pval, aptr );

		// 第2パラメータ:COMオブジェクトを格納した変数
		aptr = code_getva( &pval );
		if ( pval->flag != TYPE_COMOBJ ) throw ( HSPERR_TYPE_MISMATCH );
		ppunk = (IUnknown **)HspVarCorePtrAPTR( pval, aptr );
		if ( ! IsVaridComPtr(ppunk) ) throw ( HSPERR_COMDLL_ERROR );

		// 第3パラメータ:コネクションポイントIID (文字列形式)
		ps = code_getds("");
		if ( ps[0] != '\0' ) {
			piid = &iid;
			GetIIDFromString( piid, ps );
		} else {
			piid = NULL;	// NULL のときデフォルトIID が自動的に取得される
		}

		// 第4パラメータ:コールバック用のサブルーチンラベル
		subr = code_getlb2();

		// イベントハンドラ作成・接続
		SetComEvent( ppunkEvent, ppunk, piid, subr );
	#ifdef HSP_COMOBJ_DEBUG
		COM_DBG_MSG( "comevent : pEvent=%p : pObj=%p\n", *ppunkEvent, *ppunk);
	#endif
		break;
		}
#endif	// HSP_COM_UNSUPPORTED

	case 0x09:								// 	comevarg
#ifdef HSP_COM_UNSUPPORTED
		throw ( HSPERR_UNSUPPORTED_FUNCTION );
#else
		{
		PVal *pval, *pval2;
		APTR aptr, aptr2;
		VARIANT *v;
		void *ptr;
		int p1,p2;
		int res;
		IUnknown **ppunk;
		VARIANT varTemp;

		// 第1パラメータ:イベントのパラメータを格納する変数
		aptr = code_getva( &pval );

		// 第2パラメータ:イベントハンドラオブジェクト変数
		aptr2 = code_getva( &pval2 );
		if ( pval2->flag != TYPE_COMOBJ ) throw ( HSPERR_TYPE_MISMATCH );
		ppunk = (IUnknown **)HspVarCorePtrAPTR( pval2, aptr2 );
		if ( ! IsVaridComPtr(ppunk) ) throw ( HSPERR_COMDLL_ERROR );

		// 第3パラメータ:パラメータインデックス
		p1 = code_getdi(0);

		// 第4パラメータ:文字列変換フラグ
		p2 = code_getdi(0);

		// イベントのパラメータ取得
		v = GetEventArg( *ppunk, p1 );
		if ( v == NULL ) throw ( HSPERR_ILLEGAL_FUNCTION );
		switch ( p2 ) {
		case 0:
			VariantInit( &varTemp );
			VariantCopyInd( &varTemp, v );
			ptr = comget_variant( &varTemp, &res );
			VariantClear( &varTemp );
			break;
		case 1:
			VariantInit( &varTemp );
			if FAILED( VariantChangeType( &varTemp, v, VARIANT_ALPHABOOL, VT_BSTR ) )
				throw ( HSPERR_TYPE_INITALIZATION_FAILED );
			ptr = comget_variant( &varTemp, &res );
			VariantClear( &varTemp );
			break;
		case 2:
			ptr = v;
			res = HSPVAR_FLAG_VARIANT;
			break;
		default:
			throw ( HSPERR_ILLEGAL_FUNCTION );
		}
		code_setva( pval, aptr, res, ptr );
		hspctx->stat = res;
		break;
		}
#endif	// HSP_COM_UNSUPPORTED

	case 0x0a:								// 	sarrayconv
#ifdef HSP_COM_UNSUPPORTED
		throw ( HSPERR_UNSUPPORTED_FUNCTION );
#else
		{
		PVal *pval1, *pval2;
		APTR aptr1, aptr2;
		int convdir, size;
		VARIANT *variant, varTemp;
		VARTYPE vt;
		SAFEARRAY *psa;
		long lbound, ubound;
		HRESULT hr;

		aptr1 = code_getva( &pval1 );
		aptr2 = code_getva( &pval2 );
		convdir = code_getdi(0);
		size = code_getdi(0);

		switch ( convdir ) {
		case 0:
		case 2:
		case 4:
			// 配列変数から SafeArray に変換
			VariantInit( &varTemp );
			code_setva( pval1, aptr1, HSPVAR_FLAG_VARIANT, &varTemp );
			variant = (VARIANT *)HspVarCorePtrAPTR( pval1, aptr1 );
			VariantClear( variant );		// 一応
			if ( convdir == 2 ) {
				// バイナリデータ(一次元のみ)
				void *ptr = HspVarCorePtrAPTR( pval2, aptr2 );
				psa = CreateBinarySafeArray( ptr, size, &vt );
			} else {
				BOOL bVariant = ( convdir == 4 );
				psa = ConvVar2SafeArray( pval2, bVariant, &vt );
			}
			variant->vt = vt | VT_ARRAY;
			variant->parray = psa;
			break;
		case 1:
		case 3:
			// SafeArray から配列変数に変換
			if ( pval2->flag != HSPVAR_FLAG_VARIANT ) throw HSPERR_INVALID_TYPE;
			variant = (VARIANT *)HspVarCorePtrAPTR( pval2, aptr2 );
			if ( (variant->vt & VT_ARRAY) == 0 ) throw HSPERR_INVALID_TYPE;
			psa = variant->parray;
			if ( psa == NULL ) throw HSPERR_ARRAY_OVERFLOW;
			vt = variant->vt & VT_TYPEMASK;
			if ( vt == VT_EMPTY ) {
				hr = SafeArrayGetVartype( psa, &vt );
				if ( FAILED(hr) || vt == VT_EMPTY ) throw HSPERR_INVALID_ARRAYSTORE;
			}
			if ( convdir == 1 ) {
				ConvSafeArray2Var( pval1, psa, vt );
			} else {
				// バイナリデータ(一次元のみ)
				int varsize;
				void *ptr = HspVarCorePtrAPTR( pval1, aptr1 );				if ( vt != VT_UI1 && vt != VT_I1 ) throw HSPERR_INVALID_TYPE;
				SafeArrayGetLBound( psa, 1, &lbound );
				hr = SafeArrayGetUBound( psa, 1, &ubound );
				if ( FAILED(hr) ) throw HSPERR_ARRAY_OVERFLOW;
				size = ubound - lbound + 1;
				HspVarCoreGetBlockSize( pval1, (PDAT*)ptr, &varsize );
				if ( varsize < size ) throw HSPERR_BUFFER_OVERFLOW;
				GetBinarySafeArray( ptr, size, psa );
			}
			break;
		default:
			throw ( HSPERR_UNSUPPORTED_FUNCTION );
		}
		break;
		}
#endif	// HSP_COM_UNSUPPORTED

	default:
		throw ( HSPERR_SYNTAX );
	}
	return RUNMODE_RUN;
}
Esempio n. 15
0
static int cmdfunc_intcmd( int cmd )
{
	//		cmdfunc : TYPE_INTCMD
	//		(内蔵コマンド)
	//
	int p1,p2,p3;
	//
	code_next();							// 次のコードを取得(最初に必ず必要です)

	switch( cmd ) {							// サブコマンドごとの分岐

	case 0x00:								// onexit
	case 0x01:								// onerror
	case 0x02:								// onkey
	case 0x03:								// onclick
	case 0x04:								// oncmd
		{

/*
	rev 45
	不具合 : (onxxx系命令) (ラベル型変数)  形式の書式でエラー
	に対処
*/

		int tval = *type;
		int opt = IRQ_OPT_GOTO;
		int cust;
		int actid;
		IRQDAT *irq;
		unsigned short *sbr;

		if ( tval == TYPE_VAR ) {
			if ( ( ctx->mem_var + *val )->flag == HSPVAR_FLAG_LABEL )
				tval = TYPE_LABEL;
		}

		if (( tval != TYPE_PROGCMD )&&( tval != TYPE_LABEL )) {		// ON/OFF切り替え
			int i = code_geti();
			code_enableirq( cmd, i );
			break;
		}

		if ( tval == TYPE_PROGCMD ) {	// ジャンプ方法指定
			opt = *val;
			if ( opt >= 2 ) throw HSPERR_SYNTAX;
			code_next();
		}

		sbr = code_getlb2();
		if ( cmd != 0x04 ) {
			code_setirq( cmd, opt, -1, sbr );
			break;
		}
		cust = code_geti();
		actid = *(exinfo->actscr);
		irq = code_seekirq( actid, cust );
		if ( irq == NULL ) irq = code_addirq();
		irq->flag = IRQ_FLAG_ENABLE;
		irq->opt = opt;
		irq->ptr = sbr;
		irq->custom = cust;
		irq->custom2 = actid;
		break;
		}

	case 0x11:								// exist
	case 0x12:								// delete
	case 0x13:								// mkdir
	case 0x14:								// chdir
		code_event( HSPEVENT_FNAME, 0, 0, code_gets() );
		code_event( HSPEVENT_FEXIST + (cmd - 0x11), 0, 0, NULL );
		break;

	case 0x15:								// dirlist
		{
		PVal *pval;
		APTR aptr;
		char *ptr;
		aptr = code_getva( &pval );
		code_event( HSPEVENT_FNAME, 0, 0, code_gets() );
		p1=code_getdi(0);
		code_event( HSPEVENT_FDIRLIST1, p1, 0, &ptr );
		code_setva( pval, aptr, TYPE_STRING, ptr );
		code_event( HSPEVENT_FDIRLIST2, 0, 0, NULL );
		break;
		}
	case 0x16:								// bload
	case 0x17:								// bsave
		{
		PVal *pval;
		char *ptr;
		int size;
		int tmpsize;
		code_event( HSPEVENT_FNAME, 0, 0, code_gets() );
		ptr = code_getvptr( &pval, &size );
		p1 = code_getdi( -1 );
		p2 = code_getdi( -1 );
		if (( p1 < 0 )||( p1 > size )) p1 = size;
		if ( cmd == 0x16 ) {
			tmpsize = p2;if ( tmpsize<0 ) tmpsize = 0;
			code_event( HSPEVENT_FREAD, tmpsize, p1, ptr );
		} else {
			code_event( HSPEVENT_FWRITE, p2, p1, ptr );
		}
		break;
		}
	case 0x18:								// bcopy
		code_event( HSPEVENT_FNAME, 0, 0, code_gets() );
		code_event( HSPEVENT_FCOPY, 0, 0, code_gets() );
		break;
	case 0x19:								// memfile
		{
		PVal *pval;
		char *ptr;
		int size;
		ptr = code_getvptr( &pval, &size );
		p1=code_getdi( 0 );
		p2=code_getdi( 0 );
		if ( p2==0 ) p2 = size - p1;
		dpm_memfile( ptr+p1, p2 );
		break;
		}

	case 0x1a:								// poke
	case 0x1b:								// wpoke
	case 0x1c:								// lpoke
		{
		PVal *pval;
		char *ptr;
		int size;
		int fl;
		int len;
		char *bp;
		ptr = code_getvptr( &pval, &size );
		p1 = code_getdi( 0 );
		if ( p1<0 ) throw HSPERR_BUFFER_OVERFLOW;
		ptr += p1;

		if ( code_get() <= PARAM_END ) {
			fl = HSPVAR_FLAG_INT;
			bp = (char *)&p2; p2 = 0;
		} else {
			fl = mpval->flag;
			bp = mpval->pt;
		}

		if ( cmd == 0x1a ) {
			switch( fl ) {
			case HSPVAR_FLAG_INT:
				if ( p1 >= size ) throw HSPERR_BUFFER_OVERFLOW;
				*ptr = *bp;
				break;
			case HSPVAR_FLAG_STR:
				len = (int)strlen( bp );
				ctx->strsize = len;
				len++;
				if ( (p1+len)>size ) throw HSPERR_BUFFER_OVERFLOW;
				strcpy( ptr, bp );
				break;
			default:
				throw HSPERR_TYPE_MISMATCH;
			}
			break;
		}

		if ( fl != HSPVAR_FLAG_INT ) throw HSPERR_TYPE_MISMATCH;
		if ( cmd == 0x1b ) {
			if ( (p1+2)>size ) throw HSPERR_BUFFER_OVERFLOW;
			*(short *)ptr = (short)(*(short *)bp);
		} else {
			if ( (p1+4)>size ) throw HSPERR_BUFFER_OVERFLOW;
			*(int *)ptr = (*(int *)bp);
		}
		break;
		}

	case 0x1d:								// getstr
		{
		PVal *pval2;
		PVal *pval;
		APTR aptr;
		char *ptr;
		char *p;
		int size;
		aptr = code_getva( &pval );
		ptr = code_getvptr( &pval2, &size );
		p1 = code_getdi( 0 );
		p2 = code_getdi( 0 );
		p3 = code_getdi( 1024 );
		if ( p1 >= size ) throw HSPERR_BUFFER_OVERFLOW;
		ptr += p1;
		p = code_stmp( p3 + 1 );
		strsp_ini();
		ctx->stat = strsp_get( ptr, p, p2, p3 );
		ctx->strsize = strsp_getptr();
		code_setva( pval, aptr, HSPVAR_FLAG_STR, p );
		break;
		}
	case 0x1e:								// chdpm
		code_event( HSPEVENT_FNAME, 0, 0, code_gets() );
		p1 = code_getdi( -1 );
		dpm_bye();
		p2 = dpm_ini( ctx->fnbuffer, 0, -1, p1 );
		if ( p2 ) throw HSPERR_FILE_IO;
#ifndef HSP3IMP
#ifdef HSPWIN
		Sleep( 1000 );
#endif
#endif
		break;
	case 0x1f:								// memexpand
		{
		PVal *pval;
		APTR aptr;
		PDAT *ptr;
		aptr = code_getva( &pval );
		ptr = HspVarCorePtrAPTR( pval, aptr );
		if (( pval->support & HSPVAR_SUPPORT_FLEXSTORAGE ) == 0 ) throw HSPERR_TYPE_MISMATCH;
		p1 = code_getdi( 0 );
		if ( p1 < 64 ) p1 = 64;
		HspVarCoreAllocBlock( pval, ptr, p1 );
		break;
		}

	case 0x20:								// memcpy
		{
		PVal *pval;
		char *sptr;
		char *tptr;
		int bufsize_t,bufsize_s;

		tptr = code_getvptr( &pval, &bufsize_t );
		sptr = code_getvptr( &pval, &bufsize_s );
		p1 = code_getdi( 0 );
		p2 = code_getdi( 0 );
		p3 = code_getdi( 0 );
		if( p2 < 0 || p3 < 0 ) throw HSPERR_BUFFER_OVERFLOW;

		tptr += p2;
		sptr += p3;
		if ( (p1+p2)>bufsize_t ) throw HSPERR_BUFFER_OVERFLOW;
		if ( (p1+p3)>bufsize_s ) throw HSPERR_BUFFER_OVERFLOW;
		if ( p1>0 ) {
			memmove( tptr, sptr, p1 );
		}
		break;
		}
	case 0x21:								// memset
		{
		PVal *pval;
		char *ptr;
		int size;
		ptr = code_getvptr( &pval, &size );
		p1 = code_getdi( 0 );
		p2 = code_getdi( 0 );
		p3 = code_getdi( 0 );
		if ( p3 < 0 ) throw HSPERR_BUFFER_OVERFLOW;
		ptr += p3;
		if ( (p3+p2)>size ) throw HSPERR_BUFFER_OVERFLOW;
		if ( p2>0 ) {
			memset( ptr, p1, p2 );
		}
		break;
		}

	case 0x22:								// notesel
		ctx->notep_aptr = ctx->note_aptr;
		ctx->notep_pval = ctx->note_pval;
		ctx->note_aptr = code_getva( &ctx->note_pval );
		if ( ctx->note_pval->flag != HSPVAR_FLAG_STR ) {
			code_setva( ctx->note_pval, ctx->note_aptr, TYPE_STRING, "" );
		}
		break;
	case 0x23:								// noteadd
		{
		char *np;
		char *ps;
		char *tmp;
		int size;
		np = note_update();
		ps = code_gets();
		size = (int)strlen( ps ) + 8;
		HspVarCoreAllocBlock( ctx->note_pval, (PDAT *)np, (int)strlen(np) + size );

		tmp = sbAlloc( size );
		strcpy( tmp, ps );

		p1 = code_getdi( -1 );
		p2 = code_getdi( 0 );
		np = note_update();
		note.PutLine( tmp, p1, p2 );
		sbFree( tmp );
		break;
		}
	case 0x24:								// notedel
		p1 = code_getdi( 0 );
		note_update();
		note.PutLine( NULL, p1, 1 );
		break;
	case 0x25:								// noteload
		{
		int size;
		char *ptr;
		char *pdat;

		code_event( HSPEVENT_FNAME, 0, 0, code_gets() );
		p1 = code_getdi( -1 );
		code_event( HSPEVENT_FEXIST, 0, 0, NULL );
		size = ctx->strsize;
		if ( size < 0 ) throw HSPERR_FILE_IO;
		if ( p1>=0 ) if ( size >= p1 ) { ctx->strsize = size = p1; }

		pdat = note_update();
		HspVarCoreAllocBlock( ctx->note_pval, (PDAT *)pdat, size+1 );
		ptr = (char *)note_update();
		code_event( HSPEVENT_FREAD, 0, size, ptr );
		ptr[size] = 0;
		break;
		}
	case 0x26:								// notesave
		{
		char *pdat;
		int size;
		code_event( HSPEVENT_FNAME, 0, 0, code_gets() );
		pdat = note_update();
		size = (int)strlen( pdat );
		code_event( HSPEVENT_FWRITE, -1, size, pdat );
		break;
		}
	case 0x27:								// randomize
#ifdef HSPWIN
		p2 = (int)GetTickCount();	// Windowsの場合はtickをシード値とする
#else
		p2 = (int)time(0);			// Windows以外のランダムシード値
#endif
		p1 = code_getdi( p2 );
		srand( p1 );
		break;
	case 0x28:								// noteunsel
		ctx->note_aptr = ctx->notep_aptr;
		ctx->note_pval = ctx->notep_pval;
		break;
	case 0x29:								// noteget
		{
		PVal *pval;
		APTR aptr;
		char *p;
		note_update();
		aptr = code_getva( &pval );
		p1 = code_getdi( 0 );
		p = note.GetLineDirect( p1 );
		code_setva( pval, aptr, TYPE_STRING, p );
		note.ResumeLineDirect();
		break;
		}
	case 0x2a:								// split
		{
		//	指定した文字列で分割された要素を代入する(fujidig)
		PVal *pval = NULL;
		int aptr = 0;
		char *sptr;
		char *sep;
		char *newsptr;
		int size;
		int sep_len;
		int n = 0;
		int is_last = 0;
		
		sptr = code_getvptr( &pval, &size );
		if ( pval->flag != HSPVAR_FLAG_STR ) throw HSPERR_TYPE_MISMATCH;
		sep = code_gets();
		sep_len = (int)strlen( sep );
		
		while (1) {
			newsptr = strstr2( sptr, sep );
			if ( !is_last && *exinfo->npexflg & EXFLG_1 ) {
				// 分割結果の数が格納する変数より多ければ最後の変数に配列で格納していく
				// ただし最後の要素が a.2 のように要素指定があればそれ以降は全く格納しない
				if ( aptr != 0 ) pval = NULL;
				is_last = 1;
				aptr = 0;
			}
			if ( is_last ) {
				aptr ++;
				if ( pval != NULL && aptr >= pval->len[1] ) {
					if ( pval->len[2] != 0 ) throw HSPVAR_ERROR_ARRAYOVER;
					HspVarCoreReDim( pval, 1, aptr+1 );
				}
			} else {
				aptr = code_getva( &pval );
			}
			if ( pval != NULL ) {
				if ( newsptr == NULL ) {
					code_setva( pval, aptr, HSPVAR_FLAG_STR, sptr );
				} else {
					var_set_str_len( pval, aptr, sptr, (int)(newsptr - sptr) );
				}
			}
			n ++;
			if ( newsptr == NULL ) {
				// 格納する変数の数が分割できた数より多ければ残った変数それぞれに空文字列を格納する
				while( ( *exinfo->npexflg & EXFLG_1 ) == 0 ) {
					aptr = code_getva( &pval );
					code_setva( pval, aptr, HSPVAR_FLAG_STR, "" );
				}
				break;
			}
			sptr = newsptr + sep_len;
		}
		ctx->stat = n;
		break;
		}


	default:
		throw HSPERR_UNSUPPORTED_FUNCTION;
	}
	return RUNMODE_RUN;
}
Esempio n. 16
0
void genDwarfEh(Funcsym *sfunc, int seg, Outbuffer *et, bool scancode, unsigned startoffset, unsigned retoffset)
{
#ifdef DEBUG
    unittest_dwarfeh();
#endif

    /* LPstart = encoding of LPbase
     * LPbase = landing pad base (normally omitted)
     * TType = encoding of TTbase
     * TTbase = offset from next byte to past end of Type Table
     * CallSiteFormat = encoding of fields in Call Site Table
     * CallSiteTableSize = size in bytes of Call Site Table
     * Call Site Table[]:
     *    CallSiteStart
     *    CallSiteRange
     *    LandingPad
     *    ActionRecordPtr
     * Action Table
     *    TypeFilter
     *    NextRecordPtr
     * Type Table
     */

    et->reserve(100);
    block *startblock = sfunc->Sfunc->Fstartblock;
    //printf("genDwarfEh: func = %s, offset = x%x, startblock->Boffset = x%x, scancode = %d startoffset=x%x, retoffset=x%x\n",
      //sfunc->Sident, (int)sfunc->Soffset, (int)startblock->Boffset, scancode, startoffset, retoffset);

#if 0
    printf("------- before ----------\n");
    for (block *b = startblock; b; b = b->Bnext) WRblock(b);
    printf("-------------------------\n");
#endif

    unsigned startsize = et->size();
    assert((startsize & 3) == 0);       // should be aligned

    DwEhTable *deh = &dwehtable;
    deh->dim = 0;
    Outbuffer atbuf;
    Outbuffer cstbuf;

    /* Build deh table, and Action Table
     */
    int index = -1;
    block *bprev = NULL;
    // The first entry encompasses the entire function
    {
        unsigned i = deh->push();
        DwEhTableEntry *d = deh->index(i);
        d->start = startblock->Boffset + startoffset;
        d->end = startblock->Boffset + retoffset;
        d->lpad = 0;                    // no cleanup, no catches
        index = i;
    }
    for (block *b = startblock; b; b = b->Bnext)
    {
        if (index > 0 && b->Btry == bprev)
        {
            DwEhTableEntry *d = deh->index(index);
            d->end = b->Boffset;
            index = d->prev;
            if (bprev)
                bprev = bprev->Btry;
        }
        if (b->BC == BC_try)
        {
            unsigned i = deh->push();
            DwEhTableEntry *d = deh->index(i);
            d->start = b->Boffset;

            block *bf = b->nthSucc(1);
            if (bf->BC == BCjcatch)
            {
                d->lpad = bf->Boffset;
                d->bcatch = bf;
                unsigned *pat = bf->BS.BIJCATCH.actionTable;
                unsigned length = pat[0];
                assert(length);
                unsigned offset = -1;
                for (unsigned u = length; u; --u)
                {
                    /* Buy doing depth-first insertion into the Action Table,
                     * we can combine common tails.
                     */
                    offset = actionTableInsert(&atbuf, pat[u], offset);
                }
                d->action = offset + 1;
            }
            else
                d->lpad = bf->nthSucc(0)->Boffset;
            d->prev = index;
            index = i;
            bprev = b->Btry;
        }
        if (scancode)
        {
            unsigned coffset = b->Boffset;
            int n = 0;
            for (code *c = b->Bcode; c; c = code_next(c))
            {
                if (c->Iop == (ESCAPE | ESCdctor))
                {
                    unsigned i = deh->push();
                    DwEhTableEntry *d = deh->index(i);
                    d->start = coffset;
                    d->prev = index;
                    index = i;
                    ++n;
                }

                if (c->Iop == (ESCAPE | ESCddtor))
                {
                    assert(n > 0);
                    --n;
                    DwEhTableEntry *d = deh->index(index);
                    d->end = coffset;
                    d->lpad = coffset;
                    index = d->prev;
                }
                coffset += calccodsize(c);
            }
            assert(n == 0);
        }
    }
    //printf("deh->dim = %d\n", (int)deh->dim);

#if 1
    /* Build Call Site Table
     * Be sure to not generate empty entries,
     * and generate nested ranges reflecting the layout in the code.
     */
    assert(deh->dim);
    unsigned end = deh->index(0)->start;
    for (unsigned i = 0; i < deh->dim; ++i)
    {
        DwEhTableEntry *d = deh->index(i);
        if (d->start < d->end)
        {
#if ELFOBJ
                #define WRITE writeuLEB128
#elif MACHOBJ
                #define WRITE write32
#else
                assert(0);
#endif
                unsigned CallSiteStart = d->start - startblock->Boffset;
                cstbuf.WRITE(CallSiteStart);
                unsigned CallSiteRange = d->end - d->start;
                cstbuf.WRITE(CallSiteRange);
                unsigned LandingPad = d->lpad ? d->lpad - startblock->Boffset : 0;
                cstbuf.WRITE(LandingPad);
                unsigned ActionTable = d->action;
                cstbuf.writeuLEB128(ActionTable);
                //printf("\t%x %x %x %x\n", CallSiteStart, CallSiteRange, LandingPad, ActionTable);
                #undef WRITE
        }
    }
#else
    /* Build Call Site Table
     * Be sure to not generate empty entries,
     * and generate multiple entries for one DwEhTableEntry if the latter
     * is split by nested DwEhTableEntry's. This is based on the (undocumented)
     * presumption that there may not
     * be overlapping entries in the Call Site Table.
     */
    assert(deh->dim);
    unsigned end = deh->index(0)->start;
    for (unsigned i = 0; i < deh->dim; ++i)
    {
        unsigned j = i;
        do
        {
            DwEhTableEntry *d = deh->index(j);
            //printf(" [%d] start=%x end=%x lpad=%x action=%x bcatch=%p prev=%d\n",
            //  j, d->start, d->end, d->lpad, d->action, d->bcatch, d->prev);
            if (d->start <= end && end < d->end)
            {
                unsigned start = end;
                unsigned dend = d->end;
                if (i + 1 < deh->dim)
                {
                    DwEhTableEntry *dnext = deh->index(i + 1);
                    if (dnext->start < dend)
                        dend = dnext->start;
                }
                if (start < dend)
                {
#if ELFOBJ
                    #define WRITE writeLEB128
#elif MACHOBJ
                    #define WRITE write32
#else
                    assert(0);
#endif
                    unsigned CallSiteStart = start - startblock->Boffset;
                    cstbuf.WRITE(CallSiteStart);
                    unsigned CallSiteRange = dend - start;
                    cstbuf.WRITE(CallSiteRange);
                    unsigned LandingPad = d->lpad - startblock->Boffset;
                    cstbuf.WRITE(LandingPad);
                    unsigned ActionTable = d->action;
                    cstbuf.WRITE(ActionTable);
                    //printf("\t%x %x %x %x\n", CallSiteStart, CallSiteRange, LandingPad, ActionTable);
                    #undef WRITE
                }

                end = dend;
            }
        } while (j--);
    }
#endif

    /* Write LSDT header */
    const unsigned char LPstart = DW_EH_PE_omit;
    et->writeByte(LPstart);
    unsigned LPbase = 0;
    if (LPstart != DW_EH_PE_omit)
        et->writeuLEB128(LPbase);

    const unsigned char TType = (config.flags3 & CFG3pic)
                                ? DW_EH_PE_indirect | DW_EH_PE_pcrel | DW_EH_PE_sdata4
                                : DW_EH_PE_absptr | DW_EH_PE_udata4;
    et->writeByte(TType);

    /* Compute TTbase, which is the sum of:
     *  1. CallSiteFormat
     *  2. encoding of CallSiteTableSize
     *  3. Call Site Table size
     *  4. Action Table size
     *  5. 4 byte alignment
     *  6. Types Table
     * Iterate until it converges.
     */
    unsigned TTbase = 1;
    unsigned CallSiteTableSize = cstbuf.size();
    unsigned oldTTbase;
    do
    {
        oldTTbase = TTbase;
        unsigned start = (et->size() - startsize) + uLEB128size(TTbase);
        TTbase = 1 +
                uLEB128size(CallSiteTableSize) +
                CallSiteTableSize +
                atbuf.size();
        unsigned sz = start + TTbase;
        TTbase += -sz & 3;      // align to 4
        TTbase += sfunc->Sfunc->typesTableDim * 4;
    } while (TTbase != oldTTbase);

    if (TType != DW_EH_PE_omit)
        et->writeuLEB128(TTbase);
    unsigned TToffset = TTbase + et->size() - startsize;

#if ELFOBJ
    const unsigned char CallSiteFormat = DW_EH_PE_absptr | DW_EH_PE_uleb128;
#elif MACHOBJ
    const unsigned char CallSiteFormat = DW_EH_PE_absptr | DW_EH_PE_udata4;
#else
    assert(0);
#endif
    et->writeByte(CallSiteFormat);
    et->writeuLEB128(CallSiteTableSize);


    /* Insert Call Site Table */
    et->write(&cstbuf);

    /* Insert Action Table */
    et->write(&atbuf);

    /* Align to 4 */
    for (unsigned n = (-et->size() & 3); n; --n)
        et->writeByte(0);

    /* Write out Types Table in reverse */
    Symbol **typesTable = sfunc->Sfunc->typesTable;
    for (int i = sfunc->Sfunc->typesTableDim; i--; )
    {
        Symbol *s = typesTable[i];
        /* MACHOBJ 64: pcrel 1 length 1 extern 1 RELOC_GOT
         *         32: [0] address x004c pcrel 0 length 2 value x224 type 4 RELOC_LOCAL_SECTDIFF
         *             [1] address x0000 pcrel 0 length 2 value x160 type 1 RELOC_PAIR
         */
        dwarf_reftoident(seg, et->size(), s, 0);
    }
    assert(TToffset == et->size() - startsize);
}