Fri, 09 Aug 2013 20:48:44 +0530
8022707: Revisit all doPrivileged blocks
Reviewed-by: jlaskey, hannesw
1 /*
2 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
26 package jdk.nashorn.internal.objects;
28 import static jdk.nashorn.internal.lookup.Lookup.MH;
29 import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
30 import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
32 import java.io.IOException;
33 import java.io.PrintWriter;
34 import java.lang.invoke.MethodHandle;
35 import java.lang.invoke.MethodHandles;
36 import java.lang.ref.SoftReference;
37 import java.lang.reflect.Field;
38 import java.util.Arrays;
39 import java.util.LinkedHashMap;
40 import java.util.List;
41 import java.util.Map;
42 import java.util.concurrent.Callable;
43 import java.util.concurrent.ConcurrentHashMap;
44 import jdk.internal.dynalink.linker.GuardedInvocation;
45 import jdk.internal.dynalink.linker.LinkRequest;
46 import jdk.nashorn.internal.objects.annotations.Attribute;
47 import jdk.nashorn.internal.objects.annotations.Property;
48 import jdk.nashorn.internal.objects.annotations.ScriptClass;
49 import jdk.nashorn.internal.runtime.ConsString;
50 import jdk.nashorn.internal.runtime.Context;
51 import jdk.nashorn.internal.runtime.GlobalFunctions;
52 import jdk.nashorn.internal.runtime.GlobalObject;
53 import jdk.nashorn.internal.runtime.JSType;
54 import jdk.nashorn.internal.runtime.NativeJavaPackage;
55 import jdk.nashorn.internal.runtime.PropertyMap;
56 import jdk.nashorn.internal.runtime.ScriptEnvironment;
57 import jdk.nashorn.internal.runtime.PropertyDescriptor;
58 import jdk.nashorn.internal.runtime.arrays.ArrayData;
59 import jdk.nashorn.internal.runtime.regexp.RegExpResult;
60 import jdk.nashorn.internal.runtime.Scope;
61 import jdk.nashorn.internal.runtime.ScriptFunction;
62 import jdk.nashorn.internal.runtime.ScriptObject;
63 import jdk.nashorn.internal.runtime.ScriptRuntime;
64 import jdk.nashorn.internal.runtime.ScriptingFunctions;
65 import jdk.nashorn.internal.runtime.Source;
66 import jdk.nashorn.internal.runtime.linker.Bootstrap;
67 import jdk.nashorn.internal.runtime.linker.InvokeByName;
68 import jdk.nashorn.internal.scripts.JO;
70 /**
71 * Representation of global scope.
72 */
73 @ScriptClass("Global")
74 public final class Global extends ScriptObject implements GlobalObject, Scope {
75 private final InvokeByName TO_STRING = new InvokeByName("toString", ScriptObject.class);
76 private final InvokeByName VALUE_OF = new InvokeByName("valueOf", ScriptObject.class);
78 /** ECMA 15.1.2.2 parseInt (string , radix) */
79 @Property(attributes = Attribute.NOT_ENUMERABLE)
80 public Object parseInt;
82 /** ECMA 15.1.2.3 parseFloat (string) */
83 @Property(attributes = Attribute.NOT_ENUMERABLE)
84 public Object parseFloat;
86 /** ECMA 15.1.2.4 isNaN (number) */
87 @Property(attributes = Attribute.NOT_ENUMERABLE)
88 public Object isNaN;
90 /** ECMA 15.1.2.5 isFinite (number) */
91 @Property(attributes = Attribute.NOT_ENUMERABLE)
92 public Object isFinite;
94 /** ECMA 15.1.3.3 encodeURI */
95 @Property(attributes = Attribute.NOT_ENUMERABLE)
96 public Object encodeURI;
98 /** ECMA 15.1.3.4 encodeURIComponent */
99 @Property(attributes = Attribute.NOT_ENUMERABLE)
100 public Object encodeURIComponent;
102 /** ECMA 15.1.3.1 decodeURI */
103 @Property(attributes = Attribute.NOT_ENUMERABLE)
104 public Object decodeURI;
106 /** ECMA 15.1.3.2 decodeURIComponent */
107 @Property(attributes = Attribute.NOT_ENUMERABLE)
108 public Object decodeURIComponent;
110 /** ECMA B.2.1 escape (string) */
111 @Property(attributes = Attribute.NOT_ENUMERABLE)
112 public Object escape;
114 /** ECMA B.2.2 unescape (string) */
115 @Property(attributes = Attribute.NOT_ENUMERABLE)
116 public Object unescape;
118 /** Nashorn extension: global.print */
119 @Property(attributes = Attribute.NOT_ENUMERABLE)
120 public Object print;
122 /** Nashorn extension: global.load */
123 @Property(attributes = Attribute.NOT_ENUMERABLE)
124 public Object load;
126 /** Nashorn extension: global.loadWithNewGlobal */
127 @Property(attributes = Attribute.NOT_ENUMERABLE)
128 public Object loadWithNewGlobal;
130 /** Nashorn extension: global.exit */
131 @Property(attributes = Attribute.NOT_ENUMERABLE)
132 public Object exit;
134 /** Nashorn extension: global.quit */
135 @Property(attributes = Attribute.NOT_ENUMERABLE)
136 public Object quit;
138 /** Value property NaN of the Global Object - ECMA 15.1.1.1 NaN */
139 @Property(attributes = Attribute.NON_ENUMERABLE_CONSTANT)
140 public final Object NaN = Double.NaN;
142 /** Value property Infinity of the Global Object - ECMA 15.1.1.2 Infinity */
143 @Property(attributes = Attribute.NON_ENUMERABLE_CONSTANT)
144 public final Object Infinity = Double.POSITIVE_INFINITY;
146 /** Value property Undefined of the Global Object - ECMA 15.1.1.3 Undefined */
147 @Property(attributes = Attribute.NON_ENUMERABLE_CONSTANT)
148 public final Object undefined = UNDEFINED;
150 /** ECMA 15.1.2.1 eval(x) */
151 @Property(attributes = Attribute.NOT_ENUMERABLE)
152 public Object eval;
154 /** ECMA 15.1.4.1 Object constructor. */
155 @Property(name = "Object", attributes = Attribute.NOT_ENUMERABLE)
156 public volatile Object object;
158 /** ECMA 15.1.4.2 Function constructor. */
159 @Property(name = "Function", attributes = Attribute.NOT_ENUMERABLE)
160 public volatile Object function;
162 /** ECMA 15.1.4.3 Array constructor. */
163 @Property(name = "Array", attributes = Attribute.NOT_ENUMERABLE)
164 public volatile Object array;
166 /** ECMA 15.1.4.4 String constructor */
167 @Property(name = "String", attributes = Attribute.NOT_ENUMERABLE)
168 public volatile Object string;
170 /** ECMA 15.1.4.5 Boolean constructor */
171 @Property(name = "Boolean", attributes = Attribute.NOT_ENUMERABLE)
172 public volatile Object _boolean;
174 /** ECMA 15.1.4.6 - Number constructor */
175 @Property(name = "Number", attributes = Attribute.NOT_ENUMERABLE)
176 public volatile Object number;
178 /** ECMA 15.1.4.7 Date constructor */
179 @Property(name = "Date", attributes = Attribute.NOT_ENUMERABLE)
180 public volatile Object date;
182 /** ECMA 15.1.4.8 RegExp constructor */
183 @Property(name = "RegExp", attributes = Attribute.NOT_ENUMERABLE)
184 public volatile Object regexp;
186 /** ECMA 15.12 - The JSON object */
187 @Property(name = "JSON", attributes = Attribute.NOT_ENUMERABLE)
188 public volatile Object json;
190 /** Nashorn extension: global.JSAdapter */
191 @Property(name = "JSAdapter", attributes = Attribute.NOT_ENUMERABLE)
192 public volatile Object jsadapter;
194 /** ECMA 15.8 - The Math object */
195 @Property(name = "Math", attributes = Attribute.NOT_ENUMERABLE)
196 public volatile Object math;
198 /** Error object */
199 @Property(name = "Error", attributes = Attribute.NOT_ENUMERABLE)
200 public volatile Object error;
202 /** EvalError object */
203 @Property(name = "EvalError", attributes = Attribute.NOT_ENUMERABLE)
204 public volatile Object evalError;
206 /** RangeError object */
207 @Property(name = "RangeError", attributes = Attribute.NOT_ENUMERABLE)
208 public volatile Object rangeError;
210 /** ReferenceError object */
211 @Property(name = "ReferenceError", attributes = Attribute.NOT_ENUMERABLE)
212 public volatile Object referenceError;
214 /** SyntaxError object */
215 @Property(name = "SyntaxError", attributes = Attribute.NOT_ENUMERABLE)
216 public volatile Object syntaxError;
218 /** TypeError object */
219 @Property(name = "TypeError", attributes = Attribute.NOT_ENUMERABLE)
220 public volatile Object typeError;
222 /** URIError object */
223 @Property(name = "URIError", attributes = Attribute.NOT_ENUMERABLE)
224 public volatile Object uriError;
226 /** ArrayBuffer object */
227 @Property(name = "ArrayBuffer", attributes = Attribute.NOT_ENUMERABLE)
228 public volatile Object arrayBuffer;
230 /** TypedArray (int8) */
231 @Property(name = "Int8Array", attributes = Attribute.NOT_ENUMERABLE)
232 public volatile Object int8Array;
234 /** TypedArray (uint8) */
235 @Property(name = "Uint8Array", attributes = Attribute.NOT_ENUMERABLE)
236 public volatile Object uint8Array;
238 /** TypedArray (uint8) - Clamped */
239 @Property(name = "Uint8ClampedArray", attributes = Attribute.NOT_ENUMERABLE)
240 public volatile Object uint8ClampedArray;
242 /** TypedArray (int16) */
243 @Property(name = "Int16Array", attributes = Attribute.NOT_ENUMERABLE)
244 public volatile Object int16Array;
246 /** TypedArray (uint16) */
247 @Property(name = "Uint16Array", attributes = Attribute.NOT_ENUMERABLE)
248 public volatile Object uint16Array;
250 /** TypedArray (int32) */
251 @Property(name = "Int32Array", attributes = Attribute.NOT_ENUMERABLE)
252 public volatile Object int32Array;
254 /** TypedArray (uint32) */
255 @Property(name = "Uint32Array", attributes = Attribute.NOT_ENUMERABLE)
256 public volatile Object uint32Array;
258 /** TypedArray (float32) */
259 @Property(name = "Float32Array", attributes = Attribute.NOT_ENUMERABLE)
260 public volatile Object float32Array;
262 /** TypedArray (float64) */
263 @Property(name = "Float64Array", attributes = Attribute.NOT_ENUMERABLE)
264 public volatile Object float64Array;
266 /** Nashorn extension: Java access - global.Packages */
267 @Property(name = "Packages", attributes = Attribute.NOT_ENUMERABLE)
268 public volatile Object packages;
270 /** Nashorn extension: Java access - global.com */
271 @Property(attributes = Attribute.NOT_ENUMERABLE)
272 public volatile Object com;
274 /** Nashorn extension: Java access - global.edu */
275 @Property(attributes = Attribute.NOT_ENUMERABLE)
276 public volatile Object edu;
278 /** Nashorn extension: Java access - global.java */
279 @Property(attributes = Attribute.NOT_ENUMERABLE)
280 public volatile Object java;
282 /** Nashorn extension: Java access - global.javafx */
283 @Property(attributes = Attribute.NOT_ENUMERABLE)
284 public volatile Object javafx;
286 /** Nashorn extension: Java access - global.javax */
287 @Property(attributes = Attribute.NOT_ENUMERABLE)
288 public volatile Object javax;
290 /** Nashorn extension: Java access - global.org */
291 @Property(attributes = Attribute.NOT_ENUMERABLE)
292 public volatile Object org;
294 /** Nashorn extension: Java access - global.javaImporter */
295 @Property(name = "JavaImporter", attributes = Attribute.NOT_ENUMERABLE)
296 public volatile Object javaImporter;
298 /** Nashorn extension: global.Java Object constructor. */
299 @Property(name = "Java", attributes = Attribute.NOT_ENUMERABLE)
300 public volatile Object javaApi;
302 /** Nashorn extension: current script's file name */
303 @Property(name = "__FILE__", attributes = Attribute.NON_ENUMERABLE_CONSTANT)
304 public Object __FILE__;
306 /** Nashorn extension: current script's directory */
307 @Property(name = "__DIR__", attributes = Attribute.NON_ENUMERABLE_CONSTANT)
308 public Object __DIR__;
310 /** Nashorn extension: current source line number being executed */
311 @Property(name = "__LINE__", attributes = Attribute.NON_ENUMERABLE_CONSTANT)
312 public Object __LINE__;
314 /** Used as Date.prototype's default value */
315 public NativeDate DEFAULT_DATE;
317 /** Used as RegExp.prototype's default value */
318 public NativeRegExp DEFAULT_REGEXP;
320 /*
321 * Built-in constructor objects: Even if user changes dynamic values of
322 * "Object", "Array" etc., we still want to keep original values of these
323 * constructors here. For example, we need to be able to create array,
324 * regexp literals even after user overwrites global "Array" or "RegExp"
325 * constructor - see also ECMA 262 spec. Annex D.
326 */
327 private ScriptFunction builtinFunction;
328 private ScriptFunction builtinObject;
329 private ScriptFunction builtinArray;
330 private ScriptFunction builtinBoolean;
331 private ScriptFunction builtinDate;
332 private ScriptObject builtinJSON;
333 private ScriptFunction builtinJSAdapter;
334 private ScriptObject builtinMath;
335 private ScriptFunction builtinNumber;
336 private ScriptFunction builtinRegExp;
337 private ScriptFunction builtinString;
338 private ScriptFunction builtinError;
339 private ScriptFunction builtinEval;
340 private ScriptFunction builtinEvalError;
341 private ScriptFunction builtinRangeError;
342 private ScriptFunction builtinReferenceError;
343 private ScriptFunction builtinSyntaxError;
344 private ScriptFunction builtinTypeError;
345 private ScriptFunction builtinURIError;
346 private ScriptObject builtinPackages;
347 private ScriptObject builtinCom;
348 private ScriptObject builtinEdu;
349 private ScriptObject builtinJava;
350 private ScriptObject builtinJavafx;
351 private ScriptObject builtinJavax;
352 private ScriptObject builtinOrg;
353 private ScriptObject builtinJavaImporter;
354 private ScriptObject builtinJavaApi;
355 private ScriptObject builtinArrayBuffer;
356 private ScriptObject builtinInt8Array;
357 private ScriptObject builtinUint8Array;
358 private ScriptObject builtinUint8ClampedArray;
359 private ScriptObject builtinInt16Array;
360 private ScriptObject builtinUint16Array;
361 private ScriptObject builtinInt32Array;
362 private ScriptObject builtinUint32Array;
363 private ScriptObject builtinFloat32Array;
364 private ScriptObject builtinFloat64Array;
366 private PropertyMap accessorPropertyDescriptorMap;
367 private PropertyMap arrayBufferViewMap;
368 private PropertyMap dataPropertyDescriptorMap;
369 private PropertyMap genericPropertyDescriptorMap;
370 private PropertyMap nativeArgumentsMap;
371 private PropertyMap nativeArrayMap;
372 private PropertyMap nativeArrayBufferMap;
373 private PropertyMap nativeBooleanMap;
374 private PropertyMap nativeDateMap;
375 private PropertyMap nativeErrorMap;
376 private PropertyMap nativeEvalErrorMap;
377 private PropertyMap nativeJSAdapterMap;
378 private PropertyMap nativeJavaImporterMap;
379 private PropertyMap nativeNumberMap;
380 private PropertyMap nativeRangeErrorMap;
381 private PropertyMap nativeReferenceErrorMap;
382 private PropertyMap nativeRegExpMap;
383 private PropertyMap nativeRegExpExecResultMap;
384 private PropertyMap nativeStrictArgumentsMap;
385 private PropertyMap nativeStringMap;
386 private PropertyMap nativeSyntaxErrorMap;
387 private PropertyMap nativeTypeErrorMap;
388 private PropertyMap nativeURIErrorMap;
389 private PropertyMap prototypeObjectMap;
390 private PropertyMap objectMap;
391 private PropertyMap functionMap;
392 private PropertyMap anonymousFunctionMap;
393 private PropertyMap strictFunctionMap;
394 private PropertyMap boundFunctionMap;
396 // Flag to indicate that a split method issued a return statement
397 private int splitState = -1;
399 // class cache
400 private ClassCache classCache;
402 // Used to store the last RegExp result to support deprecated RegExp constructor properties
403 private RegExpResult lastRegExpResult;
405 private static final MethodHandle EVAL = findOwnMH("eval", Object.class, Object.class, Object.class);
406 private static final MethodHandle PRINT = findOwnMH("print", Object.class, Object.class, Object[].class);
407 private static final MethodHandle PRINTLN = findOwnMH("println", Object.class, Object.class, Object[].class);
408 private static final MethodHandle LOAD = findOwnMH("load", Object.class, Object.class, Object.class);
409 private static final MethodHandle LOADWITHNEWGLOBAL = findOwnMH("loadWithNewGlobal", Object.class, Object.class, Object[].class);
410 private static final MethodHandle EXIT = findOwnMH("exit", Object.class, Object.class, Object.class);
412 // initialized by nasgen
413 private static PropertyMap $nasgenmap$;
415 // performs initialization checks for Global constructor and returns the
416 // PropertyMap, if everything is fine.
417 private static PropertyMap checkAndGetMap(final Context context) {
418 // security check first
419 final SecurityManager sm = System.getSecurityManager();
420 if (sm != null) {
421 sm.checkPermission(new RuntimePermission(Context.NASHORN_CREATE_GLOBAL));
422 }
424 // null check on context
425 context.getClass();
427 /*
428 * Duplicate global's map and use it. This way the initial Map filled
429 * by nasgen (referenced from static field in this class) is retained
430 * 'as is' (as that one is process wide singleton.
431 */
432 return $nasgenmap$.duplicate();
433 }
435 /**
436 * Constructor
437 *
438 * @param context the context
439 */
440 public Global(final Context context) {
441 super(checkAndGetMap(context));
442 this.setContext(context);
443 this.setIsScope();
445 final int cacheSize = context.getEnv()._class_cache_size;
446 if (cacheSize > 0) {
447 classCache = new ClassCache(cacheSize);
448 }
449 }
451 /**
452 * Script access to "current" Global instance
453 *
454 * @return the global singleton
455 */
456 public static Global instance() {
457 ScriptObject global = Context.getGlobal();
458 if (! (global instanceof Global)) {
459 throw new IllegalStateException("no current global instance");
460 }
461 return (Global)global;
462 }
464 /**
465 * Script access to {@link ScriptEnvironment}
466 *
467 * @return the script environment
468 */
469 static ScriptEnvironment getEnv() {
470 return instance().getContext().getEnv();
471 }
473 /**
474 * Script access to {@link Context}
475 *
476 * @return the context
477 */
478 static Context getThisContext() {
479 return instance().getContext();
480 }
482 // GlobalObject interface implementation
484 @Override
485 public void initBuiltinObjects() {
486 if (this.builtinObject != null) {
487 // already initialized, just return
488 return;
489 }
491 init();
492 }
494 @Override
495 public ScriptFunction newScriptFunction(final String name, final MethodHandle handle, final ScriptObject scope, final boolean strict) {
496 return new ScriptFunctionImpl(name, handle, scope, null, strict, false, true);
497 }
499 @Override
500 public Object wrapAsObject(final Object obj) {
501 if (obj instanceof Boolean) {
502 return new NativeBoolean((Boolean)obj, this);
503 } else if (obj instanceof Number) {
504 return new NativeNumber(((Number)obj).doubleValue(), this);
505 } else if (obj instanceof String || obj instanceof ConsString) {
506 return new NativeString((CharSequence)obj, this);
507 } else if (obj instanceof Object[]) { // extension
508 return new NativeArray((Object[])obj);
509 } else if (obj instanceof double[]) { // extension
510 return new NativeArray((double[])obj);
511 } else if (obj instanceof long[]) {
512 return new NativeArray((long[])obj);
513 } else if (obj instanceof int[]) {
514 return new NativeArray((int[])obj);
515 } else {
516 // FIXME: more special cases? Map? List?
517 return obj;
518 }
519 }
521 @Override
522 public GuardedInvocation primitiveLookup(final LinkRequest request, final Object self) {
523 if (self instanceof String || self instanceof ConsString) {
524 return NativeString.lookupPrimitive(request, self);
525 } else if (self instanceof Number) {
526 return NativeNumber.lookupPrimitive(request, self);
527 } else if (self instanceof Boolean) {
528 return NativeBoolean.lookupPrimitive(request, self);
529 }
530 throw new IllegalArgumentException("Unsupported primitive: " + self);
531 }
533 @Override
534 public ScriptObject newObject() {
535 return new JO(getObjectPrototype(), getObjectMap());
536 }
538 @Override
539 public Object getDefaultValue(final ScriptObject sobj, final Class<?> typeHint) {
540 // When the [[DefaultValue]] internal method of O is called with no hint,
541 // then it behaves as if the hint were Number, unless O is a Date object
542 // in which case it behaves as if the hint were String.
543 Class<?> hint = typeHint;
544 if (hint == null) {
545 hint = Number.class;
546 }
548 try {
549 if (hint == String.class) {
551 final Object toString = TO_STRING.getGetter().invokeExact(sobj);
553 if (Bootstrap.isCallable(toString)) {
554 final Object value = TO_STRING.getInvoker().invokeExact(toString, sobj);
555 if (JSType.isPrimitive(value)) {
556 return value;
557 }
558 }
560 final Object valueOf = VALUE_OF.getGetter().invokeExact(sobj);
561 if (Bootstrap.isCallable(valueOf)) {
562 final Object value = VALUE_OF.getInvoker().invokeExact(valueOf, sobj);
563 if (JSType.isPrimitive(value)) {
564 return value;
565 }
566 }
567 throw typeError(this, "cannot.get.default.string");
568 }
570 if (hint == Number.class) {
571 final Object valueOf = VALUE_OF.getGetter().invokeExact(sobj);
572 if (Bootstrap.isCallable(valueOf)) {
573 final Object value = VALUE_OF.getInvoker().invokeExact(valueOf, sobj);
574 if (JSType.isPrimitive(value)) {
575 return value;
576 }
577 }
579 final Object toString = TO_STRING.getGetter().invokeExact(sobj);
580 if (Bootstrap.isCallable(toString)) {
581 final Object value = TO_STRING.getInvoker().invokeExact(toString, sobj);
582 if (JSType.isPrimitive(value)) {
583 return value;
584 }
585 }
587 throw typeError(this, "cannot.get.default.number");
588 }
589 } catch (final RuntimeException | Error e) {
590 throw e;
591 } catch (final Throwable t) {
592 throw new RuntimeException(t);
593 }
595 return UNDEFINED;
596 }
598 @Override
599 public boolean isError(final ScriptObject sobj) {
600 final ScriptObject errorProto = getErrorPrototype();
601 ScriptObject proto = sobj.getProto();
602 while (proto != null) {
603 if (proto == errorProto) {
604 return true;
605 }
606 proto = proto.getProto();
607 }
608 return false;
609 }
611 @Override
612 public ScriptObject newError(final String msg) {
613 return new NativeError(msg, this);
614 }
616 @Override
617 public ScriptObject newEvalError(final String msg) {
618 return new NativeEvalError(msg, this);
619 }
621 @Override
622 public ScriptObject newRangeError(final String msg) {
623 return new NativeRangeError(msg, this);
624 }
626 @Override
627 public ScriptObject newReferenceError(final String msg) {
628 return new NativeReferenceError(msg, this);
629 }
631 @Override
632 public ScriptObject newSyntaxError(final String msg) {
633 return new NativeSyntaxError(msg, this);
634 }
636 @Override
637 public ScriptObject newTypeError(final String msg) {
638 return new NativeTypeError(msg, this);
639 }
641 @Override
642 public ScriptObject newURIError(final String msg) {
643 return new NativeURIError(msg, this);
644 }
646 @Override
647 public PropertyDescriptor newGenericDescriptor(final boolean configurable, final boolean enumerable) {
648 return new GenericPropertyDescriptor(configurable, enumerable, this);
649 }
651 @Override
652 public PropertyDescriptor newDataDescriptor(final Object value, final boolean configurable, final boolean enumerable, final boolean writable) {
653 return new DataPropertyDescriptor(configurable, enumerable, writable, value, this);
654 }
656 @Override
657 public PropertyDescriptor newAccessorDescriptor(final Object get, final Object set, final boolean configurable, final boolean enumerable) {
658 final AccessorPropertyDescriptor desc = new AccessorPropertyDescriptor(configurable, enumerable, get == null ? UNDEFINED : get, set == null ? UNDEFINED : set, this);
660 if (get == null) {
661 desc.delete(PropertyDescriptor.GET, false);
662 }
664 if (set == null) {
665 desc.delete(PropertyDescriptor.SET, false);
666 }
668 return desc;
669 }
672 /**
673 * Cache for compiled script classes.
674 */
675 @SuppressWarnings("serial")
676 private static class ClassCache extends LinkedHashMap<Source, SoftReference<Class<?>>> {
677 private final int size;
679 ClassCache(int size) {
680 super(size, 0.75f, true);
681 this.size = size;
682 }
684 @Override
685 protected boolean removeEldestEntry(final Map.Entry<Source, SoftReference<Class<?>>> eldest) {
686 return size() >= size;
687 }
688 }
690 // Class cache management
691 @Override
692 public Class<?> findCachedClass(final Source source) {
693 assert classCache != null : "Class cache used without being initialized";
694 SoftReference<Class<?>> ref = classCache.get(source);
695 if (ref != null) {
696 final Class<?> clazz = ref.get();
697 if (clazz == null) {
698 classCache.remove(source);
699 }
700 return clazz;
701 }
703 return null;
704 }
706 @Override
707 public void cacheClass(final Source source, final Class<?> clazz) {
708 assert classCache != null : "Class cache used without being initialized";
709 classCache.put(source, new SoftReference<Class<?>>(clazz));
710 }
712 private static <T> T getLazilyCreatedValue(final Object key, final Callable<T> creator, final Map<Object, T> map) {
713 final T obj = map.get(key);
714 if (obj != null) {
715 return obj;
716 }
718 try {
719 final T newObj = creator.call();
720 final T existingObj = map.putIfAbsent(key, newObj);
721 return existingObj != null ? existingObj : newObj;
722 } catch (final Exception exp) {
723 throw new RuntimeException(exp);
724 }
725 }
727 private final Map<Object, InvokeByName> namedInvokers = new ConcurrentHashMap<>();
729 @Override
730 public InvokeByName getInvokeByName(final Object key, final Callable<InvokeByName> creator) {
731 return getLazilyCreatedValue(key, creator, namedInvokers);
732 }
734 private final Map<Object, MethodHandle> dynamicInvokers = new ConcurrentHashMap<>();
736 @Override
737 public MethodHandle getDynamicInvoker(final Object key, final Callable<MethodHandle> creator) {
738 return getLazilyCreatedValue(key, creator, dynamicInvokers);
739 }
741 /**
742 * This is the eval used when 'indirect' eval call is made.
743 *
744 * var global = this;
745 * global.eval("print('hello')");
746 *
747 * @param self eval scope
748 * @param str eval string
749 *
750 * @return the result of eval
751 */
752 public static Object eval(final Object self, final Object str) {
753 return directEval(self, str, UNDEFINED, UNDEFINED, UNDEFINED);
754 }
756 /**
757 * Direct eval
758 *
759 * @param self The scope of eval passed as 'self'
760 * @param str Evaluated code
761 * @param callThis "this" to be passed to the evaluated code
762 * @param location location of the eval call
763 * @param strict is eval called a strict mode code?
764 *
765 * @return the return value of the eval
766 *
767 * This is directly invoked from generated when eval(code) is called in user code
768 */
769 public static Object directEval(final Object self, final Object str, final Object callThis, final Object location, final Object strict) {
770 if (!(str instanceof String || str instanceof ConsString)) {
771 return str;
772 }
773 final Global global = Global.instance();
774 final ScriptObject scope = (self instanceof ScriptObject) ? (ScriptObject)self : global;
776 return global.getContext().eval(scope, str.toString(), callThis, location, Boolean.TRUE.equals(strict));
777 }
779 /**
780 * Global print implementation - Nashorn extension
781 *
782 * @param self scope
783 * @param objects arguments to print
784 *
785 * @return result of print (undefined)
786 */
787 public static Object print(final Object self, final Object... objects) {
788 return printImpl(false, objects);
789 }
791 /**
792 * Global println implementation - Nashorn extension
793 *
794 * @param self scope
795 * @param objects arguments to print
796 *
797 * @return result of println (undefined)
798 */
799 public static Object println(final Object self, final Object... objects) {
800 return printImpl(true, objects);
801 }
803 /**
804 * Global load implementation - Nashorn extension
805 *
806 * @param self scope
807 * @param source source to load
808 *
809 * @return result of load (undefined)
810 *
811 * @throws IOException if source could not be read
812 */
813 public static Object load(final Object self, final Object source) throws IOException {
814 final Global global = Global.instance();
815 final ScriptObject scope = (self instanceof ScriptObject) ? (ScriptObject)self : global;
816 return global.getContext().load(scope, source);
817 }
819 /**
820 * Global loadWithNewGlobal implementation - Nashorn extension
821 *
822 * @param self scope
823 * @param args from plus (optional) arguments to be passed to the loaded script
824 *
825 * @return result of load (may be undefined)
826 *
827 * @throws IOException if source could not be read
828 */
829 public static Object loadWithNewGlobal(final Object self, final Object...args) throws IOException {
830 final Global global = Global.instance();
831 final int length = args.length;
832 final boolean hasArgs = 0 < length;
833 final Object from = hasArgs ? args[0] : UNDEFINED;
834 final Object[] arguments = hasArgs ? Arrays.copyOfRange(args, 1, length) : args;
836 return global.getContext().loadWithNewGlobal(from, arguments);
837 }
839 /**
840 * Global exit and quit implementation - Nashorn extension: perform a {@code System.exit} call from the script
841 *
842 * @param self self reference
843 * @param code exit code
844 *
845 * @return undefined (will never be reacheD)
846 */
847 public static Object exit(final Object self, final Object code) {
848 System.exit(JSType.toInt32(code));
849 return UNDEFINED;
850 }
852 // builtin prototype accessors
853 ScriptObject getFunctionPrototype() {
854 return ScriptFunction.getPrototype(builtinFunction);
855 }
857 ScriptObject getObjectPrototype() {
858 return ScriptFunction.getPrototype(builtinObject);
859 }
861 ScriptObject getArrayPrototype() {
862 return ScriptFunction.getPrototype(builtinArray);
863 }
865 ScriptObject getBooleanPrototype() {
866 return ScriptFunction.getPrototype(builtinBoolean);
867 }
869 ScriptObject getNumberPrototype() {
870 return ScriptFunction.getPrototype(builtinNumber);
871 }
873 ScriptObject getDatePrototype() {
874 return ScriptFunction.getPrototype(builtinDate);
875 }
877 ScriptObject getRegExpPrototype() {
878 return ScriptFunction.getPrototype(builtinRegExp);
879 }
881 ScriptObject getStringPrototype() {
882 return ScriptFunction.getPrototype(builtinString);
883 }
885 ScriptObject getErrorPrototype() {
886 return ScriptFunction.getPrototype(builtinError);
887 }
889 ScriptObject getEvalErrorPrototype() {
890 return ScriptFunction.getPrototype(builtinEvalError);
891 }
893 ScriptObject getRangeErrorPrototype() {
894 return ScriptFunction.getPrototype(builtinRangeError);
895 }
897 ScriptObject getReferenceErrorPrototype() {
898 return ScriptFunction.getPrototype(builtinReferenceError);
899 }
901 ScriptObject getSyntaxErrorPrototype() {
902 return ScriptFunction.getPrototype(builtinSyntaxError);
903 }
905 ScriptObject getTypeErrorPrototype() {
906 return ScriptFunction.getPrototype(builtinTypeError);
907 }
909 ScriptObject getURIErrorPrototype() {
910 return ScriptFunction.getPrototype(builtinURIError);
911 }
913 ScriptObject getJavaImporterPrototype() {
914 return ScriptFunction.getPrototype(builtinJavaImporter);
915 }
917 ScriptObject getJSAdapterPrototype() {
918 return ScriptFunction.getPrototype(builtinJSAdapter);
919 }
921 ScriptObject getArrayBufferPrototype() {
922 return ScriptFunction.getPrototype(builtinArrayBuffer);
923 }
925 ScriptObject getInt8ArrayPrototype() {
926 return ScriptFunction.getPrototype(builtinInt8Array);
927 }
929 ScriptObject getUint8ArrayPrototype() {
930 return ScriptFunction.getPrototype(builtinUint8Array);
931 }
933 ScriptObject getUint8ClampedArrayPrototype() {
934 return ScriptFunction.getPrototype(builtinUint8ClampedArray);
935 }
937 ScriptObject getInt16ArrayPrototype() {
938 return ScriptFunction.getPrototype(builtinInt16Array);
939 }
941 ScriptObject getUint16ArrayPrototype() {
942 return ScriptFunction.getPrototype(builtinUint16Array);
943 }
945 ScriptObject getInt32ArrayPrototype() {
946 return ScriptFunction.getPrototype(builtinInt32Array);
947 }
949 ScriptObject getUint32ArrayPrototype() {
950 return ScriptFunction.getPrototype(builtinUint32Array);
951 }
953 ScriptObject getFloat32ArrayPrototype() {
954 return ScriptFunction.getPrototype(builtinFloat32Array);
955 }
957 ScriptObject getFloat64ArrayPrototype() {
958 return ScriptFunction.getPrototype(builtinFloat64Array);
959 }
961 // Builtin PropertyMap accessors
962 PropertyMap getAccessorPropertyDescriptorMap() {
963 return accessorPropertyDescriptorMap;
964 }
966 PropertyMap getArrayBufferViewMap() {
967 return arrayBufferViewMap;
968 }
970 PropertyMap getDataPropertyDescriptorMap() {
971 return dataPropertyDescriptorMap;
972 }
974 PropertyMap getGenericPropertyDescriptorMap() {
975 return genericPropertyDescriptorMap;
976 }
978 PropertyMap getArgumentsMap() {
979 return nativeArgumentsMap;
980 }
982 PropertyMap getArrayMap() {
983 return nativeArrayMap;
984 }
986 PropertyMap getArrayBufferMap() {
987 return nativeArrayBufferMap;
988 }
990 PropertyMap getBooleanMap() {
991 return nativeBooleanMap;
992 }
994 PropertyMap getDateMap() {
995 return nativeDateMap;
996 }
998 PropertyMap getErrorMap() {
999 return nativeErrorMap;
1000 }
1002 PropertyMap getEvalErrorMap() {
1003 return nativeEvalErrorMap;
1004 }
1006 PropertyMap getJSAdapterMap() {
1007 return nativeJSAdapterMap;
1008 }
1010 PropertyMap getJavaImporterMap() {
1011 return nativeJavaImporterMap;
1012 }
1014 PropertyMap getNumberMap() {
1015 return nativeNumberMap;
1016 }
1018 PropertyMap getRangeErrorMap() {
1019 return nativeRangeErrorMap;
1020 }
1022 PropertyMap getReferenceErrorMap() {
1023 return nativeReferenceErrorMap;
1024 }
1026 PropertyMap getRegExpMap() {
1027 return nativeRegExpMap;
1028 }
1030 PropertyMap getRegExpExecResultMap() {
1031 return nativeRegExpExecResultMap;
1032 }
1034 PropertyMap getStrictArgumentsMap() {
1035 return nativeStrictArgumentsMap;
1036 }
1038 PropertyMap getStringMap() {
1039 return nativeStringMap;
1040 }
1042 PropertyMap getSyntaxErrorMap() {
1043 return nativeSyntaxErrorMap;
1044 }
1046 PropertyMap getTypeErrorMap() {
1047 return nativeTypeErrorMap;
1048 }
1050 PropertyMap getURIErrorMap() {
1051 return nativeURIErrorMap;
1052 }
1054 PropertyMap getPrototypeObjectMap() {
1055 return prototypeObjectMap;
1056 }
1058 PropertyMap getObjectMap() {
1059 return objectMap;
1060 }
1062 PropertyMap getFunctionMap() {
1063 return functionMap;
1064 }
1066 PropertyMap getAnonymousFunctionMap() {
1067 return anonymousFunctionMap;
1068 }
1070 PropertyMap getStrictFunctionMap() {
1071 return strictFunctionMap;
1072 }
1074 PropertyMap getBoundFunctionMap() {
1075 return boundFunctionMap;
1076 }
1078 private ScriptFunction getBuiltinArray() {
1079 return builtinArray;
1080 }
1082 /**
1083 * Called from compiled script code to test if builtin has been overridden
1084 *
1085 * @return true if builtin array has not been overridden
1086 */
1087 public static boolean isBuiltinArray() {
1088 final Global instance = Global.instance();
1089 return instance.array == instance.getBuiltinArray();
1090 }
1092 private ScriptFunction getBuiltinBoolean() {
1093 return builtinBoolean;
1094 }
1096 /**
1097 * Called from compiled script code to test if builtin has been overridden
1098 *
1099 * @return true if builtin boolean has not been overridden
1100 */
1101 public static boolean isBuiltinBoolean() {
1102 final Global instance = Global.instance();
1103 return instance._boolean == instance.getBuiltinBoolean();
1104 }
1106 private ScriptFunction getBuiltinDate() {
1107 return builtinDate;
1108 }
1110 /**
1111 * Called from compiled script code to test if builtin has been overridden
1112 *
1113 * @return true if builtin date has not been overridden
1114 */
1115 public static boolean isBuiltinDate() {
1116 final Global instance = Global.instance();
1117 return instance.date == instance.getBuiltinDate();
1118 }
1120 private ScriptFunction getBuiltinError() {
1121 return builtinError;
1122 }
1124 /**
1125 * Called from compiled script code to test if builtin has been overridden
1126 *
1127 * @return true if builtin error has not been overridden
1128 */
1129 public static boolean isBuiltinError() {
1130 final Global instance = Global.instance();
1131 return instance.error == instance.getBuiltinError();
1132 }
1134 private ScriptFunction getBuiltinEvalError() {
1135 return builtinEvalError;
1136 }
1138 /**
1139 * Called from compiled script code to test if builtin has been overridden
1140 *
1141 * @return true if builtin eval error has not been overridden
1142 */
1143 public static boolean isBuiltinEvalError() {
1144 final Global instance = Global.instance();
1145 return instance.evalError == instance.getBuiltinEvalError();
1146 }
1148 private ScriptFunction getBuiltinFunction() {
1149 return builtinFunction;
1150 }
1152 /**
1153 * Called from compiled script code to test if builtin has been overridden
1154 *
1155 * @return true if builtin function has not been overridden
1156 */
1157 public static boolean isBuiltinFunction() {
1158 final Global instance = Global.instance();
1159 return instance.function == instance.getBuiltinFunction();
1160 }
1162 private ScriptFunction getBuiltinJSAdapter() {
1163 return builtinJSAdapter;
1164 }
1166 /**
1167 * Called from compiled script code to test if builtin has been overridden
1168 *
1169 * @return true if builtin JSAdapter has not been overridden
1170 */
1171 public static boolean isBuiltinJSAdapter() {
1172 final Global instance = Global.instance();
1173 return instance.jsadapter == instance.getBuiltinJSAdapter();
1174 }
1176 private ScriptObject getBuiltinJSON() {
1177 return builtinJSON;
1178 }
1180 /**
1181 * Called from compiled script code to test if builtin has been overridden
1182 *
1183 * @return true if builtin JSON has has not been overridden
1184 */
1185 public static boolean isBuiltinJSON() {
1186 final Global instance = Global.instance();
1187 return instance.json == instance.getBuiltinJSON();
1188 }
1190 private ScriptObject getBuiltinJava() {
1191 return builtinJava;
1192 }
1194 /**
1195 * Called from compiled script code to test if builtin has been overridden
1196 *
1197 * @return true if builtin Java has not been overridden
1198 */
1199 public static boolean isBuiltinJava() {
1200 final Global instance = Global.instance();
1201 return instance.java == instance.getBuiltinJava();
1202 }
1204 private ScriptObject getBuiltinJavax() {
1205 return builtinJavax;
1206 }
1208 /**
1209 * Called from compiled script code to test if builtin has been overridden
1210 *
1211 * @return true if builtin Javax has not been overridden
1212 */
1213 public static boolean isBuiltinJavax() {
1214 final Global instance = Global.instance();
1215 return instance.javax == instance.getBuiltinJavax();
1216 }
1218 private ScriptObject getBuiltinJavaImporter() {
1219 return builtinJavaImporter;
1220 }
1222 /**
1223 * Called from compiled script code to test if builtin has been overridden
1224 *
1225 * @return true if builtin Java importer has not been overridden
1226 */
1227 public static boolean isBuiltinJavaImporter() {
1228 final Global instance = Global.instance();
1229 return instance.javaImporter == instance.getBuiltinJavaImporter();
1230 }
1232 private ScriptObject getBuiltinMath() {
1233 return builtinMath;
1234 }
1236 /**
1237 * Called from compiled script code to test if builtin has been overridden
1238 *
1239 * @return true if builtin math has not been overridden
1240 */
1241 public static boolean isBuiltinMath() {
1242 final Global instance = Global.instance();
1243 return instance.math == instance.getBuiltinMath();
1244 }
1246 private ScriptFunction getBuiltinNumber() {
1247 return builtinNumber;
1248 }
1250 /**
1251 * Called from compiled script code to test if builtin has been overridden
1252 *
1253 * @return true if builtin number has not been overridden
1254 */
1255 public static boolean isBuiltinNumber() {
1256 final Global instance = Global.instance();
1257 return instance.number == instance.getBuiltinNumber();
1258 }
1260 private ScriptFunction getBuiltinObject() {
1261 return builtinObject;
1262 }
1264 /**
1265 * Called from compiled script code to test if builtin has been overridden
1266 *
1267 * @return true if builtin object has not been overridden
1268 */
1269 public static boolean isBuiltinObject() {
1270 final Global instance = Global.instance();
1271 return instance.object == instance.getBuiltinObject();
1272 }
1274 private ScriptObject getBuiltinPackages() {
1275 return builtinPackages;
1276 }
1278 /**
1279 * Called from compiled script code to test if builtin has been overridden
1280 *
1281 * @return true if builtin package has not been overridden
1282 */
1283 public static boolean isBuiltinPackages() {
1284 final Global instance = Global.instance();
1285 return instance.packages == instance.getBuiltinPackages();
1286 }
1288 private ScriptFunction getBuiltinRangeError() {
1289 return builtinRangeError;
1290 }
1292 /**
1293 * Called from compiled script code to test if builtin has been overridden
1294 *
1295 * @return true if builtin range error has not been overridden
1296 */
1297 public static boolean isBuiltinRangeError() {
1298 final Global instance = Global.instance();
1299 return instance.rangeError == instance.getBuiltinRangeError();
1300 }
1302 private ScriptFunction getBuiltinReferenceError() {
1303 return builtinReferenceError;
1304 }
1306 /**
1307 * Called from compiled script code to test if builtin has been overridden
1308 *
1309 * @return true if builtin reference error has not been overridden
1310 */
1311 public static boolean isBuiltinReferenceError() {
1312 final Global instance = Global.instance();
1313 return instance.referenceError == instance.getBuiltinReferenceError();
1314 }
1316 private ScriptFunction getBuiltinRegExp() {
1317 return builtinRegExp;
1318 }
1320 /**
1321 * Called from compiled script code to test if builtin has been overridden
1322 *
1323 * @return true if builtin regexp has not been overridden
1324 */
1325 public static boolean isBuiltinRegExp() {
1326 final Global instance = Global.instance();
1327 return instance.regexp == instance.getBuiltinRegExp();
1328 }
1330 private ScriptFunction getBuiltinString() {
1331 return builtinString;
1332 }
1334 /**
1335 * Called from compiled script code to test if builtin has been overridden
1336 *
1337 * @return true if builtin Java has not been overridden
1338 */
1339 public static boolean isBuiltinString() {
1340 final Global instance = Global.instance();
1341 return instance.string == instance.getBuiltinString();
1342 }
1344 private ScriptFunction getBuiltinSyntaxError() {
1345 return builtinSyntaxError;
1346 }
1348 /**
1349 * Called from compiled script code to test if builtin has been overridden
1350 *
1351 * @return true if builtin syntax error has not been overridden
1352 */
1353 public static boolean isBuiltinSyntaxError() {
1354 final Global instance = Global.instance();
1355 return instance.syntaxError == instance.getBuiltinSyntaxError();
1356 }
1358 private ScriptFunction getBuiltinTypeError() {
1359 return builtinTypeError;
1360 }
1362 /**
1363 * Called from compiled script code to test if builtin has been overridden
1364 *
1365 * @return true if builtin type error has not been overridden
1366 */
1367 public static boolean isBuiltinTypeError() {
1368 final Global instance = Global.instance();
1369 return instance.typeError == instance.getBuiltinTypeError();
1370 }
1372 private ScriptFunction getBuiltinURIError() {
1373 return builtinURIError;
1374 }
1376 /**
1377 * Called from compiled script code to test if builtin has been overridden
1378 *
1379 * @return true if builtin URI error has not been overridden
1380 */
1381 public static boolean isBuiltinURIError() {
1382 final Global instance = Global.instance();
1383 return instance.uriError == instance.getBuiltinURIError();
1384 }
1386 @Override
1387 public String getClassName() {
1388 return "global";
1389 }
1391 /**
1392 * Copy function used to clone NativeRegExp objects.
1393 *
1394 * @param regexp a NativeRegExp to clone
1395 *
1396 * @return copy of the given regexp object
1397 */
1398 public static Object regExpCopy(final Object regexp) {
1399 return new NativeRegExp((NativeRegExp)regexp);
1400 }
1402 /**
1403 * Convert given object to NativeRegExp type.
1404 *
1405 * @param obj object to be converted
1406 * @return NativeRegExp instance
1407 */
1408 public static NativeRegExp toRegExp(final Object obj) {
1409 if (obj instanceof NativeRegExp) {
1410 return (NativeRegExp)obj;
1411 }
1412 return new NativeRegExp(JSType.toString(obj));
1413 }
1415 /**
1416 * ECMA 9.9 ToObject implementation
1417 *
1418 * @param obj an item for which to run ToObject
1419 * @return ToObject version of given item
1420 */
1421 public static Object toObject(final Object obj) {
1422 if (obj == null || obj == UNDEFINED) {
1423 throw typeError("not.an.object", ScriptRuntime.safeToString(obj));
1424 }
1426 if (obj instanceof ScriptObject) {
1427 return obj;
1428 }
1430 return instance().wrapAsObject(obj);
1431 }
1433 /**
1434 * Allocate a new object array.
1435 *
1436 * @param initial object values.
1437 * @return the new array
1438 */
1439 public static NativeArray allocate(final Object[] initial) {
1440 ArrayData arrayData = ArrayData.allocate(initial);
1442 for (int index = 0; index < initial.length; index++) {
1443 final Object value = initial[index];
1445 if (value == ScriptRuntime.EMPTY) {
1446 arrayData = arrayData.delete(index);
1447 }
1448 }
1450 return new NativeArray(arrayData);
1451 }
1453 /**
1454 * Allocate a new number array.
1455 *
1456 * @param initial number values.
1457 * @return the new array
1458 */
1459 public static NativeArray allocate(final double[] initial) {
1460 return new NativeArray(ArrayData.allocate(initial));
1461 }
1463 /**
1464 * Allocate a new long array.
1465 *
1466 * @param initial number values.
1467 * @return the new array
1468 */
1469 public static NativeArray allocate(final long[] initial) {
1470 return new NativeArray(ArrayData.allocate(initial));
1471 }
1473 /**
1474 * Allocate a new integer array.
1475 *
1476 * @param initial number values.
1477 * @return the new array
1478 */
1479 public static NativeArray allocate(final int[] initial) {
1480 return new NativeArray(ArrayData.allocate(initial));
1481 }
1483 /**
1484 * Allocate a new object array for arguments.
1485 *
1486 * @param arguments initial arguments passed.
1487 * @param callee reference to the function that uses arguments object
1488 * @param numParams actual number of declared parameters
1489 *
1490 * @return the new array
1491 */
1492 public static ScriptObject allocateArguments(final Object[] arguments, final Object callee, final int numParams) {
1493 return NativeArguments.allocate(arguments, (ScriptFunction)callee, numParams);
1494 }
1496 /**
1497 * Called from generated to check if given function is the builtin 'eval'. If
1498 * eval is used in a script, a lot of optimizations and assumptions cannot be done.
1499 *
1500 * @param fn function object that is checked
1501 * @return true if fn is the builtin eval
1502 */
1503 public static boolean isEval(final Object fn) {
1504 return fn == Global.instance().builtinEval;
1505 }
1507 /**
1508 * Create a new RegExp object.
1509 *
1510 * @param expression Regular expression.
1511 * @param options Search options.
1512 *
1513 * @return New RegExp object.
1514 */
1515 public static Object newRegExp(final String expression, final String options) {
1516 if (options == null) {
1517 return new NativeRegExp(expression);
1518 }
1519 return new NativeRegExp(expression, options);
1520 }
1522 /**
1523 * Get the object prototype
1524 *
1525 * @return the object prototype
1526 */
1527 public static ScriptObject objectPrototype() {
1528 return Global.instance().getObjectPrototype();
1529 }
1531 /**
1532 * Create a new empty object instance.
1533 *
1534 * @return New empty object.
1535 */
1536 public static ScriptObject newEmptyInstance() {
1537 return Global.instance().newObject();
1538 }
1540 /**
1541 * Check if a given object is a ScriptObject, raises an exception if this is
1542 * not the case
1543 *
1544 * @param obj and object to check
1545 */
1546 public static void checkObject(final Object obj) {
1547 if (!(obj instanceof ScriptObject)) {
1548 throw typeError("not.an.object", ScriptRuntime.safeToString(obj));
1549 }
1550 }
1552 /**
1553 * ECMA 9.10 - implementation of CheckObjectCoercible, i.e. raise an exception
1554 * if this object is null or undefined.
1555 *
1556 * @param obj an object to check
1557 */
1558 public static void checkObjectCoercible(final Object obj) {
1559 if (obj == null || obj == UNDEFINED) {
1560 throw typeError("not.an.object", ScriptRuntime.safeToString(obj));
1561 }
1562 }
1564 /**
1565 * Get the current split state.
1566 *
1567 * @return current split state
1568 */
1569 @Override
1570 public int getSplitState() {
1571 return splitState;
1572 }
1574 /**
1575 * Set the current split state.
1576 *
1577 * @param state current split state
1578 */
1579 @Override
1580 public void setSplitState(final int state) {
1581 splitState = state;
1582 }
1584 private void init() {
1585 assert Context.getGlobal() == this : "this global is not set as current";
1587 final ScriptEnvironment env = getContext().getEnv();
1589 // duplicate PropertyMaps of Native* classes
1590 copyInitialMaps(env);
1592 // initialize Function and Object constructor
1593 initFunctionAndObject();
1595 // Now fix Global's own proto.
1596 this.setProto(getObjectPrototype());
1598 // initialize global function properties
1599 this.eval = this.builtinEval = ScriptFunctionImpl.makeFunction("eval", EVAL);
1601 this.parseInt = ScriptFunctionImpl.makeFunction("parseInt", GlobalFunctions.PARSEINT);
1602 this.parseFloat = ScriptFunctionImpl.makeFunction("parseFloat", GlobalFunctions.PARSEFLOAT);
1603 this.isNaN = ScriptFunctionImpl.makeFunction("isNaN", GlobalFunctions.IS_NAN);
1604 this.isFinite = ScriptFunctionImpl.makeFunction("isFinite", GlobalFunctions.IS_FINITE);
1605 this.encodeURI = ScriptFunctionImpl.makeFunction("encodeURI", GlobalFunctions.ENCODE_URI);
1606 this.encodeURIComponent = ScriptFunctionImpl.makeFunction("encodeURIComponent", GlobalFunctions.ENCODE_URICOMPONENT);
1607 this.decodeURI = ScriptFunctionImpl.makeFunction("decodeURI", GlobalFunctions.DECODE_URI);
1608 this.decodeURIComponent = ScriptFunctionImpl.makeFunction("decodeURIComponent", GlobalFunctions.DECODE_URICOMPONENT);
1609 this.escape = ScriptFunctionImpl.makeFunction("escape", GlobalFunctions.ESCAPE);
1610 this.unescape = ScriptFunctionImpl.makeFunction("unescape", GlobalFunctions.UNESCAPE);
1611 this.print = ScriptFunctionImpl.makeFunction("print", env._print_no_newline ? PRINT : PRINTLN);
1612 this.load = ScriptFunctionImpl.makeFunction("load", LOAD);
1613 this.loadWithNewGlobal = ScriptFunctionImpl.makeFunction("loadWithNewGlobal", LOADWITHNEWGLOBAL);
1614 this.exit = ScriptFunctionImpl.makeFunction("exit", EXIT);
1615 this.quit = ScriptFunctionImpl.makeFunction("quit", EXIT);
1617 // built-in constructors
1618 this.builtinArray = (ScriptFunction)initConstructor("Array");
1619 this.builtinBoolean = (ScriptFunction)initConstructor("Boolean");
1620 this.builtinDate = (ScriptFunction)initConstructor("Date");
1621 this.builtinJSON = initConstructor("JSON");
1622 this.builtinJSAdapter = (ScriptFunction)initConstructor("JSAdapter");
1623 this.builtinMath = initConstructor("Math");
1624 this.builtinNumber = (ScriptFunction)initConstructor("Number");
1625 this.builtinRegExp = (ScriptFunction)initConstructor("RegExp");
1626 this.builtinString = (ScriptFunction)initConstructor("String");
1628 // initialize String.prototype.length to 0
1629 // add String.prototype.length
1630 final ScriptObject stringPrototype = getStringPrototype();
1631 stringPrototype.addOwnProperty("length", Attribute.NON_ENUMERABLE_CONSTANT, 0.0);
1633 // add Array.prototype.length
1634 final ScriptObject arrayPrototype = getArrayPrototype();
1635 arrayPrototype.addOwnProperty("length", Attribute.NOT_ENUMERABLE|Attribute.NOT_CONFIGURABLE, 0.0);
1637 this.DEFAULT_DATE = new NativeDate(Double.NaN, this);
1639 // initialize default regexp object
1640 this.DEFAULT_REGEXP = new NativeRegExp("(?:)", this);
1642 // RegExp.prototype should behave like a RegExp object. So copy the
1643 // properties.
1644 final ScriptObject regExpProto = getRegExpPrototype();
1645 regExpProto.addBoundProperties(DEFAULT_REGEXP);
1647 // Error stuff
1648 initErrorObjects();
1650 // java access
1651 if (! env._no_java) {
1652 initJavaAccess();
1653 }
1655 if (! env._no_typed_arrays) {
1656 initTypedArray();
1657 }
1659 if (env._scripting) {
1660 initScripting(env);
1661 }
1663 if (Context.DEBUG && System.getSecurityManager() == null) {
1664 initDebug();
1665 }
1667 copyBuiltins();
1669 // initialized with strings so that typeof will work as expected.
1670 this.__FILE__ = "";
1671 this.__DIR__ = "";
1672 this.__LINE__ = 0.0;
1674 // expose script (command line) arguments as "arguments" property of global
1675 final List<String> arguments = env.getArguments();
1676 final Object argsObj = wrapAsObject(arguments.toArray());
1678 addOwnProperty("arguments", Attribute.NOT_ENUMERABLE, argsObj);
1679 if (env._scripting) {
1680 // synonym for "arguments" in scripting mode
1681 addOwnProperty("$ARG", Attribute.NOT_ENUMERABLE, argsObj);
1682 }
1683 }
1685 private void initErrorObjects() {
1686 // Error objects
1687 this.builtinError = (ScriptFunction)initConstructor("Error");
1688 final ScriptObject errorProto = getErrorPrototype();
1690 // Nashorn specific accessors on Error.prototype - stack, lineNumber, columnNumber and fileName
1691 final ScriptFunction getStack = ScriptFunctionImpl.makeFunction("getStack", NativeError.GET_STACK);
1692 final ScriptFunction setStack = ScriptFunctionImpl.makeFunction("setStack", NativeError.SET_STACK);
1693 errorProto.addOwnProperty("stack", Attribute.NOT_ENUMERABLE, getStack, setStack);
1694 final ScriptFunction getLineNumber = ScriptFunctionImpl.makeFunction("getLineNumber", NativeError.GET_LINENUMBER);
1695 final ScriptFunction setLineNumber = ScriptFunctionImpl.makeFunction("setLineNumber", NativeError.SET_LINENUMBER);
1696 errorProto.addOwnProperty("lineNumber", Attribute.NOT_ENUMERABLE, getLineNumber, setLineNumber);
1697 final ScriptFunction getColumnNumber = ScriptFunctionImpl.makeFunction("getColumnNumber", NativeError.GET_COLUMNNUMBER);
1698 final ScriptFunction setColumnNumber = ScriptFunctionImpl.makeFunction("setColumnNumber", NativeError.SET_COLUMNNUMBER);
1699 errorProto.addOwnProperty("columnNumber", Attribute.NOT_ENUMERABLE, getColumnNumber, setColumnNumber);
1700 final ScriptFunction getFileName = ScriptFunctionImpl.makeFunction("getFileName", NativeError.GET_FILENAME);
1701 final ScriptFunction setFileName = ScriptFunctionImpl.makeFunction("setFileName", NativeError.SET_FILENAME);
1702 errorProto.addOwnProperty("fileName", Attribute.NOT_ENUMERABLE, getFileName, setFileName);
1704 // ECMA 15.11.4.2 Error.prototype.name
1705 // Error.prototype.name = "Error";
1706 errorProto.set(NativeError.NAME, "Error", false);
1707 // ECMA 15.11.4.3 Error.prototype.message
1708 // Error.prototype.message = "";
1709 errorProto.set(NativeError.MESSAGE, "", false);
1711 this.builtinEvalError = initErrorSubtype("EvalError", errorProto);
1712 this.builtinRangeError = initErrorSubtype("RangeError", errorProto);
1713 this.builtinReferenceError = initErrorSubtype("ReferenceError", errorProto);
1714 this.builtinSyntaxError = initErrorSubtype("SyntaxError", errorProto);
1715 this.builtinTypeError = initErrorSubtype("TypeError", errorProto);
1716 this.builtinURIError = initErrorSubtype("URIError", errorProto);
1717 }
1719 private ScriptFunction initErrorSubtype(final String name, final ScriptObject errorProto) {
1720 final ScriptObject cons = initConstructor(name);
1721 final ScriptObject prototype = ScriptFunction.getPrototype(cons);
1722 prototype.set(NativeError.NAME, name, false);
1723 prototype.set(NativeError.MESSAGE, "", false);
1724 prototype.setProto(errorProto);
1725 return (ScriptFunction)cons;
1726 }
1728 private void initJavaAccess() {
1729 final ScriptObject objectProto = getObjectPrototype();
1730 this.builtinPackages = new NativeJavaPackage("", objectProto);
1731 this.builtinCom = new NativeJavaPackage("com", objectProto);
1732 this.builtinEdu = new NativeJavaPackage("edu", objectProto);
1733 this.builtinJava = new NativeJavaPackage("java", objectProto);
1734 this.builtinJavafx = new NativeJavaPackage("javafx", objectProto);
1735 this.builtinJavax = new NativeJavaPackage("javax", objectProto);
1736 this.builtinOrg = new NativeJavaPackage("org", objectProto);
1737 this.builtinJavaImporter = initConstructor("JavaImporter");
1738 this.builtinJavaApi = initConstructor("Java");
1739 }
1741 private void initScripting(final ScriptEnvironment scriptEnv) {
1742 Object value;
1743 value = ScriptFunctionImpl.makeFunction("readLine", ScriptingFunctions.READLINE);
1744 addOwnProperty("readLine", Attribute.NOT_ENUMERABLE, value);
1746 value = ScriptFunctionImpl.makeFunction("readFully", ScriptingFunctions.READFULLY);
1747 addOwnProperty("readFully", Attribute.NOT_ENUMERABLE, value);
1749 final String execName = ScriptingFunctions.EXEC_NAME;
1750 value = ScriptFunctionImpl.makeFunction(execName, ScriptingFunctions.EXEC);
1751 addOwnProperty(execName, Attribute.NOT_ENUMERABLE, value);
1753 // Nashorn extension: global.echo (scripting-mode-only)
1754 // alias for "print"
1755 value = get("print");
1756 addOwnProperty("echo", Attribute.NOT_ENUMERABLE, value);
1758 // Nashorn extension: global.$OPTIONS (scripting-mode-only)
1759 final ScriptObject options = newObject();
1760 copyOptions(options, scriptEnv);
1761 addOwnProperty("$OPTIONS", Attribute.NOT_ENUMERABLE, options);
1763 // Nashorn extension: global.$ENV (scripting-mode-only)
1764 if (System.getSecurityManager() == null) {
1765 // do not fill $ENV if we have a security manager around
1766 // Retrieve current state of ENV variables.
1767 final ScriptObject env = newObject();
1768 env.putAll(System.getenv());
1769 addOwnProperty(ScriptingFunctions.ENV_NAME, Attribute.NOT_ENUMERABLE, env);
1770 } else {
1771 addOwnProperty(ScriptingFunctions.ENV_NAME, Attribute.NOT_ENUMERABLE, UNDEFINED);
1772 }
1774 // add other special properties for exec support
1775 addOwnProperty(ScriptingFunctions.OUT_NAME, Attribute.NOT_ENUMERABLE, UNDEFINED);
1776 addOwnProperty(ScriptingFunctions.ERR_NAME, Attribute.NOT_ENUMERABLE, UNDEFINED);
1777 addOwnProperty(ScriptingFunctions.EXIT_NAME, Attribute.NOT_ENUMERABLE, UNDEFINED);
1778 }
1780 private static void copyOptions(final ScriptObject options, final ScriptEnvironment scriptEnv) {
1781 for (Field f : scriptEnv.getClass().getFields()) {
1782 try {
1783 options.set(f.getName(), f.get(scriptEnv), false);
1784 } catch (final IllegalArgumentException | IllegalAccessException exp) {
1785 throw new RuntimeException(exp);
1786 }
1787 }
1788 }
1790 private void initTypedArray() {
1791 this.builtinArrayBuffer = initConstructor("ArrayBuffer");
1792 this.builtinInt8Array = initConstructor("Int8Array");
1793 this.builtinUint8Array = initConstructor("Uint8Array");
1794 this.builtinUint8ClampedArray = initConstructor("Uint8ClampedArray");
1795 this.builtinInt16Array = initConstructor("Int16Array");
1796 this.builtinUint16Array = initConstructor("Uint16Array");
1797 this.builtinInt32Array = initConstructor("Int32Array");
1798 this.builtinUint32Array = initConstructor("Uint32Array");
1799 this.builtinFloat32Array = initConstructor("Float32Array");
1800 this.builtinFloat64Array = initConstructor("Float64Array");
1801 }
1803 private void copyBuiltins() {
1804 this.array = this.builtinArray;
1805 this._boolean = this.builtinBoolean;
1806 this.date = this.builtinDate;
1807 this.error = this.builtinError;
1808 this.evalError = this.builtinEvalError;
1809 this.function = this.builtinFunction;
1810 this.jsadapter = this.builtinJSAdapter;
1811 this.json = this.builtinJSON;
1812 this.com = this.builtinCom;
1813 this.edu = this.builtinEdu;
1814 this.java = this.builtinJava;
1815 this.javafx = this.builtinJavafx;
1816 this.javax = this.builtinJavax;
1817 this.org = this.builtinOrg;
1818 this.javaImporter = this.builtinJavaImporter;
1819 this.javaApi = this.builtinJavaApi;
1820 this.math = this.builtinMath;
1821 this.number = this.builtinNumber;
1822 this.object = this.builtinObject;
1823 this.packages = this.builtinPackages;
1824 this.rangeError = this.builtinRangeError;
1825 this.referenceError = this.builtinReferenceError;
1826 this.regexp = this.builtinRegExp;
1827 this.string = this.builtinString;
1828 this.syntaxError = this.builtinSyntaxError;
1829 this.typeError = this.builtinTypeError;
1830 this.uriError = this.builtinURIError;
1831 this.arrayBuffer = this.builtinArrayBuffer;
1832 this.int8Array = this.builtinInt8Array;
1833 this.uint8Array = this.builtinUint8Array;
1834 this.uint8ClampedArray = this.builtinUint8ClampedArray;
1835 this.int16Array = this.builtinInt16Array;
1836 this.uint16Array = this.builtinUint16Array;
1837 this.int32Array = this.builtinInt32Array;
1838 this.uint32Array = this.builtinUint32Array;
1839 this.float32Array = this.builtinFloat32Array;
1840 this.float64Array = this.builtinFloat64Array;
1841 }
1843 private void initDebug() {
1844 this.addOwnProperty("Debug", Attribute.NOT_ENUMERABLE, initConstructor("Debug"));
1845 }
1847 @SuppressWarnings("resource")
1848 private static Object printImpl(final boolean newLine, final Object... objects) {
1849 final PrintWriter out = Global.getEnv().getOut();
1850 final StringBuilder sb = new StringBuilder();
1852 for (final Object object : objects) {
1853 if (sb.length() != 0) {
1854 sb.append(' ');
1855 }
1857 sb.append(JSType.toString(object));
1858 }
1860 // Print all at once to ensure thread friendly result.
1861 if (newLine) {
1862 out.println(sb.toString());
1863 } else {
1864 out.print(sb.toString());
1865 }
1867 out.flush();
1869 return UNDEFINED;
1870 }
1872 /**
1873 * These classes are generated by nasgen tool and so we have to use
1874 * reflection to load and create new instance of these classes.
1875 */
1876 private ScriptObject initConstructor(final String name) {
1877 try {
1878 // Assuming class name pattern for built-in JS constructors.
1879 final StringBuilder sb = new StringBuilder("jdk.nashorn.internal.objects.");
1881 sb.append("Native");
1882 sb.append(name);
1883 sb.append("$Constructor");
1885 final Class<?> funcClass = Class.forName(sb.toString());
1886 final ScriptObject res = (ScriptObject)funcClass.newInstance();
1888 if (res instanceof ScriptFunction) {
1889 // All global constructor prototypes are not-writable,
1890 // not-enumerable and not-configurable.
1891 final ScriptFunction func = (ScriptFunction)res;
1892 func.modifyOwnProperty(func.getProperty("prototype"), Attribute.NON_ENUMERABLE_CONSTANT);
1893 }
1895 if (res.getProto() == null) {
1896 res.setProto(getObjectPrototype());
1897 }
1899 return res;
1901 } catch (final ClassNotFoundException | InstantiationException | IllegalAccessException e) {
1902 throw new RuntimeException(e);
1903 }
1904 }
1906 private void copyInitialMaps(final ScriptEnvironment env) {
1907 this.accessorPropertyDescriptorMap = AccessorPropertyDescriptor.getInitialMap().duplicate();
1908 this.dataPropertyDescriptorMap = DataPropertyDescriptor.getInitialMap().duplicate();
1909 this.genericPropertyDescriptorMap = GenericPropertyDescriptor.getInitialMap().duplicate();
1910 this.nativeArgumentsMap = NativeArguments.getInitialMap().duplicate();
1911 this.nativeArrayMap = NativeArray.getInitialMap().duplicate();
1912 this.nativeBooleanMap = NativeBoolean.getInitialMap().duplicate();
1913 this.nativeDateMap = NativeDate.getInitialMap().duplicate();
1914 this.nativeErrorMap = NativeError.getInitialMap().duplicate();
1915 this.nativeEvalErrorMap = NativeEvalError.getInitialMap().duplicate();
1916 this.nativeJSAdapterMap = NativeJSAdapter.getInitialMap().duplicate();
1917 this.nativeNumberMap = NativeNumber.getInitialMap().duplicate();
1918 this.nativeRangeErrorMap = NativeRangeError.getInitialMap().duplicate();
1919 this.nativeReferenceErrorMap = NativeReferenceError.getInitialMap().duplicate();
1920 this.nativeRegExpMap = NativeRegExp.getInitialMap().duplicate();
1921 this.nativeRegExpExecResultMap = NativeRegExpExecResult.getInitialMap().duplicate();
1922 this.nativeStrictArgumentsMap = NativeStrictArguments.getInitialMap().duplicate();
1923 this.nativeStringMap = NativeString.getInitialMap().duplicate();
1924 this.nativeSyntaxErrorMap = NativeSyntaxError.getInitialMap().duplicate();
1925 this.nativeTypeErrorMap = NativeTypeError.getInitialMap().duplicate();
1926 this.nativeURIErrorMap = NativeURIError.getInitialMap().duplicate();
1927 this.prototypeObjectMap = PrototypeObject.getInitialMap().duplicate();
1928 this.objectMap = JO.getInitialMap().duplicate();
1929 this.functionMap = ScriptFunctionImpl.getInitialMap().duplicate();
1930 this.anonymousFunctionMap = ScriptFunctionImpl.getInitialAnonymousMap().duplicate();
1931 this.strictFunctionMap = ScriptFunctionImpl.getInitialStrictMap().duplicate();
1932 this.boundFunctionMap = ScriptFunctionImpl.getInitialBoundMap().duplicate();
1934 // java
1935 if (! env._no_java) {
1936 this.nativeJavaImporterMap = NativeJavaImporter.getInitialMap().duplicate();
1937 }
1939 // typed arrays
1940 if (! env._no_typed_arrays) {
1941 this.arrayBufferViewMap = ArrayBufferView.getInitialMap().duplicate();
1942 this.nativeArrayBufferMap = NativeArrayBuffer.getInitialMap().duplicate();
1943 }
1944 }
1946 // Function and Object constructors are inter-dependent. Also,
1947 // Function.prototype
1948 // functions are not properly initialized. We fix the references here.
1949 // NOTE: be careful if you want to re-order the operations here. You may
1950 // have
1951 // to play with object references carefully!!
1952 private void initFunctionAndObject() {
1953 // First-n-foremost is Function
1954 this.builtinFunction = (ScriptFunction)initConstructor("Function");
1956 // create global anonymous function
1957 final ScriptFunction anon = ScriptFunctionImpl.newAnonymousFunction(this);
1958 // need to copy over members of Function.prototype to anon function
1959 anon.addBoundProperties(getFunctionPrototype());
1961 // Function.prototype === Object.getPrototypeOf(Function) ===
1962 // <anon-function>
1963 builtinFunction.setProto(anon);
1964 builtinFunction.setPrototype(anon);
1965 anon.set("constructor", builtinFunction, false);
1966 anon.deleteOwnProperty(anon.getMap().findProperty("prototype"));
1968 // now initialize Object
1969 this.builtinObject = (ScriptFunction)initConstructor("Object");
1970 final ScriptObject ObjectPrototype = getObjectPrototype();
1971 // Object.getPrototypeOf(Function.prototype) === Object.prototype
1972 anon.setProto(ObjectPrototype);
1974 // Function valued properties of Function.prototype were not properly
1975 // initialized. Because, these were created before global.function and
1976 // global.object were not initialized.
1977 jdk.nashorn.internal.runtime.Property[] properties = getFunctionPrototype().getMap().getProperties();
1978 for (final jdk.nashorn.internal.runtime.Property property : properties) {
1979 final Object key = property.getKey();
1980 final Object value = builtinFunction.get(key);
1982 if (value instanceof ScriptFunction && value != anon) {
1983 final ScriptFunction func = (ScriptFunction)value;
1984 func.setProto(getFunctionPrototype());
1985 final ScriptObject prototype = ScriptFunction.getPrototype(func);
1986 if (prototype != null) {
1987 prototype.setProto(ObjectPrototype);
1988 }
1989 }
1990 }
1992 // For function valued properties of Object and Object.prototype, make
1993 // sure prototype's proto chain ends with Object.prototype
1994 for (final jdk.nashorn.internal.runtime.Property property : builtinObject.getMap().getProperties()) {
1995 final Object key = property.getKey();
1996 final Object value = builtinObject.get(key);
1998 if (value instanceof ScriptFunction) {
1999 final ScriptFunction func = (ScriptFunction)value;
2000 final ScriptObject prototype = ScriptFunction.getPrototype(func);
2001 if (prototype != null) {
2002 prototype.setProto(ObjectPrototype);
2003 }
2004 }
2005 }
2007 properties = getObjectPrototype().getMap().getProperties();
2008 for (final jdk.nashorn.internal.runtime.Property property : properties) {
2009 final Object key = property.getKey();
2010 final Object value = ObjectPrototype.get(key);
2012 if (key.equals("constructor")) {
2013 continue;
2014 }
2016 if (value instanceof ScriptFunction) {
2017 final ScriptFunction func = (ScriptFunction)value;
2018 final ScriptObject prototype = ScriptFunction.getPrototype(func);
2019 if (prototype != null) {
2020 prototype.setProto(ObjectPrototype);
2021 }
2022 }
2023 }
2024 }
2026 private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
2027 return MH.findStatic(MethodHandles.lookup(), Global.class, name, MH.type(rtype, types));
2028 }
2030 RegExpResult getLastRegExpResult() {
2031 return lastRegExpResult;
2032 }
2034 void setLastRegExpResult(final RegExpResult regExpResult) {
2035 this.lastRegExpResult = regExpResult;
2036 }
2038 }