Skip to content

Commit 31ec784

Browse files
committed
Feature(compiler): Support mangling method names, Math.floor works!
1 parent 5c8d975 commit 31ec784

8 files changed

Lines changed: 68 additions & 15 deletions

File tree

package-lock.json

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
"commander": "^2.19.0"
2424
},
2525
"dependencies": {
26-
"@static-script/runtime": "^0.3.0",
26+
"@static-script/runtime": "^0.4.0",
2727
"llvm-node": "github:MichaReiser/llvm-node#master",
2828
"typescript": "^3.1.1"
2929
}
3.52 KB
Binary file not shown.

packages/runtime/package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
"main": "index.js",
66
"scripts": {
77
"build": "tsc",
8-
"prepublish": "npm run build",
98
"install": "cmake . && make"
109
},
1110
"author": "Dmitry Patsura <talk@dmtry.me>",

src/backend/llvm/c.mangler.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22
import * as ts from 'typescript';
33

44
export class CMangler {
5+
static getMethodName(parent: string, name: string, parameters: ts.NodeArray<ts.ParameterDeclaration>): string {
6+
return name;
7+
}
8+
59
static getFunctionName(name: string, parameters: ts.NodeArray<ts.ParameterDeclaration>): string {
610
return name;
711
}

src/backend/llvm/cpp.mangler.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,31 @@
22
import * as ts from 'typescript';
33

44
export class CPPMangler {
5+
static getMethodName(clazz: string, method: string, parameters: ts.NodeArray<ts.ParameterDeclaration>): string {
6+
const name = clazz + '__' + method;
7+
8+
return '_Z' + name.length + name + parameters.map(
9+
(parameter) => {
10+
if (parameter.type) {
11+
switch (parameter.type.kind) {
12+
case ts.SyntaxKind.NumberKeyword:
13+
return 'd';
14+
case ts.SyntaxKind.StringKeyword:
15+
return 'PKc';
16+
case ts.SyntaxKind.BooleanKeyword:
17+
return 'b';
18+
default:
19+
throw new Error(
20+
`Unsupported mangling parameter type: ${parameter.type.kind}`
21+
);
22+
}
23+
}
24+
25+
throw new Error('Unsupported mangling without type');
26+
}
27+
);
28+
}
29+
530
static getFunctionName(name: string, parameters: ts.NodeArray<ts.ParameterDeclaration>): string {
631
return '_Z' + name.length + name + parameters.map(
732
(parameter) => {

src/backend/llvm/index.ts

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {RUNTIME_DEFINITION_FILE} from "@static-script/runtime";
1010
import {LANGUAGE_DEFINITION_FILE} from "../../constants";
1111
import {CMangler} from "./c.mangler";
1212
import {ManglerInterface} from "./mangler.interface";
13+
import {SignatureDeclaration} from "typescript";
1314

1415
export function passReturnStatement(parent: ts.ReturnStatement, ctx: Context, builder: llvm.IRBuilder) {
1516
if (!parent.expression) {
@@ -375,6 +376,29 @@ function buildFromPostfixUnaryExpression(
375376
}
376377
}
377378

379+
380+
function mangleNameFromDecleration(
381+
declaration: ts.SignatureDeclaration,
382+
ctx: Context,
383+
mangler: ManglerInterface
384+
) {
385+
if (declaration.kind === ts.SyntaxKind.MethodDeclaration) {
386+
const left = ctx.typeChecker.getTypeAtLocation(declaration.parent!) as ts.ObjectType;
387+
388+
return mangler.getMethodName(
389+
<string>left.symbol.escapedName,
390+
<string>(<ts.Identifier>declaration.name).escapedText,
391+
declaration.parameters
392+
);
393+
}
394+
395+
return mangler.getFunctionName(
396+
<string>(<ts.Identifier>declaration.name).escapedText,
397+
declaration.parameters
398+
);
399+
}
400+
401+
378402
function buildCalleFromCallExpression(
379403
expr: ts.CallExpression,
380404
ctx: Context,
@@ -386,16 +410,16 @@ function buildCalleFromCallExpression(
386410
return ctx.signature.get(calleSignature);
387411
}
388412

389-
const symbolDeclaration = <ts.SignatureDeclaration>calleSignature.declaration;
390-
if (symbolDeclaration.name) {
391-
const sourceFile = symbolDeclaration.getSourceFile();
413+
const declaration = <ts.SignatureDeclaration>calleSignature.declaration;
414+
if (declaration.name) {
415+
const sourceFile = declaration.getSourceFile();
392416

393417
if (sourceFile.fileName === RUNTIME_DEFINITION_FILE) {
394418
const llvmFunction = declareFunctionFromDefinition(
395-
<ts.FunctionDeclaration>symbolDeclaration,
419+
<ts.FunctionDeclaration>declaration,
396420
ctx,
397421
builder,
398-
CPPMangler
422+
mangleNameFromDecleration(declaration, ctx, CPPMangler)
399423
);
400424

401425
ctx.signature.set(calleSignature, llvmFunction);
@@ -405,10 +429,10 @@ function buildCalleFromCallExpression(
405429

406430
if (sourceFile.fileName === LANGUAGE_DEFINITION_FILE) {
407431
const llvmFunction = declareFunctionFromDefinition(
408-
<ts.FunctionDeclaration>symbolDeclaration,
432+
<ts.FunctionDeclaration>declaration,
409433
ctx,
410434
builder,
411-
CMangler
435+
mangleNameFromDecleration(declaration, ctx, CMangler)
412436
);
413437

414438

@@ -449,7 +473,7 @@ function declareFunctionFromDefinition(
449473
stmt: ts.FunctionDeclaration,
450474
ctx: Context,
451475
builder: llvm.IRBuilder,
452-
mangler: ManglerInterface
476+
name: string
453477
): llvm.Function {
454478
let fnType = llvm.FunctionType.get(
455479
stmt.type ? NativeTypeResolver.getType(ctx.typeChecker.getTypeFromTypeNode(stmt.type), ctx).getType() : llvm.Type.getVoidTy(ctx.llvmContext),
@@ -469,7 +493,7 @@ function declareFunctionFromDefinition(
469493
return llvm.Function.create(
470494
fnType,
471495
llvm.LinkageTypes.ExternalLinkage,
472-
mangler.getFunctionName(<string>stmt.name.escapedText, stmt.parameters),
496+
name,
473497
ctx.llvmModule
474498
);
475499
}

src/backend/llvm/mangler.interface.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ import * as ts from "typescript";
33

44
export interface ManglerInterface {
55
getFunctionName(name: string, parameters: ts.NodeArray<ts.ParameterDeclaration>): string;
6+
getMethodName(parent: string, name: string, parameters: ts.NodeArray<ts.ParameterDeclaration>): string;
67
}

0 commit comments

Comments
 (0)