public override BoundValueType EmitGetMember(BoundGetMember node) { var constant = node.Index as BoundConstant; if (constant != null) { int index; FieldInfo cacheSlot; if (TryGetCacheSlot(node.Expression, constant, out index, out cacheSlot)) { // Load the reference to the box. IL.Emit(OpCodes.Ldloca, Local); // Load the runtime; GetProperty on this box needs it. Scope.EmitLoad(SpecialLocal.Runtime); // Load the index. IL.EmitConstant(index); // Load the cache slot. IL.Emit(OpCodes.Ldsflda, cacheSlot); // Load from the box by index. return IL.EmitCall(_getProperty); } } return base.EmitGetMember(node); }
public virtual BoundValueType EmitGetMember(BoundGetMember node) { var constant = node.Index as BoundConstant; if (constant != null && constant.ValueType == BoundValueType.String) { // Load the runtime. Scope.EmitLoad(SpecialLocal.Runtime); // Load the target to load from. Generator.EmitBox(Generator.EmitExpression(node.Expression)); // Load the index. IL.EmitConstant(Generator._identifierManager.ResolveIdentifier( (string)constant.Value )); // Get the member by index. return IL.EmitCall(_runtimeGetMemberByIndex); } return Generator.EmitOperationCall(Operation.Member, node.Expression, node.Index); }
public override BoundValueType EmitGetMember(BoundGetMember node) { if (node.Index.ValueType == BoundValueType.Number) { // Load a reference to the box. IL.Emit(OpCodes.Ldloca, Local); // Load the runtime; this GetProperty needs it. Scope.EmitLoad(SpecialLocal.Runtime); // Load the index. Generator.EmitExpression(node.Index); // Load from the box by index. return IL.EmitCall(_getProperty); } return base.EmitGetMember(node); }
public override BoundValueType EmitGetMember(BoundGetMember node) { var constant = node.Index as BoundConstant; if (constant != null) { int index; FieldInfo cacheSlot; if (TryGetCacheSlot(node.Expression, constant, out index, out cacheSlot)) { // Load the target to load from. Generator.EmitBox(Generator.EmitExpression(node.Expression)); // Load the index. IL.EmitConstant(index); // Load the cache slot. IL.Emit(OpCodes.Ldsflda, cacheSlot); // Load the value from the object. return IL.EmitCall(_objectGetPropertyCached); } if (constant.ValueType == BoundValueType.String) { // Load the target to load from. Generator.EmitBox(Generator.EmitExpression(node.Expression)); // Load the index. IL.EmitConstant(Generator._identifierManager.ResolveIdentifier( (string)constant.Value )); // Load the value from the object. return IL.EmitCall(_objectGetProperty); } } return Generator.EmitOperationCall(Operation.Member, node.Expression, node.Index); }
public virtual void VisitGetMember(BoundGetMember node) { DefaultVisit(node); }
public override void VisitGetMember(BoundGetMember node) { var getVariable = node.Expression as BoundGetVariable; if (getVariable != null) { var type = SpeculatedType.Unknown; bool definite = false; bool ignore = false; var constant = node.Index as BoundConstant; if (constant != null) { switch (constant.Value as string) { case "length": // Length applies equally to arrays and objects; // however, we do prefer array but it's not // definite yet. type = SpeculatedType.Array; break; case "join": case "pop": case "push": case "reverse": case "shift": case "unshift": case "slice": case "sort": case "splice": type = SpeculatedType.Array; definite = true; break; case "toFixed": case "toExponential": case "toPrecision": // Number functions. ignore = true; break; } } if (!ignore) { if (type == SpeculatedType.Unknown) { type = node.Index.ValueType == BoundValueType.Number ? SpeculatedType.Array : SpeculatedType.Object; } _scope.SpeculateType(getVariable.Variable, type, definite); } } base.VisitGetMember(node); }
private BoundValueType EmitGetMember(BoundGetMember node) { // Check whether we have an emitter for this statement. var emitter = GetEmitter(node.Expression); if (emitter != null) return emitter.EmitGetMember(node); // When the index is a constant string, we shortcut to // resolving the identifier here and inserting the ID of the // identifier instead of emitting the string. var constant = node.Index as BoundConstant; if (constant != null && constant.ValueType == BoundValueType.String) return EmitGetMember(node.Expression, _identifierManager.ResolveIdentifier((string)constant.Value)); return EmitGetMember(node.Expression, node.Index); }