95 final String operator = CallSiteDescriptorFactory.tokenizeOperators(desc).get(0); |
95 final String operator = CallSiteDescriptorFactory.tokenizeOperators(desc).get(0); |
96 |
96 |
97 switch (operator) { |
97 switch (operator) { |
98 case "new": |
98 case "new": |
99 case "call": |
99 case "call": |
100 lookupTypeError("cant.call.undefined", desc); |
100 throw lookupTypeError("cant.call.undefined", desc); |
101 break; |
|
102 case "callMethod": |
101 case "callMethod": |
103 lookupTypeError("cant.read.property.of.undefined", desc); |
102 throw lookupTypeError("cant.read.property.of.undefined", desc); |
104 // NOTE: we support getElem and setItem as JavaScript doesn't distinguish items from properties. Nashorn itself |
103 // NOTE: we support getElem and setItem as JavaScript doesn't distinguish items from properties. Nashorn itself |
105 // emits "dyn:getProp:identifier" for "<expr>.<identifier>" and "dyn:getElem" for "<expr>[<expr>]", but we are |
104 // emits "dyn:getProp:identifier" for "<expr>.<identifier>" and "dyn:getElem" for "<expr>[<expr>]", but we are |
106 // more flexible here and dispatch not on operation name (getProp vs. getElem), but rather on whether the |
105 // more flexible here and dispatch not on operation name (getProp vs. getElem), but rather on whether the |
107 // operation has an associated name or not. |
106 // operation has an associated name or not. |
108 break; |
|
109 case "getProp": |
107 case "getProp": |
110 case "getElem": |
108 case "getElem": |
111 case "getMethod": |
109 case "getMethod": |
112 if (desc.getNameTokenCount() < 3) { |
110 if (desc.getNameTokenCount() < 3) { |
113 return findGetIndexMethod(desc); |
111 return findGetIndexMethod(desc); |
114 } |
112 } |
115 lookupTypeError("cant.read.property.of.undefined", desc); |
113 throw lookupTypeError("cant.read.property.of.undefined", desc); |
116 break; |
|
117 case "setProp": |
114 case "setProp": |
118 case "setElem": |
115 case "setElem": |
119 if (desc.getNameTokenCount() < 3) { |
116 if (desc.getNameTokenCount() < 3) { |
120 return findSetIndexMethod(desc); |
117 return findSetIndexMethod(desc); |
121 } |
118 } |
122 lookupTypeError("cant.set.property.of.undefined", desc); |
119 throw lookupTypeError("cant.set.property.of.undefined", desc); |
123 break; |
|
124 default: |
120 default: |
125 break; |
121 break; |
126 } |
122 } |
127 |
123 |
128 return null; |
124 return null; |
129 } |
125 } |
130 |
126 |
131 private static void lookupTypeError(final String msg, final CallSiteDescriptor desc) { |
127 private static ECMAException lookupTypeError(final String msg, final CallSiteDescriptor desc) { |
132 typeError(msg, desc.getNameTokenCount() > 2 ? desc.getNameToken(2) : null); |
128 return typeError(msg, desc.getNameTokenCount() > 2 ? desc.getNameToken(2) : null); |
133 } |
129 } |
134 |
130 |
135 /** |
131 /** |
136 * Find the appropriate GETINDEX method for an invoke dynamic call. |
132 * Find the appropriate GETINDEX method for an invoke dynamic call. |
137 * @param desc The invoke dynamic callsite descriptor |
133 * @param desc The invoke dynamic callsite descriptor |
172 return new GuardedInvocation(methodHandle, UNDEFINED_GUARD); |
168 return new GuardedInvocation(methodHandle, UNDEFINED_GUARD); |
173 } |
169 } |
174 |
170 |
175 @Override |
171 @Override |
176 public Object get(final Object key) { |
172 public Object get(final Object key) { |
177 typeError("cant.read.property.of.undefined", ScriptRuntime.safeToString(key)); |
173 throw typeError("cant.read.property.of.undefined", ScriptRuntime.safeToString(key)); |
178 return ScriptRuntime.UNDEFINED; |
|
179 } |
174 } |
180 |
175 |
181 @Override |
176 @Override |
182 public void set(final Object key, final Object value, final boolean strict) { |
177 public void set(final Object key, final Object value, final boolean strict) { |
183 typeError("cant.set.property.of.undefined", ScriptRuntime.safeToString(key)); |
178 throw typeError("cant.set.property.of.undefined", ScriptRuntime.safeToString(key)); |
184 } |
179 } |
185 |
180 |
186 @Override |
181 @Override |
187 public boolean delete(final Object key, final boolean strict) { |
182 public boolean delete(final Object key, final boolean strict) { |
188 typeError("cant.delete.property.of.undefined", ScriptRuntime.safeToString(key)); |
183 throw typeError("cant.delete.property.of.undefined", ScriptRuntime.safeToString(key)); |
189 return false; |
|
190 } |
184 } |
191 |
185 |
192 @Override |
186 @Override |
193 public boolean has(final Object key) { |
187 public boolean has(final Object key) { |
194 return false; |
188 return false; |