class UnsafeFuncRewriter

Check for whether the rule invokes any “unsafe” functions (functions that might return a different value every time they are called, e.g., budtime). The test for “unsafe” functions is pretty naive: any function call with a nil receiver is treated as unsafe unless it is belongs to a list of “safe” functions (below) or it denotes a lattice identifier. In the latter case, the rule is akin to an implicit join with the lattice, so we only rescan it on deltas to the lattice (see “rescan_on_merge” in LatticeWrapper).

Although this is called a rewriter, it doesn't modify the input AST.

Constants

SAFE_FUNC_LIST

Attributes

unsafe_func_called[R]

Public Class Methods

new(bud_instance) click to toggle source
Calls superclass method
# File lib/bud/rewrite.rb, line 359
def initialize(bud_instance)
  super()
  self.require_empty = false
  self.expected = Sexp
  @bud_instance = bud_instance
  @unsafe_func_called = false
  @elem_stack = []
end

Public Instance Methods

is_collection_name?(op) click to toggle source
# File lib/bud/rewrite.rb, line 399
def is_collection_name?(op)
  @bud_instance.tables.has_key?(op.to_sym) || @bud_instance.lattices.has_key?(op.to_sym)
end
is_safe_func(op) click to toggle source
# File lib/bud/rewrite.rb, line 403
def is_safe_func(op)
  SAFE_FUNC_LIST.include? op
end
process_call(exp) click to toggle source
# File lib/bud/rewrite.rb, line 368
def process_call(exp)
  tag, recv, op, *args = exp

  # We assume that unsafe funcs have a nil receiver (Bud instance is implicit
  # receiver).
  if recv.nil? and @elem_stack.size > 0
    unless is_safe_func(op) || is_collection_name?(op)
      @unsafe_func_called = true
    end
  end

  return s(tag, process(recv), op, *(args.map{|a| process(a)}))
end
process_iter(exp) click to toggle source
# File lib/bud/rewrite.rb, line 382
def process_iter(exp)
  tag, recv, iter_args, body = exp
  if (iter_args == 0)
    iter_args = s(:args)
  end
  new_body = push_and_process(body)
  return s(tag, process(recv), process(iter_args), new_body)
end
push_and_process(exp) click to toggle source
# File lib/bud/rewrite.rb, line 391
def push_and_process(exp)
  obj_id = exp.object_id
  @elem_stack.push(obj_id)
  rv = process(exp)
  raise Bud::Error unless @elem_stack.pop == obj_id
  return rv
end