3737import string
3838
3939
40- def ToCArray (elements , step = 10 ):
41- slices = (elements [i :i + step ] for i in xrange (0 , len (elements ), step ))
42- slices = map (lambda s : ',' .join (str (x ) for x in s ), slices )
43- return ',\n ' .join (slices )
44-
45-
4640def ToCString (contents ):
47- return ToCArray (map (ord , contents ), step = 20 )
41+ step = 20
42+ slices = (contents [i :i + step ] for i in xrange (0 , len (contents ), step ))
43+ slices = map (lambda s : ',' .join (str (ord (c )) for c in s ), slices )
44+ return ',\n ' .join (slices )
4845
4946
5047def ReadFile (filename ):
@@ -164,72 +161,34 @@ def ReadMacros(lines):
164161 return (constants , macros )
165162
166163
167- TEMPLATE = """
168- #include "node.h"
169- #include "node_javascript.h"
170- #include "v8.h"
171- #include "env.h"
172- #include "env-inl.h"
173-
174- namespace node {{
175-
176- {definitions}
164+ HEADER_TEMPLATE = """\
165+ #ifndef NODE_NATIVES_H_
166+ #define NODE_NATIVES_H_
177167
178- v8::Local<v8::String> MainSource(Environment* env) {{
179- return internal_bootstrap_node_value.ToStringChecked(env->isolate());
180- }}
168+ #include <stdint.h>
181169
182- void DefineJavaScript(Environment* env, v8::Local<v8::Object> target) {{
183- {initializers}
184- }}
170+ #define NODE_NATIVES_MAP(V) \\
171+ {node_natives_map}
185172
173+ namespace node {{
174+ {sources}
186175}} // namespace node
187- """
188176
189- ONE_BYTE_STRING = """
190- static const uint8_t raw_{var}[] = {{ {data} }};
191- static struct : public v8::String::ExternalOneByteStringResource {{
192- const char* data() const override {{
193- return reinterpret_cast<const char*>(raw_{var});
194- }}
195- size_t length() const override {{ return arraysize(raw_{var}); }}
196- void Dispose() override {{ /* Default calls `delete this`. */ }}
197- v8::Local<v8::String> ToStringChecked(v8::Isolate* isolate) {{
198- return v8::String::NewExternalOneByte(isolate, this).ToLocalChecked();
199- }}
200- }} {var};
177+ #endif // NODE_NATIVES_H_
201178"""
202179
203- TWO_BYTE_STRING = """
204- static const uint16_t raw_{var}[] = {{ {data} }};
205- static struct : public v8::String::ExternalStringResource {{
206- const uint16_t* data() const override {{ return raw_{var}; }}
207- size_t length() const override {{ return arraysize(raw_{var}); }}
208- void Dispose() override {{ /* Default calls `delete this`. */ }}
209- v8::Local<v8::String> ToStringChecked(v8::Isolate* isolate) {{
210- return v8::String::NewExternalTwoByte(isolate, this).ToLocalChecked();
211- }}
212- }} {var};
213- """
214180
215- INITIALIZER = """\
216- CHECK(target->Set(env->context(),
217- {key}.ToStringChecked(env->isolate()),
218- {value}.ToStringChecked(env->isolate())).FromJust());
181+ NODE_NATIVES_MAP = """\
182+ V({escaped_id}) \\
219183"""
220184
221185
222- def Render (var , data ):
223- # Treat non-ASCII as UTF-8 and convert it to UTF-16.
224- if any (ord (c ) > 127 for c in data ):
225- template = TWO_BYTE_STRING
226- data = map (ord , data .decode ('utf-8' ).encode ('utf-16be' ))
227- data = [data [i ] * 256 + data [i + 1 ] for i in xrange (0 , len (data ), 2 )]
228- data = ToCArray (data )
229- else :
230- template = ONE_BYTE_STRING
231- data = ToCString (data )
232- return template .format (var = var , data = data )
186+ SOURCES = """\
187+ static const uint8_t {escaped_id}_name[] = {{
188+ {name}}};
189+ static const uint8_t {escaped_id}_data[] = {{
190+ {data}}};
191+ """
233192
234193
235194def JS2C (source , target ):
@@ -248,32 +207,36 @@ def JS2C(source, target):
248207 (consts , macros ) = ReadMacros (macro_lines )
249208
250209 # Build source code lines
251- definitions = []
252- initializers = []
210+ node_natives_map = []
211+ sources = []
253212
254- for name in modules :
255- lines = ReadFile (str (name ))
213+ for s in modules :
214+ lines = ReadFile (str (s ))
256215 lines = ExpandConstants (lines , consts )
257216 lines = ExpandMacros (lines , macros )
217+ data = ToCString (lines )
258218
259219 # On Windows, "./foo.bar" in the .gyp file is passed as "foo.bar"
260220 # so don't assume there is always a slash in the file path.
261- if '/' in name or '\\ ' in name :
262- name = '/' .join (re .split ('/|\\ \\ ' , name )[1 :])
221+ if '/' in s or '\\ ' in s :
222+ id = '/' .join (re .split ('/|\\ \\ ' , s )[1 :])
223+ else :
224+ id = s
225+
226+ if '.' in id :
227+ id = id .split ('.' , 1 )[0 ]
263228
264- name = name . split ( '.' , 1 )[ 0 ]
265- var = name .replace ('-' , '_' ).replace ('/' , '_' )
266- key = '%s_key' % var
267- value = '%s_value' % var
229+ name = ToCString ( id )
230+ escaped_id = id .replace ('-' , '_' ).replace ('/' , '_' )
231+ node_natives_map . append ( NODE_NATIVES_MAP . format ( ** locals ()))
232+ sources . append ( SOURCES . format ( ** locals ()))
268233
269- definitions .append (Render (key , name ))
270- definitions .append (Render (value , lines ))
271- initializers .append (INITIALIZER .format (key = key , value = value ))
234+ node_natives_map = '' .join (node_natives_map )
235+ sources = '' .join (sources )
272236
273237 # Emit result
274238 output = open (str (target [0 ]), "w" )
275- output .write (TEMPLATE .format (definitions = '' .join (definitions ),
276- initializers = '' .join (initializers )))
239+ output .write (HEADER_TEMPLATE .format (** locals ()))
277240 output .close ()
278241
279242def main ():
0 commit comments