Skip to content

Instantly share code, notes, and snippets.

@dirk
Created October 18, 2013 21:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dirk/7048649 to your computer and use it in GitHub Desktop.
Save dirk/7048649 to your computer and use it in GitHub Desktop.
# Fast nested constant implementation
class FastNestedConstant : Fancy AST NestedConstant {
def initialize: @line string: @string {
names = @string split: "::"
@toplevel = false
if: (@string =~ /^::/) then: { @toplevel = true; names shift }
@names = names map: |n| { n to_sym }
}
def bytecode: g {
pos(g)
n = @names first
if: @toplevel then: {
g push_cpath_top()
g find_const(n)
} else: { g push_const(n) }
@names rest each: |n| {
g find_const(n)
}
}
def bytecode: g assign: value {
pos(g)
# Resolve the first one
n = @names first
if: @toplevel then: {
g push_cpath_top()
g find_const(n)
} else: { g push_const(n) }
# Copy the names and pop of the last one for const_set.
names = @names dup
last = names pop
# Then resolve all in the middle.
names rest each: |n| {
g find_const(n)
}
g push_literal(last)
g check_frozen() # Make sure we can change the receiver module.
value bytecode(g)
g send('const_set_fast:to:, 2)
g ret()
}
}
class Module {
def const_set_fast: name to: value {
# if: (Rubinius Type object_kind_of?(value, Module)) then: {
# Rubinius Type set_module_name(value, name, self)
# }
@constant_table store(name, value, 'public)
Rubinius inc_global_serial()
return value
}
}
n = FastNestedConstant new: 0 string: "A::B"
# n scoped inspect println
#n chain inspect println
A = 1
class Test {
dynamic_method(':asdf) |g| {
n = FastNestedConstant new: 0 string: "A::B"
n bytecode: g assign: (Fancy AST FixnumLiteral new: 0 value: 2)
g ret()
}
}
A println
#t = Test new
#t asdf inspect println
A = 2
A println
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment