mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-04-28 08:22:15 +00:00
handle references externally assigned to fields
This commit is contained in:
parent
e1070cee86
commit
57c8bd01ca
133
src/compiler.ts
133
src/compiler.ts
@ -528,45 +528,9 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ElementKind.FIELD: {
|
case ElementKind.FIELD: {
|
||||||
let module = this.module;
|
this.ensureModuleFieldGetter(prefix + GETTER_PREFIX + name, <Field>element);
|
||||||
let type = (<Field>element).type;
|
|
||||||
let nativeType = type.toNativeType();
|
|
||||||
let offset = (<Field>element).memoryOffset;
|
|
||||||
let usizeType = this.options.usizeType;
|
|
||||||
let nativeSizeType = this.options.nativeSizeType;
|
|
||||||
|
|
||||||
// make a getter
|
|
||||||
let getterName = prefix + GETTER_PREFIX + name;
|
|
||||||
module.addFunction(
|
|
||||||
getterName,
|
|
||||||
this.ensureFunctionType(null, type, usizeType),
|
|
||||||
null,
|
|
||||||
module.createLoad(
|
|
||||||
type.byteSize,
|
|
||||||
type.is(TypeFlags.SIGNED),
|
|
||||||
module.createGetLocal(0, nativeSizeType),
|
|
||||||
nativeType,
|
|
||||||
offset
|
|
||||||
)
|
|
||||||
);
|
|
||||||
module.addFunctionExport(getterName, getterName);
|
|
||||||
|
|
||||||
// make a setter
|
|
||||||
if (!element.is(CommonFlags.READONLY)) {
|
if (!element.is(CommonFlags.READONLY)) {
|
||||||
let setterName = prefix + SETTER_PREFIX + name;
|
this.ensureModuleFieldSetter(prefix + SETTER_PREFIX + name, <Field>element);
|
||||||
module.addFunction(
|
|
||||||
setterName,
|
|
||||||
this.ensureFunctionType([ type ], Type.void, usizeType),
|
|
||||||
null,
|
|
||||||
module.createStore(
|
|
||||||
type.byteSize,
|
|
||||||
module.createGetLocal(0, nativeSizeType),
|
|
||||||
module.createGetLocal(1, nativeType),
|
|
||||||
nativeType,
|
|
||||||
offset
|
|
||||||
)
|
|
||||||
);
|
|
||||||
module.addFunctionExport(setterName, setterName);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -614,6 +578,99 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Makes a function to get the value of a field of an exported class. */
|
||||||
|
private ensureModuleFieldGetter(name: string, field: Field): void {
|
||||||
|
var module = this.module;
|
||||||
|
var type = field.type;
|
||||||
|
var usizeType = this.options.usizeType;
|
||||||
|
module.addFunction(
|
||||||
|
name,
|
||||||
|
this.ensureFunctionType(null, type, usizeType),
|
||||||
|
null,
|
||||||
|
module.createLoad(type.byteSize, type.is(TypeFlags.SIGNED),
|
||||||
|
module.createGetLocal(0, usizeType.toNativeType()),
|
||||||
|
type.toNativeType(), field.memoryOffset
|
||||||
|
)
|
||||||
|
);
|
||||||
|
module.addFunctionExport(name, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Makes a function to set the value of a field of an exported class. */
|
||||||
|
private ensureModuleFieldSetter(name: string, field: Field): void {
|
||||||
|
var module = this.module;
|
||||||
|
var program = this.program;
|
||||||
|
var type = field.type;
|
||||||
|
var nativeType = type.toNativeType();
|
||||||
|
var usizeType = this.options.usizeType;
|
||||||
|
var nativeSizeType = usizeType.toNativeType();
|
||||||
|
if (type.isManaged(program)) {
|
||||||
|
let fn1: Function | null, fn2: Function | null;
|
||||||
|
let body: ExpressionRef[] = [];
|
||||||
|
if (fn1 = program.linkRef) { // tracing
|
||||||
|
if (fn2 = program.unlinkRef) {
|
||||||
|
body.push(
|
||||||
|
module.createCall(fn2.internalName, [
|
||||||
|
module.createGetLocal(2, nativeType),
|
||||||
|
module.createGetLocal(0, nativeSizeType)
|
||||||
|
], NativeType.None)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
body.push(
|
||||||
|
module.createCall(fn1.internalName, [
|
||||||
|
module.createGetLocal(1, nativeSizeType),
|
||||||
|
module.createGetLocal(0, nativeSizeType)
|
||||||
|
], NativeType.None)
|
||||||
|
);
|
||||||
|
} else if (fn1 = program.retainRef) { // arc
|
||||||
|
fn2 = assert(program.releaseRef);
|
||||||
|
body.push(
|
||||||
|
module.createCall(fn2.internalName, [
|
||||||
|
module.createGetLocal(2, nativeType)
|
||||||
|
], NativeType.None)
|
||||||
|
);
|
||||||
|
body.push(
|
||||||
|
module.createCall(fn1.internalName, [
|
||||||
|
module.createGetLocal(1, nativeSizeType)
|
||||||
|
], NativeType.None)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
module.addFunction(
|
||||||
|
name,
|
||||||
|
this.ensureFunctionType([ type ], Type.void, usizeType),
|
||||||
|
[ nativeType ],
|
||||||
|
module.createIf( // if (value != oldValue) release/retain ..
|
||||||
|
module.createBinary(
|
||||||
|
nativeSizeType == NativeType.I64
|
||||||
|
? BinaryOp.NeI64
|
||||||
|
: BinaryOp.NeI32,
|
||||||
|
module.createGetLocal(1, nativeType),
|
||||||
|
module.createTeeLocal(2,
|
||||||
|
module.createLoad(type.byteSize, false,
|
||||||
|
module.createGetLocal(0, nativeSizeType),
|
||||||
|
nativeType, field.memoryOffset
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
module.createBlock(null, body)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
module.addFunction(
|
||||||
|
name,
|
||||||
|
this.ensureFunctionType([ type ], Type.void, usizeType),
|
||||||
|
null,
|
||||||
|
module.createStore(
|
||||||
|
type.byteSize,
|
||||||
|
module.createGetLocal(0, nativeSizeType),
|
||||||
|
module.createGetLocal(1, nativeType),
|
||||||
|
nativeType,
|
||||||
|
field.memoryOffset
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
module.addFunctionExport(name, name);
|
||||||
|
}
|
||||||
|
|
||||||
// === Elements =================================================================================
|
// === Elements =================================================================================
|
||||||
|
|
||||||
/** Compiles any element. */
|
/** Compiles any element. */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user