Logo Search packages:      
Sourcecode: kaya version File versions  Download package

Heap.h

#ifndef _HEAP_H // -*-C++-*-
#define _HEAP_H

/**
    Kaya run-time system
    Copyright (C) 2004, 2005 Edwin Brady

    This file is distributed under the terms of the GNU Lesser General
    Public Licence. See COPYING for licence.
*/

using namespace std;

#ifndef WIN32
#define SWPRINTF swprintf
#else
#define SWPRINTF snwprintf
#endif
#ifndef NOCHECK
#define GC_DEBUG
#endif
#ifndef WIN32
#include <pthread.h>
#define GC_PTHREADS
#else
#define GC_WIN32_THREADS
#endif
#include <gc/gc_cpp.h>

//#include <gc/gc_allocator.h>
#include <vector>
#include "sizes.h"
#include "ValueFuns.h"

class VMState;

typedef void(*func)(VMState*);

class Value;
class String;
class Array;
class Exception;
class Union;
class Closure;

// I really shouldn't call this Real! Float/Double better.
class Real : public gc
{
public:
    Real(double n):number(n) {}
    double number;
};

// cached values
extern Value *zero, *one, *minusone;

#define U_TAG(x) ((x->tag_arity) >> 16)
#define U_ARITY(x) ((x->tag_arity) & 65535)
#define THIS_TAG (tag_arity >> 16)
#define THIS_ARITY (tag_arity & 65535)

class Union : public gc_cleanup
{
public:
    // If getargs is true, get arguments from the stack in vm.
    Union(VMState* vm, int tag,int arity, bool getargs = true);
    ~Union() { if (args != NULL) { GC_FREE(args); } }

    bool eq(Union* x);
    int cmp(Union* x);
    int memusage();
    Union* copy(map<Value*,Value*>& done);

    int tag_arity; // tag in top 16 bits, arity in bottom
    Value** args;
};

class Value : public gc
{
public:
    /// Create an initialised value.
    Value(void* ptr, valtype ft):m_val(ptr),m_funtable(ft) {}

    valtype getType() { return m_funtable; }

  // returns a new value pointing to the same thing
    Value* clone() {
      return new Value(m_val,m_funtable);
    }

    /// Get an integer out. Assumes you've checked/know.
    kint getInt() { return (kint)m_val; };
    /// Get a real number out
    double getReal() { 
// FIXME: I don't know if turning this check off is 'safe'. It doesn't
// throw an exception after all. Maybe it should?
#ifndef NOCHECK
      if (m_funtable==KVT_REAL)
          return ((Real*)m_val)->number;
      else
          return 0.0; // Not too much of an overhead here.
#else
          return ((Real*)m_val)->number;
#endif      
    }

    /// Get the function pointer. Assumes you've checked/know.
    Closure* getFunc() { return (Closure*)m_val; }

    /// Get the string
    String* getString();
    /// Get the array.
    Array* getArray();
    /// Get the union.
    Union* getUnion();
    /// Get the exception.
    Exception* getExcept();

    /// Run the closure stored here.
    void runClosure(VMState *vm);

    /// Add more arguments from the stack to the closure stored here.
    void addClosureArgs(VMState *vm, int i);

    /// Coercions
    void int2str();
    void str2int();
    void str2real();
    void chr2str();
    void bool2str();
    void str2chr();
    void int2real();
    void real2int();
    void real2str();

    /// Get the tag out of a union
    int getTag() { return U_TAG(((Union*)m_val)); }


    /// Get the raw pointer out.
    void* getRaw() { return m_val; }


    /// Update to be an integer.
    void setInt(int i)
    {
      m_val=(void*)i;
      m_funtable = KVT_INT;
    }

    /// Update to be an integer and return a pointer
    Value* setIntReturn(int i) {
      setInt(i);
      return this;
    }

    /// Update to be a real
    void setReal(double i);

    /// Update to be a function.
    void setFunc(Closure* f);

    /// Update to be ana rray.
    void setString(String* str)
    {
      m_val=(void*)str;
      m_funtable = KVT_STRING;
    }

    void setArray(Array* a);

    void readString();
    void readInt();

    /// Set a raw pointer.
    void setPtr(Value* p) {
//    cout << "Making " << this << " to " << p->m_val << endl;
//    memcpy(this,p,sizeof(Value*));
      m_val=p->m_val;
      m_funtable=p->m_funtable;
    }

    void addInt(kint x) {
        m_val = (void*)((kint)m_val+x);
    }

    void addVal(Value* v) {
      m_val=(void*)((kint)m_val+(kint)(v->m_val));
    }

    void subVal(Value* v) {
      m_val=(void*)((kint)m_val-(kint)(v->m_val));
    }

    void mulVal(Value* v) {
      m_val=(void*)((kint)m_val*(kint)(v->m_val));
    }

    void divVal(Value* v) {
      m_val=(void*)((kint)m_val/(kint)(v->m_val));
    }

    /// Set an array element.
//    void setIdxPtr(Value* p,unsigned i);

    /// Set a value from the projection of the top stack item
    void project(VMState* vm, int i);
    void fastproject(Value* topitem, int i) {
      Union* top=(Union*)(topitem->m_val);
      Value* arg=top->args[i];
      m_val=arg->m_val;
      m_funtable = arg->m_funtable;
    }

    void fastproject(VMState* vm, int i);
    /// Project an argument out directly.
//    void projarg(int i, int t);

    /// Initialise an array with dimensions taken from the stack.
//    void makeArray(int i,vector<Value*>& stack);

    /// Lookup a value in an array --- resize/create if necessary.
    Value* lookup(VMState* vm, int i);
    /// Get the length of an array
    int length();

    /// Get the function table out
    valtype getFunTable() { return m_funtable; }
    
private:
    void* m_val;
    valtype m_funtable;
};

class String : public gc
{
public:
    String(wchar_t* val);
    String(wchar_t val);
    String(int len);

    wchar_t* getVal() { return m_str; }

    int length() { return wcslen(m_str); }
    wchar_t getIndex(int i) { return m_str[i]; }
    void setIndex(int i,wchar_t c) { m_str[i]=c; }
    void append(String* s);
    void append(wchar_t c);
    void append(wchar_t* s);
    bool eq(String* s);
    bool eq(wchar_t* s);
    int cmp(String* s);
    int hash();

  // debug/marshalling purposes
    int space() { return m_alloc; }

private:
    wchar_t* m_str;
    int m_alloc;
};

struct CallStackEntry : public gc {
    wchar_t* fn_name;
    wchar_t* file;
    int line;
    wchar_t* call_file;
    int call_line;
};

class Exception : public gc
{
public:
    Exception(VMState* vm);
    void show();
    bool eq(Exception* x);
    int cmp(Exception* x);

    void dumpBacktrace();
    
    String* err;
    int code;

    wchar_t* throwfile;
    int throwline;

    // Need a copy of entire backtrace. Ick.
    vector<CallStackEntry> backtrace;
};

#endif

Generated by  Doxygen 1.6.0   Back to index