/// @addtogroup ProcObjects /// /// <b>IA32</b> The IA32 implementation uses the Load-Immediate /// method, storing the closure record pointer into /// <code>@%eax</code>. No other register is touched, and /// <code>@%eax</code> is reserved on this architecture for use as the /// return register. Note that <code>@%eax</code> is considered /// call-clobbered even when the called procedure /// returns <code>void</code>. void * bitc_emit_procedure_object(void *stubP, void *envP) { //uint32_t envW = (uint32_t) envP; uint32_t stubW = (uint32_t) stubP; bitc_Procedure* proc = GC_ALLOC(sizeof(bitc_Procedure)); proc->code[0] = 0x90; /* padding */ proc->code[1] = 0x90; proc->code[2] = 0x90; /* movl $envP,%eax */ proc->code[3] = 0xb8u; /* MOV imm,%eax */ /* [4..7] will be filled in via env.ptr */ /* jmp rel32 */ stubW -= (uint32_t)&proc->code[13]; proc->code[8] = 0xe9u; proc->code[9] = stubW; proc->code[10] = (stubW >> 8); proc->code[11] = (stubW >> 16); proc->code[12] = (stubW >> 24); proc->env.ptr = envP; return proc; /* On this architecture, no explicit iCache flush is required as * long as a branch appears. Return suffices for a branch, which is why * this must not be an inline procedure. */ }
/// @addtogroup ProcObjects /// /// <b>SPARC64</b> The SPARC64 implementation uses a /// position-independent variant of the Procedure-Object-Relative /// method, ultimately storing the closure record pointer into /// <code>@%g1</code>. The <code>@%g4</code> register is clobbered /// while loading the address of the stub procedure. Both /// <code>@%g1</code> and <code>@%g4</code> are defined as /// call-clobbered on this architecture. /// /// The code sequence uses the same delay slot trick that is used on /// the 32-bit SPARC implementation. SPARC64 implementations are /// multi-issue, so this sequence is only <em>almost</em> as expensive /// as it looks. On the other hand, SPARC64 does not implement any /// jump immediate or call immediate instruction with a 64-bit span, /// so this code sequence is specifically optimized in SPARC64 /// hardware implementations. /// /// Thanks to Jonathan Adams for assistance in defining and debugging /// this sequence. void * bitc_emit_procedure_object(void *stubP, void *envP) { uint64_t envW = (uint64_t) envP; uint64_t stubW = (uint64_t) stubP; bitc_Procedure* proc = GC_ALLOC(sizeof(bitc_Procedure)); /* SETHI %hh(stubW), %g4 */ proc->code[0] = 0x09000000u | (stubW >> 42); /* OR %g4, %hm(stubW), %g4 */ proc->code[1] = 0x88112000u | ((stubW >> 32) & 0x3ffu); /* SETHI %lm(stubW), %g1 */ proc->code[2] = 0x03000000u | (stubW >> 10) & 0x3fffffu; /* SLLX %g4, 31, %g4 */ proc->code[3] = 0x89293020u; /* OR %g4, %g1, %g1 */ proc->code[4] = 0x82110011u; /* JMPL %g1 + %lo(stubW), %g1 */ proc->code[5] = 0x83c06000 | (stubW & 0x3ffu); /* LD [%g1 + 0xc], %g1 */ proc->code[6] = 0xc200600c; proc->env.ptr = envP; return proc; /* On this architecture, no explicit iCache flush is required as * long as a branch appears. Return suffices for a branch, which is why * this must not be an inline procedure. */ }
static char const* alloc_and_copy(char const* source, unsigned len) { char* s = (char*) GC_ALLOC(len + 1); ::memcpy(s, source, len); s[len] = '\0'; return s; }
void PushBack(int value) { ListNodeHandle node; node = GC_ALLOC(ListNode); node->m_value = value; if (m_tail) { m_tail->m_next = node; node->m_prev = m_tail; m_tail = node; } else { m_head = m_tail = node; } }
void xhn::path_node::search(const char* path) { path_name = path; transform(path_name.begin(), path_name.end(), path_name.begin(), FCharFormat()); string search_path = path_name; #if defined(_WIN32) || defined(_WIN64) if (search_path.size() && search_path[search_path.size() - 1] != '\\') { search_path += '\\'; } #elif defined(__APPLE__) if (search_path.size() && search_path[search_path.size() - 1] != '/') { search_path += '/'; } #else # error #endif #if defined(_WIN32) || defined(_WIN64) string tmp = search_path + "*"; struct _finddata_t fd; long h = _findfirst(tmp.c_str(), &fd); int ret = 0; while (h != -1L && !ret) { if (strcmp(fd.name, L".") != 0 && strcmp(fd.name, L"..") != 0) { path_node_ptr child; #ifdef USE_SMART_PTR child = VNEW path_node; #else child = GC_ALLOC(path_node); #endif child->search((search_path + fd.name).c_str()); if (fd.attrib == 0x10) { child->is_folder = true; } child->next = children; children = child; } ret = _findnext(h, &fd); } _findclose(h); #elif defined(__APPLE__) vector<string> subFolders; vector<string> paths; GetPaths(search_path.c_str(), subFolders, paths); { vector<string>::iterator iter = subFolders.begin(); vector<string>::iterator end = subFolders.end(); for (; iter != end; iter++) { string& subFolder = *iter; path_node_ptr child; #ifdef USE_SMART_PTR child = VNEW path_node; #else child = GC_ALLOC(path_node); #endif child->search(subFolder.c_str()); child->is_folder = true; child->next = children; children = child; size += child->size; folder_count += child->folder_count; file_count += child->file_count; folder_count++; } } { vector<string>::iterator iter = paths.begin(); vector<string>::iterator end = paths.end(); for (; iter != end; iter++) { string& path = *iter; path_node_ptr child; #ifdef USE_SMART_PTR child = VNEW path_node; #else child = GC_ALLOC(path_node); #endif child->path_name = path; child->is_folder = false; child->next = children; children = child; size += file_manager::get()->file_size(child->path_name); file_count++; } } #else # error #endif }
void xhn::wpath_node::search(const wchar_t* path) { path_name = path; transform(path_name.begin(), path_name.end(), path_name.begin(), FWCharFormat()); wstring search_path = path_name; #if defined(_WIN32) || defined(_WIN64) if (search_path.size() && search_path[search_path.size() - 1] != L'\\') { search_path += L'\\'; } #elif defined(__APPLE__) if (search_path.size() && search_path[search_path.size() - 1] != L'/') { search_path += L'/'; } #else # error #endif #if defined(_WIN32) || defined(_WIN64) wstring tmp = search_path + L"*"; struct _wfinddata_t fd; long h = _wfindfirst(tmp.c_str(), &fd); int ret = 0; while (h != -1L && !ret) { if (StrCmpW(fd.name, L".") != 0 && StrCmpW(fd.name, L"..") != 0) { wpath_node_ptr child; #ifdef USE_SMART_PTR child = VNEW wpath_node; #else child = GC_ALLOC(wpath_node); #endif child->search((search_path + fd.name).c_str()); if (fd.attrib == 0x10) { child->is_folder = true; } child->next = children; children = child; } ret = _wfindnext(h, &fd); } _findclose(h); #elif defined(__APPLE__) Utf8 utf8(search_path.c_str()); vector<string> subFolders; vector<string> paths; GetPaths(((string)utf8).c_str(), subFolders, paths); { vector<string>::iterator iter = subFolders.begin(); vector<string>::iterator end = subFolders.end(); for (; iter != end; iter++) { string& subFolder = *iter; Unicode uc16(subFolder.c_str()); wpath_node_ptr child; #ifdef USE_SMART_PTR child = VNEW wpath_node; #else child = GC_ALLOC(wpath_node); #endif child->search(((wstring)uc16).c_str()); child->is_folder = true; child->next = children; children = child; } } { vector<string>::iterator iter = paths.begin(); vector<string>::iterator end = paths.end(); for (; iter != end; iter++) { string& path = *iter; Unicode uc16(path.c_str()); wpath_node_ptr child; #ifdef USE_SMART_PTR child = VNEW wpath_node; #else child = GC_ALLOC(wpath_node); #endif child->path_name = uc16; child->is_folder = false; child->next = children; children = child; } } #else # error #endif }
string operator+(string const& other) const { char *s = (char*) GC_ALLOC(size() + other.size() + 1); ::memcpy(s, c_str(), size()); ::memcpy(s + size(), other.c_str(), other.size() + 1); // copy the null terminator as well return string(s, size() + other.size()); }