| 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 |