pgsNumber::pgsNumber(const wxString & data, const bool & is_real) : pgsVariable(!is_real ? pgsVariable::pgsTInt : pgsVariable::pgsTReal), m_data(data.Strip(wxString::both)) { wxASSERT(is_valid()); }
bool Stream::flush() { FLAC__ASSERT(is_valid()); return (bool)::FLAC__stream_decoder_flush(decoder_); }
bool Stream::process_single() { FLAC__ASSERT(is_valid()); return (bool)::FLAC__stream_decoder_process_single(decoder_); }
unsigned Stream::get_sample_rate() const { FLAC__ASSERT(is_valid()); return ::FLAC__stream_decoder_get_sample_rate(decoder_); }
bool Stream::get_decode_position(FLAC__uint64 *position) const { FLAC__ASSERT(is_valid()); return ::FLAC__stream_decoder_get_decode_position(decoder_, position); }
bool Stream::get_md5_checking() const { FLAC__ASSERT(is_valid()); return (bool)::FLAC__stream_decoder_get_md5_checking(decoder_); }
unsigned Stream::get_channels() const { FLAC__ASSERT(is_valid()); return ::FLAC__stream_decoder_get_channels(decoder_); }
T* get_addr() const { if (is_valid()) { return reinterpret_cast<T*>(m_addr); } throw std::runtime_error("invalid memory mapping"); }
Lower_case::Lower_case( string s ) : lc{ s } { if ( !is_valid( s ) ) throw InvalidTerminal{}; }
void JitCodeSpecializer::_inline_function_calls(SpecializationContext& context) const { // This method implements the main code fusion functionality. // It works as follows: // Throughout the fusion process, a working list of call sites (i.e., function calls) is maintained. // This queue is initialized with all call instructions from the initial root function. // Each call site is then handled in one of the following ways: // - Direct Calls: // Direct calls explicitly encode the name of the called function. If a function implementation can be located in // the JitRepository repository by that name the function is inlined (i.e., the call instruction is replaced with // the function body from the repository. Calls to functions not available in the repository (e.g., calls into the // C++ standard library) require a corresponding function declaration to be inserted into the module. // This is necessary to avoid any unresolved function calls, which would invalidate the module and cause the // just-in-time compiler to reject it. With an appropriate declaration, however, the just-in-time compiler is able // to locate the machine code of these functions in the Hyrise binary when compiling and linking the module. // - Indirect Calls // Indirect calls do not reference their called function by name. Instead, the address of the target function is // either loaded from memory or computed. The code specialization unit analyzes the instructions surrounding the // call and tries to infer the name of the called function. If this succeeds, the call is handled like a regular // direct call. If not, no specialization of the call can be performed. // In this case, the target address computed for the call at runtime will point to the correct machine code in the // Hyrise binary and the pipeline will still execute successfully. // // Whenever a call instruction is replaced by the corresponding function body, the inlining algorithm reports back // any new call sites encountered in the process. These are pushed to the end of the working queue. Once this queue // is empty, the operator fusion process is completed. std::queue<llvm::CallSite> call_sites; // Initialize the call queue with all call and invoke instructions from the root function. _visit<llvm::CallInst>(*context.root_function, [&](llvm::CallInst& inst) { call_sites.push(llvm::CallSite(&inst)); }); _visit<llvm::InvokeInst>(*context.root_function, [&](llvm::InvokeInst& inst) { call_sites.push(llvm::CallSite(&inst)); }); while (!call_sites.empty()) { auto& call_site = call_sites.front(); // Resolve indirect (virtual) function calls if (call_site.isIndirectCall()) { const auto called_value = call_site.getCalledValue(); // Get the runtime location of the called function (i.e., the compiled machine code of the function) const auto called_runtime_value = std::dynamic_pointer_cast<const JitKnownRuntimePointer>(GetRuntimePointerForValue(called_value, context)); if (called_runtime_value && called_runtime_value->is_valid()) { // LLVM implements virtual function calls via virtual function tables // (see https://en.wikipedia.org/wiki/Virtual_method_table). // The resolution of virtual calls starts with a pointer to the object that the virtual call should be performed // on. This object contains a pointer to its vtable (usually at offset 0). The vtable contains a list of // function pointers (one for each virtual function). // In the LLVM bitcode, a virtual call is resolved through a number of LLVM pointer operations: // - a load instruction to dereference the vtable pointer in the object // - a getelementptr instruction to select the correct virtual function in the vtable // - another load instruction to dereference the virtual function pointer from the table // When analyzing a virtual call, the code specializer works backwards starting from the pointer to the called // function (called_runtime_value). // Moving "up" one level (undoing one load operation) yields the pointer to the function pointer in the // vtable. The total_offset of this pointer corresponds to the index in the vtable that is used for the virtual // call. // Moving "up" another level yields the pointer to the object that the virtual function is called on. Using RTTI // the class name of the object can be determined. // These two pieces of information (the class name and the vtable index) are sufficient to unambiguously // identify the called virtual function and locate it in the bitcode repository. // Determine the vtable index and class name of the virtual call const auto vtable_index = called_runtime_value->up().total_offset() / context.module->getDataLayout().getPointerSize(); const auto instance = reinterpret_cast<JitRTTIHelper*>(called_runtime_value->up().up().base().address()); const auto class_name = typeid(*instance).name(); // If the called function can be located in the repository, the virtual call is replaced by a direct call to // that function. if (const auto repo_function = _repository.get_vtable_entry(class_name, vtable_index)) { call_site.setCalledFunction(repo_function); } } else { // The virtual call could not be resolved. There is nothing we can inline so we move on. call_sites.pop(); continue; } } auto function = call_site.getCalledFunction(); // ignore invalid functions if (!function) { call_sites.pop(); continue; } const auto function_name = function->getName().str(); const auto function_has_opossum_namespace = boost::starts_with(function_name, "_ZNK7opossum") || boost::starts_with(function_name, "_ZN7opossum"); // A note about "__clang_call_terminate": // __clang_call_terminate is generated / used internally by clang to call the std::terminate function when exception // handling fails. For some unknown reason this function cannot be resolved in the Hyrise binary when jit-compiling // bitcode that uses the function. The function is, however, present in the bitcode repository. // We thus always inline this function from the repository. // All function that are not in the opossum:: namespace are not considered for inlining. Instead, a function // declaration (without a function body) is created. if (!function_has_opossum_namespace && function_name != "__clang_call_terminate") { context.llvm_value_map[function] = _create_function_declaration(context, *function, function->getName()); call_sites.pop(); continue; } // Determine whether the first function argument is a pointer/reference to an object, but the runtime location // for this object cannot be determined. // This is the case for member functions that are called within a loop body. These functions may be called on // different objects in different loop iterations. // If two specialization passes are performed, these functions should be inlined after loop unrolling has been // performed (i.e., during the second pass). auto first_argument = call_site.arg_begin(); auto first_argument_cannot_be_resolved = first_argument->get()->getType()->isPointerTy() && !GetRuntimePointerForValue(first_argument->get(), context)->is_valid(); if (first_argument_cannot_be_resolved && function_name != "__clang_call_terminate") { call_sites.pop(); continue; } // We create a mapping from values in the source module to values in the target module. // This mapping is passed to LLVM's cloning function and ensures that all references to other functions, global // variables, and function arguments refer to values in the target module and NOT in the source module. // This way the module stays self-contained and valid. context.llvm_value_map.clear(); // Map called functions _visit<const llvm::Function>(*function, [&](const auto& fn) { if (fn.isDeclaration() && !context.llvm_value_map.count(&fn)) { context.llvm_value_map[&fn] = _create_function_declaration(context, fn, fn.getName()); } }); // Map global variables _visit<const llvm::GlobalVariable>(*function, [&](auto& global) { if (!context.llvm_value_map.count(&global)) { context.llvm_value_map[&global] = _clone_global_variable(context, global); } }); // Map function arguments auto function_arg = function->arg_begin(); auto call_arg = call_site.arg_begin(); for (; function_arg != function->arg_end() && call_arg != call_site.arg_end(); ++function_arg, ++call_arg) { context.llvm_value_map[function_arg] = call_arg->get(); } // Instruct LLVM to perform the function inlining and push all new call sites to the working queue llvm::InlineFunctionInfo info; if (InlineFunction(call_site, info, nullptr, false, nullptr, context)) { for (const auto& new_call_site : info.InlinedCallSites) { call_sites.push(new_call_site); } } // clear runtime_value_map to allow multiple inlining of same function auto runtime_this = context.runtime_value_map[context.root_function->arg_begin()]; context.runtime_value_map.clear(); context.runtime_value_map[context.root_function->arg_begin()] = runtime_this; call_sites.pop(); } }
/** * In a boolean context a MemoryMapping is true when it is a valid * existing mapping. */ explicit operator bool() const noexcept { return is_valid(); }
bool operator!() const { return !is_valid(); }
operator bool() const { return is_valid(); }
pgsNumber::pgsNumber(const pgsNumber & that) : pgsVariable(that), m_data(that.m_data) { wxASSERT(is_valid()); }
bool Stream::set_metadata_ignore_all() { FLAC__ASSERT(is_valid()); return (bool)::FLAC__stream_decoder_set_metadata_ignore_all(decoder_); }
PerfLongConstant(CounterNS ns, const char* namep, Units u, jlong initial_value=0) : PerfLong(ns, namep, u, V_Constant) { if (is_valid()) *(jlong*)_valuep = initial_value; }
Stream::State Stream::get_state() const { FLAC__ASSERT(is_valid()); return State(::FLAC__stream_decoder_get_state(decoder_)); }
PerfLongVariant(CounterNS ns, const char* namep, Units u, Variability v, jlong initial_value=0) : PerfLong(ns, namep, u, v) { if (is_valid()) *(jlong*)_valuep = initial_value; }
FLAC__uint64 Stream::get_total_samples() const { FLAC__ASSERT(is_valid()); return ::FLAC__stream_decoder_get_total_samples(decoder_); }
PerfString(CounterNS ns, const char* namep, Variability v, jint length, const char* initial_value) : PerfByteArray(ns, namep, U_String, v, length) { if (is_valid()) set_string(initial_value); }
::FLAC__ChannelAssignment Stream::get_channel_assignment() const { FLAC__ASSERT(is_valid()); return ::FLAC__stream_decoder_get_channel_assignment(decoder_); }
bool is_finite(double d) { return (d == d) && is_valid(d-d); }
unsigned Stream::get_blocksize() const { FLAC__ASSERT(is_valid()); return ::FLAC__stream_decoder_get_blocksize(decoder_); }
bool lens_flare::init(const nya_scene::texture_proxy &color, const nya_scene::texture_proxy &depth) { assert(depth.is_valid()); nya_memory::tmp_buffer_scoped res(load_resource("PostProcess/LensParam.bin")); if (!res.get_data()) return false; params::memory_reader reader(res.get_data(), res.get_size()); for (int i = 0; i < 16; ++i) { lens[i].position = reader.read<float>(); lens[i].radius = reader.read<float>(); lens[i].color = reader.read_color3_uint(); } star_radius = reader.read<float>(); star_color = reader.read_color3_uint(); glow_radius = reader.read<float>(); glow_color = reader.read_color3_uint(); ring_specular = reader.read<float>(); ring_shiness = reader.read<float>(); ring_radius = reader.read<float>(); f_min = reader.read<float>(); f_max = reader.read<float>(); aberration = reader.read<float>(); auto texture = shared::get_texture(shared::load_texture("PostProcess/lens.nut")); auto tex_data = texture.internal().get_shared_data(); if (!tex_data.is_valid()) return false; nya_render::texture tex = tex_data->tex; tex.set_wrap(nya_render::texture::wrap_repeat_mirror, nya_render::texture::wrap_repeat_mirror); auto &pass = m_material.get_pass(m_material.add_pass(nya_scene::material::default_pass)); pass.set_shader(nya_scene::shader("shaders/lens_flare.nsh")); pass.get_state().set_cull_face(false); pass.get_state().set_blend(true, nya_render::blend::src_alpha, nya_render::blend::inv_src_alpha); //pass.get_state().set_blend(true, nya_render::blend::src_alpha, nya_render::blend::one); pass.get_state().zwrite=false; pass.get_state().depth_test=false; m_material.set_texture("diffuse", texture); m_material.set_texture("color", color); m_material.set_texture("depth", depth); struct vert { nya_math::vec2 pos; float dist; float radius; nya_math::vec3 color; float special; }; vert verts[(16+1)*6]; for (int i = 0; i < 16; ++i) { vert *v = &verts[i * 6]; v[0].pos = nya_math::vec2( -1.0f, -1.0f ); v[1].pos = nya_math::vec2( -1.0f, 1.0f ); v[2].pos = nya_math::vec2( 1.0f, 1.0f ); v[3].pos = nya_math::vec2( -1.0f, -1.0f ); v[4].pos = nya_math::vec2( 1.0f, 1.0f ); v[5].pos = nya_math::vec2( 1.0f, -1.0f ); for (int t = 0; t < 6; ++t) { if (i>0) { auto &l = lens[i-1]; v[t].dist = l.position; v[t].radius = l.radius; v[t].color = l.color; v[t].special = 0.0; } else { v[t].dist = 1.0; v[t].radius = 0.2; v[t].color = nya_math::vec3(1.0, 1.0, 1.0); v[t].special = 1.0; } } } if (!m_mesh.is_valid()) m_mesh.create(); m_mesh->set_vertices(0, 4); m_mesh->set_tc(0, 16, 4); m_mesh->set_vertex_data(verts, uint32_t(sizeof(vert)), uint32_t(sizeof(verts) / sizeof(verts[0]))); if (!m_dir_alpha.is_valid()) m_dir_alpha.create(); m_material.set_param(m_material.get_param_idx("light dir"), m_dir_alpha); return true; }
::FLAC__StreamDecoderInitStatus Stream::init_ogg() { FLAC__ASSERT(is_valid()); return ::FLAC__stream_decoder_init_ogg_stream(decoder_, read_callback_, seek_callback_, tell_callback_, length_callback_, eof_callback_, write_callback_, metadata_callback_, error_callback_, /*client_data=*/(void*)this); }
InCSetState(in_cset_state_t value = NotInCSet) : _value(value) { assert(is_valid(), err_msg("Invalid state %d", _value)); }
bool Stream::reset() { FLAC__ASSERT(is_valid()); return (bool)::FLAC__stream_decoder_reset(decoder_); }
bool Stream::set_metadata_ignore_application(const FLAC__byte id[4]) { FLAC__ASSERT(is_valid()); return (bool)::FLAC__stream_decoder_set_metadata_ignore_application(decoder_, id); }
bool Stream::process_until_end_of_metadata() { FLAC__ASSERT(is_valid()); return (bool)::FLAC__stream_decoder_process_until_end_of_metadata(decoder_); }
bool operator < (const iterator<Buff, Traits0>& it) const { BOOST_CB_ASSERT(is_valid(m_buff)); // check for uninitialized or invalidated iterator BOOST_CB_ASSERT(it.is_valid(m_buff)); // check for uninitialized or invalidated iterator return less(create_helper_pointer(*this), create_helper_pointer(it)); }