/* -----------------------------------------------------------------------------
 * This file is part of SWIG, which is licensed as a whole under version 3
 * (or any later version) of the GNU General Public License. Some additional
 * terms also apply to certain portions of SWIG. The full details of the SWIG
 * license and copyrights can be found in the LICENSE and COPYRIGHT files
 * included with the SWIG source code as distributed by the SWIG developers
 * and at http://www.swig.org/legal.html.
 *
 * javascript.cxx
 *
 * Javascript language module for SWIG.
 * ----------------------------------------------------------------------------- */

#include "swigmod.h"
#include "cparse.h"

/**
 * Enables extra debugging information in typemaps.
 */
static bool js_template_enable_debug = false;

#define ERR_MSG_ONLY_ONE_ENGINE_PLEASE "Only one engine can be specified at a time."

// keywords used for state variables
#define NAME "name"
#define NAME_MANGLED "name_mangled"
#define TYPE "type"
#define TYPE_MANGLED "type_mangled"
#define WRAPPER_NAME "wrapper"
#define IS_IMMUTABLE "is_immutable"
#define IS_STATIC "is_static"
#define IS_ABSTRACT "is_abstract"
#define GETTER "getter"
#define SETTER "setter"
#define PARENT "parent"
#define PARENT_MANGLED "parent_mangled"
#define CTOR "ctor"
#define CTOR_WRAPPERS "ctor_wrappers"
#define CTOR_DISPATCHERS "ctor_dispatchers"
#define DTOR "dtor"
#define ARGCOUNT "wrap:argc"
#define HAS_TEMPLATES "has_templates"
#define FORCE_CPP "force_cpp"
#define RESET true

// keys for global state variables
#define CREATE_NAMESPACES "create_namespaces"
#define REGISTER_NAMESPACES "register_namespaces"
#define INITIALIZER "initializer"

// keys for class scoped state variables
#define MEMBER_VARIABLES "member_variables"
#define MEMBER_FUNCTIONS "member_functions"
#define STATIC_FUNCTIONS "static_functions"
#define STATIC_VARIABLES "static_variables"


/**
 * A convenience class to manage state variables for emitters.
 * The implementation delegates to SWIG Hash DOHs and provides
 * named sub-hashes for class, variable, and function states.
 */
class JSEmitterState {

public:
  JSEmitterState();
  ~JSEmitterState();
  DOH *globals();
  DOH *globals(const char *key, DOH *initial = 0);
  DOH *clazz(bool reset = false);
  DOH *clazz(const char *key, DOH *initial = 0);
  DOH *function(bool reset = false);
  DOH *function(const char *key, DOH *initial = 0);
  DOH *variable(bool reset = false);
  DOH *variable(const char *key, DOH *initial = 0);
  static int IsSet(DOH *val);

private:
  DOH *getState(const char *key, bool reset = false);
  Hash *globalHash;
};

/**
 * A convenience class that wraps a code snippet used as template
 * for code generation.
 */
class Template {

public:
  Template(const String *code);
  Template(const String *code, const String *templateName);
  Template(const Template & other);
  ~Template();
  String *str();
  Template & replace(const String *pattern, const String *repl);
  Template & print(DOH *doh);
  Template & pretty_print(DOH *doh);
  void operator=(const Template & t);
  Template & trim();

private:
  String *code;
  String *templateName;
};

/**
 * JSEmitter represents an abstraction of javascript code generators
 * for different javascript engines.
 **/
class JSEmitter {

protected:

  typedef JSEmitterState State;

  enum MarshallingMode {
    Setter,
    Getter,
    Ctor,
    Function
  };

public:

   enum JSEngine {
     JavascriptCore,
     V8,
     NodeJS
   };

   JSEmitter(JSEngine engine);

   virtual ~ JSEmitter();

  /**
   * Opens output files and temporary output DOHs.
   */
  virtual int initialize(Node *n);

  /**
   * Writes all collected code into the output file(s).
   */
  virtual int dump(Node *n) = 0;

  /**
   * Cleans up all open output DOHs.
   */
  virtual int close() = 0;

  /**
   * Switches the context for code generation.
   *
   * Classes, global variables and global functions may need to
   * be registered in certain static tables.
   * This method should be used to switch output DOHs correspondingly.
   */
  virtual int switchNamespace(Node *);

  /**
   * Invoked at the beginning of the classHandler.
   */
  virtual int enterClass(Node *);

  /**
   * Invoked at the end of the classHandler.
   */
  virtual int exitClass(Node *) {
    return SWIG_OK;
  };

  /**
   * Invoked at the beginning of the variableHandler.
   */
  virtual int enterVariable(Node *);

  /**
   * Invoked at the end of the variableHandler.
   */
  virtual int exitVariable(Node *) {
    return SWIG_OK;
  };

  /**
   * Invoked at the beginning of the functionHandler.
   */
  virtual int enterFunction(Node *);

  /**
   * Invoked at the end of the functionHandler.
   */
  virtual int exitFunction(Node *) {
    return SWIG_OK;
  };

  /**
   * Invoked by functionWrapper callback after call to Language::functionWrapper.
   */
  virtual int emitWrapperFunction(Node *n);

  /**
   * Invoked by nativeWrapper callback
   */
  virtual int emitNativeFunction(Node *n);

  /**
   * Invoked from constantWrapper after call to Language::constantWrapper.
   **/
  virtual int emitConstant(Node *n);

  /**
   * Registers a given code snippet for a given key name.
   *
   * This method is called by the fragmentDirective handler
   * of the JAVASCRIPT language module.
   **/
  int registerTemplate(const String *name, const String *code);

  /**
   * Retrieve the code template registered for a given name.
   */
  Template getTemplate(const String *name);

  State & getState();

protected:

  /**
   * Generates code for a constructor function.
   */
  virtual int emitCtor(Node *n);

  /**
   * Generates code for a destructor function.
   */
  virtual int emitDtor(Node *n);

  /**
   * Generates code for a function.
   */
  virtual int emitFunction(Node *n, bool is_member, bool is_static);

  virtual int emitFunctionDispatcher(Node *n, bool /*is_member */ );

  /**
   * Generates code for a getter function.
   */
  virtual int emitGetter(Node *n, bool is_member, bool is_static);

  /**
   * Generates code for a setter function.
   */
  virtual int emitSetter(Node *n, bool is_member, bool is_static);

  virtual void marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, MarshallingMode mode, bool is_member, bool is_static) = 0;

  virtual String *emitInputTypemap(Node *n, Parm *params, Wrapper *wrapper, String *arg);

  virtual void marshalOutput(Node *n, ParmList *params, Wrapper *wrapper, String *actioncode, const String *cresult = 0, bool emitReturnVariable = true);

  virtual void emitCleanupCode(Node *n, Wrapper *wrapper, ParmList *params);

  /**
   * Helper function to retrieve the first parent class node.
   */
  Node *getBaseClass(Node *n);

  Parm *skipIgnoredArgs(Parm *p);

  virtual int createNamespace(String *scope);

  virtual Hash *createNamespaceEntry(const char *name, const char *parent, const char *parent_mangled);

  virtual int emitNamespaces() = 0;


protected:

  JSEngine engine;
  Hash *templates;
  State state;

  // contains context specific data (DOHs)
  // to allow generation of namespace related code
  // which are switched on namespace change
  Hash *namespaces;
  Hash *current_namespace;
  String *defaultResultName;
  File *f_wrappers;
};

/* factory methods for concrete JSEmitters: */

JSEmitter *swig_javascript_create_JSCEmitter();
JSEmitter *swig_javascript_create_V8Emitter();
JSEmitter *swig_javascript_create_NodeJSEmitter();

/**********************************************************************
 * JAVASCRIPT: SWIG module implementation
 **********************************************************************/

class JAVASCRIPT:public Language {

public:

  JAVASCRIPT():emitter(NULL) {
  }
  ~JAVASCRIPT() {
    delete emitter;
  }

  virtual int functionHandler(Node *n);
  virtual int globalfunctionHandler(Node *n);
  virtual int variableHandler(Node *n);
  virtual int globalvariableHandler(Node *n);
  virtual int staticmemberfunctionHandler(Node *n);
  virtual int classHandler(Node *n);
  virtual int functionWrapper(Node *n);
  virtual int constantWrapper(Node *n);
  virtual int nativeWrapper(Node *n);
  virtual void main(int argc, char *argv[]);
  virtual int top(Node *n);

  /**
   *  Registers all %fragments assigned to section "templates".
   **/
  virtual int fragmentDirective(Node *n);

public:

  virtual String *getNSpace() const;

private:

  JSEmitter *emitter;
};

/* ---------------------------------------------------------------------
 * functionWrapper()
 *
 * Low level code generator for functions
 * --------------------------------------------------------------------- */

int JAVASCRIPT::functionWrapper(Node *n) {

  // note: the default implementation only prints a message
  // Language::functionWrapper(n);
  emitter->emitWrapperFunction(n);

  return SWIG_OK;
}

/* ---------------------------------------------------------------------
 * functionHandler()
 *
 * Function handler for generating wrappers for functions
 * --------------------------------------------------------------------- */
int JAVASCRIPT::functionHandler(Node *n) {

  if (GetFlag(n, "isextension") == 1) {
    SetFlag(n, "ismember");
  }

  emitter->enterFunction(n);
  Language::functionHandler(n);
  emitter->exitFunction(n);

  return SWIG_OK;
}

/* ---------------------------------------------------------------------
 * globalfunctionHandler()
 *
 * Function handler for generating wrappers for functions
 * --------------------------------------------------------------------- */

int JAVASCRIPT::globalfunctionHandler(Node *n) {
  emitter->switchNamespace(n);
  Language::globalfunctionHandler(n);

  return SWIG_OK;
}

/* ---------------------------------------------------------------------
 * staticmemberfunctionHandler()
 *
 * Function handler for generating wrappers for static member functions
 * --------------------------------------------------------------------- */

int JAVASCRIPT::staticmemberfunctionHandler(Node *n) {
  /*
   *  Note: storage=static is removed by Language::staticmemberfunctionHandler.
   *    So, don't rely on that after here. Instead use the state variable which is
   *    set by JSEmitter::enterFunction().
   */
  Language::staticmemberfunctionHandler(n);
  return SWIG_OK;
}

/* ---------------------------------------------------------------------
 * variableHandler()
 *
 * Function handler for generating wrappers for variables
 * --------------------------------------------------------------------- */

int JAVASCRIPT::variableHandler(Node *n) {

  emitter->enterVariable(n);
  Language::variableHandler(n);
  emitter->exitVariable(n);

  return SWIG_OK;
}

/* ---------------------------------------------------------------------
 * globalvariableHandler()
 *
 * Function handler for generating wrappers for global variables
 * --------------------------------------------------------------------- */

int JAVASCRIPT::globalvariableHandler(Node *n) {
  emitter->switchNamespace(n);
  Language::globalvariableHandler(n);

  return SWIG_OK;
}

/* ---------------------------------------------------------------------
 * constantHandler()
 *
 * Function handler for generating wrappers for constants
 * --------------------------------------------------------------------- */

int JAVASCRIPT::constantWrapper(Node *n) {
  emitter->switchNamespace(n);

  // Note: callbacks trigger this wrapper handler
  // TODO: handle callback declarations
  if (Equal(Getattr(n, "kind"), "function")) {
    return SWIG_OK;
  }
  // TODO: the emitter for constants must be implemented in a cleaner way
  // currently we treat it like a read-only variable
  // however, there is a remaining bug with function pointer constants
  // which could be fixed with a cleaner approach
  emitter->emitConstant(n);

  return SWIG_OK;
}

/* ---------------------------------------------------------------------
 * nativeWrapper()
 *
 * Function wrapper for generating placeholders for native functions
 * --------------------------------------------------------------------- */

int JAVASCRIPT::nativeWrapper(Node *n) {
  emitter->emitNativeFunction(n);

  return SWIG_OK;
}

/* ---------------------------------------------------------------------
 * classHandler()
 *
 * Function handler for generating wrappers for class
 * --------------------------------------------------------------------- */

int JAVASCRIPT::classHandler(Node *n) {
  emitter->switchNamespace(n);

  emitter->enterClass(n);
  Language::classHandler(n);
  emitter->exitClass(n);

  return SWIG_OK;
}

int JAVASCRIPT::fragmentDirective(Node *n) {

  // catch all fragment directives that have "templates" as location
  // and register them at the emitter.
  String *section = Getattr(n, "section");

  if (Equal(section, "templates") && !ImportMode) {
    emitter->registerTemplate(Getattr(n, "value"), Getattr(n, "code"));
  } else {
    return Language::fragmentDirective(n);
  }

  return SWIG_OK;
}

String *JAVASCRIPT::getNSpace() const {
  return Language::getNSpace();
}

/* ---------------------------------------------------------------------
 * top()
 *
 * Function handler for processing top node of the parse tree
 * Wrapper code generation essentially starts from here
 * --------------------------------------------------------------------- */

int JAVASCRIPT::top(Node *n) {
  emitter->initialize(n);

  Language::top(n);

  emitter->dump(n);
  emitter->close();

  return SWIG_OK;
}

static const char *usage = (char *) "\
Javascript Options (available with -javascript)\n\
     -jsc                   - creates a JavascriptCore extension \n\
     -v8                    - creates a v8 extension \n\
     -node                  - creates a node.js extension \n\
     -debug-codetemplates   - generates information about the origin of code templates\n";


/* ---------------------------------------------------------------------
 * main()
 *
 * Entry point for the JAVASCRIPT module
 * --------------------------------------------------------------------- */

void JAVASCRIPT::main(int argc, char *argv[]) {
  // Set javascript subdirectory in SWIG library
  SWIG_library_directory("javascript");

  int engine = -1;

  for (int i = 1; i < argc; i++) {
    if (argv[i]) {
      if (strcmp(argv[i], "-v8") == 0) {
      	if (engine != -1) {
	  Printf(stderr, ERR_MSG_ONLY_ONE_ENGINE_PLEASE);
	  SWIG_exit(-1);
      	}
	Swig_mark_arg(i);
	engine = JSEmitter::V8;
      } else if (strcmp(argv[i], "-jsc") == 0) {
      	if (engine != -1) {
	  Printf(stderr, ERR_MSG_ONLY_ONE_ENGINE_PLEASE);
	  SWIG_exit(-1);
      	}
	Swig_mark_arg(i);
	engine = JSEmitter::JavascriptCore;
      } else if (strcmp(argv[i], "-node") == 0) {
      	if (engine != -1) {
	  Printf(stderr, ERR_MSG_ONLY_ONE_ENGINE_PLEASE);
	  SWIG_exit(-1);
      	}
	Swig_mark_arg(i);
	engine = JSEmitter::NodeJS;
      } else if (strcmp(argv[i], "-debug-codetemplates") == 0) {
	Swig_mark_arg(i);
	js_template_enable_debug = true;
      } else if (strcmp(argv[i], "-help") == 0) {
	fputs(usage, stdout);
	return;
      }
    }
  }

  switch (engine) {
  case JSEmitter::V8:
    {
      emitter = swig_javascript_create_V8Emitter();
      Preprocessor_define("SWIG_JAVASCRIPT_V8 1", 0);
      SWIG_library_directory("javascript/v8");
      // V8 API is C++, so output must be C++ compatible even when wrapping C code
      if (!cparse_cplusplus) {
	Swig_cparse_cplusplusout(1);
      }
      break;
    }
  case JSEmitter::JavascriptCore:
    {
      emitter = swig_javascript_create_JSCEmitter();
      Preprocessor_define("SWIG_JAVASCRIPT_JSC 1", 0);
      SWIG_library_directory("javascript/jsc");
      break;
    }
  case JSEmitter::NodeJS:
    {
      emitter = swig_javascript_create_V8Emitter();
      Preprocessor_define("SWIG_JAVASCRIPT_V8 1", 0);
      Preprocessor_define("BUILDING_NODE_EXTENSION 1", 0);
      SWIG_library_directory("javascript/v8");
      break;
    }
  default:
    {
      Printf(stderr, "SWIG Javascript: Unknown engine. Please specify one of '-jsc', '-v8' or '-node'.\n");
      SWIG_exit(-1);
      break;
    }
  }

  // Add a symbol to the parser for conditional compilation
  Preprocessor_define("SWIGJAVASCRIPT 1", 0);

  // Add typemap definitions
  SWIG_typemap_lang("javascript");

  // Set configuration file
  SWIG_config_file("javascript.swg");

  allow_overloading();
}

/* -----------------------------------------------------------------------------
 * swig_javascript()    - Instantiate module
 * ----------------------------------------------------------------------------- */

static Language *new_swig_javascript() {
  return new JAVASCRIPT();
}

extern "C" Language *swig_javascript(void) {
  return new_swig_javascript();
}

/**********************************************************************
 * Emitter implementations
 **********************************************************************/

/* -----------------------------------------------------------------------------
 * JSEmitter()
 * ----------------------------------------------------------------------------- */

JSEmitter::JSEmitter(JSEmitter::JSEngine engine)
:  engine(engine), templates(NewHash()), namespaces(NULL), current_namespace(NULL), defaultResultName(NewString("result")), f_wrappers(NULL) {
}

/* -----------------------------------------------------------------------------
 * ~JSEmitter()
 * ----------------------------------------------------------------------------- */

JSEmitter::~JSEmitter() {
  Delete(templates);
}

/* -----------------------------------------------------------------------------
 * JSEmitter::RegisterTemplate() :  Registers a code template
 *
 *  Note: this is used only by JAVASCRIPT::fragmentDirective().
 * ----------------------------------------------------------------------------- */

int JSEmitter::registerTemplate(const String *name, const String *code) {
  if (!State::IsSet(state.globals(HAS_TEMPLATES))) {
    SetFlag(state.globals(), HAS_TEMPLATES);
  }
  return Setattr(templates, name, code);
}

/* -----------------------------------------------------------------------------
 * JSEmitter::getTemplate() :  Provides a registered code template
 * ----------------------------------------------------------------------------- */

Template JSEmitter::getTemplate(const String *name) {
  String *templ = Getattr(templates, name);

  if (!templ) {
    Printf(stderr, "Could not find template %s\n.", name);
    SWIG_exit(EXIT_FAILURE);
  }

  Template t(templ, name);
  return t;
}

JSEmitterState & JSEmitter::getState() {
  return state;
}

int JSEmitter::initialize(Node * /*n */ ) {

  if (namespaces != NULL) {
    Delete(namespaces);
  }
  namespaces = NewHash();
  Hash *global_namespace = createNamespaceEntry("exports", 0, 0);

  Setattr(namespaces, "::", global_namespace);
  current_namespace = global_namespace;

  f_wrappers = NewString("");

  return SWIG_OK;
}

/* ---------------------------------------------------------------------
 * skipIgnoredArgs()
 * --------------------------------------------------------------------- */

Parm *JSEmitter::skipIgnoredArgs(Parm *p) {
  while (checkAttribute(p, "tmap:in:numinputs", "0")) {
    p = Getattr(p, "tmap:in:next");
  }
  return p;
}

/* -----------------------------------------------------------------------------
 * JSEmitter::getBaseClass() :  the node of the base class or NULL
 *
 * Note: the first base class is provided. Multiple inheritance is not
 *       supported.
 * ----------------------------------------------------------------------------- */

Node *JSEmitter::getBaseClass(Node *n) {
  // retrieve the first base class that is not %ignored
  List *baselist = Getattr(n, "bases");
  if (baselist) {
    Iterator base = First(baselist);
    while (base.item && GetFlag(base.item, "feature:ignore")) {
      base = Next(base);
    }
    return base.item;
  }
  return NULL;
}

 /* -----------------------------------------------------------------------------
  * JSEmitter::emitWrapperFunction() :  dispatches emitter functions.
  *
  * This allows to have small sized, dedicated emitting functions.
  * All state dependent branching is done here.
  * ----------------------------------------------------------------------------- */

int JSEmitter::emitWrapperFunction(Node *n) {
  int ret = SWIG_OK;

  String *kind = Getattr(n, "kind");

  if (kind) {

    if (Equal(kind, "function")
	// HACK: sneaky.ctest revealed that typedef'd (global) functions must be
	// detected via the 'view' attribute.
	|| (Equal(kind, "variable") && Equal(Getattr(n, "view"), "globalfunctionHandler"))
	) {
      bool is_member = GetFlag(n, "ismember") != 0 || GetFlag(n, "feature:extend") != 0;
      bool is_static = GetFlag(state.function(), IS_STATIC) != 0;
      ret = emitFunction(n, is_member, is_static);
    } else if (Cmp(kind, "variable") == 0) {
      bool is_static = GetFlag(state.variable(), IS_STATIC) != 0;
      // HACK: smartpointeraccessed static variables are not treated as statics
      if (GetFlag(n, "allocate:smartpointeraccess")) {
	is_static = false;
      }

      bool is_member = GetFlag(n, "ismember") != 0;
      bool is_setter = GetFlag(n, "memberset") != 0 || GetFlag(n, "varset") != 0;
      bool is_getter = GetFlag(n, "memberget") != 0 || GetFlag(n, "varget") != 0;
      if (is_setter) {
	ret = emitSetter(n, is_member, is_static);
      } else if (is_getter) {
	ret = emitGetter(n, is_member, is_static);
      } else {
	Swig_print_node(n);
      }

    } else {
      Printf(stderr, "Warning: unsupported wrapper function type\n");
      Swig_print_node(n);
      ret = SWIG_ERROR;
    }
  } else {
    String *view = Getattr(n, "view");

    if (Cmp(view, "constructorHandler") == 0) {
      ret = emitCtor(n);
    } else if (Cmp(view, "destructorHandler") == 0) {
      ret = emitDtor(n);
    } else {
      Printf(stderr, "Warning: unsupported wrapper function type");
      Swig_print_node(n);
      ret = SWIG_ERROR;
    }
  }

  return ret;
}

int JSEmitter::emitNativeFunction(Node *n) {
  String *wrapname = Getattr(n, "wrap:name");
  enterFunction(n);
  state.function(WRAPPER_NAME, wrapname);
  exitFunction(n);
  return SWIG_OK;
}

int JSEmitter::enterClass(Node *n) {
  state.clazz(RESET);
  state.clazz(NAME, Getattr(n, "sym:name"));
  state.clazz("nspace", current_namespace);

  // Creating a mangled name using the current namespace and the symbol name
  String *mangled_name = NewString("");
  Printf(mangled_name, "%s_%s", Getattr(current_namespace, NAME_MANGLED), Getattr(n, "sym:name"));
  state.clazz(NAME_MANGLED, SwigType_manglestr(mangled_name));
  Delete(mangled_name);

  state.clazz(TYPE, NewString(Getattr(n, "classtype")));

  String *type = SwigType_manglestr(Getattr(n, "classtypeobj"));
  String *classtype_mangled = NewString("");
  Printf(classtype_mangled, "p%s", type);
  state.clazz(TYPE_MANGLED, classtype_mangled);
  Delete(type);

  String *ctor_wrapper = NewString("_wrap_new_veto_");
  Append(ctor_wrapper, state.clazz(NAME));
  state.clazz(CTOR, ctor_wrapper);
  state.clazz(CTOR_DISPATCHERS, NewString(""));
  state.clazz(DTOR, NewString("0"));

  // HACK: assume that a class is abstract
  // this is resolved by emitCtor (which is only called for non abstract classes)
  SetFlag(state.clazz(), IS_ABSTRACT);

  return SWIG_OK;
}

int JSEmitter::enterFunction(Node *n) {
  state.function(RESET);
  state.function(NAME, Getattr(n, "sym:name"));
  if (Equal(Getattr(n, "storage"), "static")) {
    SetFlag(state.function(), IS_STATIC);
  }
  return SWIG_OK;
}

int JSEmitter::enterVariable(Node *n) {
  // reset the state information for variables.
  state.variable(RESET);

  // Retrieve a pure symbol name. Using 'sym:name' as a basis, as it considers %renamings.
  if (Equal(Getattr(n, "view"), "memberconstantHandler")) {
    // Note: this is kind of hacky/experimental
    // For constants/enums 'sym:name' contains e.g., 'Foo_Hello' instead of 'Hello'
    state.variable(NAME, Getattr(n, "memberconstantHandler:sym:name"));
  } else {
    state.variable(NAME, Swig_scopename_last(Getattr(n, "sym:name")));
  }

  if (Equal(Getattr(n, "storage"), "static")) {
    SetFlag(state.variable(), IS_STATIC);
  }

  if (!Language::instance()->is_assignable(n)) {
    SetFlag(state.variable(), IS_IMMUTABLE);
  }
  // FIXME: test "arrays_global" does not compile with that as it is not allowed to assign to char[]
  if (Equal(Getattr(n, "type"), "a().char")) {
    SetFlag(state.variable(), IS_IMMUTABLE);
  }

  return SWIG_OK;
}

int JSEmitter::emitCtor(Node *n) {

  Wrapper *wrapper = NewWrapper();

  bool is_overloaded = GetFlag(n, "sym:overloaded") != 0;

  Template t_ctor(getTemplate("js_ctor"));

  String *wrap_name = Swig_name_wrapper(Getattr(n, "sym:name"));
  if (is_overloaded) {
    t_ctor = getTemplate("js_overloaded_ctor");
    Append(wrap_name, Getattr(n, "sym:overname"));
  }
  Setattr(n, "wrap:name", wrap_name);
  // note: we can remove the is_abstract flag now, as this
  //       is called for non-abstract classes only.
  Setattr(state.clazz(), IS_ABSTRACT, 0);

  ParmList *params = Getattr(n, "parms");
  emit_parameter_variables(params, wrapper);
  emit_attach_parmmaps(params, wrapper);
  // HACK: in test-case `ignore_parameter` emit_attach_parmmaps generated an extra line of applied typemaps.
  // Deleting wrapper->code here, to reset, and as it seemed to have no side effect elsewhere
  Delete(wrapper->code);
  wrapper->code = NewString("");

  Printf(wrapper->locals, "%sresult;", SwigType_str(Getattr(n, "type"), 0));

  marshalInputArgs(n, params, wrapper, Ctor, true, false);
  String *action = emit_action(n);
  Printv(wrapper->code, action, "\n", 0);

  emitCleanupCode(n, wrapper, params);

  t_ctor.replace("$jswrapper", wrap_name)
      .replace("$jsmangledtype", state.clazz(TYPE_MANGLED))
      .replace("$jslocals", wrapper->locals)
      .replace("$jscode", wrapper->code)
      .replace("$jsargcount", Getattr(n, ARGCOUNT))
      .pretty_print(f_wrappers);

  Template t_ctor_case(getTemplate("js_ctor_dispatch_case"));
  t_ctor_case.replace("$jswrapper", wrap_name)
      .replace("$jsargcount", Getattr(n, ARGCOUNT));
  Append(state.clazz(CTOR_DISPATCHERS), t_ctor_case.str());

  DelWrapper(wrapper);

  // create a dispatching ctor
  if (is_overloaded) {
    if (!Getattr(n, "sym:nextSibling")) {
      String *wrap_name = Swig_name_wrapper(Getattr(n, "sym:name"));
      Template t_mainctor(getTemplate("js_ctor_dispatcher"));
      t_mainctor.replace("$jswrapper", wrap_name)
	  .replace("$jsmangledname", state.clazz(NAME_MANGLED))
	  .replace("$jsdispatchcases", state.clazz(CTOR_DISPATCHERS))
	  .pretty_print(f_wrappers);
      state.clazz(CTOR, wrap_name);
    }
  } else {
    state.clazz(CTOR, wrap_name);
  }

  return SWIG_OK;
}

int JSEmitter::emitDtor(Node *n) {

  String *wrap_name = Swig_name_wrapper(Getattr(n, "sym:name"));

  SwigType *type = state.clazz(TYPE);
  String *p_classtype = SwigType_add_pointer(state.clazz(TYPE));
  String *ctype = SwigType_lstr(p_classtype, "");
  String *free = NewString("");

  // (Taken from JSCore implementation.)
  /* The if (Extend) block was taken from the Ruby implementation.
   * The problem is that in the case of an %extend to create a destructor for a struct to coordinate automatic memory cleanup with the Javascript collector,
   * the SWIG function was not being generated. More specifically:
   struct MyData {
   %extend {
   ~MyData() {
   FreeData($self);
   }
   }
   };
   %newobject CreateData;
   struct MyData* CreateData(void);
   %delobject FreeData;
   void FreeData(struct MyData* the_data);

   where the use case is something like:
   var my_data = example.CreateData();
   my_data = null;

   This function was not being generated:
   SWIGINTERN void delete_MyData(struct MyData *self){
   FreeData(self);
   }

   I don't understand fully why it wasn't being generated. It just seems to happen in the Lua generator.
   There is a comment about staticmemberfunctionHandler having an inconsistency and I tracked down dome of the SWIGINTERN void delete_*
   code to that function in the Language base class.
   The Ruby implementation seems to have an explicit check for if(Extend) and explicitly generates the code, so that's what I'm doing here.
   The Ruby implementation does other stuff which I omit.
   */
  if (Extend) {
    String *wrap = Getattr(n, "wrap:code");
    if (wrap) {
      Printv(f_wrappers, wrap, NIL);
    }
  }
  // HACK: this is only for the v8 emitter. maybe set an attribute wrap:action of node
  // TODO: generate dtors more similar to other wrappers
  // EW: I think this is wrong. delete should only be used when new was used to create. If malloc was used, free needs to be used.
  if (SwigType_isarray(type)) {
    Printf(free, "delete [] (%s)", ctype);
  } else {
    Printf(free, "delete (%s)", ctype);
  }

  String *destructor_action = Getattr(n, "wrap:action");
  // Adapted from the JSCore implementation.
  /* The next challenge is to generate the correct finalize function for JavaScriptCore to call.
     Originally, it would use this fragment from javascriptcode.swg
     %fragment ("JS_destructordefn", "templates")
     %{
     void _wrap_${classname_mangled}_finalize(JSObjectRef thisObject)
     {
     SWIG_PRV_DATA* t = (SWIG_PRV_DATA*)JSObjectGetPrivate(thisObject);
     if(t && t->swigCMemOwn) free ((${type}*)t->swigCObject);
     if(t) free(t);
     }
     %}

     But for the above example case of %extend to define a destructor on a struct, we need to override the system to not call
     free ((${type}*)t->swigCObject);
     and substitute it with what the user has provided.
     To solve this, I created a variation fragment called JS_destructoroverridedefn:
     SWIG_PRV_DATA* t = (SWIG_PRV_DATA*)JSObjectGetPrivate(thisObject);
     if(t && t->swigCMemOwn) {
     ${type}* arg1 = (${type}*)t->swigCObject;
     ${destructor_action}
     }
     if(t) free(t);

     Based on what I saw in the Lua and Ruby modules, I use Getattr(n, "wrap:action")
     to decide if the user has a preferred destructor action.
     Based on that, I decide which fragment to use.
     And in the case of the custom action, I substitute that action in.
     I noticed that destructor_action has the form
     delete_MyData(arg1);
     The explicit arg1 is a little funny, so I structured the fragment to create a temporary variable called arg1 to make the generation easier.
     This might suggest this solution misunderstands a more complex case.

     Also, there is a problem where destructor_action is always true for me, even when not requesting %extend as above.
     So this code doesn't actually quite work as I expect. The end result is that the code still works because
     destructor_action calls free like the original template. The one caveat is the string in destructor_action casts to char* which is weird.
     I think there is a deeper underlying SWIG issue because I don't think it should be char*. However, it doesn't really matter for free.

     Maybe the fix for the destructor_action always true problem is that this is supposed to be embedded in the if(Extend) block above.
     But I don't fully understand the conditions of any of these things, and since it works for the moment, I don't want to break more stuff.
   */
  if (destructor_action) {
    Template t_dtor = getTemplate("js_dtoroverride");
    state.clazz(DTOR, wrap_name);
    t_dtor.replace("${classname_mangled}", state.clazz(NAME_MANGLED))
	.replace("$jswrapper", wrap_name)
	.replace("$jsfree", free)
	.replace("$jstype", ctype);

    t_dtor.replace("${destructor_action}", destructor_action);
    Wrapper_pretty_print(t_dtor.str(), f_wrappers);
  } else {
    Template t_dtor = getTemplate("js_dtor");
    state.clazz(DTOR, wrap_name);
    t_dtor.replace("$jsmangledname", state.clazz(NAME_MANGLED))
	.replace("$jswrapper", wrap_name)
	.replace("$jsfree", free)
	.replace("$jstype", ctype)
	.pretty_print(f_wrappers);
  }

  Delete(p_classtype);
  Delete(ctype);
  Delete(free);

  return SWIG_OK;
}

int JSEmitter::emitGetter(Node *n, bool is_member, bool is_static) {
  Wrapper *wrapper = NewWrapper();
  Template t_getter(getTemplate("js_getter"));

  // prepare wrapper name
  String *wrap_name = Swig_name_wrapper(Getattr(n, "sym:name"));
  Setattr(n, "wrap:name", wrap_name);
  state.variable(GETTER, wrap_name);

  // prepare local variables
  ParmList *params = Getattr(n, "parms");
  emit_parameter_variables(params, wrapper);
  emit_attach_parmmaps(params, wrapper);

  // prepare code part
  String *action = emit_action(n);
  marshalInputArgs(n, params, wrapper, Getter, is_member, is_static);
  marshalOutput(n, params, wrapper, action);

  emitCleanupCode(n, wrapper, params);

  t_getter.replace("$jswrapper", wrap_name)
      .replace("$jslocals", wrapper->locals)
      .replace("$jscode", wrapper->code)
      .pretty_print(f_wrappers);

  DelWrapper(wrapper);

  return SWIG_OK;
}

int JSEmitter::emitSetter(Node *n, bool is_member, bool is_static) {

  // skip variables that are immutable
  if (State::IsSet(state.variable(IS_IMMUTABLE))) {
    return SWIG_OK;
  }

  Wrapper *wrapper = NewWrapper();

  Template t_setter(getTemplate("js_setter"));

  // prepare wrapper name
  String *wrap_name = Swig_name_wrapper(Getattr(n, "sym:name"));
  Setattr(n, "wrap:name", wrap_name);
  state.variable(SETTER, wrap_name);

  // prepare local variables
  ParmList *params = Getattr(n, "parms");
  emit_parameter_variables(params, wrapper);
  emit_attach_parmmaps(params, wrapper);

  // prepare code part
  String *action = emit_action(n);
  marshalInputArgs(n, params, wrapper, Setter, is_member, is_static);
  Append(wrapper->code, action);

  emitCleanupCode(n, wrapper, params);

  t_setter.replace("$jswrapper", wrap_name)
      .replace("$jslocals", wrapper->locals)
      .replace("$jscode", wrapper->code)
      .pretty_print(f_wrappers);

  DelWrapper(wrapper);

  return SWIG_OK;
}

/* -----------------------------------------------------------------------------
 * JSEmitter::emitConstant() :  triggers code generation for constants
 * ----------------------------------------------------------------------------- */

int JSEmitter::emitConstant(Node *n) {
  // HACK: somehow it happened under Mac OS X that before everything started
  // a lot of SWIG internal constants were emitted
  // This didn't happen on other platforms yet...
  // we ignore those premature definitions
  if (!State::IsSet(state.globals(HAS_TEMPLATES))) {
    return SWIG_ERROR;
  }

  Wrapper *wrapper = NewWrapper();
  SwigType *type = Getattr(n, "type");
  String *name = Getattr(n, "name");
  String *iname = Getattr(n, "sym:name");
  String *wname = Swig_name_wrapper(name);
  String *rawval = Getattr(n, "rawval");
  String *value = rawval ? rawval : Getattr(n, "value");

  // HACK: forcing usage of cppvalue for v8 (which turned out to fix typdef_struct.i, et. al)
  if (State::IsSet(state.globals(FORCE_CPP)) && Getattr(n, "cppvalue") != NULL) {
    value = Getattr(n, "cppvalue");
  }

  Template t_getter(getTemplate("js_getter"));

  // call the variable methods as a constants are
  // registered in same way
  enterVariable(n);
  state.variable(GETTER, wname);
  // TODO: why do we need this?
  Setattr(n, "wrap:name", wname);

  // special treatment of member pointers
  if (SwigType_type(type) == T_MPOINTER) {
    // TODO: this could go into a code-template
    String *mpointer_wname = NewString("");
    Printf(mpointer_wname, "_wrapConstant_%s", iname);
    Setattr(n, "memberpointer:constant:wrap:name", mpointer_wname);
    String *str = SwigType_str(type, mpointer_wname);
    Printf(f_wrappers, "static %s = %s;\n", str, value);
    Delete(str);
    value = mpointer_wname;
  }

  marshalOutput(n, 0, wrapper, NewString(""), value, false);

  t_getter.replace("$jswrapper", wname)
      .replace("$jslocals", wrapper->locals)
      .replace("$jscode", wrapper->code)
      .pretty_print(f_wrappers);

  exitVariable(n);

  DelWrapper(wrapper);

  return SWIG_OK;
}

int JSEmitter::emitFunction(Node *n, bool is_member, bool is_static) {
  Wrapper *wrapper = NewWrapper();
  Template t_function(getTemplate("js_function"));

  bool is_overloaded = GetFlag(n, "sym:overloaded") != 0;

  // prepare the function wrapper name
  String *iname = Getattr(n, "sym:name");
  String *wrap_name = Swig_name_wrapper(iname);
  if (is_overloaded) {
    t_function = getTemplate("js_overloaded_function");
    Append(wrap_name, Getattr(n, "sym:overname"));
  }
  Setattr(n, "wrap:name", wrap_name);
  state.function(WRAPPER_NAME, wrap_name);

  // prepare local variables
  ParmList *params = Getattr(n, "parms");
  emit_parameter_variables(params, wrapper);
  emit_attach_parmmaps(params, wrapper);

  // HACK: in test-case `ignore_parameter` emit_attach_parmmaps generates an extra line of applied typemap.
  // Deleting wrapper->code here fixes the problem, and seems to have no side effect elsewhere
  Delete(wrapper->code);
  wrapper->code = NewString("");

  marshalInputArgs(n, params, wrapper, Function, is_member, is_static);
  String *action = emit_action(n);
  marshalOutput(n, params, wrapper, action);
  emitCleanupCode(n, wrapper, params);
  Replaceall(wrapper->code, "$symname", iname);

  t_function.replace("$jswrapper", wrap_name)
      .replace("$jslocals", wrapper->locals)
      .replace("$jscode", wrapper->code)
      .replace("$jsargcount", Getattr(n, ARGCOUNT))
      .pretty_print(f_wrappers);


  DelWrapper(wrapper);

  return SWIG_OK;
}

int JSEmitter::emitFunctionDispatcher(Node *n, bool /*is_member */ ) {
  Wrapper *wrapper = NewWrapper();

  // Generate call list, go to first node
  Node *sibl = n;

  while (Getattr(sibl, "sym:previousSibling"))
    sibl = Getattr(sibl, "sym:previousSibling");	// go all the way up

  do {
    String *siblname = Getattr(sibl, "wrap:name");

    if (siblname) {
      // handle function overloading
      Template t_dispatch_case = getTemplate("js_function_dispatch_case");
      t_dispatch_case.replace("$jswrapper", siblname)
	  .replace("$jsargcount", Getattr(sibl, ARGCOUNT));

      Append(wrapper->code, t_dispatch_case.str());
    }

  } while ((sibl = Getattr(sibl, "sym:nextSibling")));

  Template t_function(getTemplate("js_function_dispatcher"));

  // Note: this dispatcher function gets called after the last overloaded function has been created.
  // At this time, n.wrap:name contains the name of the last wrapper function.
  // To get a valid function name for the dispatcher function we take the last wrapper name and
  // substract the extension "sym:overname",
  String *wrap_name = NewString(Getattr(n, "wrap:name"));
  String *overname = Getattr(n, "sym:overname");

  Node *methodclass = Swig_methodclass(n);
  String *class_name = Getattr(methodclass, "sym:name");

  int l1 = Len(wrap_name);
  int l2 = Len(overname);
  Delslice(wrap_name, l1 - l2, l1);

  String *new_string = NewStringf("%s_%s", class_name, wrap_name);
  String *final_wrap_name = Swig_name_wrapper(new_string);
     
  Setattr(n, "wrap:name", final_wrap_name);
  state.function(WRAPPER_NAME, final_wrap_name);



  t_function.replace("$jslocals", wrapper->locals)
      .replace("$jscode", wrapper->code);

  // call this here, to replace all variables
  t_function.replace("$jswrapper", final_wrap_name)
      .replace("$jsname", state.function(NAME))
      .pretty_print(f_wrappers);

  // Delete the state variable
  DelWrapper(wrapper);

  return SWIG_OK;
}

String *JSEmitter::emitInputTypemap(Node *n, Parm *p, Wrapper *wrapper, String *arg) {
  // Get input typemap for current param
  String *tm = Getattr(p, "tmap:in");
  SwigType *type = Getattr(p, "type");

  if (tm != NULL) {
    Replaceall(tm, "$input", arg);
    Setattr(p, "emit:input", arg);
    // do replacements for built-in variables
    if (Getattr(p, "wrap:disown") || (Getattr(p, "tmap:in:disown"))) {
      Replaceall(tm, "$disown", "SWIG_POINTER_DISOWN");
    } else {
      Replaceall(tm, "$disown", "0");
    }
    Replaceall(tm, "$symname", Getattr(n, "sym:name"));
    Printf(wrapper->code, "%s\n", tm);
  } else {
    Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(type, 0));
  }

  return tm;
}

void JSEmitter::marshalOutput(Node *n, ParmList *params, Wrapper *wrapper, String *actioncode, const String *cresult, bool emitReturnVariable) {
  SwigType *type = Getattr(n, "type");
  String *tm;
  Parm *p;

  // adds a declaration for the result variable
  if (emitReturnVariable)
    emit_return_variable(n, type, wrapper);
  // if not given, use default result identifier ('result') for output typemap
  if (cresult == 0)
    cresult = defaultResultName;

  tm = Swig_typemap_lookup_out("out", n, cresult, wrapper, actioncode);
  bool should_own = GetFlag(n, "feature:new") != 0;

  if (tm) {
    Replaceall(tm, "$objecttype", Swig_scopename_last(SwigType_str(SwigType_strip_qualifiers(type), 0)));

    if (should_own) {
      Replaceall(tm, "$owner", "SWIG_POINTER_OWN");
    } else {
      Replaceall(tm, "$owner", "0");
    }
    Append(wrapper->code, tm);

    if (Len(tm) > 0) {
      Printf(wrapper->code, "\n");
    }
  } else {
    Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(type, 0), Getattr(n, "name"));
  }

  if (params) {
    for (p = params; p;) {
      if ((tm = Getattr(p, "tmap:argout"))) {
	Replaceall(tm, "$input", Getattr(p, "emit:input"));
	Printv(wrapper->code, tm, "\n", NIL);
	p = Getattr(p, "tmap:argout:next");
      } else {
	p = nextSibling(p);
      }
    }
  }

  Replaceall(wrapper->code, "$result", "jsresult");
}

void JSEmitter::emitCleanupCode(Node *n, Wrapper *wrapper, ParmList *params) {
  Parm *p;
  String *tm;

  for (p = params; p;) {
    if ((tm = Getattr(p, "tmap:freearg"))) {
      //addThrows(n, "tmap:freearg", p);
      Replaceall(tm, "$input", Getattr(p, "emit:input"));
      Printv(wrapper->code, tm, "\n", NIL);
      p = Getattr(p, "tmap:freearg:next");
    } else {
      p = nextSibling(p);
    }
  }

  if (GetFlag(n, "feature:new")) {
    tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0);
    if (tm != NIL) {
      //addThrows(throws_hash, "newfree", n);
      Printv(wrapper->code, tm, "\n", NIL);
    }
  }

  /* See if there is any return cleanup code */
  if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) {
    Printf(wrapper->code, "%s\n", tm);
    Delete(tm);
  }
}

int JSEmitter::switchNamespace(Node *n) {
  // HACK: somehow this gets called for member functions.
  // We can safely ignore them, as members are not associated to a namespace (only their class)
  if (GetFlag(n, "ismember")) {
    return SWIG_OK;
  }

  // if nspace is deactivated, everything goes into the global scope
  if (!GetFlag(n, "feature:nspace")) {
    current_namespace = Getattr(namespaces, "::");
    return SWIG_OK;
  }

// EXPERIMENTAL: we want to use Language::getNSpace() here
// However, it is not working yet.
// For namespace functions Language::getNSpace() does not give a valid result
#if 0
  JAVASCRIPT *lang = static_cast<JAVASCRIPT*>(Language::instance());
  String *_nspace = lang->getNSpace();
  if (!Equal(nspace, _nspace)) {
    Printf(stdout, "##### Custom vs Language::getNSpace(): %s | %s\n", nspace, _nspace);
    Swig_print_node(n);
  }
#endif

  String *nspace = Getattr(n, "sym:nspace");

  if (nspace == NULL) {
    // It seems that only classes have 'sym:nspace' set.
    // We try to get the namespace from the qualified name (i.e., everything before the last '::')
    nspace = Swig_scopename_prefix(Getattr(n, "name"));
  }

  // If there is not even a scopename prefix then it must be global scope
  if (nspace == NULL) {
    current_namespace = Getattr(namespaces, "::");
    return SWIG_OK;
  }

  String *scope = NewString(nspace);
  // replace "." with "::" that we can use Swig_scopename_last
  Replaceall(scope, ".", "::");

  // if the scope is not yet registered
  // create (parent) namespaces recursively
  if (!Getattr(namespaces, scope)) {
    createNamespace(scope);
  }
  current_namespace = Getattr(namespaces, scope);

  return SWIG_OK;
}

int JSEmitter::createNamespace(String *scope) {

  String *parent_scope = Swig_scopename_prefix(scope);
  Hash *parent_namespace;
  if (parent_scope == 0) {
    parent_namespace = Getattr(namespaces, "::");
  } else if (!Getattr(namespaces, parent_scope)) {
    createNamespace(parent_scope);
    parent_namespace = Getattr(namespaces, parent_scope);
  } else {
    parent_namespace = Getattr(namespaces, parent_scope);
  }
  assert(parent_namespace != 0);

  Hash *new_namespace = createNamespaceEntry(Char(scope), Char(Getattr(parent_namespace, "name")), Char(Getattr(parent_namespace, "name_mangled")));
  Setattr(namespaces, scope, new_namespace);

  Delete(parent_scope);
  return SWIG_OK;
}

Hash *JSEmitter::createNamespaceEntry(const char *_name, const char *parent, const char *parent_mangled) {
  Hash *entry = NewHash();
  String *name = NewString(_name);
  Setattr(entry, NAME, Swig_scopename_last(name));
  Setattr(entry, NAME_MANGLED, Swig_name_mangle(name));
  Setattr(entry, PARENT, NewString(parent));
  Setattr(entry, PARENT_MANGLED, NewString(parent_mangled));

  Delete(name);
  return entry;
}

/**********************************************************************
 * JavascriptCore: JSEmitter implementation for JavascriptCore engine
 **********************************************************************/

class JSCEmitter:public JSEmitter {

public:
  JSCEmitter();
  virtual ~ JSCEmitter();
  virtual int initialize(Node *n);
  virtual int dump(Node *n);
  virtual int close();

protected:
  virtual int enterVariable(Node *n);
  virtual int exitVariable(Node *n);
  virtual int enterFunction(Node *n);
  virtual int exitFunction(Node *n);
  virtual int enterClass(Node *n);
  virtual int exitClass(Node *n);
  virtual void marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, MarshallingMode mode, bool is_member, bool is_static);
  virtual Hash *createNamespaceEntry(const char *name, const char *parent, const char *parent_mangled);
  virtual int emitNamespaces();

private:

  String *NULL_STR;
  String *VETO_SET;

  // output file and major code parts
  File *f_wrap_cpp;
  File *f_runtime;
  File *f_header;
  File *f_init;

};

JSCEmitter::JSCEmitter()
:  JSEmitter(JSEmitter::JavascriptCore), NULL_STR(NewString("NULL")), VETO_SET(NewString("JS_veto_set_variable")), f_wrap_cpp(NULL), f_runtime(NULL), f_header(NULL), f_init(NULL) {
}

JSCEmitter::~JSCEmitter() {
  Delete(NULL_STR);
  Delete(VETO_SET);
}


/* ---------------------------------------------------------------------
 * marshalInputArgs()
 *
 * Process all of the arguments passed into the argv array
 * and convert them into C/C++ function arguments using the
 * supplied typemaps.
 * --------------------------------------------------------------------- */

void JSCEmitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, MarshallingMode mode, bool is_member, bool is_static) {
  Parm *p;
  String *tm;

  // determine an offset index, as members have an extra 'this' argument
  // except: static members and ctors.
  int startIdx = 0;
  if (is_member && !is_static && mode != Ctor) {
    startIdx = 1;
  }
  // store number of arguments for argument checks
  int num_args = emit_num_arguments(parms) - startIdx;
  String *argcount = NewString("");
  Printf(argcount, "%d", num_args);
  Setattr(n, ARGCOUNT, argcount);

  // process arguments
  int i = 0;
  for (p = parms; p; i++) {
    String *arg = NewString("");
    String *type = Getattr(p, "type");

    // ignore varargs
    if (SwigType_isvarargs(type))
      break;

    switch (mode) {
    case Getter:
    case Function:
      if (is_member && !is_static && i == 0) {
	Printv(arg, "thisObject", 0);
      } else {
	Printf(arg, "argv[%d]", i - startIdx);
      }
      break;
    case Setter:
      if (is_member && !is_static && i == 0) {
	Printv(arg, "thisObject", 0);
      } else {
	Printv(arg, "value", 0);
      }
      break;
    case Ctor:
      Printf(arg, "argv[%d]", i);
      break;
    default:
      throw "Illegal state.";
    }
    tm = emitInputTypemap(n, p, wrapper, arg);
    Delete(arg);
    if (tm) {
      p = Getattr(p, "tmap:in:next");
    } else {
      p = nextSibling(p);
    }
  }
}

int JSCEmitter::initialize(Node *n) {

  JSEmitter::initialize(n);

  /* Get the output file name */
  String *outfile = Getattr(n, "outfile");

  /* Initialize I/O */
  f_wrap_cpp = NewFile(outfile, "w", SWIG_output_files());
  if (!f_wrap_cpp) {
    FileErrorDisplay(outfile);
    SWIG_exit(EXIT_FAILURE);
  }

  /* Initialization of members */
  f_runtime = NewString("");
  f_init = NewString("");
  f_header = NewString("");

  state.globals(CREATE_NAMESPACES, NewString(""));
  state.globals(REGISTER_NAMESPACES, NewString(""));
  state.globals(INITIALIZER, NewString(""));

  /* Register file targets with the SWIG file handler */
  Swig_register_filebyname("begin", f_wrap_cpp);
  Swig_register_filebyname("header", f_header);
  Swig_register_filebyname("wrapper", f_wrappers);
  Swig_register_filebyname("runtime", f_runtime);
  Swig_register_filebyname("init", f_init);

  Swig_banner(f_wrap_cpp);

  return SWIG_OK;
}

int JSCEmitter::dump(Node *n) {
  /* Get the module name */
  String *module = Getattr(n, "name");

  Template initializer_define(getTemplate("js_initializer_define"));
  initializer_define.replace("$jsname", module).pretty_print(f_header);

  SwigType_emit_type_table(f_runtime, f_wrappers);

  Printv(f_wrap_cpp, f_runtime, "\n", 0);
  Printv(f_wrap_cpp, f_header, "\n", 0);
  Printv(f_wrap_cpp, f_wrappers, "\n", 0);

  emitNamespaces();

  // compose the initializer function using a template
  Template initializer(getTemplate("js_initializer"));
  initializer.replace("$jsname", module)
      .replace("$jsregisterclasses", state.globals(INITIALIZER))
      .replace("$jscreatenamespaces", state.globals(CREATE_NAMESPACES))
      .replace("$jsregisternamespaces", state.globals(REGISTER_NAMESPACES))
      .pretty_print(f_init);

  Printv(f_wrap_cpp, f_init, 0);

  return SWIG_OK;
}

int JSCEmitter::close() {
  Delete(f_runtime);
  Delete(f_header);
  Delete(f_wrappers);
  Delete(f_init);
  Delete(namespaces);
  Delete(f_wrap_cpp);
  return SWIG_OK;
}

int JSCEmitter::enterFunction(Node *n) {

  JSEmitter::enterFunction(n);

  return SWIG_OK;
}

int JSCEmitter::exitFunction(Node *n) {
  Template t_function = getTemplate("jsc_function_declaration");

  bool is_member = GetFlag(n, "ismember") != 0 || GetFlag(n, "feature:extend") != 0;
  bool is_overloaded = GetFlag(n, "sym:overloaded") != 0;

  // handle overloaded functions
  if (is_overloaded) {
    if (!Getattr(n, "sym:nextSibling")) {
      //state.function(WRAPPER_NAME, Swig_name_wrapper(Getattr(n, "name")));
      // create dispatcher
      emitFunctionDispatcher(n, is_member);
    } else {
      //don't register wrappers of overloaded functions in function tables
      return SWIG_OK;
    }
  }

  t_function.replace("$jsname", state.function(NAME))
      .replace("$jswrapper", state.function(WRAPPER_NAME));

  if (is_member) {
    if (GetFlag(state.function(), IS_STATIC)) {
      t_function.pretty_print(state.clazz(STATIC_FUNCTIONS));
    } else {
      t_function.pretty_print(state.clazz(MEMBER_FUNCTIONS));
    }
  } else {
    t_function.pretty_print(Getattr(current_namespace, "functions"));
  }

  return SWIG_OK;
}

int JSCEmitter::enterVariable(Node *n) {
  JSEmitter::enterVariable(n);
  state.variable(GETTER, NULL_STR);
  state.variable(SETTER, VETO_SET);
  return SWIG_OK;
}

int JSCEmitter::exitVariable(Node *n) {
  Template t_variable(getTemplate("jsc_variable_declaration"));
  t_variable.replace("$jsname", state.variable(NAME))
      .replace("$jsgetter", state.variable(GETTER))
      .replace("$jssetter", state.variable(SETTER));

  if (GetFlag(n, "ismember")) {
    if (GetFlag(state.variable(), IS_STATIC)
	|| Equal(Getattr(n, "nodeType"), "enumitem")) {
      t_variable.pretty_print(state.clazz(STATIC_VARIABLES));
    } else {
      t_variable.pretty_print(state.clazz(MEMBER_VARIABLES));
    }
  } else {
    t_variable.pretty_print(Getattr(current_namespace, "values"));
  }

  return SWIG_OK;
}

int JSCEmitter::enterClass(Node *n) {
  JSEmitter::enterClass(n);
  state.clazz(MEMBER_VARIABLES, NewString(""));
  state.clazz(MEMBER_FUNCTIONS, NewString(""));
  state.clazz(STATIC_VARIABLES, NewString(""));
  state.clazz(STATIC_FUNCTIONS, NewString(""));

  Template t_class_decl = getTemplate("jsc_class_declaration");
  t_class_decl.replace("$jsmangledname", state.clazz(NAME_MANGLED))
      .pretty_print(f_wrappers);

  return SWIG_OK;
}

int JSCEmitter::exitClass(Node *n) {
  Template t_class_tables(getTemplate("jsc_class_tables"));
  t_class_tables.replace("$jsmangledname", state.clazz(NAME_MANGLED))
      .replace("$jsclassvariables", state.clazz(MEMBER_VARIABLES))
      .replace("$jsclassfunctions", state.clazz(MEMBER_FUNCTIONS))
      .replace("$jsstaticclassfunctions", state.clazz(STATIC_FUNCTIONS))
      .replace("$jsstaticclassvariables", state.clazz(STATIC_VARIABLES))
      .pretty_print(f_wrappers);

  /* adds the ctor wrappers at this position */
  // Note: this is necessary to avoid extra forward declarations.
  //Append(f_wrappers, state.clazz(CTOR_WRAPPERS));

  // for abstract classes add a vetoing ctor
  if (GetFlag(state.clazz(), IS_ABSTRACT)) {
    Template t_veto_ctor(getTemplate("js_veto_ctor"));
    t_veto_ctor.replace("$jswrapper", state.clazz(CTOR))
	.replace("$jsname", state.clazz(NAME))
	.pretty_print(f_wrappers);
  }

  /* adds a class template statement to initializer function */
  Template t_classtemplate(getTemplate("jsc_class_definition"));

  /* prepare registration of base class */
  String *jsclass_inheritance = NewString("");
  Node *base_class = getBaseClass(n);
  if (base_class != NULL) {
    Template t_inherit(getTemplate("jsc_class_inherit"));
    t_inherit.replace("$jsmangledname", state.clazz(NAME_MANGLED))
	.replace("$jsbaseclassmangled", SwigType_manglestr(Getattr(base_class, "name")))
	.pretty_print(jsclass_inheritance);
  } else {
    Template t_inherit(getTemplate("jsc_class_noinherit"));
    t_inherit.replace("$jsmangledname", state.clazz(NAME_MANGLED))
	.pretty_print(jsclass_inheritance);
  }

  t_classtemplate.replace("$jsmangledname", state.clazz(NAME_MANGLED))
      .replace("$jsmangledtype", state.clazz(TYPE_MANGLED))
      .replace("$jsclass_inheritance", jsclass_inheritance)
      .replace("$jsctor", state.clazz(CTOR))
      .replace("$jsdtor", state.clazz(DTOR))
      .pretty_print(state.globals(INITIALIZER));
  Delete(jsclass_inheritance);

  /* Note: this makes sure that there is a swig_type added for this class */
  SwigType_remember_clientdata(state.clazz(TYPE_MANGLED), NewString("0"));

  /* adds a class registration statement to initializer function */
  Template t_registerclass(getTemplate("jsc_class_registration"));
  t_registerclass.replace("$jsname", state.clazz(NAME))
      .replace("$jsmangledname", state.clazz(NAME_MANGLED))
      .replace("$jsnspace", Getattr(state.clazz("nspace"), NAME_MANGLED))
      .pretty_print(state.globals(INITIALIZER));

  return SWIG_OK;
}

Hash *JSCEmitter::createNamespaceEntry(const char *name, const char *parent, const char *parent_mangled) {
  Hash *entry = JSEmitter::createNamespaceEntry(name, parent, parent_mangled);
  Setattr(entry, "functions", NewString(""));
  Setattr(entry, "values", NewString(""));
  return entry;
}

int JSCEmitter::emitNamespaces() {
  Iterator it;
  for (it = First(namespaces); it.item; it = Next(it)) {
    Hash *entry = it.item;
    String *name = Getattr(entry, NAME);
    String *name_mangled = Getattr(entry, NAME_MANGLED);
    String *parent_mangled = Getattr(entry, PARENT_MANGLED);
    String *functions = Getattr(entry, "functions");
    String *variables = Getattr(entry, "values");

    // skip the global namespace which is given by the application

    Template namespace_definition(getTemplate("jsc_nspace_declaration"));
    namespace_definition.replace("$jsglobalvariables", variables)
	.replace("$jsglobalfunctions", functions)
	.replace("$jsnspace", name_mangled)
	.replace("$jsmangledname", name_mangled)
	.pretty_print(f_wrap_cpp);

    Template t_createNamespace(getTemplate("jsc_nspace_definition"));
    t_createNamespace.replace("$jsmangledname", name_mangled);
    Append(state.globals(CREATE_NAMESPACES), t_createNamespace.str());

    // Don't register 'exports' as namespace. It is return to the application.
    if (!Equal("exports", name)) {
      Template t_registerNamespace(getTemplate("jsc_nspace_registration"));
      t_registerNamespace.replace("$jsmangledname", name_mangled)
	  .replace("$jsname", name)
	  .replace("$jsparent", parent_mangled);
      Append(state.globals(REGISTER_NAMESPACES), t_registerNamespace.str());
    }
  }

  return SWIG_OK;
}

JSEmitter *swig_javascript_create_JSCEmitter() {
  return new JSCEmitter();
}

/**********************************************************************
 * V8: JSEmitter implementation for V8 engine
 **********************************************************************/

class V8Emitter:public JSEmitter {

public:
  V8Emitter();

  virtual ~ V8Emitter();
  virtual int initialize(Node *n);
  virtual int dump(Node *n);
  virtual int close();
  virtual int enterClass(Node *n);
  virtual int exitClass(Node *n);
  virtual int enterVariable(Node *n);
  virtual int exitVariable(Node *n);
  virtual int exitFunction(Node *n);

protected:
  virtual void marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, MarshallingMode mode, bool is_member, bool is_static);
  virtual int emitNamespaces();

protected:
  /* built-in parts */
  String *f_runtime;
  String *f_header;
  String *f_init;
  String *f_post_init;

  /* part for class templates */
  String *f_class_templates;

  /* parts for initilizer */
  String *f_init_namespaces;
  String *f_init_class_templates;
  String *f_init_wrappers;
  String *f_init_inheritance;
  String *f_init_class_instances;
  String *f_init_static_wrappers;
  String *f_init_register_classes;
  String *f_init_register_namespaces;

  // the output cpp file
  File *f_wrap_cpp;

  String *NULL_STR;
  String *VETO_SET;
  String *moduleName;

};

V8Emitter::V8Emitter()
:  JSEmitter(JSEmitter::V8), NULL_STR(NewString("0")), VETO_SET(NewString("JS_veto_set_variable")) {
}

V8Emitter::~V8Emitter() {
  Delete(NULL_STR);
  Delete(VETO_SET);
}

int V8Emitter::initialize(Node *n) {
  JSEmitter::initialize(n);

  moduleName = Getattr(n, "name");

  // Get the output file name
  String *outfile = Getattr(n, "outfile");
  f_wrap_cpp = NewFile(outfile, "w", SWIG_output_files());
  if (!f_wrap_cpp) {
    FileErrorDisplay(outfile);
    SWIG_exit(EXIT_FAILURE);
  }

  f_runtime = NewString("");
  f_header = NewString("");
  f_class_templates = NewString("");
  f_init = NewString("");
  f_post_init = NewString("");

  f_init_namespaces = NewString("");
  f_init_class_templates = NewString("");
  f_init_wrappers = NewString("");
  f_init_inheritance = NewString("");
  f_init_class_instances = NewString("");
  f_init_static_wrappers = NewString("");
  f_init_register_classes = NewString("");
  f_init_register_namespaces = NewString("");

  // note: this is necessary for built-in generation of SWIG runtime code
  Swig_register_filebyname("begin", f_wrap_cpp);
  Swig_register_filebyname("runtime", f_runtime);
  Swig_register_filebyname("header", f_header);
  Swig_register_filebyname("wrapper", f_wrappers);
  Swig_register_filebyname("init", f_init);
  Swig_register_filebyname("post-init", f_post_init);

  state.globals(FORCE_CPP, NewString("1"));

  Swig_banner(f_wrap_cpp);

  return SWIG_OK;
}

int V8Emitter::dump(Node *n) {
  /* Get the module name */
  String *module = Getattr(n, "name");

  Template initializer_define(getTemplate("js_initializer_define"));
  initializer_define.replace("$jsname", module).pretty_print(f_header);

  SwigType_emit_type_table(f_runtime, f_wrappers);

  Printv(f_wrap_cpp, f_runtime, "\n", 0);
  Printv(f_wrap_cpp, f_header, "\n", 0);
  Printv(f_wrap_cpp, f_class_templates, "\n", 0);
  Printv(f_wrap_cpp, f_wrappers, "\n", 0);

  emitNamespaces();

  // compose the initializer function using a template
  // filled with sub-parts
  Template initializer(getTemplate("js_initializer"));
  initializer.replace("$jsname", moduleName)
      .replace("$jsv8nspaces", f_init_namespaces)
      .replace("$jsv8classtemplates", f_init_class_templates)
      .replace("$jsv8wrappers", f_init_wrappers)
      .replace("$jsv8inheritance", f_init_inheritance)
      .replace("$jsv8classinstances", f_init_class_instances)
      .replace("$jsv8staticwrappers", f_init_static_wrappers)
      .replace("$jsv8registerclasses", f_init_register_classes)
      .replace("$jsv8registernspaces", f_init_register_namespaces);
  Printv(f_init, initializer.str(), 0);

  Printv(f_wrap_cpp, f_init, 0);

  Printv(f_wrap_cpp, f_post_init, 0);

  return SWIG_OK;
}

int V8Emitter::close() {
  Delete(f_runtime);
  Delete(f_header);
  Delete(f_class_templates);
  Delete(f_init_namespaces);
  Delete(f_init_class_templates);
  Delete(f_init_wrappers);
  Delete(f_init_inheritance);
  Delete(f_init_class_instances);
  Delete(f_init_static_wrappers);
  Delete(f_init_register_classes);
  Delete(f_init_register_namespaces);
  Delete(f_init);
  Delete(f_post_init);
  Delete(f_wrap_cpp);
  return SWIG_OK;
}

int V8Emitter::enterClass(Node *n) {
  JSEmitter::enterClass(n);

  // emit declaration of a v8 class template
  Template t_decl_class(getTemplate("jsv8_declare_class_template"));
  t_decl_class.replace("$jsmangledname", state.clazz(NAME_MANGLED))
      .trim()
      .pretty_print(f_class_templates);

  return SWIG_OK;
}

int V8Emitter::exitClass(Node *n) {
  if (GetFlag(state.clazz(), IS_ABSTRACT)) {
    Template t_veto_ctor(getTemplate("js_veto_ctor"));
    t_veto_ctor.replace("$jswrapper", state.clazz(CTOR))
	.replace("$jsname", state.clazz(NAME))
	.pretty_print(f_wrappers);
  }

  /* Note: this makes sure that there is a swig_type added for this class */
  String *clientData = NewString("");
  Printf(clientData, "&%s_clientData", state.clazz(NAME_MANGLED));

  /* Note: this makes sure that there is a swig_type added for this class */
  SwigType_remember_clientdata(state.clazz(TYPE_MANGLED), NewString("0"));

  // emit definition of v8 class template
  Template t_def_class = getTemplate("jsv8_define_class_template");
  t_def_class.replace("$jsmangledname", state.clazz(NAME_MANGLED))
      .replace("$jsname", state.clazz(NAME))
      .replace("$jsmangledtype", state.clazz(TYPE_MANGLED))
      .replace("$jsdtor", state.clazz(DTOR))
      .trim()
      .pretty_print(f_init_class_templates);

  Template t_class_instance = getTemplate("jsv8_create_class_instance");
  t_class_instance.replace("$jsname", state.clazz(NAME))
      .replace("$jsmangledname", state.clazz(NAME_MANGLED))
      .replace("$jsctor", state.clazz(CTOR))
      .trim()
      .pretty_print(f_init_class_instances);

  //  emit inheritance setup
  Node *baseClass = getBaseClass(n);
  if (baseClass) {
    String *base_name = Getattr(baseClass, "name");

    Template t_inherit = getTemplate("jsv8_inherit");

    String *base_name_mangled = SwigType_manglestr(base_name);
    t_inherit.replace("$jsmangledname", state.clazz(NAME_MANGLED))
	.replace("$jsbaseclass", base_name_mangled)
	.trim()
	.pretty_print(f_init_inheritance);
    Delete(base_name_mangled);
  }
  //  emit registration of class template
  Template t_register = getTemplate("jsv8_register_class");
  t_register.replace("$jsmangledname", state.clazz(NAME_MANGLED))
      .replace("$jsname", state.clazz(NAME))
      .replace("$jsparent", Getattr(state.clazz("nspace"), NAME_MANGLED))
      .trim()
      .pretty_print(f_init_register_classes);

  return SWIG_OK;
}

int V8Emitter::enterVariable(Node *n) {
  JSEmitter::enterVariable(n);

  state.variable(GETTER, NULL_STR);
  state.variable(SETTER, VETO_SET);

  return SWIG_OK;
}

int V8Emitter::exitVariable(Node *n) {
  if (GetFlag(n, "ismember")) {
    if (GetFlag(state.variable(), IS_STATIC) || Equal(Getattr(n, "nodeType"), "enumitem")) {
      Template t_register = getTemplate("jsv8_register_static_variable");
      t_register.replace("$jsparent", state.clazz(NAME_MANGLED))
	  .replace("$jsname", state.variable(NAME))
	  .replace("$jsgetter", state.variable(GETTER))
	  .replace("$jssetter", state.variable(SETTER))
	  .trim()
	  .pretty_print(f_init_static_wrappers);
    } else {
      Template t_register = getTemplate("jsv8_register_member_variable");
      t_register.replace("$jsmangledname", state.clazz(NAME_MANGLED))
	  .replace("$jsname", state.variable(NAME))
	  .replace("$jsgetter", state.variable(GETTER))
	  .replace("$jssetter", state.variable(SETTER))
	  .trim()
	  .pretty_print(f_init_wrappers);
    }
  } else {
    // Note: a global variable is treated like a static variable
    //       with the parent being a nspace object (instead of class object)
    Template t_register = getTemplate("jsv8_register_static_variable");
    t_register.replace("$jsparent", Getattr(current_namespace, NAME_MANGLED))
	.replace("$jsname", state.variable(NAME))
	.replace("$jsgetter", state.variable(GETTER))
	.replace("$jssetter", state.variable(SETTER))
	.trim()
	.pretty_print(f_init_wrappers);
  }

  return SWIG_OK;
}

int V8Emitter::exitFunction(Node *n) {
  bool is_member = GetFlag(n, "ismember") != 0 || GetFlag(n, "feature:extend") != 0;

  // create a dispatcher for overloaded functions
  bool is_overloaded = GetFlag(n, "sym:overloaded") != 0;
  if (is_overloaded) {
    if (!Getattr(n, "sym:nextSibling")) {
      //state.function(WRAPPER_NAME, Swig_name_wrapper(Getattr(n, "name")));
      emitFunctionDispatcher(n, is_member);
    } else {
      //don't register wrappers of overloaded functions in function tables
      return SWIG_OK;
    }
  }
  // register the function at the specific context
  if (is_member) {
    if (GetFlag(state.function(), IS_STATIC)) {
      Template t_register = getTemplate("jsv8_register_static_function");
      t_register.replace("$jsparent", state.clazz(NAME_MANGLED))
	  .replace("$jsname", state.function(NAME))
	  .replace("$jswrapper", state.function(WRAPPER_NAME))
	  .trim()
	  .pretty_print(f_init_static_wrappers);
    } else {
      Template t_register = getTemplate("jsv8_register_member_function");
      t_register.replace("$jsmangledname", state.clazz(NAME_MANGLED))
	  .replace("$jsname", state.function(NAME))
	  .replace("$jswrapper", state.function(WRAPPER_NAME))
	  .trim()
	  .pretty_print(f_init_wrappers);
    }
  } else {
    // Note: a global function is treated like a static function
    //       with the parent being a nspace object instead of class object
    Template t_register = getTemplate("jsv8_register_static_function");
    t_register.replace("$jsparent", Getattr(current_namespace, NAME_MANGLED))
	.replace("$jsname", state.function(NAME))
	.replace("$jswrapper", state.function(WRAPPER_NAME))
	.trim()
	.pretty_print(f_init_static_wrappers);
  }

  return SWIG_OK;
}

void V8Emitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, MarshallingMode mode, bool is_member, bool is_static) {
  Parm *p;
  String *tm;

  int startIdx = 0;
  if (is_member && !is_static && mode != Ctor) {
    startIdx = 1;
  }
  // store number of arguments for argument checks
  int num_args = emit_num_arguments(parms) - startIdx;
  String *argcount = NewString("");
  Printf(argcount, "%d", num_args);
  Setattr(n, ARGCOUNT, argcount);

  int i = 0;
  for (p = parms; p; i++) {
    String *arg = NewString("");
    String *type = Getattr(p, "type");

    // ignore varargs
    if (SwigType_isvarargs(type))
      break;

    switch (mode) {
    case Getter:
      if (is_member && !is_static && i == 0) {
	Printv(arg, "info.Holder()", 0);
      } else {
	Printf(arg, "args[%d]", i - startIdx);
      }
      break;
    case Function:
      if (is_member && !is_static && i == 0) {
	Printv(arg, "args.Holder()", 0);
      } else {
	Printf(arg, "args[%d]", i - startIdx);
      }
      break;
    case Setter:
      if (is_member && !is_static && i == 0) {
	Printv(arg, "info.Holder()", 0);
      } else {
	Printv(arg, "value", 0);
      }
      break;
    case Ctor:
      Printf(arg, "args[%d]", i);
      break;
    default:
      throw "Illegal state.";
    }

    tm = emitInputTypemap(n, p, wrapper, arg);
    Delete(arg);

    if (tm) {
      p = Getattr(p, "tmap:in:next");
    } else {
      p = nextSibling(p);
    }
  }
}

int V8Emitter::emitNamespaces() {
  Iterator it;
  for (it = First(namespaces); it.item; it = Next(it)) {
    Hash *entry = it.item;
    String *name = Getattr(entry, NAME);
    String *name_mangled = Getattr(entry, NAME_MANGLED);
    String *parent = Getattr(entry, PARENT);
    String *parent_mangled = Getattr(entry, PARENT_MANGLED);

    bool do_create = true;
    bool do_register = true;

    if (Equal(parent, "")) {
      do_register = false;
    }
    // Note: 'exports' is by convention the name of the object where
    // globals are stored into
    if (Equal(name, "exports")) {
      do_create = false;
    }

    if (do_create) {
      // create namespace object and register it to the parent scope
      Template t_create_ns = getTemplate("jsv8_create_namespace");
      t_create_ns.replace("$jsmangledname", name_mangled)
	  .trim()
	  .pretty_print(f_init_namespaces);
    }

    if (do_register) {
      Template t_register_ns = getTemplate("jsv8_register_namespace");
      t_register_ns.replace("$jsmangledname", name_mangled)
	  .replace("$jsname", name)
	  .replace("$jsparent", parent_mangled)
	  .trim();

      // prepend in order to achieve reversed order of registration statements
      String *tmp_register_stmt = NewString("");
      t_register_ns.pretty_print(tmp_register_stmt);
      Insert(f_init_register_namespaces, 0, tmp_register_stmt);
      Delete(tmp_register_stmt);
    }
  }

  return SWIG_OK;
}

JSEmitter *swig_javascript_create_V8Emitter() {
  return new V8Emitter();
}

/**********************************************************************
 * Helper implementations
 **********************************************************************/

JSEmitterState::JSEmitterState()
:  globalHash(NewHash()) {
  // initialize sub-hashes
  Setattr(globalHash, "class", NewHash());
  Setattr(globalHash, "function", NewHash());
  Setattr(globalHash, "variable", NewHash());
}

JSEmitterState::~JSEmitterState() {
  Delete(globalHash);
}

DOH *JSEmitterState::getState(const char *key, bool new_key) {
  if (new_key) {
    Hash *hash = NewHash();
    Setattr(globalHash, key, hash);
  }
  return Getattr(globalHash, key);
}

DOH *JSEmitterState::globals() {
  return globalHash;
}

DOH *JSEmitterState::globals(const char *key, DOH *initial) {
  if (initial != 0) {
    Setattr(globalHash, key, initial);
  }
  return Getattr(globalHash, key);
}

DOH *JSEmitterState::clazz(bool new_key) {
  return getState("class", new_key);
}

DOH *JSEmitterState::clazz(const char *key, DOH *initial) {
  DOH *c = clazz();
  if (initial != 0) {
    Setattr(c, key, initial);
  }
  return Getattr(c, key);
}

DOH *JSEmitterState::function(bool new_key) {
  return getState("function", new_key);
}

DOH *JSEmitterState::function(const char *key, DOH *initial) {
  DOH *f = function();
  if (initial != 0) {
    Setattr(f, key, initial);
  }
  return Getattr(f, key);
}

DOH *JSEmitterState::variable(bool new_key) {
  return getState("variable", new_key);
}

DOH *JSEmitterState::variable(const char *key, DOH *initial) {
  DOH *v = variable();
  if (initial != 0) {
    Setattr(v, key, initial);
  }
  return Getattr(v, key);
}

/*static*/
int JSEmitterState::IsSet(DOH *val) {
  if (!val) {
    return 0;
  } else {
    const char *cval = Char(val);
    if (!cval)
      return 0;
    return (strcmp(cval, "0") != 0) ? 1 : 0;
  }
}

/* -----------------------------------------------------------------------------
 * Template::Template() :  creates a Template class for given template code
 * ----------------------------------------------------------------------------- */

Template::Template(const String *code_) {

  if (!code_) {
    Printf(stdout, "Template code was null. Illegal input for template.");
    SWIG_exit(EXIT_FAILURE);
  }
  code = NewString(code_);
  templateName = NewString("");
}

Template::Template(const String *code_, const String *templateName_) {

  if (!code_) {
    Printf(stdout, "Template code was null. Illegal input for template.");
    SWIG_exit(EXIT_FAILURE);
  }

  code = NewString(code_);
  templateName = NewString(templateName_);
}


/* -----------------------------------------------------------------------------
 * Template::~Template() :  cleans up of Template.
 * ----------------------------------------------------------------------------- */

Template::~Template() {
  Delete(code);
  Delete(templateName);
}

/* -----------------------------------------------------------------------------
 * String* Template::str() :  retrieves the current content of the template.
 * ----------------------------------------------------------------------------- */

String *Template::str() {
  if (js_template_enable_debug) {
    String *pre_code = NewString("");
    String *post_code = NewString("");
    String *debug_code = NewString("");
    Printf(pre_code, "/* begin fragment(\"%s\") */", templateName);
    Printf(post_code, "/* end fragment(\"%s\") */", templateName);
    Printf(debug_code, "%s\n%s\n%s\n", pre_code, code, post_code);

    Delete(code);
    Delete(pre_code);
    Delete(post_code);

    code = debug_code;
  }
  return code;
}

Template & Template::trim() {
  const char *str = Char(code);
  if (str == 0)
    return *this;

  int length = Len(code);
  if (length == 0)
    return *this;

  int idx;
  for (idx = 0; idx < length; ++idx) {
    if (str[idx] != ' ' && str[idx] != '\t' && str[idx] != '\r' && str[idx] != '\n')
      break;
  }
  int start_pos = idx;

  for (idx = length - 1; idx >= start_pos; --idx) {
    if (str[idx] != ' ' && str[idx] != '\t' && str[idx] != '\r' && str[idx] != '\n')
      break;
  }
  int end_pos = idx;

  int new_length = end_pos - start_pos + 1;
  char *newstr = new char[new_length + 1];
  memcpy(newstr, str + start_pos, new_length);
  newstr[new_length] = 0;

  Delete(code);
  code = NewString(newstr);
  delete[]newstr;

  return *this;
}

/* -----------------------------------------------------------------------------
 * Template&  Template::replace(const String* pattern, const String* repl) :
 *
 *  replaces all occurrences of a given pattern with a given replacement.
 *
 *  - pattern:  the pattern to be replaced
 *  - repl:     the replacement string
 *  - returns a reference to the Template to allow chaining of methods.
 * ----------------------------------------------------------------------------- */

Template & Template::replace(const String *pattern, const String *repl) {
  Replaceall(code, pattern, repl);
  return *this;
}

Template & Template::print(DOH *doh) {
  Printv(doh, str(), 0);
  return *this;
}

Template & Template::pretty_print(DOH *doh) {
  Wrapper_pretty_print(str(), doh);
  return *this;
}

Template::Template(const Template & t) {
  code = NewString(t.code);
  templateName = NewString(t.templateName);
}

void Template::operator=(const Template & t) {
  Delete(code);
  Delete(templateName);
  code = NewString(t.code);
  templateName = NewString(t.templateName);
}
