<commit_before>/*
* HMAC_RNG
* (C) 2008-2009 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/

#include <botan/hmac_rng.h>
#include <botan/get_byte.h>
#include <botan/internal/xor_buf.h>
#include <botan/internal/stl_util.h>
#include <algorithm>

namespace Botan {

namespace {

void hmac_prf(MessageAuthenticationCode* prf,
              MemoryRegion<byte>& K,
              u32bit& counter,
              const std::string& label)
   {
   prf->update(K);
   prf->update(label);
   prf->update_be(counter);
   prf->final(&K[0]);

   ++counter;
   }

}

/*
* Generate a buffer of random bytes
*/
void HMAC_RNG::randomize(byte out[], size_t length)
   {
   if(!is_seeded())
      throw PRNG_Unseeded(name());

   /*
    HMAC KDF as described in E-t-E, using a CTXinfo of "rng"
   */
   while(length)
      {
      hmac_prf(prf, K, counter, "rng");

      const size_t copied = std::min<size_t>(K.size(), length);

      copy_mem(out, &K[0], copied);
      out += copied;
      length -= copied;
      }
   }

/*
* Poll for entropy and reset the internal keys
*/
void HMAC_RNG::reseed(size_t poll_bits)
   {
   /*
   Using the terminology of E-t-E, XTR is the MAC function (normally
   HMAC) seeded with XTS (below) and we form SKM, the key material, by
   fast polling each source, and then slow polling as many as we think
   we need (in the following loop), and feeding all of the poll
   results, along with any optional user input, along with, finally,
   feedback of the current PRK value, into the extractor function.
   */

   Entropy_Accumulator_BufferedComputation accum(*extractor, poll_bits);

   if(!entropy_sources.empty())
      {
      size_t poll_attempt = 0;

      while(!accum.polling_goal_achieved() && poll_attempt < poll_bits)
         {
         const size_t src_idx = poll_attempt % entropy_sources.size();
         entropy_sources[src_idx]->poll(accum);
         ++poll_attempt;
         }
      }

   /*
   * It is necessary to feed forward poll data. Otherwise, a good poll
   * (collecting a large amount of conditional entropy) followed by a
   * bad one (collecting little) would be unsafe. Do this by
   * generating new PRF outputs using the previous key and feeding
   * them into the extractor function.
   *
   * Cycle the RNG once (CTXinfo="rng"), then generate a new PRF
   * output using the CTXinfo "reseed". Provide these values as input
   * to the extractor function.
   */
   hmac_prf(prf, K, counter, "rng");
   extractor->update(K); // K is the CTXinfo=rng PRF output

   hmac_prf(prf, K, counter, "reseed");
   extractor->update(K); // K is the CTXinfo=reseed PRF output

   /* Now derive the new PRK using everything that has been fed into
      the extractor, and set the PRF key to that */
   prf->set_key(extractor->final());

   // Now generate a new PRF output to use as the XTS extractor salt
   hmac_prf(prf, K, counter, "xts");
   extractor->set_key(K);

   // Reset state
   zeroise(K);
   counter = 0;
   user_input_len = 0;

   /*
   Consider ourselves seeded once we've collected an estimated 128 bits of
   entropy in a single poll.
   */
   if(seeded == false && accum.bits_collected() >= 128)
      seeded = true;
   }

/*
* Add user-supplied entropy to the extractor input
*/
void HMAC_RNG::add_entropy(const byte input[], size_t length)
   {
   const size_t USER_ENTROPY_WATERSHED = 20;

   extractor->update(input, length);
   user_input_len += length;

   /*
   * After we've accumulated at least USER_ENTROPY_WATERSHED bytes of
   * user input, reseed.  This input will automatically have been
   * included if reseed was called already, as it's just included in
   * the extractor input.
   */
   if(user_input_len >= USER_ENTROPY_WATERSHED)
      reseed(128);
   }

/*
* Add another entropy source to the list
*/
void HMAC_RNG::add_entropy_source(EntropySource* src)
   {
   entropy_sources.push_back(src);
   }

/*
* Clear memory of sensitive data
*/
void HMAC_RNG::clear()
   {
   extractor->clear();
   prf->clear();
   zeroise(K);
   counter = 0;
   user_input_len = 0;
   seeded = false;
   }

/*
* Return the name of this type
*/
std::string HMAC_RNG::name() const
   {
   return "HMAC_RNG(" + extractor->name() + "," + prf->name() + ")";
   }

/*
* HMAC_RNG Constructor
*/
HMAC_RNG::HMAC_RNG(MessageAuthenticationCode* extractor_mac,
                   MessageAuthenticationCode* prf_mac) :
   extractor(extractor_mac), prf(prf_mac)
   {
   if(!prf->valid_keylength(extractor->output_length()) ||
      !extractor->valid_keylength(prf->output_length()))
      throw Invalid_Argument("HMAC_RNG: Bad algo combination " +
                             extractor->name() + " and " +
                             prf->name());

   // First PRF inputs are all zero, as specified in section 2
   K.resize(prf->output_length());

   counter = 0;
   user_input_len = 0;
   seeded = false;

   /*
   Normally we want to feedback PRF output into the input to the
   extractor function to ensure a single bad poll does not damage the
   RNG, but obviously that is meaningless to do on the first poll.

   We will want to use the PRF before we set the first key (in
   reseed), and it is a pain to keep track if it is set or
   not. Since the first time it doesn't matter anyway, just set the
   PRF key to constant zero: randomize() will not produce output
   unless is_seeded() returns true, and that will only be the case if
   the estimated entropy counter is high enough. That variable is only
   set when a reseeding is performed.
   */
   MemoryVector<byte> prf_key(extractor->output_length());
   prf->set_key(prf_key);

   /*
   Use PRF("Botan HMAC_RNG XTS") as the intitial XTS key.

   This will be used during the first extraction sequence; XTS values
   after this one are generated using the PRF.

   If I understand the E-t-E paper correctly (specifically Section 4),
   using this fixed extractor key is safe to do.
   */
   extractor->set_key(prf->process("Botan HMAC_RNG XTS"));
   }

/*
* HMAC_RNG Destructor
*/
HMAC_RNG::~HMAC_RNG()
   {
   delete extractor;
   delete prf;

   std::for_each(entropy_sources.begin(), entropy_sources.end(),
                 del_fun<EntropySource>());

   counter = 0;
   }

}
<commit_msg>Partially roll back b2aef16225863cef27cdee4b91703966b3ed1458, it caused huge performance issues with DSA/ECDSA signing performance.<commit_after>/*
* HMAC_RNG
* (C) 2008-2009 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/

#include <botan/hmac_rng.h>
#include <botan/get_byte.h>
#include <botan/internal/xor_buf.h>
#include <botan/internal/stl_util.h>
#include <algorithm>

namespace Botan {

namespace {

void hmac_prf(MessageAuthenticationCode* prf,
              MemoryRegion<byte>& K,
              u32bit& counter,
              const std::string& label)
   {
   prf->update(K);
   prf->update(label);
   prf->update_be(counter);
   prf->final(&K[0]);

   ++counter;
   }

}

/*
* Generate a buffer of random bytes
*/
void HMAC_RNG::randomize(byte out[], size_t length)
   {
   if(!is_seeded())
      throw PRNG_Unseeded(name());

   /*
    HMAC KDF as described in E-t-E, using a CTXinfo of "rng"
   */
   while(length)
      {
      hmac_prf(prf, K, counter, "rng");

      const size_t copied = std::min<size_t>(K.size(), length);

      copy_mem(out, &K[0], copied);
      out += copied;
      length -= copied;
      }
   }

/*
* Poll for entropy and reset the internal keys
*/
void HMAC_RNG::reseed(size_t poll_bits)
   {
   /*
   Using the terminology of E-t-E, XTR is the MAC function (normally
   HMAC) seeded with XTS (below) and we form SKM, the key material, by
   fast polling each source, and then slow polling as many as we think
   we need (in the following loop), and feeding all of the poll
   results, along with any optional user input, along with, finally,
   feedback of the current PRK value, into the extractor function.
   */

   Entropy_Accumulator_BufferedComputation accum(*extractor, poll_bits);

   if(!entropy_sources.empty())
      {
      size_t poll_attempt = 0;

      while(!accum.polling_goal_achieved() && poll_attempt < poll_bits)
         {
         const size_t src_idx = poll_attempt % entropy_sources.size();
         entropy_sources[src_idx]->poll(accum);
         ++poll_attempt;
         }
      }

   /*
   * It is necessary to feed forward poll data. Otherwise, a good poll
   * (collecting a large amount of conditional entropy) followed by a
   * bad one (collecting little) would be unsafe. Do this by
   * generating new PRF outputs using the previous key and feeding
   * them into the extractor function.
   *
   * Cycle the RNG once (CTXinfo="rng"), then generate a new PRF
   * output using the CTXinfo "reseed". Provide these values as input
   * to the extractor function.
   */
   hmac_prf(prf, K, counter, "rng");
   extractor->update(K); // K is the CTXinfo=rng PRF output

   hmac_prf(prf, K, counter, "reseed");
   extractor->update(K); // K is the CTXinfo=reseed PRF output

   /* Now derive the new PRK using everything that has been fed into
      the extractor, and set the PRF key to that */
   prf->set_key(extractor->final());

   // Now generate a new PRF output to use as the XTS extractor salt
   hmac_prf(prf, K, counter, "xts");
   extractor->set_key(K);

   // Reset state
   zeroise(K);
   counter = 0;
   user_input_len = 0;

   /*
   Consider ourselves seeded once we've collected an estimated 128 bits of
   entropy in a single poll.
   */
   if(seeded == false && accum.bits_collected() >= 128)
      seeded = true;
   }

/*
* Add user-supplied entropy to the extractor input
*/
void HMAC_RNG::add_entropy(const byte input[], size_t length)
   {
   const size_t USER_ENTROPY_WATERSHED = 64;

   extractor->update(input, length);
   user_input_len += length;

   /*
   * After we've accumulated at least USER_ENTROPY_WATERSHED bytes of
   * user input, reseed.  This input will automatically have been
   * included if reseed was called already, as it's just included in
   * the extractor input.
   */
   if(user_input_len >= USER_ENTROPY_WATERSHED)
      reseed(0);
   }

/*
* Add another entropy source to the list
*/
void HMAC_RNG::add_entropy_source(EntropySource* src)
   {
   entropy_sources.push_back(src);
   }

/*
* Clear memory of sensitive data
*/
void HMAC_RNG::clear()
   {
   extractor->clear();
   prf->clear();
   zeroise(K);
   counter = 0;
   user_input_len = 0;
   seeded = false;
   }

/*
* Return the name of this type
*/
std::string HMAC_RNG::name() const
   {
   return "HMAC_RNG(" + extractor->name() + "," + prf->name() + ")";
   }

/*
* HMAC_RNG Constructor
*/
HMAC_RNG::HMAC_RNG(MessageAuthenticationCode* extractor_mac,
                   MessageAuthenticationCode* prf_mac) :
   extractor(extractor_mac), prf(prf_mac)
   {
   if(!prf->valid_keylength(extractor->output_length()) ||
      !extractor->valid_keylength(prf->output_length()))
      throw Invalid_Argument("HMAC_RNG: Bad algo combination " +
                             extractor->name() + " and " +
                             prf->name());

   // First PRF inputs are all zero, as specified in section 2
   K.resize(prf->output_length());

   counter = 0;
   user_input_len = 0;
   seeded = false;

   /*
   Normally we want to feedback PRF output into the input to the
   extractor function to ensure a single bad poll does not damage the
   RNG, but obviously that is meaningless to do on the first poll.

   We will want to use the PRF before we set the first key (in
   reseed), and it is a pain to keep track if it is set or
   not. Since the first time it doesn't matter anyway, just set the
   PRF key to constant zero: randomize() will not produce output
   unless is_seeded() returns true, and that will only be the case if
   the estimated entropy counter is high enough. That variable is only
   set when a reseeding is performed.
   */
   MemoryVector<byte> prf_key(extractor->output_length());
   prf->set_key(prf_key);

   /*
   Use PRF("Botan HMAC_RNG XTS") as the intitial XTS key.

   This will be used during the first extraction sequence; XTS values
   after this one are generated using the PRF.

   If I understand the E-t-E paper correctly (specifically Section 4),
   using this fixed extractor key is safe to do.
   */
   extractor->set_key(prf->process("Botan HMAC_RNG XTS"));
   }

/*
* HMAC_RNG Destructor
*/
HMAC_RNG::~HMAC_RNG()
   {
   delete extractor;
   delete prf;

   std::for_each(entropy_sources.begin(), entropy_sources.end(),
                 del_fun<EntropySource>());

   counter = 0;
   }

}
<|endoftext|>


<commit_before><commit_msg>Add note that functions from CollisionScene are wrapped within Scene<commit_after><|endoftext|>


<commit_before>/*! \file */
/* ************************************************************************
 * Copyright (c) 2021 Advanced Micro Devices, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 * ************************************************************************ */

#include "bellmm_device_general.h"
#include "utility.h"

template <rocsparse_int BELL_BLOCK_DIM,
          rocsparse_int BLK_SIZE_Y,
          typename T,
          typename U,
          typename I>
__launch_bounds__(BELL_BLOCK_DIM* BLK_SIZE_Y) ROCSPARSE_KERNEL
    void bellmm_general_blockdim_kernel(rocsparse_operation trans_A,
                                        rocsparse_operation trans_B,
                                        rocsparse_order     order_B,
                                        rocsparse_order     order_C,
                                        rocsparse_direction dir_A,
                                        I                   Mb,
                                        I                   N,
                                        U                   alpha_device_host,
                                        I                   bell_cols,
                                        I                   block_dim,
                                        const I* __restrict__ bell_col_ind,
                                        const T* __restrict__ bell_val,
                                        const T* __restrict__ B,
                                        I ldb,
                                        U beta_device_host,
                                        T* __restrict__ C,
                                        I                    ldc,
                                        rocsparse_index_base idx_base)
{
    auto alpha = load_scalar_device_host(alpha_device_host);
    auto beta  = load_scalar_device_host(beta_device_host);

    if(alpha == static_cast<T>(0) && beta == static_cast<T>(1))
    {
        return;
    }

    bellmm_general_blockdim_device<BELL_BLOCK_DIM, BLK_SIZE_Y>(trans_A,
                                                               trans_B,
                                                               order_B,
                                                               order_C,
                                                               dir_A,
                                                               Mb,
                                                               N,
                                                               alpha,
                                                               bell_cols,
                                                               block_dim,
                                                               bell_col_ind,
                                                               bell_val,
                                                               B,
                                                               ldb,
                                                               beta,
                                                               C,
                                                               ldc,
                                                               idx_base);
}

template <typename T, typename U, typename I>
rocsparse_status rocsparse_bellmm_template_general(rocsparse_handle          handle,
                                                   rocsparse_operation       trans_A,
                                                   rocsparse_operation       trans_B,
                                                   rocsparse_order           order_B,
                                                   rocsparse_order           order_C,
                                                   rocsparse_direction       dir_A,
                                                   I                         mb,
                                                   I                         n,
                                                   I                         kb,
                                                   I                         bell_cols,
                                                   I                         block_dim,
                                                   U                         alpha,
                                                   const rocsparse_mat_descr descr,
                                                   const I*                  bell_col_ind,
                                                   const T*                  bell_val,
                                                   const T*                  B,
                                                   I                         ldb,
                                                   U                         beta,
                                                   T*                        C,
                                                   I                         ldc)
{
    hipStream_t stream = handle->stream;
    assert(block_dim > 32);
    dim3 bellmm_blocks((mb - 1) / 1 + 1, (n - 1) / 32 + 1);
    dim3 bellmm_threads(32, 32, 1);
    assert(trans_A == rocsparse_operation_none);
    //
    // What happends if A needs to be transposed?
    //
    hipLaunchKernelGGL((bellmm_general_blockdim_kernel<32, 32>),
                       bellmm_blocks,
                       bellmm_threads,
                       0,
                       stream,
                       trans_A,
                       trans_B,
                       order_B,
                       order_C,
                       dir_A,
                       mb,
                       n,
                       alpha,
                       bell_cols,
                       block_dim,
                       bell_col_ind,
                       bell_val,
                       B,
                       ldb,
                       beta,
                       C,
                       ldc,
                       descr->base);

    return rocsparse_status_success;
}

#define INSTANTIATE(TTYPE, UTYPE, ITYPE)                                                            \
    template rocsparse_status rocsparse_bellmm_template_general(rocsparse_handle    handle,         \
                                                                rocsparse_operation trans_A,        \
                                                                rocsparse_operation trans_B,        \
                                                                rocsparse_order     order_B,        \
                                                                rocsparse_order     order_C,        \
                                                                rocsparse_direction dir_A,          \
                                                                ITYPE               mb,             \
                                                                ITYPE               n,              \
                                                                ITYPE               kb,             \
                                                                ITYPE               bell_cols,      \
                                                                ITYPE               bell_block_dim, \
                                                                UTYPE               alpha,          \
                                                                const rocsparse_mat_descr descr,    \
                                                                const ITYPE* bell_col_ind,          \
                                                                const TTYPE* bell_val,              \
                                                                const TTYPE* B,                     \
                                                                ITYPE        ldb,                   \
                                                                UTYPE        beta,                  \
                                                                TTYPE*       C,                     \
                                                                ITYPE        ldc)

INSTANTIATE(float, float, int32_t);
INSTANTIATE(float, const float*, int32_t);

INSTANTIATE(double, double, int32_t);
INSTANTIATE(double, const double*, int32_t);

INSTANTIATE(rocsparse_float_complex, rocsparse_float_complex, int32_t);
INSTANTIATE(rocsparse_float_complex, const rocsparse_float_complex*, int32_t);

INSTANTIATE(rocsparse_double_complex, rocsparse_double_complex, int32_t);
INSTANTIATE(rocsparse_double_complex, const rocsparse_double_complex*, int32_t);

INSTANTIATE(float, float, int64_t);
INSTANTIATE(float, const float*, int64_t);

INSTANTIATE(double, double, int64_t);
INSTANTIATE(double, const double*, int64_t);

INSTANTIATE(rocsparse_float_complex, rocsparse_float_complex, int64_t);
INSTANTIATE(rocsparse_float_complex, const rocsparse_float_complex*, int64_t);

INSTANTIATE(rocsparse_double_complex, rocsparse_double_complex, int64_t);
INSTANTIATE(rocsparse_double_complex, const rocsparse_double_complex*, int64_t);

#undef INSTANTIATE
<commit_msg>remove incorrect assert from spmm_bell (#302)<commit_after>/*! \file */
/* ************************************************************************
 * Copyright (c) 2021-2022 Advanced Micro Devices, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 * ************************************************************************ */

#include "bellmm_device_general.h"
#include "utility.h"

template <rocsparse_int BELL_BLOCK_DIM,
          rocsparse_int BLK_SIZE_Y,
          typename T,
          typename U,
          typename I>
__launch_bounds__(BELL_BLOCK_DIM* BLK_SIZE_Y) ROCSPARSE_KERNEL
    void bellmm_general_blockdim_kernel(rocsparse_operation trans_A,
                                        rocsparse_operation trans_B,
                                        rocsparse_order     order_B,
                                        rocsparse_order     order_C,
                                        rocsparse_direction dir_A,
                                        I                   Mb,
                                        I                   N,
                                        U                   alpha_device_host,
                                        I                   bell_cols,
                                        I                   block_dim,
                                        const I* __restrict__ bell_col_ind,
                                        const T* __restrict__ bell_val,
                                        const T* __restrict__ B,
                                        I ldb,
                                        U beta_device_host,
                                        T* __restrict__ C,
                                        I                    ldc,
                                        rocsparse_index_base idx_base)
{
    auto alpha = load_scalar_device_host(alpha_device_host);
    auto beta  = load_scalar_device_host(beta_device_host);

    if(alpha == static_cast<T>(0) && beta == static_cast<T>(1))
    {
        return;
    }

    bellmm_general_blockdim_device<BELL_BLOCK_DIM, BLK_SIZE_Y>(trans_A,
                                                               trans_B,
                                                               order_B,
                                                               order_C,
                                                               dir_A,
                                                               Mb,
                                                               N,
                                                               alpha,
                                                               bell_cols,
                                                               block_dim,
                                                               bell_col_ind,
                                                               bell_val,
                                                               B,
                                                               ldb,
                                                               beta,
                                                               C,
                                                               ldc,
                                                               idx_base);
}

template <typename T, typename U, typename I>
rocsparse_status rocsparse_bellmm_template_general(rocsparse_handle          handle,
                                                   rocsparse_operation       trans_A,
                                                   rocsparse_operation       trans_B,
                                                   rocsparse_order           order_B,
                                                   rocsparse_order           order_C,
                                                   rocsparse_direction       dir_A,
                                                   I                         mb,
                                                   I                         n,
                                                   I                         kb,
                                                   I                         bell_cols,
                                                   I                         block_dim,
                                                   U                         alpha,
                                                   const rocsparse_mat_descr descr,
                                                   const I*                  bell_col_ind,
                                                   const T*                  bell_val,
                                                   const T*                  B,
                                                   I                         ldb,
                                                   U                         beta,
                                                   T*                        C,
                                                   I                         ldc)
{
    hipStream_t stream = handle->stream;
    dim3        bellmm_blocks((mb - 1) / 1 + 1, (n - 1) / 32 + 1);
    dim3        bellmm_threads(32, 32, 1);
    assert(trans_A == rocsparse_operation_none);
    //
    // What happends if A needs to be transposed?
    //
    hipLaunchKernelGGL((bellmm_general_blockdim_kernel<32, 32>),
                       bellmm_blocks,
                       bellmm_threads,
                       0,
                       stream,
                       trans_A,
                       trans_B,
                       order_B,
                       order_C,
                       dir_A,
                       mb,
                       n,
                       alpha,
                       bell_cols,
                       block_dim,
                       bell_col_ind,
                       bell_val,
                       B,
                       ldb,
                       beta,
                       C,
                       ldc,
                       descr->base);

    return rocsparse_status_success;
}

#define INSTANTIATE(TTYPE, UTYPE, ITYPE)                                                            \
    template rocsparse_status rocsparse_bellmm_template_general(rocsparse_handle    handle,         \
                                                                rocsparse_operation trans_A,        \
                                                                rocsparse_operation trans_B,        \
                                                                rocsparse_order     order_B,        \
                                                                rocsparse_order     order_C,        \
                                                                rocsparse_direction dir_A,          \
                                                                ITYPE               mb,             \
                                                                ITYPE               n,              \
                                                                ITYPE               kb,             \
                                                                ITYPE               bell_cols,      \
                                                                ITYPE               bell_block_dim, \
                                                                UTYPE               alpha,          \
                                                                const rocsparse_mat_descr descr,    \
                                                                const ITYPE* bell_col_ind,          \
                                                                const TTYPE* bell_val,              \
                                                                const TTYPE* B,                     \
                                                                ITYPE        ldb,                   \
                                                                UTYPE        beta,                  \
                                                                TTYPE*       C,                     \
                                                                ITYPE        ldc)

INSTANTIATE(float, float, int32_t);
INSTANTIATE(float, const float*, int32_t);

INSTANTIATE(double, double, int32_t);
INSTANTIATE(double, const double*, int32_t);

INSTANTIATE(rocsparse_float_complex, rocsparse_float_complex, int32_t);
INSTANTIATE(rocsparse_float_complex, const rocsparse_float_complex*, int32_t);

INSTANTIATE(rocsparse_double_complex, rocsparse_double_complex, int32_t);
INSTANTIATE(rocsparse_double_complex, const rocsparse_double_complex*, int32_t);

INSTANTIATE(float, float, int64_t);
INSTANTIATE(float, const float*, int64_t);

INSTANTIATE(double, double, int64_t);
INSTANTIATE(double, const double*, int64_t);

INSTANTIATE(rocsparse_float_complex, rocsparse_float_complex, int64_t);
INSTANTIATE(rocsparse_float_complex, const rocsparse_float_complex*, int64_t);

INSTANTIATE(rocsparse_double_complex, rocsparse_double_complex, int64_t);
INSTANTIATE(rocsparse_double_complex, const rocsparse_double_complex*, int64_t);

#undef INSTANTIATE
<|endoftext|>


<commit_before>/*
 * Copyright 2006-2008 The FLWOR Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include "zorbaerrors/error_manager.h"
#include "errors/user_error.h"
#include "zorbatypes/URI.h"

#include "api/serialization/serializer.h"

#include "system/globalenv.h"

#include "types/schema/revalidateUtils.h"

#include "compiler/api/compilercb.h"

#include "runtime/misc/MiscImpl.h"
#include "runtime/api/runtimecb.h"
#include "runtime/util/iterator_impl.h"
#include "runtime/visitors/planitervisitor.h"

#include "store/api/item_factory.h"
#include "store/api/store.h"
#include "store/api/pul.h"

#include "context/static_context.h"

#include <iostream>

namespace zorba {

SERIALIZABLE_CLASS_VERSIONS(FnErrorIterator)
END_SERIALIZABLE_CLASS_VERSIONS(FnErrorIterator)

SERIALIZABLE_CLASS_VERSIONS(FnResolveUriIterator)
END_SERIALIZABLE_CLASS_VERSIONS(FnResolveUriIterator)

SERIALIZABLE_CLASS_VERSIONS(SequentialIterator)
END_SERIALIZABLE_CLASS_VERSIONS(SequentialIterator)

SERIALIZABLE_CLASS_VERSIONS(FlowCtlIterator)
END_SERIALIZABLE_CLASS_VERSIONS(FlowCtlIterator)

SERIALIZABLE_CLASS_VERSIONS(LoopIterator)
END_SERIALIZABLE_CLASS_VERSIONS(LoopIterator)

SERIALIZABLE_CLASS_VERSIONS(FnReadStringIterator)
END_SERIALIZABLE_CLASS_VERSIONS(FnReadStringIterator)

SERIALIZABLE_CLASS_VERSIONS(FnPrintIterator)
END_SERIALIZABLE_CLASS_VERSIONS(FnPrintIterator)

NARY_ACCEPT(FnErrorIterator);

NARY_ACCEPT(FnResolveUriIterator);

NARY_ACCEPT(SequentialIterator);

NARY_ACCEPT(FlowCtlIterator);

NARY_ACCEPT (LoopIterator);

NARY_ACCEPT (FnReadStringIterator);

NARY_ACCEPT(FnPrintIterator);

// 3 The Error Function
//---------------------
bool FnErrorIterator::nextImpl(store::Item_t& result, PlanState& planState) const
{
  static const char *err_ns = "http://www.w3.org/2005/xqt-errors";
  store::Item_t err_qname;
  GENV_ITEMFACTORY->createQName (err_qname, err_ns, "err", "FOER0000");
  store::Item_t lTmpQName;
  store::Item_t lTmpErrorObject;
  store::Item_t lTmpDescr;
  xqp_string ns;
  xqp_string description;
  std::vector<store::Item_t> lErrorObject;

  PlanIteratorState *state;
  DEFAULT_STACK_INIT(PlanIteratorState, state, planState);

  if (theChildren.size () >= 1) {
    if (consumeNext(lTmpQName, theChildren[0].getp(), planState))
      err_qname = lTmpQName;
  }
  if (theChildren.size () >= 2) {
    consumeNext(lTmpDescr, theChildren[1].getp(), planState);
    description = lTmpDescr->getStringValue ().getp();
  }
  if (theChildren.size() == 3) {
    while (consumeNext(lTmpErrorObject, theChildren[2].getp(), planState)) {
      lErrorObject.push_back(lTmpErrorObject);
    }
  }

  {
    error::ZorbaUserError lError(err_qname, description, loc,
                                 __FILE__, __LINE__, lErrorObject);
    throw lError;
  }

  STACK_END (state);
}

// 8.1 fn:resolve-uri
//---------------------
bool FnResolveUriIterator::nextImpl(store::Item_t& result, PlanState& planState) const
{
  store::Item_t item;
  xqpStringStore_t strRelative;
  xqpStringStore_t strBase;
  xqpStringStore_t strResult;
  URI              baseURI;
  URI              resolvedURI;

  PlanIteratorState *state;
  DEFAULT_STACK_INIT(PlanIteratorState, state, planState);

  if (consumeNext(item, theChildren[0], planState ))
  {
    strRelative = item->getStringValue();

    //If first param is an absolute URI reference, it is returned unchanged.
    try{
      resolvedURI = URI(&*strRelative);
    } catch (error::ZorbaError&) {}

    if (resolvedURI.is_absolute()) {
      strResult = strRelative;
    }
    else
    {
      try
      {
        if (theChildren.size() == 1)
        {
          // use base-uri from static context
          strBase = theSctx->baseuri().getStore();
          if (strBase->empty())
          {
            ZORBA_ERROR_LOC_DESC(FONS0005, loc,
                                 "base-uri is not initialized in the static context");
          }
        }
        else if (consumeNext(item, theChildren[1], planState ))
        {
          // two parameters => get baseuri from the second argument
          strBase = item->getStringValue();
        }
        else
        {
          ZORBA_ERROR_LOC_DESC(FORG0009, loc, "Can't treat empty-sequence as base-uri");
        }
        baseURI = URI(&*strBase, true);
      }
      catch (error::ZorbaError& e)
      {
        ZORBA_ERROR_LOC_DESC(FORG0002, loc,
                             "String {" + strBase->str() +  "} is not a valid URI: " + e.theDescription);
      }

      try
      {
        resolvedURI = URI(baseURI, &*strRelative, true); // resolve with baseURI or return strRelative if it's a valid absolute URI
        strResult = resolvedURI.toString().getStore();
      }
      catch (error::ZorbaError& e)
      {
        ZORBA_ERROR_LOC_DESC(FORG0002, loc, e.theDescription);
      }
    }
    STACK_PUSH(GENV_ITEMFACTORY->createString(result, strResult), state);
  } // else return empty sequence if the first argument is the empty sequence

  STACK_END (state);
}

bool SequentialIterator::nextImpl(store::Item_t& result, PlanState& planState) const
{
  rchandle<store::PUL> lPul;

  PlanIteratorState *state;
  DEFAULT_STACK_INIT(PlanIteratorState, state, planState);

  for (unsigned i = 0; i < theChildren.size() - 1; i++)
  {
    while (CONSUME (result, i))
    {
      if (theChildren[i]->isUpdating())
      {
        std::set<zorba::store::Item*> validationNodes;

        static_cast<store::PUL *> (result.getp ())->applyUpdates(validationNodes);

        store::Item_t validationPul = GENV_ITEMFACTORY->createPendingUpdateList();

#ifndef ZORBA_NO_XMLSCHEMA
        QueryLoc& loc = theChildren[i]->loc;
        validateAfterUpdate(validationNodes,
                            validationPul,
                            getStaticContext(planState),
                            loc);
#endif
        validationPul->applyUpdates(validationNodes);
      }
    }
  }

  while (CONSUME (result, theChildren.size () - 1))
    STACK_PUSH (true, state);

  STACK_END (state);
}

bool FlowCtlIterator::nextImpl(store::Item_t& result, PlanState& planState) const {
  PlanIteratorState *state;
  DEFAULT_STACK_INIT(PlanIteratorState, state, planState);
  switch (act) {
  case EXIT:
    throw ExitException (new PlanIteratorWrapper (theChildren [0], planState));
  default:
    throw FlowCtlException (act);
  }

  STACK_END (state);
}

bool FnReadStringIterator::nextImpl (store::Item_t& result, PlanState& planState) const {
  PlanIteratorState *state;
  xqpStringStore_t xstr;
  char str [512];
  DEFAULT_STACK_INIT(PlanIteratorState, state, planState);
  std::cin.getline (str, sizeof (str));
  xstr = new xqpStringStore (str);
  GENV_ITEMFACTORY->createString (result, xstr);
  STACK_PUSH (true, state);
  STACK_END (state);
}

bool FnPrintIterator::nextImpl (store::Item_t& result, PlanState& planState) const
{
  std::ostringstream os;
  serializer* lSerializer = NULL;
  store::Item_t item;
  xqpStringStore_t resString;

  PlanIteratorState* state;
  DEFAULT_STACK_INIT(PlanIteratorState, state, planState);

  while (CONSUME (item, theChildren.size () - 1))
  {
    if (item->isNode())
    {
      if (lSerializer == NULL)
      {
        lSerializer = new serializer(planState.theCompilerCB->m_error_manager);
        lSerializer->set_parameter("omit-xml-declaration", "yes");
      }

	  if (m_printToConsole) {
		  lSerializer->serialize(item.getp(), std::cout);
	  } else {
		  lSerializer->serialize(item.getp(), os);
	  }
    }
    else
    {
	  if (m_printToConsole) {
        std::cout << item->getStringValue ();
	  } else {
	    os << item->getStringValue();
	  }
    }
  }
  if (!m_printToConsole) {
    resString = new xqpStringStore(os.str());
    STACK_PUSH(GENV_ITEMFACTORY->createString(result, resString) , state);
  }
  STACK_END (state);
}

bool LoopIterator::nextImpl (store::Item_t& result, PlanState& planState) const {
  PlanIteratorState *state;
  DEFAULT_STACK_INIT(PlanIteratorState, state, planState);
  for (;;) {
    try {
      while (! CONSUME (result, 0))
        theChildren [0]->reset (planState);
    } catch (FlowCtlIterator::FlowCtlException &e) {
      switch (e.act) {
      case FlowCtlIterator::BREAK:
        goto done;
      case FlowCtlIterator::CONTINUE:
        theChildren [0]->reset (planState);
        continue;
      default:
        throw;
      }
    }
    STACK_PUSH (true, state);
  }

done:
  STACK_END (state);
}

} /* namespace zorba */
<commit_msg>Code indentation changed.<commit_after>/*
 * Copyright 2006-2008 The FLWOR Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include "zorbaerrors/error_manager.h"
#include "errors/user_error.h"
#include "zorbatypes/URI.h"

#include "api/serialization/serializer.h"

#include "system/globalenv.h"

#include "types/schema/revalidateUtils.h"

#include "compiler/api/compilercb.h"

#include "runtime/misc/MiscImpl.h"
#include "runtime/api/runtimecb.h"
#include "runtime/util/iterator_impl.h"
#include "runtime/visitors/planitervisitor.h"

#include "store/api/item_factory.h"
#include "store/api/store.h"
#include "store/api/pul.h"

#include "context/static_context.h"

#include <iostream>

namespace zorba {

SERIALIZABLE_CLASS_VERSIONS(FnErrorIterator)
END_SERIALIZABLE_CLASS_VERSIONS(FnErrorIterator)

SERIALIZABLE_CLASS_VERSIONS(FnResolveUriIterator)
END_SERIALIZABLE_CLASS_VERSIONS(FnResolveUriIterator)

SERIALIZABLE_CLASS_VERSIONS(SequentialIterator)
END_SERIALIZABLE_CLASS_VERSIONS(SequentialIterator)

SERIALIZABLE_CLASS_VERSIONS(FlowCtlIterator)
END_SERIALIZABLE_CLASS_VERSIONS(FlowCtlIterator)

SERIALIZABLE_CLASS_VERSIONS(LoopIterator)
END_SERIALIZABLE_CLASS_VERSIONS(LoopIterator)

SERIALIZABLE_CLASS_VERSIONS(FnReadStringIterator)
END_SERIALIZABLE_CLASS_VERSIONS(FnReadStringIterator)

SERIALIZABLE_CLASS_VERSIONS(FnPrintIterator)
END_SERIALIZABLE_CLASS_VERSIONS(FnPrintIterator)

NARY_ACCEPT(FnErrorIterator);

NARY_ACCEPT(FnResolveUriIterator);

NARY_ACCEPT(SequentialIterator);

NARY_ACCEPT(FlowCtlIterator);

NARY_ACCEPT (LoopIterator);

NARY_ACCEPT (FnReadStringIterator);

NARY_ACCEPT(FnPrintIterator);

// 3 The Error Function
//---------------------
bool FnErrorIterator::nextImpl(store::Item_t& result, PlanState& planState) const
{
  static const char *err_ns = "http://www.w3.org/2005/xqt-errors";
  store::Item_t err_qname;
  GENV_ITEMFACTORY->createQName (err_qname, err_ns, "err", "FOER0000");
  store::Item_t lTmpQName;
  store::Item_t lTmpErrorObject;
  store::Item_t lTmpDescr;
  xqp_string ns;
  xqp_string description;
  std::vector<store::Item_t> lErrorObject;

  PlanIteratorState *state;
  DEFAULT_STACK_INIT(PlanIteratorState, state, planState);

  if (theChildren.size () >= 1) {
    if (consumeNext(lTmpQName, theChildren[0].getp(), planState))
      err_qname = lTmpQName;
  }
  if (theChildren.size () >= 2) {
    consumeNext(lTmpDescr, theChildren[1].getp(), planState);
    description = lTmpDescr->getStringValue ().getp();
  }
  if (theChildren.size() == 3) {
    while (consumeNext(lTmpErrorObject, theChildren[2].getp(), planState)) {
      lErrorObject.push_back(lTmpErrorObject);
    }
  }

  {
    error::ZorbaUserError lError(err_qname, description, loc,
                                 __FILE__, __LINE__, lErrorObject);
    throw lError;
  }

  STACK_END (state);
}

// 8.1 fn:resolve-uri
//---------------------
bool FnResolveUriIterator::nextImpl(store::Item_t& result, PlanState& planState) const
{
  store::Item_t item;
  xqpStringStore_t strRelative;
  xqpStringStore_t strBase;
  xqpStringStore_t strResult;
  URI              baseURI;
  URI              resolvedURI;

  PlanIteratorState *state;
  DEFAULT_STACK_INIT(PlanIteratorState, state, planState);

  if (consumeNext(item, theChildren[0], planState ))
  {
    strRelative = item->getStringValue();

    //If first param is an absolute URI reference, it is returned unchanged.
    try{
      resolvedURI = URI(&*strRelative);
    } catch (error::ZorbaError&) {}

    if (resolvedURI.is_absolute()) {
      strResult = strRelative;
    }
    else
    {
      try
      {
        if (theChildren.size() == 1)
        {
          // use base-uri from static context
          strBase = theSctx->baseuri().getStore();
          if (strBase->empty())
          {
            ZORBA_ERROR_LOC_DESC(FONS0005, loc,
                                 "base-uri is not initialized in the static context");
          }
        }
        else if (consumeNext(item, theChildren[1], planState ))
        {
          // two parameters => get baseuri from the second argument
          strBase = item->getStringValue();
        }
        else
        {
          ZORBA_ERROR_LOC_DESC(FORG0009, loc, "Can't treat empty-sequence as base-uri");
        }
        baseURI = URI(&*strBase, true);
      }
      catch (error::ZorbaError& e)
      {
        ZORBA_ERROR_LOC_DESC(FORG0002, loc,
                             "String {" + strBase->str() +  "} is not a valid URI: " + e.theDescription);
      }

      try
      {
        resolvedURI = URI(baseURI, &*strRelative, true); // resolve with baseURI or return strRelative if it's a valid absolute URI
        strResult = resolvedURI.toString().getStore();
      }
      catch (error::ZorbaError& e)
      {
        ZORBA_ERROR_LOC_DESC(FORG0002, loc, e.theDescription);
      }
    }
    STACK_PUSH(GENV_ITEMFACTORY->createString(result, strResult), state);
  } // else return empty sequence if the first argument is the empty sequence

  STACK_END (state);
}

bool SequentialIterator::nextImpl(store::Item_t& result, PlanState& planState) const
{
  rchandle<store::PUL> lPul;

  PlanIteratorState *state;
  DEFAULT_STACK_INIT(PlanIteratorState, state, planState);

  for (unsigned i = 0; i < theChildren.size() - 1; i++)
  {
    while (CONSUME (result, i))
    {
      if (theChildren[i]->isUpdating())
      {
        std::set<zorba::store::Item*> validationNodes;

        static_cast<store::PUL *> (result.getp ())->applyUpdates(validationNodes);

        store::Item_t validationPul = GENV_ITEMFACTORY->createPendingUpdateList();

#ifndef ZORBA_NO_XMLSCHEMA
        QueryLoc& loc = theChildren[i]->loc;
        validateAfterUpdate(validationNodes,
                            validationPul,
                            getStaticContext(planState),
                            loc);
#endif
        validationPul->applyUpdates(validationNodes);
      }
    }
  }

  while (CONSUME (result, theChildren.size () - 1))
    STACK_PUSH (true, state);

  STACK_END (state);
}

bool FlowCtlIterator::nextImpl(store::Item_t& result, PlanState& planState) const {
  PlanIteratorState *state;
  DEFAULT_STACK_INIT(PlanIteratorState, state, planState);
  switch (act) {
  case EXIT:
    throw ExitException (new PlanIteratorWrapper (theChildren [0], planState));
  default:
    throw FlowCtlException (act);
  }

  STACK_END (state);
}

bool FnReadStringIterator::nextImpl (store::Item_t& result, PlanState& planState) const {
  PlanIteratorState *state;
  xqpStringStore_t xstr;
  char str [512];
  DEFAULT_STACK_INIT(PlanIteratorState, state, planState);
  std::cin.getline (str, sizeof (str));
  xstr = new xqpStringStore (str);
  GENV_ITEMFACTORY->createString (result, xstr);
  STACK_PUSH (true, state);
  STACK_END (state);
}

bool FnPrintIterator::nextImpl (store::Item_t& result, PlanState& planState) const
{
  std::ostringstream os;
  serializer* lSerializer = NULL;
  store::Item_t item;
  xqpStringStore_t resString;

  PlanIteratorState* state;
  DEFAULT_STACK_INIT(PlanIteratorState, state, planState);

  while (CONSUME (item, theChildren.size () - 1))
  {
    if (item->isNode())
    {
      if (lSerializer == NULL)
      {
        lSerializer = new serializer(planState.theCompilerCB->m_error_manager);
        lSerializer->set_parameter("omit-xml-declaration", "yes");
      }

      if (m_printToConsole) {
        lSerializer->serialize(item.getp(), std::cout);
      } else {
        lSerializer->serialize(item.getp(), os);
      }
    }
    else
    {
      if (m_printToConsole) {
          std::cout << item->getStringValue ();
      } else {
        os << item->getStringValue();
      }
    }
  }
  if (!m_printToConsole) {
    resString = new xqpStringStore(os.str());
    STACK_PUSH(GENV_ITEMFACTORY->createString(result, resString) , state);
  }
  STACK_END (state);
}

bool LoopIterator::nextImpl (store::Item_t& result, PlanState& planState) const {
  PlanIteratorState *state;
  DEFAULT_STACK_INIT(PlanIteratorState, state, planState);
  for (;;) {
    try {
      while (! CONSUME (result, 0))
        theChildren [0]->reset (planState);
    } catch (FlowCtlIterator::FlowCtlException &e) {
      switch (e.act) {
      case FlowCtlIterator::BREAK:
        goto done;
      case FlowCtlIterator::CONTINUE:
        theChildren [0]->reset (planState);
        continue;
      default:
        throw;
      }
    }
    STACK_PUSH (true, state);
  }

done:
  STACK_END (state);
}

} /* namespace zorba */
<|endoftext|>


<commit_before>// @(#)root/eve:$Id$
// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007

/*************************************************************************
 * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include "TEveBoxSet.h"
#include "TEveShape.h"

#include "TRandom.h"

//==============================================================================
// TEveBoxSet
//==============================================================================

//______________________________________________________________________________
//
// Collection of 3D primitives (fixed-size boxes, boxes of different
// sizes, or arbitrary sexto-epipeds, cones); each primitive can be assigned
// a signal value and a TRef.
//
// A collection of 3D-markers. The way how they are defined depends
// on the fBoxType data-member.
//   kBT_FreeBox         arbitrary box: specify 8*(x,y,z) box corners
//   kBT_AABox           axis-aligned box: specify (x,y,z) and (w, h, d)
//   kBT_AABoxFixedDim   axis-aligned box w/ fixed dimensions: specify (x,y,z)
//                       also set fDefWidth, fDefHeight and fDefDepth
//   kBT_Cone            cone defined with position, axis-vector and radius
//   EllipticCone        conew with elliptic base (specify another radius and angle in deg)
//
// Each primitive can be assigned:
// a) Color or signal value. Thresholds and signal-to-color mapping
//    can then be set dynamically via the TEveRGBAPalette class.
// b) External TObject* (stored as TRef).
//
// See also base-class TEveDigitSet for more information.
// Tutorial: tutorials/eve/boxset_test.C

ClassImp(TEveBoxSet);

//______________________________________________________________________________
TEveBoxSet::TEveBoxSet(const char* n, const char* t) :
   TEveDigitSet  (n, t),

   fBoxType      (kBT_Undef),
   fDefWidth     (1),
   fDefHeight    (1),
   fDefDepth     (1),

   fBoxSkip      (0),

   fDrawConeCap  (kFALSE)
{
   // Constructor.

   // Override from TEveDigitSet.
   fDisableLighting = kFALSE;
}

/******************************************************************************/

//______________________________________________________________________________
Int_t TEveBoxSet::SizeofAtom(TEveBoxSet::EBoxType_e bt)
{
   // Return size of data-structure describing a box of type bt.

   static const TEveException eH("TEveBoxSet::SizeofAtom ");

   switch (bt) {
      case kBT_Undef:                return 0;
      case kBT_FreeBox:              return sizeof(BFreeBox_t);
      case kBT_AABox:                return sizeof(BAABox_t);
      case kBT_AABoxFixedDim:        return sizeof(BAABoxFixedDim_t);
      case kBT_Cone:                 return sizeof(BCone_t);
      case kBT_EllipticCone:         return sizeof(BEllipticCone_t);
      default:                       throw(eH + "unexpected atom type.");
   }
   return 0;
}

/******************************************************************************/

//______________________________________________________________________________
void TEveBoxSet::Reset(TEveBoxSet::EBoxType_e boxType, Bool_t valIsCol, Int_t chunkSize)
{
   // Reset the data containers to zero size.
   // The arguments describe the basic parameters of data storage.

   fBoxType      = boxType;
   fValueIsColor = valIsCol;
   fDefaultValue = valIsCol ? 0 : kMinInt;
   if (fOwnIds)
      ReleaseIds();
   fPlex.Reset(SizeofAtom(fBoxType), chunkSize);
}

//______________________________________________________________________________
void TEveBoxSet::Reset()
{
   // Reset the data containers to zero size.
   // Keep the old data-storage parameters.

   if (fOwnIds)
      ReleaseIds();
   fPlex.Reset(SizeofAtom(fBoxType), TMath::Max(fPlex.N(), 64));
}

/******************************************************************************/

//______________________________________________________________________________
void TEveBoxSet::AddBox(const Float_t* verts)
{
   // Create a new box from a set of 8 vertices.
   // To be used for box-type kBT_FreeBox.

   static const TEveException eH("TEveBoxSet::AddBox ");

   if (fBoxType != kBT_FreeBox)
      throw(eH + "expect free box-type.");

   BFreeBox_t* b = (BFreeBox_t*) NewDigit();
   memcpy(b->fVertices, verts, sizeof(b->fVertices));
   TEveShape::CheckAndFixBoxOrientationFv(b->fVertices);
}

//______________________________________________________________________________
void TEveBoxSet::AddBox(Float_t a, Float_t b, Float_t c, Float_t w, Float_t h, Float_t d)
{
   // Create a new axis-aligned box from at a given position and with
   // specified dimensions.
   // To be used for box-type kBT_AABox.

   static const TEveException eH("TEveBoxSet::AddBox ");

   if (fBoxType != kBT_AABox)
      throw(eH + "expect axis-aligned box-type.");

   BAABox_t* box = (BAABox_t*) NewDigit();
   box->fA = a; box->fB = b; box->fC = c;
   box->fW = w; box->fH = h; box->fD = d;
}

//______________________________________________________________________________
void TEveBoxSet::AddBox(Float_t a, Float_t b, Float_t c)
{
   // Create a new axis-aligned box from at a given position.
   // To be used for box-type kBT_AABoxFixedDim.

   static const TEveException eH("TEveBoxSet::AddBox ");

   if (fBoxType != kBT_AABoxFixedDim)
      throw(eH + "expect axis-aligned fixed-dimension box-type.");

   BAABoxFixedDim_t* box = (BAABoxFixedDim_t*) NewDigit();
   box->fA = a; box->fB = b; box->fC = c;
}

//______________________________________________________________________________
void TEveBoxSet::AddCone(const TEveVector& pos, const TEveVector& dir, Float_t r)
{
   // Create a cone with apex at pos, axis dir and radius r.
   // To be used for box-type kBT_Cone.

   static const TEveException eH("TEveBoxSet::AddCone ");

   if (fBoxType != kBT_Cone)
      throw(eH + "expect cone box-type.");

   BCone_t* cone = (BCone_t*) NewDigit();
   cone->fPos = pos;
   cone->fDir = dir;
   cone->fR   = r;
}

//______________________________________________________________________________
void TEveBoxSet::AddEllipticCone(const TEveVector& pos, const TEveVector& dir,
                                 Float_t r, Float_t r2, Float_t angle)
{
   // Create a cone with apex at pos, axis dir and radius r.
   // To be used for box-type kBT_Cone.

   static const TEveException eH("TEveBoxSet::AddEllipticCone ");

   if (fBoxType != kBT_EllipticCone)
      throw(eH + "expect ellicptic-cone box-type.");

   BEllipticCone_t* cone = (BEllipticCone_t*) NewDigit();
   cone->fPos = pos;
   cone->fDir = dir;
   cone->fR   = r;
   cone->fR2  = r2;
   cone->fAngle = angle;
}

/******************************************************************************/

//______________________________________________________________________________
void TEveBoxSet::ComputeBBox()
{
   // Fill bounding-box information of the base-class TAttBBox (virtual method).
   // If member 'TEveFrameBox* fFrame' is set, frame's corners are used as bbox.

   static const TEveException eH("TEveBoxSet::ComputeBBox ");

   if (fFrame != 0)
   {
      BBoxInit();
      Int_t    n    = fFrame->GetFrameSize() / 3;
      Float_t *bbps = fFrame->GetFramePoints();
      for (int i=0; i<n; ++i, bbps+=3)
         BBoxCheckPoint(bbps);
      return;
   }

   if(fPlex.Size() == 0)
   {
      BBoxZero();
      return;
   }

   BBoxInit();

   TEveChunkManager::iterator bi(fPlex);
   switch (fBoxType)
   {

      case kBT_FreeBox:
      {
         while (bi.next()) {
            BFreeBox_t& b = * (BFreeBox_t*) bi();
            for (Int_t i = 0; i < 8; ++i)
               BBoxCheckPoint(b.fVertices[i]);
         }
         break;
      }

      case kBT_AABox:
      {
         while (bi.next()) {
            BAABox_t& b = * (BAABox_t*) bi();
            BBoxCheckPoint(b.fA, b.fB, b.fC);
            BBoxCheckPoint(b.fA + b.fW, b.fB + b.fH , b.fC + b.fD);
         }
         break;
      }

      case kBT_AABoxFixedDim:
      {
         while (bi.next()) {
            BAABoxFixedDim_t& b = * (BAABoxFixedDim_t*) bi();
            BBoxCheckPoint(b.fA, b.fB, b.fC);
            BBoxCheckPoint(b.fA + fDefWidth, b.fB + fDefHeight , b.fC + fDefDepth);
         }
         break;
      }
      case kBT_Cone:
      {
         Float_t mag2=0, mag2Max=0, rMax=0;
         while (bi.next()) {
            BCone_t& b = * (BCone_t*) bi();
            BBoxCheckPoint(b.fPos.fX, b.fPos.fY, b.fPos.fZ);
            mag2 = b.fDir.Mag2();
            if (mag2>mag2Max) mag2Max=mag2;
            if (b.fR>rMax)    rMax=b.fR;
         }
         Float_t off = TMath::Sqrt(mag2Max + rMax*rMax);
         fBBox[0] -= off;fBBox[2] -= off;fBBox[4] -= off;
         fBBox[1] += off;fBBox[3] += off;fBBox[5] += off;
         break;
      }
      case kBT_EllipticCone:
      {
         Float_t mag2=0, mag2Max=0, rMax=0;
         while (bi.next()) {
            BEllipticCone_t& b = * (BEllipticCone_t*) bi();
            BBoxCheckPoint(b.fPos.fX, b.fPos.fY, b.fPos.fZ);
            mag2 = b.fDir.Mag2();
            if (mag2>mag2Max) mag2Max=mag2;
            if (b.fR  > rMax) rMax = b.fR;
            if (b.fR2 > rMax) rMax = b.fR2;
         }
         Float_t off = TMath::Sqrt(mag2Max + rMax*rMax);
         fBBox[0] -= off;fBBox[2] -= off;fBBox[4] -= off;
         fBBox[1] += off;fBBox[3] += off;fBBox[5] += off;
         break;
      }
      default:
      {
         throw(eH + "unsupported box-type.");
      }

   } // end switch box-type
}

/******************************************************************************/

//______________________________________________________________________________
void TEveBoxSet::Test(Int_t nboxes)
{
   // Fill the structure with a random set of boxes.

   Reset(kBT_AABox, kTRUE, nboxes);
   TRandom rnd(0);
   const Float_t origin = 10, size = 2;
   Int_t color;
   for(Int_t i=0; i<nboxes; ++i)
   {
      AddBox(origin * rnd.Uniform(-1, 1),
             origin * rnd.Uniform(-1, 1),
             origin * rnd.Uniform(-1, 1),
             size   * rnd.Uniform(0.1, 1),
             size   * rnd.Uniform(0.1, 1),
             size   * rnd.Uniform(0.1, 1));

      TEveUtil::ColorFromIdx(rnd.Integer(256), (UChar_t*)&color);
      DigitValue(color);
   }
}
<commit_msg>Fix typo in docs.<commit_after>// @(#)root/eve:$Id$
// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007

/*************************************************************************
 * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include "TEveBoxSet.h"
#include "TEveShape.h"

#include "TRandom.h"

//==============================================================================
// TEveBoxSet
//==============================================================================

//______________________________________________________________________________
//
// Collection of 3D primitives (fixed-size boxes, boxes of different
// sizes, or arbitrary sexto-epipeds, cones); each primitive can be assigned
// a signal value and a TRef.
//
// A collection of 3D-markers. The way how they are defined depends
// on the fBoxType data-member.
//   kBT_FreeBox         arbitrary box: specify 8*(x,y,z) box corners
//   kBT_AABox           axis-aligned box: specify (x,y,z) and (w, h, d)
//   kBT_AABoxFixedDim   axis-aligned box w/ fixed dimensions: specify (x,y,z)
//                       also set fDefWidth, fDefHeight and fDefDepth
//   kBT_Cone            cone defined with position, axis-vector and radius
//   EllipticCone        conew with elliptic base (specify another radius and angle in deg)
//
// Each primitive can be assigned:
// a) Color or signal value. Thresholds and signal-to-color mapping
//    can then be set dynamically via the TEveRGBAPalette class.
// b) External TObject* (stored as TRef).
//
// See also base-class TEveDigitSet for more information.
// Tutorial: tutorials/eve/boxset_test.C

ClassImp(TEveBoxSet);

//______________________________________________________________________________
TEveBoxSet::TEveBoxSet(const char* n, const char* t) :
   TEveDigitSet  (n, t),

   fBoxType      (kBT_Undef),
   fDefWidth     (1),
   fDefHeight    (1),
   fDefDepth     (1),

   fBoxSkip      (0),

   fDrawConeCap  (kFALSE)
{
   // Constructor.

   // Override from TEveDigitSet.
   fDisableLighting = kFALSE;
}

/******************************************************************************/

//______________________________________________________________________________
Int_t TEveBoxSet::SizeofAtom(TEveBoxSet::EBoxType_e bt)
{
   // Return size of data-structure describing a box of type bt.

   static const TEveException eH("TEveBoxSet::SizeofAtom ");

   switch (bt) {
      case kBT_Undef:                return 0;
      case kBT_FreeBox:              return sizeof(BFreeBox_t);
      case kBT_AABox:                return sizeof(BAABox_t);
      case kBT_AABoxFixedDim:        return sizeof(BAABoxFixedDim_t);
      case kBT_Cone:                 return sizeof(BCone_t);
      case kBT_EllipticCone:         return sizeof(BEllipticCone_t);
      default:                       throw(eH + "unexpected atom type.");
   }
   return 0;
}

/******************************************************************************/

//______________________________________________________________________________
void TEveBoxSet::Reset(TEveBoxSet::EBoxType_e boxType, Bool_t valIsCol, Int_t chunkSize)
{
   // Reset the data containers to zero size.
   // The arguments describe the basic parameters of data storage.

   fBoxType      = boxType;
   fValueIsColor = valIsCol;
   fDefaultValue = valIsCol ? 0 : kMinInt;
   if (fOwnIds)
      ReleaseIds();
   fPlex.Reset(SizeofAtom(fBoxType), chunkSize);
}

//______________________________________________________________________________
void TEveBoxSet::Reset()
{
   // Reset the data containers to zero size.
   // Keep the old data-storage parameters.

   if (fOwnIds)
      ReleaseIds();
   fPlex.Reset(SizeofAtom(fBoxType), TMath::Max(fPlex.N(), 64));
}

/******************************************************************************/

//______________________________________________________________________________
void TEveBoxSet::AddBox(const Float_t* verts)
{
   // Create a new box from a set of 8 vertices.
   // To be used for box-type kBT_FreeBox.

   static const TEveException eH("TEveBoxSet::AddBox ");

   if (fBoxType != kBT_FreeBox)
      throw(eH + "expect free box-type.");

   BFreeBox_t* b = (BFreeBox_t*) NewDigit();
   memcpy(b->fVertices, verts, sizeof(b->fVertices));
   TEveShape::CheckAndFixBoxOrientationFv(b->fVertices);
}

//______________________________________________________________________________
void TEveBoxSet::AddBox(Float_t a, Float_t b, Float_t c, Float_t w, Float_t h, Float_t d)
{
   // Create a new axis-aligned box from at a given position and with
   // specified dimensions.
   // To be used for box-type kBT_AABox.

   static const TEveException eH("TEveBoxSet::AddBox ");

   if (fBoxType != kBT_AABox)
      throw(eH + "expect axis-aligned box-type.");

   BAABox_t* box = (BAABox_t*) NewDigit();
   box->fA = a; box->fB = b; box->fC = c;
   box->fW = w; box->fH = h; box->fD = d;
}

//______________________________________________________________________________
void TEveBoxSet::AddBox(Float_t a, Float_t b, Float_t c)
{
   // Create a new axis-aligned box from at a given position.
   // To be used for box-type kBT_AABoxFixedDim.

   static const TEveException eH("TEveBoxSet::AddBox ");

   if (fBoxType != kBT_AABoxFixedDim)
      throw(eH + "expect axis-aligned fixed-dimension box-type.");

   BAABoxFixedDim_t* box = (BAABoxFixedDim_t*) NewDigit();
   box->fA = a; box->fB = b; box->fC = c;
}

//______________________________________________________________________________
void TEveBoxSet::AddCone(const TEveVector& pos, const TEveVector& dir, Float_t r)
{
   // Create a cone with apex at pos, axis dir and radius r.
   // To be used for box-type kBT_Cone.

   static const TEveException eH("TEveBoxSet::AddCone ");

   if (fBoxType != kBT_Cone)
      throw(eH + "expect cone box-type.");

   BCone_t* cone = (BCone_t*) NewDigit();
   cone->fPos = pos;
   cone->fDir = dir;
   cone->fR   = r;
}

//______________________________________________________________________________
void TEveBoxSet::AddEllipticCone(const TEveVector& pos, const TEveVector& dir,
                                 Float_t r, Float_t r2, Float_t angle)
{
   // Create a cone with apex at pos, axis dir and radius r.
   // To be used for box-type kBT_EllipticCone.

   static const TEveException eH("TEveBoxSet::AddEllipticCone ");

   if (fBoxType != kBT_EllipticCone)
      throw(eH + "expect ellicptic-cone box-type.");

   BEllipticCone_t* cone = (BEllipticCone_t*) NewDigit();
   cone->fPos = pos;
   cone->fDir = dir;
   cone->fR   = r;
   cone->fR2  = r2;
   cone->fAngle = angle;
}

/******************************************************************************/

//______________________________________________________________________________
void TEveBoxSet::ComputeBBox()
{
   // Fill bounding-box information of the base-class TAttBBox (virtual method).
   // If member 'TEveFrameBox* fFrame' is set, frame's corners are used as bbox.

   static const TEveException eH("TEveBoxSet::ComputeBBox ");

   if (fFrame != 0)
   {
      BBoxInit();
      Int_t    n    = fFrame->GetFrameSize() / 3;
      Float_t *bbps = fFrame->GetFramePoints();
      for (int i=0; i<n; ++i, bbps+=3)
         BBoxCheckPoint(bbps);
      return;
   }

   if(fPlex.Size() == 0)
   {
      BBoxZero();
      return;
   }

   BBoxInit();

   TEveChunkManager::iterator bi(fPlex);
   switch (fBoxType)
   {

      case kBT_FreeBox:
      {
         while (bi.next()) {
            BFreeBox_t& b = * (BFreeBox_t*) bi();
            for (Int_t i = 0; i < 8; ++i)
               BBoxCheckPoint(b.fVertices[i]);
         }
         break;
      }

      case kBT_AABox:
      {
         while (bi.next()) {
            BAABox_t& b = * (BAABox_t*) bi();
            BBoxCheckPoint(b.fA, b.fB, b.fC);
            BBoxCheckPoint(b.fA + b.fW, b.fB + b.fH , b.fC + b.fD);
         }
         break;
      }

      case kBT_AABoxFixedDim:
      {
         while (bi.next()) {
            BAABoxFixedDim_t& b = * (BAABoxFixedDim_t*) bi();
            BBoxCheckPoint(b.fA, b.fB, b.fC);
            BBoxCheckPoint(b.fA + fDefWidth, b.fB + fDefHeight , b.fC + fDefDepth);
         }
         break;
      }
      case kBT_Cone:
      {
         Float_t mag2=0, mag2Max=0, rMax=0;
         while (bi.next()) {
            BCone_t& b = * (BCone_t*) bi();
            BBoxCheckPoint(b.fPos.fX, b.fPos.fY, b.fPos.fZ);
            mag2 = b.fDir.Mag2();
            if (mag2>mag2Max) mag2Max=mag2;
            if (b.fR>rMax)    rMax=b.fR;
         }
         Float_t off = TMath::Sqrt(mag2Max + rMax*rMax);
         fBBox[0] -= off;fBBox[2] -= off;fBBox[4] -= off;
         fBBox[1] += off;fBBox[3] += off;fBBox[5] += off;
         break;
      }
      case kBT_EllipticCone:
      {
         Float_t mag2=0, mag2Max=0, rMax=0;
         while (bi.next()) {
            BEllipticCone_t& b = * (BEllipticCone_t*) bi();
            BBoxCheckPoint(b.fPos.fX, b.fPos.fY, b.fPos.fZ);
            mag2 = b.fDir.Mag2();
            if (mag2>mag2Max) mag2Max=mag2;
            if (b.fR  > rMax) rMax = b.fR;
            if (b.fR2 > rMax) rMax = b.fR2;
         }
         Float_t off = TMath::Sqrt(mag2Max + rMax*rMax);
         fBBox[0] -= off;fBBox[2] -= off;fBBox[4] -= off;
         fBBox[1] += off;fBBox[3] += off;fBBox[5] += off;
         break;
      }
      default:
      {
         throw(eH + "unsupported box-type.");
      }

   } // end switch box-type
}

/******************************************************************************/

//______________________________________________________________________________
void TEveBoxSet::Test(Int_t nboxes)
{
   // Fill the structure with a random set of boxes.

   Reset(kBT_AABox, kTRUE, nboxes);
   TRandom rnd(0);
   const Float_t origin = 10, size = 2;
   Int_t color;
   for(Int_t i=0; i<nboxes; ++i)
   {
      AddBox(origin * rnd.Uniform(-1, 1),
             origin * rnd.Uniform(-1, 1),
             origin * rnd.Uniform(-1, 1),
             size   * rnd.Uniform(0.1, 1),
             size   * rnd.Uniform(0.1, 1),
             size   * rnd.Uniform(0.1, 1));

      TEveUtil::ColorFromIdx(rnd.Integer(256), (UChar_t*)&color);
      DigitValue(color);
   }
}
<|endoftext|>


<commit_before>/*
 * File:   mvmDisassembly.cpp
 * Author: ghernan
 *
 * Micro virtual machine disassembly functions
 *
 * Created on December 29, 2016, 14:20 PM
 */

#include "ascript_pch.hpp"
#include "microVM.h"
//#include "asActors.h"
#include "asObjects.h"

using namespace std;

Ref<JSObject> disassemblyFunction (Ref<JSFunction> function);
Ref<JSObject> disassemblyClosure (Ref<JSClosure> function);
//Ref<JSObject> disassemblyActorClass (Ref<AsActorClass> actorClass);
//Ref<JSObject> disassemblyInputEndPoint (Ref<AsEndPoint> ep);
//Ref<JSObject> disassemblyOutputEndPoint (Ref<AsEndPoint> ep);
Ref<JSObject> disassemblyClass (Ref<JSClass> cls);
Ref<JSObject> disassemblyMembers (ASValue container);

/**
 * Generates a Javascript object representation of a single constant
 * @param constants
 * @return
 */
ASValue constantToJS (ASValue constant)
{
    switch (constant.getType())
    {
//    case VT_ACTOR_CLASS:
//        return disassemblyActorClass (constant.staticCast<AsActorClass>());

    case VT_CLASS:
        return disassemblyClass (constant.staticCast<JSClass>())->value();

    case VT_FUNCTION:
        return disassemblyFunction (constant.staticCast<JSFunction>())->value();

    case VT_CLOSURE:
        return disassemblyClosure (constant.staticCast<JSClosure>())->value();

//    case VT_INPUT_EP:
//        return disassemblyInputEndPoint (constant.staticCast<AsEndPoint>());
//
//    case VT_OUTPUT_EP:
//        return disassemblyOutputEndPoint (constant.staticCast<AsEndPoint>());

    default:
        return constant;
    }//switch
}

/**
 * Generates a textual representation of a constant list
 * @param constants
 * @return
 */
ASValue constantsToJS (const ValueVector& constants)
{
    Ref<JSObject>   obj = JSObject::create();
    char            name[64];

    for (size_t i=0; i < constants.size(); ++i )
    {
        sprintf_s (name, "%04lu", i);
        ASValue    value = constantToJS(constants[i]);

        obj->writeField(name, value, false);
    }

    return obj->value();
}

/**
 * Disassemblies a 'push constant' operation
 * @param index
 * @param constants
 * @return
 */
string disassemblyPushC (int index, const ValueVector& constants)
{
    ostringstream   output;

    output << "PUSHC(" << index << ") -> " << constants[index].toString();
    //output << "PUSHC(" << index << ")";
    return output.str();

}

/**
 * Disassemblies an 8 bit instruction
 * @param opCode
 * @param constants
 * @return
 */
string disassembly8bitInst (int opCode, const ValueVector& constants)
{
    if (opCode >= OC_PUSHC)
        return disassemblyPushC (opCode - OC_PUSHC, constants);
    else
    {
        switch (opCode)
        {
        case OC_CALL:   return "CALL(0)";
        case OC_CALL+1:   return "CALL(1)";
        case OC_CALL+2:   return "CALL(2)";
        case OC_CALL+3:   return "CALL(3)";
        case OC_CALL+4:   return "CALL(4)";
        case OC_CALL+5:   return "CALL(5)";
        case OC_CALL+6:   return "CALL(6)";
        case OC_CALL+7:   return "CALL(7)";
        case OC_CP:         return "CP(0)";
        case OC_CP+1:       return "CP(1)";
        case OC_CP+2:       return "CP(2)";
        case OC_CP+3:       return "CP(3)";
        case OC_CP+4:       return "CP(4)";
        case OC_CP+5:       return "CP(5)";
        case OC_CP+6:       return "CP(6)";
        case OC_CP+7:       return "CP(7)";
        case OC_WR+1:       return "WR(1)";
        case OC_WR+2:       return "WR(2)";
        case OC_WR+3:       return "WR(3)";
        case OC_WR+4:       return "WR(4)";
        case OC_WR+5:       return "WR(5)";
        case OC_WR+6:       return "WR(6)";
        case OC_WR+7:       return "WR(7)";
        case OC_SWAP:       return "SWAP";
        case OC_POP:        return "POP";
//        case OC_PUSH_SCOPE: return "PUSH_SCOPE";
//        case OC_POP_SCOPE:  return "POP_SCOPE";
//        case OC_RD_LOCAL:   return "RD_LOCAL";
//        case OC_WR_LOCAL:   return "WR_LOCAL";
//        case OC_RD_GLOBAL:      return "RD_GLOBAL";
//        case OC_WR_GLOBAL:      return "WR_GLOBAL";
        case OC_RD_FIELD:       return "RD_FIELD";
        case OC_WR_FIELD:       return "WR_FIELD";
        case OC_RD_INDEX:       return "RD_INDEX";
        case OC_WR_INDEX:       return "WR_INDEX";
//        case OC_NEW_VAR:        return "NEW_VAR";
//        case OC_NEW_CONST:      return "NEW_CONST";
        case OC_NEW_CONST_FIELD:return "NEW_CONST_FIELD";
//        case OC_CP_AUX:         return "CP_AUX";
//        case OC_PUSH_AUX:       return "PUSH_AUX";
        case OC_RD_PARAM:       return "OC_RD_PARAM";
        case OC_WR_PARAM:       return "OC_WR_PARAM";
        case OC_NUM_PARAMS:     return "OC_NUM_PARAMS";
        case OC_NOP:            return "NOP";
        default:
            return "BAD_OP_CODE_8";
        }
    }
}

/**
 * Disassemblies a 16 bit instruction
 * @param opCode
 * @param constants
 * @return
 */
string disassembly16bitInst (int opCode, const ValueVector& constants)
{
    opCode &= ~OC16_16BIT_FLAG;
    if (opCode >= OC16_PUSHC)
        return disassemblyPushC (opCode - (OC16_PUSHC - 64), constants);
    else if (opCode <= OC16_CALL_MAX)
    {
        ostringstream   output;

        output << "CALL(" << (opCode + OC_CALL_MAX + 1) << ")";
        return output.str();
    }
    else if (opCode <= OC16_CP_MAX)
    {
        ostringstream   output;

        output << "CP(" << ((opCode-OC16_CP) + (OC_CP_MAX - OC_CP) + 1) << ")";
        return output.str();
    }
    else if (opCode <= OC16_WR_MAX)
    {
        ostringstream   output;

        output << "WR(" << ((opCode-OC16_WR) + (OC_WR_MAX - OC_WR) + 1) << ")";
        return output.str();
    }
    else
        return "BAD_OP_CODE_16";
}

/**
 * Disassemblies a block of instructions
 * @param code
 * @param constants
 * @return
 */
Ref<JSObject> disassemblyInstructions (const ByteVector& code,
                                       const ValueVector& constants)
{
    auto    result = JSObject::create();
    char    position[64];

    for (size_t i=0; i < code.size(); ++i)
    {
        string  instructionStr;

        sprintf_s (position, "%04u", (unsigned)i);

        if (code[i] & OC_EXT_FLAG)
        {
            const int opCode = int(code[i]) << 8 | code[i+1];
            instructionStr = disassembly16bitInst (opCode, constants);
            ++i;
        }
        else
            instructionStr = disassembly8bitInst (code[i], constants);

        result->writeField(position, jsString(instructionStr), false);
    }

    return result;
}

/**
 * Blocks disassembly
 * @param blocks
 * @return
 */
Ref<JSObject> blocksToJS (const BlockVector& blocks,
                          const ValueVector& constants)
{
    Ref<JSObject>   obj = JSObject::create();
    char            name[64];

    for (size_t i=0; i < blocks.size(); ++i )
    {
        sprintf_s (name, "Block%04lu", i);
        Ref<JSObject>   blockObj = JSObject::create();

        obj->writeField(name, blockObj->value(), false);

        blockObj->writeField("nextTrue", jsInt(blocks[i].nextBlocks[1]), false);
        blockObj->writeField("nextFalse", jsInt(blocks[i].nextBlocks[0]), false);
        blockObj->writeField("instructions",
                             disassemblyInstructions (blocks[i].instructions, constants)->value(),
                             false);

    }

    return obj;
}

/**
 * Generates a human-readable representation of the input script.
 * @param code
 * @return
 */
string mvmDisassembly (Ref<MvmRoutine> code)
{
    return toJSObject(code)->getJSON(0);
}

/**
 * Disassemblies a single instruction
 * @param opCode
 * @param constants
 * @return
 */
string mvmDisassemblyInstruction (int opCode, const ValueVector& constants)
{
    if (opCode <= 127)
        return disassembly8bitInst(opCode, constants);
    else
        return disassembly16bitInst(opCode, constants);
}

/**
 * Transforms a compiled scirpt into a JSObject.
 * It can be used later from JAvascript code or written to a JSOn file.
 * @param code
 * @return
 */
Ref<JSObject> toJSObject (Ref<MvmRoutine> code)
{
    Ref<JSObject>   obj = JSObject::create();

    obj->writeField ("constants", constantsToJS(code->constants), false);
    obj->writeField ("blocks", blocksToJS(code->blocks, code->constants)->value(), false);

    return obj;
}

/**
 * Generates an human readable representation of a function
 * @param function
 * @return
 */
Ref<JSObject> disassemblyFunction (Ref<JSFunction> function)
{
    Ref<JSObject>   obj = JSObject::create();

    obj->writeField ("header", jsString(function->toString() ), false);
    if (function->isNative())
        obj->writeField("code", jsString("native"), false);
    else
    {
        obj->writeField("code",
                        toJSObject(function->getCodeMVM().staticCast<MvmRoutine>())->value(),
                        false);
    }

    return obj;
}

/**
 * Generates an human readable representation of a closure
 * @param closure
 * @return
 */
Ref<JSObject> disassemblyClosure (Ref<JSClosure> closure)
{
    return disassemblyFunction (closure->getFunction());
}

/**
 * Transforms an actor class into a Javascript object which can be serialized.
 * @param actorClass
 * @return
 */
//Ref<JSObject> disassemblyActorClass (Ref<AsActorClass> actorClass)
//{
//    Ref<JSObject>   obj = JSObject::create();
//
//    obj->writeField ("actorClass", jsString(actorClass->getName()), false );
//
//    auto members = disassemblyMembers(actorClass);
//    obj->writeField ("members", members, false);
//
//    return obj;
//}
//
///**
// * Transforms an input endpoint to a Javascript object representation
// * @param ep
// * @return
// */
//Ref<JSObject> disassemblyInputEndPoint (Ref<AsEndPoint> ep)
//{
//    return disassemblyFunction(ep);
//}
//
///**
// * Transforms an output endpoint to a Javascript object representation
// * @param ep
// * @return
// */
//Ref<JSObject> disassemblyOutputEndPoint (Ref<AsEndPoint> ep)
//{
//    auto result = JSObject::create();
//    result->writeField ("header", jsString(ep->toString() ), false);
//    return result;
//}

/**
 * Disassemblies a class declaration
 * @param cls
 * @return
 */
Ref<JSObject> disassemblyClass (Ref<JSClass> cls)
{
    auto result = JSObject::create();
    result->writeField ("Class", jsString(cls->getName()), false);

    auto    parent = cls->getParent();
    auto    constructor = constantToJS(cls->getConstructor()->value());
    string  parentName;

    if (parent.notNull())
        parentName = parent->getName();

    result->writeField ("Parent", jsString(parentName), false);
    result->writeField("constructor", constructor, false);

    auto members = disassemblyMembers(cls->value());

    result->writeField("members", members->value(), false);

    return result;
}

/**
 * Gets the disassembly representation of the members of a value
 * @param container
 * @return
 */
Ref<JSObject> disassemblyMembers (ASValue container)
{
    auto memberNames = container.getFields(false);
    auto members = JSObject::create();

    for (auto it = memberNames.begin(); it != memberNames.end(); ++it)
    {
        auto member = container.readField(*it);
        members->writeField(*it, constantToJS(member), false);
    }

    return members;
}
<commit_msg>Disassebly support for new 'this' related instructions.<commit_after>/*
 * File:   mvmDisassembly.cpp
 * Author: ghernan
 *
 * Micro virtual machine disassembly functions
 *
 * Created on December 29, 2016, 14:20 PM
 */

#include "ascript_pch.hpp"
#include "microVM.h"
//#include "asActors.h"
#include "asObjects.h"

using namespace std;

Ref<JSObject> disassemblyFunction (Ref<JSFunction> function);
Ref<JSObject> disassemblyClosure (Ref<JSClosure> function);
//Ref<JSObject> disassemblyActorClass (Ref<AsActorClass> actorClass);
//Ref<JSObject> disassemblyInputEndPoint (Ref<AsEndPoint> ep);
//Ref<JSObject> disassemblyOutputEndPoint (Ref<AsEndPoint> ep);
Ref<JSObject> disassemblyClass (Ref<JSClass> cls);
Ref<JSObject> disassemblyMembers (ASValue container);

/**
 * Generates a Javascript object representation of a single constant
 * @param constants
 * @return
 */
ASValue constantToJS (ASValue constant)
{
    switch (constant.getType())
    {
//    case VT_ACTOR_CLASS:
//        return disassemblyActorClass (constant.staticCast<AsActorClass>());

    case VT_CLASS:
        return disassemblyClass (constant.staticCast<JSClass>())->value();

    case VT_FUNCTION:
        return disassemblyFunction (constant.staticCast<JSFunction>())->value();

    case VT_CLOSURE:
        return disassemblyClosure (constant.staticCast<JSClosure>())->value();

//    case VT_INPUT_EP:
//        return disassemblyInputEndPoint (constant.staticCast<AsEndPoint>());
//
//    case VT_OUTPUT_EP:
//        return disassemblyOutputEndPoint (constant.staticCast<AsEndPoint>());

    default:
        return constant;
    }//switch
}

/**
 * Generates a textual representation of a constant list
 * @param constants
 * @return
 */
ASValue constantsToJS (const ValueVector& constants)
{
    Ref<JSObject>   obj = JSObject::create();
    char            name[64];

    for (size_t i=0; i < constants.size(); ++i )
    {
        sprintf_s (name, "%04lu", i);
        ASValue    value = constantToJS(constants[i]);

        obj->writeField(name, value, false);
    }

    return obj->value();
}

/**
 * Disassemblies a 'push constant' operation
 * @param index
 * @param constants
 * @return
 */
string disassemblyPushC (int index, const ValueVector& constants)
{
    ostringstream   output;

    output << "PUSHC(" << index << ") -> " << constants[index].toString();
    //output << "PUSHC(" << index << ")";
    return output.str();

}

/**
 * Disassemblies an 8 bit instruction
 * @param opCode
 * @param constants
 * @return
 */
string disassembly8bitInst (int opCode, const ValueVector& constants)
{
    if (opCode >= OC_PUSHC)
        return disassemblyPushC (opCode - OC_PUSHC, constants);
    else
    {
        switch (opCode)
        {
        case OC_CALL:   return "CALL(0)";
        case OC_CALL+1:   return "CALL(1)";
        case OC_CALL+2:   return "CALL(2)";
        case OC_CALL+3:   return "CALL(3)";
        case OC_CALL+4:   return "CALL(4)";
        case OC_CALL+5:   return "CALL(5)";
        case OC_CALL+6:   return "CALL(6)";
        case OC_CALL+7:   return "CALL(7)";
        case OC_CP:         return "CP(0)";
        case OC_CP+1:       return "CP(1)";
        case OC_CP+2:       return "CP(2)";
        case OC_CP+3:       return "CP(3)";
        case OC_CP+4:       return "CP(4)";
        case OC_CP+5:       return "CP(5)";
        case OC_CP+6:       return "CP(6)";
        case OC_CP+7:       return "CP(7)";
        case OC_WR+1:       return "WR(1)";
        case OC_WR+2:       return "WR(2)";
        case OC_WR+3:       return "WR(3)";
        case OC_WR+4:       return "WR(4)";
        case OC_WR+5:       return "WR(5)";
        case OC_WR+6:       return "WR(6)";
        case OC_WR+7:       return "WR(7)";
        case OC_SWAP:       return "SWAP";
        case OC_POP:        return "POP";
//        case OC_PUSH_SCOPE: return "PUSH_SCOPE";
//        case OC_POP_SCOPE:  return "POP_SCOPE";
//        case OC_RD_LOCAL:   return "RD_LOCAL";
//        case OC_WR_LOCAL:   return "WR_LOCAL";
//        case OC_RD_GLOBAL:      return "RD_GLOBAL";
//        case OC_WR_GLOBAL:      return "WR_GLOBAL";
        case OC_RD_FIELD:       return "RD_FIELD";
        case OC_WR_FIELD:       return "WR_FIELD";
        case OC_RD_INDEX:       return "RD_INDEX";
        case OC_WR_INDEX:       return "WR_INDEX";
//        case OC_NEW_VAR:        return "NEW_VAR";
//        case OC_NEW_CONST:      return "NEW_CONST";
        case OC_NEW_CONST_FIELD:return "NEW_CONST_FIELD";
//        case OC_CP_AUX:         return "CP_AUX";
//        case OC_PUSH_AUX:       return "PUSH_AUX";
        case OC_RD_PARAM:       return "OC_RD_PARAM";
        case OC_WR_PARAM:       return "OC_WR_PARAM";
        case OC_NUM_PARAMS:     return "OC_NUM_PARAMS";
        case OC_PUSH_THIS:      return "OC_PUSH_THIS";
        case OC_WR_THISP:       return "OC_WR_THISP";
        case OC_NOP:            return "NOP";
        default:
            return "BAD_OP_CODE_8";
        }
    }
}

/**
 * Disassemblies a 16 bit instruction
 * @param opCode
 * @param constants
 * @return
 */
string disassembly16bitInst (int opCode, const ValueVector& constants)
{
    opCode &= ~OC16_16BIT_FLAG;
    if (opCode >= OC16_PUSHC)
        return disassemblyPushC (opCode - (OC16_PUSHC - 64), constants);
    else if (opCode <= OC16_CALL_MAX)
    {
        ostringstream   output;

        output << "CALL(" << (opCode + OC_CALL_MAX + 1) << ")";
        return output.str();
    }
    else if (opCode <= OC16_CP_MAX)
    {
        ostringstream   output;

        output << "CP(" << ((opCode-OC16_CP) + (OC_CP_MAX - OC_CP) + 1) << ")";
        return output.str();
    }
    else if (opCode <= OC16_WR_MAX)
    {
        ostringstream   output;

        output << "WR(" << ((opCode-OC16_WR) + (OC_WR_MAX - OC_WR) + 1) << ")";
        return output.str();
    }
    else
        return "BAD_OP_CODE_16";
}

/**
 * Disassemblies a block of instructions
 * @param code
 * @param constants
 * @return
 */
Ref<JSObject> disassemblyInstructions (const ByteVector& code,
                                       const ValueVector& constants)
{
    auto    result = JSObject::create();
    char    position[64];

    for (size_t i=0; i < code.size(); ++i)
    {
        string  instructionStr;

        sprintf_s (position, "%04u", (unsigned)i);

        if (code[i] & OC_EXT_FLAG)
        {
            const int opCode = int(code[i]) << 8 | code[i+1];
            instructionStr = disassembly16bitInst (opCode, constants);
            ++i;
        }
        else
            instructionStr = disassembly8bitInst (code[i], constants);

        result->writeField(position, jsString(instructionStr), false);
    }

    return result;
}

/**
 * Blocks disassembly
 * @param blocks
 * @return
 */
Ref<JSObject> blocksToJS (const BlockVector& blocks,
                          const ValueVector& constants)
{
    Ref<JSObject>   obj = JSObject::create();
    char            name[64];

    for (size_t i=0; i < blocks.size(); ++i )
    {
        sprintf_s (name, "Block%04lu", i);
        Ref<JSObject>   blockObj = JSObject::create();

        obj->writeField(name, blockObj->value(), false);

        blockObj->writeField("nextTrue", jsInt(blocks[i].nextBlocks[1]), false);
        blockObj->writeField("nextFalse", jsInt(blocks[i].nextBlocks[0]), false);
        blockObj->writeField("instructions",
                             disassemblyInstructions (blocks[i].instructions, constants)->value(),
                             false);

    }

    return obj;
}

/**
 * Generates a human-readable representation of the input script.
 * @param code
 * @return
 */
string mvmDisassembly (Ref<MvmRoutine> code)
{
    return toJSObject(code)->getJSON(0);
}

/**
 * Disassemblies a single instruction
 * @param opCode
 * @param constants
 * @return
 */
string mvmDisassemblyInstruction (int opCode, const ValueVector& constants)
{
    if (opCode <= 127)
        return disassembly8bitInst(opCode, constants);
    else
        return disassembly16bitInst(opCode, constants);
}

/**
 * Transforms a compiled scirpt into a JSObject.
 * It can be used later from JAvascript code or written to a JSOn file.
 * @param code
 * @return
 */
Ref<JSObject> toJSObject (Ref<MvmRoutine> code)
{
    Ref<JSObject>   obj = JSObject::create();

    obj->writeField ("constants", constantsToJS(code->constants), false);
    obj->writeField ("blocks", blocksToJS(code->blocks, code->constants)->value(), false);

    return obj;
}

/**
 * Generates an human readable representation of a function
 * @param function
 * @return
 */
Ref<JSObject> disassemblyFunction (Ref<JSFunction> function)
{
    Ref<JSObject>   obj = JSObject::create();

    obj->writeField ("header", jsString(function->toString() ), false);
    if (function->isNative())
        obj->writeField("code", jsString("native"), false);
    else
    {
        obj->writeField("code",
                        toJSObject(function->getCodeMVM().staticCast<MvmRoutine>())->value(),
                        false);
    }

    return obj;
}

/**
 * Generates an human readable representation of a closure
 * @param closure
 * @return
 */
Ref<JSObject> disassemblyClosure (Ref<JSClosure> closure)
{
    return disassemblyFunction (closure->getFunction());
}

/**
 * Transforms an actor class into a Javascript object which can be serialized.
 * @param actorClass
 * @return
 */
//Ref<JSObject> disassemblyActorClass (Ref<AsActorClass> actorClass)
//{
//    Ref<JSObject>   obj = JSObject::create();
//
//    obj->writeField ("actorClass", jsString(actorClass->getName()), false );
//
//    auto members = disassemblyMembers(actorClass);
//    obj->writeField ("members", members, false);
//
//    return obj;
//}
//
///**
// * Transforms an input endpoint to a Javascript object representation
// * @param ep
// * @return
// */
//Ref<JSObject> disassemblyInputEndPoint (Ref<AsEndPoint> ep)
//{
//    return disassemblyFunction(ep);
//}
//
///**
// * Transforms an output endpoint to a Javascript object representation
// * @param ep
// * @return
// */
//Ref<JSObject> disassemblyOutputEndPoint (Ref<AsEndPoint> ep)
//{
//    auto result = JSObject::create();
//    result->writeField ("header", jsString(ep->toString() ), false);
//    return result;
//}

/**
 * Disassemblies a class declaration
 * @param cls
 * @return
 */
Ref<JSObject> disassemblyClass (Ref<JSClass> cls)
{
    auto result = JSObject::create();
    result->writeField ("Class", jsString(cls->getName()), false);

    auto    parent = cls->getParent();
    auto    constructor = constantToJS(cls->getConstructor()->value());
    string  parentName;

    if (parent.notNull())
        parentName = parent->getName();

    result->writeField ("Parent", jsString(parentName), false);
    result->writeField("constructor", constructor, false);

    auto members = disassemblyMembers(cls->value());

    result->writeField("members", members->value(), false);

    return result;
}

/**
 * Gets the disassembly representation of the members of a value
 * @param container
 * @return
 */
Ref<JSObject> disassemblyMembers (ASValue container)
{
    auto memberNames = container.getFields(false);
    auto members = JSObject::create();

    for (auto it = memberNames.begin(); it != memberNames.end(); ++it)
    {
        auto member = container.readField(*it);
        members->writeField(*it, constantToJS(member), false);
    }

    return members;
}
<|endoftext|>