コード例 #1
0
ファイル: plan9.c プロジェクト: HotHat/chibi-scheme
sexp sexp_exec (sexp ctx, sexp self, sexp_sint_t n, sexp name, sexp args) {
  int i, len = sexp_unbox_fixnum(sexp_length(ctx, args));
  char **argv = malloc((len+1)*sizeof(char*));
  for (i=0; i<len; i++, args=sexp_cdr(args))
    argv[i] = sexp_string_data(sexp_car(args));
  argv[len] = NULL;
  exec(sexp_string_data(name), argv);
  return SEXP_VOID;             /* won't really return */
}
コード例 #2
0
ファイル: pubkey-util.c プロジェクト: cobaugh/rt-rpm
/* Take the hash value and convert into an MPI, suitable for
   passing to the low level functions.  We currently support the
   old style way of passing just a MPI and the modern interface which
   allows to pass flags so that we can choose between raw and pkcs1
   padding - may be more padding options later.

   (<mpi>)
   or
   (data
    [(flags [raw, direct, pkcs1, oaep, pss, no-blinding, rfc6979, eddsa])]
    [(hash <algo> <value>)]
    [(value <text>)]
    [(hash-algo <algo>)]
    [(label <label>)]
    [(salt-length <length>)]
    [(random-override <data>)]
   )

   Either the VALUE or the HASH element must be present for use
   with signatures.  VALUE is used for encryption.

   HASH-ALGO is specific to OAEP and EDDSA.

   LABEL is specific to OAEP.

   SALT-LENGTH is for PSS.

   RANDOM-OVERRIDE is used to replace random nonces for regression
   testing.  */
gcry_err_code_t
_gcry_pk_util_data_to_mpi (gcry_sexp_t input, gcry_mpi_t *ret_mpi,
                           struct pk_encoding_ctx *ctx)
{
  gcry_err_code_t rc = 0;
  gcry_sexp_t ldata, lhash, lvalue;
  size_t n;
  const char *s;
  int unknown_flag = 0;
  int parsed_flags = 0;

  *ret_mpi = NULL;
  ldata = sexp_find_token (input, "data", 0);
  if (!ldata)
    { /* assume old style */
      *ret_mpi = sexp_nth_mpi (input, 0, 0);
      return *ret_mpi ? GPG_ERR_NO_ERROR : GPG_ERR_INV_OBJ;
    }

  /* See whether there is a flags list.  */
  {
    gcry_sexp_t lflags = sexp_find_token (ldata, "flags", 0);
    if (lflags)
      {
        if (_gcry_pk_util_parse_flaglist (lflags,
                                          &parsed_flags, &ctx->encoding))
          unknown_flag = 1;
        sexp_release (lflags);
      }
  }

  if (ctx->encoding == PUBKEY_ENC_UNKNOWN)
    ctx->encoding = PUBKEY_ENC_RAW; /* default to raw */

  /* Get HASH or MPI */
  lhash = sexp_find_token (ldata, "hash", 0);
  lvalue = lhash? NULL : sexp_find_token (ldata, "value", 0);

  if (!(!lhash ^ !lvalue))
    rc = GPG_ERR_INV_OBJ; /* none or both given */
  else if (unknown_flag)
    rc = GPG_ERR_INV_FLAG;
  else if (ctx->encoding == PUBKEY_ENC_RAW
           && (parsed_flags & PUBKEY_FLAG_EDDSA))
    {
      /* Prepare for EdDSA.  */
      gcry_sexp_t list;
      void *value;
      size_t valuelen;

      if (!lvalue)
        {
          rc = GPG_ERR_INV_OBJ;
          goto leave;
        }
      /* Get HASH-ALGO. */
      list = sexp_find_token (ldata, "hash-algo", 0);
      if (list)
        {
          s = sexp_nth_data (list, 1, &n);
          if (!s)
            rc = GPG_ERR_NO_OBJ;
          else
            {
              ctx->hash_algo = get_hash_algo (s, n);
              if (!ctx->hash_algo)
                rc = GPG_ERR_DIGEST_ALGO;
            }
          sexp_release (list);
        }
      else
        rc = GPG_ERR_INV_OBJ;
      if (rc)
        goto leave;

      /* Get VALUE.  */
      value = sexp_nth_buffer (lvalue, 1, &valuelen);
      if (!value)
        {
          /* We assume that a zero length message is meant by
             "(value)".  This is commonly used by test vectors.  Note
             that S-expression do not allow zero length items. */
          valuelen = 0;
          value = xtrymalloc (1);
          if (!value)
            rc = gpg_err_code_from_syserror ();
        }
      else if ((valuelen * 8) < valuelen)
        {
          xfree (value);
          rc = GPG_ERR_TOO_LARGE;
        }
      if (rc)
        goto leave;

      /* Note that mpi_set_opaque takes ownership of VALUE.  */
      *ret_mpi = mpi_set_opaque (NULL, value, valuelen*8);
    }
  else if (ctx->encoding == PUBKEY_ENC_RAW && lhash
           && ((parsed_flags & PUBKEY_FLAG_RAW_FLAG)
               || (parsed_flags & PUBKEY_FLAG_RFC6979)))
    {
      /* Raw encoding along with a hash element.  This is commonly
         used for DSA.  For better backward error compatibility we
         allow this only if either the rfc6979 flag has been given or
         the raw flags was explicitly given.  */
      if (sexp_length (lhash) != 3)
        rc = GPG_ERR_INV_OBJ;
      else if ( !(s=sexp_nth_data (lhash, 1, &n)) || !n )
        rc = GPG_ERR_INV_OBJ;
      else
        {
          void *value;
          size_t valuelen;

	  ctx->hash_algo = get_hash_algo (s, n);
          if (!ctx->hash_algo)
            rc = GPG_ERR_DIGEST_ALGO;
          else if (!(value=sexp_nth_buffer (lhash, 2, &valuelen)))
            rc = GPG_ERR_INV_OBJ;
          else if ((valuelen * 8) < valuelen)
            {
              xfree (value);
              rc = GPG_ERR_TOO_LARGE;
            }
          else
            *ret_mpi = mpi_set_opaque (NULL, value, valuelen*8);
        }
    }
  else if (ctx->encoding == PUBKEY_ENC_RAW && lvalue)
    {
      /* RFC6969 may only be used with the a hash value and not the
         MPI based value.  */
      if (parsed_flags & PUBKEY_FLAG_RFC6979)
        {
          rc = GPG_ERR_CONFLICT;
          goto leave;
        }

      /* Get the value */
      *ret_mpi = sexp_nth_mpi (lvalue, 1, GCRYMPI_FMT_USG);
      if (!*ret_mpi)
        rc = GPG_ERR_INV_OBJ;
    }
  else if (ctx->encoding == PUBKEY_ENC_PKCS1 && lvalue
	   && ctx->op == PUBKEY_OP_ENCRYPT)
    {
      const void * value;
      size_t valuelen;
      gcry_sexp_t list;
      void *random_override = NULL;
      size_t random_override_len = 0;

      if ( !(value=sexp_nth_data (lvalue, 1, &valuelen)) || !valuelen )
        rc = GPG_ERR_INV_OBJ;
      else
        {
          /* Get optional RANDOM-OVERRIDE.  */
          list = sexp_find_token (ldata, "random-override", 0);
          if (list)
            {
              s = sexp_nth_data (list, 1, &n);
              if (!s)
                rc = GPG_ERR_NO_OBJ;
              else if (n > 0)
                {
                  random_override = xtrymalloc (n);
                  if (!random_override)
                    rc = gpg_err_code_from_syserror ();
                  else
                    {
                      memcpy (random_override, s, n);
                      random_override_len = n;
                    }
                }
              sexp_release (list);
              if (rc)
                goto leave;
            }

          rc = _gcry_rsa_pkcs1_encode_for_enc (ret_mpi, ctx->nbits,
                                               value, valuelen,
                                               random_override,
                                               random_override_len);
          xfree (random_override);
        }
    }
  else if (ctx->encoding == PUBKEY_ENC_PKCS1 && lhash
	   && (ctx->op == PUBKEY_OP_SIGN || ctx->op == PUBKEY_OP_VERIFY))
    {
      if (sexp_length (lhash) != 3)
        rc = GPG_ERR_INV_OBJ;
      else if ( !(s=sexp_nth_data (lhash, 1, &n)) || !n )
        rc = GPG_ERR_INV_OBJ;
      else
        {
          const void * value;
          size_t valuelen;

	  ctx->hash_algo = get_hash_algo (s, n);

          if (!ctx->hash_algo)
            rc = GPG_ERR_DIGEST_ALGO;
          else if ( !(value=sexp_nth_data (lhash, 2, &valuelen))
                    || !valuelen )
            rc = GPG_ERR_INV_OBJ;
          else
	    rc = _gcry_rsa_pkcs1_encode_for_sig (ret_mpi, ctx->nbits,
                                                 value, valuelen,
                                                 ctx->hash_algo);
        }
    }
  else if (ctx->encoding == PUBKEY_ENC_OAEP && lvalue
	   && ctx->op == PUBKEY_OP_ENCRYPT)
    {
      const void * value;
      size_t valuelen;

      if ( !(value=sexp_nth_data (lvalue, 1, &valuelen)) || !valuelen )
	rc = GPG_ERR_INV_OBJ;
      else
	{
	  gcry_sexp_t list;
          void *random_override = NULL;
          size_t random_override_len = 0;

	  /* Get HASH-ALGO. */
	  list = sexp_find_token (ldata, "hash-algo", 0);
	  if (list)
	    {
	      s = sexp_nth_data (list, 1, &n);
	      if (!s)
		rc = GPG_ERR_NO_OBJ;
	      else
		{
		  ctx->hash_algo = get_hash_algo (s, n);
		  if (!ctx->hash_algo)
		    rc = GPG_ERR_DIGEST_ALGO;
		}
	      sexp_release (list);
	      if (rc)
		goto leave;
	    }

	  /* Get LABEL. */
	  list = sexp_find_token (ldata, "label", 0);
	  if (list)
	    {
	      s = sexp_nth_data (list, 1, &n);
	      if (!s)
		rc = GPG_ERR_NO_OBJ;
	      else if (n > 0)
		{
		  ctx->label = xtrymalloc (n);
		  if (!ctx->label)
		    rc = gpg_err_code_from_syserror ();
		  else
		    {
		      memcpy (ctx->label, s, n);
		      ctx->labellen = n;
		    }
		}
	      sexp_release (list);
	      if (rc)
		goto leave;
	    }
          /* Get optional RANDOM-OVERRIDE.  */
          list = sexp_find_token (ldata, "random-override", 0);
          if (list)
            {
              s = sexp_nth_data (list, 1, &n);
              if (!s)
                rc = GPG_ERR_NO_OBJ;
              else if (n > 0)
                {
                  random_override = xtrymalloc (n);
                  if (!random_override)
                    rc = gpg_err_code_from_syserror ();
                  else
                    {
                      memcpy (random_override, s, n);
                      random_override_len = n;
                    }
                }
              sexp_release (list);
              if (rc)
                goto leave;
            }

	  rc = _gcry_rsa_oaep_encode (ret_mpi, ctx->nbits, ctx->hash_algo,
                                      value, valuelen,
                                      ctx->label, ctx->labellen,
                                      random_override, random_override_len);

          xfree (random_override);
	}
    }
  else if (ctx->encoding == PUBKEY_ENC_PSS && lhash
	   && ctx->op == PUBKEY_OP_SIGN)
    {
      if (sexp_length (lhash) != 3)
        rc = GPG_ERR_INV_OBJ;
      else if ( !(s=sexp_nth_data (lhash, 1, &n)) || !n )
        rc = GPG_ERR_INV_OBJ;
      else
        {
          const void * value;
          size_t valuelen;
          void *random_override = NULL;
          size_t random_override_len = 0;

	  ctx->hash_algo = get_hash_algo (s, n);

          if (!ctx->hash_algo)
            rc = GPG_ERR_DIGEST_ALGO;
          else if ( !(value=sexp_nth_data (lhash, 2, &valuelen))
                    || !valuelen )
            rc = GPG_ERR_INV_OBJ;
          else
	    {
	      gcry_sexp_t list;

	      /* Get SALT-LENGTH. */
	      list = sexp_find_token (ldata, "salt-length", 0);
	      if (list)
		{
		  s = sexp_nth_data (list, 1, &n);
		  if (!s)
		    {
		      rc = GPG_ERR_NO_OBJ;
		      goto leave;
		    }
		  ctx->saltlen = (unsigned int)strtoul (s, NULL, 10);
		  sexp_release (list);
		}

              /* Get optional RANDOM-OVERRIDE.  */
              list = sexp_find_token (ldata, "random-override", 0);
              if (list)
                {
                  s = sexp_nth_data (list, 1, &n);
                  if (!s)
                    rc = GPG_ERR_NO_OBJ;
                  else if (n > 0)
                    {
                      random_override = xtrymalloc (n);
                      if (!random_override)
                        rc = gpg_err_code_from_syserror ();
                      else
                        {
                          memcpy (random_override, s, n);
                          random_override_len = n;
                        }
                    }
                  sexp_release (list);
                  if (rc)
                    goto leave;
                }

              /* Encode the data.  (NBITS-1 is due to 8.1.1, step 1.) */
	      rc = _gcry_rsa_pss_encode (ret_mpi, ctx->nbits - 1,
                                         ctx->hash_algo,
                                         value, valuelen, ctx->saltlen,
                                         random_override, random_override_len);

              xfree (random_override);
	    }
        }
    }
  else if (ctx->encoding == PUBKEY_ENC_PSS && lhash
	   && ctx->op == PUBKEY_OP_VERIFY)
    {
      if (sexp_length (lhash) != 3)
        rc = GPG_ERR_INV_OBJ;
      else if ( !(s=sexp_nth_data (lhash, 1, &n)) || !n )
        rc = GPG_ERR_INV_OBJ;
      else
        {
	  ctx->hash_algo = get_hash_algo (s, n);

          if (!ctx->hash_algo)
            rc = GPG_ERR_DIGEST_ALGO;
	  else
	    {
	      *ret_mpi = sexp_nth_mpi (lhash, 2, GCRYMPI_FMT_USG);
	      if (!*ret_mpi)
		rc = GPG_ERR_INV_OBJ;
	      ctx->verify_cmp = pss_verify_cmp;
	      ctx->verify_arg = *ret_mpi;
	    }
	}
    }
  else
    rc = GPG_ERR_CONFLICT;

 leave:
  sexp_release (ldata);
  sexp_release (lhash);
  sexp_release (lvalue);

  if (!rc)
    ctx->flags = parsed_flags;
  else
    {
      xfree (ctx->label);
      ctx->label = NULL;
    }

  return rc;
}
コード例 #3
0
ファイル: pubkey-util.c プロジェクト: cobaugh/rt-rpm
/* Parser for a flag list.  On return the encoding is stored at
   R_ENCODING and the flags are stored at R_FLAGS.  If any of them is
   not needed, NULL may be passed.  The function returns 0 on success
   or an error code. */
gpg_err_code_t
_gcry_pk_util_parse_flaglist (gcry_sexp_t list,
                              int *r_flags, enum pk_encoding *r_encoding)
{
  gpg_err_code_t rc = 0;
  const char *s;
  size_t n;
  int i;
  int encoding = PUBKEY_ENC_UNKNOWN;
  int flags = 0;
  int igninvflag = 0;

  for (i = list ? sexp_length (list)-1 : 0; i > 0; i--)
    {
      s = sexp_nth_data (list, i, &n);
      if (!s)
        continue; /* Not a data element. */

      switch (n)
        {
        case 3:
          if (!memcmp (s, "pss", 3) && encoding == PUBKEY_ENC_UNKNOWN)
            {
              encoding = PUBKEY_ENC_PSS;
              flags |= PUBKEY_FLAG_FIXEDLEN;
            }
          else if (!memcmp (s, "raw", 3) && encoding == PUBKEY_ENC_UNKNOWN)
            {
              encoding = PUBKEY_ENC_RAW;
              flags |= PUBKEY_FLAG_RAW_FLAG; /* Explicitly given.  */
            }
          else if (!igninvflag)
            rc = GPG_ERR_INV_FLAG;
          break;

        case 4:
          if (!memcmp (s, "comp", 4))
            flags |= PUBKEY_FLAG_COMP;
          else if (!memcmp (s, "oaep", 4) && encoding == PUBKEY_ENC_UNKNOWN)
            {
              encoding = PUBKEY_ENC_OAEP;
              flags |= PUBKEY_FLAG_FIXEDLEN;
            }
          else if (!memcmp (s, "gost", 4))
            {
              encoding = PUBKEY_ENC_RAW;
              flags |= PUBKEY_FLAG_GOST;
            }
          else if (!igninvflag)
            rc = GPG_ERR_INV_FLAG;
          break;

        case 5:
          if (!memcmp (s, "eddsa", 5))
            {
              encoding = PUBKEY_ENC_RAW;
              flags |= PUBKEY_FLAG_EDDSA;
            }
          else if (!memcmp (s, "pkcs1", 5) && encoding == PUBKEY_ENC_UNKNOWN)
            {
              encoding = PUBKEY_ENC_PKCS1;
              flags |= PUBKEY_FLAG_FIXEDLEN;
            }
          else if (!memcmp (s, "param", 5))
            flags |= PUBKEY_FLAG_PARAM;
          else if (!igninvflag)
            rc = GPG_ERR_INV_FLAG;
          break;

        case 6:
          if (!memcmp (s, "nocomp", 6))
            flags |= PUBKEY_FLAG_NOCOMP;
          else if (!igninvflag)
            rc = GPG_ERR_INV_FLAG;
          break;

        case 7:
          if (!memcmp (s, "rfc6979", 7))
            flags |= PUBKEY_FLAG_RFC6979;
          else if (!memcmp (s, "noparam", 7))
            ; /* Ignore - it is the default.  */
          else if (!igninvflag)
            rc = GPG_ERR_INV_FLAG;
          break;

        case 8:
          if (!memcmp (s, "use-x931", 8))
            flags |= PUBKEY_FLAG_USE_X931;
          else if (!igninvflag)
            rc = GPG_ERR_INV_FLAG;
          break;

        case 10:
          if (!memcmp (s, "igninvflag", 10))
            igninvflag = 1;
          else if (!memcmp (s, "no-keytest", 10))
            flags |= PUBKEY_FLAG_NO_KEYTEST;
          /* In 1.7.0 we will return an INV_FLAG on error but we
             do not fix that bug here in 1.6.4  */
          break;

        case 11:
          if (!memcmp (s, "no-blinding", 11))
            flags |= PUBKEY_FLAG_NO_BLINDING;
          else if (!memcmp (s, "use-fips186", 11))
            flags |= PUBKEY_FLAG_USE_FIPS186;
          else if (!igninvflag)
            rc = GPG_ERR_INV_FLAG;
          break;

        case 13:
          if (!memcmp (s, "use-fips186-2", 13))
            flags |= PUBKEY_FLAG_USE_FIPS186_2;
          else if (!memcmp (s, "transient-key", 13))
            flags |= PUBKEY_FLAG_TRANSIENT_KEY;
          else if (!igninvflag)
            rc = GPG_ERR_INV_FLAG;
          break;

        default:
          if (!igninvflag)
            rc = GPG_ERR_INV_FLAG;
          break;
        }
    }

  if (r_flags)
    *r_flags = flags;
  if (r_encoding)
    *r_encoding = encoding;

  return rc;
}
コード例 #4
0
ファイル: dalvik_method.c プロジェクト: Feng23/adam
dalvik_method_t* dalvik_method_from_sexp(const sexpression_t* sexp, const char* class_path,const char* file)
{

#ifdef PARSER_COUNT
    dalvik_method_count ++;
#endif

    dalvik_method_t* method = NULL;

    if(SEXP_NIL == sexp) return NULL;
    
    if(NULL == class_path) class_path = "(undefined)";
    if(NULL == file) file = "(undefined)";

    const char* name;
    sexpression_t *attrs, *arglist, *ret, *body;
    /* matches (method (attribute-list) method-name (arg-list) return-type body) */
    if(!sexp_match(sexp, "(L=C?L?C?_?A", DALVIK_TOKEN_METHOD, &attrs, &name, &arglist, &ret, &body))
    {
        LOG_ERROR("bad method defination"); 
        return NULL;
    }

    /* get attributes */
    int attrnum;
    if((attrnum = dalvik_attrs_from_sexp(attrs)) < 0)
    {
        LOG_ERROR("can not parse attributes");
        return NULL;
    }

    /* get number of arguments */
    int num_args;
    num_args = sexp_length(arglist);

    /* Now we know the size we have to allocate for this method */
    method = (dalvik_method_t*)malloc(sizeof(dalvik_method_t) + sizeof(dalvik_type_t*) * (num_args + 1));
    if(NULL == method) 
    {
        LOG_ERROR("can not allocate memory for method argument list");
        return NULL;
    }
    memset(method->args_type, 0, sizeof(dalvik_type_t*) * (num_args + 1));

    method->num_args = num_args;
    method->path = class_path;
    method->file = file;
    method->name = name;

    /* Setup the type of argument list */
    int i;
    for(i = 0;arglist != SEXP_NIL && i < num_args; i ++)
    {
        sexpression_t *this_arg;
        if(!sexp_match(arglist, "(_?A", &this_arg, &arglist))
        {
            LOG_ERROR("invalid argument list");
            goto ERR;
        }
        if(NULL == (method->args_type[i] = dalvik_type_from_sexp(this_arg)))
        {
            LOG_ERROR("invalid argument type @ #%d", i);
            goto ERR;
        }
    }

    /* Setup the return type */
    if(NULL == (method->return_type = dalvik_type_from_sexp(ret)))
    {
        LOG_ERROR("invalid return type");
        goto ERR;
    }

    /* Now fetch the body */
    
    //TODO: process other parts of a method
    int current_line_number = 0;    /* Current Line Number */
    uint32_t last = DALVIK_INSTRUCTION_INVALID;
    //int last_label = -1;
    int label_stack[DALVIK_METHOD_LABEL_STACK_SIZE];  /* how many label can one isntruction assign to */
    int label_sp;
    int from_label[DALVIK_MAX_CATCH_BLOCK];    /* NOTICE: the maximum number of catch block is limited to this constant */
    int to_label  [DALVIK_MAX_CATCH_BLOCK];
    int label_st  [DALVIK_MAX_CATCH_BLOCK];    /* 0: haven't seen any label related to the label. 
                                                * 1: seen from label before
                                                * 2: seen from and to label
                                                */
    label_sp  = 0;
    dalvik_exception_handler_t* excepthandler[DALVIK_MAX_CATCH_BLOCK] = {};
    dalvik_exception_handler_set_t* current_ehset = NULL;
    int number_of_exception_handler = 0;
    for(;body != SEXP_NIL;)
    {
        sexpression_t *this_smt;
        if(!sexp_match(body, "(C?A", &this_smt, &body))
        {
            LOG_ERROR("invalid method body");
            goto ERR;
        }
        /* First check if the statement is a psuedo-instruction */
        const char* arg;
#if LOG_LEVEL >= 6
        char buf[40906];
        static int counter = 0;
#endif
        LOG_DEBUG("#%d current instruction : %s",(++counter) ,sexp_to_string(this_smt, buf) );
        if(sexp_match(this_smt, "(L=L=L?", DALVIK_TOKEN_LIMIT, DALVIK_TOKEN_REGISTERS, &arg))
        {
            /* (limit-registers k) */
            method->num_regs = atoi(arg);
            LOG_DEBUG("uses %d registers", method->num_regs);
        }
        else if(sexp_match(this_smt, "(L=L?", DALVIK_TOKEN_LINE, &arg))
        {
            /* (line arg) */
            current_line_number = atoi(arg);
        }
        else if(sexp_match(this_smt, "(L=L?", DALVIK_TOKEN_LABEL, &arg))
        {
            /* (label arg) */
            int lid = dalvik_label_get_label_id(arg);
            int i;
            if(lid == -1) 
            {
                LOG_ERROR("can not create label for %s", arg);
                goto ERR;
            }
            //last_label = lid;
            if(label_sp < DALVIK_METHOD_LABEL_STACK_SIZE)
                label_stack[label_sp++] = lid;
            else
                LOG_WARNING("label stack overflow, might loss some label here");
            int enbaled_count = 0;
            dalvik_exception_handler_t* exceptionset[DALVIK_MAX_CATCH_BLOCK];
            for(i = 0; i < number_of_exception_handler; i ++)
            {
                if(lid == from_label[i] && label_st[i] == 0)
                    label_st[i] = 1;
                else if(lid == to_label[i] && label_st[i] == 1)
                    label_st[i] = 2;
                else if(lid == from_label[i] && label_st[i] != 0)
                    LOG_WARNING("meet from label twice, it might be a mistake");
                else if(lid == to_label[i] && label_st[i] != 1)
                    LOG_WARNING("to label is before from label, it might be a mistake");
                
                if(label_st[i] == 1)
                    exceptionset[enbaled_count++] = excepthandler[i];
            }
            current_ehset = dalvik_exception_new_handler_set(enbaled_count, exceptionset);
        }
        else if(sexp_match(this_smt, "(L=A", DALVIK_TOKEN_ANNOTATION, &arg))
        {
            /* Simplely ignore */
            LOG_INFO("fixme: ignored psuedo-insturction (annotation)");
        }
        else if(sexp_match(this_smt, "(L=L=A", DALVIK_TOKEN_DATA, DALVIK_TOKEN_ARRAY, &arg))
        {
            /* TODO: what is (data-array ....)statement currently ignored */
            LOG_INFO("fixme: (data-array) psuedo-insturction is to be implemented");
        }
        else if(sexp_match(this_smt, "(L=A", DALVIK_TOKEN_CATCH, &arg) || 
                sexp_match(this_smt, "(L=A", DALVIK_TOKEN_CATCHALL, &arg))
        {
            excepthandler[number_of_exception_handler] = 
                dalvik_exception_handler_from_sexp(
                        this_smt, 
                        from_label + number_of_exception_handler, 
                        to_label + number_of_exception_handler);
            if(excepthandler[number_of_exception_handler] == NULL)
            {
                LOG_WARNING("invalid exception handler %s", sexp_to_string(this_smt, NULL));
                continue;
            }
            LOG_DEBUG("exception %s is handlered in label #%d", 
                      excepthandler[number_of_exception_handler]->exception, 
                      excepthandler[number_of_exception_handler]->handler_label);
            //label_st[number_of_exception_handler] = 0;   /* TODO: verify this is a bug */
            number_of_exception_handler ++;
        }
        else if(sexp_match(this_smt, "(L=A", DALVIK_TOKEN_FILL, &arg))
        {
            //TODO: fill-array-data psuedo-instruction
            LOG_INFO("fixme: (fill-array-data) is to be implemented");
        }
        else
        {
            dalvik_instruction_t* inst = dalvik_instruction_new();
            if(NULL == inst) 
            {
                LOG_ERROR("can not create new instruction");
                goto ERR;
            }
            if(dalvik_instruction_from_sexp(this_smt, inst, current_line_number) < 0)
            {
                LOG_ERROR("can not recognize instuction %s", sexp_to_string(this_smt, NULL));
                goto ERR;
            }
            if(DALVIK_INSTRUCTION_INVALID == last) 
                method->entry = dalvik_instruction_get_index(inst);
            else
                dalvik_instruction_set_next(last, inst);
            last = dalvik_instruction_get_index(inst);
            inst->handler_set = current_ehset; 
            if(label_sp > 0)
            {
                int i;
                for(i = 0; i < label_sp; i++)
                {
                    LOG_DEBUG("assigned instruction@%p to label #%d", inst, label_stack[i]);
                    dalvik_label_jump_table[label_stack[i]] = dalvik_instruction_get_index(inst);
                }
                label_sp = 0;
            }
        }
    }
    return method;
ERR:
    dalvik_method_free(method);
    return NULL;
}
コード例 #5
0
ファイル: ast.c プロジェクト: okuoku/chibi-scheme-old
static sexp sexp_type_num_slots_op (sexp ctx, sexp self, sexp_sint_t n, sexp t) {
  sexp_assert_type(ctx, sexp_typep, SEXP_TYPE, t);
  return sexp_truep(sexp_type_slots(t)) ? sexp_length(ctx, sexp_type_slots(t))
    : sexp_make_fixnum(sexp_type_field_eq_len_base(t));
}
コード例 #6
0
ファイル: simplify.c プロジェクト: bnoordhuis/suv
static sexp simplify (sexp ctx, sexp ast, sexp init_substs, sexp lambda) {
  int check;
  sexp ls1, ls2, p1, p2, sv;
  sexp_gc_var5(res, substs, tmp, app, ctx2);
  sexp_gc_preserve5(ctx, res, substs, tmp, app, ctx2);
  res = ast;                    /* return the ast as-is by default */
  substs = init_substs;

 loop:
  switch (sexp_pointerp(res) ? sexp_pointer_tag(res) : 0) {

  case SEXP_PAIR:
    /* don't simplify the operator if it's a lambda because we
       simplify that as a special case below, with the appropriate
       substs list */
    app = sexp_list1(ctx, sexp_lambdap(sexp_car(res)) ? sexp_car(res)
                     : (tmp=simplify(ctx, sexp_car(res), substs, lambda)));
    sexp_pair_source(app) = sexp_pair_source(res);
    for (ls1=sexp_cdr(res); sexp_pairp(ls1); ls1=sexp_cdr(ls1)) {
      sexp_push(ctx, app, tmp=simplify(ctx, sexp_car(ls1), substs, lambda));
      if (sexp_pairp(app)) sexp_pair_source(app) = sexp_pair_source(ls1);
    }
    app = sexp_nreverse(ctx, app);
    /* app now holds a copy of the list, and is the default result
       (res = app below) if we don't replace it with a simplification */
    if (sexp_opcodep(sexp_car(app))) {
      /* opcode app - right now we just constant fold arithmetic */
      if (sexp_opcode_class(sexp_car(app)) == SEXP_OPC_ARITHMETIC) {
        for (check=1, ls1=sexp_cdr(app); sexp_pairp(ls1); ls1=sexp_cdr(ls1)) {
          if (sexp_pointerp(sexp_car(ls1)) && ! sexp_litp(sexp_car(ls1))) {
            check = 0;
            break;
          }
        }
        if (check) {
          ctx2 = sexp_make_eval_context(ctx, NULL, sexp_context_env(ctx), 0, 0);
          sexp_generate(ctx2, 0, 0, 0, app);
          res = sexp_complete_bytecode(ctx2);
          if (! sexp_exceptionp(res)) {
            tmp = sexp_make_vector(ctx2, 0, SEXP_VOID);
            tmp = sexp_make_procedure(ctx2, SEXP_ZERO, SEXP_ZERO, res, tmp);
            if (! sexp_exceptionp(tmp)) {
              tmp = sexp_apply(ctx2, tmp, SEXP_NULL);
              if (! sexp_exceptionp(tmp))
                app = sexp_make_lit(ctx2, tmp);
            }
          }
        }
      }
    } else if (lambda && sexp_lambdap(sexp_car(app))) { /* let */
      p1 = NULL;
      p2 = sexp_lambda_params(sexp_car(app));
      ls1 = app;
      ls2 = sexp_cdr(app);
      sv = sexp_lambda_sv(sexp_car(app));
      if (sexp_length(ctx, p2) == sexp_length(ctx, ls2)) {
        for ( ; sexp_pairp(ls2); ls2=sexp_cdr(ls2), p2=sexp_cdr(p2)) {
          if (sexp_not(sexp_memq(ctx, sexp_car(p2), sv))
              && (! sexp_pointerp(sexp_car(ls2)) || sexp_litp(sexp_car(ls2))
                  || (sexp_refp(sexp_car(ls2))
                      && sexp_lambdap(sexp_ref_loc(sexp_car(ls2)))
                      && sexp_not(sexp_memq(ctx, sexp_ref_name(sexp_car(ls2)),
                                            sexp_lambda_sv(sexp_ref_loc(sexp_car(ls2)))))))) {
            tmp = sexp_cons(ctx, sexp_car(app), sexp_car(ls2));
            tmp = sexp_cons(ctx, sexp_car(p2), tmp);
            sexp_push(ctx, substs, tmp);
            sexp_cdr(ls1) = sexp_cdr(ls2);
            if (p1)
              sexp_cdr(p1) = sexp_cdr(p2);
            else
              sexp_lambda_params(sexp_car(app)) = sexp_cdr(p2);
          } else {
            p1 = p2;
            ls1 = ls2;
          }
        }
        sexp_lambda_body(sexp_car(app))
          = simplify(ctx, sexp_lambda_body(sexp_car(app)), substs, sexp_car(app));
        if (sexp_nullp(sexp_cdr(app))
            && sexp_nullp(sexp_lambda_params(sexp_car(app)))
            && sexp_nullp(sexp_lambda_defs(sexp_car(app))))
          app = sexp_lambda_body(sexp_car(app));
      }
    }
    res = app;
    break;

  case SEXP_LAMBDA:
    sexp_lambda_body(res) = simplify(ctx, sexp_lambda_body(res), substs, res);
    break;

  case SEXP_CND:
    tmp = simplify(ctx, sexp_cnd_test(res), substs, lambda);
    if (sexp_litp(tmp) || ! sexp_pointerp(tmp)) {
      res = sexp_not((sexp_litp(tmp) ? sexp_lit_value(tmp) : tmp))
        ? sexp_cnd_fail(res) : sexp_cnd_pass(res);
      goto loop;
    } else {
      sexp_cnd_test(res) = tmp;
      simplify_it(sexp_cnd_pass(res));
      simplify_it(sexp_cnd_fail(res));
    }
    break;

  case SEXP_REF:
    tmp = sexp_ref_name(res);
    for (ls1=substs; sexp_pairp(ls1); ls1=sexp_cdr(ls1))
      if ((sexp_caar(ls1) == tmp) && (sexp_cadar(ls1) == sexp_ref_loc(res))) {
        res = sexp_cddar(ls1);
        break;
      }
    break;

  case SEXP_SET:
    simplify_it(sexp_set_value(res));
    break;

  case SEXP_SEQ:
    app = SEXP_NULL;
    for (ls2=sexp_seq_ls(res); sexp_pairp(ls2); ls2=sexp_cdr(ls2)) {
      tmp = simplify(ctx, sexp_car(ls2), substs, lambda);
      if (! (sexp_pairp(sexp_cdr(ls2))
             && (sexp_litp(tmp) || ! sexp_pointerp(tmp) || sexp_refp(tmp)
                 || sexp_lambdap(tmp))))
        sexp_push(ctx, app, tmp);
    }
    if (sexp_pairp(app) && sexp_nullp(sexp_cdr(app)))
      res = sexp_car(app);
    else
      sexp_seq_ls(res) = sexp_nreverse(ctx, app);
    break;

  }

  sexp_gc_release5(ctx);
  return res;
}