Files
wasmtime/meta/gen_settings.py
Jakob Stoklund Olesen cfeefde3fc Scaffolding for defining settings.
Settings can be defined globally or per-ISA. They are available to code through
a generated Settings struct with accessor methods per setting.
2016-08-05 15:50:57 -07:00

105 lines
3.0 KiB
Python

"""
Generate sources with settings.
"""
import srcgen
from cretonne import BoolSetting, NumSetting, settings
def layout_group(sgrp):
"""
Layout the settings in sgrp, assigning byte and bit offsets.
Return the next unused byte offset.
"""
# Byte offset where booleans are allocated.
bool_byte = -1
# Next available bit number in bool_byte.
bool_bit = 10
# Next available whole byte.
next_byte = 0
for setting in sgrp.settings:
if isinstance(setting, BoolSetting):
# Allocate a bit from bool_byte.
if bool_bit > 7:
bool_byte = next_byte
next_byte += 1
bool_bit = 0
setting.byte_offset = bool_byte
setting.bit_offset = bool_bit
bool_bit += 1
else:
# This is a numerical or enumerated setting. Allocate a single
# byte.
setting.byte_offset = next_byte
next_byte += 1
return next_byte
def gen_getter(setting, fmt):
"""
Emit a getter function for `setting`.
"""
fmt.doc_comment(setting.__doc__ + '.')
if isinstance(setting, BoolSetting):
proto = 'pub fn {}(&self) -> bool'.format(setting.name)
with fmt.indented(proto + ' {', '}'):
fmt.line('(self.bytes[{}] & (1 << {})) != 0'.format(
setting.byte_offset,
setting.bit_offset))
elif isinstance(setting, NumSetting):
proto = 'pub fn {}(&self) -> u8'.format(setting.name)
with fmt.indented(proto + ' {', '}'):
fmt.line('self.bytes[{}]'.format(setting.byte_offset))
else:
raise AssertionError("Unknown setting kind")
def gen_getters(sgrp, fmt):
"""
Emit getter functions for all the settings in fmt.
"""
fmt.doc_comment("User-defined settings.")
with fmt.indented('impl Settings {', '}'):
for setting in sgrp.settings:
gen_getter(setting, fmt)
def gen_default(sgrp, byte_size, fmt):
"""
Emit a Default impl for Settings.
"""
v = [0] * byte_size
for setting in sgrp.settings:
v[setting.byte_offset] |= setting.default_byte()
with fmt.indented('impl Default for Settings {', '}'):
fmt.doc_comment('Return a `Settings` object with default values.')
with fmt.indented('fn default() -> Settings {', '}'):
with fmt.indented('Settings {', '}'):
vs = ', '.join('{:#04x}'.format(x) for x in v)
fmt.line('bytes: [ {} ],'.format(vs))
def gen_group(sgrp, fmt):
"""
Generate a Settings struct representing `sgrp`.
"""
byte_size = layout_group(sgrp)
fmt.doc_comment('Settings group `{}`.'.format(sgrp.name))
with fmt.indented('pub struct Settings {', '}'):
fmt.line('bytes: [u8; {}],'.format(byte_size))
gen_getters(sgrp, fmt)
gen_default(sgrp, byte_size, fmt)
def generate(isas, out_dir):
fmt = srcgen.Formatter()
gen_group(settings.group, fmt)
fmt.update_file('settings.rs', out_dir)