vladx 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +256 -0
- package/bin/cli.js +486 -0
- package/bin/vlad.js +539 -0
- package/bin/vladpm.js +710 -0
- package/bin/vladx.js +491 -0
- package/package.json +57 -0
- package/src/engine/jit-compiler.js +285 -0
- package/src/engine/vladx-engine.js +941 -0
- package/src/index.js +44 -0
- package/src/interpreter/interpreter.js +2114 -0
- package/src/lexer/lexer.js +658 -0
- package/src/lexer/optimized-lexer.js +106 -0
- package/src/lexer/regex-cache.js +83 -0
- package/src/parser/ast-nodes.js +472 -0
- package/src/parser/parser.js +1408 -0
- package/src/runtime/advanced-type-system.js +209 -0
- package/src/runtime/async-manager.js +252 -0
- package/src/runtime/builtins.js +143 -0
- package/src/runtime/bundler.js +422 -0
- package/src/runtime/cache-manager.js +126 -0
- package/src/runtime/data-structures.js +612 -0
- package/src/runtime/debugger.js +260 -0
- package/src/runtime/enhanced-module-system.js +196 -0
- package/src/runtime/environment-enhanced.js +272 -0
- package/src/runtime/environment.js +140 -0
- package/src/runtime/event-emitter.js +232 -0
- package/src/runtime/formatter.js +280 -0
- package/src/runtime/functional.js +359 -0
- package/src/runtime/io-operations.js +390 -0
- package/src/runtime/linter.js +374 -0
- package/src/runtime/logging.js +314 -0
- package/src/runtime/minifier.js +242 -0
- package/src/runtime/module-system.js +377 -0
- package/src/runtime/network-operations.js +373 -0
- package/src/runtime/profiler.js +295 -0
- package/src/runtime/repl.js +336 -0
- package/src/runtime/security-manager.js +244 -0
- package/src/runtime/source-map-generator.js +208 -0
- package/src/runtime/test-runner.js +394 -0
- package/src/runtime/transformer.js +277 -0
- package/src/runtime/type-system.js +244 -0
- package/src/runtime/vladx-object.js +250 -0
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JIT Compiler for VladX — Компиляция в JavaScript для повышения производительности
|
|
3
|
+
* Преобразует часто выполняемые функции VladX в оптимизированный JavaScript код
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { VladXObject } from '../runtime/vladx-object.js';
|
|
7
|
+
|
|
8
|
+
export class JITCompiler {
|
|
9
|
+
constructor(interpreter) {
|
|
10
|
+
this.interpreter = interpreter;
|
|
11
|
+
this.compiledFunctions = new Map(); // Кэш скомпилированных функций
|
|
12
|
+
this.functionCallCounts = new Map(); // Счетчик вызовов функций
|
|
13
|
+
this.hotReloadEnabled = true;
|
|
14
|
+
this.compilationThreshold = 10; // После скольки вызовов компилировать
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Проверка, нужно ли компилировать функцию
|
|
19
|
+
*/
|
|
20
|
+
shouldCompile(functionName) {
|
|
21
|
+
const count = this.functionCallCounts.get(functionName) || 0;
|
|
22
|
+
return count >= this.compilationThreshold && !this.compiledFunctions.has(functionName);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Увеличение счетчика вызовов функции
|
|
27
|
+
*/
|
|
28
|
+
incrementCallCount(functionName) {
|
|
29
|
+
const count = this.functionCallCounts.get(functionName) || 0;
|
|
30
|
+
this.functionCallCounts.set(functionName, count + 1);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Проверка, нужно ли компилировать функцию
|
|
35
|
+
*/
|
|
36
|
+
shouldCompile(functionName) {
|
|
37
|
+
const count = this.functionCallCounts.get(functionName) || 0;
|
|
38
|
+
return count >= this.compilationThreshold && !this.compiledFunctions.has(functionName);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Увеличение счетчика вызовов функции
|
|
43
|
+
*/
|
|
44
|
+
incrementCallCount(functionName) {
|
|
45
|
+
const count = this.functionCallCounts.get(functionName) || 0;
|
|
46
|
+
this.functionCallCounts.set(functionName, count + 1);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Компиляция функции VladX в JavaScript
|
|
51
|
+
*/
|
|
52
|
+
compileFunction(funcNode, functionName = null) {
|
|
53
|
+
try {
|
|
54
|
+
const compiledCode = this.generateFunctionCode(funcNode, functionName);
|
|
55
|
+
|
|
56
|
+
// Создаем функцию из сгенерированного кода
|
|
57
|
+
const compiledFunction = new Function('__builtins__', '__env__', '__interpreter__', compiledCode);
|
|
58
|
+
|
|
59
|
+
this.compiledFunctions.set(functionName || funcNode.name, {
|
|
60
|
+
compiledFunction,
|
|
61
|
+
originalNode: funcNode,
|
|
62
|
+
compiledAt: Date.now()
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
return compiledFunction;
|
|
66
|
+
} catch (error) {
|
|
67
|
+
console.warn(`JIT compilation failed for ${functionName}:`, error);
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Генерация JavaScript кода из AST функции
|
|
74
|
+
*/
|
|
75
|
+
generateFunctionCode(funcNode, functionName) {
|
|
76
|
+
const params = (funcNode.params || funcNode.parameters || []).map(p => p.name || p);
|
|
77
|
+
const paramNames = params.join(', ');
|
|
78
|
+
|
|
79
|
+
// Генерируем тело функции (body может быть BlockStatement)
|
|
80
|
+
const statements = funcNode.body && funcNode.body.body ? funcNode.body.body : (funcNode.body || []);
|
|
81
|
+
const bodyCode = this.generateBodyCode(statements);
|
|
82
|
+
|
|
83
|
+
// Оборачиваем в try-catch для обработки ошибок
|
|
84
|
+
const wrappedCode = `
|
|
85
|
+
try {
|
|
86
|
+
${bodyCode}
|
|
87
|
+
} catch (error) {
|
|
88
|
+
__interpreter.wrapError(error);
|
|
89
|
+
throw error;
|
|
90
|
+
}
|
|
91
|
+
`;
|
|
92
|
+
|
|
93
|
+
// Возвращаем код анонимной функции
|
|
94
|
+
return `return async function(${paramNames}) { ${wrappedCode} };`;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Генерация кода для тела функции
|
|
99
|
+
*/
|
|
100
|
+
generateBodyCode(statements) {
|
|
101
|
+
const lines = [];
|
|
102
|
+
|
|
103
|
+
for (const stmt of statements) {
|
|
104
|
+
const line = this.generateStatementCode(stmt);
|
|
105
|
+
if (line) {
|
|
106
|
+
lines.push(line);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return lines.join('\n');
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Генерация кода для отдельного statement
|
|
115
|
+
*/
|
|
116
|
+
generateStatementCode(stmt) {
|
|
117
|
+
switch (stmt.type) {
|
|
118
|
+
case 'ReturnStatement':
|
|
119
|
+
const returnValue = stmt.argument ? this.generateExpressionCode(stmt.argument) : 'null';
|
|
120
|
+
return `return ${returnValue};`;
|
|
121
|
+
|
|
122
|
+
case 'ExpressionStatement':
|
|
123
|
+
return this.generateExpressionCode(stmt.expression) + ';';
|
|
124
|
+
|
|
125
|
+
case 'LetStatement':
|
|
126
|
+
const init = stmt.initializer ? this.generateExpressionCode(stmt.initializer) : 'undefined';
|
|
127
|
+
return `let ${stmt.name} = ${init};`;
|
|
128
|
+
|
|
129
|
+
case 'ConstStatement':
|
|
130
|
+
const constInit = stmt.initializer ? this.generateExpressionCode(stmt.initializer) : 'undefined';
|
|
131
|
+
return `const ${stmt.name} = ${constInit};`;
|
|
132
|
+
|
|
133
|
+
case 'IfStatement':
|
|
134
|
+
return this.generateIfCode(stmt);
|
|
135
|
+
|
|
136
|
+
case 'WhileStatement':
|
|
137
|
+
return this.generateWhileCode(stmt);
|
|
138
|
+
|
|
139
|
+
case 'ForStatement':
|
|
140
|
+
return this.generateForCode(stmt);
|
|
141
|
+
|
|
142
|
+
default:
|
|
143
|
+
// Для неподдерживаемых statements используем интерпретатор
|
|
144
|
+
return `__interpreter.evaluateStatement(${JSON.stringify(stmt)});`;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Генерация кода для выражений
|
|
150
|
+
*/
|
|
151
|
+
generateExpressionCode(expr) {
|
|
152
|
+
switch (expr.type) {
|
|
153
|
+
case 'Literal':
|
|
154
|
+
return JSON.stringify(expr.value);
|
|
155
|
+
|
|
156
|
+
case 'Identifier':
|
|
157
|
+
return expr.name;
|
|
158
|
+
|
|
159
|
+
case 'BinaryExpression':
|
|
160
|
+
const left = this.generateExpressionCode(expr.left);
|
|
161
|
+
const right = this.generateExpressionCode(expr.right);
|
|
162
|
+
return `(${left} ${expr.operator} ${right})`;
|
|
163
|
+
|
|
164
|
+
case 'UnaryExpression':
|
|
165
|
+
const operand = this.generateExpressionCode(expr.operand);
|
|
166
|
+
return `${expr.operator}${operand}`;
|
|
167
|
+
|
|
168
|
+
case 'CallExpression':
|
|
169
|
+
const callee = this.generateExpressionCode(expr.callee);
|
|
170
|
+
const args = expr.arguments.map(arg => this.generateExpressionCode(arg)).join(', ');
|
|
171
|
+
return `await ${callee}(${args})`;
|
|
172
|
+
|
|
173
|
+
case 'MemberExpression':
|
|
174
|
+
const obj = this.generateExpressionCode(expr.object);
|
|
175
|
+
const prop = this.generateExpressionCode(expr.property);
|
|
176
|
+
return `${obj}.${prop}`;
|
|
177
|
+
|
|
178
|
+
case 'FunctionExpression':
|
|
179
|
+
// Встраиваем определение функции
|
|
180
|
+
const funcParams = expr.parameters.map(p => p.name).join(', ');
|
|
181
|
+
const funcBody = this.generateBodyCode(expr.body);
|
|
182
|
+
return `async function(${funcParams}) { ${funcBody} }`;
|
|
183
|
+
|
|
184
|
+
default:
|
|
185
|
+
// Для сложных выражений используем интерпретатор
|
|
186
|
+
return `__interpreter.evaluateExpression(${JSON.stringify(expr)})`;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Генерация кода для if statement
|
|
192
|
+
*/
|
|
193
|
+
generateIfCode(stmt) {
|
|
194
|
+
const condition = this.generateExpressionCode(stmt.condition);
|
|
195
|
+
const thenBranch = this.generateBodyCode(stmt.thenBranch);
|
|
196
|
+
let code = `if (${condition}) { ${thenBranch} }`;
|
|
197
|
+
|
|
198
|
+
if (stmt.elseBranch) {
|
|
199
|
+
const elseBranch = this.generateBodyCode(stmt.elseBranch);
|
|
200
|
+
code += ` else { ${elseBranch} }`;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
return code;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Генерация кода для while statement
|
|
208
|
+
*/
|
|
209
|
+
generateWhileCode(stmt) {
|
|
210
|
+
const condition = this.generateExpressionCode(stmt.condition);
|
|
211
|
+
const body = this.generateBodyCode(stmt.body);
|
|
212
|
+
return `while (${condition}) { ${body} }`;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Генерация кода для for statement
|
|
217
|
+
*/
|
|
218
|
+
generateForCode(stmt) {
|
|
219
|
+
const init = this.generateStatementCode(stmt.initializer);
|
|
220
|
+
const condition = this.generateExpressionCode(stmt.condition);
|
|
221
|
+
const update = this.generateExpressionCode(stmt.update);
|
|
222
|
+
const body = this.generateBodyCode(stmt.body);
|
|
223
|
+
return `for (${init}; ${condition}; ${update}) { ${body} }`;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Выполнение скомпилированной функции
|
|
228
|
+
*/
|
|
229
|
+
async executeCompiledFunction(functionName, args, context) {
|
|
230
|
+
const compiled = this.compiledFunctions.get(functionName);
|
|
231
|
+
if (!compiled) {
|
|
232
|
+
throw new Error(`Compiled function ${functionName} not found`);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
try {
|
|
236
|
+
// Создаем execution context
|
|
237
|
+
const execFunction = compiled.compiledFunction(
|
|
238
|
+
this.interpreter.builtins,
|
|
239
|
+
context.environment || this.interpreter.currentEnv,
|
|
240
|
+
this.interpreter
|
|
241
|
+
);
|
|
242
|
+
|
|
243
|
+
return await execFunction(...args);
|
|
244
|
+
} catch (error) {
|
|
245
|
+
console.warn(`Compiled function ${functionName} failed, falling back to interpreter:`, error);
|
|
246
|
+
// Fallback to interpreter
|
|
247
|
+
return this.interpreter.evaluateExpression(compiled.originalNode);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Очистка кэша скомпилированных функций
|
|
253
|
+
*/
|
|
254
|
+
clearCache() {
|
|
255
|
+
this.compiledFunctions.clear();
|
|
256
|
+
this.functionCallCounts.clear();
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Горячая перезагрузка — очистка устаревших компиляций
|
|
261
|
+
*/
|
|
262
|
+
hotReload() {
|
|
263
|
+
if (!this.hotReloadEnabled) return;
|
|
264
|
+
|
|
265
|
+
const now = Date.now();
|
|
266
|
+
const staleThreshold = 5 * 60 * 1000; // 5 минут
|
|
267
|
+
|
|
268
|
+
for (const [name, data] of this.compiledFunctions) {
|
|
269
|
+
if (now - data.compiledAt > staleThreshold) {
|
|
270
|
+
this.compiledFunctions.delete(name);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Получение статистики JIT компиляции
|
|
277
|
+
*/
|
|
278
|
+
getStats() {
|
|
279
|
+
return {
|
|
280
|
+
compiledFunctionsCount: this.compiledFunctions.size,
|
|
281
|
+
functionCallCounts: Object.fromEntries(this.functionCallCounts),
|
|
282
|
+
compilationThreshold: this.compilationThreshold
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
}
|