/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
 * This file contains the code necessary to fake out the rest
 * of the runtime into thinking that we actually do have primitive
 * classes.
 */
/*
  This file is part of Japhar, the GNU Virtual Machine for Java Bytecodes.
  Japhar is a project of The Hungry Programmers, GNU, and OryxSoft.

  Copyright (C) 1998, 1999 The Hungry Programmers

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Library General Public
  License as published by the Free Software Foundation; either
  version 2 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Library General Public License for more details.

  You should have received a copy of the GNU Library General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "runtimeint.h"
#include "ClazzFile.h"

extern PRLogModuleInfo* primitiveClassLm;

static ClassConstant superclass_constant = {
  CONSTANT_Class,
  2
};

static Utf8Constant object_name_constant = {
  CONSTANT_Utf8,
  sizeof(java_lang_Object)-1, /* strlen(...) */
  NULL
};

PR_IMPLEMENT(ClazzFile*)
HVM_ClassFindPrimitive(HungryEnv *henv, const char *class_name)
{
  ClazzFile *clazz = HVM_ClassFindLoaded(henv, class_name);
  int method_index;

  /* we've already created it. */
  if (clazz)
    return clazz;

  PR_LOG(primitiveClassLm, PR_LOG_DEBUG, ("creating primitive class %s\n",
                                          class_name));

  clazz = PR_CALLOC(sizeof(ClazzFile));

  clazz->access_flags = ACC_PRIMITIVE | ACC_PUBLIC;
  clazz->constant_pool_count = 4;
  clazz->superclass_index = 1;
  clazz->superclass = (ClazzFile*)HVM_ClassFind(henv, java_lang_Object);
  clazz->class_name = PL_strdup(class_name);
  clazz->initialization_state = CLASS_INIT_FINISHED;

  clazz->constants = (ConstantPoolEntry*)PR_Calloc(3, sizeof(ConstantPoolEntry));
  clazz->constants[1].clazz_info = superclass_constant;
  clazz->constants[2].utf8_info = object_name_constant;
  clazz->constants[2].utf8_info.bytes = (PRUint8*)PL_strdup(java_lang_Object);

  clazz->num_fields = 0;
  clazz->num_instance_fields = 0;

  clazz->num_instance_methods = clazz->superclass->num_instance_methods;
  clazz->vmethods = (MethodStruct**)PR_MALLOC(clazz->num_instance_methods
                                           * sizeof(MethodStruct*));
  clazz->smethods = NULL;

  for (method_index = 0;
       method_index < clazz->superclass->num_instance_methods;
       method_index ++)
    {
      clazz->vmethods[ method_index ] = clazz->superclass->vmethods[ method_index ];
    }

  clazz->nesting_level = 1;

  calculate_instance_field_offsets(henv, clazz);

  PR_LOG(primitiveClassLm, PR_LOG_DEBUG,
         ("  adding primitive class to repository\n"));

  add_loaded_class(henv, clazz);

  return clazz;
}
