line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package SPVM::Builder::Util; |
2
|
|
|
|
|
|
|
|
3
|
283
|
|
|
283
|
|
241631
|
use strict; |
|
283
|
|
|
|
|
721
|
|
|
283
|
|
|
|
|
9076
|
|
4
|
283
|
|
|
283
|
|
1508
|
use warnings; |
|
283
|
|
|
|
|
663
|
|
|
283
|
|
|
|
|
7293
|
|
5
|
283
|
|
|
283
|
|
1485
|
use Carp 'confess'; |
|
283
|
|
|
|
|
640
|
|
|
283
|
|
|
|
|
13528
|
|
6
|
283
|
|
|
283
|
|
13591
|
use Config; |
|
283
|
|
|
|
|
1078
|
|
|
283
|
|
|
|
|
10579
|
|
7
|
283
|
|
|
283
|
|
1757
|
use File::Path 'mkpath'; |
|
283
|
|
|
|
|
593
|
|
|
283
|
|
|
|
|
12446
|
|
8
|
283
|
|
|
283
|
|
160317
|
use Pod::Usage 'pod2usage'; |
|
283
|
|
|
|
|
13728689
|
|
|
283
|
|
|
|
|
27472
|
|
9
|
283
|
|
|
283
|
|
221531
|
use Getopt::Long 'GetOptionsFromArray'; |
|
283
|
|
|
|
|
2925737
|
|
|
283
|
|
|
|
|
1362
|
|
10
|
283
|
|
|
283
|
|
52245
|
use List::Util 'min'; |
|
283
|
|
|
|
|
679
|
|
|
283
|
|
|
|
|
31860
|
|
11
|
283
|
|
|
283
|
|
2267
|
use File::Basename 'dirname'; |
|
283
|
|
|
|
|
655
|
|
|
283
|
|
|
|
|
11638
|
|
12
|
283
|
|
|
283
|
|
1722
|
use File::Spec; |
|
283
|
|
|
|
|
683
|
|
|
283
|
|
|
|
|
6022
|
|
13
|
283
|
|
|
283
|
|
158326
|
use SPVM::Builder::Config; |
|
283
|
|
|
|
|
4570
|
|
|
283
|
|
|
|
|
12073
|
|
14
|
283
|
|
|
283
|
|
4614
|
use Encode 'decode'; |
|
283
|
|
|
|
|
1908
|
|
|
283
|
|
|
|
|
16009
|
|
15
|
283
|
|
|
283
|
|
1771
|
use File::Find 'find'; |
|
283
|
|
|
|
|
1699
|
|
|
283
|
|
|
|
|
1190856
|
|
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
# SPVM::Builder::Util is used from Makefile.PL |
18
|
|
|
|
|
|
|
# so this class must be wrote as pure perl script, not contain XS functions. |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
sub get_spvm_core_perl_class_file_names { |
21
|
1142
|
|
|
1142
|
0
|
19244
|
my @spvm_builder_class_file_names = qw( |
22
|
|
|
|
|
|
|
SPVM/BlessedObject/Array.pm |
23
|
|
|
|
|
|
|
SPVM/BlessedObject/Class.pm |
24
|
|
|
|
|
|
|
SPVM/BlessedObject.pm |
25
|
|
|
|
|
|
|
SPVM/BlessedObject/String.pm |
26
|
|
|
|
|
|
|
SPVM/Builder/API.pm |
27
|
|
|
|
|
|
|
SPVM/Builder/CC.pm |
28
|
|
|
|
|
|
|
SPVM/Builder/CompileInfo.pm |
29
|
|
|
|
|
|
|
SPVM/Builder/Compiler.pm |
30
|
|
|
|
|
|
|
SPVM/Builder/Config/Exe.pm |
31
|
|
|
|
|
|
|
SPVM/Builder/Config.pm |
32
|
|
|
|
|
|
|
SPVM/Builder/Env.pm |
33
|
|
|
|
|
|
|
SPVM/Builder/Exe.pm |
34
|
|
|
|
|
|
|
SPVM/Builder/LibInfo.pm |
35
|
|
|
|
|
|
|
SPVM/Builder/LinkInfo.pm |
36
|
|
|
|
|
|
|
SPVM/Builder/ObjectFileInfo.pm |
37
|
|
|
|
|
|
|
SPVM/Builder.pm |
38
|
|
|
|
|
|
|
SPVM/Builder/Resource.pm |
39
|
|
|
|
|
|
|
SPVM/Builder/Runtime.pm |
40
|
|
|
|
|
|
|
SPVM/Builder/Stack.pm |
41
|
|
|
|
|
|
|
SPVM/Builder/Util/API.pm |
42
|
|
|
|
|
|
|
SPVM/Builder/Util.pm |
43
|
|
|
|
|
|
|
SPVM/Document/ExchangeAPI.pm |
44
|
|
|
|
|
|
|
SPVM/ExchangeAPI/Class.pm |
45
|
|
|
|
|
|
|
SPVM/ExchangeAPI/Error.pm |
46
|
|
|
|
|
|
|
SPVM/ExchangeAPI.pm |
47
|
|
|
|
|
|
|
SPVM/Global.pm |
48
|
|
|
|
|
|
|
SPVM.pm |
49
|
|
|
|
|
|
|
); |
50
|
|
|
|
|
|
|
|
51
|
1142
|
|
|
|
|
4695
|
return \@spvm_builder_class_file_names; |
52
|
|
|
|
|
|
|
} |
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
sub get_spvm_core_header_file_names { |
55
|
|
|
|
|
|
|
|
56
|
1142
|
|
|
1142
|
0
|
27720
|
my @spvm_core_header_file_names = qw( |
57
|
|
|
|
|
|
|
spvm_allocator.h |
58
|
|
|
|
|
|
|
spvm_allow.h |
59
|
|
|
|
|
|
|
spvm_api_allocator.h |
60
|
|
|
|
|
|
|
spvm_api_arg.h |
61
|
|
|
|
|
|
|
spvm_api_basic_type.h |
62
|
|
|
|
|
|
|
spvm_api_class_var.h |
63
|
|
|
|
|
|
|
spvm_api_compiler.h |
64
|
|
|
|
|
|
|
spvm_api_field.h |
65
|
|
|
|
|
|
|
spvm_api.h |
66
|
|
|
|
|
|
|
spvm_api_method.h |
67
|
|
|
|
|
|
|
spvm_api_class_file.h |
68
|
|
|
|
|
|
|
spvm_api_runtime.h |
69
|
|
|
|
|
|
|
spvm_api_string_buffer.h |
70
|
|
|
|
|
|
|
spvm_api_type.h |
71
|
|
|
|
|
|
|
spvm_api_internal.h |
72
|
|
|
|
|
|
|
spvm_array_field_access.h |
73
|
|
|
|
|
|
|
spvm_attribute.h |
74
|
|
|
|
|
|
|
spvm_basic_type.h |
75
|
|
|
|
|
|
|
spvm_block.h |
76
|
|
|
|
|
|
|
spvm_call_method.h |
77
|
|
|
|
|
|
|
spvm_case_info.h |
78
|
|
|
|
|
|
|
spvm_check.h |
79
|
|
|
|
|
|
|
spvm_class_var_access.h |
80
|
|
|
|
|
|
|
spvm_class_var.h |
81
|
|
|
|
|
|
|
spvm_compiler.h |
82
|
|
|
|
|
|
|
spvm_constant.h |
83
|
|
|
|
|
|
|
spvm_dumper.h |
84
|
|
|
|
|
|
|
spvm_field_access.h |
85
|
|
|
|
|
|
|
spvm_field.h |
86
|
|
|
|
|
|
|
spvm_hash.h |
87
|
|
|
|
|
|
|
spvm_implement.h |
88
|
|
|
|
|
|
|
spvm_interface.h |
89
|
|
|
|
|
|
|
spvm_list.h |
90
|
|
|
|
|
|
|
spvm_method.h |
91
|
|
|
|
|
|
|
spvm_mutex.h |
92
|
|
|
|
|
|
|
spvm_class_file.h |
93
|
|
|
|
|
|
|
spvm_native.h |
94
|
|
|
|
|
|
|
spvm_object.h |
95
|
|
|
|
|
|
|
spvm_opcode_builder.h |
96
|
|
|
|
|
|
|
spvm_opcode.h |
97
|
|
|
|
|
|
|
spvm_opcode_list.h |
98
|
|
|
|
|
|
|
spvm_op.h |
99
|
|
|
|
|
|
|
spvm_precompile.h |
100
|
|
|
|
|
|
|
spvm_public_api.h |
101
|
|
|
|
|
|
|
spvm_runtime_arg.h |
102
|
|
|
|
|
|
|
spvm_runtime_basic_type.h |
103
|
|
|
|
|
|
|
spvm_runtime_class_var.h |
104
|
|
|
|
|
|
|
spvm_runtime_field.h |
105
|
|
|
|
|
|
|
spvm_runtime.h |
106
|
|
|
|
|
|
|
spvm_runtime_method.h |
107
|
|
|
|
|
|
|
spvm_runtime_string.h |
108
|
|
|
|
|
|
|
spvm_strerror.h |
109
|
|
|
|
|
|
|
spvm_string_buffer.h |
110
|
|
|
|
|
|
|
spvm_string.h |
111
|
|
|
|
|
|
|
spvm_switch_info.h |
112
|
|
|
|
|
|
|
spvm_toke.h |
113
|
|
|
|
|
|
|
spvm_typedecl.h |
114
|
|
|
|
|
|
|
spvm_type.h |
115
|
|
|
|
|
|
|
spvm_use.h |
116
|
|
|
|
|
|
|
spvm_var_decl.h |
117
|
|
|
|
|
|
|
spvm_var.h |
118
|
|
|
|
|
|
|
spvm_vm.h |
119
|
|
|
|
|
|
|
spvm_weaken_backref.h |
120
|
|
|
|
|
|
|
spvm_yacc.h |
121
|
|
|
|
|
|
|
spvm_yacc_util.h |
122
|
|
|
|
|
|
|
); |
123
|
|
|
|
|
|
|
|
124
|
1142
|
|
|
|
|
4679
|
return \@spvm_core_header_file_names; |
125
|
|
|
|
|
|
|
} |
126
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
sub get_spvm_core_source_file_names { |
128
|
|
|
|
|
|
|
|
129
|
1144
|
|
|
1144
|
0
|
21959
|
my @spvm_core_source_file_names = qw( |
130
|
|
|
|
|
|
|
spvm_allocator.c |
131
|
|
|
|
|
|
|
spvm_allow.c |
132
|
|
|
|
|
|
|
spvm_api_allocator.c |
133
|
|
|
|
|
|
|
spvm_api_arg.c |
134
|
|
|
|
|
|
|
spvm_api_basic_type.c |
135
|
|
|
|
|
|
|
spvm_api.c |
136
|
|
|
|
|
|
|
spvm_api_class_var.c |
137
|
|
|
|
|
|
|
spvm_api_compiler.c |
138
|
|
|
|
|
|
|
spvm_api_field.c |
139
|
|
|
|
|
|
|
spvm_api_method.c |
140
|
|
|
|
|
|
|
spvm_api_class_file.c |
141
|
|
|
|
|
|
|
spvm_api_runtime.c |
142
|
|
|
|
|
|
|
spvm_api_string_buffer.c |
143
|
|
|
|
|
|
|
spvm_api_type.c |
144
|
|
|
|
|
|
|
spvm_api_internal.c |
145
|
|
|
|
|
|
|
spvm_array_field_access.c |
146
|
|
|
|
|
|
|
spvm_attribute.c |
147
|
|
|
|
|
|
|
spvm_basic_type.c |
148
|
|
|
|
|
|
|
spvm_block.c |
149
|
|
|
|
|
|
|
spvm_call_method.c |
150
|
|
|
|
|
|
|
spvm_case_info.c |
151
|
|
|
|
|
|
|
spvm_check.c |
152
|
|
|
|
|
|
|
spvm_class_var_access.c |
153
|
|
|
|
|
|
|
spvm_class_var.c |
154
|
|
|
|
|
|
|
spvm_compiler.c |
155
|
|
|
|
|
|
|
spvm_constant.c |
156
|
|
|
|
|
|
|
spvm_dumper.c |
157
|
|
|
|
|
|
|
spvm_field_access.c |
158
|
|
|
|
|
|
|
spvm_field.c |
159
|
|
|
|
|
|
|
spvm_hash.c |
160
|
|
|
|
|
|
|
spvm_interface.c |
161
|
|
|
|
|
|
|
spvm_list.c |
162
|
|
|
|
|
|
|
spvm_method.c |
163
|
|
|
|
|
|
|
spvm_mutex.c |
164
|
|
|
|
|
|
|
spvm_class_file.c |
165
|
|
|
|
|
|
|
spvm_op.c |
166
|
|
|
|
|
|
|
spvm_opcode_builder.c |
167
|
|
|
|
|
|
|
spvm_opcode.c |
168
|
|
|
|
|
|
|
spvm_opcode_list.c |
169
|
|
|
|
|
|
|
spvm_precompile.c |
170
|
|
|
|
|
|
|
spvm_runtime.c |
171
|
|
|
|
|
|
|
spvm_strerror.c |
172
|
|
|
|
|
|
|
spvm_string_buffer.c |
173
|
|
|
|
|
|
|
spvm_string.c |
174
|
|
|
|
|
|
|
spvm_switch_info.c |
175
|
|
|
|
|
|
|
spvm_toke.c |
176
|
|
|
|
|
|
|
spvm_type.c |
177
|
|
|
|
|
|
|
spvm_use.c |
178
|
|
|
|
|
|
|
spvm_var.c |
179
|
|
|
|
|
|
|
spvm_var_decl.c |
180
|
|
|
|
|
|
|
spvm_vm.c |
181
|
|
|
|
|
|
|
spvm_yacc.c |
182
|
|
|
|
|
|
|
spvm_yacc_util.c |
183
|
|
|
|
|
|
|
); |
184
|
|
|
|
|
|
|
|
185
|
1144
|
|
|
|
|
5115
|
return \@spvm_core_source_file_names; |
186
|
|
|
|
|
|
|
} |
187
|
|
|
|
|
|
|
|
188
|
|
|
|
|
|
|
sub get_spvm_compiler_and_runtime_class_file_names { |
189
|
1142
|
|
|
1142
|
0
|
11493
|
my @spvm_compiler_and_runtime_class_file_names = qw( |
190
|
|
|
|
|
|
|
SPVM/Native/Arg.c |
191
|
|
|
|
|
|
|
SPVM/Native/Arg.spvm |
192
|
|
|
|
|
|
|
SPVM/Native/BasicType.c |
193
|
|
|
|
|
|
|
SPVM/Native/BasicType.spvm |
194
|
|
|
|
|
|
|
SPVM/Native.c |
195
|
|
|
|
|
|
|
SPVM/Native/ClassVar.c |
196
|
|
|
|
|
|
|
SPVM/Native/ClassVar.spvm |
197
|
|
|
|
|
|
|
SPVM/Native/Compiler.c |
198
|
|
|
|
|
|
|
SPVM/Native/Compiler.spvm |
199
|
|
|
|
|
|
|
SPVM/Native/Env.c |
200
|
|
|
|
|
|
|
SPVM/Native/Env.spvm |
201
|
|
|
|
|
|
|
SPVM/Native/Field.c |
202
|
|
|
|
|
|
|
SPVM/Native/Field.spvm |
203
|
|
|
|
|
|
|
SPVM/Native/Method.c |
204
|
|
|
|
|
|
|
SPVM/Native/MethodCall.c |
205
|
|
|
|
|
|
|
SPVM/Native/MethodCall/Callback.spvm |
206
|
|
|
|
|
|
|
SPVM/Native/MethodCall.spvm |
207
|
|
|
|
|
|
|
SPVM/Native/Method.spvm |
208
|
|
|
|
|
|
|
SPVM/Native/ClassFile.c |
209
|
|
|
|
|
|
|
SPVM/Native/ClassFile.spvm |
210
|
|
|
|
|
|
|
SPVM/Native/Runtime.c |
211
|
|
|
|
|
|
|
SPVM/Native/Runtime.spvm |
212
|
|
|
|
|
|
|
SPVM/Native.spvm |
213
|
|
|
|
|
|
|
SPVM/Native/Stack.c |
214
|
|
|
|
|
|
|
SPVM/Native/Stack.spvm |
215
|
|
|
|
|
|
|
); |
216
|
|
|
|
|
|
|
|
217
|
1142
|
|
|
|
|
5432
|
return \@spvm_compiler_and_runtime_class_file_names; |
218
|
|
|
|
|
|
|
} |
219
|
|
|
|
|
|
|
|
220
|
|
|
|
|
|
|
sub need_generate { |
221
|
1142
|
|
|
1142
|
0
|
3697
|
my ($opt) = @_; |
222
|
|
|
|
|
|
|
|
223
|
1142
|
|
|
|
|
2911
|
my $force = $opt->{force}; |
224
|
1142
|
|
|
|
|
2343
|
my $input_files = $opt->{input_files}; |
225
|
1142
|
|
|
|
|
2318
|
my $output_file = $opt->{output_file}; |
226
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
# SPVM::Builder classes |
228
|
1142
|
|
|
|
|
5167
|
my $spvm_dependent_files = &get_spvm_dependent_files; |
229
|
|
|
|
|
|
|
|
230
|
1142
|
|
|
|
|
2058
|
my $spvm_dependent_files_mtime_max; |
231
|
1142
|
|
|
|
|
2194
|
$spvm_dependent_files_mtime_max = 0; |
232
|
1142
|
|
|
|
|
4429
|
for my $spvm_core_file (@$spvm_dependent_files) { |
233
|
194140
|
|
|
|
|
2128477
|
my $spvm_core_file_mtime = (stat($spvm_core_file))[9]; |
234
|
194140
|
100
|
|
|
|
624408
|
if ($spvm_core_file_mtime > $spvm_dependent_files_mtime_max) { |
235
|
4568
|
|
|
|
|
8718
|
$spvm_dependent_files_mtime_max = $spvm_core_file_mtime; |
236
|
|
|
|
|
|
|
} |
237
|
|
|
|
|
|
|
} |
238
|
|
|
|
|
|
|
|
239
|
1142
|
|
|
|
|
2658
|
my $need_generate; |
240
|
1142
|
50
|
|
|
|
3607
|
if ($force) { |
241
|
0
|
|
|
|
|
0
|
$need_generate = 1; |
242
|
|
|
|
|
|
|
} |
243
|
|
|
|
|
|
|
else { |
244
|
1142
|
100
|
|
|
|
64550
|
if (!-f $output_file) { |
245
|
848
|
|
|
|
|
2667
|
$need_generate = 1; |
246
|
|
|
|
|
|
|
} |
247
|
|
|
|
|
|
|
else { |
248
|
294
|
|
|
|
|
996
|
my $input_files_mtime_max = 0; |
249
|
294
|
|
|
|
|
589
|
my $exists_input_file_at_least_one; |
250
|
294
|
|
|
|
|
830
|
for my $input_file (@$input_files) { |
251
|
567
|
100
|
|
|
|
7895
|
if (-f $input_file) { |
252
|
497
|
|
|
|
|
1311
|
$exists_input_file_at_least_one = 1; |
253
|
497
|
|
|
|
|
5853
|
my $input_file_mtime = (stat($input_file))[9]; |
254
|
497
|
100
|
|
|
|
2193
|
if ($input_file_mtime > $input_files_mtime_max) { |
255
|
345
|
|
|
|
|
855
|
$input_files_mtime_max = $input_file_mtime; |
256
|
|
|
|
|
|
|
} |
257
|
|
|
|
|
|
|
} |
258
|
|
|
|
|
|
|
} |
259
|
294
|
50
|
|
|
|
1020
|
if ($exists_input_file_at_least_one) { |
260
|
294
|
|
|
|
|
3568
|
my $output_file_mtime = (stat($output_file))[9]; |
261
|
|
|
|
|
|
|
|
262
|
294
|
50
|
|
|
|
1679
|
if (defined $spvm_dependent_files_mtime_max) { |
263
|
294
|
50
|
|
|
|
982
|
if ($spvm_dependent_files_mtime_max > $input_files_mtime_max) { |
264
|
0
|
|
|
|
|
0
|
$input_files_mtime_max = $spvm_dependent_files_mtime_max; |
265
|
|
|
|
|
|
|
} |
266
|
|
|
|
|
|
|
} |
267
|
|
|
|
|
|
|
|
268
|
294
|
100
|
|
|
|
925
|
if ($input_files_mtime_max > $output_file_mtime) { |
269
|
1
|
|
|
|
|
19
|
$need_generate = 1; |
270
|
|
|
|
|
|
|
} |
271
|
|
|
|
|
|
|
} |
272
|
|
|
|
|
|
|
} |
273
|
|
|
|
|
|
|
} |
274
|
|
|
|
|
|
|
|
275
|
1142
|
|
|
|
|
21100
|
return $need_generate; |
276
|
|
|
|
|
|
|
} |
277
|
|
|
|
|
|
|
|
278
|
|
|
|
|
|
|
sub slurp_binary { |
279
|
184
|
|
|
184
|
0
|
385
|
my ($file) = @_; |
280
|
|
|
|
|
|
|
|
281
|
184
|
50
|
|
|
|
10895
|
open my $fh, '<', $file |
282
|
|
|
|
|
|
|
or confess "Can't open file \"$file\":$!"; |
283
|
|
|
|
|
|
|
|
284
|
184
|
|
|
|
|
617
|
my $content = do { local $/; <$fh> }; |
|
184
|
|
|
|
|
1175
|
|
|
184
|
|
|
|
|
7315
|
|
285
|
|
|
|
|
|
|
|
286
|
184
|
|
|
|
|
2942
|
return $content; |
287
|
|
|
|
|
|
|
} |
288
|
|
|
|
|
|
|
|
289
|
|
|
|
|
|
|
sub slurp_utf8 { |
290
|
184
|
|
|
184
|
0
|
331
|
my ($file) = @_; |
291
|
|
|
|
|
|
|
|
292
|
184
|
|
|
|
|
638
|
my $content = &slurp_binary($file); |
293
|
|
|
|
|
|
|
|
294
|
184
|
|
|
|
|
1320
|
$content = decode('UTF-8', $content); |
295
|
|
|
|
|
|
|
|
296
|
184
|
|
|
|
|
15068
|
return $content; |
297
|
|
|
|
|
|
|
} |
298
|
|
|
|
|
|
|
|
299
|
|
|
|
|
|
|
sub file_contains { |
300
|
184
|
|
|
184
|
0
|
18913975
|
my ($file, $string) = @_; |
301
|
|
|
|
|
|
|
|
302
|
184
|
|
|
|
|
555
|
my $content = &slurp_utf8($file); |
303
|
|
|
|
|
|
|
|
304
|
184
|
|
|
|
|
359
|
my $contains; |
305
|
184
|
100
|
|
|
|
2020
|
if (index($content, $string) >= 0) { |
306
|
177
|
|
|
|
|
315
|
$contains = 1; |
307
|
|
|
|
|
|
|
} |
308
|
|
|
|
|
|
|
|
309
|
184
|
|
|
|
|
1715
|
return $contains; |
310
|
|
|
|
|
|
|
} |
311
|
|
|
|
|
|
|
|
312
|
|
|
|
|
|
|
sub spurt_binary { |
313
|
2
|
|
|
2
|
0
|
17
|
my ($file, $content) = @_; |
314
|
|
|
|
|
|
|
|
315
|
2
|
50
|
|
|
|
217
|
open my $fh, '>:raw', $file |
316
|
|
|
|
|
|
|
or confess "Can't open file \"$file\":$!"; |
317
|
|
|
|
|
|
|
|
318
|
2
|
|
|
|
|
274
|
print $fh $content; |
319
|
|
|
|
|
|
|
} |
320
|
|
|
|
|
|
|
|
321
|
|
|
|
|
|
|
sub create_cfunc_name { |
322
|
42538
|
|
|
42538
|
0
|
74909
|
my ($basic_type_name, $method_name, $category) = @_; |
323
|
|
|
|
|
|
|
|
324
|
42538
|
|
|
|
|
50748
|
my $prefix; |
325
|
42538
|
100
|
|
|
|
79392
|
if ($category eq 'native') { |
|
|
50
|
|
|
|
|
|
326
|
26450
|
|
|
|
|
34038
|
$prefix = 'SPVM__'; |
327
|
|
|
|
|
|
|
} |
328
|
|
|
|
|
|
|
elsif ($category eq 'precompile') { |
329
|
16088
|
|
|
|
|
22835
|
$prefix = 'SPVMPRECOMPILE__' |
330
|
|
|
|
|
|
|
} |
331
|
|
|
|
|
|
|
|
332
|
|
|
|
|
|
|
# Precompile Method names |
333
|
42538
|
|
|
|
|
105135
|
my $method_abs_name_under_score = "${basic_type_name}::$method_name"; |
334
|
42538
|
|
|
|
|
150661
|
$method_abs_name_under_score =~ s/:/_/g; |
335
|
42538
|
|
|
|
|
82184
|
my $cfunc_name = "$prefix$method_abs_name_under_score"; |
336
|
|
|
|
|
|
|
|
337
|
42538
|
|
|
|
|
74730
|
return $cfunc_name; |
338
|
|
|
|
|
|
|
} |
339
|
|
|
|
|
|
|
|
340
|
|
|
|
|
|
|
sub unindent { |
341
|
0
|
|
|
0
|
0
|
0
|
my $str = shift; |
342
|
0
|
0
|
|
|
|
0
|
my $min = min map { m/^([ \t]*)/; length $1 || () } split "\n", $str; |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
343
|
0
|
0
|
|
|
|
0
|
$str =~ s/^[ \t]{0,$min}//gm if $min; |
344
|
0
|
|
|
|
|
0
|
return $str; |
345
|
|
|
|
|
|
|
} |
346
|
|
|
|
|
|
|
|
347
|
|
|
|
|
|
|
sub extract_usage { |
348
|
0
|
0
|
|
0
|
0
|
0
|
my $file = @_ ? "$_[0]" : (caller)[1]; |
349
|
|
|
|
|
|
|
|
350
|
0
|
|
|
|
|
0
|
open my $handle, '>', \my $output; |
351
|
|
|
|
|
|
|
|
352
|
0
|
|
|
|
|
0
|
pod2usage -exitval => 'noexit', -input => $file, -output => $handle, -verbose => 99, -sections => "Usage"; |
353
|
0
|
|
|
|
|
0
|
$output =~ s/^.*\n|\n$//; |
354
|
0
|
|
|
|
|
0
|
$output =~ s/\n$//; |
355
|
|
|
|
|
|
|
|
356
|
0
|
|
|
|
|
0
|
return SPVM::Builder::Util::unindent($output); |
357
|
|
|
|
|
|
|
} |
358
|
|
|
|
|
|
|
|
359
|
|
|
|
|
|
|
sub getopt { |
360
|
0
|
0
|
|
0
|
0
|
0
|
my ($array, $opts) = map { ref $_[0] eq 'ARRAY' ? shift : $_ } \@ARGV, []; |
|
0
|
|
|
|
|
0
|
|
361
|
0
|
|
|
|
|
0
|
my $save = Getopt::Long::Configure(qw(default no_auto_abbrev no_ignore_case), |
362
|
|
|
|
|
|
|
@$opts); |
363
|
0
|
|
|
|
|
0
|
GetOptionsFromArray $array, @_; |
364
|
0
|
|
|
|
|
0
|
Getopt::Long::Configure($save); |
365
|
|
|
|
|
|
|
} |
366
|
|
|
|
|
|
|
|
367
|
|
|
|
|
|
|
sub convert_class_file_to_dynamic_lib_file { |
368
|
3189
|
|
|
3189
|
0
|
6738
|
my ($class_file, $category) = @_; |
369
|
|
|
|
|
|
|
|
370
|
3189
|
|
|
|
|
33441
|
my $dlext = $Config{dlext}; |
371
|
3189
|
|
|
|
|
29701
|
$class_file =~ s/\.[^.]+$//; |
372
|
3189
|
|
|
|
|
6954
|
my $dynamic_lib_category_file = $class_file; |
373
|
3189
|
100
|
|
|
|
14031
|
$dynamic_lib_category_file .= $category eq 'native' ? ".$dlext" : ".$category.$dlext"; |
374
|
|
|
|
|
|
|
|
375
|
3189
|
|
|
|
|
7450
|
return $dynamic_lib_category_file; |
376
|
|
|
|
|
|
|
} |
377
|
|
|
|
|
|
|
|
378
|
|
|
|
|
|
|
sub convert_basic_type_name_to_dynamic_lib_rel_file { |
379
|
2
|
|
|
2
|
0
|
5
|
my ($basic_type_name, $category) = @_; |
380
|
|
|
|
|
|
|
|
381
|
2
|
|
|
|
|
15
|
my $dlext = $Config{dlext}; |
382
|
2
|
|
|
|
|
15
|
my $dynamic_lib_category_rel_file = &convert_basic_type_name_to_rel_file($basic_type_name); |
383
|
2
|
100
|
|
|
|
8
|
$dynamic_lib_category_rel_file .= $category eq 'native' ? ".$dlext" : ".$category.$dlext"; |
384
|
|
|
|
|
|
|
|
385
|
2
|
|
|
|
|
5
|
return $dynamic_lib_category_rel_file; |
386
|
|
|
|
|
|
|
} |
387
|
|
|
|
|
|
|
|
388
|
|
|
|
|
|
|
sub convert_basic_type_name_to_category_rel_file { |
389
|
1057
|
|
|
1057
|
0
|
4319
|
my ($basic_type_name, $category, $ext) = @_; |
390
|
|
|
|
|
|
|
|
391
|
1057
|
|
|
|
|
4896
|
$basic_type_name =~ s/^SPVM:://; |
392
|
|
|
|
|
|
|
|
393
|
1057
|
|
|
|
|
5406
|
my $rel_file_with_ext = "SPVM::$basic_type_name"; |
394
|
1057
|
|
|
|
|
7830
|
$rel_file_with_ext =~ s/::/\//g; |
395
|
1057
|
100
|
|
|
|
6073
|
$rel_file_with_ext .= $category eq 'native' ? "" : ".$category"; |
396
|
1057
|
100
|
|
|
|
3854
|
if (defined $ext) { |
397
|
716
|
|
|
|
|
2149
|
$rel_file_with_ext .= ".$ext"; |
398
|
|
|
|
|
|
|
} |
399
|
|
|
|
|
|
|
|
400
|
1057
|
|
|
|
|
4937
|
return $rel_file_with_ext; |
401
|
|
|
|
|
|
|
} |
402
|
|
|
|
|
|
|
|
403
|
|
|
|
|
|
|
sub convert_basic_type_name_to_rel_dir { |
404
|
284
|
|
|
284
|
0
|
910
|
my ($basic_type_name) = @_; |
405
|
|
|
|
|
|
|
|
406
|
284
|
|
|
|
|
901
|
$basic_type_name =~ s/^SPVM:://; |
407
|
|
|
|
|
|
|
|
408
|
284
|
|
|
|
|
554
|
my $rel_dir; |
409
|
284
|
|
|
|
|
1457
|
my $rel_file = "SPVM::$basic_type_name"; |
410
|
284
|
|
|
|
|
2149
|
$rel_file =~ s/::/\//g; |
411
|
284
|
|
|
|
|
10055
|
$rel_dir = dirname $rel_file; |
412
|
|
|
|
|
|
|
|
413
|
284
|
|
|
|
|
1896
|
return $rel_dir; |
414
|
|
|
|
|
|
|
} |
415
|
|
|
|
|
|
|
|
416
|
|
|
|
|
|
|
sub convert_basic_type_name_to_rel_file { |
417
|
377
|
|
|
377
|
0
|
1447
|
my ($basic_type_name, $ext) = @_; |
418
|
|
|
|
|
|
|
|
419
|
377
|
|
|
|
|
1353
|
$basic_type_name =~ s/^SPVM:://; |
420
|
|
|
|
|
|
|
|
421
|
377
|
|
|
|
|
4249
|
my $rel_file_with_ext = "SPVM::$basic_type_name"; |
422
|
377
|
|
|
|
|
3200
|
$rel_file_with_ext =~ s/::/\//g; |
423
|
|
|
|
|
|
|
|
424
|
377
|
100
|
|
|
|
1610
|
if (defined $ext) { |
425
|
363
|
|
|
|
|
1558
|
$rel_file_with_ext .= ".$ext"; |
426
|
|
|
|
|
|
|
} |
427
|
|
|
|
|
|
|
|
428
|
377
|
|
|
|
|
1875
|
return $rel_file_with_ext; |
429
|
|
|
|
|
|
|
} |
430
|
|
|
|
|
|
|
|
431
|
|
|
|
|
|
|
sub remove_basic_type_name_part_from_file { |
432
|
27
|
|
|
27
|
0
|
135
|
my ($file, $basic_type_name) = @_; |
433
|
|
|
|
|
|
|
|
434
|
27
|
|
|
|
|
138
|
$basic_type_name =~ s/^SPVM:://; |
435
|
|
|
|
|
|
|
|
436
|
27
|
|
|
|
|
244
|
$file =~ s/\.spvm$//; |
437
|
27
|
|
|
|
|
156
|
my $class_file = "SPVM::$basic_type_name"; |
438
|
27
|
|
|
|
|
210
|
$class_file =~ s/::/\//g; |
439
|
27
|
|
|
|
|
882
|
$file =~ s/$class_file$//; |
440
|
27
|
|
|
|
|
194
|
$file =~ s/[\\\/]$//; |
441
|
|
|
|
|
|
|
|
442
|
27
|
|
|
|
|
135
|
return $file; |
443
|
|
|
|
|
|
|
} |
444
|
|
|
|
|
|
|
|
445
|
|
|
|
|
|
|
sub create_make_rule_native { |
446
|
1
|
|
|
1
|
0
|
105
|
my $basic_type_name = shift; |
447
|
|
|
|
|
|
|
|
448
|
1
|
|
|
|
|
5
|
create_make_rule($basic_type_name, 'native', @_); |
449
|
|
|
|
|
|
|
} |
450
|
|
|
|
|
|
|
|
451
|
|
|
|
|
|
|
sub create_make_rule_precompile { |
452
|
1
|
|
|
1
|
0
|
547
|
my $basic_type_name = shift; |
453
|
|
|
|
|
|
|
|
454
|
1
|
|
|
|
|
4
|
create_make_rule($basic_type_name, 'precompile', @_); |
455
|
|
|
|
|
|
|
} |
456
|
|
|
|
|
|
|
|
457
|
|
|
|
|
|
|
sub create_make_rule { |
458
|
2
|
|
|
2
|
0
|
7
|
my ($basic_type_name, $category, $options) = @_; |
459
|
|
|
|
|
|
|
|
460
|
2
|
|
50
|
|
|
6
|
$options ||= {}; |
461
|
2
|
|
|
|
|
5
|
$basic_type_name =~ s/^SPVM:://; |
462
|
|
|
|
|
|
|
|
463
|
2
|
|
|
|
|
3
|
my $module_base_name = $basic_type_name; |
464
|
2
|
|
|
|
|
5
|
$module_base_name =~ s/^.+:://; |
465
|
|
|
|
|
|
|
|
466
|
2
|
50
|
|
|
|
8
|
my $lib_dir = defined $options->{lib_dir} ? $options->{lib_dir} : 'lib'; |
467
|
|
|
|
|
|
|
|
468
|
2
|
|
|
|
|
6
|
my $class_rel_file = &convert_basic_type_name_to_rel_file($basic_type_name, 'spvm'); |
469
|
|
|
|
|
|
|
|
470
|
2
|
|
|
|
|
4
|
my $noext_file = $class_rel_file; |
471
|
2
|
|
|
|
|
11
|
$noext_file =~ s/\.[^\.]+$//; |
472
|
|
|
|
|
|
|
|
473
|
2
|
|
|
|
|
4
|
my $spvm_file = $noext_file; |
474
|
2
|
|
|
|
|
3
|
$spvm_file .= '.spvm'; |
475
|
2
|
|
|
|
|
7
|
$spvm_file = "$lib_dir/$spvm_file"; |
476
|
|
|
|
|
|
|
|
477
|
|
|
|
|
|
|
# Dependency files |
478
|
2
|
|
|
|
|
4
|
my @deps; |
479
|
|
|
|
|
|
|
|
480
|
|
|
|
|
|
|
# Dependency c source files |
481
|
2
|
0
|
|
|
|
81
|
push @deps, grep { $_ ne '.' && $_ ne '..' } glob "$lib_dir/$class_rel_file/*"; |
|
0
|
|
|
|
|
0
|
|
482
|
|
|
|
|
|
|
|
483
|
2
|
|
|
|
|
9
|
push @deps, $spvm_file; |
484
|
|
|
|
|
|
|
|
485
|
|
|
|
|
|
|
# Dependency native class file |
486
|
2
|
100
|
|
|
|
8
|
if ($category eq 'native') { |
487
|
|
|
|
|
|
|
# Config |
488
|
1
|
|
|
|
|
3
|
my $config_file = $noext_file; |
489
|
1
|
|
|
|
|
4
|
$config_file .= '.config'; |
490
|
1
|
|
|
|
|
4
|
$config_file = "$lib_dir/$config_file"; |
491
|
1
|
|
|
|
|
10
|
my $config = SPVM::Builder::Config->load_config($config_file); |
492
|
1
|
|
|
|
|
3
|
push @deps, $config_file; |
493
|
|
|
|
|
|
|
|
494
|
|
|
|
|
|
|
# Native class |
495
|
1
|
|
|
|
|
3
|
my $native_class_file = $noext_file; |
496
|
1
|
|
|
|
|
3
|
my $native_class_file_ext = $config->ext; |
497
|
1
|
|
|
|
|
4
|
$native_class_file .= ".$native_class_file_ext"; |
498
|
1
|
|
|
|
|
4
|
$native_class_file = "$lib_dir/$native_class_file"; |
499
|
1
|
|
|
|
|
2
|
push @deps, $native_class_file; |
500
|
|
|
|
|
|
|
|
501
|
|
|
|
|
|
|
# Native include |
502
|
1
|
|
|
|
|
3
|
my $native_include_dir = "$lib_dir/$noext_file.native/include"; |
503
|
1
|
|
|
|
|
2
|
my @native_include_files; |
504
|
1
|
50
|
|
|
|
23
|
if (-d $native_include_dir) { |
505
|
0
|
0
|
|
0
|
|
0
|
find({wanted => sub { if (-f $_) { push @native_include_files, $_ } }, no_chdir => 1}, $native_include_dir); |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
506
|
|
|
|
|
|
|
} |
507
|
1
|
|
|
|
|
4
|
push @deps, @native_include_files; |
508
|
|
|
|
|
|
|
|
509
|
|
|
|
|
|
|
# Native source |
510
|
1
|
|
|
|
|
4
|
my $native_src_dir = "$lib_dir/$noext_file.native/src"; |
511
|
1
|
|
|
|
|
2
|
my @native_src_files; |
512
|
1
|
50
|
|
|
|
18
|
if (-d $native_src_dir) { |
513
|
0
|
0
|
|
0
|
|
0
|
find({wanted => sub { if (-f $_) { push @native_src_files, $_ } }, no_chdir => 1}, $native_src_dir); |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
514
|
|
|
|
|
|
|
} |
515
|
1
|
|
|
|
|
14
|
push @deps, @native_src_files; |
516
|
|
|
|
|
|
|
} |
517
|
|
|
|
|
|
|
|
518
|
|
|
|
|
|
|
# Shared library file |
519
|
2
|
|
|
|
|
7
|
my $dynamic_lib_rel_file = &convert_basic_type_name_to_dynamic_lib_rel_file($basic_type_name, $category); |
520
|
2
|
|
|
|
|
6
|
my $dynamic_lib_file = "blib/lib/$dynamic_lib_rel_file"; |
521
|
|
|
|
|
|
|
|
522
|
2
|
|
|
|
|
3
|
my $make_rule = ''; |
523
|
|
|
|
|
|
|
|
524
|
|
|
|
|
|
|
# dynamic section |
525
|
2
|
|
|
|
|
6
|
$make_rule .= "dynamic :: $dynamic_lib_file\n"; |
526
|
2
|
|
|
|
|
3
|
$make_rule .= "\t\$(NOECHO) \$(NOOP)\n\n"; |
527
|
|
|
|
|
|
|
|
528
|
|
|
|
|
|
|
# Get source files |
529
|
2
|
|
|
|
|
8
|
$make_rule .= "$dynamic_lib_file :: @deps\n"; |
530
|
2
|
|
|
|
|
7
|
$make_rule .= "\t$^X -Mblib -MSPVM::Builder::API -e \"SPVM::Builder::API->new(build_dir => '.spvm_build')->build_dynamic_lib_dist_$category('$basic_type_name')\"\n\n"; |
531
|
|
|
|
|
|
|
|
532
|
2
|
|
|
|
|
8
|
return $make_rule; |
533
|
|
|
|
|
|
|
} |
534
|
|
|
|
|
|
|
|
535
|
|
|
|
|
|
|
sub get_spvm_dependent_files { |
536
|
|
|
|
|
|
|
|
537
|
1142
|
|
|
1142
|
0
|
2671
|
my @spvm_dependent_files; |
538
|
1142
|
50
|
|
|
|
6907
|
if (my $builder_loaded_file = $INC{'SPVM/Builder/Util.pm'}) { |
539
|
1142
|
|
|
|
|
4226
|
my $builder_loaded_dir = $builder_loaded_file; |
540
|
1142
|
|
|
|
|
10068
|
$builder_loaded_dir =~ s|[/\\]SPVM/Builder/Util\.pm$||; |
541
|
|
|
|
|
|
|
|
542
|
|
|
|
|
|
|
# SPVM::Builder class files |
543
|
1142
|
|
|
|
|
6980
|
my $spvm_core_perl_class_file_names = &get_spvm_core_perl_class_file_names(); |
544
|
1142
|
|
|
|
|
5441
|
for my $spvm_core_perl_class_file_name (@$spvm_core_perl_class_file_names) { |
545
|
30834
|
|
|
|
|
104018
|
my $spvm_core_perl_class_file = "$builder_loaded_dir/$spvm_core_perl_class_file_name"; |
546
|
30834
|
50
|
|
|
|
378195
|
unless (-f $spvm_core_perl_class_file) { |
547
|
0
|
|
|
|
|
0
|
confess "Can't find $spvm_core_perl_class_file"; |
548
|
|
|
|
|
|
|
} |
549
|
30834
|
|
|
|
|
116851
|
push @spvm_dependent_files, $spvm_core_perl_class_file; |
550
|
|
|
|
|
|
|
} |
551
|
|
|
|
|
|
|
|
552
|
|
|
|
|
|
|
# SPVM core header files |
553
|
1142
|
|
|
|
|
5660
|
my $spvm_core_header_file_names = &get_spvm_core_header_file_names(); |
554
|
1142
|
|
|
|
|
3487
|
for my $spvm_core_header_file_name (@$spvm_core_header_file_names) { |
555
|
74230
|
|
|
|
|
310998
|
my $spvm_core_header_file = "$builder_loaded_dir/SPVM/Builder/include/$spvm_core_header_file_name"; |
556
|
74230
|
50
|
|
|
|
903036
|
unless (-f $spvm_core_header_file) { |
557
|
0
|
|
|
|
|
0
|
confess "Can't find $spvm_core_header_file"; |
558
|
|
|
|
|
|
|
} |
559
|
74230
|
|
|
|
|
277764
|
push @spvm_dependent_files, $spvm_core_header_file; |
560
|
|
|
|
|
|
|
} |
561
|
|
|
|
|
|
|
|
562
|
|
|
|
|
|
|
# SPVM core source files |
563
|
1142
|
|
|
|
|
4465
|
my $spvm_core_source_file_names = &get_spvm_core_source_file_names(); |
564
|
1142
|
|
|
|
|
3645
|
for my $spvm_core_source_file_name (@$spvm_core_source_file_names) { |
565
|
60526
|
|
|
|
|
247873
|
my $spvm_core_source_file = "$builder_loaded_dir/SPVM/Builder/src/$spvm_core_source_file_name"; |
566
|
60526
|
50
|
|
|
|
745203
|
unless (-f $spvm_core_source_file) { |
567
|
0
|
|
|
|
|
0
|
confess "Can't find $spvm_core_source_file"; |
568
|
|
|
|
|
|
|
} |
569
|
60526
|
|
|
|
|
237074
|
push @spvm_dependent_files, $spvm_core_source_file; |
570
|
|
|
|
|
|
|
} |
571
|
|
|
|
|
|
|
|
572
|
|
|
|
|
|
|
# SPVM Compiler and Runtime class file names |
573
|
1142
|
|
|
|
|
4349
|
my $spvm_compiler_and_runtime_class_file_names = &get_spvm_compiler_and_runtime_class_file_names(); |
574
|
1142
|
|
|
|
|
3729
|
for my $spvm_compiler_and_runtime_class_file_name (@$spvm_compiler_and_runtime_class_file_names) { |
575
|
28550
|
|
|
|
|
93470
|
my $spvm_compiler_and_runtime_class_file = "$builder_loaded_dir/$spvm_compiler_and_runtime_class_file_name"; |
576
|
28550
|
50
|
|
|
|
339149
|
unless (-f $spvm_compiler_and_runtime_class_file) { |
577
|
0
|
|
|
|
|
0
|
confess "Can't find $spvm_compiler_and_runtime_class_file"; |
578
|
|
|
|
|
|
|
} |
579
|
28550
|
|
|
|
|
108201
|
push @spvm_dependent_files, $spvm_compiler_and_runtime_class_file; |
580
|
|
|
|
|
|
|
} |
581
|
|
|
|
|
|
|
} |
582
|
|
|
|
|
|
|
|
583
|
1142
|
50
|
|
|
|
3954
|
unless (@spvm_dependent_files) { |
584
|
0
|
|
|
|
|
0
|
confess "[Unexpected Error]SPVM dependent files are not found"; |
585
|
|
|
|
|
|
|
} |
586
|
|
|
|
|
|
|
|
587
|
1142
|
|
|
|
|
3216
|
return \@spvm_dependent_files; |
588
|
|
|
|
|
|
|
} |
589
|
|
|
|
|
|
|
|
590
|
|
|
|
|
|
|
sub get_config_file_from_basic_type_name { |
591
|
22
|
|
|
22
|
0
|
101
|
my ($basic_type_name, $mode) = @_; |
592
|
|
|
|
|
|
|
|
593
|
22
|
|
|
|
|
95
|
my $ext = 'config'; |
594
|
22
|
100
|
|
|
|
96
|
if (defined $mode) { |
595
|
3
|
|
|
|
|
22
|
$ext = "$mode.$ext"; |
596
|
|
|
|
|
|
|
} |
597
|
|
|
|
|
|
|
|
598
|
22
|
|
|
|
|
150
|
my $config_file_base = SPVM::Builder::Util::convert_basic_type_name_to_rel_file($basic_type_name, $ext); |
599
|
22
|
|
|
|
|
216
|
my $config_file; |
600
|
22
|
|
|
|
|
163
|
for my $inc (@INC) { |
601
|
22
|
|
|
|
|
182
|
my $config_file_tmp = "$inc/$config_file_base"; |
602
|
22
|
50
|
|
|
|
1204
|
if (-f $config_file_tmp) { |
603
|
22
|
|
|
|
|
92
|
$config_file = $config_file_tmp; |
604
|
22
|
|
|
|
|
71
|
last; |
605
|
|
|
|
|
|
|
} |
606
|
|
|
|
|
|
|
} |
607
|
22
|
50
|
|
|
|
80
|
unless (defined $config_file) { |
608
|
0
|
|
|
|
|
0
|
confess "Can't find the config file \"$config_file_base\" in (@INC)"; |
609
|
|
|
|
|
|
|
} |
610
|
|
|
|
|
|
|
|
611
|
22
|
|
|
|
|
101
|
return $config_file; |
612
|
|
|
|
|
|
|
} |
613
|
|
|
|
|
|
|
|
614
|
|
|
|
|
|
|
sub get_builder_dir_from_config_class { |
615
|
398
|
|
|
398
|
0
|
1817
|
my $builder_config_dir = $INC{"SPVM/Builder/Config.pm"}; |
616
|
398
|
|
|
|
|
968
|
my $builder_dir = $builder_config_dir; |
617
|
398
|
|
|
|
|
3787
|
$builder_dir =~ s/\/Config\.pm$//; |
618
|
398
|
|
|
|
|
2079
|
return $builder_dir; |
619
|
|
|
|
|
|
|
} |
620
|
|
|
|
|
|
|
|
621
|
|
|
|
|
|
|
sub create_build_src_path { |
622
|
323
|
|
|
323
|
0
|
1494
|
my ($build_dir, $rel_file) = @_; |
623
|
|
|
|
|
|
|
|
624
|
323
|
|
|
|
|
1220
|
my $build_src_path = "$build_dir/work/src"; |
625
|
323
|
100
|
|
|
|
1547
|
if (defined $rel_file) { |
626
|
2
|
|
|
|
|
6
|
$build_src_path .= "/$rel_file"; |
627
|
|
|
|
|
|
|
} |
628
|
|
|
|
|
|
|
|
629
|
323
|
|
|
|
|
1276
|
return $build_src_path; |
630
|
|
|
|
|
|
|
} |
631
|
|
|
|
|
|
|
|
632
|
|
|
|
|
|
|
sub create_build_include_path { |
633
|
0
|
|
|
0
|
0
|
0
|
my ($build_dir, $rel_file) = @_; |
634
|
|
|
|
|
|
|
|
635
|
0
|
|
|
|
|
0
|
my $build_include_path = "$build_dir/work/include"; |
636
|
0
|
0
|
|
|
|
0
|
if (defined $rel_file) { |
637
|
0
|
|
|
|
|
0
|
$build_include_path .= "/$rel_file"; |
638
|
|
|
|
|
|
|
} |
639
|
|
|
|
|
|
|
|
640
|
0
|
|
|
|
|
0
|
return $build_include_path; |
641
|
|
|
|
|
|
|
} |
642
|
|
|
|
|
|
|
|
643
|
|
|
|
|
|
|
sub create_build_object_path { |
644
|
358
|
|
|
358
|
0
|
1657
|
my ($build_dir, $rel_file) = @_; |
645
|
|
|
|
|
|
|
|
646
|
358
|
|
|
|
|
1453
|
my $build_output_path = "$build_dir/work/object"; |
647
|
358
|
100
|
|
|
|
2035
|
if (defined $rel_file) { |
648
|
12
|
|
|
|
|
69
|
$build_output_path .= "/$rel_file"; |
649
|
|
|
|
|
|
|
} |
650
|
|
|
|
|
|
|
|
651
|
358
|
|
|
|
|
1561
|
return $build_output_path; |
652
|
|
|
|
|
|
|
} |
653
|
|
|
|
|
|
|
|
654
|
|
|
|
|
|
|
sub create_build_lib_path { |
655
|
341
|
|
|
341
|
0
|
1711
|
my ($build_dir, $rel_file) = @_; |
656
|
|
|
|
|
|
|
|
657
|
341
|
|
|
|
|
1369
|
my $build_lib_path = "$build_dir/work/lib"; |
658
|
341
|
50
|
|
|
|
1413
|
if (defined $rel_file) { |
659
|
0
|
|
|
|
|
0
|
$build_lib_path .= "/$rel_file"; |
660
|
|
|
|
|
|
|
} |
661
|
|
|
|
|
|
|
|
662
|
341
|
|
|
|
|
1080
|
return $build_lib_path; |
663
|
|
|
|
|
|
|
} |
664
|
|
|
|
|
|
|
|
665
|
|
|
|
|
|
|
sub create_dl_func_list { |
666
|
341
|
|
|
341
|
0
|
1375
|
my ($basic_type_name, $method_names, $options) = @_; |
667
|
|
|
|
|
|
|
|
668
|
341
|
|
50
|
|
|
1253
|
$options ||= {}; |
669
|
|
|
|
|
|
|
|
670
|
341
|
|
50
|
|
|
1617
|
my $category = $options->{category} || ''; |
671
|
|
|
|
|
|
|
|
672
|
|
|
|
|
|
|
# dl_func_list |
673
|
|
|
|
|
|
|
# This option is needed Windows DLL file |
674
|
341
|
|
|
|
|
899
|
my $dl_func_list = []; |
675
|
341
|
|
|
|
|
1530
|
for my $method_name (@$method_names) { |
676
|
3834
|
|
|
|
|
7035
|
my $cfunc_name = SPVM::Builder::Util::create_cfunc_name($basic_type_name, $method_name, $category); |
677
|
3834
|
|
|
|
|
8424
|
push @$dl_func_list, $cfunc_name; |
678
|
|
|
|
|
|
|
} |
679
|
|
|
|
|
|
|
|
680
|
|
|
|
|
|
|
# This is bad hack to suppress boot strap function error. |
681
|
341
|
50
|
|
|
|
8236
|
unless (@$dl_func_list) { |
682
|
0
|
|
|
|
|
0
|
push @$dl_func_list, ''; |
683
|
|
|
|
|
|
|
} |
684
|
|
|
|
|
|
|
|
685
|
341
|
|
|
|
|
1289
|
return $dl_func_list; |
686
|
|
|
|
|
|
|
} |
687
|
|
|
|
|
|
|
|
688
|
|
|
|
|
|
|
sub get_dynamic_lib_file_dist { |
689
|
3189
|
|
|
3189
|
0
|
8062
|
my ($class_file, $category) = @_; |
690
|
|
|
|
|
|
|
|
691
|
3189
|
|
|
|
|
9609
|
my $dynamic_lib_file = SPVM::Builder::Util::convert_class_file_to_dynamic_lib_file($class_file, $category); |
692
|
|
|
|
|
|
|
|
693
|
3189
|
|
|
|
|
7763
|
return $dynamic_lib_file; |
694
|
|
|
|
|
|
|
} |
695
|
|
|
|
|
|
|
|
696
|
|
|
|
|
|
|
sub get_method_addresses { |
697
|
3189
|
|
|
3189
|
0
|
11244
|
my ($dynamic_lib_file, $basic_type_name, $method_names, $category) = @_; |
698
|
|
|
|
|
|
|
|
699
|
3189
|
|
|
|
|
7279
|
my $method_addresses = {}; |
700
|
3189
|
50
|
|
|
|
13965
|
if (@$method_names) { |
701
|
3189
|
|
|
|
|
7689
|
my $method_infos = []; |
702
|
3189
|
|
|
|
|
8239
|
for my $method_name (@$method_names) { |
703
|
38704
|
|
|
|
|
52084
|
my $method_info = {}; |
704
|
38704
|
|
|
|
|
68378
|
$method_info->{basic_type_name} = $basic_type_name; |
705
|
38704
|
|
|
|
|
52155
|
$method_info->{method_name} = $method_name; |
706
|
38704
|
|
|
|
|
67108
|
push @$method_infos, $method_info; |
707
|
|
|
|
|
|
|
} |
708
|
|
|
|
|
|
|
|
709
|
3189
|
|
|
|
|
7872
|
for my $method_info (@$method_infos) { |
710
|
38704
|
|
|
|
|
63246
|
my $basic_type_name = $method_info->{basic_type_name}; |
711
|
38704
|
|
|
|
|
51083
|
my $method_name = $method_info->{method_name}; |
712
|
|
|
|
|
|
|
|
713
|
38704
|
|
|
|
|
46398
|
my $cfunc_address; |
714
|
38704
|
50
|
|
|
|
60710
|
if ($dynamic_lib_file) { |
715
|
38704
|
|
|
|
|
642054
|
my $dynamic_lib_libref = DynaLoader::dl_load_file($dynamic_lib_file); |
716
|
|
|
|
|
|
|
|
717
|
38704
|
50
|
|
|
|
74740
|
if ($dynamic_lib_libref) { |
718
|
|
|
|
|
|
|
|
719
|
38704
|
|
|
|
|
71109
|
my $cfunc_name = SPVM::Builder::Util::create_cfunc_name($basic_type_name, $method_name, $category); |
720
|
38704
|
|
|
|
|
114256
|
$cfunc_address = DynaLoader::dl_find_symbol($dynamic_lib_libref, $cfunc_name); |
721
|
38704
|
50
|
|
|
|
82900
|
unless ($cfunc_address) { |
722
|
0
|
|
|
|
|
0
|
my $dl_error = DynaLoader::dl_error(); |
723
|
0
|
|
|
|
|
0
|
my $error = <<"EOS"; |
724
|
|
|
|
|
|
|
Can't find native function \"$cfunc_name\" corresponding to ${basic_type_name}->$method_name in \"$dynamic_lib_file\" |
725
|
|
|
|
|
|
|
|
726
|
|
|
|
|
|
|
You must write the following definition. |
727
|
|
|
|
|
|
|
-------------------------------------------------- |
728
|
|
|
|
|
|
|
#include |
729
|
|
|
|
|
|
|
|
730
|
|
|
|
|
|
|
int32_t $cfunc_name(SPVM_ENV* env, SPVM_VALUE* stack) { |
731
|
|
|
|
|
|
|
|
732
|
|
|
|
|
|
|
return 0; |
733
|
|
|
|
|
|
|
} |
734
|
|
|
|
|
|
|
-------------------------------------------------- |
735
|
|
|
|
|
|
|
|
736
|
|
|
|
|
|
|
$dl_error |
737
|
|
|
|
|
|
|
EOS |
738
|
0
|
|
|
|
|
0
|
confess $error; |
739
|
|
|
|
|
|
|
} |
740
|
|
|
|
|
|
|
} |
741
|
|
|
|
|
|
|
else { |
742
|
0
|
|
|
|
|
0
|
my $dl_error = DynaLoader::dl_error(); |
743
|
0
|
|
|
|
|
0
|
confess "The DynaLoader::dl_load_file function failed:Can't load the \"$dynamic_lib_file\" file for $category methods in $basic_type_name class: $dl_error"; |
744
|
|
|
|
|
|
|
} |
745
|
|
|
|
|
|
|
} |
746
|
|
|
|
|
|
|
else { |
747
|
0
|
|
|
|
|
0
|
confess "DLL file is not specified"; |
748
|
|
|
|
|
|
|
} |
749
|
|
|
|
|
|
|
|
750
|
38704
|
|
|
|
|
96708
|
$method_addresses->{$method_name} = $cfunc_address; |
751
|
|
|
|
|
|
|
} |
752
|
|
|
|
|
|
|
} |
753
|
|
|
|
|
|
|
|
754
|
3189
|
|
|
|
|
45882
|
return $method_addresses; |
755
|
|
|
|
|
|
|
} |
756
|
|
|
|
|
|
|
|
757
|
|
|
|
|
|
|
sub create_default_config { |
758
|
|
|
|
|
|
|
|
759
|
323
|
|
|
323
|
0
|
4907
|
my $config = SPVM::Builder::Config->new_gnu99(file_optional => 1); |
760
|
|
|
|
|
|
|
|
761
|
323
|
|
|
|
|
1042
|
return $config; |
762
|
|
|
|
|
|
|
} |
763
|
|
|
|
|
|
|
|
764
|
|
|
|
|
|
|
sub get_normalized_env { |
765
|
3138
|
|
|
3138
|
0
|
10102
|
my ($name) = @_; |
766
|
|
|
|
|
|
|
|
767
|
3138
|
|
|
|
|
8326
|
my $value = $ENV{$name}; |
768
|
|
|
|
|
|
|
|
769
|
3138
|
50
|
66
|
|
|
12399
|
if (defined $value && !length $value) { |
770
|
0
|
|
|
|
|
0
|
$value = undef; |
771
|
|
|
|
|
|
|
} |
772
|
|
|
|
|
|
|
|
773
|
3138
|
|
|
|
|
7946
|
return $value; |
774
|
|
|
|
|
|
|
} |
775
|
|
|
|
|
|
|
|
776
|
|
|
|
|
|
|
sub get_version_string { |
777
|
0
|
|
|
0
|
0
|
0
|
my ($spvm_class_file) = @_; |
778
|
|
|
|
|
|
|
|
779
|
0
|
0
|
|
|
|
0
|
open my $spvm_module_fh, '<', $spvm_class_file or die "Can't open the file \"$spvm_class_file\": $!"; |
780
|
0
|
|
|
|
|
0
|
local $/; |
781
|
0
|
|
|
|
|
0
|
my $content = <$spvm_module_fh>; |
782
|
0
|
|
|
|
|
0
|
my $version_string; |
783
|
0
|
0
|
|
|
|
0
|
if ($content =~ /\bversion\s*"([\d\._]+)"\s*;/) { |
784
|
0
|
|
|
|
|
0
|
$version_string = $1; |
785
|
|
|
|
|
|
|
} |
786
|
|
|
|
|
|
|
|
787
|
0
|
0
|
|
|
|
0
|
unless (defined $version_string) { |
788
|
0
|
|
|
|
|
0
|
confess "The version string can't be find in $spvm_class_file file"; |
789
|
|
|
|
|
|
|
} |
790
|
|
|
|
|
|
|
|
791
|
0
|
|
|
|
|
0
|
return $version_string; |
792
|
|
|
|
|
|
|
} |
793
|
|
|
|
|
|
|
|
794
|
|
|
|
|
|
|
sub get_spvm_version_string { |
795
|
|
|
|
|
|
|
|
796
|
2
|
|
|
2
|
0
|
2064
|
my $builder_dir = &get_builder_dir_from_config_class; |
797
|
2
|
|
|
|
|
10
|
my $spvm_api_header_file = "$builder_dir/include/spvm_native.h"; |
798
|
|
|
|
|
|
|
|
799
|
2
|
50
|
|
|
|
118
|
open my $spvm_module_fh, '<', $spvm_api_header_file or die "Can't open the file \"$spvm_api_header_file\": $!"; |
800
|
2
|
|
|
|
|
13
|
local $/; |
801
|
2
|
|
|
|
|
208
|
my $content = <$spvm_module_fh>; |
802
|
2
|
|
|
|
|
10
|
my $version_string; |
803
|
2
|
50
|
|
|
|
30
|
if ($content =~ /#define\s+SPVM_NATIVE_VERSION_NUMBER\s* ([\d\._]+)/) { |
804
|
2
|
|
|
|
|
10
|
$version_string = $1; |
805
|
|
|
|
|
|
|
} |
806
|
|
|
|
|
|
|
|
807
|
2
|
50
|
|
|
|
11
|
unless (defined $version_string) { |
808
|
0
|
|
|
|
|
0
|
confess "The version string can't be find in $spvm_api_header_file file"; |
809
|
|
|
|
|
|
|
} |
810
|
|
|
|
|
|
|
|
811
|
2
|
|
|
|
|
38
|
return $version_string; |
812
|
|
|
|
|
|
|
} |
813
|
|
|
|
|
|
|
|
814
|
|
|
|
|
|
|
1; |
815
|
|
|
|
|
|
|
|
816
|
|
|
|
|
|
|
=head1 Name |
817
|
|
|
|
|
|
|
|
818
|
|
|
|
|
|
|
SPVM::Builder::Util - Builder Utilities |
819
|
|
|
|
|
|
|
|
820
|
|
|
|
|
|
|
=head1 Description |
821
|
|
|
|
|
|
|
|
822
|
|
|
|
|
|
|
The SPVM::Builder::Util class has utility functions for the L class. |
823
|
|
|
|
|
|
|
|
824
|
|
|
|
|
|
|
=head1 Copyright & License |
825
|
|
|
|
|
|
|
|
826
|
|
|
|
|
|
|
Copyright (c) 2023 Yuki Kimoto |
827
|
|
|
|
|
|
|
|
828
|
|
|
|
|
|
|
MIT License |