@@ -2217,6 +2217,16 @@ export class Compiler extends DiagnosticEmitter {
22172217 this . error ( DiagnosticCode . Cannot_assign_to_0_because_it_is_a_constant_or_a_read_only_property , expression . range , ( < Property > element ) . internalName ) ;
22182218 return this . module . createUnreachable ( ) ;
22192219
2220+ case ElementKind . FUNCTION_PROTOTYPE :
2221+ if ( expression . kind == NodeKind . ELEMENTACCESS ) { // @operator ("[]")
2222+ assert ( resolved . target && resolved . target . kind == ElementKind . CLASS && element . simpleName == ( < Class > resolved . target ) . prototype . fnIndexedGet )
2223+ var resolvedIndexedSet = ( < FunctionPrototype > element ) . resolve ( null ) ;
2224+ if ( resolvedIndexedSet ) {
2225+ elementType = resolvedIndexedSet . returnType ;
2226+ break ;
2227+ }
2228+ }
2229+ // fall-through
22202230 default :
22212231 this . error ( DiagnosticCode . Operation_not_supported , expression . range ) ;
22222232 return this . module . createUnreachable ( ) ;
@@ -2275,11 +2285,11 @@ export class Compiler extends DiagnosticEmitter {
22752285 this . currentType = tee ? ( < Field > element ) . type : Type . void ;
22762286 var elementNativeType = ( < Field > element ) . type . toNativeType ( ) ;
22772287 if ( ! tee )
2278- return this . module . createStore ( ( < Field > element ) . type . byteSize , targetExpr , valueWithCorrectType , elementNativeType , ( < Field > element ) . memoryOffset ) ;
2288+ return this . module . createStore ( ( < Field > element ) . type . size >> 3 , targetExpr , valueWithCorrectType , elementNativeType , ( < Field > element ) . memoryOffset ) ;
22792289 tempLocal = this . currentFunction . getAndFreeTempLocal ( ( < Field > element ) . type ) ;
22802290 return this . module . createBlock ( null , [ // TODO: simplify if valueWithCorrectType has no side effects
22812291 this . module . createSetLocal ( tempLocal . index , valueWithCorrectType ) ,
2282- this . module . createStore ( ( < Field > element ) . type . byteSize , targetExpr , this . module . createGetLocal ( tempLocal . index , elementNativeType ) , elementNativeType , ( < Field > element ) . memoryOffset ) ,
2292+ this . module . createStore ( ( < Field > element ) . type . size >> 3 , targetExpr , this . module . createGetLocal ( tempLocal . index , elementNativeType ) , elementNativeType , ( < Field > element ) . memoryOffset ) ,
22832293 this . module . createGetLocal ( tempLocal . index , elementNativeType )
22842294 ] , elementNativeType ) ;
22852295
@@ -2325,6 +2335,38 @@ export class Compiler extends DiagnosticEmitter {
23252335 } else
23262336 this . error ( DiagnosticCode . Cannot_assign_to_0_because_it_is_a_constant_or_a_read_only_property , expression . range , ( < Property > element ) . internalName ) ;
23272337 return this . module . createUnreachable ( ) ;
2338+
2339+ case ElementKind . FUNCTION_PROTOTYPE :
2340+ if ( expression . kind == NodeKind . ELEMENTACCESS ) { // @operator ("[]")
2341+ assert ( resolved . target && resolved . target . kind == ElementKind . CLASS ) ;
2342+ var resolvedIndexedGet = ( < FunctionPrototype > element ) . resolve ( ) ;
2343+ if ( ! resolvedIndexedGet )
2344+ return this . module . createUnreachable ( ) ;
2345+ var indexedSetName = ( < Class > resolved . target ) . prototype . fnIndexedSet ;
2346+ var indexedSet : Element | null ;
2347+ if ( indexedSetName != null && ( < Class > resolved . target ) . members && ( indexedSet = ( < Map < string , Element > > ( < Class > resolved . target ) . members ) . get ( indexedSetName ) ) && indexedSet . kind == ElementKind . FUNCTION_PROTOTYPE ) { // @operator ("[]=")
2348+ var resolvedIndexedSet = ( < FunctionPrototype > indexedSet ) . resolve ( ) ;
2349+ if ( ! resolvedIndexedSet )
2350+ return this . module . createUnreachable ( ) ;
2351+ targetExpr = this . compileExpression ( < Expression > resolved . targetExpression , this . options . target == Target . WASM64 ? Type . usize64 : Type . usize32 , ConversionKind . NONE ) ;
2352+ assert ( this . currentType . classType ) ;
2353+ var elementExpr = this . compileExpression ( ( < ElementAccessExpression > expression ) . elementExpression , Type . i32 ) ;
2354+ if ( ! tee ) {
2355+ this . currentType = resolvedIndexedSet . returnType ;
2356+ return this . makeCall ( resolvedIndexedSet , [ targetExpr , elementExpr , valueWithCorrectType ] ) ;
2357+ }
2358+ this . currentType = resolvedIndexedGet . returnType ;
2359+ tempLocal = this . currentFunction . getAndFreeTempLocal ( this . currentType ) ;
2360+ return this . module . createBlock ( null , [
2361+ this . makeCall ( resolvedIndexedSet , [ targetExpr , elementExpr , this . module . createTeeLocal ( tempLocal . index , valueWithCorrectType ) ] ) ,
2362+ this . module . createGetLocal ( tempLocal . index , tempLocal . type . toNativeType ( ) ) // TODO: could be different from an actual __get (needs 2 temp locals)
2363+ ] , this . currentType . toNativeType ( ) ) ;
2364+ } else {
2365+ this . error ( DiagnosticCode . Index_signature_in_type_0_only_permits_reading , expression . range , ( < Class > resolved . target ) . internalName ) ;
2366+ return this . module . createUnreachable ( ) ;
2367+ }
2368+ }
2369+ // fall-through
23282370 }
23292371 this . error ( DiagnosticCode . Operation_not_supported , expression . range ) ;
23302372 return this . module . createUnreachable ( ) ;
@@ -2465,8 +2507,11 @@ export class Compiler extends DiagnosticEmitter {
24652507 var resolved = this . program . resolveElementAccess ( expression , this . currentFunction ) ; // reports
24662508 if ( ! resolved )
24672509 return this . module . createUnreachable ( ) ;
2468-
2469- throw new Error ( "not implemented" ) ; // TODO
2510+ assert ( resolved . element . kind == ElementKind . FUNCTION_PROTOTYPE && resolved . target && resolved . target . kind == ElementKind . CLASS ) ;
2511+ var instance = ( < FunctionPrototype > resolved . element ) . resolve ( null , ( < Class > resolved . target ) . contextualTypeArguments ) ;
2512+ if ( ! instance )
2513+ return this . module . createUnreachable ( ) ;
2514+ return this . compileCall ( instance , [ expression . expression , expression . elementExpression ] , expression ) ;
24702515 }
24712516
24722517 compileIdentifierExpression ( expression : IdentifierExpression , contextualType : Type ) : ExpressionRef {
@@ -2632,7 +2677,7 @@ export class Compiler extends DiagnosticEmitter {
26322677 assert ( ( < Field > element ) . memoryOffset >= 0 ) ;
26332678 targetExpr = this . compileExpression ( < Expression > resolved . targetExpression , this . options . target == Target . WASM64 ? Type . usize64 : Type . usize32 ) ;
26342679 this . currentType = ( < Field > element ) . type ;
2635- return this . module . createLoad ( ( < Field > element ) . type . byteSize , ( < Field > element ) . type . is ( TypeFlags . SIGNED | TypeFlags . INTEGER ) ,
2680+ return this . module . createLoad ( ( < Field > element ) . type . size >> 3 , ( < Field > element ) . type . is ( TypeFlags . SIGNED | TypeFlags . INTEGER ) ,
26362681 targetExpr ,
26372682 ( < Field > element ) . type . toNativeType ( ) ,
26382683 ( < Field > element ) . memoryOffset
0 commit comments