Class: YTLJit::VM::Node::ClassTopNode

Inherits:
TopNode show all
Includes:
MethodTopCodeGen, SendNodeCodeGen
Defined in:
lib/ytljit/vm.rb

Direct Known Subclasses

TopTopNode

Constant Summary collapse

@@class_top_tab =
{}

Constants included from AbsArch

AbsArch::AL, AbsArch::BL, AbsArch::CL, AbsArch::DL, AbsArch::FUNC_ARG, AbsArch::FUNC_ARG_YTL, AbsArch::FUNC_FLOAT_ARG, AbsArch::FUNC_FLOAT_ARG_YTL, AbsArch::INDIRECT_BPR, AbsArch::INDIRECT_RETR, AbsArch::INDIRECT_SPR, AbsArch::INDIRECT_TMPR, AbsArch::INDIRECT_TMPR2, AbsArch::INDIRECT_TMPR3

Constants included from SSE

SSE::XMM0, SSE::XMM1, SSE::XMM2, SSE::XMM3, SSE::XMM4, SSE::XMM5, SSE::XMM6, SSE::XMM7

Constants inherited from BaseNode

BaseNode::ESCAPE_LEVEL

Instance Attribute Summary collapse

Attributes inherited from TopNode

#end_nodes, #exception_table, #name, #signature_cache, #yield_node

Attributes included from HaveChildlenMixin

#body

Attributes inherited from BaseNode

#code_space, #debug_info, #element_node_list, #id, #is_escape, #parent, #ti_observee, #ti_observer, #type

Class Method Summary collapse

Instance Method Summary collapse

Methods included from MethodTopCodeGen

#gen_method_prologue

Methods included from SendNodeCodeGen

#gen_make_argv

Methods included from CommonCodeGen

#dump_context, #gen_alloca, #gen_call, #gen_save_thepr

Methods inherited from TopNode

#add_arg_to_args, #compile_init, #disp_signature, #modified_instance_var, #traverse_childlen

Methods included from MultipleCodeSpaceUtil

#add_cs_for_signature, #find_cs_by_signature, #get_code_space

Methods included from NodeUtil

#search_class_top, #search_end, #search_frame_info, #search_top

Methods included from HaveChildlenMixin

#traverse_childlen

Methods inherited from BaseNode

#add_element_node, #add_element_node_backward, #decide_type, #decide_type_core, #decide_type_once, #gen_type_inference_proc, #inference_type, #marge_element_node, #marge_type, #same_type, #set_escape_node, #set_escape_node_backward, #ti_add_observer, #ti_changed, #ti_del_link, #ti_reset, #ti_update

Methods included from TypeListWithSignature

#add_type, #set_type_list, #type_list, #type_list_initvar

Methods included from Inspect

#inspect_by_graph

Constructor Details

#initialize(parent, klassobj, name = nil) ⇒ ClassTopNode

Returns a new instance of ClassTopNode.



1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
# File 'lib/ytljit/vm.rb', line 1250

def initialize(parent, klassobj, name = nil)
  super(parent, name)
  @before_search_module = []
  @after_search_module = []
  @constant_tab = {}
  @method_tab = {}
  @klass_object = klassobj
  @klassclass = ClassClassWrapper.instance(@klass_object)
  @klassclass_node = nil # Lazy
  RubyType::define_wraped_class(@klassclass, 
                                RubyType::RubyTypeBoxed)
  unless @@class_top_tab[klassobj]
    @@class_top_tab[klassobj] = self
  end
end

Instance Attribute Details

#after_search_moduleObject (readonly)

Returns the value of attribute after_search_module.



1272
1273
1274
# File 'lib/ytljit/vm.rb', line 1272

def after_search_module
  @after_search_module
end

#before_search_moduleObject (readonly)

Returns the value of attribute before_search_module.



1271
1272
1273
# File 'lib/ytljit/vm.rb', line 1271

def before_search_module
  @before_search_module
end

#constant_tabObject (readonly)

Returns the value of attribute constant_tab.



1267
1268
1269
# File 'lib/ytljit/vm.rb', line 1267

def constant_tab
  @constant_tab
end

#klass_objectObject (readonly)

Returns the value of attribute klass_object.



1266
1267
1268
# File 'lib/ytljit/vm.rb', line 1266

def klass_object
  @klass_object
end

#klassclassObject (readonly)

Returns the value of attribute klassclass.



1269
1270
1271
# File 'lib/ytljit/vm.rb', line 1269

def klassclass
  @klassclass
end

#klassclass_nodeObject (readonly)

Returns the value of attribute klassclass_node.



1270
1271
1272
# File 'lib/ytljit/vm.rb', line 1270

def klassclass_node
  @klassclass_node
end

#method_tabObject (readonly)

Returns the value of attribute method_tab.



1268
1269
1270
# File 'lib/ytljit/vm.rb', line 1268

def method_tab
  @method_tab
end

Class Method Details

.get_class_top_node(klass) ⇒ Object



1246
1247
1248
# File 'lib/ytljit/vm.rb', line 1246

def self.get_class_top_node(klass)
  @@class_top_tab[klass]
end

Instance Method Details

#add_after_search_module(scope, mod) ⇒ Object



1326
1327
1328
1329
1330
1331
1332
1333
1334
# File 'lib/ytljit/vm.rb', line 1326

def add_after_search_module(scope, mod)
  clsnode = @@class_top_tab[@klass_object]
  clsnode.after_search_module.each do |scope, modnode|
    if modnode == mod then
      return
    end
  end
  clsnode.before_search_module.unshift [scope, mod]
end

#add_before_search_module(scope, mod) ⇒ Object



1316
1317
1318
1319
1320
1321
1322
1323
1324
# File 'lib/ytljit/vm.rb', line 1316

def add_before_search_module(scope, mod)
  clsnode = @@class_top_tab[@klass_object]
  clsnode.before_search_module.each do |scope, modnode|
    if modnode == mod then
      return
    end
  end
  clsnode.before_search_module.push [scope, mod]
end

#collect_candidate_type(context, signode, sig) ⇒ Object



1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
# File 'lib/ytljit/vm.rb', line 1392

def collect_candidate_type(context, signode, sig)
  @type = RubyType::BaseType.from_ruby_class(@klassclass)
  add_type(sig, @type)

  if add_cs_for_signature(sig) == nil and  
      context.visited_top_node[self] then
    return context
  end

  context.visited_top_node[self] = true
  @signature_cache.push sig
  
  context.push_signature(signode, self)
  context = @body.collect_candidate_type(context)
  context.pop_signature

  if @klassclass_node then
    context = @klassclass_node.collect_candidate_type(context, 
                                                      signode, sig)
  end

  set_escape_node(:not_export)

  context
end

#collect_info(context) ⇒ Object



1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
# File 'lib/ytljit/vm.rb', line 1274

def collect_info(context)
  context.modified_local_var.push [{}]
  context.modified_instance_var = Hash.new
  context = super
  context.modified_local_var.pop
  if @klassclass_node then
    @klassclass_node.collect_info(context)
  else
    context
  end
end

#compile(context) ⇒ Object



1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
# File 'lib/ytljit/vm.rb', line 1418

def compile(context)
  context = super(context)

  sig = context.to_signature.dup
  sig[2] = @type
=begin
  pp sig
  pp @name
  pp @code_spaces.map{|a| a[0]}
=end

  cs = self.find_cs_by_signature(sig)
  if cs then
    asm = context.assembler
    add = lambda { @klass_object.address }
    var_klassclass = OpVarImmidiateAddress.new(add)
    context.start_arg_reg
    asm.with_retry do
      asm.mov(FUNC_ARG_YTL[0], BPR)
      asm.mov(FUNC_ARG_YTL[1], 4)
      asm.mov(FUNC_ARG_YTL[2], var_klassclass)
    end
    context.set_reg_content(FUNC_ARG_YTL[0].dst_opecode, BPR)
    context.set_reg_content(FUNC_ARG_YTL[1].dst_opecode, true)
    context.set_reg_content(FUNC_ARG_YTL[2].dst_opecode, self)
    add = cs.var_base_address
    context = gen_call(context, add, 3)
    context.end_arg_reg
  end
  
  context
end

#construct_frame_info(locals, argnum, args) ⇒ Object



1383
1384
1385
1386
1387
1388
1389
1390
# File 'lib/ytljit/vm.rb', line 1383

def construct_frame_info(locals, argnum, args)
  locals.unshift :_self
  locals.unshift :_block
  locals.unshift :_prev_env
  argnum += 3
  args = add_arg_to_args(args, 3)
  super(locals, argnum, args)
end

#get_constant_tab(klassobj = @klass_object) ⇒ Object



1306
1307
1308
1309
1310
1311
1312
1313
1314
# File 'lib/ytljit/vm.rb', line 1306

def get_constant_tab(klassobj = @klass_object)
  ktop =  @@class_top_tab[klassobj]
  if ktop then
    ktop.constant_tab
  else
    ktop.constant_tab = {}
    ktop.constant_tab
  end
end

#get_constant_valueObject



1451
1452
1453
# File 'lib/ytljit/vm.rb', line 1451

def get_constant_value
  [@klass_object]
end

#get_method_tab(klassobj = @klass_object) ⇒ Object



1297
1298
1299
1300
1301
1302
1303
1304
# File 'lib/ytljit/vm.rb', line 1297

def get_method_tab(klassobj = @klass_object)
  ktop =  @@class_top_tab[klassobj]
  if ktop then
    ktop.method_tab
  else
    {}
  end
end

#make_klassclass_nodeObject



1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
# File 'lib/ytljit/vm.rb', line 1286

def make_klassclass_node
  if @klassclass_node == nil then
    clsclsnode = ClassTopNode.new(self, 
                                  @klassclass, 
                                  @klassclass.name)
    clsclsnode.body = DummyNode.new
    @klassclass_node = clsclsnode
  end
  @klassclass_node
end

#search_constant_with_super(name, klassobj = @klass_object) ⇒ Object



1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
# File 'lib/ytljit/vm.rb', line 1369

def search_constant_with_super(name, klassobj = @klass_object)
  clsnode = @@class_top_tab[klassobj]
  if clsnode then
    ctab = clsnode.get_constant_tab
    if val = ctab[name] then
      return [val, clsnode]
    end

    return search_constant_with_super(name, klassobj.superclass)
  end

  [nil, nil]
end

#search_method_with_super(name, klassobj = @klass_object) ⇒ Object



1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
# File 'lib/ytljit/vm.rb', line 1336

def search_method_with_super(name, klassobj = @klass_object)
  clsnode = @@class_top_tab[klassobj]
  if clsnode then
    clsnode.before_search_module.each do |scope, mod|
      mtab = mod.get_method_tab
      if val = mtab[name] then
        return [val, mod]
      end
    end

    mtab = clsnode.get_method_tab
    if val = mtab[name] then
      return [val, clsnode]
    end

    clsnode.after_search_module.each do |scope, mod|
      mtab = mod.get_method_tab
      if val = mtab[name] then
        return [val, mod]
      end
    end

    if klassobj.is_a?(Class) then
      return search_method_with_super(name, klassobj.superclass)
    else
      # klassobj is Module
      return search_method_with_super(name, Object)
    end
  end

  [nil, nil]
end