Skip to content

Commit

Permalink
First commit
Browse files Browse the repository at this point in the history
  • Loading branch information
jmolloy committed Mar 21, 2011
0 parents commit 6cc9ee3
Show file tree
Hide file tree
Showing 44 changed files with 3,746 additions and 0 deletions.
33 changes: 33 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
cmake_minimum_required(VERSION 2.6)

project(FastPy)
set(FastPy_VERSION_MAJOR 0)
set(FastPy_VERSION_MINOR 1)

set(SRCS
src/Constant.cc
src/Type.cc
src/constants.cc
src/variables.cc
src/main.cc
src/Code.cc
src/Marshal.cc
src/Function.cc
src/BasicBlock.cc
src/OperandStack.cc
src/Instruction.cc
src/instructions.cc
src/Module.cc
src/LJ_Codegen.cc
src/PyDict.cc
src/PyString.cc
src/PyNone.cc
src/PyRuntime.cc
src/PyFunction.cc
)

find_library(LIBJIT jit)

include_directories(include)
add_executable(fastpy ${SRCS})
target_link_libraries(fastpy ${LIBJIT})
127 changes: 127 additions & 0 deletions include/BasicBlock.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
/**@file BasicBlock.h
* @author James Molloy <james.molloy@arm.com>
* @date Sun Dec 5 13:16:52 2010
* @brief The nodes in the control flow graph. */

#ifndef BASIC_BLOCK_H
#define BASIC_BLOCK_H

#include <Variable.h>
#include <Constant.h>
#include <Value.h>
#include <list>
#include <map>
#include <vector>

#include <jit/jit.h>

class OperandStack;
class Function;
class Instruction;
class Cell;

/** A block is also a value (used as a jump target) */
class BasicBlock : public Value {
public:
/** Default constructor. */
BasicBlock(Function *parent);
~BasicBlock();

/** Loads the argument as a constant, pushing onto the stack. */
void LoadConstant(Constant *arg, int &id);
/** Loads the named global variable, pushing onto the stack. */
void LoadGlobal(std::string arg, int &id);
/** Loads the named local (or parameter) variable, pushing onto the stack. */
void LoadLocal(std::string arg, int &id);

/** Stores TOS to the named global. */
void StoreGlobal(std::string arg, int &id);
/** Stores TOS to the named local. */
void StoreLocal(std::string arg, int &id);

/** Creates a new function or closure, with the given number of default parameters, fished from the stack BEFORE
the code object is expected. */
void BindClosure(long arg, int &id);

/** Performs a "standard" function call, with the given number of positional arguments and keyword arguments. */
void Call(unsigned char num_positional,
unsigned char num_keywords, int &id);

/** Pops TOS */
void Pop(int &id);

/** Returns TOS. This is a terminator instruction. */
void Return(int &id);

/** Conditional jump. This is a terminator instruction.
@param alwaysPop If true, Pop the TOS always; else only pop the item if the branch was NOT taken.
@param condition True or false comparison of TOS.
@param trueBranch Block to branch to if the condition succeeds.
@param falseBranch Block to branch to if the condition fails. */
void ConditionalJump(bool alwaysPop, bool condition, BasicBlock *trueBranch, BasicBlock *falseBranch, int &id);

/** Jump to block. This is a terminator instruction. */
void Jump(BasicBlock *branch, int &id);

/** Perform a binary operation on TOS and TOS1 */
void BinaryOp(std::string op, int &id);

/** Get an attribute of TOS. */
void GetAttr(std::string attr, int &id);

void Dup();

void BuildTuple(int n, int &id);

void BeginCatch(int &id);

void Compare(int op, int &id);

void PrintItem(int &id);
void PrintNewline(int &id);

void ReRaise(int &id);

virtual const std::string Repr();

void SetUnwindBlock(BasicBlock *uw) {
m_unwind_block = uw;
}

void LJ_Codegen();
jit_label_t *LJ_GetLabel();

protected:
char GetWart() {
return ':';
}

private:
/** Successor blocks */
BasicBlock *m_successors[2];

/** How many successors the block has. */
int m_num_successors;

/** The stack - only used during block creation. */
OperandStack *m_stack;

std::map<std::string,Value*> m_globals, m_locals;

/** Function parent. */
Function *m_fn;

/** All instructions in the block. */
std::vector<Instruction*> m_all_instructions;

std::vector<Instruction*> m_dfg_roots;
std::vector<Value*> m_dfg_leafs;
std::map<std::string,Value*> m_store_global_roots;
std::map<std::string,Value*> m_store_local_roots;

BasicBlock *m_unwind_block;

jit_label_t m_jit_label;
};

#endif
Empty file added include/CodeGenerator.h
Empty file.
40 changes: 40 additions & 0 deletions include/Constant.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#ifndef CONSTANT_H
#define CONSTANT_H

#include <Value.h>
#include <inttypes.h>
#include <Type.h>
#include <cassert>
#include <sstream>

/** A constant is a Value in that it is a piece of data and can be passed around as such. */
class Constant : public Value {
public:
static class ConstantBool *GetBool(bool b);
static class ConstantInt *GetInt(int n);
static class ConstantInt64 *GetInt64(int64_t n);
static class ConstantFloat *GetFloat(double n);
static class ConstantString *GetString(const std::string &str);
static class ConstantNone *GetNone();


// Constants are simple enough that we should show their actual value.
virtual std::string RefRepr() {
return Repr();
}

static Constant *From(Object *o) {
Constant *s = dynamic_cast<Constant*>(o);
assert(s);
return s;
}



protected:
virtual char GetWart() {
return '@';
}
};

#endif
42 changes: 42 additions & 0 deletions include/Errors.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/**@file Errors.h
* @author James Molloy <james.molloy@arm.com>
* @date Sat Dec 4 13:21:27 2010
* @brief Defines the general "Error" class used for passing errors around. */

#ifndef ERRORS_H
#define ERRORS_H

#include <string>
#include <iostream>

#include <stdlib.h>

class Errors {
public:
Errors() :
m_error(false), m_descr() {
}

/** Report an error - this does not get printed, just stored in the object. */
void Error(std::string descr) {
m_error = true;
m_descr = descr;
}

/** Return true if an error has occurred. */
bool WasError() {
return m_error;
}

/** Print error to stderr and exit. */
void Garble() {
std::cerr << "Error: " << m_descr << std::endl;
exit(1);
}

private:
bool m_error;
std::string m_descr;
};

#endif
68 changes: 68 additions & 0 deletions include/Function.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#ifndef FUNCTION_H
#define FUNCTION_H

#include <Constant.h>
#include <map>
#include <vector>
#include <string>

#include <jit/jit.h>

class Cell;
class BasicBlock;
class Code;
class Module;

class Function : public Constant {
public:
/** Creates a new function with the given identifying name. */
Function(std::string name, Code *code, Module *module);
~Function();

/** Returns the entry block of this function. */
BasicBlock *GetEntryBlock() {
return m_entry_block;
}

Code *GetCode() {
return m_code;
}

Module *GetModule() {
return m_module;
}

void AddBlock(BasicBlock *b) {
m_blocks.push_back(b);
}

const std::string &GetName() {
return m_name;
}

virtual const std::string Repr();

jit_function_t LJ_Codegen(jit_context_t ctx=0);

private:
/** Entry block */
BasicBlock *m_entry_block;

/** All basic blocks. */
std::vector<BasicBlock*> m_blocks;

/** Function name */
std::string m_name;

/** Python code object */
Code *m_code;

Module *m_module;

/** Named arguments */
std::vector<std::string> m_arguments;

jit_function_t m_jit_function;
};

#endif
28 changes: 28 additions & 0 deletions include/Instruction.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#ifndef INSTRUCTION_H
#define INSTRUCTION_H

#include <Value.h>

#include <vector>
#include <iostream>

/** The instruction class is a superset of all Python instructions.
They are objects because code is data, obviously. */
class Instruction : public Value {
public:
Instruction(const char *mnemonic, int id);

virtual const std::string Repr();

protected:
virtual char GetWart() {
return '%';
}

const char *m_mnemonic;
std::vector<Value*> m_args;

};

#endif
37 changes: 37 additions & 0 deletions include/Marshal.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/**@file Marshal.h
* @author James Molloy <james.molloy@arm.com>
* @date Sat Dec 4 13:11:06 2010
* @brief Provides the interface for the Marshal, which reads CPython bytecode. */

#ifndef MARSHAL_H
#define MARSHAL_H

#include <stdint.h>
#include <string>

class Object;
class Errors;

class Marshal {
public:
Marshal();

/** Reads an object from the given filename, garbling if there are errors. */
Object *ReadFile(std::string fname);

/** Reads an object from the given string, garbling if there are errors. */
Object *ReadString(std::string str);

/** Lower-level routine - reads an object from an istream. */
Object *ReadObject(std::istream &is, Errors &e);

private:
std::string ReadString(std::istream &is, int len);
int8_t ReadByte(std::istream &is);
int16_t ReadShort(std::istream &is);
long ReadLong(std::istream &is);
int64_t ReadLong64(std::istream &is);
double ReadFloat(std::istream &is);
};

#endif
Loading

0 comments on commit 6cc9ee3

Please sign in to comment.