1a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#!/usr/bin/env python
2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#
3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# Copyright 2006-2008 the V8 project authors. All rights reserved.
4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# Redistribution and use in source and binary forms, with or without
5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# modification, are permitted provided that the following conditions are
6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# met:
7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#
8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#     * Redistributions of source code must retain the above copyright
9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#       notice, this list of conditions and the following disclaimer.
10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#     * Redistributions in binary form must reproduce the above
11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#       copyright notice, this list of conditions and the following
12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#       disclaimer in the documentation and/or other materials provided
13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#       with the distribution.
14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#     * Neither the name of Google Inc. nor the names of its
15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#       contributors may be used to endorse or promote products derived
16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#       from this software without specific prior written permission.
17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#
18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# This is a utility for converting JavaScript source code into C-style
31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# char arrays. It is used for embedded JavaScript code in the V8
32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# library.
33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockimport os, re, sys, string
35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockimport jsmin
36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockdef ToCArray(lines):
39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  result = []
40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for chr in lines:
41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    value = ord(chr)
42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    assert value < 128
43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    result.append(str(value))
44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  result.append("0")
45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return ", ".join(result)
46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockdef RemoveCommentsAndTrailingWhitespace(lines):
49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  lines = re.sub(r'//.*\n', '\n', lines) # end-of-line comments
50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  lines = re.sub(re.compile(r'/\*.*?\*/', re.DOTALL), '', lines) # comments.
51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  lines = re.sub(r'\s+\n+', '\n', lines) # trailing whitespace
52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return lines
53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockdef ReadFile(filename):
56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  file = open(filename, "rt")
57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  try:
58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    lines = file.read()
59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  finally:
60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    file.close()
61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return lines
62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockdef ReadLines(filename):
65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  result = []
66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for line in open(filename, "rt"):
67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if '#' in line:
68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      line = line[:line.index('#')]
69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    line = line.strip()
70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if len(line) > 0:
71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      result.append(line)
72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return result
73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockdef LoadConfigFrom(name):
76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  import ConfigParser
77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  config = ConfigParser.ConfigParser()
78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  config.read(name)
79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return config
80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockdef ParseValue(string):
83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  string = string.strip()
84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if string.startswith('[') and string.endswith(']'):
85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return string.lstrip('[').rstrip(']').split()
86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  else:
87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return string
88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockEVAL_PATTERN = re.compile(r'\beval\s*\(');
91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockWITH_PATTERN = re.compile(r'\bwith\s*\(');
92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockdef Validate(lines, file):
95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  lines = RemoveCommentsAndTrailingWhitespace(lines)
96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  # Because of simplified context setup, eval and with is not
97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  # allowed in the natives files.
98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  eval_match = EVAL_PATTERN.search(lines)
99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if eval_match:
100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    raise ("Eval disallowed in natives: %s" % file)
101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  with_match = WITH_PATTERN.search(lines)
102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if with_match:
103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    raise ("With statements disallowed in natives: %s" % file)
104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockdef ExpandConstants(lines, constants):
107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for key, value in constants.items():
108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    lines = lines.replace(key, str(value))
109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return lines
110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockdef ExpandMacros(lines, macros):
113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for name, macro in macros.items():
114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    start = lines.find(name + '(', 0)
115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    while start != -1:
116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      # Scan over the arguments
117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      assert lines[start + len(name)] == '('
118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      height = 1
119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      end = start + len(name) + 1
120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      last_match = end
121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      arg_index = 0
122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      mapping = { }
123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      def add_arg(str):
124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        # Remember to expand recursively in the arguments
125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        replacement = ExpandMacros(str.strip(), macros)
126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        mapping[macro.args[arg_index]] = replacement
127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      while end < len(lines) and height > 0:
128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        # We don't count commas at higher nesting levels.
129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        if lines[end] == ',' and height == 1:
130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          add_arg(lines[last_match:end])
131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          last_match = end + 1
132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        elif lines[end] in ['(', '{', '[']:
133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          height = height + 1
134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        elif lines[end] in [')', '}', ']']:
135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          height = height - 1
136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        end = end + 1
137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      # Remember to add the last match.
138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      add_arg(lines[last_match:end-1])
139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      result = macro.expand(mapping)
140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      # Replace the occurrence of the macro with the expansion
141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      lines = lines[:start] + result + lines[end:]
142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      start = lines.find(name + '(', end)
143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return lines
144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass TextMacro:
146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  def __init__(self, args, body):
147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    self.args = args
148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    self.body = body
149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  def expand(self, mapping):
150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    result = self.body
151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    for key, value in mapping.items():
152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        result = result.replace(key, value)
153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return result
154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass PythonMacro:
156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  def __init__(self, args, fun):
157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    self.args = args
158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    self.fun = fun
159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  def expand(self, mapping):
160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    args = []
161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    for arg in self.args:
162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      args.append(mapping[arg])
163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return str(self.fun(*args))
164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockCONST_PATTERN = re.compile(r'^const\s+([a-zA-Z0-9_]+)\s*=\s*([^;]*);$')
166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockMACRO_PATTERN = re.compile(r'^macro\s+([a-zA-Z0-9_]+)\s*\(([^)]*)\)\s*=\s*([^;]*);$')
167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockPYTHON_MACRO_PATTERN = re.compile(r'^python\s+macro\s+([a-zA-Z0-9_]+)\s*\(([^)]*)\)\s*=\s*([^;]*);$')
168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockdef ReadMacros(lines):
170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  constants = { }
171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  macros = { }
172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for line in lines:
173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    hash = line.find('#')
174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if hash != -1: line = line[:hash]
175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    line = line.strip()
176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if len(line) is 0: continue
177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    const_match = CONST_PATTERN.match(line)
178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if const_match:
179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      name = const_match.group(1)
180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      value = const_match.group(2).strip()
181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      constants[name] = value
182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    else:
183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      macro_match = MACRO_PATTERN.match(line)
184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      if macro_match:
185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        name = macro_match.group(1)
186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        args = map(string.strip, macro_match.group(2).split(','))
187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        body = macro_match.group(3).strip()
188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        macros[name] = TextMacro(args, body)
189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      else:
190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        python_match = PYTHON_MACRO_PATTERN.match(line)
191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        if python_match:
192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          name = python_match.group(1)
193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          args = map(string.strip, python_match.group(2).split(','))
194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          body = python_match.group(3).strip()
195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          fun = eval("lambda " + ",".join(args) + ': ' + body)
196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          macros[name] = PythonMacro(args, fun)
197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        else:
198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          raise ("Illegal line: " + line)
199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return (constants, macros)
200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHEADER_TEMPLATE = """\
203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Copyright 2008 Google Inc. All Rights Reserved.
204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// This file was generated from .js source files by SCons.  If you
206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// want to make changes to this file you should either change the
207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// javascript source files or the SConstruct script.
208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "v8.h"
210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "natives.h"
211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 {
213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal {
214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block%(source_lines)s\
216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  template <>
218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int NativesCollection<%(type)s>::GetBuiltinsCount() {
219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return %(builtin_count)i;
220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  template <>
2233100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  int NativesCollection<%(type)s>::GetDebuggerCount() {
2243100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    return %(debugger_count)i;
225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  template <>
228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int NativesCollection<%(type)s>::GetIndex(const char* name) {
229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block%(get_index_cases)s\
230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return -1;
231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  template <>
234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Vector<const char> NativesCollection<%(type)s>::GetScriptSource(int index) {
235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block%(get_script_source_cases)s\
236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return Vector<const char>("", 0);
237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  template <>
240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Vector<const char> NativesCollection<%(type)s>::GetScriptName(int index) {
241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block%(get_script_name_cases)s\
242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return Vector<const char>("", 0);
243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}  // internal
246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}  // v8
247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block"""
248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockSOURCE_DECLARATION = """\
251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const char %(id)s[] = { %(data)s };
252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block"""
253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2553100271588b61cbc1dc472a3f2f105d2eed8497fAndrei PopescuGET_DEBUGGER_INDEX_CASE = """\
256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (strcmp(name, "%(id)s") == 0) return %(i)i;
257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block"""
258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2603100271588b61cbc1dc472a3f2f105d2eed8497fAndrei PopescuGET_DEBUGGER_SCRIPT_SOURCE_CASE = """\
261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (index == %(i)i) return Vector<const char>(%(id)s, %(length)i);
262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block"""
263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2653100271588b61cbc1dc472a3f2f105d2eed8497fAndrei PopescuGET_DEBUGGER_SCRIPT_NAME_CASE = """\
266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (index == %(i)i) return Vector<const char>("%(name)s", %(length)i);
267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block"""
268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockdef JS2C(source, target, env):
270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ids = []
2713100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  debugger_ids = []
272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  modules = []
273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  # Locate the macros file name.
274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  consts = {}
275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  macros = {}
276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for s in source:
277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if 'macros.py' == (os.path.split(str(s))[1]):
278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      (consts, macros) = ReadMacros(ReadLines(str(s)))
279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    else:
280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      modules.append(s)
281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  # Build source code lines
283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  source_lines = [ ]
284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  minifier = jsmin.JavaScriptMinifier()
286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  source_lines_empty = []
288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for module in modules:
289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    filename = str(module)
2903100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    debugger = filename.endswith('-debugger.js')
291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    lines = ReadFile(filename)
292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    lines = ExpandConstants(lines, consts)
293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    lines = ExpandMacros(lines, macros)
294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Validate(lines, filename)
295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    lines = minifier.JSMinify(lines)
296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    data = ToCArray(lines)
297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    id = (os.path.split(filename)[1])[:-3]
2983100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    if debugger: id = id[:-9]
2993100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    if debugger:
3003100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      debugger_ids.append((id, len(lines)))
301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    else:
302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      ids.append((id, len(lines)))
303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    source_lines.append(SOURCE_DECLARATION % { 'id': id, 'data': data })
304d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    source_lines_empty.append(SOURCE_DECLARATION % { 'id': id, 'data': data })
305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3063100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  # Build debugger support functions
307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  get_index_cases = [ ]
308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  get_script_source_cases = [ ]
309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  get_script_name_cases = [ ]
310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i = 0
3123100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  for (id, length) in debugger_ids:
313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    native_name = "native %s.js" % id
3143100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    get_index_cases.append(GET_DEBUGGER_INDEX_CASE % { 'id': id, 'i': i })
3153100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    get_script_source_cases.append(GET_DEBUGGER_SCRIPT_SOURCE_CASE % {
316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      'id': id,
317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      'length': length,
318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      'i': i
319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    })
3203100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    get_script_name_cases.append(GET_DEBUGGER_SCRIPT_NAME_CASE % {
321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      'name': native_name,
322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      'length': len(native_name),
323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      'i': i
324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    });
325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    i = i + 1
326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (id, length) in ids:
328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    native_name = "native %s.js" % id
3293100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    get_index_cases.append(GET_DEBUGGER_INDEX_CASE % { 'id': id, 'i': i })
3303100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    get_script_source_cases.append(GET_DEBUGGER_SCRIPT_SOURCE_CASE % {
331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      'id': id,
332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      'length': length,
333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      'i': i
334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    })
3353100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    get_script_name_cases.append(GET_DEBUGGER_SCRIPT_NAME_CASE % {
336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      'name': native_name,
337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      'length': len(native_name),
338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      'i': i
339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    });
340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    i = i + 1
341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  # Emit result
343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  output = open(str(target[0]), "w")
344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  output.write(HEADER_TEMPLATE % {
3453100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    'builtin_count': len(ids) + len(debugger_ids),
3463100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    'debugger_count': len(debugger_ids),
347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    'source_lines': "\n".join(source_lines),
348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    'get_index_cases': "".join(get_index_cases),
349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    'get_script_source_cases': "".join(get_script_source_cases),
350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    'get_script_name_cases': "".join(get_script_name_cases),
351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    'type': env['TYPE']
352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  })
353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  output.close()
354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if len(target) > 1:
356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    output = open(str(target[1]), "w")
357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    output.write(HEADER_TEMPLATE % {
3583100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      'builtin_count': len(ids) + len(debugger_ids),
3593100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      'debugger_count': len(debugger_ids),
360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      'source_lines': "\n".join(source_lines_empty),
361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      'get_index_cases': "".join(get_index_cases),
362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      'get_script_source_cases': "".join(get_script_source_cases),
363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      'get_script_name_cases': "".join(get_script_name_cases),
364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      'type': env['TYPE']
365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    })
366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    output.close()
367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockdef main():
369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  natives = sys.argv[1]
370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  natives_empty = sys.argv[2]
371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  type = sys.argv[3]
372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  source_files = sys.argv[4:]
373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  JS2C(source_files, [natives, natives_empty], { 'TYPE': type })
374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockif __name__ == "__main__":
376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  main()
377