This commit is contained in:
dcode
2019-03-13 09:05:02 +01:00
parent e581f254d0
commit 6f70826e45
11 changed files with 251 additions and 227 deletions

View File

@ -4098,9 +4098,8 @@ export function compileIterateRoots(compiler: Compiler): void {
);
}
function typedArraySymbolToType(symbol: string): Type {
function typedArraySymbolToType(symbol: string): Type | null {
switch (symbol) {
default: assert(false);
case BuiltinSymbols.Int8Array: return Type.i8;
case BuiltinSymbols.Uint8ClampedArray:
case BuiltinSymbols.Uint8Array: return Type.u8;
@ -4113,9 +4112,10 @@ function typedArraySymbolToType(symbol: string): Type {
case BuiltinSymbols.Float32Array: return Type.f32;
case BuiltinSymbols.Float64Array: return Type.f64;
}
return null;
}
export function compileTypedArrayGet(
export function compileArrayGet(
compiler: Compiler,
target: Class,
thisExpression: Expression,
@ -4123,6 +4123,20 @@ export function compileTypedArrayGet(
contextualType: Type
): ExpressionRef {
var type = typedArraySymbolToType(target.internalName);
if (type) return compileTypedArrayGet(compiler, target, type, thisExpression, elementExpression, contextualType);
assert(target.prototype == compiler.program.arrayPrototype);
type = assert(target.typeArguments)[0];
throw new Error("not implemented");
}
function compileTypedArrayGet(
compiler: Compiler,
target: Class,
type: Type,
thisExpression: Expression,
elementExpression: Expression,
contextualType: Type
): ExpressionRef {
var module = compiler.module;
var outType = (
type.is(TypeFlags.INTEGER) &&
@ -4130,8 +4144,6 @@ export function compileTypedArrayGet(
contextualType.size > type.size
) ? contextualType : type;
var bufferField = assert(target.lookupInSelf("buffer"));
assert(bufferField.kind == ElementKind.FIELD);
var dataStart = assert(target.lookupInSelf("dataStart"));
assert(dataStart.kind == ElementKind.FIELD);
var dataEnd = assert(target.lookupInSelf("dataEnd"));
@ -4198,19 +4210,36 @@ export function compileTypedArrayGet(
);
}
export function compileTypedArraySet(
export function compileArraySet(
compiler: Compiler,
target: Class,
thisExpression: Expression,
elementExpression: Expression,
valueExpression: Expression,
contextualType: Type
): ExpressionRef {
var type = typedArraySymbolToType(target.internalName);
if (type) {
return compileTypedArraySet(compiler, target, type, thisExpression,
elementExpression, valueExpression, contextualType);
}
assert(target.prototype == compiler.program.arrayPrototype);
type = assert(target.typeArguments)[0];
throw new Error("not implemented");
}
function compileTypedArraySet(
compiler: Compiler,
target: Class,
type: Type,
thisExpression: Expression,
elementExpression: Expression,
valueExpression: Expression,
contextualType: Type
): ExpressionRef {
var type = typedArraySymbolToType(target.internalName);
var module = compiler.module;
var bufferField = assert(target.lookupInSelf("buffer"));
assert(bufferField.kind == ElementKind.FIELD);
var dataStart = assert(target.lookupInSelf("dataStart"));
assert(dataStart.kind == ElementKind.FIELD);
var dataEnd = assert(target.lookupInSelf("dataEnd"));

View File

@ -9,8 +9,8 @@ import {
compileIterateRoots,
ensureGCHook,
BuiltinSymbols,
compileTypedArrayGet,
compileTypedArraySet
compileArrayGet,
compileArraySet
} from "./builtins";
import {
@ -4687,22 +4687,22 @@ export class Compiler extends DiagnosticEmitter {
case ElementKind.CLASS: {
let elementExpression = resolver.currentElementExpression;
if (elementExpression) { // indexed access
let arrayBufferView = this.program.arrayBufferView;
if (arrayBufferView) {
if ((<Class>target).prototype.extends(arrayBufferView.prototype)) {
return compileTypedArraySet(
this,
<Class>target,
assert(this.resolver.currentThisExpression),
elementExpression,
valueExpression,
contextualType
);
}
}
let isUnchecked = flow.is(FlowFlags.UNCHECKED_CONTEXT);
let indexedSet = (<Class>target).lookupOverload(OperatorKind.INDEXED_SET, isUnchecked);
if (!indexedSet) {
let arrayBufferView = this.program.arrayBufferView;
if (arrayBufferView) {
if ((<Class>target).prototype.extends(arrayBufferView.prototype)) {
return compileArraySet(
this,
<Class>target,
assert(this.resolver.currentThisExpression),
elementExpression,
valueExpression,
contextualType
);
}
}
let indexedGet = (<Class>target).lookupOverload(OperatorKind.INDEXED_GET, isUnchecked);
if (!indexedGet) {
this.error(
@ -4718,7 +4718,7 @@ export class Compiler extends DiagnosticEmitter {
return this.module.createUnreachable();
}
assert(indexedSet.signature.parameterTypes.length == 2); // parser must guarantee this
targetType = indexedSet.signature.parameterTypes[1]; // 2nd parameter is the element
targetType = indexedSet.signature.parameterTypes[1]; // 2nd parameter is the element
break;
}
// fall-through
@ -5749,26 +5749,31 @@ export class Compiler extends DiagnosticEmitter {
let allOptionalsAreConstant = true;
for (let i = numArguments; i < maxArguments; ++i) {
let initializer = parameterNodes[i].initializer;
if (!(initializer && nodeIsConstantValue(initializer.kind))) {
allOptionalsAreConstant = false;
break;
}
}
if (allOptionalsAreConstant) { // inline into the call
for (let i = numArguments; i < maxArguments; ++i) {
operands.push(
this.compileExpression(
if (initializer) {
let resolved: Element | null;
if (
nodeIsConstantValue(initializer.kind) ||
(
(resolved = this.resolver.resolveExpression(initializer, instance.flow, parameterTypes[i])) &&
(
resolved.kind == ElementKind.GLOBAL
// resolved.kind == ElementKind.FUNCTION_TARGET
)
)
) { // inline into the call
operands.push(this.compileExpression(
<Expression>parameterNodes[i].initializer,
parameterTypes[i],
ConversionKind.IMPLICIT,
WrapMode.NONE
)
);
}
} else { // otherwise fill up with zeroes and call the trampoline
for (let i = numArguments; i < maxArguments; ++i) {
operands.push(parameterTypes[i].toNativeZero(module));
));
continue;
}
}
operands.push(parameterTypes[i].toNativeZero(module));
allOptionalsAreConstant = false;
}
if (!allOptionalsAreConstant) {
if (!isCallImport) {
let original = instance;
instance = this.ensureTrampoline(instance);
@ -5902,21 +5907,21 @@ export class Compiler extends DiagnosticEmitter {
if (!target) return this.module.createUnreachable();
switch (target.kind) {
case ElementKind.CLASS: {
let arrayBufferView = this.program.arrayBufferView;
if (arrayBufferView) {
if ((<Class>target).prototype.extends(arrayBufferView.prototype)) {
return compileTypedArrayGet(
this,
<Class>target,
expression.expression,
expression.elementExpression,
contextualType
);
}
}
let isUnchecked = this.currentFlow.is(FlowFlags.UNCHECKED_CONTEXT);
let indexedGet = (<Class>target).lookupOverload(OperatorKind.INDEXED_GET, isUnchecked);
if (!indexedGet) {
let arrayBufferView = this.program.arrayBufferView;
if (arrayBufferView) {
if ((<Class>target).prototype.extends(arrayBufferView.prototype)) {
return compileArrayGet(
this,
<Class>target,
expression.expression,
expression.elementExpression,
contextualType
);
}
}
this.error(
DiagnosticCode.Index_signature_is_missing_in_type_0,
expression.expression.range, (<Class>target).internalName

View File

@ -632,11 +632,10 @@ export class Program extends DiagnosticEmitter {
true // isImport
);
} else {
// FIXME: file not found is not reported if this happens?
this.error(
DiagnosticCode.Module_0_has_no_exported_member_1,
foreignIdentifier.range,
queuedImport.foreignPath,
foreignIdentifier.text
foreignIdentifier.range, queuedImport.foreignPath, foreignIdentifier.text
);
}
} else { // i.e. import * as bar from "./bar"