/* -----------------------------------------------------------------------------
 * 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 having 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:
      Printf(stderr, "Illegal MarshallingMode.");
      SWIG_exit(EXIT_FAILURE);
    }
    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:
      Printf(stderr, "Illegal MarshallingMode.");
      SWIG_exit(EXIT_FAILURE);
    }

    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);
}
