Skip to content

Commit

Permalink
Removed dependency on khash library by moving all hashes to Go's map …
Browse files Browse the repository at this point in the history
…type.

Also expanded remaining macros so the codebase is now much more verbose, ready for refactoring.
  • Loading branch information
feyeleanor committed Nov 28, 2009
1 parent d8aae1c commit ec62aa4
Show file tree
Hide file tree
Showing 21 changed files with 591 additions and 851 deletions.
1 change: 0 additions & 1 deletion README.rdoc
Expand Up @@ -41,7 +41,6 @@ Inspired by:
* tinypy, http://tinypy.org
* potion, http://github.com/why/potion

kvec.h and khash.h (c) 2008, by Attractive Chaos <attractivechaos@aol.co.uk>
GC Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers
PCRE Copyright (c) 1997-2008 University of Cambridge released under BSD license

Expand Down
72 changes: 41 additions & 31 deletions vm/array.go
@@ -1,62 +1,72 @@
import (
"tr";
"internal";
"container/vector";
)

type Array struct {
type TR_T;
class RubyObject;
ivars *map[string] RubyObject;
kv *Vector;
ivars map[string] RubyObject;
values Vector;
}

func newArray(vm *RubyVM) RubyObject {
return Array{type: TR_T_Array, class: vm.classes[TR_T_Array], ivars: kh_init(RubyObject), kv: Vector.New(0)};
func (vm *RubyVM) newArray() RubyObject {
return Array{type: TR_T_Array, class: vm.classes[TR_T_Array], ivars: make(map[string] RubyObject), values: Vector.New(0)};
}

// Uses variadic ... parameter which replaces the mechanism used by stdarg.h
func newArray2(vm *RubyVM, argc int, ...) RubyObject {
a := newArray(vm);
func (vm *RubyVM) newArray2(args []RubyObject) RubyObject {
a := vm.newArray();
va_list argp;
int i;
va_start(argp, argc);
for (i = 0; i < argc; ++i) a.kv.Push(va_arg(argp, *RubyObject));
for i := 0; i < argc; ++i { a.Push(va_arg(argp, *RubyObject)); }
va_end(argp);
return a;
}

func newArray3(vm *RubyVM, argc int, items []RubyObject) RubyObject {
a := newArray(vm);
for i := 0; i < argc; ++i { a.kv.Push(items[i]) };
func (vm *RubyVM) newArray3(argc int, items []RubyObject) RubyObject {
a := vm.newArray();
for i := 0; i < argc; ++i { a.Push(items[i]) };
return a;
}

func (self *Array) push(vm *RubyVM, x *RubyObject) *RubyObject {
self.kv.Push(x);
func (self *Array) Push(x *RubyObject) *RubyObject {
self.values.Push(x);
return x;
}

func (self *Array) at2index(vm *RubyVM, at *RubyObject) int {
int i = TR_FIX2INT(at);
if (i < 0) i = self.kv.Len() + i;
func (self *Array) at2index(at *RubyObject) int {
i := TR_FIX2INT(at);
if i < 0 { i = self.kv.Len() + i; }
return i;
}

func (self *Array) at(vm *RubyVM, at *RubyObject) *RubyObject {
func (self *Array) At(at *RubyObject) *RubyObject {
i := self.at2index(vm, at);
if i < 0 || i >= self.kv.Len() { return TR_NIL; }
return self.kv.At(i);
if i < 0 || i >= self.values.Len() {
return TR_NIL;
} else {
return self.At(i);
}
}

func (self *Array) set(vm *RubyVM, at, x *RubyObject) *RubyObject {
i := self.at2index(vm, at);
switch {
case i < 0: tr_raise(IndexError, "index %d out of array", i);
case i < self.Len(): self.Set(at, x);
case i > self.Len(): self.AppendVector(Vector.New(at - self.Len()));
fallthrough;
case i == self.Len(): self.Push(x);
case i < 0:
vm.throw_reason = TR_THROW_EXCEPTION;
vm.throw_value = TrException_new(vm, vm.cIndexError, tr_sprintf(vm, "index %d out of array", i));
return TR_UNDEF;

case i < self.Len():
self.Set(at, x);

case i > self.Len():
self.AppendVector(Vector.New(at - self.Len()));
fallthrough;

case i == self.Len():
self.Push(x);
}
return x;
}
Expand All @@ -66,10 +76,10 @@ func (self *Array) length(vm *RubyVM) RubyObject {
}

void TrArray_init(vm *RubyVM) {
c := vm.classes[TR_T_Array] = Object_const_set(vm, vm.self, tr_intern(Array), newClass(vm, tr_intern(Array), vm.classes[TR_T_Object]));
tr_def(c, "length", TrArray_length, 0);
tr_def(c, "size", TrArray_length, 0);
tr_def(c, "<<", TrArray_push, 1);
tr_def(c, "[]", TrArray_at, 1);
tr_def(c, "[]=", TrArray_set, 2);
c := vm.classes[TR_T_Array] = Object_const_set(vm, vm.self, TrSymbol_new(vm, Array), newClass(vm, TrSymbol_new(vm, Array), vm.classes[TR_T_Object]));
c.add_method(vm, TrSymbol_new(vm, "length"), newMethod(vm, (TrFunc *)TrArray_length, TR_NIL, 0));
c.add_method(vm, TrSymbol_new(vm, "size"), newMethod(vm, (TrFunc *)TrArray_length, TR_NIL, 0));
c.add_method(vm, TrSymbol_new(vm, "<<"), newMethod(vm, (TrFunc *)Push, TR_NIL, 1));
c.add_method(vm, TrSymbol_new(vm, "[]"), newMethod(vm, (TrFunc *)TrArray_at, TR_NIL, 1));
c.add_method(vm, TrSymbol_new(vm, "[]="), newMethod(vm, (TrFunc *)TrArray_set, TR_NIL, 2));
}
47 changes: 23 additions & 24 deletions vm/block.go
@@ -1,45 +1,44 @@
import (
"tr";
"opcode";
"internal";
"fmt";
"container/vector";
)

type Block struct {
// static
k *Vector;
strings *StringVector;
locals *Vector;
upvals *Vector;
code *Vector;
defaults *IntVector;
k Vector;
strings StringVector;
locals Vector;
upvals Vector;
code Vector;
defaults Vector;
blocks []Block;
regc int;
argc int;
arg_splat int;
filename *RubyObject;
filename RubyObject;
line int;
parent *Block;
// dynamic
sites CallSiteVector;
sites Vector;
}


func newBlock(compiler *Compiler, parent *Block) *Block {
block = new(Block);
block.defaults = IntVector.New(0)
block.strings = StringVector.New(0)
block.filename = compiler.filename;
block.line = 1;
block.regc = 0;
block.argc = 0;
block.parent = parent;
block.k = Vector.New(0);
block.code = Vector.New(0);
block.locals = Vector.New(0);
block.sites = Vector.New(0);
return block;
func (compiler *Compiler) newBlock(parent *Block) *Block {
return Block{ parent: parent,
k: Vector.New(0),
strings: StringVector.new(0),
locals: Vector.new(0),
upvals: Vector.new(0),
code: Vector.new(0),
defaults: Vector.new(0),
sites: Vector.new(0),
blocks: Vector.new(0),
regc: 0,
argc: 0,
line: 1,
filename: compiler.filename,
}
}

func (b *Block) dump(vm *RubyVM, level int) RubyObject {
Expand Down
33 changes: 16 additions & 17 deletions vm/call.go
Expand Up @@ -4,18 +4,6 @@ import (
"bytes";
)

type Frame struct {
closure *Closure;
method *Method; // current called method
stack *RubyObject;
upvals *RubyObject;
self *RubyObject;
class *RubyObject;
filename *RubyObject;
line size_t;
previous *Frame;
}

func (self *Method) call(vm *RubyVM, receiver *RubyObject, argc int, args []RubyObject, splat int, closure *Closure) RubyObject {
if TR_IMMEDIATE(receiver) {
receiver_class := vm.classes[Object_type(vm, receiver)];
Expand All @@ -25,9 +13,13 @@ func (self *Method) call(vm *RubyVM, receiver *RubyObject, argc int, args []Ruby

// push a frame
vm.cf++;
if vm.cf >= TR_MAX_FRAMES { tr_raise(SystemStackError, "Stack overflow"); }
if vm.cf >= TR_MAX_FRAMES {
vm.throw_reason = TR_THROW_EXCEPTION;
vm.throw_value = TrException_new(vm, vm.cSystemStackError, tr_sprintf(vm, "Stack overflow"));
return TR_UNDEF;
}

frame := Frame{previous: vm.frame, method: nil, filename: nil, line: 0, self: receiver, class: receiver_class, closure: closure}
frame := newFrame(receiver, receiver_class, closure);
if vm.cf == 0 { vm.top_frame = frame; }
vm.frame = frame;
vm.throw_reason = vm.throw_value = 0;
Expand All @@ -42,15 +34,19 @@ func (self *Method) call(vm *RubyVM, receiver *RubyObject, argc int, args []Ruby
splatedn := splated.kv.Len();
new_args := make([]OBJ, argc)
memcpy(new_args, args, sizeof(OBJ) * (argc - 1));
memcpy(new_args + argc - 1, &splated.kv.At(0), sizeof(OBJ) * splatedn);
memcpy(new_args + argc - 1, &splated.values.At(0), sizeof(OBJ) * splatedn);
argc += splatedn-1;
args = new_args;
}

if (m.arity == -1) {
result := function(vm, receiver, argc, args);
} else {
if method.arity != argc { tr_raise(ArgumentError, "Expected %d arguments, got %d.", frame.method.arity, argc); }
if method.arity != argc {
vm.throw_reason = TR_THROW_EXCEPTION;
vm.throw_value = TrException_new(vm, vm.cArgumentError, tr_sprintf(vm, "Expected %d arguments, got %d.", frame.method.arity, argc));
return TR_UNDEF;
}
switch argc {
case 0: result := function(vm, receiver);
case 1: result := function(vm, receiver, args[0]);
Expand All @@ -63,7 +59,10 @@ func (self *Method) call(vm *RubyVM, receiver *RubyObject, argc int, args []Ruby
case 8: result := function(vm, receiver, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7]);
case 9: result := function(vm, receiver, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8]);
case 10: result := function(vm, receiver, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9]);
default: tr_raise(ArgumentError, "Too much arguments: %d, max is %d for now.", argc, 10);
default:
vm.throw_reason = TR_THROW_EXCEPTION;
vm.throw_value = TrException_new(vm, vm.cArgumentError, tr_sprintf(vm, "Too many arguments: %d, max is %d for now.", argc, 10));
return TR_UNDEF;
}
}

Expand Down

0 comments on commit ec62aa4

Please sign in to comment.