lines = ExpandMacroDefinition(lines, pos, name_pattern, macro, non_expander)
+INLINE_CONSTANT_PATTERN = re.compile(r'const\s+([a-zA-Z0-9_]+)\s*=\s*([^;\n]+)[;\n]')
+
+def ExpandInlineConstants(lines):
+ pos = 0
+ while True:
+ const_match = INLINE_CONSTANT_PATTERN.search(lines, pos)
+ if const_match is None:
+ # no more constants
+ return lines
+ name = const_match.group(1)
+ replacement = const_match.group(2)
+ name_pattern = re.compile("\\b%s\\b" % name)
+
+ # remove constant definition and replace
+ lines = (lines[:const_match.start()] +
+ re.sub(name_pattern, replacement, lines[const_match.end():]))
+
+ # advance position to where the constant defintion was
+ pos = const_match.start()
+
+
HEADER_TEMPLATE = """\
// Copyright 2011 Google Inc. All Rights Reserved.
template <>
void NativesCollection<%(type)s>::SetRawScriptsSource(Vector<const char> raw_source) {
- ASSERT(%(raw_total_length)i == raw_source.length());
+ DCHECK(%(raw_total_length)i == raw_source.length());
raw_sources = raw_source.start();
}
if macro_filename:
(consts, macros) = ReadMacros(ReadFile(macro_filename))
filter_chain.append(lambda l: ExpandConstants(l, consts))
- filter_chain.append(lambda l: ExpandInlineMacros(l))
filter_chain.append(lambda l: ExpandMacros(l, macros))
filter_chain.extend([
RemoveCommentsAndTrailingWhitespace,
+ ExpandInlineMacros,
+ ExpandInlineConstants,
Validate,
jsmin.JavaScriptMinifier().JSMinify
])
return result
-def BuildMetadata(sources, source_bytes, native_type, omit):
+def BuildMetadata(sources, source_bytes, native_type):
"""Build the meta data required to generate a libaries file.
Args:
source_bytes: A list of source bytes.
(The concatenation of all sources; might be compressed.)
native_type: The parameter for the NativesCollection template.
- omit: bool, whether we should omit the sources in the output.
Returns:
A dictionary for use with HEADER_TEMPLATE.
assert offset == len(raw_sources)
# If we have the raw sources we can declare them accordingly.
- have_raw_sources = source_bytes == raw_sources and not omit
+ have_raw_sources = source_bytes == raw_sources
raw_sources_declaration = (RAW_SOURCES_DECLARATION
if have_raw_sources else RAW_SOURCES_COMPRESSION_DECLARATION)
"builtin_count": len(sources.modules),
"debugger_count": sum(sources.is_debugger_id),
"sources_declaration": SOURCES_DECLARATION % ToCArray(source_bytes),
- "sources_data": ToCArray(source_bytes) if not omit else "",
"raw_sources_declaration": raw_sources_declaration,
"raw_total_length": sum(map(len, sources.modules)),
"total_length": total_length,
raise Error("Unknown compression type %s." % compression_type)
-def JS2C(source, target, native_type, compression_type, raw_file, omit):
+def PutInt(blob_file, value):
+ assert(value >= 0 and value < (1 << 28))
+ if (value < 1 << 6):
+ size = 1
+ elif (value < 1 << 14):
+ size = 2
+ elif (value < 1 << 22):
+ size = 3
+ else:
+ size = 4
+ value_with_length = (value << 2) | (size - 1)
+
+ byte_sequence = bytearray()
+ for i in xrange(size):
+ byte_sequence.append(value_with_length & 255)
+ value_with_length >>= 8;
+ blob_file.write(byte_sequence)
+
+
+def PutStr(blob_file, value):
+ PutInt(blob_file, len(value));
+ blob_file.write(value);
+
+
+def WriteStartupBlob(sources, startup_blob):
+ """Write a startup blob, as expected by V8 Initialize ...
+ TODO(vogelheim): Add proper method name.
+
+ Args:
+ sources: A Sources instance with the prepared sources.
+ startup_blob_file: Name of file to write the blob to.
+ """
+ output = open(startup_blob, "wb")
+
+ debug_sources = sum(sources.is_debugger_id);
+ PutInt(output, debug_sources)
+ for i in xrange(debug_sources):
+ PutStr(output, sources.names[i]);
+ PutStr(output, sources.modules[i]);
+
+ PutInt(output, len(sources.names) - debug_sources)
+ for i in xrange(debug_sources, len(sources.names)):
+ PutStr(output, sources.names[i]);
+ PutStr(output, sources.modules[i]);
+
+ output.close()
+
+
+def JS2C(source, target, native_type, compression_type, raw_file, startup_blob):
sources = PrepareSources(source)
sources_bytes = CompressMaybe(sources, compression_type)
- metadata = BuildMetadata(sources, sources_bytes, native_type, omit)
+ metadata = BuildMetadata(sources, sources_bytes, native_type)
# Optionally emit raw file.
if raw_file:
output.write(sources_bytes)
output.close()
+ if startup_blob:
+ WriteStartupBlob(sources, startup_blob);
+
# Emit resulting source file.
output = open(target, "w")
output.write(HEADER_TEMPLATE % metadata)
def main():
parser = optparse.OptionParser()
parser.add_option("--raw", action="store",
- help="file to write the processed sources array to.")
- parser.add_option("--omit", dest="omit", action="store_true",
- help="Omit the raw sources from the generated code.")
+ help="file to write the processed sources array to.")
+ parser.add_option("--startup_blob", action="store",
+ help="file to write the startup blob to.")
parser.set_usage("""js2c out.cc type compression sources.js ...
out.cc: C code to be generated.
type: type parameter for NativesCollection template.
sources.js: JS internal sources or macros.py.""")
(options, args) = parser.parse_args()
- JS2C(args[3:], args[0], args[1], args[2], options.raw, options.omit)
+ JS2C(args[3:], args[0], args[1], args[2], options.raw, options.startup_blob)
if __name__ == "__main__":