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); }
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); }
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); }
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); }
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; }
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; * ^ */ } }
//----------------------------------------------------------// // 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; }
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); }
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)); }
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); }
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); }
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 }
CFileManager::Error::Enum CFileManager::Close(const CFileData* pFile) { if (IS_PTR(pFile)) { return Close(pFile->GetHash()); } return Error::FileNotFound; }
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); }
//----------------------------------------------------------// // 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; }
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)); }
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; }
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; }
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; }
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; }
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; }
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; }
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); }
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"); }
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; }
//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; }
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; }
/* 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; }