Example #1
0
static void
exec_set_descr(YogEnv* env, YogVal attr, YogVal obj, YogVal val)
{
    SAVE_ARGS3(env, attr, obj, val);
    YogVal setter = YUNDEF;
    YogVal class_of_setter = YUNDEF;
    YogVal method = YUNDEF;
    YogVal class_of_method = YUNDEF;
    YogVal class_of_obj = YUNDEF;
    PUSH_LOCALS5(env, setter, class_of_setter, method, class_of_method, class_of_obj);
    YogHandle* args[] = { YogHandle_REGISTER(env, val) };

    setter = PTR_AS(YogProperty, attr)->setter;
    class_of_setter = YogVal_get_class(env, setter);
    if (!IS_PTR(setter)) {
        ID id = PTR_AS(YogClass, class_of_setter)->name;
        YogError_raise_TypeError(env, "\"%I\" object is not callable", id);
    }
    class_of_obj = YogVal_get_class(env, obj);
    YOG_ASSERT(env, PTR_AS(YogClass, class_of_setter)->call_get_descr != NULL, "can't make instance method");
    method = PTR_AS(YogClass, class_of_setter)->call_get_descr(env, setter, obj, class_of_obj);
    YOG_ASSERT(env, IS_PTR(method), "method isn't pointer");
    class_of_method = YogVal_get_class(env, method);
    Executor exec = PTR_AS(YogClass, class_of_method)->exec;
    YOG_ASSERT(env, exec != NULL, "method isn't callable");

    YogHandle* h_method = YogHandle_REGISTER(env, method);
    exec(env, h_method, array_sizeof(args), args, 0, NULL, NULL, NULL, NULL);

    RETURN_VOID(env);
}
Example #2
0
static YogVal
import(YogEnv* env, YogVM* vm, YogHandle* path_head, YogHandle* pkg_name)
{
    SAVE_LOCALS(env);
    YogVal pkg = YUNDEF;
    YogVal body = YUNDEF;
    YogVal yog = YUNDEF;
    PUSH_LOCALS3(env, pkg, body, yog);

    uint_t size = YogArray_size(env, vm->search_path);
    uint_t i;
    for (i = 0; i < size; i++) {
        YogHandle* dir = VAL2HDL(env, YogArray_at(env, vm->search_path, i));
        YogHandle* yog = make_package_path(env, dir, path_head, ".yog");
        pkg = import_yog(env, yog, pkg_name);
        if (IS_PTR(pkg)) {
            RETURN(env, pkg);
        }

        YogHandle* so = make_package_path(env, dir, path_head, ".so");
        pkg = import_so(env, vm, so, pkg_name);
        if (IS_PTR(pkg)) {
            RETURN(env, pkg);
        }
    }

    const char* fmt = "No package named \"%S\"";
    YogError_raise_ImportError(env, fmt, HDL2VAL(pkg_name));
    /* NOTREACHED */

    RETURN(env, YUNDEF);
}
Example #3
0
static YogVal
call_get_descr(YogEnv* env, YogVal attr, YogVal obj, YogVal klass)
{
    SAVE_ARGS3(env, attr, obj, klass);
    YogVal getter = YUNDEF;
    YogVal class_of_getter = YUNDEF;
    YogVal method = YUNDEF;
    YogVal class_of_method = YUNDEF;
    YogVal retval = YUNDEF;
    PUSH_LOCALS5(env, getter, class_of_getter, method, class_of_method, retval);

    getter = PTR_AS(YogProperty, attr)->getter;
    class_of_getter = YogVal_get_class(env, getter);
    if (!IS_PTR(getter)) {
        ID id = PTR_AS(YogClass, class_of_getter)->name;
        YogError_raise_TypeError(env, "\"%I\" object is not callable", id);
    }
    YOG_ASSERT(env, PTR_AS(YogClass, class_of_getter)->call_get_descr != NULL, "can't make instance method");
    method = PTR_AS(YogClass, class_of_getter)->call_get_descr(env, getter, obj, klass);
    YOG_ASSERT(env, IS_PTR(method), "method isn't pointer");
    class_of_method = YogVal_get_class(env, method);
    Caller call = PTR_AS(YogClass, class_of_method)->call;
    YOG_ASSERT(env, call != NULL, "method isn't callable");
    YogHandle* h_method = YogHandle_REGISTER(env, method);
    retval = call(env, h_method, 0, NULL, 0, NULL, NULL, NULL, NULL);

    RETURN(env, retval);
}
Example #4
0
void
YogVM_remove_thread(YogEnv* env, YogVM* vm, YogVal thread)
{
    SAVE_ARG(env, thread);

    YogVM_acquire_global_interp_lock(env, vm);
    gc(env, vm);

    YogVal prev = PTR_AS(YogThread, thread)->prev;
    YogVal next = PTR_AS(YogThread, thread)->next;
    if (IS_PTR(prev)) {
        YogGC_UPDATE_PTR(env, PTR_AS(YogThread, prev), next, next);
    }
    else {
        vm->running_threads = next;
    }
    if (IS_PTR(next)) {
        YogGC_UPDATE_PTR(env, PTR_AS(YogThread, next), prev, prev);
    }

    if (!IS_PTR(vm->running_threads)) {
        pthread_cond_signal(&vm->vm_finish_cond);
    }

    RESTORE_LOCALS(env);

    YogVM_release_global_interp_lock(env, vm);
}
Example #5
0
uchar *
dbg_print_domain(uchar * hdr, uchar * itor)
{
    uchar len;
    uchar *tmp = NULL;
    ushort offset;
    int debug = 100;
    len = itor[0];
    if (len == 0) {
        printf("root\n");
        return 0;
    }
    offset = ntohs((ushort) * (ushort *) itor);
    if (IS_PTR(offset))
        itor = hdr + GET_OFFSET(offset);
    while (len != 0 && debug--) {
        if (IS_PTR(offset)) {
            tmp = itor + 2;
            itor = dbg_print_label(hdr + GET_OFFSET(offset), 1);
        } else
            itor = dbg_print_label(itor, 1);
        printf(".");
        len = itor[0];
        offset = ntohs((ushort) * (ushort *) itor);
    }
    printf("\n");
    if (tmp == NULL)
        tmp = itor + 1;
    return tmp;
}
Example #6
0
static void type_add_str_pre(
		type *r,
		int *need_paren, int *need_spc,
		char **bufp, int *sz)
{
	type *prev_skipped;
	enum type_qualifier q = qual_none;

	/* int (**fn())[2]
	 * btype -> array -> ptr -> ptr -> func
	 *                ^ parens
	 *
	 * .tmp looks right, down the chain, .ref looks left, up the chain
	 */
	*need_paren = r->ref
		&& IS_PTR(r->type)
		&& (prev_skipped = type_skip_all(r->ref))->type != type_btype
		&& !IS_PTR(prev_skipped->type);

	if(*need_paren){
		ADD_SPC();
		BUF_ADD("(");
	}

	switch(r->type){
		case type_ptr:
#ifdef SHOW_DECAYED_ARRAYS
			if(r->bits.ptr.size)
				break; /* decayed array */
#endif

			ADD_SPC();
			BUF_ADD("*");
			break;

		case type_cast:
			q = r->bits.cast.qual;
			break;

		case type_block:
			ADD_SPC();
			BUF_ADD("^");
			break;

		default:break;
	}

	if(q){
		ADD_SPC();
		BUF_ADD("%s", type_qual_to_str(q, 0));
		*need_spc = 1;
		/* space out after qualifier, e.g.
		 * int *const p;
		 *           ^
		 * int const a;
		 *          ^
		 */
	}
}
Example #7
0
//----------------------------------------------------------//
// CFileManager::Open
//----------------------------------------------------------//
//-- Description
// Returns a pointer to open file if it exists, even if
// the file already existed.
// If returned pointer is not null, you should always test
// the type of the file to confirm it is the same as the 
// one requested to open.
//----------------------------------------------------------//
const CFileData* CFileManager::Open(s8* strFileName, CFileData::Type::Enum eType, CFileData::AccessMethod::Enum eAccess)
{
	switch (eAccess)
	{
		case CFileData::AccessMethod::DirectRead:
		case CFileData::AccessMethod::DirectWrite:
		{
			const CFileData* pFile = Find(strFileName);
			if (IS_PTR(pFile))
			{
				//-- Already exists.
				return pFile;
			}
			else
			{
				//-- Not found. Add it.
				m_DirectFiles.push_back(CFileData(strFileName, eType, eAccess));
				return &(m_DirectFiles.back());
			}
		}
		break;

		case CFileData::AccessMethod::BufferedRead:
		case CFileData::AccessMethod::BufferedWrite:
		case CFileData::AccessMethod::AsyncRead:
		case CFileData::AccessMethod::AsyncWrite:
		case CFileData::AccessMethod::StreamedRead:
		{
			const CFileData* pFile = Find(strFileName);
			if (IS_PTR(pFile))
			{
				//-- Already exists.
				return pFile;
			}
			else
			{
				//-- Not found. Add it.
				m_BufferedFiles.push_back(CFileData(strFileName, eType, eAccess));
				return &(m_BufferedFiles.back());
			}
		}
		break;

		default:
		{
			return NULL;
		}
		break;
	}

	return NULL;
}
Example #8
0
static int Scalar2VRegLoad(short sid)
/*
 * this function loads a scalar variable into vector register 
 */
{
   short reg, typ, vtyp;
   enum inst inst;
   sid--;
   vtyp = 0;
   typ = FLAG2TYPE(STflag[sid]);
   if (!IS_CONST(STflag[sid]) && !IS_PTR(STflag[sid]))
   {
      switch(typ)
      {
         case T_FLOAT:
            vtyp = T_VFLOAT;
            inst = VFLDS;
            break;
         case T_DOUBLE:
            vtyp = T_VDOUBLE;
            inst = VDLDS;
            break;
         default:
            fko_error(__LINE__, "type not supported!!");
      }
   }
   else
      fko_error(__LINE__, "not supported for const/ptr!!");
   
   reg = GetReg(vtyp);
   InsNewInst(NULL, NULL, NULL, inst, -reg, SToff[sid].sa[2], 0);
   return(reg);
}
Example #9
0
static YogVal
end_str(YogEnv* env, YogVal self, YogVal group)
{
    YOG_ASSERT(env, IS_PTR(group), "invalid group (0x%x)", group);
    YOG_ASSERT(env, BASIC_OBJ_TYPE(group) == TYPE_STRING, "invalid group type (0x%0x)", BASIC_OBJ_TYPE(group));
    return end_num(env, self, group_name2id(env, self, group));
}
Example #10
0
static void
raise_ZipError(YogEnv* env, YogVal pkg, const char* msg)
{
    SAVE_ARG(env, pkg);
    YogVal eZipError = YUNDEF;
    YogVal e = YUNDEF;
    YogVal s = YUNDEF;
    PUSH_LOCALS3(env, eZipError, e, s);
    if (!IS_PTR(pkg) || (BASIC_OBJ_TYPE(pkg) != TYPE_ZIP_PKG)) {
        YogError_raise_TypeError(env, "package type must be TYPE_ZIP_PKG");
    }

    eZipError = PTR_AS(Package, pkg)->eZipError;
    if (msg != NULL) {
        s = YogString_from_string(env, msg);
        e = YogEval_call_method1(env, eZipError, "new", s);
    }
    else {
        e = YogEval_call_method0(env, eZipError, "new");
    }
    YogError_raise(env, e);
    /* NOTREACHED */

    RETURN_VOID(env);
}
Example #11
0
static YogVal
end(YogEnv* env, YogVal self, YogVal pkg, YogVal args, YogVal kw, YogVal block)
{
    SAVE_ARGS5(env, self, pkg, args, kw, block);
    YogVal group = YNIL;
    YogVal retval = YUNDEF;
    PUSH_LOCALS2(env, group, retval);

    YogCArg params[] = { { "|", NULL }, { "group", &group }, { NULL, NULL } };
    YogGetArgs_parse_args(env, "end", params, args, kw);
    CHECK_SELF_MATCH(env, self);

    if (IS_FIXNUM(group)) {
        retval = end_num(env, self, VAL2INT(group));
    }
    else if (IS_NIL(group)) {
        retval = end_num(env, self, 0);
    }
    else if (IS_PTR(group) && (BASIC_OBJ_TYPE(group) == TYPE_STRING)) {
        retval = end_str(env, self, group);
    }
    else {
        raise_invalid_group(env, group);
    }

    RETURN(env, retval);
}
Example #12
0
uint32_t hash_value(value_t val) {
#if NANTAG
    if (IS_PTR(val)) {
        return hash_ptr(AS_PTR(val));
    } else {
        value_conv_t data;
        data.bits = val;
        return hash_number(data.bits);
    }
#else   // ! NANTAG
    switch (val.type) {
        case V_NIL:
            return 0;
        case V_TRUE:
            return 1;
        case V_FALSE:
            return 2;
        case V_UNDEFINED:
            return 3;
        case V_NUM:
            return hash_number(AS_NUM(val));
        case V_PTR:
            return hash_ptr(AS_PTR(val));
        default:
            return 0;
    }
#endif  // NANTAG
}
Example #13
0
CFileManager::Error::Enum CFileManager::Close(const CFileData* pFile)
{
	if (IS_PTR(pFile))
	{
		return Close(pFile->GetHash());
	}

	return Error::FileNotFound;
}
Example #14
0
YogVal
YogRegexp_binop_search(YogEnv* env, YogHandle* self, YogHandle* s)
{
    if (!IS_PTR(HDL2VAL(s)) || (BASIC_OBJ_TYPE(HDL2VAL(s)) != TYPE_STRING)) {
        YogError_raise_TypeError(env, "Can't convert %C object to String implicitly", HDL2VAL(s));
        /* NOTREACHED */
    }
    return YogString_search(env, s, self, 0);
}
//----------------------------------------------------------//
// CWinSysRollupContainer::EventProc
//----------------------------------------------------------//
//-- Description
// Window Procedure for handling events sent to the rollup 
// container window.
// Container window will process any mouse clicks within
// title bar areas of the rollups, because the title bars are
// not part of the rollup dialog resources, and so will NOT 
// generate events in WinSys_RollupProc.
// The rollup container also holds the animation timer used
// to animate the rollups.
//----------------------------------------------------------//
LRESULT CALLBACK CWinSysRollupContainer::StaticWndEventProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam)
{
	CWinSysRollupContainer* pThis = reinterpret_cast<CWinSysRollupContainer*>(GetWindowLongPtr(hWnd, GWLP_USERDATA));
	if (IS_PTR(pThis))
	{
		return pThis->WndEventProc(hWnd, nMsg, wParam, lParam);
	}

	return DefWindowProc(hWnd, nMsg, wParam, lParam);
}
Example #16
0
//----------------------------------------------------------//
// CSQLiteDatabase::Close
//----------------------------------------------------------//
//-- Description
//----------------------------------------------------------//
s32	CSQLiteDatabase::Close(void)
{
	if (IS_PTR(m_pDatabase))
	{
		s32 nRet = sqlite3_close(m_pDatabase);
		m_pDatabase = NULL;
		return nRet;
	}

	return SQLITE_OK;
}
Example #17
0
static YogVal
create_string(YogEnv* env, YogVal self, YogVal pkg, YogVal args, YogVal kw, YogVal block)
{
    SAVE_ARGS5(env, self, pkg, args, kw, block);
    YogCArg params[] = { { NULL, NULL } };
    YogGetArgs_parse_args(env, "create_string", params, args, kw);
    if (!IS_PTR(self) || (BASIC_OBJ_TYPE(self) != TYPE_ENCODING)) {
        YogError_raise_TypeError((env), "self must be Encoding");
    }
    RETURN(env, YogString_new(env));
}
Example #18
0
YogEnv*
YogVM_get_env(YogVM* vm)
{
    YogVM_acquire_global_interp_lock(NULL, vm);
    pthread_t self = pthread_self();
    YogVal thread = vm->running_threads;
    while (IS_PTR(thread)) {
        if (pthread_equal(self, PTR_AS(YogThread, thread)->pthread)) {
            break;
        }
        thread = PTR_AS(YogThread, thread)->next;
    }
    YogVM_release_global_interp_lock(NULL, vm);

    if (IS_PTR(thread)) {
        return PTR_AS(YogThread, thread)->env;
    }
    else {
        return NULL;
    }
}
//----------------------------------------------------------//
// CFileDirectTextReader::GetString
//----------------------------------------------------------//
//-- Description
// Read a string from an open direct access file.
// A string is determined as terminated by a newline
// character or the end of file. Any trailing newline will be
// stripped from the output string.
//----------------------------------------------------------//
s8* CFileDirectTextReader::GetString(s8* pDstBuffer, size_t nDstBufferSize)
{
	if ( IS_TRUE(Validate())
		&& IS_TRUE(IsOpen())
		&& IS_PTR(pDstBuffer)
		&& (nDstBufferSize > 0) )
	{
		return SysFileIO::Fgets(m_pFile, pDstBuffer, nDstBufferSize);
	}

	return NULL;
}
Example #20
0
YogVal
YogClass_get_attr_and_defining_class(YogEnv* env, YogVal self, ID name, YogVal* defining_class)
{
    YogVal klass = self;
    YogVal attr = YUNDEF;
    while (IS_UNDEF(attr) && IS_PTR(klass)) {
        *defining_class = klass;
        attr = YogObj_get_attr(env, klass, name);
        klass = PTR_AS(YogClass, klass)->super;
    }
    return attr;
}
Example #21
0
static YogVal
repr_as_str(YogEnv* env, YogVal obj)
{
    if (IS_PTR(obj) && (BASIC_OBJ_TYPE(obj) == TYPE_STRING)) {
        return obj;
    }
    YogHandle* h = VAL2HDL(env, obj);

#define METHOD_NAME "to_s"
    YogVal s = YogEval_call_method0(env, obj, METHOD_NAME);
    YOG_ASSERT(env, !IS_UNDEF(s), "%s returned undef", METHOD_NAME);
    if (IS_PTR(s) && (BASIC_OBJ_TYPE(s) == TYPE_STRING)) {
        return s;
    }
    const char* fmt = "%C#%s() returned non-string (%C)";
    YogError_raise_TypeError(env, fmt, HDL2VAL(h), METHOD_NAME, s);
#undef METHOD_NAME
    /* NOTREACHED */

    return YUNDEF;
}
Example #22
0
static uint_t
count_running_threads(YogEnv* env, YogVM* vm)
{
    uint_t n = 0;
    YogVal thread = vm->running_threads;
    while (IS_PTR(thread)) {
        n++;
        thread = PTR_AS(YogThread, thread)->next;
    }

    return n;
}
Example #23
0
File: fat.c Project: nielh/dragon
static s64 file_close(void* obj)
{
	assert(IS_PTR(obj));

	fatfile_t* file = (fatfile_t*)obj;

	down(&file->sem);

    assert(file->ref > 0);
    file->ref --;

    up_one(&file->sem);
    return 0;
}
Example #24
0
static YogVal
mkdir_(YogEnv* env, YogHandle* self, YogHandle* pkg, YogHandle* path)
{
    YogVal obj = HDL2VAL(path);
    if (!IS_PTR(obj) || (BASIC_OBJ_TYPE(obj) != TYPE_STRING)) {
        YogError_raise_TypeError(env, "path must be String");
    }

    YogVal s = YogString_to_bin_in_default_encoding(env, path);
    if (YogSysdeps_mkdir(BINARY_CSTR(s)) != 0) {
        YogError_raise_sys_err(env, errno, HDL2VAL(path));
    }

    return YNIL;
}
Example #25
0
static void
wait_package(YogEnv* env, YogVal pkg)
{
    SAVE_ARG(env, pkg);

    pthread_cond_t* cond = &PTR_AS(ImportingPackage, pkg)->cond;
    pthread_mutex_t* lock = &PTR_AS(ImportingPackage, pkg)->lock;
    while (!IS_PTR(PTR_AS(ImportingPackage, pkg)->pkg)) {
        YogGC_free_from_gc(env);
        pthread_cond_wait(cond, lock);
        YogGC_bind_to_gc(env);
    }

    RETURN_VOID(env);
}
Example #26
0
void HandlePtrArith(short dest, short src0, char op, short src1)
/*
 * Ptr arithmetic must be of form <ptr> = <ptr> [+,-] <int/const>
 */
{
   short rs0, rs1, flag, type, dflag;
   #ifdef X86_64
      short k;
   #endif
   if (op != '+' && op != '-')
      fko_error(__LINE__,"pointers may take only + and - operators");
   if (!IS_PTR(STflag[src0-1]))
      fko_error(__LINE__,"Expecting <ptr> = <ptr> + <int>");
   
/*
 * Majedul: The concept of LIL as three address code violets here. We have 
 * multiple operations in single load-store block. For example:
 *    A1 = A0  + lda is actually treated as 
 *    A1 = A0 + (lda * size)
 * So, we have addition and shift in same load-store block. This would create
 * redundant computation. We eliminate the redundant computation of (lda*size),
 * we need to split this expression out and treated this as two HIL instruction
 * while converting this into LIL, like:
 *    _lda = lda * size
 *    A1 = A0 + _lda
 * NOTE: All variables starting with '_' are compiler's internal variables, 
 * should not be used as variable name in HIL
 */

   dflag = STflag[dest-1];
   type = FLAG2TYPE(dflag);
   flag = STflag[src1-1];

   if (IS_CONST(flag))
   {
      rs0 = LocalLoad(src0); /* load src0 */
      if (IS_INT(flag))
      #ifdef X86_64
      {
         if (IS_INT(dflag)) rs1 = -STiconstlookup(SToff[src1-1].i*4);
         else rs1 = -STiconstlookup(SToff[src1-1].i*type2len(type));
      }
      #else
         rs1 = -STiconstlookup(SToff[src1-1].i*type2len(type));
      #endif
      else
         fko_error(__LINE__,"Pointers may only be incremented by integers");
   }
Example #27
0
static YogVal
group(YogEnv* env, YogHandle* self, YogHandle* pkg, YogHandle* group)
{
    CHECK_SELF_MATCH2(env, self);

    if ((group == NULL) || IS_NIL(HDL2VAL(group))) {
        return group_num(env, self, 0);
    }
    if (IS_FIXNUM(HDL2VAL(group))) {
        return group_num(env, self, VAL2INT(HDL2VAL(group)));
    }
    if (IS_PTR(HDL2VAL(group)) && (BASIC_OBJ_TYPE(HDL2VAL(group)) == TYPE_STRING)) {
        return group_str(env, self, group);
    }
    raise_invalid_group(env, HDL2VAL(group));
    return YUNDEF;
}
Example #28
0
//transfrom domain from lenlabel format to string
int
get_domain_from_msg(uchar * itor, uchar * hdr, uchar * to, int *tmplen)
{
    uchar len;
    ushort offset = 0;
    len = itor[0];
    int dlen = 0;
    int hasptr = 0, infinite = 20;
    offset = ntohs((ushort) * (ushort *) itor);
    *tmplen = 0;
    while ((len != 0) && (infinite--)) {
        if (IS_PTR(offset)) {
            itor = hdr + GET_OFFSET(offset);
            if (hasptr == 0) {
                dlen = 2;
                if (*tmplen != 0)
                    dlen += *tmplen;
            }
            hasptr = 1;
            offset = ntohs((ushort) * (ushort *) itor);
            continue;
        }
        to[0] = itor[0];
        *tmplen += 1;            //len
        *tmplen += to[0];        //label
        if (to[0] > 64)
            return -1;
        to++;
        memcpy(to, itor + 1, itor[0]);
        to += itor[0];
        itor = itor + itor[0] + 1;
        len = itor[0];
        offset = ntohs((ushort) * (ushort *) itor);
    }
    if (infinite <= 0)          //loops error
        return -1;
    to[0] = 0;
    to++;
    (*tmplen)++;
    if (dlen == 0)
        dlen = *tmplen;          //root len is 1
    if (dlen > MAX_DOMAIN_LEN)
        return -1;
    return dlen;
}
Example #29
0
static int_t
group_name2id(YogEnv* env, YogVal self, YogVal group)
{
    YOG_ASSERT(env, IS_PTR(group), "invalid group (0x%x)", group);
    YOG_ASSERT(env, BASIC_OBJ_TYPE(group) == TYPE_STRING, "invalid group type (0x%x)", BASIC_OBJ_TYPE(group));

    YogVal regexp = PTR_AS(YogMatch, self)->regexp;
    CorgiRegexp* corgi_regexp = PTR_AS(YogRegexp, regexp)->corgi_regexp;
    YogChar* begin = STRING_CHARS(group);
    YogChar* end = begin + STRING_SIZE(group);

    uint_t id;
    CorgiStatus status = corgi_group_name2id(corgi_regexp, begin, end, &id);
    if (status != CORGI_OK) {
        YogError_raise_IndexError(env, "No such group: %S", group);
    }

    return id + 1;
}
Example #30
0
/* Do CSE estimation */
static bool cseCostEstimation (iCode *ic, iCode *pdic)
{
    operand *result = IC_RESULT(ic);
    sym_link *result_type = operandType(result);

    /* if it is a pointer then return ok for now */
    if (IC_RESULT(ic) && IS_PTR(result_type)) return 1;

    /* if bitwise | add & subtract then no since xa51 is pretty good at it
       so we will cse only if they are local (i.e. both ic & pdic belong to
       the same basic block */
    if (IS_BITWISE_OP(ic) || ic->op == '+' || ic->op == '-') {
        /* then if they are the same Basic block then ok */
        if (ic->eBBlockNum == pdic->eBBlockNum) return 1;
        else return 0;
    }

    /* for others it is cheaper to do the cse */
    return 1;
}