Skip to content
Browse files

omg

  • Loading branch information...
1 parent 49f9eee commit abd28d9428d7a65822428503d1407ef7e1b8fb31 @txus committed
View
8 compiler/Rakefile
@@ -0,0 +1,8 @@
+require 'rake/testtask'
+Rake::TestTask.new do |t|
+ t.libs << "test"
+ t.test_files = FileList['test/**/*_test.rb']
+ t.verbose = true
+end
+
+task :default => :test
View
20 compiler/Readme.md
@@ -0,0 +1,20 @@
+# Terror compiler
+
+This is a proof-of-concept compiler written in Ruby (although it runs only on
+Rubinius) that compiles a subset of Ruby to Terror bytecode.
+
+Since writing a compiler targeting a register-based VM is not trivial to me,
+register allocation is rather naive and non-efficient. Basically, reusability
+of registers is close to zero. If you have a suggestion about this (some book
+or article regarding this topic) I'd be really happy if you pointed it out for
+me to read about this.
+
+## Usage
+
+ $ rvm use rbx-head
+ $ bin/terror examples/hello_world.rb > myprogram.tvm
+
+Or just use the easy shell script to compile and run on the fly:
+
+ $ rvm use rbx-head
+ $ ./tvm examples/hello_world.rb
View
12 compiler/bin/terror
@@ -0,0 +1,12 @@
+#!/usr/bin/env rbx
+$: << 'lib'
+require 'terror'
+
+unless ARGV.first
+ puts "Terror #{Terror::VERSION}\n================"
+ puts "\tUsage: terror my_file.rb > my_file.tc"
+ exit(1)
+end
+
+verbose = ARGV[1] == '-v'
+puts Terror.parse_file(ARGV[0], verbose)
View
1 compiler/examples/numbers.rb
@@ -0,0 +1 @@
+puts (3-1) + (3 * (9/3))
View
15 compiler/examples/objects.rb
@@ -0,0 +1,15 @@
+parent = Object.clone()
+parent.age = 50
+parent.money = 1000
+child = parent.clone()
+child.age = 25
+
+print "Parent age:"
+puts parent.age
+print "Parent money:"
+puts parent.money
+
+print "Child age:"
+puts child.age
+print "Child money:"
+puts child.money
View
4 compiler/examples/primitives.rb
@@ -0,0 +1,4 @@
+puts VM.primitive[:+].apply(3, 4)
+puts VM.primitive[:-].apply(4, 3)
+puts VM.primitive[:*].apply(4, 3)
+puts VM.primitive[:/].apply(4, 2)
View
1 compiler/kernel/prelude.rb
@@ -0,0 +1 @@
+Object.prelude_ran = true
View
13 compiler/lib/terror.rb
@@ -0,0 +1,13 @@
+require "terror/version"
+require "terror/core_ext/node"
+require "terror/visitor"
+
+module Terror
+ def self.parse_file(file, verbose=false)
+ ast = Rubinius::Melbourne19.parse_file(ARGV[0])
+ visitor = Terror::Visitor.new
+ ast.lazy_visit(visitor, ast)
+ puts visitor.generator.disassemble if verbose
+ puts visitor.finalize
+ end
+end
View
37 compiler/lib/terror/branching.rb
@@ -0,0 +1,37 @@
+module Terror
+ module Branching
+ class Label
+ def initialize(generator)
+ @g = generator
+ @now = 0
+ @then = 0
+ end
+
+ def start!
+ @now = @g.ip
+ self
+ end
+
+ def set!
+ @then = @g.ip
+ self
+ end
+
+ def offset
+ @then - @now
+ end
+
+ def to_i
+ offset
+ end
+
+ def ==(other)
+ to_i == other.to_i
+ end
+ end
+
+ def new_label
+ Label.new(self)
+ end
+ end
+end
View
19 compiler/lib/terror/core_ext/node.rb
@@ -0,0 +1,19 @@
+module Rubinius
+ module AST
+ class Node
+ # Public: Works like #visit, but it doesn't visit the children just yet;
+ # instead, lets the visitor decide when and how to do it.
+ #
+ # visitor - The visitor object. It must respond to methods named after the
+ # node names.
+ #
+ # Returns nothing.
+ def lazy_visit(visitor, parent=nil, indent=false)
+ args = [self.node_name, self, parent]
+ args.push true if indent
+
+ visitor.__send__ *args
+ end
+ end
+ end
+end
View
138 compiler/lib/terror/generator.rb
@@ -0,0 +1,138 @@
+require 'terror/instructions'
+require 'terror/branching'
+
+module Terror
+ class Generator
+ include Instructions
+ include Branching
+ attr_reader :literals, :locals, :ip
+
+ Local = Struct.new(:name)
+
+ def initialize
+ @locals = []
+ @literals = []
+ @ip = 0
+ end
+
+ def disassemble
+ instructions.map(&:to_s).join "\n"
+ end
+
+ def encode
+ # Always return nil at the end of a script
+ pushnil
+ ret
+
+ output = "_main\n"
+ output << ":%i:%i\n" % [
+ @literals.size,
+ @ip
+ ]
+ output << @literals.join("\n")
+ output << "\n"
+ # instructions.each do |i|
+ # p i
+ # end
+ output << instructions.map(&:encode).flatten.join("\n")
+ output
+ end
+
+ def push(value)
+ @ip += 1
+ _push literal(value)
+ end
+
+ def pop
+ @ip += 1
+ _pop
+ end
+
+ def pushtrue
+ @ip += 1
+ _pushtrue
+ end
+
+ def pushfalse
+ @ip += 1
+ _pushfalse
+ end
+
+ def pushnil
+ @ip += 1
+ _pushnil
+ end
+
+ def jmp(label)
+ label.start!
+ @ip += 1
+ _jmp label
+ end
+
+ def jif(label)
+ label.start!
+ @ip += 1
+ _jif label
+ end
+
+ def jit(label)
+ label.start!
+ @ip += 1
+ _jit label
+ end
+
+ def pushself
+ @ip += 1
+ _pushself
+ end
+
+ def pushlocal(name)
+ @ip += 1
+ _pushlocal local(name)
+ end
+
+ def setlocal(name)
+ @ip += 1
+ idx = local(name)
+ _setlocal idx
+ end
+
+ def getslot(name)
+ @ip += 1
+ _getslot literal(name)
+ end
+
+ def setslot(name)
+ @ip += 1
+ _setslot literal(name)
+ end
+
+ def send_message(msg, argc)
+ @ip += 1
+ _send literal(msg), argc
+ end
+
+ def ret
+ @ip += 1
+ _ret
+ end
+
+ private
+
+ def local name
+ @locals.index { |l| l.name == name } or begin
+ @locals.push Local.new name
+ @locals.size - 1
+ end
+ end
+
+ def literal value
+ val = value.is_a?(Numeric) ? value : "\"#{value}"
+
+ @literals.index(val) or begin
+ @literals.push val
+ @literals.index(val)
+ end
+ end
+ end
+end
View
139 compiler/lib/terror/instructions.rb
@@ -0,0 +1,139 @@
+module Terror
+ module Instructions
+ module Instruction
+ # Internal: Add a :value accessor to the host class when included.
+ def self.included(base)
+ class << base; attr_accessor :value; end
+ end
+
+ # Public: encodes an Instruction into a compact 32-bit format.
+ #
+ # Returns a String encoded in hexadecimal format.
+ def encode
+ [self.class.value].tap do |ary|
+ ary.push(a) if respond_to?(:a)
+ ary.push(b) if respond_to?(:b)
+ end
+ end
+
+ # Public: Disassembles the instruction to a readable format.
+ #
+ # Returns a readable String representing the instruction and its operands.
+ def to_s
+ name = self.class.name.split('::').last
+ output = [
+ name.upcase,
+ # self.class.value
+ ] + operands
+
+ output.join " "
+ end
+
+ def inspect
+ to_s
+ end
+
+ # Public: Checks for equality between instructions.
+ #
+ # Returns whether or not the two instructions are equal.
+ def ==(other)
+ self.class.value == other.class.value && operands == other.operands
+ end
+
+ # Internal: Returns the operands of the instruction.
+ def operands
+ length = if respond_to?(:members)
+ members.length
+ else
+ 0
+ end
+ [:a, :b].take(length).map do |operand|
+ __send__ operand
+ end
+ end
+ end
+
+ # Internal: Little DSL helper that generates a method for a given opcode,
+ # value and arity.
+ #
+ # name - the Symbol opcode name (:move, :loadi...)
+ # value - the Fixnum opcode value (0x00, 0x01...)
+ # arity - the Fixnum number of operands that the instruction accepts
+ #
+ # Example
+ #
+ # op :move, 0x00, 2
+ #
+ # # Generates:
+ # klass = Class.new Struct.new(:a, :b)
+ # klass.value # => 0x00
+ # define_method(:move) do |*args|
+ # Move.new(*args)
+ # end
+ #
+ def self.op(name, value, arity)
+ operands = [:a, :b].take(arity)
+
+ if arity > 0
+ klass = Class.new(Struct.new(*operands)) { include Instruction }
+ else
+ klass = Class.new { include Instruction }
+ end
+ klass.value = value
+
+ Instructions.const_set name.to_s.capitalize, klass
+
+ define_method(:"_#{name}") do |*args|
+ instruction = Instructions.const_get(name.capitalize)
+ if arity > 0
+ emit instruction.new(*args)
+ else
+ emit instruction.new
+ end
+ end
+ end
+
+ # Internal: Rmits an instruction.
+ #
+ # instruction - the Instruction to emit.
+ #
+ # Returns nothing.
+ def emit(instruction)
+ instructions << instruction
+ instruction
+ end
+
+ # op :opcode, value, arity
+ op :noop, 0x00, 0
+
+ op :pushself, 0x10, 0
+ op :push, 0x11, 1
+ op :pushtrue, 0x12, 0
+ op :pushfalse, 0x13, 0
+ op :pushnil, 0x14, 0
+
+ op :pushlocal, 0x20, 1
+ op :setlocal, 0x21, 1
+
+ op :add, 0x22, 0
+
+ op :jmp, 0x30, 1
+ op :jif, 0x31, 1
+ op :jit, 0x32, 1
+
+ op :getslot, 0x40, 1
+ op :setslot, 0x41, 1
+
+ op :pop, 0x42, 0
+
+ op :send, 0x80, 2
+ op :ret, 0x90, 0
+
+ op :dump, 0x91, 0
+
+ # Public: Returns the Array of emitted instructions.
+ def instructions
+ @instructions ||= []
+ end
+ end
+end
View
3 compiler/lib/terror/version.rb
@@ -0,0 +1,3 @@
+module Terror
+ VERSION = "0.0.1"
+end
View
154 compiler/lib/terror/visitor.rb
@@ -0,0 +1,154 @@
+require 'terror/generator'
+
+module Terror
+ class Visitor
+ attr_reader :generator
+
+ def initialize(g=Generator.new)
+ @generator = g
+ @slots = {}
+ end
+ alias_method :g, :generator
+
+ def fixnum_literal(node, parent)
+ g.push node.value
+ end
+
+ def local_variable_assignment(node, parent)
+ node.value.lazy_visit self, node
+ g.setlocal node.name
+ end
+
+ def local_variable_access(node, parent)
+ g.pushlocal node.name
+ end
+
+ def block(node, parent)
+ node.array.each do |expression|
+ expression.lazy_visit self, node
+ end
+ end
+
+ def nil_literal(node, parent)
+ g.pushnil
+ end
+
+ def true_literal(node, parent)
+ g.pushtrue
+ end
+
+ def false_literal(node, parent)
+ g.pushfalse
+ end
+
+ def string_literal(node, parent)
+ g.push node.string
+ end
+
+ def send(node, parent)
+ if node.receiver.respond_to?(:name) && @slots[node.receiver.name] && @slots[node.receiver.name].include?(node.name)
+ return slot_retrieval(node, parent)
+ end
+
+ node.receiver.lazy_visit self, node
+ g.send_message node.name, 0
+ end
+
+ def send_with_arguments(node, parent)
+ node.receiver.lazy_visit self, node
+ argc = node.arguments.array.count
+ node.arguments.lazy_visit self
+
+ g.send_message node.name, argc
+ end
+
+ def actual_arguments(node, parent)
+ node.array.each do |argument|
+ argument.lazy_visit(self, parent)
+ end
+ end
+
+ def self(node, parent)
+ g.pushself
+ end
+
+ def if(node, parent)
+ node.condition.lazy_visit(self, parent)
+
+ body_val = else_val = nil
+
+ done = g.new_label
+ else_label = g.new_label
+
+ g.jif else_label
+
+ node.body.lazy_visit(self, parent)
+ g.jmp done
+
+ else_label.set!
+
+ node.else.lazy_visit(self, parent)
+
+ done.set!
+ end
+
+ def slot_retrieval(node, parent)
+ node.receiver.lazy_visit self
+ g.getslot node.name
+ end
+
+ def attribute_assignment(node, parent)
+ receiver_name = node.receiver.name
+ attribute_name = node.name[0..-2].to_sym
+ @slots[receiver_name] ||= []
+ @slots[receiver_name] << attribute_name
+
+ node.receiver.lazy_visit self
+ node.arguments.array.first.lazy_visit self
+ g.setslot attribute_name
+ end
+
+ # def array_literal(node, parent)
+ # first = nil
+ # node.body.each do |element|
+ # slot = element.lazy_visit self
+ # # Save the register of only the first element
+ # first ||= slot
+ # end
+ # g.makearray first, node.body.count
+ # end
+
+ # def empty_array(node, parent)
+ # g.makearray 0, 0
+ # end
+
+ # def hash_literal(node, parent)
+ # slf = g.loadself
+ # meth = g.loads :hash
+
+ # # Create an array
+ # first = nil
+ # node.array.each do |element|
+ # slot = element.lazy_visit self
+ # # Save the register of only the first element
+ # first ||= slot
+ # end
+ # ary = g.makearray first, node.array.count
+
+ # g.send_message slf, meth, ary
+ # end
+
+ def symbol_literal(node, parent)
+ g.push node.value
+ end
+
+ def constant_access(node, parent)
+ g.pushself
+ g.getslot node.name
+ end
+
+ def finalize
+ g.encode
+ end
+ end
+end
View
115 compiler/test/terror/generator_test.rb
@@ -0,0 +1,115 @@
+$: << 'lib'
+require 'terror/generator'
+require 'minitest/autorun'
+
+module Terror
+ describe Generator do
+ before do
+ @g = Generator.new
+ end
+
+ describe 'branching labels' do
+ it 'works' do
+ @g.push(3)
+ label = @g.new_label
+ @g.push(3)
+ @g.jmp label
+ @g.push(3)
+ @g.push(3)
+ label.set!
+
+ label.offset.must_equal 3
+ end
+ end
+
+ describe '#push' do
+ it 'pushes an integer literal to the stack' do
+ @g.push(3)
+ @g.literals.must_equal [3]
+ end
+
+ it 'pushes a string literal to the stack' do
+ @g.push('foo')
+ @g.literals.must_equal ['"foo']
+ end
+ end
+
+ describe '#pushtrue' do
+ it 'pushes true' do
+ @g.must_respond_to(:pushtrue)
+ end
+ end
+
+ describe '#pushfalse' do
+ it 'pushes false' do
+ @g.must_respond_to(:pushfalse)
+ end
+ end
+
+ describe '#pushnil' do
+ it 'pushes nil' do
+ @g.must_respond_to(:pushnil)
+ end
+ end
+
+ describe '#jmp' do
+ it 'performs an inconditional jump' do
+ @g.jmp(@g.new_label)
+ end
+ end
+
+ describe '#jif' do
+ it 'jumps a instructions if TOS is falsy' do
+ @g.jif(@g.new_label)
+ end
+ end
+
+ describe '#jit' do
+ it 'jumps to a label if TOS is truthy' do
+ @g.jit(@g.new_label)
+ end
+ end
+
+
+
+ describe '#pushlocal' do
+ it 'pushes a local variable' do
+ @g.pushlocal :foo
+ @g.locals.first.name.must_equal :foo
+ end
+ end
+
+ describe '#setlocal' do
+ it 'sets a local variable' do
+ @g.push 42
+ @g.setlocal :foo
+ local = @g.locals[0]
+ local.name.must_equal :foo
+ end
+ end
+
+ describe '#getslot' do
+ it 'pushes a slot from an object' do
+ @g.getslot :foo
+ end
+ end
+
+ describe '#setslot' do
+ it 'sets a slot from an object' do
+ @g.setslot :foo
+ end
+ end
+
+ describe '#send' do
+ it 'sends a message to an object' do
+ @g.send_message(:foo, 3)
+ end
+ end
+
+ describe '#ret' do
+ it 'returns from the active call frame' do
+ @g.ret
+ end
+ end
+ end
+end
View
53 compiler/test/terror/instructions_test.rb
@@ -0,0 +1,53 @@
+$: << 'lib'
+require 'terror/instructions'
+require 'minitest/autorun'
+
+module Terror
+ describe Instructions do
+ before do
+ @g = Class.new { include Instructions }.new
+ end
+
+ describe 'instructions with 2 operands' do
+ %w(send).each do |instruction|
+ describe instruction do
+ it "#{instruction} is encoded correctly" do
+ inst = @g.__send__ :"_#{instruction}", 2, 3
+ value = inst.class.value
+
+ inst.operands.must_equal [2, 3]
+ inst.encode.must_equal [value, 2, 3]
+ end
+ end
+ end
+ end
+
+ describe 'instructions with 1 operand' do
+ %w(push pushlocal setlocal jmp jif jit getslot setslot).each do |instruction|
+ describe instruction do
+ it "#{instruction} is encoded correctly" do
+ inst = @g.__send__ "_#{instruction}", 2
+ value = inst.class.value
+
+ inst.operands.must_equal [2]
+ inst.encode.must_equal [value, 2]
+ end
+ end
+ end
+ end
+
+ describe 'instructions with no operands' do
+ %w(noop pushself pushtrue pushfalse pushnil add pop ret dump).each do |instruction|
+ describe instruction do
+ it "#{instruction} is encoded correctly" do
+ inst = @g.__send__ :"_#{instruction}"
+ value = inst.class.value
+
+ inst.operands.must_equal []
+ inst.encode.must_equal [value]
+ end
+ end
+ end
+ end
+ end
+end
View
157 compiler/test/terror/visitor_test.rb
@@ -0,0 +1,157 @@
+$: << 'lib'
+require 'terror/visitor'
+require 'terror/core_ext/node'
+require 'minitest/autorun'
+
+module Terror
+ describe Visitor do
+ include Instructions
+ def visit(code)
+ ast = Rubinius::Melbourne19.parse_string(code)
+ visitor = Visitor.new
+ ast.lazy_visit(visitor, ast)
+ visitor.generator
+ end
+
+ def compiles(code, &block)
+ g = Generator.new
+ g.instance_eval(&block)
+ visit(code).instructions.must_equal g.instructions
+ end
+
+ it 'assigns local variables' do
+ compiles("a = 3; b = 3; c = 4") do
+ _push 0
+ _setlocal 0
+ _push 0
+ _setlocal 1
+ _push 1
+ _setlocal 2
+ end
+ end
+
+ it 'remembers local names' do
+ compiles("a = 3; a = 4") do
+ _push 0
+ _setlocal 0
+ _push 1
+ _setlocal 0
+ end
+ end
+
+ it 'compiles nested assignment' do
+ compiles("a = b = 3") do
+ _push 0
+ _setlocal 0
+ _setlocal 1
+ end
+ end
+
+ it 'compiles local variable access' do
+ compiles("a = 3; a") do
+ _push 0
+ _setlocal 0
+ _pushlocal 0
+ end
+ end
+
+ it 'compiles boolean literals' do
+ compiles("true") do
+ _pushtrue
+ end
+
+ compiles("false") do
+ _pushfalse
+ end
+
+ compiles("nil") do
+ _pushnil
+ end
+ end
+
+ it 'compiles string literals' do
+ compiles("'hey'") do
+ _push 0
+ end
+ end
+
+ it 'compiles messages without arguments' do
+ compiles("a") do
+ _pushself
+ _send 0, 0
+ end
+ end
+
+ it 'compiles messages with arguments' do
+ compiles("puts 1, 2, 3") do
+ _pushself
+ _push 0
+ _push 1
+ _push 2
+ _send 3, 3
+ end
+ end
+
+ describe 'branching' do
+ it 'compiles if' do
+ compiles("if 1 then 3; end") do
+ _push 0
+ _jif 3
+ _push 1
+ _jmp 2
+ _pushnil
+ end
+ end
+
+ it 'compiles if-else' do
+ compiles("if 1 then 3 else 4 end") do
+ _push 0 # condition
+ _jif 3
+ _push 1 # body
+ _jmp 2
+ _push 2 # else body
+ end
+ end
+ end
+
+ describe 'slots' do
+ it 'compiles objects with setters' do
+ compiles("a = 3; a.foo = 9") do
+ _push 0
+ _setlocal 0
+ _pushlocal 0
+ _push 1
+ _setslot 2
+ end
+ end
+
+ it 'compiles objects with getters and setters' do
+ compiles("a = 3; a.foo = 9; a.foo") do
+ # a = 3
+ _push 0
+ _setlocal 0
+
+ # a.foo = 9
+ _pushlocal 0
+ _push 1
+ _setslot 2
+
+ # a.foo
+ _pushlocal 0
+ _getslot 2
+ end
+ end
+ end
+
+ describe 'constants' do
+ it 'are compiled down to normal identifiers' do
+ compiles("Object.clone") do
+ _pushself
+ _getslot 0
+
+ _send 1, 0
+ end
+ end
+ end
+ end
+end
View
108 examples/objects.fx
@@ -0,0 +1,108 @@
+_main
+:13:46
+"Object
+"clone
+50
+"age
+1000
+"money
+25
+"Parent age:
+"print
+"puts
+"Parent money:
+"Child age:
+"Child money:
+16
+64
+0
+128
+1
+0
+33
+0
+32
+0
+17
+2
+65
+3
+32
+0
+17
+4
+65
+5
+32
+0
+128
+1
+0
+33
+1
+32
+1
+17
+6
+65
+3
+16
+17
+7
+128
+8
+1
+16
+32
+0
+64
+3
+128
+9
+1
+16
+17
+10
+128
+8
+1
+16
+32
+0
+64
+5
+128
+9
+1
+16
+17
+11
+128
+8
+1
+16
+32
+1
+64
+3
+128
+9
+1
+16
+17
+12
+128
+8
+1
+16
+32
+1
+128
+5
+0
+128
+9
+1
+20
+144
+
View
27 src/forkix/value.c
@@ -1,7 +1,11 @@
#include <stdio.h>
#include <forkix/value.h>
+#include <forkix/bstrlib.h>
+#include <forkix/runtime.h>
#include <forkix/gc.h>
+VALUE NilObject;
+
VALUE
Value_new(ValueType type)
{
@@ -67,3 +71,26 @@ String_new(char* value)
val->data.as_str = value;
return val;
}
+
+void
+Value_set(VALUE receiver, char *key, VALUE value)
+{
+ bstring _slotname = bfromcstr(key);
+ Hashmap_delete(receiver->table, _slotname);
+ Hashmap_set(receiver->table, _slotname, value);
+}
+
+VALUE
+Value_get(VALUE receiver, char *key)
+{
+ VALUE value = (VALUE)Hashmap_get(receiver->table, bfromcstr(key));
+
+ if(value != NULL) {
+ return value;
+ } else {
+ return NilObject;
+ }
+}
+
+
+
View
10 src/forkix/value.h
@@ -29,14 +29,8 @@ VALUE Integer_new(int);
VALUE String_new(char*);
#define VAL2STR(o) (o->data.as_str)
-#define VALSET(S, K, V) \
- { \
- bstring _slotname = bfromcstr((K)); \
- Hashmap_delete((S)->table, _slotname); \
- Hashmap_set((S)->table, _slotname, (V)); \
- }
-
-#define VALGET(S, K) (VALUE)Hashmap_get((S)->table, bfromcstr((K)))
+void Value_set(VALUE receiver, char *key, VALUE value);
+VALUE Value_get(VALUE receiver, char *key);
#endif
View
4 src/forkix/vm.c
@@ -130,7 +130,7 @@ VALUE VM_run(STATE state, Stack *frames)
check(slot->type == StringType, "Slot name must be a String.");
- Stack_push(stack, VALGET(receiver, VAL2STR(slot)));
+ Stack_push(stack, Value_get(receiver, VAL2STR(slot)));
break;
}
case SETSLOT: {
@@ -142,7 +142,7 @@ VALUE VM_run(STATE state, Stack *frames)
check(slot->type == StringType, "Slot name must be a String.");
- VALSET(receiver, VAL2STR(slot), value);
+ Value_set(receiver, VAL2STR(slot), value);
Stack_push(stack, value); // push the rhs back to the stack
break;
}
View
6 tests/vm_tests.c
@@ -213,7 +213,7 @@ char *test_getslot()
SETUP();
VALUE receiver = String_new("foo");
- VALSET(receiver, "tainted", TrueObject);
+ Value_set(receiver, "tainted", TrueObject);
DArray_push(literals, receiver);
PUSH_LITERAL(String_new("tainted"), slot);
@@ -234,7 +234,7 @@ char *test_setslot()
SETUP();
VALUE receiver = String_new("foo");
- VALSET(receiver, "tainted", TrueObject);
+ Value_set(receiver, "tainted", TrueObject);
DArray_push(literals, receiver);
PUSH_LITERAL(String_new("tainted"), slot);
@@ -247,7 +247,7 @@ char *test_setslot()
);
mu_assert(result == FalseObject, "Setslot didn't push the rhs back to the stack.");
- mu_assert(VALGET(receiver, "tainted") == FalseObject, "Setslot didn't set the slot.");
+ mu_assert(Value_get(receiver, "tainted") == FalseObject, "Setslot didn't set the slot.");
TEARDOWN();
}

0 comments on commit abd28d9

Please sign in to comment.
Something went wrong with that request. Please try again.