# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# This script generates jit/CacheIROpsGenerated.h from CacheIROps.yaml
import os
import os.path
import buildconfig
import six
import yaml
from mozbuild.preprocessor
import Preprocessor
HEADER_TEMPLATE =
"" "\
/* This Source Code Form
is subject to the terms of the Mozilla Public
* License, v. 2.0.
If a copy of the MPL was
not distributed
with this
* file, You can obtain one at
http://mozilla.org/MPL/2.0/. */
#ifndef %(includeguard)s
#define %(includeguard)s
/* This file
is generated by jit/GenerateCacheIRFiles.py. Do
not edit! */
%(contents)s
#endif // %(includeguard)s
"" "
def generate_header(c_out, includeguard, contents):
c_out.write(
HEADER_TEMPLATE
% {
"includeguard" : includeguard,
"contents" : contents,
}
)
def load_yaml(yaml_path):
# First invoke preprocessor.py so that we can use #ifdef JS_SIMULATOR in
# the YAML file.
pp = Preprocessor()
pp.context.update(buildconfig.defines[
"ALLDEFINES" ])
pp.out = six.StringIO()
pp.do_filter(
"substitution" )
pp.do_include(yaml_path)
contents = pp.out.getvalue()
return yaml.safe_load(contents)
# Information for generating CacheIRWriter code for a single argument. Tuple
# stores the C++ argument type and the CacheIRWriter method to call.
arg_writer_info = {
"ValId" : (
"ValOperandId" ,
"writeOperandId" ),
"ObjId" : (
"ObjOperandId" ,
"writeOperandId" ),
"StringId" : (
"StringOperandId" ,
"writeOperandId" ),
"SymbolId" : (
"SymbolOperandId" ,
"writeOperandId" ),
"BooleanId" : (
"BooleanOperandId" ,
"writeOperandId" ),
"Int32Id" : (
"Int32OperandId" ,
"writeOperandId" ),
"NumberId" : (
"NumberOperandId" ,
"writeOperandId" ),
"BigIntId" : (
"BigIntOperandId" ,
"writeOperandId" ),
"ValueTagId" : (
"ValueTagOperandId" ,
"writeOperandId" ),
"IntPtrId" : (
"IntPtrOperandId" ,
"writeOperandId" ),
"RawId" : (
"OperandId" ,
"writeOperandId" ),
"ShapeField" : (
"Shape*" ,
"writeShapeField" ),
"WeakShapeField" : (
"Shape*" ,
"writeWeakShapeField" ),
"WeakGetterSetterField" : (
"GetterSetter*" ,
"writeWeakGetterSetterField" ),
"ObjectField" : (
"JSObject*" ,
"writeObjectField" ),
"WeakObjectField" : (
"JSObject*" ,
"writeWeakObjectField" ),
"StringField" : (
"JSString*" ,
"writeStringField" ),
"AtomField" : (
"JSAtom*" ,
"writeStringField" ),
"SymbolField" : (
"JS::Symbol*" ,
"writeSymbolField" ),
"WeakBaseScriptField" : (
"BaseScript*" ,
"writeWeakBaseScriptField" ),
"JitCodeField" : (
"JitCode*" ,
"writeJitCodeField" ),
"RawInt32Field" : (
"uint32_t" ,
"writeRawInt32Field" ),
"RawPointerField" : (
"const void*" ,
"writeRawPointerField" ),
"IdField" : (
"jsid" ,
"writeIdField" ),
"ValueField" : (
"const Value&" ,
"writeValueField" ),
"RawInt64Field" : (
"uint64_t" ,
"writeRawInt64Field" ),
"DoubleField" : (
"double" ,
"writeDoubleField" ),
"AllocSiteField" : (
"gc::AllocSite*" ,
"writeAllocSiteField" ),
"JSOpImm" : (
"JSOp" ,
"writeJSOpImm" ),
"JSTypeImm" : (
"JSType" ,
"writeJSTypeImm" ),
"TypeofEqOperandImm" : (
"TypeofEqOperand" ,
"writeTypeofEqOperandImm" ),
"BoolImm" : (
"bool" ,
"writeBoolImm" ),
"ByteImm" : (
"uint32_t" ,
"writeByteImm" ),
# uint32_t to enable fits-in-byte asserts.
"GuardClassKindImm" : (
"GuardClassKind" ,
"writeGuardClassKindImm" ),
"ArrayBufferViewKindImm" : (
"ArrayBufferViewKind" ,
"writeArrayBufferViewKindImm" ),
"ValueTypeImm" : (
"ValueType" ,
"writeValueTypeImm" ),
"JSWhyMagicImm" : (
"JSWhyMagic" ,
"writeJSWhyMagicImm" ),
"CallFlagsImm" : (
"CallFlags" ,
"writeCallFlagsImm" ),
"ScalarTypeImm" : (
"Scalar::Type" ,
"writeScalarTypeImm" ),
"UnaryMathFunctionImm" : (
"UnaryMathFunction" ,
"writeUnaryMathFunctionImm" ),
"WasmValTypeImm" : (
"wasm::ValType::Kind" ,
"writeWasmValTypeImm" ),
"Int32Imm" : (
"int32_t" ,
"writeInt32Imm" ),
"UInt32Imm" : (
"uint32_t" ,
"writeUInt32Imm" ),
"JSNativeImm" : (
"JSNative" ,
"writeJSNativeImm" ),
"StaticStringImm" : (
"const char*" ,
"writeStaticStringImm" ),
"AllocKindImm" : (
"gc::AllocKind" ,
"writeAllocKindImm" ),
"CompletionKindImm" : (
"CompletionKind" ,
"writeCompletionKindImm" ),
"RealmFuseIndexImm" : (
"RealmFuses::FuseIndex" ,
"writeRealmFuseIndexImm" ),
}
def gen_writer_method(name, args, custom_writer):
"" "Generates a CacheIRWRiter method for a single opcode." ""
# Generate a single method that writes the opcode and each argument.
# For example:
#
# void guardShape(ObjOperandId obj, Shape* shape) {
# writeOp(CacheOp::GuardShape);
# writeOperandId(obj);
# writeShapeField(shape);
# assertLengthMatches();
# }
#
# The assertLengthMatches() call is to assert the information in the
# arg_length dictionary below matches what's written.
# Method names start with a lowercase letter.
method_name = name[0].lower() + name[1:]
if custom_writer:
method_name +=
"_"
method_args = []
ret_type =
"void"
args_code =
""
if args:
for arg_name, arg_type
in six.iteritems(args):
cpp_type, write_method = arg_writer_info[arg_type]
if arg_name ==
"result" :
ret_type = cpp_type
args_code +=
" {} result(newOperandId());\\\n" .format(cpp_type)
args_code +=
" writeOperandId(result);\\\n"
else :
method_args.append(
"{} {}" .format(cpp_type, arg_name))
args_code +=
" {}({});\\\n" .format(write_method, arg_name)
code =
""
if custom_writer:
code +=
"private:\\\n"
code +=
"{} {}({}) {{\\\n" .format(ret_type, method_name,
", " .join(method_args))
code +=
" writeOp(CacheOp::{});\\\n" .format(name)
code += args_code
code +=
" assertLengthMatches();\\\n"
if ret_type !=
"void" :
code +=
" return result;\\\n"
code +=
"}"
if custom_writer:
code +=
"\\\npublic:"
return code
# Information for generating code using CacheIRReader for a single argument.
# Tuple stores the C++ type, the suffix used for arguments/variables of this
# type, and the expression to read this type from CacheIRReader.
arg_reader_info = {
"ValId" : (
"ValOperandId" ,
"Id" ,
"reader.valOperandId()" ),
"ObjId" : (
"ObjOperandId" ,
"Id" ,
"reader.objOperandId()" ),
"StringId" : (
"StringOperandId" ,
"Id" ,
"reader.stringOperandId()" ),
"SymbolId" : (
"SymbolOperandId" ,
"Id" ,
"reader.symbolOperandId()" ),
"BooleanId" : (
"BooleanOperandId" ,
"Id" ,
"reader.booleanOperandId()" ),
"Int32Id" : (
"Int32OperandId" ,
"Id" ,
"reader.int32OperandId()" ),
"NumberId" : (
"NumberOperandId" ,
"Id" ,
"reader.numberOperandId()" ),
"BigIntId" : (
"BigIntOperandId" ,
"Id" ,
"reader.bigIntOperandId()" ),
"ValueTagId" : (
"ValueTagOperandId" ,
"Id" ,
"reader.valueTagOperandId()" ),
"IntPtrId" : (
"IntPtrOperandId" ,
"Id" ,
"reader.intPtrOperandId()" ),
"RawId" : (
"uint32_t" ,
"Id" ,
"reader.rawOperandId()" ),
"ShapeField" : (
"uint32_t" ,
"Offset" ,
"reader.stubOffset()" ),
"WeakShapeField" : (
"uint32_t" ,
"Offset" ,
"reader.stubOffset()" ),
"WeakGetterSetterField" : (
"uint32_t" ,
"Offset" ,
"reader.stubOffset()" ),
"ObjectField" : (
"uint32_t" ,
"Offset" ,
"reader.stubOffset()" ),
"WeakObjectField" : (
"uint32_t" ,
"Offset" ,
"reader.stubOffset()" ),
"StringField" : (
"uint32_t" ,
"Offset" ,
"reader.stubOffset()" ),
"AtomField" : (
"uint32_t" ,
"Offset" ,
"reader.stubOffset()" ),
"SymbolField" : (
"uint32_t" ,
"Offset" ,
"reader.stubOffset()" ),
"WeakBaseScriptField" : (
"uint32_t" ,
"Offset" ,
"reader.stubOffset()" ),
"JitCodeField" : (
"uint32_t" ,
"Offset" ,
"reader.stubOffset()" ),
"RawInt32Field" : (
"uint32_t" ,
"Offset" ,
"reader.stubOffset()" ),
"RawPointerField" : (
"uint32_t" ,
"Offset" ,
"reader.stubOffset()" ),
"IdField" : (
"uint32_t" ,
"Offset" ,
"reader.stubOffset()" ),
"ValueField" : (
"uint32_t" ,
"Offset" ,
"reader.stubOffset()" ),
"RawInt64Field" : (
"uint32_t" ,
"Offset" ,
"reader.stubOffset()" ),
"DoubleField" : (
"uint32_t" ,
"Offset" ,
"reader.stubOffset()" ),
"AllocSiteField" : (
"uint32_t" ,
"Offset" ,
"reader.stubOffset()" ),
"JSOpImm" : (
"JSOp" ,
"" ,
"reader.jsop()" ),
"JSTypeImm" : (
"JSType" ,
"" ,
"reader.jstype()" ),
"TypeofEqOperandImm" : (
"TypeofEqOperand" ,
"" ,
"reader.typeofEqOperand()" ),
"BoolImm" : (
"bool" ,
"" ,
"reader.readBool()" ),
"ByteImm" : (
"uint8_t" ,
"" ,
"reader.readByte()" ),
"GuardClassKindImm" : (
"GuardClassKind" ,
"" ,
"reader.guardClassKind()" ),
"ArrayBufferViewKindImm" : (
"ArrayBufferViewKind" ,
"" ,
"reader.arrayBufferViewKind()" ,
),
"ValueTypeImm" : (
"ValueType" ,
"" ,
"reader.valueType()" ),
"JSWhyMagicImm" : (
"JSWhyMagic" ,
"" ,
"reader.whyMagic()" ),
"CallFlagsImm" : (
"CallFlags" ,
"" ,
"reader.callFlags()" ),
"ScalarTypeImm" : (
"Scalar::Type" ,
"" ,
"reader.scalarType()" ),
"UnaryMathFunctionImm" : (
"UnaryMathFunction" ,
"" ,
"reader.unaryMathFunction()" ),
"WasmValTypeImm" : (
"wasm::ValType::Kind" ,
"" ,
"reader.wasmValType()" ),
"Int32Imm" : (
"int32_t" ,
"" ,
"reader.int32Immediate()" ),
"UInt32Imm" : (
"uint32_t" ,
"" ,
"reader.uint32Immediate()" ),
"JSNativeImm" : (
"JSNative" ,
"" ,
"reinterpret_cast(reader.pointer())" ),
"StaticStringImm" : (
"const char*" ,
"" ,
"reinterpret_cast(reader.pointer())" ),
"AllocKindImm" : (
"gc::AllocKind" ,
"" ,
"reader.allocKind()" ),
"CompletionKindImm" : (
"CompletionKind" ,
"" ,
"reader.completionKind()" ),
"RealmFuseIndexImm" : (
"RealmFuses::FuseIndex" ,
"" ,
"reader.realmFuseIndex()" ),
}
def gen_compiler_method(name, args):
"" "Generates CacheIRCompiler or WarpCacheIRTranspiler header code for a
single opcode.
"" "
method_name =
"emit" + name
# We generate the signature of the method that needs to be implemented and a
# separate function forwarding to it. For example:
#
# [[nodiscard]] bool emitGuardShape(ObjOperandId objId, uint32_t shapeOffset);
# [[nodiscard]] bool emitGuardShape(CacheIRReader& reader) {
# ObjOperandId objId = reader.objOperandId();
# uint32_t shapeOffset = reader.stubOffset();
# return emitGuardShape(objId, shapeOffset);
# }
cpp_args = []
method_args = []
args_code =
""
if args:
for arg_name, arg_type
in six.iteritems(args):
cpp_type, suffix, readexpr = arg_reader_info[arg_type]
cpp_name = arg_name + suffix
cpp_args.append(cpp_name)
method_args.append(
"{} {}" .format(cpp_type, cpp_name))
args_code +=
" {} {} = {};\\\n" .format(cpp_type, cpp_name, readexpr)
# Generate signature.
code =
"[[nodiscard]] bool {}({});\\\n" .format(method_name,
", " .join(method_args))
# Generate the method forwarding to it.
code +=
"[[nodiscard]] bool {}(CacheIRReader& reader) {{\\\n" .format(method_name)
code += args_code
code +=
" return {}({});\\\n" .format(method_name,
", " .join(cpp_args))
code +=
"}\\\n"
return code
# For each argument type, the method name for printing it.
arg_spewer_method = {
"ValId" :
"spewOperandId" ,
"ObjId" :
"spewOperandId" ,
"StringId" :
"spewOperandId" ,
"SymbolId" :
"spewOperandId" ,
"BooleanId" :
"spewOperandId" ,
"Int32Id" :
"spewOperandId" ,
"NumberId" :
"spewOperandId" ,
"BigIntId" :
"spewOperandId" ,
"ValueTagId" :
"spewOperandId" ,
"IntPtrId" :
"spewOperandId" ,
"RawId" :
"spewRawOperandId" ,
"ShapeField" :
"spewField" ,
"WeakShapeField" :
"spewField" ,
"WeakGetterSetterField" :
"spewField" ,
"ObjectField" :
"spewField" ,
"WeakObjectField" :
"spewField" ,
"StringField" :
"spewField" ,
"AtomField" :
"spewField" ,
"SymbolField" :
"spewField" ,
"WeakBaseScriptField" :
"spewField" ,
"JitCodeField" :
"spewField" ,
"RawInt32Field" :
"spewField" ,
"RawPointerField" :
"spewField" ,
"IdField" :
"spewField" ,
"ValueField" :
"spewField" ,
"RawInt64Field" :
"spewField" ,
"DoubleField" :
"spewField" ,
"AllocSiteField" :
"spewField" ,
"JSOpImm" :
"spewJSOpImm" ,
"JSTypeImm" :
"spewJSTypeImm" ,
"TypeofEqOperandImm" :
"spewTypeofEqOperandImm" ,
"BoolImm" :
"spewBoolImm" ,
"ByteImm" :
"spewByteImm" ,
"GuardClassKindImm" :
"spewGuardClassKindImm" ,
"ArrayBufferViewKindImm" :
"spewArrayBufferViewKindImm" ,
"ValueTypeImm" :
"spewValueTypeImm" ,
"JSWhyMagicImm" :
"spewJSWhyMagicImm" ,
"CallFlagsImm" :
"spewCallFlagsImm" ,
"ScalarTypeImm" :
"spewScalarTypeImm" ,
"UnaryMathFunctionImm" :
"spewUnaryMathFunctionImm" ,
"WasmValTypeImm" :
"spewWasmValTypeImm" ,
"Int32Imm" :
"spewInt32Imm" ,
"UInt32Imm" :
"spewUInt32Imm" ,
"JSNativeImm" :
"spewJSNativeImm" ,
"StaticStringImm" :
"spewStaticStringImm" ,
"AllocKindImm" :
"spewAllocKindImm" ,
"CompletionKindImm" :
"spewCompletionKindImm" ,
"RealmFuseIndexImm" :
"spewRealmFuseIndexImm" ,
}
def gen_spewer_method(name, args):
"" "Generates spewer code for a single opcode." ""
method_name =
"spew" + name
# Generate code like this:
#
# void spewGuardShape(CacheIRReader& reader) {
# spewOp(CacheOp::GuardShape);
# spewOperandId("objId", reader.objOperandId());
# spewOperandSeparator();
# spewField("shapeOffset", reader.stubOffset());
# spewOpEnd();
# }
args_code =
""
if args:
is_first =
True
for arg_name, arg_type
in six.iteritems(args):
_, suffix, readexpr = arg_reader_info[arg_type]
arg_name += suffix
spew_method = arg_spewer_method[arg_type]
if not is_first:
args_code +=
" spewArgSeparator();\\\n"
args_code +=
' {}("{}", {});\\\n' .format(spew_method, arg_name, readexpr)
is_first =
False
code =
"void {}(CacheIRReader& reader) {{\\\n" .format(method_name)
code +=
" spewOp(CacheOp::{});\\\n" .format(name)
code += args_code
code +=
" spewOpEnd();\\\n"
code +=
"}\\\n"
return code
def gen_clone_method(name, args):
"" "Generates code for cloning a single opcode." ""
method_name =
"clone" + name
# Generate code like this:
#
# void cloneGuardShape(CacheIRReader& reader, CacheIRWriter& writer) {
# writer.writeOp(CacheOp::GuardShape);
# ObjOperandId objId = reader.objOperandId();
# writer.writeOperandId(objId);
# uint32_t shapeOffset = reader.stubOffset();
# Shape* shape = getShapeField(shapeOffset);
# writer.writeShapeField(shape);
# writer.assertLengthMatches();
# }
args_code =
""
if args:
for arg_name, arg_type
in six.iteritems(args):
if arg_type ==
"RawId" :
arg_type =
"ValId"
read_type, suffix, readexpr = arg_reader_info[arg_type]
read_name = arg_name + suffix
value_name = read_name
args_code +=
" {} {} = {};\\\n" .format(read_type, read_name, readexpr)
write_type, write_method = arg_writer_info[arg_type]
if arg_name ==
"result" :
args_code +=
" writer.newOperandId();\\\n"
if suffix ==
"Offset" :
# If the write function takes T&, the intermediate variable
# should be of type T.
if write_type.endswith(
"&" ):
write_type = write_type[:-1]
value_name = arg_name
args_code +=
" {} {} = get{}({});\\\n" .format(
write_type, value_name, arg_type, read_name
)
args_code +=
" writer.{}({});\\\n" .format(write_method, value_name)
code =
"void {}" .format(method_name)
code +=
"(CacheIRReader& reader, CacheIRWriter& writer) {{\\\n"
code +=
" writer.writeOp(CacheOp::{});\\\n" .format(name)
code += args_code
code +=
" writer.assertLengthMatches();\\\n"
code +=
"}}\\\n"
return code
# Length in bytes for each argument type, either an integer or a C++ expression.
# This is used to generate the CacheIROpArgLengths array. CacheIRWriter asserts
# the number of bytes written matches the value in that array.
arg_length = {
"ValId" : 1,
"ObjId" : 1,
"StringId" : 1,
"SymbolId" : 1,
"BooleanId" : 1,
"Int32Id" : 1,
"NumberId" : 1,
"BigIntId" : 1,
"ValueTagId" : 1,
"IntPtrId" : 1,
"RawId" : 1,
"ShapeField" : 1,
"WeakShapeField" : 1,
"WeakGetterSetterField" : 1,
"ObjectField" : 1,
"WeakObjectField" : 1,
"StringField" : 1,
"AtomField" : 1,
"SymbolField" : 1,
"WeakBaseScriptField" : 1,
"JitCodeField" : 1,
"RawInt32Field" : 1,
"RawPointerField" : 1,
"RawInt64Field" : 1,
"DoubleField" : 1,
"IdField" : 1,
"ValueField" : 1,
"AllocSiteField" : 1,
"ByteImm" : 1,
"BoolImm" : 1,
"CallFlagsImm" : 1,
"ScalarTypeImm" : 1,
"UnaryMathFunctionImm" : 1,
"JSOpImm" : 1,
"JSTypeImm" : 1,
"TypeofEqOperandImm" : 1,
"ValueTypeImm" : 1,
"GuardClassKindImm" : 1,
"ArrayBufferViewKindImm" : 1,
"JSWhyMagicImm" : 1,
"WasmValTypeImm" : 1,
"Int32Imm" : 4,
"UInt32Imm" : 4,
"JSNativeImm" :
"sizeof(uintptr_t)" ,
"StaticStringImm" :
"sizeof(uintptr_t)" ,
"AllocKindImm" : 1,
"CompletionKindImm" : 1,
"RealmFuseIndexImm" : 1,
}
def generate_cacheirops_header(c_out, yaml_path):
"" "Generate CacheIROpsGenerated.h from CacheIROps.yaml. The generated file
contains a list of all CacheIR ops
and generated source code
for
CacheIRWriter
and CacheIRCompiler.
"" "
data = load_yaml(yaml_path)
# CACHE_IR_OPS items. Each item stores an opcode name and arguments length
# expression. For example: _(GuardShape, 1 + 1)
ops_items = []
# Generated CacheIRWriter methods.
writer_methods = []
# Generated CacheIRCompiler methods.
compiler_shared_methods = []
compiler_unshared_methods = []
# Generated WarpCacheIRTranspiler methods.
transpiler_methods = []
# List of ops supported by WarpCacheIRTranspiler.
transpiler_ops = []
# Generated methods for spewers.
spewer_methods = []
# Generated methods for cloning IC stubs
clone_methods = []
for op
in data:
name = op[
"name" ]
args = op[
"args" ]
assert args
is None or isinstance(args, dict)
shared = op[
"shared" ]
assert isinstance(shared, bool)
transpile = op[
"transpile" ]
assert isinstance(transpile, bool)
# Unscored Ops default to UINT32_MAX
cost_estimate = op.get(
"cost_estimate" , int(0xFFFFFFFF))
assert isinstance(cost_estimate, int)
custom_writer = op.get(
"custom_writer" ,
False )
assert isinstance(custom_writer, bool)
if args:
args_length =
" + " .join([str(arg_length[v])
for v
in args.values()])
else :
args_length =
"0"
transpile_str =
"true" if transpile
else "false"
ops_items.append(
"_({}, {}, {}, {})" .format(name, args_length, transpile_str, cost_estimate)
)
writer_methods.append(gen_writer_method(name, args, custom_writer))
if shared:
compiler_shared_methods.append(gen_compiler_method(name, args))
else :
compiler_unshared_methods.append(gen_compiler_method(name, args))
if transpile:
transpiler_methods.append(gen_compiler_method(name, args))
transpiler_ops.append(
"_({})" .format(name))
spewer_methods.append(gen_spewer_method(name, args))
clone_methods.append(gen_clone_method(name, args))
contents =
"#define CACHE_IR_OPS(_)\\\n"
contents +=
"\\\n" .join(ops_items)
contents +=
"\n\n"
contents +=
"#define CACHE_IR_WRITER_GENERATED \\\n"
contents +=
"\\\n" .join(writer_methods)
contents +=
"\n\n"
contents +=
"#define CACHE_IR_COMPILER_SHARED_GENERATED \\\n"
contents +=
"\\\n" .join(compiler_shared_methods)
contents +=
"\n\n"
contents +=
"#define CACHE_IR_COMPILER_UNSHARED_GENERATED \\\n"
contents +=
"\\\n" .join(compiler_unshared_methods)
contents +=
"\n\n"
contents +=
"#define CACHE_IR_TRANSPILER_GENERATED \\\n"
contents +=
"\\\n" .join(transpiler_methods)
contents +=
"\n\n"
contents +=
"#define CACHE_IR_TRANSPILER_OPS(_)\\\n"
contents +=
"\\\n" .join(transpiler_ops)
contents +=
"\n\n"
contents +=
"#define CACHE_IR_SPEWER_GENERATED \\\n"
contents +=
"\\\n" .join(spewer_methods)
contents +=
"\n\n"
contents +=
"#define CACHE_IR_CLONE_GENERATED \\\n"
contents +=
"\\\n" .join(clone_methods)
contents +=
"\n\n"
generate_header(c_out,
"jit_CacheIROpsGenerated_h" , contents)
def read_aot_ics(ic_path):
ics =
""
idx = 0
for entry
in os.scandir(ic_path):
if entry.is_file()
and os.path.basename(entry.path).startswith(
"IC-" ):
with open(entry.path)
as f:
content = f.read().strip()
ics +=
" _(%d, %s) \\\n" % (idx, content)
idx += 1
return ics
def generate_aot_ics_header(c_out, ic_path):
"" "Generate CacheIROpsGenerated.h from AOT IC corpus." ""
# Read in all ICs from js/src/ics/IC-*.
ics = read_aot_ics(ic_path)
contents =
"#define JS_AOT_IC_DATA(_) \\\n"
contents += ics
contents +=
"\n"
generate_header(c_out,
"jit_CacheIRAOTGenerated_h" , contents)
Messung V0.5 C=88 H=96 G=91
¤ Dauer der Verarbeitung: 0.2 Sekunden
(vorverarbeitet)
¤
*© Formatika GbR, Deutschland