Fri, 17 Jan 2014 20:09:47 +0530
8032060: PropertyMap of Error objects is not stable
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.ReferenceQueue;
37 import java.lang.ref.SoftReference;
38 import java.lang.reflect.Field;
39 import java.util.Arrays;
40 import java.util.LinkedHashMap;
41 import java.util.List;
42 import java.util.Map;
43 import java.util.concurrent.Callable;
44 import java.util.concurrent.ConcurrentHashMap;
45 import jdk.internal.dynalink.linker.GuardedInvocation;
46 import jdk.internal.dynalink.linker.LinkRequest;
47 import jdk.nashorn.internal.lookup.Lookup;
48 import jdk.nashorn.internal.objects.annotations.Attribute;
49 import jdk.nashorn.internal.objects.annotations.Property;
50 import jdk.nashorn.internal.objects.annotations.ScriptClass;
51 import jdk.nashorn.internal.runtime.ConsString;
52 import jdk.nashorn.internal.runtime.Context;
53 import jdk.nashorn.internal.runtime.GlobalFunctions;
54 import jdk.nashorn.internal.runtime.GlobalObject;
55 import jdk.nashorn.internal.runtime.JSType;
56 import jdk.nashorn.internal.runtime.NativeJavaPackage;
57 import jdk.nashorn.internal.runtime.PropertyDescriptor;
58 import jdk.nashorn.internal.runtime.PropertyMap;
59 import jdk.nashorn.internal.runtime.Scope;
60 import jdk.nashorn.internal.runtime.ScriptEnvironment;
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.arrays.ArrayData;
67 import jdk.nashorn.internal.runtime.linker.Bootstrap;
68 import jdk.nashorn.internal.runtime.linker.InvokeByName;
69 import jdk.nashorn.internal.runtime.regexp.RegExpResult;
70 import jdk.nashorn.internal.scripts.JO;
72 /**
73 * Representation of global scope.
74 */
75 @ScriptClass("Global")
76 public final class Global extends ScriptObject implements GlobalObject, Scope {
77 private final InvokeByName TO_STRING = new InvokeByName("toString", ScriptObject.class);
78 private final InvokeByName VALUE_OF = new InvokeByName("valueOf", ScriptObject.class);
80 /** ECMA 15.1.2.2 parseInt (string , radix) */
81 @Property(attributes = Attribute.NOT_ENUMERABLE)
82 public Object parseInt;
84 /** ECMA 15.1.2.3 parseFloat (string) */
85 @Property(attributes = Attribute.NOT_ENUMERABLE)
86 public Object parseFloat;
88 /** ECMA 15.1.2.4 isNaN (number) */
89 @Property(attributes = Attribute.NOT_ENUMERABLE)
90 public Object isNaN;
92 /** ECMA 15.1.2.5 isFinite (number) */
93 @Property(attributes = Attribute.NOT_ENUMERABLE)
94 public Object isFinite;
96 /** ECMA 15.1.3.3 encodeURI */
97 @Property(attributes = Attribute.NOT_ENUMERABLE)
98 public Object encodeURI;
100 /** ECMA 15.1.3.4 encodeURIComponent */
101 @Property(attributes = Attribute.NOT_ENUMERABLE)
102 public Object encodeURIComponent;
104 /** ECMA 15.1.3.1 decodeURI */
105 @Property(attributes = Attribute.NOT_ENUMERABLE)
106 public Object decodeURI;
108 /** ECMA 15.1.3.2 decodeURIComponent */
109 @Property(attributes = Attribute.NOT_ENUMERABLE)
110 public Object decodeURIComponent;
112 /** ECMA B.2.1 escape (string) */
113 @Property(attributes = Attribute.NOT_ENUMERABLE)
114 public Object escape;
116 /** ECMA B.2.2 unescape (string) */
117 @Property(attributes = Attribute.NOT_ENUMERABLE)
118 public Object unescape;
120 /** Nashorn extension: global.print */
121 @Property(attributes = Attribute.NOT_ENUMERABLE)
122 public Object print;
124 /** Nashorn extension: global.load */
125 @Property(attributes = Attribute.NOT_ENUMERABLE)
126 public Object load;
128 /** Nashorn extension: global.loadWithNewGlobal */
129 @Property(attributes = Attribute.NOT_ENUMERABLE)
130 public Object loadWithNewGlobal;
132 /** Nashorn extension: global.exit */
133 @Property(attributes = Attribute.NOT_ENUMERABLE)
134 public Object exit;
136 /** Nashorn extension: global.quit */
137 @Property(attributes = Attribute.NOT_ENUMERABLE)
138 public Object quit;
140 /** Value property NaN of the Global Object - ECMA 15.1.1.1 NaN */
141 @Property(attributes = Attribute.NON_ENUMERABLE_CONSTANT)
142 public final Object NaN = Double.NaN;
144 /** Value property Infinity of the Global Object - ECMA 15.1.1.2 Infinity */
145 @Property(attributes = Attribute.NON_ENUMERABLE_CONSTANT)
146 public final Object Infinity = Double.POSITIVE_INFINITY;
148 /** Value property Undefined of the Global Object - ECMA 15.1.1.3 Undefined */
149 @Property(attributes = Attribute.NON_ENUMERABLE_CONSTANT)
150 public final Object undefined = UNDEFINED;
152 /** ECMA 15.1.2.1 eval(x) */
153 @Property(attributes = Attribute.NOT_ENUMERABLE)
154 public Object eval;
156 /** ECMA 15.1.4.1 Object constructor. */
157 @Property(name = "Object", attributes = Attribute.NOT_ENUMERABLE)
158 public volatile Object object;
160 /** ECMA 15.1.4.2 Function constructor. */
161 @Property(name = "Function", attributes = Attribute.NOT_ENUMERABLE)
162 public volatile Object function;
164 /** ECMA 15.1.4.3 Array constructor. */
165 @Property(name = "Array", attributes = Attribute.NOT_ENUMERABLE)
166 public volatile Object array;
168 /** ECMA 15.1.4.4 String constructor */
169 @Property(name = "String", attributes = Attribute.NOT_ENUMERABLE)
170 public volatile Object string;
172 /** ECMA 15.1.4.5 Boolean constructor */
173 @Property(name = "Boolean", attributes = Attribute.NOT_ENUMERABLE)
174 public volatile Object _boolean;
176 /** ECMA 15.1.4.6 - Number constructor */
177 @Property(name = "Number", attributes = Attribute.NOT_ENUMERABLE)
178 public volatile Object number;
180 /** ECMA 15.1.4.7 Date constructor */
181 @Property(name = "Date", attributes = Attribute.NOT_ENUMERABLE)
182 public volatile Object date;
184 /** ECMA 15.1.4.8 RegExp constructor */
185 @Property(name = "RegExp", attributes = Attribute.NOT_ENUMERABLE)
186 public volatile Object regexp;
188 /** ECMA 15.12 - The JSON object */
189 @Property(name = "JSON", attributes = Attribute.NOT_ENUMERABLE)
190 public volatile Object json;
192 /** Nashorn extension: global.JSAdapter */
193 @Property(name = "JSAdapter", attributes = Attribute.NOT_ENUMERABLE)
194 public volatile Object jsadapter;
196 /** ECMA 15.8 - The Math object */
197 @Property(name = "Math", attributes = Attribute.NOT_ENUMERABLE)
198 public volatile Object math;
200 /** Error object */
201 @Property(name = "Error", attributes = Attribute.NOT_ENUMERABLE)
202 public volatile Object error;
204 /** EvalError object */
205 @Property(name = "EvalError", attributes = Attribute.NOT_ENUMERABLE)
206 public volatile Object evalError;
208 /** RangeError object */
209 @Property(name = "RangeError", attributes = Attribute.NOT_ENUMERABLE)
210 public volatile Object rangeError;
212 /** ReferenceError object */
213 @Property(name = "ReferenceError", attributes = Attribute.NOT_ENUMERABLE)
214 public volatile Object referenceError;
216 /** SyntaxError object */
217 @Property(name = "SyntaxError", attributes = Attribute.NOT_ENUMERABLE)
218 public volatile Object syntaxError;
220 /** TypeError object */
221 @Property(name = "TypeError", attributes = Attribute.NOT_ENUMERABLE)
222 public volatile Object typeError;
224 /** URIError object */
225 @Property(name = "URIError", attributes = Attribute.NOT_ENUMERABLE)
226 public volatile Object uriError;
228 /** ArrayBuffer object */
229 @Property(name = "ArrayBuffer", attributes = Attribute.NOT_ENUMERABLE)
230 public volatile Object arrayBuffer;
232 /** TypedArray (int8) */
233 @Property(name = "Int8Array", attributes = Attribute.NOT_ENUMERABLE)
234 public volatile Object int8Array;
236 /** TypedArray (uint8) */
237 @Property(name = "Uint8Array", attributes = Attribute.NOT_ENUMERABLE)
238 public volatile Object uint8Array;
240 /** TypedArray (uint8) - Clamped */
241 @Property(name = "Uint8ClampedArray", attributes = Attribute.NOT_ENUMERABLE)
242 public volatile Object uint8ClampedArray;
244 /** TypedArray (int16) */
245 @Property(name = "Int16Array", attributes = Attribute.NOT_ENUMERABLE)
246 public volatile Object int16Array;
248 /** TypedArray (uint16) */
249 @Property(name = "Uint16Array", attributes = Attribute.NOT_ENUMERABLE)
250 public volatile Object uint16Array;
252 /** TypedArray (int32) */
253 @Property(name = "Int32Array", attributes = Attribute.NOT_ENUMERABLE)
254 public volatile Object int32Array;
256 /** TypedArray (uint32) */
257 @Property(name = "Uint32Array", attributes = Attribute.NOT_ENUMERABLE)
258 public volatile Object uint32Array;
260 /** TypedArray (float32) */
261 @Property(name = "Float32Array", attributes = Attribute.NOT_ENUMERABLE)
262 public volatile Object float32Array;
264 /** TypedArray (float64) */
265 @Property(name = "Float64Array", attributes = Attribute.NOT_ENUMERABLE)
266 public volatile Object float64Array;
268 /** Nashorn extension: Java access - global.Packages */
269 @Property(name = "Packages", attributes = Attribute.NOT_ENUMERABLE)
270 public volatile Object packages;
272 /** Nashorn extension: Java access - global.com */
273 @Property(attributes = Attribute.NOT_ENUMERABLE)
274 public volatile Object com;
276 /** Nashorn extension: Java access - global.edu */
277 @Property(attributes = Attribute.NOT_ENUMERABLE)
278 public volatile Object edu;
280 /** Nashorn extension: Java access - global.java */
281 @Property(attributes = Attribute.NOT_ENUMERABLE)
282 public volatile Object java;
284 /** Nashorn extension: Java access - global.javafx */
285 @Property(attributes = Attribute.NOT_ENUMERABLE)
286 public volatile Object javafx;
288 /** Nashorn extension: Java access - global.javax */
289 @Property(attributes = Attribute.NOT_ENUMERABLE)
290 public volatile Object javax;
292 /** Nashorn extension: Java access - global.org */
293 @Property(attributes = Attribute.NOT_ENUMERABLE)
294 public volatile Object org;
296 /** Nashorn extension: Java access - global.javaImporter */
297 @Property(name = "JavaImporter", attributes = Attribute.NOT_ENUMERABLE)
298 public volatile Object javaImporter;
300 /** Nashorn extension: global.Java Object constructor. */
301 @Property(name = "Java", attributes = Attribute.NOT_ENUMERABLE)
302 public volatile Object javaApi;
304 /** Nashorn extension: current script's file name */
305 @Property(name = "__FILE__", attributes = Attribute.NON_ENUMERABLE_CONSTANT)
306 public Object __FILE__;
308 /** Nashorn extension: current script's directory */
309 @Property(name = "__DIR__", attributes = Attribute.NON_ENUMERABLE_CONSTANT)
310 public Object __DIR__;
312 /** Nashorn extension: current source line number being executed */
313 @Property(name = "__LINE__", attributes = Attribute.NON_ENUMERABLE_CONSTANT)
314 public Object __LINE__;
316 /** Used as Date.prototype's default value */
317 public NativeDate DEFAULT_DATE;
319 /** Used as RegExp.prototype's default value */
320 public NativeRegExp DEFAULT_REGEXP;
322 /*
323 * Built-in constructor objects: Even if user changes dynamic values of
324 * "Object", "Array" etc., we still want to keep original values of these
325 * constructors here. For example, we need to be able to create array,
326 * regexp literals even after user overwrites global "Array" or "RegExp"
327 * constructor - see also ECMA 262 spec. Annex D.
328 */
329 private ScriptFunction builtinFunction;
330 private ScriptFunction builtinObject;
331 private ScriptFunction builtinArray;
332 private ScriptFunction builtinBoolean;
333 private ScriptFunction builtinDate;
334 private ScriptObject builtinJSON;
335 private ScriptFunction builtinJSAdapter;
336 private ScriptObject builtinMath;
337 private ScriptFunction builtinNumber;
338 private ScriptFunction builtinRegExp;
339 private ScriptFunction builtinString;
340 private ScriptFunction builtinError;
341 private ScriptFunction builtinEval;
342 private ScriptFunction builtinEvalError;
343 private ScriptFunction builtinRangeError;
344 private ScriptFunction builtinReferenceError;
345 private ScriptFunction builtinSyntaxError;
346 private ScriptFunction builtinTypeError;
347 private ScriptFunction builtinURIError;
348 private ScriptObject builtinPackages;
349 private ScriptObject builtinCom;
350 private ScriptObject builtinEdu;
351 private ScriptObject builtinJava;
352 private ScriptObject builtinJavafx;
353 private ScriptObject builtinJavax;
354 private ScriptObject builtinOrg;
355 private ScriptObject builtinJavaImporter;
356 private ScriptObject builtinJavaApi;
357 private ScriptObject builtinArrayBuffer;
358 private ScriptObject builtinInt8Array;
359 private ScriptObject builtinUint8Array;
360 private ScriptObject builtinUint8ClampedArray;
361 private ScriptObject builtinInt16Array;
362 private ScriptObject builtinUint16Array;
363 private ScriptObject builtinInt32Array;
364 private ScriptObject builtinUint32Array;
365 private ScriptObject builtinFloat32Array;
366 private ScriptObject builtinFloat64Array;
368 /*
369 * ECMA section 13.2.3 The [[ThrowTypeError]] Function Object
370 */
371 private ScriptFunction typeErrorThrower;
373 private PropertyMap accessorPropertyDescriptorMap;
374 private PropertyMap arrayBufferViewMap;
375 private PropertyMap dataPropertyDescriptorMap;
376 private PropertyMap genericPropertyDescriptorMap;
377 private PropertyMap nativeArgumentsMap;
378 private PropertyMap nativeArrayMap;
379 private PropertyMap nativeArrayBufferMap;
380 private PropertyMap nativeBooleanMap;
381 private PropertyMap nativeDateMap;
382 private PropertyMap nativeErrorMap;
383 private PropertyMap nativeEvalErrorMap;
384 private PropertyMap nativeJSAdapterMap;
385 private PropertyMap nativeJavaImporterMap;
386 private PropertyMap nativeNumberMap;
387 private PropertyMap nativeRangeErrorMap;
388 private PropertyMap nativeReferenceErrorMap;
389 private PropertyMap nativeRegExpMap;
390 private PropertyMap nativeRegExpExecResultMap;
391 private PropertyMap nativeStrictArgumentsMap;
392 private PropertyMap nativeStringMap;
393 private PropertyMap nativeSyntaxErrorMap;
394 private PropertyMap nativeTypeErrorMap;
395 private PropertyMap nativeURIErrorMap;
396 private PropertyMap prototypeObjectMap;
397 private PropertyMap objectMap;
398 private PropertyMap functionMap;
399 private PropertyMap anonymousFunctionMap;
400 private PropertyMap strictFunctionMap;
401 private PropertyMap boundFunctionMap;
403 // Flag to indicate that a split method issued a return statement
404 private int splitState = -1;
406 // class cache
407 private ClassCache classCache;
409 // Used to store the last RegExp result to support deprecated RegExp constructor properties
410 private RegExpResult lastRegExpResult;
412 private static final MethodHandle EVAL = findOwnMH("eval", Object.class, Object.class, Object.class);
413 private static final MethodHandle PRINT = findOwnMH("print", Object.class, Object.class, Object[].class);
414 private static final MethodHandle PRINTLN = findOwnMH("println", Object.class, Object.class, Object[].class);
415 private static final MethodHandle LOAD = findOwnMH("load", Object.class, Object.class, Object.class);
416 private static final MethodHandle LOADWITHNEWGLOBAL = findOwnMH("loadWithNewGlobal", Object.class, Object.class, Object[].class);
417 private static final MethodHandle EXIT = findOwnMH("exit", Object.class, Object.class, Object.class);
419 // initialized by nasgen
420 private static PropertyMap $nasgenmap$;
422 // context to which this global belongs to
423 private final Context context;
425 @Override
426 protected Context getContext() {
427 return context;
428 }
430 // performs initialization checks for Global constructor and returns the
431 // PropertyMap, if everything is fine.
432 private static PropertyMap checkAndGetMap(final Context context) {
433 // security check first
434 final SecurityManager sm = System.getSecurityManager();
435 if (sm != null) {
436 sm.checkPermission(new RuntimePermission(Context.NASHORN_CREATE_GLOBAL));
437 }
439 // null check on context
440 context.getClass();
442 /*
443 * Duplicate global's map and use it. This way the initial Map filled
444 * by nasgen (referenced from static field in this class) is retained
445 * 'as is' (as that one is process wide singleton.
446 */
447 return $nasgenmap$.duplicate();
448 }
450 /**
451 * Constructor
452 *
453 * @param context the context
454 */
455 public Global(final Context context) {
456 super(checkAndGetMap(context));
457 this.context = context;
458 this.setIsScope();
460 final int cacheSize = context.getEnv()._class_cache_size;
461 if (cacheSize > 0) {
462 classCache = new ClassCache(cacheSize);
463 }
464 }
466 /**
467 * Script access to "current" Global instance
468 *
469 * @return the global singleton
470 */
471 public static Global instance() {
472 ScriptObject global = Context.getGlobal();
473 if (! (global instanceof Global)) {
474 throw new IllegalStateException("no current global instance");
475 }
476 return (Global)global;
477 }
479 /**
480 * Script access to {@link ScriptEnvironment}
481 *
482 * @return the script environment
483 */
484 static ScriptEnvironment getEnv() {
485 return instance().getContext().getEnv();
486 }
488 /**
489 * Script access to {@link Context}
490 *
491 * @return the context
492 */
493 static Context getThisContext() {
494 return instance().getContext();
495 }
497 // GlobalObject interface implementation
499 @Override
500 public boolean isOfContext(final Context ctxt) {
501 return this.context == ctxt;
502 }
504 @Override
505 public boolean isStrictContext() {
506 return context.getEnv()._strict;
507 }
509 @Override
510 public void initBuiltinObjects() {
511 if (this.builtinObject != null) {
512 // already initialized, just return
513 return;
514 }
516 init();
517 }
519 @Override
520 public ScriptFunction newScriptFunction(final String name, final MethodHandle handle, final ScriptObject scope, final boolean strict) {
521 return new ScriptFunctionImpl(name, handle, scope, null, strict, false, true);
522 }
524 @Override
525 public Object wrapAsObject(final Object obj) {
526 if (obj instanceof Boolean) {
527 return new NativeBoolean((Boolean)obj, this);
528 } else if (obj instanceof Number) {
529 return new NativeNumber(((Number)obj).doubleValue(), this);
530 } else if (obj instanceof String || obj instanceof ConsString) {
531 return new NativeString((CharSequence)obj, this);
532 } else if (obj instanceof Object[]) { // extension
533 return new NativeArray((Object[])obj);
534 } else if (obj instanceof double[]) { // extension
535 return new NativeArray((double[])obj);
536 } else if (obj instanceof long[]) {
537 return new NativeArray((long[])obj);
538 } else if (obj instanceof int[]) {
539 return new NativeArray((int[])obj);
540 } else {
541 // FIXME: more special cases? Map? List?
542 return obj;
543 }
544 }
546 @Override
547 public GuardedInvocation primitiveLookup(final LinkRequest request, final Object self) {
548 if (self instanceof String || self instanceof ConsString) {
549 return NativeString.lookupPrimitive(request, self);
550 } else if (self instanceof Number) {
551 return NativeNumber.lookupPrimitive(request, self);
552 } else if (self instanceof Boolean) {
553 return NativeBoolean.lookupPrimitive(request, self);
554 }
555 throw new IllegalArgumentException("Unsupported primitive: " + self);
556 }
558 @Override
559 public ScriptObject newObject() {
560 return new JO(getObjectPrototype(), getObjectMap());
561 }
563 @Override
564 public Object getDefaultValue(final ScriptObject sobj, final Class<?> typeHint) {
565 // When the [[DefaultValue]] internal method of O is called with no hint,
566 // then it behaves as if the hint were Number, unless O is a Date object
567 // in which case it behaves as if the hint were String.
568 Class<?> hint = typeHint;
569 if (hint == null) {
570 hint = Number.class;
571 }
573 try {
574 if (hint == String.class) {
576 final Object toString = TO_STRING.getGetter().invokeExact(sobj);
578 if (Bootstrap.isCallable(toString)) {
579 final Object value = TO_STRING.getInvoker().invokeExact(toString, sobj);
580 if (JSType.isPrimitive(value)) {
581 return value;
582 }
583 }
585 final Object valueOf = VALUE_OF.getGetter().invokeExact(sobj);
586 if (Bootstrap.isCallable(valueOf)) {
587 final Object value = VALUE_OF.getInvoker().invokeExact(valueOf, sobj);
588 if (JSType.isPrimitive(value)) {
589 return value;
590 }
591 }
592 throw typeError(this, "cannot.get.default.string");
593 }
595 if (hint == Number.class) {
596 final Object valueOf = VALUE_OF.getGetter().invokeExact(sobj);
597 if (Bootstrap.isCallable(valueOf)) {
598 final Object value = VALUE_OF.getInvoker().invokeExact(valueOf, sobj);
599 if (JSType.isPrimitive(value)) {
600 return value;
601 }
602 }
604 final Object toString = TO_STRING.getGetter().invokeExact(sobj);
605 if (Bootstrap.isCallable(toString)) {
606 final Object value = TO_STRING.getInvoker().invokeExact(toString, sobj);
607 if (JSType.isPrimitive(value)) {
608 return value;
609 }
610 }
612 throw typeError(this, "cannot.get.default.number");
613 }
614 } catch (final RuntimeException | Error e) {
615 throw e;
616 } catch (final Throwable t) {
617 throw new RuntimeException(t);
618 }
620 return UNDEFINED;
621 }
623 @Override
624 public boolean isError(final ScriptObject sobj) {
625 final ScriptObject errorProto = getErrorPrototype();
626 ScriptObject proto = sobj.getProto();
627 while (proto != null) {
628 if (proto == errorProto) {
629 return true;
630 }
631 proto = proto.getProto();
632 }
633 return false;
634 }
636 @Override
637 public ScriptObject newError(final String msg) {
638 return new NativeError(msg, this);
639 }
641 @Override
642 public ScriptObject newEvalError(final String msg) {
643 return new NativeEvalError(msg, this);
644 }
646 @Override
647 public ScriptObject newRangeError(final String msg) {
648 return new NativeRangeError(msg, this);
649 }
651 @Override
652 public ScriptObject newReferenceError(final String msg) {
653 return new NativeReferenceError(msg, this);
654 }
656 @Override
657 public ScriptObject newSyntaxError(final String msg) {
658 return new NativeSyntaxError(msg, this);
659 }
661 @Override
662 public ScriptObject newTypeError(final String msg) {
663 return new NativeTypeError(msg, this);
664 }
666 @Override
667 public ScriptObject newURIError(final String msg) {
668 return new NativeURIError(msg, this);
669 }
671 @Override
672 public PropertyDescriptor newGenericDescriptor(final boolean configurable, final boolean enumerable) {
673 return new GenericPropertyDescriptor(configurable, enumerable, this);
674 }
676 @Override
677 public PropertyDescriptor newDataDescriptor(final Object value, final boolean configurable, final boolean enumerable, final boolean writable) {
678 return new DataPropertyDescriptor(configurable, enumerable, writable, value, this);
679 }
681 @Override
682 public PropertyDescriptor newAccessorDescriptor(final Object get, final Object set, final boolean configurable, final boolean enumerable) {
683 final AccessorPropertyDescriptor desc = new AccessorPropertyDescriptor(configurable, enumerable, get == null ? UNDEFINED : get, set == null ? UNDEFINED : set, this);
685 if (get == null) {
686 desc.delete(PropertyDescriptor.GET, false);
687 }
689 if (set == null) {
690 desc.delete(PropertyDescriptor.SET, false);
691 }
693 return desc;
694 }
697 /**
698 * Cache for compiled script classes.
699 */
700 @SuppressWarnings("serial")
701 private static class ClassCache extends LinkedHashMap<Source, ClassReference> {
702 private final int size;
703 private final ReferenceQueue<Class<?>> queue;
705 ClassCache(int size) {
706 super(size, 0.75f, true);
707 this.size = size;
708 this.queue = new ReferenceQueue<>();
709 }
711 void cache(final Source source, final Class<?> clazz) {
712 put(source, new ClassReference(clazz, queue, source));
713 }
715 @Override
716 protected boolean removeEldestEntry(final Map.Entry<Source, ClassReference> eldest) {
717 return size() > size;
718 }
720 @Override
721 public ClassReference get(Object key) {
722 for (ClassReference ref; (ref = (ClassReference)queue.poll()) != null; ) {
723 remove(ref.source);
724 }
725 return super.get(key);
726 }
728 }
730 private static class ClassReference extends SoftReference<Class<?>> {
731 private final Source source;
733 ClassReference(final Class<?> clazz, final ReferenceQueue<Class<?>> queue, final Source source) {
734 super(clazz, queue);
735 this.source = source;
736 }
737 }
739 // Class cache management
740 @Override
741 public Class<?> findCachedClass(final Source source) {
742 assert classCache != null : "Class cache used without being initialized";
743 ClassReference ref = classCache.get(source);
744 return ref != null ? ref.get() : null;
745 }
747 @Override
748 public void cacheClass(final Source source, final Class<?> clazz) {
749 assert classCache != null : "Class cache used without being initialized";
750 classCache.cache(source, clazz);
751 }
753 private static <T> T getLazilyCreatedValue(final Object key, final Callable<T> creator, final Map<Object, T> map) {
754 final T obj = map.get(key);
755 if (obj != null) {
756 return obj;
757 }
759 try {
760 final T newObj = creator.call();
761 final T existingObj = map.putIfAbsent(key, newObj);
762 return existingObj != null ? existingObj : newObj;
763 } catch (final Exception exp) {
764 throw new RuntimeException(exp);
765 }
766 }
768 private final Map<Object, InvokeByName> namedInvokers = new ConcurrentHashMap<>();
770 @Override
771 public InvokeByName getInvokeByName(final Object key, final Callable<InvokeByName> creator) {
772 return getLazilyCreatedValue(key, creator, namedInvokers);
773 }
775 private final Map<Object, MethodHandle> dynamicInvokers = new ConcurrentHashMap<>();
777 @Override
778 public MethodHandle getDynamicInvoker(final Object key, final Callable<MethodHandle> creator) {
779 return getLazilyCreatedValue(key, creator, dynamicInvokers);
780 }
782 /**
783 * This is the eval used when 'indirect' eval call is made.
784 *
785 * var global = this;
786 * global.eval("print('hello')");
787 *
788 * @param self eval scope
789 * @param str eval string
790 *
791 * @return the result of eval
792 */
793 public static Object eval(final Object self, final Object str) {
794 return directEval(self, str, UNDEFINED, UNDEFINED, UNDEFINED);
795 }
797 /**
798 * Direct eval
799 *
800 * @param self The scope of eval passed as 'self'
801 * @param str Evaluated code
802 * @param callThis "this" to be passed to the evaluated code
803 * @param location location of the eval call
804 * @param strict is eval called a strict mode code?
805 *
806 * @return the return value of the eval
807 *
808 * This is directly invoked from generated when eval(code) is called in user code
809 */
810 public static Object directEval(final Object self, final Object str, final Object callThis, final Object location, final Object strict) {
811 if (!(str instanceof String || str instanceof ConsString)) {
812 return str;
813 }
814 final Global global = Global.instance();
815 final ScriptObject scope = (self instanceof ScriptObject) ? (ScriptObject)self : global;
817 return global.getContext().eval(scope, str.toString(), callThis, location, Boolean.TRUE.equals(strict));
818 }
820 /**
821 * Global print implementation - Nashorn extension
822 *
823 * @param self scope
824 * @param objects arguments to print
825 *
826 * @return result of print (undefined)
827 */
828 public static Object print(final Object self, final Object... objects) {
829 return printImpl(false, objects);
830 }
832 /**
833 * Global println implementation - Nashorn extension
834 *
835 * @param self scope
836 * @param objects arguments to print
837 *
838 * @return result of println (undefined)
839 */
840 public static Object println(final Object self, final Object... objects) {
841 return printImpl(true, objects);
842 }
844 /**
845 * Global load implementation - Nashorn extension
846 *
847 * @param self scope
848 * @param source source to load
849 *
850 * @return result of load (undefined)
851 *
852 * @throws IOException if source could not be read
853 */
854 public static Object load(final Object self, final Object source) throws IOException {
855 final Global global = Global.instance();
856 final ScriptObject scope = (self instanceof ScriptObject) ? (ScriptObject)self : global;
857 return global.getContext().load(scope, source);
858 }
860 /**
861 * Global loadWithNewGlobal implementation - Nashorn extension
862 *
863 * @param self scope
864 * @param args from plus (optional) arguments to be passed to the loaded script
865 *
866 * @return result of load (may be undefined)
867 *
868 * @throws IOException if source could not be read
869 */
870 public static Object loadWithNewGlobal(final Object self, final Object...args) throws IOException {
871 final Global global = Global.instance();
872 final int length = args.length;
873 final boolean hasArgs = 0 < length;
874 final Object from = hasArgs ? args[0] : UNDEFINED;
875 final Object[] arguments = hasArgs ? Arrays.copyOfRange(args, 1, length) : args;
877 return global.getContext().loadWithNewGlobal(from, arguments);
878 }
880 /**
881 * Global exit and quit implementation - Nashorn extension: perform a {@code System.exit} call from the script
882 *
883 * @param self self reference
884 * @param code exit code
885 *
886 * @return undefined (will never be reacheD)
887 */
888 public static Object exit(final Object self, final Object code) {
889 System.exit(JSType.toInt32(code));
890 return UNDEFINED;
891 }
893 // builtin prototype accessors
894 ScriptObject getFunctionPrototype() {
895 return ScriptFunction.getPrototype(builtinFunction);
896 }
898 ScriptObject getObjectPrototype() {
899 return ScriptFunction.getPrototype(builtinObject);
900 }
902 ScriptObject getArrayPrototype() {
903 return ScriptFunction.getPrototype(builtinArray);
904 }
906 ScriptObject getBooleanPrototype() {
907 return ScriptFunction.getPrototype(builtinBoolean);
908 }
910 ScriptObject getNumberPrototype() {
911 return ScriptFunction.getPrototype(builtinNumber);
912 }
914 ScriptObject getDatePrototype() {
915 return ScriptFunction.getPrototype(builtinDate);
916 }
918 ScriptObject getRegExpPrototype() {
919 return ScriptFunction.getPrototype(builtinRegExp);
920 }
922 ScriptObject getStringPrototype() {
923 return ScriptFunction.getPrototype(builtinString);
924 }
926 ScriptObject getErrorPrototype() {
927 return ScriptFunction.getPrototype(builtinError);
928 }
930 ScriptObject getEvalErrorPrototype() {
931 return ScriptFunction.getPrototype(builtinEvalError);
932 }
934 ScriptObject getRangeErrorPrototype() {
935 return ScriptFunction.getPrototype(builtinRangeError);
936 }
938 ScriptObject getReferenceErrorPrototype() {
939 return ScriptFunction.getPrototype(builtinReferenceError);
940 }
942 ScriptObject getSyntaxErrorPrototype() {
943 return ScriptFunction.getPrototype(builtinSyntaxError);
944 }
946 ScriptObject getTypeErrorPrototype() {
947 return ScriptFunction.getPrototype(builtinTypeError);
948 }
950 ScriptObject getURIErrorPrototype() {
951 return ScriptFunction.getPrototype(builtinURIError);
952 }
954 ScriptObject getJavaImporterPrototype() {
955 return ScriptFunction.getPrototype(builtinJavaImporter);
956 }
958 ScriptObject getJSAdapterPrototype() {
959 return ScriptFunction.getPrototype(builtinJSAdapter);
960 }
962 ScriptObject getArrayBufferPrototype() {
963 return ScriptFunction.getPrototype(builtinArrayBuffer);
964 }
966 ScriptObject getInt8ArrayPrototype() {
967 return ScriptFunction.getPrototype(builtinInt8Array);
968 }
970 ScriptObject getUint8ArrayPrototype() {
971 return ScriptFunction.getPrototype(builtinUint8Array);
972 }
974 ScriptObject getUint8ClampedArrayPrototype() {
975 return ScriptFunction.getPrototype(builtinUint8ClampedArray);
976 }
978 ScriptObject getInt16ArrayPrototype() {
979 return ScriptFunction.getPrototype(builtinInt16Array);
980 }
982 ScriptObject getUint16ArrayPrototype() {
983 return ScriptFunction.getPrototype(builtinUint16Array);
984 }
986 ScriptObject getInt32ArrayPrototype() {
987 return ScriptFunction.getPrototype(builtinInt32Array);
988 }
990 ScriptObject getUint32ArrayPrototype() {
991 return ScriptFunction.getPrototype(builtinUint32Array);
992 }
994 ScriptObject getFloat32ArrayPrototype() {
995 return ScriptFunction.getPrototype(builtinFloat32Array);
996 }
998 ScriptObject getFloat64ArrayPrototype() {
999 return ScriptFunction.getPrototype(builtinFloat64Array);
1000 }
1002 // Builtin PropertyMap accessors
1003 PropertyMap getAccessorPropertyDescriptorMap() {
1004 return accessorPropertyDescriptorMap;
1005 }
1007 PropertyMap getArrayBufferViewMap() {
1008 return arrayBufferViewMap;
1009 }
1011 PropertyMap getDataPropertyDescriptorMap() {
1012 return dataPropertyDescriptorMap;
1013 }
1015 PropertyMap getGenericPropertyDescriptorMap() {
1016 return genericPropertyDescriptorMap;
1017 }
1019 PropertyMap getArgumentsMap() {
1020 return nativeArgumentsMap;
1021 }
1023 PropertyMap getArrayMap() {
1024 return nativeArrayMap;
1025 }
1027 PropertyMap getArrayBufferMap() {
1028 return nativeArrayBufferMap;
1029 }
1031 PropertyMap getBooleanMap() {
1032 return nativeBooleanMap;
1033 }
1035 PropertyMap getDateMap() {
1036 return nativeDateMap;
1037 }
1039 PropertyMap getErrorMap() {
1040 return nativeErrorMap;
1041 }
1043 PropertyMap getEvalErrorMap() {
1044 return nativeEvalErrorMap;
1045 }
1047 PropertyMap getJSAdapterMap() {
1048 return nativeJSAdapterMap;
1049 }
1051 PropertyMap getJavaImporterMap() {
1052 return nativeJavaImporterMap;
1053 }
1055 PropertyMap getNumberMap() {
1056 return nativeNumberMap;
1057 }
1059 PropertyMap getRangeErrorMap() {
1060 return nativeRangeErrorMap;
1061 }
1063 PropertyMap getReferenceErrorMap() {
1064 return nativeReferenceErrorMap;
1065 }
1067 PropertyMap getRegExpMap() {
1068 return nativeRegExpMap;
1069 }
1071 PropertyMap getRegExpExecResultMap() {
1072 return nativeRegExpExecResultMap;
1073 }
1075 PropertyMap getStrictArgumentsMap() {
1076 return nativeStrictArgumentsMap;
1077 }
1079 PropertyMap getStringMap() {
1080 return nativeStringMap;
1081 }
1083 PropertyMap getSyntaxErrorMap() {
1084 return nativeSyntaxErrorMap;
1085 }
1087 PropertyMap getTypeErrorMap() {
1088 return nativeTypeErrorMap;
1089 }
1091 PropertyMap getURIErrorMap() {
1092 return nativeURIErrorMap;
1093 }
1095 PropertyMap getPrototypeObjectMap() {
1096 return prototypeObjectMap;
1097 }
1099 PropertyMap getObjectMap() {
1100 return objectMap;
1101 }
1103 PropertyMap getFunctionMap() {
1104 return functionMap;
1105 }
1107 PropertyMap getAnonymousFunctionMap() {
1108 return anonymousFunctionMap;
1109 }
1111 PropertyMap getStrictFunctionMap() {
1112 return strictFunctionMap;
1113 }
1115 PropertyMap getBoundFunctionMap() {
1116 return boundFunctionMap;
1117 }
1119 private ScriptFunction getBuiltinArray() {
1120 return builtinArray;
1121 }
1123 ScriptFunction getTypeErrorThrower() {
1124 return typeErrorThrower;
1125 }
1127 /**
1128 * Called from compiled script code to test if builtin has been overridden
1129 *
1130 * @return true if builtin array has not been overridden
1131 */
1132 public static boolean isBuiltinArray() {
1133 final Global instance = Global.instance();
1134 return instance.array == instance.getBuiltinArray();
1135 }
1137 private ScriptFunction getBuiltinBoolean() {
1138 return builtinBoolean;
1139 }
1141 /**
1142 * Called from compiled script code to test if builtin has been overridden
1143 *
1144 * @return true if builtin boolean has not been overridden
1145 */
1146 public static boolean isBuiltinBoolean() {
1147 final Global instance = Global.instance();
1148 return instance._boolean == instance.getBuiltinBoolean();
1149 }
1151 private ScriptFunction getBuiltinDate() {
1152 return builtinDate;
1153 }
1155 /**
1156 * Called from compiled script code to test if builtin has been overridden
1157 *
1158 * @return true if builtin date has not been overridden
1159 */
1160 public static boolean isBuiltinDate() {
1161 final Global instance = Global.instance();
1162 return instance.date == instance.getBuiltinDate();
1163 }
1165 private ScriptFunction getBuiltinError() {
1166 return builtinError;
1167 }
1169 /**
1170 * Called from compiled script code to test if builtin has been overridden
1171 *
1172 * @return true if builtin error has not been overridden
1173 */
1174 public static boolean isBuiltinError() {
1175 final Global instance = Global.instance();
1176 return instance.error == instance.getBuiltinError();
1177 }
1179 private ScriptFunction getBuiltinEvalError() {
1180 return builtinEvalError;
1181 }
1183 /**
1184 * Called from compiled script code to test if builtin has been overridden
1185 *
1186 * @return true if builtin eval error has not been overridden
1187 */
1188 public static boolean isBuiltinEvalError() {
1189 final Global instance = Global.instance();
1190 return instance.evalError == instance.getBuiltinEvalError();
1191 }
1193 private ScriptFunction getBuiltinFunction() {
1194 return builtinFunction;
1195 }
1197 /**
1198 * Called from compiled script code to test if builtin has been overridden
1199 *
1200 * @return true if builtin function has not been overridden
1201 */
1202 public static boolean isBuiltinFunction() {
1203 final Global instance = Global.instance();
1204 return instance.function == instance.getBuiltinFunction();
1205 }
1207 private ScriptFunction getBuiltinJSAdapter() {
1208 return builtinJSAdapter;
1209 }
1211 /**
1212 * Called from compiled script code to test if builtin has been overridden
1213 *
1214 * @return true if builtin JSAdapter has not been overridden
1215 */
1216 public static boolean isBuiltinJSAdapter() {
1217 final Global instance = Global.instance();
1218 return instance.jsadapter == instance.getBuiltinJSAdapter();
1219 }
1221 private ScriptObject getBuiltinJSON() {
1222 return builtinJSON;
1223 }
1225 /**
1226 * Called from compiled script code to test if builtin has been overridden
1227 *
1228 * @return true if builtin JSON has has not been overridden
1229 */
1230 public static boolean isBuiltinJSON() {
1231 final Global instance = Global.instance();
1232 return instance.json == instance.getBuiltinJSON();
1233 }
1235 private ScriptObject getBuiltinJava() {
1236 return builtinJava;
1237 }
1239 /**
1240 * Called from compiled script code to test if builtin has been overridden
1241 *
1242 * @return true if builtin Java has not been overridden
1243 */
1244 public static boolean isBuiltinJava() {
1245 final Global instance = Global.instance();
1246 return instance.java == instance.getBuiltinJava();
1247 }
1249 private ScriptObject getBuiltinJavax() {
1250 return builtinJavax;
1251 }
1253 /**
1254 * Called from compiled script code to test if builtin has been overridden
1255 *
1256 * @return true if builtin Javax has not been overridden
1257 */
1258 public static boolean isBuiltinJavax() {
1259 final Global instance = Global.instance();
1260 return instance.javax == instance.getBuiltinJavax();
1261 }
1263 private ScriptObject getBuiltinJavaImporter() {
1264 return builtinJavaImporter;
1265 }
1267 /**
1268 * Called from compiled script code to test if builtin has been overridden
1269 *
1270 * @return true if builtin Java importer has not been overridden
1271 */
1272 public static boolean isBuiltinJavaImporter() {
1273 final Global instance = Global.instance();
1274 return instance.javaImporter == instance.getBuiltinJavaImporter();
1275 }
1277 private ScriptObject getBuiltinMath() {
1278 return builtinMath;
1279 }
1281 /**
1282 * Called from compiled script code to test if builtin has been overridden
1283 *
1284 * @return true if builtin math has not been overridden
1285 */
1286 public static boolean isBuiltinMath() {
1287 final Global instance = Global.instance();
1288 return instance.math == instance.getBuiltinMath();
1289 }
1291 private ScriptFunction getBuiltinNumber() {
1292 return builtinNumber;
1293 }
1295 /**
1296 * Called from compiled script code to test if builtin has been overridden
1297 *
1298 * @return true if builtin number has not been overridden
1299 */
1300 public static boolean isBuiltinNumber() {
1301 final Global instance = Global.instance();
1302 return instance.number == instance.getBuiltinNumber();
1303 }
1305 private ScriptFunction getBuiltinObject() {
1306 return builtinObject;
1307 }
1309 /**
1310 * Called from compiled script code to test if builtin has been overridden
1311 *
1312 * @return true if builtin object has not been overridden
1313 */
1314 public static boolean isBuiltinObject() {
1315 final Global instance = Global.instance();
1316 return instance.object == instance.getBuiltinObject();
1317 }
1319 private ScriptObject getBuiltinPackages() {
1320 return builtinPackages;
1321 }
1323 /**
1324 * Called from compiled script code to test if builtin has been overridden
1325 *
1326 * @return true if builtin package has not been overridden
1327 */
1328 public static boolean isBuiltinPackages() {
1329 final Global instance = Global.instance();
1330 return instance.packages == instance.getBuiltinPackages();
1331 }
1333 private ScriptFunction getBuiltinRangeError() {
1334 return builtinRangeError;
1335 }
1337 /**
1338 * Called from compiled script code to test if builtin has been overridden
1339 *
1340 * @return true if builtin range error has not been overridden
1341 */
1342 public static boolean isBuiltinRangeError() {
1343 final Global instance = Global.instance();
1344 return instance.rangeError == instance.getBuiltinRangeError();
1345 }
1347 private ScriptFunction getBuiltinReferenceError() {
1348 return builtinReferenceError;
1349 }
1351 /**
1352 * Called from compiled script code to test if builtin has been overridden
1353 *
1354 * @return true if builtin reference error has not been overridden
1355 */
1356 public static boolean isBuiltinReferenceError() {
1357 final Global instance = Global.instance();
1358 return instance.referenceError == instance.getBuiltinReferenceError();
1359 }
1361 private ScriptFunction getBuiltinRegExp() {
1362 return builtinRegExp;
1363 }
1365 /**
1366 * Called from compiled script code to test if builtin has been overridden
1367 *
1368 * @return true if builtin regexp has not been overridden
1369 */
1370 public static boolean isBuiltinRegExp() {
1371 final Global instance = Global.instance();
1372 return instance.regexp == instance.getBuiltinRegExp();
1373 }
1375 private ScriptFunction getBuiltinString() {
1376 return builtinString;
1377 }
1379 /**
1380 * Called from compiled script code to test if builtin has been overridden
1381 *
1382 * @return true if builtin Java has not been overridden
1383 */
1384 public static boolean isBuiltinString() {
1385 final Global instance = Global.instance();
1386 return instance.string == instance.getBuiltinString();
1387 }
1389 private ScriptFunction getBuiltinSyntaxError() {
1390 return builtinSyntaxError;
1391 }
1393 /**
1394 * Called from compiled script code to test if builtin has been overridden
1395 *
1396 * @return true if builtin syntax error has not been overridden
1397 */
1398 public static boolean isBuiltinSyntaxError() {
1399 final Global instance = Global.instance();
1400 return instance.syntaxError == instance.getBuiltinSyntaxError();
1401 }
1403 private ScriptFunction getBuiltinTypeError() {
1404 return builtinTypeError;
1405 }
1407 /**
1408 * Called from compiled script code to test if builtin has been overridden
1409 *
1410 * @return true if builtin type error has not been overridden
1411 */
1412 public static boolean isBuiltinTypeError() {
1413 final Global instance = Global.instance();
1414 return instance.typeError == instance.getBuiltinTypeError();
1415 }
1417 private ScriptFunction getBuiltinURIError() {
1418 return builtinURIError;
1419 }
1421 /**
1422 * Called from compiled script code to test if builtin has been overridden
1423 *
1424 * @return true if builtin URI error has not been overridden
1425 */
1426 public static boolean isBuiltinURIError() {
1427 final Global instance = Global.instance();
1428 return instance.uriError == instance.getBuiltinURIError();
1429 }
1431 @Override
1432 public String getClassName() {
1433 return "global";
1434 }
1436 /**
1437 * Copy function used to clone NativeRegExp objects.
1438 *
1439 * @param regexp a NativeRegExp to clone
1440 *
1441 * @return copy of the given regexp object
1442 */
1443 public static Object regExpCopy(final Object regexp) {
1444 return new NativeRegExp((NativeRegExp)regexp);
1445 }
1447 /**
1448 * Convert given object to NativeRegExp type.
1449 *
1450 * @param obj object to be converted
1451 * @return NativeRegExp instance
1452 */
1453 public static NativeRegExp toRegExp(final Object obj) {
1454 if (obj instanceof NativeRegExp) {
1455 return (NativeRegExp)obj;
1456 }
1457 return new NativeRegExp(JSType.toString(obj));
1458 }
1460 /**
1461 * ECMA 9.9 ToObject implementation
1462 *
1463 * @param obj an item for which to run ToObject
1464 * @return ToObject version of given item
1465 */
1466 public static Object toObject(final Object obj) {
1467 if (obj == null || obj == UNDEFINED) {
1468 throw typeError("not.an.object", ScriptRuntime.safeToString(obj));
1469 }
1471 if (obj instanceof ScriptObject) {
1472 return obj;
1473 }
1475 return instance().wrapAsObject(obj);
1476 }
1478 /**
1479 * Allocate a new object array.
1480 *
1481 * @param initial object values.
1482 * @return the new array
1483 */
1484 public static NativeArray allocate(final Object[] initial) {
1485 ArrayData arrayData = ArrayData.allocate(initial);
1487 for (int index = 0; index < initial.length; index++) {
1488 final Object value = initial[index];
1490 if (value == ScriptRuntime.EMPTY) {
1491 arrayData = arrayData.delete(index);
1492 }
1493 }
1495 return new NativeArray(arrayData);
1496 }
1498 /**
1499 * Allocate a new number array.
1500 *
1501 * @param initial number values.
1502 * @return the new array
1503 */
1504 public static NativeArray allocate(final double[] initial) {
1505 return new NativeArray(ArrayData.allocate(initial));
1506 }
1508 /**
1509 * Allocate a new long array.
1510 *
1511 * @param initial number values.
1512 * @return the new array
1513 */
1514 public static NativeArray allocate(final long[] initial) {
1515 return new NativeArray(ArrayData.allocate(initial));
1516 }
1518 /**
1519 * Allocate a new integer array.
1520 *
1521 * @param initial number values.
1522 * @return the new array
1523 */
1524 public static NativeArray allocate(final int[] initial) {
1525 return new NativeArray(ArrayData.allocate(initial));
1526 }
1528 /**
1529 * Allocate a new object array for arguments.
1530 *
1531 * @param arguments initial arguments passed.
1532 * @param callee reference to the function that uses arguments object
1533 * @param numParams actual number of declared parameters
1534 *
1535 * @return the new array
1536 */
1537 public static ScriptObject allocateArguments(final Object[] arguments, final Object callee, final int numParams) {
1538 return NativeArguments.allocate(arguments, (ScriptFunction)callee, numParams);
1539 }
1541 /**
1542 * Called from generated to check if given function is the builtin 'eval'. If
1543 * eval is used in a script, a lot of optimizations and assumptions cannot be done.
1544 *
1545 * @param fn function object that is checked
1546 * @return true if fn is the builtin eval
1547 */
1548 public static boolean isEval(final Object fn) {
1549 return fn == Global.instance().builtinEval;
1550 }
1552 /**
1553 * Create a new RegExp object.
1554 *
1555 * @param expression Regular expression.
1556 * @param options Search options.
1557 *
1558 * @return New RegExp object.
1559 */
1560 public static Object newRegExp(final String expression, final String options) {
1561 if (options == null) {
1562 return new NativeRegExp(expression);
1563 }
1564 return new NativeRegExp(expression, options);
1565 }
1567 /**
1568 * Get the object prototype
1569 *
1570 * @return the object prototype
1571 */
1572 public static ScriptObject objectPrototype() {
1573 return Global.instance().getObjectPrototype();
1574 }
1576 /**
1577 * Create a new empty object instance.
1578 *
1579 * @return New empty object.
1580 */
1581 public static ScriptObject newEmptyInstance() {
1582 return Global.instance().newObject();
1583 }
1585 /**
1586 * Check if a given object is a ScriptObject, raises an exception if this is
1587 * not the case
1588 *
1589 * @param obj and object to check
1590 */
1591 public static void checkObject(final Object obj) {
1592 if (!(obj instanceof ScriptObject)) {
1593 throw typeError("not.an.object", ScriptRuntime.safeToString(obj));
1594 }
1595 }
1597 /**
1598 * ECMA 9.10 - implementation of CheckObjectCoercible, i.e. raise an exception
1599 * if this object is null or undefined.
1600 *
1601 * @param obj an object to check
1602 */
1603 public static void checkObjectCoercible(final Object obj) {
1604 if (obj == null || obj == UNDEFINED) {
1605 throw typeError("not.an.object", ScriptRuntime.safeToString(obj));
1606 }
1607 }
1609 /**
1610 * Get the current split state.
1611 *
1612 * @return current split state
1613 */
1614 @Override
1615 public int getSplitState() {
1616 return splitState;
1617 }
1619 /**
1620 * Set the current split state.
1621 *
1622 * @param state current split state
1623 */
1624 @Override
1625 public void setSplitState(final int state) {
1626 splitState = state;
1627 }
1629 private void init() {
1630 assert Context.getGlobal() == this : "this global is not set as current";
1632 final ScriptEnvironment env = getContext().getEnv();
1634 // duplicate PropertyMaps of Native* classes
1635 copyInitialMaps(env);
1637 // initialize Function and Object constructor
1638 initFunctionAndObject();
1640 // Now fix Global's own proto.
1641 this.setProto(getObjectPrototype());
1643 // initialize global function properties
1644 this.eval = this.builtinEval = ScriptFunctionImpl.makeFunction("eval", EVAL);
1646 this.parseInt = ScriptFunctionImpl.makeFunction("parseInt", GlobalFunctions.PARSEINT);
1647 this.parseFloat = ScriptFunctionImpl.makeFunction("parseFloat", GlobalFunctions.PARSEFLOAT);
1648 this.isNaN = ScriptFunctionImpl.makeFunction("isNaN", GlobalFunctions.IS_NAN);
1649 this.isFinite = ScriptFunctionImpl.makeFunction("isFinite", GlobalFunctions.IS_FINITE);
1650 this.encodeURI = ScriptFunctionImpl.makeFunction("encodeURI", GlobalFunctions.ENCODE_URI);
1651 this.encodeURIComponent = ScriptFunctionImpl.makeFunction("encodeURIComponent", GlobalFunctions.ENCODE_URICOMPONENT);
1652 this.decodeURI = ScriptFunctionImpl.makeFunction("decodeURI", GlobalFunctions.DECODE_URI);
1653 this.decodeURIComponent = ScriptFunctionImpl.makeFunction("decodeURIComponent", GlobalFunctions.DECODE_URICOMPONENT);
1654 this.escape = ScriptFunctionImpl.makeFunction("escape", GlobalFunctions.ESCAPE);
1655 this.unescape = ScriptFunctionImpl.makeFunction("unescape", GlobalFunctions.UNESCAPE);
1656 this.print = ScriptFunctionImpl.makeFunction("print", env._print_no_newline ? PRINT : PRINTLN);
1657 this.load = ScriptFunctionImpl.makeFunction("load", LOAD);
1658 this.loadWithNewGlobal = ScriptFunctionImpl.makeFunction("loadWithNewGlobal", LOADWITHNEWGLOBAL);
1659 this.exit = ScriptFunctionImpl.makeFunction("exit", EXIT);
1660 this.quit = ScriptFunctionImpl.makeFunction("quit", EXIT);
1662 // built-in constructors
1663 this.builtinArray = (ScriptFunction)initConstructor("Array");
1664 this.builtinBoolean = (ScriptFunction)initConstructor("Boolean");
1665 this.builtinDate = (ScriptFunction)initConstructor("Date");
1666 this.builtinJSON = initConstructor("JSON");
1667 this.builtinJSAdapter = (ScriptFunction)initConstructor("JSAdapter");
1668 this.builtinMath = initConstructor("Math");
1669 this.builtinNumber = (ScriptFunction)initConstructor("Number");
1670 this.builtinRegExp = (ScriptFunction)initConstructor("RegExp");
1671 this.builtinString = (ScriptFunction)initConstructor("String");
1673 // initialize String.prototype.length to 0
1674 // add String.prototype.length
1675 final ScriptObject stringPrototype = getStringPrototype();
1676 stringPrototype.addOwnProperty("length", Attribute.NON_ENUMERABLE_CONSTANT, 0.0);
1678 // set isArray flag on Array.prototype
1679 final ScriptObject arrayPrototype = getArrayPrototype();
1680 arrayPrototype.setIsArray();
1682 this.DEFAULT_DATE = new NativeDate(Double.NaN, this);
1684 // initialize default regexp object
1685 this.DEFAULT_REGEXP = new NativeRegExp("(?:)", this);
1687 // RegExp.prototype should behave like a RegExp object. So copy the
1688 // properties.
1689 final ScriptObject regExpProto = getRegExpPrototype();
1690 regExpProto.addBoundProperties(DEFAULT_REGEXP);
1692 // Error stuff
1693 initErrorObjects();
1695 // java access
1696 if (! env._no_java) {
1697 initJavaAccess();
1698 }
1700 if (! env._no_typed_arrays) {
1701 initTypedArray();
1702 }
1704 if (env._scripting) {
1705 initScripting(env);
1706 }
1708 if (Context.DEBUG) {
1709 boolean debugOkay;
1710 final SecurityManager sm = System.getSecurityManager();
1711 if (sm != null) {
1712 try {
1713 sm.checkPermission(new RuntimePermission(Context.NASHORN_DEBUG_MODE));
1714 debugOkay = true;
1715 } catch (final SecurityException ignored) {
1716 // if no permission, don't initialize Debug object
1717 debugOkay = false;
1718 }
1720 } else {
1721 debugOkay = true;
1722 }
1724 if (debugOkay) {
1725 initDebug();
1726 }
1727 }
1729 copyBuiltins();
1731 // initialized with strings so that typeof will work as expected.
1732 this.__FILE__ = "";
1733 this.__DIR__ = "";
1734 this.__LINE__ = 0.0;
1736 // expose script (command line) arguments as "arguments" property of global
1737 final List<String> arguments = env.getArguments();
1738 final Object argsObj = wrapAsObject(arguments.toArray());
1740 addOwnProperty("arguments", Attribute.NOT_ENUMERABLE, argsObj);
1741 if (env._scripting) {
1742 // synonym for "arguments" in scripting mode
1743 addOwnProperty("$ARG", Attribute.NOT_ENUMERABLE, argsObj);
1744 }
1745 }
1747 private void initErrorObjects() {
1748 // Error objects
1749 this.builtinError = (ScriptFunction)initConstructor("Error");
1750 final ScriptObject errorProto = getErrorPrototype();
1752 // Nashorn specific accessors on Error.prototype - stack, lineNumber, columnNumber and fileName
1753 final ScriptFunction getStack = ScriptFunctionImpl.makeFunction("getStack", NativeError.GET_STACK);
1754 final ScriptFunction setStack = ScriptFunctionImpl.makeFunction("setStack", NativeError.SET_STACK);
1755 errorProto.addOwnProperty("stack", Attribute.NOT_ENUMERABLE, getStack, setStack);
1756 final ScriptFunction getLineNumber = ScriptFunctionImpl.makeFunction("getLineNumber", NativeError.GET_LINENUMBER);
1757 final ScriptFunction setLineNumber = ScriptFunctionImpl.makeFunction("setLineNumber", NativeError.SET_LINENUMBER);
1758 errorProto.addOwnProperty("lineNumber", Attribute.NOT_ENUMERABLE, getLineNumber, setLineNumber);
1759 final ScriptFunction getColumnNumber = ScriptFunctionImpl.makeFunction("getColumnNumber", NativeError.GET_COLUMNNUMBER);
1760 final ScriptFunction setColumnNumber = ScriptFunctionImpl.makeFunction("setColumnNumber", NativeError.SET_COLUMNNUMBER);
1761 errorProto.addOwnProperty("columnNumber", Attribute.NOT_ENUMERABLE, getColumnNumber, setColumnNumber);
1762 final ScriptFunction getFileName = ScriptFunctionImpl.makeFunction("getFileName", NativeError.GET_FILENAME);
1763 final ScriptFunction setFileName = ScriptFunctionImpl.makeFunction("setFileName", NativeError.SET_FILENAME);
1764 errorProto.addOwnProperty("fileName", Attribute.NOT_ENUMERABLE, getFileName, setFileName);
1766 // ECMA 15.11.4.2 Error.prototype.name
1767 // Error.prototype.name = "Error";
1768 errorProto.set(NativeError.NAME, "Error", false);
1769 // ECMA 15.11.4.3 Error.prototype.message
1770 // Error.prototype.message = "";
1771 errorProto.set(NativeError.MESSAGE, "", false);
1773 this.builtinEvalError = initErrorSubtype("EvalError", errorProto);
1774 this.builtinRangeError = initErrorSubtype("RangeError", errorProto);
1775 this.builtinReferenceError = initErrorSubtype("ReferenceError", errorProto);
1776 this.builtinSyntaxError = initErrorSubtype("SyntaxError", errorProto);
1777 this.builtinTypeError = initErrorSubtype("TypeError", errorProto);
1778 this.builtinURIError = initErrorSubtype("URIError", errorProto);
1779 }
1781 private ScriptFunction initErrorSubtype(final String name, final ScriptObject errorProto) {
1782 final ScriptObject cons = initConstructor(name);
1783 final ScriptObject prototype = ScriptFunction.getPrototype(cons);
1784 prototype.set(NativeError.NAME, name, false);
1785 prototype.set(NativeError.MESSAGE, "", false);
1786 prototype.setProto(errorProto);
1787 return (ScriptFunction)cons;
1788 }
1790 private void initJavaAccess() {
1791 final ScriptObject objectProto = getObjectPrototype();
1792 this.builtinPackages = new NativeJavaPackage("", objectProto);
1793 this.builtinCom = new NativeJavaPackage("com", objectProto);
1794 this.builtinEdu = new NativeJavaPackage("edu", objectProto);
1795 this.builtinJava = new NativeJavaPackage("java", objectProto);
1796 this.builtinJavafx = new NativeJavaPackage("javafx", objectProto);
1797 this.builtinJavax = new NativeJavaPackage("javax", objectProto);
1798 this.builtinOrg = new NativeJavaPackage("org", objectProto);
1799 this.builtinJavaImporter = initConstructor("JavaImporter");
1800 this.builtinJavaApi = initConstructor("Java");
1801 }
1803 private void initScripting(final ScriptEnvironment scriptEnv) {
1804 Object value;
1805 value = ScriptFunctionImpl.makeFunction("readLine", ScriptingFunctions.READLINE);
1806 addOwnProperty("readLine", Attribute.NOT_ENUMERABLE, value);
1808 value = ScriptFunctionImpl.makeFunction("readFully", ScriptingFunctions.READFULLY);
1809 addOwnProperty("readFully", Attribute.NOT_ENUMERABLE, value);
1811 final String execName = ScriptingFunctions.EXEC_NAME;
1812 value = ScriptFunctionImpl.makeFunction(execName, ScriptingFunctions.EXEC);
1813 addOwnProperty(execName, Attribute.NOT_ENUMERABLE, value);
1815 // Nashorn extension: global.echo (scripting-mode-only)
1816 // alias for "print"
1817 value = get("print");
1818 addOwnProperty("echo", Attribute.NOT_ENUMERABLE, value);
1820 // Nashorn extension: global.$OPTIONS (scripting-mode-only)
1821 final ScriptObject options = newObject();
1822 copyOptions(options, scriptEnv);
1823 addOwnProperty("$OPTIONS", Attribute.NOT_ENUMERABLE, options);
1825 // Nashorn extension: global.$ENV (scripting-mode-only)
1826 if (System.getSecurityManager() == null) {
1827 // do not fill $ENV if we have a security manager around
1828 // Retrieve current state of ENV variables.
1829 final ScriptObject env = newObject();
1830 env.putAll(System.getenv(), scriptEnv._strict);
1831 addOwnProperty(ScriptingFunctions.ENV_NAME, Attribute.NOT_ENUMERABLE, env);
1832 } else {
1833 addOwnProperty(ScriptingFunctions.ENV_NAME, Attribute.NOT_ENUMERABLE, UNDEFINED);
1834 }
1836 // add other special properties for exec support
1837 addOwnProperty(ScriptingFunctions.OUT_NAME, Attribute.NOT_ENUMERABLE, UNDEFINED);
1838 addOwnProperty(ScriptingFunctions.ERR_NAME, Attribute.NOT_ENUMERABLE, UNDEFINED);
1839 addOwnProperty(ScriptingFunctions.EXIT_NAME, Attribute.NOT_ENUMERABLE, UNDEFINED);
1840 }
1842 private static void copyOptions(final ScriptObject options, final ScriptEnvironment scriptEnv) {
1843 for (Field f : scriptEnv.getClass().getFields()) {
1844 try {
1845 options.set(f.getName(), f.get(scriptEnv), false);
1846 } catch (final IllegalArgumentException | IllegalAccessException exp) {
1847 throw new RuntimeException(exp);
1848 }
1849 }
1850 }
1852 private void initTypedArray() {
1853 this.builtinArrayBuffer = initConstructor("ArrayBuffer");
1854 this.builtinInt8Array = initConstructor("Int8Array");
1855 this.builtinUint8Array = initConstructor("Uint8Array");
1856 this.builtinUint8ClampedArray = initConstructor("Uint8ClampedArray");
1857 this.builtinInt16Array = initConstructor("Int16Array");
1858 this.builtinUint16Array = initConstructor("Uint16Array");
1859 this.builtinInt32Array = initConstructor("Int32Array");
1860 this.builtinUint32Array = initConstructor("Uint32Array");
1861 this.builtinFloat32Array = initConstructor("Float32Array");
1862 this.builtinFloat64Array = initConstructor("Float64Array");
1863 }
1865 private void copyBuiltins() {
1866 this.array = this.builtinArray;
1867 this._boolean = this.builtinBoolean;
1868 this.date = this.builtinDate;
1869 this.error = this.builtinError;
1870 this.evalError = this.builtinEvalError;
1871 this.function = this.builtinFunction;
1872 this.jsadapter = this.builtinJSAdapter;
1873 this.json = this.builtinJSON;
1874 this.com = this.builtinCom;
1875 this.edu = this.builtinEdu;
1876 this.java = this.builtinJava;
1877 this.javafx = this.builtinJavafx;
1878 this.javax = this.builtinJavax;
1879 this.org = this.builtinOrg;
1880 this.javaImporter = this.builtinJavaImporter;
1881 this.javaApi = this.builtinJavaApi;
1882 this.math = this.builtinMath;
1883 this.number = this.builtinNumber;
1884 this.object = this.builtinObject;
1885 this.packages = this.builtinPackages;
1886 this.rangeError = this.builtinRangeError;
1887 this.referenceError = this.builtinReferenceError;
1888 this.regexp = this.builtinRegExp;
1889 this.string = this.builtinString;
1890 this.syntaxError = this.builtinSyntaxError;
1891 this.typeError = this.builtinTypeError;
1892 this.uriError = this.builtinURIError;
1893 this.arrayBuffer = this.builtinArrayBuffer;
1894 this.int8Array = this.builtinInt8Array;
1895 this.uint8Array = this.builtinUint8Array;
1896 this.uint8ClampedArray = this.builtinUint8ClampedArray;
1897 this.int16Array = this.builtinInt16Array;
1898 this.uint16Array = this.builtinUint16Array;
1899 this.int32Array = this.builtinInt32Array;
1900 this.uint32Array = this.builtinUint32Array;
1901 this.float32Array = this.builtinFloat32Array;
1902 this.float64Array = this.builtinFloat64Array;
1903 }
1905 private void initDebug() {
1906 this.addOwnProperty("Debug", Attribute.NOT_ENUMERABLE, initConstructor("Debug"));
1907 }
1909 @SuppressWarnings("resource")
1910 private static Object printImpl(final boolean newLine, final Object... objects) {
1911 final PrintWriter out = Global.getEnv().getOut();
1912 final StringBuilder sb = new StringBuilder();
1914 for (final Object object : objects) {
1915 if (sb.length() != 0) {
1916 sb.append(' ');
1917 }
1919 sb.append(JSType.toString(object));
1920 }
1922 // Print all at once to ensure thread friendly result.
1923 if (newLine) {
1924 out.println(sb.toString());
1925 } else {
1926 out.print(sb.toString());
1927 }
1929 out.flush();
1931 return UNDEFINED;
1932 }
1934 /**
1935 * These classes are generated by nasgen tool and so we have to use
1936 * reflection to load and create new instance of these classes.
1937 */
1938 private ScriptObject initConstructor(final String name) {
1939 try {
1940 // Assuming class name pattern for built-in JS constructors.
1941 final StringBuilder sb = new StringBuilder("jdk.nashorn.internal.objects.");
1943 sb.append("Native");
1944 sb.append(name);
1945 sb.append("$Constructor");
1947 final Class<?> funcClass = Class.forName(sb.toString());
1948 final ScriptObject res = (ScriptObject)funcClass.newInstance();
1950 if (res instanceof ScriptFunction) {
1951 // All global constructor prototypes are not-writable,
1952 // not-enumerable and not-configurable.
1953 final ScriptFunction func = (ScriptFunction)res;
1954 func.modifyOwnProperty(func.getProperty("prototype"), Attribute.NON_ENUMERABLE_CONSTANT);
1955 }
1957 if (res.getProto() == null) {
1958 res.setProto(getObjectPrototype());
1959 }
1961 return res;
1963 } catch (final ClassNotFoundException | InstantiationException | IllegalAccessException e) {
1964 throw new RuntimeException(e);
1965 }
1966 }
1968 private void copyInitialMaps(final ScriptEnvironment env) {
1969 this.accessorPropertyDescriptorMap = AccessorPropertyDescriptor.getInitialMap().duplicate();
1970 this.dataPropertyDescriptorMap = DataPropertyDescriptor.getInitialMap().duplicate();
1971 this.genericPropertyDescriptorMap = GenericPropertyDescriptor.getInitialMap().duplicate();
1972 this.nativeArgumentsMap = NativeArguments.getInitialMap().duplicate();
1973 this.nativeArrayMap = NativeArray.getInitialMap().duplicate();
1974 this.nativeBooleanMap = NativeBoolean.getInitialMap().duplicate();
1975 this.nativeDateMap = NativeDate.getInitialMap().duplicate();
1976 this.nativeErrorMap = NativeError.getInitialMap().duplicate();
1977 this.nativeEvalErrorMap = NativeEvalError.getInitialMap().duplicate();
1978 this.nativeJSAdapterMap = NativeJSAdapter.getInitialMap().duplicate();
1979 this.nativeNumberMap = NativeNumber.getInitialMap().duplicate();
1980 this.nativeRangeErrorMap = NativeRangeError.getInitialMap().duplicate();
1981 this.nativeReferenceErrorMap = NativeReferenceError.getInitialMap().duplicate();
1982 this.nativeRegExpMap = NativeRegExp.getInitialMap().duplicate();
1983 this.nativeRegExpExecResultMap = NativeRegExpExecResult.getInitialMap().duplicate();
1984 this.nativeStrictArgumentsMap = NativeStrictArguments.getInitialMap().duplicate();
1985 this.nativeStringMap = NativeString.getInitialMap().duplicate();
1986 this.nativeSyntaxErrorMap = NativeSyntaxError.getInitialMap().duplicate();
1987 this.nativeTypeErrorMap = NativeTypeError.getInitialMap().duplicate();
1988 this.nativeURIErrorMap = NativeURIError.getInitialMap().duplicate();
1989 this.prototypeObjectMap = PrototypeObject.getInitialMap().duplicate();
1990 this.objectMap = JO.getInitialMap().duplicate();
1991 this.functionMap = ScriptFunctionImpl.getInitialMap().duplicate();
1992 this.anonymousFunctionMap = ScriptFunctionImpl.getInitialAnonymousMap().duplicate();
1993 this.strictFunctionMap = ScriptFunctionImpl.getInitialStrictMap().duplicate();
1994 this.boundFunctionMap = ScriptFunctionImpl.getInitialBoundMap().duplicate();
1996 // java
1997 if (! env._no_java) {
1998 this.nativeJavaImporterMap = NativeJavaImporter.getInitialMap().duplicate();
1999 }
2001 // typed arrays
2002 if (! env._no_typed_arrays) {
2003 this.arrayBufferViewMap = ArrayBufferView.getInitialMap().duplicate();
2004 this.nativeArrayBufferMap = NativeArrayBuffer.getInitialMap().duplicate();
2005 }
2006 }
2008 // Function and Object constructors are inter-dependent. Also,
2009 // Function.prototype
2010 // functions are not properly initialized. We fix the references here.
2011 // NOTE: be careful if you want to re-order the operations here. You may
2012 // have
2013 // to play with object references carefully!!
2014 private void initFunctionAndObject() {
2015 // First-n-foremost is Function
2016 this.builtinFunction = (ScriptFunction)initConstructor("Function");
2018 // create global anonymous function
2019 final ScriptFunction anon = ScriptFunctionImpl.newAnonymousFunction(this);
2020 // need to copy over members of Function.prototype to anon function
2021 anon.addBoundProperties(getFunctionPrototype());
2023 // Function.prototype === Object.getPrototypeOf(Function) ===
2024 // <anon-function>
2025 builtinFunction.setProto(anon);
2026 builtinFunction.setPrototype(anon);
2027 anon.set("constructor", builtinFunction, false);
2028 anon.deleteOwnProperty(anon.getMap().findProperty("prototype"));
2030 // use "getter" so that [[ThrowTypeError]] function's arity is 0 - as specified in step 10 of section 13.2.3
2031 this.typeErrorThrower = new ScriptFunctionImpl("TypeErrorThrower", Lookup.TYPE_ERROR_THROWER_GETTER, null, null, false, false, false);
2032 typeErrorThrower.setPrototype(UNDEFINED);
2033 // Non-constructor built-in functions do not have "prototype" property
2034 typeErrorThrower.deleteOwnProperty(typeErrorThrower.getMap().findProperty("prototype"));
2035 typeErrorThrower.preventExtensions();
2037 // now initialize Object
2038 this.builtinObject = (ScriptFunction)initConstructor("Object");
2039 final ScriptObject ObjectPrototype = getObjectPrototype();
2040 // Object.getPrototypeOf(Function.prototype) === Object.prototype
2041 anon.setProto(ObjectPrototype);
2043 // Function valued properties of Function.prototype were not properly
2044 // initialized. Because, these were created before global.function and
2045 // global.object were not initialized.
2046 jdk.nashorn.internal.runtime.Property[] properties = getFunctionPrototype().getMap().getProperties();
2047 for (final jdk.nashorn.internal.runtime.Property property : properties) {
2048 final Object key = property.getKey();
2049 final Object value = builtinFunction.get(key);
2051 if (value instanceof ScriptFunction && value != anon) {
2052 final ScriptFunction func = (ScriptFunction)value;
2053 func.setProto(getFunctionPrototype());
2054 final ScriptObject prototype = ScriptFunction.getPrototype(func);
2055 if (prototype != null) {
2056 prototype.setProto(ObjectPrototype);
2057 }
2058 }
2059 }
2061 // For function valued properties of Object and Object.prototype, make
2062 // sure prototype's proto chain ends with Object.prototype
2063 for (final jdk.nashorn.internal.runtime.Property property : builtinObject.getMap().getProperties()) {
2064 final Object key = property.getKey();
2065 final Object value = builtinObject.get(key);
2067 if (value instanceof ScriptFunction) {
2068 final ScriptFunction func = (ScriptFunction)value;
2069 final ScriptObject prototype = ScriptFunction.getPrototype(func);
2070 if (prototype != null) {
2071 prototype.setProto(ObjectPrototype);
2072 }
2073 }
2074 }
2076 properties = getObjectPrototype().getMap().getProperties();
2077 for (final jdk.nashorn.internal.runtime.Property property : properties) {
2078 final Object key = property.getKey();
2079 final Object value = ObjectPrototype.get(key);
2081 if (key.equals("constructor")) {
2082 continue;
2083 }
2085 if (value instanceof ScriptFunction) {
2086 final ScriptFunction func = (ScriptFunction)value;
2087 final ScriptObject prototype = ScriptFunction.getPrototype(func);
2088 if (prototype != null) {
2089 prototype.setProto(ObjectPrototype);
2090 }
2091 }
2092 }
2093 }
2095 private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
2096 return MH.findStatic(MethodHandles.lookup(), Global.class, name, MH.type(rtype, types));
2097 }
2099 RegExpResult getLastRegExpResult() {
2100 return lastRegExpResult;
2101 }
2103 void setLastRegExpResult(final RegExpResult regExpResult) {
2104 this.lastRegExpResult = regExpResult;
2105 }
2107 }