nitc :: APropdef :: _after_flow_context
The ending flownitc :: APropdef :: _basic_block
The first basic block of the codenitc :: APropdef :: _before_flow_context
The starting flownitc :: APropdef :: _environment_size
The size of the environment to create to call this methodnitc :: APropdef :: _is_compiled
Indicite if this propdef was compilenitc :: APropdef :: _is_generated
If true, the basic blocks where generatednitc :: APropdef :: _is_numbering
Indicate if the variables numbering has been donenitc :: APropdef :: _is_phased
Is the propdef already analyzed byrun_phases_on_npropdef
.
nitc :: APropdef :: _object_sites
Contain all AST-parts related to object mechanisms the propdef has:nitc :: APropdef :: _return_mark
The break escape mark associated with the returnnitc :: APropdef :: _selfvariable
The variable associated to the receiver (if any)nitc :: APropdef :: _variables
The variables contained in the body on this propdefnitc :: APropdef :: after_flow_context=
The ending flownitc :: APropdef :: basic_block
The first basic block of the codenitc :: APropdef :: basic_block=
The first basic block of the codenitc :: APropdef :: before_flow_context
The starting flownitc :: APropdef :: before_flow_context=
The starting flownitc :: APropdef :: build_property
nitc :: APropdef :: build_signature
mpropdef
associated with the current node.
nitc :: APropdef :: can_inline
nitc :: APropdef :: check_redef_keyword
nitc :: APropdef :: check_repeated_types
Checks for useless type in redef signatures.nitc :: APropdef :: check_signature
nitc :: APropdef :: compile_to_c
nitc :: APropdef :: compile_to_java
Compile that property definition to java codenitc :: APropdef :: compute_phi
Compute the first phase of SSA algorithm: placing phi-functionsnitc :: APropdef :: defaultinit
nitc :: APropdef :: do_local_var_init
Entry point of the whole local variable initialization verifiernitc :: APropdef :: environment_size
The size of the environment to create to call this methodnitc :: APropdef :: environment_size=
The size of the environment to create to call this methodnitc :: APropdef :: generate_basic_blocks
Generate all basic blocks for this codenitc :: APropdef :: is_compiled=
Indicite if this propdef was compilenitc :: APropdef :: is_generated=
If true, the basic blocks where generatednitc :: APropdef :: is_numbering
Indicate if the variables numbering has been donenitc :: APropdef :: is_numbering=
Indicate if the variables numbering has been donenitc :: APropdef :: is_phased=
Is the propdef already analyzed byrun_phases_on_npropdef
.
nitc :: APropdef :: numbering_variables
Numbering the variable inside the propdefnitc :: APropdef :: object_sites
Contain all AST-parts related to object mechanisms the propdef has:nitc :: APropdef :: object_sites=
Contain all AST-parts related to object mechanisms the propdef has:nitc :: APropdef :: propagate_dependences
Propagate the dependences of the phi-functions into following variablesnitc :: APropdef :: rename_variables
Compute the second phase of SSA algorithm: renaming variablesnitc :: APropdef :: return_mark
The break escape mark associated with the returnnitc :: APropdef :: return_mark=
The break escape mark associated with the returnnitc :: APropdef :: returnvar=
The return variable of the propdefnitc :: APropdef :: selfvariable
The variable associated to the receiver (if any)nitc :: APropdef :: selfvariable=
The variable associated to the receiver (if any)nitc :: APropdef :: ssa_destruction
Transform SSA-representation into an executable code (delete phi-functions)nitc :: APropdef :: variables=
The variables contained in the body on this propdefnitc :: APropdef :: visit_annotations
Factorize annotations visit for all APropdef.nitc :: APropdef :: visit_block
Factorize block visit for APropdefs.nitc :: flow $ APropdef :: accept_flow_visitor
nitc :: pretty $ APropdef :: accept_pretty_printer
Start visit ofself
using a PrettyPrinterVisitor
nitc :: contracts $ APropdef :: check_callsite
nitc :: compilation $ APropdef :: compile
Compile this propdefnitc :: compilation $ APropdef :: generate_name
Redef to add the same position to a new version of a Variable than the original variablenitc :: pretty $ APropdef :: start_token
The token where the production really start (skipping ADoc).nitc :: APropdef :: _after_flow_context
The ending flownitc :: APropdef :: _basic_block
The first basic block of the codenitc :: APropdef :: _before_flow_context
The starting flownitc :: APropdef :: _environment_size
The size of the environment to create to call this methodnitc :: Prod :: _first_location
Location on the first token after the start of a productionnitc :: Prod :: _first_token
The first token of the production in the ASTnitc :: ANode :: _is_broken
The indication that the node did not pass some semantic verifications.nitc :: APropdef :: _is_compiled
Indicite if this propdef was compilenitc :: APropdef :: _is_generated
If true, the basic blocks where generatednitc :: APropdef :: _is_numbering
Indicate if the variables numbering has been donenitc :: APropdef :: _is_phased
Is the propdef already analyzed byrun_phases_on_npropdef
.
nitc :: Prod :: _last_token
The last token of the production in the ASTnitc :: Prod :: _n_annotations
All the annotations attached directly to the nodenitc :: ADefinition :: _n_visibility
The declared visibilitynitc :: APropdef :: _object_sites
Contain all AST-parts related to object mechanisms the propdef has:nitc :: APropdef :: _return_mark
The break escape mark associated with the returnnitc :: APropdef :: _selfvariable
The variable associated to the receiver (if any)nitc :: APropdef :: _variables
The variables contained in the body on this propdefnitc :: ANode :: accept_ast_validation
nitc :: ANode :: accept_auto_super_init
nitc :: ANode :: accept_flow_visitor
nitc :: ANode :: accept_forward_analysis
Apply the forward analysisv
to self
.
nitc :: ANode :: accept_literal
nitc :: ANode :: accept_post_typing
nitc :: ANode :: accept_pretty_printer
Start visit ofself
using a PrettyPrinterVisitor
nitc :: ANode :: accept_reaching_defs
Apply a ReachingDefsAnalysis toself
.
nitc :: ANode :: accept_regex_visitor
nitc :: ANode :: accept_scope_visitor
nitc :: ANode :: accept_simple_misc
nitc :: ANode :: accept_string_finder
nitc :: APropdef :: after_flow_context=
The ending flownitc :: ANode :: after_simple_misc
nitc :: ANode :: bad_expr_message
An additional information message to explain the role of a child expression.nitc :: APropdef :: basic_block
The first basic block of the codenitc :: APropdef :: basic_block=
The first basic block of the codenitc :: APropdef :: before_flow_context
The starting flownitc :: APropdef :: before_flow_context=
The starting flownitc :: APropdef :: build_property
nitc :: APropdef :: build_signature
mpropdef
associated with the current node.
nitc :: APropdef :: can_inline
nitc :: ANode :: check_callsite
nitc :: APropdef :: check_redef_keyword
nitc :: APropdef :: check_repeated_types
Checks for useless type in redef signatures.nitc :: APropdef :: check_signature
core :: Object :: class_factory
Implementation used byget_class
to create the specific class.
nitc :: ANode :: collect_annotations_by_name
Do a deep search and return an array of node that are annotatednitc :: Prod :: collect_comments
Collect allTComment
contained in the production
nitc :: ANode :: collect_length
Collect the length (inChar
) of the node.
nitc :: ANode :: collect_tokens_by_text
Do a deep search and return an array of tokens that match a given textnitc :: ANode :: common_parent
The most specific common parent betweenself
and other
nitc :: APropdef :: compile_to_c
nitc :: APropdef :: compile_to_java
Compile that property definition to java codenitc :: APropdef :: compute_phi
Compute the first phase of SSA algorithm: placing phi-functionsnitc :: ANode :: create_contracts
nitc :: ANode :: decorate_tag
Add aditionnal information on a child-token and return an additionnal HInfoBox on itnitc :: APropdef :: defaultinit
nitc :: Prod :: defaultinit
nitc :: ADefinition :: defaultinit
core :: Cloneable :: defaultinit
nitc :: ANode :: defaultinit
core :: Object :: defaultinit
nitc :: ANode :: do_cloneable
nitc :: APropdef :: do_local_var_init
Entry point of the whole local variable initialization verifiernitc :: APropdef :: environment_size
The size of the environment to create to call this methodnitc :: APropdef :: environment_size=
The size of the environment to create to call this methodnitc :: Prod :: first_location
Location on the first token after the start of a productionnitc :: Prod :: first_location=
Location on the first token after the start of a productionnitc :: Prod :: first_token
The first token of the production in the ASTnitc :: Prod :: first_token=
The first token of the production in the ASTnitc :: ANode :: force_block=
Forceself
to be rendered as a block.
nitc :: ANode :: force_inline=
Forceself
to be rendered as a line.
nitc :: ANode :: full_transform_visitor
nitc :: APropdef :: generate_basic_blocks
Generate all basic blocks for this codenitc :: Prod :: get_annotations
Return all its annotations of a given name in the order of their declarationnitc :: Prod :: get_single_annotation
Try to get its single annotation with a given namenitc :: ANode :: hot_location
The location of the important part of the node (identifier or whatever)nitc :: ANode :: is_broken=
The indication that the node did not pass some semantic verifications.nitc :: APropdef :: is_compiled=
Indicite if this propdef was compilenitc :: APropdef :: is_generated=
If true, the basic blocks where generatednitc :: ANode :: is_noserialize
Is this node annotated to not be made serializable?nitc :: APropdef :: is_numbering
Indicate if the variables numbering has been donenitc :: APropdef :: is_numbering=
Indicate if the variables numbering has been donenitc :: APropdef :: is_phased=
Is the propdef already analyzed byrun_phases_on_npropdef
.
core :: Object :: is_same_instance
Return true ifself
and other
are the same instance (i.e. same identity).
core :: Object :: is_same_serialized
Isself
the same as other
in a serialization context?
core :: Object :: is_same_type
Return true ifself
and other
have the same dynamic type.
nitc :: ANode :: is_serialize
Is this node annotated to be made serializable?nitc :: ANode :: is_structural
Isself
a token or a pure-structural production like AQId
?
nitc :: Prod :: last_token
The last token of the production in the ASTnitc :: Prod :: last_token=
The last token of the production in the ASTnitc :: ANode :: must_be_block
Doesself
have to be rendered as a block?
nitc :: ANode :: must_be_inline
Doesself
have be rendered as a line?
nitc :: Prod :: n_annotations
All the annotations attached directly to the nodenitc :: Prod :: n_annotations=
All the annotations attached directly to the nodenitc :: ADefinition :: n_visibility=
The declared visibilitycore :: Object :: native_class_name
The class name of the object in CString format.nitc :: APropdef :: numbering_variables
Numbering the variable inside the propdefnitc :: APropdef :: object_sites
Contain all AST-parts related to object mechanisms the propdef has:nitc :: APropdef :: object_sites=
Contain all AST-parts related to object mechanisms the propdef has:core :: Object :: output_class_name
Display class name on stdout (debug only).nitc :: ANode :: parentize_tokens
Visit the AST and computes advanced AST attributes on Tokens and Prodnitc :: APropdef :: propagate_dependences
Propagate the dependences of the phi-functions into following variablesnitc :: APropdef :: rename_variables
Compute the second phase of SSA algorithm: renaming variablesnitc :: ANode :: replace_child
Replace a child with an other node in the ASTnitc :: ANode :: replace_with
Replace itself with an other node in the ASTnitc :: APropdef :: return_mark
The break escape mark associated with the returnnitc :: APropdef :: return_mark=
The break escape mark associated with the returnnitc :: APropdef :: returnvar=
The return variable of the propdefnitc :: APropdef :: selfvariable
The variable associated to the receiver (if any)nitc :: APropdef :: selfvariable=
The variable associated to the receiver (if any)nitc :: APropdef :: ssa_destruction
Transform SSA-representation into an executable code (delete phi-functions)nitc :: Prod :: start_token
The token where the production really start (skipping ADoc).nitc :: APropdef :: variables=
The variables contained in the body on this propdefnitc :: APropdef :: visit_annotations
Factorize annotations visit for all APropdef.nitc :: APropdef :: visit_block
Factorize block visit for APropdefs.nitc :: ANode :: was_inline
Doesself
was written in one line before transformation?
# The definition of a property
abstract class APropdef
super ADefinition
end
src/parser/parser_nodes.nit:1364,1--1367,3
redef class APropdef
# The break escape mark associated with the return
var return_mark: nullable EscapeMark
# Entry point of the scope analysis
fun do_scope(toolcontext: ToolContext)
do
var v = new ScopeVisitor(toolcontext, self)
v.enter_visit(self)
v.shift_scope
end
end
src/semantize/scope.nit:253,1--264,3
redef class APropdef
# The associated main model entity
type MPROPDEF: MPropDef
# The associated propdef once build by a `ModelBuilder`
var mpropdef: nullable MPROPDEF is writable
private fun build_property(modelbuilder: ModelBuilder, mclassdef: MClassDef) do end
private fun build_signature(modelbuilder: ModelBuilder) do end
private fun check_signature(modelbuilder: ModelBuilder) do end
private fun new_property_visibility(modelbuilder: ModelBuilder, mclassdef: MClassDef, nvisibility: nullable AVisibility): MVisibility
do
var mvisibility = public_visibility
if nvisibility != null then
mvisibility = nvisibility.mvisibility
if mvisibility == intrude_visibility then
modelbuilder.error(nvisibility, "Error: `intrude` is not a legal visibility for properties.")
mvisibility = public_visibility
end
end
if mclassdef.mclass.visibility == private_visibility then
if mvisibility == protected_visibility then
assert nvisibility != null
modelbuilder.error(nvisibility, "Error: `private` is the only legal visibility for properties in a private class.")
else if mvisibility == private_visibility then
assert nvisibility != null
modelbuilder.advice(nvisibility, "useless-visibility", "Warning: `private` is superfluous since the only legal visibility for properties in a private class is private.")
end
mvisibility = private_visibility
end
return mvisibility
end
private fun set_doc(mpropdef: MPropDef, modelbuilder: ModelBuilder)
do
var ndoc = self.n_doc
if ndoc != null then
var mdoc = ndoc.to_mdoc
mpropdef.mdoc = mdoc
mdoc.original_mentity = mpropdef
else if mpropdef.is_intro and mpropdef.mproperty.visibility >= protected_visibility and mpropdef.name != "new" then
modelbuilder.advice(self, "missing-doc", "Documentation warning: Undocumented property `{mpropdef.mproperty}`")
end
var at_deprecated = get_single_annotation("deprecated", modelbuilder)
if at_deprecated != null then
if not mpropdef.is_intro then
modelbuilder.error(self, "Error: method redefinition cannot be deprecated.")
else
var info = new MDeprecationInfo
ndoc = at_deprecated.n_doc
if ndoc != null then info.mdoc = ndoc.to_mdoc
mpropdef.mproperty.deprecation = info
end
end
end
private fun check_redef_property_visibility(modelbuilder: ModelBuilder, nvisibility: nullable AVisibility, mprop: MProperty)
do
if nvisibility == null then return
var mvisibility = nvisibility.mvisibility
if mvisibility != mprop.visibility and mvisibility != public_visibility then
modelbuilder.error(nvisibility, "Error: redefinition changed the visibility from `{mprop.visibility}` to `{mvisibility}`.")
end
end
private fun check_redef_keyword(modelbuilder: ModelBuilder, mclassdef: MClassDef, kwredef: nullable Token, need_redef: Bool, mprop: MProperty): Bool
do
if mclassdef.mprop2npropdef.has_key(mprop) then
modelbuilder.error(self, "Error: a property `{mprop}` is already defined in class `{mclassdef.mclass}` at line {mclassdef.mprop2npropdef[mprop].location.line_start}.")
return false
end
if mprop isa MMethod and mprop.is_root_init then return true
if kwredef == null then
if need_redef then
modelbuilder.error(self, "Redef Error: `{mclassdef.mclass}::{mprop.name}` is an inherited property. To redefine it, add the `redef` keyword.")
return false
end
# Check for full-name conflicts in the package.
# A public property should have a unique qualified name `package::class::prop`.
if mprop.intro_mclassdef.mmodule.mgroup != null and mprop.visibility >= protected_visibility then
var others = modelbuilder.model.get_mproperties_by_name(mprop.name)
if others != null then for other in others do
if other != mprop and other.intro_mclassdef.mmodule.mgroup != null and other.intro_mclassdef.mmodule.mgroup.mpackage == mprop.intro_mclassdef.mmodule.mgroup.mpackage and other.intro_mclassdef.mclass.name == mprop.intro_mclassdef.mclass.name and other.visibility >= protected_visibility then
modelbuilder.advice(self, "full-name-conflict", "Warning: A property named `{other.full_name}` is already defined in module `{other.intro_mclassdef.mmodule}` for the class `{other.intro_mclassdef.mclass.name}`.")
break
end
end
end
else
if not need_redef then
modelbuilder.error(self, "Error: no property `{mclassdef.mclass}::{mprop.name}` is inherited. Remove the `redef` keyword to define a new property.")
return false
end
end
return true
end
# Checks for useless type in redef signatures.
private fun check_repeated_types(modelbuilder: ModelBuilder) do end
end
src/modelize/modelize_property.nit:579,1--680,3
redef class APropdef
# The entry point of the whole flow analysis
fun do_flow(toolcontext: ToolContext)
do
var v = new FlowVisitor(toolcontext)
v.enter_visit(self)
end
# The starting flow
var before_flow_context: nullable FlowContext is noautoinit
# The ending flow
var after_flow_context: nullable FlowContext is noautoinit
redef fun accept_flow_visitor(v)
do
self.before_flow_context = v.current_flow_context
super
self.after_flow_context = v.current_flow_context
end
end
src/semantize/flow.nit:256,1--277,3
redef class APropdef
redef fun accept_pretty_printer(v) do
v.visit n_doc
v.addt
if not n_visibility isa nullable APublicVisibility then
v.visit n_visibility
v.adds
end
if n_kwredef != null then
v.visit n_kwredef
v.adds
end
end
# Factorize annotations visit for all APropdef.
#
# Return true if annotations were inlined.
fun visit_annotations(v: PrettyPrinterVisitor, n_annotations: nullable AAnnotations): Bool do
var res = v.can_inline(n_annotations)
if n_annotations != null then v.visit n_annotations
return res
end
# Factorize block visit for APropdefs.
#
# Were annotations printed inline? If so, we need to print the block differently.
fun visit_block(v: PrettyPrinterVisitor, n_block: nullable AExpr, annot_inline: Bool) do
# var can_inline = v.can_inline(n_block)
if n_block == null then return
if n_annotations != null and not annot_inline then
v.forcen
v.addt
end
if v.inline_do then
while not v.current_token isa TKwdo do v.skip
end
var token = v.current_token
var do_inline = true
loop
if token isa TEol then
v.skip
if not v.can_inline(n_block) then
v.forcen
v.addt
do_inline = false
end
end
token = v.current_token
if token isa TKwdo then break
end
if annot_inline and do_inline then v.adds
v.consume "do"
if v.can_inline(n_block) and do_inline then
v.adds
if n_block isa ABlockExpr then
if n_block.n_expr.is_empty then
v.visit n_block.n_kwend
else
v.visit n_block.n_expr.first
v.current_token = n_block.n_kwend
v.skip
end
else
v.visit n_block
if v.current_token isa TKwend then v.skip
end
else
v.finish_line
if was_inline then
v.forcen
else
v.addn
end
v.indent += 1
if n_block isa ABlockExpr then
n_block.force_block = true
v.visit n_block
v.catch_up n_block.n_kwend
else
v.addt
v.visit n_block
v.forcen
end
v.indent -= 1
v.addt
if n_block isa ABlockExpr then
v.visit n_block.n_kwend
else
v.add "end"
end
end
v.finish_line
end
redef fun start_token do
if n_doc == null then return super
return n_doc.last_token.next_token
end
end
src/pretty.nit:801,1--905,3
redef class APropdef
# Entry point of the whole local variable initialization verifier
fun do_local_var_init(toolcontext: ToolContext)
do
var v = new LocalVarInitVisitor(toolcontext)
v.enter_visit(self)
end
end
src/semantize/local_var_init.nit:34,1--41,3
redef class APropdef
# The entry point of the whole typing analysis
fun do_typing(modelbuilder: ModelBuilder)
do
end
# The variable associated to the receiver (if any)
var selfvariable: nullable Variable
end
src/semantize/typing.nit:886,1--894,3
redef class APropdef
# Execute a `mpropdef` associated with the current node.
private fun call(v: NaiveInterpreter, mpropdef: MMethodDef, args: Array[Instance]): nullable Instance
do
fatal(v, "NOT YET IMPLEMENTED method kind {class_name}. {mpropdef}")
abort
end
end
src/interpreter/naive_interpreter.nit:889,1--896,3
redef class APropdef
# The variables contained in the body on this propdef
var variables: HashSet[Variable] = new HashSet[Variable] is lazy
# The first basic block of the code
var basic_block: nullable BasicBlock
# If true, the basic blocks where generated
var is_generated: Bool = false
# Generate all basic blocks for this code
fun generate_basic_blocks(ssa: SSA) is abstract
# Contain all AST-parts related to object mechanisms the propdef has:
# instantiation, method dispatch, attribute access, subtyping-test
var object_sites: Array[AExpr] = new Array[AExpr]
# The return variable of the propdef
# Create an empty variable for the return of the method
# and treat returns like variable assignments
var returnvar: Variable = new Variable("returnvar")
# Compute the three steps of SSA-algorithm
# `ssa` A new instance of SSA class initialized with `self`
fun compute_ssa(ssa: SSA)
do
if is_generated then return
# The first step is to generate the basic blocks
generate_basic_blocks(ssa)
# The propdef has no body (abstract)
if not is_generated then return
# Once basic blocks were generated, compute SSA algorithm
compute_phi(ssa)
rename_variables(ssa)
ssa_destruction(ssa)
end
# Compute the first phase of SSA algorithm: placing phi-functions
fun compute_phi(ssa: SSA)
do
var root_block = basic_block.as(not null)
# Compute the iterated dominance frontier of the graph of basic blocks
root_block.compute_df
# Places where a phi-function is added per variable
var phi_blocks = new HashMap[Variable, Array[BasicBlock]]
# For each variables in the propdef
for v in variables do
var phi_variables = new Array[BasicBlock]
var read_blocks = new Array[BasicBlock]
read_blocks.add_all(v.read_blocks)
read_blocks.add_all(v.assignment_blocks)
# While we have not treated each part accessing `v`
while not read_blocks.is_empty do
# Remove a block from the array
var block = read_blocks.shift
# For each block in the dominance frontier of `block`
for df in block.dominance_frontier do
# If we have not yet put a phi-function at the beginning of this block
if not phi_variables.has(df) then
phi_variables.add(df)
# Create a new phi-function and set its dependences
var phi = new PhiFunction("phi", df)
phi.add_dependences(df, v)
phi.block = df
phi.original_variable = phi
phi.declared_type = v.declared_type
# Indicate this phi-function is assigned in this block
phi.assignment_blocks.add(block)
ssa.phi_functions.add(phi)
# Add a phi-function at the beginning of df for variable v
df.phi_functions.add(phi)
if not v.read_blocks.has(df) or not v.assignment_blocks.has(df) then read_blocks.add(df)
end
end
end
# Add `phi-variables` to the global map
phi_blocks[v] = phi_variables
end
end
# Compute the second phase of SSA algorithm: renaming variables
# NOTE: `compute_phi` must has been called before
fun rename_variables(ssa: SSA)
do
# A counter for each variable
# The key is the variable, the value the number of assignment into the variable
var counter = new HashMap[Variable, Int]
for v in variables do
counter[v] = 0
v.stack.push(v)
end
for phi in ssa.phi_functions do counter[phi] = 0
# Launch the recursive renaming from the root block
rename(basic_block.as(not null), counter, ssa)
end
# Recursively rename each variable from `block`
# *`block` The starting basic block
# *`counter` The key is the variable, the value the number of assignment into the variable
fun rename(block: BasicBlock, counter: HashMap[Variable, Int], ssa: SSA)
do
if block.is_renaming then return
block.is_renaming = true
# For each phi-function of this block
for phi in block.phi_functions do
generate_name(phi, counter, block.first, ssa)
# Replace the phi into the block
block.phi_functions[block.phi_functions.index_of(phi)] = phi.original_variable.stack.last.as(PhiFunction)
end
# For each variable read in `block`
for vread in block.read_sites do
# Replace the old variable in AST
vread.variable = vread.variable.original_variable.stack.last
end
# For each variable write
for vwrite in block.write_sites do
generate_name(vwrite.variable.as(not null), counter, vwrite, ssa)
var new_version = vwrite.variable.original_variable.stack.last
# Set dependence of the new variable
if vwrite isa AVarReassignExpr then
new_version.dep_exprs.add(vwrite.n_value)
else if vwrite isa AVarAssignExpr then
new_version.dep_exprs.add(vwrite.n_value)
end
# Replace the old variable by the last created
vwrite.variable = new_version
end
# Rename occurrence of old names in phi-function
for successor in block.dominance_frontier do
for sphi in successor.phi_functions do
# Go over the couples in the phi dependences to rename variables
for couple in sphi.dependences do
if couple.second == block then
# Rename this variable
couple.first = couple.first.original_variable.stack.last
end
end
end
end
# Recurse in successor blocks
for successor in block.successors do
rename(successor, counter, ssa)
end
# Pop old names off the stack for each phi-function
for phi in block.phi_functions do
if not phi.stack.is_empty then phi.stack.pop
end
end
# Generate a new version of the variable `v` and return it
# *`v` The variable for which we generate a name
# *`counter` The key is the variable, the value the number of assignment into the variable
# *`expr` The AST node in which the assignment of v is made
# *`ssa` The instance of SSA
fun generate_name(v: Variable, counter: HashMap[Variable, Int], expr: ANode, ssa: SSA): Variable
do
var original_variable = v.original_variable.as(not null)
var i = counter[original_variable]
var new_version: Variable
# Create a new version of Variable
if original_variable isa PhiFunction then
var block = original_variable.block
new_version = new PhiFunction(original_variable.name + i.to_s, block)
new_version.dependences.add_all(original_variable.dependences)
ssa.phi_functions.add(new_version)
else
new_version = new Variable(original_variable.name + i.to_s)
new_version.declared_type = expr.as(AVarFormExpr).variable.declared_type
variables.add(new_version)
end
# Recopy the fields into the new version
new_version.location = expr.location
new_version.original_variable = original_variable
# Push a new version on the stack
original_variable.stack.add(new_version)
counter[v] = i + 1
return new_version
end
# Transform SSA-representation into an executable code (delete phi-functions)
# `ssa` Current instance of SSA
fun ssa_destruction(ssa: SSA)
do
var builder = new ASTBuilder(mpropdef.mclassdef.mmodule, mpropdef.mclassdef.bound_mtype)
# Iterate over all phi-functions
for phi in ssa.phi_functions do
for dep in phi.dependences do
# dep.second is the block where we need to create a varassign
var var_read = builder.make_var_read(dep.first, dep.first.declared_type.as(not null))
var nvar = builder.make_var_assign(dep.first, var_read)
var block = dep.second.last.parent
# This variable read must be add to a ABlockExpr
if block isa ABlockExpr then
block.add(nvar)
end
propagate_dependences(phi, phi.block)
ssa.propdef.variables.add(dep.first)
end
end
end
# Propagate the dependences of the phi-functions into following variables
# `phi` The PhiFunction
# `block` Current block where we propagate dependences
fun propagate_dependences(phi: PhiFunction, block: BasicBlock)
do
# Treat each block once
if block.treated then return
# For each variable access site in the block
for site in block.variables_sites do
if site isa AVarExpr then
# Propagate the dependences of the phi-function in variables after the phi
for dep in phi.dependences do
for expr in dep.first.dep_exprs do
if site.variable.dep_exprs.has(expr) then break
if dep.first.original_variable == site.variable.original_variable then
site.variable.dep_exprs.add(expr)
end
end
end
else
# The site is a variable write, we stop the propagation
return
end
end
block.treated = true
# If we do not meet a variable write, continue the propagation
for b in block.successors do propagate_dependences(phi, b)
end
end
src/ssa.nit:198,1--469,3
redef class APropdef
# Indicite if this propdef was compile
var is_compiled: Bool = false
# Indicate if the variables numbering has been done
private var is_numbering: Bool = false
# The size of the environment to create to call this method
private var environment_size: Int = 0
# Compile this propdef
# *`vm` The running instance of `VirtualMachine`
fun compile(vm: VirtualMachine)
do
# Number the variables
if not is_numbering then numbering_variables(vm)
is_compiled = true
end
# Numbering the variable inside the propdef
fun numbering_variables(vm: VirtualMachine) is abstract
end
src/vm/variables_numbering.nit:95,1--117,3
redef class APropdef
redef fun check_callsite(v)
do
v.visited_propdef = self
end
end
src/contracts.nit:699,1--704,3
redef class APropdef
fun compile_to_c(v: AbstractCompilerVisitor, mpropdef: MMethodDef, arguments: Array[RuntimeVariable])
do
v.add("PRINT_ERROR(\"NOT YET IMPLEMENTED {class_name} {mpropdef} at {location.to_s}\\n\");")
debug("Not yet implemented")
end
fun can_inline: Bool do return true
end
src/compiler/abstract_compiler.nit:2614,1--2622,3
redef class APropdef
redef fun compile(vm)
do
super
# A new instance of SSA to analyze the self propdef
var ssa = new SSA(self)
# Generate basic_blocks and compute SSA-algorithm for this propdef
compute_ssa(ssa)
end
# Redef to add the same position to a new version of a Variable than the original variable
redef fun generate_name(v, counter, expr, ssa)
do
var new_version = super
# All versions of a variable have the same position in the environment
new_version.position = v.original_variable.position
return new_version
end
end
src/vm/compilation.nit:37,1--60,3
redef class APropdef
# Compile that property definition to java code
fun compile_to_java(v: JavaCompilerVisitor, mpropdef: MMethodDef, arguments: Array[RuntimeVariable]) do
v.info("NOT YET IMPLEMENTED {class_name}::compile_to_java")
end
end
src/compiler/java_compiler.nit:1495,1--1501,3
redef class APropdef
redef fun make_tag(v)
do
var res = new HTMLTag("span")
res.add_class("nc_pdef")
var mpd
mpd = mpropdef
if mpd != null then
#res.add(tag(mpd))
res.attr("id", mpd.to_s)
end
if self isa AAttrPropdef then
mpd = mreadpropdef
if mpd != null then res.add(tag(mpd))
mpd = mwritepropdef
if mpd != null then res.add(tag(mpd))
end
return res
end
private fun tag(mpd: MPropDef): HTMLTag
do
var a = new HTMLTag("a")
a.attr("id", mpd.to_s)
return a
end
end
src/htmlight.nit:779,1--805,3